appium-adb 9.10.2 → 9.10.3

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.
@@ -1,1150 +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 _logger = _interopRequireDefault(require("../logger.js"));
13
-
14
- var _helpers = require("../helpers.js");
15
-
16
- var _path = _interopRequireDefault(require("path"));
17
-
18
- var _lodash = _interopRequireDefault(require("lodash"));
19
-
20
- var _support = require("@appium/support");
21
-
22
- var _os = require("os");
23
-
24
- var _logcat = _interopRequireDefault(require("../logcat"));
25
-
26
- var _asyncbox = require("asyncbox");
27
-
28
- var _teen_process = require("teen_process");
29
-
30
- var _bluebird = _interopRequireDefault(require("bluebird"));
31
-
32
- const MAX_SHELL_BUFFER_LENGTH = 1000;
33
- const NOT_CHANGEABLE_PERM_ERROR = /not a changeable permission type/i;
34
- const IGNORED_PERM_ERRORS = [NOT_CHANGEABLE_PERM_ERROR, /Unknown permission/i];
35
- const MAX_PGREP_PATTERN_LEN = 15;
36
- const HIDDEN_API_POLICY_KEYS = ['hidden_api_policy_pre_p_apps', 'hidden_api_policy_p_apps', 'hidden_api_policy'];
37
- const PID_COLUMN_TITLE = 'PID';
38
- const PROCESS_NAME_COLUMN_TITLE = 'NAME';
39
- const PS_TITLE_PATTERN = new RegExp(`^(.*\\b${PID_COLUMN_TITLE}\\b.*\\b${PROCESS_NAME_COLUMN_TITLE}\\b.*)$`, 'm');
40
- const ADB_INPUT_ESCAPE_PATTERN = /[()<>|;&*\\~^"']/g;
41
- const methods = {};
42
-
43
- methods.shellChunks = async function shellChunks(argTransformer, args) {
44
- const commands = [];
45
- let cmdChunk = [];
46
-
47
- for (const arg of args) {
48
- const nextCmd = argTransformer(arg);
49
-
50
- if (!_lodash.default.isArray(nextCmd)) {
51
- throw new Error('Argument transformer must result in an array');
52
- }
53
-
54
- if (_lodash.default.last(nextCmd) !== ';') {
55
- nextCmd.push(';');
56
- }
57
-
58
- if (nextCmd.join(' ').length + cmdChunk.join(' ').length >= MAX_SHELL_BUFFER_LENGTH) {
59
- commands.push(cmdChunk);
60
- cmdChunk = [];
61
- }
62
-
63
- cmdChunk = [...cmdChunk, ...nextCmd];
64
- }
65
-
66
- if (!_lodash.default.isEmpty(cmdChunk)) {
67
- commands.push(cmdChunk);
68
- }
69
-
70
- _logger.default.debug(`Got the following command chunks to execute: ${JSON.stringify(commands)}`);
71
-
72
- let lastError = null;
73
-
74
- for (const cmd of commands) {
75
- try {
76
- await this.shell(cmd);
77
- } catch (e) {
78
- lastError = e;
79
- }
80
- }
81
-
82
- if (lastError) {
83
- throw lastError;
84
- }
85
- };
86
-
87
- methods.getAdbWithCorrectAdbPath = async function getAdbWithCorrectAdbPath() {
88
- this.executable.path = await this.getSdkBinaryPath('adb');
89
- return this.adb;
90
- };
91
-
92
- methods.initAapt = async function initAapt() {
93
- await this.getSdkBinaryPath('aapt');
94
- };
95
-
96
- methods.initAapt2 = async function initAapt2() {
97
- await this.getSdkBinaryPath('aapt2');
98
- };
99
-
100
- methods.initZipAlign = async function initZipAlign() {
101
- await this.getSdkBinaryPath('zipalign');
102
- };
103
-
104
- methods.initBundletool = async function initBundletool() {
105
- try {
106
- this.binaries.bundletool = await _support.fs.which('bundletool.jar');
107
- } catch (err) {
108
- throw new Error('bundletool.jar binary is expected to be present in PATH. ' + 'Visit https://github.com/google/bundletool for more details.');
109
- }
110
- };
111
-
112
- methods.getApiLevel = async function getApiLevel() {
113
- if (!_lodash.default.isInteger(this._apiLevel)) {
114
- try {
115
- const strOutput = await this.getDeviceProperty('ro.build.version.sdk');
116
- let apiLevel = parseInt(strOutput.trim(), 10);
117
- const charCodeQ = 'q'.charCodeAt(0);
118
- const apiLevelDiff = apiLevel - 28;
119
- const codename = String.fromCharCode(charCodeQ + apiLevelDiff);
120
-
121
- if (apiLevelDiff >= 0 && (await this.getPlatformVersion()).toLowerCase() === codename) {
122
- _logger.default.debug(`Release version is ${codename.toUpperCase()} but found API Level ${apiLevel}. Setting API Level to ${apiLevel + 1}`);
123
-
124
- apiLevel++;
125
- }
126
-
127
- this._apiLevel = apiLevel;
128
-
129
- _logger.default.debug(`Device API level: ${this._apiLevel}`);
130
-
131
- if (isNaN(this._apiLevel)) {
132
- throw new Error(`The actual output '${strOutput}' cannot be converted to an integer`);
133
- }
134
- } catch (e) {
135
- throw new Error(`Error getting device API level. Original error: ${e.message}`);
136
- }
137
- }
138
-
139
- return this._apiLevel;
140
- };
141
-
142
- methods.getPlatformVersion = async function getPlatformVersion() {
143
- _logger.default.info('Getting device platform version');
144
-
145
- try {
146
- return await this.getDeviceProperty('ro.build.version.release');
147
- } catch (e) {
148
- throw new Error(`Error getting device platform version. Original error: ${e.message}`);
149
- }
150
- };
151
-
152
- methods.isDeviceConnected = async function isDeviceConnected() {
153
- let devices = await this.getConnectedDevices();
154
- return devices.length > 0;
155
- };
156
-
157
- methods.mkdir = async function mkdir(remotePath) {
158
- return await this.shell(['mkdir', '-p', remotePath]);
159
- };
160
-
161
- methods.isValidClass = function isValidClass(classString) {
162
- return (0, _helpers.matchComponentName)(classString);
163
- };
164
-
165
- methods.resolveLaunchableActivity = async function resolveLaunchableActivity(pkg, opts = {}) {
166
- const {
167
- preferCmd = true
168
- } = opts;
169
-
170
- if (!preferCmd || (await this.getApiLevel()) < 24) {
171
- const stdout = await this.shell(['dumpsys', 'package', pkg]);
172
- const names = (0, _helpers.parseLaunchableActivityNames)(stdout);
173
-
174
- if (_lodash.default.isEmpty(names)) {
175
- _logger.default.debug(stdout);
176
-
177
- throw new Error(`Unable to resolve the launchable activity of '${pkg}'. Is it installed on the device?`);
178
- }
179
-
180
- if (names.length === 1) {
181
- return names[0];
182
- }
183
-
184
- const tmpRoot = await _support.tempDir.openDir();
185
-
186
- try {
187
- const tmpApp = await this.pullApk(pkg, tmpRoot);
188
- const {
189
- apkActivity
190
- } = await this.packageAndLaunchActivityFromManifest(tmpApp);
191
- return apkActivity;
192
- } catch (e) {
193
- _logger.default.debug(e.stack);
194
-
195
- _logger.default.warn(`Unable to resolve the launchable activity of '${pkg}'. ` + `The very first match of the dumpsys output is going to be used. ` + `Original error: ${e.message}`);
196
-
197
- return names[0];
198
- } finally {
199
- await _support.fs.rimraf(tmpRoot);
200
- }
201
- }
202
-
203
- const {
204
- stdout,
205
- stderr
206
- } = await this.shell(['cmd', 'package', 'resolve-activity', '--brief', pkg], {
207
- outputFormat: this.EXEC_OUTPUT_FORMAT.FULL
208
- });
209
-
210
- for (const line of (stdout || '').split('\n').map(_lodash.default.trim)) {
211
- if (this.isValidClass(line)) {
212
- return line;
213
- }
214
- }
215
-
216
- throw new Error(`Unable to resolve the launchable activity of '${pkg}'. Original error: ${stderr || stdout}`);
217
- };
218
-
219
- methods.forceStop = async function forceStop(pkg) {
220
- return await this.shell(['am', 'force-stop', pkg]);
221
- };
222
-
223
- methods.killPackage = async function killPackage(pkg) {
224
- return await this.shell(['am', 'kill', pkg]);
225
- };
226
-
227
- methods.clear = async function clear(pkg) {
228
- return await this.shell(['pm', 'clear', pkg]);
229
- };
230
-
231
- methods.grantAllPermissions = async function grantAllPermissions(pkg, apk) {
232
- const apiLevel = await this.getApiLevel();
233
- let targetSdk = 0;
234
- let dumpsysOutput = null;
235
-
236
- try {
237
- if (!apk) {
238
- dumpsysOutput = await this.shell(['dumpsys', 'package', pkg]);
239
- targetSdk = await this.targetSdkVersionUsingPKG(pkg, dumpsysOutput);
240
- } else {
241
- targetSdk = await this.targetSdkVersionFromManifest(apk);
242
- }
243
- } catch (e) {
244
- _logger.default.warn(`Ran into problem getting target SDK version; ignoring...`);
245
- }
246
-
247
- if (apiLevel >= 23 && targetSdk >= 23) {
248
- dumpsysOutput = dumpsysOutput || (await this.shell(['dumpsys', 'package', pkg]));
249
- const requestedPermissions = await this.getReqPermissions(pkg, dumpsysOutput);
250
- const grantedPermissions = await this.getGrantedPermissions(pkg, dumpsysOutput);
251
-
252
- const permissionsToGrant = _lodash.default.difference(requestedPermissions, grantedPermissions);
253
-
254
- if (_lodash.default.isEmpty(permissionsToGrant)) {
255
- _logger.default.info(`${pkg} contains no permissions available for granting`);
256
- } else {
257
- await this.grantPermissions(pkg, permissionsToGrant);
258
- }
259
- }
260
- };
261
-
262
- methods.grantPermissions = async function grantPermissions(pkg, permissions) {
263
- _logger.default.debug(`Granting permissions ${JSON.stringify(permissions)} to '${pkg}'`);
264
-
265
- try {
266
- await this.shellChunks(perm => ['pm', 'grant', pkg, perm], permissions);
267
- } catch (e) {
268
- if (!IGNORED_PERM_ERRORS.some(pattern => pattern.test(e.stderr || e.message))) {
269
- throw e;
270
- }
271
- }
272
- };
273
-
274
- methods.grantPermission = async function grantPermission(pkg, permission) {
275
- try {
276
- await this.shell(['pm', 'grant', pkg, permission]);
277
- } catch (e) {
278
- if (!NOT_CHANGEABLE_PERM_ERROR.test(e.stderr || e.message)) {
279
- throw e;
280
- }
281
- }
282
- };
283
-
284
- methods.revokePermission = async function revokePermission(pkg, permission) {
285
- try {
286
- await this.shell(['pm', 'revoke', pkg, permission]);
287
- } catch (e) {
288
- if (!NOT_CHANGEABLE_PERM_ERROR.test(e.stderr || e.message)) {
289
- throw e;
290
- }
291
- }
292
- };
293
-
294
- methods.getGrantedPermissions = async function getGrantedPermissions(pkg, cmdOutput = null) {
295
- _logger.default.debug('Retrieving granted permissions');
296
-
297
- const stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
298
- return (0, _helpers.extractMatchingPermissions)(stdout, ['install', 'runtime'], true);
299
- };
300
-
301
- methods.getDeniedPermissions = async function getDeniedPermissions(pkg, cmdOutput = null) {
302
- _logger.default.debug('Retrieving denied permissions');
303
-
304
- const stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
305
- return (0, _helpers.extractMatchingPermissions)(stdout, ['install', 'runtime'], false);
306
- };
307
-
308
- methods.getReqPermissions = async function getReqPermissions(pkg, cmdOutput = null) {
309
- _logger.default.debug('Retrieving requested permissions');
310
-
311
- const stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
312
- return (0, _helpers.extractMatchingPermissions)(stdout, ['requested']);
313
- };
314
-
315
- methods.getLocationProviders = async function getLocationProviders() {
316
- let stdout = await this.getSetting('secure', 'location_providers_allowed');
317
- return stdout.trim().split(',').map(p => p.trim()).filter(Boolean);
318
- };
319
-
320
- methods.toggleGPSLocationProvider = async function toggleGPSLocationProvider(enabled) {
321
- await this.setSetting('secure', 'location_providers_allowed', `${enabled ? '+' : '-'}gps`);
322
- };
323
-
324
- methods.setHiddenApiPolicy = async function setHiddenApiPolicy(value, ignoreError = false) {
325
- try {
326
- await this.shell(HIDDEN_API_POLICY_KEYS.map(k => `settings put global ${k} ${value}`).join(';'));
327
- } catch (e) {
328
- if (!ignoreError) {
329
- throw e;
330
- }
331
-
332
- _logger.default.info(`Failed to set setting keys '${HIDDEN_API_POLICY_KEYS}' to '${value}'. Original error: ${e.message}`);
333
- }
334
- };
335
-
336
- methods.setDefaultHiddenApiPolicy = async function setDefaultHiddenApiPolicy(ignoreError = false) {
337
- try {
338
- await this.shell(HIDDEN_API_POLICY_KEYS.map(k => `settings delete global ${k}`).join(';'));
339
- } catch (e) {
340
- if (!ignoreError) {
341
- throw e;
342
- }
343
-
344
- _logger.default.info(`Failed to delete keys '${HIDDEN_API_POLICY_KEYS}'. Original error: ${e.message}`);
345
- }
346
- };
347
-
348
- methods.stopAndClear = async function stopAndClear(pkg) {
349
- try {
350
- await this.forceStop(pkg);
351
- await this.clear(pkg);
352
- } catch (e) {
353
- throw new Error(`Cannot stop and clear ${pkg}. Original error: ${e.message}`);
354
- }
355
- };
356
-
357
- methods.availableIMEs = async function availableIMEs() {
358
- try {
359
- return (0, _helpers.getIMEListFromOutput)(await this.shell(['ime', 'list', '-a']));
360
- } catch (e) {
361
- throw new Error(`Error getting available IME's. Original error: ${e.message}`);
362
- }
363
- };
364
-
365
- methods.enabledIMEs = async function enabledIMEs() {
366
- try {
367
- return (0, _helpers.getIMEListFromOutput)(await this.shell(['ime', 'list']));
368
- } catch (e) {
369
- throw new Error(`Error getting enabled IME's. Original error: ${e.message}`);
370
- }
371
- };
372
-
373
- methods.enableIME = async function enableIME(imeId) {
374
- await this.shell(['ime', 'enable', imeId]);
375
- };
376
-
377
- methods.disableIME = async function disableIME(imeId) {
378
- await this.shell(['ime', 'disable', imeId]);
379
- };
380
-
381
- methods.setIME = async function setIME(imeId) {
382
- await this.shell(['ime', 'set', imeId]);
383
- };
384
-
385
- methods.defaultIME = async function defaultIME() {
386
- try {
387
- let engine = await this.getSetting('secure', 'default_input_method');
388
-
389
- if (engine === 'null') {
390
- return null;
391
- }
392
-
393
- return engine.trim();
394
- } catch (e) {
395
- throw new Error(`Error getting default IME. Original error: ${e.message}`);
396
- }
397
- };
398
-
399
- methods.keyevent = async function keyevent(keycode) {
400
- let code = parseInt(keycode, 10);
401
- await this.shell(['input', 'keyevent', code]);
402
- };
403
-
404
- methods.inputText = async function inputText(text) {
405
- if (text === '') {
406
- return;
407
- }
408
-
409
- const originalStr = `${text}`;
410
- const escapedText = originalStr.replace(/\$/g, '\\$').replace(/ /g, '%s');
411
- let args = ['input', 'text', originalStr];
412
-
413
- if (escapedText !== originalStr || ADB_INPUT_ESCAPE_PATTERN.test(originalStr)) {
414
- if (_lodash.default.every(['"', `'`], c => originalStr.includes(c))) {
415
- throw new Error(`Did not know how to escape a string that contains both types of quotes (" and ')`);
416
- }
417
-
418
- const q = originalStr.includes('"') ? `'` : '"';
419
- args = [`input text ${q}${escapedText}${q}`];
420
- }
421
-
422
- await this.shell(args);
423
- };
424
-
425
- methods.clearTextField = async function clearTextField(length = 100) {
426
- _logger.default.debug(`Clearing up to ${length} characters`);
427
-
428
- if (length === 0) {
429
- return;
430
- }
431
-
432
- let args = ['input', 'keyevent'];
433
-
434
- for (let i = 0; i < length; i++) {
435
- args.push('67', '112');
436
- }
437
-
438
- await this.shell(args);
439
- };
440
-
441
- methods.lock = async function lock() {
442
- if (await this.isScreenLocked()) {
443
- _logger.default.debug('Screen is already locked. Doing nothing.');
444
-
445
- return;
446
- }
447
-
448
- _logger.default.debug('Pressing the KEYCODE_POWER button to lock screen');
449
-
450
- await this.keyevent(26);
451
- const timeoutMs = 5000;
452
-
453
- try {
454
- await (0, _asyncbox.waitForCondition)(async () => await this.isScreenLocked(), {
455
- waitMs: timeoutMs,
456
- intervalMs: 500
457
- });
458
- } catch (e) {
459
- throw new Error(`The device screen is still locked after ${timeoutMs}ms timeout`);
460
- }
461
- };
462
-
463
- methods.back = async function back() {
464
- _logger.default.debug('Pressing the BACK button');
465
-
466
- await this.keyevent(4);
467
- };
468
-
469
- methods.goToHome = async function goToHome() {
470
- _logger.default.debug('Pressing the HOME button');
471
-
472
- await this.keyevent(3);
473
- };
474
-
475
- methods.getAdbPath = function getAdbPath() {
476
- return this.executable.path;
477
- };
478
-
479
- methods.getScreenOrientation = async function getScreenOrientation() {
480
- let stdout = await this.shell(['dumpsys', 'input']);
481
- return (0, _helpers.getSurfaceOrientation)(stdout);
482
- };
483
-
484
- methods.sendTelnetCommand = async function sendTelnetCommand(command) {
485
- return await this.execEmuConsoleCommand(command, {
486
- port: await this.getEmulatorPort()
487
- });
488
- };
489
-
490
- methods.isAirplaneModeOn = async function isAirplaneModeOn() {
491
- let stdout = await this.getSetting('global', 'airplane_mode_on');
492
- return parseInt(stdout, 10) !== 0;
493
- };
494
-
495
- methods.setAirplaneMode = async function setAirplaneMode(on) {
496
- await this.setSetting('global', 'airplane_mode_on', on ? 1 : 0);
497
- };
498
-
499
- methods.broadcastAirplaneMode = async function broadcastAirplaneMode(on) {
500
- await this.shell(['am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', on ? 'true' : 'false']);
501
- };
502
-
503
- methods.isWifiOn = async function isWifiOn() {
504
- let stdout = await this.getSetting('global', 'wifi_on');
505
- return parseInt(stdout, 10) !== 0;
506
- };
507
-
508
- methods.isDataOn = async function isDataOn() {
509
- let stdout = await this.getSetting('global', 'mobile_data');
510
- return parseInt(stdout, 10) !== 0;
511
- };
512
-
513
- methods.setWifiAndData = async function setWifiAndData({
514
- wifi,
515
- data
516
- }, isEmulator = false) {
517
- if (_support.util.hasValue(wifi)) {
518
- await this.setWifiState(wifi, isEmulator);
519
- }
520
-
521
- if (_support.util.hasValue(data)) {
522
- await this.setDataState(data, isEmulator);
523
- }
524
- };
525
-
526
- methods.isAnimationOn = async function isAnimationOn() {
527
- let animator_duration_scale = await this.getSetting('global', 'animator_duration_scale');
528
- let transition_animation_scale = await this.getSetting('global', 'transition_animation_scale');
529
- let window_animation_scale = await this.getSetting('global', 'window_animation_scale');
530
- return _lodash.default.some([animator_duration_scale, transition_animation_scale, window_animation_scale], setting => setting !== '0.0');
531
- };
532
-
533
- methods.rimraf = async function rimraf(path) {
534
- await this.shell(['rm', '-rf', path]);
535
- };
536
-
537
- methods.push = async function push(localPath, remotePath, opts) {
538
- await this.mkdir(_path.default.posix.dirname(remotePath));
539
- await this.adbExec(['push', localPath, remotePath], opts);
540
- };
541
-
542
- methods.pull = async function pull(remotePath, localPath, opts = {}) {
543
- var _opts$timeout;
544
-
545
- await this.adbExec(['pull', remotePath, localPath], { ...opts,
546
- timeout: (_opts$timeout = opts.timeout) !== null && _opts$timeout !== void 0 ? _opts$timeout : 60000
547
- });
548
- };
549
-
550
- methods.processExists = async function processExists(processName) {
551
- return !_lodash.default.isEmpty(await this.getPIDsByName(processName));
552
- };
553
-
554
- methods.getForwardList = async function getForwardList() {
555
- _logger.default.debug(`List forwarding ports`);
556
-
557
- const connections = await this.adbExec(['forward', '--list']);
558
- return connections.split(_os.EOL).filter(line => Boolean(line.trim()));
559
- };
560
-
561
- methods.forwardPort = async function forwardPort(systemPort, devicePort) {
562
- _logger.default.debug(`Forwarding system: ${systemPort} to device: ${devicePort}`);
563
-
564
- await this.adbExec(['forward', `tcp:${systemPort}`, `tcp:${devicePort}`]);
565
- };
566
-
567
- methods.removePortForward = async function removePortForward(systemPort) {
568
- _logger.default.debug(`Removing forwarded port socket connection: ${systemPort} `);
569
-
570
- await this.adbExec(['forward', `--remove`, `tcp:${systemPort}`]);
571
- };
572
-
573
- methods.getReverseList = async function getReverseList() {
574
- _logger.default.debug(`List reverse forwarding ports`);
575
-
576
- const connections = await this.adbExec(['reverse', '--list']);
577
- return connections.split(_os.EOL).filter(line => Boolean(line.trim()));
578
- };
579
-
580
- methods.reversePort = async function reversePort(devicePort, systemPort) {
581
- _logger.default.debug(`Forwarding device: ${devicePort} to system: ${systemPort}`);
582
-
583
- await this.adbExec(['reverse', `tcp:${devicePort}`, `tcp:${systemPort}`]);
584
- };
585
-
586
- methods.removePortReverse = async function removePortReverse(devicePort) {
587
- _logger.default.debug(`Removing reverse forwarded port socket connection: ${devicePort} `);
588
-
589
- await this.adbExec(['reverse', `--remove`, `tcp:${devicePort}`]);
590
- };
591
-
592
- methods.forwardAbstractPort = async function forwardAbstractPort(systemPort, devicePort) {
593
- _logger.default.debug(`Forwarding system: ${systemPort} to abstract device: ${devicePort}`);
594
-
595
- await this.adbExec(['forward', `tcp:${systemPort}`, `localabstract:${devicePort}`]);
596
- };
597
-
598
- methods.ping = async function ping() {
599
- let stdout = await this.shell(['echo', 'ping']);
600
-
601
- if (stdout.indexOf('ping') === 0) {
602
- return true;
603
- }
604
-
605
- throw new Error(`ADB ping failed, returned ${stdout}`);
606
- };
607
-
608
- methods.restart = async function restart() {
609
- try {
610
- await this.stopLogcat();
611
- await this.restartAdb();
612
- await this.waitForDevice(60);
613
- await this.startLogcat(this._logcatStartupParams);
614
- } catch (e) {
615
- throw new Error(`Restart failed. Original error: ${e.message}`);
616
- }
617
- };
618
-
619
- methods.startLogcat = async function startLogcat(opts = {}) {
620
- if (!_lodash.default.isEmpty(this.logcat)) {
621
- throw new Error("Trying to start logcat capture but it's already started!");
622
- }
623
-
624
- this.logcat = new _logcat.default({
625
- adb: this.executable,
626
- debug: false,
627
- debugTrace: false,
628
- clearDeviceLogsOnStart: !!this.clearDeviceLogsOnStart
629
- });
630
- await this.logcat.startCapture(opts);
631
- this._logcatStartupParams = opts;
632
- };
633
-
634
- methods.stopLogcat = async function stopLogcat() {
635
- if (_lodash.default.isEmpty(this.logcat)) {
636
- return;
637
- }
638
-
639
- try {
640
- await this.logcat.stopCapture();
641
- } finally {
642
- this.logcat = null;
643
- }
644
- };
645
-
646
- methods.getLogcatLogs = function getLogcatLogs() {
647
- if (_lodash.default.isEmpty(this.logcat)) {
648
- throw new Error("Can't get logcat logs since logcat hasn't started");
649
- }
650
-
651
- return this.logcat.getLogs();
652
- };
653
-
654
- methods.setLogcatListener = function setLogcatListener(listener) {
655
- if (_lodash.default.isEmpty(this.logcat)) {
656
- throw new Error("Logcat process hasn't been started");
657
- }
658
-
659
- this.logcat.on('output', listener);
660
- };
661
-
662
- methods.removeLogcatListener = function removeLogcatListener(listener) {
663
- if (_lodash.default.isEmpty(this.logcat)) {
664
- throw new Error("Logcat process hasn't been started");
665
- }
666
-
667
- this.logcat.removeListener('output', listener);
668
- };
669
-
670
- methods.listProcessStatus = async function listProcessStatus() {
671
- if (!_lodash.default.isBoolean(this._doesPsSupportAOption)) {
672
- try {
673
- this._doesPsSupportAOption = /^-A\b/m.test(await this.shell(['ps', '--help']));
674
- } catch (e) {
675
- _logger.default.debug(e.stack);
676
-
677
- this._doesPsSupportAOption = false;
678
- }
679
- }
680
-
681
- return await this.shell(this._doesPsSupportAOption ? ['ps', '-A'] : ['ps']);
682
- };
683
-
684
- methods.getNameByPid = async function getNameByPid(pid) {
685
- if (isNaN(pid)) {
686
- throw new Error(`The PID value must be a valid number. '${pid}' is given instead`);
687
- }
688
-
689
- pid = parseInt(pid, 10);
690
- const stdout = await this.listProcessStatus();
691
- const titleMatch = PS_TITLE_PATTERN.exec(stdout);
692
-
693
- if (!titleMatch) {
694
- _logger.default.debug(stdout);
695
-
696
- throw new Error(`Could not get the process name for PID '${pid}'`);
697
- }
698
-
699
- const allTitles = titleMatch[1].trim().split(/\s+/);
700
- const pidIndex = allTitles.indexOf(PID_COLUMN_TITLE);
701
- const nameOffset = allTitles.indexOf(PROCESS_NAME_COLUMN_TITLE) - allTitles.length;
702
- const pidRegex = new RegExp(`^(.*\\b${pid}\\b.*)$`, 'gm');
703
- let matchedLine;
704
-
705
- while (matchedLine = pidRegex.exec(stdout)) {
706
- const items = matchedLine[1].trim().split(/\s+/);
707
-
708
- if (parseInt(items[pidIndex], 10) === pid && items[items.length + nameOffset]) {
709
- return items[items.length + nameOffset];
710
- }
711
- }
712
-
713
- _logger.default.debug(stdout);
714
-
715
- throw new Error(`Could not get the process name for PID '${pid}'`);
716
- };
717
-
718
- methods.getPIDsByName = async function getPIDsByName(name) {
719
- _logger.default.debug(`Getting IDs of all '${name}' processes`);
720
-
721
- if (!this.isValidClass(name)) {
722
- throw new Error(`Invalid process name: '${name}'`);
723
- }
724
-
725
- if ((await this.getApiLevel()) >= 23) {
726
- if (!_lodash.default.isBoolean(this._isPgrepAvailable)) {
727
- const pgrepOutput = _lodash.default.trim(await this.shell(['pgrep --help; echo $?']));
728
-
729
- this._isPgrepAvailable = parseInt(_lodash.default.last(pgrepOutput.split(/\s+/)), 10) === 0;
730
-
731
- if (this._isPgrepAvailable) {
732
- this._canPgrepUseFullCmdLineSearch = /^-f\b/m.test(pgrepOutput);
733
- } else {
734
- this._isPidofAvailable = parseInt(await this.shell(['pidof --help > /dev/null; echo $?']), 10) === 0;
735
- }
736
- }
737
-
738
- if (this._isPgrepAvailable || this._isPidofAvailable) {
739
- const shellCommand = this._isPgrepAvailable ? this._canPgrepUseFullCmdLineSearch ? ['pgrep', '-f', _lodash.default.escapeRegExp(`([[:blank:]]|^)${name}([[:blank:]]|$)`)] : [`pgrep ^${_lodash.default.escapeRegExp(name.slice(-MAX_PGREP_PATTERN_LEN))}$ ` + `|| pgrep ^${_lodash.default.escapeRegExp(name.slice(0, MAX_PGREP_PATTERN_LEN))}$`] : ['pidof', name];
740
-
741
- try {
742
- return (await this.shell(shellCommand)).split(/\s+/).map(x => parseInt(x, 10)).filter(x => _lodash.default.isInteger(x));
743
- } catch (e) {
744
- if (e.code !== 1) {
745
- throw new Error(`Could not extract process ID of '${name}': ${e.message}`);
746
- }
747
-
748
- if (_lodash.default.includes(e.stderr || e.stdout, 'syntax error')) {
749
- _logger.default.warn(`Got an unexpected response from the shell interpreter: ${e.stderr || e.stdout}`);
750
- } else {
751
- return [];
752
- }
753
- }
754
- }
755
- }
756
-
757
- _logger.default.debug('Using ps-based PID detection');
758
-
759
- const stdout = await this.listProcessStatus();
760
- const titleMatch = PS_TITLE_PATTERN.exec(stdout);
761
-
762
- if (!titleMatch) {
763
- _logger.default.debug(stdout);
764
-
765
- throw new Error(`Could not extract PID of '${name}' from ps output`);
766
- }
767
-
768
- const allTitles = titleMatch[1].trim().split(/\s+/);
769
- const pidIndex = allTitles.indexOf(PID_COLUMN_TITLE);
770
- const pids = [];
771
- const processNameRegex = new RegExp(`^(.*\\b\\d+\\b.*\\b${_lodash.default.escapeRegExp(name)}\\b.*)$`, 'gm');
772
- let matchedLine;
773
-
774
- while (matchedLine = processNameRegex.exec(stdout)) {
775
- const items = matchedLine[1].trim().split(/\s+/);
776
-
777
- if (pidIndex >= allTitles.length || isNaN(items[pidIndex])) {
778
- _logger.default.debug(stdout);
779
-
780
- throw new Error(`Could not extract PID of '${name}' from '${matchedLine[1].trim()}'`);
781
- }
782
-
783
- pids.push(parseInt(items[pidIndex], 10));
784
- }
785
-
786
- return pids;
787
- };
788
-
789
- methods.killProcessesByName = async function killProcessesByName(name) {
790
- try {
791
- _logger.default.debug(`Attempting to kill all ${name} processes`);
792
-
793
- const pids = await this.getPIDsByName(name);
794
-
795
- if (_lodash.default.isEmpty(pids)) {
796
- _logger.default.info(`No '${name}' process has been found`);
797
- } else {
798
- await _bluebird.default.all(pids.map(p => this.killProcessByPID(p)));
799
- }
800
- } catch (e) {
801
- throw new Error(`Unable to kill ${name} processes. Original error: ${e.message}`);
802
- }
803
- };
804
-
805
- methods.killProcessByPID = async function killProcessByPID(pid) {
806
- _logger.default.debug(`Attempting to kill process ${pid}`);
807
-
808
- const noProcessFlag = 'No such process';
809
-
810
- try {
811
- await this.shell(['kill', pid]);
812
- } catch (e) {
813
- if (_lodash.default.includes(e.stderr, noProcessFlag)) {
814
- return;
815
- }
816
-
817
- if (!_lodash.default.includes(e.stderr, 'Operation not permitted')) {
818
- throw e;
819
- }
820
-
821
- _logger.default.info(`Cannot kill PID ${pid} due to insufficient permissions. Retrying as root`);
822
-
823
- try {
824
- await this.shell(['kill', pid], {
825
- privileged: true
826
- });
827
- } catch (e1) {
828
- if (_lodash.default.includes(e1.stderr, noProcessFlag)) {
829
- return;
830
- }
831
-
832
- throw e1;
833
- }
834
- }
835
- };
836
-
837
- methods.broadcastProcessEnd = async function broadcastProcessEnd(intent, processName) {
838
- this.broadcast(intent);
839
- let start = Date.now();
840
- let timeoutMs = 40000;
841
-
842
- try {
843
- while (Date.now() - start < timeoutMs) {
844
- if (await this.processExists(processName)) {
845
- await (0, _asyncbox.sleep)(400);
846
- continue;
847
- }
848
-
849
- return;
850
- }
851
-
852
- throw new Error(`Process never died within ${timeoutMs} ms`);
853
- } catch (e) {
854
- throw new Error(`Unable to broadcast process end. Original error: ${e.message}`);
855
- }
856
- };
857
-
858
- methods.broadcast = async function broadcast(intent) {
859
- if (!this.isValidClass(intent)) {
860
- throw new Error(`Invalid intent ${intent}`);
861
- }
862
-
863
- _logger.default.debug(`Broadcasting: ${intent}`);
864
-
865
- await this.shell(['am', 'broadcast', '-a', intent]);
866
- };
867
-
868
- methods.endAndroidCoverage = async function endAndroidCoverage() {
869
- if (this.instrumentProc && this.instrumentProc.isRunning) {
870
- await this.instrumentProc.stop();
871
- }
872
- };
873
-
874
- methods.instrument = async function instrument(pkg, activity, instrumentWith) {
875
- if (activity[0] !== '.') {
876
- pkg = '';
877
- }
878
-
879
- let pkgActivity = (pkg + activity).replace(/\.+/g, '.');
880
- let stdout = await this.shell(['am', 'instrument', '-e', 'main_activity', pkgActivity, instrumentWith]);
881
-
882
- if (stdout.indexOf('Exception') !== -1) {
883
- throw new Error(`Unknown exception during instrumentation. Original error ${stdout.split('\n')[0]}`);
884
- }
885
- };
886
-
887
- methods.androidCoverage = async function androidCoverage(instrumentClass, waitPkg, waitActivity) {
888
- if (!this.isValidClass(instrumentClass)) {
889
- throw new Error(`Invalid class ${instrumentClass}`);
890
- }
891
-
892
- return await new _bluebird.default(async (resolve, reject) => {
893
- let args = this.executable.defaultArgs.concat(['shell', 'am', 'instrument', '-e', 'coverage', 'true', '-w']).concat([instrumentClass]);
894
-
895
- _logger.default.debug(`Collecting coverage data with: ${[this.executable.path].concat(args).join(' ')}`);
896
-
897
- try {
898
- this.instrumentProc = new _teen_process.SubProcess(this.executable.path, args);
899
- await this.instrumentProc.start(0);
900
- this.instrumentProc.on('output', (stdout, stderr) => {
901
- if (stderr) {
902
- reject(new Error(`Failed to run instrumentation. Original error: ${stderr}`));
903
- }
904
- });
905
- await this.waitForActivity(waitPkg, waitActivity);
906
- resolve();
907
- } catch (e) {
908
- reject(new Error(`Android coverage failed. Original error: ${e.message}`));
909
- }
910
- });
911
- };
912
-
913
- methods.getDeviceProperty = async function getDeviceProperty(property) {
914
- let stdout = await this.shell(['getprop', property]);
915
- let val = stdout.trim();
916
-
917
- _logger.default.debug(`Current device property '${property}': ${val}`);
918
-
919
- return val;
920
- };
921
-
922
- methods.setDeviceProperty = async function setDeviceProperty(prop, val, opts = {}) {
923
- const {
924
- privileged = true
925
- } = opts;
926
-
927
- _logger.default.debug(`Setting device property '${prop}' to '${val}'`);
928
-
929
- await this.shell(['setprop', prop, val], {
930
- privileged
931
- });
932
- };
933
-
934
- methods.getDeviceSysLanguage = async function getDeviceSysLanguage() {
935
- return await this.getDeviceProperty('persist.sys.language');
936
- };
937
-
938
- methods.getDeviceSysCountry = async function getDeviceSysCountry() {
939
- return await this.getDeviceProperty('persist.sys.country');
940
- };
941
-
942
- methods.getDeviceSysLocale = async function getDeviceSysLocale() {
943
- return await this.getDeviceProperty('persist.sys.locale');
944
- };
945
-
946
- methods.getDeviceProductLanguage = async function getDeviceProductLanguage() {
947
- return await this.getDeviceProperty('ro.product.locale.language');
948
- };
949
-
950
- methods.getDeviceProductCountry = async function getDeviceProductCountry() {
951
- return await this.getDeviceProperty('ro.product.locale.region');
952
- };
953
-
954
- methods.getDeviceProductLocale = async function getDeviceProductLocale() {
955
- return await this.getDeviceProperty('ro.product.locale');
956
- };
957
-
958
- methods.getModel = async function getModel() {
959
- return await this.getDeviceProperty('ro.product.model');
960
- };
961
-
962
- methods.getManufacturer = async function getManufacturer() {
963
- return await this.getDeviceProperty('ro.product.manufacturer');
964
- };
965
-
966
- methods.getScreenSize = async function getScreenSize() {
967
- let stdout = await this.shell(['wm', 'size']);
968
- let size = new RegExp(/Physical size: ([^\r?\n]+)*/g).exec(stdout);
969
-
970
- if (size && size.length >= 2) {
971
- return size[1].trim();
972
- }
973
-
974
- return null;
975
- };
976
-
977
- methods.getScreenDensity = async function getScreenDensity() {
978
- let stdout = await this.shell(['wm', 'density']);
979
- let density = new RegExp(/Physical density: ([^\r?\n]+)*/g).exec(stdout);
980
-
981
- if (density && density.length >= 2) {
982
- let densityNumber = parseInt(density[1].trim(), 10);
983
- return isNaN(densityNumber) ? null : densityNumber;
984
- }
985
-
986
- return null;
987
- };
988
-
989
- methods.setHttpProxy = async function setHttpProxy(proxyHost, proxyPort) {
990
- let proxy = `${proxyHost}:${proxyPort}`;
991
-
992
- if (_lodash.default.isUndefined(proxyHost)) {
993
- throw new Error(`Call to setHttpProxy method with undefined proxy_host: ${proxy}`);
994
- }
995
-
996
- if (_lodash.default.isUndefined(proxyPort)) {
997
- throw new Error(`Call to setHttpProxy method with undefined proxy_port ${proxy}`);
998
- }
999
-
1000
- const httpProxySettins = [['http_proxy', proxy], ['global_http_proxy_host', proxyHost], ['global_http_proxy_port', proxyPort]];
1001
-
1002
- for (const [settingKey, settingValue] of httpProxySettins) {
1003
- await this.setSetting('global', settingKey, settingValue);
1004
- }
1005
- };
1006
-
1007
- methods.deleteHttpProxy = async function deleteHttpProxy() {
1008
- const httpProxySettins = ['http_proxy', 'global_http_proxy_host', 'global_http_proxy_port', 'global_http_proxy_exclusion_list'];
1009
-
1010
- for (const setting of httpProxySettins) {
1011
- await this.shell(['settings', 'delete', 'global', setting]);
1012
- }
1013
- };
1014
-
1015
- methods.setSetting = async function setSetting(namespace, setting, value) {
1016
- return await this.shell(['settings', 'put', namespace, setting, value]);
1017
- };
1018
-
1019
- methods.getSetting = async function getSetting(namespace, setting) {
1020
- return await this.shell(['settings', 'get', namespace, setting]);
1021
- };
1022
-
1023
- methods.bugreport = async function bugreport(timeout = 120000) {
1024
- return await this.adbExec(['bugreport'], {
1025
- timeout
1026
- });
1027
- };
1028
-
1029
- methods.screenrecord = function screenrecord(destination, options = {}) {
1030
- const cmd = ['screenrecord'];
1031
- const {
1032
- videoSize,
1033
- bitRate,
1034
- timeLimit,
1035
- bugReport
1036
- } = options;
1037
-
1038
- if (_support.util.hasValue(videoSize)) {
1039
- cmd.push('--size', videoSize);
1040
- }
1041
-
1042
- if (_support.util.hasValue(timeLimit)) {
1043
- cmd.push('--time-limit', timeLimit);
1044
- }
1045
-
1046
- if (_support.util.hasValue(bitRate)) {
1047
- cmd.push('--bit-rate', bitRate);
1048
- }
1049
-
1050
- if (bugReport) {
1051
- cmd.push('--bugreport');
1052
- }
1053
-
1054
- cmd.push(destination);
1055
- const fullCmd = [...this.executable.defaultArgs, 'shell', ...cmd];
1056
-
1057
- _logger.default.debug(`Building screenrecord process with the command line: adb ${_support.util.quote(fullCmd)}`);
1058
-
1059
- return new _teen_process.SubProcess(this.executable.path, fullCmd);
1060
- };
1061
-
1062
- methods.runInImeContext = async function runInImeContext(ime, fn) {
1063
- const originalIme = await this.defaultIME();
1064
-
1065
- if (originalIme === ime) {
1066
- _logger.default.debug(`The original IME is the same as '${ime}'. There is no need to reset it`);
1067
- } else {
1068
- await this.enableIME(ime);
1069
- await this.setIME(ime);
1070
- await _bluebird.default.delay(500);
1071
- }
1072
-
1073
- try {
1074
- return await fn();
1075
- } finally {
1076
- if (originalIme !== ime) {
1077
- await this.setIME(originalIme);
1078
- }
1079
- }
1080
- };
1081
-
1082
- methods.getTimeZone = async function getTimeZone() {
1083
- _logger.default.debug('Getting current timezone');
1084
-
1085
- try {
1086
- return await this.getDeviceProperty('persist.sys.timezone');
1087
- } catch (e) {
1088
- throw new Error(`Error getting timezone. Original error: ${e.message}`);
1089
- }
1090
- };
1091
-
1092
- methods.listFeatures = async function listFeatures() {
1093
- this._memoizedFeatures = this._memoizedFeatures || _lodash.default.memoize(async () => await this.adbExec(['features']), () => this.curDeviceId);
1094
-
1095
- try {
1096
- return (await this._memoizedFeatures()).split(/\s+/).map(x => x.trim()).filter(Boolean);
1097
- } catch (e) {
1098
- if (_lodash.default.includes(e.stderr, 'unknown command')) {
1099
- return [];
1100
- }
1101
-
1102
- throw e;
1103
- }
1104
- };
1105
-
1106
- methods.isStreamedInstallSupported = async function isStreamedInstallSupported() {
1107
- const proto = Object.getPrototypeOf(this);
1108
- proto._helpOutput = proto._helpOutput || (await this.adbExec(['help']));
1109
- return proto._helpOutput.includes('--streaming') && (await this.listFeatures()).includes('cmd');
1110
- };
1111
-
1112
- methods.isIncrementalInstallSupported = async function isIncrementalInstallSupported() {
1113
- const {
1114
- binary
1115
- } = await this.getVersion();
1116
-
1117
- if (!binary) {
1118
- return false;
1119
- }
1120
-
1121
- return _support.util.compareVersions(binary.version, '>=', '30.0.1') && (await this.listFeatures()).includes('abb_exec');
1122
- };
1123
-
1124
- methods.getDeviceIdleWhitelist = async function getDeviceIdleWhitelist() {
1125
- if ((await this.getApiLevel()) < 23) {
1126
- return [];
1127
- }
1128
-
1129
- _logger.default.info('Listing packages in Doze whitelist');
1130
-
1131
- const output = await this.shell(['dumpsys', 'deviceidle', 'whitelist']);
1132
- return _lodash.default.trim(output).split(/\n/).map(line => _lodash.default.trim(line)).filter(Boolean);
1133
- };
1134
-
1135
- methods.addToDeviceIdleWhitelist = async function addToDeviceIdleWhitelist(...packages) {
1136
- if (_lodash.default.isEmpty(packages) || (await this.getApiLevel()) < 23) {
1137
- return false;
1138
- }
1139
-
1140
- _logger.default.info(`Adding ${_support.util.pluralize('package', packages.length)} ${JSON.stringify(packages)} to Doze whitelist`);
1141
-
1142
- await this.shellChunks(pkg => ['dumpsys', 'deviceidle', 'whitelist', `+${pkg}`], packages);
1143
- return true;
1144
- };
1145
-
1146
- var _default = methods;
1147
- exports.default = _default;require('source-map-support').install();
1148
-
1149
-
1150
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliL3Rvb2xzL2FkYi1jb21tYW5kcy5qcyIsIm5hbWVzIjpbIk1BWF9TSEVMTF9CVUZGRVJfTEVOR1RIIiwiTk9UX0NIQU5HRUFCTEVfUEVSTV9FUlJPUiIsIklHTk9SRURfUEVSTV9FUlJPUlMiLCJNQVhfUEdSRVBfUEFUVEVSTl9MRU4iLCJISURERU5fQVBJX1BPTElDWV9LRVlTIiwiUElEX0NPTFVNTl9USVRMRSIsIlBST0NFU1NfTkFNRV9DT0xVTU5fVElUTEUiLCJQU19USVRMRV9QQVRURVJOIiwiUmVnRXhwIiwiQURCX0lOUFVUX0VTQ0FQRV9QQVRURVJOIiwibWV0aG9kcyIsInNoZWxsQ2h1bmtzIiwiYXJnVHJhbnNmb3JtZXIiLCJhcmdzIiwiY29tbWFuZHMiLCJjbWRDaHVuayIsImFyZyIsIm5leHRDbWQiLCJfIiwiaXNBcnJheSIsIkVycm9yIiwibGFzdCIsInB1c2giLCJqb2luIiwibGVuZ3RoIiwiaXNFbXB0eSIsImxvZyIsImRlYnVnIiwiSlNPTiIsInN0cmluZ2lmeSIsImxhc3RFcnJvciIsImNtZCIsInNoZWxsIiwiZSIsImdldEFkYldpdGhDb3JyZWN0QWRiUGF0aCIsImV4ZWN1dGFibGUiLCJwYXRoIiwiZ2V0U2RrQmluYXJ5UGF0aCIsImFkYiIsImluaXRBYXB0IiwiaW5pdEFhcHQyIiwiaW5pdFppcEFsaWduIiwiaW5pdEJ1bmRsZXRvb2wiLCJiaW5hcmllcyIsImJ1bmRsZXRvb2wiLCJmcyIsIndoaWNoIiwiZXJyIiwiZ2V0QXBpTGV2ZWwiLCJpc0ludGVnZXIiLCJfYXBpTGV2ZWwiLCJzdHJPdXRwdXQiLCJnZXREZXZpY2VQcm9wZXJ0eSIsImFwaUxldmVsIiwicGFyc2VJbnQiLCJ0cmltIiwiY2hhckNvZGVRIiwiY2hhckNvZGVBdCIsImFwaUxldmVsRGlmZiIsImNvZGVuYW1lIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiZ2V0UGxhdGZvcm1WZXJzaW9uIiwidG9Mb3dlckNhc2UiLCJ0b1VwcGVyQ2FzZSIsImlzTmFOIiwibWVzc2FnZSIsImluZm8iLCJpc0RldmljZUNvbm5lY3RlZCIsImRldmljZXMiLCJnZXRDb25uZWN0ZWREZXZpY2VzIiwibWtkaXIiLCJyZW1vdGVQYXRoIiwiaXNWYWxpZENsYXNzIiwiY2xhc3NTdHJpbmciLCJtYXRjaENvbXBvbmVudE5hbWUiLCJyZXNvbHZlTGF1bmNoYWJsZUFjdGl2aXR5IiwicGtnIiwib3B0cyIsInByZWZlckNtZCIsInN0ZG91dCIsIm5hbWVzIiwicGFyc2VMYXVuY2hhYmxlQWN0aXZpdHlOYW1lcyIsInRtcFJvb3QiLCJ0ZW1wRGlyIiwib3BlbkRpciIsInRtcEFwcCIsInB1bGxBcGsiLCJhcGtBY3Rpdml0eSIsInBhY2thZ2VBbmRMYXVuY2hBY3Rpdml0eUZyb21NYW5pZmVzdCIsInN0YWNrIiwid2FybiIsInJpbXJhZiIsInN0ZGVyciIsIm91dHB1dEZvcm1hdCIsIkVYRUNfT1VUUFVUX0ZPUk1BVCIsIkZVTEwiLCJsaW5lIiwic3BsaXQiLCJtYXAiLCJmb3JjZVN0b3AiLCJraWxsUGFja2FnZSIsImNsZWFyIiwiZ3JhbnRBbGxQZXJtaXNzaW9ucyIsImFwayIsInRhcmdldFNkayIsImR1bXBzeXNPdXRwdXQiLCJ0YXJnZXRTZGtWZXJzaW9uVXNpbmdQS0ciLCJ0YXJnZXRTZGtWZXJzaW9uRnJvbU1hbmlmZXN0IiwicmVxdWVzdGVkUGVybWlzc2lvbnMiLCJnZXRSZXFQZXJtaXNzaW9ucyIsImdyYW50ZWRQZXJtaXNzaW9ucyIsImdldEdyYW50ZWRQZXJtaXNzaW9ucyIsInBlcm1pc3Npb25zVG9HcmFudCIsImRpZmZlcmVuY2UiLCJncmFudFBlcm1pc3Npb25zIiwicGVybWlzc2lvbnMiLCJwZXJtIiwic29tZSIsInBhdHRlcm4iLCJ0ZXN0IiwiZ3JhbnRQZXJtaXNzaW9uIiwicGVybWlzc2lvbiIsInJldm9rZVBlcm1pc3Npb24iLCJjbWRPdXRwdXQiLCJleHRyYWN0TWF0Y2hpbmdQZXJtaXNzaW9ucyIsImdldERlbmllZFBlcm1pc3Npb25zIiwiZ2V0TG9jYXRpb25Qcm92aWRlcnMiLCJnZXRTZXR0aW5nIiwicCIsImZpbHRlciIsIkJvb2xlYW4iLCJ0b2dnbGVHUFNMb2NhdGlvblByb3ZpZGVyIiwiZW5hYmxlZCIsInNldFNldHRpbmciLCJzZXRIaWRkZW5BcGlQb2xpY3kiLCJ2YWx1ZSIsImlnbm9yZUVycm9yIiwiayIsInNldERlZmF1bHRIaWRkZW5BcGlQb2xpY3kiLCJzdG9wQW5kQ2xlYXIiLCJhdmFpbGFibGVJTUVzIiwiZ2V0SU1FTGlzdEZyb21PdXRwdXQiLCJlbmFibGVkSU1FcyIsImVuYWJsZUlNRSIsImltZUlkIiwiZGlzYWJsZUlNRSIsInNldElNRSIsImRlZmF1bHRJTUUiLCJlbmdpbmUiLCJrZXlldmVudCIsImtleWNvZGUiLCJjb2RlIiwiaW5wdXRUZXh0IiwidGV4dCIsIm9yaWdpbmFsU3RyIiwiZXNjYXBlZFRleHQiLCJyZXBsYWNlIiwiZXZlcnkiLCJjIiwiaW5jbHVkZXMiLCJxIiwiY2xlYXJUZXh0RmllbGQiLCJpIiwibG9jayIsImlzU2NyZWVuTG9ja2VkIiwidGltZW91dE1zIiwid2FpdEZvckNvbmRpdGlvbiIsIndhaXRNcyIsImludGVydmFsTXMiLCJiYWNrIiwiZ29Ub0hvbWUiLCJnZXRBZGJQYXRoIiwiZ2V0U2NyZWVuT3JpZW50YXRpb24iLCJnZXRTdXJmYWNlT3JpZW50YXRpb24iLCJzZW5kVGVsbmV0Q29tbWFuZCIsImNvbW1hbmQiLCJleGVjRW11Q29uc29sZUNvbW1hbmQiLCJwb3J0IiwiZ2V0RW11bGF0b3JQb3J0IiwiaXNBaXJwbGFuZU1vZGVPbiIsInNldEFpcnBsYW5lTW9kZSIsIm9uIiwiYnJvYWRjYXN0QWlycGxhbmVNb2RlIiwiaXNXaWZpT24iLCJpc0RhdGFPbiIsInNldFdpZmlBbmREYXRhIiwid2lmaSIsImRhdGEiLCJpc0VtdWxhdG9yIiwidXRpbCIsImhhc1ZhbHVlIiwic2V0V2lmaVN0YXRlIiwic2V0RGF0YVN0YXRlIiwiaXNBbmltYXRpb25PbiIsImFuaW1hdG9yX2R1cmF0aW9uX3NjYWxlIiwidHJhbnNpdGlvbl9hbmltYXRpb25fc2NhbGUiLCJ3aW5kb3dfYW5pbWF0aW9uX3NjYWxlIiwic2V0dGluZyIsImxvY2FsUGF0aCIsInBvc2l4IiwiZGlybmFtZSIsImFkYkV4ZWMiLCJwdWxsIiwidGltZW91dCIsInByb2Nlc3NFeGlzdHMiLCJwcm9jZXNzTmFtZSIsImdldFBJRHNCeU5hbWUiLCJnZXRGb3J3YXJkTGlzdCIsImNvbm5lY3Rpb25zIiwiRU9MIiwiZm9yd2FyZFBvcnQiLCJzeXN0ZW1Qb3J0IiwiZGV2aWNlUG9ydCIsInJlbW92ZVBvcnRGb3J3YXJkIiwiZ2V0UmV2ZXJzZUxpc3QiLCJyZXZlcnNlUG9ydCIsInJlbW92ZVBvcnRSZXZlcnNlIiwiZm9yd2FyZEFic3RyYWN0UG9ydCIsInBpbmciLCJpbmRleE9mIiwicmVzdGFydCIsInN0b3BMb2djYXQiLCJyZXN0YXJ0QWRiIiwid2FpdEZvckRldmljZSIsInN0YXJ0TG9nY2F0IiwiX2xvZ2NhdFN0YXJ0dXBQYXJhbXMiLCJsb2djYXQiLCJMb2djYXQiLCJkZWJ1Z1RyYWNlIiwiY2xlYXJEZXZpY2VMb2dzT25TdGFydCIsInN0YXJ0Q2FwdHVyZSIsInN0b3BDYXB0dXJlIiwiZ2V0TG9nY2F0TG9ncyIsImdldExvZ3MiLCJzZXRMb2djYXRMaXN0ZW5lciIsImxpc3RlbmVyIiwicmVtb3ZlTG9nY2F0TGlzdGVuZXIiLCJyZW1vdmVMaXN0ZW5lciIsImxpc3RQcm9jZXNzU3RhdHVzIiwiaXNCb29sZWFuIiwiX2RvZXNQc1N1cHBvcnRBT3B0aW9uIiwiZ2V0TmFtZUJ5UGlkIiwicGlkIiwidGl0bGVNYXRjaCIsImV4ZWMiLCJhbGxUaXRsZXMiLCJwaWRJbmRleCIsIm5hbWVPZmZzZXQiLCJwaWRSZWdleCIsIm1hdGNoZWRMaW5lIiwiaXRlbXMiLCJuYW1lIiwiX2lzUGdyZXBBdmFpbGFibGUiLCJwZ3JlcE91dHB1dCIsIl9jYW5QZ3JlcFVzZUZ1bGxDbWRMaW5lU2VhcmNoIiwiX2lzUGlkb2ZBdmFpbGFibGUiLCJzaGVsbENvbW1hbmQiLCJlc2NhcGVSZWdFeHAiLCJzbGljZSIsIngiLCJwaWRzIiwicHJvY2Vzc05hbWVSZWdleCIsImtpbGxQcm9jZXNzZXNCeU5hbWUiLCJCIiwiYWxsIiwia2lsbFByb2Nlc3NCeVBJRCIsIm5vUHJvY2Vzc0ZsYWciLCJwcml2aWxlZ2VkIiwiZTEiLCJicm9hZGNhc3RQcm9jZXNzRW5kIiwiaW50ZW50IiwiYnJvYWRjYXN0Iiwic3RhcnQiLCJEYXRlIiwibm93Iiwic2xlZXAiLCJlbmRBbmRyb2lkQ292ZXJhZ2UiLCJpbnN0cnVtZW50UHJvYyIsImlzUnVubmluZyIsInN0b3AiLCJpbnN0cnVtZW50IiwiYWN0aXZpdHkiLCJpbnN0cnVtZW50V2l0aCIsInBrZ0FjdGl2aXR5IiwiYW5kcm9pZENvdmVyYWdlIiwiaW5zdHJ1bWVudENsYXNzIiwid2FpdFBrZyIsIndhaXRBY3Rpdml0eSIsInJlc29sdmUiLCJyZWplY3QiLCJkZWZhdWx0QXJncyIsImNvbmNhdCIsIlN1YlByb2Nlc3MiLCJ3YWl0Rm9yQWN0aXZpdHkiLCJwcm9wZXJ0eSIsInZhbCIsInNldERldmljZVByb3BlcnR5IiwicHJvcCIsImdldERldmljZVN5c0xhbmd1YWdlIiwiZ2V0RGV2aWNlU3lzQ291bnRyeSIsImdldERldmljZVN5c0xvY2FsZSIsImdldERldmljZVByb2R1Y3RMYW5ndWFnZSIsImdldERldmljZVByb2R1Y3RDb3VudHJ5IiwiZ2V0RGV2aWNlUHJvZHVjdExvY2FsZSIsImdldE1vZGVsIiwiZ2V0TWFudWZhY3R1cmVyIiwiZ2V0U2NyZWVuU2l6ZSIsInNpemUiLCJnZXRTY3JlZW5EZW5zaXR5IiwiZGVuc2l0eSIsImRlbnNpdHlOdW1iZXIiLCJzZXRIdHRwUHJveHkiLCJwcm94eUhvc3QiLCJwcm94eVBvcnQiLCJwcm94eSIsImlzVW5kZWZpbmVkIiwiaHR0cFByb3h5U2V0dGlucyIsInNldHRpbmdLZXkiLCJzZXR0aW5nVmFsdWUiLCJkZWxldGVIdHRwUHJveHkiLCJuYW1lc3BhY2UiLCJidWdyZXBvcnQiLCJzY3JlZW5yZWNvcmQiLCJkZXN0aW5hdGlvbiIsIm9wdGlvbnMiLCJ2aWRlb1NpemUiLCJiaXRSYXRlIiwidGltZUxpbWl0IiwiYnVnUmVwb3J0IiwiZnVsbENtZCIsInF1b3RlIiwicnVuSW5JbWVDb250ZXh0IiwiaW1lIiwiZm4iLCJvcmlnaW5hbEltZSIsImRlbGF5IiwiZ2V0VGltZVpvbmUiLCJsaXN0RmVhdHVyZXMiLCJfbWVtb2l6ZWRGZWF0dXJlcyIsIm1lbW9pemUiLCJjdXJEZXZpY2VJZCIsImlzU3RyZWFtZWRJbnN0YWxsU3VwcG9ydGVkIiwicHJvdG8iLCJPYmplY3QiLCJnZXRQcm90b3R5cGVPZiIsIl9oZWxwT3V0cHV0IiwiaXNJbmNyZW1lbnRhbEluc3RhbGxTdXBwb3J0ZWQiLCJiaW5hcnkiLCJnZXRWZXJzaW9uIiwiY29tcGFyZVZlcnNpb25zIiwidmVyc2lvbiIsImdldERldmljZUlkbGVXaGl0ZWxpc3QiLCJvdXRwdXQiLCJhZGRUb0RldmljZUlkbGVXaGl0ZWxpc3QiLCJwYWNrYWdlcyIsInBsdXJhbGl6ZSJdLCJzb3VyY2VSb290IjoiLi4vLi4vLi4iLCJzb3VyY2VzIjpbImxpYi90b29scy9hZGItY29tbWFuZHMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGxvZyBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHtcbiAgZ2V0SU1FTGlzdEZyb21PdXRwdXQsIGdldFN1cmZhY2VPcmllbnRhdGlvbiwgZXh0cmFjdE1hdGNoaW5nUGVybWlzc2lvbnMsXG4gIHBhcnNlTGF1bmNoYWJsZUFjdGl2aXR5TmFtZXMsIG1hdGNoQ29tcG9uZW50TmFtZSxcbn0gZnJvbSAnLi4vaGVscGVycy5qcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBmcywgdXRpbCwgdGVtcERpciB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBFT0wgfSBmcm9tICdvcyc7XG5pbXBvcnQgTG9nY2F0IGZyb20gJy4uL2xvZ2NhdCc7XG5pbXBvcnQgeyBzbGVlcCwgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IFN1YlByb2Nlc3MgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuXG5jb25zdCBNQVhfU0hFTExfQlVGRkVSX0xFTkdUSCA9IDEwMDA7XG5jb25zdCBOT1RfQ0hBTkdFQUJMRV9QRVJNX0VSUk9SID0gL25vdCBhIGNoYW5nZWFibGUgcGVybWlzc2lvbiB0eXBlL2k7XG5jb25zdCBJR05PUkVEX1BFUk1fRVJST1JTID0gW1xuICBOT1RfQ0hBTkdFQUJMRV9QRVJNX0VSUk9SLFxuICAvVW5rbm93biBwZXJtaXNzaW9uL2ksXG5dO1xuY29uc3QgTUFYX1BHUkVQX1BBVFRFUk5fTEVOID0gMTU7XG5jb25zdCBISURERU5fQVBJX1BPTElDWV9LRVlTID0gW1xuICAnaGlkZGVuX2FwaV9wb2xpY3lfcHJlX3BfYXBwcycsXG4gICdoaWRkZW5fYXBpX3BvbGljeV9wX2FwcHMnLFxuICAnaGlkZGVuX2FwaV9wb2xpY3knXG5dO1xuY29uc3QgUElEX0NPTFVNTl9USVRMRSA9ICdQSUQnO1xuY29uc3QgUFJPQ0VTU19OQU1FX0NPTFVNTl9USVRMRSA9ICdOQU1FJztcbmNvbnN0IFBTX1RJVExFX1BBVFRFUk4gPSBuZXcgUmVnRXhwKGBeKC4qXFxcXGIke1BJRF9DT0xVTU5fVElUTEV9XFxcXGIuKlxcXFxiJHtQUk9DRVNTX05BTUVfQ09MVU1OX1RJVExFfVxcXFxiLiopJGAsICdtJyk7XG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yNTc5MTQyMy9hZGItc2hlbGwtaW5wdXQtdGV4dC1kb2VzLW5vdC10YWtlLWFtcGVyc2FuZC1jaGFyYWN0ZXIvMjU3OTE0OThcbmNvbnN0IEFEQl9JTlBVVF9FU0NBUEVfUEFUVEVSTiA9IC9bKCk8Pnw7JipcXFxcfl5cIiddL2c7XG5cbmNvbnN0IG1ldGhvZHMgPSB7fTtcblxuLyoqXG4gKiBDcmVhdGVzIGNodW5rcyBmb3IgdGhlIGdpdmVuIGFyZ3VtZW50cyBhbmQgZXhlY3V0ZXMgdGhlbSBpbiBgYWRiIHNoZWxsYC5cbiAqIFRoaXMgaXMgZmFzdGVyIHRoYW4gY2FsbGluZyBgYWRiIHNoZWxsYCBzZXBhcmF0ZWx5IGZvciBlYWNoIGFyZywgaG93ZXZlclxuICogdGhlcmUgaXMgYSBsaW1pdCBmb3IgYSBtYXhpbXVtIGxlbmd0aCBvZiBhIHNpbmdsZSBhZGIgY29tbWFuZC4gdGhhdCBpcyB3aHlcbiAqIHdlIG5lZWQgYWxsIHRoaXMgY29tcGxpY2F0ZWQgbG9naWMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gYXJnVHJhbnNmb3JtZXIgQSBmdW5jdGlvbiwgdGhhdCByZWNlaXZlcyBzaW5nbGUgYXJndW1lbnRcbiAqIGZyb20gdGhlIGBhcmdzYCBhcnJheSBhbmQgdHJhbnNmb3JtcyBpdCBpbnRvIGEgc2hlbGwgY29tbWFuZC4gVGhlIHJlc3VsdFxuICogb2YgdGhlIGZ1bmN0aW9uIG11c3QgYmUgYW4gYXJyYXksIHdoZXJlIGVhY2ggaXRlbSBpcyBhIHBhcnQgb2YgYSBzaW5nbGUgY29tbWFuZC5cbiAqIFRoZSBsYXN0IGl0ZW0gb2YgdGhlIGFycmF5IGNvdWxkIGJlICc7Jy4gSWYgdGhpcyBpcyBub3QgYSBzZW1pY29sb24gdGhlbiBpdCBpcyBnb2luZyB0b1xuICogYmUgYWRkZWQgYXV0b21hdGljYWxseS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyfHN0cmluZz59IGFyZ3MgQXJyYXkgb2YgYXJndW1lbnQgdmFsdWVzIHRvIGNyZWF0ZSBjaHVua3MgZm9yXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgYW55IG9mIHRoZSBjaHVua3MgcmV0dXJucyBub24temVybyBleGl0IGNvZGUgYWZ0ZXIgYmVpbmcgZXhlY3V0ZWRcbiAqL1xubWV0aG9kcy5zaGVsbENodW5rcyA9IGFzeW5jIGZ1bmN0aW9uIHNoZWxsQ2h1bmtzIChhcmdUcmFuc2Zvcm1lciwgYXJncykge1xuICBjb25zdCBjb21tYW5kcyA9IFtdO1xuICBsZXQgY21kQ2h1bmsgPSBbXTtcbiAgZm9yIChjb25zdCBhcmcgb2YgYXJncykge1xuICAgIGNvbnN0IG5leHRDbWQgPSBhcmdUcmFuc2Zvcm1lcihhcmcpO1xuICAgIGlmICghXy5pc0FycmF5KG5leHRDbWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FyZ3VtZW50IHRyYW5zZm9ybWVyIG11c3QgcmVzdWx0IGluIGFuIGFycmF5Jyk7XG4gICAgfVxuICAgIGlmIChfLmxhc3QobmV4dENtZCkgIT09ICc7Jykge1xuICAgICAgbmV4dENtZC5wdXNoKCc7Jyk7XG4gICAgfVxuICAgIGlmIChuZXh0Q21kLmpvaW4oJyAnKS5sZW5ndGggKyBjbWRDaHVuay5qb2luKCcgJykubGVuZ3RoID49IE1BWF9TSEVMTF9CVUZGRVJfTEVOR1RIKSB7XG4gICAgICBjb21tYW5kcy5wdXNoKGNtZENodW5rKTtcbiAgICAgIGNtZENodW5rID0gW107XG4gICAgfVxuICAgIGNtZENodW5rID0gWy4uLmNtZENodW5rLCAuLi5uZXh0Q21kXTtcbiAgfVxuICBpZiAoIV8uaXNFbXB0eShjbWRDaHVuaykpIHtcbiAgICBjb21tYW5kcy5wdXNoKGNtZENodW5rKTtcbiAgfVxuICBsb2cuZGVidWcoYEdvdCB0aGUgZm9sbG93aW5nIGNvbW1hbmQgY2h1bmtzIHRvIGV4ZWN1dGU6ICR7SlNPTi5zdHJpbmdpZnkoY29tbWFuZHMpfWApO1xuICBsZXQgbGFzdEVycm9yID0gbnVsbDtcbiAgZm9yIChjb25zdCBjbWQgb2YgY29tbWFuZHMpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zaGVsbChjbWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxhc3RFcnJvciA9IGU7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0RXJyb3IpIHtcbiAgICB0aHJvdyBsYXN0RXJyb3I7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IHRoZSBwYXRoIHRvIGFkYiBleGVjdXRhYmxlIGFtZCBhc3NpZ24gaXRcbiAqIHRvIHRoaXMuZXhlY3V0YWJsZS5wYXRoIGFuZCB0aGlzLmJpbmFyaWVzLmFkYiBwcm9wZXJ0aWVzLlxuICpcbiAqIEByZXR1cm4ge0FEQn0gQURCIGluc3RhbmNlLlxuICovXG5tZXRob2RzLmdldEFkYldpdGhDb3JyZWN0QWRiUGF0aCA9IGFzeW5jIGZ1bmN0aW9uIGdldEFkYldpdGhDb3JyZWN0QWRiUGF0aCAoKSB7XG4gIHRoaXMuZXhlY3V0YWJsZS5wYXRoID0gYXdhaXQgdGhpcy5nZXRTZGtCaW5hcnlQYXRoKCdhZGInKTtcbiAgcmV0dXJuIHRoaXMuYWRiO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGZ1bGwgcGF0aCB0byBhYXB0IHRvb2wgYW5kIGFzc2lnbiBpdCB0b1xuICogdGhpcy5iaW5hcmllcy5hYXB0IHByb3BlcnR5XG4gKi9cbm1ldGhvZHMuaW5pdEFhcHQgPSBhc3luYyBmdW5jdGlvbiBpbml0QWFwdCAoKSB7XG4gIGF3YWl0IHRoaXMuZ2V0U2RrQmluYXJ5UGF0aCgnYWFwdCcpO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGZ1bGwgcGF0aCB0byBhYXB0MiB0b29sIGFuZCBhc3NpZ24gaXQgdG9cbiAqIHRoaXMuYmluYXJpZXMuYWFwdDIgcHJvcGVydHlcbiAqL1xubWV0aG9kcy5pbml0QWFwdDIgPSBhc3luYyBmdW5jdGlvbiBpbml0QWFwdDIgKCkge1xuICBhd2FpdCB0aGlzLmdldFNka0JpbmFyeVBhdGgoJ2FhcHQyJyk7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgZnVsbCBwYXRoIHRvIHppcGFsaWduIHRvb2wgYW5kIGFzc2lnbiBpdCB0b1xuICogdGhpcy5iaW5hcmllcy56aXBhbGlnbiBwcm9wZXJ0eVxuICovXG5tZXRob2RzLmluaXRaaXBBbGlnbiA9IGFzeW5jIGZ1bmN0aW9uIGluaXRaaXBBbGlnbiAoKSB7XG4gIGF3YWl0IHRoaXMuZ2V0U2RrQmluYXJ5UGF0aCgnemlwYWxpZ24nKTtcbn07XG5cbi8qKlxuICogR2V0IHRoZSBmdWxsIHBhdGggdG8gYnVuZGxldG9vbCBiaW5hcnkgYW5kIGFzc2lnbiBpdCB0b1xuICogdGhpcy5iaW5hcmllcy5idW5kbGV0b29sIHByb3BlcnR5XG4gKi9cbm1ldGhvZHMuaW5pdEJ1bmRsZXRvb2wgPSBhc3luYyBmdW5jdGlvbiBpbml0QnVuZGxldG9vbCAoKSB7XG4gIHRyeSB7XG4gICAgdGhpcy5iaW5hcmllcy5idW5kbGV0b29sID0gYXdhaXQgZnMud2hpY2goJ2J1bmRsZXRvb2wuamFyJyk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcignYnVuZGxldG9vbC5qYXIgYmluYXJ5IGlzIGV4cGVjdGVkIHRvIGJlIHByZXNlbnQgaW4gUEFUSC4gJyArXG4gICAgICAnVmlzaXQgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9idW5kbGV0b29sIGZvciBtb3JlIGRldGFpbHMuJyk7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIEFQSSBsZXZlbCBvZiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgQVBJIGxldmVsIGFzIGludGVnZXIgbnVtYmVyLCBmb3IgZXhhbXBsZSAyMSBmb3JcbiAqICAgICAgICAgICAgICAgICAgQW5kcm9pZCBMb2xsaXBvcC4gVGhlIHJlc3VsdCBvZiB0aGlzIG1ldGhvZCBpcyBjYWNoZWQsIHNvIGFsbCB0aGUgZnVydGhlclxuICogY2FsbHMgcmV0dXJuIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBmaXJzdCBvbmUuXG4gKi9cbm1ldGhvZHMuZ2V0QXBpTGV2ZWwgPSBhc3luYyBmdW5jdGlvbiBnZXRBcGlMZXZlbCAoKSB7XG4gIGlmICghXy5pc0ludGVnZXIodGhpcy5fYXBpTGV2ZWwpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0ck91dHB1dCA9IGF3YWl0IHRoaXMuZ2V0RGV2aWNlUHJvcGVydHkoJ3JvLmJ1aWxkLnZlcnNpb24uc2RrJyk7XG4gICAgICBsZXQgYXBpTGV2ZWwgPSBwYXJzZUludChzdHJPdXRwdXQudHJpbSgpLCAxMCk7XG5cbiAgICAgIC8vIFdvcmthcm91bmQgZm9yIHByZXZpZXcvYmV0YSBwbGF0Zm9ybSBBUEkgbGV2ZWxcbiAgICAgIGNvbnN0IGNoYXJDb2RlUSA9ICdxJy5jaGFyQ29kZUF0KDApO1xuICAgICAgLy8gMjggaXMgdGhlIGZpcnN0IEFQSSBMZXZlbCwgd2hlcmUgQW5kcm9pZCBTREsgc3RhcnRlZCByZXR1cm5pbmcgbGV0dGVycyBpbiByZXNwb25zZSB0byBnZXRQbGF0Zm9ybVZlcnNpb25cbiAgICAgIGNvbnN0IGFwaUxldmVsRGlmZiA9IGFwaUxldmVsIC0gMjg7XG4gICAgICBjb25zdCBjb2RlbmFtZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGVRICsgYXBpTGV2ZWxEaWZmKTtcbiAgICAgIGlmIChhcGlMZXZlbERpZmYgPj0gMCAmJiAoYXdhaXQgdGhpcy5nZXRQbGF0Zm9ybVZlcnNpb24oKSkudG9Mb3dlckNhc2UoKSA9PT0gY29kZW5hbWUpIHtcbiAgICAgICAgbG9nLmRlYnVnKGBSZWxlYXNlIHZlcnNpb24gaXMgJHtjb2RlbmFtZS50b1VwcGVyQ2FzZSgpfSBidXQgZm91bmQgQVBJIExldmVsICR7YXBpTGV2ZWx9LiBTZXR0aW5nIEFQSSBMZXZlbCB0byAke2FwaUxldmVsICsgMX1gKTtcbiAgICAgICAgYXBpTGV2ZWwrKztcbiAgICAgIH1cblxuICAgICAgdGhpcy5fYXBpTGV2ZWwgPSBhcGlMZXZlbDtcbiAgICAgIGxvZy5kZWJ1ZyhgRGV2aWNlIEFQSSBsZXZlbDogJHt0aGlzLl9hcGlMZXZlbH1gKTtcbiAgICAgIGlmIChpc05hTih0aGlzLl9hcGlMZXZlbCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgYWN0dWFsIG91dHB1dCAnJHtzdHJPdXRwdXR9JyBjYW5ub3QgYmUgY29udmVydGVkIHRvIGFuIGludGVnZXJgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGdldHRpbmcgZGV2aWNlIEFQSSBsZXZlbC4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcy5fYXBpTGV2ZWw7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBwbGF0Zm9ybSB2ZXJzaW9uIG9mIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwbGF0Zm9ybSB2ZXJzaW9uIGFzIGEgc3RyaW5nLCBmb3IgZXhhbXBsZSAnNS4wJyBmb3JcbiAqIEFuZHJvaWQgTG9sbGlwb3AuXG4gKi9cbm1ldGhvZHMuZ2V0UGxhdGZvcm1WZXJzaW9uID0gYXN5bmMgZnVuY3Rpb24gZ2V0UGxhdGZvcm1WZXJzaW9uICgpIHtcbiAgbG9nLmluZm8oJ0dldHRpbmcgZGV2aWNlIHBsYXRmb3JtIHZlcnNpb24nKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5nZXREZXZpY2VQcm9wZXJ0eSgncm8uYnVpbGQudmVyc2lvbi5yZWxlYXNlJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGdldHRpbmcgZGV2aWNlIHBsYXRmb3JtIHZlcnNpb24uIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBWZXJpZnkgd2hldGhlciBhIGRldmljZSBpcyBjb25uZWN0ZWQuXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBhdCBsZWFzdCBvbmUgZGV2aWNlIGlzIHZpc2libGUgdG8gYWRiLlxuICovXG5tZXRob2RzLmlzRGV2aWNlQ29ubmVjdGVkID0gYXN5bmMgZnVuY3Rpb24gaXNEZXZpY2VDb25uZWN0ZWQgKCkge1xuICBsZXQgZGV2aWNlcyA9IGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkRGV2aWNlcygpO1xuICByZXR1cm4gZGV2aWNlcy5sZW5ndGggPiAwO1xufTtcblxuLyoqXG4gKiBSZWN1cnNpdmVseSBjcmVhdGUgYSBuZXcgZm9sZGVyIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVtb3RlUGF0aCAtIFRoZSBuZXcgcGF0aCB0byBiZSBjcmVhdGVkLlxuICogQHJldHVybiB7c3RyaW5nfSBta2RpciBjb21tYW5kIG91dHB1dC5cbiAqL1xubWV0aG9kcy5ta2RpciA9IGFzeW5jIGZ1bmN0aW9uIG1rZGlyIChyZW1vdGVQYXRoKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLnNoZWxsKFsnbWtkaXInLCAnLXAnLCByZW1vdGVQYXRoXSk7XG59O1xuXG4vKipcbiAqIFZlcmlmeSB3aGV0aGVyIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBhXG4gKiB2YWxpZCBjbGFzcyBuYW1lLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc1N0cmluZyAtIFRoZSBhY3R1YWwgY2xhc3MgbmFtZSB0byBiZSB2ZXJpZmllZC5cbiAqIEByZXR1cm4gez9BcnJheS48TWF0Y2g+fSBUaGUgcmVzdWx0IG9mIFJlZ2V4cC5leGVjIG9wZXJhdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgICAgIG9yIF9udWxsXyBpZiBubyBtYXRjaGVzIGFyZSBmb3VuZC5cbiAqL1xubWV0aG9kcy5pc1ZhbGlkQ2xhc3MgPSBmdW5jdGlvbiBpc1ZhbGlkQ2xhc3MgKGNsYXNzU3RyaW5nKSB7XG4gIC8vIHNvbWUucGFja2FnZS9zb21lLnBhY2thZ2UuQWN0aXZpdHlcbiAgcmV0dXJuIG1hdGNoQ29tcG9uZW50TmFtZShjbGFzc1N0cmluZyk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFJlc29sdmVBY3Rpdml0eU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbj99IHByZWZlckNtZCBbdHJ1ZV0gV2hldGhlciB0byBwcmVmZXIgYGNtZGAgdG9vbCB1c2FnZSBmb3JcbiAqIGxhdW5jaGFibGUgYWN0aXZpdHkgbmFtZSBkZXRlY3Rpb24uIEl0IG1pZ2h0IGJlIHVzZWZ1bCB0byBkaXNhYmxlIGl0IGlmXG4gKiBgY21kIHBhY2thZ2UgcmVzb2x2ZS1hY3Rpdml0eWAgcmV0dXJucyAnYW5kcm9pZC9jb20uYW5kcm9pZC5pbnRlcm5hbC5hcHAuUmVzb2x2ZXJBY3Rpdml0eScsXG4gKiB3aGljaCBtZWFucyB0aGUgYXBwIGhhcyBubyBkZWZhdWx0IGhhbmRsZXIgc2V0IGluIHN5c3RlbSBzZXR0aW5ncy5cbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYXBwaXVtL2FwcGl1bS9pc3N1ZXMvMTcxMjggZm9yIG1vcmUgZGV0YWlscy5cbiAqIFRoaXMgb3B0aW9uIGhhcyBubyBlZmZlY3QgaWYgdGhlIHRhcmdldCBBbmRyb2lkIHZlcnNpb24gaXMgYmVsb3cgMjQgYXMgdGhlcmVcbiAqIHRoZSBjb3JyZXNwb25kaW5nIGBjbWRgIHN1YmNvbW1hbmQgaXMgbm90IGltcGxlbWVudGVkIGFuZCBkdW1wc3lzIHVzYWdlIGlzIHRoZSBvbmx5XG4gKiBwb3NzaWJsZSB3YXkgdG8gZGV0ZWN0IHRoZSBsYXVuY2hhYmxlIGFjdGl2aXR5IG5hbWUuXG4gKi9cblxuLyoqXG4gKiBGZXRjaGVzIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgbGF1bmNoYWJsZSBhY3Rpdml0eSBmb3IgdGhlXG4gKiBnaXZlbiBwYWNrYWdlLiBJdCBpcyBleHBlY3RlZCB0aGUgcGFja2FnZSBpcyBhbHJlYWR5IGluc3RhbGxlZCBvblxuICogdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgdGFyZ2V0IHBhY2thZ2UgaWRlbnRpZmllclxuICogQHBhcmFtIHtSZXNvbHZlQWN0aXZpdHlPcHRpb25zP30gb3B0c1xuICogQHJldHVybiB7c3RyaW5nfSBGdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgbGF1bmNoYWJsZSBhY3Rpdml0eVxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSByZXNvbHZpbmcgdGhlIGFjdGl2aXR5IG5hbWVcbiAqL1xubWV0aG9kcy5yZXNvbHZlTGF1bmNoYWJsZUFjdGl2aXR5ID0gYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUxhdW5jaGFibGVBY3Rpdml0eSAocGtnLCBvcHRzID0ge30pIHtcbiAgY29uc3QgeyBwcmVmZXJDbWQgPSB0cnVlIH0gPSBvcHRzO1xuICBpZiAoIXByZWZlckNtZCB8fCBhd2FpdCB0aGlzLmdldEFwaUxldmVsKCkgPCAyNCkge1xuICAgIGNvbnN0IHN0ZG91dCA9IGF3YWl0IHRoaXMuc2hlbGwoWydkdW1wc3lzJywgJ3BhY2thZ2UnLCBwa2ddKTtcbiAgICBjb25zdCBuYW1lcyA9IHBhcnNlTGF1bmNoYWJsZUFjdGl2aXR5TmFtZXMoc3Rkb3V0KTtcbiAgICBpZiAoXy5pc0VtcHR5KG5hbWVzKSkge1xuICAgICAgbG9nLmRlYnVnKHN0ZG91dCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byByZXNvbHZlIHRoZSBsYXVuY2hhYmxlIGFjdGl2aXR5IG9mICcke3BrZ30nLiBJcyBpdCBpbnN0YWxsZWQgb24gdGhlIGRldmljZT9gKTtcbiAgICB9XG4gICAgaWYgKG5hbWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIG5hbWVzWzBdO1xuICAgIH1cblxuICAgIGNvbnN0IHRtcFJvb3QgPSBhd2FpdCB0ZW1wRGlyLm9wZW5EaXIoKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdG1wQXBwID0gYXdhaXQgdGhpcy5wdWxsQXBrKHBrZywgdG1wUm9vdCk7XG4gICAgICBjb25zdCB7YXBrQWN0aXZpdHl9ID0gYXdhaXQgdGhpcy5wYWNrYWdlQW5kTGF1bmNoQWN0aXZpdHlGcm9tTWFuaWZlc3QodG1wQXBwKTtcbiAgICAgIHJldHVybiBhcGtBY3Rpdml0eTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2cuZGVidWcoZS5zdGFjayk7XG4gICAgICBsb2cud2FybihgVW5hYmxlIHRvIHJlc29sdmUgdGhlIGxhdW5jaGFibGUgYWN0aXZpdHkgb2YgJyR7cGtnfScuIGAgK1xuICAgICAgICBgVGhlIHZlcnkgZmlyc3QgbWF0Y2ggb2YgdGhlIGR1bXBzeXMgb3V0cHV0IGlzIGdvaW5nIHRvIGJlIHVzZWQuIGAgK1xuICAgICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgcmV0dXJuIG5hbWVzWzBdO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHtzdGRvdXQsIHN0ZGVycn0gPSBhd2FpdCB0aGlzLnNoZWxsKFsnY21kJywgJ3BhY2thZ2UnLCAncmVzb2x2ZS1hY3Rpdml0eScsICctLWJyaWVmJywgcGtnXSwge1xuICAgIG91dHB1dEZvcm1hdDogdGhpcy5FWEVDX09VVFBVVF9GT1JNQVQuRlVMTFxuICB9KTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIChzdGRvdXQgfHwgJycpLnNwbGl0KCdcXG4nKS5tYXAoXy50cmltKSkge1xuICAgIGlmICh0aGlzLmlzVmFsaWRDbGFzcyhsaW5lKSkge1xuICAgICAgcmV0dXJuIGxpbmU7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHJlc29sdmUgdGhlIGxhdW5jaGFibGUgYWN0aXZpdHkgb2YgJyR7cGtnfScuIE9yaWdpbmFsIGVycm9yOiAke3N0ZGVyciB8fCBzdGRvdXR9YCk7XG59O1xuXG4vKipcbiAqIEZvcmNlIGFwcGxpY2F0aW9uIHRvIHN0b3Agb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHN0b3BwZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBvdXRwdXQgb2YgdGhlIGNvcnJlc3BvbmRpbmcgYWRiIGNvbW1hbmQuXG4gKi9cbm1ldGhvZHMuZm9yY2VTdG9wID0gYXN5bmMgZnVuY3Rpb24gZm9yY2VTdG9wIChwa2cpIHtcbiAgcmV0dXJuIGF3YWl0IHRoaXMuc2hlbGwoWydhbScsICdmb3JjZS1zdG9wJywgcGtnXSk7XG59O1xuXG4vKlxuICogS2lsbCBhcHBsaWNhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHN0b3BwZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBvdXRwdXQgb2YgdGhlIGNvcnJlc3BvbmRpbmcgYWRiIGNvbW1hbmQuXG4gKi9cbm1ldGhvZHMua2lsbFBhY2thZ2UgPSBhc3luYyBmdW5jdGlvbiBraWxsUGFja2FnZSAocGtnKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLnNoZWxsKFsnYW0nLCAna2lsbCcsIHBrZ10pO1xufTtcblxuLyoqXG4gKiBDbGVhciB0aGUgdXNlciBkYXRhIG9mIHRoZSBwYXJ0aWN1bGFyIGFwcGxpY2F0aW9uIG9uIHRoZSBkZXZpY2VcbiAqIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBrZyAtIFRoZSBwYWNrYWdlIG5hbWUgdG8gYmUgY2xlYXJlZC5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIG91dHB1dCBvZiB0aGUgY29ycmVzcG9uZGluZyBhZGIgY29tbWFuZC5cbiAqL1xubWV0aG9kcy5jbGVhciA9IGFzeW5jIGZ1bmN0aW9uIGNsZWFyIChwa2cpIHtcbiAgcmV0dXJuIGF3YWl0IHRoaXMuc2hlbGwoWydwbScsICdjbGVhcicsIHBrZ10pO1xufTtcblxuLyoqXG4gKiBHcmFudCBhbGwgcGVybWlzc2lvbnMgcmVxdWVzdGVkIGJ5IHRoZSBwYXJ0aWN1bGFyIHBhY2thZ2UuXG4gKiBUaGlzIG1ldGhvZCBpcyBvbmx5IHVzZWZ1bCBvbiBBbmRyb2lkIDYuMCsgYW5kIGZvciBhcHBsaWNhdGlvbnNcbiAqIHRoYXQgc3VwcG9ydCBjb21wb25lbnRzLWJhc2VkIHBlcm1pc3Npb25zIHNldHRpbmcuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBrZyAtIFRoZSBwYWNrYWdlIG5hbWUgdG8gYmUgcHJvY2Vzc2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IGFwayAtIFRoZSBwYXRoIHRvIHRoZSBhY3R1YWwgYXBrIGZpbGUuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGFuIGVycm9yIHdoaWxlIGdyYW50aW5nIHBlcm1pc3Npb25zXG4gKi9cbm1ldGhvZHMuZ3JhbnRBbGxQZXJtaXNzaW9ucyA9IGFzeW5jIGZ1bmN0aW9uIGdyYW50QWxsUGVybWlzc2lvbnMgKHBrZywgYXBrKSB7XG4gIGNvbnN0IGFwaUxldmVsID0gYXdhaXQgdGhpcy5nZXRBcGlMZXZlbCgpO1xuICBsZXQgdGFyZ2V0U2RrID0gMDtcbiAgbGV0IGR1bXBzeXNPdXRwdXQgPSBudWxsO1xuICB0cnkge1xuICAgIGlmICghYXBrKSB7XG4gICAgICAvKipcbiAgICAgICAqIElmIGFwayBub3QgcHJvdmlkZWQsIGNvbnNpZGVyaW5nIGFwayBhbHJlYWR5IGluc3RhbGxlZCBvbiB0aGUgZGV2aWNlXG4gICAgICAgKiBhbmQgZmV0Y2hpbmcgdGFyZ2V0U2RrIHVzaW5nIHBhY2thZ2UgbmFtZS5cbiAgICAgICAqL1xuICAgICAgZHVtcHN5c091dHB1dCA9IGF3YWl0IHRoaXMuc2hlbGwoWydkdW1wc3lzJywgJ3BhY2thZ2UnLCBwa2ddKTtcbiAgICAgIHRhcmdldFNkayA9IGF3YWl0IHRoaXMudGFyZ2V0U2RrVmVyc2lvblVzaW5nUEtHKHBrZywgZHVtcHN5c091dHB1dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldFNkayA9IGF3YWl0IHRoaXMudGFyZ2V0U2RrVmVyc2lvbkZyb21NYW5pZmVzdChhcGspO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vYXZvaWRpbmcgbG9nZ2luZyBlcnJvciBzdGFjaywgYXMgY2FsbGluZyBsaWJyYXJ5IGZ1bmN0aW9uIHdvdWxkIGhhdmUgbG9nZ2VkXG4gICAgbG9nLndhcm4oYFJhbiBpbnRvIHByb2JsZW0gZ2V0dGluZyB0YXJnZXQgU0RLIHZlcnNpb247IGlnbm9yaW5nLi4uYCk7XG4gIH1cbiAgaWYgKGFwaUxldmVsID49IDIzICYmIHRhcmdldFNkayA+PSAyMykge1xuICAgIC8qKlxuICAgICAqIElmIHRoZSBkZXZpY2UgaXMgcnVubmluZyBBbmRyb2lkIDYuMChBUEkgMjMpIG9yIGhpZ2hlciwgYW5kIHlvdXIgYXBwJ3MgdGFyZ2V0IFNESyBpcyAyMyBvciBoaWdoZXI6XG4gICAgICogVGhlIGFwcCBoYXMgdG8gbGlzdCB0aGUgcGVybWlzc2lvbnMgaW4gdGhlIG1hbmlmZXN0LlxuICAgICAqIHJlZmVyOiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS90cmFpbmluZy9wZXJtaXNzaW9ucy9yZXF1ZXN0aW5nLmh0bWxcbiAgICAgKi9cbiAgICBkdW1wc3lzT3V0cHV0ID0gZHVtcHN5c091dHB1dCB8fCBhd2FpdCB0aGlzLnNoZWxsKFsnZHVtcHN5cycsICdwYWNrYWdlJywgcGtnXSk7XG4gICAgY29uc3QgcmVxdWVzdGVkUGVybWlzc2lvbnMgPSBhd2FpdCB0aGlzLmdldFJlcVBlcm1pc3Npb25zKHBrZywgZHVtcHN5c091dHB1dCk7XG4gICAgY29uc3QgZ3JhbnRlZFBlcm1pc3Npb25zID0gYXdhaXQgdGhpcy5nZXRHcmFudGVkUGVybWlzc2lvbnMocGtnLCBkdW1wc3lzT3V0cHV0KTtcbiAgICBjb25zdCBwZXJtaXNzaW9uc1RvR3JhbnQgPSBfLmRpZmZlcmVuY2UocmVxdWVzdGVkUGVybWlzc2lvbnMsIGdyYW50ZWRQZXJtaXNzaW9ucyk7XG4gICAgaWYgKF8uaXNFbXB0eShwZXJtaXNzaW9uc1RvR3JhbnQpKSB7XG4gICAgICBsb2cuaW5mbyhgJHtwa2d9IGNvbnRhaW5zIG5vIHBlcm1pc3Npb25zIGF2YWlsYWJsZSBmb3IgZ3JhbnRpbmdgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy5ncmFudFBlcm1pc3Npb25zKHBrZywgcGVybWlzc2lvbnNUb0dyYW50KTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogR3JhbnQgbXVsdGlwbGUgcGVybWlzc2lvbnMgZm9yIHRoZSBwYXJ0aWN1bGFyIHBhY2thZ2UuXG4gKiBUaGlzIGNhbGwgaXMgbW9yZSBwZXJmb3JtYW50IHRoYW4gYGdyYW50UGVybWlzc2lvbmAgb25lLCBzaW5jZSBpdCBjb21iaW5lc1xuICogbXVsdGlwbGUgYGFkYiBzaGVsbGAgY2FsbHMgaW50byBhIHNpbmdsZSBjb21tYW5kLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHByb2Nlc3NlZC5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gcGVybWlzc2lvbnMgLSBUaGUgbGlzdCBvZiBwZXJtaXNzaW9ucyB0byBiZSBncmFudGVkLlxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBjaGFuZ2luZyBwZXJtaXNzaW9ucy5cbiAqL1xubWV0aG9kcy5ncmFudFBlcm1pc3Npb25zID0gYXN5bmMgZnVuY3Rpb24gZ3JhbnRQZXJtaXNzaW9ucyAocGtnLCBwZXJtaXNzaW9ucykge1xuICAvLyBBcyBpdCBjb25zdW1lcyBtb3JlIHRpbWUgZm9yIGdyYW50aW5nIGVhY2ggcGVybWlzc2lvbixcbiAgLy8gdHJ5aW5nIHRvIGdyYW50IGFsbCBwZXJtaXNzaW9uIGJ5IGZvcm1pbmcgZXF1aXZhbGVudCBjb21tYW5kLlxuICAvLyBBbHNvLCBpdCBpcyBuZWNlc3NhcnkgdG8gc3BsaXQgbG9uZyBjb21tYW5kcyBpbnRvIGNodW5rcywgc2luY2UgdGhlIG1heGltdW0gbGVuZ3RoIG9mXG4gIC8vIGFkYiBzaGVsbCBidWZmZXIgaXMgbGltaXRlZFxuICBsb2cuZGVidWcoYEdyYW50aW5nIHBlcm1pc3Npb25zICR7SlNPTi5zdHJpbmdpZnkocGVybWlzc2lvbnMpfSB0byAnJHtwa2d9J2ApO1xuICB0cnkge1xuICAgIGF3YWl0IHRoaXMuc2hlbGxDaHVua3MoKHBlcm0pID0+IFsncG0nLCAnZ3JhbnQnLCBwa2csIHBlcm1dLCBwZXJtaXNzaW9ucyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIUlHTk9SRURfUEVSTV9FUlJPUlMuc29tZSgocGF0dGVybikgPT4gcGF0dGVybi50ZXN0KGUuc3RkZXJyIHx8IGUubWVzc2FnZSkpKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBHcmFudCBzaW5nbGUgcGVybWlzc2lvbiBmb3IgdGhlIHBhcnRpY3VsYXIgcGFja2FnZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGtnIC0gVGhlIHBhY2thZ2UgbmFtZSB0byBiZSBwcm9jZXNzZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGVybWlzc2lvbiAtIFRoZSBmdWxsIG5hbWUgb2YgdGhlIHBlcm1pc3Npb24gdG8gYmUgZ3JhbnRlZC5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgY2hhbmdpbmcgcGVybWlzc2lvbnMuXG4gKi9cbm1ldGhvZHMuZ3JhbnRQZXJtaXNzaW9uID0gYXN5bmMgZnVuY3Rpb24gZ3JhbnRQZXJtaXNzaW9uIChwa2csIHBlcm1pc3Npb24pIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFsncG0nLCAnZ3JhbnQnLCBwa2csIHBlcm1pc3Npb25dKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmICghTk9UX0NIQU5HRUFCTEVfUEVSTV9FUlJPUi50ZXN0KGUuc3RkZXJyIHx8IGUubWVzc2FnZSkpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJldm9rZSBzaW5nbGUgcGVybWlzc2lvbiBmcm9tIHRoZSBwYXJ0aWN1bGFyIHBhY2thZ2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBrZyAtIFRoZSBwYWNrYWdlIG5hbWUgdG8gYmUgcHJvY2Vzc2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IHBlcm1pc3Npb24gLSBUaGUgZnVsbCBuYW1lIG9mIHRoZSBwZXJtaXNzaW9uIHRvIGJlIHJldm9rZWQuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlcmUgd2FzIGFuIGVycm9yIHdoaWxlIGNoYW5naW5nIHBlcm1pc3Npb25zLlxuICovXG5tZXRob2RzLnJldm9rZVBlcm1pc3Npb24gPSBhc3luYyBmdW5jdGlvbiByZXZva2VQZXJtaXNzaW9uIChwa2csIHBlcm1pc3Npb24pIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFsncG0nLCAncmV2b2tlJywgcGtnLCBwZXJtaXNzaW9uXSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIU5PVF9DSEFOR0VBQkxFX1BFUk1fRVJST1IudGVzdChlLnN0ZGVyciB8fCBlLm1lc3NhZ2UpKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBSZXRyaWV2ZSB0aGUgbGlzdCBvZiBncmFudGVkIHBlcm1pc3Npb25zIGZvciB0aGUgcGFydGljdWxhciBwYWNrYWdlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHByb2Nlc3NlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbWRPdXRwdXQgW251bGxdIC0gT3B0aW9uYWwgcGFyYW1ldGVyIGNvbnRhaW5pbmcgY29tbWFuZCBvdXRwdXQgb2ZcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2R1bXBzeXMgcGFja2FnZV8gY29tbWFuZC4gSXQgbWF5IHNwZWVkIHVwIHRoZSBtZXRob2QgZXhlY3V0aW9uLlxuICogQHJldHVybiB7QXJyYXk8U3RyaW5nPn0gVGhlIGxpc3Qgb2YgZ3JhbnRlZCBwZXJtaXNzaW9ucyBvciBhbiBlbXB0eSBsaXN0LlxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBjaGFuZ2luZyBwZXJtaXNzaW9ucy5cbiAqL1xubWV0aG9kcy5nZXRHcmFudGVkUGVybWlzc2lvbnMgPSBhc3luYyBmdW5jdGlvbiBnZXRHcmFudGVkUGVybWlzc2lvbnMgKHBrZywgY21kT3V0cHV0ID0gbnVsbCkge1xuICBsb2cuZGVidWcoJ1JldHJpZXZpbmcgZ3JhbnRlZCBwZXJtaXNzaW9ucycpO1xuICBjb25zdCBzdGRvdXQgPSBjbWRPdXRwdXQgfHwgYXdhaXQgdGhpcy5zaGVsbChbJ2R1bXBzeXMnLCAncGFja2FnZScsIHBrZ10pO1xuICByZXR1cm4gZXh0cmFjdE1hdGNoaW5nUGVybWlzc2lvbnMoc3Rkb3V0LCBbJ2luc3RhbGwnLCAncnVudGltZSddLCB0cnVlKTtcbn07XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGxpc3Qgb2YgZGVuaWVkIHBlcm1pc3Npb25zIGZvciB0aGUgcGFydGljdWxhciBwYWNrYWdlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHByb2Nlc3NlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbWRPdXRwdXQgW251bGxdIC0gT3B0aW9uYWwgcGFyYW1ldGVyIGNvbnRhaW5pbmcgY29tbWFuZCBvdXRwdXQgb2ZcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2R1bXBzeXMgcGFja2FnZV8gY29tbWFuZC4gSXQgbWF5IHNwZWVkIHVwIHRoZSBtZXRob2QgZXhlY3V0aW9uLlxuICogQHJldHVybiB7QXJyYXk8U3RyaW5nPn0gVGhlIGxpc3Qgb2YgZGVuaWVkIHBlcm1pc3Npb25zIG9yIGFuIGVtcHR5IGxpc3QuXG4gKi9cbm1ldGhvZHMuZ2V0RGVuaWVkUGVybWlzc2lvbnMgPSBhc3luYyBmdW5jdGlvbiBnZXREZW5pZWRQZXJtaXNzaW9ucyAocGtnLCBjbWRPdXRwdXQgPSBudWxsKSB7XG4gIGxvZy5kZWJ1ZygnUmV0cmlldmluZyBkZW5pZWQgcGVybWlzc2lvbnMnKTtcbiAgY29uc3Qgc3Rkb3V0ID0gY21kT3V0cHV0IHx8IGF3YWl0IHRoaXMuc2hlbGwoWydkdW1wc3lzJywgJ3BhY2thZ2UnLCBwa2ddKTtcbiAgcmV0dXJuIGV4dHJhY3RNYXRjaGluZ1Blcm1pc3Npb25zKHN0ZG91dCwgWydpbnN0YWxsJywgJ3J1bnRpbWUnXSwgZmFsc2UpO1xufTtcblxuLyoqXG4gKiBSZXRyaWV2ZSB0aGUgbGlzdCBvZiByZXF1ZXN0ZWQgcGVybWlzc2lvbnMgZm9yIHRoZSBwYXJ0aWN1bGFyIHBhY2thZ2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBrZyAtIFRoZSBwYWNrYWdlIG5hbWUgdG8gYmUgcHJvY2Vzc2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IGNtZE91dHB1dCBbbnVsbF0gLSBPcHRpb25hbCBwYXJhbWV0ZXIgY29udGFpbmluZyBjb21tYW5kIG91dHB1dCBvZlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZHVtcHN5cyBwYWNrYWdlXyBjb21tYW5kLiBJdCBtYXkgc3BlZWQgdXAgdGhlIG1ldGhvZCBleGVjdXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxTdHJpbmc+fSBUaGUgbGlzdCBvZiByZXF1ZXN0ZWQgcGVybWlzc2lvbnMgb3IgYW4gZW1wdHkgbGlzdC5cbiAqL1xubWV0aG9kcy5nZXRSZXFQZXJtaXNzaW9ucyA9IGFzeW5jIGZ1bmN0aW9uIGdldFJlcVBlcm1pc3Npb25zIChwa2csIGNtZE91dHB1dCA9IG51bGwpIHtcbiAgbG9nLmRlYnVnKCdSZXRyaWV2aW5nIHJlcXVlc3RlZCBwZXJtaXNzaW9ucycpO1xuICBjb25zdCBzdGRvdXQgPSBjbWRPdXRwdXQgfHwgYXdhaXQgdGhpcy5zaGVsbChbJ2R1bXBzeXMnLCAncGFja2FnZScsIHBrZ10pO1xuICByZXR1cm4gZXh0cmFjdE1hdGNoaW5nUGVybWlzc2lvbnMoc3Rkb3V0LCBbJ3JlcXVlc3RlZCddKTtcbn07XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGxpc3Qgb2YgbG9jYXRpb24gcHJvdmlkZXJzIGZvciB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybiB7QXJyYXkuPFN0cmluZz59IFRoZSBsaXN0IG9mIGF2YWlsYWJsZSBsb2NhdGlvbiBwcm92aWRlcnMgb3IgYW4gZW1wdHkgbGlzdC5cbiAqL1xubWV0aG9kcy5nZXRMb2NhdGlvblByb3ZpZGVycyA9IGFzeW5jIGZ1bmN0aW9uIGdldExvY2F0aW9uUHJvdmlkZXJzICgpIHtcbiAgbGV0IHN0ZG91dCA9IGF3YWl0IHRoaXMuZ2V0U2V0dGluZygnc2VjdXJlJywgJ2xvY2F0aW9uX3Byb3ZpZGVyc19hbGxvd2VkJyk7XG4gIHJldHVybiBzdGRvdXQudHJpbSgpLnNwbGl0KCcsJylcbiAgICAubWFwKChwKSA9PiBwLnRyaW0oKSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pO1xufTtcblxuLyoqXG4gKiBUb2dnbGUgdGhlIHN0YXRlIG9mIEdQUyBsb2NhdGlvbiBwcm92aWRlci5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGVuYWJsZWQgLSBXaGV0aGVyIHRvIGVuYWJsZSAodHJ1ZSkgb3IgZGlzYWJsZSAoZmFsc2UpIHRoZSBHUFMgcHJvdmlkZXIuXG4gKi9cbm1ldGhvZHMudG9nZ2xlR1BTTG9jYXRpb25Qcm92aWRlciA9IGFzeW5jIGZ1bmN0aW9uIHRvZ2dsZUdQU0xvY2F0aW9uUHJvdmlkZXIgKGVuYWJsZWQpIHtcbiAgYXdhaXQgdGhpcy5zZXRTZXR0aW5nKCdzZWN1cmUnLCAnbG9jYXRpb25fcHJvdmlkZXJzX2FsbG93ZWQnLCBgJHtlbmFibGVkID8gJysnIDogJy0nfWdwc2ApO1xufTtcblxuLyoqXG4gKiBTZXQgaGlkZGVuIGFwaSBwb2xpY3kgdG8gbWFuYWdlIGFjY2VzcyB0byBub24tU0RLIEFQSXMuXG4gKiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9wcmV2aWV3L3Jlc3RyaWN0aW9ucy1ub24tc2RrLWludGVyZmFjZXNcbiAqXG4gKiBAcGFyYW0ge251bWJlcnxzdHJpbmd9IHZhbHVlIC0gVGhlIEFQSSBlbmZvcmNlbWVudCBwb2xpY3kuXG4gKiAgICAgRm9yIEFuZHJvaWQgUFxuICogICAgIDA6IERpc2FibGUgbm9uLVNESyBBUEkgdXNhZ2UgZGV0ZWN0aW9uLiBUaGlzIHdpbGwgYWxzbyBkaXNhYmxlIGxvZ2dpbmcsIGFuZCBhbHNvIGJyZWFrIHRoZSBzdHJpY3QgbW9kZSBBUEksXG4gKiAgICAgICAgZGV0ZWN0Tm9uU2RrQXBpVXNhZ2UoKS4gTm90IHJlY29tbWVuZGVkLlxuICogICAgIDE6IFwiSnVzdCB3YXJuXCIgLSBwZXJtaXQgYWNjZXNzIHRvIGFsbCBub24tU0RLIEFQSXMsIGJ1dCBrZWVwIHdhcm5pbmdzIGluIHRoZSBsb2cuXG4gKiAgICAgICAgVGhlIHN0cmljdCBtb2RlIEFQSSB3aWxsIGtlZXAgd29ya2luZy5cbiAqICAgICAyOiBEaXNhbGxvdyB1c2FnZSBvZiBkYXJrIGdyZXkgYW5kIGJsYWNrIGxpc3RlZCBBUElzLlxuICogICAgIDM6IERpc2FsbG93IHVzYWdlIG9mIGJsYWNrbGlzdGVkIEFQSXMsIGJ1dCBhbGxvdyB1c2FnZSBvZiBkYXJrIGdyZXkgbGlzdGVkIEFQSXMuXG4gKlxuICogICAgIEZvciBBbmRyb2lkIFFcbiAqICAgICBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9wcmV2aWV3L25vbi1zZGstcSNlbmFibGUtbm9uLXNkay1hY2Nlc3NcbiAqICAgICAwOiBEaXNhYmxlIGFsbCBkZXRlY3Rpb24gb2Ygbm9uLVNESyBpbnRlcmZhY2VzLiBVc2luZyB0aGlzIHNldHRpbmcgZGlzYWJsZXMgYWxsIGxvZyBtZXNzYWdlcyBmb3Igbm9uLVNESyBpbnRlcmZhY2UgdXNhZ2VcbiAqICAgICAgICBhbmQgcHJldmVudHMgeW91IGZyb20gdGVzdGluZyB5b3VyIGFwcCB1c2luZyB0aGUgU3RyaWN0TW9kZSBBUEkuIFRoaXMgc2V0dGluZyBpcyBub3QgcmVjb21tZW5kZWQuXG4gKiAgICAgMTogRW5hYmxlIGFjY2VzcyB0byBhbGwgbm9uLVNESyBpbnRlcmZhY2VzLCBidXQgcHJpbnQgbG9nIG1lc3NhZ2VzIHdpdGggd2FybmluZ3MgZm9yIGFueSBub24tU0RLIGludGVyZmFjZSB1c2FnZS5cbiAqICAgICAgICBVc2luZyB0aGlzIHNldHRpbmcgYWxzbyBhbGxvd3MgeW91IHRvIHRlc3QgeW91ciBhcHAgdXNpbmcgdGhlIFN0cmljdE1vZGUgQVBJLlxuICogICAgIDI6IERpc2FsbG93IHVzYWdlIG9mIG5vbi1TREsgaW50ZXJmYWNlcyB0aGF0IGJlbG9uZyB0byBlaXRoZXIgdGhlIGJsYWNrIGxpc3RcbiAqICAgICAgICBvciB0byBhIHJlc3RyaWN0ZWQgZ3JleWxpc3QgZm9yIHlvdXIgdGFyZ2V0IEFQSSBsZXZlbC5cbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlnbm9yZUVycm9yIFtmYWxzZV0gV2hldGhlciB0byBpZ25vcmUgYW4gZXhjZXB0aW9uIGluICdhZGIgc2hlbGwgc2V0dGluZ3MgcHV0IGdsb2JhbCcgY29tbWFuZFxuICogQHRocm93cyB7ZXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciBhbmQgaWdub3JlRXJyb3Igd2FzIHRydWUgd2hpbGUgZXhlY3V0aW5nICdhZGIgc2hlbGwgc2V0dGluZ3MgcHV0IGdsb2JhbCdcbiAqICAgICAgICAgICAgICAgICBjb21tYW5kIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xubWV0aG9kcy5zZXRIaWRkZW5BcGlQb2xpY3kgPSBhc3luYyBmdW5jdGlvbiBzZXRIaWRkZW5BcGlQb2xpY3kgKHZhbHVlLCBpZ25vcmVFcnJvciA9IGZhbHNlKSB7XG4gIHRyeSB7XG4gICAgYXdhaXQgdGhpcy5zaGVsbChISURERU5fQVBJX1BPTElDWV9LRVlTLm1hcCgoaykgPT4gYHNldHRpbmdzIHB1dCBnbG9iYWwgJHtrfSAke3ZhbHVlfWApLmpvaW4oJzsnKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIWlnbm9yZUVycm9yKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgICBsb2cuaW5mbyhgRmFpbGVkIHRvIHNldCBzZXR0aW5nIGtleXMgJyR7SElEREVOX0FQSV9QT0xJQ1lfS0VZU30nIHRvICcke3ZhbHVlfScuIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXNldCBhY2Nlc3MgdG8gbm9uLVNESyBBUElzIHRvIGl0cyBkZWZhdWx0IHNldHRpbmcuXG4gKiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9wcmV2aWV3L3Jlc3RyaWN0aW9ucy1ub24tc2RrLWludGVyZmFjZXNcbiAqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlnbm9yZUVycm9yIFtmYWxzZV0gV2hldGhlciB0byBpZ25vcmUgYW4gZXhjZXB0aW9uIGluICdhZGIgc2hlbGwgc2V0dGluZ3MgZGVsZXRlIGdsb2JhbCcgY29tbWFuZFxuICogQHRocm93cyB7ZXJyb3J9IElmIHRoZXJlIHdhcyBhbiBlcnJvciBhbmQgaWdub3JlRXJyb3Igd2FzIHRydWUgd2hpbGUgZXhlY3V0aW5nICdhZGIgc2hlbGwgc2V0dGluZ3MgZGVsZXRlIGdsb2JhbCdcbiAqICAgICAgICAgICAgICAgICBjb21tYW5kIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xubWV0aG9kcy5zZXREZWZhdWx0SGlkZGVuQXBpUG9saWN5ID0gYXN5bmMgZnVuY3Rpb24gc2V0RGVmYXVsdEhpZGRlbkFwaVBvbGljeSAoaWdub3JlRXJyb3IgPSBmYWxzZSkge1xuICB0cnkge1xuICAgIGF3YWl0IHRoaXMuc2hlbGwoSElEREVOX0FQSV9QT0xJQ1lfS0VZUy5tYXAoKGspID0+IGBzZXR0aW5ncyBkZWxldGUgZ2xvYmFsICR7a31gKS5qb2luKCc7JykpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKCFpZ25vcmVFcnJvcikge1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgbG9nLmluZm8oYEZhaWxlZCB0byBkZWxldGUga2V5cyAnJHtISURERU5fQVBJX1BPTElDWV9LRVlTfScuIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdG9wIHRoZSBwYXJ0aWN1bGFyIHBhY2thZ2UgaWYgaXQgaXMgcnVubmluZyBhbmQgY2xlYXJzIGl0cyBhcHBsaWNhdGlvbiBkYXRhLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwa2cgLSBUaGUgcGFja2FnZSBuYW1lIHRvIGJlIHByb2Nlc3NlZC5cbiAqL1xubWV0aG9kcy5zdG9wQW5kQ2xlYXIgPSBhc3luYyBmdW5jdGlvbiBzdG9wQW5kQ2xlYXIgKHBrZykge1xuICB0cnkge1xuICAgIGF3YWl0IHRoaXMuZm9yY2VTdG9wKHBrZyk7XG4gICAgYXdhaXQgdGhpcy5jbGVhcihwa2cpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3Qgc3RvcCBhbmQgY2xlYXIgJHtwa2d9LiBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIGlucHV0IG1ldGhvZHMgKElNRXMpIGZvciB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybiB7QXJyYXkuPFN0cmluZz59IFRoZSBsaXN0IG9mIElNRSBuYW1lcyBvciBhbiBlbXB0eSBsaXN0LlxuICovXG5tZXRob2RzLmF2YWlsYWJsZUlNRXMgPSBhc3luYyBmdW5jdGlvbiBhdmFpbGFibGVJTUVzICgpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZ2V0SU1FTGlzdEZyb21PdXRwdXQoYXdhaXQgdGhpcy5zaGVsbChbJ2ltZScsICdsaXN0JywgJy1hJ10pKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZ2V0dGluZyBhdmFpbGFibGUgSU1FJ3MuIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXRyaWV2ZSB0aGUgbGlzdCBvZiBlbmFibGVkIGlucHV0IG1ldGhvZHMgKElNRXMpIGZvciB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybiB7QXJyYXkuPFN0cmluZz59IFRoZSBsaXN0IG9mIGVuYWJsZWQgSU1FIG5hbWVzIG9yIGFuIGVtcHR5IGxpc3QuXG4gKi9cbm1ldGhvZHMuZW5hYmxlZElNRXMgPSBhc3luYyBmdW5jdGlvbiBlbmFibGVkSU1FcyAoKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGdldElNRUxpc3RGcm9tT3V0cHV0KGF3YWl0IHRoaXMuc2hlbGwoWydpbWUnLCAnbGlzdCddKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGdldHRpbmcgZW5hYmxlZCBJTUUncy4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICB9XG59O1xuXG4vKipcbiAqIEVuYWJsZSB0aGUgcGFydGljdWxhciBpbnB1dCBtZXRob2Qgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbWVJZCAtIE9uZSBvZiBleGlzdGluZyBJTUUgaWRzLlxuICovXG5tZXRob2RzLmVuYWJsZUlNRSA9IGFzeW5jIGZ1bmN0aW9uIGVuYWJsZUlNRSAoaW1lSWQpIHtcbiAgYXdhaXQgdGhpcy5zaGVsbChbJ2ltZScsICdlbmFibGUnLCBpbWVJZF0pO1xufTtcblxuLyoqXG4gKiBEaXNhYmxlIHRoZSBwYXJ0aWN1bGFyIGlucHV0IG1ldGhvZCBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGltZUlkIC0gT25lIG9mIGV4aXN0aW5nIElNRSBpZHMuXG4gKi9cbm1ldGhvZHMuZGlzYWJsZUlNRSA9IGFzeW5jIGZ1bmN0aW9uIGRpc2FibGVJTUUgKGltZUlkKSB7XG4gIGF3YWl0IHRoaXMuc2hlbGwoWydpbWUnLCAnZGlzYWJsZScsIGltZUlkXSk7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgcGFydGljdWxhciBpbnB1dCBtZXRob2Qgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbWVJZCAtIE9uZSBvZiBleGlzdGluZyBJTUUgaWRzLlxuICovXG5tZXRob2RzLnNldElNRSA9IGFzeW5jIGZ1bmN0aW9uIHNldElNRSAoaW1lSWQpIHtcbiAgYXdhaXQgdGhpcy5zaGVsbChbJ2ltZScsICdzZXQnLCBpbWVJZF0pO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGRlZmF1bHQgaW5wdXQgbWV0aG9kIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcmV0dXJuIHs/c3RyaW5nfSBUaGUgbmFtZSBvZiB0aGUgZGVmYXVsdCBpbnB1dCBtZXRob2RcbiAqL1xubWV0aG9kcy5kZWZhdWx0SU1FID0gYXN5bmMgZnVuY3Rpb24gZGVmYXVsdElNRSAoKSB7XG4gIHRyeSB7XG4gICAgbGV0IGVuZ2luZSA9IGF3YWl0IHRoaXMuZ2V0U2V0dGluZygnc2VjdXJlJywgJ2RlZmF1bHRfaW5wdXRfbWV0aG9kJyk7XG4gICAgaWYgKGVuZ2luZSA9PT0gJ251bGwnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGVuZ2luZS50cmltKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGdldHRpbmcgZGVmYXVsdCBJTUUuIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kIHRoZSBwYXJ0aWN1bGFyIGtleWNvZGUgdG8gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0ga2V5Y29kZSAtIFRoZSBhY3R1YWwga2V5IGNvZGUgdG8gYmUgc2VudC5cbiAqL1xubWV0aG9kcy5rZXlldmVudCA9IGFzeW5jIGZ1bmN0aW9uIGtleWV2ZW50IChrZXljb2RlKSB7XG4gIC8vIGtleWNvZGUgbXVzdCBiZSBhbiBpbnQuXG4gIGxldCBjb2RlID0gcGFyc2VJbnQoa2V5Y29kZSwgMTApO1xuICBhd2FpdCB0aGlzLnNoZWxsKFsnaW5wdXQnLCAna2V5ZXZlbnQnLCBjb2RlXSk7XG59O1xuXG4vKipcbiAqIFNlbmQgdGhlIHBhcnRpY3VsYXIgdGV4dCBvciBhIG51bWJlciB0byB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKiBUaGUgdGV4dCBnZXRzIHByb3Blcmx5IGVzY2FwZWQgYmVmb3JlIGJlaW5nIHBhc3NlZCB0byBBREIuXG4gKiBOb29wIGlmIHRoZSB0ZXh0IGlzIGVtcHR5LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gdGV4dCAtIFRoZSBhY3R1YWwgdGV4dCB0byBiZSBzZW50LlxuICogQHRocm93cyB7RXJyb3J9IElmIGl0IGlzIGltcG9zc2libGUgdG8gZXNjYXBlIHRoZSBnaXZlbiBzdHJpbmdcbiAqL1xubWV0aG9kcy5pbnB1dFRleHQgPSBhc3luYyBmdW5jdGlvbiBpbnB1dFRleHQgKHRleHQpIHtcbiAgaWYgKHRleHQgPT09ICcnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgb3JpZ2luYWxTdHIgPSBgJHt0ZXh0fWA7XG4gIGNvbnN0IGVzY2FwZWRUZXh0ID0gb3JpZ2luYWxTdHIucmVwbGFjZSgvXFwkL2csICdcXFxcJCcpLnJlcGxhY2UoLyAvZywgJyVzJyk7XG4gIGxldCBhcmdzID0gWydpbnB1dCcsICd0ZXh0Jywgb3JpZ2luYWxTdHJdO1xuICBpZiAoZXNjYXBlZFRleHQgIT09IG9yaWdpbmFsU3RyIHx8IEFEQl9JTlBVVF9FU0NBUEVfUEFUVEVSTi50ZXN0KG9yaWdpbmFsU3RyKSkge1xuICAgIGlmIChfLmV2ZXJ5KFsnXCInLCBgJ2BdLCAoYykgPT4gb3JpZ2luYWxTdHIuaW5jbHVkZXMoYykpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBEaWQgbm90IGtub3cgaG93IHRvIGVzY2FwZSBhIHN0cmluZyB0aGF0IGNvbnRhaW5zIGJvdGggdHlwZXMgb2YgcXVvdGVzIChcIiBhbmQgJylgXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBxID0gb3JpZ2luYWxTdHIuaW5jbHVkZXMoJ1wiJykgPyBgJ2AgOiAnXCInO1xuICAgIGFyZ3MgPSBbYGlucHV0IHRleHQgJHtxfSR7ZXNjYXBlZFRleHR9JHtxfWBdO1xuICB9XG4gIGF3YWl0IHRoaXMuc2hlbGwoYXJncyk7XG59O1xuXG4vKipcbiAqIENsZWFyIHRoZSBhY3RpdmUgdGV4dCBmaWVsZCBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QgYnkgc2VuZGluZ1xuICogc3BlY2lhbCBrZXlldmVudHMgdG8gaXQuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBbMTAwXSAtIFRoZSBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgdGV4dCBpbiB0aGUgZmllbGQgdG8gYmUgY2xlYXJlZC5cbiAqL1xubWV0aG9kcy5jbGVhclRleHRGaWVsZCA9IGFzeW5jIGZ1bmN0aW9uIGNsZWFyVGV4dEZpZWxkIChsZW5ndGggPSAxMDApIHtcbiAgLy8gYXNzdW1lcyB0aGF0IHRoZSBFZGl0VGV4dCBmaWVsZCBhbHJlYWR5IGhhcyBmb2N1c1xuICBsb2cuZGVidWcoYENsZWFyaW5nIHVwIHRvICR7bGVuZ3RofSBjaGFyYWN0ZXJzYCk7XG4gIGlmIChsZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IGFyZ3MgPSBbJ2lucHV0JywgJ2tleWV2ZW50J107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAvLyB3ZSBjYW5ub3Qga25vdyB3aGVyZSB0aGUgY3Vyc29yIGlzIGluIHRoZSB0ZXh0IGZpZWxkLCBzbyBkZWxldGUgYm90aCBiZWZvcmVcbiAgICAvLyBhbmQgYWZ0ZXIgc28gdGhhdCB3ZSBnZXQgcmlkIG9mIGV2ZXJ5dGhpbmdcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC92aWV3L0tleUV2ZW50Lmh0bWwjS0VZQ09ERV9ERUxcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC92aWV3L0tleUV2ZW50Lmh0bWwjS0VZQ09ERV9GT1JXQVJEX0RFTFxuICAgIGFyZ3MucHVzaCgnNjcnLCAnMTEyJyk7XG4gIH1cbiAgYXdhaXQgdGhpcy5zaGVsbChhcmdzKTtcbn07XG5cbi8qKlxuICogU2VuZCB0aGUgc3BlY2lhbCBrZXljb2RlIHRvIHRoZSBkZXZpY2UgdW5kZXIgdGVzdCBpbiBvcmRlciB0byBsb2NrIGl0LlxuICovXG5tZXRob2RzLmxvY2sgPSBhc3luYyBmdW5jdGlvbiBsb2NrICgpIHtcbiAgaWYgKGF3YWl0IHRoaXMuaXNTY3JlZW5Mb2NrZWQoKSkge1xuICAgIGxvZy5kZWJ1ZygnU2NyZWVuIGlzIGFscmVhZHkgbG9ja2VkLiBEb2luZyBub3RoaW5nLicpO1xuICAgIHJldHVybjtcbiAgfVxuICBsb2cuZGVidWcoJ1ByZXNzaW5nIHRoZSBLRVlDT0RFX1BPV0VSIGJ1dHRvbiB0byBsb2NrIHNjcmVlbicpO1xuICBhd2FpdCB0aGlzLmtleWV2ZW50KDI2KTtcblxuICBjb25zdCB0aW1lb3V0TXMgPSA1MDAwO1xuICB0cnkge1xuICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5pc1NjcmVlbkxvY2tlZCgpLCB7XG4gICAgICB3YWl0TXM6IHRpbWVvdXRNcyxcbiAgICAgIGludGVydmFsTXM6IDUwMCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGRldmljZSBzY3JlZW4gaXMgc3RpbGwgbG9ja2VkIGFmdGVyICR7dGltZW91dE1zfW1zIHRpbWVvdXRgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kIHRoZSBzcGVjaWFsIGtleWNvZGUgdG8gdGhlIGRldmljZSB1bmRlciB0ZXN0IGluIG9yZGVyIHRvIGVtdWxhdGVcbiAqIEJhY2sgYnV0dG9uIHRhcC5cbiAqL1xubWV0aG9kcy5iYWNrID0gYXN5bmMgZnVuY3Rpb24gYmFjayAoKSB7XG4gIGxvZy5kZWJ1ZygnUHJlc3NpbmcgdGhlIEJBQ0sgYnV0dG9uJyk7XG4gIGF3YWl0IHRoaXMua2V5ZXZlbnQoNCk7XG59O1xuXG4vKipcbiAqIFNlbmQgdGhlIHNwZWNpYWwga2V5Y29kZSB0byB0aGUgZGV2aWNlIHVuZGVyIHRlc3QgaW4gb3JkZXIgdG8gZW11bGF0ZVxuICogSG9tZSBidXR0b24gdGFwLlxuICovXG5tZXRob2RzLmdvVG9Ib21lID0gYXN5bmMgZnVuY3Rpb24gZ29Ub0hvbWUgKCkge1xuICBsb2cuZGVidWcoJ1ByZXNzaW5nIHRoZSBIT01FIGJ1dHRvbicpO1xuICBhd2FpdCB0aGlzLmtleWV2ZW50KDMpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBhY3R1YWwgcGF0aCB0byBhZGIgZXhlY3V0YWJsZS5cbiAqL1xubWV0aG9kcy5nZXRBZGJQYXRoID0gZnVuY3Rpb24gZ2V0QWRiUGF0aCAoKSB7XG4gIHJldHVybiB0aGlzLmV4ZWN1dGFibGUucGF0aDtcbn07XG5cbi8qKlxuICogUmV0cmlldmUgY3VycmVudCBzY3JlZW4gb3JpZW50YXRpb24gb2YgdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGN1cnJlbnQgb3JpZW50YXRpb24gZW5jb2RlZCBhcyBhbiBpbnRlZ2VyIG51bWJlci5cbiAqL1xubWV0aG9kcy5nZXRTY3JlZW5PcmllbnRhdGlvbiA9IGFzeW5jIGZ1bmN0aW9uIGdldFNjcmVlbk9yaWVudGF0aW9uICgpIHtcbiAgbGV0IHN0ZG91dCA9IGF3YWl0IHRoaXMuc2hlbGwoWydkdW1wc3lzJywgJ2lucHV0J10pO1xuICByZXR1cm4gZ2V0U3VyZmFjZU9yaWVudGF0aW9uKHN0ZG91dCk7XG59O1xuXG4vKipcbiAqIFNlbmQgYW4gYXJiaXRyYXJ5IFRlbG5ldCBjb21tYW5kIHRvIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29tbWFuZCAtIFRoZSBjb21tYW5kIHRvIGJlIHNlbnQuXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgYWN0dWFsIG91dHB1dCBvZiB0aGUgZ2l2ZW4gY29tbWFuZC5cbiAqL1xubWV0aG9kcy5zZW5kVGVsbmV0Q29tbWFuZCA9IGFzeW5jIGZ1bmN0aW9uIHNlbmRUZWxuZXRDb21tYW5kIChjb21tYW5kKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLmV4ZWNFbXVDb25zb2xlQ29tbWFuZChjb21tYW5kLCB7cG9ydDogYXdhaXQgdGhpcy5nZXRFbXVsYXRvclBvcnQoKX0pO1xufTtcblxuLyoqXG4gKiBDaGVjayB0aGUgc3RhdGUgb2YgQWlycGxhbmUgbW9kZSBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBBaXJwbGFuZSBtb2RlIGlzIGVuYWJsZWQuXG4gKi9cbm1ldGhvZHMuaXNBaXJwbGFuZU1vZGVPbiA9IGFzeW5jIGZ1bmN0aW9uIGlzQWlycGxhbmVNb2RlT24gKCkge1xuICBsZXQgc3Rkb3V0ID0gYXdhaXQgdGhpcy5nZXRTZXR0aW5nKCdnbG9iYWwnLCAnYWlycGxhbmVfbW9kZV9vbicpO1xuICByZXR1cm4gcGFyc2VJbnQoc3Rkb3V0LCAxMCkgIT09IDA7XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgc3RhdGUgb2YgQWlycGxhbmUgbW9kZSBpbiBTZXR0aW5ncyBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBvbiAtIFRydWUgdG8gZW5hYmxlIHRoZSBBaXJwbGFuZSBtb2RlIGluIFNldHRpbmdzIGFuZCBmYWxzZSB0byBkaXNhYmxlIGl0LlxuICovXG5tZXRob2RzLnNldEFpcnBsYW5lTW9kZSA9IGFzeW5jIGZ1bmN0aW9uIHNldEFpcnBsYW5lTW9kZSAob24pIHtcbiAgYXdhaXQgdGhpcy5zZXRTZXR0aW5nKCdnbG9iYWwnLCAnYWlycGxhbmVfbW9kZV9vbicsIG9uID8gMSA6IDApO1xufTtcblxuLyoqXG4gKiBCcm9hZGNhc3QgdGhlIHN0YXRlIG9mIEFpcnBsYW5lIG1vZGUgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICogVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBhZnRlciB7QGxpbmsgI3NldEFpcnBsYW5lTW9kZX0sIG90aGVyd2lzZVxuICogdGhlIG1vZGUgY2hhbmdlIGlzIG5vdCBnb2luZyB0byBiZSBhcHBsaWVkIGZvciB0aGUgZGV2aWNlLlxuICpcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gb24gLSBUcnVlIHRvIGJyb2FkY2FzdCBlbmFibGUgYW5kIGZhbHNlIHRvIGJyb2FkY2FzdCBkaXNhYmxlLlxuICovXG5tZXRob2RzLmJyb2FkY2FzdEFpcnBsYW5lTW9kZSA9IGFzeW5jIGZ1bmN0aW9uIGJyb2FkY2FzdEFpcnBsYW5lTW9kZSAob24pIHtcbiAgYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgJ2FtJywgJ2Jyb2FkY2FzdCcsXG4gICAgJy1hJywgJ2FuZHJvaWQuaW50ZW50LmFjdGlvbi5BSVJQTEFORV9NT0RFJyxcbiAgICAnLS1leicsICdzdGF0ZScsIG9uID8gJ3RydWUnIDogJ2ZhbHNlJ1xuICBdKTtcbn07XG5cbi8qKlxuICogQ2hlY2sgdGhlIHN0YXRlIG9mIFdpRmkgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgV2lGaSBpcyBlbmFibGVkLlxuICovXG5tZXRob2RzLmlzV2lmaU9uID0gYXN5bmMgZnVuY3Rpb24gaXNXaWZpT24gKCkge1xuICBsZXQgc3Rkb3V0ID0gYXdhaXQgdGhpcy5nZXRTZXR0aW5nKCdnbG9iYWwnLCAnd2lmaV9vbicpO1xuICByZXR1cm4gKHBhcnNlSW50KHN0ZG91dCwgMTApICE9PSAwKTtcbn07XG5cbi8qKlxuICogQ2hlY2sgdGhlIHN0YXRlIG9mIERhdGEgdHJhbnNmZXIgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgRGF0YSB0cmFuc2ZlciBpcyBlbmFibGVkLlxuICovXG5tZXRob2RzLmlzRGF0YU9uID0gYXN5bmMgZnVuY3Rpb24gaXNEYXRhT24gKCkge1xuICBsZXQgc3Rkb3V0ID0gYXdhaXQgdGhpcy5nZXRTZXR0aW5nKCdnbG9iYWwnLCAnbW9iaWxlX2RhdGEnKTtcbiAgcmV0dXJuIChwYXJzZUludChzdGRvdXQsIDEwKSAhPT0gMCk7XG59O1xuXG4vKipcbiAqIENoYW5nZSB0aGUgc3RhdGUgb2YgV2lGaSBhbmQvb3IgRGF0YSB0cmFuc2ZlciBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSB3aWZpIC0gVHJ1ZSB0byBlbmFibGUgYW5kIGZhbHNlIHRvIGRpc2FibGUgV2lGaS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZGF0YSAtIFRydWUgdG8gZW5hYmxlIGFuZCBmYWxzZSB0byBkaXNhYmxlIERhdGEgdHJhbnNmZXIuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzRW11bGF0b3IgW2ZhbHNlXSAtIFNldCBpdCB0byB0cnVlIGlmIHRoZSBkZXZpY2UgdW5kZXIgdGVzdFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcyBhbiBlbXVsYXRvciByYXRoZXIgdGhhbiBhIHJlYWwgZGV2aWNlLlxuICovXG5tZXRob2RzLnNldFdpZmlBbmREYXRhID0gYXN5bmMgZnVuY3Rpb24gc2V0V2lmaUFuZERhdGEgKHt3aWZpLCBkYXRhfSwgaXNFbXVsYXRvciA9IGZhbHNlKSB7XG4gIGlmICh1dGlsLmhhc1ZhbHVlKHdpZmkpKSB7XG4gICAgYXdhaXQgdGhpcy5zZXRXaWZpU3RhdGUod2lmaSwgaXNFbXVsYXRvcik7XG4gIH1cbiAgaWYgKHV0aWwuaGFzVmFsdWUoZGF0YSkpIHtcbiAgICBhd2FpdCB0aGlzLnNldERhdGFTdGF0ZShkYXRhLCBpc0VtdWxhdG9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDaGVjayB0aGUgc3RhdGUgb2YgYW5pbWF0aW9uIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGF0IGxlYXN0IG9uZSBvZiBhbmltYXRpb24gc2NhbGUgc2V0dGluZ3NcbiAqICAgICAgICAgICAgICAgICAgIGlzIG5vdCBlcXVhbCB0byAnMC4wJy5cbiAqL1xubWV0aG9kcy5pc0FuaW1hdGlvbk9uID0gYXN5bmMgZnVuY3Rpb24gaXNBbmltYXRpb25PbiAoKSB7XG4gIGxldCBhbmltYXRvcl9kdXJhdGlvbl9zY2FsZSA9IGF3YWl0IHRoaXMuZ2V0U2V0dGluZygnZ2xvYmFsJywgJ2FuaW1hdG9yX2R1cmF0aW9uX3NjYWxlJyk7XG4gIGxldCB0cmFuc2l0aW9uX2FuaW1hdGlvbl9zY2FsZSA9IGF3YWl0IHRoaXMuZ2V0U2V0dGluZygnZ2xvYmFsJywgJ3RyYW5zaXRpb25fYW5pbWF0aW9uX3NjYWxlJyk7XG4gIGxldCB3aW5kb3dfYW5pbWF0aW9uX3NjYWxlID0gYXdhaXQgdGhpcy5nZXRTZXR0aW5nKCdnbG9iYWwnLCAnd2luZG93X2FuaW1hdGlvbl9zY2FsZScpO1xuICByZXR1cm4gXy5zb21lKFthbmltYXRvcl9kdXJhdGlvbl9zY2FsZSwgdHJhbnNpdGlvbl9hbmltYXRpb25fc2NhbGUsIHdpbmRvd19hbmltYXRpb25fc2NhbGVdLFxuICAgICAgICAgICAgICAgIChzZXR0aW5nKSA9PiBzZXR0aW5nICE9PSAnMC4wJyk7XG59O1xuXG4vKipcbiAqIEZvcmNlZnVsbHkgcmVjdXJzaXZlbHkgcmVtb3ZlIGEgcGF0aCBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKiBCZSBjYXJlZnVsIHdoaWxlIGNhbGxpbmcgdGhpcyBtZXRob2QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBUaGUgcGF0aCB0byBiZSByZW1vdmVkIHJlY3Vyc2l2ZWx5LlxuICovXG5tZXRob2RzLnJpbXJhZiA9IGFzeW5jIGZ1bmN0aW9uIHJpbXJhZiAocGF0aCkge1xuICBhd2FpdCB0aGlzLnNoZWxsKFsncm0nLCAnLXJmJywgcGF0aF0pO1xufTtcblxuLyoqXG4gKiBTZW5kIGEgZmlsZSB0byB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBmaWxlIG9uIHRoZSBsb2NhbCBmaWxlIHN5c3RlbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSByZW1vdGVQYXRoIC0gVGhlIGRlc3RpbmF0aW9uIHBhdGggb24gdGhlIHJlbW90ZSBkZXZpY2UuXG4gKiBAcGFyYW0ge29iamVjdH0gb3B0cyAtIEFkZGl0aW9uYWwgb3B0aW9ucyBtYXBwaW5nLiBTZWVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgaHR0cHM6Ly9naXRodWIuY29tL2FwcGl1bS9ub2RlLXRlZW5fcHJvY2VzcyxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgX2V4ZWNfIG1ldGhvZCBvcHRpb25zLCBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBhdmFpbGFibGVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5cbiAqL1xubWV0aG9kcy5wdXNoID0gYXN5bmMgZnVuY3Rpb24gcHVzaCAobG9jYWxQYXRoLCByZW1vdGVQYXRoLCBvcHRzKSB7XG4gIGF3YWl0IHRoaXMubWtkaXIocGF0aC5wb3NpeC5kaXJuYW1lKHJlbW90ZVBhdGgpKTtcbiAgYXdhaXQgdGhpcy5hZGJFeGVjKFsncHVzaCcsIGxvY2FsUGF0aCwgcmVtb3RlUGF0aF0sIG9wdHMpO1xufTtcblxuLyoqXG4gKiBSZWNlaXZlIGEgZmlsZSBmcm9tIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVtb3RlUGF0aCAtIFRoZSBzb3VyY2UgcGF0aCBvbiB0aGUgcmVtb3RlIGRldmljZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbFBhdGggLSBUaGUgZGVzdGluYXRpb24gcGF0aCB0byB0aGUgZmlsZSBvbiB0aGUgbG9jYWwgZmlsZSBzeXN0ZW0uXG4gKiBAcGFyYW0ge29iamVjdH0gb3B0cyAtIEFkZGl0aW9uYWwgb3B0aW9ucyBtYXBwaW5nLiBTZWVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgaHR0cHM6Ly9naXRodWIuY29tL2FwcGl1bS9ub2RlLXRlZW5fcHJvY2VzcyxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgX2V4ZWNfIG1ldGhvZCBvcHRpb25zLCBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBhdmFpbGFibGVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5cbiAqL1xubWV0aG9kcy5wdWxsID0gYXN5bmMgZnVuY3Rpb24gcHVsbCAocmVtb3RlUGF0aCwgbG9jYWxQYXRoLCBvcHRzID0ge30pIHtcbiAgLy8gcHVsbCBmb2xkZXIgY2FuIHRha2UgbW9yZSB0aW1lLCBpbmNyZWFzaW5nIHRpbWUgb3V0IHRvIDYwIHNlY3NcbiAgYXdhaXQgdGhpcy5hZGJFeGVjKFsncHVsbCcsIHJlbW90ZVBhdGgsIGxvY2FsUGF0aF0sIHsuLi5vcHRzLCB0aW1lb3V0OiBvcHRzLnRpbWVvdXQgPz8gNjAwMDB9KTtcbn07XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgcHJvY2VzcyB3aXRoIHRoZSBwYXJ0aWN1bGFyIG5hbWUgaXMgcnVubmluZyBvbiB0aGUgZGV2aWNlXG4gKiB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9jZXNzTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9jZXNzIHRvIGJlIGNoZWNrZWQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBnaXZlbiBwcm9jZXNzIGlzIHJ1bm5pbmcuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGdpdmVuIHByb2Nlc3MgbmFtZSBpcyBub3QgYSB2YWxpZCBjbGFzcyBuYW1lLlxuICovXG5tZXRob2RzLnByb2Nlc3NFeGlzdHMgPSBhc3luYyBmdW5jdGlvbiBwcm9jZXNzRXhpc3RzIChwcm9jZXNzTmFtZSkge1xuICByZXR1cm4gIV8uaXNFbXB0eShhd2FpdCB0aGlzLmdldFBJRHNCeU5hbWUocHJvY2Vzc05hbWUpKTtcbn07XG5cbi8qKlxuICogR2V0IFRDUCBwb3J0IGZvcndhcmRpbmcgd2l0aCBhZGIgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICogQHJldHVybiB7QXJyYXkuPFN0cmluZz59IFRoZSBvdXRwdXQgb2YgdGhlIGNvcnJlc3BvbmRpbmcgYWRiIGNvbW1hbmQuIEFuIGFycmF5IGNvbnRhaW5zIGVhY2ggZm9yd2FyZGluZyBsaW5lIG9mIG91dHB1dFxuICovXG5tZXRob2RzLmdldEZvcndhcmRMaXN0ID0gYXN5bmMgZnVuY3Rpb24gZ2V0Rm9yd2FyZExpc3QgKCkge1xuICBsb2cuZGVidWcoYExpc3QgZm9yd2FyZGluZyBwb3J0c2ApO1xuICBjb25zdCBjb25uZWN0aW9ucyA9IGF3YWl0IHRoaXMuYWRiRXhlYyhbJ2ZvcndhcmQnLCAnLS1saXN0J10pO1xuICByZXR1cm4gY29ubmVjdGlvbnMuc3BsaXQoRU9MKS5maWx0ZXIoKGxpbmUpID0+IEJvb2xlYW4obGluZS50cmltKCkpKTtcbn07XG5cbi8qKlxuICogU2V0dXAgVENQIHBvcnQgZm9yd2FyZGluZyB3aXRoIGFkYiBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzeXN0ZW1Qb3J0IC0gVGhlIG51bWJlciBvZiB0aGUgbG9jYWwgc3lzdGVtIHBvcnQuXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGRldmljZVBvcnQgLSBUaGUgbnVtYmVyIG9mIHRoZSByZW1vdGUgZGV2aWNlIHBvcnQuXG4gKi9cbm1ldGhvZHMuZm9yd2FyZFBvcnQgPSBhc3luYyBmdW5jdGlvbiBmb3J3YXJkUG9ydCAoc3lzdGVtUG9ydCwgZGV2aWNlUG9ydCkge1xuICBsb2cuZGVidWcoYEZvcndhcmRpbmcgc3lzdGVtOiAke3N5c3RlbVBvcnR9IHRvIGRldmljZTogJHtkZXZpY2VQb3J0fWApO1xuICBhd2FpdCB0aGlzLmFkYkV4ZWMoWydmb3J3YXJkJywgYHRjcDoke3N5c3RlbVBvcnR9YCwgYHRjcDoke2RldmljZVBvcnR9YF0pO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgVENQIHBvcnQgZm9yd2FyZGluZyB3aXRoIGFkYiBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuIFRoZSBmb3J3YXJkaW5nXG4gKiBmb3IgdGhlIGdpdmVuIHBvcnQgc2hvdWxkIGJlIHNldHVwIHdpdGgge0BsaW5rICNmb3J3YXJkUG9ydH0gZmlyc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzeXN0ZW1Qb3J0IC0gVGhlIG51bWJlciBvZiB0aGUgbG9jYWwgc3lzdGVtIHBvcnRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHJlbW92ZSBmb3J3YXJkaW5nIG9uLlxuICovXG5tZXRob2RzLnJlbW92ZVBvcnRGb3J3YXJkID0gYXN5bmMgZnVuY3Rpb24gcmVtb3ZlUG9ydEZvcndhcmQgKHN5c3RlbVBvcnQpIHtcbiAgbG9nLmRlYnVnKGBSZW1vdmluZyBmb3J3YXJkZWQgcG9ydCBzb2NrZXQgY29ubmVjdGlvbjogJHtzeXN0ZW1Qb3J0fSBgKTtcbiAgYXdhaXQgdGhpcy5hZGJFeGVjKFsnZm9yd2FyZCcsIGAtLXJlbW92ZWAsIGB0Y3A6JHtzeXN0ZW1Qb3J0fWBdKTtcbn07XG5cbi8qKlxuICogR2V0IFRDUCBwb3J0IGZvcndhcmRpbmcgd2l0aCBhZGIgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICogQHJldHVybiB7QXJyYXkuPFN0cmluZz59IFRoZSBvdXRwdXQgb2YgdGhlIGNvcnJlc3BvbmRpbmcgYWRiIGNvbW1hbmQuIEFuIGFycmF5IGNvbnRhaW5zIGVhY2ggZm9yd2FyZGluZyBsaW5lIG9mIG91dHB1dFxuICovXG5tZXRob2RzLmdldFJldmVyc2VMaXN0ID0gYXN5bmMgZnVuY3Rpb24gZ2V0UmV2ZXJzZUxpc3QgKCkge1xuICBsb2cuZGVidWcoYExpc3QgcmV2ZXJzZSBmb3J3YXJkaW5nIHBvcnRzYCk7XG4gIGNvbnN0IGNvbm5lY3Rpb25zID0gYXdhaXQgdGhpcy5hZGJFeGVjKFsncmV2ZXJzZScsICctLWxpc3QnXSk7XG4gIHJldHVybiBjb25uZWN0aW9ucy5zcGxpdChFT0wpLmZpbHRlcigobGluZSkgPT4gQm9vbGVhbihsaW5lLnRyaW0oKSkpO1xufTtcblxuLyoqXG4gKiBTZXR1cCBUQ1AgcG9ydCBmb3J3YXJkaW5nIHdpdGggYWRiIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqIE9ubHkgYXZhaWxhYmxlIGZvciBBUEkgMjErLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gZGV2aWNlUG9ydCAtIFRoZSBudW1iZXIgb2YgdGhlIHJlbW90ZSBkZXZpY2UgcG9ydC5cbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gc3lzdGVtUG9ydCAtIFRoZSBudW1iZXIgb2YgdGhlIGxvY2FsIHN5c3RlbSBwb3J0LlxuICovXG5tZXRob2RzLnJldmVyc2VQb3J0ID0gYXN5bmMgZnVuY3Rpb24gcmV2ZXJzZVBvcnQgKGRldmljZVBvcnQsIHN5c3RlbVBvcnQpIHtcbiAgbG9nLmRlYnVnKGBGb3J3YXJkaW5nIGRldmljZTogJHtkZXZpY2VQb3J0fSB0byBzeXN0ZW06ICR7c3lzdGVtUG9ydH1gKTtcbiAgYXdhaXQgdGhpcy5hZGJFeGVjKFsncmV2ZXJzZScsIGB0Y3A6JHtkZXZpY2VQb3J0fWAsIGB0Y3A6JHtzeXN0ZW1Qb3J0fWBdKTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIFRDUCBwb3J0IGZvcndhcmRpbmcgd2l0aCBhZGIgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LiBUaGUgZm9yd2FyZGluZ1xuICogZm9yIHRoZSBnaXZlbiBwb3J0IHNob3VsZCBiZSBzZXR1cCB3aXRoIHtAbGluayAjZm9yd2FyZFBvcnR9IGZpcnN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gZGV2aWNlUG9ydCAtIFRoZSBudW1iZXIgb2YgdGhlIHJlbW90ZSBkZXZpY2UgcG9ydFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gcmVtb3ZlIGZvcndhcmRpbmcgb24uXG4gKi9cbm1ldGhvZHMucmVtb3ZlUG9ydFJldmVyc2UgPSBhc3luYyBmdW5jdGlvbiByZW1vdmVQb3J0UmV2ZXJzZSAoZGV2aWNlUG9ydCkge1xuICBsb2cuZGVidWcoYFJlbW92aW5nIHJldmVyc2UgZm9yd2FyZGVkIHBvcnQgc29ja2V0IGNvbm5lY3Rpb246ICR7ZGV2aWNlUG9ydH0gYCk7XG4gIGF3YWl0IHRoaXMuYWRiRXhlYyhbJ3JldmVyc2UnLCBgLS1yZW1vdmVgLCBgdGNwOiR7ZGV2aWNlUG9ydH1gXSk7XG59O1xuXG4vKipcbiAqIFNldHVwIFRDUCBwb3J0IGZvcndhcmRpbmcgd2l0aCBhZGIgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LiBUaGUgZGlmZmVyZW5jZVxuICogYmV0d2VlbiB7QGxpbmsgI2ZvcndhcmRQb3J0fSBpcyB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgc2V0dXAgZm9yIGFuIGFic3RyYWN0XG4gKiBsb2NhbCBwb3J0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gc3lzdGVtUG9ydCAtIFRoZSBudW1iZXIgb2YgdGhlIGxvY2FsIHN5c3RlbSBwb3J0LlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBkZXZpY2VQb3J0IC0gVGhlIG51bWJlciBvZiB0aGUgcmVtb3RlIGRldmljZSBwb3J0LlxuICovXG5tZXRob2RzLmZvcndhcmRBYnN0cmFjdFBvcnQgPSBhc3luYyBmdW5jdGlvbiBmb3J3YXJkQWJzdHJhY3RQb3J0IChzeXN0ZW1Qb3J0LCBkZXZpY2VQb3J0KSB7XG4gIGxvZy5kZWJ1ZyhgRm9yd2FyZGluZyBzeXN0ZW06ICR7c3lzdGVtUG9ydH0gdG8gYWJzdHJhY3QgZGV2aWNlOiAke2RldmljZVBvcnR9YCk7XG4gIGF3YWl0IHRoaXMuYWRiRXhlYyhbJ2ZvcndhcmQnLCBgdGNwOiR7c3lzdGVtUG9ydH1gLCBgbG9jYWxhYnN0cmFjdDoke2RldmljZVBvcnR9YF0pO1xufTtcblxuLyoqXG4gKiBFeGVjdXRlIHBpbmcgc2hlbGwgY29tbWFuZCBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgY29tbWFuZCBvdXRwdXQgY29udGFpbnMgJ3BpbmcnIHN1YnN0cmluZy5cbiAqIEB0aHJvd3Mge2Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgZXhlY3V0aW5nICdwaW5nJyBjb21tYW5kIG9uIHRoZVxuICogICAgICAgICAgICAgICAgIGRldmljZSB1bmRlciB0ZXN0LlxuICovXG5tZXRob2RzLnBpbmcgPSBhc3luYyBmdW5jdGlvbiBwaW5nICgpIHtcbiAgbGV0IHN0ZG91dCA9IGF3YWl0IHRoaXMuc2hlbGwoWydlY2hvJywgJ3BpbmcnXSk7XG4gIGlmIChzdGRvdXQuaW5kZXhPZigncGluZycpID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBBREIgcGluZyBmYWlsZWQsIHJldHVybmVkICR7c3Rkb3V0fWApO1xufTtcblxuLyoqXG4gKiBSZXN0YXJ0IHRoZSBkZXZpY2UgdW5kZXIgdGVzdCB1c2luZyBhZGIgY29tbWFuZHMuXG4gKlxuICogQHRocm93cyB7ZXJyb3J9IElmIHN0YXJ0IGZhaWxzLlxuICovXG5tZXRob2RzLnJlc3RhcnQgPSBhc3luYyBmdW5jdGlvbiByZXN0YXJ0ICgpIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCB0aGlzLnN0b3BMb2djYXQoKTtcbiAgICBhd2FpdCB0aGlzLnJlc3RhcnRBZGIoKTtcbiAgICBhd2FpdCB0aGlzLndhaXRGb3JEZXZpY2UoNjApO1xuICAgIGF3YWl0IHRoaXMuc3RhcnRMb2djYXQodGhpcy5fbG9nY2F0U3RhcnR1cFBhcmFtcyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFJlc3RhcnQgZmFpbGVkLiBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gIH1cbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTG9nY2F0T3B0c1xuICogQHByb3BlcnR5IHtzdHJpbmd9IGZvcm1hdCBUaGUgbG9nIHByaW50IGZvcm1hdCwgd2hlcmUgPGZvcm1hdD4gaXMgb25lIG9mOlxuICogICBicmllZiBwcm9jZXNzIHRhZyB0aHJlYWQgcmF3IHRpbWUgdGhyZWFkdGltZSBsb25nXG4gKiBgdGhyZWFkdGltZWAgaXMgdGhlIGRlZmF1bHQgdmFsdWUuXG4gKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IGZpbHRlclNwZWNzIFNlcmllcyBvZiA8dGFnPls6cHJpb3JpdHldXG4gKiB3aGVyZSA8dGFnPiBpcyBhIGxvZyBjb21wb25lbnQgdGFnIChvciAqIGZvciBhbGwpIGFuZCBwcmlvcml0eSBpczpcbiAqICBWICAgIFZlcmJvc2VcbiAqICBEICAgIERlYnVnXG4gKiAgSSAgICBJbmZvXG4gKiAgVyAgICBXYXJuXG4gKiAgRSAgICBFcnJvclxuICogIEYgICAgRmF0YWxcbiAqICBTICAgIFNpbGVudCAoc3VwcmVzcyBhbGwgb3V0cHV0KVxuICpcbiAqICcqJyBtZWFucyAnKjpkJyBhbmQgPHRhZz4gYnkgaXRzZWxmIG1lYW5zIDx0YWc+OnZcbiAqXG4gKiBJZiBub3Qgc3BlY2lmaWVkIG9uIHRoZSBjb21tYW5kbGluZSwgZmlsdGVyc3BlYyBpcyBzZXQgZnJvbSBBTkRST0lEX0xPR19UQUdTLlxuICogSWYgbm8gZmlsdGVyc3BlYyBpcyBmb3VuZCwgZmlsdGVyIGRlZmF1bHRzIHRvICcqOkknXG4gKi9cblxuLyoqXG4gKiBTdGFydCB0aGUgbG9nY2F0IHByb2Nlc3MgdG8gZ2F0aGVyIGxvZ3MuXG4gKlxuICogQHBhcmFtIHs/TG9nY2F0T3B0c30gb3B0c1xuICogQHRocm93cyB7RXJyb3J9IElmIHJlc3RhcnQgZmFpbHMuXG4gKi9cbm1ldGhvZHMuc3RhcnRMb2djYXQgPSBhc3luYyBmdW5jdGlvbiBzdGFydExvZ2NhdCAob3B0cyA9IHt9KSB7XG4gIGlmICghXy5pc0VtcHR5KHRoaXMubG9nY2F0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlRyeWluZyB0byBzdGFydCBsb2djYXQgY2FwdHVyZSBidXQgaXQncyBhbHJlYWR5IHN0YXJ0ZWQhXCIpO1xuICB9XG5cbiAgdGhpcy5sb2djYXQgPSBuZXcgTG9nY2F0KHtcbiAgICBhZGI6IHRoaXMuZXhlY3V0YWJsZSxcbiAgICBkZWJ1ZzogZmFsc2UsXG4gICAgZGVidWdUcmFjZTogZmFsc2UsXG4gICAgY2xlYXJEZXZpY2VMb2dzT25TdGFydDogISF0aGlzLmNsZWFyRGV2aWNlTG9nc09uU3RhcnQsXG4gIH0pO1xuICBhd2FpdCB0aGlzLmxvZ2NhdC5zdGFydENhcHR1cmUob3B0cyk7XG4gIHRoaXMuX2xvZ2NhdFN0YXJ0dXBQYXJhbXMgPSBvcHRzO1xufTtcblxuLyoqXG4gKiBTdG9wIHRoZSBhY3RpdmUgbG9nY2F0IHByb2Nlc3Mgd2hpY2ggZ2F0aGVycyBsb2dzLlxuICogVGhlIGNhbGwgd2lsbCBiZSBpZ25vcmVkIGlmIG5vIGxvZ2NhdCBwcm9jZXNzIGlzIHJ1bm5pbmcuXG4gKi9cbm1ldGhvZHMuc3RvcExvZ2NhdCA9IGFzeW5jIGZ1bmN0aW9uIHN0b3BMb2djYXQgKCkge1xuICBpZiAoXy5pc0VtcHR5KHRoaXMubG9nY2F0KSkge1xuICAgIHJldHVybjtcbiAgfVxuICB0cnkge1xuICAgIGF3YWl0IHRoaXMubG9nY2F0LnN0b3BDYXB0dXJlKCk7XG4gIH0gZmluYWxseSB7XG4gICAgdGhpcy5sb2djYXQgPSBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBvdXRwdXQgZnJvbSB0aGUgY3VycmVudGx5IHJ1bm5pbmcgbG9nY2F0IHByb2Nlc3MuXG4gKiBUaGUgbG9nY2F0IHByb2Nlc3Mgc2hvdWxkIGJlIGV4ZWN1dGVkIGJ5IHsybGluayAjc3RhcnRMb2djYXR9IG1ldGhvZC5cbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjb2xsZWN0ZWQgbG9nY2F0IG91dHB1dC5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBsb2djYXQgcHJvY2VzcyBpcyBub3QgcnVubmluZy5cbiAqL1xubWV0aG9kcy5nZXRMb2djYXRMb2dzID0gZnVuY3Rpb24gZ2V0TG9nY2F0TG9ncyAoKSB7XG4gIGlmIChfLmlzRW1wdHkodGhpcy5sb2djYXQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgZ2V0IGxvZ2NhdCBsb2dzIHNpbmNlIGxvZ2NhdCBoYXNuJ3Qgc3RhcnRlZFwiKTtcbiAgfVxuICByZXR1cm4gdGhpcy5sb2djYXQuZ2V0TG9ncygpO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIGNhbGxiYWNrIGZvciB0aGUgbG9nY2F0IG91dHB1dCBldmVudC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciAtIFRoZSBsaXN0ZW5lciBmdW5jdGlvbiwgd2hpY2ggYWNjZXB0cyBvbmUgYXJndW1lbnQuIFRoZSBhcmd1bWVudCBpc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhIGxvZyByZWNvcmQgb2JqZWN0IHdpdGggYHRpbWVzdGFtcGAsIGBsZXZlbGAgYW5kIGBtZXNzYWdlYCBwcm9wZXJ0aWVzLlxuICogQHRocm93cyB7RXJyb3J9IElmIGxvZ2NhdCBwcm9jZXNzIGlzIG5vdCBydW5uaW5nLlxuICovXG5tZXRob2RzLnNldExvZ2NhdExpc3RlbmVyID0gZnVuY3Rpb24gc2V0TG9nY2F0TGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gIGlmIChfLmlzRW1wdHkodGhpcy5sb2djYXQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTG9nY2F0IHByb2Nlc3MgaGFzbid0IGJlZW4gc3RhcnRlZFwiKTtcbiAgfVxuICB0aGlzLmxvZ2NhdC5vbignb3V0cHV0JywgbGlzdGVuZXIpO1xufTtcblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBwcmV2aW91c2x5IHNldCBjYWxsYmFjayBmb3IgdGhlIGxvZ2NhdCBvdXRwdXQgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgLSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24sIHdoaWNoIGhhcyBiZWVuIHByZXZpb3VzbHlcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzc2VkIHRvIGBzZXRMb2djYXRMaXN0ZW5lcmBcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBsb2djYXQgcHJvY2VzcyBpcyBub3QgcnVubmluZy5cbiAqL1xubWV0aG9kcy5yZW1vdmVMb2djYXRMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxvZ2NhdExpc3RlbmVyIChsaXN0ZW5lcikge1xuICBpZiAoXy5pc0VtcHR5KHRoaXMubG9nY2F0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkxvZ2NhdCBwcm9jZXNzIGhhc24ndCBiZWVuIHN0YXJ0ZWRcIik7XG4gIH1cbiAgdGhpcy5sb2djYXQucmVtb3ZlTGlzdGVuZXIoJ291dHB1dCcsIGxpc3RlbmVyKTtcbn07XG5cbi8qKlxuICogQXQgc29tZSBwb2ludCBvZiB0aW1lIEdvb2dsZSBoYXMgY2hhbmdlZCB0aGUgZGVmYXVsdCBgcHNgIGJlaGF2aW91ciwgc28gaXQgb25seVxuICogbGlzdHMgcHJvY2Vzc2VzIHRoYXQgYmVsb25nIHRvIHRoZSBjdXJyZW50IHNoZWxsIHVzZXIgcmF0aGVyIHRvIGFsbFxuICogdXNlcnMuIEl0IGlzIG5lY2Vzc2FyeSB0byBleGVjdXRlIHBzIHdpdGggLUEgY29tbWFuZCBsaW5lIGFyZ3VtZW50XG4gKiB0byBtaW1pYyB0aGUgcHJldmlvdXMgYmVoYXZpb3VyLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBvdXRwdXQgb2YgYHBzYCBjb21tYW5kIHdoZXJlIGFsbCBwcm9jZXNzZXMgYXJlIGluY2x1ZGVkXG4gKi9cbm1ldGhvZHMubGlzdFByb2Nlc3NTdGF0dXMgPSBhc3luYyBmdW5jdGlvbiBsaXN0UHJvY2Vzc1N0YXR1cyAoKSB7XG4gIGlmICghXy5pc0Jvb2xlYW4odGhpcy5fZG9lc1BzU3VwcG9ydEFPcHRpb24pKSB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuX2RvZXNQc1N1cHBvcnRBT3B0aW9uID0gL14tQVxcYi9tLnRlc3QoYXdhaXQgdGhpcy5zaGVsbChbJ3BzJywgJy0taGVscCddKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nLmRlYnVnKGUuc3RhY2spO1xuICAgICAgdGhpcy5fZG9lc1BzU3VwcG9ydEFPcHRpb24gPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGF3YWl0IHRoaXMuc2hlbGwodGhpcy5fZG9lc1BzU3VwcG9ydEFPcHRpb24gPyBbJ3BzJywgJy1BJ10gOiBbJ3BzJ10pO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHByb2Nlc3MgbmFtZSBmb3IgdGhlIGdpdmVuIHByb2Nlc3MgaWRlbnRpZmllclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gcGlkIC0gVGhlIHZhbGlkIHByb2Nlc3MgaWRlbnRpZmllclxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBnaXZlbiBQSUQgaXMgZWl0aGVyIGludmFsaWQgb3IgaXMgbm90IHByZXNlbnRcbiAqIGluIHRoZSBhY3RpdmUgcHJvY2Vzc2VzIGxpc3RcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBwcm9jZXNzIG5hbWVcbiAqL1xubWV0aG9kcy5nZXROYW1lQnlQaWQgPSBhc3luYyBmdW5jdGlvbiBnZXROYW1lQnlQaWQgKHBpZCkge1xuICBpZiAoaXNOYU4ocGlkKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIFBJRCB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgbnVtYmVyLiAnJHtwaWR9JyBpcyBnaXZlbiBpbnN0ZWFkYCk7XG4gIH1cbiAgcGlkID0gcGFyc2VJbnQocGlkLCAxMCk7XG5cbiAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgdGhpcy5saXN0UHJvY2Vzc1N0YXR1cygpO1xuICBjb25zdCB0aXRsZU1hdGNoID0gUFNfVElUTEVfUEFUVEVSTi5leGVjKHN0ZG91dCk7XG4gIGlmICghdGl0bGVNYXRjaCkge1xuICAgIGxvZy5kZWJ1ZyhzdGRvdXQpO1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGdldCB0aGUgcHJvY2VzcyBuYW1lIGZvciBQSUQgJyR7cGlkfSdgKTtcbiAgfVxuICBjb25zdCBhbGxUaXRsZXMgPSB0aXRsZU1hdGNoWzFdLnRyaW0oKS5zcGxpdCgvXFxzKy8pO1xuICBjb25zdCBwaWRJbmRleCA9IGFsbFRpdGxlcy5pbmRleE9mKFBJRF9DT0xVTU5fVElUTEUpO1xuICAvLyBpdCBtaWdodCBub3QgYmUgc3RhYmxlIHRvIHRha2UgTkFNRSBieSBpbmRleCwgYmVjYXVzZSBkZXBlbmRpbmcgb24gdGhlXG4gIC8vIGFjdHVhbCBTREsgdGhlIHBzIG91dHB1dCBtaWdodCBub3QgY29udGFpbiBhbiBhYmJyZXZpYXRpb24gZm9yIHRoZSBTIGZsYWc6XG4gIC8vIFVTRVIgICAgIFBJRCAgIFBQSUQgIFZTSVpFICBSU1MgICAgIFdDSEFOICAgIFBDICAgICAgICBOQU1FXG4gIC8vIFVTRVIgICAgIFBJRCAgIFBQSUQgIFZTSVpFICBSU1MgICAgIFdDSEFOICAgIFBDICAgUyAgICBOQU1FXG4gIGNvbnN0IG5hbWVPZmZzZXQgPSBhbGxUaXRsZXMuaW5kZXhPZihQUk9DRVNTX05BTUVfQ09MVU1OX1RJVExFKSAtIGFsbFRpdGxlcy5sZW5ndGg7XG4gIGNvbnN0IHBpZFJlZ2V4ID0gbmV3IFJlZ0V4cChgXiguKlxcXFxiJHtwaWR9XFxcXGIuKikkYCwgJ2dtJyk7XG4gIGxldCBtYXRjaGVkTGluZTtcbiAgd2hpbGUgKChtYXRjaGVkTGluZSA9IHBpZFJlZ2V4LmV4ZWMoc3Rkb3V0KSkpIHtcbiAgICBjb25zdCBpdGVtcyA9IG1hdGNoZWRMaW5lWzFdLnRyaW0oKS5zcGxpdCgvXFxzKy8pO1xuICAgIGlmIChwYXJzZUludChpdGVtc1twaWRJbmRleF0sIDEwKSA9PT0gcGlkICYmIGl0ZW1zW2l0ZW1zLmxlbmd0aCArIG5hbWVPZmZzZXRdKSB7XG4gICAgICByZXR1cm4gaXRlbXNbaXRlbXMubGVuZ3RoICsgbmFtZU9mZnNldF07XG4gICAgfVxuICB9XG4gIGxvZy5kZWJ1ZyhzdGRvdXQpO1xuICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBnZXQgdGhlIHByb2Nlc3MgbmFtZSBmb3IgUElEICcke3BpZH0nYCk7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgbGlzdCBvZiBwcm9jZXNzIGlkcyBmb3IgdGhlIHBhcnRpY3VsYXIgcHJvY2VzcyBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgcGFydCBvZiBwcm9jZXNzIG5hbWUuXG4gKiBAcmV0dXJuIHtBcnJheS48bnVtYmVyPn0gVGhlIGxpc3Qgb2YgbWF0Y2hlZCBwcm9jZXNzIElEcyBvciBhbiBlbXB0eSBsaXN0LlxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXNzZWQgcHJvY2VzcyBuYW1lIGlzIG5vdCBhIHZhbGlkIG9uZVxuICovXG5tZXRob2RzLmdldFBJRHNCeU5hbWUgPSBhc3luYyBmdW5jdGlvbiBnZXRQSURzQnlOYW1lIChuYW1lKSB7XG4gIGxvZy5kZWJ1ZyhgR2V0dGluZyBJRHMgb2YgYWxsICcke25hbWV9JyBwcm9jZXNzZXNgKTtcbiAgaWYgKCF0aGlzLmlzVmFsaWRDbGFzcyhuYW1lKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwcm9jZXNzIG5hbWU6ICcke25hbWV9J2ApO1xuICB9XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMzU2N1xuICBpZiAoYXdhaXQgdGhpcy5nZXRBcGlMZXZlbCgpID49IDIzKSB7XG4gICAgaWYgKCFfLmlzQm9vbGVhbih0aGlzLl9pc1BncmVwQXZhaWxhYmxlKSkge1xuICAgICAgLy8gcGdyZXAgaXMgaW4gcHJpb3JpdHksIHNpbmNlIHBpZG9mIGhhcyBiZWVuIHJlcG9ydGVkIG9mIGhhdmluZyBidWdzIG9uIHNvbWUgcGxhdGZvcm1zXG4gICAgICBjb25zdCBwZ3JlcE91dHB1dCA9IF8udHJpbShhd2FpdCB0aGlzLnNoZWxsKFsncGdyZXAgLS1oZWxwOyBlY2hvICQ/J10pKTtcbiAgICAgIHRoaXMuX2lzUGdyZXBBdmFpbGFibGUgPSBwYXJzZUludChfLmxhc3QocGdyZXBPdXRwdXQuc3BsaXQoL1xccysvKSksIDEwKSA9PT0gMDtcbiAgICAgIGlmICh0aGlzLl9pc1BncmVwQXZhaWxhYmxlKSB7XG4gICAgICAgIHRoaXMuX2NhblBncmVwVXNlRnVsbENtZExpbmVTZWFyY2ggPSAvXi1mXFxiL20udGVzdChwZ3JlcE91dHB1dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pc1BpZG9mQXZhaWxhYmxlID0gcGFyc2VJbnQoYXdhaXQgdGhpcy5zaGVsbChbJ3BpZG9mIC0taGVscCA+IC9kZXYvbnVsbDsgZWNobyAkPyddKSwgMTApID09PSAwO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5faXNQZ3JlcEF2YWlsYWJsZSB8fCB0aGlzLl9pc1BpZG9mQXZhaWxhYmxlKSB7XG4gICAgICBjb25zdCBzaGVsbENvbW1hbmQgPSB0aGlzLl9pc1BncmVwQXZhaWxhYmxlXG4gICAgICAgID8gKHRoaXMuX2NhblBncmVwVXNlRnVsbENtZExpbmVTZWFyY2hcbiAgICAgICAgICA/IFsncGdyZXAnLCAnLWYnLCBfLmVzY2FwZVJlZ0V4cChgKFtbOmJsYW5rOl1dfF4pJHtuYW1lfShbWzpibGFuazpdXXwkKWApXVxuICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMzg3MlxuICAgICAgICAgIDogW2BwZ3JlcCBeJHtfLmVzY2FwZVJlZ0V4cChuYW1lLnNsaWNlKC1NQVhfUEdSRVBfUEFUVEVSTl9MRU4pKX0kIGAgK1xuICAgICAgICAgICAgICBgfHwgcGdyZXAgXiR7Xy5lc2NhcGVSZWdFeHAobmFtZS5zbGljZSgwLCBNQVhfUEdSRVBfUEFUVEVSTl9MRU4pKX0kYF0pXG4gICAgICAgIDogWydwaWRvZicsIG5hbWVdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIChhd2FpdCB0aGlzLnNoZWxsKHNoZWxsQ29tbWFuZCkpXG4gICAgICAgICAgLnNwbGl0KC9cXHMrLylcbiAgICAgICAgICAubWFwKCh4KSA9PiBwYXJzZUludCh4LCAxMCkpXG4gICAgICAgICAgLmZpbHRlcigoeCkgPT4gXy5pc0ludGVnZXIoeCkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBlcnJvciBjb2RlIDEgaXMgcmV0dXJuZWQgaWYgdGhlIHV0aWxpdHkgZGlkIG5vdCBmaW5kIGFueSBwcm9jZXNzZXNcbiAgICAgICAgLy8gd2l0aCB0aGUgZ2l2ZW4gbmFtZVxuICAgICAgICBpZiAoZS5jb2RlICE9PSAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZXh0cmFjdCBwcm9jZXNzIElEIG9mICcke25hbWV9JzogJHtlLm1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF8uaW5jbHVkZXMoZS5zdGRlcnIgfHwgZS5zdGRvdXQsICdzeW50YXggZXJyb3InKSkge1xuICAgICAgICAgIGxvZy53YXJuKGBHb3QgYW4gdW5leHBlY3RlZCByZXNwb25zZSBmcm9tIHRoZSBzaGVsbCBpbnRlcnByZXRlcjogJHtlLnN0ZGVyciB8fCBlLnN0ZG91dH1gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsb2cuZGVidWcoJ1VzaW5nIHBzLWJhc2VkIFBJRCBkZXRlY3Rpb24nKTtcbiAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgdGhpcy5saXN0UHJvY2Vzc1N0YXR1cygpO1xuICBjb25zdCB0aXRsZU1hdGNoID0gUFNfVElUTEVfUEFUVEVSTi5leGVjKHN0ZG91dCk7XG4gIGlmICghdGl0bGVNYXRjaCkge1xuICAgIGxvZy5kZWJ1ZyhzdGRvdXQpO1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGV4dHJhY3QgUElEIG9mICcke25hbWV9JyBmcm9tIHBzIG91dHB1dGApO1xuICB9XG4gIGNvbnN0IGFsbFRpdGxlcyA9IHRpdGxlTWF0Y2hbMV0udHJpbSgpLnNwbGl0KC9cXHMrLyk7XG4gIGNvbnN0IHBpZEluZGV4ID0gYWxsVGl0bGVzLmluZGV4T2YoUElEX0NPTFVNTl9USVRMRSk7XG4gIGNvbnN0IHBpZHMgPSBbXTtcbiAgY29uc3QgcHJvY2Vzc05hbWVSZWdleCA9IG5ldyBSZWdFeHAoYF4oLipcXFxcYlxcXFxkK1xcXFxiLipcXFxcYiR7Xy5lc2NhcGVSZWdFeHAobmFtZSl9XFxcXGIuKikkYCwgJ2dtJyk7XG4gIGxldCBtYXRjaGVkTGluZTtcbiAgd2hpbGUgKChtYXRjaGVkTGluZSA9IHByb2Nlc3NOYW1lUmVnZXguZXhlYyhzdGRvdXQpKSkge1xuICAgIGNvbnN0IGl0ZW1zID0gbWF0Y2hlZExpbmVbMV0udHJpbSgpLnNwbGl0KC9cXHMrLyk7XG4gICAgaWYgKHBpZEluZGV4ID49IGFsbFRpdGxlcy5sZW5ndGggfHwgaXNOYU4oaXRlbXNbcGlkSW5kZXhdKSkge1xuICAgICAgbG9nLmRlYnVnKHN0ZG91dCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBleHRyYWN0IFBJRCBvZiAnJHtuYW1lfScgZnJvbSAnJHttYXRjaGVkTGluZVsxXS50cmltKCl9J2ApO1xuICAgIH1cbiAgICBwaWRzLnB1c2gocGFyc2VJbnQoaXRlbXNbcGlkSW5kZXhdLCAxMCkpO1xuICB9XG4gIHJldHVybiBwaWRzO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGxpc3Qgb2YgcHJvY2VzcyBpZHMgZm9yIHRoZSBwYXJ0aWN1bGFyIHByb2Nlc3Mgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIHBhcnQgb2YgcHJvY2VzcyBuYW1lLlxuICogQHJldHVybiB7QXJyYXkuPG51bWJlcj59IFRoZSBsaXN0IG9mIG1hdGNoZWQgcHJvY2VzcyBJRHMgb3IgYW4gZW1wdHkgbGlzdC5cbiAqL1xubWV0aG9kcy5raWxsUHJvY2Vzc2VzQnlOYW1lID0gYXN5bmMgZnVuY3Rpb24ga2lsbFByb2Nlc3Nlc0J5TmFtZSAobmFtZSkge1xuICB0cnkge1xuICAgIGxvZy5kZWJ1ZyhgQXR0ZW1wdGluZyB0byBraWxsIGFsbCAke25hbWV9IHByb2Nlc3Nlc2ApO1xuICAgIGNvbnN0IHBpZHMgPSBhd2FpdCB0aGlzLmdldFBJRHNCeU5hbWUobmFtZSk7XG4gICAgaWYgKF8uaXNFbXB0eShwaWRzKSkge1xuICAgICAgbG9nLmluZm8oYE5vICcke25hbWV9JyBwcm9jZXNzIGhhcyBiZWVuIGZvdW5kYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IEIuYWxsKHBpZHMubWFwKChwKSA9PiB0aGlzLmtpbGxQcm9jZXNzQnlQSUQocCkpKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBraWxsICR7bmFtZX0gcHJvY2Vzc2VzLiBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gIH1cbn07XG5cbi8qKlxuICogS2lsbCB0aGUgcGFydGljdWxhciBwcm9jZXNzIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqIFRoZSBjdXJyZW50IHVzZXIgaXMgYXV0b21hdGljYWxseSBzd2l0Y2hlZCB0byByb290IGlmIG5lY2Vzc2FyeSBpbiBvcmRlclxuICogdG8gcHJvcGVybHkga2lsbCB0aGUgcHJvY2Vzcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHBpZCAtIFRoZSBJRCBvZiB0aGUgcHJvY2VzcyB0byBiZSBraWxsZWQuXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHByb2Nlc3MgY2Fubm90IGJlIGtpbGxlZC5cbiAqL1xubWV0aG9kcy5raWxsUHJvY2Vzc0J5UElEID0gYXN5bmMgZnVuY3Rpb24ga2lsbFByb2Nlc3NCeVBJRCAocGlkKSB7XG4gIGxvZy5kZWJ1ZyhgQXR0ZW1wdGluZyB0byBraWxsIHByb2Nlc3MgJHtwaWR9YCk7XG4gIGNvbnN0IG5vUHJvY2Vzc0ZsYWcgPSAnTm8gc3VjaCBwcm9jZXNzJztcbiAgdHJ5IHtcbiAgICAvLyBDaGVjayBpZiB0aGUgcHJvY2VzcyBleGlzdHMgYW5kIHRocm93IGFuIGV4Y2VwdGlvbiBvdGhlcndpc2VcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFsna2lsbCcsIHBpZF0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKF8uaW5jbHVkZXMoZS5zdGRlcnIsIG5vUHJvY2Vzc0ZsYWcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghXy5pbmNsdWRlcyhlLnN0ZGVyciwgJ09wZXJhdGlvbiBub3QgcGVybWl0dGVkJykpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIGxvZy5pbmZvKGBDYW5ub3Qga2lsbCBQSUQgJHtwaWR9IGR1ZSB0byBpbnN1ZmZpY2llbnQgcGVybWlzc2lvbnMuIFJldHJ5aW5nIGFzIHJvb3RgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zaGVsbChbJ2tpbGwnLCBwaWRdLCB7XG4gICAgICAgIHByaXZpbGVnZWQ6IHRydWVcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUxKSB7XG4gICAgICBpZiAoXy5pbmNsdWRlcyhlMS5zdGRlcnIsIG5vUHJvY2Vzc0ZsYWcpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRocm93IGUxO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBCcm9hZGNhc3QgcHJvY2VzcyBraWxsaW5nIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW50ZW50IC0gVGhlIG5hbWUgb2YgdGhlIGludGVudCB0byBicm9hZGNhc3QgdG8uXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvY2Vzc05hbWUgLSBUaGUgbmFtZSBvZiB0aGUga2lsbGVkIHByb2Nlc3MuXG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgdGhlIHByb2Nlc3Mgd2FzIG5vdCBraWxsZWQuXG4gKi9cbm1ldGhvZHMuYnJvYWRjYXN0UHJvY2Vzc0VuZCA9IGFzeW5jIGZ1bmN0aW9uIGJyb2FkY2FzdFByb2Nlc3NFbmQgKGludGVudCwgcHJvY2Vzc05hbWUpIHtcbiAgLy8gc3RhcnQgdGhlIGJyb2FkY2FzdCB3aXRob3V0IHdhaXRpbmcgZm9yIGl0IHRvIGZpbmlzaC5cbiAgdGhpcy5icm9hZGNhc3QoaW50ZW50KTtcbiAgLy8gd2FpdCBmb3IgdGhlIHByb2Nlc3MgdG8gZW5kXG4gIGxldCBzdGFydCA9IERhdGUubm93KCk7XG4gIGxldCB0aW1lb3V0TXMgPSA0MDAwMDtcbiAgdHJ5IHtcbiAgICB3aGlsZSAoKERhdGUubm93KCkgLSBzdGFydCkgPCB0aW1lb3V0TXMpIHtcbiAgICAgIGlmIChhd2FpdCB0aGlzLnByb2Nlc3NFeGlzdHMocHJvY2Vzc05hbWUpKSB7XG4gICAgICAgIC8vIGNvb2wgZG93blxuICAgICAgICBhd2FpdCBzbGVlcCg0MDApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBQcm9jZXNzIG5ldmVyIGRpZWQgd2l0aGluICR7dGltZW91dE1zfSBtc2ApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gYnJvYWRjYXN0IHByb2Nlc3MgZW5kLiBPcmlnaW5hbCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gIH1cbn07XG5cbi8qKlxuICogQnJvYWRjYXN0IGEgbWVzc2FnZSB0byB0aGUgZ2l2ZW4gaW50ZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnRlbnQgLSBUaGUgbmFtZSBvZiB0aGUgaW50ZW50IHRvIGJyb2FkY2FzdCB0by5cbiAqIEB0aHJvd3Mge2Vycm9yfSBJZiBpbnRlbnQgbmFtZSBpcyBub3QgYSB2YWxpZCBjbGFzcyBuYW1lLlxuICovXG5tZXRob2RzLmJyb2FkY2FzdCA9IGFzeW5jIGZ1bmN0aW9uIGJyb2FkY2FzdCAoaW50ZW50KSB7XG4gIGlmICghdGhpcy5pc1ZhbGlkQ2xhc3MoaW50ZW50KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBpbnRlbnQgJHtpbnRlbnR9YCk7XG4gIH1cbiAgbG9nLmRlYnVnKGBCcm9hZGNhc3Rpbmc6ICR7aW50ZW50fWApO1xuICBhd2FpdCB0aGlzLnNoZWxsKFsnYW0nLCAnYnJvYWRjYXN0JywgJy1hJywgaW50ZW50XSk7XG59O1xuXG4vKipcbiAqIEtpbGwgQW5kcm9pZCBpbnN0cnVtZW50cyBpZiB0aGV5IGFyZSBjdXJyZW50bHkgcnVubmluZy5cbiAqL1xubWV0aG9kcy5lbmRBbmRyb2lkQ292ZXJhZ2UgPSBhc3luYyBmdW5jdGlvbiBlbmRBbmRyb2lkQ292ZXJhZ2UgKCkge1xuICBpZiAodGhpcy5pbnN0cnVtZW50UHJvYyAmJiB0aGlzLmluc3RydW1lbnRQcm9jLmlzUnVubmluZykge1xuICAgIGF3YWl0IHRoaXMuaW5zdHJ1bWVudFByb2Muc3RvcCgpO1xuICB9XG59O1xuXG4vKipcbiAqIEluc3RydW1lbnQgdGhlIHBhcnRpY3VsYXIgYWN0aXZpdHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHBrZyAtIFRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGJlIGluc3RydW1lbnRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpdml0eSAtIFRoZSBuYW1lIG9mIHRoZSBtYWluIGFjdGl2aXR5IGluIHRoaXMgcGFja2FnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnN0cnVtZW50V2l0aCAtIFRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGluc3RydW1lbnRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBhY3Rpdml0eSB3aXRoLlxuICogQHRocm93cyB7ZXJyb3J9IElmIGFueSBleGNlcHRpb24gaXMgcmVwb3J0ZWQgYnkgYWRiIHNoZWxsLlxuICovXG5tZXRob2RzLmluc3RydW1lbnQgPSBhc3luYyBmdW5jdGlvbiBpbnN0cnVtZW50IChwa2csIGFjdGl2aXR5LCBpbnN0cnVtZW50V2l0aCkge1xuICBpZiAoYWN0aXZpdHlbMF0gIT09ICcuJykge1xuICAgIHBrZyA9ICcnO1xuICB9XG4gIGxldCBwa2dBY3Rpdml0eSA9IChwa2cgKyBhY3Rpdml0eSkucmVwbGFjZSgvXFwuKy9nLCAnLicpOyAvLyBGaXggcGtnLi5hY3Rpdml0eSBlcnJvclxuICBsZXQgc3Rkb3V0ID0gYXdhaXQgdGhpcy5zaGVsbChbXG4gICAgJ2FtJywgJ2luc3RydW1lbnQnLFxuICAgICctZScsICdtYWluX2FjdGl2aXR5JyxcbiAgICBwa2dBY3Rpdml0eSxcbiAgICBpbnN0cnVtZW50V2l0aCxcbiAgXSk7XG4gIGlmIChzdGRvdXQuaW5kZXhPZignRXhjZXB0aW9uJykgIT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGV4Y2VwdGlvbiBkdXJpbmcgaW5zdHJ1bWVudGF0aW9uLiBPcmlnaW5hbCBlcnJvciAke3N0ZG91dC5zcGxpdCgnXFxuJylbMF19YCk7XG4gIH1cbn07XG5cbi8qKlxuICogQ29sbGVjdCBBbmRyb2lkIGNvdmVyYWdlIGJ5IGluc3RydW1lbnRpbmcgdGhlIHBhcnRpY3VsYXIgYWN0aXZpdHkuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGluc3RydW1lbnRDbGFzcyAtIFRoZSBuYW1lIG9mIHRoZSBpbnN0cnVtZW50YXRpb24gY2xhc3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gd2FpdFBrZyAtIFRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGJlIGluc3RydW1lbnRlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB3YWl0QWN0aXZpdHkgLSBUaGUgbmFtZSBvZiB0aGUgbWFpbiBhY3Rpdml0eSBpbiB0aGlzIHBhY2thZ2UuXG4gKlxuICogQHJldHVybiB7cHJvbWlzZX0gVGhlIHByb21pc2UgaXMgc3VjY2Vzc2Z1bGx5IHJlc29sdmVkIGlmIHRoZSBpbnN0cnVtZW50YXRpb24gc3RhcnRzXG4gKiAgICAgICAgICAgICAgICAgICB3aXRob3V0IGVycm9ycy5cbiAqL1xubWV0aG9kcy5hbmRyb2lkQ292ZXJhZ2UgPSBhc3luYyBmdW5jdGlvbiBhbmRyb2lkQ292ZXJhZ2UgKGluc3RydW1lbnRDbGFzcywgd2FpdFBrZywgd2FpdEFjdGl2aXR5KSB7XG4gIGlmICghdGhpcy5pc1ZhbGlkQ2xhc3MoaW5zdHJ1bWVudENsYXNzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBjbGFzcyAke2luc3RydW1lbnRDbGFzc31gKTtcbiAgfVxuICByZXR1cm4gYXdhaXQgbmV3IEIoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCBhcmdzID0gdGhpcy5leGVjdXRhYmxlLmRlZmF1bHRBcmdzXG4gICAgICAuY29uY2F0KFsnc2hlbGwnLCAnYW0nLCAnaW5zdHJ1bWVudCcsICctZScsICdjb3ZlcmFnZScsICd0cnVlJywgJy13J10pXG4gICAgICAuY29uY2F0KFtpbnN0cnVtZW50Q2xhc3NdKTtcbiAgICBsb2cuZGVidWcoYENvbGxlY3RpbmcgY292ZXJhZ2UgZGF0YSB3aXRoOiAke1t0aGlzLmV4ZWN1dGFibGUucGF0aF0uY29uY2F0KGFyZ3MpLmpvaW4oJyAnKX1gKTtcbiAgICB0cnkge1xuICAgICAgLy8gYW0gaW5zdHJ1bWVudCBydW5zIGZvciB0aGUgbGlmZSBvZiB0aGUgYXBwIHByb2Nlc3MuXG4gICAgICB0aGlzLmluc3RydW1lbnRQcm9jID0gbmV3IFN1YlByb2Nlc3ModGhpcy5leGVjdXRhYmxlLnBhdGgsIGFyZ3MpO1xuICAgICAgYXdhaXQgdGhpcy5pbnN0cnVtZW50UHJvYy5zdGFydCgwKTtcbiAgICAgIHRoaXMuaW5zdHJ1bWVudFByb2Mub24oJ291dHB1dCcsIChzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIHJ1biBpbnN0cnVtZW50YXRpb24uIE9yaWdpbmFsIGVycm9yOiAke3N0ZGVycn1gKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yQWN0aXZpdHkod2FpdFBrZywgd2FpdEFjdGl2aXR5KTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QobmV3IEVycm9yKGBBbmRyb2lkIGNvdmVyYWdlIGZhaWxlZC4gT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIHBhcnRpY3VsYXIgcHJvcGVydHkgb2YgdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eS4gVGhpcyBuYW1lIHNob3VsZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmUga25vd24gdG8gX2FkYiBzaGVsbCBnZXRwcm9wXyB0b29sLlxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAqL1xubWV0aG9kcy5nZXREZXZpY2VQcm9wZXJ0eSA9IGFzeW5jIGZ1bmN0aW9uIGdldERldmljZVByb3BlcnR5IChwcm9wZXJ0eSkge1xuICBsZXQgc3Rkb3V0ID0gYXdhaXQgdGhpcy5zaGVsbChbJ2dldHByb3AnLCBwcm9wZXJ0eV0pO1xuICBsZXQgdmFsID0gc3Rkb3V0LnRyaW0oKTtcbiAgbG9nLmRlYnVnKGBDdXJyZW50IGRldmljZSBwcm9wZXJ0eSAnJHtwcm9wZXJ0eX0nOiAke3ZhbH1gKTtcbiAgcmV0dXJuIHZhbDtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gc2V0UHJvcE9wdHNcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcHJpdmlsZWdlZCAtIERvIHdlIHJ1biBzZXRQcm9wIGFzIGEgcHJpdmlsZWdlZCBjb21tYW5kPyBEZWZhdWx0IHRydWUuXG4gKi9cblxuLyoqXG4gKiBTZXQgdGhlIHBhcnRpY3VsYXIgcHJvcGVydHkgb2YgdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eS4gVGhpcyBuYW1lIHNob3VsZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmUga25vd24gdG8gX2FkYiBzaGVsbCBzZXRwcm9wXyB0b29sLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbCAtIFRoZSBuZXcgcHJvcGVydHkgdmFsdWUuXG4gKiBAcGFyYW0ge3NldFByb3BPcHRzfSBvcHRzXG4gKlxuICogQHRocm93cyB7ZXJyb3J9IElmIF9zZXRwcm9wXyB1dGlsaXR5IGZhaWxzIHRvIGNoYW5nZSBwcm9wZXJ0eSB2YWx1ZS5cbiAqL1xubWV0aG9kcy5zZXREZXZpY2VQcm9wZXJ0eSA9IGFzeW5jIGZ1bmN0aW9uIHNldERldmljZVByb3BlcnR5IChwcm9wLCB2YWwsIG9wdHMgPSB7fSkge1xuICBjb25zdCB7cHJpdmlsZWdlZCA9IHRydWV9ID0gb3B0cztcbiAgbG9nLmRlYnVnKGBTZXR0aW5nIGRldmljZSBwcm9wZXJ0eSAnJHtwcm9wfScgdG8gJyR7dmFsfSdgKTtcbiAgYXdhaXQgdGhpcy5zaGVsbChbJ3NldHByb3AnLCBwcm9wLCB2YWxdLCB7XG4gICAgcHJpdmlsZWdlZCxcbiAgfSk7XG59O1xuXG4vKipcbiAqIEByZXR1cm4ge3N0cmluZ30gQ3VycmVudCBzeXN0ZW0gbGFuZ3VhZ2Ugb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICovXG5tZXRob2RzLmdldERldmljZVN5c0xhbmd1YWdlID0gYXN5bmMgZnVuY3Rpb24gZ2V0RGV2aWNlU3lzTGFuZ3VhZ2UgKCkge1xuICByZXR1cm4gYXdhaXQgdGhpcy5nZXREZXZpY2VQcm9wZXJ0eSgncGVyc2lzdC5zeXMubGFuZ3VhZ2UnKTtcbn07XG5cbi8qKlxuICogQHJldHVybiB7c3RyaW5nfSBDdXJyZW50IGNvdW50cnkgbmFtZSBvbiB0aGUgZGV2aWNlIHVuZGVyIHRlc3QuXG4gKi9cbm1ldGhvZHMuZ2V0RGV2aWNlU3lzQ291bnRyeSA9IGFzeW5jIGZ1bmN0aW9uIGdldERldmljZVN5c0NvdW50cnkgKCkge1xuICByZXR1cm4gYXdhaXQgdGhpcy5nZXREZXZpY2VQcm9wZXJ0eSgncGVyc2lzdC5zeXMuY291bnRyeScpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEN1cnJlbnQgc3lzdGVtIGxvY2FsZSBuYW1lIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xubWV0aG9kcy5nZXREZXZpY2VTeXNMb2NhbGUgPSBhc3luYyBmdW5jdGlvbiBnZXREZXZpY2VTeXNMb2NhbGUgKCkge1xuICByZXR1cm4gYXdhaXQgdGhpcy5nZXREZXZpY2VQcm9wZXJ0eSgncGVyc2lzdC5zeXMubG9jYWxlJyk7XG59O1xuXG4vKipcbiAqIEByZXR1cm4ge3N0cmluZ30gQ3VycmVudCBwcm9kdWN0IGxhbmd1YWdlIG5hbWUgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICovXG5tZXRob2RzLmdldERldmljZVByb2R1Y3RMYW5ndWFnZSA9IGFzeW5jIGZ1bmN0aW9uIGdldERldmljZVByb2R1Y3RMYW5ndWFnZSAoKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLmdldERldmljZVByb3BlcnR5KCdyby5wcm9kdWN0LmxvY2FsZS5sYW5ndWFnZScpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEN1cnJlbnQgcHJvZHVjdCBjb3VudHJ5IG5hbWUgb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICovXG5tZXRob2RzLmdldERldmljZVByb2R1Y3RDb3VudHJ5ID0gYXN5bmMgZnVuY3Rpb24gZ2V0RGV2aWNlUHJvZHVjdENvdW50cnkgKCkge1xuICByZXR1cm4gYXdhaXQgdGhpcy5nZXREZXZpY2VQcm9wZXJ0eSgncm8ucHJvZHVjdC5sb2NhbGUucmVnaW9uJyk7XG59O1xuXG4vKipcbiAqIEByZXR1cm4ge3N0cmluZ30gQ3VycmVudCBwcm9kdWN0IGxvY2FsZSBuYW1lIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xubWV0aG9kcy5nZXREZXZpY2VQcm9kdWN0TG9jYWxlID0gYXN5bmMgZnVuY3Rpb24gZ2V0RGV2aWNlUHJvZHVjdExvY2FsZSAoKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLmdldERldmljZVByb3BlcnR5KCdyby5wcm9kdWN0LmxvY2FsZScpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBtb2RlbCBuYW1lIG9mIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xubWV0aG9kcy5nZXRNb2RlbCA9IGFzeW5jIGZ1bmN0aW9uIGdldE1vZGVsICgpIHtcbiAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0RGV2aWNlUHJvcGVydHkoJ3JvLnByb2R1Y3QubW9kZWwnKTtcbn07XG5cbi8qKlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgbWFudWZhY3R1cmVyIG5hbWUgb2YgdGhlIGRldmljZSB1bmRlciB0ZXN0LlxuICovXG5tZXRob2RzLmdldE1hbnVmYWN0dXJlciA9IGFzeW5jIGZ1bmN0aW9uIGdldE1hbnVmYWN0dXJlciAoKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLmdldERldmljZVByb3BlcnR5KCdyby5wcm9kdWN0Lm1hbnVmYWN0dXJlcicpO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgc2NyZWVuIHNpemUuXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBEZXZpY2Ugc2NyZWVuIHNpemUgYXMgc3RyaW5nIGluIGZvcm1hdCAnV3hIJyBvclxuICogICAgICAgICAgICAgICAgICBfbnVsbF8gaWYgaXQgY2Fubm90IGJlIGRldGVybWluZWQuXG4gKi9cbm1ldGhvZHMuZ2V0U2NyZWVuU2l6ZSA9IGFzeW5jIGZ1bmN0aW9uIGdldFNjcmVlblNpemUgKCkge1xuICBsZXQgc3Rkb3V0ID0gYXdhaXQgdGhpcy5zaGVsbChbJ3dtJywgJ3NpemUnXSk7XG4gIGxldCBzaXplID0gbmV3IFJlZ0V4cCgvUGh5c2ljYWwgc2l6ZTogKFteXFxyP1xcbl0rKSovZykuZXhlYyhzdGRvdXQpO1xuICBpZiAoc2l6ZSAmJiBzaXplLmxlbmd0aCA+PSAyKSB7XG4gICAgcmV0dXJuIHNpemVbMV0udHJpbSgpO1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgc2NyZWVuIGRlbnNpdHkgaW4gZHBpXG4gKlxuICogQHJldHVybiB7P251bWJlcn0gRGV2aWNlIHNjcmVlbiBkZW5zaXR5IGFzIGEgbnVtYmVyIG9yIF9udWxsXyBpZiBpdFxuICogICAgICAgICAgICAgICAgICBjYW5ub3QgYmUgZGV0ZXJtaW5lZFxuICovXG5tZXRob2RzLmdldFNjcmVlbkRlbnNpdHkgPSBhc3luYyBmdW5jdGlvbiBnZXRTY3JlZW5EZW5zaXR5ICgpIHtcbiAgbGV0IHN0ZG91dCA9IGF3YWl0IHRoaXMuc2hlbGwoWyd3bScsICdkZW5zaXR5J10pO1xuICBsZXQgZGVuc2l0eSA9IG5ldyBSZWdFeHAoL1BoeXNpY2FsIGRlbnNpdHk6IChbXlxccj9cXG5dKykqL2cpLmV4ZWMoc3Rkb3V0KTtcbiAgaWYgKGRlbnNpdHkgJiYgZGVuc2l0eS5sZW5ndGggPj0gMikge1xuICAgIGxldCBkZW5zaXR5TnVtYmVyID0gcGFyc2VJbnQoZGVuc2l0eVsxXS50cmltKCksIDEwKTtcbiAgICByZXR1cm4gaXNOYU4oZGVuc2l0eU51bWJlcikgPyBudWxsIDogZGVuc2l0eU51bWJlcjtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cbi8qKlxuICogU2V0dXAgSFRUUCBwcm94eSBpbiBkZXZpY2UgZ2xvYmFsIHNldHRpbmdzLlxuICogUmVhZCBodHRwczovL2FuZHJvaWQuZ29vZ2xlc291cmNlLmNvbS9wbGF0Zm9ybS9mcmFtZXdvcmtzL2Jhc2UvKy9hbmRyb2lkLTkuMC4wX3IyMS9jb3JlL2phdmEvYW5kcm9pZC9wcm92aWRlci9TZXR0aW5ncy5qYXZhIGZvciBlYWNoIHByb3BlcnR5XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3h5SG9zdCAtIFRoZSBob3N0IG5hbWUgb2YgdGhlIHByb3h5LlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBwcm94eVBvcnQgLSBUaGUgcG9ydCBudW1iZXIgdG8gYmUgc2V0LlxuICovXG5tZXRob2RzLnNldEh0dHBQcm94eSA9IGFzeW5jIGZ1bmN0aW9uIHNldEh0dHBQcm94eSAocHJveHlIb3N0LCBwcm94eVBvcnQpIHtcbiAgbGV0IHByb3h5ID0gYCR7cHJveHlIb3N0fToke3Byb3h5UG9ydH1gO1xuICBpZiAoXy5pc1VuZGVmaW5lZChwcm94eUhvc3QpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYWxsIHRvIHNldEh0dHBQcm94eSBtZXRob2Qgd2l0aCB1bmRlZmluZWQgcHJveHlfaG9zdDogJHtwcm94eX1gKTtcbiAgfVxuICBpZiAoXy5pc1VuZGVmaW5lZChwcm94eVBvcnQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYWxsIHRvIHNldEh0dHBQcm94eSBtZXRob2Qgd2l0aCB1bmRlZmluZWQgcHJveHlfcG9ydCAke3Byb3h5fWApO1xuICB9XG5cbiAgY29uc3QgaHR0cFByb3h5U2V0dGlucyA9IFtcbiAgICBbJ2h0dHBfcHJveHknLCBwcm94eV0sXG4gICAgWydnbG9iYWxfaHR0cF9wcm94eV9ob3N0JywgcHJveHlIb3N0XSxcbiAgICBbJ2dsb2JhbF9odHRwX3Byb3h5X3BvcnQnLCBwcm94eVBvcnRdXG4gIF07XG4gIGZvciAoY29uc3QgW3NldHRpbmdLZXksIHNldHRpbmdWYWx1ZV0gb2YgaHR0cFByb3h5U2V0dGlucykge1xuICAgIGF3YWl0IHRoaXMuc2V0U2V0dGluZygnZ2xvYmFsJywgc2V0dGluZ0tleSwgc2V0dGluZ1ZhbHVlKTtcbiAgfVxufTtcblxuLyoqXG4gKiBEZWxldGUgSFRUUCBwcm94eSBpbiBkZXZpY2UgZ2xvYmFsIHNldHRpbmdzLlxuICogUmVib290aW5nIHRoZSB0ZXN0IGRldmljZSBpcyBuZWNlc3NhcnkgdG8gYXBwbHkgdGhlIGNoYW5nZS5cbiAqL1xubWV0aG9kcy5kZWxldGVIdHRwUHJveHkgPSBhc3luYyBmdW5jdGlvbiBkZWxldGVIdHRwUHJveHkgKCkge1xuICBjb25zdCBodHRwUHJveHlTZXR0aW5zID0gW1xuICAgICdodHRwX3Byb3h5JyxcbiAgICAnZ2xvYmFsX2h0dHBfcHJveHlfaG9zdCcsXG4gICAgJ2dsb2JhbF9odHRwX3Byb3h5X3BvcnQnLFxuICAgICdnbG9iYWxfaHR0cF9wcm94eV9leGNsdXNpb25fbGlzdCcgLy8gYGdsb2JhbF9odHRwX3Byb3h5X2V4Y2x1c2lvbl9saXN0PWAgd2FzIGdlbmVyYXRlZCBieSBgc2V0dGluZ3MgZ2xvYmFsIGh0dG9fcHJveHkgeHh4eGBcbiAgXTtcbiAgZm9yIChjb25zdCBzZXR0aW5nIG9mIGh0dHBQcm94eVNldHRpbnMpIHtcbiAgICBhd2FpdCB0aGlzLnNoZWxsKFsnc2V0dGluZ3MnLCAnZGVsZXRlJywgJ2dsb2JhbCcsIHNldHRpbmddKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZXQgZGV2aWNlIHByb3BlcnR5LlxuICogW2FuZHJvaWQucHJvdmlkZXIuU2V0dGluZ3Nde0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL3Byb3ZpZGVyL1NldHRpbmdzLmh0bWx9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVzcGFjZSAtIG9uZSBvZiB7c3lzdGVtLCBzZWN1cmUsIGdsb2JhbH0sIGNhc2UtaW5zZW5zaXRpdmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2V0dGluZyAtIHByb3BlcnR5IG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHZhbHVlIC0gcHJvcGVydHkgdmFsdWUuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGNvbW1hbmQgb3V0cHV0LlxuICovXG5tZXRob2RzLnNldFNldHRpbmcgPSBhc3luYyBmdW5jdGlvbiBzZXRTZXR0aW5nIChuYW1lc3BhY2UsIHNldHRpbmcsIHZhbHVlKSB7XG4gIHJldHVybiBhd2FpdCB0aGlzLnNoZWxsKFsnc2V0dGluZ3MnLCAncHV0JywgbmFtZXNwYWNlLCBzZXR0aW5nLCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBHZXQgZGV2aWNlIHByb3BlcnR5LlxuICogW2FuZHJvaWQucHJvdmlkZXIuU2V0dGluZ3Nde0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL3Byb3ZpZGVyL1NldHRpbmdzLmh0bWx9XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVzcGFjZSAtIG9uZSBvZiB7c3lzdGVtLCBzZWN1cmUsIGdsb2JhbH0sIGNhc2UtaW5zZW5zaXRpdmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2V0dGluZyAtIHByb3BlcnR5IG5hbWUuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHByb3BlcnR5IHZhbHVlLlxuICovXG5tZXRob2RzLmdldFNldHRpbmcgPSBhc3luYyBmdW5jdGlvbiBnZXRTZXR0aW5nIChuYW1lc3BhY2UsIHNldHRpbmcpIHtcbiAgcmV0dXJuIGF3YWl0IHRoaXMuc2hlbGwoWydzZXR0aW5ncycsICdnZXQnLCBuYW1lc3BhY2UsIHNldHRpbmddKTtcbn07XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGBhZGIgYnVncmVwb3J0YCBjb21tYW5kIG91dHB1dC4gVGhpc1xuICogb3BlcmF0aW9uIG1heSB0YWtlIHVwIHRvIHNldmVyYWwgbWludXRlcy5cbiAqXG4gKiBAcGFyYW0gez9udW1iZXJ9IHRpbWVvdXQgWzEyMDAwMF0gLSBDb21tYW5kIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBDb21tYW5kIHN0ZG91dFxuICovXG5tZXRob2RzLmJ1Z3JlcG9ydCA9IGFzeW5jIGZ1bmN0aW9uIGJ1Z3JlcG9ydCAodGltZW91dCA9IDEyMDAwMCkge1xuICByZXR1cm4gYXdhaXQgdGhpcy5hZGJFeGVjKFsnYnVncmVwb3J0J10sIHt0aW1lb3V0fSk7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNjcmVlbnJlY29yZE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gdmlkZW9TaXplIC0gVGhlIGZvcm1hdCBpcyB3aWR0aHhoZWlnaHQuXG4gKiAgICAgICAgICAgICAgICAgIFRoZSBkZWZhdWx0IHZhbHVlIGlzIHRoZSBkZXZpY2UncyBuYXRpdmUgZGlzcGxheSByZXNvbHV0aW9uIChpZiBzdXBwb3J0ZWQpLFxuICogICAgICAgICAgICAgICAgICAxMjgweDcyMCBpZiBub3QuIEZvciBiZXN0IHJlc3VsdHMsXG4gKiAgICAgICAgICAgICAgICAgIHVzZSBhIHNpemUgc3VwcG9ydGVkIGJ5IHlvdXIgZGV2aWNlJ3MgQWR2YW5jZWQgVmlkZW8gQ29kaW5nIChBVkMpIGVuY29kZXIuXG4gKiAgICAgICAgICAgICAgICAgIEZvciBleGFtcGxlLCBcIjEyODB4NzIwXCJcbiAqIEBwcm9wZXJ0eSB7P2Jvb2xlYW59IGJ1Z1JlcG9ydCAtIFNldCBpdCB0byBgdHJ1ZWAgaW4gb3JkZXIgdG8gZGlzcGxheSBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9uIHRoZSB2aWRlbyBvdmVybGF5LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjaCBhcyBhIHRpbWVzdGFtcCwgdGhhdCBpcyBoZWxwZnVsIGluIHZpZGVvcyBjYXB0dXJlZCB0byBpbGx1c3RyYXRlIGJ1Z3MuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIG9wdGlvbiBpcyBvbmx5IHN1cHBvcnRlZCBzaW5jZSBBUEkgbGV2ZWwgMjcgKEFuZHJvaWQgUCkuXG4gKiBAcHJvcGVydHkgez9zdHJpbmd8bnVtYmVyfSB0aW1lTGltaXQgLSBUaGUgbWF4aW11bSByZWNvcmRpbmcgdGltZSwgaW4gc2Vjb25kcy5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBkZWZhdWx0IChhbmQgbWF4aW11bSkgdmFsdWUgaXMgMTgwICgzIG1pbnV0ZXMpLlxuICogQHByb3BlcnR5IHs/c3RyaW5nfG51bWJlcn0gYml0UmF0ZSAtIFRoZSB2aWRlbyBiaXQgcmF0ZSBmb3IgdGhlIHZpZGVvLCBpbiBtZWdhYml0cyBwZXIgc2Vjb25kLlxuICogICAgICAgICAgICAgICAgVGhlIGRlZmF1bHQgdmFsdWUgaXMgNC4gWW91IGNhbiBpbmNyZWFzZSB0aGUgYml0IHJhdGUgdG8gaW1wcm92ZSB2aWRlbyBxdWFsaXR5LFxuICogICAgICAgICAgICAgICAgYnV0IGRvaW5nIHNvIHJlc3VsdHMgaW4gbGFyZ2VyIG1vdmllIGZpbGVzLlxuICovXG5cbi8qKlxuICogSW5pdGlhdGUgc2NyZWVucmVjb3JkIHV0aWxpdHkgb24gdGhlIGRldmljZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXN0aW5hdGlvbiAtIEZ1bGwgcGF0aCB0byB0aGUgd3JpdGFibGUgbWVkaWEgZmlsZSBkZXN0aW5hdGlvblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb24gdGhlIGRldmljZSBmaWxlIHN5c3RlbS5cbiAqIEBwYXJhbSB7P1NjcmVlbnJlY29yZE9wdGlvbnN9IG9wdGlvbnMgW3t9XVxuICogQHJldHVybnMge1N1YlByb2Nlc3N9IHNjcmVlbnJlY29yZCBwcm9jZXNzLCB3aGljaCBjYW4gYmUgdGhlbiBjb250cm9sbGVkIGJ5IHRoZSBjbGllbnQgY29kZVxuICovXG5tZXRob2RzLnNjcmVlbnJlY29yZCA9IGZ1bmN0aW9uIHNjcmVlbnJlY29yZCAoZGVzdGluYXRpb24sIG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBjbWQgPSBbJ3NjcmVlbnJlY29yZCddO1xuICBjb25zdCB7XG4gICAgdmlkZW9TaXplLFxuICAgIGJpdFJhdGUsXG4gICAgdGltZUxpbWl0LFxuICAgIGJ1Z1JlcG9ydCxcbiAgfSA9IG9wdGlvbnM7XG4gIGlmICh1dGlsLmhhc1ZhbHVlKHZpZGVvU2l6ZSkpIHtcbiAgICBjbWQucHVzaCgnLS1zaXplJywgdmlkZW9TaXplKTtcbiAgfVxuICBpZiAodXRpbC5oYXNWYWx1ZSh0aW1lTGltaXQpKSB7XG4gICAgY21kLnB1c2goJy0tdGltZS1saW1pdCcsIHRpbWVMaW1pdCk7XG4gIH1cbiAgaWYgKHV0aWwuaGFzVmFsdWUoYml0UmF0ZSkpIHtcbiAgICBjbWQucHVzaCgnLS1iaXQtcmF0ZScsIGJpdFJhdGUpO1xuICB9XG4gIGlmIChidWdSZXBvcnQpIHtcbiAgICBjbWQucHVzaCgnLS1idWdyZXBvcnQnKTtcbiAgfVxuICBjbWQucHVzaChkZXN0aW5hdGlvbik7XG5cbiAgY29uc3QgZnVsbENtZCA9IFtcbiAgICAuLi50aGlzLmV4ZWN1dGFibGUuZGVmYXVsdEFyZ3MsXG4gICAgJ3NoZWxsJyxcbiAgICAuLi5jbWRcbiAgXTtcbiAgbG9nLmRlYnVnKGBCdWlsZGluZyBzY3JlZW5yZWNvcmQgcHJvY2VzcyB3aXRoIHRoZSBjb21tYW5kIGxpbmU6IGFkYiAke3V0aWwucXVvdGUoZnVsbENtZCl9YCk7XG4gIHJldHVybiBuZXcgU3ViUHJvY2Vzcyh0aGlzLmV4ZWN1dGFibGUucGF0aCwgZnVsbENtZCk7XG59O1xuXG4vKipcbiAqIEV4ZWN1dGVzIHRoZSBnaXZlbiBmdW5jdGlvbiB3aXRoIHRoZSBnaXZlbiBpbnB1dCBtZXRob2QgY29udGV4dFxuICogYW5kIHRoZW4gcmVzdG9yZXMgdGhlIElNRSB0byB0aGUgb3JpZ2luYWwgdmFsdWVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW1lIC0gVmFsaWQgSU1FIGlkZW50aWZpZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gRnVuY3Rpb24gdG8gZXhlY3V0ZVxuICogQHJldHVybnMgeyp9IFRoZSByZXN1bHQgb2YgdGhlIGdpdmVuIGZ1bmN0aW9uXG4gKi9cbm1ldGhvZHMucnVuSW5JbWVDb250ZXh0ID0gYXN5bmMgZnVuY3Rpb24gcnVuSW5JbWVDb250ZXh0IChpbWUsIGZuKSB7XG4gIGNvbnN0IG9yaWdpbmFsSW1lID0gYXdhaXQgdGhpcy5kZWZhdWx0SU1FKCk7XG4gIGlmIChvcmlnaW5hbEltZSA9PT0gaW1lKSB7XG4gICAgbG9nLmRlYnVnKGBUaGUgb3JpZ2luYWwgSU1FIGlzIHRoZSBzYW1lIGFzICcke2ltZX0nLiBUaGVyZSBpcyBubyBuZWVkIHRvIHJlc2V0IGl0YCk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgdGhpcy5lbmFibGVJTUUoaW1lKTtcbiAgICBhd2FpdCB0aGlzLnNldElNRShpbWUpO1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xNTk0M1xuICAgIGF3YWl0IEIuZGVsYXkoNTAwKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBmbigpO1xuICB9IGZpbmFsbHkge1xuICAgIGlmIChvcmlnaW5hbEltZSAhPT0gaW1lKSB7XG4gICAgICBhd2FpdCB0aGlzLnNldElNRShvcmlnaW5hbEltZSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEdldCB0eiBkYXRhYmFzZSB0aW1lIHpvbmUgZm9ybWF0dGVkIHRpbWV6b25lXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gVFogZGF0YWJhc2UgVGltZSBab25lcyBmb3JtYXRcbiAqXG4gKiBAdGhyb3dzIHtlcnJvcn0gSWYgYW55IGV4Y2VwdGlvbiBpcyByZXBvcnRlZCBieSBhZGIgc2hlbGwuXG4gKi9cbm1ldGhvZHMuZ2V0VGltZVpvbmUgPSBhc3luYyBmdW5jdGlvbiBnZXRUaW1lWm9uZSAoKSB7XG4gIGxvZy5kZWJ1ZygnR2V0dGluZyBjdXJyZW50IHRpbWV6b25lJyk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0RGV2aWNlUHJvcGVydHkoJ3BlcnNpc3Quc3lzLnRpbWV6b25lJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGdldHRpbmcgdGltZXpvbmUuIE9yaWdpbmFsIGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgZmVhdHVyZXMgc3VwcG9ydGVkIGJ5IHRoZSBkZXZpY2UgdW5kZXIgdGVzdFxuICpcbiAqIEByZXR1cm5zIHtBcnJheTxzdHJpbmc+fSB0aGUgbGlzdCBvZiBzdXBwb3J0ZWQgZmVhdHVyZSBuYW1lcyBvciBhbiBlbXB0eSBsaXN0LlxuICogQW4gZXhhbXBsZSBhZGIgY29tbWFuZCBvdXRwdXQ6XG4gKiBgYGBcbiAqIGNtZFxuICogbHNfdjJcbiAqIGZpeGVkX3B1c2hfbWtkaXJcbiAqIHNoZWxsX3YyXG4gKiBhYmJcbiAqIHN0YXRfdjJcbiAqIGFwZXhcbiAqIGFiYl9leGVjXG4gKiByZW1vdW50X3NoZWxsXG4gKiBmaXhlZF9wdXNoX3N5bWxpbmtfdGltZXN0YW1wXG4gKiBgYGBcbiAqIEB0aHJvd3Mge0Vycm9yfSBpZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgcmV0cmlldmluZyB0aGUgbGlzdFxuICovXG5tZXRob2RzLmxpc3RGZWF0dXJlcyA9IGFzeW5jIGZ1bmN0aW9uIGxpc3RGZWF0dXJlcyAoKSB7XG4gIHRoaXMuX21lbW9pemVkRmVhdHVyZXMgPSB0aGlzLl9tZW1vaXplZEZlYXR1cmVzXG4gICAgfHwgXy5tZW1vaXplKGFzeW5jICgpID0+IGF3YWl0IHRoaXMuYWRiRXhlYyhbJ2ZlYXR1cmVzJ10pLCAoKSA9PiB0aGlzLmN1ckRldmljZUlkKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuX21lbW9pemVkRmVhdHVyZXMoKSlcbiAgICAgIC5zcGxpdCgvXFxzKy8pXG4gICAgICAubWFwKCh4KSA9PiB4LnRyaW0oKSlcbiAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoXy5pbmNsdWRlcyhlLnN0ZGVyciwgJ3Vua25vd24gY29tbWFuZCcpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbn07XG5cbi8qKlxuICogQ2hlY2tzIHRoZSBzdGF0ZSBvZiBzdHJlYW1lZCBpbnN0YWxsIGZlYXR1cmUuXG4gKiBUaGlzIGZlYXR1cmUgYWxsb3dzIHRvIHNwZWVkIHVwIGFwayBpbnN0YWxsYXRpb25cbiAqIHNpbmNlIGl0IGRvZXMgbm90IHJlcXVpcmUgdGhlIG9yaWdpbmFsIGFwayB0byBiZSBwdXNoZWQgdG9cbiAqIHRoZSBkZXZpY2UgdW5kZXIgdGVzdCBmaXJzdCwgd2hpY2ggYWxzbyBzYXZlcyBzcGFjZS5cbiAqIEFsdGhvdWdoLCBpdCBpcyByZXF1aXJlZCB0aGF0IGJvdGggdGhlIGRldmljZSB1bmRlciB0ZXN0XG4gKiBhbmQgdGhlIGFkYiBzZXJ2ZXIgaGF2ZSB0aGUgbWVudGlvbmVkIGZ1bmN0aW9uYWxpdHkuXG4gKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2Fvc3AtbWlycm9yL3BsYXRmb3JtX3N5c3RlbV9jb3JlL2Jsb2IvbWFzdGVyL2FkYi9jbGllbnQvYWRiX2luc3RhbGwuY3BwXG4gKiBmb3IgbW9yZSBkZXRhaWxzXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZmVhdHVyZSBpcyBzdXBwb3J0ZWQgYnkgYm90aCBhZGIgYW5kIHRoZVxuICogZGV2aWNlIHVuZGVyIHRlc3RcbiAqL1xubWV0aG9kcy5pc1N0cmVhbWVkSW5zdGFsbFN1cHBvcnRlZCA9IGFzeW5jIGZ1bmN0aW9uIGlzU3RyZWFtZWRJbnN0YWxsU3VwcG9ydGVkICgpIHtcbiAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcyk7XG4gIHByb3RvLl9oZWxwT3V0cHV0ID0gcHJvdG8uX2hlbHBPdXRwdXQgfHwgYXdhaXQgdGhpcy5hZGJFeGVjKFsnaGVscCddKTtcbiAgcmV0dXJuIHByb3RvLl9oZWxwT3V0cHV0LmluY2x1ZGVzKCctLXN0cmVhbWluZycpXG4gICAgJiYgKGF3YWl0IHRoaXMubGlzdEZlYXR1cmVzKCkpLmluY2x1ZGVzKCdjbWQnKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgaW5jcmVtZW50YWwgaW5zdGFsbCBmZWF0dXJlIGlzIHN1cHBvcnRlZCBieSBBREIuXG4gKiBSZWFkIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3ByZXZpZXcvZmVhdHVyZXMjaW5jcmVtZW50YWxcbiAqIGZvciBtb3JlIGRldGFpbHMgb24gaXQuXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZmVhdHVyZSBpcyBzdXBwb3J0ZWQgYnkgYm90aCBhZGIgYW5kIHRoZVxuICogZGV2aWNlIHVuZGVyIHRlc3RcbiAqL1xubWV0aG9kcy5pc0luY3JlbWVudGFsSW5zdGFsbFN1cHBvcnRlZCA9IGFzeW5jIGZ1bmN0aW9uIGlzSW5jcmVtZW50YWxJbnN0YWxsU3VwcG9ydGVkICgpIHtcbiAgY29uc3Qge2JpbmFyeX0gPSBhd2FpdCB0aGlzLmdldFZlcnNpb24oKTtcbiAgaWYgKCFiaW5hcnkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHV0aWwuY29tcGFyZVZlcnNpb25zKGJpbmFyeS52ZXJzaW9uLCAnPj0nLCAnMzAuMC4xJylcbiAgICAmJiAoYXdhaXQgdGhpcy5saXN0RmVhdHVyZXMoKSkuaW5jbHVkZXMoJ2FiYl9leGVjJyk7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBwYWNrYWdlcyBmcm9tIERvemUgd2hpdGVsaXN0IG9uIEFuZHJvaWQgOCtcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nPn0gVGhlIGxpc3Qgb2Ygd2hpdGVsaXN0ZWQgcGFja2FnZXMuIEFuIGV4YW1wbGUgb3V0cHV0OlxuICogc3lzdGVtLGNvbS5hbmRyb2lkLnNoZWxsLDIwMDBcbiAqIHN5c3RlbSxjb20uZ29vZ2xlLmFuZHJvaWQuY2VsbGJyb2FkY2FzdHJlY2VpdmVyLDEwMTQzXG4gKiB1c2VyLGlvLmFwcGl1bS5zZXR0aW5ncywxMDE1N1xuICovXG5tZXRob2RzLmdldERldmljZUlkbGVXaGl0ZWxpc3QgPSBhc3luYyBmdW5jdGlvbiBnZXREZXZpY2VJZGxlV2hpdGVsaXN0ICgpIHtcbiAgaWYgKGF3YWl0IHRoaXMuZ2V0QXBpTGV2ZWwoKSA8IDIzKSB7XG4gICAgLy8gRG96ZSBtb2RlIGhhcyBvbmx5IGJlZW4gYWRkZWQgc2luY2UgQW5kcm9pZCA2XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgbG9nLmluZm8oJ0xpc3RpbmcgcGFja2FnZXMgaW4gRG96ZSB3aGl0ZWxpc3QnKTtcbiAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgdGhpcy5zaGVsbChbJ2R1bXBzeXMnLCAnZGV2aWNlaWRsZScsICd3aGl0ZWxpc3QnXSk7XG4gIHJldHVybiBfLnRyaW0ob3V0cHV0KS5zcGxpdCgvXFxuLylcbiAgICAubWFwKChsaW5lKSA9PiBfLnRyaW0obGluZSkpXG4gICAgLmZpbHRlcihCb29sZWFuKTtcbn07XG5cbi8qKlxuICogQWRkcyBhbiBleGlzdGluZyBwYWNrYWdlKHMpIGludG8gdGhlIERvemUgd2hpdGVsaXN0IG9uIEFuZHJvaWQgOCtcbiAqXG4gKiBAcGFyYW0gIHsuLi5zdHJpbmd9IHBhY2thZ2VzIE9uZSBvciBtb3JlIHBhY2thZ2VzIHRvIGFkZC4gSWYgdGhlIHBhY2thZ2VcbiAqIGFscmVhZHkgZXhpc3RzIGluIHRoZSB3aGl0ZWxpc3QgdGhlbiBpdCBpcyBvbmx5IGdvaW5nIHRvIGJlIGFkZGVkIG9uY2UuXG4gKiBJZiB0aGUgcGFja2FnZSB3aXRoIHRoZSBnaXZlbiBuYW1lIGlzIG5vdCBpbnN0YWxsZWQvbm90IGtub3duIHRoZW4gYW4gZXJyb3JcbiAqIHdpbGwgYmUgdGhyb3duLlxuICogQHJldHVybnMge0Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgY29tbWFuZCB0byBhZGQgcGFja2FnZShzKSBoYXMgYmVlbiBleGVjdXRlZFxuICovXG5tZXRob2RzLmFkZFRvRGV2aWNlSWRsZVdoaXRlbGlzdCA9IGFzeW5jIGZ1bmN0aW9uIGFkZFRvRGV2aWNlSWRsZVdoaXRlbGlzdCAoLi4ucGFja2FnZXMpIHtcbiAgaWYgKF8uaXNFbXB0eShwYWNrYWdlcykgfHwgYXdhaXQgdGhpcy5nZXRBcGlMZXZlbCgpIDwgMjMpIHtcbiAgICAvLyBEb3plIG1vZGUgaGFzIG9ubHkgYmVlbiBhZGRlZCBzaW5jZSBBbmRyb2lkIDZcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsb2cuaW5mbyhgQWRkaW5nICR7dXRpbC5wbHVyYWxpemUoJ3BhY2thZ2UnLCBwYWNrYWdlcy5sZW5ndGgpfSAke0pTT04uc3RyaW5naWZ5KHBhY2thZ2VzKX0gdG8gRG96ZSB3aGl0ZWxpc3RgKTtcbiAgYXdhaXQgdGhpcy5zaGVsbENodW5rcygocGtnKSA9PiBbJ2R1bXBzeXMnLCAnZGV2aWNlaWRsZScsICd3aGl0ZWxpc3QnLCBgKyR7cGtnfWBdLCBwYWNrYWdlcyk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgbWV0aG9kcztcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFJQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQSxNQUFNQSx1QkFBdUIsR0FBRyxJQUFoQztBQUNBLE1BQU1DLHlCQUF5QixHQUFHLG1DQUFsQztBQUNBLE1BQU1DLG1CQUFtQixHQUFHLENBQzFCRCx5QkFEMEIsRUFFMUIscUJBRjBCLENBQTVCO0FBSUEsTUFBTUUscUJBQXFCLEdBQUcsRUFBOUI7QUFDQSxNQUFNQyxzQkFBc0IsR0FBRyxDQUM3Qiw4QkFENkIsRUFFN0IsMEJBRjZCLEVBRzdCLG1CQUg2QixDQUEvQjtBQUtBLE1BQU1DLGdCQUFnQixHQUFHLEtBQXpCO0FBQ0EsTUFBTUMseUJBQXlCLEdBQUcsTUFBbEM7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxJQUFJQyxNQUFKLENBQVksVUFBU0gsZ0JBQWlCLFdBQVVDLHlCQUEwQixTQUExRSxFQUFvRixHQUFwRixDQUF6QjtBQUVBLE1BQU1HLHdCQUF3QixHQUFHLG1CQUFqQztBQUVBLE1BQU1DLE9BQU8sR0FBRyxFQUFoQjs7QUFnQkFBLE9BQU8sQ0FBQ0MsV0FBUixHQUFzQixlQUFlQSxXQUFmLENBQTRCQyxjQUE1QixFQUE0Q0MsSUFBNUMsRUFBa0Q7RUFDdEUsTUFBTUMsUUFBUSxHQUFHLEVBQWpCO0VBQ0EsSUFBSUMsUUFBUSxHQUFHLEVBQWY7O0VBQ0EsS0FBSyxNQUFNQyxHQUFYLElBQWtCSCxJQUFsQixFQUF3QjtJQUN0QixNQUFNSSxPQUFPLEdBQUdMLGNBQWMsQ0FBQ0ksR0FBRCxDQUE5Qjs7SUFDQSxJQUFJLENBQUNFLGVBQUEsQ0FBRUMs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