@appium/base-driver 8.5.7 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/build/lib/basedriver/capabilities.js +2 -2
  2. package/build/lib/basedriver/commands/execute.d.ts +11 -0
  3. package/build/lib/basedriver/commands/execute.d.ts.map +1 -0
  4. package/build/lib/basedriver/commands/execute.js +62 -0
  5. package/build/lib/basedriver/commands/index.d.ts +1 -1
  6. package/build/lib/basedriver/commands/index.d.ts.map +1 -1
  7. package/build/lib/basedriver/commands/index.js +5 -2
  8. package/build/lib/basedriver/commands/log.js +2 -4
  9. package/build/lib/basedriver/core.d.ts +11 -0
  10. package/build/lib/basedriver/core.d.ts.map +1 -1
  11. package/build/lib/basedriver/core.js +6 -1
  12. package/build/lib/basedriver/helpers.js +2 -2
  13. package/build/lib/express/server.d.ts +70 -7
  14. package/build/lib/express/server.d.ts.map +1 -1
  15. package/build/lib/express/server.js +19 -16
  16. package/build/lib/express/websocket.d.ts +12 -30
  17. package/build/lib/express/websocket.d.ts.map +1 -1
  18. package/build/lib/express/websocket.js +6 -4
  19. package/build/lib/index.d.ts +12 -180
  20. package/build/lib/index.d.ts.map +1 -1
  21. package/build/lib/index.js +107 -80
  22. package/build/lib/jsonwp-proxy/protocol-converter.js +2 -4
  23. package/build/lib/jsonwp-proxy/proxy.js +3 -7
  24. package/build/lib/protocol/index.d.ts +3 -1
  25. package/build/lib/protocol/index.js +13 -1
  26. package/build/lib/protocol/protocol.d.ts +8 -4
  27. package/build/lib/protocol/protocol.d.ts.map +1 -1
  28. package/build/lib/protocol/protocol.js +7 -7
  29. package/build/lib/protocol/routes.js +2 -6
  30. package/build/tsconfig.tsbuildinfo +1 -1
  31. package/lib/basedriver/commands/execute.js +65 -0
  32. package/lib/basedriver/commands/index.js +3 -1
  33. package/lib/basedriver/core.js +15 -0
  34. package/lib/express/server.js +126 -36
  35. package/lib/express/websocket.js +13 -11
  36. package/lib/index.js +19 -61
  37. package/lib/protocol/index.js +4 -0
  38. package/lib/protocol/protocol.js +10 -3
  39. package/package.json +17 -15
  40. package/build/test/basedriver/README.md +0 -5
  41. package/build/test/basedriver/driver-e2e-tests.js +0 -413
  42. package/build/test/basedriver/driver-tests.js +0 -572
  43. package/build/test/basedriver/index.js +0 -26
  44. package/build/test/e2e/basedriver/driver.e2e.spec.js +0 -15
  45. package/build/test/e2e/basedriver/helpers.e2e.spec.js +0 -192
  46. package/build/test/e2e/basedriver/websockets.e2e.spec.js +0 -87
  47. package/build/test/e2e/express/server.e2e.spec.js +0 -159
  48. package/build/test/e2e/jsonwp-proxy/proxy.e2e.spec.js +0 -59
  49. package/build/test/e2e/protocol/fake-driver.js +0 -163
  50. package/build/test/e2e/protocol/helpers.js +0 -25
  51. package/build/test/e2e/protocol/protocol.e2e.spec.js +0 -1186
  52. package/build/test/helpers.js +0 -55
  53. package/build/test/unit/basedriver/capabilities.spec.js +0 -672
  54. package/build/test/unit/basedriver/capability.spec.js +0 -353
  55. package/build/test/unit/basedriver/commands/event.spec.js +0 -110
  56. package/build/test/unit/basedriver/commands/log.spec.js +0 -92
  57. package/build/test/unit/basedriver/device-settings.spec.js +0 -97
  58. package/build/test/unit/basedriver/driver.spec.js +0 -15
  59. package/build/test/unit/basedriver/helpers.spec.js +0 -151
  60. package/build/test/unit/basedriver/timeout.spec.js +0 -135
  61. package/build/test/unit/express/server.spec.js +0 -155
  62. package/build/test/unit/express/static.spec.js +0 -26
  63. package/build/test/unit/jsonwp-proxy/mock-request.js +0 -91
  64. package/build/test/unit/jsonwp-proxy/protocol-converter.spec.js +0 -171
  65. package/build/test/unit/jsonwp-proxy/proxy.spec.js +0 -292
  66. package/build/test/unit/jsonwp-proxy/url.spec.js +0 -165
  67. package/build/test/unit/jsonwp-status/status.spec.js +0 -34
  68. package/build/test/unit/protocol/errors.spec.js +0 -390
  69. package/build/test/unit/protocol/routes.spec.js +0 -80
  70. package/build/test/unit/protocol/validator.spec.js +0 -149
  71. package/test/basedriver/README.md +0 -5
  72. package/test/basedriver/driver-e2e-tests.js +0 -386
  73. package/test/basedriver/driver-tests.js +0 -624
  74. package/test/basedriver/index.js +0 -6
