socket.io.dev.js (170745B)
1 /*! 2 * Socket.IO v2.3.0 3 * (c) 2014-2019 Guillermo Rauch 4 * Released under the MIT License. 5 */ 6 (function webpackUniversalModuleDefinition(root, factory) { 7 if(typeof exports === 'object' && typeof module === 'object') 8 module.exports = factory(); 9 else if(typeof define === 'function' && define.amd) 10 define([], factory); 11 else if(typeof exports === 'object') 12 exports["io"] = factory(); 13 else 14 root["io"] = factory(); 15 })(this, function() { 16 return /******/ (function(modules) { // webpackBootstrap 17 /******/ // The module cache 18 /******/ var installedModules = {}; 19 /******/ 20 /******/ // The require function 21 /******/ function __webpack_require__(moduleId) { 22 /******/ 23 /******/ // Check if module is in cache 24 /******/ if(installedModules[moduleId]) 25 /******/ return installedModules[moduleId].exports; 26 /******/ 27 /******/ // Create a new module (and put it into the cache) 28 /******/ var module = installedModules[moduleId] = { 29 /******/ exports: {}, 30 /******/ id: moduleId, 31 /******/ loaded: false 32 /******/ }; 33 /******/ 34 /******/ // Execute the module function 35 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 36 /******/ 37 /******/ // Flag the module as loaded 38 /******/ module.loaded = true; 39 /******/ 40 /******/ // Return the exports of the module 41 /******/ return module.exports; 42 /******/ } 43 /******/ 44 /******/ 45 /******/ // expose the modules object (__webpack_modules__) 46 /******/ __webpack_require__.m = modules; 47 /******/ 48 /******/ // expose the module cache 49 /******/ __webpack_require__.c = installedModules; 50 /******/ 51 /******/ // __webpack_public_path__ 52 /******/ __webpack_require__.p = ""; 53 /******/ 54 /******/ // Load entry module and return exports 55 /******/ return __webpack_require__(0); 56 /******/ }) 57 /************************************************************************/ 58 /******/ ([ 59 /* 0 */ 60 /***/ (function(module, exports, __webpack_require__) { 61 62 63 /** 64 * Module dependencies. 65 */ 66 67 var url = __webpack_require__(1); 68 var parser = __webpack_require__(7); 69 var Manager = __webpack_require__(15); 70 var debug = __webpack_require__(3)('socket.io-client'); 71 72 /** 73 * Module exports. 74 */ 75 76 module.exports = exports = lookup; 77 78 /** 79 * Managers cache. 80 */ 81 82 var cache = exports.managers = {}; 83 84 /** 85 * Looks up an existing `Manager` for multiplexing. 86 * If the user summons: 87 * 88 * `io('http://localhost/a');` 89 * `io('http://localhost/b');` 90 * 91 * We reuse the existing instance based on same scheme/port/host, 92 * and we initialize sockets for each namespace. 93 * 94 * @api public 95 */ 96 97 function lookup (uri, opts) { 98 if (typeof uri === 'object') { 99 opts = uri; 100 uri = undefined; 101 } 102 103 opts = opts || {}; 104 105 var parsed = url(uri); 106 var source = parsed.source; 107 var id = parsed.id; 108 var path = parsed.path; 109 var sameNamespace = cache[id] && path in cache[id].nsps; 110 var newConnection = opts.forceNew || opts['force new connection'] || 111 false === opts.multiplex || sameNamespace; 112 113 var io; 114 115 if (newConnection) { 116 debug('ignoring socket cache for %s', source); 117 io = Manager(source, opts); 118 } else { 119 if (!cache[id]) { 120 debug('new io instance for %s', source); 121 cache[id] = Manager(source, opts); 122 } 123 io = cache[id]; 124 } 125 if (parsed.query && !opts.query) { 126 opts.query = parsed.query; 127 } 128 return io.socket(parsed.path, opts); 129 } 130 131 /** 132 * Protocol version. 133 * 134 * @api public 135 */ 136 137 exports.protocol = parser.protocol; 138 139 /** 140 * `connect`. 141 * 142 * @param {String} uri 143 * @api public 144 */ 145 146 exports.connect = lookup; 147 148 /** 149 * Expose constructors for standalone build. 150 * 151 * @api public 152 */ 153 154 exports.Manager = __webpack_require__(15); 155 exports.Socket = __webpack_require__(39); 156 157 158 /***/ }), 159 /* 1 */ 160 /***/ (function(module, exports, __webpack_require__) { 161 162 163 /** 164 * Module dependencies. 165 */ 166 167 var parseuri = __webpack_require__(2); 168 var debug = __webpack_require__(3)('socket.io-client:url'); 169 170 /** 171 * Module exports. 172 */ 173 174 module.exports = url; 175 176 /** 177 * URL parser. 178 * 179 * @param {String} url 180 * @param {Object} An object meant to mimic window.location. 181 * Defaults to window.location. 182 * @api public 183 */ 184 185 function url (uri, loc) { 186 var obj = uri; 187 188 // default to window.location 189 loc = loc || (typeof location !== 'undefined' && location); 190 if (null == uri) uri = loc.protocol + '//' + loc.host; 191 192 // relative path support 193 if ('string' === typeof uri) { 194 if ('/' === uri.charAt(0)) { 195 if ('/' === uri.charAt(1)) { 196 uri = loc.protocol + uri; 197 } else { 198 uri = loc.host + uri; 199 } 200 } 201 202 if (!/^(https?|wss?):\/\//.test(uri)) { 203 debug('protocol-less url %s', uri); 204 if ('undefined' !== typeof loc) { 205 uri = loc.protocol + '//' + uri; 206 } else { 207 uri = 'https://' + uri; 208 } 209 } 210 211 // parse 212 debug('parse %s', uri); 213 obj = parseuri(uri); 214 } 215 216 // make sure we treat `localhost:80` and `localhost` equally 217 if (!obj.port) { 218 if (/^(http|ws)$/.test(obj.protocol)) { 219 obj.port = '80'; 220 } else if (/^(http|ws)s$/.test(obj.protocol)) { 221 obj.port = '443'; 222 } 223 } 224 225 obj.path = obj.path || '/'; 226 227 var ipv6 = obj.host.indexOf(':') !== -1; 228 var host = ipv6 ? '[' + obj.host + ']' : obj.host; 229 230 // define unique id 231 obj.id = obj.protocol + '://' + host + ':' + obj.port; 232 // define href 233 obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port)); 234 235 return obj; 236 } 237 238 239 /***/ }), 240 /* 2 */ 241 /***/ (function(module, exports) { 242 243 /** 244 * Parses an URI 245 * 246 * @author Steven Levithan <stevenlevithan.com> (MIT license) 247 * @api private 248 */ 249 250 var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; 251 252 var parts = [ 253 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor' 254 ]; 255 256 module.exports = function parseuri(str) { 257 var src = str, 258 b = str.indexOf('['), 259 e = str.indexOf(']'); 260 261 if (b != -1 && e != -1) { 262 str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length); 263 } 264 265 var m = re.exec(str || ''), 266 uri = {}, 267 i = 14; 268 269 while (i--) { 270 uri[parts[i]] = m[i] || ''; 271 } 272 273 if (b != -1 && e != -1) { 274 uri.source = src; 275 uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':'); 276 uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':'); 277 uri.ipv6uri = true; 278 } 279 280 return uri; 281 }; 282 283 284 /***/ }), 285 /* 3 */ 286 /***/ (function(module, exports, __webpack_require__) { 287 288 /* WEBPACK VAR INJECTION */(function(process) {'use strict'; 289 290 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 291 292 /* eslint-env browser */ 293 294 /** 295 * This is the web browser implementation of `debug()`. 296 */ 297 298 exports.log = log; 299 exports.formatArgs = formatArgs; 300 exports.save = save; 301 exports.load = load; 302 exports.useColors = useColors; 303 exports.storage = localstorage(); 304 305 /** 306 * Colors. 307 */ 308 309 exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; 310 311 /** 312 * Currently only WebKit-based Web Inspectors, Firefox >= v31, 313 * and the Firebug extension (any Firefox version) are known 314 * to support "%c" CSS customizations. 315 * 316 * TODO: add a `localStorage` variable to explicitly enable/disable colors 317 */ 318 319 // eslint-disable-next-line complexity 320 function useColors() { 321 // NB: In an Electron preload script, document will be defined but not fully 322 // initialized. Since we know we're in Chrome, we'll just detect this case 323 // explicitly 324 if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { 325 return true; 326 } 327 328 // Internet Explorer and Edge do not support colors. 329 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { 330 return false; 331 } 332 333 // Is webkit? http://stackoverflow.com/a/16459606/376773 334 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 335 return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || 336 // Is firebug? http://stackoverflow.com/a/398120/376773 337 typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || 338 // Is firefox >= v31? 339 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages 340 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || 341 // Double check webkit in userAgent just in case we are in a worker 342 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); 343 } 344 345 /** 346 * Colorize log arguments if enabled. 347 * 348 * @api public 349 */ 350 351 function formatArgs(args) { 352 args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); 353 354 if (!this.useColors) { 355 return; 356 } 357 358 var c = 'color: ' + this.color; 359 args.splice(1, 0, c, 'color: inherit'); 360 361 // The final "%c" is somewhat tricky, because there could be other 362 // arguments passed either before or after the %c, so we need to 363 // figure out the correct index to insert the CSS into 364 var index = 0; 365 var lastC = 0; 366 args[0].replace(/%[a-zA-Z%]/g, function (match) { 367 if (match === '%%') { 368 return; 369 } 370 index++; 371 if (match === '%c') { 372 // We only are interested in the *last* %c 373 // (the user may have provided their own) 374 lastC = index; 375 } 376 }); 377 378 args.splice(lastC, 0, c); 379 } 380 381 /** 382 * Invokes `console.log()` when available. 383 * No-op when `console.log` is not a "function". 384 * 385 * @api public 386 */ 387 function log() { 388 var _console; 389 390 // This hackery is required for IE8/9, where 391 // the `console.log` function doesn't have 'apply' 392 return (typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments); 393 } 394 395 /** 396 * Save `namespaces`. 397 * 398 * @param {String} namespaces 399 * @api private 400 */ 401 function save(namespaces) { 402 try { 403 if (namespaces) { 404 exports.storage.setItem('debug', namespaces); 405 } else { 406 exports.storage.removeItem('debug'); 407 } 408 } catch (error) { 409 // Swallow 410 // XXX (@Qix-) should we be logging these? 411 } 412 } 413 414 /** 415 * Load `namespaces`. 416 * 417 * @return {String} returns the previously persisted debug modes 418 * @api private 419 */ 420 function load() { 421 var r = void 0; 422 try { 423 r = exports.storage.getItem('debug'); 424 } catch (error) {} 425 // Swallow 426 // XXX (@Qix-) should we be logging these? 427 428 429 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG 430 if (!r && typeof process !== 'undefined' && 'env' in process) { 431 r = process.env.DEBUG; 432 } 433 434 return r; 435 } 436 437 /** 438 * Localstorage attempts to return the localstorage. 439 * 440 * This is necessary because safari throws 441 * when a user disables cookies/localstorage 442 * and you attempt to access it. 443 * 444 * @return {LocalStorage} 445 * @api private 446 */ 447 448 function localstorage() { 449 try { 450 // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context 451 // The Browser also has localStorage in the global context. 452 return localStorage; 453 } catch (error) { 454 // Swallow 455 // XXX (@Qix-) should we be logging these? 456 } 457 } 458 459 module.exports = __webpack_require__(5)(exports); 460 461 var formatters = module.exports.formatters; 462 463 /** 464 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. 465 */ 466 467 formatters.j = function (v) { 468 try { 469 return JSON.stringify(v); 470 } catch (error) { 471 return '[UnexpectedJSONParseError]: ' + error.message; 472 } 473 }; 474 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) 475 476 /***/ }), 477 /* 4 */ 478 /***/ (function(module, exports) { 479 480 // shim for using process in browser 481 var process = module.exports = {}; 482 483 // cached from whatever global is present so that test runners that stub it 484 // don't break things. But we need to wrap it in a try catch in case it is 485 // wrapped in strict mode code which doesn't define any globals. It's inside a 486 // function because try/catches deoptimize in certain engines. 487 488 var cachedSetTimeout; 489 var cachedClearTimeout; 490 491 function defaultSetTimout() { 492 throw new Error('setTimeout has not been defined'); 493 } 494 function defaultClearTimeout () { 495 throw new Error('clearTimeout has not been defined'); 496 } 497 (function () { 498 try { 499 if (typeof setTimeout === 'function') { 500 cachedSetTimeout = setTimeout; 501 } else { 502 cachedSetTimeout = defaultSetTimout; 503 } 504 } catch (e) { 505 cachedSetTimeout = defaultSetTimout; 506 } 507 try { 508 if (typeof clearTimeout === 'function') { 509 cachedClearTimeout = clearTimeout; 510 } else { 511 cachedClearTimeout = defaultClearTimeout; 512 } 513 } catch (e) { 514 cachedClearTimeout = defaultClearTimeout; 515 } 516 } ()) 517 function runTimeout(fun) { 518 if (cachedSetTimeout === setTimeout) { 519 //normal enviroments in sane situations 520 return setTimeout(fun, 0); 521 } 522 // if setTimeout wasn't available but was latter defined 523 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 524 cachedSetTimeout = setTimeout; 525 return setTimeout(fun, 0); 526 } 527 try { 528 // when when somebody has screwed with setTimeout but no I.E. maddness 529 return cachedSetTimeout(fun, 0); 530 } catch(e){ 531 try { 532 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 533 return cachedSetTimeout.call(null, fun, 0); 534 } catch(e){ 535 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 536 return cachedSetTimeout.call(this, fun, 0); 537 } 538 } 539 540 541 } 542 function runClearTimeout(marker) { 543 if (cachedClearTimeout === clearTimeout) { 544 //normal enviroments in sane situations 545 return clearTimeout(marker); 546 } 547 // if clearTimeout wasn't available but was latter defined 548 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 549 cachedClearTimeout = clearTimeout; 550 return clearTimeout(marker); 551 } 552 try { 553 // when when somebody has screwed with setTimeout but no I.E. maddness 554 return cachedClearTimeout(marker); 555 } catch (e){ 556 try { 557 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 558 return cachedClearTimeout.call(null, marker); 559 } catch (e){ 560 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 561 // Some versions of I.E. have different rules for clearTimeout vs setTimeout 562 return cachedClearTimeout.call(this, marker); 563 } 564 } 565 566 567 568 } 569 var queue = []; 570 var draining = false; 571 var currentQueue; 572 var queueIndex = -1; 573 574 function cleanUpNextTick() { 575 if (!draining || !currentQueue) { 576 return; 577 } 578 draining = false; 579 if (currentQueue.length) { 580 queue = currentQueue.concat(queue); 581 } else { 582 queueIndex = -1; 583 } 584 if (queue.length) { 585 drainQueue(); 586 } 587 } 588 589 function drainQueue() { 590 if (draining) { 591 return; 592 } 593 var timeout = runTimeout(cleanUpNextTick); 594 draining = true; 595 596 var len = queue.length; 597 while(len) { 598 currentQueue = queue; 599 queue = []; 600 while (++queueIndex < len) { 601 if (currentQueue) { 602 currentQueue[queueIndex].run(); 603 } 604 } 605 queueIndex = -1; 606 len = queue.length; 607 } 608 currentQueue = null; 609 draining = false; 610 runClearTimeout(timeout); 611 } 612 613 process.nextTick = function (fun) { 614 var args = new Array(arguments.length - 1); 615 if (arguments.length > 1) { 616 for (var i = 1; i < arguments.length; i++) { 617 args[i - 1] = arguments[i]; 618 } 619 } 620 queue.push(new Item(fun, args)); 621 if (queue.length === 1 && !draining) { 622 runTimeout(drainQueue); 623 } 624 }; 625 626 // v8 likes predictible objects 627 function Item(fun, array) { 628 this.fun = fun; 629 this.array = array; 630 } 631 Item.prototype.run = function () { 632 this.fun.apply(null, this.array); 633 }; 634 process.title = 'browser'; 635 process.browser = true; 636 process.env = {}; 637 process.argv = []; 638 process.version = ''; // empty string to avoid regexp issues 639 process.versions = {}; 640 641 function noop() {} 642 643 process.on = noop; 644 process.addListener = noop; 645 process.once = noop; 646 process.off = noop; 647 process.removeListener = noop; 648 process.removeAllListeners = noop; 649 process.emit = noop; 650 process.prependListener = noop; 651 process.prependOnceListener = noop; 652 653 process.listeners = function (name) { return [] } 654 655 process.binding = function (name) { 656 throw new Error('process.binding is not supported'); 657 }; 658 659 process.cwd = function () { return '/' }; 660 process.chdir = function (dir) { 661 throw new Error('process.chdir is not supported'); 662 }; 663 process.umask = function() { return 0; }; 664 665 666 /***/ }), 667 /* 5 */ 668 /***/ (function(module, exports, __webpack_require__) { 669 670 'use strict'; 671 672 function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } 673 674 /** 675 * This is the common logic for both the Node.js and web browser 676 * implementations of `debug()`. 677 */ 678 679 function setup(env) { 680 createDebug.debug = createDebug; 681 createDebug.default = createDebug; 682 createDebug.coerce = coerce; 683 createDebug.disable = disable; 684 createDebug.enable = enable; 685 createDebug.enabled = enabled; 686 createDebug.humanize = __webpack_require__(6); 687 688 Object.keys(env).forEach(function (key) { 689 createDebug[key] = env[key]; 690 }); 691 692 /** 693 * Active `debug` instances. 694 */ 695 createDebug.instances = []; 696 697 /** 698 * The currently active debug mode names, and names to skip. 699 */ 700 701 createDebug.names = []; 702 createDebug.skips = []; 703 704 /** 705 * Map of special "%n" handling functions, for the debug "format" argument. 706 * 707 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". 708 */ 709 createDebug.formatters = {}; 710 711 /** 712 * Selects a color for a debug namespace 713 * @param {String} namespace The namespace string for the for the debug instance to be colored 714 * @return {Number|String} An ANSI color code for the given namespace 715 * @api private 716 */ 717 function selectColor(namespace) { 718 var hash = 0; 719 720 for (var i = 0; i < namespace.length; i++) { 721 hash = (hash << 5) - hash + namespace.charCodeAt(i); 722 hash |= 0; // Convert to 32bit integer 723 } 724 725 return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; 726 } 727 createDebug.selectColor = selectColor; 728 729 /** 730 * Create a debugger with the given `namespace`. 731 * 732 * @param {String} namespace 733 * @return {Function} 734 * @api public 735 */ 736 function createDebug(namespace) { 737 var prevTime = void 0; 738 739 function debug() { 740 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 741 args[_key] = arguments[_key]; 742 } 743 744 // Disabled? 745 if (!debug.enabled) { 746 return; 747 } 748 749 var self = debug; 750 751 // Set `diff` timestamp 752 var curr = Number(new Date()); 753 var ms = curr - (prevTime || curr); 754 self.diff = ms; 755 self.prev = prevTime; 756 self.curr = curr; 757 prevTime = curr; 758 759 args[0] = createDebug.coerce(args[0]); 760 761 if (typeof args[0] !== 'string') { 762 // Anything else let's inspect with %O 763 args.unshift('%O'); 764 } 765 766 // Apply any `formatters` transformations 767 var index = 0; 768 args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { 769 // If we encounter an escaped % then don't increase the array index 770 if (match === '%%') { 771 return match; 772 } 773 index++; 774 var formatter = createDebug.formatters[format]; 775 if (typeof formatter === 'function') { 776 var val = args[index]; 777 match = formatter.call(self, val); 778 779 // Now we need to remove `args[index]` since it's inlined in the `format` 780 args.splice(index, 1); 781 index--; 782 } 783 return match; 784 }); 785 786 // Apply env-specific formatting (colors, etc.) 787 createDebug.formatArgs.call(self, args); 788 789 var logFn = self.log || createDebug.log; 790 logFn.apply(self, args); 791 } 792 793 debug.namespace = namespace; 794 debug.enabled = createDebug.enabled(namespace); 795 debug.useColors = createDebug.useColors(); 796 debug.color = selectColor(namespace); 797 debug.destroy = destroy; 798 debug.extend = extend; 799 // Debug.formatArgs = formatArgs; 800 // debug.rawLog = rawLog; 801 802 // env-specific initialization logic for debug instances 803 if (typeof createDebug.init === 'function') { 804 createDebug.init(debug); 805 } 806 807 createDebug.instances.push(debug); 808 809 return debug; 810 } 811 812 function destroy() { 813 var index = createDebug.instances.indexOf(this); 814 if (index !== -1) { 815 createDebug.instances.splice(index, 1); 816 return true; 817 } 818 return false; 819 } 820 821 function extend(namespace, delimiter) { 822 var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); 823 newDebug.log = this.log; 824 return newDebug; 825 } 826 827 /** 828 * Enables a debug mode by namespaces. This can include modes 829 * separated by a colon and wildcards. 830 * 831 * @param {String} namespaces 832 * @api public 833 */ 834 function enable(namespaces) { 835 createDebug.save(namespaces); 836 837 createDebug.names = []; 838 createDebug.skips = []; 839 840 var i = void 0; 841 var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); 842 var len = split.length; 843 844 for (i = 0; i < len; i++) { 845 if (!split[i]) { 846 // ignore empty strings 847 continue; 848 } 849 850 namespaces = split[i].replace(/\*/g, '.*?'); 851 852 if (namespaces[0] === '-') { 853 createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); 854 } else { 855 createDebug.names.push(new RegExp('^' + namespaces + '$')); 856 } 857 } 858 859 for (i = 0; i < createDebug.instances.length; i++) { 860 var instance = createDebug.instances[i]; 861 instance.enabled = createDebug.enabled(instance.namespace); 862 } 863 } 864 865 /** 866 * Disable debug output. 867 * 868 * @return {String} namespaces 869 * @api public 870 */ 871 function disable() { 872 var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) { 873 return '-' + namespace; 874 }))).join(','); 875 createDebug.enable(''); 876 return namespaces; 877 } 878 879 /** 880 * Returns true if the given mode name is enabled, false otherwise. 881 * 882 * @param {String} name 883 * @return {Boolean} 884 * @api public 885 */ 886 function enabled(name) { 887 if (name[name.length - 1] === '*') { 888 return true; 889 } 890 891 var i = void 0; 892 var len = void 0; 893 894 for (i = 0, len = createDebug.skips.length; i < len; i++) { 895 if (createDebug.skips[i].test(name)) { 896 return false; 897 } 898 } 899 900 for (i = 0, len = createDebug.names.length; i < len; i++) { 901 if (createDebug.names[i].test(name)) { 902 return true; 903 } 904 } 905 906 return false; 907 } 908 909 /** 910 * Convert regexp to namespace 911 * 912 * @param {RegExp} regxep 913 * @return {String} namespace 914 * @api private 915 */ 916 function toNamespace(regexp) { 917 return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); 918 } 919 920 /** 921 * Coerce `val`. 922 * 923 * @param {Mixed} val 924 * @return {Mixed} 925 * @api private 926 */ 927 function coerce(val) { 928 if (val instanceof Error) { 929 return val.stack || val.message; 930 } 931 return val; 932 } 933 934 createDebug.enable(createDebug.load()); 935 936 return createDebug; 937 } 938 939 module.exports = setup; 940 941 /***/ }), 942 /* 6 */ 943 /***/ (function(module, exports) { 944 945 /** 946 * Helpers. 947 */ 948 949 var s = 1000; 950 var m = s * 60; 951 var h = m * 60; 952 var d = h * 24; 953 var w = d * 7; 954 var y = d * 365.25; 955 956 /** 957 * Parse or format the given `val`. 958 * 959 * Options: 960 * 961 * - `long` verbose formatting [false] 962 * 963 * @param {String|Number} val 964 * @param {Object} [options] 965 * @throws {Error} throw an error if val is not a non-empty string or a number 966 * @return {String|Number} 967 * @api public 968 */ 969 970 module.exports = function(val, options) { 971 options = options || {}; 972 var type = typeof val; 973 if (type === 'string' && val.length > 0) { 974 return parse(val); 975 } else if (type === 'number' && isFinite(val)) { 976 return options.long ? fmtLong(val) : fmtShort(val); 977 } 978 throw new Error( 979 'val is not a non-empty string or a valid number. val=' + 980 JSON.stringify(val) 981 ); 982 }; 983 984 /** 985 * Parse the given `str` and return milliseconds. 986 * 987 * @param {String} str 988 * @return {Number} 989 * @api private 990 */ 991 992 function parse(str) { 993 str = String(str); 994 if (str.length > 100) { 995 return; 996 } 997 var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( 998 str 999 ); 1000 if (!match) { 1001 return; 1002 } 1003 var n = parseFloat(match[1]); 1004 var type = (match[2] || 'ms').toLowerCase(); 1005 switch (type) { 1006 case 'years': 1007 case 'year': 1008 case 'yrs': 1009 case 'yr': 1010 case 'y': 1011 return n * y; 1012 case 'weeks': 1013 case 'week': 1014 case 'w': 1015 return n * w; 1016 case 'days': 1017 case 'day': 1018 case 'd': 1019 return n * d; 1020 case 'hours': 1021 case 'hour': 1022 case 'hrs': 1023 case 'hr': 1024 case 'h': 1025 return n * h; 1026 case 'minutes': 1027 case 'minute': 1028 case 'mins': 1029 case 'min': 1030 case 'm': 1031 return n * m; 1032 case 'seconds': 1033 case 'second': 1034 case 'secs': 1035 case 'sec': 1036 case 's': 1037 return n * s; 1038 case 'milliseconds': 1039 case 'millisecond': 1040 case 'msecs': 1041 case 'msec': 1042 case 'ms': 1043 return n; 1044 default: 1045 return undefined; 1046 } 1047 } 1048 1049 /** 1050 * Short format for `ms`. 1051 * 1052 * @param {Number} ms 1053 * @return {String} 1054 * @api private 1055 */ 1056 1057 function fmtShort(ms) { 1058 var msAbs = Math.abs(ms); 1059 if (msAbs >= d) { 1060 return Math.round(ms / d) + 'd'; 1061 } 1062 if (msAbs >= h) { 1063 return Math.round(ms / h) + 'h'; 1064 } 1065 if (msAbs >= m) { 1066 return Math.round(ms / m) + 'm'; 1067 } 1068 if (msAbs >= s) { 1069 return Math.round(ms / s) + 's'; 1070 } 1071 return ms + 'ms'; 1072 } 1073 1074 /** 1075 * Long format for `ms`. 1076 * 1077 * @param {Number} ms 1078 * @return {String} 1079 * @api private 1080 */ 1081 1082 function fmtLong(ms) { 1083 var msAbs = Math.abs(ms); 1084 if (msAbs >= d) { 1085 return plural(ms, msAbs, d, 'day'); 1086 } 1087 if (msAbs >= h) { 1088 return plural(ms, msAbs, h, 'hour'); 1089 } 1090 if (msAbs >= m) { 1091 return plural(ms, msAbs, m, 'minute'); 1092 } 1093 if (msAbs >= s) { 1094 return plural(ms, msAbs, s, 'second'); 1095 } 1096 return ms + ' ms'; 1097 } 1098 1099 /** 1100 * Pluralization helper. 1101 */ 1102 1103 function plural(ms, msAbs, n, name) { 1104 var isPlural = msAbs >= n * 1.5; 1105 return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); 1106 } 1107 1108 1109 /***/ }), 1110 /* 7 */ 1111 /***/ (function(module, exports, __webpack_require__) { 1112 1113 1114 /** 1115 * Module dependencies. 1116 */ 1117 1118 var debug = __webpack_require__(8)('socket.io-parser'); 1119 var Emitter = __webpack_require__(11); 1120 var binary = __webpack_require__(12); 1121 var isArray = __webpack_require__(13); 1122 var isBuf = __webpack_require__(14); 1123 1124 /** 1125 * Protocol version. 1126 * 1127 * @api public 1128 */ 1129 1130 exports.protocol = 4; 1131 1132 /** 1133 * Packet types. 1134 * 1135 * @api public 1136 */ 1137 1138 exports.types = [ 1139 'CONNECT', 1140 'DISCONNECT', 1141 'EVENT', 1142 'ACK', 1143 'ERROR', 1144 'BINARY_EVENT', 1145 'BINARY_ACK' 1146 ]; 1147 1148 /** 1149 * Packet type `connect`. 1150 * 1151 * @api public 1152 */ 1153 1154 exports.CONNECT = 0; 1155 1156 /** 1157 * Packet type `disconnect`. 1158 * 1159 * @api public 1160 */ 1161 1162 exports.DISCONNECT = 1; 1163 1164 /** 1165 * Packet type `event`. 1166 * 1167 * @api public 1168 */ 1169 1170 exports.EVENT = 2; 1171 1172 /** 1173 * Packet type `ack`. 1174 * 1175 * @api public 1176 */ 1177 1178 exports.ACK = 3; 1179 1180 /** 1181 * Packet type `error`. 1182 * 1183 * @api public 1184 */ 1185 1186 exports.ERROR = 4; 1187 1188 /** 1189 * Packet type 'binary event' 1190 * 1191 * @api public 1192 */ 1193 1194 exports.BINARY_EVENT = 5; 1195 1196 /** 1197 * Packet type `binary ack`. For acks with binary arguments. 1198 * 1199 * @api public 1200 */ 1201 1202 exports.BINARY_ACK = 6; 1203 1204 /** 1205 * Encoder constructor. 1206 * 1207 * @api public 1208 */ 1209 1210 exports.Encoder = Encoder; 1211 1212 /** 1213 * Decoder constructor. 1214 * 1215 * @api public 1216 */ 1217 1218 exports.Decoder = Decoder; 1219 1220 /** 1221 * A socket.io Encoder instance 1222 * 1223 * @api public 1224 */ 1225 1226 function Encoder() {} 1227 1228 var ERROR_PACKET = exports.ERROR + '"encode error"'; 1229 1230 /** 1231 * Encode a packet as a single string if non-binary, or as a 1232 * buffer sequence, depending on packet type. 1233 * 1234 * @param {Object} obj - packet object 1235 * @param {Function} callback - function to handle encodings (likely engine.write) 1236 * @return Calls callback with Array of encodings 1237 * @api public 1238 */ 1239 1240 Encoder.prototype.encode = function(obj, callback){ 1241 debug('encoding packet %j', obj); 1242 1243 if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { 1244 encodeAsBinary(obj, callback); 1245 } else { 1246 var encoding = encodeAsString(obj); 1247 callback([encoding]); 1248 } 1249 }; 1250 1251 /** 1252 * Encode packet as string. 1253 * 1254 * @param {Object} packet 1255 * @return {String} encoded 1256 * @api private 1257 */ 1258 1259 function encodeAsString(obj) { 1260 1261 // first is type 1262 var str = '' + obj.type; 1263 1264 // attachments if we have them 1265 if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { 1266 str += obj.attachments + '-'; 1267 } 1268 1269 // if we have a namespace other than `/` 1270 // we append it followed by a comma `,` 1271 if (obj.nsp && '/' !== obj.nsp) { 1272 str += obj.nsp + ','; 1273 } 1274 1275 // immediately followed by the id 1276 if (null != obj.id) { 1277 str += obj.id; 1278 } 1279 1280 // json data 1281 if (null != obj.data) { 1282 var payload = tryStringify(obj.data); 1283 if (payload !== false) { 1284 str += payload; 1285 } else { 1286 return ERROR_PACKET; 1287 } 1288 } 1289 1290 debug('encoded %j as %s', obj, str); 1291 return str; 1292 } 1293 1294 function tryStringify(str) { 1295 try { 1296 return JSON.stringify(str); 1297 } catch(e){ 1298 return false; 1299 } 1300 } 1301 1302 /** 1303 * Encode packet as 'buffer sequence' by removing blobs, and 1304 * deconstructing packet into object with placeholders and 1305 * a list of buffers. 1306 * 1307 * @param {Object} packet 1308 * @return {Buffer} encoded 1309 * @api private 1310 */ 1311 1312 function encodeAsBinary(obj, callback) { 1313 1314 function writeEncoding(bloblessData) { 1315 var deconstruction = binary.deconstructPacket(bloblessData); 1316 var pack = encodeAsString(deconstruction.packet); 1317 var buffers = deconstruction.buffers; 1318 1319 buffers.unshift(pack); // add packet info to beginning of data list 1320 callback(buffers); // write all the buffers 1321 } 1322 1323 binary.removeBlobs(obj, writeEncoding); 1324 } 1325 1326 /** 1327 * A socket.io Decoder instance 1328 * 1329 * @return {Object} decoder 1330 * @api public 1331 */ 1332 1333 function Decoder() { 1334 this.reconstructor = null; 1335 } 1336 1337 /** 1338 * Mix in `Emitter` with Decoder. 1339 */ 1340 1341 Emitter(Decoder.prototype); 1342 1343 /** 1344 * Decodes an encoded packet string into packet JSON. 1345 * 1346 * @param {String} obj - encoded packet 1347 * @return {Object} packet 1348 * @api public 1349 */ 1350 1351 Decoder.prototype.add = function(obj) { 1352 var packet; 1353 if (typeof obj === 'string') { 1354 packet = decodeString(obj); 1355 if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { // binary packet's json 1356 this.reconstructor = new BinaryReconstructor(packet); 1357 1358 // no attachments, labeled binary but no binary data to follow 1359 if (this.reconstructor.reconPack.attachments === 0) { 1360 this.emit('decoded', packet); 1361 } 1362 } else { // non-binary full packet 1363 this.emit('decoded', packet); 1364 } 1365 } else if (isBuf(obj) || obj.base64) { // raw binary data 1366 if (!this.reconstructor) { 1367 throw new Error('got binary data when not reconstructing a packet'); 1368 } else { 1369 packet = this.reconstructor.takeBinaryData(obj); 1370 if (packet) { // received final buffer 1371 this.reconstructor = null; 1372 this.emit('decoded', packet); 1373 } 1374 } 1375 } else { 1376 throw new Error('Unknown type: ' + obj); 1377 } 1378 }; 1379 1380 /** 1381 * Decode a packet String (JSON data) 1382 * 1383 * @param {String} str 1384 * @return {Object} packet 1385 * @api private 1386 */ 1387 1388 function decodeString(str) { 1389 var i = 0; 1390 // look up type 1391 var p = { 1392 type: Number(str.charAt(0)) 1393 }; 1394 1395 if (null == exports.types[p.type]) { 1396 return error('unknown packet type ' + p.type); 1397 } 1398 1399 // look up attachments if type binary 1400 if (exports.BINARY_EVENT === p.type || exports.BINARY_ACK === p.type) { 1401 var buf = ''; 1402 while (str.charAt(++i) !== '-') { 1403 buf += str.charAt(i); 1404 if (i == str.length) break; 1405 } 1406 if (buf != Number(buf) || str.charAt(i) !== '-') { 1407 throw new Error('Illegal attachments'); 1408 } 1409 p.attachments = Number(buf); 1410 } 1411 1412 // look up namespace (if any) 1413 if ('/' === str.charAt(i + 1)) { 1414 p.nsp = ''; 1415 while (++i) { 1416 var c = str.charAt(i); 1417 if (',' === c) break; 1418 p.nsp += c; 1419 if (i === str.length) break; 1420 } 1421 } else { 1422 p.nsp = '/'; 1423 } 1424 1425 // look up id 1426 var next = str.charAt(i + 1); 1427 if ('' !== next && Number(next) == next) { 1428 p.id = ''; 1429 while (++i) { 1430 var c = str.charAt(i); 1431 if (null == c || Number(c) != c) { 1432 --i; 1433 break; 1434 } 1435 p.id += str.charAt(i); 1436 if (i === str.length) break; 1437 } 1438 p.id = Number(p.id); 1439 } 1440 1441 // look up json data 1442 if (str.charAt(++i)) { 1443 var payload = tryParse(str.substr(i)); 1444 var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload)); 1445 if (isPayloadValid) { 1446 p.data = payload; 1447 } else { 1448 return error('invalid payload'); 1449 } 1450 } 1451 1452 debug('decoded %s as %j', str, p); 1453 return p; 1454 } 1455 1456 function tryParse(str) { 1457 try { 1458 return JSON.parse(str); 1459 } catch(e){ 1460 return false; 1461 } 1462 } 1463 1464 /** 1465 * Deallocates a parser's resources 1466 * 1467 * @api public 1468 */ 1469 1470 Decoder.prototype.destroy = function() { 1471 if (this.reconstructor) { 1472 this.reconstructor.finishedReconstruction(); 1473 } 1474 }; 1475 1476 /** 1477 * A manager of a binary event's 'buffer sequence'. Should 1478 * be constructed whenever a packet of type BINARY_EVENT is 1479 * decoded. 1480 * 1481 * @param {Object} packet 1482 * @return {BinaryReconstructor} initialized reconstructor 1483 * @api private 1484 */ 1485 1486 function BinaryReconstructor(packet) { 1487 this.reconPack = packet; 1488 this.buffers = []; 1489 } 1490 1491 /** 1492 * Method to be called when binary data received from connection 1493 * after a BINARY_EVENT packet. 1494 * 1495 * @param {Buffer | ArrayBuffer} binData - the raw binary data received 1496 * @return {null | Object} returns null if more binary data is expected or 1497 * a reconstructed packet object if all buffers have been received. 1498 * @api private 1499 */ 1500 1501 BinaryReconstructor.prototype.takeBinaryData = function(binData) { 1502 this.buffers.push(binData); 1503 if (this.buffers.length === this.reconPack.attachments) { // done with buffer list 1504 var packet = binary.reconstructPacket(this.reconPack, this.buffers); 1505 this.finishedReconstruction(); 1506 return packet; 1507 } 1508 return null; 1509 }; 1510 1511 /** 1512 * Cleans up binary packet reconstruction variables. 1513 * 1514 * @api private 1515 */ 1516 1517 BinaryReconstructor.prototype.finishedReconstruction = function() { 1518 this.reconPack = null; 1519 this.buffers = []; 1520 }; 1521 1522 function error(msg) { 1523 return { 1524 type: exports.ERROR, 1525 data: 'parser error: ' + msg 1526 }; 1527 } 1528 1529 1530 /***/ }), 1531 /* 8 */ 1532 /***/ (function(module, exports, __webpack_require__) { 1533 1534 /* WEBPACK VAR INJECTION */(function(process) {'use strict'; 1535 1536 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 1537 1538 /** 1539 * This is the web browser implementation of `debug()`. 1540 * 1541 * Expose `debug()` as the module. 1542 */ 1543 1544 exports = module.exports = __webpack_require__(9); 1545 exports.log = log; 1546 exports.formatArgs = formatArgs; 1547 exports.save = save; 1548 exports.load = load; 1549 exports.useColors = useColors; 1550 exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage(); 1551 1552 /** 1553 * Colors. 1554 */ 1555 1556 exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; 1557 1558 /** 1559 * Currently only WebKit-based Web Inspectors, Firefox >= v31, 1560 * and the Firebug extension (any Firefox version) are known 1561 * to support "%c" CSS customizations. 1562 * 1563 * TODO: add a `localStorage` variable to explicitly enable/disable colors 1564 */ 1565 1566 function useColors() { 1567 // NB: In an Electron preload script, document will be defined but not fully 1568 // initialized. Since we know we're in Chrome, we'll just detect this case 1569 // explicitly 1570 if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { 1571 return true; 1572 } 1573 1574 // Internet Explorer and Edge do not support colors. 1575 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { 1576 return false; 1577 } 1578 1579 // is webkit? http://stackoverflow.com/a/16459606/376773 1580 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 1581 return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || 1582 // is firebug? http://stackoverflow.com/a/398120/376773 1583 typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || 1584 // is firefox >= v31? 1585 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages 1586 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || 1587 // double check webkit in userAgent just in case we are in a worker 1588 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); 1589 } 1590 1591 /** 1592 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. 1593 */ 1594 1595 exports.formatters.j = function (v) { 1596 try { 1597 return JSON.stringify(v); 1598 } catch (err) { 1599 return '[UnexpectedJSONParseError]: ' + err.message; 1600 } 1601 }; 1602 1603 /** 1604 * Colorize log arguments if enabled. 1605 * 1606 * @api public 1607 */ 1608 1609 function formatArgs(args) { 1610 var useColors = this.useColors; 1611 1612 args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); 1613 1614 if (!useColors) return; 1615 1616 var c = 'color: ' + this.color; 1617 args.splice(1, 0, c, 'color: inherit'); 1618 1619 // the final "%c" is somewhat tricky, because there could be other 1620 // arguments passed either before or after the %c, so we need to 1621 // figure out the correct index to insert the CSS into 1622 var index = 0; 1623 var lastC = 0; 1624 args[0].replace(/%[a-zA-Z%]/g, function (match) { 1625 if ('%%' === match) return; 1626 index++; 1627 if ('%c' === match) { 1628 // we only are interested in the *last* %c 1629 // (the user may have provided their own) 1630 lastC = index; 1631 } 1632 }); 1633 1634 args.splice(lastC, 0, c); 1635 } 1636 1637 /** 1638 * Invokes `console.log()` when available. 1639 * No-op when `console.log` is not a "function". 1640 * 1641 * @api public 1642 */ 1643 1644 function log() { 1645 // this hackery is required for IE8/9, where 1646 // the `console.log` function doesn't have 'apply' 1647 return 'object' === (typeof console === 'undefined' ? 'undefined' : _typeof(console)) && console.log && Function.prototype.apply.call(console.log, console, arguments); 1648 } 1649 1650 /** 1651 * Save `namespaces`. 1652 * 1653 * @param {String} namespaces 1654 * @api private 1655 */ 1656 1657 function save(namespaces) { 1658 try { 1659 if (null == namespaces) { 1660 exports.storage.removeItem('debug'); 1661 } else { 1662 exports.storage.debug = namespaces; 1663 } 1664 } catch (e) {} 1665 } 1666 1667 /** 1668 * Load `namespaces`. 1669 * 1670 * @return {String} returns the previously persisted debug modes 1671 * @api private 1672 */ 1673 1674 function load() { 1675 var r; 1676 try { 1677 r = exports.storage.debug; 1678 } catch (e) {} 1679 1680 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG 1681 if (!r && typeof process !== 'undefined' && 'env' in process) { 1682 r = process.env.DEBUG; 1683 } 1684 1685 return r; 1686 } 1687 1688 /** 1689 * Enable namespaces listed in `localStorage.debug` initially. 1690 */ 1691 1692 exports.enable(load()); 1693 1694 /** 1695 * Localstorage attempts to return the localstorage. 1696 * 1697 * This is necessary because safari throws 1698 * when a user disables cookies/localstorage 1699 * and you attempt to access it. 1700 * 1701 * @return {LocalStorage} 1702 * @api private 1703 */ 1704 1705 function localstorage() { 1706 try { 1707 return window.localStorage; 1708 } catch (e) {} 1709 } 1710 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) 1711 1712 /***/ }), 1713 /* 9 */ 1714 /***/ (function(module, exports, __webpack_require__) { 1715 1716 'use strict'; 1717 1718 /** 1719 * This is the common logic for both the Node.js and web browser 1720 * implementations of `debug()`. 1721 * 1722 * Expose `debug()` as the module. 1723 */ 1724 1725 exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; 1726 exports.coerce = coerce; 1727 exports.disable = disable; 1728 exports.enable = enable; 1729 exports.enabled = enabled; 1730 exports.humanize = __webpack_require__(10); 1731 1732 /** 1733 * Active `debug` instances. 1734 */ 1735 exports.instances = []; 1736 1737 /** 1738 * The currently active debug mode names, and names to skip. 1739 */ 1740 1741 exports.names = []; 1742 exports.skips = []; 1743 1744 /** 1745 * Map of special "%n" handling functions, for the debug "format" argument. 1746 * 1747 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". 1748 */ 1749 1750 exports.formatters = {}; 1751 1752 /** 1753 * Select a color. 1754 * @param {String} namespace 1755 * @return {Number} 1756 * @api private 1757 */ 1758 1759 function selectColor(namespace) { 1760 var hash = 0, 1761 i; 1762 1763 for (i in namespace) { 1764 hash = (hash << 5) - hash + namespace.charCodeAt(i); 1765 hash |= 0; // Convert to 32bit integer 1766 } 1767 1768 return exports.colors[Math.abs(hash) % exports.colors.length]; 1769 } 1770 1771 /** 1772 * Create a debugger with the given `namespace`. 1773 * 1774 * @param {String} namespace 1775 * @return {Function} 1776 * @api public 1777 */ 1778 1779 function createDebug(namespace) { 1780 1781 var prevTime; 1782 1783 function debug() { 1784 // disabled? 1785 if (!debug.enabled) return; 1786 1787 var self = debug; 1788 1789 // set `diff` timestamp 1790 var curr = +new Date(); 1791 var ms = curr - (prevTime || curr); 1792 self.diff = ms; 1793 self.prev = prevTime; 1794 self.curr = curr; 1795 prevTime = curr; 1796 1797 // turn the `arguments` into a proper Array 1798 var args = new Array(arguments.length); 1799 for (var i = 0; i < args.length; i++) { 1800 args[i] = arguments[i]; 1801 } 1802 1803 args[0] = exports.coerce(args[0]); 1804 1805 if ('string' !== typeof args[0]) { 1806 // anything else let's inspect with %O 1807 args.unshift('%O'); 1808 } 1809 1810 // apply any `formatters` transformations 1811 var index = 0; 1812 args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { 1813 // if we encounter an escaped % then don't increase the array index 1814 if (match === '%%') return match; 1815 index++; 1816 var formatter = exports.formatters[format]; 1817 if ('function' === typeof formatter) { 1818 var val = args[index]; 1819 match = formatter.call(self, val); 1820 1821 // now we need to remove `args[index]` since it's inlined in the `format` 1822 args.splice(index, 1); 1823 index--; 1824 } 1825 return match; 1826 }); 1827 1828 // apply env-specific formatting (colors, etc.) 1829 exports.formatArgs.call(self, args); 1830 1831 var logFn = debug.log || exports.log || console.log.bind(console); 1832 logFn.apply(self, args); 1833 } 1834 1835 debug.namespace = namespace; 1836 debug.enabled = exports.enabled(namespace); 1837 debug.useColors = exports.useColors(); 1838 debug.color = selectColor(namespace); 1839 debug.destroy = destroy; 1840 1841 // env-specific initialization logic for debug instances 1842 if ('function' === typeof exports.init) { 1843 exports.init(debug); 1844 } 1845 1846 exports.instances.push(debug); 1847 1848 return debug; 1849 } 1850 1851 function destroy() { 1852 var index = exports.instances.indexOf(this); 1853 if (index !== -1) { 1854 exports.instances.splice(index, 1); 1855 return true; 1856 } else { 1857 return false; 1858 } 1859 } 1860 1861 /** 1862 * Enables a debug mode by namespaces. This can include modes 1863 * separated by a colon and wildcards. 1864 * 1865 * @param {String} namespaces 1866 * @api public 1867 */ 1868 1869 function enable(namespaces) { 1870 exports.save(namespaces); 1871 1872 exports.names = []; 1873 exports.skips = []; 1874 1875 var i; 1876 var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); 1877 var len = split.length; 1878 1879 for (i = 0; i < len; i++) { 1880 if (!split[i]) continue; // ignore empty strings 1881 namespaces = split[i].replace(/\*/g, '.*?'); 1882 if (namespaces[0] === '-') { 1883 exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); 1884 } else { 1885 exports.names.push(new RegExp('^' + namespaces + '$')); 1886 } 1887 } 1888 1889 for (i = 0; i < exports.instances.length; i++) { 1890 var instance = exports.instances[i]; 1891 instance.enabled = exports.enabled(instance.namespace); 1892 } 1893 } 1894 1895 /** 1896 * Disable debug output. 1897 * 1898 * @api public 1899 */ 1900 1901 function disable() { 1902 exports.enable(''); 1903 } 1904 1905 /** 1906 * Returns true if the given mode name is enabled, false otherwise. 1907 * 1908 * @param {String} name 1909 * @return {Boolean} 1910 * @api public 1911 */ 1912 1913 function enabled(name) { 1914 if (name[name.length - 1] === '*') { 1915 return true; 1916 } 1917 var i, len; 1918 for (i = 0, len = exports.skips.length; i < len; i++) { 1919 if (exports.skips[i].test(name)) { 1920 return false; 1921 } 1922 } 1923 for (i = 0, len = exports.names.length; i < len; i++) { 1924 if (exports.names[i].test(name)) { 1925 return true; 1926 } 1927 } 1928 return false; 1929 } 1930 1931 /** 1932 * Coerce `val`. 1933 * 1934 * @param {Mixed} val 1935 * @return {Mixed} 1936 * @api private 1937 */ 1938 1939 function coerce(val) { 1940 if (val instanceof Error) return val.stack || val.message; 1941 return val; 1942 } 1943 1944 /***/ }), 1945 /* 10 */ 1946 /***/ (function(module, exports) { 1947 1948 /** 1949 * Helpers. 1950 */ 1951 1952 var s = 1000; 1953 var m = s * 60; 1954 var h = m * 60; 1955 var d = h * 24; 1956 var y = d * 365.25; 1957 1958 /** 1959 * Parse or format the given `val`. 1960 * 1961 * Options: 1962 * 1963 * - `long` verbose formatting [false] 1964 * 1965 * @param {String|Number} val 1966 * @param {Object} [options] 1967 * @throws {Error} throw an error if val is not a non-empty string or a number 1968 * @return {String|Number} 1969 * @api public 1970 */ 1971 1972 module.exports = function(val, options) { 1973 options = options || {}; 1974 var type = typeof val; 1975 if (type === 'string' && val.length > 0) { 1976 return parse(val); 1977 } else if (type === 'number' && isNaN(val) === false) { 1978 return options.long ? fmtLong(val) : fmtShort(val); 1979 } 1980 throw new Error( 1981 'val is not a non-empty string or a valid number. val=' + 1982 JSON.stringify(val) 1983 ); 1984 }; 1985 1986 /** 1987 * Parse the given `str` and return milliseconds. 1988 * 1989 * @param {String} str 1990 * @return {Number} 1991 * @api private 1992 */ 1993 1994 function parse(str) { 1995 str = String(str); 1996 if (str.length > 100) { 1997 return; 1998 } 1999 var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( 2000 str 2001 ); 2002 if (!match) { 2003 return; 2004 } 2005 var n = parseFloat(match[1]); 2006 var type = (match[2] || 'ms').toLowerCase(); 2007 switch (type) { 2008 case 'years': 2009 case 'year': 2010 case 'yrs': 2011 case 'yr': 2012 case 'y': 2013 return n * y; 2014 case 'days': 2015 case 'day': 2016 case 'd': 2017 return n * d; 2018 case 'hours': 2019 case 'hour': 2020 case 'hrs': 2021 case 'hr': 2022 case 'h': 2023 return n * h; 2024 case 'minutes': 2025 case 'minute': 2026 case 'mins': 2027 case 'min': 2028 case 'm': 2029 return n * m; 2030 case 'seconds': 2031 case 'second': 2032 case 'secs': 2033 case 'sec': 2034 case 's': 2035 return n * s; 2036 case 'milliseconds': 2037 case 'millisecond': 2038 case 'msecs': 2039 case 'msec': 2040 case 'ms': 2041 return n; 2042 default: 2043 return undefined; 2044 } 2045 } 2046 2047 /** 2048 * Short format for `ms`. 2049 * 2050 * @param {Number} ms 2051 * @return {String} 2052 * @api private 2053 */ 2054 2055 function fmtShort(ms) { 2056 if (ms >= d) { 2057 return Math.round(ms / d) + 'd'; 2058 } 2059 if (ms >= h) { 2060 return Math.round(ms / h) + 'h'; 2061 } 2062 if (ms >= m) { 2063 return Math.round(ms / m) + 'm'; 2064 } 2065 if (ms >= s) { 2066 return Math.round(ms / s) + 's'; 2067 } 2068 return ms + 'ms'; 2069 } 2070 2071 /** 2072 * Long format for `ms`. 2073 * 2074 * @param {Number} ms 2075 * @return {String} 2076 * @api private 2077 */ 2078 2079 function fmtLong(ms) { 2080 return plural(ms, d, 'day') || 2081 plural(ms, h, 'hour') || 2082 plural(ms, m, 'minute') || 2083 plural(ms, s, 'second') || 2084 ms + ' ms'; 2085 } 2086 2087 /** 2088 * Pluralization helper. 2089 */ 2090 2091 function plural(ms, n, name) { 2092 if (ms < n) { 2093 return; 2094 } 2095 if (ms < n * 1.5) { 2096 return Math.floor(ms / n) + ' ' + name; 2097 } 2098 return Math.ceil(ms / n) + ' ' + name + 's'; 2099 } 2100 2101 2102 /***/ }), 2103 /* 11 */ 2104 /***/ (function(module, exports, __webpack_require__) { 2105 2106 2107 /** 2108 * Expose `Emitter`. 2109 */ 2110 2111 if (true) { 2112 module.exports = Emitter; 2113 } 2114 2115 /** 2116 * Initialize a new `Emitter`. 2117 * 2118 * @api public 2119 */ 2120 2121 function Emitter(obj) { 2122 if (obj) return mixin(obj); 2123 }; 2124 2125 /** 2126 * Mixin the emitter properties. 2127 * 2128 * @param {Object} obj 2129 * @return {Object} 2130 * @api private 2131 */ 2132 2133 function mixin(obj) { 2134 for (var key in Emitter.prototype) { 2135 obj[key] = Emitter.prototype[key]; 2136 } 2137 return obj; 2138 } 2139 2140 /** 2141 * Listen on the given `event` with `fn`. 2142 * 2143 * @param {String} event 2144 * @param {Function} fn 2145 * @return {Emitter} 2146 * @api public 2147 */ 2148 2149 Emitter.prototype.on = 2150 Emitter.prototype.addEventListener = function(event, fn){ 2151 this._callbacks = this._callbacks || {}; 2152 (this._callbacks['$' + event] = this._callbacks['$' + event] || []) 2153 .push(fn); 2154 return this; 2155 }; 2156 2157 /** 2158 * Adds an `event` listener that will be invoked a single 2159 * time then automatically removed. 2160 * 2161 * @param {String} event 2162 * @param {Function} fn 2163 * @return {Emitter} 2164 * @api public 2165 */ 2166 2167 Emitter.prototype.once = function(event, fn){ 2168 function on() { 2169 this.off(event, on); 2170 fn.apply(this, arguments); 2171 } 2172 2173 on.fn = fn; 2174 this.on(event, on); 2175 return this; 2176 }; 2177 2178 /** 2179 * Remove the given callback for `event` or all 2180 * registered callbacks. 2181 * 2182 * @param {String} event 2183 * @param {Function} fn 2184 * @return {Emitter} 2185 * @api public 2186 */ 2187 2188 Emitter.prototype.off = 2189 Emitter.prototype.removeListener = 2190 Emitter.prototype.removeAllListeners = 2191 Emitter.prototype.removeEventListener = function(event, fn){ 2192 this._callbacks = this._callbacks || {}; 2193 2194 // all 2195 if (0 == arguments.length) { 2196 this._callbacks = {}; 2197 return this; 2198 } 2199 2200 // specific event 2201 var callbacks = this._callbacks['$' + event]; 2202 if (!callbacks) return this; 2203 2204 // remove all handlers 2205 if (1 == arguments.length) { 2206 delete this._callbacks['$' + event]; 2207 return this; 2208 } 2209 2210 // remove specific handler 2211 var cb; 2212 for (var i = 0; i < callbacks.length; i++) { 2213 cb = callbacks[i]; 2214 if (cb === fn || cb.fn === fn) { 2215 callbacks.splice(i, 1); 2216 break; 2217 } 2218 } 2219 return this; 2220 }; 2221 2222 /** 2223 * Emit `event` with the given args. 2224 * 2225 * @param {String} event 2226 * @param {Mixed} ... 2227 * @return {Emitter} 2228 */ 2229 2230 Emitter.prototype.emit = function(event){ 2231 this._callbacks = this._callbacks || {}; 2232 var args = [].slice.call(arguments, 1) 2233 , callbacks = this._callbacks['$' + event]; 2234 2235 if (callbacks) { 2236 callbacks = callbacks.slice(0); 2237 for (var i = 0, len = callbacks.length; i < len; ++i) { 2238 callbacks[i].apply(this, args); 2239 } 2240 } 2241 2242 return this; 2243 }; 2244 2245 /** 2246 * Return array of callbacks for `event`. 2247 * 2248 * @param {String} event 2249 * @return {Array} 2250 * @api public 2251 */ 2252 2253 Emitter.prototype.listeners = function(event){ 2254 this._callbacks = this._callbacks || {}; 2255 return this._callbacks['$' + event] || []; 2256 }; 2257 2258 /** 2259 * Check if this emitter has `event` handlers. 2260 * 2261 * @param {String} event 2262 * @return {Boolean} 2263 * @api public 2264 */ 2265 2266 Emitter.prototype.hasListeners = function(event){ 2267 return !! this.listeners(event).length; 2268 }; 2269 2270 2271 /***/ }), 2272 /* 12 */ 2273 /***/ (function(module, exports, __webpack_require__) { 2274 2275 /*global Blob,File*/ 2276 2277 /** 2278 * Module requirements 2279 */ 2280 2281 var isArray = __webpack_require__(13); 2282 var isBuf = __webpack_require__(14); 2283 var toString = Object.prototype.toString; 2284 var withNativeBlob = typeof Blob === 'function' || (typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'); 2285 var withNativeFile = typeof File === 'function' || (typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'); 2286 2287 /** 2288 * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder. 2289 * Anything with blobs or files should be fed through removeBlobs before coming 2290 * here. 2291 * 2292 * @param {Object} packet - socket.io event packet 2293 * @return {Object} with deconstructed packet and list of buffers 2294 * @api public 2295 */ 2296 2297 exports.deconstructPacket = function(packet) { 2298 var buffers = []; 2299 var packetData = packet.data; 2300 var pack = packet; 2301 pack.data = _deconstructPacket(packetData, buffers); 2302 pack.attachments = buffers.length; // number of binary 'attachments' 2303 return {packet: pack, buffers: buffers}; 2304 }; 2305 2306 function _deconstructPacket(data, buffers) { 2307 if (!data) return data; 2308 2309 if (isBuf(data)) { 2310 var placeholder = { _placeholder: true, num: buffers.length }; 2311 buffers.push(data); 2312 return placeholder; 2313 } else if (isArray(data)) { 2314 var newData = new Array(data.length); 2315 for (var i = 0; i < data.length; i++) { 2316 newData[i] = _deconstructPacket(data[i], buffers); 2317 } 2318 return newData; 2319 } else if (typeof data === 'object' && !(data instanceof Date)) { 2320 var newData = {}; 2321 for (var key in data) { 2322 newData[key] = _deconstructPacket(data[key], buffers); 2323 } 2324 return newData; 2325 } 2326 return data; 2327 } 2328 2329 /** 2330 * Reconstructs a binary packet from its placeholder packet and buffers 2331 * 2332 * @param {Object} packet - event packet with placeholders 2333 * @param {Array} buffers - binary buffers to put in placeholder positions 2334 * @return {Object} reconstructed packet 2335 * @api public 2336 */ 2337 2338 exports.reconstructPacket = function(packet, buffers) { 2339 packet.data = _reconstructPacket(packet.data, buffers); 2340 packet.attachments = undefined; // no longer useful 2341 return packet; 2342 }; 2343 2344 function _reconstructPacket(data, buffers) { 2345 if (!data) return data; 2346 2347 if (data && data._placeholder) { 2348 return buffers[data.num]; // appropriate buffer (should be natural order anyway) 2349 } else if (isArray(data)) { 2350 for (var i = 0; i < data.length; i++) { 2351 data[i] = _reconstructPacket(data[i], buffers); 2352 } 2353 } else if (typeof data === 'object') { 2354 for (var key in data) { 2355 data[key] = _reconstructPacket(data[key], buffers); 2356 } 2357 } 2358 2359 return data; 2360 } 2361 2362 /** 2363 * Asynchronously removes Blobs or Files from data via 2364 * FileReader's readAsArrayBuffer method. Used before encoding 2365 * data as msgpack. Calls callback with the blobless data. 2366 * 2367 * @param {Object} data 2368 * @param {Function} callback 2369 * @api private 2370 */ 2371 2372 exports.removeBlobs = function(data, callback) { 2373 function _removeBlobs(obj, curKey, containingObject) { 2374 if (!obj) return obj; 2375 2376 // convert any blob 2377 if ((withNativeBlob && obj instanceof Blob) || 2378 (withNativeFile && obj instanceof File)) { 2379 pendingBlobs++; 2380 2381 // async filereader 2382 var fileReader = new FileReader(); 2383 fileReader.onload = function() { // this.result == arraybuffer 2384 if (containingObject) { 2385 containingObject[curKey] = this.result; 2386 } 2387 else { 2388 bloblessData = this.result; 2389 } 2390 2391 // if nothing pending its callback time 2392 if(! --pendingBlobs) { 2393 callback(bloblessData); 2394 } 2395 }; 2396 2397 fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer 2398 } else if (isArray(obj)) { // handle array 2399 for (var i = 0; i < obj.length; i++) { 2400 _removeBlobs(obj[i], i, obj); 2401 } 2402 } else if (typeof obj === 'object' && !isBuf(obj)) { // and object 2403 for (var key in obj) { 2404 _removeBlobs(obj[key], key, obj); 2405 } 2406 } 2407 } 2408 2409 var pendingBlobs = 0; 2410 var bloblessData = data; 2411 _removeBlobs(bloblessData); 2412 if (!pendingBlobs) { 2413 callback(bloblessData); 2414 } 2415 }; 2416 2417 2418 /***/ }), 2419 /* 13 */ 2420 /***/ (function(module, exports) { 2421 2422 var toString = {}.toString; 2423 2424 module.exports = Array.isArray || function (arr) { 2425 return toString.call(arr) == '[object Array]'; 2426 }; 2427 2428 2429 /***/ }), 2430 /* 14 */ 2431 /***/ (function(module, exports) { 2432 2433 2434 module.exports = isBuf; 2435 2436 var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function'; 2437 var withNativeArrayBuffer = typeof ArrayBuffer === 'function'; 2438 2439 var isView = function (obj) { 2440 return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : (obj.buffer instanceof ArrayBuffer); 2441 }; 2442 2443 /** 2444 * Returns true if obj is a buffer or an arraybuffer. 2445 * 2446 * @api private 2447 */ 2448 2449 function isBuf(obj) { 2450 return (withNativeBuffer && Buffer.isBuffer(obj)) || 2451 (withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))); 2452 } 2453 2454 2455 /***/ }), 2456 /* 15 */ 2457 /***/ (function(module, exports, __webpack_require__) { 2458 2459 2460 /** 2461 * Module dependencies. 2462 */ 2463 2464 var eio = __webpack_require__(16); 2465 var Socket = __webpack_require__(39); 2466 var Emitter = __webpack_require__(11); 2467 var parser = __webpack_require__(7); 2468 var on = __webpack_require__(41); 2469 var bind = __webpack_require__(42); 2470 var debug = __webpack_require__(3)('socket.io-client:manager'); 2471 var indexOf = __webpack_require__(38); 2472 var Backoff = __webpack_require__(43); 2473 2474 /** 2475 * IE6+ hasOwnProperty 2476 */ 2477 2478 var has = Object.prototype.hasOwnProperty; 2479 2480 /** 2481 * Module exports 2482 */ 2483 2484 module.exports = Manager; 2485 2486 /** 2487 * `Manager` constructor. 2488 * 2489 * @param {String} engine instance or engine uri/opts 2490 * @param {Object} options 2491 * @api public 2492 */ 2493 2494 function Manager (uri, opts) { 2495 if (!(this instanceof Manager)) return new Manager(uri, opts); 2496 if (uri && ('object' === typeof uri)) { 2497 opts = uri; 2498 uri = undefined; 2499 } 2500 opts = opts || {}; 2501 2502 opts.path = opts.path || '/socket.io'; 2503 this.nsps = {}; 2504 this.subs = []; 2505 this.opts = opts; 2506 this.reconnection(opts.reconnection !== false); 2507 this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); 2508 this.reconnectionDelay(opts.reconnectionDelay || 1000); 2509 this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); 2510 this.randomizationFactor(opts.randomizationFactor || 0.5); 2511 this.backoff = new Backoff({ 2512 min: this.reconnectionDelay(), 2513 max: this.reconnectionDelayMax(), 2514 jitter: this.randomizationFactor() 2515 }); 2516 this.timeout(null == opts.timeout ? 20000 : opts.timeout); 2517 this.readyState = 'closed'; 2518 this.uri = uri; 2519 this.connecting = []; 2520 this.lastPing = null; 2521 this.encoding = false; 2522 this.packetBuffer = []; 2523 var _parser = opts.parser || parser; 2524 this.encoder = new _parser.Encoder(); 2525 this.decoder = new _parser.Decoder(); 2526 this.autoConnect = opts.autoConnect !== false; 2527 if (this.autoConnect) this.open(); 2528 } 2529 2530 /** 2531 * Propagate given event to sockets and emit on `this` 2532 * 2533 * @api private 2534 */ 2535 2536 Manager.prototype.emitAll = function () { 2537 this.emit.apply(this, arguments); 2538 for (var nsp in this.nsps) { 2539 if (has.call(this.nsps, nsp)) { 2540 this.nsps[nsp].emit.apply(this.nsps[nsp], arguments); 2541 } 2542 } 2543 }; 2544 2545 /** 2546 * Update `socket.id` of all sockets 2547 * 2548 * @api private 2549 */ 2550 2551 Manager.prototype.updateSocketIds = function () { 2552 for (var nsp in this.nsps) { 2553 if (has.call(this.nsps, nsp)) { 2554 this.nsps[nsp].id = this.generateId(nsp); 2555 } 2556 } 2557 }; 2558 2559 /** 2560 * generate `socket.id` for the given `nsp` 2561 * 2562 * @param {String} nsp 2563 * @return {String} 2564 * @api private 2565 */ 2566 2567 Manager.prototype.generateId = function (nsp) { 2568 return (nsp === '/' ? '' : (nsp + '#')) + this.engine.id; 2569 }; 2570 2571 /** 2572 * Mix in `Emitter`. 2573 */ 2574 2575 Emitter(Manager.prototype); 2576 2577 /** 2578 * Sets the `reconnection` config. 2579 * 2580 * @param {Boolean} true/false if it should automatically reconnect 2581 * @return {Manager} self or value 2582 * @api public 2583 */ 2584 2585 Manager.prototype.reconnection = function (v) { 2586 if (!arguments.length) return this._reconnection; 2587 this._reconnection = !!v; 2588 return this; 2589 }; 2590 2591 /** 2592 * Sets the reconnection attempts config. 2593 * 2594 * @param {Number} max reconnection attempts before giving up 2595 * @return {Manager} self or value 2596 * @api public 2597 */ 2598 2599 Manager.prototype.reconnectionAttempts = function (v) { 2600 if (!arguments.length) return this._reconnectionAttempts; 2601 this._reconnectionAttempts = v; 2602 return this; 2603 }; 2604 2605 /** 2606 * Sets the delay between reconnections. 2607 * 2608 * @param {Number} delay 2609 * @return {Manager} self or value 2610 * @api public 2611 */ 2612 2613 Manager.prototype.reconnectionDelay = function (v) { 2614 if (!arguments.length) return this._reconnectionDelay; 2615 this._reconnectionDelay = v; 2616 this.backoff && this.backoff.setMin(v); 2617 return this; 2618 }; 2619 2620 Manager.prototype.randomizationFactor = function (v) { 2621 if (!arguments.length) return this._randomizationFactor; 2622 this._randomizationFactor = v; 2623 this.backoff && this.backoff.setJitter(v); 2624 return this; 2625 }; 2626 2627 /** 2628 * Sets the maximum delay between reconnections. 2629 * 2630 * @param {Number} delay 2631 * @return {Manager} self or value 2632 * @api public 2633 */ 2634 2635 Manager.prototype.reconnectionDelayMax = function (v) { 2636 if (!arguments.length) return this._reconnectionDelayMax; 2637 this._reconnectionDelayMax = v; 2638 this.backoff && this.backoff.setMax(v); 2639 return this; 2640 }; 2641 2642 /** 2643 * Sets the connection timeout. `false` to disable 2644 * 2645 * @return {Manager} self or value 2646 * @api public 2647 */ 2648 2649 Manager.prototype.timeout = function (v) { 2650 if (!arguments.length) return this._timeout; 2651 this._timeout = v; 2652 return this; 2653 }; 2654 2655 /** 2656 * Starts trying to reconnect if reconnection is enabled and we have not 2657 * started reconnecting yet 2658 * 2659 * @api private 2660 */ 2661 2662 Manager.prototype.maybeReconnectOnOpen = function () { 2663 // Only try to reconnect if it's the first time we're connecting 2664 if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) { 2665 // keeps reconnection from firing twice for the same reconnection loop 2666 this.reconnect(); 2667 } 2668 }; 2669 2670 /** 2671 * Sets the current transport `socket`. 2672 * 2673 * @param {Function} optional, callback 2674 * @return {Manager} self 2675 * @api public 2676 */ 2677 2678 Manager.prototype.open = 2679 Manager.prototype.connect = function (fn, opts) { 2680 debug('readyState %s', this.readyState); 2681 if (~this.readyState.indexOf('open')) return this; 2682 2683 debug('opening %s', this.uri); 2684 this.engine = eio(this.uri, this.opts); 2685 var socket = this.engine; 2686 var self = this; 2687 this.readyState = 'opening'; 2688 this.skipReconnect = false; 2689 2690 // emit `open` 2691 var openSub = on(socket, 'open', function () { 2692 self.onopen(); 2693 fn && fn(); 2694 }); 2695 2696 // emit `connect_error` 2697 var errorSub = on(socket, 'error', function (data) { 2698 debug('connect_error'); 2699 self.cleanup(); 2700 self.readyState = 'closed'; 2701 self.emitAll('connect_error', data); 2702 if (fn) { 2703 var err = new Error('Connection error'); 2704 err.data = data; 2705 fn(err); 2706 } else { 2707 // Only do this if there is no fn to handle the error 2708 self.maybeReconnectOnOpen(); 2709 } 2710 }); 2711 2712 // emit `connect_timeout` 2713 if (false !== this._timeout) { 2714 var timeout = this._timeout; 2715 debug('connect attempt will timeout after %d', timeout); 2716 2717 // set timer 2718 var timer = setTimeout(function () { 2719 debug('connect attempt timed out after %d', timeout); 2720 openSub.destroy(); 2721 socket.close(); 2722 socket.emit('error', 'timeout'); 2723 self.emitAll('connect_timeout', timeout); 2724 }, timeout); 2725 2726 this.subs.push({ 2727 destroy: function () { 2728 clearTimeout(timer); 2729 } 2730 }); 2731 } 2732 2733 this.subs.push(openSub); 2734 this.subs.push(errorSub); 2735 2736 return this; 2737 }; 2738 2739 /** 2740 * Called upon transport open. 2741 * 2742 * @api private 2743 */ 2744 2745 Manager.prototype.onopen = function () { 2746 debug('open'); 2747 2748 // clear old subs 2749 this.cleanup(); 2750 2751 // mark as open 2752 this.readyState = 'open'; 2753 this.emit('open'); 2754 2755 // add new subs 2756 var socket = this.engine; 2757 this.subs.push(on(socket, 'data', bind(this, 'ondata'))); 2758 this.subs.push(on(socket, 'ping', bind(this, 'onping'))); 2759 this.subs.push(on(socket, 'pong', bind(this, 'onpong'))); 2760 this.subs.push(on(socket, 'error', bind(this, 'onerror'))); 2761 this.subs.push(on(socket, 'close', bind(this, 'onclose'))); 2762 this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded'))); 2763 }; 2764 2765 /** 2766 * Called upon a ping. 2767 * 2768 * @api private 2769 */ 2770 2771 Manager.prototype.onping = function () { 2772 this.lastPing = new Date(); 2773 this.emitAll('ping'); 2774 }; 2775 2776 /** 2777 * Called upon a packet. 2778 * 2779 * @api private 2780 */ 2781 2782 Manager.prototype.onpong = function () { 2783 this.emitAll('pong', new Date() - this.lastPing); 2784 }; 2785 2786 /** 2787 * Called with data. 2788 * 2789 * @api private 2790 */ 2791 2792 Manager.prototype.ondata = function (data) { 2793 this.decoder.add(data); 2794 }; 2795 2796 /** 2797 * Called when parser fully decodes a packet. 2798 * 2799 * @api private 2800 */ 2801 2802 Manager.prototype.ondecoded = function (packet) { 2803 this.emit('packet', packet); 2804 }; 2805 2806 /** 2807 * Called upon socket error. 2808 * 2809 * @api private 2810 */ 2811 2812 Manager.prototype.onerror = function (err) { 2813 debug('error', err); 2814 this.emitAll('error', err); 2815 }; 2816 2817 /** 2818 * Creates a new socket for the given `nsp`. 2819 * 2820 * @return {Socket} 2821 * @api public 2822 */ 2823 2824 Manager.prototype.socket = function (nsp, opts) { 2825 var socket = this.nsps[nsp]; 2826 if (!socket) { 2827 socket = new Socket(this, nsp, opts); 2828 this.nsps[nsp] = socket; 2829 var self = this; 2830 socket.on('connecting', onConnecting); 2831 socket.on('connect', function () { 2832 socket.id = self.generateId(nsp); 2833 }); 2834 2835 if (this.autoConnect) { 2836 // manually call here since connecting event is fired before listening 2837 onConnecting(); 2838 } 2839 } 2840 2841 function onConnecting () { 2842 if (!~indexOf(self.connecting, socket)) { 2843 self.connecting.push(socket); 2844 } 2845 } 2846 2847 return socket; 2848 }; 2849 2850 /** 2851 * Called upon a socket close. 2852 * 2853 * @param {Socket} socket 2854 */ 2855 2856 Manager.prototype.destroy = function (socket) { 2857 var index = indexOf(this.connecting, socket); 2858 if (~index) this.connecting.splice(index, 1); 2859 if (this.connecting.length) return; 2860 2861 this.close(); 2862 }; 2863 2864 /** 2865 * Writes a packet. 2866 * 2867 * @param {Object} packet 2868 * @api private 2869 */ 2870 2871 Manager.prototype.packet = function (packet) { 2872 debug('writing packet %j', packet); 2873 var self = this; 2874 if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query; 2875 2876 if (!self.encoding) { 2877 // encode, then write to engine with result 2878 self.encoding = true; 2879 this.encoder.encode(packet, function (encodedPackets) { 2880 for (var i = 0; i < encodedPackets.length; i++) { 2881 self.engine.write(encodedPackets[i], packet.options); 2882 } 2883 self.encoding = false; 2884 self.processPacketQueue(); 2885 }); 2886 } else { // add packet to the queue 2887 self.packetBuffer.push(packet); 2888 } 2889 }; 2890 2891 /** 2892 * If packet buffer is non-empty, begins encoding the 2893 * next packet in line. 2894 * 2895 * @api private 2896 */ 2897 2898 Manager.prototype.processPacketQueue = function () { 2899 if (this.packetBuffer.length > 0 && !this.encoding) { 2900 var pack = this.packetBuffer.shift(); 2901 this.packet(pack); 2902 } 2903 }; 2904 2905 /** 2906 * Clean up transport subscriptions and packet buffer. 2907 * 2908 * @api private 2909 */ 2910 2911 Manager.prototype.cleanup = function () { 2912 debug('cleanup'); 2913 2914 var subsLength = this.subs.length; 2915 for (var i = 0; i < subsLength; i++) { 2916 var sub = this.subs.shift(); 2917 sub.destroy(); 2918 } 2919 2920 this.packetBuffer = []; 2921 this.encoding = false; 2922 this.lastPing = null; 2923 2924 this.decoder.destroy(); 2925 }; 2926 2927 /** 2928 * Close the current socket. 2929 * 2930 * @api private 2931 */ 2932 2933 Manager.prototype.close = 2934 Manager.prototype.disconnect = function () { 2935 debug('disconnect'); 2936 this.skipReconnect = true; 2937 this.reconnecting = false; 2938 if ('opening' === this.readyState) { 2939 // `onclose` will not fire because 2940 // an open event never happened 2941 this.cleanup(); 2942 } 2943 this.backoff.reset(); 2944 this.readyState = 'closed'; 2945 if (this.engine) this.engine.close(); 2946 }; 2947 2948 /** 2949 * Called upon engine close. 2950 * 2951 * @api private 2952 */ 2953 2954 Manager.prototype.onclose = function (reason) { 2955 debug('onclose'); 2956 2957 this.cleanup(); 2958 this.backoff.reset(); 2959 this.readyState = 'closed'; 2960 this.emit('close', reason); 2961 2962 if (this._reconnection && !this.skipReconnect) { 2963 this.reconnect(); 2964 } 2965 }; 2966 2967 /** 2968 * Attempt a reconnection. 2969 * 2970 * @api private 2971 */ 2972 2973 Manager.prototype.reconnect = function () { 2974 if (this.reconnecting || this.skipReconnect) return this; 2975 2976 var self = this; 2977 2978 if (this.backoff.attempts >= this._reconnectionAttempts) { 2979 debug('reconnect failed'); 2980 this.backoff.reset(); 2981 this.emitAll('reconnect_failed'); 2982 this.reconnecting = false; 2983 } else { 2984 var delay = this.backoff.duration(); 2985 debug('will wait %dms before reconnect attempt', delay); 2986 2987 this.reconnecting = true; 2988 var timer = setTimeout(function () { 2989 if (self.skipReconnect) return; 2990 2991 debug('attempting reconnect'); 2992 self.emitAll('reconnect_attempt', self.backoff.attempts); 2993 self.emitAll('reconnecting', self.backoff.attempts); 2994 2995 // check again for the case socket closed in above events 2996 if (self.skipReconnect) return; 2997 2998 self.open(function (err) { 2999 if (err) { 3000 debug('reconnect attempt error'); 3001 self.reconnecting = false; 3002 self.reconnect(); 3003 self.emitAll('reconnect_error', err.data); 3004 } else { 3005 debug('reconnect success'); 3006 self.onreconnect(); 3007 } 3008 }); 3009 }, delay); 3010 3011 this.subs.push({ 3012 destroy: function () { 3013 clearTimeout(timer); 3014 } 3015 }); 3016 } 3017 }; 3018 3019 /** 3020 * Called upon successful reconnect. 3021 * 3022 * @api private 3023 */ 3024 3025 Manager.prototype.onreconnect = function () { 3026 var attempt = this.backoff.attempts; 3027 this.reconnecting = false; 3028 this.backoff.reset(); 3029 this.updateSocketIds(); 3030 this.emitAll('reconnect', attempt); 3031 }; 3032 3033 3034 /***/ }), 3035 /* 16 */ 3036 /***/ (function(module, exports, __webpack_require__) { 3037 3038 3039 module.exports = __webpack_require__(17); 3040 3041 /** 3042 * Exports parser 3043 * 3044 * @api public 3045 * 3046 */ 3047 module.exports.parser = __webpack_require__(24); 3048 3049 3050 /***/ }), 3051 /* 17 */ 3052 /***/ (function(module, exports, __webpack_require__) { 3053 3054 /** 3055 * Module dependencies. 3056 */ 3057 3058 var transports = __webpack_require__(18); 3059 var Emitter = __webpack_require__(11); 3060 var debug = __webpack_require__(3)('engine.io-client:socket'); 3061 var index = __webpack_require__(38); 3062 var parser = __webpack_require__(24); 3063 var parseuri = __webpack_require__(2); 3064 var parseqs = __webpack_require__(32); 3065 3066 /** 3067 * Module exports. 3068 */ 3069 3070 module.exports = Socket; 3071 3072 /** 3073 * Socket constructor. 3074 * 3075 * @param {String|Object} uri or options 3076 * @param {Object} options 3077 * @api public 3078 */ 3079 3080 function Socket (uri, opts) { 3081 if (!(this instanceof Socket)) return new Socket(uri, opts); 3082 3083 opts = opts || {}; 3084 3085 if (uri && 'object' === typeof uri) { 3086 opts = uri; 3087 uri = null; 3088 } 3089 3090 if (uri) { 3091 uri = parseuri(uri); 3092 opts.hostname = uri.host; 3093 opts.secure = uri.protocol === 'https' || uri.protocol === 'wss'; 3094 opts.port = uri.port; 3095 if (uri.query) opts.query = uri.query; 3096 } else if (opts.host) { 3097 opts.hostname = parseuri(opts.host).host; 3098 } 3099 3100 this.secure = null != opts.secure ? opts.secure 3101 : (typeof location !== 'undefined' && 'https:' === location.protocol); 3102 3103 if (opts.hostname && !opts.port) { 3104 // if no port is specified manually, use the protocol default 3105 opts.port = this.secure ? '443' : '80'; 3106 } 3107 3108 this.agent = opts.agent || false; 3109 this.hostname = opts.hostname || 3110 (typeof location !== 'undefined' ? location.hostname : 'localhost'); 3111 this.port = opts.port || (typeof location !== 'undefined' && location.port 3112 ? location.port 3113 : (this.secure ? 443 : 80)); 3114 this.query = opts.query || {}; 3115 if ('string' === typeof this.query) this.query = parseqs.decode(this.query); 3116 this.upgrade = false !== opts.upgrade; 3117 this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; 3118 this.forceJSONP = !!opts.forceJSONP; 3119 this.jsonp = false !== opts.jsonp; 3120 this.forceBase64 = !!opts.forceBase64; 3121 this.enablesXDR = !!opts.enablesXDR; 3122 this.withCredentials = false !== opts.withCredentials; 3123 this.timestampParam = opts.timestampParam || 't'; 3124 this.timestampRequests = opts.timestampRequests; 3125 this.transports = opts.transports || ['polling', 'websocket']; 3126 this.transportOptions = opts.transportOptions || {}; 3127 this.readyState = ''; 3128 this.writeBuffer = []; 3129 this.prevBufferLen = 0; 3130 this.policyPort = opts.policyPort || 843; 3131 this.rememberUpgrade = opts.rememberUpgrade || false; 3132 this.binaryType = null; 3133 this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades; 3134 this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false; 3135 3136 if (true === this.perMessageDeflate) this.perMessageDeflate = {}; 3137 if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) { 3138 this.perMessageDeflate.threshold = 1024; 3139 } 3140 3141 // SSL options for Node.js client 3142 this.pfx = opts.pfx || null; 3143 this.key = opts.key || null; 3144 this.passphrase = opts.passphrase || null; 3145 this.cert = opts.cert || null; 3146 this.ca = opts.ca || null; 3147 this.ciphers = opts.ciphers || null; 3148 this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? true : opts.rejectUnauthorized; 3149 this.forceNode = !!opts.forceNode; 3150 3151 // detect ReactNative environment 3152 this.isReactNative = (typeof navigator !== 'undefined' && typeof navigator.product === 'string' && navigator.product.toLowerCase() === 'reactnative'); 3153 3154 // other options for Node.js or ReactNative client 3155 if (typeof self === 'undefined' || this.isReactNative) { 3156 if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) { 3157 this.extraHeaders = opts.extraHeaders; 3158 } 3159 3160 if (opts.localAddress) { 3161 this.localAddress = opts.localAddress; 3162 } 3163 } 3164 3165 // set on handshake 3166 this.id = null; 3167 this.upgrades = null; 3168 this.pingInterval = null; 3169 this.pingTimeout = null; 3170 3171 // set on heartbeat 3172 this.pingIntervalTimer = null; 3173 this.pingTimeoutTimer = null; 3174 3175 this.open(); 3176 } 3177 3178 Socket.priorWebsocketSuccess = false; 3179 3180 /** 3181 * Mix in `Emitter`. 3182 */ 3183 3184 Emitter(Socket.prototype); 3185 3186 /** 3187 * Protocol version. 3188 * 3189 * @api public 3190 */ 3191 3192 Socket.protocol = parser.protocol; // this is an int 3193 3194 /** 3195 * Expose deps for legacy compatibility 3196 * and standalone browser access. 3197 */ 3198 3199 Socket.Socket = Socket; 3200 Socket.Transport = __webpack_require__(23); 3201 Socket.transports = __webpack_require__(18); 3202 Socket.parser = __webpack_require__(24); 3203 3204 /** 3205 * Creates transport of the given type. 3206 * 3207 * @param {String} transport name 3208 * @return {Transport} 3209 * @api private 3210 */ 3211 3212 Socket.prototype.createTransport = function (name) { 3213 debug('creating transport "%s"', name); 3214 var query = clone(this.query); 3215 3216 // append engine.io protocol identifier 3217 query.EIO = parser.protocol; 3218 3219 // transport name 3220 query.transport = name; 3221 3222 // per-transport options 3223 var options = this.transportOptions[name] || {}; 3224 3225 // session id if we already have one 3226 if (this.id) query.sid = this.id; 3227 3228 var transport = new transports[name]({ 3229 query: query, 3230 socket: this, 3231 agent: options.agent || this.agent, 3232 hostname: options.hostname || this.hostname, 3233 port: options.port || this.port, 3234 secure: options.secure || this.secure, 3235 path: options.path || this.path, 3236 forceJSONP: options.forceJSONP || this.forceJSONP, 3237 jsonp: options.jsonp || this.jsonp, 3238 forceBase64: options.forceBase64 || this.forceBase64, 3239 enablesXDR: options.enablesXDR || this.enablesXDR, 3240 withCredentials: options.withCredentials || this.withCredentials, 3241 timestampRequests: options.timestampRequests || this.timestampRequests, 3242 timestampParam: options.timestampParam || this.timestampParam, 3243 policyPort: options.policyPort || this.policyPort, 3244 pfx: options.pfx || this.pfx, 3245 key: options.key || this.key, 3246 passphrase: options.passphrase || this.passphrase, 3247 cert: options.cert || this.cert, 3248 ca: options.ca || this.ca, 3249 ciphers: options.ciphers || this.ciphers, 3250 rejectUnauthorized: options.rejectUnauthorized || this.rejectUnauthorized, 3251 perMessageDeflate: options.perMessageDeflate || this.perMessageDeflate, 3252 extraHeaders: options.extraHeaders || this.extraHeaders, 3253 forceNode: options.forceNode || this.forceNode, 3254 localAddress: options.localAddress || this.localAddress, 3255 requestTimeout: options.requestTimeout || this.requestTimeout, 3256 protocols: options.protocols || void (0), 3257 isReactNative: this.isReactNative 3258 }); 3259 3260 return transport; 3261 }; 3262 3263 function clone (obj) { 3264 var o = {}; 3265 for (var i in obj) { 3266 if (obj.hasOwnProperty(i)) { 3267 o[i] = obj[i]; 3268 } 3269 } 3270 return o; 3271 } 3272 3273 /** 3274 * Initializes transport to use and starts probe. 3275 * 3276 * @api private 3277 */ 3278 Socket.prototype.open = function () { 3279 var transport; 3280 if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) { 3281 transport = 'websocket'; 3282 } else if (0 === this.transports.length) { 3283 // Emit error on next tick so it can be listened to 3284 var self = this; 3285 setTimeout(function () { 3286 self.emit('error', 'No transports available'); 3287 }, 0); 3288 return; 3289 } else { 3290 transport = this.transports[0]; 3291 } 3292 this.readyState = 'opening'; 3293 3294 // Retry with the next transport if the transport is disabled (jsonp: false) 3295 try { 3296 transport = this.createTransport(transport); 3297 } catch (e) { 3298 this.transports.shift(); 3299 this.open(); 3300 return; 3301 } 3302 3303 transport.open(); 3304 this.setTransport(transport); 3305 }; 3306 3307 /** 3308 * Sets the current transport. Disables the existing one (if any). 3309 * 3310 * @api private 3311 */ 3312 3313 Socket.prototype.setTransport = function (transport) { 3314 debug('setting transport %s', transport.name); 3315 var self = this; 3316 3317 if (this.transport) { 3318 debug('clearing existing transport %s', this.transport.name); 3319 this.transport.removeAllListeners(); 3320 } 3321 3322 // set up transport 3323 this.transport = transport; 3324 3325 // set up transport listeners 3326 transport 3327 .on('drain', function () { 3328 self.onDrain(); 3329 }) 3330 .on('packet', function (packet) { 3331 self.onPacket(packet); 3332 }) 3333 .on('error', function (e) { 3334 self.onError(e); 3335 }) 3336 .on('close', function () { 3337 self.onClose('transport close'); 3338 }); 3339 }; 3340 3341 /** 3342 * Probes a transport. 3343 * 3344 * @param {String} transport name 3345 * @api private 3346 */ 3347 3348 Socket.prototype.probe = function (name) { 3349 debug('probing transport "%s"', name); 3350 var transport = this.createTransport(name, { probe: 1 }); 3351 var failed = false; 3352 var self = this; 3353 3354 Socket.priorWebsocketSuccess = false; 3355 3356 function onTransportOpen () { 3357 if (self.onlyBinaryUpgrades) { 3358 var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; 3359 failed = failed || upgradeLosesBinary; 3360 } 3361 if (failed) return; 3362 3363 debug('probe transport "%s" opened', name); 3364 transport.send([{ type: 'ping', data: 'probe' }]); 3365 transport.once('packet', function (msg) { 3366 if (failed) return; 3367 if ('pong' === msg.type && 'probe' === msg.data) { 3368 debug('probe transport "%s" pong', name); 3369 self.upgrading = true; 3370 self.emit('upgrading', transport); 3371 if (!transport) return; 3372 Socket.priorWebsocketSuccess = 'websocket' === transport.name; 3373 3374 debug('pausing current transport "%s"', self.transport.name); 3375 self.transport.pause(function () { 3376 if (failed) return; 3377 if ('closed' === self.readyState) return; 3378 debug('changing transport and sending upgrade packet'); 3379 3380 cleanup(); 3381 3382 self.setTransport(transport); 3383 transport.send([{ type: 'upgrade' }]); 3384 self.emit('upgrade', transport); 3385 transport = null; 3386 self.upgrading = false; 3387 self.flush(); 3388 }); 3389 } else { 3390 debug('probe transport "%s" failed', name); 3391 var err = new Error('probe error'); 3392 err.transport = transport.name; 3393 self.emit('upgradeError', err); 3394 } 3395 }); 3396 } 3397 3398 function freezeTransport () { 3399 if (failed) return; 3400 3401 // Any callback called by transport should be ignored since now 3402 failed = true; 3403 3404 cleanup(); 3405 3406 transport.close(); 3407 transport = null; 3408 } 3409 3410 // Handle any error that happens while probing 3411 function onerror (err) { 3412 var error = new Error('probe error: ' + err); 3413 error.transport = transport.name; 3414 3415 freezeTransport(); 3416 3417 debug('probe transport "%s" failed because of error: %s', name, err); 3418 3419 self.emit('upgradeError', error); 3420 } 3421 3422 function onTransportClose () { 3423 onerror('transport closed'); 3424 } 3425 3426 // When the socket is closed while we're probing 3427 function onclose () { 3428 onerror('socket closed'); 3429 } 3430 3431 // When the socket is upgraded while we're probing 3432 function onupgrade (to) { 3433 if (transport && to.name !== transport.name) { 3434 debug('"%s" works - aborting "%s"', to.name, transport.name); 3435 freezeTransport(); 3436 } 3437 } 3438 3439 // Remove all listeners on the transport and on self 3440 function cleanup () { 3441 transport.removeListener('open', onTransportOpen); 3442 transport.removeListener('error', onerror); 3443 transport.removeListener('close', onTransportClose); 3444 self.removeListener('close', onclose); 3445 self.removeListener('upgrading', onupgrade); 3446 } 3447 3448 transport.once('open', onTransportOpen); 3449 transport.once('error', onerror); 3450 transport.once('close', onTransportClose); 3451 3452 this.once('close', onclose); 3453 this.once('upgrading', onupgrade); 3454 3455 transport.open(); 3456 }; 3457 3458 /** 3459 * Called when connection is deemed open. 3460 * 3461 * @api public 3462 */ 3463 3464 Socket.prototype.onOpen = function () { 3465 debug('socket open'); 3466 this.readyState = 'open'; 3467 Socket.priorWebsocketSuccess = 'websocket' === this.transport.name; 3468 this.emit('open'); 3469 this.flush(); 3470 3471 // we check for `readyState` in case an `open` 3472 // listener already closed the socket 3473 if ('open' === this.readyState && this.upgrade && this.transport.pause) { 3474 debug('starting upgrade probes'); 3475 for (var i = 0, l = this.upgrades.length; i < l; i++) { 3476 this.probe(this.upgrades[i]); 3477 } 3478 } 3479 }; 3480 3481 /** 3482 * Handles a packet. 3483 * 3484 * @api private 3485 */ 3486 3487 Socket.prototype.onPacket = function (packet) { 3488 if ('opening' === this.readyState || 'open' === this.readyState || 3489 'closing' === this.readyState) { 3490 debug('socket receive: type "%s", data "%s"', packet.type, packet.data); 3491 3492 this.emit('packet', packet); 3493 3494 // Socket is live - any packet counts 3495 this.emit('heartbeat'); 3496 3497 switch (packet.type) { 3498 case 'open': 3499 this.onHandshake(JSON.parse(packet.data)); 3500 break; 3501 3502 case 'pong': 3503 this.setPing(); 3504 this.emit('pong'); 3505 break; 3506 3507 case 'error': 3508 var err = new Error('server error'); 3509 err.code = packet.data; 3510 this.onError(err); 3511 break; 3512 3513 case 'message': 3514 this.emit('data', packet.data); 3515 this.emit('message', packet.data); 3516 break; 3517 } 3518 } else { 3519 debug('packet received with socket readyState "%s"', this.readyState); 3520 } 3521 }; 3522 3523 /** 3524 * Called upon handshake completion. 3525 * 3526 * @param {Object} handshake obj 3527 * @api private 3528 */ 3529 3530 Socket.prototype.onHandshake = function (data) { 3531 this.emit('handshake', data); 3532 this.id = data.sid; 3533 this.transport.query.sid = data.sid; 3534 this.upgrades = this.filterUpgrades(data.upgrades); 3535 this.pingInterval = data.pingInterval; 3536 this.pingTimeout = data.pingTimeout; 3537 this.onOpen(); 3538 // In case open handler closes socket 3539 if ('closed' === this.readyState) return; 3540 this.setPing(); 3541 3542 // Prolong liveness of socket on heartbeat 3543 this.removeListener('heartbeat', this.onHeartbeat); 3544 this.on('heartbeat', this.onHeartbeat); 3545 }; 3546 3547 /** 3548 * Resets ping timeout. 3549 * 3550 * @api private 3551 */ 3552 3553 Socket.prototype.onHeartbeat = function (timeout) { 3554 clearTimeout(this.pingTimeoutTimer); 3555 var self = this; 3556 self.pingTimeoutTimer = setTimeout(function () { 3557 if ('closed' === self.readyState) return; 3558 self.onClose('ping timeout'); 3559 }, timeout || (self.pingInterval + self.pingTimeout)); 3560 }; 3561 3562 /** 3563 * Pings server every `this.pingInterval` and expects response 3564 * within `this.pingTimeout` or closes connection. 3565 * 3566 * @api private 3567 */ 3568 3569 Socket.prototype.setPing = function () { 3570 var self = this; 3571 clearTimeout(self.pingIntervalTimer); 3572 self.pingIntervalTimer = setTimeout(function () { 3573 debug('writing ping packet - expecting pong within %sms', self.pingTimeout); 3574 self.ping(); 3575 self.onHeartbeat(self.pingTimeout); 3576 }, self.pingInterval); 3577 }; 3578 3579 /** 3580 * Sends a ping packet. 3581 * 3582 * @api private 3583 */ 3584 3585 Socket.prototype.ping = function () { 3586 var self = this; 3587 this.sendPacket('ping', function () { 3588 self.emit('ping'); 3589 }); 3590 }; 3591 3592 /** 3593 * Called on `drain` event 3594 * 3595 * @api private 3596 */ 3597 3598 Socket.prototype.onDrain = function () { 3599 this.writeBuffer.splice(0, this.prevBufferLen); 3600 3601 // setting prevBufferLen = 0 is very important 3602 // for example, when upgrading, upgrade packet is sent over, 3603 // and a nonzero prevBufferLen could cause problems on `drain` 3604 this.prevBufferLen = 0; 3605 3606 if (0 === this.writeBuffer.length) { 3607 this.emit('drain'); 3608 } else { 3609 this.flush(); 3610 } 3611 }; 3612 3613 /** 3614 * Flush write buffers. 3615 * 3616 * @api private 3617 */ 3618 3619 Socket.prototype.flush = function () { 3620 if ('closed' !== this.readyState && this.transport.writable && 3621 !this.upgrading && this.writeBuffer.length) { 3622 debug('flushing %d packets in socket', this.writeBuffer.length); 3623 this.transport.send(this.writeBuffer); 3624 // keep track of current length of writeBuffer 3625 // splice writeBuffer and callbackBuffer on `drain` 3626 this.prevBufferLen = this.writeBuffer.length; 3627 this.emit('flush'); 3628 } 3629 }; 3630 3631 /** 3632 * Sends a message. 3633 * 3634 * @param {String} message. 3635 * @param {Function} callback function. 3636 * @param {Object} options. 3637 * @return {Socket} for chaining. 3638 * @api public 3639 */ 3640 3641 Socket.prototype.write = 3642 Socket.prototype.send = function (msg, options, fn) { 3643 this.sendPacket('message', msg, options, fn); 3644 return this; 3645 }; 3646 3647 /** 3648 * Sends a packet. 3649 * 3650 * @param {String} packet type. 3651 * @param {String} data. 3652 * @param {Object} options. 3653 * @param {Function} callback function. 3654 * @api private 3655 */ 3656 3657 Socket.prototype.sendPacket = function (type, data, options, fn) { 3658 if ('function' === typeof data) { 3659 fn = data; 3660 data = undefined; 3661 } 3662 3663 if ('function' === typeof options) { 3664 fn = options; 3665 options = null; 3666 } 3667 3668 if ('closing' === this.readyState || 'closed' === this.readyState) { 3669 return; 3670 } 3671 3672 options = options || {}; 3673 options.compress = false !== options.compress; 3674 3675 var packet = { 3676 type: type, 3677 data: data, 3678 options: options 3679 }; 3680 this.emit('packetCreate', packet); 3681 this.writeBuffer.push(packet); 3682 if (fn) this.once('flush', fn); 3683 this.flush(); 3684 }; 3685 3686 /** 3687 * Closes the connection. 3688 * 3689 * @api private 3690 */ 3691 3692 Socket.prototype.close = function () { 3693 if ('opening' === this.readyState || 'open' === this.readyState) { 3694 this.readyState = 'closing'; 3695 3696 var self = this; 3697 3698 if (this.writeBuffer.length) { 3699 this.once('drain', function () { 3700 if (this.upgrading) { 3701 waitForUpgrade(); 3702 } else { 3703 close(); 3704 } 3705 }); 3706 } else if (this.upgrading) { 3707 waitForUpgrade(); 3708 } else { 3709 close(); 3710 } 3711 } 3712 3713 function close () { 3714 self.onClose('forced close'); 3715 debug('socket closing - telling transport to close'); 3716 self.transport.close(); 3717 } 3718 3719 function cleanupAndClose () { 3720 self.removeListener('upgrade', cleanupAndClose); 3721 self.removeListener('upgradeError', cleanupAndClose); 3722 close(); 3723 } 3724 3725 function waitForUpgrade () { 3726 // wait for upgrade to finish since we can't send packets while pausing a transport 3727 self.once('upgrade', cleanupAndClose); 3728 self.once('upgradeError', cleanupAndClose); 3729 } 3730 3731 return this; 3732 }; 3733 3734 /** 3735 * Called upon transport error 3736 * 3737 * @api private 3738 */ 3739 3740 Socket.prototype.onError = function (err) { 3741 debug('socket error %j', err); 3742 Socket.priorWebsocketSuccess = false; 3743 this.emit('error', err); 3744 this.onClose('transport error', err); 3745 }; 3746 3747 /** 3748 * Called upon transport close. 3749 * 3750 * @api private 3751 */ 3752 3753 Socket.prototype.onClose = function (reason, desc) { 3754 if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) { 3755 debug('socket close with reason: "%s"', reason); 3756 var self = this; 3757 3758 // clear timers 3759 clearTimeout(this.pingIntervalTimer); 3760 clearTimeout(this.pingTimeoutTimer); 3761 3762 // stop event from firing again for transport 3763 this.transport.removeAllListeners('close'); 3764 3765 // ensure transport won't stay open 3766 this.transport.close(); 3767 3768 // ignore further transport communication 3769 this.transport.removeAllListeners(); 3770 3771 // set ready state 3772 this.readyState = 'closed'; 3773 3774 // clear session id 3775 this.id = null; 3776 3777 // emit close event 3778 this.emit('close', reason, desc); 3779 3780 // clean buffers after, so users can still 3781 // grab the buffers on `close` event 3782 self.writeBuffer = []; 3783 self.prevBufferLen = 0; 3784 } 3785 }; 3786 3787 /** 3788 * Filters upgrades, returning only those matching client transports. 3789 * 3790 * @param {Array} server upgrades 3791 * @api private 3792 * 3793 */ 3794 3795 Socket.prototype.filterUpgrades = function (upgrades) { 3796 var filteredUpgrades = []; 3797 for (var i = 0, j = upgrades.length; i < j; i++) { 3798 if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]); 3799 } 3800 return filteredUpgrades; 3801 }; 3802 3803 3804 /***/ }), 3805 /* 18 */ 3806 /***/ (function(module, exports, __webpack_require__) { 3807 3808 /** 3809 * Module dependencies 3810 */ 3811 3812 var XMLHttpRequest = __webpack_require__(19); 3813 var XHR = __webpack_require__(21); 3814 var JSONP = __webpack_require__(35); 3815 var websocket = __webpack_require__(36); 3816 3817 /** 3818 * Export transports. 3819 */ 3820 3821 exports.polling = polling; 3822 exports.websocket = websocket; 3823 3824 /** 3825 * Polling transport polymorphic constructor. 3826 * Decides on xhr vs jsonp based on feature detection. 3827 * 3828 * @api private 3829 */ 3830 3831 function polling (opts) { 3832 var xhr; 3833 var xd = false; 3834 var xs = false; 3835 var jsonp = false !== opts.jsonp; 3836 3837 if (typeof location !== 'undefined') { 3838 var isSSL = 'https:' === location.protocol; 3839 var port = location.port; 3840 3841 // some user agents have empty `location.port` 3842 if (!port) { 3843 port = isSSL ? 443 : 80; 3844 } 3845 3846 xd = opts.hostname !== location.hostname || port !== opts.port; 3847 xs = opts.secure !== isSSL; 3848 } 3849 3850 opts.xdomain = xd; 3851 opts.xscheme = xs; 3852 xhr = new XMLHttpRequest(opts); 3853 3854 if ('open' in xhr && !opts.forceJSONP) { 3855 return new XHR(opts); 3856 } else { 3857 if (!jsonp) throw new Error('JSONP disabled'); 3858 return new JSONP(opts); 3859 } 3860 } 3861 3862 3863 /***/ }), 3864 /* 19 */ 3865 /***/ (function(module, exports, __webpack_require__) { 3866 3867 // browser shim for xmlhttprequest module 3868 3869 var hasCORS = __webpack_require__(20); 3870 3871 module.exports = function (opts) { 3872 var xdomain = opts.xdomain; 3873 3874 // scheme must be same when usign XDomainRequest 3875 // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx 3876 var xscheme = opts.xscheme; 3877 3878 // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default. 3879 // https://github.com/Automattic/engine.io-client/pull/217 3880 var enablesXDR = opts.enablesXDR; 3881 3882 // XMLHttpRequest can be disabled on IE 3883 try { 3884 if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) { 3885 return new XMLHttpRequest(); 3886 } 3887 } catch (e) { } 3888 3889 // Use XDomainRequest for IE8 if enablesXDR is true 3890 // because loading bar keeps flashing when using jsonp-polling 3891 // https://github.com/yujiosaka/socke.io-ie8-loading-example 3892 try { 3893 if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) { 3894 return new XDomainRequest(); 3895 } 3896 } catch (e) { } 3897 3898 if (!xdomain) { 3899 try { 3900 return new self[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP'); 3901 } catch (e) { } 3902 } 3903 }; 3904 3905 3906 /***/ }), 3907 /* 20 */ 3908 /***/ (function(module, exports) { 3909 3910 3911 /** 3912 * Module exports. 3913 * 3914 * Logic borrowed from Modernizr: 3915 * 3916 * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js 3917 */ 3918 3919 try { 3920 module.exports = typeof XMLHttpRequest !== 'undefined' && 3921 'withCredentials' in new XMLHttpRequest(); 3922 } catch (err) { 3923 // if XMLHttp support is disabled in IE then it will throw 3924 // when trying to create 3925 module.exports = false; 3926 } 3927 3928 3929 /***/ }), 3930 /* 21 */ 3931 /***/ (function(module, exports, __webpack_require__) { 3932 3933 /* global attachEvent */ 3934 3935 /** 3936 * Module requirements. 3937 */ 3938 3939 var XMLHttpRequest = __webpack_require__(19); 3940 var Polling = __webpack_require__(22); 3941 var Emitter = __webpack_require__(11); 3942 var inherit = __webpack_require__(33); 3943 var debug = __webpack_require__(3)('engine.io-client:polling-xhr'); 3944 3945 /** 3946 * Module exports. 3947 */ 3948 3949 module.exports = XHR; 3950 module.exports.Request = Request; 3951 3952 /** 3953 * Empty function 3954 */ 3955 3956 function empty () {} 3957 3958 /** 3959 * XHR Polling constructor. 3960 * 3961 * @param {Object} opts 3962 * @api public 3963 */ 3964 3965 function XHR (opts) { 3966 Polling.call(this, opts); 3967 this.requestTimeout = opts.requestTimeout; 3968 this.extraHeaders = opts.extraHeaders; 3969 3970 if (typeof location !== 'undefined') { 3971 var isSSL = 'https:' === location.protocol; 3972 var port = location.port; 3973 3974 // some user agents have empty `location.port` 3975 if (!port) { 3976 port = isSSL ? 443 : 80; 3977 } 3978 3979 this.xd = (typeof location !== 'undefined' && opts.hostname !== location.hostname) || 3980 port !== opts.port; 3981 this.xs = opts.secure !== isSSL; 3982 } 3983 } 3984 3985 /** 3986 * Inherits from Polling. 3987 */ 3988 3989 inherit(XHR, Polling); 3990 3991 /** 3992 * XHR supports binary 3993 */ 3994 3995 XHR.prototype.supportsBinary = true; 3996 3997 /** 3998 * Creates a request. 3999 * 4000 * @param {String} method 4001 * @api private 4002 */ 4003 4004 XHR.prototype.request = function (opts) { 4005 opts = opts || {}; 4006 opts.uri = this.uri(); 4007 opts.xd = this.xd; 4008 opts.xs = this.xs; 4009 opts.agent = this.agent || false; 4010 opts.supportsBinary = this.supportsBinary; 4011 opts.enablesXDR = this.enablesXDR; 4012 opts.withCredentials = this.withCredentials; 4013 4014 // SSL options for Node.js client 4015 opts.pfx = this.pfx; 4016 opts.key = this.key; 4017 opts.passphrase = this.passphrase; 4018 opts.cert = this.cert; 4019 opts.ca = this.ca; 4020 opts.ciphers = this.ciphers; 4021 opts.rejectUnauthorized = this.rejectUnauthorized; 4022 opts.requestTimeout = this.requestTimeout; 4023 4024 // other options for Node.js client 4025 opts.extraHeaders = this.extraHeaders; 4026 4027 return new Request(opts); 4028 }; 4029 4030 /** 4031 * Sends data. 4032 * 4033 * @param {String} data to send. 4034 * @param {Function} called upon flush. 4035 * @api private 4036 */ 4037 4038 XHR.prototype.doWrite = function (data, fn) { 4039 var isBinary = typeof data !== 'string' && data !== undefined; 4040 var req = this.request({ method: 'POST', data: data, isBinary: isBinary }); 4041 var self = this; 4042 req.on('success', fn); 4043 req.on('error', function (err) { 4044 self.onError('xhr post error', err); 4045 }); 4046 this.sendXhr = req; 4047 }; 4048 4049 /** 4050 * Starts a poll cycle. 4051 * 4052 * @api private 4053 */ 4054 4055 XHR.prototype.doPoll = function () { 4056 debug('xhr poll'); 4057 var req = this.request(); 4058 var self = this; 4059 req.on('data', function (data) { 4060 self.onData(data); 4061 }); 4062 req.on('error', function (err) { 4063 self.onError('xhr poll error', err); 4064 }); 4065 this.pollXhr = req; 4066 }; 4067 4068 /** 4069 * Request constructor 4070 * 4071 * @param {Object} options 4072 * @api public 4073 */ 4074 4075 function Request (opts) { 4076 this.method = opts.method || 'GET'; 4077 this.uri = opts.uri; 4078 this.xd = !!opts.xd; 4079 this.xs = !!opts.xs; 4080 this.async = false !== opts.async; 4081 this.data = undefined !== opts.data ? opts.data : null; 4082 this.agent = opts.agent; 4083 this.isBinary = opts.isBinary; 4084 this.supportsBinary = opts.supportsBinary; 4085 this.enablesXDR = opts.enablesXDR; 4086 this.withCredentials = opts.withCredentials; 4087 this.requestTimeout = opts.requestTimeout; 4088 4089 // SSL options for Node.js client 4090 this.pfx = opts.pfx; 4091 this.key = opts.key; 4092 this.passphrase = opts.passphrase; 4093 this.cert = opts.cert; 4094 this.ca = opts.ca; 4095 this.ciphers = opts.ciphers; 4096 this.rejectUnauthorized = opts.rejectUnauthorized; 4097 4098 // other options for Node.js client 4099 this.extraHeaders = opts.extraHeaders; 4100 4101 this.create(); 4102 } 4103 4104 /** 4105 * Mix in `Emitter`. 4106 */ 4107 4108 Emitter(Request.prototype); 4109 4110 /** 4111 * Creates the XHR object and sends the request. 4112 * 4113 * @api private 4114 */ 4115 4116 Request.prototype.create = function () { 4117 var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR }; 4118 4119 // SSL options for Node.js client 4120 opts.pfx = this.pfx; 4121 opts.key = this.key; 4122 opts.passphrase = this.passphrase; 4123 opts.cert = this.cert; 4124 opts.ca = this.ca; 4125 opts.ciphers = this.ciphers; 4126 opts.rejectUnauthorized = this.rejectUnauthorized; 4127 4128 var xhr = this.xhr = new XMLHttpRequest(opts); 4129 var self = this; 4130 4131 try { 4132 debug('xhr open %s: %s', this.method, this.uri); 4133 xhr.open(this.method, this.uri, this.async); 4134 try { 4135 if (this.extraHeaders) { 4136 xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true); 4137 for (var i in this.extraHeaders) { 4138 if (this.extraHeaders.hasOwnProperty(i)) { 4139 xhr.setRequestHeader(i, this.extraHeaders[i]); 4140 } 4141 } 4142 } 4143 } catch (e) {} 4144 4145 if ('POST' === this.method) { 4146 try { 4147 if (this.isBinary) { 4148 xhr.setRequestHeader('Content-type', 'application/octet-stream'); 4149 } else { 4150 xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); 4151 } 4152 } catch (e) {} 4153 } 4154 4155 try { 4156 xhr.setRequestHeader('Accept', '*/*'); 4157 } catch (e) {} 4158 4159 // ie6 check 4160 if ('withCredentials' in xhr) { 4161 xhr.withCredentials = this.withCredentials; 4162 } 4163 4164 if (this.requestTimeout) { 4165 xhr.timeout = this.requestTimeout; 4166 } 4167 4168 if (this.hasXDR()) { 4169 xhr.onload = function () { 4170 self.onLoad(); 4171 }; 4172 xhr.onerror = function () { 4173 self.onError(xhr.responseText); 4174 }; 4175 } else { 4176 xhr.onreadystatechange = function () { 4177 if (xhr.readyState === 2) { 4178 try { 4179 var contentType = xhr.getResponseHeader('Content-Type'); 4180 if (self.supportsBinary && contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') { 4181 xhr.responseType = 'arraybuffer'; 4182 } 4183 } catch (e) {} 4184 } 4185 if (4 !== xhr.readyState) return; 4186 if (200 === xhr.status || 1223 === xhr.status) { 4187 self.onLoad(); 4188 } else { 4189 // make sure the `error` event handler that's user-set 4190 // does not throw in the same tick and gets caught here 4191 setTimeout(function () { 4192 self.onError(typeof xhr.status === 'number' ? xhr.status : 0); 4193 }, 0); 4194 } 4195 }; 4196 } 4197 4198 debug('xhr data %s', this.data); 4199 xhr.send(this.data); 4200 } catch (e) { 4201 // Need to defer since .create() is called directly fhrom the constructor 4202 // and thus the 'error' event can only be only bound *after* this exception 4203 // occurs. Therefore, also, we cannot throw here at all. 4204 setTimeout(function () { 4205 self.onError(e); 4206 }, 0); 4207 return; 4208 } 4209 4210 if (typeof document !== 'undefined') { 4211 this.index = Request.requestsCount++; 4212 Request.requests[this.index] = this; 4213 } 4214 }; 4215 4216 /** 4217 * Called upon successful response. 4218 * 4219 * @api private 4220 */ 4221 4222 Request.prototype.onSuccess = function () { 4223 this.emit('success'); 4224 this.cleanup(); 4225 }; 4226 4227 /** 4228 * Called if we have data. 4229 * 4230 * @api private 4231 */ 4232 4233 Request.prototype.onData = function (data) { 4234 this.emit('data', data); 4235 this.onSuccess(); 4236 }; 4237 4238 /** 4239 * Called upon error. 4240 * 4241 * @api private 4242 */ 4243 4244 Request.prototype.onError = function (err) { 4245 this.emit('error', err); 4246 this.cleanup(true); 4247 }; 4248 4249 /** 4250 * Cleans up house. 4251 * 4252 * @api private 4253 */ 4254 4255 Request.prototype.cleanup = function (fromError) { 4256 if ('undefined' === typeof this.xhr || null === this.xhr) { 4257 return; 4258 } 4259 // xmlhttprequest 4260 if (this.hasXDR()) { 4261 this.xhr.onload = this.xhr.onerror = empty; 4262 } else { 4263 this.xhr.onreadystatechange = empty; 4264 } 4265 4266 if (fromError) { 4267 try { 4268 this.xhr.abort(); 4269 } catch (e) {} 4270 } 4271 4272 if (typeof document !== 'undefined') { 4273 delete Request.requests[this.index]; 4274 } 4275 4276 this.xhr = null; 4277 }; 4278 4279 /** 4280 * Called upon load. 4281 * 4282 * @api private 4283 */ 4284 4285 Request.prototype.onLoad = function () { 4286 var data; 4287 try { 4288 var contentType; 4289 try { 4290 contentType = this.xhr.getResponseHeader('Content-Type'); 4291 } catch (e) {} 4292 if (contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') { 4293 data = this.xhr.response || this.xhr.responseText; 4294 } else { 4295 data = this.xhr.responseText; 4296 } 4297 } catch (e) { 4298 this.onError(e); 4299 } 4300 if (null != data) { 4301 this.onData(data); 4302 } 4303 }; 4304 4305 /** 4306 * Check if it has XDomainRequest. 4307 * 4308 * @api private 4309 */ 4310 4311 Request.prototype.hasXDR = function () { 4312 return typeof XDomainRequest !== 'undefined' && !this.xs && this.enablesXDR; 4313 }; 4314 4315 /** 4316 * Aborts the request. 4317 * 4318 * @api public 4319 */ 4320 4321 Request.prototype.abort = function () { 4322 this.cleanup(); 4323 }; 4324 4325 /** 4326 * Aborts pending requests when unloading the window. This is needed to prevent 4327 * memory leaks (e.g. when using IE) and to ensure that no spurious error is 4328 * emitted. 4329 */ 4330 4331 Request.requestsCount = 0; 4332 Request.requests = {}; 4333 4334 if (typeof document !== 'undefined') { 4335 if (typeof attachEvent === 'function') { 4336 attachEvent('onunload', unloadHandler); 4337 } else if (typeof addEventListener === 'function') { 4338 var terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload'; 4339 addEventListener(terminationEvent, unloadHandler, false); 4340 } 4341 } 4342 4343 function unloadHandler () { 4344 for (var i in Request.requests) { 4345 if (Request.requests.hasOwnProperty(i)) { 4346 Request.requests[i].abort(); 4347 } 4348 } 4349 } 4350 4351 4352 /***/ }), 4353 /* 22 */ 4354 /***/ (function(module, exports, __webpack_require__) { 4355 4356 /** 4357 * Module dependencies. 4358 */ 4359 4360 var Transport = __webpack_require__(23); 4361 var parseqs = __webpack_require__(32); 4362 var parser = __webpack_require__(24); 4363 var inherit = __webpack_require__(33); 4364 var yeast = __webpack_require__(34); 4365 var debug = __webpack_require__(3)('engine.io-client:polling'); 4366 4367 /** 4368 * Module exports. 4369 */ 4370 4371 module.exports = Polling; 4372 4373 /** 4374 * Is XHR2 supported? 4375 */ 4376 4377 var hasXHR2 = (function () { 4378 var XMLHttpRequest = __webpack_require__(19); 4379 var xhr = new XMLHttpRequest({ xdomain: false }); 4380 return null != xhr.responseType; 4381 })(); 4382 4383 /** 4384 * Polling interface. 4385 * 4386 * @param {Object} opts 4387 * @api private 4388 */ 4389 4390 function Polling (opts) { 4391 var forceBase64 = (opts && opts.forceBase64); 4392 if (!hasXHR2 || forceBase64) { 4393 this.supportsBinary = false; 4394 } 4395 Transport.call(this, opts); 4396 } 4397 4398 /** 4399 * Inherits from Transport. 4400 */ 4401 4402 inherit(Polling, Transport); 4403 4404 /** 4405 * Transport name. 4406 */ 4407 4408 Polling.prototype.name = 'polling'; 4409 4410 /** 4411 * Opens the socket (triggers polling). We write a PING message to determine 4412 * when the transport is open. 4413 * 4414 * @api private 4415 */ 4416 4417 Polling.prototype.doOpen = function () { 4418 this.poll(); 4419 }; 4420 4421 /** 4422 * Pauses polling. 4423 * 4424 * @param {Function} callback upon buffers are flushed and transport is paused 4425 * @api private 4426 */ 4427 4428 Polling.prototype.pause = function (onPause) { 4429 var self = this; 4430 4431 this.readyState = 'pausing'; 4432 4433 function pause () { 4434 debug('paused'); 4435 self.readyState = 'paused'; 4436 onPause(); 4437 } 4438 4439 if (this.polling || !this.writable) { 4440 var total = 0; 4441 4442 if (this.polling) { 4443 debug('we are currently polling - waiting to pause'); 4444 total++; 4445 this.once('pollComplete', function () { 4446 debug('pre-pause polling complete'); 4447 --total || pause(); 4448 }); 4449 } 4450 4451 if (!this.writable) { 4452 debug('we are currently writing - waiting to pause'); 4453 total++; 4454 this.once('drain', function () { 4455 debug('pre-pause writing complete'); 4456 --total || pause(); 4457 }); 4458 } 4459 } else { 4460 pause(); 4461 } 4462 }; 4463 4464 /** 4465 * Starts polling cycle. 4466 * 4467 * @api public 4468 */ 4469 4470 Polling.prototype.poll = function () { 4471 debug('polling'); 4472 this.polling = true; 4473 this.doPoll(); 4474 this.emit('poll'); 4475 }; 4476 4477 /** 4478 * Overloads onData to detect payloads. 4479 * 4480 * @api private 4481 */ 4482 4483 Polling.prototype.onData = function (data) { 4484 var self = this; 4485 debug('polling got data %s', data); 4486 var callback = function (packet, index, total) { 4487 // if its the first message we consider the transport open 4488 if ('opening' === self.readyState) { 4489 self.onOpen(); 4490 } 4491 4492 // if its a close packet, we close the ongoing requests 4493 if ('close' === packet.type) { 4494 self.onClose(); 4495 return false; 4496 } 4497 4498 // otherwise bypass onData and handle the message 4499 self.onPacket(packet); 4500 }; 4501 4502 // decode payload 4503 parser.decodePayload(data, this.socket.binaryType, callback); 4504 4505 // if an event did not trigger closing 4506 if ('closed' !== this.readyState) { 4507 // if we got data we're not polling 4508 this.polling = false; 4509 this.emit('pollComplete'); 4510 4511 if ('open' === this.readyState) { 4512 this.poll(); 4513 } else { 4514 debug('ignoring poll - transport state "%s"', this.readyState); 4515 } 4516 } 4517 }; 4518 4519 /** 4520 * For polling, send a close packet. 4521 * 4522 * @api private 4523 */ 4524 4525 Polling.prototype.doClose = function () { 4526 var self = this; 4527 4528 function close () { 4529 debug('writing close packet'); 4530 self.write([{ type: 'close' }]); 4531 } 4532 4533 if ('open' === this.readyState) { 4534 debug('transport open - closing'); 4535 close(); 4536 } else { 4537 // in case we're trying to close while 4538 // handshaking is in progress (GH-164) 4539 debug('transport not open - deferring close'); 4540 this.once('open', close); 4541 } 4542 }; 4543 4544 /** 4545 * Writes a packets payload. 4546 * 4547 * @param {Array} data packets 4548 * @param {Function} drain callback 4549 * @api private 4550 */ 4551 4552 Polling.prototype.write = function (packets) { 4553 var self = this; 4554 this.writable = false; 4555 var callbackfn = function () { 4556 self.writable = true; 4557 self.emit('drain'); 4558 }; 4559 4560 parser.encodePayload(packets, this.supportsBinary, function (data) { 4561 self.doWrite(data, callbackfn); 4562 }); 4563 }; 4564 4565 /** 4566 * Generates uri for connection. 4567 * 4568 * @api private 4569 */ 4570 4571 Polling.prototype.uri = function () { 4572 var query = this.query || {}; 4573 var schema = this.secure ? 'https' : 'http'; 4574 var port = ''; 4575 4576 // cache busting is forced 4577 if (false !== this.timestampRequests) { 4578 query[this.timestampParam] = yeast(); 4579 } 4580 4581 if (!this.supportsBinary && !query.sid) { 4582 query.b64 = 1; 4583 } 4584 4585 query = parseqs.encode(query); 4586 4587 // avoid port if default for schema 4588 if (this.port && (('https' === schema && Number(this.port) !== 443) || 4589 ('http' === schema && Number(this.port) !== 80))) { 4590 port = ':' + this.port; 4591 } 4592 4593 // prepend ? to query 4594 if (query.length) { 4595 query = '?' + query; 4596 } 4597 4598 var ipv6 = this.hostname.indexOf(':') !== -1; 4599 return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query; 4600 }; 4601 4602 4603 /***/ }), 4604 /* 23 */ 4605 /***/ (function(module, exports, __webpack_require__) { 4606 4607 /** 4608 * Module dependencies. 4609 */ 4610 4611 var parser = __webpack_require__(24); 4612 var Emitter = __webpack_require__(11); 4613 4614 /** 4615 * Module exports. 4616 */ 4617 4618 module.exports = Transport; 4619 4620 /** 4621 * Transport abstract constructor. 4622 * 4623 * @param {Object} options. 4624 * @api private 4625 */ 4626 4627 function Transport (opts) { 4628 this.path = opts.path; 4629 this.hostname = opts.hostname; 4630 this.port = opts.port; 4631 this.secure = opts.secure; 4632 this.query = opts.query; 4633 this.timestampParam = opts.timestampParam; 4634 this.timestampRequests = opts.timestampRequests; 4635 this.readyState = ''; 4636 this.agent = opts.agent || false; 4637 this.socket = opts.socket; 4638 this.enablesXDR = opts.enablesXDR; 4639 this.withCredentials = opts.withCredentials; 4640 4641 // SSL options for Node.js client 4642 this.pfx = opts.pfx; 4643 this.key = opts.key; 4644 this.passphrase = opts.passphrase; 4645 this.cert = opts.cert; 4646 this.ca = opts.ca; 4647 this.ciphers = opts.ciphers; 4648 this.rejectUnauthorized = opts.rejectUnauthorized; 4649 this.forceNode = opts.forceNode; 4650 4651 // results of ReactNative environment detection 4652 this.isReactNative = opts.isReactNative; 4653 4654 // other options for Node.js client 4655 this.extraHeaders = opts.extraHeaders; 4656 this.localAddress = opts.localAddress; 4657 } 4658 4659 /** 4660 * Mix in `Emitter`. 4661 */ 4662 4663 Emitter(Transport.prototype); 4664 4665 /** 4666 * Emits an error. 4667 * 4668 * @param {String} str 4669 * @return {Transport} for chaining 4670 * @api public 4671 */ 4672 4673 Transport.prototype.onError = function (msg, desc) { 4674 var err = new Error(msg); 4675 err.type = 'TransportError'; 4676 err.description = desc; 4677 this.emit('error', err); 4678 return this; 4679 }; 4680 4681 /** 4682 * Opens the transport. 4683 * 4684 * @api public 4685 */ 4686 4687 Transport.prototype.open = function () { 4688 if ('closed' === this.readyState || '' === this.readyState) { 4689 this.readyState = 'opening'; 4690 this.doOpen(); 4691 } 4692 4693 return this; 4694 }; 4695 4696 /** 4697 * Closes the transport. 4698 * 4699 * @api private 4700 */ 4701 4702 Transport.prototype.close = function () { 4703 if ('opening' === this.readyState || 'open' === this.readyState) { 4704 this.doClose(); 4705 this.onClose(); 4706 } 4707 4708 return this; 4709 }; 4710 4711 /** 4712 * Sends multiple packets. 4713 * 4714 * @param {Array} packets 4715 * @api private 4716 */ 4717 4718 Transport.prototype.send = function (packets) { 4719 if ('open' === this.readyState) { 4720 this.write(packets); 4721 } else { 4722 throw new Error('Transport not open'); 4723 } 4724 }; 4725 4726 /** 4727 * Called upon open 4728 * 4729 * @api private 4730 */ 4731 4732 Transport.prototype.onOpen = function () { 4733 this.readyState = 'open'; 4734 this.writable = true; 4735 this.emit('open'); 4736 }; 4737 4738 /** 4739 * Called with data. 4740 * 4741 * @param {String} data 4742 * @api private 4743 */ 4744 4745 Transport.prototype.onData = function (data) { 4746 var packet = parser.decodePacket(data, this.socket.binaryType); 4747 this.onPacket(packet); 4748 }; 4749 4750 /** 4751 * Called with a decoded packet. 4752 */ 4753 4754 Transport.prototype.onPacket = function (packet) { 4755 this.emit('packet', packet); 4756 }; 4757 4758 /** 4759 * Called upon close. 4760 * 4761 * @api private 4762 */ 4763 4764 Transport.prototype.onClose = function () { 4765 this.readyState = 'closed'; 4766 this.emit('close'); 4767 }; 4768 4769 4770 /***/ }), 4771 /* 24 */ 4772 /***/ (function(module, exports, __webpack_require__) { 4773 4774 /** 4775 * Module dependencies. 4776 */ 4777 4778 var keys = __webpack_require__(25); 4779 var hasBinary = __webpack_require__(26); 4780 var sliceBuffer = __webpack_require__(27); 4781 var after = __webpack_require__(28); 4782 var utf8 = __webpack_require__(29); 4783 4784 var base64encoder; 4785 if (typeof ArrayBuffer !== 'undefined') { 4786 base64encoder = __webpack_require__(30); 4787 } 4788 4789 /** 4790 * Check if we are running an android browser. That requires us to use 4791 * ArrayBuffer with polling transports... 4792 * 4793 * http://ghinda.net/jpeg-blob-ajax-android/ 4794 */ 4795 4796 var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent); 4797 4798 /** 4799 * Check if we are running in PhantomJS. 4800 * Uploading a Blob with PhantomJS does not work correctly, as reported here: 4801 * https://github.com/ariya/phantomjs/issues/11395 4802 * @type boolean 4803 */ 4804 var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent); 4805 4806 /** 4807 * When true, avoids using Blobs to encode payloads. 4808 * @type boolean 4809 */ 4810 var dontSendBlobs = isAndroid || isPhantomJS; 4811 4812 /** 4813 * Current protocol version. 4814 */ 4815 4816 exports.protocol = 3; 4817 4818 /** 4819 * Packet types. 4820 */ 4821 4822 var packets = exports.packets = { 4823 open: 0 // non-ws 4824 , close: 1 // non-ws 4825 , ping: 2 4826 , pong: 3 4827 , message: 4 4828 , upgrade: 5 4829 , noop: 6 4830 }; 4831 4832 var packetslist = keys(packets); 4833 4834 /** 4835 * Premade error packet. 4836 */ 4837 4838 var err = { type: 'error', data: 'parser error' }; 4839 4840 /** 4841 * Create a blob api even for blob builder when vendor prefixes exist 4842 */ 4843 4844 var Blob = __webpack_require__(31); 4845 4846 /** 4847 * Encodes a packet. 4848 * 4849 * <packet type id> [ <data> ] 4850 * 4851 * Example: 4852 * 4853 * 5hello world 4854 * 3 4855 * 4 4856 * 4857 * Binary is encoded in an identical principle 4858 * 4859 * @api private 4860 */ 4861 4862 exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { 4863 if (typeof supportsBinary === 'function') { 4864 callback = supportsBinary; 4865 supportsBinary = false; 4866 } 4867 4868 if (typeof utf8encode === 'function') { 4869 callback = utf8encode; 4870 utf8encode = null; 4871 } 4872 4873 var data = (packet.data === undefined) 4874 ? undefined 4875 : packet.data.buffer || packet.data; 4876 4877 if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) { 4878 return encodeArrayBuffer(packet, supportsBinary, callback); 4879 } else if (typeof Blob !== 'undefined' && data instanceof Blob) { 4880 return encodeBlob(packet, supportsBinary, callback); 4881 } 4882 4883 // might be an object with { base64: true, data: dataAsBase64String } 4884 if (data && data.base64) { 4885 return encodeBase64Object(packet, callback); 4886 } 4887 4888 // Sending data as a utf-8 string 4889 var encoded = packets[packet.type]; 4890 4891 // data fragment is optional 4892 if (undefined !== packet.data) { 4893 encoded += utf8encode ? utf8.encode(String(packet.data), { strict: false }) : String(packet.data); 4894 } 4895 4896 return callback('' + encoded); 4897 4898 }; 4899 4900 function encodeBase64Object(packet, callback) { 4901 // packet data is an object { base64: true, data: dataAsBase64String } 4902 var message = 'b' + exports.packets[packet.type] + packet.data.data; 4903 return callback(message); 4904 } 4905 4906 /** 4907 * Encode packet helpers for binary types 4908 */ 4909 4910 function encodeArrayBuffer(packet, supportsBinary, callback) { 4911 if (!supportsBinary) { 4912 return exports.encodeBase64Packet(packet, callback); 4913 } 4914 4915 var data = packet.data; 4916 var contentArray = new Uint8Array(data); 4917 var resultBuffer = new Uint8Array(1 + data.byteLength); 4918 4919 resultBuffer[0] = packets[packet.type]; 4920 for (var i = 0; i < contentArray.length; i++) { 4921 resultBuffer[i+1] = contentArray[i]; 4922 } 4923 4924 return callback(resultBuffer.buffer); 4925 } 4926 4927 function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) { 4928 if (!supportsBinary) { 4929 return exports.encodeBase64Packet(packet, callback); 4930 } 4931 4932 var fr = new FileReader(); 4933 fr.onload = function() { 4934 exports.encodePacket({ type: packet.type, data: fr.result }, supportsBinary, true, callback); 4935 }; 4936 return fr.readAsArrayBuffer(packet.data); 4937 } 4938 4939 function encodeBlob(packet, supportsBinary, callback) { 4940 if (!supportsBinary) { 4941 return exports.encodeBase64Packet(packet, callback); 4942 } 4943 4944 if (dontSendBlobs) { 4945 return encodeBlobAsArrayBuffer(packet, supportsBinary, callback); 4946 } 4947 4948 var length = new Uint8Array(1); 4949 length[0] = packets[packet.type]; 4950 var blob = new Blob([length.buffer, packet.data]); 4951 4952 return callback(blob); 4953 } 4954 4955 /** 4956 * Encodes a packet with binary data in a base64 string 4957 * 4958 * @param {Object} packet, has `type` and `data` 4959 * @return {String} base64 encoded message 4960 */ 4961 4962 exports.encodeBase64Packet = function(packet, callback) { 4963 var message = 'b' + exports.packets[packet.type]; 4964 if (typeof Blob !== 'undefined' && packet.data instanceof Blob) { 4965 var fr = new FileReader(); 4966 fr.onload = function() { 4967 var b64 = fr.result.split(',')[1]; 4968 callback(message + b64); 4969 }; 4970 return fr.readAsDataURL(packet.data); 4971 } 4972 4973 var b64data; 4974 try { 4975 b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data)); 4976 } catch (e) { 4977 // iPhone Safari doesn't let you apply with typed arrays 4978 var typed = new Uint8Array(packet.data); 4979 var basic = new Array(typed.length); 4980 for (var i = 0; i < typed.length; i++) { 4981 basic[i] = typed[i]; 4982 } 4983 b64data = String.fromCharCode.apply(null, basic); 4984 } 4985 message += btoa(b64data); 4986 return callback(message); 4987 }; 4988 4989 /** 4990 * Decodes a packet. Changes format to Blob if requested. 4991 * 4992 * @return {Object} with `type` and `data` (if any) 4993 * @api private 4994 */ 4995 4996 exports.decodePacket = function (data, binaryType, utf8decode) { 4997 if (data === undefined) { 4998 return err; 4999 } 5000 // String data 5001 if (typeof data === 'string') { 5002 if (data.charAt(0) === 'b') { 5003 return exports.decodeBase64Packet(data.substr(1), binaryType); 5004 } 5005 5006 if (utf8decode) { 5007 data = tryDecode(data); 5008 if (data === false) { 5009 return err; 5010 } 5011 } 5012 var type = data.charAt(0); 5013 5014 if (Number(type) != type || !packetslist[type]) { 5015 return err; 5016 } 5017 5018 if (data.length > 1) { 5019 return { type: packetslist[type], data: data.substring(1) }; 5020 } else { 5021 return { type: packetslist[type] }; 5022 } 5023 } 5024 5025 var asArray = new Uint8Array(data); 5026 var type = asArray[0]; 5027 var rest = sliceBuffer(data, 1); 5028 if (Blob && binaryType === 'blob') { 5029 rest = new Blob([rest]); 5030 } 5031 return { type: packetslist[type], data: rest }; 5032 }; 5033 5034 function tryDecode(data) { 5035 try { 5036 data = utf8.decode(data, { strict: false }); 5037 } catch (e) { 5038 return false; 5039 } 5040 return data; 5041 } 5042 5043 /** 5044 * Decodes a packet encoded in a base64 string 5045 * 5046 * @param {String} base64 encoded message 5047 * @return {Object} with `type` and `data` (if any) 5048 */ 5049 5050 exports.decodeBase64Packet = function(msg, binaryType) { 5051 var type = packetslist[msg.charAt(0)]; 5052 if (!base64encoder) { 5053 return { type: type, data: { base64: true, data: msg.substr(1) } }; 5054 } 5055 5056 var data = base64encoder.decode(msg.substr(1)); 5057 5058 if (binaryType === 'blob' && Blob) { 5059 data = new Blob([data]); 5060 } 5061 5062 return { type: type, data: data }; 5063 }; 5064 5065 /** 5066 * Encodes multiple messages (payload). 5067 * 5068 * <length>:data 5069 * 5070 * Example: 5071 * 5072 * 11:hello world2:hi 5073 * 5074 * If any contents are binary, they will be encoded as base64 strings. Base64 5075 * encoded strings are marked with a b before the length specifier 5076 * 5077 * @param {Array} packets 5078 * @api private 5079 */ 5080 5081 exports.encodePayload = function (packets, supportsBinary, callback) { 5082 if (typeof supportsBinary === 'function') { 5083 callback = supportsBinary; 5084 supportsBinary = null; 5085 } 5086 5087 var isBinary = hasBinary(packets); 5088 5089 if (supportsBinary && isBinary) { 5090 if (Blob && !dontSendBlobs) { 5091 return exports.encodePayloadAsBlob(packets, callback); 5092 } 5093 5094 return exports.encodePayloadAsArrayBuffer(packets, callback); 5095 } 5096 5097 if (!packets.length) { 5098 return callback('0:'); 5099 } 5100 5101 function setLengthHeader(message) { 5102 return message.length + ':' + message; 5103 } 5104 5105 function encodeOne(packet, doneCallback) { 5106 exports.encodePacket(packet, !isBinary ? false : supportsBinary, false, function(message) { 5107 doneCallback(null, setLengthHeader(message)); 5108 }); 5109 } 5110 5111 map(packets, encodeOne, function(err, results) { 5112 return callback(results.join('')); 5113 }); 5114 }; 5115 5116 /** 5117 * Async array map using after 5118 */ 5119 5120 function map(ary, each, done) { 5121 var result = new Array(ary.length); 5122 var next = after(ary.length, done); 5123 5124 var eachWithIndex = function(i, el, cb) { 5125 each(el, function(error, msg) { 5126 result[i] = msg; 5127 cb(error, result); 5128 }); 5129 }; 5130 5131 for (var i = 0; i < ary.length; i++) { 5132 eachWithIndex(i, ary[i], next); 5133 } 5134 } 5135 5136 /* 5137 * Decodes data when a payload is maybe expected. Possible binary contents are 5138 * decoded from their base64 representation 5139 * 5140 * @param {String} data, callback method 5141 * @api public 5142 */ 5143 5144 exports.decodePayload = function (data, binaryType, callback) { 5145 if (typeof data !== 'string') { 5146 return exports.decodePayloadAsBinary(data, binaryType, callback); 5147 } 5148 5149 if (typeof binaryType === 'function') { 5150 callback = binaryType; 5151 binaryType = null; 5152 } 5153 5154 var packet; 5155 if (data === '') { 5156 // parser error - ignoring payload 5157 return callback(err, 0, 1); 5158 } 5159 5160 var length = '', n, msg; 5161 5162 for (var i = 0, l = data.length; i < l; i++) { 5163 var chr = data.charAt(i); 5164 5165 if (chr !== ':') { 5166 length += chr; 5167 continue; 5168 } 5169 5170 if (length === '' || (length != (n = Number(length)))) { 5171 // parser error - ignoring payload 5172 return callback(err, 0, 1); 5173 } 5174 5175 msg = data.substr(i + 1, n); 5176 5177 if (length != msg.length) { 5178 // parser error - ignoring payload 5179 return callback(err, 0, 1); 5180 } 5181 5182 if (msg.length) { 5183 packet = exports.decodePacket(msg, binaryType, false); 5184 5185 if (err.type === packet.type && err.data === packet.data) { 5186 // parser error in individual packet - ignoring payload 5187 return callback(err, 0, 1); 5188 } 5189 5190 var ret = callback(packet, i + n, l); 5191 if (false === ret) return; 5192 } 5193 5194 // advance cursor 5195 i += n; 5196 length = ''; 5197 } 5198 5199 if (length !== '') { 5200 // parser error - ignoring payload 5201 return callback(err, 0, 1); 5202 } 5203 5204 }; 5205 5206 /** 5207 * Encodes multiple messages (payload) as binary. 5208 * 5209 * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number 5210 * 255><data> 5211 * 5212 * Example: 5213 * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers 5214 * 5215 * @param {Array} packets 5216 * @return {ArrayBuffer} encoded payload 5217 * @api private 5218 */ 5219 5220 exports.encodePayloadAsArrayBuffer = function(packets, callback) { 5221 if (!packets.length) { 5222 return callback(new ArrayBuffer(0)); 5223 } 5224 5225 function encodeOne(packet, doneCallback) { 5226 exports.encodePacket(packet, true, true, function(data) { 5227 return doneCallback(null, data); 5228 }); 5229 } 5230 5231 map(packets, encodeOne, function(err, encodedPackets) { 5232 var totalLength = encodedPackets.reduce(function(acc, p) { 5233 var len; 5234 if (typeof p === 'string'){ 5235 len = p.length; 5236 } else { 5237 len = p.byteLength; 5238 } 5239 return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2 5240 }, 0); 5241 5242 var resultArray = new Uint8Array(totalLength); 5243 5244 var bufferIndex = 0; 5245 encodedPackets.forEach(function(p) { 5246 var isString = typeof p === 'string'; 5247 var ab = p; 5248 if (isString) { 5249 var view = new Uint8Array(p.length); 5250 for (var i = 0; i < p.length; i++) { 5251 view[i] = p.charCodeAt(i); 5252 } 5253 ab = view.buffer; 5254 } 5255 5256 if (isString) { // not true binary 5257 resultArray[bufferIndex++] = 0; 5258 } else { // true binary 5259 resultArray[bufferIndex++] = 1; 5260 } 5261 5262 var lenStr = ab.byteLength.toString(); 5263 for (var i = 0; i < lenStr.length; i++) { 5264 resultArray[bufferIndex++] = parseInt(lenStr[i]); 5265 } 5266 resultArray[bufferIndex++] = 255; 5267 5268 var view = new Uint8Array(ab); 5269 for (var i = 0; i < view.length; i++) { 5270 resultArray[bufferIndex++] = view[i]; 5271 } 5272 }); 5273 5274 return callback(resultArray.buffer); 5275 }); 5276 }; 5277 5278 /** 5279 * Encode as Blob 5280 */ 5281 5282 exports.encodePayloadAsBlob = function(packets, callback) { 5283 function encodeOne(packet, doneCallback) { 5284 exports.encodePacket(packet, true, true, function(encoded) { 5285 var binaryIdentifier = new Uint8Array(1); 5286 binaryIdentifier[0] = 1; 5287 if (typeof encoded === 'string') { 5288 var view = new Uint8Array(encoded.length); 5289 for (var i = 0; i < encoded.length; i++) { 5290 view[i] = encoded.charCodeAt(i); 5291 } 5292 encoded = view.buffer; 5293 binaryIdentifier[0] = 0; 5294 } 5295 5296 var len = (encoded instanceof ArrayBuffer) 5297 ? encoded.byteLength 5298 : encoded.size; 5299 5300 var lenStr = len.toString(); 5301 var lengthAry = new Uint8Array(lenStr.length + 1); 5302 for (var i = 0; i < lenStr.length; i++) { 5303 lengthAry[i] = parseInt(lenStr[i]); 5304 } 5305 lengthAry[lenStr.length] = 255; 5306 5307 if (Blob) { 5308 var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]); 5309 doneCallback(null, blob); 5310 } 5311 }); 5312 } 5313 5314 map(packets, encodeOne, function(err, results) { 5315 return callback(new Blob(results)); 5316 }); 5317 }; 5318 5319 /* 5320 * Decodes data when a payload is maybe expected. Strings are decoded by 5321 * interpreting each byte as a key code for entries marked to start with 0. See 5322 * description of encodePayloadAsBinary 5323 * 5324 * @param {ArrayBuffer} data, callback method 5325 * @api public 5326 */ 5327 5328 exports.decodePayloadAsBinary = function (data, binaryType, callback) { 5329 if (typeof binaryType === 'function') { 5330 callback = binaryType; 5331 binaryType = null; 5332 } 5333 5334 var bufferTail = data; 5335 var buffers = []; 5336 5337 while (bufferTail.byteLength > 0) { 5338 var tailArray = new Uint8Array(bufferTail); 5339 var isString = tailArray[0] === 0; 5340 var msgLength = ''; 5341 5342 for (var i = 1; ; i++) { 5343 if (tailArray[i] === 255) break; 5344 5345 // 310 = char length of Number.MAX_VALUE 5346 if (msgLength.length > 310) { 5347 return callback(err, 0, 1); 5348 } 5349 5350 msgLength += tailArray[i]; 5351 } 5352 5353 bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length); 5354 msgLength = parseInt(msgLength); 5355 5356 var msg = sliceBuffer(bufferTail, 0, msgLength); 5357 if (isString) { 5358 try { 5359 msg = String.fromCharCode.apply(null, new Uint8Array(msg)); 5360 } catch (e) { 5361 // iPhone Safari doesn't let you apply to typed arrays 5362 var typed = new Uint8Array(msg); 5363 msg = ''; 5364 for (var i = 0; i < typed.length; i++) { 5365 msg += String.fromCharCode(typed[i]); 5366 } 5367 } 5368 } 5369 5370 buffers.push(msg); 5371 bufferTail = sliceBuffer(bufferTail, msgLength); 5372 } 5373 5374 var total = buffers.length; 5375 buffers.forEach(function(buffer, i) { 5376 callback(exports.decodePacket(buffer, binaryType, true), i, total); 5377 }); 5378 }; 5379 5380 5381 /***/ }), 5382 /* 25 */ 5383 /***/ (function(module, exports) { 5384 5385 5386 /** 5387 * Gets the keys for an object. 5388 * 5389 * @return {Array} keys 5390 * @api private 5391 */ 5392 5393 module.exports = Object.keys || function keys (obj){ 5394 var arr = []; 5395 var has = Object.prototype.hasOwnProperty; 5396 5397 for (var i in obj) { 5398 if (has.call(obj, i)) { 5399 arr.push(i); 5400 } 5401 } 5402 return arr; 5403 }; 5404 5405 5406 /***/ }), 5407 /* 26 */ 5408 /***/ (function(module, exports, __webpack_require__) { 5409 5410 /* global Blob File */ 5411 5412 /* 5413 * Module requirements. 5414 */ 5415 5416 var isArray = __webpack_require__(13); 5417 5418 var toString = Object.prototype.toString; 5419 var withNativeBlob = typeof Blob === 'function' || 5420 typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'; 5421 var withNativeFile = typeof File === 'function' || 5422 typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'; 5423 5424 /** 5425 * Module exports. 5426 */ 5427 5428 module.exports = hasBinary; 5429 5430 /** 5431 * Checks for binary data. 5432 * 5433 * Supports Buffer, ArrayBuffer, Blob and File. 5434 * 5435 * @param {Object} anything 5436 * @api public 5437 */ 5438 5439 function hasBinary (obj) { 5440 if (!obj || typeof obj !== 'object') { 5441 return false; 5442 } 5443 5444 if (isArray(obj)) { 5445 for (var i = 0, l = obj.length; i < l; i++) { 5446 if (hasBinary(obj[i])) { 5447 return true; 5448 } 5449 } 5450 return false; 5451 } 5452 5453 if ((typeof Buffer === 'function' && Buffer.isBuffer && Buffer.isBuffer(obj)) || 5454 (typeof ArrayBuffer === 'function' && obj instanceof ArrayBuffer) || 5455 (withNativeBlob && obj instanceof Blob) || 5456 (withNativeFile && obj instanceof File) 5457 ) { 5458 return true; 5459 } 5460 5461 // see: https://github.com/Automattic/has-binary/pull/4 5462 if (obj.toJSON && typeof obj.toJSON === 'function' && arguments.length === 1) { 5463 return hasBinary(obj.toJSON(), true); 5464 } 5465 5466 for (var key in obj) { 5467 if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) { 5468 return true; 5469 } 5470 } 5471 5472 return false; 5473 } 5474 5475 5476 /***/ }), 5477 /* 27 */ 5478 /***/ (function(module, exports) { 5479 5480 /** 5481 * An abstraction for slicing an arraybuffer even when 5482 * ArrayBuffer.prototype.slice is not supported 5483 * 5484 * @api public 5485 */ 5486 5487 module.exports = function(arraybuffer, start, end) { 5488 var bytes = arraybuffer.byteLength; 5489 start = start || 0; 5490 end = end || bytes; 5491 5492 if (arraybuffer.slice) { return arraybuffer.slice(start, end); } 5493 5494 if (start < 0) { start += bytes; } 5495 if (end < 0) { end += bytes; } 5496 if (end > bytes) { end = bytes; } 5497 5498 if (start >= bytes || start >= end || bytes === 0) { 5499 return new ArrayBuffer(0); 5500 } 5501 5502 var abv = new Uint8Array(arraybuffer); 5503 var result = new Uint8Array(end - start); 5504 for (var i = start, ii = 0; i < end; i++, ii++) { 5505 result[ii] = abv[i]; 5506 } 5507 return result.buffer; 5508 }; 5509 5510 5511 /***/ }), 5512 /* 28 */ 5513 /***/ (function(module, exports) { 5514 5515 module.exports = after 5516 5517 function after(count, callback, err_cb) { 5518 var bail = false 5519 err_cb = err_cb || noop 5520 proxy.count = count 5521 5522 return (count === 0) ? callback() : proxy 5523 5524 function proxy(err, result) { 5525 if (proxy.count <= 0) { 5526 throw new Error('after called too many times') 5527 } 5528 --proxy.count 5529 5530 // after first error, rest are passed to err_cb 5531 if (err) { 5532 bail = true 5533 callback(err) 5534 // future error callbacks will go to error handler 5535 callback = err_cb 5536 } else if (proxy.count === 0 && !bail) { 5537 callback(null, result) 5538 } 5539 } 5540 } 5541 5542 function noop() {} 5543 5544 5545 /***/ }), 5546 /* 29 */ 5547 /***/ (function(module, exports) { 5548 5549 /*! https://mths.be/utf8js v2.1.2 by @mathias */ 5550 5551 var stringFromCharCode = String.fromCharCode; 5552 5553 // Taken from https://mths.be/punycode 5554 function ucs2decode(string) { 5555 var output = []; 5556 var counter = 0; 5557 var length = string.length; 5558 var value; 5559 var extra; 5560 while (counter < length) { 5561 value = string.charCodeAt(counter++); 5562 if (value >= 0xD800 && value <= 0xDBFF && counter < length) { 5563 // high surrogate, and there is a next character 5564 extra = string.charCodeAt(counter++); 5565 if ((extra & 0xFC00) == 0xDC00) { // low surrogate 5566 output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); 5567 } else { 5568 // unmatched surrogate; only append this code unit, in case the next 5569 // code unit is the high surrogate of a surrogate pair 5570 output.push(value); 5571 counter--; 5572 } 5573 } else { 5574 output.push(value); 5575 } 5576 } 5577 return output; 5578 } 5579 5580 // Taken from https://mths.be/punycode 5581 function ucs2encode(array) { 5582 var length = array.length; 5583 var index = -1; 5584 var value; 5585 var output = ''; 5586 while (++index < length) { 5587 value = array[index]; 5588 if (value > 0xFFFF) { 5589 value -= 0x10000; 5590 output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); 5591 value = 0xDC00 | value & 0x3FF; 5592 } 5593 output += stringFromCharCode(value); 5594 } 5595 return output; 5596 } 5597 5598 function checkScalarValue(codePoint, strict) { 5599 if (codePoint >= 0xD800 && codePoint <= 0xDFFF) { 5600 if (strict) { 5601 throw Error( 5602 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() + 5603 ' is not a scalar value' 5604 ); 5605 } 5606 return false; 5607 } 5608 return true; 5609 } 5610 /*--------------------------------------------------------------------------*/ 5611 5612 function createByte(codePoint, shift) { 5613 return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); 5614 } 5615 5616 function encodeCodePoint(codePoint, strict) { 5617 if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence 5618 return stringFromCharCode(codePoint); 5619 } 5620 var symbol = ''; 5621 if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence 5622 symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); 5623 } 5624 else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence 5625 if (!checkScalarValue(codePoint, strict)) { 5626 codePoint = 0xFFFD; 5627 } 5628 symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); 5629 symbol += createByte(codePoint, 6); 5630 } 5631 else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence 5632 symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); 5633 symbol += createByte(codePoint, 12); 5634 symbol += createByte(codePoint, 6); 5635 } 5636 symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); 5637 return symbol; 5638 } 5639 5640 function utf8encode(string, opts) { 5641 opts = opts || {}; 5642 var strict = false !== opts.strict; 5643 5644 var codePoints = ucs2decode(string); 5645 var length = codePoints.length; 5646 var index = -1; 5647 var codePoint; 5648 var byteString = ''; 5649 while (++index < length) { 5650 codePoint = codePoints[index]; 5651 byteString += encodeCodePoint(codePoint, strict); 5652 } 5653 return byteString; 5654 } 5655 5656 /*--------------------------------------------------------------------------*/ 5657 5658 function readContinuationByte() { 5659 if (byteIndex >= byteCount) { 5660 throw Error('Invalid byte index'); 5661 } 5662 5663 var continuationByte = byteArray[byteIndex] & 0xFF; 5664 byteIndex++; 5665 5666 if ((continuationByte & 0xC0) == 0x80) { 5667 return continuationByte & 0x3F; 5668 } 5669 5670 // If we end up here, it’s not a continuation byte 5671 throw Error('Invalid continuation byte'); 5672 } 5673 5674 function decodeSymbol(strict) { 5675 var byte1; 5676 var byte2; 5677 var byte3; 5678 var byte4; 5679 var codePoint; 5680 5681 if (byteIndex > byteCount) { 5682 throw Error('Invalid byte index'); 5683 } 5684 5685 if (byteIndex == byteCount) { 5686 return false; 5687 } 5688 5689 // Read first byte 5690 byte1 = byteArray[byteIndex] & 0xFF; 5691 byteIndex++; 5692 5693 // 1-byte sequence (no continuation bytes) 5694 if ((byte1 & 0x80) == 0) { 5695 return byte1; 5696 } 5697 5698 // 2-byte sequence 5699 if ((byte1 & 0xE0) == 0xC0) { 5700 byte2 = readContinuationByte(); 5701 codePoint = ((byte1 & 0x1F) << 6) | byte2; 5702 if (codePoint >= 0x80) { 5703 return codePoint; 5704 } else { 5705 throw Error('Invalid continuation byte'); 5706 } 5707 } 5708 5709 // 3-byte sequence (may include unpaired surrogates) 5710 if ((byte1 & 0xF0) == 0xE0) { 5711 byte2 = readContinuationByte(); 5712 byte3 = readContinuationByte(); 5713 codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; 5714 if (codePoint >= 0x0800) { 5715 return checkScalarValue(codePoint, strict) ? codePoint : 0xFFFD; 5716 } else { 5717 throw Error('Invalid continuation byte'); 5718 } 5719 } 5720 5721 // 4-byte sequence 5722 if ((byte1 & 0xF8) == 0xF0) { 5723 byte2 = readContinuationByte(); 5724 byte3 = readContinuationByte(); 5725 byte4 = readContinuationByte(); 5726 codePoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0C) | 5727 (byte3 << 0x06) | byte4; 5728 if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { 5729 return codePoint; 5730 } 5731 } 5732 5733 throw Error('Invalid UTF-8 detected'); 5734 } 5735 5736 var byteArray; 5737 var byteCount; 5738 var byteIndex; 5739 function utf8decode(byteString, opts) { 5740 opts = opts || {}; 5741 var strict = false !== opts.strict; 5742 5743 byteArray = ucs2decode(byteString); 5744 byteCount = byteArray.length; 5745 byteIndex = 0; 5746 var codePoints = []; 5747 var tmp; 5748 while ((tmp = decodeSymbol(strict)) !== false) { 5749 codePoints.push(tmp); 5750 } 5751 return ucs2encode(codePoints); 5752 } 5753 5754 module.exports = { 5755 version: '2.1.2', 5756 encode: utf8encode, 5757 decode: utf8decode 5758 }; 5759 5760 5761 /***/ }), 5762 /* 30 */ 5763 /***/ (function(module, exports) { 5764 5765 /* 5766 * base64-arraybuffer 5767 * https://github.com/niklasvh/base64-arraybuffer 5768 * 5769 * Copyright (c) 2012 Niklas von Hertzen 5770 * Licensed under the MIT license. 5771 */ 5772 (function(){ 5773 "use strict"; 5774 5775 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 5776 5777 // Use a lookup table to find the index. 5778 var lookup = new Uint8Array(256); 5779 for (var i = 0; i < chars.length; i++) { 5780 lookup[chars.charCodeAt(i)] = i; 5781 } 5782 5783 exports.encode = function(arraybuffer) { 5784 var bytes = new Uint8Array(arraybuffer), 5785 i, len = bytes.length, base64 = ""; 5786 5787 for (i = 0; i < len; i+=3) { 5788 base64 += chars[bytes[i] >> 2]; 5789 base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; 5790 base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; 5791 base64 += chars[bytes[i + 2] & 63]; 5792 } 5793 5794 if ((len % 3) === 2) { 5795 base64 = base64.substring(0, base64.length - 1) + "="; 5796 } else if (len % 3 === 1) { 5797 base64 = base64.substring(0, base64.length - 2) + "=="; 5798 } 5799 5800 return base64; 5801 }; 5802 5803 exports.decode = function(base64) { 5804 var bufferLength = base64.length * 0.75, 5805 len = base64.length, i, p = 0, 5806 encoded1, encoded2, encoded3, encoded4; 5807 5808 if (base64[base64.length - 1] === "=") { 5809 bufferLength--; 5810 if (base64[base64.length - 2] === "=") { 5811 bufferLength--; 5812 } 5813 } 5814 5815 var arraybuffer = new ArrayBuffer(bufferLength), 5816 bytes = new Uint8Array(arraybuffer); 5817 5818 for (i = 0; i < len; i+=4) { 5819 encoded1 = lookup[base64.charCodeAt(i)]; 5820 encoded2 = lookup[base64.charCodeAt(i+1)]; 5821 encoded3 = lookup[base64.charCodeAt(i+2)]; 5822 encoded4 = lookup[base64.charCodeAt(i+3)]; 5823 5824 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); 5825 bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); 5826 bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); 5827 } 5828 5829 return arraybuffer; 5830 }; 5831 })(); 5832 5833 5834 /***/ }), 5835 /* 31 */ 5836 /***/ (function(module, exports) { 5837 5838 /** 5839 * Create a blob builder even when vendor prefixes exist 5840 */ 5841 5842 var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : 5843 typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder : 5844 typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : 5845 typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : 5846 false; 5847 5848 /** 5849 * Check if Blob constructor is supported 5850 */ 5851 5852 var blobSupported = (function() { 5853 try { 5854 var a = new Blob(['hi']); 5855 return a.size === 2; 5856 } catch(e) { 5857 return false; 5858 } 5859 })(); 5860 5861 /** 5862 * Check if Blob constructor supports ArrayBufferViews 5863 * Fails in Safari 6, so we need to map to ArrayBuffers there. 5864 */ 5865 5866 var blobSupportsArrayBufferView = blobSupported && (function() { 5867 try { 5868 var b = new Blob([new Uint8Array([1,2])]); 5869 return b.size === 2; 5870 } catch(e) { 5871 return false; 5872 } 5873 })(); 5874 5875 /** 5876 * Check if BlobBuilder is supported 5877 */ 5878 5879 var blobBuilderSupported = BlobBuilder 5880 && BlobBuilder.prototype.append 5881 && BlobBuilder.prototype.getBlob; 5882 5883 /** 5884 * Helper function that maps ArrayBufferViews to ArrayBuffers 5885 * Used by BlobBuilder constructor and old browsers that didn't 5886 * support it in the Blob constructor. 5887 */ 5888 5889 function mapArrayBufferViews(ary) { 5890 return ary.map(function(chunk) { 5891 if (chunk.buffer instanceof ArrayBuffer) { 5892 var buf = chunk.buffer; 5893 5894 // if this is a subarray, make a copy so we only 5895 // include the subarray region from the underlying buffer 5896 if (chunk.byteLength !== buf.byteLength) { 5897 var copy = new Uint8Array(chunk.byteLength); 5898 copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); 5899 buf = copy.buffer; 5900 } 5901 5902 return buf; 5903 } 5904 5905 return chunk; 5906 }); 5907 } 5908 5909 function BlobBuilderConstructor(ary, options) { 5910 options = options || {}; 5911 5912 var bb = new BlobBuilder(); 5913 mapArrayBufferViews(ary).forEach(function(part) { 5914 bb.append(part); 5915 }); 5916 5917 return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); 5918 }; 5919 5920 function BlobConstructor(ary, options) { 5921 return new Blob(mapArrayBufferViews(ary), options || {}); 5922 }; 5923 5924 if (typeof Blob !== 'undefined') { 5925 BlobBuilderConstructor.prototype = Blob.prototype; 5926 BlobConstructor.prototype = Blob.prototype; 5927 } 5928 5929 module.exports = (function() { 5930 if (blobSupported) { 5931 return blobSupportsArrayBufferView ? Blob : BlobConstructor; 5932 } else if (blobBuilderSupported) { 5933 return BlobBuilderConstructor; 5934 } else { 5935 return undefined; 5936 } 5937 })(); 5938 5939 5940 /***/ }), 5941 /* 32 */ 5942 /***/ (function(module, exports) { 5943 5944 /** 5945 * Compiles a querystring 5946 * Returns string representation of the object 5947 * 5948 * @param {Object} 5949 * @api private 5950 */ 5951 5952 exports.encode = function (obj) { 5953 var str = ''; 5954 5955 for (var i in obj) { 5956 if (obj.hasOwnProperty(i)) { 5957 if (str.length) str += '&'; 5958 str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); 5959 } 5960 } 5961 5962 return str; 5963 }; 5964 5965 /** 5966 * Parses a simple querystring into an object 5967 * 5968 * @param {String} qs 5969 * @api private 5970 */ 5971 5972 exports.decode = function(qs){ 5973 var qry = {}; 5974 var pairs = qs.split('&'); 5975 for (var i = 0, l = pairs.length; i < l; i++) { 5976 var pair = pairs[i].split('='); 5977 qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); 5978 } 5979 return qry; 5980 }; 5981 5982 5983 /***/ }), 5984 /* 33 */ 5985 /***/ (function(module, exports) { 5986 5987 5988 module.exports = function(a, b){ 5989 var fn = function(){}; 5990 fn.prototype = b.prototype; 5991 a.prototype = new fn; 5992 a.prototype.constructor = a; 5993 }; 5994 5995 /***/ }), 5996 /* 34 */ 5997 /***/ (function(module, exports) { 5998 5999 'use strict'; 6000 6001 var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('') 6002 , length = 64 6003 , map = {} 6004 , seed = 0 6005 , i = 0 6006 , prev; 6007 6008 /** 6009 * Return a string representing the specified number. 6010 * 6011 * @param {Number} num The number to convert. 6012 * @returns {String} The string representation of the number. 6013 * @api public 6014 */ 6015 function encode(num) { 6016 var encoded = ''; 6017 6018 do { 6019 encoded = alphabet[num % length] + encoded; 6020 num = Math.floor(num / length); 6021 } while (num > 0); 6022 6023 return encoded; 6024 } 6025 6026 /** 6027 * Return the integer value specified by the given string. 6028 * 6029 * @param {String} str The string to convert. 6030 * @returns {Number} The integer value represented by the string. 6031 * @api public 6032 */ 6033 function decode(str) { 6034 var decoded = 0; 6035 6036 for (i = 0; i < str.length; i++) { 6037 decoded = decoded * length + map[str.charAt(i)]; 6038 } 6039 6040 return decoded; 6041 } 6042 6043 /** 6044 * Yeast: A tiny growing id generator. 6045 * 6046 * @returns {String} A unique id. 6047 * @api public 6048 */ 6049 function yeast() { 6050 var now = encode(+new Date()); 6051 6052 if (now !== prev) return seed = 0, prev = now; 6053 return now +'.'+ encode(seed++); 6054 } 6055 6056 // 6057 // Map each character to its index. 6058 // 6059 for (; i < length; i++) map[alphabet[i]] = i; 6060 6061 // 6062 // Expose the `yeast`, `encode` and `decode` functions. 6063 // 6064 yeast.encode = encode; 6065 yeast.decode = decode; 6066 module.exports = yeast; 6067 6068 6069 /***/ }), 6070 /* 35 */ 6071 /***/ (function(module, exports, __webpack_require__) { 6072 6073 /* WEBPACK VAR INJECTION */(function(global) {/** 6074 * Module requirements. 6075 */ 6076 6077 var Polling = __webpack_require__(22); 6078 var inherit = __webpack_require__(33); 6079 6080 /** 6081 * Module exports. 6082 */ 6083 6084 module.exports = JSONPPolling; 6085 6086 /** 6087 * Cached regular expressions. 6088 */ 6089 6090 var rNewline = /\n/g; 6091 var rEscapedNewline = /\\n/g; 6092 6093 /** 6094 * Global JSONP callbacks. 6095 */ 6096 6097 var callbacks; 6098 6099 /** 6100 * Noop. 6101 */ 6102 6103 function empty () { } 6104 6105 /** 6106 * Until https://github.com/tc39/proposal-global is shipped. 6107 */ 6108 function glob () { 6109 return typeof self !== 'undefined' ? self 6110 : typeof window !== 'undefined' ? window 6111 : typeof global !== 'undefined' ? global : {}; 6112 } 6113 6114 /** 6115 * JSONP Polling constructor. 6116 * 6117 * @param {Object} opts. 6118 * @api public 6119 */ 6120 6121 function JSONPPolling (opts) { 6122 Polling.call(this, opts); 6123 6124 this.query = this.query || {}; 6125 6126 // define global callbacks array if not present 6127 // we do this here (lazily) to avoid unneeded global pollution 6128 if (!callbacks) { 6129 // we need to consider multiple engines in the same page 6130 var global = glob(); 6131 callbacks = global.___eio = (global.___eio || []); 6132 } 6133 6134 // callback identifier 6135 this.index = callbacks.length; 6136 6137 // add callback to jsonp global 6138 var self = this; 6139 callbacks.push(function (msg) { 6140 self.onData(msg); 6141 }); 6142 6143 // append to query string 6144 this.query.j = this.index; 6145 6146 // prevent spurious errors from being emitted when the window is unloaded 6147 if (typeof addEventListener === 'function') { 6148 addEventListener('beforeunload', function () { 6149 if (self.script) self.script.onerror = empty; 6150 }, false); 6151 } 6152 } 6153 6154 /** 6155 * Inherits from Polling. 6156 */ 6157 6158 inherit(JSONPPolling, Polling); 6159 6160 /* 6161 * JSONP only supports binary as base64 encoded strings 6162 */ 6163 6164 JSONPPolling.prototype.supportsBinary = false; 6165 6166 /** 6167 * Closes the socket. 6168 * 6169 * @api private 6170 */ 6171 6172 JSONPPolling.prototype.doClose = function () { 6173 if (this.script) { 6174 this.script.parentNode.removeChild(this.script); 6175 this.script = null; 6176 } 6177 6178 if (this.form) { 6179 this.form.parentNode.removeChild(this.form); 6180 this.form = null; 6181 this.iframe = null; 6182 } 6183 6184 Polling.prototype.doClose.call(this); 6185 }; 6186 6187 /** 6188 * Starts a poll cycle. 6189 * 6190 * @api private 6191 */ 6192 6193 JSONPPolling.prototype.doPoll = function () { 6194 var self = this; 6195 var script = document.createElement('script'); 6196 6197 if (this.script) { 6198 this.script.parentNode.removeChild(this.script); 6199 this.script = null; 6200 } 6201 6202 script.async = true; 6203 script.src = this.uri(); 6204 script.onerror = function (e) { 6205 self.onError('jsonp poll error', e); 6206 }; 6207 6208 var insertAt = document.getElementsByTagName('script')[0]; 6209 if (insertAt) { 6210 insertAt.parentNode.insertBefore(script, insertAt); 6211 } else { 6212 (document.head || document.body).appendChild(script); 6213 } 6214 this.script = script; 6215 6216 var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent); 6217 6218 if (isUAgecko) { 6219 setTimeout(function () { 6220 var iframe = document.createElement('iframe'); 6221 document.body.appendChild(iframe); 6222 document.body.removeChild(iframe); 6223 }, 100); 6224 } 6225 }; 6226 6227 /** 6228 * Writes with a hidden iframe. 6229 * 6230 * @param {String} data to send 6231 * @param {Function} called upon flush. 6232 * @api private 6233 */ 6234 6235 JSONPPolling.prototype.doWrite = function (data, fn) { 6236 var self = this; 6237 6238 if (!this.form) { 6239 var form = document.createElement('form'); 6240 var area = document.createElement('textarea'); 6241 var id = this.iframeId = 'eio_iframe_' + this.index; 6242 var iframe; 6243 6244 form.className = 'socketio'; 6245 form.style.position = 'absolute'; 6246 form.style.top = '-1000px'; 6247 form.style.left = '-1000px'; 6248 form.target = id; 6249 form.method = 'POST'; 6250 form.setAttribute('accept-charset', 'utf-8'); 6251 area.name = 'd'; 6252 form.appendChild(area); 6253 document.body.appendChild(form); 6254 6255 this.form = form; 6256 this.area = area; 6257 } 6258 6259 this.form.action = this.uri(); 6260 6261 function complete () { 6262 initIframe(); 6263 fn(); 6264 } 6265 6266 function initIframe () { 6267 if (self.iframe) { 6268 try { 6269 self.form.removeChild(self.iframe); 6270 } catch (e) { 6271 self.onError('jsonp polling iframe removal error', e); 6272 } 6273 } 6274 6275 try { 6276 // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) 6277 var html = '<iframe src="javascript:0" name="' + self.iframeId + '">'; 6278 iframe = document.createElement(html); 6279 } catch (e) { 6280 iframe = document.createElement('iframe'); 6281 iframe.name = self.iframeId; 6282 iframe.src = 'javascript:0'; 6283 } 6284 6285 iframe.id = self.iframeId; 6286 6287 self.form.appendChild(iframe); 6288 self.iframe = iframe; 6289 } 6290 6291 initIframe(); 6292 6293 // escape \n to prevent it from being converted into \r\n by some UAs 6294 // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side 6295 data = data.replace(rEscapedNewline, '\\\n'); 6296 this.area.value = data.replace(rNewline, '\\n'); 6297 6298 try { 6299 this.form.submit(); 6300 } catch (e) {} 6301 6302 if (this.iframe.attachEvent) { 6303 this.iframe.onreadystatechange = function () { 6304 if (self.iframe.readyState === 'complete') { 6305 complete(); 6306 } 6307 }; 6308 } else { 6309 this.iframe.onload = complete; 6310 } 6311 }; 6312 6313 /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 6314 6315 /***/ }), 6316 /* 36 */ 6317 /***/ (function(module, exports, __webpack_require__) { 6318 6319 /** 6320 * Module dependencies. 6321 */ 6322 6323 var Transport = __webpack_require__(23); 6324 var parser = __webpack_require__(24); 6325 var parseqs = __webpack_require__(32); 6326 var inherit = __webpack_require__(33); 6327 var yeast = __webpack_require__(34); 6328 var debug = __webpack_require__(3)('engine.io-client:websocket'); 6329 6330 var BrowserWebSocket, NodeWebSocket; 6331 6332 if (typeof WebSocket !== 'undefined') { 6333 BrowserWebSocket = WebSocket; 6334 } else if (typeof self !== 'undefined') { 6335 BrowserWebSocket = self.WebSocket || self.MozWebSocket; 6336 } 6337 6338 if (typeof window === 'undefined') { 6339 try { 6340 NodeWebSocket = __webpack_require__(37); 6341 } catch (e) { } 6342 } 6343 6344 /** 6345 * Get either the `WebSocket` or `MozWebSocket` globals 6346 * in the browser or try to resolve WebSocket-compatible 6347 * interface exposed by `ws` for Node-like environment. 6348 */ 6349 6350 var WebSocketImpl = BrowserWebSocket || NodeWebSocket; 6351 6352 /** 6353 * Module exports. 6354 */ 6355 6356 module.exports = WS; 6357 6358 /** 6359 * WebSocket transport constructor. 6360 * 6361 * @api {Object} connection options 6362 * @api public 6363 */ 6364 6365 function WS (opts) { 6366 var forceBase64 = (opts && opts.forceBase64); 6367 if (forceBase64) { 6368 this.supportsBinary = false; 6369 } 6370 this.perMessageDeflate = opts.perMessageDeflate; 6371 this.usingBrowserWebSocket = BrowserWebSocket && !opts.forceNode; 6372 this.protocols = opts.protocols; 6373 if (!this.usingBrowserWebSocket) { 6374 WebSocketImpl = NodeWebSocket; 6375 } 6376 Transport.call(this, opts); 6377 } 6378 6379 /** 6380 * Inherits from Transport. 6381 */ 6382 6383 inherit(WS, Transport); 6384 6385 /** 6386 * Transport name. 6387 * 6388 * @api public 6389 */ 6390 6391 WS.prototype.name = 'websocket'; 6392 6393 /* 6394 * WebSockets support binary 6395 */ 6396 6397 WS.prototype.supportsBinary = true; 6398 6399 /** 6400 * Opens socket. 6401 * 6402 * @api private 6403 */ 6404 6405 WS.prototype.doOpen = function () { 6406 if (!this.check()) { 6407 // let probe timeout 6408 return; 6409 } 6410 6411 var uri = this.uri(); 6412 var protocols = this.protocols; 6413 var opts = { 6414 agent: this.agent, 6415 perMessageDeflate: this.perMessageDeflate 6416 }; 6417 6418 // SSL options for Node.js client 6419 opts.pfx = this.pfx; 6420 opts.key = this.key; 6421 opts.passphrase = this.passphrase; 6422 opts.cert = this.cert; 6423 opts.ca = this.ca; 6424 opts.ciphers = this.ciphers; 6425 opts.rejectUnauthorized = this.rejectUnauthorized; 6426 if (this.extraHeaders) { 6427 opts.headers = this.extraHeaders; 6428 } 6429 if (this.localAddress) { 6430 opts.localAddress = this.localAddress; 6431 } 6432 6433 try { 6434 this.ws = 6435 this.usingBrowserWebSocket && !this.isReactNative 6436 ? protocols 6437 ? new WebSocketImpl(uri, protocols) 6438 : new WebSocketImpl(uri) 6439 : new WebSocketImpl(uri, protocols, opts); 6440 } catch (err) { 6441 return this.emit('error', err); 6442 } 6443 6444 if (this.ws.binaryType === undefined) { 6445 this.supportsBinary = false; 6446 } 6447 6448 if (this.ws.supports && this.ws.supports.binary) { 6449 this.supportsBinary = true; 6450 this.ws.binaryType = 'nodebuffer'; 6451 } else { 6452 this.ws.binaryType = 'arraybuffer'; 6453 } 6454 6455 this.addEventListeners(); 6456 }; 6457 6458 /** 6459 * Adds event listeners to the socket 6460 * 6461 * @api private 6462 */ 6463 6464 WS.prototype.addEventListeners = function () { 6465 var self = this; 6466 6467 this.ws.onopen = function () { 6468 self.onOpen(); 6469 }; 6470 this.ws.onclose = function () { 6471 self.onClose(); 6472 }; 6473 this.ws.onmessage = function (ev) { 6474 self.onData(ev.data); 6475 }; 6476 this.ws.onerror = function (e) { 6477 self.onError('websocket error', e); 6478 }; 6479 }; 6480 6481 /** 6482 * Writes data to socket. 6483 * 6484 * @param {Array} array of packets. 6485 * @api private 6486 */ 6487 6488 WS.prototype.write = function (packets) { 6489 var self = this; 6490 this.writable = false; 6491 6492 // encodePacket efficient as it uses WS framing 6493 // no need for encodePayload 6494 var total = packets.length; 6495 for (var i = 0, l = total; i < l; i++) { 6496 (function (packet) { 6497 parser.encodePacket(packet, self.supportsBinary, function (data) { 6498 if (!self.usingBrowserWebSocket) { 6499 // always create a new object (GH-437) 6500 var opts = {}; 6501 if (packet.options) { 6502 opts.compress = packet.options.compress; 6503 } 6504 6505 if (self.perMessageDeflate) { 6506 var len = 'string' === typeof data ? Buffer.byteLength(data) : data.length; 6507 if (len < self.perMessageDeflate.threshold) { 6508 opts.compress = false; 6509 } 6510 } 6511 } 6512 6513 // Sometimes the websocket has already been closed but the browser didn't 6514 // have a chance of informing us about it yet, in that case send will 6515 // throw an error 6516 try { 6517 if (self.usingBrowserWebSocket) { 6518 // TypeError is thrown when passing the second argument on Safari 6519 self.ws.send(data); 6520 } else { 6521 self.ws.send(data, opts); 6522 } 6523 } catch (e) { 6524 debug('websocket closed before onclose event'); 6525 } 6526 6527 --total || done(); 6528 }); 6529 })(packets[i]); 6530 } 6531 6532 function done () { 6533 self.emit('flush'); 6534 6535 // fake drain 6536 // defer to next tick to allow Socket to clear writeBuffer 6537 setTimeout(function () { 6538 self.writable = true; 6539 self.emit('drain'); 6540 }, 0); 6541 } 6542 }; 6543 6544 /** 6545 * Called upon close 6546 * 6547 * @api private 6548 */ 6549 6550 WS.prototype.onClose = function () { 6551 Transport.prototype.onClose.call(this); 6552 }; 6553 6554 /** 6555 * Closes socket. 6556 * 6557 * @api private 6558 */ 6559 6560 WS.prototype.doClose = function () { 6561 if (typeof this.ws !== 'undefined') { 6562 this.ws.close(); 6563 } 6564 }; 6565 6566 /** 6567 * Generates uri for connection. 6568 * 6569 * @api private 6570 */ 6571 6572 WS.prototype.uri = function () { 6573 var query = this.query || {}; 6574 var schema = this.secure ? 'wss' : 'ws'; 6575 var port = ''; 6576 6577 // avoid port if default for schema 6578 if (this.port && (('wss' === schema && Number(this.port) !== 443) || 6579 ('ws' === schema && Number(this.port) !== 80))) { 6580 port = ':' + this.port; 6581 } 6582 6583 // append timestamp to URI 6584 if (this.timestampRequests) { 6585 query[this.timestampParam] = yeast(); 6586 } 6587 6588 // communicate binary support capabilities 6589 if (!this.supportsBinary) { 6590 query.b64 = 1; 6591 } 6592 6593 query = parseqs.encode(query); 6594 6595 // prepend ? to query 6596 if (query.length) { 6597 query = '?' + query; 6598 } 6599 6600 var ipv6 = this.hostname.indexOf(':') !== -1; 6601 return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query; 6602 }; 6603 6604 /** 6605 * Feature detection for WebSocket. 6606 * 6607 * @return {Boolean} whether this transport is available. 6608 * @api public 6609 */ 6610 6611 WS.prototype.check = function () { 6612 return !!WebSocketImpl && !('__initialize' in WebSocketImpl && this.name === WS.prototype.name); 6613 }; 6614 6615 6616 /***/ }), 6617 /* 37 */ 6618 /***/ (function(module, exports) { 6619 6620 /* (ignored) */ 6621 6622 /***/ }), 6623 /* 38 */ 6624 /***/ (function(module, exports) { 6625 6626 6627 var indexOf = [].indexOf; 6628 6629 module.exports = function(arr, obj){ 6630 if (indexOf) return arr.indexOf(obj); 6631 for (var i = 0; i < arr.length; ++i) { 6632 if (arr[i] === obj) return i; 6633 } 6634 return -1; 6635 }; 6636 6637 /***/ }), 6638 /* 39 */ 6639 /***/ (function(module, exports, __webpack_require__) { 6640 6641 6642 /** 6643 * Module dependencies. 6644 */ 6645 6646 var parser = __webpack_require__(7); 6647 var Emitter = __webpack_require__(11); 6648 var toArray = __webpack_require__(40); 6649 var on = __webpack_require__(41); 6650 var bind = __webpack_require__(42); 6651 var debug = __webpack_require__(3)('socket.io-client:socket'); 6652 var parseqs = __webpack_require__(32); 6653 var hasBin = __webpack_require__(26); 6654 6655 /** 6656 * Module exports. 6657 */ 6658 6659 module.exports = exports = Socket; 6660 6661 /** 6662 * Internal events (blacklisted). 6663 * These events can't be emitted by the user. 6664 * 6665 * @api private 6666 */ 6667 6668 var events = { 6669 connect: 1, 6670 connect_error: 1, 6671 connect_timeout: 1, 6672 connecting: 1, 6673 disconnect: 1, 6674 error: 1, 6675 reconnect: 1, 6676 reconnect_attempt: 1, 6677 reconnect_failed: 1, 6678 reconnect_error: 1, 6679 reconnecting: 1, 6680 ping: 1, 6681 pong: 1 6682 }; 6683 6684 /** 6685 * Shortcut to `Emitter#emit`. 6686 */ 6687 6688 var emit = Emitter.prototype.emit; 6689 6690 /** 6691 * `Socket` constructor. 6692 * 6693 * @api public 6694 */ 6695 6696 function Socket (io, nsp, opts) { 6697 this.io = io; 6698 this.nsp = nsp; 6699 this.json = this; // compat 6700 this.ids = 0; 6701 this.acks = {}; 6702 this.receiveBuffer = []; 6703 this.sendBuffer = []; 6704 this.connected = false; 6705 this.disconnected = true; 6706 this.flags = {}; 6707 if (opts && opts.query) { 6708 this.query = opts.query; 6709 } 6710 if (this.io.autoConnect) this.open(); 6711 } 6712 6713 /** 6714 * Mix in `Emitter`. 6715 */ 6716 6717 Emitter(Socket.prototype); 6718 6719 /** 6720 * Subscribe to open, close and packet events 6721 * 6722 * @api private 6723 */ 6724 6725 Socket.prototype.subEvents = function () { 6726 if (this.subs) return; 6727 6728 var io = this.io; 6729 this.subs = [ 6730 on(io, 'open', bind(this, 'onopen')), 6731 on(io, 'packet', bind(this, 'onpacket')), 6732 on(io, 'close', bind(this, 'onclose')) 6733 ]; 6734 }; 6735 6736 /** 6737 * "Opens" the socket. 6738 * 6739 * @api public 6740 */ 6741 6742 Socket.prototype.open = 6743 Socket.prototype.connect = function () { 6744 if (this.connected) return this; 6745 6746 this.subEvents(); 6747 this.io.open(); // ensure open 6748 if ('open' === this.io.readyState) this.onopen(); 6749 this.emit('connecting'); 6750 return this; 6751 }; 6752 6753 /** 6754 * Sends a `message` event. 6755 * 6756 * @return {Socket} self 6757 * @api public 6758 */ 6759 6760 Socket.prototype.send = function () { 6761 var args = toArray(arguments); 6762 args.unshift('message'); 6763 this.emit.apply(this, args); 6764 return this; 6765 }; 6766 6767 /** 6768 * Override `emit`. 6769 * If the event is in `events`, it's emitted normally. 6770 * 6771 * @param {String} event name 6772 * @return {Socket} self 6773 * @api public 6774 */ 6775 6776 Socket.prototype.emit = function (ev) { 6777 if (events.hasOwnProperty(ev)) { 6778 emit.apply(this, arguments); 6779 return this; 6780 } 6781 6782 var args = toArray(arguments); 6783 var packet = { 6784 type: (this.flags.binary !== undefined ? this.flags.binary : hasBin(args)) ? parser.BINARY_EVENT : parser.EVENT, 6785 data: args 6786 }; 6787 6788 packet.options = {}; 6789 packet.options.compress = !this.flags || false !== this.flags.compress; 6790 6791 // event ack callback 6792 if ('function' === typeof args[args.length - 1]) { 6793 debug('emitting packet with ack id %d', this.ids); 6794 this.acks[this.ids] = args.pop(); 6795 packet.id = this.ids++; 6796 } 6797 6798 if (this.connected) { 6799 this.packet(packet); 6800 } else { 6801 this.sendBuffer.push(packet); 6802 } 6803 6804 this.flags = {}; 6805 6806 return this; 6807 }; 6808 6809 /** 6810 * Sends a packet. 6811 * 6812 * @param {Object} packet 6813 * @api private 6814 */ 6815 6816 Socket.prototype.packet = function (packet) { 6817 packet.nsp = this.nsp; 6818 this.io.packet(packet); 6819 }; 6820 6821 /** 6822 * Called upon engine `open`. 6823 * 6824 * @api private 6825 */ 6826 6827 Socket.prototype.onopen = function () { 6828 debug('transport is open - connecting'); 6829 6830 // write connect packet if necessary 6831 if ('/' !== this.nsp) { 6832 if (this.query) { 6833 var query = typeof this.query === 'object' ? parseqs.encode(this.query) : this.query; 6834 debug('sending connect packet with query %s', query); 6835 this.packet({type: parser.CONNECT, query: query}); 6836 } else { 6837 this.packet({type: parser.CONNECT}); 6838 } 6839 } 6840 }; 6841 6842 /** 6843 * Called upon engine `close`. 6844 * 6845 * @param {String} reason 6846 * @api private 6847 */ 6848 6849 Socket.prototype.onclose = function (reason) { 6850 debug('close (%s)', reason); 6851 this.connected = false; 6852 this.disconnected = true; 6853 delete this.id; 6854 this.emit('disconnect', reason); 6855 }; 6856 6857 /** 6858 * Called with socket packet. 6859 * 6860 * @param {Object} packet 6861 * @api private 6862 */ 6863 6864 Socket.prototype.onpacket = function (packet) { 6865 var sameNamespace = packet.nsp === this.nsp; 6866 var rootNamespaceError = packet.type === parser.ERROR && packet.nsp === '/'; 6867 6868 if (!sameNamespace && !rootNamespaceError) return; 6869 6870 switch (packet.type) { 6871 case parser.CONNECT: 6872 this.onconnect(); 6873 break; 6874 6875 case parser.EVENT: 6876 this.onevent(packet); 6877 break; 6878 6879 case parser.BINARY_EVENT: 6880 this.onevent(packet); 6881 break; 6882 6883 case parser.ACK: 6884 this.onack(packet); 6885 break; 6886 6887 case parser.BINARY_ACK: 6888 this.onack(packet); 6889 break; 6890 6891 case parser.DISCONNECT: 6892 this.ondisconnect(); 6893 break; 6894 6895 case parser.ERROR: 6896 this.emit('error', packet.data); 6897 break; 6898 } 6899 }; 6900 6901 /** 6902 * Called upon a server event. 6903 * 6904 * @param {Object} packet 6905 * @api private 6906 */ 6907 6908 Socket.prototype.onevent = function (packet) { 6909 var args = packet.data || []; 6910 debug('emitting event %j', args); 6911 6912 if (null != packet.id) { 6913 debug('attaching ack callback to event'); 6914 args.push(this.ack(packet.id)); 6915 } 6916 6917 if (this.connected) { 6918 emit.apply(this, args); 6919 } else { 6920 this.receiveBuffer.push(args); 6921 } 6922 }; 6923 6924 /** 6925 * Produces an ack callback to emit with an event. 6926 * 6927 * @api private 6928 */ 6929 6930 Socket.prototype.ack = function (id) { 6931 var self = this; 6932 var sent = false; 6933 return function () { 6934 // prevent double callbacks 6935 if (sent) return; 6936 sent = true; 6937 var args = toArray(arguments); 6938 debug('sending ack %j', args); 6939 6940 self.packet({ 6941 type: hasBin(args) ? parser.BINARY_ACK : parser.ACK, 6942 id: id, 6943 data: args 6944 }); 6945 }; 6946 }; 6947 6948 /** 6949 * Called upon a server acknowlegement. 6950 * 6951 * @param {Object} packet 6952 * @api private 6953 */ 6954 6955 Socket.prototype.onack = function (packet) { 6956 var ack = this.acks[packet.id]; 6957 if ('function' === typeof ack) { 6958 debug('calling ack %s with %j', packet.id, packet.data); 6959 ack.apply(this, packet.data); 6960 delete this.acks[packet.id]; 6961 } else { 6962 debug('bad ack %s', packet.id); 6963 } 6964 }; 6965 6966 /** 6967 * Called upon server connect. 6968 * 6969 * @api private 6970 */ 6971 6972 Socket.prototype.onconnect = function () { 6973 this.connected = true; 6974 this.disconnected = false; 6975 this.emit('connect'); 6976 this.emitBuffered(); 6977 }; 6978 6979 /** 6980 * Emit buffered events (received and emitted). 6981 * 6982 * @api private 6983 */ 6984 6985 Socket.prototype.emitBuffered = function () { 6986 var i; 6987 for (i = 0; i < this.receiveBuffer.length; i++) { 6988 emit.apply(this, this.receiveBuffer[i]); 6989 } 6990 this.receiveBuffer = []; 6991 6992 for (i = 0; i < this.sendBuffer.length; i++) { 6993 this.packet(this.sendBuffer[i]); 6994 } 6995 this.sendBuffer = []; 6996 }; 6997 6998 /** 6999 * Called upon server disconnect. 7000 * 7001 * @api private 7002 */ 7003 7004 Socket.prototype.ondisconnect = function () { 7005 debug('server disconnect (%s)', this.nsp); 7006 this.destroy(); 7007 this.onclose('io server disconnect'); 7008 }; 7009 7010 /** 7011 * Called upon forced client/server side disconnections, 7012 * this method ensures the manager stops tracking us and 7013 * that reconnections don't get triggered for this. 7014 * 7015 * @api private. 7016 */ 7017 7018 Socket.prototype.destroy = function () { 7019 if (this.subs) { 7020 // clean subscriptions to avoid reconnections 7021 for (var i = 0; i < this.subs.length; i++) { 7022 this.subs[i].destroy(); 7023 } 7024 this.subs = null; 7025 } 7026 7027 this.io.destroy(this); 7028 }; 7029 7030 /** 7031 * Disconnects the socket manually. 7032 * 7033 * @return {Socket} self 7034 * @api public 7035 */ 7036 7037 Socket.prototype.close = 7038 Socket.prototype.disconnect = function () { 7039 if (this.connected) { 7040 debug('performing disconnect (%s)', this.nsp); 7041 this.packet({ type: parser.DISCONNECT }); 7042 } 7043 7044 // remove socket from pool 7045 this.destroy(); 7046 7047 if (this.connected) { 7048 // fire events 7049 this.onclose('io client disconnect'); 7050 } 7051 return this; 7052 }; 7053 7054 /** 7055 * Sets the compress flag. 7056 * 7057 * @param {Boolean} if `true`, compresses the sending data 7058 * @return {Socket} self 7059 * @api public 7060 */ 7061 7062 Socket.prototype.compress = function (compress) { 7063 this.flags.compress = compress; 7064 return this; 7065 }; 7066 7067 /** 7068 * Sets the binary flag 7069 * 7070 * @param {Boolean} whether the emitted data contains binary 7071 * @return {Socket} self 7072 * @api public 7073 */ 7074 7075 Socket.prototype.binary = function (binary) { 7076 this.flags.binary = binary; 7077 return this; 7078 }; 7079 7080 7081 /***/ }), 7082 /* 40 */ 7083 /***/ (function(module, exports) { 7084 7085 module.exports = toArray 7086 7087 function toArray(list, index) { 7088 var array = [] 7089 7090 index = index || 0 7091 7092 for (var i = index || 0; i < list.length; i++) { 7093 array[i - index] = list[i] 7094 } 7095 7096 return array 7097 } 7098 7099 7100 /***/ }), 7101 /* 41 */ 7102 /***/ (function(module, exports) { 7103 7104 7105 /** 7106 * Module exports. 7107 */ 7108 7109 module.exports = on; 7110 7111 /** 7112 * Helper for subscriptions. 7113 * 7114 * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter` 7115 * @param {String} event name 7116 * @param {Function} callback 7117 * @api public 7118 */ 7119 7120 function on (obj, ev, fn) { 7121 obj.on(ev, fn); 7122 return { 7123 destroy: function () { 7124 obj.removeListener(ev, fn); 7125 } 7126 }; 7127 } 7128 7129 7130 /***/ }), 7131 /* 42 */ 7132 /***/ (function(module, exports) { 7133 7134 /** 7135 * Slice reference. 7136 */ 7137 7138 var slice = [].slice; 7139 7140 /** 7141 * Bind `obj` to `fn`. 7142 * 7143 * @param {Object} obj 7144 * @param {Function|String} fn or string 7145 * @return {Function} 7146 * @api public 7147 */ 7148 7149 module.exports = function(obj, fn){ 7150 if ('string' == typeof fn) fn = obj[fn]; 7151 if ('function' != typeof fn) throw new Error('bind() requires a function'); 7152 var args = slice.call(arguments, 2); 7153 return function(){ 7154 return fn.apply(obj, args.concat(slice.call(arguments))); 7155 } 7156 }; 7157 7158 7159 /***/ }), 7160 /* 43 */ 7161 /***/ (function(module, exports) { 7162 7163 7164 /** 7165 * Expose `Backoff`. 7166 */ 7167 7168 module.exports = Backoff; 7169 7170 /** 7171 * Initialize backoff timer with `opts`. 7172 * 7173 * - `min` initial timeout in milliseconds [100] 7174 * - `max` max timeout [10000] 7175 * - `jitter` [0] 7176 * - `factor` [2] 7177 * 7178 * @param {Object} opts 7179 * @api public 7180 */ 7181 7182 function Backoff(opts) { 7183 opts = opts || {}; 7184 this.ms = opts.min || 100; 7185 this.max = opts.max || 10000; 7186 this.factor = opts.factor || 2; 7187 this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; 7188 this.attempts = 0; 7189 } 7190 7191 /** 7192 * Return the backoff duration. 7193 * 7194 * @return {Number} 7195 * @api public 7196 */ 7197 7198 Backoff.prototype.duration = function(){ 7199 var ms = this.ms * Math.pow(this.factor, this.attempts++); 7200 if (this.jitter) { 7201 var rand = Math.random(); 7202 var deviation = Math.floor(rand * this.jitter * ms); 7203 ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; 7204 } 7205 return Math.min(ms, this.max) | 0; 7206 }; 7207 7208 /** 7209 * Reset the number of attempts. 7210 * 7211 * @api public 7212 */ 7213 7214 Backoff.prototype.reset = function(){ 7215 this.attempts = 0; 7216 }; 7217 7218 /** 7219 * Set the minimum duration 7220 * 7221 * @api public 7222 */ 7223 7224 Backoff.prototype.setMin = function(min){ 7225 this.ms = min; 7226 }; 7227 7228 /** 7229 * Set the maximum duration 7230 * 7231 * @api public 7232 */ 7233 7234 Backoff.prototype.setMax = function(max){ 7235 this.max = max; 7236 }; 7237 7238 /** 7239 * Set the jitter 7240 * 7241 * @api public 7242 */ 7243 7244 Backoff.prototype.setJitter = function(jitter){ 7245 this.jitter = jitter; 7246 }; 7247 7248 7249 7250 /***/ }) 7251 /******/ ]) 7252 }); 7253 ; 7254 //# sourceMappingURL=socket.io.dev.js.map