| 
					
				 | 
			
			
				@@ -0,0 +1,3250 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.adapter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var _adapter_factory = require("./adapter_factory.js"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var adapter = (0, _adapter_factory.adapterFactory)({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window: typeof window === 'undefined' ? undefined : window 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    module.exports = adapter; // this is the difference from adapter_core. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"./adapter_factory.js":2}],2:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    "use strict"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.adapterFactory = adapterFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("./utils")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var chromeShim = _interopRequireWildcard(require("./chrome/chrome_shim")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var firefoxShim = _interopRequireWildcard(require("./firefox/firefox_shim")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var safariShim = _interopRequireWildcard(require("./safari/safari_shim")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var commonShim = _interopRequireWildcard(require("./common_shim")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var sdp = _interopRequireWildcard(require("sdp")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Browser shims. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Shimming starts here. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function adapterFactory() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window = _ref.window; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        shimChrome: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        shimFirefox: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        shimSafari: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Utils. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var logging = utils.log; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var browserDetails = utils.detectBrowser(window); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var adapter = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        browserDetails: browserDetails, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        commonShim: commonShim, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        extractVersion: utils.extractVersion, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        disableLog: utils.disableLog, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        disableWarnings: utils.disableWarnings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Expose sdp as a convenience. For production apps include directly. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp: sdp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Shim browser if found. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      switch (browserDetails.browser) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 'chrome': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!chromeShim || !chromeShim.shimPeerConnection || !options.shimChrome) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logging('Chrome shim is not included in this adapter release.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return adapter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (browserDetails.version === null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logging('Chrome shim can not determine version, not shimming.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return adapter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          logging('adapter.js shimming chrome.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Export to the adapter global object visible in the browser. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          adapter.browserShim = chromeShim; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Must be called before shimPeerConnection. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimParameterlessSetLocalDescription(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimGetUserMedia(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimMediaStream(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimPeerConnection(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimOnTrack(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimAddTrackRemoveTrack(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimGetSendersWithDtmf(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.shimSenderReceiverGetStats(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          chromeShim.fixNegotiationNeeded(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimRTCIceCandidate(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimConnectionState(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimMaxMessageSize(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimSendThrowTypeError(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.removeExtmapAllowMixed(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 'firefox': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!firefoxShim || !firefoxShim.shimPeerConnection || !options.shimFirefox) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logging('Firefox shim is not included in this adapter release.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return adapter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          logging('adapter.js shimming firefox.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Export to the adapter global object visible in the browser. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          adapter.browserShim = firefoxShim; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Must be called before shimPeerConnection. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimParameterlessSetLocalDescription(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimGetUserMedia(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimPeerConnection(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimOnTrack(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimRemoveStream(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimSenderGetStats(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimReceiverGetStats(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimRTCDataChannel(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimAddTransceiver(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimGetParameters(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimCreateOffer(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firefoxShim.shimCreateAnswer(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimRTCIceCandidate(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimConnectionState(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimMaxMessageSize(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimSendThrowTypeError(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 'safari': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!safariShim || !options.shimSafari) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            logging('Safari shim is not included in this adapter release.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return adapter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          logging('adapter.js shimming safari.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Export to the adapter global object visible in the browser. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          adapter.browserShim = safariShim; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Must be called before shimCallbackAPI. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimParameterlessSetLocalDescription(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimRTCIceServerUrls(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimCreateOfferLegacy(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimCallbacksAPI(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimLocalStreamsAPI(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimRemoteStreamsAPI(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimTrackEventTransceiver(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimGetUserMedia(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          safariShim.shimAudioContext(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimRTCIceCandidate(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimMaxMessageSize(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.shimSendThrowTypeError(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          commonShim.removeExtmapAllowMixed(window, browserDetails); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          logging('Unsupported browser!'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return adapter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"./chrome/chrome_shim":3,"./common_shim":5,"./firefox/firefox_shim":6,"./safari/safari_shim":9,"./utils":10,"sdp":11}],3:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.fixNegotiationNeeded = fixNegotiationNeeded; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimAddTrackRemoveTrack = shimAddTrackRemoveTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimAddTrackRemoveTrackWithNative = shimAddTrackRemoveTrackWithNative; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimGetSendersWithDtmf = shimGetSendersWithDtmf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "shimGetUserMedia", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return _getusermedia.shimGetUserMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimMediaStream = shimMediaStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimOnTrack = shimOnTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimPeerConnection = shimPeerConnection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimSenderReceiverGetStats = shimSenderReceiverGetStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("../utils.js")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var _getusermedia = require("./getusermedia"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimMediaStream(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.MediaStream = window.MediaStream || window.webkitMediaStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimOnTrack(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return this._ontrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          set: function set(f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this._ontrack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.removeEventListener('track', this._ontrack); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('track', this._ontrack = f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          configurable: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._ontrackpoly) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._ontrackpoly = function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // onaddstream does not fire when a track is added to an existing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // stream. But stream.onaddtrack is implemented so we use that. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              e.stream.addEventListener('addtrack', function (te) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var receiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (window.RTCPeerConnection.prototype.getReceivers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  receiver = _this.getReceivers().find(function (r) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return r.track && r.track.id === te.track.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  receiver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    track: te.track 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var event = new Event('track'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.track = te.track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.receiver = receiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.transceiver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  receiver: receiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.streams = [e.stream]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _this.dispatchEvent(event); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              e.stream.getTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var receiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (window.RTCPeerConnection.prototype.getReceivers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  receiver = _this.getReceivers().find(function (r) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return r.track && r.track.id === track.id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  receiver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    track: track 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var event = new Event('track'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.track = track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.receiver = receiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.transceiver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  receiver: receiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.streams = [e.stream]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _this.dispatchEvent(event); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('addstream', this._ontrackpoly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return origSetRemoteDescription.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // even if RTCRtpTransceiver is in window, it is only used and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // emitted in unified-plan. Unfortunately this means we need 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // to unconditionally wrap the event. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        utils.wrapPeerConnectionEvent(window, 'track', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!e.transceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Object.defineProperty(e, 'transceiver', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              value: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                receiver: e.receiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimGetSendersWithDtmf(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) === 'object' && window.RTCPeerConnection && !('getSenders' in window.RTCPeerConnection.prototype) && 'createDTMFSender' in window.RTCPeerConnection.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var shimSenderWithDtmf = function shimSenderWithDtmf(pc, track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            track: track, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            get dtmf() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this._dtmf === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (track.kind === 'audio') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  this._dtmf = pc.createDTMFSender(track); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  this._dtmf = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return this._dtmf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _pc: pc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // augment addTrack when getSenders is not available. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!window.RTCPeerConnection.prototype.getSenders) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype.getSenders = function getSenders() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._senders = this._senders || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return this._senders.slice(); // return a copy of the internal state. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var origAddTrack = window.RTCPeerConnection.prototype.addTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var sender = origAddTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sender = shimSenderWithDtmf(this, track); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this._senders.push(sender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            origRemoveTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var idx = this._senders.indexOf(sender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (idx !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this._senders.splice(idx, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origAddStream = window.RTCPeerConnection.prototype.addStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.addStream = function addStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this2 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._senders = this._senders || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          origAddStream.apply(this, [stream]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stream.getTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _this2._senders.push(shimSenderWithDtmf(_this2, track)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this3 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._senders = this._senders || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          origRemoveStream.apply(this, [stream]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stream.getTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var sender = _this3._senders.find(function (s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return s.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // remove sender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              _this3._senders.splice(_this3._senders.indexOf(sender), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (_typeof(window) === 'object' && window.RTCPeerConnection && 'getSenders' in window.RTCPeerConnection.prototype && 'createDTMFSender' in window.RTCPeerConnection.prototype && window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origGetSenders = window.RTCPeerConnection.prototype.getSenders; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.getSenders = function getSenders() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this4 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var senders = origGetSenders.apply(this, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          senders.forEach(function (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return sender._pc = _this4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return senders; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this._dtmf === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.track.kind === 'audio') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this._dtmf = this._pc.createDTMFSender(this.track); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this._dtmf = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return this._dtmf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimSenderReceiverGetStats(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // shim sender stats. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('getStats' in window.RTCRtpSender.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origGetSenders = window.RTCPeerConnection.prototype.getSenders; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (origGetSenders) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype.getSenders = function getSenders() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var _this5 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var senders = origGetSenders.apply(this, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            senders.forEach(function (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return sender._pc = _this5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return senders; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origAddTrack = window.RTCPeerConnection.prototype.addTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (origAddTrack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype.addTrack = function addTrack() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var sender = origAddTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sender._pc = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCRtpSender.prototype.getStats = function getStats() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var sender = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this._pc.getStats().then(function (result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              /* Note: this will include stats of all senders that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               *   send a track with the same id as sender.track as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               *   it is not possible to identify the RTCRtpSender. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              utils.filterStats(result, sender.track, true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // shim receiver stats. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('getStats' in window.RTCRtpReceiver.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (origGetReceivers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype.getReceivers = function getReceivers() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var _this6 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var receivers = origGetReceivers.apply(this, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            receivers.forEach(function (receiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return receiver._pc = _this6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return receivers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        utils.wrapPeerConnectionEvent(window, 'track', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          e.receiver._pc = e.srcElement; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCRtpReceiver.prototype.getStats = function getStats() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var receiver = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this._pc.getStats().then(function (result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return utils.filterStats(result, receiver.track, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('getStats' in window.RTCRtpSender.prototype && 'getStats' in window.RTCRtpReceiver.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // shim RTCPeerConnection.getStats(track). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origGetStats = window.RTCPeerConnection.prototype.getStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.getStats = function getStats() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var track = arguments[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var receiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.getSenders().forEach(function (s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (s.track === track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                err = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sender = s; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.getReceivers().forEach(function (r) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (r.track === track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (receiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                err = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                receiver = r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return r.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (err || sender && receiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return Promise.reject(new DOMException('There are more than one sender or receiver for the track.', 'InvalidAccessError')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return sender.getStats(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (receiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return receiver.getStats(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return Promise.reject(new DOMException('There is no sender or receiver for the track.', 'InvalidAccessError')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origGetStats.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimAddTrackRemoveTrackWithNative(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // shim addTrack/removeTrack with native variants in order to make 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // the interactions with legacy getLocalStreams behave as in other browsers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Keeps a mapping stream.id => [stream, rtpsenders...] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this7 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._shimmedLocalStreams = this._shimmedLocalStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Object.keys(this._shimmedLocalStreams).map(function (streamId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return _this7._shimmedLocalStreams[streamId][0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origAddTrack = window.RTCPeerConnection.prototype.addTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return origAddTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._shimmedLocalStreams = this._shimmedLocalStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var sender = origAddTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!this._shimmedLocalStreams[stream.id]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._shimmedLocalStreams[stream.id] = [stream, sender]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._shimmedLocalStreams[stream.id].push(sender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origAddStream = window.RTCPeerConnection.prototype.addStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.addStream = function addStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this8 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._shimmedLocalStreams = this._shimmedLocalStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stream.getTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var alreadyExists = _this8.getSenders().find(function (s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return s.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (alreadyExists) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new DOMException('Track already exists.', 'InvalidAccessError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var existingSenders = this.getSenders(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        origAddStream.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var newSenders = this.getSenders().filter(function (newSender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return existingSenders.indexOf(newSender) === -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._shimmedLocalStreams = this._shimmedLocalStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete this._shimmedLocalStreams[stream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origRemoveStream.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this9 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._shimmedLocalStreams = this._shimmedLocalStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Object.keys(this._shimmedLocalStreams).forEach(function (streamId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var idx = _this9._shimmedLocalStreams[streamId].indexOf(sender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (idx !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              _this9._shimmedLocalStreams[streamId].splice(idx, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (_this9._shimmedLocalStreams[streamId].length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              delete _this9._shimmedLocalStreams[streamId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origRemoveTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimAddTrackRemoveTrack(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // shim addTrack and removeTrack. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return shimAddTrackRemoveTrackWithNative(window); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // also shim pc.getLocalStreams when addTrack is shimmed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // to return the original streams. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this10 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var nativeStreams = origGetLocalStreams.apply(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._reverseStreams = this._reverseStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return nativeStreams.map(function (stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return _this10._reverseStreams[stream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origAddStream = window.RTCPeerConnection.prototype.addStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.addStream = function addStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this11 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._streams = this._streams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._reverseStreams = this._reverseStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stream.getTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var alreadyExists = _this11.getSenders().find(function (s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return s.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (alreadyExists) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new DOMException('Track already exists.', 'InvalidAccessError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Add identity mapping for consistency with addTrack. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Unless this is being used with a stream from addTrack. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!this._reverseStreams[stream.id]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var newStream = new window.MediaStream(stream.getTracks()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._streams[stream.id] = newStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._reverseStreams[newStream.id] = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stream = newStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        origAddStream.apply(this, [stream]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origRemoveStream = window.RTCPeerConnection.prototype.removeStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._streams = this._streams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._reverseStreams = this._reverseStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        origRemoveStream.apply(this, [this._streams[stream.id] || stream]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete this._streams[stream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this12 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.signalingState === 'closed') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var streams = [].slice.call(arguments, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (streams.length !== 1 || !streams[0].getTracks().find(function (t) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return t === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        })) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // this is not fully correct but all we can manage without 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // [[associated MediaStreams]] internal slot. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          throw new DOMException('The adapter.js addTrack polyfill only supports a single ' + ' stream which is associated with the specified track.', 'NotSupportedError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var alreadyExists = this.getSenders().find(function (s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return s.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (alreadyExists) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          throw new DOMException('Track already exists.', 'InvalidAccessError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._streams = this._streams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._reverseStreams = this._reverseStreams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var oldStream = this._streams[stream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (oldStream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // this is using odd Chrome behaviour, use with caution: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Note: we rely on the high-level addTrack/dtmf shim to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // create the sender with a dtmf sender. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          oldStream.addTrack(track); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Trigger ONN async. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Promise.resolve().then(function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _this12.dispatchEvent(new Event('negotiationneeded')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var newStream = new window.MediaStream([track]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._streams[stream.id] = newStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._reverseStreams[newStream.id] = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.addStream(newStream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this.getSenders().find(function (s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return s.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // replace the internal stream id with the external one and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // vice versa. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function replaceInternalStreamId(pc, description) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var sdp = description.sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.keys(pc._reverseStreams || []).forEach(function (internalId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var externalStream = pc._reverseStreams[internalId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var internalStream = pc._streams[externalStream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sdp = sdp.replace(new RegExp(internalStream.id, 'g'), externalStream.id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new RTCSessionDescription({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          type: description.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sdp: sdp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function replaceExternalStreamId(pc, description) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var sdp = description.sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.keys(pc._reverseStreams || []).forEach(function (internalId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var externalStream = pc._reverseStreams[internalId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var internalStream = pc._streams[externalStream.id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sdp = sdp.replace(new RegExp(externalStream.id, 'g'), internalStream.id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new RTCSessionDescription({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          type: description.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sdp: sdp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ['createOffer', 'createAnswer'].forEach(function (method) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var nativeMethod = window.RTCPeerConnection.prototype[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var methodObj = _defineProperty({}, method, function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this13 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var args = arguments; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var isLegacyCall = arguments.length && typeof arguments[0] === 'function'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (isLegacyCall) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return nativeMethod.apply(this, [function (description) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var desc = replaceInternalStreamId(_this13, description); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              args[0].apply(null, [desc]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }, function (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (args[1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                args[1].apply(null, err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }, arguments[2]]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeMethod.apply(this, arguments).then(function (description) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return replaceInternalStreamId(_this13, description); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype[method] = methodObj[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!arguments.length || !arguments[0].type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return origSetLocalDescription.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        arguments[0] = replaceExternalStreamId(this, arguments[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origSetLocalDescription.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, 'localDescription'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Object.defineProperty(window.RTCPeerConnection.prototype, 'localDescription', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var description = origLocalDescription.get.apply(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (description.type === '') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return description; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return replaceInternalStreamId(this, description); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this14 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.signalingState === 'closed') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // We can not yet check for sender instanceof RTCRtpSender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // since we shim RTPSender. So we check if sender._pc is set. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!sender._pc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.', 'TypeError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var isLocal = sender._pc === this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!isLocal) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          throw new DOMException('Sender was not created by this connection.', 'InvalidAccessError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Search for the native stream the senders track belongs to. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._streams = this._streams || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.keys(this._streams).forEach(function (streamid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var hasTrack = _this14._streams[streamid].getTracks().find(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return sender.track === track; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (hasTrack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream = _this14._streams[streamid]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (stream.getTracks().length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // if this is the last track of the stream, remove the stream. This 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // takes care of any shimmed _senders. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.removeStream(this._reverseStreams[stream.id]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // relying on the same odd chrome behaviour as above. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            stream.removeTrack(sender.track); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.dispatchEvent(new Event('negotiationneeded')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimPeerConnection(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // very basic support for old versions. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection = window.webkitRTCPeerConnection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // shim implicit creation of RTCSessionDescription/RTCIceCandidate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (browserDetails.version < 53) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var nativeMethod = window.RTCPeerConnection.prototype[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var methodObj = _defineProperty({}, method, function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return nativeMethod.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype[method] = methodObj[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Attempt to fix ONN in plan-b mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function fixNegotiationNeeded(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      utils.wrapPeerConnectionEvent(window, 'negotiationneeded', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var pc = e.target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (browserDetails.version < 72 || pc.getConfiguration && pc.getConfiguration().sdpSemantics === 'plan-b') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (pc.signalingState !== 'stable') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"../utils.js":10,"./getusermedia":4}],4:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimGetUserMedia = shimGetUserMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("../utils.js")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var logging = utils.log; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimGetUserMedia(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var navigator = window && window.navigator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!navigator.mediaDevices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var constraintsToChrome_ = function constraintsToChrome_(c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (_typeof(c) !== 'object' || c.mandatory || c.optional) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cc = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.keys(c).forEach(function (key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (key === 'require' || key === 'advanced' || key === 'mediaSource') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var r = _typeof(c[key]) === 'object' ? c[key] : { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ideal: c[key] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (r.exact !== undefined && typeof r.exact === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            r.min = r.max = r.exact; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var oldname_ = function oldname_(prefix, name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (prefix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return prefix + name.charAt(0).toUpperCase() + name.slice(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return name === 'deviceId' ? 'sourceId' : name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (r.ideal !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cc.optional = cc.optional || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var oc = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (typeof r.ideal === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              oc[oldname_('min', key)] = r.ideal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cc.optional.push(oc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              oc = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              oc[oldname_('max', key)] = r.ideal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cc.optional.push(oc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              oc[oldname_('', key)] = r.ideal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cc.optional.push(oc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (r.exact !== undefined && typeof r.exact !== 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cc.mandatory = cc.mandatory || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cc.mandatory[oldname_('', key)] = r.exact; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ['min', 'max'].forEach(function (mix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (r[mix] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cc.mandatory = cc.mandatory || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                cc.mandatory[oldname_(mix, key)] = r[mix]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (c.advanced) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cc.optional = (cc.optional || []).concat(c.advanced); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return cc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var shimConstraints_ = function shimConstraints_(constraints, func) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (browserDetails.version >= 61) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return func(constraints); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        constraints = JSON.parse(JSON.stringify(constraints)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (constraints && _typeof(constraints.audio) === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var remap = function remap(obj, a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (a in obj && !(b in obj)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              obj[b] = obj[a]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              delete obj[a]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          constraints = JSON.parse(JSON.stringify(constraints)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          remap(constraints.audio, 'autoGainControl', 'googAutoGainControl'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          constraints.audio = constraintsToChrome_(constraints.audio); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (constraints && _typeof(constraints.video) === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Shim facingMode for mobile & surface pro. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var face = constraints.video.facingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          face = face && (_typeof(face) === 'object' ? face : { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ideal: face 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var getSupportedFacingModeLies = browserDetails.version < 66; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (face && (face.exact === 'user' || face.exact === 'environment' || face.ideal === 'user' || face.ideal === 'environment') && !(navigator.mediaDevices.getSupportedConstraints && navigator.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            delete constraints.video.facingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var matches; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (face.exact === 'environment' || face.ideal === 'environment') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              matches = ['back', 'rear']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (face.exact === 'user' || face.ideal === 'user') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              matches = ['front']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (matches) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Look for matches in label, or use last cam for back (typical). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return navigator.mediaDevices.enumerateDevices().then(function (devices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                devices = devices.filter(function (d) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return d.kind === 'videoinput'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var dev = devices.find(function (d) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return matches.some(function (match) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return d.label.toLowerCase().includes(match); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!dev && devices.length && matches.includes('back')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  dev = devices[devices.length - 1]; // more likely the back cam 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (dev) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  constraints.video.deviceId = face.exact ? { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    exact: dev.deviceId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  } : { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ideal: dev.deviceId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                constraints.video = constraintsToChrome_(constraints.video); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                logging('chrome: ' + JSON.stringify(constraints)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return func(constraints); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          constraints.video = constraintsToChrome_(constraints.video); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        logging('chrome: ' + JSON.stringify(constraints)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return func(constraints); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var shimError_ = function shimError_(e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (browserDetails.version >= 64) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          name: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PermissionDeniedError: 'NotAllowedError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PermissionDismissedError: 'NotAllowedError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            InvalidStateError: 'NotAllowedError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DevicesNotFoundError: 'NotFoundError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ConstraintNotSatisfiedError: 'OverconstrainedError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TrackStartError: 'NotReadableError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            MediaDeviceFailedDueToShutdown: 'NotAllowedError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            MediaDeviceKillSwitchOn: 'NotAllowedError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TabCaptureError: 'AbortError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ScreenCaptureError: 'AbortError', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            DeviceCaptureError: 'AbortError' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }[e.name] || e.name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          message: e.message, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          constraint: e.constraint || e.constraintName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          toString: function toString() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return this.name + (this.message && ': ') + this.message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var getUserMedia_ = function getUserMedia_(constraints, onSuccess, onError) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        shimConstraints_(constraints, function (c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          navigator.webkitGetUserMedia(c, onSuccess, function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (onError) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              onError(shimError_(e)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      navigator.getUserMedia = getUserMedia_.bind(navigator); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // function which returns a Promise, it does not accept spec-style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // constraints. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (navigator.mediaDevices.getUserMedia) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        navigator.mediaDevices.getUserMedia = function (cs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return shimConstraints_(cs, function (c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return origGetUserMedia(c).then(function (stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stream.getTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  track.stop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new DOMException('', 'NotFoundError'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }, function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return Promise.reject(shimError_(e)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"../utils.js":10}],5:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.removeExtmapAllowMixed = removeExtmapAllowMixed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimAddIceCandidateNullOrEmpty = shimAddIceCandidateNullOrEmpty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimConnectionState = shimConnectionState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimMaxMessageSize = shimMaxMessageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimParameterlessSetLocalDescription = shimParameterlessSetLocalDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimRTCIceCandidate = shimRTCIceCandidate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimRTCIceCandidateRelayProtocol = shimRTCIceCandidateRelayProtocol; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimSendThrowTypeError = shimSendThrowTypeError; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var _sdp = _interopRequireDefault(require("sdp")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("./utils")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimRTCIceCandidate(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // foundation is arbitrarily chosen as an indicator for full support for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCIceCandidate || window.RTCIceCandidate && 'foundation' in window.RTCIceCandidate.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var NativeRTCIceCandidate = window.RTCIceCandidate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCIceCandidate = function RTCIceCandidate(args) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Remove the a= which shouldn't be part of the candidate string. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (_typeof(args) === 'object' && args.candidate && args.candidate.indexOf('a=') === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          args = JSON.parse(JSON.stringify(args)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          args.candidate = args.candidate.substring(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (args.candidate && args.candidate.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Augment the native candidate with the parsed fields. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var nativeCandidate = new NativeRTCIceCandidate(args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var parsedCandidate = _sdp["default"].parseCandidate(args.candidate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var key in parsedCandidate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!(key in nativeCandidate)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              Object.defineProperty(nativeCandidate, key, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                value: parsedCandidate[key] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Override serializer to not serialize the extra attributes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          nativeCandidate.toJSON = function toJSON() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              candidate: nativeCandidate.candidate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sdpMid: nativeCandidate.sdpMid, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sdpMLineIndex: nativeCandidate.sdpMLineIndex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              usernameFragment: nativeCandidate.usernameFragment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeCandidate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new NativeRTCIceCandidate(args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Hook up the augmented candidate in onicecandidate and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // addEventListener('icecandidate', ...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      utils.wrapPeerConnectionEvent(window, 'icecandidate', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (e.candidate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Object.defineProperty(e, 'candidate', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            value: new window.RTCIceCandidate(e.candidate), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            writable: 'false' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimRTCIceCandidateRelayProtocol(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCIceCandidate || window.RTCIceCandidate && 'relayProtocol' in window.RTCIceCandidate.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Hook up the augmented candidate in onicecandidate and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // addEventListener('icecandidate', ...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      utils.wrapPeerConnectionEvent(window, 'icecandidate', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (e.candidate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var parsedCandidate = _sdp["default"].parseCandidate(e.candidate.candidate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (parsedCandidate.type === 'relay') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // This is a libwebrtc-specific mapping of local type preference 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // to relayProtocol. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            e.candidate.relayProtocol = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              0: 'tls', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              1: 'tcp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              2: 'udp' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }[parsedCandidate.priority >> 24]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimMaxMessageSize(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('sctp' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return typeof this._sctp === 'undefined' ? null : this._sctp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sctpInDescription = function sctpInDescription(description) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!description || !description.sdp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var sections = _sdp["default"].splitSections(description.sdp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sections.shift(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return sections.some(function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var mLine = _sdp["default"].parseMLine(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return mLine && mLine.kind === 'application' && mLine.protocol.indexOf('SCTP') !== -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var getRemoteFirefoxVersion = function getRemoteFirefoxVersion(description) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: Is there a better solution for detecting Firefox? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (match === null || match.length < 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var version = parseInt(match[1], 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Test for NaN (yes, this is ugly) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return version !== version ? -1 : version; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var getCanSendMaxMessageSize = function getCanSendMaxMessageSize(remoteIsFirefox) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Every implementation we know can send at least 64 KiB. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Note: Although Chrome is technically able to send up to 256 KiB, the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       data does not reach the other peer reliably. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var canSendMaxMessageSize = 65536; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (browserDetails.browser === 'firefox') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (browserDetails.version < 57) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (remoteIsFirefox === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // FF < 57 will send in 16 KiB chunks using the deprecated PPID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // fragmentation. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              canSendMaxMessageSize = 16384; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // However, other FF (and RAWRTC) can reassemble PPID-fragmented 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // messages. Thus, supporting ~2 GiB when sending. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              canSendMaxMessageSize = 2147483637; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (browserDetails.version < 60) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Currently, all FF >= 57 will reset the remote maximum message size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // to the default value when a data channel is created at a later 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // stage. :( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // FF >= 60 supports sending ~2 GiB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canSendMaxMessageSize = 2147483637; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return canSendMaxMessageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var getMaxMessageSize = function getMaxMessageSize(description, remoteIsFirefox) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Note: 65536 bytes is the default value from the SDP spec. Also, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       every implementation we know supports receiving 65536 bytes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var maxMessageSize = 65536; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // FF 57 has a slightly incorrect default remote max message size, so 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // we need to adjust it here to avoid a failure when sending. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (browserDetails.browser === 'firefox' && browserDetails.version === 57) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          maxMessageSize = 65535; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var match = _sdp["default"].matchPrefix(description.sdp, 'a=max-message-size:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (match.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          maxMessageSize = parseInt(match[0].substring(19), 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // If the maximum message size is not present in the remote SDP and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // both local and remote are Firefox, the remote peer can receive 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // ~2 GiB. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          maxMessageSize = 2147483637; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return maxMessageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._sctp = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Chrome decided to not expose .sctp in plan-b mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // As usual, adapter.js has to do an 'ugly worakaround' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // to cover up the mess. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this$getConfiguratio = this.getConfiguration(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sdpSemantics = _this$getConfiguratio.sdpSemantics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (sdpSemantics === 'plan-b') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Object.defineProperty(this, 'sctp', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return typeof this._sctp === 'undefined' ? null : this._sctp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              configurable: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sctpInDescription(arguments[0])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Check if the remote is FF. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var isFirefox = getRemoteFirefoxVersion(arguments[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Get the maximum message size the local peer is capable of sending 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var canSendMMS = getCanSendMaxMessageSize(isFirefox); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Get the maximum message size of the remote peer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var remoteMMS = getMaxMessageSize(arguments[0], isFirefox); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Determine final maximum message size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var maxMessageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (canSendMMS === 0 && remoteMMS === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            maxMessageSize = Number.POSITIVE_INFINITY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (canSendMMS === 0 || remoteMMS === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            maxMessageSize = Math.max(canSendMMS, remoteMMS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            maxMessageSize = Math.min(canSendMMS, remoteMMS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Create a dummy RTCSctpTransport object and the 'maxMessageSize' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // attribute. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var sctp = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          Object.defineProperty(sctp, 'maxMessageSize', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return maxMessageSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._sctp = sctp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origSetRemoteDescription.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimSendThrowTypeError(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(window.RTCPeerConnection && 'createDataChannel' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Note: Although Firefox >= 57 has a native implementation, the maximum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //       message size can be reset for all data channels at a later stage. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //       See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function wrapDcSend(dc, pc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origDataChannelSend = dc.send; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dc.send = function send() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var data = arguments[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var length = data.length || data.size || data.byteLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (dc.readyState === 'open' && pc.sctp && length > pc.sctp.maxMessageSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new TypeError('Message too large (can send a maximum of ' + pc.sctp.maxMessageSize + ' bytes)'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return origDataChannelSend.apply(dc, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.createDataChannel = function createDataChannel() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var dataChannel = origCreateDataChannel.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        wrapDcSend(dataChannel, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return dataChannel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      utils.wrapPeerConnectionEvent(window, 'datachannel', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        wrapDcSend(e.channel, e.target); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* shims RTCConnectionState by pretending it is the same as iceConnectionState. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * since DTLS failures would be hidden. See 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * for the Firefox tracking bug. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimConnectionState(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection || 'connectionState' in window.RTCPeerConnection.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var proto = window.RTCPeerConnection.prototype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Object.defineProperty(proto, 'connectionState', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            completed: 'connected', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            checking: 'connecting' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }[this.iceConnectionState] || this.iceConnectionState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        configurable: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Object.defineProperty(proto, 'onconnectionstatechange', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this._onconnectionstatechange || null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        set: function set(cb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (this._onconnectionstatechange) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.removeEventListener('connectionstatechange', this._onconnectionstatechange); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            delete this._onconnectionstatechange; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (cb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('connectionstatechange', this._onconnectionstatechange = cb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        configurable: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ['setLocalDescription', 'setRemoteDescription'].forEach(function (method) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origMethod = proto[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        proto[method] = function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._connectionstatechangepoly) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._connectionstatechangepoly = function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var pc = e.target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (pc._lastConnectionState !== pc.connectionState) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pc._lastConnectionState = pc.connectionState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var newEvent = new Event('connectionstatechange', e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pc.dispatchEvent(newEvent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('iceconnectionstatechange', this._connectionstatechangepoly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return origMethod.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function removeExtmapAllowMixed(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* remove a=extmap-allow-mixed for webrtc.org < M71 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (browserDetails.browser === 'safari' && browserDetails.version >= 605) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription(desc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (desc && desc.sdp && desc.sdp.indexOf('\na=extmap-allow-mixed') !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var sdp = desc.sdp.split('\n').filter(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return line.trim() !== 'a=extmap-allow-mixed'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }).join('\n'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Safari enforces read-only-ness of RTCSessionDescription fields. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (window.RTCSessionDescription && desc instanceof window.RTCSessionDescription) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            arguments[0] = new window.RTCSessionDescription({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              type: desc.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sdp: sdp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            desc.sdp = sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return nativeSRD.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimAddIceCandidateNullOrEmpty(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Support for addIceCandidate(null or undefined) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // as well as addIceCandidate({candidate: "", ...}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://bugs.chromium.org/p/chromium/issues/detail?id=978582 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Note: must be called before other polyfills which change the signature. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!arguments[0]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (arguments[1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            arguments[1].apply(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Firefox 68+ emits and processes {candidate: "", ...}, ignore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // in older versions. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Native support for ignoring exists for Chrome M77+. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Safari ignores as well, exact version unknown but works in the same 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // version that also ignores addIceCandidate(null). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ((browserDetails.browser === 'chrome' && browserDetails.version < 78 || browserDetails.browser === 'firefox' && browserDetails.version < 68 || browserDetails.browser === 'safari') && arguments[0] && arguments[0].candidate === '') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return nativeAddIceCandidate.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Note: Make sure to call this ahead of APIs that modify 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // setLocalDescription.length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimParameterlessSetLocalDescription(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var nativeSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var desc = arguments[0] || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (_typeof(desc) !== 'object' || desc.type && desc.sdp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeSetLocalDescription.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The remaining steps should technically happen when SLD comes off the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // RTCPeerConnection's operations chain (not ahead of going on it), but 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // this is too difficult to shim. Instead, this shim only covers the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // common case where the operations chain is empty. This is imperfect, but 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // should cover many cases. Rationale: Even if we can't reduce the glare 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // window to zero on imperfect implementations, there's value in tapping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // into the perfect negotiation pattern that several browsers support. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        desc = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          type: desc.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sdp: desc.sdp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!desc.type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          switch (this.signalingState) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'stable': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'have-local-offer': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'have-remote-pranswer': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              desc.type = 'offer'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              desc.type = 'answer'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (desc.sdp || desc.type !== 'offer' && desc.type !== 'answer') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeSetLocalDescription.apply(this, [desc]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var func = desc.type === 'offer' ? this.createOffer : this.createAnswer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return func.apply(this).then(function (d) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeSetLocalDescription.apply(_this, [d]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"./utils":10,"sdp":11}],6:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimAddTransceiver = shimAddTransceiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimCreateAnswer = shimCreateAnswer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimCreateOffer = shimCreateOffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "shimGetDisplayMedia", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return _getdisplaymedia.shimGetDisplayMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimGetParameters = shimGetParameters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "shimGetUserMedia", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return _getusermedia.shimGetUserMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimOnTrack = shimOnTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimPeerConnection = shimPeerConnection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimRTCDataChannel = shimRTCDataChannel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimReceiverGetStats = shimReceiverGetStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimRemoveStream = shimRemoveStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimSenderGetStats = shimSenderGetStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("../utils")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var _getusermedia = require("./getusermedia"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var _getdisplaymedia = require("./getdisplaymedia"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimOnTrack(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              receiver: this.receiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimPeerConnection(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; // probably media.peerconnection.enabled=false in about:config 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection && window.mozRTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // very basic support for old versions. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection = window.mozRTCPeerConnection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (browserDetails.version < 53) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // shim away need for obsolete RTCIceCandidate/RTCSessionDescription. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var nativeMethod = window.RTCPeerConnection.prototype[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var methodObj = _defineProperty({}, method, function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return nativeMethod.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          window.RTCPeerConnection.prototype[method] = methodObj[method]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var modernStatsTypes = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        inboundrtp: 'inbound-rtp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        outboundrtp: 'outbound-rtp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        candidatepair: 'candidate-pair', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        localcandidate: 'local-candidate', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        remotecandidate: 'remote-candidate' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var nativeGetStats = window.RTCPeerConnection.prototype.getStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.getStats = function getStats() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _arguments = Array.prototype.slice.call(arguments), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          selector = _arguments[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          onSucc = _arguments[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          onErr = _arguments[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return nativeGetStats.apply(this, [selector || null]).then(function (stats) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (browserDetails.version < 53 && !onSucc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Shim only promise getStats with spec-hyphens in type names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Leave callback version alone; misc old uses of forEach before Map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stats.forEach(function (stat) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stat.type = modernStatsTypes[stat.type] || stat.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (e.name !== 'TypeError') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Avoid TypeError: "type" is read-only, in old versions. 34-43ish 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stats.forEach(function (stat, i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stats.set(i, Object.assign({}, stat, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  type: modernStatsTypes[stat.type] || stat.type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return stats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }).then(onSucc, onErr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimSenderGetStats(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origGetSenders = window.RTCPeerConnection.prototype.getSenders; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (origGetSenders) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.getSenders = function getSenders() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var senders = origGetSenders.apply(this, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          senders.forEach(function (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return sender._pc = _this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return senders; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origAddTrack = window.RTCPeerConnection.prototype.addTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (origAddTrack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.addTrack = function addTrack() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var sender = origAddTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sender._pc = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCRtpSender.prototype.getStats = function getStats() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this.track ? this._pc.getStats(this.track) : Promise.resolve(new Map()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimReceiverGetStats(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (origGetReceivers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.getReceivers = function getReceivers() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this2 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var receivers = origGetReceivers.apply(this, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          receivers.forEach(function (receiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return receiver._pc = _this2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return receivers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      utils.wrapPeerConnectionEvent(window, 'track', function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        e.receiver._pc = e.srcElement; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return e; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCRtpReceiver.prototype.getStats = function getStats() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this._pc.getStats(this.track); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimRemoveStream(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection || 'removeStream' in window.RTCPeerConnection.prototype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _this3 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        utils.deprecated('removeStream', 'removeTrack'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.getSenders().forEach(function (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (sender.track && stream.getTracks().includes(sender.track)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _this3.removeTrack(sender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimRTCDataChannel(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // rename DataChannel to RTCDataChannel (native fix in FF60): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (window.DataChannel && !window.RTCDataChannel) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCDataChannel = window.DataChannel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimAddTransceiver(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Firefox ignores the init sendEncodings options passed to addTransceiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCPeerConnection)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (origAddTransceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.addTransceiver = function addTransceiver() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.setParametersPromises = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // WebIDL input coercion and validation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var sendEncodings = arguments[1] && arguments[1].sendEncodings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (sendEncodings === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sendEncodings = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sendEncodings = _toConsumableArray(sendEncodings); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var shouldPerformCheck = sendEncodings.length > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (shouldPerformCheck) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // If sendEncodings params are provided, validate grammar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sendEncodings.forEach(function (encodingParam) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if ('rid' in encodingParam) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var ridRegex = /^[a-z0-9]{0,16}$/i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!ridRegex.test(encodingParam.rid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  throw new TypeError('Invalid RID value provided.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if ('scaleResolutionDownBy' in encodingParam) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  throw new RangeError('scale_resolution_down_by must be >= 1.0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if ('maxFramerate' in encodingParam) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!(parseFloat(encodingParam.maxFramerate) >= 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  throw new RangeError('max_framerate must be >= 0.0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var transceiver = origAddTransceiver.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (shouldPerformCheck) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Check if the init options were applied. If not we do this in an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // asynchronous way and save the promise reference in a global object. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // This is an ugly hack, but at the same time is way more robust than 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // checking the sender parameters before and after the createOffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Also note that after the createoffer we are not 100% sure that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // the params were asynchronously applied so we might miss the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // opportunity to recreate offer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var sender = transceiver.sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var params = sender.getParameters(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!('encodings' in params) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Avoid being fooled by patched getParameters() below. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            params.encodings.length === 1 && Object.keys(params.encodings[0]).length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              params.encodings = sendEncodings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sender.sendEncodings = sendEncodings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.setParametersPromises.push(sender.setParameters(params).then(function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                delete sender.sendEncodings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              })["catch"](function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                delete sender.sendEncodings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return transceiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimGetParameters(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCRtpSender)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origGetParameters = window.RTCRtpSender.prototype.getParameters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (origGetParameters) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCRtpSender.prototype.getParameters = function getParameters() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var params = origGetParameters.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!('encodings' in params)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            params.encodings = [].concat(this.sendEncodings || [{}]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return params; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimCreateOffer(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Firefox ignores the init sendEncodings options passed to addTransceiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCPeerConnection)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origCreateOffer = window.RTCPeerConnection.prototype.createOffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.createOffer = function createOffer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _arguments2 = arguments, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          _this4 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.setParametersPromises && this.setParametersPromises.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return Promise.all(this.setParametersPromises).then(function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return origCreateOffer.apply(_this4, _arguments2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          })["finally"](function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _this4.setParametersPromises = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origCreateOffer.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimCreateAnswer(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Firefox ignores the init sendEncodings options passed to addTransceiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(_typeof(window) === 'object' && window.RTCPeerConnection)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.createAnswer = function createAnswer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _arguments3 = arguments, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          _this5 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.setParametersPromises && this.setParametersPromises.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return Promise.all(this.setParametersPromises).then(function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return origCreateAnswer.apply(_this5, _arguments3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          })["finally"](function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _this5.setParametersPromises = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origCreateAnswer.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"../utils":10,"./getdisplaymedia":7,"./getusermedia":8}],7:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2018 The adapter.js project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimGetDisplayMedia = shimGetDisplayMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimGetDisplayMedia(window, preferredMediaSource) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.navigator.mediaDevices) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(constraints && constraints.video)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var err = new DOMException('getDisplayMedia without video ' + 'constraints is undefined'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          err.name = 'NotFoundError'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // from https://heycam.github.io/webidl/#idl-DOMException-error-names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          err.code = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return Promise.reject(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (constraints.video === true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          constraints.video = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mediaSource: preferredMediaSource 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          constraints.video.mediaSource = preferredMediaSource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return window.navigator.mediaDevices.getUserMedia(constraints); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{}],8:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimGetUserMedia = shimGetUserMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("../utils")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimGetUserMedia(window, browserDetails) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var navigator = window && window.navigator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var MediaStreamTrack = window && window.MediaStreamTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      navigator.getUserMedia = function (constraints, onSuccess, onError) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Replace Firefox 44+'s deprecation warning with unprefixed version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        utils.deprecated('navigator.getUserMedia', 'navigator.mediaDevices.getUserMedia'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(browserDetails.version > 55 && 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var remap = function remap(obj, a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (a in obj && !(b in obj)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            obj[b] = obj[a]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            delete obj[a]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        navigator.mediaDevices.getUserMedia = function (c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (_typeof(c) === 'object' && _typeof(c.audio) === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            c = JSON.parse(JSON.stringify(c)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            remap(c.audio, 'autoGainControl', 'mozAutoGainControl'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeGetUserMedia(c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var nativeGetSettings = MediaStreamTrack.prototype.getSettings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          MediaStreamTrack.prototype.getSettings = function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var obj = nativeGetSettings.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            remap(obj, 'mozAutoGainControl', 'autoGainControl'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            remap(obj, 'mozNoiseSuppression', 'noiseSuppression'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return obj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          MediaStreamTrack.prototype.applyConstraints = function (c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this.kind === 'audio' && _typeof(c) === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              c = JSON.parse(JSON.stringify(c)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              remap(c, 'autoGainControl', 'mozAutoGainControl'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              remap(c, 'noiseSuppression', 'mozNoiseSuppression'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return nativeApplyConstraints.apply(this, [c]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"../utils":10}],9:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimAudioContext = shimAudioContext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimCallbacksAPI = shimCallbacksAPI; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimConstraints = shimConstraints; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimCreateOfferLegacy = shimCreateOfferLegacy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimGetUserMedia = shimGetUserMedia; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimLocalStreamsAPI = shimLocalStreamsAPI; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimRTCIceServerUrls = shimRTCIceServerUrls; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimRemoteStreamsAPI = shimRemoteStreamsAPI; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.shimTrackEventTransceiver = shimTrackEventTransceiver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var utils = _interopRequireWildcard(require("../utils")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimLocalStreamsAPI(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) !== 'object' || !window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._localStreams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._localStreams = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this._localStreams; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('addStream' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _addTrack = window.RTCPeerConnection.prototype.addTrack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.addStream = function addStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._localStreams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._localStreams = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._localStreams.includes(stream)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._localStreams.push(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Try to emulate Chrome's behaviour of adding in audio-video order. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Safari orders by track id. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stream.getAudioTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return _addTrack.call(_this, track, stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stream.getVideoTracks().forEach(function (track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return _addTrack.call(_this, track, stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.addTrack = function addTrack(track) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this2 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var _len = arguments.length, streams = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            streams[_key - 1] = arguments[_key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (streams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            streams.forEach(function (stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (!_this2._localStreams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _this2._localStreams = [stream]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else if (!_this2._localStreams.includes(stream)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _this2._localStreams.push(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return _addTrack.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('removeStream' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var _this3 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._localStreams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this._localStreams = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var index = this._localStreams.indexOf(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (index === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._localStreams.splice(index, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var tracks = stream.getTracks(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.getSenders().forEach(function (sender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (tracks.includes(sender.track)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              _this3.removeTrack(sender); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimRemoteStreamsAPI(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) !== 'object' || !window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.getRemoteStreams = function getRemoteStreams() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this._remoteStreams ? this._remoteStreams : []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!('onaddstream' in window.RTCPeerConnection.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return this._onaddstream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          set: function set(f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var _this4 = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this._onaddstream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.removeEventListener('addstream', this._onaddstream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.removeEventListener('track', this._onaddstreampoly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('addstream', this._onaddstream = f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('track', this._onaddstreampoly = function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              e.streams.forEach(function (stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!_this4._remoteStreams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  _this4._remoteStreams = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (_this4._remoteStreams.includes(stream)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _this4._remoteStreams.push(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var event = new Event('addstream'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.stream = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _this4.dispatchEvent(event); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var pc = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this._onaddstreampoly) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener('track', this._onaddstreampoly = function (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              e.streams.forEach(function (stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!pc._remoteStreams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  pc._remoteStreams = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (pc._remoteStreams.indexOf(stream) >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pc._remoteStreams.push(stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var event = new Event('addstream'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                event.stream = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pc.dispatchEvent(event); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return origSetRemoteDescription.apply(pc, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimCallbacksAPI(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) !== 'object' || !window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var prototype = window.RTCPeerConnection.prototype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origCreateOffer = prototype.createOffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origCreateAnswer = prototype.createAnswer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var setLocalDescription = prototype.setLocalDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var setRemoteDescription = prototype.setRemoteDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var addIceCandidate = prototype.addIceCandidate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prototype.createOffer = function createOffer(successCallback, failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var options = arguments.length >= 2 ? arguments[2] : arguments[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var promise = origCreateOffer.apply(this, [options]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return promise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        promise.then(successCallback, failureCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prototype.createAnswer = function createAnswer(successCallback, failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var options = arguments.length >= 2 ? arguments[2] : arguments[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var promise = origCreateAnswer.apply(this, [options]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return promise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        promise.then(successCallback, failureCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var withCallback = function withCallback(description, successCallback, failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var promise = setLocalDescription.apply(this, [description]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return promise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        promise.then(successCallback, failureCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prototype.setLocalDescription = withCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      withCallback = function withCallback(description, successCallback, failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var promise = setRemoteDescription.apply(this, [description]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return promise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        promise.then(successCallback, failureCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prototype.setRemoteDescription = withCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      withCallback = function withCallback(candidate, successCallback, failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var promise = addIceCandidate.apply(this, [candidate]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!failureCallback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return promise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        promise.then(successCallback, failureCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Promise.resolve(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      prototype.addIceCandidate = withCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimGetUserMedia(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var navigator = window && window.navigator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // shim not needed in Safari 12.1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var mediaDevices = navigator.mediaDevices; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        navigator.mediaDevices.getUserMedia = function (constraints) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return _getUserMedia(shimConstraints(constraints)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!navigator.getUserMedia && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          navigator.mediaDevices.getUserMedia(constraints).then(cb, errcb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }.bind(navigator); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimConstraints(constraints) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (constraints && constraints.video !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Object.assign({}, constraints, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          video: utils.compactObject(constraints.video) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return constraints; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimRTCIceServerUrls(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // migrate from non-spec RTCIceServer.url to RTCIceServer.urls 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var OrigPeerConnection = window.RTCPeerConnection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection = function RTCPeerConnection(pcConfig, pcConstraints) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (pcConfig && pcConfig.iceServers) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var newIceServers = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var i = 0; i < pcConfig.iceServers.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var server = pcConfig.iceServers[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (server.urls === undefined && server.url) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              server = JSON.parse(JSON.stringify(server)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              server.urls = server.url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              delete server.url; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              newIceServers.push(server); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              newIceServers.push(pcConfig.iceServers[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          pcConfig.iceServers = newIceServers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new OrigPeerConnection(pcConfig, pcConstraints); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype = OrigPeerConnection.prototype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // wrap static methods. Currently just generateCertificate. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ('generateCertificate' in OrigPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return OrigPeerConnection.generateCertificate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimTrackEventTransceiver(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Add event.transceiver member over deprecated event.receiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              receiver: this.receiver 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimCreateOfferLegacy(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var origCreateOffer = window.RTCPeerConnection.prototype.createOffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.RTCPeerConnection.prototype.createOffer = function createOffer(offerOptions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (offerOptions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (typeof offerOptions.offerToReceiveAudio !== 'undefined') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // support bit values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var audioTransceiver = this.getTransceivers().find(function (transceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return transceiver.receiver.track.kind === 'audio'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (offerOptions.offerToReceiveAudio === false && audioTransceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (audioTransceiver.direction === 'sendrecv') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (audioTransceiver.setDirection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                audioTransceiver.setDirection('sendonly'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                audioTransceiver.direction = 'sendonly'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (audioTransceiver.direction === 'recvonly') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (audioTransceiver.setDirection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                audioTransceiver.setDirection('inactive'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                audioTransceiver.direction = 'inactive'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addTransceiver('audio', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              direction: 'recvonly' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (typeof offerOptions.offerToReceiveVideo !== 'undefined') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // support bit values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var videoTransceiver = this.getTransceivers().find(function (transceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return transceiver.receiver.track.kind === 'video'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (offerOptions.offerToReceiveVideo === false && videoTransceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (videoTransceiver.direction === 'sendrecv') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (videoTransceiver.setDirection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                videoTransceiver.setDirection('sendonly'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                videoTransceiver.direction = 'sendonly'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (videoTransceiver.direction === 'recvonly') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (videoTransceiver.setDirection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                videoTransceiver.setDirection('inactive'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                videoTransceiver.direction = 'inactive'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addTransceiver('video', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              direction: 'recvonly' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return origCreateOffer.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function shimAudioContext(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (_typeof(window) !== 'object' || window.AudioContext) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      window.AudioContext = window.webkitAudioContext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{"../utils":10}],10:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  Use of this source code is governed by a BSD-style license 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  that can be found in the LICENSE file in the root of the source 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  tree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(exports, "__esModule", { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      value: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.compactObject = compactObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.deprecated = deprecated; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.detectBrowser = detectBrowser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.disableLog = disableLog; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.disableWarnings = disableWarnings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.extractVersion = extractVersion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.filterStats = filterStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.log = log; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.walkStats = walkStats; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exports.wrapPeerConnectionEvent = wrapPeerConnectionEvent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var logDisabled_ = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var deprecationWarnings_ = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Extract browser version out of the provided user agent string. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param {!string} uastring userAgent string. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param {!string} expr Regular expression used as match criteria. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param {!number} pos position in the version string to be returned. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return {!number} browser version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function extractVersion(uastring, expr, pos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var match = uastring.match(expr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return match && match.length >= pos && parseInt(match[pos], 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Wraps the peerconnection event eventNameToWrap in a function 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // which returns the modified event object (or false to prevent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // the event). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!window.RTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var proto = window.RTCPeerConnection.prototype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var nativeAddEventListener = proto.addEventListener; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto.addEventListener = function (nativeEventName, cb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (nativeEventName !== eventNameToWrap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeAddEventListener.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var wrappedCallback = function wrappedCallback(e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var modifiedEvent = wrapper(e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (modifiedEvent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (cb.handleEvent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cb.handleEvent(modifiedEvent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cb(modifiedEvent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._eventMap = this._eventMap || {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!this._eventMap[eventNameToWrap]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this._eventMap[eventNameToWrap] = new Map(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._eventMap[eventNameToWrap].set(cb, wrappedCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return nativeAddEventListener.apply(this, [nativeEventName, wrappedCallback]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var nativeRemoveEventListener = proto.removeEventListener; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto.removeEventListener = function (nativeEventName, cb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[eventNameToWrap]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeRemoveEventListener.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!this._eventMap[eventNameToWrap].has(cb)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return nativeRemoveEventListener.apply(this, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var unwrappedCb = this._eventMap[eventNameToWrap].get(cb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._eventMap[eventNameToWrap]["delete"](cb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this._eventMap[eventNameToWrap].size === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          delete this._eventMap[eventNameToWrap]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Object.keys(this._eventMap).length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          delete this._eventMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return nativeRemoveEventListener.apply(this, [nativeEventName, unwrappedCb]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Object.defineProperty(proto, 'on' + eventNameToWrap, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get: function get() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this['_on' + eventNameToWrap]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        set: function set(cb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (this['_on' + eventNameToWrap]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.removeEventListener(eventNameToWrap, this['_on' + eventNameToWrap]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            delete this['_on' + eventNameToWrap]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (cb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.addEventListener(eventNameToWrap, this['_on' + eventNameToWrap] = cb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        enumerable: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        configurable: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function disableLog(bool) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (typeof bool !== 'boolean') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new Error('Argument type: ' + _typeof(bool) + '. Please use a boolean.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      logDisabled_ = bool; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Disable or enable deprecation warnings 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param {!boolean} bool set to true to disable warnings. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function disableWarnings(bool) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (typeof bool !== 'boolean') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new Error('Argument type: ' + _typeof(bool) + '. Please use a boolean.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      deprecationWarnings_ = !bool; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function log() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (logDisabled_) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (typeof console !== 'undefined' && typeof console.log === 'function') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          console.log.apply(console, arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Shows a deprecation warning suggesting the modern and spec-compatible API. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function deprecated(oldMethod, newMethod) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!deprecationWarnings_) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      console.warn(oldMethod + ' is deprecated, please use ' + newMethod + ' instead.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Browser detector. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return {object} result containing browser and version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *     properties. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function detectBrowser(window) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Returned result object. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var result = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        browser: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        version: null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Fail early if it's not a browser 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (typeof window === 'undefined' || !window.navigator || !window.navigator.userAgent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.browser = 'Not a browser.'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var navigator = window.navigator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Prefer navigator.userAgentData. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (navigator.userAgentData && navigator.userAgentData.brands) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var chromium = navigator.userAgentData.brands.find(function (brand) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return brand.brand === 'Chromium'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (chromium) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            browser: 'chrome', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            version: parseInt(chromium.version, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (navigator.mozGetUserMedia) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Firefox. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.browser = 'firefox'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.version = extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (navigator.webkitGetUserMedia || window.isSecureContext === false && window.webkitRTCPeerConnection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Chrome, Chromium, Webview, Opera. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Version matches Chrome/WebRTC version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Chrome 74 removed webkitGetUserMedia on http as well so we need the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // more complicated fallback to webkitRTCPeerConnection. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.browser = 'chrome'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.version = extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Safari. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.browser = 'safari'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.version = extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.supportsUnifiedPlan = window.RTCRtpTransceiver && 'currentDirection' in window.RTCRtpTransceiver.prototype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Default fallthrough: not supported. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.browser = 'Not a supported browser.'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Checks if something is an object. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param {*} val The something you want to check. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return true if val is an object, false otherwise. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function isObject(val) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Object.prototype.toString.call(val) === '[object Object]'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Remove all empty objects and undefined values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * from a nested object -- an enhanced and vanilla version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * of Lodash's `compact`. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function compactObject(data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!isObject(data)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Object.keys(data).reduce(function (accumulator, key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var isObj = isObject(data[key]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var value = isObj ? compactObject(data[key]) : data[key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var isEmptyObject = isObj && !Object.keys(value).length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (value === undefined || isEmptyObject) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return accumulator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Object.assign(accumulator, _defineProperty({}, key, value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }, {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* iterates the stats graph recursively. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function walkStats(stats, base, resultSet) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!base || resultSet.has(base.id)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      resultSet.set(base.id, base); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      Object.keys(base).forEach(function (name) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (name.endsWith('Id')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          walkStats(stats, stats.get(base[name]), resultSet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (name.endsWith('Ids')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          base[name].forEach(function (id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            walkStats(stats, stats.get(id), resultSet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* filter getStats for a sender/receiver track. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    function filterStats(result, track, outbound) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var filteredResult = new Map(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (track === null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return filteredResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var trackStats = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      result.forEach(function (value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (value.type === 'track' && value.trackIdentifier === track.id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          trackStats.push(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      trackStats.forEach(function (trackStat) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        result.forEach(function (stats) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (stats.type === streamStatsType && stats.trackId === trackStat.id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            walkStats(result, stats, filteredResult); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return filteredResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{}],11:[function(require,module,exports){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* eslint-env node */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // SDP helpers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var SDPUtils = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generate an alphanumeric identifier for cname or mids. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO: use UUIDs instead? https://gist.github.com/jed/982883 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.generateIdentifier = function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Math.random().toString(36).substring(2, 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // The RTCP CNAME used by all peerconnections from the same JS. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.localCName = SDPUtils.generateIdentifier(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Splits SDP into lines, dealing with both CRLF and LF. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.splitLines = function (blob) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return blob.trim().split('\n').map(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return line.trim(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Splits SDP into sessionpart and mediasections. Ensures CRLF. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.splitSections = function (blob) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = blob.split('\nm='); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return parts.map(function (part, index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return (index > 0 ? 'm=' + part : part).trim() + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Returns the session description. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getDescription = function (blob) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sections = SDPUtils.splitSections(blob); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return sections && sections[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Returns the individual media sections. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getMediaSections = function (blob) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sections = SDPUtils.splitSections(blob); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sections.shift(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return sections; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Returns lines that start with a certain prefix. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.matchPrefix = function (blob, prefix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return SDPUtils.splitLines(blob).filter(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return line.indexOf(prefix) === 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses an ICE candidate line. Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // rport 55996" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Input can be prefixed with a=. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseCandidate = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = void 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Parse both variants. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (line.indexOf('a=candidate:') === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts = line.substring(12).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts = line.substring(10).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var candidate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        foundation: parts[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        component: { 1: 'rtp', 2: 'rtcp' }[parts[1]] || parts[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        protocol: parts[2].toLowerCase(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        priority: parseInt(parts[3], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ip: parts[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        address: parts[4], // address is an alias for ip. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        port: parseInt(parts[5], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // skip parts[6] == 'typ' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type: parts[7] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 8; i < parts.length; i += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (parts[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'raddr': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            candidate.relatedAddress = parts[i + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'rport': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            candidate.relatedPort = parseInt(parts[i + 1], 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'tcptype': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            candidate.tcpType = parts[i + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'ufrag': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            candidate.ufrag = parts[i + 1]; // for backward compatibility. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            candidate.usernameFragment = parts[i + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // extension handling, in particular ufrag. Don't overwrite. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (candidate[parts[i]] === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              candidate[parts[i]] = parts[i + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return candidate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Translates a candidate object into SDP candidate attribute. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // This does not include the a= prefix! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeCandidate = function (candidate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sdp = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push(candidate.foundation); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var component = candidate.component; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (component === 'rtp') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (component === 'rtcp') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(component); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push(candidate.protocol.toUpperCase()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push(candidate.priority); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push(candidate.address || candidate.ip); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push(candidate.port); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var type = candidate.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push('typ'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp.push(type); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push('raddr'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(candidate.relatedAddress); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push('rport'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(candidate.relatedPort); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push('tcptype'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(candidate.tcpType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (candidate.usernameFragment || candidate.ufrag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push('ufrag'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp.push(candidate.usernameFragment || candidate.ufrag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'candidate:' + sdp.join(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses an ice-options line, returns an array of option tags. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=ice-options:foo bar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseIceOptions = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return line.substring(14).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=rtpmap:111 opus/48000/2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseRtpMap = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(9).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parsed = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        payloadType: parseInt(parts.shift(), 10) // was: id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parts = parts[0].split('/'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parsed.name = parts[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parsed.clockRate = parseInt(parts[1], 10); // was: clockrate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // legacy alias, got renamed back to channels in ORTC. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      parsed.numChannels = parsed.channels; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return parsed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generates a rtpmap line from RTCRtpCodecCapability or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // RTCRtpCodecParameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeRtpMap = function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pt = codec.payloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (codec.preferredPayloadType !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pt = codec.preferredPayloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var channels = codec.channels || codec.numChannels || 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a extmap line (headerextension from RFC 5285). Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseExtmap = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(9).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        id: parseInt(parts[0], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uri: parts[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        attributes: parts.slice(2).join(' ') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generates an extmap line from RTCRtpHeaderExtensionParameters or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // RTCRtpHeaderExtension. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeExtmap = function (headerExtension) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + (headerExtension.attributes ? ' ' + headerExtension.attributes : '') + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a fmtp line, returns dictionary. Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=fmtp:96 vbr=on;cng=on 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Also deals with vbr=on; cng=on 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseFmtp = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parsed = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var kv = void 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(line.indexOf(' ') + 1).split(';'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var j = 0; j < parts.length; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        kv = parts[j].trim().split('='); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parsed[kv[0].trim()] = kv[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return parsed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeFmtp = function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var line = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pt = codec.payloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (codec.preferredPayloadType !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pt = codec.preferredPayloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (codec.parameters && Object.keys(codec.parameters).length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var params = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Object.keys(codec.parameters).forEach(function (param) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (codec.parameters[param] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            params.push(param + '=' + codec.parameters[param]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            params.push(param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return line; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=rtcp-fb:98 nack rpsi 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseRtcpFb = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(line.indexOf(' ') + 1).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type: parts.shift(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parameter: parts.join(' ') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeRtcpFb = function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pt = codec.payloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (codec.preferredPayloadType !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pt = codec.preferredPayloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (codec.rtcpFeedback && codec.rtcpFeedback.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // FIXME: special handling for trr-int? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        codec.rtcpFeedback.forEach(function (fb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return lines; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a RFC 5576 ssrc media attribute. Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=ssrc:3735928559 cname:something 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseSsrcMedia = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sp = line.indexOf(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ssrc: parseInt(line.substring(7, sp), 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var colon = line.indexOf(':', sp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (colon > -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts.attribute = line.substring(sp + 1, colon); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts.value = line.substring(colon + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts.attribute = line.substring(sp + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return parts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parse a ssrc-group line (see RFC 5576). Sample input: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a=ssrc-group:semantics 12 34 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseSsrcGroup = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(13).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        semantics: parts.shift(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ssrcs: parts.map(function (ssrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return parseInt(ssrc, 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Extracts the MID (RFC 5888) from a media section. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Returns the MID or undefined if no mid line was found. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getMid = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (mid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return mid.substring(6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a fingerprint line for DTLS-SRTP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseFingerprint = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(14).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Extracts DTLS parameters from SDP media section or sessionpart. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // FIXME: for consistency with other functions this should only 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //   get the fingerprint line as input. See also getIceParameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Note: a=setup line is ignored since we use the 'auto' role in Edge. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        role: 'auto', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fingerprints: lines.map(SDPUtils.parseFingerprint) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Serializes DTLS parameters to SDP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeDtlsParameters = function (params, setupType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sdp = 'a=setup:' + setupType + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      params.fingerprints.forEach(function (fp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses a=crypto lines into 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //   https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseCryptoLine = function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(9).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tag: parseInt(parts[0], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cryptoSuite: parts[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        keyParams: parts[2], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sessionParams: parts.slice(3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeCryptoLine = function (parameters) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (_typeof(parameters.keyParams) === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses the crypto key parameters into 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //   https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseCryptoKeyParams = function (keyParams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (keyParams.indexOf('inline:') !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = keyParams.substring(7).split('|'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        keyMethod: 'inline', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        keySalt: parts[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        lifeTime: parts[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mkiValue: parts[2] ? parts[2].split(':')[0] : undefined, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mkiLength: parts[2] ? parts[2].split(':')[1] : undefined 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeCryptoKeyParams = function (keyParams) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : ''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Extracts all SDES parameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return lines.map(SDPUtils.parseCryptoLine); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses ICE information from SDP media section or sessionpart. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // FIXME: for consistency with other functions this should only 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //   get the ice-ufrag and ice-pwd lines as input. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getIceParameters = function (mediaSection, sessionpart) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!(ufrag && pwd)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        usernameFragment: ufrag.substring(12), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        password: pwd.substring(10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Serializes ICE parameters to SDP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeIceParameters = function (params) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (params.iceLite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += 'a=ice-lite\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses the SDP media section and returns RTCRtpParameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseRtpParameters = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var description = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        codecs: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        headerExtensions: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fecMechanisms: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rtcp: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.splitLines(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var mline = lines[0].split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      description.profile = mline[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 3; i < mline.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // find all codecs from mline[3..] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var pt = mline[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (rtpmapline) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var codec = SDPUtils.parseRtpMap(rtpmapline); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Only the first a=fmtp:<pt> is considered. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          description.codecs.push(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // parse FEC mechanisms from rtpmap lines. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          switch (codec.name.toUpperCase()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'RED': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 'ULPFEC': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              description.fecMechanisms.push(codec.name.toUpperCase()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // only RED and ULPFEC are recognized as FEC mechanisms. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        description.headerExtensions.push(SDPUtils.parseExtmap(line)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ').map(SDPUtils.parseRtcpFb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      description.codecs.forEach(function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        wildcardRtcpFb.forEach(function (fb) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var duplicate = codec.rtcpFeedback.find(function (existingFeedback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!duplicate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            codec.rtcpFeedback.push(fb); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // FIXME: parse rtcp. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return description; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generates parts of the SDP media section describing the capabilities / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // parameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeRtpDescription = function (kind, caps) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sdp = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Build the mline. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp += 'm=' + kind + ' '; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' '; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp += caps.codecs.map(function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (codec.preferredPayloadType !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return codec.preferredPayloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return codec.payloadType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }).join(' ') + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp += 'c=IN IP4 0.0.0.0\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      caps.codecs.forEach(function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += SDPUtils.writeRtpMap(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += SDPUtils.writeFmtp(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += SDPUtils.writeRtcpFb(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maxptime = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      caps.codecs.forEach(function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (codec.maxptime > maxptime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          maxptime = codec.maxptime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (maxptime > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += 'a=maxptime:' + maxptime + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (caps.headerExtensions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        caps.headerExtensions.forEach(function (extension) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sdp += SDPUtils.writeExtmap(extension); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // FIXME: write fecMechanisms. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Parses the SDP media section and returns an array of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // RTCRtpEncodingParameters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseRtpEncodingParameters = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var encodingParameters = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var description = SDPUtils.parseRtpParameters(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var hasRed = description.fecMechanisms.indexOf('RED') !== -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // filter a=ssrc:... cname:, ignore PlanB-msid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return SDPUtils.parseSsrcMedia(line); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }).filter(function (parts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return parts.attribute === 'cname'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var secondarySsrc = void 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var parts = line.substring(17).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return parts.map(function (part) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return parseInt(part, 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        secondarySsrc = flows[0][1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      description.codecs.forEach(function (codec) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var encParam = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ssrc: primarySsrc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            codecPayloadType: parseInt(codec.parameters.apt, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (primarySsrc && secondarySsrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encParam.rtx = { ssrc: secondarySsrc }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          encodingParameters.push(encParam); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (hasRed) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encParam = JSON.parse(JSON.stringify(encParam)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encParam.fec = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              ssrc: primarySsrc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              mechanism: hasUlpfec ? 'red+ulpfec' : 'red' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encodingParameters.push(encParam); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (encodingParameters.length === 0 && primarySsrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        encodingParameters.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ssrc: primarySsrc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // we support both b=AS and b=TIAS but interpret AS as TIAS. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b='); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (bandwidth.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (bandwidth[0].indexOf('b=TIAS:') === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          bandwidth = parseInt(bandwidth[0].substring(7), 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (bandwidth[0].indexOf('b=AS:') === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // use formula from JSEP to convert b=AS to TIAS value. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95 - 50 * 40 * 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          bandwidth = undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        encodingParameters.forEach(function (params) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          params.maxBitrate = bandwidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return encodingParameters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // parses http://draft.ortc.org/#rtcrtcpparameters* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseRtcpParameters = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var rtcpParameters = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Gets the first SSRC. Note that with RTX there might be multiple 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // SSRCs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return SDPUtils.parseSsrcMedia(line); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }).filter(function (obj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return obj.attribute === 'cname'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      })[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (remoteSsrc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rtcpParameters.cname = remoteSsrc.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rtcpParameters.ssrc = remoteSsrc.ssrc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Edge uses the compound attribute instead of reducedSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // compound is !reducedSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rtcpParameters.reducedSize = rsize.length > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rtcpParameters.compound = rsize.length === 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // parses the rtcp-mux attrіbute. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Note that Edge does not support unmuxed RTCP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rtcpParameters.mux = mux.length > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return rtcpParameters; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeRtcpParameters = function (rtcpParameters) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sdp = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (rtcpParameters.reducedSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += 'a=rtcp-rsize\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (rtcpParameters.mux) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += 'a=rtcp-mux\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return sdp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // parses either a=msid: or a=ssrc:... msid lines and returns 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // the id of the MediaStream and MediaStreamTrack. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseMsid = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = void 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (spec.length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts = spec[0].substring(7).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { stream: parts[0], track: parts[1] }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return SDPUtils.parseSsrcMedia(line); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }).filter(function (msidParts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return msidParts.attribute === 'msid'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (planB.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        parts = planB[0].value.split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { stream: parts[0], track: parts[1] }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // SCTP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // to draft-ietf-mmusic-sctp-sdp-05 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseSctpDescription = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var mline = SDPUtils.parseMLine(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maxMessageSize = void 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (maxSizeLine.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isNaN(maxMessageSize)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maxMessageSize = 65536; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sctpPort.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          port: parseInt(sctpPort[0].substring(12), 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          protocol: mline.fmt, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          maxMessageSize: maxMessageSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sctpMapLines.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var parts = sctpMapLines[0].substring(10).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          port: parseInt(parts[0], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          protocol: parts[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          maxMessageSize: maxMessageSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // SCTP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // support by now receiving in this format, unless we originally parsed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // protocol of DTLS/SCTP -- without UDP/ or TCP/) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeSctpDescription = function (media, sctp) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var output = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (media.protocol !== 'DTLS/SCTP') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sctp.maxMessageSize !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return output.join(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Generate a session ID for SDP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // recommends using a cryptographically random +ve 64-bit value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // but right now this should be acceptable and within the right range 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.generateSessionId = function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Math.random().toString().substr(2, 22); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Write boiler plate for start of SDP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // sessId argument is optional - if not supplied it will 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // be generated randomly 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // sessVersion is optional and defaults to 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // sessUser is optional and defaults to 'thisisadapterortc' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sessionId = void 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var version = sessVer !== undefined ? sessVer : 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sessId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sessionId = sessId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sessionId = SDPUtils.generateSessionId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var user = sessUser || 'thisisadapterortc'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // FIXME: sess-id should be an NTP timestamp. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Gets the direction from the mediaSection or the sessionpart. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getDirection = function (mediaSection, sessionpart) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.splitLines(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0; i < lines.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (lines[i]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'a=sendrecv': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'a=sendonly': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'a=recvonly': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'a=inactive': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return lines[i].substring(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // FIXME: What should happen here? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sessionpart) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return SDPUtils.getDirection(sessionpart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return 'sendrecv'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.getKind = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.splitLines(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var mline = lines[0].split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return mline[0].substring(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.isRejected = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return mediaSection.split(' ', 2)[1] === '0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseMLine = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.splitLines(mediaSection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = lines[0].substring(2).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        kind: parts[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        port: parseInt(parts[1], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        protocol: parts[2], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fmt: parts.slice(3).join(' ') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.parseOLine = function (mediaSection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var parts = line.substring(2).split(' '); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        username: parts[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sessionId: parts[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sessionVersion: parseInt(parts[2], 10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        netType: parts[3], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        addressType: parts[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        address: parts[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // a very naive interpretation of a valid SDP. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SDPUtils.isValidSDP = function (blob) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (typeof blob !== 'string' || blob.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lines = SDPUtils.splitLines(blob); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0; i < lines.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (lines[i].length < 2 || lines[i].charAt(1) !== '=') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: check the modifier a bit more. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Expose public methods. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      module.exports = SDPUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    },{}]},{},[1])(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 |