source: trip-planner-front/node_modules/sockjs-client/dist/sockjs.js@ 59329aa

Last change on this file since 59329aa was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

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