@@ -1,390 +0,0 @@
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 _errors = require("../../../lib/protocol/errors");
10
-
11
- var _lodash = _interopRequireDefault(require("lodash"));
12
-
13
- var _httpStatusCodes = require("http-status-codes");
14
-
15
- var _path = _interopRequireDefault(require("path"));
16
-
17
- const basename = _path.default.basename(__filename);
18
-
19
- let errorsList = [{
20
- errorName: 'NoSuchDriverError',
21
- errorMsg: 'A session is either terminated or not started',
22
- error: 'invalid session id',
23
- errorCode: 6
24
- }, {
25
- errorName: 'ElementClickInterceptedError',
26
- errorMsg: 'The Element Click command could not be completed because the element receiving the events is obscuring the element that was requested clicked',
27
- error: 'element click intercepted'
28
- }, {
29
- errorName: 'ElementNotInteractableError',
30
- errorMsg: 'A command could not be completed because the element is not pointer- or keyboard interactable',
31
- error: 'element not interactable'
32
- }, {
33
- errorName: 'InsecureCertificateError',
34
- errorMsg: 'Navigation caused the user agent to hit a certificate warning, which is usually the result of an expired or invalid TLS certificate',
35
- error: 'insecure certificate'
36
- }, {
37
- errorName: 'InvalidArgumentError',
38
- errorMsg: 'The arguments passed to the command are either invalid or malformed',
39
- error: 'invalid argument'
40
- }, {
41
- errorName: 'NoSuchElementError',
42
- errorMsg: 'An element could not be located on the page using the ' + 'given search parameters.',
43
- error: 'no such element',
44
- errorCode: 7
45
- }, {
46
- errorName: 'NoSuchFrameError',
47
- errorMsg: 'A request to switch to a frame could not be satisfied ' + 'because the frame could not be found.',
48
- error: 'no such frame',
49
- errorCode: 8
50
- }, {
51
- errorName: 'UnknownCommandError',
52
- errorMsg: 'The requested resource could not be found, or a request ' + 'was received using an HTTP method that is not supported by ' + 'the mapped resource.',
53
- error: 'unknown command',
54
- errorCode: 9
55
- }, {
56
- errorName: 'StaleElementReferenceError',
57
- errorMsg: 'An element command failed because the referenced element is ' + 'no longer attached to the DOM.',
58
- error: 'stale element reference',
59
- errorCode: 10
60
- }, {
61
- errorName: 'ElementNotVisibleError',
62
- errorMsg: 'An element command could not be completed because the ' + 'element is not visible on the page.',
63
- errorCode: 11
64
- }, {
65
- errorName: 'InvalidElementStateError',
66
- errorMsg: 'An element command could not be completed because the element ' + 'is in an invalid state (e.g. attempting to click a disabled ' + 'element).',
67
- error: 'invalid element state',
68
- errorCode: 12
69
- }, {
70
- errorName: 'UnknownError',
71
- errorMsg: 'An unknown server-side error occurred while processing the ' + 'command.',
72
- error: 'unknown error',
73
- errorCode: 13
74
- }, {
75
- errorName: 'ElementIsNotSelectableError',
76
- errorMsg: 'An attempt was made to select an element that cannot ' + 'be selected.',
77
- error: 'element not selectable',
78
- errorCode: 15
79
- }, {
80
- errorName: 'JavaScriptError',
81
- errorMsg: 'An error occurred while executing user supplied JavaScript.',
82
- error: 'javascript error',
83
- errorCode: 17
84
- }, {
85
- errorName: 'XPathLookupError',
86
- errorMsg: 'An error occurred while searching for an element by XPath.',
87
- errorCode: 19
88
- }, {
89
- errorName: 'TimeoutError',
90
- errorMsg: 'An operation did not complete before its timeout expired.',
91
- error: 'timeout',
92
- errorCode: 21
93
- }, {
94
- errorName: 'NoSuchWindowError',
95
- errorMsg: 'A request to switch to a different window could not be ' + 'satisfied because the window could not be found.',
96
- error: 'no such window',
97
- errorCode: 23
98
- }, {
99
- errorName: 'InvalidCookieDomainError',
100
- errorMsg: 'An illegal attempt was made to set a cookie under a different ' + 'domain than the current page.',
101
- error: 'invalid cookie domain',
102
- errorCode: 24
103
- }, {
104
- errorName: 'InvalidCoordinatesError',
105
- errorMsg: 'The coordinates provided to an interactions operation are invalid.',
106
- error: 'invalid coordinates'
107
- }, {
108
- errorName: 'UnableToSetCookieError',
109
- errorMsg: `A request to set a cookie's value could not be satisfied.`,
110
- error: 'unable to set cookie',
111
- errorCode: 25
112
- }, {
113
- errorName: 'UnexpectedAlertOpenError',
114
- errorMsg: 'A modal dialog was open, blocking this operation',
115
- error: 'unexpected alert open',
116
- errorCode: 26
117
- }, {
118
- errorName: 'NoAlertOpenError',
119
- errorMsg: 'An attempt was made to operate on a modal dialog when one was ' + 'not open.',
120
- errorCode: 27
121
- }, {
122
- errorName: 'ScriptTimeoutError',
123
- errorMsg: 'A script did not complete before its timeout expired.',
124
- error: 'script timeout',
125
- errorCode: 28
126
- }, {
127
- errorName: 'InvalidElementCoordinatesError',
128
- errorMsg: 'The coordinates provided to an interactions operation are ' + 'invalid.',
129
- errorCode: 29
130
- }, {
131
- errorName: 'IMENotAvailableError',
132
- errorMsg: 'IME was not available.',
133
- errorCode: 30
134
- }, {
135
- errorName: 'IMEEngineActivationFailedError',
136
- errorMsg: 'An IME engine could not be started.',
137
- errorCode: 31
138
- }, {
139
- errorName: 'InvalidSelectorError',
140
- errorMsg: 'Argument was an invalid selector (e.g. XPath/CSS).',
141
- error: 'invalid selector',
142
- errorCode: 32
143
- }, {
144
- errorName: 'SessionNotCreatedError',
145
- errorMsg: 'A new session could not be created.',
146
- error: 'session not created',
147
- errorCode: 33
148
- }, {
149
- errorName: 'MoveTargetOutOfBoundsError',
150
- errorMsg: 'Target provided for a move action is out of bounds.',
151
- error: 'move target out of bounds',
152
- errorCode: 34
153
- }, {
154
- errorName: 'NoSuchAlertError',
155
- errorMsg: 'An attempt was made to operate on a modal dialog when one was not open.',
156
- error: 'no such alert'
157
- }, {
158
- errorName: 'NoSuchCookieError',
159
- errorMsg: 'No cookie matching the given path name was found amongst the associated cookies of the current browsing context’s active document',
160
- error: 'no such cookie'
161
- }, {
162
- errorName: 'NotYetImplementedError',
163
- errorMsg: 'Method has not yet been implemented',
164
- error: 'unknown method',
165
- errorCode: 405
166
- }, {
167
- errorName: 'UnknownCommandError',
168
- errorMsg: 'The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.',
169
- error: 'unknown command'
170
- }, {
171
- errorName: 'UnknownMethodError',
172
- errorMsg: 'The requested command matched a known URL but did not match an method for that URL',
173
- error: 'unknown method'
174
- }, {
175
- errorName: 'UnsupportedOperationError',
176
- errorMsg: 'A server-side error occurred. Command cannot be supported.',
177
- error: 'unsupported operation'
178
- }];
179
- describe('errors', function () {
180
- for (let error of errorsList) {
181
- it(error.errorName + ' should have a JSONWP code or W3C code and message', function () {
182
- if (error.errorCode) {
183
- new _lib.errors[error.errorName]().should.have.property('jsonwpCode', error.errorCode);
184
- } else {
185
- new _lib.errors[error.errorName]().should.have.property('error', error.error);
186
- }
187
-
188
- new _lib.errors[error.errorName]().should.have.property('message', error.errorMsg);
189
- });
190
- }
191
-
192
- it('BadParametersError should not have code and should have messg', function () {
193
- new _lib.errors.BadParametersError().should.not.have.property('jsonwpCode');
194
- new _lib.errors.BadParametersError().should.have.property('message');
195
- });
196
- it('ProxyRequestError should have message and jsonwp', function () {
197
- new _lib.errors.ProxyRequestError().should.have.property('jsonwp');
198
- new _lib.errors.ProxyRequestError().should.have.property('message');
199
- });
200
- });
201
- describe('errorFromMJSONWPStatusCode', function () {
202
- for (let error of errorsList) {
203
- if (error.errorName !== 'NotYetImplementedError') {
204
- it(error.errorCode + ' should return correct error', function () {
205
- if (error.errorCode) {
206
- (0, _lib.errorFromMJSONWPStatusCode)(error.errorCode).should.have.property('jsonwpCode', error.errorCode);
207
- (0, _lib.errorFromMJSONWPStatusCode)(error.errorCode).should.have.property('message', error.errorMsg);
208
-
209
- if (!_lodash.default.includes([13, 33], error.errorCode)) {
210
- (0, _lib.errorFromMJSONWPStatusCode)(error.errorCode, 'abcd').should.have.property('jsonwpCode', error.errorCode);
211
- (0, _lib.errorFromMJSONWPStatusCode)(error.errorCode, 'abcd').should.have.property('message', 'abcd');
212
- }
213
- } else {
214
- (0, _lib.isErrorType)((0, _lib.errorFromMJSONWPStatusCode)(error.errorCode), _lib.errors.UnknownError).should.be.true;
215
- }
216
- });
217
- }
218
- }
219
-
220
- it('should throw unknown error for unknown code', function () {
221
- (0, _lib.errorFromMJSONWPStatusCode)(99).should.have.property('jsonwpCode', 13);
222
- (0, _lib.errorFromMJSONWPStatusCode)(99).should.have.property('message', 'An unknown server-side error occurred ' + 'while processing the command.');
223
- });
224
- });
225
- describe('errorFromW3CJsonCode', function () {
226
- for (let error of errorsList) {
227
- if (error.errorName !== 'NotYetImplementedError') {
228
- it(error.errorName + ' should return correct error', function () {
229
- const {
230
- error: w3cError
231
- } = error;
232
-
233
- if (w3cError) {
234
- (0, _lib.errorFromW3CJsonCode)(w3cError).error.should.equal(error.error);
235
- (0, _lib.errorFromW3CJsonCode)(w3cError).should.have.property('message', error.errorMsg);
236
- } else {
237
- (0, _lib.isErrorType)((0, _lib.errorFromW3CJsonCode)(w3cError), _lib.errors.UnknownError).should.be.true;
238
- }
239
- });
240
- }
241
- }
242
-
243
- it('should parse unknown errors', function () {
244
- (0, _lib.isErrorType)((0, _lib.errorFromW3CJsonCode)('not a real error code'), _lib.errors.UnknownError).should.be.true;
245
- (0, _lib.errorFromW3CJsonCode)('not a real error code').message.should.match(/An unknown server-side error occurred/);
246
- (0, _lib.errorFromW3CJsonCode)('not a real error code').error.should.equal('unknown error');
247
- });
248
- });
249
- describe('w3c Status Codes', function () {
250
- it('should match the correct error codes', function () {
251
- let non400Errors = [['NoSuchDriverError', 404], ['NoSuchFrameError', 404], ['NoAlertOpenError', 404], ['NoSuchWindowError', 404], ['StaleElementReferenceError', 404], ['JavaScriptError', 500], ['MoveTargetOutOfBoundsError', 500], ['NoSuchCookieError', 404], ['NoSuchElementError', 404], ['ScriptTimeoutError', 408], ['SessionNotCreatedError', 500], ['TimeoutError', 408], ['UnableToSetCookieError', 500], ['UnableToCaptureScreen', 500], ['UnexpectedAlertOpenError', 500], ['UnknownCommandError', 404], ['UnknownError', 500], ['UnknownMethodError', 405], ['UnsupportedOperationError', 500]];
252
-
253
- for (let [errorName, expectedErrorCode] of non400Errors) {
254
- _lib.errors[errorName].should.exist;
255
- new _lib.errors[errorName]().should.have.property('w3cStatus', expectedErrorCode);
256
- }
257
-
258
- new _lib.errors.ElementClickInterceptedError().should.have.property('w3cStatus', 400);
259
- });
260
- });
261
- describe('.getResponseForW3CError', function () {
262
- it('should return an error, message and stacktrace for just a generic exception', function () {
263
- try {
264
- throw new Error('Some random error');
265
- } catch (e) {
266
- const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)(e);
267
- httpStatus.should.equal(500);
268
- const {
269
- error,
270
- message,
271
- stacktrace
272
- } = httpResponseBody.value;
273
- message.should.match(/Some random error/);
274
- error.should.equal('unknown error');
275
- stacktrace.should.match(/at getResponseForW3CError/);
276
- stacktrace.should.match(/Some random error/);
277
- stacktrace.should.contain(basename);
278
- }
279
- });
280
- it('should return an error, message and stacktrace for a NoSuchElementError', function () {
281
- const noSuchElementError = new _lib.errors.NoSuchElementError('specific error message');
282
- const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)(noSuchElementError);
283
- httpStatus.should.equal(404);
284
- const {
285
- error,
286
- message,
287
- stacktrace
288
- } = httpResponseBody.value;
289
- error.should.equal('no such element');
290
- message.should.match(/specific error message/);
291
- stacktrace.should.contain(basename);
292
- });
293
- it('should handle BadParametersError', function () {
294
- const badParamsError = new _lib.errors.BadParametersError('__FOO__', '__BAR__', '__HELLO_WORLD__');
295
- const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)(badParamsError);
296
- httpStatus.should.equal(400);
297
- const {
298
- error,
299
- message,
300
- stacktrace
301
- } = httpResponseBody.value;
302
- error.should.equal('invalid argument');
303
- message.should.match(/__BAR__/);
304
- message.should.match(/__HELLO_WORLD__/);
305
- stacktrace.should.contain(basename);
306
- });
307
- it('should translate JSONWP errors', function () {
308
- const [httpStatus, httpResponseBody] = (0, _errors.getResponseForW3CError)({
309
- status: 7,
310
- value: 'My custom message',
311
- sessionId: 'Fake Session Id'
312
- });
313
- httpStatus.should.equal(404);
314
- const {
315
- error,
316
- message,
317
- stacktrace
318
- } = httpResponseBody.value;
319
- message.should.equal('My custom message');
320
- error.should.equal('no such element');
321
- stacktrace.should.exist;
322
- });
323
- });
324
- describe('.getActualError', function () {
325
- describe('MJSONWP', function () {
326
- it('should map a status code 7 no such element error as a NoSuchElementError', function () {
327
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
328
- value: 'does not matter',
329
- status: 7
330
- }).getActualError();
331
- (0, _lib.isErrorType)(actualError, _lib.errors.NoSuchElementError).should.be.true;
332
- });
333
- it('should map a status code 10, StaleElementReferenceError', function () {
334
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
335
- value: 'Does not matter',
336
- status: 10
337
- }).getActualError();
338
- (0, _lib.isErrorType)(actualError, _lib.errors.StaleElementReferenceError).should.be.true;
339
- });
340
- it('should map an unknown error to UnknownError', function () {
341
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
342
- value: 'Does not matter',
343
- status: -100
344
- }).getActualError();
345
- (0, _lib.isErrorType)(actualError, _lib.errors.UnknownError).should.be.true;
346
- });
347
- it('should parse a JSON string', function () {
348
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', JSON.stringify({
349
- value: 'Does not matter',
350
- status: -100
351
- })).getActualError();
352
- (0, _lib.isErrorType)(actualError, _lib.errors.UnknownError).should.be.true;
353
- });
354
- });
355
- describe('W3C', function () {
356
- it('should map a 404 no such element error as a NoSuchElementError', function () {
357
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
358
- value: {
359
- error: _lib.errors.NoSuchElementError.error()
360
- }
361
- }, _httpStatusCodes.StatusCodes.NOT_FOUND).getActualError();
362
- (0, _lib.isErrorType)(actualError, _lib.errors.NoSuchElementError).should.be.true;
363
- });
364
- it('should map a 400 StaleElementReferenceError', function () {
365
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', {
366
- value: {
367
- error: _lib.errors.StaleElementReferenceError.error()
368
- }
369
- }, _httpStatusCodes.StatusCodes.BAD_REQUEST).getActualError();
370
- (0, _lib.isErrorType)(actualError, _lib.errors.StaleElementReferenceError).should.be.true;
371
- });
372
- it('should map an unknown error to UnknownError', function () {
373
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', null, {
374
- value: {
375
- error: 'Not a valid w3c JSON code'
376
- }
377
- }, 456).getActualError();
378
- (0, _lib.isErrorType)(actualError, _lib.errors.UnknownError).should.be.true;
379
- });
380
- it('should parse a JSON string', function () {
381
- const actualError = new _lib.errors.ProxyRequestError('Error message does not matter', JSON.stringify({
382
- value: {
383
- error: _lib.errors.StaleElementReferenceError.error()
384
- }
385
- }), _httpStatusCodes.StatusCodes.BAD_REQUEST).getActualError();
386
- (0, _lib.isErrorType)(actualError, _lib.errors.StaleElementReferenceError).should.be.true;
387
- });
388
- });
389
- });
390
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJiYXNlbmFtZSIsInBhdGgiLCJfX2ZpbGVuYW1lIiwiZXJyb3JzTGlzdCIsImVycm9yTmFtZSIsImVycm9yTXNnIiwiZXJyb3IiLCJlcnJvckNvZGUiLCJkZXNjcmliZSIsIml0IiwiZXJyb3JzIiwic2hvdWxkIiwiaGF2ZSIsInByb3BlcnR5IiwiQmFkUGFyYW1ldGVyc0Vycm9yIiwibm90IiwiUHJveHlSZXF1ZXN0RXJyb3IiLCJlcnJvckZyb21NSlNPTldQU3RhdHVzQ29kZSIsIl8iLCJpbmNsdWRlcyIsImlzRXJyb3JUeXBlIiwiVW5rbm93bkVycm9yIiwiYmUiLCJ0cnVlIiwidzNjRXJyb3IiLCJlcnJvckZyb21XM0NKc29uQ29kZSIsImVxdWFsIiwibWVzc2FnZSIsIm1hdGNoIiwibm9uNDAwRXJyb3JzIiwiZXhwZWN0ZWRFcnJvckNvZGUiLCJleGlzdCIsIkVsZW1lbnRDbGlja0ludGVyY2VwdGVkRXJyb3IiLCJFcnJvciIsImUiLCJodHRwU3RhdHVzIiwiaHR0cFJlc3BvbnNlQm9keSIsImdldFJlc3BvbnNlRm9yVzNDRXJyb3IiLCJzdGFja3RyYWNlIiwidmFsdWUiLCJjb250YWluIiwibm9TdWNoRWxlbWVudEVycm9yIiwiTm9TdWNoRWxlbWVudEVycm9yIiwiYmFkUGFyYW1zRXJyb3IiLCJzdGF0dXMiLCJzZXNzaW9uSWQiLCJhY3R1YWxFcnJvciIsImdldEFjdHVhbEVycm9yIiwiU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwiSFRUUFN0YXR1c0NvZGVzIiwiTk9UX0ZPVU5EIiwiQkFEX1JFUVVFU1QiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvcHJvdG9jb2wvZXJyb3JzLnNwZWMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtlcnJvcnMsIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlLCBlcnJvckZyb21XM0NKc29uQ29kZSwgaXNFcnJvclR5cGV9IGZyb20gJy4uLy4uLy4uL2xpYic7XG5pbXBvcnQge2dldFJlc3BvbnNlRm9yVzNDRXJyb3J9IGZyb20gJy4uLy4uLy4uL2xpYi9wcm90b2NvbC9lcnJvcnMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7U3RhdHVzQ29kZXMgYXMgSFRUUFN0YXR1c0NvZGVzfSBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuY29uc3QgYmFzZW5hbWUgPSBwYXRoLmJhc2VuYW1lKF9fZmlsZW5hbWUpO1xuXG4vLyBFcnJvciBjb2RlcyBhbmQgbWVzc2FnZXMgaGF2ZSBiZWVuIGFkZGVkIGFjY29yZGluZyB0byBKc29uV2lyZVByb3RvY29sIHNlZVxuLy8gaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9zZWxlbml1bS93aWtpL0pzb25XaXJlUHJvdG9jb2wjUmVzcG9uc2VfU3RhdHVzX0NvZGVzXG5sZXQgZXJyb3JzTGlzdCA9IFtcbiAge1xuICAgIGVycm9yTmFtZTogJ05vU3VjaERyaXZlckVycm9yJyxcbiAgICBlcnJvck1zZzogJ0Egc2Vzc2lvbiBpcyBlaXRoZXIgdGVybWluYXRlZCBvciBub3Qgc3RhcnRlZCcsXG4gICAgZXJyb3I6ICdpbnZhbGlkIHNlc3Npb24gaWQnLFxuICAgIGVycm9yQ29kZTogNixcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0VsZW1lbnRDbGlja0ludGVyY2VwdGVkRXJyb3InLFxuICAgIGVycm9yTXNnOlxuICAgICAgJ1RoZSBFbGVtZW50IENsaWNrIGNvbW1hbmQgY291bGQgbm90IGJlIGNvbXBsZXRlZCBiZWNhdXNlIHRoZSBlbGVtZW50IHJlY2VpdmluZyB0aGUgZXZlbnRzIGlzIG9ic2N1cmluZyB0aGUgZWxlbWVudCB0aGF0IHdhcyByZXF1ZXN0ZWQgY2xpY2tlZCcsXG4gICAgZXJyb3I6ICdlbGVtZW50IGNsaWNrIGludGVyY2VwdGVkJyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0VsZW1lbnROb3RJbnRlcmFjdGFibGVFcnJvcicsXG4gICAgZXJyb3JNc2c6XG4gICAgICAnQSBjb21tYW5kIGNvdWxkIG5vdCBiZSBjb21wbGV0ZWQgYmVjYXVzZSB0aGUgZWxlbWVudCBpcyBub3QgcG9pbnRlci0gb3Iga2V5Ym9hcmQgaW50ZXJhY3RhYmxlJyxcbiAgICBlcnJvcjogJ2VsZW1lbnQgbm90IGludGVyYWN0YWJsZScsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJbnNlY3VyZUNlcnRpZmljYXRlRXJyb3InLFxuICAgIGVycm9yTXNnOlxuICAgICAgJ05hdmlnYXRpb24gY2F1c2VkIHRoZSB1c2VyIGFnZW50IHRvIGhpdCBhIGNlcnRpZmljYXRlIHdhcm5pbmcsIHdoaWNoIGlzIHVzdWFsbHkgdGhlIHJlc3VsdCBvZiBhbiBleHBpcmVkIG9yIGludmFsaWQgVExTIGNlcnRpZmljYXRlJyxcbiAgICBlcnJvcjogJ2luc2VjdXJlIGNlcnRpZmljYXRlJyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0ludmFsaWRBcmd1bWVudEVycm9yJyxcbiAgICBlcnJvck1zZzogJ1RoZSBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBjb21tYW5kIGFyZSBlaXRoZXIgaW52YWxpZCBvciBtYWxmb3JtZWQnLFxuICAgIGVycm9yOiAnaW52YWxpZCBhcmd1bWVudCcsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdOb1N1Y2hFbGVtZW50RXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gZWxlbWVudCBjb3VsZCBub3QgYmUgbG9jYXRlZCBvbiB0aGUgcGFnZSB1c2luZyB0aGUgJyArICdnaXZlbiBzZWFyY2ggcGFyYW1ldGVycy4nLFxuICAgIGVycm9yOiAnbm8gc3VjaCBlbGVtZW50JyxcbiAgICBlcnJvckNvZGU6IDcsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdOb1N1Y2hGcmFtZUVycm9yJyxcbiAgICBlcnJvck1zZzpcbiAgICAgICdBIHJlcXVlc3QgdG8gc3dpdGNoIHRvIGEgZnJhbWUgY291bGQgbm90IGJlIHNhdGlzZmllZCAnICtcbiAgICAgICdiZWNhdXNlIHRoZSBmcmFtZSBjb3VsZCBub3QgYmUgZm91bmQuJyxcbiAgICBlcnJvcjogJ25vIHN1Y2ggZnJhbWUnLFxuICAgIGVycm9yQ29kZTogOCxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ1Vua25vd25Db21tYW5kRXJyb3InLFxuICAgIGVycm9yTXNnOlxuICAgICAgJ1RoZSByZXF1ZXN0ZWQgcmVzb3VyY2UgY291bGQgbm90IGJlIGZvdW5kLCBvciBhIHJlcXVlc3QgJyArXG4gICAgICAnd2FzIHJlY2VpdmVkIHVzaW5nIGFuIEhUVFAgbWV0aG9kIHRoYXQgaXMgbm90IHN1cHBvcnRlZCBieSAnICtcbiAgICAgICd0aGUgbWFwcGVkIHJlc291cmNlLicsXG4gICAgZXJyb3I6ICd1bmtub3duIGNvbW1hbmQnLFxuICAgIGVycm9yQ29kZTogOSxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ1N0YWxlRWxlbWVudFJlZmVyZW5jZUVycm9yJyxcbiAgICBlcnJvck1zZzpcbiAgICAgICdBbiBlbGVtZW50IGNvbW1hbmQgZmFpbGVkIGJlY2F1c2UgdGhlIHJlZmVyZW5jZWQgZWxlbWVudCBpcyAnICtcbiAgICAgICdubyBsb25nZXIgYXR0YWNoZWQgdG8gdGhlIERPTS4nLFxuICAgIGVycm9yOiAnc3RhbGUgZWxlbWVudCByZWZlcmVuY2UnLFxuICAgIGVycm9yQ29kZTogMTAsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdFbGVtZW50Tm90VmlzaWJsZUVycm9yJyxcbiAgICBlcnJvck1zZzpcbiAgICAgICdBbiBlbGVtZW50IGNvbW1hbmQgY291bGQgbm90IGJlIGNvbXBsZXRlZCBiZWNhdXNlIHRoZSAnICtcbiAgICAgICdlbGVtZW50IGlzIG5vdCB2aXNpYmxlIG9uIHRoZSBwYWdlLicsXG4gICAgZXJyb3JDb2RlOiAxMSxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0ludmFsaWRFbGVtZW50U3RhdGVFcnJvcicsXG4gICAgZXJyb3JNc2c6XG4gICAgICAnQW4gZWxlbWVudCBjb21tYW5kIGNvdWxkIG5vdCBiZSBjb21wbGV0ZWQgYmVjYXVzZSB0aGUgZWxlbWVudCAnICtcbiAgICAgICdpcyBpbiBhbiBpbnZhbGlkIHN0YXRlIChlLmcuIGF0dGVtcHRpbmcgdG8gY2xpY2sgYSBkaXNhYmxlZCAnICtcbiAgICAgICdlbGVtZW50KS4nLFxuICAgIGVycm9yOiAnaW52YWxpZCBlbGVtZW50IHN0YXRlJyxcbiAgICBlcnJvckNvZGU6IDEyLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVW5rbm93bkVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIHVua25vd24gc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyB0aGUgJyArICdjb21tYW5kLicsXG4gICAgZXJyb3I6ICd1bmtub3duIGVycm9yJyxcbiAgICBlcnJvckNvZGU6IDEzLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnRWxlbWVudElzTm90U2VsZWN0YWJsZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIGF0dGVtcHQgd2FzIG1hZGUgdG8gc2VsZWN0IGFuIGVsZW1lbnQgdGhhdCBjYW5ub3QgJyArICdiZSBzZWxlY3RlZC4nLFxuICAgIGVycm9yOiAnZWxlbWVudCBub3Qgc2VsZWN0YWJsZScsXG4gICAgZXJyb3JDb2RlOiAxNSxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0phdmFTY3JpcHRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBleGVjdXRpbmcgdXNlciBzdXBwbGllZCBKYXZhU2NyaXB0LicsXG4gICAgZXJyb3I6ICdqYXZhc2NyaXB0IGVycm9yJyxcbiAgICBlcnJvckNvZGU6IDE3LFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnWFBhdGhMb29rdXBFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBzZWFyY2hpbmcgZm9yIGFuIGVsZW1lbnQgYnkgWFBhdGguJyxcbiAgICBlcnJvckNvZGU6IDE5LFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVGltZW91dEVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIG9wZXJhdGlvbiBkaWQgbm90IGNvbXBsZXRlIGJlZm9yZSBpdHMgdGltZW91dCBleHBpcmVkLicsXG4gICAgZXJyb3I6ICd0aW1lb3V0JyxcbiAgICBlcnJvckNvZGU6IDIxLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnTm9TdWNoV2luZG93RXJyb3InLFxuICAgIGVycm9yTXNnOlxuICAgICAgJ0EgcmVxdWVzdCB0byBzd2l0Y2ggdG8gYSBkaWZmZXJlbnQgd2luZG93IGNvdWxkIG5vdCBiZSAnICtcbiAgICAgICdzYXRpc2ZpZWQgYmVjYXVzZSB0aGUgd2luZG93IGNvdWxkIG5vdCBiZSBmb3VuZC4nLFxuICAgIGVycm9yOiAnbm8gc3VjaCB3aW5kb3cnLFxuICAgIGVycm9yQ29kZTogMjMsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJbnZhbGlkQ29va2llRG9tYWluRXJyb3InLFxuICAgIGVycm9yTXNnOlxuICAgICAgJ0FuIGlsbGVnYWwgYXR0ZW1wdCB3YXMgbWFkZSB0byBzZXQgYSBjb29raWUgdW5kZXIgYSBkaWZmZXJlbnQgJyArXG4gICAgICAnZG9tYWluIHRoYW4gdGhlIGN1cnJlbnQgcGFnZS4nLFxuICAgIGVycm9yOiAnaW52YWxpZCBjb29raWUgZG9tYWluJyxcbiAgICBlcnJvckNvZGU6IDI0LFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnSW52YWxpZENvb3JkaW5hdGVzRXJyb3InLFxuICAgIGVycm9yTXNnOiAnVGhlIGNvb3JkaW5hdGVzIHByb3ZpZGVkIHRvIGFuIGludGVyYWN0aW9ucyBvcGVyYXRpb24gYXJlIGludmFsaWQuJyxcbiAgICBlcnJvcjogJ2ludmFsaWQgY29vcmRpbmF0ZXMnLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVW5hYmxlVG9TZXRDb29raWVFcnJvcicsXG4gICAgZXJyb3JNc2c6IGBBIHJlcXVlc3QgdG8gc2V0IGEgY29va2llJ3MgdmFsdWUgY291bGQgbm90IGJlIHNhdGlzZmllZC5gLFxuICAgIGVycm9yOiAndW5hYmxlIHRvIHNldCBjb29raWUnLFxuICAgIGVycm9yQ29kZTogMjUsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdVbmV4cGVjdGVkQWxlcnRPcGVuRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQSBtb2RhbCBkaWFsb2cgd2FzIG9wZW4sIGJsb2NraW5nIHRoaXMgb3BlcmF0aW9uJyxcbiAgICBlcnJvcjogJ3VuZXhwZWN0ZWQgYWxlcnQgb3BlbicsXG4gICAgZXJyb3JDb2RlOiAyNixcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ05vQWxlcnRPcGVuRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBvcGVyYXRlIG9uIGEgbW9kYWwgZGlhbG9nIHdoZW4gb25lIHdhcyAnICsgJ25vdCBvcGVuLicsXG4gICAgZXJyb3JDb2RlOiAyNyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ1NjcmlwdFRpbWVvdXRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBIHNjcmlwdCBkaWQgbm90IGNvbXBsZXRlIGJlZm9yZSBpdHMgdGltZW91dCBleHBpcmVkLicsXG4gICAgZXJyb3I6ICdzY3JpcHQgdGltZW91dCcsXG4gICAgZXJyb3JDb2RlOiAyOCxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0ludmFsaWRFbGVtZW50Q29vcmRpbmF0ZXNFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdUaGUgY29vcmRpbmF0ZXMgcHJvdmlkZWQgdG8gYW4gaW50ZXJhY3Rpb25zIG9wZXJhdGlvbiBhcmUgJyArICdpbnZhbGlkLicsXG4gICAgZXJyb3JDb2RlOiAyOSxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ0lNRU5vdEF2YWlsYWJsZUVycm9yJyxcbiAgICBlcnJvck1zZzogJ0lNRSB3YXMgbm90IGF2YWlsYWJsZS4nLFxuICAgIGVycm9yQ29kZTogMzAsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJTUVFbmdpbmVBY3RpdmF0aW9uRmFpbGVkRXJyb3InLFxuICAgIGVycm9yTXNnOiAnQW4gSU1FIGVuZ2luZSBjb3VsZCBub3QgYmUgc3RhcnRlZC4nLFxuICAgIGVycm9yQ29kZTogMzEsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdJbnZhbGlkU2VsZWN0b3JFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBcmd1bWVudCB3YXMgYW4gaW52YWxpZCBzZWxlY3RvciAoZS5nLiBYUGF0aC9DU1MpLicsXG4gICAgZXJyb3I6ICdpbnZhbGlkIHNlbGVjdG9yJyxcbiAgICBlcnJvckNvZGU6IDMyLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnU2Vzc2lvbk5vdENyZWF0ZWRFcnJvcicsXG4gICAgZXJyb3JNc2c6ICdBIG5ldyBzZXNzaW9uIGNvdWxkIG5vdCBiZSBjcmVhdGVkLicsXG4gICAgZXJyb3I6ICdzZXNzaW9uIG5vdCBjcmVhdGVkJyxcbiAgICBlcnJvckNvZGU6IDMzLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnTW92ZVRhcmdldE91dE9mQm91bmRzRXJyb3InLFxuICAgIGVycm9yTXNnOiAnVGFyZ2V0IHByb3ZpZGVkIGZvciBhIG1vdmUgYWN0aW9uIGlzIG91dCBvZiBib3VuZHMuJyxcbiAgICBlcnJvcjogJ21vdmUgdGFyZ2V0IG91dCBvZiBib3VuZHMnLFxuICAgIGVycm9yQ29kZTogMzQsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdOb1N1Y2hBbGVydEVycm9yJyxcbiAgICBlcnJvck1zZzogJ0FuIGF0dGVtcHQgd2FzIG1hZGUgdG8gb3BlcmF0ZSBvbiBhIG1vZGFsIGRpYWxvZyB3aGVuIG9uZSB3YXMgbm90IG9wZW4uJyxcbiAgICBlcnJvcjogJ25vIHN1Y2ggYWxlcnQnLFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnTm9TdWNoQ29va2llRXJyb3InLFxuICAgIGVycm9yTXNnOlxuICAgICAgJ05vIGNvb2tpZSBtYXRjaGluZyB0aGUgZ2l2ZW4gcGF0aCBuYW1lIHdhcyBmb3VuZCBhbW9uZ3N0IHRoZSBhc3NvY2lhdGVkIGNvb2tpZXMgb2YgdGhlIGN1cnJlbnQgYnJvd3NpbmcgY29udGV4dOKAmXMgYWN0aXZlIGRvY3VtZW50JyxcbiAgICBlcnJvcjogJ25vIHN1Y2ggY29va2llJyxcbiAgfSxcbiAge1xuICAgIGVycm9yTmFtZTogJ05vdFlldEltcGxlbWVudGVkRXJyb3InLFxuICAgIGVycm9yTXNnOiAnTWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gaW1wbGVtZW50ZWQnLFxuICAgIGVycm9yOiAndW5rbm93biBtZXRob2QnLFxuICAgIGVycm9yQ29kZTogNDA1LFxuICB9LFxuICB7XG4gICAgZXJyb3JOYW1lOiAnVW5rbm93bkNvbW1hbmRFcnJvcicsXG4gICAgZXJyb3JNc2c6XG4gICAgICAnVGhlIHJlcXVlc3RlZCByZXNvdXJjZSBjb3VsZCBub3QgYmUgZm91bmQsIG9yIGEgcmVxdWVzdCB3YXMgcmVjZWl2ZWQgdXNpbmcgYW4gSFRUUCBtZXRob2QgdGhhdCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXBwZWQgcmVzb3VyY2UuJyxcbiAgICBlcnJvcjogJ3Vua25vd24gY29tbWFuZCcsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdVbmtub3duTWV0aG9kRXJyb3InLFxuICAgIGVycm9yTXNnOiAnVGhlIHJlcXVlc3RlZCBjb21tYW5kIG1hdGNoZWQgYSBrbm93biBVUkwgYnV0IGRpZCBub3QgbWF0Y2ggYW4gbWV0aG9kIGZvciB0aGF0IFVSTCcsXG4gICAgZXJyb3I6ICd1bmtub3duIG1ldGhvZCcsXG4gIH0sXG4gIHtcbiAgICBlcnJvck5hbWU6ICdVbnN1cHBvcnRlZE9wZXJhdGlvbkVycm9yJyxcbiAgICBlcnJvck1zZzogJ0Egc2VydmVyLXNpZGUgZXJyb3Igb2NjdXJyZWQuIENvbW1hbmQgY2Fubm90IGJlIHN1cHBvcnRlZC4nLFxuICAgIGVycm9yOiAndW5zdXBwb3J0ZWQgb3BlcmF0aW9uJyxcbiAgfSxcbl07XG5cbmRlc2NyaWJlKCdlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gIGZvciAobGV0IGVycm9yIG9mIGVycm9yc0xpc3QpIHtcbiAgICBpdChlcnJvci5lcnJvck5hbWUgKyAnIHNob3VsZCBoYXZlIGEgSlNPTldQIGNvZGUgb3IgVzNDIGNvZGUgYW5kIG1lc3NhZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoZXJyb3IuZXJyb3JDb2RlKSB7XG4gICAgICAgIG5ldyBlcnJvcnNbZXJyb3IuZXJyb3JOYW1lXSgpLnNob3VsZC5oYXZlLnByb3BlcnR5KCdqc29ud3BDb2RlJywgZXJyb3IuZXJyb3JDb2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ldyBlcnJvcnNbZXJyb3IuZXJyb3JOYW1lXSgpLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlcnJvcicsIGVycm9yLmVycm9yKTtcbiAgICAgIH1cbiAgICAgIG5ldyBlcnJvcnNbZXJyb3IuZXJyb3JOYW1lXSgpLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtZXNzYWdlJywgZXJyb3IuZXJyb3JNc2cpO1xuICAgIH0pO1xuICB9XG4gIGl0KCdCYWRQYXJhbWV0ZXJzRXJyb3Igc2hvdWxkIG5vdCBoYXZlIGNvZGUgYW5kIHNob3VsZCBoYXZlIG1lc3NnJywgZnVuY3Rpb24gKCkge1xuICAgIG5ldyBlcnJvcnMuQmFkUGFyYW1ldGVyc0Vycm9yKCkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdqc29ud3BDb2RlJyk7XG4gICAgbmV3IGVycm9ycy5CYWRQYXJhbWV0ZXJzRXJyb3IoKS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWVzc2FnZScpO1xuICB9KTtcbiAgaXQoJ1Byb3h5UmVxdWVzdEVycm9yIHNob3VsZCBoYXZlIG1lc3NhZ2UgYW5kIGpzb253cCcsIGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKCkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2pzb253cCcpO1xuICAgIG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoKS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWVzc2FnZScpO1xuICB9KTtcbn0pO1xuZGVzY3JpYmUoJ2Vycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlJywgZnVuY3Rpb24gKCkge1xuICBmb3IgKGxldCBlcnJvciBvZiBlcnJvcnNMaXN0KSB7XG4gICAgaWYgKGVycm9yLmVycm9yTmFtZSAhPT0gJ05vdFlldEltcGxlbWVudGVkRXJyb3InKSB7XG4gICAgICBpdChlcnJvci5lcnJvckNvZGUgKyAnIHNob3VsZCByZXR1cm4gY29ycmVjdCBlcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGVycm9yLmVycm9yQ29kZSkge1xuICAgICAgICAgIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlKGVycm9yLmVycm9yQ29kZSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAnanNvbndwQ29kZScsXG4gICAgICAgICAgICBlcnJvci5lcnJvckNvZGVcbiAgICAgICAgICApO1xuICAgICAgICAgIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlKGVycm9yLmVycm9yQ29kZSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAnbWVzc2FnZScsXG4gICAgICAgICAgICBlcnJvci5lcnJvck1zZ1xuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKCFfLmluY2x1ZGVzKFsxMywgMzNdLCBlcnJvci5lcnJvckNvZGUpKSB7XG4gICAgICAgICAgICBlcnJvckZyb21NSlNPTldQU3RhdHVzQ29kZShlcnJvci5lcnJvckNvZGUsICdhYmNkJykuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAgICdqc29ud3BDb2RlJyxcbiAgICAgICAgICAgICAgZXJyb3IuZXJyb3JDb2RlXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZXJyb3JGcm9tTUpTT05XUFN0YXR1c0NvZGUoZXJyb3IuZXJyb3JDb2RlLCAnYWJjZCcpLnNob3VsZC5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWVzc2FnZScsXG4gICAgICAgICAgICAgICdhYmNkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXNFcnJvclR5cGUoZXJyb3JGcm9tTUpTT05XUFN0YXR1c0NvZGUoZXJyb3IuZXJyb3JDb2RlKSwgZXJyb3JzLlVua25vd25FcnJvcikuc2hvdWxkLmJlXG4gICAgICAgICAgICAudHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGl0KCdzaG91bGQgdGhyb3cgdW5rbm93biBlcnJvciBmb3IgdW5rbm93biBjb2RlJywgZnVuY3Rpb24gKCkge1xuICAgIGVycm9yRnJvbU1KU09OV1BTdGF0dXNDb2RlKDk5KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnanNvbndwQ29kZScsIDEzKTtcbiAgICBlcnJvckZyb21NSlNPTldQU3RhdHVzQ29kZSg5OSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAnbWVzc2FnZScsXG4gICAgICAnQW4gdW5rbm93biBzZXJ2ZXItc2lkZSBlcnJvciBvY2N1cnJlZCAnICsgJ3doaWxlIHByb2Nlc3NpbmcgdGhlIGNvbW1hbmQuJ1xuICAgICk7XG4gIH0pO1xufSk7XG5kZXNjcmliZSgnZXJyb3JGcm9tVzNDSnNvbkNvZGUnLCBmdW5jdGlvbiAoKSB7XG4gIGZvciAobGV0IGVycm9yIG9mIGVycm9yc0xpc3QpIHtcbiAgICBpZiAoZXJyb3IuZXJyb3JOYW1lICE9PSAnTm90WWV0SW1wbGVtZW50ZWRFcnJvcicpIHtcbiAgICAgIGl0KGVycm9yLmVycm9yTmFtZSArICcgc2hvdWxkIHJldHVybiBjb3JyZWN0IGVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB7ZXJyb3I6IHczY0Vycm9yfSA9IGVycm9yO1xuICAgICAgICBpZiAodzNjRXJyb3IpIHtcbiAgICAgICAgICBlcnJvckZyb21XM0NKc29uQ29kZSh3M2NFcnJvcikuZXJyb3Iuc2hvdWxkLmVxdWFsKGVycm9yLmVycm9yKTtcbiAgICAgICAgICBlcnJvckZyb21XM0NKc29uQ29kZSh3M2NFcnJvcikuc2hvdWxkLmhhdmUucHJvcGVydHkoJ21lc3NhZ2UnLCBlcnJvci5lcnJvck1zZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXNFcnJvclR5cGUoZXJyb3JGcm9tVzNDSnNvbkNvZGUodzNjRXJyb3IpLCBlcnJvcnMuVW5rbm93bkVycm9yKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGl0KCdzaG91bGQgcGFyc2UgdW5rbm93biBlcnJvcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXNFcnJvclR5cGUoZXJyb3JGcm9tVzNDSnNvbkNvZGUoJ25vdCBhIHJlYWwgZXJyb3IgY29kZScpLCBlcnJvcnMuVW5rbm93bkVycm9yKS5zaG91bGQuYmUudHJ1ZTtcbiAgICBlcnJvckZyb21XM0NKc29uQ29kZSgnbm90IGEgcmVhbCBlcnJvciBjb2RlJykubWVzc2FnZS5zaG91bGQubWF0Y2goXG4gICAgICAvQW4gdW5rbm93biBzZXJ2ZXItc2lkZSBlcnJvciBvY2N1cnJlZC9cbiAgICApO1xuICAgIGVycm9yRnJvbVczQ0pzb25Db2RlKCdub3QgYSByZWFsIGVycm9yIGNvZGUnKS5lcnJvci5zaG91bGQuZXF1YWwoJ3Vua25vd24gZXJyb3InKTtcbiAgfSk7XG59KTtcbmRlc2NyaWJlKCd3M2MgU3RhdHVzIENvZGVzJywgZnVuY3Rpb24gKCkge1xuICBpdCgnc2hvdWxkIG1hdGNoIHRoZSBjb3JyZWN0IGVycm9yIGNvZGVzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBub240MDBFcnJvcnMgPSBbXG4gICAgICBbJ05vU3VjaERyaXZlckVycm9yJywgNDA0XSxcbiAgICAgIFsnTm9TdWNoRnJhbWVFcnJvcicsIDQwNF0sXG4gICAgICBbJ05vQWxlcnRPcGVuRXJyb3InLCA0MDRdLFxuICAgICAgWydOb1N1Y2hXaW5kb3dFcnJvcicsIDQwNF0sXG4gICAgICBbJ1N0YWxlRWxlbWVudFJlZmVyZW5jZUVycm9yJywgNDA0XSxcbiAgICAgIFsnSmF2YVNjcmlwdEVycm9yJywgNTAwXSxcbiAgICAgIFsnTW92ZVRhcmdldE91dE9mQm91bmRzRXJyb3InLCA1MDBdLFxuICAgICAgWydOb1N1Y2hDb29raWVFcnJvcicsIDQwNF0sXG4gICAgICBbJ05vU3VjaEVsZW1lbnRFcnJvcicsIDQwNF0sXG4gICAgICBbJ1NjcmlwdFRpbWVvdXRFcnJvcicsIDQwOF0sXG4gICAgICBbJ1Nlc3Npb25Ob3RDcmVhdGVkRXJyb3InLCA1MDBdLFxuICAgICAgWydUaW1lb3V0RXJyb3InLCA0MDhdLFxuICAgICAgWydVbmFibGVUb1NldENvb2tpZUVycm9yJywgNTAwXSxcbiAgICAgIFsnVW5hYmxlVG9DYXB0dXJlU2NyZWVuJywgNTAwXSxcbiAgICAgIFsnVW5leHBlY3RlZEFsZXJ0T3BlbkVycm9yJywgNTAwXSxcbiAgICAgIFsnVW5rbm93bkNvbW1hbmRFcnJvcicsIDQwNF0sXG4gICAgICBbJ1Vua25vd25FcnJvcicsIDUwMF0sXG4gICAgICBbJ1Vua25vd25NZXRob2RFcnJvcicsIDQwNV0sXG4gICAgICBbJ1Vuc3VwcG9ydGVkT3BlcmF0aW9uRXJyb3InLCA1MDBdLFxuICAgIF07XG5cbiAgICAvLyBUZXN0IHRoZSBlcnJvcnMgdGhhdCB3ZSBkb24ndCBleHBlY3QgdG8gcmV0dXJuIDQwMCBjb2RlXG4gICAgZm9yIChsZXQgW2Vycm9yTmFtZSwgZXhwZWN0ZWRFcnJvckNvZGVdIG9mIG5vbjQwMEVycm9ycykge1xuICAgICAgZXJyb3JzW2Vycm9yTmFtZV0uc2hvdWxkLmV4aXN0O1xuICAgICAgbmV3IGVycm9yc1tlcnJvck5hbWVdKCkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3czY1N0YXR1cycsIGV4cGVjdGVkRXJyb3JDb2RlKTtcbiAgICB9XG5cbiAgICAvLyBUZXN0IGFuIGVycm9yIHRoYXQgd2UgZXhwZWN0IHRvIHJldHVybiA0MDAgY29kZVxuICAgIG5ldyBlcnJvcnMuRWxlbWVudENsaWNrSW50ZXJjZXB0ZWRFcnJvcigpLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3M2NTdGF0dXMnLCA0MDApO1xuICB9KTtcbn0pO1xuZGVzY3JpYmUoJy5nZXRSZXNwb25zZUZvclczQ0Vycm9yJywgZnVuY3Rpb24gKCkge1xuICBpdCgnc2hvdWxkIHJldHVybiBhbiBlcnJvciwgbWVzc2FnZSBhbmQgc3RhY2t0cmFjZSBmb3IganVzdCBhIGdlbmVyaWMgZXhjZXB0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvbWUgcmFuZG9tIGVycm9yJyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc3QgW2h0dHBTdGF0dXMsIGh0dHBSZXNwb25zZUJvZHldID0gZ2V0UmVzcG9uc2VGb3JXM0NFcnJvcihlKTtcbiAgICAgIGh0dHBTdGF0dXMuc2hvdWxkLmVxdWFsKDUwMCk7XG4gICAgICBjb25zdCB7ZXJyb3IsIG1lc3NhZ2UsIHN0YWNrdHJhY2V9ID0gaHR0cFJlc3BvbnNlQm9keS52YWx1ZTtcbiAgICAgIG1lc3NhZ2Uuc2hvdWxkLm1hdGNoKC9Tb21lIHJhbmRvbSBlcnJvci8pO1xuICAgICAgZXJyb3Iuc2hvdWxkLmVxdWFsKCd1bmtub3duIGVycm9yJyk7XG4gICAgICBzdGFja3RyYWNlLnNob3VsZC5tYXRjaCgvYXQgZ2V0UmVzcG9uc2VGb3JXM0NFcnJvci8pO1xuICAgICAgc3RhY2t0cmFjZS5zaG91bGQubWF0Y2goL1NvbWUgcmFuZG9tIGVycm9yLyk7XG4gICAgICBzdGFja3RyYWNlLnNob3VsZC5jb250YWluKGJhc2VuYW1lKTtcbiAgICB9XG4gIH0pO1xuICBpdCgnc2hvdWxkIHJldHVybiBhbiBlcnJvciwgbWVzc2FnZSBhbmQgc3RhY2t0cmFjZSBmb3IgYSBOb1N1Y2hFbGVtZW50RXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9TdWNoRWxlbWVudEVycm9yID0gbmV3IGVycm9ycy5Ob1N1Y2hFbGVtZW50RXJyb3IoJ3NwZWNpZmljIGVycm9yIG1lc3NhZ2UnKTtcbiAgICBjb25zdCBbaHR0cFN0YXR1cywgaHR0cFJlc3BvbnNlQm9keV0gPSBnZXRSZXNwb25zZUZvclczQ0Vycm9yKG5vU3VjaEVsZW1lbnRFcnJvcik7XG4gICAgaHR0cFN0YXR1cy5zaG91bGQuZXF1YWwoNDA0KTtcbiAgICBjb25zdCB7ZXJyb3IsIG1lc3NhZ2UsIHN0YWNrdHJhY2V9ID0gaHR0cFJlc3BvbnNlQm9keS52YWx1ZTtcbiAgICBlcnJvci5zaG91bGQuZXF1YWwoJ25vIHN1Y2ggZWxlbWVudCcpO1xuICAgIG1lc3NhZ2Uuc2hvdWxkLm1hdGNoKC9zcGVjaWZpYyBlcnJvciBtZXNzYWdlLyk7XG4gICAgc3RhY2t0cmFjZS5zaG91bGQuY29udGFpbihiYXNlbmFtZSk7XG4gIH0pO1xuICBpdCgnc2hvdWxkIGhhbmRsZSBCYWRQYXJhbWV0ZXJzRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmFkUGFyYW1zRXJyb3IgPSBuZXcgZXJyb3JzLkJhZFBhcmFtZXRlcnNFcnJvcignX19GT09fXycsICdfX0JBUl9fJywgJ19fSEVMTE9fV09STERfXycpO1xuICAgIGNvbnN0IFtodHRwU3RhdHVzLCBodHRwUmVzcG9uc2VCb2R5XSA9IGdldFJlc3BvbnNlRm9yVzNDRXJyb3IoYmFkUGFyYW1zRXJyb3IpO1xuICAgIGh0dHBTdGF0dXMuc2hvdWxkLmVxdWFsKDQwMCk7XG4gICAgY29uc3Qge2Vycm9yLCBtZXNzYWdlLCBzdGFja3RyYWNlfSA9IGh0dHBSZXNwb25zZUJvZHkudmFsdWU7XG4gICAgZXJyb3Iuc2hvdWxkLmVxdWFsKCdpbnZhbGlkIGFyZ3VtZW50Jyk7XG4gICAgbWVzc2FnZS5zaG91bGQubWF0Y2goL19fQkFSX18vKTtcbiAgICBtZXNzYWdlLnNob3VsZC5tYXRjaCgvX19IRUxMT19XT1JMRF9fLyk7XG4gICAgc3RhY2t0cmFjZS5zaG91bGQuY29udGFpbihiYXNlbmFtZSk7XG4gIH0pO1xuICBpdCgnc2hvdWxkIHRyYW5zbGF0ZSBKU09OV1AgZXJyb3JzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IFtodHRwU3RhdHVzLCBodHRwUmVzcG9uc2VCb2R5XSA9IGdldFJlc3BvbnNlRm9yVzNDRXJyb3Ioe1xuICAgICAgc3RhdHVzOiA3LFxuICAgICAgdmFsdWU6ICdNeSBjdXN0b20gbWVzc2FnZScsXG4gICAgICBzZXNzaW9uSWQ6ICdGYWtlIFNlc3Npb24gSWQnLFxuICAgIH0pO1xuICAgIGh0dHBTdGF0dXMuc2hvdWxkLmVxdWFsKDQwNCk7XG4gICAgY29uc3Qge2Vycm9yLCBtZXNzYWdlLCBzdGFja3RyYWNlfSA9IGh0dHBSZXNwb25zZUJvZHkudmFsdWU7XG4gICAgbWVzc2FnZS5zaG91bGQuZXF1YWwoJ015IGN1c3RvbSBtZXNzYWdlJyk7XG4gICAgZXJyb3Iuc2hvdWxkLmVxdWFsKCdubyBzdWNoIGVsZW1lbnQnKTtcbiAgICBzdGFja3RyYWNlLnNob3VsZC5leGlzdDtcbiAgfSk7XG59KTtcbmRlc2NyaWJlKCcuZ2V0QWN0dWFsRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCdNSlNPTldQJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbWFwIGEgc3RhdHVzIGNvZGUgNyBubyBzdWNoIGVsZW1lbnQgZXJyb3IgYXMgYSBOb1N1Y2hFbGVtZW50RXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoJ0Vycm9yIG1lc3NhZ2UgZG9lcyBub3QgbWF0dGVyJywge1xuICAgICAgICB2YWx1ZTogJ2RvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIHN0YXR1czogNyxcbiAgICAgIH0pLmdldEFjdHVhbEVycm9yKCk7XG4gICAgICBpc0Vycm9yVHlwZShhY3R1YWxFcnJvciwgZXJyb3JzLk5vU3VjaEVsZW1lbnRFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBtYXAgYSBzdGF0dXMgY29kZSAxMCwgU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoJ0Vycm9yIG1lc3NhZ2UgZG9lcyBub3QgbWF0dGVyJywge1xuICAgICAgICB2YWx1ZTogJ0RvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIHN0YXR1czogMTAsXG4gICAgICB9KS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBtYXAgYW4gdW5rbm93biBlcnJvciB0byBVbmtub3duRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoJ0Vycm9yIG1lc3NhZ2UgZG9lcyBub3QgbWF0dGVyJywge1xuICAgICAgICB2YWx1ZTogJ0RvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIHN0YXR1czogLTEwMCxcbiAgICAgIH0pLmdldEFjdHVhbEVycm9yKCk7XG4gICAgICBpc0Vycm9yVHlwZShhY3R1YWxFcnJvciwgZXJyb3JzLlVua25vd25FcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIEpTT04gc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWN0dWFsRXJyb3IgPSBuZXcgZXJyb3JzLlByb3h5UmVxdWVzdEVycm9yKFxuICAgICAgICAnRXJyb3IgbWVzc2FnZSBkb2VzIG5vdCBtYXR0ZXInLFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdmFsdWU6ICdEb2VzIG5vdCBtYXR0ZXInLFxuICAgICAgICAgIHN0YXR1czogLTEwMCxcbiAgICAgICAgfSlcbiAgICAgICkuZ2V0QWN0dWFsRXJyb3IoKTtcbiAgICAgIGlzRXJyb3JUeXBlKGFjdHVhbEVycm9yLCBlcnJvcnMuVW5rbm93bkVycm9yKS5zaG91bGQuYmUudHJ1ZTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1czQycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG1hcCBhIDQwNCBubyBzdWNoIGVsZW1lbnQgZXJyb3IgYXMgYSBOb1N1Y2hFbGVtZW50RXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoXG4gICAgICAgICdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgZXJyb3I6IGVycm9ycy5Ob1N1Y2hFbGVtZW50RXJyb3IuZXJyb3IoKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBIVFRQU3RhdHVzQ29kZXMuTk9UX0ZPVU5EXG4gICAgICApLmdldEFjdHVhbEVycm9yKCk7XG4gICAgICBpc0Vycm9yVHlwZShhY3R1YWxFcnJvciwgZXJyb3JzLk5vU3VjaEVsZW1lbnRFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBtYXAgYSA0MDAgU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoXG4gICAgICAgICdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgZXJyb3I6IGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvci5lcnJvcigpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIEhUVFBTdGF0dXNDb2Rlcy5CQURfUkVRVUVTVFxuICAgICAgKS5nZXRBY3R1YWxFcnJvcigpO1xuICAgICAgaXNFcnJvclR5cGUoYWN0dWFsRXJyb3IsIGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvcikuc2hvdWxkLmJlLnRydWU7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBtYXAgYW4gdW5rbm93biBlcnJvciB0byBVbmtub3duRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoXG4gICAgICAgICdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIG51bGwsXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgZXJyb3I6ICdOb3QgYSB2YWxpZCB3M2MgSlNPTiBjb2RlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICA0NTZcbiAgICAgICkuZ2V0QWN0dWFsRXJyb3IoKTtcbiAgICAgIGlzRXJyb3JUeXBlKGFjdHVhbEVycm9yLCBlcnJvcnMuVW5rbm93bkVycm9yKS5zaG91bGQuYmUudHJ1ZTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHBhcnNlIGEgSlNPTiBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY3R1YWxFcnJvciA9IG5ldyBlcnJvcnMuUHJveHlSZXF1ZXN0RXJyb3IoXG4gICAgICAgICdFcnJvciBtZXNzYWdlIGRvZXMgbm90IG1hdHRlcicsXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgZXJyb3I6IGVycm9ycy5TdGFsZUVsZW1lbnRSZWZlcmVuY2VFcnJvci5lcnJvcigpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBIVFRQU3RhdHVzQ29kZXMuQkFEX1JFUVVFU1RcbiAgICAgICkuZ2V0QWN0dWFsRXJyb3IoKTtcbiAgICAgIGlzRXJyb3JUeXBlKGFjdHVhbEVycm9yLCBlcnJvcnMuU3RhbGVFbGVtZW50UmVmZXJlbmNlRXJyb3IpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxNQUFNQSxRQUFRLEdBQUdDLGFBQUEsQ0FBS0QsUUFBTCxDQUFjRSxVQUFkLENBQWpCOztBQUlBLElBQUlDLFVBQVUsR0FBRyxDQUNmO0VBQ0VDLFNBQVMsRUFBRSxtQkFEYjtFQUVFQyxRQUFRLEVBQUUsK0NBRlo7RUFHRUMsS0FBSyxFQUFFLG9CQUhUO0VBSUVDLFNBQVMsRUFBRTtBQUpiLENBRGUsRUFPZjtFQUNFSCxTQUFTLEVBQUUsOEJBRGI7RUFFRUMsUUFBUSxFQUNOLCtJQUhKO0VBSUVDLEtBQUssRUFBRTtBQUpULENBUGUsRUFhZjtFQUNFRixTQUFTLEVBQUUsNkJBRGI7RUFFRUMsUUFBUSxFQUNOLCtGQUhKO0VBSUVDLEtBQUssRUFBRTtBQUpULENBYmUsRUFtQmY7RUFDRUYsU0FBUyxFQUFFLDBCQURiO0VBRUVDLFFBQVEsRUFDTixxSUFISjtFQUlFQyxLQUFLLEVBQUU7QUFKVCxDQW5CZSxFQXlCZjtFQUNFRixTQUFTLEVBQUUsc0JBRGI7RUFFRUMsUUFBUSxFQUFFLHFFQUZaO0VBR0VDLEtBQUssRUFBRTtBQUhULENBekJlLEVBOEJmO0VBQ0VGLFNBQVMsRUFBRSxvQkFEYjtFQUVFQyxRQUFRLEVBQUUsMkRBQTJELDBCQUZ2RTtFQUdFQyxLQUFLLEVBQUUsaUJBSFQ7RUFJRUMsU0FBUyxFQUFFO0FBSmIsQ0E5QmUsRUFvQ2Y7RUFDRUgsU0FBUyxFQUFFLGtCQURiO0VBRUVDLFFBQVEsRUFDTiwyREFDQSx1Q0FKSjtFQUtFQyxLQUFLLEVBQUUsZUFMVDtFQU1F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
@@ -1,80 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- require("source-map-support/register");
6
-
7
- var _lodash = require("lodash");
8
-
9
- var _protocol = require("../../../lib/protocol");
10
-
11
- var _crypto = _interopRequireDefault(require("crypto"));
12
-
13
- describe('Protocol', function () {
14
- describe('ensure protocol consistency', function () {
15
- it('should not change protocol between patch versions', function () {
16
- let shasum = _crypto.default.createHash('sha1');
17
-
18
- for (let [url, urlMapping] of _lodash._.toPairs(_protocol.METHOD_MAP)) {
19
- shasum.update(url);
20
-
21
- for (let [method, methodMapping] of _lodash._.toPairs(urlMapping)) {
22
- shasum.update(method);
23
-
24
- if (methodMapping.command) {
25
- shasum.update(methodMapping.command);
26
- }
27
-
28
- if (methodMapping.payloadParams) {
29
- let allParams = _lodash._.flatten(methodMapping.payloadParams.required);
30
-
31
- if (methodMapping.payloadParams.optional) {
32
- allParams = allParams.concat(_lodash._.flatten(methodMapping.payloadParams.optional));
33
- }
34
-
35
- for (let param of allParams) {
36
- shasum.update(param);
37
- }
38
-
39
- if (methodMapping.payloadParams.wrap) {
40
- shasum.update('skip');
41
- shasum.update(methodMapping.payloadParams.wrap);
42
- }
43
- }
44
- }
45
- }
46
-
47
- let hash = shasum.digest('hex').substring(0, 8);
48
- hash.should.equal('736bf246');
49
- });
50
- });
51
- describe('check route to command name conversion', function () {
52
- it('should properly lookup correct command name for endpoint with session', function () {
53
- const cmdName = (0, _protocol.routeToCommandName)('/timeouts', 'POST');
54
- cmdName.should.equal('timeouts');
55
- });
56
- it('should properly lookup correct command name for endpoint with session', function () {
57
- const cmdName = (0, _protocol.routeToCommandName)('/timeouts/implicit_wait', 'POST');
58
- cmdName.should.equal('implicitWait');
59
- });
60
- it('should properly lookup correct command name for endpoint without session', function () {
61
- const cmdName = (0, _protocol.routeToCommandName)('/status', 'GET');
62
- cmdName.should.equal('getStatus');
63
- });
64
- it('should properly lookup correct command name for endpoint without leading slash', function () {
65
- const cmdName = (0, _protocol.routeToCommandName)('status', 'GET');
66
- cmdName.should.equal('getStatus');
67
- });
68
- it('should properly lookup correct command name for fully specified endpoint', function () {
69
- const cmdName = (0, _protocol.routeToCommandName)('/status', 'GET');
70
- cmdName.should.equal('getStatus');
71
- });
72
- it('should not find command name if incorrect input data has been specified', function () {
73
- for (let [route, method] of [['/status', 'POST'], ['/xstatus', 'GET'], ['status', 'POST']]) {
74
- const cmdName = (0, _protocol.routeToCommandName)(route, method);
75
- chai.should().equal(cmdName, undefined);
76
- }
77
- });
78
- });
79
- });
80
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJkZXNjcmliZSIsIml0Iiwic2hhc3VtIiwiY3J5cHRvIiwiY3JlYXRlSGFzaCIsInVybCIsInVybE1hcHBpbmciLCJfIiwidG9QYWlycyIsIk1FVEhPRF9NQVAiLCJ1cGRhdGUiLCJtZXRob2QiLCJtZXRob2RNYXBwaW5nIiwiY29tbWFuZCIsInBheWxvYWRQYXJhbXMiLCJhbGxQYXJhbXMiLCJmbGF0dGVuIiwicmVxdWlyZWQiLCJvcHRpb25hbCIsImNvbmNhdCIsInBhcmFtIiwid3JhcCIsImhhc2giLCJkaWdlc3QiLCJzdWJzdHJpbmciLCJzaG91bGQiLCJlcXVhbCIsImNtZE5hbWUiLCJyb3V0ZVRvQ29tbWFuZE5hbWUiLCJyb3V0ZSIsImNoYWkiLCJ1bmRlZmluZWQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvcHJvdG9jb2wvcm91dGVzLnNwZWMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJhbnNwaWxlOm1vY2hhXG5cbmltcG9ydCB7X30gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7TUVUSE9EX01BUCwgcm91dGVUb0NvbW1hbmROYW1lfSBmcm9tICcuLi8uLi8uLi9saWIvcHJvdG9jb2wnO1xuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5kZXNjcmliZSgnUHJvdG9jb2wnLCBmdW5jdGlvbiAoKSB7XG4gIC8vIFRPRE8gdGVzdCBhZ2FpbnN0IGFuIGV4cGxpY2l0IHByb3RvY29sIHJhdGhlciB0aGFuIGEgaGFzaCBvZiBhIHByZXZpb3VzXG4gIC8vIHByb3RvY29sXG5cbiAgZGVzY3JpYmUoJ2Vuc3VyZSBwcm90b2NvbCBjb25zaXN0ZW5jeScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG5vdCBjaGFuZ2UgcHJvdG9jb2wgYmV0d2VlbiBwYXRjaCB2ZXJzaW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzaGFzdW0gPSBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhMScpO1xuICAgICAgZm9yIChsZXQgW3VybCwgdXJsTWFwcGluZ10gb2YgXy50b1BhaXJzKE1FVEhPRF9NQVApKSB7XG4gICAgICAgIHNoYXN1bS51cGRhdGUodXJsKTtcbiAgICAgICAgZm9yIChsZXQgW21ldGhvZCwgbWV0aG9kTWFwcGluZ10gb2YgXy50b1BhaXJzKHVybE1hcHBpbmcpKSB7XG4gICAgICAgICAgc2hhc3VtLnVwZGF0ZShtZXRob2QpO1xuICAgICAgICAgIGlmIChtZXRob2RNYXBwaW5nLmNvbW1hbmQpIHtcbiAgICAgICAgICAgIHNoYXN1bS51cGRhdGUobWV0aG9kTWFwcGluZy5jb21tYW5kKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG1ldGhvZE1hcHBpbmcucGF5bG9hZFBhcmFtcykge1xuICAgICAgICAgICAgbGV0IGFsbFBhcmFtcyA9IF8uZmxhdHRlbihtZXRob2RNYXBwaW5nLnBheWxvYWRQYXJhbXMucmVxdWlyZWQpO1xuICAgICAgICAgICAgaWYgKG1ldGhvZE1hcHBpbmcucGF5bG9hZFBhcmFtcy5vcHRpb25hbCkge1xuICAgICAgICAgICAgICBhbGxQYXJhbXMgPSBhbGxQYXJhbXMuY29uY2F0KF8uZmxhdHRlbihtZXRob2RNYXBwaW5nLnBheWxvYWRQYXJhbXMub3B0aW9uYWwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IHBhcmFtIG9mIGFsbFBhcmFtcykge1xuICAgICAgICAgICAgICBzaGFzdW0udXBkYXRlKHBhcmFtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXRob2RNYXBwaW5nLnBheWxvYWRQYXJhbXMud3JhcCkge1xuICAgICAgICAgICAgICBzaGFzdW0udXBkYXRlKCdza2lwJyk7XG4gICAgICAgICAgICAgIHNoYXN1bS51cGRhdGUobWV0aG9kTWFwcGluZy5wYXlsb2FkUGFyYW1zLndyYXApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IGhhc2ggPSBzaGFzdW0uZGlnZXN0KCdoZXgnKS5zdWJzdHJpbmcoMCwgOCk7XG4gICAgICAvLyBNb2RpZnkgdGhlIGhhc2ggd2hlbmV2ZXIgdGhlIHByb3RvY29sIGhhcyBpbnRlbnRpb25hbGx5IGJlZW4gbW9kaWZpZWQuXG4gICAgICBoYXNoLnNob3VsZC5lcXVhbCgnNzM2YmYyNDYnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NoZWNrIHJvdXRlIHRvIGNvbW1hbmQgbmFtZSBjb252ZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcHJvcGVybHkgbG9va3VwIGNvcnJlY3QgY29tbWFuZCBuYW1lIGZvciBlbmRwb2ludCB3aXRoIHNlc3Npb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjbWROYW1lID0gcm91dGVUb0NvbW1hbmROYW1lKCcvdGltZW91dHMnLCAnUE9TVCcpO1xuICAgICAgY21kTmFtZS5zaG91bGQuZXF1YWwoJ3RpbWVvdXRzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IGxvb2t1cCBjb3JyZWN0IGNvbW1hbmQgbmFtZSBmb3IgZW5kcG9pbnQgd2l0aCBzZXNzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY21kTmFtZSA9IHJvdXRlVG9Db21tYW5kTmFtZSgnL3RpbWVvdXRzL2ltcGxpY2l0X3dhaXQnLCAnUE9TVCcpO1xuICAgICAgY21kTmFtZS5zaG91bGQuZXF1YWwoJ2ltcGxpY2l0V2FpdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9wZXJseSBsb29rdXAgY29ycmVjdCBjb21tYW5kIG5hbWUgZm9yIGVuZHBvaW50IHdpdGhvdXQgc2Vzc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNtZE5hbWUgPSByb3V0ZVRvQ29tbWFuZE5hbWUoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICBjbWROYW1lLnNob3VsZC5lcXVhbCgnZ2V0U3RhdHVzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IGxvb2t1cCBjb3JyZWN0IGNvbW1hbmQgbmFtZSBmb3IgZW5kcG9pbnQgd2l0aG91dCBsZWFkaW5nIHNsYXNoJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY21kTmFtZSA9IHJvdXRlVG9Db21tYW5kTmFtZSgnc3RhdHVzJywgJ0dFVCcpO1xuICAgICAgY21kTmFtZS5zaG91bGQuZXF1YWwoJ2dldFN0YXR1cycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9wZXJseSBsb29rdXAgY29ycmVjdCBjb21tYW5kIG5hbWUgZm9yIGZ1bGx5IHNwZWNpZmllZCBlbmRwb2ludCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNtZE5hbWUgPSByb3V0ZVRvQ29tbWFuZE5hbWUoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICBjbWROYW1lLnNob3VsZC5lcXVhbCgnZ2V0U3RhdHVzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBmaW5kIGNvbW1hbmQgbmFtZSBpZiBpbmNvcnJlY3QgaW5wdXQgZGF0YSBoYXMgYmVlbiBzcGVjaWZpZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBmb3IgKGxldCBbcm91dGUsIG1ldGhvZF0gb2YgW1xuICAgICAgICBbJy9zdGF0dXMnLCAnUE9TVCddLFxuICAgICAgICBbJy94c3RhdHVzJywgJ0dFVCddLFxuICAgICAgICBbJ3N0YXR1cycsICdQT1NUJ10sXG4gICAgICBdKSB7XG4gICAgICAgIGNvbnN0IGNtZE5hbWUgPSByb3V0ZVRvQ29tbWFuZE5hbWUocm91dGUsIG1ldGhvZCk7XG4gICAgICAgIGNoYWkuc2hvdWxkKCkuZXF1YWwoY21kTmFtZSwgdW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBRUFBLFFBQVEsQ0FBQyxVQUFELEVBQWEsWUFBWTtFQUkvQkEsUUFBUSxDQUFDLDZCQUFELEVBQWdDLFlBQVk7SUFD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