@depup/primus 8.0.9-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +36 -0
  3. package/changes.json +30 -0
  4. package/dist/primus.js +3663 -0
  5. package/errors.js +51 -0
  6. package/index.js +1153 -0
  7. package/middleware/access-control.js +20 -0
  8. package/middleware/authorization.js +57 -0
  9. package/middleware/error.js +41 -0
  10. package/middleware/forwarded.js +18 -0
  11. package/middleware/no-cache.js +25 -0
  12. package/middleware/primus.js +47 -0
  13. package/middleware/spec.js +36 -0
  14. package/middleware/xss.js +28 -0
  15. package/package.json +140 -0
  16. package/parsers/binary.js +54 -0
  17. package/parsers/ejson.js +41 -0
  18. package/parsers/json.js +35 -0
  19. package/parsers/msgpack.js +55 -0
  20. package/parsers.json +12 -0
  21. package/primus.js +1158 -0
  22. package/spark.js +515 -0
  23. package/transformer.js +237 -0
  24. package/transformers/browserchannel/client.js +92 -0
  25. package/transformers/browserchannel/index.js +19 -0
  26. package/transformers/browserchannel/server.js +64 -0
  27. package/transformers/engine.io/README.md +34 -0
  28. package/transformers/engine.io/client.js +111 -0
  29. package/transformers/engine.io/index.js +15 -0
  30. package/transformers/engine.io/library.js +2273 -0
  31. package/transformers/engine.io/server.js +63 -0
  32. package/transformers/faye/client.js +103 -0
  33. package/transformers/faye/index.js +12 -0
  34. package/transformers/faye/server.js +85 -0
  35. package/transformers/sockjs/README.md +31 -0
  36. package/transformers/sockjs/client.js +86 -0
  37. package/transformers/sockjs/index.js +15 -0
  38. package/transformers/sockjs/library.js +4201 -0
  39. package/transformers/sockjs/server.js +108 -0
  40. package/transformers/uws/index.js +12 -0
  41. package/transformers/uws/server.js +131 -0
  42. package/transformers/websockets/client.js +112 -0
  43. package/transformers/websockets/index.js +12 -0
  44. package/transformers/websockets/server.js +77 -0
  45. package/transformers.json +26 -0
@@ -0,0 +1,4201 @@
1
+ (function(f){var g;if(typeof window!=='undefined'){g=window}else if(typeof self!=='undefined'){g=self}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(_dereq_,module,exports){
2
+ (function (global){(function (){
3
+ 'use strict';
4
+
5
+ var transportList = _dereq_('./transport-list');
6
+
7
+ module.exports = _dereq_('./main')(transportList);
8
+
9
+ // TODO can't get rid of this until all servers do
10
+ if ('_sockjs_onload' in global) {
11
+ setTimeout(global._sockjs_onload, 1);
12
+ }
13
+
14
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
15
+ },{"./main":14,"./transport-list":16}],2:[function(_dereq_,module,exports){
16
+ 'use strict';
17
+
18
+ var inherits = _dereq_('inherits')
19
+ , Event = _dereq_('./event')
20
+ ;
21
+
22
+ function CloseEvent() {
23
+ Event.call(this);
24
+ this.initEvent('close', false, false);
25
+ this.wasClean = false;
26
+ this.code = 0;
27
+ this.reason = '';
28
+ }
29
+
30
+ inherits(CloseEvent, Event);
31
+
32
+ module.exports = CloseEvent;
33
+
34
+ },{"./event":4,"inherits":54}],3:[function(_dereq_,module,exports){
35
+ 'use strict';
36
+
37
+ var inherits = _dereq_('inherits')
38
+ , EventTarget = _dereq_('./eventtarget')
39
+ ;
40
+
41
+ function EventEmitter() {
42
+ EventTarget.call(this);
43
+ }
44
+
45
+ inherits(EventEmitter, EventTarget);
46
+
47
+ EventEmitter.prototype.removeAllListeners = function(type) {
48
+ if (type) {
49
+ delete this._listeners[type];
50
+ } else {
51
+ this._listeners = {};
52
+ }
53
+ };
54
+
55
+ EventEmitter.prototype.once = function(type, listener) {
56
+ var self = this
57
+ , fired = false;
58
+
59
+ function g() {
60
+ self.removeListener(type, g);
61
+
62
+ if (!fired) {
63
+ fired = true;
64
+ listener.apply(this, arguments);
65
+ }
66
+ }
67
+
68
+ this.on(type, g);
69
+ };
70
+
71
+ EventEmitter.prototype.emit = function() {
72
+ var type = arguments[0];
73
+ var listeners = this._listeners[type];
74
+ if (!listeners) {
75
+ return;
76
+ }
77
+ // equivalent of Array.prototype.slice.call(arguments, 1);
78
+ var l = arguments.length;
79
+ var args = new Array(l - 1);
80
+ for (var ai = 1; ai < l; ai++) {
81
+ args[ai - 1] = arguments[ai];
82
+ }
83
+ for (var i = 0; i < listeners.length; i++) {
84
+ listeners[i].apply(this, args);
85
+ }
86
+ };
87
+
88
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener = EventTarget.prototype.addEventListener;
89
+ EventEmitter.prototype.removeListener = EventTarget.prototype.removeEventListener;
90
+
91
+ module.exports.EventEmitter = EventEmitter;
92
+
93
+ },{"./eventtarget":5,"inherits":54}],4:[function(_dereq_,module,exports){
94
+ 'use strict';
95
+
96
+ function Event(eventType) {
97
+ this.type = eventType;
98
+ }
99
+
100
+ Event.prototype.initEvent = function(eventType, canBubble, cancelable) {
101
+ this.type = eventType;
102
+ this.bubbles = canBubble;
103
+ this.cancelable = cancelable;
104
+ this.timeStamp = +new Date();
105
+ return this;
106
+ };
107
+
108
+ Event.prototype.stopPropagation = function() {};
109
+ Event.prototype.preventDefault = function() {};
110
+
111
+ Event.CAPTURING_PHASE = 1;
112
+ Event.AT_TARGET = 2;
113
+ Event.BUBBLING_PHASE = 3;
114
+
115
+ module.exports = Event;
116
+
117
+ },{}],5:[function(_dereq_,module,exports){
118
+ 'use strict';
119
+
120
+ /* Simplified implementation of DOM2 EventTarget.
121
+ * http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget
122
+ */
123
+
124
+ function EventTarget() {
125
+ this._listeners = {};
126
+ }
127
+
128
+ EventTarget.prototype.addEventListener = function(eventType, listener) {
129
+ if (!(eventType in this._listeners)) {
130
+ this._listeners[eventType] = [];
131
+ }
132
+ var arr = this._listeners[eventType];
133
+ // #4
134
+ if (arr.indexOf(listener) === -1) {
135
+ // Make a copy so as not to interfere with a current dispatchEvent.
136
+ arr = arr.concat([listener]);
137
+ }
138
+ this._listeners[eventType] = arr;
139
+ };
140
+
141
+ EventTarget.prototype.removeEventListener = function(eventType, listener) {
142
+ var arr = this._listeners[eventType];
143
+ if (!arr) {
144
+ return;
145
+ }
146
+ var idx = arr.indexOf(listener);
147
+ if (idx !== -1) {
148
+ if (arr.length > 1) {
149
+ // Make a copy so as not to interfere with a current dispatchEvent.
150
+ this._listeners[eventType] = arr.slice(0, idx).concat(arr.slice(idx + 1));
151
+ } else {
152
+ delete this._listeners[eventType];
153
+ }
154
+ return;
155
+ }
156
+ };
157
+
158
+ EventTarget.prototype.dispatchEvent = function() {
159
+ var event = arguments[0];
160
+ var t = event.type;
161
+ // equivalent of Array.prototype.slice.call(arguments, 0);
162
+ var args = arguments.length === 1 ? [event] : Array.apply(null, arguments);
163
+ // TODO: This doesn't match the real behavior; per spec, onfoo get
164
+ // their place in line from the /first/ time they're set from
165
+ // non-null. Although WebKit bumps it to the end every time it's
166
+ // set.
167
+ if (this['on' + t]) {
168
+ this['on' + t].apply(this, args);
169
+ }
170
+ if (t in this._listeners) {
171
+ // Grab a reference to the listeners list. removeEventListener may alter the list.
172
+ var listeners = this._listeners[t];
173
+ for (var i = 0; i < listeners.length; i++) {
174
+ listeners[i].apply(this, args);
175
+ }
176
+ }
177
+ };
178
+
179
+ module.exports = EventTarget;
180
+
181
+ },{}],6:[function(_dereq_,module,exports){
182
+ 'use strict';
183
+
184
+ var inherits = _dereq_('inherits')
185
+ , Event = _dereq_('./event')
186
+ ;
187
+
188
+ function TransportMessageEvent(data) {
189
+ Event.call(this);
190
+ this.initEvent('message', false, false);
191
+ this.data = data;
192
+ }
193
+
194
+ inherits(TransportMessageEvent, Event);
195
+
196
+ module.exports = TransportMessageEvent;
197
+
198
+ },{"./event":4,"inherits":54}],7:[function(_dereq_,module,exports){
199
+ 'use strict';
200
+
201
+ var iframeUtils = _dereq_('./utils/iframe')
202
+ ;
203
+
204
+ function FacadeJS(transport) {
205
+ this._transport = transport;
206
+ transport.on('message', this._transportMessage.bind(this));
207
+ transport.on('close', this._transportClose.bind(this));
208
+ }
209
+
210
+ FacadeJS.prototype._transportClose = function(code, reason) {
211
+ iframeUtils.postMessage('c', JSON.stringify([code, reason]));
212
+ };
213
+ FacadeJS.prototype._transportMessage = function(frame) {
214
+ iframeUtils.postMessage('t', frame);
215
+ };
216
+ FacadeJS.prototype._send = function(data) {
217
+ this._transport.send(data);
218
+ };
219
+ FacadeJS.prototype._close = function() {
220
+ this._transport.close();
221
+ this._transport.removeAllListeners();
222
+ };
223
+
224
+ module.exports = FacadeJS;
225
+
226
+ },{"./utils/iframe":47}],8:[function(_dereq_,module,exports){
227
+ 'use strict';
228
+
229
+ var urlUtils = _dereq_('./utils/url')
230
+ , eventUtils = _dereq_('./utils/event')
231
+ , FacadeJS = _dereq_('./facade')
232
+ , InfoIframeReceiver = _dereq_('./info-iframe-receiver')
233
+ , iframeUtils = _dereq_('./utils/iframe')
234
+ , loc = _dereq_('./location')
235
+ ;
236
+
237
+ module.exports = function(SockJS, availableTransports) {
238
+ var transportMap = {};
239
+ availableTransports.forEach(function(at) {
240
+ if (at.facadeTransport) {
241
+ transportMap[at.facadeTransport.transportName] = at.facadeTransport;
242
+ }
243
+ });
244
+
245
+ // hard-coded for the info iframe
246
+ // TODO see if we can make this more dynamic
247
+ transportMap[InfoIframeReceiver.transportName] = InfoIframeReceiver;
248
+ var parentOrigin;
249
+
250
+ /* eslint-disable camelcase */
251
+ SockJS.bootstrap_iframe = function() {
252
+ /* eslint-enable camelcase */
253
+ var facade;
254
+ iframeUtils.currentWindowId = loc.hash.slice(1);
255
+ var onMessage = function(e) {
256
+ if (e.source !== parent) {
257
+ return;
258
+ }
259
+ if (typeof parentOrigin === 'undefined') {
260
+ parentOrigin = e.origin;
261
+ }
262
+ if (e.origin !== parentOrigin) {
263
+ return;
264
+ }
265
+
266
+ var iframeMessage;
267
+ try {
268
+ iframeMessage = JSON.parse(e.data);
269
+ } catch (ignored) {
270
+ return;
271
+ }
272
+
273
+ if (iframeMessage.windowId !== iframeUtils.currentWindowId) {
274
+ return;
275
+ }
276
+ switch (iframeMessage.type) {
277
+ case 's':
278
+ var p;
279
+ try {
280
+ p = JSON.parse(iframeMessage.data);
281
+ } catch (ignored) {
282
+ break;
283
+ }
284
+ var version = p[0];
285
+ var transport = p[1];
286
+ var transUrl = p[2];
287
+ var baseUrl = p[3];
288
+ // change this to semver logic
289
+ if (version !== SockJS.version) {
290
+ throw new Error('Incompatible SockJS! Main site uses:' +
291
+ ' "' + version + '", the iframe:' +
292
+ ' "' + SockJS.version + '".');
293
+ }
294
+
295
+ if (!urlUtils.isOriginEqual(transUrl, loc.href) ||
296
+ !urlUtils.isOriginEqual(baseUrl, loc.href)) {
297
+ throw new Error('Can\'t connect to different domain from within an ' +
298
+ 'iframe. (' + loc.href + ', ' + transUrl + ', ' + baseUrl + ')');
299
+ }
300
+ facade = new FacadeJS(new transportMap[transport](transUrl, baseUrl));
301
+ break;
302
+ case 'm':
303
+ facade._send(iframeMessage.data);
304
+ break;
305
+ case 'c':
306
+ if (facade) {
307
+ facade._close();
308
+ }
309
+ facade = null;
310
+ break;
311
+ }
312
+ };
313
+
314
+ eventUtils.attachEvent('message', onMessage);
315
+
316
+ // Start
317
+ iframeUtils.postMessage('s');
318
+ };
319
+ };
320
+
321
+ },{"./facade":7,"./info-iframe-receiver":10,"./location":13,"./utils/event":46,"./utils/iframe":47,"./utils/url":52}],9:[function(_dereq_,module,exports){
322
+ 'use strict';
323
+
324
+ var EventEmitter = _dereq_('events').EventEmitter
325
+ , inherits = _dereq_('inherits')
326
+ , objectUtils = _dereq_('./utils/object')
327
+ ;
328
+
329
+ function InfoAjax(url, AjaxObject) {
330
+ EventEmitter.call(this);
331
+
332
+ var self = this;
333
+ var t0 = +new Date();
334
+ this.xo = new AjaxObject('GET', url);
335
+
336
+ this.xo.once('finish', function(status, text) {
337
+ var info, rtt;
338
+ if (status === 200) {
339
+ rtt = (+new Date()) - t0;
340
+ if (text) {
341
+ try {
342
+ info = JSON.parse(text);
343
+ } catch (e) {
344
+ }
345
+ }
346
+
347
+ if (!objectUtils.isObject(info)) {
348
+ info = {};
349
+ }
350
+ }
351
+ self.emit('finish', info, rtt);
352
+ self.removeAllListeners();
353
+ });
354
+ }
355
+
356
+ inherits(InfoAjax, EventEmitter);
357
+
358
+ InfoAjax.prototype.close = function() {
359
+ this.removeAllListeners();
360
+ this.xo.close();
361
+ };
362
+
363
+ module.exports = InfoAjax;
364
+
365
+ },{"./utils/object":49,"events":3,"inherits":54}],10:[function(_dereq_,module,exports){
366
+ 'use strict';
367
+
368
+ var inherits = _dereq_('inherits')
369
+ , EventEmitter = _dereq_('events').EventEmitter
370
+ , XHRLocalObject = _dereq_('./transport/sender/xhr-local')
371
+ , InfoAjax = _dereq_('./info-ajax')
372
+ ;
373
+
374
+ function InfoReceiverIframe(transUrl) {
375
+ var self = this;
376
+ EventEmitter.call(this);
377
+
378
+ this.ir = new InfoAjax(transUrl, XHRLocalObject);
379
+ this.ir.once('finish', function(info, rtt) {
380
+ self.ir = null;
381
+ self.emit('message', JSON.stringify([info, rtt]));
382
+ });
383
+ }
384
+
385
+ inherits(InfoReceiverIframe, EventEmitter);
386
+
387
+ InfoReceiverIframe.transportName = 'iframe-info-receiver';
388
+
389
+ InfoReceiverIframe.prototype.close = function() {
390
+ if (this.ir) {
391
+ this.ir.close();
392
+ this.ir = null;
393
+ }
394
+ this.removeAllListeners();
395
+ };
396
+
397
+ module.exports = InfoReceiverIframe;
398
+
399
+ },{"./info-ajax":9,"./transport/sender/xhr-local":37,"events":3,"inherits":54}],11:[function(_dereq_,module,exports){
400
+ (function (global){(function (){
401
+ 'use strict';
402
+
403
+ var EventEmitter = _dereq_('events').EventEmitter
404
+ , inherits = _dereq_('inherits')
405
+ , utils = _dereq_('./utils/event')
406
+ , IframeTransport = _dereq_('./transport/iframe')
407
+ , InfoReceiverIframe = _dereq_('./info-iframe-receiver')
408
+ ;
409
+
410
+ function InfoIframe(baseUrl, url) {
411
+ var self = this;
412
+ EventEmitter.call(this);
413
+
414
+ var go = function() {
415
+ var ifr = self.ifr = new IframeTransport(InfoReceiverIframe.transportName, url, baseUrl);
416
+
417
+ ifr.once('message', function(msg) {
418
+ if (msg) {
419
+ var d;
420
+ try {
421
+ d = JSON.parse(msg);
422
+ } catch (e) {
423
+ self.emit('finish');
424
+ self.close();
425
+ return;
426
+ }
427
+
428
+ var info = d[0], rtt = d[1];
429
+ self.emit('finish', info, rtt);
430
+ }
431
+ self.close();
432
+ });
433
+
434
+ ifr.once('close', function() {
435
+ self.emit('finish');
436
+ self.close();
437
+ });
438
+ };
439
+
440
+ // TODO this seems the same as the 'needBody' from transports
441
+ if (!global.document.body) {
442
+ utils.attachEvent('load', go);
443
+ } else {
444
+ go();
445
+ }
446
+ }
447
+
448
+ inherits(InfoIframe, EventEmitter);
449
+
450
+ InfoIframe.enabled = function() {
451
+ return IframeTransport.enabled();
452
+ };
453
+
454
+ InfoIframe.prototype.close = function() {
455
+ if (this.ifr) {
456
+ this.ifr.close();
457
+ }
458
+ this.removeAllListeners();
459
+ this.ifr = null;
460
+ };
461
+
462
+ module.exports = InfoIframe;
463
+
464
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
465
+ },{"./info-iframe-receiver":10,"./transport/iframe":22,"./utils/event":46,"events":3,"inherits":54}],12:[function(_dereq_,module,exports){
466
+ 'use strict';
467
+
468
+ var EventEmitter = _dereq_('events').EventEmitter
469
+ , inherits = _dereq_('inherits')
470
+ , urlUtils = _dereq_('./utils/url')
471
+ , XDR = _dereq_('./transport/sender/xdr')
472
+ , XHRCors = _dereq_('./transport/sender/xhr-cors')
473
+ , XHRLocal = _dereq_('./transport/sender/xhr-local')
474
+ , XHRFake = _dereq_('./transport/sender/xhr-fake')
475
+ , InfoIframe = _dereq_('./info-iframe')
476
+ , InfoAjax = _dereq_('./info-ajax')
477
+ ;
478
+
479
+ function InfoReceiver(baseUrl, urlInfo) {
480
+ var self = this;
481
+ EventEmitter.call(this);
482
+
483
+ setTimeout(function() {
484
+ self.doXhr(baseUrl, urlInfo);
485
+ }, 0);
486
+ }
487
+
488
+ inherits(InfoReceiver, EventEmitter);
489
+
490
+ // TODO this is currently ignoring the list of available transports and the whitelist
491
+
492
+ InfoReceiver._getReceiver = function(baseUrl, url, urlInfo) {
493
+ // determine method of CORS support (if needed)
494
+ if (urlInfo.sameOrigin) {
495
+ return new InfoAjax(url, XHRLocal);
496
+ }
497
+ if (XHRCors.enabled) {
498
+ return new InfoAjax(url, XHRCors);
499
+ }
500
+ if (XDR.enabled && urlInfo.sameScheme) {
501
+ return new InfoAjax(url, XDR);
502
+ }
503
+ if (InfoIframe.enabled()) {
504
+ return new InfoIframe(baseUrl, url);
505
+ }
506
+ return new InfoAjax(url, XHRFake);
507
+ };
508
+
509
+ InfoReceiver.prototype.doXhr = function(baseUrl, urlInfo) {
510
+ var self = this
511
+ , url = urlUtils.addPath(baseUrl, '/info')
512
+ ;
513
+
514
+ this.xo = InfoReceiver._getReceiver(baseUrl, url, urlInfo);
515
+
516
+ this.timeoutRef = setTimeout(function() {
517
+ self._cleanup(false);
518
+ self.emit('finish');
519
+ }, InfoReceiver.timeout);
520
+
521
+ this.xo.once('finish', function(info, rtt) {
522
+ self._cleanup(true);
523
+ self.emit('finish', info, rtt);
524
+ });
525
+ };
526
+
527
+ InfoReceiver.prototype._cleanup = function(wasClean) {
528
+ clearTimeout(this.timeoutRef);
529
+ this.timeoutRef = null;
530
+ if (!wasClean && this.xo) {
531
+ this.xo.close();
532
+ }
533
+ this.xo = null;
534
+ };
535
+
536
+ InfoReceiver.prototype.close = function() {
537
+ this.removeAllListeners();
538
+ this._cleanup(false);
539
+ };
540
+
541
+ InfoReceiver.timeout = 8000;
542
+
543
+ module.exports = InfoReceiver;
544
+
545
+ },{"./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,"events":3,"inherits":54}],13:[function(_dereq_,module,exports){
546
+ (function (global){(function (){
547
+ 'use strict';
548
+
549
+ module.exports = global.location || {
550
+ origin: 'http://localhost:80'
551
+ , protocol: 'http:'
552
+ , host: 'localhost'
553
+ , port: 80
554
+ , href: 'http://localhost/'
555
+ , hash: ''
556
+ };
557
+
558
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
559
+ },{}],14:[function(_dereq_,module,exports){
560
+ (function (global){(function (){
561
+ 'use strict';
562
+
563
+ _dereq_('./shims');
564
+
565
+ var URL = _dereq_('url-parse')
566
+ , inherits = _dereq_('inherits')
567
+ , random = _dereq_('./utils/random')
568
+ , escape = _dereq_('./utils/escape')
569
+ , urlUtils = _dereq_('./utils/url')
570
+ , eventUtils = _dereq_('./utils/event')
571
+ , transport = _dereq_('./utils/transport')
572
+ , objectUtils = _dereq_('./utils/object')
573
+ , browser = _dereq_('./utils/browser')
574
+ , log = _dereq_('./utils/log')
575
+ , Event = _dereq_('./event/event')
576
+ , EventTarget = _dereq_('./event/eventtarget')
577
+ , loc = _dereq_('./location')
578
+ , CloseEvent = _dereq_('./event/close')
579
+ , TransportMessageEvent = _dereq_('./event/trans-message')
580
+ , InfoReceiver = _dereq_('./info-receiver')
581
+ ;
582
+
583
+ var transports;
584
+
585
+ // follow constructor steps defined at http://dev.w3.org/html5/websockets/#the-websocket-interface
586
+ function SockJS(url, protocols, options) {
587
+ if (!(this instanceof SockJS)) {
588
+ return new SockJS(url, protocols, options);
589
+ }
590
+ if (arguments.length < 1) {
591
+ throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");
592
+ }
593
+ EventTarget.call(this);
594
+
595
+ this.readyState = SockJS.CONNECTING;
596
+ this.extensions = '';
597
+ this.protocol = '';
598
+
599
+ // non-standard extension
600
+ options = options || {};
601
+ if (options.protocols_whitelist) {
602
+ log.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead.");
603
+ }
604
+ this._transportsWhitelist = options.transports;
605
+ this._transportOptions = options.transportOptions || {};
606
+ this._timeout = options.timeout || 0;
607
+
608
+ var sessionId = options.sessionId || 8;
609
+ if (typeof sessionId === 'function') {
610
+ this._generateSessionId = sessionId;
611
+ } else if (typeof sessionId === 'number') {
612
+ this._generateSessionId = function() {
613
+ return random.string(sessionId);
614
+ };
615
+ } else {
616
+ throw new TypeError('If sessionId is used in the options, it needs to be a number or a function.');
617
+ }
618
+
619
+ this._server = options.server || random.numberString(1000);
620
+
621
+ // Step 1 of WS spec - parse and validate the url. Issue #8
622
+ var parsedUrl = new URL(url);
623
+ if (!parsedUrl.host || !parsedUrl.protocol) {
624
+ throw new SyntaxError("The URL '" + url + "' is invalid");
625
+ } else if (parsedUrl.hash) {
626
+ throw new SyntaxError('The URL must not contain a fragment');
627
+ } else if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
628
+ throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '" + parsedUrl.protocol + "' is not allowed.");
629
+ }
630
+
631
+ var secure = parsedUrl.protocol === 'https:';
632
+ // Step 2 - don't allow secure origin with an insecure protocol
633
+ if (loc.protocol === 'https:' && !secure) {
634
+ // exception is 127.0.0.0/8 and ::1 urls
635
+ if (!urlUtils.isLoopbackAddr(parsedUrl.hostname)) {
636
+ throw new Error('SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS');
637
+ }
638
+ }
639
+
640
+ // Step 3 - check port access - no need here
641
+ // Step 4 - parse protocols argument
642
+ if (!protocols) {
643
+ protocols = [];
644
+ } else if (!Array.isArray(protocols)) {
645
+ protocols = [protocols];
646
+ }
647
+
648
+ // Step 5 - check protocols argument
649
+ var sortedProtocols = protocols.sort();
650
+ sortedProtocols.forEach(function(proto, i) {
651
+ if (!proto) {
652
+ throw new SyntaxError("The protocols entry '" + proto + "' is invalid.");
653
+ }
654
+ if (i < (sortedProtocols.length - 1) && proto === sortedProtocols[i + 1]) {
655
+ throw new SyntaxError("The protocols entry '" + proto + "' is duplicated.");
656
+ }
657
+ });
658
+
659
+ // Step 6 - convert origin
660
+ var o = urlUtils.getOrigin(loc.href);
661
+ this._origin = o ? o.toLowerCase() : null;
662
+
663
+ // remove the trailing slash
664
+ parsedUrl.set('pathname', parsedUrl.pathname.replace(/\/+$/, ''));
665
+
666
+ // store the sanitized url
667
+ this.url = parsedUrl.href;
668
+
669
+ // Step 7 - start connection in background
670
+ // obtain server info
671
+ // http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-26
672
+ this._urlInfo = {
673
+ nullOrigin: !browser.hasDomain()
674
+ , sameOrigin: urlUtils.isOriginEqual(this.url, loc.href)
675
+ , sameScheme: urlUtils.isSchemeEqual(this.url, loc.href)
676
+ };
677
+
678
+ this._ir = new InfoReceiver(this.url, this._urlInfo);
679
+ this._ir.once('finish', this._receiveInfo.bind(this));
680
+ }
681
+
682
+ inherits(SockJS, EventTarget);
683
+
684
+ function userSetCode(code) {
685
+ return code === 1000 || (code >= 3000 && code <= 4999);
686
+ }
687
+
688
+ SockJS.prototype.close = function(code, reason) {
689
+ // Step 1
690
+ if (code && !userSetCode(code)) {
691
+ throw new Error('InvalidAccessError: Invalid code');
692
+ }
693
+ // Step 2.4 states the max is 123 bytes, but we are just checking length
694
+ if (reason && reason.length > 123) {
695
+ throw new SyntaxError('reason argument has an invalid length');
696
+ }
697
+
698
+ // Step 3.1
699
+ if (this.readyState === SockJS.CLOSING || this.readyState === SockJS.CLOSED) {
700
+ return;
701
+ }
702
+
703
+ // TODO look at docs to determine how to set this
704
+ var wasClean = true;
705
+ this._close(code || 1000, reason || 'Normal closure', wasClean);
706
+ };
707
+
708
+ SockJS.prototype.send = function(data) {
709
+ // #13 - convert anything non-string to string
710
+ // TODO this currently turns objects into [object Object]
711
+ if (typeof data !== 'string') {
712
+ data = '' + data;
713
+ }
714
+ if (this.readyState === SockJS.CONNECTING) {
715
+ throw new Error('InvalidStateError: The connection has not been established yet');
716
+ }
717
+ if (this.readyState !== SockJS.OPEN) {
718
+ return;
719
+ }
720
+ this._transport.send(escape.quote(data));
721
+ };
722
+
723
+ SockJS.version = _dereq_('./version');
724
+
725
+ SockJS.CONNECTING = 0;
726
+ SockJS.OPEN = 1;
727
+ SockJS.CLOSING = 2;
728
+ SockJS.CLOSED = 3;
729
+
730
+ SockJS.prototype._receiveInfo = function(info, rtt) {
731
+ this._ir = null;
732
+ if (!info) {
733
+ this._close(1002, 'Cannot connect to server');
734
+ return;
735
+ }
736
+
737
+ // establish a round-trip timeout (RTO) based on the
738
+ // round-trip time (RTT)
739
+ this._rto = this.countRTO(rtt);
740
+ // allow server to override url used for the actual transport
741
+ this._transUrl = info.base_url ? info.base_url : this.url;
742
+ info = objectUtils.extend(info, this._urlInfo);
743
+ // determine list of desired and supported transports
744
+ var enabledTransports = transports.filterToEnabled(this._transportsWhitelist, info);
745
+ this._transports = enabledTransports.main;
746
+
747
+ this._connect();
748
+ };
749
+
750
+ SockJS.prototype._connect = function() {
751
+ for (var Transport = this._transports.shift(); Transport; Transport = this._transports.shift()) {
752
+ if (Transport.needBody) {
753
+ if (!global.document.body ||
754
+ (typeof global.document.readyState !== 'undefined' &&
755
+ global.document.readyState !== 'complete' &&
756
+ global.document.readyState !== 'interactive')) {
757
+ this._transports.unshift(Transport);
758
+ eventUtils.attachEvent('load', this._connect.bind(this));
759
+ return;
760
+ }
761
+ }
762
+
763
+ // calculate timeout based on RTO and round trips. Default to 5s
764
+ var timeoutMs = Math.max(this._timeout, (this._rto * Transport.roundTrips) || 5000);
765
+ this._transportTimeoutId = setTimeout(this._transportTimeout.bind(this), timeoutMs);
766
+
767
+ var transportUrl = urlUtils.addPath(this._transUrl, '/' + this._server + '/' + this._generateSessionId());
768
+ var options = this._transportOptions[Transport.transportName];
769
+ var transportObj = new Transport(transportUrl, this._transUrl, options);
770
+ transportObj.on('message', this._transportMessage.bind(this));
771
+ transportObj.once('close', this._transportClose.bind(this));
772
+ transportObj.transportName = Transport.transportName;
773
+ this._transport = transportObj;
774
+
775
+ return;
776
+ }
777
+ this._close(2000, 'All transports failed', false);
778
+ };
779
+
780
+ SockJS.prototype._transportTimeout = function() {
781
+ if (this.readyState === SockJS.CONNECTING) {
782
+ if (this._transport) {
783
+ this._transport.close();
784
+ }
785
+
786
+ this._transportClose(2007, 'Transport timed out');
787
+ }
788
+ };
789
+
790
+ SockJS.prototype._transportMessage = function(msg) {
791
+ var self = this
792
+ , type = msg.slice(0, 1)
793
+ , content = msg.slice(1)
794
+ , payload
795
+ ;
796
+
797
+ // first check for messages that don't need a payload
798
+ switch (type) {
799
+ case 'o':
800
+ this._open();
801
+ return;
802
+ case 'h':
803
+ this.dispatchEvent(new Event('heartbeat'));
804
+ return;
805
+ }
806
+
807
+ if (content) {
808
+ try {
809
+ payload = JSON.parse(content);
810
+ } catch (e) {
811
+ }
812
+ }
813
+
814
+ if (typeof payload === 'undefined') {
815
+ return;
816
+ }
817
+
818
+ switch (type) {
819
+ case 'a':
820
+ if (Array.isArray(payload)) {
821
+ payload.forEach(function(p) {
822
+ self.dispatchEvent(new TransportMessageEvent(p));
823
+ });
824
+ }
825
+ break;
826
+ case 'm':
827
+ this.dispatchEvent(new TransportMessageEvent(payload));
828
+ break;
829
+ case 'c':
830
+ if (Array.isArray(payload) && payload.length === 2) {
831
+ this._close(payload[0], payload[1], true);
832
+ }
833
+ break;
834
+ }
835
+ };
836
+
837
+ SockJS.prototype._transportClose = function(code, reason) {
838
+ if (this._transport) {
839
+ this._transport.removeAllListeners();
840
+ this._transport = null;
841
+ this.transport = null;
842
+ }
843
+
844
+ if (!userSetCode(code) && code !== 2000 && this.readyState === SockJS.CONNECTING) {
845
+ this._connect();
846
+ return;
847
+ }
848
+
849
+ this._close(code, reason);
850
+ };
851
+
852
+ SockJS.prototype._open = function() {
853
+ if (this.readyState === SockJS.CONNECTING) {
854
+ if (this._transportTimeoutId) {
855
+ clearTimeout(this._transportTimeoutId);
856
+ this._transportTimeoutId = null;
857
+ }
858
+ this.readyState = SockJS.OPEN;
859
+ this.transport = this._transport.transportName;
860
+ this.dispatchEvent(new Event('open'));
861
+ } else {
862
+ // The server might have been restarted, and lost track of our
863
+ // connection.
864
+ this._close(1006, 'Server lost session');
865
+ }
866
+ };
867
+
868
+ SockJS.prototype._close = function(code, reason, wasClean) {
869
+ var forceFail = false;
870
+
871
+ if (this._ir) {
872
+ forceFail = true;
873
+ this._ir.close();
874
+ this._ir = null;
875
+ }
876
+ if (this._transport) {
877
+ this._transport.close();
878
+ this._transport = null;
879
+ this.transport = null;
880
+ }
881
+
882
+ if (this.readyState === SockJS.CLOSED) {
883
+ throw new Error('InvalidStateError: SockJS has already been closed');
884
+ }
885
+
886
+ this.readyState = SockJS.CLOSING;
887
+ setTimeout(function() {
888
+ this.readyState = SockJS.CLOSED;
889
+
890
+ if (forceFail) {
891
+ this.dispatchEvent(new Event('error'));
892
+ }
893
+
894
+ var e = new CloseEvent('close');
895
+ e.wasClean = wasClean || false;
896
+ e.code = code || 1000;
897
+ e.reason = reason;
898
+
899
+ this.dispatchEvent(e);
900
+ this.onmessage = this.onclose = this.onerror = null;
901
+ }.bind(this), 0);
902
+ };
903
+
904
+ // See: http://www.erg.abdn.ac.uk/~gerrit/dccp/notes/ccid2/rto_estimator/
905
+ // and RFC 2988.
906
+ SockJS.prototype.countRTO = function(rtt) {
907
+ // In a local environment, when using IE8/9 and the `jsonp-polling`
908
+ // transport the time needed to establish a connection (the time that pass
909
+ // from the opening of the transport to the call of `_dispatchOpen`) is
910
+ // around 200msec (the lower bound used in the article above) and this
911
+ // causes spurious timeouts. For this reason we calculate a value slightly
912
+ // larger than that used in the article.
913
+ if (rtt > 100) {
914
+ return 4 * rtt; // rto > 400msec
915
+ }
916
+ return 300 + rtt; // 300msec < rto <= 400msec
917
+ };
918
+
919
+ module.exports = function(availableTransports) {
920
+ transports = transport(availableTransports);
921
+ _dereq_('./iframe-bootstrap')(SockJS, availableTransports);
922
+ return SockJS;
923
+ };
924
+
925
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
926
+ },{"./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,"inherits":54,"url-parse":57}],15:[function(_dereq_,module,exports){
927
+ /* eslint-disable */
928
+ /* jscs: disable */
929
+ 'use strict';
930
+
931
+ // pulled specific shims from https://github.com/es-shims/es5-shim
932
+
933
+ var ArrayPrototype = Array.prototype;
934
+ var ObjectPrototype = Object.prototype;
935
+ var FunctionPrototype = Function.prototype;
936
+ var StringPrototype = String.prototype;
937
+ var array_slice = ArrayPrototype.slice;
938
+
939
+ var _toString = ObjectPrototype.toString;
940
+ var isFunction = function (val) {
941
+ return ObjectPrototype.toString.call(val) === '[object Function]';
942
+ };
943
+ var isArray = function isArray(obj) {
944
+ return _toString.call(obj) === '[object Array]';
945
+ };
946
+ var isString = function isString(obj) {
947
+ return _toString.call(obj) === '[object String]';
948
+ };
949
+
950
+ var supportsDescriptors = Object.defineProperty && (function () {
951
+ try {
952
+ Object.defineProperty({}, 'x', {});
953
+ return true;
954
+ } catch (e) { /* this is ES3 */
955
+ return false;
956
+ }
957
+ }());
958
+
959
+ // Define configurable, writable and non-enumerable props
960
+ // if they don't exist.
961
+ var defineProperty;
962
+ if (supportsDescriptors) {
963
+ defineProperty = function (object, name, method, forceAssign) {
964
+ if (!forceAssign && (name in object)) { return; }
965
+ Object.defineProperty(object, name, {
966
+ configurable: true,
967
+ enumerable: false,
968
+ writable: true,
969
+ value: method
970
+ });
971
+ };
972
+ } else {
973
+ defineProperty = function (object, name, method, forceAssign) {
974
+ if (!forceAssign && (name in object)) { return; }
975
+ object[name] = method;
976
+ };
977
+ }
978
+ var defineProperties = function (object, map, forceAssign) {
979
+ for (var name in map) {
980
+ if (ObjectPrototype.hasOwnProperty.call(map, name)) {
981
+ defineProperty(object, name, map[name], forceAssign);
982
+ }
983
+ }
984
+ };
985
+
986
+ var toObject = function (o) {
987
+ if (o == null) { // this matches both null and undefined
988
+ throw new TypeError("can't convert " + o + ' to object');
989
+ }
990
+ return Object(o);
991
+ };
992
+
993
+ //
994
+ // Util
995
+ // ======
996
+ //
997
+
998
+ // ES5 9.4
999
+ // http://es5.github.com/#x9.4
1000
+ // http://jsperf.com/to-integer
1001
+
1002
+ function toInteger(num) {
1003
+ var n = +num;
1004
+ if (n !== n) { // isNaN
1005
+ n = 0;
1006
+ } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
1007
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
1008
+ }
1009
+ return n;
1010
+ }
1011
+
1012
+ function ToUint32(x) {
1013
+ return x >>> 0;
1014
+ }
1015
+
1016
+ //
1017
+ // Function
1018
+ // ========
1019
+ //
1020
+
1021
+ // ES-5 15.3.4.5
1022
+ // http://es5.github.com/#x15.3.4.5
1023
+
1024
+ function Empty() {}
1025
+
1026
+ defineProperties(FunctionPrototype, {
1027
+ bind: function bind(that) { // .length is 1
1028
+ // 1. Let Target be the this value.
1029
+ var target = this;
1030
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
1031
+ if (!isFunction(target)) {
1032
+ throw new TypeError('Function.prototype.bind called on incompatible ' + target);
1033
+ }
1034
+ // 3. Let A be a new (possibly empty) internal list of all of the
1035
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
1036
+ // XXX slicedArgs will stand in for "A" if used
1037
+ var args = array_slice.call(arguments, 1); // for normal call
1038
+ // 4. Let F be a new native ECMAScript object.
1039
+ // 11. Set the [[Prototype]] internal property of F to the standard
1040
+ // built-in Function prototype object as specified in 15.3.3.1.
1041
+ // 12. Set the [[Call]] internal property of F as described in
1042
+ // 15.3.4.5.1.
1043
+ // 13. Set the [[Construct]] internal property of F as described in
1044
+ // 15.3.4.5.2.
1045
+ // 14. Set the [[HasInstance]] internal property of F as described in
1046
+ // 15.3.4.5.3.
1047
+ var binder = function () {
1048
+
1049
+ if (this instanceof bound) {
1050
+ // 15.3.4.5.2 [[Construct]]
1051
+ // When the [[Construct]] internal method of a function object,
1052
+ // F that was created using the bind function is called with a
1053
+ // list of arguments ExtraArgs, the following steps are taken:
1054
+ // 1. Let target be the value of F's [[TargetFunction]]
1055
+ // internal property.
1056
+ // 2. If target has no [[Construct]] internal method, a
1057
+ // TypeError exception is thrown.
1058
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
1059
+ // property.
1060
+ // 4. Let args be a new list containing the same values as the
1061
+ // list boundArgs in the same order followed by the same
1062
+ // values as the list ExtraArgs in the same order.
1063
+ // 5. Return the result of calling the [[Construct]] internal
1064
+ // method of target providing args as the arguments.
1065
+
1066
+ var result = target.apply(
1067
+ this,
1068
+ args.concat(array_slice.call(arguments))
1069
+ );
1070
+ if (Object(result) === result) {
1071
+ return result;
1072
+ }
1073
+ return this;
1074
+
1075
+ } else {
1076
+ // 15.3.4.5.1 [[Call]]
1077
+ // When the [[Call]] internal method of a function object, F,
1078
+ // which was created using the bind function is called with a
1079
+ // this value and a list of arguments ExtraArgs, the following
1080
+ // steps are taken:
1081
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
1082
+ // property.
1083
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
1084
+ // property.
1085
+ // 3. Let target be the value of F's [[TargetFunction]] internal
1086
+ // property.
1087
+ // 4. Let args be a new list containing the same values as the
1088
+ // list boundArgs in the same order followed by the same
1089
+ // values as the list ExtraArgs in the same order.
1090
+ // 5. Return the result of calling the [[Call]] internal method
1091
+ // of target providing boundThis as the this value and
1092
+ // providing args as the arguments.
1093
+
1094
+ // equiv: target.call(this, ...boundArgs, ...args)
1095
+ return target.apply(
1096
+ that,
1097
+ args.concat(array_slice.call(arguments))
1098
+ );
1099
+
1100
+ }
1101
+
1102
+ };
1103
+
1104
+ // 15. If the [[Class]] internal property of Target is "Function", then
1105
+ // a. Let L be the length property of Target minus the length of A.
1106
+ // b. Set the length own property of F to either 0 or L, whichever is
1107
+ // larger.
1108
+ // 16. Else set the length own property of F to 0.
1109
+
1110
+ var boundLength = Math.max(0, target.length - args.length);
1111
+
1112
+ // 17. Set the attributes of the length own property of F to the values
1113
+ // specified in 15.3.5.1.
1114
+ var boundArgs = [];
1115
+ for (var i = 0; i < boundLength; i++) {
1116
+ boundArgs.push('$' + i);
1117
+ }
1118
+
1119
+ // XXX Build a dynamic function with desired amount of arguments is the only
1120
+ // way to set the length property of a function.
1121
+ // In environments where Content Security Policies enabled (Chrome extensions,
1122
+ // for ex.) all use of eval or Function costructor throws an exception.
1123
+ // However in all of these environments Function.prototype.bind exists
1124
+ // and so this code will never be executed.
1125
+ var bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
1126
+
1127
+ if (target.prototype) {
1128
+ Empty.prototype = target.prototype;
1129
+ bound.prototype = new Empty();
1130
+ // Clean up dangling references.
1131
+ Empty.prototype = null;
1132
+ }
1133
+
1134
+ // TODO
1135
+ // 18. Set the [[Extensible]] internal property of F to true.
1136
+
1137
+ // TODO
1138
+ // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
1139
+ // 20. Call the [[DefineOwnProperty]] internal method of F with
1140
+ // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
1141
+ // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
1142
+ // false.
1143
+ // 21. Call the [[DefineOwnProperty]] internal method of F with
1144
+ // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
1145
+ // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
1146
+ // and false.
1147
+
1148
+ // TODO
1149
+ // NOTE Function objects created using Function.prototype.bind do not
1150
+ // have a prototype property or the [[Code]], [[FormalParameters]], and
1151
+ // [[Scope]] internal properties.
1152
+ // XXX can't delete prototype in pure-js.
1153
+
1154
+ // 22. Return F.
1155
+ return bound;
1156
+ }
1157
+ });
1158
+
1159
+ //
1160
+ // Array
1161
+ // =====
1162
+ //
1163
+
1164
+ // ES5 15.4.3.2
1165
+ // http://es5.github.com/#x15.4.3.2
1166
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
1167
+ defineProperties(Array, { isArray: isArray });
1168
+
1169
+ var boxedString = Object('a');
1170
+ var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
1171
+
1172
+ var properlyBoxesContext = function properlyBoxed(method) {
1173
+ // Check node 0.6.21 bug where third parameter is not boxed
1174
+ var properlyBoxesNonStrict = true;
1175
+ var properlyBoxesStrict = true;
1176
+ if (method) {
1177
+ method.call('foo', function (_, __, context) {
1178
+ if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
1179
+ });
1180
+
1181
+ method.call([1], function () {
1182
+ 'use strict';
1183
+ properlyBoxesStrict = typeof this === 'string';
1184
+ }, 'x');
1185
+ }
1186
+ return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
1187
+ };
1188
+
1189
+ defineProperties(ArrayPrototype, {
1190
+ forEach: function forEach(fun /*, thisp*/) {
1191
+ var object = toObject(this),
1192
+ self = splitString && isString(this) ? this.split('') : object,
1193
+ thisp = arguments[1],
1194
+ i = -1,
1195
+ length = self.length >>> 0;
1196
+
1197
+ // If no callback function or if callback is not a callable function
1198
+ if (!isFunction(fun)) {
1199
+ throw new TypeError(); // TODO message
1200
+ }
1201
+
1202
+ while (++i < length) {
1203
+ if (i in self) {
1204
+ // Invoke the callback function with call, passing arguments:
1205
+ // context, property value, property key, thisArg object
1206
+ // context
1207
+ fun.call(thisp, self[i], i, object);
1208
+ }
1209
+ }
1210
+ }
1211
+ }, !properlyBoxesContext(ArrayPrototype.forEach));
1212
+
1213
+ // ES5 15.4.4.14
1214
+ // http://es5.github.com/#x15.4.4.14
1215
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
1216
+ var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
1217
+ defineProperties(ArrayPrototype, {
1218
+ indexOf: function indexOf(sought /*, fromIndex */ ) {
1219
+ var self = splitString && isString(this) ? this.split('') : toObject(this),
1220
+ length = self.length >>> 0;
1221
+
1222
+ if (!length) {
1223
+ return -1;
1224
+ }
1225
+
1226
+ var i = 0;
1227
+ if (arguments.length > 1) {
1228
+ i = toInteger(arguments[1]);
1229
+ }
1230
+
1231
+ // handle negative indices
1232
+ i = i >= 0 ? i : Math.max(0, length + i);
1233
+ for (; i < length; i++) {
1234
+ if (i in self && self[i] === sought) {
1235
+ return i;
1236
+ }
1237
+ }
1238
+ return -1;
1239
+ }
1240
+ }, hasFirefox2IndexOfBug);
1241
+
1242
+ //
1243
+ // String
1244
+ // ======
1245
+ //
1246
+
1247
+ // ES5 15.5.4.14
1248
+ // http://es5.github.com/#x15.5.4.14
1249
+
1250
+ // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1251
+ // Many browsers do not split properly with regular expressions or they
1252
+ // do not perform the split correctly under obscure conditions.
1253
+ // See http://blog.stevenlevithan.com/archives/cross-browser-split
1254
+ // I've tested in many browsers and this seems to cover the deviant ones:
1255
+ // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1256
+ // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1257
+ // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1258
+ // [undefined, "t", undefined, "e", ...]
1259
+ // ''.split(/.?/) should be [], not [""]
1260
+ // '.'.split(/()()/) should be ["."], not ["", "", "."]
1261
+
1262
+ var string_split = StringPrototype.split;
1263
+ if (
1264
+ 'ab'.split(/(?:ab)*/).length !== 2 ||
1265
+ '.'.split(/(.?)(.?)/).length !== 4 ||
1266
+ 'tesst'.split(/(s)*/)[1] === 't' ||
1267
+ 'test'.split(/(?:)/, -1).length !== 4 ||
1268
+ ''.split(/.?/).length ||
1269
+ '.'.split(/()()/).length > 1
1270
+ ) {
1271
+ (function () {
1272
+ var compliantExecNpcg = /()??/.exec('')[1] === void 0; // NPCG: nonparticipating capturing group
1273
+
1274
+ StringPrototype.split = function (separator, limit) {
1275
+ var string = this;
1276
+ if (separator === void 0 && limit === 0) {
1277
+ return [];
1278
+ }
1279
+
1280
+ // If `separator` is not a regex, use native split
1281
+ if (_toString.call(separator) !== '[object RegExp]') {
1282
+ return string_split.call(this, separator, limit);
1283
+ }
1284
+
1285
+ var output = [],
1286
+ flags = (separator.ignoreCase ? 'i' : '') +
1287
+ (separator.multiline ? 'm' : '') +
1288
+ (separator.extended ? 'x' : '') + // Proposed for ES6
1289
+ (separator.sticky ? 'y' : ''), // Firefox 3+
1290
+ lastLastIndex = 0,
1291
+ // Make `global` and avoid `lastIndex` issues by working with a copy
1292
+ separator2, match, lastIndex, lastLength;
1293
+ separator = new RegExp(separator.source, flags + 'g');
1294
+ string += ''; // Type-convert
1295
+ if (!compliantExecNpcg) {
1296
+ // Doesn't need flags gy, but they don't hurt
1297
+ separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags);
1298
+ }
1299
+ /* Values for `limit`, per the spec:
1300
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
1301
+ * If 0, Infinity, or NaN: 0
1302
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1303
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1304
+ * If other: Type-convert, then use the above rules
1305
+ */
1306
+ limit = limit === void 0 ?
1307
+ -1 >>> 0 : // Math.pow(2, 32) - 1
1308
+ ToUint32(limit);
1309
+ while (match = separator.exec(string)) {
1310
+ // `separator.lastIndex` is not reliable cross-browser
1311
+ lastIndex = match.index + match[0].length;
1312
+ if (lastIndex > lastLastIndex) {
1313
+ output.push(string.slice(lastLastIndex, match.index));
1314
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
1315
+ // nonparticipating capturing groups
1316
+ if (!compliantExecNpcg && match.length > 1) {
1317
+ match[0].replace(separator2, function () {
1318
+ for (var i = 1; i < arguments.length - 2; i++) {
1319
+ if (arguments[i] === void 0) {
1320
+ match[i] = void 0;
1321
+ }
1322
+ }
1323
+ });
1324
+ }
1325
+ if (match.length > 1 && match.index < string.length) {
1326
+ ArrayPrototype.push.apply(output, match.slice(1));
1327
+ }
1328
+ lastLength = match[0].length;
1329
+ lastLastIndex = lastIndex;
1330
+ if (output.length >= limit) {
1331
+ break;
1332
+ }
1333
+ }
1334
+ if (separator.lastIndex === match.index) {
1335
+ separator.lastIndex++; // Avoid an infinite loop
1336
+ }
1337
+ }
1338
+ if (lastLastIndex === string.length) {
1339
+ if (lastLength || !separator.test('')) {
1340
+ output.push('');
1341
+ }
1342
+ } else {
1343
+ output.push(string.slice(lastLastIndex));
1344
+ }
1345
+ return output.length > limit ? output.slice(0, limit) : output;
1346
+ };
1347
+ }());
1348
+
1349
+ // [bugfix, chrome]
1350
+ // If separator is undefined, then the result array contains just one String,
1351
+ // which is the this value (converted to a String). If limit is not undefined,
1352
+ // then the output array is truncated so that it contains no more than limit
1353
+ // elements.
1354
+ // "0".split(undefined, 0) -> []
1355
+ } else if ('0'.split(void 0, 0).length) {
1356
+ StringPrototype.split = function split(separator, limit) {
1357
+ if (separator === void 0 && limit === 0) { return []; }
1358
+ return string_split.call(this, separator, limit);
1359
+ };
1360
+ }
1361
+
1362
+ // ECMA-262, 3rd B.2.3
1363
+ // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
1364
+ // non-normative section suggesting uniform semantics and it should be
1365
+ // normalized across all browsers
1366
+ // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1367
+ var string_substr = StringPrototype.substr;
1368
+ var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
1369
+ defineProperties(StringPrototype, {
1370
+ substr: function substr(start, length) {
1371
+ return string_substr.call(
1372
+ this,
1373
+ start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
1374
+ length
1375
+ );
1376
+ }
1377
+ }, hasNegativeSubstrBug);
1378
+
1379
+ },{}],16:[function(_dereq_,module,exports){
1380
+ 'use strict';
1381
+
1382
+ module.exports = [
1383
+ // streaming transports
1384
+ _dereq_('./transport/websocket')
1385
+ , _dereq_('./transport/xhr-streaming')
1386
+ , _dereq_('./transport/xdr-streaming')
1387
+ , _dereq_('./transport/eventsource')
1388
+ , _dereq_('./transport/lib/iframe-wrap')(_dereq_('./transport/eventsource'))
1389
+
1390
+ // polling transports
1391
+ , _dereq_('./transport/htmlfile')
1392
+ , _dereq_('./transport/lib/iframe-wrap')(_dereq_('./transport/htmlfile'))
1393
+ , _dereq_('./transport/xhr-polling')
1394
+ , _dereq_('./transport/xdr-polling')
1395
+ , _dereq_('./transport/lib/iframe-wrap')(_dereq_('./transport/xhr-polling'))
1396
+ , _dereq_('./transport/jsonp-polling')
1397
+ ];
1398
+
1399
+ },{"./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(_dereq_,module,exports){
1400
+ (function (global){(function (){
1401
+ 'use strict';
1402
+
1403
+ var EventEmitter = _dereq_('events').EventEmitter
1404
+ , inherits = _dereq_('inherits')
1405
+ , utils = _dereq_('../../utils/event')
1406
+ , urlUtils = _dereq_('../../utils/url')
1407
+ , XHR = global.XMLHttpRequest
1408
+ ;
1409
+
1410
+ function AbstractXHRObject(method, url, payload, opts) {
1411
+ var self = this;
1412
+ EventEmitter.call(this);
1413
+
1414
+ setTimeout(function () {
1415
+ self._start(method, url, payload, opts);
1416
+ }, 0);
1417
+ }
1418
+
1419
+ inherits(AbstractXHRObject, EventEmitter);
1420
+
1421
+ AbstractXHRObject.prototype._start = function(method, url, payload, opts) {
1422
+ var self = this;
1423
+
1424
+ try {
1425
+ this.xhr = new XHR();
1426
+ } catch (x) {
1427
+ // intentionally empty
1428
+ }
1429
+
1430
+ if (!this.xhr) {
1431
+ this.emit('finish', 0, 'no xhr support');
1432
+ this._cleanup();
1433
+ return;
1434
+ }
1435
+
1436
+ // several browsers cache POSTs
1437
+ url = urlUtils.addQuery(url, 't=' + (+new Date()));
1438
+
1439
+ // Explorer tends to keep connection open, even after the
1440
+ // tab gets closed: http://bugs.jquery.com/ticket/5280
1441
+ this.unloadRef = utils.unloadAdd(function() {
1442
+ self._cleanup(true);
1443
+ });
1444
+ try {
1445
+ this.xhr.open(method, url, true);
1446
+ if (this.timeout && 'timeout' in this.xhr) {
1447
+ this.xhr.timeout = this.timeout;
1448
+ this.xhr.ontimeout = function() {
1449
+ self.emit('finish', 0, '');
1450
+ self._cleanup(false);
1451
+ };
1452
+ }
1453
+ } catch (e) {
1454
+ // IE raises an exception on wrong port.
1455
+ this.emit('finish', 0, '');
1456
+ this._cleanup(false);
1457
+ return;
1458
+ }
1459
+
1460
+ if ((!opts || !opts.noCredentials) && AbstractXHRObject.supportsCORS) {
1461
+ // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest :
1462
+ // "This never affects same-site requests."
1463
+
1464
+ this.xhr.withCredentials = true;
1465
+ }
1466
+ if (opts && opts.headers) {
1467
+ for (var key in opts.headers) {
1468
+ this.xhr.setRequestHeader(key, opts.headers[key]);
1469
+ }
1470
+ }
1471
+
1472
+ this.xhr.onreadystatechange = function() {
1473
+ if (self.xhr) {
1474
+ var x = self.xhr;
1475
+ var text, status;
1476
+ switch (x.readyState) {
1477
+ case 3:
1478
+ // IE doesn't like peeking into responseText or status
1479
+ // on Microsoft.XMLHTTP and readystate=3
1480
+ try {
1481
+ status = x.status;
1482
+ text = x.responseText;
1483
+ } catch (e) {
1484
+ // intentionally empty
1485
+ }
1486
+ // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450
1487
+ if (status === 1223) {
1488
+ status = 204;
1489
+ }
1490
+
1491
+ // IE does return readystate == 3 for 404 answers.
1492
+ if (status === 200 && text && text.length > 0) {
1493
+ self.emit('chunk', status, text);
1494
+ }
1495
+ break;
1496
+ case 4:
1497
+ status = x.status;
1498
+ // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450
1499
+ if (status === 1223) {
1500
+ status = 204;
1501
+ }
1502
+ // IE returns this for a bad port
1503
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa383770(v=vs.85).aspx
1504
+ if (status === 12005 || status === 12029) {
1505
+ status = 0;
1506
+ }
1507
+
1508
+ self.emit('finish', status, x.responseText);
1509
+ self._cleanup(false);
1510
+ break;
1511
+ }
1512
+ }
1513
+ };
1514
+
1515
+ try {
1516
+ self.xhr.send(payload);
1517
+ } catch (e) {
1518
+ self.emit('finish', 0, '');
1519
+ self._cleanup(false);
1520
+ }
1521
+ };
1522
+
1523
+ AbstractXHRObject.prototype._cleanup = function(abort) {
1524
+ if (!this.xhr) {
1525
+ return;
1526
+ }
1527
+ this.removeAllListeners();
1528
+ utils.unloadDel(this.unloadRef);
1529
+
1530
+ // IE needs this field to be a function
1531
+ this.xhr.onreadystatechange = function() {};
1532
+ if (this.xhr.ontimeout) {
1533
+ this.xhr.ontimeout = null;
1534
+ }
1535
+
1536
+ if (abort) {
1537
+ try {
1538
+ this.xhr.abort();
1539
+ } catch (x) {
1540
+ // intentionally empty
1541
+ }
1542
+ }
1543
+ this.unloadRef = this.xhr = null;
1544
+ };
1545
+
1546
+ AbstractXHRObject.prototype.close = function() {
1547
+ this._cleanup(true);
1548
+ };
1549
+
1550
+ AbstractXHRObject.enabled = !!XHR;
1551
+ // override XMLHttpRequest for IE6/7
1552
+ // obfuscate to avoid firewalls
1553
+ var axo = ['Active'].concat('Object').join('X');
1554
+ if (!AbstractXHRObject.enabled && (axo in global)) {
1555
+ XHR = function() {
1556
+ try {
1557
+ return new global[axo]('Microsoft.XMLHTTP');
1558
+ } catch (e) {
1559
+ return null;
1560
+ }
1561
+ };
1562
+ AbstractXHRObject.enabled = !!new XHR();
1563
+ }
1564
+
1565
+ var cors = false;
1566
+ try {
1567
+ cors = 'withCredentials' in new XHR();
1568
+ } catch (ignored) {
1569
+ // intentionally empty
1570
+ }
1571
+
1572
+ AbstractXHRObject.supportsCORS = cors;
1573
+
1574
+ module.exports = AbstractXHRObject;
1575
+
1576
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1577
+ },{"../../utils/event":46,"../../utils/url":52,"events":3,"inherits":54}],18:[function(_dereq_,module,exports){
1578
+ (function (global){(function (){
1579
+ module.exports = global.EventSource;
1580
+
1581
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1582
+ },{}],19:[function(_dereq_,module,exports){
1583
+ (function (global){(function (){
1584
+ 'use strict';
1585
+
1586
+ var Driver = global.WebSocket || global.MozWebSocket;
1587
+ if (Driver) {
1588
+ module.exports = function WebSocketBrowserDriver(url) {
1589
+ return new Driver(url);
1590
+ };
1591
+ } else {
1592
+ module.exports = undefined;
1593
+ }
1594
+
1595
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1596
+ },{}],20:[function(_dereq_,module,exports){
1597
+ 'use strict';
1598
+
1599
+ var inherits = _dereq_('inherits')
1600
+ , AjaxBasedTransport = _dereq_('./lib/ajax-based')
1601
+ , EventSourceReceiver = _dereq_('./receiver/eventsource')
1602
+ , XHRCorsObject = _dereq_('./sender/xhr-cors')
1603
+ , EventSourceDriver = _dereq_('eventsource')
1604
+ ;
1605
+
1606
+ function EventSourceTransport(transUrl) {
1607
+ if (!EventSourceTransport.enabled()) {
1608
+ throw new Error('Transport created when disabled');
1609
+ }
1610
+
1611
+ AjaxBasedTransport.call(this, transUrl, '/eventsource', EventSourceReceiver, XHRCorsObject);
1612
+ }
1613
+
1614
+ inherits(EventSourceTransport, AjaxBasedTransport);
1615
+
1616
+ EventSourceTransport.enabled = function() {
1617
+ return !!EventSourceDriver;
1618
+ };
1619
+
1620
+ EventSourceTransport.transportName = 'eventsource';
1621
+ EventSourceTransport.roundTrips = 2;
1622
+
1623
+ module.exports = EventSourceTransport;
1624
+
1625
+ },{"./lib/ajax-based":24,"./receiver/eventsource":29,"./sender/xhr-cors":35,"eventsource":18,"inherits":54}],21:[function(_dereq_,module,exports){
1626
+ 'use strict';
1627
+
1628
+ var inherits = _dereq_('inherits')
1629
+ , HtmlfileReceiver = _dereq_('./receiver/htmlfile')
1630
+ , XHRLocalObject = _dereq_('./sender/xhr-local')
1631
+ , AjaxBasedTransport = _dereq_('./lib/ajax-based')
1632
+ ;
1633
+
1634
+ function HtmlFileTransport(transUrl) {
1635
+ if (!HtmlfileReceiver.enabled) {
1636
+ throw new Error('Transport created when disabled');
1637
+ }
1638
+ AjaxBasedTransport.call(this, transUrl, '/htmlfile', HtmlfileReceiver, XHRLocalObject);
1639
+ }
1640
+
1641
+ inherits(HtmlFileTransport, AjaxBasedTransport);
1642
+
1643
+ HtmlFileTransport.enabled = function(info) {
1644
+ return HtmlfileReceiver.enabled && info.sameOrigin;
1645
+ };
1646
+
1647
+ HtmlFileTransport.transportName = 'htmlfile';
1648
+ HtmlFileTransport.roundTrips = 2;
1649
+
1650
+ module.exports = HtmlFileTransport;
1651
+
1652
+ },{"./lib/ajax-based":24,"./receiver/htmlfile":30,"./sender/xhr-local":37,"inherits":54}],22:[function(_dereq_,module,exports){
1653
+ 'use strict';
1654
+
1655
+ // Few cool transports do work only for same-origin. In order to make
1656
+ // them work cross-domain we shall use iframe, served from the
1657
+ // remote domain. New browsers have capabilities to communicate with
1658
+ // cross domain iframe using postMessage(). In IE it was implemented
1659
+ // from IE 8+, but of course, IE got some details wrong:
1660
+ // http://msdn.microsoft.com/en-us/library/cc197015(v=VS.85).aspx
1661
+ // http://stevesouders.com/misc/test-postmessage.php
1662
+
1663
+ var inherits = _dereq_('inherits')
1664
+ , EventEmitter = _dereq_('events').EventEmitter
1665
+ , version = _dereq_('../version')
1666
+ , urlUtils = _dereq_('../utils/url')
1667
+ , iframeUtils = _dereq_('../utils/iframe')
1668
+ , eventUtils = _dereq_('../utils/event')
1669
+ , random = _dereq_('../utils/random')
1670
+ ;
1671
+
1672
+ function IframeTransport(transport, transUrl, baseUrl) {
1673
+ if (!IframeTransport.enabled()) {
1674
+ throw new Error('Transport created when disabled');
1675
+ }
1676
+ EventEmitter.call(this);
1677
+
1678
+ var self = this;
1679
+ this.origin = urlUtils.getOrigin(baseUrl);
1680
+ this.baseUrl = baseUrl;
1681
+ this.transUrl = transUrl;
1682
+ this.transport = transport;
1683
+ this.windowId = random.string(8);
1684
+
1685
+ var iframeUrl = urlUtils.addPath(baseUrl, '/iframe.html') + '#' + this.windowId;
1686
+
1687
+ this.iframeObj = iframeUtils.createIframe(iframeUrl, function(r) {
1688
+ self.emit('close', 1006, 'Unable to load an iframe (' + r + ')');
1689
+ self.close();
1690
+ });
1691
+
1692
+ this.onmessageCallback = this._message.bind(this);
1693
+ eventUtils.attachEvent('message', this.onmessageCallback);
1694
+ }
1695
+
1696
+ inherits(IframeTransport, EventEmitter);
1697
+
1698
+ IframeTransport.prototype.close = function() {
1699
+ this.removeAllListeners();
1700
+ if (this.iframeObj) {
1701
+ eventUtils.detachEvent('message', this.onmessageCallback);
1702
+ try {
1703
+ // When the iframe is not loaded, IE raises an exception
1704
+ // on 'contentWindow'.
1705
+ this.postMessage('c');
1706
+ } catch (x) {
1707
+ // intentionally empty
1708
+ }
1709
+ this.iframeObj.cleanup();
1710
+ this.iframeObj = null;
1711
+ this.onmessageCallback = this.iframeObj = null;
1712
+ }
1713
+ };
1714
+
1715
+ IframeTransport.prototype._message = function(e) {
1716
+ if (!urlUtils.isOriginEqual(e.origin, this.origin)) {
1717
+ return;
1718
+ }
1719
+
1720
+ var iframeMessage;
1721
+ try {
1722
+ iframeMessage = JSON.parse(e.data);
1723
+ } catch (ignored) {
1724
+ return;
1725
+ }
1726
+
1727
+ if (iframeMessage.windowId !== this.windowId) {
1728
+ return;
1729
+ }
1730
+
1731
+ switch (iframeMessage.type) {
1732
+ case 's':
1733
+ this.iframeObj.loaded();
1734
+ // window global dependency
1735
+ this.postMessage('s', JSON.stringify([
1736
+ version
1737
+ , this.transport
1738
+ , this.transUrl
1739
+ , this.baseUrl
1740
+ ]));
1741
+ break;
1742
+ case 't':
1743
+ this.emit('message', iframeMessage.data);
1744
+ break;
1745
+ case 'c':
1746
+ var cdata;
1747
+ try {
1748
+ cdata = JSON.parse(iframeMessage.data);
1749
+ } catch (ignored) {
1750
+ return;
1751
+ }
1752
+ this.emit('close', cdata[0], cdata[1]);
1753
+ this.close();
1754
+ break;
1755
+ }
1756
+ };
1757
+
1758
+ IframeTransport.prototype.postMessage = function(type, data) {
1759
+ this.iframeObj.post(JSON.stringify({
1760
+ windowId: this.windowId
1761
+ , type: type
1762
+ , data: data || ''
1763
+ }), this.origin);
1764
+ };
1765
+
1766
+ IframeTransport.prototype.send = function(message) {
1767
+ this.postMessage('m', message);
1768
+ };
1769
+
1770
+ IframeTransport.enabled = function() {
1771
+ return iframeUtils.iframeEnabled;
1772
+ };
1773
+
1774
+ IframeTransport.transportName = 'iframe';
1775
+ IframeTransport.roundTrips = 2;
1776
+
1777
+ module.exports = IframeTransport;
1778
+
1779
+ },{"../utils/event":46,"../utils/iframe":47,"../utils/random":50,"../utils/url":52,"../version":53,"events":3,"inherits":54}],23:[function(_dereq_,module,exports){
1780
+ (function (global){(function (){
1781
+ 'use strict';
1782
+
1783
+ // The simplest and most robust transport, using the well-know cross
1784
+ // domain hack - JSONP. This transport is quite inefficient - one
1785
+ // message could use up to one http request. But at least it works almost
1786
+ // everywhere.
1787
+ // Known limitations:
1788
+ // o you will get a spinning cursor
1789
+ // o for Konqueror a dumb timer is needed to detect errors
1790
+
1791
+ var inherits = _dereq_('inherits')
1792
+ , SenderReceiver = _dereq_('./lib/sender-receiver')
1793
+ , JsonpReceiver = _dereq_('./receiver/jsonp')
1794
+ , jsonpSender = _dereq_('./sender/jsonp')
1795
+ ;
1796
+
1797
+ function JsonPTransport(transUrl) {
1798
+ if (!JsonPTransport.enabled()) {
1799
+ throw new Error('Transport created when disabled');
1800
+ }
1801
+ SenderReceiver.call(this, transUrl, '/jsonp', jsonpSender, JsonpReceiver);
1802
+ }
1803
+
1804
+ inherits(JsonPTransport, SenderReceiver);
1805
+
1806
+ JsonPTransport.enabled = function() {
1807
+ return !!global.document;
1808
+ };
1809
+
1810
+ JsonPTransport.transportName = 'jsonp-polling';
1811
+ JsonPTransport.roundTrips = 1;
1812
+ JsonPTransport.needBody = true;
1813
+
1814
+ module.exports = JsonPTransport;
1815
+
1816
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1817
+ },{"./lib/sender-receiver":28,"./receiver/jsonp":31,"./sender/jsonp":33,"inherits":54}],24:[function(_dereq_,module,exports){
1818
+ 'use strict';
1819
+
1820
+ var inherits = _dereq_('inherits')
1821
+ , urlUtils = _dereq_('../../utils/url')
1822
+ , SenderReceiver = _dereq_('./sender-receiver')
1823
+ ;
1824
+
1825
+ function createAjaxSender(AjaxObject) {
1826
+ return function(url, payload, callback) {
1827
+ var opt = {};
1828
+ if (typeof payload === 'string') {
1829
+ opt.headers = {'Content-type': 'text/plain'};
1830
+ }
1831
+ var ajaxUrl = urlUtils.addPath(url, '/xhr_send');
1832
+ var xo = new AjaxObject('POST', ajaxUrl, payload, opt);
1833
+ xo.once('finish', function(status) {
1834
+ xo = null;
1835
+
1836
+ if (status !== 200 && status !== 204) {
1837
+ return callback(new Error('http status ' + status));
1838
+ }
1839
+ callback();
1840
+ });
1841
+ return function() {
1842
+ xo.close();
1843
+ xo = null;
1844
+
1845
+ var err = new Error('Aborted');
1846
+ err.code = 1000;
1847
+ callback(err);
1848
+ };
1849
+ };
1850
+ }
1851
+
1852
+ function AjaxBasedTransport(transUrl, urlSuffix, Receiver, AjaxObject) {
1853
+ SenderReceiver.call(this, transUrl, urlSuffix, createAjaxSender(AjaxObject), Receiver, AjaxObject);
1854
+ }
1855
+
1856
+ inherits(AjaxBasedTransport, SenderReceiver);
1857
+
1858
+ module.exports = AjaxBasedTransport;
1859
+
1860
+ },{"../../utils/url":52,"./sender-receiver":28,"inherits":54}],25:[function(_dereq_,module,exports){
1861
+ 'use strict';
1862
+
1863
+ var inherits = _dereq_('inherits')
1864
+ , EventEmitter = _dereq_('events').EventEmitter
1865
+ ;
1866
+
1867
+ function BufferedSender(url, sender) {
1868
+ EventEmitter.call(this);
1869
+ this.sendBuffer = [];
1870
+ this.sender = sender;
1871
+ this.url = url;
1872
+ }
1873
+
1874
+ inherits(BufferedSender, EventEmitter);
1875
+
1876
+ BufferedSender.prototype.send = function(message) {
1877
+ this.sendBuffer.push(message);
1878
+ if (!this.sendStop) {
1879
+ this.sendSchedule();
1880
+ }
1881
+ };
1882
+
1883
+ // For polling transports in a situation when in the message callback,
1884
+ // new message is being send. If the sending connection was started
1885
+ // before receiving one, it is possible to saturate the network and
1886
+ // timeout due to the lack of receiving socket. To avoid that we delay
1887
+ // sending messages by some small time, in order to let receiving
1888
+ // connection be started beforehand. This is only a halfmeasure and
1889
+ // does not fix the big problem, but it does make the tests go more
1890
+ // stable on slow networks.
1891
+ BufferedSender.prototype.sendScheduleWait = function() {
1892
+ var self = this;
1893
+ var tref;
1894
+ this.sendStop = function() {
1895
+ self.sendStop = null;
1896
+ clearTimeout(tref);
1897
+ };
1898
+ tref = setTimeout(function() {
1899
+ self.sendStop = null;
1900
+ self.sendSchedule();
1901
+ }, 25);
1902
+ };
1903
+
1904
+ BufferedSender.prototype.sendSchedule = function() {
1905
+ var self = this;
1906
+ if (this.sendBuffer.length > 0) {
1907
+ var payload = '[' + this.sendBuffer.join(',') + ']';
1908
+ this.sendStop = this.sender(this.url, payload, function(err) {
1909
+ self.sendStop = null;
1910
+ if (err) {
1911
+ self.emit('close', err.code || 1006, 'Sending error: ' + err);
1912
+ self.close();
1913
+ } else {
1914
+ self.sendScheduleWait();
1915
+ }
1916
+ });
1917
+ this.sendBuffer = [];
1918
+ }
1919
+ };
1920
+
1921
+ BufferedSender.prototype._cleanup = function() {
1922
+ this.removeAllListeners();
1923
+ };
1924
+
1925
+ BufferedSender.prototype.close = function() {
1926
+ this._cleanup();
1927
+ if (this.sendStop) {
1928
+ this.sendStop();
1929
+ this.sendStop = null;
1930
+ }
1931
+ };
1932
+
1933
+ module.exports = BufferedSender;
1934
+
1935
+ },{"events":3,"inherits":54}],26:[function(_dereq_,module,exports){
1936
+ (function (global){(function (){
1937
+ 'use strict';
1938
+
1939
+ var inherits = _dereq_('inherits')
1940
+ , IframeTransport = _dereq_('../iframe')
1941
+ , objectUtils = _dereq_('../../utils/object')
1942
+ ;
1943
+
1944
+ module.exports = function(transport) {
1945
+
1946
+ function IframeWrapTransport(transUrl, baseUrl) {
1947
+ IframeTransport.call(this, transport.transportName, transUrl, baseUrl);
1948
+ }
1949
+
1950
+ inherits(IframeWrapTransport, IframeTransport);
1951
+
1952
+ IframeWrapTransport.enabled = function(url, info) {
1953
+ if (!global.document) {
1954
+ return false;
1955
+ }
1956
+
1957
+ var iframeInfo = objectUtils.extend({}, info);
1958
+ iframeInfo.sameOrigin = true;
1959
+ return transport.enabled(iframeInfo) && IframeTransport.enabled();
1960
+ };
1961
+
1962
+ IframeWrapTransport.transportName = 'iframe-' + transport.transportName;
1963
+ IframeWrapTransport.needBody = true;
1964
+ IframeWrapTransport.roundTrips = IframeTransport.roundTrips + transport.roundTrips - 1; // html, javascript (2) + transport - no CORS (1)
1965
+
1966
+ IframeWrapTransport.facadeTransport = transport;
1967
+
1968
+ return IframeWrapTransport;
1969
+ };
1970
+
1971
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1972
+ },{"../../utils/object":49,"../iframe":22,"inherits":54}],27:[function(_dereq_,module,exports){
1973
+ 'use strict';
1974
+
1975
+ var inherits = _dereq_('inherits')
1976
+ , EventEmitter = _dereq_('events').EventEmitter
1977
+ ;
1978
+
1979
+ function Polling(Receiver, receiveUrl, AjaxObject) {
1980
+ EventEmitter.call(this);
1981
+ this.Receiver = Receiver;
1982
+ this.receiveUrl = receiveUrl;
1983
+ this.AjaxObject = AjaxObject;
1984
+ this._scheduleReceiver();
1985
+ }
1986
+
1987
+ inherits(Polling, EventEmitter);
1988
+
1989
+ Polling.prototype._scheduleReceiver = function() {
1990
+ var self = this;
1991
+ var poll = this.poll = new this.Receiver(this.receiveUrl, this.AjaxObject);
1992
+
1993
+ poll.on('message', function(msg) {
1994
+ self.emit('message', msg);
1995
+ });
1996
+
1997
+ poll.once('close', function(code, reason) {
1998
+ self.poll = poll = null;
1999
+
2000
+ if (!self.pollIsClosing) {
2001
+ if (reason === 'network') {
2002
+ self._scheduleReceiver();
2003
+ } else {
2004
+ self.emit('close', code || 1006, reason);
2005
+ self.removeAllListeners();
2006
+ }
2007
+ }
2008
+ });
2009
+ };
2010
+
2011
+ Polling.prototype.abort = function() {
2012
+ this.removeAllListeners();
2013
+ this.pollIsClosing = true;
2014
+ if (this.poll) {
2015
+ this.poll.abort();
2016
+ }
2017
+ };
2018
+
2019
+ module.exports = Polling;
2020
+
2021
+ },{"events":3,"inherits":54}],28:[function(_dereq_,module,exports){
2022
+ 'use strict';
2023
+
2024
+ var inherits = _dereq_('inherits')
2025
+ , urlUtils = _dereq_('../../utils/url')
2026
+ , BufferedSender = _dereq_('./buffered-sender')
2027
+ , Polling = _dereq_('./polling')
2028
+ ;
2029
+
2030
+ function SenderReceiver(transUrl, urlSuffix, senderFunc, Receiver, AjaxObject) {
2031
+ var pollUrl = urlUtils.addPath(transUrl, urlSuffix);
2032
+ var self = this;
2033
+ BufferedSender.call(this, transUrl, senderFunc);
2034
+
2035
+ this.poll = new Polling(Receiver, pollUrl, AjaxObject);
2036
+ this.poll.on('message', function(msg) {
2037
+ self.emit('message', msg);
2038
+ });
2039
+ this.poll.once('close', function(code, reason) {
2040
+ self.poll = null;
2041
+ self.emit('close', code, reason);
2042
+ self.close();
2043
+ });
2044
+ }
2045
+
2046
+ inherits(SenderReceiver, BufferedSender);
2047
+
2048
+ SenderReceiver.prototype.close = function() {
2049
+ BufferedSender.prototype.close.call(this);
2050
+ this.removeAllListeners();
2051
+ if (this.poll) {
2052
+ this.poll.abort();
2053
+ this.poll = null;
2054
+ }
2055
+ };
2056
+
2057
+ module.exports = SenderReceiver;
2058
+
2059
+ },{"../../utils/url":52,"./buffered-sender":25,"./polling":27,"inherits":54}],29:[function(_dereq_,module,exports){
2060
+ 'use strict';
2061
+
2062
+ var inherits = _dereq_('inherits')
2063
+ , EventEmitter = _dereq_('events').EventEmitter
2064
+ , EventSourceDriver = _dereq_('eventsource')
2065
+ ;
2066
+
2067
+ function EventSourceReceiver(url) {
2068
+ EventEmitter.call(this);
2069
+
2070
+ var self = this;
2071
+ var es = this.es = new EventSourceDriver(url);
2072
+ es.onmessage = function(e) {
2073
+ self.emit('message', decodeURI(e.data));
2074
+ };
2075
+ es.onerror = function(e) {
2076
+ // ES on reconnection has readyState = 0 or 1.
2077
+ // on network error it's CLOSED = 2
2078
+ var reason = (es.readyState !== 2 ? 'network' : 'permanent');
2079
+ self._cleanup();
2080
+ self._close(reason);
2081
+ };
2082
+ }
2083
+
2084
+ inherits(EventSourceReceiver, EventEmitter);
2085
+
2086
+ EventSourceReceiver.prototype.abort = function() {
2087
+ this._cleanup();
2088
+ this._close('user');
2089
+ };
2090
+
2091
+ EventSourceReceiver.prototype._cleanup = function() {
2092
+ var es = this.es;
2093
+ if (es) {
2094
+ es.onmessage = es.onerror = null;
2095
+ es.close();
2096
+ this.es = null;
2097
+ }
2098
+ };
2099
+
2100
+ EventSourceReceiver.prototype._close = function(reason) {
2101
+ var self = this;
2102
+ // Safari and chrome < 15 crash if we close window before
2103
+ // waiting for ES cleanup. See:
2104
+ // https://code.google.com/p/chromium/issues/detail?id=89155
2105
+ setTimeout(function() {
2106
+ self.emit('close', null, reason);
2107
+ self.removeAllListeners();
2108
+ }, 200);
2109
+ };
2110
+
2111
+ module.exports = EventSourceReceiver;
2112
+
2113
+ },{"events":3,"eventsource":18,"inherits":54}],30:[function(_dereq_,module,exports){
2114
+ (function (global){(function (){
2115
+ 'use strict';
2116
+
2117
+ var inherits = _dereq_('inherits')
2118
+ , iframeUtils = _dereq_('../../utils/iframe')
2119
+ , urlUtils = _dereq_('../../utils/url')
2120
+ , EventEmitter = _dereq_('events').EventEmitter
2121
+ , random = _dereq_('../../utils/random')
2122
+ ;
2123
+
2124
+ function HtmlfileReceiver(url) {
2125
+ EventEmitter.call(this);
2126
+ var self = this;
2127
+ iframeUtils.polluteGlobalNamespace();
2128
+
2129
+ this.id = 'a' + random.string(6);
2130
+ url = urlUtils.addQuery(url, 'c=' + decodeURIComponent(iframeUtils.WPrefix + '.' + this.id));
2131
+
2132
+ var constructFunc = HtmlfileReceiver.htmlfileEnabled ?
2133
+ iframeUtils.createHtmlfile : iframeUtils.createIframe;
2134
+
2135
+ global[iframeUtils.WPrefix][this.id] = {
2136
+ start: function() {
2137
+ self.iframeObj.loaded();
2138
+ }
2139
+ , message: function(data) {
2140
+ self.emit('message', data);
2141
+ }
2142
+ , stop: function() {
2143
+ self._cleanup();
2144
+ self._close('network');
2145
+ }
2146
+ };
2147
+ this.iframeObj = constructFunc(url, function() {
2148
+ self._cleanup();
2149
+ self._close('permanent');
2150
+ });
2151
+ }
2152
+
2153
+ inherits(HtmlfileReceiver, EventEmitter);
2154
+
2155
+ HtmlfileReceiver.prototype.abort = function() {
2156
+ this._cleanup();
2157
+ this._close('user');
2158
+ };
2159
+
2160
+ HtmlfileReceiver.prototype._cleanup = function() {
2161
+ if (this.iframeObj) {
2162
+ this.iframeObj.cleanup();
2163
+ this.iframeObj = null;
2164
+ }
2165
+ delete global[iframeUtils.WPrefix][this.id];
2166
+ };
2167
+
2168
+ HtmlfileReceiver.prototype._close = function(reason) {
2169
+ this.emit('close', null, reason);
2170
+ this.removeAllListeners();
2171
+ };
2172
+
2173
+ HtmlfileReceiver.htmlfileEnabled = false;
2174
+
2175
+ // obfuscate to avoid firewalls
2176
+ var axo = ['Active'].concat('Object').join('X');
2177
+ if (axo in global) {
2178
+ try {
2179
+ HtmlfileReceiver.htmlfileEnabled = !!new global[axo]('htmlfile');
2180
+ } catch (x) {
2181
+ // intentionally empty
2182
+ }
2183
+ }
2184
+
2185
+ HtmlfileReceiver.enabled = HtmlfileReceiver.htmlfileEnabled || iframeUtils.iframeEnabled;
2186
+
2187
+ module.exports = HtmlfileReceiver;
2188
+
2189
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2190
+ },{"../../utils/iframe":47,"../../utils/random":50,"../../utils/url":52,"events":3,"inherits":54}],31:[function(_dereq_,module,exports){
2191
+ (function (global){(function (){
2192
+ 'use strict';
2193
+
2194
+ var utils = _dereq_('../../utils/iframe')
2195
+ , random = _dereq_('../../utils/random')
2196
+ , browser = _dereq_('../../utils/browser')
2197
+ , urlUtils = _dereq_('../../utils/url')
2198
+ , inherits = _dereq_('inherits')
2199
+ , EventEmitter = _dereq_('events').EventEmitter
2200
+ ;
2201
+
2202
+ function JsonpReceiver(url) {
2203
+ var self = this;
2204
+ EventEmitter.call(this);
2205
+
2206
+ utils.polluteGlobalNamespace();
2207
+
2208
+ this.id = 'a' + random.string(6);
2209
+ var urlWithId = urlUtils.addQuery(url, 'c=' + encodeURIComponent(utils.WPrefix + '.' + this.id));
2210
+
2211
+ global[utils.WPrefix][this.id] = this._callback.bind(this);
2212
+ this._createScript(urlWithId);
2213
+
2214
+ // Fallback mostly for Konqueror - stupid timer, 35 seconds shall be plenty.
2215
+ this.timeoutId = setTimeout(function() {
2216
+ self._abort(new Error('JSONP script loaded abnormally (timeout)'));
2217
+ }, JsonpReceiver.timeout);
2218
+ }
2219
+
2220
+ inherits(JsonpReceiver, EventEmitter);
2221
+
2222
+ JsonpReceiver.prototype.abort = function() {
2223
+ if (global[utils.WPrefix][this.id]) {
2224
+ var err = new Error('JSONP user aborted read');
2225
+ err.code = 1000;
2226
+ this._abort(err);
2227
+ }
2228
+ };
2229
+
2230
+ JsonpReceiver.timeout = 35000;
2231
+ JsonpReceiver.scriptErrorTimeout = 1000;
2232
+
2233
+ JsonpReceiver.prototype._callback = function(data) {
2234
+ this._cleanup();
2235
+
2236
+ if (this.aborting) {
2237
+ return;
2238
+ }
2239
+
2240
+ if (data) {
2241
+ this.emit('message', data);
2242
+ }
2243
+ this.emit('close', null, 'network');
2244
+ this.removeAllListeners();
2245
+ };
2246
+
2247
+ JsonpReceiver.prototype._abort = function(err) {
2248
+ this._cleanup();
2249
+ this.aborting = true;
2250
+ this.emit('close', err.code, err.message);
2251
+ this.removeAllListeners();
2252
+ };
2253
+
2254
+ JsonpReceiver.prototype._cleanup = function() {
2255
+ clearTimeout(this.timeoutId);
2256
+ if (this.script2) {
2257
+ this.script2.parentNode.removeChild(this.script2);
2258
+ this.script2 = null;
2259
+ }
2260
+ if (this.script) {
2261
+ var script = this.script;
2262
+ // Unfortunately, you can't really abort script loading of
2263
+ // the script.
2264
+ script.parentNode.removeChild(script);
2265
+ script.onreadystatechange = script.onerror =
2266
+ script.onload = script.onclick = null;
2267
+ this.script = null;
2268
+ }
2269
+ delete global[utils.WPrefix][this.id];
2270
+ };
2271
+
2272
+ JsonpReceiver.prototype._scriptError = function() {
2273
+ var self = this;
2274
+ if (this.errorTimer) {
2275
+ return;
2276
+ }
2277
+
2278
+ this.errorTimer = setTimeout(function() {
2279
+ if (!self.loadedOkay) {
2280
+ self._abort(new Error('JSONP script loaded abnormally (onerror)'));
2281
+ }
2282
+ }, JsonpReceiver.scriptErrorTimeout);
2283
+ };
2284
+
2285
+ JsonpReceiver.prototype._createScript = function(url) {
2286
+ var self = this;
2287
+ var script = this.script = global.document.createElement('script');
2288
+ var script2; // Opera synchronous load trick.
2289
+
2290
+ script.id = 'a' + random.string(8);
2291
+ script.src = url;
2292
+ script.type = 'text/javascript';
2293
+ script.charset = 'UTF-8';
2294
+ script.onerror = this._scriptError.bind(this);
2295
+ script.onload = function() {
2296
+ self._abort(new Error('JSONP script loaded abnormally (onload)'));
2297
+ };
2298
+
2299
+ // IE9 fires 'error' event after onreadystatechange or before, in random order.
2300
+ // Use loadedOkay to determine if actually errored
2301
+ script.onreadystatechange = function() {
2302
+ if (/loaded|closed/.test(script.readyState)) {
2303
+ if (script && script.htmlFor && script.onclick) {
2304
+ self.loadedOkay = true;
2305
+ try {
2306
+ // In IE, actually execute the script.
2307
+ script.onclick();
2308
+ } catch (x) {
2309
+ // intentionally empty
2310
+ }
2311
+ }
2312
+ if (script) {
2313
+ self._abort(new Error('JSONP script loaded abnormally (onreadystatechange)'));
2314
+ }
2315
+ }
2316
+ };
2317
+ // IE: event/htmlFor/onclick trick.
2318
+ // One can't rely on proper order for onreadystatechange. In order to
2319
+ // make sure, set a 'htmlFor' and 'event' properties, so that
2320
+ // script code will be installed as 'onclick' handler for the
2321
+ // script object. Later, onreadystatechange, manually execute this
2322
+ // code. FF and Chrome doesn't work with 'event' and 'htmlFor'
2323
+ // set. For reference see:
2324
+ // http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
2325
+ // Also, read on that about script ordering:
2326
+ // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
2327
+ if (typeof script.async === 'undefined' && global.document.attachEvent) {
2328
+ // According to mozilla docs, in recent browsers script.async defaults
2329
+ // to 'true', so we may use it to detect a good browser:
2330
+ // https://developer.mozilla.org/en/HTML/Element/script
2331
+ if (!browser.isOpera()) {
2332
+ // Naively assume we're in IE
2333
+ try {
2334
+ script.htmlFor = script.id;
2335
+ script.event = 'onclick';
2336
+ } catch (x) {
2337
+ // intentionally empty
2338
+ }
2339
+ script.async = true;
2340
+ } else {
2341
+ // Opera, second sync script hack
2342
+ script2 = this.script2 = global.document.createElement('script');
2343
+ script2.text = "try{var a = document.getElementById('" + script.id + "'); if(a)a.onerror();}catch(x){};";
2344
+ script.async = script2.async = false;
2345
+ }
2346
+ }
2347
+ if (typeof script.async !== 'undefined') {
2348
+ script.async = true;
2349
+ }
2350
+
2351
+ var head = global.document.getElementsByTagName('head')[0];
2352
+ head.insertBefore(script, head.firstChild);
2353
+ if (script2) {
2354
+ head.insertBefore(script2, head.firstChild);
2355
+ }
2356
+ };
2357
+
2358
+ module.exports = JsonpReceiver;
2359
+
2360
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2361
+ },{"../../utils/browser":44,"../../utils/iframe":47,"../../utils/random":50,"../../utils/url":52,"events":3,"inherits":54}],32:[function(_dereq_,module,exports){
2362
+ 'use strict';
2363
+
2364
+ var inherits = _dereq_('inherits')
2365
+ , EventEmitter = _dereq_('events').EventEmitter
2366
+ ;
2367
+
2368
+ function XhrReceiver(url, AjaxObject) {
2369
+ EventEmitter.call(this);
2370
+ var self = this;
2371
+
2372
+ this.bufferPosition = 0;
2373
+
2374
+ this.xo = new AjaxObject('POST', url, null);
2375
+ this.xo.on('chunk', this._chunkHandler.bind(this));
2376
+ this.xo.once('finish', function(status, text) {
2377
+ self._chunkHandler(status, text);
2378
+ self.xo = null;
2379
+ var reason = status === 200 ? 'network' : 'permanent';
2380
+ self.emit('close', null, reason);
2381
+ self._cleanup();
2382
+ });
2383
+ }
2384
+
2385
+ inherits(XhrReceiver, EventEmitter);
2386
+
2387
+ XhrReceiver.prototype._chunkHandler = function(status, text) {
2388
+ if (status !== 200 || !text) {
2389
+ return;
2390
+ }
2391
+
2392
+ for (var idx = -1; ; this.bufferPosition += idx + 1) {
2393
+ var buf = text.slice(this.bufferPosition);
2394
+ idx = buf.indexOf('\n');
2395
+ if (idx === -1) {
2396
+ break;
2397
+ }
2398
+ var msg = buf.slice(0, idx);
2399
+ if (msg) {
2400
+ this.emit('message', msg);
2401
+ }
2402
+ }
2403
+ };
2404
+
2405
+ XhrReceiver.prototype._cleanup = function() {
2406
+ this.removeAllListeners();
2407
+ };
2408
+
2409
+ XhrReceiver.prototype.abort = function() {
2410
+ if (this.xo) {
2411
+ this.xo.close();
2412
+ this.emit('close', null, 'user');
2413
+ this.xo = null;
2414
+ }
2415
+ this._cleanup();
2416
+ };
2417
+
2418
+ module.exports = XhrReceiver;
2419
+
2420
+ },{"events":3,"inherits":54}],33:[function(_dereq_,module,exports){
2421
+ (function (global){(function (){
2422
+ 'use strict';
2423
+
2424
+ var random = _dereq_('../../utils/random')
2425
+ , urlUtils = _dereq_('../../utils/url')
2426
+ ;
2427
+
2428
+ var form, area;
2429
+
2430
+ function createIframe(id) {
2431
+ try {
2432
+ // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
2433
+ return global.document.createElement('<iframe name="' + id + '">');
2434
+ } catch (x) {
2435
+ var iframe = global.document.createElement('iframe');
2436
+ iframe.name = id;
2437
+ return iframe;
2438
+ }
2439
+ }
2440
+
2441
+ function createForm() {
2442
+ form = global.document.createElement('form');
2443
+ form.style.display = 'none';
2444
+ form.style.position = 'absolute';
2445
+ form.method = 'POST';
2446
+ form.enctype = 'application/x-www-form-urlencoded';
2447
+ form.acceptCharset = 'UTF-8';
2448
+
2449
+ area = global.document.createElement('textarea');
2450
+ area.name = 'd';
2451
+ form.appendChild(area);
2452
+
2453
+ global.document.body.appendChild(form);
2454
+ }
2455
+
2456
+ module.exports = function(url, payload, callback) {
2457
+ if (!form) {
2458
+ createForm();
2459
+ }
2460
+ var id = 'a' + random.string(8);
2461
+ form.target = id;
2462
+ form.action = urlUtils.addQuery(urlUtils.addPath(url, '/jsonp_send'), 'i=' + id);
2463
+
2464
+ var iframe = createIframe(id);
2465
+ iframe.id = id;
2466
+ iframe.style.display = 'none';
2467
+ form.appendChild(iframe);
2468
+
2469
+ try {
2470
+ area.value = payload;
2471
+ } catch (e) {
2472
+ // seriously broken browsers get here
2473
+ }
2474
+ form.submit();
2475
+
2476
+ var completed = function(err) {
2477
+ if (!iframe.onerror) {
2478
+ return;
2479
+ }
2480
+ iframe.onreadystatechange = iframe.onerror = iframe.onload = null;
2481
+ // Opera mini doesn't like if we GC iframe
2482
+ // immediately, thus this timeout.
2483
+ setTimeout(function() {
2484
+ iframe.parentNode.removeChild(iframe);
2485
+ iframe = null;
2486
+ }, 500);
2487
+ area.value = '';
2488
+ // It is not possible to detect if the iframe succeeded or
2489
+ // failed to submit our form.
2490
+ callback(err);
2491
+ };
2492
+ iframe.onerror = function() {
2493
+ completed();
2494
+ };
2495
+ iframe.onload = function() {
2496
+ completed();
2497
+ };
2498
+ iframe.onreadystatechange = function(e) {
2499
+ if (iframe.readyState === 'complete') {
2500
+ completed();
2501
+ }
2502
+ };
2503
+ return function() {
2504
+ completed(new Error('Aborted'));
2505
+ };
2506
+ };
2507
+
2508
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2509
+ },{"../../utils/random":50,"../../utils/url":52}],34:[function(_dereq_,module,exports){
2510
+ (function (global){(function (){
2511
+ 'use strict';
2512
+
2513
+ var EventEmitter = _dereq_('events').EventEmitter
2514
+ , inherits = _dereq_('inherits')
2515
+ , eventUtils = _dereq_('../../utils/event')
2516
+ , browser = _dereq_('../../utils/browser')
2517
+ , urlUtils = _dereq_('../../utils/url')
2518
+ ;
2519
+
2520
+ // References:
2521
+ // http://ajaxian.com/archives/100-line-ajax-wrapper
2522
+ // http://msdn.microsoft.com/en-us/library/cc288060(v=VS.85).aspx
2523
+
2524
+ function XDRObject(method, url, payload) {
2525
+ var self = this;
2526
+ EventEmitter.call(this);
2527
+
2528
+ setTimeout(function() {
2529
+ self._start(method, url, payload);
2530
+ }, 0);
2531
+ }
2532
+
2533
+ inherits(XDRObject, EventEmitter);
2534
+
2535
+ XDRObject.prototype._start = function(method, url, payload) {
2536
+ var self = this;
2537
+ var xdr = new global.XDomainRequest();
2538
+ // IE caches even POSTs
2539
+ url = urlUtils.addQuery(url, 't=' + (+new Date()));
2540
+
2541
+ xdr.onerror = function() {
2542
+ self._error();
2543
+ };
2544
+ xdr.ontimeout = function() {
2545
+ self._error();
2546
+ };
2547
+ xdr.onprogress = function() {
2548
+ self.emit('chunk', 200, xdr.responseText);
2549
+ };
2550
+ xdr.onload = function() {
2551
+ self.emit('finish', 200, xdr.responseText);
2552
+ self._cleanup(false);
2553
+ };
2554
+ this.xdr = xdr;
2555
+ this.unloadRef = eventUtils.unloadAdd(function() {
2556
+ self._cleanup(true);
2557
+ });
2558
+ try {
2559
+ // Fails with AccessDenied if port number is bogus
2560
+ this.xdr.open(method, url);
2561
+ if (this.timeout) {
2562
+ this.xdr.timeout = this.timeout;
2563
+ }
2564
+ this.xdr.send(payload);
2565
+ } catch (x) {
2566
+ this._error();
2567
+ }
2568
+ };
2569
+
2570
+ XDRObject.prototype._error = function() {
2571
+ this.emit('finish', 0, '');
2572
+ this._cleanup(false);
2573
+ };
2574
+
2575
+ XDRObject.prototype._cleanup = function(abort) {
2576
+ if (!this.xdr) {
2577
+ return;
2578
+ }
2579
+ this.removeAllListeners();
2580
+ eventUtils.unloadDel(this.unloadRef);
2581
+
2582
+ this.xdr.ontimeout = this.xdr.onerror = this.xdr.onprogress = this.xdr.onload = null;
2583
+ if (abort) {
2584
+ try {
2585
+ this.xdr.abort();
2586
+ } catch (x) {
2587
+ // intentionally empty
2588
+ }
2589
+ }
2590
+ this.unloadRef = this.xdr = null;
2591
+ };
2592
+
2593
+ XDRObject.prototype.close = function() {
2594
+ this._cleanup(true);
2595
+ };
2596
+
2597
+ // IE 8/9 if the request target uses the same scheme - #79
2598
+ XDRObject.enabled = !!(global.XDomainRequest && browser.hasDomain());
2599
+
2600
+ module.exports = XDRObject;
2601
+
2602
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2603
+ },{"../../utils/browser":44,"../../utils/event":46,"../../utils/url":52,"events":3,"inherits":54}],35:[function(_dereq_,module,exports){
2604
+ 'use strict';
2605
+
2606
+ var inherits = _dereq_('inherits')
2607
+ , XhrDriver = _dereq_('../driver/xhr')
2608
+ ;
2609
+
2610
+ function XHRCorsObject(method, url, payload, opts) {
2611
+ XhrDriver.call(this, method, url, payload, opts);
2612
+ }
2613
+
2614
+ inherits(XHRCorsObject, XhrDriver);
2615
+
2616
+ XHRCorsObject.enabled = XhrDriver.enabled && XhrDriver.supportsCORS;
2617
+
2618
+ module.exports = XHRCorsObject;
2619
+
2620
+ },{"../driver/xhr":17,"inherits":54}],36:[function(_dereq_,module,exports){
2621
+ 'use strict';
2622
+
2623
+ var EventEmitter = _dereq_('events').EventEmitter
2624
+ , inherits = _dereq_('inherits')
2625
+ ;
2626
+
2627
+ function XHRFake(/* method, url, payload, opts */) {
2628
+ var self = this;
2629
+ EventEmitter.call(this);
2630
+
2631
+ this.to = setTimeout(function() {
2632
+ self.emit('finish', 200, '{}');
2633
+ }, XHRFake.timeout);
2634
+ }
2635
+
2636
+ inherits(XHRFake, EventEmitter);
2637
+
2638
+ XHRFake.prototype.close = function() {
2639
+ clearTimeout(this.to);
2640
+ };
2641
+
2642
+ XHRFake.timeout = 2000;
2643
+
2644
+ module.exports = XHRFake;
2645
+
2646
+ },{"events":3,"inherits":54}],37:[function(_dereq_,module,exports){
2647
+ 'use strict';
2648
+
2649
+ var inherits = _dereq_('inherits')
2650
+ , XhrDriver = _dereq_('../driver/xhr')
2651
+ ;
2652
+
2653
+ function XHRLocalObject(method, url, payload /*, opts */) {
2654
+ XhrDriver.call(this, method, url, payload, {
2655
+ noCredentials: true
2656
+ });
2657
+ }
2658
+
2659
+ inherits(XHRLocalObject, XhrDriver);
2660
+
2661
+ XHRLocalObject.enabled = XhrDriver.enabled;
2662
+
2663
+ module.exports = XHRLocalObject;
2664
+
2665
+ },{"../driver/xhr":17,"inherits":54}],38:[function(_dereq_,module,exports){
2666
+ 'use strict';
2667
+
2668
+ var utils = _dereq_('../utils/event')
2669
+ , urlUtils = _dereq_('../utils/url')
2670
+ , inherits = _dereq_('inherits')
2671
+ , EventEmitter = _dereq_('events').EventEmitter
2672
+ , WebsocketDriver = _dereq_('./driver/websocket')
2673
+ ;
2674
+
2675
+ function WebSocketTransport(transUrl, ignore, options) {
2676
+ if (!WebSocketTransport.enabled()) {
2677
+ throw new Error('Transport created when disabled');
2678
+ }
2679
+
2680
+ EventEmitter.call(this);
2681
+
2682
+ var self = this;
2683
+ var url = urlUtils.addPath(transUrl, '/websocket');
2684
+ if (url.slice(0, 5) === 'https') {
2685
+ url = 'wss' + url.slice(5);
2686
+ } else {
2687
+ url = 'ws' + url.slice(4);
2688
+ }
2689
+ this.url = url;
2690
+
2691
+ this.ws = new WebsocketDriver(this.url, [], options);
2692
+ this.ws.onmessage = function(e) {
2693
+ self.emit('message', e.data);
2694
+ };
2695
+ // Firefox has an interesting bug. If a websocket connection is
2696
+ // created after onunload, it stays alive even when user
2697
+ // navigates away from the page. In such situation let's lie -
2698
+ // let's not open the ws connection at all. See:
2699
+ // https://github.com/sockjs/sockjs-client/issues/28
2700
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=696085
2701
+ this.unloadRef = utils.unloadAdd(function() {
2702
+ self.ws.close();
2703
+ });
2704
+ this.ws.onclose = function(e) {
2705
+ self.emit('close', e.code, e.reason);
2706
+ self._cleanup();
2707
+ };
2708
+ this.ws.onerror = function(e) {
2709
+ self.emit('close', 1006, 'WebSocket connection broken');
2710
+ self._cleanup();
2711
+ };
2712
+ }
2713
+
2714
+ inherits(WebSocketTransport, EventEmitter);
2715
+
2716
+ WebSocketTransport.prototype.send = function(data) {
2717
+ var msg = '[' + data + ']';
2718
+ this.ws.send(msg);
2719
+ };
2720
+
2721
+ WebSocketTransport.prototype.close = function() {
2722
+ var ws = this.ws;
2723
+ this._cleanup();
2724
+ if (ws) {
2725
+ ws.close();
2726
+ }
2727
+ };
2728
+
2729
+ WebSocketTransport.prototype._cleanup = function() {
2730
+ var ws = this.ws;
2731
+ if (ws) {
2732
+ ws.onmessage = ws.onclose = ws.onerror = null;
2733
+ }
2734
+ utils.unloadDel(this.unloadRef);
2735
+ this.unloadRef = this.ws = null;
2736
+ this.removeAllListeners();
2737
+ };
2738
+
2739
+ WebSocketTransport.enabled = function() {
2740
+ return !!WebsocketDriver;
2741
+ };
2742
+ WebSocketTransport.transportName = 'websocket';
2743
+
2744
+ // In theory, ws should require 1 round trip. But in chrome, this is
2745
+ // not very stable over SSL. Most likely a ws connection requires a
2746
+ // separate SSL connection, in which case 2 round trips are an
2747
+ // absolute minumum.
2748
+ WebSocketTransport.roundTrips = 2;
2749
+
2750
+ module.exports = WebSocketTransport;
2751
+
2752
+ },{"../utils/event":46,"../utils/url":52,"./driver/websocket":19,"events":3,"inherits":54}],39:[function(_dereq_,module,exports){
2753
+ 'use strict';
2754
+
2755
+ var inherits = _dereq_('inherits')
2756
+ , AjaxBasedTransport = _dereq_('./lib/ajax-based')
2757
+ , XdrStreamingTransport = _dereq_('./xdr-streaming')
2758
+ , XhrReceiver = _dereq_('./receiver/xhr')
2759
+ , XDRObject = _dereq_('./sender/xdr')
2760
+ ;
2761
+
2762
+ function XdrPollingTransport(transUrl) {
2763
+ if (!XDRObject.enabled) {
2764
+ throw new Error('Transport created when disabled');
2765
+ }
2766
+ AjaxBasedTransport.call(this, transUrl, '/xhr', XhrReceiver, XDRObject);
2767
+ }
2768
+
2769
+ inherits(XdrPollingTransport, AjaxBasedTransport);
2770
+
2771
+ XdrPollingTransport.enabled = XdrStreamingTransport.enabled;
2772
+ XdrPollingTransport.transportName = 'xdr-polling';
2773
+ XdrPollingTransport.roundTrips = 2; // preflight, ajax
2774
+
2775
+ module.exports = XdrPollingTransport;
2776
+
2777
+ },{"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xdr":34,"./xdr-streaming":40,"inherits":54}],40:[function(_dereq_,module,exports){
2778
+ 'use strict';
2779
+
2780
+ var inherits = _dereq_('inherits')
2781
+ , AjaxBasedTransport = _dereq_('./lib/ajax-based')
2782
+ , XhrReceiver = _dereq_('./receiver/xhr')
2783
+ , XDRObject = _dereq_('./sender/xdr')
2784
+ ;
2785
+
2786
+ // According to:
2787
+ // http://stackoverflow.com/questions/1641507/detect-browser-support-for-cross-domain-xmlhttprequests
2788
+ // http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/
2789
+
2790
+ function XdrStreamingTransport(transUrl) {
2791
+ if (!XDRObject.enabled) {
2792
+ throw new Error('Transport created when disabled');
2793
+ }
2794
+ AjaxBasedTransport.call(this, transUrl, '/xhr_streaming', XhrReceiver, XDRObject);
2795
+ }
2796
+
2797
+ inherits(XdrStreamingTransport, AjaxBasedTransport);
2798
+
2799
+ XdrStreamingTransport.enabled = function(info) {
2800
+ if (info.cookie_needed || info.nullOrigin) {
2801
+ return false;
2802
+ }
2803
+ return XDRObject.enabled && info.sameScheme;
2804
+ };
2805
+
2806
+ XdrStreamingTransport.transportName = 'xdr-streaming';
2807
+ XdrStreamingTransport.roundTrips = 2; // preflight, ajax
2808
+
2809
+ module.exports = XdrStreamingTransport;
2810
+
2811
+ },{"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xdr":34,"inherits":54}],41:[function(_dereq_,module,exports){
2812
+ 'use strict';
2813
+
2814
+ var inherits = _dereq_('inherits')
2815
+ , AjaxBasedTransport = _dereq_('./lib/ajax-based')
2816
+ , XhrReceiver = _dereq_('./receiver/xhr')
2817
+ , XHRCorsObject = _dereq_('./sender/xhr-cors')
2818
+ , XHRLocalObject = _dereq_('./sender/xhr-local')
2819
+ ;
2820
+
2821
+ function XhrPollingTransport(transUrl) {
2822
+ if (!XHRLocalObject.enabled && !XHRCorsObject.enabled) {
2823
+ throw new Error('Transport created when disabled');
2824
+ }
2825
+ AjaxBasedTransport.call(this, transUrl, '/xhr', XhrReceiver, XHRCorsObject);
2826
+ }
2827
+
2828
+ inherits(XhrPollingTransport, AjaxBasedTransport);
2829
+
2830
+ XhrPollingTransport.enabled = function(info) {
2831
+ if (info.nullOrigin) {
2832
+ return false;
2833
+ }
2834
+
2835
+ if (XHRLocalObject.enabled && info.sameOrigin) {
2836
+ return true;
2837
+ }
2838
+ return XHRCorsObject.enabled;
2839
+ };
2840
+
2841
+ XhrPollingTransport.transportName = 'xhr-polling';
2842
+ XhrPollingTransport.roundTrips = 2; // preflight, ajax
2843
+
2844
+ module.exports = XhrPollingTransport;
2845
+
2846
+ },{"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xhr-cors":35,"./sender/xhr-local":37,"inherits":54}],42:[function(_dereq_,module,exports){
2847
+ (function (global){(function (){
2848
+ 'use strict';
2849
+
2850
+ var inherits = _dereq_('inherits')
2851
+ , AjaxBasedTransport = _dereq_('./lib/ajax-based')
2852
+ , XhrReceiver = _dereq_('./receiver/xhr')
2853
+ , XHRCorsObject = _dereq_('./sender/xhr-cors')
2854
+ , XHRLocalObject = _dereq_('./sender/xhr-local')
2855
+ , browser = _dereq_('../utils/browser')
2856
+ ;
2857
+
2858
+ function XhrStreamingTransport(transUrl) {
2859
+ if (!XHRLocalObject.enabled && !XHRCorsObject.enabled) {
2860
+ throw new Error('Transport created when disabled');
2861
+ }
2862
+ AjaxBasedTransport.call(this, transUrl, '/xhr_streaming', XhrReceiver, XHRCorsObject);
2863
+ }
2864
+
2865
+ inherits(XhrStreamingTransport, AjaxBasedTransport);
2866
+
2867
+ XhrStreamingTransport.enabled = function(info) {
2868
+ if (info.nullOrigin) {
2869
+ return false;
2870
+ }
2871
+ // Opera doesn't support xhr-streaming #60
2872
+ // But it might be able to #92
2873
+ if (browser.isOpera()) {
2874
+ return false;
2875
+ }
2876
+
2877
+ return XHRCorsObject.enabled;
2878
+ };
2879
+
2880
+ XhrStreamingTransport.transportName = 'xhr-streaming';
2881
+ XhrStreamingTransport.roundTrips = 2; // preflight, ajax
2882
+
2883
+ // Safari gets confused when a streaming ajax request is started
2884
+ // before onload. This causes the load indicator to spin indefinetely.
2885
+ // Only require body when used in a browser
2886
+ XhrStreamingTransport.needBody = !!global.document;
2887
+
2888
+ module.exports = XhrStreamingTransport;
2889
+
2890
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2891
+ },{"../utils/browser":44,"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xhr-cors":35,"./sender/xhr-local":37,"inherits":54}],43:[function(_dereq_,module,exports){
2892
+ (function (global){(function (){
2893
+ 'use strict';
2894
+
2895
+ if (global.crypto && global.crypto.getRandomValues) {
2896
+ module.exports.randomBytes = function(length) {
2897
+ var bytes = new Uint8Array(length);
2898
+ global.crypto.getRandomValues(bytes);
2899
+ return bytes;
2900
+ };
2901
+ } else {
2902
+ module.exports.randomBytes = function(length) {
2903
+ var bytes = new Array(length);
2904
+ for (var i = 0; i < length; i++) {
2905
+ bytes[i] = Math.floor(Math.random() * 256);
2906
+ }
2907
+ return bytes;
2908
+ };
2909
+ }
2910
+
2911
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2912
+ },{}],44:[function(_dereq_,module,exports){
2913
+ (function (global){(function (){
2914
+ 'use strict';
2915
+
2916
+ module.exports = {
2917
+ isOpera: function() {
2918
+ return global.navigator &&
2919
+ /opera/i.test(global.navigator.userAgent);
2920
+ }
2921
+
2922
+ , isKonqueror: function() {
2923
+ return global.navigator &&
2924
+ /konqueror/i.test(global.navigator.userAgent);
2925
+ }
2926
+
2927
+ // #187 wrap document.domain in try/catch because of WP8 from file:///
2928
+ , hasDomain: function () {
2929
+ // non-browser client always has a domain
2930
+ if (!global.document) {
2931
+ return true;
2932
+ }
2933
+
2934
+ try {
2935
+ return !!global.document.domain;
2936
+ } catch (e) {
2937
+ return false;
2938
+ }
2939
+ }
2940
+ };
2941
+
2942
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2943
+ },{}],45:[function(_dereq_,module,exports){
2944
+ 'use strict';
2945
+
2946
+ // Some extra characters that Chrome gets wrong, and substitutes with
2947
+ // something else on the wire.
2948
+ // eslint-disable-next-line no-control-regex, no-misleading-character-class
2949
+ var extraEscapable = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g
2950
+ , extraLookup;
2951
+
2952
+ // This may be quite slow, so let's delay until user actually uses bad
2953
+ // characters.
2954
+ var unrollLookup = function(escapable) {
2955
+ var i;
2956
+ var unrolled = {};
2957
+ var c = [];
2958
+ for (i = 0; i < 65536; i++) {
2959
+ c.push( String.fromCharCode(i) );
2960
+ }
2961
+ escapable.lastIndex = 0;
2962
+ c.join('').replace(escapable, function(a) {
2963
+ unrolled[ a ] = '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
2964
+ return '';
2965
+ });
2966
+ escapable.lastIndex = 0;
2967
+ return unrolled;
2968
+ };
2969
+
2970
+ // Quote string, also taking care of unicode characters that browsers
2971
+ // often break. Especially, take care of unicode surrogates:
2972
+ // http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates
2973
+ module.exports = {
2974
+ quote: function(string) {
2975
+ var quoted = JSON.stringify(string);
2976
+
2977
+ // In most cases this should be very fast and good enough.
2978
+ extraEscapable.lastIndex = 0;
2979
+ if (!extraEscapable.test(quoted)) {
2980
+ return quoted;
2981
+ }
2982
+
2983
+ if (!extraLookup) {
2984
+ extraLookup = unrollLookup(extraEscapable);
2985
+ }
2986
+
2987
+ return quoted.replace(extraEscapable, function(a) {
2988
+ return extraLookup[a];
2989
+ });
2990
+ }
2991
+ };
2992
+
2993
+ },{}],46:[function(_dereq_,module,exports){
2994
+ (function (global){(function (){
2995
+ 'use strict';
2996
+
2997
+ var random = _dereq_('./random');
2998
+
2999
+ var onUnload = {}
3000
+ , afterUnload = false
3001
+ // detect google chrome packaged apps because they don't allow the 'unload' event
3002
+ , isChromePackagedApp = global.chrome && global.chrome.app && global.chrome.app.runtime
3003
+ ;
3004
+
3005
+ module.exports = {
3006
+ attachEvent: function(event, listener) {
3007
+ if (typeof global.addEventListener !== 'undefined') {
3008
+ global.addEventListener(event, listener, false);
3009
+ } else if (global.document && global.attachEvent) {
3010
+ // IE quirks.
3011
+ // According to: http://stevesouders.com/misc/test-postmessage.php
3012
+ // the message gets delivered only to 'document', not 'window'.
3013
+ global.document.attachEvent('on' + event, listener);
3014
+ // I get 'window' for ie8.
3015
+ global.attachEvent('on' + event, listener);
3016
+ }
3017
+ }
3018
+
3019
+ , detachEvent: function(event, listener) {
3020
+ if (typeof global.addEventListener !== 'undefined') {
3021
+ global.removeEventListener(event, listener, false);
3022
+ } else if (global.document && global.detachEvent) {
3023
+ global.document.detachEvent('on' + event, listener);
3024
+ global.detachEvent('on' + event, listener);
3025
+ }
3026
+ }
3027
+
3028
+ , unloadAdd: function(listener) {
3029
+ if (isChromePackagedApp) {
3030
+ return null;
3031
+ }
3032
+
3033
+ var ref = random.string(8);
3034
+ onUnload[ref] = listener;
3035
+ if (afterUnload) {
3036
+ setTimeout(this.triggerUnloadCallbacks, 0);
3037
+ }
3038
+ return ref;
3039
+ }
3040
+
3041
+ , unloadDel: function(ref) {
3042
+ if (ref in onUnload) {
3043
+ delete onUnload[ref];
3044
+ }
3045
+ }
3046
+
3047
+ , triggerUnloadCallbacks: function() {
3048
+ for (var ref in onUnload) {
3049
+ onUnload[ref]();
3050
+ delete onUnload[ref];
3051
+ }
3052
+ }
3053
+ };
3054
+
3055
+ var unloadTriggered = function() {
3056
+ if (afterUnload) {
3057
+ return;
3058
+ }
3059
+ afterUnload = true;
3060
+ module.exports.triggerUnloadCallbacks();
3061
+ };
3062
+
3063
+ // 'unload' alone is not reliable in opera within an iframe, but we
3064
+ // can't use `beforeunload` as IE fires it on javascript: links.
3065
+ if (!isChromePackagedApp) {
3066
+ module.exports.attachEvent('unload', unloadTriggered);
3067
+ }
3068
+
3069
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3070
+ },{"./random":50}],47:[function(_dereq_,module,exports){
3071
+ (function (global){(function (){
3072
+ 'use strict';
3073
+
3074
+ var eventUtils = _dereq_('./event')
3075
+ , browser = _dereq_('./browser')
3076
+ ;
3077
+
3078
+ module.exports = {
3079
+ WPrefix: '_jp'
3080
+ , currentWindowId: null
3081
+
3082
+ , polluteGlobalNamespace: function() {
3083
+ if (!(module.exports.WPrefix in global)) {
3084
+ global[module.exports.WPrefix] = {};
3085
+ }
3086
+ }
3087
+
3088
+ , postMessage: function(type, data) {
3089
+ if (global.parent !== global) {
3090
+ global.parent.postMessage(JSON.stringify({
3091
+ windowId: module.exports.currentWindowId
3092
+ , type: type
3093
+ , data: data || ''
3094
+ }), '*');
3095
+ } else {
3096
+ }
3097
+ }
3098
+
3099
+ , createIframe: function(iframeUrl, errorCallback) {
3100
+ var iframe = global.document.createElement('iframe');
3101
+ var tref, unloadRef;
3102
+ var unattach = function() {
3103
+ clearTimeout(tref);
3104
+ // Explorer had problems with that.
3105
+ try {
3106
+ iframe.onload = null;
3107
+ } catch (x) {
3108
+ // intentionally empty
3109
+ }
3110
+ iframe.onerror = null;
3111
+ };
3112
+ var cleanup = function() {
3113
+ if (iframe) {
3114
+ unattach();
3115
+ // This timeout makes chrome fire onbeforeunload event
3116
+ // within iframe. Without the timeout it goes straight to
3117
+ // onunload.
3118
+ setTimeout(function() {
3119
+ if (iframe) {
3120
+ iframe.parentNode.removeChild(iframe);
3121
+ }
3122
+ iframe = null;
3123
+ }, 0);
3124
+ eventUtils.unloadDel(unloadRef);
3125
+ }
3126
+ };
3127
+ var onerror = function(err) {
3128
+ if (iframe) {
3129
+ cleanup();
3130
+ errorCallback(err);
3131
+ }
3132
+ };
3133
+ var post = function(msg, origin) {
3134
+ setTimeout(function() {
3135
+ try {
3136
+ // When the iframe is not loaded, IE raises an exception
3137
+ // on 'contentWindow'.
3138
+ if (iframe && iframe.contentWindow) {
3139
+ iframe.contentWindow.postMessage(msg, origin);
3140
+ }
3141
+ } catch (x) {
3142
+ // intentionally empty
3143
+ }
3144
+ }, 0);
3145
+ };
3146
+
3147
+ iframe.src = iframeUrl;
3148
+ iframe.style.display = 'none';
3149
+ iframe.style.position = 'absolute';
3150
+ iframe.onerror = function() {
3151
+ onerror('onerror');
3152
+ };
3153
+ iframe.onload = function() {
3154
+ // `onload` is triggered before scripts on the iframe are
3155
+ // executed. Give it few seconds to actually load stuff.
3156
+ clearTimeout(tref);
3157
+ tref = setTimeout(function() {
3158
+ onerror('onload timeout');
3159
+ }, 2000);
3160
+ };
3161
+ global.document.body.appendChild(iframe);
3162
+ tref = setTimeout(function() {
3163
+ onerror('timeout');
3164
+ }, 15000);
3165
+ unloadRef = eventUtils.unloadAdd(cleanup);
3166
+ return {
3167
+ post: post
3168
+ , cleanup: cleanup
3169
+ , loaded: unattach
3170
+ };
3171
+ }
3172
+
3173
+ /* eslint no-undef: "off", new-cap: "off" */
3174
+ , createHtmlfile: function(iframeUrl, errorCallback) {
3175
+ var axo = ['Active'].concat('Object').join('X');
3176
+ var doc = new global[axo]('htmlfile');
3177
+ var tref, unloadRef;
3178
+ var iframe;
3179
+ var unattach = function() {
3180
+ clearTimeout(tref);
3181
+ iframe.onerror = null;
3182
+ };
3183
+ var cleanup = function() {
3184
+ if (doc) {
3185
+ unattach();
3186
+ eventUtils.unloadDel(unloadRef);
3187
+ iframe.parentNode.removeChild(iframe);
3188
+ iframe = doc = null;
3189
+ CollectGarbage();
3190
+ }
3191
+ };
3192
+ var onerror = function(r) {
3193
+ if (doc) {
3194
+ cleanup();
3195
+ errorCallback(r);
3196
+ }
3197
+ };
3198
+ var post = function(msg, origin) {
3199
+ try {
3200
+ // When the iframe is not loaded, IE raises an exception
3201
+ // on 'contentWindow'.
3202
+ setTimeout(function() {
3203
+ if (iframe && iframe.contentWindow) {
3204
+ iframe.contentWindow.postMessage(msg, origin);
3205
+ }
3206
+ }, 0);
3207
+ } catch (x) {
3208
+ // intentionally empty
3209
+ }
3210
+ };
3211
+
3212
+ doc.open();
3213
+ doc.write('<html><s' + 'cript>' +
3214
+ 'document.domain="' + global.document.domain + '";' +
3215
+ '</s' + 'cript></html>');
3216
+ doc.close();
3217
+ doc.parentWindow[module.exports.WPrefix] = global[module.exports.WPrefix];
3218
+ var c = doc.createElement('div');
3219
+ doc.body.appendChild(c);
3220
+ iframe = doc.createElement('iframe');
3221
+ c.appendChild(iframe);
3222
+ iframe.src = iframeUrl;
3223
+ iframe.onerror = function() {
3224
+ onerror('onerror');
3225
+ };
3226
+ tref = setTimeout(function() {
3227
+ onerror('timeout');
3228
+ }, 15000);
3229
+ unloadRef = eventUtils.unloadAdd(cleanup);
3230
+ return {
3231
+ post: post
3232
+ , cleanup: cleanup
3233
+ , loaded: unattach
3234
+ };
3235
+ }
3236
+ };
3237
+
3238
+ module.exports.iframeEnabled = false;
3239
+ if (global.document) {
3240
+ // postMessage misbehaves in konqueror 4.6.5 - the messages are delivered with
3241
+ // huge delay, or not at all.
3242
+ module.exports.iframeEnabled = (typeof global.postMessage === 'function' ||
3243
+ typeof global.postMessage === 'object') && (!browser.isKonqueror());
3244
+ }
3245
+
3246
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3247
+ },{"./browser":44,"./event":46}],48:[function(_dereq_,module,exports){
3248
+ (function (global){(function (){
3249
+ 'use strict';
3250
+
3251
+ var logObject = {};
3252
+ ['log', 'debug', 'warn'].forEach(function (level) {
3253
+ var levelExists;
3254
+
3255
+ try {
3256
+ levelExists = global.console && global.console[level] && global.console[level].apply;
3257
+ } catch(e) {
3258
+ // do nothing
3259
+ }
3260
+
3261
+ logObject[level] = levelExists ? function () {
3262
+ return global.console[level].apply(global.console, arguments);
3263
+ } : (level === 'log' ? function () {} : logObject.log);
3264
+ });
3265
+
3266
+ module.exports = logObject;
3267
+
3268
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3269
+ },{}],49:[function(_dereq_,module,exports){
3270
+ 'use strict';
3271
+
3272
+ module.exports = {
3273
+ isObject: function(obj) {
3274
+ var type = typeof obj;
3275
+ return type === 'function' || type === 'object' && !!obj;
3276
+ }
3277
+
3278
+ , extend: function(obj) {
3279
+ if (!this.isObject(obj)) {
3280
+ return obj;
3281
+ }
3282
+ var source, prop;
3283
+ for (var i = 1, length = arguments.length; i < length; i++) {
3284
+ source = arguments[i];
3285
+ for (prop in source) {
3286
+ if (Object.prototype.hasOwnProperty.call(source, prop)) {
3287
+ obj[prop] = source[prop];
3288
+ }
3289
+ }
3290
+ }
3291
+ return obj;
3292
+ }
3293
+ };
3294
+
3295
+ },{}],50:[function(_dereq_,module,exports){
3296
+ 'use strict';
3297
+
3298
+ var crypto = _dereq_('crypto');
3299
+
3300
+ // This string has length 32, a power of 2, so the modulus doesn't introduce a
3301
+ // bias.
3302
+ var _randomStringChars = 'abcdefghijklmnopqrstuvwxyz012345';
3303
+ module.exports = {
3304
+ string: function(length) {
3305
+ var max = _randomStringChars.length;
3306
+ var bytes = crypto.randomBytes(length);
3307
+ var ret = [];
3308
+ for (var i = 0; i < length; i++) {
3309
+ ret.push(_randomStringChars.substr(bytes[i] % max, 1));
3310
+ }
3311
+ return ret.join('');
3312
+ }
3313
+
3314
+ , number: function(max) {
3315
+ return Math.floor(Math.random() * max);
3316
+ }
3317
+
3318
+ , numberString: function(max) {
3319
+ var t = ('' + (max - 1)).length;
3320
+ var p = new Array(t + 1).join('0');
3321
+ return (p + this.number(max)).slice(-t);
3322
+ }
3323
+ };
3324
+
3325
+ },{"crypto":43}],51:[function(_dereq_,module,exports){
3326
+ 'use strict';
3327
+
3328
+ module.exports = function(availableTransports) {
3329
+ return {
3330
+ filterToEnabled: function(transportsWhitelist, info) {
3331
+ var transports = {
3332
+ main: []
3333
+ , facade: []
3334
+ };
3335
+ if (!transportsWhitelist) {
3336
+ transportsWhitelist = [];
3337
+ } else if (typeof transportsWhitelist === 'string') {
3338
+ transportsWhitelist = [transportsWhitelist];
3339
+ }
3340
+
3341
+ availableTransports.forEach(function(trans) {
3342
+ if (!trans) {
3343
+ return;
3344
+ }
3345
+
3346
+ if (trans.transportName === 'websocket' && info.websocket === false) {
3347
+ return;
3348
+ }
3349
+
3350
+ if (transportsWhitelist.length &&
3351
+ transportsWhitelist.indexOf(trans.transportName) === -1) {
3352
+ return;
3353
+ }
3354
+
3355
+ if (trans.enabled(info)) {
3356
+ transports.main.push(trans);
3357
+ if (trans.facadeTransport) {
3358
+ transports.facade.push(trans.facadeTransport);
3359
+ }
3360
+ } else {
3361
+ }
3362
+ });
3363
+ return transports;
3364
+ }
3365
+ };
3366
+ };
3367
+
3368
+ },{}],52:[function(_dereq_,module,exports){
3369
+ 'use strict';
3370
+
3371
+ var URL = _dereq_('url-parse');
3372
+
3373
+ module.exports = {
3374
+ getOrigin: function(url) {
3375
+ if (!url) {
3376
+ return null;
3377
+ }
3378
+
3379
+ var p = new URL(url);
3380
+ if (p.protocol === 'file:') {
3381
+ return null;
3382
+ }
3383
+
3384
+ var port = p.port;
3385
+ if (!port) {
3386
+ port = (p.protocol === 'https:') ? '443' : '80';
3387
+ }
3388
+
3389
+ return p.protocol + '//' + p.hostname + ':' + port;
3390
+ }
3391
+
3392
+ , isOriginEqual: function(a, b) {
3393
+ var res = this.getOrigin(a) === this.getOrigin(b);
3394
+ return res;
3395
+ }
3396
+
3397
+ , isSchemeEqual: function(a, b) {
3398
+ return (a.split(':')[0] === b.split(':')[0]);
3399
+ }
3400
+
3401
+ , addPath: function (url, path) {
3402
+ var qs = url.split('?');
3403
+ return qs[0] + path + (qs[1] ? '?' + qs[1] : '');
3404
+ }
3405
+
3406
+ , addQuery: function (url, q) {
3407
+ return url + (url.indexOf('?') === -1 ? ('?' + q) : ('&' + q));
3408
+ }
3409
+
3410
+ , isLoopbackAddr: function (addr) {
3411
+ return /^127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) || /^\[::1\]$/.test(addr);
3412
+ }
3413
+ };
3414
+
3415
+ },{"url-parse":57}],53:[function(_dereq_,module,exports){
3416
+ module.exports = '1.6.0';
3417
+
3418
+ },{}],54:[function(_dereq_,module,exports){
3419
+ if (typeof Object.create === 'function') {
3420
+ // implementation from standard node.js 'util' module
3421
+ module.exports = function inherits(ctor, superCtor) {
3422
+ if (superCtor) {
3423
+ ctor.super_ = superCtor
3424
+ ctor.prototype = Object.create(superCtor.prototype, {
3425
+ constructor: {
3426
+ value: ctor,
3427
+ enumerable: false,
3428
+ writable: true,
3429
+ configurable: true
3430
+ }
3431
+ })
3432
+ }
3433
+ };
3434
+ } else {
3435
+ // old school shim for old browsers
3436
+ module.exports = function inherits(ctor, superCtor) {
3437
+ if (superCtor) {
3438
+ ctor.super_ = superCtor
3439
+ var TempCtor = function () {}
3440
+ TempCtor.prototype = superCtor.prototype
3441
+ ctor.prototype = new TempCtor()
3442
+ ctor.prototype.constructor = ctor
3443
+ }
3444
+ }
3445
+ }
3446
+
3447
+ },{}],55:[function(_dereq_,module,exports){
3448
+ 'use strict';
3449
+
3450
+ var has = Object.prototype.hasOwnProperty
3451
+ , undef;
3452
+
3453
+ /**
3454
+ * Decode a URI encoded string.
3455
+ *
3456
+ * @param {String} input The URI encoded string.
3457
+ * @returns {String|Null} The decoded string.
3458
+ * @api private
3459
+ */
3460
+ function decode(input) {
3461
+ try {
3462
+ return decodeURIComponent(input.replace(/\+/g, ' '));
3463
+ } catch (e) {
3464
+ return null;
3465
+ }
3466
+ }
3467
+
3468
+ /**
3469
+ * Attempts to encode a given input.
3470
+ *
3471
+ * @param {String} input The string that needs to be encoded.
3472
+ * @returns {String|Null} The encoded string.
3473
+ * @api private
3474
+ */
3475
+ function encode(input) {
3476
+ try {
3477
+ return encodeURIComponent(input);
3478
+ } catch (e) {
3479
+ return null;
3480
+ }
3481
+ }
3482
+
3483
+ /**
3484
+ * Simple query string parser.
3485
+ *
3486
+ * @param {String} query The query string that needs to be parsed.
3487
+ * @returns {Object}
3488
+ * @api public
3489
+ */
3490
+ function querystring(query) {
3491
+ var parser = /([^=?&]+)=?([^&]*)/g
3492
+ , result = {}
3493
+ , part;
3494
+
3495
+ while (part = parser.exec(query)) {
3496
+ var key = decode(part[1])
3497
+ , value = decode(part[2]);
3498
+
3499
+ //
3500
+ // Prevent overriding of existing properties. This ensures that build-in
3501
+ // methods like `toString` or __proto__ are not overriden by malicious
3502
+ // querystrings.
3503
+ //
3504
+ // In the case if failed decoding, we want to omit the key/value pairs
3505
+ // from the result.
3506
+ //
3507
+ if (key === null || value === null || key in result) continue;
3508
+ result[key] = value;
3509
+ }
3510
+
3511
+ return result;
3512
+ }
3513
+
3514
+ /**
3515
+ * Transform a query string to an object.
3516
+ *
3517
+ * @param {Object} obj Object that should be transformed.
3518
+ * @param {String} prefix Optional prefix.
3519
+ * @returns {String}
3520
+ * @api public
3521
+ */
3522
+ function querystringify(obj, prefix) {
3523
+ prefix = prefix || '';
3524
+
3525
+ var pairs = []
3526
+ , value
3527
+ , key;
3528
+
3529
+ //
3530
+ // Optionally prefix with a '?' if needed
3531
+ //
3532
+ if ('string' !== typeof prefix) prefix = '?';
3533
+
3534
+ for (key in obj) {
3535
+ if (has.call(obj, key)) {
3536
+ value = obj[key];
3537
+
3538
+ //
3539
+ // Edge cases where we actually want to encode the value to an empty
3540
+ // string instead of the stringified value.
3541
+ //
3542
+ if (!value && (value === null || value === undef || isNaN(value))) {
3543
+ value = '';
3544
+ }
3545
+
3546
+ key = encodeURIComponent(key);
3547
+ value = encodeURIComponent(value);
3548
+
3549
+ //
3550
+ // If we failed to encode the strings, we should bail out as we don't
3551
+ // want to add invalid strings to the query.
3552
+ //
3553
+ if (key === null || value === null) continue;
3554
+ pairs.push(key +'='+ value);
3555
+ }
3556
+ }
3557
+
3558
+ return pairs.length ? prefix + pairs.join('&') : '';
3559
+ }
3560
+
3561
+ //
3562
+ // Expose the module.
3563
+ //
3564
+ exports.stringify = querystringify;
3565
+ exports.parse = querystring;
3566
+
3567
+ },{}],56:[function(_dereq_,module,exports){
3568
+ 'use strict';
3569
+
3570
+ /**
3571
+ * Check if we're required to add a port number.
3572
+ *
3573
+ * @see https://url.spec.whatwg.org/#default-port
3574
+ * @param {Number|String} port Port number we need to check
3575
+ * @param {String} protocol Protocol we need to check against.
3576
+ * @returns {Boolean} Is it a default port for the given protocol
3577
+ * @api private
3578
+ */
3579
+ module.exports = function required(port, protocol) {
3580
+ protocol = protocol.split(':')[0];
3581
+ port = +port;
3582
+
3583
+ if (!port) return false;
3584
+
3585
+ switch (protocol) {
3586
+ case 'http':
3587
+ case 'ws':
3588
+ return port !== 80;
3589
+
3590
+ case 'https':
3591
+ case 'wss':
3592
+ return port !== 443;
3593
+
3594
+ case 'ftp':
3595
+ return port !== 21;
3596
+
3597
+ case 'gopher':
3598
+ return port !== 70;
3599
+
3600
+ case 'file':
3601
+ return false;
3602
+ }
3603
+
3604
+ return port !== 0;
3605
+ };
3606
+
3607
+ },{}],57:[function(_dereq_,module,exports){
3608
+ (function (global){(function (){
3609
+ 'use strict';
3610
+
3611
+ var required = _dereq_('requires-port')
3612
+ , qs = _dereq_('querystringify')
3613
+ , controlOrWhitespace = /^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/
3614
+ , CRHTLF = /[\n\r\t]/g
3615
+ , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//
3616
+ , port = /:\d+$/
3617
+ , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i
3618
+ , windowsDriveLetter = /^[a-zA-Z]:/;
3619
+
3620
+ /**
3621
+ * Remove control characters and whitespace from the beginning of a string.
3622
+ *
3623
+ * @param {Object|String} str String to trim.
3624
+ * @returns {String} A new string representing `str` stripped of control
3625
+ * characters and whitespace from its beginning.
3626
+ * @public
3627
+ */
3628
+ function trimLeft(str) {
3629
+ return (str ? str : '').toString().replace(controlOrWhitespace, '');
3630
+ }
3631
+
3632
+ /**
3633
+ * These are the parse rules for the URL parser, it informs the parser
3634
+ * about:
3635
+ *
3636
+ * 0. The char it Needs to parse, if it's a string it should be done using
3637
+ * indexOf, RegExp using exec and NaN means set as current value.
3638
+ * 1. The property we should set when parsing this value.
3639
+ * 2. Indication if it's backwards or forward parsing, when set as number it's
3640
+ * the value of extra chars that should be split off.
3641
+ * 3. Inherit from location if non existing in the parser.
3642
+ * 4. `toLowerCase` the resulting value.
3643
+ */
3644
+ var rules = [
3645
+ ['#', 'hash'], // Extract from the back.
3646
+ ['?', 'query'], // Extract from the back.
3647
+ function sanitize(address, url) { // Sanitize what is left of the address
3648
+ return isSpecial(url.protocol) ? address.replace(/\\/g, '/') : address;
3649
+ },
3650
+ ['/', 'pathname'], // Extract from the back.
3651
+ ['@', 'auth', 1], // Extract from the front.
3652
+ [NaN, 'host', undefined, 1, 1], // Set left over value.
3653
+ [/:(\d*)$/, 'port', undefined, 1], // RegExp the back.
3654
+ [NaN, 'hostname', undefined, 1, 1] // Set left over.
3655
+ ];
3656
+
3657
+ /**
3658
+ * These properties should not be copied or inherited from. This is only needed
3659
+ * for all non blob URL's as a blob URL does not include a hash, only the
3660
+ * origin.
3661
+ *
3662
+ * @type {Object}
3663
+ * @private
3664
+ */
3665
+ var ignore = { hash: 1, query: 1 };
3666
+
3667
+ /**
3668
+ * The location object differs when your code is loaded through a normal page,
3669
+ * Worker or through a worker using a blob. And with the blobble begins the
3670
+ * trouble as the location object will contain the URL of the blob, not the
3671
+ * location of the page where our code is loaded in. The actual origin is
3672
+ * encoded in the `pathname` so we can thankfully generate a good "default"
3673
+ * location from it so we can generate proper relative URL's again.
3674
+ *
3675
+ * @param {Object|String} loc Optional default location object.
3676
+ * @returns {Object} lolcation object.
3677
+ * @public
3678
+ */
3679
+ function lolcation(loc) {
3680
+ var globalVar;
3681
+
3682
+ if (typeof window !== 'undefined') globalVar = window;
3683
+ else if (typeof global !== 'undefined') globalVar = global;
3684
+ else if (typeof self !== 'undefined') globalVar = self;
3685
+ else globalVar = {};
3686
+
3687
+ var location = globalVar.location || {};
3688
+ loc = loc || location;
3689
+
3690
+ var finaldestination = {}
3691
+ , type = typeof loc
3692
+ , key;
3693
+
3694
+ if ('blob:' === loc.protocol) {
3695
+ finaldestination = new Url(unescape(loc.pathname), {});
3696
+ } else if ('string' === type) {
3697
+ finaldestination = new Url(loc, {});
3698
+ for (key in ignore) delete finaldestination[key];
3699
+ } else if ('object' === type) {
3700
+ for (key in loc) {
3701
+ if (key in ignore) continue;
3702
+ finaldestination[key] = loc[key];
3703
+ }
3704
+
3705
+ if (finaldestination.slashes === undefined) {
3706
+ finaldestination.slashes = slashes.test(loc.href);
3707
+ }
3708
+ }
3709
+
3710
+ return finaldestination;
3711
+ }
3712
+
3713
+ /**
3714
+ * Check whether a protocol scheme is special.
3715
+ *
3716
+ * @param {String} The protocol scheme of the URL
3717
+ * @return {Boolean} `true` if the protocol scheme is special, else `false`
3718
+ * @private
3719
+ */
3720
+ function isSpecial(scheme) {
3721
+ return (
3722
+ scheme === 'file:' ||
3723
+ scheme === 'ftp:' ||
3724
+ scheme === 'http:' ||
3725
+ scheme === 'https:' ||
3726
+ scheme === 'ws:' ||
3727
+ scheme === 'wss:'
3728
+ );
3729
+ }
3730
+
3731
+ /**
3732
+ * @typedef ProtocolExtract
3733
+ * @type Object
3734
+ * @property {String} protocol Protocol matched in the URL, in lowercase.
3735
+ * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
3736
+ * @property {String} rest Rest of the URL that is not part of the protocol.
3737
+ */
3738
+
3739
+ /**
3740
+ * Extract protocol information from a URL with/without double slash ("//").
3741
+ *
3742
+ * @param {String} address URL we want to extract from.
3743
+ * @param {Object} location
3744
+ * @return {ProtocolExtract} Extracted information.
3745
+ * @private
3746
+ */
3747
+ function extractProtocol(address, location) {
3748
+ address = trimLeft(address);
3749
+ address = address.replace(CRHTLF, '');
3750
+ location = location || {};
3751
+
3752
+ var match = protocolre.exec(address);
3753
+ var protocol = match[1] ? match[1].toLowerCase() : '';
3754
+ var forwardSlashes = !!match[2];
3755
+ var otherSlashes = !!match[3];
3756
+ var slashesCount = 0;
3757
+ var rest;
3758
+
3759
+ if (forwardSlashes) {
3760
+ if (otherSlashes) {
3761
+ rest = match[2] + match[3] + match[4];
3762
+ slashesCount = match[2].length + match[3].length;
3763
+ } else {
3764
+ rest = match[2] + match[4];
3765
+ slashesCount = match[2].length;
3766
+ }
3767
+ } else {
3768
+ if (otherSlashes) {
3769
+ rest = match[3] + match[4];
3770
+ slashesCount = match[3].length;
3771
+ } else {
3772
+ rest = match[4]
3773
+ }
3774
+ }
3775
+
3776
+ if (protocol === 'file:') {
3777
+ if (slashesCount >= 2) {
3778
+ rest = rest.slice(2);
3779
+ }
3780
+ } else if (isSpecial(protocol)) {
3781
+ rest = match[4];
3782
+ } else if (protocol) {
3783
+ if (forwardSlashes) {
3784
+ rest = rest.slice(2);
3785
+ }
3786
+ } else if (slashesCount >= 2 && isSpecial(location.protocol)) {
3787
+ rest = match[4];
3788
+ }
3789
+
3790
+ return {
3791
+ protocol: protocol,
3792
+ slashes: forwardSlashes || isSpecial(protocol),
3793
+ slashesCount: slashesCount,
3794
+ rest: rest
3795
+ };
3796
+ }
3797
+
3798
+ /**
3799
+ * Resolve a relative URL pathname against a base URL pathname.
3800
+ *
3801
+ * @param {String} relative Pathname of the relative URL.
3802
+ * @param {String} base Pathname of the base URL.
3803
+ * @return {String} Resolved pathname.
3804
+ * @private
3805
+ */
3806
+ function resolve(relative, base) {
3807
+ if (relative === '') return base;
3808
+
3809
+ var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
3810
+ , i = path.length
3811
+ , last = path[i - 1]
3812
+ , unshift = false
3813
+ , up = 0;
3814
+
3815
+ while (i--) {
3816
+ if (path[i] === '.') {
3817
+ path.splice(i, 1);
3818
+ } else if (path[i] === '..') {
3819
+ path.splice(i, 1);
3820
+ up++;
3821
+ } else if (up) {
3822
+ if (i === 0) unshift = true;
3823
+ path.splice(i, 1);
3824
+ up--;
3825
+ }
3826
+ }
3827
+
3828
+ if (unshift) path.unshift('');
3829
+ if (last === '.' || last === '..') path.push('');
3830
+
3831
+ return path.join('/');
3832
+ }
3833
+
3834
+ /**
3835
+ * The actual URL instance. Instead of returning an object we've opted-in to
3836
+ * create an actual constructor as it's much more memory efficient and
3837
+ * faster and it pleases my OCD.
3838
+ *
3839
+ * It is worth noting that we should not use `URL` as class name to prevent
3840
+ * clashes with the global URL instance that got introduced in browsers.
3841
+ *
3842
+ * @constructor
3843
+ * @param {String} address URL we want to parse.
3844
+ * @param {Object|String} [location] Location defaults for relative paths.
3845
+ * @param {Boolean|Function} [parser] Parser for the query string.
3846
+ * @private
3847
+ */
3848
+ function Url(address, location, parser) {
3849
+ address = trimLeft(address);
3850
+ address = address.replace(CRHTLF, '');
3851
+
3852
+ if (!(this instanceof Url)) {
3853
+ return new Url(address, location, parser);
3854
+ }
3855
+
3856
+ var relative, extracted, parse, instruction, index, key
3857
+ , instructions = rules.slice()
3858
+ , type = typeof location
3859
+ , url = this
3860
+ , i = 0;
3861
+
3862
+ //
3863
+ // The following if statements allows this module two have compatibility with
3864
+ // 2 different API:
3865
+ //
3866
+ // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
3867
+ // where the boolean indicates that the query string should also be parsed.
3868
+ //
3869
+ // 2. The `URL` interface of the browser which accepts a URL, object as
3870
+ // arguments. The supplied object will be used as default values / fall-back
3871
+ // for relative paths.
3872
+ //
3873
+ if ('object' !== type && 'string' !== type) {
3874
+ parser = location;
3875
+ location = null;
3876
+ }
3877
+
3878
+ if (parser && 'function' !== typeof parser) parser = qs.parse;
3879
+
3880
+ location = lolcation(location);
3881
+
3882
+ //
3883
+ // Extract protocol information before running the instructions.
3884
+ //
3885
+ extracted = extractProtocol(address || '', location);
3886
+ relative = !extracted.protocol && !extracted.slashes;
3887
+ url.slashes = extracted.slashes || relative && location.slashes;
3888
+ url.protocol = extracted.protocol || location.protocol || '';
3889
+ address = extracted.rest;
3890
+
3891
+ //
3892
+ // When the authority component is absent the URL starts with a path
3893
+ // component.
3894
+ //
3895
+ if (
3896
+ extracted.protocol === 'file:' && (
3897
+ extracted.slashesCount !== 2 || windowsDriveLetter.test(address)) ||
3898
+ (!extracted.slashes &&
3899
+ (extracted.protocol ||
3900
+ extracted.slashesCount < 2 ||
3901
+ !isSpecial(url.protocol)))
3902
+ ) {
3903
+ instructions[3] = [/(.*)/, 'pathname'];
3904
+ }
3905
+
3906
+ for (; i < instructions.length; i++) {
3907
+ instruction = instructions[i];
3908
+
3909
+ if (typeof instruction === 'function') {
3910
+ address = instruction(address, url);
3911
+ continue;
3912
+ }
3913
+
3914
+ parse = instruction[0];
3915
+ key = instruction[1];
3916
+
3917
+ if (parse !== parse) {
3918
+ url[key] = address;
3919
+ } else if ('string' === typeof parse) {
3920
+ index = parse === '@'
3921
+ ? address.lastIndexOf(parse)
3922
+ : address.indexOf(parse);
3923
+
3924
+ if (~index) {
3925
+ if ('number' === typeof instruction[2]) {
3926
+ url[key] = address.slice(0, index);
3927
+ address = address.slice(index + instruction[2]);
3928
+ } else {
3929
+ url[key] = address.slice(index);
3930
+ address = address.slice(0, index);
3931
+ }
3932
+ }
3933
+ } else if ((index = parse.exec(address))) {
3934
+ url[key] = index[1];
3935
+ address = address.slice(0, index.index);
3936
+ }
3937
+
3938
+ url[key] = url[key] || (
3939
+ relative && instruction[3] ? location[key] || '' : ''
3940
+ );
3941
+
3942
+ //
3943
+ // Hostname, host and protocol should be lowercased so they can be used to
3944
+ // create a proper `origin`.
3945
+ //
3946
+ if (instruction[4]) url[key] = url[key].toLowerCase();
3947
+ }
3948
+
3949
+ //
3950
+ // Also parse the supplied query string in to an object. If we're supplied
3951
+ // with a custom parser as function use that instead of the default build-in
3952
+ // parser.
3953
+ //
3954
+ if (parser) url.query = parser(url.query);
3955
+
3956
+ //
3957
+ // If the URL is relative, resolve the pathname against the base URL.
3958
+ //
3959
+ if (
3960
+ relative
3961
+ && location.slashes
3962
+ && url.pathname.charAt(0) !== '/'
3963
+ && (url.pathname !== '' || location.pathname !== '')
3964
+ ) {
3965
+ url.pathname = resolve(url.pathname, location.pathname);
3966
+ }
3967
+
3968
+ //
3969
+ // Default to a / for pathname if none exists. This normalizes the URL
3970
+ // to always have a /
3971
+ //
3972
+ if (url.pathname.charAt(0) !== '/' && isSpecial(url.protocol)) {
3973
+ url.pathname = '/' + url.pathname;
3974
+ }
3975
+
3976
+ //
3977
+ // We should not add port numbers if they are already the default port number
3978
+ // for a given protocol. As the host also contains the port number we're going
3979
+ // override it with the hostname which contains no port number.
3980
+ //
3981
+ if (!required(url.port, url.protocol)) {
3982
+ url.host = url.hostname;
3983
+ url.port = '';
3984
+ }
3985
+
3986
+ //
3987
+ // Parse down the `auth` for the username and password.
3988
+ //
3989
+ url.username = url.password = '';
3990
+
3991
+ if (url.auth) {
3992
+ index = url.auth.indexOf(':');
3993
+
3994
+ if (~index) {
3995
+ url.username = url.auth.slice(0, index);
3996
+ url.username = encodeURIComponent(decodeURIComponent(url.username));
3997
+
3998
+ url.password = url.auth.slice(index + 1);
3999
+ url.password = encodeURIComponent(decodeURIComponent(url.password))
4000
+ } else {
4001
+ url.username = encodeURIComponent(decodeURIComponent(url.auth));
4002
+ }
4003
+
4004
+ url.auth = url.password ? url.username +':'+ url.password : url.username;
4005
+ }
4006
+
4007
+ url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host
4008
+ ? url.protocol +'//'+ url.host
4009
+ : 'null';
4010
+
4011
+ //
4012
+ // The href is just the compiled result.
4013
+ //
4014
+ url.href = url.toString();
4015
+ }
4016
+
4017
+ /**
4018
+ * This is convenience method for changing properties in the URL instance to
4019
+ * insure that they all propagate correctly.
4020
+ *
4021
+ * @param {String} part Property we need to adjust.
4022
+ * @param {Mixed} value The newly assigned value.
4023
+ * @param {Boolean|Function} fn When setting the query, it will be the function
4024
+ * used to parse the query.
4025
+ * When setting the protocol, double slash will be
4026
+ * removed from the final url if it is true.
4027
+ * @returns {URL} URL instance for chaining.
4028
+ * @public
4029
+ */
4030
+ function set(part, value, fn) {
4031
+ var url = this;
4032
+
4033
+ switch (part) {
4034
+ case 'query':
4035
+ if ('string' === typeof value && value.length) {
4036
+ value = (fn || qs.parse)(value);
4037
+ }
4038
+
4039
+ url[part] = value;
4040
+ break;
4041
+
4042
+ case 'port':
4043
+ url[part] = value;
4044
+
4045
+ if (!required(value, url.protocol)) {
4046
+ url.host = url.hostname;
4047
+ url[part] = '';
4048
+ } else if (value) {
4049
+ url.host = url.hostname +':'+ value;
4050
+ }
4051
+
4052
+ break;
4053
+
4054
+ case 'hostname':
4055
+ url[part] = value;
4056
+
4057
+ if (url.port) value += ':'+ url.port;
4058
+ url.host = value;
4059
+ break;
4060
+
4061
+ case 'host':
4062
+ url[part] = value;
4063
+
4064
+ if (port.test(value)) {
4065
+ value = value.split(':');
4066
+ url.port = value.pop();
4067
+ url.hostname = value.join(':');
4068
+ } else {
4069
+ url.hostname = value;
4070
+ url.port = '';
4071
+ }
4072
+
4073
+ break;
4074
+
4075
+ case 'protocol':
4076
+ url.protocol = value.toLowerCase();
4077
+ url.slashes = !fn;
4078
+ break;
4079
+
4080
+ case 'pathname':
4081
+ case 'hash':
4082
+ if (value) {
4083
+ var char = part === 'pathname' ? '/' : '#';
4084
+ url[part] = value.charAt(0) !== char ? char + value : value;
4085
+ } else {
4086
+ url[part] = value;
4087
+ }
4088
+ break;
4089
+
4090
+ case 'username':
4091
+ case 'password':
4092
+ url[part] = encodeURIComponent(value);
4093
+ break;
4094
+
4095
+ case 'auth':
4096
+ var index = value.indexOf(':');
4097
+
4098
+ if (~index) {
4099
+ url.username = value.slice(0, index);
4100
+ url.username = encodeURIComponent(decodeURIComponent(url.username));
4101
+
4102
+ url.password = value.slice(index + 1);
4103
+ url.password = encodeURIComponent(decodeURIComponent(url.password));
4104
+ } else {
4105
+ url.username = encodeURIComponent(decodeURIComponent(value));
4106
+ }
4107
+ }
4108
+
4109
+ for (var i = 0; i < rules.length; i++) {
4110
+ var ins = rules[i];
4111
+
4112
+ if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
4113
+ }
4114
+
4115
+ url.auth = url.password ? url.username +':'+ url.password : url.username;
4116
+
4117
+ url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host
4118
+ ? url.protocol +'//'+ url.host
4119
+ : 'null';
4120
+
4121
+ url.href = url.toString();
4122
+
4123
+ return url;
4124
+ }
4125
+
4126
+ /**
4127
+ * Transform the properties back in to a valid and full URL string.
4128
+ *
4129
+ * @param {Function} stringify Optional query stringify function.
4130
+ * @returns {String} Compiled version of the URL.
4131
+ * @public
4132
+ */
4133
+ function toString(stringify) {
4134
+ if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
4135
+
4136
+ var query
4137
+ , url = this
4138
+ , host = url.host
4139
+ , protocol = url.protocol;
4140
+
4141
+ if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
4142
+
4143
+ var result =
4144
+ protocol +
4145
+ ((url.protocol && url.slashes) || isSpecial(url.protocol) ? '//' : '');
4146
+
4147
+ if (url.username) {
4148
+ result += url.username;
4149
+ if (url.password) result += ':'+ url.password;
4150
+ result += '@';
4151
+ } else if (url.password) {
4152
+ result += ':'+ url.password;
4153
+ result += '@';
4154
+ } else if (
4155
+ url.protocol !== 'file:' &&
4156
+ isSpecial(url.protocol) &&
4157
+ !host &&
4158
+ url.pathname !== '/'
4159
+ ) {
4160
+ //
4161
+ // Add back the empty userinfo, otherwise the original invalid URL
4162
+ // might be transformed into a valid one with `url.pathname` as host.
4163
+ //
4164
+ result += '@';
4165
+ }
4166
+
4167
+ //
4168
+ // Trailing colon is removed from `url.host` when it is parsed. If it still
4169
+ // ends with a colon, then add back the trailing colon that was removed. This
4170
+ // prevents an invalid URL from being transformed into a valid one.
4171
+ //
4172
+ if (host[host.length - 1] === ':' || (port.test(url.hostname) && !url.port)) {
4173
+ host += ':';
4174
+ }
4175
+
4176
+ result += host + url.pathname;
4177
+
4178
+ query = 'object' === typeof url.query ? stringify(url.query) : url.query;
4179
+ if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
4180
+
4181
+ if (url.hash) result += url.hash;
4182
+
4183
+ return result;
4184
+ }
4185
+
4186
+ Url.prototype = { set: set, toString: toString };
4187
+
4188
+ //
4189
+ // Expose the URL parser and some additional properties that might be useful for
4190
+ // others or testing.
4191
+ //
4192
+ Url.extractProtocol = extractProtocol;
4193
+ Url.location = lolcation;
4194
+ Url.trimLeft = trimLeft;
4195
+ Url.qs = qs;
4196
+
4197
+ module.exports = Url;
4198
+
4199
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4200
+ },{"querystringify":55,"requires-port":56}]},{},[1])(1)
4201
+ });