@appium/test-support 1.3.22 → 1.5.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/README.md +8 -8
- package/build/lib/driver-e2e-suite.d.ts +77 -0
- package/build/lib/driver-e2e-suite.d.ts.map +1 -0
- package/build/lib/driver-e2e-suite.js +389 -0
- package/build/lib/driver-unit-suite.d.ts +12 -0
- package/build/lib/driver-unit-suite.d.ts.map +1 -0
- package/build/lib/driver-unit-suite.js +564 -0
- package/build/lib/env-utils.d.ts +5 -0
- package/build/lib/env-utils.d.ts.map +1 -0
- package/build/lib/env-utils.js +3 -6
- package/build/lib/helpers.d.ts +19 -0
- package/build/lib/helpers.d.ts.map +1 -0
- package/build/lib/helpers.js +49 -0
- package/build/lib/index.d.ts +12 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +59 -2
- package/build/lib/log-utils.d.ts +34 -0
- package/build/lib/log-utils.d.ts.map +1 -0
- package/build/lib/log-utils.js +4 -8
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +2 -2
- package/build/lib/mock-utils.d.ts +47 -0
- package/build/lib/mock-utils.d.ts.map +1 -0
- package/build/lib/mock-utils.js +57 -29
- package/build/lib/plugin-e2e-harness.d.ts +67 -0
- package/build/lib/plugin-e2e-harness.d.ts.map +1 -0
- package/build/lib/plugin-e2e-harness.js +144 -0
- package/build/lib/sandbox-utils.d.ts +41 -0
- package/build/lib/sandbox-utils.d.ts.map +1 -0
- package/build/lib/sandbox-utils.js +46 -29
- package/build/lib/time-utils.d.ts +9 -0
- package/build/lib/time-utils.d.ts.map +1 -0
- package/build/lib/time-utils.js +1 -1
- package/build/lib/unhandled-rejection.d.ts +2 -0
- package/build/lib/unhandled-rejection.d.ts.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/lib/driver-e2e-suite.js +465 -0
- package/lib/driver-unit-suite.js +642 -0
- package/lib/env-utils.js +5 -3
- package/lib/helpers.js +68 -0
- package/lib/index.js +17 -7
- package/lib/log-utils.js +25 -8
- package/lib/logger.js +1 -1
- package/lib/mock-utils.js +89 -25
- package/lib/plugin-e2e-harness.js +163 -0
- package/lib/sandbox-utils.js +70 -26
- package/lib/time-utils.js +1 -0
- package/package.json +15 -6
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.driverUnitTestSuite = driverUnitTestSuite;
|
|
9
|
+
|
|
10
|
+
require("source-map-support/register");
|
|
11
|
+
|
|
12
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
13
|
+
|
|
14
|
+
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
15
|
+
|
|
16
|
+
var _baseDriver = require("@appium/base-driver");
|
|
17
|
+
|
|
18
|
+
var _sinon = require("sinon");
|
|
19
|
+
|
|
20
|
+
var _chai = _interopRequireDefault(require("chai"));
|
|
21
|
+
|
|
22
|
+
const should = _chai.default.should();
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
expect
|
|
26
|
+
} = _chai.default;
|
|
27
|
+
|
|
28
|
+
function driverUnitTestSuite(DriverClass, defaultCaps = {}) {
|
|
29
|
+
const className = DriverClass.name ?? '(unknown driver)';
|
|
30
|
+
describe(`BaseDriver unit suite (as ${className})`, function () {
|
|
31
|
+
let d;
|
|
32
|
+
let w3cCaps;
|
|
33
|
+
let sandbox;
|
|
34
|
+
beforeEach(function () {
|
|
35
|
+
sandbox = (0, _sinon.createSandbox)();
|
|
36
|
+
d = new DriverClass();
|
|
37
|
+
w3cCaps = {
|
|
38
|
+
alwaysMatch: { ...defaultCaps,
|
|
39
|
+
platformName: 'Fake',
|
|
40
|
+
'appium:deviceName': 'Commodore 64'
|
|
41
|
+
},
|
|
42
|
+
firstMatch: [{}]
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
afterEach(async function () {
|
|
46
|
+
sandbox.restore();
|
|
47
|
+
await d.deleteSession();
|
|
48
|
+
});
|
|
49
|
+
describe('static property', function () {
|
|
50
|
+
describe('baseVersion', function () {
|
|
51
|
+
it('should exist', function () {
|
|
52
|
+
DriverClass.baseVersion.should.exist;
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe('Log prefix', function () {
|
|
57
|
+
it('should setup log prefix', async function () {
|
|
58
|
+
const d = new DriverClass();
|
|
59
|
+
const previousPrefix = d.log.prefix;
|
|
60
|
+
await d.createSession({
|
|
61
|
+
alwaysMatch: { ...defaultCaps,
|
|
62
|
+
platformName: 'Fake',
|
|
63
|
+
'appium:deviceName': 'Commodore 64'
|
|
64
|
+
},
|
|
65
|
+
firstMatch: [{}]
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
expect(previousPrefix).not.to.eql(d.log.prefix);
|
|
70
|
+
} finally {
|
|
71
|
+
await d.deleteSession();
|
|
72
|
+
expect(previousPrefix).to.eql(d.log.prefix);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it('should return an empty status object', async function () {
|
|
77
|
+
let status = await d.getStatus();
|
|
78
|
+
status.should.eql({});
|
|
79
|
+
});
|
|
80
|
+
it('should return a sessionId from createSession', async function () {
|
|
81
|
+
let [sessId] = await d.createSession(w3cCaps);
|
|
82
|
+
should.exist(sessId);
|
|
83
|
+
sessId.should.be.a('string');
|
|
84
|
+
sessId.length.should.be.above(5);
|
|
85
|
+
});
|
|
86
|
+
it('should not be able to start two sessions without closing the first', async function () {
|
|
87
|
+
await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
88
|
+
await d.createSession(_lodash.default.cloneDeep(w3cCaps)).should.be.rejectedWith('session');
|
|
89
|
+
});
|
|
90
|
+
it('should be able to delete a session', async function () {
|
|
91
|
+
let sessionId1 = await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
92
|
+
await d.deleteSession();
|
|
93
|
+
should.equal(d.sessionId, null);
|
|
94
|
+
let sessionId2 = await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
95
|
+
sessionId1.should.not.eql(sessionId2);
|
|
96
|
+
});
|
|
97
|
+
it('should get the current session', async function () {
|
|
98
|
+
let [, caps] = await d.createSession(w3cCaps);
|
|
99
|
+
caps.should.equal(await d.getSession());
|
|
100
|
+
});
|
|
101
|
+
it('should return sessions if no session exists', async function () {
|
|
102
|
+
let sessions = await d.getSessions();
|
|
103
|
+
sessions.length.should.equal(0);
|
|
104
|
+
});
|
|
105
|
+
it('should return sessions', async function () {
|
|
106
|
+
const caps = _lodash.default.cloneDeep(w3cCaps);
|
|
107
|
+
|
|
108
|
+
await d.createSession(caps);
|
|
109
|
+
let sessions = await d.getSessions();
|
|
110
|
+
sessions.length.should.equal(1);
|
|
111
|
+
sessions[0].should.include({
|
|
112
|
+
id: d.sessionId
|
|
113
|
+
});
|
|
114
|
+
sessions[0].capabilities.should.include({
|
|
115
|
+
deviceName: 'Commodore 64',
|
|
116
|
+
platformName: 'Fake'
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
it('should fulfill an unexpected driver quit promise', async function () {
|
|
120
|
+
sandbox.stub(d, 'getStatus').callsFake(async () => {
|
|
121
|
+
await _bluebird.default.delay(1000);
|
|
122
|
+
return 'good status';
|
|
123
|
+
});
|
|
124
|
+
let cmdPromise = d.executeCommand('getStatus');
|
|
125
|
+
await _bluebird.default.delay(10);
|
|
126
|
+
const p = new _bluebird.default((resolve, reject) => {
|
|
127
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
128
|
+
d.onUnexpectedShutdown(resolve);
|
|
129
|
+
});
|
|
130
|
+
d.startUnexpectedShutdown(new Error('We crashed'));
|
|
131
|
+
await cmdPromise.should.be.rejectedWith(/We crashed/);
|
|
132
|
+
await p;
|
|
133
|
+
});
|
|
134
|
+
it('should not allow commands in middle of unexpected shutdown', async function () {
|
|
135
|
+
sandbox.stub(d, 'deleteSession').callsFake(async function () {
|
|
136
|
+
await _bluebird.default.delay(100);
|
|
137
|
+
DriverClass.prototype.deleteSession.call(this);
|
|
138
|
+
});
|
|
139
|
+
await d.createSession(w3cCaps);
|
|
140
|
+
const p = new _bluebird.default((resolve, reject) => {
|
|
141
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
142
|
+
d.onUnexpectedShutdown(resolve);
|
|
143
|
+
});
|
|
144
|
+
d.startUnexpectedShutdown(new Error('We crashed'));
|
|
145
|
+
await p;
|
|
146
|
+
await d.executeCommand('getSession').should.be.rejectedWith(/shut down/);
|
|
147
|
+
});
|
|
148
|
+
it('should allow new commands after done shutting down', async function () {
|
|
149
|
+
sandbox.stub(d, 'deleteSession').callsFake(async function () {
|
|
150
|
+
await _bluebird.default.delay(100);
|
|
151
|
+
DriverClass.prototype.deleteSession.call(this);
|
|
152
|
+
});
|
|
153
|
+
await d.createSession(_lodash.default.cloneDeep(w3cCaps));
|
|
154
|
+
const p = new _bluebird.default((resolve, reject) => {
|
|
155
|
+
setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);
|
|
156
|
+
d.onUnexpectedShutdown(resolve);
|
|
157
|
+
});
|
|
158
|
+
d.startUnexpectedShutdown(new Error('We crashed'));
|
|
159
|
+
await p;
|
|
160
|
+
await d.executeCommand('getSession').should.be.rejectedWith(/shut down/);
|
|
161
|
+
await _bluebird.default.delay(500);
|
|
162
|
+
await d.executeCommand('createSession', null, null, _lodash.default.cloneDeep(w3cCaps));
|
|
163
|
+
await d.deleteSession();
|
|
164
|
+
});
|
|
165
|
+
it('should distinguish between W3C and JSONWP session', async function () {
|
|
166
|
+
await d.executeCommand('createSession', null, null, {
|
|
167
|
+
alwaysMatch: { ...defaultCaps,
|
|
168
|
+
platformName: 'Fake',
|
|
169
|
+
'appium:deviceName': 'Commodore 64'
|
|
170
|
+
},
|
|
171
|
+
firstMatch: [{}]
|
|
172
|
+
});
|
|
173
|
+
expect(d.protocol).to.equal('W3C');
|
|
174
|
+
});
|
|
175
|
+
describe('protocol detection', function () {
|
|
176
|
+
it('should use W3C if only W3C caps are provided', async function () {
|
|
177
|
+
await d.createSession({
|
|
178
|
+
alwaysMatch: _lodash.default.clone(defaultCaps),
|
|
179
|
+
firstMatch: [{}]
|
|
180
|
+
});
|
|
181
|
+
expect(d.protocol).to.equal('W3C');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
it('should have a method to get driver for a session', async function () {
|
|
185
|
+
let [sessId] = await d.createSession(w3cCaps);
|
|
186
|
+
expect(d.driverForSession(sessId)).to.eql(d);
|
|
187
|
+
});
|
|
188
|
+
describe('command queue', function () {
|
|
189
|
+
let d;
|
|
190
|
+
let waitMs = 10;
|
|
191
|
+
beforeEach(function () {
|
|
192
|
+
d = new DriverClass();
|
|
193
|
+
sandbox.stub(d, 'getStatus').callsFake(async () => {
|
|
194
|
+
await _bluebird.default.delay(waitMs);
|
|
195
|
+
return Date.now();
|
|
196
|
+
});
|
|
197
|
+
sandbox.stub(d, 'getSessions').callsFake(async () => {
|
|
198
|
+
await _bluebird.default.delay(waitMs);
|
|
199
|
+
throw new Error('multipass');
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
afterEach(async function () {
|
|
203
|
+
await d.clearNewCommandTimeout();
|
|
204
|
+
});
|
|
205
|
+
it('should queue commands and.executeCommand/respond in the order received', async function () {
|
|
206
|
+
let numCmds = 10;
|
|
207
|
+
let cmds = [];
|
|
208
|
+
|
|
209
|
+
for (let i = 0; i < numCmds; i++) {
|
|
210
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let results = await _bluebird.default.all(cmds);
|
|
214
|
+
|
|
215
|
+
for (let i = 1; i < numCmds; i++) {
|
|
216
|
+
if (results[i] <= results[i - 1]) {
|
|
217
|
+
throw new Error('Got result out of order');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
it('should handle errors correctly when queuing', async function () {
|
|
222
|
+
let numCmds = 10;
|
|
223
|
+
let cmds = [];
|
|
224
|
+
|
|
225
|
+
for (let i = 0; i < numCmds; i++) {
|
|
226
|
+
if (i === 5) {
|
|
227
|
+
cmds.push(d.executeCommand('getSessions'));
|
|
228
|
+
} else {
|
|
229
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
let results = await Promise.allSettled(cmds);
|
|
234
|
+
|
|
235
|
+
for (let i = 1; i < 5; i++) {
|
|
236
|
+
if (results[i].value <= results[i - 1].value) {
|
|
237
|
+
throw new Error('Got result out of order');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
results[5].reason.message.should.contain('multipass');
|
|
242
|
+
|
|
243
|
+
for (let i = 7; i < numCmds; i++) {
|
|
244
|
+
if (results[i].value <= results[i - 1].value) {
|
|
245
|
+
throw new Error('Got result out of order');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
it('should not care if queue empties for a bit', async function () {
|
|
250
|
+
let numCmds = 10;
|
|
251
|
+
let cmds = [];
|
|
252
|
+
|
|
253
|
+
for (let i = 0; i < numCmds; i++) {
|
|
254
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
let results = await _bluebird.default.all(cmds);
|
|
258
|
+
cmds = [];
|
|
259
|
+
|
|
260
|
+
for (let i = 0; i < numCmds; i++) {
|
|
261
|
+
cmds.push(d.executeCommand('getStatus'));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
results = await _bluebird.default.all(cmds);
|
|
265
|
+
|
|
266
|
+
for (let i = 1; i < numCmds; i++) {
|
|
267
|
+
if (results[i] <= results[i - 1]) {
|
|
268
|
+
throw new Error('Got result out of order');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
describe('timeouts', function () {
|
|
274
|
+
before(async function () {
|
|
275
|
+
await d.createSession(w3cCaps);
|
|
276
|
+
});
|
|
277
|
+
describe('command', function () {
|
|
278
|
+
it('should exist by default', function () {
|
|
279
|
+
d.newCommandTimeoutMs.should.equal(60000);
|
|
280
|
+
});
|
|
281
|
+
it('should be settable through `timeouts`', async function () {
|
|
282
|
+
await d.timeouts('command', 20);
|
|
283
|
+
d.newCommandTimeoutMs.should.equal(20);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
describe('implicit', function () {
|
|
287
|
+
it('should not exist by default', function () {
|
|
288
|
+
d.implicitWaitMs.should.equal(0);
|
|
289
|
+
});
|
|
290
|
+
it('should be settable through `timeouts`', async function () {
|
|
291
|
+
await d.timeouts('implicit', 20);
|
|
292
|
+
d.implicitWaitMs.should.equal(20);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
describe('timeouts (W3C)', function () {
|
|
297
|
+
beforeEach(async function () {
|
|
298
|
+
await d.createSession(w3cCaps);
|
|
299
|
+
});
|
|
300
|
+
afterEach(async function () {
|
|
301
|
+
await d.deleteSession();
|
|
302
|
+
});
|
|
303
|
+
it('should get timeouts that we set', async function () {
|
|
304
|
+
await d.timeouts(undefined, undefined, undefined, undefined, 1000);
|
|
305
|
+
await d.getTimeouts().should.eventually.have.property('implicit', 1000);
|
|
306
|
+
await d.timeouts('command', 2000);
|
|
307
|
+
await d.getTimeouts().should.eventually.deep.equal({
|
|
308
|
+
implicit: 1000,
|
|
309
|
+
command: 2000
|
|
310
|
+
});
|
|
311
|
+
await d.timeouts(undefined, undefined, undefined, undefined, 3000);
|
|
312
|
+
await d.getTimeouts().should.eventually.deep.equal({
|
|
313
|
+
implicit: 3000,
|
|
314
|
+
command: 2000
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
describe('reset compatibility', function () {
|
|
319
|
+
it('should not allow both fullReset and noReset to be true', async function () {
|
|
320
|
+
const newCaps = {
|
|
321
|
+
alwaysMatch: { ...defaultCaps,
|
|
322
|
+
platformName: 'Fake',
|
|
323
|
+
'appium:deviceName': 'Commodore 64',
|
|
324
|
+
'appium:fullReset': true,
|
|
325
|
+
'appium:noReset': true
|
|
326
|
+
},
|
|
327
|
+
firstMatch: [{}]
|
|
328
|
+
};
|
|
329
|
+
await d.createSession(newCaps).should.be.rejectedWith(/noReset.+fullReset/);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
describe('proxying', function () {
|
|
333
|
+
let sessId;
|
|
334
|
+
beforeEach(async function () {
|
|
335
|
+
[sessId] = await d.createSession(w3cCaps);
|
|
336
|
+
});
|
|
337
|
+
describe('#proxyActive', function () {
|
|
338
|
+
it('should exist', function () {
|
|
339
|
+
d.proxyActive.should.be.an.instanceof(Function);
|
|
340
|
+
});
|
|
341
|
+
it('should return false', function () {
|
|
342
|
+
d.proxyActive(sessId).should.be.false;
|
|
343
|
+
});
|
|
344
|
+
it('should throw an error when sessionId is wrong', function () {
|
|
345
|
+
(() => {
|
|
346
|
+
d.proxyActive('aaa');
|
|
347
|
+
}).should.throw;
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
describe('#getProxyAvoidList', function () {
|
|
351
|
+
it('should exist', function () {
|
|
352
|
+
d.getProxyAvoidList.should.be.an.instanceof(Function);
|
|
353
|
+
});
|
|
354
|
+
it('should return an array', function () {
|
|
355
|
+
d.getProxyAvoidList(sessId).should.be.an.instanceof(Array);
|
|
356
|
+
});
|
|
357
|
+
it('should throw an error when sessionId is wrong', function () {
|
|
358
|
+
(() => {
|
|
359
|
+
d.getProxyAvoidList('aaa');
|
|
360
|
+
}).should.throw;
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
describe('#canProxy', function () {
|
|
364
|
+
it('should have a #canProxy method', function () {
|
|
365
|
+
d.canProxy.should.be.an.instanceof(Function);
|
|
366
|
+
});
|
|
367
|
+
it('should return a boolean from #canProxy', function () {
|
|
368
|
+
d.canProxy(sessId).should.be.a('boolean');
|
|
369
|
+
});
|
|
370
|
+
it('should throw an error when sessionId is wrong', function () {
|
|
371
|
+
(() => {
|
|
372
|
+
d.canProxy();
|
|
373
|
+
}).should.throw;
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
describe('#proxyRouteIsAvoided', function () {
|
|
377
|
+
it('should validate form of avoidance list', function () {
|
|
378
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
379
|
+
avoidStub.returns([['POST', /\/foo/], ['GET']]);
|
|
380
|
+
(() => {
|
|
381
|
+
d.proxyRouteIsAvoided();
|
|
382
|
+
}).should.throw;
|
|
383
|
+
avoidStub.returns([['POST', /\/foo/], ['GET', /^foo/, 'bar']]);
|
|
384
|
+
(() => {
|
|
385
|
+
d.proxyRouteIsAvoided();
|
|
386
|
+
}).should.throw;
|
|
387
|
+
});
|
|
388
|
+
it('should reject bad http methods', function () {
|
|
389
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
390
|
+
avoidStub.returns([['POST', /^foo/], ['BAZETE', /^bar/]]);
|
|
391
|
+
(() => {
|
|
392
|
+
d.proxyRouteIsAvoided();
|
|
393
|
+
}).should.throw;
|
|
394
|
+
});
|
|
395
|
+
it('should reject non-regex routes', function () {
|
|
396
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
397
|
+
avoidStub.returns([['POST', /^foo/], ['GET', '/bar']]);
|
|
398
|
+
(() => {
|
|
399
|
+
d.proxyRouteIsAvoided();
|
|
400
|
+
}).should.throw;
|
|
401
|
+
});
|
|
402
|
+
it('should return true for routes in the avoid list', function () {
|
|
403
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
404
|
+
avoidStub.returns([['POST', /^\/foo/]]);
|
|
405
|
+
d.proxyRouteIsAvoided('foo', 'POST', '/foo/bar').should.be.true;
|
|
406
|
+
});
|
|
407
|
+
it('should strip away any wd/hub prefix', function () {
|
|
408
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
409
|
+
avoidStub.returns([['POST', /^\/foo/]]);
|
|
410
|
+
d.proxyRouteIsAvoided('foo', 'POST', '/foo/bar').should.be.true;
|
|
411
|
+
});
|
|
412
|
+
it('should return false for routes not in the avoid list', function () {
|
|
413
|
+
const avoidStub = sandbox.stub(d, 'getProxyAvoidList');
|
|
414
|
+
avoidStub.returns([['POST', /^\/foo/]]);
|
|
415
|
+
d.proxyRouteIsAvoided('foo', 'GET', '/foo/bar').should.be.false;
|
|
416
|
+
d.proxyRouteIsAvoided('foo', 'POST', '/boo').should.be.false;
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
describe('event timing framework', function () {
|
|
421
|
+
let beforeStartTime;
|
|
422
|
+
beforeEach(async function () {
|
|
423
|
+
beforeStartTime = Date.now();
|
|
424
|
+
d.shouldValidateCaps = false;
|
|
425
|
+
await d.executeCommand('createSession', null, null, {
|
|
426
|
+
alwaysMatch: { ...defaultCaps
|
|
427
|
+
},
|
|
428
|
+
firstMatch: [{}]
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
describe('#eventHistory', function () {
|
|
432
|
+
it('should have an eventHistory property', function () {
|
|
433
|
+
should.exist(d.eventHistory);
|
|
434
|
+
should.exist(d.eventHistory.commands);
|
|
435
|
+
});
|
|
436
|
+
it('should have a session start timing after session start', function () {
|
|
437
|
+
let {
|
|
438
|
+
newSessionRequested,
|
|
439
|
+
newSessionStarted
|
|
440
|
+
} = d.eventHistory;
|
|
441
|
+
newSessionRequested.should.have.length(1);
|
|
442
|
+
newSessionStarted.should.have.length(1);
|
|
443
|
+
newSessionRequested[0].should.be.a('number');
|
|
444
|
+
newSessionStarted[0].should.be.a('number');
|
|
445
|
+
(newSessionRequested[0] >= beforeStartTime).should.be.true;
|
|
446
|
+
(newSessionStarted[0] >= newSessionRequested[0]).should.be.true;
|
|
447
|
+
});
|
|
448
|
+
it('should include a commands list', async function () {
|
|
449
|
+
await d.executeCommand('getStatus', []);
|
|
450
|
+
d.eventHistory.commands.length.should.equal(2);
|
|
451
|
+
d.eventHistory.commands[1].cmd.should.equal('getStatus');
|
|
452
|
+
d.eventHistory.commands[1].startTime.should.be.a('number');
|
|
453
|
+
d.eventHistory.commands[1].endTime.should.be.a('number');
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
describe('#logEvent', function () {
|
|
457
|
+
it('should allow logging arbitrary events', function () {
|
|
458
|
+
d.logEvent('foo');
|
|
459
|
+
d.eventHistory.foo[0].should.be.a('number');
|
|
460
|
+
(d.eventHistory.foo[0] >= beforeStartTime).should.be.true;
|
|
461
|
+
});
|
|
462
|
+
it('should not allow reserved or oddly formed event names', function () {
|
|
463
|
+
(() => {
|
|
464
|
+
d.logEvent('commands');
|
|
465
|
+
}).should.throw();
|
|
466
|
+
(() => {
|
|
467
|
+
d.logEvent(1);
|
|
468
|
+
}).should.throw();
|
|
469
|
+
(() => {
|
|
470
|
+
d.logEvent({});
|
|
471
|
+
}).should.throw();
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
it('should allow logging the same event multiple times', function () {
|
|
475
|
+
d.logEvent('bar');
|
|
476
|
+
d.logEvent('bar');
|
|
477
|
+
d.eventHistory.bar.should.have.length(2);
|
|
478
|
+
d.eventHistory.bar[1].should.be.a('number');
|
|
479
|
+
(d.eventHistory.bar[1] >= d.eventHistory.bar[0]).should.be.true;
|
|
480
|
+
});
|
|
481
|
+
describe('getSession decoration', function () {
|
|
482
|
+
it('should decorate getSession response if opt-in cap is provided', async function () {
|
|
483
|
+
var _res$events, _res$events2;
|
|
484
|
+
|
|
485
|
+
let res = await d.getSession();
|
|
486
|
+
should.not.exist(res.events);
|
|
487
|
+
|
|
488
|
+
_lodash.default.set(d, 'caps.eventTimings', true);
|
|
489
|
+
|
|
490
|
+
res = await d.getSession();
|
|
491
|
+
should.exist(res.events);
|
|
492
|
+
should.exist((_res$events = res.events) === null || _res$events === void 0 ? void 0 : _res$events.newSessionRequested);
|
|
493
|
+
expect((_res$events2 = res.events) === null || _res$events2 === void 0 ? void 0 : _res$events2.newSessionRequested[0]).to.be.a('number');
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
describe('.reset', function () {
|
|
498
|
+
it('should reset as W3C if the original session was W3C', async function () {
|
|
499
|
+
const caps = {
|
|
500
|
+
alwaysMatch: {
|
|
501
|
+
'appium:app': 'Fake',
|
|
502
|
+
'appium:deviceName': 'Fake',
|
|
503
|
+
'appium:automationName': 'Fake',
|
|
504
|
+
platformName: 'Fake',
|
|
505
|
+
...defaultCaps
|
|
506
|
+
},
|
|
507
|
+
firstMatch: [{}]
|
|
508
|
+
};
|
|
509
|
+
await d.createSession(caps);
|
|
510
|
+
expect(d.protocol).to.equal('W3C');
|
|
511
|
+
await d.reset();
|
|
512
|
+
expect(d.protocol).to.equal('W3C');
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
describe('DeviceSettings', function () {
|
|
517
|
+
it('should not hold on to reference of defaults in constructor', function () {
|
|
518
|
+
let obj = {
|
|
519
|
+
foo: 'bar'
|
|
520
|
+
};
|
|
521
|
+
let d1 = new _baseDriver.DeviceSettings(obj);
|
|
522
|
+
let d2 = new _baseDriver.DeviceSettings(obj);
|
|
523
|
+
d1.getSettings().foo = 'baz';
|
|
524
|
+
d1.getSettings().should.not.eql(d2.getSettings());
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
describe('.isFeatureEnabled', function () {
|
|
528
|
+
let d;
|
|
529
|
+
beforeEach(function () {
|
|
530
|
+
d = new DriverClass();
|
|
531
|
+
});
|
|
532
|
+
it('should say a feature is enabled when it is explicitly allowed', function () {
|
|
533
|
+
d.allowInsecure = ['foo', 'bar'];
|
|
534
|
+
d.isFeatureEnabled('foo').should.be.true;
|
|
535
|
+
d.isFeatureEnabled('bar').should.be.true;
|
|
536
|
+
d.isFeatureEnabled('baz').should.be.false;
|
|
537
|
+
});
|
|
538
|
+
it('should say a feature is not enabled if it is not enabled', function () {
|
|
539
|
+
d.allowInsecure = [];
|
|
540
|
+
d.isFeatureEnabled('foo').should.be.false;
|
|
541
|
+
});
|
|
542
|
+
it('should prefer denyInsecure to allowInsecure', function () {
|
|
543
|
+
d.allowInsecure = ['foo', 'bar'];
|
|
544
|
+
d.denyInsecure = ['foo'];
|
|
545
|
+
d.isFeatureEnabled('foo').should.be.false;
|
|
546
|
+
d.isFeatureEnabled('bar').should.be.true;
|
|
547
|
+
d.isFeatureEnabled('baz').should.be.false;
|
|
548
|
+
});
|
|
549
|
+
it('should allow global setting for insecurity', function () {
|
|
550
|
+
d.relaxedSecurityEnabled = true;
|
|
551
|
+
d.isFeatureEnabled('foo').should.be.true;
|
|
552
|
+
d.isFeatureEnabled('bar').should.be.true;
|
|
553
|
+
d.isFeatureEnabled('baz').should.be.true;
|
|
554
|
+
});
|
|
555
|
+
it('global setting should be overrideable', function () {
|
|
556
|
+
d.relaxedSecurityEnabled = true;
|
|
557
|
+
d.denyInsecure = ['foo', 'bar'];
|
|
558
|
+
d.isFeatureEnabled('foo').should.be.false;
|
|
559
|
+
d.isFeatureEnabled('bar').should.be.false;
|
|
560
|
+
d.isFeatureEnabled('baz').should.be.true;
|
|
561
|
+
});
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzaG91bGQiLCJjaGFpIiwiZXhwZWN0IiwiZHJpdmVyVW5pdFRlc3RTdWl0ZSIsIkRyaXZlckNsYXNzIiwiZGVmYXVsdENhcHMiLCJjbGFzc05hbWUiLCJuYW1lIiwiZGVzY3JpYmUiLCJkIiwidzNjQ2FwcyIsInNhbmRib3giLCJiZWZvcmVFYWNoIiwiY3JlYXRlU2FuZGJveCIsImFsd2F5c01hdGNoIiwicGxhdGZvcm1OYW1lIiwiZmlyc3RNYXRjaCIsImFmdGVyRWFjaCIsInJlc3RvcmUiLCJkZWxldGVTZXNzaW9uIiwiaXQiLCJiYXNlVmVyc2lvbiIsImV4aXN0IiwicHJldmlvdXNQcmVmaXgiLCJsb2ciLCJwcmVmaXgiLCJjcmVhdGVTZXNzaW9uIiwibm90IiwidG8iLCJlcWwiLCJzdGF0dXMiLCJnZXRTdGF0dXMiLCJzZXNzSWQiLCJiZSIsImEiLCJsZW5ndGgiLCJhYm92ZSIsIl8iLCJjbG9uZURlZXAiLCJyZWplY3RlZFdpdGgiLCJzZXNzaW9uSWQxIiwiZXF1YWwiLCJzZXNzaW9uSWQiLCJzZXNzaW9uSWQyIiwiY2FwcyIsImdldFNlc3Npb24iLCJzZXNzaW9ucyIsImdldFNlc3Npb25zIiwiaW5jbHVkZSIsImlkIiwiY2FwYWJpbGl0aWVzIiwiZGV2aWNlTmFtZSIsInN0dWIiLCJjYWxsc0Zha2UiLCJCIiwiZGVsYXkiLCJjbWRQcm9taXNlIiwiZXhlY3V0ZUNvbW1hbmQiLCJwIiwicmVzb2x2ZSIsInJlamVjdCIsInNldFRpbWVvdXQiLCJFcnJvciIsIm9uVW5leHBlY3RlZFNodXRkb3duIiwic3RhcnRVbmV4cGVjdGVkU2h1dGRvd24iLCJwcm90b3R5cGUiLCJjYWxsIiwicHJvdG9jb2wiLCJjbG9uZSIsImRyaXZlckZvclNlc3Npb24iLCJ3YWl0TXMiLCJEYXRlIiwibm93IiwiY2xlYXJOZXdDb21tYW5kVGltZW91dCIsIm51bUNtZHMiLCJjbWRzIiwiaSIsInB1c2giLCJyZXN1bHRzIiwiYWxsIiwiUHJvbWlzZSIsImFsbFNldHRsZWQiLCJ2YWx1ZSIsInJlYXNvbiIsIm1lc3NhZ2UiLCJjb250YWluIiwiYmVmb3JlIiwibmV3Q29tbWFuZFRpbWVvdXRNcyIsInRpbWVvdXRzIiwiaW1wbGljaXRXYWl0TXMiLCJ1bmRlZmluZWQiLCJnZXRUaW1lb3V0cyIsImV2ZW50dWFsbHkiLCJoYXZlIiwicHJvcGVydHkiLCJkZWVwIiwiaW1wbGljaXQiLCJjb21tYW5kIiwibmV3Q2FwcyIsInByb3h5QWN0aXZlIiwiYW4iLCJpbnN0YW5jZW9mIiwiRnVuY3Rpb24iLCJmYWxzZSIsInRocm93IiwiZ2V0UHJveHlBdm9pZExpc3QiLCJBcnJheSIsImNhblByb3h5IiwiYXZvaWRTdHViIiwicmV0dXJucyIsInByb3h5Um91dGVJc0F2b2lkZWQiLCJ0cnVlIiwiYmVmb3JlU3RhcnRUaW1lIiwic2hvdWxkVmFsaWRhdGVDYXBzIiwiZXZlbnRIaXN0b3J5IiwiY29tbWFuZHMiLCJuZXdTZXNzaW9uUmVxdWVzdGVkIiwibmV3U2Vzc2lvblN0YXJ0ZWQiLCJjbWQiLCJzdGFydFRpbWUiLCJlbmRUaW1lIiwibG9nRXZlbnQiLCJmb28iLCJiYXIiLCJyZXMiLCJldmVudHMiLCJzZXQiLCJyZXNldCIsIm9iaiIsImQxIiwiRGV2aWNlU2V0dGluZ3MiLCJkMiIsImdldFNldHRpbmdzIiwiYWxsb3dJbnNlY3VyZSIsImlzRmVhdHVyZUVuYWJsZWQiLCJkZW55SW5zZWN1cmUiLCJyZWxheGVkU2VjdXJpdHlFbmFibGVkIl0sInNvdXJjZXMiOlsiLi4vLi4vbGliL2RyaXZlci11bml0LXN1aXRlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQge0RldmljZVNldHRpbmdzfSBmcm9tICdAYXBwaXVtL2Jhc2UtZHJpdmVyJztcbmltcG9ydCB7Y3JlYXRlU2FuZGJveH0gZnJvbSAnc2lub24nO1xuXG5pbXBvcnQgY2hhaSBmcm9tICdjaGFpJztcblxuY29uc3Qgc2hvdWxkID0gY2hhaS5zaG91bGQoKTtcbmNvbnN0IHtleHBlY3R9ID0gY2hhaTtcblxuLy8gd3JhcCB0aGVzZSB0ZXN0cyBpbiBhIGZ1bmN0aW9uIHNvIHdlIGNhbiBleHBvcnQgdGhlIHRlc3RzIGFuZCByZS11c2UgdGhlbVxuLy8gZm9yIGFjdHVhbCBkcml2ZXIgaW1wbGVtZW50YXRpb25zXG5cbi8qKlxuICogQ3JlYXRlcyB1bml0IHRlc3Qgc3VpdGVzIGZvciBhIGRyaXZlci5cbiAqIEBwYXJhbSB7RHJpdmVyQ2xhc3N9IERyaXZlckNsYXNzXG4gKiBAcGFyYW0ge0FwcGl1bVczQ0NhcGFiaWxpdGllc30gW2RlZmF1bHRDYXBzXVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkcml2ZXJVbml0VGVzdFN1aXRlKERyaXZlckNsYXNzLCBkZWZhdWx0Q2FwcyA9IHt9KSB7XG4gIC8vIHRvIGRpc3BsYXkgdGhlIGRyaXZlciB1bmRlciB0ZXN0IGluIHJlcG9ydFxuICBjb25zdCBjbGFzc05hbWUgPSBEcml2ZXJDbGFzcy5uYW1lID8/ICcodW5rbm93biBkcml2ZXIpJztcblxuICBkZXNjcmliZShgQmFzZURyaXZlciB1bml0IHN1aXRlIChhcyAke2NsYXNzTmFtZX0pYCwgZnVuY3Rpb24gKCkge1xuICAgIC8qKiBAdHlwZSB7SW5zdGFuY2VUeXBlPHR5cGVvZiBEcml2ZXJDbGFzcz59ICovXG4gICAgbGV0IGQ7XG4gICAgLyoqIEB0eXBlIHtXM0NDYXBhYmlsaXRpZXN9ICovXG4gICAgbGV0IHczY0NhcHM7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoJ3Npbm9uJykuU2lub25TYW5kYm94fSAqL1xuICAgIGxldCBzYW5kYm94O1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94ID0gY3JlYXRlU2FuZGJveCgpO1xuICAgICAgZCA9IG5ldyBEcml2ZXJDbGFzcygpO1xuICAgICAgdzNjQ2FwcyA9IHtcbiAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAuLi5kZWZhdWx0Q2FwcyxcbiAgICAgICAgICBwbGF0Zm9ybU5hbWU6ICdGYWtlJyxcbiAgICAgICAgICAnYXBwaXVtOmRldmljZU5hbWUnOiAnQ29tbW9kb3JlIDY0JyxcbiAgICAgICAgfSxcbiAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgYXdhaXQgZC5kZWxldGVTZXNzaW9uKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc3RhdGljIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgZGVzY3JpYmUoJ2Jhc2VWZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGV4aXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIERyaXZlckNsYXNzLmJhc2VWZXJzaW9uLnNob3VsZC5leGlzdDtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdMb2cgcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzZXR1cCBsb2cgcHJlZml4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBkID0gbmV3IERyaXZlckNsYXNzKCk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzUHJlZml4ID0gZC5sb2cucHJlZml4O1xuICAgICAgICBhd2FpdCBkLmNyZWF0ZVNlc3Npb24oe1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7Li4uZGVmYXVsdENhcHMsIHBsYXRmb3JtTmFtZTogJ0Zha2UnLCAnYXBwaXVtOmRldmljZU5hbWUnOiAnQ29tbW9kb3JlIDY0J30sXG4gICAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZXhwZWN0KHByZXZpb3VzUHJlZml4KS5ub3QudG8uZXFsKGQubG9nLnByZWZpeCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZC5kZWxldGVTZXNzaW9uKCk7XG4gICAgICAgICAgZXhwZWN0KHByZXZpb3VzUHJlZml4KS50by5lcWwoZC5sb2cucHJlZml4KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbiBlbXB0eSBzdGF0dXMgb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHN0YXR1cyA9IGF3YWl0IGQuZ2V0U3RhdHVzKCk7XG4gICAgICBzdGF0dXMuc2hvdWxkLmVxbCh7fSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIHNlc3Npb25JZCBmcm9tIGNyZWF0ZVNlc3Npb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgW3Nlc3NJZF0gPSBhd2FpdCBkLmNyZWF0ZVNlc3Npb24odzNjQ2Fwcyk7XG4gICAgICBzaG91bGQuZXhpc3Qoc2Vzc0lkKTtcbiAgICAgIHNlc3NJZC5zaG91bGQuYmUuYSgnc3RyaW5nJyk7XG4gICAgICBzZXNzSWQubGVuZ3RoLnNob3VsZC5iZS5hYm92ZSg1KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGJlIGFibGUgdG8gc3RhcnQgdHdvIHNlc3Npb25zIHdpdGhvdXQgY2xvc2luZyB0aGUgZmlyc3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBkLmNyZWF0ZVNlc3Npb24oXy5jbG9uZURlZXAodzNjQ2FwcykpO1xuICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKF8uY2xvbmVEZWVwKHczY0NhcHMpKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdzZXNzaW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gZGVsZXRlIGEgc2Vzc2lvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzZXNzaW9uSWQxID0gYXdhaXQgZC5jcmVhdGVTZXNzaW9uKF8uY2xvbmVEZWVwKHczY0NhcHMpKTtcbiAgICAgIGF3YWl0IGQuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgc2hvdWxkLmVxdWFsKGQuc2Vzc2lvbklkLCBudWxsKTtcbiAgICAgIGxldCBzZXNzaW9uSWQyID0gYXdhaXQgZC5jcmVhdGVTZXNzaW9uKF8uY2xvbmVEZWVwKHczY0NhcHMpKTtcbiAgICAgIHNlc3Npb25JZDEuc2hvdWxkLm5vdC5lcWwoc2Vzc2lvbklkMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgY3VycmVudCBzZXNzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IFssIGNhcHNdID0gYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHczY0NhcHMpO1xuICAgICAgY2Fwcy5zaG91bGQuZXF1YWwoYXdhaXQgZC5nZXRTZXNzaW9uKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc2Vzc2lvbnMgaWYgbm8gc2Vzc2lvbiBleGlzdHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgc2Vzc2lvbnMgPSBhd2FpdCBkLmdldFNlc3Npb25zKCk7XG4gICAgICBzZXNzaW9ucy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc2Vzc2lvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjYXBzID0gXy5jbG9uZURlZXAodzNjQ2Fwcyk7XG4gICAgICBhd2FpdCBkLmNyZWF0ZVNlc3Npb24oY2Fwcyk7XG4gICAgICBsZXQgc2Vzc2lvbnMgPSBhd2FpdCBkLmdldFNlc3Npb25zKCk7XG5cbiAgICAgIHNlc3Npb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBzZXNzaW9uc1swXS5zaG91bGQuaW5jbHVkZSh7XG4gICAgICAgIGlkOiBkLnNlc3Npb25JZCxcbiAgICAgIH0pO1xuICAgICAgc2Vzc2lvbnNbMF0uY2FwYWJpbGl0aWVzLnNob3VsZC5pbmNsdWRlKHtcbiAgICAgICAgZGV2aWNlTmFtZTogJ0NvbW1vZG9yZSA2NCcsXG4gICAgICAgIHBsYXRmb3JtTmFtZTogJ0Zha2UnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZ1bGZpbGwgYW4gdW5leHBlY3RlZCBkcml2ZXIgcXVpdCBwcm9taXNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gbWFrZSBhIGNvbW1hbmQgdGhhdCB3aWxsIHdhaXQgYSBiaXQgc28gd2UgY2FuIGNyYXNoIHdoaWxlIGl0J3MgcnVubmluZ1xuICAgICAgc2FuZGJveC5zdHViKGQsICdnZXRTdGF0dXMnKS5jYWxsc0Zha2UoYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBCLmRlbGF5KDEwMDApO1xuICAgICAgICByZXR1cm4gJ2dvb2Qgc3RhdHVzJztcbiAgICAgIH0pO1xuICAgICAgbGV0IGNtZFByb21pc2UgPSBkLmV4ZWN1dGVDb21tYW5kKCdnZXRTdGF0dXMnKTtcbiAgICAgIGF3YWl0IEIuZGVsYXkoMTApO1xuICAgICAgY29uc3QgcCA9IG5ldyBCKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgcmVqZWN0KFxuICAgICAgICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ29uVW5leHBlY3RlZFNodXRkb3duIGV2ZW50IGlzIGV4cGVjdGVkIHRvIGJlIGZpcmVkIHdpdGhpbiA1IHNlY29uZHMgdGltZW91dCdcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICA1MDAwXG4gICAgICAgICk7XG4gICAgICAgIGQub25VbmV4cGVjdGVkU2h1dGRvd24ocmVzb2x2ZSk7XG4gICAgICB9KTtcbiAgICAgIGQuc3RhcnRVbmV4cGVjdGVkU2h1dGRvd24obmV3IEVycm9yKCdXZSBjcmFzaGVkJykpO1xuICAgICAgYXdhaXQgY21kUHJvbWlzZS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9XZSBjcmFzaGVkLyk7XG4gICAgICBhd2FpdCBwO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgYWxsb3cgY29tbWFuZHMgaW4gbWlkZGxlIG9mIHVuZXhwZWN0ZWQgc2h1dGRvd24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBtYWtlIGEgY29tbWFuZCB0aGF0IHdpbGwgd2FpdCBhIGJpdCBzbyB3ZSBjYW4gY3Jhc2ggd2hpbGUgaXQncyBydW5uaW5nXG4gICAgICBzYW5kYm94LnN0dWIoZCwgJ2RlbGV0ZVNlc3Npb24nKS5jYWxsc0Zha2UoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBCLmRlbGF5KDEwMCk7XG4gICAgICAgIERyaXZlckNsYXNzLnByb3RvdHlwZS5kZWxldGVTZXNzaW9uLmNhbGwodGhpcyk7XG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGQuY3JlYXRlU2Vzc2lvbih3M2NDYXBzKTtcbiAgICAgIGNvbnN0IHAgPSBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdvblVuZXhwZWN0ZWRTaHV0ZG93biBldmVudCBpcyBleHBlY3RlZCB0byBiZSBmaXJlZCB3aXRoaW4gNSBzZWNvbmRzIHRpbWVvdXQnXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgNTAwMFxuICAgICAgICApO1xuICAgICAgICBkLm9uVW5leHBlY3RlZFNodXRkb3duKHJlc29sdmUpO1xuICAgICAgfSk7XG4gICAgICBkLnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKG5ldyBFcnJvcignV2UgY3Jhc2hlZCcpKTtcbiAgICAgIGF3YWl0IHA7XG4gICAgICBhd2FpdCBkLmV4ZWN1dGVDb21tYW5kKCdnZXRTZXNzaW9uJykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvc2h1dCBkb3duLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFsbG93IG5ldyBjb21tYW5kcyBhZnRlciBkb25lIHNodXR0aW5nIGRvd24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBtYWtlIGEgY29tbWFuZCB0aGF0IHdpbGwgd2FpdCBhIGJpdCBzbyB3ZSBjYW4gY3Jhc2ggd2hpbGUgaXQncyBydW5uaW5nXG4gICAgICBzYW5kYm94LnN0dWIoZCwgJ2RlbGV0ZVNlc3Npb24nKS5jYWxsc0Zha2UoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBCLmRlbGF5KDEwMCk7XG4gICAgICAgIERyaXZlckNsYXNzLnByb3RvdHlwZS5kZWxldGVTZXNzaW9uLmNhbGwodGhpcyk7XG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKF8uY2xvbmVEZWVwKHczY0NhcHMpKTtcbiAgICAgIGNvbnN0IHAgPSBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgICAgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdvblVuZXhwZWN0ZWRTaHV0ZG93biBldmVudCBpcyBleHBlY3RlZCB0byBiZSBmaXJlZCB3aXRoaW4gNSBzZWNvbmRzIHRpbWVvdXQnXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgNTAwMFxuICAgICAgICApO1xuICAgICAgICBkLm9uVW5leHBlY3RlZFNodXRkb3duKHJlc29sdmUpO1xuICAgICAgfSk7XG4gICAgICBkLnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKG5ldyBFcnJvcignV2UgY3Jhc2hlZCcpKTtcbiAgICAgIGF3YWl0IHA7XG5cbiAgICAgIGF3YWl0IGQuZXhlY3V0ZUNvbW1hbmQoJ2dldFNlc3Npb24nKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9zaHV0IGRvd24vKTtcbiAgICAgIGF3YWl0IEIuZGVsYXkoNTAwKTtcblxuICAgICAgYXdhaXQgZC5leGVjdXRlQ29tbWFuZCgnY3JlYXRlU2Vzc2lvbicsIG51bGwsIG51bGwsIF8uY2xvbmVEZWVwKHczY0NhcHMpKTtcbiAgICAgIGF3YWl0IGQuZGVsZXRlU2Vzc2lvbigpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBkaXN0aW5ndWlzaCBiZXR3ZWVuIFczQyBhbmQgSlNPTldQIHNlc3Npb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUZXN0IFczQyAobGVhdmUgZmlyc3QgMiBhcmdzIG51bGwgYmVjYXVzZSB0aG9zZSBhcmUgdGhlIEpTT05XUCBhcmdzKVxuICAgICAgYXdhaXQgZC5leGVjdXRlQ29tbWFuZCgnY3JlYXRlU2Vzc2lvbicsIG51bGwsIG51bGwsIHtcbiAgICAgICAgYWx3YXlzTWF0Y2g6IHtcbiAgICAgICAgICAuLi5kZWZhdWx0Q2FwcyxcbiAgICAgICAgICBwbGF0Zm9ybU5hbWU6ICdGYWtlJyxcbiAgICAgICAgICAnYXBwaXVtOmRldmljZU5hbWUnOiAnQ29tbW9kb3JlIDY0JyxcbiAgICAgICAgfSxcbiAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoZC5wcm90b2NvbCkudG8uZXF1YWwoJ1czQycpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Byb3RvY29sIGRldGVjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgdXNlIFczQyBpZiBvbmx5IFczQyBjYXBzIGFyZSBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHtcbiAgICAgICAgICBhbHdheXNNYXRjaDogXy5jbG9uZShkZWZhdWx0Q2FwcyksXG4gICAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgICAgfSk7XG4gICAgICAgIGV4cGVjdChkLnByb3RvY29sKS50by5lcXVhbCgnVzNDJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBhIG1ldGhvZCB0byBnZXQgZHJpdmVyIGZvciBhIHNlc3Npb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgW3Nlc3NJZF0gPSBhd2FpdCBkLmNyZWF0ZVNlc3Npb24odzNjQ2Fwcyk7XG4gICAgICBleHBlY3QoZC5kcml2ZXJGb3JTZXNzaW9uKHNlc3NJZCkpLnRvLmVxbChkKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjb21tYW5kIHF1ZXVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgLyoqIEB0eXBlIHtJbnN0YW5jZVR5cGU8RHJpdmVyQ2xhc3M+fSAqL1xuICAgICAgbGV0IGQ7XG4gICAgICBsZXQgd2FpdE1zID0gMTA7XG5cbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBkID0gbmV3IERyaXZlckNsYXNzKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihkLCAnZ2V0U3RhdHVzJykuY2FsbHNGYWtlKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBCLmRlbGF5KHdhaXRNcyk7XG4gICAgICAgICAgcmV0dXJuIERhdGUubm93KCk7XG4gICAgICAgIH0pO1xuICAgICAgICBzYW5kYm94LnN0dWIoZCwgJ2dldFNlc3Npb25zJykuY2FsbHNGYWtlKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBCLmRlbGF5KHdhaXRNcyk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtdWx0aXBhc3MnKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5jbGVhck5ld0NvbW1hbmRUaW1lb3V0KCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBxdWV1ZSBjb21tYW5kcyBhbmQuZXhlY3V0ZUNvbW1hbmQvcmVzcG9uZCBpbiB0aGUgb3JkZXIgcmVjZWl2ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBudW1DbWRzID0gMTA7XG4gICAgICAgIGxldCBjbWRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ21kczsgaSsrKSB7XG4gICAgICAgICAgY21kcy5wdXNoKGQuZXhlY3V0ZUNvbW1hbmQoJ2dldFN0YXR1cycpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IEIuYWxsKGNtZHMpO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG51bUNtZHM7IGkrKykge1xuICAgICAgICAgIGlmIChyZXN1bHRzW2ldIDw9IHJlc3VsdHNbaSAtIDFdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0dvdCByZXN1bHQgb3V0IG9mIG9yZGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgZXJyb3JzIGNvcnJlY3RseSB3aGVuIHF1ZXVpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBudW1DbWRzID0gMTA7XG4gICAgICAgIGxldCBjbWRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ21kczsgaSsrKSB7XG4gICAgICAgICAgaWYgKGkgPT09IDUpIHtcbiAgICAgICAgICAgIGNtZHMucHVzaChkLmV4ZWN1dGVDb21tYW5kKCdnZXRTZXNzaW9ucycpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY21kcy5wdXNoKGQuZXhlY3V0ZUNvbW1hbmQoJ2dldFN0YXR1cycpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3VsdHMgPSAvKiogQHR5cGUge1Byb21pc2VGdWxmaWxsZWRSZXN1bHQ8YW55PltdfSAqLyAoXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByb21pc2Uvbm8tbmF0aXZlXG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGNtZHMpXG4gICAgICAgICk7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgNTsgaSsrKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdHNbaV0udmFsdWUgPD0gcmVzdWx0c1tpIC0gMV0udmFsdWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignR290IHJlc3VsdCBvdXQgb2Ygb3JkZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLyoqIEB0eXBlIHtQcm9taXNlUmVqZWN0ZWRSZXN1bHR9ICovIChcbiAgICAgICAgICAvKiogQHR5cGUge3Vua25vd259ICovIChyZXN1bHRzWzVdKVxuICAgICAgICApLnJlYXNvbi5tZXNzYWdlLnNob3VsZC5jb250YWluKCdtdWx0aXBhc3MnKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDc7IGkgPCBudW1DbWRzOyBpKyspIHtcbiAgICAgICAgICBpZiAocmVzdWx0c1tpXS52YWx1ZSA8PSByZXN1bHRzW2kgLSAxXS52YWx1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdHb3QgcmVzdWx0IG91dCBvZiBvcmRlcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGNhcmUgaWYgcXVldWUgZW1wdGllcyBmb3IgYSBiaXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBudW1DbWRzID0gMTA7XG4gICAgICAgIGxldCBjbWRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ21kczsgaSsrKSB7XG4gICAgICAgICAgY21kcy5wdXNoKGQuZXhlY3V0ZUNvbW1hbmQoJ2dldFN0YXR1cycpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IEIuYWxsKGNtZHMpO1xuICAgICAgICBjbWRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ21kczsgaSsrKSB7XG4gICAgICAgICAgY21kcy5wdXNoKGQuZXhlY3V0ZUNvbW1hbmQoJ2dldFN0YXR1cycpKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHRzID0gYXdhaXQgQi5hbGwoY21kcyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbnVtQ21kczsgaSsrKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdHNbaV0gPD0gcmVzdWx0c1tpIC0gMV0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignR290IHJlc3VsdCBvdXQgb2Ygb3JkZXInKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3RpbWVvdXRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHczY0NhcHMpO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnY29tbWFuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBleGlzdCBieSBkZWZhdWx0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGQubmV3Q29tbWFuZFRpbWVvdXRNcy5zaG91bGQuZXF1YWwoNjAwMDApO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCBiZSBzZXR0YWJsZSB0aHJvdWdoIGB0aW1lb3V0c2AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgZC50aW1lb3V0cygnY29tbWFuZCcsIDIwKTtcbiAgICAgICAgICBkLm5ld0NvbW1hbmRUaW1lb3V0TXMuc2hvdWxkLmVxdWFsKDIwKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGRlc2NyaWJlKCdpbXBsaWNpdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBub3QgZXhpc3QgYnkgZGVmYXVsdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkLmltcGxpY2l0V2FpdE1zLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgYmUgc2V0dGFibGUgdGhyb3VnaCBgdGltZW91dHNgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGQudGltZW91dHMoJ2ltcGxpY2l0JywgMjApO1xuICAgICAgICAgIGQuaW1wbGljaXRXYWl0TXMuc2hvdWxkLmVxdWFsKDIwKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCd0aW1lb3V0cyAoVzNDKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBkLmNyZWF0ZVNlc3Npb24odzNjQ2Fwcyk7XG4gICAgICB9KTtcbiAgICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGQuZGVsZXRlU2Vzc2lvbigpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGdldCB0aW1lb3V0cyB0aGF0IHdlIHNldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICBhd2FpdCBkLnRpbWVvdXRzKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgMTAwMCk7XG4gICAgICAgIGF3YWl0IGQuZ2V0VGltZW91dHMoKS5zaG91bGQuZXZlbnR1YWxseS5oYXZlLnByb3BlcnR5KCdpbXBsaWNpdCcsIDEwMDApO1xuICAgICAgICBhd2FpdCBkLnRpbWVvdXRzKCdjb21tYW5kJywgMjAwMCk7XG4gICAgICAgIGF3YWl0IGQuZ2V0VGltZW91dHMoKS5zaG91bGQuZXZlbnR1YWxseS5kZWVwLmVxdWFsKHtcbiAgICAgICAgICBpbXBsaWNpdDogMTAwMCxcbiAgICAgICAgICBjb21tYW5kOiAyMDAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICBhd2FpdCBkLnRpbWVvdXRzKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgMzAwMCk7XG4gICAgICAgIGF3YWl0IGQuZ2V0VGltZW91dHMoKS5zaG91bGQuZXZlbnR1YWxseS5kZWVwLmVxdWFsKHtcbiAgICAgICAgICBpbXBsaWNpdDogMzAwMCxcbiAgICAgICAgICBjb21tYW5kOiAyMDAwLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Jlc2V0IGNvbXBhdGliaWxpdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIG5vdCBhbGxvdyBib3RoIGZ1bGxSZXNldCBhbmQgbm9SZXNldCB0byBiZSB0cnVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBuZXdDYXBzID0ge1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgICAuLi5kZWZhdWx0Q2FwcyxcbiAgICAgICAgICAgIHBsYXRmb3JtTmFtZTogJ0Zha2UnLFxuICAgICAgICAgICAgJ2FwcGl1bTpkZXZpY2VOYW1lJzogJ0NvbW1vZG9yZSA2NCcsXG4gICAgICAgICAgICAnYXBwaXVtOmZ1bGxSZXNldCc6IHRydWUsXG4gICAgICAgICAgICAnYXBwaXVtOm5vUmVzZXQnOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmlyc3RNYXRjaDogW3t9XSxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgZC5jcmVhdGVTZXNzaW9uKG5ld0NhcHMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL25vUmVzZXQuK2Z1bGxSZXNldC8pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncHJveHlpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgc2Vzc0lkO1xuICAgICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFtzZXNzSWRdID0gYXdhaXQgZC5jcmVhdGVTZXNzaW9uKHczY0NhcHMpO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnI3Byb3h5QWN0aXZlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGV4aXN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGQucHJveHlBY3RpdmUuc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoRnVuY3Rpb24pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZC5wcm94eUFjdGl2ZShzZXNzSWQpLnNob3VsZC5iZS5mYWxzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3Igd2hlbiBzZXNzaW9uSWQgaXMgd3JvbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIGQucHJveHlBY3RpdmUoJ2FhYScpO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdztcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJyNnZXRQcm94eUF2b2lkTGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkLmdldFByb3h5QXZvaWRMaXN0LnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEZ1bmN0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGFuIGFycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGQuZ2V0UHJveHlBdm9pZExpc3Qoc2Vzc0lkKS5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihBcnJheSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gc2Vzc2lvbklkIGlzIHdyb25nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICBkLmdldFByb3h5QXZvaWRMaXN0KCdhYWEnKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3c7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCcjY2FuUHJveHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgaGF2ZSBhICNjYW5Qcm94eSBtZXRob2QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZC5jYW5Qcm94eS5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihGdW5jdGlvbik7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIGJvb2xlYW4gZnJvbSAjY2FuUHJveHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZC5jYW5Qcm94eShzZXNzSWQpLnNob3VsZC5iZS5hKCdib29sZWFuJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gc2Vzc2lvbklkIGlzIHdyb25nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICgoKSA9PiB7XG4gICAgICAgICAgICBkLmNhblByb3h5KCk7XG4gICAgICAgICAgfSkuc2hvdWxkLnRocm93O1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnI3Byb3h5Um91dGVJc0F2b2lkZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgZm9ybSBvZiBhdm9pZGFuY2UgbGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBhdm9pZFN0dWIgPSBzYW5kYm94LnN0dWIoZCwgJ2dldFByb3h5QXZvaWRMaXN0Jyk7XG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtbJ1BPU1QnLCAvXFwvZm9vL10sIFsnR0VUJ11dKTtcbiAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgZC5wcm94eVJvdXRlSXNBdm9pZGVkKCk7XG4gICAgICAgICAgfSkuc2hvdWxkLnRocm93O1xuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtcbiAgICAgICAgICAgIFsnUE9TVCcsIC9cXC9mb28vXSxcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIFsnR0VUJywgL15mb28vLCAnYmFyJ10sXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgpO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdztcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGJhZCBodHRwIG1ldGhvZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgYXZvaWRTdHViID0gc2FuZGJveC5zdHViKGQsICdnZXRQcm94eUF2b2lkTGlzdCcpO1xuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtcbiAgICAgICAgICAgIFsnUE9TVCcsIC9eZm9vL10sXG4gICAgICAgICAgICBbJ0JBWkVURScsIC9eYmFyL10sXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgpO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdztcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IG5vbi1yZWdleCByb3V0ZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgYXZvaWRTdHViID0gc2FuZGJveC5zdHViKGQsICdnZXRQcm94eUF2b2lkTGlzdCcpO1xuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtcbiAgICAgICAgICAgIFsnUE9TVCcsIC9eZm9vL10sXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICBbJ0dFVCcsICcvYmFyJ10sXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgpO1xuICAgICAgICAgIH0pLnNob3VsZC50aHJvdztcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHJvdXRlcyBpbiB0aGUgYXZvaWQgbGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBhdm9pZFN0dWIgPSBzYW5kYm94LnN0dWIoZCwgJ2dldFByb3h5QXZvaWRMaXN0Jyk7XG4gICAgICAgICAgYXZvaWRTdHViLnJldHVybnMoW1snUE9TVCcsIC9eXFwvZm9vL11dKTtcbiAgICAgICAgICBkLnByb3h5Um91dGVJc0F2b2lkZWQoJ2ZvbycsICdQT1NUJywgJy9mb28vYmFyJykuc2hvdWxkLmJlLnRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnc2hvdWxkIHN0cmlwIGF3YXkgYW55IHdkL2h1YiBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgYXZvaWRTdHViID0gc2FuZGJveC5zdHViKGQsICdnZXRQcm94eUF2b2lkTGlzdCcpO1xuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtbJ1BPU1QnLCAvXlxcL2Zvby9dXSk7XG4gICAgICAgICAgZC5wcm94eVJvdXRlSXNBdm9pZGVkKCdmb28nLCAnUE9TVCcsICcvZm9vL2JhcicpLnNob3VsZC5iZS50cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIHJvdXRlcyBub3QgaW4gdGhlIGF2b2lkIGxpc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgYXZvaWRTdHViID0gc2FuZGJveC5zdHViKGQsICdnZXRQcm94eUF2b2lkTGlzdCcpO1xuICAgICAgICAgIGF2b2lkU3R1Yi5yZXR1cm5zKFtbJ1BPU1QnLCAvXlxcL2Zvby9dXSk7XG4gICAgICAgICAgZC5wcm94eVJvdXRlSXNBdm9pZGVkKCdmb28nLCAnR0VUJywgJy9mb28vYmFyJykuc2hvdWxkLmJlLmZhbHNlO1xuICAgICAgICAgIGQucHJveHlSb3V0ZUlzQXZvaWRlZCgnZm9vJywgJ1BPU1QnLCAnL2JvbycpLnNob3VsZC5iZS5mYWxzZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdldmVudCB0aW1pbmcgZnJhbWV3b3JrJywgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IGJlZm9yZVN0YXJ0VGltZTtcbiAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBiZWZvcmVTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICBkLnNob3VsZFZhbGlkYXRlQ2FwcyA9IGZhbHNlO1xuICAgICAgICBhd2FpdCBkLmV4ZWN1dGVDb21tYW5kKCdjcmVhdGVTZXNzaW9uJywgbnVsbCwgbnVsbCwge1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7Li4uZGVmYXVsdENhcHN9LFxuICAgICAgICAgIGZpcnN0TWF0Y2g6IFt7fV0sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnI2V2ZW50SGlzdG9yeScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCBoYXZlIGFuIGV2ZW50SGlzdG9yeSBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBzaG91bGQuZXhpc3QoZC5ldmVudEhpc3RvcnkpO1xuICAgICAgICAgIHNob3VsZC5leGlzdChkLmV2ZW50SGlzdG9yeS5jb21tYW5kcyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgaGF2ZSBhIHNlc3Npb24gc3RhcnQgdGltaW5nIGFmdGVyIHNlc3Npb24gc3RhcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbGV0IHtuZXdTZXNzaW9uUmVxdWVzdGVkLCBuZXdTZXNzaW9uU3RhcnRlZH0gPSBkLmV2ZW50SGlzdG9yeTtcbiAgICAgICAgICBuZXdTZXNzaW9uUmVxdWVzdGVkLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgICBuZXdTZXNzaW9uU3RhcnRlZC5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgICAgbmV3U2Vzc2lvblJlcXVlc3RlZFswXS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgICAgbmV3U2Vzc2lvblN0YXJ0ZWRbMF0uc2hvdWxkLmJlLmEoJ251bWJlcicpO1xuICAgICAgICAgIChuZXdTZXNzaW9uUmVxdWVzdGVkWzBdID49IGJlZm9yZVN0YXJ0VGltZSkuc2hvdWxkLmJlLnRydWU7XG4gICAgICAgICAgKG5ld1Nlc3Npb25TdGFydGVkWzBdID49IG5ld1Nlc3Npb25SZXF1ZXN0ZWRbMF0pLnNob3VsZC5iZS50cnVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIGluY2x1ZGUgYSBjb21tYW5kcyBsaXN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGQuZXhlY3V0ZUNvbW1hbmQoJ2dldFN0YXR1cycsIFtdKTtcbiAgICAgICAgICBkLmV2ZW50SGlzdG9yeS5jb21tYW5kcy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICAgIGQuZXZlbnRIaXN0b3J5LmNvbW1hbmRzWzFdLmNtZC5zaG91bGQuZXF1YWwoJ2dldFN0YXR1cycpO1xuICAgICAgICAgIGQuZXZlbnRIaXN0b3J5LmNvbW1hbmRzWzFdLnN0YXJ0VGltZS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgICAgZC5ldmVudEhpc3RvcnkuY29tbWFuZHNbMV0uZW5kVGltZS5zaG91bGQuYmUuYSgnbnVtYmVyJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnI2xvZ0V2ZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGFsbG93IGxvZ2dpbmcgYXJiaXRyYXJ5IGV2ZW50cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkLmxvZ0V2ZW50KCdmb28nKTtcbiAgICAgICAgICBkLmV2ZW50SGlzdG9yeS5mb29bMF0uc2hvdWxkLmJlLmEoJ251bWJlcicpO1xuICAgICAgICAgIChkLmV2ZW50SGlzdG9yeS5mb29bMF0gPj0gYmVmb3JlU3RhcnRUaW1lKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IHJlc2VydmVkIG9yIG9kZGx5IGZvcm1lZCBldmVudCBuYW1lcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgZC5sb2dFdmVudCgnY29tbWFuZHMnKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3coKTtcbiAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgZC5sb2dFdmVudCgxKTtcbiAgICAgICAgICB9KS5zaG91bGQudGhyb3coKTtcbiAgICAgICAgICAoKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgZC5sb2dFdmVudCh7fSk7XG4gICAgICAgICAgfSkuc2hvdWxkLnRocm93KCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIGFsbG93IGxvZ2dpbmcgdGhlIHNhbWUgZXZlbnQgbXVsdGlwbGUgdGltZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGQubG9nRXZlbnQoJ2JhcicpO1xuICAgICAgICBkLmxvZ0V2ZW50KCdiYXInKTtcbiAgICAgICAgZC5ldmVudEhpc3RvcnkuYmFyLnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICAgICAgZC5ldmVudEhpc3RvcnkuYmFyWzFdLnNob3VsZC5iZS5hKCdudW1iZXInKTtcbiAgICAgICAgKGQuZXZlbnRIaXN0b3J5LmJhclsxXSA+PSBkLmV2ZW50SGlzdG9yeS5iYXJbMF0pLnNob3VsZC5iZS50cnVlO1xuICAgICAgfSk7XG4gICAgICBkZXNjcmliZSgnZ2V0U2Vzc2lvbiBkZWNvcmF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIGRlY29yYXRlIGdldFNlc3Npb24gcmVzcG9uc2UgaWYgb3B0LWluIGNhcCBpcyBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgZC5nZXRTZXNzaW9uKCk7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXMuZXZlbnRzKTtcblxuICAgICAgICAgIF8uc2V0KGQsICdjYXBzLmV2ZW50VGltaW5ncycsIHRydWUpO1xuICAgICAgICAgIHJlcyA9IGF3YWl0IGQuZ2V0U2Vzc2lvbigpO1xuICAgICAgICAgIHNob3VsZC5leGlzdChyZXMuZXZlbnRzKTtcbiAgICAgICAgICBzaG91bGQuZXhpc3QocmVzLmV2ZW50cz8ubmV3U2Vzc2lvblJlcXVlc3RlZCk7XG4gICAgICAgICAgZXhwZWN0KHJlcy5ldmVudHM/Lm5ld1Nlc3Npb25SZXF1ZXN0ZWRbMF0pLnRvLmJlLmEoJ251bWJlcicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGRlc2NyaWJlKCcucmVzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJlc2V0IGFzIFczQyBpZiB0aGUgb3JpZ2luYWwgc2Vzc2lvbiB3YXMgVzNDJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjYXBzID0ge1xuICAgICAgICAgIGFsd2F5c01hdGNoOiB7XG4gICAgICAgICAgICAnYXBwaXVtOmFwcCc6ICdGYWtlJyxcbiAgICAgICAgICAgICdhcHBpdW06ZGV2aWNlTmFtZSc6ICdGYWtlJyxcbiAgICAgICAgICAgICdhcHBpdW06YXV0b21hdGlvbk5hbWUnOiAnRmFrZScsXG4gICAgICAgICAgICBwbGF0Zm9ybU5hbWU6ICdGYWtlJyxcbiAgICAgICAgICAgIC4uLmRlZmF1bHRDYXBzLFxuICAgICAgICAgIH0sXG5cbiAgICAgICAgICBmaXJzdE1hdGNoOiBbe31dLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBkLmNyZWF0ZVNlc3Npb24oY2Fwcyk7XG4gICAgICAgIGV4cGVjdChkLnByb3RvY29sKS50by5lcXVhbCgnVzNDJyk7XG4gICAgICAgIGF3YWl0IGQucmVzZXQoKTtcbiAgICAgICAgZXhwZWN0KGQucHJvdG9jb2wpLnRvLmVxdWFsKCdXM0MnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRGV2aWNlU2V0dGluZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBub3QgaG9sZCBvbiB0byByZWZlcmVuY2Ugb2YgZGVmYXVsdHMgaW4gY29uc3RydWN0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgb2JqID0ge2ZvbzogJ2Jhcid9O1xuICAgICAgbGV0IGQxID0gbmV3IERldmljZVNldHRpbmdzKG9iaik7XG4gICAgICBsZXQgZDIgPSBuZXcgRGV2aWNlU2V0dGluZ3Mob2JqKTtcbiAgICAgIGQxLmdldFNldHRpbmdzKCkuZm9vID0gJ2Jheic7XG4gICAgICBkMS5nZXRTZXR0aW5ncygpLnNob3VsZC5ub3QuZXFsKGQyLmdldFNldHRpbmdzKCkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnLmlzRmVhdHVyZUVuYWJsZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGQ7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGQgPSBuZXcgRHJpdmVyQ2xhc3MoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2F5IGEgZmVhdHVyZSBpcyBlbmFibGVkIHdoZW4gaXQgaXMgZXhwbGljaXRseSBhbGxvd2VkJywgZnVuY3Rpb24gKCkge1xuICAgICAgZC5hbGxvd0luc2VjdXJlID0gWydmb28nLCAnYmFyJ107XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2ZvbycpLnNob3VsZC5iZS50cnVlO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdiYXInKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnYmF6Jykuc2hvdWxkLmJlLmZhbHNlO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzYXkgYSBmZWF0dXJlIGlzIG5vdCBlbmFibGVkIGlmIGl0IGlzIG5vdCBlbmFibGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgZC5hbGxvd0luc2VjdXJlID0gW107XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2ZvbycpLnNob3VsZC5iZS5mYWxzZTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJlZmVyIGRlbnlJbnNlY3VyZSB0byBhbGxvd0luc2VjdXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgZC5hbGxvd0luc2VjdXJlID0gWydmb28nLCAnYmFyJ107XG4gICAgICBkLmRlbnlJbnNlY3VyZSA9IFsnZm9vJ107XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2ZvbycpLnNob3VsZC5iZS5mYWxzZTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnYmFyJykuc2hvdWxkLmJlLnRydWU7XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2JheicpLnNob3VsZC5iZS5mYWxzZTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWxsb3cgZ2xvYmFsIHNldHRpbmcgZm9yIGluc2VjdXJpdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBkLnJlbGF4ZWRTZWN1cml0eUVuYWJsZWQgPSB0cnVlO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdmb28nKS5zaG91bGQuYmUudHJ1ZTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnYmFyJykuc2hvdWxkLmJlLnRydWU7XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2JheicpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuXG4gICAgaXQoJ2dsb2JhbCBzZXR0aW5nIHNob3VsZCBiZSBvdmVycmlkZWFibGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBkLnJlbGF4ZWRTZWN1cml0eUVuYWJsZWQgPSB0cnVlO1xuICAgICAgZC5kZW55SW5zZWN1cmUgPSBbJ2ZvbycsICdiYXInXTtcbiAgICAgIGQuaXNGZWF0dXJlRW5hYmxlZCgnZm9vJykuc2hvdWxkLmJlLmZhbHNlO1xuICAgICAgZC5pc0ZlYXR1cmVFbmFibGVkKCdiYXInKS5zaG91bGQuYmUuZmFsc2U7XG4gICAgICBkLmlzRmVhdHVyZUVuYWJsZWQoJ2JheicpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuRHJpdmVyQ2xhc3N9IERyaXZlckNsYXNzXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuVzNDQ2FwYWJpbGl0aWVzfSBXM0NDYXBhYmlsaXRpZXNcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5BcHBpdW1XM0NDYXBhYmlsaXRpZXN9IEFwcGl1bVczQ0NhcGFiaWxpdGllc1xuICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBRUEsTUFBTUEsTUFBTSxHQUFHQyxhQUFBLENBQUtELE1BQUwsRUFBZjs7QUFDQSxNQUFNO0VBQUNFO0FBQUQsSUFBV0QsYUFBakI7O0FBV08sU0FBU0UsbUJBQVQsQ0FBNkJDLFdBQTdCLEVBQTBDQyxXQUFXLEdBQUcsRUFBeEQsRUFBNEQ7RUFFakUsTUFBTUMsU0FBUyxHQUFHRixXQUFXLENBQUNHLElBQVosSUFBb0Isa0JBQXRDO0VBRUFDLFFBQVEsQ0FB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
|