jsforce2 1.11.1 → 5.2.1

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.

Potentially problematic release.


This version of jsforce2 might be problematic. Click here for more details.

Files changed (80) hide show
  1. package/index.js +46 -1
  2. package/package.json +7 -105
  3. package/LICENSE +0 -22
  4. package/README.md +0 -74
  5. package/bin/jsforce +0 -3
  6. package/bower.json +0 -30
  7. package/build/jsforce-api-analytics.js +0 -393
  8. package/build/jsforce-api-analytics.min.js +0 -2
  9. package/build/jsforce-api-analytics.min.js.map +0 -1
  10. package/build/jsforce-api-apex.js +0 -183
  11. package/build/jsforce-api-apex.min.js +0 -2
  12. package/build/jsforce-api-apex.min.js.map +0 -1
  13. package/build/jsforce-api-bulk.js +0 -1054
  14. package/build/jsforce-api-bulk.min.js +0 -2
  15. package/build/jsforce-api-bulk.min.js.map +0 -1
  16. package/build/jsforce-api-chatter.js +0 -320
  17. package/build/jsforce-api-chatter.min.js +0 -2
  18. package/build/jsforce-api-chatter.min.js.map +0 -1
  19. package/build/jsforce-api-metadata.js +0 -3020
  20. package/build/jsforce-api-metadata.min.js +0 -2
  21. package/build/jsforce-api-metadata.min.js.map +0 -1
  22. package/build/jsforce-api-soap.js +0 -403
  23. package/build/jsforce-api-soap.min.js +0 -2
  24. package/build/jsforce-api-soap.min.js.map +0 -1
  25. package/build/jsforce-api-streaming.js +0 -3479
  26. package/build/jsforce-api-streaming.min.js +0 -2
  27. package/build/jsforce-api-streaming.min.js.map +0 -1
  28. package/build/jsforce-api-tooling.js +0 -319
  29. package/build/jsforce-api-tooling.min.js +0 -2
  30. package/build/jsforce-api-tooling.min.js.map +0 -1
  31. package/build/jsforce-core.js +0 -25250
  32. package/build/jsforce-core.min.js +0 -2
  33. package/build/jsforce-core.min.js.map +0 -1
  34. package/build/jsforce.js +0 -31637
  35. package/build/jsforce.min.js +0 -2
  36. package/build/jsforce.min.js.map +0 -1
  37. package/core.js +0 -1
  38. package/lib/VERSION.js +0 -2
  39. package/lib/_required.js +0 -29
  40. package/lib/api/analytics.js +0 -387
  41. package/lib/api/apex.js +0 -177
  42. package/lib/api/bulk.js +0 -862
  43. package/lib/api/chatter.js +0 -314
  44. package/lib/api/index.js +0 -8
  45. package/lib/api/metadata.js +0 -848
  46. package/lib/api/soap.js +0 -397
  47. package/lib/api/streaming-extension.js +0 -136
  48. package/lib/api/streaming.js +0 -270
  49. package/lib/api/tooling.js +0 -313
  50. package/lib/browser/canvas.js +0 -90
  51. package/lib/browser/client.js +0 -241
  52. package/lib/browser/core.js +0 -5
  53. package/lib/browser/jsforce.js +0 -6
  54. package/lib/browser/jsonp.js +0 -52
  55. package/lib/browser/request.js +0 -70
  56. package/lib/cache.js +0 -252
  57. package/lib/cli/cli.js +0 -431
  58. package/lib/cli/repl.js +0 -337
  59. package/lib/connection.js +0 -1881
  60. package/lib/core.js +0 -16
  61. package/lib/csv.js +0 -50
  62. package/lib/date.js +0 -163
  63. package/lib/http-api.js +0 -300
  64. package/lib/jsforce.js +0 -10
  65. package/lib/logger.js +0 -52
  66. package/lib/oauth2.js +0 -206
  67. package/lib/process.js +0 -275
  68. package/lib/promise.js +0 -164
  69. package/lib/query.js +0 -881
  70. package/lib/quick-action.js +0 -90
  71. package/lib/record-stream.js +0 -305
  72. package/lib/record.js +0 -107
  73. package/lib/registry/file-registry.js +0 -48
  74. package/lib/registry/index.js +0 -3
  75. package/lib/registry/registry.js +0 -111
  76. package/lib/require.js +0 -14
  77. package/lib/soap.js +0 -207
  78. package/lib/sobject.js +0 -558
  79. package/lib/soql-builder.js +0 -236
  80. package/lib/transport.js +0 -233
@@ -1,3479 +0,0 @@
1
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.jsforce||(g.jsforce = {}));g=(g.modules||(g.modules = {}));g=(g.api||(g.api = {}));g.Streaming = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
- /**
3
- * Faye Client extensions: https://faye.jcoglan.com/browser/extensions.html
4
- *
5
- * For use with Streaming.prototype.createClient()
6
- **/
7
- var StreamingExtension = {};
8
-
9
- /**
10
- * Constructor for an auth failure detector extension
11
- *
12
- * Based on new feature released with Salesforce Spring '18:
13
- * https://releasenotes.docs.salesforce.com/en-us/spring18/release-notes/rn_messaging_cometd_auth_validation.htm?edition=&impact=
14
- *
15
- * Example triggering error message:
16
- *
17
- * ```
18
- * {
19
- * "ext":{
20
- * "sfdc":{"failureReason":"401::Authentication invalid"},
21
- * "replay":true},
22
- * "advice":{"reconnect":"none"},
23
- * "channel":"/meta/handshake",
24
- * "error":"403::Handshake denied",
25
- * "successful":false
26
- * }
27
- * ```
28
- *
29
- * Example usage:
30
- *
31
- * ```javascript
32
- * const conn = new jsforce.Connection({ … });
33
- *
34
- * const channel = "/event/My_Event__e";
35
- *
36
- * // Exit the Node process when auth fails
37
- * const exitCallback = () => process.exit(1);
38
- * const authFailureExt = new jsforce.StreamingExtension.AuthFailure(exitCallback);
39
- *
40
- * const fayeClient = conn.streaming.createClient([ authFailureExt ]);
41
- *
42
- * const subscription = fayeClient.subscribe(channel, data => {
43
- * console.log('topic received data', data);
44
- * });
45
- *
46
- * subscription.cancel();
47
- * ```
48
- *
49
- * @param {Function} failureCallback - Invoked when authentication becomes invalid
50
- */
51
- StreamingExtension.AuthFailure = function(failureCallback) {
52
- this.incoming = function(message, callback) {
53
- if (
54
- (message.channel === '/meta/connect' ||
55
- message.channel === '/meta/handshake')
56
- && message.advice
57
- && message.advice.reconnect == 'none'
58
- ) {
59
- failureCallback(message);
60
- } else {
61
- callback(message);
62
- }
63
- }
64
- };
65
-
66
- /**
67
- * Constructor for a durable streaming replay extension
68
- *
69
- * Modified from original Salesforce demo source code:
70
- * https://github.com/developerforce/SalesforceDurableStreamingDemo/blob/3d4a56eac956f744ad6c22e6a8141b6feb57abb9/staticresources/cometdReplayExtension.resource
71
- *
72
- * Example usage:
73
- *
74
- * ```javascript
75
- * const conn = new jsforce.Connection({ … });
76
- *
77
- * const channel = "/event/My_Event__e";
78
- * const replayId = -2; // -2 is all retained events
79
- *
80
- * const replayExt = new jsforce.StreamingExtension.Replay(channel, replayId);
81
- *
82
- * const fayeClient = conn.streaming.createClient([ replayExt ]);
83
- *
84
- * const subscription = fayeClient.subscribe(channel, data => {
85
- * console.log('topic received data', data);
86
- * });
87
- *
88
- * subscription.cancel();
89
- * ```
90
- */
91
- StreamingExtension.Replay = function(channel, replayId) {
92
- var REPLAY_FROM_KEY = "replay";
93
-
94
- var _extensionEnabled = replayId != null ? true : false;
95
- var _replay = replayId;
96
- var _channel = channel;
97
-
98
- this.setExtensionEnabled = function(extensionEnabled) {
99
- _extensionEnabled = extensionEnabled;
100
- }
101
-
102
- this.setReplay = function (replay) {
103
- _replay = parseInt(replay, 10);
104
- }
105
-
106
- this.setChannel = function(channel) {
107
- _channel = channel;
108
- }
109
-
110
- this.incoming = function(message, callback) {
111
- if (message.channel === '/meta/handshake') {
112
- if (message.ext && message.ext[REPLAY_FROM_KEY] == true) {
113
- _extensionEnabled = true;
114
- }
115
- } else if (message.channel === _channel && message.data && message.data.event && message.data.event.replayId) {
116
- _replay = message.data.event.replayId;
117
- }
118
- callback(message);
119
- }
120
-
121
- this.outgoing = function(message, callback) {
122
- if (message.channel === '/meta/subscribe' && message.subscription === _channel) {
123
- if (_extensionEnabled) {
124
- if (!message.ext) { message.ext = {}; }
125
-
126
- var replayFromMap = {};
127
- replayFromMap[_channel] = _replay;
128
-
129
- // add "ext : { "replay" : { CHANNEL : REPLAY_VALUE }}" to subscribe message
130
- message.ext[REPLAY_FROM_KEY] = replayFromMap;
131
- }
132
- }
133
- callback(message);
134
- };
135
- };
136
-
137
- module.exports = StreamingExtension;
138
-
139
- },{}],2:[function(require,module,exports){
140
- /**
141
- * @file Manages Streaming APIs
142
- * @author Shinichi Tomita <shinichi.tomita@gmail.com>
143
- */
144
-
145
- 'use strict';
146
-
147
- var events = window.jsforce.require('events'),
148
- inherits = window.jsforce.require('inherits'),
149
- _ = window.jsforce.require('lodash/core'),
150
- Faye = require('faye'),
151
- StreamingExtension = require('./streaming-extension'),
152
- jsforce = window.jsforce.require('./core');
153
-
154
- /**
155
- * Streaming API topic class
156
- *
157
- * @class Streaming~Topic
158
- * @param {Streaming} steaming - Streaming API object
159
- * @param {String} name - Topic name
160
- */
161
- var Topic = function(streaming, name) {
162
- this._streaming = streaming;
163
- this.name = name;
164
- };
165
-
166
- /**
167
- * @typedef {Object} Streaming~StreamingMessage
168
- * @prop {Object} event
169
- * @prop {Object} event.type - Event type
170
- * @prop {Record} sobject - Record information
171
- */
172
- /**
173
- * Subscribe listener to topic
174
- *
175
- * @method Streaming~Topic#subscribe
176
- * @param {Callback.<Streaming~StreamingMesasge>} listener - Streaming message listener
177
- * @returns {Subscription} - Faye subscription object
178
- */
179
- Topic.prototype.subscribe = function(listener) {
180
- return this._streaming.subscribe(this.name, listener);
181
- };
182
-
183
- /**
184
- * Unsubscribe listener from topic
185
- *
186
- * @method Streaming~Topic#unsubscribe
187
- * @param {Callback.<Streaming~StreamingMesasge>} listener - Streaming message listener
188
- * @returns {Streaming~Topic}
189
- */
190
- Topic.prototype.unsubscribe = function(listener) {
191
- this._streaming.unsubscribe(this.name, listener);
192
- return this;
193
- };
194
-
195
- /*--------------------------------------------*/
196
-
197
- /**
198
- * Streaming API Generic Streaming Channel
199
- *
200
- * @class Streaming~Channel
201
- * @param {Streaming} steaming - Streaming API object
202
- * @param {String} name - Channel name (starts with "/u/")
203
- */
204
- var Channel = function(streaming, name) {
205
- this._streaming = streaming;
206
- this._name = name;
207
- };
208
-
209
- /**
210
- * Subscribe to channel
211
- *
212
- * @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
213
- * @returns {Subscription} - Faye subscription object
214
- */
215
- Channel.prototype.subscribe = function(listener) {
216
- return this._streaming.subscribe(this._name, listener);
217
- };
218
-
219
- Channel.prototype.unsubscribe = function(listener) {
220
- this._streaming.unsubscribe(this._name, listener);
221
- return this;
222
- };
223
-
224
- Channel.prototype.push = function(events, callback) {
225
- var isArray = _.isArray(events);
226
- events = isArray ? events : [ events ];
227
- var conn = this._streaming._conn;
228
- if (!this._id) {
229
- this._id = conn.sobject('StreamingChannel').findOne({ Name: this._name }, 'Id')
230
- .then(function(rec) { return rec.Id });
231
- }
232
- return this._id.then(function(id) {
233
- var channelUrl = '/sobjects/StreamingChannel/' + id + '/push';
234
- return conn.requestPost(channelUrl, { pushEvents: events });
235
- }).then(function(rets) {
236
- return isArray ? rets : rets[0];
237
- }).thenCall(callback);
238
- };
239
-
240
- /*--------------------------------------------*/
241
-
242
- /**
243
- * Streaming API class
244
- *
245
- * @class
246
- * @extends events.EventEmitter
247
- * @param {Connection} conn - Connection object
248
- */
249
- var Streaming = function(conn) {
250
- this._conn = conn;
251
- };
252
-
253
- inherits(Streaming, events.EventEmitter);
254
-
255
- /** @private **/
256
- Streaming.prototype._createClient = function(forChannelName, extensions) {
257
- // forChannelName is advisory, for an API workaround. It does not restrict or select the channel.
258
- var needsReplayFix = typeof forChannelName === 'string' && forChannelName.indexOf('/u/') === 0;
259
- var endpointUrl = [
260
- this._conn.instanceUrl,
261
- // special endpoint "/cometd/replay/xx.x" is only available in 36.0.
262
- // See https://releasenotes.docs.salesforce.com/en-us/summer16/release-notes/rn_api_streaming_classic_replay.htm
263
- "cometd" + (needsReplayFix === true && this._conn.version === "36.0" ? "/replay" : ""),
264
- this._conn.version
265
- ].join('/');
266
- var fayeClient = new Faye.Client(endpointUrl, {});
267
- fayeClient.setHeader('Authorization', 'OAuth '+this._conn.accessToken);
268
- if (extensions instanceof Array) {
269
- extensions.forEach(function(extension) {
270
- fayeClient.addExtension(extension);
271
- });
272
- }
273
- if (fayeClient._dispatcher.getConnectionTypes().indexOf('callback-polling') === -1) {
274
- // prevent streaming API server error
275
- fayeClient._dispatcher.selectTransport('long-polling');
276
- fayeClient._dispatcher._transport.batching = false;
277
- }
278
- return fayeClient;
279
- };
280
-
281
- /** @private **/
282
- Streaming.prototype._getFayeClient = function(channelName) {
283
- var isGeneric = channelName.indexOf('/u/') === 0;
284
- var clientType = isGeneric ? 'generic' : 'pushTopic';
285
- if (!this._fayeClients || !this._fayeClients[clientType]) {
286
- this._fayeClients = this._fayeClients || {};
287
- this._fayeClients[clientType] = this._createClient(channelName);
288
- }
289
- return this._fayeClients[clientType];
290
- };
291
-
292
-
293
- /**
294
- * Get named topic
295
- *
296
- * @param {String} name - Topic name
297
- * @returns {Streaming~Topic}
298
- */
299
- Streaming.prototype.topic = function(name) {
300
- this._topics = this._topics || {};
301
- var topic = this._topics[name] =
302
- this._topics[name] || new Topic(this, name);
303
- return topic;
304
- };
305
-
306
- /**
307
- * Get Channel for Id
308
- * @param {String} channelId - Id of StreamingChannel object
309
- * @returns {Streaming~Channel}
310
- */
311
- Streaming.prototype.channel = function(channelId) {
312
- return new Channel(this, channelId);
313
- };
314
-
315
- /**
316
- * Subscribe topic/channel
317
- *
318
- * @param {String} name - Topic name
319
- * @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
320
- * @returns {Subscription} - Faye subscription object
321
- */
322
- Streaming.prototype.subscribe = function(name, listener) {
323
- var channelName = name.indexOf('/') === 0 ? name : '/topic/' + name;
324
- var fayeClient = this._getFayeClient(channelName);
325
- return fayeClient.subscribe(channelName, listener);
326
- };
327
-
328
- /**
329
- * Unsubscribe topic
330
- *
331
- * @param {String} name - Topic name
332
- * @param {Callback.<Streaming~StreamingMessage>} listener - Streaming message listener
333
- * @returns {Streaming}
334
- */
335
- Streaming.prototype.unsubscribe = function(name, listener) {
336
- var channelName = name.indexOf('/') === 0 ? name : '/topic/' + name;
337
- var fayeClient = this._getFayeClient(channelName);
338
- fayeClient.unsubscribe(channelName, listener);
339
- return this;
340
- };
341
-
342
-
343
- /**
344
- * Create a Streaming client, optionally with extensions
345
- *
346
- * See Faye docs for implementation details: https://faye.jcoglan.com/browser/extensions.html
347
- *
348
- * Example usage:
349
- *
350
- * ```javascript
351
- * // Establish a Salesforce connection. (Details elided)
352
- * const conn = new jsforce.Connection({ … });
353
- *
354
- * const fayeClient = conn.streaming.createClient();
355
- *
356
- * const subscription = fayeClient.subscribe(channel, data => {
357
- * console.log('topic received data', data);
358
- * });
359
- *
360
- * subscription.cancel();
361
- * ```
362
- *
363
- * Example with extensions, using Replay & Auth Failure extensions in a server-side Node.js app:
364
- *
365
- * ```javascript
366
- * // Establish a Salesforce connection. (Details elided)
367
- * const conn = new jsforce.Connection({ … });
368
- *
369
- * const channel = "/event/My_Event__e";
370
- * const replayId = -2; // -2 is all retained events
371
- *
372
- * const exitCallback = () => process.exit(1);
373
- * const authFailureExt = new jsforce.StreamingExtension.AuthFailure(exitCallback);
374
- *
375
- * const replayExt = new jsforce.StreamingExtension.Replay(channel, replayId);
376
- *
377
- * const fayeClient = conn.streaming.createClient([
378
- * authFailureExt,
379
- * replayExt
380
- * ]);
381
- *
382
- * const subscription = fayeClient.subscribe(channel, data => {
383
- * console.log('topic received data', data);
384
- * });
385
- *
386
- * subscription.cancel();
387
- * ```
388
- *
389
- * @param {Array} Extensions - Optional, extensions to apply to the Faye client
390
- * @returns {FayeClient} - Faye client object
391
- */
392
- Streaming.prototype.createClient = function(extensions) {
393
- return this._createClient(null, extensions);
394
- };
395
-
396
- /*--------------------------------------------*/
397
- /*
398
- * Register hook in connection instantiation for dynamically adding this API module features
399
- */
400
- jsforce.on('connection:new', function(conn) {
401
- conn.streaming = new Streaming(conn);
402
- });
403
-
404
- /*
405
- *
406
- */
407
- jsforce.StreamingExtension = StreamingExtension;
408
-
409
- module.exports = Streaming;
410
-
411
- },{"./streaming-extension":1,"faye":5}],3:[function(require,module,exports){
412
- "use strict";
413
-
414
- // rawAsap provides everything we need except exception management.
415
- var rawAsap = require("./raw");
416
- // RawTasks are recycled to reduce GC churn.
417
- var freeTasks = [];
418
- // We queue errors to ensure they are thrown in right order (FIFO).
419
- // Array-as-queue is good enough here, since we are just dealing with exceptions.
420
- var pendingErrors = [];
421
- var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);
422
-
423
- function throwFirstError() {
424
- if (pendingErrors.length) {
425
- throw pendingErrors.shift();
426
- }
427
- }
428
-
429
- /**
430
- * Calls a task as soon as possible after returning, in its own event, with priority
431
- * over other events like animation, reflow, and repaint. An error thrown from an
432
- * event will not interrupt, nor even substantially slow down the processing of
433
- * other events, but will be rather postponed to a lower priority event.
434
- * @param {{call}} task A callable object, typically a function that takes no
435
- * arguments.
436
- */
437
- module.exports = asap;
438
- function asap(task) {
439
- var rawTask;
440
- if (freeTasks.length) {
441
- rawTask = freeTasks.pop();
442
- } else {
443
- rawTask = new RawTask();
444
- }
445
- rawTask.task = task;
446
- rawAsap(rawTask);
447
- }
448
-
449
- // We wrap tasks with recyclable task objects. A task object implements
450
- // `call`, just like a function.
451
- function RawTask() {
452
- this.task = null;
453
- }
454
-
455
- // The sole purpose of wrapping the task is to catch the exception and recycle
456
- // the task object after its single use.
457
- RawTask.prototype.call = function () {
458
- try {
459
- this.task.call();
460
- } catch (error) {
461
- if (asap.onerror) {
462
- // This hook exists purely for testing purposes.
463
- // Its name will be periodically randomized to break any code that
464
- // depends on its existence.
465
- asap.onerror(error);
466
- } else {
467
- // In a web browser, exceptions are not fatal. However, to avoid
468
- // slowing down the queue of pending tasks, we rethrow the error in a
469
- // lower priority turn.
470
- pendingErrors.push(error);
471
- requestErrorThrow();
472
- }
473
- } finally {
474
- this.task = null;
475
- freeTasks[freeTasks.length] = this;
476
- }
477
- };
478
-
479
- },{"./raw":4}],4:[function(require,module,exports){
480
- (function (global){
481
- "use strict";
482
-
483
- // Use the fastest means possible to execute a task in its own turn, with
484
- // priority over other events including IO, animation, reflow, and redraw
485
- // events in browsers.
486
- //
487
- // An exception thrown by a task will permanently interrupt the processing of
488
- // subsequent tasks. The higher level `asap` function ensures that if an
489
- // exception is thrown by a task, that the task queue will continue flushing as
490
- // soon as possible, but if you use `rawAsap` directly, you are responsible to
491
- // either ensure that no exceptions are thrown from your task, or to manually
492
- // call `rawAsap.requestFlush` if an exception is thrown.
493
- module.exports = rawAsap;
494
- function rawAsap(task) {
495
- if (!queue.length) {
496
- requestFlush();
497
- flushing = true;
498
- }
499
- // Equivalent to push, but avoids a function call.
500
- queue[queue.length] = task;
501
- }
502
-
503
- var queue = [];
504
- // Once a flush has been requested, no further calls to `requestFlush` are
505
- // necessary until the next `flush` completes.
506
- var flushing = false;
507
- // `requestFlush` is an implementation-specific method that attempts to kick
508
- // off a `flush` event as quickly as possible. `flush` will attempt to exhaust
509
- // the event queue before yielding to the browser's own event loop.
510
- var requestFlush;
511
- // The position of the next task to execute in the task queue. This is
512
- // preserved between calls to `flush` so that it can be resumed if
513
- // a task throws an exception.
514
- var index = 0;
515
- // If a task schedules additional tasks recursively, the task queue can grow
516
- // unbounded. To prevent memory exhaustion, the task queue will periodically
517
- // truncate already-completed tasks.
518
- var capacity = 1024;
519
-
520
- // The flush function processes all tasks that have been scheduled with
521
- // `rawAsap` unless and until one of those tasks throws an exception.
522
- // If a task throws an exception, `flush` ensures that its state will remain
523
- // consistent and will resume where it left off when called again.
524
- // However, `flush` does not make any arrangements to be called again if an
525
- // exception is thrown.
526
- function flush() {
527
- while (index < queue.length) {
528
- var currentIndex = index;
529
- // Advance the index before calling the task. This ensures that we will
530
- // begin flushing on the next task the task throws an error.
531
- index = index + 1;
532
- queue[currentIndex].call();
533
- // Prevent leaking memory for long chains of recursive calls to `asap`.
534
- // If we call `asap` within tasks scheduled by `asap`, the queue will
535
- // grow, but to avoid an O(n) walk for every task we execute, we don't
536
- // shift tasks off the queue after they have been executed.
537
- // Instead, we periodically shift 1024 tasks off the queue.
538
- if (index > capacity) {
539
- // Manually shift all values starting at the index back to the
540
- // beginning of the queue.
541
- for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
542
- queue[scan] = queue[scan + index];
543
- }
544
- queue.length -= index;
545
- index = 0;
546
- }
547
- }
548
- queue.length = 0;
549
- index = 0;
550
- flushing = false;
551
- }
552
-
553
- // `requestFlush` is implemented using a strategy based on data collected from
554
- // every available SauceLabs Selenium web driver worker at time of writing.
555
- // https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
556
-
557
- // Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
558
- // have WebKitMutationObserver but not un-prefixed MutationObserver.
559
- // Must use `global` or `self` instead of `window` to work in both frames and web
560
- // workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
561
-
562
- /* globals self */
563
- var scope = typeof global !== "undefined" ? global : self;
564
- var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
565
-
566
- // MutationObservers are desirable because they have high priority and work
567
- // reliably everywhere they are implemented.
568
- // They are implemented in all modern browsers.
569
- //
570
- // - Android 4-4.3
571
- // - Chrome 26-34
572
- // - Firefox 14-29
573
- // - Internet Explorer 11
574
- // - iPad Safari 6-7.1
575
- // - iPhone Safari 7-7.1
576
- // - Safari 6-7
577
- if (typeof BrowserMutationObserver === "function") {
578
- requestFlush = makeRequestCallFromMutationObserver(flush);
579
-
580
- // MessageChannels are desirable because they give direct access to the HTML
581
- // task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
582
- // 11-12, and in web workers in many engines.
583
- // Although message channels yield to any queued rendering and IO tasks, they
584
- // would be better than imposing the 4ms delay of timers.
585
- // However, they do not work reliably in Internet Explorer or Safari.
586
-
587
- // Internet Explorer 10 is the only browser that has setImmediate but does
588
- // not have MutationObservers.
589
- // Although setImmediate yields to the browser's renderer, it would be
590
- // preferrable to falling back to setTimeout since it does not have
591
- // the minimum 4ms penalty.
592
- // Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
593
- // Desktop to a lesser extent) that renders both setImmediate and
594
- // MessageChannel useless for the purposes of ASAP.
595
- // https://github.com/kriskowal/q/issues/396
596
-
597
- // Timers are implemented universally.
598
- // We fall back to timers in workers in most engines, and in foreground
599
- // contexts in the following browsers.
600
- // However, note that even this simple case requires nuances to operate in a
601
- // broad spectrum of browsers.
602
- //
603
- // - Firefox 3-13
604
- // - Internet Explorer 6-9
605
- // - iPad Safari 4.3
606
- // - Lynx 2.8.7
607
- } else {
608
- requestFlush = makeRequestCallFromTimer(flush);
609
- }
610
-
611
- // `requestFlush` requests that the high priority event queue be flushed as
612
- // soon as possible.
613
- // This is useful to prevent an error thrown in a task from stalling the event
614
- // queue if the exception handled by Node.js’s
615
- // `process.on("uncaughtException")` or by a domain.
616
- rawAsap.requestFlush = requestFlush;
617
-
618
- // To request a high priority event, we induce a mutation observer by toggling
619
- // the text of a text node between "1" and "-1".
620
- function makeRequestCallFromMutationObserver(callback) {
621
- var toggle = 1;
622
- var observer = new BrowserMutationObserver(callback);
623
- var node = document.createTextNode("");
624
- observer.observe(node, {characterData: true});
625
- return function requestCall() {
626
- toggle = -toggle;
627
- node.data = toggle;
628
- };
629
- }
630
-
631
- // The message channel technique was discovered by Malte Ubl and was the
632
- // original foundation for this library.
633
- // http://www.nonblocking.io/2011/06/windownexttick.html
634
-
635
- // Safari 6.0.5 (at least) intermittently fails to create message ports on a
636
- // page's first load. Thankfully, this version of Safari supports
637
- // MutationObservers, so we don't need to fall back in that case.
638
-
639
- // function makeRequestCallFromMessageChannel(callback) {
640
- // var channel = new MessageChannel();
641
- // channel.port1.onmessage = callback;
642
- // return function requestCall() {
643
- // channel.port2.postMessage(0);
644
- // };
645
- // }
646
-
647
- // For reasons explained above, we are also unable to use `setImmediate`
648
- // under any circumstances.
649
- // Even if we were, there is another bug in Internet Explorer 10.
650
- // It is not sufficient to assign `setImmediate` to `requestFlush` because
651
- // `setImmediate` must be called *by name* and therefore must be wrapped in a
652
- // closure.
653
- // Never forget.
654
-
655
- // function makeRequestCallFromSetImmediate(callback) {
656
- // return function requestCall() {
657
- // setImmediate(callback);
658
- // };
659
- // }
660
-
661
- // Safari 6.0 has a problem where timers will get lost while the user is
662
- // scrolling. This problem does not impact ASAP because Safari 6.0 supports
663
- // mutation observers, so that implementation is used instead.
664
- // However, if we ever elect to use timers in Safari, the prevalent work-around
665
- // is to add a scroll event listener that calls for a flush.
666
-
667
- // `setTimeout` does not call the passed callback if the delay is less than
668
- // approximately 7 in web workers in Firefox 8 through 18, and sometimes not
669
- // even then.
670
-
671
- function makeRequestCallFromTimer(callback) {
672
- return function requestCall() {
673
- // We dispatch a timeout with a specified delay of 0 for engines that
674
- // can reliably accommodate that request. This will usually be snapped
675
- // to a 4 milisecond delay, but once we're flushing, there's no delay
676
- // between events.
677
- var timeoutHandle = setTimeout(handleTimer, 0);
678
- // However, since this timer gets frequently dropped in Firefox
679
- // workers, we enlist an interval handle that will try to fire
680
- // an event 20 times per second until it succeeds.
681
- var intervalHandle = setInterval(handleTimer, 50);
682
-
683
- function handleTimer() {
684
- // Whichever timer succeeds will cancel both timers and
685
- // execute the callback.
686
- clearTimeout(timeoutHandle);
687
- clearInterval(intervalHandle);
688
- callback();
689
- }
690
- };
691
- }
692
-
693
- // This is for `asap.js` only.
694
- // Its name will be periodically randomized to break any code that depends on
695
- // its existence.
696
- rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
697
-
698
- // ASAP was originally a nextTick shim included in Q. This was factored out
699
- // into this ASAP package. It was later adapted to RSVP which made further
700
- // amendments. These decisions, particularly to marginalize MessageChannel and
701
- // to capture the MutationObserver implementation in a closure, were integrated
702
- // back into ASAP proper.
703
- // https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
704
-
705
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
706
-
707
- },{}],5:[function(require,module,exports){
708
- 'use strict';
709
-
710
- var constants = require('./util/constants'),
711
- Logging = require('./mixins/logging');
712
-
713
- var Faye = {
714
- VERSION: constants.VERSION,
715
-
716
- Client: require('./protocol/client'),
717
- Scheduler: require('./protocol/scheduler')
718
- };
719
-
720
- Logging.wrapper = Faye;
721
-
722
- module.exports = Faye;
723
-
724
- },{"./mixins/logging":7,"./protocol/client":11,"./protocol/scheduler":17,"./util/constants":29}],6:[function(require,module,exports){
725
- (function (global){
726
- 'use strict';
727
-
728
- var Promise = require('../util/promise');
729
-
730
- module.exports = {
731
- then: function(callback, errback) {
732
- var self = this;
733
- if (!this._promise)
734
- this._promise = new Promise(function(resolve, reject) {
735
- self._resolve = resolve;
736
- self._reject = reject;
737
- });
738
-
739
- if (arguments.length === 0)
740
- return this._promise;
741
- else
742
- return this._promise.then(callback, errback);
743
- },
744
-
745
- callback: function(callback, context) {
746
- return this.then(function(value) { callback.call(context, value) });
747
- },
748
-
749
- errback: function(callback, context) {
750
- return this.then(null, function(reason) { callback.call(context, reason) });
751
- },
752
-
753
- timeout: function(seconds, message) {
754
- this.then();
755
- var self = this;
756
- this._timer = global.setTimeout(function() {
757
- self._reject(message);
758
- }, seconds * 1000);
759
- },
760
-
761
- setDeferredStatus: function(status, value) {
762
- if (this._timer) global.clearTimeout(this._timer);
763
-
764
- this.then();
765
-
766
- if (status === 'succeeded')
767
- this._resolve(value);
768
- else if (status === 'failed')
769
- this._reject(value);
770
- else
771
- delete this._promise;
772
- }
773
- };
774
-
775
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
776
-
777
- },{"../util/promise":34}],7:[function(require,module,exports){
778
- 'use strict';
779
-
780
- var toJSON = require('../util/to_json');
781
-
782
- var Logging = {
783
- LOG_LEVELS: {
784
- fatal: 4,
785
- error: 3,
786
- warn: 2,
787
- info: 1,
788
- debug: 0
789
- },
790
-
791
- writeLog: function(messageArgs, level) {
792
- var logger = Logging.logger || (Logging.wrapper || Logging).logger;
793
- if (!logger) return;
794
-
795
- var args = Array.prototype.slice.apply(messageArgs),
796
- banner = '[Faye',
797
- klass = this.className,
798
-
799
- message = args.shift().replace(/\?/g, function() {
800
- try {
801
- return toJSON(args.shift());
802
- } catch (error) {
803
- return '[Object]';
804
- }
805
- });
806
-
807
- if (klass) banner += '.' + klass;
808
- banner += '] ';
809
-
810
- if (typeof logger[level] === 'function')
811
- logger[level](banner + message);
812
- else if (typeof logger === 'function')
813
- logger(banner + message);
814
- }
815
- };
816
-
817
- for (var key in Logging.LOG_LEVELS)
818
- (function(level) {
819
- Logging[level] = function() {
820
- this.writeLog(arguments, level);
821
- };
822
- })(key);
823
-
824
- module.exports = Logging;
825
-
826
- },{"../util/to_json":36}],8:[function(require,module,exports){
827
- 'use strict';
828
-
829
- var extend = require('../util/extend'),
830
- EventEmitter = require('../util/event_emitter');
831
-
832
- var Publisher = {
833
- countListeners: function(eventType) {
834
- return this.listeners(eventType).length;
835
- },
836
-
837
- bind: function(eventType, listener, context) {
838
- var slice = Array.prototype.slice,
839
- handler = function() { listener.apply(context, slice.call(arguments)) };
840
-
841
- this._listeners = this._listeners || [];
842
- this._listeners.push([eventType, listener, context, handler]);
843
- return this.on(eventType, handler);
844
- },
845
-
846
- unbind: function(eventType, listener, context) {
847
- this._listeners = this._listeners || [];
848
- var n = this._listeners.length, tuple;
849
-
850
- while (n--) {
851
- tuple = this._listeners[n];
852
- if (tuple[0] !== eventType) continue;
853
- if (listener && (tuple[1] !== listener || tuple[2] !== context)) continue;
854
- this._listeners.splice(n, 1);
855
- this.removeListener(eventType, tuple[3]);
856
- }
857
- }
858
- };
859
-
860
- extend(Publisher, EventEmitter.prototype);
861
- Publisher.trigger = Publisher.emit;
862
-
863
- module.exports = Publisher;
864
-
865
- },{"../util/event_emitter":32,"../util/extend":33}],9:[function(require,module,exports){
866
- (function (global){
867
- 'use strict';
868
-
869
- module.exports = {
870
- addTimeout: function(name, delay, callback, context) {
871
- this._timeouts = this._timeouts || {};
872
- if (this._timeouts.hasOwnProperty(name)) return;
873
- var self = this;
874
- this._timeouts[name] = global.setTimeout(function() {
875
- delete self._timeouts[name];
876
- callback.call(context);
877
- }, 1000 * delay);
878
- },
879
-
880
- removeTimeout: function(name) {
881
- this._timeouts = this._timeouts || {};
882
- var timeout = this._timeouts[name];
883
- if (!timeout) return;
884
- global.clearTimeout(timeout);
885
- delete this._timeouts[name];
886
- },
887
-
888
- removeAllTimeouts: function() {
889
- this._timeouts = this._timeouts || {};
890
- for (var name in this._timeouts) this.removeTimeout(name);
891
- }
892
- };
893
-
894
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
895
-
896
- },{}],10:[function(require,module,exports){
897
- 'use strict';
898
-
899
- var Class = require('../util/class'),
900
- extend = require('../util/extend'),
901
- Publisher = require('../mixins/publisher'),
902
- Grammar = require('./grammar');
903
-
904
- var Channel = Class({
905
- initialize: function(name) {
906
- this.id = this.name = name;
907
- },
908
-
909
- push: function(message) {
910
- this.trigger('message', message);
911
- },
912
-
913
- isUnused: function() {
914
- return this.countListeners('message') === 0;
915
- }
916
- });
917
-
918
- extend(Channel.prototype, Publisher);
919
-
920
- extend(Channel, {
921
- HANDSHAKE: '/meta/handshake',
922
- CONNECT: '/meta/connect',
923
- SUBSCRIBE: '/meta/subscribe',
924
- UNSUBSCRIBE: '/meta/unsubscribe',
925
- DISCONNECT: '/meta/disconnect',
926
-
927
- META: 'meta',
928
- SERVICE: 'service',
929
-
930
- expand: function(name) {
931
- var segments = this.parse(name),
932
- channels = ['/**', name];
933
-
934
- var copy = segments.slice();
935
- copy[copy.length - 1] = '*';
936
- channels.push(this.unparse(copy));
937
-
938
- for (var i = 1, n = segments.length; i < n; i++) {
939
- copy = segments.slice(0, i);
940
- copy.push('**');
941
- channels.push(this.unparse(copy));
942
- }
943
-
944
- return channels;
945
- },
946
-
947
- isValid: function(name) {
948
- return Grammar.CHANNEL_NAME.test(name) ||
949
- Grammar.CHANNEL_PATTERN.test(name);
950
- },
951
-
952
- parse: function(name) {
953
- if (!this.isValid(name)) return null;
954
- return name.split('/').slice(1);
955
- },
956
-
957
- unparse: function(segments) {
958
- return '/' + segments.join('/');
959
- },
960
-
961
- isMeta: function(name) {
962
- var segments = this.parse(name);
963
- return segments ? (segments[0] === this.META) : null;
964
- },
965
-
966
- isService: function(name) {
967
- var segments = this.parse(name);
968
- return segments ? (segments[0] === this.SERVICE) : null;
969
- },
970
-
971
- isSubscribable: function(name) {
972
- if (!this.isValid(name)) return null;
973
- return !this.isMeta(name) && !this.isService(name);
974
- },
975
-
976
- Set: Class({
977
- initialize: function() {
978
- this._channels = {};
979
- },
980
-
981
- getKeys: function() {
982
- var keys = [];
983
- for (var key in this._channels) keys.push(key);
984
- return keys;
985
- },
986
-
987
- remove: function(name) {
988
- delete this._channels[name];
989
- },
990
-
991
- hasSubscription: function(name) {
992
- return this._channels.hasOwnProperty(name);
993
- },
994
-
995
- subscribe: function(names, subscription) {
996
- var name;
997
- for (var i = 0, n = names.length; i < n; i++) {
998
- name = names[i];
999
- var channel = this._channels[name] = this._channels[name] || new Channel(name);
1000
- channel.bind('message', subscription);
1001
- }
1002
- },
1003
-
1004
- unsubscribe: function(name, subscription) {
1005
- var channel = this._channels[name];
1006
- if (!channel) return false;
1007
- channel.unbind('message', subscription);
1008
-
1009
- if (channel.isUnused()) {
1010
- this.remove(name);
1011
- return true;
1012
- } else {
1013
- return false;
1014
- }
1015
- },
1016
-
1017
- distributeMessage: function(message) {
1018
- var channels = Channel.expand(message.channel);
1019
-
1020
- for (var i = 0, n = channels.length; i < n; i++) {
1021
- var channel = this._channels[channels[i]];
1022
- if (channel) channel.trigger('message', message);
1023
- }
1024
- }
1025
- })
1026
- });
1027
-
1028
- module.exports = Channel;
1029
-
1030
- },{"../mixins/publisher":8,"../util/class":28,"../util/extend":33,"./grammar":15}],11:[function(require,module,exports){
1031
- (function (global){
1032
- 'use strict';
1033
-
1034
- var asap = require('asap'),
1035
- Class = require('../util/class'),
1036
- Promise = require('../util/promise'),
1037
- URI = require('../util/uri'),
1038
- array = require('../util/array'),
1039
- browser = require('../util/browser'),
1040
- constants = require('../util/constants'),
1041
- extend = require('../util/extend'),
1042
- validateOptions = require('../util/validate_options'),
1043
- Deferrable = require('../mixins/deferrable'),
1044
- Logging = require('../mixins/logging'),
1045
- Publisher = require('../mixins/publisher'),
1046
- Channel = require('./channel'),
1047
- Dispatcher = require('./dispatcher'),
1048
- Error = require('./error'),
1049
- Extensible = require('./extensible'),
1050
- Publication = require('./publication'),
1051
- Subscription = require('./subscription');
1052
-
1053
- var Client = Class({ className: 'Client',
1054
- UNCONNECTED: 1,
1055
- CONNECTING: 2,
1056
- CONNECTED: 3,
1057
- DISCONNECTED: 4,
1058
-
1059
- HANDSHAKE: 'handshake',
1060
- RETRY: 'retry',
1061
- NONE: 'none',
1062
-
1063
- CONNECTION_TIMEOUT: 60,
1064
-
1065
- DEFAULT_ENDPOINT: '/bayeux',
1066
- INTERVAL: 0,
1067
-
1068
- initialize: function(endpoint, options) {
1069
- this.info('New client created for ?', endpoint);
1070
- options = options || {};
1071
-
1072
- validateOptions(options, ['interval', 'timeout', 'endpoints', 'proxy', 'retry', 'scheduler', 'websocketExtensions', 'tls', 'ca']);
1073
-
1074
- this._channels = new Channel.Set();
1075
- this._dispatcher = Dispatcher.create(this, endpoint || this.DEFAULT_ENDPOINT, options);
1076
-
1077
- this._messageId = 0;
1078
- this._state = this.UNCONNECTED;
1079
-
1080
- this._responseCallbacks = {};
1081
-
1082
- this._advice = {
1083
- reconnect: this.RETRY,
1084
- interval: 1000 * (options.interval || this.INTERVAL),
1085
- timeout: 1000 * (options.timeout || this.CONNECTION_TIMEOUT)
1086
- };
1087
- this._dispatcher.timeout = this._advice.timeout / 1000;
1088
-
1089
- this._dispatcher.bind('message', this._receiveMessage, this);
1090
-
1091
- if (browser.Event && global.onbeforeunload !== undefined)
1092
- browser.Event.on(global, 'beforeunload', function() {
1093
- if (array.indexOf(this._dispatcher._disabled, 'autodisconnect') < 0)
1094
- this.disconnect();
1095
- }, this);
1096
- },
1097
-
1098
- addWebsocketExtension: function(extension) {
1099
- return this._dispatcher.addWebsocketExtension(extension);
1100
- },
1101
-
1102
- disable: function(feature) {
1103
- return this._dispatcher.disable(feature);
1104
- },
1105
-
1106
- setHeader: function(name, value) {
1107
- return this._dispatcher.setHeader(name, value);
1108
- },
1109
-
1110
- // Request
1111
- // MUST include: * channel
1112
- // * version
1113
- // * supportedConnectionTypes
1114
- // MAY include: * minimumVersion
1115
- // * ext
1116
- // * id
1117
- //
1118
- // Success Response Failed Response
1119
- // MUST include: * channel MUST include: * channel
1120
- // * version * successful
1121
- // * supportedConnectionTypes * error
1122
- // * clientId MAY include: * supportedConnectionTypes
1123
- // * successful * advice
1124
- // MAY include: * minimumVersion * version
1125
- // * advice * minimumVersion
1126
- // * ext * ext
1127
- // * id * id
1128
- // * authSuccessful
1129
- handshake: function(callback, context) {
1130
- if (this._advice.reconnect === this.NONE) return;
1131
- if (this._state !== this.UNCONNECTED) return;
1132
-
1133
- this._state = this.CONNECTING;
1134
- var self = this;
1135
-
1136
- this.info('Initiating handshake with ?', URI.stringify(this._dispatcher.endpoint));
1137
- this._dispatcher.selectTransport(constants.MANDATORY_CONNECTION_TYPES);
1138
-
1139
- this._sendMessage({
1140
- channel: Channel.HANDSHAKE,
1141
- version: constants.BAYEUX_VERSION,
1142
- supportedConnectionTypes: this._dispatcher.getConnectionTypes()
1143
-
1144
- }, {}, function(response) {
1145
-
1146
- if (response.successful) {
1147
- this._state = this.CONNECTED;
1148
- this._dispatcher.clientId = response.clientId;
1149
-
1150
- this._dispatcher.selectTransport(response.supportedConnectionTypes);
1151
-
1152
- this.info('Handshake successful: ?', this._dispatcher.clientId);
1153
-
1154
- this.subscribe(this._channels.getKeys(), true);
1155
- if (callback) asap(function() { callback.call(context) });
1156
-
1157
- } else {
1158
- this.info('Handshake unsuccessful');
1159
- global.setTimeout(function() { self.handshake(callback, context) }, this._dispatcher.retry * 1000);
1160
- this._state = this.UNCONNECTED;
1161
- }
1162
- }, this);
1163
- },
1164
-
1165
- // Request Response
1166
- // MUST include: * channel MUST include: * channel
1167
- // * clientId * successful
1168
- // * connectionType * clientId
1169
- // MAY include: * ext MAY include: * error
1170
- // * id * advice
1171
- // * ext
1172
- // * id
1173
- // * timestamp
1174
- connect: function(callback, context) {
1175
- if (this._advice.reconnect === this.NONE) return;
1176
- if (this._state === this.DISCONNECTED) return;
1177
-
1178
- if (this._state === this.UNCONNECTED)
1179
- return this.handshake(function() { this.connect(callback, context) }, this);
1180
-
1181
- this.callback(callback, context);
1182
- if (this._state !== this.CONNECTED) return;
1183
-
1184
- this.info('Calling deferred actions for ?', this._dispatcher.clientId);
1185
- this.setDeferredStatus('succeeded');
1186
- this.setDeferredStatus('unknown');
1187
-
1188
- if (this._connectRequest) return;
1189
- this._connectRequest = true;
1190
-
1191
- this.info('Initiating connection for ?', this._dispatcher.clientId);
1192
-
1193
- this._sendMessage({
1194
- channel: Channel.CONNECT,
1195
- clientId: this._dispatcher.clientId,
1196
- connectionType: this._dispatcher.connectionType
1197
-
1198
- }, {}, this._cycleConnection, this);
1199
- },
1200
-
1201
- // Request Response
1202
- // MUST include: * channel MUST include: * channel
1203
- // * clientId * successful
1204
- // MAY include: * ext * clientId
1205
- // * id MAY include: * error
1206
- // * ext
1207
- // * id
1208
- disconnect: function() {
1209
- if (this._state !== this.CONNECTED) return;
1210
- this._state = this.DISCONNECTED;
1211
-
1212
- this.info('Disconnecting ?', this._dispatcher.clientId);
1213
- var promise = new Publication();
1214
-
1215
- this._sendMessage({
1216
- channel: Channel.DISCONNECT,
1217
- clientId: this._dispatcher.clientId
1218
-
1219
- }, {}, function(response) {
1220
- if (response.successful) {
1221
- this._dispatcher.close();
1222
- promise.setDeferredStatus('succeeded');
1223
- } else {
1224
- promise.setDeferredStatus('failed', Error.parse(response.error));
1225
- }
1226
- }, this);
1227
-
1228
- this.info('Clearing channel listeners for ?', this._dispatcher.clientId);
1229
- this._channels = new Channel.Set();
1230
-
1231
- return promise;
1232
- },
1233
-
1234
- // Request Response
1235
- // MUST include: * channel MUST include: * channel
1236
- // * clientId * successful
1237
- // * subscription * clientId
1238
- // MAY include: * ext * subscription
1239
- // * id MAY include: * error
1240
- // * advice
1241
- // * ext
1242
- // * id
1243
- // * timestamp
1244
- subscribe: function(channel, callback, context) {
1245
- if (channel instanceof Array)
1246
- return array.map(channel, function(c) {
1247
- return this.subscribe(c, callback, context);
1248
- }, this);
1249
-
1250
- var subscription = new Subscription(this, channel, callback, context),
1251
- force = (callback === true),
1252
- hasSubscribe = this._channels.hasSubscription(channel);
1253
-
1254
- if (hasSubscribe && !force) {
1255
- this._channels.subscribe([channel], subscription);
1256
- subscription.setDeferredStatus('succeeded');
1257
- return subscription;
1258
- }
1259
-
1260
- this.connect(function() {
1261
- this.info('Client ? attempting to subscribe to ?', this._dispatcher.clientId, channel);
1262
- if (!force) this._channels.subscribe([channel], subscription);
1263
-
1264
- this._sendMessage({
1265
- channel: Channel.SUBSCRIBE,
1266
- clientId: this._dispatcher.clientId,
1267
- subscription: channel
1268
-
1269
- }, {}, function(response) {
1270
- if (!response.successful) {
1271
- subscription.setDeferredStatus('failed', Error.parse(response.error));
1272
- return this._channels.unsubscribe(channel, subscription);
1273
- }
1274
-
1275
- var channels = [].concat(response.subscription);
1276
- this.info('Subscription acknowledged for ? to ?', this._dispatcher.clientId, channels);
1277
- subscription.setDeferredStatus('succeeded');
1278
- }, this);
1279
- }, this);
1280
-
1281
- return subscription;
1282
- },
1283
-
1284
- // Request Response
1285
- // MUST include: * channel MUST include: * channel
1286
- // * clientId * successful
1287
- // * subscription * clientId
1288
- // MAY include: * ext * subscription
1289
- // * id MAY include: * error
1290
- // * advice
1291
- // * ext
1292
- // * id
1293
- // * timestamp
1294
- unsubscribe: function(channel, subscription) {
1295
- if (channel instanceof Array)
1296
- return array.map(channel, function(c) {
1297
- return this.unsubscribe(c, subscription);
1298
- }, this);
1299
-
1300
- var dead = this._channels.unsubscribe(channel, subscription);
1301
- if (!dead) return;
1302
-
1303
- this.connect(function() {
1304
- this.info('Client ? attempting to unsubscribe from ?', this._dispatcher.clientId, channel);
1305
-
1306
- this._sendMessage({
1307
- channel: Channel.UNSUBSCRIBE,
1308
- clientId: this._dispatcher.clientId,
1309
- subscription: channel
1310
-
1311
- }, {}, function(response) {
1312
- if (!response.successful) return;
1313
-
1314
- var channels = [].concat(response.subscription);
1315
- this.info('Unsubscription acknowledged for ? from ?', this._dispatcher.clientId, channels);
1316
- }, this);
1317
- }, this);
1318
- },
1319
-
1320
- // Request Response
1321
- // MUST include: * channel MUST include: * channel
1322
- // * data * successful
1323
- // MAY include: * clientId MAY include: * id
1324
- // * id * error
1325
- // * ext * ext
1326
- publish: function(channel, data, options) {
1327
- validateOptions(options || {}, ['attempts', 'deadline']);
1328
- var publication = new Publication();
1329
-
1330
- this.connect(function() {
1331
- this.info('Client ? queueing published message to ?: ?', this._dispatcher.clientId, channel, data);
1332
-
1333
- this._sendMessage({
1334
- channel: channel,
1335
- data: data,
1336
- clientId: this._dispatcher.clientId
1337
-
1338
- }, options, function(response) {
1339
- if (response.successful)
1340
- publication.setDeferredStatus('succeeded');
1341
- else
1342
- publication.setDeferredStatus('failed', Error.parse(response.error));
1343
- }, this);
1344
- }, this);
1345
-
1346
- return publication;
1347
- },
1348
-
1349
- _sendMessage: function(message, options, callback, context) {
1350
- message.id = this._generateMessageId();
1351
-
1352
- var timeout = this._advice.timeout
1353
- ? 1.2 * this._advice.timeout / 1000
1354
- : 1.2 * this._dispatcher.retry;
1355
-
1356
- this.pipeThroughExtensions('outgoing', message, null, function(message) {
1357
- if (!message) return;
1358
- if (callback) this._responseCallbacks[message.id] = [callback, context];
1359
- this._dispatcher.sendMessage(message, timeout, options || {});
1360
- }, this);
1361
- },
1362
-
1363
- _generateMessageId: function() {
1364
- this._messageId += 1;
1365
- if (this._messageId >= Math.pow(2,32)) this._messageId = 0;
1366
- return this._messageId.toString(36);
1367
- },
1368
-
1369
- _receiveMessage: function(message) {
1370
- var id = message.id, callback;
1371
-
1372
- if (message.successful !== undefined) {
1373
- callback = this._responseCallbacks[id];
1374
- delete this._responseCallbacks[id];
1375
- }
1376
-
1377
- this.pipeThroughExtensions('incoming', message, null, function(message) {
1378
- if (!message) return;
1379
- if (message.advice) this._handleAdvice(message.advice);
1380
- this._deliverMessage(message);
1381
- if (callback) callback[0].call(callback[1], message);
1382
- }, this);
1383
- },
1384
-
1385
- _handleAdvice: function(advice) {
1386
- extend(this._advice, advice);
1387
- this._dispatcher.timeout = this._advice.timeout / 1000;
1388
-
1389
- if (this._advice.reconnect === this.HANDSHAKE && this._state !== this.DISCONNECTED) {
1390
- this._state = this.UNCONNECTED;
1391
- this._dispatcher.clientId = null;
1392
- this._cycleConnection();
1393
- }
1394
- },
1395
-
1396
- _deliverMessage: function(message) {
1397
- if (!message.channel || message.data === undefined) return;
1398
- this.info('Client ? calling listeners for ? with ?', this._dispatcher.clientId, message.channel, message.data);
1399
- this._channels.distributeMessage(message);
1400
- },
1401
-
1402
- _cycleConnection: function() {
1403
- if (this._connectRequest) {
1404
- this._connectRequest = null;
1405
- this.info('Closed connection for ?', this._dispatcher.clientId);
1406
- }
1407
- var self = this;
1408
- global.setTimeout(function() { self.connect() }, this._advice.interval);
1409
- }
1410
- });
1411
-
1412
- extend(Client.prototype, Deferrable);
1413
- extend(Client.prototype, Publisher);
1414
- extend(Client.prototype, Logging);
1415
- extend(Client.prototype, Extensible);
1416
-
1417
- module.exports = Client;
1418
-
1419
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1420
-
1421
- },{"../mixins/deferrable":6,"../mixins/logging":7,"../mixins/publisher":8,"../util/array":26,"../util/browser":27,"../util/class":28,"../util/constants":29,"../util/extend":33,"../util/promise":34,"../util/uri":37,"../util/validate_options":38,"./channel":10,"./dispatcher":12,"./error":13,"./extensible":14,"./publication":16,"./subscription":18,"asap":3}],12:[function(require,module,exports){
1422
- (function (global){
1423
- 'use strict';
1424
-
1425
- var Class = require('../util/class'),
1426
- URI = require('../util/uri'),
1427
- cookies = require('../util/cookies'),
1428
- extend = require('../util/extend'),
1429
- Logging = require('../mixins/logging'),
1430
- Publisher = require('../mixins/publisher'),
1431
- Transport = require('../transport'),
1432
- Scheduler = require('./scheduler');
1433
-
1434
- var Dispatcher = Class({ className: 'Dispatcher',
1435
- MAX_REQUEST_SIZE: 2048,
1436
- DEFAULT_RETRY: 5,
1437
-
1438
- UP: 1,
1439
- DOWN: 2,
1440
-
1441
- initialize: function(client, endpoint, options) {
1442
- this._client = client;
1443
- this.endpoint = URI.parse(endpoint);
1444
- this._alternates = options.endpoints || {};
1445
-
1446
- this.cookies = cookies.CookieJar && new cookies.CookieJar();
1447
- this._disabled = [];
1448
- this._envelopes = {};
1449
- this.headers = {};
1450
- this.retry = options.retry || this.DEFAULT_RETRY;
1451
- this._scheduler = options.scheduler || Scheduler;
1452
- this._state = 0;
1453
- this.transports = {};
1454
- this.wsExtensions = [];
1455
-
1456
- this.proxy = options.proxy || {};
1457
- if (typeof this._proxy === 'string') this._proxy = {origin: this._proxy};
1458
-
1459
- var exts = options.websocketExtensions;
1460
- if (exts) {
1461
- exts = [].concat(exts);
1462
- for (var i = 0, n = exts.length; i < n; i++)
1463
- this.addWebsocketExtension(exts[i]);
1464
- }
1465
-
1466
- this.tls = options.tls || {};
1467
- this.tls.ca = this.tls.ca || options.ca;
1468
-
1469
- for (var type in this._alternates)
1470
- this._alternates[type] = URI.parse(this._alternates[type]);
1471
-
1472
- this.maxRequestSize = this.MAX_REQUEST_SIZE;
1473
- },
1474
-
1475
- endpointFor: function(connectionType) {
1476
- return this._alternates[connectionType] || this.endpoint;
1477
- },
1478
-
1479
- addWebsocketExtension: function(extension) {
1480
- this.wsExtensions.push(extension);
1481
- },
1482
-
1483
- disable: function(feature) {
1484
- this._disabled.push(feature);
1485
- },
1486
-
1487
- setHeader: function(name, value) {
1488
- this.headers[name] = value;
1489
- },
1490
-
1491
- close: function() {
1492
- var transport = this._transport;
1493
- delete this._transport;
1494
- if (transport) transport.close();
1495
- },
1496
-
1497
- getConnectionTypes: function() {
1498
- return Transport.getConnectionTypes();
1499
- },
1500
-
1501
- selectTransport: function(transportTypes) {
1502
- Transport.get(this, transportTypes, this._disabled, function(transport) {
1503
- this.debug('Selected ? transport for ?', transport.connectionType, URI.stringify(transport.endpoint));
1504
-
1505
- if (transport === this._transport) return;
1506
- if (this._transport) this._transport.close();
1507
-
1508
- this._transport = transport;
1509
- this.connectionType = transport.connectionType;
1510
- }, this);
1511
- },
1512
-
1513
- sendMessage: function(message, timeout, options) {
1514
- options = options || {};
1515
-
1516
- var id = message.id,
1517
- attempts = options.attempts,
1518
- deadline = options.deadline && new Date().getTime() + (options.deadline * 1000),
1519
- envelope = this._envelopes[id],
1520
- scheduler;
1521
-
1522
- if (!envelope) {
1523
- scheduler = new this._scheduler(message, {timeout: timeout, interval: this.retry, attempts: attempts, deadline: deadline});
1524
- envelope = this._envelopes[id] = {message: message, scheduler: scheduler};
1525
- }
1526
-
1527
- this._sendEnvelope(envelope);
1528
- },
1529
-
1530
- _sendEnvelope: function(envelope) {
1531
- if (!this._transport) return;
1532
- if (envelope.request || envelope.timer) return;
1533
-
1534
- var message = envelope.message,
1535
- scheduler = envelope.scheduler,
1536
- self = this;
1537
-
1538
- if (!scheduler.isDeliverable()) {
1539
- scheduler.abort();
1540
- delete this._envelopes[message.id];
1541
- return;
1542
- }
1543
-
1544
- envelope.timer = global.setTimeout(function() {
1545
- self.handleError(message);
1546
- }, scheduler.getTimeout() * 1000);
1547
-
1548
- scheduler.send();
1549
- envelope.request = this._transport.sendMessage(message);
1550
- },
1551
-
1552
- handleResponse: function(reply) {
1553
- var envelope = this._envelopes[reply.id];
1554
-
1555
- if (reply.successful !== undefined && envelope) {
1556
- envelope.scheduler.succeed();
1557
- delete this._envelopes[reply.id];
1558
- global.clearTimeout(envelope.timer);
1559
- }
1560
-
1561
- this.trigger('message', reply);
1562
-
1563
- if (this._state === this.UP) return;
1564
- this._state = this.UP;
1565
- this._client.trigger('transport:up');
1566
- },
1567
-
1568
- handleError: function(message, immediate) {
1569
- var envelope = this._envelopes[message.id],
1570
- request = envelope && envelope.request,
1571
- self = this;
1572
-
1573
- if (!request) return;
1574
-
1575
- request.then(function(req) {
1576
- if (req && req.abort) req.abort();
1577
- });
1578
-
1579
- var scheduler = envelope.scheduler;
1580
- scheduler.fail();
1581
-
1582
- global.clearTimeout(envelope.timer);
1583
- envelope.request = envelope.timer = null;
1584
-
1585
- if (immediate) {
1586
- this._sendEnvelope(envelope);
1587
- } else {
1588
- envelope.timer = global.setTimeout(function() {
1589
- envelope.timer = null;
1590
- self._sendEnvelope(envelope);
1591
- }, scheduler.getInterval() * 1000);
1592
- }
1593
-
1594
- if (this._state === this.DOWN) return;
1595
- this._state = this.DOWN;
1596
- this._client.trigger('transport:down');
1597
- }
1598
- });
1599
-
1600
- Dispatcher.create = function(client, endpoint, options) {
1601
- return new Dispatcher(client, endpoint, options);
1602
- };
1603
-
1604
- extend(Dispatcher.prototype, Publisher);
1605
- extend(Dispatcher.prototype, Logging);
1606
-
1607
- module.exports = Dispatcher;
1608
-
1609
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1610
-
1611
- },{"../mixins/logging":7,"../mixins/publisher":8,"../transport":19,"../util/class":28,"../util/cookies":30,"../util/extend":33,"../util/uri":37,"./scheduler":17}],13:[function(require,module,exports){
1612
- 'use strict';
1613
-
1614
- var Class = require('../util/class'),
1615
- Grammar = require('./grammar');
1616
-
1617
- var Error = Class({
1618
- initialize: function(code, params, message) {
1619
- this.code = code;
1620
- this.params = Array.prototype.slice.call(params);
1621
- this.message = message;
1622
- },
1623
-
1624
- toString: function() {
1625
- return this.code + ':' +
1626
- this.params.join(',') + ':' +
1627
- this.message;
1628
- }
1629
- });
1630
-
1631
- Error.parse = function(message) {
1632
- message = message || '';
1633
- if (!Grammar.ERROR.test(message)) return new Error(null, [], message);
1634
-
1635
- var parts = message.split(':'),
1636
- code = parseInt(parts[0]),
1637
- params = parts[1].split(','),
1638
- message = parts[2];
1639
-
1640
- return new Error(code, params, message);
1641
- };
1642
-
1643
- // http://code.google.com/p/cometd/wiki/BayeuxCodes
1644
- var errors = {
1645
- versionMismatch: [300, 'Version mismatch'],
1646
- conntypeMismatch: [301, 'Connection types not supported'],
1647
- extMismatch: [302, 'Extension mismatch'],
1648
- badRequest: [400, 'Bad request'],
1649
- clientUnknown: [401, 'Unknown client'],
1650
- parameterMissing: [402, 'Missing required parameter'],
1651
- channelForbidden: [403, 'Forbidden channel'],
1652
- channelUnknown: [404, 'Unknown channel'],
1653
- channelInvalid: [405, 'Invalid channel'],
1654
- extUnknown: [406, 'Unknown extension'],
1655
- publishFailed: [407, 'Failed to publish'],
1656
- serverError: [500, 'Internal server error']
1657
- };
1658
-
1659
- for (var name in errors)
1660
- (function(name) {
1661
- Error[name] = function() {
1662
- return new Error(errors[name][0], arguments, errors[name][1]).toString();
1663
- };
1664
- })(name);
1665
-
1666
- module.exports = Error;
1667
-
1668
- },{"../util/class":28,"./grammar":15}],14:[function(require,module,exports){
1669
- 'use strict';
1670
-
1671
- var extend = require('../util/extend'),
1672
- Logging = require('../mixins/logging');
1673
-
1674
- var Extensible = {
1675
- addExtension: function(extension) {
1676
- this._extensions = this._extensions || [];
1677
- this._extensions.push(extension);
1678
- if (extension.added) extension.added(this);
1679
- },
1680
-
1681
- removeExtension: function(extension) {
1682
- if (!this._extensions) return;
1683
- var i = this._extensions.length;
1684
- while (i--) {
1685
- if (this._extensions[i] !== extension) continue;
1686
- this._extensions.splice(i,1);
1687
- if (extension.removed) extension.removed(this);
1688
- }
1689
- },
1690
-
1691
- pipeThroughExtensions: function(stage, message, request, callback, context) {
1692
- this.debug('Passing through ? extensions: ?', stage, message);
1693
-
1694
- if (!this._extensions) return callback.call(context, message);
1695
- var extensions = this._extensions.slice();
1696
-
1697
- var pipe = function(message) {
1698
- if (!message) return callback.call(context, message);
1699
-
1700
- var extension = extensions.shift();
1701
- if (!extension) return callback.call(context, message);
1702
-
1703
- var fn = extension[stage];
1704
- if (!fn) return pipe(message);
1705
-
1706
- if (fn.length >= 3) extension[stage](message, request, pipe);
1707
- else extension[stage](message, pipe);
1708
- };
1709
- pipe(message);
1710
- }
1711
- };
1712
-
1713
- extend(Extensible, Logging);
1714
-
1715
- module.exports = Extensible;
1716
-
1717
- },{"../mixins/logging":7,"../util/extend":33}],15:[function(require,module,exports){
1718
- 'use strict';
1719
-
1720
- module.exports = {
1721
- CHANNEL_NAME: /^\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*$/,
1722
- CHANNEL_PATTERN: /^(\/(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)))+)*\/\*{1,2}$/,
1723
- ERROR: /^([0-9][0-9][0-9]:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*(,(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)*:(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*|[0-9][0-9][0-9]::(((([a-z]|[A-Z])|[0-9])|(\-|\_|\!|\~|\(|\)|\$|\@)| |\/|\*|\.))*)$/,
1724
- VERSION: /^([0-9])+(\.(([a-z]|[A-Z])|[0-9])(((([a-z]|[A-Z])|[0-9])|\-|\_))*)*$/
1725
- };
1726
-
1727
- },{}],16:[function(require,module,exports){
1728
- 'use strict';
1729
-
1730
- var Class = require('../util/class'),
1731
- Deferrable = require('../mixins/deferrable');
1732
-
1733
- module.exports = Class(Deferrable);
1734
-
1735
- },{"../mixins/deferrable":6,"../util/class":28}],17:[function(require,module,exports){
1736
- 'use strict';
1737
-
1738
- var extend = require('../util/extend');
1739
-
1740
- var Scheduler = function(message, options) {
1741
- this.message = message;
1742
- this.options = options;
1743
- this.attempts = 0;
1744
- };
1745
-
1746
- extend(Scheduler.prototype, {
1747
- getTimeout: function() {
1748
- return this.options.timeout;
1749
- },
1750
-
1751
- getInterval: function() {
1752
- return this.options.interval;
1753
- },
1754
-
1755
- isDeliverable: function() {
1756
- var attempts = this.options.attempts,
1757
- made = this.attempts,
1758
- deadline = this.options.deadline,
1759
- now = new Date().getTime();
1760
-
1761
- if (attempts !== undefined && made >= attempts)
1762
- return false;
1763
-
1764
- if (deadline !== undefined && now > deadline)
1765
- return false;
1766
-
1767
- return true;
1768
- },
1769
-
1770
- send: function() {
1771
- this.attempts += 1;
1772
- },
1773
-
1774
- succeed: function() {},
1775
-
1776
- fail: function() {},
1777
-
1778
- abort: function() {}
1779
- });
1780
-
1781
- module.exports = Scheduler;
1782
-
1783
- },{"../util/extend":33}],18:[function(require,module,exports){
1784
- 'use strict';
1785
-
1786
- var Class = require('../util/class'),
1787
- extend = require('../util/extend'),
1788
- Deferrable = require('../mixins/deferrable');
1789
-
1790
- var Subscription = Class({
1791
- initialize: function(client, channels, callback, context) {
1792
- this._client = client;
1793
- this._channels = channels;
1794
- this._callback = callback;
1795
- this._context = context;
1796
- this._cancelled = false;
1797
- },
1798
-
1799
- withChannel: function(callback, context) {
1800
- this._withChannel = [callback, context];
1801
- return this;
1802
- },
1803
-
1804
- apply: function(context, args) {
1805
- var message = args[0];
1806
-
1807
- if (this._callback)
1808
- this._callback.call(this._context, message.data);
1809
-
1810
- if (this._withChannel)
1811
- this._withChannel[0].call(this._withChannel[1], message.channel, message.data);
1812
- },
1813
-
1814
- cancel: function() {
1815
- if (this._cancelled) return;
1816
- this._client.unsubscribe(this._channels, this);
1817
- this._cancelled = true;
1818
- },
1819
-
1820
- unsubscribe: function() {
1821
- this.cancel();
1822
- }
1823
- });
1824
-
1825
- extend(Subscription.prototype, Deferrable);
1826
-
1827
- module.exports = Subscription;
1828
-
1829
- },{"../mixins/deferrable":6,"../util/class":28,"../util/extend":33}],19:[function(require,module,exports){
1830
- 'use strict';
1831
-
1832
- var Transport = require('./transport');
1833
-
1834
- Transport.register('websocket', require('./web_socket'));
1835
- Transport.register('eventsource', require('./event_source'));
1836
- Transport.register('long-polling', require('./xhr'));
1837
- Transport.register('cross-origin-long-polling', require('./cors'));
1838
- Transport.register('callback-polling', require('./jsonp'));
1839
-
1840
- module.exports = Transport;
1841
-
1842
- },{"./cors":20,"./event_source":21,"./jsonp":22,"./transport":23,"./web_socket":24,"./xhr":25}],20:[function(require,module,exports){
1843
- (function (global){
1844
- 'use strict';
1845
-
1846
- var Class = require('../util/class'),
1847
- Set = require('../util/set'),
1848
- URI = require('../util/uri'),
1849
- extend = require('../util/extend'),
1850
- toJSON = require('../util/to_json'),
1851
- Transport = require('./transport');
1852
-
1853
- var CORS = extend(Class(Transport, {
1854
- encode: function(messages) {
1855
- return 'message=' + encodeURIComponent(toJSON(messages));
1856
- },
1857
-
1858
- request: function(messages) {
1859
- var xhrClass = global.XDomainRequest ? XDomainRequest : XMLHttpRequest,
1860
- xhr = new xhrClass(),
1861
- id = ++CORS._id,
1862
- headers = this._dispatcher.headers,
1863
- self = this,
1864
- key;
1865
-
1866
- xhr.open('POST', URI.stringify(this.endpoint), true);
1867
-
1868
- if (xhr.setRequestHeader) {
1869
- xhr.setRequestHeader('Pragma', 'no-cache');
1870
- for (key in headers) {
1871
- if (!headers.hasOwnProperty(key)) continue;
1872
- xhr.setRequestHeader(key, headers[key]);
1873
- }
1874
- }
1875
-
1876
- var cleanUp = function() {
1877
- if (!xhr) return false;
1878
- CORS._pending.remove(id);
1879
- xhr.onload = xhr.onerror = xhr.ontimeout = xhr.onprogress = null;
1880
- xhr = null;
1881
- };
1882
-
1883
- xhr.onload = function() {
1884
- var replies;
1885
- try { replies = JSON.parse(xhr.responseText) } catch (error) {}
1886
-
1887
- cleanUp();
1888
-
1889
- if (replies)
1890
- self._receive(replies);
1891
- else
1892
- self._handleError(messages);
1893
- };
1894
-
1895
- xhr.onerror = xhr.ontimeout = function() {
1896
- cleanUp();
1897
- self._handleError(messages);
1898
- };
1899
-
1900
- xhr.onprogress = function() {};
1901
-
1902
- if (xhrClass === global.XDomainRequest)
1903
- CORS._pending.add({id: id, xhr: xhr});
1904
-
1905
- xhr.send(this.encode(messages));
1906
- return xhr;
1907
- }
1908
- }), {
1909
- _id: 0,
1910
- _pending: new Set(),
1911
-
1912
- isUsable: function(dispatcher, endpoint, callback, context) {
1913
- if (URI.isSameOrigin(endpoint))
1914
- return callback.call(context, false);
1915
-
1916
- if (global.XDomainRequest)
1917
- return callback.call(context, endpoint.protocol === location.protocol);
1918
-
1919
- if (global.XMLHttpRequest) {
1920
- var xhr = new XMLHttpRequest();
1921
- return callback.call(context, xhr.withCredentials !== undefined);
1922
- }
1923
- return callback.call(context, false);
1924
- }
1925
- });
1926
-
1927
- module.exports = CORS;
1928
-
1929
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1930
-
1931
- },{"../util/class":28,"../util/extend":33,"../util/set":35,"../util/to_json":36,"../util/uri":37,"./transport":23}],21:[function(require,module,exports){
1932
- (function (global){
1933
- 'use strict';
1934
-
1935
- var Class = require('../util/class'),
1936
- URI = require('../util/uri'),
1937
- copyObject = require('../util/copy_object'),
1938
- extend = require('../util/extend'),
1939
- Deferrable = require('../mixins/deferrable'),
1940
- Transport = require('./transport'),
1941
- XHR = require('./xhr');
1942
-
1943
- var EventSource = extend(Class(Transport, {
1944
- initialize: function(dispatcher, endpoint) {
1945
- Transport.prototype.initialize.call(this, dispatcher, endpoint);
1946
- if (!global.EventSource) return this.setDeferredStatus('failed');
1947
-
1948
- this._xhr = new XHR(dispatcher, endpoint);
1949
-
1950
- endpoint = copyObject(endpoint);
1951
- endpoint.pathname += '/' + dispatcher.clientId;
1952
-
1953
- var socket = new global.EventSource(URI.stringify(endpoint)),
1954
- self = this;
1955
-
1956
- socket.onopen = function() {
1957
- self._everConnected = true;
1958
- self.setDeferredStatus('succeeded');
1959
- };
1960
-
1961
- socket.onerror = function() {
1962
- if (self._everConnected) {
1963
- self._handleError([]);
1964
- } else {
1965
- self.setDeferredStatus('failed');
1966
- socket.close();
1967
- }
1968
- };
1969
-
1970
- socket.onmessage = function(event) {
1971
- var replies;
1972
- try { replies = JSON.parse(event.data) } catch (error) {}
1973
-
1974
- if (replies)
1975
- self._receive(replies);
1976
- else
1977
- self._handleError([]);
1978
- };
1979
-
1980
- this._socket = socket;
1981
- },
1982
-
1983
- close: function() {
1984
- if (!this._socket) return;
1985
- this._socket.onopen = this._socket.onerror = this._socket.onmessage = null;
1986
- this._socket.close();
1987
- delete this._socket;
1988
- },
1989
-
1990
- isUsable: function(callback, context) {
1991
- this.callback(function() { callback.call(context, true) });
1992
- this.errback(function() { callback.call(context, false) });
1993
- },
1994
-
1995
- encode: function(messages) {
1996
- return this._xhr.encode(messages);
1997
- },
1998
-
1999
- request: function(messages) {
2000
- return this._xhr.request(messages);
2001
- }
2002
-
2003
- }), {
2004
- isUsable: function(dispatcher, endpoint, callback, context) {
2005
- var id = dispatcher.clientId;
2006
- if (!id) return callback.call(context, false);
2007
-
2008
- XHR.isUsable(dispatcher, endpoint, function(usable) {
2009
- if (!usable) return callback.call(context, false);
2010
- this.create(dispatcher, endpoint).isUsable(callback, context);
2011
- }, this);
2012
- },
2013
-
2014
- create: function(dispatcher, endpoint) {
2015
- var sockets = dispatcher.transports.eventsource = dispatcher.transports.eventsource || {},
2016
- id = dispatcher.clientId;
2017
-
2018
- var url = copyObject(endpoint);
2019
- url.pathname += '/' + (id || '');
2020
- url = URI.stringify(url);
2021
-
2022
- sockets[url] = sockets[url] || new this(dispatcher, endpoint);
2023
- return sockets[url];
2024
- }
2025
- });
2026
-
2027
- extend(EventSource.prototype, Deferrable);
2028
-
2029
- module.exports = EventSource;
2030
-
2031
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2032
-
2033
- },{"../mixins/deferrable":6,"../util/class":28,"../util/copy_object":31,"../util/extend":33,"../util/uri":37,"./transport":23,"./xhr":25}],22:[function(require,module,exports){
2034
- (function (global){
2035
- 'use strict';
2036
-
2037
- var Class = require('../util/class'),
2038
- URI = require('../util/uri'),
2039
- copyObject = require('../util/copy_object'),
2040
- extend = require('../util/extend'),
2041
- toJSON = require('../util/to_json'),
2042
- Transport = require('./transport');
2043
-
2044
- var JSONP = extend(Class(Transport, {
2045
- encode: function(messages) {
2046
- var url = copyObject(this.endpoint);
2047
- url.query.message = toJSON(messages);
2048
- url.query.jsonp = '__jsonp' + JSONP._cbCount + '__';
2049
- return URI.stringify(url);
2050
- },
2051
-
2052
- request: function(messages) {
2053
- var head = document.getElementsByTagName('head')[0],
2054
- script = document.createElement('script'),
2055
- callbackName = JSONP.getCallbackName(),
2056
- endpoint = copyObject(this.endpoint),
2057
- self = this;
2058
-
2059
- endpoint.query.message = toJSON(messages);
2060
- endpoint.query.jsonp = callbackName;
2061
-
2062
- var cleanup = function() {
2063
- if (!global[callbackName]) return false;
2064
- global[callbackName] = undefined;
2065
- try { delete global[callbackName] } catch (error) {}
2066
- script.parentNode.removeChild(script);
2067
- };
2068
-
2069
- global[callbackName] = function(replies) {
2070
- cleanup();
2071
- self._receive(replies);
2072
- };
2073
-
2074
- script.type = 'text/javascript';
2075
- script.src = URI.stringify(endpoint);
2076
- head.appendChild(script);
2077
-
2078
- script.onerror = function() {
2079
- cleanup();
2080
- self._handleError(messages);
2081
- };
2082
-
2083
- return {abort: cleanup};
2084
- }
2085
- }), {
2086
- _cbCount: 0,
2087
-
2088
- getCallbackName: function() {
2089
- this._cbCount += 1;
2090
- return '__jsonp' + this._cbCount + '__';
2091
- },
2092
-
2093
- isUsable: function(dispatcher, endpoint, callback, context) {
2094
- callback.call(context, true);
2095
- }
2096
- });
2097
-
2098
- module.exports = JSONP;
2099
-
2100
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2101
-
2102
- },{"../util/class":28,"../util/copy_object":31,"../util/extend":33,"../util/to_json":36,"../util/uri":37,"./transport":23}],23:[function(require,module,exports){
2103
- (function (process){
2104
- 'use strict';
2105
-
2106
- var Class = require('../util/class'),
2107
- Cookie = require('../util/cookies').Cookie,
2108
- Promise = require('../util/promise'),
2109
- URI = require('../util/uri'),
2110
- array = require('../util/array'),
2111
- extend = require('../util/extend'),
2112
- Logging = require('../mixins/logging'),
2113
- Timeouts = require('../mixins/timeouts'),
2114
- Channel = require('../protocol/channel');
2115
-
2116
- var Transport = extend(Class({ className: 'Transport',
2117
- DEFAULT_PORTS: {'http:': 80, 'https:': 443, 'ws:': 80, 'wss:': 443},
2118
- MAX_DELAY: 0,
2119
-
2120
- batching: true,
2121
-
2122
- initialize: function(dispatcher, endpoint) {
2123
- this._dispatcher = dispatcher;
2124
- this.endpoint = endpoint;
2125
- this._outbox = [];
2126
- this._proxy = extend({}, this._dispatcher.proxy);
2127
-
2128
- if (!this._proxy.origin)
2129
- this._proxy.origin = this._findProxy();
2130
- },
2131
-
2132
- close: function() {},
2133
-
2134
- encode: function(messages) {
2135
- return '';
2136
- },
2137
-
2138
- sendMessage: function(message) {
2139
- this.debug('Client ? sending message to ?: ?',
2140
- this._dispatcher.clientId, URI.stringify(this.endpoint), message);
2141
-
2142
- if (!this.batching) return Promise.resolve(this.request([message]));
2143
-
2144
- this._outbox.push(message);
2145
- this._flushLargeBatch();
2146
-
2147
- if (message.channel === Channel.HANDSHAKE)
2148
- return this._publish(0.01);
2149
-
2150
- if (message.channel === Channel.CONNECT)
2151
- this._connectMessage = message;
2152
-
2153
- return this._publish(this.MAX_DELAY);
2154
- },
2155
-
2156
- _makePromise: function() {
2157
- var self = this;
2158
-
2159
- this._requestPromise = this._requestPromise || new Promise(function(resolve) {
2160
- self._resolvePromise = resolve;
2161
- });
2162
- },
2163
-
2164
- _publish: function(delay) {
2165
- this._makePromise();
2166
-
2167
- this.addTimeout('publish', delay, function() {
2168
- this._flush();
2169
- delete this._requestPromise;
2170
- }, this);
2171
-
2172
- return this._requestPromise;
2173
- },
2174
-
2175
- _flush: function() {
2176
- this.removeTimeout('publish');
2177
-
2178
- if (this._outbox.length > 1 && this._connectMessage)
2179
- this._connectMessage.advice = {timeout: 0};
2180
-
2181
- this._resolvePromise(this.request(this._outbox));
2182
-
2183
- this._connectMessage = null;
2184
- this._outbox = [];
2185
- },
2186
-
2187
- _flushLargeBatch: function() {
2188
- var string = this.encode(this._outbox);
2189
- if (string.length < this._dispatcher.maxRequestSize) return;
2190
- var last = this._outbox.pop();
2191
-
2192
- this._makePromise();
2193
- this._flush();
2194
-
2195
- if (last) this._outbox.push(last);
2196
- },
2197
-
2198
- _receive: function(replies) {
2199
- if (!replies) return;
2200
- replies = [].concat(replies);
2201
-
2202
- this.debug('Client ? received from ? via ?: ?',
2203
- this._dispatcher.clientId, URI.stringify(this.endpoint), this.connectionType, replies);
2204
-
2205
- for (var i = 0, n = replies.length; i < n; i++)
2206
- this._dispatcher.handleResponse(replies[i]);
2207
- },
2208
-
2209
- _handleError: function(messages, immediate) {
2210
- messages = [].concat(messages);
2211
-
2212
- this.debug('Client ? failed to send to ? via ?: ?',
2213
- this._dispatcher.clientId, URI.stringify(this.endpoint), this.connectionType, messages);
2214
-
2215
- for (var i = 0, n = messages.length; i < n; i++)
2216
- this._dispatcher.handleError(messages[i]);
2217
- },
2218
-
2219
- _getCookies: function() {
2220
- var cookies = this._dispatcher.cookies,
2221
- url = URI.stringify(this.endpoint);
2222
-
2223
- if (!cookies) return '';
2224
-
2225
- return array.map(cookies.getCookiesSync(url), function(cookie) {
2226
- return cookie.cookieString();
2227
- }).join('; ');
2228
- },
2229
-
2230
- _storeCookies: function(setCookie) {
2231
- var cookies = this._dispatcher.cookies,
2232
- url = URI.stringify(this.endpoint),
2233
- cookie;
2234
-
2235
- if (!setCookie || !cookies) return;
2236
- setCookie = [].concat(setCookie);
2237
-
2238
- for (var i = 0, n = setCookie.length; i < n; i++) {
2239
- cookie = Cookie.parse(setCookie[i]);
2240
- cookies.setCookieSync(cookie, url);
2241
- }
2242
- },
2243
-
2244
- _findProxy: function() {
2245
- if (typeof process === 'undefined') return undefined;
2246
-
2247
- var protocol = this.endpoint.protocol;
2248
- if (!protocol) return undefined;
2249
-
2250
- var name = protocol.replace(/:$/, '').toLowerCase() + '_proxy',
2251
- upcase = name.toUpperCase(),
2252
- env = process.env,
2253
- keys, proxy;
2254
-
2255
- if (name === 'http_proxy' && env.REQUEST_METHOD) {
2256
- keys = Object.keys(env).filter(function(k) { return /^http_proxy$/i.test(k) });
2257
- if (keys.length === 1) {
2258
- if (keys[0] === name && env[upcase] === undefined)
2259
- proxy = env[name];
2260
- } else if (keys.length > 1) {
2261
- proxy = env[name];
2262
- }
2263
- proxy = proxy || env['CGI_' + upcase];
2264
- } else {
2265
- proxy = env[name] || env[upcase];
2266
- if (proxy && !env[name])
2267
- console.warn('The environment variable ' + upcase +
2268
- ' is discouraged. Use ' + name + '.');
2269
- }
2270
- return proxy;
2271
- }
2272
-
2273
- }), {
2274
- get: function(dispatcher, allowed, disabled, callback, context) {
2275
- var endpoint = dispatcher.endpoint;
2276
-
2277
- array.asyncEach(this._transports, function(pair, resume) {
2278
- var connType = pair[0], klass = pair[1],
2279
- connEndpoint = dispatcher.endpointFor(connType);
2280
-
2281
- if (array.indexOf(disabled, connType) >= 0)
2282
- return resume();
2283
-
2284
- if (array.indexOf(allowed, connType) < 0) {
2285
- klass.isUsable(dispatcher, connEndpoint, function() {});
2286
- return resume();
2287
- }
2288
-
2289
- klass.isUsable(dispatcher, connEndpoint, function(isUsable) {
2290
- if (!isUsable) return resume();
2291
- var transport = klass.hasOwnProperty('create') ? klass.create(dispatcher, connEndpoint) : new klass(dispatcher, connEndpoint);
2292
- callback.call(context, transport);
2293
- });
2294
- }, function() {
2295
- throw new Error('Could not find a usable connection type for ' + URI.stringify(endpoint));
2296
- });
2297
- },
2298
-
2299
- register: function(type, klass) {
2300
- this._transports.push([type, klass]);
2301
- klass.prototype.connectionType = type;
2302
- },
2303
-
2304
- getConnectionTypes: function() {
2305
- return array.map(this._transports, function(t) { return t[0] });
2306
- },
2307
-
2308
- _transports: []
2309
- });
2310
-
2311
- extend(Transport.prototype, Logging);
2312
- extend(Transport.prototype, Timeouts);
2313
-
2314
- module.exports = Transport;
2315
-
2316
- }).call(this,require('_process'))
2317
-
2318
- },{"../mixins/logging":7,"../mixins/timeouts":9,"../protocol/channel":10,"../util/array":26,"../util/class":28,"../util/cookies":30,"../util/extend":33,"../util/promise":34,"../util/uri":37,"_process":40}],24:[function(require,module,exports){
2319
- (function (global){
2320
- 'use strict';
2321
-
2322
- var Class = require('../util/class'),
2323
- Promise = require('../util/promise'),
2324
- Set = require('../util/set'),
2325
- URI = require('../util/uri'),
2326
- browser = require('../util/browser'),
2327
- copyObject = require('../util/copy_object'),
2328
- extend = require('../util/extend'),
2329
- toJSON = require('../util/to_json'),
2330
- ws = require('../util/websocket'),
2331
- Deferrable = require('../mixins/deferrable'),
2332
- Transport = require('./transport');
2333
-
2334
- var WebSocket = extend(Class(Transport, {
2335
- UNCONNECTED: 1,
2336
- CONNECTING: 2,
2337
- CONNECTED: 3,
2338
-
2339
- batching: false,
2340
-
2341
- isUsable: function(callback, context) {
2342
- this.callback(function() { callback.call(context, true) });
2343
- this.errback(function() { callback.call(context, false) });
2344
- this.connect();
2345
- },
2346
-
2347
- request: function(messages) {
2348
- this._pending = this._pending || new Set();
2349
- for (var i = 0, n = messages.length; i < n; i++) this._pending.add(messages[i]);
2350
-
2351
- var self = this;
2352
-
2353
- var promise = new Promise(function(resolve, reject) {
2354
- self.callback(function(socket) {
2355
- if (!socket || socket.readyState !== 1) return;
2356
- socket.send(toJSON(messages));
2357
- resolve(socket);
2358
- });
2359
-
2360
- self.connect();
2361
- });
2362
-
2363
- return {
2364
- abort: function() { promise.then(function(ws) { ws.close() }) }
2365
- };
2366
- },
2367
-
2368
- connect: function() {
2369
- if (WebSocket._unloaded) return;
2370
-
2371
- this._state = this._state || this.UNCONNECTED;
2372
- if (this._state !== this.UNCONNECTED) return;
2373
- this._state = this.CONNECTING;
2374
-
2375
- var socket = this._createSocket();
2376
- if (!socket) return this.setDeferredStatus('failed');
2377
-
2378
- var self = this;
2379
-
2380
- socket.onopen = function() {
2381
- if (socket.headers) self._storeCookies(socket.headers['set-cookie']);
2382
- self._socket = socket;
2383
- self._state = self.CONNECTED;
2384
- self._everConnected = true;
2385
- self._ping();
2386
- self.setDeferredStatus('succeeded', socket);
2387
- };
2388
-
2389
- var closed = false;
2390
- socket.onclose = socket.onerror = function() {
2391
- if (closed) return;
2392
- closed = true;
2393
-
2394
- var wasConnected = (self._state === self.CONNECTED);
2395
- socket.onopen = socket.onclose = socket.onerror = socket.onmessage = null;
2396
-
2397
- delete self._socket;
2398
- self._state = self.UNCONNECTED;
2399
- self.removeTimeout('ping');
2400
-
2401
- var pending = self._pending ? self._pending.toArray() : [];
2402
- delete self._pending;
2403
-
2404
- if (wasConnected || self._everConnected) {
2405
- self.setDeferredStatus('unknown');
2406
- self._handleError(pending, wasConnected);
2407
- } else {
2408
- self.setDeferredStatus('failed');
2409
- }
2410
- };
2411
-
2412
- socket.onmessage = function(event) {
2413
- var replies;
2414
- try { replies = JSON.parse(event.data) } catch (error) {}
2415
-
2416
- if (!replies) return;
2417
-
2418
- replies = [].concat(replies);
2419
-
2420
- for (var i = 0, n = replies.length; i < n; i++) {
2421
- if (replies[i].successful === undefined) continue;
2422
- self._pending.remove(replies[i]);
2423
- }
2424
- self._receive(replies);
2425
- };
2426
- },
2427
-
2428
- close: function() {
2429
- if (!this._socket) return;
2430
- this._socket.close();
2431
- },
2432
-
2433
- _createSocket: function() {
2434
- var url = WebSocket.getSocketUrl(this.endpoint),
2435
- headers = this._dispatcher.headers,
2436
- extensions = this._dispatcher.wsExtensions,
2437
- cookie = this._getCookies(),
2438
- tls = this._dispatcher.tls,
2439
- options = {extensions: extensions, headers: headers, proxy: this._proxy, tls: tls};
2440
-
2441
- if (cookie !== '') options.headers['Cookie'] = cookie;
2442
-
2443
- return ws.create(url, [], options);
2444
- },
2445
-
2446
- _ping: function() {
2447
- if (!this._socket || this._socket.readyState !== 1) return;
2448
- this._socket.send('[]');
2449
- this.addTimeout('ping', this._dispatcher.timeout / 2, this._ping, this);
2450
- }
2451
-
2452
- }), {
2453
- PROTOCOLS: {
2454
- 'http:': 'ws:',
2455
- 'https:': 'wss:'
2456
- },
2457
-
2458
- create: function(dispatcher, endpoint) {
2459
- var sockets = dispatcher.transports.websocket = dispatcher.transports.websocket || {};
2460
- sockets[endpoint.href] = sockets[endpoint.href] || new this(dispatcher, endpoint);
2461
- return sockets[endpoint.href];
2462
- },
2463
-
2464
- getSocketUrl: function(endpoint) {
2465
- endpoint = copyObject(endpoint);
2466
- endpoint.protocol = this.PROTOCOLS[endpoint.protocol];
2467
- return URI.stringify(endpoint);
2468
- },
2469
-
2470
- isUsable: function(dispatcher, endpoint, callback, context) {
2471
- this.create(dispatcher, endpoint).isUsable(callback, context);
2472
- }
2473
- });
2474
-
2475
- extend(WebSocket.prototype, Deferrable);
2476
-
2477
- if (browser.Event && global.onbeforeunload !== undefined)
2478
- browser.Event.on(global, 'beforeunload', function() { WebSocket._unloaded = true });
2479
-
2480
- module.exports = WebSocket;
2481
-
2482
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2483
-
2484
- },{"../mixins/deferrable":6,"../util/browser":27,"../util/class":28,"../util/copy_object":31,"../util/extend":33,"../util/promise":34,"../util/set":35,"../util/to_json":36,"../util/uri":37,"../util/websocket":39,"./transport":23}],25:[function(require,module,exports){
2485
- (function (global){
2486
- 'use strict';
2487
-
2488
- var Class = require('../util/class'),
2489
- URI = require('../util/uri'),
2490
- browser = require('../util/browser'),
2491
- extend = require('../util/extend'),
2492
- toJSON = require('../util/to_json'),
2493
- Transport = require('./transport');
2494
-
2495
- var XHR = extend(Class(Transport, {
2496
- encode: function(messages) {
2497
- return toJSON(messages);
2498
- },
2499
-
2500
- request: function(messages) {
2501
- var href = this.endpoint.href,
2502
- self = this,
2503
- xhr;
2504
-
2505
- // Prefer XMLHttpRequest over ActiveXObject if they both exist
2506
- if (global.XMLHttpRequest) {
2507
- xhr = new XMLHttpRequest();
2508
- } else if (global.ActiveXObject) {
2509
- xhr = new ActiveXObject('Microsoft.XMLHTTP');
2510
- } else {
2511
- return this._handleError(messages);
2512
- }
2513
-
2514
- xhr.open('POST', href, true);
2515
- xhr.setRequestHeader('Content-Type', 'application/json');
2516
- xhr.setRequestHeader('Pragma', 'no-cache');
2517
- xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
2518
-
2519
- var headers = this._dispatcher.headers;
2520
- for (var key in headers) {
2521
- if (!headers.hasOwnProperty(key)) continue;
2522
- xhr.setRequestHeader(key, headers[key]);
2523
- }
2524
-
2525
- var abort = function() { xhr.abort() };
2526
- if (global.onbeforeunload !== undefined)
2527
- browser.Event.on(global, 'beforeunload', abort);
2528
-
2529
- xhr.onreadystatechange = function() {
2530
- if (!xhr || xhr.readyState !== 4) return;
2531
-
2532
- var replies = null,
2533
- status = xhr.status,
2534
- text = xhr.responseText,
2535
- successful = (status >= 200 && status < 300) || status === 304 || status === 1223;
2536
-
2537
- if (global.onbeforeunload !== undefined)
2538
- browser.Event.detach(global, 'beforeunload', abort);
2539
-
2540
- xhr.onreadystatechange = function() {};
2541
- xhr = null;
2542
-
2543
- if (!successful) return self._handleError(messages);
2544
-
2545
- try {
2546
- replies = JSON.parse(text);
2547
- } catch (error) {}
2548
-
2549
- if (replies)
2550
- self._receive(replies);
2551
- else
2552
- self._handleError(messages);
2553
- };
2554
-
2555
- xhr.send(this.encode(messages));
2556
- return xhr;
2557
- }
2558
- }), {
2559
- isUsable: function(dispatcher, endpoint, callback, context) {
2560
- var usable = (navigator.product === 'ReactNative')
2561
- || URI.isSameOrigin(endpoint);
2562
-
2563
- callback.call(context, usable);
2564
- }
2565
- });
2566
-
2567
- module.exports = XHR;
2568
-
2569
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2570
-
2571
- },{"../util/browser":27,"../util/class":28,"../util/extend":33,"../util/to_json":36,"../util/uri":37,"./transport":23}],26:[function(require,module,exports){
2572
- 'use strict';
2573
-
2574
- module.exports = {
2575
- commonElement: function(lista, listb) {
2576
- for (var i = 0, n = lista.length; i < n; i++) {
2577
- if (this.indexOf(listb, lista[i]) !== -1)
2578
- return lista[i];
2579
- }
2580
- return null;
2581
- },
2582
-
2583
- indexOf: function(list, needle) {
2584
- if (list.indexOf) return list.indexOf(needle);
2585
-
2586
- for (var i = 0, n = list.length; i < n; i++) {
2587
- if (list[i] === needle) return i;
2588
- }
2589
- return -1;
2590
- },
2591
-
2592
- map: function(object, callback, context) {
2593
- if (object.map) return object.map(callback, context);
2594
- var result = [];
2595
-
2596
- if (object instanceof Array) {
2597
- for (var i = 0, n = object.length; i < n; i++) {
2598
- result.push(callback.call(context || null, object[i], i));
2599
- }
2600
- } else {
2601
- for (var key in object) {
2602
- if (!object.hasOwnProperty(key)) continue;
2603
- result.push(callback.call(context || null, key, object[key]));
2604
- }
2605
- }
2606
- return result;
2607
- },
2608
-
2609
- filter: function(array, callback, context) {
2610
- if (array.filter) return array.filter(callback, context);
2611
- var result = [];
2612
- for (var i = 0, n = array.length; i < n; i++) {
2613
- if (callback.call(context || null, array[i], i))
2614
- result.push(array[i]);
2615
- }
2616
- return result;
2617
- },
2618
-
2619
- asyncEach: function(list, iterator, callback, context) {
2620
- var n = list.length,
2621
- i = -1,
2622
- calls = 0,
2623
- looping = false;
2624
-
2625
- var iterate = function() {
2626
- calls -= 1;
2627
- i += 1;
2628
- if (i === n) return callback && callback.call(context);
2629
- iterator(list[i], resume);
2630
- };
2631
-
2632
- var loop = function() {
2633
- if (looping) return;
2634
- looping = true;
2635
- while (calls > 0) iterate();
2636
- looping = false;
2637
- };
2638
-
2639
- var resume = function() {
2640
- calls += 1;
2641
- loop();
2642
- };
2643
- resume();
2644
- }
2645
- };
2646
-
2647
- },{}],27:[function(require,module,exports){
2648
- (function (global){
2649
- 'use strict';
2650
-
2651
- var Event = {
2652
- _registry: [],
2653
-
2654
- on: function(element, eventName, callback, context) {
2655
- var wrapped = function() { callback.call(context) };
2656
-
2657
- if (element.addEventListener)
2658
- element.addEventListener(eventName, wrapped, false);
2659
- else
2660
- element.attachEvent('on' + eventName, wrapped);
2661
-
2662
- this._registry.push({
2663
- _element: element,
2664
- _type: eventName,
2665
- _callback: callback,
2666
- _context: context,
2667
- _handler: wrapped
2668
- });
2669
- },
2670
-
2671
- detach: function(element, eventName, callback, context) {
2672
- var i = this._registry.length, register;
2673
- while (i--) {
2674
- register = this._registry[i];
2675
-
2676
- if ((element && element !== register._element) ||
2677
- (eventName && eventName !== register._type) ||
2678
- (callback && callback !== register._callback) ||
2679
- (context && context !== register._context))
2680
- continue;
2681
-
2682
- if (register._element.removeEventListener)
2683
- register._element.removeEventListener(register._type, register._handler, false);
2684
- else
2685
- register._element.detachEvent('on' + register._type, register._handler);
2686
-
2687
- this._registry.splice(i,1);
2688
- register = null;
2689
- }
2690
- }
2691
- };
2692
-
2693
- if (global.onunload !== undefined)
2694
- Event.on(global, 'unload', Event.detach, Event);
2695
-
2696
- module.exports = {
2697
- Event: Event
2698
- };
2699
-
2700
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2701
-
2702
- },{}],28:[function(require,module,exports){
2703
- 'use strict';
2704
-
2705
- var extend = require('./extend');
2706
-
2707
- module.exports = function(parent, methods) {
2708
- if (typeof parent !== 'function') {
2709
- methods = parent;
2710
- parent = Object;
2711
- }
2712
-
2713
- var klass = function() {
2714
- if (!this.initialize) return this;
2715
- return this.initialize.apply(this, arguments) || this;
2716
- };
2717
-
2718
- var bridge = function() {};
2719
- bridge.prototype = parent.prototype;
2720
-
2721
- klass.prototype = new bridge();
2722
- extend(klass.prototype, methods);
2723
-
2724
- return klass;
2725
- };
2726
-
2727
- },{"./extend":33}],29:[function(require,module,exports){
2728
- module.exports = {
2729
- VERSION: '1.2.4',
2730
-
2731
- BAYEUX_VERSION: '1.0',
2732
- ID_LENGTH: 160,
2733
- JSONP_CALLBACK: 'jsonpcallback',
2734
- CONNECTION_TYPES: ['long-polling', 'cross-origin-long-polling', 'callback-polling', 'websocket', 'eventsource', 'in-process'],
2735
-
2736
- MANDATORY_CONNECTION_TYPES: ['long-polling', 'callback-polling', 'in-process']
2737
- };
2738
-
2739
- },{}],30:[function(require,module,exports){
2740
- 'use strict';
2741
-
2742
- module.exports = {};
2743
-
2744
- },{}],31:[function(require,module,exports){
2745
- 'use strict';
2746
-
2747
- var copyObject = function(object) {
2748
- var clone, i, key;
2749
- if (object instanceof Array) {
2750
- clone = [];
2751
- i = object.length;
2752
- while (i--) clone[i] = copyObject(object[i]);
2753
- return clone;
2754
- } else if (typeof object === 'object') {
2755
- clone = (object === null) ? null : {};
2756
- for (key in object) clone[key] = copyObject(object[key]);
2757
- return clone;
2758
- } else {
2759
- return object;
2760
- }
2761
- };
2762
-
2763
- module.exports = copyObject;
2764
-
2765
- },{}],32:[function(require,module,exports){
2766
- /*
2767
- Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2768
- Permission is hereby granted, free of charge, to any person obtaining a copy of
2769
- this software and associated documentation files (the "Software"), to deal in
2770
- the Software without restriction, including without limitation the rights to
2771
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
2772
- of the Software, and to permit persons to whom the Software is furnished to do
2773
- so, subject to the following conditions:
2774
-
2775
- The above copyright notice and this permission notice shall be included in all
2776
- copies or substantial portions of the Software.
2777
-
2778
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2779
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2780
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2781
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2782
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2783
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2784
- SOFTWARE.
2785
- */
2786
-
2787
- var isArray = typeof Array.isArray === 'function'
2788
- ? Array.isArray
2789
- : function (xs) {
2790
- return Object.prototype.toString.call(xs) === '[object Array]'
2791
- }
2792
- ;
2793
- function indexOf (xs, x) {
2794
- if (xs.indexOf) return xs.indexOf(x);
2795
- for (var i = 0; i < xs.length; i++) {
2796
- if (x === xs[i]) return i;
2797
- }
2798
- return -1;
2799
- }
2800
-
2801
- function EventEmitter() {}
2802
- module.exports = EventEmitter;
2803
-
2804
- EventEmitter.prototype.emit = function(type) {
2805
- // If there is no 'error' event listener then throw.
2806
- if (type === 'error') {
2807
- if (!this._events || !this._events.error ||
2808
- (isArray(this._events.error) && !this._events.error.length))
2809
- {
2810
- if (arguments[1] instanceof Error) {
2811
- throw arguments[1]; // Unhandled 'error' event
2812
- } else {
2813
- throw new Error("Uncaught, unspecified 'error' event.");
2814
- }
2815
- return false;
2816
- }
2817
- }
2818
-
2819
- if (!this._events) return false;
2820
- var handler = this._events[type];
2821
- if (!handler) return false;
2822
-
2823
- if (typeof handler == 'function') {
2824
- switch (arguments.length) {
2825
- // fast cases
2826
- case 1:
2827
- handler.call(this);
2828
- break;
2829
- case 2:
2830
- handler.call(this, arguments[1]);
2831
- break;
2832
- case 3:
2833
- handler.call(this, arguments[1], arguments[2]);
2834
- break;
2835
- // slower
2836
- default:
2837
- var args = Array.prototype.slice.call(arguments, 1);
2838
- handler.apply(this, args);
2839
- }
2840
- return true;
2841
-
2842
- } else if (isArray(handler)) {
2843
- var args = Array.prototype.slice.call(arguments, 1);
2844
-
2845
- var listeners = handler.slice();
2846
- for (var i = 0, l = listeners.length; i < l; i++) {
2847
- listeners[i].apply(this, args);
2848
- }
2849
- return true;
2850
-
2851
- } else {
2852
- return false;
2853
- }
2854
- };
2855
-
2856
- // EventEmitter is defined in src/node_events.cc
2857
- // EventEmitter.prototype.emit() is also defined there.
2858
- EventEmitter.prototype.addListener = function(type, listener) {
2859
- if ('function' !== typeof listener) {
2860
- throw new Error('addListener only takes instances of Function');
2861
- }
2862
-
2863
- if (!this._events) this._events = {};
2864
-
2865
- // To avoid recursion in the case that type == "newListeners"! Before
2866
- // adding it to the listeners, first emit "newListeners".
2867
- this.emit('newListener', type, listener);
2868
-
2869
- if (!this._events[type]) {
2870
- // Optimize the case of one listener. Don't need the extra array object.
2871
- this._events[type] = listener;
2872
- } else if (isArray(this._events[type])) {
2873
- // If we've already got an array, just append.
2874
- this._events[type].push(listener);
2875
- } else {
2876
- // Adding the second element, need to change to array.
2877
- this._events[type] = [this._events[type], listener];
2878
- }
2879
-
2880
- return this;
2881
- };
2882
-
2883
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
2884
-
2885
- EventEmitter.prototype.once = function(type, listener) {
2886
- var self = this;
2887
- self.on(type, function g() {
2888
- self.removeListener(type, g);
2889
- listener.apply(this, arguments);
2890
- });
2891
-
2892
- return this;
2893
- };
2894
-
2895
- EventEmitter.prototype.removeListener = function(type, listener) {
2896
- if ('function' !== typeof listener) {
2897
- throw new Error('removeListener only takes instances of Function');
2898
- }
2899
-
2900
- // does not use listeners(), so no side effect of creating _events[type]
2901
- if (!this._events || !this._events[type]) return this;
2902
-
2903
- var list = this._events[type];
2904
-
2905
- if (isArray(list)) {
2906
- var i = indexOf(list, listener);
2907
- if (i < 0) return this;
2908
- list.splice(i, 1);
2909
- if (list.length == 0)
2910
- delete this._events[type];
2911
- } else if (this._events[type] === listener) {
2912
- delete this._events[type];
2913
- }
2914
-
2915
- return this;
2916
- };
2917
-
2918
- EventEmitter.prototype.removeAllListeners = function(type) {
2919
- if (arguments.length === 0) {
2920
- this._events = {};
2921
- return this;
2922
- }
2923
-
2924
- // does not use listeners(), so no side effect of creating _events[type]
2925
- if (type && this._events && this._events[type]) this._events[type] = null;
2926
- return this;
2927
- };
2928
-
2929
- EventEmitter.prototype.listeners = function(type) {
2930
- if (!this._events) this._events = {};
2931
- if (!this._events[type]) this._events[type] = [];
2932
- if (!isArray(this._events[type])) {
2933
- this._events[type] = [this._events[type]];
2934
- }
2935
- return this._events[type];
2936
- };
2937
-
2938
- },{}],33:[function(require,module,exports){
2939
- 'use strict';
2940
-
2941
- module.exports = function(dest, source, overwrite) {
2942
- if (!source) return dest;
2943
- for (var key in source) {
2944
- if (!source.hasOwnProperty(key)) continue;
2945
- if (dest.hasOwnProperty(key) && overwrite === false) continue;
2946
- if (dest[key] !== source[key])
2947
- dest[key] = source[key];
2948
- }
2949
- return dest;
2950
- };
2951
-
2952
- },{}],34:[function(require,module,exports){
2953
- 'use strict';
2954
-
2955
- var asap = require('asap');
2956
-
2957
- var PENDING = 0,
2958
- FULFILLED = 1,
2959
- REJECTED = 2;
2960
-
2961
- var RETURN = function(x) { return x },
2962
- THROW = function(x) { throw x };
2963
-
2964
- var Promise = function(task) {
2965
- this._state = PENDING;
2966
- this._onFulfilled = [];
2967
- this._onRejected = [];
2968
-
2969
- if (typeof task !== 'function') return;
2970
- var self = this;
2971
-
2972
- task(function(value) { resolve(self, value) },
2973
- function(reason) { reject(self, reason) });
2974
- };
2975
-
2976
- Promise.prototype.then = function(onFulfilled, onRejected) {
2977
- var next = new Promise();
2978
- registerOnFulfilled(this, onFulfilled, next);
2979
- registerOnRejected(this, onRejected, next);
2980
- return next;
2981
- };
2982
-
2983
- Promise.prototype['catch'] = function(onRejected) {
2984
- return this.then(null, onRejected);
2985
- };
2986
-
2987
- var registerOnFulfilled = function(promise, onFulfilled, next) {
2988
- if (typeof onFulfilled !== 'function') onFulfilled = RETURN;
2989
- var handler = function(value) { invoke(onFulfilled, value, next) };
2990
-
2991
- if (promise._state === PENDING) {
2992
- promise._onFulfilled.push(handler);
2993
- } else if (promise._state === FULFILLED) {
2994
- handler(promise._value);
2995
- }
2996
- };
2997
-
2998
- var registerOnRejected = function(promise, onRejected, next) {
2999
- if (typeof onRejected !== 'function') onRejected = THROW;
3000
- var handler = function(reason) { invoke(onRejected, reason, next) };
3001
-
3002
- if (promise._state === PENDING) {
3003
- promise._onRejected.push(handler);
3004
- } else if (promise._state === REJECTED) {
3005
- handler(promise._reason);
3006
- }
3007
- };
3008
-
3009
- var invoke = function(fn, value, next) {
3010
- asap(function() { _invoke(fn, value, next) });
3011
- };
3012
-
3013
- var _invoke = function(fn, value, next) {
3014
- var outcome;
3015
-
3016
- try {
3017
- outcome = fn(value);
3018
- } catch (error) {
3019
- return reject(next, error);
3020
- }
3021
-
3022
- if (outcome === next) {
3023
- reject(next, new TypeError('Recursive promise chain detected'));
3024
- } else {
3025
- resolve(next, outcome);
3026
- }
3027
- };
3028
-
3029
- var resolve = function(promise, value) {
3030
- var called = false, type, then;
3031
-
3032
- try {
3033
- type = typeof value;
3034
- then = value !== null && (type === 'function' || type === 'object') && value.then;
3035
-
3036
- if (typeof then !== 'function') return fulfill(promise, value);
3037
-
3038
- then.call(value, function(v) {
3039
- if (!(called ^ (called = true))) return;
3040
- resolve(promise, v);
3041
- }, function(r) {
3042
- if (!(called ^ (called = true))) return;
3043
- reject(promise, r);
3044
- });
3045
- } catch (error) {
3046
- if (!(called ^ (called = true))) return;
3047
- reject(promise, error);
3048
- }
3049
- };
3050
-
3051
- var fulfill = function(promise, value) {
3052
- if (promise._state !== PENDING) return;
3053
-
3054
- promise._state = FULFILLED;
3055
- promise._value = value;
3056
- promise._onRejected = [];
3057
-
3058
- var onFulfilled = promise._onFulfilled, fn;
3059
- while (fn = onFulfilled.shift()) fn(value);
3060
- };
3061
-
3062
- var reject = function(promise, reason) {
3063
- if (promise._state !== PENDING) return;
3064
-
3065
- promise._state = REJECTED;
3066
- promise._reason = reason;
3067
- promise._onFulfilled = [];
3068
-
3069
- var onRejected = promise._onRejected, fn;
3070
- while (fn = onRejected.shift()) fn(reason);
3071
- };
3072
-
3073
- Promise.resolve = function(value) {
3074
- return new Promise(function(resolve, reject) { resolve(value) });
3075
- };
3076
-
3077
- Promise.reject = function(reason) {
3078
- return new Promise(function(resolve, reject) { reject(reason) });
3079
- };
3080
-
3081
- Promise.all = function(promises) {
3082
- return new Promise(function(resolve, reject) {
3083
- var list = [], n = promises.length, i;
3084
-
3085
- if (n === 0) return resolve(list);
3086
-
3087
- for (i = 0; i < n; i++) (function(promise, i) {
3088
- Promise.resolve(promise).then(function(value) {
3089
- list[i] = value;
3090
- if (--n === 0) resolve(list);
3091
- }, reject);
3092
- })(promises[i], i);
3093
- });
3094
- };
3095
-
3096
- Promise.race = function(promises) {
3097
- return new Promise(function(resolve, reject) {
3098
- for (var i = 0, n = promises.length; i < n; i++)
3099
- Promise.resolve(promises[i]).then(resolve, reject);
3100
- });
3101
- };
3102
-
3103
- Promise.deferred = Promise.pending = function() {
3104
- var tuple = {};
3105
-
3106
- tuple.promise = new Promise(function(resolve, reject) {
3107
- tuple.resolve = resolve;
3108
- tuple.reject = reject;
3109
- });
3110
- return tuple;
3111
- };
3112
-
3113
- module.exports = Promise;
3114
-
3115
- },{"asap":3}],35:[function(require,module,exports){
3116
- 'use strict';
3117
-
3118
- var Class = require('./class');
3119
-
3120
- module.exports = Class({
3121
- initialize: function() {
3122
- this._index = {};
3123
- },
3124
-
3125
- add: function(item) {
3126
- var key = (item.id !== undefined) ? item.id : item;
3127
- if (this._index.hasOwnProperty(key)) return false;
3128
- this._index[key] = item;
3129
- return true;
3130
- },
3131
-
3132
- forEach: function(block, context) {
3133
- for (var key in this._index) {
3134
- if (this._index.hasOwnProperty(key))
3135
- block.call(context, this._index[key]);
3136
- }
3137
- },
3138
-
3139
- isEmpty: function() {
3140
- for (var key in this._index) {
3141
- if (this._index.hasOwnProperty(key)) return false;
3142
- }
3143
- return true;
3144
- },
3145
-
3146
- member: function(item) {
3147
- for (var key in this._index) {
3148
- if (this._index[key] === item) return true;
3149
- }
3150
- return false;
3151
- },
3152
-
3153
- remove: function(item) {
3154
- var key = (item.id !== undefined) ? item.id : item;
3155
- var removed = this._index[key];
3156
- delete this._index[key];
3157
- return removed;
3158
- },
3159
-
3160
- toArray: function() {
3161
- var array = [];
3162
- this.forEach(function(item) { array.push(item) });
3163
- return array;
3164
- }
3165
- });
3166
-
3167
- },{"./class":28}],36:[function(require,module,exports){
3168
- 'use strict';
3169
-
3170
- // http://assanka.net/content/tech/2009/09/02/json2-js-vs-prototype/
3171
-
3172
- module.exports = function(object) {
3173
- return JSON.stringify(object, function(key, value) {
3174
- return (this[key] instanceof Array) ? this[key] : value;
3175
- });
3176
- };
3177
-
3178
- },{}],37:[function(require,module,exports){
3179
- 'use strict';
3180
-
3181
- module.exports = {
3182
- isURI: function(uri) {
3183
- return uri && uri.protocol && uri.host && uri.path;
3184
- },
3185
-
3186
- isSameOrigin: function(uri) {
3187
- return uri.protocol === location.protocol &&
3188
- uri.hostname === location.hostname &&
3189
- uri.port === location.port;
3190
- },
3191
-
3192
- parse: function(url) {
3193
- if (typeof url !== 'string') return url;
3194
- var uri = {}, parts, query, pairs, i, n, data;
3195
-
3196
- var consume = function(name, pattern) {
3197
- url = url.replace(pattern, function(match) {
3198
- uri[name] = match;
3199
- return '';
3200
- });
3201
- uri[name] = uri[name] || '';
3202
- };
3203
-
3204
- consume('protocol', /^[a-z]+\:/i);
3205
- consume('host', /^\/\/[^\/\?#]+/);
3206
-
3207
- if (!/^\//.test(url) && !uri.host)
3208
- url = location.pathname.replace(/[^\/]*$/, '') + url;
3209
-
3210
- consume('pathname', /^[^\?#]*/);
3211
- consume('search', /^\?[^#]*/);
3212
- consume('hash', /^#.*/);
3213
-
3214
- uri.protocol = uri.protocol || location.protocol;
3215
-
3216
- if (uri.host) {
3217
- uri.host = uri.host.substr(2);
3218
- parts = uri.host.split(':');
3219
- uri.hostname = parts[0];
3220
- uri.port = parts[1] || '';
3221
- } else {
3222
- uri.host = location.host;
3223
- uri.hostname = location.hostname;
3224
- uri.port = location.port;
3225
- }
3226
-
3227
- uri.pathname = uri.pathname || '/';
3228
- uri.path = uri.pathname + uri.search;
3229
-
3230
- query = uri.search.replace(/^\?/, '');
3231
- pairs = query ? query.split('&') : [];
3232
- data = {};
3233
-
3234
- for (i = 0, n = pairs.length; i < n; i++) {
3235
- parts = pairs[i].split('=');
3236
- data[decodeURIComponent(parts[0] || '')] = decodeURIComponent(parts[1] || '');
3237
- }
3238
-
3239
- uri.query = data;
3240
-
3241
- uri.href = this.stringify(uri);
3242
- return uri;
3243
- },
3244
-
3245
- stringify: function(uri) {
3246
- var string = uri.protocol + '//' + uri.hostname;
3247
- if (uri.port) string += ':' + uri.port;
3248
- string += uri.pathname + this.queryString(uri.query) + (uri.hash || '');
3249
- return string;
3250
- },
3251
-
3252
- queryString: function(query) {
3253
- var pairs = [];
3254
- for (var key in query) {
3255
- if (!query.hasOwnProperty(key)) continue;
3256
- pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(query[key]));
3257
- }
3258
- if (pairs.length === 0) return '';
3259
- return '?' + pairs.join('&');
3260
- }
3261
- };
3262
-
3263
- },{}],38:[function(require,module,exports){
3264
- 'use strict';
3265
-
3266
- var array = require('./array');
3267
-
3268
- module.exports = function(options, validKeys) {
3269
- for (var key in options) {
3270
- if (array.indexOf(validKeys, key) < 0)
3271
- throw new Error('Unrecognized option: ' + key);
3272
- }
3273
- };
3274
-
3275
- },{"./array":26}],39:[function(require,module,exports){
3276
- (function (global){
3277
- 'use strict';
3278
-
3279
- var WS = global.MozWebSocket || global.WebSocket;
3280
-
3281
- module.exports = {
3282
- create: function(url, protocols, options) {
3283
- if (typeof WS !== 'function') return null;
3284
- return new WS(url);
3285
- }
3286
- };
3287
-
3288
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3289
-
3290
- },{}],40:[function(require,module,exports){
3291
- // shim for using process in browser
3292
- var process = module.exports = {};
3293
-
3294
- // cached from whatever global is present so that test runners that stub it
3295
- // don't break things. But we need to wrap it in a try catch in case it is
3296
- // wrapped in strict mode code which doesn't define any globals. It's inside a
3297
- // function because try/catches deoptimize in certain engines.
3298
-
3299
- var cachedSetTimeout;
3300
- var cachedClearTimeout;
3301
-
3302
- function defaultSetTimout() {
3303
- throw new Error('setTimeout has not been defined');
3304
- }
3305
- function defaultClearTimeout () {
3306
- throw new Error('clearTimeout has not been defined');
3307
- }
3308
- (function () {
3309
- try {
3310
- if (typeof setTimeout === 'function') {
3311
- cachedSetTimeout = setTimeout;
3312
- } else {
3313
- cachedSetTimeout = defaultSetTimout;
3314
- }
3315
- } catch (e) {
3316
- cachedSetTimeout = defaultSetTimout;
3317
- }
3318
- try {
3319
- if (typeof clearTimeout === 'function') {
3320
- cachedClearTimeout = clearTimeout;
3321
- } else {
3322
- cachedClearTimeout = defaultClearTimeout;
3323
- }
3324
- } catch (e) {
3325
- cachedClearTimeout = defaultClearTimeout;
3326
- }
3327
- } ())
3328
- function runTimeout(fun) {
3329
- if (cachedSetTimeout === setTimeout) {
3330
- //normal enviroments in sane situations
3331
- return setTimeout(fun, 0);
3332
- }
3333
- // if setTimeout wasn't available but was latter defined
3334
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
3335
- cachedSetTimeout = setTimeout;
3336
- return setTimeout(fun, 0);
3337
- }
3338
- try {
3339
- // when when somebody has screwed with setTimeout but no I.E. maddness
3340
- return cachedSetTimeout(fun, 0);
3341
- } catch(e){
3342
- try {
3343
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
3344
- return cachedSetTimeout.call(null, fun, 0);
3345
- } catch(e){
3346
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
3347
- return cachedSetTimeout.call(this, fun, 0);
3348
- }
3349
- }
3350
-
3351
-
3352
- }
3353
- function runClearTimeout(marker) {
3354
- if (cachedClearTimeout === clearTimeout) {
3355
- //normal enviroments in sane situations
3356
- return clearTimeout(marker);
3357
- }
3358
- // if clearTimeout wasn't available but was latter defined
3359
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
3360
- cachedClearTimeout = clearTimeout;
3361
- return clearTimeout(marker);
3362
- }
3363
- try {
3364
- // when when somebody has screwed with setTimeout but no I.E. maddness
3365
- return cachedClearTimeout(marker);
3366
- } catch (e){
3367
- try {
3368
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
3369
- return cachedClearTimeout.call(null, marker);
3370
- } catch (e){
3371
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
3372
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
3373
- return cachedClearTimeout.call(this, marker);
3374
- }
3375
- }
3376
-
3377
-
3378
-
3379
- }
3380
- var queue = [];
3381
- var draining = false;
3382
- var currentQueue;
3383
- var queueIndex = -1;
3384
-
3385
- function cleanUpNextTick() {
3386
- if (!draining || !currentQueue) {
3387
- return;
3388
- }
3389
- draining = false;
3390
- if (currentQueue.length) {
3391
- queue = currentQueue.concat(queue);
3392
- } else {
3393
- queueIndex = -1;
3394
- }
3395
- if (queue.length) {
3396
- drainQueue();
3397
- }
3398
- }
3399
-
3400
- function drainQueue() {
3401
- if (draining) {
3402
- return;
3403
- }
3404
- var timeout = runTimeout(cleanUpNextTick);
3405
- draining = true;
3406
-
3407
- var len = queue.length;
3408
- while(len) {
3409
- currentQueue = queue;
3410
- queue = [];
3411
- while (++queueIndex < len) {
3412
- if (currentQueue) {
3413
- currentQueue[queueIndex].run();
3414
- }
3415
- }
3416
- queueIndex = -1;
3417
- len = queue.length;
3418
- }
3419
- currentQueue = null;
3420
- draining = false;
3421
- runClearTimeout(timeout);
3422
- }
3423
-
3424
- process.nextTick = function (fun) {
3425
- var args = new Array(arguments.length - 1);
3426
- if (arguments.length > 1) {
3427
- for (var i = 1; i < arguments.length; i++) {
3428
- args[i - 1] = arguments[i];
3429
- }
3430
- }
3431
- queue.push(new Item(fun, args));
3432
- if (queue.length === 1 && !draining) {
3433
- runTimeout(drainQueue);
3434
- }
3435
- };
3436
-
3437
- // v8 likes predictible objects
3438
- function Item(fun, array) {
3439
- this.fun = fun;
3440
- this.array = array;
3441
- }
3442
- Item.prototype.run = function () {
3443
- this.fun.apply(null, this.array);
3444
- };
3445
- process.title = 'browser';
3446
- process.browser = true;
3447
- process.env = {};
3448
- process.argv = [];
3449
- process.version = ''; // empty string to avoid regexp issues
3450
- process.versions = {};
3451
-
3452
- function noop() {}
3453
-
3454
- process.on = noop;
3455
- process.addListener = noop;
3456
- process.once = noop;
3457
- process.off = noop;
3458
- process.removeListener = noop;
3459
- process.removeAllListeners = noop;
3460
- process.emit = noop;
3461
- process.prependListener = noop;
3462
- process.prependOnceListener = noop;
3463
-
3464
- process.listeners = function (name) { return [] }
3465
-
3466
- process.binding = function (name) {
3467
- throw new Error('process.binding is not supported');
3468
- };
3469
-
3470
- process.cwd = function () { return '/' };
3471
- process.chdir = function (dir) {
3472
- throw new Error('process.chdir is not supported');
3473
- };
3474
- process.umask = function() { return 0; };
3475
-
3476
- },{}]},{},[2])(2)
3477
- });
3478
-
3479
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvYXBpL3N0cmVhbWluZy1leHRlbnNpb24uanMiLCJsaWIvYXBpL3N0cmVhbWluZy5qcyIsIm5vZGVfbW9kdWxlcy9hc2FwL2Jyb3dzZXItYXNhcC5qcyIsIm5vZGVfbW9kdWxlcy9hc2FwL2Jyb3dzZXItcmF3LmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL2ZheWVfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9taXhpbnMvZGVmZXJyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9taXhpbnMvbG9nZ2luZy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9taXhpbnMvcHVibGlzaGVyLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL21peGlucy90aW1lb3V0cy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9jaGFubmVsLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3Byb3RvY29sL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9kaXNwYXRjaGVyLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3Byb3RvY29sL2Vycm9yLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3Byb3RvY29sL2V4dGVuc2libGUuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvcHJvdG9jb2wvZ3JhbW1hci5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9wdWJsaWNhdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy9wcm90b2NvbC9zY2hlZHVsZXIuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvcHJvdG9jb2wvc3Vic2NyaXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3RyYW5zcG9ydC9icm93c2VyX3RyYW5zcG9ydHMuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdHJhbnNwb3J0L2NvcnMuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdHJhbnNwb3J0L2V2ZW50X3NvdXJjZS5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy90cmFuc3BvcnQvanNvbnAuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdHJhbnNwb3J0L3RyYW5zcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy90cmFuc3BvcnQvd2ViX3NvY2tldC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy90cmFuc3BvcnQveGhyLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvYXJyYXkuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9icm93c2VyL2V2ZW50LmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvY2xhc3MuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9jb25zdGFudHMuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9jb29raWVzL2Jyb3dzZXJfY29va2llcy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL2NvcHlfb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvZXZlbnRfZW1pdHRlci5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL2V4dGVuZC5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL3Byb21pc2UuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC9zZXQuanMiLCJub2RlX21vZHVsZXMvZmF5ZS9zcmMvdXRpbC90b19qc29uLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvdXJpLmpzIiwibm9kZV9tb2R1bGVzL2ZheWUvc3JjL3V0aWwvdmFsaWRhdGVfb3B0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9mYXllL3NyYy91dGlsL3dlYnNvY2tldC9icm93c2VyX3dlYnNvY2tldC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbFlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbk5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNqS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8qKlxuICogRmF5ZSBDbGllbnQgZXh0ZW5zaW9uczogaHR0cHM6Ly9mYXllLmpjb2dsYW4uY29tL2Jyb3dzZXIvZXh0ZW5zaW9ucy5odG1sXG4gKlxuICogRm9yIHVzZSB3aXRoIFN0cmVhbWluZy5wcm90b3R5cGUuY3JlYXRlQ2xpZW50KClcbioqL1xudmFyIFN0cmVhbWluZ0V4dGVuc2lvbiA9IHt9O1xuXG4vKipcbiAqIENvbnN0cnVjdG9yIGZvciBhbiBhdXRoIGZhaWx1cmUgZGV0ZWN0b3IgZXh0ZW5zaW9uXG4gKlxuICogQmFzZWQgb24gbmV3IGZlYXR1cmUgcmVsZWFzZWQgd2l0aCBTYWxlc2ZvcmNlIFNwcmluZyAnMTg6XG4gKiBodHRwczovL3JlbGVhc2Vub3Rlcy5kb2NzLnNhbGVzZm9yY2UuY29tL2VuLXVzL3NwcmluZzE4L3JlbGVhc2Utbm90ZXMvcm5fbWVzc2FnaW5nX2NvbWV0ZF9hdXRoX3ZhbGlkYXRpb24uaHRtP2VkaXRpb249JmltcGFjdD1cbiAqXG4gKiBFeGFtcGxlIHRyaWdnZXJpbmcgZXJyb3IgbWVzc2FnZTpcbiAqXG4gKiBgYGBcbiAqIHtcbiAqICAgXCJleHRcIjp7XG4gKiAgICAgXCJzZmRjXCI6e1wiZmFpbHVyZVJlYXNvblwiOlwiNDAxOjpBdXRoZW50aWNhdGlvbiBpbnZhbGlkXCJ9LFxuICogICAgIFwicmVwbGF5XCI6dHJ1ZX0sXG4gKiAgIFwiYWR2aWNlXCI6e1wicmVjb25uZWN0XCI6XCJub25lXCJ9LFxuICogICBcImNoYW5uZWxcIjpcIi9tZXRhL2hhbmRzaGFrZVwiLFxuICogICBcImVycm9yXCI6XCI0MDM6OkhhbmRzaGFrZSBkZW5pZWRcIixcbiAqICAgXCJzdWNjZXNzZnVsXCI6ZmFsc2VcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEV4YW1wbGUgdXNhZ2U6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogY29uc3QgY29ubiA9IG5ldyBqc2ZvcmNlLkNvbm5lY3Rpb24oeyDigKYgfSk7XG4gKiBcbiAqIGNvbnN0IGNoYW5uZWwgPSBcIi9ldmVudC9NeV9FdmVudF9fZVwiO1xuICogXG4gKiAvLyBFeGl0IHRoZSBOb2RlIHByb2Nlc3Mgd2hlbiBhdXRoIGZhaWxzXG4gKiBjb25zdCBleGl0Q2FsbGJhY2sgPSAoKSA9PiBwcm9jZXNzLmV4aXQoMSk7XG4gKiBjb25zdCBhdXRoRmFpbHVyZUV4dCA9IG5ldyBqc2ZvcmNlLlN0cmVhbWluZ0V4dGVuc2lvbi5BdXRoRmFpbHVyZShleGl0Q2FsbGJhY2spO1xuICogXG4gKiBjb25zdCBmYXllQ2xpZW50ID0gY29ubi5zdHJlYW1pbmcuY3JlYXRlQ2xpZW50KFsgYXV0aEZhaWx1cmVFeHQgXSk7XG4gKiBcbiAqIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGZheWVDbGllbnQuc3Vic2NyaWJlKGNoYW5uZWwsIGRhdGEgPT4ge1xuICogICBjb25zb2xlLmxvZygndG9waWMgcmVjZWl2ZWQgZGF0YScsIGRhdGEpO1xuICogfSk7XG4gKiBcbiAqIHN1YnNjcmlwdGlvbi5jYW5jZWwoKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZhaWx1cmVDYWxsYmFjayAtIEludm9rZWQgd2hlbiBhdXRoZW50aWNhdGlvbiBiZWNvbWVzIGludmFsaWRcbiAqL1xuU3RyZWFtaW5nRXh0ZW5zaW9uLkF1dGhGYWlsdXJlID0gZnVuY3Rpb24oZmFpbHVyZUNhbGxiYWNrKSB7XG4gIHRoaXMuaW5jb21pbmcgPSBmdW5jdGlvbihtZXNzYWdlLCBjYWxsYmFjaykge1xuICAgIGlmIChcbiAgICAgIChtZXNzYWdlLmNoYW5uZWwgPT09ICcvbWV0YS9jb25uZWN0JyB8fFxuICAgICAgICBtZXNzYWdlLmNoYW5uZWwgPT09ICcvbWV0YS9oYW5kc2hha2UnKVxuICAgICAgJiYgbWVzc2FnZS5hZHZpY2VcbiAgICAgICYmIG1lc3NhZ2UuYWR2aWNlLnJlY29ubmVjdCA9PSAnbm9uZSdcbiAgICApIHtcbiAgICAgIGZhaWx1cmVDYWxsYmFjayhtZXNzYWdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbGJhY2sobWVzc2FnZSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIENvbnN0cnVjdG9yIGZvciBhIGR1cmFibGUgc3RyZWFtaW5nIHJlcGxheSBleHRlbnNpb25cbiAqXG4gKiBNb2RpZmllZCBmcm9tIG9yaWdpbmFsIFNhbGVzZm9yY2UgZGVtbyBzb3VyY2UgY29kZTpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9kZXZlbG9wZXJmb3JjZS9TYWxlc2ZvcmNlRHVyYWJsZVN0cmVhbWluZ0RlbW8vYmxvYi8zZDRhNTZlYWM5NTZmNzQ0YWQ2YzIyZTZhODE0MWI2ZmViNTdhYmI5L3N0YXRpY3Jlc291cmNlcy9jb21ldGRSZXBsYXlFeHRlbnNpb24ucmVzb3VyY2VcbiAqIFxuICogRXhhbXBsZSB1c2FnZTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBjb25zdCBjb25uID0gbmV3IGpzZm9yY2UuQ29ubmVjdGlvbih7IOKApiB9KTtcbiAqIFxuICogY29uc3QgY2hhbm5lbCA9IFwiL2V2ZW50L015X0V2ZW50X19lXCI7XG4gKiBjb25zdCByZXBsYXlJZCA9IC0yOyAvLyAtMiBpcyBhbGwgcmV0YWluZWQgZXZlbnRzXG4gKiBcbiAqIGNvbnN0IHJlcGxheUV4dCA9IG5ldyBqc2ZvcmNlLlN0cmVhbWluZ0V4dGVuc2lvbi5SZXBsYXkoY2hhbm5lbCwgcmVwbGF5SWQpO1xuICogXG4gKiBjb25zdCBmYXllQ2xpZW50ID0gY29ubi5zdHJlYW1pbmcuY3JlYXRlQ2xpZW50KFsgcmVwbGF5RXh0IF0pO1xuICogXG4gKiBjb25zdCBzdWJzY3JpcHRpb24gPSBmYXllQ2xpZW50LnN1YnNjcmliZShjaGFubmVsLCBkYXRhID0+IHtcbiAqICAgY29uc29sZS5sb2coJ3RvcGljIHJlY2VpdmVkIGRhdGEnLCBkYXRhKTtcbiAqIH0pO1xuICogXG4gKiBzdWJzY3JpcHRpb24uY2FuY2VsKCk7XG4gKiBgYGBcbiAqL1xuU3RyZWFtaW5nRXh0ZW5zaW9uLlJlcGxheSA9IGZ1bmN0aW9uKGNoYW5uZWwsIHJlcGxheUlkKSB7XG4gIHZhciBSRVBMQVlfRlJPTV9LRVkgPSBcInJlcGxheVwiO1xuICBcbiAgdmFyIF9leHRlbnNpb25FbmFibGVkID0gcmVwbGF5SWQgIT0gbnVsbCA/IHRydWUgOiBmYWxzZTtcbiAgdmFyIF9yZXBsYXkgPSByZXBsYXlJZDtcbiAgdmFyIF9jaGFubmVsID0gY2hhbm5lbDtcblxuICB0aGlzLnNldEV4dGVuc2lvbkVuYWJsZWQgPSBmdW5jdGlvbihleHRlbnNpb25FbmFibGVkKSB7XG4gICAgX2V4dGVuc2lvbkVuYWJsZWQgPSBleHRlbnNpb25FbmFibGVkO1xuICB9XG5cbiAgdGhpcy5zZXRSZXBsYXkgPSBmdW5jdGlvbiAocmVwbGF5KSB7XG4gICAgX3JlcGxheSA9IHBhcnNlSW50KHJlcGxheSwgMTApO1xuICB9XG5cbiAgdGhpcy5zZXRDaGFubmVsID0gZnVuY3Rpb24oY2hhbm5lbCkge1xuICAgIF9jaGFubmVsID0gY2hhbm5lbDtcbiAgfVxuXG4gIHRoaXMuaW5jb21pbmcgPSBmdW5jdGlvbihtZXNzYWdlLCBjYWxsYmFjaykge1xuICAgIGlmIChtZXNzYWdlLmNoYW5uZWwgPT09ICcvbWV0YS9oYW5kc2hha2UnKSB7XG4gICAgICBpZiAobWVzc2FnZS5leHQgJiYgbWVzc2FnZS5leHRbUkVQTEFZX0ZST01fS0VZXSA9PSB0cnVlKSB7XG4gICAgICAgIF9leHRlbnNpb25FbmFibGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG1lc3NhZ2UuY2hhbm5lbCA9PT0gX2NoYW5uZWwgJiYgbWVzc2FnZS5kYXRhICYmIG1lc3NhZ2UuZGF0YS5ldmVudCAmJiBtZXNzYWdlLmRhdGEuZXZlbnQucmVwbGF5SWQpIHtcbiAgICAgIF9yZXBsYXkgPSBtZXNzYWdlLmRhdGEuZXZlbnQucmVwbGF5SWQ7XG4gICAgfVxuICAgIGNhbGxiYWNrKG1lc3NhZ2UpO1xuICB9XG4gIFxuICB0aGlzLm91dGdvaW5nID0gZnVuY3Rpb24obWVzc2FnZSwgY2FsbGJhY2spIHtcbiAgICBpZiAobWVzc2FnZS5jaGFubmVsID09PSAnL21ldGEvc3Vic2NyaWJlJyAmJiBtZXNzYWdlLnN1YnNjcmlwdGlvbiA9PT0gX2NoYW5uZWwpIHtcbiAgICAgIGlmIChfZXh0ZW5zaW9uRW5hYmxlZCkge1xuICAgICAgICBpZiAoIW1lc3NhZ2UuZXh0KSB7IG1lc3NhZ2UuZXh0ID0ge307IH1cblxuICAgICAgICB2YXIgcmVwbGF5RnJvbU1hcCA9IHt9O1xuICAgICAgICByZXBsYXlGcm9tTWFwW19jaGFubmVsXSA9IF9yZXBsYXk7XG5cbiAgICAgICAgLy8gYWRkIFwiZXh0IDogeyBcInJlcGxheVwiIDogeyBDSEFOTkVMIDogUkVQTEFZX1ZBTFVFIH19XCIgdG8gc3Vic2NyaWJlIG1lc3NhZ2VcbiAgICAgICAgbWVzc2FnZS5leHRbUkVQTEFZX0ZST01fS0VZXSA9IHJlcGxheUZyb21NYXA7XG4gICAgICB9XG4gICAgfVxuICAgIGNhbGxiYWNrKG1lc3NhZ2UpO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1pbmdFeHRlbnNpb247XG4iLCIvKipcbiAqIEBmaWxlIE1hbmFnZXMgU3RyZWFtaW5nIEFQSXNcbiAqIEBhdXRob3IgU2hpbmljaGkgVG9taXRhIDxzaGluaWNoaS50b21pdGFAZ21haWwuY29tPlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGV2ZW50cyA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJ2V2ZW50cycpLFxuICAgIGluaGVyaXRzID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnaW5oZXJpdHMnKSxcbiAgICBfID0gd2luZG93LmpzZm9yY2UucmVxdWlyZSgnbG9kYXNoL2NvcmUnKSxcbiAgICBGYXllICAgPSByZXF1aXJlKCdmYXllJyksXG4gICAgU3RyZWFtaW5nRXh0ZW5zaW9uID0gcmVxdWlyZSgnLi9zdHJlYW1pbmctZXh0ZW5zaW9uJyksXG4gICAganNmb3JjZSA9IHdpbmRvdy5qc2ZvcmNlLnJlcXVpcmUoJy4vY29yZScpO1xuXG4vKipcbiAqIFN0cmVhbWluZyBBUEkgdG9waWMgY2xhc3NcbiAqXG4gKiBAY2xhc3MgU3RyZWFtaW5nflRvcGljXG4gKiBAcGFyYW0ge1N0cmVhbWluZ30gc3RlYW1pbmcgLSBTdHJlYW1pbmcgQVBJIG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKi9cbnZhciBUb3BpYyA9IGZ1bmN0aW9uKHN0cmVhbWluZywgbmFtZSkge1xuICB0aGlzLl9zdHJlYW1pbmcgPSBzdHJlYW1pbmc7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFN0cmVhbWluZ35TdHJlYW1pbmdNZXNzYWdlXG4gKiBAcHJvcCB7T2JqZWN0fSBldmVudFxuICogQHByb3Age09iamVjdH0gZXZlbnQudHlwZSAtIEV2ZW50IHR5cGVcbiAqIEBwcm9wIHtSZWNvcmR9IHNvYmplY3QgLSBSZWNvcmQgaW5mb3JtYXRpb25cbiAqL1xuLyoqXG4gKiBTdWJzY3JpYmUgbGlzdGVuZXIgdG8gdG9waWNcbiAqXG4gKiBAbWV0aG9kIFN0cmVhbWluZ35Ub3BpYyNzdWJzY3JpYmVcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPFN0cmVhbWluZ35TdHJlYW1pbmdNZXNhc2dlPn0gbGlzdGVuZXIgLSBTdHJlYW1pbmcgbWVzc2FnZSBsaXN0ZW5lclxuICogQHJldHVybnMge1N1YnNjcmlwdGlvbn0gLSBGYXllIHN1YnNjcmlwdGlvbiBvYmplY3RcbiAqL1xuVG9waWMucHJvdG90eXBlLnN1YnNjcmliZSA9IGZ1bmN0aW9uKGxpc3RlbmVyKSB7XG4gIHJldHVybiB0aGlzLl9zdHJlYW1pbmcuc3Vic2NyaWJlKHRoaXMubmFtZSwgbGlzdGVuZXIpO1xufTtcblxuLyoqXG4gKiBVbnN1YnNjcmliZSBsaXN0ZW5lciBmcm9tIHRvcGljXG4gKlxuICogQG1ldGhvZCBTdHJlYW1pbmd+VG9waWMjdW5zdWJzY3JpYmVcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPFN0cmVhbWluZ35TdHJlYW1pbmdNZXNhc2dlPn0gbGlzdGVuZXIgLSBTdHJlYW1pbmcgbWVzc2FnZSBsaXN0ZW5lclxuICogQHJldHVybnMge1N0cmVhbWluZ35Ub3BpY31cbiAqL1xuVG9waWMucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24obGlzdGVuZXIpIHtcbiAgdGhpcy5fc3RyZWFtaW5nLnVuc3Vic2NyaWJlKHRoaXMubmFtZSwgbGlzdGVuZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4vKipcbiAqIFN0cmVhbWluZyBBUEkgR2VuZXJpYyBTdHJlYW1pbmcgQ2hhbm5lbFxuICpcbiAqIEBjbGFzcyBTdHJlYW1pbmd+Q2hhbm5lbFxuICogQHBhcmFtIHtTdHJlYW1pbmd9IHN0ZWFtaW5nIC0gU3RyZWFtaW5nIEFQSSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIC0gQ2hhbm5lbCBuYW1lIChzdGFydHMgd2l0aCBcIi91L1wiKVxuICovXG52YXIgQ2hhbm5lbCA9IGZ1bmN0aW9uKHN0cmVhbWluZywgbmFtZSkge1xuICB0aGlzLl9zdHJlYW1pbmcgPSBzdHJlYW1pbmc7XG4gIHRoaXMuX25hbWUgPSBuYW1lO1xufTtcblxuLyoqXG4gKiBTdWJzY3JpYmUgdG8gY2hhbm5lbFxuICpcbiAqIEBwYXJhbSB7Q2FsbGJhY2suPFN0cmVhbWluZ35TdHJlYW1pbmdNZXNzYWdlPn0gbGlzdGVuZXIgLSBTdHJlYW1pbmcgbWVzc2FnZSBsaXN0ZW5lclxuICogQHJldHVybnMge1N1YnNjcmlwdGlvbn0gLSBGYXllIHN1YnNjcmlwdGlvbiBvYmplY3RcbiAqL1xuQ2hhbm5lbC5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24obGlzdGVuZXIpIHtcbiAgcmV0dXJuIHRoaXMuX3N0cmVhbWluZy5zdWJzY3JpYmUodGhpcy5fbmFtZSwgbGlzdGVuZXIpO1xufTtcblxuQ2hhbm5lbC5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbihsaXN0ZW5lcikge1xuICB0aGlzLl9zdHJlYW1pbmcudW5zdWJzY3JpYmUodGhpcy5fbmFtZSwgbGlzdGVuZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkNoYW5uZWwucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbihldmVudHMsIGNhbGxiYWNrKSB7XG4gIHZhciBpc0FycmF5ID0gXy5pc0FycmF5KGV2ZW50cyk7XG4gIGV2ZW50cyA9IGlzQXJyYXkgPyBldmVudHMgOiBbIGV2ZW50cyBdO1xuICB2YXIgY29ubiA9IHRoaXMuX3N0cmVhbWluZy5fY29ubjtcbiAgaWYgKCF0aGlzLl9pZCkge1xuICAgIHRoaXMuX2lkID0gY29ubi5zb2JqZWN0KCdTdHJlYW1pbmdDaGFubmVsJykuZmluZE9uZSh7IE5hbWU6IHRoaXMuX25hbWUgfSwgJ0lkJylcbiAgICAgIC50aGVuKGZ1bmN0aW9uKHJlYykgeyByZXR1cm4gcmVjLklkIH0pO1xuICB9XG4gIHJldHVybiB0aGlzLl9pZC50aGVuKGZ1bmN0aW9uKGlkKSB7XG4gICAgdmFyIGNoYW5uZWxVcmwgPSAnL3NvYmplY3RzL1N0cmVhbWluZ0NoYW5uZWwvJyArIGlkICsgJy9wdXNoJztcbiAgICByZXR1cm4gY29ubi5yZXF1ZXN0UG9zdChjaGFubmVsVXJsLCB7IHB1c2hFdmVudHM6IGV2ZW50cyB9KTtcbiAgfSkudGhlbihmdW5jdGlvbihyZXRzKSB7XG4gICAgcmV0dXJuIGlzQXJyYXkgPyByZXRzIDogcmV0c1swXTtcbiAgfSkudGhlbkNhbGwoY2FsbGJhY2spO1xufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbi8qKlxuICogU3RyZWFtaW5nIEFQSSBjbGFzc1xuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlclxuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uIC0gQ29ubmVjdGlvbiBvYmplY3RcbiAqL1xudmFyIFN0cmVhbWluZyA9IGZ1bmN0aW9uKGNvbm4pIHtcbiAgdGhpcy5fY29ubiA9IGNvbm47XG59O1xuXG5pbmhlcml0cyhTdHJlYW1pbmcsIGV2ZW50cy5FdmVudEVtaXR0ZXIpO1xuXG4vKiogQHByaXZhdGUgKiovXG5TdHJlYW1pbmcucHJvdG90eXBlLl9jcmVhdGVDbGllbnQgPSBmdW5jdGlvbihmb3JDaGFubmVsTmFtZSwgZXh0ZW5zaW9ucykge1xuICAvLyBmb3JDaGFubmVsTmFtZSBpcyBhZHZpc29yeSwgZm9yIGFuIEFQSSB3b3JrYXJvdW5kLiBJdCBkb2VzIG5vdCByZXN0cmljdCBvciBzZWxlY3QgdGhlIGNoYW5uZWwuXG4gIHZhciBuZWVkc1JlcGxheUZpeCA9IHR5cGVvZiBmb3JDaGFubmVsTmFtZSA9PT0gJ3N0cmluZycgJiYgZm9yQ2hhbm5lbE5hbWUuaW5kZXhPZignL3UvJykgPT09IDA7XG4gIHZhciBlbmRwb2ludFVybCA9IFtcbiAgICB0aGlzLl9jb25uLmluc3RhbmNlVXJsLFxuICAgIC8vIHNwZWNpYWwgZW5kcG9pbnQgXCIvY29tZXRkL3JlcGxheS94eC54XCIgaXMgb25seSBhdmFpbGFibGUgaW4gMzYuMC5cbiAgICAvLyBTZWUgaHR0cHM6Ly9yZWxlYXNlbm90ZXMuZG9jcy5zYWxlc2ZvcmNlLmNvbS9lbi11cy9zdW1tZXIxNi9yZWxlYXNlLW5vdGVzL3JuX2FwaV9zdHJlYW1pbmdfY2xhc3NpY19yZXBsYXkuaHRtXG4gICAgXCJjb21ldGRcIiArIChuZWVkc1JlcGxheUZpeCA9PT0gdHJ1ZSAmJiB0aGlzLl9jb25uLnZlcnNpb24gPT09IFwiMzYuMFwiID8gXCIvcmVwbGF5XCIgOiBcIlwiKSxcbiAgICB0aGlzLl9jb25uLnZlcnNpb25cbiAgXS5qb2luKCcvJyk7XG4gIHZhciBmYXllQ2xpZW50ID0gbmV3IEZheWUuQ2xpZW50KGVuZHBvaW50VXJsLCB7fSk7XG4gIGZheWVDbGllbnQuc2V0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgJ09BdXRoICcrdGhpcy5fY29ubi5hY2Nlc3NUb2tlbik7XG4gIGlmIChleHRlbnNpb25zIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBleHRlbnNpb25zLmZvckVhY2goZnVuY3Rpb24oZXh0ZW5zaW9uKSB7XG4gICAgICBmYXllQ2xpZW50LmFkZEV4dGVuc2lvbihleHRlbnNpb24pO1xuICAgIH0pO1xuICB9XG4gIGlmIChmYXllQ2xpZW50Ll9kaXNwYXRjaGVyLmdldENvbm5lY3Rpb25UeXBlcygpLmluZGV4T2YoJ2NhbGxiYWNrLXBvbGxpbmcnKSA9PT0gLTEpIHtcbiAgICAvLyBwcmV2ZW50IHN0cmVhbWluZyBBUEkgc2VydmVyIGVycm9yXG4gICAgZmF5ZUNsaWVudC5fZGlzcGF0Y2hlci5zZWxlY3RUcmFuc3BvcnQoJ2xvbmctcG9sbGluZycpO1xuICAgIGZheWVDbGllbnQuX2Rpc3BhdGNoZXIuX3RyYW5zcG9ydC5iYXRjaGluZyA9IGZhbHNlO1xuICB9XG4gIHJldHVybiBmYXllQ2xpZW50O1xufTtcblxuLyoqIEBwcml2YXRlICoqL1xuU3RyZWFtaW5nLnByb3RvdHlwZS5fZ2V0RmF5ZUNsaWVudCA9IGZ1bmN0aW9uKGNoYW5uZWxOYW1lKSB7XG4gIHZhciBpc0dlbmVyaWMgPSBjaGFubmVsTmFtZS5pbmRleE9mKCcvdS8nKSA9PT0gMDtcbiAgdmFyIGNsaWVudFR5cGUgPSBpc0dlbmVyaWMgPyAnZ2VuZXJpYycgOiAncHVzaFRvcGljJztcbiAgaWYgKCF0aGlzLl9mYXllQ2xpZW50cyB8fCAhdGhpcy5fZmF5ZUNsaWVudHNbY2xpZW50VHlwZV0pIHtcbiAgICB0aGlzLl9mYXllQ2xpZW50cyA9IHRoaXMuX2ZheWVDbGllbnRzIHx8IHt9O1xuICAgIHRoaXMuX2ZheWVDbGllbnRzW2NsaWVudFR5cGVdID0gdGhpcy5fY3JlYXRlQ2xpZW50KGNoYW5uZWxOYW1lKTtcbiAgfVxuICByZXR1cm4gdGhpcy5fZmF5ZUNsaWVudHNbY2xpZW50VHlwZV07XG59O1xuXG5cbi8qKlxuICogR2V0IG5hbWVkIHRvcGljXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKiBAcmV0dXJucyB7U3RyZWFtaW5nflRvcGljfVxuICovXG5TdHJlYW1pbmcucHJvdG90eXBlLnRvcGljID0gZnVuY3Rpb24obmFtZSkge1xuICB0aGlzLl90b3BpY3MgPSB0aGlzLl90b3BpY3MgfHwge307XG4gIHZhciB0b3BpYyA9IHRoaXMuX3RvcGljc1tuYW1lXSA9XG4gICAgdGhpcy5fdG9waWNzW25hbWVdIHx8IG5ldyBUb3BpYyh0aGlzLCBuYW1lKTtcbiAgcmV0dXJuIHRvcGljO1xufTtcblxuLyoqXG4gKiBHZXQgQ2hhbm5lbCBmb3IgSWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsSWQgLSBJZCBvZiBTdHJlYW1pbmdDaGFubmVsIG9iamVjdFxuICogQHJldHVybnMge1N0cmVhbWluZ35DaGFubmVsfVxuICovXG5TdHJlYW1pbmcucHJvdG90eXBlLmNoYW5uZWwgPSBmdW5jdGlvbihjaGFubmVsSWQpIHtcbiAgcmV0dXJuIG5ldyBDaGFubmVsKHRoaXMsIGNoYW5uZWxJZCk7XG59O1xuXG4vKipcbiAqIFN1YnNjcmliZSB0b3BpYy9jaGFubmVsXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxTdHJlYW1pbmd+U3RyZWFtaW5nTWVzc2FnZT59IGxpc3RlbmVyIC0gU3RyZWFtaW5nIG1lc3NhZ2UgbGlzdGVuZXJcbiAqIEByZXR1cm5zIHtTdWJzY3JpcHRpb259IC0gRmF5ZSBzdWJzY3JpcHRpb24gb2JqZWN0XG4gKi9cblN0cmVhbWluZy5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGNoYW5uZWxOYW1lID0gbmFtZS5pbmRleE9mKCcvJykgPT09IDAgPyBuYW1lIDogJy90b3BpYy8nICsgbmFtZTtcbiAgdmFyIGZheWVDbGllbnQgPSB0aGlzLl9nZXRGYXllQ2xpZW50KGNoYW5uZWxOYW1lKTtcbiAgcmV0dXJuIGZheWVDbGllbnQuc3Vic2NyaWJlKGNoYW5uZWxOYW1lLCBsaXN0ZW5lcik7XG59O1xuXG4vKipcbiAqIFVuc3Vic2NyaWJlIHRvcGljXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUb3BpYyBuYW1lXG4gKiBAcGFyYW0ge0NhbGxiYWNrLjxTdHJlYW1pbmd+U3RyZWFtaW5nTWVzc2FnZT59IGxpc3RlbmVyIC0gU3RyZWFtaW5nIG1lc3NhZ2UgbGlzdGVuZXJcbiAqIEByZXR1cm5zIHtTdHJlYW1pbmd9XG4gKi9cblN0cmVhbWluZy5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbihuYW1lLCBsaXN0ZW5lcikge1xuICB2YXIgY2hhbm5lbE5hbWUgPSBuYW1lLmluZGV4T2YoJy8nKSA9PT0gMCA/IG5hbWUgOiAnL3RvcGljLycgKyBuYW1lO1xuICB2YXIgZmF5ZUNsaWVudCA9IHRoaXMuX2dldEZheWVDbGllbnQoY2hhbm5lbE5hbWUpO1xuICBmYXllQ2xpZW50LnVuc3Vic2NyaWJlKGNoYW5uZWxOYW1lLCBsaXN0ZW5lcik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSBhIFN0cmVhbWluZyBjbGllbnQsIG9wdGlvbmFsbHkgd2l0aCBleHRlbnNpb25zXG4gKlxuICogU2VlIEZheWUgZG9jcyBmb3IgaW1wbGVtZW50YXRpb24gZGV0YWlsczogaHR0cHM6Ly9mYXllLmpjb2dsYW4uY29tL2Jyb3dzZXIvZXh0ZW5zaW9ucy5odG1sXG4gKlxuICogRXhhbXBsZSB1c2FnZTpcbiAqIFxuICogYGBgamF2YXNjcmlwdFxuICogLy8gRXN0YWJsaXNoIGEgU2FsZXNmb3JjZSBjb25uZWN0aW9uLiAoRGV0YWlscyBlbGlkZWQpXG4gKiBjb25zdCBjb25uID0gbmV3IGpzZm9yY2UuQ29ubmVjdGlvbih7IOKApiB9KTtcbiAqIFxuICogY29uc3QgZmF5ZUNsaWVudCA9IGNvbm4uc3RyZWFtaW5nLmNyZWF0ZUNsaWVudCgpO1xuICogXG4gKiBjb25zdCBzdWJzY3JpcHRpb24gPSBmYXllQ2xpZW50LnN1YnNjcmliZShjaGFubmVsLCBkYXRhID0+IHtcbiAqICAgY29uc29sZS5sb2coJ3RvcGljIHJlY2VpdmVkIGRhdGEnLCBkYXRhKTtcbiAqIH0pO1xuICogXG4gKiBzdWJzY3JpcHRpb24uY2FuY2VsKCk7XG4gKiBgYGBcbiAqIFxuICogRXhhbXBsZSB3aXRoIGV4dGVuc2lvbnMsIHVzaW5nIFJlcGxheSAmIEF1dGggRmFpbHVyZSBleHRlbnNpb25zIGluIGEgc2VydmVyLXNpZGUgTm9kZS5qcyBhcHA6XG4gKiBcbiAqIGBgYGphdmFzY3JpcHRcbiAqIC8vIEVzdGFibGlzaCBhIFNhbGVzZm9yY2UgY29ubmVjdGlvbi4gKERldGFpbHMgZWxpZGVkKVxuICogY29uc3QgY29ubiA9IG5ldyBqc2ZvcmNlLkNvbm5lY3Rpb24oeyDigKYgfSk7XG4gKiBcbiAqIGNvbnN0IGNoYW5uZWwgPSBcIi9ldmVudC9NeV9FdmVudF9fZVwiO1xuICogY29uc3QgcmVwbGF5SWQgPSAtMjsgLy8gLTIgaXMgYWxsIHJldGFpbmVkIGV2ZW50c1xuICogXG4gKiBjb25zdCBleGl0Q2FsbGJhY2sgPSAoKSA9PiBwcm9jZXNzLmV4aXQoMSk7XG4gKiBjb25zdCBhdXRoRmFpbHVyZUV4dCA9IG5ldyBqc2ZvcmNlLlN0cmVhbWluZ0V4dGVuc2lvbi5BdXRoRmFpbHVyZShleGl0Q2FsbGJhY2spO1xuICogXG4gKiBjb25zdCByZXBsYXlFeHQgPSBuZXcganNmb3JjZS5TdHJlYW1pbmdFeHRlbnNpb24uUmVwbGF5KGNoYW5uZWwsIHJlcGxheUlkKTtcbiAqIFxuICogY29uc3QgZmF5ZUNsaWVudCA9IGNvbm4uc3RyZWFtaW5nLmNyZWF0ZUNsaWVudChbXG4gKiAgIGF1dGhGYWlsdXJlRXh0LFxuICogICByZXBsYXlFeHRcbiAqIF0pO1xuICogXG4gKiBjb25zdCBzdWJzY3JpcHRpb24gPSBmYXllQ2xpZW50LnN1YnNjcmliZShjaGFubmVsLCBkYXRhID0+IHtcbiAqICAgY29uc29sZS5sb2coJ3RvcGljIHJlY2VpdmVkIGRhdGEnLCBkYXRhKTtcbiAqIH0pO1xuICogXG4gKiBzdWJzY3JpcHRpb24uY2FuY2VsKCk7XG4gKiBgYGBcbiAqIFxuICogQHBhcmFtIHtBcnJheX0gRXh0ZW5zaW9ucyAtIE9wdGlvbmFsLCBleHRlbnNpb25zIHRvIGFwcGx5IHRvIHRoZSBGYXllIGNsaWVudFxuICogQHJldHVybnMge0ZheWVDbGllbnR9IC0gRmF5ZSBjbGllbnQgb2JqZWN0XG4gKi9cblN0cmVhbWluZy5wcm90b3R5cGUuY3JlYXRlQ2xpZW50ID0gZnVuY3Rpb24oZXh0ZW5zaW9ucykge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlQ2xpZW50KG51bGwsIGV4dGVuc2lvbnMpO1xufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKlxuICogUmVnaXN0ZXIgaG9vayBpbiBjb25uZWN0aW9uIGluc3RhbnRpYXRpb24gZm9yIGR5bmFtaWNhbGx5IGFkZGluZyB0aGlzIEFQSSBtb2R1bGUgZmVhdHVyZXNcbiAqL1xuanNmb3JjZS5vbignY29ubmVjdGlvbjpuZXcnLCBmdW5jdGlvbihjb25uKSB7XG4gIGNvbm4uc3RyZWFtaW5nID0gbmV3IFN0cmVhbWluZyhjb25uKTtcbn0pO1xuXG4vKlxuICogXG4gKi9cbmpzZm9yY2UuU3RyZWFtaW5nRXh0ZW5zaW9uID0gU3RyZWFtaW5nRXh0ZW5zaW9uO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbWluZztcbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vLyByYXdBc2FwIHByb3ZpZGVzIGV2ZXJ5dGhpbmcgd2UgbmVlZCBleGNlcHQgZXhjZXB0aW9uIG1hbmFnZW1lbnQuXG52YXIgcmF3QXNhcCA9IHJlcXVpcmUoXCIuL3Jhd1wiKTtcbi8vIFJhd1Rhc2tzIGFyZSByZWN5Y2xlZCB0byByZWR1Y2UgR0MgY2h1cm4uXG52YXIgZnJlZVRhc2tzID0gW107XG4vLyBXZSBxdWV1ZSBlcnJvcnMgdG8gZW5zdXJlIHRoZXkgYXJlIHRocm93biBpbiByaWdodCBvcmRlciAoRklGTykuXG4vLyBBcnJheS1hcy1xdWV1ZSBpcyBnb29kIGVub3VnaCBoZXJlLCBzaW5jZSB3ZSBhcmUganVzdCBkZWFsaW5nIHdpdGggZXhjZXB0aW9ucy5cbnZhciBwZW5kaW5nRXJyb3JzID0gW107XG52YXIgcmVxdWVzdEVycm9yVGhyb3cgPSByYXdBc2FwLm1ha2VSZXF1ZXN0Q2FsbEZyb21UaW1lcih0aHJvd0ZpcnN0RXJyb3IpO1xuXG5mdW5jdGlvbiB0aHJvd0ZpcnN0RXJyb3IoKSB7XG4gICAgaWYgKHBlbmRpbmdFcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IHBlbmRpbmdFcnJvcnMuc2hpZnQoKTtcbiAgICB9XG59XG5cbi8qKlxuICogQ2FsbHMgYSB0YXNrIGFzIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgcmV0dXJuaW5nLCBpbiBpdHMgb3duIGV2ZW50LCB3aXRoIHByaW9yaXR5XG4gKiBvdmVyIG90aGVyIGV2ZW50cyBsaWtlIGFuaW1hdGlvbiwgcmVmbG93LCBhbmQgcmVwYWludC4gQW4gZXJyb3IgdGhyb3duIGZyb20gYW5cbiAqIGV2ZW50IHdpbGwgbm90IGludGVycnVwdCwgbm9yIGV2ZW4gc3Vic3RhbnRpYWxseSBzbG93IGRvd24gdGhlIHByb2Nlc3Npbmcgb2ZcbiAqIG90aGVyIGV2ZW50cywgYnV0IHdpbGwgYmUgcmF0aGVyIHBvc3Rwb25lZCB0byBhIGxvd2VyIHByaW9yaXR5IGV2ZW50LlxuICogQHBhcmFtIHt7Y2FsbH19IHRhc2sgQSBjYWxsYWJsZSBvYmplY3QsIHR5cGljYWxseSBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgbm9cbiAqIGFyZ3VtZW50cy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBhc2FwO1xuZnVuY3Rpb24gYXNhcCh0YXNrKSB7XG4gICAgdmFyIHJhd1Rhc2s7XG4gICAgaWYgKGZyZWVUYXNrcy5sZW5ndGgpIHtcbiAgICAgICAgcmF3VGFzayA9IGZyZWVUYXNrcy5wb3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByYXdUYXNrID0gbmV3IFJhd1Rhc2soKTtcbiAgICB9XG4gICAgcmF3VGFzay50YXNrID0gdGFzaztcbiAgICByYXdBc2FwKHJhd1Rhc2spO1xufVxuXG4vLyBXZSB3cmFwIHRhc2tzIHdpdGggcmVjeWNsYWJsZSB0YXNrIG9iamVjdHMuICBBIHRhc2sgb2JqZWN0IGltcGxlbWVudHNcbi8vIGBjYWxsYCwganVzdCBsaWtlIGEgZnVuY3Rpb24uXG5mdW5jdGlvbiBSYXdUYXNrKCkge1xuICAgIHRoaXMudGFzayA9IG51bGw7XG59XG5cbi8vIFRoZSBzb2xlIHB1cnBvc2Ugb2Ygd3JhcHBpbmcgdGhlIHRhc2sgaXMgdG8gY2F0Y2ggdGhlIGV4Y2VwdGlvbiBhbmQgcmVjeWNsZVxuLy8gdGhlIHRhc2sgb2JqZWN0IGFmdGVyIGl0cyBzaW5nbGUgdXNlLlxuUmF3VGFzay5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICB0aGlzLnRhc2suY2FsbCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChhc2FwLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgaG9vayBleGlzdHMgcHVyZWx5IGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxuICAgICAgICAgICAgLy8gSXRzIG5hbWUgd2lsbCBiZSBwZXJpb2RpY2FsbHkgcmFuZG9taXplZCB0byBicmVhayBhbnkgY29kZSB0aGF0XG4gICAgICAgICAgICAvLyBkZXBlbmRzIG9uIGl0cyBleGlzdGVuY2UuXG4gICAgICAgICAgICBhc2FwLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSW4gYSB3ZWIgYnJvd3NlciwgZXhjZXB0aW9ucyBhcmUgbm90IGZhdGFsLiBIb3dldmVyLCB0byBhdm9pZFxuICAgICAgICAgICAgLy8gc2xvd2luZyBkb3duIHRoZSBxdWV1ZSBvZiBwZW5kaW5nIHRhc2tzLCB3ZSByZXRocm93IHRoZSBlcnJvciBpbiBhXG4gICAgICAgICAgICAvLyBsb3dlciBwcmlvcml0eSB0dXJuLlxuICAgICAgICAgICAgcGVuZGluZ0Vycm9ycy5wdXNoKGVycm9yKTtcbiAgICAgICAgICAgIHJlcXVlc3RFcnJvclRocm93KCk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLnRhc2sgPSBudWxsO1xuICAgICAgICBmcmVlVGFza3NbZnJlZVRhc2tzLmxlbmd0aF0gPSB0aGlzO1xuICAgIH1cbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLy8gVXNlIHRoZSBmYXN0ZXN0IG1lYW5zIHBvc3NpYmxlIHRvIGV4ZWN1dGUgYSB0YXNrIGluIGl0cyBvd24gdHVybiwgd2l0aFxuLy8gcHJpb3JpdHkgb3ZlciBvdGhlciBldmVudHMgaW5jbHVkaW5nIElPLCBhbmltYXRpb24sIHJlZmxvdywgYW5kIHJlZHJhd1xuLy8gZXZlbnRzIGluIGJyb3dzZXJzLlxuLy9cbi8vIEFuIGV4Y2VwdGlvbiB0aHJvd24gYnkgYSB0YXNrIHdpbGwgcGVybWFuZW50bHkgaW50ZXJydXB0IHRoZSBwcm9jZXNzaW5nIG9mXG4vLyBzdWJzZXF1ZW50IHRhc2tzLiBUaGUgaGlnaGVyIGxldmVsIGBhc2FwYCBmdW5jdGlvbiBlbnN1cmVzIHRoYXQgaWYgYW5cbi8vIGV4Y2VwdGlvbiBpcyB0aHJvd24gYnkgYSB0YXNrLCB0aGF0IHRoZSB0YXNrIHF1ZXVlIHdpbGwgY29udGludWUgZmx1c2hpbmcgYXNcbi8vIHNvb24gYXMgcG9zc2libGUsIGJ1dCBpZiB5b3UgdXNlIGByYXdBc2FwYCBkaXJlY3RseSwgeW91IGFyZSByZXNwb25zaWJsZSB0b1xuLy8gZWl0aGVyIGVuc3VyZSB0aGF0IG5vIGV4Y2VwdGlvbnMgYXJlIHRocm93biBmcm9tIHlvdXIgdGFzaywgb3IgdG8gbWFudWFsbHlcbi8vIGNhbGwgYHJhd0FzYXAucmVxdWVzdEZsdXNoYCBpZiBhbiBleGNlcHRpb24gaXMgdGhyb3duLlxubW9kdWxlLmV4cG9ydHMgPSByYXdBc2FwO1xuZnVuY3Rpb24gcmF3QXNhcCh0YXNrKSB7XG4gICAgaWYgKCFxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcmVxdWVzdEZsdXNoKCk7XG4gICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICB9XG4gICAgLy8gRXF1aXZhbGVudCB0byBwdXNoLCBidXQgYXZvaWRzIGEgZnVuY3Rpb24gY2FsbC5cbiAgICBxdWV1ZVtxdWV1ZS5sZW5ndGhdID0gdGFzaztcbn1cblxudmFyIHF1ZXVlID0gW107XG4vLyBPbmNlIGEgZmx1c2ggaGFzIGJlZW4gcmVxdWVzdGVkLCBubyBmdXJ0aGVyIGNhbGxzIHRvIGByZXF1ZXN0Rmx1c2hgIGFyZVxuLy8gbmVjZXNzYXJ5IHVudGlsIHRoZSBuZXh0IGBmbHVzaGAgY29tcGxldGVzLlxudmFyIGZsdXNoaW5nID0gZmFsc2U7XG4vLyBgcmVxdWVzdEZsdXNoYCBpcyBhbiBpbXBsZW1lbnRhdGlvbi1zcGVjaWZpYyBtZXRob2QgdGhhdCBhdHRlbXB0cyB0byBraWNrXG4vLyBvZmYgYSBgZmx1c2hgIGV2ZW50IGFzIHF1aWNrbHkgYXMgcG9zc2libGUuIGBmbHVzaGAgd2lsbCBhdHRlbXB0IHRvIGV4aGF1c3Rcbi8vIHRoZSBldmVudCBxdWV1ZSBiZWZvcmUgeWllbGRpbmcgdG8gdGhlIGJyb3dzZXIncyBvd24gZXZlbnQgbG9vcC5cbnZhciByZXF1ZXN0Rmx1c2g7XG4vLyBUaGUgcG9zaXRpb24gb2YgdGhlIG5leHQgdGFzayB0byBleGVjdXRlIGluIHRoZSB0YXNrIHF1ZXVlLiBUaGlzIGlzXG4vLyBwcmVzZXJ2ZWQgYmV0d2VlbiBjYWxscyB0byBgZmx1c2hgIHNvIHRoYXQgaXQgY2FuIGJlIHJlc3VtZWQgaWZcbi8vIGEgdGFzayB0aHJvd3MgYW4gZXhjZXB0aW9uLlxudmFyIGluZGV4ID0gMDtcbi8vIElmIGEgdGFzayBzY2hlZHVsZXMgYWRkaXRpb25hbCB0YXNrcyByZWN1cnNpdmVseSwgdGhlIHRhc2sgcXVldWUgY2FuIGdyb3dcbi8vIHVuYm91bmRlZC4gVG8gcHJldmVudCBtZW1vcnkgZXhoYXVzdGlvbiwgdGhlIHRhc2sgcXVldWUgd2lsbCBwZXJpb2RpY2FsbHlcbi8vIHRydW5jYXRlIGFscmVhZHktY29tcGxldGVkIHRhc2tzLlxudmFyIGNhcGFjaXR5ID0gMTAyNDtcblxuLy8gVGhlIGZsdXNoIGZ1bmN0aW9uIHByb2Nlc3NlcyBhbGwgdGFza3MgdGhhdCBoYXZlIGJlZW4gc2NoZWR1bGVkIHdpdGhcbi8vIGByYXdBc2FwYCB1bmxlc3MgYW5kIHVudGlsIG9uZSBvZiB0aG9zZSB0YXNrcyB0aHJvd3MgYW4gZXhjZXB0aW9uLlxuLy8gSWYgYSB0YXNrIHRocm93cyBhbiBleGNlcHRpb24sIGBmbHVzaGAgZW5zdXJlcyB0aGF0IGl0cyBzdGF0ZSB3aWxsIHJlbWFpblxuLy8gY29uc2lzdGVudCBhbmQgd2lsbCByZXN1bWUgd2hlcmUgaXQgbGVmdCBvZmYgd2hlbiBjYWxsZWQgYWdhaW4uXG4vLyBIb3dldmVyLCBgZmx1c2hgIGRvZXMgbm90IG1ha2UgYW55IGFycmFuZ2VtZW50cyB0byBiZSBjYWxsZWQgYWdhaW4gaWYgYW5cbi8vIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG5mdW5jdGlvbiBmbHVzaCgpIHtcbiAgICB3aGlsZSAoaW5kZXggPCBxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRJbmRleCA9IGluZGV4O1xuICAgICAgICAvLyBBZHZhbmNlIHRoZSBpbmRleCBiZWZvcmUgY2FsbGluZyB0aGUgdGFzay4gVGhpcyBlbnN1cmVzIHRoYXQgd2Ugd2lsbFxuICAgICAgICAvLyBiZWdpbiBmbHVzaGluZyBvbiB0aGUgbmV4dCB0YXNrIHRoZSB0YXNrIHRocm93cyBhbiBlcnJvci5cbiAgICAgICAgaW5kZXggPSBpbmRleCArIDE7XG4gICAgICAgIHF1ZXVlW2N1cnJlbnRJbmRleF0uY2FsbCgpO1xuICAgICAgICAvLyBQcmV2ZW50IGxlYWtpbmcgbWVtb3J5IGZvciBsb25nIGNoYWlucyBvZiByZWN1cnNpdmUgY2FsbHMgdG8gYGFzYXBgLlxuICAgICAgICAvLyBJZiB3ZSBjYWxsIGBhc2FwYCB3aXRoaW4gdGFza3Mgc2NoZWR1bGVkIGJ5IGBhc2FwYCwgdGhlIHF1ZXVlIHdpbGxcbiAgICAgICAgLy8gZ3JvdywgYnV0IHRvIGF2b2lkIGFuIE8obikgd2FsayBmb3IgZXZlcnkgdGFzayB3ZSBleGVjdXRlLCB3ZSBkb24ndFxuICAgICAgICAvLyBzaGlmdCB0YXNrcyBvZmYgdGhlIHF1ZXVlIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIGV4ZWN1dGVkLlxuICAgICAgICAvLyBJbnN0ZWFkLCB3ZSBwZXJpb2RpY2FsbHkgc2hpZnQgMTAyNCB0YXNrcyBvZmYgdGhlIHF1ZXVlLlxuICAgICAgICBpZiAoaW5kZXggPiBjYXBhY2l0eSkge1xuICAgICAgICAgICAgLy8gTWFudWFsbHkgc2hpZnQgYWxsIHZhbHVlcyBzdGFydGluZyBhdCB0aGUgaW5kZXggYmFjayB0byB0aGVcbiAgICAgICAgICAgIC8vIGJlZ2lubmluZyBvZiB0aGUgcXVldWUuXG4gICAgICAgICAgICBmb3IgKHZhciBzY2FuID0gMCwgbmV3TGVuZ3RoID0gcXVldWUubGVuZ3RoIC0gaW5kZXg7IHNjYW4gPCBuZXdMZW5ndGg7IHNjYW4rKykge1xuICAgICAgICAgICAgICAgIHF1ZXVlW3NjYW5dID0gcXVldWVbc2NhbiArIGluZGV4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHF1ZXVlLmxlbmd0aCAtPSBpbmRleDtcbiAgICAgICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5sZW5ndGggPSAwO1xuICAgIGluZGV4ID0gMDtcbiAgICBmbHVzaGluZyA9IGZhbHNlO1xufVxuXG4vLyBgcmVxdWVzdEZsdXNoYCBpcyBpbXBsZW1lbnRlZCB1c2luZyBhIHN0cmF0ZWd5IGJhc2VkIG9uIGRhdGEgY29sbGVjdGVkIGZyb21cbi8vIGV2ZXJ5IGF2YWlsYWJsZSBTYXVjZUxhYnMgU2VsZW5pdW0gd2ViIGRyaXZlciB3b3JrZXIgYXQgdGltZSBvZiB3cml0aW5nLlxuLy8gaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMW1HLTVVWUd1cDVxeEdkRU1Xa2hQNkJXQ3owNTNOVWIyRTFRb1VUVTE2dUEvZWRpdCNnaWQ9NzgzNzI0NTkzXG5cbi8vIFNhZmFyaSA2IGFuZCA2LjEgZm9yIGRlc2t0b3AsIGlQYWQsIGFuZCBpUGhvbmUgYXJlIHRoZSBvbmx5IGJyb3dzZXJzIHRoYXRcbi8vIGhhdmUgV2ViS2l0TXV0YXRpb25PYnNlcnZlciBidXQgbm90IHVuLXByZWZpeGVkIE11dGF0aW9uT2JzZXJ2ZXIuXG4vLyBNdXN0IHVzZSBgZ2xvYmFsYCBvciBgc2VsZmAgaW5zdGVhZCBvZiBgd2luZG93YCB0byB3b3JrIGluIGJvdGggZnJhbWVzIGFuZCB3ZWJcbi8vIHdvcmtlcnMuIGBnbG9iYWxgIGlzIGEgcHJvdmlzaW9uIG9mIEJyb3dzZXJpZnksIE1yLCBNcnMsIG9yIE1vcC5cblxuLyogZ2xvYmFscyBzZWxmICovXG52YXIgc2NvcGUgPSB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogc2VsZjtcbnZhciBCcm93c2VyTXV0YXRpb25PYnNlcnZlciA9IHNjb3BlLk11dGF0aW9uT2JzZXJ2ZXIgfHwgc2NvcGUuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcblxuLy8gTXV0YXRpb25PYnNlcnZlcnMgYXJlIGRlc2lyYWJsZSBiZWNhdXNlIHRoZXkgaGF2ZSBoaWdoIHByaW9yaXR5IGFuZCB3b3JrXG4vLyByZWxpYWJseSBldmVyeXdoZXJlIHRoZXkgYXJlIGltcGxlbWVudGVkLlxuLy8gVGhleSBhcmUgaW1wbGVtZW50ZWQgaW4gYWxsIG1vZGVybiBicm93c2Vycy5cbi8vXG4vLyAtIEFuZHJvaWQgNC00LjNcbi8vIC0gQ2hyb21lIDI2LTM0XG4vLyAtIEZpcmVmb3ggMTQtMjlcbi8vIC0gSW50ZXJuZXQgRXhwbG9yZXIgMTFcbi8vIC0gaVBhZCBTYWZhcmkgNi03LjFcbi8vIC0gaVBob25lIFNhZmFyaSA3LTcuMVxuLy8gLSBTYWZhcmkgNi03XG5pZiAodHlwZW9mIEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICByZXF1ZXN0Rmx1c2ggPSBtYWtlUmVxdWVzdENhbGxGcm9tTXV0YXRpb25PYnNlcnZlcihmbHVzaCk7XG5cbi8vIE1lc3NhZ2VDaGFubmVscyBhcmUgZGVzaXJhYmxlIGJlY2F1c2UgdGhleSBnaXZlIGRpcmVjdCBhY2Nlc3MgdG8gdGhlIEhUTUxcbi8vIHRhc2sgcXVldWUsIGFyZSBpbXBsZW1lbnRlZCBpbiBJbnRlcm5ldCBFeHBsb3JlciAxMCwgU2FmYXJpIDUuMC0xLCBhbmQgT3BlcmFcbi8vIDExLTEyLCBhbmQgaW4gd2ViIHdvcmtlcnMgaW4gbWFueSBlbmdpbmVzLlxuLy8gQWx0aG91Z2ggbWVzc2FnZSBjaGFubmVscyB5aWVsZCB0byBhbnkgcXVldWVkIHJlbmRlcmluZyBhbmQgSU8gdGFza3MsIHRoZXlcbi8vIHdvdWxkIGJlIGJldHRlciB0aGFuIGltcG9zaW5nIHRoZSA0bXMgZGVsYXkgb2YgdGltZXJzLlxuLy8gSG93ZXZlciwgdGhleSBkbyBub3Qgd29yayByZWxpYWJseSBpbiBJbnRlcm5ldCBFeHBsb3JlciBvciBTYWZhcmkuXG5cbi8vIEludGVybmV0IEV4cGxvcmVyIDEwIGlzIHRoZSBvbmx5IGJyb3dzZXIgdGhhdCBoYXMgc2V0SW1tZWRpYXRlIGJ1dCBkb2VzXG4vLyBub3QgaGF2ZSBNdXRhdGlvbk9ic2VydmVycy5cbi8vIEFsdGhvdWdoIHNldEltbWVkaWF0ZSB5aWVsZHMgdG8gdGhlIGJyb3dzZXIncyByZW5kZXJlciwgaXQgd291bGQgYmVcbi8vIHByZWZlcnJhYmxlIHRvIGZhbGxpbmcgYmFjayB0byBzZXRUaW1lb3V0IHNpbmNlIGl0IGRvZXMgbm90IGhhdmVcbi8vIHRoZSBtaW5pbXVtIDRtcyBwZW5hbHR5LlxuLy8gVW5mb3J0dW5hdGVseSB0aGVyZSBhcHBlYXJzIHRvIGJlIGEgYnVnIGluIEludGVybmV0IEV4cGxvcmVyIDEwIE1vYmlsZSAoYW5kXG4vLyBEZXNrdG9wIHRvIGEgbGVzc2VyIGV4dGVudCkgdGhhdCByZW5kZXJzIGJvdGggc2V0SW1tZWRpYXRlIGFuZFxuLy8gTWVzc2FnZUNoYW5uZWwgdXNlbGVzcyBmb3IgdGhlIHB1cnBvc2VzIG9mIEFTQVAuXG4vLyBodHRwczovL2dpdGh1Yi5jb20va3Jpc2tvd2FsL3EvaXNzdWVzLzM5NlxuXG4vLyBUaW1lcnMgYXJlIGltcGxlbWVudGVkIHVuaXZlcnNhbGx5LlxuLy8gV2UgZmFsbCBiYWNrIHRvIHRpbWVycyBpbiB3b3JrZXJzIGluIG1vc3QgZW5naW5lcywgYW5kIGluIGZvcmVncm91bmRcbi8vIGNvbnRleHRzIGluIHRoZSBmb2xsb3dpbmcgYnJvd3NlcnMuXG4vLyBIb3dldmVyLCBub3RlIHRoYXQgZXZlbiB0aGlzIHNpbXBsZSBjYXNlIHJlcXVpcmVzIG51YW5jZXMgdG8gb3BlcmF0ZSBpbiBhXG4vLyBicm9hZCBzcGVjdHJ1bSBvZiBicm93c2Vycy5cbi8vXG4vLyAtIEZpcmVmb3ggMy0xM1xuLy8gLSBJbnRlcm5ldCBFeHBsb3JlciA2LTlcbi8vIC0gaVBhZCBTYWZhcmkgNC4zXG4vLyAtIEx5bnggMi44Ljdcbn0gZWxzZSB7XG4gICAgcmVxdWVzdEZsdXNoID0gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyKGZsdXNoKTtcbn1cblxuLy8gYHJlcXVlc3RGbHVzaGAgcmVxdWVzdHMgdGhhdCB0aGUgaGlnaCBwcmlvcml0eSBldmVudCBxdWV1ZSBiZSBmbHVzaGVkIGFzXG4vLyBzb29uIGFzIHBvc3NpYmxlLlxuLy8gVGhpcyBpcyB1c2VmdWwgdG8gcHJldmVudCBhbiBlcnJvciB0aHJvd24gaW4gYSB0YXNrIGZyb20gc3RhbGxpbmcgdGhlIGV2ZW50XG4vLyBxdWV1ZSBpZiB0aGUgZXhjZXB0aW9uIGhhbmRsZWQgYnkgTm9kZS5qc+KAmXNcbi8vIGBwcm9jZXNzLm9uKFwidW5jYXVnaHRFeGNlcHRpb25cIilgIG9yIGJ5IGEgZG9tYWluLlxucmF3QXNhcC5yZXF1ZXN0Rmx1c2ggPSByZXF1ZXN0Rmx1c2g7XG5cbi8vIFRvIHJlcXVlc3QgYSBoaWdoIHByaW9yaXR5IGV2ZW50LCB3ZSBpbmR1Y2UgYSBtdXRhdGlvbiBvYnNlcnZlciBieSB0b2dnbGluZ1xuLy8gdGhlIHRleHQgb2YgYSB0ZXh0IG5vZGUgYmV0d2VlbiBcIjFcIiBhbmQgXCItMVwiLlxuZnVuY3Rpb24gbWFrZVJlcXVlc3RDYWxsRnJvbU11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spIHtcbiAgICB2YXIgdG9nZ2xlID0gMTtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJcIik7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShub2RlLCB7Y2hhcmFjdGVyRGF0YTogdHJ1ZX0pO1xuICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbiAgICAgICAgdG9nZ2xlID0gLXRvZ2dsZTtcbiAgICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlO1xuICAgIH07XG59XG5cbi8vIFRoZSBtZXNzYWdlIGNoYW5uZWwgdGVjaG5pcXVlIHdhcyBkaXNjb3ZlcmVkIGJ5IE1hbHRlIFVibCBhbmQgd2FzIHRoZVxuLy8gb3JpZ2luYWwgZm91bmRhdGlvbiBmb3IgdGhpcyBsaWJyYXJ5LlxuLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcblxuLy8gU2FmYXJpIDYuMC41IChhdCBsZWFzdCkgaW50ZXJtaXR0ZW50bHkgZmFpbHMgdG8gY3JlYXRlIG1lc3NhZ2UgcG9ydHMgb24gYVxuLy8gcGFnZSdzIGZpcnN0IGxvYWQuIFRoYW5rZnVsbHksIHRoaXMgdmVyc2lvbiBvZiBTYWZhcmkgc3VwcG9ydHNcbi8vIE11dGF0aW9uT2JzZXJ2ZXJzLCBzbyB3ZSBkb24ndCBuZWVkIHRvIGZhbGwgYmFjayBpbiB0aGF0IGNhc2UuXG5cbi8vIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21NZXNzYWdlQ2hhbm5lbChjYWxsYmFjaykge1xuLy8gICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4vLyAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBjYWxsYmFjaztcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gcmVxdWVzdENhbGwoKSB7XG4vLyAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4vLyAgICAgfTtcbi8vIH1cblxuLy8gRm9yIHJlYXNvbnMgZXhwbGFpbmVkIGFib3ZlLCB3ZSBhcmUgYWxzbyB1bmFibGUgdG8gdXNlIGBzZXRJbW1lZGlhdGVgXG4vLyB1bmRlciBhbnkgY2lyY3Vtc3RhbmNlcy5cbi8vIEV2ZW4gaWYgd2Ugd2VyZSwgdGhlcmUgaXMgYW5vdGhlciBidWcgaW4gSW50ZXJuZXQgRXhwbG9yZXIgMTAuXG4vLyBJdCBpcyBub3Qgc3VmZmljaWVudCB0byBhc3NpZ24gYHNldEltbWVkaWF0ZWAgdG8gYHJlcXVlc3RGbHVzaGAgYmVjYXVzZVxuLy8gYHNldEltbWVkaWF0ZWAgbXVzdCBiZSBjYWxsZWQgKmJ5IG5hbWUqIGFuZCB0aGVyZWZvcmUgbXVzdCBiZSB3cmFwcGVkIGluIGFcbi8vIGNsb3N1cmUuXG4vLyBOZXZlciBmb3JnZXQuXG5cbi8vIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21TZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gcmVxdWVzdENhbGwoKSB7XG4vLyAgICAgICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4vLyAgICAgfTtcbi8vIH1cblxuLy8gU2FmYXJpIDYuMCBoYXMgYSBwcm9ibGVtIHdoZXJlIHRpbWVycyB3aWxsIGdldCBsb3N0IHdoaWxlIHRoZSB1c2VyIGlzXG4vLyBzY3JvbGxpbmcuIFRoaXMgcHJvYmxlbSBkb2VzIG5vdCBpbXBhY3QgQVNBUCBiZWNhdXNlIFNhZmFyaSA2LjAgc3VwcG9ydHNcbi8vIG11dGF0aW9uIG9ic2VydmVycywgc28gdGhhdCBpbXBsZW1lbnRhdGlvbiBpcyB1c2VkIGluc3RlYWQuXG4vLyBIb3dldmVyLCBpZiB3ZSBldmVyIGVsZWN0IHRvIHVzZSB0aW1lcnMgaW4gU2FmYXJpLCB0aGUgcHJldmFsZW50IHdvcmstYXJvdW5kXG4vLyBpcyB0byBhZGQgYSBzY3JvbGwgZXZlbnQgbGlzdGVuZXIgdGhhdCBjYWxscyBmb3IgYSBmbHVzaC5cblxuLy8gYHNldFRpbWVvdXRgIGRvZXMgbm90IGNhbGwgdGhlIHBhc3NlZCBjYWxsYmFjayBpZiB0aGUgZGVsYXkgaXMgbGVzcyB0aGFuXG4vLyBhcHByb3hpbWF0ZWx5IDcgaW4gd2ViIHdvcmtlcnMgaW4gRmlyZWZveCA4IHRocm91Z2ggMTgsIGFuZCBzb21ldGltZXMgbm90XG4vLyBldmVuIHRoZW4uXG5cbmZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21UaW1lcihjYWxsYmFjaykge1xuICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbiAgICAgICAgLy8gV2UgZGlzcGF0Y2ggYSB0aW1lb3V0IHdpdGggYSBzcGVjaWZpZWQgZGVsYXkgb2YgMCBmb3IgZW5naW5lcyB0aGF0XG4gICAgICAgIC8vIGNhbiByZWxpYWJseSBhY2NvbW1vZGF0ZSB0aGF0IHJlcXVlc3QuIFRoaXMgd2lsbCB1c3VhbGx5IGJlIHNuYXBwZWRcbiAgICAgICAgLy8gdG8gYSA0IG1pbGlzZWNvbmQgZGVsYXksIGJ1dCBvbmNlIHdlJ3JlIGZsdXNoaW5nLCB0aGVyZSdzIG5vIGRlbGF5XG4gICAgICAgIC8vIGJldHdlZW4gZXZlbnRzLlxuICAgICAgICB2YXIgdGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoaGFuZGxlVGltZXIsIDApO1xuICAgICAgICAvLyBIb3dldmVyLCBzaW5jZSB0aGlzIHRpbWVyIGdldHMgZnJlcXVlbnRseSBkcm9wcGVkIGluIEZpcmVmb3hcbiAgICAgICAgLy8gd29ya2Vycywgd2UgZW5saXN0IGFuIGludGVydmFsIGhhbmRsZSB0aGF0IHdpbGwgdHJ5IHRvIGZpcmVcbiAgICAgICAgLy8gYW4gZXZlbnQgMjAgdGltZXMgcGVyIHNlY29uZCB1bnRpbCBpdCBzdWNjZWVkcy5cbiAgICAgICAgdmFyIGludGVydmFsSGFuZGxlID0gc2V0SW50ZXJ2YWwoaGFuZGxlVGltZXIsIDUwKTtcblxuICAgICAgICBmdW5jdGlvbiBoYW5kbGVUaW1lcigpIHtcbiAgICAgICAgICAgIC8vIFdoaWNoZXZlciB0aW1lciBzdWNjZWVkcyB3aWxsIGNhbmNlbCBib3RoIHRpbWVycyBhbmRcbiAgICAgICAgICAgIC8vIGV4ZWN1dGUgdGhlIGNhbGxiYWNrLlxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRIYW5kbGUpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbEhhbmRsZSk7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxuLy8gVGhpcyBpcyBmb3IgYGFzYXAuanNgIG9ubHkuXG4vLyBJdHMgbmFtZSB3aWxsIGJlIHBlcmlvZGljYWxseSByYW5kb21pemVkIHRvIGJyZWFrIGFueSBjb2RlIHRoYXQgZGVwZW5kcyBvblxuLy8gaXRzIGV4aXN0ZW5jZS5cbnJhd0FzYXAubWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyID0gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyO1xuXG4vLyBBU0FQIHdhcyBvcmlnaW5hbGx5IGEgbmV4dFRpY2sgc2hpbSBpbmNsdWRlZCBpbiBRLiBUaGlzIHdhcyBmYWN0b3JlZCBvdXRcbi8vIGludG8gdGhpcyBBU0FQIHBhY2thZ2UuIEl0IHdhcyBsYXRlciBhZGFwdGVkIHRvIFJTVlAgd2hpY2ggbWFkZSBmdXJ0aGVyXG4vLyBhbWVuZG1lbnRzLiBUaGVzZSBkZWNpc2lvbnMsIHBhcnRpY3VsYXJseSB0byBtYXJnaW5hbGl6ZSBNZXNzYWdlQ2hhbm5lbCBhbmRcbi8vIHRvIGNhcHR1cmUgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaW4gYSBjbG9zdXJlLCB3ZXJlIGludGVncmF0ZWRcbi8vIGJhY2sgaW50byBBU0FQIHByb3Blci5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90aWxkZWlvL3JzdnAuanMvYmxvYi9jZGRmNzIzMjU0NmE5Y2Y4NTg1MjRiNzVjZGU2ZjllZGY3MjYyMGE3L2xpYi9yc3ZwL2FzYXAuanNcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbnN0YW50cyA9IHJlcXVpcmUoJy4vdXRpbC9jb25zdGFudHMnKSxcbiAgICBMb2dnaW5nICAgPSByZXF1aXJlKCcuL21peGlucy9sb2dnaW5nJyk7XG5cbnZhciBGYXllID0ge1xuICBWRVJTSU9OOiAgICBjb25zdGFudHMuVkVSU0lPTixcblxuICBDbGllbnQ6ICAgICByZXF1aXJlKCcuL3Byb3RvY29sL2NsaWVudCcpLFxuICBTY2hlZHVsZXI6ICByZXF1aXJlKCcuL3Byb3RvY29sL3NjaGVkdWxlcicpXG59O1xuXG5Mb2dnaW5nLndyYXBwZXIgPSBGYXllO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZheWU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBQcm9taXNlICAgPSByZXF1aXJlKCcuLi91dGlsL3Byb21pc2UnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHRoZW46IGZ1bmN0aW9uKGNhbGxiYWNrLCBlcnJiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICghdGhpcy5fcHJvbWlzZSlcbiAgICAgIHRoaXMuX3Byb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5fcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIHNlbGYuX3JlamVjdCAgPSByZWplY3Q7XG4gICAgICB9KTtcblxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2UudGhlbihjYWxsYmFjaywgZXJyYmFjayk7XG4gIH0sXG5cbiAgY2FsbGJhY2s6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbih2YWx1ZSkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQsIHZhbHVlKSB9KTtcbiAgfSxcblxuICBlcnJiYWNrOiBmdW5jdGlvbihjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4obnVsbCwgZnVuY3Rpb24ocmVhc29uKSB7IGNhbGxiYWNrLmNhbGwoY29udGV4dCwgcmVhc29uKSB9KTtcbiAgfSxcblxuICB0aW1lb3V0OiBmdW5jdGlvbihzZWNvbmRzLCBtZXNzYWdlKSB7XG4gICAgdGhpcy50aGVuKCk7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuX3RpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLl9yZWplY3QobWVzc2FnZSk7XG4gICAgfSwgc2Vjb25kcyAqIDEwMDApO1xuICB9LFxuXG4gIHNldERlZmVycmVkU3RhdHVzOiBmdW5jdGlvbihzdGF0dXMsIHZhbHVlKSB7XG4gICAgaWYgKHRoaXMuX3RpbWVyKSBnbG9iYWwuY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcblxuICAgIHRoaXMudGhlbigpO1xuXG4gICAgaWYgKHN0YXR1cyA9PT0gJ3N1Y2NlZWRlZCcpXG4gICAgICB0aGlzLl9yZXNvbHZlKHZhbHVlKTtcbiAgICBlbHNlIGlmIChzdGF0dXMgPT09ICdmYWlsZWQnKVxuICAgICAgdGhpcy5fcmVqZWN0KHZhbHVlKTtcbiAgICBlbHNlXG4gICAgICBkZWxldGUgdGhpcy5fcHJvbWlzZTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHRvSlNPTiA9IHJlcXVpcmUoJy4uL3V0aWwvdG9fanNvbicpO1xuXG52YXIgTG9nZ2luZyA9IHtcbiAgTE9HX0xFVkVMUzoge1xuICAgIGZhdGFsOiAgNCxcbiAgICBlcnJvcjogIDMsXG4gICAgd2FybjogICAyLFxuICAgIGluZm86ICAgMSxcbiAgICBkZWJ1ZzogIDBcbiAgfSxcblxuICB3cml0ZUxvZzogZnVuY3Rpb24obWVzc2FnZUFyZ3MsIGxldmVsKSB7XG4gICAgdmFyIGxvZ2dlciA9IExvZ2dpbmcubG9nZ2VyIHx8IChMb2dnaW5nLndyYXBwZXIgfHwgTG9nZ2luZykubG9nZ2VyO1xuICAgIGlmICghbG9nZ2VyKSByZXR1cm47XG5cbiAgICB2YXIgYXJncyAgID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KG1lc3NhZ2VBcmdzKSxcbiAgICAgICAgYmFubmVyID0gJ1tGYXllJyxcbiAgICAgICAga2xhc3MgID0gdGhpcy5jbGFzc05hbWUsXG5cbiAgICAgICAgbWVzc2FnZSA9IGFyZ3Muc2hpZnQoKS5yZXBsYWNlKC9cXD8vZywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0b0pTT04oYXJncy5zaGlmdCgpKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuICdbT2JqZWN0XSc7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgIGlmIChrbGFzcykgYmFubmVyICs9ICcuJyArIGtsYXNzO1xuICAgIGJhbm5lciArPSAnXSAnO1xuXG4gICAgaWYgKHR5cGVvZiBsb2dnZXJbbGV2ZWxdID09PSAnZnVuY3Rpb24nKVxuICAgICAgbG9nZ2VyW2xldmVsXShiYW5uZXIgKyBtZXNzYWdlKTtcbiAgICBlbHNlIGlmICh0eXBlb2YgbG9nZ2VyID09PSAnZnVuY3Rpb24nKVxuICAgICAgbG9nZ2VyKGJhbm5lciArIG1lc3NhZ2UpO1xuICB9XG59O1xuXG5mb3IgKHZhciBrZXkgaW4gTG9nZ2luZy5MT0dfTEVWRUxTKVxuICAoZnVuY3Rpb24obGV2ZWwpIHtcbiAgICBMb2dnaW5nW2xldmVsXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy53cml0ZUxvZyhhcmd1bWVudHMsIGxldmVsKTtcbiAgICB9O1xuICB9KShrZXkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExvZ2dpbmc7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL3V0aWwvZXZlbnRfZW1pdHRlcicpO1xuXG52YXIgUHVibGlzaGVyID0ge1xuICBjb3VudExpc3RlbmVyczogZnVuY3Rpb24oZXZlbnRUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXJzKGV2ZW50VHlwZSkubGVuZ3RoO1xuICB9LFxuXG4gIGJpbmQ6IGZ1bmN0aW9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIGNvbnRleHQpIHtcbiAgICB2YXIgc2xpY2UgICA9IEFycmF5LnByb3RvdHlwZS5zbGljZSxcbiAgICAgICAgaGFuZGxlciA9IGZ1bmN0aW9uKCkgeyBsaXN0ZW5lci5hcHBseShjb250ZXh0LCBzbGljZS5jYWxsKGFyZ3VtZW50cykpIH07XG5cbiAgICB0aGlzLl9saXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnMgfHwgW107XG4gICAgdGhpcy5fbGlzdGVuZXJzLnB1c2goW2V2ZW50VHlwZSwgbGlzdGVuZXIsIGNvbnRleHQsIGhhbmRsZXJdKTtcbiAgICByZXR1cm4gdGhpcy5vbihldmVudFR5cGUsIGhhbmRsZXIpO1xuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24oZXZlbnRUeXBlLCBsaXN0ZW5lciwgY29udGV4dCkge1xuICAgIHRoaXMuX2xpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycyB8fCBbXTtcbiAgICB2YXIgbiA9IHRoaXMuX2xpc3RlbmVycy5sZW5ndGgsIHR1cGxlO1xuXG4gICAgd2hpbGUgKG4tLSkge1xuICAgICAgdHVwbGUgPSB0aGlzLl9saXN0ZW5lcnNbbl07XG4gICAgICBpZiAodHVwbGVbMF0gIT09IGV2ZW50VHlwZSkgY29udGludWU7XG4gICAgICBpZiAobGlzdGVuZXIgJiYgKHR1cGxlWzFdICE9PSBsaXN0ZW5lciB8fCB0dXBsZVsyXSAhPT0gY29udGV4dCkpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShuLCAxKTtcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCB0dXBsZVszXSk7XG4gICAgfVxuICB9XG59O1xuXG5leHRlbmQoUHVibGlzaGVyLCBFdmVudEVtaXR0ZXIucHJvdG90eXBlKTtcblB1Ymxpc2hlci50cmlnZ2VyID0gUHVibGlzaGVyLmVtaXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gUHVibGlzaGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYWRkVGltZW91dDogZnVuY3Rpb24obmFtZSwgZGVsYXksIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fdGltZW91dHMgPSB0aGlzLl90aW1lb3V0cyB8fCB7fTtcbiAgICBpZiAodGhpcy5fdGltZW91dHMuaGFzT3duUHJvcGVydHkobmFtZSkpIHJldHVybjtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fdGltZW91dHNbbmFtZV0gPSBnbG9iYWwuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIGRlbGV0ZSBzZWxmLl90aW1lb3V0c1tuYW1lXTtcbiAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCk7XG4gICAgfSwgMTAwMCAqIGRlbGF5KTtcbiAgfSxcblxuICByZW1vdmVUaW1lb3V0OiBmdW5jdGlvbihuYW1lKSB7XG4gICAgdGhpcy5fdGltZW91dHMgPSB0aGlzLl90aW1lb3V0cyB8fCB7fTtcbiAgICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXRzW25hbWVdO1xuICAgIGlmICghdGltZW91dCkgcmV0dXJuO1xuICAgIGdsb2JhbC5jbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgZGVsZXRlIHRoaXMuX3RpbWVvdXRzW25hbWVdO1xuICB9LFxuXG4gIHJlbW92ZUFsbFRpbWVvdXRzOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl90aW1lb3V0cyA9IHRoaXMuX3RpbWVvdXRzIHx8IHt9O1xuICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcy5fdGltZW91dHMpIHRoaXMucmVtb3ZlVGltZW91dChuYW1lKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBleHRlbmQgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIFB1Ymxpc2hlciA9IHJlcXVpcmUoJy4uL21peGlucy9wdWJsaXNoZXInKSxcbiAgICBHcmFtbWFyICAgPSByZXF1aXJlKCcuL2dyYW1tYXInKTtcblxudmFyIENoYW5uZWwgPSBDbGFzcyh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB0aGlzLmlkID0gdGhpcy5uYW1lID0gbmFtZTtcbiAgfSxcblxuICBwdXNoOiBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgdGhpcy50cmlnZ2VyKCdtZXNzYWdlJywgbWVzc2FnZSk7XG4gIH0sXG5cbiAgaXNVbnVzZWQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNvdW50TGlzdGVuZXJzKCdtZXNzYWdlJykgPT09IDA7XG4gIH1cbn0pO1xuXG5leHRlbmQoQ2hhbm5lbC5wcm90b3R5cGUsIFB1Ymxpc2hlcik7XG5cbmV4dGVuZChDaGFubmVsLCB7XG4gIEhBTkRTSEFLRTogICAgJy9tZXRhL2hhbmRzaGFrZScsXG4gIENPTk5FQ1Q6ICAgICAgJy9tZXRhL2Nvbm5lY3QnLFxuICBTVUJTQ1JJQkU6ICAgICcvbWV0YS9zdWJzY3JpYmUnLFxuICBVTlNVQlNDUklCRTogICcvbWV0YS91bnN1YnNjcmliZScsXG4gIERJU0NPTk5FQ1Q6ICAgJy9tZXRhL2Rpc2Nvbm5lY3QnLFxuXG4gIE1FVEE6ICAgICAgICAgJ21ldGEnLFxuICBTRVJWSUNFOiAgICAgICdzZXJ2aWNlJyxcblxuICBleHBhbmQ6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgc2VnbWVudHMgPSB0aGlzLnBhcnNlKG5hbWUpLFxuICAgICAgICBjaGFubmVscyA9IFsnLyoqJywgbmFtZV07XG5cbiAgICB2YXIgY29weSA9IHNlZ21lbnRzLnNsaWNlKCk7XG4gICAgY29weVtjb3B5Lmxlbmd0aCAtIDFdID0gJyonO1xuICAgIGNoYW5uZWxzLnB1c2godGhpcy51bnBhcnNlKGNvcHkpKTtcblxuICAgIGZvciAodmFyIGkgPSAxLCBuID0gc2VnbWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICBjb3B5ID0gc2VnbWVudHMuc2xpY2UoMCwgaSk7XG4gICAgICBjb3B5LnB1c2goJyoqJyk7XG4gICAgICBjaGFubmVscy5wdXNoKHRoaXMudW5wYXJzZShjb3B5KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNoYW5uZWxzO1xuICB9LFxuXG4gIGlzVmFsaWQ6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gR3JhbW1hci5DSEFOTkVMX05BTUUudGVzdChuYW1lKSB8fFxuICAgICAgICAgICBHcmFtbWFyLkNIQU5ORUxfUEFUVEVSTi50ZXN0KG5hbWUpO1xuICB9LFxuXG4gIHBhcnNlOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWQobmFtZSkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBuYW1lLnNwbGl0KCcvJykuc2xpY2UoMSk7XG4gIH0sXG5cbiAgdW5wYXJzZTogZnVuY3Rpb24oc2VnbWVudHMpIHtcbiAgICByZXR1cm4gJy8nICsgc2VnbWVudHMuam9pbignLycpO1xuICB9LFxuXG4gIGlzTWV0YTogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBzZWdtZW50cyA9IHRoaXMucGFyc2UobmFtZSk7XG4gICAgcmV0dXJuIHNlZ21lbnRzID8gKHNlZ21lbnRzWzBdID09PSB0aGlzLk1FVEEpIDogbnVsbDtcbiAgfSxcblxuICBpc1NlcnZpY2U6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgc2VnbWVudHMgPSB0aGlzLnBhcnNlKG5hbWUpO1xuICAgIHJldHVybiBzZWdtZW50cyA/IChzZWdtZW50c1swXSA9PT0gdGhpcy5TRVJWSUNFKSA6IG51bGw7XG4gIH0sXG5cbiAgaXNTdWJzY3JpYmFibGU6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZChuYW1lKSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuICF0aGlzLmlzTWV0YShuYW1lKSAmJiAhdGhpcy5pc1NlcnZpY2UobmFtZSk7XG4gIH0sXG5cbiAgU2V0OiBDbGFzcyh7XG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLl9jaGFubmVscyA9IHt9O1xuICAgIH0sXG5cbiAgICBnZXRLZXlzOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrZXlzID0gW107XG4gICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5fY2hhbm5lbHMpIGtleXMucHVzaChrZXkpO1xuICAgICAgcmV0dXJuIGtleXM7XG4gICAgfSxcblxuICAgIHJlbW92ZTogZnVuY3Rpb24obmFtZSkge1xuICAgICAgZGVsZXRlIHRoaXMuX2NoYW5uZWxzW25hbWVdO1xuICAgIH0sXG5cbiAgICBoYXNTdWJzY3JpcHRpb246IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jaGFubmVscy5oYXNPd25Qcm9wZXJ0eShuYW1lKTtcbiAgICB9LFxuXG4gICAgc3Vic2NyaWJlOiBmdW5jdGlvbihuYW1lcywgc3Vic2NyaXB0aW9uKSB7XG4gICAgICB2YXIgbmFtZTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBuID0gbmFtZXMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lc1tpXTtcbiAgICAgICAgdmFyIGNoYW5uZWwgPSB0aGlzLl9jaGFubmVsc1tuYW1lXSA9IHRoaXMuX2NoYW5uZWxzW25hbWVdIHx8IG5ldyBDaGFubmVsKG5hbWUpO1xuICAgICAgICBjaGFubmVsLmJpbmQoJ21lc3NhZ2UnLCBzdWJzY3JpcHRpb24pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICB1bnN1YnNjcmliZTogZnVuY3Rpb24obmFtZSwgc3Vic2NyaXB0aW9uKSB7XG4gICAgICB2YXIgY2hhbm5lbCA9IHRoaXMuX2NoYW5uZWxzW25hbWVdO1xuICAgICAgaWYgKCFjaGFubmVsKSByZXR1cm4gZmFsc2U7XG4gICAgICBjaGFubmVsLnVuYmluZCgnbWVzc2FnZScsIHN1YnNjcmlwdGlvbik7XG5cbiAgICAgIGlmIChjaGFubmVsLmlzVW51c2VkKCkpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUobmFtZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBkaXN0cmlidXRlTWVzc2FnZTogZnVuY3Rpb24obWVzc2FnZSkge1xuICAgICAgdmFyIGNoYW5uZWxzID0gQ2hhbm5lbC5leHBhbmQobWVzc2FnZS5jaGFubmVsKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBjaGFubmVscy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIGNoYW5uZWwgPSB0aGlzLl9jaGFubmVsc1tjaGFubmVsc1tpXV07XG4gICAgICAgIGlmIChjaGFubmVsKSBjaGFubmVsLnRyaWdnZXIoJ21lc3NhZ2UnLCBtZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBDaGFubmVsO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNhcCAgICAgICAgICAgID0gcmVxdWlyZSgnYXNhcCcpLFxuICAgIENsYXNzICAgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBQcm9taXNlICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3Byb21pc2UnKSxcbiAgICBVUkkgICAgICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3VyaScpLFxuICAgIGFycmF5ICAgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvYXJyYXknKSxcbiAgICBicm93c2VyICAgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2Jyb3dzZXInKSxcbiAgICBjb25zdGFudHMgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2NvbnN0YW50cycpLFxuICAgIGV4dGVuZCAgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgdmFsaWRhdGVPcHRpb25zID0gcmVxdWlyZSgnLi4vdXRpbC92YWxpZGF0ZV9vcHRpb25zJyksXG4gICAgRGVmZXJyYWJsZSAgICAgID0gcmVxdWlyZSgnLi4vbWl4aW5zL2RlZmVycmFibGUnKSxcbiAgICBMb2dnaW5nICAgICAgICAgPSByZXF1aXJlKCcuLi9taXhpbnMvbG9nZ2luZycpLFxuICAgIFB1Ymxpc2hlciAgICAgICA9IHJlcXVpcmUoJy4uL21peGlucy9wdWJsaXNoZXInKSxcbiAgICBDaGFubmVsICAgICAgICAgPSByZXF1aXJlKCcuL2NoYW5uZWwnKSxcbiAgICBEaXNwYXRjaGVyICAgICAgPSByZXF1aXJlKCcuL2Rpc3BhdGNoZXInKSxcbiAgICBFcnJvciAgICAgICAgICAgPSByZXF1aXJlKCcuL2Vycm9yJyksXG4gICAgRXh0ZW5zaWJsZSAgICAgID0gcmVxdWlyZSgnLi9leHRlbnNpYmxlJyksXG4gICAgUHVibGljYXRpb24gICAgID0gcmVxdWlyZSgnLi9wdWJsaWNhdGlvbicpLFxuICAgIFN1YnNjcmlwdGlvbiAgICA9IHJlcXVpcmUoJy4vc3Vic2NyaXB0aW9uJyk7XG5cbnZhciBDbGllbnQgPSBDbGFzcyh7IGNsYXNzTmFtZTogJ0NsaWVudCcsXG4gIFVOQ09OTkVDVEVEOiAgICAgICAgMSxcbiAgQ09OTkVDVElORzogICAgICAgICAyLFxuICBDT05ORUNURUQ6ICAgICAgICAgIDMsXG4gIERJU0NPTk5FQ1RFRDogICAgICAgNCxcblxuICBIQU5EU0hBS0U6ICAgICAgICAgICdoYW5kc2hha2UnLFxuICBSRVRSWTogICAgICAgICAgICAgICdyZXRyeScsXG4gIE5PTkU6ICAgICAgICAgICAgICAgJ25vbmUnLFxuXG4gIENPTk5FQ1RJT05fVElNRU9VVDogNjAsXG5cbiAgREVGQVVMVF9FTkRQT0lOVDogICAnL2JheWV1eCcsXG4gIElOVEVSVkFMOiAgICAgICAgICAgMCxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihlbmRwb2ludCwgb3B0aW9ucykge1xuICAgIHRoaXMuaW5mbygnTmV3IGNsaWVudCBjcmVhdGVkIGZvciA/JywgZW5kcG9pbnQpO1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgdmFsaWRhdGVPcHRpb25zKG9wdGlvbnMsIFsnaW50ZXJ2YWwnLCAndGltZW91dCcsICdlbmRwb2ludHMnLCAncHJveHknLCAncmV0cnknLCAnc2NoZWR1bGVyJywgJ3dlYnNvY2tldEV4dGVuc2lvbnMnLCAndGxzJywgJ2NhJ10pO1xuXG4gICAgdGhpcy5fY2hhbm5lbHMgICA9IG5ldyBDaGFubmVsLlNldCgpO1xuICAgIHRoaXMuX2Rpc3BhdGNoZXIgPSBEaXNwYXRjaGVyLmNyZWF0ZSh0aGlzLCBlbmRwb2ludCB8fCB0aGlzLkRFRkFVTFRfRU5EUE9JTlQsIG9wdGlvbnMpO1xuXG4gICAgdGhpcy5fbWVzc2FnZUlkID0gMDtcbiAgICB0aGlzLl9zdGF0ZSAgICAgPSB0aGlzLlVOQ09OTkVDVEVEO1xuXG4gICAgdGhpcy5fcmVzcG9uc2VDYWxsYmFja3MgPSB7fTtcblxuICAgIHRoaXMuX2FkdmljZSA9IHtcbiAgICAgIHJlY29ubmVjdDogdGhpcy5SRVRSWSxcbiAgICAgIGludGVydmFsOiAgMTAwMCAqIChvcHRpb25zLmludGVydmFsIHx8IHRoaXMuSU5URVJWQUwpLFxuICAgICAgdGltZW91dDogICAxMDAwICogKG9wdGlvbnMudGltZW91dCAgfHwgdGhpcy5DT05ORUNUSU9OX1RJTUVPVVQpXG4gICAgfTtcbiAgICB0aGlzLl9kaXNwYXRjaGVyLnRpbWVvdXQgPSB0aGlzLl9hZHZpY2UudGltZW91dCAvIDEwMDA7XG5cbiAgICB0aGlzLl9kaXNwYXRjaGVyLmJpbmQoJ21lc3NhZ2UnLCB0aGlzLl9yZWNlaXZlTWVzc2FnZSwgdGhpcyk7XG5cbiAgICBpZiAoYnJvd3Nlci5FdmVudCAmJiBnbG9iYWwub25iZWZvcmV1bmxvYWQgIT09IHVuZGVmaW5lZClcbiAgICAgIGJyb3dzZXIuRXZlbnQub24oZ2xvYmFsLCAnYmVmb3JldW5sb2FkJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChhcnJheS5pbmRleE9mKHRoaXMuX2Rpc3BhdGNoZXIuX2Rpc2FibGVkLCAnYXV0b2Rpc2Nvbm5lY3QnKSA8IDApXG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgICB9LCB0aGlzKTtcbiAgfSxcblxuICBhZGRXZWJzb2NrZXRFeHRlbnNpb246IGZ1bmN0aW9uKGV4dGVuc2lvbikge1xuICAgIHJldHVybiB0aGlzLl9kaXNwYXRjaGVyLmFkZFdlYnNvY2tldEV4dGVuc2lvbihleHRlbnNpb24pO1xuICB9LFxuXG4gIGRpc2FibGU6IGZ1bmN0aW9uKGZlYXR1cmUpIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzcGF0Y2hlci5kaXNhYmxlKGZlYXR1cmUpO1xuICB9LFxuXG4gIHNldEhlYWRlcjogZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzcGF0Y2hlci5zZXRIZWFkZXIobmFtZSwgdmFsdWUpO1xuICB9LFxuXG4gIC8vIFJlcXVlc3RcbiAgLy8gTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsXG4gIC8vICAgICAgICAgICAgICAgICogdmVyc2lvblxuICAvLyAgICAgICAgICAgICAgICAqIHN1cHBvcnRlZENvbm5lY3Rpb25UeXBlc1xuICAvLyBNQVkgaW5jbHVkZTogICAqIG1pbmltdW1WZXJzaW9uXG4gIC8vICAgICAgICAgICAgICAgICogZXh0XG4gIC8vICAgICAgICAgICAgICAgICogaWRcbiAgLy9cbiAgLy8gU3VjY2VzcyBSZXNwb25zZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFpbGVkIFJlc3BvbnNlXG4gIC8vIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbCAgICAgICAgICAgICAgICAgICAgIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbFxuICAvLyAgICAgICAgICAgICAgICAqIHZlcnNpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHN1Y2Nlc3NmdWxcbiAgLy8gICAgICAgICAgICAgICAgKiBzdXBwb3J0ZWRDb25uZWN0aW9uVHlwZXMgICAgICAgICAgICAgICAgICAgKiBlcnJvclxuICAvLyAgICAgICAgICAgICAgICAqIGNsaWVudElkICAgICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIHN1cHBvcnRlZENvbm5lY3Rpb25UeXBlc1xuICAvLyAgICAgICAgICAgICAgICAqIHN1Y2Nlc3NmdWwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkdmljZVxuICAvLyBNQVkgaW5jbHVkZTogICAqIG1pbmltdW1WZXJzaW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHZlcnNpb25cbiAgLy8gICAgICAgICAgICAgICAgKiBhZHZpY2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBtaW5pbXVtVmVyc2lvblxuICAvLyAgICAgICAgICAgICAgICAqIGV4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4dFxuICAvLyAgICAgICAgICAgICAgICAqIGlkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGlkXG4gIC8vICAgICAgICAgICAgICAgICogYXV0aFN1Y2Nlc3NmdWxcbiAgaGFuZHNoYWtlOiBmdW5jdGlvbihjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmICh0aGlzLl9hZHZpY2UucmVjb25uZWN0ID09PSB0aGlzLk5PTkUpIHJldHVybjtcbiAgICBpZiAodGhpcy5fc3RhdGUgIT09IHRoaXMuVU5DT05ORUNURUQpIHJldHVybjtcblxuICAgIHRoaXMuX3N0YXRlID0gdGhpcy5DT05ORUNUSU5HO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHRoaXMuaW5mbygnSW5pdGlhdGluZyBoYW5kc2hha2Ugd2l0aCA/JywgVVJJLnN0cmluZ2lmeSh0aGlzLl9kaXNwYXRjaGVyLmVuZHBvaW50KSk7XG4gICAgdGhpcy5fZGlzcGF0Y2hlci5zZWxlY3RUcmFuc3BvcnQoY29uc3RhbnRzLk1BTkRBVE9SWV9DT05ORUNUSU9OX1RZUEVTKTtcblxuICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWw6ICAgICAgICAgICAgICAgICAgQ2hhbm5lbC5IQU5EU0hBS0UsXG4gICAgICB2ZXJzaW9uOiAgICAgICAgICAgICAgICAgIGNvbnN0YW50cy5CQVlFVVhfVkVSU0lPTixcbiAgICAgIHN1cHBvcnRlZENvbm5lY3Rpb25UeXBlczogdGhpcy5fZGlzcGF0Y2hlci5nZXRDb25uZWN0aW9uVHlwZXMoKVxuXG4gICAgfSwge30sIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG5cbiAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzZnVsKSB7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gdGhpcy5DT05ORUNURUQ7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQgID0gcmVzcG9uc2UuY2xpZW50SWQ7XG5cbiAgICAgICAgdGhpcy5fZGlzcGF0Y2hlci5zZWxlY3RUcmFuc3BvcnQocmVzcG9uc2Uuc3VwcG9ydGVkQ29ubmVjdGlvblR5cGVzKTtcblxuICAgICAgICB0aGlzLmluZm8oJ0hhbmRzaGFrZSBzdWNjZXNzZnVsOiA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCk7XG5cbiAgICAgICAgdGhpcy5zdWJzY3JpYmUodGhpcy5fY2hhbm5lbHMuZ2V0S2V5cygpLCB0cnVlKTtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSBhc2FwKGZ1bmN0aW9uKCkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQpIH0pO1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluZm8oJ0hhbmRzaGFrZSB1bnN1Y2Nlc3NmdWwnKTtcbiAgICAgICAgZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHNlbGYuaGFuZHNoYWtlKGNhbGxiYWNrLCBjb250ZXh0KSB9LCB0aGlzLl9kaXNwYXRjaGVyLnJldHJ5ICogMTAwMCk7XG4gICAgICAgIHRoaXMuX3N0YXRlID0gdGhpcy5VTkNPTk5FQ1RFRDtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgfSxcblxuICAvLyBSZXF1ZXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzcG9uc2VcbiAgLy8gTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsICAgICAgICAgICAgIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbFxuICAvLyAgICAgICAgICAgICAgICAqIGNsaWVudElkICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzdWNjZXNzZnVsXG4gIC8vICAgICAgICAgICAgICAgICogY29ubmVjdGlvblR5cGUgICAgICAgICAgICAgICAgICAgICAqIGNsaWVudElkXG4gIC8vIE1BWSBpbmNsdWRlOiAgICogZXh0ICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIGVycm9yXG4gIC8vICAgICAgICAgICAgICAgICogaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkdmljZVxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBleHRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaWRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdGltZXN0YW1wXG4gIGNvbm5lY3Q6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgaWYgKHRoaXMuX2FkdmljZS5yZWNvbm5lY3QgPT09IHRoaXMuTk9ORSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gdGhpcy5ESVNDT05ORUNURUQpIHJldHVybjtcblxuICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gdGhpcy5VTkNPTk5FQ1RFRClcbiAgICAgIHJldHVybiB0aGlzLmhhbmRzaGFrZShmdW5jdGlvbigpIHsgdGhpcy5jb25uZWN0KGNhbGxiYWNrLCBjb250ZXh0KSB9LCB0aGlzKTtcblxuICAgIHRoaXMuY2FsbGJhY2soY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gdGhpcy5DT05ORUNURUQpIHJldHVybjtcblxuICAgIHRoaXMuaW5mbygnQ2FsbGluZyBkZWZlcnJlZCBhY3Rpb25zIGZvciA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCk7XG4gICAgdGhpcy5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgdGhpcy5zZXREZWZlcnJlZFN0YXR1cygndW5rbm93bicpO1xuXG4gICAgaWYgKHRoaXMuX2Nvbm5lY3RSZXF1ZXN0KSByZXR1cm47XG4gICAgdGhpcy5fY29ubmVjdFJlcXVlc3QgPSB0cnVlO1xuXG4gICAgdGhpcy5pbmZvKCdJbml0aWF0aW5nIGNvbm5lY3Rpb24gZm9yID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkKTtcblxuICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWw6ICAgICAgICBDaGFubmVsLkNPTk5FQ1QsXG4gICAgICBjbGllbnRJZDogICAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCxcbiAgICAgIGNvbm5lY3Rpb25UeXBlOiB0aGlzLl9kaXNwYXRjaGVyLmNvbm5lY3Rpb25UeXBlXG5cbiAgICB9LCB7fSwgdGhpcy5fY3ljbGVDb25uZWN0aW9uLCB0aGlzKTtcbiAgfSxcblxuICAvLyBSZXF1ZXN0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzcG9uc2VcbiAgLy8gTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsICAgICAgICAgICAgIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbFxuICAvLyAgICAgICAgICAgICAgICAqIGNsaWVudElkICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzdWNjZXNzZnVsXG4gIC8vIE1BWSBpbmNsdWRlOiAgICogZXh0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGNsaWVudElkXG4gIC8vICAgICAgICAgICAgICAgICogaWQgICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIGVycm9yXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4dFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpZFxuICBkaXNjb25uZWN0OiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fc3RhdGUgIT09IHRoaXMuQ09OTkVDVEVEKSByZXR1cm47XG4gICAgdGhpcy5fc3RhdGUgPSB0aGlzLkRJU0NPTk5FQ1RFRDtcblxuICAgIHRoaXMuaW5mbygnRGlzY29ubmVjdGluZyA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCk7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHVibGljYXRpb24oKTtcblxuICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgIGNoYW5uZWw6ICBDaGFubmVsLkRJU0NPTk5FQ1QsXG4gICAgICBjbGllbnRJZDogdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZFxuXG4gICAgfSwge30sIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICBpZiAocmVzcG9uc2Uuc3VjY2Vzc2Z1bCkge1xuICAgICAgICB0aGlzLl9kaXNwYXRjaGVyLmNsb3NlKCk7XG4gICAgICAgIHByb21pc2Uuc2V0RGVmZXJyZWRTdGF0dXMoJ3N1Y2NlZWRlZCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJvbWlzZS5zZXREZWZlcnJlZFN0YXR1cygnZmFpbGVkJywgRXJyb3IucGFyc2UocmVzcG9uc2UuZXJyb3IpKTtcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcblxuICAgIHRoaXMuaW5mbygnQ2xlYXJpbmcgY2hhbm5lbCBsaXN0ZW5lcnMgZm9yID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkKTtcbiAgICB0aGlzLl9jaGFubmVscyA9IG5ldyBDaGFubmVsLlNldCgpO1xuXG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH0sXG5cbiAgLy8gUmVxdWVzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3BvbnNlXG4gIC8vIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbCAgICAgICAgICAgICBNVVNUIGluY2x1ZGU6ICAqIGNoYW5uZWxcbiAgLy8gICAgICAgICAgICAgICAgKiBjbGllbnRJZCAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3VjY2Vzc2Z1bFxuICAvLyAgICAgICAgICAgICAgICAqIHN1YnNjcmlwdGlvbiAgICAgICAgICAgICAgICAgICAgICAgKiBjbGllbnRJZFxuICAvLyBNQVkgaW5jbHVkZTogICAqIGV4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzdWJzY3JpcHRpb25cbiAgLy8gICAgICAgICAgICAgICAgKiBpZCAgICAgICAgICAgICAgICAgIE1BWSBpbmNsdWRlOiAgICogZXJyb3JcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogYWR2aWNlXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGV4dFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpZFxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0aW1lc3RhbXBcbiAgc3Vic2NyaWJlOiBmdW5jdGlvbihjaGFubmVsLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmIChjaGFubmVsIGluc3RhbmNlb2YgQXJyYXkpXG4gICAgICByZXR1cm4gYXJyYXkubWFwKGNoYW5uZWwsIGZ1bmN0aW9uKGMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3Vic2NyaWJlKGMsIGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgICAgIH0sIHRoaXMpO1xuXG4gICAgdmFyIHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24odGhpcywgY2hhbm5lbCwgY2FsbGJhY2ssIGNvbnRleHQpLFxuICAgICAgICBmb3JjZSAgICAgICAgPSAoY2FsbGJhY2sgPT09IHRydWUpLFxuICAgICAgICBoYXNTdWJzY3JpYmUgPSB0aGlzLl9jaGFubmVscy5oYXNTdWJzY3JpcHRpb24oY2hhbm5lbCk7XG5cbiAgICBpZiAoaGFzU3Vic2NyaWJlICYmICFmb3JjZSkge1xuICAgICAgdGhpcy5fY2hhbm5lbHMuc3Vic2NyaWJlKFtjaGFubmVsXSwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIHN1YnNjcmlwdGlvbi5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgICByZXR1cm4gc3Vic2NyaXB0aW9uO1xuICAgIH1cblxuICAgIHRoaXMuY29ubmVjdChmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuaW5mbygnQ2xpZW50ID8gYXR0ZW1wdGluZyB0byBzdWJzY3JpYmUgdG8gPycsIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQsIGNoYW5uZWwpO1xuICAgICAgaWYgKCFmb3JjZSkgdGhpcy5fY2hhbm5lbHMuc3Vic2NyaWJlKFtjaGFubmVsXSwgc3Vic2NyaXB0aW9uKTtcblxuICAgICAgdGhpcy5fc2VuZE1lc3NhZ2Uoe1xuICAgICAgICBjaGFubmVsOiAgICAgIENoYW5uZWwuU1VCU0NSSUJFLFxuICAgICAgICBjbGllbnRJZDogICAgIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQsXG4gICAgICAgIHN1YnNjcmlwdGlvbjogY2hhbm5lbFxuXG4gICAgICB9LCB7fSwgZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdWNjZXNzZnVsKSB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uLnNldERlZmVycmVkU3RhdHVzKCdmYWlsZWQnLCBFcnJvci5wYXJzZShyZXNwb25zZS5lcnJvcikpO1xuICAgICAgICAgIHJldHVybiB0aGlzLl9jaGFubmVscy51bnN1YnNjcmliZShjaGFubmVsLCBzdWJzY3JpcHRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNoYW5uZWxzID0gW10uY29uY2F0KHJlc3BvbnNlLnN1YnNjcmlwdGlvbik7XG4gICAgICAgIHRoaXMuaW5mbygnU3Vic2NyaXB0aW9uIGFja25vd2xlZGdlZCBmb3IgPyB0byA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgY2hhbm5lbHMpO1xuICAgICAgICBzdWJzY3JpcHRpb24uc2V0RGVmZXJyZWRTdGF0dXMoJ3N1Y2NlZWRlZCcpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gc3Vic2NyaXB0aW9uO1xuICB9LFxuXG4gIC8vIFJlcXVlc3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNwb25zZVxuICAvLyBNVVNUIGluY2x1ZGU6ICAqIGNoYW5uZWwgICAgICAgICAgICAgTVVTVCBpbmNsdWRlOiAgKiBjaGFubmVsXG4gIC8vICAgICAgICAgICAgICAgICogY2xpZW50SWQgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHN1Y2Nlc3NmdWxcbiAgLy8gICAgICAgICAgICAgICAgKiBzdWJzY3JpcHRpb24gICAgICAgICAgICAgICAgICAgICAgICogY2xpZW50SWRcbiAgLy8gTUFZIGluY2x1ZGU6ICAgKiBleHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3Vic2NyaXB0aW9uXG4gIC8vICAgICAgICAgICAgICAgICogaWQgICAgICAgICAgICAgICAgICBNQVkgaW5jbHVkZTogICAqIGVycm9yXG4gIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkdmljZVxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBleHRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogaWRcbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdGltZXN0YW1wXG4gIHVuc3Vic2NyaWJlOiBmdW5jdGlvbihjaGFubmVsLCBzdWJzY3JpcHRpb24pIHtcbiAgICBpZiAoY2hhbm5lbCBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgcmV0dXJuIGFycmF5Lm1hcChjaGFubmVsLCBmdW5jdGlvbihjKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuc3Vic2NyaWJlKGMsIHN1YnNjcmlwdGlvbik7XG4gICAgICB9LCB0aGlzKTtcblxuICAgIHZhciBkZWFkID0gdGhpcy5fY2hhbm5lbHMudW5zdWJzY3JpYmUoY2hhbm5lbCwgc3Vic2NyaXB0aW9uKTtcbiAgICBpZiAoIWRlYWQpIHJldHVybjtcblxuICAgIHRoaXMuY29ubmVjdChmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuaW5mbygnQ2xpZW50ID8gYXR0ZW1wdGluZyB0byB1bnN1YnNjcmliZSBmcm9tID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkLCBjaGFubmVsKTtcblxuICAgICAgdGhpcy5fc2VuZE1lc3NhZ2Uoe1xuICAgICAgICBjaGFubmVsOiAgICAgIENoYW5uZWwuVU5TVUJTQ1JJQkUsXG4gICAgICAgIGNsaWVudElkOiAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCxcbiAgICAgICAgc3Vic2NyaXB0aW9uOiBjaGFubmVsXG5cbiAgICAgIH0sIHt9LCBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnN1Y2Nlc3NmdWwpIHJldHVybjtcblxuICAgICAgICB2YXIgY2hhbm5lbHMgPSBbXS5jb25jYXQocmVzcG9uc2Uuc3Vic2NyaXB0aW9uKTtcbiAgICAgICAgdGhpcy5pbmZvKCdVbnN1YnNjcmlwdGlvbiBhY2tub3dsZWRnZWQgZm9yID8gZnJvbSA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgY2hhbm5lbHMpO1xuICAgICAgfSwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG4gIH0sXG5cbiAgLy8gUmVxdWVzdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc3BvbnNlXG4gIC8vIE1VU1QgaW5jbHVkZTogICogY2hhbm5lbCAgICAgICAgICAgICBNVVNUIGluY2x1ZGU6ICAqIGNoYW5uZWxcbiAgLy8gICAgICAgICAgICAgICAgKiBkYXRhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc3VjY2Vzc2Z1bFxuICAvLyBNQVkgaW5jbHVkZTogICAqIGNsaWVudElkICAgICAgICAgICAgTUFZIGluY2x1ZGU6ICAgKiBpZFxuICAvLyAgICAgICAgICAgICAgICAqIGlkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBlcnJvclxuICAvLyAgICAgICAgICAgICAgICAqIGV4dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBleHRcbiAgcHVibGlzaDogZnVuY3Rpb24oY2hhbm5lbCwgZGF0YSwgb3B0aW9ucykge1xuICAgIHZhbGlkYXRlT3B0aW9ucyhvcHRpb25zIHx8IHt9LCBbJ2F0dGVtcHRzJywgJ2RlYWRsaW5lJ10pO1xuICAgIHZhciBwdWJsaWNhdGlvbiA9IG5ldyBQdWJsaWNhdGlvbigpO1xuXG4gICAgdGhpcy5jb25uZWN0KGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5pbmZvKCdDbGllbnQgPyBxdWV1ZWluZyBwdWJsaXNoZWQgbWVzc2FnZSB0byA/OiA/JywgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgY2hhbm5lbCwgZGF0YSk7XG5cbiAgICAgIHRoaXMuX3NlbmRNZXNzYWdlKHtcbiAgICAgICAgY2hhbm5lbDogIGNoYW5uZWwsXG4gICAgICAgIGRhdGE6ICAgICBkYXRhLFxuICAgICAgICBjbGllbnRJZDogdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZFxuXG4gICAgICB9LCBvcHRpb25zLCBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgICAgICBpZiAocmVzcG9uc2Uuc3VjY2Vzc2Z1bClcbiAgICAgICAgICBwdWJsaWNhdGlvbi5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBwdWJsaWNhdGlvbi5zZXREZWZlcnJlZFN0YXR1cygnZmFpbGVkJywgRXJyb3IucGFyc2UocmVzcG9uc2UuZXJyb3IpKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIHB1YmxpY2F0aW9uO1xuICB9LFxuXG4gIF9zZW5kTWVzc2FnZTogZnVuY3Rpb24obWVzc2FnZSwgb3B0aW9ucywgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBtZXNzYWdlLmlkID0gdGhpcy5fZ2VuZXJhdGVNZXNzYWdlSWQoKTtcblxuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fYWR2aWNlLnRpbWVvdXRcbiAgICAgICAgICAgICAgICA/IDEuMiAqIHRoaXMuX2FkdmljZS50aW1lb3V0IC8gMTAwMFxuICAgICAgICAgICAgICAgIDogMS4yICogdGhpcy5fZGlzcGF0Y2hlci5yZXRyeTtcblxuICAgIHRoaXMucGlwZVRocm91Z2hFeHRlbnNpb25zKCdvdXRnb2luZycsIG1lc3NhZ2UsIG51bGwsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGlmICghbWVzc2FnZSkgcmV0dXJuO1xuICAgICAgaWYgKGNhbGxiYWNrKSB0aGlzLl9yZXNwb25zZUNhbGxiYWNrc1ttZXNzYWdlLmlkXSA9IFtjYWxsYmFjaywgY29udGV4dF07XG4gICAgICB0aGlzLl9kaXNwYXRjaGVyLnNlbmRNZXNzYWdlKG1lc3NhZ2UsIHRpbWVvdXQsIG9wdGlvbnMgfHwge30pO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuXG4gIF9nZW5lcmF0ZU1lc3NhZ2VJZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbWVzc2FnZUlkICs9IDE7XG4gICAgaWYgKHRoaXMuX21lc3NhZ2VJZCA+PSBNYXRoLnBvdygyLDMyKSkgdGhpcy5fbWVzc2FnZUlkID0gMDtcbiAgICByZXR1cm4gdGhpcy5fbWVzc2FnZUlkLnRvU3RyaW5nKDM2KTtcbiAgfSxcblxuICBfcmVjZWl2ZU1lc3NhZ2U6IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICB2YXIgaWQgPSBtZXNzYWdlLmlkLCBjYWxsYmFjaztcblxuICAgIGlmIChtZXNzYWdlLnN1Y2Nlc3NmdWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FsbGJhY2sgPSB0aGlzLl9yZXNwb25zZUNhbGxiYWNrc1tpZF07XG4gICAgICBkZWxldGUgdGhpcy5fcmVzcG9uc2VDYWxsYmFja3NbaWRdO1xuICAgIH1cblxuICAgIHRoaXMucGlwZVRocm91Z2hFeHRlbnNpb25zKCdpbmNvbWluZycsIG1lc3NhZ2UsIG51bGwsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgIGlmICghbWVzc2FnZSkgcmV0dXJuO1xuICAgICAgaWYgKG1lc3NhZ2UuYWR2aWNlKSB0aGlzLl9oYW5kbGVBZHZpY2UobWVzc2FnZS5hZHZpY2UpO1xuICAgICAgdGhpcy5fZGVsaXZlck1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrWzBdLmNhbGwoY2FsbGJhY2tbMV0sIG1lc3NhZ2UpO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuXG4gIF9oYW5kbGVBZHZpY2U6IGZ1bmN0aW9uKGFkdmljZSkge1xuICAgIGV4dGVuZCh0aGlzLl9hZHZpY2UsIGFkdmljZSk7XG4gICAgdGhpcy5fZGlzcGF0Y2hlci50aW1lb3V0ID0gdGhpcy5fYWR2aWNlLnRpbWVvdXQgLyAxMDAwO1xuXG4gICAgaWYgKHRoaXMuX2FkdmljZS5yZWNvbm5lY3QgPT09IHRoaXMuSEFORFNIQUtFICYmIHRoaXMuX3N0YXRlICE9PSB0aGlzLkRJU0NPTk5FQ1RFRCkge1xuICAgICAgdGhpcy5fc3RhdGUgPSB0aGlzLlVOQ09OTkVDVEVEO1xuICAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCA9IG51bGw7XG4gICAgICB0aGlzLl9jeWNsZUNvbm5lY3Rpb24oKTtcbiAgICB9XG4gIH0sXG5cbiAgX2RlbGl2ZXJNZXNzYWdlOiBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlLmNoYW5uZWwgfHwgbWVzc2FnZS5kYXRhID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICB0aGlzLmluZm8oJ0NsaWVudCA/IGNhbGxpbmcgbGlzdGVuZXJzIGZvciA/IHdpdGggPycsIHRoaXMuX2Rpc3BhdGNoZXIuY2xpZW50SWQsIG1lc3NhZ2UuY2hhbm5lbCwgbWVzc2FnZS5kYXRhKTtcbiAgICB0aGlzLl9jaGFubmVscy5kaXN0cmlidXRlTWVzc2FnZShtZXNzYWdlKTtcbiAgfSxcblxuICBfY3ljbGVDb25uZWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fY29ubmVjdFJlcXVlc3QpIHtcbiAgICAgIHRoaXMuX2Nvbm5lY3RSZXF1ZXN0ID0gbnVsbDtcbiAgICAgIHRoaXMuaW5mbygnQ2xvc2VkIGNvbm5lY3Rpb24gZm9yID8nLCB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkKTtcbiAgICB9XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGdsb2JhbC5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBzZWxmLmNvbm5lY3QoKSB9LCB0aGlzLl9hZHZpY2UuaW50ZXJ2YWwpO1xuICB9XG59KTtcblxuZXh0ZW5kKENsaWVudC5wcm90b3R5cGUsIERlZmVycmFibGUpO1xuZXh0ZW5kKENsaWVudC5wcm90b3R5cGUsIFB1Ymxpc2hlcik7XG5leHRlbmQoQ2xpZW50LnByb3RvdHlwZSwgTG9nZ2luZyk7XG5leHRlbmQoQ2xpZW50LnByb3RvdHlwZSwgRXh0ZW5zaWJsZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2xpZW50O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3MgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9jbGFzcycpLFxuICAgIFVSSSAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvdXJpJyksXG4gICAgY29va2llcyAgID0gcmVxdWlyZSgnLi4vdXRpbC9jb29raWVzJyksXG4gICAgZXh0ZW5kICAgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICBMb2dnaW5nICAgPSByZXF1aXJlKCcuLi9taXhpbnMvbG9nZ2luZycpLFxuICAgIFB1Ymxpc2hlciA9IHJlcXVpcmUoJy4uL21peGlucy9wdWJsaXNoZXInKSxcbiAgICBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKSxcbiAgICBTY2hlZHVsZXIgPSByZXF1aXJlKCcuL3NjaGVkdWxlcicpO1xuXG52YXIgRGlzcGF0Y2hlciA9IENsYXNzKHsgY2xhc3NOYW1lOiAnRGlzcGF0Y2hlcicsXG4gIE1BWF9SRVFVRVNUX1NJWkU6IDIwNDgsXG4gIERFRkFVTFRfUkVUUlk6ICAgIDUsXG5cbiAgVVA6ICAgMSxcbiAgRE9XTjogMixcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihjbGllbnQsIGVuZHBvaW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy5fY2xpZW50ICAgICA9IGNsaWVudDtcbiAgICB0aGlzLmVuZHBvaW50ICAgID0gVVJJLnBhcnNlKGVuZHBvaW50KTtcbiAgICB0aGlzLl9hbHRlcm5hdGVzID0gb3B0aW9ucy5lbmRwb2ludHMgfHwge307XG5cbiAgICB0aGlzLmNvb2tpZXMgICAgICA9IGNvb2tpZXMuQ29va2llSmFyICYmIG5ldyBjb29raWVzLkNvb2tpZUphcigpO1xuICAgIHRoaXMuX2Rpc2FibGVkICAgID0gW107XG4gICAgdGhpcy5fZW52ZWxvcGVzICAgPSB7fTtcbiAgICB0aGlzLmhlYWRlcnMgICAgICA9IHt9O1xuICAgIHRoaXMucmV0cnkgICAgICAgID0gb3B0aW9ucy5yZXRyeSB8fCB0aGlzLkRFRkFVTFRfUkVUUlk7XG4gICAgdGhpcy5fc2NoZWR1bGVyICAgPSBvcHRpb25zLnNjaGVkdWxlciB8fCBTY2hlZHVsZXI7XG4gICAgdGhpcy5fc3RhdGUgICAgICAgPSAwO1xuICAgIHRoaXMudHJhbnNwb3J0cyAgID0ge307XG4gICAgdGhpcy53c0V4dGVuc2lvbnMgPSBbXTtcblxuICAgIHRoaXMucHJveHkgPSBvcHRpb25zLnByb3h5IHx8IHt9O1xuICAgIGlmICh0eXBlb2YgdGhpcy5fcHJveHkgPT09ICdzdHJpbmcnKSB0aGlzLl9wcm94eSA9IHtvcmlnaW46IHRoaXMuX3Byb3h5fTtcblxuICAgIHZhciBleHRzID0gb3B0aW9ucy53ZWJzb2NrZXRFeHRlbnNpb25zO1xuICAgIGlmIChleHRzKSB7XG4gICAgICBleHRzID0gW10uY29uY2F0KGV4dHMpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBleHRzLmxlbmd0aDsgaSA8IG47IGkrKylcbiAgICAgICAgdGhpcy5hZGRXZWJzb2NrZXRFeHRlbnNpb24oZXh0c1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy50bHMgPSBvcHRpb25zLnRscyB8fCB7fTtcbiAgICB0aGlzLnRscy5jYSA9IHRoaXMudGxzLmNhIHx8IG9wdGlvbnMuY2E7XG5cbiAgICBmb3IgKHZhciB0eXBlIGluIHRoaXMuX2FsdGVybmF0ZXMpXG4gICAgICB0aGlzLl9hbHRlcm5hdGVzW3R5cGVdID0gVVJJLnBhcnNlKHRoaXMuX2FsdGVybmF0ZXNbdHlwZV0pO1xuXG4gICAgdGhpcy5tYXhSZXF1ZXN0U2l6ZSA9IHRoaXMuTUFYX1JFUVVFU1RfU0laRTtcbiAgfSxcblxuICBlbmRwb2ludEZvcjogZnVuY3Rpb24oY29ubmVjdGlvblR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5fYWx0ZXJuYXRlc1tjb25uZWN0aW9uVHlwZV0gfHwgdGhpcy5lbmRwb2ludDtcbiAgfSxcblxuICBhZGRXZWJzb2NrZXRFeHRlbnNpb246IGZ1bmN0aW9uKGV4dGVuc2lvbikge1xuICAgIHRoaXMud3NFeHRlbnNpb25zLnB1c2goZXh0ZW5zaW9uKTtcbiAgfSxcblxuICBkaXNhYmxlOiBmdW5jdGlvbihmZWF0dXJlKSB7XG4gICAgdGhpcy5fZGlzYWJsZWQucHVzaChmZWF0dXJlKTtcbiAgfSxcblxuICBzZXRIZWFkZXI6IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgdGhpcy5oZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gIH0sXG5cbiAgY2xvc2U6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLl90cmFuc3BvcnQ7XG4gICAgZGVsZXRlIHRoaXMuX3RyYW5zcG9ydDtcbiAgICBpZiAodHJhbnNwb3J0KSB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgfSxcblxuICBnZXRDb25uZWN0aW9uVHlwZXM6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBUcmFuc3BvcnQuZ2V0Q29ubmVjdGlvblR5cGVzKCk7XG4gIH0sXG5cbiAgc2VsZWN0VHJhbnNwb3J0OiBmdW5jdGlvbih0cmFuc3BvcnRUeXBlcykge1xuICAgIFRyYW5zcG9ydC5nZXQodGhpcywgdHJhbnNwb3J0VHlwZXMsIHRoaXMuX2Rpc2FibGVkLCBmdW5jdGlvbih0cmFuc3BvcnQpIHtcbiAgICAgIHRoaXMuZGVidWcoJ1NlbGVjdGVkID8gdHJhbnNwb3J0IGZvciA/JywgdHJhbnNwb3J0LmNvbm5lY3Rpb25UeXBlLCBVUkkuc3RyaW5naWZ5KHRyYW5zcG9ydC5lbmRwb2ludCkpO1xuXG4gICAgICBpZiAodHJhbnNwb3J0ID09PSB0aGlzLl90cmFuc3BvcnQpIHJldHVybjtcbiAgICAgIGlmICh0aGlzLl90cmFuc3BvcnQpIHRoaXMuX3RyYW5zcG9ydC5jbG9zZSgpO1xuXG4gICAgICB0aGlzLl90cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25UeXBlID0gdHJhbnNwb3J0LmNvbm5lY3Rpb25UeXBlO1xuICAgIH0sIHRoaXMpO1xuICB9LFxuXG4gIHNlbmRNZXNzYWdlOiBmdW5jdGlvbihtZXNzYWdlLCB0aW1lb3V0LCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICB2YXIgaWQgICAgICAgPSBtZXNzYWdlLmlkLFxuICAgICAgICBhdHRlbXB0cyA9IG9wdGlvbnMuYXR0ZW1wdHMsXG4gICAgICAgIGRlYWRsaW5lID0gb3B0aW9ucy5kZWFkbGluZSAmJiBuZXcgRGF0ZSgpLmdldFRpbWUoKSArIChvcHRpb25zLmRlYWRsaW5lICogMTAwMCksXG4gICAgICAgIGVudmVsb3BlID0gdGhpcy5fZW52ZWxvcGVzW2lkXSxcbiAgICAgICAgc2NoZWR1bGVyO1xuXG4gICAgaWYgKCFlbnZlbG9wZSkge1xuICAgICAgc2NoZWR1bGVyID0gbmV3IHRoaXMuX3NjaGVkdWxlcihtZXNzYWdlLCB7dGltZW91dDogdGltZW91dCwgaW50ZXJ2YWw6IHRoaXMucmV0cnksIGF0dGVtcHRzOiBhdHRlbXB0cywgZGVhZGxpbmU6IGRlYWRsaW5lfSk7XG4gICAgICBlbnZlbG9wZSAgPSB0aGlzLl9lbnZlbG9wZXNbaWRdID0ge21lc3NhZ2U6IG1lc3NhZ2UsIHNjaGVkdWxlcjogc2NoZWR1bGVyfTtcbiAgICB9XG5cbiAgICB0aGlzLl9zZW5kRW52ZWxvcGUoZW52ZWxvcGUpO1xuICB9LFxuXG4gIF9zZW5kRW52ZWxvcGU6IGZ1bmN0aW9uKGVudmVsb3BlKSB7XG4gICAgaWYgKCF0aGlzLl90cmFuc3BvcnQpIHJldHVybjtcbiAgICBpZiAoZW52ZWxvcGUucmVxdWVzdCB8fCBlbnZlbG9wZS50aW1lcikgcmV0dXJuO1xuXG4gICAgdmFyIG1lc3NhZ2UgICA9IGVudmVsb3BlLm1lc3NhZ2UsXG4gICAgICAgIHNjaGVkdWxlciA9IGVudmVsb3BlLnNjaGVkdWxlcixcbiAgICAgICAgc2VsZiAgICAgID0gdGhpcztcblxuICAgIGlmICghc2NoZWR1bGVyLmlzRGVsaXZlcmFibGUoKSkge1xuICAgICAgc2NoZWR1bGVyLmFib3J0KCk7XG4gICAgICBkZWxldGUgdGhpcy5fZW52ZWxvcGVzW21lc3NhZ2UuaWRdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVudmVsb3BlLnRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLmhhbmRsZUVycm9yKG1lc3NhZ2UpO1xuICAgIH0sIHNjaGVkdWxlci5nZXRUaW1lb3V0KCkgKiAxMDAwKTtcblxuICAgIHNjaGVkdWxlci5zZW5kKCk7XG4gICAgZW52ZWxvcGUucmVxdWVzdCA9IHRoaXMuX3RyYW5zcG9ydC5zZW5kTWVzc2FnZShtZXNzYWdlKTtcbiAgfSxcblxuICBoYW5kbGVSZXNwb25zZTogZnVuY3Rpb24ocmVwbHkpIHtcbiAgICB2YXIgZW52ZWxvcGUgPSB0aGlzLl9lbnZlbG9wZXNbcmVwbHkuaWRdO1xuXG4gICAgaWYgKHJlcGx5LnN1Y2Nlc3NmdWwgIT09IHVuZGVmaW5lZCAmJiBlbnZlbG9wZSkge1xuICAgICAgZW52ZWxvcGUuc2NoZWR1bGVyLnN1Y2NlZWQoKTtcbiAgICAgIGRlbGV0ZSB0aGlzLl9lbnZlbG9wZXNbcmVwbHkuaWRdO1xuICAgICAgZ2xvYmFsLmNsZWFyVGltZW91dChlbnZlbG9wZS50aW1lcik7XG4gICAgfVxuXG4gICAgdGhpcy50cmlnZ2VyKCdtZXNzYWdlJywgcmVwbHkpO1xuXG4gICAgaWYgKHRoaXMuX3N0YXRlID09PSB0aGlzLlVQKSByZXR1cm47XG4gICAgdGhpcy5fc3RhdGUgPSB0aGlzLlVQO1xuICAgIHRoaXMuX2NsaWVudC50cmlnZ2VyKCd0cmFuc3BvcnQ6dXAnKTtcbiAgfSxcblxuICBoYW5kbGVFcnJvcjogZnVuY3Rpb24obWVzc2FnZSwgaW1tZWRpYXRlKSB7XG4gICAgdmFyIGVudmVsb3BlID0gdGhpcy5fZW52ZWxvcGVzW21lc3NhZ2UuaWRdLFxuICAgICAgICByZXF1ZXN0ICA9IGVudmVsb3BlICYmIGVudmVsb3BlLnJlcXVlc3QsXG4gICAgICAgIHNlbGYgICAgID0gdGhpcztcblxuICAgIGlmICghcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgcmVxdWVzdC50aGVuKGZ1bmN0aW9uKHJlcSkge1xuICAgICAgaWYgKHJlcSAmJiByZXEuYWJvcnQpIHJlcS5hYm9ydCgpO1xuICAgIH0pO1xuXG4gICAgdmFyIHNjaGVkdWxlciA9IGVudmVsb3BlLnNjaGVkdWxlcjtcbiAgICBzY2hlZHVsZXIuZmFpbCgpO1xuXG4gICAgZ2xvYmFsLmNsZWFyVGltZW91dChlbnZlbG9wZS50aW1lcik7XG4gICAgZW52ZWxvcGUucmVxdWVzdCA9IGVudmVsb3BlLnRpbWVyID0gbnVsbDtcblxuICAgIGlmIChpbW1lZGlhdGUpIHtcbiAgICAgIHRoaXMuX3NlbmRFbnZlbG9wZShlbnZlbG9wZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudmVsb3BlLnRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIGVudmVsb3BlLnRpbWVyID0gbnVsbDtcbiAgICAgICAgc2VsZi5fc2VuZEVudmVsb3BlKGVudmVsb3BlKTtcbiAgICAgIH0sIHNjaGVkdWxlci5nZXRJbnRlcnZhbCgpICogMTAwMCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3N0YXRlID09PSB0aGlzLkRPV04pIHJldHVybjtcbiAgICB0aGlzLl9zdGF0ZSA9IHRoaXMuRE9XTjtcbiAgICB0aGlzLl9jbGllbnQudHJpZ2dlcigndHJhbnNwb3J0OmRvd24nKTtcbiAgfVxufSk7XG5cbkRpc3BhdGNoZXIuY3JlYXRlID0gZnVuY3Rpb24oY2xpZW50LCBlbmRwb2ludCwgb3B0aW9ucykge1xuICByZXR1cm4gbmV3IERpc3BhdGNoZXIoY2xpZW50LCBlbmRwb2ludCwgb3B0aW9ucyk7XG59O1xuXG5leHRlbmQoRGlzcGF0Y2hlci5wcm90b3R5cGUsIFB1Ymxpc2hlcik7XG5leHRlbmQoRGlzcGF0Y2hlci5wcm90b3R5cGUsIExvZ2dpbmcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IERpc3BhdGNoZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyAgID0gcmVxdWlyZSgnLi4vdXRpbC9jbGFzcycpLFxuICAgIEdyYW1tYXIgPSByZXF1aXJlKCcuL2dyYW1tYXInKTtcblxudmFyIEVycm9yID0gQ2xhc3Moe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbihjb2RlLCBwYXJhbXMsIG1lc3NhZ2UpIHtcbiAgICB0aGlzLmNvZGUgICAgPSBjb2RlO1xuICAgIHRoaXMucGFyYW1zICA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHBhcmFtcyk7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgfSxcblxuICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuY29kZSArICc6JyArXG4gICAgICAgICAgIHRoaXMucGFyYW1zLmpvaW4oJywnKSArICc6JyArXG4gICAgICAgICAgIHRoaXMubWVzc2FnZTtcbiAgfVxufSk7XG5cbkVycm9yLnBhcnNlID0gZnVuY3Rpb24obWVzc2FnZSkge1xuICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnJztcbiAgaWYgKCFHcmFtbWFyLkVSUk9SLnRlc3QobWVzc2FnZSkpIHJldHVybiBuZXcgRXJyb3IobnVsbCwgW10sIG1lc3NhZ2UpO1xuXG4gIHZhciBwYXJ0cyAgID0gbWVzc2FnZS5zcGxpdCgnOicpLFxuICAgICAgY29kZSAgICA9IHBhcnNlSW50KHBhcnRzWzBdKSxcbiAgICAgIHBhcmFtcyAgPSBwYXJ0c1sxXS5zcGxpdCgnLCcpLFxuICAgICAgbWVzc2FnZSA9IHBhcnRzWzJdO1xuXG4gIHJldHVybiBuZXcgRXJyb3IoY29kZSwgcGFyYW1zLCBtZXNzYWdlKTtcbn07XG5cbi8vIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9jb21ldGQvd2lraS9CYXlldXhDb2Rlc1xudmFyIGVycm9ycyA9IHtcbiAgdmVyc2lvbk1pc21hdGNoOiAgWzMwMCwgJ1ZlcnNpb24gbWlzbWF0Y2gnXSxcbiAgY29ubnR5cGVNaXNtYXRjaDogWzMwMSwgJ0Nvbm5lY3Rpb24gdHlwZXMgbm90IHN1cHBvcnRlZCddLFxuICBleHRNaXNtYXRjaDogICAgICBbMzAyLCAnRXh0ZW5zaW9uIG1pc21hdGNoJ10sXG4gIGJhZFJlcXVlc3Q6ICAgICAgIFs0MDAsICdCYWQgcmVxdWVzdCddLFxuICBjbGllbnRVbmtub3duOiAgICBbNDAxLCAnVW5rbm93biBjbGllbnQnXSxcbiAgcGFyYW1ldGVyTWlzc2luZzogWzQwMiwgJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyJ10sXG4gIGNoYW5uZWxGb3JiaWRkZW46IFs0MDMsICdGb3JiaWRkZW4gY2hhbm5lbCddLFxuICBjaGFubmVsVW5rbm93bjogICBbNDA0LCAnVW5rbm93biBjaGFubmVsJ10sXG4gIGNoYW5uZWxJbnZhbGlkOiAgIFs0MDUsICdJbnZhbGlkIGNoYW5uZWwnXSxcbiAgZXh0VW5rbm93bjogICAgICAgWzQwNiwgJ1Vua25vd24gZXh0ZW5zaW9uJ10sXG4gIHB1Ymxpc2hGYWlsZWQ6ICAgIFs0MDcsICdGYWlsZWQgdG8gcHVibGlzaCddLFxuICBzZXJ2ZXJFcnJvcjogICAgICBbNTAwLCAnSW50ZXJuYWwgc2VydmVyIGVycm9yJ11cbn07XG5cbmZvciAodmFyIG5hbWUgaW4gZXJyb3JzKVxuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIEVycm9yW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEVycm9yKGVycm9yc1tuYW1lXVswXSwgYXJndW1lbnRzLCBlcnJvcnNbbmFtZV1bMV0pLnRvU3RyaW5nKCk7XG4gICAgfTtcbiAgfSkobmFtZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRXJyb3I7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICBMb2dnaW5nID0gcmVxdWlyZSgnLi4vbWl4aW5zL2xvZ2dpbmcnKTtcblxudmFyIEV4dGVuc2libGUgPSB7XG4gIGFkZEV4dGVuc2lvbjogZnVuY3Rpb24oZXh0ZW5zaW9uKSB7XG4gICAgdGhpcy5fZXh0ZW5zaW9ucyA9IHRoaXMuX2V4dGVuc2lvbnMgfHwgW107XG4gICAgdGhpcy5fZXh0ZW5zaW9ucy5wdXNoKGV4dGVuc2lvbik7XG4gICAgaWYgKGV4dGVuc2lvbi5hZGRlZCkgZXh0ZW5zaW9uLmFkZGVkKHRoaXMpO1xuICB9LFxuXG4gIHJlbW92ZUV4dGVuc2lvbjogZnVuY3Rpb24oZXh0ZW5zaW9uKSB7XG4gICAgaWYgKCF0aGlzLl9leHRlbnNpb25zKSByZXR1cm47XG4gICAgdmFyIGkgPSB0aGlzLl9leHRlbnNpb25zLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBpZiAodGhpcy5fZXh0ZW5zaW9uc1tpXSAhPT0gZXh0ZW5zaW9uKSBjb250aW51ZTtcbiAgICAgIHRoaXMuX2V4dGVuc2lvbnMuc3BsaWNlKGksMSk7XG4gICAgICBpZiAoZXh0ZW5zaW9uLnJlbW92ZWQpIGV4dGVuc2lvbi5yZW1vdmVkKHRoaXMpO1xuICAgIH1cbiAgfSxcblxuICBwaXBlVGhyb3VnaEV4dGVuc2lvbnM6IGZ1bmN0aW9uKHN0YWdlLCBtZXNzYWdlLCByZXF1ZXN0LCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHRoaXMuZGVidWcoJ1Bhc3NpbmcgdGhyb3VnaCA/IGV4dGVuc2lvbnM6ID8nLCBzdGFnZSwgbWVzc2FnZSk7XG5cbiAgICBpZiAoIXRoaXMuX2V4dGVuc2lvbnMpIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1lc3NhZ2UpO1xuICAgIHZhciBleHRlbnNpb25zID0gdGhpcy5fZXh0ZW5zaW9ucy5zbGljZSgpO1xuXG4gICAgdmFyIHBpcGUgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICBpZiAoIW1lc3NhZ2UpIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1lc3NhZ2UpO1xuXG4gICAgICB2YXIgZXh0ZW5zaW9uID0gZXh0ZW5zaW9ucy5zaGlmdCgpO1xuICAgICAgaWYgKCFleHRlbnNpb24pIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1lc3NhZ2UpO1xuXG4gICAgICB2YXIgZm4gPSBleHRlbnNpb25bc3RhZ2VdO1xuICAgICAgaWYgKCFmbikgcmV0dXJuIHBpcGUobWVzc2FnZSk7XG5cbiAgICAgIGlmIChmbi5sZW5ndGggPj0gMykgZXh0ZW5zaW9uW3N0YWdlXShtZXNzYWdlLCByZXF1ZXN0LCBwaXBlKTtcbiAgICAgIGVsc2UgICAgICAgICAgICAgICAgZXh0ZW5zaW9uW3N0YWdlXShtZXNzYWdlLCBwaXBlKTtcbiAgICB9O1xuICAgIHBpcGUobWVzc2FnZSk7XG4gIH1cbn07XG5cbmV4dGVuZChFeHRlbnNpYmxlLCBMb2dnaW5nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBFeHRlbnNpYmxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQ0hBTk5FTF9OQU1FOiAgICAgL15cXC8oKCgoW2Etel18W0EtWl0pfFswLTldKXwoXFwtfFxcX3xcXCF8XFx+fFxcKHxcXCl8XFwkfFxcQCkpKSsoXFwvKCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApKSkrKSokLyxcbiAgQ0hBTk5FTF9QQVRURVJOOiAgL14oXFwvKCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApKSkrKSpcXC9cXCp7MSwyfSQvLFxuICBFUlJPUjogICAgICAgICAgICAvXihbMC05XVswLTldWzAtOV06KCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApfCB8XFwvfFxcKnxcXC4pKSooLCgoKChbYS16XXxbQS1aXSl8WzAtOV0pfChcXC18XFxffFxcIXxcXH58XFwofFxcKXxcXCR8XFxAKXwgfFxcL3xcXCp8XFwuKSkqKSo6KCgoKFthLXpdfFtBLVpdKXxbMC05XSl8KFxcLXxcXF98XFwhfFxcfnxcXCh8XFwpfFxcJHxcXEApfCB8XFwvfFxcKnxcXC4pKSp8WzAtOV1bMC05XVswLTldOjooKCgoW2Etel18W0EtWl0pfFswLTldKXwoXFwtfFxcX3xcXCF8XFx+fFxcKHxcXCl8XFwkfFxcQCl8IHxcXC98XFwqfFxcLikpKikkLyxcbiAgVkVSU0lPTjogICAgICAgICAgL14oWzAtOV0pKyhcXC4oKFthLXpdfFtBLVpdKXxbMC05XSkoKCgoW2Etel18W0EtWl0pfFswLTldKXxcXC18XFxfKSkqKSokL1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2NsYXNzJyksXG4gICAgRGVmZXJyYWJsZSA9IHJlcXVpcmUoJy4uL21peGlucy9kZWZlcnJhYmxlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2xhc3MoRGVmZXJyYWJsZSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBleHRlbmQgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpO1xuXG52YXIgU2NoZWR1bGVyID0gZnVuY3Rpb24obWVzc2FnZSwgb3B0aW9ucykge1xuICB0aGlzLm1lc3NhZ2UgID0gbWVzc2FnZTtcbiAgdGhpcy5vcHRpb25zICA9IG9wdGlvbnM7XG4gIHRoaXMuYXR0ZW1wdHMgPSAwO1xufTtcblxuZXh0ZW5kKFNjaGVkdWxlci5wcm90b3R5cGUsIHtcbiAgZ2V0VGltZW91dDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy50aW1lb3V0O1xuICB9LFxuXG4gIGdldEludGVydmFsOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmludGVydmFsO1xuICB9LFxuXG4gIGlzRGVsaXZlcmFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhdHRlbXB0cyA9IHRoaXMub3B0aW9ucy5hdHRlbXB0cyxcbiAgICAgICAgbWFkZSAgICAgPSB0aGlzLmF0dGVtcHRzLFxuICAgICAgICBkZWFkbGluZSA9IHRoaXMub3B0aW9ucy5kZWFkbGluZSxcbiAgICAgICAgbm93ICAgICAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgIGlmIChhdHRlbXB0cyAhPT0gdW5kZWZpbmVkICYmIG1hZGUgPj0gYXR0ZW1wdHMpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAoZGVhZGxpbmUgIT09IHVuZGVmaW5lZCAmJiBub3cgPiBkZWFkbGluZSlcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9LFxuXG4gIHNlbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuYXR0ZW1wdHMgKz0gMTtcbiAgfSxcblxuICBzdWNjZWVkOiBmdW5jdGlvbigpIHt9LFxuXG4gIGZhaWw6IGZ1bmN0aW9uKCkge30sXG5cbiAgYWJvcnQ6IGZ1bmN0aW9uKCkge31cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVkdWxlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICAgPSByZXF1aXJlKCcuLi91dGlsL2NsYXNzJyksXG4gICAgZXh0ZW5kICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgRGVmZXJyYWJsZSA9IHJlcXVpcmUoJy4uL21peGlucy9kZWZlcnJhYmxlJyk7XG5cbnZhciBTdWJzY3JpcHRpb24gPSBDbGFzcyh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNsaWVudCwgY2hhbm5lbHMsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fY2xpZW50ICAgID0gY2xpZW50O1xuICAgIHRoaXMuX2NoYW5uZWxzICA9IGNoYW5uZWxzO1xuICAgIHRoaXMuX2NhbGxiYWNrICA9IGNhbGxiYWNrO1xuICAgIHRoaXMuX2NvbnRleHQgICA9IGNvbnRleHQ7XG4gICAgdGhpcy5fY2FuY2VsbGVkID0gZmFsc2U7XG4gIH0sXG5cbiAgd2l0aENoYW5uZWw6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5fd2l0aENoYW5uZWwgPSBbY2FsbGJhY2ssIGNvbnRleHRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGFwcGx5OiBmdW5jdGlvbihjb250ZXh0LCBhcmdzKSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBhcmdzWzBdO1xuXG4gICAgaWYgKHRoaXMuX2NhbGxiYWNrKVxuICAgICAgdGhpcy5fY2FsbGJhY2suY2FsbCh0aGlzLl9jb250ZXh0LCBtZXNzYWdlLmRhdGEpO1xuXG4gICAgaWYgKHRoaXMuX3dpdGhDaGFubmVsKVxuICAgICAgdGhpcy5fd2l0aENoYW5uZWxbMF0uY2FsbCh0aGlzLl93aXRoQ2hhbm5lbFsxXSwgbWVzc2FnZS5jaGFubmVsLCBtZXNzYWdlLmRhdGEpO1xuICB9LFxuXG4gIGNhbmNlbDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2NhbmNlbGxlZCkgcmV0dXJuO1xuICAgIHRoaXMuX2NsaWVudC51bnN1YnNjcmliZSh0aGlzLl9jaGFubmVscywgdGhpcyk7XG4gICAgdGhpcy5fY2FuY2VsbGVkID0gdHJ1ZTtcbiAgfSxcblxuICB1bnN1YnNjcmliZTogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5jYW5jZWwoKTtcbiAgfVxufSk7XG5cbmV4dGVuZChTdWJzY3JpcHRpb24ucHJvdG90eXBlLCBEZWZlcnJhYmxlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTdWJzY3JpcHRpb247XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuXG5UcmFuc3BvcnQucmVnaXN0ZXIoJ3dlYnNvY2tldCcsIHJlcXVpcmUoJy4vd2ViX3NvY2tldCcpKTtcblRyYW5zcG9ydC5yZWdpc3RlcignZXZlbnRzb3VyY2UnLCByZXF1aXJlKCcuL2V2ZW50X3NvdXJjZScpKTtcblRyYW5zcG9ydC5yZWdpc3RlcignbG9uZy1wb2xsaW5nJywgcmVxdWlyZSgnLi94aHInKSk7XG5UcmFuc3BvcnQucmVnaXN0ZXIoJ2Nyb3NzLW9yaWdpbi1sb25nLXBvbGxpbmcnLCByZXF1aXJlKCcuL2NvcnMnKSk7XG5UcmFuc3BvcnQucmVnaXN0ZXIoJ2NhbGxiYWNrLXBvbGxpbmcnLCByZXF1aXJlKCcuL2pzb25wJykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zcG9ydDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBTZXQgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3NldCcpLFxuICAgIFVSSSAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvdXJpJyksXG4gICAgZXh0ZW5kICAgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICB0b0pTT04gICAgPSByZXF1aXJlKCcuLi91dGlsL3RvX2pzb24nKSxcbiAgICBUcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuXG52YXIgQ09SUyA9IGV4dGVuZChDbGFzcyhUcmFuc3BvcnQsIHtcbiAgZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlcykge1xuICAgIHJldHVybiAnbWVzc2FnZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHRvSlNPTihtZXNzYWdlcykpO1xuICB9LFxuXG4gIHJlcXVlc3Q6IGZ1bmN0aW9uKG1lc3NhZ2VzKSB7XG4gICAgdmFyIHhockNsYXNzID0gZ2xvYmFsLlhEb21haW5SZXF1ZXN0ID8gWERvbWFpblJlcXVlc3QgOiBYTUxIdHRwUmVxdWVzdCxcbiAgICAgICAgeGhyICAgICAgPSBuZXcgeGhyQ2xhc3MoKSxcbiAgICAgICAgaWQgICAgICAgPSArK0NPUlMuX2lkLFxuICAgICAgICBoZWFkZXJzICA9IHRoaXMuX2Rpc3BhdGNoZXIuaGVhZGVycyxcbiAgICAgICAgc2VsZiAgICAgPSB0aGlzLFxuICAgICAgICBrZXk7XG5cbiAgICB4aHIub3BlbignUE9TVCcsIFVSSS5zdHJpbmdpZnkodGhpcy5lbmRwb2ludCksIHRydWUpO1xuXG4gICAgaWYgKHhoci5zZXRSZXF1ZXN0SGVhZGVyKSB7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignUHJhZ21hJywgJ25vLWNhY2hlJyk7XG4gICAgICBmb3IgKGtleSBpbiBoZWFkZXJzKSB7XG4gICAgICAgIGlmICghaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCBoZWFkZXJzW2tleV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjbGVhblVwID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXhocikgcmV0dXJuIGZhbHNlO1xuICAgICAgQ09SUy5fcGVuZGluZy5yZW1vdmUoaWQpO1xuICAgICAgeGhyLm9ubG9hZCA9IHhoci5vbmVycm9yID0geGhyLm9udGltZW91dCA9IHhoci5vbnByb2dyZXNzID0gbnVsbDtcbiAgICAgIHhociA9IG51bGw7XG4gICAgfTtcblxuICAgIHhoci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXBsaWVzO1xuICAgICAgdHJ5IHsgcmVwbGllcyA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCkgfSBjYXRjaCAoZXJyb3IpIHt9XG5cbiAgICAgIGNsZWFuVXAoKTtcblxuICAgICAgaWYgKHJlcGxpZXMpXG4gICAgICAgIHNlbGYuX3JlY2VpdmUocmVwbGllcyk7XG4gICAgICBlbHNlXG4gICAgICAgIHNlbGYuX2hhbmRsZUVycm9yKG1lc3NhZ2VzKTtcbiAgICB9O1xuXG4gICAgeGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICBjbGVhblVwKCk7XG4gICAgICBzZWxmLl9oYW5kbGVFcnJvcihtZXNzYWdlcyk7XG4gICAgfTtcblxuICAgIHhoci5vbnByb2dyZXNzID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIGlmICh4aHJDbGFzcyA9PT0gZ2xvYmFsLlhEb21haW5SZXF1ZXN0KVxuICAgICAgQ09SUy5fcGVuZGluZy5hZGQoe2lkOiBpZCwgeGhyOiB4aHJ9KTtcblxuICAgIHhoci5zZW5kKHRoaXMuZW5jb2RlKG1lc3NhZ2VzKSk7XG4gICAgcmV0dXJuIHhocjtcbiAgfVxufSksIHtcbiAgX2lkOiAgICAgIDAsXG4gIF9wZW5kaW5nOiBuZXcgU2V0KCksXG5cbiAgaXNVc2FibGU6IGZ1bmN0aW9uKGRpc3BhdGNoZXIsIGVuZHBvaW50LCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmIChVUkkuaXNTYW1lT3JpZ2luKGVuZHBvaW50KSlcbiAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIGZhbHNlKTtcblxuICAgIGlmIChnbG9iYWwuWERvbWFpblJlcXVlc3QpXG4gICAgICByZXR1cm4gY2FsbGJhY2suY2FsbChjb250ZXh0LCBlbmRwb2ludC5wcm90b2NvbCA9PT0gbG9jYXRpb24ucHJvdG9jb2wpO1xuXG4gICAgaWYgKGdsb2JhbC5YTUxIdHRwUmVxdWVzdCkge1xuICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgeGhyLndpdGhDcmVkZW50aWFscyAhPT0gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZmFsc2UpO1xuICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBDT1JTO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3MgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBVUkkgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBjb3B5T2JqZWN0ID0gcmVxdWlyZSgnLi4vdXRpbC9jb3B5X29iamVjdCcpLFxuICAgIGV4dGVuZCAgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIERlZmVycmFibGUgPSByZXF1aXJlKCcuLi9taXhpbnMvZGVmZXJyYWJsZScpLFxuICAgIFRyYW5zcG9ydCAgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpLFxuICAgIFhIUiAgICAgICAgPSByZXF1aXJlKCcuL3hocicpO1xuXG52YXIgRXZlbnRTb3VyY2UgPSBleHRlbmQoQ2xhc3MoVHJhbnNwb3J0LCB7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKGRpc3BhdGNoZXIsIGVuZHBvaW50KSB7XG4gICAgVHJhbnNwb3J0LnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcywgZGlzcGF0Y2hlciwgZW5kcG9pbnQpO1xuICAgIGlmICghZ2xvYmFsLkV2ZW50U291cmNlKSByZXR1cm4gdGhpcy5zZXREZWZlcnJlZFN0YXR1cygnZmFpbGVkJyk7XG5cbiAgICB0aGlzLl94aHIgPSBuZXcgWEhSKGRpc3BhdGNoZXIsIGVuZHBvaW50KTtcblxuICAgIGVuZHBvaW50ID0gY29weU9iamVjdChlbmRwb2ludCk7XG4gICAgZW5kcG9pbnQucGF0aG5hbWUgKz0gJy8nICsgZGlzcGF0Y2hlci5jbGllbnRJZDtcblxuICAgIHZhciBzb2NrZXQgPSBuZXcgZ2xvYmFsLkV2ZW50U291cmNlKFVSSS5zdHJpbmdpZnkoZW5kcG9pbnQpKSxcbiAgICAgICAgc2VsZiAgID0gdGhpcztcblxuICAgIHNvY2tldC5vbm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuX2V2ZXJDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgc2VsZi5zZXREZWZlcnJlZFN0YXR1cygnc3VjY2VlZGVkJyk7XG4gICAgfTtcblxuICAgIHNvY2tldC5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoc2VsZi5fZXZlckNvbm5lY3RlZCkge1xuICAgICAgICBzZWxmLl9oYW5kbGVFcnJvcihbXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCdmYWlsZWQnKTtcbiAgICAgICAgc29ja2V0LmNsb3NlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNvY2tldC5vbm1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIHJlcGxpZXM7XG4gICAgICB0cnkgeyByZXBsaWVzID0gSlNPTi5wYXJzZShldmVudC5kYXRhKSB9IGNhdGNoIChlcnJvcikge31cblxuICAgICAgaWYgKHJlcGxpZXMpXG4gICAgICAgIHNlbGYuX3JlY2VpdmUocmVwbGllcyk7XG4gICAgICBlbHNlXG4gICAgICAgIHNlbGYuX2hhbmRsZUVycm9yKFtdKTtcbiAgICB9O1xuXG4gICAgdGhpcy5fc29ja2V0ID0gc29ja2V0O1xuICB9LFxuXG4gIGNsb3NlOiBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX3NvY2tldCkgcmV0dXJuO1xuICAgIHRoaXMuX3NvY2tldC5vbm9wZW4gPSB0aGlzLl9zb2NrZXQub25lcnJvciA9IHRoaXMuX3NvY2tldC5vbm1lc3NhZ2UgPSBudWxsO1xuICAgIHRoaXMuX3NvY2tldC5jbG9zZSgpO1xuICAgIGRlbGV0ZSB0aGlzLl9zb2NrZXQ7XG4gIH0sXG5cbiAgaXNVc2FibGU6IGZ1bmN0aW9uKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5jYWxsYmFjayhmdW5jdGlvbigpIHsgY2FsbGJhY2suY2FsbChjb250ZXh0LCB0cnVlKSB9KTtcbiAgICB0aGlzLmVycmJhY2soZnVuY3Rpb24oKSB7IGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZmFsc2UpIH0pO1xuICB9LFxuXG4gIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICByZXR1cm4gdGhpcy5feGhyLmVuY29kZShtZXNzYWdlcyk7XG4gIH0sXG5cbiAgcmVxdWVzdDogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICByZXR1cm4gdGhpcy5feGhyLnJlcXVlc3QobWVzc2FnZXMpO1xuICB9XG5cbn0pLCB7XG4gIGlzVXNhYmxlOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgaWQgPSBkaXNwYXRjaGVyLmNsaWVudElkO1xuICAgIGlmICghaWQpIHJldHVybiBjYWxsYmFjay5jYWxsKGNvbnRleHQsIGZhbHNlKTtcblxuICAgIFhIUi5pc1VzYWJsZShkaXNwYXRjaGVyLCBlbmRwb2ludCwgZnVuY3Rpb24odXNhYmxlKSB7XG4gICAgICBpZiAoIXVzYWJsZSkgcmV0dXJuIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgZmFsc2UpO1xuICAgICAgdGhpcy5jcmVhdGUoZGlzcGF0Y2hlciwgZW5kcG9pbnQpLmlzVXNhYmxlKGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgICB9LCB0aGlzKTtcbiAgfSxcblxuICBjcmVhdGU6IGZ1bmN0aW9uKGRpc3BhdGNoZXIsIGVuZHBvaW50KSB7XG4gICAgdmFyIHNvY2tldHMgPSBkaXNwYXRjaGVyLnRyYW5zcG9ydHMuZXZlbnRzb3VyY2UgPSBkaXNwYXRjaGVyLnRyYW5zcG9ydHMuZXZlbnRzb3VyY2UgfHwge30sXG4gICAgICAgIGlkICAgICAgPSBkaXNwYXRjaGVyLmNsaWVudElkO1xuXG4gICAgdmFyIHVybCA9IGNvcHlPYmplY3QoZW5kcG9pbnQpO1xuICAgIHVybC5wYXRobmFtZSArPSAnLycgKyAoaWQgfHwgJycpO1xuICAgIHVybCA9IFVSSS5zdHJpbmdpZnkodXJsKTtcblxuICAgIHNvY2tldHNbdXJsXSA9IHNvY2tldHNbdXJsXSB8fCBuZXcgdGhpcyhkaXNwYXRjaGVyLCBlbmRwb2ludCk7XG4gICAgcmV0dXJuIHNvY2tldHNbdXJsXTtcbiAgfVxufSk7XG5cbmV4dGVuZChFdmVudFNvdXJjZS5wcm90b3R5cGUsIERlZmVycmFibGUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50U291cmNlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3MgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBVUkkgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBjb3B5T2JqZWN0ID0gcmVxdWlyZSgnLi4vdXRpbC9jb3B5X29iamVjdCcpLFxuICAgIGV4dGVuZCAgICAgPSByZXF1aXJlKCcuLi91dGlsL2V4dGVuZCcpLFxuICAgIHRvSlNPTiAgICAgPSByZXF1aXJlKCcuLi91dGlsL3RvX2pzb24nKSxcbiAgICBUcmFuc3BvcnQgID0gcmVxdWlyZSgnLi90cmFuc3BvcnQnKTtcblxudmFyIEpTT05QID0gZXh0ZW5kKENsYXNzKFRyYW5zcG9ydCwge1xuIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICB2YXIgdXJsID0gY29weU9iamVjdCh0aGlzLmVuZHBvaW50KTtcbiAgICB1cmwucXVlcnkubWVzc2FnZSA9IHRvSlNPTihtZXNzYWdlcyk7XG4gICAgdXJsLnF1ZXJ5Lmpzb25wICAgPSAnX19qc29ucCcgKyBKU09OUC5fY2JDb3VudCArICdfXyc7XG4gICAgcmV0dXJuIFVSSS5zdHJpbmdpZnkodXJsKTtcbiAgfSxcblxuICByZXF1ZXN0OiBmdW5jdGlvbihtZXNzYWdlcykge1xuICAgIHZhciBoZWFkICAgICAgICAgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLFxuICAgICAgICBzY3JpcHQgICAgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSxcbiAgICAgICAgY2FsbGJhY2tOYW1lID0gSlNPTlAuZ2V0Q2FsbGJhY2tOYW1lKCksXG4gICAgICAgIGVuZHBvaW50ICAgICA9IGNvcHlPYmplY3QodGhpcy5lbmRwb2ludCksXG4gICAgICAgIHNlbGYgICAgICAgICA9IHRoaXM7XG5cbiAgICBlbmRwb2ludC5xdWVyeS5tZXNzYWdlID0gdG9KU09OKG1lc3NhZ2VzKTtcbiAgICBlbmRwb2ludC5xdWVyeS5qc29ucCAgID0gY2FsbGJhY2tOYW1lO1xuXG4gICAgdmFyIGNsZWFudXAgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghZ2xvYmFsW2NhbGxiYWNrTmFtZV0pIHJldHVybiBmYWxzZTtcbiAgICAgIGdsb2JhbFtjYWxsYmFja05hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgdHJ5IHsgZGVsZXRlIGdsb2JhbFtjYWxsYmFja05hbWVdIH0gY2F0Y2ggKGVycm9yKSB7fVxuICAgICAgc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICB9O1xuXG4gICAgZ2xvYmFsW2NhbGxiYWNrTmFtZV0gPSBmdW5jdGlvbihyZXBsaWVzKSB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICBzZWxmLl9yZWNlaXZlKHJlcGxpZXMpO1xuICAgIH07XG5cbiAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnO1xuICAgIHNjcmlwdC5zcmMgID0gVVJJLnN0cmluZ2lmeShlbmRwb2ludCk7XG4gICAgaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXG4gICAgc2NyaXB0Lm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICAgIHNlbGYuX2hhbmRsZUVycm9yKG1lc3NhZ2VzKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHthYm9ydDogY2xlYW51cH07XG4gIH1cbn0pLCB7XG4gIF9jYkNvdW50OiAwLFxuXG4gIGdldENhbGxiYWNrTmFtZTogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY2JDb3VudCArPSAxO1xuICAgIHJldHVybiAnX19qc29ucCcgKyB0aGlzLl9jYkNvdW50ICsgJ19fJztcbiAgfSxcblxuICBpc1VzYWJsZTogZnVuY3Rpb24oZGlzcGF0Y2hlciwgZW5kcG9pbnQsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgY2FsbGJhY2suY2FsbChjb250ZXh0LCB0cnVlKTtcbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gSlNPTlA7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBDb29raWUgICA9IHJlcXVpcmUoJy4uL3V0aWwvY29va2llcycpLkNvb2tpZSxcbiAgICBQcm9taXNlICA9IHJlcXVpcmUoJy4uL3V0aWwvcHJvbWlzZScpLFxuICAgIFVSSSAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBhcnJheSAgICA9IHJlcXVpcmUoJy4uL3V0aWwvYXJyYXknKSxcbiAgICBleHRlbmQgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgTG9nZ2luZyAgPSByZXF1aXJlKCcuLi9taXhpbnMvbG9nZ2luZycpLFxuICAgIFRpbWVvdXRzID0gcmVxdWlyZSgnLi4vbWl4aW5zL3RpbWVvdXRzJyksXG4gICAgQ2hhbm5lbCAgPSByZXF1aXJlKCcuLi9wcm90b2NvbC9jaGFubmVsJyk7XG5cbnZhciBUcmFuc3BvcnQgPSBleHRlbmQoQ2xhc3MoeyBjbGFzc05hbWU6ICdUcmFuc3BvcnQnLFxuICBERUZBVUxUX1BPUlRTOiB7J2h0dHA6JzogODAsICdodHRwczonOiA0NDMsICd3czonOiA4MCwgJ3dzczonOiA0NDN9LFxuICBNQVhfREVMQVk6ICAgICAwLFxuXG4gIGJhdGNoaW5nOiAgdHJ1ZSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCkge1xuICAgIHRoaXMuX2Rpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xuICAgIHRoaXMuZW5kcG9pbnQgICAgPSBlbmRwb2ludDtcbiAgICB0aGlzLl9vdXRib3ggICAgID0gW107XG4gICAgdGhpcy5fcHJveHkgICAgICA9IGV4dGVuZCh7fSwgdGhpcy5fZGlzcGF0Y2hlci5wcm94eSk7XG5cbiAgICBpZiAoIXRoaXMuX3Byb3h5Lm9yaWdpbilcbiAgICAgIHRoaXMuX3Byb3h5Lm9yaWdpbiA9IHRoaXMuX2ZpbmRQcm94eSgpO1xuICB9LFxuXG4gIGNsb3NlOiBmdW5jdGlvbigpIHt9LFxuXG4gIGVuY29kZTogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICByZXR1cm4gJyc7XG4gIH0sXG5cbiAgc2VuZE1lc3NhZ2U6IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICB0aGlzLmRlYnVnKCdDbGllbnQgPyBzZW5kaW5nIG1lc3NhZ2UgdG8gPzogPycsXG4gICAgICAgICAgICAgICB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkLCBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpLCBtZXNzYWdlKTtcblxuICAgIGlmICghdGhpcy5iYXRjaGluZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLnJlcXVlc3QoW21lc3NhZ2VdKSk7XG5cbiAgICB0aGlzLl9vdXRib3gucHVzaChtZXNzYWdlKTtcbiAgICB0aGlzLl9mbHVzaExhcmdlQmF0Y2goKTtcblxuICAgIGlmIChtZXNzYWdlLmNoYW5uZWwgPT09IENoYW5uZWwuSEFORFNIQUtFKVxuICAgICAgcmV0dXJuIHRoaXMuX3B1Ymxpc2goMC4wMSk7XG5cbiAgICBpZiAobWVzc2FnZS5jaGFubmVsID09PSBDaGFubmVsLkNPTk5FQ1QpXG4gICAgICB0aGlzLl9jb25uZWN0TWVzc2FnZSA9IG1lc3NhZ2U7XG5cbiAgICByZXR1cm4gdGhpcy5fcHVibGlzaCh0aGlzLk1BWF9ERUxBWSk7XG4gIH0sXG5cbiAgX21ha2VQcm9taXNlOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB0aGlzLl9yZXF1ZXN0UHJvbWlzZSA9IHRoaXMuX3JlcXVlc3RQcm9taXNlIHx8IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgIHNlbGYuX3Jlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICB9KTtcbiAgfSxcblxuICBfcHVibGlzaDogZnVuY3Rpb24oZGVsYXkpIHtcbiAgICB0aGlzLl9tYWtlUHJvbWlzZSgpO1xuXG4gICAgdGhpcy5hZGRUaW1lb3V0KCdwdWJsaXNoJywgZGVsYXksIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5fZmx1c2goKTtcbiAgICAgIGRlbGV0ZSB0aGlzLl9yZXF1ZXN0UHJvbWlzZTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiB0aGlzLl9yZXF1ZXN0UHJvbWlzZTtcbiAgfSxcblxuICBfZmx1c2g6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucmVtb3ZlVGltZW91dCgncHVibGlzaCcpO1xuXG4gICAgaWYgKHRoaXMuX291dGJveC5sZW5ndGggPiAxICYmIHRoaXMuX2Nvbm5lY3RNZXNzYWdlKVxuICAgICAgdGhpcy5fY29ubmVjdE1lc3NhZ2UuYWR2aWNlID0ge3RpbWVvdXQ6IDB9O1xuXG4gICAgdGhpcy5fcmVzb2x2ZVByb21pc2UodGhpcy5yZXF1ZXN0KHRoaXMuX291dGJveCkpO1xuXG4gICAgdGhpcy5fY29ubmVjdE1lc3NhZ2UgPSBudWxsO1xuICAgIHRoaXMuX291dGJveCA9IFtdO1xuICB9LFxuXG4gIF9mbHVzaExhcmdlQmF0Y2g6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdHJpbmcgPSB0aGlzLmVuY29kZSh0aGlzLl9vdXRib3gpO1xuICAgIGlmIChzdHJpbmcubGVuZ3RoIDwgdGhpcy5fZGlzcGF0Y2hlci5tYXhSZXF1ZXN0U2l6ZSkgcmV0dXJuO1xuICAgIHZhciBsYXN0ID0gdGhpcy5fb3V0Ym94LnBvcCgpO1xuXG4gICAgdGhpcy5fbWFrZVByb21pc2UoKTtcbiAgICB0aGlzLl9mbHVzaCgpO1xuXG4gICAgaWYgKGxhc3QpIHRoaXMuX291dGJveC5wdXNoKGxhc3QpO1xuICB9LFxuXG4gIF9yZWNlaXZlOiBmdW5jdGlvbihyZXBsaWVzKSB7XG4gICAgaWYgKCFyZXBsaWVzKSByZXR1cm47XG4gICAgcmVwbGllcyA9IFtdLmNvbmNhdChyZXBsaWVzKTtcblxuICAgIHRoaXMuZGVidWcoJ0NsaWVudCA/IHJlY2VpdmVkIGZyb20gPyB2aWEgPzogPycsXG4gICAgICAgICAgICAgICB0aGlzLl9kaXNwYXRjaGVyLmNsaWVudElkLCBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpLCB0aGlzLmNvbm5lY3Rpb25UeXBlLCByZXBsaWVzKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBuID0gcmVwbGllcy5sZW5ndGg7IGkgPCBuOyBpKyspXG4gICAgICB0aGlzLl9kaXNwYXRjaGVyLmhhbmRsZVJlc3BvbnNlKHJlcGxpZXNbaV0pO1xuICB9LFxuXG4gIF9oYW5kbGVFcnJvcjogZnVuY3Rpb24obWVzc2FnZXMsIGltbWVkaWF0ZSkge1xuICAgIG1lc3NhZ2VzID0gW10uY29uY2F0KG1lc3NhZ2VzKTtcblxuICAgIHRoaXMuZGVidWcoJ0NsaWVudCA/IGZhaWxlZCB0byBzZW5kIHRvID8gdmlhID86ID8nLFxuICAgICAgICAgICAgICAgdGhpcy5fZGlzcGF0Y2hlci5jbGllbnRJZCwgVVJJLnN0cmluZ2lmeSh0aGlzLmVuZHBvaW50KSwgdGhpcy5jb25uZWN0aW9uVHlwZSwgbWVzc2FnZXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBtZXNzYWdlcy5sZW5ndGg7IGkgPCBuOyBpKyspXG4gICAgICB0aGlzLl9kaXNwYXRjaGVyLmhhbmRsZUVycm9yKG1lc3NhZ2VzW2ldKTtcbiAgfSxcblxuICBfZ2V0Q29va2llczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvb2tpZXMgPSB0aGlzLl9kaXNwYXRjaGVyLmNvb2tpZXMsXG4gICAgICAgIHVybCAgICAgPSBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpO1xuXG4gICAgaWYgKCFjb29raWVzKSByZXR1cm4gJyc7XG5cbiAgICByZXR1cm4gYXJyYXkubWFwKGNvb2tpZXMuZ2V0Q29va2llc1N5bmModXJsKSwgZnVuY3Rpb24oY29va2llKSB7XG4gICAgICByZXR1cm4gY29va2llLmNvb2tpZVN0cmluZygpO1xuICAgIH0pLmpvaW4oJzsgJyk7XG4gIH0sXG5cbiAgX3N0b3JlQ29va2llczogZnVuY3Rpb24oc2V0Q29va2llKSB7XG4gICAgdmFyIGNvb2tpZXMgPSB0aGlzLl9kaXNwYXRjaGVyLmNvb2tpZXMsXG4gICAgICAgIHVybCAgICAgPSBVUkkuc3RyaW5naWZ5KHRoaXMuZW5kcG9pbnQpLFxuICAgICAgICBjb29raWU7XG5cbiAgICBpZiAoIXNldENvb2tpZSB8fCAhY29va2llcykgcmV0dXJuO1xuICAgIHNldENvb2tpZSA9IFtdLmNvbmNhdChzZXRDb29raWUpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBzZXRDb29raWUubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICBjb29raWUgPSBDb29raWUucGFyc2Uoc2V0Q29va2llW2ldKTtcbiAgICAgIGNvb2tpZXMuc2V0Q29va2llU3luYyhjb29raWUsIHVybCk7XG4gICAgfVxuICB9LFxuXG4gIF9maW5kUHJveHk6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgcHJvdG9jb2wgPSB0aGlzLmVuZHBvaW50LnByb3RvY29sO1xuICAgIGlmICghcHJvdG9jb2wpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgbmFtZSAgID0gcHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJykudG9Mb3dlckNhc2UoKSArICdfcHJveHknLFxuICAgICAgICB1cGNhc2UgPSBuYW1lLnRvVXBwZXJDYXNlKCksXG4gICAgICAgIGVudiAgICA9IHByb2Nlc3MuZW52LFxuICAgICAgICBrZXlzLCBwcm94eTtcblxuICAgIGlmIChuYW1lID09PSAnaHR0cF9wcm94eScgJiYgZW52LlJFUVVFU1RfTUVUSE9EKSB7XG4gICAgICBrZXlzID0gT2JqZWN0LmtleXMoZW52KS5maWx0ZXIoZnVuY3Rpb24oaykgeyByZXR1cm4gL15odHRwX3Byb3h5JC9pLnRlc3QoaykgfSk7XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgaWYgKGtleXNbMF0gPT09IG5hbWUgJiYgZW52W3VwY2FzZV0gPT09IHVuZGVmaW5lZClcbiAgICAgICAgICBwcm94eSA9IGVudltuYW1lXTtcbiAgICAgIH0gZWxzZSBpZiAoa2V5cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHByb3h5ID0gZW52W25hbWVdO1xuICAgICAgfVxuICAgICAgcHJveHkgPSBwcm94eSB8fCBlbnZbJ0NHSV8nICsgdXBjYXNlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJveHkgPSBlbnZbbmFtZV0gfHwgZW52W3VwY2FzZV07XG4gICAgICBpZiAocHJveHkgJiYgIWVudltuYW1lXSlcbiAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZW52aXJvbm1lbnQgdmFyaWFibGUgJyArIHVwY2FzZSArXG4gICAgICAgICAgICAgICAgICAgICAnIGlzIGRpc2NvdXJhZ2VkLiBVc2UgJyArIG5hbWUgKyAnLicpO1xuICAgIH1cbiAgICByZXR1cm4gcHJveHk7XG4gIH1cblxufSksIHtcbiAgZ2V0OiBmdW5jdGlvbihkaXNwYXRjaGVyLCBhbGxvd2VkLCBkaXNhYmxlZCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgZW5kcG9pbnQgPSBkaXNwYXRjaGVyLmVuZHBvaW50O1xuXG4gICAgYXJyYXkuYXN5bmNFYWNoKHRoaXMuX3RyYW5zcG9ydHMsIGZ1bmN0aW9uKHBhaXIsIHJlc3VtZSkge1xuICAgICAgdmFyIGNvbm5UeXBlICAgICA9IHBhaXJbMF0sIGtsYXNzID0gcGFpclsxXSxcbiAgICAgICAgICBjb25uRW5kcG9pbnQgPSBkaXNwYXRjaGVyLmVuZHBvaW50Rm9yKGNvbm5UeXBlKTtcblxuICAgICAgaWYgKGFycmF5LmluZGV4T2YoZGlzYWJsZWQsIGNvbm5UeXBlKSA+PSAwKVxuICAgICAgICByZXR1cm4gcmVzdW1lKCk7XG5cbiAgICAgIGlmIChhcnJheS5pbmRleE9mKGFsbG93ZWQsIGNvbm5UeXBlKSA8IDApIHtcbiAgICAgICAga2xhc3MuaXNVc2FibGUoZGlzcGF0Y2hlciwgY29ubkVuZHBvaW50LCBmdW5jdGlvbigpIHt9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VtZSgpO1xuICAgICAgfVxuXG4gICAgICBrbGFzcy5pc1VzYWJsZShkaXNwYXRjaGVyLCBjb25uRW5kcG9pbnQsIGZ1bmN0aW9uKGlzVXNhYmxlKSB7XG4gICAgICAgIGlmICghaXNVc2FibGUpIHJldHVybiByZXN1bWUoKTtcbiAgICAgICAgdmFyIHRyYW5zcG9ydCA9IGtsYXNzLmhhc093blByb3BlcnR5KCdjcmVhdGUnKSA/IGtsYXNzLmNyZWF0ZShkaXNwYXRjaGVyLCBjb25uRW5kcG9pbnQpIDogbmV3IGtsYXNzKGRpc3BhdGNoZXIsIGNvbm5FbmRwb2ludCk7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgdHJhbnNwb3J0KTtcbiAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBhIHVzYWJsZSBjb25uZWN0aW9uIHR5cGUgZm9yICcgKyBVUkkuc3RyaW5naWZ5KGVuZHBvaW50KSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgcmVnaXN0ZXI6IGZ1bmN0aW9uKHR5cGUsIGtsYXNzKSB7XG4gICAgdGhpcy5fdHJhbnNwb3J0cy5wdXNoKFt0eXBlLCBrbGFzc10pO1xuICAgIGtsYXNzLnByb3RvdHlwZS5jb25uZWN0aW9uVHlwZSA9IHR5cGU7XG4gIH0sXG5cbiAgZ2V0Q29ubmVjdGlvblR5cGVzOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXJyYXkubWFwKHRoaXMuX3RyYW5zcG9ydHMsIGZ1bmN0aW9uKHQpIHsgcmV0dXJuIHRbMF0gfSk7XG4gIH0sXG5cbiAgX3RyYW5zcG9ydHM6IFtdXG59KTtcblxuZXh0ZW5kKFRyYW5zcG9ydC5wcm90b3R5cGUsIExvZ2dpbmcpO1xuZXh0ZW5kKFRyYW5zcG9ydC5wcm90b3R5cGUsIFRpbWVvdXRzKTtcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9jbGFzcycpLFxuICAgIFByb21pc2UgICAgPSByZXF1aXJlKCcuLi91dGlsL3Byb21pc2UnKSxcbiAgICBTZXQgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9zZXQnKSxcbiAgICBVUkkgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbC91cmknKSxcbiAgICBicm93c2VyICAgID0gcmVxdWlyZSgnLi4vdXRpbC9icm93c2VyJyksXG4gICAgY29weU9iamVjdCA9IHJlcXVpcmUoJy4uL3V0aWwvY29weV9vYmplY3QnKSxcbiAgICBleHRlbmQgICAgID0gcmVxdWlyZSgnLi4vdXRpbC9leHRlbmQnKSxcbiAgICB0b0pTT04gICAgID0gcmVxdWlyZSgnLi4vdXRpbC90b19qc29uJyksXG4gICAgd3MgICAgICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvd2Vic29ja2V0JyksXG4gICAgRGVmZXJyYWJsZSA9IHJlcXVpcmUoJy4uL21peGlucy9kZWZlcnJhYmxlJyksXG4gICAgVHJhbnNwb3J0ICA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0Jyk7XG5cbnZhciBXZWJTb2NrZXQgPSBleHRlbmQoQ2xhc3MoVHJhbnNwb3J0LCB7XG4gIFVOQ09OTkVDVEVEOiAgMSxcbiAgQ09OTkVDVElORzogICAyLFxuICBDT05ORUNURUQ6ICAgIDMsXG5cbiAgYmF0Y2hpbmc6ICAgICBmYWxzZSxcblxuICBpc1VzYWJsZTogZnVuY3Rpb24oY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB0aGlzLmNhbGxiYWNrKGZ1bmN0aW9uKCkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQsIHRydWUpIH0pO1xuICAgIHRoaXMuZXJyYmFjayhmdW5jdGlvbigpIHsgY2FsbGJhY2suY2FsbChjb250ZXh0LCBmYWxzZSkgfSk7XG4gICAgdGhpcy5jb25uZWN0KCk7XG4gIH0sXG5cbiAgcmVxdWVzdDogZnVuY3Rpb24obWVzc2FnZXMpIHtcbiAgICB0aGlzLl9wZW5kaW5nID0gdGhpcy5fcGVuZGluZyB8fCBuZXcgU2V0KCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBtZXNzYWdlcy5sZW5ndGg7IGkgPCBuOyBpKyspIHRoaXMuX3BlbmRpbmcuYWRkKG1lc3NhZ2VzW2ldKTtcblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBzZWxmLmNhbGxiYWNrKGZ1bmN0aW9uKHNvY2tldCkge1xuICAgICAgICBpZiAoIXNvY2tldCB8fCBzb2NrZXQucmVhZHlTdGF0ZSAhPT0gMSkgcmV0dXJuO1xuICAgICAgICBzb2NrZXQuc2VuZCh0b0pTT04obWVzc2FnZXMpKTtcbiAgICAgICAgcmVzb2x2ZShzb2NrZXQpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlbGYuY29ubmVjdCgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFib3J0OiBmdW5jdGlvbigpIHsgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHdzKSB7IHdzLmNsb3NlKCkgfSkgfVxuICAgIH07XG4gIH0sXG5cbiAgY29ubmVjdDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKFdlYlNvY2tldC5fdW5sb2FkZWQpIHJldHVybjtcblxuICAgIHRoaXMuX3N0YXRlID0gdGhpcy5fc3RhdGUgfHwgdGhpcy5VTkNPTk5FQ1RFRDtcbiAgICBpZiAodGhpcy5fc3RhdGUgIT09IHRoaXMuVU5DT05ORUNURUQpIHJldHVybjtcbiAgICB0aGlzLl9zdGF0ZSA9IHRoaXMuQ09OTkVDVElORztcblxuICAgIHZhciBzb2NrZXQgPSB0aGlzLl9jcmVhdGVTb2NrZXQoKTtcbiAgICBpZiAoIXNvY2tldCkgcmV0dXJuIHRoaXMuc2V0RGVmZXJyZWRTdGF0dXMoJ2ZhaWxlZCcpO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgc29ja2V0Lm9ub3BlbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHNvY2tldC5oZWFkZXJzKSBzZWxmLl9zdG9yZUNvb2tpZXMoc29ja2V0LmhlYWRlcnNbJ3NldC1jb29raWUnXSk7XG4gICAgICBzZWxmLl9zb2NrZXQgPSBzb2NrZXQ7XG4gICAgICBzZWxmLl9zdGF0ZSA9IHNlbGYuQ09OTkVDVEVEO1xuICAgICAgc2VsZi5fZXZlckNvbm5lY3RlZCA9IHRydWU7XG4gICAgICBzZWxmLl9waW5nKCk7XG4gICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCdzdWNjZWVkZWQnLCBzb2NrZXQpO1xuICAgIH07XG5cbiAgICB2YXIgY2xvc2VkID0gZmFsc2U7XG4gICAgc29ja2V0Lm9uY2xvc2UgPSBzb2NrZXQub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGNsb3NlZCkgcmV0dXJuO1xuICAgICAgY2xvc2VkID0gdHJ1ZTtcblxuICAgICAgdmFyIHdhc0Nvbm5lY3RlZCA9IChzZWxmLl9zdGF0ZSA9PT0gc2VsZi5DT05ORUNURUQpO1xuICAgICAgc29ja2V0Lm9ub3BlbiA9IHNvY2tldC5vbmNsb3NlID0gc29ja2V0Lm9uZXJyb3IgPSBzb2NrZXQub25tZXNzYWdlID0gbnVsbDtcblxuICAgICAgZGVsZXRlIHNlbGYuX3NvY2tldDtcbiAgICAgIHNlbGYuX3N0YXRlID0gc2VsZi5VTkNPTk5FQ1RFRDtcbiAgICAgIHNlbGYucmVtb3ZlVGltZW91dCgncGluZycpO1xuXG4gICAgICB2YXIgcGVuZGluZyA9IHNlbGYuX3BlbmRpbmcgPyBzZWxmLl9wZW5kaW5nLnRvQXJyYXkoKSA6IFtdO1xuICAgICAgZGVsZXRlIHNlbGYuX3BlbmRpbmc7XG5cbiAgICAgIGlmICh3YXNDb25uZWN0ZWQgfHwgc2VsZi5fZXZlckNvbm5lY3RlZCkge1xuICAgICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCd1bmtub3duJyk7XG4gICAgICAgIHNlbGYuX2hhbmRsZUVycm9yKHBlbmRpbmcsIHdhc0Nvbm5lY3RlZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWxmLnNldERlZmVycmVkU3RhdHVzKCdmYWlsZWQnKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc29ja2V0Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgcmVwbGllcztcbiAgICAgIHRyeSB7IHJlcGxpZXMgPSBKU09OLnBhcnNlKGV2ZW50LmRhdGEpIH0gY2F0Y2ggKGVycm9yKSB7fVxuXG4gICAgICBpZiAoIXJlcGxpZXMpIHJldHVybjtcblxuICAgICAgcmVwbGllcyA9IFtdLmNvbmNhdChyZXBsaWVzKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSByZXBsaWVzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICBpZiAocmVwbGllc1tpXS5zdWNjZXNzZnVsID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICBzZWxmLl9wZW5kaW5nLnJlbW92ZShyZXBsaWVzW2ldKTtcbiAgICAgIH1cbiAgICAgIHNlbGYuX3JlY2VpdmUocmVwbGllcyk7XG4gICAgfTtcbiAgfSxcblxuICBjbG9zZTogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLl9zb2NrZXQpIHJldHVybjtcbiAgICB0aGlzLl9zb2NrZXQuY2xvc2UoKTtcbiAgfSxcblxuICBfY3JlYXRlU29ja2V0OiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdXJsICAgICAgICA9IFdlYlNvY2tldC5nZXRTb2NrZXRVcmwodGhpcy5lbmRwb2ludCksXG4gICAgICAgIGhlYWRlcnMgICAgPSB0aGlzLl9kaXNwYXRjaGVyLmhlYWRlcnMsXG4gICAgICAgIGV4dGVuc2lvbnMgPSB0aGlzLl9kaXNwYXRjaGVyLndzRXh0ZW5zaW9ucyxcbiAgICAgICAgY29va2llICAgICA9IHRoaXMuX2dldENvb2tpZXMoKSxcbiAgICAgICAgdGxzICAgICAgICA9IHRoaXMuX2Rpc3BhdGNoZXIudGxzLFxuICAgICAgICBvcHRpb25zICAgID0ge2V4dGVuc2lvbnM6IGV4dGVuc2lvbnMsIGhlYWRlcnM6IGhlYWRlcnMsIHByb3h5OiB0aGlzLl9wcm94eSwgdGxzOiB0bHN9O1xuXG4gICAgaWYgKGNvb2tpZSAhPT0gJycpIG9wdGlvbnMuaGVhZGVyc1snQ29va2llJ10gPSBjb29raWU7XG5cbiAgICByZXR1cm4gd3MuY3JlYXRlKHVybCwgW10sIG9wdGlvbnMpO1xuICB9LFxuXG4gIF9waW5nOiBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX3NvY2tldCB8fCB0aGlzLl9zb2NrZXQucmVhZHlTdGF0ZSAhPT0gMSkgcmV0dXJuO1xuICAgIHRoaXMuX3NvY2tldC5zZW5kKCdbXScpO1xuICAgIHRoaXMuYWRkVGltZW91dCgncGluZycsIHRoaXMuX2Rpc3BhdGNoZXIudGltZW91dCAvIDIsIHRoaXMuX3BpbmcsIHRoaXMpO1xuICB9XG5cbn0pLCB7XG4gIFBST1RPQ09MUzoge1xuICAgICdodHRwOic6ICAnd3M6JyxcbiAgICAnaHR0cHM6JzogJ3dzczonXG4gIH0sXG5cbiAgY3JlYXRlOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCkge1xuICAgIHZhciBzb2NrZXRzID0gZGlzcGF0Y2hlci50cmFuc3BvcnRzLndlYnNvY2tldCA9IGRpc3BhdGNoZXIudHJhbnNwb3J0cy53ZWJzb2NrZXQgfHwge307XG4gICAgc29ja2V0c1tlbmRwb2ludC5ocmVmXSA9IHNvY2tldHNbZW5kcG9pbnQuaHJlZl0gfHwgbmV3IHRoaXMoZGlzcGF0Y2hlciwgZW5kcG9pbnQpO1xuICAgIHJldHVybiBzb2NrZXRzW2VuZHBvaW50LmhyZWZdO1xuICB9LFxuXG4gIGdldFNvY2tldFVybDogZnVuY3Rpb24oZW5kcG9pbnQpIHtcbiAgICBlbmRwb2ludCA9IGNvcHlPYmplY3QoZW5kcG9pbnQpO1xuICAgIGVuZHBvaW50LnByb3RvY29sID0gdGhpcy5QUk9UT0NPTFNbZW5kcG9pbnQucHJvdG9jb2xdO1xuICAgIHJldHVybiBVUkkuc3RyaW5naWZ5KGVuZHBvaW50KTtcbiAgfSxcblxuICBpc1VzYWJsZTogZnVuY3Rpb24oZGlzcGF0Y2hlciwgZW5kcG9pbnQsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgdGhpcy5jcmVhdGUoZGlzcGF0Y2hlciwgZW5kcG9pbnQpLmlzVXNhYmxlKGNhbGxiYWNrLCBjb250ZXh0KTtcbiAgfVxufSk7XG5cbmV4dGVuZChXZWJTb2NrZXQucHJvdG90eXBlLCBEZWZlcnJhYmxlKTtcblxuaWYgKGJyb3dzZXIuRXZlbnQgJiYgZ2xvYmFsLm9uYmVmb3JldW5sb2FkICE9PSB1bmRlZmluZWQpXG4gIGJyb3dzZXIuRXZlbnQub24oZ2xvYmFsLCAnYmVmb3JldW5sb2FkJywgZnVuY3Rpb24oKSB7IFdlYlNvY2tldC5fdW5sb2FkZWQgPSB0cnVlIH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzICAgICA9IHJlcXVpcmUoJy4uL3V0aWwvY2xhc3MnKSxcbiAgICBVUkkgICAgICAgPSByZXF1aXJlKCcuLi91dGlsL3VyaScpLFxuICAgIGJyb3dzZXIgICA9IHJlcXVpcmUoJy4uL3V0aWwvYnJvd3NlcicpLFxuICAgIGV4dGVuZCAgICA9IHJlcXVpcmUoJy4uL3V0aWwvZXh0ZW5kJyksXG4gICAgdG9KU09OICAgID0gcmVxdWlyZSgnLi4vdXRpbC90b19qc29uJyksXG4gICAgVHJhbnNwb3J0ID0gcmVxdWlyZSgnLi90cmFuc3BvcnQnKTtcblxudmFyIFhIUiA9IGV4dGVuZChDbGFzcyhUcmFuc3BvcnQsIHtcbiAgZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlcykge1xuICAgIHJldHVybiB0b0pTT04obWVzc2FnZXMpO1xuICB9LFxuXG4gIHJlcXVlc3Q6IGZ1bmN0aW9uKG1lc3NhZ2VzKSB7XG4gICAgdmFyIGhyZWYgPSB0aGlzLmVuZHBvaW50LmhyZWYsXG4gICAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgICB4aHI7XG5cbiAgICAvLyBQcmVmZXIgWE1MSHR0cFJlcXVlc3Qgb3ZlciBBY3RpdmVYT2JqZWN0IGlmIHRoZXkgYm90aCBleGlzdFxuICAgIGlmIChnbG9iYWwuWE1MSHR0cFJlcXVlc3QpIHtcbiAgICAgIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH0gZWxzZSBpZiAoZ2xvYmFsLkFjdGl2ZVhPYmplY3QpIHtcbiAgICAgIHhociA9IG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5faGFuZGxlRXJyb3IobWVzc2FnZXMpO1xuICAgIH1cblxuICAgIHhoci5vcGVuKCdQT1NUJywgaHJlZiwgdHJ1ZSk7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1ByYWdtYScsICduby1jYWNoZScpO1xuICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdYLVJlcXVlc3RlZC1XaXRoJywgJ1hNTEh0dHBSZXF1ZXN0Jyk7XG5cbiAgICB2YXIgaGVhZGVycyA9IHRoaXMuX2Rpc3BhdGNoZXIuaGVhZGVycztcbiAgICBmb3IgKHZhciBrZXkgaW4gaGVhZGVycykge1xuICAgICAgaWYgKCFoZWFkZXJzLmhhc093blByb3BlcnR5KGtleSkpIGNvbnRpbnVlO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCBoZWFkZXJzW2tleV0pO1xuICAgIH1cblxuICAgIHZhciBhYm9ydCA9IGZ1bmN0aW9uKCkgeyB4aHIuYWJvcnQoKSB9O1xuICAgIGlmIChnbG9iYWwub25iZWZvcmV1bmxvYWQgIT09IHVuZGVmaW5lZClcbiAgICAgIGJyb3dzZXIuRXZlbnQub24oZ2xvYmFsLCAnYmVmb3JldW5sb2FkJywgYWJvcnQpO1xuXG4gICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF4aHIgfHwgeGhyLnJlYWR5U3RhdGUgIT09IDQpIHJldHVybjtcblxuICAgICAgdmFyIHJlcGxpZXMgICAgPSBudWxsLFxuICAgICAgICAgIHN0YXR1cyAgICAgPSB4aHIuc3RhdHVzLFxuICAgICAgICAgIHRleHQgICAgICAgPSB4aHIucmVzcG9uc2VUZXh0LFxuICAgICAgICAgIHN1Y2Nlc3NmdWwgPSAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHx8IHN0YXR1cyA9PT0gMzA0IHx8IHN0YXR1cyA9PT0gMTIyMztcblxuICAgICAgaWYgKGdsb2JhbC5vbmJlZm9yZXVubG9hZCAhPT0gdW5kZWZpbmVkKVxuICAgICAgICBicm93c2VyLkV2ZW50LmRldGFjaChnbG9iYWwsICdiZWZvcmV1bmxvYWQnLCBhYm9ydCk7XG5cbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHt9O1xuICAgICAgeGhyID0gbnVsbDtcblxuICAgICAgaWYgKCFzdWNjZXNzZnVsKSByZXR1cm4gc2VsZi5faGFuZGxlRXJyb3IobWVzc2FnZXMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXBsaWVzID0gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7fVxuXG4gICAgICBpZiAocmVwbGllcylcbiAgICAgICAgc2VsZi5fcmVjZWl2ZShyZXBsaWVzKTtcbiAgICAgIGVsc2VcbiAgICAgICAgc2VsZi5faGFuZGxlRXJyb3IobWVzc2FnZXMpO1xuICAgIH07XG5cbiAgICB4aHIuc2VuZCh0aGlzLmVuY29kZShtZXNzYWdlcykpO1xuICAgIHJldHVybiB4aHI7XG4gIH1cbn0pLCB7XG4gIGlzVXNhYmxlOiBmdW5jdGlvbihkaXNwYXRjaGVyLCBlbmRwb2ludCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgdXNhYmxlID0gKG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnKVxuICAgICAgICAgICAgICB8fCBVUkkuaXNTYW1lT3JpZ2luKGVuZHBvaW50KTtcblxuICAgIGNhbGxiYWNrLmNhbGwoY29udGV4dCwgdXNhYmxlKTtcbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gWEhSO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tbW9uRWxlbWVudDogZnVuY3Rpb24obGlzdGEsIGxpc3RiKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaXN0YS5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgIGlmICh0aGlzLmluZGV4T2YobGlzdGIsIGxpc3RhW2ldKSAhPT0gLTEpXG4gICAgICAgIHJldHVybiBsaXN0YVtpXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG5cbiAgaW5kZXhPZjogZnVuY3Rpb24obGlzdCwgbmVlZGxlKSB7XG4gICAgaWYgKGxpc3QuaW5kZXhPZikgcmV0dXJuIGxpc3QuaW5kZXhPZihuZWVkbGUpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaXN0Lmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgaWYgKGxpc3RbaV0gPT09IG5lZWRsZSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfSxcblxuICBtYXA6IGZ1bmN0aW9uKG9iamVjdCwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICBpZiAob2JqZWN0Lm1hcCkgcmV0dXJuIG9iamVjdC5tYXAoY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGNhbGxiYWNrLmNhbGwoY29udGV4dCB8fCBudWxsLCBvYmplY3RbaV0sIGkpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAoIW9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgICAgcmVzdWx0LnB1c2goY2FsbGJhY2suY2FsbChjb250ZXh0IHx8IG51bGwsIGtleSwgb2JqZWN0W2tleV0pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICBmaWx0ZXI6IGZ1bmN0aW9uKGFycmF5LCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIGlmIChhcnJheS5maWx0ZXIpIHJldHVybiBhcnJheS5maWx0ZXIoY2FsbGJhY2ssIGNvbnRleHQpO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IGFycmF5Lmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgaWYgKGNhbGxiYWNrLmNhbGwoY29udGV4dCB8fCBudWxsLCBhcnJheVtpXSwgaSkpXG4gICAgICAgIHJlc3VsdC5wdXNoKGFycmF5W2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICBhc3luY0VhY2g6IGZ1bmN0aW9uKGxpc3QsIGl0ZXJhdG9yLCBjYWxsYmFjaywgY29udGV4dCkge1xuICAgIHZhciBuICAgICAgID0gbGlzdC5sZW5ndGgsXG4gICAgICAgIGkgICAgICAgPSAtMSxcbiAgICAgICAgY2FsbHMgICA9IDAsXG4gICAgICAgIGxvb3BpbmcgPSBmYWxzZTtcblxuICAgIHZhciBpdGVyYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgICBjYWxscyAtPSAxO1xuICAgICAgaSArPSAxO1xuICAgICAgaWYgKGkgPT09IG4pIHJldHVybiBjYWxsYmFjayAmJiBjYWxsYmFjay5jYWxsKGNvbnRleHQpO1xuICAgICAgaXRlcmF0b3IobGlzdFtpXSwgcmVzdW1lKTtcbiAgICB9O1xuXG4gICAgdmFyIGxvb3AgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChsb29waW5nKSByZXR1cm47XG4gICAgICBsb29waW5nID0gdHJ1ZTtcbiAgICAgIHdoaWxlIChjYWxscyA+IDApIGl0ZXJhdGUoKTtcbiAgICAgIGxvb3BpbmcgPSBmYWxzZTtcbiAgICB9O1xuXG4gICAgdmFyIHJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgY2FsbHMgKz0gMTtcbiAgICAgIGxvb3AoKTtcbiAgICB9O1xuICAgIHJlc3VtZSgpO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgRXZlbnQgPSB7XG4gIF9yZWdpc3RyeTogW10sXG5cbiAgb246IGZ1bmN0aW9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uKCkgeyBjYWxsYmFjay5jYWxsKGNvbnRleHQpIH07XG5cbiAgICBpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKVxuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgd3JhcHBlZCwgZmFsc2UpO1xuICAgIGVsc2VcbiAgICAgIGVsZW1lbnQuYXR0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZSwgd3JhcHBlZCk7XG5cbiAgICB0aGlzLl9yZWdpc3RyeS5wdXNoKHtcbiAgICAgIF9lbGVtZW50OiAgIGVsZW1lbnQsXG4gICAgICBfdHlwZTogICAgICBldmVudE5hbWUsXG4gICAgICBfY2FsbGJhY2s6ICBjYWxsYmFjayxcbiAgICAgIF9jb250ZXh0OiAgICAgY29udGV4dCxcbiAgICAgIF9oYW5kbGVyOiAgIHdyYXBwZWRcbiAgICB9KTtcbiAgfSxcblxuICBkZXRhY2g6IGZ1bmN0aW9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICB2YXIgaSA9IHRoaXMuX3JlZ2lzdHJ5Lmxlbmd0aCwgcmVnaXN0ZXI7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgcmVnaXN0ZXIgPSB0aGlzLl9yZWdpc3RyeVtpXTtcblxuICAgICAgaWYgKChlbGVtZW50ICAgICYmIGVsZW1lbnQgICAgIT09IHJlZ2lzdGVyLl9lbGVtZW50KSAgfHxcbiAgICAgICAgICAoZXZlbnROYW1lICAmJiBldmVudE5hbWUgICE9PSByZWdpc3Rlci5fdHlwZSkgICAgIHx8XG4gICAgICAgICAgKGNhbGxiYWNrICAgJiYgY2FsbGJhY2sgICAhPT0gcmVnaXN0ZXIuX2NhbGxiYWNrKSB8fFxuICAgICAgICAgIChjb250ZXh0ICAgICYmIGNvbnRleHQgICAgIT09IHJlZ2lzdGVyLl9jb250ZXh0KSlcbiAgICAgICAgY29udGludWU7XG5cbiAgICAgIGlmIChyZWdpc3Rlci5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKVxuICAgICAgICByZWdpc3Rlci5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHJlZ2lzdGVyLl90eXBlLCByZWdpc3Rlci5faGFuZGxlciwgZmFsc2UpO1xuICAgICAgZWxzZVxuICAgICAgICByZWdpc3Rlci5fZWxlbWVudC5kZXRhY2hFdmVudCgnb24nICsgcmVnaXN0ZXIuX3R5cGUsIHJlZ2lzdGVyLl9oYW5kbGVyKTtcblxuICAgICAgdGhpcy5fcmVnaXN0cnkuc3BsaWNlKGksMSk7XG4gICAgICByZWdpc3RlciA9IG51bGw7XG4gICAgfVxuICB9XG59O1xuXG5pZiAoZ2xvYmFsLm9udW5sb2FkICE9PSB1bmRlZmluZWQpXG4gIEV2ZW50Lm9uKGdsb2JhbCwgJ3VubG9hZCcsIEV2ZW50LmRldGFjaCwgRXZlbnQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgRXZlbnQ6IEV2ZW50XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXh0ZW5kID0gcmVxdWlyZSgnLi9leHRlbmQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihwYXJlbnQsIG1ldGhvZHMpIHtcbiAgaWYgKHR5cGVvZiBwYXJlbnQgIT09ICdmdW5jdGlvbicpIHtcbiAgICBtZXRob2RzID0gcGFyZW50O1xuICAgIHBhcmVudCAgPSBPYmplY3Q7XG4gIH1cblxuICB2YXIga2xhc3MgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuaW5pdGlhbGl6ZSkgcmV0dXJuIHRoaXM7XG4gICAgcmV0dXJuIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XG4gIH07XG5cbiAgdmFyIGJyaWRnZSA9IGZ1bmN0aW9uKCkge307XG4gIGJyaWRnZS5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlO1xuXG4gIGtsYXNzLnByb3RvdHlwZSA9IG5ldyBicmlkZ2UoKTtcbiAgZXh0ZW5kKGtsYXNzLnByb3RvdHlwZSwgbWV0aG9kcyk7XG5cbiAgcmV0dXJuIGtsYXNzO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBWRVJTSU9OOiAgICAgICAgICAnMS4yLjQnLFxuXG4gIEJBWUVVWF9WRVJTSU9OOiAgICcxLjAnLFxuICBJRF9MRU5HVEg6ICAgICAgICAxNjAsXG4gIEpTT05QX0NBTExCQUNLOiAgICdqc29ucGNhbGxiYWNrJyxcbiAgQ09OTkVDVElPTl9UWVBFUzogWydsb25nLXBvbGxpbmcnLCAnY3Jvc3Mtb3JpZ2luLWxvbmctcG9sbGluZycsICdjYWxsYmFjay1wb2xsaW5nJywgJ3dlYnNvY2tldCcsICdldmVudHNvdXJjZScsICdpbi1wcm9jZXNzJ10sXG5cbiAgTUFOREFUT1JZX0NPTk5FQ1RJT05fVFlQRVM6IFsnbG9uZy1wb2xsaW5nJywgJ2NhbGxiYWNrLXBvbGxpbmcnLCAnaW4tcHJvY2VzcyddXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29weU9iamVjdCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgY2xvbmUsIGksIGtleTtcbiAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgY2xvbmUgPSBbXTtcbiAgICBpID0gb2JqZWN0Lmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSBjbG9uZVtpXSA9IGNvcHlPYmplY3Qob2JqZWN0W2ldKTtcbiAgICByZXR1cm4gY2xvbmU7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpIHtcbiAgICBjbG9uZSA9IChvYmplY3QgPT09IG51bGwpID8gbnVsbCA6IHt9O1xuICAgIGZvciAoa2V5IGluIG9iamVjdCkgY2xvbmVba2V5XSA9IGNvcHlPYmplY3Qob2JqZWN0W2tleV0pO1xuICAgIHJldHVybiBjbG9uZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNvcHlPYmplY3Q7XG4iLCIvKlxuQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5IG9mXG50aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluXG50aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvXG51c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllc1xub2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvXG5zbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuU09GVFdBUkUuXG4qL1xuXG52YXIgaXNBcnJheSA9IHR5cGVvZiBBcnJheS5pc0FycmF5ID09PSAnZnVuY3Rpb24nXG4gICAgPyBBcnJheS5pc0FycmF5XG4gICAgOiBmdW5jdGlvbiAoeHMpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSdcbiAgICB9XG47XG5mdW5jdGlvbiBpbmRleE9mICh4cywgeCkge1xuICAgIGlmICh4cy5pbmRleE9mKSByZXR1cm4geHMuaW5kZXhPZih4KTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh4ID09PSB4c1tpXSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge31cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc0FycmF5KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKVxuICAgIHtcbiAgICAgIGlmIChhcmd1bWVudHNbMV0gaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBhcmd1bWVudHNbMV07IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmNhdWdodCwgdW5zcGVjaWZpZWQgJ2Vycm9yJyBldmVudC5cIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpIHJldHVybiBmYWxzZTtcbiAgdmFyIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGlmICghaGFuZGxlcikgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfSBlbHNlIGlmIChpc0FycmF5KGhhbmRsZXIpKSB7XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8vIEV2ZW50RW1pdHRlciBpcyBkZWZpbmVkIGluIHNyYy9ub2RlX2V2ZW50cy5jY1xuLy8gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0KCkgaXMgYWxzbyBkZWZpbmVkIHRoZXJlLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICgnZnVuY3Rpb24nICE9PSB0eXBlb2YgbGlzdGVuZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2FkZExpc3RlbmVyIG9ubHkgdGFrZXMgaW5zdGFuY2VzIG9mIEZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAoIXRoaXMuX2V2ZW50cykgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PSBcIm5ld0xpc3RlbmVyc1wiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lcnNcIi5cbiAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkge1xuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICB9IGVsc2UgaWYgKGlzQXJyYXkodGhpcy5fZXZlbnRzW3R5cGVdKSkge1xuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG4gIH0gZWxzZSB7XG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzZWxmLm9uKHR5cGUsIGZ1bmN0aW9uIGcoKSB7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcbiAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9KTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoJ2Z1bmN0aW9uJyAhPT0gdHlwZW9mIGxpc3RlbmVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZW1vdmVMaXN0ZW5lciBvbmx5IHRha2VzIGluc3RhbmNlcyBvZiBGdW5jdGlvbicpO1xuICB9XG5cbiAgLy8gZG9lcyBub3QgdXNlIGxpc3RlbmVycygpLCBzbyBubyBzaWRlIGVmZmVjdCBvZiBjcmVhdGluZyBfZXZlbnRzW3R5cGVdXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pIHJldHVybiB0aGlzO1xuXG4gIHZhciBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0FycmF5KGxpc3QpKSB7XG4gICAgdmFyIGkgPSBpbmRleE9mKGxpc3QsIGxpc3RlbmVyKTtcbiAgICBpZiAoaSA8IDApIHJldHVybiB0aGlzO1xuICAgIGxpc3Quc3BsaWNlKGksIDEpO1xuICAgIGlmIChsaXN0Lmxlbmd0aCA9PSAwKVxuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgfSBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0gPT09IGxpc3RlbmVyKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBkb2VzIG5vdCB1c2UgbGlzdGVuZXJzKCksIHNvIG5vIHNpZGUgZWZmZWN0IG9mIGNyZWF0aW5nIF9ldmVudHNbdHlwZV1cbiAgaWYgKHR5cGUgJiYgdGhpcy5fZXZlbnRzICYmIHRoaXMuX2V2ZW50c1t0eXBlXSkgdGhpcy5fZXZlbnRzW3R5cGVdID0gbnVsbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMpIHRoaXMuX2V2ZW50cyA9IHt9O1xuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkgdGhpcy5fZXZlbnRzW3R5cGVdID0gW107XG4gIGlmICghaXNBcnJheSh0aGlzLl9ldmVudHNbdHlwZV0pKSB7XG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIH1cbiAgcmV0dXJuIHRoaXMuX2V2ZW50c1t0eXBlXTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZGVzdCwgc291cmNlLCBvdmVyd3JpdGUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiBkZXN0O1xuICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgaWYgKCFzb3VyY2UuaGFzT3duUHJvcGVydHkoa2V5KSkgY29udGludWU7XG4gICAgaWYgKGRlc3QuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBvdmVyd3JpdGUgPT09IGZhbHNlKSBjb250aW51ZTtcbiAgICBpZiAoZGVzdFtrZXldICE9PSBzb3VyY2Vba2V5XSlcbiAgICAgIGRlc3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBkZXN0O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzYXAgPSByZXF1aXJlKCdhc2FwJyk7XG5cbnZhciBQRU5ESU5HICAgPSAwLFxuICAgIEZVTEZJTExFRCA9IDEsXG4gICAgUkVKRUNURUQgID0gMjtcblxudmFyIFJFVFVSTiA9IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHggfSxcbiAgICBUSFJPVyAgPSBmdW5jdGlvbih4KSB7IHRocm93ICB4IH07XG5cbnZhciBQcm9taXNlID0gZnVuY3Rpb24odGFzaykge1xuICB0aGlzLl9zdGF0ZSAgICAgICA9IFBFTkRJTkc7XG4gIHRoaXMuX29uRnVsZmlsbGVkID0gW107XG4gIHRoaXMuX29uUmVqZWN0ZWQgID0gW107XG5cbiAgaWYgKHR5cGVvZiB0YXNrICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0YXNrKGZ1bmN0aW9uKHZhbHVlKSAgeyByZXNvbHZlKHNlbGYsIHZhbHVlKSB9LFxuICAgICAgIGZ1bmN0aW9uKHJlYXNvbikgeyByZWplY3Qoc2VsZiwgcmVhc29uKSB9KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICB2YXIgbmV4dCA9IG5ldyBQcm9taXNlKCk7XG4gIHJlZ2lzdGVyT25GdWxmaWxsZWQodGhpcywgb25GdWxmaWxsZWQsIG5leHQpO1xuICByZWdpc3Rlck9uUmVqZWN0ZWQodGhpcywgb25SZWplY3RlZCwgbmV4dCk7XG4gIHJldHVybiBuZXh0O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGVbJ2NhdGNoJ10gPSBmdW5jdGlvbihvblJlamVjdGVkKSB7XG4gIHJldHVybiB0aGlzLnRoZW4obnVsbCwgb25SZWplY3RlZCk7XG59O1xuXG52YXIgcmVnaXN0ZXJPbkZ1bGZpbGxlZCA9IGZ1bmN0aW9uKHByb21pc2UsIG9uRnVsZmlsbGVkLCBuZXh0KSB7XG4gIGlmICh0eXBlb2Ygb25GdWxmaWxsZWQgIT09ICdmdW5jdGlvbicpIG9uRnVsZmlsbGVkID0gUkVUVVJOO1xuICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKHZhbHVlKSB7IGludm9rZShvbkZ1bGZpbGxlZCwgdmFsdWUsIG5leHQpIH07XG5cbiAgaWYgKHByb21pc2UuX3N0YXRlID09PSBQRU5ESU5HKSB7XG4gICAgcHJvbWlzZS5fb25GdWxmaWxsZWQucHVzaChoYW5kbGVyKTtcbiAgfSBlbHNlIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gRlVMRklMTEVEKSB7XG4gICAgaGFuZGxlcihwcm9taXNlLl92YWx1ZSk7XG4gIH1cbn07XG5cbnZhciByZWdpc3Rlck9uUmVqZWN0ZWQgPSBmdW5jdGlvbihwcm9taXNlLCBvblJlamVjdGVkLCBuZXh0KSB7XG4gIGlmICh0eXBlb2Ygb25SZWplY3RlZCAhPT0gJ2Z1bmN0aW9uJykgb25SZWplY3RlZCA9IFRIUk9XO1xuICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uKHJlYXNvbikgeyBpbnZva2Uob25SZWplY3RlZCwgcmVhc29uLCBuZXh0KSB9O1xuXG4gIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUEVORElORykge1xuICAgIHByb21pc2UuX29uUmVqZWN0ZWQucHVzaChoYW5kbGVyKTtcbiAgfSBlbHNlIGlmIChwcm9taXNlLl9zdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICBoYW5kbGVyKHByb21pc2UuX3JlYXNvbik7XG4gIH1cbn07XG5cbnZhciBpbnZva2UgPSBmdW5jdGlvbihmbiwgdmFsdWUsIG5leHQpIHtcbiAgYXNhcChmdW5jdGlvbigpIHsgX2ludm9rZShmbiwgdmFsdWUsIG5leHQpIH0pO1xufTtcblxudmFyIF9pbnZva2UgPSBmdW5jdGlvbihmbiwgdmFsdWUsIG5leHQpIHtcbiAgdmFyIG91dGNvbWU7XG5cbiAgdHJ5IHtcbiAgICBvdXRjb21lID0gZm4odmFsdWUpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiByZWplY3QobmV4dCwgZXJyb3IpO1xuICB9XG5cbiAgaWYgKG91dGNvbWUgPT09IG5leHQpIHtcbiAgICByZWplY3QobmV4dCwgbmV3IFR5cGVFcnJvcignUmVjdXJzaXZlIHByb21pc2UgY2hhaW4gZGV0ZWN0ZWQnKSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzb2x2ZShuZXh0LCBvdXRjb21lKTtcbiAgfVxufTtcblxudmFyIHJlc29sdmUgPSBmdW5jdGlvbihwcm9taXNlLCB2YWx1ZSkge1xuICB2YXIgY2FsbGVkID0gZmFsc2UsIHR5cGUsIHRoZW47XG5cbiAgdHJ5IHtcbiAgICB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgIHRoZW4gPSB2YWx1ZSAhPT0gbnVsbCAmJiAodHlwZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlID09PSAnb2JqZWN0JykgJiYgdmFsdWUudGhlbjtcblxuICAgIGlmICh0eXBlb2YgdGhlbiAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuXG4gICAgdGhlbi5jYWxsKHZhbHVlLCBmdW5jdGlvbih2KSB7XG4gICAgICBpZiAoIShjYWxsZWQgXiAoY2FsbGVkID0gdHJ1ZSkpKSByZXR1cm47XG4gICAgICByZXNvbHZlKHByb21pc2UsIHYpO1xuICAgIH0sIGZ1bmN0aW9uKHIpIHtcbiAgICAgIGlmICghKGNhbGxlZCBeIChjYWxsZWQgPSB0cnVlKSkpIHJldHVybjtcbiAgICAgIHJlamVjdChwcm9taXNlLCByKTtcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoIShjYWxsZWQgXiAoY2FsbGVkID0gdHJ1ZSkpKSByZXR1cm47XG4gICAgcmVqZWN0KHByb21pc2UsIGVycm9yKTtcbiAgfVxufTtcblxudmFyIGZ1bGZpbGwgPSBmdW5jdGlvbihwcm9taXNlLCB2YWx1ZSkge1xuICBpZiAocHJvbWlzZS5fc3RhdGUgIT09IFBFTkRJTkcpIHJldHVybjtcblxuICBwcm9taXNlLl9zdGF0ZSAgICAgID0gRlVMRklMTEVEO1xuICBwcm9taXNlLl92YWx1ZSAgICAgID0gdmFsdWU7XG4gIHByb21pc2UuX29uUmVqZWN0ZWQgPSBbXTtcblxuICB2YXIgb25GdWxmaWxsZWQgPSBwcm9taXNlLl9vbkZ1bGZpbGxlZCwgZm47XG4gIHdoaWxlIChmbiA9IG9uRnVsZmlsbGVkLnNoaWZ0KCkpIGZuKHZhbHVlKTtcbn07XG5cbnZhciByZWplY3QgPSBmdW5jdGlvbihwcm9taXNlLCByZWFzb24pIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSByZXR1cm47XG5cbiAgcHJvbWlzZS5fc3RhdGUgICAgICAgPSBSRUpFQ1RFRDtcbiAgcHJvbWlzZS5fcmVhc29uICAgICAgPSByZWFzb247XG4gIHByb21pc2UuX29uRnVsZmlsbGVkID0gW107XG5cbiAgdmFyIG9uUmVqZWN0ZWQgPSBwcm9taXNlLl9vblJlamVjdGVkLCBmbjtcbiAgd2hpbGUgKGZuID0gb25SZWplY3RlZC5zaGlmdCgpKSBmbihyZWFzb24pO1xufTtcblxuUHJvbWlzZS5yZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkgeyByZXNvbHZlKHZhbHVlKSB9KTtcbn07XG5cblByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24ocmVhc29uKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHsgcmVqZWN0KHJlYXNvbikgfSk7XG59O1xuXG5Qcm9taXNlLmFsbCA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgbGlzdCA9IFtdLCBuID0gcHJvbWlzZXMubGVuZ3RoLCBpO1xuXG4gICAgaWYgKG4gPT09IDApIHJldHVybiByZXNvbHZlKGxpc3QpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgKGZ1bmN0aW9uKHByb21pc2UsIGkpIHtcbiAgICAgIFByb21pc2UucmVzb2x2ZShwcm9taXNlKS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIGxpc3RbaV0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKC0tbiA9PT0gMCkgcmVzb2x2ZShsaXN0KTtcbiAgICAgIH0sIHJlamVjdCk7XG4gICAgfSkocHJvbWlzZXNbaV0sIGkpO1xuICB9KTtcbn07XG5cblByb21pc2UucmFjZSA9IGZ1bmN0aW9uKHByb21pc2VzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IHByb21pc2VzLmxlbmd0aDsgaSA8IG47IGkrKylcbiAgICAgIFByb21pc2UucmVzb2x2ZShwcm9taXNlc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICB9KTtcbn07XG5cblByb21pc2UuZGVmZXJyZWQgPSBQcm9taXNlLnBlbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHR1cGxlID0ge307XG5cbiAgdHVwbGUucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHR1cGxlLnJlc29sdmUgPSByZXNvbHZlO1xuICAgIHR1cGxlLnJlamVjdCAgPSByZWplY3Q7XG4gIH0pO1xuICByZXR1cm4gdHVwbGU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzcyA9IHJlcXVpcmUoJy4vY2xhc3MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDbGFzcyh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2luZGV4ID0ge307XG4gIH0sXG5cbiAgYWRkOiBmdW5jdGlvbihpdGVtKSB7XG4gICAgdmFyIGtleSA9IChpdGVtLmlkICE9PSB1bmRlZmluZWQpID8gaXRlbS5pZCA6IGl0ZW07XG4gICAgaWYgKHRoaXMuX2luZGV4Lmhhc093blByb3BlcnR5KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICB0aGlzLl9pbmRleFtrZXldID0gaXRlbTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSxcblxuICBmb3JFYWNoOiBmdW5jdGlvbihibG9jaywgY29udGV4dCkge1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLl9pbmRleCkge1xuICAgICAgaWYgKHRoaXMuX2luZGV4Lmhhc093blByb3BlcnR5KGtleSkpXG4gICAgICAgIGJsb2NrLmNhbGwoY29udGV4dCwgdGhpcy5faW5kZXhba2V5XSk7XG4gICAgfVxuICB9LFxuXG4gIGlzRW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLl9pbmRleCkge1xuICAgICAgaWYgKHRoaXMuX2luZGV4Lmhhc093blByb3BlcnR5KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgbWVtYmVyOiBmdW5jdGlvbihpdGVtKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuX2luZGV4KSB7XG4gICAgICBpZiAodGhpcy5faW5kZXhba2V5XSA9PT0gaXRlbSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICB2YXIga2V5ID0gKGl0ZW0uaWQgIT09IHVuZGVmaW5lZCkgPyBpdGVtLmlkIDogaXRlbTtcbiAgICB2YXIgcmVtb3ZlZCA9IHRoaXMuX2luZGV4W2tleV07XG4gICAgZGVsZXRlIHRoaXMuX2luZGV4W2tleV07XG4gICAgcmV0dXJuIHJlbW92ZWQ7XG4gIH0sXG5cbiAgdG9BcnJheTogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHsgYXJyYXkucHVzaChpdGVtKSB9KTtcbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBodHRwOi8vYXNzYW5rYS5uZXQvY29udGVudC90ZWNoLzIwMDkvMDkvMDIvanNvbjItanMtdnMtcHJvdG90eXBlL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqZWN0LCBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuICh0aGlzW2tleV0gaW5zdGFuY2VvZiBBcnJheSkgPyB0aGlzW2tleV0gOiB2YWx1ZTtcbiAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaXNVUkk6IGZ1bmN0aW9uKHVyaSkge1xuICAgIHJldHVybiB1cmkgJiYgdXJpLnByb3RvY29sICYmIHVyaS5ob3N0ICYmIHVyaS5wYXRoO1xuICB9LFxuXG4gIGlzU2FtZU9yaWdpbjogZnVuY3Rpb24odXJpKSB7XG4gICAgcmV0dXJuIHVyaS5wcm90b2NvbCA9PT0gbG9jYXRpb24ucHJvdG9jb2wgJiZcbiAgICAgICAgICAgdXJpLmhvc3RuYW1lID09PSBsb2NhdGlvbi5ob3N0bmFtZSAmJlxuICAgICAgICAgICB1cmkucG9ydCAgICAgPT09IGxvY2F0aW9uLnBvcnQ7XG4gIH0sXG5cbiAgcGFyc2U6IGZ1bmN0aW9uKHVybCkge1xuICAgIGlmICh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgcmV0dXJuIHVybDtcbiAgICB2YXIgdXJpID0ge30sIHBhcnRzLCBxdWVyeSwgcGFpcnMsIGksIG4sIGRhdGE7XG5cbiAgICB2YXIgY29uc3VtZSA9IGZ1bmN0aW9uKG5hbWUsIHBhdHRlcm4pIHtcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlKHBhdHRlcm4sIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICAgIHVyaVtuYW1lXSA9IG1hdGNoO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9KTtcbiAgICAgIHVyaVtuYW1lXSA9IHVyaVtuYW1lXSB8fCAnJztcbiAgICB9O1xuXG4gICAgY29uc3VtZSgncHJvdG9jb2wnLCAvXlthLXpdK1xcOi9pKTtcbiAgICBjb25zdW1lKCdob3N0JywgICAgIC9eXFwvXFwvW15cXC9cXD8jXSsvKTtcblxuICAgIGlmICghL15cXC8vLnRlc3QodXJsKSAmJiAhdXJpLmhvc3QpXG4gICAgICB1cmwgPSBsb2NhdGlvbi5wYXRobmFtZS5yZXBsYWNlKC9bXlxcL10qJC8sICcnKSArIHVybDtcblxuICAgIGNvbnN1bWUoJ3BhdGhuYW1lJywgL15bXlxcPyNdKi8pO1xuICAgIGNvbnN1bWUoJ3NlYXJjaCcsICAgL15cXD9bXiNdKi8pO1xuICAgIGNvbnN1bWUoJ2hhc2gnLCAgICAgL14jLiovKTtcblxuICAgIHVyaS5wcm90b2NvbCA9IHVyaS5wcm90b2NvbCB8fCBsb2NhdGlvbi5wcm90b2NvbDtcblxuICAgIGlmICh1cmkuaG9zdCkge1xuICAgICAgdXJpLmhvc3QgICAgID0gdXJpLmhvc3Quc3Vic3RyKDIpO1xuICAgICAgcGFydHMgICAgICAgID0gdXJpLmhvc3Quc3BsaXQoJzonKTtcbiAgICAgIHVyaS5ob3N0bmFtZSA9IHBhcnRzWzBdO1xuICAgICAgdXJpLnBvcnQgICAgID0gcGFydHNbMV0gfHwgJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVyaS5ob3N0ICAgICA9IGxvY2F0aW9uLmhvc3Q7XG4gICAgICB1cmkuaG9zdG5hbWUgPSBsb2NhdGlvbi5ob3N0bmFtZTtcbiAgICAgIHVyaS5wb3J0ICAgICA9IGxvY2F0aW9uLnBvcnQ7XG4gICAgfVxuXG4gICAgdXJpLnBhdGhuYW1lID0gdXJpLnBhdGhuYW1lIHx8ICcvJztcbiAgICB1cmkucGF0aCA9IHVyaS5wYXRobmFtZSArIHVyaS5zZWFyY2g7XG5cbiAgICBxdWVyeSA9IHVyaS5zZWFyY2gucmVwbGFjZSgvXlxcPy8sICcnKTtcbiAgICBwYWlycyA9IHF1ZXJ5ID8gcXVlcnkuc3BsaXQoJyYnKSA6IFtdO1xuICAgIGRhdGEgID0ge307XG5cbiAgICBmb3IgKGkgPSAwLCBuID0gcGFpcnMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XG4gICAgICBwYXJ0cyA9IHBhaXJzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICBkYXRhW2RlY29kZVVSSUNvbXBvbmVudChwYXJ0c1swXSB8fCAnJyldID0gZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzWzFdIHx8ICcnKTtcbiAgICB9XG5cbiAgICB1cmkucXVlcnkgPSBkYXRhO1xuXG4gICAgdXJpLmhyZWYgPSB0aGlzLnN0cmluZ2lmeSh1cmkpO1xuICAgIHJldHVybiB1cmk7XG4gIH0sXG5cbiAgc3RyaW5naWZ5OiBmdW5jdGlvbih1cmkpIHtcbiAgICB2YXIgc3RyaW5nID0gdXJpLnByb3RvY29sICsgJy8vJyArIHVyaS5ob3N0bmFtZTtcbiAgICBpZiAodXJpLnBvcnQpIHN0cmluZyArPSAnOicgKyB1cmkucG9ydDtcbiAgICBzdHJpbmcgKz0gdXJpLnBhdGhuYW1lICsgdGhpcy5xdWVyeVN0cmluZyh1cmkucXVlcnkpICsgKHVyaS5oYXNoIHx8ICcnKTtcbiAgICByZXR1cm4gc3RyaW5nO1xuICB9LFxuXG4gIHF1ZXJ5U3RyaW5nOiBmdW5jdGlvbihxdWVyeSkge1xuICAgIHZhciBwYWlycyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBxdWVyeSkge1xuICAgICAgaWYgKCFxdWVyeS5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcbiAgICAgIHBhaXJzLnB1c2goZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQocXVlcnlba2V5XSkpO1xuICAgIH1cbiAgICBpZiAocGFpcnMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuICc/JyArIHBhaXJzLmpvaW4oJyYnKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFycmF5ID0gcmVxdWlyZSgnLi9hcnJheScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdGlvbnMsIHZhbGlkS2V5cykge1xuICBmb3IgKHZhciBrZXkgaW4gb3B0aW9ucykge1xuICAgIGlmIChhcnJheS5pbmRleE9mKHZhbGlkS2V5cywga2V5KSA8IDApXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VucmVjb2duaXplZCBvcHRpb246ICcgKyBrZXkpO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgV1MgPSBnbG9iYWwuTW96V2ViU29ja2V0IHx8IGdsb2JhbC5XZWJTb2NrZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGU6IGZ1bmN0aW9uKHVybCwgcHJvdG9jb2xzLCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBXUyAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIG5ldyBXUyh1cmwpO1xuICB9XG59O1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiJdfQ==