@appium/base-driver 8.1.1 → 8.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/build/lib/basedriver/capabilities.js +6 -6
  2. package/build/lib/basedriver/commands/find.js +1 -1
  3. package/build/lib/basedriver/commands/index.js +2 -4
  4. package/build/lib/basedriver/commands/log.js +1 -1
  5. package/build/lib/basedriver/commands/session.js +1 -1
  6. package/build/lib/basedriver/commands/timeout.js +1 -1
  7. package/build/lib/basedriver/desired-caps.js +1 -1
  8. package/build/lib/basedriver/device-settings.js +1 -1
  9. package/build/lib/basedriver/driver.js +5 -7
  10. package/build/lib/basedriver/helpers.js +5 -3
  11. package/build/lib/constants.js +1 -1
  12. package/build/lib/express/crash.js +1 -1
  13. package/build/lib/express/middleware.js +3 -3
  14. package/build/lib/express/server.js +1 -1
  15. package/build/lib/express/static.js +2 -2
  16. package/build/lib/express/websocket.js +3 -3
  17. package/build/lib/index.js +124 -0
  18. package/build/lib/jsonwp-status/status.js +1 -1
  19. package/build/lib/protocol/errors.js +6 -5
  20. package/build/lib/protocol/helpers.js +3 -3
  21. package/build/lib/protocol/index.js +31 -19
  22. package/build/lib/protocol/protocol.js +22 -11
  23. package/build/lib/protocol/routes.js +6 -12
  24. package/build/test/basedriver/capability-specs.js +10 -10
  25. package/build/test/basedriver/commands/event-specs.js +10 -10
  26. package/build/test/basedriver/driver-e2e-specs.js +3 -3
  27. package/build/test/basedriver/driver-e2e-tests.js +53 -256
  28. package/build/test/basedriver/driver-specs.js +3 -3
  29. package/build/test/basedriver/driver-tests.js +6 -6
  30. package/build/test/basedriver/helpers-e2e-specs.js +10 -4
  31. package/build/test/basedriver/index.js +4 -4
  32. package/build/test/basedriver/timeout-specs.js +7 -7
  33. package/build/test/basedriver/websockets-e2e-specs.js +11 -11
  34. package/build/test/express/server-e2e-specs.js +156 -0
  35. package/build/test/express/server-specs.js +151 -0
  36. package/build/test/express/static-specs.js +23 -0
  37. package/build/test/helpers.js +57 -0
  38. package/build/test/jsonwp-proxy/mock-request.js +93 -0
  39. package/build/test/jsonwp-proxy/protocol-converter-specs.js +173 -0
  40. package/build/test/jsonwp-proxy/proxy-e2e-specs.js +62 -0
  41. package/build/test/jsonwp-proxy/proxy-specs.js +299 -0
  42. package/build/test/jsonwp-proxy/url-specs.js +167 -0
  43. package/build/test/jsonwp-status/status-specs.js +36 -0
  44. package/build/test/protocol/errors-specs.js +388 -0
  45. package/build/test/protocol/fake-driver.js +168 -0
  46. package/build/test/protocol/helpers.js +27 -0
  47. package/build/test/protocol/protocol-e2e-specs.js +1242 -0
  48. package/build/test/protocol/routes-specs.js +82 -0
  49. package/build/test/protocol/validator-specs.js +151 -0
  50. package/index.d.ts +309 -44
  51. package/index.js +1 -62
  52. package/lib/basedriver/commands/index.js +0 -2
  53. package/lib/basedriver/driver.js +2 -22
  54. package/lib/basedriver/helpers.js +5 -4
  55. package/lib/index.js +62 -0
  56. package/lib/protocol/index.js +3 -1
  57. package/lib/protocol/protocol.js +18 -7
  58. package/lib/protocol/routes.js +1 -4
  59. package/package.json +8 -16
  60. package/test/basedriver/capability-specs.js +1 -1
  61. package/test/basedriver/commands/event-specs.js +1 -1
  62. package/test/basedriver/driver-e2e-specs.js +1 -1
  63. package/test/basedriver/driver-e2e-tests.js +66 -213
  64. package/test/basedriver/driver-specs.js +1 -1
  65. package/test/basedriver/driver-tests.js +3 -3
  66. package/test/basedriver/helpers-e2e-specs.js +9 -4
  67. package/test/basedriver/timeout-specs.js +1 -1
  68. package/test/basedriver/websockets-e2e-specs.js +7 -7
  69. package/build/index.js +0 -118
  70. package/build/lib/basedriver/commands/execute-child.js +0 -137
  71. package/build/lib/basedriver/commands/execute.js +0 -119
  72. package/build/test/basedriver/fixtures/custom-element-finder-bad.js +0 -12
  73. package/build/test/basedriver/fixtures/custom-element-finder.js +0 -36
  74. package/lib/basedriver/commands/execute-child.js +0 -132
  75. package/lib/basedriver/commands/execute.js +0 -126
