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