diff --git a/static/uadmin/assets/socket.io-client/package.json b/static/uadmin/assets/socket.io-client/package.json index e54be9a..08d5ccf 100644 --- a/static/uadmin/assets/socket.io-client/package.json +++ b/static/uadmin/assets/socket.io-client/package.json @@ -1,116 +1,28 @@ { - "_args": [ - [ - "socket.io-client@1.3.7", - "C:\\nodejs\\node_modules\\socket.io" - ] - ], - "_from": "socket.io-client@1.3.7", - "_id": "socket.io-client@1.3.7", - "_inCache": true, - "_installable": true, - "_location": "/socket.io-client", - "_nodeVersion": "4.0.0", - "_npmUser": { - "email": "rauchg@gmail.com", - "name": "rauchg" - }, - "_npmVersion": "2.14.2", - "_phantomChildren": {}, - "_requested": { - "name": "socket.io-client", - "raw": "socket.io-client@1.3.7", - "rawSpec": "1.3.7", - "scope": null, - "spec": "1.3.7", - "type": "version" + "name": "socket.io-client", + "version": "4.8.3", + "description": "Realtime application framework client", + "license": "MIT", + "homepage": "https://github.com/socketio/socket.io/tree/main/packages/socket.io-client#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/socketio/socket.io.git" }, - "_requiredBy": [ - "/socket.io" - ], - "_resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.3.7.tgz", - "_shasum": "7ab7c069b8d50425eb265f031f84a97e6ebe719c", - "_shrinkwrap": null, - "_spec": "socket.io-client@1.3.7", - "_where": "C:\\nodejs\\node_modules\\socket.io", "bugs": { - "url": "https://github.com/Automattic/socket.io-client/issues" - }, - "contributors": [ - { - "name": "Guillermo Rauch", - "email": "rauchg@gmail.com" - }, - { - "name": "Arnout Kazemier", - "email": "info@3rd-eden.com" - }, - { - "name": "Vladimir Dronnikov", - "email": "dronnikov@gmail.com" - }, - { - "name": "Einar Otto Stangvik", - "email": "einaros@gmail.com" - } - ], - "dependencies": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.1.2", - "debug": "0.7.4", - "engine.io-client": "3.5.3", - "has-binary": "0.1.6", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.2", - "socket.io-parser": "4.2.1", - "to-array": "0.1.3" - }, - "description": "[![Build Status](https://secure.travis-ci.org/Automattic/socket.io-client.svg)](http://travis-ci.org/Automattic/socket.io-client) ![NPM version](https://badge.fury.io/js/socket.io-client.svg) ![Downloads](http://img.shields.io/npm/dm/socket.io-client.svg?", - "devDependencies": { - "base64-arraybuffer": "0.1.0", - "browserify": "4.2.1", - "expect.js": "0.2.0", - "has-cors": "1.0.3", - "istanbul": "0.2.1", - "mocha": "1.16.2", - "socket.io": "1.3.7", - "text-blob-builder": "0.0.1", - "uglify-js": "2.4.15", - "zuul": "github:rase-/zuul#9d3a02" - }, - "directories": {}, - "dist": { - "shasum": "7ab7c069b8d50425eb265f031f84a97e6ebe719c", - "tarball": "http://registry.npmjs.org/socket.io-client/-/socket.io-client-1.3.7.tgz" + "url": "https://github.com/socketio/socket.io/issues" }, - "gitHead": "3fe5c2a26c82f195c0872a4cffabb421f0d73748", - "homepage": "https://github.com/Automattic/socket.io-client#readme", "keywords": [ - "client", - "events", - "framework", "realtime", + "framework", + "websocket", "tcp", - "websocket" - ], - "license": "MIT", - "maintainers": [ - { - "name": "rauchg", - "email": "rauchg@gmail.com" - } + "events", + "client" ], - "name": "socket.io-client", - "optionalDependencies": {}, - "readme": "ERROR: No README data found!", - "repository": { - "type": "git", - "url": "git+https://github.com/Automattic/socket.io-client.git" - }, - "scripts": { - "test": "make test" - }, - "version": "1.3.7" + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + } } diff --git a/static/uadmin/assets/socket.io-client/socket.io.js b/static/uadmin/assets/socket.io-client/socket.io.js index 4f39e08..d26487c 100644 --- a/static/uadmin/assets/socket.io-client/socket.io.js +++ b/static/uadmin/assets/socket.io-client/socket.io.js @@ -1,6988 +1,4955 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o r.length) && (a = r.length); + for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; + return n; + } + function _arrayWithoutHoles(r) { + if (Array.isArray(r)) return _arrayLikeToArray(r); + } + function _construct(t, e, r) { + if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); + var o = [null]; + o.push.apply(o, e); + var p = new (t.bind.apply(t, o))(); + return r && _setPrototypeOf(p, r.prototype), p; + } + function _defineProperties(e, r) { + for (var t = 0; t < r.length; t++) { + var o = r[t]; + o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); + } } - - opts = opts || {}; - - var parsed = url(uri); - var source = parsed.source; - var id = parsed.id; - var io; - - if (opts.forceNew || opts['force new connection'] || false === opts.multiplex) { - debug('ignoring socket cache for %s', source); - io = Manager(source, opts); - } else { - if (!cache[id]) { - debug('new io instance for %s', source); - cache[id] = Manager(source, opts); - } - io = cache[id]; + function _createClass(e, r, t) { + return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { + writable: !1 + }), e; + } + function _createForOfIteratorHelper(r, e) { + var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; + if (!t) { + if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { + t && (r = t); + var n = 0, + F = function () {}; + return { + s: F, + n: function () { + return n >= r.length ? { + done: !0 + } : { + done: !1, + value: r[n++] + }; + }, + e: function (r) { + throw r; + }, + f: F + }; + } + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + var o, + a = !0, + u = !1; + return { + s: function () { + t = t.call(r); + }, + n: function () { + var r = t.next(); + return a = r.done, r; + }, + e: function (r) { + u = !0, o = r; + }, + f: function () { + try { + a || null == t.return || t.return(); + } finally { + if (u) throw o; + } + } + }; } - - return io.socket(parsed.path); -} - -/** - * Protocol version. - * - * @api public - */ - -exports.protocol = parser.protocol; - -/** - * `connect`. - * - * @param {String} uri - * @api public - */ - -exports.connect = lookup; - -/** - * Expose constructors for standalone build. - * - * @api public - */ - -exports.Manager = _dereq_('./manager'); -exports.Socket = _dereq_('./socket'); - -},{"./manager":3,"./socket":5,"./url":6,"debug":10,"socket.io-parser":44}],3:[function(_dereq_,module,exports){ - -/** - * Module dependencies. - */ - -var url = _dereq_('./url'); -var eio = _dereq_('engine.io-client'); -var Socket = _dereq_('./socket'); -var Emitter = _dereq_('component-emitter'); -var parser = _dereq_('socket.io-parser'); -var on = _dereq_('./on'); -var bind = _dereq_('component-bind'); -var object = _dereq_('object-component'); -var debug = _dereq_('debug')('socket.io-client:manager'); -var indexOf = _dereq_('indexof'); -var Backoff = _dereq_('backo2'); - -/** - * Module exports - */ - -module.exports = Manager; - -/** - * `Manager` constructor. - * - * @param {String} engine instance or engine uri/opts - * @param {Object} options - * @api public - */ - -function Manager(uri, opts){ - if (!(this instanceof Manager)) return new Manager(uri, opts); - if (uri && ('object' == typeof uri)) { - opts = uri; - uri = undefined; + function _extends() { + return _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); + } + return n; + }, _extends.apply(null, arguments); } - opts = opts || {}; - - opts.path = opts.path || '/socket.io'; - this.nsps = {}; - this.subs = []; - this.opts = opts; - this.reconnection(opts.reconnection !== false); - this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); - this.reconnectionDelay(opts.reconnectionDelay || 1000); - this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); - this.randomizationFactor(opts.randomizationFactor || 0.5); - this.backoff = new Backoff({ - min: this.reconnectionDelay(), - max: this.reconnectionDelayMax(), - jitter: this.randomizationFactor() - }); - this.timeout(null == opts.timeout ? 20000 : opts.timeout); - this.readyState = 'closed'; - this.uri = uri; - this.connected = []; - this.encoding = false; - this.packetBuffer = []; - this.encoder = new parser.Encoder(); - this.decoder = new parser.Decoder(); - this.autoConnect = opts.autoConnect !== false; - if (this.autoConnect) this.open(); -} - -/** - * Propagate given event to sockets and emit on `this` - * - * @api private - */ - -Manager.prototype.emitAll = function() { - this.emit.apply(this, arguments); - for (var nsp in this.nsps) { - this.nsps[nsp].emit.apply(this.nsps[nsp], arguments); + function _getPrototypeOf(t) { + return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { + return t.__proto__ || Object.getPrototypeOf(t); + }, _getPrototypeOf(t); } -}; - -/** - * Update `socket.id` of all sockets - * - * @api private - */ - -Manager.prototype.updateSocketIds = function(){ - for (var nsp in this.nsps) { - this.nsps[nsp].id = this.engine.id; + function _inheritsLoose(t, o) { + t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o); } -}; - -/** - * Mix in `Emitter`. - */ - -Emitter(Manager.prototype); - -/** - * Sets the `reconnection` config. - * - * @param {Boolean} true/false if it should automatically reconnect - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnection = function(v){ - if (!arguments.length) return this._reconnection; - this._reconnection = !!v; - return this; -}; - -/** - * Sets the reconnection attempts config. - * - * @param {Number} max reconnection attempts before giving up - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnectionAttempts = function(v){ - if (!arguments.length) return this._reconnectionAttempts; - this._reconnectionAttempts = v; - return this; -}; - -/** - * Sets the delay between reconnections. - * - * @param {Number} delay - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnectionDelay = function(v){ - if (!arguments.length) return this._reconnectionDelay; - this._reconnectionDelay = v; - this.backoff && this.backoff.setMin(v); - return this; -}; - -Manager.prototype.randomizationFactor = function(v){ - if (!arguments.length) return this._randomizationFactor; - this._randomizationFactor = v; - this.backoff && this.backoff.setJitter(v); - return this; -}; - -/** - * Sets the maximum delay between reconnections. - * - * @param {Number} delay - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnectionDelayMax = function(v){ - if (!arguments.length) return this._reconnectionDelayMax; - this._reconnectionDelayMax = v; - this.backoff && this.backoff.setMax(v); - return this; -}; - -/** - * Sets the connection timeout. `false` to disable - * - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.timeout = function(v){ - if (!arguments.length) return this._timeout; - this._timeout = v; - return this; -}; - -/** - * Starts trying to reconnect if reconnection is enabled and we have not - * started reconnecting yet - * - * @api private - */ - -Manager.prototype.maybeReconnectOnOpen = function() { - // Only try to reconnect if it's the first time we're connecting - if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) { - // keeps reconnection from firing twice for the same reconnection loop - this.reconnect(); + function _isNativeFunction(t) { + try { + return -1 !== Function.toString.call(t).indexOf("[native code]"); + } catch (n) { + return "function" == typeof t; + } } -}; - - -/** - * Sets the current transport `socket`. - * - * @param {Function} optional, callback - * @return {Manager} self - * @api public - */ - -Manager.prototype.open = -Manager.prototype.connect = function(fn){ - debug('readyState %s', this.readyState); - if (~this.readyState.indexOf('open')) return this; - - debug('opening %s', this.uri); - this.engine = eio(this.uri, this.opts); - var socket = this.engine; - var self = this; - this.readyState = 'opening'; - this.skipReconnect = false; - - // emit `open` - var openSub = on(socket, 'open', function() { - self.onopen(); - fn && fn(); - }); - - // emit `connect_error` - var errorSub = on(socket, 'error', function(data){ - debug('connect_error'); - self.cleanup(); - self.readyState = 'closed'; - self.emitAll('connect_error', data); - if (fn) { - var err = new Error('Connection error'); - err.data = data; - fn(err); - } else { - // Only do this if there is no fn to handle the error - self.maybeReconnectOnOpen(); + function _isNativeReflectConstruct() { + try { + var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); + } catch (t) {} + return (_isNativeReflectConstruct = function () { + return !!t; + })(); + } + function _iterableToArray(r) { + if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); + } + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + function _setPrototypeOf(t, e) { + return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { + return t.__proto__ = e, t; + }, _setPrototypeOf(t, e); + } + function _toConsumableArray(r) { + return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); + } + function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); + } + function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : i + ""; + } + function _typeof(o) { + "@babel/helpers - typeof"; + + return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { + return typeof o; + } : function (o) { + return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; + }, _typeof(o); + } + function _unsupportedIterableToArray(r, a) { + if (r) { + if ("string" == typeof r) return _arrayLikeToArray(r, a); + var t = {}.toString.call(r).slice(8, -1); + return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } + } + function _wrapNativeSuper(t) { + var r = "function" == typeof Map ? new Map() : void 0; + return _wrapNativeSuper = function (t) { + if (null === t || !_isNativeFunction(t)) return t; + if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function"); + if (void 0 !== r) { + if (r.has(t)) return r.get(t); + r.set(t, Wrapper); + } + function Wrapper() { + return _construct(t, arguments, _getPrototypeOf(this).constructor); + } + return Wrapper.prototype = Object.create(t.prototype, { + constructor: { + value: Wrapper, + enumerable: !1, + writable: !0, + configurable: !0 + } + }), _setPrototypeOf(Wrapper, t); + }, _wrapNativeSuper(t); + } + + var PACKET_TYPES = Object.create(null); // no Map = no polyfill + PACKET_TYPES["open"] = "0"; + PACKET_TYPES["close"] = "1"; + PACKET_TYPES["ping"] = "2"; + PACKET_TYPES["pong"] = "3"; + PACKET_TYPES["message"] = "4"; + PACKET_TYPES["upgrade"] = "5"; + PACKET_TYPES["noop"] = "6"; + var PACKET_TYPES_REVERSE = Object.create(null); + Object.keys(PACKET_TYPES).forEach(function (key) { + PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key; }); + var ERROR_PACKET = { + type: "error", + data: "parser error" + }; - // emit `connect_timeout` - if (false !== this._timeout) { - var timeout = this._timeout; - debug('connect attempt will timeout after %d', timeout); - - // set timer - var timer = setTimeout(function(){ - debug('connect attempt timed out after %d', timeout); - openSub.destroy(); - socket.close(); - socket.emit('error', 'timeout'); - self.emitAll('connect_timeout', timeout); - }, timeout); - - this.subs.push({ - destroy: function(){ - clearTimeout(timer); + var withNativeBlob$1 = typeof Blob === "function" || typeof Blob !== "undefined" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]"; + var withNativeArrayBuffer$2 = typeof ArrayBuffer === "function"; + // ArrayBuffer.isView method is not defined in IE10 + var isView$1 = function isView(obj) { + return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj && obj.buffer instanceof ArrayBuffer; + }; + var encodePacket = function encodePacket(_ref, supportsBinary, callback) { + var type = _ref.type, + data = _ref.data; + if (withNativeBlob$1 && data instanceof Blob) { + if (supportsBinary) { + return callback(data); + } else { + return encodeBlobAsBase64(data, callback); } - }); + } else if (withNativeArrayBuffer$2 && (data instanceof ArrayBuffer || isView$1(data))) { + if (supportsBinary) { + return callback(data); + } else { + return encodeBlobAsBase64(new Blob([data]), callback); + } + } + // plain string + return callback(PACKET_TYPES[type] + (data || "")); + }; + var encodeBlobAsBase64 = function encodeBlobAsBase64(data, callback) { + var fileReader = new FileReader(); + fileReader.onload = function () { + var content = fileReader.result.split(",")[1]; + callback("b" + (content || "")); + }; + return fileReader.readAsDataURL(data); + }; + function toArray(data) { + if (data instanceof Uint8Array) { + return data; + } else if (data instanceof ArrayBuffer) { + return new Uint8Array(data); + } else { + return new Uint8Array(data.buffer, data.byteOffset, data.byteLength); + } } - - this.subs.push(openSub); - this.subs.push(errorSub); - - return this; -}; - -/** - * Called upon transport open. - * - * @api private - */ - -Manager.prototype.onopen = function(){ - debug('open'); - - // clear old subs - this.cleanup(); - - // mark as open - this.readyState = 'open'; - this.emit('open'); - - // add new subs - var socket = this.engine; - this.subs.push(on(socket, 'data', bind(this, 'ondata'))); - this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded'))); - this.subs.push(on(socket, 'error', bind(this, 'onerror'))); - this.subs.push(on(socket, 'close', bind(this, 'onclose'))); -}; - -/** - * Called with data. - * - * @api private - */ - -Manager.prototype.ondata = function(data){ - this.decoder.add(data); -}; - -/** - * Called when parser fully decodes a packet. - * - * @api private - */ - -Manager.prototype.ondecoded = function(packet) { - this.emit('packet', packet); -}; - -/** - * Called upon socket error. - * - * @api private - */ - -Manager.prototype.onerror = function(err){ - debug('error', err); - this.emitAll('error', err); -}; - -/** - * Creates a new socket for the given `nsp`. - * - * @return {Socket} - * @api public - */ - -Manager.prototype.socket = function(nsp){ - var socket = this.nsps[nsp]; - if (!socket) { - socket = new Socket(this, nsp); - this.nsps[nsp] = socket; - var self = this; - socket.on('connect', function(){ - socket.id = self.engine.id; - if (!~indexOf(self.connected, socket)) { - self.connected.push(socket); + var TEXT_ENCODER; + function encodePacketToBinary(packet, callback) { + if (withNativeBlob$1 && packet.data instanceof Blob) { + return packet.data.arrayBuffer().then(toArray).then(callback); + } else if (withNativeArrayBuffer$2 && (packet.data instanceof ArrayBuffer || isView$1(packet.data))) { + return callback(toArray(packet.data)); + } + encodePacket(packet, false, function (encoded) { + if (!TEXT_ENCODER) { + TEXT_ENCODER = new TextEncoder(); } + callback(TEXT_ENCODER.encode(encoded)); }); } - return socket; -}; - -/** - * Called upon a socket close. - * - * @param {Socket} socket - */ -Manager.prototype.destroy = function(socket){ - var index = indexOf(this.connected, socket); - if (~index) this.connected.splice(index, 1); - if (this.connected.length) return; - - this.close(); -}; - -/** - * Writes a packet. - * - * @param {Object} packet - * @api private - */ + // imported from https://github.com/socketio/base64-arraybuffer + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + // Use a lookup table to find the index. + var lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256); + for (var i = 0; i < chars.length; i++) { + lookup$1[chars.charCodeAt(i)] = i; + } + var decode$1 = function decode(base64) { + var bufferLength = base64.length * 0.75, + len = base64.length, + i, + p = 0, + encoded1, + encoded2, + encoded3, + encoded4; + if (base64[base64.length - 1] === '=') { + bufferLength--; + if (base64[base64.length - 2] === '=') { + bufferLength--; + } + } + var arraybuffer = new ArrayBuffer(bufferLength), + bytes = new Uint8Array(arraybuffer); + for (i = 0; i < len; i += 4) { + encoded1 = lookup$1[base64.charCodeAt(i)]; + encoded2 = lookup$1[base64.charCodeAt(i + 1)]; + encoded3 = lookup$1[base64.charCodeAt(i + 2)]; + encoded4 = lookup$1[base64.charCodeAt(i + 3)]; + bytes[p++] = encoded1 << 2 | encoded2 >> 4; + bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + return arraybuffer; + }; -Manager.prototype.packet = function(packet){ - debug('writing packet %j', packet); - var self = this; + var withNativeArrayBuffer$1 = typeof ArrayBuffer === "function"; + var decodePacket = function decodePacket(encodedPacket, binaryType) { + if (typeof encodedPacket !== "string") { + return { + type: "message", + data: mapBinary(encodedPacket, binaryType) + }; + } + var type = encodedPacket.charAt(0); + if (type === "b") { + return { + type: "message", + data: decodeBase64Packet(encodedPacket.substring(1), binaryType) + }; + } + var packetType = PACKET_TYPES_REVERSE[type]; + if (!packetType) { + return ERROR_PACKET; + } + return encodedPacket.length > 1 ? { + type: PACKET_TYPES_REVERSE[type], + data: encodedPacket.substring(1) + } : { + type: PACKET_TYPES_REVERSE[type] + }; + }; + var decodeBase64Packet = function decodeBase64Packet(data, binaryType) { + if (withNativeArrayBuffer$1) { + var decoded = decode$1(data); + return mapBinary(decoded, binaryType); + } else { + return { + base64: true, + data: data + }; // fallback for old browsers + } + }; + var mapBinary = function mapBinary(data, binaryType) { + switch (binaryType) { + case "blob": + if (data instanceof Blob) { + // from WebSocket + binaryType "blob" + return data; + } else { + // from HTTP long-polling or WebTransport + return new Blob([data]); + } + case "arraybuffer": + default: + if (data instanceof ArrayBuffer) { + // from HTTP long-polling (base64) or WebSocket + binaryType "arraybuffer" + return data; + } else { + // from WebTransport (Uint8Array) + return data.buffer; + } + } + }; - if (!self.encoding) { - // encode, then write to engine with result - self.encoding = true; - this.encoder.encode(packet, function(encodedPackets) { - for (var i = 0; i < encodedPackets.length; i++) { - self.engine.write(encodedPackets[i]); + var SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text + var encodePayload = function encodePayload(packets, callback) { + // some packets may be added to the array while encoding, so the initial length must be saved + var length = packets.length; + var encodedPackets = new Array(length); + var count = 0; + packets.forEach(function (packet, i) { + // force base64 encoding for binary packets + encodePacket(packet, false, function (encodedPacket) { + encodedPackets[i] = encodedPacket; + if (++count === length) { + callback(encodedPackets.join(SEPARATOR)); + } + }); + }); + }; + var decodePayload = function decodePayload(encodedPayload, binaryType) { + var encodedPackets = encodedPayload.split(SEPARATOR); + var packets = []; + for (var i = 0; i < encodedPackets.length; i++) { + var decodedPacket = decodePacket(encodedPackets[i], binaryType); + packets.push(decodedPacket); + if (decodedPacket.type === "error") { + break; + } + } + return packets; + }; + function createPacketEncoderStream() { + return new TransformStream({ + transform: function transform(packet, controller) { + encodePacketToBinary(packet, function (encodedPacket) { + var payloadLength = encodedPacket.length; + var header; + // inspired by the WebSocket format: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#decoding_payload_length + if (payloadLength < 126) { + header = new Uint8Array(1); + new DataView(header.buffer).setUint8(0, payloadLength); + } else if (payloadLength < 65536) { + header = new Uint8Array(3); + var view = new DataView(header.buffer); + view.setUint8(0, 126); + view.setUint16(1, payloadLength); + } else { + header = new Uint8Array(9); + var _view = new DataView(header.buffer); + _view.setUint8(0, 127); + _view.setBigUint64(1, BigInt(payloadLength)); + } + // first bit indicates whether the payload is plain text (0) or binary (1) + if (packet.data && typeof packet.data !== "string") { + header[0] |= 0x80; + } + controller.enqueue(header); + controller.enqueue(encodedPacket); + }); } - self.encoding = false; - self.processPacketQueue(); }); - } else { // add packet to the queue - self.packetBuffer.push(packet); } -}; - -/** - * If packet buffer is non-empty, begins encoding the - * next packet in line. - * - * @api private - */ - -Manager.prototype.processPacketQueue = function() { - if (this.packetBuffer.length > 0 && !this.encoding) { - var pack = this.packetBuffer.shift(); - this.packet(pack); + var TEXT_DECODER; + function totalLength(chunks) { + return chunks.reduce(function (acc, chunk) { + return acc + chunk.length; + }, 0); } -}; - -/** - * Clean up transport subscriptions and packet buffer. - * - * @api private - */ - -Manager.prototype.cleanup = function(){ - var sub; - while (sub = this.subs.shift()) sub.destroy(); - - this.packetBuffer = []; - this.encoding = false; - - this.decoder.destroy(); -}; - -/** - * Close the current socket. - * - * @api private - */ - -Manager.prototype.close = -Manager.prototype.disconnect = function(){ - this.skipReconnect = true; - this.backoff.reset(); - this.readyState = 'closed'; - this.engine && this.engine.close(); -}; - -/** - * Called upon engine close. - * - * @api private - */ - -Manager.prototype.onclose = function(reason){ - debug('close'); - this.cleanup(); - this.backoff.reset(); - this.readyState = 'closed'; - this.emit('close', reason); - if (this._reconnection && !this.skipReconnect) { - this.reconnect(); + function concatChunks(chunks, size) { + if (chunks[0].length === size) { + return chunks.shift(); + } + var buffer = new Uint8Array(size); + var j = 0; + for (var i = 0; i < size; i++) { + buffer[i] = chunks[0][j++]; + if (j === chunks[0].length) { + chunks.shift(); + j = 0; + } + } + if (chunks.length && j < chunks[0].length) { + chunks[0] = chunks[0].slice(j); + } + return buffer; } -}; - -/** - * Attempt a reconnection. - * - * @api private - */ - -Manager.prototype.reconnect = function(){ - if (this.reconnecting || this.skipReconnect) return this; - - var self = this; - - if (this.backoff.attempts >= this._reconnectionAttempts) { - debug('reconnect failed'); - this.backoff.reset(); - this.emitAll('reconnect_failed'); - this.reconnecting = false; - } else { - var delay = this.backoff.duration(); - debug('will wait %dms before reconnect attempt', delay); - - this.reconnecting = true; - var timer = setTimeout(function(){ - if (self.skipReconnect) return; - - debug('attempting reconnect'); - self.emitAll('reconnect_attempt', self.backoff.attempts); - self.emitAll('reconnecting', self.backoff.attempts); - - // check again for the case socket closed in above events - if (self.skipReconnect) return; - - self.open(function(err){ - if (err) { - debug('reconnect attempt error'); - self.reconnecting = false; - self.reconnect(); - self.emitAll('reconnect_error', err.data); - } else { - debug('reconnect success'); - self.onreconnect(); + function createPacketDecoderStream(maxPayload, binaryType) { + if (!TEXT_DECODER) { + TEXT_DECODER = new TextDecoder(); + } + var chunks = []; + var state = 0 /* State.READ_HEADER */; + var expectedLength = -1; + var isBinary = false; + return new TransformStream({ + transform: function transform(chunk, controller) { + chunks.push(chunk); + while (true) { + if (state === 0 /* State.READ_HEADER */) { + if (totalLength(chunks) < 1) { + break; + } + var header = concatChunks(chunks, 1); + isBinary = (header[0] & 0x80) === 0x80; + expectedLength = header[0] & 0x7f; + if (expectedLength < 126) { + state = 3 /* State.READ_PAYLOAD */; + } else if (expectedLength === 126) { + state = 1 /* State.READ_EXTENDED_LENGTH_16 */; + } else { + state = 2 /* State.READ_EXTENDED_LENGTH_64 */; + } + } else if (state === 1 /* State.READ_EXTENDED_LENGTH_16 */) { + if (totalLength(chunks) < 2) { + break; + } + var headerArray = concatChunks(chunks, 2); + expectedLength = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length).getUint16(0); + state = 3 /* State.READ_PAYLOAD */; + } else if (state === 2 /* State.READ_EXTENDED_LENGTH_64 */) { + if (totalLength(chunks) < 8) { + break; + } + var _headerArray = concatChunks(chunks, 8); + var view = new DataView(_headerArray.buffer, _headerArray.byteOffset, _headerArray.length); + var n = view.getUint32(0); + if (n > Math.pow(2, 53 - 32) - 1) { + // the maximum safe integer in JavaScript is 2^53 - 1 + controller.enqueue(ERROR_PACKET); + break; + } + expectedLength = n * Math.pow(2, 32) + view.getUint32(4); + state = 3 /* State.READ_PAYLOAD */; + } else { + if (totalLength(chunks) < expectedLength) { + break; + } + var data = concatChunks(chunks, expectedLength); + controller.enqueue(decodePacket(isBinary ? data : TEXT_DECODER.decode(data), binaryType)); + state = 0 /* State.READ_HEADER */; + } + if (expectedLength === 0 || expectedLength > maxPayload) { + controller.enqueue(ERROR_PACKET); + break; + } } - }); - }, delay); - - this.subs.push({ - destroy: function(){ - clearTimeout(timer); } }); } -}; + var protocol$1 = 4; -/** - * Called upon successful reconnect. - * - * @api private - */ + /** + * Initialize a new `Emitter`. + * + * @api public + */ -Manager.prototype.onreconnect = function(){ - var attempt = this.backoff.attempts; - this.reconnecting = false; - this.backoff.reset(); - this.updateSocketIds(); - this.emitAll('reconnect', attempt); -}; + function Emitter(obj) { + if (obj) return mixin(obj); + } -},{"./on":4,"./socket":5,"./url":6,"backo2":7,"component-bind":8,"component-emitter":9,"debug":10,"engine.io-client":11,"indexof":40,"object-component":41,"socket.io-parser":44}],4:[function(_dereq_,module,exports){ + /** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ -/** - * Module exports. - */ + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; + } -module.exports = on; + /** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ -/** - * Helper for subscriptions. - * - * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter` - * @param {String} event name - * @param {Function} callback - * @api public - */ + Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); + return this; + }; -function on(obj, ev, fn) { - obj.on(ev, fn); - return { - destroy: function(){ - obj.removeListener(ev, fn); + /** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.once = function (event, fn) { + function on() { + this.off(event, on); + fn.apply(this, arguments); } + on.fn = fn; + this.on(event, on); + return this; }; -} - -},{}],5:[function(_dereq_,module,exports){ - -/** - * Module dependencies. - */ - -var parser = _dereq_('socket.io-parser'); -var Emitter = _dereq_('component-emitter'); -var toArray = _dereq_('to-array'); -var on = _dereq_('./on'); -var bind = _dereq_('component-bind'); -var debug = _dereq_('debug')('socket.io-client:socket'); -var hasBin = _dereq_('has-binary'); - -/** - * Module exports. - */ -module.exports = exports = Socket; + /** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } -/** - * Internal events (blacklisted). - * These events can't be emitted by the user. - * - * @api private - */ + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; -var events = { - connect: 1, - connect_error: 1, - connect_timeout: 1, - disconnect: 1, - error: 1, - reconnect: 1, - reconnect_attempt: 1, - reconnect_failed: 1, - reconnect_error: 1, - reconnecting: 1 -}; + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } -/** - * Shortcut to `Emitter#emit`. - */ + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } -var emit = Emitter.prototype.emit; + // Remove event specific arrays for event types that no + // one is subscribed for to avoid memory leak. + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + return this; + }; -/** - * `Socket` constructor. - * - * @api public - */ + /** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + + Emitter.prototype.emit = function (event) { + this._callbacks = this._callbacks || {}; + var args = new Array(arguments.length - 1), + callbacks = this._callbacks['$' + event]; + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + return this; + }; -function Socket(io, nsp){ - this.io = io; - this.nsp = nsp; - this.json = this; // compat - this.ids = 0; - this.acks = {}; - if (this.io.autoConnect) this.open(); - this.receiveBuffer = []; - this.sendBuffer = []; - this.connected = false; - this.disconnected = true; -} + // alias used for reserved events (protected method) + Emitter.prototype.emitReserved = Emitter.prototype.emit; -/** - * Mix in `Emitter`. - */ + /** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ -Emitter(Socket.prototype); + Emitter.prototype.listeners = function (event) { + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; + }; -/** - * Subscribe to open, close and packet events - * - * @api private - */ + /** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ -Socket.prototype.subEvents = function() { - if (this.subs) return; + Emitter.prototype.hasListeners = function (event) { + return !!this.listeners(event).length; + }; - var io = this.io; - this.subs = [ - on(io, 'open', bind(this, 'onopen')), - on(io, 'packet', bind(this, 'onpacket')), - on(io, 'close', bind(this, 'onclose')) - ]; -}; - -/** - * "Opens" the socket. - * - * @api public - */ - -Socket.prototype.open = -Socket.prototype.connect = function(){ - if (this.connected) return this; - - this.subEvents(); - this.io.open(); // ensure open - if ('open' == this.io.readyState) this.onopen(); - return this; -}; - -/** - * Sends a `message` event. - * - * @return {Socket} self - * @api public - */ - -Socket.prototype.send = function(){ - var args = toArray(arguments); - args.unshift('message'); - this.emit.apply(this, args); - return this; -}; - -/** - * Override `emit`. - * If the event is in `events`, it's emitted normally. - * - * @param {String} event name - * @return {Socket} self - * @api public - */ - -Socket.prototype.emit = function(ev){ - if (events.hasOwnProperty(ev)) { - emit.apply(this, arguments); - return this; - } - - var args = toArray(arguments); - var parserType = parser.EVENT; // default - if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary - var packet = { type: parserType, data: args }; - - // event ack callback - if ('function' == typeof args[args.length - 1]) { - debug('emitting packet with ack id %d', this.ids); - this.acks[this.ids] = args.pop(); - packet.id = this.ids++; - } - - if (this.connected) { - this.packet(packet); - } else { - this.sendBuffer.push(packet); - } - - return this; -}; - -/** - * Sends a packet. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.packet = function(packet){ - packet.nsp = this.nsp; - this.io.packet(packet); -}; - -/** - * Called upon engine `open`. - * - * @api private - */ - -Socket.prototype.onopen = function(){ - debug('transport is open - connecting'); - - // write connect packet if necessary - if ('/' != this.nsp) { - this.packet({ type: parser.CONNECT }); - } -}; - -/** - * Called upon engine `close`. - * - * @param {String} reason - * @api private - */ - -Socket.prototype.onclose = function(reason){ - debug('close (%s)', reason); - this.connected = false; - this.disconnected = true; - delete this.id; - this.emit('disconnect', reason); -}; - -/** - * Called with socket packet. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.onpacket = function(packet){ - if (packet.nsp != this.nsp) return; - - switch (packet.type) { - case parser.CONNECT: - this.onconnect(); - break; - - case parser.EVENT: - this.onevent(packet); - break; - - case parser.BINARY_EVENT: - this.onevent(packet); - break; - - case parser.ACK: - this.onack(packet); - break; - - case parser.BINARY_ACK: - this.onack(packet); - break; - - case parser.DISCONNECT: - this.ondisconnect(); - break; - - case parser.ERROR: - this.emit('error', packet.data); - break; - } -}; - -/** - * Called upon a server event. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.onevent = function(packet){ - var args = packet.data || []; - debug('emitting event %j', args); - - if (null != packet.id) { - debug('attaching ack callback to event'); - args.push(this.ack(packet.id)); - } - - if (this.connected) { - emit.apply(this, args); - } else { - this.receiveBuffer.push(args); - } -}; - -/** - * Produces an ack callback to emit with an event. - * - * @api private - */ - -Socket.prototype.ack = function(id){ - var self = this; - var sent = false; - return function(){ - // prevent double callbacks - if (sent) return; - sent = true; - var args = toArray(arguments); - debug('sending ack %j', args); - - var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK; - self.packet({ - type: type, - id: id, - data: args - }); - }; -}; - -/** - * Called upon a server acknowlegement. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.onack = function(packet){ - debug('calling ack %s with %j', packet.id, packet.data); - var fn = this.acks[packet.id]; - fn.apply(this, packet.data); - delete this.acks[packet.id]; -}; - -/** - * Called upon server connect. - * - * @api private - */ - -Socket.prototype.onconnect = function(){ - this.connected = true; - this.disconnected = false; - this.emit('connect'); - this.emitBuffered(); -}; - -/** - * Emit buffered events (received and emitted). - * - * @api private - */ - -Socket.prototype.emitBuffered = function(){ - var i; - for (i = 0; i < this.receiveBuffer.length; i++) { - emit.apply(this, this.receiveBuffer[i]); - } - this.receiveBuffer = []; - - for (i = 0; i < this.sendBuffer.length; i++) { - this.packet(this.sendBuffer[i]); - } - this.sendBuffer = []; -}; - -/** - * Called upon server disconnect. - * - * @api private - */ - -Socket.prototype.ondisconnect = function(){ - debug('server disconnect (%s)', this.nsp); - this.destroy(); - this.onclose('io server disconnect'); -}; - -/** - * Called upon forced client/server side disconnections, - * this method ensures the manager stops tracking us and - * that reconnections don't get triggered for this. - * - * @api private. - */ - -Socket.prototype.destroy = function(){ - if (this.subs) { - // clean subscriptions to avoid reconnections - for (var i = 0; i < this.subs.length; i++) { - this.subs[i].destroy(); - } - this.subs = null; - } - - this.io.destroy(this); -}; - -/** - * Disconnects the socket manually. - * - * @return {Socket} self - * @api public - */ - -Socket.prototype.close = -Socket.prototype.disconnect = function(){ - if (this.connected) { - debug('performing disconnect (%s)', this.nsp); - this.packet({ type: parser.DISCONNECT }); - } - - // remove socket from pool - this.destroy(); - - if (this.connected) { - // fire events - this.onclose('io client disconnect'); - } - return this; -}; - -},{"./on":4,"component-bind":8,"component-emitter":9,"debug":10,"has-binary":36,"socket.io-parser":44,"to-array":48}],6:[function(_dereq_,module,exports){ -(function (global){ - -/** - * Module dependencies. - */ - -var parseuri = _dereq_('parseuri'); -var debug = _dereq_('debug')('socket.io-client:url'); - -/** - * Module exports. - */ - -module.exports = url; - -/** - * URL parser. - * - * @param {String} url - * @param {Object} An object meant to mimic window.location. - * Defaults to window.location. - * @api public - */ - -function url(uri, loc){ - var obj = uri; - - // default to window.location - var loc = loc || global.location; - if (null == uri) uri = loc.protocol + '//' + loc.host; - - // relative path support - if ('string' == typeof uri) { - if ('/' == uri.charAt(0)) { - if ('/' == uri.charAt(1)) { - uri = loc.protocol + uri; - } else { - uri = loc.hostname + uri; - } - } - - if (!/^(https?|wss?):\/\//.test(uri)) { - debug('protocol-less url %s', uri); - if ('undefined' != typeof loc) { - uri = loc.protocol + '//' + uri; - } else { - uri = 'https://' + uri; - } - } - - // parse - debug('parse %s', uri); - obj = parseuri(uri); - } - - // make sure we treat `localhost:80` and `localhost` equally - if (!obj.port) { - if (/^(http|ws)$/.test(obj.protocol)) { - obj.port = '80'; - } - else if (/^(http|ws)s$/.test(obj.protocol)) { - obj.port = '443'; - } - } - - obj.path = obj.path || '/'; - - // define unique id - obj.id = obj.protocol + '://' + obj.host + ':' + obj.port; - // define href - obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port)); - - return obj; -} - -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"debug":10,"parseuri":42}],7:[function(_dereq_,module,exports){ - -/** - * Expose `Backoff`. - */ - -module.exports = Backoff; - -/** - * Initialize backoff timer with `opts`. - * - * - `min` initial timeout in milliseconds [100] - * - `max` max timeout [10000] - * - `jitter` [0] - * - `factor` [2] - * - * @param {Object} opts - * @api public - */ - -function Backoff(opts) { - opts = opts || {}; - this.ms = opts.min || 100; - this.max = opts.max || 10000; - this.factor = opts.factor || 2; - this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; - this.attempts = 0; -} - -/** - * Return the backoff duration. - * - * @return {Number} - * @api public - */ - -Backoff.prototype.duration = function(){ - var ms = this.ms * Math.pow(this.factor, this.attempts++); - if (this.jitter) { - var rand = Math.random(); - var deviation = Math.floor(rand * this.jitter * ms); - ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; - } - return Math.min(ms, this.max) | 0; -}; - -/** - * Reset the number of attempts. - * - * @api public - */ - -Backoff.prototype.reset = function(){ - this.attempts = 0; -}; - -/** - * Set the minimum duration - * - * @api public - */ - -Backoff.prototype.setMin = function(min){ - this.ms = min; -}; - -/** - * Set the maximum duration - * - * @api public - */ - -Backoff.prototype.setMax = function(max){ - this.max = max; -}; - -/** - * Set the jitter - * - * @api public - */ - -Backoff.prototype.setJitter = function(jitter){ - this.jitter = jitter; -}; - - -},{}],8:[function(_dereq_,module,exports){ -/** - * Slice reference. - */ - -var slice = [].slice; - -/** - * Bind `obj` to `fn`. - * - * @param {Object} obj - * @param {Function|String} fn or string - * @return {Function} - * @api public - */ - -module.exports = function(obj, fn){ - if ('string' == typeof fn) fn = obj[fn]; - if ('function' != typeof fn) throw new Error('bind() requires a function'); - var args = slice.call(arguments, 2); - return function(){ - return fn.apply(obj, args.concat(slice.call(arguments))); - } -}; - -},{}],9:[function(_dereq_,module,exports){ - -/** - * Expose `Emitter`. - */ - -module.exports = Emitter; - -/** - * Initialize a new `Emitter`. - * - * @api public - */ - -function Emitter(obj) { - if (obj) return mixin(obj); -}; - -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; -} - -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks[event] = this._callbacks[event] || []) - .push(fn); - return this; -}; - -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.once = function(event, fn){ - var self = this; - this._callbacks = this._callbacks || {}; - - function on() { - self.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; -}; - -/** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks[event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks[event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; -}; - -/** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks[event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; -}; - -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks[event] || []; -}; - -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; - -},{}],10:[function(_dereq_,module,exports){ - -/** - * Expose `debug()` as the module. - */ - -module.exports = debug; - -/** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - -function debug(name) { - if (!debug.enabled(name)) return function(){}; - - return function(fmt){ - fmt = coerce(fmt); - - var curr = new Date; - var ms = curr - (debug[name] || curr); - debug[name] = curr; - - fmt = name - + ' ' - + fmt - + ' +' + debug.humanize(ms); - - // This hackery is required for IE8 - // where `console.log` doesn't have 'apply' - window.console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); - } -} - -/** - * The currently active debug mode names. - */ - -debug.names = []; -debug.skips = []; - -/** - * Enables a debug mode by name. This can include modes - * separated by a colon and wildcards. - * - * @param {String} name - * @api public - */ - -debug.enable = function(name) { - try { - localStorage.debug = name; - } catch(e){} - - var split = (name || '').split(/[\s,]+/) - , len = split.length; - - for (var i = 0; i < len; i++) { - name = split[i].replace('*', '.*?'); - if (name[0] === '-') { - debug.skips.push(new RegExp('^' + name.substr(1) + '$')); - } - else { - debug.names.push(new RegExp('^' + name + '$')); - } - } -}; - -/** - * Disable debug output. - * - * @api public - */ - -debug.disable = function(){ - debug.enable(''); -}; - -/** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - -debug.humanize = function(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; -}; - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -debug.enabled = function(name) { - for (var i = 0, len = debug.skips.length; i < len; i++) { - if (debug.skips[i].test(name)) { - return false; - } - } - for (var i = 0, len = debug.names.length; i < len; i++) { - if (debug.names[i].test(name)) { - return true; - } - } - return false; -}; - -/** - * Coerce `val`. - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} - -// persist - -try { - if (window.localStorage) debug.enable(localStorage.debug); -} catch(e){} - -},{}],11:[function(_dereq_,module,exports){ - -module.exports = _dereq_('./lib/'); - -},{"./lib/":12}],12:[function(_dereq_,module,exports){ - -module.exports = _dereq_('./socket'); - -/** - * Exports parser - * - * @api public - * - */ -module.exports.parser = _dereq_('engine.io-parser'); - -},{"./socket":13,"engine.io-parser":25}],13:[function(_dereq_,module,exports){ -(function (global){ -/** - * Module dependencies. - */ - -var transports = _dereq_('./transports'); -var Emitter = _dereq_('component-emitter'); -var debug = _dereq_('debug')('engine.io-client:socket'); -var index = _dereq_('indexof'); -var parser = _dereq_('engine.io-parser'); -var parseuri = _dereq_('parseuri'); -var parsejson = _dereq_('parsejson'); -var parseqs = _dereq_('parseqs'); - -/** - * Module exports. - */ - -module.exports = Socket; - -/** - * Noop function. - * - * @api private - */ - -function noop(){} - -/** - * Socket constructor. - * - * @param {String|Object} uri or options - * @param {Object} options - * @api public - */ - -function Socket(uri, opts){ - if (!(this instanceof Socket)) return new Socket(uri, opts); - - opts = opts || {}; - - if (uri && 'object' == typeof uri) { - opts = uri; - uri = null; - } - - if (uri) { - uri = parseuri(uri); - opts.host = uri.host; - opts.secure = uri.protocol == 'https' || uri.protocol == 'wss'; - opts.port = uri.port; - if (uri.query) opts.query = uri.query; - } - - this.secure = null != opts.secure ? opts.secure : - (global.location && 'https:' == location.protocol); - - if (opts.host) { - var pieces = opts.host.split(':'); - opts.hostname = pieces.shift(); - if (pieces.length) { - opts.port = pieces.pop(); - } else if (!opts.port) { - // if no port is specified manually, use the protocol default - opts.port = this.secure ? '443' : '80'; - } - } - - this.agent = opts.agent || false; - this.hostname = opts.hostname || - (global.location ? location.hostname : 'localhost'); - this.port = opts.port || (global.location && location.port ? - location.port : - (this.secure ? 443 : 80)); - this.query = opts.query || {}; - if ('string' == typeof this.query) this.query = parseqs.decode(this.query); - this.upgrade = false !== opts.upgrade; - this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; - this.forceJSONP = !!opts.forceJSONP; - this.jsonp = false !== opts.jsonp; - this.forceBase64 = !!opts.forceBase64; - this.enablesXDR = !!opts.enablesXDR; - this.timestampParam = opts.timestampParam || 't'; - this.timestampRequests = opts.timestampRequests; - this.transports = opts.transports || ['polling', 'websocket']; - this.readyState = ''; - this.writeBuffer = []; - this.callbackBuffer = []; - this.policyPort = opts.policyPort || 843; - this.rememberUpgrade = opts.rememberUpgrade || false; - this.binaryType = null; - this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades; - - // SSL options for Node.js client - this.pfx = opts.pfx || null; - this.key = opts.key || null; - this.passphrase = opts.passphrase || null; - this.cert = opts.cert || null; - this.ca = opts.ca || null; - this.ciphers = opts.ciphers || null; - this.rejectUnauthorized = opts.rejectUnauthorized || null; - - this.open(); -} - -Socket.priorWebsocketSuccess = false; - -/** - * Mix in `Emitter`. - */ - -Emitter(Socket.prototype); - -/** - * Protocol version. - * - * @api public - */ - -Socket.protocol = parser.protocol; // this is an int - -/** - * Expose deps for legacy compatibility - * and standalone browser access. - */ - -Socket.Socket = Socket; -Socket.Transport = _dereq_('./transport'); -Socket.transports = _dereq_('./transports'); -Socket.parser = _dereq_('engine.io-parser'); - -/** - * Creates transport of the given type. - * - * @param {String} transport name - * @return {Transport} - * @api private - */ - -Socket.prototype.createTransport = function (name) { - debug('creating transport "%s"', name); - var query = clone(this.query); - - // append engine.io protocol identifier - query.EIO = parser.protocol; - - // transport name - query.transport = name; - - // session id if we already have one - if (this.id) query.sid = this.id; - - var transport = new transports[name]({ - agent: this.agent, - hostname: this.hostname, - port: this.port, - secure: this.secure, - path: this.path, - query: query, - forceJSONP: this.forceJSONP, - jsonp: this.jsonp, - forceBase64: this.forceBase64, - enablesXDR: this.enablesXDR, - timestampRequests: this.timestampRequests, - timestampParam: this.timestampParam, - policyPort: this.policyPort, - socket: this, - pfx: this.pfx, - key: this.key, - passphrase: this.passphrase, - cert: this.cert, - ca: this.ca, - ciphers: this.ciphers, - rejectUnauthorized: this.rejectUnauthorized - }); - - return transport; -}; - -function clone (obj) { - var o = {}; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - o[i] = obj[i]; - } - } - return o; -} - -/** - * Initializes transport to use and starts probe. - * - * @api private - */ -Socket.prototype.open = function () { - var transport; - if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) { - transport = 'websocket'; - } else if (0 == this.transports.length) { - // Emit error on next tick so it can be listened to - var self = this; - setTimeout(function() { - self.emit('error', 'No transports available'); - }, 0); - return; - } else { - transport = this.transports[0]; - } - this.readyState = 'opening'; - - // Retry with the next transport if the transport is disabled (jsonp: false) - var transport; - try { - transport = this.createTransport(transport); - } catch (e) { - this.transports.shift(); - this.open(); - return; - } - - transport.open(); - this.setTransport(transport); -}; - -/** - * Sets the current transport. Disables the existing one (if any). - * - * @api private - */ - -Socket.prototype.setTransport = function(transport){ - debug('setting transport %s', transport.name); - var self = this; - - if (this.transport) { - debug('clearing existing transport %s', this.transport.name); - this.transport.removeAllListeners(); - } - - // set up transport - this.transport = transport; - - // set up transport listeners - transport - .on('drain', function(){ - self.onDrain(); - }) - .on('packet', function(packet){ - self.onPacket(packet); - }) - .on('error', function(e){ - self.onError(e); - }) - .on('close', function(){ - self.onClose('transport close'); - }); -}; - -/** - * Probes a transport. - * - * @param {String} transport name - * @api private - */ - -Socket.prototype.probe = function (name) { - debug('probing transport "%s"', name); - var transport = this.createTransport(name, { probe: 1 }) - , failed = false - , self = this; - - Socket.priorWebsocketSuccess = false; - - function onTransportOpen(){ - if (self.onlyBinaryUpgrades) { - var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; - failed = failed || upgradeLosesBinary; - } - if (failed) return; - - debug('probe transport "%s" opened', name); - transport.send([{ type: 'ping', data: 'probe' }]); - transport.once('packet', function (msg) { - if (failed) return; - if ('pong' == msg.type && 'probe' == msg.data) { - debug('probe transport "%s" pong', name); - self.upgrading = true; - self.emit('upgrading', transport); - if (!transport) return; - Socket.priorWebsocketSuccess = 'websocket' == transport.name; - - debug('pausing current transport "%s"', self.transport.name); - self.transport.pause(function () { - if (failed) return; - if ('closed' == self.readyState) return; - debug('changing transport and sending upgrade packet'); - - cleanup(); - - self.setTransport(transport); - transport.send([{ type: 'upgrade' }]); - self.emit('upgrade', transport); - transport = null; - self.upgrading = false; - self.flush(); - }); - } else { - debug('probe transport "%s" failed', name); - var err = new Error('probe error'); - err.transport = transport.name; - self.emit('upgradeError', err); - } - }); - } - - function freezeTransport() { - if (failed) return; - - // Any callback called by transport should be ignored since now - failed = true; - - cleanup(); - - transport.close(); - transport = null; - } - - //Handle any error that happens while probing - function onerror(err) { - var error = new Error('probe error: ' + err); - error.transport = transport.name; - - freezeTransport(); - - debug('probe transport "%s" failed because of error: %s', name, err); - - self.emit('upgradeError', error); - } - - function onTransportClose(){ - onerror("transport closed"); - } - - //When the socket is closed while we're probing - function onclose(){ - onerror("socket closed"); - } - - //When the socket is upgraded while we're probing - function onupgrade(to){ - if (transport && to.name != transport.name) { - debug('"%s" works - aborting "%s"', to.name, transport.name); - freezeTransport(); - } - } - - //Remove all listeners on the transport and on self - function cleanup(){ - transport.removeListener('open', onTransportOpen); - transport.removeListener('error', onerror); - transport.removeListener('close', onTransportClose); - self.removeListener('close', onclose); - self.removeListener('upgrading', onupgrade); - } - - transport.once('open', onTransportOpen); - transport.once('error', onerror); - transport.once('close', onTransportClose); - - this.once('close', onclose); - this.once('upgrading', onupgrade); - - transport.open(); - -}; - -/** - * Called when connection is deemed open. - * - * @api public - */ - -Socket.prototype.onOpen = function () { - debug('socket open'); - this.readyState = 'open'; - Socket.priorWebsocketSuccess = 'websocket' == this.transport.name; - this.emit('open'); - this.flush(); - - // we check for `readyState` in case an `open` - // listener already closed the socket - if ('open' == this.readyState && this.upgrade && this.transport.pause) { - debug('starting upgrade probes'); - for (var i = 0, l = this.upgrades.length; i < l; i++) { - this.probe(this.upgrades[i]); - } - } -}; - -/** - * Handles a packet. - * - * @api private - */ - -Socket.prototype.onPacket = function (packet) { - if ('opening' == this.readyState || 'open' == this.readyState) { - debug('socket receive: type "%s", data "%s"', packet.type, packet.data); - - this.emit('packet', packet); - - // Socket is live - any packet counts - this.emit('heartbeat'); - - switch (packet.type) { - case 'open': - this.onHandshake(parsejson(packet.data)); - break; - - case 'pong': - this.setPing(); - break; - - case 'error': - var err = new Error('server error'); - err.code = packet.data; - this.emit('error', err); - break; - - case 'message': - this.emit('data', packet.data); - this.emit('message', packet.data); - break; - } - } else { - debug('packet received with socket readyState "%s"', this.readyState); - } -}; - -/** - * Called upon handshake completion. - * - * @param {Object} handshake obj - * @api private - */ - -Socket.prototype.onHandshake = function (data) { - this.emit('handshake', data); - this.id = data.sid; - this.transport.query.sid = data.sid; - this.upgrades = this.filterUpgrades(data.upgrades); - this.pingInterval = data.pingInterval; - this.pingTimeout = data.pingTimeout; - this.onOpen(); - // In case open handler closes socket - if ('closed' == this.readyState) return; - this.setPing(); - - // Prolong liveness of socket on heartbeat - this.removeListener('heartbeat', this.onHeartbeat); - this.on('heartbeat', this.onHeartbeat); -}; - -/** - * Resets ping timeout. - * - * @api private - */ - -Socket.prototype.onHeartbeat = function (timeout) { - clearTimeout(this.pingTimeoutTimer); - var self = this; - self.pingTimeoutTimer = setTimeout(function () { - if ('closed' == self.readyState) return; - self.onClose('ping timeout'); - }, timeout || (self.pingInterval + self.pingTimeout)); -}; - -/** - * Pings server every `this.pingInterval` and expects response - * within `this.pingTimeout` or closes connection. - * - * @api private - */ - -Socket.prototype.setPing = function () { - var self = this; - clearTimeout(self.pingIntervalTimer); - self.pingIntervalTimer = setTimeout(function () { - debug('writing ping packet - expecting pong within %sms', self.pingTimeout); - self.ping(); - self.onHeartbeat(self.pingTimeout); - }, self.pingInterval); -}; - -/** -* Sends a ping packet. -* -* @api public -*/ - -Socket.prototype.ping = function () { - this.sendPacket('ping'); -}; - -/** - * Called on `drain` event - * - * @api private - */ - -Socket.prototype.onDrain = function() { - for (var i = 0; i < this.prevBufferLen; i++) { - if (this.callbackBuffer[i]) { - this.callbackBuffer[i](); - } - } - - this.writeBuffer.splice(0, this.prevBufferLen); - this.callbackBuffer.splice(0, this.prevBufferLen); - - // setting prevBufferLen = 0 is very important - // for example, when upgrading, upgrade packet is sent over, - // and a nonzero prevBufferLen could cause problems on `drain` - this.prevBufferLen = 0; - - if (this.writeBuffer.length == 0) { - this.emit('drain'); - } else { - this.flush(); - } -}; - -/** - * Flush write buffers. - * - * @api private - */ - -Socket.prototype.flush = function () { - if ('closed' != this.readyState && this.transport.writable && - !this.upgrading && this.writeBuffer.length) { - debug('flushing %d packets in socket', this.writeBuffer.length); - this.transport.send(this.writeBuffer); - // keep track of current length of writeBuffer - // splice writeBuffer and callbackBuffer on `drain` - this.prevBufferLen = this.writeBuffer.length; - this.emit('flush'); - } -}; - -/** - * Sends a message. - * - * @param {String} message. - * @param {Function} callback function. - * @return {Socket} for chaining. - * @api public - */ - -Socket.prototype.write = -Socket.prototype.send = function (msg, fn) { - this.sendPacket('message', msg, fn); - return this; -}; - -/** - * Sends a packet. - * - * @param {String} packet type. - * @param {String} data. - * @param {Function} callback function. - * @api private - */ - -Socket.prototype.sendPacket = function (type, data, fn) { - if ('closing' == this.readyState || 'closed' == this.readyState) { - return; - } - - var packet = { type: type, data: data }; - this.emit('packetCreate', packet); - this.writeBuffer.push(packet); - this.callbackBuffer.push(fn); - this.flush(); -}; - -/** - * Closes the connection. - * - * @api private - */ - -Socket.prototype.close = function () { - if ('opening' == this.readyState || 'open' == this.readyState) { - this.readyState = 'closing'; - - var self = this; - - function close() { - self.onClose('forced close'); - debug('socket closing - telling transport to close'); - self.transport.close(); - } - - function cleanupAndClose() { - self.removeListener('upgrade', cleanupAndClose); - self.removeListener('upgradeError', cleanupAndClose); - close(); - } - - function waitForUpgrade() { - // wait for upgrade to finish since we can't send packets while pausing a transport - self.once('upgrade', cleanupAndClose); - self.once('upgradeError', cleanupAndClose); - } - - if (this.writeBuffer.length) { - this.once('drain', function() { - if (this.upgrading) { - waitForUpgrade(); - } else { - close(); - } - }); - } else if (this.upgrading) { - waitForUpgrade(); - } else { - close(); - } - } - - return this; -}; - -/** - * Called upon transport error - * - * @api private - */ - -Socket.prototype.onError = function (err) { - debug('socket error %j', err); - Socket.priorWebsocketSuccess = false; - this.emit('error', err); - this.onClose('transport error', err); -}; - -/** - * Called upon transport close. - * - * @api private - */ - -Socket.prototype.onClose = function (reason, desc) { - if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) { - debug('socket close with reason: "%s"', reason); - var self = this; - - // clear timers - clearTimeout(this.pingIntervalTimer); - clearTimeout(this.pingTimeoutTimer); - - // clean buffers in next tick, so developers can still - // grab the buffers on `close` event - setTimeout(function() { - self.writeBuffer = []; - self.callbackBuffer = []; - self.prevBufferLen = 0; - }, 0); - - // stop event from firing again for transport - this.transport.removeAllListeners('close'); - - // ensure transport won't stay open - this.transport.close(); - - // ignore further transport communication - this.transport.removeAllListeners(); - - // set ready state - this.readyState = 'closed'; - - // clear session id - this.id = null; - - // emit close event - this.emit('close', reason, desc); - } -}; - -/** - * Filters upgrades, returning only those matching client transports. - * - * @param {Array} server upgrades - * @api private - * - */ - -Socket.prototype.filterUpgrades = function (upgrades) { - var filteredUpgrades = []; - for (var i = 0, j = upgrades.length; i