@@ -0,0 +1,1242 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _lib = require("../../lib");
8
+
9
+ var _fakeDriver = require("./fake-driver");
10
+
11
+ var _axios = _interopRequireDefault(require("axios"));
12
+
13
+ var _sinon = _interopRequireDefault(require("sinon"));
14
+
15
+ var _httpStatusCodes = require("http-status-codes");
16
+
17
+ var _helpers = require("./helpers");
18
+
19
+ var _constants = require("../../lib/constants");
20
+
21
+ var _querystring = _interopRequireDefault(require("querystring"));
22
+
23
+ var _helpers2 = require("../helpers");
24
+
25
+ let port;
26
+ let baseUrl;
27
+ describe('Protocol', function () {
28
+ before(async function () {
29
+ port = await (0, _helpers2.getTestPort)();
30
+ baseUrl = `http://${_helpers2.TEST_HOST}:${port}`;
31
+ });
32
+ describe('direct to driver', function () {
33
+ let d = new _fakeDriver.FakeDriver();
34
+ it('should return response values directly from the driver', async function () {
35
+ (await d.setUrl('http://google.com')).should.contain('google');
36
+ });
37
+ });
38
+ describe('via express router', function () {
39
+ let mjsonwpServer;
40
+ let driver;
41
+ before(async function () {
42
+ driver = new _fakeDriver.FakeDriver();
43
+ driver.sessionId = 'foo';
44
+ mjsonwpServer = await (0, _lib.server)({
45
+ routeConfiguringFunction: (0, _lib.routeConfiguringFunction)(driver),
46
+ port
47
+ });
48
+ });
49
+ after(async function () {
50
+ await mjsonwpServer.close();
51
+ });
52
+ it('should proxy to driver and return valid jsonwp response', async function () {
53
+ const {
54
+ data
55
+ } = await (0, _axios.default)({
56
+ url: `${baseUrl}/session/foo/url`,
57
+ method: 'POST',
58
+ data: {
59
+ url: 'http://google.com'
60
+ }
61
+ });
62
+ data.should.eql({
63
+ status: 0,
64
+ value: 'Navigated to: http://google.com',
65
+ sessionId: 'foo'
66
+ });
67
+ });
68
+ it('should assume requests without a Content-Type are json requests', async function () {
69
+ const {
70
+ data
71
+ } = await (0, _axios.default)({
72
+ url: `${baseUrl}/session/foo/url`,
73
+ method: 'POST',
74
+ data: {
75
+ url: 'http://google.com'
76
+ }
77
+ });
78
+ data.should.eql({
79
+ status: 0,
80
+ value: 'Navigated to: http://google.com',
81
+ sessionId: 'foo'
82
+ });
83
+ });
84
+ it('should respond to x-www-form-urlencoded as well as json requests', async function () {
85
+ const {
86
+ data
87
+ } = await (0, _axios.default)({
88
+ url: `${baseUrl}/session/foo/url`,
89
+ headers: {
90
+ 'Content-Type': 'application/x-www-form-urlencoded'
91
+ },
92
+ method: 'POST',
93
+ data: _querystring.default.stringify({
94
+ url: 'http://google.com'
95
+ })
96
+ });
97
+ data.should.eql({
98
+ status: 0,
99
+ value: 'Navigated to: http://google.com',
100
+ sessionId: 'foo'
101
+ });
102
+ });
103
+ it('should include url request parameters for methods to use - sessionid', async function () {
104
+ const {
105
+ data
106
+ } = await (0, _axios.default)({
107
+ url: `${baseUrl}/session/foo/back`,
108
+ method: 'POST',
109
+ data: {}
110
+ });
111
+ data.should.eql({
112
+ status: 0,
113
+ value: 'foo',
114
+ sessionId: 'foo'
115
+ });
116
+ });
117
+ it('should include url request parameters for methods to use - elementid', async function () {
118
+ const {
119
+ data
120
+ } = await (0, _axios.default)({
121
+ url: `${baseUrl}/session/foo/element/bar/click`,
122
+ method: 'POST',
123
+ data: {}
124
+ });
125
+ data.status.should.equal(0);
126
+ data.value.should.eql(['bar', 'foo']);
127
+ });
128
+ it('should include url req params in the order: custom, element, session', async function () {
129
+ const {
130
+ data
131
+ } = await (0, _axios.default)({
132
+ url: `${baseUrl}/session/foo/element/bar/attribute/baz`
133
+ });
134
+ data.status.should.equal(0);
135
+ data.value.should.eql(['baz', 'bar', 'foo']);
136
+ });
137
+ it('should respond with 400 Bad Request if parameters missing', async function () {
138
+ const {
139
+ data,
140
+ status
141
+ } = await (0, _axios.default)({
142
+ url: `${baseUrl}/session/foo/url`,
143
+ method: 'POST',
144
+ data: {},
145
+ validateStatus: null
146
+ });
147
+ status.should.equal(400);
148
+ JSON.stringify(data).should.contain('url');
149
+ });
150
+ it('should reject requests with a badly formatted body and not crash', async function () {
151
+ await (0, _axios.default)({
152
+ url: `${baseUrl}/session/foo/url`,
153
+ method: 'POST',
154
+ data: 'oh hello'
155
+ }).should.eventually.be.rejected;
156
+ const {
157
+ data
158
+ } = await (0, _axios.default)({
159
+ url: `${baseUrl}/session/foo/url`,
160
+ method: 'POST',
161
+ data: {
162
+ url: 'http://google.com'
163
+ }
164
+ });
165
+ data.should.eql({
166
+ status: 0,
167
+ value: 'Navigated to: http://google.com',
168
+ sessionId: 'foo'
169
+ });
170
+ });
171
+ it('should get 404 for bad routes', async function () {
172
+ await (0, _axios.default)({
173
+ url: `${baseUrl}/blargimarg`
174
+ }).should.eventually.be.rejectedWith(/404/);
175
+ });
176
+ it('4xx responses should have content-type of application/json', async function () {
177
+ const {
178
+ headers
179
+ } = await (0, _axios.default)({
180
+ url: `${baseUrl}/blargimargarita`,
181
+ validateStatus: null
182
+ });
183
+ headers['content-type'].should.include('application/json');
184
+ });
185
+ it('should throw not yet implemented for unfilledout commands', async function () {
186
+ const {
187
+ status,
188
+ data
189
+ } = await (0, _axios.default)({
190
+ url: `${baseUrl}/session/foo/element/bar/location`,
191
+ validateStatus: null
192
+ });
193
+ status.should.equal(501);
194
+ data.should.eql({
195
+ status: 405,
196
+ value: {
197
+ message: 'Method has not yet been implemented'
198
+ },
199
+ sessionId: 'foo'
200
+ });
201
+ });
202
+ it('should throw not implemented for ignored commands', async function () {
203
+ const {
204
+ status,
205
+ data
206
+ } = await (0, _axios.default)({
207
+ url: `${baseUrl}/session/foo/buttonup`,
208
+ method: 'POST',
209
+ validateStatus: null,
210
+ data: {}
211
+ });
212
+ status.should.equal(501);
213
+ data.should.eql({
214
+ status: 405,
215
+ value: {
216
+ message: 'Method has not yet been implemented'
217
+ },
218
+ sessionId: 'foo'
219
+ });
220
+ });
221
+ it('should get 400 for bad parameters', async function () {
222
+ await (0, _axios.default)({
223
+ url: `${baseUrl}/session/foo/url`,
224
+ method: 'POST',
225
+ data: {}
226
+ }).should.eventually.be.rejectedWith(/400/);
227
+ });
228
+ it('should ignore special extra payload params in the right contexts', async function () {
229
+ await (0, _axios.default)({
230
+ url: `${baseUrl}/session/foo/element/bar/value`,
231
+ method: 'POST',
232
+ data: {
233
+ id: 'baz',
234
+ sessionId: 'lol',
235
+ value: ['a']
236
+ }
237
+ });
238
+ await (0, _axios.default)({
239
+ url: `${baseUrl}/session/foo/element/bar/value`,
240
+ method: 'POST',
241
+ data: {
242
+ id: 'baz'
243
+ }
244
+ }).should.eventually.be.rejectedWith(/400/);
245
+ await (0, _axios.default)({
246
+ url: `${baseUrl}/session/foo/frame`,
247
+ method: 'POST',
248
+ data: {
249
+ id: 'baz'
250
+ }
251
+ });
252
+ });
253
+ it('should return the correct error even if driver does not throw', async function () {
254
+ const {
255
+ status,
256
+ data
257
+ } = await (0, _axios.default)({
258
+ url: `${baseUrl}/session/foo/appium/receive_async_response`,
259
+ method: 'POST',
260
+ data: {
261
+ response: 'baz'
262
+ },
263
+ validateStatus: null
264
+ });
265
+ status.should.equal(500);
266
+ data.should.eql({
267
+ status: 13,
268
+ value: {
269
+ message: 'An unknown server-side error occurred while processing ' + 'the command. Original error: Mishandled Driver Error'
270
+ },
271
+ sessionId: 'foo'
272
+ });
273
+ });
274
+ describe('w3c sendkeys migration', function () {
275
+ it('should accept value for sendkeys', async function () {
276
+ const {
277
+ data
278
+ } = await (0, _axios.default)({
279
+ url: `${baseUrl}/session/foo/element/bar/value`,
280
+ method: 'POST',
281
+ data: {
282
+ value: 'text to type'
283
+ }
284
+ });
285
+ data.status.should.equal(0);
286
+ data.value.should.eql(['text to type', 'bar']);
287
+ });
288
+ it('should accept text for sendkeys', async function () {
289
+ const {
290
+ data
291
+ } = await (0, _axios.default)({
292
+ url: `${baseUrl}/session/foo/element/bar/value`,
293
+ method: 'POST',
294
+ data: {
295
+ text: 'text to type'
296
+ }
297
+ });
298
+ data.status.should.equal(0);
299
+ data.value.should.eql(['text to type', 'bar']);
300
+ });
301
+ it('should accept value and text for sendkeys, and use value', async function () {
302
+ const {
303
+ data
304
+ } = await (0, _axios.default)({
305
+ url: `${baseUrl}/session/foo/element/bar/value`,
306
+ method: 'POST',
307
+ data: {
308
+ value: 'text to type',
309
+ text: 'text to ignore'
310
+ }
311
+ });
312
+ data.status.should.equal(0);
313
+ data.value.should.eql(['text to type', 'bar']);
314
+ });
315
+ });
316
+ describe('multiple sets of arguments', function () {
317
+ describe('optional', function () {
318
+ it('should allow moveto with element', async function () {
319
+ const {
320
+ data
321
+ } = await (0, _axios.default)({
322
+ url: `${baseUrl}/session/foo/moveto`,
323
+ method: 'POST',
324
+ data: {
325
+ element: '3'
326
+ }
327
+ });
328
+ data.status.should.equal(0);
329
+ data.value.should.eql(['3', null, null]);
330
+ });
331
+ it('should allow moveto with xoffset/yoffset', async function () {
332
+ const {
333
+ data
334
+ } = await (0, _axios.default)({
335
+ url: `${baseUrl}/session/foo/moveto`,
336
+ method: 'POST',
337
+ data: {
338
+ xoffset: 42,
339
+ yoffset: 17
340
+ }
341
+ });
342
+ data.status.should.equal(0);
343
+ data.value.should.eql([null, 42, 17]);
344
+ });
345
+ });
346
+ describe('required', function () {
347
+ it('should allow removeApp with appId', async function () {
348
+ const {
349
+ data
350
+ } = await (0, _axios.default)({
351
+ url: `${baseUrl}/session/foo/appium/device/remove_app`,
352
+ method: 'POST',
353
+ data: {
354
+ appId: 42
355
+ }
356
+ });
357
+ data.status.should.equal(0);
358
+ data.value.should.eql(42);
359
+ });
360
+ it('should allow removeApp with bundleId', async function () {
361
+ const {
362
+ data
363
+ } = await (0, _axios.default)({
364
+ url: `${baseUrl}/session/foo/appium/device/remove_app`,
365
+ method: 'POST',
366
+ data: {
367
+ bundleId: 42
368
+ }
369
+ });
370
+ data.status.should.equal(0);
371
+ data.value.should.eql(42);
372
+ });
373
+ });
374
+ });
375
+ describe('default param wrap', function () {
376
+ it('should wrap', async function () {
377
+ const {
378
+ data
379
+ } = await (0, _axios.default)({
380
+ url: `${baseUrl}/session/foo/touch/perform`,
381
+ method: 'POST',
382
+ data: [{
383
+ 'action': 'tap',
384
+ 'options': {
385
+ 'element': '3'
386
+ }
387
+ }]
388
+ });
389
+ data.value.should.deep.equal([[{
390
+ 'action': 'tap',
391
+ 'options': {
392
+ 'element': '3'
393
+ }
394
+ }], 'foo']);
395
+ });
396
+ it('should not wrap twice', async function () {
397
+ const {
398
+ data
399
+ } = await (0, _axios.default)({
400
+ url: `${baseUrl}/session/foo/touch/perform`,
401
+ method: 'POST',
402
+ data: {
403
+ actions: [{
404
+ 'action': 'tap',
405
+ 'options': {
406
+ 'element': '3'
407
+ }
408
+ }]
409
+ }
410
+ });
411
+ data.value.should.deep.equal([[{
412
+ 'action': 'tap',
413
+ 'options': {
414
+ 'element': '3'
415
+ }
416
+ }], 'foo']);
417
+ });
418
+ });
419
+ describe('create sessions via HTTP endpoint', function () {
420
+ let sessionId;
421
+ beforeEach(function () {
422
+ sessionId = null;
423
+ });
424
+ afterEach(async function () {
425
+ if (sessionId) {
426
+ await _axios.default.delete(`${baseUrl}/session/${sessionId}`);
427
+ }
428
+ });
429
+ it('should not allow create session with desired caps (MJSONWP)', async function () {
430
+ const desiredCapabilities = {
431
+ a: 'b'
432
+ };
433
+ const {
434
+ data
435
+ } = await (0, _axios.default)({
436
+ url: `${baseUrl}/session`,
437
+ method: 'POST',
438
+ data: {
439
+ desiredCapabilities
440
+ }
441
+ });
442
+ should.equal(data.value, null);
443
+ });
444
+ it('should fail to create session without capabilities', async function () {
445
+ await (0, _axios.default)({
446
+ url: `${baseUrl}/session`,
447
+ method: 'POST',
448
+ data: {}
449
+ }).should.eventually.be.rejectedWith(/400/);
450
+ });
451
+ it('should allow create session with capabilities (W3C)', async function () {
452
+ const w3cCapabilities = {
453
+ 'appium:e': 'f'
454
+ };
455
+ const {
456
+ data
457
+ } = await (0, _axios.default)({
458
+ url: `${baseUrl}/session`,
459
+ method: 'POST',
460
+ data: {
461
+ capabilities: w3cCapabilities
462
+ }
463
+ });
464
+ sessionId = data.sessionId;
465
+ should.not.exist(data.status);
466
+ should.not.exist(data.sessionId);
467
+ data.value.capabilities.should.eql(w3cCapabilities);
468
+ data.value.sessionId.should.exist;
469
+ });
470
+ it('should raise an error if the driver does not support W3C yet', async function () {
471
+ const createSessionStub = _sinon.default.stub(driver, 'createSession').callsFake(function (capabilities) {
472
+ driver.sessionId = null;
473
+ return _lib.BaseDriver.prototype.createSession.call(driver, capabilities);
474
+ });
475
+
476
+ try {
477
+ await (0, _axios.default)({
478
+ url: `${baseUrl}/session`,
479
+ method: 'POST',
480
+ data: {
481
+ capabilities: {
482
+ alwaysMatch: {
483
+ platformName: 'Fake',
484
+ 'appium:deviceName': 'Fake'
485
+ },
486
+ firstMatch: [{}]
487
+ }
488
+ }
489
+ }).should.eventually.be.rejectedWith(/500/);
490
+ } finally {
491
+ createSessionStub.restore();
492
+ }
493
+ });
494
+ describe('w3c endpoints', function () {
495
+ let sessionUrl;
496
+ beforeEach(async function () {
497
+ const {
498
+ value
499
+ } = (await (0, _axios.default)({
500
+ url: `${baseUrl}/session`,
501
+ method: 'POST',
502
+ data: {
503
+ capabilities: {
504
+ alwaysMatch: {
505
+ platformName: 'Fake',
506
+ 'appium:deviceName': 'Commodore 64'
507
+ },
508
+ firstMatch: [{}]
509
+ }
510
+ }
511
+ })).data;
512
+ sessionId = value.sessionId;
513
+ sessionUrl = `${baseUrl}/session/${sessionId}`;
514
+ });
515
+ it(`should throw 400 Bad Parameters exception if the parameters are bad`, async function () {
516
+ const {
517
+ status,
518
+ data
519
+ } = await (0, _axios.default)({
520
+ url: `${sessionUrl}/actions`,
521
+ method: 'POST',
522
+ validateStatus: null,
523
+ data: {
524
+ bad: 'params'
525
+ }
526
+ });
527
+ status.should.equal(400);
528
+ const {
529
+ error: w3cError,
530
+ message,
531
+ stacktrace
532
+ } = data.value;
533
+ message.should.match(/Parameters were incorrect/);
534
+ stacktrace.should.match(/protocol.js/);
535
+ w3cError.should.be.a.string;
536
+ w3cError.should.equal(_lib.errors.InvalidArgumentError.error());
537
+ });
538
+ it(`should throw 405 exception if the command hasn't been implemented yet`, async function () {
539
+ const {
540
+ status,
541
+ data
542
+ } = await (0, _axios.default)({
543
+ url: `${sessionUrl}/actions`,
544
+ method: 'POST',
545
+ validateStatus: null,
546
+ data: {
547
+ actions: []
548
+ }
549
+ });
550
+ status.should.equal(405);
551
+ const {
552
+ error: w3cError,
553
+ message,
554
+ stacktrace
555
+ } = data.value;
556
+ message.should.match(/Method has not yet been implemented/);
557
+ stacktrace.should.match(/protocol.js/);
558
+ w3cError.should.be.a.string;
559
+ w3cError.should.equal(_lib.errors.NotYetImplementedError.error());
560
+ message.should.match(/Method has not yet been implemented/);
561
+ });
562
+ it(`should throw 500 Unknown Error if the command throws an unexpected exception`, async function () {
563
+ driver.performActions = () => {
564
+ throw new Error(`Didn't work`);
565
+ };
566
+
567
+ const {
568
+ status,
569
+ data
570
+ } = await (0, _axios.default)({
571
+ url: `${sessionUrl}/actions`,
572
+ method: 'POST',
573
+ validateStatus: null,
574
+ data: {
575
+ actions: []
576
+ }
577
+ });
578
+ status.should.equal(500);
579
+ const {
580
+ error: w3cError,
581
+ message,
582
+ stacktrace
583
+ } = data.value;
584
+ stacktrace.should.match(/protocol.js/);
585
+ w3cError.should.be.a.string;
586
+ w3cError.should.equal(_lib.errors.UnknownError.error());
587
+ message.should.match(/Didn't work/);
588
+ delete driver.performActions;
589
+ });
590
+ it(`should translate element format from MJSONWP to W3C`, async function () {
591
+ const retValue = [{
592
+ something: {
593
+ [_constants.MJSONWP_ELEMENT_KEY]: 'fooo',
594
+ other: 'bar'
595
+ }
596
+ }, {
597
+ [_constants.MJSONWP_ELEMENT_KEY]: 'bar'
598
+ }, 'ignore'];
599
+ const expectedValue = [{
600
+ something: {
601
+ [_constants.MJSONWP_ELEMENT_KEY]: 'fooo',
602
+ [_constants.W3C_ELEMENT_KEY]: 'fooo',
603
+ other: 'bar'
604
+ }
605
+ }, {
606
+ [_constants.MJSONWP_ELEMENT_KEY]: 'bar',
607
+ [_constants.W3C_ELEMENT_KEY]: 'bar'
608
+ }, 'ignore'];
609
+ const findElementsBackup = driver.findElements;
610
+
611
+ driver.findElements = () => retValue;
612
+
613
+ const {
614
+ data
615
+ } = await _axios.default.post(`${sessionUrl}/elements`, {
616
+ using: 'whatever',
617
+ value: 'whatever'
618
+ });
619
+ data.value.should.eql(expectedValue);
620
+ driver.findElements = findElementsBackup;
621
+ });
622
+ it(`should fail with a 408 error if it throws a TimeoutError exception`, async function () {
623
+ let setUrlStub = _sinon.default.stub(driver, 'setUrl').callsFake(function () {
624
+ throw new _lib.errors.TimeoutError();
625
+ });
626
+
627
+ const {
628
+ status,
629
+ data
630
+ } = await (0, _axios.default)({
631
+ url: `${sessionUrl}/url`,
632
+ method: 'POST',
633
+ validateStatus: null,
634
+ data: {
635
+ url: 'https://example.com/'
636
+ }
637
+ });
638
+ status.should.equal(408);
639
+ const {
640
+ error: w3cError,
641
+ message,
642
+ stacktrace
643
+ } = data.value;
644
+ stacktrace.should.match(/protocol.js/);
645
+ w3cError.should.be.a.string;
646
+ w3cError.should.equal(_lib.errors.TimeoutError.error());
647
+ message.should.match(/An operation did not complete before its timeout expired/);
648
+ setUrlStub.restore();
649
+ });
650
+ it(`should pass with 200 HTTP status code if the command returns a value`, async function () {
651
+ driver.performActions = actions => 'It works ' + actions.join('');
652
+
653
+ const {
654
+ status,
655
+ value,
656
+ sessionId
657
+ } = (await _axios.default.post(`${sessionUrl}/actions`, {
658
+ actions: ['a', 'b', 'c']
659
+ })).data;
660
+ should.not.exist(sessionId);
661
+ should.not.exist(status);
662
+ value.should.equal('It works abc');
663
+ delete driver.performActions;
664
+ });
665
+ describe('jwproxy', function () {
666
+ let port;
667
+ let server, jwproxy, app;
668
+ before(async function () {
669
+ port = await (0, _helpers2.getTestPort)(true);
670
+ });
671
+ beforeEach(function () {
672
+ const res = (0, _helpers.createProxyServer)(sessionId, port);
673
+ server = res.server;
674
+ app = res.app;
675
+ jwproxy = new _lib.JWProxy({
676
+ host: _helpers2.TEST_HOST,
677
+ port
678
+ });
679
+ jwproxy.sessionId = sessionId;
680
+
681
+ driver.performActions = async actions => await jwproxy.command('/perform-actions', 'POST', actions);
682
+ });
683
+ afterEach(async function () {
684
+ delete driver.performActions;
685
+ await server.close();
686
+ });
687
+ it('should work if a proxied request returns a response with status 200', async function () {
688
+ app.post('/session/:sessionId/perform-actions', (req, res) => {
689
+ res.json({
690
+ sessionId: req.params.sessionId,
691
+ value: req.body,
692
+ status: 0
693
+ });
694
+ });
695
+ const {
696
+ status,
697
+ value,
698
+ sessionId
699
+ } = (await _axios.default.post(`${sessionUrl}/actions`, {
700
+ actions: [1, 2, 3]
701
+ })).data;
702
+ value.should.eql([1, 2, 3]);
703
+ should.not.exist(status);
704
+ should.not.exist(sessionId);
705
+ });
706
+ it('should return error if a proxied request returns a MJSONWP error response', async function () {
707
+ app.post('/session/:sessionId/perform-actions', (req, res) => {
708
+ res.status(500).json({
709
+ sessionId,
710
+ status: 6,
711
+ value: 'A problem occurred'
712
+ });
713
+ });
714
+ const {
715
+ status,
716
+ data
717
+ } = await (0, _axios.default)({
718
+ url: `${sessionUrl}/actions`,
719
+ method: 'POST',
720
+ validateStatus: null,
721
+ data: {
722
+ actions: [1, 2, 3]
723
+ }
724
+ });
725
+ status.should.equal(_httpStatusCodes.StatusCodes.NOT_FOUND);
726
+ JSON.stringify(data).should.match(/A problem occurred/);
727
+ });
728
+ it('should return W3C error if a proxied request returns a W3C error response', async function () {
729
+ const error = new Error(`Some error occurred`);
730
+ error.w3cStatus = 414;
731
+
732
+ const executeCommandStub = _sinon.default.stub(driver, 'executeCommand').returns({
733
+ protocol: 'W3C',
734
+ error
735
+ });
736
+
737
+ const {
738
+ status,
739
+ data
740
+ } = await (0, _axios.default)({
741
+ url: `${sessionUrl}/actions`,
742
+ method: 'POST',
743
+ validateStatus: null,
744
+ data: {
745
+ actions: [1, 2, 3]
746
+ }
747
+ });
748
+ status.should.equal(414);
749
+ const {
750
+ error: w3cError,
751
+ message: errMessage,
752
+ stacktrace
753
+ } = data.value;
754
+ w3cError.should.equal('unknown error');
755
+ stacktrace.should.match(/Some error occurred/);
756
+ errMessage.should.equal('Some error occurred');
757
+ executeCommandStub.restore();
758
+ });
759
+ it('should return error if a proxied request returns a MJSONWP error response but HTTP status code is 200', async function () {
760
+ app.post('/session/:sessionId/perform-actions', (req, res) => {
761
+ res.status(200).json({
762
+ sessionId: 'Fake Session Id',
763
+ status: 7,
764
+ value: 'A problem occurred'
765
+ });
766
+ });
767
+ const {
768
+ status,
769
+ data
770
+ } = await (0, _axios.default)({
771
+ url: `${sessionUrl}/actions`,
772
+ method: 'POST',
773
+ validateStatus: null,
774
+ data: {
775
+ actions: [1, 2, 3]
776
+ }
777
+ });
778
+ status.should.equal(_httpStatusCodes.StatusCodes.NOT_FOUND);
779
+ const {
780
+ error: w3cError,
781
+ message: errMessage,
782
+ stacktrace
783
+ } = data.value;
784
+ w3cError.should.equal('no such element');
785
+ errMessage.should.match(/A problem occurred/);
786
+ stacktrace.should.exist;
787
+ });
788
+ it('should return error if a proxied request returns a W3C error response', async function () {
789
+ app.post('/session/:sessionId/perform-actions', (req, res) => {
790
+ res.status(404).json({
791
+ value: {
792
+ error: 'no such element',
793
+ message: 'does not make a difference',
794
+ stacktrace: 'arbitrary stacktrace'
795
+ }
796
+ });
797
+ });
798
+ const {
799
+ status,
800
+ data
801
+ } = await (0, _axios.default)({
802
+ url: `${sessionUrl}/actions`,
803
+ method: 'POST',
804
+ validateStatus: null,
805
+ data: {
806
+ actions: [1, 2, 3]
807
+ }
808
+ });
809
+ status.should.equal(_httpStatusCodes.StatusCodes.NOT_FOUND);
810
+ const {
811
+ error: w3cError,
812
+ stacktrace
813
+ } = data.value;
814
+ w3cError.should.equal('no such element');
815
+ stacktrace.should.match(/arbitrary stacktrace/);
816
+ });
817
+ it('should return an error if a proxied request returns a W3C error response', async function () {
818
+ app.post('/session/:sessionId/perform-actions', (req, res) => {
819
+ res.set('Connection', 'close');
820
+ res.status(444).json({
821
+ value: {
822
+ error: 'bogus error code',
823
+ message: 'does not make a difference',
824
+ stacktrace: 'arbitrary stacktrace'
825
+ }
826
+ });
827
+ });
828
+ const {
829
+ status,
830
+ data
831
+ } = await (0, _axios.default)({
832
+ url: `${sessionUrl}/actions`,
833
+ method: 'POST',
834
+ validateStatus: null,
835
+ data: {
836
+ actions: [1, 2, 3]
837
+ }
838
+ });
839
+ status.should.equal(_httpStatusCodes.StatusCodes.INTERNAL_SERVER_ERROR);
840
+ const {
841
+ error: w3cError,
842
+ stacktrace
843
+ } = data.value;
844
+ w3cError.should.equal('unknown error');
845
+ stacktrace.should.match(/arbitrary stacktrace/);
846
+ });
847
+ });
848
+ });
849
+ });
850
+ it('should handle commands with no response values', async function () {
851
+ const {
852
+ data
853
+ } = await (0, _axios.default)({
854
+ url: `${baseUrl}/session/foo/forward`,
855
+ method: 'POST'
856
+ });
857
+ data.should.eql({
858
+ status: 0,
859
+ value: null,
860
+ sessionId: 'foo'
861
+ });
862
+ });
863
+ it('should allow empty string response values', async function () {
864
+ const {
865
+ data
866
+ } = await (0, _axios.default)({
867
+ url: `${baseUrl}/session/foo/element/bar/text`
868
+ });
869
+ data.should.eql({
870
+ status: 0,
871
+ value: '',
872
+ sessionId: 'foo'
873
+ });
874
+ });
875
+ it('should send 500 response and an Unknown object for rejected commands', async function () {
876
+ const {
877
+ status,
878
+ data
879
+ } = await (0, _axios.default)({
880
+ url: `${baseUrl}/session/foo/refresh`,
881
+ method: 'POST',
882
+ validateStatus: null
883
+ });
884
+ status.should.equal(500);
885
+ data.should.eql({
886
+ status: 13,
887
+ value: {
888
+ message: 'An unknown server-side error occurred while processing ' + 'the command. Original error: Too Fresh!'
889
+ },
890
+ sessionId: 'foo'
891
+ });
892
+ });
893
+ it('should not throw UnknownError when known', async function () {
894
+ const {
895
+ status,
896
+ data
897
+ } = await (0, _axios.default)({
898
+ url: `${baseUrl}/session/foo`,
899
+ validateStatus: null
900
+ });
901
+ status.should.equal(404);
902
+ data.should.eql({
903
+ status: 6,
904
+ value: {
905
+ message: 'A session is either terminated or not started'
906
+ },
907
+ sessionId: 'foo'
908
+ });
909
+ });
910
+ });
911
+ describe('session Ids', function () {
912
+ let driver = new _fakeDriver.FakeDriver();
913
+ let mjsonwpServer;
914
+ before(async function () {
915
+ mjsonwpServer = await (0, _lib.server)({
916
+ routeConfiguringFunction: (0, _lib.routeConfiguringFunction)(driver),
917
+ port
918
+ });
919
+ });
920
+ after(async function () {
921
+ await mjsonwpServer.close();
922
+ });
923
+ afterEach(function () {
924
+ driver.sessionId = null;
925
+ });
926
+ it('should return null SessionId for commands without sessionIds', async function () {
927
+ const {
928
+ data
929
+ } = await (0, _axios.default)({
930
+ url: `${baseUrl}/status`
931
+ });
932
+ should.equal(data.sessionId, null);
933
+ });
934
+ it('responds with the same session ID in the request', async function () {
935
+ let sessionId = 'Vader Sessions';
936
+ driver.sessionId = sessionId;
937
+ const {
938
+ data
939
+ } = await (0, _axios.default)({
940
+ url: `${baseUrl}/session/${sessionId}/url`,
941
+ method: 'POST',
942
+ data: {
943
+ url: 'http://google.com'
944
+ }
945
+ });
946
+ should.exist(data.sessionId);
947
+ data.sessionId.should.eql(sessionId);
948
+ });
949
+ it('yells if no session exists', async function () {
950
+ let sessionId = 'Vader Sessions';
951
+ const {
952
+ data,
953
+ status
954
+ } = await (0, _axios.default)({
955
+ url: `${baseUrl}/session/${sessionId}/url`,
956
+ method: 'POST',
957
+ validateStatus: null,
958
+ data: {
959
+ url: 'http://google.com'
960
+ }
961
+ });
962
+ status.should.equal(404);
963
+ data.status.should.equal(6);
964
+ data.value.message.should.contain('session');
965
+ });
966
+ it('yells if invalid session is sent', async function () {
967
+ let sessionId = 'Vader Sessions';
968
+ driver.sessionId = 'recession';
969
+ const {
970
+ data,
971
+ status
972
+ } = await (0, _axios.default)({
973
+ url: `${baseUrl}/session/${sessionId}/url`,
974
+ method: 'POST',
975
+ validateStatus: null,
976
+ data: {
977
+ url: 'http://google.com'
978
+ }
979
+ });
980
+ status.should.equal(404);
981
+ data.status.should.equal(6);
982
+ data.value.message.should.contain('session');
983
+ });
984
+ it('should have session IDs in error responses', async function () {
985
+ let sessionId = 'Vader Sessions';
986
+ driver.sessionId = sessionId;
987
+ const {
988
+ data,
989
+ status
990
+ } = await (0, _axios.default)({
991
+ url: `${baseUrl}/session/${sessionId}/refresh`,
992
+ method: 'POST',
993
+ validateStatus: null
994
+ });
995
+ status.should.equal(500);
996
+ data.should.eql({
997
+ status: 13,
998
+ value: {
999
+ message: 'An unknown server-side error occurred while processing ' + 'the command. Original error: Too Fresh!'
1000
+ },
1001
+ sessionId
1002
+ });
1003
+ });
1004
+ it('should return a new session ID on create', async function () {
1005
+ const {
1006
+ data
1007
+ } = await (0, _axios.default)({
1008
+ url: `${baseUrl}/session`,
1009
+ method: 'POST',
1010
+ data: {
1011
+ capabilities: {
1012
+ alwaysMatch: {
1013
+ 'appium:greeting': 'hello'
1014
+ },
1015
+ firstMatch: [{}]
1016
+ }
1017
+ }
1018
+ });
1019
+ should.exist(data.value.sessionId);
1020
+ data.value.sessionId.indexOf('fakeSession_').should.equal(0);
1021
+ data.value.capabilities.should.eql({
1022
+ alwaysMatch: {
1023
+ 'appium:greeting': 'hello'
1024
+ },
1025
+ firstMatch: [{}]
1026
+ });
1027
+ });
1028
+ });
1029
+ describe('via drivers jsonwp proxy', function () {
1030
+ let driver;
1031
+ let sessionId = 'foo';
1032
+ let mjsonwpServer;
1033
+ beforeEach(async function () {
1034
+ driver = new _fakeDriver.FakeDriver();
1035
+ driver.sessionId = sessionId;
1036
+
1037
+ driver.proxyActive = () => true;
1038
+
1039
+ driver.canProxy = () => true;
1040
+
1041
+ mjsonwpServer = await (0, _lib.server)({
1042
+ routeConfiguringFunction: (0, _lib.routeConfiguringFunction)(driver),
1043
+ port,
1044
+ extraMethodMap: _fakeDriver.FakeDriver.newMethodMap
1045
+ });
1046
+ });
1047
+ afterEach(async function () {
1048
+ await mjsonwpServer.close();
1049
+ });
1050
+ it('should give a nice error if proxying is set but no proxy function exists', async function () {
1051
+ driver.canProxy = () => false;
1052
+
1053
+ const {
1054
+ status,
1055
+ data
1056
+ } = await (0, _axios.default)({
1057
+ url: `${baseUrl}/session/${sessionId}/url`,
1058
+ method: 'POST',
1059
+ validateStatus: null,
1060
+ data: {
1061
+ url: 'http://google.com'
1062
+ }
1063
+ });
1064
+ status.should.equal(500);
1065
+ data.should.eql({
1066
+ status: 13,
1067
+ value: {
1068
+ message: 'An unknown server-side error occurred while processing ' + 'the command. Original error: Trying to proxy to a JSONWP ' + 'server but driver is unable to proxy'
1069
+ },
1070
+ sessionId
1071
+ });
1072
+ });
1073
+ it('should pass on any errors in proxying', async function () {
1074
+ driver.proxyReqRes = async function () {
1075
+ throw new Error('foo');
1076
+ };
1077
+
1078
+ const {
1079
+ status,
1080
+ data
1081
+ } = await (0, _axios.default)({
1082
+ url: `${baseUrl}/session/${sessionId}/url`,
1083
+ method: 'POST',
1084
+ validateStatus: null,
1085
+ data: {
1086
+ url: 'http://google.com'
1087
+ }
1088
+ });
1089
+ status.should.equal(500);
1090
+ data.should.eql({
1091
+ status: 13,
1092
+ value: {
1093
+ message: 'An unknown server-side error occurred while processing ' + 'the command. Original error: Could not proxy. Proxy ' + 'error: foo'
1094
+ },
1095
+ sessionId
1096
+ });
1097
+ });
1098
+ it('should able to throw ProxyRequestError in proxying', async function () {
1099
+ driver.proxyReqRes = async function () {
1100
+ let jsonwp = {
1101
+ status: 35,
1102
+ value: 'No such context found.',
1103
+ sessionId: 'foo'
1104
+ };
1105
+ throw new _lib.errors.ProxyRequestError(`Could not proxy command to remote server. `, jsonwp);
1106
+ };
1107
+
1108
+ const {
1109
+ status,
1110
+ data
1111
+ } = await (0, _axios.default)({
1112
+ url: `${baseUrl}/session/${sessionId}/url`,
1113
+ method: 'POST',
1114
+ validateStatus: null,
1115
+ data: {
1116
+ url: 'http://google.com'
1117
+ }
1118
+ });
1119
+ status.should.equal(500);
1120
+ data.should.eql({
1121
+ status: 35,
1122
+ value: {
1123
+ message: 'No such context found.'
1124
+ },
1125
+ sessionId: 'foo'
1126
+ });
1127
+ });
1128
+ it('should let the proxy handle req/res', async function () {
1129
+ driver.proxyReqRes = async function (req, res) {
1130
+ res.status(200).json({
1131
+ custom: 'data'
1132
+ });
1133
+ };
1134
+
1135
+ const {
1136
+ status,
1137
+ data
1138
+ } = await (0, _axios.default)({
1139
+ url: `${baseUrl}/session/${sessionId}/url`,
1140
+ method: 'POST',
1141
+ data: {
1142
+ url: 'http://google.com'
1143
+ }
1144
+ });
1145
+ status.should.equal(200);
1146
+ data.should.eql({
1147
+ custom: 'data'
1148
+ });
1149
+ });
1150
+ it('should avoid jsonwp proxying when path matches avoidance list', async function () {
1151
+ driver.getProxyAvoidList = () => [['POST', new RegExp('^/session/[^/]+/url$')]];
1152
+
1153
+ const {
1154
+ status,
1155
+ data
1156
+ } = await (0, _axios.default)({
1157
+ url: `${baseUrl}/session/${sessionId}/url`,
1158
+ method: 'POST',
1159
+ data: {
1160
+ url: 'http://google.com'
1161
+ }
1162
+ });
1163
+ status.should.equal(200);
1164
+ data.should.eql({
1165
+ status: 0,
1166
+ value: 'Navigated to: http://google.com',
1167
+ sessionId
1168
+ });
1169
+ });
1170
+ it('should fail if avoid proxy list is malformed in some way', async function () {
1171
+ async function badProxyAvoidanceList(list) {
1172
+ driver.getProxyAvoidList = () => list;
1173
+
1174
+ const {
1175
+ status,
1176
+ data
1177
+ } = await (0, _axios.default)({
1178
+ url: `${baseUrl}/session/${sessionId}/url`,
1179
+ method: 'POST',
1180
+ validateStatus: null,
1181
+ data: {
1182
+ url: 'http://google.com'
1183
+ }
1184
+ });
1185
+ status.should.equal(500);
1186
+ data.status.should.equal(13);
1187
+ data.value.message.should.contain('roxy');
1188
+ }
1189
+
1190
+ const lists = ['foo', [['foo']], [['BAR', /lol/]], [['GET', 'foo']]];
1191
+
1192
+ for (let list of lists) {
1193
+ await badProxyAvoidanceList(list);
1194
+ }
1195
+ });
1196
+ it('should avoid proxying non-session commands even if not in the list', async function () {
1197
+ driver.getProxyAvoidList = () => [['POST', new RegExp('')]];
1198
+
1199
+ const {
1200
+ status,
1201
+ data
1202
+ } = await (0, _axios.default)({
1203
+ url: `${baseUrl}/status`
1204
+ });
1205
+ status.should.equal(200);
1206
+ data.should.eql({
1207
+ status: 0,
1208
+ value: "I'm fine",
1209
+ sessionId: null
1210
+ });
1211
+ });
1212
+ it('should avoid proxying deleteSession commands', async function () {
1213
+ driver.getProxyAvoidList = () => [['POST', new RegExp('')]];
1214
+
1215
+ driver.sessionId.should.equal(sessionId);
1216
+ const {
1217
+ status
1218
+ } = await _axios.default.delete(`${baseUrl}/session/${sessionId}`);
1219
+ status.should.equal(200);
1220
+ should.not.exist(driver.sessionId);
1221
+ driver.jwpProxyActive.should.be.false;
1222
+ });
1223
+ it('should avoid proxying when command spec specifies neverProxy', async function () {
1224
+ const {
1225
+ status,
1226
+ data
1227
+ } = await (0, _axios.default)({
1228
+ url: `${baseUrl}/session/${sessionId}/noproxy`,
1229
+ method: 'GET'
1230
+ });
1231
+ status.should.equal(200);
1232
+ data.should.eql({
1233
+ status: 0,
1234
+ value: 'This was not proxied',
1235
+ sessionId
1236
+ });
1237
+ });
1238
+ });
1239
+ });require('source-map-support').install();
1240
+
1241
+
1242
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvcHJvdG9jb2wvcHJvdG9jb2wtZTJlLXNwZWNzLmpzIl0sIm5hbWVzIjpbInBvcnQiLCJiYXNlVXJsIiwiZGVzY3JpYmUiLCJiZWZvcmUiLCJURVNUX0hPU1QiLCJkIiwiRmFrZURyaXZlciIsIml0Iiwic2V0VXJsIiwic2hvdWxkIiwiY29udGFpbiIsIm1qc29ud3BTZXJ2ZXIiLCJkcml2ZXIiLCJzZXNzaW9uSWQiLCJyb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24iLCJhZnRlciIsImNsb3NlIiwiZGF0YSIsInVybCIsIm1ldGhvZCIsImVxbCIsInN0YXR1cyIsInZhbHVlIiwiaGVhZGVycyIsInFzIiwic3RyaW5naWZ5IiwiZXF1YWwiLCJ2YWxpZGF0ZVN0YXR1cyIsIkpTT04iLCJldmVudHVhbGx5IiwiYmUiLCJyZWplY3RlZCIsInJlamVjdGVkV2l0aCIsImluY2x1ZGUiLCJtZXNzYWdlIiwiaWQiLCJyZXNwb25zZSIsInRleHQiLCJlbGVtZW50IiwieG9mZnNldCIsInlvZmZzZXQiLCJhcHBJZCIsImJ1bmRsZUlkIiwiZGVlcCIsImFjdGlvbnMiLCJiZWZvcmVFYWNoIiwiYWZ0ZXJFYWNoIiwiYXhpb3MiLCJkZWxldGUiLCJkZXNpcmVkQ2FwYWJpbGl0aWVzIiwiYSIsInczY0NhcGFiaWxpdGllcyIsImNhcGFiaWxpdGllcyIsIm5vdCIsImV4aXN0IiwiY3JlYXRlU2Vzc2lvblN0dWIiLCJzaW5vbiIsInN0dWIiLCJjYWxsc0Zha2UiLCJCYXNlRHJpdmVyIiwicHJvdG90eXBlIiwiY3JlYXRlU2Vzc2lvbiIsImNhbGwiLCJhbHdheXNNYXRjaCIsInBsYXRmb3JtTmFtZSIsImZpcnN0TWF0Y2giLCJyZXN0b3JlIiwic2Vzc2lvblVybCIsImJhZCIsImVycm9yIiwidzNjRXJyb3IiLCJzdGFja3RyYWNlIiwibWF0Y2giLCJzdHJpbmciLCJlcnJvcnMiLCJJbnZhbGlkQXJndW1lbnRFcnJvciIsIk5vdFlldEltcGxlbWVudGVkRXJyb3IiLCJwZXJmb3JtQWN0aW9ucyIsIkVycm9yIiwiVW5rbm93bkVycm9yIiwicmV0VmFsdWUiLCJzb21ldGhpbmciLCJNSlNPTldQX0VMRU1FTlRfS0VZIiwib3RoZXIiLCJleHBlY3RlZFZhbHVlIiwiVzNDX0VMRU1FTlRfS0VZIiwiZmluZEVsZW1lbnRzQmFja3VwIiwiZmluZEVsZW1lbnRzIiwicG9zdCIsInVzaW5nIiwic2V0VXJsU3R1YiIsIlRpbWVvdXRFcnJvciIsImpvaW4iLCJzZXJ2ZXIiLCJqd3Byb3h5IiwiYXBwIiwicmVzIiwiSldQcm94eSIsImhvc3QiLCJjb21tYW5kIiwicmVxIiwianNvbiIsInBhcmFtcyIsImJvZHkiLCJIVFRQU3RhdHVzQ29kZXMiLCJOT1RfRk9VTkQiLCJ3M2NTdGF0dXMiLCJleGVjdXRlQ29tbWFuZFN0dWIiLCJyZXR1cm5zIiwicHJvdG9jb2wiLCJlcnJNZXNzYWdlIiwic2V0IiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiaW5kZXhPZiIsInByb3h5QWN0aXZlIiwiY2FuUHJveHkiLCJleHRyYU1ldGhvZE1hcCIsIm5ld01ldGhvZE1hcCIsInByb3h5UmVxUmVzIiwianNvbndwIiwiUHJveHlSZXF1ZXN0RXJyb3IiLCJjdXN0b20iLCJnZXRQcm94eUF2b2lkTGlzdCIsIlJlZ0V4cCIsImJhZFByb3h5QXZvaWRhbmNlTGlzdCIsImxpc3QiLCJsaXN0cyIsImp3cFByb3h5QWN0aXZlIiwiZmFsc2UiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUdBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUdBOztBQUNBOztBQUVBLElBQUlBLElBQUo7QUFDQSxJQUFJQyxPQUFKO0FBRUFDLFFBQVEsQ0FBQyxVQUFELEVBQWEsWUFBWTtBQUUvQkMsRUFBQUEsTUFBTSxDQUFDLGtCQUFrQjtBQUN2QkgsSUFBQUEsSUFBSSxHQUFHLE1BQU0sNEJBQWI7QUFDQUMsSUFBQUEsT0FBTyxHQUFJLFVBQVNHLG1CQUFVLElBQUdKLElBQUssRUFBdEM7QUFDRCxHQUhLLENBQU47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Q0FBQ1osTUFBUCxDQUFjaUIsS0FBZCxDQUFvQixHQUFwQjtBQUNBakIsTUFBQUEsTUFBTSxDQUFDNEMsR0FBUCxDQUFXQyxLQUFYLENBQWlCMUMsTUFBTSxDQUFDQyxTQUF4QjtBQUNBRCxNQUFBQSxNQUFNLENBQUNtSCxjQUFQLENBQXNCdEgsTUFBdEIsQ0FBNkJxQixFQUE3QixDQUFnQ2tHLEtBQWhDO0FBQ0QsS0FUQyxDQUFGO0FBV0F6SCxJQUFBQSxFQUFFLENBQUMsOERBQUQsRUFBaUUsa0JBQWtCO0FBQ25GLFlBQU07QUFBQ2MsUUFBQUEsTUFBRDtBQUFTSixRQUFBQTtBQUFULFVBQWlCLE1BQU0sb0JBQU07QUFDakNDLFFBQUFBLEdBQUcsRUFBRyxHQUFFakIsT0FBUSxZQUFXWSxTQUFVLFVBREo7QUFFakNNLFFBQUFBLE1BQU0sRUFBRTtBQUZ5QixPQUFOLENBQTdCO0FBS0FFLE1BQUFBLE1BQU0sQ0FBQ1osTUFBUCxDQUFjaUIsS0FBZCxDQUFvQixHQUFwQjtBQUNBVCxNQUFBQSxJQUFJLENBQUNSLE1BQUwsQ0FBWVcsR0FBWixDQUFnQjtBQUNkQyxRQUFBQSxNQUFNLEVBQUUsQ0FETTtBQUVkQyxRQUFBQSxLQUFLLEVBQUUsc0JBRk87QUFHZFQsUUFBQUE7QUFIYyxPQUFoQjtBQUtELEtBWkMsQ0FBRjtBQWNELEdBdkxPLENBQVI7QUF3TEQsQ0E3aENPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bW9jaGFcblxuaW1wb3J0IHtcbiAgc2VydmVyLCByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24sIGVycm9ycywgSldQcm94eSwgQmFzZURyaXZlclxufSBmcm9tICcuLi8uLi9saWInO1xuaW1wb3J0IHsgRmFrZURyaXZlciB9IGZyb20gJy4vZmFrZS1kcml2ZXInO1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBTdGF0dXNDb2RlcyBhcyBIVFRQU3RhdHVzQ29kZXMgfSBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XG5pbXBvcnQgeyBjcmVhdGVQcm94eVNlcnZlciB9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQge1xuICBNSlNPTldQX0VMRU1FTlRfS0VZLCBXM0NfRUxFTUVOVF9LRVlcbn0gZnJvbSAnLi4vLi4vbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgcXMgZnJvbSAncXVlcnlzdHJpbmcnO1xuaW1wb3J0IHtURVNUX0hPU1QsIGdldFRlc3RQb3J0fSBmcm9tICcuLi9oZWxwZXJzJztcblxubGV0IHBvcnQ7XG5sZXQgYmFzZVVybDtcblxuZGVzY3JpYmUoJ1Byb3RvY29sJywgZnVuY3Rpb24gKCkge1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydCA9IGF3YWl0IGdldFRlc3RQb3J0KCk7XG4gICAgYmFzZVVybCA9IGBodHRwOi8vJHtURVNUX0hPU1R9OiR7cG9ydH1gO1xuICB9KTtcblxuICAvL1RPRE86IG1vcmUgdGVzdHMhOlxuICAvLyBVbmtub3duIGNvbW1hbmRzIHNob3VsZCByZXR1cm4gNDA0XG5cbiAgZGVzY3JpYmUoJ2RpcmVjdCB0byBkcml2ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGQgPSBuZXcgRmFrZURyaXZlcigpO1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHJlc3BvbnNlIHZhbHVlcyBkaXJlY3RseSBmcm9tIHRoZSBkcml2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAoYXdhaXQgZC5zZXRVcmwoJ2h0dHA6Ly9nb29nbGUuY29tJykpLnNob3VsZC5jb250YWluKCdnb29nbGUnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZpYSBleHByZXNzIHJvdXRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgbWpzb253cFNlcnZlcjtcbiAgICBsZXQgZHJpdmVyO1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRyaXZlciA9IG5ldyBGYWtlRHJpdmVyKCk7XG4gICAgICBkcml2ZXIuc2Vzc2lvbklkID0gJ2Zvbyc7XG4gICAgICBtanNvbndwU2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgICAgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uOiByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24oZHJpdmVyKSxcbiAgICAgICAgcG9ydCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgbWpzb253cFNlcnZlci5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm94eSB0byBkcml2ZXIgYW5kIHJldHVybiB2YWxpZCBqc29ud3AgcmVzcG9uc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vdXJsYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGRhdGE6IHt1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbSd9XG4gICAgICB9KTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMCxcbiAgICAgICAgdmFsdWU6ICdOYXZpZ2F0ZWQgdG86IGh0dHA6Ly9nb29nbGUuY29tJyxcbiAgICAgICAgc2Vzc2lvbklkOiAnZm9vJ1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFzc3VtZSByZXF1ZXN0cyB3aXRob3V0IGEgQ29udGVudC1UeXBlIGFyZSBqc29uIHJlcXVlc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL3VybGAsXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBkYXRhOiB7dXJsOiAnaHR0cDovL2dvb2dsZS5jb20nfSxcbiAgICAgIH0pO1xuICAgICAgZGF0YS5zaG91bGQuZXFsKHtcbiAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICB2YWx1ZTogJ05hdmlnYXRlZCB0bzogaHR0cDovL2dvb2dsZS5jb20nLFxuICAgICAgICBzZXNzaW9uSWQ6ICdmb28nXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVzcG9uZCB0byB4LXd3dy1mb3JtLXVybGVuY29kZWQgYXMgd2VsbCBhcyBqc29uIHJlcXVlc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL3VybGAsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICAgIH0sXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBkYXRhOiBxcy5zdHJpbmdpZnkoe1xuICAgICAgICAgIHVybDogJ2h0dHA6Ly9nb29nbGUuY29tJyxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMCxcbiAgICAgICAgdmFsdWU6ICdOYXZpZ2F0ZWQgdG86IGh0dHA6Ly9nb29nbGUuY29tJyxcbiAgICAgICAgc2Vzc2lvbklkOiAnZm9vJ1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGluY2x1ZGUgdXJsIHJlcXVlc3QgcGFyYW1ldGVycyBmb3IgbWV0aG9kcyB0byB1c2UgLSBzZXNzaW9uaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vYmFja2AsXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBkYXRhOiB7fSxcbiAgICAgIH0pO1xuICAgICAgZGF0YS5zaG91bGQuZXFsKHtcbiAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICB2YWx1ZTogJ2ZvbycsXG4gICAgICAgIHNlc3Npb25JZDogJ2ZvbydcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIHVybCByZXF1ZXN0IHBhcmFtZXRlcnMgZm9yIG1ldGhvZHMgdG8gdXNlIC0gZWxlbWVudGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL2VsZW1lbnQvYmFyL2NsaWNrYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGRhdGE6IHt9LFxuICAgICAgfSk7XG4gICAgICBkYXRhLnN0YXR1cy5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBkYXRhLnZhbHVlLnNob3VsZC5lcWwoWydiYXInLCAnZm9vJ10pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIHVybCByZXEgcGFyYW1zIGluIHRoZSBvcmRlcjogY3VzdG9tLCBlbGVtZW50LCBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL2VsZW1lbnQvYmFyL2F0dHJpYnV0ZS9iYXpgLFxuICAgICAgfSk7XG4gICAgICBkYXRhLnN0YXR1cy5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBkYXRhLnZhbHVlLnNob3VsZC5lcWwoWydiYXonLCAnYmFyJywgJ2ZvbyddKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVzcG9uZCB3aXRoIDQwMCBCYWQgUmVxdWVzdCBpZiBwYXJhbWV0ZXJzIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7ZGF0YSwgc3RhdHVzfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YToge30sXG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSk7XG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDQwMCk7XG4gICAgICBKU09OLnN0cmluZ2lmeShkYXRhKS5zaG91bGQuY29udGFpbigndXJsJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCByZXF1ZXN0cyB3aXRoIGEgYmFkbHkgZm9ybWF0dGVkIGJvZHkgYW5kIG5vdCBjcmFzaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YTogJ29oIGhlbGxvJ1xuICAgICAgfSkuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWQ7XG5cbiAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YToge3VybDogJ2h0dHA6Ly9nb29nbGUuY29tJ31cbiAgICAgIH0pO1xuICAgICAgZGF0YS5zaG91bGQuZXFsKHtcbiAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICB2YWx1ZTogJ05hdmlnYXRlZCB0bzogaHR0cDovL2dvb2dsZS5jb20nLFxuICAgICAgICBzZXNzaW9uSWQ6ICdmb28nXG4gICAgICB9KTtcblxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgNDA0IGZvciBiYWQgcm91dGVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L2JsYXJnaW1hcmdgLFxuICAgICAgfSkuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKC80MDQvKTtcbiAgICB9KTtcblxuICAgIGl0KCc0eHggcmVzcG9uc2VzIHNob3VsZCBoYXZlIGNvbnRlbnQtdHlwZSBvZiBhcHBsaWNhdGlvbi9qc29uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2hlYWRlcnN9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L2JsYXJnaW1hcmdhcml0YWAsXG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddLnNob3VsZC5pbmNsdWRlKCdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG5vdCB5ZXQgaW1wbGVtZW50ZWQgZm9yIHVuZmlsbGVkb3V0IGNvbW1hbmRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vZWxlbWVudC9iYXIvbG9jYXRpb25gLFxuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDUwMSk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe1xuICAgICAgICBzdGF0dXM6IDQwNSxcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBtZXNzYWdlOiAnTWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gaW1wbGVtZW50ZWQnXG4gICAgICAgIH0sXG4gICAgICAgIHNlc3Npb25JZDogJ2ZvbydcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBub3QgaW1wbGVtZW50ZWQgZm9yIGlnbm9yZWQgY29tbWFuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9idXR0b251cGAsXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgICAgZGF0YToge30sXG4gICAgICB9KTtcblxuICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCg1MDEpO1xuICAgICAgZGF0YS5zaG91bGQuZXFsKHtcbiAgICAgICAgc3RhdHVzOiA0MDUsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ01ldGhvZCBoYXMgbm90IHlldCBiZWVuIGltcGxlbWVudGVkJ1xuICAgICAgICB9LFxuICAgICAgICBzZXNzaW9uSWQ6ICdmb28nXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IDQwMCBmb3IgYmFkIHBhcmFtZXRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vdXJsYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGRhdGE6IHt9XG4gICAgICB9KS5zaG91bGQuZXZlbnR1YWxseS5iZS5yZWplY3RlZFdpdGgoLzQwMC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpZ25vcmUgc3BlY2lhbCBleHRyYSBwYXlsb2FkIHBhcmFtcyBpbiB0aGUgcmlnaHQgY29udGV4dHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vZWxlbWVudC9iYXIvdmFsdWVgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YToge2lkOiAnYmF6Jywgc2Vzc2lvbklkOiAnbG9sJywgdmFsdWU6IFsnYSddfVxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9lbGVtZW50L2Jhci92YWx1ZWAsXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBkYXRhOiB7aWQ6ICdiYXonfVxuICAgICAgfSkuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKC80MDAvKTtcblxuICAgICAgLy8gbWFrZSBzdXJlIGFkZGluZyB0aGUgb3B0aW9uYWwgJ2lkJyBkb2Vzbid0IGNsb2JiZXIgYSByb3V0ZSB3aGVyZSB3ZVxuICAgICAgLy8gaGF2ZSBhbiBhY3R1YWwgcmVxdWlyZWQgJ2lkJ1xuICAgICAgYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL2ZyYW1lYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGRhdGE6IHtpZDogJ2Jheid9XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IGVycm9yIGV2ZW4gaWYgZHJpdmVyIGRvZXMgbm90IHRocm93JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vYXBwaXVtL3JlY2VpdmVfYXN5bmNfcmVzcG9uc2VgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YToge3Jlc3BvbnNlOiAnYmF6J30sXG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSk7XG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDUwMCk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe1xuICAgICAgICBzdGF0dXM6IDEzLFxuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIG1lc3NhZ2U6ICdBbiB1bmtub3duIHNlcnZlci1zaWRlIGVycm9yIG9jY3VycmVkIHdoaWxlIHByb2Nlc3NpbmcgJyArXG4gICAgICAgICAgICAgICAgICAgJ3RoZSBjb21tYW5kLiBPcmlnaW5hbCBlcnJvcjogTWlzaGFuZGxlZCBEcml2ZXIgRXJyb3InXG4gICAgICAgIH0sXG4gICAgICAgIHNlc3Npb25JZDogJ2ZvbydcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3czYyBzZW5ka2V5cyBtaWdyYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCB2YWx1ZSBmb3Igc2VuZGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL2VsZW1lbnQvYmFyL3ZhbHVlYCxcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBkYXRhOiB7dmFsdWU6ICd0ZXh0IHRvIHR5cGUnfVxuICAgICAgICB9KTtcbiAgICAgICAgZGF0YS5zdGF0dXMuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICBkYXRhLnZhbHVlLnNob3VsZC5lcWwoWyd0ZXh0IHRvIHR5cGUnLCAnYmFyJ10pO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCB0ZXh0IGZvciBzZW5ka2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vZWxlbWVudC9iYXIvdmFsdWVgLFxuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIGRhdGE6IHt0ZXh0OiAndGV4dCB0byB0eXBlJ31cbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGEuc3RhdHVzLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgZGF0YS52YWx1ZS5zaG91bGQuZXFsKFsndGV4dCB0byB0eXBlJywgJ2JhciddKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgdmFsdWUgYW5kIHRleHQgZm9yIHNlbmRrZXlzLCBhbmQgdXNlIHZhbHVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9lbGVtZW50L2Jhci92YWx1ZWAsXG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgZGF0YToge3ZhbHVlOiAndGV4dCB0byB0eXBlJywgdGV4dDogJ3RleHQgdG8gaWdub3JlJ31cbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGEuc3RhdHVzLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgZGF0YS52YWx1ZS5zaG91bGQuZXFsKFsndGV4dCB0byB0eXBlJywgJ2JhciddKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ211bHRpcGxlIHNldHMgb2YgYXJndW1lbnRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgZGVzY3JpYmUoJ29wdGlvbmFsJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGFsbG93IG1vdmV0byB3aXRoIGVsZW1lbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9tb3ZldG9gLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7ZWxlbWVudDogJzMnfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGRhdGEuc3RhdHVzLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgICBkYXRhLnZhbHVlLnNob3VsZC5lcWwoWyczJywgbnVsbCwgbnVsbF0pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBhbGxvdyBtb3ZldG8gd2l0aCB4b2Zmc2V0L3lvZmZzZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9tb3ZldG9gLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7eG9mZnNldDogNDIsIHlvZmZzZXQ6IDE3fVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGRhdGEuc3RhdHVzLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgICBkYXRhLnZhbHVlLnNob3VsZC5lcWwoW251bGwsIDQyLCAxN10pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgZGVzY3JpYmUoJ3JlcXVpcmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGFsbG93IHJlbW92ZUFwcCB3aXRoIGFwcElkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vYXBwaXVtL2RldmljZS9yZW1vdmVfYXBwYCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YToge2FwcElkOiA0Mn1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBkYXRhLnN0YXR1cy5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgICAgZGF0YS52YWx1ZS5zaG91bGQuZXFsKDQyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgYWxsb3cgcmVtb3ZlQXBwIHdpdGggYnVuZGxlSWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9hcHBpdW0vZGV2aWNlL3JlbW92ZV9hcHBgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7YnVuZGxlSWQ6IDQyfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGRhdGEuc3RhdHVzLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgICBkYXRhLnZhbHVlLnNob3VsZC5lcWwoNDIpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2RlZmF1bHQgcGFyYW0gd3JhcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgd3JhcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vdG91Y2gvcGVyZm9ybWAsXG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgZGF0YTogW3snYWN0aW9uJzogJ3RhcCcsICdvcHRpb25zJzogeydlbGVtZW50JzogJzMnfX1dXG4gICAgICAgIH0pO1xuICAgICAgICBkYXRhLnZhbHVlLnNob3VsZC5kZWVwLmVxdWFsKFtbeydhY3Rpb24nOiAndGFwJywgJ29wdGlvbnMnOiB7J2VsZW1lbnQnOiAnMyd9fV0sICdmb28nXSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBub3Qgd3JhcCB0d2ljZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb28vdG91Y2gvcGVyZm9ybWAsXG4gICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgZGF0YToge2FjdGlvbnM6IFt7J2FjdGlvbic6ICd0YXAnLCAnb3B0aW9ucyc6IHsnZWxlbWVudCc6ICczJ319XX1cbiAgICAgICAgfSk7XG4gICAgICAgIGRhdGEudmFsdWUuc2hvdWxkLmRlZXAuZXF1YWwoW1t7J2FjdGlvbic6ICd0YXAnLCAnb3B0aW9ucyc6IHsnZWxlbWVudCc6ICczJ319XSwgJ2ZvbyddKTtcbiAgICAgIH0pO1xuXG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlIHNlc3Npb25zIHZpYSBIVFRQIGVuZHBvaW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNlc3Npb25JZDtcblxuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlc3Npb25JZCA9IG51bGw7XG4gICAgICB9KTtcbiAgICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChzZXNzaW9uSWQpIHtcbiAgICAgICAgICBhd2FpdCBheGlvcy5kZWxldGUoYCR7YmFzZVVybH0vc2Vzc2lvbi8ke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IGNyZWF0ZSBzZXNzaW9uIHdpdGggZGVzaXJlZCBjYXBzIChNSlNPTldQKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGVzaXJlZENhcGFiaWxpdGllcyA9IHthOiAnYid9O1xuICAgICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uYCxcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBkYXRhOiB7ZGVzaXJlZENhcGFiaWxpdGllc31cbiAgICAgICAgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkYXRhLnZhbHVlLCBudWxsKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGNyZWF0ZSBzZXNzaW9uIHdpdGhvdXQgY2FwYWJpbGl0aWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBheGlvcyh7XG4gICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uYCxcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgfSkuc2hvdWxkLmV2ZW50dWFsbHkuYmUucmVqZWN0ZWRXaXRoKC80MDAvKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBhbGxvdyBjcmVhdGUgc2Vzc2lvbiB3aXRoIGNhcGFiaWxpdGllcyAoVzNDKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdzNjQ2FwYWJpbGl0aWVzID0geydhcHBpdW06ZSc6ICdmJ307XG4gICAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb25gLFxuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIGRhdGE6IHtjYXBhYmlsaXRpZXM6IHczY0NhcGFiaWxpdGllc31cbiAgICAgICAgfSk7XG4gICAgICAgIHNlc3Npb25JZCA9IGRhdGEuc2Vzc2lvbklkO1xuXG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3QoZGF0YS5zdGF0dXMpO1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KGRhdGEuc2Vzc2lvbklkKTtcbiAgICAgICAgZGF0YS52YWx1ZS5jYXBhYmlsaXRpZXMuc2hvdWxkLmVxbCh3M2NDYXBhYmlsaXRpZXMpO1xuICAgICAgICBkYXRhLnZhbHVlLnNlc3Npb25JZC5zaG91bGQuZXhpc3Q7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgcmFpc2UgYW4gZXJyb3IgaWYgdGhlIGRyaXZlciBkb2VzIG5vdCBzdXBwb3J0IFczQyB5ZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVNlc3Npb25TdHViID0gc2lub24uc3R1Yihkcml2ZXIsICdjcmVhdGVTZXNzaW9uJykuY2FsbHNGYWtlKGZ1bmN0aW9uIChjYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgICBkcml2ZXIuc2Vzc2lvbklkID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gQmFzZURyaXZlci5wcm90b3R5cGUuY3JlYXRlU2Vzc2lvbi5jYWxsKGRyaXZlciwgY2FwYWJpbGl0aWVzKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gbGV0IHtzdGF0dXMsIHZhbHVlLCBzZXNzaW9uSWR9ID0gYXdhaXQgcmVxdWVzdCh7XG4gICAgICAgICAgYXdhaXQgYXhpb3Moe1xuICAgICAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uYCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgICAgICAgICBhbHdheXNNYXRjaDoge1xuICAgICAgICAgICAgICAgICAgcGxhdGZvcm1OYW1lOiAnRmFrZScsXG4gICAgICAgICAgICAgICAgICAnYXBwaXVtOmRldmljZU5hbWUnOiAnRmFrZScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmaXJzdE1hdGNoOiBbe31dLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLnNob3VsZC5ldmVudHVhbGx5LmJlLnJlamVjdGVkV2l0aCgvNTAwLyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgY3JlYXRlU2Vzc2lvblN0dWIucmVzdG9yZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3czYyBlbmRwb2ludHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBzZXNzaW9uVXJsO1xuXG4gICAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIFN0YXJ0IGEgVzNDIHNlc3Npb25cbiAgICAgICAgICBjb25zdCB7dmFsdWV9ID0gKGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbmAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICAgICAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAgICAgICAgIHBsYXRmb3JtTmFtZTogJ0Zha2UnLFxuICAgICAgICAgICAgICAgICAgJ2FwcGl1bTpkZXZpY2VOYW1lJzogJ0NvbW1vZG9yZSA2NCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmaXJzdE1hdGNoOiBbe31dLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSkuZGF0YTtcbiAgICAgICAgICBzZXNzaW9uSWQgPSB2YWx1ZS5zZXNzaW9uSWQ7XG4gICAgICAgICAgc2Vzc2lvblVybCA9IGAke2Jhc2VVcmx9L3Nlc3Npb24vJHtzZXNzaW9uSWR9YDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoYHNob3VsZCB0aHJvdyA0MDAgQmFkIFBhcmFtZXRlcnMgZXhjZXB0aW9uIGlmIHRoZSBwYXJhbWV0ZXJzIGFyZSBiYWRgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgICAgICB1cmw6IGAke3Nlc3Npb25Vcmx9L2FjdGlvbnNgLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgYmFkOiAncGFyYW1zJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDQwMCk7XG5cbiAgICAgICAgICBjb25zdCB7ZXJyb3I6IHczY0Vycm9yLCBtZXNzYWdlLCBzdGFja3RyYWNlfSA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgbWVzc2FnZS5zaG91bGQubWF0Y2goL1BhcmFtZXRlcnMgd2VyZSBpbmNvcnJlY3QvKTtcbiAgICAgICAgICBzdGFja3RyYWNlLnNob3VsZC5tYXRjaCgvcHJvdG9jb2wuanMvKTtcbiAgICAgICAgICB3M2NFcnJvci5zaG91bGQuYmUuYS5zdHJpbmc7XG4gICAgICAgICAgdzNjRXJyb3Iuc2hvdWxkLmVxdWFsKGVycm9ycy5JbnZhbGlkQXJndW1lbnRFcnJvci5lcnJvcigpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoYHNob3VsZCB0aHJvdyA0MDUgZXhjZXB0aW9uIGlmIHRoZSBjb21tYW5kIGhhc24ndCBiZWVuIGltcGxlbWVudGVkIHlldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICAgIHVybDogYCR7c2Vzc2lvblVybH0vYWN0aW9uc2AsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICBhY3Rpb25zOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCg0MDUpO1xuXG4gICAgICAgICAgY29uc3Qge2Vycm9yOiB3M2NFcnJvciwgbWVzc2FnZSwgc3RhY2t0cmFjZX0gPSBkYXRhLnZhbHVlO1xuICAgICAgICAgIG1lc3NhZ2Uuc2hvdWxkLm1hdGNoKC9NZXRob2QgaGFzIG5vdCB5ZXQgYmVlbiBpbXBsZW1lbnRlZC8pO1xuICAgICAgICAgIHN0YWNrdHJhY2Uuc2hvdWxkLm1hdGNoKC9wcm90b2NvbC5qcy8pO1xuICAgICAgICAgIHczY0Vycm9yLnNob3VsZC5iZS5hLnN0cmluZztcbiAgICAgICAgICB3M2NFcnJvci5zaG91bGQuZXF1YWwoZXJyb3JzLk5vdFlldEltcGxlbWVudGVkRXJyb3IuZXJyb3IoKSk7XG4gICAgICAgICAgbWVzc2FnZS5zaG91bGQubWF0Y2goL01ldGhvZCBoYXMgbm90IHlldCBiZWVuIGltcGxlbWVudGVkLyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KGBzaG91bGQgdGhyb3cgNTAwIFVua25vd24gRXJyb3IgaWYgdGhlIGNvbW1hbmQgdGhyb3dzIGFuIHVuZXhwZWN0ZWQgZXhjZXB0aW9uYCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRyaXZlci5wZXJmb3JtQWN0aW9ucyA9ICgpID0+IHsgdGhyb3cgbmV3IEVycm9yKGBEaWRuJ3Qgd29ya2ApOyB9O1xuICAgICAgICAgIGNvbnN0IHtzdGF0dXMsIGRhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgICAgdXJsOiBgJHtzZXNzaW9uVXJsfS9hY3Rpb25zYCxcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtdLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNTAwKTtcblxuICAgICAgICAgIGNvbnN0IHtlcnJvcjogdzNjRXJyb3IsIG1lc3NhZ2UsIHN0YWNrdHJhY2V9ID0gZGF0YS52YWx1ZTtcbiAgICAgICAgICBzdGFja3RyYWNlLnNob3VsZC5tYXRjaCgvcHJvdG9jb2wuanMvKTtcbiAgICAgICAgICB3M2NFcnJvci5zaG91bGQuYmUuYS5zdHJpbmc7XG4gICAgICAgICAgdzNjRXJyb3Iuc2hvdWxkLmVxdWFsKGVycm9ycy5Vbmtub3duRXJyb3IuZXJyb3IoKSk7XG4gICAgICAgICAgbWVzc2FnZS5zaG91bGQubWF0Y2goL0RpZG4ndCB3b3JrLyk7XG5cbiAgICAgICAgICBkZWxldGUgZHJpdmVyLnBlcmZvcm1BY3Rpb25zO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChgc2hvdWxkIHRyYW5zbGF0ZSBlbGVtZW50IGZvcm1hdCBmcm9tIE1KU09OV1AgdG8gVzNDYCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHJldFZhbHVlID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzb21ldGhpbmc6IHtcbiAgICAgICAgICAgICAgICBbTUpTT05XUF9FTEVNRU5UX0tFWV06ICdmb29vJyxcbiAgICAgICAgICAgICAgICBvdGhlcjogJ2JhcidcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICBbTUpTT05XUF9FTEVNRU5UX0tFWV06ICdiYXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ2lnbm9yZScsXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWUgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHNvbWV0aGluZzoge1xuICAgICAgICAgICAgICAgIFtNSlNPTldQX0VMRU1FTlRfS0VZXTogJ2Zvb28nLFxuICAgICAgICAgICAgICAgIFtXM0NfRUxFTUVOVF9LRVldOiAnZm9vbycsXG4gICAgICAgICAgICAgICAgb3RoZXI6ICdiYXInXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgW01KU09OV1BfRUxFTUVOVF9LRVldOiAnYmFyJyxcbiAgICAgICAgICAgICAgW1czQ19FTEVNRU5UX0tFWV06ICdiYXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ2lnbm9yZScsXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IGZpbmRFbGVtZW50c0JhY2t1cCA9IGRyaXZlci5maW5kRWxlbWVudHM7XG4gICAgICAgICAgZHJpdmVyLmZpbmRFbGVtZW50cyA9ICgpID0+IHJldFZhbHVlO1xuICAgICAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zLnBvc3QoYCR7c2Vzc2lvblVybH0vZWxlbWVudHNgLCB7XG4gICAgICAgICAgICB1c2luZzogJ3doYXRldmVyJyxcbiAgICAgICAgICAgIHZhbHVlOiAnd2hhdGV2ZXInLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGRhdGEudmFsdWUuc2hvdWxkLmVxbChleHBlY3RlZFZhbHVlKTtcbiAgICAgICAgICBkcml2ZXIuZmluZEVsZW1lbnRzID0gZmluZEVsZW1lbnRzQmFja3VwO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChgc2hvdWxkIGZhaWwgd2l0aCBhIDQwOCBlcnJvciBpZiBpdCB0aHJvd3MgYSBUaW1lb3V0RXJyb3IgZXhjZXB0aW9uYCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxldCBzZXRVcmxTdHViID0gc2lub24uc3R1Yihkcml2ZXIsICdzZXRVcmwnKS5jYWxsc0Zha2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IGVycm9ycy5UaW1lb3V0RXJyb3I7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgICAgICB1cmw6IGAke3Nlc3Npb25Vcmx9L3VybGAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tLycsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCg0MDgpO1xuXG4gICAgICAgICAgY29uc3Qge2Vycm9yOiB3M2NFcnJvciwgbWVzc2FnZSwgc3RhY2t0cmFjZX0gPSBkYXRhLnZhbHVlO1xuICAgICAgICAgIHN0YWNrdHJhY2Uuc2hvdWxkLm1hdGNoKC9wcm90b2NvbC5qcy8pO1xuICAgICAgICAgIHczY0Vycm9yLnNob3VsZC5iZS5hLnN0cmluZztcbiAgICAgICAgICB3M2NFcnJvci5zaG91bGQuZXF1YWwoZXJyb3JzLlRpbWVvdXRFcnJvci5lcnJvcigpKTtcbiAgICAgICAgICBtZXNzYWdlLnNob3VsZC5tYXRjaCgvQW4gb3BlcmF0aW9uIGRpZCBub3QgY29tcGxldGUgYmVmb3JlIGl0cyB0aW1lb3V0IGV4cGlyZWQvKTtcblxuICAgICAgICAgIHNldFVybFN0dWIucmVzdG9yZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChgc2hvdWxkIHBhc3Mgd2l0aCAyMDAgSFRUUCBzdGF0dXMgY29kZSBpZiB0aGUgY29tbWFuZCByZXR1cm5zIGEgdmFsdWVgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZHJpdmVyLnBlcmZvcm1BY3Rpb25zID0gKGFjdGlvbnMpID0+ICdJdCB3b3JrcyAnICsgYWN0aW9ucy5qb2luKCcnKTtcbiAgICAgICAgICBjb25zdCB7c3RhdHVzLCB2YWx1ZSwgc2Vzc2lvbklkfSA9IChhd2FpdCBheGlvcy5wb3N0KGAke3Nlc3Npb25Vcmx9L2FjdGlvbnNgLCB7XG4gICAgICAgICAgICBhY3Rpb25zOiBbJ2EnLCAnYicsICdjJ10sXG4gICAgICAgICAgfSkpLmRhdGE7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChzZXNzaW9uSWQpO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3Qoc3RhdHVzKTtcbiAgICAgICAgICB2YWx1ZS5zaG91bGQuZXF1YWwoJ0l0IHdvcmtzIGFiYycpO1xuICAgICAgICAgIGRlbGV0ZSBkcml2ZXIucGVyZm9ybUFjdGlvbnM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdqd3Byb3h5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxldCBwb3J0O1xuICAgICAgICAgIGxldCBzZXJ2ZXIsIGp3cHJveHksIGFwcDtcblxuICAgICAgICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3J0ID0gYXdhaXQgZ2V0VGVzdFBvcnQodHJ1ZSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGNyZWF0ZVByb3h5U2VydmVyKHNlc3Npb25JZCwgcG9ydCk7XG4gICAgICAgICAgICBzZXJ2ZXIgPSByZXMuc2VydmVyO1xuICAgICAgICAgICAgYXBwID0gcmVzLmFwcDtcbiAgICAgICAgICAgIGp3cHJveHkgPSBuZXcgSldQcm94eSh7aG9zdDogVEVTVF9IT1NULCBwb3J0fSk7XG4gICAgICAgICAgICBqd3Byb3h5LnNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgICAgICAgICAgIGRyaXZlci5wZXJmb3JtQWN0aW9ucyA9IGFzeW5jIChhY3Rpb25zKSA9PiBhd2FpdCBqd3Byb3h5LmNvbW1hbmQoJy9wZXJmb3JtLWFjdGlvbnMnLCAnUE9TVCcsIGFjdGlvbnMpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBkcml2ZXIucGVyZm9ybUFjdGlvbnM7XG4gICAgICAgICAgICBhd2FpdCBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgd29yayBpZiBhIHByb3hpZWQgcmVxdWVzdCByZXR1cm5zIGEgcmVzcG9uc2Ugd2l0aCBzdGF0dXMgMjAwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXBwLnBvc3QoJy9zZXNzaW9uLzpzZXNzaW9uSWQvcGVyZm9ybS1hY3Rpb25zJywgKHJlcSwgcmVzKSA9PiB7XG4gICAgICAgICAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHJlcS5wYXJhbXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgIHZhbHVlOiByZXEuYm9keSxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IDAsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHtzdGF0dXMsIHZhbHVlLCBzZXNzaW9uSWR9ID0gKGF3YWl0IGF4aW9zLnBvc3QoYCR7c2Vzc2lvblVybH0vYWN0aW9uc2AsIHtcbiAgICAgICAgICAgICAgYWN0aW9uczogWzEsIDIsIDNdLFxuICAgICAgICAgICAgfSkpLmRhdGE7XG4gICAgICAgICAgICB2YWx1ZS5zaG91bGQuZXFsKFsxLCAyLCAzXSk7XG4gICAgICAgICAgICBzaG91bGQubm90LmV4aXN0KHN0YXR1cyk7XG4gICAgICAgICAgICBzaG91bGQubm90LmV4aXN0KHNlc3Npb25JZCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBlcnJvciBpZiBhIHByb3hpZWQgcmVxdWVzdCByZXR1cm5zIGEgTUpTT05XUCBlcnJvciByZXNwb25zZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGFwcC5wb3N0KCcvc2Vzc2lvbi86c2Vzc2lvbklkL3BlcmZvcm0tYWN0aW9ucycsIChyZXEsIHJlcykgPT4ge1xuICAgICAgICAgICAgICByZXMuc3RhdHVzKDUwMCkuanNvbih7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgIHN0YXR1czogNixcbiAgICAgICAgICAgICAgICB2YWx1ZTogJ0EgcHJvYmxlbSBvY2N1cnJlZCcsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICAgICAgdXJsOiBgJHtzZXNzaW9uVXJsfS9hY3Rpb25zYCxcbiAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWN0aW9uczogWzEsIDIsIDNdLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoSFRUUFN0YXR1c0NvZGVzLk5PVF9GT1VORCk7XG4gICAgICAgICAgICBKU09OLnN0cmluZ2lmeShkYXRhKS5zaG91bGQubWF0Y2goL0EgcHJvYmxlbSBvY2N1cnJlZC8pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gVzNDIGVycm9yIGlmIGEgcHJveGllZCByZXF1ZXN0IHJldHVybnMgYSBXM0MgZXJyb3IgcmVzcG9uc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgU29tZSBlcnJvciBvY2N1cnJlZGApO1xuICAgICAgICAgICAgZXJyb3IudzNjU3RhdHVzID0gNDE0O1xuICAgICAgICAgICAgY29uc3QgZXhlY3V0ZUNvbW1hbmRTdHViID0gc2lub24uc3R1Yihkcml2ZXIsICdleGVjdXRlQ29tbWFuZCcpLnJldHVybnMoe1xuICAgICAgICAgICAgICBwcm90b2NvbDogJ1czQycsXG4gICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICAgICAgdXJsOiBgJHtzZXNzaW9uVXJsfS9hY3Rpb25zYCxcbiAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgICAgICAgICBkYXRhOiB7YWN0aW9uczogWzEsIDIsIDNdfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCg0MTQpO1xuICAgICAgICAgICAgY29uc3Qge2Vycm9yOiB3M2NFcnJvciwgbWVzc2FnZTogZXJyTWVzc2FnZSwgc3RhY2t0cmFjZX0gPSBkYXRhLnZhbHVlO1xuICAgICAgICAgICAgdzNjRXJyb3Iuc2hvdWxkLmVxdWFsKCd1bmtub3duIGVycm9yJyk7XG4gICAgICAgICAgICBzdGFja3RyYWNlLnNob3VsZC5tYXRjaCgvU29tZSBlcnJvciBvY2N1cnJlZC8pO1xuICAgICAgICAgICAgZXJyTWVzc2FnZS5zaG91bGQuZXF1YWwoJ1NvbWUgZXJyb3Igb2NjdXJyZWQnKTtcbiAgICAgICAgICAgIGV4ZWN1dGVDb21tYW5kU3R1Yi5yZXN0b3JlKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBlcnJvciBpZiBhIHByb3hpZWQgcmVxdWVzdCByZXR1cm5zIGEgTUpTT05XUCBlcnJvciByZXNwb25zZSBidXQgSFRUUCBzdGF0dXMgY29kZSBpcyAyMDAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhcHAucG9zdCgnL3Nlc3Npb24vOnNlc3Npb25JZC9wZXJmb3JtLWFjdGlvbnMnLCAocmVxLCByZXMpID0+IHtcbiAgICAgICAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogJ0Zha2UgU2Vzc2lvbiBJZCcsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiA3LFxuICAgICAgICAgICAgICAgIHZhbHVlOiAnQSBwcm9ibGVtIG9jY3VycmVkJyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHtzdGF0dXMsIGRhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgICAgICB1cmw6IGAke3Nlc3Npb25Vcmx9L2FjdGlvbnNgLFxuICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiBbMSwgMiwgM10sXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbChIVFRQU3RhdHVzQ29kZXMuTk9UX0ZPVU5EKTtcbiAgICAgICAgICAgIGNvbnN0IHtlcnJvcjogdzNjRXJyb3IsIG1lc3NhZ2U6IGVyck1lc3NhZ2UsIHN0YWNrdHJhY2V9ID0gZGF0YS52YWx1ZTtcbiAgICAgICAgICAgIHczY0Vycm9yLnNob3VsZC5lcXVhbCgnbm8gc3VjaCBlbGVtZW50Jyk7XG4gICAgICAgICAgICBlcnJNZXNzYWdlLnNob3VsZC5tYXRjaCgvQSBwcm9ibGVtIG9jY3VycmVkLyk7XG4gICAgICAgICAgICBzdGFja3RyYWNlLnNob3VsZC5leGlzdDtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGVycm9yIGlmIGEgcHJveGllZCByZXF1ZXN0IHJldHVybnMgYSBXM0MgZXJyb3IgcmVzcG9uc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhcHAucG9zdCgnL3Nlc3Npb24vOnNlc3Npb25JZC9wZXJmb3JtLWFjdGlvbnMnLCAocmVxLCByZXMpID0+IHtcbiAgICAgICAgICAgICAgcmVzLnN0YXR1cyg0MDQpLmpzb24oe1xuICAgICAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICBlcnJvcjogJ25vIHN1Y2ggZWxlbWVudCcsXG4gICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnZG9lcyBub3QgbWFrZSBhIGRpZmZlcmVuY2UnLFxuICAgICAgICAgICAgICAgICAgc3RhY2t0cmFjZTogJ2FyYml0cmFyeSBzdGFja3RyYWNlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgICAgICAgIHVybDogYCR7c2Vzc2lvblVybH0vYWN0aW9uc2AsXG4gICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIGFjdGlvbnM6IFsxLCAyLCAzXSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKEhUVFBTdGF0dXNDb2Rlcy5OT1RfRk9VTkQpO1xuICAgICAgICAgICAgY29uc3Qge2Vycm9yOiB3M2NFcnJvciwgc3RhY2t0cmFjZX0gPSBkYXRhLnZhbHVlO1xuICAgICAgICAgICAgdzNjRXJyb3Iuc2hvdWxkLmVxdWFsKCdubyBzdWNoIGVsZW1lbnQnKTtcbiAgICAgICAgICAgIHN0YWNrdHJhY2Uuc2hvdWxkLm1hdGNoKC9hcmJpdHJhcnkgc3RhY2t0cmFjZS8pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gZXJyb3IgaWYgYSBwcm94aWVkIHJlcXVlc3QgcmV0dXJucyBhIFczQyBlcnJvciByZXNwb25zZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGFwcC5wb3N0KCcvc2Vzc2lvbi86c2Vzc2lvbklkL3BlcmZvcm0tYWN0aW9ucycsIChyZXEsIHJlcykgPT4ge1xuICAgICAgICAgICAgICByZXMuc2V0KCdDb25uZWN0aW9uJywgJ2Nsb3NlJyk7XG4gICAgICAgICAgICAgIHJlcy5zdGF0dXMoNDQ0KS5qc29uKHtcbiAgICAgICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICAgICAgZXJyb3I6ICdib2d1cyBlcnJvciBjb2RlJyxcbiAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdkb2VzIG5vdCBtYWtlIGEgZGlmZmVyZW5jZScsXG4gICAgICAgICAgICAgICAgICBzdGFja3RyYWNlOiAnYXJiaXRyYXJ5IHN0YWNrdHJhY2UnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgICAgICAgdXJsOiBgJHtzZXNzaW9uVXJsfS9hY3Rpb25zYCxcbiAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWN0aW9uczogWzEsIDIsIDNdLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoSFRUUFN0YXR1c0NvZGVzLklOVEVSTkFMX1NFUlZFUl9FUlJPUik7XG4gICAgICAgICAgICBjb25zdCB7ZXJyb3I6IHczY0Vycm9yLCBzdGFja3RyYWNlfSA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgICB3M2NFcnJvci5zaG91bGQuZXF1YWwoJ3Vua25vd24gZXJyb3InKTtcbiAgICAgICAgICAgIHN0YWNrdHJhY2Uuc2hvdWxkLm1hdGNoKC9hcmJpdHJhcnkgc3RhY2t0cmFjZS8pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBjb21tYW5kcyB3aXRoIG5vIHJlc3BvbnNlIHZhbHVlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9mb3J3YXJkYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICB9KTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMCxcbiAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgIHNlc3Npb25JZDogJ2ZvbydcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhbGxvdyBlbXB0eSBzdHJpbmcgcmVzcG9uc2UgdmFsdWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge2RhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vZm9vL2VsZW1lbnQvYmFyL3RleHRgLFxuICAgICAgfSk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe1xuICAgICAgICBzdGF0dXM6IDAsXG4gICAgICAgIHZhbHVlOiAnJyxcbiAgICAgICAgc2Vzc2lvbklkOiAnZm9vJ1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNlbmQgNTAwIHJlc3BvbnNlIGFuZCBhbiBVbmtub3duIG9iamVjdCBmb3IgcmVqZWN0ZWQgY29tbWFuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uL2Zvby9yZWZyZXNoYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNTAwKTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMTMsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ0FuIHVua25vd24gc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyAnICtcbiAgICAgICAgICAgICAgICAgICAndGhlIGNvbW1hbmQuIE9yaWdpbmFsIGVycm9yOiBUb28gRnJlc2ghJ1xuICAgICAgICB9LFxuICAgICAgICBzZXNzaW9uSWQ6ICdmb28nXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHRocm93IFVua25vd25FcnJvciB3aGVuIGtub3duJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge3N0YXR1cywgZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi9mb29gLFxuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgIH0pO1xuXG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDQwNCk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe1xuICAgICAgICBzdGF0dXM6IDYsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ0Egc2Vzc2lvbiBpcyBlaXRoZXIgdGVybWluYXRlZCBvciBub3Qgc3RhcnRlZCdcbiAgICAgICAgfSxcbiAgICAgICAgc2Vzc2lvbklkOiAnZm9vJ1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzZXNzaW9uIElkcycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgZHJpdmVyID0gbmV3IEZha2VEcml2ZXIoKTtcbiAgICBsZXQgbWpzb253cFNlcnZlcjtcblxuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBtanNvbndwU2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgICAgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uOiByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24oZHJpdmVyKSxcbiAgICAgICAgcG9ydCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgbWpzb253cFNlcnZlci5jbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGRyaXZlci5zZXNzaW9uSWQgPSBudWxsO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbnVsbCBTZXNzaW9uSWQgZm9yIGNvbW1hbmRzIHdpdGhvdXQgc2Vzc2lvbklkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHtkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zdGF0dXNgLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5lcXVhbChkYXRhLnNlc3Npb25JZCwgbnVsbCk7XG4gICAgfSk7XG5cbiAgICBpdCgncmVzcG9uZHMgd2l0aCB0aGUgc2FtZSBzZXNzaW9uIElEIGluIHRoZSByZXF1ZXN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNlc3Npb25JZCA9ICdWYWRlciBTZXNzaW9ucyc7XG4gICAgICBkcml2ZXIuc2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuXG4gICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi8ke3Nlc3Npb25JZH0vdXJsYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGRhdGE6IHt1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbSd9XG4gICAgICB9KTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGRhdGEuc2Vzc2lvbklkKTtcbiAgICAgIGRhdGEuc2Vzc2lvbklkLnNob3VsZC5lcWwoc2Vzc2lvbklkKTtcbiAgICB9KTtcblxuICAgIGl0KCd5ZWxscyBpZiBubyBzZXNzaW9uIGV4aXN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzZXNzaW9uSWQgPSAnVmFkZXIgU2Vzc2lvbnMnO1xuXG4gICAgICBjb25zdCB7ZGF0YSwgc3RhdHVzfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgIGRhdGE6IHt1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbSd9LFxuICAgICAgfSk7XG5cbiAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNDA0KTtcbiAgICAgIGRhdGEuc3RhdHVzLnNob3VsZC5lcXVhbCg2KTtcbiAgICAgIGRhdGEudmFsdWUubWVzc2FnZS5zaG91bGQuY29udGFpbignc2Vzc2lvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3llbGxzIGlmIGludmFsaWQgc2Vzc2lvbiBpcyBzZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNlc3Npb25JZCA9ICdWYWRlciBTZXNzaW9ucyc7XG4gICAgICBkcml2ZXIuc2Vzc2lvbklkID0gJ3JlY2Vzc2lvbic7XG5cbiAgICAgIGNvbnN0IHtkYXRhLCBzdGF0dXN9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3Nlc3Npb24vJHtzZXNzaW9uSWR9L3VybGAsXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgICAgZGF0YToge3VybDogJ2h0dHA6Ly9nb29nbGUuY29tJ30sXG4gICAgICB9KTtcblxuICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCg0MDQpO1xuICAgICAgZGF0YS5zdGF0dXMuc2hvdWxkLmVxdWFsKDYpO1xuICAgICAgZGF0YS52YWx1ZS5tZXNzYWdlLnNob3VsZC5jb250YWluKCdzZXNzaW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhdmUgc2Vzc2lvbiBJRHMgaW4gZXJyb3IgcmVzcG9uc2VzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHNlc3Npb25JZCA9ICdWYWRlciBTZXNzaW9ucyc7XG4gICAgICBkcml2ZXIuc2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuXG4gICAgICBjb25zdCB7ZGF0YSwgc3RhdHVzfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS9yZWZyZXNoYCxcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIHZhbGlkYXRlU3RhdHVzOiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNTAwKTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMTMsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ0FuIHVua25vd24gc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyAnICtcbiAgICAgICAgICAgICAgICAgICAndGhlIGNvbW1hbmQuIE9yaWdpbmFsIGVycm9yOiBUb28gRnJlc2ghJ1xuICAgICAgICB9LFxuICAgICAgICBzZXNzaW9uSWRcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBuZXcgc2Vzc2lvbiBJRCBvbiBjcmVhdGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7ZGF0YX0gPSBhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbmAsXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBkYXRhOiB7Y2FwYWJpbGl0aWVzOiB7YWx3YXlzTWF0Y2g6IHsnYXBwaXVtOmdyZWV0aW5nJzogJ2hlbGxvJ30sIGZpcnN0TWF0Y2g6IFt7fV19fVxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChkYXRhLnZhbHVlLnNlc3Npb25JZCk7XG4gICAgICBkYXRhLnZhbHVlLnNlc3Npb25JZC5pbmRleE9mKCdmYWtlU2Vzc2lvbl8nKS5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBkYXRhLnZhbHVlLmNhcGFiaWxpdGllcy5zaG91bGQuZXFsKHthbHdheXNNYXRjaDogeydhcHBpdW06Z3JlZXRpbmcnOiAnaGVsbG8nfSwgZmlyc3RNYXRjaDogW3t9XX0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmlhIGRyaXZlcnMganNvbndwIHByb3h5JywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBkcml2ZXI7XG4gICAgbGV0IHNlc3Npb25JZCA9ICdmb28nO1xuICAgIGxldCBtanNvbndwU2VydmVyO1xuXG4gICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBkcml2ZXIgPSBuZXcgRmFrZURyaXZlcigpO1xuICAgICAgZHJpdmVyLnNlc3Npb25JZCA9IHNlc3Npb25JZDtcbiAgICAgIGRyaXZlci5wcm94eUFjdGl2ZSA9ICgpID0+IHRydWU7XG4gICAgICBkcml2ZXIuY2FuUHJveHkgPSAoKSA9PiB0cnVlO1xuXG4gICAgICBtanNvbndwU2VydmVyID0gYXdhaXQgc2VydmVyKHtcbiAgICAgICAgcm91dGVDb25maWd1cmluZ0Z1bmN0aW9uOiByb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24oZHJpdmVyKSxcbiAgICAgICAgcG9ydCxcbiAgICAgICAgZXh0cmFNZXRob2RNYXA6IEZha2VEcml2ZXIubmV3TWV0aG9kTWFwXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBtanNvbndwU2VydmVyLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdpdmUgYSBuaWNlIGVycm9yIGlmIHByb3h5aW5nIGlzIHNldCBidXQgbm8gcHJveHkgZnVuY3Rpb24gZXhpc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZHJpdmVyLmNhblByb3h5ID0gKCkgPT4gZmFsc2U7XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgIGRhdGE6IHt1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbSd9LFxuICAgICAgfSk7XG5cbiAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNTAwKTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMTMsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ0FuIHVua25vd24gc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyAnICtcbiAgICAgICAgICAgICAgICAgICAndGhlIGNvbW1hbmQuIE9yaWdpbmFsIGVycm9yOiBUcnlpbmcgdG8gcHJveHkgdG8gYSBKU09OV1AgJyArXG4gICAgICAgICAgICAgICAgICAgJ3NlcnZlciBidXQgZHJpdmVyIGlzIHVuYWJsZSB0byBwcm94eSdcbiAgICAgICAgfSxcbiAgICAgICAgc2Vzc2lvbklkXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyBvbiBhbnkgZXJyb3JzIGluIHByb3h5aW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZHJpdmVyLnByb3h5UmVxUmVzID0gYXN5bmMgZnVuY3Rpb24gKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlcXVpcmUtYXdhaXRcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmb28nKTtcbiAgICAgIH07XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgIGRhdGE6IHt1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbSd9LFxuICAgICAgfSk7XG5cbiAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNTAwKTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMTMsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ0FuIHVua25vd24gc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyAnICtcbiAgICAgICAgICAgICAgICAgICAndGhlIGNvbW1hbmQuIE9yaWdpbmFsIGVycm9yOiBDb3VsZCBub3QgcHJveHkuIFByb3h5ICcgK1xuICAgICAgICAgICAgICAgICAgICdlcnJvcjogZm9vJ1xuICAgICAgICB9LFxuICAgICAgICBzZXNzaW9uSWRcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhYmxlIHRvIHRocm93IFByb3h5UmVxdWVzdEVycm9yIGluIHByb3h5aW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZHJpdmVyLnByb3h5UmVxUmVzID0gYXN5bmMgZnVuY3Rpb24gKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlcXVpcmUtYXdhaXRcbiAgICAgICAgbGV0IGpzb253cCA9IHtzdGF0dXM6IDM1LCB2YWx1ZTogJ05vIHN1Y2ggY29udGV4dCBmb3VuZC4nLCBzZXNzaW9uSWQ6ICdmb28nfTtcbiAgICAgICAgdGhyb3cgbmV3IGVycm9ycy5Qcm94eVJlcXVlc3RFcnJvcihgQ291bGQgbm90IHByb3h5IGNvbW1hbmQgdG8gcmVtb3RlIHNlcnZlci4gYCwganNvbndwKTtcbiAgICAgIH07XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgdmFsaWRhdGVTdGF0dXM6IG51bGwsXG4gICAgICAgIGRhdGE6IHt1cmw6ICdodHRwOi8vZ29vZ2xlLmNvbSd9LFxuICAgICAgfSk7XG5cbiAgICAgIHN0YXR1cy5zaG91bGQuZXF1YWwoNTAwKTtcbiAgICAgIGRhdGEuc2hvdWxkLmVxbCh7XG4gICAgICAgIHN0YXR1czogMzUsXG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgbWVzc2FnZTogJ05vIHN1Y2ggY29udGV4dCBmb3VuZC4nXG4gICAgICAgIH0sXG4gICAgICAgIHNlc3Npb25JZDogJ2ZvbydcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsZXQgdGhlIHByb3h5IGhhbmRsZSByZXEvcmVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZHJpdmVyLnByb3h5UmVxUmVzID0gYXN5bmMgZnVuY3Rpb24gKHJlcSwgcmVzKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcmVxdWlyZS1hd2FpdFxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7Y3VzdG9tOiAnZGF0YSd9KTtcbiAgICAgIH07XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YToge3VybDogJ2h0dHA6Ly9nb29nbGUuY29tJ31cbiAgICAgIH0pO1xuXG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe2N1c3RvbTogJ2RhdGEnfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGF2b2lkIGpzb253cCBwcm94eWluZyB3aGVuIHBhdGggbWF0Y2hlcyBhdm9pZGFuY2UgbGlzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRyaXZlci5nZXRQcm94eUF2b2lkTGlzdCA9ICgpID0+IFtbJ1BPU1QnLCBuZXcgUmVnRXhwKCdeL3Nlc3Npb24vW14vXSsvdXJsJCcpXV07XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS91cmxgLFxuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgZGF0YToge3VybDogJ2h0dHA6Ly9nb29nbGUuY29tJ30sXG4gICAgICB9KTtcblxuICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgZGF0YS5zaG91bGQuZXFsKHtcbiAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICB2YWx1ZTogJ05hdmlnYXRlZCB0bzogaHR0cDovL2dvb2dsZS5jb20nLFxuICAgICAgICBzZXNzaW9uSWRcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIGF2b2lkIHByb3h5IGxpc3QgaXMgbWFsZm9ybWVkIGluIHNvbWUgd2F5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXN5bmMgZnVuY3Rpb24gYmFkUHJveHlBdm9pZGFuY2VMaXN0IChsaXN0KSB7XG4gICAgICAgIGRyaXZlci5nZXRQcm94eUF2b2lkTGlzdCA9ICgpID0+IGxpc3Q7XG4gICAgICAgIGNvbnN0IHtzdGF0dXMsIGRhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICAgIHVybDogYCR7YmFzZVVybH0vc2Vzc2lvbi8ke3Nlc3Npb25JZH0vdXJsYCxcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICB2YWxpZGF0ZVN0YXR1czogbnVsbCxcbiAgICAgICAgICBkYXRhOiB7dXJsOiAnaHR0cDovL2dvb2dsZS5jb20nfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCg1MDApO1xuICAgICAgICBkYXRhLnN0YXR1cy5zaG91bGQuZXF1YWwoMTMpO1xuICAgICAgICBkYXRhLnZhbHVlLm1lc3NhZ2Uuc2hvdWxkLmNvbnRhaW4oJ3JveHknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxpc3RzID0gW1xuICAgICAgICAnZm9vJyxcbiAgICAgICAgW1snZm9vJ11dLFxuICAgICAgICBbWydCQVInLCAvbG9sL11dLFxuICAgICAgICBbWydHRVQnLCAnZm9vJ11dXG4gICAgICBdO1xuICAgICAgZm9yIChsZXQgbGlzdCBvZiBsaXN0cykge1xuICAgICAgICBhd2FpdCBiYWRQcm94eUF2b2lkYW5jZUxpc3QobGlzdCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGF2b2lkIHByb3h5aW5nIG5vbi1zZXNzaW9uIGNvbW1hbmRzIGV2ZW4gaWYgbm90IGluIHRoZSBsaXN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZHJpdmVyLmdldFByb3h5QXZvaWRMaXN0ID0gKCkgPT4gW1snUE9TVCcsIG5ldyBSZWdFeHAoJycpXV07XG5cbiAgICAgIGNvbnN0IHtzdGF0dXMsIGRhdGF9ID0gYXdhaXQgYXhpb3Moe1xuICAgICAgICB1cmw6IGAke2Jhc2VVcmx9L3N0YXR1c2AsXG4gICAgICB9KTtcblxuICAgICAgc3RhdHVzLnNob3VsZC5lcXVhbCgyMDApO1xuICAgICAgZGF0YS5zaG91bGQuZXFsKHtcbiAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICB2YWx1ZTogXCJJJ20gZmluZVwiLFxuICAgICAgICBzZXNzaW9uSWQ6IG51bGxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhdm9pZCBwcm94eWluZyBkZWxldGVTZXNzaW9uIGNvbW1hbmRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZHJpdmVyLmdldFByb3h5QXZvaWRMaXN0ID0gKCkgPT4gW1snUE9TVCcsIG5ldyBSZWdFeHAoJycpXV07XG5cbiAgICAgIGRyaXZlci5zZXNzaW9uSWQuc2hvdWxkLmVxdWFsKHNlc3Npb25JZCk7XG4gICAgICBjb25zdCB7c3RhdHVzfSA9IGF3YWl0IGF4aW9zLmRlbGV0ZShgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfWApO1xuXG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KGRyaXZlci5zZXNzaW9uSWQpO1xuICAgICAgZHJpdmVyLmp3cFByb3h5QWN0aXZlLnNob3VsZC5iZS5mYWxzZTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYXZvaWQgcHJveHlpbmcgd2hlbiBjb21tYW5kIHNwZWMgc3BlY2lmaWVzIG5ldmVyUHJveHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7c3RhdHVzLCBkYXRhfSA9IGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgJHtiYXNlVXJsfS9zZXNzaW9uLyR7c2Vzc2lvbklkfS9ub3Byb3h5YCxcbiAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIH0pO1xuXG4gICAgICBzdGF0dXMuc2hvdWxkLmVxdWFsKDIwMCk7XG4gICAgICBkYXRhLnNob3VsZC5lcWwoe1xuICAgICAgICBzdGF0dXM6IDAsXG4gICAgICAgIHZhbHVlOiAnVGhpcyB3YXMgbm90IHByb3hpZWQnLFxuICAgICAgICBzZXNzaW9uSWRcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3QvcHJvdG9jb2wvcHJvdG9jb2wtZTJlLXNwZWNzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uIn0=