微信小程序之stompjs

stompjs接收rabbit推送的消息,三个平台的用法:

H5平台使用:

HTML代码:

<html>
<head>
<title>WebSocket</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="main" style="width: 200px;height: 200px;background-color: antiquewhite;">
<div id="message"></div>
</div>
</body>
<script src="./js/jquery.js"></script>
<!-- stomp协议的客户端脚本 -->
<script src="./js/stomp.js"></script>
<!-- SockJS的客户端脚本 -->
<script src="./js/sockjs.js"></script>
<script type="text/javascript">

/**
/queue/queuename:使用默认转发器订阅/发布消息,默认由stomp自动创建一个持久化队列

/amq/queue/queuename:与/queue/queuename的区别在于队列不由stomp自动进行创建,队列不存在失败

/topic/routing_key:通过amq.topic转发器订阅/发布消息,订阅时默认创建一个临时队列,通过routing_key与topic进行绑定

/temp-queue/xxx:创建一个临时队列(只能在headers中的属性reply-to中使用),可用于发送消息后通过临时队列接收回复消息,接收通过client.onreceive

/exchange/exchangename/[routing_key]:通过转发器订阅/发布消息,转发器需要手动创建

client.subscribe(destination,callback,headers) :订阅消息

client.send(destination,headers,body):发布消息

client.unsubscribe(id):取消订阅,id为订阅时返回的编号

client.onreceive:默认接收回调从临时队列获取消息

*/



var ws = new WebSocket('ws://121.37.105.34:15674/ws');
// var ws = new WebSocket('ws://pay.erpyt.com/ws');
// 获得Stomp client对象
var client = Stomp.over(ws);

// SockJS does not support heart-beat: disable heart-beats
// client.heartbeat.outgoing = 0;
// client.heartbeat.incoming = 0;

// 定义连接成功回调函数
var on_connect = function(x) {
//data.body是接收到的数据
// client.subscribe("/topic/mer-888888.voicemsg", function(data) {
client.subscribe("/topic/HB.voice.2023011000069999999.*", function(data) {
var msg = data.body;
$("#message").append("收到数据:" + msg);
});
};

// 定义错误时回调函数
var on_error = function() {
console.log('error');
};

// 连接RabbitMQ
client.connect('yt', 'yt666888.', on_connect, on_error, '/');


</script>
</html>
View Code

