diff --git a/resources/html/webrtcgateway/index.html b/resources/html/webrtcgateway/index.html index 3f0f9f1..05aff9e 100644 --- a/resources/html/webrtcgateway/index.html +++ b/resources/html/webrtcgateway/index.html @@ -1,47 +1,46 @@ SylkServer WebRTC gateway

SylkServer WebRTC gateway

Overview

Welcome to the SylkServer WebRTC gateway application!

This application enables web based clients to communicate transparently with SIP endpoints using WebRTC suite of standards and protocols.

Features

Server software

Client software

Live service

diff --git a/resources/html/webrtcgateway/js/sylkrtc.js b/resources/html/webrtcgateway/js/sylkrtc.js deleted file mode 100644 index a5ace24..0000000 --- a/resources/html/webrtcgateway/js/sylkrtc.js +++ /dev/null @@ -1,4478 +0,0 @@ -/* - * sylkrtc.js v0.1.2 - * SylkServer WebRTC Gateway client library - * Copyright 2015 AG Projects - * License MIT - */ - -(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.sylkrtc = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o %s', this._state, newState); - var oldState = this._state; - this._state = newState; - this.emit('stateChanged', oldState, newState); - } - }, { - key: '_onOpen', - - // WebSocket callbacks - - value: function _onOpen() { - clearTimeout(this._timer); - this._timer = null; - this._delay = INITIAL_DELAY; - this._setState('connected'); - } - }, { - key: '_onClose', - value: function _onClose() { - var _this5 = this; - - this._sock = null; - if (this._timer) { - clearTimeout(this._timer); - this._timer = null; - } - - // remove all accounts, the server no longer has them anyway - this._accounts.clear(); - - this._setState('disconnected'); - if (!this._closed) { - this._delay = this._delay * 2; - if (this._delay > Number.MAX_VALUE) { - this._delay = INITIAL_DELAY; - } - DEBUG('Retrying connection in %s seconds', this._delay / 1000); - this._timer = setTimeout(function () { - _this5._connect(); - }, this._delay); - } else { - this._setState('closed'); - } - } - }, { - key: '_onMessage', - value: function _onMessage(event) { - var message = JSON.parse(event.data); - if (typeof message.sylkrtc === 'undefined') { - DEBUG('Unrecognized message received'); - return; - } - - DEBUG('Received "%s" message: %o', message.sylkrtc, message); - - if (message.sylkrtc === 'event') { - DEBUG('Received event: "%s"', message.event); - switch (message.event) { - case 'ready': - this._setState('ready'); - break; - default: - break; - } - } else if (message.sylkrtc === 'account_event') { - var acc = this._accounts.get(message.account); - if (!acc) { - DEBUG('Account %s not found', message.account); - return; - } - acc._handleEvent(message); - } else if (message.sylkrtc === 'session_event') { - var sessionId = message.session; - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = this._accounts.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var acc = _step.value; - - var call = acc._calls.get(sessionId); - if (call) { - call._handleEvent(message); - break; - } - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator['return']) { - _iterator['return'](); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - } else if (message.sylkrtc === 'ack' || message.sylkrtc === 'error') { - var transaction = message.transaction; - var data = this._requests.get(transaction); - if (!data) { - DEBUG('Could not find transaction %s', transaction); - return; - } - this._requests['delete'](transaction); - DEBUG('Received "%s" for request: %o', message.sylkrtc, data.req); - if (data.cb) { - if (message.sylkrtc === 'ack') { - data.cb(null); - } else { - data.cb(new Error(message.error)); - } - } - } - } - }, { - key: 'state', - get: function get() { - return this._state; - } - }]); - - return Connection; -})(_events.EventEmitter); - -exports.Connection = Connection; - -}).call(this,require('_process')) - -},{"./account":1,"_process":7,"debug":9,"events":6,"node-uuid":12,"timers":8,"websocket":20}],4:[function(require,module,exports){ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { 'default': obj }; -} - -var _debug = require('debug'); - -var _debug2 = _interopRequireDefault(_debug); - -var _rtcninja = require('rtcninja'); - -var _rtcninja2 = _interopRequireDefault(_rtcninja); - -var _connection = require('./connection'); - -// Public API - -function createConnection() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - if (!_rtcninja2['default'].hasWebRTC()) { - throw new Error('WebRTC support not detected'); - } - - var conn = new _connection.Connection(options); - conn._initialize(); - return conn; -} - -// Some proxied functions from rtcninja - -function isWebRTCSupported() { - return _rtcninja2['default'].hasWebRTC(); -} - -function attachMediaStream(element, stream) { - return _rtcninja2['default'].attachMediaStream(element, stream); -} - -function closeMediaStream(stream) { - _rtcninja2['default'].closeMediaStream(stream); -} - -exports['default'] = { - createConnection: createConnection, - debug: _debug2['default'], - attachMediaStream: attachMediaStream, closeMediaStream: closeMediaStream, isWebRTCSupported: isWebRTCSupported -}; -module.exports = exports['default']; - -},{"./connection":3,"debug":9,"rtcninja":15}],5:[function(require,module,exports){ -/* - * JavaScript MD5 1.0.1 - * https://github.com/blueimp/JavaScript-MD5 - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - * - * Based on - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * Digest Algorithm, as defined in RFC 1321. - * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for more info. - */ - -/*jslint bitwise: true */ -/*global unescape, define */ - -(function ($) { - 'use strict'; - - /* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ - function safe_add(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), - msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); - } - - /* - * Bitwise rotate a 32-bit number to the left. - */ - function bit_rol(num, cnt) { - return (num << cnt) | (num >>> (32 - cnt)); - } - - /* - * These functions implement the four basic operations the algorithm uses. - */ - function md5_cmn(q, a, b, x, s, t) { - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); - } - function md5_ff(a, b, c, d, x, s, t) { - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); - } - function md5_gg(a, b, c, d, x, s, t) { - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); - } - function md5_hh(a, b, c, d, x, s, t) { - return md5_cmn(b ^ c ^ d, a, b, x, s, t); - } - function md5_ii(a, b, c, d, x, s, t) { - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); - } - - /* - * Calculate the MD5 of an array of little-endian words, and a bit length. - */ - function binl_md5(x, len) { - /* append padding */ - x[len >> 5] |= 0x80 << (len % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; - - var i, olda, oldb, oldc, oldd, - a = 1732584193, - b = -271733879, - c = -1732584194, - d = 271733878; - - for (i = 0; i < x.length; i += 16) { - olda = a; - oldb = b; - oldc = c; - oldd = d; - - a = md5_ff(a, b, c, d, x[i], 7, -680876936); - d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); - d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); - d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); - b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); - d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); - - a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); - d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); - c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i], 20, -373897302); - a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); - d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); - c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); - d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); - c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); - d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); - c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); - - a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); - d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); - d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); - d = md5_hh(d, a, b, c, x[i], 11, -358537222); - c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); - d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); - - a = md5_ii(a, b, c, d, x[i], 6, -198630844); - d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); - d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); - d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); - d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return [a, b, c, d]; - } - - /* - * Convert an array of little-endian words to a string - */ - function binl2rstr(input) { - var i, - output = ''; - for (i = 0; i < input.length * 32; i += 8) { - output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); - } - return output; - } - - /* - * Convert a raw string to an array of little-endian words - * Characters >255 have their high-byte silently ignored. - */ - function rstr2binl(input) { - var i, - output = []; - output[(input.length >> 2) - 1] = undefined; - for (i = 0; i < output.length; i += 1) { - output[i] = 0; - } - for (i = 0; i < input.length * 8; i += 8) { - output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); - } - return output; - } - - /* - * Calculate the MD5 of a raw string - */ - function rstr_md5(s) { - return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); - } - - /* - * Calculate the HMAC-MD5, of a key and some data (raw strings) - */ - function rstr_hmac_md5(key, data) { - var i, - bkey = rstr2binl(key), - ipad = [], - opad = [], - hash; - ipad[15] = opad[15] = undefined; - if (bkey.length > 16) { - bkey = binl_md5(bkey, key.length * 8); - } - for (i = 0; i < 16; i += 1) { - ipad[i] = bkey[i] ^ 0x36363636; - opad[i] = bkey[i] ^ 0x5C5C5C5C; - } - hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); - return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); - } - - /* - * Convert a raw string to a hex string - */ - function rstr2hex(input) { - var hex_tab = '0123456789abcdef', - output = '', - x, - i; - for (i = 0; i < input.length; i += 1) { - x = input.charCodeAt(i); - output += hex_tab.charAt((x >>> 4) & 0x0F) + - hex_tab.charAt(x & 0x0F); - } - return output; - } - - /* - * Encode a string as utf-8 - */ - function str2rstr_utf8(input) { - return unescape(encodeURIComponent(input)); - } - - /* - * Take string arguments and return either raw or hex encoded strings - */ - function raw_md5(s) { - return rstr_md5(str2rstr_utf8(s)); - } - function hex_md5(s) { - return rstr2hex(raw_md5(s)); - } - function raw_hmac_md5(k, d) { - return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)); - } - function hex_hmac_md5(k, d) { - return rstr2hex(raw_hmac_md5(k, d)); - } - - function md5(string, key, raw) { - if (!key) { - if (!raw) { - return hex_md5(string); - } - return raw_md5(string); - } - if (!raw) { - return hex_hmac_md5(key, string); - } - return raw_hmac_md5(key, string); - } - - if (typeof define === 'function' && define.amd) { - define(function () { - return md5; - }); - } else { - $.md5 = md5; - } -}(this)); - -},{}],6:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); - } - } - - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} - -},{}],7:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = setTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - currentQueue[queueIndex].run(); - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - clearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - setTimeout(drainQueue, 0); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],8:[function(require,module,exports){ -var nextTick = require('process/browser.js').nextTick; -var apply = Function.prototype.apply; -var slice = Array.prototype.slice; -var immediateIds = {}; -var nextImmediateId = 0; - -// DOM APIs, for completeness - -exports.setTimeout = function() { - return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); -}; -exports.setInterval = function() { - return new Timeout(apply.call(setInterval, window, arguments), clearInterval); -}; -exports.clearTimeout = -exports.clearInterval = function(timeout) { timeout.close(); }; - -function Timeout(id, clearFn) { - this._id = id; - this._clearFn = clearFn; -} -Timeout.prototype.unref = Timeout.prototype.ref = function() {}; -Timeout.prototype.close = function() { - this._clearFn.call(window, this._id); -}; - -// Does not start the time, just sets up the members needed. -exports.enroll = function(item, msecs) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = msecs; -}; - -exports.unenroll = function(item) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = -1; -}; - -exports._unrefActive = exports.active = function(item) { - clearTimeout(item._idleTimeoutId); - - var msecs = item._idleTimeout; - if (msecs >= 0) { - item._idleTimeoutId = setTimeout(function onTimeout() { - if (item._onTimeout) - item._onTimeout(); - }, msecs); - } -}; - -// That's not how node.js implements it but the exposed api is the same. -exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { - var id = nextImmediateId++; - var args = arguments.length < 2 ? false : slice.call(arguments, 1); - - immediateIds[id] = true; - - nextTick(function onNextTick() { - if (immediateIds[id]) { - // fn.call() is faster so we optimize for the common use-case - // @see http://jsperf.com/call-apply-segu - if (args) { - fn.apply(null, args); - } else { - fn.call(null); - } - // Prevent ids from leaking - exports.clearImmediate(id); - } - }); - - return id; -}; - -exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { - delete immediateIds[id]; -}; -},{"process/browser.js":7}],9:[function(require,module,exports){ - -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = require('./debug'); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ - -exports.colors = [ - 'lightseagreen', - 'forestgreen', - 'goldenrod', - 'dodgerblue', - 'darkorchid', - 'crimson' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -function useColors() { - // is webkit? http://stackoverflow.com/a/16459606/376773 - return ('WebkitAppearance' in document.documentElement.style) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (window.console && (console.firebug || (console.exception && console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -exports.formatters.j = function(v) { - return JSON.stringify(v); -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs() { - var args = arguments; - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - - if (!useColors) return args; - - var c = 'color: ' + this.color; - args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); - - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); - return args; -} - -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} - return r; -} - -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage(){ - try { - return window.localStorage; - } catch (e) {} -} - -},{"./debug":10}],10:[function(require,module,exports){ - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = debug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = require('ms'); - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lowercased letter, i.e. "n". - */ - -exports.formatters = {}; - -/** - * Previously assigned color. - */ - -var prevColor = 0; - -/** - * Previous log timestamp. - */ - -var prevTime; - -/** - * Select a color. - * - * @return {Number} - * @api private - */ - -function selectColor() { - return exports.colors[prevColor++ % exports.colors.length]; -} - -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - -function debug(namespace) { - - // define the `disabled` version - function disabled() { - } - disabled.enabled = false; - - // define the `enabled` version - function enabled() { - - var self = enabled; - - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - // add the `color` if not set - if (null == self.useColors) self.useColors = exports.useColors(); - if (null == self.color && self.useColors) self.color = selectColor(); - - var args = Array.prototype.slice.call(arguments); - - args[0] = exports.coerce(args[0]); - - if ('string' !== typeof args[0]) { - // anything else let's inspect with %o - args = ['%o'].concat(args); - } - - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); - - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - if ('function' === typeof exports.formatArgs) { - args = exports.formatArgs.apply(self, args); - } - var logFn = enabled.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } - enabled.enabled = true; - - var fn = exports.enabled(namespace) ? enabled : disabled; - - fn.namespace = namespace; - - return fn; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - var split = (namespaces || '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } - } - return false; -} - -/** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} - -},{"ms":11}],11:[function(require,module,exports){ -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} options - * @return {String|Number} - * @api public - */ - -module.exports = function(val, options){ - options = options || {}; - if ('string' == typeof val) return parse(val); - return options.long - ? long(val) - : short(val); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse(str) { - str = '' + str; - if (str.length > 10000) return; - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); - if (!match) return; - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function short(ms) { - if (ms >= d) return Math.round(ms / d) + 'd'; - if (ms >= h) return Math.round(ms / h) + 'h'; - if (ms >= m) return Math.round(ms / m) + 'm'; - if (ms >= s) return Math.round(ms / s) + 's'; - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function long(ms) { - return plural(ms, d, 'day') - || plural(ms, h, 'hour') - || plural(ms, m, 'minute') - || plural(ms, s, 'second') - || ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural(ms, n, name) { - if (ms < n) return; - if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; - return Math.ceil(ms / n) + ' ' + name + 's'; -} - -},{}],12:[function(require,module,exports){ -// uuid.js -// -// Copyright (c) 2010-2012 Robert Kieffer -// MIT License - http://opensource.org/licenses/mit-license.php - -(function() { - var _global = this; - - // Unique ID creation requires a high quality random # generator. We feature - // detect to determine the best RNG source, normalizing to a function that - // returns 128-bits of randomness, since that's what's usually required - var _rng; - - // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html - // - // Moderately fast, high quality - if (typeof(_global.require) == 'function') { - try { - var _rb = _global.require('crypto').randomBytes; - _rng = _rb && function() {return _rb(16);}; - } catch(e) {} - } - - if (!_rng && _global.crypto && crypto.getRandomValues) { - // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto - // - // Moderately fast, high quality - var _rnds8 = new Uint8Array(16); - _rng = function whatwgRNG() { - crypto.getRandomValues(_rnds8); - return _rnds8; - }; - } - - if (!_rng) { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var _rnds = new Array(16); - _rng = function() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return _rnds; - }; - } - - // Buffer class to use - var BufferClass = typeof(_global.Buffer) == 'function' ? _global.Buffer : Array; - - // Maps for number <-> hex string conversion - var _byteToHex = []; - var _hexToByte = {}; - for (var i = 0; i < 256; i++) { - _byteToHex[i] = (i + 0x100).toString(16).substr(1); - _hexToByte[_byteToHex[i]] = i; - } - - // **`parse()` - Parse a UUID into it's component bytes** - function parse(s, buf, offset) { - var i = (buf && offset) || 0, ii = 0; - - buf = buf || []; - s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) { - if (ii < 16) { // Don't overflow! - buf[i + ii++] = _hexToByte[oct]; - } - }); - - // Zero out remaining bytes if string was short - while (ii < 16) { - buf[i + ii++] = 0; - } - - return buf; - } - - // **`unparse()` - Convert UUID byte array (ala parse()) into a string** - function unparse(buf, offset) { - var i = offset || 0, bth = _byteToHex; - return bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + '-' + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]] + - bth[buf[i++]] + bth[buf[i++]]; - } - - // **`v1()` - Generate time-based UUID** - // - // Inspired by https://github.com/LiosK/UUID.js - // and http://docs.python.org/library/uuid.html - - // random #'s we need to init node and clockseq - var _seedBytes = _rng(); - - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - var _nodeId = [ - _seedBytes[0] | 0x01, - _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5] - ]; - - // Per 4.2.2, randomize (14 bit) clockseq - var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff; - - // Previous uuid creation time - var _lastMSecs = 0, _lastNSecs = 0; - - // See https://github.com/broofa/node-uuid for API details - function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - - var clockseq = options.clockseq != null ? options.clockseq : _clockseq; - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs != null ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq == null) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - var node = options.node || _nodeId; - for (var n = 0; n < 6; n++) { - b[i + n] = node[n]; - } - - return buf ? buf : unparse(b); - } - - // **`v4()` - Generate random UUID** - - // See https://github.com/broofa/node-uuid for API details - function v4(options, buf, offset) { - // Deprecated - 'format' argument, as supported in v1.2 - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options == 'binary' ? new BufferClass(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || _rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ii++) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || unparse(rnds); - } - - // Export public API - var uuid = v4; - uuid.v1 = v1; - uuid.v4 = v4; - uuid.parse = parse; - uuid.unparse = unparse; - uuid.BufferClass = BufferClass; - - if (typeof(module) != 'undefined' && module.exports) { - // Publish as node.js module - module.exports = uuid; - } else if (typeof define === 'function' && define.amd) { - // Publish as AMD module - define(function() {return uuid;}); - - - } else { - // Publish as global (in browsers) - var _previousRoot = _global.uuid; - - // **`noConflict()` - (browser only) to reset global 'uuid' var** - uuid.noConflict = function() { - _global.uuid = _previousRoot; - return uuid; - }; - - _global.uuid = uuid; - } -}).call(this); - -},{}],13:[function(require,module,exports){ -(function (global){ -'use strict'; - -// Expose the Adapter function/object. -module.exports = Adapter; - - -// Dependencies - -var browser = require('bowser'), - debug = require('debug')('rtcninja:Adapter'), - debugerror = require('debug')('rtcninja:ERROR:Adapter'), - - // Internal vars - getUserMedia = null, - RTCPeerConnection = null, - RTCSessionDescription = null, - RTCIceCandidate = null, - MediaStreamTrack = null, - getMediaDevices = null, - attachMediaStream = null, - canRenegotiate = false, - oldSpecRTCOfferOptions = false, - browserVersion = Number(browser.version) || 0, - isDesktop = !!(!browser.mobile && !browser.tablet), - hasWebRTC = false, - virtGlobal, virtNavigator; - -debugerror.log = console.warn.bind(console); - -// Dirty trick to get this library working in a Node-webkit env with browserified libs -virtGlobal = global.window || global; -// Don't fail in Node -virtNavigator = virtGlobal.navigator || {}; - - -// Constructor. - -function Adapter(options) { - // Chrome desktop, Chrome Android, Opera desktop, Opera Android, Android native browser - // or generic Webkit browser. - if ( - (isDesktop && browser.chrome && browserVersion >= 32) || - (browser.android && browser.chrome && browserVersion >= 39) || - (isDesktop && browser.opera && browserVersion >= 27) || - (browser.android && browser.opera && browserVersion >= 24) || - (browser.android && browser.webkit && !browser.chrome && browserVersion >= 37) || - (virtNavigator.webkitGetUserMedia && virtGlobal.webkitRTCPeerConnection) - ) { - hasWebRTC = true; - getUserMedia = virtNavigator.webkitGetUserMedia.bind(virtNavigator); - RTCPeerConnection = virtGlobal.webkitRTCPeerConnection; - RTCSessionDescription = virtGlobal.RTCSessionDescription; - RTCIceCandidate = virtGlobal.RTCIceCandidate; - MediaStreamTrack = virtGlobal.MediaStreamTrack; - if (MediaStreamTrack && MediaStreamTrack.getSources) { - getMediaDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack); - } else if (virtNavigator.getMediaDevices) { - getMediaDevices = virtNavigator.getMediaDevices.bind(virtNavigator); - } - attachMediaStream = function (element, stream) { - element.src = URL.createObjectURL(stream); - return element; - }; - canRenegotiate = true; - oldSpecRTCOfferOptions = false; - // Firefox desktop, Firefox Android. - } else if ( - (isDesktop && browser.firefox && browserVersion >= 22) || - (browser.android && browser.firefox && browserVersion >= 33) || - (virtNavigator.mozGetUserMedia && virtGlobal.mozRTCPeerConnection) - ) { - hasWebRTC = true; - getUserMedia = virtNavigator.mozGetUserMedia.bind(virtNavigator); - RTCPeerConnection = virtGlobal.mozRTCPeerConnection; - RTCSessionDescription = virtGlobal.mozRTCSessionDescription; - RTCIceCandidate = virtGlobal.mozRTCIceCandidate; - MediaStreamTrack = virtGlobal.MediaStreamTrack; - attachMediaStream = function (element, stream) { - element.src = URL.createObjectURL(stream); - return element; - }; - canRenegotiate = false; - oldSpecRTCOfferOptions = false; - // WebRTC plugin required. For example IE or Safari with the Temasys plugin. - } else if ( - options.plugin && - typeof options.plugin.isRequired === 'function' && - options.plugin.isRequired() && - typeof options.plugin.isInstalled === 'function' && - options.plugin.isInstalled() - ) { - var pluginiface = options.plugin.interface; - - hasWebRTC = true; - getUserMedia = pluginiface.getUserMedia; - RTCPeerConnection = pluginiface.RTCPeerConnection; - RTCSessionDescription = pluginiface.RTCSessionDescription; - RTCIceCandidate = pluginiface.RTCIceCandidate; - MediaStreamTrack = pluginiface.MediaStreamTrack; - if (MediaStreamTrack && MediaStreamTrack.getSources) { - getMediaDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack); - } else if (virtNavigator.getMediaDevices) { - getMediaDevices = virtNavigator.getMediaDevices.bind(virtNavigator); - } - attachMediaStream = pluginiface.attachMediaStream; - canRenegotiate = pluginiface.canRenegotiate; - oldSpecRTCOfferOptions = true; // TODO: Update when fixed in the plugin. - // Best effort (may be adater.js is loaded). - } else if (virtNavigator.getUserMedia && virtGlobal.RTCPeerConnection) { - hasWebRTC = true; - getUserMedia = virtNavigator.getUserMedia.bind(virtNavigator); - RTCPeerConnection = virtGlobal.RTCPeerConnection; - RTCSessionDescription = virtGlobal.RTCSessionDescription; - RTCIceCandidate = virtGlobal.RTCIceCandidate; - MediaStreamTrack = virtGlobal.MediaStreamTrack; - if (MediaStreamTrack && MediaStreamTrack.getSources) { - getMediaDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack); - } else if (virtNavigator.getMediaDevices) { - getMediaDevices = virtNavigator.getMediaDevices.bind(virtNavigator); - } - attachMediaStream = virtGlobal.attachMediaStream || function (element, stream) { - element.src = URL.createObjectURL(stream); - return element; - }; - canRenegotiate = false; - oldSpecRTCOfferOptions = false; - } - - - function throwNonSupported(item) { - return function () { - throw new Error('rtcninja: WebRTC not supported, missing ' + item + - ' [browser: ' + browser.name + ' ' + browser.version + ']'); - }; - } - - - // Public API. - - // Expose a WebRTC checker. - Adapter.hasWebRTC = function () { - return hasWebRTC; - }; - - // Expose getUserMedia. - if (getUserMedia) { - Adapter.getUserMedia = function (constraints, successCallback, errorCallback) { - debug('getUserMedia() | constraints: %o', constraints); - - try { - getUserMedia(constraints, - function (stream) { - debug('getUserMedia() | success'); - if (successCallback) { - successCallback(stream); - } - }, - function (error) { - debug('getUserMedia() | error:', error); - if (errorCallback) { - errorCallback(error); - } - } - ); - } - catch (error) { - debugerror('getUserMedia() | error:', error); - if (errorCallback) { - errorCallback(error); - } - } - }; - } else { - Adapter.getUserMedia = function (constraints, successCallback, errorCallback) { - debugerror('getUserMedia() | WebRTC not supported'); - if (errorCallback) { - errorCallback(new Error('rtcninja: WebRTC not supported, missing ' + - 'getUserMedia [browser: ' + browser.name + ' ' + browser.version + ']')); - } else { - throwNonSupported('getUserMedia'); - } - }; - } - - // Expose RTCPeerConnection. - Adapter.RTCPeerConnection = RTCPeerConnection || throwNonSupported('RTCPeerConnection'); - - // Expose RTCSessionDescription. - Adapter.RTCSessionDescription = RTCSessionDescription || throwNonSupported('RTCSessionDescription'); - - // Expose RTCIceCandidate. - Adapter.RTCIceCandidate = RTCIceCandidate || throwNonSupported('RTCIceCandidate'); - - // Expose MediaStreamTrack. - Adapter.MediaStreamTrack = MediaStreamTrack || throwNonSupported('MediaStreamTrack'); - - // Expose getMediaDevices. - Adapter.getMediaDevices = getMediaDevices; - - // Expose MediaStreamTrack. - Adapter.attachMediaStream = attachMediaStream || throwNonSupported('attachMediaStream'); - - // Expose canRenegotiate attribute. - Adapter.canRenegotiate = canRenegotiate; - - // Expose closeMediaStream. - Adapter.closeMediaStream = function (stream) { - if (!stream) { - return; - } - - // Latest spec states that MediaStream has no stop() method and instead must - // call stop() on every MediaStreamTrack. - if (MediaStreamTrack && MediaStreamTrack.prototype && MediaStreamTrack.prototype.stop) { - debug('closeMediaStream() | calling stop() on all the MediaStreamTrack'); - - var tracks, i, len; - - if (stream.getTracks) { - tracks = stream.getTracks(); - for (i = 0, len = tracks.length; i < len; i += 1) { - tracks[i].stop(); - } - } else { - tracks = stream.getAudioTracks(); - for (i = 0, len = tracks.length; i < len; i += 1) { - tracks[i].stop(); - } - - tracks = stream.getVideoTracks(); - for (i = 0, len = tracks.length; i < len; i += 1) { - tracks[i].stop(); - } - } - // Deprecated by the spec, but still in use. - } else if (typeof stream.stop === 'function') { - debug('closeMediaStream() | calling stop() on the MediaStream'); - - stream.stop(); - } - }; - - // Expose fixPeerConnectionConfig. - Adapter.fixPeerConnectionConfig = function (pcConfig) { - var i, len, iceServer, hasUrls, hasUrl; - - if (!Array.isArray(pcConfig.iceServers)) { - pcConfig.iceServers = []; - } - - for (i = 0, len = pcConfig.iceServers.length; i < len; i += 1) { - iceServer = pcConfig.iceServers[i]; - hasUrls = iceServer.hasOwnProperty('urls'); - hasUrl = iceServer.hasOwnProperty('url'); - - if (typeof iceServer === 'object') { - // Has .urls but not .url, so add .url with a single string value. - if (hasUrls && !hasUrl) { - iceServer.url = (Array.isArray(iceServer.urls) ? iceServer.urls[0] : iceServer.urls); - // Has .url but not .urls, so add .urls with same value. - } else if (!hasUrls && hasUrl) { - iceServer.urls = (Array.isArray(iceServer.url) ? iceServer.url.slice() : iceServer.url); - } - - // Ensure .url is a single string. - if (hasUrl && Array.isArray(iceServer.url)) { - iceServer.url = iceServer.url[0]; - } - } - } - }; - - // Expose fixRTCOfferOptions. - Adapter.fixRTCOfferOptions = function (options) { - options = options || {}; - - // New spec. - if (!oldSpecRTCOfferOptions) { - if (options.mandatory && options.mandatory.OfferToReceiveAudio) { - options.offerToReceiveAudio = 1; - } - if (options.mandatory && options.mandatory.OfferToReceiveVideo) { - options.offerToReceiveVideo = 1; - } - delete options.mandatory; - // Old spec. - } else { - if (options.offerToReceiveAudio) { - options.mandatory = options.mandatory || {}; - options.mandatory.OfferToReceiveAudio = true; - } - if (options.offerToReceiveVideo) { - options.mandatory = options.mandatory || {}; - options.mandatory.OfferToReceiveVideo = true; - } - } - }; - - return Adapter; -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"bowser":17,"debug":9}],14:[function(require,module,exports){ -'use strict'; - -// Expose the RTCPeerConnection class. -module.exports = RTCPeerConnection; - - -// Dependencies. - -var merge = require('merge'), - debug = require('debug')('rtcninja:RTCPeerConnection'), - debugerror = require('debug')('rtcninja:ERROR:RTCPeerConnection'), - Adapter = require('./Adapter'), - - // Internal constants. - C = { - REGEXP_NORMALIZED_CANDIDATE: new RegExp(/^candidate:/i), - REGEXP_FIX_CANDIDATE: new RegExp(/(^a=|\r|\n)/gi), - REGEXP_RELAY_CANDIDATE: new RegExp(/ relay /i), - REGEXP_SDP_CANDIDATES: new RegExp(/^a=candidate:.*\r\n/igm), - REGEXP_SDP_NON_RELAY_CANDIDATES: new RegExp(/^a=candidate:(.(?!relay ))*\r\n/igm) - }, - - // Internal variables. - VAR = { - normalizeCandidate: null - }; - -debugerror.log = console.warn.bind(console); - - -// Constructor - -function RTCPeerConnection(pcConfig, pcConstraints) { - debug('new | pcConfig: %o', pcConfig); - - // Set this.pcConfig and this.options. - setConfigurationAndOptions.call(this, pcConfig); - - // NOTE: Deprecated pcConstraints argument. - this.pcConstraints = pcConstraints; - - // Own version of the localDescription. - this.ourLocalDescription = null; - - // Latest values of PC attributes to avoid events with same value. - this.ourSignalingState = null; - this.ourIceConnectionState = null; - this.ourIceGatheringState = null; - - // Timer for options.gatheringTimeout. - this.timerGatheringTimeout = null; - - // Timer for options.gatheringTimeoutAfterRelay. - this.timerGatheringTimeoutAfterRelay = null; - - // Flag to ignore new gathered ICE candidates. - this.ignoreIceGathering = false; - - // Flag set when closed. - this.closed = false; - - // Set RTCPeerConnection. - setPeerConnection.call(this); - - // Set properties. - setProperties.call(this); -} - - -// Public API. - -RTCPeerConnection.prototype.createOffer = function (successCallback, failureCallback, options) { - debug('createOffer()'); - - var self = this; - - Adapter.fixRTCOfferOptions(options); - - this.pc.createOffer( - function (offer) { - if (isClosed.call(self)) { - return; - } - debug('createOffer() | success'); - if (successCallback) { - successCallback(offer); - } - }, - function (error) { - if (isClosed.call(self)) { - return; - } - debugerror('createOffer() | error:', error); - if (failureCallback) { - failureCallback(error); - } - }, - options - ); -}; - - -RTCPeerConnection.prototype.createAnswer = function (successCallback, failureCallback, options) { - debug('createAnswer()'); - - var self = this; - - this.pc.createAnswer( - function (answer) { - if (isClosed.call(self)) { - return; - } - debug('createAnswer() | success'); - if (successCallback) { - successCallback(answer); - } - }, - function (error) { - if (isClosed.call(self)) { - return; - } - debugerror('createAnswer() | error:', error); - if (failureCallback) { - failureCallback(error); - } - }, - options - ); -}; - - -RTCPeerConnection.prototype.setLocalDescription = function (description, successCallback, failureCallback) { - debug('setLocalDescription()'); - - var self = this; - - this.pc.setLocalDescription( - description, - // success. - function () { - if (isClosed.call(self)) { - return; - } - debug('setLocalDescription() | success'); - - // Clear gathering timers. - clearTimeout(self.timerGatheringTimeout); - delete self.timerGatheringTimeout; - clearTimeout(self.timerGatheringTimeoutAfterRelay); - delete self.timerGatheringTimeoutAfterRelay; - - runTimerGatheringTimeout(); - if (successCallback) { - successCallback(); - } - }, - // failure - function (error) { - if (isClosed.call(self)) { - return; - } - debugerror('setLocalDescription() | error:', error); - if (failureCallback) { - failureCallback(error); - } - } - ); - - // Enable (again) ICE gathering. - this.ignoreIceGathering = false; - - // Handle gatheringTimeout. - function runTimerGatheringTimeout() { - if (typeof self.options.gatheringTimeout !== 'number') { - return; - } - // If setLocalDescription was already called, it may happen that - // ICE gathering is not needed, so don't run this timer. - if (self.pc.iceGatheringState === 'complete') { - return; - } - - debug('setLocalDescription() | ending gathering in %d ms (gatheringTimeout option)', - self.options.gatheringTimeout); - - self.timerGatheringTimeout = setTimeout(function () { - if (isClosed.call(self)) { - return; - } - - debug('forced end of candidates after gatheringTimeout timeout'); - - // Clear gathering timers. - delete self.timerGatheringTimeout; - clearTimeout(self.timerGatheringTimeoutAfterRelay); - delete self.timerGatheringTimeoutAfterRelay; - - // Ignore new candidates. - self.ignoreIceGathering = true; - if (self.onicecandidate) { - self.onicecandidate({ candidate: null }, null); - } - - }, self.options.gatheringTimeout); - } -}; - - -RTCPeerConnection.prototype.setRemoteDescription = function (description, successCallback, failureCallback) { - debug('setRemoteDescription()'); - - var self = this; - - this.pc.setRemoteDescription( - description, - function () { - if (isClosed.call(self)) { - return; - } - debug('setRemoteDescription() | success'); - if (successCallback) { - successCallback(); - } - }, - function (error) { - if (isClosed.call(self)) { - return; - } - debugerror('setRemoteDescription() | error:', error); - if (failureCallback) { - failureCallback(error); - } - } - ); -}; - - -RTCPeerConnection.prototype.updateIce = function (pcConfig) { - debug('updateIce() | pcConfig: %o', pcConfig); - - // Update this.pcConfig and this.options. - setConfigurationAndOptions.call(this, pcConfig); - - this.pc.updateIce(this.pcConfig); - - // Enable (again) ICE gathering. - this.ignoreIceGathering = false; -}; - - -RTCPeerConnection.prototype.addIceCandidate = function (candidate, successCallback, failureCallback) { - debug('addIceCandidate() | candidate: %o', candidate); - - var self = this; - - this.pc.addIceCandidate( - candidate, - function () { - if (isClosed.call(self)) { - return; - } - debug('addIceCandidate() | success'); - if (successCallback) { - successCallback(); - } - }, - function (error) { - if (isClosed.call(self)) { - return; - } - debugerror('addIceCandidate() | error:', error); - if (failureCallback) { - failureCallback(error); - } - } - ); -}; - - -RTCPeerConnection.prototype.getConfiguration = function () { - debug('getConfiguration()'); - - return this.pc.getConfiguration(); -}; - - -RTCPeerConnection.prototype.getLocalStreams = function () { - debug('getLocalStreams()'); - - return this.pc.getLocalStreams(); -}; - - -RTCPeerConnection.prototype.getRemoteStreams = function () { - debug('getRemoteStreams()'); - - return this.pc.getRemoteStreams(); -}; - - -RTCPeerConnection.prototype.getStreamById = function (streamId) { - debug('getStreamById() | streamId: %s', streamId); - - return this.pc.getStreamById(streamId); -}; - - -RTCPeerConnection.prototype.addStream = function (stream) { - debug('addStream() | stream: %s', stream); - - this.pc.addStream(stream); -}; - - -RTCPeerConnection.prototype.removeStream = function (stream) { - debug('removeStream() | stream: %o', stream); - - this.pc.removeStream(stream); -}; - - -RTCPeerConnection.prototype.close = function () { - debug('close()'); - - this.closed = true; - - // Clear gathering timers. - clearTimeout(this.timerGatheringTimeout); - delete this.timerGatheringTimeout; - clearTimeout(this.timerGatheringTimeoutAfterRelay); - delete this.timerGatheringTimeoutAfterRelay; - - this.pc.close(); -}; - - -RTCPeerConnection.prototype.createDataChannel = function () { - debug('createDataChannel()'); - - return this.pc.createDataChannel.apply(this.pc, arguments); -}; - - -RTCPeerConnection.prototype.createDTMFSender = function (track) { - debug('createDTMFSender()'); - - return this.pc.createDTMFSender(track); -}; - - -RTCPeerConnection.prototype.getStats = function () { - debug('getStats()'); - - return this.pc.getStats.apply(this.pc, arguments); -}; - - -RTCPeerConnection.prototype.setIdentityProvider = function () { - debug('setIdentityProvider()'); - - return this.pc.setIdentityProvider.apply(this.pc, arguments); -}; - - -RTCPeerConnection.prototype.getIdentityAssertion = function () { - debug('getIdentityAssertion()'); - - return this.pc.getIdentityAssertion(); -}; - - -RTCPeerConnection.prototype.reset = function (pcConfig) { - debug('reset() | pcConfig: %o', pcConfig); - - var pc = this.pc; - - // Remove events in the old PC. - pc.onnegotiationneeded = null; - pc.onicecandidate = null; - pc.onaddstream = null; - pc.onremovestream = null; - pc.ondatachannel = null; - pc.onsignalingstatechange = null; - pc.oniceconnectionstatechange = null; - pc.onicegatheringstatechange = null; - pc.onidentityresult = null; - pc.onpeeridentity = null; - pc.onidpassertionerror = null; - pc.onidpvalidationerror = null; - - // Clear gathering timers. - clearTimeout(this.timerGatheringTimeout); - delete this.timerGatheringTimeout; - clearTimeout(this.timerGatheringTimeoutAfterRelay); - delete this.timerGatheringTimeoutAfterRelay; - - // Silently close the old PC. - debug('reset() | closing current peerConnection'); - pc.close(); - - // Set this.pcConfig and this.options. - setConfigurationAndOptions.call(this, pcConfig); - - // Create a new PC. - setPeerConnection.call(this); -}; - - -// Private Helpers. - -function setConfigurationAndOptions(pcConfig) { - // Clone pcConfig. - this.pcConfig = merge(true, pcConfig); - - // Fix pcConfig. - Adapter.fixPeerConnectionConfig(this.pcConfig); - - this.options = { - iceTransportsRelay: (this.pcConfig.iceTransports === 'relay'), - iceTransportsNone: (this.pcConfig.iceTransports === 'none'), - gatheringTimeout: this.pcConfig.gatheringTimeout, - gatheringTimeoutAfterRelay: this.pcConfig.gatheringTimeoutAfterRelay - }; - - // Remove custom rtcninja.RTCPeerConnection options from pcConfig. - delete this.pcConfig.gatheringTimeout; - delete this.pcConfig.gatheringTimeoutAfterRelay; - - debug('setConfigurationAndOptions | processed pcConfig: %o', this.pcConfig); -} - - -function isClosed() { - return ((this.closed) || (this.pc && this.pc.iceConnectionState === 'closed')); -} - - -function setEvents() { - var self = this, - pc = this.pc; - - pc.onnegotiationneeded = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onnegotiationneeded()'); - if (self.onnegotiationneeded) { - self.onnegotiationneeded(event); - } - }; - - pc.onicecandidate = function (event) { - var candidate, isRelay, newCandidate; - - if (isClosed.call(self)) { - return; - } - if (self.ignoreIceGathering) { - return; - } - - // Ignore any candidate (event the null one) if iceTransports:'none' is set. - if (self.options.iceTransportsNone) { - return; - } - - candidate = event.candidate; - - if (candidate) { - isRelay = C.REGEXP_RELAY_CANDIDATE.test(candidate.candidate); - - // Ignore if just relay candidates are requested. - if (self.options.iceTransportsRelay && !isRelay) { - return; - } - - // Handle gatheringTimeoutAfterRelay. - if (isRelay && !self.timerGatheringTimeoutAfterRelay && - (typeof self.options.gatheringTimeoutAfterRelay === 'number')) { - debug('onicecandidate() | first relay candidate found, ending gathering in %d ms', self.options.gatheringTimeoutAfterRelay); - - self.timerGatheringTimeoutAfterRelay = setTimeout(function () { - if (isClosed.call(self)) { - return; - } - - debug('forced end of candidates after timeout'); - - // Clear gathering timers. - delete self.timerGatheringTimeoutAfterRelay; - clearTimeout(self.timerGatheringTimeout); - delete self.timerGatheringTimeout; - - // Ignore new candidates. - self.ignoreIceGathering = true; - if (self.onicecandidate) { - self.onicecandidate({candidate: null}, null); - } - }, self.options.gatheringTimeoutAfterRelay); - } - - newCandidate = new Adapter.RTCIceCandidate({ - sdpMid: candidate.sdpMid, - sdpMLineIndex: candidate.sdpMLineIndex, - candidate: candidate.candidate - }); - - // Force correct candidate syntax (just check it once). - if (VAR.normalizeCandidate === null) { - if (C.REGEXP_NORMALIZED_CANDIDATE.test(candidate.candidate)) { - VAR.normalizeCandidate = false; - } else { - debug('onicecandidate() | normalizing ICE candidates syntax (remove "a=" and "\\r\\n")'); - VAR.normalizeCandidate = true; - } - } - if (VAR.normalizeCandidate) { - newCandidate.candidate = candidate.candidate.replace(C.REGEXP_FIX_CANDIDATE, ''); - } - - debug( - 'onicecandidate() | m%d(%s) %s', - newCandidate.sdpMLineIndex, - newCandidate.sdpMid || 'no mid', newCandidate.candidate); - if (self.onicecandidate) { - self.onicecandidate(event, newCandidate); - } - // Null candidate (end of candidates). - } else { - debug('onicecandidate() | end of candidates'); - - // Clear gathering timers. - clearTimeout(self.timerGatheringTimeout); - delete self.timerGatheringTimeout; - clearTimeout(self.timerGatheringTimeoutAfterRelay); - delete self.timerGatheringTimeoutAfterRelay; - if (self.onicecandidate) { - self.onicecandidate(event, null); - } - } - }; - - pc.onaddstream = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onaddstream() | stream: %o', event.stream); - if (self.onaddstream) { - self.onaddstream(event, event.stream); - } - }; - - pc.onremovestream = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onremovestream() | stream: %o', event.stream); - if (self.onremovestream) { - self.onremovestream(event, event.stream); - } - }; - - pc.ondatachannel = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('ondatachannel() | datachannel: %o', event.channel); - if (self.ondatachannel) { - self.ondatachannel(event, event.channel); - } - }; - - pc.onsignalingstatechange = function (event) { - if (pc.signalingState === self.ourSignalingState) { - return; - } - - debug('onsignalingstatechange() | signalingState: %s', pc.signalingState); - self.ourSignalingState = pc.signalingState; - if (self.onsignalingstatechange) { - self.onsignalingstatechange(event, pc.signalingState); - } - }; - - pc.oniceconnectionstatechange = function (event) { - if (pc.iceConnectionState === self.ourIceConnectionState) { - return; - } - - debug('oniceconnectionstatechange() | iceConnectionState: %s', pc.iceConnectionState); - self.ourIceConnectionState = pc.iceConnectionState; - if (self.oniceconnectionstatechange) { - self.oniceconnectionstatechange(event, pc.iceConnectionState); - } - }; - - pc.onicegatheringstatechange = function (event) { - if (isClosed.call(self)) { - return; - } - - if (pc.iceGatheringState === self.ourIceGatheringState) { - return; - } - - debug('onicegatheringstatechange() | iceGatheringState: %s', pc.iceGatheringState); - self.ourIceGatheringState = pc.iceGatheringState; - if (self.onicegatheringstatechange) { - self.onicegatheringstatechange(event, pc.iceGatheringState); - } - }; - - pc.onidentityresult = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onidentityresult()'); - if (self.onidentityresult) { - self.onidentityresult(event); - } - }; - - pc.onpeeridentity = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onpeeridentity()'); - if (self.onpeeridentity) { - self.onpeeridentity(event); - } - }; - - pc.onidpassertionerror = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onidpassertionerror()'); - if (self.onidpassertionerror) { - self.onidpassertionerror(event); - } - }; - - pc.onidpvalidationerror = function (event) { - if (isClosed.call(self)) { - return; - } - - debug('onidpvalidationerror()'); - if (self.onidpvalidationerror) { - self.onidpvalidationerror(event); - } - }; -} - - -function setPeerConnection() { - // Create a RTCPeerConnection. - if (!this.pcConstraints) { - this.pc = new Adapter.RTCPeerConnection(this.pcConfig); - } else { - // NOTE: Deprecated. - this.pc = new Adapter.RTCPeerConnection(this.pcConfig, this.pcConstraints); - } - - // Set RTC events. - setEvents.call(this); -} - - -function getLocalDescription() { - var pc = this.pc, - options = this.options, - sdp = null; - - if (!pc.localDescription) { - this.ourLocalDescription = null; - return null; - } - - // Mangle the SDP string. - if (options.iceTransportsRelay) { - sdp = pc.localDescription.sdp.replace(C.REGEXP_SDP_NON_RELAY_CANDIDATES, ''); - } else if (options.iceTransportsNone) { - sdp = pc.localDescription.sdp.replace(C.REGEXP_SDP_CANDIDATES, ''); - } - - this.ourLocalDescription = new Adapter.RTCSessionDescription({ - type: pc.localDescription.type, - sdp: sdp || pc.localDescription.sdp - }); - - return this.ourLocalDescription; -} - - -function setProperties() { - var self = this; - - Object.defineProperties(this, { - peerConnection: { - get: function () { - return self.pc; - } - }, - - signalingState: { - get: function () { - return self.pc.signalingState; - } - }, - - iceConnectionState: { - get: function () { - return self.pc.iceConnectionState; - } - }, - - iceGatheringState: { - get: function () { - return self.pc.iceGatheringState; - } - }, - - localDescription: { - get: function () { - return getLocalDescription.call(self); - } - }, - - remoteDescription: { - get: function () { - return self.pc.remoteDescription; - } - }, - - peerIdentity: { - get: function () { - return self.pc.peerIdentity; - } - } - }); -} - -},{"./Adapter":13,"debug":9,"merge":18}],15:[function(require,module,exports){ -'use strict'; - -module.exports = rtcninja; - - -// Dependencies. - -var browser = require('bowser'), - debug = require('debug')('rtcninja'), - debugerror = require('debug')('rtcninja:ERROR'), - version = require('./version'), - Adapter = require('./Adapter'), - RTCPeerConnection = require('./RTCPeerConnection'), - - // Internal vars. - called = false; - -debugerror.log = console.warn.bind(console); -debug('version %s', version); -debug('detected browser: %s %s [mobile:%s, tablet:%s, android:%s, ios:%s]', - browser.name, browser.version, !!browser.mobile, !!browser.tablet, - !!browser.android, !!browser.ios); - - -// Constructor. - -function rtcninja(options) { - // Load adapter - var iface = Adapter(options || {}); // jshint ignore:line - - called = true; - - // Expose RTCPeerConnection class. - rtcninja.RTCPeerConnection = RTCPeerConnection; - - // Expose WebRTC API and utils. - rtcninja.getUserMedia = iface.getUserMedia; - rtcninja.RTCSessionDescription = iface.RTCSessionDescription; - rtcninja.RTCIceCandidate = iface.RTCIceCandidate; - rtcninja.MediaStreamTrack = iface.MediaStreamTrack; - rtcninja.getMediaDevices = iface.getMediaDevices; - rtcninja.attachMediaStream = iface.attachMediaStream; - rtcninja.closeMediaStream = iface.closeMediaStream; - rtcninja.canRenegotiate = iface.canRenegotiate; - - // Log WebRTC support. - if (iface.hasWebRTC()) { - debug('WebRTC supported'); - return true; - } else { - debugerror('WebRTC not supported'); - return false; - } -} - - -// Public API. - -// If called without calling rtcninja(), call it. -rtcninja.hasWebRTC = function () { - if (!called) { - rtcninja(); - } - - return Adapter.hasWebRTC(); -}; - - -// Expose version property. -Object.defineProperty(rtcninja, 'version', { - get: function () { - return version; - } -}); - - -// Expose called property. -Object.defineProperty(rtcninja, 'called', { - get: function () { - return called; - } -}); - - -// Exposing stuff. - -rtcninja.debug = require('debug'); -rtcninja.browser = browser; - -},{"./Adapter":13,"./RTCPeerConnection":14,"./version":16,"bowser":17,"debug":9}],16:[function(require,module,exports){ -'use strict'; - -// Expose the 'version' field of package.json. -module.exports = require('../package.json').version; - - -},{"../package.json":19}],17:[function(require,module,exports){ -/*! - * Bowser - a browser detector - * https://github.com/ded/bowser - * MIT License | (c) Dustin Diaz 2015 - */ - -!function (name, definition) { - if (typeof module != 'undefined' && module.exports) module.exports = definition() - else if (typeof define == 'function' && define.amd) define(definition) - else this[name] = definition() -}('bowser', function () { - /** - * See useragents.js for examples of navigator.userAgent - */ - - var t = true - - function detect(ua) { - - function getFirstMatch(regex) { - var match = ua.match(regex); - return (match && match.length > 1 && match[1]) || ''; - } - - function getSecondMatch(regex) { - var match = ua.match(regex); - return (match && match.length > 1 && match[2]) || ''; - } - - var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase() - , likeAndroid = /like android/i.test(ua) - , android = !likeAndroid && /android/i.test(ua) - , chromeBook = /CrOS/.test(ua) - , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i) - , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i) - , tablet = /tablet/i.test(ua) - , mobile = !tablet && /[^-]mobi/i.test(ua) - , result - - if (/opera|opr/i.test(ua)) { - result = { - name: 'Opera' - , opera: t - , version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i) - } - } - else if (/yabrowser/i.test(ua)) { - result = { - name: 'Yandex Browser' - , yandexbrowser: t - , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i) - } - } - else if (/windows phone/i.test(ua)) { - result = { - name: 'Windows Phone' - , windowsphone: t - } - if (edgeVersion) { - result.msedge = t - result.version = edgeVersion - } - else { - result.msie = t - result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) - } - } - else if (/msie|trident/i.test(ua)) { - result = { - name: 'Internet Explorer' - , msie: t - , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) - } - } else if (chromeBook) { - result = { - name: 'Chrome' - , chromeBook: t - , chrome: t - , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) - } - } else if (/chrome.+? edge/i.test(ua)) { - result = { - name: 'Microsoft Edge' - , msedge: t - , version: edgeVersion - } - } - else if (/chrome|crios|crmo/i.test(ua)) { - result = { - name: 'Chrome' - , chrome: t - , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) - } - } - else if (iosdevice) { - result = { - name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod' - } - // WTF: version is not part of user agent in web apps - if (versionIdentifier) { - result.version = versionIdentifier - } - } - else if (/sailfish/i.test(ua)) { - result = { - name: 'Sailfish' - , sailfish: t - , version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i) - } - } - else if (/seamonkey\//i.test(ua)) { - result = { - name: 'SeaMonkey' - , seamonkey: t - , version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i) - } - } - else if (/firefox|iceweasel/i.test(ua)) { - result = { - name: 'Firefox' - , firefox: t - , version: getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i) - } - if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { - result.firefoxos = t - } - } - else if (/silk/i.test(ua)) { - result = { - name: 'Amazon Silk' - , silk: t - , version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) - } - } - else if (android) { - result = { - name: 'Android' - , version: versionIdentifier - } - } - else if (/phantom/i.test(ua)) { - result = { - name: 'PhantomJS' - , phantom: t - , version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) - } - } - else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { - result = { - name: 'BlackBerry' - , blackberry: t - , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) - } - } - else if (/(web|hpw)os/i.test(ua)) { - result = { - name: 'WebOS' - , webos: t - , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) - }; - /touchpad\//i.test(ua) && (result.touchpad = t) - } - else if (/bada/i.test(ua)) { - result = { - name: 'Bada' - , bada: t - , version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i) - }; - } - else if (/tizen/i.test(ua)) { - result = { - name: 'Tizen' - , tizen: t - , version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier - }; - } - else if (/safari/i.test(ua)) { - result = { - name: 'Safari' - , safari: t - , version: versionIdentifier - } - } - else { - result = { - name: getFirstMatch(/^(.*)\/(.*) /), - version: getSecondMatch(/^(.*)\/(.*) /) - }; - } - - // set webkit or gecko flag for browsers based on these engines - if (!result.msedge && /(apple)?webkit/i.test(ua)) { - result.name = result.name || "Webkit" - result.webkit = t - if (!result.version && versionIdentifier) { - result.version = versionIdentifier - } - } else if (!result.opera && /gecko\//i.test(ua)) { - result.name = result.name || "Gecko" - result.gecko = t - result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i) - } - - // set OS flags for platforms that have multiple browsers - if (!result.msedge && (android || result.silk)) { - result.android = t - } else if (iosdevice) { - result[iosdevice] = t - result.ios = t - } - - // OS version extraction - var osVersion = ''; - if (result.windowsphone) { - osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); - } else if (iosdevice) { - osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); - osVersion = osVersion.replace(/[_\s]/g, '.'); - } else if (android) { - osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i); - } else if (result.webos) { - osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); - } else if (result.blackberry) { - osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); - } else if (result.bada) { - osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i); - } else if (result.tizen) { - osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i); - } - if (osVersion) { - result.osversion = osVersion; - } - - // device type extraction - var osMajorVersion = osVersion.split('.')[0]; - if (tablet || iosdevice == 'ipad' || (android && (osMajorVersion == 3 || (osMajorVersion == 4 && !mobile))) || result.silk) { - result.tablet = t - } else if (mobile || iosdevice == 'iphone' || iosdevice == 'ipod' || android || result.blackberry || result.webos || result.bada) { - result.mobile = t - } - - // Graded Browser Support - // http://developer.yahoo.com/yui/articles/gbs - if (result.msedge || - (result.msie && result.version >= 10) || - (result.yandexbrowser && result.version >= 15) || - (result.chrome && result.version >= 20) || - (result.firefox && result.version >= 20.0) || - (result.safari && result.version >= 6) || - (result.opera && result.version >= 10.0) || - (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) || - (result.blackberry && result.version >= 10.1) - ) { - result.a = t; - } - else if ((result.msie && result.version < 10) || - (result.chrome && result.version < 20) || - (result.firefox && result.version < 20.0) || - (result.safari && result.version < 6) || - (result.opera && result.version < 10.0) || - (result.ios && result.osversion && result.osversion.split(".")[0] < 6) - ) { - result.c = t - } else result.x = t - - return result - } - - var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '') - - bowser.test = function (browserList) { - for (var i = 0; i < browserList.length; ++i) { - var browserItem = browserList[i]; - if (typeof browserItem=== 'string') { - if (browserItem in bowser) { - return true; - } - } - } - return false; - } - - /* - * Set our detect method to the main bowser object so we can - * reuse it to test other user agents. - * This is needed to implement future tests. - */ - bowser._detect = detect; - - return bowser -}); - -},{}],18:[function(require,module,exports){ -/*! - * @name JavaScript/NodeJS Merge v1.2.0 - * @author yeikos - * @repository https://github.com/yeikos/js.merge - - * Copyright 2014 yeikos - MIT license - * https://raw.github.com/yeikos/js.merge/master/LICENSE - */ - -;(function(isNode) { - - /** - * Merge one or more objects - * @param bool? clone - * @param mixed,... arguments - * @return object - */ - - var Public = function(clone) { - - return merge(clone === true, false, arguments); - - }, publicName = 'merge'; - - /** - * Merge two or more objects recursively - * @param bool? clone - * @param mixed,... arguments - * @return object - */ - - Public.recursive = function(clone) { - - return merge(clone === true, true, arguments); - - }; - - /** - * Clone the input removing any reference - * @param mixed input - * @return mixed - */ - - Public.clone = function(input) { - - var output = input, - type = typeOf(input), - index, size; - - if (type === 'array') { - - output = []; - size = input.length; - - for (index=0;index=0.10.32" - }, - "dependencies": { - "bowser": "^1.0.0", - "debug": "^2.2.0", - "merge": "^1.2.0" - }, - "devDependencies": { - "browserify": "^11.0.1", - "gulp": "git+https://github.com/gulpjs/gulp.git#4.0", - "gulp-expect-file": "0.0.7", - "gulp-filelog": "^0.4.1", - "gulp-header": "^1.7.1", - "gulp-jscs": "^2.0.0", - "gulp-jscs-stylish": "^1.1.2", - "gulp-jshint": "^1.11.2", - "gulp-rename": "^1.2.2", - "gulp-uglify": "^1.4.0", - "jshint-stylish": "^2.0.1", - "retire": "^1.1.1", - "shelljs": "^0.5.3", - "vinyl-source-stream": "^1.1.0" - }, - "gitHead": "18789cbefdb5a6c6c038ab4f1ce8e9e3813135b0", - "bugs": { - "url": "https://github.com/eface2face/rtcninja.js/issues" - }, - "_id": "rtcninja@0.6.4", - "scripts": {}, - "_shasum": "7ede8577ce978cb431772d877967c53aadeb5e99", - "_from": "rtcninja@0.6.4", - "_npmVersion": "2.5.1", - "_nodeVersion": "0.12.0", - "_npmUser": { - "name": "ibc", - "email": "ibc@aliax.net" - }, - "dist": { - "shasum": "7ede8577ce978cb431772d877967c53aadeb5e99", - "tarball": "http://registry.npmjs.org/rtcninja/-/rtcninja-0.6.4.tgz" - }, - "maintainers": [ - { - "name": "ibc", - "email": "ibc@aliax.net" - } - ], - "directories": {}, - "_resolved": "https://registry.npmjs.org/rtcninja/-/rtcninja-0.6.4.tgz" -} - -},{}],20:[function(require,module,exports){ -var _global = (function() { return this; })(); -var nativeWebSocket = _global.WebSocket || _global.MozWebSocket; - - -/** - * Expose a W3C WebSocket class with just one or two arguments. - */ -function W3CWebSocket(uri, protocols) { - var native_instance; - - if (protocols) { - native_instance = new nativeWebSocket(uri, protocols); - } - else { - native_instance = new nativeWebSocket(uri); - } - - /** - * 'native_instance' is an instance of nativeWebSocket (the browser's WebSocket - * class). Since it is an Object it will be returned as it is when creating an - * instance of W3CWebSocket via 'new W3CWebSocket()'. - * - * ECMAScript 5: http://bclary.com/2004/11/07/#a-13.2.2 - */ - return native_instance; -} - - -/** - * Module exports. - */ -module.exports = { - 'w3cwebsocket' : nativeWebSocket ? W3CWebSocket : null, - 'version' : require('./version') -}; - -},{"./version":21}],21:[function(require,module,exports){ -module.exports = require('../package.json').version; - -},{"../package.json":22}],22:[function(require,module,exports){ -module.exports={ - "name": "websocket", - "description": "Websocket Client & Server Library implementing the WebSocket protocol as specified in RFC 6455.", - "keywords": [ - "websocket", - "websockets", - "socket", - "networking", - "comet", - "push", - "RFC-6455", - "realtime", - "server", - "client" - ], - "author": { - "name": "Brian McKelvey", - "email": "brian@worlize.com", - "url": "https://www.worlize.com/" - }, - "contributors": [ - { - "name": "Iñaki Baz Castillo", - "email": "ibc@aliax.net", - "url": "http://dev.sipdoc.net" - } - ], - "version": "1.0.21", - "repository": { - "type": "git", - "url": "git+https://github.com/theturtle32/WebSocket-Node.git" - }, - "homepage": "https://github.com/theturtle32/WebSocket-Node", - "engines": { - "node": ">=0.8.0" - }, - "dependencies": { - "debug": "~2.2.0", - "nan": "~1.8.x", - "typedarray-to-buffer": "~3.0.3", - "yaeti": "~0.0.4" - }, - "devDependencies": { - "buffer-equal": "^0.0.1", - "faucet": "^0.0.1", - "gulp": "git+https://github.com/gulpjs/gulp.git#4.0", - "gulp-jshint": "^1.11.2", - "jshint-stylish": "^1.0.2", - "tape": "^4.0.1" - }, - "config": { - "verbose": false - }, - "scripts": { - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)", - "test": "faucet test/unit", - "gulp": "gulp" - }, - "main": "index", - "directories": { - "lib": "./lib" - }, - "browser": "lib/browser.js", - "license": "Apache-2.0", - "gitHead": "8f5d5f3ef3d946324fe016d525893546ff6500e1", - "bugs": { - "url": "https://github.com/theturtle32/WebSocket-Node/issues" - }, - "_id": "websocket@1.0.21", - "_shasum": "f51f0a96ed19629af39922470ab591907f1c5bd9", - "_from": "websocket@1.0.21", - "_npmVersion": "2.12.1", - "_nodeVersion": "2.3.4", - "_npmUser": { - "name": "theturtle32", - "email": "brian@worlize.com" - }, - "maintainers": [ - { - "name": "theturtle32", - "email": "brian@worlize.com" - } - ], - "dist": { - "shasum": "f51f0a96ed19629af39922470ab591907f1c5bd9", - "tarball": "http://registry.npmjs.org/websocket/-/websocket-1.0.21.tgz" - }, - "_resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.21.tgz", - "readme": "ERROR: No README data found!" -} - -},{}]},{},[4])(4) -}); - - -//# sourceMappingURL=sylkrtc.js.map \ No newline at end of file diff --git a/resources/html/webrtcgateway/js/sylkrtc.js.map b/resources/html/webrtcgateway/js/sylkrtc.js.map deleted file mode 100644 index 417bd53..0000000 --- a/resources/html/webrtcgateway/js/sylkrtc.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","lib/account.js","lib/call.js","lib/connection.js","lib/sylkrtc.js","node_modules/blueimp-md5/js/md5.js","node_modules/browserify/node_modules/events/events.js","node_modules/browserify/node_modules/process/browser.js","node_modules/browserify/node_modules/timers-browserify/main.js","node_modules/debug/browser.js","node_modules/debug/debug.js","node_modules/debug/node_modules/ms/index.js","node_modules/node-uuid/uuid.js","node_modules/rtcninja/lib/Adapter.js","node_modules/rtcninja/lib/RTCPeerConnection.js","node_modules/rtcninja/lib/rtcninja.js","node_modules/rtcninja/lib/version.js","node_modules/rtcninja/node_modules/bowser/bowser.js","node_modules/rtcninja/node_modules/merge/merge.js","node_modules/rtcninja/package.json","node_modules/websocket/lib/browser.js","node_modules/websocket/lib/version.js","node_modules/websocket/package.json"],"names":[],"mappings":"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AC,6BAA6B,CAAC,CAAC;KAClD;;AAED,QAAI,IAAI,GAAG,IAAA,WAAA,CAVN,UAAU,CAUW,OAAO,CAAC,CAAC;AACnC,QAAI,CAAC,WAAW,EAAE,CAAC;AACnB,WAAO,IAAI,CAAC;CACf;;;;AAKD,SAAS,iBAAiB,GAAG;AACzB,WAAO,UAAA,CAAA,SAAA,CAAA,CAAS,SAAS,EAAE,CAAC;CAC/B;;AAED,SAAS,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE;AACxC,WAAO,UAAA,CAAA,SAAA,CAAA,CAAS,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CACtD;;AAED,SAAS,gBAAgB,CAAC,MAAM,EAAE;AAC9B,cAAA,CAAA,SAAA,CAAA,CAAS,gBAAgB,CAAC,MAAM,CAAC,CAAC;CACrC;;AAcD,OAAO,CAAC,SAAS,CAAC,GAXH;AACX,oBAAgB,EAAhB,gBAAgB;AAChB,SAAK,EAAA,OAAA,CAAA,SAAA,CAAA;AACL,qBAAiB,EAAjB,iBAAiB,EAAE,gBAAgB,EAAhB,gBAAgB,EAAE,iBAAiB,EAAjB,iBAAiB;CACzD,CAAA;AAYD,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;;;ACnDpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7uBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"sylkrtc.js","sourceRoot":"/source/","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o {\n if (error) {\n DEBUG('Register error: %s', error);\n const oldState = this._registrationState;\n const newState = 'failed';\n let data = {reason: error.toString()};\n this._registrationState = newState;\n this.emit('registrationStateChanged', oldState, newState, data);\n }\n });\n }\n\n unregister() {\n let req = {\n sylkrtc: 'account-unregister',\n account: this._id,\n };\n this._sendRequest(req, (error) => {\n if (error) {\n DEBUG('Unregister error: %s', error);\n }\n const oldState = this._registrationState;\n const newState = null;\n this._registrationState = newState;\n this.emit('registrationStateChanged', oldState, newState, {});\n });\n }\n\n call(uri, options={}) {\n let call = new Call(this);\n call._initOutgoing(uri, options);\n this._calls.set(call.id, call);\n this.emit('outgoingCall', call);\n return call;\n }\n\n // Private API\n\n _handleEvent(message) {\n DEBUG('Received account event: %s', message.event);\n switch (message.event) {\n case 'registration_state':\n const oldState = this._registrationState;\n const newState = message.data.state;\n let data = {};\n this._registrationState = newState;\n if (newState === 'failed') {\n data.reason = message.data.reason;\n }\n this.emit('registrationStateChanged', oldState, newState, data);\n break;\n case 'incoming_session':\n let call = new Call(this);\n call._initIncoming(message.session, message.data.originator, message.data.sdp);\n this._calls.set(call.id, call);\n this.emit('incomingCall', call);\n break;\n default:\n break;\n }\n }\n\n _sendRequest(req, cb) {\n this._connection._sendRequest(req, cb);\n }\n\n}\n\n\nexport { Account };\n","'use strict';\n\nimport debug from 'debug';\nimport uuid from 'node-uuid';\nimport rtcninja from 'rtcninja';\n\nimport { EventEmitter } from 'events';\n\nconst DEBUG = debug('sylkrtc:Call');\n\n\nclass Call extends EventEmitter {\n constructor(account) {\n super();\n this._account = account;\n this._id = null;\n this._direction = null;\n this._pc = null;\n this._state = null;\n this._terminated = false;\n this._incomingSdp = null;\n this._remoteIdentity = null;\n }\n\n get account() {\n return this._account;\n }\n\n get id() {\n return this._id;\n }\n\n get direction() {\n return this._direction;\n }\n\n get state() {\n return this._state;\n }\n\n get localIdentity() {\n return this._account.id;\n }\n\n get remoteIdentity() {\n return this._remoteIdentity;\n }\n\n getLocalStreams() {\n if (this._pc !== null) {\n return this._pc.getLocalStreams();\n } else {\n return [];\n }\n }\n\n getRemoteStreams() {\n if (this._pc !== null) {\n return this._pc.getRemoteStreams();\n } else {\n return [];\n }\n }\n\n answer(options = {}) {\n if (this._state !== 'incoming') {\n throw new Error('Call is not in the incoming state: ' + this._state);\n }\n\n const self = this;\n const pcConfig = options.pcConfig || {iceServers:[]};\n const mediaConstraints = options.mediaConstraints || {audio: true, video: true};\n const answerOptions = options.answerOptions;\n\n // Create the RTCPeerConnection\n this._initRTCPeerConnection(pcConfig);\n\n // Get the user media\n rtcninja.getUserMedia(\n mediaConstraints,\n userMediaSucceeded,\n userMediaFailed\n );\n\n function userMediaSucceeded(stream) {\n // adding a local stream doesn't trigger the 'onaddstream' callback\n self._pc.addStream(stream);\n self.emit('localStreamAdded', stream);\n\n self._pc.setRemoteDescription(\n new rtcninja.RTCSessionDescription({type: 'offer', sdp: self._incomingSdp}),\n // success\n function() {\n self._createLocalSDP(\n 'answer',\n answerOptions,\n // success\n function(sdp) {\n DEBUG('Local SDP: %s', sdp);\n self._sendAnswer(sdp);\n },\n // failure\n function(error) {\n DEBUG('Error creating local SDP: %s', error);\n self.terminate();\n }\n );\n },\n // failure\n function(error) {\n DEBUG('Error setting remote description: %s', error);\n self.terminate();\n }\n );\n }\n\n function userMediaFailed(error) {\n DEBUG('Error getting user media: %s', error);\n self.terminate();\n }\n }\n\n terminate() {\n if (this._terminated) {\n return;\n }\n\n this._sendTerminate();\n }\n\n // Private API\n\n _initOutgoing(uri, options={}) {\n if (uri.indexOf('@') === -1) {\n throw new Error('Invalid URI');\n }\n\n this._id = uuid.v4();\n this._direction = 'outgoing';\n this._remoteIdentity = uri;\n\n const self = this;\n const pcConfig = options.pcConfig || {iceServers:[]};\n const mediaConstraints = options.mediaConstraints || {audio: true, video: true};\n const offerOptions = options.offerOptions;\n\n // Create the RTCPeerConnection\n this._initRTCPeerConnection(pcConfig);\n\n // Get the user media\n rtcninja.getUserMedia(\n mediaConstraints,\n userMediaSucceeded,\n userMediaFailed\n );\n\n function userMediaSucceeded(stream) {\n // adding a local stream doesn't trigger the 'onaddstream' callback\n self._pc.addStream(stream);\n self.emit('localStreamAdded', stream);\n\n self._createLocalSDP(\n 'offer',\n offerOptions,\n // success\n function(sdp) {\n DEBUG('Local SDP: %s', sdp);\n self._sendCall(uri, sdp);\n },\n // failure\n function(error) {\n DEBUG('Error creating local SDP: %s', error);\n self._localTerminate(error);\n }\n );\n }\n\n function userMediaFailed(error) {\n DEBUG('Error getting user media: %s', error);\n self._localTerminate(error);\n }\n }\n\n _initIncoming(id, caller, sdp) {\n this._id = id;\n this._remoteIdentity = caller;\n this._incomingSdp = sdp;\n this._direction = 'incoming';\n this._state = 'incoming';\n }\n\n _handleEvent(message) {\n DEBUG('Call event: %o', message);\n switch (message.event) {\n case 'state':\n const oldState = this._state;\n const newState = message.data.state;\n this._state = newState;\n let data = {};\n\n if (newState === 'accepted' && this._direction === 'outgoing') {\n const self = this;\n this._pc.setRemoteDescription(\n new rtcninja.RTCSessionDescription({type: 'answer', sdp: message.data.sdp}),\n // success\n function() {\n DEBUG('Call accepted');\n self.emit('stateChanged', oldState, newState, data);\n },\n // failure\n function(error) {\n DEBUG('Error accepting call: %s', error);\n self.terminate();\n }\n );\n } else {\n if (newState === 'terminated') {\n data.reason = message.data.reason;\n this._terminated = true;\n }\n this.emit('stateChanged', oldState, newState, data);\n if (newState === 'terminated') {\n this._closeRTCPeerConnection();\n }\n }\n break;\n default:\n break;\n }\n }\n\n _initRTCPeerConnection(pcConfig) {\n if (this._pc !== null) {\n throw new Error('RTCPeerConnection already initialized');\n }\n\n const self = this;\n this._pc = new rtcninja.RTCPeerConnection(pcConfig);\n this._pc.onaddstream = function(event, stream) {\n DEBUG('Stream added');\n self.emit('streamAdded', stream);\n };\n this._pc.onicecandidate = function(event) {\n let candidate = null;\n if (event.candidate !== null) {\n candidate = {\n 'candidate': event.candidate.candidate,\n 'sdpMid': event.candidate.sdpMid,\n 'sdpMLineIndex': event.candidate.sdpMLineIndex\n };\n DEBUG('New ICE candidate %o', candidate);\n }\n self._sendTrickle(candidate);\n };\n }\n\n _createLocalSDP(type, options, onSuccess, onFailure) {\n const self = this;\n\n if (type === 'offer') {\n this._pc.createOffer(\n // success\n createSucceeded,\n // failure\n failure,\n // options\n options\n );\n } else if (type === 'answer') {\n this._pc.createAnswer(\n // success\n createSucceeded,\n // failure\n failure,\n // options\n options\n );\n } else {\n throw new Error('type must be \"offer\" or \"answer\", but \"' +type+ '\" was given');\n }\n\n function createSucceeded(desc) {\n self._pc.setLocalDescription(\n desc,\n // success\n function() {\n onSuccess(self._pc.localDescription.sdp);\n },\n // failure\n failure\n );\n }\n\n function failure(error) {\n onFailure(error);\n }\n }\n\n _sendRequest(req, cb) {\n this._account._sendRequest(req, cb);\n }\n\n _sendCall(uri, sdp) {\n let req = {\n sylkrtc: 'session-create',\n account: this.account.id,\n session: this.id,\n uri: uri,\n sdp: sdp\n };\n const self = this;\n this._sendRequest(req, function(error) {\n if (error) {\n DEBUG('Call error: %s', error);\n self._localTerminate(error);\n }\n });\n }\n\n _sendTerminate() {\n let req = {\n sylkrtc: 'session-terminate',\n session: this.id\n };\n const self = this;\n this._sendRequest(req, function(error) {\n if (error) {\n DEBUG('Error terminating call: %s', error);\n self._localTerminate(error);\n }\n self._terminated = true;\n });\n }\n\n _sendTrickle(candidate) {\n let req = {\n sylkrtc: 'session-trickle',\n session: this.id,\n candidates: candidate !== null ? [candidate] : [],\n };\n this._sendRequest(req, null);\n }\n\n _sendAnswer(sdp) {\n let req = {\n sylkrtc: 'session-answer',\n session: this.id,\n sdp: sdp\n };\n const self = this;\n this._sendRequest(req, function(error) {\n if (error) {\n DEBUG('Answer error: %s', error);\n self.terminate();\n }\n });\n }\n\n _closeRTCPeerConnection() {\n DEBUG('Closing RTCPeerConnection');\n if (this._pc !== null) {\n for (let stream of this._pc.getLocalStreams()) {\n rtcninja.closeMediaStream(stream);\n }\n for (let stream of this._pc.getRemoteStreams()) {\n rtcninja.closeMediaStream(stream);\n }\n this._pc.close();\n this._pc = null;\n }\n }\n\n _localTerminate(error) {\n if (this._terminated) {\n return;\n }\n this._account._calls.delete(this.id);\n this._terminated = true;\n const oldState = this._state;\n const newState = 'terminated';\n let data = {\n reason: error.toString()\n };\n this.emit('stateChanged', oldState, newState, data);\n this._closeRTCPeerConnection();\n }\n}\n\n\nexport { Call };\n","'use strict';\n\nimport debug from 'debug';\nimport uuid from 'node-uuid';\n\nimport { EventEmitter } from 'events';\nimport { setImmediate } from 'timers';\nimport { w3cwebsocket as W3CWebSocket } from 'websocket';\nimport { Account } from './account';\n\nconst SYLKRTC_PROTO = 'sylkRTC-1';\nconst DEBUG = debug('sylkrtc:Connection');\nconst INITIAL_DELAY = 0.5 * 1000;\n\n\nclass Connection extends EventEmitter {\n constructor(options = {}) {\n if (!options.server) {\n throw new Error('\\\"server\\\" must be specified');\n }\n super();\n this._wsUri = options.server;\n this._sock = null;\n this._state = null;\n this._closed = false;\n this._timer = null;\n this._delay = INITIAL_DELAY;\n this._accounts = new Map();\n this._requests = new Map();\n }\n\n get state() {\n return this._state;\n }\n\n close() {\n if (this._closed) {\n return;\n }\n this._closed = true;\n if (this._timer) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n if (this._sock) {\n this._sock.close();\n this._sock = null;\n } else {\n setImmediate(() => {\n this._setState('closed');\n });\n }\n }\n\n addAccount(options = {}, cb = null) {\n if (typeof options.account !== 'string' || typeof options.password !== 'string') {\n throw new Error('Invalid options, \\\"account\\\" and \\\"password\\\" must be supplied');\n }\n if (this._accounts.has(options.account)) {\n throw new Error('Account already added');\n }\n\n let acc = new Account(options.account, options.password, this);\n // add it early to the set so we don't add it more than once, ever\n this._accounts.set(acc.id, acc);\n\n let req = {\n sylkrtc: 'account-add',\n account: acc.id,\n password: acc.password\n };\n this._sendRequest(req, (error) => {\n if (error) {\n DEBUG('add_account error: %s', error);\n this._accounts.delete(acc.id);\n acc = null;\n }\n if (cb) {\n cb(error, acc);\n }\n });\n\n }\n\n removeAccount(account, cb=null) {\n const acc = this._accounts.get(account.id);\n if (account !== acc) {\n throw new Error('Unknown account');\n }\n\n // delete the account from the mapping, regardless of the result\n this._accounts.delete(account.id);\n\n let req = {\n sylkrtc: 'account-remove',\n account: acc.id\n };\n this._sendRequest(req, (error) => {\n if (error) {\n DEBUG('remove_account error: %s', error);\n }\n if (cb) {\n cb();\n }\n });\n\n }\n\n // Private API\n\n _initialize() {\n if (this._sock !== null) {\n throw new Error('WebSocket already initialized');\n }\n if (this._timer !== null) {\n throw new Error('Initialize is in progress');\n }\n\n DEBUG('Initializing');\n\n if (process.browser) {\n window.addEventListener('beforeunload', () => {\n if (this._sock !== null) {\n let noop = function() {};\n this._sock.onerror = noop;\n this._sock.onmessage = noop;\n this._sock.onclose = noop;\n this._sock.close();\n }\n });\n }\n\n this._timer = setTimeout(() => {\n this._connect();\n }, this._delay);\n }\n\n _connect() {\n DEBUG('WebSocket connecting');\n this._setState('connecting');\n\n this._sock = new W3CWebSocket(this._wsUri, SYLKRTC_PROTO);\n this._sock.onopen = () => {\n DEBUG('WebSocket connection open');\n this._onOpen();\n };\n this._sock.onerror = () => {\n DEBUG('WebSocket connection got error');\n };\n this._sock.onclose = (event) => {\n DEBUG('WebSocket connection closed: %d: (reason=\\\"%s\\\", clean=%s)', event.code, event.reason, event.wasClean);\n this._onClose();\n };\n this._sock.onmessage = (event) => {\n DEBUG('WebSocket received message: %o', event);\n this._onMessage(event);\n };\n }\n\n _sendRequest(req, cb) {\n const transaction = uuid.v4();\n req.transaction = transaction;\n if (this._state !== 'ready') {\n setImmediate(() => {\n cb(new Error('Connection is not ready'));\n });\n return;\n }\n this._requests.set(transaction, {req: req, cb: cb});\n this._sock.send(JSON.stringify(req));\n }\n\n _setState(newState) {\n DEBUG('Set state: %s -> %s', this._state, newState);\n const oldState = this._state;\n this._state = newState;\n this.emit('stateChanged', oldState, newState);\n }\n\n // WebSocket callbacks\n\n _onOpen() {\n clearTimeout(this._timer);\n this._timer = null;\n this._delay = INITIAL_DELAY;\n this._setState('connected');\n }\n\n _onClose() {\n this._sock = null;\n if (this._timer) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n\n // remove all accounts, the server no longer has them anyway\n this._accounts.clear();\n\n this._setState('disconnected');\n if (!this._closed) {\n this._delay = this._delay * 2;\n if (this._delay > Number.MAX_VALUE) {\n this._delay = INITIAL_DELAY;\n }\n DEBUG('Retrying connection in %s seconds', this._delay / 1000);\n this._timer = setTimeout(() => {\n this._connect();\n }, this._delay);\n } else {\n this._setState('closed');\n }\n }\n\n _onMessage(event) {\n let message = JSON.parse(event.data);\n if (typeof message.sylkrtc === 'undefined') {\n DEBUG('Unrecognized message received');\n return;\n }\n\n DEBUG('Received \\\"%s\\\" message: %o', message.sylkrtc, message);\n\n if (message.sylkrtc === 'event') {\n DEBUG('Received event: \\\"%s\\\"', message.event);\n switch (message.event) {\n case 'ready':\n this._setState('ready');\n break;\n default:\n break;\n }\n } else if (message.sylkrtc === 'account_event') {\n let acc = this._accounts.get(message.account);\n if (!acc) {\n DEBUG('Account %s not found', message.account);\n return;\n }\n acc._handleEvent(message);\n } else if (message.sylkrtc === 'session_event') {\n const sessionId = message.session;\n for (let acc of this._accounts.values()) {\n let call = acc._calls.get(sessionId);\n if (call) {\n call._handleEvent(message);\n break;\n }\n }\n } else if (message.sylkrtc === 'ack' || message.sylkrtc === 'error') {\n const transaction = message.transaction;\n const data = this._requests.get(transaction);\n if (!data) {\n DEBUG('Could not find transaction %s', transaction);\n return;\n }\n this._requests.delete(transaction);\n DEBUG('Received \\\"%s\\\" for request: %o', message.sylkrtc, data.req);\n if (data.cb) {\n if (message.sylkrtc === 'ack') {\n data.cb(null);\n } else {\n data.cb(new Error(message.error));\n }\n }\n }\n }\n\n}\n\n\nexport { Connection };\n","'use strict';\n\nimport debug from 'debug';\nimport rtcninja from 'rtcninja';\nimport { Connection } from './connection';\n\n\n// Public API\n\nfunction createConnection(options = {}) {\n if (!rtcninja.hasWebRTC()) {\n throw new Error('WebRTC support not detected');\n }\n\n let conn = new Connection(options);\n conn._initialize();\n return conn;\n}\n\n\n// Some proxied functions from rtcninja\n\nfunction isWebRTCSupported() {\n return rtcninja.hasWebRTC();\n}\n\nfunction attachMediaStream(element, stream) {\n return rtcninja.attachMediaStream(element, stream);\n}\n\nfunction closeMediaStream(stream) {\n rtcninja.closeMediaStream(stream);\n}\n\n\nexport default {\n createConnection,\n debug,\n attachMediaStream, closeMediaStream, isWebRTCSupported\n};\n","/*\n * JavaScript MD5 1.0.1\n * https://github.com/blueimp/JavaScript-MD5\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n * \n * Based on\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n */\n\n/*jslint bitwise: true */\n/*global unescape, define */\n\n(function ($) {\n 'use strict';\n\n /*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\n function safe_add(x, y) {\n var lsw = (x & 0xFFFF) + (y & 0xFFFF),\n msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return (msw << 16) | (lsw & 0xFFFF);\n }\n\n /*\n * Bitwise rotate a 32-bit number to the left.\n */\n function bit_rol(num, cnt) {\n return (num << cnt) | (num >>> (32 - cnt));\n }\n\n /*\n * These functions implement the four basic operations the algorithm uses.\n */\n function md5_cmn(q, a, b, x, s, t) {\n return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);\n }\n function md5_ff(a, b, c, d, x, s, t) {\n return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);\n }\n function md5_gg(a, b, c, d, x, s, t) {\n return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);\n }\n function md5_hh(a, b, c, d, x, s, t) {\n return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n }\n function md5_ii(a, b, c, d, x, s, t) {\n return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);\n }\n\n /*\n * Calculate the MD5 of an array of little-endian words, and a bit length.\n */\n function binl_md5(x, len) {\n /* append padding */\n x[len >> 5] |= 0x80 << (len % 32);\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n var i, olda, oldb, oldc, oldd,\n a = 1732584193,\n b = -271733879,\n c = -1732584194,\n d = 271733878;\n\n for (i = 0; i < x.length; i += 16) {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n\n a = md5_ff(a, b, c, d, x[i], 7, -680876936);\n d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);\n c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);\n a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);\n d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);\n b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);\n a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);\n c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);\n b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);\n d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);\n c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);\n\n a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);\n d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);\n b = md5_gg(b, c, d, a, x[i], 20, -373897302);\n a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);\n c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);\n b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);\n d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);\n c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);\n a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);\n d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);\n b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);\n\n a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);\n d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);\n c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);\n b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);\n d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);\n c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);\n a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);\n d = md5_hh(d, a, b, c, x[i], 11, -358537222);\n c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);\n b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);\n a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);\n c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);\n b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);\n\n a = md5_ii(a, b, c, d, x[i], 6, -198630844);\n d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);\n c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);\n a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);\n d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);\n b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);\n a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);\n c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);\n b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);\n d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);\n c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);\n\n a = safe_add(a, olda);\n b = safe_add(b, oldb);\n c = safe_add(c, oldc);\n d = safe_add(d, oldd);\n }\n return [a, b, c, d];\n }\n\n /*\n * Convert an array of little-endian words to a string\n */\n function binl2rstr(input) {\n var i,\n output = '';\n for (i = 0; i < input.length * 32; i += 8) {\n output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);\n }\n return output;\n }\n\n /*\n * Convert a raw string to an array of little-endian words\n * Characters >255 have their high-byte silently ignored.\n */\n function rstr2binl(input) {\n var i,\n output = [];\n output[(input.length >> 2) - 1] = undefined;\n for (i = 0; i < output.length; i += 1) {\n output[i] = 0;\n }\n for (i = 0; i < input.length * 8; i += 8) {\n output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);\n }\n return output;\n }\n\n /*\n * Calculate the MD5 of a raw string\n */\n function rstr_md5(s) {\n return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));\n }\n\n /*\n * Calculate the HMAC-MD5, of a key and some data (raw strings)\n */\n function rstr_hmac_md5(key, data) {\n var i,\n bkey = rstr2binl(key),\n ipad = [],\n opad = [],\n hash;\n ipad[15] = opad[15] = undefined;\n if (bkey.length > 16) {\n bkey = binl_md5(bkey, key.length * 8);\n }\n for (i = 0; i < 16; i += 1) {\n ipad[i] = bkey[i] ^ 0x36363636;\n opad[i] = bkey[i] ^ 0x5C5C5C5C;\n }\n hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);\n return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));\n }\n\n /*\n * Convert a raw string to a hex string\n */\n function rstr2hex(input) {\n var hex_tab = '0123456789abcdef',\n output = '',\n x,\n i;\n for (i = 0; i < input.length; i += 1) {\n x = input.charCodeAt(i);\n output += hex_tab.charAt((x >>> 4) & 0x0F) +\n hex_tab.charAt(x & 0x0F);\n }\n return output;\n }\n\n /*\n * Encode a string as utf-8\n */\n function str2rstr_utf8(input) {\n return unescape(encodeURIComponent(input));\n }\n\n /*\n * Take string arguments and return either raw or hex encoded strings\n */\n function raw_md5(s) {\n return rstr_md5(str2rstr_utf8(s));\n }\n function hex_md5(s) {\n return rstr2hex(raw_md5(s));\n }\n function raw_hmac_md5(k, d) {\n return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d));\n }\n function hex_hmac_md5(k, d) {\n return rstr2hex(raw_hmac_md5(k, d));\n }\n\n function md5(string, key, raw) {\n if (!key) {\n if (!raw) {\n return hex_md5(string);\n }\n return raw_md5(string);\n }\n if (!raw) {\n return hex_hmac_md5(key, string);\n }\n return raw_hmac_md5(key, string);\n }\n\n if (typeof define === 'function' && define.amd) {\n define(function () {\n return md5;\n });\n } else {\n $.md5 = md5;\n }\n}(this));\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n }\n throw TypeError('Uncaught, unspecified \"error\" event.');\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n len = arguments.length;\n args = new Array(len - 1);\n for (i = 1; i < len; i++)\n args[i - 1] = arguments[i];\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n len = arguments.length;\n args = new Array(len - 1);\n for (i = 1; i < len; i++)\n args[i - 1] = arguments[i];\n\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n var m;\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n var ret;\n if (!emitter._events || !emitter._events[type])\n ret = 0;\n else if (isFunction(emitter._events[type]))\n ret = 1;\n else\n ret = emitter._events[type].length;\n return ret;\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = setTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n currentQueue[queueIndex].run();\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\n// TODO(shtylman)\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","var nextTick = require('process/browser.js').nextTick;\nvar apply = Function.prototype.apply;\nvar slice = Array.prototype.slice;\nvar immediateIds = {};\nvar nextImmediateId = 0;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) { timeout.close(); };\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// That's not how node.js implements it but the exposed api is the same.\nexports.setImmediate = typeof setImmediate === \"function\" ? setImmediate : function(fn) {\n var id = nextImmediateId++;\n var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n\n immediateIds[id] = true;\n\n nextTick(function onNextTick() {\n if (immediateIds[id]) {\n // fn.call() is faster so we optimize for the common use-case\n // @see http://jsperf.com/call-apply-segu\n if (args) {\n fn.apply(null, args);\n } else {\n fn.call(null);\n }\n // Prevent ids from leaking\n exports.clearImmediate(id);\n }\n });\n\n return id;\n};\n\nexports.clearImmediate = typeof clearImmediate === \"function\" ? clearImmediate : function(id) {\n delete immediateIds[id];\n};","\n/**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = require('./debug');\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = 'undefined' != typeof chrome\n && 'undefined' != typeof chrome.storage\n ? chrome.storage.local\n : localstorage();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n 'lightseagreen',\n 'forestgreen',\n 'goldenrod',\n 'dodgerblue',\n 'darkorchid',\n 'crimson'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\nfunction useColors() {\n // is webkit? http://stackoverflow.com/a/16459606/376773\n return ('WebkitAppearance' in document.documentElement.style) ||\n // is firebug? http://stackoverflow.com/a/398120/376773\n (window.console && (console.firebug || (console.exception && console.table))) ||\n // is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n (navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31);\n}\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nexports.formatters.j = function(v) {\n return JSON.stringify(v);\n};\n\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs() {\n var args = arguments;\n var useColors = this.useColors;\n\n args[0] = (useColors ? '%c' : '')\n + this.namespace\n + (useColors ? ' %c' : ' ')\n + args[0]\n + (useColors ? '%c ' : ' ')\n + '+' + exports.humanize(this.diff);\n\n if (!useColors) return args;\n\n var c = 'color: ' + this.color;\n args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n // the final \"%c\" is somewhat tricky, because there could be other\n // arguments passed either before or after the %c, so we need to\n // figure out the correct index to insert the CSS into\n var index = 0;\n var lastC = 0;\n args[0].replace(/%[a-z%]/g, function(match) {\n if ('%%' === match) return;\n index++;\n if ('%c' === match) {\n // we only are interested in the *last* %c\n // (the user may have provided their own)\n lastC = index;\n }\n });\n\n args.splice(lastC, 0, c);\n return args;\n}\n\n/**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\nfunction log() {\n // this hackery is required for IE8/9, where\n // the `console.log` function doesn't have 'apply'\n return 'object' === typeof console\n && console.log\n && Function.prototype.apply.call(console.log, console, arguments);\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\nfunction save(namespaces) {\n try {\n if (null == namespaces) {\n exports.storage.removeItem('debug');\n } else {\n exports.storage.debug = namespaces;\n }\n } catch(e) {}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n var r;\n try {\n r = exports.storage.debug;\n } catch(e) {}\n return r;\n}\n\n/**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\nexports.enable(load());\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage(){\n try {\n return window.localStorage;\n } catch (e) {}\n}\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\nexports = module.exports = debug;\nexports.coerce = coerce;\nexports.disable = disable;\nexports.enable = enable;\nexports.enabled = enabled;\nexports.humanize = require('ms');\n\n/**\n * The currently active debug mode names, and names to skip.\n */\n\nexports.names = [];\nexports.skips = [];\n\n/**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\nexports.formatters = {};\n\n/**\n * Previously assigned color.\n */\n\nvar prevColor = 0;\n\n/**\n * Previous log timestamp.\n */\n\nvar prevTime;\n\n/**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\nfunction selectColor() {\n return exports.colors[prevColor++ % exports.colors.length];\n}\n\n/**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\nfunction debug(namespace) {\n\n // define the `disabled` version\n function disabled() {\n }\n disabled.enabled = false;\n\n // define the `enabled` version\n function enabled() {\n\n var self = enabled;\n\n // set `diff` timestamp\n var curr = +new Date();\n var ms = curr - (prevTime || curr);\n self.diff = ms;\n self.prev = prevTime;\n self.curr = curr;\n prevTime = curr;\n\n // add the `color` if not set\n if (null == self.useColors) self.useColors = exports.useColors();\n if (null == self.color && self.useColors) self.color = selectColor();\n\n var args = Array.prototype.slice.call(arguments);\n\n args[0] = exports.coerce(args[0]);\n\n if ('string' !== typeof args[0]) {\n // anything else let's inspect with %o\n args = ['%o'].concat(args);\n }\n\n // apply any `formatters` transformations\n var index = 0;\n args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {\n // if we encounter an escaped % then don't increase the array index\n if (match === '%%') return match;\n index++;\n var formatter = exports.formatters[format];\n if ('function' === typeof formatter) {\n var val = args[index];\n match = formatter.call(self, val);\n\n // now we need to remove `args[index]` since it's inlined in the `format`\n args.splice(index, 1);\n index--;\n }\n return match;\n });\n\n if ('function' === typeof exports.formatArgs) {\n args = exports.formatArgs.apply(self, args);\n }\n var logFn = enabled.log || exports.log || console.log.bind(console);\n logFn.apply(self, args);\n }\n enabled.enabled = true;\n\n var fn = exports.enabled(namespace) ? enabled : disabled;\n\n fn.namespace = namespace;\n\n return fn;\n}\n\n/**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\nfunction enable(namespaces) {\n exports.save(namespaces);\n\n var split = (namespaces || '').split(/[\\s,]+/);\n var len = split.length;\n\n for (var i = 0; i < len; i++) {\n if (!split[i]) continue; // ignore empty strings\n namespaces = split[i].replace(/\\*/g, '.*?');\n if (namespaces[0] === '-') {\n exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n } else {\n exports.names.push(new RegExp('^' + namespaces + '$'));\n }\n }\n}\n\n/**\n * Disable debug output.\n *\n * @api public\n */\n\nfunction disable() {\n exports.enable('');\n}\n\n/**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\nfunction enabled(name) {\n var i, len;\n for (i = 0, len = exports.skips.length; i < len; i++) {\n if (exports.skips[i].test(name)) {\n return false;\n }\n }\n for (i = 0, len = exports.names.length; i < len; i++) {\n if (exports.names[i].test(name)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\nfunction coerce(val) {\n if (val instanceof Error) return val.stack || val.message;\n return val;\n}\n","/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n options = options || {};\n if ('string' == typeof val) return parse(val);\n return options.long\n ? long(val)\n : short(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = '' + str;\n if (str.length > 10000) return;\n var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);\n if (!match) return;\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction short(ms) {\n if (ms >= d) return Math.round(ms / d) + 'd';\n if (ms >= h) return Math.round(ms / h) + 'h';\n if (ms >= m) return Math.round(ms / m) + 'm';\n if (ms >= s) return Math.round(ms / s) + 's';\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction long(ms) {\n return plural(ms, d, 'day')\n || plural(ms, h, 'hour')\n || plural(ms, m, 'minute')\n || plural(ms, s, 'second')\n || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n if (ms < n) return;\n if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n return Math.ceil(ms / n) + ' ' + name + 's';\n}\n","// uuid.js\n//\n// Copyright (c) 2010-2012 Robert Kieffer\n// MIT License - http://opensource.org/licenses/mit-license.php\n\n(function() {\n var _global = this;\n\n // Unique ID creation requires a high quality random # generator. We feature\n // detect to determine the best RNG source, normalizing to a function that\n // returns 128-bits of randomness, since that's what's usually required\n var _rng;\n\n // Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html\n //\n // Moderately fast, high quality\n if (typeof(_global.require) == 'function') {\n try {\n var _rb = _global.require('crypto').randomBytes;\n _rng = _rb && function() {return _rb(16);};\n } catch(e) {}\n }\n\n if (!_rng && _global.crypto && crypto.getRandomValues) {\n // WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto\n //\n // Moderately fast, high quality\n var _rnds8 = new Uint8Array(16);\n _rng = function whatwgRNG() {\n crypto.getRandomValues(_rnds8);\n return _rnds8;\n };\n }\n\n if (!_rng) {\n // Math.random()-based (RNG)\n //\n // If all else fails, use Math.random(). It's fast, but is of unspecified\n // quality.\n var _rnds = new Array(16);\n _rng = function() {\n for (var i = 0, r; i < 16; i++) {\n if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n _rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n }\n\n return _rnds;\n };\n }\n\n // Buffer class to use\n var BufferClass = typeof(_global.Buffer) == 'function' ? _global.Buffer : Array;\n\n // Maps for number <-> hex string conversion\n var _byteToHex = [];\n var _hexToByte = {};\n for (var i = 0; i < 256; i++) {\n _byteToHex[i] = (i + 0x100).toString(16).substr(1);\n _hexToByte[_byteToHex[i]] = i;\n }\n\n // **`parse()` - Parse a UUID into it's component bytes**\n function parse(s, buf, offset) {\n var i = (buf && offset) || 0, ii = 0;\n\n buf = buf || [];\n s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {\n if (ii < 16) { // Don't overflow!\n buf[i + ii++] = _hexToByte[oct];\n }\n });\n\n // Zero out remaining bytes if string was short\n while (ii < 16) {\n buf[i + ii++] = 0;\n }\n\n return buf;\n }\n\n // **`unparse()` - Convert UUID byte array (ala parse()) into a string**\n function unparse(buf, offset) {\n var i = offset || 0, bth = _byteToHex;\n return bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] + '-' +\n bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]] +\n bth[buf[i++]] + bth[buf[i++]];\n }\n\n // **`v1()` - Generate time-based UUID**\n //\n // Inspired by https://github.com/LiosK/UUID.js\n // and http://docs.python.org/library/uuid.html\n\n // random #'s we need to init node and clockseq\n var _seedBytes = _rng();\n\n // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n var _nodeId = [\n _seedBytes[0] | 0x01,\n _seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]\n ];\n\n // Per 4.2.2, randomize (14 bit) clockseq\n var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;\n\n // Previous uuid creation time\n var _lastMSecs = 0, _lastNSecs = 0;\n\n // See https://github.com/broofa/node-uuid for API details\n function v1(options, buf, offset) {\n var i = buf && offset || 0;\n var b = buf || [];\n\n options = options || {};\n\n var clockseq = options.clockseq != null ? options.clockseq : _clockseq;\n\n // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so\n // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n var msecs = options.msecs != null ? options.msecs : new Date().getTime();\n\n // Per 4.2.1.2, use count of uuid's generated during the current clock\n // cycle to simulate higher resolution clock\n var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1;\n\n // Time since last uuid creation (in msecs)\n var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;\n\n // Per 4.2.1.2, Bump clockseq on clock regression\n if (dt < 0 && options.clockseq == null) {\n clockseq = clockseq + 1 & 0x3fff;\n }\n\n // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n // time interval\n if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {\n nsecs = 0;\n }\n\n // Per 4.2.1.2 Throw error if too many uuids are requested\n if (nsecs >= 10000) {\n throw new Error('uuid.v1(): Can\\'t create more than 10M uuids/sec');\n }\n\n _lastMSecs = msecs;\n _lastNSecs = nsecs;\n _clockseq = clockseq;\n\n // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n msecs += 12219292800000;\n\n // `time_low`\n var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n b[i++] = tl >>> 24 & 0xff;\n b[i++] = tl >>> 16 & 0xff;\n b[i++] = tl >>> 8 & 0xff;\n b[i++] = tl & 0xff;\n\n // `time_mid`\n var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;\n b[i++] = tmh >>> 8 & 0xff;\n b[i++] = tmh & 0xff;\n\n // `time_high_and_version`\n b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n b[i++] = tmh >>> 16 & 0xff;\n\n // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n b[i++] = clockseq >>> 8 | 0x80;\n\n // `clock_seq_low`\n b[i++] = clockseq & 0xff;\n\n // `node`\n var node = options.node || _nodeId;\n for (var n = 0; n < 6; n++) {\n b[i + n] = node[n];\n }\n\n return buf ? buf : unparse(b);\n }\n\n // **`v4()` - Generate random UUID**\n\n // See https://github.com/broofa/node-uuid for API details\n function v4(options, buf, offset) {\n // Deprecated - 'format' argument, as supported in v1.2\n var i = buf && offset || 0;\n\n if (typeof(options) == 'string') {\n buf = options == 'binary' ? new BufferClass(16) : null;\n options = null;\n }\n options = options || {};\n\n var rnds = options.random || (options.rng || _rng)();\n\n // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n // Copy bytes to buffer, if provided\n if (buf) {\n for (var ii = 0; ii < 16; ii++) {\n buf[i + ii] = rnds[ii];\n }\n }\n\n return buf || unparse(rnds);\n }\n\n // Export public API\n var uuid = v4;\n uuid.v1 = v1;\n uuid.v4 = v4;\n uuid.parse = parse;\n uuid.unparse = unparse;\n uuid.BufferClass = BufferClass;\n\n if (typeof(module) != 'undefined' && module.exports) {\n // Publish as node.js module\n module.exports = uuid;\n } else if (typeof define === 'function' && define.amd) {\n // Publish as AMD module\n define(function() {return uuid;});\n \n\n } else {\n // Publish as global (in browsers)\n var _previousRoot = _global.uuid;\n\n // **`noConflict()` - (browser only) to reset global 'uuid' var**\n uuid.noConflict = function() {\n _global.uuid = _previousRoot;\n return uuid;\n };\n\n _global.uuid = uuid;\n }\n}).call(this);\n","'use strict';\n\n// Expose the Adapter function/object.\nmodule.exports = Adapter;\n\n\n// Dependencies\n\nvar browser = require('bowser'),\n\tdebug = require('debug')('rtcninja:Adapter'),\n\tdebugerror = require('debug')('rtcninja:ERROR:Adapter'),\n\n\t// Internal vars\n\tgetUserMedia = null,\n\tRTCPeerConnection = null,\n\tRTCSessionDescription = null,\n\tRTCIceCandidate = null,\n\tMediaStreamTrack = null,\n\tgetMediaDevices = null,\n\tattachMediaStream = null,\n\tcanRenegotiate = false,\n\toldSpecRTCOfferOptions = false,\n\tbrowserVersion = Number(browser.version) || 0,\n\tisDesktop = !!(!browser.mobile && !browser.tablet),\n\thasWebRTC = false,\n\tvirtGlobal, virtNavigator;\n\ndebugerror.log = console.warn.bind(console);\n\n// Dirty trick to get this library working in a Node-webkit env with browserified libs\nvirtGlobal = global.window || global;\n// Don't fail in Node\nvirtNavigator = virtGlobal.navigator || {};\n\n\n// Constructor.\n\nfunction Adapter(options) {\n\t// Chrome desktop, Chrome Android, Opera desktop, Opera Android, Android native browser\n\t// or generic Webkit browser.\n\tif (\n\t\t(isDesktop && browser.chrome && browserVersion >= 32) ||\n\t\t(browser.android && browser.chrome && browserVersion >= 39) ||\n\t\t(isDesktop && browser.opera && browserVersion >= 27) ||\n\t\t(browser.android && browser.opera && browserVersion >= 24) ||\n\t\t(browser.android && browser.webkit && !browser.chrome && browserVersion >= 37) ||\n\t\t(virtNavigator.webkitGetUserMedia && virtGlobal.webkitRTCPeerConnection)\n\t) {\n\t\thasWebRTC = true;\n\t\tgetUserMedia = virtNavigator.webkitGetUserMedia.bind(virtNavigator);\n\t\tRTCPeerConnection = virtGlobal.webkitRTCPeerConnection;\n\t\tRTCSessionDescription = virtGlobal.RTCSessionDescription;\n\t\tRTCIceCandidate = virtGlobal.RTCIceCandidate;\n\t\tMediaStreamTrack = virtGlobal.MediaStreamTrack;\n\t\tif (MediaStreamTrack && MediaStreamTrack.getSources) {\n\t\t\tgetMediaDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack);\n\t\t} else if (virtNavigator.getMediaDevices) {\n\t\t\tgetMediaDevices = virtNavigator.getMediaDevices.bind(virtNavigator);\n\t\t}\n\t\tattachMediaStream = function (element, stream) {\n\t\t\telement.src = URL.createObjectURL(stream);\n\t\t\treturn element;\n\t\t};\n\t\tcanRenegotiate = true;\n\t\toldSpecRTCOfferOptions = false;\n\t// Firefox desktop, Firefox Android.\n\t} else if (\n\t\t(isDesktop && browser.firefox && browserVersion >= 22) ||\n\t\t(browser.android && browser.firefox && browserVersion >= 33) ||\n\t\t(virtNavigator.mozGetUserMedia && virtGlobal.mozRTCPeerConnection)\n\t) {\n\t\thasWebRTC = true;\n\t\tgetUserMedia = virtNavigator.mozGetUserMedia.bind(virtNavigator);\n\t\tRTCPeerConnection = virtGlobal.mozRTCPeerConnection;\n\t\tRTCSessionDescription = virtGlobal.mozRTCSessionDescription;\n\t\tRTCIceCandidate = virtGlobal.mozRTCIceCandidate;\n\t\tMediaStreamTrack = virtGlobal.MediaStreamTrack;\n\t\tattachMediaStream = function (element, stream) {\n\t\t\telement.src = URL.createObjectURL(stream);\n\t\t\treturn element;\n\t\t};\n\t\tcanRenegotiate = false;\n\t\toldSpecRTCOfferOptions = false;\n\t\t// WebRTC plugin required. For example IE or Safari with the Temasys plugin.\n\t} else if (\n\t\toptions.plugin &&\n\t\ttypeof options.plugin.isRequired === 'function' &&\n\t\toptions.plugin.isRequired() &&\n\t\ttypeof options.plugin.isInstalled === 'function' &&\n\t\toptions.plugin.isInstalled()\n\t) {\n\t\tvar pluginiface = options.plugin.interface;\n\n\t\thasWebRTC = true;\n\t\tgetUserMedia = pluginiface.getUserMedia;\n\t\tRTCPeerConnection = pluginiface.RTCPeerConnection;\n\t\tRTCSessionDescription = pluginiface.RTCSessionDescription;\n\t\tRTCIceCandidate = pluginiface.RTCIceCandidate;\n\t\tMediaStreamTrack = pluginiface.MediaStreamTrack;\n\t\tif (MediaStreamTrack && MediaStreamTrack.getSources) {\n\t\t\tgetMediaDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack);\n\t\t} else if (virtNavigator.getMediaDevices) {\n\t\t\tgetMediaDevices = virtNavigator.getMediaDevices.bind(virtNavigator);\n\t\t}\n\t\tattachMediaStream = pluginiface.attachMediaStream;\n\t\tcanRenegotiate = pluginiface.canRenegotiate;\n\t\toldSpecRTCOfferOptions = true; // TODO: Update when fixed in the plugin.\n\t// Best effort (may be adater.js is loaded).\n\t} else if (virtNavigator.getUserMedia && virtGlobal.RTCPeerConnection) {\n\t\thasWebRTC = true;\n\t\tgetUserMedia = virtNavigator.getUserMedia.bind(virtNavigator);\n\t\tRTCPeerConnection = virtGlobal.RTCPeerConnection;\n\t\tRTCSessionDescription = virtGlobal.RTCSessionDescription;\n\t\tRTCIceCandidate = virtGlobal.RTCIceCandidate;\n\t\tMediaStreamTrack = virtGlobal.MediaStreamTrack;\n\t\tif (MediaStreamTrack && MediaStreamTrack.getSources) {\n\t\t\tgetMediaDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack);\n\t\t} else if (virtNavigator.getMediaDevices) {\n\t\t\tgetMediaDevices = virtNavigator.getMediaDevices.bind(virtNavigator);\n\t\t}\n\t\tattachMediaStream = virtGlobal.attachMediaStream || function (element, stream) {\n\t\t\telement.src = URL.createObjectURL(stream);\n\t\t\treturn element;\n\t\t};\n\t\tcanRenegotiate = false;\n\t\toldSpecRTCOfferOptions = false;\n\t}\n\n\n\tfunction throwNonSupported(item) {\n\t\treturn function () {\n\t\t\tthrow new Error('rtcninja: WebRTC not supported, missing ' + item +\n\t\t\t' [browser: ' + browser.name + ' ' + browser.version + ']');\n\t\t};\n\t}\n\n\n\t// Public API.\n\n\t// Expose a WebRTC checker.\n\tAdapter.hasWebRTC = function () {\n\t\treturn hasWebRTC;\n\t};\n\n\t// Expose getUserMedia.\n\tif (getUserMedia) {\n\t\tAdapter.getUserMedia = function (constraints, successCallback, errorCallback) {\n\t\t\tdebug('getUserMedia() | constraints: %o', constraints);\n\n\t\t\ttry {\n\t\t\t\tgetUserMedia(constraints,\n\t\t\t\t\tfunction (stream) {\n\t\t\t\t\t\tdebug('getUserMedia() | success');\n\t\t\t\t\t\tif (successCallback) {\n\t\t\t\t\t\t\tsuccessCallback(stream);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tfunction (error) {\n\t\t\t\t\t\tdebug('getUserMedia() | error:', error);\n\t\t\t\t\t\tif (errorCallback) {\n\t\t\t\t\t\t\terrorCallback(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\tcatch (error) {\n\t\t\t\tdebugerror('getUserMedia() | error:', error);\n\t\t\t\tif (errorCallback) {\n\t\t\t\t\terrorCallback(error);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} else {\n\t\tAdapter.getUserMedia = function (constraints, successCallback, errorCallback) {\n\t\t\tdebugerror('getUserMedia() | WebRTC not supported');\n\t\t\tif (errorCallback) {\n\t\t\t\terrorCallback(new Error('rtcninja: WebRTC not supported, missing ' +\n\t\t\t\t'getUserMedia [browser: ' + browser.name + ' ' + browser.version + ']'));\n\t\t\t} else {\n\t\t\t\tthrowNonSupported('getUserMedia');\n\t\t\t}\n\t\t};\n\t}\n\n\t// Expose RTCPeerConnection.\n\tAdapter.RTCPeerConnection = RTCPeerConnection || throwNonSupported('RTCPeerConnection');\n\n\t// Expose RTCSessionDescription.\n\tAdapter.RTCSessionDescription = RTCSessionDescription || throwNonSupported('RTCSessionDescription');\n\n\t// Expose RTCIceCandidate.\n\tAdapter.RTCIceCandidate = RTCIceCandidate || throwNonSupported('RTCIceCandidate');\n\n\t// Expose MediaStreamTrack.\n\tAdapter.MediaStreamTrack = MediaStreamTrack || throwNonSupported('MediaStreamTrack');\n\n\t// Expose getMediaDevices.\n\tAdapter.getMediaDevices = getMediaDevices;\n\n\t// Expose MediaStreamTrack.\n\tAdapter.attachMediaStream = attachMediaStream || throwNonSupported('attachMediaStream');\n\n\t// Expose canRenegotiate attribute.\n\tAdapter.canRenegotiate = canRenegotiate;\n\n\t// Expose closeMediaStream.\n\tAdapter.closeMediaStream = function (stream) {\n\t\tif (!stream) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Latest spec states that MediaStream has no stop() method and instead must\n\t\t// call stop() on every MediaStreamTrack.\n\t\tif (MediaStreamTrack && MediaStreamTrack.prototype && MediaStreamTrack.prototype.stop) {\n\t\t\tdebug('closeMediaStream() | calling stop() on all the MediaStreamTrack');\n\n\t\t\tvar tracks, i, len;\n\n\t\t\tif (stream.getTracks) {\n\t\t\t\ttracks = stream.getTracks();\n\t\t\t\tfor (i = 0, len = tracks.length; i < len; i += 1) {\n\t\t\t\t\ttracks[i].stop();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttracks = stream.getAudioTracks();\n\t\t\t\tfor (i = 0, len = tracks.length; i < len; i += 1) {\n\t\t\t\t\ttracks[i].stop();\n\t\t\t\t}\n\n\t\t\t\ttracks = stream.getVideoTracks();\n\t\t\t\tfor (i = 0, len = tracks.length; i < len; i += 1) {\n\t\t\t\t\ttracks[i].stop();\n\t\t\t\t}\n\t\t\t}\n\t\t// Deprecated by the spec, but still in use.\n\t\t} else if (typeof stream.stop === 'function') {\n\t\t\tdebug('closeMediaStream() | calling stop() on the MediaStream');\n\n\t\t\tstream.stop();\n\t\t}\n\t};\n\n\t// Expose fixPeerConnectionConfig.\n\tAdapter.fixPeerConnectionConfig = function (pcConfig) {\n\t\tvar i, len, iceServer, hasUrls, hasUrl;\n\n\t\tif (!Array.isArray(pcConfig.iceServers)) {\n\t\t\tpcConfig.iceServers = [];\n\t\t}\n\n\t\tfor (i = 0, len = pcConfig.iceServers.length; i < len; i += 1) {\n\t\t\ticeServer = pcConfig.iceServers[i];\n\t\t\thasUrls = iceServer.hasOwnProperty('urls');\n\t\t\thasUrl = iceServer.hasOwnProperty('url');\n\n\t\t\tif (typeof iceServer === 'object') {\n\t\t\t\t// Has .urls but not .url, so add .url with a single string value.\n\t\t\t\tif (hasUrls && !hasUrl) {\n\t\t\t\t\ticeServer.url = (Array.isArray(iceServer.urls) ? iceServer.urls[0] : iceServer.urls);\n\t\t\t\t// Has .url but not .urls, so add .urls with same value.\n\t\t\t\t} else if (!hasUrls && hasUrl) {\n\t\t\t\t\ticeServer.urls = (Array.isArray(iceServer.url) ? iceServer.url.slice() : iceServer.url);\n\t\t\t\t}\n\n\t\t\t\t// Ensure .url is a single string.\n\t\t\t\tif (hasUrl && Array.isArray(iceServer.url)) {\n\t\t\t\t\ticeServer.url = iceServer.url[0];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Expose fixRTCOfferOptions.\n\tAdapter.fixRTCOfferOptions = function (options) {\n\t\toptions = options || {};\n\n\t\t// New spec.\n\t\tif (!oldSpecRTCOfferOptions) {\n\t\t\tif (options.mandatory && options.mandatory.OfferToReceiveAudio) {\n\t\t\t\toptions.offerToReceiveAudio = 1;\n\t\t\t}\n\t\t\tif (options.mandatory && options.mandatory.OfferToReceiveVideo) {\n\t\t\t\toptions.offerToReceiveVideo = 1;\n\t\t\t}\n\t\t\tdelete options.mandatory;\n\t\t// Old spec.\n\t\t} else {\n\t\t\tif (options.offerToReceiveAudio) {\n\t\t\t\toptions.mandatory = options.mandatory || {};\n\t\t\t\toptions.mandatory.OfferToReceiveAudio = true;\n\t\t\t}\n\t\t\tif (options.offerToReceiveVideo) {\n\t\t\t\toptions.mandatory = options.mandatory || {};\n\t\t\t\toptions.mandatory.OfferToReceiveVideo = true;\n\t\t\t}\n\t\t}\n\t};\n\n\treturn Adapter;\n}\n","'use strict';\n\n// Expose the RTCPeerConnection class.\nmodule.exports = RTCPeerConnection;\n\n\n// Dependencies.\n\nvar merge = require('merge'),\n\tdebug = require('debug')('rtcninja:RTCPeerConnection'),\n\tdebugerror = require('debug')('rtcninja:ERROR:RTCPeerConnection'),\n\tAdapter = require('./Adapter'),\n\n\t// Internal constants.\n\tC = {\n\t\tREGEXP_NORMALIZED_CANDIDATE: new RegExp(/^candidate:/i),\n\t\tREGEXP_FIX_CANDIDATE: new RegExp(/(^a=|\\r|\\n)/gi),\n\t\tREGEXP_RELAY_CANDIDATE: new RegExp(/ relay /i),\n\t\tREGEXP_SDP_CANDIDATES: new RegExp(/^a=candidate:.*\\r\\n/igm),\n\t\tREGEXP_SDP_NON_RELAY_CANDIDATES: new RegExp(/^a=candidate:(.(?!relay ))*\\r\\n/igm)\n\t},\n\n\t// Internal variables.\n\tVAR = {\n\t\tnormalizeCandidate: null\n\t};\n\ndebugerror.log = console.warn.bind(console);\n\n\n// Constructor\n\nfunction RTCPeerConnection(pcConfig, pcConstraints) {\n\tdebug('new | pcConfig: %o', pcConfig);\n\n\t// Set this.pcConfig and this.options.\n\tsetConfigurationAndOptions.call(this, pcConfig);\n\n\t// NOTE: Deprecated pcConstraints argument.\n\tthis.pcConstraints = pcConstraints;\n\n\t// Own version of the localDescription.\n\tthis.ourLocalDescription = null;\n\n\t// Latest values of PC attributes to avoid events with same value.\n\tthis.ourSignalingState = null;\n\tthis.ourIceConnectionState = null;\n\tthis.ourIceGatheringState = null;\n\n\t// Timer for options.gatheringTimeout.\n\tthis.timerGatheringTimeout = null;\n\n\t// Timer for options.gatheringTimeoutAfterRelay.\n\tthis.timerGatheringTimeoutAfterRelay = null;\n\n\t// Flag to ignore new gathered ICE candidates.\n\tthis.ignoreIceGathering = false;\n\n\t// Flag set when closed.\n\tthis.closed = false;\n\n\t// Set RTCPeerConnection.\n\tsetPeerConnection.call(this);\n\n\t// Set properties.\n\tsetProperties.call(this);\n}\n\n\n// Public API.\n\nRTCPeerConnection.prototype.createOffer = function (successCallback, failureCallback, options) {\n\tdebug('createOffer()');\n\n\tvar self = this;\n\n\tAdapter.fixRTCOfferOptions(options);\n\n\tthis.pc.createOffer(\n\t\tfunction (offer) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebug('createOffer() | success');\n\t\t\tif (successCallback) {\n\t\t\t\tsuccessCallback(offer);\n\t\t\t}\n\t\t},\n\t\tfunction (error) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebugerror('createOffer() | error:', error);\n\t\t\tif (failureCallback) {\n\t\t\t\tfailureCallback(error);\n\t\t\t}\n\t\t},\n\t\toptions\n\t);\n};\n\n\nRTCPeerConnection.prototype.createAnswer = function (successCallback, failureCallback, options) {\n\tdebug('createAnswer()');\n\n\tvar self = this;\n\n\tthis.pc.createAnswer(\n\t\tfunction (answer) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebug('createAnswer() | success');\n\t\t\tif (successCallback) {\n\t\t\t\tsuccessCallback(answer);\n\t\t\t}\n\t\t},\n\t\tfunction (error) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebugerror('createAnswer() | error:', error);\n\t\t\tif (failureCallback) {\n\t\t\t\tfailureCallback(error);\n\t\t\t}\n\t\t},\n\t\toptions\n\t);\n};\n\n\nRTCPeerConnection.prototype.setLocalDescription = function (description, successCallback, failureCallback) {\n\tdebug('setLocalDescription()');\n\n\tvar self = this;\n\n\tthis.pc.setLocalDescription(\n\t\tdescription,\n\t\t// success.\n\t\tfunction () {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebug('setLocalDescription() | success');\n\n\t\t\t// Clear gathering timers.\n\t\t\tclearTimeout(self.timerGatheringTimeout);\n\t\t\tdelete self.timerGatheringTimeout;\n\t\t\tclearTimeout(self.timerGatheringTimeoutAfterRelay);\n\t\t\tdelete self.timerGatheringTimeoutAfterRelay;\n\n\t\t\trunTimerGatheringTimeout();\n\t\t\tif (successCallback) {\n\t\t\t\tsuccessCallback();\n\t\t\t}\n\t\t},\n\t\t// failure\n\t\tfunction (error) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebugerror('setLocalDescription() | error:', error);\n\t\t\tif (failureCallback) {\n\t\t\t\tfailureCallback(error);\n\t\t\t}\n\t\t}\n\t);\n\n\t// Enable (again) ICE gathering.\n\tthis.ignoreIceGathering = false;\n\n\t// Handle gatheringTimeout.\n\tfunction runTimerGatheringTimeout() {\n\t\tif (typeof self.options.gatheringTimeout !== 'number') {\n\t\t\treturn;\n\t\t}\n\t\t// If setLocalDescription was already called, it may happen that\n\t\t// ICE gathering is not needed, so don't run this timer.\n\t\tif (self.pc.iceGatheringState === 'complete') {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('setLocalDescription() | ending gathering in %d ms (gatheringTimeout option)',\n\t\t\tself.options.gatheringTimeout);\n\n\t\tself.timerGatheringTimeout = setTimeout(function () {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdebug('forced end of candidates after gatheringTimeout timeout');\n\n\t\t\t// Clear gathering timers.\n\t\t\tdelete self.timerGatheringTimeout;\n\t\t\tclearTimeout(self.timerGatheringTimeoutAfterRelay);\n\t\t\tdelete self.timerGatheringTimeoutAfterRelay;\n\n\t\t\t// Ignore new candidates.\n\t\t\tself.ignoreIceGathering = true;\n\t\t\tif (self.onicecandidate) {\n\t\t\t\tself.onicecandidate({ candidate: null }, null);\n\t\t\t}\n\n\t\t}, self.options.gatheringTimeout);\n\t}\n};\n\n\nRTCPeerConnection.prototype.setRemoteDescription = function (description, successCallback, failureCallback) {\n\tdebug('setRemoteDescription()');\n\n\tvar self = this;\n\n\tthis.pc.setRemoteDescription(\n\t\tdescription,\n\t\tfunction () {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebug('setRemoteDescription() | success');\n\t\t\tif (successCallback) {\n\t\t\t\tsuccessCallback();\n\t\t\t}\n\t\t},\n\t\tfunction (error) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebugerror('setRemoteDescription() | error:', error);\n\t\t\tif (failureCallback) {\n\t\t\t\tfailureCallback(error);\n\t\t\t}\n\t\t}\n\t);\n};\n\n\nRTCPeerConnection.prototype.updateIce = function (pcConfig) {\n\tdebug('updateIce() | pcConfig: %o', pcConfig);\n\n\t// Update this.pcConfig and this.options.\n\tsetConfigurationAndOptions.call(this, pcConfig);\n\n\tthis.pc.updateIce(this.pcConfig);\n\n\t// Enable (again) ICE gathering.\n\tthis.ignoreIceGathering = false;\n};\n\n\nRTCPeerConnection.prototype.addIceCandidate = function (candidate, successCallback, failureCallback) {\n\tdebug('addIceCandidate() | candidate: %o', candidate);\n\n\tvar self = this;\n\n\tthis.pc.addIceCandidate(\n\t\tcandidate,\n\t\tfunction () {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebug('addIceCandidate() | success');\n\t\t\tif (successCallback) {\n\t\t\t\tsuccessCallback();\n\t\t\t}\n\t\t},\n\t\tfunction (error) {\n\t\t\tif (isClosed.call(self)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdebugerror('addIceCandidate() | error:', error);\n\t\t\tif (failureCallback) {\n\t\t\t\tfailureCallback(error);\n\t\t\t}\n\t\t}\n\t);\n};\n\n\nRTCPeerConnection.prototype.getConfiguration = function () {\n\tdebug('getConfiguration()');\n\n\treturn this.pc.getConfiguration();\n};\n\n\nRTCPeerConnection.prototype.getLocalStreams = function () {\n\tdebug('getLocalStreams()');\n\n\treturn this.pc.getLocalStreams();\n};\n\n\nRTCPeerConnection.prototype.getRemoteStreams = function () {\n\tdebug('getRemoteStreams()');\n\n\treturn this.pc.getRemoteStreams();\n};\n\n\nRTCPeerConnection.prototype.getStreamById = function (streamId) {\n\tdebug('getStreamById() | streamId: %s', streamId);\n\n\treturn this.pc.getStreamById(streamId);\n};\n\n\nRTCPeerConnection.prototype.addStream = function (stream) {\n\tdebug('addStream() | stream: %s', stream);\n\n\tthis.pc.addStream(stream);\n};\n\n\nRTCPeerConnection.prototype.removeStream = function (stream) {\n\tdebug('removeStream() | stream: %o', stream);\n\n\tthis.pc.removeStream(stream);\n};\n\n\nRTCPeerConnection.prototype.close = function () {\n\tdebug('close()');\n\n\tthis.closed = true;\n\n\t// Clear gathering timers.\n\tclearTimeout(this.timerGatheringTimeout);\n\tdelete this.timerGatheringTimeout;\n\tclearTimeout(this.timerGatheringTimeoutAfterRelay);\n\tdelete this.timerGatheringTimeoutAfterRelay;\n\n\tthis.pc.close();\n};\n\n\nRTCPeerConnection.prototype.createDataChannel = function () {\n\tdebug('createDataChannel()');\n\n\treturn this.pc.createDataChannel.apply(this.pc, arguments);\n};\n\n\nRTCPeerConnection.prototype.createDTMFSender = function (track) {\n\tdebug('createDTMFSender()');\n\n\treturn this.pc.createDTMFSender(track);\n};\n\n\nRTCPeerConnection.prototype.getStats = function () {\n\tdebug('getStats()');\n\n\treturn this.pc.getStats.apply(this.pc, arguments);\n};\n\n\nRTCPeerConnection.prototype.setIdentityProvider = function () {\n\tdebug('setIdentityProvider()');\n\n\treturn this.pc.setIdentityProvider.apply(this.pc, arguments);\n};\n\n\nRTCPeerConnection.prototype.getIdentityAssertion = function () {\n\tdebug('getIdentityAssertion()');\n\n\treturn this.pc.getIdentityAssertion();\n};\n\n\nRTCPeerConnection.prototype.reset = function (pcConfig) {\n\tdebug('reset() | pcConfig: %o', pcConfig);\n\n\tvar pc = this.pc;\n\n\t// Remove events in the old PC.\n\tpc.onnegotiationneeded = null;\n\tpc.onicecandidate = null;\n\tpc.onaddstream = null;\n\tpc.onremovestream = null;\n\tpc.ondatachannel = null;\n\tpc.onsignalingstatechange = null;\n\tpc.oniceconnectionstatechange = null;\n\tpc.onicegatheringstatechange = null;\n\tpc.onidentityresult = null;\n\tpc.onpeeridentity = null;\n\tpc.onidpassertionerror = null;\n\tpc.onidpvalidationerror = null;\n\n\t// Clear gathering timers.\n\tclearTimeout(this.timerGatheringTimeout);\n\tdelete this.timerGatheringTimeout;\n\tclearTimeout(this.timerGatheringTimeoutAfterRelay);\n\tdelete this.timerGatheringTimeoutAfterRelay;\n\n\t// Silently close the old PC.\n\tdebug('reset() | closing current peerConnection');\n\tpc.close();\n\n\t// Set this.pcConfig and this.options.\n\tsetConfigurationAndOptions.call(this, pcConfig);\n\n\t// Create a new PC.\n\tsetPeerConnection.call(this);\n};\n\n\n// Private Helpers.\n\nfunction setConfigurationAndOptions(pcConfig) {\n\t// Clone pcConfig.\n\tthis.pcConfig = merge(true, pcConfig);\n\n\t// Fix pcConfig.\n\tAdapter.fixPeerConnectionConfig(this.pcConfig);\n\n\tthis.options = {\n\t\ticeTransportsRelay: (this.pcConfig.iceTransports === 'relay'),\n\t\ticeTransportsNone: (this.pcConfig.iceTransports === 'none'),\n\t\tgatheringTimeout: this.pcConfig.gatheringTimeout,\n\t\tgatheringTimeoutAfterRelay: this.pcConfig.gatheringTimeoutAfterRelay\n\t};\n\n\t// Remove custom rtcninja.RTCPeerConnection options from pcConfig.\n\tdelete this.pcConfig.gatheringTimeout;\n\tdelete this.pcConfig.gatheringTimeoutAfterRelay;\n\n\tdebug('setConfigurationAndOptions | processed pcConfig: %o', this.pcConfig);\n}\n\n\nfunction isClosed() {\n\treturn ((this.closed) || (this.pc && this.pc.iceConnectionState === 'closed'));\n}\n\n\nfunction setEvents() {\n\tvar self = this,\n\t\tpc = this.pc;\n\n\tpc.onnegotiationneeded = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onnegotiationneeded()');\n\t\tif (self.onnegotiationneeded) {\n\t\t\tself.onnegotiationneeded(event);\n\t\t}\n\t};\n\n\tpc.onicecandidate = function (event) {\n\t\tvar candidate, isRelay, newCandidate;\n\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\t\tif (self.ignoreIceGathering) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ignore any candidate (event the null one) if iceTransports:'none' is set.\n\t\tif (self.options.iceTransportsNone) {\n\t\t\treturn;\n\t\t}\n\n\t\tcandidate = event.candidate;\n\n\t\tif (candidate) {\n\t\t\tisRelay = C.REGEXP_RELAY_CANDIDATE.test(candidate.candidate);\n\n\t\t\t// Ignore if just relay candidates are requested.\n\t\t\tif (self.options.iceTransportsRelay && !isRelay) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Handle gatheringTimeoutAfterRelay.\n\t\t\tif (isRelay && !self.timerGatheringTimeoutAfterRelay &&\n\t\t\t\t(typeof self.options.gatheringTimeoutAfterRelay === 'number')) {\n\t\t\t\tdebug('onicecandidate() | first relay candidate found, ending gathering in %d ms', self.options.gatheringTimeoutAfterRelay);\n\n\t\t\t\tself.timerGatheringTimeoutAfterRelay = setTimeout(function () {\n\t\t\t\t\tif (isClosed.call(self)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tdebug('forced end of candidates after timeout');\n\n\t\t\t\t\t// Clear gathering timers.\n\t\t\t\t\tdelete self.timerGatheringTimeoutAfterRelay;\n\t\t\t\t\tclearTimeout(self.timerGatheringTimeout);\n\t\t\t\t\tdelete self.timerGatheringTimeout;\n\n\t\t\t\t\t// Ignore new candidates.\n\t\t\t\t\tself.ignoreIceGathering = true;\n\t\t\t\t\tif (self.onicecandidate) {\n\t\t\t\t\t\tself.onicecandidate({candidate: null}, null);\n\t\t\t\t\t}\n\t\t\t\t}, self.options.gatheringTimeoutAfterRelay);\n\t\t\t}\n\n\t\t\tnewCandidate = new Adapter.RTCIceCandidate({\n\t\t\t\tsdpMid: candidate.sdpMid,\n\t\t\t\tsdpMLineIndex: candidate.sdpMLineIndex,\n\t\t\t\tcandidate: candidate.candidate\n\t\t\t});\n\n\t\t\t// Force correct candidate syntax (just check it once).\n\t\t\tif (VAR.normalizeCandidate === null) {\n\t\t\t\tif (C.REGEXP_NORMALIZED_CANDIDATE.test(candidate.candidate)) {\n\t\t\t\t\tVAR.normalizeCandidate = false;\n\t\t\t\t} else {\n\t\t\t\t\tdebug('onicecandidate() | normalizing ICE candidates syntax (remove \"a=\" and \"\\\\r\\\\n\")');\n\t\t\t\t\tVAR.normalizeCandidate = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (VAR.normalizeCandidate) {\n\t\t\t\tnewCandidate.candidate = candidate.candidate.replace(C.REGEXP_FIX_CANDIDATE, '');\n\t\t\t}\n\n\t\t\tdebug(\n\t\t\t\t'onicecandidate() | m%d(%s) %s',\n\t\t\t\tnewCandidate.sdpMLineIndex,\n\t\t\t\tnewCandidate.sdpMid || 'no mid', newCandidate.candidate);\n\t\t\tif (self.onicecandidate) {\n\t\t\t\tself.onicecandidate(event, newCandidate);\n\t\t\t}\n\t\t// Null candidate (end of candidates).\n\t\t} else {\n\t\t\tdebug('onicecandidate() | end of candidates');\n\n\t\t\t// Clear gathering timers.\n\t\t\tclearTimeout(self.timerGatheringTimeout);\n\t\t\tdelete self.timerGatheringTimeout;\n\t\t\tclearTimeout(self.timerGatheringTimeoutAfterRelay);\n\t\t\tdelete self.timerGatheringTimeoutAfterRelay;\n\t\t\tif (self.onicecandidate) {\n\t\t\t\tself.onicecandidate(event, null);\n\t\t\t}\n\t\t}\n\t};\n\n\tpc.onaddstream = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onaddstream() | stream: %o', event.stream);\n\t\tif (self.onaddstream) {\n\t\t\tself.onaddstream(event, event.stream);\n\t\t}\n\t};\n\n\tpc.onremovestream = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onremovestream() | stream: %o', event.stream);\n\t\tif (self.onremovestream) {\n\t\t\tself.onremovestream(event, event.stream);\n\t\t}\n\t};\n\n\tpc.ondatachannel = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('ondatachannel() | datachannel: %o', event.channel);\n\t\tif (self.ondatachannel) {\n\t\t\tself.ondatachannel(event, event.channel);\n\t\t}\n\t};\n\n\tpc.onsignalingstatechange = function (event) {\n\t\tif (pc.signalingState === self.ourSignalingState) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onsignalingstatechange() | signalingState: %s', pc.signalingState);\n\t\tself.ourSignalingState = pc.signalingState;\n\t\tif (self.onsignalingstatechange) {\n\t\t\tself.onsignalingstatechange(event, pc.signalingState);\n\t\t}\n\t};\n\n\tpc.oniceconnectionstatechange = function (event) {\n\t\tif (pc.iceConnectionState === self.ourIceConnectionState) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('oniceconnectionstatechange() | iceConnectionState: %s', pc.iceConnectionState);\n\t\tself.ourIceConnectionState = pc.iceConnectionState;\n\t\tif (self.oniceconnectionstatechange) {\n\t\t\tself.oniceconnectionstatechange(event, pc.iceConnectionState);\n\t\t}\n\t};\n\n\tpc.onicegatheringstatechange = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (pc.iceGatheringState === self.ourIceGatheringState) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onicegatheringstatechange() | iceGatheringState: %s', pc.iceGatheringState);\n\t\tself.ourIceGatheringState = pc.iceGatheringState;\n\t\tif (self.onicegatheringstatechange) {\n\t\t\tself.onicegatheringstatechange(event, pc.iceGatheringState);\n\t\t}\n\t};\n\n\tpc.onidentityresult = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onidentityresult()');\n\t\tif (self.onidentityresult) {\n\t\t\tself.onidentityresult(event);\n\t\t}\n\t};\n\n\tpc.onpeeridentity = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onpeeridentity()');\n\t\tif (self.onpeeridentity) {\n\t\t\tself.onpeeridentity(event);\n\t\t}\n\t};\n\n\tpc.onidpassertionerror = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onidpassertionerror()');\n\t\tif (self.onidpassertionerror) {\n\t\t\tself.onidpassertionerror(event);\n\t\t}\n\t};\n\n\tpc.onidpvalidationerror = function (event) {\n\t\tif (isClosed.call(self)) {\n\t\t\treturn;\n\t\t}\n\n\t\tdebug('onidpvalidationerror()');\n\t\tif (self.onidpvalidationerror) {\n\t\t\tself.onidpvalidationerror(event);\n\t\t}\n\t};\n}\n\n\nfunction setPeerConnection() {\n\t// Create a RTCPeerConnection.\n\tif (!this.pcConstraints) {\n\t\tthis.pc = new Adapter.RTCPeerConnection(this.pcConfig);\n\t} else {\n\t\t// NOTE: Deprecated.\n\t\tthis.pc = new Adapter.RTCPeerConnection(this.pcConfig, this.pcConstraints);\n\t}\n\n\t// Set RTC events.\n\tsetEvents.call(this);\n}\n\n\nfunction getLocalDescription() {\n\tvar pc = this.pc,\n\t\toptions = this.options,\n\t\tsdp = null;\n\n\tif (!pc.localDescription) {\n\t\tthis.ourLocalDescription = null;\n\t\treturn null;\n\t}\n\n\t// Mangle the SDP string.\n\tif (options.iceTransportsRelay) {\n\t\tsdp = pc.localDescription.sdp.replace(C.REGEXP_SDP_NON_RELAY_CANDIDATES, '');\n\t} else if (options.iceTransportsNone) {\n\t\tsdp = pc.localDescription.sdp.replace(C.REGEXP_SDP_CANDIDATES, '');\n\t}\n\n\tthis.ourLocalDescription = new Adapter.RTCSessionDescription({\n\t\ttype: pc.localDescription.type,\n\t\tsdp: sdp || pc.localDescription.sdp\n\t});\n\n\treturn this.ourLocalDescription;\n}\n\n\nfunction setProperties() {\n\tvar self = this;\n\n\tObject.defineProperties(this, {\n\t\tpeerConnection: {\n\t\t\tget: function () {\n\t\t\t\treturn self.pc;\n\t\t\t}\n\t\t},\n\n\t\tsignalingState: {\n\t\t\tget: function () {\n\t\t\t\treturn self.pc.signalingState;\n\t\t\t}\n\t\t},\n\n\t\ticeConnectionState: {\n\t\t\tget: function () {\n\t\t\t\treturn self.pc.iceConnectionState;\n\t\t\t}\n\t\t},\n\n\t\ticeGatheringState: {\n\t\t\tget: function () {\n\t\t\t\treturn self.pc.iceGatheringState;\n\t\t\t}\n\t\t},\n\n\t\tlocalDescription: {\n\t\t\tget: function () {\n\t\t\t\treturn getLocalDescription.call(self);\n\t\t\t}\n\t\t},\n\n\t\tremoteDescription: {\n\t\t\tget: function () {\n\t\t\t\treturn self.pc.remoteDescription;\n\t\t\t}\n\t\t},\n\n\t\tpeerIdentity: {\n\t\t\tget: function () {\n\t\t\t\treturn self.pc.peerIdentity;\n\t\t\t}\n\t\t}\n\t});\n}\n","'use strict';\n\nmodule.exports = rtcninja;\n\n\n// Dependencies.\n\nvar browser = require('bowser'),\n\tdebug = require('debug')('rtcninja'),\n\tdebugerror = require('debug')('rtcninja:ERROR'),\n\tversion = require('./version'),\n\tAdapter = require('./Adapter'),\n\tRTCPeerConnection = require('./RTCPeerConnection'),\n\n\t// Internal vars.\n\tcalled = false;\n\ndebugerror.log = console.warn.bind(console);\ndebug('version %s', version);\ndebug('detected browser: %s %s [mobile:%s, tablet:%s, android:%s, ios:%s]',\n\t\tbrowser.name, browser.version, !!browser.mobile, !!browser.tablet,\n\t\t!!browser.android, !!browser.ios);\n\n\n// Constructor.\n\nfunction rtcninja(options) {\n\t// Load adapter\n\tvar iface = Adapter(options || {}); // jshint ignore:line\n\n\tcalled = true;\n\n\t// Expose RTCPeerConnection class.\n\trtcninja.RTCPeerConnection = RTCPeerConnection;\n\n\t// Expose WebRTC API and utils.\n\trtcninja.getUserMedia = iface.getUserMedia;\n\trtcninja.RTCSessionDescription = iface.RTCSessionDescription;\n\trtcninja.RTCIceCandidate = iface.RTCIceCandidate;\n\trtcninja.MediaStreamTrack = iface.MediaStreamTrack;\n\trtcninja.getMediaDevices = iface.getMediaDevices;\n\trtcninja.attachMediaStream = iface.attachMediaStream;\n\trtcninja.closeMediaStream = iface.closeMediaStream;\n\trtcninja.canRenegotiate = iface.canRenegotiate;\n\n\t// Log WebRTC support.\n\tif (iface.hasWebRTC()) {\n\t\tdebug('WebRTC supported');\n\t\treturn true;\n\t} else {\n\t\tdebugerror('WebRTC not supported');\n\t\treturn false;\n\t}\n}\n\n\n// Public API.\n\n// If called without calling rtcninja(), call it.\nrtcninja.hasWebRTC = function () {\n\tif (!called) {\n\t\trtcninja();\n\t}\n\n\treturn Adapter.hasWebRTC();\n};\n\n\n// Expose version property.\nObject.defineProperty(rtcninja, 'version', {\n\tget: function () {\n\t\treturn version;\n\t}\n});\n\n\n// Expose called property.\nObject.defineProperty(rtcninja, 'called', {\n\tget: function () {\n\t\treturn called;\n\t}\n});\n\n\n// Exposing stuff.\n\nrtcninja.debug = require('debug');\nrtcninja.browser = browser;\n","'use strict';\n\n// Expose the 'version' field of package.json.\nmodule.exports = require('../package.json').version;\n\n","/*!\n * Bowser - a browser detector\n * https://github.com/ded/bowser\n * MIT License | (c) Dustin Diaz 2015\n */\n\n!function (name, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(definition)\n else this[name] = definition()\n}('bowser', function () {\n /**\n * See useragents.js for examples of navigator.userAgent\n */\n\n var t = true\n\n function detect(ua) {\n\n function getFirstMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[1]) || '';\n }\n\n function getSecondMatch(regex) {\n var match = ua.match(regex);\n return (match && match.length > 1 && match[2]) || '';\n }\n\n var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()\n , likeAndroid = /like android/i.test(ua)\n , android = !likeAndroid && /android/i.test(ua)\n , chromeBook = /CrOS/.test(ua)\n , edgeVersion = getFirstMatch(/edge\\/(\\d+(\\.\\d+)?)/i)\n , versionIdentifier = getFirstMatch(/version\\/(\\d+(\\.\\d+)?)/i)\n , tablet = /tablet/i.test(ua)\n , mobile = !tablet && /[^-]mobi/i.test(ua)\n , result\n\n if (/opera|opr/i.test(ua)) {\n result = {\n name: 'Opera'\n , opera: t\n , version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/yabrowser/i.test(ua)) {\n result = {\n name: 'Yandex Browser'\n , yandexbrowser: t\n , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\\s\\/](\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/windows phone/i.test(ua)) {\n result = {\n name: 'Windows Phone'\n , windowsphone: t\n }\n if (edgeVersion) {\n result.msedge = t\n result.version = edgeVersion\n }\n else {\n result.msie = t\n result.version = getFirstMatch(/iemobile\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/msie|trident/i.test(ua)) {\n result = {\n name: 'Internet Explorer'\n , msie: t\n , version: getFirstMatch(/(?:msie |rv:)(\\d+(\\.\\d+)?)/i)\n }\n } else if (chromeBook) {\n result = {\n name: 'Chrome'\n , chromeBook: t\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n } else if (/chrome.+? edge/i.test(ua)) {\n result = {\n name: 'Microsoft Edge'\n , msedge: t\n , version: edgeVersion\n }\n }\n else if (/chrome|crios|crmo/i.test(ua)) {\n result = {\n name: 'Chrome'\n , chrome: t\n , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (iosdevice) {\n result = {\n name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'\n }\n // WTF: version is not part of user agent in web apps\n if (versionIdentifier) {\n result.version = versionIdentifier\n }\n }\n else if (/sailfish/i.test(ua)) {\n result = {\n name: 'Sailfish'\n , sailfish: t\n , version: getFirstMatch(/sailfish\\s?browser\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/seamonkey\\//i.test(ua)) {\n result = {\n name: 'SeaMonkey'\n , seamonkey: t\n , version: getFirstMatch(/seamonkey\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/firefox|iceweasel/i.test(ua)) {\n result = {\n name: 'Firefox'\n , firefox: t\n , version: getFirstMatch(/(?:firefox|iceweasel)[ \\/](\\d+(\\.\\d+)?)/i)\n }\n if (/\\((mobile|tablet);[^\\)]*rv:[\\d\\.]+\\)/i.test(ua)) {\n result.firefoxos = t\n }\n }\n else if (/silk/i.test(ua)) {\n result = {\n name: 'Amazon Silk'\n , silk: t\n , version : getFirstMatch(/silk\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (android) {\n result = {\n name: 'Android'\n , version: versionIdentifier\n }\n }\n else if (/phantom/i.test(ua)) {\n result = {\n name: 'PhantomJS'\n , phantom: t\n , version: getFirstMatch(/phantomjs\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/blackberry|\\bbb\\d+/i.test(ua) || /rim\\stablet/i.test(ua)) {\n result = {\n name: 'BlackBerry'\n , blackberry: t\n , version: versionIdentifier || getFirstMatch(/blackberry[\\d]+\\/(\\d+(\\.\\d+)?)/i)\n }\n }\n else if (/(web|hpw)os/i.test(ua)) {\n result = {\n name: 'WebOS'\n , webos: t\n , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\\/(\\d+(\\.\\d+)?)/i)\n };\n /touchpad\\//i.test(ua) && (result.touchpad = t)\n }\n else if (/bada/i.test(ua)) {\n result = {\n name: 'Bada'\n , bada: t\n , version: getFirstMatch(/dolfin\\/(\\d+(\\.\\d+)?)/i)\n };\n }\n else if (/tizen/i.test(ua)) {\n result = {\n name: 'Tizen'\n , tizen: t\n , version: getFirstMatch(/(?:tizen\\s?)?browser\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n };\n }\n else if (/safari/i.test(ua)) {\n result = {\n name: 'Safari'\n , safari: t\n , version: versionIdentifier\n }\n }\n else {\n result = {\n name: getFirstMatch(/^(.*)\\/(.*) /),\n version: getSecondMatch(/^(.*)\\/(.*) /)\n };\n }\n\n // set webkit or gecko flag for browsers based on these engines\n if (!result.msedge && /(apple)?webkit/i.test(ua)) {\n result.name = result.name || \"Webkit\"\n result.webkit = t\n if (!result.version && versionIdentifier) {\n result.version = versionIdentifier\n }\n } else if (!result.opera && /gecko\\//i.test(ua)) {\n result.name = result.name || \"Gecko\"\n result.gecko = t\n result.version = result.version || getFirstMatch(/gecko\\/(\\d+(\\.\\d+)?)/i)\n }\n\n // set OS flags for platforms that have multiple browsers\n if (!result.msedge && (android || result.silk)) {\n result.android = t\n } else if (iosdevice) {\n result[iosdevice] = t\n result.ios = t\n }\n\n // OS version extraction\n var osVersion = '';\n if (result.windowsphone) {\n osVersion = getFirstMatch(/windows phone (?:os)?\\s?(\\d+(\\.\\d+)*)/i);\n } else if (iosdevice) {\n osVersion = getFirstMatch(/os (\\d+([_\\s]\\d+)*) like mac os x/i);\n osVersion = osVersion.replace(/[_\\s]/g, '.');\n } else if (android) {\n osVersion = getFirstMatch(/android[ \\/-](\\d+(\\.\\d+)*)/i);\n } else if (result.webos) {\n osVersion = getFirstMatch(/(?:web|hpw)os\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.blackberry) {\n osVersion = getFirstMatch(/rim\\stablet\\sos\\s(\\d+(\\.\\d+)*)/i);\n } else if (result.bada) {\n osVersion = getFirstMatch(/bada\\/(\\d+(\\.\\d+)*)/i);\n } else if (result.tizen) {\n osVersion = getFirstMatch(/tizen[\\/\\s](\\d+(\\.\\d+)*)/i);\n }\n if (osVersion) {\n result.osversion = osVersion;\n }\n\n // device type extraction\n var osMajorVersion = osVersion.split('.')[0];\n if (tablet || iosdevice == 'ipad' || (android && (osMajorVersion == 3 || (osMajorVersion == 4 && !mobile))) || result.silk) {\n result.tablet = t\n } else if (mobile || iosdevice == 'iphone' || iosdevice == 'ipod' || android || result.blackberry || result.webos || result.bada) {\n result.mobile = t\n }\n\n // Graded Browser Support\n // http://developer.yahoo.com/yui/articles/gbs\n if (result.msedge ||\n (result.msie && result.version >= 10) ||\n (result.yandexbrowser && result.version >= 15) ||\n (result.chrome && result.version >= 20) ||\n (result.firefox && result.version >= 20.0) ||\n (result.safari && result.version >= 6) ||\n (result.opera && result.version >= 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] >= 6) ||\n (result.blackberry && result.version >= 10.1)\n ) {\n result.a = t;\n }\n else if ((result.msie && result.version < 10) ||\n (result.chrome && result.version < 20) ||\n (result.firefox && result.version < 20.0) ||\n (result.safari && result.version < 6) ||\n (result.opera && result.version < 10.0) ||\n (result.ios && result.osversion && result.osversion.split(\".\")[0] < 6)\n ) {\n result.c = t\n } else result.x = t\n\n return result\n }\n\n var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '')\n\n bowser.test = function (browserList) {\n for (var i = 0; i < browserList.length; ++i) {\n var browserItem = browserList[i];\n if (typeof browserItem=== 'string') {\n if (browserItem in bowser) {\n return true;\n }\n }\n }\n return false;\n }\n\n /*\n * Set our detect method to the main bowser object so we can\n * reuse it to test other user agents.\n * This is needed to implement future tests.\n */\n bowser._detect = detect;\n\n return bowser\n});\n","/*!\r\n * @name JavaScript/NodeJS Merge v1.2.0\r\n * @author yeikos\r\n * @repository https://github.com/yeikos/js.merge\r\n\r\n * Copyright 2014 yeikos - MIT license\r\n * https://raw.github.com/yeikos/js.merge/master/LICENSE\r\n */\r\n\r\n;(function(isNode) {\r\n\r\n\t/**\r\n\t * Merge one or more objects \r\n\t * @param bool? clone\r\n\t * @param mixed,... arguments\r\n\t * @return object\r\n\t */\r\n\r\n\tvar Public = function(clone) {\r\n\r\n\t\treturn merge(clone === true, false, arguments);\r\n\r\n\t}, publicName = 'merge';\r\n\r\n\t/**\r\n\t * Merge two or more objects recursively \r\n\t * @param bool? clone\r\n\t * @param mixed,... arguments\r\n\t * @return object\r\n\t */\r\n\r\n\tPublic.recursive = function(clone) {\r\n\r\n\t\treturn merge(clone === true, true, arguments);\r\n\r\n\t};\r\n\r\n\t/**\r\n\t * Clone the input removing any reference\r\n\t * @param mixed input\r\n\t * @return mixed\r\n\t */\r\n\r\n\tPublic.clone = function(input) {\r\n\r\n\t\tvar output = input,\r\n\t\t\ttype = typeOf(input),\r\n\t\t\tindex, size;\r\n\r\n\t\tif (type === 'array') {\r\n\r\n\t\t\toutput = [];\r\n\t\t\tsize = input.length;\r\n\r\n\t\t\tfor (index=0;index=0.10.32\"\n },\n \"dependencies\": {\n \"bowser\": \"^1.0.0\",\n \"debug\": \"^2.2.0\",\n \"merge\": \"^1.2.0\"\n },\n \"devDependencies\": {\n \"browserify\": \"^11.0.1\",\n \"gulp\": \"git+https://github.com/gulpjs/gulp.git#4.0\",\n \"gulp-expect-file\": \"0.0.7\",\n \"gulp-filelog\": \"^0.4.1\",\n \"gulp-header\": \"^1.7.1\",\n \"gulp-jscs\": \"^2.0.0\",\n \"gulp-jscs-stylish\": \"^1.1.2\",\n \"gulp-jshint\": \"^1.11.2\",\n \"gulp-rename\": \"^1.2.2\",\n \"gulp-uglify\": \"^1.4.0\",\n \"jshint-stylish\": \"^2.0.1\",\n \"retire\": \"^1.1.1\",\n \"shelljs\": \"^0.5.3\",\n \"vinyl-source-stream\": \"^1.1.0\"\n },\n \"gitHead\": \"18789cbefdb5a6c6c038ab4f1ce8e9e3813135b0\",\n \"bugs\": {\n \"url\": \"https://github.com/eface2face/rtcninja.js/issues\"\n },\n \"_id\": \"rtcninja@0.6.4\",\n \"scripts\": {},\n \"_shasum\": \"7ede8577ce978cb431772d877967c53aadeb5e99\",\n \"_from\": \"rtcninja@0.6.4\",\n \"_npmVersion\": \"2.5.1\",\n \"_nodeVersion\": \"0.12.0\",\n \"_npmUser\": {\n \"name\": \"ibc\",\n \"email\": \"ibc@aliax.net\"\n },\n \"dist\": {\n \"shasum\": \"7ede8577ce978cb431772d877967c53aadeb5e99\",\n \"tarball\": \"http://registry.npmjs.org/rtcninja/-/rtcninja-0.6.4.tgz\"\n },\n \"maintainers\": [\n {\n \"name\": \"ibc\",\n \"email\": \"ibc@aliax.net\"\n }\n ],\n \"directories\": {},\n \"_resolved\": \"https://registry.npmjs.org/rtcninja/-/rtcninja-0.6.4.tgz\"\n}\n","var _global = (function() { return this; })();\nvar nativeWebSocket = _global.WebSocket || _global.MozWebSocket;\n\n\n/**\n * Expose a W3C WebSocket class with just one or two arguments.\n */\nfunction W3CWebSocket(uri, protocols) {\n\tvar native_instance;\n\n\tif (protocols) {\n\t\tnative_instance = new nativeWebSocket(uri, protocols);\n\t}\n\telse {\n\t\tnative_instance = new nativeWebSocket(uri);\n\t}\n\n\t/**\n\t * 'native_instance' is an instance of nativeWebSocket (the browser's WebSocket\n\t * class). Since it is an Object it will be returned as it is when creating an\n\t * instance of W3CWebSocket via 'new W3CWebSocket()'.\n\t *\n\t * ECMAScript 5: http://bclary.com/2004/11/07/#a-13.2.2\n\t */\n\treturn native_instance;\n}\n\n\n/**\n * Module exports.\n */\nmodule.exports = {\n 'w3cwebsocket' : nativeWebSocket ? W3CWebSocket : null,\n 'version' : require('./version')\n};\n","module.exports = require('../package.json').version;\n","module.exports={\n \"name\": \"websocket\",\n \"description\": \"Websocket Client & Server Library implementing the WebSocket protocol as specified in RFC 6455.\",\n \"keywords\": [\n \"websocket\",\n \"websockets\",\n \"socket\",\n \"networking\",\n \"comet\",\n \"push\",\n \"RFC-6455\",\n \"realtime\",\n \"server\",\n \"client\"\n ],\n \"author\": {\n \"name\": \"Brian McKelvey\",\n \"email\": \"brian@worlize.com\",\n \"url\": \"https://www.worlize.com/\"\n },\n \"contributors\": [\n {\n \"name\": \"Iñaki Baz Castillo\",\n \"email\": \"ibc@aliax.net\",\n \"url\": \"http://dev.sipdoc.net\"\n }\n ],\n \"version\": \"1.0.21\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/theturtle32/WebSocket-Node.git\"\n },\n \"homepage\": \"https://github.com/theturtle32/WebSocket-Node\",\n \"engines\": {\n \"node\": \">=0.8.0\"\n },\n \"dependencies\": {\n \"debug\": \"~2.2.0\",\n \"nan\": \"~1.8.x\",\n \"typedarray-to-buffer\": \"~3.0.3\",\n \"yaeti\": \"~0.0.4\"\n },\n \"devDependencies\": {\n \"buffer-equal\": \"^0.0.1\",\n \"faucet\": \"^0.0.1\",\n \"gulp\": \"git+https://github.com/gulpjs/gulp.git#4.0\",\n \"gulp-jshint\": \"^1.11.2\",\n \"jshint-stylish\": \"^1.0.2\",\n \"tape\": \"^4.0.1\"\n },\n \"config\": {\n \"verbose\": false\n },\n \"scripts\": {\n \"install\": \"(node-gyp rebuild 2> builderror.log) || (exit 0)\",\n \"test\": \"faucet test/unit\",\n \"gulp\": \"gulp\"\n },\n \"main\": \"index\",\n \"directories\": {\n \"lib\": \"./lib\"\n },\n \"browser\": \"lib/browser.js\",\n \"license\": \"Apache-2.0\",\n \"gitHead\": \"8f5d5f3ef3d946324fe016d525893546ff6500e1\",\n \"bugs\": {\n \"url\": \"https://github.com/theturtle32/WebSocket-Node/issues\"\n },\n \"_id\": \"websocket@1.0.21\",\n \"_shasum\": \"f51f0a96ed19629af39922470ab591907f1c5bd9\",\n \"_from\": \"websocket@1.0.21\",\n \"_npmVersion\": \"2.12.1\",\n \"_nodeVersion\": \"2.3.4\",\n \"_npmUser\": {\n \"name\": \"theturtle32\",\n \"email\": \"brian@worlize.com\"\n },\n \"maintainers\": [\n {\n \"name\": \"theturtle32\",\n \"email\": \"brian@worlize.com\"\n }\n ],\n \"dist\": {\n \"shasum\": \"f51f0a96ed19629af39922470ab591907f1c5bd9\",\n \"tarball\": \"http://registry.npmjs.org/websocket/-/websocket-1.0.21.tgz\"\n },\n \"_resolved\": \"https://registry.npmjs.org/websocket/-/websocket-1.0.21.tgz\",\n \"readme\": \"ERROR: No README data found!\"\n}\n"]} \ No newline at end of file diff --git a/resources/html/webrtcgateway/test/components/accountbox.jsx b/resources/html/webrtcgateway/test/components/accountbox.jsx deleted file mode 100644 index 0882cce..0000000 --- a/resources/html/webrtcgateway/test/components/accountbox.jsx +++ /dev/null @@ -1,107 +0,0 @@ - -var AccountBox = React.createClass({ - getInitialState: function() { - return {accountId: '', - password: '', - account: null, - registrationState: null, - addInProgress: false, - registerInProgress: false, - }; - }, - - componentWillReceiveProps: function(nextProps) { - if (this.props.connection !== null && nextProps.connection === null) { - // we have been disconnected! - this.replaceState(this.getInitialState()); - } - }, - - handleAccountIdChange: function(event) { - this.setState({accountId: event.target.value}); - }, - - handlePasswordChange: function(event) { - this.setState({password: event.target.value}); - }, - - registrationStateChanged: function(oldState, newState, data) { - this.setState({registrationState: newState}); - switch (newState) { - case 'failed': - case 'registered': - case 'unregistered': - case null: - this.setState({registerInProgress: false}); - break; - default: - break; - } - }, - - toggleAdd: function(event) { - event.preventDefault(); - var conn = this.props.connection; - var self = this; - this.setState({addInProgress: true}); - if (this.state.account === null) { - var options = {account: this.state.accountId, password: this.state.password}; - conn.addAccount(options, function(error, account) { - if (!error) { - account.on('registrationStateChanged', self.registrationStateChanged); - } else { - console.log('Error adding account: ' + error); - } - self.setState({account: account, addInProgress: false}); - self.props.setAccount(account); - }); - } else { - conn.removeAccount(this.state.account, function(error) { - if (error) { - console.log('Error removing account: ' + error); - } - self.replaceState(self.getInitialState()); - self.props.setAccount(null); - }); - } - }, - - toggleRegister: function(event) { - event.preventDefault(); - this.setState({registerInProgress: true}); - if (this.state.registrationState !== null) { - this.state.account.unregister(); - } else { - this.state.account.register(); - } - }, - - render: function() { - var connectionReady = this.props.connection !== null && this.props.connection.state === 'ready'; - var accountReady = this.state.account !== null; - return ( -
-
-
- Account - -
-
-
- Password - -
-
-
- - -
-
-
- ); - }, -}); diff --git a/resources/html/webrtcgateway/test/components/app.jsx b/resources/html/webrtcgateway/test/components/app.jsx deleted file mode 100644 index 909d7a0..0000000 --- a/resources/html/webrtcgateway/test/components/app.jsx +++ /dev/null @@ -1,167 +0,0 @@ - -var SylkTest = React.createClass({ - getInitialState: function() { - return { - connection: null, - connectionState: null, - account: null, - registrationState: null, - currentCall: null, - callState: null, - }; - }, - - getServerUrl: function() { - return window.location.protocol.replace('http', 'ws') + '//' + window.location.host + '/webrtcgateway/ws'; - }, - - connectionStateChanged: function(oldState, newState) { - switch (newState) { - case 'closed': - this.setState({connection: null, connectionState: newState}); - break; - case 'disconnected': - if (this.state.currentCall) { - this.state.currentCall.terminate(); - } - this.setState({account: null, registrationState: null, currentCall: null, callState: null, connectionState: newState}); - break; - default: - this.setState({connectionState: newState}); - break; - } - }, - - registrationStateChanged: function(oldState, newState, data) { - var state = newState; - if (newState === 'failed') { - state += ' (' + data.reason + ')' - } - this.setState({registrationState: state}); - }, - - callStateChanged: function(oldState, newState, data) { - var state = newState; - var currentCall = this.state.currentCall; - if (newState === 'terminated') { - state += ' (' + data.reason + ')'; - currentCall = null; - setTimeout(() => { - if (this.state.currentCall === null) { - this.setState({callState: null}); - } - }, 4000); - } - this.setState({currentCall: currentCall, callState: state}); - }, - - setAccount: function(account) { - if (account !== null) { - account.on('registrationStateChanged', this.registrationStateChanged); - account.on('incomingCall', this.handleNewCall); - account.on('outgoingCall', this.handleNewCall); - } - this.setState({account: account}); - }, - - handleNewCall: function(call) { - if (this.state.currentCall !== null) { - call.terminate(); - } else { - call.on('stateChanged', this.callStateChanged); - this.setState({currentCall: call, callState: call.state}); - } - }, - - toggleConnect: function(event) { - event.preventDefault(); - if (this.state.connection === null) { - var connection = sylkrtc.createConnection({server: this.getServerUrl()}); - connection.on('stateChanged', this.connectionStateChanged); - this.setState({connection: connection}); - } else { - this.state.connection.close(); - } - }, - - render: function() { - var accountBox; - var callBox; - var videoBox; - var ringtonePlayer; - if (sylkrtc.isWebRTCSupported()) { - accountBox = ; - if (this.state.callState === 'established') { - videoBox = - } else { - if (this.state.currentCall) { - ringtonePlayer = - } - if (this.state.currentCall === null || this.state.currentCall.direction === 'outgoing') { - callBox = - } else { - callBox = - } - } - } else { - accountBox =
-

Your browser does not support WebRTC

-

- Too bad! Checkout the WebRTC support across browsers in the link below. -
- Is WebRTC ready yet? -

-
; - } - return ( -
- -
-
-
-
- {accountBox} -
- {videoBox} - {callBox} - {ringtonePlayer} -
-
-
-
- WebSocket server — {this.getServerUrl()} -
-
-
- -
- ); - } -}); diff --git a/resources/html/webrtcgateway/test/components/incomingcall.jsx b/resources/html/webrtcgateway/test/components/incomingcall.jsx deleted file mode 100644 index 5a60620..0000000 --- a/resources/html/webrtcgateway/test/components/incomingcall.jsx +++ /dev/null @@ -1,33 +0,0 @@ - -var IncomingCall = React.createClass({ - answerClicked: function(event) { - event.preventDefault(); - var callOptions = {pcConfig: {iceServers: [{urls: 'stun:stun.l.google.com:19302'}]}}; - this.props.call.answer(callOptions); - }, - - hangupClicked: function(event) { - event.preventDefault(); - this.props.call.terminate(); - }, - - render: function() { - return ( -
-
-
- - - - - -
-
-
- ); - }, -}); diff --git a/resources/html/webrtcgateway/test/components/outgoingcall.jsx b/resources/html/webrtcgateway/test/components/outgoingcall.jsx deleted file mode 100644 index 04b06f8..0000000 --- a/resources/html/webrtcgateway/test/components/outgoingcall.jsx +++ /dev/null @@ -1,59 +0,0 @@ - -var OutgoingCall = React.createClass({ - getInitialState: function() { - return { - call: null, - targetUri: '', - }; - }, - - callStateChanged: function(oldState, newState, data) { - if (!this.isMounted()) { - // we might get here when the component has been unmounted - return; - } - if (newState === 'terminated') { - this.replaceState(this.getInitialState()); - } - }, - - toggleCall: function(event) { - event.preventDefault(); - if (this.state.call === null) { - var callOptions = {pcConfig: {iceServers: [{urls: 'stun:stun.l.google.com:19302'}]}}; - var call = this.props.account.call(this.state.targetUri, callOptions); - call.on('stateChanged', this.callStateChanged); - this.setState({call: call}); - } else { - this.state.call.terminate(); - } - }, - - handleTargetChange: function(event) { - this.setState({targetUri: event.target.value}); - }, - - render: function() { - var ready = this.props.account !== null; - var buttonClasses = 'btn'; - if (this.state.call) { - buttonClasses += ' btn-danger'; - } else { - buttonClasses += ' btn-success'; - } - return ( -
-
-
- - - - -
-
-
- ); - }, -}); diff --git a/resources/html/webrtcgateway/test/components/ringtoneplayer.jsx b/resources/html/webrtcgateway/test/components/ringtoneplayer.jsx deleted file mode 100644 index e12a225..0000000 --- a/resources/html/webrtcgateway/test/components/ringtoneplayer.jsx +++ /dev/null @@ -1,30 +0,0 @@ - -var RingtonePlayer = React.createClass({ - audioEnded: function() { - this.timeout = setTimeout(() => { - this.refs.audio.getDOMNode().play(); - }, 4500); - }, - - componentDidMount: function() { - this.refs.audio.getDOMNode().addEventListener('ended', this.audioEnded); - }, - - componentWillUnmount: function() { - if (this.timeout) { - clearTimeout(this.timeout); - } - this.timeout = null; - this.refs.audio.getDOMNode().removeEventListener('ended', this.audioEnded); - }, - - render: function() { - return ( -
- -
- ); - } -}); diff --git a/resources/html/webrtcgateway/test/components/videobox.jsx b/resources/html/webrtcgateway/test/components/videobox.jsx deleted file mode 100644 index 45d6f4c..0000000 --- a/resources/html/webrtcgateway/test/components/videobox.jsx +++ /dev/null @@ -1,36 +0,0 @@ - -var VideoBox = React.createClass({ - componentDidMount: function() { - var localStream = this.props.call.getLocalStreams()[0]; - var localVideoElement = React.findDOMNode(this.refs.localVideo); - var remoteStream = this.props.call.getRemoteStreams()[0]; - var remoteVideoElement = React.findDOMNode(this.refs.callVideo); - sylkrtc.attachMediaStream(localVideoElement, localStream); - sylkrtc.attachMediaStream(remoteVideoElement, remoteStream); - }, - - hangupClicked: function(event) { - event.preventDefault(); - this.props.call.terminate(); - }, - - render: function() { - return ( -
-

-

Call with {this.props.call.remoteIdentity}

-

-
-
-
-
- -
-
- ); - }, -}); diff --git a/resources/html/webrtcgateway/test/index.html b/resources/html/webrtcgateway/test/index.html deleted file mode 100644 index 5d5243f..0000000 --- a/resources/html/webrtcgateway/test/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SylkServer WebRTC Test Application - - - - - - - - - - - - - - - diff --git a/resources/html/webrtcgateway/test/sounds/ringtone.wav b/resources/html/webrtcgateway/test/sounds/ringtone.wav deleted file mode 100644 index e72dd50..0000000 Binary files a/resources/html/webrtcgateway/test/sounds/ringtone.wav and /dev/null differ