appium-uiautomator2-driver 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +241 -25
  2. package/build/index.js +1 -4
  3. package/build/lib/commands/actions.js +3 -12
  4. package/build/lib/commands/actions.js.map +1 -0
  5. package/build/lib/commands/alert.js +3 -9
  6. package/build/lib/commands/alert.js.map +1 -0
  7. package/build/lib/commands/battery.js +3 -5
  8. package/build/lib/commands/battery.js.map +1 -0
  9. package/build/lib/commands/element.js +3 -36
  10. package/build/lib/commands/element.js.map +1 -0
  11. package/build/lib/commands/find.js +2 -9
  12. package/build/lib/commands/find.js.map +1 -0
  13. package/build/lib/commands/general.js +5 -36
  14. package/build/lib/commands/general.js.map +1 -0
  15. package/build/lib/commands/gestures.js +1 -15
  16. package/build/lib/commands/gestures.js.map +1 -0
  17. package/build/lib/commands/index.js +3 -15
  18. package/build/lib/commands/index.js.map +1 -0
  19. package/build/lib/commands/screenshot.js +1 -8
  20. package/build/lib/commands/screenshot.js.map +1 -0
  21. package/build/lib/commands/touch.js +2 -8
  22. package/build/lib/commands/touch.js.map +1 -0
  23. package/build/lib/commands/viewport.js +3 -9
  24. package/build/lib/commands/viewport.js.map +1 -0
  25. package/build/lib/css-converter.js +1 -42
  26. package/build/lib/css-converter.js.map +1 -0
  27. package/build/lib/desired-caps.js +1 -4
  28. package/build/lib/desired-caps.js.map +1 -0
  29. package/build/lib/driver.js +24 -102
  30. package/build/lib/driver.js.map +1 -0
  31. package/build/lib/extensions.js +1 -3
  32. package/build/lib/extensions.js.map +1 -0
  33. package/build/lib/helpers.js +1 -15
  34. package/build/lib/helpers.js.map +1 -0
  35. package/build/lib/logger.js +1 -5
  36. package/build/lib/logger.js.map +1 -0
  37. package/build/lib/uiautomator2.js +1 -70
  38. package/build/lib/uiautomator2.js.map +1 -0
  39. package/npm-shrinkwrap.json +402 -309
  40. package/package.json +3 -3
@@ -1,32 +1,20 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.default = exports.UiAutomator2Server = exports.SERVER_TEST_PACKAGE_ID = exports.SERVER_PACKAGE_ID = exports.INSTRUMENTATION_TARGET = void 0;
9
-
10
8
  require("source-map-support/register");
11
-
12
9
  var _lodash = _interopRequireDefault(require("lodash"));
13
-
14
10
  var _driver = require("appium/driver");
15
-
16
11
  var _asyncbox = require("asyncbox");
17
-
18
12
  var _appiumUiautomator2Server = require("appium-uiautomator2-server");
19
-
20
13
  var _support = require("appium/support");
21
-
22
14
  var _bluebird = _interopRequireDefault(require("bluebird"));
23
-
24
15
  var _helpers = _interopRequireDefault(require("./helpers"));
25
-
26
16
  var _axios = _interopRequireDefault(require("axios"));
27
-
28
17
  var _path = _interopRequireDefault(require("path"));
29
-
30
18
  const REQD_PARAMS = ['adb', 'tmpDir', 'host', 'systemPort', 'devicePort', 'disableWindowAnimation'];
31
19
  const SERVER_LAUNCH_TIMEOUT = 30000;
32
20
  const SERVER_INSTALL_RETRIES = 20;
@@ -37,30 +25,23 @@ const SERVER_TEST_PACKAGE_ID = `${SERVER_PACKAGE_ID}.test`;
37
25
  exports.SERVER_TEST_PACKAGE_ID = SERVER_TEST_PACKAGE_ID;
38
26
  const INSTRUMENTATION_TARGET = `${SERVER_TEST_PACKAGE_ID}/androidx.test.runner.AndroidJUnitRunner`;
39
27
  exports.INSTRUMENTATION_TARGET = INSTRUMENTATION_TARGET;
40
-
41
28
  const instrumentationLogger = _support.logger.getLogger('Instrumentation');
42
-
43
29
  class UIA2Proxy extends _driver.JWProxy {
44
30
  async proxyCommand(url, method, body = null) {
45
31
  if (this.didInstrumentationExit) {
46
32
  throw new _driver.errors.InvalidContextError(`'${method} ${url}' cannot be proxied to UiAutomator2 server because ` + 'the instrumentation process is not running (probably crashed). ' + 'Check the server log and/or the logcat output for more details');
47
33
  }
48
-
49
34
  return await super.proxyCommand(url, method, body);
50
35
  }
51
-
52
36
  }