sockjs.js

   1 /* sockjs-client v1.1.4 | http://sockjs.org | MIT license */
   2 (function (f) {
   3     if (typeof exports === "object" && typeof module !== "undefined") {
   4         module.exports = f()
   5     } else if (typeof define === "function" && define.amd) {
   6         define([], f)
   7     } else {
   8         var g;
   9         if (typeof window !== "undefined") {
  10             g = window
  11         } else if (typeof global !== "undefined") {
  12             g = global
  13         } else if (typeof self !== "undefined") {
  14             g = self
  15         } else {
  16             g = this
  17         }
  18         g.SockJS = f()
  19     }
  20 })(function () {
  21     var define, module, exports;
  22     return (function e(t, n, r) {
  23         function s(o, u) {
  24             if (!n[o]) {
  25                 if (!t[o]) {
  26                     var a = typeof require == "function" && require;
  27                     if (!u && a) return a(o, !0);
  28                     if (i) return i(o, !0);
  29                     var f = new Error("Cannot find module '" + o + "'");
  30                     throw f.code = "MODULE_NOT_FOUND", f
  31                 }
  32                 var l = n[o] = {exports: {}};
  33                 t[o][0].call(l.exports, function (e) {
  34                     var n = t[o][1][e];
  35                     return s(n ? n : e)
  36                 }, l, l.exports, e, t, n, r)
  37             }
  38             return n[o].exports
  39         }
  40 
  41         var i = typeof require == "function" && require;
  42         for (var o = 0; o < r.length; o++) s(r[o]);
  43         return s
  44     })({
  45         1: [function (require, module, exports) {
  46             (function (global) {
  47                 'use strict';
  48 
  49                 var transportList = require('./transport-list');
  50 
  51                 module.exports = require('./main')(transportList);
  52 
  53 // TODO can't get rid of this until all servers do
  54                 if ('_sockjs_onload' in global) {
  55                     setTimeout(global._sockjs_onload, 1);
  56                 }
  57 
  58             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  59 
  60         }, {"./main": 14, "./transport-list": 16}],
  61         2: [function (require, module, exports) {
  62             'use strict';
  63 
  64             var inherits = require('inherits')
  65                 , Event = require('./event')
  66             ;
  67 
  68             function CloseEvent() {
  69                 Event.call(this);
  70                 this.initEvent('close', false, false);
  71                 this.wasClean = false;
  72                 this.code = 0;
  73                 this.reason = '';
  74             }
  75 
  76             inherits(CloseEvent, Event);
  77 
  78             module.exports = CloseEvent;
  79 
  80         }, {"./event": 4, "inherits": 57}],
  81         3: [function (require, module, exports) {
  82             'use strict';
  83 
  84             var inherits = require('inherits')
  85                 , EventTarget = require('./eventtarget')
  86             ;
  87 
  88             function EventEmitter() {
  89                 EventTarget.call(this);
  90             }
  91 
  92             inherits(EventEmitter, EventTarget);
  93 
  94             EventEmitter.prototype.removeAllListeners = function (type) {
  95                 if (type) {
  96                     delete this._listeners[type];
  97                 } else {
  98                     this._listeners = {};
  99                 }
 100             };
 101 
 102             EventEmitter.prototype.once = function (type, listener) {
 103                 var self = this
 104                     , fired = false;
 105 
 106                 function g() {
 107                     self.removeListener(type, g);
 108 
 109                     if (!fired) {
 110                         fired = true;
 111                         listener.apply(this, arguments);
 112                     }
 113                 }
 114 
 115                 this.on(type, g);
 116             };
 117 
 118             EventEmitter.prototype.emit = function () {
 119                 var type = arguments[0];
 120                 var listeners = this._listeners[type];
 121                 if (!listeners) {
 122                     return;
 123                 }
 124                 // equivalent of Array.prototype.slice.call(arguments, 1);
 125                 var l = arguments.length;
 126                 var args = new Array(l - 1);
 127                 for (var ai = 1; ai < l; ai++) {
 128                     args[ai - 1] = arguments[ai];
 129                 }
 130                 for (var i = 0; i < listeners.length; i++) {
 131                     listeners[i].apply(this, args);
 132                 }
 133             };
 134 
 135             EventEmitter.prototype.on = EventEmitter.prototype.addListener = EventTarget.prototype.addEventListener;
 136             EventEmitter.prototype.removeListener = EventTarget.prototype.removeEventListener;
 137 
 138             module.exports.EventEmitter = EventEmitter;
 139 
 140         }, {"./eventtarget": 5, "inherits": 57}],
 141         4: [function (require, module, exports) {
 142             'use strict';
 143 
 144             function Event(eventType) {
 145                 this.type = eventType;
 146             }
 147 
 148             Event.prototype.initEvent = function (eventType, canBubble, cancelable) {
 149                 this.type = eventType;
 150                 this.bubbles = canBubble;
 151                 this.cancelable = cancelable;
 152                 this.timeStamp = +new Date();
 153                 return this;
 154             };
 155 
 156             Event.prototype.stopPropagation = function () {
 157             };
 158             Event.prototype.preventDefault = function () {
 159             };
 160 
 161             Event.CAPTURING_PHASE = 1;
 162             Event.AT_TARGET = 2;
 163             Event.BUBBLING_PHASE = 3;
 164 
 165             module.exports = Event;
 166 
 167         }, {}],
 168         5: [function (require, module, exports) {
 169             'use strict';
 170 
 171             /* Simplified implementation of DOM2 EventTarget.
 172  *   http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
 173  */
 174 
 175             function EventTarget() {
 176                 this._listeners = {};
 177             }
 178 
 179             EventTarget.prototype.addEventListener = function (eventType, listener) {
 180                 if (!(eventType in this._listeners)) {
 181                     this._listeners[eventType] = [];
 182                 }
 183                 var arr = this._listeners[eventType];
 184                 // #4
 185                 if (arr.indexOf(listener) === -1) {
 186                     // Make a copy so as not to interfere with a current dispatchEvent.
 187                     arr = arr.concat([listener]);
 188                 }
 189                 this._listeners[eventType] = arr;
 190             };
 191 
 192             EventTarget.prototype.removeEventListener = function (eventType, listener) {
 193                 var arr = this._listeners[eventType];
 194                 if (!arr) {
 195                     return;
 196                 }
 197                 var idx = arr.indexOf(listener);
 198                 if (idx !== -1) {
 199                     if (arr.length > 1) {
 200                         // Make a copy so as not to interfere with a current dispatchEvent.
 201                         this._listeners[eventType] = arr.slice(0, idx).concat(arr.slice(idx + 1));
 202                     } else {
 203                         delete this._listeners[eventType];
 204                     }
 205                     return;
 206                 }
 207             };
 208 
 209             EventTarget.prototype.dispatchEvent = function () {
 210                 var event = arguments[0];
 211                 var t = event.type;
 212                 // equivalent of Array.prototype.slice.call(arguments, 0);
 213                 var args = arguments.length === 1 ? [event] : Array.apply(null, arguments);
 214                 // TODO: This doesn't match the real behavior; per spec, onfoo get
 215                 // their place in line from the /first/ time they're set from
 216                 // non-null. Although WebKit bumps it to the end every time it's
 217                 // set.
 218                 if (this['on' + t]) {
 219                     this['on' + t].apply(this, args);
 220                 }
 221                 if (t in this._listeners) {
 222                     // Grab a reference to the listeners list. removeEventListener may alter the list.
 223                     var listeners = this._listeners[t];
 224                     for (var i = 0; i < listeners.length; i++) {
 225                         listeners[i].apply(this, args);
 226                     }
 227                 }
 228             };
 229 
 230             module.exports = EventTarget;
 231 
 232         }, {}],
 233         6: [function (require, module, exports) {
 234             'use strict';
 235 
 236             var inherits = require('inherits')
 237                 , Event = require('./event')
 238             ;
 239 
 240             function TransportMessageEvent(data) {
 241                 Event.call(this);
 242                 this.initEvent('message', false, false);
 243                 this.data = data;
 244             }
 245 
 246             inherits(TransportMessageEvent, Event);
 247 
 248             module.exports = TransportMessageEvent;
 249 
 250         }, {"./event": 4, "inherits": 57}],
 251         7: [function (require, module, exports) {
 252             'use strict';
 253 
 254             var JSON3 = require('json3')
 255                 , iframeUtils = require('./utils/iframe')
 256             ;
 257 
 258             function FacadeJS(transport) {
 259                 this._transport = transport;
 260                 transport.on('message', this._transportMessage.bind(this));
 261                 transport.on('close', this._transportClose.bind(this));
 262             }
 263 
 264             FacadeJS.prototype._transportClose = function (code, reason) {
 265                 iframeUtils.postMessage('c', JSON3.stringify([code, reason]));
 266             };
 267             FacadeJS.prototype._transportMessage = function (frame) {
 268                 iframeUtils.postMessage('t', frame);
 269             };
 270             FacadeJS.prototype._send = function (data) {
 271                 this._transport.send(data);
 272             };
 273             FacadeJS.prototype._close = function () {
 274                 this._transport.close();
 275                 this._transport.removeAllListeners();
 276             };
 277 
 278             module.exports = FacadeJS;
 279 
 280         }, {"./utils/iframe": 47, "json3": 58}],
 281         8: [function (require, module, exports) {
 282             (function (process) {
 283                 'use strict';
 284 
 285                 var urlUtils = require('./utils/url')
 286                     , eventUtils = require('./utils/event')
 287                     , JSON3 = require('json3')
 288                     , FacadeJS = require('./facade')
 289                     , InfoIframeReceiver = require('./info-iframe-receiver')
 290                     , iframeUtils = require('./utils/iframe')
 291                     , loc = require('./location')
 292                 ;
 293 
 294                 var debug = function () {
 295                 };
 296                 if (process.env.NODE_ENV !== 'production') {
 297                     debug = require('debug')('sockjs-client:iframe-bootstrap');
 298                 }
 299 
 300                 module.exports = function (SockJS, availableTransports) {
 301                     var transportMap = {};
 302                     availableTransports.forEach(function (at) {
 303                         if (at.facadeTransport) {
 304                             transportMap[at.facadeTransport.transportName] = at.facadeTransport;
 305                         }
 306                     });
 307 
 308                     // hard-coded for the info iframe
 309                     // TODO see if we can make this more dynamic
 310                     transportMap[InfoIframeReceiver.transportName] = InfoIframeReceiver;
 311                     var parentOrigin;
 312 
 313                     /* eslint-disable camelcase */
 314                     SockJS.bootstrap_iframe = function () {
 315                         /* eslint-enable camelcase */
 316                         var facade;
 317                         iframeUtils.currentWindowId = loc.hash.slice(1);
 318                         var onMessage = function (e) {
 319                             if (e.source !== parent) {
 320                                 return;
 321                             }
 322                             if (typeof parentOrigin === 'undefined') {
 323                                 parentOrigin = e.origin;
 324                             }
 325                             if (e.origin !== parentOrigin) {
 326                                 return;
 327                             }
 328 
 329                             var iframeMessage;
 330                             try {
 331                                 iframeMessage = JSON3.parse(e.data);
 332                             } catch (ignored) {
 333                                 debug('bad json', e.data);
 334                                 return;
 335                             }
 336 
 337                             if (iframeMessage.windowId !== iframeUtils.currentWindowId) {
 338                                 return;
 339                             }
 340                             switch (iframeMessage.type) {
 341                                 case 's':
 342                                     var p;
 343                                     try {
 344                                         p = JSON3.parse(iframeMessage.data);
 345                                     } catch (ignored) {
 346                                         debug('bad json', iframeMessage.data);
 347                                         break;
 348                                     }
 349                                     var version = p[0];
 350                                     var transport = p[1];
 351                                     var transUrl = p[2];
 352                                     var baseUrl = p[3];
 353                                     debug(version, transport, transUrl, baseUrl);
 354                                     // change this to semver logic
 355                                     if (version !== SockJS.version) {
 356                                         throw new Error('Incompatible SockJS! Main site uses:' +
 357                                             ' "' + version + '", the iframe:' +
 358                                             ' "' + SockJS.version + '".');
 359                                     }
 360 
 361                                     if (!urlUtils.isOriginEqual(transUrl, loc.href) ||
 362                                         !urlUtils.isOriginEqual(baseUrl, loc.href)) {
 363                                         throw new Error('Can\'t connect to different domain from within an ' +
 364                                             'iframe. (' + loc.href + ', ' + transUrl + ', ' + baseUrl + ')');
 365                                     }
 366                                     facade = new FacadeJS(new transportMap[transport](transUrl, baseUrl));
 367                                     break;
 368                                 case 'm':
 369                                     facade._send(iframeMessage.data);
 370                                     break;
 371                                 case 'c':
 372                                     if (facade) {
 373                                         facade._close();
 374                                     }
 375                                     facade = null;
 376                                     break;
 377                             }
 378                         };
 379 
 380                         eventUtils.attachEvent('message', onMessage);
 381 
 382                         // Start
 383                         iframeUtils.postMessage('s');
 384                     };
 385                 };
 386 
 387             }).call(this, {env: {}})
 388 
 389         }, {
 390             "./facade": 7,
 391             "./info-iframe-receiver": 10,
 392             "./location": 13,
 393             "./utils/event": 46,
 394             "./utils/iframe": 47,
 395             "./utils/url": 52,
 396             "debug": 55,
 397             "json3": 58
 398         }],
 399         9: [function (require, module, exports) {
 400             (function (process) {
 401                 'use strict';
 402 
 403                 var EventEmitter = require('events').EventEmitter
 404                     , inherits = require('inherits')
 405                     , JSON3 = require('json3')
 406                     , objectUtils = require('./utils/object')
 407                 ;
 408 
 409                 var debug = function () {
 410                 };
 411                 if (process.env.NODE_ENV !== 'production') {
 412                     debug = require('debug')('sockjs-client:info-ajax');
 413                 }
 414 
 415                 function InfoAjax(url, AjaxObject) {
 416                     EventEmitter.call(this);
 417 
 418                     var self = this;
 419                     var t0 = +new Date();
 420                     this.xo = new AjaxObject('GET', url);
 421 
 422                     this.xo.once('finish', function (status, text) {
 423                         var info, rtt;
 424                         if (status === 200) {
 425                             rtt = (+new Date()) - t0;
 426                             if (text) {
 427                                 try {
 428                                     info = JSON3.parse(text);
 429                                 } catch (e) {
 430                                     debug('bad json', text);
 431                                 }
 432                             }
 433 
 434                             if (!objectUtils.isObject(info)) {
 435                                 info = {};
 436                             }
 437                         }
 438                         self.emit('finish', info, rtt);
 439                         self.removeAllListeners();
 440                     });
 441                 }
 442 
 443                 inherits(InfoAjax, EventEmitter);
 444 
 445                 InfoAjax.prototype.close = function () {
 446                     this.removeAllListeners();
 447                     this.xo.close();
 448                 };
 449 
 450                 module.exports = InfoAjax;
 451 
 452             }).call(this, {env: {}})
 453 
 454         }, {"./utils/object": 49, "debug": 55, "events": 3, "inherits": 57, "json3": 58}],
 455         10: [function (require, module, exports) {
 456             'use strict';
 457 
 458             var inherits = require('inherits')
 459                 , EventEmitter = require('events').EventEmitter
 460                 , JSON3 = require('json3')
 461                 , XHRLocalObject = require('./transport/sender/xhr-local')
 462                 , InfoAjax = require('./info-ajax')
 463             ;
 464 
 465             function InfoReceiverIframe(transUrl) {
 466                 var self = this;
 467                 EventEmitter.call(this);
 468 
 469                 this.ir = new InfoAjax(transUrl, XHRLocalObject);
 470                 this.ir.once('finish', function (info, rtt) {
 471                     self.ir = null;
 472                     self.emit('message', JSON3.stringify([info, rtt]));
 473                 });
 474             }
 475 
 476             inherits(InfoReceiverIframe, EventEmitter);
 477 
 478             InfoReceiverIframe.transportName = 'iframe-info-receiver';
 479 
 480             InfoReceiverIframe.prototype.close = function () {
 481                 if (this.ir) {
 482                     this.ir.close();
 483                     this.ir = null;
 484                 }
 485                 this.removeAllListeners();
 486             };
 487 
 488             module.exports = InfoReceiverIframe;
 489 
 490         }, {"./info-ajax": 9, "./transport/sender/xhr-local": 37, "events": 3, "inherits": 57, "json3": 58}],
 491         11: [function (require, module, exports) {
 492             (function (process, global) {
 493                 'use strict';
 494 
 495                 var EventEmitter = require('events').EventEmitter
 496                     , inherits = require('inherits')
 497                     , JSON3 = require('json3')
 498                     , utils = require('./utils/event')
 499                     , IframeTransport = require('./transport/iframe')
 500                     , InfoReceiverIframe = require('./info-iframe-receiver')
 501                 ;
 502 
 503                 var debug = function () {
 504                 };
 505                 if (process.env.NODE_ENV !== 'production') {
 506                     debug = require('debug')('sockjs-client:info-iframe');
 507                 }
 508 
 509                 function InfoIframe(baseUrl, url) {
 510                     var self = this;
 511                     EventEmitter.call(this);
 512 
 513                     var go = function () {
 514                         var ifr = self.ifr = new IframeTransport(InfoReceiverIframe.transportName, url, baseUrl);
 515 
 516                         ifr.once('message', function (msg) {
 517                             if (msg) {
 518                                 var d;
 519                                 try {
 520                                     d = JSON3.parse(msg);
 521                                 } catch (e) {
 522                                     debug('bad json', msg);
 523                                     self.emit('finish');
 524                                     self.close();
 525                                     return;
 526                                 }
 527 
 528                                 var info = d[0], rtt = d[1];
 529                                 self.emit('finish', info, rtt);
 530                             }
 531                             self.close();
 532                         });
 533 
 534                         ifr.once('close', function () {
 535                             self.emit('finish');
 536                             self.close();
 537                         });
 538                     };
 539 
 540                     // TODO this seems the same as the 'needBody' from transports
 541                     if (!global.document.body) {
 542                         utils.attachEvent('load', go);
 543                     } else {
 544                         go();
 545                     }
 546                 }
 547 
 548                 inherits(InfoIframe, EventEmitter);
 549 
 550                 InfoIframe.enabled = function () {
 551                     return IframeTransport.enabled();
 552                 };
 553 
 554                 InfoIframe.prototype.close = function () {
 555                     if (this.ifr) {
 556                         this.ifr.close();
 557                     }
 558                     this.removeAllListeners();
 559                     this.ifr = null;
 560                 };
 561 
 562                 module.exports = InfoIframe;
 563 
 564             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 565 
 566         }, {
 567             "./info-iframe-receiver": 10,
 568             "./transport/iframe": 22,
 569             "./utils/event": 46,
 570             "debug": 55,
 571             "events": 3,
 572             "inherits": 57,
 573             "json3": 58
 574         }],
 575         12: [function (require, module, exports) {
 576             (function (process) {
 577                 'use strict';
 578 
 579                 var EventEmitter = require('events').EventEmitter
 580                     , inherits = require('inherits')
 581                     , urlUtils = require('./utils/url')
 582                     , XDR = require('./transport/sender/xdr')
 583                     , XHRCors = require('./transport/sender/xhr-cors')
 584                     , XHRLocal = require('./transport/sender/xhr-local')
 585                     , XHRFake = require('./transport/sender/xhr-fake')
 586                     , InfoIframe = require('./info-iframe')
 587                     , InfoAjax = require('./info-ajax')
 588                 ;
 589 
 590                 var debug = function () {
 591                 };
 592                 if (process.env.NODE_ENV !== 'production') {
 593                     debug = require('debug')('sockjs-client:info-receiver');
 594                 }
 595 
 596                 function InfoReceiver(baseUrl, urlInfo) {
 597                     debug(baseUrl);
 598                     var self = this;
 599                     EventEmitter.call(this);
 600 
 601                     setTimeout(function () {
 602                         self.doXhr(baseUrl, urlInfo);
 603                     }, 0);
 604                 }
 605 
 606                 inherits(InfoReceiver, EventEmitter);
 607 
 608 // TODO this is currently ignoring the list of available transports and the whitelist
 609 
 610                 InfoReceiver._getReceiver = function (baseUrl, url, urlInfo) {
 611                     // determine method of CORS support (if needed)
 612                     if (urlInfo.sameOrigin) {
 613                         return new InfoAjax(url, XHRLocal);
 614                     }
 615                     if (XHRCors.enabled) {
 616                         return new InfoAjax(url, XHRCors);
 617                     }
 618                     if (XDR.enabled && urlInfo.sameScheme) {
 619                         return new InfoAjax(url, XDR);
 620                     }
 621                     if (InfoIframe.enabled()) {
 622                         return new InfoIframe(baseUrl, url);
 623                     }
 624                     return new InfoAjax(url, XHRFake);
 625                 };
 626 
 627                 InfoReceiver.prototype.doXhr = function (baseUrl, urlInfo) {
 628                     var self = this
 629                         , url = urlUtils.addPath(baseUrl, '/info')
 630                     ;
 631                     debug('doXhr', url);
 632 
 633                     this.xo = InfoReceiver._getReceiver(baseUrl, url, urlInfo);
 634 
 635                     this.timeoutRef = setTimeout(function () {
 636                         debug('timeout');
 637                         self._cleanup(false);
 638                         self.emit('finish');
 639                     }, InfoReceiver.timeout);
 640 
 641                     this.xo.once('finish', function (info, rtt) {
 642                         debug('finish', info, rtt);
 643                         self._cleanup(true);
 644                         self.emit('finish', info, rtt);
 645                     });
 646                 };
 647 
 648                 InfoReceiver.prototype._cleanup = function (wasClean) {
 649                     debug('_cleanup');
 650                     clearTimeout(this.timeoutRef);
 651                     this.timeoutRef = null;
 652                     if (!wasClean && this.xo) {
 653                         this.xo.close();
 654                     }
 655                     this.xo = null;
 656                 };
 657 
 658                 InfoReceiver.prototype.close = function () {
 659                     debug('close');
 660                     this.removeAllListeners();
 661                     this._cleanup(false);
 662                 };
 663 
 664                 InfoReceiver.timeout = 8000;
 665 
 666                 module.exports = InfoReceiver;
 667 
 668             }).call(this, {env: {}})
 669 
 670         }, {
 671             "./info-ajax": 9,
 672             "./info-iframe": 11,
 673             "./transport/sender/xdr": 34,
 674             "./transport/sender/xhr-cors": 35,
 675             "./transport/sender/xhr-fake": 36,
 676             "./transport/sender/xhr-local": 37,
 677             "./utils/url": 52,
 678             "debug": 55,
 679             "events": 3,
 680             "inherits": 57
 681         }],
 682         13: [function (require, module, exports) {
 683             (function (global) {
 684                 'use strict';
 685 
 686                 module.exports = global.location || {
 687                     origin: 'http://localhost:80'
 688                     , protocol: 'http'
 689                     , host: 'localhost'
 690                     , port: 80
 691                     , href: 'http://localhost/'
 692                     , hash: ''
 693                 };
 694 
 695             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 696 
 697         }, {}],
 698         14: [function (require, module, exports) {
 699             (function (process, global) {
 700                 'use strict';
 701 
 702                 require('./shims');
 703 
 704                 var URL = require('url-parse')
 705                     , inherits = require('inherits')
 706                     , JSON3 = require('json3')
 707                     , random = require('./utils/random')
 708                     , escape = require('./utils/escape')
 709                     , urlUtils = require('./utils/url')
 710                     , eventUtils = require('./utils/event')
 711                     , transport = require('./utils/transport')
 712                     , objectUtils = require('./utils/object')
 713                     , browser = require('./utils/browser')
 714                     , log = require('./utils/log')
 715                     , Event = require('./event/event')
 716                     , EventTarget = require('./event/eventtarget')
 717                     , loc = require('./location')
 718                     , CloseEvent = require('./event/close')
 719                     , TransportMessageEvent = require('./event/trans-message')
 720                     , InfoReceiver = require('./info-receiver')
 721                 ;
 722 
 723                 var debug = function () {
 724                 };
 725                 if (process.env.NODE_ENV !== 'production') {
 726                     debug = require('debug')('sockjs-client:main');
 727                 }
 728 
 729                 var transports;
 730 
 731 // follow constructor steps defined at http://dev.w3.org/html5/websockets/#the-websocket-interface
 732                 function SockJS(url, protocols, options) {
 733                     if (!(this instanceof SockJS)) {
 734                         return new SockJS(url, protocols, options);
 735                     }
 736                     if (arguments.length < 1) {
 737                         throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");
 738                     }
 739                     EventTarget.call(this);
 740 
 741                     this.readyState = SockJS.CONNECTING;
 742                     this.extensions = '';
 743                     this.protocol = '';
 744 
 745                     // non-standard extension
 746                     options = options || {};
 747                     if (options.protocols_whitelist) {
 748                         log.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead.");
 749                     }
 750                     this._transportsWhitelist = options.transports;
 751                     this._transportOptions = options.transportOptions || {};
 752 
 753                     var sessionId = options.sessionId || 8;
 754                     if (typeof sessionId === 'function') {
 755                         this._generateSessionId = sessionId;
 756                     } else if (typeof sessionId === 'number') {
 757                         this._generateSessionId = function () {
 758                             return random.string(sessionId);
 759                         };
 760                     } else {
 761                         throw new TypeError('If sessionId is used in the options, it needs to be a number or a function.');
 762                     }
 763 
 764                     this._server = options.server || random.numberString(1000);
 765 
 766                     // Step 1 of WS spec - parse and validate the url. Issue #8
 767                     var parsedUrl = new URL(url);
 768                     if (!parsedUrl.host || !parsedUrl.protocol) {
 769                         throw new SyntaxError("The URL '" + url + "' is invalid");
 770                     } else if (parsedUrl.hash) {
 771                         throw new SyntaxError('The URL must not contain a fragment');
 772                     } else if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
 773                         throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '" + parsedUrl.protocol + "' is not allowed.");
 774                     }
 775 
 776                     var secure = parsedUrl.protocol === 'https:';
 777                     // Step 2 - don't allow secure origin with an insecure protocol
 778                     if (loc.protocol === 'https' && !secure) {
 779                         throw new Error('SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS');
 780                     }
 781 
 782                     // Step 3 - check port access - no need here
 783                     // Step 4 - parse protocols argument
 784                     if (!protocols) {
 785                         protocols = [];
 786                     } else if (!Array.isArray(protocols)) {
 787                         protocols = [protocols];
 788                     }
 789 
 790                     // Step 5 - check protocols argument
 791                     var sortedProtocols = protocols.sort();
 792                     sortedProtocols.forEach(function (proto, i) {
 793                         if (!proto) {
 794                             throw new SyntaxError("The protocols entry '" + proto + "' is invalid.");
 795                         }
 796                         if (i < (sortedProtocols.length - 1) && proto === sortedProtocols[i + 1]) {
 797                             throw new SyntaxError("The protocols entry '" + proto + "' is duplicated.");
 798                         }
 799                     });
 800 
 801                     // Step 6 - convert origin
 802                     var o = urlUtils.getOrigin(loc.href);
 803                     this._origin = o ? o.toLowerCase() : null;
 804 
 805                     // remove the trailing slash
 806                     parsedUrl.set('pathname', parsedUrl.pathname.replace(/\/+$/, ''));
 807 
 808                     // store the sanitized url
 809                     this.url = parsedUrl.href;
 810                     debug('using url', this.url);
 811 
 812                     // Step 7 - start connection in background
 813                     // obtain server info
 814                     // http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-26
 815                     this._urlInfo = {
 816                         nullOrigin: !browser.hasDomain()
 817                         , sameOrigin: urlUtils.isOriginEqual(this.url, loc.href)
 818                         , sameScheme: urlUtils.isSchemeEqual(this.url, loc.href)
 819                     };
 820 
 821                     this._ir = new InfoReceiver(this.url, this._urlInfo);
 822                     this._ir.once('finish', this._receiveInfo.bind(this));
 823                 }
 824 
 825                 inherits(SockJS, EventTarget);
 826 
 827                 function userSetCode(code) {
 828                     return code === 1000 || (code >= 3000 && code <= 4999);
 829                 }
 830 
 831                 SockJS.prototype.close = function (code, reason) {
 832                     // Step 1
 833                     if (code && !userSetCode(code)) {
 834                         throw new Error('InvalidAccessError: Invalid code');
 835                     }
 836                     // Step 2.4 states the max is 123 bytes, but we are just checking length
 837                     if (reason && reason.length > 123) {
 838                         throw new SyntaxError('reason argument has an invalid length');
 839                     }
 840 
 841                     // Step 3.1
 842                     if (this.readyState === SockJS.CLOSING || this.readyState === SockJS.CLOSED) {
 843                         return;
 844                     }
 845 
 846                     // TODO look at docs to determine how to set this
 847                     var wasClean = true;
 848                     this._close(code || 1000, reason || 'Normal closure', wasClean);
 849                 };
 850 
 851                 SockJS.prototype.send = function (data) {
 852                     // #13 - convert anything non-string to string
 853                     // TODO this currently turns objects into [object Object]
 854                     if (typeof data !== 'string') {
 855                         data = '' + data;
 856                     }
 857                     if (this.readyState === SockJS.CONNECTING) {
 858                         throw new Error('InvalidStateError: The connection has not been established yet');
 859                     }
 860                     if (this.readyState !== SockJS.OPEN) {
 861                         return;
 862                     }
 863                     this._transport.send(escape.quote(data));
 864                 };
 865 
 866                 SockJS.version = require('./version');
 867 
 868                 SockJS.CONNECTING = 0;
 869                 SockJS.OPEN = 1;
 870                 SockJS.CLOSING = 2;
 871                 SockJS.CLOSED = 3;
 872 
 873                 SockJS.prototype._receiveInfo = function (info, rtt) {
 874                     debug('_receiveInfo', rtt);
 875                     this._ir = null;
 876                     if (!info) {
 877                         this._close(1002, 'Cannot connect to server');
 878                         return;
 879                     }
 880 
 881                     // establish a round-trip timeout (RTO) based on the
 882                     // round-trip time (RTT)
 883                     this._rto = this.countRTO(rtt);
 884                     // allow server to override url used for the actual transport
 885                     this._transUrl = info.base_url ? info.base_url : this.url;
 886                     info = objectUtils.extend(info, this._urlInfo);
 887                     debug('info', info);
 888                     // determine list of desired and supported transports
 889                     var enabledTransports = transports.filterToEnabled(this._transportsWhitelist, info);
 890                     this._transports = enabledTransports.main;
 891                     debug(this._transports.length + ' enabled transports');
 892 
 893                     this._connect();
 894                 };
 895 
 896                 SockJS.prototype._connect = function () {
 897                     for (var Transport = this._transports.shift(); Transport; Transport = this._transports.shift()) {
 898                         debug('attempt', Transport.transportName);
 899                         if (Transport.needBody) {
 900                             if (!global.document.body ||
 901                                 (typeof global.document.readyState !== 'undefined' &&
 902                                     global.document.readyState !== 'complete' &&
 903                                     global.document.readyState !== 'interactive')) {
 904                                 debug('waiting for body');
 905                                 this._transports.unshift(Transport);
 906                                 eventUtils.attachEvent('load', this._connect.bind(this));
 907                                 return;
 908                             }
 909                         }
 910 
 911                         // calculate timeout based on RTO and round trips. Default to 5s
 912                         var timeoutMs = (this._rto * Transport.roundTrips) || 5000;
 913                         this._transportTimeoutId = setTimeout(this._transportTimeout.bind(this), timeoutMs);
 914                         debug('using timeout', timeoutMs);
 915 
 916                         var transportUrl = urlUtils.addPath(this._transUrl, '/' + this._server + '/' + this._generateSessionId());
 917                         var options = this._transportOptions[Transport.transportName];
 918                         debug('transport url', transportUrl);
 919                         var transportObj = new Transport(transportUrl, this._transUrl, options);
 920                         transportObj.on('message', this._transportMessage.bind(this));
 921                         transportObj.once('close', this._transportClose.bind(this));
 922                         transportObj.transportName = Transport.transportName;
 923                         this._transport = transportObj;
 924 
 925                         return;
 926                     }
 927                     this._close(2000, 'All transports failed', false);
 928                 };
 929 
 930                 SockJS.prototype._transportTimeout = function () {
 931                     debug('_transportTimeout');
 932                     if (this.readyState === SockJS.CONNECTING) {
 933                         this._transportClose(2007, 'Transport timed out');
 934                     }
 935                 };
 936 
 937                 SockJS.prototype._transportMessage = function (msg) {
 938                     debug('_transportMessage', msg);
 939                     var self = this
 940                         , type = msg.slice(0, 1)
 941                         , content = msg.slice(1)
 942                         , payload
 943                     ;
 944 
 945                     // first check for messages that don't need a payload
 946                     switch (type) {
 947                         case 'o':
 948                             this._open();
 949                             return;
 950                         case 'h':
 951                             this.dispatchEvent(new Event('heartbeat'));
 952                             debug('heartbeat', this.transport);
 953                             return;
 954                     }
 955 
 956                     if (content) {
 957                         try {
 958                             payload = JSON3.parse(content);
 959                         } catch (e) {
 960                             debug('bad json', content);
 961                         }
 962                     }
 963 
 964                     if (typeof payload === 'undefined') {
 965                         debug('empty payload', content);
 966                         return;
 967                     }
 968 
 969                     switch (type) {
 970                         case 'a':
 971                             if (Array.isArray(payload)) {
 972                                 payload.forEach(function (p) {
 973                                     debug('message', self.transport, p);
 974                                     self.dispatchEvent(new TransportMessageEvent(p));
 975                                 });
 976                             }
 977                             break;
 978                         case 'm':
 979                             debug('message', this.transport, payload);
 980                             this.dispatchEvent(new TransportMessageEvent(payload));
 981                             break;
 982                         case 'c':
 983                             if (Array.isArray(payload) && payload.length === 2) {
 984                                 this._close(payload[0], payload[1], true);
 985                             }
 986                             break;
 987                     }
 988                 };
 989 
 990                 SockJS.prototype._transportClose = function (code, reason) {
 991                     debug('_transportClose', this.transport, code, reason);
 992                     if (this._transport) {
 993                         this._transport.removeAllListeners();
 994                         this._transport = null;
 995                         this.transport = null;
 996                     }
 997 
 998                     if (!userSetCode(code) && code !== 2000 && this.readyState === SockJS.CONNECTING) {
 999                         this._connect();
1000                         return;
1001                     }
1002 
1003                     this._close(code, reason);
1004                 };
1005 
1006                 SockJS.prototype._open = function () {
1007                     debug('_open', this._transport.transportName, this.readyState);
1008                     if (this.readyState === SockJS.CONNECTING) {
1009                         if (this._transportTimeoutId) {
1010                             clearTimeout(this._transportTimeoutId);
1011                             this._transportTimeoutId = null;
1012                         }
1013                         this.readyState = SockJS.OPEN;
1014                         this.transport = this._transport.transportName;
1015                         this.dispatchEvent(new Event('open'));
1016                         debug('connected', this.transport);
1017                     } else {
1018                         // The server might have been restarted, and lost track of our
1019                         // connection.
1020                         this._close(1006, 'Server lost session');
1021                     }
1022                 };
1023 
1024                 SockJS.prototype._close = function (code, reason, wasClean) {
1025                     debug('_close', this.transport, code, reason, wasClean, this.readyState);
1026                     var forceFail = false;
1027 
1028                     if (this._ir) {
1029                         forceFail = true;
1030                         this._ir.close();
1031                         this._ir = null;
1032                     }
1033                     if (this._transport) {
1034                         this._transport.close();
1035                         this._transport = null;
1036                         this.transport = null;
1037                     }
1038 
1039                     if (this.readyState === SockJS.CLOSED) {
1040                         throw new Error('InvalidStateError: SockJS has already been closed');
1041                     }
1042 
1043                     this.readyState = SockJS.CLOSING;
1044                     setTimeout(function () {
1045                         this.readyState = SockJS.CLOSED;
1046 
1047                         if (forceFail) {
1048                             this.dispatchEvent(new Event('error'));
1049                         }
1050 
1051                         var e = new CloseEvent('close');
1052                         e.wasClean = wasClean || false;
1053                         e.code = code || 1000;
1054                         e.reason = reason;
1055 
1056                         this.dispatchEvent(e);
1057                         this.onmessage = this.onclose = this.onerror = null;
1058                         debug('disconnected');
1059                     }.bind(this), 0);
1060                 };
1061 
1062 // See: http://www.erg.abdn.ac.uk/~gerrit/dccp/notes/ccid2/rto_estimator/
1063 // and RFC 2988.
1064                 SockJS.prototype.countRTO = function (rtt) {
1065                     // In a local environment, when using IE8/9 and the `jsonp-polling`
1066                     // transport the time needed to establish a connection (the time that pass
1067                     // from the opening of the transport to the call of `_dispatchOpen`) is
1068                     // around 200msec (the lower bound used in the article above) and this
1069                     // causes spurious timeouts. For this reason we calculate a value slightly
1070                     // larger than that used in the article.
1071                     if (rtt > 100) {
1072                         return 4 * rtt; // rto > 400msec
1073                     }
1074                     return 300 + rtt; // 300msec < rto <= 400msec
1075                 };
1076 
1077                 module.exports = function (availableTransports) {
1078                     transports = transport(availableTransports);
1079                     require('./iframe-bootstrap')(SockJS, availableTransports);
1080                     return SockJS;
1081                 };
1082 
1083             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1084 
1085         }, {
1086             "./event/close": 2,
1087             "./event/event": 4,
1088             "./event/eventtarget": 5,
1089             "./event/trans-message": 6,
1090             "./iframe-bootstrap": 8,
1091             "./info-receiver": 12,
1092             "./location": 13,
1093             "./shims": 15,
1094             "./utils/browser": 44,
1095             "./utils/escape": 45,
1096             "./utils/event": 46,
1097             "./utils/log": 48,
1098             "./utils/object": 49,
1099             "./utils/random": 50,
1100             "./utils/transport": 51,
1101             "./utils/url": 52,
1102             "./version": 53,
1103             "debug": 55,
1104             "inherits": 57,
1105             "json3": 58,
1106             "url-parse": 61
1107         }],
1108         15: [function (require, module, exports) {
1109             /* eslint-disable */
1110             /* jscs: disable */
1111             'use strict';
1112 
1113 // pulled specific shims from https://github.com/es-shims/es5-shim
1114 
1115             var ArrayPrototype = Array.prototype;
1116             var ObjectPrototype = Object.prototype;
1117             var FunctionPrototype = Function.prototype;
1118             var StringPrototype = String.prototype;
1119             var array_slice = ArrayPrototype.slice;
1120 
1121             var _toString = ObjectPrototype.toString;
1122             var isFunction = function (val) {
1123                 return ObjectPrototype.toString.call(val) === '[object Function]';
1124             };
1125             var isArray = function isArray(obj) {
1126                 return _toString.call(obj) === '[object Array]';
1127             };
1128             var isString = function isString(obj) {
1129                 return _toString.call(obj) === '[object String]';
1130             };
1131 
1132             var supportsDescriptors = Object.defineProperty && (function () {
1133                 try {
1134                     Object.defineProperty({}, 'x', {});
1135                     return true;
1136                 } catch (e) { /* this is ES3 */
1137                     return false;
1138                 }
1139             }());
1140 
1141 // Define configurable, writable and non-enumerable props
1142 // if they don't exist.
1143             var defineProperty;
1144             if (supportsDescriptors) {
1145                 defineProperty = function (object, name, method, forceAssign) {
1146                     if (!forceAssign && (name in object)) {
1147                         return;
1148                     }
1149                     Object.defineProperty(object, name, {
1150                         configurable: true,
1151                         enumerable: false,
1152                         writable: true,
1153                         value: method
1154                     });
1155                 };
1156             } else {
1157                 defineProperty = function (object, name, method, forceAssign) {
1158                     if (!forceAssign && (name in object)) {
1159                         return;
1160                     }
1161                     object[name] = method;
1162                 };
1163             }
1164             var defineProperties = function (object, map, forceAssign) {
1165                 for (var name in map) {
1166                     if (ObjectPrototype.hasOwnProperty.call(map, name)) {
1167                         defineProperty(object, name, map[name], forceAssign);
1168                     }
1169                 }
1170             };
1171 
1172             var toObject = function (o) {
1173                 if (o == null) { // this matches both null and undefined
1174                     throw new TypeError("can't convert " + o + ' to object');
1175                 }
1176                 return Object(o);
1177             };
1178 
1179 //
1180 // Util
1181 // ======
1182 //
1183 
1184 // ES5 9.4
1185 // http://es5.github.com/#x9.4
1186 // http://jsperf.com/to-integer
1187 
1188             function toInteger(num) {
1189                 var n = +num;
1190                 if (n !== n) { // isNaN
1191                     n = 0;
1192                 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
1193                     n = (n > 0 || -1) * Math.floor(Math.abs(n));
1194                 }
1195                 return n;
1196             }
1197 
1198             function ToUint32(x) {
1199                 return x >>> 0;
1200             }
1201 
1202 //
1203 // Function
1204 // ========
1205 //
1206 
1207 // ES-5 15.3.4.5
1208 // http://es5.github.com/#x15.3.4.5
1209 
1210             function Empty() {
1211             }
1212 
1213             defineProperties(FunctionPrototype, {
1214                 bind: function bind(that) { // .length is 1
1215                     // 1. Let Target be the this value.
1216                     var target = this;
1217                     // 2. If IsCallable(Target) is false, throw a TypeError exception.
1218                     if (!isFunction(target)) {
1219                         throw new TypeError('Function.prototype.bind called on incompatible ' + target);
1220                     }
1221                     // 3. Let A be a new (possibly empty) internal list of all of the
1222                     //   argument values provided after thisArg (arg1, arg2 etc), in order.
1223                     // XXX slicedArgs will stand in for "A" if used
1224                     var args = array_slice.call(arguments, 1); // for normal call
1225                     // 4. Let F be a new native ECMAScript object.
1226                     // 11. Set the [[Prototype]] internal property of F to the standard
1227                     //   built-in Function prototype object as specified in 15.3.3.1.
1228                     // 12. Set the [[Call]] internal property of F as described in
1229                     //   15.3.4.5.1.
1230                     // 13. Set the [[Construct]] internal property of F as described in
1231                     //   15.3.4.5.2.
1232                     // 14. Set the [[HasInstance]] internal property of F as described in
1233                     //   15.3.4.5.3.
1234                     var binder = function () {
1235 
1236                         if (this instanceof bound) {
1237                             // 15.3.4.5.2 [[Construct]]
1238                             // When the [[Construct]] internal method of a function object,
1239                             // F that was created using the bind function is called with a
1240                             // list of arguments ExtraArgs, the following steps are taken:
1241                             // 1. Let target be the value of F's [[TargetFunction]]
1242                             //   internal property.
1243                             // 2. If target has no [[Construct]] internal method, a
1244                             //   TypeError exception is thrown.
1245                             // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
1246                             //   property.
1247                             // 4. Let args be a new list containing the same values as the
1248                             //   list boundArgs in the same order followed by the same
1249                             //   values as the list ExtraArgs in the same order.
1250                             // 5. Return the result of calling the [[Construct]] internal
1251                             //   method of target providing args as the arguments.
1252 
1253                             var result = target.apply(
1254                                 this,
1255                                 args.concat(array_slice.call(arguments))
1256                             );
1257                             if (Object(result) === result) {
1258                                 return result;
1259                             }
1260                             return this;
1261 
1262                         } else {
1263                             // 15.3.4.5.1 [[Call]]
1264                             // When the [[Call]] internal method of a function object, F,
1265                             // which was created using the bind function is called with a
1266                             // this value and a list of arguments ExtraArgs, the following
1267                             // steps are taken:
1268                             // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
1269                             //   property.
1270                             // 2. Let boundThis be the value of F's [[BoundThis]] internal
1271                             //   property.
1272                             // 3. Let target be the value of F's [[TargetFunction]] internal
1273                             //   property.
1274                             // 4. Let args be a new list containing the same values as the
1275                             //   list boundArgs in the same order followed by the same
1276                             //   values as the list ExtraArgs in the same order.
1277                             // 5. Return the result of calling the [[Call]] internal method
1278                             //   of target providing boundThis as the this value and
1279                             //   providing args as the arguments.
1280 
1281                             // equiv: target.call(this, ...boundArgs, ...args)
1282                             return target.apply(
1283                                 that,
1284                                 args.concat(array_slice.call(arguments))
1285                             );
1286 
1287                         }
1288 
1289                     };
1290 
1291                     // 15. If the [[Class]] internal property of Target is "Function", then
1292                     //     a. Let L be the length property of Target minus the length of A.
1293                     //     b. Set the length own property of F to either 0 or L, whichever is
1294                     //       larger.
1295                     // 16. Else set the length own property of F to 0.
1296 
1297                     var boundLength = Math.max(0, target.length - args.length);
1298 
1299                     // 17. Set the attributes of the length own property of F to the values
1300                     //   specified in 15.3.5.1.
1301                     var boundArgs = [];
1302                     for (var i = 0; i < boundLength; i++) {
1303                         boundArgs.push('$' + i);
1304                     }
1305 
1306                     // XXX Build a dynamic function with desired amount of arguments is the only
1307                     // way to set the length property of a function.
1308                     // In environments where Content Security Policies enabled (Chrome extensions,
1309                     // for ex.) all use of eval or Function costructor throws an exception.
1310                     // However in all of these environments Function.prototype.bind exists
1311                     // and so this code will never be executed.
1312                     var bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
1313 
1314                     if (target.prototype) {
1315                         Empty.prototype = target.prototype;
1316                         bound.prototype = new Empty();
1317                         // Clean up dangling references.
1318                         Empty.prototype = null;
1319                     }
1320 
1321                     // TODO
1322                     // 18. Set the [[Extensible]] internal property of F to true.
1323 
1324                     // TODO
1325                     // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
1326                     // 20. Call the [[DefineOwnProperty]] internal method of F with
1327                     //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
1328                     //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
1329                     //   false.
1330                     // 21. Call the [[DefineOwnProperty]] internal method of F with
1331                     //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
1332                     //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
1333                     //   and false.
1334 
1335                     // TODO
1336                     // NOTE Function objects created using Function.prototype.bind do not
1337                     // have a prototype property or the [[Code]], [[FormalParameters]], and
1338                     // [[Scope]] internal properties.
1339                     // XXX can't delete prototype in pure-js.
1340 
1341                     // 22. Return F.
1342                     return bound;
1343                 }
1344             });
1345 
1346 //
1347 // Array
1348 // =====
1349 //
1350 
1351 // ES5 15.4.3.2
1352 // http://es5.github.com/#x15.4.3.2
1353 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
1354             defineProperties(Array, {isArray: isArray});
1355 
1356 
1357             var boxedString = Object('a');
1358             var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
1359 
1360             var properlyBoxesContext = function properlyBoxed(method) {
1361                 // Check node 0.6.21 bug where third parameter is not boxed
1362                 var properlyBoxesNonStrict = true;
1363                 var properlyBoxesStrict = true;
1364                 if (method) {
1365                     method.call('foo', function (_, __, context) {
1366                         if (typeof context !== 'object') {
1367                             properlyBoxesNonStrict = false;
1368                         }
1369                     });
1370 
1371                     method.call([1], function () {
1372                         'use strict';
1373                         properlyBoxesStrict = typeof this === 'string';
1374                     }, 'x');
1375                 }
1376                 return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
1377             };
1378 
1379             defineProperties(ArrayPrototype, {
1380                 forEach: function forEach(fun /*, thisp*/) {
1381                     var object = toObject(this),
1382                         self = splitString && isString(this) ? this.split('') : object,
1383                         thisp = arguments[1],
1384                         i = -1,
1385                         length = self.length >>> 0;
1386 
1387                     // If no callback function or if callback is not a callable function
1388                     if (!isFunction(fun)) {
1389                         throw new TypeError(); // TODO message
1390                     }
1391 
1392                     while (++i < length) {
1393                         if (i in self) {
1394                             // Invoke the callback function with call, passing arguments:
1395                             // context, property value, property key, thisArg object
1396                             // context
1397                             fun.call(thisp, self[i], i, object);
1398                         }
1399                     }
1400                 }
1401             }, !properlyBoxesContext(ArrayPrototype.forEach));
1402 
1403 // ES5 15.4.4.14
1404 // http://es5.github.com/#x15.4.4.14
1405 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
1406             var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
1407             defineProperties(ArrayPrototype, {
1408                 indexOf: function indexOf(sought /*, fromIndex */) {
1409                     var self = splitString && isString(this) ? this.split('') : toObject(this),
1410                         length = self.length >>> 0;
1411 
1412                     if (!length) {
1413                         return -1;
1414                     }
1415 
1416                     var i = 0;
1417                     if (arguments.length > 1) {
1418                         i = toInteger(arguments[1]);
1419                     }
1420 
1421                     // handle negative indices
1422                     i = i >= 0 ? i : Math.max(0, length + i);
1423                     for (; i < length; i++) {
1424                         if (i in self && self[i] === sought) {
1425                             return i;
1426                         }
1427                     }
1428                     return -1;
1429                 }
1430             }, hasFirefox2IndexOfBug);
1431 
1432 //
1433 // String
1434 // ======
1435 //
1436 
1437 // ES5 15.5.4.14
1438 // http://es5.github.com/#x15.5.4.14
1439 
1440 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1441 // Many browsers do not split properly with regular expressions or they
1442 // do not perform the split correctly under obscure conditions.
1443 // See http://blog.stevenlevithan.com/archives/cross-browser-split
1444 // I've tested in many browsers and this seems to cover the deviant ones:
1445 //    'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1446 //    '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1447 //    'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1448 //       [undefined, "t", undefined, "e", ...]
1449 //    ''.split(/.?/) should be [], not [""]
1450 //    '.'.split(/()()/) should be ["."], not ["", "", "."]
1451 
1452             var string_split = StringPrototype.split;
1453             if (
1454                 'ab'.split(/(?:ab)*/).length !== 2 ||
1455                 '.'.split(/(.?)(.?)/).length !== 4 ||
1456                 'tesst'.split(/(s)*/)[1] === 't' ||
1457                 'test'.split(/(?:)/, -1).length !== 4 ||
1458                 ''.split(/.?/).length ||
1459                 '.'.split(/()()/).length > 1
1460             ) {
1461                 (function () {
1462                     var compliantExecNpcg = /()??/.exec('')[1] === void 0; // NPCG: nonparticipating capturing group
1463 
1464                     StringPrototype.split = function (separator, limit) {
1465                         var string = this;
1466                         if (separator === void 0 && limit === 0) {
1467                             return [];
1468                         }
1469 
1470                         // If `separator` is not a regex, use native split
1471                         if (_toString.call(separator) !== '[object RegExp]') {
1472                             return string_split.call(this, separator, limit);
1473                         }
1474 
1475                         var output = [],
1476                             flags = (separator.ignoreCase ? 'i' : '') +
1477                                 (separator.multiline ? 'm' : '') +
1478                                 (separator.extended ? 'x' : '') + // Proposed for ES6
1479                                 (separator.sticky ? 'y' : ''), // Firefox 3+
1480                             lastLastIndex = 0,
1481                             // Make `global` and avoid `lastIndex` issues by working with a copy
1482                             separator2, match, lastIndex, lastLength;
1483                         separator = new RegExp(separator.source, flags + 'g');
1484                         string += ''; // Type-convert
1485                         if (!compliantExecNpcg) {
1486                             // Doesn't need flags gy, but they don't hurt
1487                             separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags);
1488                         }
1489                         /* Values for `limit`, per the spec:
1490              * If undefined: 4294967295 // Math.pow(2, 32) - 1
1491              * If 0, Infinity, or NaN: 0
1492              * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1493              * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1494              * If other: Type-convert, then use the above rules
1495              */
1496                         limit = limit === void 0 ?
1497                             -1 >>> 0 : // Math.pow(2, 32) - 1
1498                             ToUint32(limit);
1499                         while (match = separator.exec(string)) {
1500                             // `separator.lastIndex` is not reliable cross-browser
1501                             lastIndex = match.index + match[0].length;
1502                             if (lastIndex > lastLastIndex) {
1503                                 output.push(string.slice(lastLastIndex, match.index));
1504                                 // Fix browsers whose `exec` methods don't consistently return `undefined` for
1505                                 // nonparticipating capturing groups
1506                                 if (!compliantExecNpcg && match.length > 1) {
1507                                     match[0].replace(separator2, function () {
1508                                         for (var i = 1; i < arguments.length - 2; i++) {
1509                                             if (arguments[i] === void 0) {
1510                                                 match[i] = void 0;
1511                                             }
1512                                         }
1513                                     });
1514                                 }
1515                                 if (match.length > 1 && match.index < string.length) {
1516                                     ArrayPrototype.push.apply(output, match.slice(1));
1517                                 }
1518                                 lastLength = match[0].length;
1519                                 lastLastIndex = lastIndex;
1520                                 if (output.length >= limit) {
1521                                     break;
1522                                 }
1523                             }
1524                             if (separator.lastIndex === match.index) {
1525                                 separator.lastIndex++; // Avoid an infinite loop
1526                             }
1527                         }
1528                         if (lastLastIndex === string.length) {
1529                             if (lastLength || !separator.test('')) {
1530                                 output.push('');
1531                             }
1532                         } else {
1533                             output.push(string.slice(lastLastIndex));
1534                         }
1535                         return output.length > limit ? output.slice(0, limit) : output;
1536                     };
1537                 }());
1538 
1539 // [bugfix, chrome]
1540 // If separator is undefined, then the result array contains just one String,
1541 // which is the this value (converted to a String). If limit is not undefined,
1542 // then the output array is truncated so that it contains no more than limit
1543 // elements.
1544 // "0".split(undefined, 0) -> []
1545             } else if ('0'.split(void 0, 0).length) {
1546                 StringPrototype.split = function split(separator, limit) {
1547                     if (separator === void 0 && limit === 0) {
1548                         return [];
1549                     }
1550                     return string_split.call(this, separator, limit);
1551                 };
1552             }
1553 
1554 // ECMA-262, 3rd B.2.3
1555 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1556 // non-normative section suggesting uniform semantics and it should be
1557 // normalized across all browsers
1558 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1559             var string_substr = StringPrototype.substr;
1560             var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
1561             defineProperties(StringPrototype, {
1562                 substr: function substr(start, length) {
1563                     return string_substr.call(
1564                         this,
1565                         start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
1566                         length
1567                     );
1568                 }
1569             }, hasNegativeSubstrBug);
1570 
1571         }, {}],
1572         16: [function (require, module, exports) {
1573             'use strict';
1574 
1575             module.exports = [
1576                 // streaming transports
1577                 require('./transport/websocket')
1578                 , require('./transport/xhr-streaming')
1579                 , require('./transport/xdr-streaming')
1580                 , require('./transport/eventsource')
1581                 , require('./transport/lib/iframe-wrap')(require('./transport/eventsource'))
1582 
1583                 // polling transports
1584                 , require('./transport/htmlfile')
1585                 , require('./transport/lib/iframe-wrap')(require('./transport/htmlfile'))
1586                 , require('./transport/xhr-polling')
1587                 , require('./transport/xdr-polling')
1588                 , require('./transport/lib/iframe-wrap')(require('./transport/xhr-polling'))
1589                 , require('./transport/jsonp-polling')
1590             ];
1591 
1592         }, {
1593             "./transport/eventsource": 20,
1594             "./transport/htmlfile": 21,
1595             "./transport/jsonp-polling": 23,
1596             "./transport/lib/iframe-wrap": 26,
1597             "./transport/websocket": 38,
1598             "./transport/xdr-polling": 39,
1599             "./transport/xdr-streaming": 40,
1600             "./transport/xhr-polling": 41,
1601             "./transport/xhr-streaming": 42
1602         }],
1603         17: [function (require, module, exports) {
1604             (function (process, global) {
1605                 'use strict';
1606 
1607                 var EventEmitter = require('events').EventEmitter
1608                     , inherits = require('inherits')
1609                     , utils = require('../../utils/event')
1610                     , urlUtils = require('../../utils/url')
1611                     , XHR = global.XMLHttpRequest
1612                 ;
1613 
1614                 var debug = function () {
1615                 };
1616                 if (process.env.NODE_ENV !== 'production') {
1617                     debug = require('debug')('sockjs-client:browser:xhr');
1618                 }
1619 
1620                 function AbstractXHRObject(method, url, payload, opts) {
1621                     debug(method, url);
1622                     var self = this;
1623                     EventEmitter.call(this);
1624 
1625                     setTimeout(function () {
1626                         self._start(method, url, payload, opts);
1627                     }, 0);
1628                 }
1629 
1630                 inherits(AbstractXHRObject, EventEmitter);
1631 
1632                 AbstractXHRObject.prototype._start = function (method, url, payload, opts) {
1633                     var self = this;
1634 
1635                     try {
1636                         this.xhr = new XHR();
1637                     } catch (x) {
1638                         // intentionally empty
1639                     }
1640 
1641                     if (!this.xhr) {
1642                         debug('no xhr');
1643                         this.emit('finish', 0, 'no xhr support');
1644                         this._cleanup();
1645                         return;
1646                     }
1647 
1648                     // several browsers cache POSTs
1649                     url = urlUtils.addQuery(url, 't=' + (+new Date()));
1650 
1651                     // Explorer tends to keep connection open, even after the
1652                     // tab gets closed: http://bugs.jquery.com/ticket/5280
1653                     this.unloadRef = utils.unloadAdd(function () {
1654                         debug('unload cleanup');
1655                         self._cleanup(true);
1656                     });
1657                     try {
1658                         this.xhr.open(method, url, true);
1659                         if (this.timeout && 'timeout' in this.xhr) {
1660                             this.xhr.timeout = this.timeout;
1661                             this.xhr.ontimeout = function () {
1662                                 debug('xhr timeout');
1663                                 self.emit('finish', 0, '');
1664                                 self._cleanup(false);
1665                             };
1666                         }
1667                     } catch (e) {
1668                         debug('exception', e);
1669                         // IE raises an exception on wrong port.
1670                         this.emit('finish', 0, '');
1671                         this._cleanup(false);
1672                         return;
1673                     }
1674 
1675                     if ((!opts || !opts.noCredentials) && AbstractXHRObject.supportsCORS) {
1676                         debug('withCredentials');
1677                         // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest :
1678                         // "This never affects same-site requests."
1679 
1680                         this.xhr.withCredentials = 'true';
1681                     }
1682                     if (opts && opts.headers) {
1683                         for (var key in opts.headers) {
1684                             this.xhr.setRequestHeader(key, opts.headers[key]);
1685                         }
1686                     }
1687 
1688                     this.xhr.onreadystatechange = function () {
1689                         if (self.xhr) {
1690                             var x = self.xhr;
1691                             var text, status;
1692                             debug('readyState', x.readyState);
1693                             switch (x.readyState) {
1694                                 case 3:
1695                                     // IE doesn't like peeking into responseText or status
1696                                     // on Microsoft.XMLHTTP and readystate=3
1697                                     try {
1698                                         status = x.status;
1699                                         text = x.responseText;
1700                                     } catch (e) {
1701                                         // intentionally empty
1702                                     }
1703                                     debug('status', status);
1704                                     // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450
1705                                     if (status === 1223) {
1706                                         status = 204;
1707                                     }
1708 
1709                                     // IE does return readystate == 3 for 404 answers.
1710                                     if (status === 200 && text && text.length > 0) {
1711                                         debug('chunk');
1712                                         self.emit('chunk', status, text);
1713                                     }
1714                                     break;
1715                                 case 4:
1716                                     status = x.status;
1717                                     debug('status', status);
1718                                     // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450
1719                                     if (status === 1223) {
1720                                         status = 204;
1721                                     }
1722                                     // IE returns this for a bad port
1723                                     // http://msdn.microsoft.com/en-us/library/windows/desktop/aa383770(v=vs.85).aspx
1724                                     if (status === 12005 || status === 12029) {
1725                                         status = 0;
1726                                     }
1727 
1728                                     debug('finish', status, x.responseText);
1729                                     self.emit('finish', status, x.responseText);
1730                                     self._cleanup(false);
1731                                     break;
1732                             }
1733                         }
1734                     };
1735 
1736                     try {
1737                         self.xhr.send(payload);
1738                     } catch (e) {
1739                         self.emit('finish', 0, '');
1740                         self._cleanup(false);
1741                     }
1742                 };
1743 
1744                 AbstractXHRObject.prototype._cleanup = function (abort) {
1745                     debug('cleanup');
1746                     if (!this.xhr) {
1747                         return;
1748                     }
1749                     this.removeAllListeners();
1750                     utils.unloadDel(this.unloadRef);
1751 
1752                     // IE needs this field to be a function
1753                     this.xhr.onreadystatechange = function () {
1754                     };
1755                     if (this.xhr.ontimeout) {
1756                         this.xhr.ontimeout = null;
1757                     }
1758 
1759                     if (abort) {
1760                         try {
1761                             this.xhr.abort();
1762                         } catch (x) {
1763                             // intentionally empty
1764                         }
1765                     }
1766                     this.unloadRef = this.xhr = null;
1767                 };
1768 
1769                 AbstractXHRObject.prototype.close = function () {
1770                     debug('close');
1771                     this._cleanup(true);
1772                 };
1773 
1774                 AbstractXHRObject.enabled = !!XHR;
1775 // override XMLHttpRequest for IE6/7
1776 // obfuscate to avoid firewalls
1777                 var axo = ['Active'].concat('Object').join('X');
1778                 if (!AbstractXHRObject.enabled && (axo in global)) {
1779                     debug('overriding xmlhttprequest');
1780                     XHR = function () {
1781                         try {
1782                             return new global[axo]('Microsoft.XMLHTTP');
1783                         } catch (e) {
1784                             return null;
1785                         }
1786                     };
1787                     AbstractXHRObject.enabled = !!new XHR();
1788                 }
1789 
1790                 var cors = false;
1791                 try {
1792                     cors = 'withCredentials' in new XHR();
1793                 } catch (ignored) {
1794                     // intentionally empty
1795                 }
1796 
1797                 AbstractXHRObject.supportsCORS = cors;
1798 
1799                 module.exports = AbstractXHRObject;
1800 
1801             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1802 
1803         }, {"../../utils/event": 46, "../../utils/url": 52, "debug": 55, "events": 3, "inherits": 57}],
1804         18: [function (require, module, exports) {
1805             (function (global) {
1806                 module.exports = global.EventSource;
1807 
1808             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1809 
1810         }, {}],
1811         19: [function (require, module, exports) {
1812             (function (global) {
1813                 'use strict';
1814 
1815                 var Driver = global.WebSocket || global.MozWebSocket;
1816                 if (Driver) {
1817                     module.exports = function WebSocketBrowserDriver(url) {
1818                         return new Driver(url);
1819                     };
1820                 } else {
1821                     module.exports = undefined;
1822                 }
1823 
1824             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1825 
1826         }, {}],
1827         20: [function (require, module, exports) {
1828             'use strict';
1829 
1830             var inherits = require('inherits')
1831                 , AjaxBasedTransport = require('./lib/ajax-based')
1832                 , EventSourceReceiver = require('./receiver/eventsource')
1833                 , XHRCorsObject = require('./sender/xhr-cors')
1834                 , EventSourceDriver = require('eventsource')
1835             ;
1836 
1837             function EventSourceTransport(transUrl) {
1838                 if (!EventSourceTransport.enabled()) {
1839                     throw new Error('Transport created when disabled');
1840                 }
1841 
1842                 AjaxBasedTransport.call(this, transUrl, '/eventsource', EventSourceReceiver, XHRCorsObject);
1843             }
1844 
1845             inherits(EventSourceTransport, AjaxBasedTransport);
1846 
1847             EventSourceTransport.enabled = function () {
1848                 return !!EventSourceDriver;
1849             };
1850 
1851             EventSourceTransport.transportName = 'eventsource';
1852             EventSourceTransport.roundTrips = 2;
1853 
1854             module.exports = EventSourceTransport;
1855 
1856         }, {
1857             "./lib/ajax-based": 24,
1858             "./receiver/eventsource": 29,
1859             "./sender/xhr-cors": 35,
1860             "eventsource": 18,
1861             "inherits": 57
1862         }],
1863         21: [function (require, module, exports) {
1864             'use strict';
1865 
1866             var inherits = require('inherits')
1867                 , HtmlfileReceiver = require('./receiver/htmlfile')
1868                 , XHRLocalObject = require('./sender/xhr-local')
1869                 , AjaxBasedTransport = require('./lib/ajax-based')
1870             ;
1871 
1872             function HtmlFileTransport(transUrl) {
1873                 if (!HtmlfileReceiver.enabled) {
1874                     throw new Error('Transport created when disabled');
1875                 }
1876                 AjaxBasedTransport.call(this, transUrl, '/htmlfile', HtmlfileReceiver, XHRLocalObject);
1877             }
1878 
1879             inherits(HtmlFileTransport, AjaxBasedTransport);
1880 
1881             HtmlFileTransport.enabled = function (info) {
1882                 return HtmlfileReceiver.enabled && info.sameOrigin;
1883             };
1884 
1885             HtmlFileTransport.transportName = 'htmlfile';
1886             HtmlFileTransport.roundTrips = 2;
1887 
1888             module.exports = HtmlFileTransport;
1889 
1890         }, {"./lib/ajax-based": 24, "./receiver/htmlfile": 30, "./sender/xhr-local": 37, "inherits": 57}],
1891         22: [function (require, module, exports) {
1892             (function (process) {
1893                 'use strict';
1894 
1895 // Few cool transports do work only for same-origin. In order to make
1896 // them work cross-domain we shall use iframe, served from the
1897 // remote domain. New browsers have capabilities to communicate with
1898 // cross domain iframe using postMessage(). In IE it was implemented
1899 // from IE 8+, but of course, IE got some details wrong:
1900 //    http://msdn.microsoft.com/en-us/library/cc197015(v=VS.85).aspx
1901 //    http://stevesouders.com/misc/test-postmessage.php
1902 
1903                 var inherits = require('inherits')
1904                     , JSON3 = require('json3')
1905                     , EventEmitter = require('events').EventEmitter
1906                     , version = require('../version')
1907                     , urlUtils = require('../utils/url')
1908                     , iframeUtils = require('../utils/iframe')
1909                     , eventUtils = require('../utils/event')
1910                     , random = require('../utils/random')
1911                 ;
1912 
1913                 var debug = function () {
1914                 };
1915                 if (process.env.NODE_ENV !== 'production') {
1916                     debug = require('debug')('sockjs-client:transport:iframe');
1917                 }
1918 
1919                 function IframeTransport(transport, transUrl, baseUrl) {
1920                     if (!IframeTransport.enabled()) {
1921                         throw new Error('Transport created when disabled');
1922                     }
1923                     EventEmitter.call(this);
1924 
1925                     var self = this;
1926                     this.origin = urlUtils.getOrigin(baseUrl);
1927                     this.baseUrl = baseUrl;
1928                     this.transUrl = transUrl;
1929                     this.transport = transport;
1930                     this.windowId = random.string(8);
1931 
1932                     var iframeUrl = urlUtils.addPath(baseUrl, '/iframe.html') + '#' + this.windowId;
1933                     debug(transport, transUrl, iframeUrl);
1934 
1935                     this.iframeObj = iframeUtils.createIframe(iframeUrl, function (r) {
1936                         debug('err callback');
1937                         self.emit('close', 1006, 'Unable to load an iframe (' + r + ')');
1938                         self.close();
1939                     });
1940 
1941                     this.onmessageCallback = this._message.bind(this);
1942                     eventUtils.attachEvent('message', this.onmessageCallback);
1943                 }
1944 
1945                 inherits(IframeTransport, EventEmitter);
1946 
1947                 IframeTransport.prototype.close = function () {
1948                     debug('close');
1949                     this.removeAllListeners();
1950                     if (this.iframeObj) {
1951                         eventUtils.detachEvent('message', this.onmessageCallback);
1952                         try {
1953                             // When the iframe is not loaded, IE raises an exception
1954                             // on 'contentWindow'.
1955                             this.postMessage('c');
1956                         } catch (x) {
1957                             // intentionally empty
1958                         }
1959                         this.iframeObj.cleanup();
1960                         this.iframeObj = null;
1961                         this.onmessageCallback = this.iframeObj = null;
1962                     }
1963                 };
1964 
1965                 IframeTransport.prototype._message = function (e) {
1966                     debug('message', e.data);
1967                     if (!urlUtils.isOriginEqual(e.origin, this.origin)) {
1968                         debug('not same origin', e.origin, this.origin);
1969                         return;
1970                     }
1971 
1972                     var iframeMessage;
1973                     try {
1974                         iframeMessage = JSON3.parse(e.data);
1975                     } catch (ignored) {
1976                         debug('bad json', e.data);
1977                         return;
1978                     }
1979 
1980                     if (iframeMessage.windowId !== this.windowId) {
1981                         debug('mismatched window id', iframeMessage.windowId, this.windowId);
1982                         return;
1983                     }
1984 
1985                     switch (iframeMessage.type) {
1986                         case 's':
1987                             this.iframeObj.loaded();
1988                             // window global dependency
1989                             this.postMessage('s', JSON3.stringify([
1990                                 version
1991                                 , this.transport
1992                                 , this.transUrl
1993                                 , this.baseUrl
1994                             ]));
1995                             break;
1996                         case 't':
1997                             this.emit('message', iframeMessage.data);
1998                             break;
1999                         case 'c':
2000                             var cdata;
2001                             try {
2002                                 cdata = JSON3.parse(iframeMessage.data);
2003                             } catch (ignored) {
2004                                 debug('bad json', iframeMessage.data);
2005                                 return;
2006                             }
2007                             this.emit('close', cdata[0], cdata[1]);
2008                             this.close();
2009                             break;
2010                     }
2011                 };
2012 
2013                 IframeTransport.prototype.postMessage = function (type, data) {
2014                     debug('postMessage', type, data);
2015                     this.iframeObj.post(JSON3.stringify({
2016                         windowId: this.windowId
2017                         , type: type
2018                         , data: data || ''
2019                     }), this.origin);
2020                 };
2021 
2022                 IframeTransport.prototype.send = function (message) {
2023                     debug('send', message);
2024                     this.postMessage('m', message);
2025                 };
2026 
2027                 IframeTransport.enabled = function () {
2028                     return iframeUtils.iframeEnabled;
2029                 };
2030 
2031                 IframeTransport.transportName = 'iframe';
2032                 IframeTransport.roundTrips = 2;
2033 
2034                 module.exports = IframeTransport;
2035 
2036             }).call(this, {env: {}})
2037 
2038         }, {
2039             "../utils/event": 46,
2040             "../utils/iframe": 47,
2041             "../utils/random": 50,
2042             "../utils/url": 52,
2043             "../version": 53,
2044             "debug": 55,
2045             "events": 3,
2046             "inherits": 57,
2047             "json3": 58
2048         }],
2049         23: [function (require, module, exports) {
2050             (function (global) {
2051                 'use strict';
2052 
2053 // The simplest and most robust transport, using the well-know cross
2054 // domain hack - JSONP. This transport is quite inefficient - one
2055 // message could use up to one http request. But at least it works almost
2056 // everywhere.
2057 // Known limitations:
2058 //   o you will get a spinning cursor
2059 //   o for Konqueror a dumb timer is needed to detect errors
2060 
2061                 var inherits = require('inherits')
2062                     , SenderReceiver = require('./lib/sender-receiver')
2063                     , JsonpReceiver = require('./receiver/jsonp')
2064                     , jsonpSender = require('./sender/jsonp')
2065                 ;
2066 
2067                 function JsonPTransport(transUrl) {
2068                     if (!JsonPTransport.enabled()) {
2069                         throw new Error('Transport created when disabled');
2070                     }
2071                     SenderReceiver.call(this, transUrl, '/jsonp', jsonpSender, JsonpReceiver);
2072                 }
2073 
2074                 inherits(JsonPTransport, SenderReceiver);
2075 
2076                 JsonPTransport.enabled = function () {
2077                     return !!global.document;
2078                 };
2079 
2080                 JsonPTransport.transportName = 'jsonp-polling';
2081                 JsonPTransport.roundTrips = 1;
2082                 JsonPTransport.needBody = true;
2083 
2084                 module.exports = JsonPTransport;
2085 
2086             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2087 
2088         }, {"./lib/sender-receiver": 28, "./receiver/jsonp": 31, "./sender/jsonp": 33, "inherits": 57}],
2089         24: [function (require, module, exports) {
2090             (function (process) {
2091                 'use strict';
2092 
2093                 var inherits = require('inherits')
2094                     , urlUtils = require('../../utils/url')
2095                     , SenderReceiver = require('./sender-receiver')
2096                 ;
2097 
2098                 var debug = function () {
2099                 };
2100                 if (process.env.NODE_ENV !== 'production') {
2101                     debug = require('debug')('sockjs-client:ajax-based');
2102                 }
2103 
2104                 function createAjaxSender(AjaxObject) {
2105                     return function (url, payload, callback) {
2106                         debug('create ajax sender', url, payload);
2107                         var opt = {};
2108                         if (typeof payload === 'string') {
2109                             opt.headers = {'Content-type': 'text/plain'};
2110                         }
2111                         var ajaxUrl = urlUtils.addPath(url, '/xhr_send');
2112                         var xo = new AjaxObject('POST', ajaxUrl, payload, opt);
2113                         xo.once('finish', function (status) {
2114                             debug('finish', status);
2115                             xo = null;
2116 
2117                             if (status !== 200 && status !== 204) {
2118                                 return callback(new Error('http status ' + status));
2119                             }
2120                             callback();
2121                         });
2122                         return function () {
2123                             debug('abort');
2124                             xo.close();
2125                             xo = null;
2126 
2127                             var err = new Error('Aborted');
2128                             err.code = 1000;
2129                             callback(err);
2130                         };
2131                     };
2132                 }
2133 
2134                 function AjaxBasedTransport(transUrl, urlSuffix, Receiver, AjaxObject) {
2135                     SenderReceiver.call(this, transUrl, urlSuffix, createAjaxSender(AjaxObject), Receiver, AjaxObject);
2136                 }
2137 
2138                 inherits(AjaxBasedTransport, SenderReceiver);
2139 
2140                 module.exports = AjaxBasedTransport;
2141 
2142             }).call(this, {env: {}})
2143 
2144         }, {"../../utils/url": 52, "./sender-receiver": 28, "debug": 55, "inherits": 57}],
2145         25: [function (require, module, exports) {
2146             (function (process) {
2147                 'use strict';
2148 
2149                 var inherits = require('inherits')
2150                     , EventEmitter = require('events').EventEmitter
2151                 ;
2152 
2153                 var debug = function () {
2154                 };
2155                 if (process.env.NODE_ENV !== 'production') {
2156                     debug = require('debug')('sockjs-client:buffered-sender');
2157                 }
2158 
2159                 function BufferedSender(url, sender) {
2160                     debug(url);
2161                     EventEmitter.call(this);
2162                     this.sendBuffer = [];
2163                     this.sender = sender;
2164                     this.url = url;
2165                 }
2166 
2167                 inherits(BufferedSender, EventEmitter);
2168 
2169                 BufferedSender.prototype.send = function (message) {
2170                     debug('send', message);
2171                     this.sendBuffer.push(message);
2172                     if (!this.sendStop) {
2173                         this.sendSchedule();
2174                     }
2175                 };
2176 
2177 // For polling transports in a situation when in the message callback,
2178 // new message is being send. If the sending connection was started
2179 // before receiving one, it is possible to saturate the network and
2180 // timeout due to the lack of receiving socket. To avoid that we delay
2181 // sending messages by some small time, in order to let receiving
2182 // connection be started beforehand. This is only a halfmeasure and
2183 // does not fix the big problem, but it does make the tests go more
2184 // stable on slow networks.
2185                 BufferedSender.prototype.sendScheduleWait = function () {
2186                     debug('sendScheduleWait');
2187                     var self = this;
2188                     var tref;
2189                     this.sendStop = function () {
2190                         debug('sendStop');
2191                         self.sendStop = null;
2192                         clearTimeout(tref);
2193                     };
2194                     tref = setTimeout(function () {
2195                         debug('timeout');
2196                         self.sendStop = null;
2197                         self.sendSchedule();
2198                     }, 25);
2199                 };
2200 
2201                 BufferedSender.prototype.sendSchedule = function () {
2202                     debug('sendSchedule', this.sendBuffer.length);
2203                     var self = this;
2204                     if (this.sendBuffer.length > 0) {
2205                         var payload = '[' + this.sendBuffer.join(',') + ']';
2206                         this.sendStop = this.sender(this.url, payload, function (err) {
2207                             self.sendStop = null;
2208                             if (err) {
2209                                 debug('error', err);
2210                                 self.emit('close', err.code || 1006, 'Sending error: ' + err);
2211                                 self.close();
2212                             } else {
2213                                 self.sendScheduleWait();
2214                             }
2215                         });
2216                         this.sendBuffer = [];
2217                     }
2218                 };
2219 
2220                 BufferedSender.prototype._cleanup = function () {
2221                     debug('_cleanup');
2222                     this.removeAllListeners();
2223                 };
2224 
2225                 BufferedSender.prototype.close = function () {
2226                     debug('close');
2227                     this._cleanup();
2228                     if (this.sendStop) {
2229                         this.sendStop();
2230                         this.sendStop = null;
2231                     }
2232                 };
2233 
2234                 module.exports = BufferedSender;
2235 
2236             }).call(this, {env: {}})
2237 
2238         }, {"debug": 55, "events": 3, "inherits": 57}],
2239         26: [function (require, module, exports) {
2240             (function (global) {
2241                 'use strict';
2242 
2243                 var inherits = require('inherits')
2244                     , IframeTransport = require('../iframe')
2245                     , objectUtils = require('../../utils/object')
2246                 ;
2247 
2248                 module.exports = function (transport) {
2249 
2250                     function IframeWrapTransport(transUrl, baseUrl) {
2251                         IframeTransport.call(this, transport.transportName, transUrl, baseUrl);
2252                     }
2253 
2254                     inherits(IframeWrapTransport, IframeTransport);
2255 
2256                     IframeWrapTransport.enabled = function (url, info) {
2257                         if (!global.document) {
2258                             return false;
2259                         }
2260 
2261                         var iframeInfo = objectUtils.extend({}, info);
2262                         iframeInfo.sameOrigin = true;
2263                         return transport.enabled(iframeInfo) && IframeTransport.enabled();
2264                     };
2265 
2266                     IframeWrapTransport.transportName = 'iframe-' + transport.transportName;
2267                     IframeWrapTransport.needBody = true;
2268                     IframeWrapTransport.roundTrips = IframeTransport.roundTrips + transport.roundTrips - 1; // html, javascript (2) + transport - no CORS (1)
2269 
2270                     IframeWrapTransport.facadeTransport = transport;
2271 
2272                     return IframeWrapTransport;
2273                 };
2274 
2275             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2276 
2277         }, {"../../utils/object": 49, "../iframe": 22, "inherits": 57}],
2278         27: [function (require, module, exports) {
2279             (function (process) {
2280                 'use strict';
2281 
2282                 var inherits = require('inherits')
2283                     , EventEmitter = require('events').EventEmitter
2284                 ;
2285 
2286                 var debug = function () {
2287                 };
2288                 if (process.env.NODE_ENV !== 'production') {
2289                     debug = require('debug')('sockjs-client:polling');
2290                 }
2291 
2292                 function Polling(Receiver, receiveUrl, AjaxObject) {
2293                     debug(receiveUrl);
2294                     EventEmitter.call(this);
2295                     this.Receiver = Receiver;
2296                     this.receiveUrl = receiveUrl;
2297                     this.AjaxObject = AjaxObject;
2298                     this._scheduleReceiver();
2299                 }
2300 
2301                 inherits(Polling, EventEmitter);
2302 
2303                 Polling.prototype._scheduleReceiver = function () {
2304                     debug('_scheduleReceiver');
2305                     var self = this;
2306                     var poll = this.poll = new this.Receiver(this.receiveUrl, this.AjaxObject);
2307 
2308                     poll.on('message', function (msg) {
2309                         debug('message', msg);
2310                         self.emit('message', msg);
2311                     });
2312 
2313                     poll.once('close', function (code, reason) {
2314                         debug('close', code, reason, self.pollIsClosing);
2315                         self.poll = poll = null;
2316 
2317                         if (!self.pollIsClosing) {
2318                             if (reason === 'network') {
2319                                 self._scheduleReceiver();
2320                             } else {
2321                                 self.emit('close', code || 1006, reason);
2322                                 self.removeAllListeners();
2323                             }
2324                         }
2325                     });
2326                 };
2327 
2328                 Polling.prototype.abort = function () {
2329                     debug('abort');
2330                     this.removeAllListeners();
2331                     this.pollIsClosing = true;
2332                     if (this.poll) {
2333                         this.poll.abort();
2334                     }
2335                 };
2336 
2337                 module.exports = Polling;
2338 
2339             }).call(this, {env: {}})
2340 
2341         }, {"debug": 55, "events": 3, "inherits": 57}],
2342         28: [function (require, module, exports) {
2343             (function (process) {
2344                 'use strict';
2345 
2346                 var inherits = require('inherits')
2347                     , urlUtils = require('../../utils/url')
2348                     , BufferedSender = require('./buffered-sender')
2349                     , Polling = require('./polling')
2350                 ;
2351 
2352                 var debug = function () {
2353                 };
2354                 if (process.env.NODE_ENV !== 'production') {
2355                     debug = require('debug')('sockjs-client:sender-receiver');
2356                 }
2357 
2358                 function SenderReceiver(transUrl, urlSuffix, senderFunc, Receiver, AjaxObject) {
2359                     var pollUrl = urlUtils.addPath(transUrl, urlSuffix);
2360                     debug(pollUrl);
2361                     var self = this;
2362                     BufferedSender.call(this, transUrl, senderFunc);
2363 
2364                     this.poll = new Polling(Receiver, pollUrl, AjaxObject);
2365                     this.poll.on('message', function (msg) {
2366                         debug('poll message', msg);
2367                         self.emit('message', msg);
2368                     });
2369                     this.poll.once('close', function (code, reason) {
2370                         debug('poll close', code, reason);
2371                         self.poll = null;
2372                         self.emit('close', code, reason);
2373                         self.close();
2374                     });
2375                 }
2376 
2377                 inherits(SenderReceiver, BufferedSender);
2378 
2379                 SenderReceiver.prototype.close = function () {
2380                     BufferedSender.prototype.close.call(this);
2381                     debug('close');
2382                     this.removeAllListeners();
2383                     if (this.poll) {
2384                         this.poll.abort();
2385                         this.poll = null;
2386                     }
2387                 };
2388 
2389                 module.exports = SenderReceiver;
2390 
2391             }).call(this, {env: {}})
2392 
2393         }, {"../../utils/url": 52, "./buffered-sender": 25, "./polling": 27, "debug": 55, "inherits": 57}],
2394         29: [function (require, module, exports) {
2395             (function (process) {
2396                 'use strict';
2397 
2398                 var inherits = require('inherits')
2399                     , EventEmitter = require('events').EventEmitter
2400                     , EventSourceDriver = require('eventsource')
2401                 ;
2402 
2403                 var debug = function () {
2404                 };
2405                 if (process.env.NODE_ENV !== 'production') {
2406                     debug = require('debug')('sockjs-client:receiver:eventsource');
2407                 }
2408 
2409                 function EventSourceReceiver(url) {
2410                     debug(url);
2411                     EventEmitter.call(this);
2412 
2413                     var self = this;
2414                     var es = this.es = new EventSourceDriver(url);
2415                     es.onmessage = function (e) {
2416                         debug('message', e.data);
2417                         self.emit('message', decodeURI(e.data));
2418                     };
2419                     es.onerror = function (e) {
2420                         debug('error', es.readyState, e);
2421                         // ES on reconnection has readyState = 0 or 1.
2422                         // on network error it's CLOSED = 2
2423                         var reason = (es.readyState !== 2 ? 'network' : 'permanent');
2424                         self._cleanup();
2425                         self._close(reason);
2426                     };
2427                 }
2428 
2429                 inherits(EventSourceReceiver, EventEmitter);
2430 
2431                 EventSourceReceiver.prototype.abort = function () {
2432                     debug('abort');
2433                     this._cleanup();
2434                     this._close('user');
2435                 };
2436 
2437                 EventSourceReceiver.prototype._cleanup = function () {
2438                     debug('cleanup');
2439                     var es = this.es;
2440                     if (es) {
2441                         es.onmessage = es.onerror = null;
2442                         es.close();
2443                         this.es = null;
2444                     }
2445                 };
2446 
2447                 EventSourceReceiver.prototype._close = function (reason) {
2448                     debug('close', reason);
2449                     var self = this;
2450                     // Safari and chrome < 15 crash if we close window before
2451                     // waiting for ES cleanup. See:
2452                     // https://code.google.com/p/chromium/issues/detail?id=89155
2453                     setTimeout(function () {
2454                         self.emit('close', null, reason);
2455                         self.removeAllListeners();
2456                     }, 200);
2457                 };
2458 
2459                 module.exports = EventSourceReceiver;
2460 
2461             }).call(this, {env: {}})
2462 
2463         }, {"debug": 55, "events": 3, "eventsource": 18, "inherits": 57}],
2464         30: [function (require, module, exports) {
2465             (function (process, global) {
2466                 'use strict';
2467 
2468                 var inherits = require('inherits')
2469                     , iframeUtils = require('../../utils/iframe')
2470                     , urlUtils = require('../../utils/url')
2471                     , EventEmitter = require('events').EventEmitter
2472                     , random = require('../../utils/random')
2473                 ;
2474 
2475                 var debug = function () {
2476                 };
2477                 if (process.env.NODE_ENV !== 'production') {
2478                     debug = require('debug')('sockjs-client:receiver:htmlfile');
2479                 }
2480 
2481                 function HtmlfileReceiver(url) {
2482                     debug(url);
2483                     EventEmitter.call(this);
2484                     var self = this;
2485                     iframeUtils.polluteGlobalNamespace();
2486 
2487                     this.id = 'a' + random.string(6);
2488                     url = urlUtils.addQuery(url, 'c=' + decodeURIComponent(iframeUtils.WPrefix + '.' + this.id));
2489 
2490                     debug('using htmlfile', HtmlfileReceiver.htmlfileEnabled);
2491                     var constructFunc = HtmlfileReceiver.htmlfileEnabled ?
2492                         iframeUtils.createHtmlfile : iframeUtils.createIframe;
2493 
2494                     global[iframeUtils.WPrefix][this.id] = {
2495                         start: function () {
2496                             debug('start');
2497                             self.iframeObj.loaded();
2498                         }
2499                         , message: function (data) {
2500                             debug('message', data);
2501                             self.emit('message', data);
2502                         }
2503                         , stop: function () {
2504                             debug('stop');
2505                             self._cleanup();
2506                             self._close('network');
2507                         }
2508                     };
2509                     this.iframeObj = constructFunc(url, function () {
2510                         debug('callback');
2511                         self._cleanup();
2512                         self._close('permanent');
2513                     });
2514                 }
2515 
2516                 inherits(HtmlfileReceiver, EventEmitter);
2517 
2518                 HtmlfileReceiver.prototype.abort = function () {
2519                     debug('abort');
2520                     this._cleanup();
2521                     this._close('user');
2522                 };
2523 
2524                 HtmlfileReceiver.prototype._cleanup = function () {
2525                     debug('_cleanup');
2526                     if (this.iframeObj) {
2527                         this.iframeObj.cleanup();
2528                         this.iframeObj = null;
2529                     }
2530                     delete global[iframeUtils.WPrefix][this.id];
2531                 };
2532 
2533                 HtmlfileReceiver.prototype._close = function (reason) {
2534                     debug('_close', reason);
2535                     this.emit('close', null, reason);
2536                     this.removeAllListeners();
2537                 };
2538 
2539                 HtmlfileReceiver.htmlfileEnabled = false;
2540 
2541 // obfuscate to avoid firewalls
2542                 var axo = ['Active'].concat('Object').join('X');
2543                 if (axo in global) {
2544                     try {
2545                         HtmlfileReceiver.htmlfileEnabled = !!new global[axo]('htmlfile');
2546                     } catch (x) {
2547                         // intentionally empty
2548                     }
2549                 }
2550 
2551                 HtmlfileReceiver.enabled = HtmlfileReceiver.htmlfileEnabled || iframeUtils.iframeEnabled;
2552 
2553                 module.exports = HtmlfileReceiver;
2554 
2555             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2556 
2557         }, {
2558             "../../utils/iframe": 47,
2559             "../../utils/random": 50,
2560             "../../utils/url": 52,
2561             "debug": 55,
2562             "events": 3,
2563             "inherits": 57
2564         }],
2565         31: [function (require, module, exports) {
2566             (function (process, global) {
2567                 'use strict';
2568 
2569                 var utils = require('../../utils/iframe')
2570                     , random = require('../../utils/random')
2571                     , browser = require('../../utils/browser')
2572                     , urlUtils = require('../../utils/url')
2573                     , inherits = require('inherits')
2574                     , EventEmitter = require('events').EventEmitter
2575                 ;
2576 
2577                 var debug = function () {
2578                 };
2579                 if (process.env.NODE_ENV !== 'production') {
2580                     debug = require('debug')('sockjs-client:receiver:jsonp');
2581                 }
2582 
2583                 function JsonpReceiver(url) {
2584                     debug(url);
2585                     var self = this;
2586                     EventEmitter.call(this);
2587 
2588                     utils.polluteGlobalNamespace();
2589 
2590                     this.id = 'a' + random.string(6);
2591                     var urlWithId = urlUtils.addQuery(url, 'c=' + encodeURIComponent(utils.WPrefix + '.' + this.id));
2592 
2593                     global[utils.WPrefix][this.id] = this._callback.bind(this);
2594                     this._createScript(urlWithId);
2595 
2596                     // Fallback mostly for Konqueror - stupid timer, 35 seconds shall be plenty.
2597                     this.timeoutId = setTimeout(function () {
2598                         debug('timeout');
2599                         self._abort(new Error('JSONP script loaded abnormally (timeout)'));
2600                     }, JsonpReceiver.timeout);
2601                 }
2602 
2603                 inherits(JsonpReceiver, EventEmitter);
2604 
2605                 JsonpReceiver.prototype.abort = function () {
2606                     debug('abort');
2607                     if (global[utils.WPrefix][this.id]) {
2608                         var err = new Error('JSONP user aborted read');
2609                         err.code = 1000;
2610                         this._abort(err);
2611                     }
2612                 };
2613 
2614                 JsonpReceiver.timeout = 35000;
2615                 JsonpReceiver.scriptErrorTimeout = 1000;
2616 
2617                 JsonpReceiver.prototype._callback = function (data) {
2618                     debug('_callback', data);
2619                     this._cleanup();
2620 
2621                     if (this.aborting) {
2622                         return;
2623                     }
2624 
2625                     if (data) {
2626                         debug('message', data);
2627                         this.emit('message', data);
2628                     }
2629                     this.emit('close', null, 'network');
2630                     this.removeAllListeners();
2631                 };
2632 
2633                 JsonpReceiver.prototype._abort = function (err) {
2634                     debug('_abort', err);
2635                     this._cleanup();
2636                     this.aborting = true;
2637                     this.emit('close', err.code, err.message);
2638                     this.removeAllListeners();
2639                 };
2640 
2641                 JsonpReceiver.prototype._cleanup = function () {
2642                     debug('_cleanup');
2643                     clearTimeout(this.timeoutId);
2644                     if (this.script2) {
2645                         this.script2.parentNode.removeChild(this.script2);
2646                         this.script2 = null;
2647                     }
2648                     if (this.script) {
2649                         var script = this.script;
2650                         // Unfortunately, you can't really abort script loading of
2651                         // the script.
2652                         script.parentNode.removeChild(script);
2653                         script.onreadystatechange = script.onerror =
2654                             script.onload = script.onclick = null;
2655                         this.script = null;
2656                     }
2657                     delete global[utils.WPrefix][this.id];
2658                 };
2659 
2660                 JsonpReceiver.prototype._scriptError = function () {
2661                     debug('_scriptError');
2662                     var self = this;
2663                     if (this.errorTimer) {
2664                         return;
2665                     }
2666 
2667                     this.errorTimer = setTimeout(function () {
2668                         if (!self.loadedOkay) {
2669                             self._abort(new Error('JSONP script loaded abnormally (onerror)'));
2670                         }
2671                     }, JsonpReceiver.scriptErrorTimeout);
2672                 };
2673 
2674                 JsonpReceiver.prototype._createScript = function (url) {
2675                     debug('_createScript', url);
2676                     var self = this;
2677                     var script = this.script = global.document.createElement('script');
2678                     var script2;  // Opera synchronous load trick.
2679 
2680                     script.id = 'a' + random.string(8);
2681                     script.src = url;
2682                     script.type = 'text/javascript';
2683                     script.charset = 'UTF-8';
2684                     script.onerror = this._scriptError.bind(this);
2685                     script.onload = function () {
2686                         debug('onload');
2687                         self._abort(new Error('JSONP script loaded abnormally (onload)'));
2688                     };
2689 
2690                     // IE9 fires 'error' event after onreadystatechange or before, in random order.
2691                     // Use loadedOkay to determine if actually errored
2692                     script.onreadystatechange = function () {
2693                         debug('onreadystatechange', script.readyState);
2694                         if (/loaded|closed/.test(script.readyState)) {
2695                             if (script && script.htmlFor && script.onclick) {
2696                                 self.loadedOkay = true;
2697                                 try {
2698                                     // In IE, actually execute the script.
2699                                     script.onclick();
2700                                 } catch (x) {
2701                                     // intentionally empty
2702                                 }
2703                             }
2704                             if (script) {
2705                                 self._abort(new Error('JSONP script loaded abnormally (onreadystatechange)'));
2706                             }
2707                         }
2708                     };
2709                     // IE: event/htmlFor/onclick trick.
2710                     // One can't rely on proper order for onreadystatechange. In order to
2711                     // make sure, set a 'htmlFor' and 'event' properties, so that
2712                     // script code will be installed as 'onclick' handler for the
2713                     // script object. Later, onreadystatechange, manually execute this
2714                     // code. FF and Chrome doesn't work with 'event' and 'htmlFor'
2715                     // set. For reference see:
2716                     //   http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
2717                     // Also, read on that about script ordering:
2718                     //   http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
2719                     if (typeof script.async === 'undefined' && global.document.attachEvent) {
2720                         // According to mozilla docs, in recent browsers script.async defaults
2721                         // to 'true', so we may use it to detect a good browser:
2722                         // https://developer.mozilla.org/en/HTML/Element/script
2723                         if (!browser.isOpera()) {
2724                             // Naively assume we're in IE
2725                             try {
2726                                 script.htmlFor = script.id;
2727                                 script.event = 'onclick';
2728                             } catch (x) {
2729                                 // intentionally empty
2730                             }
2731                             script.async = true;
2732                         } else {
2733                             // Opera, second sync script hack
2734                             script2 = this.script2 = global.document.createElement('script');
2735                             script2.text = "try{var a = document.getElementById('" + script.id + "'); if(a)a.onerror();}catch(x){};";
2736                             script.async = script2.async = false;
2737                         }
2738                     }
2739                     if (typeof script.async !== 'undefined') {
2740                         script.async = true;
2741                     }
2742 
2743                     var head = global.document.getElementsByTagName('head')[0];
2744                     head.insertBefore(script, head.firstChild);
2745                     if (script2) {
2746                         head.insertBefore(script2, head.firstChild);
2747                     }
2748                 };
2749 
2750                 module.exports = JsonpReceiver;
2751 
2752             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2753 
2754         }, {
2755             "../../utils/browser": 44,
2756             "../../utils/iframe": 47,
2757             "../../utils/random": 50,
2758             "../../utils/url": 52,
2759             "debug": 55,
2760             "events": 3,
2761             "inherits": 57
2762         }],
2763         32: [function (require, module, exports) {
2764             (function (process) {
2765                 'use strict';
2766 
2767                 var inherits = require('inherits')
2768                     , EventEmitter = require('events').EventEmitter
2769                 ;
2770 
2771                 var debug = function () {
2772                 };
2773                 if (process.env.NODE_ENV !== 'production') {
2774                     debug = require('debug')('sockjs-client:receiver:xhr');
2775                 }
2776 
2777                 function XhrReceiver(url, AjaxObject) {
2778                     debug(url);
2779                     EventEmitter.call(this);
2780                     var self = this;
2781 
2782                     this.bufferPosition = 0;
2783 
2784                     this.xo = new AjaxObject('POST', url, null);
2785                     this.xo.on('chunk', this._chunkHandler.bind(this));
2786                     this.xo.once('finish', function (status, text) {
2787                         debug('finish', status, text);
2788                         self._chunkHandler(status, text);
2789                         self.xo = null;
2790                         var reason = status === 200 ? 'network' : 'permanent';
2791                         debug('close', reason);
2792                         self.emit('close', null, reason);
2793                         self._cleanup();
2794                     });
2795                 }
2796 
2797                 inherits(XhrReceiver, EventEmitter);
2798 
2799                 XhrReceiver.prototype._chunkHandler = function (status, text) {
2800                     debug('_chunkHandler', status);
2801                     if (status !== 200 || !text) {
2802                         return;
2803                     }
2804 
2805                     for (var idx = -1; ; this.bufferPosition += idx + 1) {
2806                         var buf = text.slice(this.bufferPosition);
2807                         idx = buf.indexOf('\n');
2808                         if (idx === -1) {
2809                             break;
2810                         }
2811                         var msg = buf.slice(0, idx);
2812                         if (msg) {
2813                             debug('message', msg);
2814                             this.emit('message', msg);
2815                         }
2816                     }
2817                 };
2818 
2819                 XhrReceiver.prototype._cleanup = function () {
2820                     debug('_cleanup');
2821                     this.removeAllListeners();
2822                 };
2823 
2824                 XhrReceiver.prototype.abort = function () {
2825                     debug('abort');
2826                     if (this.xo) {
2827                         this.xo.close();
2828                         debug('close');
2829                         this.emit('close', null, 'user');
2830                         this.xo = null;
2831                     }
2832                     this._cleanup();
2833                 };
2834 
2835                 module.exports = XhrReceiver;
2836 
2837             }).call(this, {env: {}})
2838 
2839         }, {"debug": 55, "events": 3, "inherits": 57}],
2840         33: [function (require, module, exports) {
2841             (function (process, global) {
2842                 'use strict';
2843 
2844                 var random = require('../../utils/random')
2845                     , urlUtils = require('../../utils/url')
2846                 ;
2847 
2848                 var debug = function () {
2849                 };
2850                 if (process.env.NODE_ENV !== 'production') {
2851                     debug = require('debug')('sockjs-client:sender:jsonp');
2852                 }
2853 
2854                 var form, area;
2855 
2856                 function createIframe(id) {
2857                     debug('createIframe', id);
2858                     try {
2859                         // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
2860                         return global.document.createElement('<iframe name="' + id + '">');
2861                     } catch (x) {
2862                         var iframe = global.document.createElement('iframe');
2863                         iframe.name = id;
2864                         return iframe;
2865                     }
2866                 }
2867 
2868                 function createForm() {
2869                     debug('createForm');
2870                     form = global.document.createElement('form');
2871                     form.style.display = 'none';
2872                     form.style.position = 'absolute';
2873                     form.method = 'POST';
2874                     form.enctype = 'application/x-www-form-urlencoded';
2875                     form.acceptCharset = 'UTF-8';
2876 
2877                     area = global.document.createElement('textarea');
2878                     area.name = 'd';
2879                     form.appendChild(area);
2880 
2881                     global.document.body.appendChild(form);
2882                 }
2883 
2884                 module.exports = function (url, payload, callback) {
2885                     debug(url, payload);
2886                     if (!form) {
2887                         createForm();
2888                     }
2889                     var id = 'a' + random.string(8);
2890                     form.target = id;
2891                     form.action = urlUtils.addQuery(urlUtils.addPath(url, '/jsonp_send'), 'i=' + id);
2892 
2893                     var iframe = createIframe(id);
2894                     iframe.id = id;
2895                     iframe.style.display = 'none';
2896                     form.appendChild(iframe);
2897 
2898                     try {
2899                         area.value = payload;
2900                     } catch (e) {
2901                         // seriously broken browsers get here
2902                     }
2903                     form.submit();
2904 
2905                     var completed = function (err) {
2906                         debug('completed', id, err);
2907                         if (!iframe.onerror) {
2908                             return;
2909                         }
2910                         iframe.onreadystatechange = iframe.onerror = iframe.onload = null;
2911                         // Opera mini doesn't like if we GC iframe
2912                         // immediately, thus this timeout.
2913                         setTimeout(function () {
2914                             debug('cleaning up', id);
2915                             iframe.parentNode.removeChild(iframe);
2916                             iframe = null;
2917                         }, 500);
2918                         area.value = '';
2919                         // It is not possible to detect if the iframe succeeded or
2920                         // failed to submit our form.
2921                         callback(err);
2922                     };
2923                     iframe.onerror = function () {
2924                         debug('onerror', id);
2925                         completed();
2926                     };
2927                     iframe.onload = function () {
2928                         debug('onload', id);
2929                         completed();
2930                     };
2931                     iframe.onreadystatechange = function (e) {
2932                         debug('onreadystatechange', id, iframe.readyState, e);
2933                         if (iframe.readyState === 'complete') {
2934                             completed();
2935                         }
2936                     };
2937                     return function () {
2938                         debug('aborted', id);
2939                         completed(new Error('Aborted'));
2940                     };
2941                 };
2942 
2943             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2944 
2945         }, {"../../utils/random": 50, "../../utils/url": 52, "debug": 55}],
2946         34: [function (require, module, exports) {
2947             (function (process, global) {
2948                 'use strict';
2949 
2950                 var EventEmitter = require('events').EventEmitter
2951                     , inherits = require('inherits')
2952                     , eventUtils = require('../../utils/event')
2953                     , browser = require('../../utils/browser')
2954                     , urlUtils = require('../../utils/url')
2955                 ;
2956 
2957                 var debug = function () {
2958                 };
2959                 if (process.env.NODE_ENV !== 'production') {
2960                     debug = require('debug')('sockjs-client:sender:xdr');
2961                 }
2962 
2963 // References:
2964 //   http://ajaxian.com/archives/100-line-ajax-wrapper
2965 //   http://msdn.microsoft.com/en-us/library/cc288060(v=VS.85).aspx
2966 
2967                 function XDRObject(method, url, payload) {
2968                     debug(method, url);
2969                     var self = this;
2970                     EventEmitter.call(this);
2971 
2972                     setTimeout(function () {
2973                         self._start(method, url, payload);
2974                     }, 0);
2975                 }
2976 
2977                 inherits(XDRObject, EventEmitter);
2978 
2979                 XDRObject.prototype._start = function (method, url, payload) {
2980                     debug('_start');
2981                     var self = this;
2982                     var xdr = new global.XDomainRequest();
2983                     // IE caches even POSTs
2984                     url = urlUtils.addQuery(url, 't=' + (+new Date()));
2985 
2986                     xdr.onerror = function () {
2987                         debug('onerror');
2988                         self._error();
2989                     };
2990                     xdr.ontimeout = function () {
2991                         debug('ontimeout');
2992                         self._error();
2993                     };
2994                     xdr.onprogress = function () {
2995                         debug('progress', xdr.responseText);
2996                         self.emit('chunk', 200, xdr.responseText);
2997                     };
2998                     xdr.onload = function () {
2999                         debug('load');
3000                         self.emit('finish', 200, xdr.responseText);
3001                         self._cleanup(false);
3002                     };
3003                     this.xdr = xdr;
3004                     this.unloadRef = eventUtils.unloadAdd(function () {
3005                         self._cleanup(true);
3006                     });
3007                     try {
3008                         // Fails with AccessDenied if port number is bogus
3009                         this.xdr.open(method, url);
3010                         if (this.timeout) {
3011                             this.xdr.timeout = this.timeout;
3012                         }
3013                         this.xdr.send(payload);
3014                     } catch (x) {
3015                         this._error();
3016                     }
3017                 };
3018 
3019                 XDRObject.prototype._error = function () {
3020                     this.emit('finish', 0, '');
3021                     this._cleanup(false);
3022                 };
3023 
3024                 XDRObject.prototype._cleanup = function (abort) {
3025                     debug('cleanup', abort);
3026                     if (!this.xdr) {
3027                         return;
3028                     }
3029                     this.removeAllListeners();
3030                     eventUtils.unloadDel(this.unloadRef);
3031 
3032                     this.xdr.ontimeout = this.xdr.onerror = this.xdr.onprogress = this.xdr.onload = null;
3033                     if (abort) {
3034                         try {
3035                             this.xdr.abort();
3036                         } catch (x) {
3037                             // intentionally empty
3038                         }
3039                     }
3040                     this.unloadRef = this.xdr = null;
3041                 };
3042 
3043                 XDRObject.prototype.close = function () {
3044                     debug('close');
3045                     this._cleanup(true);
3046                 };
3047 
3048 // IE 8/9 if the request target uses the same scheme - #79
3049                 XDRObject.enabled = !!(global.XDomainRequest && browser.hasDomain());
3050 
3051                 module.exports = XDRObject;
3052 
3053             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3054 
3055         }, {
3056             "../../utils/browser": 44,
3057             "../../utils/event": 46,
3058             "../../utils/url": 52,
3059             "debug": 55,
3060             "events": 3,
3061             "inherits": 57
3062         }],
3063         35: [function (require, module, exports) {
3064             'use strict';
3065 
3066             var inherits = require('inherits')
3067                 , XhrDriver = require('../driver/xhr')
3068             ;
3069 
3070             function XHRCorsObject(method, url, payload, opts) {
3071                 XhrDriver.call(this, method, url, payload, opts);
3072             }
3073 
3074             inherits(XHRCorsObject, XhrDriver);
3075 
3076             XHRCorsObject.enabled = XhrDriver.enabled && XhrDriver.supportsCORS;
3077 
3078             module.exports = XHRCorsObject;
3079 
3080         }, {"../driver/xhr": 17, "inherits": 57}],
3081         36: [function (require, module, exports) {
3082             'use strict';
3083 
3084             var EventEmitter = require('events').EventEmitter
3085                 , inherits = require('inherits')
3086             ;
3087 
3088             function XHRFake(/* method, url, payload, opts */) {
3089                 var self = this;
3090                 EventEmitter.call(this);
3091 
3092                 this.to = setTimeout(function () {
3093                     self.emit('finish', 200, '{}');
3094                 }, XHRFake.timeout);
3095             }
3096 
3097             inherits(XHRFake, EventEmitter);
3098 
3099             XHRFake.prototype.close = function () {
3100                 clearTimeout(this.to);
3101             };
3102 
3103             XHRFake.timeout = 2000;
3104 
3105             module.exports = XHRFake;
3106 
3107         }, {"events": 3, "inherits": 57}],
3108         37: [function (require, module, exports) {
3109             'use strict';
3110 
3111             var inherits = require('inherits')
3112                 , XhrDriver = require('../driver/xhr')
3113             ;
3114 
3115             function XHRLocalObject(method, url, payload /*, opts */) {
3116                 XhrDriver.call(this, method, url, payload, {
3117                     noCredentials: true
3118                 });
3119             }
3120 
3121             inherits(XHRLocalObject, XhrDriver);
3122 
3123             XHRLocalObject.enabled = XhrDriver.enabled;
3124 
3125             module.exports = XHRLocalObject;
3126 
3127         }, {"../driver/xhr": 17, "inherits": 57}],
3128         38: [function (require, module, exports) {
3129             (function (process) {
3130                 'use strict';
3131 
3132                 var utils = require('../utils/event')
3133                     , urlUtils = require('../utils/url')
3134                     , inherits = require('inherits')
3135                     , EventEmitter = require('events').EventEmitter
3136                     , WebsocketDriver = require('./driver/websocket')
3137                 ;
3138 
3139                 var debug = function () {
3140                 };
3141                 if (process.env.NODE_ENV !== 'production') {
3142                     debug = require('debug')('sockjs-client:websocket');
3143                 }
3144 
3145                 function WebSocketTransport(transUrl, ignore, options) {
3146                     if (!WebSocketTransport.enabled()) {
3147                         throw new Error('Transport created when disabled');
3148                     }
3149 
3150                     EventEmitter.call(this);
3151                     debug('constructor', transUrl);
3152 
3153                     var self = this;
3154                     var url = urlUtils.addPath(transUrl, '/websocket');
3155                     if (url.slice(0, 5) === 'https') {
3156                         url = 'wss' + url.slice(5);
3157                     } else {
3158                         url = 'ws' + url.slice(4);
3159                     }
3160                     this.url = url;
3161 
3162                     this.ws = new WebsocketDriver(this.url, [], options);
3163                     this.ws.onmessage = function (e) {
3164                         debug('message event', e.data);
3165                         self.emit('message', e.data);
3166                     };
3167                     // Firefox has an interesting bug. If a websocket connection is
3168                     // created after onunload, it stays alive even when user
3169                     // navigates away from the page. In such situation let's lie -
3170                     // let's not open the ws connection at all. See:
3171                     // https://github.com/sockjs/sockjs-client/issues/28
3172                     // https://bugzilla.mozilla.org/show_bug.cgi?id=696085
3173                     this.unloadRef = utils.unloadAdd(function () {
3174                         debug('unload');
3175                         self.ws.close();
3176                     });
3177                     this.ws.onclose = function (e) {
3178                         debug('close event', e.code, e.reason);
3179                         self.emit('close', e.code, e.reason);
3180                         self._cleanup();
3181                     };
3182                     this.ws.onerror = function (e) {
3183                         debug('error event', e);
3184                         self.emit('close', 1006, 'WebSocket connection broken');
3185                         self._cleanup();
3186                     };
3187                 }
3188 
3189                 inherits(WebSocketTransport, EventEmitter);
3190 
3191                 WebSocketTransport.prototype.send = function (data) {
3192                     var msg = '[' + data + ']';
3193                     debug('send', msg);
3194                     this.ws.send(msg);
3195                 };
3196 
3197                 WebSocketTransport.prototype.close = function () {
3198                     debug('close');
3199                     var ws = this.ws;
3200                     this._cleanup();
3201                     if (ws) {
3202                         ws.close();
3203                     }
3204                 };
3205 
3206                 WebSocketTransport.prototype._cleanup = function () {
3207                     debug('_cleanup');
3208                     var ws = this.ws;
3209                     if (ws) {
3210                         ws.onmessage = ws.onclose = ws.onerror = null;
3211                     }
3212                     utils.unloadDel(this.unloadRef);
3213                     this.unloadRef = this.ws = null;
3214                     this.removeAllListeners();
3215                 };
3216 
3217                 WebSocketTransport.enabled = function () {
3218                     debug('enabled');
3219                     return !!WebsocketDriver;
3220                 };
3221                 WebSocketTransport.transportName = 'websocket';
3222 
3223 // In theory, ws should require 1 round trip. But in chrome, this is
3224 // not very stable over SSL. Most likely a ws connection requires a
3225 // separate SSL connection, in which case 2 round trips are an
3226 // absolute minumum.
3227                 WebSocketTransport.roundTrips = 2;
3228 
3229                 module.exports = WebSocketTransport;
3230 
3231             }).call(this, {env: {}})
3232 
3233         }, {
3234             "../utils/event": 46,
3235             "../utils/url": 52,
3236             "./driver/websocket": 19,
3237             "debug": 55,
3238             "events": 3,
3239             "inherits": 57
3240         }],
3241         39: [function (require, module, exports) {
3242             'use strict';
3243 
3244             var inherits = require('inherits')
3245                 , AjaxBasedTransport = require('./lib/ajax-based')
3246                 , XdrStreamingTransport = require('./xdr-streaming')
3247                 , XhrReceiver = require('./receiver/xhr')
3248                 , XDRObject = require('./sender/xdr')
3249             ;
3250 
3251             function XdrPollingTransport(transUrl) {
3252                 if (!XDRObject.enabled) {
3253                     throw new Error('Transport created when disabled');
3254                 }
3255                 AjaxBasedTransport.call(this, transUrl, '/xhr', XhrReceiver, XDRObject);
3256             }
3257 
3258             inherits(XdrPollingTransport, AjaxBasedTransport);
3259 
3260             XdrPollingTransport.enabled = XdrStreamingTransport.enabled;
3261             XdrPollingTransport.transportName = 'xdr-polling';
3262             XdrPollingTransport.roundTrips = 2; // preflight, ajax
3263 
3264             module.exports = XdrPollingTransport;
3265 
3266         }, {"./lib/ajax-based": 24, "./receiver/xhr": 32, "./sender/xdr": 34, "./xdr-streaming": 40, "inherits": 57}],
3267         40: [function (require, module, exports) {
3268             'use strict';
3269 
3270             var inherits = require('inherits')
3271                 , AjaxBasedTransport = require('./lib/ajax-based')
3272                 , XhrReceiver = require('./receiver/xhr')
3273                 , XDRObject = require('./sender/xdr')
3274             ;
3275 
3276 // According to:
3277 //   http://stackoverflow.com/questions/1641507/detect-browser-support-for-cross-domain-xmlhttprequests
3278 //   http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/
3279 
3280             function XdrStreamingTransport(transUrl) {
3281                 if (!XDRObject.enabled) {
3282                     throw new Error('Transport created when disabled');
3283                 }
3284                 AjaxBasedTransport.call(this, transUrl, '/xhr_streaming', XhrReceiver, XDRObject);
3285             }
3286 
3287             inherits(XdrStreamingTransport, AjaxBasedTransport);
3288 
3289             XdrStreamingTransport.enabled = function (info) {
3290                 if (info.cookie_needed || info.nullOrigin) {
3291                     return false;
3292                 }
3293                 return XDRObject.enabled && info.sameScheme;
3294             };
3295 
3296             XdrStreamingTransport.transportName = 'xdr-streaming';
3297             XdrStreamingTransport.roundTrips = 2; // preflight, ajax
3298 
3299             module.exports = XdrStreamingTransport;
3300 
3301         }, {"./lib/ajax-based": 24, "./receiver/xhr": 32, "./sender/xdr": 34, "inherits": 57}],
3302         41: [function (require, module, exports) {
3303             'use strict';
3304 
3305             var inherits = require('inherits')
3306                 , AjaxBasedTransport = require('./lib/ajax-based')
3307                 , XhrReceiver = require('./receiver/xhr')
3308                 , XHRCorsObject = require('./sender/xhr-cors')
3309                 , XHRLocalObject = require('./sender/xhr-local')
3310             ;
3311 
3312             function XhrPollingTransport(transUrl) {
3313                 if (!XHRLocalObject.enabled && !XHRCorsObject.enabled) {
3314                     throw new Error('Transport created when disabled');
3315                 }
3316                 AjaxBasedTransport.call(this, transUrl, '/xhr', XhrReceiver, XHRCorsObject);
3317             }
3318 
3319             inherits(XhrPollingTransport, AjaxBasedTransport);
3320 
3321             XhrPollingTransport.enabled = function (info) {
3322                 if (info.nullOrigin) {
3323                     return false;
3324                 }
3325 
3326                 if (XHRLocalObject.enabled && info.sameOrigin) {
3327                     return true;
3328                 }
3329                 return XHRCorsObject.enabled;
3330             };
3331 
3332             XhrPollingTransport.transportName = 'xhr-polling';
3333             XhrPollingTransport.roundTrips = 2; // preflight, ajax
3334 
3335             module.exports = XhrPollingTransport;
3336 
3337         }, {
3338             "./lib/ajax-based": 24,
3339             "./receiver/xhr": 32,
3340             "./sender/xhr-cors": 35,
3341             "./sender/xhr-local": 37,
3342             "inherits": 57
3343         }],
3344         42: [function (require, module, exports) {
3345             (function (global) {
3346                 'use strict';
3347 
3348                 var inherits = require('inherits')
3349                     , AjaxBasedTransport = require('./lib/ajax-based')
3350                     , XhrReceiver = require('./receiver/xhr')
3351                     , XHRCorsObject = require('./sender/xhr-cors')
3352                     , XHRLocalObject = require('./sender/xhr-local')
3353                     , browser = require('../utils/browser')
3354                 ;
3355 
3356                 function XhrStreamingTransport(transUrl) {
3357                     if (!XHRLocalObject.enabled && !XHRCorsObject.enabled) {
3358                         throw new Error('Transport created when disabled');
3359                     }
3360                     AjaxBasedTransport.call(this, transUrl, '/xhr_streaming', XhrReceiver, XHRCorsObject);
3361                 }
3362 
3363                 inherits(XhrStreamingTransport, AjaxBasedTransport);
3364 
3365                 XhrStreamingTransport.enabled = function (info) {
3366                     if (info.nullOrigin) {
3367                         return false;
3368                     }
3369                     // Opera doesn't support xhr-streaming #60
3370                     // But it might be able to #92
3371                     if (browser.isOpera()) {
3372                         return false;
3373                     }
3374 
3375                     return XHRCorsObject.enabled;
3376                 };
3377 
3378                 XhrStreamingTransport.transportName = 'xhr-streaming';
3379                 XhrStreamingTransport.roundTrips = 2; // preflight, ajax
3380 
3381 // Safari gets confused when a streaming ajax request is started
3382 // before onload. This causes the load indicator to spin indefinetely.
3383 // Only require body when used in a browser
3384                 XhrStreamingTransport.needBody = !!global.document;
3385 
3386                 module.exports = XhrStreamingTransport;
3387 
3388             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3389 
3390         }, {
3391             "../utils/browser": 44,
3392             "./lib/ajax-based": 24,
3393             "./receiver/xhr": 32,
3394             "./sender/xhr-cors": 35,
3395             "./sender/xhr-local": 37,
3396             "inherits": 57
3397         }],
3398         43: [function (require, module, exports) {
3399             (function (global) {
3400                 'use strict';
3401 
3402                 if (global.crypto && global.crypto.getRandomValues) {
3403                     module.exports.randomBytes = function (length) {
3404                         var bytes = new Uint8Array(length);
3405                         global.crypto.getRandomValues(bytes);
3406                         return bytes;
3407                     };
3408                 } else {
3409                     module.exports.randomBytes = function (length) {
3410                         var bytes = new Array(length);
3411                         for (var i = 0; i < length; i++) {
3412                             bytes[i] = Math.floor(Math.random() * 256);
3413                         }
3414                         return bytes;
3415                     };
3416                 }
3417 
3418             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3419 
3420         }, {}],
3421         44: [function (require, module, exports) {
3422             (function (global) {
3423                 'use strict';
3424 
3425                 module.exports = {
3426                     isOpera: function () {
3427                         return global.navigator &&
3428                             /opera/i.test(global.navigator.userAgent);
3429                     }
3430 
3431                     , isKonqueror: function () {
3432                         return global.navigator &&
3433                             /konqueror/i.test(global.navigator.userAgent);
3434                     }
3435 
3436                     // #187 wrap document.domain in try/catch because of WP8 from file:///
3437                     , hasDomain: function () {
3438                         // non-browser client always has a domain
3439                         if (!global.document) {
3440                             return true;
3441                         }
3442 
3443                         try {
3444                             return !!global.document.domain;
3445                         } catch (e) {
3446                             return false;
3447                         }
3448                     }
3449                 };
3450 
3451             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3452 
3453         }, {}],
3454         45: [function (require, module, exports) {
3455             'use strict';
3456 
3457             var JSON3 = require('json3');
3458 
3459 // Some extra characters that Chrome gets wrong, and substitutes with
3460 // something else on the wire.
3461 // eslint-disable-next-line no-control-regex
3462             var extraEscapable = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g
3463                 , extraLookup;
3464 
3465 // This may be quite slow, so let's delay until user actually uses bad
3466 // characters.
3467             var unrollLookup = function (escapable) {
3468                 var i;
3469                 var unrolled = {};
3470                 var c = [];
3471                 for (i = 0; i < 65536; i++) {
3472                     c.push(String.fromCharCode(i));
3473                 }
3474                 escapable.lastIndex = 0;
3475                 c.join('').replace(escapable, function (a) {
3476                     unrolled[a] = '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
3477                     return '';
3478                 });
3479                 escapable.lastIndex = 0;
3480                 return unrolled;
3481             };
3482 
3483 // Quote string, also taking care of unicode characters that browsers
3484 // often break. Especially, take care of unicode surrogates:
3485 // http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates
3486             module.exports = {
3487                 quote: function (string) {
3488                     var quoted = JSON3.stringify(string);
3489 
3490                     // In most cases this should be very fast and good enough.
3491                     extraEscapable.lastIndex = 0;
3492                     if (!extraEscapable.test(quoted)) {
3493                         return quoted;
3494                     }
3495 
3496                     if (!extraLookup) {
3497                         extraLookup = unrollLookup(extraEscapable);
3498                     }
3499 
3500                     return quoted.replace(extraEscapable, function (a) {
3501                         return extraLookup[a];
3502                     });
3503                 }
3504             };
3505 
3506         }, {"json3": 58}],
3507         46: [function (require, module, exports) {
3508             (function (global) {
3509                 'use strict';
3510 
3511                 var random = require('./random');
3512 
3513                 var onUnload = {}
3514                     , afterUnload = false
3515                     // detect google chrome packaged apps because they don't allow the 'unload' event
3516                     , isChromePackagedApp = global.chrome && global.chrome.app && global.chrome.app.runtime
3517                 ;
3518 
3519                 module.exports = {
3520                     attachEvent: function (event, listener) {
3521                         if (typeof global.addEventListener !== 'undefined') {
3522                             global.addEventListener(event, listener, false);
3523                         } else if (global.document && global.attachEvent) {
3524                             // IE quirks.
3525                             // According to: http://stevesouders.com/misc/test-postmessage.php
3526                             // the message gets delivered only to 'document', not 'window'.
3527                             global.document.attachEvent('on' + event, listener);
3528                             // I get 'window' for ie8.
3529                             global.attachEvent('on' + event, listener);
3530                         }
3531                     }
3532 
3533                     , detachEvent: function (event, listener) {
3534                         if (typeof global.addEventListener !== 'undefined') {
3535                             global.removeEventListener(event, listener, false);
3536                         } else if (global.document && global.detachEvent) {
3537                             global.document.detachEvent('on' + event, listener);
3538                             global.detachEvent('on' + event, listener);
3539                         }
3540                     }
3541 
3542                     , unloadAdd: function (listener) {
3543                         if (isChromePackagedApp) {
3544                             return null;
3545                         }
3546 
3547                         var ref = random.string(8);
3548                         onUnload[ref] = listener;
3549                         if (afterUnload) {
3550                             setTimeout(this.triggerUnloadCallbacks, 0);
3551                         }
3552                         return ref;
3553                     }
3554 
3555                     , unloadDel: function (ref) {
3556                         if (ref in onUnload) {
3557                             delete onUnload[ref];
3558                         }
3559                     }
3560 
3561                     , triggerUnloadCallbacks: function () {
3562                         for (var ref in onUnload) {
3563                             onUnload[ref]();
3564                             delete onUnload[ref];
3565                         }
3566                     }
3567                 };
3568 
3569                 var unloadTriggered = function () {
3570                     if (afterUnload) {
3571                         return;
3572                     }
3573                     afterUnload = true;
3574                     module.exports.triggerUnloadCallbacks();
3575                 };
3576 
3577 // 'unload' alone is not reliable in opera within an iframe, but we
3578 // can't use `beforeunload` as IE fires it on javascript: links.
3579                 if (!isChromePackagedApp) {
3580                     module.exports.attachEvent('unload', unloadTriggered);
3581                 }
3582 
3583             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3584 
3585         }, {"./random": 50}],
3586         47: [function (require, module, exports) {
3587             (function (process, global) {
3588                 'use strict';
3589 
3590                 var eventUtils = require('./event')
3591                     , JSON3 = require('json3')
3592                     , browser = require('./browser')
3593                 ;
3594 
3595                 var debug = function () {
3596                 };
3597                 if (process.env.NODE_ENV !== 'production') {
3598                     debug = require('debug')('sockjs-client:utils:iframe');
3599                 }
3600 
3601                 module.exports = {
3602                     WPrefix: '_jp'
3603                     , currentWindowId: null
3604 
3605                     , polluteGlobalNamespace: function () {
3606                         if (!(module.exports.WPrefix in global)) {
3607                             global[module.exports.WPrefix] = {};
3608                         }
3609                     }
3610 
3611                     , postMessage: function (type, data) {
3612                         if (global.parent !== global) {
3613                             global.parent.postMessage(JSON3.stringify({
3614                                 windowId: module.exports.currentWindowId
3615                                 , type: type
3616                                 , data: data || ''
3617                             }), '*');
3618                         } else {
3619                             debug('Cannot postMessage, no parent window.', type, data);
3620                         }
3621                     }
3622 
3623                     , createIframe: function (iframeUrl, errorCallback) {
3624                         var iframe = global.document.createElement('iframe');
3625                         var tref, unloadRef;
3626                         var unattach = function () {
3627                             debug('unattach');
3628                             clearTimeout(tref);
3629                             // Explorer had problems with that.
3630                             try {
3631                                 iframe.onload = null;
3632                             } catch (x) {
3633                                 // intentionally empty
3634                             }
3635                             iframe.onerror = null;
3636                         };
3637                         var cleanup = function () {
3638                             debug('cleanup');
3639                             if (iframe) {
3640                                 unattach();
3641                                 // This timeout makes chrome fire onbeforeunload event
3642                                 // within iframe. Without the timeout it goes straight to
3643                                 // onunload.
3644                                 setTimeout(function () {
3645                                     if (iframe) {
3646                                         iframe.parentNode.removeChild(iframe);
3647                                     }
3648                                     iframe = null;
3649                                 }, 0);
3650                                 eventUtils.unloadDel(unloadRef);
3651                             }
3652                         };
3653                         var onerror = function (err) {
3654                             debug('onerror', err);
3655                             if (iframe) {
3656                                 cleanup();
3657                                 errorCallback(err);
3658                             }
3659                         };
3660                         var post = function (msg, origin) {
3661                             debug('post', msg, origin);
3662                             try {
3663                                 // When the iframe is not loaded, IE raises an exception
3664                                 // on 'contentWindow'.
3665                                 setTimeout(function () {
3666                                     if (iframe && iframe.contentWindow) {
3667                                         iframe.contentWindow.postMessage(msg, origin);
3668                                     }
3669                                 }, 0);
3670                             } catch (x) {
3671                                 // intentionally empty
3672                             }
3673                         };
3674 
3675                         iframe.src = iframeUrl;
3676                         iframe.style.display = 'none';
3677                         iframe.style.position = 'absolute';
3678                         iframe.onerror = function () {
3679                             onerror('onerror');
3680                         };
3681                         iframe.onload = function () {
3682                             debug('onload');
3683                             // `onload` is triggered before scripts on the iframe are
3684                             // executed. Give it few seconds to actually load stuff.
3685                             clearTimeout(tref);
3686                             tref = setTimeout(function () {
3687                                 onerror('onload timeout');
3688                             }, 2000);
3689                         };
3690                         global.document.body.appendChild(iframe);
3691                         tref = setTimeout(function () {
3692                             onerror('timeout');
3693                         }, 15000);
3694                         unloadRef = eventUtils.unloadAdd(cleanup);
3695                         return {
3696                             post: post
3697                             , cleanup: cleanup
3698                             , loaded: unattach
3699                         };
3700                     }
3701 
3702                     /* eslint no-undef: "off", new-cap: "off" */
3703                     , createHtmlfile: function (iframeUrl, errorCallback) {
3704                         var axo = ['Active'].concat('Object').join('X');
3705                         var doc = new global[axo]('htmlfile');
3706                         var tref, unloadRef;
3707                         var iframe;
3708                         var unattach = function () {
3709                             clearTimeout(tref);
3710                             iframe.onerror = null;
3711                         };
3712                         var cleanup = function () {
3713                             if (doc) {
3714                                 unattach();
3715                                 eventUtils.unloadDel(unloadRef);
3716                                 iframe.parentNode.removeChild(iframe);
3717                                 iframe = doc = null;
3718                                 CollectGarbage();
3719                             }
3720                         };
3721                         var onerror = function (r) {
3722                             debug('onerror', r);
3723                             if (doc) {
3724                                 cleanup();
3725                                 errorCallback(r);
3726                             }
3727                         };
3728                         var post = function (msg, origin) {
3729                             try {
3730                                 // When the iframe is not loaded, IE raises an exception
3731                                 // on 'contentWindow'.
3732                                 setTimeout(function () {
3733                                     if (iframe && iframe.contentWindow) {
3734                                         iframe.contentWindow.postMessage(msg, origin);
3735                                     }
3736                                 }, 0);
3737                             } catch (x) {
3738                                 // intentionally empty
3739                             }
3740                         };
3741 
3742                         doc.open();
3743                         doc.write('<html><s' + 'cript>' +
3744                             'document.domain="' + global.document.domain + '";' +
3745                             '</s' + 'cript></html>');
3746                         doc.close();
3747                         doc.parentWindow[module.exports.WPrefix] = global[module.exports.WPrefix];
3748                         var c = doc.createElement('div');
3749                         doc.body.appendChild(c);
3750                         iframe = doc.createElement('iframe');
3751                         c.appendChild(iframe);
3752                         iframe.src = iframeUrl;
3753                         iframe.onerror = function () {
3754                             onerror('onerror');
3755                         };
3756                         tref = setTimeout(function () {
3757                             onerror('timeout');
3758                         }, 15000);
3759                         unloadRef = eventUtils.unloadAdd(cleanup);
3760                         return {
3761                             post: post
3762                             , cleanup: cleanup
3763                             , loaded: unattach
3764                         };
3765                     }
3766                 };
3767 
3768                 module.exports.iframeEnabled = false;
3769                 if (global.document) {
3770                     // postMessage misbehaves in konqueror 4.6.5 - the messages are delivered with
3771                     // huge delay, or not at all.
3772                     module.exports.iframeEnabled = (typeof global.postMessage === 'function' ||
3773                         typeof global.postMessage === 'object') && (!browser.isKonqueror());
3774                 }
3775 
3776             }).call(this, {env: {}}, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3777 
3778         }, {"./browser": 44, "./event": 46, "debug": 55, "json3": 58}],
3779         48: [function (require, module, exports) {
3780             (function (global) {
3781                 'use strict';
3782 
3783                 var logObject = {};
3784                 ['log', 'debug', 'warn'].forEach(function (level) {
3785                     var levelExists;
3786 
3787                     try {
3788                         levelExists = global.console && global.console[level] && global.console[level].apply;
3789                     } catch (e) {
3790                         // do nothing
3791                     }
3792 
3793                     logObject[level] = levelExists ? function () {
3794                         return global.console[level].apply(global.console, arguments);
3795                     } : (level === 'log' ? function () {
3796                     } : logObject.log);
3797                 });
3798 
3799                 module.exports = logObject;
3800 
3801             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3802 
3803         }, {}],
3804         49: [function (require, module, exports) {
3805             'use strict';
3806 
3807             module.exports = {
3808                 isObject: function (obj) {
3809                     var type = typeof obj;
3810                     return type === 'function' || type === 'object' && !!obj;
3811                 }
3812 
3813                 , extend: function (obj) {
3814                     if (!this.isObject(obj)) {
3815                         return obj;
3816                     }
3817                     var source, prop;
3818                     for (var i = 1, length = arguments.length; i < length; i++) {
3819                         source = arguments[i];
3820                         for (prop in source) {
3821                             if (Object.prototype.hasOwnProperty.call(source, prop)) {
3822                                 obj[prop] = source[prop];
3823                             }
3824                         }
3825                     }
3826                     return obj;
3827                 }
3828             };
3829 
3830         }, {}],
3831         50: [function (require, module, exports) {
3832             'use strict';
3833 
3834             /* global crypto:true */
3835             var crypto = require('crypto');
3836 
3837 // This string has length 32, a power of 2, so the modulus doesn't introduce a
3838 // bias.
3839             var _randomStringChars = 'abcdefghijklmnopqrstuvwxyz012345';
3840             module.exports = {
3841                 string: function (length) {
3842                     var max = _randomStringChars.length;
3843                     var bytes = crypto.randomBytes(length);
3844                     var ret = [];
3845                     for (var i = 0; i < length; i++) {
3846                         ret.push(_randomStringChars.substr(bytes[i] % max, 1));
3847                     }
3848                     return ret.join('');
3849                 }
3850 
3851                 , number: function (max) {
3852                     return Math.floor(Math.random() * max);
3853                 }
3854 
3855                 , numberString: function (max) {
3856                     var t = ('' + (max - 1)).length;
3857                     var p = new Array(t + 1).join('0');
3858                     return (p + this.number(max)).slice(-t);
3859                 }
3860             };
3861 
3862         }, {"crypto": 43}],
3863         51: [function (require, module, exports) {
3864             (function (process) {
3865                 'use strict';
3866 
3867                 var debug = function () {
3868                 };
3869                 if (process.env.NODE_ENV !== 'production') {
3870                     debug = require('debug')('sockjs-client:utils:transport');
3871                 }
3872 
3873                 module.exports = function (availableTransports) {
3874                     return {
3875                         filterToEnabled: function (transportsWhitelist, info) {
3876                             var transports = {
3877                                 main: []
3878                                 , facade: []
3879                             };
3880                             if (!transportsWhitelist) {
3881                                 transportsWhitelist = [];
3882                             } else if (typeof transportsWhitelist === 'string') {
3883                                 transportsWhitelist = [transportsWhitelist];
3884                             }
3885 
3886                             availableTransports.forEach(function (trans) {
3887                                 if (!trans) {
3888                                     return;
3889                                 }
3890 
3891                                 if (trans.transportName === 'websocket' && info.websocket === false) {
3892                                     debug('disabled from server', 'websocket');
3893                                     return;
3894                                 }
3895 
3896                                 if (transportsWhitelist.length &&
3897                                     transportsWhitelist.indexOf(trans.transportName) === -1) {
3898                                     debug('not in whitelist', trans.transportName);
3899                                     return;
3900                                 }
3901 
3902                                 if (trans.enabled(info)) {
3903                                     debug('enabled', trans.transportName);
3904                                     transports.main.push(trans);
3905                                     if (trans.facadeTransport) {
3906                                         transports.facade.push(trans.facadeTransport);
3907                                     }
3908                                 } else {
3909                                     debug('disabled', trans.transportName);
3910                                 }
3911                             });
3912                             return transports;
3913                         }
3914                     };
3915                 };
3916 
3917             }).call(this, {env: {}})
3918 
3919         }, {"debug": 55}],
3920         52: [function (require, module, exports) {
3921             (function (process) {
3922                 'use strict';
3923 
3924                 var URL = require('url-parse');
3925 
3926                 var debug = function () {
3927                 };
3928                 if (process.env.NODE_ENV !== 'production') {
3929                     debug = require('debug')('sockjs-client:utils:url');
3930                 }
3931 
3932                 module.exports = {
3933                     getOrigin: function (url) {
3934                         if (!url) {
3935                             return null;
3936                         }
3937 
3938                         var p = new URL(url);
3939                         if (p.protocol === 'file:') {
3940                             return null;
3941                         }
3942 
3943                         var port = p.port;
3944                         if (!port) {
3945                             port = (p.protocol === 'https:') ? '443' : '80';
3946                         }
3947 
3948                         return p.protocol + '//' + p.hostname + ':' + port;
3949                     }
3950 
3951                     , isOriginEqual: function (a, b) {
3952                         var res = this.getOrigin(a) === this.getOrigin(b);
3953                         debug('same', a, b, res);
3954                         return res;
3955                     }
3956 
3957                     , isSchemeEqual: function (a, b) {
3958                         return (a.split(':')[0] === b.split(':')[0]);
3959                     }
3960 
3961                     , addPath: function (url, path) {
3962                         var qs = url.split('?');
3963                         return qs[0] + path + (qs[1] ? '?' + qs[1] : '');
3964                     }
3965 
3966                     , addQuery: function (url, q) {
3967                         return url + (url.indexOf('?') === -1 ? ('?' + q) : ('&' + q));
3968                     }
3969                 };
3970 
3971             }).call(this, {env: {}})
3972 
3973         }, {"debug": 55, "url-parse": 61}],
3974         53: [function (require, module, exports) {
3975             module.exports = '1.1.4';
3976 
3977         }, {}],
3978         54: [function (require, module, exports) {
3979             /**
3980              * Helpers.
3981              */
3982 
3983             var s = 1000
3984             var m = s * 60
3985             var h = m * 60
3986             var d = h * 24
3987             var y = d * 365.25
3988 
3989             /**
3990              * Parse or format the given `val`.
3991              *
3992              * Options:
3993              *
3994              *  - `long` verbose formatting [false]
3995              *
3996              * @param {String|Number} val
3997              * @param {Object} [options]
3998              * @throws {Error} throw an error if val is not a non-empty string or a number
3999              * @return {String|Number}
4000              * @api public
4001              */
4002 
4003             module.exports = function (val, options) {
4004                 options = options || {}
4005                 var type = typeof val
4006                 if (type === 'string' && val.length > 0) {
4007                     return parse(val)
4008                 } else if (type === 'number' && isNaN(val) === false) {
4009                     return options.long ?
4010                         fmtLong(val) :
4011                         fmtShort(val)
4012                 }
4013                 throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
4014             }
4015 
4016             /**
4017              * Parse the given `str` and return milliseconds.
4018              *
4019              * @param {String} str
4020              * @return {Number}
4021              * @api private
4022              */
4023 
4024             function parse(str) {
4025                 str = String(str)
4026                 if (str.length > 10000) {
4027                     return
4028                 }
4029                 var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
4030                 if (!match) {
4031                     return
4032                 }
4033                 var n = parseFloat(match[1])
4034                 var type = (match[2] || 'ms').toLowerCase()
4035                 switch (type) {
4036                     case 'years':
4037                     case 'year':
4038                     case 'yrs':
4039                     case 'yr':
4040                     case 'y':
4041                         return n * y
4042                     case 'days':
4043                     case 'day':
4044                     case 'd':
4045                         return n * d
4046                     case 'hours':
4047                     case 'hour':
4048                     case 'hrs':
4049                     case 'hr':
4050                     case 'h':
4051                         return n * h
4052                     case 'minutes':
4053                     case 'minute':
4054                     case 'mins':
4055                     case 'min':
4056                     case 'm':
4057                         return n * m
4058                     case 'seconds':
4059                     case 'second':
4060                     case 'secs':
4061                     case 'sec':
4062                     case 's':
4063                         return n * s
4064                     case 'milliseconds':
4065                     case 'millisecond':
4066                     case 'msecs':
4067                     case 'msec':
4068                     case 'ms':
4069                         return n
4070                     default:
4071                         return undefined
4072                 }
4073             }
4074 
4075             /**
4076              * Short format for `ms`.
4077              *
4078              * @param {Number} ms
4079              * @return {String}
4080              * @api private
4081              */
4082 
4083             function fmtShort(ms) {
4084                 if (ms >= d) {
4085                     return Math.round(ms / d) + 'd'
4086                 }
4087                 if (ms >= h) {
4088                     return Math.round(ms / h) + 'h'
4089                 }
4090                 if (ms >= m) {
4091                     return Math.round(ms / m) + 'm'
4092                 }
4093                 if (ms >= s) {
4094                     return Math.round(ms / s) + 's'
4095                 }
4096                 return ms + 'ms'
4097             }
4098 
4099             /**
4100              * Long format for `ms`.
4101              *
4102              * @param {Number} ms
4103              * @return {String}
4104              * @api private
4105              */
4106 
4107             function fmtLong(ms) {
4108                 return plural(ms, d, 'day') ||
4109                     plural(ms, h, 'hour') ||
4110                     plural(ms, m, 'minute') ||
4111                     plural(ms, s, 'second') ||
4112                     ms + ' ms'
4113             }
4114 
4115             /**
4116              * Pluralization helper.
4117              */
4118 
4119             function plural(ms, n, name) {
4120                 if (ms < n) {
4121                     return
4122                 }
4123                 if (ms < n * 1.5) {
4124                     return Math.floor(ms / n) + ' ' + name
4125                 }
4126                 return Math.ceil(ms / n) + ' ' + name + 's'
4127             }
4128 
4129         }, {}],
4130         55: [function (require, module, exports) {
4131             (function (process) {
4132                 /**
4133                  * This is the web browser implementation of `debug()`.
4134                  *
4135                  * Expose `debug()` as the module.
4136                  */
4137 
4138                 exports = module.exports = require('./debug');
4139                 exports.log = log;
4140                 exports.formatArgs = formatArgs;
4141                 exports.save = save;
4142                 exports.load = load;
4143                 exports.useColors = useColors;
4144                 exports.storage = 'undefined' != typeof chrome
4145                 && 'undefined' != typeof chrome.storage
4146                     ? chrome.storage.local
4147                     : localstorage();
4148 
4149                 /**
4150                  * Colors.
4151                  */
4152 
4153                 exports.colors = [
4154                     'lightseagreen',
4155                     'forestgreen',
4156                     'goldenrod',
4157                     'dodgerblue',
4158                     'darkorchid',
4159                     'crimson'
4160                 ];
4161 
4162                 /**
4163                  * Currently only WebKit-based Web Inspectors, Firefox >= v31,
4164                  * and the Firebug extension (any Firefox version) are known
4165                  * to support "%c" CSS customizations.
4166                  *
4167                  * TODO: add a `localStorage` variable to explicitly enable/disable colors
4168                  */
4169 
4170                 function useColors() {
4171                     // NB: In an Electron preload script, document will be defined but not fully
4172                     // initialized. Since we know we're in Chrome, we'll just detect this case
4173                     // explicitly
4174                     if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
4175                         return true;
4176                     }
4177 
4178                     // is webkit? http://stackoverflow.com/a/16459606/376773
4179                     // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
4180                     return (typeof document !== 'undefined' && document && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
4181                         // is firebug? http://stackoverflow.com/a/398120/376773
4182                         (typeof window !== 'undefined' && window && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
4183                         // is firefox >= v31?
4184                         // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
4185                         (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
4186                         // double check webkit in userAgent just in case we are in a worker
4187                         (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
4188                 }
4189 
4190                 /**
4191                  * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
4192                  */
4193 
4194                 exports.formatters.j = function (v) {
4195                     try {
4196                         return JSON.stringify(v);
4197                     } catch (err) {
4198                         return '[UnexpectedJSONParseError]: ' + err.message;
4199                     }
4200                 };
4201 
4202 
4203                 /**
4204                  * Colorize log arguments if enabled.
4205                  *
4206                  * @api public
4207                  */
4208 
4209                 function formatArgs(args) {
4210                     var useColors = this.useColors;
4211 
4212                     args[0] = (useColors ? '%c' : '')
4213                         + this.namespace
4214                         + (useColors ? ' %c' : ' ')
4215                         + args[0]
4216                         + (useColors ? '%c ' : ' ')
4217                         + '+' + exports.humanize(this.diff);
4218 
4219                     if (!useColors) return;
4220 
4221                     var c = 'color: ' + this.color;
4222                     args.splice(1, 0, c, 'color: inherit')
4223 
4224                     // the final "%c" is somewhat tricky, because there could be other
4225                     // arguments passed either before or after the %c, so we need to
4226                     // figure out the correct index to insert the CSS into
4227                     var index = 0;
4228                     var lastC = 0;
4229                     args[0].replace(/%[a-zA-Z%]/g, function (match) {
4230                         if ('%%' === match) return;
4231                         index++;
4232                         if ('%c' === match) {
4233                             // we only are interested in the *last* %c
4234                             // (the user may have provided their own)
4235                             lastC = index;
4236                         }
4237                     });
4238 
4239                     args.splice(lastC, 0, c);
4240                 }
4241 
4242                 /**
4243                  * Invokes `console.log()` when available.
4244                  * No-op when `console.log` is not a "function".
4245                  *
4246                  * @api public
4247                  */
4248 
4249                 function log() {
4250                     // this hackery is required for IE8/9, where
4251                     // the `console.log` function doesn't have 'apply'
4252                     return 'object' === typeof console
4253                         && console.log
4254                         && Function.prototype.apply.call(console.log, console, arguments);
4255                 }
4256 
4257                 /**
4258                  * Save `namespaces`.
4259                  *
4260                  * @param {String} namespaces
4261                  * @api private
4262                  */
4263 
4264                 function save(namespaces) {
4265                     try {
4266                         if (null == namespaces) {
4267                             exports.storage.removeItem('debug');
4268                         } else {
4269                             exports.storage.debug = namespaces;
4270                         }
4271                     } catch (e) {
4272                     }
4273                 }
4274 
4275                 /**
4276                  * Load `namespaces`.
4277                  *
4278                  * @return {String} returns the previously persisted debug modes
4279                  * @api private
4280                  */
4281 
4282                 function load() {
4283                     var r;
4284                     try {
4285                         r = exports.storage.debug;
4286                     } catch (e) {
4287                     }
4288 
4289                     // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
4290                     if (!r && typeof process !== 'undefined' && 'env' in process) {
4291                         r = process.env.DEBUG;
4292                     }
4293 
4294                     return r;
4295                 }
4296 
4297                 /**
4298                  * Enable namespaces listed in `localStorage.debug` initially.
4299                  */
4300 
4301                 exports.enable(load());
4302 
4303                 /**
4304                  * Localstorage attempts to return the localstorage.
4305                  *
4306                  * This is necessary because safari throws
4307                  * when a user disables cookies/localstorage
4308                  * and you attempt to access it.
4309                  *
4310                  * @return {LocalStorage}
4311                  * @api private
4312                  */
4313 
4314                 function localstorage() {
4315                     try {
4316                         return window.localStorage;
4317                     } catch (e) {
4318                     }
4319                 }
4320 
4321             }).call(this, {env: {}})
4322 
4323         }, {"./debug": 56}],
4324         56: [function (require, module, exports) {
4325 
4326             /**
4327              * This is the common logic for both the Node.js and web browser
4328              * implementations of `debug()`.
4329              *
4330              * Expose `debug()` as the module.
4331              */
4332 
4333             exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
4334             exports.coerce = coerce;
4335             exports.disable = disable;
4336             exports.enable = enable;
4337             exports.enabled = enabled;
4338             exports.humanize = require('ms');
4339 
4340             /**
4341              * The currently active debug mode names, and names to skip.
4342              */
4343 
4344             exports.names = [];
4345             exports.skips = [];
4346 
4347             /**
4348              * Map of special "%n" handling functions, for the debug "format" argument.
4349              *
4350              * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
4351              */
4352 
4353             exports.formatters = {};
4354 
4355             /**
4356              * Previous log timestamp.
4357              */
4358 
4359             var prevTime;
4360 
4361             /**
4362              * Select a color.
4363              * @param {String} namespace
4364              * @return {Number}
4365              * @api private
4366              */
4367 
4368             function selectColor(namespace) {
4369                 var hash = 0, i;
4370 
4371                 for (i in namespace) {
4372                     hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
4373                     hash |= 0; // Convert to 32bit integer
4374                 }
4375 
4376                 return exports.colors[Math.abs(hash) % exports.colors.length];
4377             }
4378 
4379             /**
4380              * Create a debugger with the given `namespace`.
4381              *
4382              * @param {String} namespace
4383              * @return {Function}
4384              * @api public
4385              */
4386 
4387             function createDebug(namespace) {
4388 
4389                 function debug() {
4390                     // disabled?
4391                     if (!debug.enabled) return;
4392 
4393                     var self = debug;
4394 
4395                     // set `diff` timestamp
4396                     var curr = +new Date();
4397                     var ms = curr - (prevTime || curr);
4398                     self.diff = ms;
4399                     self.prev = prevTime;
4400                     self.curr = curr;
4401                     prevTime = curr;
4402 
4403                     // turn the `arguments` into a proper Array
4404                     var args = new Array(arguments.length);
4405                     for (var i = 0; i < args.length; i++) {
4406                         args[i] = arguments[i];
4407                     }
4408 
4409                     args[0] = exports.coerce(args[0]);
4410 
4411                     if ('string' !== typeof args[0]) {
4412                         // anything else let's inspect with %O
4413                         args.unshift('%O');
4414                     }
4415 
4416                     // apply any `formatters` transformations
4417                     var index = 0;
4418                     args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
4419                         // if we encounter an escaped % then don't increase the array index
4420                         if (match === '%%') return match;
4421                         index++;
4422                         var formatter = exports.formatters[format];
4423                         if ('function' === typeof formatter) {
4424                             var val = args[index];
4425                             match = formatter.call(self, val);
4426 
4427                             // now we need to remove `args[index]` since it's inlined in the `format`
4428                             args.splice(index, 1);
4429                             index--;
4430                         }
4431                         return match;
4432                     });
4433 
4434                     // apply env-specific formatting (colors, etc.)
4435                     exports.formatArgs.call(self, args);
4436 
4437                     var logFn = debug.log || exports.log || console.log.bind(console);
4438                     logFn.apply(self, args);
4439                 }
4440 
4441                 debug.namespace = namespace;
4442                 debug.enabled = exports.enabled(namespace);
4443                 debug.useColors = exports.useColors();
4444                 debug.color = selectColor(namespace);
4445 
4446                 // env-specific initialization logic for debug instances
4447                 if ('function' === typeof exports.init) {
4448                     exports.init(debug);
4449                 }
4450 
4451                 return debug;
4452             }
4453 
4454             /**
4455              * Enables a debug mode by namespaces. This can include modes
4456              * separated by a colon and wildcards.
4457              *
4458              * @param {String} namespaces
4459              * @api public
4460              */
4461 
4462             function enable(namespaces) {
4463                 exports.save(namespaces);
4464 
4465                 exports.names = [];
4466                 exports.skips = [];
4467 
4468                 var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
4469                 var len = split.length;
4470 
4471                 for (var i = 0; i < len; i++) {
4472                     if (!split[i]) continue; // ignore empty strings
4473                     namespaces = split[i].replace(/\*/g, '.*?');
4474                     if (namespaces[0] === '-') {
4475                         exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
4476                     } else {
4477                         exports.names.push(new RegExp('^' + namespaces + '$'));
4478                     }
4479                 }
4480             }
4481 
4482             /**
4483              * Disable debug output.
4484              *
4485              * @api public
4486              */
4487 
4488             function disable() {
4489                 exports.enable('');
4490             }
4491 
4492             /**
4493              * Returns true if the given mode name is enabled, false otherwise.
4494              *
4495              * @param {String} name
4496              * @return {Boolean}
4497              * @api public
4498              */
4499 
4500             function enabled(name) {
4501                 var i, len;
4502                 for (i = 0, len = exports.skips.length; i < len; i++) {
4503                     if (exports.skips[i].test(name)) {
4504                         return false;
4505                     }
4506                 }
4507                 for (i = 0, len = exports.names.length; i < len; i++) {
4508                     if (exports.names[i].test(name)) {
4509                         return true;
4510                     }
4511                 }
4512                 return false;
4513             }
4514 
4515             /**
4516              * Coerce `val`.
4517              *
4518              * @param {Mixed} val
4519              * @return {Mixed}
4520              * @api private
4521              */
4522 
4523             function coerce(val) {
4524                 if (val instanceof Error) return val.stack || val.message;
4525                 return val;
4526             }
4527 
4528         }, {"ms": 54}],
4529         57: [function (require, module, exports) {
4530             if (typeof Object.create === 'function') {
4531                 // implementation from standard node.js 'util' module
4532                 module.exports = function inherits(ctor, superCtor) {
4533                     ctor.super_ = superCtor
4534                     ctor.prototype = Object.create(superCtor.prototype, {
4535                         constructor: {
4536                             value: ctor,
4537                             enumerable: false,
4538                             writable: true,
4539                             configurable: true
4540                         }
4541                     });
4542                 };
4543             } else {
4544                 // old school shim for old browsers
4545                 module.exports = function inherits(ctor, superCtor) {
4546                     ctor.super_ = superCtor
4547                     var TempCtor = function () {
4548                     }
4549                     TempCtor.prototype = superCtor.prototype
4550                     ctor.prototype = new TempCtor()
4551                     ctor.prototype.constructor = ctor
4552                 }
4553             }
4554 
4555         }, {}],
4556         58: [function (require, module, exports) {
4557             (function (global) {
4558                 /*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */
4559                 ;(function () {
4560                     // Detect the `define` function exposed by asynchronous module loaders. The
4561                     // strict `define` check is necessary for compatibility with `r.js`.
4562                     var isLoader = typeof define === "function" && define.amd;
4563 
4564                     // A set of types used to distinguish objects from primitives.
4565                     var objectTypes = {
4566                         "function": true,
4567                         "object": true
4568                     };
4569 
4570                     // Detect the `exports` object exposed by CommonJS implementations.
4571                     var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
4572 
4573                     // Use the `global` object exposed by Node (including Browserify via
4574                     // `insert-module-globals`), Narwhal, and Ringo as the default context,
4575                     // and the `window` object in browsers. Rhino exports a `global` function
4576                     // instead.
4577                     var root = objectTypes[typeof window] && window || this,
4578                         freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global;
4579 
4580                     if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) {
4581                         root = freeGlobal;
4582                     }
4583 
4584                     // Public: Initializes JSON 3 using the given `context` object, attaching the
4585                     // `stringify` and `parse` functions to the specified `exports` object.
4586                     function runInContext(context, exports) {
4587                         context || (context = root["Object"]());
4588                         exports || (exports = root["Object"]());
4589 
4590                         // Native constructor aliases.
4591                         var Number = context["Number"] || root["Number"],
4592                             String = context["String"] || root["String"],
4593                             Object = context["Object"] || root["Object"],
4594                             Date = context["Date"] || root["Date"],
4595                             SyntaxError = context["SyntaxError"] || root["SyntaxError"],
4596                             TypeError = context["TypeError"] || root["TypeError"],
4597                             Math = context["Math"] || root["Math"],
4598                             nativeJSON = context["JSON"] || root["JSON"];
4599 
4600                         // Delegate to the native `stringify` and `parse` implementations.
4601                         if (typeof nativeJSON == "object" && nativeJSON) {
4602                             exports.stringify = nativeJSON.stringify;
4603                             exports.parse = nativeJSON.parse;
4604                         }
4605 
4606                         // Convenience aliases.
4607                         var objectProto = Object.prototype,
4608                             getClass = objectProto.toString,
4609                             isProperty, forEach, undef;
4610 
4611                         // Test the `Date#getUTC*` methods. Based on work by @Yaffle.
4612                         var isExtended = new Date(-3509827334573292);
4613                         try {
4614                             // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
4615                             // results for certain dates in Opera >= 10.53.
4616                             isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&
4617                                 // Safari < 2.0.2 stores the internal millisecond time value correctly,
4618                                 // but clips the values returned by the date methods to the range of
4619                                 // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
4620                                 isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
4621                         } catch (exception) {
4622                         }
4623 
4624                         // Internal: Determines whether the native `JSON.stringify` and `parse`
4625                         // implementations are spec-compliant. Based on work by Ken Snyder.
4626                         function has(name) {
4627                             if (has[name] !== undef) {
4628                                 // Return cached feature test result.
4629                                 return has[name];
4630                             }
4631                             var isSupported;
4632                             if (name == "bug-string-char-index") {
4633                                 // IE <= 7 doesn't support accessing string characters using square
4634                                 // bracket notation. IE 8 only supports this for primitives.
4635                                 isSupported = "a"[0] != "a";
4636                             } else if (name == "json") {
4637                                 // Indicates whether both `JSON.stringify` and `JSON.parse` are
4638                                 // supported.
4639                                 isSupported = has("json-stringify") && has("json-parse");
4640                             } else {
4641                                 var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
4642                                 // Test `JSON.stringify`.
4643                                 if (name == "json-stringify") {
4644                                     var stringify = exports.stringify,
4645                                         stringifySupported = typeof stringify == "function" && isExtended;
4646                                     if (stringifySupported) {
4647                                         // A test function object with a custom `toJSON` method.
4648                                         (value = function () {
4649                                             return 1;
4650                                         }).toJSON = value;
4651                                         try {
4652                                             stringifySupported =
4653                                                 // Firefox 3.1b1 and b2 serialize string, number, and boolean
4654                                                 // primitives as object literals.
4655                                                 stringify(0) === "0" &&
4656                                                 // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
4657                                                 // literals.
4658                                                 stringify(new Number()) === "0" &&
4659                                                 stringify(new String()) == '""' &&
4660                                                 // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
4661                                                 // does not define a canonical JSON representation (this applies to
4662                                                 // objects with `toJSON` properties as well, *unless* they are nested
4663                                                 // within an object or array).
4664                                                 stringify(getClass) === undef &&
4665                                                 // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
4666                                                 // FF 3.1b3 pass this test.
4667                                                 stringify(undef) === undef &&
4668                                                 // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
4669                                                 // respectively, if the value is omitted entirely.
4670                                                 stringify() === undef &&
4671                                                 // FF 3.1b1, 2 throw an error if the given value is not a number,
4672                                                 // string, array, object, Boolean, or `null` literal. This applies to
4673                                                 // objects with custom `toJSON` methods as well, unless they are nested
4674                                                 // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
4675                                                 // methods entirely.
4676                                                 stringify(value) === "1" &&
4677                                                 stringify([value]) == "[1]" &&
4678                                                 // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
4679                                                 // `"[null]"`.
4680                                                 stringify([undef]) == "[null]" &&
4681                                                 // YUI 3.0.0b1 fails to serialize `null` literals.
4682                                                 stringify(null) == "null" &&
4683                                                 // FF 3.1b1, 2 halts serialization if an array contains a function:
4684                                                 // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
4685                                                 // elides non-JSON values from objects and arrays, unless they
4686                                                 // define custom `toJSON` methods.
4687                                                 stringify([undef, getClass, null]) == "[null,null,null]" &&
4688                                                 // Simple serialization test. FF 3.1b1 uses Unicode escape sequences
4689                                                 // where character escape codes are expected (e.g., `\b` => `\u0008`).
4690                                                 stringify({"a": [value, true, false, null, "\x00\b\n\f\r\t"]}) == serialized &&
4691                                                 // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
4692                                                 stringify(null, value) === "1" &&
4693                                                 stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
4694                                                 // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
4695                                                 // serialize extended years.
4696                                                 stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
4697                                                 // The milliseconds are optional in ES 5, but required in 5.1.
4698                                                 stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
4699                                                 // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
4700                                                 // four-digit years instead of six-digit years. Credits: @Yaffle.
4701                                                 stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
4702                                                 // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
4703                                                 // values less than 1000. Credits: @Yaffle.
4704                                                 stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
4705                                         } catch (exception) {
4706                                             stringifySupported = false;
4707                                         }
4708                                     }
4709                                     isSupported = stringifySupported;
4710                                 }
4711                                 // Test `JSON.parse`.
4712                                 if (name == "json-parse") {
4713                                     var parse = exports.parse;
4714                                     if (typeof parse == "function") {
4715                                         try {
4716                                             // FF 3.1b1, b2 will throw an exception if a bare literal is provided.
4717                                             // Conforming implementations should also coerce the initial argument to
4718                                             // a string prior to parsing.
4719                                             if (parse("0") === 0 && !parse(false)) {
4720                                                 // Simple parsing test.
4721                                                 value = parse(serialized);
4722                                                 var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
4723                                                 if (parseSupported) {
4724                                                     try {
4725                                                         // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
4726                                                         parseSupported = !parse('"\t"');
4727                                                     } catch (exception) {
4728                                                     }
4729                                                     if (parseSupported) {
4730                                                         try {
4731                                                             // FF 4.0 and 4.0.1 allow leading `+` signs and leading
4732                                                             // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
4733                                                             // certain octal literals.
4734                                                             parseSupported = parse("01") !== 1;
4735                                                         } catch (exception) {
4736                                                         }
4737                                                     }
4738                                                     if (parseSupported) {
4739                                                         try {
4740                                                             // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
4741                                                             // points. These environments, along with FF 3.1b1 and 2,
4742                                                             // also allow trailing commas in JSON objects and arrays.
4743                                                             parseSupported = parse("1.") !== 1;
4744                                                         } catch (exception) {
4745                                                         }
4746                                                     }
4747                                                 }
4748                                             }
4749                                         } catch (exception) {
4750                                             parseSupported = false;
4751                                         }
4752                                     }
4753                                     isSupported = parseSupported;
4754                                 }
4755                             }
4756                             return has[name] = !!isSupported;
4757                         }
4758 
4759                         if (!has("json")) {
4760                             // Common `[[Class]]` name aliases.
4761                             var functionClass = "[object Function]",
4762                                 dateClass = "[object Date]",
4763                                 numberClass = "[object Number]",
4764                                 stringClass = "[object String]",
4765                                 arrayClass = "[object Array]",
4766                                 booleanClass = "[object Boolean]";
4767 
4768                             // Detect incomplete support for accessing string characters by index.
4769                             var charIndexBuggy = has("bug-string-char-index");
4770 
4771                             // Define additional utility methods if the `Date` methods are buggy.
4772                             if (!isExtended) {
4773                                 var floor = Math.floor;
4774                                 // A mapping between the months of the year and the number of days between
4775                                 // January 1st and the first of the respective month.
4776                                 var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
4777                                 // Internal: Calculates the number of days between the Unix epoch and the
4778                                 // first day of the given month.
4779                                 var getDay = function (year, month) {
4780                                     return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
4781                                 };
4782                             }
4783 
4784                             // Internal: Determines if a property is a direct property of the given
4785                             // object. Delegates to the native `Object#hasOwnProperty` method.
4786                             if (!(isProperty = objectProto.hasOwnProperty)) {
4787                                 isProperty = function (property) {
4788                                     var members = {}, constructor;
4789                                     if ((members.__proto__ = null, members.__proto__ = {
4790                                             // The *proto* property cannot be set multiple times in recent
4791                                             // versions of Firefox and SeaMonkey.
4792                                             "toString": 1
4793                                         }, members).toString != getClass) {
4794                                         // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
4795                                         // supports the mutable *proto* property.
4796                                         isProperty = function (property) {
4797                                             // Capture and break the object's prototype chain (see section 8.6.2
4798                                             // of the ES 5.1 spec). The parenthesized expression prevents an
4799                                             // unsafe transformation by the Closure Compiler.
4800                                             var original = this.__proto__,
4801                                                 result = property in (this.__proto__ = null, this);
4802                                             // Restore the original prototype chain.
4803                                             this.__proto__ = original;
4804                                             return result;
4805                                         };
4806                                     } else {
4807                                         // Capture a reference to the top-level `Object` constructor.
4808                                         constructor = members.constructor;
4809                                         // Use the `constructor` property to simulate `Object#hasOwnProperty` in
4810                                         // other environments.
4811                                         isProperty = function (property) {
4812                                             var parent = (this.constructor || constructor).prototype;
4813                                             return property in this && !(property in parent && this[property] === parent[property]);
4814                                         };
4815                                     }
4816                                     members = null;
4817                                     return isProperty.call(this, property);
4818                                 };
4819                             }
4820 
4821                             // Internal: Normalizes the `for...in` iteration algorithm across
4822                             // environments. Each enumerated key is yielded to a `callback` function.
4823                             forEach = function (object, callback) {
4824                                 var size = 0, Properties, members, property;
4825 
4826                                 // Tests for bugs in the current environment's `for...in` algorithm. The
4827                                 // `valueOf` property inherits the non-enumerable flag from
4828                                 // `Object.prototype` in older versions of IE, Netscape, and Mozilla.
4829                                 (Properties = function () {
4830                                     this.valueOf = 0;
4831                                 }).prototype.valueOf = 0;
4832 
4833                                 // Iterate over a new instance of the `Properties` class.
4834                                 members = new Properties();
4835                                 for (property in members) {
4836                                     // Ignore all properties inherited from `Object.prototype`.
4837                                     if (isProperty.call(members, property)) {
4838                                         size++;
4839                                     }
4840                                 }
4841                                 Properties = members = null;
4842 
4843                                 // Normalize the iteration algorithm.
4844                                 if (!size) {
4845                                     // A list of non-enumerable properties inherited from `Object.prototype`.
4846                                     members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
4847                                     // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
4848                                     // properties.
4849                                     forEach = function (object, callback) {
4850                                         var isFunction = getClass.call(object) == functionClass, property, length;
4851                                         var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;
4852                                         for (property in object) {
4853                                             // Gecko <= 1.0 enumerates the `prototype` property of functions under
4854                                             // certain conditions; IE does not.
4855                                             if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) {
4856                                                 callback(property);
4857                                             }
4858                                         }
4859                                         // Manually invoke the callback for each non-enumerable property.
4860                                         for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)) ;
4861                                     };
4862                                 } else if (size == 2) {
4863                                     // Safari <= 2.0.4 enumerates shadowed properties twice.
4864                                     forEach = function (object, callback) {
4865                                         // Create a set of iterated properties.
4866                                         var members = {}, isFunction = getClass.call(object) == functionClass, property;
4867                                         for (property in object) {
4868                                             // Store each property name to prevent double enumeration. The
4869                                             // `prototype` property of functions is not enumerated due to cross-
4870                                             // environment inconsistencies.
4871                                             if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
4872                                                 callback(property);
4873                                             }
4874                                         }
4875                                     };
4876                                 } else {
4877                                     // No bugs detected; use the standard `for...in` algorithm.
4878                                     forEach = function (object, callback) {
4879                                         var isFunction = getClass.call(object) == functionClass, property,
4880                                             isConstructor;
4881                                         for (property in object) {
4882                                             if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
4883                                                 callback(property);
4884                                             }
4885                                         }
4886                                         // Manually invoke the callback for the `constructor` property due to
4887                                         // cross-environment inconsistencies.
4888                                         if (isConstructor || isProperty.call(object, (property = "constructor"))) {
4889                                             callback(property);
4890                                         }
4891                                     };
4892                                 }
4893                                 return forEach(object, callback);
4894                             };
4895 
4896                             // Public: Serializes a JavaScript `value` as a JSON string. The optional
4897                             // `filter` argument may specify either a function that alters how object and
4898                             // array members are serialized, or an array of strings and numbers that
4899                             // indicates which properties should be serialized. The optional `width`
4900                             // argument may be either a string or number that specifies the indentation
4901                             // level of the output.
4902                             if (!has("json-stringify")) {
4903                                 // Internal: A map of control characters and their escaped equivalents.
4904                                 var Escapes = {
4905                                     92: "\\\\",
4906                                     34: '\\"',
4907                                     8: "\\b",
4908                                     12: "\\f",
4909                                     10: "\\n",
4910                                     13: "\\r",
4911                                     9: "\\t"
4912                                 };
4913 
4914                                 // Internal: Converts `value` into a zero-padded string such that its
4915                                 // length is at least equal to `width`. The `width` must be <= 6.
4916                                 var leadingZeroes = "000000";
4917                                 var toPaddedString = function (width, value) {
4918                                     // The `|| 0` expression is necessary to work around a bug in
4919                                     // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
4920                                     return (leadingZeroes + (value || 0)).slice(-width);
4921                                 };
4922 
4923                                 // Internal: Double-quotes a string `value`, replacing all ASCII control
4924                                 // characters (characters with code unit values between 0 and 31) with
4925                                 // their escaped equivalents. This is an implementation of the
4926                                 // `Quote(value)` operation defined in ES 5.1 section 15.12.3.
4927                                 var unicodePrefix = "\\u00";
4928                                 var quote = function (value) {
4929                                     var result = '"', index = 0, length = value.length,
4930                                         useCharIndex = !charIndexBuggy || length > 10;
4931                                     var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value);
4932                                     for (; index < length; index++) {
4933                                         var charCode = value.charCodeAt(index);
4934                                         // If the character is a control character, append its Unicode or
4935                                         // shorthand escape sequence; otherwise, append the character as-is.
4936                                         switch (charCode) {
4937                                             case 8:
4938                                             case 9:
4939                                             case 10:
4940                                             case 12:
4941                                             case 13:
4942                                             case 34:
4943                                             case 92:
4944                                                 result += Escapes[charCode];
4945                                                 break;
4946                                             default:
4947                                                 if (charCode < 32) {
4948                                                     result += unicodePrefix + toPaddedString(2, charCode.toString(16));
4949                                                     break;
4950                                                 }
4951                                                 result += useCharIndex ? symbols[index] : value.charAt(index);
4952                                         }
4953                                     }
4954                                     return result + '"';
4955                                 };
4956 
4957                                 // Internal: Recursively serializes an object. Implements the
4958                                 // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
4959                                 var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
4960                                     var value, className, year, month, date, time, hours, minutes, seconds,
4961                                         milliseconds, results, element, index, length, prefix, result;
4962                                     try {
4963                                         // Necessary for host object support.
4964                                         value = object[property];
4965                                     } catch (exception) {
4966                                     }
4967                                     if (typeof value == "object" && value) {
4968                                         className = getClass.call(value);
4969                                         if (className == dateClass && !isProperty.call(value, "toJSON")) {
4970                                             if (value > -1 / 0 && value < 1 / 0) {
4971                                                 // Dates are serialized according to the `Date#toJSON` method
4972                                                 // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
4973                                                 // for the ISO 8601 date time string format.
4974                                                 if (getDay) {
4975                                                     // Manually compute the year, month, date, hours, minutes,
4976                                                     // seconds, and milliseconds if the `getUTC*` methods are
4977                                                     // buggy. Adapted from @Yaffle's `date-shim` project.
4978                                                     date = floor(value / 864e5);
4979                                                     for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++) ;
4980                                                     for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++) ;
4981                                                     date = 1 + date - getDay(year, month);
4982                                                     // The `time` value specifies the time within the day (see ES
4983                                                     // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
4984                                                     // to compute `A modulo B`, as the `%` operator does not
4985                                                     // correspond to the `modulo` operation for negative numbers.
4986                                                     time = (value % 864e5 + 864e5) % 864e5;
4987                                                     // The hours, minutes, seconds, and milliseconds are obtained by
4988                                                     // decomposing the time within the day. See section 15.9.1.10.
4989                                                     hours = floor(time / 36e5) % 24;
4990                                                     minutes = floor(time / 6e4) % 60;
4991                                                     seconds = floor(time / 1e3) % 60;
4992                                                     milliseconds = time % 1e3;
4993                                                 } else {
4994                                                     year = value.getUTCFullYear();
4995                                                     month = value.getUTCMonth();
4996                                                     date = value.getUTCDate();
4997                                                     hours = value.getUTCHours();
4998                                                     minutes = value.getUTCMinutes();
4999                                                     seconds = value.getUTCSeconds();
5000                                                     milliseconds = value.getUTCMilliseconds();
5001                                                 }
5002                                                 // Serialize extended years correctly.
5003                                                 value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
5004                                                     "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
5005                                                     // Months, dates, hours, minutes, and seconds should have two
5006                                                     // digits; milliseconds should have three.
5007                                                     "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
5008                                                     // Milliseconds are optional in ES 5.0, but required in 5.1.
5009                                                     "." + toPaddedString(3, milliseconds) + "Z";
5010                                             } else {
5011                                                 value = null;
5012                                             }
5013                                         } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) {
5014                                             // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
5015                                             // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
5016                                             // ignores all `toJSON` methods on these objects unless they are
5017                                             // defined directly on an instance.
5018                                             value = value.toJSON(property);
5019                                         }
5020                                     }
5021                                     if (callback) {
5022                                         // If a replacement function was provided, call it to obtain the value
5023                                         // for serialization.
5024                                         value = callback.call(object, property, value);
5025                                     }
5026                                     if (value === null) {
5027                                         return "null";
5028                                     }
5029                                     className = getClass.call(value);
5030                                     if (className == booleanClass) {
5031                                         // Booleans are represented literally.
5032                                         return "" + value;
5033                                     } else if (className == numberClass) {
5034                                         // JSON numbers must be finite. `Infinity` and `NaN` are serialized as
5035                                         // `"null"`.
5036                                         return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
5037                                     } else if (className == stringClass) {
5038                                         // Strings are double-quoted and escaped.
5039                                         return quote("" + value);
5040                                     }
5041                                     // Recursively serialize objects and arrays.
5042                                     if (typeof value == "object") {
5043                                         // Check for cyclic structures. This is a linear search; performance
5044                                         // is inversely proportional to the number of unique nested objects.
5045                                         for (length = stack.length; length--;) {
5046                                             if (stack[length] === value) {
5047                                                 // Cyclic structures cannot be serialized by `JSON.stringify`.
5048                                                 throw TypeError();
5049                                             }
5050                                         }
5051                                         // Add the object to the stack of traversed objects.
5052                                         stack.push(value);
5053                                         results = [];
5054                                         // Save the current indentation level and indent one additional level.
5055                                         prefix = indentation;
5056                                         indentation += whitespace;
5057                                         if (className == arrayClass) {
5058                                             // Recursively serialize array elements.
5059                                             for (index = 0, length = value.length; index < length; index++) {
5060                                                 element = serialize(index, value, callback, properties, whitespace, indentation, stack);
5061                                                 results.push(element === undef ? "null" : element);
5062                                             }
5063                                             result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
5064                                         } else {
5065                                             // Recursively serialize object members. Members are selected from
5066                                             // either a user-specified list of property names, or the object
5067                                             // itself.
5068                                             forEach(properties || value, function (property) {
5069                                                 var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
5070                                                 if (element !== undef) {
5071                                                     // According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
5072                                                     // is not the empty string, let `member` {quote(property) + ":"}
5073                                                     // be the concatenation of `member` and the `space` character."
5074                                                     // The "`space` character" refers to the literal space
5075                                                     // character, not the `space` {width} argument provided to
5076                                                     // `JSON.stringify`.
5077                                                     results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
5078                                                 }
5079                                             });
5080                                             result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
5081                                         }
5082                                         // Remove the object from the traversed object stack.
5083                                         stack.pop();
5084                                         return result;
5085                                     }
5086                                 };
5087 
5088                                 // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
5089                                 exports.stringify = function (source, filter, width) {
5090                                     var whitespace, callback, properties, className;
5091                                     if (objectTypes[typeof filter] && filter) {
5092                                         if ((className = getClass.call(filter)) == functionClass) {
5093                                             callback = filter;
5094                                         } else if (className == arrayClass) {
5095                                             // Convert the property names array into a makeshift set.
5096                                             properties = {};
5097                                             for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)) ;
5098                                         }
5099                                     }
5100                                     if (width) {
5101                                         if ((className = getClass.call(width)) == numberClass) {
5102                                             // Convert the `width` to an integer and create a string containing
5103                                             // `width` number of space characters.
5104                                             if ((width -= width % 1) > 0) {
5105                                                 for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ") ;
5106                                             }
5107                                         } else if (className == stringClass) {
5108                                             whitespace = width.length <= 10 ? width : width.slice(0, 10);
5109                                         }
5110                                     }
5111                                     // Opera <= 7.54u2 discards the values associated with empty string keys
5112                                     // (`""`) only if they are used directly within an object member list
5113                                     // (e.g., `!("" in { "": 1})`).
5114                                     return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
5115                                 };
5116                             }
5117 
5118                             // Public: Parses a JSON source string.
5119                             if (!has("json-parse")) {
5120                                 var fromCharCode = String.fromCharCode;
5121 
5122                                 // Internal: A map of escaped control characters and their unescaped
5123                                 // equivalents.
5124                                 var Unescapes = {
5125                                     92: "\\",
5126                                     34: '"',
5127                                     47: "/",
5128                                     98: "\b",
5129                                     116: "\t",
5130                                     110: "\n",
5131                                     102: "\f",
5132                                     114: "\r"
5133                                 };
5134 
5135                                 // Internal: Stores the parser state.
5136                                 var Index, Source;
5137 
5138                                 // Internal: Resets the parser state and throws a `SyntaxError`.
5139                                 var abort = function () {
5140                                     Index = Source = null;
5141                                     throw SyntaxError();
5142                                 };
5143 
5144                                 // Internal: Returns the next token, or `"$"` if the parser has reached
5145                                 // the end of the source string. A token may be a string, number, `null`
5146                                 // literal, or Boolean literal.
5147                                 var lex = function () {
5148                                     var source = Source, length = source.length, value, begin, position, isSigned,
5149                                         charCode;
5150                                     while (Index < length) {
5151                                         charCode = source.charCodeAt(Index);
5152                                         switch (charCode) {
5153                                             case 9:
5154                                             case 10:
5155                                             case 13:
5156                                             case 32:
5157                                                 // Skip whitespace tokens, including tabs, carriage returns, line
5158                                                 // feeds, and space characters.
5159                                                 Index++;
5160                                                 break;
5161                                             case 123:
5162                                             case 125:
5163                                             case 91:
5164                                             case 93:
5165                                             case 58:
5166                                             case 44:
5167                                                 // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
5168                                                 // the current position.
5169                                                 value = charIndexBuggy ? source.charAt(Index) : source[Index];
5170                                                 Index++;
5171                                                 return value;
5172                                             case 34:
5173                                                 // `"` delimits a JSON string; advance to the next character and
5174                                                 // begin parsing the string. String tokens are prefixed with the
5175                                                 // sentinel `@` character to distinguish them from punctuators and
5176                                                 // end-of-string tokens.
5177                                                 for (value = "@", Index++; Index < length;) {
5178                                                     charCode = source.charCodeAt(Index);
5179                                                     if (charCode < 32) {
5180                                                         // Unescaped ASCII control characters (those with a code unit
5181                                                         // less than the space character) are not permitted.
5182                                                         abort();
5183                                                     } else if (charCode == 92) {
5184                                                         // A reverse solidus (`\`) marks the beginning of an escaped
5185                                                         // control character (including `"`, `\`, and `/`) or Unicode
5186                                                         // escape sequence.
5187                                                         charCode = source.charCodeAt(++Index);
5188                                                         switch (charCode) {
5189                                                             case 92:
5190                                                             case 34:
5191                                                             case 47:
5192                                                             case 98:
5193                                                             case 116:
5194                                                             case 110:
5195                                                             case 102:
5196                                                             case 114:
5197                                                                 // Revive escaped control characters.
5198                                                                 value += Unescapes[charCode];
5199                                                                 Index++;
5200                                                                 break;
5201                                                             case 117:
5202                                                                 // `\u` marks the beginning of a Unicode escape sequence.
5203                                                                 // Advance to the first character and validate the
5204                                                                 // four-digit code point.
5205                                                                 begin = ++Index;
5206                                                                 for (position = Index + 4; Index < position; Index++) {
5207                                                                     charCode = source.charCodeAt(Index);
5208                                                                     // A valid sequence comprises four hexdigits (case-
5209                                                                     // insensitive) that form a single hexadecimal value.
5210                                                                     if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {
5211                                                                         // Invalid Unicode escape sequence.
5212                                                                         abort();
5213                                                                     }
5214                                                                 }
5215                                                                 // Revive the escaped character.
5216                                                                 value += fromCharCode("0x" + source.slice(begin, Index));
5217                                                                 break;
5218                                                             default:
5219                                                                 // Invalid escape sequence.
5220                                                                 abort();
5221                                                         }
5222                                                     } else {
5223                                                         if (charCode == 34) {
5224                                                             // An unescaped double-quote character marks the end of the
5225                                                             // string.
5226                                                             break;
5227                                                         }
5228                                                         charCode = source.charCodeAt(Index);
5229                                                         begin = Index;
5230                                                         // Optimize for the common case where a string is valid.
5231                                                         while (charCode >= 32 && charCode != 92 && charCode != 34) {
5232                                                             charCode = source.charCodeAt(++Index);
5233                                                         }
5234                                                         // Append the string as-is.
5235                                                         value += source.slice(begin, Index);
5236                                                     }
5237                                                 }
5238                                                 if (source.charCodeAt(Index) == 34) {
5239                                                     // Advance to the next character and return the revived string.
5240                                                     Index++;
5241                                                     return value;
5242                                                 }
5243                                                 // Unterminated string.
5244                                                 abort();
5245                                             default:
5246                                                 // Parse numbers and literals.
5247                                                 begin = Index;
5248                                                 // Advance past the negative sign, if one is specified.
5249                                                 if (charCode == 45) {
5250                                                     isSigned = true;
5251                                                     charCode = source.charCodeAt(++Index);
5252                                                 }
5253                                                 // Parse an integer or floating-point value.
5254                                                 if (charCode >= 48 && charCode <= 57) {
5255                                                     // Leading zeroes are interpreted as octal literals.
5256                                                     if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {
5257                                                         // Illegal octal literal.
5258                                                         abort();
5259                                                     }
5260                                                     isSigned = false;
5261                                                     // Parse the integer component.
5262                                                     for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++) ;
5263                                                     // Floats cannot contain a leading decimal point; however, this
5264                                                     // case is already accounted for by the parser.
5265                                                     if (source.charCodeAt(Index) == 46) {
5266                                                         position = ++Index;
5267                                                         // Parse the decimal component.
5268                                                         for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++) ;
5269                                                         if (position == Index) {
5270                                                             // Illegal trailing decimal.
5271                                                             abort();
5272                                                         }
5273                                                         Index = position;
5274                                                     }
5275                                                     // Parse exponents. The `e` denoting the exponent is
5276                                                     // case-insensitive.
5277                                                     charCode = source.charCodeAt(Index);
5278                                                     if (charCode == 101 || charCode == 69) {
5279                                                         charCode = source.charCodeAt(++Index);
5280                                                         // Skip past the sign following the exponent, if one is
5281                                                         // specified.
5282                                                         if (charCode == 43 || charCode == 45) {
5283                                                             Index++;
5284                                                         }
5285                                                         // Parse the exponential component.
5286                                                         for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++) ;
5287                                                         if (position == Index) {
5288                                                             // Illegal empty exponent.
5289                                                             abort();
5290                                                         }
5291                                                         Index = position;
5292                                                     }
5293                                                     // Coerce the parsed value to a JavaScript number.
5294                                                     return +source.slice(begin, Index);
5295                                                 }
5296                                                 // A negative sign may only precede numbers.
5297                                                 if (isSigned) {
5298                                                     abort();
5299                                                 }
5300                                                 // `true`, `false`, and `null` literals.
5301                                                 if (source.slice(Index, Index + 4) == "true") {
5302                                                     Index += 4;
5303                                                     return true;
5304                                                 } else if (source.slice(Index, Index + 5) == "false") {
5305                                                     Index += 5;
5306                                                     return false;
5307                                                 } else if (source.slice(Index, Index + 4) == "null") {
5308                                                     Index += 4;
5309                                                     return null;
5310                                                 }
5311                                                 // Unrecognized token.
5312                                                 abort();
5313                                         }
5314                                     }
5315                                     // Return the sentinel `$` character if the parser has reached the end
5316                                     // of the source string.
5317                                     return "$";
5318                                 };
5319 
5320                                 // Internal: Parses a JSON `value` token.
5321                                 var get = function (value) {
5322                                     var results, hasMembers;
5323                                     if (value == "$") {
5324                                         // Unexpected end of input.
5325                                         abort();
5326                                     }
5327                                     if (typeof value == "string") {
5328                                         if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") {
5329                                             // Remove the sentinel `@` character.
5330                                             return value.slice(1);
5331                                         }
5332                                         // Parse object and array literals.
5333                                         if (value == "[") {
5334                                             // Parses a JSON array, returning a new JavaScript array.
5335                                             results = [];
5336                                             for (; ; hasMembers || (hasMembers = true)) {
5337                                                 value = lex();
5338                                                 // A closing square bracket marks the end of the array literal.
5339                                                 if (value == "]") {
5340                                                     break;
5341                                                 }
5342                                                 // If the array literal contains elements, the current token
5343                                                 // should be a comma separating the previous element from the
5344                                                 // next.
5345                                                 if (hasMembers) {
5346                                                     if (value == ",") {
5347                                                         value = lex();
5348                                                         if (value == "]") {
5349                                                             // Unexpected trailing `,` in array literal.
5350                                                             abort();
5351                                                         }
5352                                                     } else {
5353                                                         // A `,` must separate each array element.
5354                                                         abort();
5355                                                     }
5356                                                 }
5357                                                 // Elisions and leading commas are not permitted.
5358                                                 if (value == ",") {
5359                                                     abort();
5360                                                 }
5361                                                 results.push(get(value));
5362                                             }
5363                                             return results;
5364                                         } else if (value == "{") {
5365                                             // Parses a JSON object, returning a new JavaScript object.
5366                                             results = {};
5367                                             for (; ; hasMembers || (hasMembers = true)) {
5368                                                 value = lex();
5369                                                 // A closing curly brace marks the end of the object literal.
5370                                                 if (value == "}") {
5371                                                     break;
5372                                                 }
5373                                                 // If the object literal contains members, the current token
5374                                                 // should be a comma separator.
5375                                                 if (hasMembers) {
5376                                                     if (value == ",") {
5377                                                         value = lex();
5378                                                         if (value == "}") {
5379                                                             // Unexpected trailing `,` in object literal.
5380                                                             abort();
5381                                                         }
5382                                                     } else {
5383                                                         // A `,` must separate each object member.
5384                                                         abort();
5385                                                     }
5386                                                 }
5387                                                 // Leading commas are not permitted, object property names must be
5388                                                 // double-quoted strings, and a `:` must separate each property
5389                                                 // name and value.
5390                                                 if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") {
5391                                                     abort();
5392                                                 }
5393                                                 results[value.slice(1)] = get(lex());
5394                                             }
5395                                             return results;
5396                                         }
5397                                         // Unexpected token encountered.
5398                                         abort();
5399                                     }
5400                                     return value;
5401                                 };
5402 
5403                                 // Internal: Updates a traversed object member.
5404                                 var update = function (source, property, callback) {
5405                                     var element = walk(source, property, callback);
5406                                     if (element === undef) {
5407                                         delete source[property];
5408                                     } else {
5409                                         source[property] = element;
5410                                     }
5411                                 };
5412 
5413                                 // Internal: Recursively traverses a parsed JSON object, invoking the
5414                                 // `callback` function for each value. This is an implementation of the
5415                                 // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
5416                                 var walk = function (source, property, callback) {
5417                                     var value = source[property], length;
5418                                     if (typeof value == "object" && value) {
5419                                         // `forEach` can't be used to traverse an array in Opera <= 8.54
5420                                         // because its `Object#hasOwnProperty` implementation returns `false`
5421                                         // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
5422                                         if (getClass.call(value) == arrayClass) {
5423                                             for (length = value.length; length--;) {
5424                                                 update(value, length, callback);
5425                                             }
5426                                         } else {
5427                                             forEach(value, function (property) {
5428                                                 update(value, property, callback);
5429                                             });
5430                                         }
5431                                     }
5432                                     return callback.call(source, property, value);
5433                                 };
5434 
5435                                 // Public: `JSON.parse`. See ES 5.1 section 15.12.2.
5436                                 exports.parse = function (source, callback) {
5437                                     var result, value;
5438                                     Index = 0;
5439                                     Source = "" + source;
5440                                     result = get(lex());
5441                                     // If a JSON string contains multiple tokens, it is invalid.
5442                                     if (lex() != "$") {
5443                                         abort();
5444                                     }
5445                                     // Reset the parser state.
5446                                     Index = Source = null;
5447                                     return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result;
5448                                 };
5449                             }
5450                         }
5451 
5452                         exports["runInContext"] = runInContext;
5453                         return exports;
5454                     }
5455 
5456                     if (freeExports && !isLoader) {
5457                         // Export for CommonJS environments.
5458                         runInContext(root, freeExports);
5459                     } else {
5460                         // Export for web browsers and JavaScript engines.
5461                         var nativeJSON = root.JSON,
5462                             previousJSON = root["JSON3"],
5463                             isRestored = false;
5464 
5465                         var JSON3 = runInContext(root, (root["JSON3"] = {
5466                             // Public: Restores the original value of the global `JSON` object and
5467                             // returns a reference to the `JSON3` object.
5468                             "noConflict": function () {
5469                                 if (!isRestored) {
5470                                     isRestored = true;
5471                                     root.JSON = nativeJSON;
5472                                     root["JSON3"] = previousJSON;
5473                                     nativeJSON = previousJSON = null;
5474                                 }
5475                                 return JSON3;
5476                             }
5477                         }));
5478 
5479                         root.JSON = {
5480                             "parse": JSON3.parse,
5481                             "stringify": JSON3.stringify
5482                         };
5483                     }
5484 
5485                     // Export for asynchronous module loaders.
5486                     if (isLoader) {
5487                         define(function () {
5488                             return JSON3;
5489                         });
5490                     }
5491                 }).call(this);
5492 
5493             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
5494 
5495         }, {}],
5496         59: [function (require, module, exports) {
5497             'use strict';
5498 
5499             var has = Object.prototype.hasOwnProperty;
5500 
5501             /**
5502              * Simple query string parser.
5503              *
5504              * @param {String} query The query string that needs to be parsed.
5505              * @returns {Object}
5506              * @api public
5507              */
5508             function querystring(query) {
5509                 var parser = /([^=?&]+)=?([^&]*)/g
5510                     , result = {}
5511                     , part;
5512 
5513                 //
5514                 // Little nifty parsing hack, leverage the fact that RegExp.exec increments
5515                 // the lastIndex property so we can continue executing this loop until we've
5516                 // parsed all results.
5517                 //
5518                 for (;
5519                     part = parser.exec(query);
5520                     result[decodeURIComponent(part[1])] = decodeURIComponent(part[2])
5521                 ) ;
5522 
5523                 return result;
5524             }
5525 
5526             /**
5527              * Transform a query string to an object.
5528              *
5529              * @param {Object} obj Object that should be transformed.
5530              * @param {String} prefix Optional prefix.
5531              * @returns {String}
5532              * @api public
5533              */
5534             function querystringify(obj, prefix) {
5535                 prefix = prefix || '';
5536 
5537                 var pairs = [];
5538 
5539                 //
5540                 // Optionally prefix with a '?' if needed
5541                 //
5542                 if ('string' !== typeof prefix) prefix = '?';
5543 
5544                 for (var key in obj) {
5545                     if (has.call(obj, key)) {
5546                         pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
5547                     }
5548                 }
5549 
5550                 return pairs.length ? prefix + pairs.join('&') : '';
5551             }
5552 
5553 //
5554 // Expose the module.
5555 //
5556             exports.stringify = querystringify;
5557             exports.parse = querystring;
5558 
5559         }, {}],
5560         60: [function (require, module, exports) {
5561             'use strict';
5562 
5563             /**
5564              * Check if we're required to add a port number.
5565              *
5566              * @see https://url.spec.whatwg.org/#default-port
5567              * @param {Number|String} port Port number we need to check
5568              * @param {String} protocol Protocol we need to check against.
5569              * @returns {Boolean} Is it a default port for the given protocol
5570              * @api private
5571              */
5572             module.exports = function required(port, protocol) {
5573                 protocol = protocol.split(':')[0];
5574                 port = +port;
5575 
5576                 if (!port) return false;
5577 
5578                 switch (protocol) {
5579                     case 'http':
5580                     case 'ws':
5581                         return port !== 80;
5582 
5583                     case 'https':
5584                     case 'wss':
5585                         return port !== 443;
5586 
5587                     case 'ftp':
5588                         return port !== 21;
5589 
5590                     case 'gopher':
5591                         return port !== 70;
5592 
5593                     case 'file':
5594                         return false;
5595                 }
5596 
5597                 return port !== 0;
5598             };
5599 
5600         }, {}],
5601         61: [function (require, module, exports) {
5602             'use strict';
5603 
5604             var required = require('requires-port')
5605                 , lolcation = require('./lolcation')
5606                 , qs = require('querystringify')
5607                 , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i;
5608 
5609             /**
5610              * These are the parse rules for the URL parser, it informs the parser
5611              * about:
5612              *
5613              * 0. The char it Needs to parse, if it's a string it should be done using
5614              *    indexOf, RegExp using exec and NaN means set as current value.
5615              * 1. The property we should set when parsing this value.
5616              * 2. Indication if it's backwards or forward parsing, when set as number it's
5617              *    the value of extra chars that should be split off.
5618              * 3. Inherit from location if non existing in the parser.
5619              * 4. `toLowerCase` the resulting value.
5620              */
5621             var rules = [
5622                 ['#', 'hash'],                        // Extract from the back.
5623                 ['?', 'query'],                       // Extract from the back.
5624                 ['/', 'pathname'],                    // Extract from the back.
5625                 ['@', 'auth', 1],                     // Extract from the front.
5626                 [NaN, 'host', undefined, 1, 1],       // Set left over value.
5627                 [/:(\d+)$/, 'port', undefined, 1],    // RegExp the back.
5628                 [NaN, 'hostname', undefined, 1, 1]    // Set left over.
5629             ];
5630 
5631             /**
5632              * @typedef ProtocolExtract
5633              * @type Object
5634              * @property {String} protocol Protocol matched in the URL, in lowercase.
5635              * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
5636              * @property {String} rest Rest of the URL that is not part of the protocol.
5637              */
5638 
5639             /**
5640              * Extract protocol information from a URL with/without double slash ("//").
5641              *
5642              * @param {String} address URL we want to extract from.
5643              * @return {ProtocolExtract} Extracted information.
5644              * @api private
5645              */
5646             function extractProtocol(address) {
5647                 var match = protocolre.exec(address);
5648 
5649                 return {
5650                     protocol: match[1] ? match[1].toLowerCase() : '',
5651                     slashes: !!match[2],
5652                     rest: match[3]
5653                 };
5654             }
5655 
5656             /**
5657              * Resolve a relative URL pathname against a base URL pathname.
5658              *
5659              * @param {String} relative Pathname of the relative URL.
5660              * @param {String} base Pathname of the base URL.
5661              * @return {String} Resolved pathname.
5662              * @api private
5663              */
5664             function resolve(relative, base) {
5665                 var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
5666                     , i = path.length
5667                     , last = path[i - 1]
5668                     , unshift = false
5669                     , up = 0;
5670 
5671                 while (i--) {
5672                     if (path[i] === '.') {
5673                         path.splice(i, 1);
5674                     } else if (path[i] === '..') {
5675                         path.splice(i, 1);
5676                         up++;
5677                     } else if (up) {
5678                         if (i === 0) unshift = true;
5679                         path.splice(i, 1);
5680                         up--;
5681                     }
5682                 }
5683 
5684                 if (unshift) path.unshift('');
5685                 if (last === '.' || last === '..') path.push('');
5686 
5687                 return path.join('/');
5688             }
5689 
5690             /**
5691              * The actual URL instance. Instead of returning an object we've opted-in to
5692              * create an actual constructor as it's much more memory efficient and
5693              * faster and it pleases my OCD.
5694              *
5695              * @constructor
5696              * @param {String} address URL we want to parse.
5697              * @param {Object|String} location Location defaults for relative paths.
5698              * @param {Boolean|Function} parser Parser for the query string.
5699              * @api public
5700              */
5701             function URL(address, location, parser) {
5702                 if (!(this instanceof URL)) {
5703                     return new URL(address, location, parser);
5704                 }
5705 
5706                 var relative, extracted, parse, instruction, index, key
5707                     , instructions = rules.slice()
5708                     , type = typeof location
5709                     , url = this
5710                     , i = 0;
5711 
5712                 //
5713                 // The following if statements allows this module two have compatibility with
5714                 // 2 different API:
5715                 //
5716                 // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
5717                 //    where the boolean indicates that the query string should also be parsed.
5718                 //
5719                 // 2. The `URL` interface of the browser which accepts a URL, object as
5720                 //    arguments. The supplied object will be used as default values / fall-back
5721                 //    for relative paths.
5722                 //
5723                 if ('object' !== type && 'string' !== type) {
5724                     parser = location;
5725                     location = null;
5726                 }
5727 
5728                 if (parser && 'function' !== typeof parser) parser = qs.parse;
5729 
5730                 location = lolcation(location);
5731 
5732                 //
5733                 // Extract protocol information before running the instructions.
5734                 //
5735                 extracted = extractProtocol(address || '');
5736                 relative = !extracted.protocol && !extracted.slashes;
5737                 url.slashes = extracted.slashes || relative && location.slashes;
5738                 url.protocol = extracted.protocol || location.protocol || '';
5739                 address = extracted.rest;
5740 
5741                 //
5742                 // When the authority component is absent the URL starts with a path
5743                 // component.
5744                 //
5745                 if (!extracted.slashes) instructions[2] = [/(.*)/, 'pathname'];
5746 
5747                 for (; i < instructions.length; i++) {
5748                     instruction = instructions[i];
5749                     parse = instruction[0];
5750                     key = instruction[1];
5751 
5752                     if (parse !== parse) {
5753                         url[key] = address;
5754                     } else if ('string' === typeof parse) {
5755                         if (~(index = address.indexOf(parse))) {
5756                             if ('number' === typeof instruction[2]) {
5757                                 url[key] = address.slice(0, index);
5758                                 address = address.slice(index + instruction[2]);
5759                             } else {
5760                                 url[key] = address.slice(index);
5761                                 address = address.slice(0, index);
5762                             }
5763                         }
5764                     } else if ((index = parse.exec(address))) {
5765                         url[key] = index[1];
5766                         address = address.slice(0, index.index);
5767                     }
5768 
5769                     url[key] = url[key] || (
5770                         relative && instruction[3] ? location[key] || '' : ''
5771                     );
5772 
5773                     //
5774                     // Hostname, host and protocol should be lowercased so they can be used to
5775                     // create a proper `origin`.
5776                     //
5777                     if (instruction[4]) url[key] = url[key].toLowerCase();
5778                 }
5779 
5780                 //
5781                 // Also parse the supplied query string in to an object. If we're supplied
5782                 // with a custom parser as function use that instead of the default build-in
5783                 // parser.
5784                 //
5785                 if (parser) url.query = parser(url.query);
5786 
5787                 //
5788                 // If the URL is relative, resolve the pathname against the base URL.
5789                 //
5790                 if (
5791                     relative
5792                     && location.slashes
5793                     && url.pathname.charAt(0) !== '/'
5794                     && (url.pathname !== '' || location.pathname !== '')
5795                 ) {
5796                     url.pathname = resolve(url.pathname, location.pathname);
5797                 }
5798 
5799                 //
5800                 // We should not add port numbers if they are already the default port number
5801                 // for a given protocol. As the host also contains the port number we're going
5802                 // override it with the hostname which contains no port number.
5803                 //
5804                 if (!required(url.port, url.protocol)) {
5805                     url.host = url.hostname;
5806                     url.port = '';
5807                 }
5808 
5809                 //
5810                 // Parse down the `auth` for the username and password.
5811                 //
5812                 url.username = url.password = '';
5813                 if (url.auth) {
5814                     instruction = url.auth.split(':');
5815                     url.username = instruction[0] || '';
5816                     url.password = instruction[1] || '';
5817                 }
5818 
5819                 url.origin = url.protocol && url.host && url.protocol !== 'file:'
5820                     ? url.protocol + '//' + url.host
5821                     : 'null';
5822 
5823                 //
5824                 // The href is just the compiled result.
5825                 //
5826                 url.href = url.toString();
5827             }
5828 
5829             /**
5830              * This is convenience method for changing properties in the URL instance to
5831              * insure that they all propagate correctly.
5832              *
5833              * @param {String} part          Property we need to adjust.
5834              * @param {Mixed} value          The newly assigned value.
5835              * @param {Boolean|Function} fn  When setting the query, it will be the function
5836              *                               used to parse the query.
5837              *                               When setting the protocol, double slash will be
5838              *                               removed from the final url if it is true.
5839              * @returns {URL}
5840              * @api public
5841              */
5842             function set (part, value, fn) {
5843                 var url = this;
5844 
5845                 switch (part) {
5846                     case 'query':
5847                         if ('string' === typeof value && value.length) {
5848                             value = (fn || qs.parse)(value);
5849                         }
5850 
5851                         url[part] = value;
5852                         break;
5853 
5854                     case 'port':
5855                         url[part] = value;
5856 
5857                         if (!required(value, url.protocol)) {
5858                             url.host = url.hostname;
5859                             url[part] = '';
5860                         } else if (value) {
5861                             url.host = url.hostname + ':' + value;
5862                         }
5863 
5864                         break;
5865 
5866                     case 'hostname':
5867                         url[part] = value;
5868 
5869                         if (url.port) value += ':' + url.port;
5870                         url.host = value;
5871                         break;
5872 
5873                     case 'host':
5874                         url[part] = value;
5875 
5876                         if (/:\d+$/.test(value)) {
5877                             value = value.split(':');
5878                             url.port = value.pop();
5879                             url.hostname = value.join(':');
5880                         } else {
5881                             url.hostname = value;
5882                             url.port = '';
5883                         }
5884 
5885                         break;
5886 
5887                     case 'protocol':
5888                         url.protocol = value.toLowerCase();
5889                         url.slashes = !fn;
5890                         break;
5891 
5892                     case 'pathname':
5893                         url.pathname = value.length && value.charAt(0) !== '/' ? '/' + value : value;
5894 
5895                         break;
5896 
5897                     default:
5898                         url[part] = value;
5899                 }
5900 
5901                 for (var i = 0; i < rules.length; i++) {
5902                     var ins = rules[i];
5903 
5904                     if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
5905                 }
5906 
5907                 url.origin = url.protocol && url.host && url.protocol !== 'file:'
5908                     ? url.protocol + '//' + url.host
5909                     : 'null';
5910 
5911                 url.href = url.toString();
5912 
5913                 return url;
5914             };
5915 
5916             /**
5917              * Transform the properties back in to a valid and full URL string.
5918              *
5919              * @param {Function} stringify Optional query stringify function.
5920              * @returns {String}
5921              * @api public
5922              */
5923             function toString(stringify) {
5924                 if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
5925 
5926                 var query
5927                     , url = this
5928                     , protocol = url.protocol;
5929 
5930                 if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
5931 
5932                 var result = protocol + (url.slashes ? '//' : '');
5933 
5934                 if (url.username) {
5935                     result += url.username;
5936                     if (url.password) result += ':' + url.password;
5937                     result += '@';
5938                 }
5939 
5940                 result += url.host + url.pathname;
5941 
5942                 query = 'object' === typeof url.query ? stringify(url.query) : url.query;
5943                 if (query) result += '?' !== query.charAt(0) ? '?' + query : query;
5944 
5945                 if (url.hash) result += url.hash;
5946 
5947                 return result;
5948             }
5949 
5950             URL.prototype = {set: set, toString: toString};
5951 
5952 //
5953 // Expose the URL parser and some additional properties that might be useful for
5954 // others or testing.
5955 //
5956             URL.extractProtocol = extractProtocol;
5957             URL.location = lolcation;
5958             URL.qs = qs;
5959 
5960             module.exports = URL;
5961 
5962         }, {"./lolcation": 62, "querystringify": 59, "requires-port": 60}],
5963         62: [function (require, module, exports) {
5964             (function (global) {
5965                 'use strict';
5966 
5967                 var slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//;
5968 
5969                 /**
5970                  * These properties should not be copied or inherited from. This is only needed
5971                  * for all non blob URL's as a blob URL does not include a hash, only the
5972                  * origin.
5973                  *
5974                  * @type {Object}
5975                  * @private
5976                  */
5977                 var ignore = {hash: 1, query: 1}
5978                     , URL;
5979 
5980                 /**
5981                  * The location object differs when your code is loaded through a normal page,
5982                  * Worker or through a worker using a blob. And with the blobble begins the
5983                  * trouble as the location object will contain the URL of the blob, not the
5984                  * location of the page where our code is loaded in. The actual origin is
5985                  * encoded in the `pathname` so we can thankfully generate a good "default"
5986                  * location from it so we can generate proper relative URL's again.
5987                  *
5988                  * @param {Object|String} loc Optional default location object.
5989                  * @returns {Object} lolcation object.
5990                  * @api public
5991                  */
5992                 module.exports = function lolcation(loc) {
5993                     loc = loc || global.location || {};
5994                     URL = URL || require('./');
5995 
5996                     var finaldestination = {}
5997                         , type = typeof loc
5998                         , key;
5999 
6000                     if ('blob:' === loc.protocol) {
6001                         finaldestination = new URL(unescape(loc.pathname), {});
6002                     } else if ('string' === type) {
6003                         finaldestination = new URL(loc, {});
6004                         for (key in ignore) delete finaldestination[key];
6005                     } else if ('object' === type) {
6006                         for (key in loc) {
6007                             if (key in ignore) continue;
6008                             finaldestination[key] = loc[key];
6009                         }
6010 
6011                         if (finaldestination.slashes === undefined) {
6012                             finaldestination.slashes = slashes.test(loc.href);
6013                         }
6014                     }
6015 
6016                     return finaldestination;
6017                 };
6018 
6019             }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
6020 
6021         }, {"./": 61}]
6022     }, {}, [1])(1)
6023 });
6024 
6025 
6026 //# sourceMappingURL=sockjs.js.map
View Code

stomp.js

  1 // Generated by CoffeeScript 1.7.1
  2 
  3 /*
  4    Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0
  5 
  6    Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/)
  7    Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com)
  8  */
  9 
 10 (function() {
 11   var Byte, Client, Frame, Stomp,
 12     __hasProp = {}.hasOwnProperty,
 13     __slice = [].slice;
 14 
 15   Byte = {
 16     LF: '\x0A',
 17     NULL: '\x00'
 18   };
 19 
 20   Frame = (function() {
 21     var unmarshallSingle;
 22 
 23     function Frame(command, headers, body) {
 24       this.command = command;
 25       this.headers = headers != null ? headers : {};
 26       this.body = body != null ? body : '';
 27     }
 28 
 29     Frame.prototype.toString = function() {
 30       var lines, name, skipContentLength, value, _ref;
 31       lines = [this.command];
 32       skipContentLength = this.headers['content-length'] === false ? true : false;
 33       if (skipContentLength) {
 34         delete this.headers['content-length'];
 35       }
 36       _ref = this.headers;
 37       for (name in _ref) {
 38         if (!__hasProp.call(_ref, name)) continue;
 39         value = _ref[name];
 40         lines.push("" + name + ":" + value);
 41       }
 42       if (this.body && !skipContentLength) {
 43         lines.push("content-length:" + (Frame.sizeOfUTF8(this.body)));
 44       }
 45       lines.push(Byte.LF + this.body);
 46       return lines.join(Byte.LF);
 47     };
 48 
 49     Frame.sizeOfUTF8 = function(s) {
 50       if (s) {
 51         return encodeURI(s).match(/%..|./g).length;
 52       } else {
 53         return 0;
 54       }
 55     };
 56 
 57     unmarshallSingle = function(data) {
 58       var body, chr, command, divider, headerLines, headers, i, idx, len, line, start, trim, _i, _j, _len, _ref, _ref1;
 59       divider = data.search(RegExp("" + Byte.LF + Byte.LF));
 60       headerLines = data.substring(0, divider).split(Byte.LF);
 61       command = headerLines.shift();
 62       headers = {};
 63       trim = function(str) {
 64         return str.replace(/^\s+|\s+$/g, '');
 65       };
 66       _ref = headerLines.reverse();
 67       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 68         line = _ref[_i];
 69         idx = line.indexOf(':');
 70         headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1));
 71       }
 72       body = '';
 73       start = divider + 2;
 74       if (headers['content-length']) {
 75         len = parseInt(headers['content-length']);
 76         body = ('' + data).substring(start, start + len);
 77       } else {
 78         chr = null;
 79         for (i = _j = start, _ref1 = data.length; start <= _ref1 ? _j < _ref1 : _j > _ref1; i = start <= _ref1 ? ++_j : --_j) {
 80           chr = data.charAt(i);
 81           if (chr === Byte.NULL) {
 82             break;
 83           }
 84           body += chr;
 85         }
 86       }
 87       return new Frame(command, headers, body);
 88     };
 89 
 90     Frame.unmarshall = function(datas) {
 91       var frame, frames, last_frame, r;
 92       frames = datas.split(RegExp("" + Byte.NULL + Byte.LF + "*"));
 93       r = {
 94         frames: [],
 95         partial: ''
 96       };
 97       r.frames = (function() {
 98         var _i, _len, _ref, _results;
 99         _ref = frames.slice(0, -1);
100         _results = [];
101         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
102           frame = _ref[_i];
103           _results.push(unmarshallSingle(frame));
104         }
105         return _results;
106       })();
107       last_frame = frames.slice(-1)[0];
108       if (last_frame === Byte.LF || (last_frame.search(RegExp("" + Byte.NULL + Byte.LF + "*$"))) !== -1) {
109         r.frames.push(unmarshallSingle(last_frame));
110       } else {
111         r.partial = last_frame;
112       }
113       return r;
114     };
115 
116     Frame.marshall = function(command, headers, body) {
117       var frame;
118       frame = new Frame(command, headers, body);
119       return frame.toString() + Byte.NULL;
120     };
121 
122     return Frame;
123 
124   })();
125 
126   Client = (function() {
127     var now;
128 
129     function Client(ws) {
130       this.ws = ws;
131       this.ws.binaryType = "arraybuffer";
132       this.counter = 0;
133       this.connected = false;
134       this.heartbeat = {
135         outgoing: 10000,
136         incoming: 10000
137       };
138       this.maxWebSocketFrameSize = 16 * 1024;
139       this.subscriptions = {};
140       this.partialData = '';
141     }
142 
143     Client.prototype.debug = function(message) {
144       var _ref;
145       return typeof window !== "undefined" && window !== null ? (_ref = window.console) != null ? _ref.log(message) : void 0 : void 0;
146     };
147 
148     now = function() {
149       if (Date.now) {
150         return Date.now();
151       } else {
152         return new Date().valueOf;
153       }
154     };
155 
156     Client.prototype._transmit = function(command, headers, body) {
157       var out;
158       out = Frame.marshall(command, headers, body);
159       if (typeof this.debug === "function") {
160         this.debug(">>> " + out);
161       }
162       while (true) {
163         if (out.length > this.maxWebSocketFrameSize) {
164           this.ws.send(out.substring(0, this.maxWebSocketFrameSize));
165           out = out.substring(this.maxWebSocketFrameSize);
166           if (typeof this.debug === "function") {
167             this.debug("remaining = " + out.length);
168           }
169         } else {
170           return this.ws.send(out);
171         }
172       }
173     };
174 
175     Client.prototype._setupHeartbeat = function(headers) {
176       var serverIncoming, serverOutgoing, ttl, v, _ref, _ref1;
177       if ((_ref = headers.version) !== Stomp.VERSIONS.V1_1 && _ref !== Stomp.VERSIONS.V1_2) {
178         return;
179       }
180       _ref1 = (function() {
181         var _i, _len, _ref1, _results;
182         _ref1 = headers['heart-beat'].split(",");
183         _results = [];
184         for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
185           v = _ref1[_i];
186           _results.push(parseInt(v));
187         }
188         return _results;
189       })(), serverOutgoing = _ref1[0], serverIncoming = _ref1[1];
190       if (!(this.heartbeat.outgoing === 0 || serverIncoming === 0)) {
191         ttl = Math.max(this.heartbeat.outgoing, serverIncoming);
192         if (typeof this.debug === "function") {
193           this.debug("send PING every " + ttl + "ms");
194         }
195         this.pinger = Stomp.setInterval(ttl, (function(_this) {
196           return function() {
197             _this.ws.send(Byte.LF);
198             return typeof _this.debug === "function" ? _this.debug(">>> PING") : void 0;
199           };
200         })(this));
201       }
202       if (!(this.heartbeat.incoming === 0 || serverOutgoing === 0)) {
203         ttl = Math.max(this.heartbeat.incoming, serverOutgoing);
204         if (typeof this.debug === "function") {
205           this.debug("check PONG every " + ttl + "ms");
206         }
207         return this.ponger = Stomp.setInterval(ttl, (function(_this) {
208           return function() {
209             var delta;
210             delta = now() - _this.serverActivity;
211             if (delta > ttl * 2) {
212               if (typeof _this.debug === "function") {
213                 _this.debug("did not receive server activity for the last " + delta + "ms");
214               }
215               return _this.ws.close();
216             }
217           };
218         })(this));
219       }
220     };
221 
222     Client.prototype._parseConnect = function() {
223       var args, connectCallback, errorCallback, headers;
224       args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
225       headers = {};
226       switch (args.length) {
227         case 2:
228           headers = args[0], connectCallback = args[1];
229           break;
230         case 3:
231           if (args[1] instanceof Function) {
232             headers = args[0], connectCallback = args[1], errorCallback = args[2];
233           } else {
234             headers.login = args[0], headers.passcode = args[1], connectCallback = args[2];
235           }
236           break;
237         case 4:
238           headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3];
239           break;
240         default:
241           headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3], headers.host = args[4];
242       }
243       return [headers, connectCallback, errorCallback];
244     };
245 
246     Client.prototype.connect = function() {
247       var args, errorCallback, headers, out;
248       args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
249       out = this._parseConnect.apply(this, args);
250       headers = out[0], this.connectCallback = out[1], errorCallback = out[2];
251       if (typeof this.debug === "function") {
252         this.debug("Opening Web Socket...");
253       }
254       this.ws.onmessage = (function(_this) {
255         return function(evt) {
256           var arr, c, client, data, frame, messageID, onreceive, subscription, unmarshalledData, _i, _len, _ref, _results;
257           data = typeof ArrayBuffer !== 'undefined' && evt.data instanceof ArrayBuffer ? (arr = new Uint8Array(evt.data), typeof _this.debug === "function" ? _this.debug("--- got data length: " + arr.length) : void 0, ((function() {
258             var _i, _len, _results;
259             _results = [];
260             for (_i = 0, _len = arr.length; _i < _len; _i++) {
261               c = arr[_i];
262               _results.push(String.fromCharCode(c));
263             }
264             return _results;
265           })()).join('')) : evt.data;
266           _this.serverActivity = now();
267           if (data === Byte.LF) {
268             if (typeof _this.debug === "function") {
269               _this.debug("<<< PONG");
270             }
271             return;
272           }
273           if (typeof _this.debug === "function") {
274             _this.debug("<<< " + data);
275           }
276           unmarshalledData = Frame.unmarshall(_this.partialData + data);
277           _this.partialData = unmarshalledData.partial;
278           _ref = unmarshalledData.frames;
279           _results = [];
280           for (_i = 0, _len = _ref.length; _i < _len; _i++) {
281             frame = _ref[_i];
282             switch (frame.command) {
283               case "CONNECTED":
284                 if (typeof _this.debug === "function") {
285                   _this.debug("connected to server " + frame.headers.server);
286                 }
287                 _this.connected = true;
288                 _this._setupHeartbeat(frame.headers);
289                 _results.push(typeof _this.connectCallback === "function" ? _this.connectCallback(frame) : void 0);
290                 break;
291               case "MESSAGE":
292                 subscription = frame.headers.subscription;
293                 onreceive = _this.subscriptions[subscription] || _this.onreceive;
294                 if (onreceive) {
295                   client = _this;
296                   messageID = frame.headers["message-id"];
297                   frame.ack = function(headers) {
298                     if (headers == null) {
299                       headers = {};
300                     }
301                     return client.ack(messageID, subscription, headers);
302                   };
303                   frame.nack = function(headers) {
304                     if (headers == null) {
305                       headers = {};
306                     }
307                     return client.nack(messageID, subscription, headers);
308                   };
309                   _results.push(onreceive(frame));
310                 } else {
311                   _results.push(typeof _this.debug === "function" ? _this.debug("Unhandled received MESSAGE: " + frame) : void 0);
312                 }
313                 break;
314               case "RECEIPT":
315                 _results.push(typeof _this.onreceipt === "function" ? _this.onreceipt(frame) : void 0);
316                 break;
317               case "ERROR":
318                 _results.push(typeof errorCallback === "function" ? errorCallback(frame) : void 0);
319                 break;
320               default:
321                 _results.push(typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0);
322             }
323           }
324           return _results;
325         };
326       })(this);
327       this.ws.onclose = (function(_this) {
328         return function() {
329           var msg;
330           msg = "Whoops! Lost connection to " + _this.ws.url;
331           if (typeof _this.debug === "function") {
332             _this.debug(msg);
333           }
334           _this._cleanUp();
335           return typeof errorCallback === "function" ? errorCallback(msg) : void 0;
336         };
337       })(this);
338       return this.ws.onopen = (function(_this) {
339         return function() {
340           if (typeof _this.debug === "function") {
341             _this.debug('Web Socket Opened...');
342           }
343           headers["accept-version"] = Stomp.VERSIONS.supportedVersions();
344           headers["heart-beat"] = [_this.heartbeat.outgoing, _this.heartbeat.incoming].join(',');
345           return _this._transmit("CONNECT", headers);
346         };
347       })(this);
348     };
349 
350     Client.prototype.disconnect = function(disconnectCallback, headers) {
351       if (headers == null) {
352         headers = {};
353       }
354       this._transmit("DISCONNECT", headers);
355       this.ws.onclose = null;
356       this.ws.close();
357       this._cleanUp();
358       return typeof disconnectCallback === "function" ? disconnectCallback() : void 0;
359     };
360 
361     Client.prototype._cleanUp = function() {
362       this.connected = false;
363       if (this.pinger) {
364         Stomp.clearInterval(this.pinger);
365       }
366       if (this.ponger) {
367         return Stomp.clearInterval(this.ponger);
368       }
369     };
370 
371     Client.prototype.send = function(destination, headers, body) {
372       if (headers == null) {
373         headers = {};
374       }
375       if (body == null) {
376         body = '';
377       }
378       headers.destination = destination;
379       return this._transmit("SEND", headers, body);
380     };
381 
382     Client.prototype.subscribe = function(destination, callback, headers) {
383       var client;
384       if (headers == null) {
385         headers = {};
386       }
387       if (!headers.id) {
388         headers.id = "sub-" + this.counter++;
389       }
390       headers.destination = destination;
391       this.subscriptions[headers.id] = callback;
392       this._transmit("SUBSCRIBE", headers);
393       client = this;
394       return {
395         id: headers.id,
396         unsubscribe: function() {
397           return client.unsubscribe(headers.id);
398         }
399       };
400     };
401 
402     Client.prototype.unsubscribe = function(id) {
403       delete this.subscriptions[id];
404       return this._transmit("UNSUBSCRIBE", {
405         id: id
406       });
407     };
408 
409     Client.prototype.begin = function(transaction) {
410       var client, txid;
411       txid = transaction || "tx-" + this.counter++;
412       this._transmit("BEGIN", {
413         transaction: txid
414       });
415       client = this;
416       return {
417         id: txid,
418         commit: function() {
419           return client.commit(txid);
420         },
421         abort: function() {
422           return client.abort(txid);
423         }
424       };
425     };
426 
427     Client.prototype.commit = function(transaction) {
428       return this._transmit("COMMIT", {
429         transaction: transaction
430       });
431     };
432 
433     Client.prototype.abort = function(transaction) {
434       return this._transmit("ABORT", {
435         transaction: transaction
436       });
437     };
438 
439     Client.prototype.ack = function(messageID, subscription, headers) {
440       if (headers == null) {
441         headers = {};
442       }
443       headers["message-id"] = messageID;
444       headers.subscription = subscription;
445       return this._transmit("ACK", headers);
446     };
447 
448     Client.prototype.nack = function(messageID, subscription, headers) {
449       if (headers == null) {
450         headers = {};
451       }
452       headers["message-id"] = messageID;
453       headers.subscription = subscription;
454       return this._transmit("NACK", headers);
455     };
456 
457     return Client;
458 
459   })();
460 
461   Stomp = {
462     VERSIONS: {
463       V1_0: '1.0',
464       V1_1: '1.1',
465       V1_2: '1.2',
466       supportedVersions: function() {
467         return '1.1,1.0';
468       }
469     },
470     client: function(url, protocols) {
471       var klass, ws;
472       if (protocols == null) {
473         protocols = ['v10.stomp', 'v11.stomp'];
474       }
475       klass = Stomp.WebSocketClass || WebSocket;
476       ws = new klass(url, protocols);
477       return new Client(ws);
478     },
479     over: function(ws) {
480       return new Client(ws);
481     },
482     Frame: Frame
483   };
484 
485   if (typeof exports !== "undefined" && exports !== null) {
486     exports.Stomp = Stomp;
487   }
488 
489   if (typeof window !== "undefined" && window !== null) {
490     Stomp.setInterval = function(interval, f) {
491       return window.setInterval(f, interval);
492     };
493     Stomp.clearInterval = function(id) {
494       return window.clearInterval(id);
495     };
496     window.Stomp = Stomp;
497   } else if (!exports) {
498     self.Stomp = Stomp;
499   }
500 
501 }).call(this);
View Code

uniapp平台使用:

微信小程序平台使用:

WXML代码:

 1 import WebSocket from '../../../utils/stomp/websocket'
 2 import { URL, WS } from '../../../utils/index';
 3 const wsURL = 'wss://'+WS+'/ws' // websocket连接地址
 4 
 5 Page({
 6 
 7   /**
 8    * 页面的初始数据
 9    */
10   data: {
11     client: null,
12     subscription:'',
13   },
14 
15   /**
16    * 生命周期函数--监听页面加载
17    */
18   async onLoad(options) {
19   },
20   async onShow(){
21     // 切换任务后台,ws断开后重连
22     if(!WebSocket.client){
23         this.initWS()
24     }
25   },
26   // 到账语音*** 获取语音,连接地址
27   async getConnectUrl(paycode) {
28     // stomp协议请求 
29       this.initWS()
30   },
31   /**
32    * stomp协议请求
33    */
34   async initWS() {
35     WebSocket.init(wsURL,
36       // 传参
37       {
38         login: 'xxx', // 你的登录名
39         passcode: 'xxxx', // 你的密码
40       },
41       // ws断开回调
42       () => {
43         this.initWS()
44       }
45     ).then((client) => {
46       this.setData({
47         client: client
48       })
49       
50       // 订阅
51       const subscription = client.subscribe(
52         // 路径
53         '/topic/'+this.data.paycode,
54         // 接收到的数据
55         (res) => {
56           let info = JSON.parse(res.body)
57           console.log("订阅成功了吗,接收到的数据",res.body,info.msg)
58         },
59         // 消息不会被确认接收,不确认每次连接都会推送
60         // { ack: 'client' } 
61       )
62       console.log("",client.subscribe)
63       this.setData({
64             subscription: subscription
65       })
66     })
67   },
68   /**
69    * 生命周期函数--监听页面卸载
70    */
71   onUnload() {
72     // 不关闭websocket连接,但是断开订阅
73     this.data.subscription && this.data.subscription.unsubscribe(this.data.subscription.id)
74     // 直接关闭websocket
75     // this.data.client && this.data.client.close()
76   },
77 })
View Code

 

utils/websocket.js:

 1 const Stomp = require('./stomp.js').Stomp;
 2 
 3 let socketOpen = false
 4 let socketMsgQueue = []
 5 
 6 export default {
 7   client: null,
 8   init(url, header ,connectWS) {
 9     if (this.client) {
10       return Promise.resolve(this.client)
11     }
12 
13     return new Promise((resolve, reject) => {
14       const ws = {
15         send: this.sendMessage,
16         onopen: null,
17         onmessage: this.getMessage,
18       }
19       wx.connectSocket({ url, header })
20       wx.onSocketOpen(function (res) {
21         console.log('WebSocket连接已打开!', res)
22         socketOpen = true
23         for (let i = 0; i < socketMsgQueue.length; i++) {
24           ws.send(socketMsgQueue[i])
25         }
26         socketMsgQueue = []
27         ws.onopen && ws.onopen()
28       })
29 
30       wx.onSocketMessage(function (res) {
31           // ios 缺少 0x00 导致解析失败
32         if (res && res.data) {
33           let value = res.data;
34           let code = value.charCodeAt(value.length - 1);
35           if (code !== 0x00) {
36             value += String.fromCharCode(0x00);
37             res.data = value;
38           }
39         }
40         ws.onmessage && ws.onmessage(res)
41       })
42 
43       wx.onSocketError(function (res) {
44         console.log('WebSocket 错误!', res)
45       })
46 
47       wx.onSocketClose((res) => {
48         this.client = null
49         socketOpen = false
50         console.log('WebSocket 已关闭!', res)
51         if(res.code !== 1000){
52           setTimeout(()=>{
53             connectWS()
54           },3000)
55         }
56       })
57       Stomp.setInterval = function (interval, f) {
58         return setInterval(f, interval)
59       }
60       Stomp.clearInterval = function (id) {
61         return clearInterval(id)
62       }
63       const client = (this.client = Stomp.over(ws))
64       // 关闭连接
65       client.close = () =>{
66         wx.closeSocket()
67       }
68       client.connect(header, function () {
69         console.log('stomp connected')
70         resolve(client)
71       })
72     })
73   },
74   sendMessage(message) {
75     if (socketOpen) {
76       wx.sendSocketMessage({
77         data: message,
78       })
79     } else {
80       socketMsgQueue.push(message)
81     }
82   },
83   getMessage(message){
84     console.log("从Rabbit获取到的消息", message)
85   },
86 }
View Code

 

utils/stomp.js:

  1 // Generated by CoffeeScript 1.7.1
  2 
  3 /*
  4    Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0
  5 
  6    Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/)
  7    Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com)
  8  */
  9 
 10 (function() {
 11   var Byte, Client, Frame, Stomp,
 12     __hasProp = {}.hasOwnProperty,
 13     __slice = [].slice;
 14 
 15   Byte = {
 16     LF: '\x0A',
 17     NULL: '\x00'
 18   };
 19 
 20   Frame = (function() {
 21     var unmarshallSingle;
 22 
 23     function Frame(command, headers, body) {
 24       this.command = command;
 25       this.headers = headers != null ? headers : {};
 26       this.body = body != null ? body : '';
 27     }
 28 
 29     Frame.prototype.toString = function() {
 30       var lines, name, skipContentLength, value, _ref;
 31       lines = [this.command];
 32       skipContentLength = this.headers['content-length'] === false ? true : false;
 33       if (skipContentLength) {
 34         delete this.headers['content-length'];
 35       }
 36       _ref = this.headers;
 37       for (name in _ref) {
 38         if (!__hasProp.call(_ref, name)) continue;
 39         value = _ref[name];
 40         lines.push("" + name + ":" + value);
 41       }
 42       if (this.body && !skipContentLength) {
 43         lines.push("content-length:" + (Frame.sizeOfUTF8(this.body)));
 44       }
 45       lines.push(Byte.LF + this.body);
 46       return lines.join(Byte.LF);
 47     };
 48 
 49     Frame.sizeOfUTF8 = function(s) {
 50       if (s) {
 51         return encodeURI(s).match(/%..|./g).length;
 52       } else {
 53         return 0;
 54       }
 55     };
 56 
 57     unmarshallSingle = function(data) {
 58       var body, chr, command, divider, headerLines, headers, i, idx, len, line, start, trim, _i, _j, _len, _ref, _ref1;
 59       divider = data.search(RegExp("" + Byte.LF + Byte.LF));
 60       headerLines = data.substring(0, divider).split(Byte.LF);
 61       command = headerLines.shift();
 62       headers = {};
 63       trim = function(str) {
 64         return str.replace(/^\s+|\s+$/g, '');
 65       };
 66       _ref = headerLines.reverse();
 67       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 68         line = _ref[_i];
 69         idx = line.indexOf(':');
 70         headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1));
 71       }
 72       body = '';
 73       start = divider + 2;
 74       if (headers['content-length']) {
 75         len = parseInt(headers['content-length']);
 76         body = ('' + data).substring(start, start + len);
 77       } else {
 78         chr = null;
 79         for (i = _j = start, _ref1 = data.length; start <= _ref1 ? _j < _ref1 : _j > _ref1; i = start <= _ref1 ? ++_j : --_j) {
 80           chr = data.charAt(i);
 81           if (chr === Byte.NULL) {
 82             break;
 83           }
 84           body += chr;
 85         }
 86       }
 87       return new Frame(command, headers, body);
 88     };
 89 
 90     Frame.unmarshall = function(datas) {
 91       var frame, frames, last_frame, r;
 92       frames = datas.split(RegExp("" + Byte.NULL + Byte.LF + "*"));
 93       r = {
 94         frames: [],
 95         partial: ''
 96       };
 97       r.frames = (function() {
 98         var _i, _len, _ref, _results;
 99         _ref = frames.slice(0, -1);
100         _results = [];
101         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
102           frame = _ref[_i];
103           _results.push(unmarshallSingle(frame));
104         }
105         return _results;
106       })();
107       last_frame = frames.slice(-1)[0];
108       if (last_frame === Byte.LF || (last_frame.search(RegExp("" + Byte.NULL + Byte.LF + "*$"))) !== -1) {
109         r.frames.push(unmarshallSingle(last_frame));
110       } else {
111         r.partial = last_frame;
112       }
113       return r;
114     };
115 
116     Frame.marshall = function(command, headers, body) {
117       var frame;
118       frame = new Frame(command, headers, body);
119       return frame.toString() + Byte.NULL;
120     };
121 
122     return Frame;
123 
124   })();
125 
126   Client = (function() {
127     var now;
128 
129     function Client(ws) {
130       this.ws = ws;
131       this.ws.binaryType = "arraybuffer";
132       this.counter = 0;
133       this.connected = false;
134       this.heartbeat = {
135         outgoing: 10000,
136         incoming: 10000
137       };
138       this.maxWebSocketFrameSize = 16 * 1024;
139       this.subscriptions = {};
140       this.partialData = '';
141     }
142 
143     Client.prototype.debug = function(message) {
144       var _ref;
145       return typeof window !== "undefined" && window !== null ? (_ref = window.console) != null ? _ref.log(message) : void 0 : void 0;
146     };
147 
148     now = function() {
149       if (Date.now) {
150         return Date.now();
151       } else {
152         return new Date().valueOf;
153       }
154     };
155 
156     Client.prototype._transmit = function(command, headers, body) {
157       var out;
158       out = Frame.marshall(command, headers, body);
159       if (typeof this.debug === "function") {
160         this.debug(">>> " + out);
161       }
162       while (true) {
163         if (out.length > this.maxWebSocketFrameSize) {
164           this.ws.send(out.substring(0, this.maxWebSocketFrameSize));
165           out = out.substring(this.maxWebSocketFrameSize);
166           if (typeof this.debug === "function") {
167             this.debug("remaining = " + out.length);
168           }
169         } else {
170           return this.ws.send(out);
171         }
172       }
173     };
174 
175     Client.prototype._setupHeartbeat = function(headers) {
176       var serverIncoming, serverOutgoing, ttl, v, _ref, _ref1;
177       if ((_ref = headers.version) !== Stomp.VERSIONS.V1_1 && _ref !== Stomp.VERSIONS.V1_2) {
178         return;
179       }
180       _ref1 = (function() {
181         var _i, _len, _ref1, _results;
182         _ref1 = headers['heart-beat'].split(",");
183         _results = [];
184         for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
185           v = _ref1[_i];
186           _results.push(parseInt(v));
187         }
188         return _results;
189       })(), serverOutgoing = _ref1[0], serverIncoming = _ref1[1];
190       if (!(this.heartbeat.outgoing === 0 || serverIncoming === 0)) {
191         ttl = Math.max(this.heartbeat.outgoing, serverIncoming);
192         if (typeof this.debug === "function") {
193           this.debug("send PING every " + ttl + "ms");
194         }
195         this.pinger = Stomp.setInterval(ttl, (function(_this) {
196           return function() {
197             _this.ws.send(Byte.LF);
198             return typeof _this.debug === "function" ? _this.debug(">>> PING") : void 0;
199           };
200         })(this));
201       }
202       if (!(this.heartbeat.incoming === 0 || serverOutgoing === 0)) {
203         ttl = Math.max(this.heartbeat.incoming, serverOutgoing);
204         if (typeof this.debug === "function") {
205           this.debug("check PONG every " + ttl + "ms");
206         }
207         return this.ponger = Stomp.setInterval(ttl, (function(_this) {
208           return function() {
209             var delta;
210             delta = now() - _this.serverActivity;
211             if (delta > ttl * 2) {
212               if (typeof _this.debug === "function") {
213                 _this.debug("did not receive server activity for the last " + delta + "ms");
214               }
215               return _this.ws.close();
216             }
217           };
218         })(this));
219       }
220     };
221 
222     Client.prototype._parseConnect = function() {
223       var args, connectCallback, errorCallback, headers;
224       args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
225       headers = {};
226       switch (args.length) {
227         case 2:
228           headers = args[0], connectCallback = args[1];
229           break;
230         case 3:
231           if (args[1] instanceof Function) {
232             headers = args[0], connectCallback = args[1], errorCallback = args[2];
233           } else {
234             headers.login = args[0], headers.passcode = args[1], connectCallback = args[2];
235           }
236           break;
237         case 4:
238           headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3];
239           break;
240         default:
241           headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3], headers.host = args[4];
242       }
243       return [headers, connectCallback, errorCallback];
244     };
245 
246     Client.prototype.connect = function() {
247       var args, errorCallback, headers, out;
248       args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
249       out = this._parseConnect.apply(this, args);
250       headers = out[0], this.connectCallback = out[1], errorCallback = out[2];
251       if (typeof this.debug === "function") {
252         this.debug("Opening Web Socket...");
253       }
254       this.ws.onmessage = (function(_this) {
255         return function(evt) {
256           var arr, c, client, data, frame, messageID, onreceive, subscription, unmarshalledData, _i, _len, _ref, _results;
257           data = typeof ArrayBuffer !== 'undefined' && evt.data instanceof ArrayBuffer ? (arr = new Uint8Array(evt.data), typeof _this.debug === "function" ? _this.debug("--- got data length: " + arr.length) : void 0, ((function() {
258             var _i, _len, _results;
259             _results = [];
260             for (_i = 0, _len = arr.length; _i < _len; _i++) {
261               c = arr[_i];
262               _results.push(String.fromCharCode(c));
263             }
264             return _results;
265           })()).join('')) : evt.data;
266           _this.serverActivity = now();
267           if (data === Byte.LF) {
268             if (typeof _this.debug === "function") {
269               _this.debug("<<< PONG");
270             }
271             return;
272           }
273           if (typeof _this.debug === "function") {
274             _this.debug("<<< " + data);
275           }
276           unmarshalledData = Frame.unmarshall(_this.partialData + data);
277           _this.partialData = unmarshalledData.partial;
278           _ref = unmarshalledData.frames;
279           _results = [];
280           for (_i = 0, _len = _ref.length; _i < _len; _i++) {
281             frame = _ref[_i];
282             switch (frame.command) {
283               case "CONNECTED":
284                 if (typeof _this.debug === "function") {
285                   _this.debug("connected to server " + frame.headers.server);
286                 }
287                 _this.connected = true;
288                 _this._setupHeartbeat(frame.headers);
289                 _results.push(typeof _this.connectCallback === "function" ? _this.connectCallback(frame) : void 0);
290                 break;
291               case "MESSAGE":
292                 subscription = frame.headers.subscription;
293                 onreceive = _this.subscriptions[subscription] || _this.onreceive;
294                 if (onreceive) {
295                   client = _this;
296                   messageID = frame.headers["message-id"];
297                   frame.ack = function(headers) {
298                     if (headers == null) {
299                       headers = {};
300                     }
301                     return client.ack(messageID, subscription, headers);
302                   };
303                   frame.nack = function(headers) {
304                     if (headers == null) {
305                       headers = {};
306                     }
307                     return client.nack(messageID, subscription, headers);
308                   };
309                   _results.push(onreceive(frame));
310                 } else {
311                   _results.push(typeof _this.debug === "function" ? _this.debug("Unhandled received MESSAGE: " + frame) : void 0);
312                 }
313                 break;
314               case "RECEIPT":
315                 _results.push(typeof _this.onreceipt === "function" ? _this.onreceipt(frame) : void 0);
316                 break;
317               case "ERROR":
318                 _results.push(typeof errorCallback === "function" ? errorCallback(frame) : void 0);
319                 break;
320               default:
321                 _results.push(typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0);
322             }
323           }
324           return _results;
325         };
326       })(this);
327       this.ws.onclose = (function(_this) {
328         return function() {
329           var msg;
330           msg = "Whoops! Lost connection to " + _this.ws.url;
331           if (typeof _this.debug === "function") {
332             _this.debug(msg);
333           }
334           _this._cleanUp();
335           return typeof errorCallback === "function" ? errorCallback(msg) : void 0;
336         };
337       })(this);
338       return this.ws.onopen = (function(_this) {
339         return function() {
340           if (typeof _this.debug === "function") {
341             _this.debug('Web Socket Opened...');
342           }
343           headers["accept-version"] = Stomp.VERSIONS.supportedVersions();
344           headers["heart-beat"] = [_this.heartbeat.outgoing, _this.heartbeat.incoming].join(',');
345           return _this._transmit("CONNECT", headers);
346         };
347       })(this);
348     };
349 
350     Client.prototype.disconnect = function(disconnectCallback, headers) {
351       if (headers == null) {
352         headers = {};
353       }
354       this._transmit("DISCONNECT", headers);
355       this.ws.onclose = null;
356       this.ws.close();
357       this._cleanUp();
358       return typeof disconnectCallback === "function" ? disconnectCallback() : void 0;
359     };
360 
361     Client.prototype._cleanUp = function() {
362       this.connected = false;
363       if (this.pinger) {
364         Stomp.clearInterval(this.pinger);
365       }
366       if (this.ponger) {
367         return Stomp.clearInterval(this.ponger);
368       }
369     };
370 
371     Client.prototype.send = function(destination, headers, body) {
372       if (headers == null) {
373         headers = {};
374       }
375       if (body == null) {
376         body = '';
377       }
378       headers.destination = destination;
379       return this._transmit("SEND", headers, body);
380     };
381 
382     Client.prototype.subscribe = function(destination, callback, headers) {
383       var client;
384       if (headers == null) {
385         headers = {};
386       }
387       if (!headers.id) {
388         headers.id = "sub-" + this.counter++;
389       }
390       headers.destination = destination;
391       this.subscriptions[headers.id] = callback;
392       this._transmit("SUBSCRIBE", headers);
393       client = this;
394       return {
395         id: headers.id,
396         unsubscribe: function() {
397           return client.unsubscribe(headers.id);
398         }
399       };
400     };
401 
402     Client.prototype.unsubscribe = function(id) {
403       delete this.subscriptions[id];
404       return this._transmit("UNSUBSCRIBE", {
405         id: id
406       });
407     };
408 
409     Client.prototype.begin = function(transaction) {
410       var client, txid;
411       txid = transaction || "tx-" + this.counter++;
412       this._transmit("BEGIN", {
413         transaction: txid
414       });
415       client = this;
416       return {
417         id: txid,
418         commit: function() {
419           return client.commit(txid);
420         },
421         abort: function() {
422           return client.abort(txid);
423         }
424       };
425     };
426 
427     Client.prototype.commit = function(transaction) {
428       return this._transmit("COMMIT", {
429         transaction: transaction
430       });
431     };
432 
433     Client.prototype.abort = function(transaction) {
434       return this._transmit("ABORT", {
435         transaction: transaction
436       });
437     };
438 
439     Client.prototype.ack = function(messageID, subscription, headers) {
440       if (headers == null) {
441         headers = {};
442       }
443       headers["message-id"] = messageID;
444       headers.subscription = subscription;
445       return this._transmit("ACK", headers);
446     };
447 
448     Client.prototype.nack = function(messageID, subscription, headers) {
449       if (headers == null) {
450         headers = {};
451       }
452       headers["message-id"] = messageID;
453       headers.subscription = subscription;
454       return this._transmit("NACK", headers);
455     };
456 
457     return Client;
458 
459   })();
460 
461   Stomp = {
462     VERSIONS: {
463       V1_0: '1.0',
464       V1_1: '1.1',
465       V1_2: '1.2',
466       supportedVersions: function() {
467         return '1.1,1.0';
468       }
469     },
470     client: function(url, protocols) {
471       var klass, ws;
472       if (protocols == null) {
473         protocols = ['v10.stomp', 'v11.stomp'];
474       }
475       klass = Stomp.WebSocketClass || WebSocket;
476       ws = new klass(url, protocols);
477       return new Client(ws);
478     },
479     over: function(ws) {
480       return new Client(ws);
481     },
482     Frame: Frame
483   };
484 
485   if (typeof exports !== "undefined" && exports !== null) {
486     exports.Stomp = Stomp;
487   }
488 
489   if (typeof window !== "undefined" && window !== null) {
490     Stomp.setInterval = function(interval, f) {
491       return window.setInterval(f, interval);
492     };
493     Stomp.clearInterval = function(id) {
494       return window.clearInterval(id);
495     };
496     window.Stomp = Stomp;
497   } else if (!exports) {
498     self.Stomp = Stomp;
499   }
500 
501 }).call(this);
View Code

 

posted @ 2024-01-24 10:49  海底流  阅读(82)  评论(0编辑  收藏  举报