appium 2.0.0-beta.20 → 2.0.0-beta.24
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.
- package/README.md +1 -2
- package/build/check-npm-pack-files.js +23 -0
- package/build/commands-yml/parse.js +319 -0
- package/build/commands-yml/validator.js +130 -0
- package/build/index.js +19 -0
- package/build/lib/appium.js +22 -7
- package/build/lib/cli/args.js +13 -15
- package/build/lib/cli/npm.js +27 -16
- package/build/lib/cli/parser.js +7 -3
- package/build/lib/config.js +27 -47
- package/build/lib/extension-config.js +1 -1
- package/build/lib/main.js +29 -28
- package/build/lib/plugin-config.js +2 -2
- package/build/lib/plugins.js +4 -2
- package/build/lib/schema/appium-config-schema.js +3 -2
- package/build/lib/schema/arg-spec.js +5 -3
- package/build/lib/schema/cli-args.js +25 -16
- package/build/lib/schema/keywords.js +14 -4
- package/build/lib/schema/schema.js +80 -9
- package/build/lib/utils.js +16 -36
- package/build/postinstall.js +90 -0
- package/build/test/cli/cli-e2e-specs.js +221 -0
- package/build/test/cli/cli-helpers.js +86 -0
- package/build/test/cli/cli-specs.js +71 -0
- package/build/test/cli/fixtures/test-driver/package.json +27 -0
- package/build/test/cli/schema-args-specs.js +48 -0
- package/build/test/cli/schema-e2e-specs.js +47 -0
- package/build/test/config-e2e-specs.js +112 -0
- package/build/test/config-file-e2e-specs.js +209 -0
- package/build/test/config-file-specs.js +281 -0
- package/build/test/config-specs.js +246 -0
- package/build/test/driver-e2e-specs.js +435 -0
- package/build/test/driver-specs.js +386 -0
- package/build/test/ext-config-io-specs.js +181 -0
- package/build/test/extension-config-specs.js +365 -0
- package/build/test/fixtures/allow-feat.txt +5 -0
- package/build/test/fixtures/caps.json +3 -0
- package/build/test/fixtures/config/allow-insecure.txt +3 -0
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
- package/build/test/fixtures/config/appium.config.bad.json +32 -0
- package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
- package/build/test/fixtures/config/appium.config.good.js +40 -0
- package/build/test/fixtures/config/appium.config.good.json +33 -0
- package/build/test/fixtures/config/appium.config.good.yaml +30 -0
- package/build/test/fixtures/config/appium.config.invalid.json +31 -0
- package/build/test/fixtures/config/appium.config.security-array.json +5 -0
- package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
- package/build/test/fixtures/config/appium.config.security-path.json +5 -0
- package/build/test/fixtures/config/driver-fake.config.json +8 -0
- package/build/test/fixtures/config/nodeconfig.json +3 -0
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +35 -0
- package/build/test/fixtures/deny-feat.txt +5 -0
- package/build/test/fixtures/driver.schema.js +20 -0
- package/build/test/fixtures/extensions.yaml +27 -0
- package/build/test/fixtures/flattened-schema.js +532 -0
- package/build/test/fixtures/plugin.schema.js +20 -0
- package/build/test/fixtures/schema-with-extensions.js +28 -0
- package/build/test/grid-register-specs.js +74 -0
- package/build/test/helpers.js +75 -0
- package/build/test/logger-specs.js +76 -0
- package/build/test/npm-specs.js +20 -0
- package/build/test/parser-specs.js +319 -0
- package/build/test/plugin-e2e-specs.js +316 -0
- package/build/test/schema/arg-spec-specs.js +70 -0
- package/build/test/schema/cli-args-specs.js +408 -0
- package/build/test/schema/schema-specs.js +407 -0
- package/build/test/utils-specs.js +288 -0
- package/index.js +11 -0
- package/lib/appium-config.schema.json +2 -1
- package/lib/appium.js +51 -8
- package/lib/cli/args.js +17 -14
- package/lib/cli/npm.js +68 -6
- package/lib/cli/parser.js +5 -2
- package/lib/config.js +72 -54
- package/lib/extension-config.js +1 -1
- package/lib/main.js +93 -40
- package/lib/plugin-config.js +1 -1
- package/lib/plugins.js +2 -0
- package/lib/schema/appium-config-schema.js +1 -0
- package/lib/schema/arg-spec.js +12 -2
- package/lib/schema/cli-args.js +22 -34
- package/lib/schema/keywords.js +20 -4
- package/lib/schema/schema.js +142 -22
- package/lib/utils.js +28 -29
- package/package.json +10 -14
- package/types/types.d.ts +5 -0
- package/build/lib/cli/argparse-actions.js +0 -104
- package/lib/cli/argparse-actions.js +0 -77
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
require("source-map-support/register");
|
|
6
|
+
|
|
7
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
8
|
+
|
|
9
|
+
var _schema = require("../../lib/schema");
|
|
10
|
+
|
|
11
|
+
var _cliArgs = require("../../lib/schema/cli-args");
|
|
12
|
+
|
|
13
|
+
var _cliTransformers = require("../../lib/schema/cli-transformers");
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
expect
|
|
17
|
+
} = chai;
|
|
18
|
+
describe('cli-args', function () {
|
|
19
|
+
describe('toParserArgs()', function () {
|
|
20
|
+
function getArgs(opts = {}) {
|
|
21
|
+
let {
|
|
22
|
+
extName,
|
|
23
|
+
extType,
|
|
24
|
+
schema
|
|
25
|
+
} = opts;
|
|
26
|
+
|
|
27
|
+
if (schema && extName && extType) {
|
|
28
|
+
(0, _schema.registerSchema)(extType, extName, schema);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
(0, _schema.finalizeSchema)();
|
|
32
|
+
return _lodash.default.fromPairs([...(0, _cliArgs.toParserArgs)()]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
beforeEach(_schema.resetSchema);
|
|
36
|
+
afterEach(_schema.resetSchema);
|
|
37
|
+
describe('schema contents', function () {
|
|
38
|
+
const extName = 'blob';
|
|
39
|
+
const extType = 'plugin';
|
|
40
|
+
describe('type', function () {
|
|
41
|
+
let result;
|
|
42
|
+
describe('boolean', function () {
|
|
43
|
+
beforeEach(function () {
|
|
44
|
+
const schema = {
|
|
45
|
+
properties: {
|
|
46
|
+
foo: {
|
|
47
|
+
type: 'boolean'
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
type: 'object'
|
|
51
|
+
};
|
|
52
|
+
result = getArgs({
|
|
53
|
+
schema,
|
|
54
|
+
extName,
|
|
55
|
+
extType
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
it('should return options containing `action` prop of `store_const` and no `type`', function () {
|
|
59
|
+
expect(result['--plugin-blob-foo']).to.have.property('action', 'store_const');
|
|
60
|
+
});
|
|
61
|
+
it('should not contain a `metavar` property', function () {
|
|
62
|
+
expect(result['--plugin-blob-foo']).not.to.have.property('metavar');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe('object', function () {
|
|
66
|
+
beforeEach(function () {
|
|
67
|
+
const schema = {
|
|
68
|
+
properties: {
|
|
69
|
+
foo: {
|
|
70
|
+
type: 'object'
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
type: 'object'
|
|
74
|
+
};
|
|
75
|
+
result = getArgs({
|
|
76
|
+
schema,
|
|
77
|
+
extName,
|
|
78
|
+
extType
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
it('should use the `json` transformer', function () {
|
|
82
|
+
expect(result['--plugin-blob-foo']).to.have.property('type', _cliTransformers.transformers.json);
|
|
83
|
+
});
|
|
84
|
+
it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
|
|
85
|
+
expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe('array', function () {
|
|
89
|
+
beforeEach(function () {
|
|
90
|
+
const schema = {
|
|
91
|
+
properties: {
|
|
92
|
+
foo: {
|
|
93
|
+
type: 'array'
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
type: 'object'
|
|
97
|
+
};
|
|
98
|
+
result = getArgs({
|
|
99
|
+
schema,
|
|
100
|
+
extName,
|
|
101
|
+
extType
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it('should use the `csv` transformer', function () {
|
|
105
|
+
expect(result['--plugin-blob-foo']).to.have.property('type', _cliTransformers.transformers.csv);
|
|
106
|
+
});
|
|
107
|
+
it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
|
|
108
|
+
expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe('number', function () {
|
|
112
|
+
beforeEach(function () {
|
|
113
|
+
const schema = {
|
|
114
|
+
properties: {
|
|
115
|
+
foo: {
|
|
116
|
+
type: 'number'
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
type: 'object'
|
|
120
|
+
};
|
|
121
|
+
result = getArgs({
|
|
122
|
+
schema,
|
|
123
|
+
extName,
|
|
124
|
+
extType
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
it('should parse the value as a float', function () {
|
|
128
|
+
expect(result['--plugin-blob-foo'].type('10.5')).to.equal(10.5);
|
|
129
|
+
});
|
|
130
|
+
it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
|
|
131
|
+
expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('integer', function () {
|
|
135
|
+
beforeEach(function () {
|
|
136
|
+
const schema = {
|
|
137
|
+
properties: {
|
|
138
|
+
foo: {
|
|
139
|
+
type: 'integer'
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
type: 'object'
|
|
143
|
+
};
|
|
144
|
+
result = getArgs({
|
|
145
|
+
schema,
|
|
146
|
+
extName,
|
|
147
|
+
extType
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
it('should parse the value as an integer', function () {
|
|
151
|
+
expect(result['--plugin-blob-foo'].type('10.5')).to.equal(10);
|
|
152
|
+
});
|
|
153
|
+
it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
|
|
154
|
+
expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('string', function () {
|
|
158
|
+
beforeEach(function () {
|
|
159
|
+
const schema = {
|
|
160
|
+
properties: {
|
|
161
|
+
foo: {
|
|
162
|
+
type: 'string'
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
type: 'object'
|
|
166
|
+
};
|
|
167
|
+
result = getArgs({
|
|
168
|
+
schema,
|
|
169
|
+
extName,
|
|
170
|
+
extType
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
it('should parse the value as an integer', function () {
|
|
174
|
+
expect(result['--plugin-blob-foo'].type('10.5')).to.equal('10.5');
|
|
175
|
+
});
|
|
176
|
+
it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
|
|
177
|
+
expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('null', function () {
|
|
181
|
+
it('should throw', function () {
|
|
182
|
+
const schema = {
|
|
183
|
+
properties: {
|
|
184
|
+
foo: {
|
|
185
|
+
type: 'null'
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
type: 'object'
|
|
189
|
+
};
|
|
190
|
+
expect(() => getArgs({
|
|
191
|
+
extType,
|
|
192
|
+
extName,
|
|
193
|
+
schema
|
|
194
|
+
})).to.throw(TypeError, /unknown or disallowed/);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe('(unknown)', function () {
|
|
198
|
+
it('should throw', function () {
|
|
199
|
+
const schema = {
|
|
200
|
+
properties: {
|
|
201
|
+
foo: {
|
|
202
|
+
type: 'donkey'
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
type: 'object'
|
|
206
|
+
};
|
|
207
|
+
expect(() => getArgs({
|
|
208
|
+
extType,
|
|
209
|
+
extName,
|
|
210
|
+
schema
|
|
211
|
+
})).to.throw(Error, /schema is invalid/);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
describe('appiumCliAliases', function () {
|
|
216
|
+
let result;
|
|
217
|
+
it('should not allow short aliases for extensions', function () {
|
|
218
|
+
const schema = {
|
|
219
|
+
properties: {
|
|
220
|
+
foo: {
|
|
221
|
+
type: 'string',
|
|
222
|
+
appiumCliAliases: ['fooooo', 'F']
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
type: 'object'
|
|
226
|
+
};
|
|
227
|
+
result = getArgs({
|
|
228
|
+
schema,
|
|
229
|
+
extName,
|
|
230
|
+
extType
|
|
231
|
+
});
|
|
232
|
+
expect(result).to.have.property('--plugin-blob-foo,--plugin-blob-fooooo,--plugin-blob-F');
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
describe('appiumCliDescription', function () {
|
|
236
|
+
let result;
|
|
237
|
+
it('should be preferred over `description`', function () {
|
|
238
|
+
const schema = {
|
|
239
|
+
properties: {
|
|
240
|
+
foo: {
|
|
241
|
+
type: 'string',
|
|
242
|
+
appiumCliDescription: 'foo',
|
|
243
|
+
description: 'bar'
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
type: 'object'
|
|
247
|
+
};
|
|
248
|
+
result = getArgs({
|
|
249
|
+
schema,
|
|
250
|
+
extName,
|
|
251
|
+
extType
|
|
252
|
+
});
|
|
253
|
+
expect(result['--plugin-blob-foo']).to.have.property('help', 'foo');
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
describe('appiumCliTransformer', function () {
|
|
257
|
+
let result;
|
|
258
|
+
it('should use the transformer', function () {
|
|
259
|
+
const schema = {
|
|
260
|
+
properties: {
|
|
261
|
+
foo: {
|
|
262
|
+
type: 'string',
|
|
263
|
+
appiumCliTransformer: 'json'
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
type: 'object'
|
|
267
|
+
};
|
|
268
|
+
result = getArgs({
|
|
269
|
+
schema,
|
|
270
|
+
extName,
|
|
271
|
+
extType
|
|
272
|
+
});
|
|
273
|
+
expect(result['--plugin-blob-foo'].type('{"herp": "derp"}')).to.eql({
|
|
274
|
+
herp: 'derp'
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
it('should error if the value is not valid for the transformer', function () {
|
|
278
|
+
const schema = {
|
|
279
|
+
properties: {
|
|
280
|
+
foo: {
|
|
281
|
+
type: 'string',
|
|
282
|
+
appiumCliTransformer: 'json'
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
type: 'object'
|
|
286
|
+
};
|
|
287
|
+
result = getArgs({
|
|
288
|
+
schema,
|
|
289
|
+
extName,
|
|
290
|
+
extType
|
|
291
|
+
});
|
|
292
|
+
expect(() => result['--plugin-blob-foo'].type('123')).to.throw(/must be a valid json/i);
|
|
293
|
+
});
|
|
294
|
+
describe('when used with `enum`', function () {
|
|
295
|
+
describe('and enum members are invalid as per the transformer', function () {
|
|
296
|
+
describe('when provided an enum member', function () {
|
|
297
|
+
it('should throw', function () {
|
|
298
|
+
const schema = {
|
|
299
|
+
properties: {
|
|
300
|
+
foo: {
|
|
301
|
+
type: 'string',
|
|
302
|
+
appiumCliTransformer: 'json',
|
|
303
|
+
enum: ['herp', 'derp']
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
type: 'object'
|
|
307
|
+
};
|
|
308
|
+
result = getArgs({
|
|
309
|
+
schema,
|
|
310
|
+
extName,
|
|
311
|
+
extType
|
|
312
|
+
});
|
|
313
|
+
expect(() => result['--plugin-blob-foo'].type('herp')).to.throw(/must be a valid json/i);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
describe('and enum members are valid as per the transformer', function () {
|
|
318
|
+
describe('when provided an enum member', function () {
|
|
319
|
+
it('should return a transformed value', function () {
|
|
320
|
+
const schema = {
|
|
321
|
+
properties: {
|
|
322
|
+
foo: {
|
|
323
|
+
type: 'string',
|
|
324
|
+
appiumCliTransformer: 'json',
|
|
325
|
+
enum: ['{"herp": "derp"}', '{"derp": "herp"}']
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
type: 'object'
|
|
329
|
+
};
|
|
330
|
+
result = getArgs({
|
|
331
|
+
schema,
|
|
332
|
+
extName,
|
|
333
|
+
extType
|
|
334
|
+
});
|
|
335
|
+
expect(result['--plugin-blob-foo'].type('{"herp": "derp"}')).to.eql({
|
|
336
|
+
herp: 'derp'
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
describe('when not provided an enum member', function () {
|
|
341
|
+
it('should throw', function () {
|
|
342
|
+
const schema = {
|
|
343
|
+
properties: {
|
|
344
|
+
foo: {
|
|
345
|
+
type: 'string',
|
|
346
|
+
appiumCliTransformer: 'json',
|
|
347
|
+
enum: ['{"herp": "derp"}', '{"derp": "herp"}']
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
type: 'object'
|
|
351
|
+
};
|
|
352
|
+
result = getArgs({
|
|
353
|
+
schema,
|
|
354
|
+
extName,
|
|
355
|
+
extType
|
|
356
|
+
});
|
|
357
|
+
expect(() => result['--plugin-blob-foo'].type('{"georgy": "porgy"}')).to.throw(/one of the allowed values/i);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
describe('enum', function () {
|
|
364
|
+
describe('when used with a non-`string` type', function () {
|
|
365
|
+
it('should throw', function () {
|
|
366
|
+
const schema = {
|
|
367
|
+
properties: {
|
|
368
|
+
foo: {
|
|
369
|
+
type: 'number',
|
|
370
|
+
enum: ['herp', 'derp']
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
type: 'object'
|
|
374
|
+
};
|
|
375
|
+
expect(() => getArgs({
|
|
376
|
+
schema,
|
|
377
|
+
extName,
|
|
378
|
+
extType
|
|
379
|
+
})).to.throw(TypeError, /`enum` is only supported for `type: 'string'`/i);
|
|
380
|
+
});
|
|
381
|
+
it('should actually throw earlier by failing schema validation, but that would mean overriding the behavior of `enum` which sounds inadvisable');
|
|
382
|
+
});
|
|
383
|
+
describe('when used with a `string` type', function () {
|
|
384
|
+
it('should set `choices` prop', function () {
|
|
385
|
+
const schema = {
|
|
386
|
+
properties: {
|
|
387
|
+
foo: {
|
|
388
|
+
type: 'string',
|
|
389
|
+
enum: ['herp', 'derp']
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
type: 'object'
|
|
393
|
+
};
|
|
394
|
+
const result = getArgs({
|
|
395
|
+
schema,
|
|
396
|
+
extName,
|
|
397
|
+
extType
|
|
398
|
+
});
|
|
399
|
+
expect(result['--plugin-blob-foo']).to.have.deep.property('choices', ['herp', 'derp']);
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
});require('source-map-support').install();
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3Qvc2NoZW1hL2NsaS1hcmdzLXNwZWNzLmpzIl0sIm5hbWVzIjpbImV4cGVjdCIsImNoYWkiLCJkZXNjcmliZSIsImdldEFyZ3MiLCJvcHRzIiwiZXh0TmFtZSIsImV4dFR5cGUiLCJzY2hlbWEiLCJfIiwiZnJvbVBhaXJzIiwiYmVmb3JlRWFjaCIsInJlc2V0U2NoZW1hIiwiYWZ0ZXJFYWNoIiwicmVzdWx0IiwicHJvcGVydGllcyIsImZvbyIsInR5cGUiLCJpdCIsInRvIiwiaGF2ZSIsInByb3BlcnR5Iiwibm90IiwidHJhbnNmb3JtZXJzIiwianNvbiIsImNzdiIsImVxdWFsIiwidGhyb3ciLCJUeXBlRXJyb3IiLCJFcnJvciIsImFwcGl1bUNsaUFsaWFzZXMiLCJhcHBpdW1DbGlEZXNjcmlwdGlvbiIsImRlc2NyaXB0aW9uIiwiYXBwaXVtQ2xpVHJhbnNmb3JtZXIiLCJlcWwiLCJoZXJwIiwiZW51bSIsImRlZXAiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU07QUFBQ0EsRUFBQUE7QUFBRCxJQUFXQyxJQUFqQjtBQUVBQyxRQUFRLENBQUMsVUFBRCxFQUFhLFlBQVk7QUFDL0JBLEVBQUFBLFFBQVEsQ0FBQyxnQkFBRCxFQUFtQixZQUFZO0FBTXJDLGFBQVNDLE9BQVQsQ0FBa0JDLElBQUksR0FBRyxFQUF6QixFQUE2QjtBQUMzQixVQUFJO0FBQUNDLFFBQUFBLE9BQUQ7QUFBVUMsUUFBQUEsT0FBVjtBQUFtQkMsUUFBQUE7QUFBbkIsVUFBNkJILElBQWpDOztBQUNBLFVBQUlHLE1BQU0sSUFBSUYsT0FBVixJQUFxQkMsT0FBekIsRUFBa0M7QUFDaEMsb0NBQWVBLE9BQWYsRUFBd0JELE9BQXhCLEVBQWlDRSxNQUFqQztBQUNEOztBQUNEO0FBQ0EsYUFBT0MsZ0JBQUVDLFNBQUYsQ0FBWSxDQUFDLEdBQUcsNEJBQUosQ0FBWixDQUFQO0FBQ0Q7O0FBRURDLElBQUFBLFVBQVUsQ0FBQ0MsbUJBQUQs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RGhCLFFBQWpELENBQ0UsU0FERixFQUVFLENBQUMsTUFBRCxFQUFTLE1BQVQsQ0FGRjtBQUlELFdBZkMsQ0FBRjtBQWdCRCxTQWpCTyxDQUFSO0FBa0JELE9BekNPLENBQVI7QUEwQ0QsS0E1VE8sQ0FBUjtBQTZURCxHQWhWTyxDQUFSO0FBaVZELENBbFZPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7cmVzZXRTY2hlbWEsIGZpbmFsaXplU2NoZW1hLCByZWdpc3RlclNjaGVtYX0gZnJvbSAnLi4vLi4vbGliL3NjaGVtYSc7XG5pbXBvcnQge3RvUGFyc2VyQXJnc30gZnJvbSAnLi4vLi4vbGliL3NjaGVtYS9jbGktYXJncyc7XG5pbXBvcnQge3RyYW5zZm9ybWVyc30gZnJvbSAnLi4vLi4vbGliL3NjaGVtYS9jbGktdHJhbnNmb3JtZXJzJztcblxuY29uc3Qge2V4cGVjdH0gPSBjaGFpO1xuXG5kZXNjcmliZSgnY2xpLWFyZ3MnLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCd0b1BhcnNlckFyZ3MoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gb3B0c1xuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QXJncyAob3B0cyA9IHt9KSB7XG4gICAgICBsZXQge2V4dE5hbWUsIGV4dFR5cGUsIHNjaGVtYX0gPSBvcHRzO1xuICAgICAgaWYgKHNjaGVtYSAmJiBleHROYW1lICYmIGV4dFR5cGUpIHtcbiAgICAgICAgcmVnaXN0ZXJTY2hlbWEoZXh0VHlwZSwgZXh0TmFtZSwgc2NoZW1hKTtcbiAgICAgIH1cbiAgICAgIGZpbmFsaXplU2NoZW1hKCk7XG4gICAgICByZXR1cm4gXy5mcm9tUGFpcnMoWy4uLnRvUGFyc2VyQXJncygpXSk7XG4gICAgfVxuXG4gICAgYmVmb3JlRWFjaChyZXNldFNjaGVtYSk7XG5cbiAgICBhZnRlckVhY2gocmVzZXRTY2hlbWEpO1xuXG4gICAgZGVzY3JpYmUoJ3NjaGVtYSBjb250ZW50cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4dE5hbWUgPSAnYmxvYic7XG4gICAgICBjb25zdCBleHRUeXBlID0gJ3BsdWdpbic7XG5cbiAgICAgIGRlc2NyaWJlKCd0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGRlc2NyaWJlKCdib29sZWFuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge3Byb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnYm9vbGVhbid9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBvcHRpb25zIGNvbnRhaW5pbmcgYGFjdGlvbmAgcHJvcCBvZiBgc3RvcmVfY29uc3RgIGFuZCBubyBgdHlwZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnYWN0aW9uJyxcbiAgICAgICAgICAgICAgJ3N0b3JlX2NvbnN0JyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIG5vdCBjb250YWluIGEgYG1ldGF2YXJgIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkubm90LnRvLmhhdmUucHJvcGVydHkoJ21ldGF2YXInKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ29iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ29iamVjdCd9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgYGpzb25gIHRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICAgICB0cmFuc2Zvcm1lcnMuanNvbixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIGNvbnRhaW4gYSBTQ1JFQU1JTkdfU05BS0VfQ0FTRSBgbWV0YXZhcmAgcHJvcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAgICdtZXRhdmFyJyxcbiAgICAgICAgICAgICAgJ0ZPTycsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdhcnJheSd9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgYGNzdmAgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgICAgIHRyYW5zZm9ybWVycy5jc3YsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ251bWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ251bWJlcid9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHBhcnNlIHRoZSB2YWx1ZSBhcyBhIGZsb2F0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXS50eXBlKCcxMC41JykpLnRvLmVxdWFsKDEwLjUpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2ludGVnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdpbnRlZ2VyJ319LCB0eXBlOiAnb2JqZWN0J307XG4gICAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgcGFyc2UgdGhlIHZhbHVlIGFzIGFuIGludGVnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJzEwLjUnKSkudG8uZXF1YWwoMTApO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3N0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdzdHJpbmcnfX0sXG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBwYXJzZSB0aGUgdmFsdWUgYXMgYW4gaW50ZWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnMTAuNScpKS50by5lcXVhbCgnMTAuNScpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ251bGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ251bGwnfX0sIHR5cGU6ICdvYmplY3QnfTtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBnZXRBcmdzKHtleHRUeXBlLCBleHROYW1lLCBzY2hlbWF9KSkudG8udGhyb3coXG4gICAgICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAgICAgL3Vua25vd24gb3IgZGlzYWxsb3dlZC8sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnKHVua25vd24pJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnZG9ua2V5J319LFxuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZ2V0QXJncyh7ZXh0VHlwZSwgZXh0TmFtZSwgc2NoZW1hfSkpLnRvLnRocm93KFxuICAgICAgICAgICAgICBFcnJvcixcbiAgICAgICAgICAgICAgL3NjaGVtYSBpcyBpbnZhbGlkLyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdhcHBpdW1DbGlBbGlhc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IHNob3J0IGFsaWFzZXMgZm9yIGV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBmb286IHt0eXBlOiAnc3RyaW5nJywgYXBwaXVtQ2xpQWxpYXNlczogWydmb29vb28nLCAnRiddfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAnLS1wbHVnaW4tYmxvYi1mb28sLS1wbHVnaW4tYmxvYi1mb29vb28sLS1wbHVnaW4tYmxvYi1GJyxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnYXBwaXVtQ2xpRGVzY3JpcHRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCByZXN1bHQ7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBiZSBwcmVmZXJyZWQgb3ZlciBgZGVzY3JpcHRpb25gJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgZm9vOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgYXBwaXVtQ2xpRGVzY3JpcHRpb246ICdmb28nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnYmFyJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUucHJvcGVydHkoJ2hlbHAnLCAnZm9vJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdhcHBpdW1DbGlUcmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHJlc3VsdDtcblxuICAgICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgcHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdzdHJpbmcnLCBhcHBpdW1DbGlUcmFuc2Zvcm1lcjogJ2pzb24nfX0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgne1wiaGVycFwiOiBcImRlcnBcIn0nKSkudG8uZXFsKHtcbiAgICAgICAgICAgIGhlcnA6ICdkZXJwJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBlcnJvciBpZiB0aGUgdmFsdWUgaXMgbm90IHZhbGlkIGZvciB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgcHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdzdHJpbmcnLCBhcHBpdW1DbGlUcmFuc2Zvcm1lcjogJ2pzb24nfX0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdCgoKSA9PiByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnMTIzJykpLnRvLnRocm93KFxuICAgICAgICAgICAgL211c3QgYmUgYSB2YWxpZCBqc29uL2ksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gdGhpcyBpcyB1bmxpa2VseSB0byBoYXBwZW4sIGJ1dCBJIHdhbnQgdG8gZXN0YWJsaXNoIHRoZSBiZWhhdmlvciBhcyBkZWZpbmVkLlxuICAgICAgICBkZXNjcmliZSgnd2hlbiB1c2VkIHdpdGggYGVudW1gJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRlc2NyaWJlKCdhbmQgZW51bSBtZW1iZXJzIGFyZSBpbnZhbGlkIGFzIHBlciB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhbiBlbnVtIG1lbWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgIGFwcGl1bUNsaVRyYW5zZm9ybWVyOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgZW51bTogWydoZXJwJywgJ2RlcnAnXSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnaGVycCcpKS50by50aHJvdyhcbiAgICAgICAgICAgICAgICAgIC9tdXN0IGJlIGEgdmFsaWQganNvbi9pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBkZXNjcmliZSgnYW5kIGVudW0gbWVtYmVycyBhcmUgdmFsaWQgYXMgcGVyIHRoZSB0cmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIGVudW0gbWVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHRyYW5zZm9ybWVkIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9vOiB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgYXBwaXVtQ2xpVHJhbnNmb3JtZXI6ICdqc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICBlbnVtOiBbJ3tcImhlcnBcIjogXCJkZXJwXCJ9JywgJ3tcImRlcnBcIjogXCJoZXJwXCJ9J10sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICAgICAgICByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgne1wiaGVycFwiOiBcImRlcnBcIn0nKSxcbiAgICAgICAgICAgICAgICApLnRvLmVxbCh7aGVycDogJ2RlcnAnfSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRlc2NyaWJlKCd3aGVuIG5vdCBwcm92aWRlZCBhbiBlbnVtIG1lbWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgIGFwcGl1bUNsaVRyYW5zZm9ybWVyOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgZW51bTogWyd7XCJoZXJwXCI6IFwiZGVycFwifScsICd7XCJkZXJwXCI6IFwiaGVycFwifSddLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+XG4gICAgICAgICAgICAgICAgICByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgne1wiZ2Vvcmd5XCI6IFwicG9yZ3lcIn0nKSxcbiAgICAgICAgICAgICAgICApLnRvLnRocm93KC9vbmUgb2YgdGhlIGFsbG93ZWQgdmFsdWVzL2kpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnZW51bScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdXNlZCB3aXRoIGEgbm9uLWBzdHJpbmdgIHR5cGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgICBlbnVtOiBbJ2hlcnAnLCAnZGVycCddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KSkudG8udGhyb3coXG4gICAgICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAgICAgL2BlbnVtYCBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgYHR5cGU6ICdzdHJpbmcnYC9pLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KFxuICAgICAgICAgICAgJ3Nob3VsZCBhY3R1YWxseSB0aHJvdyBlYXJsaWVyIGJ5IGZhaWxpbmcgc2NoZW1hIHZhbGlkYXRpb24sIGJ1dCB0aGF0IHdvdWxkIG1lYW4gb3ZlcnJpZGluZyB0aGUgYmVoYXZpb3Igb2YgYGVudW1gIHdoaWNoIHNvdW5kcyBpbmFkdmlzYWJsZScsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdXNlZCB3aXRoIGEgYHN0cmluZ2AgdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHNldCBgY2hvaWNlc2AgcHJvcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICBlbnVtOiBbJ2hlcnAnLCAnZGVycCddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5kZWVwLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnY2hvaWNlcycsXG4gICAgICAgICAgICAgIFsnaGVycCcsICdkZXJwJ10sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L3NjaGVtYS9jbGktYXJncy1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLiJ9
|