var util = { chromeCompatible: true, firefoxCompatibile: false, chromeVersion: 26, firefoxVersion: 22, debug: false, browserisms: '', inherits: function(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }, extend: function(dest, source) { for(var key in source) { if(source.hasOwnProperty(key)) { dest[key] = source[key]; } } return dest; }, pack: BinaryPack.pack, unpack: BinaryPack.unpack, randomPort: function() { return Math.round(Math.random() * 60535) + 5000; }, log: function () { if (util.debug) { var err = false; var copy = Array.prototype.slice.call(arguments); copy.unshift('PeerJS: '); for (var i = 0, l = copy.length; i < l; i++){ if (copy[i] instanceof Error) { copy[i] = '(' + copy[i].name + ') ' + copy[i].message; err = true; } } err ? console.error.apply(console, copy) : console.log.apply(console, copy); } }, setZeroTimeout: (function(global) { var timeouts = []; var messageName = 'zero-timeout-message'; // Like setTimeout, but only takes a function argument. There's // no time argument (always zero) and no arguments (you have to // use a closure). function setZeroTimeoutPostMessage(fn) { timeouts.push(fn); global.postMessage(messageName, '*'); } function handleMessage(event) { if (event.source == global && event.data == messageName) { if (event.stopPropagation) { event.stopPropagation(); } if (timeouts.length) { timeouts.shift()(); } } } if (global.addEventListener) { global.addEventListener('message', handleMessage, true); } else if (global.attachEvent) { global.attachEvent('onmessage', handleMessage); } return setZeroTimeoutPostMessage; }(this)), blobToArrayBuffer: function(blob, cb){ var fr = new FileReader(); fr.onload = function(evt) { cb(evt.target.result); }; fr.readAsArrayBuffer(blob); }, blobToBinaryString: function(blob, cb){ var fr = new FileReader(); fr.onload = function(evt) { cb(evt.target.result); }; fr.readAsBinaryString(blob); }, binaryStringToArrayBuffer: function(binary) { var byteArray = new Uint8Array(binary.length); for (var i = 0; i < binary.length; i++) { byteArray[i] = binary.charCodeAt(i) & 0xff; } return byteArray.buffer; }, randomToken: function () { return Math.random().toString(36).substr(2); }, isBrowserCompatible: function() { var c, f; if (this.chromeCompatible) { if ((c = navigator.userAgent.split('Chrome/')) && c.length > 1) { // Get version #. var v = c[1].split('.')[0]; return parseInt(v) >= this.chromeVersion; } } if (this.firefoxCompatible) { if ((f = navigator.userAgent.split('Firefox/')) && f.length > 1) { // Get version #. var v = f[1].split('.')[0]; return parseInt(v) >= this.firefoxVersion; } } return false; } };