@jsii/kernel 1.58.0 → 1.59.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.
- package/lib/api.d.ts +1 -0
- package/lib/api.js +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -1
- package/lib/kernel.d.ts +1 -0
- package/lib/kernel.js +1 -1
- package/lib/objects.d.ts +1 -0
- package/lib/objects.js +1 -1
- package/lib/on-exit.d.ts +1 -0
- package/lib/on-exit.js +1 -1
- package/{test → lib}/recording.d.ts +2 -1
- package/lib/recording.js +73 -0
- package/lib/serialization.d.ts +1 -0
- package/lib/serialization.js +1 -1
- package/package.json +8 -8
- package/test/kernel.test.d.ts +0 -1
- package/test/kernel.test.js +0 -1805
- package/test/objects.test.d.ts +0 -1
- package/test/objects.test.js +0 -20
- package/test/recording.js +0 -73
- package/test/serialization.test.d.ts +0 -1
- package/test/serialization.test.js +0 -93
package/test/kernel.test.js
DELETED
|
@@ -1,1805 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deepEqualWithRegex = void 0;
|
|
4
|
-
const childProcess = require("child_process");
|
|
5
|
-
const fs = require("fs-extra");
|
|
6
|
-
const os = require("os");
|
|
7
|
-
const path_1 = require("path");
|
|
8
|
-
const path = require("path");
|
|
9
|
-
const vm = require("vm");
|
|
10
|
-
const lib_1 = require("../lib");
|
|
11
|
-
const api_1 = require("../lib/api");
|
|
12
|
-
const recording_1 = require("./recording");
|
|
13
|
-
/* eslint-disable require-atomic-updates */
|
|
14
|
-
// extract versions of fixtures
|
|
15
|
-
const calcBaseVersion = require('@scope/jsii-calc-base/package.json').version.replace(/\+.+$/, ''); // eslint-disable-line
|
|
16
|
-
const calcLibVersion = require('@scope/jsii-calc-lib/package.json').version.replace(/\+.+$/, ''); // eslint-disable-line
|
|
17
|
-
const calcVersion = require('jsii-calc/package.json').version.replace(// eslint-disable-line
|
|
18
|
-
/\+.+$/, '');
|
|
19
|
-
// Do this so that regexes stringify nicely in approximate tests
|
|
20
|
-
RegExp.prototype.toJSON = function toJSON() {
|
|
21
|
-
return this.source;
|
|
22
|
-
};
|
|
23
|
-
process.setMaxListeners(9999); // since every kernel instance adds an `on('exit')` handler.
|
|
24
|
-
process.on('unhandledRejection', (e) => {
|
|
25
|
-
console.error(e.stack);
|
|
26
|
-
process.exit(1);
|
|
27
|
-
});
|
|
28
|
-
jest.setTimeout(60000);
|
|
29
|
-
const recordingOutput = process.env.JSII_RECORD;
|
|
30
|
-
if (recordingOutput) {
|
|
31
|
-
fs.mkdirpSync(recordingOutput);
|
|
32
|
-
console.error(`JSII_RECORD=${recordingOutput}`);
|
|
33
|
-
}
|
|
34
|
-
function defineTest(name, method, testFunc = test) {
|
|
35
|
-
const recording = name.replace(/[^A-Za-z]/g, '_');
|
|
36
|
-
testFunc(name, async () => {
|
|
37
|
-
const kernel = await createCalculatorSandbox(recording);
|
|
38
|
-
await method(kernel);
|
|
39
|
-
return recording_1.closeRecording(kernel);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
defineTest.skip = function (name, method) {
|
|
43
|
-
return defineTest(name, method, test.skip);
|
|
44
|
-
};
|
|
45
|
-
// Note: this test asserts file permissions, which work differently on Windows, so we skip it there
|
|
46
|
-
(process.platform === 'win32' ? test.skip : test)('load preserves file permissions', async () => {
|
|
47
|
-
// Changing the umask to 077 (which would neutralize group/other permissions)
|
|
48
|
-
const originalUmask = process.umask(0o077);
|
|
49
|
-
try {
|
|
50
|
-
const kernel = await createCalculatorSandbox('load_preserves_file_permissions');
|
|
51
|
-
const result = kernel.sinvoke({
|
|
52
|
-
fqn: 'jsii-calc.UmaskCheck',
|
|
53
|
-
method: 'mode',
|
|
54
|
-
});
|
|
55
|
-
expect(result.result).toBe(0o644);
|
|
56
|
-
return await recording_1.closeRecording(kernel);
|
|
57
|
-
}
|
|
58
|
-
finally {
|
|
59
|
-
// Restore the original umask
|
|
60
|
-
process.umask(originalUmask);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
defineTest('stats() return sandbox statistics', (sandbox) => {
|
|
64
|
-
const stats = sandbox.stats({});
|
|
65
|
-
expect(stats.objectCount).toBe(0);
|
|
66
|
-
for (let i = 0; i < 100; ++i) {
|
|
67
|
-
sandbox.create({ fqn: '@scope/jsii-calc-lib.Number', args: [i] });
|
|
68
|
-
}
|
|
69
|
-
expect(sandbox.stats({}).objectCount).toBe(100);
|
|
70
|
-
});
|
|
71
|
-
defineTest('deleteObject will remove the reference', (sandbox) => {
|
|
72
|
-
const objects = new Array();
|
|
73
|
-
for (let i = 0; i < 100; ++i) {
|
|
74
|
-
objects.push(sandbox.create({ fqn: '@scope/jsii-calc-lib.Number', args: [i] }));
|
|
75
|
-
}
|
|
76
|
-
expect(sandbox.stats({}).objectCount).toBe(100);
|
|
77
|
-
for (let i = 0; i < 50; ++i) {
|
|
78
|
-
sandbox.del({ objref: objects[i] });
|
|
79
|
-
}
|
|
80
|
-
expect(sandbox.stats({}).objectCount).toBe(50);
|
|
81
|
-
expect(() => sandbox.get({ objref: objects[10], property: 'value' })).toThrow();
|
|
82
|
-
});
|
|
83
|
-
defineTest('in/out primitive types', (sandbox) => {
|
|
84
|
-
const alltypes = sandbox.create({ fqn: 'jsii-calc.AllTypes', args: [] });
|
|
85
|
-
sandbox.set({ objref: alltypes, property: 'booleanProperty', value: true });
|
|
86
|
-
expect(sandbox.get({ objref: alltypes, property: 'booleanProperty' }).value).toBe(true);
|
|
87
|
-
sandbox.set({ objref: alltypes, property: 'booleanProperty', value: false });
|
|
88
|
-
expect(sandbox.get({ objref: alltypes, property: 'booleanProperty' }).value).toBe(false);
|
|
89
|
-
sandbox.set({ objref: alltypes, property: 'stringProperty', value: 'hello' });
|
|
90
|
-
expect(sandbox.get({ objref: alltypes, property: 'stringProperty' }).value).toBe('hello');
|
|
91
|
-
sandbox.set({ objref: alltypes, property: 'numberProperty', value: 123 });
|
|
92
|
-
expect(sandbox.get({ objref: alltypes, property: 'numberProperty' }).value).toBe(123);
|
|
93
|
-
// in -> out for an ANY
|
|
94
|
-
const num = sandbox.create({
|
|
95
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
96
|
-
args: [444],
|
|
97
|
-
});
|
|
98
|
-
sandbox.set({ objref: alltypes, property: 'anyProperty', value: num });
|
|
99
|
-
expect(sandbox.get({ objref: alltypes, property: 'anyProperty' }).value).toEqual(num);
|
|
100
|
-
// out -> in for an ANY
|
|
101
|
-
const ret = sandbox.invoke({ objref: alltypes, method: 'anyOut' }).result;
|
|
102
|
-
sandbox.invoke({ objref: alltypes, method: 'anyIn', args: [ret] });
|
|
103
|
-
});
|
|
104
|
-
defineTest('in/out objects', (sandbox) => {
|
|
105
|
-
const alltypes = sandbox.create({ fqn: 'jsii-calc.AllTypes' });
|
|
106
|
-
const num = sandbox.create({
|
|
107
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
108
|
-
args: [444],
|
|
109
|
-
});
|
|
110
|
-
sandbox.set({ objref: alltypes, property: 'anyProperty', value: num });
|
|
111
|
-
expect(sandbox.get({ objref: alltypes, property: 'anyProperty' }).value).toEqual(num);
|
|
112
|
-
});
|
|
113
|
-
defineTest('in/out collections', (sandbox) => {
|
|
114
|
-
const alltypes = sandbox.create({ fqn: 'jsii-calc.AllTypes', args: [] });
|
|
115
|
-
const array = ['1', '2', '3', '4'];
|
|
116
|
-
sandbox.set({ objref: alltypes, property: 'arrayProperty', value: array });
|
|
117
|
-
expect(sandbox.get({ objref: alltypes, property: 'arrayProperty' }).value).toEqual(array);
|
|
118
|
-
const num = create(sandbox, '@scope/jsii-calc-lib.Number');
|
|
119
|
-
const map = {
|
|
120
|
-
a: num(12),
|
|
121
|
-
b: num(33),
|
|
122
|
-
c: num(33),
|
|
123
|
-
d: num(123),
|
|
124
|
-
};
|
|
125
|
-
sandbox.set({
|
|
126
|
-
objref: alltypes,
|
|
127
|
-
property: 'mapProperty',
|
|
128
|
-
value: { [api_1.TOKEN_MAP]: map },
|
|
129
|
-
});
|
|
130
|
-
expect(sandbox.get({ objref: alltypes, property: 'mapProperty' }).value[api_1.TOKEN_MAP]).toEqual(map);
|
|
131
|
-
});
|
|
132
|
-
defineTest('in/out date values', (sandbox) => {
|
|
133
|
-
const alltypes = sandbox.create({ fqn: 'jsii-calc.AllTypes' });
|
|
134
|
-
const date = new Date('2018-01-18T00:00:32.347Z');
|
|
135
|
-
sandbox.set({
|
|
136
|
-
objref: alltypes,
|
|
137
|
-
property: 'dateProperty',
|
|
138
|
-
value: { [lib_1.api.TOKEN_DATE]: date.toISOString() },
|
|
139
|
-
});
|
|
140
|
-
expect(sandbox.get({ objref: alltypes, property: 'dateProperty' }).value).toEqual({ [lib_1.api.TOKEN_DATE]: '2018-01-18T00:00:32.347Z' });
|
|
141
|
-
});
|
|
142
|
-
defineTest('in/out enum values', (sandbox) => {
|
|
143
|
-
const alltypes = sandbox.create({ fqn: 'jsii-calc.AllTypes' });
|
|
144
|
-
sandbox.set({
|
|
145
|
-
objref: alltypes,
|
|
146
|
-
property: 'enumProperty',
|
|
147
|
-
value: { [lib_1.api.TOKEN_ENUM]: 'jsii-calc.AllTypesEnum/MY_ENUM_VALUE' },
|
|
148
|
-
});
|
|
149
|
-
expect(sandbox.get({ objref: alltypes, property: 'enumPropertyValue' }).value).toBe(0);
|
|
150
|
-
sandbox.set({
|
|
151
|
-
objref: alltypes,
|
|
152
|
-
property: 'enumProperty',
|
|
153
|
-
value: { [lib_1.api.TOKEN_ENUM]: 'jsii-calc.AllTypesEnum/YOUR_ENUM_VALUE' },
|
|
154
|
-
});
|
|
155
|
-
expect(sandbox.get({ objref: alltypes, property: 'enumPropertyValue' }).value).toBe(100);
|
|
156
|
-
sandbox.set({
|
|
157
|
-
objref: alltypes,
|
|
158
|
-
property: 'enumProperty',
|
|
159
|
-
value: { [lib_1.api.TOKEN_ENUM]: 'jsii-calc.AllTypesEnum/THIS_IS_GREAT' },
|
|
160
|
-
});
|
|
161
|
-
expect(sandbox.get({ objref: alltypes, property: 'enumPropertyValue' }).value).toBe(101);
|
|
162
|
-
expect(sandbox.get({ objref: alltypes, property: 'enumProperty' }).value).toEqual({ '$jsii.enum': 'jsii-calc.AllTypesEnum/THIS_IS_GREAT' });
|
|
163
|
-
});
|
|
164
|
-
describe('in/out json values', () => {
|
|
165
|
-
defineTest('with a plain object', (sandbox) => {
|
|
166
|
-
const allTypes = sandbox.create({ fqn: 'jsii-calc.AllTypes' });
|
|
167
|
-
sandbox.set({
|
|
168
|
-
objref: allTypes,
|
|
169
|
-
property: 'jsonProperty',
|
|
170
|
-
value: { foo: 'bar', baz: 1337 },
|
|
171
|
-
});
|
|
172
|
-
expect(sandbox.get({ objref: allTypes, property: 'jsonProperty' }).value).toEqual({ foo: 'bar', baz: 1337 });
|
|
173
|
-
});
|
|
174
|
-
defineTest('with a simple mapping', (sandbox) => {
|
|
175
|
-
const allTypes = sandbox.create({ fqn: 'jsii-calc.AllTypes' });
|
|
176
|
-
sandbox.set({
|
|
177
|
-
objref: allTypes,
|
|
178
|
-
property: 'jsonProperty',
|
|
179
|
-
value: { [lib_1.api.TOKEN_MAP]: { foo: 'bar', baz: 1337 } },
|
|
180
|
-
});
|
|
181
|
-
expect(sandbox.get({ objref: allTypes, property: 'jsonProperty' }).value).toEqual({ foo: 'bar', baz: 1337 });
|
|
182
|
-
});
|
|
183
|
-
defineTest('with a nested mapping', (sandbox) => {
|
|
184
|
-
const allTypes = sandbox.create({ fqn: 'jsii-calc.AllTypes' });
|
|
185
|
-
sandbox.set({
|
|
186
|
-
objref: allTypes,
|
|
187
|
-
property: 'jsonProperty',
|
|
188
|
-
value: {
|
|
189
|
-
[lib_1.api.TOKEN_MAP]: {
|
|
190
|
-
foo: 'bar',
|
|
191
|
-
baz: { [lib_1.api.TOKEN_MAP]: { bazinga: [null, 'Pickle Rick'] } },
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
});
|
|
195
|
-
expect(sandbox.get({ objref: allTypes, property: 'jsonProperty' }).value).toEqual({ foo: 'bar', baz: { bazinga: [null, 'Pickle Rick'] } });
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
defineTest('enum values from @scoped packages awslabs/jsii#138', (sandbox) => {
|
|
199
|
-
const objref = sandbox.create({
|
|
200
|
-
fqn: 'jsii-calc.ReferenceEnumFromScopedPackage',
|
|
201
|
-
});
|
|
202
|
-
const value = sandbox.get({ objref, property: 'foo' });
|
|
203
|
-
expect(value).toEqual({
|
|
204
|
-
value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/VALUE2' },
|
|
205
|
-
});
|
|
206
|
-
sandbox.set({
|
|
207
|
-
objref,
|
|
208
|
-
property: 'foo',
|
|
209
|
-
value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/VALUE1' },
|
|
210
|
-
});
|
|
211
|
-
const ret = sandbox.invoke({ objref, method: 'loadFoo' });
|
|
212
|
-
expect(ret).toEqual({
|
|
213
|
-
result: {
|
|
214
|
-
'$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/VALUE1',
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
sandbox.invoke({
|
|
218
|
-
objref,
|
|
219
|
-
method: 'saveFoo',
|
|
220
|
-
args: [
|
|
221
|
-
{ '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/VALUE2' },
|
|
222
|
-
],
|
|
223
|
-
});
|
|
224
|
-
const value2 = sandbox.get({ objref, property: 'foo' });
|
|
225
|
-
expect(value2).toEqual({
|
|
226
|
-
value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/VALUE2' },
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
defineTest('fails for invalid enum member name', (sandbox) => {
|
|
230
|
-
const objref = sandbox.create({
|
|
231
|
-
fqn: 'jsii-calc.ReferenceEnumFromScopedPackage',
|
|
232
|
-
});
|
|
233
|
-
expect(() => {
|
|
234
|
-
sandbox.set({
|
|
235
|
-
objref,
|
|
236
|
-
property: 'foo',
|
|
237
|
-
value: {
|
|
238
|
-
'$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/ValueX',
|
|
239
|
-
},
|
|
240
|
-
});
|
|
241
|
-
}).toThrow(/No enum member named ValueX/);
|
|
242
|
-
});
|
|
243
|
-
defineTest('set for a non existing property', (sandbox) => {
|
|
244
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.SyncVirtualMethods' });
|
|
245
|
-
expect(() => sandbox.set({ objref: obj, property: 'idontexist', value: 'Foo' })).toThrow();
|
|
246
|
-
});
|
|
247
|
-
defineTest('set for a readonly property', (sandbox) => {
|
|
248
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.SyncVirtualMethods' });
|
|
249
|
-
expect(() => sandbox.set({ objref: obj, property: 'readonlyProperty', value: 'Foo' })).toThrow();
|
|
250
|
-
});
|
|
251
|
-
defineTest('create object with ctor overloads', (sandbox) => {
|
|
252
|
-
sandbox.create({ fqn: 'jsii-calc.Calculator' });
|
|
253
|
-
sandbox.create({
|
|
254
|
-
fqn: 'jsii-calc.Calculator',
|
|
255
|
-
args: [{ initialValue: 100 }],
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
defineTest('objects created inside the sandbox are returned with type info and new objid', (sandbox) => {
|
|
259
|
-
const calc = sandbox.create({
|
|
260
|
-
fqn: 'jsii-calc.Calculator',
|
|
261
|
-
args: [{ initialValue: 100 }],
|
|
262
|
-
});
|
|
263
|
-
sandbox.invoke({ objref: calc, method: 'add', args: [50] });
|
|
264
|
-
const add = sandbox.get({ objref: calc, property: 'curr' }).value;
|
|
265
|
-
expect(sandbox.get({ objref: add, property: 'value' }).value).toBe(150);
|
|
266
|
-
});
|
|
267
|
-
defineTest('naming allows returns the module name for different languages', (sandbox) => {
|
|
268
|
-
expect(sandbox.naming({ assembly: 'jsii-calc' }).naming).toEqual({
|
|
269
|
-
dotnet: {
|
|
270
|
-
iconUrl: 'https://sdk-for-net.amazonwebservices.com/images/AWSLogo128x128.png',
|
|
271
|
-
namespace: 'Amazon.JSII.Tests.CalculatorNamespace',
|
|
272
|
-
packageId: 'Amazon.JSII.Tests.CalculatorPackageId',
|
|
273
|
-
},
|
|
274
|
-
go: {
|
|
275
|
-
moduleName: 'github.com/aws/jsii/jsii-calc/go',
|
|
276
|
-
},
|
|
277
|
-
java: {
|
|
278
|
-
package: 'software.amazon.jsii.tests.calculator',
|
|
279
|
-
maven: {
|
|
280
|
-
groupId: 'software.amazon.jsii.tests',
|
|
281
|
-
artifactId: 'calculator',
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
js: { npm: 'jsii-calc' },
|
|
285
|
-
python: {
|
|
286
|
-
distName: 'jsii-calc',
|
|
287
|
-
module: 'jsii_calc',
|
|
288
|
-
classifiers: ['Test :: Classifier :: Is Dummy'],
|
|
289
|
-
},
|
|
290
|
-
});
|
|
291
|
-
expect(sandbox.naming({ assembly: '@scope/jsii-calc-lib' }).naming).toEqual({
|
|
292
|
-
dotnet: {
|
|
293
|
-
namespace: 'Amazon.JSII.Tests.CalculatorNamespace.LibNamespace',
|
|
294
|
-
packageId: 'Amazon.JSII.Tests.CalculatorPackageId.LibPackageId',
|
|
295
|
-
versionSuffix: '-devpreview',
|
|
296
|
-
},
|
|
297
|
-
go: {
|
|
298
|
-
moduleName: 'github.com/aws/jsii/jsii-calc/go',
|
|
299
|
-
versionSuffix: '-devpreview',
|
|
300
|
-
},
|
|
301
|
-
java: {
|
|
302
|
-
package: 'software.amazon.jsii.tests.calculator.lib',
|
|
303
|
-
maven: {
|
|
304
|
-
groupId: 'software.amazon.jsii.tests',
|
|
305
|
-
artifactId: 'calculator-lib',
|
|
306
|
-
versionSuffix: '.DEVPREVIEW',
|
|
307
|
-
},
|
|
308
|
-
},
|
|
309
|
-
js: { npm: '@scope/jsii-calc-lib' },
|
|
310
|
-
python: {
|
|
311
|
-
distName: 'scope.jsii-calc-lib',
|
|
312
|
-
module: 'scope.jsii_calc_lib',
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
defineTest('collection of objects', (sandbox) => {
|
|
317
|
-
const sum = sandbox.create({ fqn: 'jsii-calc.Sum' });
|
|
318
|
-
const n1 = sandbox.create({ fqn: '@scope/jsii-calc-lib.Number', args: [10] });
|
|
319
|
-
const n2 = sandbox.create({ fqn: '@scope/jsii-calc-lib.Number', args: [4] });
|
|
320
|
-
const n3 = sandbox.create({ fqn: 'jsii-calc.Power', args: [n1, n2] });
|
|
321
|
-
sandbox.set({ objref: sum, property: 'parts', value: [n1, n2, n3] });
|
|
322
|
-
const parts = sandbox.get({ objref: sum, property: 'parts' }).value;
|
|
323
|
-
expect(sandbox.get({ objref: parts[0], property: 'value' }).value).toBe(10);
|
|
324
|
-
expect(sandbox.get({ objref: parts[1], property: 'value' }).value).toBe(4);
|
|
325
|
-
expect(sandbox.get({ objref: parts[2], property: 'value' }).value).toBe(Math.pow(10, 4));
|
|
326
|
-
const expr = sandbox.get({ objref: sum, property: 'expression' }).value;
|
|
327
|
-
expect(sandbox.invoke({ objref: expr, method: 'toString' }).result).toBe('(((0 + 10) + 4) + ((((1 * 10) * 10) * 10) * 10))');
|
|
328
|
-
expect(sandbox.get({ objref: expr, property: 'value' }).value).toBe(10014);
|
|
329
|
-
});
|
|
330
|
-
defineTest('class not found', (sandbox) => {
|
|
331
|
-
expect(() => sandbox.create({ fqn: 'NotFound', args: [] })).toThrow();
|
|
332
|
-
});
|
|
333
|
-
defineTest('type-checking: method and property names are validated against class and base classes', (sandbox) => {
|
|
334
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.Calculator' });
|
|
335
|
-
sandbox.get({ objref: obj, property: 'stringStyle' }); // property from CompositeOperation
|
|
336
|
-
sandbox.get({ objref: obj, property: 'value' }); // property from Value
|
|
337
|
-
sandbox.get({ objref: obj, property: 'curr' }); // property from Calculator
|
|
338
|
-
sandbox.invoke({ objref: obj, method: 'typeName' }); // method from Value
|
|
339
|
-
sandbox.invoke({ objref: obj, method: 'add', args: [1] }); // method from Calculator
|
|
340
|
-
expect(() => sandbox.get({ objref: obj, property: 'notFound' })).toThrow();
|
|
341
|
-
expect(() => sandbox.invoke({ objref: obj, method: 'boo', args: [] })).toThrow();
|
|
342
|
-
});
|
|
343
|
-
defineTest('type-checking; module not found', (sandbox) => {
|
|
344
|
-
expect(() => sandbox.create({ fqn: 'jsii$boo.Foo' })).toThrow(/Module 'jsii\$boo' not found/);
|
|
345
|
-
});
|
|
346
|
-
defineTest('type-checking: type not found', (sandbox) => {
|
|
347
|
-
expect(() => sandbox.create({ fqn: 'jsii-calc.Unknown' })).toThrow(/Type 'jsii-calc.Unknown' not found/);
|
|
348
|
-
});
|
|
349
|
-
defineTest('type-checking: try to create an object from a non-class type', (sandbox) => {
|
|
350
|
-
expect(() => sandbox.create({ fqn: 'jsii-calc.AllTypesEnum' })).toThrow(/Unexpected FQN kind/);
|
|
351
|
-
});
|
|
352
|
-
defineTest('type-checking: argument count in methods and initializers', (sandbox) => {
|
|
353
|
-
// ctor has one optional argument
|
|
354
|
-
sandbox.create({ fqn: 'jsii-calc.Calculator' });
|
|
355
|
-
sandbox.create({ fqn: 'jsii-calc.Calculator', args: [{}] });
|
|
356
|
-
// but we expect an error if more arguments are passed
|
|
357
|
-
expect(() => sandbox.create({ fqn: 'jsii-calc.Calculator', args: [1, 2, 3] })).toThrow(/Too many arguments/);
|
|
358
|
-
expect(() => sandbox.create({ fqn: 'jsii-calc.Calculator', args: [1, 2, 3, 4] })).toThrow(/Too many arguments/);
|
|
359
|
-
expect(() => sandbox.create({ fqn: 'jsii-calc.Add', args: [] })).toThrow(/Not enough arguments/);
|
|
360
|
-
expect(() => sandbox.create({ fqn: 'jsii-calc.Add', args: [1] })).toThrow(/Not enough arguments/);
|
|
361
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.RuntimeTypeChecking' });
|
|
362
|
-
expect(() => sandbox.invoke({
|
|
363
|
-
objref: obj,
|
|
364
|
-
method: 'methodWithOptionalArguments',
|
|
365
|
-
args: [],
|
|
366
|
-
})).toThrow(/Not enough arguments/);
|
|
367
|
-
expect(() => sandbox.invoke({
|
|
368
|
-
objref: obj,
|
|
369
|
-
method: 'methodWithOptionalArguments',
|
|
370
|
-
args: [1],
|
|
371
|
-
})).toThrow(/Not enough arguments/);
|
|
372
|
-
sandbox.invoke({
|
|
373
|
-
objref: obj,
|
|
374
|
-
method: 'methodWithOptionalArguments',
|
|
375
|
-
args: [1, 'hello'],
|
|
376
|
-
});
|
|
377
|
-
sandbox.invoke({
|
|
378
|
-
objref: obj,
|
|
379
|
-
method: 'methodWithOptionalArguments',
|
|
380
|
-
args: [1, 'hello', { [lib_1.api.TOKEN_DATE]: new Date().toISOString() }],
|
|
381
|
-
});
|
|
382
|
-
expect(() => sandbox.invoke({
|
|
383
|
-
objref: obj,
|
|
384
|
-
method: 'methodWithOptionalArguments',
|
|
385
|
-
args: [
|
|
386
|
-
1,
|
|
387
|
-
'hello',
|
|
388
|
-
{ [lib_1.api.TOKEN_DATE]: new Date().toISOString() },
|
|
389
|
-
'too much',
|
|
390
|
-
],
|
|
391
|
-
})).toThrow(/Too many arguments/);
|
|
392
|
-
});
|
|
393
|
-
defineTest('verify object literals are converted to real classes', (sandbox) => {
|
|
394
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.JSObjectLiteralToNative' });
|
|
395
|
-
const obj2 = sandbox.invoke({
|
|
396
|
-
objref: obj,
|
|
397
|
-
method: 'returnLiteral',
|
|
398
|
-
}).result;
|
|
399
|
-
expect(obj2[lib_1.api.TOKEN_REF]).toBeTruthy(); // verify that we received a ref as a result;
|
|
400
|
-
const objid = obj2[lib_1.api.TOKEN_REF];
|
|
401
|
-
expect(objid).toMatch(/^jsii-calc.JSObjectLiteralToNativeClass@/);
|
|
402
|
-
});
|
|
403
|
-
defineTest('get a property from an type that only has base class properties', (sandbox) => {
|
|
404
|
-
const obj = sandbox.create({
|
|
405
|
-
fqn: 'jsii-calc.DerivedClassHasNoProperties.Derived',
|
|
406
|
-
});
|
|
407
|
-
sandbox.set({ objref: obj, property: 'prop', value: 'hi' });
|
|
408
|
-
expect(sandbox.get({ objref: obj, property: 'prop' }).value).toBe('hi');
|
|
409
|
-
});
|
|
410
|
-
defineTest('async overrides: ignores overrides for unknown methods (to allow derived class to just pass all local method names)', (sandbox) => {
|
|
411
|
-
sandbox.create({
|
|
412
|
-
fqn: 'jsii-calc.AsyncVirtualMethods',
|
|
413
|
-
overrides: [{ method: 'notFound' }],
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
defineTest('async overrides: override a method', async (sandbox) => {
|
|
417
|
-
// first call without an override and expect pendingCallbacks to return
|
|
418
|
-
// an empty array.
|
|
419
|
-
const obj1 = sandbox.create({ fqn: 'jsii-calc.AsyncVirtualMethods' });
|
|
420
|
-
async function callWithOverride(overrideCallback) {
|
|
421
|
-
const promise1 = sandbox.begin({ objref: obj1, method: 'callMe' });
|
|
422
|
-
expect(sandbox.callbacks().callbacks.length).toBe(0);
|
|
423
|
-
const result1 = (await sandbox.end(promise1)).result;
|
|
424
|
-
expect(result1).toBe(128);
|
|
425
|
-
// now add an override and complete it with a some value.
|
|
426
|
-
const obj = sandbox.create({
|
|
427
|
-
fqn: 'jsii-calc.AsyncVirtualMethods',
|
|
428
|
-
overrides: [{ method: 'overrideMe', cookie: 'myCookie' }],
|
|
429
|
-
});
|
|
430
|
-
const promise2 = sandbox.begin({ objref: obj, method: 'callMe' });
|
|
431
|
-
const callbacks = sandbox.callbacks().callbacks;
|
|
432
|
-
expect(callbacks.length).toBe(1);
|
|
433
|
-
const cb = callbacks[0];
|
|
434
|
-
expect(cb.invoke).toBeTruthy();
|
|
435
|
-
expect(cb.invoke.objref).toEqual(obj);
|
|
436
|
-
expect(cb.invoke.method).toBe('overrideMe');
|
|
437
|
-
expect(cb.cookie).toBe('myCookie');
|
|
438
|
-
expect(cb.invoke.args).toEqual([10]);
|
|
439
|
-
// calling pendingCallbacks again will return zero results
|
|
440
|
-
// since all callbacks are moved to "waiting" state
|
|
441
|
-
expect(sandbox.callbacks().callbacks.length).toBe(0);
|
|
442
|
-
// call the override
|
|
443
|
-
let callbackResult;
|
|
444
|
-
let callbackError;
|
|
445
|
-
try {
|
|
446
|
-
callbackResult = overrideCallback(cb.invoke.args[0]);
|
|
447
|
-
}
|
|
448
|
-
catch (e) {
|
|
449
|
-
callbackError = e.message;
|
|
450
|
-
}
|
|
451
|
-
// complete the callback with a successful return value of 600
|
|
452
|
-
sandbox.complete({
|
|
453
|
-
cbid: cb.cbid,
|
|
454
|
-
err: callbackError,
|
|
455
|
-
result: callbackResult,
|
|
456
|
-
});
|
|
457
|
-
// await for the promise and verify that the completion was successfully
|
|
458
|
-
// conveyed from the callback.
|
|
459
|
-
return (await sandbox.end(promise2)).result;
|
|
460
|
-
}
|
|
461
|
-
expect(await callWithOverride((_) => 600)).toBe(608);
|
|
462
|
-
expect(await callWithOverride((x) => 2 * x)).toBe(28);
|
|
463
|
-
// override throws
|
|
464
|
-
return expect(callWithOverride((_) => {
|
|
465
|
-
throw new Error('Bla');
|
|
466
|
-
})).rejects.toThrow('Bla');
|
|
467
|
-
});
|
|
468
|
-
defineTest('async overrides: directly call a method with an override from native code should invoke the "super.method" since it can only be done by the derived class', async (sandbox) => {
|
|
469
|
-
const obj = sandbox.create({
|
|
470
|
-
fqn: 'jsii-calc.AsyncVirtualMethods',
|
|
471
|
-
overrides: [{ method: 'overrideMe', cookie: 'myCookie' }],
|
|
472
|
-
});
|
|
473
|
-
const promise = sandbox.begin({
|
|
474
|
-
objref: obj,
|
|
475
|
-
method: 'overrideMe',
|
|
476
|
-
args: [12],
|
|
477
|
-
});
|
|
478
|
-
// no callbacks should be pending, since this should invoke "super"
|
|
479
|
-
expect(sandbox.callbacks().callbacks.length).toBe(0);
|
|
480
|
-
expect((await sandbox.end(promise)).result).toBe(144);
|
|
481
|
-
});
|
|
482
|
-
defineTest('async overrides: two overrides', async (sandbox) => {
|
|
483
|
-
const obj = sandbox.create({
|
|
484
|
-
fqn: 'jsii-calc.AsyncVirtualMethods',
|
|
485
|
-
overrides: [
|
|
486
|
-
{ method: 'overrideMeToo', cookie: 'cookie1' },
|
|
487
|
-
{ method: 'overrideMe', cookie: 'cookie2' },
|
|
488
|
-
],
|
|
489
|
-
});
|
|
490
|
-
const promise = sandbox.begin({ objref: obj, method: 'callMe' });
|
|
491
|
-
const callbacks1 = sandbox.callbacks();
|
|
492
|
-
expect(callbacks1.callbacks.length).toBe(1);
|
|
493
|
-
sandbox.complete({ cbid: callbacks1.callbacks[0].cbid, result: 666 });
|
|
494
|
-
await processPendingPromises(sandbox); // processing next promise
|
|
495
|
-
const callbacks2 = sandbox.callbacks();
|
|
496
|
-
expect(callbacks2.callbacks.length).toBe(1);
|
|
497
|
-
sandbox.complete({ cbid: callbacks2.callbacks[0].cbid, result: 101 });
|
|
498
|
-
await processPendingPromises(sandbox);
|
|
499
|
-
const result = await sandbox.end({ promiseid: promise.promiseid });
|
|
500
|
-
expect(result.result).toBe(775);
|
|
501
|
-
});
|
|
502
|
-
/**
|
|
503
|
-
* This test simulates a sitation where an async method is called, which invokes
|
|
504
|
-
* an async override in return, but the override's promise is not called synchronously
|
|
505
|
-
* but rather within the "next tick". This can happen (at the discression of the runtime
|
|
506
|
-
* and we should verify that the @jsii/runtime (or any runtime for that matter) "processes"
|
|
507
|
-
* promises after a "begin" invocation in order to make sure any callbacks are queued.
|
|
508
|
-
*
|
|
509
|
-
* This is also relevant immediate after a "complete" invocation, which fulfills an async
|
|
510
|
-
* promise and may subsequently queue more callbacks before one can "end" the original
|
|
511
|
-
* async request.
|
|
512
|
-
*
|
|
513
|
-
* Yes, this is hairy.
|
|
514
|
-
*
|
|
515
|
-
* host.ts#93 is where this is implemented in the runtime.
|
|
516
|
-
*/
|
|
517
|
-
defineTest('async overrides - process promises after "begin"', async (sandbox) => {
|
|
518
|
-
const obj = sandbox.create({
|
|
519
|
-
fqn: 'jsii-calc.AsyncVirtualMethods',
|
|
520
|
-
overrides: [
|
|
521
|
-
{ method: 'overrideMe', cookie: 'cookie2' },
|
|
522
|
-
{ method: 'overrideMeToo' },
|
|
523
|
-
],
|
|
524
|
-
});
|
|
525
|
-
const p1 = sandbox.begin({ objref: obj, method: 'callMeDoublePromise' });
|
|
526
|
-
// this is needed in order to cycle through another event loop so
|
|
527
|
-
// that promises that are lazily called will be processed (nothing ensures
|
|
528
|
-
// that the promise callback will be invokes synchronously).
|
|
529
|
-
await processPendingPromises(sandbox);
|
|
530
|
-
const callbacks1 = sandbox.callbacks();
|
|
531
|
-
expect(callbacks1.callbacks.length).toBe(1);
|
|
532
|
-
// --------------- start of "override" execution
|
|
533
|
-
// we simulate the situation where the override invokes another async override
|
|
534
|
-
// call a sync method (just for fun)
|
|
535
|
-
const out = sandbox.invoke({ objref: obj, method: 'dontOverrideMe' });
|
|
536
|
-
expect(out).toEqual({ result: 8 });
|
|
537
|
-
// call another overridden async method
|
|
538
|
-
const p2 = sandbox.begin({ objref: obj, method: 'callMe2' });
|
|
539
|
-
// we should get a a callback to overrideMe2
|
|
540
|
-
const callback2 = sandbox.callbacks();
|
|
541
|
-
expect(callback2.callbacks.length).toBe(1);
|
|
542
|
-
expect(callback2.callbacks[0].invoke.method).toBe('overrideMeToo');
|
|
543
|
-
// complete the inner callback
|
|
544
|
-
sandbox.complete({ cbid: callback2.callbacks[0].cbid, result: 9999 });
|
|
545
|
-
// fetch it
|
|
546
|
-
expect(await sandbox.end({ promiseid: p2.promiseid })).toEqual({
|
|
547
|
-
result: 9999,
|
|
548
|
-
});
|
|
549
|
-
// no more callbacks
|
|
550
|
-
expect(sandbox.callbacks()).toEqual({ callbacks: [] });
|
|
551
|
-
// now complete the outer callback
|
|
552
|
-
sandbox.complete({ cbid: callbacks1.callbacks[0].cbid, result: 8888 });
|
|
553
|
-
// required: process pending promises so that we will get the next one in the callbacks list
|
|
554
|
-
await processPendingPromises(sandbox);
|
|
555
|
-
// ------ end of execution of "overrideMe"
|
|
556
|
-
// now we expect 'overrideMeToo' to be called back
|
|
557
|
-
const cb3 = sandbox.callbacks();
|
|
558
|
-
expect(cb3.callbacks.length).toBe(1);
|
|
559
|
-
expect(cb3.callbacks[0].invoke.method).toBe('overrideMeToo');
|
|
560
|
-
// complete it
|
|
561
|
-
sandbox.complete({ cbid: cb3.callbacks[0].cbid, result: -20 });
|
|
562
|
-
// no more callbacks
|
|
563
|
-
const cb4 = sandbox.callbacks();
|
|
564
|
-
expect(cb4.callbacks.length).toBe(0);
|
|
565
|
-
const result = await sandbox.end({ promiseid: p1.promiseid });
|
|
566
|
-
expect(result.result).toBe(8876);
|
|
567
|
-
});
|
|
568
|
-
function processPendingPromises(sandbox) {
|
|
569
|
-
return vm.runInContext('new Promise(done => setImmediate(done));', sandbox.sandbox);
|
|
570
|
-
}
|
|
571
|
-
defineTest('sync overrides', async (sandbox) => {
|
|
572
|
-
const pre = sandbox.create({ fqn: 'jsii-calc.SyncVirtualMethods' });
|
|
573
|
-
// without override
|
|
574
|
-
expect(sandbox.invoke({ objref: pre, method: 'callerIsMethod' }).result).toBe(20);
|
|
575
|
-
expect(sandbox.get({ objref: pre, property: 'callerIsProperty' }).value).toBe(20);
|
|
576
|
-
const p = sandbox.begin({ objref: pre, method: 'callerIsAsync' });
|
|
577
|
-
expect((await sandbox.end({ promiseid: p.promiseid })).result).toBe(20);
|
|
578
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
579
|
-
expect(callback.cookie).toBe('myCookie');
|
|
580
|
-
expect(callback.invoke.objref[api_1.TOKEN_REF]).toMatch(/jsii-calc\.SyncVirtualMethods/);
|
|
581
|
-
expect(callback.invoke.method).toBe('virtualMethod');
|
|
582
|
-
expect(callback.invoke.args[0]).toBe(10);
|
|
583
|
-
// to make things a bit more interesting, let's interact with a jsii object
|
|
584
|
-
// from within the callback
|
|
585
|
-
const lhs = sandbox.create({
|
|
586
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
587
|
-
args: [callback.invoke.args[0]],
|
|
588
|
-
});
|
|
589
|
-
const rhs = sandbox.create({
|
|
590
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
591
|
-
args: [12],
|
|
592
|
-
});
|
|
593
|
-
const add = sandbox.create({ fqn: 'jsii-calc.Add', args: [lhs, rhs] });
|
|
594
|
-
return sandbox.get({ objref: add, property: 'value' }).value;
|
|
595
|
-
});
|
|
596
|
-
// now make the same set of calls, and you will notice that the results are affected by the override.
|
|
597
|
-
const obj = sandbox.create({
|
|
598
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
599
|
-
overrides: [{ method: 'virtualMethod', cookie: 'myCookie' }],
|
|
600
|
-
});
|
|
601
|
-
expect(sandbox.invoke({ objref: obj, method: 'callerIsMethod' }).result).toBe(22);
|
|
602
|
-
expect(sandbox.get({ objref: obj, property: 'callerIsProperty' }).value).toBe(22);
|
|
603
|
-
// verify callbacks can also be called by setters.
|
|
604
|
-
let called = false;
|
|
605
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
606
|
-
expect(callback.invoke.args[0]).toBe(999);
|
|
607
|
-
called = true;
|
|
608
|
-
return callback.invoke.args[0];
|
|
609
|
-
});
|
|
610
|
-
sandbox.set({ objref: obj, property: 'callerIsProperty', value: 999 });
|
|
611
|
-
expect(called).toBeTruthy();
|
|
612
|
-
});
|
|
613
|
-
defineTest('sync overrides with async caller', async (sandbox) => {
|
|
614
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
615
|
-
expect(callback.cookie).toBe('myCookie');
|
|
616
|
-
expect(callback.invoke.objref[api_1.TOKEN_REF]).toMatch(/jsii-calc\.SyncVirtualMethods/);
|
|
617
|
-
expect(callback.invoke.method).toBe('virtualMethod');
|
|
618
|
-
expect(callback.invoke.args[0]).toBe(10);
|
|
619
|
-
// to make things a bit more interesting, let's interact with a jsii object
|
|
620
|
-
// from within the callback
|
|
621
|
-
const lhs = sandbox.create({
|
|
622
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
623
|
-
args: [callback.invoke.args[0]],
|
|
624
|
-
});
|
|
625
|
-
const rhs = sandbox.create({
|
|
626
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
627
|
-
args: [12],
|
|
628
|
-
});
|
|
629
|
-
const add = sandbox.create({ fqn: 'jsii-calc.Add', args: [lhs, rhs] });
|
|
630
|
-
return sandbox.get({ objref: add, property: 'value' }).value;
|
|
631
|
-
});
|
|
632
|
-
const obj = sandbox.create({
|
|
633
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
634
|
-
overrides: [{ method: 'virtualMethod', cookie: 'myCookie' }],
|
|
635
|
-
});
|
|
636
|
-
const p2 = sandbox.begin({ objref: obj, method: 'callerIsAsync' });
|
|
637
|
-
expect((await sandbox.end({ promiseid: p2.promiseid })).result).toBe(22);
|
|
638
|
-
});
|
|
639
|
-
defineTest('sync overrides: properties - readwrite', (sandbox) => {
|
|
640
|
-
const obj = sandbox.create({
|
|
641
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
642
|
-
overrides: [{ property: 'theProperty', cookie: 'myCookie1234' }],
|
|
643
|
-
});
|
|
644
|
-
let setValue;
|
|
645
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
646
|
-
expect(callback.cookie).toBe('myCookie1234');
|
|
647
|
-
if (callback.get) {
|
|
648
|
-
expect(callback.get.property).toBe('theProperty');
|
|
649
|
-
return 'override applied';
|
|
650
|
-
}
|
|
651
|
-
else if (callback.set) {
|
|
652
|
-
expect(callback.set.property).toBe('theProperty');
|
|
653
|
-
setValue = callback.set.value;
|
|
654
|
-
return undefined;
|
|
655
|
-
}
|
|
656
|
-
throw new Error('Invalid callback. Expected get/set');
|
|
657
|
-
});
|
|
658
|
-
const value = sandbox.invoke({
|
|
659
|
-
objref: obj,
|
|
660
|
-
method: 'retrieveValueOfTheProperty',
|
|
661
|
-
});
|
|
662
|
-
expect(value).toEqual({ result: 'override applied' });
|
|
663
|
-
// make sure we can still set the property
|
|
664
|
-
sandbox.invoke({
|
|
665
|
-
objref: obj,
|
|
666
|
-
method: 'modifyValueOfTheProperty',
|
|
667
|
-
args: ['1234'],
|
|
668
|
-
});
|
|
669
|
-
expect(setValue).toBe('1234');
|
|
670
|
-
});
|
|
671
|
-
defineTest('sync overrides: properties - readwrite (backed by functions)', (sandbox) => {
|
|
672
|
-
const obj = sandbox.create({
|
|
673
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
674
|
-
overrides: [{ property: 'otherProperty', cookie: 'myCookie1234' }],
|
|
675
|
-
});
|
|
676
|
-
let setValue;
|
|
677
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
678
|
-
expect(callback.cookie).toBe('myCookie1234');
|
|
679
|
-
if (callback.get) {
|
|
680
|
-
expect(callback.get.property).toBe('otherProperty');
|
|
681
|
-
return 'override applied for otherProperty';
|
|
682
|
-
}
|
|
683
|
-
else if (callback.set) {
|
|
684
|
-
expect(callback.set.property).toBe('otherProperty');
|
|
685
|
-
setValue = callback.set.value;
|
|
686
|
-
return undefined;
|
|
687
|
-
}
|
|
688
|
-
throw new Error('Invalid callback. Expected get/set');
|
|
689
|
-
});
|
|
690
|
-
const value = sandbox.invoke({
|
|
691
|
-
objref: obj,
|
|
692
|
-
method: 'retrieveOtherProperty',
|
|
693
|
-
});
|
|
694
|
-
expect(value).toEqual({ result: 'override applied for otherProperty' });
|
|
695
|
-
// make sure we can still set the property
|
|
696
|
-
sandbox.invoke({
|
|
697
|
-
objref: obj,
|
|
698
|
-
method: 'modifyOtherProperty',
|
|
699
|
-
args: ['778877'],
|
|
700
|
-
});
|
|
701
|
-
expect(setValue).toBe('778877');
|
|
702
|
-
});
|
|
703
|
-
defineTest('sync overrides: duplicate overrides for the same property', (sandbox) => {
|
|
704
|
-
expect(() => sandbox.create({
|
|
705
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
706
|
-
overrides: [
|
|
707
|
-
{ property: 'otherProperty', cookie: 'myCookie1234' },
|
|
708
|
-
{ property: 'otherProperty', cookie: 'yourCookie' },
|
|
709
|
-
],
|
|
710
|
-
})).toThrow();
|
|
711
|
-
});
|
|
712
|
-
defineTest('sync overrides: properties - readonly', (sandbox) => {
|
|
713
|
-
const obj = sandbox.create({
|
|
714
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
715
|
-
overrides: [{ property: 'readonlyProperty', cookie: 'myCookie1234' }],
|
|
716
|
-
});
|
|
717
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
718
|
-
expect(callback.cookie).toBe('myCookie1234');
|
|
719
|
-
expect(callback.get).toBeTruthy();
|
|
720
|
-
expect(callback.get.property).toBe('readonlyProperty');
|
|
721
|
-
return 'override for readonly property applied';
|
|
722
|
-
});
|
|
723
|
-
const value = sandbox.invoke({
|
|
724
|
-
objref: obj,
|
|
725
|
-
method: 'retrieveReadOnlyProperty',
|
|
726
|
-
});
|
|
727
|
-
expect(value).toEqual({ result: 'override for readonly property applied' });
|
|
728
|
-
// can't set the value of a readonly property, dah!
|
|
729
|
-
expect(() => sandbox.set({ objref: obj, property: 'readonlyProperty', value: 1234 })).toThrow();
|
|
730
|
-
});
|
|
731
|
-
defineTest('sync overrides: properties - get calls super', (sandbox) => {
|
|
732
|
-
const obj = sandbox.create({
|
|
733
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
734
|
-
overrides: [{ property: 'theProperty' }],
|
|
735
|
-
});
|
|
736
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
737
|
-
expect(callback.get.property).toBe('theProperty');
|
|
738
|
-
const superValue = sandbox.get({ objref: obj, property: 'theProperty' });
|
|
739
|
-
return `override, super=${superValue.value}`;
|
|
740
|
-
});
|
|
741
|
-
const value = sandbox.invoke({
|
|
742
|
-
objref: obj,
|
|
743
|
-
method: 'retrieveValueOfTheProperty',
|
|
744
|
-
});
|
|
745
|
-
expect(value).toEqual({ result: 'override, super=initial value' });
|
|
746
|
-
});
|
|
747
|
-
defineTest('sync overrides: properties - set calls super', (sandbox) => {
|
|
748
|
-
const obj = sandbox.create({
|
|
749
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
750
|
-
overrides: [{ property: 'theProperty' }],
|
|
751
|
-
});
|
|
752
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
753
|
-
if (callback.get) {
|
|
754
|
-
return sandbox.get({ objref: obj, property: 'theProperty' }).value;
|
|
755
|
-
}
|
|
756
|
-
if (callback.set) {
|
|
757
|
-
return sandbox.set({
|
|
758
|
-
objref: obj,
|
|
759
|
-
property: 'theProperty',
|
|
760
|
-
value: `set by override: ${callback.set.value}`,
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
throw new Error(`Unexpected callback request: ${JSON.stringify(callback)}`);
|
|
764
|
-
});
|
|
765
|
-
sandbox.invoke({
|
|
766
|
-
objref: obj,
|
|
767
|
-
method: 'modifyValueOfTheProperty',
|
|
768
|
-
args: ['new_value'],
|
|
769
|
-
});
|
|
770
|
-
const value = sandbox.invoke({
|
|
771
|
-
objref: obj,
|
|
772
|
-
method: 'retrieveValueOfTheProperty',
|
|
773
|
-
});
|
|
774
|
-
expect(value).toEqual({ result: 'set by override: new_value' });
|
|
775
|
-
});
|
|
776
|
-
defineTest('sync overrides: properties - verify keys are enumerable', (sandbox) => {
|
|
777
|
-
const obj = sandbox.create({
|
|
778
|
-
fqn: 'Object',
|
|
779
|
-
overrides: [{ property: 'foo' }, { property: 'readOnlyString' }],
|
|
780
|
-
});
|
|
781
|
-
const reader = sandbox.create({
|
|
782
|
-
fqn: 'jsii-calc.UsesInterfaceWithProperties',
|
|
783
|
-
args: [obj],
|
|
784
|
-
});
|
|
785
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
786
|
-
var _a, _b;
|
|
787
|
-
if (((_a = callback.get) === null || _a === void 0 ? void 0 : _a.property) === 'foo') {
|
|
788
|
-
return 999;
|
|
789
|
-
}
|
|
790
|
-
if (((_b = callback.get) === null || _b === void 0 ? void 0 : _b.property) === 'readOnlyString') {
|
|
791
|
-
return 'STR';
|
|
792
|
-
}
|
|
793
|
-
throw new Error('Unexpected callback');
|
|
794
|
-
});
|
|
795
|
-
const result = sandbox.invoke({
|
|
796
|
-
objref: reader,
|
|
797
|
-
method: 'readStringAndNumber',
|
|
798
|
-
args: [obj],
|
|
799
|
-
});
|
|
800
|
-
expect(result).toEqual({
|
|
801
|
-
result: 'base=STR child=999 keys=[foo,readOnlyString]',
|
|
802
|
-
});
|
|
803
|
-
});
|
|
804
|
-
defineTest('sync overrides: returns an object', (sandbox) => {
|
|
805
|
-
const returnsNumber = sandbox.create({
|
|
806
|
-
fqn: 'Object',
|
|
807
|
-
overrides: [{ method: 'obtainNumber' }, { property: 'numberProp' }],
|
|
808
|
-
});
|
|
809
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.OverrideReturnsObject' });
|
|
810
|
-
const number100 = sandbox.create({
|
|
811
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
812
|
-
args: [100],
|
|
813
|
-
});
|
|
814
|
-
const number500 = sandbox.create({
|
|
815
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
816
|
-
args: [500],
|
|
817
|
-
});
|
|
818
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
819
|
-
var _a, _b;
|
|
820
|
-
if (((_a = callback.invoke) === null || _a === void 0 ? void 0 : _a.method) === 'obtainNumber') {
|
|
821
|
-
return number100;
|
|
822
|
-
}
|
|
823
|
-
if (((_b = callback.get) === null || _b === void 0 ? void 0 : _b.property) === 'numberProp') {
|
|
824
|
-
return number500;
|
|
825
|
-
}
|
|
826
|
-
throw new Error(`Unexpected callback:${JSON.stringify(callback)}`);
|
|
827
|
-
});
|
|
828
|
-
const ret = sandbox.invoke({
|
|
829
|
-
objref: obj,
|
|
830
|
-
method: 'test',
|
|
831
|
-
args: [returnsNumber],
|
|
832
|
-
});
|
|
833
|
-
expect(ret).toEqual({ result: 100 * 2 + 500 * 2 });
|
|
834
|
-
});
|
|
835
|
-
defineTest('fail to begin async from sync - method', (sandbox) => {
|
|
836
|
-
const obj = sandbox.create({
|
|
837
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
838
|
-
overrides: [{ method: 'virtualMethod', cookie: 'myCookie' }],
|
|
839
|
-
});
|
|
840
|
-
let called = 0;
|
|
841
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((_) => {
|
|
842
|
-
const innerObj = sandbox.create({ fqn: 'jsii-calc.AsyncVirtualMethods' });
|
|
843
|
-
expect(() => sandbox.begin({ objref: innerObj, method: 'callMe' })).toThrow();
|
|
844
|
-
called++;
|
|
845
|
-
return 42; // Need a valid return value
|
|
846
|
-
});
|
|
847
|
-
sandbox.invoke({ objref: obj, method: 'callerIsMethod' });
|
|
848
|
-
expect(called).toBe(1);
|
|
849
|
-
sandbox.get({ objref: obj, property: 'callerIsProperty' });
|
|
850
|
-
expect(called).toBe(2);
|
|
851
|
-
sandbox.set({ objref: obj, property: 'callerIsProperty', value: 33 });
|
|
852
|
-
expect(called).toBe(3);
|
|
853
|
-
});
|
|
854
|
-
defineTest('the "Object" FQN can be used to allow creating empty objects with overrides which comply with an interface', (sandbox) => {
|
|
855
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.Polymorphism' });
|
|
856
|
-
const friendly = sandbox.create({
|
|
857
|
-
fqn: 'Object',
|
|
858
|
-
overrides: [{ method: 'hello' }],
|
|
859
|
-
});
|
|
860
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((_) => 'oh, hello');
|
|
861
|
-
const ret = sandbox.invoke({
|
|
862
|
-
objref: obj,
|
|
863
|
-
method: 'sayHello',
|
|
864
|
-
args: [friendly],
|
|
865
|
-
});
|
|
866
|
-
expect(ret.result).toBe('oh, oh, hello');
|
|
867
|
-
});
|
|
868
|
-
defineTest('literal objects can be returned when an interface is expected, and they will be adorned with jsii metadata so they can be interacted with', (sandbox) => {
|
|
869
|
-
const obj = sandbox.create({
|
|
870
|
-
fqn: 'jsii-calc.JSObjectLiteralForInterface',
|
|
871
|
-
});
|
|
872
|
-
const ret = sandbox.invoke({ objref: obj, method: 'giveMeFriendly' });
|
|
873
|
-
expect(sandbox.invoke({ objref: ret.result, method: 'hello' })).toEqual({
|
|
874
|
-
result: 'I am literally friendly!',
|
|
875
|
-
});
|
|
876
|
-
const ret2 = sandbox.invoke({
|
|
877
|
-
objref: obj,
|
|
878
|
-
method: 'giveMeFriendlyGenerator',
|
|
879
|
-
});
|
|
880
|
-
expect(sandbox.invoke({ objref: ret2.result, method: 'hello' })).toEqual({
|
|
881
|
-
result: 'giveMeFriendlyGenerator',
|
|
882
|
-
});
|
|
883
|
-
expect(sandbox.invoke({ objref: ret2.result, method: 'next' })).toEqual({
|
|
884
|
-
result: 42,
|
|
885
|
-
});
|
|
886
|
-
});
|
|
887
|
-
defineTest('exceptions include a stack trace into the original source code', (sandbox) => {
|
|
888
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.Thrower' });
|
|
889
|
-
expect(() => {
|
|
890
|
-
try {
|
|
891
|
-
sandbox.invoke({ objref: obj, method: 'throwError' });
|
|
892
|
-
}
|
|
893
|
-
catch (error) {
|
|
894
|
-
const regexp = /^\s*at Thrower\.doThrowError \(.*jsii[-_]calc.*\/lib\/compliance\.ts:\d+:\d+\)$/m;
|
|
895
|
-
expect(regexp.test(error.stack)).toBeTruthy(); // The stack trace includes the path to the original source file
|
|
896
|
-
throw error;
|
|
897
|
-
}
|
|
898
|
-
}).toThrow();
|
|
899
|
-
});
|
|
900
|
-
defineTest('variadic methods can be called', (sandbox) => {
|
|
901
|
-
const obj = sandbox.create({ fqn: 'jsii-calc.VariadicMethod' });
|
|
902
|
-
expect(sandbox.invoke({ objref: obj, method: 'asArray', args: [1, 2, 3, 4] })
|
|
903
|
-
.result).toEqual([1, 2, 3, 4]);
|
|
904
|
-
});
|
|
905
|
-
defineTest('variadic methods can be called without any vararg', (sandbox) => {
|
|
906
|
-
const obj = sandbox.create({
|
|
907
|
-
fqn: 'jsii-calc.VariadicMethod',
|
|
908
|
-
args: [1, 2, 3],
|
|
909
|
-
});
|
|
910
|
-
expect(sandbox.invoke({ objref: obj, method: 'asArray', args: [4] }).result).toEqual([1, 2, 3, 4]);
|
|
911
|
-
});
|
|
912
|
-
defineTest('static properties - get', (sandbox) => {
|
|
913
|
-
const value = sandbox.sget({ fqn: 'jsii-calc.Statics', property: 'Foo' });
|
|
914
|
-
expect(value).toEqual({ value: 'hello' });
|
|
915
|
-
});
|
|
916
|
-
defineTest('fails: static properties - set readonly', (sandbox) => {
|
|
917
|
-
expect(() => sandbox.sset({ fqn: 'jsii-calc.Statics', property: 'Foo', value: 123 })).toThrow();
|
|
918
|
-
});
|
|
919
|
-
defineTest('static properties - set', (sandbox) => {
|
|
920
|
-
const defaultInstance = sandbox.sget({
|
|
921
|
-
fqn: 'jsii-calc.Statics',
|
|
922
|
-
property: 'instance',
|
|
923
|
-
});
|
|
924
|
-
expect(sandbox.get({ objref: defaultInstance.value, property: 'value' })).toEqual({ value: 'default' });
|
|
925
|
-
const obj = sandbox.create({
|
|
926
|
-
fqn: 'jsii-calc.Statics',
|
|
927
|
-
args: ['MyInstance'],
|
|
928
|
-
});
|
|
929
|
-
sandbox.sset({ fqn: 'jsii-calc.Statics', property: 'instance', value: obj });
|
|
930
|
-
const updatedInstance = sandbox.sget({
|
|
931
|
-
fqn: 'jsii-calc.Statics',
|
|
932
|
-
property: 'instance',
|
|
933
|
-
});
|
|
934
|
-
expect(sandbox.get({ objref: updatedInstance.value, property: 'value' })).toEqual({ value: 'MyInstance' });
|
|
935
|
-
});
|
|
936
|
-
defineTest('fails: static properties - get/set non-static', (sandbox) => {
|
|
937
|
-
expect(() => sandbox.sget({ fqn: 'jsii-calc.Statics', property: 'value' })).toThrow(/is not static/);
|
|
938
|
-
expect(() => sandbox.sset({ fqn: 'jsii-calc.Statics', property: 'value', value: 123 })).toThrow(/is not static/);
|
|
939
|
-
});
|
|
940
|
-
defineTest('fails: static properties - get/set not found', (sandbox) => {
|
|
941
|
-
expect(() => sandbox.sget({ fqn: 'jsii-calc.Statics', property: 'zoo' })).toThrow(/doesn't have a property/);
|
|
942
|
-
expect(() => sandbox.sset({ fqn: 'jsii-calc.Statics', property: 'bar', value: 123 })).toThrow(/doesn't have a property/);
|
|
943
|
-
});
|
|
944
|
-
defineTest('static methods', (sandbox) => {
|
|
945
|
-
const result = sandbox.sinvoke({
|
|
946
|
-
fqn: 'jsii-calc.Statics',
|
|
947
|
-
method: 'staticMethod',
|
|
948
|
-
args: ['Jsii'],
|
|
949
|
-
});
|
|
950
|
-
expect(result).toEqual({ result: 'hello ,Jsii!' });
|
|
951
|
-
});
|
|
952
|
-
defineTest('fails: static methods - not found', (sandbox) => {
|
|
953
|
-
expect(() => sandbox.sinvoke({
|
|
954
|
-
fqn: 'jsii-calc.Statics',
|
|
955
|
-
method: 'staticMethodNotFound',
|
|
956
|
-
args: ['Jsii'],
|
|
957
|
-
})).toThrow(/doesn't have a method/);
|
|
958
|
-
});
|
|
959
|
-
defineTest('fails: static methods - not static', (sandbox) => {
|
|
960
|
-
expect(() => sandbox.sinvoke({
|
|
961
|
-
fqn: 'jsii-calc.Statics',
|
|
962
|
-
method: 'justMethod',
|
|
963
|
-
args: ['Jsii'],
|
|
964
|
-
})).toThrow(/is not a static method/);
|
|
965
|
-
});
|
|
966
|
-
defineTest('loading a module twice idepotently succeeds', async (sandbox) => {
|
|
967
|
-
sandbox.load({
|
|
968
|
-
tarball: await preparePackage('jsii-calc', false),
|
|
969
|
-
name: 'jsii-calc',
|
|
970
|
-
version: calcVersion,
|
|
971
|
-
});
|
|
972
|
-
});
|
|
973
|
-
defineTest('fails if trying to load two different versions of the same module', async (sandbox) => {
|
|
974
|
-
const tarball = await preparePackage('jsii-calc', false);
|
|
975
|
-
return expect(() => sandbox.load({ tarball, name: 'jsii-calc', version: '99.999.9' })).toThrow(/Multiple versions .+ and .+ of the package 'jsii-calc' cannot be loaded together/);
|
|
976
|
-
});
|
|
977
|
-
defineTest('node.js standard library', async (sandbox) => {
|
|
978
|
-
const objref = sandbox.create({ fqn: 'jsii-calc.NodeStandardLibrary' });
|
|
979
|
-
const promise = sandbox.begin({ objref, method: 'fsReadFile' });
|
|
980
|
-
await processPendingPromises(sandbox);
|
|
981
|
-
const output = await sandbox.end({ promiseid: promise.promiseid });
|
|
982
|
-
expect(output).toEqual({ result: 'Hello, resource!' });
|
|
983
|
-
expect(sandbox.invoke({ objref, method: 'fsReadFileSync' })).toEqual({
|
|
984
|
-
result: 'Hello, resource! SYNC!',
|
|
985
|
-
});
|
|
986
|
-
const platform = sandbox.get({ objref, property: 'osPlatform' }).value;
|
|
987
|
-
expect(platform === null || platform === void 0 ? void 0 : platform.length).toBeGreaterThan(0);
|
|
988
|
-
expect(sandbox.invoke({ objref, method: 'cryptoSha256' })).toEqual({
|
|
989
|
-
result: '6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50',
|
|
990
|
-
});
|
|
991
|
-
});
|
|
992
|
-
// @see awslabs/jsii#248
|
|
993
|
-
defineTest('object literals are returned by reference', (sandbox) => {
|
|
994
|
-
const objref = sandbox.create({
|
|
995
|
-
fqn: 'jsii-calc.ClassWithMutableObjectLiteralProperty',
|
|
996
|
-
});
|
|
997
|
-
const property = sandbox.get({ objref, property: 'mutableObject' }).value;
|
|
998
|
-
const newValue = 'Bazinga!1!';
|
|
999
|
-
sandbox.set({ objref: property, property: 'value', value: newValue });
|
|
1000
|
-
expect(sandbox.get({
|
|
1001
|
-
objref: sandbox.get({ objref, property: 'mutableObject' }).value,
|
|
1002
|
-
property: 'value',
|
|
1003
|
-
}).value).toEqual(newValue);
|
|
1004
|
-
sandbox.del({ objref: property });
|
|
1005
|
-
});
|
|
1006
|
-
defineTest('overrides: method instead of property with the same name', (sandbox) => {
|
|
1007
|
-
expect(() => {
|
|
1008
|
-
sandbox.create({
|
|
1009
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
1010
|
-
overrides: [{ method: 'theProperty' }],
|
|
1011
|
-
});
|
|
1012
|
-
}).toThrow(/Trying to override property/);
|
|
1013
|
-
});
|
|
1014
|
-
defineTest('overrides: property instead of method with the same name', (sandbox) => {
|
|
1015
|
-
expect(() => {
|
|
1016
|
-
sandbox.create({
|
|
1017
|
-
fqn: 'jsii-calc.SyncVirtualMethods',
|
|
1018
|
-
overrides: [{ property: 'virtualMethod' }],
|
|
1019
|
-
});
|
|
1020
|
-
}).toThrow(/Trying to override method/);
|
|
1021
|
-
});
|
|
1022
|
-
defineTest('overrides: skip overrides of private methods', (sandbox) => {
|
|
1023
|
-
const objref = sandbox.create({
|
|
1024
|
-
fqn: 'jsii-calc.DoNotOverridePrivates',
|
|
1025
|
-
overrides: [{ method: 'privateMethod' }],
|
|
1026
|
-
});
|
|
1027
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((_) => {
|
|
1028
|
-
throw new Error('override callback should not be called');
|
|
1029
|
-
});
|
|
1030
|
-
const result = sandbox.invoke({ objref, method: 'privateMethodValue' });
|
|
1031
|
-
expect(result.result).toBe('privateMethod');
|
|
1032
|
-
});
|
|
1033
|
-
defineTest('overrides: skip overrides of private properties', (sandbox) => {
|
|
1034
|
-
const objref = sandbox.create({
|
|
1035
|
-
fqn: 'jsii-calc.DoNotOverridePrivates',
|
|
1036
|
-
overrides: [{ property: 'privateProperty' }],
|
|
1037
|
-
});
|
|
1038
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((_) => {
|
|
1039
|
-
throw new Error('override callback should not be called');
|
|
1040
|
-
});
|
|
1041
|
-
const result = sandbox.invoke({ objref, method: 'privatePropertyValue' });
|
|
1042
|
-
expect(result.result).toBe('privateProperty');
|
|
1043
|
-
});
|
|
1044
|
-
defineTest('nulls are converted to undefined - ctor', (sandbox) => {
|
|
1045
|
-
sandbox.create({
|
|
1046
|
-
fqn: 'jsii-calc.NullShouldBeTreatedAsUndefined',
|
|
1047
|
-
args: ['foo', null],
|
|
1048
|
-
});
|
|
1049
|
-
});
|
|
1050
|
-
defineTest('nulls are converted to undefined - method arguments', (sandbox) => {
|
|
1051
|
-
const objref = sandbox.create({
|
|
1052
|
-
fqn: 'jsii-calc.NullShouldBeTreatedAsUndefined',
|
|
1053
|
-
args: ['foo'],
|
|
1054
|
-
});
|
|
1055
|
-
sandbox.invoke({ objref, method: 'giveMeUndefined', args: [null] });
|
|
1056
|
-
});
|
|
1057
|
-
defineTest('nulls are converted to undefined - inside objects', (sandbox) => {
|
|
1058
|
-
const objref = sandbox.create({
|
|
1059
|
-
fqn: 'jsii-calc.NullShouldBeTreatedAsUndefined',
|
|
1060
|
-
args: ['foo'],
|
|
1061
|
-
});
|
|
1062
|
-
sandbox.invoke({
|
|
1063
|
-
objref,
|
|
1064
|
-
method: 'giveMeUndefinedInsideAnObject',
|
|
1065
|
-
args: [
|
|
1066
|
-
{
|
|
1067
|
-
thisShouldBeUndefined: null,
|
|
1068
|
-
arrayWithThreeElementsAndUndefinedAsSecondArgument: [
|
|
1069
|
-
'one',
|
|
1070
|
-
null,
|
|
1071
|
-
'two',
|
|
1072
|
-
],
|
|
1073
|
-
},
|
|
1074
|
-
],
|
|
1075
|
-
});
|
|
1076
|
-
});
|
|
1077
|
-
defineTest('nulls are converted to undefined - properties', (sandbox) => {
|
|
1078
|
-
const objref = sandbox.create({
|
|
1079
|
-
fqn: 'jsii-calc.NullShouldBeTreatedAsUndefined',
|
|
1080
|
-
args: ['foo'],
|
|
1081
|
-
});
|
|
1082
|
-
sandbox.set({ objref, property: 'changeMeToUndefined', value: null });
|
|
1083
|
-
sandbox.invoke({ objref, method: 'verifyPropertyIsUndefined' });
|
|
1084
|
-
});
|
|
1085
|
-
defineTest('JSII_AGENT is undefined in node.js', (sandbox) => {
|
|
1086
|
-
expect(sandbox.sget({ fqn: 'jsii-calc.JsiiAgent', property: 'value' }).value).toBe(undefined);
|
|
1087
|
-
});
|
|
1088
|
-
defineTest('ObjRefs are labeled with the "most correct" type', (sandbox) => {
|
|
1089
|
-
typeMatches('makeClass', { [api_1.TOKEN_REF]: /^jsii-calc.InbetweenClass@/ });
|
|
1090
|
-
typeMatches('makeInterface', {
|
|
1091
|
-
[api_1.TOKEN_REF]: /^jsii-calc.InbetweenClass@/,
|
|
1092
|
-
[api_1.TOKEN_INTERFACES]: ['jsii-calc.IPublicInterface'],
|
|
1093
|
-
});
|
|
1094
|
-
typeMatches('makeInterface2', { [api_1.TOKEN_REF]: /^jsii-calc.InbetweenClass@/ });
|
|
1095
|
-
typeMatches('makeInterfaces', [
|
|
1096
|
-
{
|
|
1097
|
-
[api_1.TOKEN_REF]: /^jsii-calc.InbetweenClass@/,
|
|
1098
|
-
[api_1.TOKEN_INTERFACES]: ['jsii-calc.IPublicInterface'],
|
|
1099
|
-
},
|
|
1100
|
-
]);
|
|
1101
|
-
typeMatches('hiddenInterface', {
|
|
1102
|
-
[api_1.TOKEN_REF]: /^Object@/,
|
|
1103
|
-
[api_1.TOKEN_INTERFACES]: ['jsii-calc.IPublicInterface'],
|
|
1104
|
-
});
|
|
1105
|
-
typeMatches('hiddenInterfaces', [
|
|
1106
|
-
{
|
|
1107
|
-
[api_1.TOKEN_REF]: /^Object@/,
|
|
1108
|
-
[api_1.TOKEN_INTERFACES]: ['jsii-calc.IPublicInterface'],
|
|
1109
|
-
},
|
|
1110
|
-
]);
|
|
1111
|
-
typeMatches('hiddenSubInterfaces', [
|
|
1112
|
-
{
|
|
1113
|
-
[api_1.TOKEN_REF]: /^Object@/,
|
|
1114
|
-
[api_1.TOKEN_INTERFACES]: ['jsii-calc.IPublicInterface'],
|
|
1115
|
-
},
|
|
1116
|
-
]);
|
|
1117
|
-
function typeMatches(staticMethod, typeSpec) {
|
|
1118
|
-
const ret = sandbox.sinvoke({
|
|
1119
|
-
fqn: 'jsii-calc.Constructors',
|
|
1120
|
-
method: staticMethod,
|
|
1121
|
-
}).result;
|
|
1122
|
-
if (!deepEqualWithRegex(ret, typeSpec)) {
|
|
1123
|
-
throw new Error(`Constructors.${staticMethod}() => ${JSON.stringify(ret)}, does not match ${JSON.stringify(typeSpec)}`);
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
});
|
|
1127
|
-
/**
|
|
1128
|
-
* This is used to validate the ability to use `this` from within a static context.
|
|
1129
|
-
*
|
|
1130
|
-
* https://github.com/awslabs/aws-cdk/issues/2304
|
|
1131
|
-
*/
|
|
1132
|
-
defineTest('sinvoke allows access to the static context', (sandbox) => {
|
|
1133
|
-
const response = sandbox.sinvoke({
|
|
1134
|
-
fqn: 'jsii-calc.StaticContext',
|
|
1135
|
-
method: 'canAccessStaticContext',
|
|
1136
|
-
});
|
|
1137
|
-
expect(response.result).toBe(true);
|
|
1138
|
-
});
|
|
1139
|
-
defineTest('sget allows access to the static context', (sandbox) => {
|
|
1140
|
-
const response = sandbox.sget({
|
|
1141
|
-
fqn: 'jsii-calc.StaticContext',
|
|
1142
|
-
property: 'staticVariable',
|
|
1143
|
-
});
|
|
1144
|
-
expect(response.value).toBe(true);
|
|
1145
|
-
});
|
|
1146
|
-
defineTest('sset allows access to the static context', (sandbox) => {
|
|
1147
|
-
sandbox.sset({
|
|
1148
|
-
fqn: 'jsii-calc.StaticContext',
|
|
1149
|
-
property: 'staticVariable',
|
|
1150
|
-
value: false,
|
|
1151
|
-
});
|
|
1152
|
-
const response = sandbox.sget({
|
|
1153
|
-
fqn: 'jsii-calc.StaticContext',
|
|
1154
|
-
property: 'staticVariable',
|
|
1155
|
-
});
|
|
1156
|
-
expect(response.value).toBe(false);
|
|
1157
|
-
});
|
|
1158
|
-
/*
|
|
1159
|
-
|
|
1160
|
-
Test currently disabled because we don't have the infrastructure to make it pass.
|
|
1161
|
-
https://github.com/aws/jsii/issues/399
|
|
1162
|
-
|
|
1163
|
-
defineTest('A single instance can be returned under two types', (sandbox) => {
|
|
1164
|
-
const singleInstanceTwoTypes = create(sandbox, 'jsii-calc.SingleInstanceTwoTypes')();
|
|
1165
|
-
|
|
1166
|
-
typeMatches('interface1', { [TOKEN_REF]: /^jsii-calc.InbetweenClass@/ });
|
|
1167
|
-
typeMatches('interface2', { [TOKEN_REF]: /^jsii-calc.IPublicInterface@/ });
|
|
1168
|
-
|
|
1169
|
-
function typeMatches(method: string, typeSpec: any) {
|
|
1170
|
-
const ret = sandbox.invoke({ objref: singleInstanceTwoTypes, method }).result as api.ObjRef;
|
|
1171
|
-
|
|
1172
|
-
test.ok(deepEqualWithRegex(ret, typeSpec), `Constructors.${method}() => ${JSON.stringify(ret)}, does not match ${JSON.stringify(typeSpec)}`);
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
|
|
1176
|
-
*/
|
|
1177
|
-
defineTest('toSandbox: "null" in hash values send to JS should be treated as non-existing key', (sandbox) => {
|
|
1178
|
-
const input = { option1: null, option2: 'hello' };
|
|
1179
|
-
const option1Exists = sandbox.sinvoke({
|
|
1180
|
-
fqn: 'jsii-calc.EraseUndefinedHashValues',
|
|
1181
|
-
method: 'doesKeyExist',
|
|
1182
|
-
args: [input, 'option1'],
|
|
1183
|
-
});
|
|
1184
|
-
expect(option1Exists.result).toBe(false);
|
|
1185
|
-
const option2Exists = sandbox.sinvoke({
|
|
1186
|
-
fqn: 'jsii-calc.EraseUndefinedHashValues',
|
|
1187
|
-
method: 'doesKeyExist',
|
|
1188
|
-
args: [input, 'option2'],
|
|
1189
|
-
});
|
|
1190
|
-
expect(option2Exists.result).toBe(true);
|
|
1191
|
-
});
|
|
1192
|
-
defineTest('toSandbox: "undefined" in hash values sent to JS should be treated as non-existing key', (sandbox) => {
|
|
1193
|
-
const input = { option1: undefined, option2: 'hello' };
|
|
1194
|
-
const option1Exists = sandbox.sinvoke({
|
|
1195
|
-
fqn: 'jsii-calc.EraseUndefinedHashValues',
|
|
1196
|
-
method: 'doesKeyExist',
|
|
1197
|
-
args: [input, 'option1'],
|
|
1198
|
-
});
|
|
1199
|
-
expect(option1Exists.result).toBe(false);
|
|
1200
|
-
const option2Exists = sandbox.sinvoke({
|
|
1201
|
-
fqn: 'jsii-calc.EraseUndefinedHashValues',
|
|
1202
|
-
method: 'doesKeyExist',
|
|
1203
|
-
args: [input, 'option2'],
|
|
1204
|
-
});
|
|
1205
|
-
expect(option2Exists.result).toBe(true);
|
|
1206
|
-
});
|
|
1207
|
-
defineTest('calculator can set and retrieve union properties', (sandbox) => {
|
|
1208
|
-
const calculator = create(sandbox, 'jsii-calc.Calculator')();
|
|
1209
|
-
const mul = create(sandbox, 'jsii-calc.Multiply');
|
|
1210
|
-
const num = create(sandbox, '@scope/jsii-calc-lib.Number');
|
|
1211
|
-
sandbox.set({
|
|
1212
|
-
objref: calculator,
|
|
1213
|
-
property: 'unionProperty',
|
|
1214
|
-
value: mul(num(9), num(3)),
|
|
1215
|
-
});
|
|
1216
|
-
const value = sandbox.invoke({
|
|
1217
|
-
objref: calculator,
|
|
1218
|
-
method: 'readUnionValue',
|
|
1219
|
-
}).result;
|
|
1220
|
-
expect(27).toBe(value);
|
|
1221
|
-
const expression = sandbox.get({
|
|
1222
|
-
objref: calculator,
|
|
1223
|
-
property: 'unionProperty',
|
|
1224
|
-
}).value;
|
|
1225
|
-
expect(deepEqualWithRegex(expression, { [api_1.TOKEN_REF]: /^jsii-calc.Multiply@/ })).toBeTruthy();
|
|
1226
|
-
});
|
|
1227
|
-
defineTest('can set and retrieve union properties', (sandbox) => {
|
|
1228
|
-
const types = create(sandbox, 'jsii-calc.AllTypes')();
|
|
1229
|
-
const typesSet = set(sandbox, types);
|
|
1230
|
-
const typesGet = get(sandbox, types);
|
|
1231
|
-
const mul = create(sandbox, 'jsii-calc.Multiply');
|
|
1232
|
-
const num = create(sandbox, '@scope/jsii-calc-lib.Number');
|
|
1233
|
-
typesSet('unionProperty', 1234);
|
|
1234
|
-
expect(typesGet('unionProperty')).toBe(1234);
|
|
1235
|
-
typesSet('unionProperty', 'Hello');
|
|
1236
|
-
expect(typesGet('unionProperty')).toBe('Hello');
|
|
1237
|
-
typesSet('unionProperty', mul(num(2), num(12)));
|
|
1238
|
-
const mulObj = typesGet('unionProperty');
|
|
1239
|
-
expect(get(sandbox, mulObj)('value')).toBe(24);
|
|
1240
|
-
// Collections
|
|
1241
|
-
typesSet('unionMapProperty', {
|
|
1242
|
-
Foo: num(99),
|
|
1243
|
-
});
|
|
1244
|
-
typesSet('unionArrayProperty', [123, num(33)]);
|
|
1245
|
-
const unionArray = typesGet('unionArrayProperty');
|
|
1246
|
-
expect(get(sandbox, unionArray[1])('value')).toBe(33);
|
|
1247
|
-
});
|
|
1248
|
-
defineTest('require presence of required properties -- top level', (sandbox) => {
|
|
1249
|
-
expect(() => {
|
|
1250
|
-
sandbox.sinvoke({
|
|
1251
|
-
fqn: 'jsii-calc.StructPassing',
|
|
1252
|
-
method: 'roundTrip',
|
|
1253
|
-
args: [123, { incomplete: true }],
|
|
1254
|
-
});
|
|
1255
|
-
}).toThrow(/Missing required properties for jsii-calc.TopLevelStruct: required, secondLevel/);
|
|
1256
|
-
});
|
|
1257
|
-
defineTest('require presence of required properties -- deeper level', (sandbox) => {
|
|
1258
|
-
expect(() => {
|
|
1259
|
-
sandbox.sinvoke({
|
|
1260
|
-
fqn: 'jsii-calc.StructPassing',
|
|
1261
|
-
method: 'roundTrip',
|
|
1262
|
-
args: [
|
|
1263
|
-
123,
|
|
1264
|
-
{
|
|
1265
|
-
required: 'abc',
|
|
1266
|
-
secondLevel: { alsoIncomplete: true },
|
|
1267
|
-
},
|
|
1268
|
-
],
|
|
1269
|
-
});
|
|
1270
|
-
}).toThrow(/Missing required properties for jsii-calc.SecondLevelStruct: deeperRequiredProp/);
|
|
1271
|
-
});
|
|
1272
|
-
defineTest('notice when an array is passed instead of varargs', (sandbox) => {
|
|
1273
|
-
expect(() => {
|
|
1274
|
-
sandbox.sinvoke({
|
|
1275
|
-
fqn: 'jsii-calc.StructPassing',
|
|
1276
|
-
method: 'howManyVarArgsDidIPass',
|
|
1277
|
-
args: [123, [{ required: 'abc', secondLevel: 6 }]],
|
|
1278
|
-
});
|
|
1279
|
-
}).toThrow(/Got an array where a jsii-calc.TopLevelStruct was expected/);
|
|
1280
|
-
});
|
|
1281
|
-
defineTest('Object ID does not get re-allocated when the constructor passes "this" out', (sandbox) => {
|
|
1282
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
1283
|
-
var _a, _b;
|
|
1284
|
-
expect((_a = callback.invoke) === null || _a === void 0 ? void 0 : _a.method).toBe('consumePartiallyInitializedThis');
|
|
1285
|
-
expect((_b = callback.invoke) === null || _b === void 0 ? void 0 : _b.args).toEqual([
|
|
1286
|
-
{
|
|
1287
|
-
[lib_1.api.TOKEN_REF]: 'jsii-calc.ConstructorPassesThisOut@10001',
|
|
1288
|
-
},
|
|
1289
|
-
{
|
|
1290
|
-
[lib_1.api.TOKEN_DATE]: '1970-01-01T00:00:00.000Z',
|
|
1291
|
-
},
|
|
1292
|
-
{
|
|
1293
|
-
[lib_1.api.TOKEN_ENUM]: 'jsii-calc.AllTypesEnum/THIS_IS_GREAT',
|
|
1294
|
-
},
|
|
1295
|
-
]);
|
|
1296
|
-
return 'OK';
|
|
1297
|
-
});
|
|
1298
|
-
const reflector = sandbox.create({
|
|
1299
|
-
fqn: 'jsii-calc.PartiallyInitializedThisConsumer',
|
|
1300
|
-
overrides: [{ method: 'consumePartiallyInitializedThis' }],
|
|
1301
|
-
});
|
|
1302
|
-
expect(reflector[lib_1.api.TOKEN_REF]).toBe('jsii-calc.PartiallyInitializedThisConsumer@10000');
|
|
1303
|
-
const classRef = sandbox.create({
|
|
1304
|
-
fqn: 'jsii-calc.ConstructorPassesThisOut',
|
|
1305
|
-
args: [reflector],
|
|
1306
|
-
});
|
|
1307
|
-
expect(classRef[lib_1.api.TOKEN_REF]).toBe('jsii-calc.ConstructorPassesThisOut@10001');
|
|
1308
|
-
});
|
|
1309
|
-
defineTest('struct: empty object is turned to undefined by deserialization', (sandbox) => {
|
|
1310
|
-
const object = sandbox.create({
|
|
1311
|
-
fqn: 'jsii-calc.OptionalStructConsumer',
|
|
1312
|
-
args: [{}],
|
|
1313
|
-
});
|
|
1314
|
-
const result = sandbox.get({
|
|
1315
|
-
objref: object,
|
|
1316
|
-
property: 'parameterWasUndefined',
|
|
1317
|
-
});
|
|
1318
|
-
expect(result.value).toBeTruthy(); // The parameter was undefined within the constructor'
|
|
1319
|
-
});
|
|
1320
|
-
defineTest('struct: non-empty object deserializes properly', (sandbox) => {
|
|
1321
|
-
const objref = sandbox.create({
|
|
1322
|
-
fqn: 'jsii-calc.OptionalStructConsumer',
|
|
1323
|
-
args: [{ field: 'foo' }],
|
|
1324
|
-
});
|
|
1325
|
-
const result = sandbox.get({ objref, property: 'parameterWasUndefined' });
|
|
1326
|
-
expect(result.value).toBeFalsy(); // The parameter was not undefined within the constructor'
|
|
1327
|
-
const field = sandbox.get({ objref, property: 'fieldValue' });
|
|
1328
|
-
expect(field.value).toBe('foo');
|
|
1329
|
-
});
|
|
1330
|
-
defineTest('erased base: can receive an instance of private type', (sandbox) => {
|
|
1331
|
-
const objref = sandbox.sinvoke({
|
|
1332
|
-
fqn: 'jsii-calc.JSII417PublicBaseOfBase',
|
|
1333
|
-
method: 'makeInstance',
|
|
1334
|
-
});
|
|
1335
|
-
expect(objref.result).toEqual({
|
|
1336
|
-
[lib_1.api.TOKEN_REF]: 'jsii-calc.JSII417PublicBaseOfBase@10000',
|
|
1337
|
-
});
|
|
1338
|
-
});
|
|
1339
|
-
defineTest('deserialize a struct by reference', (sandbox) => {
|
|
1340
|
-
sandbox.callbackHandler = makeSyncCallbackHandler(() => 'xoxoxox');
|
|
1341
|
-
const objref = sandbox.create({
|
|
1342
|
-
fqn: 'Object',
|
|
1343
|
-
overrides: [{ property: 'field' }],
|
|
1344
|
-
});
|
|
1345
|
-
const consumer = sandbox.create({
|
|
1346
|
-
fqn: 'jsii-calc.OptionalStructConsumer',
|
|
1347
|
-
args: [objref],
|
|
1348
|
-
});
|
|
1349
|
-
const value = sandbox.get({ objref: consumer, property: 'fieldValue' });
|
|
1350
|
-
expect(value).toEqual({ value: 'xoxoxox' });
|
|
1351
|
-
});
|
|
1352
|
-
defineTest('correctly passes enum values across', (sandbox) => {
|
|
1353
|
-
const stringLike = sandbox.sinvoke({
|
|
1354
|
-
fqn: 'jsii-calc.EnumDispenser',
|
|
1355
|
-
method: 'randomStringLikeEnum',
|
|
1356
|
-
});
|
|
1357
|
-
expect(stringLike.result).toEqual({ '$jsii.enum': 'jsii-calc.StringEnum/B' });
|
|
1358
|
-
const integerLike = sandbox.sinvoke({
|
|
1359
|
-
fqn: 'jsii-calc.EnumDispenser',
|
|
1360
|
-
method: 'randomIntegerLikeEnum',
|
|
1361
|
-
});
|
|
1362
|
-
expect(integerLike.result).toEqual({
|
|
1363
|
-
'$jsii.enum': 'jsii-calc.AllTypesEnum/YOUR_ENUM_VALUE',
|
|
1364
|
-
});
|
|
1365
|
-
});
|
|
1366
|
-
defineTest('registers interfaces requested', (sandbox) => {
|
|
1367
|
-
const interfaces = [
|
|
1368
|
-
'jsii-calc.IReturnsNumber',
|
|
1369
|
-
'jsii-calc.IInterfaceWithOptionalMethodArguments',
|
|
1370
|
-
];
|
|
1371
|
-
const objref = sandbox.create({ fqn: 'Object', interfaces });
|
|
1372
|
-
expect(objref).toEqual({
|
|
1373
|
-
[api_1.TOKEN_REF]: 'Object@10000',
|
|
1374
|
-
[api_1.TOKEN_INTERFACES]: interfaces.sort(),
|
|
1375
|
-
});
|
|
1376
|
-
});
|
|
1377
|
-
defineTest('retains the type of object literals', (sandbox) => {
|
|
1378
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((cb) => {
|
|
1379
|
-
var _a, _b;
|
|
1380
|
-
expect((_a = cb.invoke) === null || _a === void 0 ? void 0 : _a.method).toBe('provideAsInterface');
|
|
1381
|
-
expect((_b = cb.invoke) === null || _b === void 0 ? void 0 : _b.objref).toMatchObject({ [api_1.TOKEN_REF]: 'Object@10000' });
|
|
1382
|
-
const realObject = sandbox.create({
|
|
1383
|
-
fqn: 'jsii-calc.AnonymousImplementationProvider',
|
|
1384
|
-
});
|
|
1385
|
-
const { result } = sandbox.invoke({
|
|
1386
|
-
objref: realObject,
|
|
1387
|
-
method: 'provideAsInterface',
|
|
1388
|
-
});
|
|
1389
|
-
sandbox.del({ objref: realObject });
|
|
1390
|
-
return result;
|
|
1391
|
-
});
|
|
1392
|
-
const objref = sandbox.create({
|
|
1393
|
-
fqn: 'Object',
|
|
1394
|
-
interfaces: ['jsii-calc.IAnonymousImplementationProvider'],
|
|
1395
|
-
overrides: [{ method: 'provideAsInterface' }],
|
|
1396
|
-
});
|
|
1397
|
-
const result = sandbox.invoke({ objref, method: 'provideAsInterface' });
|
|
1398
|
-
expect(result).toEqual({
|
|
1399
|
-
result: {
|
|
1400
|
-
[api_1.TOKEN_REF]: 'jsii-calc.Implementation@10002',
|
|
1401
|
-
[api_1.TOKEN_INTERFACES]: ['jsii-calc.IAnonymouslyImplementMe'],
|
|
1402
|
-
},
|
|
1403
|
-
});
|
|
1404
|
-
});
|
|
1405
|
-
defineTest('correctly deserializes struct unions', (sandbox) => {
|
|
1406
|
-
const unionConsumer = 'jsii-calc.StructUnionConsumer';
|
|
1407
|
-
const structA0 = {
|
|
1408
|
-
[api_1.TOKEN_STRUCT]: {
|
|
1409
|
-
fqn: 'jsii-calc.StructA',
|
|
1410
|
-
data: { requiredString: 'Present!', optionalString: 'Bazinga!' },
|
|
1411
|
-
},
|
|
1412
|
-
};
|
|
1413
|
-
const structA1 = {
|
|
1414
|
-
[api_1.TOKEN_STRUCT]: {
|
|
1415
|
-
fqn: 'jsii-calc.StructA',
|
|
1416
|
-
data: { requiredString: 'Present!', optionalNumber: 1337 },
|
|
1417
|
-
},
|
|
1418
|
-
};
|
|
1419
|
-
const structB0 = {
|
|
1420
|
-
[api_1.TOKEN_STRUCT]: {
|
|
1421
|
-
fqn: 'jsii-calc.StructB',
|
|
1422
|
-
data: { requiredString: 'Present!', optionalBoolean: true },
|
|
1423
|
-
},
|
|
1424
|
-
};
|
|
1425
|
-
const structB1 = {
|
|
1426
|
-
[api_1.TOKEN_STRUCT]: {
|
|
1427
|
-
fqn: 'jsii-calc.StructB',
|
|
1428
|
-
data: { requiredString: 'Present!', optionalStructA: structA1 },
|
|
1429
|
-
},
|
|
1430
|
-
};
|
|
1431
|
-
for (const item of [structA0, structA1]) {
|
|
1432
|
-
expect(sandbox.sinvoke({ fqn: unionConsumer, method: 'isStructA', args: [item] })
|
|
1433
|
-
.result).toBe(true);
|
|
1434
|
-
expect(sandbox.sinvoke({ fqn: unionConsumer, method: 'isStructB', args: [item] })
|
|
1435
|
-
.result).toBe(false);
|
|
1436
|
-
}
|
|
1437
|
-
for (const item of [structB0, structB1]) {
|
|
1438
|
-
expect(sandbox.sinvoke({ fqn: unionConsumer, method: 'isStructA', args: [item] })
|
|
1439
|
-
.result).toBe(false);
|
|
1440
|
-
expect(sandbox.sinvoke({ fqn: unionConsumer, method: 'isStructB', args: [item] })
|
|
1441
|
-
.result).toBe(true);
|
|
1442
|
-
}
|
|
1443
|
-
});
|
|
1444
|
-
defineTest('ANY deserializer: decorated structs', (sandbox) => {
|
|
1445
|
-
const input = {
|
|
1446
|
-
'$jsii.struct': {
|
|
1447
|
-
fqn: 'jsii-calc.StructB',
|
|
1448
|
-
data: { requiredString: 'Bazinga!', optionalBoolean: false },
|
|
1449
|
-
},
|
|
1450
|
-
};
|
|
1451
|
-
expect(deserializeAny(sandbox, input)).toStrictEqual({
|
|
1452
|
-
requiredString: 'Bazinga!',
|
|
1453
|
-
optionalBoolean: false,
|
|
1454
|
-
});
|
|
1455
|
-
});
|
|
1456
|
-
defineTest('ANY deserializer: primitives', (sandbox) => {
|
|
1457
|
-
expect(deserializeAny(sandbox, -100)).toStrictEqual(-100);
|
|
1458
|
-
expect(deserializeAny(sandbox, 0)).toStrictEqual(0);
|
|
1459
|
-
expect(deserializeAny(sandbox, 1234)).toStrictEqual(1234);
|
|
1460
|
-
expect(deserializeAny(sandbox, 'hello')).toStrictEqual('hello');
|
|
1461
|
-
expect(deserializeAny(sandbox, '')).toStrictEqual('');
|
|
1462
|
-
expect(deserializeAny(sandbox, true)).toStrictEqual(true);
|
|
1463
|
-
expect(deserializeAny(sandbox, false)).toStrictEqual(false);
|
|
1464
|
-
});
|
|
1465
|
-
defineTest('ANY deserializer: array', (sandbox) => {
|
|
1466
|
-
expect(deserializeAny(sandbox, [1, 2, 3, 'four'])).toStrictEqual([
|
|
1467
|
-
1,
|
|
1468
|
-
2,
|
|
1469
|
-
3,
|
|
1470
|
-
'four',
|
|
1471
|
-
]);
|
|
1472
|
-
});
|
|
1473
|
-
defineTest('ANY deserializer: undefined/null', (sandbox) => {
|
|
1474
|
-
expect(deserializeAny(sandbox, null)).toStrictEqual(undefined);
|
|
1475
|
-
expect(deserializeAny(sandbox, undefined)).toStrictEqual(undefined);
|
|
1476
|
-
});
|
|
1477
|
-
defineTest('ANY deserializer: wire date', (sandbox) => {
|
|
1478
|
-
expect(deserializeAny(sandbox, { '$jsii.date': '2019-11-18T13:01:20.515Z' })).toStrictEqual('2019-11-18T13:01:20.515Z');
|
|
1479
|
-
});
|
|
1480
|
-
defineTest('ANY deserializer: enum', (sandbox) => {
|
|
1481
|
-
expect(deserializeAny(sandbox, {
|
|
1482
|
-
'$jsii.enum': 'jsii-calc.AllTypesEnum/YOUR_ENUM_VALUE',
|
|
1483
|
-
})).toStrictEqual(100);
|
|
1484
|
-
});
|
|
1485
|
-
defineTest('ANY deserializer: wire map', (sandbox) => {
|
|
1486
|
-
const input = {
|
|
1487
|
-
'$jsii.map': {
|
|
1488
|
-
foo: 123,
|
|
1489
|
-
bar: { '$jsii.enum': 'jsii-calc.AllTypesEnum/YOUR_ENUM_VALUE' },
|
|
1490
|
-
},
|
|
1491
|
-
};
|
|
1492
|
-
expect(deserializeAny(sandbox, input)).toStrictEqual({
|
|
1493
|
-
foo: 123,
|
|
1494
|
-
bar: 100,
|
|
1495
|
-
});
|
|
1496
|
-
});
|
|
1497
|
-
defineTest('ANY deserializer: by value', (sandbox) => {
|
|
1498
|
-
const ref = sandbox.create({
|
|
1499
|
-
fqn: '@scope/jsii-calc-lib.Number',
|
|
1500
|
-
args: [444],
|
|
1501
|
-
});
|
|
1502
|
-
const input = {
|
|
1503
|
-
foo: 123,
|
|
1504
|
-
bar: { '$jsii.enum': 'jsii-calc.AllTypesEnum/YOUR_ENUM_VALUE' },
|
|
1505
|
-
struct: {
|
|
1506
|
-
'$jsii.struct': {
|
|
1507
|
-
fqn: 'jsii-calc.StructB',
|
|
1508
|
-
data: { requiredString: 'Bazinga!', optionalBoolean: false },
|
|
1509
|
-
},
|
|
1510
|
-
},
|
|
1511
|
-
ref,
|
|
1512
|
-
};
|
|
1513
|
-
expect(deserializeAny(sandbox, input)).toStrictEqual({
|
|
1514
|
-
foo: 123,
|
|
1515
|
-
bar: 100,
|
|
1516
|
-
struct: {
|
|
1517
|
-
requiredString: 'Bazinga!',
|
|
1518
|
-
optionalBoolean: false,
|
|
1519
|
-
},
|
|
1520
|
-
ref: { value: 444 },
|
|
1521
|
-
});
|
|
1522
|
-
});
|
|
1523
|
-
defineTest('ANY serializer: null/undefined', (sandbox) => {
|
|
1524
|
-
expect(serializeAny(sandbox, 'anyNull')).toStrictEqual(undefined);
|
|
1525
|
-
expect(serializeAny(sandbox, 'anyUndefined')).toStrictEqual(undefined);
|
|
1526
|
-
});
|
|
1527
|
-
defineTest('ANY serializer: function (fails)', (sandbox) => {
|
|
1528
|
-
expect(() => serializeAny(sandbox, 'anyFunction')).toThrow(/JSII Kernel is unable to serialize `function`. An instance with methods might have been returned by an `any` method\?/);
|
|
1529
|
-
});
|
|
1530
|
-
defineTest('ANY serializer: date', (sandbox) => {
|
|
1531
|
-
expect(serializeAny(sandbox, 'anyDate')).toStrictEqual({
|
|
1532
|
-
'$jsii.date': '2019-11-18T13:01:20.515Z',
|
|
1533
|
-
});
|
|
1534
|
-
});
|
|
1535
|
-
defineTest('ANY serializer: primitives', (sandbox) => {
|
|
1536
|
-
expect(serializeAny(sandbox, 'anyNumber')).toStrictEqual(123);
|
|
1537
|
-
expect(serializeAny(sandbox, 'anyZero')).toStrictEqual(0);
|
|
1538
|
-
expect(serializeAny(sandbox, 'anyString')).toStrictEqual('foo');
|
|
1539
|
-
expect(serializeAny(sandbox, 'anyEmptyString')).toStrictEqual('');
|
|
1540
|
-
expect(serializeAny(sandbox, 'anyBooleanTrue')).toStrictEqual(true);
|
|
1541
|
-
expect(serializeAny(sandbox, 'anyBooleanFalse')).toStrictEqual(false);
|
|
1542
|
-
});
|
|
1543
|
-
defineTest('ANY serializer: array', (sandbox) => {
|
|
1544
|
-
expect(serializeAny(sandbox, 'anyArray')).toEqual([
|
|
1545
|
-
1,
|
|
1546
|
-
2,
|
|
1547
|
-
3,
|
|
1548
|
-
{
|
|
1549
|
-
'$jsii.byref': '@scope/jsii-calc-lib.Number@10000',
|
|
1550
|
-
'$jsii.interfaces': undefined,
|
|
1551
|
-
},
|
|
1552
|
-
{ foo: 'bar' },
|
|
1553
|
-
]);
|
|
1554
|
-
});
|
|
1555
|
-
defineTest('ANY serializer: hash', (sandbox) => {
|
|
1556
|
-
expect(serializeAny(sandbox, 'anyHash')).toStrictEqual({
|
|
1557
|
-
hello: 1234,
|
|
1558
|
-
world: {
|
|
1559
|
-
'$jsii.byref': '@scope/jsii-calc-lib.Number@10000',
|
|
1560
|
-
'$jsii.interfaces': undefined,
|
|
1561
|
-
},
|
|
1562
|
-
});
|
|
1563
|
-
});
|
|
1564
|
-
defineTest('ANY serializer: ref', (sandbox) => {
|
|
1565
|
-
expect(serializeAny(sandbox, 'anyRef')).toStrictEqual({
|
|
1566
|
-
'$jsii.byref': '@scope/jsii-calc-lib.Number@10000',
|
|
1567
|
-
'$jsii.interfaces': undefined,
|
|
1568
|
-
});
|
|
1569
|
-
});
|
|
1570
|
-
defineTest('Override transitive property', (sandbox) => {
|
|
1571
|
-
//////////
|
|
1572
|
-
// GIVEN
|
|
1573
|
-
//////////
|
|
1574
|
-
const originalString = 'r00t';
|
|
1575
|
-
const initialOverriddenPropValue = 'Overridden Value';
|
|
1576
|
-
let propValue = initialOverriddenPropValue;
|
|
1577
|
-
sandbox.callbackHandler = makeSyncCallbackHandler((callback) => {
|
|
1578
|
-
var _a, _b;
|
|
1579
|
-
const getOrSet = (_a = callback.get) !== null && _a !== void 0 ? _a : callback.set;
|
|
1580
|
-
// We don't expect to receive any other callback
|
|
1581
|
-
expect(getOrSet).toBeDefined();
|
|
1582
|
-
expect(getOrSet === null || getOrSet === void 0 ? void 0 : getOrSet.property).toBe('dynamicProperty');
|
|
1583
|
-
if (callback.get) {
|
|
1584
|
-
return propValue;
|
|
1585
|
-
}
|
|
1586
|
-
propValue = (_b = callback.set) === null || _b === void 0 ? void 0 : _b.value;
|
|
1587
|
-
return void 0;
|
|
1588
|
-
});
|
|
1589
|
-
//////////
|
|
1590
|
-
// WHEN
|
|
1591
|
-
//////////
|
|
1592
|
-
const objref = sandbox.create({
|
|
1593
|
-
fqn: 'jsii-calc.DynamicPropertyBearerChild',
|
|
1594
|
-
args: [originalString],
|
|
1595
|
-
overrides: [{ property: 'dynamicProperty' }],
|
|
1596
|
-
});
|
|
1597
|
-
//////////
|
|
1598
|
-
// THEN
|
|
1599
|
-
//////////
|
|
1600
|
-
// Reading the "super" property
|
|
1601
|
-
expect(sandbox.get({ objref, property: 'dynamicProperty' }).value).toBe(originalString);
|
|
1602
|
-
expect(sandbox.get({ objref, property: 'valueStore' }).value).toBe(originalString);
|
|
1603
|
-
// Setting the dynamicProperty value through the override
|
|
1604
|
-
expect(sandbox.invoke({ objref, method: 'overrideValue', args: ['N3W'] }).result).toBe(initialOverriddenPropValue);
|
|
1605
|
-
// Checking the side effect happened on the override:
|
|
1606
|
-
expect(propValue).toBe('N3W');
|
|
1607
|
-
// Check the "super" property didn't change:
|
|
1608
|
-
expect(sandbox.get({ objref, property: 'dynamicProperty' }).value).toBe(originalString);
|
|
1609
|
-
expect(sandbox.get({ objref, property: 'valueStore' }).value).toBe(originalString);
|
|
1610
|
-
// Set the "super" property now
|
|
1611
|
-
sandbox.set({ objref, property: 'dynamicProperty', value: '' });
|
|
1612
|
-
// Check the side effect made it to the storage
|
|
1613
|
-
expect(sandbox.get({ objref, property: 'valueStore' }).value).toBe('');
|
|
1614
|
-
// Check the overridden property didn't change...
|
|
1615
|
-
expect(propValue).toBe('N3W');
|
|
1616
|
-
});
|
|
1617
|
-
defineTest('invokeBinScript() return output', (sandbox) => {
|
|
1618
|
-
const result = sandbox.invokeBinScript({
|
|
1619
|
-
assembly: 'jsii-calc',
|
|
1620
|
-
script: 'calc',
|
|
1621
|
-
});
|
|
1622
|
-
expect(result.stdout).toEqual('Hello World!\n');
|
|
1623
|
-
expect(result.stderr).toEqual('');
|
|
1624
|
-
expect(result.status).toEqual(0);
|
|
1625
|
-
expect(result.signal).toBeNull();
|
|
1626
|
-
});
|
|
1627
|
-
// =================================================================================================
|
|
1628
|
-
const testNames = {};
|
|
1629
|
-
async function createCalculatorSandbox(name) {
|
|
1630
|
-
if (name in testNames) {
|
|
1631
|
-
throw new Error(`Duplicate test name: ${name}`);
|
|
1632
|
-
}
|
|
1633
|
-
testNames[name] = true;
|
|
1634
|
-
const initialCallbackHandler = () => {
|
|
1635
|
-
throw new Error('Callback invoked without a callback handler');
|
|
1636
|
-
};
|
|
1637
|
-
const sandbox = new lib_1.Kernel(initialCallbackHandler);
|
|
1638
|
-
if (recordingOutput) {
|
|
1639
|
-
const inputOutputLogPath = path_1.join(recordingOutput, `${name}.log`);
|
|
1640
|
-
recording_1.recordInteraction(sandbox, inputOutputLogPath);
|
|
1641
|
-
}
|
|
1642
|
-
sandbox.traceEnabled = `${process.env.JSII_DEBUG}` === '1';
|
|
1643
|
-
sandbox.load({
|
|
1644
|
-
tarball: await preparePackage('@scope/jsii-calc-base-of-base'),
|
|
1645
|
-
name: '@scope/jsii-calc-base-of-base',
|
|
1646
|
-
version: calcBaseVersion,
|
|
1647
|
-
});
|
|
1648
|
-
sandbox.load({
|
|
1649
|
-
tarball: await preparePackage('@scope/jsii-calc-base'),
|
|
1650
|
-
name: '@scope/jsii-calc-base',
|
|
1651
|
-
version: calcBaseVersion,
|
|
1652
|
-
});
|
|
1653
|
-
sandbox.load({
|
|
1654
|
-
tarball: await preparePackage('@scope/jsii-calc-lib'),
|
|
1655
|
-
name: '@scope/jsii-calc-lib',
|
|
1656
|
-
version: calcLibVersion,
|
|
1657
|
-
});
|
|
1658
|
-
sandbox.load({
|
|
1659
|
-
tarball: await preparePackage('jsii-calc'),
|
|
1660
|
-
name: 'jsii-calc',
|
|
1661
|
-
version: calcVersion,
|
|
1662
|
-
});
|
|
1663
|
-
return sandbox;
|
|
1664
|
-
}
|
|
1665
|
-
const cache = {};
|
|
1666
|
-
async function preparePackage(module, useCache = true) {
|
|
1667
|
-
if (module in cache && useCache) {
|
|
1668
|
-
return cache[module];
|
|
1669
|
-
}
|
|
1670
|
-
const staging = await fs.mkdtemp(path.join(os.tmpdir(), 'jsii-kernel-tests-'));
|
|
1671
|
-
// clean up only if we are not recording, so playback can refer to these
|
|
1672
|
-
if (!recordingOutput) {
|
|
1673
|
-
process.on('exit', () => fs.removeSync(staging)); // cleanup
|
|
1674
|
-
}
|
|
1675
|
-
const packageRoot = findPackageRoot(module);
|
|
1676
|
-
await new Promise((ok, ko) => {
|
|
1677
|
-
const child = childProcess.spawn('npm', ['pack', packageRoot], {
|
|
1678
|
-
cwd: staging,
|
|
1679
|
-
shell: true,
|
|
1680
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
1681
|
-
});
|
|
1682
|
-
const stdout = new Array();
|
|
1683
|
-
child.stdout.on('data', (chunk) => stdout.push(Buffer.from(chunk)));
|
|
1684
|
-
child.once('close', (code, signal) => {
|
|
1685
|
-
if (code === 0) {
|
|
1686
|
-
return ok();
|
|
1687
|
-
}
|
|
1688
|
-
if (code != null) {
|
|
1689
|
-
return ko(`'npm pack' exited with code ${code}`);
|
|
1690
|
-
}
|
|
1691
|
-
return ko(`'npm pack' killed by signal ${signal}`);
|
|
1692
|
-
});
|
|
1693
|
-
});
|
|
1694
|
-
const dir = path.join(staging, (await fs.readdir(staging))[0]);
|
|
1695
|
-
return (cache[module] = dir);
|
|
1696
|
-
}
|
|
1697
|
-
function findPackageRoot(pkg) {
|
|
1698
|
-
return path.resolve(path.join(require.resolve(`${pkg}/package.json`), '..'));
|
|
1699
|
-
}
|
|
1700
|
-
/**
|
|
1701
|
-
* synchronous overrides are implemented as a simple callback function that gets
|
|
1702
|
-
* all the information needed to perform the callback and return the result.
|
|
1703
|
-
*/
|
|
1704
|
-
function makeSyncCallbackHandler(logic) {
|
|
1705
|
-
return function (callback) {
|
|
1706
|
-
// since sync callbacks must be handled at host level, we will "fake"
|
|
1707
|
-
// how @jsii/runtime and a client will interact when a callback is requested
|
|
1708
|
-
const recording = this.logfile;
|
|
1709
|
-
if (recording) {
|
|
1710
|
-
// @jsii/runtime => client (callback request from the runtime)
|
|
1711
|
-
recording.write(`< ${JSON.stringify({ callback })}\n`);
|
|
1712
|
-
}
|
|
1713
|
-
const result = logic(callback);
|
|
1714
|
-
if (recording) {
|
|
1715
|
-
// client => @jsii/runtime (callback completion by client)
|
|
1716
|
-
recording.write(`> ${JSON.stringify({ complete: { cbid: callback.cbid, result } })}\n`);
|
|
1717
|
-
}
|
|
1718
|
-
return result;
|
|
1719
|
-
};
|
|
1720
|
-
}
|
|
1721
|
-
function deepEqualWithRegex(lvalue, rvalue) {
|
|
1722
|
-
if (lvalue === rvalue) {
|
|
1723
|
-
return true;
|
|
1724
|
-
}
|
|
1725
|
-
if (typeof lvalue === 'string' && rvalue instanceof RegExp) {
|
|
1726
|
-
return rvalue.test(lvalue);
|
|
1727
|
-
}
|
|
1728
|
-
if (typeof lvalue !== typeof rvalue) {
|
|
1729
|
-
return false;
|
|
1730
|
-
}
|
|
1731
|
-
if (Array.isArray(lvalue) !== Array.isArray(rvalue)) {
|
|
1732
|
-
return false;
|
|
1733
|
-
}
|
|
1734
|
-
if (Array.isArray(lvalue) /* && Array.isArray(rvalue) */) {
|
|
1735
|
-
if (lvalue.length !== rvalue.length) {
|
|
1736
|
-
return false;
|
|
1737
|
-
}
|
|
1738
|
-
for (let i = 0; i < lvalue.length; i++) {
|
|
1739
|
-
if (!deepEqualWithRegex(lvalue[i], rvalue[i])) {
|
|
1740
|
-
return false;
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
return true;
|
|
1744
|
-
}
|
|
1745
|
-
if (typeof lvalue === 'object' /* && typeof rvalue === 'object' */) {
|
|
1746
|
-
if (lvalue === null || rvalue === null) {
|
|
1747
|
-
// If both were null, they'd have been ===
|
|
1748
|
-
return false;
|
|
1749
|
-
}
|
|
1750
|
-
const keys = Object.entries(lvalue)
|
|
1751
|
-
.filter(([, v]) => v != null)
|
|
1752
|
-
.map(([k]) => k);
|
|
1753
|
-
if (keys.length !== Object.keys(rvalue).length) {
|
|
1754
|
-
return false;
|
|
1755
|
-
}
|
|
1756
|
-
for (const key of keys) {
|
|
1757
|
-
if (!Object.prototype.hasOwnProperty.call(rvalue, key)) {
|
|
1758
|
-
return false;
|
|
1759
|
-
}
|
|
1760
|
-
if (!deepEqualWithRegex(lvalue[key], rvalue[key])) {
|
|
1761
|
-
return false;
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
return true;
|
|
1765
|
-
}
|
|
1766
|
-
// Neither object, nor array: I deduce this is primitive type
|
|
1767
|
-
// Primitive type and not ===, so I deduce not deepEqual
|
|
1768
|
-
return false;
|
|
1769
|
-
}
|
|
1770
|
-
exports.deepEqualWithRegex = deepEqualWithRegex;
|
|
1771
|
-
function create(kernel, fqn) {
|
|
1772
|
-
return (...args) => {
|
|
1773
|
-
return kernel.create({ fqn, args });
|
|
1774
|
-
};
|
|
1775
|
-
}
|
|
1776
|
-
function set(kernel, objref) {
|
|
1777
|
-
return (property, value) => {
|
|
1778
|
-
return kernel.set({ objref, property, value });
|
|
1779
|
-
};
|
|
1780
|
-
}
|
|
1781
|
-
function get(kernel, objref) {
|
|
1782
|
-
return (property) => {
|
|
1783
|
-
return kernel.get({ objref, property }).value;
|
|
1784
|
-
};
|
|
1785
|
-
}
|
|
1786
|
-
/**
|
|
1787
|
-
* Passes `input` to the kernel through an "any" type and returns the JSON
|
|
1788
|
-
* stringified version that the JavaScript code saw.
|
|
1789
|
-
*/
|
|
1790
|
-
function deserializeAny(sandbox, input) {
|
|
1791
|
-
const ret = sandbox.sinvoke({
|
|
1792
|
-
fqn: 'jsii-calc.JsonFormatter',
|
|
1793
|
-
method: 'stringify',
|
|
1794
|
-
args: [input],
|
|
1795
|
-
});
|
|
1796
|
-
if (ret.result === undefined) {
|
|
1797
|
-
return undefined;
|
|
1798
|
-
}
|
|
1799
|
-
const json = JSON.parse(ret.result);
|
|
1800
|
-
return json;
|
|
1801
|
-
}
|
|
1802
|
-
function serializeAny(sandbox, method) {
|
|
1803
|
-
return sandbox.sinvoke({ fqn: 'jsii-calc.JsonFormatter', method }).result;
|
|
1804
|
-
}
|
|
1805
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2VybmVsLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJrZXJuZWwudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4Q0FBOEM7QUFDOUMsK0JBQStCO0FBQy9CLHlCQUF5QjtBQUN6QiwrQkFBNEI7QUFDNUIsNkJBQTZCO0FBQzdCLHlCQUF5QjtBQUV6QixnQ0FBcUM7QUFDckMsb0NBUW9CO0FBQ3BCLDJDQUFnRTtBQUVoRSwyQ0FBMkM7QUFFM0MsK0JBQStCO0FBQy9CLE1BQU0sZUFBZSxHQUNuQixPQUFPLENBQUMsb0NBQW9DLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLHNCQUFzQjtBQUNwRyxNQUFNLGNBQWMsR0FDbEIsT0FBTyxDQUFDLG1DQUFtQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxzQkFBc0I7QUFDbkcsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBRSxzQkFBc0I7QUFDM0YsT0FBTyxFQUNQLEVBQUUsQ0FDSCxDQUFDO0FBRUYsZ0VBQWdFO0FBQy9ELE1BQU0sQ0FBQyxTQUFpQixDQUFDLE1BQU0sR0FBRyxTQUFTLE1BQU07SUFDaEQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQ3JCLENBQUMsQ0FBQztBQUVGLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyw0REFBNEQ7QUFFM0YsT0FBTyxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO0lBQ3JDLE9BQU8sQ0FBQyxLQUFLLENBQUUsQ0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQyxDQUFDLENBQUM7QUFF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QyxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzRSxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUNyRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FDaEIsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN4RSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUN0RSxrREFBa0QsQ0FDbkQsQ0FBQztJQUNGLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0UsQ0FBQyxDQUFDLENBQUM7QUFFSCxVQUFVLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtJQUN4QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUN4RSxDQUFDLENBQUMsQ0FBQztBQUVILFVBQVUs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TSxLQUFLLFNBQVMsRUFBRTtRQUM1QixPQUFPLFNBQVMsQ0FBQztLQUNsQjtJQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLE9BQWUsRUFBRSxNQUFjO0lBQ25ELE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUM1RSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2hpbGRQcm9jZXNzIGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIHZtIGZyb20gJ3ZtJztcblxuaW1wb3J0IHsgYXBpLCBLZXJuZWwgfSBmcm9tICcuLi9saWInO1xuaW1wb3J0IHtcbiAgQ2FsbGJhY2ssXG4gIE9ialJlZixcbiAgVE9LRU5fUkVGLFxuICBUT0tFTl9JTlRFUkZBQ0VTLFxuICBUT0tFTl9NQVAsXG4gIFdpcmVTdHJ1Y3QsXG4gIFRPS0VOX1NUUlVDVCxcbn0gZnJvbSAnLi4vbGliL2FwaSc7XG5pbXBvcnQgeyBjbG9zZVJlY29yZGluZywgcmVjb3JkSW50ZXJhY3Rpb24gfSBmcm9tICcuL3JlY29yZGluZyc7XG5cbi8qIGVzbGludC1kaXNhYmxlIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXMgKi9cblxuLy8gZXh0cmFjdCB2ZXJzaW9ucyBvZiBmaXh0dXJlc1xuY29uc3QgY2FsY0Jhc2VWZXJzaW9uID1cbiAgcmVxdWlyZSgnQHNjb3BlL2pzaWktY2FsYy1iYXNlL3BhY2thZ2UuanNvbicpLnZlcnNpb24ucmVwbGFjZSgvXFwrLiskLywgJycpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5jb25zdCBjYWxjTGliVmVyc2lvbiA9XG4gIHJlcXVpcmUoJ0BzY29wZS9qc2lpLWNhbGMtbGliL3BhY2thZ2UuanNvbicpLnZlcnNpb24ucmVwbGFjZSgvXFwrLiskLywgJycpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5jb25zdCBjYWxjVmVyc2lvbiA9IHJlcXVpcmUoJ2pzaWktY2FsYy9wYWNrYWdlLmpzb24nKS52ZXJzaW9uLnJlcGxhY2UoIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgL1xcKy4rJC8sXG4gICcnLFxuKTtcblxuLy8gRG8gdGhpcyBzbyB0aGF0IHJlZ2V4ZXMgc3RyaW5naWZ5IG5pY2VseSBpbiBhcHByb3hpbWF0ZSB0ZXN0c1xuKFJlZ0V4cC5wcm90b3R5cGUgYXMgYW55KS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gIHJldHVybiB0aGlzLnNvdXJjZTtcbn07XG5cbnByb2Nlc3Muc2V0TWF4TGlzdGVuZXJzKDk5OTkpOyAvLyBzaW5jZSBldmVyeSBrZXJuZWwgaW5zdGFuY2UgYWRkcyBhbiBgb24oJ2V4aXQnKWAgaGFuZGxlci5cblxucHJvY2Vzcy5vbigndW5oYW5kbGVkUmVqZWN0aW9uJywgKGUpID0+IHtcbiAgY29uc29sZS5lcnJvcigoZSBhcyBFcnJvcikuc3RhY2spO1xuICBwcm9jZXNzLmV4aXQoMSk7XG59KTtcblxuamVzdC5zZXRUaW1lb3V0KDYwXzAwMCk7XG5cbmNvbnN0IHJlY29yZGluZ091dHB1dCA9IHByb2Nlc3MuZW52LkpTSUlfUkVDT1JEO1xuaWYgKHJlY29yZGluZ091dHB1dCkge1xuICBmcy5ta2RpcnBTeW5jKHJlY29yZGluZ091dHB1dCk7XG4gIGNvbnNvbGUuZXJyb3IoYEpTSUlfUkVDT1JEPSR7cmVjb3JkaW5nT3V0cHV0fWApO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVUZXN0KFxuICBuYW1lOiBzdHJpbmcsXG4gIG1ldGhvZDogKHNhbmRib3g6IEtlcm5lbCkgPT4gUHJvbWlzZTxhbnk+IHwgYW55LFxuICB0ZXN0RnVuYyA9IHRlc3QsXG4pIHtcbiAgY29uc3QgcmVjb3JkaW5nID0gbmFtZS5yZXBsYWNlKC9bXkEtWmEtel0vZywgJ18nKTtcblxuICB0ZXN0RnVuYyhuYW1lLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qga2VybmVsID0gYXdhaXQgY3JlYXRlQ2FsY3VsYXRvclNhbmRib3gocmVjb3JkaW5nKTtcbiAgICBhd2FpdCBtZXRob2Qoa2VybmVsKTtcbiAgICByZXR1cm4gY2xvc2VSZWNvcmRpbmcoa2VybmVsKTtcbiAgfSk7XG59XG5cbmRlZmluZVRlc3Quc2tpcCA9IGZ1bmN0aW9uIChcbiAgbmFtZTogc3RyaW5nLFxuICBtZXRob2Q6IChzYW5kYm94OiBLZXJuZWwpID0+IFByb21pc2U8YW55PiB8IGFueSxcbikge1xuICByZXR1cm4gZGVmaW5lVGVzdChuYW1lLCBtZXRob2QsIHRlc3Quc2tpcCk7XG59O1xuXG4vLyBOb3RlOiB0aGlzIHRlc3QgYXNzZXJ0cyBmaWxlIHBlcm1pc3Npb25zLCB3aGljaCB3b3JrIGRpZmZlcmVudGx5IG9uIFdpbmRvd3MsIHNvIHdlIHNraXAgaXQgdGhlcmVcbihwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInID8gdGVzdC5za2lwIDogdGVzdCkoXG4gICdsb2FkIHByZXNlcnZlcyBmaWxlIHBlcm1pc3Npb25zJyxcbiAgYXN5bmMgKCkgPT4ge1xuICAgIC8vIENoYW5naW5nIHRoZSB1bWFzayB0byAwNzcgKHdoaWNoIHdvdWxkIG5ldXRyYWxpemUgZ3JvdXAvb3RoZXIgcGVybWlzc2lvbnMpXG4gICAgY29uc3Qgb3JpZ2luYWxVbWFzayA9IHByb2Nlc3MudW1hc2soMG8wNzcpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGtlcm5lbCA9IGF3YWl0IGNyZWF0ZUNhbGN1bGF0b3JTYW5kYm94KFxuICAgICAgICAnbG9hZF9wcmVzZXJ2ZXNfZmlsZV9wZXJtaXNzaW9ucycsXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBrZXJuZWwuc2ludm9rZSh7XG4gICAgICAgIGZxbjogJ2pzaWktY2FsYy5VbWFza0NoZWNrJyxcbiAgICAgICAgbWV0aG9kOiAnbW9kZScsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChyZXN1bHQucmVzdWx0KS50b0JlKDBvNjQ0KTtcblxuICAgICAgcmV0dXJuIGF3YWl0IGNsb3NlUmVjb3JkaW5nKGtlcm5lbCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHVtYXNrXG4gICAgICBwcm9jZXNzLnVtYXNrKG9yaWdpbmFsVW1hc2spO1xuICAgIH1cbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoJ3N0YXRzKCkgcmV0dXJuIHNhbmRib3ggc3RhdGlzdGljcycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IHN0YXRzID0gc2FuZGJveC5zdGF0cyh7fSk7XG4gIGV4cGVjdChzdGF0cy5vYmplY3RDb3VudCkudG9CZSgwKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IDEwMDsgKytpKSB7XG4gICAgc2FuZGJveC5jcmVhdGUoeyBmcW46ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXInLCBhcmdzOiBbaV0gfSk7XG4gIH1cblxuICBleHBlY3Qoc2FuZGJveC5zdGF0cyh7fSkub2JqZWN0Q291bnQpLnRvQmUoMTAwKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdkZWxldGVPYmplY3Qgd2lsbCByZW1vdmUgdGhlIHJlZmVyZW5jZScsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9iamVjdHMgPSBuZXcgQXJyYXk8YW55PigpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgMTAwOyArK2kpIHtcbiAgICBvYmplY3RzLnB1c2goXG4gICAgICBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlcicsIGFyZ3M6IFtpXSB9KSxcbiAgICApO1xuICB9XG5cbiAgZXhwZWN0KHNhbmRib3guc3RhdHMoe30pLm9iamVjdENvdW50KS50b0JlKDEwMCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA1MDsgKytpKSB7XG4gICAgc2FuZGJveC5kZWwoeyBvYmpyZWY6IG9iamVjdHNbaV0gfSk7XG4gIH1cblxuICBleHBlY3Qoc2FuZGJveC5zdGF0cyh7fSkub2JqZWN0Q291bnQpLnRvQmUoNTApO1xuXG4gIGV4cGVjdCgoKSA9PlxuICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBvYmplY3RzWzEwXSwgcHJvcGVydHk6ICd2YWx1ZScgfSksXG4gICkudG9UaHJvdygpO1xufSk7XG5cbmRlZmluZVRlc3QoJ2luL291dCBwcmltaXRpdmUgdHlwZXMnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBhbGx0eXBlcyA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFsbFR5cGVzJywgYXJnczogW10gfSk7XG5cbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2Jvb2xlYW5Qcm9wZXJ0eScsIHZhbHVlOiB0cnVlIH0pO1xuICBleHBlY3QoXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2Jvb2xlYW5Qcm9wZXJ0eScgfSkudmFsdWUsXG4gICkudG9CZSh0cnVlKTtcblxuICBzYW5kYm94LnNldCh7IG9ianJlZjogYWxsdHlwZXMsIHByb3BlcnR5OiAnYm9vbGVhblByb3BlcnR5JywgdmFsdWU6IGZhbHNlIH0pO1xuICBleHBlY3QoXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2Jvb2xlYW5Qcm9wZXJ0eScgfSkudmFsdWUsXG4gICkudG9CZShmYWxzZSk7XG5cbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ3N0cmluZ1Byb3BlcnR5JywgdmFsdWU6ICdoZWxsbycgfSk7XG4gIGV4cGVjdChcbiAgICBzYW5kYm94LmdldCh7IG9ianJlZjogYWxsdHlwZXMsIHByb3BlcnR5OiAnc3RyaW5nUHJvcGVydHknIH0pLnZhbHVlLFxuICApLnRvQmUoJ2hlbGxvJyk7XG5cbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ251bWJlclByb3BlcnR5JywgdmFsdWU6IDEyMyB9KTtcbiAgZXhwZWN0KFxuICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBhbGx0eXBlcywgcHJvcGVydHk6ICdudW1iZXJQcm9wZXJ0eScgfSkudmFsdWUsXG4gICkudG9CZSgxMjMpO1xuXG4gIC8vIGluIC0+IG91dCBmb3IgYW4gQU5ZXG4gIGNvbnN0IG51bSA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXInLFxuICAgIGFyZ3M6IFs0NDRdLFxuICB9KTtcbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2FueVByb3BlcnR5JywgdmFsdWU6IG51bSB9KTtcbiAgZXhwZWN0KFxuICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBhbGx0eXBlcywgcHJvcGVydHk6ICdhbnlQcm9wZXJ0eScgfSkudmFsdWUsXG4gICkudG9FcXVhbChudW0pO1xuXG4gIC8vIG91dCAtPiBpbiBmb3IgYW4gQU5ZXG4gIGNvbnN0IHJldCA9IHNhbmRib3guaW52b2tlKHsgb2JqcmVmOiBhbGx0eXBlcywgbWV0aG9kOiAnYW55T3V0JyB9KS5yZXN1bHQ7XG4gIHNhbmRib3guaW52b2tlKHsgb2JqcmVmOiBhbGx0eXBlcywgbWV0aG9kOiAnYW55SW4nLCBhcmdzOiBbcmV0XSB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdpbi9vdXQgb2JqZWN0cycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IGFsbHR5cGVzID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQWxsVHlwZXMnIH0pO1xuXG4gIGNvbnN0IG51bSA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXInLFxuICAgIGFyZ3M6IFs0NDRdLFxuICB9KTtcbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2FueVByb3BlcnR5JywgdmFsdWU6IG51bSB9KTtcbiAgZXhwZWN0KFxuICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBhbGx0eXBlcywgcHJvcGVydHk6ICdhbnlQcm9wZXJ0eScgfSkudmFsdWUsXG4gICkudG9FcXVhbChudW0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ2luL291dCBjb2xsZWN0aW9ucycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IGFsbHR5cGVzID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQWxsVHlwZXMnLCBhcmdzOiBbXSB9KTtcblxuICBjb25zdCBhcnJheSA9IFsnMScsICcyJywgJzMnLCAnNCddO1xuICBzYW5kYm94LnNldCh7IG9ianJlZjogYWxsdHlwZXMsIHByb3BlcnR5OiAnYXJyYXlQcm9wZXJ0eScsIHZhbHVlOiBhcnJheSB9KTtcbiAgZXhwZWN0KFxuICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBhbGx0eXBlcywgcHJvcGVydHk6ICdhcnJheVByb3BlcnR5JyB9KS52YWx1ZSxcbiAgKS50b0VxdWFsKGFycmF5KTtcblxuICBjb25zdCBudW0gPSBjcmVhdGUoc2FuZGJveCwgJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlcicpO1xuXG4gIGNvbnN0IG1hcCA9IHtcbiAgICBhOiBudW0oMTIpLFxuICAgIGI6IG51bSgzMyksXG4gICAgYzogbnVtKDMzKSxcbiAgICBkOiBudW0oMTIzKSxcbiAgfTtcblxuICBzYW5kYm94LnNldCh7XG4gICAgb2JqcmVmOiBhbGx0eXBlcyxcbiAgICBwcm9wZXJ0eTogJ21hcFByb3BlcnR5JyxcbiAgICB2YWx1ZTogeyBbVE9LRU5fTUFQXTogbWFwIH0sXG4gIH0pO1xuICBleHBlY3QoXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ21hcFByb3BlcnR5JyB9KS52YWx1ZVtUT0tFTl9NQVBdLFxuICApLnRvRXF1YWwobWFwKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdpbi9vdXQgZGF0ZSB2YWx1ZXMnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBhbGx0eXBlcyA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFsbFR5cGVzJyB9KTtcblxuICBjb25zdCBkYXRlID0gbmV3IERhdGUoJzIwMTgtMDEtMThUMDA6MDA6MzIuMzQ3WicpO1xuICBzYW5kYm94LnNldCh7XG4gICAgb2JqcmVmOiBhbGx0eXBlcyxcbiAgICBwcm9wZXJ0eTogJ2RhdGVQcm9wZXJ0eScsXG4gICAgdmFsdWU6IHsgW2FwaS5UT0tFTl9EQVRFXTogZGF0ZS50b0lTT1N0cmluZygpIH0sXG4gIH0pO1xuICBleHBlY3QoXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2RhdGVQcm9wZXJ0eScgfSkudmFsdWUsXG4gICkudG9FcXVhbCh7IFthcGkuVE9LRU5fREFURV06ICcyMDE4LTAxLTE4VDAwOjAwOjMyLjM0N1onIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ2luL291dCBlbnVtIHZhbHVlcycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IGFsbHR5cGVzID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQWxsVHlwZXMnIH0pO1xuXG4gIHNhbmRib3guc2V0KHtcbiAgICBvYmpyZWY6IGFsbHR5cGVzLFxuICAgIHByb3BlcnR5OiAnZW51bVByb3BlcnR5JyxcbiAgICB2YWx1ZTogeyBbYXBpLlRPS0VOX0VOVU1dOiAnanNpaS1jYWxjLkFsbFR5cGVzRW51bS9NWV9FTlVNX1ZBTFVFJyB9LFxuICB9KTtcbiAgZXhwZWN0KFxuICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBhbGx0eXBlcywgcHJvcGVydHk6ICdlbnVtUHJvcGVydHlWYWx1ZScgfSkudmFsdWUsXG4gICkudG9CZSgwKTtcbiAgc2FuZGJveC5zZXQoe1xuICAgIG9ianJlZjogYWxsdHlwZXMsXG4gICAgcHJvcGVydHk6ICdlbnVtUHJvcGVydHknLFxuICAgIHZhbHVlOiB7IFthcGkuVE9LRU5fRU5VTV06ICdqc2lpLWNhbGMuQWxsVHlwZXNFbnVtL1lPVVJfRU5VTV9WQUxVRScgfSxcbiAgfSk7XG4gIGV4cGVjdChcbiAgICBzYW5kYm94LmdldCh7IG9ianJlZjogYWxsdHlwZXMsIHByb3BlcnR5OiAnZW51bVByb3BlcnR5VmFsdWUnIH0pLnZhbHVlLFxuICApLnRvQmUoMTAwKTtcbiAgc2FuZGJveC5zZXQoe1xuICAgIG9ianJlZjogYWxsdHlwZXMsXG4gICAgcHJvcGVydHk6ICdlbnVtUHJvcGVydHknLFxuICAgIHZhbHVlOiB7IFthcGkuVE9LRU5fRU5VTV06ICdqc2lpLWNhbGMuQWxsVHlwZXNFbnVtL1RISVNfSVNfR1JFQVQnIH0sXG4gIH0pO1xuICBleHBlY3QoXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbHR5cGVzLCBwcm9wZXJ0eTogJ2VudW1Qcm9wZXJ0eVZhbHVlJyB9KS52YWx1ZSxcbiAgKS50b0JlKDEwMSk7XG4gIGV4cGVjdChcbiAgICBzYW5kYm94LmdldCh7IG9ianJlZjogYWxsdHlwZXMsIHByb3BlcnR5OiAnZW51bVByb3BlcnR5JyB9KS52YWx1ZSxcbiAgKS50b0VxdWFsKHsgJyRqc2lpLmVudW0nOiAnanNpaS1jYWxjLkFsbFR5cGVzRW51bS9USElTX0lTX0dSRUFUJyB9KTtcbn0pO1xuXG5kZXNjcmliZSgnaW4vb3V0IGpzb24gdmFsdWVzJywgKCkgPT4ge1xuICBkZWZpbmVUZXN0KCd3aXRoIGEgcGxhaW4gb2JqZWN0JywgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBhbGxUeXBlcyA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFsbFR5cGVzJyB9KTtcbiAgICBzYW5kYm94LnNldCh7XG4gICAgICBvYmpyZWY6IGFsbFR5cGVzLFxuICAgICAgcHJvcGVydHk6ICdqc29uUHJvcGVydHknLFxuICAgICAgdmFsdWU6IHsgZm9vOiAnYmFyJywgYmF6OiAxMzM3IH0sXG4gICAgfSk7XG4gICAgZXhwZWN0KFxuICAgICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbFR5cGVzLCBwcm9wZXJ0eTogJ2pzb25Qcm9wZXJ0eScgfSkudmFsdWUsXG4gICAgKS50b0VxdWFsKHsgZm9vOiAnYmFyJywgYmF6OiAxMzM3IH0pO1xuICB9KTtcbiAgZGVmaW5lVGVzdCgnd2l0aCBhIHNpbXBsZSBtYXBwaW5nJywgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBhbGxUeXBlcyA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFsbFR5cGVzJyB9KTtcbiAgICBzYW5kYm94LnNldCh7XG4gICAgICBvYmpyZWY6IGFsbFR5cGVzLFxuICAgICAgcHJvcGVydHk6ICdqc29uUHJvcGVydHknLFxuICAgICAgdmFsdWU6IHsgW2FwaS5UT0tFTl9NQVBdOiB7IGZvbzogJ2JhcicsIGJhejogMTMzNyB9IH0sXG4gICAgfSk7XG4gICAgZXhwZWN0KFxuICAgICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFsbFR5cGVzLCBwcm9wZXJ0eTogJ2pzb25Qcm9wZXJ0eScgfSkudmFsdWUsXG4gICAgKS50b0VxdWFsKHsgZm9vOiAnYmFyJywgYmF6OiAxMzM3IH0pO1xuICB9KTtcbiAgZGVmaW5lVGVzdCgnd2l0aCBhIG5lc3RlZCBtYXBwaW5nJywgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBhbGxUeXBlcyA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFsbFR5cGVzJyB9KTtcbiAgICBzYW5kYm94LnNldCh7XG4gICAgICBvYmpyZWY6IGFsbFR5cGVzLFxuICAgICAgcHJvcGVydHk6ICdqc29uUHJvcGVydHknLFxuICAgICAgdmFsdWU6IHtcbiAgICAgICAgW2FwaS5UT0tFTl9NQVBdOiB7XG4gICAgICAgICAgZm9vOiAnYmFyJyxcbiAgICAgICAgICBiYXo6IHsgW2FwaS5UT0tFTl9NQVBdOiB7IGJhemluZ2E6IFtudWxsLCAnUGlja2xlIFJpY2snXSB9IH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGV4cGVjdChcbiAgICAgIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBhbGxUeXBlcywgcHJvcGVydHk6ICdqc29uUHJvcGVydHknIH0pLnZhbHVlLFxuICAgICkudG9FcXVhbCh7IGZvbzogJ2JhcicsIGJhejogeyBiYXppbmdhOiBbbnVsbCwgJ1BpY2tsZSBSaWNrJ10gfSB9KTtcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnZW51bSB2YWx1ZXMgZnJvbSBAc2NvcGVkIHBhY2thZ2VzIGF3c2xhYnMvanNpaSMxMzgnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLlJlZmVyZW5jZUVudW1Gcm9tU2NvcGVkUGFja2FnZScsXG4gIH0pO1xuXG4gIGNvbnN0IHZhbHVlID0gc2FuZGJveC5nZXQoeyBvYmpyZWYsIHByb3BlcnR5OiAnZm9vJyB9KTtcbiAgZXhwZWN0KHZhbHVlKS50b0VxdWFsKHtcbiAgICB2YWx1ZTogeyAnJGpzaWkuZW51bSc6ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5FbnVtRnJvbVNjb3BlZE1vZHVsZS9WQUxVRTInIH0sXG4gIH0pO1xuXG4gIHNhbmRib3guc2V0KHtcbiAgICBvYmpyZWYsXG4gICAgcHJvcGVydHk6ICdmb28nLFxuICAgIHZhbHVlOiB7ICckanNpaS5lbnVtJzogJ0BzY29wZS9qc2lpLWNhbGMtbGliLkVudW1Gcm9tU2NvcGVkTW9kdWxlL1ZBTFVFMScgfSxcbiAgfSk7XG4gIGNvbnN0IHJldCA9IHNhbmRib3guaW52b2tlKHsgb2JqcmVmLCBtZXRob2Q6ICdsb2FkRm9vJyB9KTtcbiAgZXhwZWN0KHJldCkudG9FcXVhbCh7XG4gICAgcmVzdWx0OiB7XG4gICAgICAnJGpzaWkuZW51bSc6ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5FbnVtRnJvbVNjb3BlZE1vZHVsZS9WQUxVRTEnLFxuICAgIH0sXG4gIH0pO1xuXG4gIHNhbmRib3guaW52b2tlKHtcbiAgICBvYmpyZWYsXG4gICAgbWV0aG9kOiAnc2F2ZUZvbycsXG4gICAgYXJnczogW1xuICAgICAgeyAnJGpzaWkuZW51bSc6ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5FbnVtRnJvbVNjb3BlZE1vZHVsZS9WQUxVRTInIH0sXG4gICAgXSxcbiAgfSk7XG4gIGNvbnN0IHZhbHVlMiA9IHNhbmRib3guZ2V0KHsgb2JqcmVmLCBwcm9wZXJ0eTogJ2ZvbycgfSk7XG4gIGV4cGVjdCh2YWx1ZTIpLnRvRXF1YWwoe1xuICAgIHZhbHVlOiB7ICckanNpaS5lbnVtJzogJ0BzY29wZS9qc2lpLWNhbGMtbGliLkVudW1Gcm9tU2NvcGVkTW9kdWxlL1ZBTFVFMicgfSxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnZmFpbHMgZm9yIGludmFsaWQgZW51bSBtZW1iZXIgbmFtZScsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9ianJlZiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuUmVmZXJlbmNlRW51bUZyb21TY29wZWRQYWNrYWdlJyxcbiAgfSk7XG5cbiAgZXhwZWN0KCgpID0+IHtcbiAgICBzYW5kYm94LnNldCh7XG4gICAgICBvYmpyZWYsXG4gICAgICBwcm9wZXJ0eTogJ2ZvbycsXG4gICAgICB2YWx1ZToge1xuICAgICAgICAnJGpzaWkuZW51bSc6ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5FbnVtRnJvbVNjb3BlZE1vZHVsZS9WYWx1ZVgnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSkudG9UaHJvdygvTm8gZW51bSBtZW1iZXIgbmFtZWQgVmFsdWVYLyk7XG59KTtcblxuZGVmaW5lVGVzdCgnc2V0IGZvciBhIG5vbiBleGlzdGluZyBwcm9wZXJ0eScsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLlN5bmNWaXJ0dWFsTWV0aG9kcycgfSk7XG4gIGV4cGVjdCgoKSA9PlxuICAgIHNhbmRib3guc2V0KHsgb2JqcmVmOiBvYmosIHByb3BlcnR5OiAnaWRvbnRleGlzdCcsIHZhbHVlOiAnRm9vJyB9KSxcbiAgKS50b1Rocm93KCk7XG59KTtcblxuZGVmaW5lVGVzdCgnc2V0IGZvciBhIHJlYWRvbmx5IHByb3BlcnR5JywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyB9KTtcbiAgZXhwZWN0KCgpID0+XG4gICAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICdyZWFkb25seVByb3BlcnR5JywgdmFsdWU6ICdGb28nIH0pLFxuICApLnRvVGhyb3coKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdjcmVhdGUgb2JqZWN0IHdpdGggY3RvciBvdmVybG9hZHMnLCAoc2FuZGJveCkgPT4ge1xuICBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ2pzaWktY2FsYy5DYWxjdWxhdG9yJyB9KTtcbiAgc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5DYWxjdWxhdG9yJyxcbiAgICBhcmdzOiBbeyBpbml0aWFsVmFsdWU6IDEwMCB9XSxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdChcbiAgJ29iamVjdHMgY3JlYXRlZCBpbnNpZGUgdGhlIHNhbmRib3ggYXJlIHJldHVybmVkIHdpdGggdHlwZSBpbmZvIGFuZCBuZXcgb2JqaWQnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGNvbnN0IGNhbGMgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuQ2FsY3VsYXRvcicsXG4gICAgICBhcmdzOiBbeyBpbml0aWFsVmFsdWU6IDEwMCB9XSxcbiAgICB9KTtcbiAgICBzYW5kYm94Lmludm9rZSh7IG9ianJlZjogY2FsYywgbWV0aG9kOiAnYWRkJywgYXJnczogWzUwXSB9KTtcblxuICAgIGNvbnN0IGFkZCA9IHNhbmRib3guZ2V0KHsgb2JqcmVmOiBjYWxjLCBwcm9wZXJ0eTogJ2N1cnInIH0pLnZhbHVlO1xuICAgIGV4cGVjdChzYW5kYm94LmdldCh7IG9ianJlZjogYWRkLCBwcm9wZXJ0eTogJ3ZhbHVlJyB9KS52YWx1ZSkudG9CZSgxNTApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ25hbWluZyBhbGxvd3MgcmV0dXJucyB0aGUgbW9kdWxlIG5hbWUgZm9yIGRpZmZlcmVudCBsYW5ndWFnZXMnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGV4cGVjdChzYW5kYm94Lm5hbWluZyh7IGFzc2VtYmx5OiAnanNpaS1jYWxjJyB9KS5uYW1pbmcpLnRvRXF1YWwoe1xuICAgICAgZG90bmV0OiB7XG4gICAgICAgIGljb25Vcmw6XG4gICAgICAgICAgJ2h0dHBzOi8vc2RrLWZvci1uZXQuYW1hem9ud2Vic2VydmljZXMuY29tL2ltYWdlcy9BV1NMb2dvMTI4eDEyOC5wbmcnLFxuICAgICAgICBuYW1lc3BhY2U6ICdBbWF6b24uSlNJSS5UZXN0cy5DYWxjdWxhdG9yTmFtZXNwYWNlJyxcbiAgICAgICAgcGFja2FnZUlkOiAnQW1hem9uLkpTSUkuVGVzdHMuQ2FsY3VsYXRvclBhY2thZ2VJZCcsXG4gICAgICB9LFxuICAgICAgZ286IHtcbiAgICAgICAgbW9kdWxlTmFtZTogJ2dpdGh1Yi5jb20vYXdzL2pzaWkvanNpaS1jYWxjL2dvJyxcbiAgICAgIH0sXG4gICAgICBqYXZhOiB7XG4gICAgICAgIHBhY2thZ2U6ICdzb2Z0d2FyZS5hbWF6b24uanNpaS50ZXN0cy5jYWxjdWxhdG9yJyxcbiAgICAgICAgbWF2ZW46IHtcbiAgICAgICAgICBncm91cElkOiAnc29mdHdhcmUuYW1hem9uLmpzaWkudGVzdHMnLFxuICAgICAgICAgIGFydGlmYWN0SWQ6ICdjYWxjdWxhdG9yJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBqczogeyBucG06ICdqc2lpLWNhbGMnIH0sXG4gICAgICBweXRob246IHtcbiAgICAgICAgZGlzdE5hbWU6ICdqc2lpLWNhbGMnLFxuICAgICAgICBtb2R1bGU6ICdqc2lpX2NhbGMnLFxuICAgICAgICBjbGFzc2lmaWVyczogWydUZXN0IDo6IENsYXNzaWZpZXIgOjogSXMgRHVtbXknXSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgZXhwZWN0KHNhbmRib3gubmFtaW5nKHsgYXNzZW1ibHk6ICdAc2NvcGUvanNpaS1jYWxjLWxpYicgfSkubmFtaW5nKS50b0VxdWFsKFxuICAgICAge1xuICAgICAgICBkb3RuZXQ6IHtcbiAgICAgICAgICBuYW1lc3BhY2U6ICdBbWF6b24uSlNJSS5UZXN0cy5DYWxjdWxhdG9yTmFtZXNwYWNlLkxpYk5hbWVzcGFjZScsXG4gICAgICAgICAgcGFja2FnZUlkOiAnQW1hem9uLkpTSUkuVGVzdHMuQ2FsY3VsYXRvclBhY2thZ2VJZC5MaWJQYWNrYWdlSWQnLFxuICAgICAgICAgIHZlcnNpb25TdWZmaXg6ICctZGV2cHJldmlldycsXG4gICAgICAgIH0sXG4gICAgICAgIGdvOiB7XG4gICAgICAgICAgbW9kdWxlTmFtZTogJ2dpdGh1Yi5jb20vYXdzL2pzaWkvanNpaS1jYWxjL2dvJyxcbiAgICAgICAgICB2ZXJzaW9uU3VmZml4OiAnLWRldnByZXZpZXcnLFxuICAgICAgICB9LFxuICAgICAgICBqYXZhOiB7XG4gICAgICAgICAgcGFja2FnZTogJ3NvZnR3YXJlLmFtYXpvbi5qc2lpLnRlc3RzLmNhbGN1bGF0b3IubGliJyxcbiAgICAgICAgICBtYXZlbjoge1xuICAgICAgICAgICAgZ3JvdXBJZDogJ3NvZnR3YXJlLmFtYXpvbi5qc2lpLnRlc3RzJyxcbiAgICAgICAgICAgIGFydGlmYWN0SWQ6ICdjYWxjdWxhdG9yLWxpYicsXG4gICAgICAgICAgICB2ZXJzaW9uU3VmZml4OiAnLkRFVlBSRVZJRVcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGpzOiB7IG5wbTogJ0BzY29wZS9qc2lpLWNhbGMtbGliJyB9LFxuICAgICAgICBweXRob246IHtcbiAgICAgICAgICBkaXN0TmFtZTogJ3Njb3BlLmpzaWktY2FsYy1saWInLFxuICAgICAgICAgIG1vZHVsZTogJ3Njb3BlLmpzaWlfY2FsY19saWInLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdCgnY29sbGVjdGlvbiBvZiBvYmplY3RzJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgc3VtID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuU3VtJyB9KTtcblxuICBjb25zdCBuMSA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnQHNjb3BlL2pzaWktY2FsYy1saWIuTnVtYmVyJywgYXJnczogWzEwXSB9KTtcbiAgY29uc3QgbjIgPSBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlcicsIGFyZ3M6IFs0XSB9KTtcbiAgY29uc3QgbjMgPSBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ2pzaWktY2FsYy5Qb3dlcicsIGFyZ3M6IFtuMSwgbjJdIH0pO1xuXG4gIHNhbmRib3guc2V0KHsgb2JqcmVmOiBzdW0sIHByb3BlcnR5OiAncGFydHMnLCB2YWx1ZTogW24xLCBuMiwgbjNdIH0pO1xuXG4gIGNvbnN0IHBhcnRzID0gc2FuZGJveC5nZXQoeyBvYmpyZWY6IHN1bSwgcHJvcGVydHk6ICdwYXJ0cycgfSkudmFsdWU7XG4gIGV4cGVjdChzYW5kYm94LmdldCh7IG9ianJlZjogcGFydHNbMF0sIHByb3BlcnR5OiAndmFsdWUnIH0pLnZhbHVlKS50b0JlKDEwKTtcbiAgZXhwZWN0KHNhbmRib3guZ2V0KHsgb2JqcmVmOiBwYXJ0c1sxXSwgcHJvcGVydHk6ICd2YWx1ZScgfSkudmFsdWUpLnRvQmUoNCk7XG4gIGV4cGVjdChzYW5kYm94LmdldCh7IG9ianJlZjogcGFydHNbMl0sIHByb3BlcnR5OiAndmFsdWUnIH0pLnZhbHVlKS50b0JlKFxuICAgIE1hdGgucG93KDEwLCA0KSxcbiAgKTtcblxuICBjb25zdCBleHByID0gc2FuZGJveC5nZXQoeyBvYmpyZWY6IHN1bSwgcHJvcGVydHk6ICdleHByZXNzaW9uJyB9KS52YWx1ZTtcbiAgZXhwZWN0KHNhbmRib3guaW52b2tlKHsgb2JqcmVmOiBleHByLCBtZXRob2Q6ICd0b1N0cmluZycgfSkucmVzdWx0KS50b0JlKFxuICAgICcoKCgwICsgMTApICsgNCkgKyAoKCgoMSAqIDEwKSAqIDEwKSAqIDEwKSAqIDEwKSknLFxuICApO1xuICBleHBlY3Qoc2FuZGJveC5nZXQoeyBvYmpyZWY6IGV4cHIsIHByb3BlcnR5OiAndmFsdWUnIH0pLnZhbHVlKS50b0JlKDEwMDE0KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdjbGFzcyBub3QgZm91bmQnLCAoc2FuZGJveCkgPT4ge1xuICBleHBlY3QoKCkgPT4gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdOb3RGb3VuZCcsIGFyZ3M6IFtdIH0pKS50b1Rocm93KCk7XG59KTtcblxuZGVmaW5lVGVzdChcbiAgJ3R5cGUtY2hlY2tpbmc6IG1ldGhvZCBhbmQgcHJvcGVydHkgbmFtZXMgYXJlIHZhbGlkYXRlZCBhZ2FpbnN0IGNsYXNzIGFuZCBiYXNlIGNsYXNzZXMnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkNhbGN1bGF0b3InIH0pO1xuXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICdzdHJpbmdTdHlsZScgfSk7IC8vIHByb3BlcnR5IGZyb20gQ29tcG9zaXRlT3BlcmF0aW9uXG4gICAgc2FuZGJveC5nZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICd2YWx1ZScgfSk7IC8vIHByb3BlcnR5IGZyb20gVmFsdWVcbiAgICBzYW5kYm94LmdldCh7IG9ianJlZjogb2JqLCBwcm9wZXJ0eTogJ2N1cnInIH0pOyAvLyBwcm9wZXJ0eSBmcm9tIENhbGN1bGF0b3JcblxuICAgIHNhbmRib3guaW52b2tlKHsgb2JqcmVmOiBvYmosIG1ldGhvZDogJ3R5cGVOYW1lJyB9KTsgLy8gbWV0aG9kIGZyb20gVmFsdWVcbiAgICBzYW5kYm94Lmludm9rZSh7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdhZGQnLCBhcmdzOiBbMV0gfSk7IC8vIG1ldGhvZCBmcm9tIENhbGN1bGF0b3JcblxuICAgIGV4cGVjdCgoKSA9PiBzYW5kYm94LmdldCh7IG9ianJlZjogb2JqLCBwcm9wZXJ0eTogJ25vdEZvdW5kJyB9KSkudG9UaHJvdygpO1xuICAgIGV4cGVjdCgoKSA9PlxuICAgICAgc2FuZGJveC5pbnZva2UoeyBvYmpyZWY6IG9iaiwgbWV0aG9kOiAnYm9vJywgYXJnczogW10gfSksXG4gICAgKS50b1Rocm93KCk7XG4gIH0sXG4pO1xuXG5kZWZpbmVUZXN0KCd0eXBlLWNoZWNraW5nOyBtb2R1bGUgbm90IGZvdW5kJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KCgpID0+IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaSRib28uRm9vJyB9KSkudG9UaHJvdyhcbiAgICAvTW9kdWxlICdqc2lpXFwkYm9vJyBub3QgZm91bmQvLFxuICApO1xufSk7XG5cbmRlZmluZVRlc3QoJ3R5cGUtY2hlY2tpbmc6IHR5cGUgbm90IGZvdW5kJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KCgpID0+IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLlVua25vd24nIH0pKS50b1Rocm93KFxuICAgIC9UeXBlICdqc2lpLWNhbGMuVW5rbm93bicgbm90IGZvdW5kLyxcbiAgKTtcbn0pO1xuXG5kZWZpbmVUZXN0KFxuICAndHlwZS1jaGVja2luZzogdHJ5IHRvIGNyZWF0ZSBhbiBvYmplY3QgZnJvbSBhIG5vbi1jbGFzcyB0eXBlJyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBleHBlY3QoKCkgPT4gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQWxsVHlwZXNFbnVtJyB9KSkudG9UaHJvdyhcbiAgICAgIC9VbmV4cGVjdGVkIEZRTiBraW5kLyxcbiAgICApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ3R5cGUtY2hlY2tpbmc6IGFyZ3VtZW50IGNvdW50IGluIG1ldGhvZHMgYW5kIGluaXRpYWxpemVycycsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgLy8gY3RvciBoYXMgb25lIG9wdGlvbmFsIGFyZ3VtZW50XG4gICAgc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQ2FsY3VsYXRvcicgfSk7XG4gICAgc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQ2FsY3VsYXRvcicsIGFyZ3M6IFt7fV0gfSk7XG5cbiAgICAvLyBidXQgd2UgZXhwZWN0IGFuIGVycm9yIGlmIG1vcmUgYXJndW1lbnRzIGFyZSBwYXNzZWRcbiAgICBleHBlY3QoKCkgPT5cbiAgICAgIHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkNhbGN1bGF0b3InLCBhcmdzOiBbMSwgMiwgM10gfSksXG4gICAgKS50b1Rocm93KC9Ub28gbWFueSBhcmd1bWVudHMvKTtcbiAgICBleHBlY3QoKCkgPT5cbiAgICAgIHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkNhbGN1bGF0b3InLCBhcmdzOiBbMSwgMiwgMywgNF0gfSksXG4gICAgKS50b1Rocm93KC9Ub28gbWFueSBhcmd1bWVudHMvKTtcblxuICAgIGV4cGVjdCgoKSA9PiBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ2pzaWktY2FsYy5BZGQnLCBhcmdzOiBbXSB9KSkudG9UaHJvdyhcbiAgICAgIC9Ob3QgZW5vdWdoIGFyZ3VtZW50cy8sXG4gICAgKTtcbiAgICBleHBlY3QoKCkgPT4gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQWRkJywgYXJnczogWzFdIH0pKS50b1Rocm93KFxuICAgICAgL05vdCBlbm91Z2ggYXJndW1lbnRzLyxcbiAgICApO1xuXG4gICAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuUnVudGltZVR5cGVDaGVja2luZycgfSk7XG4gICAgZXhwZWN0KCgpID0+XG4gICAgICBzYW5kYm94Lmludm9rZSh7XG4gICAgICAgIG9ianJlZjogb2JqLFxuICAgICAgICBtZXRob2Q6ICdtZXRob2RXaXRoT3B0aW9uYWxBcmd1bWVudHMnLFxuICAgICAgICBhcmdzOiBbXSxcbiAgICAgIH0pLFxuICAgICkudG9UaHJvdygvTm90IGVub3VnaCBhcmd1bWVudHMvKTtcbiAgICBleHBlY3QoKCkgPT5cbiAgICAgIHNhbmRib3guaW52b2tlKHtcbiAgICAgICAgb2JqcmVmOiBvYmosXG4gICAgICAgIG1ldGhvZDogJ21ldGhvZFdpdGhPcHRpb25hbEFyZ3VtZW50cycsXG4gICAgICAgIGFyZ3M6IFsxXSxcbiAgICAgIH0pLFxuICAgICkudG9UaHJvdygvTm90IGVub3VnaCBhcmd1bWVudHMvKTtcbiAgICBzYW5kYm94Lmludm9rZSh7XG4gICAgICBvYmpyZWY6IG9iaixcbiAgICAgIG1ldGhvZDogJ21ldGhvZFdpdGhPcHRpb25hbEFyZ3VtZW50cycsXG4gICAgICBhcmdzOiBbMSwgJ2hlbGxvJ10sXG4gICAgfSk7XG4gICAgc2FuZGJveC5pbnZva2Uoe1xuICAgICAgb2JqcmVmOiBvYmosXG4gICAgICBtZXRob2Q6ICdtZXRob2RXaXRoT3B0aW9uYWxBcmd1bWVudHMnLFxuICAgICAgYXJnczogWzEsICdoZWxsbycsIHsgW2FwaS5UT0tFTl9EQVRFXTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH1dLFxuICAgIH0pO1xuICAgIGV4cGVjdCgoKSA9PlxuICAgICAgc2FuZGJveC5pbnZva2Uoe1xuICAgICAgICBvYmpyZWY6IG9iaixcbiAgICAgICAgbWV0aG9kOiAnbWV0aG9kV2l0aE9wdGlvbmFsQXJndW1lbnRzJyxcbiAgICAgICAgYXJnczogW1xuICAgICAgICAgIDEsXG4gICAgICAgICAgJ2hlbGxvJyxcbiAgICAgICAgICB7IFthcGkuVE9LRU5fREFURV06IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSB9LFxuICAgICAgICAgICd0b28gbXVjaCcsXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApLnRvVGhyb3coL1RvbyBtYW55IGFyZ3VtZW50cy8pO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ3ZlcmlmeSBvYmplY3QgbGl0ZXJhbHMgYXJlIGNvbnZlcnRlZCB0byByZWFsIGNsYXNzZXMnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkpTT2JqZWN0TGl0ZXJhbFRvTmF0aXZlJyB9KTtcbiAgICBjb25zdCBvYmoyID0gc2FuZGJveC5pbnZva2Uoe1xuICAgICAgb2JqcmVmOiBvYmosXG4gICAgICBtZXRob2Q6ICdyZXR1cm5MaXRlcmFsJyxcbiAgICB9KS5yZXN1bHQ7XG5cbiAgICBleHBlY3Qob2JqMlthcGkuVE9LRU5fUkVGXSkudG9CZVRydXRoeSgpOyAvLyB2ZXJpZnkgdGhhdCB3ZSByZWNlaXZlZCBhIHJlZiBhcyBhIHJlc3VsdDtcblxuICAgIGNvbnN0IG9iamlkOiBzdHJpbmcgPSBvYmoyW2FwaS5UT0tFTl9SRUZdO1xuICAgIGV4cGVjdChvYmppZCkudG9NYXRjaCgvXmpzaWktY2FsYy5KU09iamVjdExpdGVyYWxUb05hdGl2ZUNsYXNzQC8pO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ2dldCBhIHByb3BlcnR5IGZyb20gYW4gdHlwZSB0aGF0IG9ubHkgaGFzIGJhc2UgY2xhc3MgcHJvcGVydGllcycsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgICAgZnFuOiAnanNpaS1jYWxjLkRlcml2ZWRDbGFzc0hhc05vUHJvcGVydGllcy5EZXJpdmVkJyxcbiAgICB9KTtcbiAgICBzYW5kYm94LnNldCh7IG9ianJlZjogb2JqLCBwcm9wZXJ0eTogJ3Byb3AnLCB2YWx1ZTogJ2hpJyB9KTtcbiAgICBleHBlY3Qoc2FuZGJveC5nZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICdwcm9wJyB9KS52YWx1ZSkudG9CZSgnaGknKTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoXG4gICdhc3luYyBvdmVycmlkZXM6IGlnbm9yZXMgb3ZlcnJpZGVzIGZvciB1bmtub3duIG1ldGhvZHMgKHRvIGFsbG93IGRlcml2ZWQgY2xhc3MgdG8ganVzdCBwYXNzIGFsbCBsb2NhbCBtZXRob2QgbmFtZXMpJyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuQXN5bmNWaXJ0dWFsTWV0aG9kcycsXG4gICAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ25vdEZvdW5kJyB9XSxcbiAgICB9KTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoJ2FzeW5jIG92ZXJyaWRlczogb3ZlcnJpZGUgYSBtZXRob2QnLCBhc3luYyAoc2FuZGJveCkgPT4ge1xuICAvLyBmaXJzdCBjYWxsIHdpdGhvdXQgYW4gb3ZlcnJpZGUgYW5kIGV4cGVjdCBwZW5kaW5nQ2FsbGJhY2tzIHRvIHJldHVyblxuICAvLyBhbiBlbXB0eSBhcnJheS5cbiAgY29uc3Qgb2JqMSA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFzeW5jVmlydHVhbE1ldGhvZHMnIH0pO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGNhbGxXaXRoT3ZlcnJpZGUob3ZlcnJpZGVDYWxsYmFjazogKHg6IG51bWJlcikgPT4gbnVtYmVyKSB7XG4gICAgY29uc3QgcHJvbWlzZTEgPSBzYW5kYm94LmJlZ2luKHsgb2JqcmVmOiBvYmoxLCBtZXRob2Q6ICdjYWxsTWUnIH0pO1xuICAgIGV4cGVjdChzYW5kYm94LmNhbGxiYWNrcygpLmNhbGxiYWNrcy5sZW5ndGgpLnRvQmUoMCk7XG4gICAgY29uc3QgcmVzdWx0MSA9IChhd2FpdCBzYW5kYm94LmVuZChwcm9taXNlMSkpLnJlc3VsdDtcbiAgICBleHBlY3QocmVzdWx0MSkudG9CZSgxMjgpO1xuXG4gICAgLy8gbm93IGFkZCBhbiBvdmVycmlkZSBhbmQgY29tcGxldGUgaXQgd2l0aCBhIHNvbWUgdmFsdWUuXG4gICAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgICAgZnFuOiAnanNpaS1jYWxjLkFzeW5jVmlydHVhbE1ldGhvZHMnLFxuICAgICAgb3ZlcnJpZGVzOiBbeyBtZXRob2Q6ICdvdmVycmlkZU1lJywgY29va2llOiAnbXlDb29raWUnIH1dLFxuICAgIH0pO1xuICAgIGNvbnN0IHByb21pc2UyID0gc2FuZGJveC5iZWdpbih7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdjYWxsTWUnIH0pO1xuICAgIGNvbnN0IGNhbGxiYWNrcyA9IHNhbmRib3guY2FsbGJhY2tzKCkuY2FsbGJhY2tzO1xuICAgIGV4cGVjdChjYWxsYmFja3MubGVuZ3RoKS50b0JlKDEpO1xuICAgIGNvbnN0IGNiID0gY2FsbGJhY2tzWzBdO1xuICAgIGV4cGVjdChjYi5pbnZva2UpLnRvQmVUcnV0aHkoKTtcbiAgICBleHBlY3QoY2IuaW52b2tlIS5vYmpyZWYpLnRvRXF1YWwob2JqKTtcbiAgICBleHBlY3QoY2IuaW52b2tlIS5tZXRob2QpLnRvQmUoJ292ZXJyaWRlTWUnKTtcbiAgICBleHBlY3QoY2IuY29va2llKS50b0JlKCdteUNvb2tpZScpO1xuICAgIGV4cGVjdChjYi5pbnZva2UhLmFyZ3MpLnRvRXF1YWwoWzEwXSk7XG5cbiAgICAvLyBjYWxsaW5nIHBlbmRpbmdDYWxsYmFja3MgYWdhaW4gd2lsbCByZXR1cm4gemVybyByZXN1bHRzXG4gICAgLy8gc2luY2UgYWxsIGNhbGxiYWNrcyBhcmUgbW92ZWQgdG8gXCJ3YWl0aW5nXCIgc3RhdGVcbiAgICBleHBlY3Qoc2FuZGJveC5jYWxsYmFja3MoKS5jYWxsYmFja3MubGVuZ3RoKS50b0JlKDApO1xuXG4gICAgLy8gY2FsbCB0aGUgb3ZlcnJpZGVcbiAgICBsZXQgY2FsbGJhY2tSZXN1bHQ7XG4gICAgbGV0IGNhbGxiYWNrRXJyb3I7XG4gICAgdHJ5IHtcbiAgICAgIGNhbGxiYWNrUmVzdWx0ID0gb3ZlcnJpZGVDYWxsYmFjayhjYi5pbnZva2UhLmFyZ3MhWzBdKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjYWxsYmFja0Vycm9yID0gZS5tZXNzYWdlO1xuICAgIH1cblxuICAgIC8vIGNvbXBsZXRlIHRoZSBjYWxsYmFjayB3aXRoIGEgc3VjY2Vzc2Z1bCByZXR1cm4gdmFsdWUgb2YgNjAwXG4gICAgc2FuZGJveC5jb21wbGV0ZSh7XG4gICAgICBjYmlkOiBjYi5jYmlkLFxuICAgICAgZXJyOiBjYWxsYmFja0Vycm9yLFxuICAgICAgcmVzdWx0OiBjYWxsYmFja1Jlc3VsdCxcbiAgICB9KTtcblxuICAgIC8vIGF3YWl0IGZvciB0aGUgcHJvbWlzZSBhbmQgdmVyaWZ5IHRoYXQgdGhlIGNvbXBsZXRpb24gd2FzIHN1Y2Nlc3NmdWxseVxuICAgIC8vIGNvbnZleWVkIGZyb20gdGhlIGNhbGxiYWNrLlxuICAgIHJldHVybiAoYXdhaXQgc2FuZGJveC5lbmQocHJvbWlzZTIpKS5yZXN1bHQ7XG4gIH1cblxuICBleHBlY3QoYXdhaXQgY2FsbFdpdGhPdmVycmlkZSgoXykgPT4gNjAwKSkudG9CZSg2MDgpO1xuICBleHBlY3QoYXdhaXQgY2FsbFdpdGhPdmVycmlkZSgoeCkgPT4gMiAqIHgpKS50b0JlKDI4KTtcblxuICAvLyBvdmVycmlkZSB0aHJvd3NcbiAgcmV0dXJuIGV4cGVjdChcbiAgICBjYWxsV2l0aE92ZXJyaWRlKChfKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JsYScpO1xuICAgIH0pLFxuICApLnJlamVjdHMudG9UaHJvdygnQmxhJyk7XG59KTtcblxuZGVmaW5lVGVzdChcbiAgJ2FzeW5jIG92ZXJyaWRlczogZGlyZWN0bHkgY2FsbCBhIG1ldGhvZCB3aXRoIGFuIG92ZXJyaWRlIGZyb20gbmF0aXZlIGNvZGUgc2hvdWxkIGludm9rZSB0aGUgXCJzdXBlci5tZXRob2RcIiBzaW5jZSBpdCBjYW4gb25seSBiZSBkb25lIGJ5IHRoZSBkZXJpdmVkIGNsYXNzJyxcbiAgYXN5bmMgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBvYmogPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuQXN5bmNWaXJ0dWFsTWV0aG9kcycsXG4gICAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ292ZXJyaWRlTWUnLCBjb29raWU6ICdteUNvb2tpZScgfV0sXG4gICAgfSk7XG4gICAgY29uc3QgcHJvbWlzZSA9IHNhbmRib3guYmVnaW4oe1xuICAgICAgb2JqcmVmOiBvYmosXG4gICAgICBtZXRob2Q6ICdvdmVycmlkZU1lJyxcbiAgICAgIGFyZ3M6IFsxMl0sXG4gICAgfSk7XG5cbiAgICAvLyBubyBjYWxsYmFja3Mgc2hvdWxkIGJlIHBlbmRpbmcsIHNpbmNlIHRoaXMgc2hvdWxkIGludm9rZSBcInN1cGVyXCJcbiAgICBleHBlY3Qoc2FuZGJveC5jYWxsYmFja3MoKS5jYWxsYmFja3MubGVuZ3RoKS50b0JlKDApO1xuICAgIGV4cGVjdCgoYXdhaXQgc2FuZGJveC5lbmQocHJvbWlzZSkpLnJlc3VsdCkudG9CZSgxNDQpO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdCgnYXN5bmMgb3ZlcnJpZGVzOiB0d28gb3ZlcnJpZGVzJywgYXN5bmMgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5Bc3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICBvdmVycmlkZXM6IFtcbiAgICAgIHsgbWV0aG9kOiAnb3ZlcnJpZGVNZVRvbycsIGNvb2tpZTogJ2Nvb2tpZTEnIH0sXG4gICAgICB7IG1ldGhvZDogJ292ZXJyaWRlTWUnLCBjb29raWU6ICdjb29raWUyJyB9LFxuICAgIF0sXG4gIH0pO1xuXG4gIGNvbnN0IHByb21pc2UgPSBzYW5kYm94LmJlZ2luKHsgb2JqcmVmOiBvYmosIG1ldGhvZDogJ2NhbGxNZScgfSk7XG5cbiAgY29uc3QgY2FsbGJhY2tzMSA9IHNhbmRib3guY2FsbGJhY2tzKCk7XG4gIGV4cGVjdChjYWxsYmFja3MxLmNhbGxiYWNrcy5sZW5ndGgpLnRvQmUoMSk7XG5cbiAgc2FuZGJveC5jb21wbGV0ZSh7IGNiaWQ6IGNhbGxiYWNrczEuY2FsbGJhY2tzWzBdLmNiaWQsIHJlc3VsdDogNjY2IH0pO1xuICBhd2FpdCBwcm9jZXNzUGVuZGluZ1Byb21pc2VzKHNhbmRib3gpOyAvLyBwcm9jZXNzaW5nIG5leHQgcHJvbWlzZVxuXG4gIGNvbnN0IGNhbGxiYWNrczIgPSBzYW5kYm94LmNhbGxiYWNrcygpO1xuICBleHBlY3QoY2FsbGJhY2tzMi5jYWxsYmFja3MubGVuZ3RoKS50b0JlKDEpO1xuXG4gIHNhbmRib3guY29tcGxldGUoeyBjYmlkOiBjYWxsYmFja3MyLmNhbGxiYWNrc1swXS5jYmlkLCByZXN1bHQ6IDEwMSB9KTtcbiAgYXdhaXQgcHJvY2Vzc1BlbmRpbmdQcm9taXNlcyhzYW5kYm94KTtcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBzYW5kYm94LmVuZCh7IHByb21pc2VpZDogcHJvbWlzZS5wcm9taXNlaWQgfSk7XG4gIGV4cGVjdChyZXN1bHQucmVzdWx0KS50b0JlKDc3NSk7XG59KTtcblxuLyoqXG4gKiBUaGlzIHRlc3Qgc2ltdWxhdGVzIGEgc2l0YXRpb24gd2hlcmUgYW4gYXN5bmMgbWV0aG9kIGlzIGNhbGxlZCwgd2hpY2ggaW52b2tlc1xuICogYW4gYXN5bmMgb3ZlcnJpZGUgaW4gcmV0dXJuLCBidXQgdGhlIG92ZXJyaWRlJ3MgcHJvbWlzZSBpcyBub3QgY2FsbGVkIHN5bmNocm9ub3VzbHlcbiAqIGJ1dCByYXRoZXIgd2l0aGluIHRoZSBcIm5leHQgdGlja1wiLiBUaGlzIGNhbiBoYXBwZW4gKGF0IHRoZSBkaXNjcmVzc2lvbiBvZiB0aGUgcnVudGltZVxuICogYW5kIHdlIHNob3VsZCB2ZXJpZnkgdGhhdCB0aGUgQGpzaWkvcnVudGltZSAob3IgYW55IHJ1bnRpbWUgZm9yIHRoYXQgbWF0dGVyKSBcInByb2Nlc3Nlc1wiXG4gKiBwcm9taXNlcyBhZnRlciBhIFwiYmVnaW5cIiBpbnZvY2F0aW9uIGluIG9yZGVyIHRvIG1ha2Ugc3VyZSBhbnkgY2FsbGJhY2tzIGFyZSBxdWV1ZWQuXG4gKlxuICogVGhpcyBpcyBhbHNvIHJlbGV2YW50IGltbWVkaWF0ZSBhZnRlciBhIFwiY29tcGxldGVcIiBpbnZvY2F0aW9uLCB3aGljaCBmdWxmaWxscyBhbiBhc3luY1xuICogcHJvbWlzZSBhbmQgbWF5IHN1YnNlcXVlbnRseSBxdWV1ZSBtb3JlIGNhbGxiYWNrcyBiZWZvcmUgb25lIGNhbiBcImVuZFwiIHRoZSBvcmlnaW5hbFxuICogYXN5bmMgcmVxdWVzdC5cbiAqXG4gKiBZZXMsIHRoaXMgaXMgaGFpcnkuXG4gKlxuICogaG9zdC50cyM5MyBpcyB3aGVyZSB0aGlzIGlzIGltcGxlbWVudGVkIGluIHRoZSBydW50aW1lLlxuICovXG5kZWZpbmVUZXN0KFxuICAnYXN5bmMgb3ZlcnJpZGVzIC0gcHJvY2VzcyBwcm9taXNlcyBhZnRlciBcImJlZ2luXCInLFxuICBhc3luYyAoc2FuZGJveCkgPT4ge1xuICAgIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5Bc3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICAgIG92ZXJyaWRlczogW1xuICAgICAgICB7IG1ldGhvZDogJ292ZXJyaWRlTWUnLCBjb29raWU6ICdjb29raWUyJyB9LFxuICAgICAgICB7IG1ldGhvZDogJ292ZXJyaWRlTWVUb28nIH0sXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcDEgPSBzYW5kYm94LmJlZ2luKHsgb2JqcmVmOiBvYmosIG1ldGhvZDogJ2NhbGxNZURvdWJsZVByb21pc2UnIH0pO1xuXG4gICAgLy8gdGhpcyBpcyBuZWVkZWQgaW4gb3JkZXIgdG8gY3ljbGUgdGhyb3VnaCBhbm90aGVyIGV2ZW50IGxvb3Agc29cbiAgICAvLyB0aGF0IHByb21pc2VzIHRoYXQgYXJlIGxhemlseSBjYWxsZWQgd2lsbCBiZSBwcm9jZXNzZWQgKG5vdGhpbmcgZW5zdXJlc1xuICAgIC8vIHRoYXQgdGhlIHByb21pc2UgY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VzIHN5bmNocm9ub3VzbHkpLlxuICAgIGF3YWl0IHByb2Nlc3NQZW5kaW5nUHJvbWlzZXMoc2FuZGJveCk7XG5cbiAgICBjb25zdCBjYWxsYmFja3MxID0gc2FuZGJveC5jYWxsYmFja3MoKTtcblxuICAgIGV4cGVjdChjYWxsYmFja3MxLmNhbGxiYWNrcy5sZW5ndGgpLnRvQmUoMSk7XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0gc3RhcnQgb2YgXCJvdmVycmlkZVwiIGV4ZWN1dGlvblxuXG4gICAgLy8gd2Ugc2ltdWxhdGUgdGhlIHNpdHVhdGlvbiB3aGVyZSB0aGUgb3ZlcnJpZGUgaW52b2tlcyBhbm90aGVyIGFzeW5jIG92ZXJyaWRlXG5cbiAgICAvLyBjYWxsIGEgc3luYyBtZXRob2QgKGp1c3QgZm9yIGZ1bilcbiAgICBjb25zdCBvdXQgPSBzYW5kYm94Lmludm9rZSh7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdkb250T3ZlcnJpZGVNZScgfSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbCh7IHJlc3VsdDogOCB9KTtcblxuICAgIC8vIGNhbGwgYW5vdGhlciBvdmVycmlkZGVuIGFzeW5jIG1ldGhvZFxuICAgIGNvbnN0IHAyID0gc2FuZGJveC5iZWdpbih7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdjYWxsTWUyJyB9KTtcblxuICAgIC8vIHdlIHNob3VsZCBnZXQgYSBhIGNhbGxiYWNrIHRvIG92ZXJyaWRlTWUyXG4gICAgY29uc3QgY2FsbGJhY2syID0gc2FuZGJveC5jYWxsYmFja3MoKTtcbiAgICBleHBlY3QoY2FsbGJhY2syLmNhbGxiYWNrcy5sZW5ndGgpLnRvQmUoMSk7XG4gICAgZXhwZWN0KGNhbGxiYWNrMi5jYWxsYmFja3NbMF0uaW52b2tlIS5tZXRob2QpLnRvQmUoJ292ZXJyaWRlTWVUb28nKTtcblxuICAgIC8vIGNvbXBsZXRlIHRoZSBpbm5lciBjYWxsYmFja1xuICAgIHNhbmRib3guY29tcGxldGUoeyBjYmlkOiBjYWxsYmFjazIuY2FsbGJhY2tzWzBdLmNiaWQsIHJlc3VsdDogOTk5OSB9KTtcblxuICAgIC8vIGZldGNoIGl0XG4gICAgZXhwZWN0KGF3YWl0IHNhbmRib3guZW5kKHsgcHJvbWlzZWlkOiBwMi5wcm9taXNlaWQgfSkpLnRvRXF1YWwoe1xuICAgICAgcmVzdWx0OiA5OTk5LFxuICAgIH0pO1xuXG4gICAgLy8gbm8gbW9yZSBjYWxsYmFja3NcbiAgICBleHBlY3Qoc2FuZGJveC5jYWxsYmFja3MoKSkudG9FcXVhbCh7IGNhbGxiYWNrczogW10gfSk7XG5cbiAgICAvLyBub3cgY29tcGxldGUgdGhlIG91dGVyIGNhbGxiYWNrXG4gICAgc2FuZGJveC5jb21wbGV0ZSh7IGNiaWQ6IGNhbGxiYWNrczEuY2FsbGJhY2tzWzBdLmNiaWQsIHJlc3VsdDogODg4OCB9KTtcblxuICAgIC8vIHJlcXVpcmVkOiBwcm9jZXNzIHBlbmRpbmcgcHJvbWlzZXMgc28gdGhhdCB3ZSB3aWxsIGdldCB0aGUgbmV4dCBvbmUgaW4gdGhlIGNhbGxiYWNrcyBsaXN0XG4gICAgYXdhaXQgcHJvY2Vzc1BlbmRpbmdQcm9taXNlcyhzYW5kYm94KTtcblxuICAgIC8vIC0tLS0tLSBlbmQgb2YgZXhlY3V0aW9uIG9mIFwib3ZlcnJpZGVNZVwiXG5cbiAgICAvLyBub3cgd2UgZXhwZWN0ICdvdmVycmlkZU1lVG9vJyB0byBiZSBjYWxsZWQgYmFja1xuICAgIGNvbnN0IGNiMyA9IHNhbmRib3guY2FsbGJhY2tzKCk7XG4gICAgZXhwZWN0KGNiMy5jYWxsYmFja3MubGVuZ3RoKS50b0JlKDEpO1xuICAgIGV4cGVjdChjYjMuY2FsbGJhY2tzWzBdLmludm9rZSEubWV0aG9kKS50b0JlKCdvdmVycmlkZU1lVG9vJyk7XG5cbiAgICAvLyBjb21wbGV0ZSBpdFxuICAgIHNhbmRib3guY29tcGxldGUoeyBjYmlkOiBjYjMuY2FsbGJhY2tzWzBdLmNiaWQsIHJlc3VsdDogLTIwIH0pO1xuXG4gICAgLy8gbm8gbW9yZSBjYWxsYmFja3NcbiAgICBjb25zdCBjYjQgPSBzYW5kYm94LmNhbGxiYWNrcygpO1xuICAgIGV4cGVjdChjYjQuY2FsbGJhY2tzLmxlbmd0aCkudG9CZSgwKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNhbmRib3guZW5kKHsgcHJvbWlzZWlkOiBwMS5wcm9taXNlaWQgfSk7XG4gICAgZXhwZWN0KHJlc3VsdC5yZXN1bHQpLnRvQmUoODg3Nik7XG4gIH0sXG4pO1xuXG5mdW5jdGlvbiBwcm9jZXNzUGVuZGluZ1Byb21pc2VzKHNhbmRib3g6IEtlcm5lbCkge1xuICByZXR1cm4gdm0ucnVuSW5Db250ZXh0KFxuICAgICduZXcgUHJvbWlzZShkb25lID0+IHNldEltbWVkaWF0ZShkb25lKSk7JyxcbiAgICAoc2FuZGJveCBhcyBhbnkpLnNhbmRib3gsXG4gICk7XG59XG5cbmRlZmluZVRlc3QoJ3N5bmMgb3ZlcnJpZGVzJywgYXN5bmMgKHNhbmRib3gpID0+IHtcbiAgY29uc3QgcHJlID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyB9KTtcblxuICAvLyB3aXRob3V0IG92ZXJyaWRlXG4gIGV4cGVjdChzYW5kYm94Lmludm9rZSh7IG9ianJlZjogcHJlLCBtZXRob2Q6ICdjYWxsZXJJc01ldGhvZCcgfSkucmVzdWx0KS50b0JlKFxuICAgIDIwLFxuICApO1xuICBleHBlY3Qoc2FuZGJveC5nZXQoeyBvYmpyZWY6IHByZSwgcHJvcGVydHk6ICdjYWxsZXJJc1Byb3BlcnR5JyB9KS52YWx1ZSkudG9CZShcbiAgICAyMCxcbiAgKTtcbiAgY29uc3QgcCA9IHNhbmRib3guYmVnaW4oeyBvYmpyZWY6IHByZSwgbWV0aG9kOiAnY2FsbGVySXNBc3luYycgfSk7XG4gIGV4cGVjdCgoYXdhaXQgc2FuZGJveC5lbmQoeyBwcm9taXNlaWQ6IHAucHJvbWlzZWlkIH0pKS5yZXN1bHQpLnRvQmUoMjApO1xuXG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKGNhbGxiYWNrKSA9PiB7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmNvb2tpZSkudG9CZSgnbXlDb29raWUnKTtcbiAgICBleHBlY3QoY2FsbGJhY2suaW52b2tlIS5vYmpyZWZbVE9LRU5fUkVGXSkudG9NYXRjaChcbiAgICAgIC9qc2lpLWNhbGNcXC5TeW5jVmlydHVhbE1ldGhvZHMvLFxuICAgICk7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmludm9rZSEubWV0aG9kKS50b0JlKCd2aXJ0dWFsTWV0aG9kJyk7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmludm9rZSEuYXJncyFbMF0pLnRvQmUoMTApO1xuXG4gICAgLy8gdG8gbWFrZSB0aGluZ3MgYSBiaXQgbW9yZSBpbnRlcmVzdGluZywgbGV0J3MgaW50ZXJhY3Qgd2l0aCBhIGpzaWkgb2JqZWN0XG4gICAgLy8gZnJvbSB3aXRoaW4gdGhlIGNhbGxiYWNrXG4gICAgY29uc3QgbGhzID0gc2FuZGJveC5jcmVhdGUoe1xuICAgICAgZnFuOiAnQHNjb3BlL2pzaWktY2FsYy1saWIuTnVtYmVyJyxcbiAgICAgIGFyZ3M6IFtjYWxsYmFjay5pbnZva2UhLmFyZ3MhWzBdXSxcbiAgICB9KTtcbiAgICBjb25zdCByaHMgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXInLFxuICAgICAgYXJnczogWzEyXSxcbiAgICB9KTtcbiAgICBjb25zdCBhZGQgPSBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ2pzaWktY2FsYy5BZGQnLCBhcmdzOiBbbGhzLCByaHNdIH0pO1xuICAgIHJldHVybiBzYW5kYm94LmdldCh7IG9ianJlZjogYWRkLCBwcm9wZXJ0eTogJ3ZhbHVlJyB9KS52YWx1ZTtcbiAgfSk7XG5cbiAgLy8gbm93IG1ha2UgdGhlIHNhbWUgc2V0IG9mIGNhbGxzLCBhbmQgeW91IHdpbGwgbm90aWNlIHRoYXQgdGhlIHJlc3VsdHMgYXJlIGFmZmVjdGVkIGJ5IHRoZSBvdmVycmlkZS5cbiAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TeW5jVmlydHVhbE1ldGhvZHMnLFxuICAgIG92ZXJyaWRlczogW3sgbWV0aG9kOiAndmlydHVhbE1ldGhvZCcsIGNvb2tpZTogJ215Q29va2llJyB9XSxcbiAgfSk7XG4gIGV4cGVjdChzYW5kYm94Lmludm9rZSh7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdjYWxsZXJJc01ldGhvZCcgfSkucmVzdWx0KS50b0JlKFxuICAgIDIyLFxuICApO1xuICBleHBlY3Qoc2FuZGJveC5nZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICdjYWxsZXJJc1Byb3BlcnR5JyB9KS52YWx1ZSkudG9CZShcbiAgICAyMixcbiAgKTtcblxuICAvLyB2ZXJpZnkgY2FsbGJhY2tzIGNhbiBhbHNvIGJlIGNhbGxlZCBieSBzZXR0ZXJzLlxuICBsZXQgY2FsbGVkID0gZmFsc2U7XG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKGNhbGxiYWNrKSA9PiB7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmludm9rZSEuYXJncyFbMF0pLnRvQmUoOTk5KTtcbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIHJldHVybiBjYWxsYmFjay5pbnZva2UhLmFyZ3MhWzBdO1xuICB9KTtcblxuICBzYW5kYm94LnNldCh7IG9ianJlZjogb2JqLCBwcm9wZXJ0eTogJ2NhbGxlcklzUHJvcGVydHknLCB2YWx1ZTogOTk5IH0pO1xuICBleHBlY3QoY2FsbGVkKS50b0JlVHJ1dGh5KCk7XG59KTtcblxuZGVmaW5lVGVzdCgnc3luYyBvdmVycmlkZXMgd2l0aCBhc3luYyBjYWxsZXInLCBhc3luYyAoc2FuZGJveCkgPT4ge1xuICBzYW5kYm94LmNhbGxiYWNrSGFuZGxlciA9IG1ha2VTeW5jQ2FsbGJhY2tIYW5kbGVyKChjYWxsYmFjaykgPT4ge1xuICAgIGV4cGVjdChjYWxsYmFjay5jb29raWUpLnRvQmUoJ215Q29va2llJyk7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmludm9rZSEub2JqcmVmW1RPS0VOX1JFRl0pLnRvTWF0Y2goXG4gICAgICAvanNpaS1jYWxjXFwuU3luY1ZpcnR1YWxNZXRob2RzLyxcbiAgICApO1xuICAgIGV4cGVjdChjYWxsYmFjay5pbnZva2UhLm1ldGhvZCkudG9CZSgndmlydHVhbE1ldGhvZCcpO1xuICAgIGV4cGVjdChjYWxsYmFjay5pbnZva2UhLmFyZ3MhWzBdKS50b0JlKDEwKTtcblxuICAgIC8vIHRvIG1ha2UgdGhpbmdzIGEgYml0IG1vcmUgaW50ZXJlc3RpbmcsIGxldCdzIGludGVyYWN0IHdpdGggYSBqc2lpIG9iamVjdFxuICAgIC8vIGZyb20gd2l0aGluIHRoZSBjYWxsYmFja1xuICAgIGNvbnN0IGxocyA9IHNhbmRib3guY3JlYXRlKHtcbiAgICAgIGZxbjogJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlcicsXG4gICAgICBhcmdzOiBbY2FsbGJhY2suaW52b2tlIS5hcmdzIVswXV0sXG4gICAgfSk7XG4gICAgY29uc3QgcmhzID0gc2FuZGJveC5jcmVhdGUoe1xuICAgICAgZnFuOiAnQHNjb3BlL2pzaWktY2FsYy1saWIuTnVtYmVyJyxcbiAgICAgIGFyZ3M6IFsxMl0sXG4gICAgfSk7XG4gICAgY29uc3QgYWRkID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuQWRkJywgYXJnczogW2xocywgcmhzXSB9KTtcbiAgICByZXR1cm4gc2FuZGJveC5nZXQoeyBvYmpyZWY6IGFkZCwgcHJvcGVydHk6ICd2YWx1ZScgfSkudmFsdWU7XG4gIH0pO1xuXG4gIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ3ZpcnR1YWxNZXRob2QnLCBjb29raWU6ICdteUNvb2tpZScgfV0sXG4gIH0pO1xuICBjb25zdCBwMiA9IHNhbmRib3guYmVnaW4oeyBvYmpyZWY6IG9iaiwgbWV0aG9kOiAnY2FsbGVySXNBc3luYycgfSk7XG4gIGV4cGVjdCgoYXdhaXQgc2FuZGJveC5lbmQoeyBwcm9taXNlaWQ6IHAyLnByb21pc2VpZCB9KSkucmVzdWx0KS50b0JlKDIyKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdzeW5jIG92ZXJyaWRlczogcHJvcGVydGllcyAtIHJlYWR3cml0ZScsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICBvdmVycmlkZXM6IFt7IHByb3BlcnR5OiAndGhlUHJvcGVydHknLCBjb29raWU6ICdteUNvb2tpZTEyMzQnIH1dLFxuICB9KTtcblxuICBsZXQgc2V0VmFsdWU7XG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKGNhbGxiYWNrKSA9PiB7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmNvb2tpZSkudG9CZSgnbXlDb29raWUxMjM0Jyk7XG4gICAgaWYgKGNhbGxiYWNrLmdldCkge1xuICAgICAgZXhwZWN0KGNhbGxiYWNrLmdldC5wcm9wZXJ0eSkudG9CZSgndGhlUHJvcGVydHknKTtcbiAgICAgIHJldHVybiAnb3ZlcnJpZGUgYXBwbGllZCc7XG4gICAgfSBlbHNlIGlmIChjYWxsYmFjay5zZXQpIHtcbiAgICAgIGV4cGVjdChjYWxsYmFjay5zZXQucHJvcGVydHkpLnRvQmUoJ3RoZVByb3BlcnR5Jyk7XG4gICAgICBzZXRWYWx1ZSA9IGNhbGxiYWNrLnNldC52YWx1ZTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjYWxsYmFjay4gRXhwZWN0ZWQgZ2V0L3NldCcpO1xuICB9KTtcblxuICBjb25zdCB2YWx1ZSA9IHNhbmRib3guaW52b2tlKHtcbiAgICBvYmpyZWY6IG9iaixcbiAgICBtZXRob2Q6ICdyZXRyaWV2ZVZhbHVlT2ZUaGVQcm9wZXJ0eScsXG4gIH0pO1xuICBleHBlY3QodmFsdWUpLnRvRXF1YWwoeyByZXN1bHQ6ICdvdmVycmlkZSBhcHBsaWVkJyB9KTtcblxuICAvLyBtYWtlIHN1cmUgd2UgY2FuIHN0aWxsIHNldCB0aGUgcHJvcGVydHlcbiAgc2FuZGJveC5pbnZva2Uoe1xuICAgIG9ianJlZjogb2JqLFxuICAgIG1ldGhvZDogJ21vZGlmeVZhbHVlT2ZUaGVQcm9wZXJ0eScsXG4gICAgYXJnczogWycxMjM0J10sXG4gIH0pO1xuICBleHBlY3Qoc2V0VmFsdWUpLnRvQmUoJzEyMzQnKTtcbn0pO1xuXG5kZWZpbmVUZXN0KFxuICAnc3luYyBvdmVycmlkZXM6IHByb3BlcnRpZXMgLSByZWFkd3JpdGUgKGJhY2tlZCBieSBmdW5jdGlvbnMpJyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBvYmogPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICAgIG92ZXJyaWRlczogW3sgcHJvcGVydHk6ICdvdGhlclByb3BlcnR5JywgY29va2llOiAnbXlDb29raWUxMjM0JyB9XSxcbiAgICB9KTtcblxuICAgIGxldCBzZXRWYWx1ZTtcbiAgICBzYW5kYm94LmNhbGxiYWNrSGFuZGxlciA9IG1ha2VTeW5jQ2FsbGJhY2tIYW5kbGVyKChjYWxsYmFjaykgPT4ge1xuICAgICAgZXhwZWN0KGNhbGxiYWNrLmNvb2tpZSkudG9CZSgnbXlDb29raWUxMjM0Jyk7XG4gICAgICBpZiAoY2FsbGJhY2suZ2V0KSB7XG4gICAgICAgIGV4cGVjdChjYWxsYmFjay5nZXQucHJvcGVydHkpLnRvQmUoJ290aGVyUHJvcGVydHknKTtcbiAgICAgICAgcmV0dXJuICdvdmVycmlkZSBhcHBsaWVkIGZvciBvdGhlclByb3BlcnR5JztcbiAgICAgIH0gZWxzZSBpZiAoY2FsbGJhY2suc2V0KSB7XG4gICAgICAgIGV4cGVjdChjYWxsYmFjay5zZXQucHJvcGVydHkpLnRvQmUoJ290aGVyUHJvcGVydHknKTtcbiAgICAgICAgc2V0VmFsdWUgPSBjYWxsYmFjay5zZXQudmFsdWU7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2FsbGJhY2suIEV4cGVjdGVkIGdldC9zZXQnKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHZhbHVlID0gc2FuZGJveC5pbnZva2Uoe1xuICAgICAgb2JqcmVmOiBvYmosXG4gICAgICBtZXRob2Q6ICdyZXRyaWV2ZU90aGVyUHJvcGVydHknLFxuICAgIH0pO1xuICAgIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCh7IHJlc3VsdDogJ292ZXJyaWRlIGFwcGxpZWQgZm9yIG90aGVyUHJvcGVydHknIH0pO1xuXG4gICAgLy8gbWFrZSBzdXJlIHdlIGNhbiBzdGlsbCBzZXQgdGhlIHByb3BlcnR5XG4gICAgc2FuZGJveC5pbnZva2Uoe1xuICAgICAgb2JqcmVmOiBvYmosXG4gICAgICBtZXRob2Q6ICdtb2RpZnlPdGhlclByb3BlcnR5JyxcbiAgICAgIGFyZ3M6IFsnNzc4ODc3J10sXG4gICAgfSk7XG4gICAgZXhwZWN0KHNldFZhbHVlKS50b0JlKCc3Nzg4NzcnKTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoXG4gICdzeW5jIG92ZXJyaWRlczogZHVwbGljYXRlIG92ZXJyaWRlcyBmb3IgdGhlIHNhbWUgcHJvcGVydHknLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PlxuICAgICAgc2FuZGJveC5jcmVhdGUoe1xuICAgICAgICBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICAgICAgb3ZlcnJpZGVzOiBbXG4gICAgICAgICAgeyBwcm9wZXJ0eTogJ290aGVyUHJvcGVydHknLCBjb29raWU6ICdteUNvb2tpZTEyMzQnIH0sXG4gICAgICAgICAgeyBwcm9wZXJ0eTogJ290aGVyUHJvcGVydHknLCBjb29raWU6ICd5b3VyQ29va2llJyB9LFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKS50b1Rocm93KCk7XG4gIH0sXG4pO1xuXG5kZWZpbmVUZXN0KCdzeW5jIG92ZXJyaWRlczogcHJvcGVydGllcyAtIHJlYWRvbmx5JywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TeW5jVmlydHVhbE1ldGhvZHMnLFxuICAgIG92ZXJyaWRlczogW3sgcHJvcGVydHk6ICdyZWFkb25seVByb3BlcnR5JywgY29va2llOiAnbXlDb29raWUxMjM0JyB9XSxcbiAgfSk7XG5cbiAgc2FuZGJveC5jYWxsYmFja0hhbmRsZXIgPSBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcigoY2FsbGJhY2spID0+IHtcbiAgICBleHBlY3QoY2FsbGJhY2suY29va2llKS50b0JlKCdteUNvb2tpZTEyMzQnKTtcbiAgICBleHBlY3QoY2FsbGJhY2suZ2V0KS50b0JlVHJ1dGh5KCk7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmdldCEucHJvcGVydHkpLnRvQmUoJ3JlYWRvbmx5UHJvcGVydHknKTtcbiAgICByZXR1cm4gJ292ZXJyaWRlIGZvciByZWFkb25seSBwcm9wZXJ0eSBhcHBsaWVkJztcbiAgfSk7XG5cbiAgY29uc3QgdmFsdWUgPSBzYW5kYm94Lmludm9rZSh7XG4gICAgb2JqcmVmOiBvYmosXG4gICAgbWV0aG9kOiAncmV0cmlldmVSZWFkT25seVByb3BlcnR5JyxcbiAgfSk7XG4gIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCh7IHJlc3VsdDogJ292ZXJyaWRlIGZvciByZWFkb25seSBwcm9wZXJ0eSBhcHBsaWVkJyB9KTtcblxuICAvLyBjYW4ndCBzZXQgdGhlIHZhbHVlIG9mIGEgcmVhZG9ubHkgcHJvcGVydHksIGRhaCFcbiAgZXhwZWN0KCgpID0+XG4gICAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICdyZWFkb25seVByb3BlcnR5JywgdmFsdWU6IDEyMzQgfSksXG4gICkudG9UaHJvdygpO1xufSk7XG5cbmRlZmluZVRlc3QoJ3N5bmMgb3ZlcnJpZGVzOiBwcm9wZXJ0aWVzIC0gZ2V0IGNhbGxzIHN1cGVyJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TeW5jVmlydHVhbE1ldGhvZHMnLFxuICAgIG92ZXJyaWRlczogW3sgcHJvcGVydHk6ICd0aGVQcm9wZXJ0eScgfV0sXG4gIH0pO1xuXG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKGNhbGxiYWNrKSA9PiB7XG4gICAgZXhwZWN0KGNhbGxiYWNrLmdldCEucHJvcGVydHkpLnRvQmUoJ3RoZVByb3BlcnR5Jyk7XG4gICAgY29uc3Qgc3VwZXJWYWx1ZSA9IHNhbmRib3guZ2V0KHsgb2JqcmVmOiBvYmosIHByb3BlcnR5OiAndGhlUHJvcGVydHknIH0pO1xuICAgIHJldHVybiBgb3ZlcnJpZGUsIHN1cGVyPSR7c3VwZXJWYWx1ZS52YWx1ZX1gO1xuICB9KTtcblxuICBjb25zdCB2YWx1ZSA9IHNhbmRib3guaW52b2tlKHtcbiAgICBvYmpyZWY6IG9iaixcbiAgICBtZXRob2Q6ICdyZXRyaWV2ZVZhbHVlT2ZUaGVQcm9wZXJ0eScsXG4gIH0pO1xuICBleHBlY3QodmFsdWUpLnRvRXF1YWwoeyByZXN1bHQ6ICdvdmVycmlkZSwgc3VwZXI9aW5pdGlhbCB2YWx1ZScgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnc3luYyBvdmVycmlkZXM6IHByb3BlcnRpZXMgLSBzZXQgY2FsbHMgc3VwZXInLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBvYmogPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLlN5bmNWaXJ0dWFsTWV0aG9kcycsXG4gICAgb3ZlcnJpZGVzOiBbeyBwcm9wZXJ0eTogJ3RoZVByb3BlcnR5JyB9XSxcbiAgfSk7XG5cbiAgc2FuZGJveC5jYWxsYmFja0hhbmRsZXIgPSBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcigoY2FsbGJhY2spID0+IHtcbiAgICBpZiAoY2FsbGJhY2suZ2V0KSB7XG4gICAgICByZXR1cm4gc2FuZGJveC5nZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICd0aGVQcm9wZXJ0eScgfSkudmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKGNhbGxiYWNrLnNldCkge1xuICAgICAgcmV0dXJuIHNhbmRib3guc2V0KHtcbiAgICAgICAgb2JqcmVmOiBvYmosXG4gICAgICAgIHByb3BlcnR5OiAndGhlUHJvcGVydHknLFxuICAgICAgICB2YWx1ZTogYHNldCBieSBvdmVycmlkZTogJHtjYWxsYmFjay5zZXQudmFsdWV9YCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBjYWxsYmFjayByZXF1ZXN0OiAke0pTT04uc3RyaW5naWZ5KGNhbGxiYWNrKX1gKTtcbiAgfSk7XG5cbiAgc2FuZGJveC5pbnZva2Uoe1xuICAgIG9ianJlZjogb2JqLFxuICAgIG1ldGhvZDogJ21vZGlmeVZhbHVlT2ZUaGVQcm9wZXJ0eScsXG4gICAgYXJnczogWyduZXdfdmFsdWUnXSxcbiAgfSk7XG4gIGNvbnN0IHZhbHVlID0gc2FuZGJveC5pbnZva2Uoe1xuICAgIG9ianJlZjogb2JqLFxuICAgIG1ldGhvZDogJ3JldHJpZXZlVmFsdWVPZlRoZVByb3BlcnR5JyxcbiAgfSk7XG4gIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCh7IHJlc3VsdDogJ3NldCBieSBvdmVycmlkZTogbmV3X3ZhbHVlJyB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KFxuICAnc3luYyBvdmVycmlkZXM6IHByb3BlcnRpZXMgLSB2ZXJpZnkga2V5cyBhcmUgZW51bWVyYWJsZScsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoe1xuICAgICAgZnFuOiAnT2JqZWN0JyxcbiAgICAgIG92ZXJyaWRlczogW3sgcHJvcGVydHk6ICdmb28nIH0sIHsgcHJvcGVydHk6ICdyZWFkT25seVN0cmluZycgfV0sXG4gICAgfSk7XG4gICAgY29uc3QgcmVhZGVyID0gc2FuZGJveC5jcmVhdGUoe1xuICAgICAgZnFuOiAnanNpaS1jYWxjLlVzZXNJbnRlcmZhY2VXaXRoUHJvcGVydGllcycsXG4gICAgICBhcmdzOiBbb2JqXSxcbiAgICB9KTtcblxuICAgIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKGNhbGxiYWNrKSA9PiB7XG4gICAgICBpZiAoY2FsbGJhY2suZ2V0Py5wcm9wZXJ0eSA9PT0gJ2ZvbycpIHtcbiAgICAgICAgcmV0dXJuIDk5OTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNhbGxiYWNrLmdldD8ucHJvcGVydHkgPT09ICdyZWFkT25seVN0cmluZycpIHtcbiAgICAgICAgcmV0dXJuICdTVFInO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgY2FsbGJhY2snKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHNhbmRib3guaW52b2tlKHtcbiAgICAgIG9ianJlZjogcmVhZGVyLFxuICAgICAgbWV0aG9kOiAncmVhZFN0cmluZ0FuZE51bWJlcicsXG4gICAgICBhcmdzOiBbb2JqXSxcbiAgICB9KTtcbiAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKHtcbiAgICAgIHJlc3VsdDogJ2Jhc2U9U1RSIGNoaWxkPTk5OSBrZXlzPVtmb28scmVhZE9ubHlTdHJpbmddJyxcbiAgICB9KTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoJ3N5bmMgb3ZlcnJpZGVzOiByZXR1cm5zIGFuIG9iamVjdCcsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IHJldHVybnNOdW1iZXIgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnT2JqZWN0JyxcbiAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ29idGFpbk51bWJlcicgfSwgeyBwcm9wZXJ0eTogJ251bWJlclByb3AnIH1dLFxuICB9KTtcblxuICBjb25zdCBvYmogPSBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ2pzaWktY2FsYy5PdmVycmlkZVJldHVybnNPYmplY3QnIH0pO1xuICBjb25zdCBudW1iZXIxMDAgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnQHNjb3BlL2pzaWktY2FsYy1saWIuTnVtYmVyJyxcbiAgICBhcmdzOiBbMTAwXSxcbiAgfSk7XG4gIGNvbnN0IG51bWJlcjUwMCA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXInLFxuICAgIGFyZ3M6IFs1MDBdLFxuICB9KTtcblxuICBzYW5kYm94LmNhbGxiYWNrSGFuZGxlciA9IG1ha2VTeW5jQ2FsbGJhY2tIYW5kbGVyKChjYWxsYmFjaykgPT4ge1xuICAgIGlmIChjYWxsYmFjay5pbnZva2U/Lm1ldGhvZCA9PT0gJ29idGFpbk51bWJlcicpIHtcbiAgICAgIHJldHVybiBudW1iZXIxMDA7XG4gICAgfVxuXG4gICAgaWYgKGNhbGxiYWNrLmdldD8ucHJvcGVydHkgPT09ICdudW1iZXJQcm9wJykge1xuICAgICAgcmV0dXJuIG51bWJlcjUwMDtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgY2FsbGJhY2s6JHtKU09OLnN0cmluZ2lmeShjYWxsYmFjayl9YCk7XG4gIH0pO1xuXG4gIGNvbnN0IHJldCA9IHNhbmRib3guaW52b2tlKHtcbiAgICBvYmpyZWY6IG9iaixcbiAgICBtZXRob2Q6ICd0ZXN0JyxcbiAgICBhcmdzOiBbcmV0dXJuc051bWJlcl0sXG4gIH0pO1xuICBleHBlY3QocmV0KS50b0VxdWFsKHsgcmVzdWx0OiAxMDAgKiAyICsgNTAwICogMiB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdmYWlsIHRvIGJlZ2luIGFzeW5jIGZyb20gc3luYyAtIG1ldGhvZCcsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuU3luY1ZpcnR1YWxNZXRob2RzJyxcbiAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ3ZpcnR1YWxNZXRob2QnLCBjb29raWU6ICdteUNvb2tpZScgfV0sXG4gIH0pO1xuXG4gIGxldCBjYWxsZWQgPSAwO1xuXG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKF8pID0+IHtcbiAgICBjb25zdCBpbm5lck9iaiA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLkFzeW5jVmlydHVhbE1ldGhvZHMnIH0pO1xuICAgIGV4cGVjdCgoKSA9PlxuICAgICAgc2FuZGJveC5iZWdpbih7IG9ianJlZjogaW5uZXJPYmosIG1ldGhvZDogJ2NhbGxNZScgfSksXG4gICAgKS50b1Rocm93KCk7XG4gICAgY2FsbGVkKys7XG5cbiAgICByZXR1cm4gNDI7IC8vIE5lZWQgYSB2YWxpZCByZXR1cm4gdmFsdWVcbiAgfSk7XG5cbiAgc2FuZGJveC5pbnZva2UoeyBvYmpyZWY6IG9iaiwgbWV0aG9kOiAnY2FsbGVySXNNZXRob2QnIH0pO1xuICBleHBlY3QoY2FsbGVkKS50b0JlKDEpO1xuXG4gIHNhbmRib3guZ2V0KHsgb2JqcmVmOiBvYmosIHByb3BlcnR5OiAnY2FsbGVySXNQcm9wZXJ0eScgfSk7XG4gIGV4cGVjdChjYWxsZWQpLnRvQmUoMik7XG5cbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IG9iaiwgcHJvcGVydHk6ICdjYWxsZXJJc1Byb3BlcnR5JywgdmFsdWU6IDMzIH0pO1xuICBleHBlY3QoY2FsbGVkKS50b0JlKDMpO1xufSk7XG5cbmRlZmluZVRlc3QoXG4gICd0aGUgXCJPYmplY3RcIiBGUU4gY2FuIGJlIHVzZWQgdG8gYWxsb3cgY3JlYXRpbmcgZW1wdHkgb2JqZWN0cyB3aXRoIG92ZXJyaWRlcyB3aGljaCBjb21wbHkgd2l0aCBhbiBpbnRlcmZhY2UnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHsgZnFuOiAnanNpaS1jYWxjLlBvbHltb3JwaGlzbScgfSk7XG4gICAgY29uc3QgZnJpZW5kbHkgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdPYmplY3QnLFxuICAgICAgb3ZlcnJpZGVzOiBbeyBtZXRob2Q6ICdoZWxsbycgfV0sXG4gICAgfSk7XG4gICAgc2FuZGJveC5jYWxsYmFja0hhbmRsZXIgPSBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcigoXykgPT4gJ29oLCBoZWxsbycpO1xuICAgIGNvbnN0IHJldCA9IHNhbmRib3guaW52b2tlKHtcbiAgICAgIG9ianJlZjogb2JqLFxuICAgICAgbWV0aG9kOiAnc2F5SGVsbG8nLFxuICAgICAgYXJnczogW2ZyaWVuZGx5XSxcbiAgICB9KTtcbiAgICBleHBlY3QocmV0LnJlc3VsdCkudG9CZSgnb2gsIG9oLCBoZWxsbycpO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ2xpdGVyYWwgb2JqZWN0cyBjYW4gYmUgcmV0dXJuZWQgd2hlbiBhbiBpbnRlcmZhY2UgaXMgZXhwZWN0ZWQsIGFuZCB0aGV5IHdpbGwgYmUgYWRvcm5lZCB3aXRoIGpzaWkgbWV0YWRhdGEgc28gdGhleSBjYW4gYmUgaW50ZXJhY3RlZCB3aXRoJyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBvYmogPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuSlNPYmplY3RMaXRlcmFsRm9ySW50ZXJmYWNlJyxcbiAgICB9KTtcbiAgICBjb25zdCByZXQgPSBzYW5kYm94Lmludm9rZSh7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdnaXZlTWVGcmllbmRseScgfSk7XG5cbiAgICBleHBlY3Qoc2FuZGJveC5pbnZva2UoeyBvYmpyZWY6IHJldC5yZXN1bHQsIG1ldGhvZDogJ2hlbGxvJyB9KSkudG9FcXVhbCh7XG4gICAgICByZXN1bHQ6ICdJIGFtIGxpdGVyYWxseSBmcmllbmRseSEnLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmV0MiA9IHNhbmRib3guaW52b2tlKHtcbiAgICAgIG9ianJlZjogb2JqLFxuICAgICAgbWV0aG9kOiAnZ2l2ZU1lRnJpZW5kbHlHZW5lcmF0b3InLFxuICAgIH0pO1xuICAgIGV4cGVjdChzYW5kYm94Lmludm9rZSh7IG9ianJlZjogcmV0Mi5yZXN1bHQsIG1ldGhvZDogJ2hlbGxvJyB9KSkudG9FcXVhbCh7XG4gICAgICByZXN1bHQ6ICdnaXZlTWVGcmllbmRseUdlbmVyYXRvcicsXG4gICAgfSk7XG4gICAgZXhwZWN0KHNhbmRib3guaW52b2tlKHsgb2JqcmVmOiByZXQyLnJlc3VsdCwgbWV0aG9kOiAnbmV4dCcgfSkpLnRvRXF1YWwoe1xuICAgICAgcmVzdWx0OiA0MixcbiAgICB9KTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoXG4gICdleGNlcHRpb25zIGluY2x1ZGUgYSBzdGFjayB0cmFjZSBpbnRvIHRoZSBvcmlnaW5hbCBzb3VyY2UgY29kZScsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuVGhyb3dlcicgfSk7XG4gICAgZXhwZWN0KCgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNhbmRib3guaW52b2tlKHsgb2JqcmVmOiBvYmosIG1ldGhvZDogJ3Rocm93RXJyb3InIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc3QgcmVnZXhwID1cbiAgICAgICAgICAvXlxccyphdCBUaHJvd2VyXFwuZG9UaHJvd0Vycm9yIFxcKC4qanNpaVstX11jYWxjLipcXC9saWJcXC9jb21wbGlhbmNlXFwudHM6XFxkKzpcXGQrXFwpJC9tO1xuICAgICAgICBleHBlY3QocmVnZXhwLnRlc3QoZXJyb3Iuc3RhY2spKS50b0JlVHJ1dGh5KCk7IC8vIFRoZSBzdGFjayB0cmFjZSBpbmNsdWRlcyB0aGUgcGF0aCB0byB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGVcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSkudG9UaHJvdygpO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdCgndmFyaWFkaWMgbWV0aG9kcyBjYW4gYmUgY2FsbGVkJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuVmFyaWFkaWNNZXRob2QnIH0pO1xuICBleHBlY3QoXG4gICAgc2FuZGJveC5pbnZva2UoeyBvYmpyZWY6IG9iaiwgbWV0aG9kOiAnYXNBcnJheScsIGFyZ3M6IFsxLCAyLCAzLCA0XSB9KVxuICAgICAgLnJlc3VsdCxcbiAgKS50b0VxdWFsKFsxLCAyLCAzLCA0XSk7XG59KTtcblxuZGVmaW5lVGVzdCgndmFyaWFkaWMgbWV0aG9kcyBjYW4gYmUgY2FsbGVkIHdpdGhvdXQgYW55IHZhcmFyZycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9iaiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuVmFyaWFkaWNNZXRob2QnLFxuICAgIGFyZ3M6IFsxLCAyLCAzXSxcbiAgfSk7XG4gIGV4cGVjdChcbiAgICBzYW5kYm94Lmludm9rZSh7IG9ianJlZjogb2JqLCBtZXRob2Q6ICdhc0FycmF5JywgYXJnczogWzRdIH0pLnJlc3VsdCxcbiAgKS50b0VxdWFsKFsxLCAyLCAzLCA0XSk7XG59KTtcblxuZGVmaW5lVGVzdCgnc3RhdGljIHByb3BlcnRpZXMgLSBnZXQnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCB2YWx1ZSA9IHNhbmRib3guc2dldCh7IGZxbjogJ2pzaWktY2FsYy5TdGF0aWNzJywgcHJvcGVydHk6ICdGb28nIH0pO1xuICBleHBlY3QodmFsdWUpLnRvRXF1YWwoeyB2YWx1ZTogJ2hlbGxvJyB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdmYWlsczogc3RhdGljIHByb3BlcnRpZXMgLSBzZXQgcmVhZG9ubHknLCAoc2FuZGJveCkgPT4ge1xuICBleHBlY3QoKCkgPT5cbiAgICBzYW5kYm94LnNzZXQoeyBmcW46ICdqc2lpLWNhbGMuU3RhdGljcycsIHByb3BlcnR5OiAnRm9vJywgdmFsdWU6IDEyMyB9KSxcbiAgKS50b1Rocm93KCk7XG59KTtcblxuZGVmaW5lVGVzdCgnc3RhdGljIHByb3BlcnRpZXMgLSBzZXQnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBkZWZhdWx0SW5zdGFuY2UgPSBzYW5kYm94LnNnZXQoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TdGF0aWNzJyxcbiAgICBwcm9wZXJ0eTogJ2luc3RhbmNlJyxcbiAgfSk7XG4gIGV4cGVjdChcbiAgICBzYW5kYm94LmdldCh7IG9ianJlZjogZGVmYXVsdEluc3RhbmNlLnZhbHVlLCBwcm9wZXJ0eTogJ3ZhbHVlJyB9KSxcbiAgKS50b0VxdWFsKHsgdmFsdWU6ICdkZWZhdWx0JyB9KTtcblxuICBjb25zdCBvYmogPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLlN0YXRpY3MnLFxuICAgIGFyZ3M6IFsnTXlJbnN0YW5jZSddLFxuICB9KTtcbiAgc2FuZGJveC5zc2V0KHsgZnFuOiAnanNpaS1jYWxjLlN0YXRpY3MnLCBwcm9wZXJ0eTogJ2luc3RhbmNlJywgdmFsdWU6IG9iaiB9KTtcblxuICBjb25zdCB1cGRhdGVkSW5zdGFuY2UgPSBzYW5kYm94LnNnZXQoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TdGF0aWNzJyxcbiAgICBwcm9wZXJ0eTogJ2luc3RhbmNlJyxcbiAgfSk7XG4gIGV4cGVjdChcbiAgICBzYW5kYm94LmdldCh7IG9ianJlZjogdXBkYXRlZEluc3RhbmNlLnZhbHVlLCBwcm9wZXJ0eTogJ3ZhbHVlJyB9KSxcbiAgKS50b0VxdWFsKHsgdmFsdWU6ICdNeUluc3RhbmNlJyB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdmYWlsczogc3RhdGljIHByb3BlcnRpZXMgLSBnZXQvc2V0IG5vbi1zdGF0aWMnLCAoc2FuZGJveCkgPT4ge1xuICBleHBlY3QoKCkgPT5cbiAgICBzYW5kYm94LnNnZXQoeyBmcW46ICdqc2lpLWNhbGMuU3RhdGljcycsIHByb3BlcnR5OiAndmFsdWUnIH0pLFxuICApLnRvVGhyb3coL2lzIG5vdCBzdGF0aWMvKTtcbiAgZXhwZWN0KCgpID0+XG4gICAgc2FuZGJveC5zc2V0KHsgZnFuOiAnanNpaS1jYWxjLlN0YXRpY3MnLCBwcm9wZXJ0eTogJ3ZhbHVlJywgdmFsdWU6IDEyMyB9KSxcbiAgKS50b1Rocm93KC9pcyBub3Qgc3RhdGljLyk7XG59KTtcblxuZGVmaW5lVGVzdCgnZmFpbHM6IHN0YXRpYyBwcm9wZXJ0aWVzIC0gZ2V0L3NldCBub3QgZm91bmQnLCAoc2FuZGJveCkgPT4ge1xuICBleHBlY3QoKCkgPT5cbiAgICBzYW5kYm94LnNnZXQoeyBmcW46ICdqc2lpLWNhbGMuU3RhdGljcycsIHByb3BlcnR5OiAnem9vJyB9KSxcbiAgKS50b1Rocm93KC9kb2Vzbid0IGhhdmUgYSBwcm9wZXJ0eS8pO1xuICBleHBlY3QoKCkgPT5cbiAgICBzYW5kYm94LnNzZXQoeyBmcW46ICdqc2lpLWNhbGMuU3RhdGljcycsIHByb3BlcnR5OiAnYmFyJywgdmFsdWU6IDEyMyB9KSxcbiAgKS50b1Rocm93KC9kb2Vzbid0IGhhdmUgYSBwcm9wZXJ0eS8pO1xufSk7XG5cbmRlZmluZVRlc3QoJ3N0YXRpYyBtZXRob2RzJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3QgcmVzdWx0ID0gc2FuZGJveC5zaW52b2tlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuU3RhdGljcycsXG4gICAgbWV0aG9kOiAnc3RhdGljTWV0aG9kJyxcbiAgICBhcmdzOiBbJ0pzaWknXSxcbiAgfSk7XG4gIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoeyByZXN1bHQ6ICdoZWxsbyAsSnNpaSEnIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ2ZhaWxzOiBzdGF0aWMgbWV0aG9kcyAtIG5vdCBmb3VuZCcsIChzYW5kYm94KSA9PiB7XG4gIGV4cGVjdCgoKSA9PlxuICAgIHNhbmRib3guc2ludm9rZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuU3RhdGljcycsXG4gICAgICBtZXRob2Q6ICdzdGF0aWNNZXRob2ROb3RGb3VuZCcsXG4gICAgICBhcmdzOiBbJ0pzaWknXSxcbiAgICB9KSxcbiAgKS50b1Rocm93KC9kb2Vzbid0IGhhdmUgYSBtZXRob2QvKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdmYWlsczogc3RhdGljIG1ldGhvZHMgLSBub3Qgc3RhdGljJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KCgpID0+XG4gICAgc2FuZGJveC5zaW52b2tlKHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5TdGF0aWNzJyxcbiAgICAgIG1ldGhvZDogJ2p1c3RNZXRob2QnLFxuICAgICAgYXJnczogWydKc2lpJ10sXG4gICAgfSksXG4gICkudG9UaHJvdygvaXMgbm90IGEgc3RhdGljIG1ldGhvZC8pO1xufSk7XG5cbmRlZmluZVRlc3QoJ2xvYWRpbmcgYSBtb2R1bGUgdHdpY2UgaWRlcG90ZW50bHkgc3VjY2VlZHMnLCBhc3luYyAoc2FuZGJveCkgPT4ge1xuICBzYW5kYm94LmxvYWQoe1xuICAgIHRhcmJhbGw6IGF3YWl0IHByZXBhcmVQYWNrYWdlKCdqc2lpLWNhbGMnLCBmYWxzZSksXG4gICAgbmFtZTogJ2pzaWktY2FsYycsXG4gICAgdmVyc2lvbjogY2FsY1ZlcnNpb24sXG4gIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoXG4gICdmYWlscyBpZiB0cnlpbmcgdG8gbG9hZCB0d28gZGlmZmVyZW50IHZlcnNpb25zIG9mIHRoZSBzYW1lIG1vZHVsZScsXG4gIGFzeW5jIChzYW5kYm94KSA9PiB7XG4gICAgY29uc3QgdGFyYmFsbCA9IGF3YWl0IHByZXBhcmVQYWNrYWdlKCdqc2lpLWNhbGMnLCBmYWxzZSk7XG4gICAgcmV0dXJuIGV4cGVjdCgoKSA9PlxuICAgICAgc2FuZGJveC5sb2FkKHsgdGFyYmFsbCwgbmFtZTogJ2pzaWktY2FsYycsIHZlcnNpb246ICc5OS45OTkuOScgfSksXG4gICAgKS50b1Rocm93KFxuICAgICAgL011bHRpcGxlIHZlcnNpb25zIC4rIGFuZCAuKyBvZiB0aGUgcGFja2FnZSAnanNpaS1jYWxjJyBjYW5ub3QgYmUgbG9hZGVkIHRvZ2V0aGVyLyxcbiAgICApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdCgnbm9kZS5qcyBzdGFuZGFyZCBsaWJyYXJ5JywgYXN5bmMgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqcmVmID0gc2FuZGJveC5jcmVhdGUoeyBmcW46ICdqc2lpLWNhbGMuTm9kZVN0YW5kYXJkTGlicmFyeScgfSk7XG4gIGNvbnN0IHByb21pc2UgPSBzYW5kYm94LmJlZ2luKHsgb2JqcmVmLCBtZXRob2Q6ICdmc1JlYWRGaWxlJyB9KTtcbiAgYXdhaXQgcHJvY2Vzc1BlbmRpbmdQcm9taXNlcyhzYW5kYm94KTtcblxuICBjb25zdCBvdXRwdXQgPSBhd2FpdCBzYW5kYm94LmVuZCh7IHByb21pc2VpZDogcHJvbWlzZS5wcm9taXNlaWQgfSk7XG4gIGV4cGVjdChvdXRwdXQpLnRvRXF1YWwoeyByZXN1bHQ6ICdIZWxsbywgcmVzb3VyY2UhJyB9KTtcbiAgZXhwZWN0KHNhbmRib3guaW52b2tlKHsgb2JqcmVmLCBtZXRob2Q6ICdmc1JlYWRGaWxlU3luYycgfSkpLnRvRXF1YWwoe1xuICAgIHJlc3VsdDogJ0hlbGxvLCByZXNvdXJjZSEgU1lOQyEnLFxuICB9KTtcblxuICBjb25zdCBwbGF0Zm9ybSA9IHNhbmRib3guZ2V0KHsgb2JqcmVmLCBwcm9wZXJ0eTogJ29zUGxhdGZvcm0nIH0pLnZhbHVlO1xuICBleHBlY3QocGxhdGZvcm0/Lmxlbmd0aCkudG9CZUdyZWF0ZXJUaGFuKDApO1xuXG4gIGV4cGVjdChzYW5kYm94Lmludm9rZSh7IG9ianJlZiwgbWV0aG9kOiAnY3J5cHRvU2hhMjU2JyB9KSkudG9FcXVhbCh7XG4gICAgcmVzdWx0OiAnNmEyZGEyMDk0MzkzMWU5ODM0ZmMxMmNmZTViYjQ3YmJkOWFlNDM0ODlhMzA3MjY5NjJiNTc2ZjRlMzk5M2U1MCcsXG4gIH0pO1xufSk7XG5cbi8vIEBzZWUgYXdzbGFicy9qc2lpIzI0OFxuZGVmaW5lVGVzdCgnb2JqZWN0IGxpdGVyYWxzIGFyZSByZXR1cm5lZCBieSByZWZlcmVuY2UnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLkNsYXNzV2l0aE11dGFibGVPYmplY3RMaXRlcmFsUHJvcGVydHknLFxuICB9KTtcbiAgY29uc3QgcHJvcGVydHkgPSBzYW5kYm94LmdldCh7IG9ianJlZiwgcHJvcGVydHk6ICdtdXRhYmxlT2JqZWN0JyB9KS52YWx1ZTtcblxuICBjb25zdCBuZXdWYWx1ZSA9ICdCYXppbmdhITEhJztcbiAgc2FuZGJveC5zZXQoeyBvYmpyZWY6IHByb3BlcnR5LCBwcm9wZXJ0eTogJ3ZhbHVlJywgdmFsdWU6IG5ld1ZhbHVlIH0pO1xuXG4gIGV4cGVjdChcbiAgICBzYW5kYm94LmdldCh7XG4gICAgICBvYmpyZWY6IHNhbmRib3guZ2V0KHsgb2JqcmVmLCBwcm9wZXJ0eTogJ211dGFibGVPYmplY3QnIH0pLnZhbHVlLFxuICAgICAgcHJvcGVydHk6ICd2YWx1ZScsXG4gICAgfSkudmFsdWUsXG4gICkudG9FcXVhbChuZXdWYWx1ZSk7XG5cbiAgc2FuZGJveC5kZWwoeyBvYmpyZWY6IHByb3BlcnR5IH0pO1xufSk7XG5cbmRlZmluZVRlc3QoXG4gICdvdmVycmlkZXM6IG1ldGhvZCBpbnN0ZWFkIG9mIHByb3BlcnR5IHdpdGggdGhlIHNhbWUgbmFtZScsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IHtcbiAgICAgIHNhbmRib3guY3JlYXRlKHtcbiAgICAgICAgZnFuOiAnanNpaS1jYWxjLlN5bmNWaXJ0dWFsTWV0aG9kcycsXG4gICAgICAgIG92ZXJyaWRlczogW3sgbWV0aG9kOiAndGhlUHJvcGVydHknIH1dLFxuICAgICAgfSk7XG4gICAgfSkudG9UaHJvdygvVHJ5aW5nIHRvIG92ZXJyaWRlIHByb3BlcnR5Lyk7XG4gIH0sXG4pO1xuXG5kZWZpbmVUZXN0KFxuICAnb3ZlcnJpZGVzOiBwcm9wZXJ0eSBpbnN0ZWFkIG9mIG1ldGhvZCB3aXRoIHRoZSBzYW1lIG5hbWUnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICAgIGZxbjogJ2pzaWktY2FsYy5TeW5jVmlydHVhbE1ldGhvZHMnLFxuICAgICAgICBvdmVycmlkZXM6IFt7IHByb3BlcnR5OiAndmlydHVhbE1ldGhvZCcgfV0sXG4gICAgICB9KTtcbiAgICB9KS50b1Rocm93KC9UcnlpbmcgdG8gb3ZlcnJpZGUgbWV0aG9kLyk7XG4gIH0sXG4pO1xuXG5kZWZpbmVUZXN0KCdvdmVycmlkZXM6IHNraXAgb3ZlcnJpZGVzIG9mIHByaXZhdGUgbWV0aG9kcycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9ianJlZiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuRG9Ob3RPdmVycmlkZVByaXZhdGVzJyxcbiAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ3ByaXZhdGVNZXRob2QnIH1dLFxuICB9KTtcblxuICBzYW5kYm94LmNhbGxiYWNrSGFuZGxlciA9IG1ha2VTeW5jQ2FsbGJhY2tIYW5kbGVyKChfKSA9PiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdvdmVycmlkZSBjYWxsYmFjayBzaG91bGQgbm90IGJlIGNhbGxlZCcpO1xuICB9KTtcblxuICBjb25zdCByZXN1bHQgPSBzYW5kYm94Lmludm9rZSh7IG9ianJlZiwgbWV0aG9kOiAncHJpdmF0ZU1ldGhvZFZhbHVlJyB9KTtcbiAgZXhwZWN0KHJlc3VsdC5yZXN1bHQpLnRvQmUoJ3ByaXZhdGVNZXRob2QnKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdvdmVycmlkZXM6IHNraXAgb3ZlcnJpZGVzIG9mIHByaXZhdGUgcHJvcGVydGllcycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9ianJlZiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuRG9Ob3RPdmVycmlkZVByaXZhdGVzJyxcbiAgICBvdmVycmlkZXM6IFt7IHByb3BlcnR5OiAncHJpdmF0ZVByb3BlcnR5JyB9XSxcbiAgfSk7XG5cbiAgc2FuZGJveC5jYWxsYmFja0hhbmRsZXIgPSBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcigoXykgPT4ge1xuICAgIHRocm93IG5ldyBFcnJvcignb3ZlcnJpZGUgY2FsbGJhY2sgc2hvdWxkIG5vdCBiZSBjYWxsZWQnKTtcbiAgfSk7XG5cbiAgY29uc3QgcmVzdWx0ID0gc2FuZGJveC5pbnZva2UoeyBvYmpyZWYsIG1ldGhvZDogJ3ByaXZhdGVQcm9wZXJ0eVZhbHVlJyB9KTtcbiAgZXhwZWN0KHJlc3VsdC5yZXN1bHQpLnRvQmUoJ3ByaXZhdGVQcm9wZXJ0eScpO1xufSk7XG5cbmRlZmluZVRlc3QoJ251bGxzIGFyZSBjb252ZXJ0ZWQgdG8gdW5kZWZpbmVkIC0gY3RvcicsIChzYW5kYm94KSA9PiB7XG4gIHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuTnVsbFNob3VsZEJlVHJlYXRlZEFzVW5kZWZpbmVkJyxcbiAgICBhcmdzOiBbJ2ZvbycsIG51bGxdLFxuICB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdudWxscyBhcmUgY29udmVydGVkIHRvIHVuZGVmaW5lZCAtIG1ldGhvZCBhcmd1bWVudHMnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLk51bGxTaG91bGRCZVRyZWF0ZWRBc1VuZGVmaW5lZCcsXG4gICAgYXJnczogWydmb28nXSxcbiAgfSk7XG4gIHNhbmRib3guaW52b2tlKHsgb2JqcmVmLCBtZXRob2Q6ICdnaXZlTWVVbmRlZmluZWQnLCBhcmdzOiBbbnVsbF0gfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnbnVsbHMgYXJlIGNvbnZlcnRlZCB0byB1bmRlZmluZWQgLSBpbnNpZGUgb2JqZWN0cycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IG9ianJlZiA9IHNhbmRib3guY3JlYXRlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuTnVsbFNob3VsZEJlVHJlYXRlZEFzVW5kZWZpbmVkJyxcbiAgICBhcmdzOiBbJ2ZvbyddLFxuICB9KTtcbiAgc2FuZGJveC5pbnZva2Uoe1xuICAgIG9ianJlZixcbiAgICBtZXRob2Q6ICdnaXZlTWVVbmRlZmluZWRJbnNpZGVBbk9iamVjdCcsXG4gICAgYXJnczogW1xuICAgICAge1xuICAgICAgICB0aGlzU2hvdWxkQmVVbmRlZmluZWQ6IG51bGwsXG4gICAgICAgIGFycmF5V2l0aFRocmVlRWxlbWVudHNBbmRVbmRlZmluZWRBc1NlY29uZEFyZ3VtZW50OiBbXG4gICAgICAgICAgJ29uZScsXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICAndHdvJyxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnbnVsbHMgYXJlIGNvbnZlcnRlZCB0byB1bmRlZmluZWQgLSBwcm9wZXJ0aWVzJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqcmVmID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5OdWxsU2hvdWxkQmVUcmVhdGVkQXNVbmRlZmluZWQnLFxuICAgIGFyZ3M6IFsnZm9vJ10sXG4gIH0pO1xuICBzYW5kYm94LnNldCh7IG9ianJlZiwgcHJvcGVydHk6ICdjaGFuZ2VNZVRvVW5kZWZpbmVkJywgdmFsdWU6IG51bGwgfSk7XG4gIHNhbmRib3guaW52b2tlKHsgb2JqcmVmLCBtZXRob2Q6ICd2ZXJpZnlQcm9wZXJ0eUlzVW5kZWZpbmVkJyB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdKU0lJX0FHRU5UIGlzIHVuZGVmaW5lZCBpbiBub2RlLmpzJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KFxuICAgIHNhbmRib3guc2dldCh7IGZxbjogJ2pzaWktY2FsYy5Kc2lpQWdlbnQnLCBwcm9wZXJ0eTogJ3ZhbHVlJyB9KS52YWx1ZSxcbiAgKS50b0JlKHVuZGVmaW5lZCk7XG59KTtcblxuZGVmaW5lVGVzdCgnT2JqUmVmcyBhcmUgbGFiZWxlZCB3aXRoIHRoZSBcIm1vc3QgY29ycmVjdFwiIHR5cGUnLCAoc2FuZGJveCkgPT4ge1xuICB0eXBlTWF0Y2hlcygnbWFrZUNsYXNzJywgeyBbVE9LRU5fUkVGXTogL15qc2lpLWNhbGMuSW5iZXR3ZWVuQ2xhc3NALyB9KTtcbiAgdHlwZU1hdGNoZXMoJ21ha2VJbnRlcmZhY2UnLCB7XG4gICAgW1RPS0VOX1JFRl06IC9eanNpaS1jYWxjLkluYmV0d2VlbkNsYXNzQC8sXG4gICAgW1RPS0VOX0lOVEVSRkFDRVNdOiBbJ2pzaWktY2FsYy5JUHVibGljSW50ZXJmYWNlJ10sXG4gIH0pO1xuICB0eXBlTWF0Y2hlcygnbWFrZUludGVyZmFjZTInLCB7IFtUT0tFTl9SRUZdOiAvXmpzaWktY2FsYy5JbmJldHdlZW5DbGFzc0AvIH0pO1xuICB0eXBlTWF0Y2hlcygnbWFrZUludGVyZmFjZXMnLCBbXG4gICAge1xuICAgICAgW1RPS0VOX1JFRl06IC9eanNpaS1jYWxjLkluYmV0d2VlbkNsYXNzQC8sXG4gICAgICBbVE9LRU5fSU5URVJGQUNFU106IFsnanNpaS1jYWxjLklQdWJsaWNJbnRlcmZhY2UnXSxcbiAgICB9LFxuICBdKTtcbiAgdHlwZU1hdGNoZXMoJ2hpZGRlbkludGVyZmFjZScsIHtcbiAgICBbVE9LRU5fUkVGXTogL15PYmplY3RALyxcbiAgICBbVE9LRU5fSU5URVJGQUNFU106IFsnanNpaS1jYWxjLklQdWJsaWNJbnRlcmZhY2UnXSxcbiAgfSk7XG4gIHR5cGVNYXRjaGVzKCdoaWRkZW5JbnRlcmZhY2VzJywgW1xuICAgIHtcbiAgICAgIFtUT0tFTl9SRUZdOiAvXk9iamVjdEAvLFxuICAgICAgW1RPS0VOX0lOVEVSRkFDRVNdOiBbJ2pzaWktY2FsYy5JUHVibGljSW50ZXJmYWNlJ10sXG4gICAgfSxcbiAgXSk7XG4gIHR5cGVNYXRjaGVzKCdoaWRkZW5TdWJJbnRlcmZhY2VzJywgW1xuICAgIHtcbiAgICAgIFtUT0tFTl9SRUZdOiAvXk9iamVjdEAvLFxuICAgICAgW1RPS0VOX0lOVEVSRkFDRVNdOiBbJ2pzaWktY2FsYy5JUHVibGljSW50ZXJmYWNlJ10sXG4gICAgfSxcbiAgXSk7XG5cbiAgZnVuY3Rpb24gdHlwZU1hdGNoZXMoc3RhdGljTWV0aG9kOiBzdHJpbmcsIHR5cGVTcGVjOiBhbnkpIHtcbiAgICBjb25zdCByZXQgPSBzYW5kYm94LnNpbnZva2Uoe1xuICAgICAgZnFuOiAnanNpaS1jYWxjLkNvbnN0cnVjdG9ycycsXG4gICAgICBtZXRob2Q6IHN0YXRpY01ldGhvZCxcbiAgICB9KS5yZXN1bHQgYXMgYXBpLk9ialJlZjtcblxuICAgIGlmICghZGVlcEVxdWFsV2l0aFJlZ2V4KHJldCwgdHlwZVNwZWMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb25zdHJ1Y3RvcnMuJHtzdGF0aWNNZXRob2R9KCkgPT4gJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICByZXQsXG4gICAgICAgICl9LCBkb2VzIG5vdCBtYXRjaCAke0pTT04uc3RyaW5naWZ5KHR5cGVTcGVjKX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vKipcbiAqIFRoaXMgaXMgdXNlZCB0byB2YWxpZGF0ZSB0aGUgYWJpbGl0eSB0byB1c2UgYHRoaXNgIGZyb20gd2l0aGluIGEgc3RhdGljIGNvbnRleHQuXG4gKlxuICogaHR0cHM6Ly9naXRodWIuY29tL2F3c2xhYnMvYXdzLWNkay9pc3N1ZXMvMjMwNFxuICovXG5kZWZpbmVUZXN0KCdzaW52b2tlIGFsbG93cyBhY2Nlc3MgdG8gdGhlIHN0YXRpYyBjb250ZXh0JywgKHNhbmRib3gpID0+IHtcbiAgY29uc3QgcmVzcG9uc2UgPSBzYW5kYm94LnNpbnZva2Uoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TdGF0aWNDb250ZXh0JyxcbiAgICBtZXRob2Q6ICdjYW5BY2Nlc3NTdGF0aWNDb250ZXh0JyxcbiAgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5yZXN1bHQpLnRvQmUodHJ1ZSk7XG59KTtcbmRlZmluZVRlc3QoJ3NnZXQgYWxsb3dzIGFjY2VzcyB0byB0aGUgc3RhdGljIGNvbnRleHQnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCByZXNwb25zZSA9IHNhbmRib3guc2dldCh7XG4gICAgZnFuOiAnanNpaS1jYWxjLlN0YXRpY0NvbnRleHQnLFxuICAgIHByb3BlcnR5OiAnc3RhdGljVmFyaWFibGUnLFxuICB9KTtcbiAgZXhwZWN0KHJlc3BvbnNlLnZhbHVlKS50b0JlKHRydWUpO1xufSk7XG5kZWZpbmVUZXN0KCdzc2V0IGFsbG93cyBhY2Nlc3MgdG8gdGhlIHN0YXRpYyBjb250ZXh0JywgKHNhbmRib3gpID0+IHtcbiAgc2FuZGJveC5zc2V0KHtcbiAgICBmcW46ICdqc2lpLWNhbGMuU3RhdGljQ29udGV4dCcsXG4gICAgcHJvcGVydHk6ICdzdGF0aWNWYXJpYWJsZScsXG4gICAgdmFsdWU6IGZhbHNlLFxuICB9KTtcbiAgY29uc3QgcmVzcG9uc2UgPSBzYW5kYm94LnNnZXQoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5TdGF0aWNDb250ZXh0JyxcbiAgICBwcm9wZXJ0eTogJ3N0YXRpY1ZhcmlhYmxlJyxcbiAgfSk7XG4gIGV4cGVjdChyZXNwb25zZS52YWx1ZSkudG9CZShmYWxzZSk7XG59KTtcblxuLypcblxuVGVzdCBjdXJyZW50bHkgZGlzYWJsZWQgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIHRoZSBpbmZyYXN0cnVjdHVyZSB0byBtYWtlIGl0IHBhc3MuXG5odHRwczovL2dpdGh1Yi5jb20vYXdzL2pzaWkvaXNzdWVzLzM5OVxuXG5kZWZpbmVUZXN0KCdBIHNpbmdsZSBpbnN0YW5jZSBjYW4gYmUgcmV0dXJuZWQgdW5kZXIgdHdvIHR5cGVzJywgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBzaW5nbGVJbnN0YW5jZVR3b1R5cGVzID0gY3JlYXRlKHNhbmRib3gsICdqc2lpLWNhbGMuU2luZ2xlSW5zdGFuY2VUd29UeXBlcycpKCk7XG5cbiAgICB0eXBlTWF0Y2hlcygnaW50ZXJmYWNlMScsIHsgW1RPS0VOX1JFRl06IC9eanNpaS1jYWxjLkluYmV0d2VlbkNsYXNzQC8gfSk7XG4gICAgdHlwZU1hdGNoZXMoJ2ludGVyZmFjZTInLCB7IFtUT0tFTl9SRUZdOiAvXmpzaWktY2FsYy5JUHVibGljSW50ZXJmYWNlQC8gfSk7XG5cbiAgICBmdW5jdGlvbiB0eXBlTWF0Y2hlcyhtZXRob2Q6IHN0cmluZywgdHlwZVNwZWM6IGFueSkge1xuICAgICAgICBjb25zdCByZXQgPSBzYW5kYm94Lmludm9rZSh7IG9ianJlZjogc2luZ2xlSW5zdGFuY2VUd29UeXBlcywgbWV0aG9kIH0pLnJlc3VsdCBhcyBhcGkuT2JqUmVmO1xuXG4gICAgICAgIHRlc3Qub2soZGVlcEVxdWFsV2l0aFJlZ2V4KHJldCwgdHlwZVNwZWMpLCBgQ29uc3RydWN0b3JzLiR7bWV0aG9kfSgpID0+ICR7SlNPTi5zdHJpbmdpZnkocmV0KX0sIGRvZXMgbm90IG1hdGNoICR7SlNPTi5zdHJpbmdpZnkodHlwZVNwZWMpfWApO1xuICAgIH1cbn0pO1xuXG4qL1xuXG5kZWZpbmVUZXN0KFxuICAndG9TYW5kYm94OiBcIm51bGxcIiBpbiBoYXNoIHZhbHVlcyBzZW5kIHRvIEpTIHNob3VsZCBiZSB0cmVhdGVkIGFzIG5vbi1leGlzdGluZyBrZXknLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0geyBvcHRpb24xOiBudWxsLCBvcHRpb24yOiAnaGVsbG8nIH07XG4gICAgY29uc3Qgb3B0aW9uMUV4aXN0cyA9IHNhbmRib3guc2ludm9rZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuRXJhc2VVbmRlZmluZWRIYXNoVmFsdWVzJyxcbiAgICAgIG1ldGhvZDogJ2RvZXNLZXlFeGlzdCcsXG4gICAgICBhcmdzOiBbaW5wdXQsICdvcHRpb24xJ10sXG4gICAgfSk7XG4gICAgZXhwZWN0KG9wdGlvbjFFeGlzdHMucmVzdWx0KS50b0JlKGZhbHNlKTtcblxuICAgIGNvbnN0IG9wdGlvbjJFeGlzdHMgPSBzYW5kYm94LnNpbnZva2Uoe1xuICAgICAgZnFuOiAnanNpaS1jYWxjLkVyYXNlVW5kZWZpbmVkSGFzaFZhbHVlcycsXG4gICAgICBtZXRob2Q6ICdkb2VzS2V5RXhpc3QnLFxuICAgICAgYXJnczogW2lucHV0LCAnb3B0aW9uMiddLFxuICAgIH0pO1xuICAgIGV4cGVjdChvcHRpb24yRXhpc3RzLnJlc3VsdCkudG9CZSh0cnVlKTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoXG4gICd0b1NhbmRib3g6IFwidW5kZWZpbmVkXCIgaW4gaGFzaCB2YWx1ZXMgc2VudCB0byBKUyBzaG91bGQgYmUgdHJlYXRlZCBhcyBub24tZXhpc3Rpbmcga2V5JyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IHsgb3B0aW9uMTogdW5kZWZpbmVkLCBvcHRpb24yOiAnaGVsbG8nIH07XG4gICAgY29uc3Qgb3B0aW9uMUV4aXN0cyA9IHNhbmRib3guc2ludm9rZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuRXJhc2VVbmRlZmluZWRIYXNoVmFsdWVzJyxcbiAgICAgIG1ldGhvZDogJ2RvZXNLZXlFeGlzdCcsXG4gICAgICBhcmdzOiBbaW5wdXQsICdvcHRpb24xJ10sXG4gICAgfSk7XG4gICAgZXhwZWN0KG9wdGlvbjFFeGlzdHMucmVzdWx0KS50b0JlKGZhbHNlKTtcbiAgICBjb25zdCBvcHRpb24yRXhpc3RzID0gc2FuZGJveC5zaW52b2tlKHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5FcmFzZVVuZGVmaW5lZEhhc2hWYWx1ZXMnLFxuICAgICAgbWV0aG9kOiAnZG9lc0tleUV4aXN0JyxcbiAgICAgIGFyZ3M6IFtpbnB1dCwgJ29wdGlvbjInXSxcbiAgICB9KTtcbiAgICBleHBlY3Qob3B0aW9uMkV4aXN0cy5yZXN1bHQpLnRvQmUodHJ1ZSk7XG4gIH0sXG4pO1xuXG5kZWZpbmVUZXN0KCdjYWxjdWxhdG9yIGNhbiBzZXQgYW5kIHJldHJpZXZlIHVuaW9uIHByb3BlcnRpZXMnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBjYWxjdWxhdG9yID0gY3JlYXRlKHNhbmRib3gsICdqc2lpLWNhbGMuQ2FsY3VsYXRvcicpKCk7XG5cbiAgY29uc3QgbXVsID0gY3JlYXRlKHNhbmRib3gsICdqc2lpLWNhbGMuTXVsdGlwbHknKTtcbiAgY29uc3QgbnVtID0gY3JlYXRlKHNhbmRib3gsICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXInKTtcblxuICBzYW5kYm94LnNldCh7XG4gICAgb2JqcmVmOiBjYWxjdWxhdG9yLFxuICAgIHByb3BlcnR5OiAndW5pb25Qcm9wZXJ0eScsXG4gICAgdmFsdWU6IG11bChudW0oOSksIG51bSgzKSksXG4gIH0pO1xuXG4gIGNvbnN0IHZhbHVlID0gc2FuZGJveC5pbnZva2Uoe1xuICAgIG9ianJlZjogY2FsY3VsYXRvcixcbiAgICBtZXRob2Q6ICdyZWFkVW5pb25WYWx1ZScsXG4gIH0pLnJlc3VsdDtcbiAgZXhwZWN0KDI3KS50b0JlKHZhbHVlKTtcblxuICBjb25zdCBleHByZXNzaW9uID0gc2FuZGJveC5nZXQoe1xuICAgIG9ianJlZjogY2FsY3VsYXRvcixcbiAgICBwcm9wZXJ0eTogJ3VuaW9uUHJvcGVydHknLFxuICB9KS52YWx1ZTtcbiAgZXhwZWN0KFxuICAgIGRlZXBFcXVhbFdpdGhSZWdleChleHByZXNzaW9uLCB7IFtUT0tFTl9SRUZdOiAvXmpzaWktY2FsYy5NdWx0aXBseUAvIH0pLFxuICApLnRvQmVUcnV0aHkoKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdjYW4gc2V0IGFuZCByZXRyaWV2ZSB1bmlvbiBwcm9wZXJ0aWVzJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3QgdHlwZXMgPSBjcmVhdGUoc2FuZGJveCwgJ2pzaWktY2FsYy5BbGxUeXBlcycpKCk7XG4gIGNvbnN0IHR5cGVzU2V0ID0gc2V0KHNhbmRib3gsIHR5cGVzKTtcbiAgY29uc3QgdHlwZXNHZXQgPSBnZXQoc2FuZGJveCwgdHlwZXMpO1xuICBjb25zdCBtdWwgPSBjcmVhdGUoc2FuZGJveCwgJ2pzaWktY2FsYy5NdWx0aXBseScpO1xuICBjb25zdCBudW0gPSBjcmVhdGUoc2FuZGJveCwgJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlcicpO1xuXG4gIHR5cGVzU2V0KCd1bmlvblByb3BlcnR5JywgMTIzNCk7XG4gIGV4cGVjdCh0eXBlc0dldCgndW5pb25Qcm9wZXJ0eScpKS50b0JlKDEyMzQpO1xuXG4gIHR5cGVzU2V0KCd1bmlvblByb3BlcnR5JywgJ0hlbGxvJyk7XG4gIGV4cGVjdCh0eXBlc0dldCgndW5pb25Qcm9wZXJ0eScpKS50b0JlKCdIZWxsbycpO1xuXG4gIHR5cGVzU2V0KCd1bmlvblByb3BlcnR5JywgbXVsKG51bSgyKSwgbnVtKDEyKSkpO1xuICBjb25zdCBtdWxPYmogPSB0eXBlc0dldCgndW5pb25Qcm9wZXJ0eScpO1xuICBleHBlY3QoZ2V0KHNhbmRib3gsIG11bE9iaikoJ3ZhbHVlJykpLnRvQmUoMjQpO1xuXG4gIC8vIENvbGxlY3Rpb25zXG5cbiAgdHlwZXNTZXQoJ3VuaW9uTWFwUHJvcGVydHknLCB7XG4gICAgRm9vOiBudW0oOTkpLFxuICB9KTtcblxuICB0eXBlc1NldCgndW5pb25BcnJheVByb3BlcnR5JywgWzEyMywgbnVtKDMzKV0pO1xuICBjb25zdCB1bmlvbkFycmF5ID0gdHlwZXNHZXQoJ3VuaW9uQXJyYXlQcm9wZXJ0eScpO1xuICBleHBlY3QoZ2V0KHNhbmRib3gsIHVuaW9uQXJyYXlbMV0pKCd2YWx1ZScpKS50b0JlKDMzKTtcbn0pO1xuXG5kZWZpbmVUZXN0KFxuICAncmVxdWlyZSBwcmVzZW5jZSBvZiByZXF1aXJlZCBwcm9wZXJ0aWVzIC0tIHRvcCBsZXZlbCcsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IHtcbiAgICAgIHNhbmRib3guc2ludm9rZSh7XG4gICAgICAgIGZxbjogJ2pzaWktY2FsYy5TdHJ1Y3RQYXNzaW5nJyxcbiAgICAgICAgbWV0aG9kOiAncm91bmRUcmlwJyxcbiAgICAgICAgYXJnczogWzEyMywgeyBpbmNvbXBsZXRlOiB0cnVlIH1dLFxuICAgICAgfSk7XG4gICAgfSkudG9UaHJvdyhcbiAgICAgIC9NaXNzaW5nIHJlcXVpcmVkIHByb3BlcnRpZXMgZm9yIGpzaWktY2FsYy5Ub3BMZXZlbFN0cnVjdDogcmVxdWlyZWQsIHNlY29uZExldmVsLyxcbiAgICApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ3JlcXVpcmUgcHJlc2VuY2Ugb2YgcmVxdWlyZWQgcHJvcGVydGllcyAtLSBkZWVwZXIgbGV2ZWwnLFxuICAoc2FuZGJveCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICBzYW5kYm94LnNpbnZva2Uoe1xuICAgICAgICBmcW46ICdqc2lpLWNhbGMuU3RydWN0UGFzc2luZycsXG4gICAgICAgIG1ldGhvZDogJ3JvdW5kVHJpcCcsXG4gICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAxMjMsXG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVxdWlyZWQ6ICdhYmMnLFxuICAgICAgICAgICAgc2Vjb25kTGV2ZWw6IHsgYWxzb0luY29tcGxldGU6IHRydWUgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgfSkudG9UaHJvdyhcbiAgICAgIC9NaXNzaW5nIHJlcXVpcmVkIHByb3BlcnRpZXMgZm9yIGpzaWktY2FsYy5TZWNvbmRMZXZlbFN0cnVjdDogZGVlcGVyUmVxdWlyZWRQcm9wLyxcbiAgICApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdCgnbm90aWNlIHdoZW4gYW4gYXJyYXkgaXMgcGFzc2VkIGluc3RlYWQgb2YgdmFyYXJncycsIChzYW5kYm94KSA9PiB7XG4gIGV4cGVjdCgoKSA9PiB7XG4gICAgc2FuZGJveC5zaW52b2tlKHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5TdHJ1Y3RQYXNzaW5nJyxcbiAgICAgIG1ldGhvZDogJ2hvd01hbnlWYXJBcmdzRGlkSVBhc3MnLFxuICAgICAgYXJnczogWzEyMywgW3sgcmVxdWlyZWQ6ICdhYmMnLCBzZWNvbmRMZXZlbDogNiB9XV0sXG4gICAgfSk7XG4gIH0pLnRvVGhyb3coL0dvdCBhbiBhcnJheSB3aGVyZSBhIGpzaWktY2FsYy5Ub3BMZXZlbFN0cnVjdCB3YXMgZXhwZWN0ZWQvKTtcbn0pO1xuXG5kZWZpbmVUZXN0KFxuICAnT2JqZWN0IElEIGRvZXMgbm90IGdldCByZS1hbGxvY2F0ZWQgd2hlbiB0aGUgY29uc3RydWN0b3IgcGFzc2VzIFwidGhpc1wiIG91dCcsXG4gIChzYW5kYm94KSA9PiB7XG4gICAgc2FuZGJveC5jYWxsYmFja0hhbmRsZXIgPSBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcigoY2FsbGJhY2spID0+IHtcbiAgICAgIGV4cGVjdChjYWxsYmFjay5pbnZva2U/Lm1ldGhvZCkudG9CZSgnY29uc3VtZVBhcnRpYWxseUluaXRpYWxpemVkVGhpcycpO1xuICAgICAgZXhwZWN0KGNhbGxiYWNrLmludm9rZT8uYXJncykudG9FcXVhbChbXG4gICAgICAgIHtcbiAgICAgICAgICBbYXBpLlRPS0VOX1JFRl06ICdqc2lpLWNhbGMuQ29uc3RydWN0b3JQYXNzZXNUaGlzT3V0QDEwMDAxJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFthcGkuVE9LRU5fREFURV06ICcxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMFonLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgW2FwaS5UT0tFTl9FTlVNXTogJ2pzaWktY2FsYy5BbGxUeXBlc0VudW0vVEhJU19JU19HUkVBVCcsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICAgIHJldHVybiAnT0snO1xuICAgIH0pO1xuICAgIGNvbnN0IHJlZmxlY3RvciA9IHNhbmRib3guY3JlYXRlKHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5QYXJ0aWFsbHlJbml0aWFsaXplZFRoaXNDb25zdW1lcicsXG4gICAgICBvdmVycmlkZXM6IFt7IG1ldGhvZDogJ2NvbnN1bWVQYXJ0aWFsbHlJbml0aWFsaXplZFRoaXMnIH1dLFxuICAgIH0pO1xuICAgIGV4cGVjdChyZWZsZWN0b3JbYXBpLlRPS0VOX1JFRl0pLnRvQmUoXG4gICAgICAnanNpaS1jYWxjLlBhcnRpYWxseUluaXRpYWxpemVkVGhpc0NvbnN1bWVyQDEwMDAwJyxcbiAgICApO1xuXG4gICAgY29uc3QgY2xhc3NSZWYgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuQ29uc3RydWN0b3JQYXNzZXNUaGlzT3V0JyxcbiAgICAgIGFyZ3M6IFtyZWZsZWN0b3JdLFxuICAgIH0pO1xuICAgIGV4cGVjdChjbGFzc1JlZlthcGkuVE9LRU5fUkVGXSkudG9CZShcbiAgICAgICdqc2lpLWNhbGMuQ29uc3RydWN0b3JQYXNzZXNUaGlzT3V0QDEwMDAxJyxcbiAgICApO1xuICB9LFxuKTtcblxuZGVmaW5lVGVzdChcbiAgJ3N0cnVjdDogZW1wdHkgb2JqZWN0IGlzIHR1cm5lZCB0byB1bmRlZmluZWQgYnkgZGVzZXJpYWxpemF0aW9uJyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBvYmplY3QgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuT3B0aW9uYWxTdHJ1Y3RDb25zdW1lcicsXG4gICAgICBhcmdzOiBbe31dLFxuICAgIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IHNhbmRib3guZ2V0KHtcbiAgICAgIG9ianJlZjogb2JqZWN0LFxuICAgICAgcHJvcGVydHk6ICdwYXJhbWV0ZXJXYXNVbmRlZmluZWQnLFxuICAgIH0pO1xuICAgIGV4cGVjdChyZXN1bHQudmFsdWUpLnRvQmVUcnV0aHkoKTsgLy8gVGhlIHBhcmFtZXRlciB3YXMgdW5kZWZpbmVkIHdpdGhpbiB0aGUgY29uc3RydWN0b3InXG4gIH0sXG4pO1xuXG5kZWZpbmVUZXN0KCdzdHJ1Y3Q6IG5vbi1lbXB0eSBvYmplY3QgZGVzZXJpYWxpemVzIHByb3Blcmx5JywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgb2JqcmVmID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5PcHRpb25hbFN0cnVjdENvbnN1bWVyJyxcbiAgICBhcmdzOiBbeyBmaWVsZDogJ2ZvbycgfV0sXG4gIH0pO1xuICBjb25zdCByZXN1bHQgPSBzYW5kYm94LmdldCh7IG9ianJlZiwgcHJvcGVydHk6ICdwYXJhbWV0ZXJXYXNVbmRlZmluZWQnIH0pO1xuICBleHBlY3QocmVzdWx0LnZhbHVlKS50b0JlRmFsc3koKTsgLy8gVGhlIHBhcmFtZXRlciB3YXMgbm90IHVuZGVmaW5lZCB3aXRoaW4gdGhlIGNvbnN0cnVjdG9yJ1xuICBjb25zdCBmaWVsZCA9IHNhbmRib3guZ2V0KHsgb2JqcmVmLCBwcm9wZXJ0eTogJ2ZpZWxkVmFsdWUnIH0pO1xuICBleHBlY3QoZmllbGQudmFsdWUpLnRvQmUoJ2ZvbycpO1xufSk7XG5cbmRlZmluZVRlc3QoXG4gICdlcmFzZWQgYmFzZTogY2FuIHJlY2VpdmUgYW4gaW5zdGFuY2Ugb2YgcHJpdmF0ZSB0eXBlJyxcbiAgKHNhbmRib3gpID0+IHtcbiAgICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LnNpbnZva2Uoe1xuICAgICAgZnFuOiAnanNpaS1jYWxjLkpTSUk0MTdQdWJsaWNCYXNlT2ZCYXNlJyxcbiAgICAgIG1ldGhvZDogJ21ha2VJbnN0YW5jZScsXG4gICAgfSk7XG4gICAgZXhwZWN0KG9ianJlZi5yZXN1bHQpLnRvRXF1YWwoe1xuICAgICAgW2FwaS5UT0tFTl9SRUZdOiAnanNpaS1jYWxjLkpTSUk0MTdQdWJsaWNCYXNlT2ZCYXNlQDEwMDAwJyxcbiAgICB9KTtcbiAgfSxcbik7XG5cbmRlZmluZVRlc3QoJ2Rlc2VyaWFsaXplIGEgc3RydWN0IGJ5IHJlZmVyZW5jZScsIChzYW5kYm94KSA9PiB7XG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKCkgPT4gJ3hveG94b3gnKTtcbiAgY29uc3Qgb2JqcmVmID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ09iamVjdCcsXG4gICAgb3ZlcnJpZGVzOiBbeyBwcm9wZXJ0eTogJ2ZpZWxkJyB9XSxcbiAgfSk7XG4gIGNvbnN0IGNvbnN1bWVyID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ2pzaWktY2FsYy5PcHRpb25hbFN0cnVjdENvbnN1bWVyJyxcbiAgICBhcmdzOiBbb2JqcmVmXSxcbiAgfSk7XG4gIGNvbnN0IHZhbHVlID0gc2FuZGJveC5nZXQoeyBvYmpyZWY6IGNvbnN1bWVyLCBwcm9wZXJ0eTogJ2ZpZWxkVmFsdWUnIH0pO1xuICBleHBlY3QodmFsdWUpLnRvRXF1YWwoeyB2YWx1ZTogJ3hveG94b3gnIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ2NvcnJlY3RseSBwYXNzZXMgZW51bSB2YWx1ZXMgYWNyb3NzJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3Qgc3RyaW5nTGlrZSA9IHNhbmRib3guc2ludm9rZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLkVudW1EaXNwZW5zZXInLFxuICAgIG1ldGhvZDogJ3JhbmRvbVN0cmluZ0xpa2VFbnVtJyxcbiAgfSk7XG4gIGV4cGVjdChzdHJpbmdMaWtlLnJlc3VsdCkudG9FcXVhbCh7ICckanNpaS5lbnVtJzogJ2pzaWktY2FsYy5TdHJpbmdFbnVtL0InIH0pO1xuXG4gIGNvbnN0IGludGVnZXJMaWtlID0gc2FuZGJveC5zaW52b2tlKHtcbiAgICBmcW46ICdqc2lpLWNhbGMuRW51bURpc3BlbnNlcicsXG4gICAgbWV0aG9kOiAncmFuZG9tSW50ZWdlckxpa2VFbnVtJyxcbiAgfSk7XG4gIGV4cGVjdChpbnRlZ2VyTGlrZS5yZXN1bHQpLnRvRXF1YWwoe1xuICAgICckanNpaS5lbnVtJzogJ2pzaWktY2FsYy5BbGxUeXBlc0VudW0vWU9VUl9FTlVNX1ZBTFVFJyxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgncmVnaXN0ZXJzIGludGVyZmFjZXMgcmVxdWVzdGVkJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3QgaW50ZXJmYWNlcyA9IFtcbiAgICAnanNpaS1jYWxjLklSZXR1cm5zTnVtYmVyJyxcbiAgICAnanNpaS1jYWxjLklJbnRlcmZhY2VXaXRoT3B0aW9uYWxNZXRob2RBcmd1bWVudHMnLFxuICBdO1xuICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LmNyZWF0ZSh7IGZxbjogJ09iamVjdCcsIGludGVyZmFjZXMgfSk7XG4gIGV4cGVjdChvYmpyZWYpLnRvRXF1YWwoe1xuICAgIFtUT0tFTl9SRUZdOiAnT2JqZWN0QDEwMDAwJyxcbiAgICBbVE9LRU5fSU5URVJGQUNFU106IGludGVyZmFjZXMuc29ydCgpLFxuICB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdyZXRhaW5zIHRoZSB0eXBlIG9mIG9iamVjdCBsaXRlcmFscycsIChzYW5kYm94KSA9PiB7XG4gIHNhbmRib3guY2FsbGJhY2tIYW5kbGVyID0gbWFrZVN5bmNDYWxsYmFja0hhbmRsZXIoKGNiKSA9PiB7XG4gICAgZXhwZWN0KGNiLmludm9rZT8ubWV0aG9kKS50b0JlKCdwcm92aWRlQXNJbnRlcmZhY2UnKTtcbiAgICBleHBlY3QoY2IuaW52b2tlPy5vYmpyZWYpLnRvTWF0Y2hPYmplY3QoeyBbVE9LRU5fUkVGXTogJ09iamVjdEAxMDAwMCcgfSk7XG4gICAgY29uc3QgcmVhbE9iamVjdCA9IHNhbmRib3guY3JlYXRlKHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5Bbm9ueW1vdXNJbXBsZW1lbnRhdGlvblByb3ZpZGVyJyxcbiAgICB9KTtcbiAgICBjb25zdCB7IHJlc3VsdCB9ID0gc2FuZGJveC5pbnZva2Uoe1xuICAgICAgb2JqcmVmOiByZWFsT2JqZWN0LFxuICAgICAgbWV0aG9kOiAncHJvdmlkZUFzSW50ZXJmYWNlJyxcbiAgICB9KTtcbiAgICBzYW5kYm94LmRlbCh7IG9ianJlZjogcmVhbE9iamVjdCB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9KTtcblxuICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnT2JqZWN0JyxcbiAgICBpbnRlcmZhY2VzOiBbJ2pzaWktY2FsYy5JQW5vbnltb3VzSW1wbGVtZW50YXRpb25Qcm92aWRlciddLFxuICAgIG92ZXJyaWRlczogW3sgbWV0aG9kOiAncHJvdmlkZUFzSW50ZXJmYWNlJyB9XSxcbiAgfSk7XG4gIGNvbnN0IHJlc3VsdCA9IHNhbmRib3guaW52b2tlKHsgb2JqcmVmLCBtZXRob2Q6ICdwcm92aWRlQXNJbnRlcmZhY2UnIH0pO1xuICBleHBlY3QocmVzdWx0KS50b0VxdWFsKHtcbiAgICByZXN1bHQ6IHtcbiAgICAgIFtUT0tFTl9SRUZdOiAnanNpaS1jYWxjLkltcGxlbWVudGF0aW9uQDEwMDAyJyxcbiAgICAgIFtUT0tFTl9JTlRFUkZBQ0VTXTogWydqc2lpLWNhbGMuSUFub255bW91c2x5SW1wbGVtZW50TWUnXSxcbiAgICB9LFxuICB9KTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdjb3JyZWN0bHkgZGVzZXJpYWxpemVzIHN0cnVjdCB1bmlvbnMnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCB1bmlvbkNvbnN1bWVyID0gJ2pzaWktY2FsYy5TdHJ1Y3RVbmlvbkNvbnN1bWVyJztcbiAgY29uc3Qgc3RydWN0QTA6IFdpcmVTdHJ1Y3QgPSB7XG4gICAgW1RPS0VOX1NUUlVDVF06IHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5TdHJ1Y3RBJyxcbiAgICAgIGRhdGE6IHsgcmVxdWlyZWRTdHJpbmc6ICdQcmVzZW50IScsIG9wdGlvbmFsU3RyaW5nOiAnQmF6aW5nYSEnIH0sXG4gICAgfSxcbiAgfTtcbiAgY29uc3Qgc3RydWN0QTE6IFdpcmVTdHJ1Y3QgPSB7XG4gICAgW1RPS0VOX1NUUlVDVF06IHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5TdHJ1Y3RBJyxcbiAgICAgIGRhdGE6IHsgcmVxdWlyZWRTdHJpbmc6ICdQcmVzZW50IScsIG9wdGlvbmFsTnVtYmVyOiAxMzM3IH0sXG4gICAgfSxcbiAgfTtcbiAgY29uc3Qgc3RydWN0QjA6IFdpcmVTdHJ1Y3QgPSB7XG4gICAgW1RPS0VOX1NUUlVDVF06IHtcbiAgICAgIGZxbjogJ2pzaWktY2FsYy5TdHJ1Y3RCJyxcbiAgICAgIGRhdGE6IHsgcmVxdWlyZWRTdHJpbmc6ICdQcmVzZW50IScsIG9wdGlvbmFsQm9vbGVhbjogdHJ1ZSB9LFxuICAgIH0sXG4gIH07XG4gIGNvbnN0IHN0cnVjdEIxOiBXaXJlU3RydWN0ID0ge1xuICAgIFtUT0tFTl9TVFJVQ1RdOiB7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuU3RydWN0QicsXG4gICAgICBkYXRhOiB7IHJlcXVpcmVkU3RyaW5nOiAnUHJlc2VudCEnLCBvcHRpb25hbFN0cnVjdEE6IHN0cnVjdEExIH0sXG4gICAgfSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgW3N0cnVjdEEwLCBzdHJ1Y3RBMV0pIHtcbiAgICBleHBlY3QoXG4gICAgICBzYW5kYm94LnNpbnZva2UoeyBmcW46IHVuaW9uQ29uc3VtZXIsIG1ldGhvZDogJ2lzU3RydWN0QScsIGFyZ3M6IFtpdGVtXSB9KVxuICAgICAgICAucmVzdWx0LFxuICAgICkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QoXG4gICAgICBzYW5kYm94LnNpbnZva2UoeyBmcW46IHVuaW9uQ29uc3VtZXIsIG1ldGhvZDogJ2lzU3RydWN0QicsIGFyZ3M6IFtpdGVtXSB9KVxuICAgICAgICAucmVzdWx0LFxuICAgICkudG9CZShmYWxzZSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgW3N0cnVjdEIwLCBzdHJ1Y3RCMV0pIHtcbiAgICBleHBlY3QoXG4gICAgICBzYW5kYm94LnNpbnZva2UoeyBmcW46IHVuaW9uQ29uc3VtZXIsIG1ldGhvZDogJ2lzU3RydWN0QScsIGFyZ3M6IFtpdGVtXSB9KVxuICAgICAgICAucmVzdWx0LFxuICAgICkudG9CZShmYWxzZSk7XG4gICAgZXhwZWN0KFxuICAgICAgc2FuZGJveC5zaW52b2tlKHsgZnFuOiB1bmlvbkNvbnN1bWVyLCBtZXRob2Q6ICdpc1N0cnVjdEInLCBhcmdzOiBbaXRlbV0gfSlcbiAgICAgICAgLnJlc3VsdCxcbiAgICApLnRvQmUodHJ1ZSk7XG4gIH1cbn0pO1xuXG5kZWZpbmVUZXN0KCdBTlkgZGVzZXJpYWxpemVyOiBkZWNvcmF0ZWQgc3RydWN0cycsIChzYW5kYm94KSA9PiB7XG4gIGNvbnN0IGlucHV0ID0ge1xuICAgICckanNpaS5zdHJ1Y3QnOiB7XG4gICAgICBmcW46ICdqc2lpLWNhbGMuU3RydWN0QicsXG4gICAgICBkYXRhOiB7IHJlcXVpcmVkU3RyaW5nOiAnQmF6aW5nYSEnLCBvcHRpb25hbEJvb2xlYW46IGZhbHNlIH0sXG4gICAgfSxcbiAgfTtcbiAgZXhwZWN0KGRlc2VyaWFsaXplQW55KHNhbmRib3gsIGlucHV0KSkudG9TdHJpY3RFcXVhbCh7XG4gICAgcmVxdWlyZWRTdHJpbmc6ICdCYXppbmdhIScsXG4gICAgb3B0aW9uYWxCb29sZWFuOiBmYWxzZSxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIGRlc2VyaWFsaXplcjogcHJpbWl0aXZlcycsIChzYW5kYm94KSA9PiB7XG4gIGV4cGVjdChkZXNlcmlhbGl6ZUFueShzYW5kYm94LCAtMTAwKSkudG9TdHJpY3RFcXVhbCgtMTAwKTtcbiAgZXhwZWN0KGRlc2VyaWFsaXplQW55KHNhbmRib3gsIDApKS50b1N0cmljdEVxdWFsKDApO1xuICBleHBlY3QoZGVzZXJpYWxpemVBbnkoc2FuZGJveCwgMTIzNCkpLnRvU3RyaWN0RXF1YWwoMTIzNCk7XG4gIGV4cGVjdChkZXNlcmlhbGl6ZUFueShzYW5kYm94LCAnaGVsbG8nKSkudG9TdHJpY3RFcXVhbCgnaGVsbG8nKTtcbiAgZXhwZWN0KGRlc2VyaWFsaXplQW55KHNhbmRib3gsICcnKSkudG9TdHJpY3RFcXVhbCgnJyk7XG4gIGV4cGVjdChkZXNlcmlhbGl6ZUFueShzYW5kYm94LCB0cnVlKSkudG9TdHJpY3RFcXVhbCh0cnVlKTtcbiAgZXhwZWN0KGRlc2VyaWFsaXplQW55KHNhbmRib3gsIGZhbHNlKSkudG9TdHJpY3RFcXVhbChmYWxzZSk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIGRlc2VyaWFsaXplcjogYXJyYXknLCAoc2FuZGJveCkgPT4ge1xuICBleHBlY3QoZGVzZXJpYWxpemVBbnkoc2FuZGJveCwgWzEsIDIsIDMsICdmb3VyJ10pKS50b1N0cmljdEVxdWFsKFtcbiAgICAxLFxuICAgIDIsXG4gICAgMyxcbiAgICAnZm91cicsXG4gIF0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ0FOWSBkZXNlcmlhbGl6ZXI6IHVuZGVmaW5lZC9udWxsJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KGRlc2VyaWFsaXplQW55KHNhbmRib3gsIG51bGwpKS50b1N0cmljdEVxdWFsKHVuZGVmaW5lZCk7XG4gIGV4cGVjdChkZXNlcmlhbGl6ZUFueShzYW5kYm94LCB1bmRlZmluZWQpKS50b1N0cmljdEVxdWFsKHVuZGVmaW5lZCk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIGRlc2VyaWFsaXplcjogd2lyZSBkYXRlJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KFxuICAgIGRlc2VyaWFsaXplQW55KHNhbmRib3gsIHsgJyRqc2lpLmRhdGUnOiAnMjAxOS0xMS0xOFQxMzowMToyMC41MTVaJyB9KSxcbiAgKS50b1N0cmljdEVxdWFsKCcyMDE5LTExLTE4VDEzOjAxOjIwLjUxNVonKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdBTlkgZGVzZXJpYWxpemVyOiBlbnVtJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KFxuICAgIGRlc2VyaWFsaXplQW55KHNhbmRib3gsIHtcbiAgICAgICckanNpaS5lbnVtJzogJ2pzaWktY2FsYy5BbGxUeXBlc0VudW0vWU9VUl9FTlVNX1ZBTFVFJyxcbiAgICB9KSxcbiAgKS50b1N0cmljdEVxdWFsKDEwMCk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIGRlc2VyaWFsaXplcjogd2lyZSBtYXAnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCBpbnB1dCA9IHtcbiAgICAnJGpzaWkubWFwJzoge1xuICAgICAgZm9vOiAxMjMsXG4gICAgICBiYXI6IHsgJyRqc2lpLmVudW0nOiAnanNpaS1jYWxjLkFsbFR5cGVzRW51bS9ZT1VSX0VOVU1fVkFMVUUnIH0sXG4gICAgfSxcbiAgfTtcbiAgZXhwZWN0KGRlc2VyaWFsaXplQW55KHNhbmRib3gsIGlucHV0KSkudG9TdHJpY3RFcXVhbCh7XG4gICAgZm9vOiAxMjMsXG4gICAgYmFyOiAxMDAsXG4gIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ0FOWSBkZXNlcmlhbGl6ZXI6IGJ5IHZhbHVlJywgKHNhbmRib3gpID0+IHtcbiAgY29uc3QgcmVmID0gc2FuZGJveC5jcmVhdGUoe1xuICAgIGZxbjogJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlcicsXG4gICAgYXJnczogWzQ0NF0sXG4gIH0pO1xuXG4gIGNvbnN0IGlucHV0ID0ge1xuICAgIGZvbzogMTIzLFxuICAgIGJhcjogeyAnJGpzaWkuZW51bSc6ICdqc2lpLWNhbGMuQWxsVHlwZXNFbnVtL1lPVVJfRU5VTV9WQUxVRScgfSxcbiAgICBzdHJ1Y3Q6IHtcbiAgICAgICckanNpaS5zdHJ1Y3QnOiB7XG4gICAgICAgIGZxbjogJ2pzaWktY2FsYy5TdHJ1Y3RCJyxcbiAgICAgICAgZGF0YTogeyByZXF1aXJlZFN0cmluZzogJ0JhemluZ2EhJywgb3B0aW9uYWxCb29sZWFuOiBmYWxzZSB9LFxuICAgICAgfSxcbiAgICB9LFxuICAgIHJlZixcbiAgfTtcblxuICBleHBlY3QoZGVzZXJpYWxpemVBbnkoc2FuZGJveCwgaW5wdXQpKS50b1N0cmljdEVxdWFsKHtcbiAgICBmb286IDEyMyxcbiAgICBiYXI6IDEwMCxcbiAgICBzdHJ1Y3Q6IHtcbiAgICAgIHJlcXVpcmVkU3RyaW5nOiAnQmF6aW5nYSEnLFxuICAgICAgb3B0aW9uYWxCb29sZWFuOiBmYWxzZSxcbiAgICB9LFxuICAgIHJlZjogeyB2YWx1ZTogNDQ0IH0sXG4gIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ0FOWSBzZXJpYWxpemVyOiBudWxsL3VuZGVmaW5lZCcsIChzYW5kYm94KSA9PiB7XG4gIGV4cGVjdChzZXJpYWxpemVBbnkoc2FuZGJveCwgJ2FueU51bGwnKSkudG9TdHJpY3RFcXVhbCh1bmRlZmluZWQpO1xuICBleHBlY3Qoc2VyaWFsaXplQW55KHNhbmRib3gsICdhbnlVbmRlZmluZWQnKSkudG9TdHJpY3RFcXVhbCh1bmRlZmluZWQpO1xufSk7XG5cbmRlZmluZVRlc3QoJ0FOWSBzZXJpYWxpemVyOiBmdW5jdGlvbiAoZmFpbHMpJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KCgpID0+IHNlcmlhbGl6ZUFueShzYW5kYm94LCAnYW55RnVuY3Rpb24nKSkudG9UaHJvdyhcbiAgICAvSlNJSSBLZXJuZWwgaXMgdW5hYmxlIHRvIHNlcmlhbGl6ZSBgZnVuY3Rpb25gLiBBbiBpbnN0YW5jZSB3aXRoIG1ldGhvZHMgbWlnaHQgaGF2ZSBiZWVuIHJldHVybmVkIGJ5IGFuIGBhbnlgIG1ldGhvZFxcPy8sXG4gICk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIHNlcmlhbGl6ZXI6IGRhdGUnLCAoc2FuZGJveCkgPT4ge1xuICBleHBlY3Qoc2VyaWFsaXplQW55KHNhbmRib3gsICdhbnlEYXRlJykpLnRvU3RyaWN0RXF1YWwoe1xuICAgICckanNpaS5kYXRlJzogJzIwMTktMTEtMThUMTM6MDE6MjAuNTE1WicsXG4gIH0pO1xufSk7XG5cbmRlZmluZVRlc3QoJ0FOWSBzZXJpYWxpemVyOiBwcmltaXRpdmVzJywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KHNlcmlhbGl6ZUFueShzYW5kYm94LCAnYW55TnVtYmVyJykpLnRvU3RyaWN0RXF1YWwoMTIzKTtcbiAgZXhwZWN0KHNlcmlhbGl6ZUFueShzYW5kYm94LCAnYW55WmVybycpKS50b1N0cmljdEVxdWFsKDApO1xuICBleHBlY3Qoc2VyaWFsaXplQW55KHNhbmRib3gsICdhbnlTdHJpbmcnKSkudG9TdHJpY3RFcXVhbCgnZm9vJyk7XG4gIGV4cGVjdChzZXJpYWxpemVBbnkoc2FuZGJveCwgJ2FueUVtcHR5U3RyaW5nJykpLnRvU3RyaWN0RXF1YWwoJycpO1xuICBleHBlY3Qoc2VyaWFsaXplQW55KHNhbmRib3gsICdhbnlCb29sZWFuVHJ1ZScpKS50b1N0cmljdEVxdWFsKHRydWUpO1xuICBleHBlY3Qoc2VyaWFsaXplQW55KHNhbmRib3gsICdhbnlCb29sZWFuRmFsc2UnKSkudG9TdHJpY3RFcXVhbChmYWxzZSk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIHNlcmlhbGl6ZXI6IGFycmF5JywgKHNhbmRib3gpID0+IHtcbiAgZXhwZWN0KHNlcmlhbGl6ZUFueShzYW5kYm94LCAnYW55QXJyYXknKSkudG9FcXVhbChbXG4gICAgMSxcbiAgICAyLFxuICAgIDMsXG4gICAge1xuICAgICAgJyRqc2lpLmJ5cmVmJzogJ0BzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlckAxMDAwMCcsXG4gICAgICAnJGpzaWkuaW50ZXJmYWNlcyc6IHVuZGVmaW5lZCxcbiAgICB9LFxuICAgIHsgZm9vOiAnYmFyJyB9LFxuICBdKTtcbn0pO1xuXG5kZWZpbmVUZXN0KCdBTlkgc2VyaWFsaXplcjogaGFzaCcsIChzYW5kYm94KSA9PiB7XG4gIGV4cGVjdChzZXJpYWxpemVBbnkoc2FuZGJveCwgJ2FueUhhc2gnKSkudG9TdHJpY3RFcXVhbCh7XG4gICAgaGVsbG86IDEyMzQsXG4gICAgd29ybGQ6IHtcbiAgICAgICckanNpaS5ieXJlZic6ICdAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXJAMTAwMDAnLFxuICAgICAgJyRqc2lpLmludGVyZmFjZXMnOiB1bmRlZmluZWQsXG4gICAgfSxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnQU5ZIHNlcmlhbGl6ZXI6IHJlZicsIChzYW5kYm94KSA9PiB7XG4gIGV4cGVjdChzZXJpYWxpemVBbnkoc2FuZGJveCwgJ2FueVJlZicpKS50b1N0cmljdEVxdWFsKHtcbiAgICAnJGpzaWkuYnlyZWYnOiAnQHNjb3BlL2pzaWktY2FsYy1saWIuTnVtYmVyQDEwMDAwJyxcbiAgICAnJGpzaWkuaW50ZXJmYWNlcyc6IHVuZGVmaW5lZCxcbiAgfSk7XG59KTtcblxuZGVmaW5lVGVzdCgnT3ZlcnJpZGUgdHJhbnNpdGl2ZSBwcm9wZXJ0eScsIChzYW5kYm94KSA9PiB7XG4gIC8vLy8vLy8vLy9cbiAgLy8gR0lWRU5cbiAgLy8vLy8vLy8vL1xuICBjb25zdCBvcmlnaW5hbFN0cmluZyA9ICdyMDB0JztcbiAgY29uc3QgaW5pdGlhbE92ZXJyaWRkZW5Qcm9wVmFsdWUgPSAnT3ZlcnJpZGRlbiBWYWx1ZSc7XG4gIGxldCBwcm9wVmFsdWUgPSBpbml0aWFsT3ZlcnJpZGRlblByb3BWYWx1ZTtcbiAgc2FuZGJveC5jYWxsYmFja0hhbmRsZXIgPSBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcigoY2FsbGJhY2spID0+IHtcbiAgICBjb25zdCBnZXRPclNldCA9IGNhbGxiYWNrLmdldCA/PyBjYWxsYmFjay5zZXQ7XG4gICAgLy8gV2UgZG9uJ3QgZXhwZWN0IHRvIHJlY2VpdmUgYW55IG90aGVyIGNhbGxiYWNrXG4gICAgZXhwZWN0KGdldE9yU2V0KS50b0JlRGVmaW5lZCgpO1xuICAgIGV4cGVjdChnZXRPclNldD8ucHJvcGVydHkpLnRvQmUoJ2R5bmFtaWNQcm9wZXJ0eScpO1xuXG4gICAgaWYgKGNhbGxiYWNrLmdldCkge1xuICAgICAgcmV0dXJuIHByb3BWYWx1ZTtcbiAgICB9XG4gICAgcHJvcFZhbHVlID0gY2FsbGJhY2suc2V0Py52YWx1ZTtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9KTtcblxuICAvLy8vLy8vLy8vXG4gIC8vIFdIRU5cbiAgLy8vLy8vLy8vL1xuICBjb25zdCBvYmpyZWYgPSBzYW5kYm94LmNyZWF0ZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLkR5bmFtaWNQcm9wZXJ0eUJlYXJlckNoaWxkJyxcbiAgICBhcmdzOiBbb3JpZ2luYWxTdHJpbmddLFxuICAgIG92ZXJyaWRlczogW3sgcHJvcGVydHk6ICdkeW5hbWljUHJvcGVydHknIH1dLFxuICB9KTtcblxuICAvLy8vLy8vLy8vXG4gIC8vIFRIRU5cbiAgLy8vLy8vLy8vL1xuXG4gIC8vIFJlYWRpbmcgdGhlIFwic3VwZXJcIiBwcm9wZXJ0eVxuICBleHBlY3Qoc2FuZGJveC5nZXQoeyBvYmpyZWYsIHByb3BlcnR5OiAnZHluYW1pY1Byb3BlcnR5JyB9KS52YWx1ZSkudG9CZShcbiAgICBvcmlnaW5hbFN0cmluZyxcbiAgKTtcbiAgZXhwZWN0KHNhbmRib3guZ2V0KHsgb2JqcmVmLCBwcm9wZXJ0eTogJ3ZhbHVlU3RvcmUnIH0pLnZhbHVlKS50b0JlKFxuICAgIG9yaWdpbmFsU3RyaW5nLFxuICApO1xuXG4gIC8vIFNldHRpbmcgdGhlIGR5bmFtaWNQcm9wZXJ0eSB2YWx1ZSB0aHJvdWdoIHRoZSBvdmVycmlkZVxuICBleHBlY3QoXG4gICAgc2FuZGJveC5pbnZva2UoeyBvYmpyZWYsIG1ldGhvZDogJ292ZXJyaWRlVmFsdWUnLCBhcmdzOiBbJ04zVyddIH0pLnJlc3VsdCxcbiAgKS50b0JlKGluaXRpYWxPdmVycmlkZGVuUHJvcFZhbHVlKTtcbiAgLy8gQ2hlY2tpbmcgdGhlIHNpZGUgZWZmZWN0IGhhcHBlbmVkIG9uIHRoZSBvdmVycmlkZTpcbiAgZXhwZWN0KHByb3BWYWx1ZSkudG9CZSgnTjNXJyk7XG4gIC8vIENoZWNrIHRoZSBcInN1cGVyXCIgcHJvcGVydHkgZGlkbid0IGNoYW5nZTpcbiAgZXhwZWN0KHNhbmRib3guZ2V0KHsgb2JqcmVmLCBwcm9wZXJ0eTogJ2R5bmFtaWNQcm9wZXJ0eScgfSkudmFsdWUpLnRvQmUoXG4gICAgb3JpZ2luYWxTdHJpbmcsXG4gICk7XG4gIGV4cGVjdChzYW5kYm94LmdldCh7IG9ianJlZiwgcHJvcGVydHk6ICd2YWx1ZVN0b3JlJyB9KS52YWx1ZSkudG9CZShcbiAgICBvcmlnaW5hbFN0cmluZyxcbiAgKTtcblxuICAvLyBTZXQgdGhlIFwic3VwZXJcIiBwcm9wZXJ0eSBub3dcbiAgc2FuZGJveC5zZXQoeyBvYmpyZWYsIHByb3BlcnR5OiAnZHluYW1pY1Byb3BlcnR5JywgdmFsdWU6ICcnIH0pO1xuICAvLyBDaGVjayB0aGUgc2lkZSBlZmZlY3QgbWFkZSBpdCB0byB0aGUgc3RvcmFnZVxuICBleHBlY3Qoc2FuZGJveC5nZXQoeyBvYmpyZWYsIHByb3BlcnR5OiAndmFsdWVTdG9yZScgfSkudmFsdWUpLnRvQmUoJycpO1xuICAvLyBDaGVjayB0aGUgb3ZlcnJpZGRlbiBwcm9wZXJ0eSBkaWRuJ3QgY2hhbmdlLi4uXG4gIGV4cGVjdChwcm9wVmFsdWUpLnRvQmUoJ04zVycpO1xufSk7XG5cbmRlZmluZVRlc3QoJ2ludm9rZUJpblNjcmlwdCgpIHJldHVybiBvdXRwdXQnLCAoc2FuZGJveCkgPT4ge1xuICBjb25zdCByZXN1bHQgPSBzYW5kYm94Lmludm9rZUJpblNjcmlwdCh7XG4gICAgYXNzZW1ibHk6ICdqc2lpLWNhbGMnLFxuICAgIHNjcmlwdDogJ2NhbGMnLFxuICB9KTtcblxuICBleHBlY3QocmVzdWx0LnN0ZG91dCkudG9FcXVhbCgnSGVsbG8gV29ybGQhXFxuJyk7XG4gIGV4cGVjdChyZXN1bHQuc3RkZXJyKS50b0VxdWFsKCcnKTtcbiAgZXhwZWN0KHJlc3VsdC5zdGF0dXMpLnRvRXF1YWwoMCk7XG4gIGV4cGVjdChyZXN1bHQuc2lnbmFsKS50b0JlTnVsbCgpO1xufSk7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuY29uc3QgdGVzdE5hbWVzOiB7IFtuYW1lOiBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ2FsY3VsYXRvclNhbmRib3gobmFtZTogc3RyaW5nKSB7XG4gIGlmIChuYW1lIGluIHRlc3ROYW1lcykge1xuICAgIHRocm93IG5ldyBFcnJvcihgRHVwbGljYXRlIHRlc3QgbmFtZTogJHtuYW1lfWApO1xuICB9XG4gIHRlc3ROYW1lc1tuYW1lXSA9IHRydWU7XG5cbiAgY29uc3QgaW5pdGlhbENhbGxiYWNrSGFuZGxlciA9ICgpID0+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxiYWNrIGludm9rZWQgd2l0aG91dCBhIGNhbGxiYWNrIGhhbmRsZXInKTtcbiAgfTtcbiAgY29uc3Qgc2FuZGJveCA9IG5ldyBLZXJuZWwoaW5pdGlhbENhbGxiYWNrSGFuZGxlcik7XG5cbiAgaWYgKHJlY29yZGluZ091dHB1dCkge1xuICAgIGNvbnN0IGlucHV0T3V0cHV0TG9nUGF0aCA9IGpvaW4ocmVjb3JkaW5nT3V0cHV0LCBgJHtuYW1lfS5sb2dgKTtcbiAgICByZWNvcmRJbnRlcmFjdGlvbihzYW5kYm94LCBpbnB1dE91dHB1dExvZ1BhdGgpO1xuICB9XG5cbiAgc2FuZGJveC50cmFjZUVuYWJsZWQgPSBgJHtwcm9jZXNzLmVudi5KU0lJX0RFQlVHfWAgPT09ICcxJztcblxuICBzYW5kYm94LmxvYWQoe1xuICAgIHRhcmJhbGw6IGF3YWl0IHByZXBhcmVQYWNrYWdlKCdAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZScpLFxuICAgIG5hbWU6ICdAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZScsXG4gICAgdmVyc2lvbjogY2FsY0Jhc2VWZXJzaW9uLFxuICB9KTtcbiAgc2FuZGJveC5sb2FkKHtcbiAgICB0YXJiYWxsOiBhd2FpdCBwcmVwYXJlUGFja2FnZSgnQHNjb3BlL2pzaWktY2FsYy1iYXNlJyksXG4gICAgbmFtZTogJ0BzY29wZS9qc2lpLWNhbGMtYmFzZScsXG4gICAgdmVyc2lvbjogY2FsY0Jhc2VWZXJzaW9uLFxuICB9KTtcbiAgc2FuZGJveC5sb2FkKHtcbiAgICB0YXJiYWxsOiBhd2FpdCBwcmVwYXJlUGFja2FnZSgnQHNjb3BlL2pzaWktY2FsYy1saWInKSxcbiAgICBuYW1lOiAnQHNjb3BlL2pzaWktY2FsYy1saWInLFxuICAgIHZlcnNpb246IGNhbGNMaWJWZXJzaW9uLFxuICB9KTtcbiAgc2FuZGJveC5sb2FkKHtcbiAgICB0YXJiYWxsOiBhd2FpdCBwcmVwYXJlUGFja2FnZSgnanNpaS1jYWxjJyksXG4gICAgbmFtZTogJ2pzaWktY2FsYycsXG4gICAgdmVyc2lvbjogY2FsY1ZlcnNpb24sXG4gIH0pO1xuICByZXR1cm4gc2FuZGJveDtcbn1cblxuY29uc3QgY2FjaGU6IHsgW21vZHVsZTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcblxuYXN5bmMgZnVuY3Rpb24gcHJlcGFyZVBhY2thZ2UobW9kdWxlOiBzdHJpbmcsIHVzZUNhY2hlID0gdHJ1ZSkge1xuICBpZiAobW9kdWxlIGluIGNhY2hlICYmIHVzZUNhY2hlKSB7XG4gICAgcmV0dXJuIGNhY2hlW21vZHVsZV07XG4gIH1cblxuICBjb25zdCBzdGFnaW5nID0gYXdhaXQgZnMubWtkdGVtcChcbiAgICBwYXRoLmpvaW4ob3MudG1wZGlyKCksICdqc2lpLWtlcm5lbC10ZXN0cy0nKSxcbiAgKTtcblxuICAvLyBjbGVhbiB1cCBvbmx5IGlmIHdlIGFyZSBub3QgcmVjb3JkaW5nLCBzbyBwbGF5YmFjayBjYW4gcmVmZXIgdG8gdGhlc2VcbiAgaWYgKCFyZWNvcmRpbmdPdXRwdXQpIHtcbiAgICBwcm9jZXNzLm9uKCdleGl0JywgKCkgPT4gZnMucmVtb3ZlU3luYyhzdGFnaW5nKSk7IC8vIGNsZWFudXBcbiAgfVxuXG4gIGNvbnN0IHBhY2thZ2VSb290ID0gZmluZFBhY2thZ2VSb290KG1vZHVsZSk7XG4gIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChvaywga28pID0+IHtcbiAgICBjb25zdCBjaGlsZCA9IGNoaWxkUHJvY2Vzcy5zcGF3bignbnBtJywgWydwYWNrJywgcGFja2FnZVJvb3RdLCB7XG4gICAgICBjd2Q6IHN0YWdpbmcsXG4gICAgICBzaGVsbDogdHJ1ZSxcbiAgICAgIHN0ZGlvOiBbJ2lnbm9yZScsICdwaXBlJywgJ2lnbm9yZSddLFxuICAgIH0pO1xuICAgIGNvbnN0IHN0ZG91dCA9IG5ldyBBcnJheTxCdWZmZXI+KCk7XG4gICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgKGNodW5rKSA9PiBzdGRvdXQucHVzaChCdWZmZXIuZnJvbShjaHVuaykpKTtcbiAgICBjaGlsZC5vbmNlKCdjbG9zZScsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICAgIGlmIChjb2RlID09PSAwKSB7XG4gICAgICAgIHJldHVybiBvaygpO1xuICAgICAgfVxuICAgICAgaWYgKGNvZGUgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4ga28oYCducG0gcGFjaycgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4ga28oYCducG0gcGFjaycga2lsbGVkIGJ5IHNpZ25hbCAke3NpZ25hbH1gKTtcbiAgICB9KTtcbiAgfSk7XG4gIGNvbnN0IGRpciA9IHBhdGguam9pbihzdGFnaW5nLCAoYXdhaXQgZnMucmVhZGRpcihzdGFnaW5nKSlbMF0pO1xuICByZXR1cm4gKGNhY2hlW21vZHVsZV0gPSBkaXIpO1xufVxuXG5mdW5jdGlvbiBmaW5kUGFja2FnZVJvb3QocGtnOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHBhdGgucmVzb2x2ZShwYXRoLmpvaW4ocmVxdWlyZS5yZXNvbHZlKGAke3BrZ30vcGFja2FnZS5qc29uYCksICcuLicpKTtcbn1cblxuLyoqXG4gKiBzeW5jaHJvbm91cyBvdmVycmlkZXMgYXJlIGltcGxlbWVudGVkIGFzIGEgc2ltcGxlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgZ2V0c1xuICogYWxsIHRoZSBpbmZvcm1hdGlvbiBuZWVkZWQgdG8gcGVyZm9ybSB0aGUgY2FsbGJhY2sgYW5kIHJldHVybiB0aGUgcmVzdWx0LlxuICovXG5mdW5jdGlvbiBtYWtlU3luY0NhbGxiYWNrSGFuZGxlcihsb2dpYzogKGNhbGxiYWNrOiBDYWxsYmFjaykgPT4gYW55KSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGhpczogS2VybmVsLCBjYWxsYmFjazogQ2FsbGJhY2spIHtcbiAgICAvLyBzaW5jZSBzeW5jIGNhbGxiYWNrcyBtdXN0IGJlIGhhbmRsZWQgYXQgaG9zdCBsZXZlbCwgd2Ugd2lsbCBcImZha2VcIlxuICAgIC8vIGhvdyBAanNpaS9ydW50aW1lIGFuZCBhIGNsaWVudCB3aWxsIGludGVyYWN0IHdoZW4gYSBjYWxsYmFjayBpcyByZXF1ZXN0ZWRcbiAgICBjb25zdCByZWNvcmRpbmc6IGZzLldyaXRlU3RyZWFtID0gKHRoaXMgYXMgYW55KS5sb2dmaWxlO1xuXG4gICAgaWYgKHJlY29yZGluZykge1xuICAgICAgLy8gQGpzaWkvcnVudGltZSA9PiBjbGllbnQgKGNhbGxiYWNrIHJlcXVlc3QgZnJvbSB0aGUgcnVudGltZSlcbiAgICAgIHJlY29yZGluZy53cml0ZShgPCAke0pTT04uc3RyaW5naWZ5KHsgY2FsbGJhY2sgfSl9XFxuYCk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gbG9naWMoY2FsbGJhY2spO1xuXG4gICAgaWYgKHJlY29yZGluZykge1xuICAgICAgLy8gY2xpZW50ID0+IEBqc2lpL3J1bnRpbWUgKGNhbGxiYWNrIGNvbXBsZXRpb24gYnkgY2xpZW50KVxuICAgICAgcmVjb3JkaW5nLndyaXRlKFxuICAgICAgICBgPiAke0pTT04uc3RyaW5naWZ5KHsgY29tcGxldGU6IHsgY2JpZDogY2FsbGJhY2suY2JpZCwgcmVzdWx0IH0gfSl9XFxuYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbFdpdGhSZWdleChsdmFsdWU6IGFueSwgcnZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKGx2YWx1ZSA9PT0gcnZhbHVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHR5cGVvZiBsdmFsdWUgPT09ICdzdHJpbmcnICYmIHJ2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgIHJldHVybiBydmFsdWUudGVzdChsdmFsdWUpO1xuICB9XG4gIGlmICh0eXBlb2YgbHZhbHVlICE9PSB0eXBlb2YgcnZhbHVlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KGx2YWx1ZSkgIT09IEFycmF5LmlzQXJyYXkocnZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShsdmFsdWUpIC8qICYmIEFycmF5LmlzQXJyYXkocnZhbHVlKSAqLykge1xuICAgIGlmIChsdmFsdWUubGVuZ3RoICE9PSBydmFsdWUubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIWRlZXBFcXVhbFdpdGhSZWdleChsdmFsdWVbaV0sIHJ2YWx1ZVtpXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAodHlwZW9mIGx2YWx1ZSA9PT0gJ29iamVjdCcgLyogJiYgdHlwZW9mIHJ2YWx1ZSA9PT0gJ29iamVjdCcgKi8pIHtcbiAgICBpZiAobHZhbHVlID09PSBudWxsIHx8IHJ2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgLy8gSWYgYm90aCB3ZXJlIG51bGwsIHRoZXknZCBoYXZlIGJlZW4gPT09XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGtleXMgPSBPYmplY3QuZW50cmllcyhsdmFsdWUpXG4gICAgICAuZmlsdGVyKChbLCB2XSkgPT4gdiAhPSBudWxsKVxuICAgICAgLm1hcCgoW2tdKSA9PiBrKTtcbiAgICBpZiAoa2V5cy5sZW5ndGggIT09IE9iamVjdC5rZXlzKHJ2YWx1ZSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJ2YWx1ZSwga2V5KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIWRlZXBFcXVhbFdpdGhSZWdleChsdmFsdWVba2V5XSwgcnZhbHVlW2tleV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgLy8gTmVpdGhlciBvYmplY3QsIG5vciBhcnJheTogSSBkZWR1Y2UgdGhpcyBpcyBwcmltaXRpdmUgdHlwZVxuICAvLyBQcmltaXRpdmUgdHlwZSBhbmQgbm90ID09PSwgc28gSSBkZWR1Y2Ugbm90IGRlZXBFcXVhbFxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZShrZXJuZWw6IEtlcm5lbCwgZnFuOiBzdHJpbmcpIHtcbiAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIHJldHVybiBrZXJuZWwuY3JlYXRlKHsgZnFuLCBhcmdzIH0pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzZXQoa2VybmVsOiBLZXJuZWwsIG9ianJlZjogT2JqUmVmKSB7XG4gIHJldHVybiAocHJvcGVydHk6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgIHJldHVybiBrZXJuZWwuc2V0KHsgb2JqcmVmLCBwcm9wZXJ0eSwgdmFsdWUgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldChrZXJuZWw6IEtlcm5lbCwgb2JqcmVmOiBPYmpSZWYpIHtcbiAgcmV0dXJuIChwcm9wZXJ0eTogc3RyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGtlcm5lbC5nZXQoeyBvYmpyZWYsIHByb3BlcnR5IH0pLnZhbHVlO1xuICB9O1xufVxuXG4vKipcbiAqIFBhc3NlcyBgaW5wdXRgIHRvIHRoZSBrZXJuZWwgdGhyb3VnaCBhbiBcImFueVwiIHR5cGUgYW5kIHJldHVybnMgdGhlIEpTT05cbiAqIHN0cmluZ2lmaWVkIHZlcnNpb24gdGhhdCB0aGUgSmF2YVNjcmlwdCBjb2RlIHNhdy5cbiAqL1xuZnVuY3Rpb24gZGVzZXJpYWxpemVBbnkoc2FuZGJveDogS2VybmVsLCBpbnB1dDogYW55KSB7XG4gIGNvbnN0IHJldCA9IHNhbmRib3guc2ludm9rZSh7XG4gICAgZnFuOiAnanNpaS1jYWxjLkpzb25Gb3JtYXR0ZXInLFxuICAgIG1ldGhvZDogJ3N0cmluZ2lmeScsXG4gICAgYXJnczogW2lucHV0XSxcbiAgfSk7XG4gIGlmIChyZXQucmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGpzb24gPSBKU09OLnBhcnNlKHJldC5yZXN1bHQpO1xuICByZXR1cm4ganNvbjtcbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplQW55KHNhbmRib3g6IEtlcm5lbCwgbWV0aG9kOiBzdHJpbmcpOiBhbnkge1xuICByZXR1cm4gc2FuZGJveC5zaW52b2tlKHsgZnFuOiAnanNpaS1jYWxjLkpzb25Gb3JtYXR0ZXInLCBtZXRob2QgfSkucmVzdWx0O1xufVxuIl19
|