53
-
54
37
  class UiAutomator2Server {
55
38
  constructor(log, opts = {}) {
56
39
  for (let req of REQD_PARAMS) {
57
40
  if (!opts || !_support.util.hasValue(opts[req])) {
58
41
  throw new Error(`Option '${req}' is required!`);
59
42
  }
60
-
61
43
  this[req] = opts[req];
62
44
  }
63
-
64
45
  this.log = log;
65
46
  this.disableSuppressAccessibilityService = opts.disableSuppressAccessibilityService;
66
47
  const proxyOpts = {
@@ -69,11 +50,9 @@ class UiAutomator2Server {
69
50
  port: this.systemPort,
70
51
  keepAlive: true
71
52
  };
72
-
73
53
  if (opts.readTimeout && opts.readTimeout > 0) {
74
54
  proxyOpts.timeout = opts.readTimeout;
75
55
  }
76
-
77
56
  this.jwproxy = new UIA2Proxy(proxyOpts);
78
57
  this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);
79
58
  this.proxyCommand = this.jwproxy.command.bind(this.jwproxy);
@@ -82,7 +61,6 @@ class UiAutomator2Server {
82
61
 
83
62
  async installServerApk(installTimeout = SERVER_INSTALL_RETRIES * 1000) {
84
63
  const tmpRoot = await _support.tempDir.openDir();
85
-
86
64
  const packageInfosMapper = async ({
87
65
  appPath,
88
66
  appId
@@ -93,18 +71,14 @@ class UiAutomator2Server {
93
71
  appId
94
72
  };
95
73
  }
96
-
97
74
  this.log.info(`Server package at '${appPath}' is not writeable. ` + `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` + `Consider making this file writeable manually in order to improve the performance of session startup.`);
98
-
99
75
  const dstPath = _path.default.resolve(tmpRoot, _path.default.basename(appPath));
100
-
101
76
  await _support.fs.copyFile(appPath, dstPath);
102
77
  return {
103
78
  appPath: dstPath,
104
79
  appId
105
80
  };
106
81
  };
107
-
108
82
  try {
109
83
  const packagesInfo = await _bluebird.default.all(_bluebird.default.map([{
110
84
  appPath: _appiumUiautomator2Server.SERVER_APK_PATH,
@@ -115,7 +89,6 @@ class UiAutomator2Server {
115
89
  }], packageInfosMapper));
116
90
  let shouldUninstallServerPackages = false;
117
91
  let shouldInstallServerPackages = false;
118
-
119
92
  for (const {
120
93
  appId,
121
94
  appPath
@@ -128,33 +101,25 @@ class UiAutomator2Server {
128
101
  shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;
129
102
  shouldInstallServerPackages = true;
130
103
  }
131
-
132
104
  if (!isAppInstalled) {
133
105
  shouldInstallServerPackages = true;
134
106
  }
135
-
136
107
  continue;
137
108
  }
138
-
139
109
  const appState = await this.adb.getApplicationInstallState(appPath, appId);
140
110
  this.log.debug(`${appId} installation state: ${appState}`);
141
-
142
111
  if (await this.adb.checkApkCert(appPath, appId)) {
143
112
  shouldUninstallServerPackages = shouldUninstallServerPackages || [this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED, this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED].includes(appState);
144
113
  } else {
145
114
  await _helpers.default.signApp(this.adb, appPath);
146
115
  shouldUninstallServerPackages = shouldUninstallServerPackages || ![this.adb.APP_INSTALL_STATE.NOT_INSTALLED].includes(appState);
147
116
  }
148
-
149
117
  shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [this.adb.APP_INSTALL_STATE.NOT_INSTALLED].includes(appState);
150
118
  }
151
-
152
119
  this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);
153
-
154
120
  if (shouldInstallServerPackages && shouldUninstallServerPackages) {
155
121
  this.log.info('Full packages reinstall is going to be performed');
156
122
  }
157
-
158
123
  for (const {
159
124
  appId,
160
125
  appPath
@@ -166,7 +131,6 @@ class UiAutomator2Server {
166
131
  this.log.warn(`Error uninstalling '${appId}': ${err.message}`);
167
132
  }
168
133
  }
169
-
170
134
  if (shouldInstallServerPackages) {
171
135
  await this.adb.install(appPath, {
172
136
  noIncremental: true,
@@ -179,28 +143,23 @@ class UiAutomator2Server {
179
143
  } finally {
180
144
  await _support.fs.rimraf(tmpRoot);
181
145
  }
182
-
183
146
  await this.verifyServicesAvailability();
184
147
  }
185
-
186
148
  async verifyServicesAvailability() {
187
149
  this.log.debug(`Waiting up to ${SERVICES_LAUNCH_TIMEOUT}ms for services to be available`);
188
150
  let isPmServiceAvailable = false;
189
151
  let pmOutput = '';
190
152
  let pmError = null;
191
-
192
153
  try {
193
154
  await (0, _asyncbox.waitForCondition)(async () => {
194
155
  if (!isPmServiceAvailable) {
195
156
  pmError = null;
196
157
  pmOutput = '';
197
-
198
158
  try {
199
159
  pmOutput = await this.adb.shell(['pm', 'list', 'instrumentation']);
200
160
  } catch (e) {
201
161
  pmError = e;
202
162
  }
203
-
204
163
  if (pmOutput.includes('Could not access the Package Manager')) {
205
164
  pmError = new Error(`Problem running Package Manager: ${pmOutput}`);
206
165
  pmOutput = '';
@@ -212,7 +171,6 @@ class UiAutomator2Server {
212
171
  pmError = new Error('The instrumentation target is not listed by Package Manager');
213
172
  }
214
173
  }
215
-
216
174
  return isPmServiceAvailable;
217
175
  }, {
218
176
  waitMs: SERVICES_LAUNCH_TIMEOUT,
@@ -220,38 +178,31 @@ class UiAutomator2Server {
220
178
  });
221
179
  } catch (err) {
222
180
  this.log.error(`Unable to find instrumentation target '${INSTRUMENTATION_TARGET}': ${(pmError || {}).message}`);
223
-
224
181
  if (pmOutput) {
225
182
  this.log.debug('Available targets:');
226
-
227
183
  for (const line of pmOutput.split('\n')) {
228
184
  this.log.debug(` ${line.replace('instrumentation:', '')}`);
229
185
  }
230
186
  }
231
187
  }
232
188
  }
233
-
234
189
  async startSession(caps) {
235
190
  await this.cleanupAutomationLeftovers();
236
-
237
191
  if (caps.skipServerInstallation) {
238
192
  this.log.info(`'skipServerInstallation' is set. Attempting to use UIAutomator2 server from the device`);
239
193
  } else {
240
194
  this.log.info(`Starting UIAutomator2 server ${_appiumUiautomator2Server.version}`);
241
195
  this.log.info(`Using UIAutomator2 server from '${_appiumUiautomator2Server.SERVER_APK_PATH}' and test from '${_appiumUiautomator2Server.TEST_APK_PATH}'`);
242
196
  }
243
-
244
197
  const timeout = caps.uiautomator2ServerLaunchTimeout || SERVER_LAUNCH_TIMEOUT;
245
198
  const timer = new _support.timing.Timer().start();
246
199
  let retries = 0;
247
200
  const maxRetries = 2;
248
201
  const delayBetweenRetries = 3000;
249
-
250
202
  while (retries < maxRetries) {
251
203
  this.log.info(`Waiting up to ${timeout}ms for UiAutomator2 to be online...`);
252
204
  this.jwproxy.didInstrumentationExit = false;
253
205
  await this.startInstrumentationProcess();
254
-
255
206
  if (!this.jwproxy.didInstrumentationExit) {
256
207
  try {
257
208
  await (0, _asyncbox.waitForCondition)(async () => {
@@ -269,22 +220,17 @@ class UiAutomator2Server {
269
220
  this.log.errorAndThrow(`The instrumentation process cannot be initialized within ${timeout}ms timeout. ` + 'Make sure the application under test does not crash and investigate the logcat output. ' + `You could also try to increase the value of 'uiautomator2ServerLaunchTimeout' capability`);
270
221
  }
271
222
  }
272
-
273
223
  if (!this.jwproxy.didInstrumentationExit) {
274
224
  break;
275
225
  }
276
-
277
226
  retries++;
278
-
279
227
  if (retries >= maxRetries) {
280
228
  this.log.errorAndThrow('The instrumentation process cannot be initialized. ' + 'Make sure the application under test does not crash and investigate the logcat output.');
281
229
  }
282
-
283
230
  this.log.warn(`The instrumentation process has been unexpectedly terminated. ` + `Retrying UiAutomator2 startup (#${retries} of ${maxRetries - 1})`);
284
231
  await this.cleanupAutomationLeftovers(true);
285
232
  await _bluebird.default.delay(delayBetweenRetries);
286
233
  }
287
-
288
234
  this.log.debug(`The initialization of the instrumentation process took ` + `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
289
235
  await this.jwproxy.command('/session', 'POST', {
290
236
  capabilities: {
@@ -293,24 +239,19 @@ class UiAutomator2Server {
293
239
  }
294
240
  });
295
241
  }
296
-
297
242
  async startInstrumentationProcess() {
298
243
  const cmd = ['am', 'instrument', '-w'];
299
-
300
244
  if (this.disableWindowAnimation) {
301
245
  cmd.push('--no-window-animation');
302
246
  }
303
-
304
247
  if (_lodash.default.isBoolean(this.disableSuppressAccessibilityService)) {
305
248
  cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);
306
249
  }
307
-
308
250
  cmd.push('-e', 'disableAnalytics', true);
309
251
  cmd.push(INSTRUMENTATION_TARGET);
310
252
  const instrumentationProcess = this.adb.createSubProcess(['shell', ...cmd]);
311
253
  instrumentationProcess.on('output', (stdout, stderr) => {
312
254
  const output = _lodash.default.trim(stdout || stderr);
313
-
314
255
  if (output) {
315
256
  instrumentationLogger.debug(output);
316
257
  }
@@ -321,20 +262,16 @@ class UiAutomator2Server {
321
262
  });
322
263
  await instrumentationProcess.start(0);
323
264
  }
324
-
325
265
  async deleteSession() {
326
266
  this.log.debug('Deleting UiAutomator2 server session');
327
-
328
267
  try {
329
268
  await this.jwproxy.command('/', 'DELETE');
330
269
  } catch (err) {
331
270
  this.log.warn(`Did not get confirmation UiAutomator2 deleteSession worked; ` + `Error was: ${err}`);
332
271
  }
333
272
  }
334
-
335
273
  async cleanupAutomationLeftovers(strictCleanup = false) {
336
274
  this.log.debug(`Performing ${strictCleanup ? 'strict' : 'shallow'} cleanup of automation leftovers`);
337
-
338
275
  try {
339
276
  const {
340
277
  value
@@ -345,7 +282,6 @@ class UiAutomator2Server {
345
282
  const activeSessionIds = value.map(({
346
283
  id
347
284
  }) => id).filter(Boolean);
348
-
349
285
  if (activeSessionIds.length) {
350
286
  this.log.debug(`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`);
351
287
  this.log.debug(`Cleaning up ${_support.util.pluralize('obsolete session', activeSessionIds.length, true)}`);
@@ -357,23 +293,18 @@ class UiAutomator2Server {
357
293
  } catch (e) {
358
294
  this.log.debug(`No obsolete sessions have been detected (${e.message})`);
359
295
  }
360
-
361
296
  try {
362
297
  await this.adb.forceStop(SERVER_TEST_PACKAGE_ID);
363
298
  } catch (ignore) {}
364
-
365
299
  if (!strictCleanup) {
366
300
  return;
367
301
  }
368
-
369
302
  try {
370
303
  await this.adb.killProcessesByName('uiautomator');
371
304
  } catch (ignore) {}
372
305
  }
373
-
374
306
  }
375
-
376
307
  exports.UiAutomator2Server = UiAutomator2Server;
377
308
  var _default = UiAutomator2Server;
378
309
  exports.default = _default;
379
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSRVFEX1BBUkFNUyIsIlNFUlZFUl9MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9JTlNUQUxMX1JFVFJJRVMiLCJTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9QQUNLQUdFX0lEIiwiU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCIsIklOU1RSVU1FTlRBVElPTl9UQVJHRVQiLCJpbnN0cnVtZW50YXRpb25Mb2dnZXIiLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJVSUEyUHJveHkiLCJKV1Byb3h5IiwicHJveHlDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImRpZEluc3RydW1lbnRhdGlvbkV4aXQiLCJlcnJvcnMiLCJJbnZhbGlkQ29udGV4dEVycm9yIiwiVWlBdXRvbWF0b3IyU2VydmVyIiwiY29uc3RydWN0b3IiLCJsb2ciLCJvcHRzIiwicmVxIiwidXRpbCIsImhhc1ZhbHVlIiwiRXJyb3IiLCJkaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSIsInByb3h5T3B0cyIsInNlcnZlciIsImhvc3QiLCJwb3J0Iiwic3lzdGVtUG9ydCIsImtlZXBBbGl2ZSIsInJlYWRUaW1lb3V0IiwidGltZW91dCIsImp3cHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJjb21tYW5kIiwiaW5zdGFsbFNlcnZlckFwayIsImluc3RhbGxUaW1lb3V0IiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwicGFja2FnZUluZm9zTWFwcGVyIiwiYXBwUGF0aCIsImFwcElkIiwiaGVscGVycyIsImlzV3JpdGVhYmxlIiwiaW5mbyIsImRzdFBhdGgiLCJwYXRoIiwicmVzb2x2ZSIsImJhc2VuYW1lIiwiZnMiLCJjb3B5RmlsZSIsInBhY2thZ2VzSW5mbyIsIkIiLCJhbGwiLCJtYXAiLCJhcGtQYXRoIiwidGVzdEFwa1BhdGgiLCJzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsInNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsImlzQXBwSW5zdGFsbGVkIiwiYWRiIiwiY2hlY2tBcGtDZXJ0Iiwic2lnbkFwcCIsImFwcFN0YXRlIiwiZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUiLCJkZWJ1ZyIsIkFQUF9JTlNUQUxMX1NUQVRFIiwiT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQiLCJORVdFUl9WRVJTSU9OX0lOU1RBTExFRCIsImluY2x1ZGVzIiwiTk9UX0lOU1RBTExFRCIsInVuaW5zdGFsbEFwayIsImVyciIsIndhcm4iLCJtZXNzYWdlIiwiaW5zdGFsbCIsIm5vSW5jcmVtZW50YWwiLCJyZXBsYWNlIiwidGltZW91dENhcE5hbWUiLCJyaW1yYWYiLCJ2ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSIsImlzUG1TZXJ2aWNlQXZhaWxhYmxlIiwicG1PdXRwdXQiLCJwbUVycm9yIiwid2FpdEZvckNvbmRpdGlvbiIsInNoZWxsIiwiZSIsIndhaXRNcyIsImludGVydmFsTXMiLCJlcnJvciIsImxpbmUiLCJzcGxpdCIsInN0YXJ0U2Vzc2lvbiIsImNhcHMiLCJjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyIsInNraXBTZXJ2ZXJJbnN0YWxsYXRpb24iLCJzZXJ2ZXJWZXJzaW9uIiwidWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJzdGFydCIsInJldHJpZXMiLCJtYXhSZXRyaWVzIiwiZGVsYXlCZXR3ZWVuUmV0cmllcyIsInN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImVycm9yQW5kVGhyb3ciLCJkZWxheSIsImdldER1cmF0aW9uIiwiYXNNaWxsaVNlY29uZHMiLCJ0b0ZpeGVkIiwiY2FwYWJpbGl0aWVzIiwiZmlyc3RNYXRjaCIsImFsd2F5c01hdGNoIiwiY21kIiwiZGlzYWJsZVdpbmRvd0FuaW1hdGlvbiIsInB1c2giLCJfIiwiaXNCb29sZWFuIiwiaW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImNyZWF0ZVN1YlByb2Nlc3MiLCJvbiIsInN0ZG91dCIsInN0ZGVyciIsIm91dHB1dCIsInRyaW0iLCJjb2RlIiwiZGVsZXRlU2Vzc2lvbiIsInN0cmljdENsZWFudXAiLCJ2YWx1ZSIsImF4aW9zIiwiZGF0YSIsImFjdGl2ZVNlc3Npb25JZHMiLCJpZCIsImZpbHRlciIsIkJvb2xlYW4iLCJsZW5ndGgiLCJKU09OIiwic3RyaW5naWZ5IiwicGx1cmFsaXplIiwiZGVsZXRlIiwiZm9yY2VTdG9wIiwiaWdub3JlIiwia2lsbFByb2Nlc3Nlc0J5TmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91aWF1dG9tYXRvcjIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEpXUHJveHksIGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7XG4gIFNFUlZFUl9BUEtfUEFUSCBhcyBhcGtQYXRoLFxuICBURVNUX0FQS19QQVRIIGFzIHRlc3RBcGtQYXRoLFxuICB2ZXJzaW9uIGFzIHNlcnZlclZlcnNpb25cbn0gZnJvbSAnYXBwaXVtLXVpYXV0b21hdG9yMi1zZXJ2ZXInO1xuaW1wb3J0IHtcbiAgdXRpbCwgbG9nZ2VyLCB0ZW1wRGlyLCBmcywgdGltaW5nXG59IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IFJFUURfUEFSQU1TID0gWydhZGInLCAndG1wRGlyJywgJ2hvc3QnLCAnc3lzdGVtUG9ydCcsICdkZXZpY2VQb3J0JywgJ2Rpc2FibGVXaW5kb3dBbmltYXRpb24nXTtcbmNvbnN0IFNFUlZFUl9MQVVOQ0hfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgU0VSVkVSX0lOU1RBTExfUkVUUklFUyA9IDIwO1xuY29uc3QgU0VSVklDRVNfTEFVTkNIX1RJTUVPVVQgPSAzMDAwMDtcbmNvbnN0IFNFUlZFUl9QQUNLQUdFX0lEID0gJ2lvLmFwcGl1bS51aWF1dG9tYXRvcjIuc2VydmVyJztcbmNvbnN0IFNFUlZFUl9URVNUX1BBQ0tBR0VfSUQgPSBgJHtTRVJWRVJfUEFDS0FHRV9JRH0udGVzdGA7XG5jb25zdCBJTlNUUlVNRU5UQVRJT05fVEFSR0VUID0gYCR7U0VSVkVSX1RFU1RfUEFDS0FHRV9JRH0vYW5kcm9pZHgudGVzdC5ydW5uZXIuQW5kcm9pZEpVbml0UnVubmVyYDtcbmNvbnN0IGluc3RydW1lbnRhdGlvbkxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIoJ0luc3RydW1lbnRhdGlvbicpO1xuXG5jbGFzcyBVSUEyUHJveHkgZXh0ZW5kcyBKV1Byb3h5IHtcbiAgYXN5bmMgcHJveHlDb21tYW5kICh1cmwsIG1ldGhvZCwgYm9keSA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRDb250ZXh0RXJyb3IoXG4gICAgICAgIGAnJHttZXRob2R9ICR7dXJsfScgY2Fubm90IGJlIHByb3hpZWQgdG8gVWlBdXRvbWF0b3IyIHNlcnZlciBiZWNhdXNlIGAgK1xuICAgICAgICAndGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGlzIG5vdCBydW5uaW5nIChwcm9iYWJseSBjcmFzaGVkKS4gJyArXG4gICAgICAgICdDaGVjayB0aGUgc2VydmVyIGxvZyBhbmQvb3IgdGhlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscycpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgc3VwZXIucHJveHlDb21tYW5kKHVybCwgbWV0aG9kLCBib2R5KTtcbiAgfVxufVxuXG5jbGFzcyBVaUF1dG9tYXRvcjJTZXJ2ZXIge1xuICBjb25zdHJ1Y3RvciAobG9nLCBvcHRzID0ge30pIHtcbiAgICBmb3IgKGxldCByZXEgb2YgUkVRRF9QQVJBTVMpIHtcbiAgICAgIGlmICghb3B0cyB8fCAhdXRpbC5oYXNWYWx1ZShvcHRzW3JlcV0pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgT3B0aW9uICcke3JlcX0nIGlzIHJlcXVpcmVkIWApO1xuICAgICAgfVxuICAgICAgdGhpc1tyZXFdID0gb3B0c1tyZXFdO1xuICAgIH1cbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlID0gb3B0cy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZTtcbiAgICBjb25zdCBwcm94eU9wdHMgPSB7XG4gICAgICBsb2csXG4gICAgICBzZXJ2ZXI6IHRoaXMuaG9zdCxcbiAgICAgIHBvcnQ6IHRoaXMuc3lzdGVtUG9ydCxcbiAgICAgIGtlZXBBbGl2ZTogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChvcHRzLnJlYWRUaW1lb3V0ICYmIG9wdHMucmVhZFRpbWVvdXQgPiAwKSB7XG4gICAgICBwcm94eU9wdHMudGltZW91dCA9IG9wdHMucmVhZFRpbWVvdXQ7XG4gICAgfVxuICAgIHRoaXMuandwcm94eSA9IG5ldyBVSUEyUHJveHkocHJveHlPcHRzKTtcbiAgICB0aGlzLnByb3h5UmVxUmVzID0gdGhpcy5qd3Byb3h5LnByb3h5UmVxUmVzLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuandwcm94eS5jb21tYW5kLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHRoZSBhcGtzIG9uIHRvIHRoZSBkZXZpY2Ugb3IgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbnN0YWxsVGltZW91dCAtIEluc3RhbGxhdGlvbiB0aW1lb3V0XG4gICAqL1xuICBhc3luYyBpbnN0YWxsU2VydmVyQXBrIChpbnN0YWxsVGltZW91dCA9IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgKiAxMDAwKSB7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIGNvbnN0IHBhY2thZ2VJbmZvc01hcHBlciA9IGFzeW5jICh7YXBwUGF0aCwgYXBwSWR9KSA9PiB7XG4gICAgICBpZiAoYXdhaXQgaGVscGVycy5pc1dyaXRlYWJsZShhcHBQYXRoKSkge1xuICAgICAgICByZXR1cm4geyBhcHBQYXRoLCBhcHBJZCB9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZy5pbmZvKGBTZXJ2ZXIgcGFja2FnZSBhdCAnJHthcHBQYXRofScgaXMgbm90IHdyaXRlYWJsZS4gYCArXG4gICAgICAgIGBXaWxsIGNvcHkgaXQgaW50byB0aGUgdGVtcG9yYXJ5IGxvY2F0aW9uIGF0ICcke3RtcFJvb3R9JyBhcyBhIHdvcmthcm91bmQuIGAgK1xuICAgICAgICBgQ29uc2lkZXIgbWFraW5nIHRoaXMgZmlsZSB3cml0ZWFibGUgbWFudWFsbHkgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygc2Vzc2lvbiBzdGFydHVwLmApO1xuICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLmJhc2VuYW1lKGFwcFBhdGgpKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGFwcFBhdGgsIGRzdFBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwUGF0aDogZHN0UGF0aCxcbiAgICAgICAgYXBwSWQsXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFja2FnZXNJbmZvID0gYXdhaXQgQi5hbGwoQi5tYXAoW1xuICAgICAgICB7XG4gICAgICAgICAgYXBwUGF0aDogYXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1BBQ0tBR0VfSUQsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBhcHBQYXRoOiB0ZXN0QXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCxcbiAgICAgICAgfSxcbiAgICAgIF0sIHBhY2thZ2VJbmZvc01hcHBlcikpO1xuXG4gICAgICBsZXQgc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGxldCBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3Qge2FwcElkLCBhcHBQYXRofSBvZiBwYWNrYWdlc0luZm8pIHtcbiAgICAgICAgaWYgKGFwcElkID09PSBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKSB7XG4gICAgICAgICAgY29uc3QgaXNBcHBJbnN0YWxsZWQgPSBhd2FpdCB0aGlzLmFkYi5pc0FwcEluc3RhbGxlZChhcHBJZCk7XG5cbiAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwb2ludCBpbiBnZXR0aW5nIHRoZSBzdGF0ZSBmb3IgdGVzdCBzZXJ2ZXIsXG4gICAgICAgICAgLy8gc2luY2UgaXQgZG9lcyBub3QgY29udGFpbiB2ZXJzaW9uIGluZm9cbiAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMuYWRiLmNoZWNrQXBrQ2VydChhcHBQYXRoLCBhcHBJZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGhlbHBlcnMuc2lnbkFwcCh0aGlzLmFkYiwgYXBwUGF0aCk7XG4gICAgICAgICAgICBzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyA9IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IGlzQXBwSW5zdGFsbGVkO1xuICAgICAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWlzQXBwSW5zdGFsbGVkKSB7XG4gICAgICAgICAgICBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcFN0YXRlID0gYXdhaXQgdGhpcy5hZGIuZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUoYXBwUGF0aCwgYXBwSWQpO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgJHthcHBJZH0gaW5zdGFsbGF0aW9uIHN0YXRlOiAke2FwcFN0YXRlfWApO1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5hZGIuY2hlY2tBcGtDZXJ0KGFwcFBhdGgsIGFwcElkKSkge1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgW1xuICAgICAgICAgICAgdGhpcy5hZGIuQVBQX0lOU1RBTExfU1RBVEUuT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQsXG4gICAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5ORVdFUl9WRVJTSU9OX0lOU1RBTExFRCxcbiAgICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCBoZWxwZXJzLnNpZ25BcHAodGhpcy5hZGIsIGFwcFBhdGgpO1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgIVtcbiAgICAgICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICAgICAgXS5pbmNsdWRlcyhhcHBTdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IFtcbiAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5OT1RfSU5TVEFMTEVELFxuICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLmluZm8oYFNlcnZlciBwYWNrYWdlcyBhcmUgJHtzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPyAnJyA6ICdub3QgJ31nb2luZyB0byBiZSAocmUpaW5zdGFsbGVkYCk7XG4gICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzICYmIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0Z1bGwgcGFja2FnZXMgcmVpbnN0YWxsIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm1lZCcpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB7YXBwSWQsIGFwcFBhdGh9IG9mIHBhY2thZ2VzSW5mbykge1xuICAgICAgICBpZiAoc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIudW5pbnN0YWxsQXBrKGFwcElkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9nLndhcm4oYEVycm9yIHVuaW5zdGFsbGluZyAnJHthcHBJZH0nOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIuaW5zdGFsbChhcHBQYXRoLCB7XG4gICAgICAgICAgICBub0luY3JlbWVudGFsOiB0cnVlLFxuICAgICAgICAgICAgcmVwbGFjZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpbWVvdXQ6IGluc3RhbGxUaW1lb3V0LFxuICAgICAgICAgICAgdGltZW91dENhcE5hbWU6ICd1aWF1dG9tYXRvcjJTZXJ2ZXJJbnN0YWxsVGltZW91dCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy52ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSgpO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5U2VydmljZXNBdmFpbGFiaWxpdHkgKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKGBXYWl0aW5nIHVwIHRvICR7U0VSVklDRVNfTEFVTkNIX1RJTUVPVVR9bXMgZm9yIHNlcnZpY2VzIHRvIGJlIGF2YWlsYWJsZWApO1xuICAgIGxldCBpc1BtU2VydmljZUF2YWlsYWJsZSA9IGZhbHNlO1xuICAgIGxldCBwbU91dHB1dCA9ICcnO1xuICAgIGxldCBwbUVycm9yID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghaXNQbVNlcnZpY2VBdmFpbGFibGUpIHtcbiAgICAgICAgICBwbUVycm9yID0gbnVsbDtcbiAgICAgICAgICBwbU91dHB1dCA9ICcnO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwbU91dHB1dCA9IGF3YWl0IHRoaXMuYWRiLnNoZWxsKFsncG0nLCAnbGlzdCcsICdpbnN0cnVtZW50YXRpb24nXSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcG1FcnJvciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwbU91dHB1dC5pbmNsdWRlcygnQ291bGQgbm90IGFjY2VzcyB0aGUgUGFja2FnZSBNYW5hZ2VyJykpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoYFByb2JsZW0gcnVubmluZyBQYWNrYWdlIE1hbmFnZXI6ICR7cG1PdXRwdXR9YCk7XG4gICAgICAgICAgICBwbU91dHB1dCA9ICcnOyAvLyByZW1vdmUgb3V0cHV0LCBzbyBpdCBpcyBub3QgcHJpbnRlZCBiZWxvd1xuICAgICAgICAgIH0gZWxzZSBpZiAocG1PdXRwdXQuaW5jbHVkZXMoSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCkpIHtcbiAgICAgICAgICAgIHBtT3V0cHV0ID0gJyc7IC8vIHJlbW92ZSBvdXRwdXQsIHNvIGl0IGlzIG5vdCBwcmludGVkIGJlbG93XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgSW5zdHJ1bWVudGF0aW9uIHRhcmdldCAnJHtJTlNUUlVNRU5UQVRJT05fVEFSR0VUfScgaXMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlc1xuICAgICAgICAgICAgaXNQbVNlcnZpY2VBdmFpbGFibGUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXBtRXJyb3IpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBpbnN0cnVtZW50YXRpb24gdGFyZ2V0IGlzIG5vdCBsaXN0ZWQgYnkgUGFja2FnZSBNYW5hZ2VyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc1BtU2VydmljZUF2YWlsYWJsZTtcbiAgICAgIH0sIHtcbiAgICAgICAgd2FpdE1zOiBTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCxcbiAgICAgICAgaW50ZXJ2YWxNczogMTAwMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYFVuYWJsZSB0byBmaW5kIGluc3RydW1lbnRhdGlvbiB0YXJnZXQgJyR7SU5TVFJVTUVOVEFUSU9OX1RBUkdFVH0nOiAkeyhwbUVycm9yIHx8IHt9KS5tZXNzYWdlfWApO1xuICAgICAgaWYgKHBtT3V0cHV0KSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdBdmFpbGFibGUgdGFyZ2V0czonKTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHBtT3V0cHV0LnNwbGl0KCdcXG4nKSkge1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGAgICAgJHtsaW5lLnJlcGxhY2UoJ2luc3RydW1lbnRhdGlvbjonLCAnJyl9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKGNhcHMpIHtcbiAgICBhd2FpdCB0aGlzLmNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzKCk7XG4gICAgaWYgKGNhcHMuc2tpcFNlcnZlckluc3RhbGxhdGlvbikge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgJ3NraXBTZXJ2ZXJJbnN0YWxsYXRpb24nIGlzIHNldC4gQXR0ZW1wdGluZyB0byB1c2UgVUlBdXRvbWF0b3IyIHNlcnZlciBmcm9tIHRoZSBkZXZpY2VgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgU3RhcnRpbmcgVUlBdXRvbWF0b3IyIHNlcnZlciAke3NlcnZlclZlcnNpb259YCk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBVc2luZyBVSUF1dG9tYXRvcjIgc2VydmVyIGZyb20gJyR7YXBrUGF0aH0nIGFuZCB0ZXN0IGZyb20gJyR7dGVzdEFwa1BhdGh9J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXQgPSBjYXBzLnVpYXV0b21hdG9yMlNlcnZlckxhdW5jaFRpbWVvdXQgfHwgU0VSVkVSX0xBVU5DSF9USU1FT1VUO1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgbGV0IHJldHJpZXMgPSAwO1xuICAgIGNvbnN0IG1heFJldHJpZXMgPSAyO1xuICAgIGNvbnN0IGRlbGF5QmV0d2VlblJldHJpZXMgPSAzMDAwO1xuICAgIHdoaWxlIChyZXRyaWVzIDwgbWF4UmV0cmllcykge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgV2FpdGluZyB1cCB0byAke3RpbWVvdXR9bXMgZm9yIFVpQXV0b21hdG9yMiB0byBiZSBvbmxpbmUuLi5gKTtcbiAgICAgIHRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcygpO1xuICAgICAgaWYgKCF0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIC8vIHNob3J0IGNpcmN1aXQgdG8gcmV0cnkgb3IgZmFpbCBmYXN0XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICB3YWl0TXM6IHRpbWVvdXQsXG4gICAgICAgICAgICBpbnRlcnZhbE1zOiAxMDAwLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBUaGUgaW5zdHJ1bWVudGF0aW9uIHByb2Nlc3MgY2Fubm90IGJlIGluaXRpYWxpemVkIHdpdGhpbiAke3RpbWVvdXR9bXMgdGltZW91dC4gYFxuICAgICAgICAgICAgKyAnTWFrZSBzdXJlIHRoZSBhcHBsaWNhdGlvbiB1bmRlciB0ZXN0IGRvZXMgbm90IGNyYXNoIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgbG9nY2F0IG91dHB1dC4gJ1xuICAgICAgICAgICAgKyBgWW91IGNvdWxkIGFsc28gdHJ5IHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiAndWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCcgY2FwYWJpbGl0eWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXRyaWVzKys7XG4gICAgICBpZiAocmV0cmllcyA+PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coJ1RoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBjYW5ub3QgYmUgaW5pdGlhbGl6ZWQuICdcbiAgICAgICAgICArICdNYWtlIHN1cmUgdGhlIGFwcGxpY2F0aW9uIHVuZGVyIHRlc3QgZG9lcyBub3QgY3Jhc2ggYW5kIGludmVzdGlnYXRlIHRoZSBsb2djYXQgb3V0cHV0LicpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihgVGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGhhcyBiZWVuIHVuZXhwZWN0ZWRseSB0ZXJtaW5hdGVkLiBgXG4gICAgICAgICsgYFJldHJ5aW5nIFVpQXV0b21hdG9yMiBzdGFydHVwICgjJHtyZXRyaWVzfSBvZiAke21heFJldHJpZXMgLSAxfSlgKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xlYW51cEF1dG9tYXRpb25MZWZ0b3ZlcnModHJ1ZSk7XG4gICAgICBhd2FpdCBCLmRlbGF5KGRlbGF5QmV0d2VlblJldHJpZXMpO1xuICAgIH1cblxuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIHRvb2sgYFxuICAgICAgKyBgJHt0aW1lci5nZXREdXJhdGlvbigpLmFzTWlsbGlTZWNvbmRzLnRvRml4ZWQoMCl9bXNgKTtcbiAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHtcbiAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICBmaXJzdE1hdGNoOiBbY2Fwc10sXG4gICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyAoKSB7XG4gICAgY29uc3QgY21kID0gWydhbScsICdpbnN0cnVtZW50JywgJy13J107XG4gICAgaWYgKHRoaXMuZGlzYWJsZVdpbmRvd0FuaW1hdGlvbikge1xuICAgICAgY21kLnB1c2goJy0tbm8td2luZG93LWFuaW1hdGlvbicpO1xuICAgIH1cbiAgICBpZiAoXy5pc0Jvb2xlYW4odGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSkpIHtcbiAgICAgIGNtZC5wdXNoKCctZScsICdESVNBQkxFX1NVUFBSRVNTX0FDQ0VTU0lCSUxJVFlfU0VSVklDRVMnLCB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlKTtcbiAgICB9XG4gICAgLy8gRGlzYWJsZSBHb29nbGUgYW5hbHl0aWNzIHRvIHByZXZlbnQgcG9zc2libGUgZmF0YWwgZXhjZXB0aW9uXG4gICAgY21kLnB1c2goJy1lJywgJ2Rpc2FibGVBbmFseXRpY3MnLCB0cnVlKTtcbiAgICBjbWQucHVzaChJTlNUUlVNRU5UQVRJT05fVEFSR0VUKTtcbiAgICBjb25zdCBpbnN0cnVtZW50YXRpb25Qcm9jZXNzID0gdGhpcy5hZGIuY3JlYXRlU3ViUHJvY2VzcyhbJ3NoZWxsJywgLi4uY21kXSk7XG4gICAgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5vbignb3V0cHV0JywgKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBfLnRyaW0oc3Rkb3V0IHx8IHN0ZGVycik7XG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGluc3RydW1lbnRhdGlvbkxvZ2dlci5kZWJ1ZyhvdXRwdXQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGluc3RydW1lbnRhdGlvblByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgICAgaW5zdHJ1bWVudGF0aW9uTG9nZ2VyLmRlYnVnKGBUaGUgcHJvY2VzcyBoYXMgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IHRydWU7XG4gICAgfSk7XG4gICAgYXdhaXQgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5zdGFydCgwKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZVNlc3Npb24gKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKCdEZWxldGluZyBVaUF1dG9tYXRvcjIgc2VydmVyIHNlc3Npb24nKTtcbiAgICAvLyByZWx5IG9uIGp3cHJveHkncyBpbnRlbGxpZ2VuY2UgdG8ga25vdyB3aGF0IHdlJ3JlIHRhbGtpbmcgYWJvdXQgYW5kXG4gICAgLy8gZGVsZXRlIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy8nLCAnREVMRVRFJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKGBEaWQgbm90IGdldCBjb25maXJtYXRpb24gVWlBdXRvbWF0b3IyIGRlbGV0ZVNlc3Npb24gd29ya2VkOyBgICtcbiAgICAgICAgICBgRXJyb3Igd2FzOiAke2Vycn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyAoc3RyaWN0Q2xlYW51cCA9IGZhbHNlKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoYFBlcmZvcm1pbmcgJHtzdHJpY3RDbGVhbnVwID8gJ3N0cmljdCcgOiAnc2hhbGxvdyd9IGNsZWFudXAgb2YgYXV0b21hdGlvbiBsZWZ0b3ZlcnNgKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7dmFsdWV9ID0gKGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbnNgLFxuICAgICAgICB0aW1lb3V0OiA1MDAsXG4gICAgICB9KSkuZGF0YTtcbiAgICAgIGNvbnN0IGFjdGl2ZVNlc3Npb25JZHMgPSB2YWx1ZS5tYXAoKHtpZH0pID0+IGlkKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgICBpZiAoYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBmb2xsb3dpbmcgb2Jzb2xldGUgc2Vzc2lvbnMgYXJlIHN0aWxsIHJ1bm5pbmc6ICR7SlNPTi5zdHJpbmdpZnkoYWN0aXZlU2Vzc2lvbklkcyl9YCk7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBDbGVhbmluZyB1cCAke3V0aWwucGx1cmFsaXplKCdvYnNvbGV0ZSBzZXNzaW9uJywgYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgsIHRydWUpfWApO1xuICAgICAgICBhd2FpdCBCLmFsbChhY3RpdmVTZXNzaW9uSWRzXG4gICAgICAgICAgLm1hcCgoaWQpID0+IGF4aW9zLmRlbGV0ZShgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbi8ke2lkfWApKVxuICAgICAgICApO1xuICAgICAgICAvLyBMZXQgYWxsIHNlc3Npb25zIHRvIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWQgYmVmb3JlIGNvbnRpbnVpbmdcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdObyBvYnNvbGV0ZSBzZXNzaW9ucyBoYXZlIGJlZW4gZGV0ZWN0ZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgTm8gb2Jzb2xldGUgc2Vzc2lvbnMgaGF2ZSBiZWVuIGRldGVjdGVkICgke2UubWVzc2FnZX0pYCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLmZvcmNlU3RvcChTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKTtcbiAgICB9IGNhdGNoIChpZ25vcmUpIHt9XG4gICAgaWYgKCFzdHJpY3RDbGVhbnVwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMDc0OVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5raWxsUHJvY2Vzc2VzQnlOYW1lKCd1aWF1dG9tYXRvcicpO1xuICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cbiAgfVxufVxuXG5leHBvcnQgeyBVaUF1dG9tYXRvcjJTZXJ2ZXIsIElOU1RSVU1FTlRBVElPTl9UQVJHRVQsIFNFUlZFUl9QQUNLQUdFX0lELCBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEIH07XG5leHBvcnQgZGVmYXVsdCBVaUF1dG9tYXRvcjJTZXJ2ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBS0E7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUEsTUFBTUEsV0FBVyxHQUFHLENBQUMsS0FBRCxFQUFRLFFBQVIsRUFBa0IsTUFBbEIsRUFBMEIsWUFBMUIsRUFBd0MsWUFBeEMsRUFBc0Qsd0JBQXRELENBQXBCO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsS0FBOUI7QUFDQSxNQUFNQyxzQkFBc0IsR0FBRyxFQUEvQjtBQUNBLE1BQU1DLHVCQUF1QixHQUFHLEtBQWhDO0FBQ0EsTUFBTUMsaUJBQWlCLEdBQUcsK0JBQTFCOztBQUNBLE1BQU1DLHNCQUFzQixHQUFJLEdBQUVELGlCQUFrQixPQUFwRDs7QUFDQSxNQUFNRSxzQkFBc0IsR0FBSSxHQUFFRCxzQkFBdUIsMENBQXpEOzs7QUFDQSxNQUFNRSxxQkFBcUIsR0FBR0MsZUFBQSxDQUFPQyxTQUFQLENBQWlCLGlCQUFqQixDQUE5Qjs7QUFFQSxNQUFNQyxTQUFOLFNBQXdCQyxlQUF4QixDQUFnQztFQUNaLE1BQVpDLFlBQVksQ0FBRUMsR0FBRixFQUFPQyxNQUFQLEVBQWVDLElBQUksR0FBRyxJQUF0QixFQUE0QjtJQUM1QyxJQUFJLEtBQUtDLHNCQUFULEVBQWlDO01BQy9CLE1BQU0sSUFBSUMsY0FBQSxDQUFPQyxtQkFBWCxDQUNILElBQUdKLE1BQU8sSUFBR0QsR0FBSSxxREFBbEIsR0FDQSxpRUFEQSxHQUVBLGdFQUhJLENBQU47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
310
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSRVFEX1BBUkFNUyIsIlNFUlZFUl9MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9JTlNUQUxMX1JFVFJJRVMiLCJTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCIsIlNFUlZFUl9QQUNLQUdFX0lEIiwiU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCIsIklOU1RSVU1FTlRBVElPTl9UQVJHRVQiLCJpbnN0cnVtZW50YXRpb25Mb2dnZXIiLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJVSUEyUHJveHkiLCJKV1Byb3h5IiwicHJveHlDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImRpZEluc3RydW1lbnRhdGlvbkV4aXQiLCJlcnJvcnMiLCJJbnZhbGlkQ29udGV4dEVycm9yIiwiVWlBdXRvbWF0b3IyU2VydmVyIiwiY29uc3RydWN0b3IiLCJsb2ciLCJvcHRzIiwicmVxIiwidXRpbCIsImhhc1ZhbHVlIiwiRXJyb3IiLCJkaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSIsInByb3h5T3B0cyIsInNlcnZlciIsImhvc3QiLCJwb3J0Iiwic3lzdGVtUG9ydCIsImtlZXBBbGl2ZSIsInJlYWRUaW1lb3V0IiwidGltZW91dCIsImp3cHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJjb21tYW5kIiwiaW5zdGFsbFNlcnZlckFwayIsImluc3RhbGxUaW1lb3V0IiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwicGFja2FnZUluZm9zTWFwcGVyIiwiYXBwUGF0aCIsImFwcElkIiwiaGVscGVycyIsImlzV3JpdGVhYmxlIiwiaW5mbyIsImRzdFBhdGgiLCJwYXRoIiwicmVzb2x2ZSIsImJhc2VuYW1lIiwiZnMiLCJjb3B5RmlsZSIsInBhY2thZ2VzSW5mbyIsIkIiLCJhbGwiLCJtYXAiLCJhcGtQYXRoIiwidGVzdEFwa1BhdGgiLCJzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsInNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsImlzQXBwSW5zdGFsbGVkIiwiYWRiIiwiY2hlY2tBcGtDZXJ0Iiwic2lnbkFwcCIsImFwcFN0YXRlIiwiZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUiLCJkZWJ1ZyIsIkFQUF9JTlNUQUxMX1NUQVRFIiwiT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQiLCJORVdFUl9WRVJTSU9OX0lOU1RBTExFRCIsImluY2x1ZGVzIiwiTk9UX0lOU1RBTExFRCIsInVuaW5zdGFsbEFwayIsImVyciIsIndhcm4iLCJtZXNzYWdlIiwiaW5zdGFsbCIsIm5vSW5jcmVtZW50YWwiLCJyZXBsYWNlIiwidGltZW91dENhcE5hbWUiLCJyaW1yYWYiLCJ2ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSIsImlzUG1TZXJ2aWNlQXZhaWxhYmxlIiwicG1PdXRwdXQiLCJwbUVycm9yIiwid2FpdEZvckNvbmRpdGlvbiIsInNoZWxsIiwiZSIsIndhaXRNcyIsImludGVydmFsTXMiLCJlcnJvciIsImxpbmUiLCJzcGxpdCIsInN0YXJ0U2Vzc2lvbiIsImNhcHMiLCJjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyIsInNraXBTZXJ2ZXJJbnN0YWxsYXRpb24iLCJzZXJ2ZXJWZXJzaW9uIiwidWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJzdGFydCIsInJldHJpZXMiLCJtYXhSZXRyaWVzIiwiZGVsYXlCZXR3ZWVuUmV0cmllcyIsInN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImVycm9yQW5kVGhyb3ciLCJkZWxheSIsImdldER1cmF0aW9uIiwiYXNNaWxsaVNlY29uZHMiLCJ0b0ZpeGVkIiwiY2FwYWJpbGl0aWVzIiwiZmlyc3RNYXRjaCIsImFsd2F5c01hdGNoIiwiY21kIiwiZGlzYWJsZVdpbmRvd0FuaW1hdGlvbiIsInB1c2giLCJfIiwiaXNCb29sZWFuIiwiaW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImNyZWF0ZVN1YlByb2Nlc3MiLCJvbiIsInN0ZG91dCIsInN0ZGVyciIsIm91dHB1dCIsInRyaW0iLCJjb2RlIiwiZGVsZXRlU2Vzc2lvbiIsInN0cmljdENsZWFudXAiLCJ2YWx1ZSIsImF4aW9zIiwiZGF0YSIsImFjdGl2ZVNlc3Npb25JZHMiLCJpZCIsImZpbHRlciIsIkJvb2xlYW4iLCJsZW5ndGgiLCJKU09OIiwic3RyaW5naWZ5IiwicGx1cmFsaXplIiwiZGVsZXRlIiwiZm9yY2VTdG9wIiwiaWdub3JlIiwia2lsbFByb2Nlc3Nlc0J5TmFtZSJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91aWF1dG9tYXRvcjIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEpXUHJveHksIGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7XG4gIFNFUlZFUl9BUEtfUEFUSCBhcyBhcGtQYXRoLFxuICBURVNUX0FQS19QQVRIIGFzIHRlc3RBcGtQYXRoLFxuICB2ZXJzaW9uIGFzIHNlcnZlclZlcnNpb25cbn0gZnJvbSAnYXBwaXVtLXVpYXV0b21hdG9yMi1zZXJ2ZXInO1xuaW1wb3J0IHtcbiAgdXRpbCwgbG9nZ2VyLCB0ZW1wRGlyLCBmcywgdGltaW5nXG59IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IFJFUURfUEFSQU1TID0gWydhZGInLCAndG1wRGlyJywgJ2hvc3QnLCAnc3lzdGVtUG9ydCcsICdkZXZpY2VQb3J0JywgJ2Rpc2FibGVXaW5kb3dBbmltYXRpb24nXTtcbmNvbnN0IFNFUlZFUl9MQVVOQ0hfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgU0VSVkVSX0lOU1RBTExfUkVUUklFUyA9IDIwO1xuY29uc3QgU0VSVklDRVNfTEFVTkNIX1RJTUVPVVQgPSAzMDAwMDtcbmNvbnN0IFNFUlZFUl9QQUNLQUdFX0lEID0gJ2lvLmFwcGl1bS51aWF1dG9tYXRvcjIuc2VydmVyJztcbmNvbnN0IFNFUlZFUl9URVNUX1BBQ0tBR0VfSUQgPSBgJHtTRVJWRVJfUEFDS0FHRV9JRH0udGVzdGA7XG5jb25zdCBJTlNUUlVNRU5UQVRJT05fVEFSR0VUID0gYCR7U0VSVkVSX1RFU1RfUEFDS0FHRV9JRH0vYW5kcm9pZHgudGVzdC5ydW5uZXIuQW5kcm9pZEpVbml0UnVubmVyYDtcbmNvbnN0IGluc3RydW1lbnRhdGlvbkxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIoJ0luc3RydW1lbnRhdGlvbicpO1xuXG5jbGFzcyBVSUEyUHJveHkgZXh0ZW5kcyBKV1Byb3h5IHtcbiAgYXN5bmMgcHJveHlDb21tYW5kICh1cmwsIG1ldGhvZCwgYm9keSA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRDb250ZXh0RXJyb3IoXG4gICAgICAgIGAnJHttZXRob2R9ICR7dXJsfScgY2Fubm90IGJlIHByb3hpZWQgdG8gVWlBdXRvbWF0b3IyIHNlcnZlciBiZWNhdXNlIGAgK1xuICAgICAgICAndGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGlzIG5vdCBydW5uaW5nIChwcm9iYWJseSBjcmFzaGVkKS4gJyArXG4gICAgICAgICdDaGVjayB0aGUgc2VydmVyIGxvZyBhbmQvb3IgdGhlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscycpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgc3VwZXIucHJveHlDb21tYW5kKHVybCwgbWV0aG9kLCBib2R5KTtcbiAgfVxufVxuXG5jbGFzcyBVaUF1dG9tYXRvcjJTZXJ2ZXIge1xuICBjb25zdHJ1Y3RvciAobG9nLCBvcHRzID0ge30pIHtcbiAgICBmb3IgKGxldCByZXEgb2YgUkVRRF9QQVJBTVMpIHtcbiAgICAgIGlmICghb3B0cyB8fCAhdXRpbC5oYXNWYWx1ZShvcHRzW3JlcV0pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgT3B0aW9uICcke3JlcX0nIGlzIHJlcXVpcmVkIWApO1xuICAgICAgfVxuICAgICAgdGhpc1tyZXFdID0gb3B0c1tyZXFdO1xuICAgIH1cbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlID0gb3B0cy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZTtcbiAgICBjb25zdCBwcm94eU9wdHMgPSB7XG4gICAgICBsb2csXG4gICAgICBzZXJ2ZXI6IHRoaXMuaG9zdCxcbiAgICAgIHBvcnQ6IHRoaXMuc3lzdGVtUG9ydCxcbiAgICAgIGtlZXBBbGl2ZTogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChvcHRzLnJlYWRUaW1lb3V0ICYmIG9wdHMucmVhZFRpbWVvdXQgPiAwKSB7XG4gICAgICBwcm94eU9wdHMudGltZW91dCA9IG9wdHMucmVhZFRpbWVvdXQ7XG4gICAgfVxuICAgIHRoaXMuandwcm94eSA9IG5ldyBVSUEyUHJveHkocHJveHlPcHRzKTtcbiAgICB0aGlzLnByb3h5UmVxUmVzID0gdGhpcy5qd3Byb3h5LnByb3h5UmVxUmVzLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuandwcm94eS5jb21tYW5kLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHRoZSBhcGtzIG9uIHRvIHRoZSBkZXZpY2Ugb3IgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbnN0YWxsVGltZW91dCAtIEluc3RhbGxhdGlvbiB0aW1lb3V0XG4gICAqL1xuICBhc3luYyBpbnN0YWxsU2VydmVyQXBrIChpbnN0YWxsVGltZW91dCA9IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgKiAxMDAwKSB7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIGNvbnN0IHBhY2thZ2VJbmZvc01hcHBlciA9IGFzeW5jICh7YXBwUGF0aCwgYXBwSWR9KSA9PiB7XG4gICAgICBpZiAoYXdhaXQgaGVscGVycy5pc1dyaXRlYWJsZShhcHBQYXRoKSkge1xuICAgICAgICByZXR1cm4geyBhcHBQYXRoLCBhcHBJZCB9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZy5pbmZvKGBTZXJ2ZXIgcGFja2FnZSBhdCAnJHthcHBQYXRofScgaXMgbm90IHdyaXRlYWJsZS4gYCArXG4gICAgICAgIGBXaWxsIGNvcHkgaXQgaW50byB0aGUgdGVtcG9yYXJ5IGxvY2F0aW9uIGF0ICcke3RtcFJvb3R9JyBhcyBhIHdvcmthcm91bmQuIGAgK1xuICAgICAgICBgQ29uc2lkZXIgbWFraW5nIHRoaXMgZmlsZSB3cml0ZWFibGUgbWFudWFsbHkgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygc2Vzc2lvbiBzdGFydHVwLmApO1xuICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLmJhc2VuYW1lKGFwcFBhdGgpKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGFwcFBhdGgsIGRzdFBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwUGF0aDogZHN0UGF0aCxcbiAgICAgICAgYXBwSWQsXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFja2FnZXNJbmZvID0gYXdhaXQgQi5hbGwoQi5tYXAoW1xuICAgICAgICB7XG4gICAgICAgICAgYXBwUGF0aDogYXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1BBQ0tBR0VfSUQsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBhcHBQYXRoOiB0ZXN0QXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCxcbiAgICAgICAgfSxcbiAgICAgIF0sIHBhY2thZ2VJbmZvc01hcHBlcikpO1xuXG4gICAgICBsZXQgc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGxldCBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3Qge2FwcElkLCBhcHBQYXRofSBvZiBwYWNrYWdlc0luZm8pIHtcbiAgICAgICAgaWYgKGFwcElkID09PSBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKSB7XG4gICAgICAgICAgY29uc3QgaXNBcHBJbnN0YWxsZWQgPSBhd2FpdCB0aGlzLmFkYi5pc0FwcEluc3RhbGxlZChhcHBJZCk7XG5cbiAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwb2ludCBpbiBnZXR0aW5nIHRoZSBzdGF0ZSBmb3IgdGVzdCBzZXJ2ZXIsXG4gICAgICAgICAgLy8gc2luY2UgaXQgZG9lcyBub3QgY29udGFpbiB2ZXJzaW9uIGluZm9cbiAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMuYWRiLmNoZWNrQXBrQ2VydChhcHBQYXRoLCBhcHBJZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGhlbHBlcnMuc2lnbkFwcCh0aGlzLmFkYiwgYXBwUGF0aCk7XG4gICAgICAgICAgICBzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyA9IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IGlzQXBwSW5zdGFsbGVkO1xuICAgICAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWlzQXBwSW5zdGFsbGVkKSB7XG4gICAgICAgICAgICBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcFN0YXRlID0gYXdhaXQgdGhpcy5hZGIuZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUoYXBwUGF0aCwgYXBwSWQpO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgJHthcHBJZH0gaW5zdGFsbGF0aW9uIHN0YXRlOiAke2FwcFN0YXRlfWApO1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5hZGIuY2hlY2tBcGtDZXJ0KGFwcFBhdGgsIGFwcElkKSkge1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgW1xuICAgICAgICAgICAgdGhpcy5hZGIuQVBQX0lOU1RBTExfU1RBVEUuT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQsXG4gICAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5ORVdFUl9WRVJTSU9OX0lOU1RBTExFRCxcbiAgICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCBoZWxwZXJzLnNpZ25BcHAodGhpcy5hZGIsIGFwcFBhdGgpO1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgIVtcbiAgICAgICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICAgICAgXS5pbmNsdWRlcyhhcHBTdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IFtcbiAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5OT1RfSU5TVEFMTEVELFxuICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLmluZm8oYFNlcnZlciBwYWNrYWdlcyBhcmUgJHtzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPyAnJyA6ICdub3QgJ31nb2luZyB0byBiZSAocmUpaW5zdGFsbGVkYCk7XG4gICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzICYmIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0Z1bGwgcGFja2FnZXMgcmVpbnN0YWxsIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm1lZCcpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB7YXBwSWQsIGFwcFBhdGh9IG9mIHBhY2thZ2VzSW5mbykge1xuICAgICAgICBpZiAoc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIudW5pbnN0YWxsQXBrKGFwcElkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9nLndhcm4oYEVycm9yIHVuaW5zdGFsbGluZyAnJHthcHBJZH0nOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIuaW5zdGFsbChhcHBQYXRoLCB7XG4gICAgICAgICAgICBub0luY3JlbWVudGFsOiB0cnVlLFxuICAgICAgICAgICAgcmVwbGFjZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpbWVvdXQ6IGluc3RhbGxUaW1lb3V0LFxuICAgICAgICAgICAgdGltZW91dENhcE5hbWU6ICd1aWF1dG9tYXRvcjJTZXJ2ZXJJbnN0YWxsVGltZW91dCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy52ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSgpO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5U2VydmljZXNBdmFpbGFiaWxpdHkgKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKGBXYWl0aW5nIHVwIHRvICR7U0VSVklDRVNfTEFVTkNIX1RJTUVPVVR9bXMgZm9yIHNlcnZpY2VzIHRvIGJlIGF2YWlsYWJsZWApO1xuICAgIGxldCBpc1BtU2VydmljZUF2YWlsYWJsZSA9IGZhbHNlO1xuICAgIGxldCBwbU91dHB1dCA9ICcnO1xuICAgIGxldCBwbUVycm9yID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghaXNQbVNlcnZpY2VBdmFpbGFibGUpIHtcbiAgICAgICAgICBwbUVycm9yID0gbnVsbDtcbiAgICAgICAgICBwbU91dHB1dCA9ICcnO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwbU91dHB1dCA9IGF3YWl0IHRoaXMuYWRiLnNoZWxsKFsncG0nLCAnbGlzdCcsICdpbnN0cnVtZW50YXRpb24nXSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcG1FcnJvciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwbU91dHB1dC5pbmNsdWRlcygnQ291bGQgbm90IGFjY2VzcyB0aGUgUGFja2FnZSBNYW5hZ2VyJykpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoYFByb2JsZW0gcnVubmluZyBQYWNrYWdlIE1hbmFnZXI6ICR7cG1PdXRwdXR9YCk7XG4gICAgICAgICAgICBwbU91dHB1dCA9ICcnOyAvLyByZW1vdmUgb3V0cHV0LCBzbyBpdCBpcyBub3QgcHJpbnRlZCBiZWxvd1xuICAgICAgICAgIH0gZWxzZSBpZiAocG1PdXRwdXQuaW5jbHVkZXMoSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCkpIHtcbiAgICAgICAgICAgIHBtT3V0cHV0ID0gJyc7IC8vIHJlbW92ZSBvdXRwdXQsIHNvIGl0IGlzIG5vdCBwcmludGVkIGJlbG93XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgSW5zdHJ1bWVudGF0aW9uIHRhcmdldCAnJHtJTlNUUlVNRU5UQVRJT05fVEFSR0VUfScgaXMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlc1xuICAgICAgICAgICAgaXNQbVNlcnZpY2VBdmFpbGFibGUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXBtRXJyb3IpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBpbnN0cnVtZW50YXRpb24gdGFyZ2V0IGlzIG5vdCBsaXN0ZWQgYnkgUGFja2FnZSBNYW5hZ2VyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc1BtU2VydmljZUF2YWlsYWJsZTtcbiAgICAgIH0sIHtcbiAgICAgICAgd2FpdE1zOiBTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCxcbiAgICAgICAgaW50ZXJ2YWxNczogMTAwMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYFVuYWJsZSB0byBmaW5kIGluc3RydW1lbnRhdGlvbiB0YXJnZXQgJyR7SU5TVFJVTUVOVEFUSU9OX1RBUkdFVH0nOiAkeyhwbUVycm9yIHx8IHt9KS5tZXNzYWdlfWApO1xuICAgICAgaWYgKHBtT3V0cHV0KSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdBdmFpbGFibGUgdGFyZ2V0czonKTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHBtT3V0cHV0LnNwbGl0KCdcXG4nKSkge1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGAgICAgJHtsaW5lLnJlcGxhY2UoJ2luc3RydW1lbnRhdGlvbjonLCAnJyl9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKGNhcHMpIHtcbiAgICBhd2FpdCB0aGlzLmNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzKCk7XG4gICAgaWYgKGNhcHMuc2tpcFNlcnZlckluc3RhbGxhdGlvbikge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgJ3NraXBTZXJ2ZXJJbnN0YWxsYXRpb24nIGlzIHNldC4gQXR0ZW1wdGluZyB0byB1c2UgVUlBdXRvbWF0b3IyIHNlcnZlciBmcm9tIHRoZSBkZXZpY2VgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgU3RhcnRpbmcgVUlBdXRvbWF0b3IyIHNlcnZlciAke3NlcnZlclZlcnNpb259YCk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBVc2luZyBVSUF1dG9tYXRvcjIgc2VydmVyIGZyb20gJyR7YXBrUGF0aH0nIGFuZCB0ZXN0IGZyb20gJyR7dGVzdEFwa1BhdGh9J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXQgPSBjYXBzLnVpYXV0b21hdG9yMlNlcnZlckxhdW5jaFRpbWVvdXQgfHwgU0VSVkVSX0xBVU5DSF9USU1FT1VUO1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgbGV0IHJldHJpZXMgPSAwO1xuICAgIGNvbnN0IG1heFJldHJpZXMgPSAyO1xuICAgIGNvbnN0IGRlbGF5QmV0d2VlblJldHJpZXMgPSAzMDAwO1xuICAgIHdoaWxlIChyZXRyaWVzIDwgbWF4UmV0cmllcykge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgV2FpdGluZyB1cCB0byAke3RpbWVvdXR9bXMgZm9yIFVpQXV0b21hdG9yMiB0byBiZSBvbmxpbmUuLi5gKTtcbiAgICAgIHRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcygpO1xuICAgICAgaWYgKCF0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIC8vIHNob3J0IGNpcmN1aXQgdG8gcmV0cnkgb3IgZmFpbCBmYXN0XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICB3YWl0TXM6IHRpbWVvdXQsXG4gICAgICAgICAgICBpbnRlcnZhbE1zOiAxMDAwLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBUaGUgaW5zdHJ1bWVudGF0aW9uIHByb2Nlc3MgY2Fubm90IGJlIGluaXRpYWxpemVkIHdpdGhpbiAke3RpbWVvdXR9bXMgdGltZW91dC4gYFxuICAgICAgICAgICAgKyAnTWFrZSBzdXJlIHRoZSBhcHBsaWNhdGlvbiB1bmRlciB0ZXN0IGRvZXMgbm90IGNyYXNoIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgbG9nY2F0IG91dHB1dC4gJ1xuICAgICAgICAgICAgKyBgWW91IGNvdWxkIGFsc28gdHJ5IHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiAndWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCcgY2FwYWJpbGl0eWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXRyaWVzKys7XG4gICAgICBpZiAocmV0cmllcyA+PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coJ1RoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBjYW5ub3QgYmUgaW5pdGlhbGl6ZWQuICdcbiAgICAgICAgICArICdNYWtlIHN1cmUgdGhlIGFwcGxpY2F0aW9uIHVuZGVyIHRlc3QgZG9lcyBub3QgY3Jhc2ggYW5kIGludmVzdGlnYXRlIHRoZSBsb2djYXQgb3V0cHV0LicpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihgVGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGhhcyBiZWVuIHVuZXhwZWN0ZWRseSB0ZXJtaW5hdGVkLiBgXG4gICAgICAgICsgYFJldHJ5aW5nIFVpQXV0b21hdG9yMiBzdGFydHVwICgjJHtyZXRyaWVzfSBvZiAke21heFJldHJpZXMgLSAxfSlgKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xlYW51cEF1dG9tYXRpb25MZWZ0b3ZlcnModHJ1ZSk7XG4gICAgICBhd2FpdCBCLmRlbGF5KGRlbGF5QmV0d2VlblJldHJpZXMpO1xuICAgIH1cblxuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIHRvb2sgYFxuICAgICAgKyBgJHt0aW1lci5nZXREdXJhdGlvbigpLmFzTWlsbGlTZWNvbmRzLnRvRml4ZWQoMCl9bXNgKTtcbiAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHtcbiAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICBmaXJzdE1hdGNoOiBbY2Fwc10sXG4gICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyAoKSB7XG4gICAgY29uc3QgY21kID0gWydhbScsICdpbnN0cnVtZW50JywgJy13J107XG4gICAgaWYgKHRoaXMuZGlzYWJsZVdpbmRvd0FuaW1hdGlvbikge1xuICAgICAgY21kLnB1c2goJy0tbm8td2luZG93LWFuaW1hdGlvbicpO1xuICAgIH1cbiAgICBpZiAoXy5pc0Jvb2xlYW4odGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSkpIHtcbiAgICAgIGNtZC5wdXNoKCctZScsICdESVNBQkxFX1NVUFBSRVNTX0FDQ0VTU0lCSUxJVFlfU0VSVklDRVMnLCB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlKTtcbiAgICB9XG4gICAgLy8gRGlzYWJsZSBHb29nbGUgYW5hbHl0aWNzIHRvIHByZXZlbnQgcG9zc2libGUgZmF0YWwgZXhjZXB0aW9uXG4gICAgY21kLnB1c2goJy1lJywgJ2Rpc2FibGVBbmFseXRpY3MnLCB0cnVlKTtcbiAgICBjbWQucHVzaChJTlNUUlVNRU5UQVRJT05fVEFSR0VUKTtcbiAgICBjb25zdCBpbnN0cnVtZW50YXRpb25Qcm9jZXNzID0gdGhpcy5hZGIuY3JlYXRlU3ViUHJvY2VzcyhbJ3NoZWxsJywgLi4uY21kXSk7XG4gICAgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5vbignb3V0cHV0JywgKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBfLnRyaW0oc3Rkb3V0IHx8IHN0ZGVycik7XG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGluc3RydW1lbnRhdGlvbkxvZ2dlci5kZWJ1ZyhvdXRwdXQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGluc3RydW1lbnRhdGlvblByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgICAgaW5zdHJ1bWVudGF0aW9uTG9nZ2VyLmRlYnVnKGBUaGUgcHJvY2VzcyBoYXMgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IHRydWU7XG4gICAgfSk7XG4gICAgYXdhaXQgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5zdGFydCgwKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZVNlc3Npb24gKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKCdEZWxldGluZyBVaUF1dG9tYXRvcjIgc2VydmVyIHNlc3Npb24nKTtcbiAgICAvLyByZWx5IG9uIGp3cHJveHkncyBpbnRlbGxpZ2VuY2UgdG8ga25vdyB3aGF0IHdlJ3JlIHRhbGtpbmcgYWJvdXQgYW5kXG4gICAgLy8gZGVsZXRlIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy8nLCAnREVMRVRFJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKGBEaWQgbm90IGdldCBjb25maXJtYXRpb24gVWlBdXRvbWF0b3IyIGRlbGV0ZVNlc3Npb24gd29ya2VkOyBgICtcbiAgICAgICAgICBgRXJyb3Igd2FzOiAke2Vycn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyAoc3RyaWN0Q2xlYW51cCA9IGZhbHNlKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoYFBlcmZvcm1pbmcgJHtzdHJpY3RDbGVhbnVwID8gJ3N0cmljdCcgOiAnc2hhbGxvdyd9IGNsZWFudXAgb2YgYXV0b21hdGlvbiBsZWZ0b3ZlcnNgKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7dmFsdWV9ID0gKGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbnNgLFxuICAgICAgICB0aW1lb3V0OiA1MDAsXG4gICAgICB9KSkuZGF0YTtcbiAgICAgIGNvbnN0IGFjdGl2ZVNlc3Npb25JZHMgPSB2YWx1ZS5tYXAoKHtpZH0pID0+IGlkKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgICBpZiAoYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBmb2xsb3dpbmcgb2Jzb2xldGUgc2Vzc2lvbnMgYXJlIHN0aWxsIHJ1bm5pbmc6ICR7SlNPTi5zdHJpbmdpZnkoYWN0aXZlU2Vzc2lvbklkcyl9YCk7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBDbGVhbmluZyB1cCAke3V0aWwucGx1cmFsaXplKCdvYnNvbGV0ZSBzZXNzaW9uJywgYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgsIHRydWUpfWApO1xuICAgICAgICBhd2FpdCBCLmFsbChhY3RpdmVTZXNzaW9uSWRzXG4gICAgICAgICAgLm1hcCgoaWQpID0+IGF4aW9zLmRlbGV0ZShgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbi8ke2lkfWApKVxuICAgICAgICApO1xuICAgICAgICAvLyBMZXQgYWxsIHNlc3Npb25zIHRvIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWQgYmVmb3JlIGNvbnRpbnVpbmdcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdObyBvYnNvbGV0ZSBzZXNzaW9ucyBoYXZlIGJlZW4gZGV0ZWN0ZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgTm8gb2Jzb2xldGUgc2Vzc2lvbnMgaGF2ZSBiZWVuIGRldGVjdGVkICgke2UubWVzc2FnZX0pYCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLmZvcmNlU3RvcChTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKTtcbiAgICB9IGNhdGNoIChpZ25vcmUpIHt9XG4gICAgaWYgKCFzdHJpY3RDbGVhbnVwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMDc0OVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5raWxsUHJvY2Vzc2VzQnlOYW1lKCd1aWF1dG9tYXRvcicpO1xuICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cbiAgfVxufVxuXG5leHBvcnQgeyBVaUF1dG9tYXRvcjJTZXJ2ZXIsIElOU1RSVU1FTlRBVElPTl9UQVJHRVQsIFNFUlZFUl9QQUNLQUdFX0lELCBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEIH07XG5leHBvcnQgZGVmYXVsdCBVaUF1dG9tYXRvcjJTZXJ2ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFLQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTUEsV0FBVyxHQUFHLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSx3QkFBd0IsQ0FBQztBQUNuRyxNQUFNQyxxQkFBcUIsR0FBRyxLQUFLO0FBQ25DLE1BQU1DLHNCQUFzQixHQUFHLEVBQUU7QUFDakMsTUFBTUMsdUJBQXVCLEdBQUcsS0FBSztBQUNyQyxNQUFNQyxpQkFBaUIsR0FBRywrQkFBK0I7QUFBQztBQUMxRCxNQUFNQyxzQkFBc0IsR0FBSSxHQUFFRCxpQkFBa0IsT0FBTTtBQUFDO0FBQzNELE1BQU1FLHNCQUFzQixHQUFJLEdBQUVELHNCQUF1QiwwQ0FBeUM7QUFBQztBQUNuRyxNQUFNRSxxQkFBcUIsR0FBR0MsZUFBTSxDQUFDQyxTQUFTLENBQUMsaUJBQWlCLENBQUM7QUFFakUsTUFBTUMsU0FBUyxTQUFTQyxlQUFPLENBQUM7RUFDOUIsTUFBTUMsWUFBWSxDQUFFQyxHQUFHLEVBQUVDLE1BQU0sRUFBRUMsSUFBSSxHQUFHLElBQUksRUFBRTtJQUM1QyxJQUFJLElBQUksQ0FBQ0Msc0JBQXNCLEVBQUU7TUFDL0IsTUFBTSxJQUFJQyxjQUFNLENBQUNDLG1CQUFtQixDQUNqQyxJQUFHSixNQUFPLElBQUdELEdBQUkscURBQW9ELEdBQ3RFLGlFQUFpRSxHQUNqRSxnRUFBZ0UsQ0FBQztJ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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uiautomator2.js","names":["REQD_PARAMS","SERVER_LAUNCH_TIMEOUT","SERVER_INSTALL_RETRIES","SERVICES_LAUNCH_TIMEOUT","SERVER_PACKAGE_ID","SERVER_TEST_PACKAGE_ID","INSTRUMENTATION_TARGET","instrumentationLogger","logger","getLogger","UIA2Proxy","JWProxy","proxyCommand","url","method","body","didInstrumentationExit","errors","InvalidContextError","UiAutomator2Server","constructor","log","opts","req","util","hasValue","Error","disableSuppressAccessibilityService","proxyOpts","server","host","port","systemPort","keepAlive","readTimeout","timeout","jwproxy","proxyReqRes","bind","command","installServerApk","installTimeout","tmpRoot","tempDir","openDir","packageInfosMapper","appPath","appId","helpers","isWriteable","info","dstPath","path","resolve","basename","fs","copyFile","packagesInfo","B","all","map","apkPath","testApkPath","shouldUninstallServerPackages","shouldInstallServerPackages","isAppInstalled","adb","checkApkCert","signApp","appState","getApplicationInstallState","debug","APP_INSTALL_STATE","OLDER_VERSION_INSTALLED","NEWER_VERSION_INSTALLED","includes","NOT_INSTALLED","uninstallApk","err","warn","message","install","noIncremental","replace","timeoutCapName","rimraf","verifyServicesAvailability","isPmServiceAvailable","pmOutput","pmError","waitForCondition","shell","e","waitMs","intervalMs","error","line","split","startSession","caps","cleanupAutomationLeftovers","skipServerInstallation","serverVersion","uiautomator2ServerLaunchTimeout","timer","timing","Timer","start","retries","maxRetries","delayBetweenRetries","startInstrumentationProcess","errorAndThrow","delay","getDuration","asMilliSeconds","toFixed","capabilities","firstMatch","alwaysMatch","cmd","disableWindowAnimation","push","_","isBoolean","instrumentationProcess","createSubProcess","on","stdout","stderr","output","trim","code","deleteSession","strictCleanup","value","axios","data","activeSessionIds","id","filter","Boolean","length","JSON","stringify","pluralize","delete","forceStop","ignore","killProcessesByName"],"sources":["../../lib/uiautomator2.js"],"sourcesContent":["import _ from 'lodash';\nimport { JWProxy, errors } from 'appium/driver';\nimport { waitForCondition } from 'asyncbox';\nimport {\n SERVER_APK_PATH as apkPath,\n TEST_APK_PATH as testApkPath,\n version as serverVersion\n} from 'appium-uiautomator2-server';\nimport {\n util, logger, tempDir, fs, timing\n} from 'appium/support';\nimport B from 'bluebird';\nimport helpers from './helpers';\nimport axios from 'axios';\nimport path from 'path';\n\nconst REQD_PARAMS = ['adb', 'tmpDir', 'host', 'systemPort', 'devicePort', 'disableWindowAnimation'];\nconst SERVER_LAUNCH_TIMEOUT = 30000;\nconst SERVER_INSTALL_RETRIES = 20;\nconst SERVICES_LAUNCH_TIMEOUT = 30000;\nconst SERVER_PACKAGE_ID = 'io.appium.uiautomator2.server';\nconst SERVER_TEST_PACKAGE_ID = `${SERVER_PACKAGE_ID}.test`;\nconst INSTRUMENTATION_TARGET = `${SERVER_TEST_PACKAGE_ID}/androidx.test.runner.AndroidJUnitRunner`;\nconst instrumentationLogger = logger.getLogger('Instrumentation');\n\nclass UIA2Proxy extends JWProxy {\n async proxyCommand (url, method, body = null) {\n if (this.didInstrumentationExit) {\n throw new errors.InvalidContextError(\n `'${method} ${url}' cannot be proxied to UiAutomator2 server because ` +\n 'the instrumentation process is not running (probably crashed). ' +\n 'Check the server log and/or the logcat output for more details');\n }\n return await super.proxyCommand(url, method, body);\n }\n}\n\nclass UiAutomator2Server {\n constructor (log, opts = {}) {\n for (let req of REQD_PARAMS) {\n if (!opts || !util.hasValue(opts[req])) {\n throw new Error(`Option '${req}' is required!`);\n }\n this[req] = opts[req];\n }\n this.log = log;\n this.disableSuppressAccessibilityService = opts.disableSuppressAccessibilityService;\n const proxyOpts = {\n log,\n server: this.host,\n port: this.systemPort,\n keepAlive: true,\n };\n if (opts.readTimeout && opts.readTimeout > 0) {\n proxyOpts.timeout = opts.readTimeout;\n }\n this.jwproxy = new UIA2Proxy(proxyOpts);\n this.proxyReqRes = this.jwproxy.proxyReqRes.bind(this.jwproxy);\n this.proxyCommand = this.jwproxy.command.bind(this.jwproxy);\n this.jwproxy.didInstrumentationExit = false;\n }\n\n /**\n * Installs the apks on to the device or emulator.\n *\n * @param {number} installTimeout - Installation timeout\n */\n async installServerApk (installTimeout = SERVER_INSTALL_RETRIES * 1000) {\n const tmpRoot = await tempDir.openDir();\n const packageInfosMapper = async ({appPath, appId}) => {\n if (await helpers.isWriteable(appPath)) {\n return { appPath, appId };\n }\n\n this.log.info(`Server package at '${appPath}' is not writeable. ` +\n `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` +\n `Consider making this file writeable manually in order to improve the performance of session startup.`);\n const dstPath = path.resolve(tmpRoot, path.basename(appPath));\n await fs.copyFile(appPath, dstPath);\n return {\n appPath: dstPath,\n appId,\n };\n };\n\n try {\n const packagesInfo = await B.all(B.map([\n {\n appPath: apkPath,\n appId: SERVER_PACKAGE_ID,\n }, {\n appPath: testApkPath,\n appId: SERVER_TEST_PACKAGE_ID,\n },\n ], packageInfosMapper));\n\n let shouldUninstallServerPackages = false;\n let shouldInstallServerPackages = false;\n for (const {appId, appPath} of packagesInfo) {\n if (appId === SERVER_TEST_PACKAGE_ID) {\n const isAppInstalled = await this.adb.isAppInstalled(appId);\n\n // There is no point in getting the state for test server,\n // since it does not contain version info\n if (!await this.adb.checkApkCert(appPath, appId)) {\n await helpers.signApp(this.adb, appPath);\n shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;\n shouldInstallServerPackages = true;\n }\n\n if (!isAppInstalled) {\n shouldInstallServerPackages = true;\n }\n continue;\n }\n\n const appState = await this.adb.getApplicationInstallState(appPath, appId);\n this.log.debug(`${appId} installation state: ${appState}`);\n if (await this.adb.checkApkCert(appPath, appId)) {\n shouldUninstallServerPackages = shouldUninstallServerPackages || [\n this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,\n this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED,\n ].includes(appState);\n } else {\n await helpers.signApp(this.adb, appPath);\n shouldUninstallServerPackages = shouldUninstallServerPackages || ![\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n ].includes(appState);\n }\n shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n ].includes(appState);\n }\n this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);\n if (shouldInstallServerPackages && shouldUninstallServerPackages) {\n this.log.info('Full packages reinstall is going to be performed');\n }\n for (const {appId, appPath} of packagesInfo) {\n if (shouldUninstallServerPackages) {\n try {\n await this.adb.uninstallApk(appId);\n } catch (err) {\n this.log.warn(`Error uninstalling '${appId}': ${err.message}`);\n }\n }\n if (shouldInstallServerPackages) {\n await this.adb.install(appPath, {\n noIncremental: true,\n replace: true,\n timeout: installTimeout,\n timeoutCapName: 'uiautomator2ServerInstallTimeout'\n });\n }\n }\n } finally {\n await fs.rimraf(tmpRoot);\n }\n\n await this.verifyServicesAvailability();\n }\n\n async verifyServicesAvailability () {\n this.log.debug(`Waiting up to ${SERVICES_LAUNCH_TIMEOUT}ms for services to be available`);\n let isPmServiceAvailable = false;\n let pmOutput = '';\n let pmError = null;\n try {\n await waitForCondition(async () => {\n if (!isPmServiceAvailable) {\n pmError = null;\n pmOutput = '';\n try {\n pmOutput = await this.adb.shell(['pm', 'list', 'instrumentation']);\n } catch (e) {\n pmError = e;\n }\n if (pmOutput.includes('Could not access the Package Manager')) {\n pmError = new Error(`Problem running Package Manager: ${pmOutput}`);\n pmOutput = ''; // remove output, so it is not printed below\n } else if (pmOutput.includes(INSTRUMENTATION_TARGET)) {\n pmOutput = ''; // remove output, so it is not printed below\n this.log.debug(`Instrumentation target '${INSTRUMENTATION_TARGET}' is available`);\n // eslint-disable-next-line require-atomic-updates\n isPmServiceAvailable = true;\n } else if (!pmError) {\n pmError = new Error('The instrumentation target is not listed by Package Manager');\n }\n }\n return isPmServiceAvailable;\n }, {\n waitMs: SERVICES_LAUNCH_TIMEOUT,\n intervalMs: 1000,\n });\n } catch (err) {\n this.log.error(`Unable to find instrumentation target '${INSTRUMENTATION_TARGET}': ${(pmError || {}).message}`);\n if (pmOutput) {\n this.log.debug('Available targets:');\n for (const line of pmOutput.split('\\n')) {\n this.log.debug(` ${line.replace('instrumentation:', '')}`);\n }\n }\n }\n }\n\n async startSession (caps) {\n await this.cleanupAutomationLeftovers();\n if (caps.skipServerInstallation) {\n this.log.info(`'skipServerInstallation' is set. Attempting to use UIAutomator2 server from the device`);\n } else {\n this.log.info(`Starting UIAutomator2 server ${serverVersion}`);\n this.log.info(`Using UIAutomator2 server from '${apkPath}' and test from '${testApkPath}'`);\n }\n\n const timeout = caps.uiautomator2ServerLaunchTimeout || SERVER_LAUNCH_TIMEOUT;\n const timer = new timing.Timer().start();\n let retries = 0;\n const maxRetries = 2;\n const delayBetweenRetries = 3000;\n while (retries < maxRetries) {\n this.log.info(`Waiting up to ${timeout}ms for UiAutomator2 to be online...`);\n this.jwproxy.didInstrumentationExit = false;\n await this.startInstrumentationProcess();\n if (!this.jwproxy.didInstrumentationExit) {\n try {\n await waitForCondition(async () => {\n try {\n await this.jwproxy.command('/status', 'GET');\n return true;\n } catch (err) {\n // short circuit to retry or fail fast\n return this.jwproxy.didInstrumentationExit;\n }\n }, {\n waitMs: timeout,\n intervalMs: 1000,\n });\n } catch (err) {\n this.log.errorAndThrow(`The instrumentation process cannot be initialized within ${timeout}ms timeout. `\n + 'Make sure the application under test does not crash and investigate the logcat output. '\n + `You could also try to increase the value of 'uiautomator2ServerLaunchTimeout' capability`);\n }\n }\n if (!this.jwproxy.didInstrumentationExit) {\n break;\n }\n\n retries++;\n if (retries >= maxRetries) {\n this.log.errorAndThrow('The instrumentation process cannot be initialized. '\n + 'Make sure the application under test does not crash and investigate the logcat output.');\n }\n this.log.warn(`The instrumentation process has been unexpectedly terminated. `\n + `Retrying UiAutomator2 startup (#${retries} of ${maxRetries - 1})`);\n await this.cleanupAutomationLeftovers(true);\n await B.delay(delayBetweenRetries);\n }\n\n this.log.debug(`The initialization of the instrumentation process took `\n + `${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);\n await this.jwproxy.command('/session', 'POST', {\n capabilities: {\n firstMatch: [caps],\n alwaysMatch: {},\n }\n });\n }\n\n async startInstrumentationProcess () {\n const cmd = ['am', 'instrument', '-w'];\n if (this.disableWindowAnimation) {\n cmd.push('--no-window-animation');\n }\n if (_.isBoolean(this.disableSuppressAccessibilityService)) {\n cmd.push('-e', 'DISABLE_SUPPRESS_ACCESSIBILITY_SERVICES', this.disableSuppressAccessibilityService);\n }\n // Disable Google analytics to prevent possible fatal exception\n cmd.push('-e', 'disableAnalytics', true);\n cmd.push(INSTRUMENTATION_TARGET);\n const instrumentationProcess = this.adb.createSubProcess(['shell', ...cmd]);\n instrumentationProcess.on('output', (stdout, stderr) => {\n const output = _.trim(stdout || stderr);\n if (output) {\n instrumentationLogger.debug(output);\n }\n });\n instrumentationProcess.on('exit', (code) => {\n instrumentationLogger.debug(`The process has exited with code ${code}`);\n this.jwproxy.didInstrumentationExit = true;\n });\n await instrumentationProcess.start(0);\n }\n\n async deleteSession () {\n this.log.debug('Deleting UiAutomator2 server session');\n // rely on jwproxy's intelligence to know what we're talking about and\n // delete the current session\n try {\n await this.jwproxy.command('/', 'DELETE');\n } catch (err) {\n this.log.warn(`Did not get confirmation UiAutomator2 deleteSession worked; ` +\n `Error was: ${err}`);\n }\n }\n\n async cleanupAutomationLeftovers (strictCleanup = false) {\n this.log.debug(`Performing ${strictCleanup ? 'strict' : 'shallow'} cleanup of automation leftovers`);\n\n try {\n const {value} = (await axios({\n url: `http://${this.host}:${this.systemPort}/sessions`,\n timeout: 500,\n })).data;\n const activeSessionIds = value.map(({id}) => id).filter(Boolean);\n if (activeSessionIds.length) {\n this.log.debug(`The following obsolete sessions are still running: ${JSON.stringify(activeSessionIds)}`);\n this.log.debug(`Cleaning up ${util.pluralize('obsolete session', activeSessionIds.length, true)}`);\n await B.all(activeSessionIds\n .map((id) => axios.delete(`http://${this.host}:${this.systemPort}/session/${id}`))\n );\n // Let all sessions to be properly terminated before continuing\n await B.delay(1000);\n } else {\n this.log.debug('No obsolete sessions have been detected');\n }\n } catch (e) {\n this.log.debug(`No obsolete sessions have been detected (${e.message})`);\n }\n\n try {\n await this.adb.forceStop(SERVER_TEST_PACKAGE_ID);\n } catch (ignore) {}\n if (!strictCleanup) {\n return;\n }\n // https://github.com/appium/appium/issues/10749\n try {\n await this.adb.killProcessesByName('uiautomator');\n } catch (ignore) {}\n }\n}\n\nexport { UiAutomator2Server, INSTRUMENTATION_TARGET, SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID };\nexport default UiAutomator2Server;\n"],"mappings":"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"}