appium-uiautomator2-driver 2.26.3 → 2.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [2.28.0](https://github.com/appium/appium-uiautomator2-driver/compare/v2.27.0...v2.28.0) (2023-06-22)
2
+
3
+
4
+ ### Features
5
+
6
+ * Optimize server packages installation ([#631](https://github.com/appium/appium-uiautomator2-driver/issues/631)) ([ddfceab](https://github.com/appium/appium-uiautomator2-driver/commit/ddfceab31ac64afe67219537f7fe3f8d03bbfb28))
7
+
8
+ ## [2.27.0](https://github.com/appium/appium-uiautomator2-driver/compare/v2.26.3...v2.27.0) (2023-06-21)
9
+
10
+
11
+ ### Features
12
+
13
+ * add the description of setting API snapshotMaxDepth ([#629](https://github.com/appium/appium-uiautomator2-driver/issues/629)) ([c74ad63](https://github.com/appium/appium-uiautomator2-driver/commit/c74ad638af2bddd107bb774c76f2683acb7a8a07))
14
+
1
15
  ## [2.26.3](https://github.com/appium/appium-uiautomator2-driver/compare/v2.26.2...v2.26.3) (2023-06-21)
2
16
 
3
17
 
package/README.md CHANGED
@@ -289,6 +289,7 @@ enforceXPath1 | boolean | Since UiAutomator2 driver version `4.25.0` XPath2 is s
289
289
  limitXPathContextScope | boolean | Due to historical reasons UiAutomator2 driver limits scopes of element context-based searches to the parent element. This means a request like `findElement(By.xpath, "//root").findElement(By.xpath, "./..")` would always fail, because the driver only collects descendants of the `root` element for the destination XML source. The `limitXPathContextScope` setting being set to `false` changes that default behavior, so the collected page source includes the whole page source XML where `root` node is set as the search context. With that setting disabled the search query above should not fail anymore. Although, you must still be careful while building XPath requests for context-based searches with the `limitXPathContextScope` setting set to `false`. A request like `findElement(By.xpath, "//root").findElement(By.xpath, "//element")` would ignore the current context and search for `element` trough the whole page source. Use `.` notation to correct that behavior and only find `element` nodes which are descendants of the `root` node: `findElement(By.xpath, "//root").findElement(By.xpath, ".//element")`.
290
290
  disableIdLocatorAutocompletion | boolean | According to internal Android standards it is expected that each resource identifier is prefixed with `<packageName>:id/` string. This should guarantee uniqueness of each identifier. Although some application development frameworks ignore this rule and don't add such prefix automatically or, rather, let it up to the developer to decide how to represent their application identifiers. For example, [testTag modifier attribute in the Jetpack Compose](https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.Modifier).testTag(kotlin.String)) with [testTagsAsResourceId](https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).testTagsAsResourceId()) allows developers to set an arbitrary string without the prefix rule. [Interoperability with UiAutomator](https://developer.android.com/jetpack/compose/testing) also explains how to set it. By default UIA2 driver adds the above prefixes automatically to all resource id locators if they are not prefixed, but in case of such "special" apps this feature might be disabled by assigning the setting to `true`.
291
291
  includeExtrasInPageSource | boolean | Whether to include `extras` element attribute in the XML page source result. Then, XPath locator can find the element by the extras. Its value consists of combined [getExtras](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#getExtras()) as `keys=value` pair separated by a semicolon (`;`), thus you may need to find the element with partial matching like `contains` e.g. `driver.find_element :xpath, '//*[contains(@extras, "AccessibilityNodeInfo.roleDescription=")]'`. The value could be huge if elements in the XML page source have large `extras`. It could affect the performance of XML page source generation.
292
+ snapshotMaxDepth | int | The number of maximum depth for the source tree snapshot. The default value is `70`. This number should be in range [1, 500]. A part of the elements source tree might be lost if the value is too low. Also, StackOverflowError might be caused if the value is too high (Issues [12545](https://github.com/appium/appium/issues/12545), [12892](https://github.com/appium/appium/issues/12892)). The available driver version is `2.27.0` or higher.
292
293
 
293
294
 
294
295
  ## Platform-Specific Extensions
@@ -58,85 +58,83 @@ class UiAutomator2Server {
58
58
  this.proxyCommand = this.jwproxy.command.bind(this.jwproxy);
59
59
  this.jwproxy.didInstrumentationExit = false;
60
60
  }
61
- async installServerApk(installTimeout = SERVER_INSTALL_RETRIES * 1000) {
62
- const tmpRoot = await _support.tempDir.openDir();
63
- const packageInfosMapper = async ({
61
+ async prepareServerPackage(appPath, appId, tmpRoot) {
62
+ const resultInfo = {
63
+ wasSigned: false,
64
+ installState: this.adb.APP_INSTALL_STATE.NOT_INSTALLED,
64
65
  appPath,
65
66
  appId
66
- }) => {
67
- if (await _helpers.default.isWriteable(appPath)) {
68
- return {
69
- appPath,
70
- appId
71
- };
72
- }
73
- 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.`);
74
- const dstPath = _path.default.resolve(tmpRoot, _path.default.basename(appPath));
75
- await _support.fs.copyFile(appPath, dstPath);
76
- return {
77
- appPath: dstPath,
78
- appId
79
- };
80
67
  };
68
+ if (await this.adb.checkApkCert(resultInfo.appPath, appId)) {
69
+ resultInfo.wasSigned = true;
70
+ } else {
71
+ if (!(await _helpers.default.isWriteable(appPath))) {
72
+ this.log.warn(`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.`);
73
+ const dstPath = _path.default.resolve(tmpRoot, _path.default.basename(appPath));
74
+ await _support.fs.copyFile(appPath, dstPath);
75
+ resultInfo.appPath = dstPath;
76
+ }
77
+ await _helpers.default.signApp(this.adb, resultInfo.appPath);
78
+ }
79
+ if (appId === SERVER_TEST_PACKAGE_ID && (await this.adb.isAppInstalled(appId))) {
80
+ resultInfo.installState = this.adb.APP_INSTALL_STATE.SAME_VERSION_INSTALLED;
81
+ } else if (appId === SERVER_PACKAGE_ID) {
82
+ resultInfo.installState = await this.adb.getApplicationInstallState(resultInfo.appPath, appId);
83
+ }
84
+ return resultInfo;
85
+ }
86
+ async installServerApk(installTimeout = SERVER_INSTALL_RETRIES * 1000) {
87
+ const tmpRoot = await _support.tempDir.openDir();
81
88
  try {
82
- const packagesInfo = await _bluebird.default.all(_bluebird.default.map([{
89
+ const packagesInfo = await _bluebird.default.all([{
83
90
  appPath: _appiumUiautomator2Server.SERVER_APK_PATH,
84
91
  appId: SERVER_PACKAGE_ID
85
92
  }, {
86
93
  appPath: _appiumUiautomator2Server.TEST_APK_PATH,
87
94
  appId: SERVER_TEST_PACKAGE_ID
88
- }], packageInfosMapper));
89
- let shouldUninstallServerPackages = false;
90
- let shouldInstallServerPackages = false;
91
- for (const {
92
- appId,
93
- appPath
94
- } of packagesInfo) {
95
- if (appId === SERVER_TEST_PACKAGE_ID) {
96
- const isAppInstalled = await this.adb.isAppInstalled(appId);
97
- if (!(await this.adb.checkApkCert(appPath, appId))) {
98
- await _helpers.default.signApp(this.adb, appPath);
99
- shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;
100
- shouldInstallServerPackages = true;
101
- }
102
- if (!isAppInstalled) {
103
- shouldInstallServerPackages = true;
104
- }
105
- continue;
106
- }
107
- const appState = await this.adb.getApplicationInstallState(appPath, appId);
108
- this.log.debug(`${appId} installation state: ${appState}`);
109
- if (await this.adb.checkApkCert(appPath, appId)) {
110
- shouldUninstallServerPackages = shouldUninstallServerPackages || [this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED, this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED].includes(appState);
111
- } else {
112
- await _helpers.default.signApp(this.adb, appPath);
113
- shouldUninstallServerPackages = shouldUninstallServerPackages || ![this.adb.APP_INSTALL_STATE.NOT_INSTALLED].includes(appState);
114
- }
115
- shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [this.adb.APP_INSTALL_STATE.NOT_INSTALLED].includes(appState);
116
- }
95
+ }].map(({
96
+ appPath,
97
+ appId
98
+ }) => this.prepareServerPackage(appPath, appId, tmpRoot)));
99
+ this.log.debug(`Server packages status: ${JSON.stringify(packagesInfo)}`);
100
+ const shouldUninstallServerPackages = packagesInfo.some(({
101
+ wasSigned
102
+ }) => !wasSigned) || packagesInfo.some(({
103
+ installState
104
+ }) => installState === this.adb.APP_INSTALL_STATE.NOT_INSTALLED) && !packagesInfo.every(({
105
+ installState
106
+ }) => installState === this.adb.APP_INSTALL_STATE.NOT_INSTALLED);
107
+ const shouldInstallServerPackages = shouldUninstallServerPackages || packagesInfo.some(({
108
+ installState
109
+ }) => [this.adb.APP_INSTALL_STATE.NOT_INSTALLED, this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED].includes(installState));
117
110
  this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);
118
111
  if (shouldInstallServerPackages && shouldUninstallServerPackages) {
119
112
  this.log.info('Full packages reinstall is going to be performed');
120
113
  }
121
- for (const {
122
- appId,
123
- appPath
124
- } of packagesInfo) {
125
- if (shouldUninstallServerPackages) {
114
+ if (shouldUninstallServerPackages) {
115
+ const silentUninstallPkg = async pkgId => {
126
116
  try {
127
- await this.adb.uninstallApk(appId);
117
+ await this.adb.uninstallApk(pkgId);
128
118
  } catch (err) {
129
- this.log.warn(`Error uninstalling '${appId}': ${err.message}`);
119
+ this.log.info(`Cannot uninstall '${pkgId}': ${err.message}`);
130
120
  }
131
- }
132
- if (shouldInstallServerPackages) {
133
- await this.adb.install(appPath, {
121
+ };
122
+ await _bluebird.default.all(packagesInfo.map(({
123
+ appId
124
+ }) => silentUninstallPkg(appId)));
125
+ }
126
+ if (shouldInstallServerPackages) {
127
+ const installPkg = async pkgPath => {
128
+ await this.adb.install(pkgPath, {
134
129
  noIncremental: true,
135
130
  replace: true,
136
131
  timeout: installTimeout,
137
132
  timeoutCapName: 'uiautomator2ServerInstallTimeout'
138
133
  });
139
- }
134
+ };
135
+ await _bluebird.default.all(packagesInfo.map(({
136
+ appPath
137
+ }) => installPkg(appPath)));
140
138
  }
141
139
  } finally {
142
140
  await _support.fs.rimraf(tmpRoot);
@@ -305,4 +303,4 @@ class UiAutomator2Server {
305
303
  exports.UiAutomator2Server = UiAutomator2Server;
306
304
  var _default = UiAutomator2Server;
307
305
  exports.default = _default;
308
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZHJpdmVyIiwiX2FzeW5jYm94IiwiX2FwcGl1bVVpYXV0b21hdG9yMlNlcnZlciIsIl9zdXBwb3J0IiwiX2JsdWViaXJkIiwiX2hlbHBlcnMiLCJfYXhpb3MiLCJfcGF0aCIsIlJFUURfUEFSQU1TIiwiU0VSVkVSX0xBVU5DSF9USU1FT1VUIiwiU0VSVkVSX0lOU1RBTExfUkVUUklFUyIsIlNFUlZJQ0VTX0xBVU5DSF9USU1FT1VUIiwiU0VSVkVSX1BBQ0tBR0VfSUQiLCJleHBvcnRzIiwiU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCIsIklOU1RSVU1FTlRBVElPTl9UQVJHRVQiLCJpbnN0cnVtZW50YXRpb25Mb2dnZXIiLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJVSUEyUHJveHkiLCJKV1Byb3h5IiwicHJveHlDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImRpZEluc3RydW1lbnRhdGlvbkV4aXQiLCJlcnJvcnMiLCJJbnZhbGlkQ29udGV4dEVycm9yIiwiVWlBdXRvbWF0b3IyU2VydmVyIiwiY29uc3RydWN0b3IiLCJsb2ciLCJvcHRzIiwicmVxIiwidXRpbCIsImhhc1ZhbHVlIiwiRXJyb3IiLCJkaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSIsInByb3h5T3B0cyIsInNlcnZlciIsImhvc3QiLCJwb3J0Iiwic3lzdGVtUG9ydCIsImtlZXBBbGl2ZSIsInJlYWRUaW1lb3V0IiwidGltZW91dCIsImp3cHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJjb21tYW5kIiwiaW5zdGFsbFNlcnZlckFwayIsImluc3RhbGxUaW1lb3V0IiwidG1wUm9vdCIsInRlbXBEaXIiLCJvcGVuRGlyIiwicGFja2FnZUluZm9zTWFwcGVyIiwiYXBwUGF0aCIsImFwcElkIiwiaGVscGVycyIsImlzV3JpdGVhYmxlIiwiaW5mbyIsImRzdFBhdGgiLCJwYXRoIiwicmVzb2x2ZSIsImJhc2VuYW1lIiwiZnMiLCJjb3B5RmlsZSIsInBhY2thZ2VzSW5mbyIsIkIiLCJhbGwiLCJtYXAiLCJhcGtQYXRoIiwidGVzdEFwa1BhdGgiLCJzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsInNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsImlzQXBwSW5zdGFsbGVkIiwiYWRiIiwiY2hlY2tBcGtDZXJ0Iiwic2lnbkFwcCIsImFwcFN0YXRlIiwiZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUiLCJkZWJ1ZyIsIkFQUF9JTlNUQUxMX1NUQVRFIiwiT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQiLCJORVdFUl9WRVJTSU9OX0lOU1RBTExFRCIsImluY2x1ZGVzIiwiTk9UX0lOU1RBTExFRCIsInVuaW5zdGFsbEFwayIsImVyciIsIndhcm4iLCJtZXNzYWdlIiwiaW5zdGFsbCIsIm5vSW5jcmVtZW50YWwiLCJyZXBsYWNlIiwidGltZW91dENhcE5hbWUiLCJyaW1yYWYiLCJ2ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSIsImlzUG1TZXJ2aWNlQXZhaWxhYmxlIiwicG1PdXRwdXQiLCJwbUVycm9yIiwid2FpdEZvckNvbmRpdGlvbiIsInNoZWxsIiwiZSIsIndhaXRNcyIsImludGVydmFsTXMiLCJlcnJvciIsImxpbmUiLCJzcGxpdCIsInN0YXJ0U2Vzc2lvbiIsImNhcHMiLCJjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyIsInNraXBTZXJ2ZXJJbnN0YWxsYXRpb24iLCJzZXJ2ZXJWZXJzaW9uIiwidWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCIsInRpbWVyIiwidGltaW5nIiwiVGltZXIiLCJzdGFydCIsInJldHJpZXMiLCJtYXhSZXRyaWVzIiwiZGVsYXlCZXR3ZWVuUmV0cmllcyIsInN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImVycm9yQW5kVGhyb3ciLCJkZWxheSIsImdldER1cmF0aW9uIiwiYXNNaWxsaVNlY29uZHMiLCJ0b0ZpeGVkIiwiY2FwYWJpbGl0aWVzIiwiZmlyc3RNYXRjaCIsImFsd2F5c01hdGNoIiwiY21kIiwiZGlzYWJsZVdpbmRvd0FuaW1hdGlvbiIsInB1c2giLCJfIiwiaXNCb29sZWFuIiwiaW5zdHJ1bWVudGF0aW9uUHJvY2VzcyIsImNyZWF0ZVN1YlByb2Nlc3MiLCJvbiIsInN0ZG91dCIsInN0ZGVyciIsIm91dHB1dCIsInRyaW0iLCJjb2RlIiwiZGVsZXRlU2Vzc2lvbiIsInN0cmljdENsZWFudXAiLCJ2YWx1ZSIsImF4aW9zIiwiZGF0YSIsImFjdGl2ZVNlc3Npb25JZHMiLCJpZCIsImZpbHRlciIsIkJvb2xlYW4iLCJsZW5ndGgiLCJKU09OIiwic3RyaW5naWZ5IiwicGx1cmFsaXplIiwiZGVsZXRlIiwiZm9yY2VTdG9wIiwiaWdub3JlIiwia2lsbFByb2Nlc3Nlc0J5TmFtZSIsIl9kZWZhdWx0IiwiZGVmYXVsdCJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91aWF1dG9tYXRvcjIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEpXUHJveHksIGVycm9ycyB9IGZyb20gJ2FwcGl1bS9kcml2ZXInO1xuaW1wb3J0IHsgd2FpdEZvckNvbmRpdGlvbiB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7XG4gIFNFUlZFUl9BUEtfUEFUSCBhcyBhcGtQYXRoLFxuICBURVNUX0FQS19QQVRIIGFzIHRlc3RBcGtQYXRoLFxuICB2ZXJzaW9uIGFzIHNlcnZlclZlcnNpb25cbn0gZnJvbSAnYXBwaXVtLXVpYXV0b21hdG9yMi1zZXJ2ZXInO1xuaW1wb3J0IHtcbiAgdXRpbCwgbG9nZ2VyLCB0ZW1wRGlyLCBmcywgdGltaW5nXG59IGZyb20gJ2FwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IFJFUURfUEFSQU1TID0gWydhZGInLCAndG1wRGlyJywgJ2hvc3QnLCAnc3lzdGVtUG9ydCcsICdkZXZpY2VQb3J0JywgJ2Rpc2FibGVXaW5kb3dBbmltYXRpb24nXTtcbmNvbnN0IFNFUlZFUl9MQVVOQ0hfVElNRU9VVCA9IDMwMDAwO1xuY29uc3QgU0VSVkVSX0lOU1RBTExfUkVUUklFUyA9IDIwO1xuY29uc3QgU0VSVklDRVNfTEFVTkNIX1RJTUVPVVQgPSAzMDAwMDtcbmNvbnN0IFNFUlZFUl9QQUNLQUdFX0lEID0gJ2lvLmFwcGl1bS51aWF1dG9tYXRvcjIuc2VydmVyJztcbmNvbnN0IFNFUlZFUl9URVNUX1BBQ0tBR0VfSUQgPSBgJHtTRVJWRVJfUEFDS0FHRV9JRH0udGVzdGA7XG5jb25zdCBJTlNUUlVNRU5UQVRJT05fVEFSR0VUID0gYCR7U0VSVkVSX1RFU1RfUEFDS0FHRV9JRH0vYW5kcm9pZHgudGVzdC5ydW5uZXIuQW5kcm9pZEpVbml0UnVubmVyYDtcbmNvbnN0IGluc3RydW1lbnRhdGlvbkxvZ2dlciA9IGxvZ2dlci5nZXRMb2dnZXIoJ0luc3RydW1lbnRhdGlvbicpO1xuXG5jbGFzcyBVSUEyUHJveHkgZXh0ZW5kcyBKV1Byb3h5IHtcbiAgYXN5bmMgcHJveHlDb21tYW5kICh1cmwsIG1ldGhvZCwgYm9keSA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRDb250ZXh0RXJyb3IoXG4gICAgICAgIGAnJHttZXRob2R9ICR7dXJsfScgY2Fubm90IGJlIHByb3hpZWQgdG8gVWlBdXRvbWF0b3IyIHNlcnZlciBiZWNhdXNlIGAgK1xuICAgICAgICAndGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGlzIG5vdCBydW5uaW5nIChwcm9iYWJseSBjcmFzaGVkKS4gJyArXG4gICAgICAgICdDaGVjayB0aGUgc2VydmVyIGxvZyBhbmQvb3IgdGhlIGxvZ2NhdCBvdXRwdXQgZm9yIG1vcmUgZGV0YWlscycpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgc3VwZXIucHJveHlDb21tYW5kKHVybCwgbWV0aG9kLCBib2R5KTtcbiAgfVxufVxuXG5jbGFzcyBVaUF1dG9tYXRvcjJTZXJ2ZXIge1xuICBjb25zdHJ1Y3RvciAobG9nLCBvcHRzID0ge30pIHtcbiAgICBmb3IgKGxldCByZXEgb2YgUkVRRF9QQVJBTVMpIHtcbiAgICAgIGlmICghb3B0cyB8fCAhdXRpbC5oYXNWYWx1ZShvcHRzW3JlcV0pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgT3B0aW9uICcke3JlcX0nIGlzIHJlcXVpcmVkIWApO1xuICAgICAgfVxuICAgICAgdGhpc1tyZXFdID0gb3B0c1tyZXFdO1xuICAgIH1cbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgICB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlID0gb3B0cy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZTtcbiAgICBjb25zdCBwcm94eU9wdHMgPSB7XG4gICAgICBsb2csXG4gICAgICBzZXJ2ZXI6IHRoaXMuaG9zdCxcbiAgICAgIHBvcnQ6IHRoaXMuc3lzdGVtUG9ydCxcbiAgICAgIGtlZXBBbGl2ZTogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChvcHRzLnJlYWRUaW1lb3V0ICYmIG9wdHMucmVhZFRpbWVvdXQgPiAwKSB7XG4gICAgICBwcm94eU9wdHMudGltZW91dCA9IG9wdHMucmVhZFRpbWVvdXQ7XG4gICAgfVxuICAgIHRoaXMuandwcm94eSA9IG5ldyBVSUEyUHJveHkocHJveHlPcHRzKTtcbiAgICB0aGlzLnByb3h5UmVxUmVzID0gdGhpcy5qd3Byb3h5LnByb3h5UmVxUmVzLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuandwcm94eS5jb21tYW5kLmJpbmQodGhpcy5qd3Byb3h5KTtcbiAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHRoZSBhcGtzIG9uIHRvIHRoZSBkZXZpY2Ugb3IgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbnN0YWxsVGltZW91dCAtIEluc3RhbGxhdGlvbiB0aW1lb3V0XG4gICAqL1xuICBhc3luYyBpbnN0YWxsU2VydmVyQXBrIChpbnN0YWxsVGltZW91dCA9IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgKiAxMDAwKSB7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIGNvbnN0IHBhY2thZ2VJbmZvc01hcHBlciA9IGFzeW5jICh7YXBwUGF0aCwgYXBwSWR9KSA9PiB7XG4gICAgICBpZiAoYXdhaXQgaGVscGVycy5pc1dyaXRlYWJsZShhcHBQYXRoKSkge1xuICAgICAgICByZXR1cm4geyBhcHBQYXRoLCBhcHBJZCB9O1xuICAgICAgfVxuXG4gICAgICB0aGlzLmxvZy5pbmZvKGBTZXJ2ZXIgcGFja2FnZSBhdCAnJHthcHBQYXRofScgaXMgbm90IHdyaXRlYWJsZS4gYCArXG4gICAgICAgIGBXaWxsIGNvcHkgaXQgaW50byB0aGUgdGVtcG9yYXJ5IGxvY2F0aW9uIGF0ICcke3RtcFJvb3R9JyBhcyBhIHdvcmthcm91bmQuIGAgK1xuICAgICAgICBgQ29uc2lkZXIgbWFraW5nIHRoaXMgZmlsZSB3cml0ZWFibGUgbWFudWFsbHkgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygc2Vzc2lvbiBzdGFydHVwLmApO1xuICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLmJhc2VuYW1lKGFwcFBhdGgpKTtcbiAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKGFwcFBhdGgsIGRzdFBhdGgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXBwUGF0aDogZHN0UGF0aCxcbiAgICAgICAgYXBwSWQsXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFja2FnZXNJbmZvID0gYXdhaXQgQi5hbGwoQi5tYXAoW1xuICAgICAgICB7XG4gICAgICAgICAgYXBwUGF0aDogYXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1BBQ0tBR0VfSUQsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBhcHBQYXRoOiB0ZXN0QXBrUGF0aCxcbiAgICAgICAgICBhcHBJZDogU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCxcbiAgICAgICAgfSxcbiAgICAgIF0sIHBhY2thZ2VJbmZvc01hcHBlcikpO1xuXG4gICAgICBsZXQgc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGxldCBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSBmYWxzZTtcbiAgICAgIGZvciAoY29uc3Qge2FwcElkLCBhcHBQYXRofSBvZiBwYWNrYWdlc0luZm8pIHtcbiAgICAgICAgaWYgKGFwcElkID09PSBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKSB7XG4gICAgICAgICAgY29uc3QgaXNBcHBJbnN0YWxsZWQgPSBhd2FpdCB0aGlzLmFkYi5pc0FwcEluc3RhbGxlZChhcHBJZCk7XG5cbiAgICAgICAgICAvLyBUaGVyZSBpcyBubyBwb2ludCBpbiBnZXR0aW5nIHRoZSBzdGF0ZSBmb3IgdGVzdCBzZXJ2ZXIsXG4gICAgICAgICAgLy8gc2luY2UgaXQgZG9lcyBub3QgY29udGFpbiB2ZXJzaW9uIGluZm9cbiAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMuYWRiLmNoZWNrQXBrQ2VydChhcHBQYXRoLCBhcHBJZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IGhlbHBlcnMuc2lnbkFwcCh0aGlzLmFkYiwgYXBwUGF0aCk7XG4gICAgICAgICAgICBzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyA9IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IGlzQXBwSW5zdGFsbGVkO1xuICAgICAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWlzQXBwSW5zdGFsbGVkKSB7XG4gICAgICAgICAgICBzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcFN0YXRlID0gYXdhaXQgdGhpcy5hZGIuZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUoYXBwUGF0aCwgYXBwSWQpO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgJHthcHBJZH0gaW5zdGFsbGF0aW9uIHN0YXRlOiAke2FwcFN0YXRlfWApO1xuICAgICAgICBpZiAoYXdhaXQgdGhpcy5hZGIuY2hlY2tBcGtDZXJ0KGFwcFBhdGgsIGFwcElkKSkge1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgW1xuICAgICAgICAgICAgdGhpcy5hZGIuQVBQX0lOU1RBTExfU1RBVEUuT0xERVJfVkVSU0lPTl9JTlNUQUxMRUQsXG4gICAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5ORVdFUl9WRVJTSU9OX0lOU1RBTExFRCxcbiAgICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCBoZWxwZXJzLnNpZ25BcHAodGhpcy5hZGIsIGFwcFBhdGgpO1xuICAgICAgICAgIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgIVtcbiAgICAgICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICAgICAgXS5pbmNsdWRlcyhhcHBTdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzIHx8IFtcbiAgICAgICAgICB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5OT1RfSU5TVEFMTEVELFxuICAgICAgICBdLmluY2x1ZGVzKGFwcFN0YXRlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLmluZm8oYFNlcnZlciBwYWNrYWdlcyBhcmUgJHtzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPyAnJyA6ICdub3QgJ31nb2luZyB0byBiZSAocmUpaW5zdGFsbGVkYCk7XG4gICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzICYmIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0Z1bGwgcGFja2FnZXMgcmVpbnN0YWxsIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm1lZCcpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB7YXBwSWQsIGFwcFBhdGh9IG9mIHBhY2thZ2VzSW5mbykge1xuICAgICAgICBpZiAoc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hZGIudW5pbnN0YWxsQXBrKGFwcElkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMubG9nLndhcm4oYEVycm9yIHVuaW5zdGFsbGluZyAnJHthcHBJZH0nOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5hZGIuaW5zdGFsbChhcHBQYXRoLCB7XG4gICAgICAgICAgICBub0luY3JlbWVudGFsOiB0cnVlLFxuICAgICAgICAgICAgcmVwbGFjZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpbWVvdXQ6IGluc3RhbGxUaW1lb3V0LFxuICAgICAgICAgICAgdGltZW91dENhcE5hbWU6ICd1aWF1dG9tYXRvcjJTZXJ2ZXJJbnN0YWxsVGltZW91dCdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBmcy5yaW1yYWYodG1wUm9vdCk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy52ZXJpZnlTZXJ2aWNlc0F2YWlsYWJpbGl0eSgpO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5U2VydmljZXNBdmFpbGFiaWxpdHkgKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKGBXYWl0aW5nIHVwIHRvICR7U0VSVklDRVNfTEFVTkNIX1RJTUVPVVR9bXMgZm9yIHNlcnZpY2VzIHRvIGJlIGF2YWlsYWJsZWApO1xuICAgIGxldCBpc1BtU2VydmljZUF2YWlsYWJsZSA9IGZhbHNlO1xuICAgIGxldCBwbU91dHB1dCA9ICcnO1xuICAgIGxldCBwbUVycm9yID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghaXNQbVNlcnZpY2VBdmFpbGFibGUpIHtcbiAgICAgICAgICBwbUVycm9yID0gbnVsbDtcbiAgICAgICAgICBwbU91dHB1dCA9ICcnO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwbU91dHB1dCA9IGF3YWl0IHRoaXMuYWRiLnNoZWxsKFsncG0nLCAnbGlzdCcsICdpbnN0cnVtZW50YXRpb24nXSk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcG1FcnJvciA9IGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwbU91dHB1dC5pbmNsdWRlcygnQ291bGQgbm90IGFjY2VzcyB0aGUgUGFja2FnZSBNYW5hZ2VyJykpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoYFByb2JsZW0gcnVubmluZyBQYWNrYWdlIE1hbmFnZXI6ICR7cG1PdXRwdXR9YCk7XG4gICAgICAgICAgICBwbU91dHB1dCA9ICcnOyAvLyByZW1vdmUgb3V0cHV0LCBzbyBpdCBpcyBub3QgcHJpbnRlZCBiZWxvd1xuICAgICAgICAgIH0gZWxzZSBpZiAocG1PdXRwdXQuaW5jbHVkZXMoSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCkpIHtcbiAgICAgICAgICAgIHBtT3V0cHV0ID0gJyc7IC8vIHJlbW92ZSBvdXRwdXQsIHNvIGl0IGlzIG5vdCBwcmludGVkIGJlbG93XG4gICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgSW5zdHJ1bWVudGF0aW9uIHRhcmdldCAnJHtJTlNUUlVNRU5UQVRJT05fVEFSR0VUfScgaXMgYXZhaWxhYmxlYCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlc1xuICAgICAgICAgICAgaXNQbVNlcnZpY2VBdmFpbGFibGUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIXBtRXJyb3IpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBpbnN0cnVtZW50YXRpb24gdGFyZ2V0IGlzIG5vdCBsaXN0ZWQgYnkgUGFja2FnZSBNYW5hZ2VyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc1BtU2VydmljZUF2YWlsYWJsZTtcbiAgICAgIH0sIHtcbiAgICAgICAgd2FpdE1zOiBTRVJWSUNFU19MQVVOQ0hfVElNRU9VVCxcbiAgICAgICAgaW50ZXJ2YWxNczogMTAwMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoYFVuYWJsZSB0byBmaW5kIGluc3RydW1lbnRhdGlvbiB0YXJnZXQgJyR7SU5TVFJVTUVOVEFUSU9OX1RBUkdFVH0nOiAkeyhwbUVycm9yIHx8IHt9KS5tZXNzYWdlfWApO1xuICAgICAgaWYgKHBtT3V0cHV0KSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdBdmFpbGFibGUgdGFyZ2V0czonKTtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIHBtT3V0cHV0LnNwbGl0KCdcXG4nKSkge1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKGAgICAgJHtsaW5lLnJlcGxhY2UoJ2luc3RydW1lbnRhdGlvbjonLCAnJyl9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzdGFydFNlc3Npb24gKGNhcHMpIHtcbiAgICBhd2FpdCB0aGlzLmNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzKCk7XG4gICAgaWYgKGNhcHMuc2tpcFNlcnZlckluc3RhbGxhdGlvbikge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgJ3NraXBTZXJ2ZXJJbnN0YWxsYXRpb24nIGlzIHNldC4gQXR0ZW1wdGluZyB0byB1c2UgVUlBdXRvbWF0b3IyIHNlcnZlciBmcm9tIHRoZSBkZXZpY2VgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgU3RhcnRpbmcgVUlBdXRvbWF0b3IyIHNlcnZlciAke3NlcnZlclZlcnNpb259YCk7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBVc2luZyBVSUF1dG9tYXRvcjIgc2VydmVyIGZyb20gJyR7YXBrUGF0aH0nIGFuZCB0ZXN0IGZyb20gJyR7dGVzdEFwa1BhdGh9J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVvdXQgPSBjYXBzLnVpYXV0b21hdG9yMlNlcnZlckxhdW5jaFRpbWVvdXQgfHwgU0VSVkVSX0xBVU5DSF9USU1FT1VUO1xuICAgIGNvbnN0IHRpbWVyID0gbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCk7XG4gICAgbGV0IHJldHJpZXMgPSAwO1xuICAgIGNvbnN0IG1heFJldHJpZXMgPSAyO1xuICAgIGNvbnN0IGRlbGF5QmV0d2VlblJldHJpZXMgPSAzMDAwO1xuICAgIHdoaWxlIChyZXRyaWVzIDwgbWF4UmV0cmllcykge1xuICAgICAgdGhpcy5sb2cuaW5mbyhgV2FpdGluZyB1cCB0byAke3RpbWVvdXR9bXMgZm9yIFVpQXV0b21hdG9yMiB0byBiZSBvbmxpbmUuLi5gKTtcbiAgICAgIHRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcygpO1xuICAgICAgaWYgKCF0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgIC8vIHNob3J0IGNpcmN1aXQgdG8gcmV0cnkgb3IgZmFpbCBmYXN0XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCB7XG4gICAgICAgICAgICB3YWl0TXM6IHRpbWVvdXQsXG4gICAgICAgICAgICBpbnRlcnZhbE1zOiAxMDAwLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBUaGUgaW5zdHJ1bWVudGF0aW9uIHByb2Nlc3MgY2Fubm90IGJlIGluaXRpYWxpemVkIHdpdGhpbiAke3RpbWVvdXR9bXMgdGltZW91dC4gYFxuICAgICAgICAgICAgKyAnTWFrZSBzdXJlIHRoZSBhcHBsaWNhdGlvbiB1bmRlciB0ZXN0IGRvZXMgbm90IGNyYXNoIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgbG9nY2F0IG91dHB1dC4gJ1xuICAgICAgICAgICAgKyBgWW91IGNvdWxkIGFsc28gdHJ5IHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiAndWlhdXRvbWF0b3IyU2VydmVyTGF1bmNoVGltZW91dCcgY2FwYWJpbGl0eWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuandwcm94eS5kaWRJbnN0cnVtZW50YXRpb25FeGl0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXRyaWVzKys7XG4gICAgICBpZiAocmV0cmllcyA+PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coJ1RoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBjYW5ub3QgYmUgaW5pdGlhbGl6ZWQuICdcbiAgICAgICAgICArICdNYWtlIHN1cmUgdGhlIGFwcGxpY2F0aW9uIHVuZGVyIHRlc3QgZG9lcyBub3QgY3Jhc2ggYW5kIGludmVzdGlnYXRlIHRoZSBsb2djYXQgb3V0cHV0LicpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihgVGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGhhcyBiZWVuIHVuZXhwZWN0ZWRseSB0ZXJtaW5hdGVkLiBgXG4gICAgICAgICsgYFJldHJ5aW5nIFVpQXV0b21hdG9yMiBzdGFydHVwICgjJHtyZXRyaWVzfSBvZiAke21heFJldHJpZXMgLSAxfSlgKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xlYW51cEF1dG9tYXRpb25MZWZ0b3ZlcnModHJ1ZSk7XG4gICAgICBhd2FpdCBCLmRlbGF5KGRlbGF5QmV0d2VlblJldHJpZXMpO1xuICAgIH1cblxuICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIHRvb2sgYFxuICAgICAgKyBgJHt0aW1lci5nZXREdXJhdGlvbigpLmFzTWlsbGlTZWNvbmRzLnRvRml4ZWQoMCl9bXNgKTtcbiAgICBhd2FpdCB0aGlzLmp3cHJveHkuY29tbWFuZCgnL3Nlc3Npb24nLCAnUE9TVCcsIHtcbiAgICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgICBmaXJzdE1hdGNoOiBbY2Fwc10sXG4gICAgICAgIGFsd2F5c01hdGNoOiB7fSxcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0SW5zdHJ1bWVudGF0aW9uUHJvY2VzcyAoKSB7XG4gICAgY29uc3QgY21kID0gWydhbScsICdpbnN0cnVtZW50JywgJy13J107XG4gICAgaWYgKHRoaXMuZGlzYWJsZVdpbmRvd0FuaW1hdGlvbikge1xuICAgICAgY21kLnB1c2goJy0tbm8td2luZG93LWFuaW1hdGlvbicpO1xuICAgIH1cbiAgICBpZiAoXy5pc0Jvb2xlYW4odGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSkpIHtcbiAgICAgIGNtZC5wdXNoKCctZScsICdESVNBQkxFX1NVUFBSRVNTX0FDQ0VTU0lCSUxJVFlfU0VSVklDRVMnLCB0aGlzLmRpc2FibGVTdXBwcmVzc0FjY2Vzc2liaWxpdHlTZXJ2aWNlKTtcbiAgICB9XG4gICAgLy8gRGlzYWJsZSBHb29nbGUgYW5hbHl0aWNzIHRvIHByZXZlbnQgcG9zc2libGUgZmF0YWwgZXhjZXB0aW9uXG4gICAgY21kLnB1c2goJy1lJywgJ2Rpc2FibGVBbmFseXRpY3MnLCB0cnVlKTtcbiAgICBjbWQucHVzaChJTlNUUlVNRU5UQVRJT05fVEFSR0VUKTtcbiAgICBjb25zdCBpbnN0cnVtZW50YXRpb25Qcm9jZXNzID0gdGhpcy5hZGIuY3JlYXRlU3ViUHJvY2VzcyhbJ3NoZWxsJywgLi4uY21kXSk7XG4gICAgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5vbignb3V0cHV0JywgKHN0ZG91dCwgc3RkZXJyKSA9PiB7XG4gICAgICBjb25zdCBvdXRwdXQgPSBfLnRyaW0oc3Rkb3V0IHx8IHN0ZGVycik7XG4gICAgICBpZiAob3V0cHV0KSB7XG4gICAgICAgIGluc3RydW1lbnRhdGlvbkxvZ2dlci5kZWJ1ZyhvdXRwdXQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGluc3RydW1lbnRhdGlvblByb2Nlc3Mub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgICAgaW5zdHJ1bWVudGF0aW9uTG9nZ2VyLmRlYnVnKGBUaGUgcHJvY2VzcyBoYXMgZXhpdGVkIHdpdGggY29kZSAke2NvZGV9YCk7XG4gICAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IHRydWU7XG4gICAgfSk7XG4gICAgYXdhaXQgaW5zdHJ1bWVudGF0aW9uUHJvY2Vzcy5zdGFydCgwKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZVNlc3Npb24gKCkge1xuICAgIHRoaXMubG9nLmRlYnVnKCdEZWxldGluZyBVaUF1dG9tYXRvcjIgc2VydmVyIHNlc3Npb24nKTtcbiAgICAvLyByZWx5IG9uIGp3cHJveHkncyBpbnRlbGxpZ2VuY2UgdG8ga25vdyB3aGF0IHdlJ3JlIHRhbGtpbmcgYWJvdXQgYW5kXG4gICAgLy8gZGVsZXRlIHRoZSBjdXJyZW50IHNlc3Npb25cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy8nLCAnREVMRVRFJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmxvZy53YXJuKGBEaWQgbm90IGdldCBjb25maXJtYXRpb24gVWlBdXRvbWF0b3IyIGRlbGV0ZVNlc3Npb24gd29ya2VkOyBgICtcbiAgICAgICAgICBgRXJyb3Igd2FzOiAke2Vycn1gKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycyAoc3RyaWN0Q2xlYW51cCA9IGZhbHNlKSB7XG4gICAgdGhpcy5sb2cuZGVidWcoYFBlcmZvcm1pbmcgJHtzdHJpY3RDbGVhbnVwID8gJ3N0cmljdCcgOiAnc2hhbGxvdyd9IGNsZWFudXAgb2YgYXV0b21hdGlvbiBsZWZ0b3ZlcnNgKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7dmFsdWV9ID0gKGF3YWl0IGF4aW9zKHtcbiAgICAgICAgdXJsOiBgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbnNgLFxuICAgICAgICB0aW1lb3V0OiA1MDAsXG4gICAgICB9KSkuZGF0YTtcbiAgICAgIGNvbnN0IGFjdGl2ZVNlc3Npb25JZHMgPSB2YWx1ZS5tYXAoKHtpZH0pID0+IGlkKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgICBpZiAoYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBmb2xsb3dpbmcgb2Jzb2xldGUgc2Vzc2lvbnMgYXJlIHN0aWxsIHJ1bm5pbmc6ICR7SlNPTi5zdHJpbmdpZnkoYWN0aXZlU2Vzc2lvbklkcyl9YCk7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBDbGVhbmluZyB1cCAke3V0aWwucGx1cmFsaXplKCdvYnNvbGV0ZSBzZXNzaW9uJywgYWN0aXZlU2Vzc2lvbklkcy5sZW5ndGgsIHRydWUpfWApO1xuICAgICAgICBhd2FpdCBCLmFsbChhY3RpdmVTZXNzaW9uSWRzXG4gICAgICAgICAgLm1hcCgoaWQpID0+IGF4aW9zLmRlbGV0ZShgaHR0cDovLyR7dGhpcy5ob3N0fToke3RoaXMuc3lzdGVtUG9ydH0vc2Vzc2lvbi8ke2lkfWApKVxuICAgICAgICApO1xuICAgICAgICAvLyBMZXQgYWxsIHNlc3Npb25zIHRvIGJlIHByb3Blcmx5IHRlcm1pbmF0ZWQgYmVmb3JlIGNvbnRpbnVpbmdcbiAgICAgICAgYXdhaXQgQi5kZWxheSgxMDAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKCdObyBvYnNvbGV0ZSBzZXNzaW9ucyBoYXZlIGJlZW4gZGV0ZWN0ZWQnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgTm8gb2Jzb2xldGUgc2Vzc2lvbnMgaGF2ZSBiZWVuIGRldGVjdGVkICgke2UubWVzc2FnZX0pYCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLmZvcmNlU3RvcChTRVJWRVJfVEVTVF9QQUNLQUdFX0lEKTtcbiAgICB9IGNhdGNoIChpZ25vcmUpIHt9XG4gICAgaWYgKCFzdHJpY3RDbGVhbnVwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hcHBpdW0vYXBwaXVtL2lzc3Vlcy8xMDc0OVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5raWxsUHJvY2Vzc2VzQnlOYW1lKCd1aWF1dG9tYXRvcicpO1xuICAgIH0gY2F0Y2ggKGlnbm9yZSkge31cbiAgfVxufVxuXG5leHBvcnQgeyBVaUF1dG9tYXRvcjJTZXJ2ZXIsIElOU1RSVU1FTlRBVElPTl9UQVJHRVQsIFNFUlZFUl9QQUNLQUdFX0lELCBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEIH07XG5leHBvcnQgZGVmYXVsdCBVaUF1dG9tYXRvcjJTZXJ2ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUEsSUFBQUEsT0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsU0FBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcseUJBQUEsR0FBQUgsT0FBQTtBQUtBLElBQUFJLFFBQUEsR0FBQUosT0FBQTtBQUdBLElBQUFLLFNBQUEsR0FBQU4sc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFNLFFBQUEsR0FBQVAsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFPLE1BQUEsR0FBQVIsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFRLEtBQUEsR0FBQVQsc0JBQUEsQ0FBQUMsT0FBQTtBQUVBLE1BQU1TLFdBQVcsR0FBRyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsd0JBQXdCLENBQUM7QUFDbkcsTUFBTUMscUJBQXFCLEdBQUcsS0FBSztBQUNuQyxNQUFNQyxzQkFBc0IsR0FBRyxFQUFFO0FBQ2pDLE1BQU1DLHVCQUF1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
306
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZHJpdmVyIiwiX2FzeW5jYm94IiwiX2FwcGl1bVVpYXV0b21hdG9yMlNlcnZlciIsIl9zdXBwb3J0IiwiX2JsdWViaXJkIiwiX2hlbHBlcnMiLCJfYXhpb3MiLCJfcGF0aCIsIlJFUURfUEFSQU1TIiwiU0VSVkVSX0xBVU5DSF9USU1FT1VUIiwiU0VSVkVSX0lOU1RBTExfUkVUUklFUyIsIlNFUlZJQ0VTX0xBVU5DSF9USU1FT1VUIiwiU0VSVkVSX1BBQ0tBR0VfSUQiLCJleHBvcnRzIiwiU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCIsIklOU1RSVU1FTlRBVElPTl9UQVJHRVQiLCJpbnN0cnVtZW50YXRpb25Mb2dnZXIiLCJsb2dnZXIiLCJnZXRMb2dnZXIiLCJVSUEyUHJveHkiLCJKV1Byb3h5IiwicHJveHlDb21tYW5kIiwidXJsIiwibWV0aG9kIiwiYm9keSIsImRpZEluc3RydW1lbnRhdGlvbkV4aXQiLCJlcnJvcnMiLCJJbnZhbGlkQ29udGV4dEVycm9yIiwiVWlBdXRvbWF0b3IyU2VydmVyIiwiY29uc3RydWN0b3IiLCJsb2ciLCJvcHRzIiwicmVxIiwidXRpbCIsImhhc1ZhbHVlIiwiRXJyb3IiLCJkaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSIsInByb3h5T3B0cyIsInNlcnZlciIsImhvc3QiLCJwb3J0Iiwic3lzdGVtUG9ydCIsImtlZXBBbGl2ZSIsInJlYWRUaW1lb3V0IiwidGltZW91dCIsImp3cHJveHkiLCJwcm94eVJlcVJlcyIsImJpbmQiLCJjb21tYW5kIiwicHJlcGFyZVNlcnZlclBhY2thZ2UiLCJhcHBQYXRoIiwiYXBwSWQiLCJ0bXBSb290IiwicmVzdWx0SW5mbyIsIndhc1NpZ25lZCIsImluc3RhbGxTdGF0ZSIsImFkYiIsIkFQUF9JTlNUQUxMX1NUQVRFIiwiTk9UX0lOU1RBTExFRCIsImNoZWNrQXBrQ2VydCIsImhlbHBlcnMiLCJpc1dyaXRlYWJsZSIsIndhcm4iLCJkc3RQYXRoIiwicGF0aCIsInJlc29sdmUiLCJiYXNlbmFtZSIsImZzIiwiY29weUZpbGUiLCJzaWduQXBwIiwiaXNBcHBJbnN0YWxsZWQiLCJTQU1FX1ZFUlNJT05fSU5TVEFMTEVEIiwiZ2V0QXBwbGljYXRpb25JbnN0YWxsU3RhdGUiLCJpbnN0YWxsU2VydmVyQXBrIiwiaW5zdGFsbFRpbWVvdXQiLCJ0ZW1wRGlyIiwib3BlbkRpciIsInBhY2thZ2VzSW5mbyIsIkIiLCJhbGwiLCJhcGtQYXRoIiwidGVzdEFwa1BhdGgiLCJtYXAiLCJkZWJ1ZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJzaG91bGRVbmluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsInNvbWUiLCJldmVyeSIsInNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcyIsIk9MREVSX1ZFUlNJT05fSU5TVEFMTEVEIiwiaW5jbHVkZXMiLCJpbmZvIiwic2lsZW50VW5pbnN0YWxsUGtnIiwicGtnSWQiLCJ1bmluc3RhbGxBcGsiLCJlcnIiLCJtZXNzYWdlIiwiaW5zdGFsbFBrZyIsInBrZ1BhdGgiLCJpbnN0YWxsIiwibm9JbmNyZW1lbnRhbCIsInJlcGxhY2UiLCJ0aW1lb3V0Q2FwTmFtZSIsInJpbXJhZiIsInZlcmlmeVNlcnZpY2VzQXZhaWxhYmlsaXR5IiwiaXNQbVNlcnZpY2VBdmFpbGFibGUiLCJwbU91dHB1dCIsInBtRXJyb3IiLCJ3YWl0Rm9yQ29uZGl0aW9uIiwic2hlbGwiLCJlIiwid2FpdE1zIiwiaW50ZXJ2YWxNcyIsImVycm9yIiwibGluZSIsInNwbGl0Iiwic3RhcnRTZXNzaW9uIiwiY2FwcyIsImNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzIiwic2tpcFNlcnZlckluc3RhbGxhdGlvbiIsInNlcnZlclZlcnNpb24iLCJ1aWF1dG9tYXRvcjJTZXJ2ZXJMYXVuY2hUaW1lb3V0IiwidGltZXIiLCJ0aW1pbmciLCJUaW1lciIsInN0YXJ0IiwicmV0cmllcyIsIm1heFJldHJpZXMiLCJkZWxheUJldHdlZW5SZXRyaWVzIiwic3RhcnRJbnN0cnVtZW50YXRpb25Qcm9jZXNzIiwiZXJyb3JBbmRUaHJvdyIsImRlbGF5IiwiZ2V0RHVyYXRpb24iLCJhc01pbGxpU2Vjb25kcyIsInRvRml4ZWQiLCJjYXBhYmlsaXRpZXMiLCJmaXJzdE1hdGNoIiwiYWx3YXlzTWF0Y2giLCJjbWQiLCJkaXNhYmxlV2luZG93QW5pbWF0aW9uIiwicHVzaCIsIl8iLCJpc0Jvb2xlYW4iLCJpbnN0cnVtZW50YXRpb25Qcm9jZXNzIiwiY3JlYXRlU3ViUHJvY2VzcyIsIm9uIiwic3Rkb3V0Iiwic3RkZXJyIiwib3V0cHV0IiwidHJpbSIsImNvZGUiLCJkZWxldGVTZXNzaW9uIiwic3RyaWN0Q2xlYW51cCIsInZhbHVlIiwiYXhpb3MiLCJkYXRhIiwiYWN0aXZlU2Vzc2lvbklkcyIsImlkIiwiZmlsdGVyIiwiQm9vbGVhbiIsImxlbmd0aCIsInBsdXJhbGl6ZSIsImRlbGV0ZSIsImZvcmNlU3RvcCIsImlnbm9yZSIsImtpbGxQcm9jZXNzZXNCeU5hbWUiLCJfZGVmYXVsdCIsImRlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi9saWIvdWlhdXRvbWF0b3IyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBKV1Byb3h5LCBlcnJvcnMgfSBmcm9tICdhcHBpdW0vZHJpdmVyJztcbmltcG9ydCB7IHdhaXRGb3JDb25kaXRpb24gfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQge1xuICBTRVJWRVJfQVBLX1BBVEggYXMgYXBrUGF0aCxcbiAgVEVTVF9BUEtfUEFUSCBhcyB0ZXN0QXBrUGF0aCxcbiAgdmVyc2lvbiBhcyBzZXJ2ZXJWZXJzaW9uXG59IGZyb20gJ2FwcGl1bS11aWF1dG9tYXRvcjItc2VydmVyJztcbmltcG9ydCB7XG4gIHV0aWwsIGxvZ2dlciwgdGVtcERpciwgZnMsIHRpbWluZ1xufSBmcm9tICdhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQgaGVscGVycyBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuXG5jb25zdCBSRVFEX1BBUkFNUyA9IFsnYWRiJywgJ3RtcERpcicsICdob3N0JywgJ3N5c3RlbVBvcnQnLCAnZGV2aWNlUG9ydCcsICdkaXNhYmxlV2luZG93QW5pbWF0aW9uJ107XG5jb25zdCBTRVJWRVJfTEFVTkNIX1RJTUVPVVQgPSAzMDAwMDtcbmNvbnN0IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgPSAyMDtcbmNvbnN0IFNFUlZJQ0VTX0xBVU5DSF9USU1FT1VUID0gMzAwMDA7XG5jb25zdCBTRVJWRVJfUEFDS0FHRV9JRCA9ICdpby5hcHBpdW0udWlhdXRvbWF0b3IyLnNlcnZlcic7XG5jb25zdCBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEID0gYCR7U0VSVkVSX1BBQ0tBR0VfSUR9LnRlc3RgO1xuY29uc3QgSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCA9IGAke1NFUlZFUl9URVNUX1BBQ0tBR0VfSUR9L2FuZHJvaWR4LnRlc3QucnVubmVyLkFuZHJvaWRKVW5pdFJ1bm5lcmA7XG5jb25zdCBpbnN0cnVtZW50YXRpb25Mb2dnZXIgPSBsb2dnZXIuZ2V0TG9nZ2VyKCdJbnN0cnVtZW50YXRpb24nKTtcblxuY2xhc3MgVUlBMlByb3h5IGV4dGVuZHMgSldQcm94eSB7XG4gIGFzeW5jIHByb3h5Q29tbWFuZCAodXJsLCBtZXRob2QsIGJvZHkgPSBudWxsKSB7XG4gICAgaWYgKHRoaXMuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkQ29udGV4dEVycm9yKFxuICAgICAgICBgJyR7bWV0aG9kfSAke3VybH0nIGNhbm5vdCBiZSBwcm94aWVkIHRvIFVpQXV0b21hdG9yMiBzZXJ2ZXIgYmVjYXVzZSBgICtcbiAgICAgICAgJ3RoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBpcyBub3QgcnVubmluZyAocHJvYmFibHkgY3Jhc2hlZCkuICcgK1xuICAgICAgICAnQ2hlY2sgdGhlIHNlcnZlciBsb2cgYW5kL29yIHRoZSBsb2djYXQgb3V0cHV0IGZvciBtb3JlIGRldGFpbHMnKTtcbiAgICB9XG4gICAgcmV0dXJuIGF3YWl0IHN1cGVyLnByb3h5Q29tbWFuZCh1cmwsIG1ldGhvZCwgYm9keSk7XG4gIH1cbn1cblxuY2xhc3MgVWlBdXRvbWF0b3IyU2VydmVyIHtcbiAgY29uc3RydWN0b3IgKGxvZywgb3B0cyA9IHt9KSB7XG4gICAgZm9yIChsZXQgcmVxIG9mIFJFUURfUEFSQU1TKSB7XG4gICAgICBpZiAoIW9wdHMgfHwgIXV0aWwuaGFzVmFsdWUob3B0c1tyZXFdKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE9wdGlvbiAnJHtyZXF9JyBpcyByZXF1aXJlZCFgKTtcbiAgICAgIH1cbiAgICAgIHRoaXNbcmVxXSA9IG9wdHNbcmVxXTtcbiAgICB9XG4gICAgdGhpcy5sb2cgPSBsb2c7XG4gICAgdGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSA9IG9wdHMuZGlzYWJsZVN1cHByZXNzQWNjZXNzaWJpbGl0eVNlcnZpY2U7XG4gICAgY29uc3QgcHJveHlPcHRzID0ge1xuICAgICAgbG9nLFxuICAgICAgc2VydmVyOiB0aGlzLmhvc3QsXG4gICAgICBwb3J0OiB0aGlzLnN5c3RlbVBvcnQsXG4gICAgICBrZWVwQWxpdmU6IHRydWUsXG4gICAgfTtcbiAgICBpZiAob3B0cy5yZWFkVGltZW91dCAmJiBvcHRzLnJlYWRUaW1lb3V0ID4gMCkge1xuICAgICAgcHJveHlPcHRzLnRpbWVvdXQgPSBvcHRzLnJlYWRUaW1lb3V0O1xuICAgIH1cbiAgICB0aGlzLmp3cHJveHkgPSBuZXcgVUlBMlByb3h5KHByb3h5T3B0cyk7XG4gICAgdGhpcy5wcm94eVJlcVJlcyA9IHRoaXMuandwcm94eS5wcm94eVJlcVJlcy5iaW5kKHRoaXMuandwcm94eSk7XG4gICAgdGhpcy5wcm94eUNvbW1hbmQgPSB0aGlzLmp3cHJveHkuY29tbWFuZC5iaW5kKHRoaXMuandwcm94eSk7XG4gICAgdGhpcy5qd3Byb3h5LmRpZEluc3RydW1lbnRhdGlvbkV4aXQgPSBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIHByZXBhcmVTZXJ2ZXJQYWNrYWdlKGFwcFBhdGgsIGFwcElkLCB0bXBSb290KSB7XG4gICAgY29uc3QgcmVzdWx0SW5mbyA9IHtcbiAgICAgIHdhc1NpZ25lZDogZmFsc2UsXG4gICAgICBpbnN0YWxsU3RhdGU6IHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICBhcHBQYXRoLFxuICAgICAgYXBwSWQsXG4gICAgfTtcblxuICAgIGlmIChhd2FpdCB0aGlzLmFkYi5jaGVja0Fwa0NlcnQocmVzdWx0SW5mby5hcHBQYXRoLCBhcHBJZCkpIHtcbiAgICAgIHJlc3VsdEluZm8ud2FzU2lnbmVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFhd2FpdCBoZWxwZXJzLmlzV3JpdGVhYmxlKGFwcFBhdGgpKSB7XG4gICAgICAgIHRoaXMubG9nLndhcm4oXG4gICAgICAgICAgYFNlcnZlciBwYWNrYWdlIGF0ICcke2FwcFBhdGh9JyBpcyBub3Qgd3JpdGVhYmxlLiBgICtcbiAgICAgICAgICBgV2lsbCBjb3B5IGl0IGludG8gdGhlIHRlbXBvcmFyeSBsb2NhdGlvbiBhdCAnJHt0bXBSb290fScgYXMgYSB3b3JrYXJvdW5kLiBgICtcbiAgICAgICAgICBgQ29uc2lkZXIgbWFraW5nIHRoaXMgZmlsZSB3cml0ZWFibGUgbWFudWFsbHkgaW4gb3JkZXIgdG8gaW1wcm92ZSB0aGUgcGVyZm9ybWFuY2Ugb2Ygc2Vzc2lvbiBzdGFydHVwLmBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLmJhc2VuYW1lKGFwcFBhdGgpKTtcbiAgICAgICAgYXdhaXQgZnMuY29weUZpbGUoYXBwUGF0aCwgZHN0UGF0aCk7XG4gICAgICAgIHJlc3VsdEluZm8uYXBwUGF0aCA9IGRzdFBhdGg7XG4gICAgICB9XG4gICAgICBhd2FpdCBoZWxwZXJzLnNpZ25BcHAodGhpcy5hZGIsIHJlc3VsdEluZm8uYXBwUGF0aCk7XG4gICAgfVxuXG4gICAgaWYgKGFwcElkID09PSBTRVJWRVJfVEVTVF9QQUNLQUdFX0lEICYmIGF3YWl0IHRoaXMuYWRiLmlzQXBwSW5zdGFsbGVkKGFwcElkKSkge1xuICAgICAgLy8gVGhlcmUgaXMgbm8gcG9pbnQgaW4gZ2V0dGluZyB0aGUgc3RhdGUgZm9yIHRoZSB0ZXN0IHNlcnZlcixcbiAgICAgIC8vIHNpbmNlIGl0IGRvZXMgbm90IGNvbnRhaW4gYW55IHZlcnNpb24gaW5mb1xuICAgICAgcmVzdWx0SW5mby5pbnN0YWxsU3RhdGUgPSB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5TQU1FX1ZFUlNJT05fSU5TVEFMTEVEO1xuICAgIH0gZWxzZSBpZiAoYXBwSWQgPT09IFNFUlZFUl9QQUNLQUdFX0lEKSB7XG4gICAgICByZXN1bHRJbmZvLmluc3RhbGxTdGF0ZSA9IGF3YWl0IHRoaXMuYWRiLmdldEFwcGxpY2F0aW9uSW5zdGFsbFN0YXRlKHJlc3VsdEluZm8uYXBwUGF0aCwgYXBwSWQpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRJbmZvO1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHRoZSBhcGtzIG9uIHRvIHRoZSBkZXZpY2Ugb3IgZW11bGF0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbnN0YWxsVGltZW91dCAtIEluc3RhbGxhdGlvbiB0aW1lb3V0XG4gICAqL1xuICBhc3luYyBpbnN0YWxsU2VydmVyQXBrIChpbnN0YWxsVGltZW91dCA9IFNFUlZFUl9JTlNUQUxMX1JFVFJJRVMgKiAxMDAwKSB7XG4gICAgY29uc3QgdG1wUm9vdCA9IGF3YWl0IHRlbXBEaXIub3BlbkRpcigpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYWNrYWdlc0luZm8gPSBhd2FpdCBCLmFsbChcbiAgICAgICAgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFwcFBhdGg6IGFwa1BhdGgsXG4gICAgICAgICAgICBhcHBJZDogU0VSVkVSX1BBQ0tBR0VfSUQsXG4gICAgICAgICAgfSwge1xuICAgICAgICAgICAgYXBwUGF0aDogdGVzdEFwa1BhdGgsXG4gICAgICAgICAgICBhcHBJZDogU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLm1hcCgoe2FwcFBhdGgsIGFwcElkfSkgPT4gdGhpcy5wcmVwYXJlU2VydmVyUGFja2FnZShhcHBQYXRoLCBhcHBJZCwgdG1wUm9vdCkpXG4gICAgICApO1xuXG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgU2VydmVyIHBhY2thZ2VzIHN0YXR1czogJHtKU09OLnN0cmluZ2lmeShwYWNrYWdlc0luZm8pfWApO1xuICAgICAgLy8gV2Ugd2FudCB0byBlbmZvcmNlIHVuaW5zdGFsbCBpbiBjYXNlIHRoZSBjdXJyZW50IHNlcnZlciBwYWNrYWdlIGhhcyBub3QgYmVlbiBzaWduZWQgcHJvcGVybHlcbiAgICAgIC8vIG9yIGlmIGFueSBvZiBzZXJ2ZXIgcGFja2FnZXMgaXMgbm90IGluc3RhbGxlZCwgd2hpbGUgdGhlIG90aGVyIGRvZXNcbiAgICAgIGNvbnN0IHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzID0gcGFja2FnZXNJbmZvLnNvbWUoKHt3YXNTaWduZWR9KSA9PiAhd2FzU2lnbmVkKVxuICAgICAgICB8fCAocGFja2FnZXNJbmZvLnNvbWUoKHtpbnN0YWxsU3RhdGV9KSA9PiBpbnN0YWxsU3RhdGUgPT09IHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQpXG4gICAgICAgICAgICAmJiAhcGFja2FnZXNJbmZvLmV2ZXJ5KCh7aW5zdGFsbFN0YXRlfSkgPT4gaW5zdGFsbFN0YXRlID09PSB0aGlzLmFkYi5BUFBfSU5TVEFMTF9TVEFURS5OT1RfSU5TVEFMTEVEKSk7XG4gICAgICAvLyBJbnN0YWxsIG11c3QgYWx3YXlzIGZvbGxvdyB1bmluc3RhbGwuIEFsc28sIHBlcmZvcm0gdGhlIGluc3RhbGwgaWZcbiAgICAgIC8vIGFueSBvZiBzZXJ2ZXIgcGFja2FnZXMgaXMgbm90IGluc3RhbGxlZCBvciBpcyBvdXRkYXRlZFxuICAgICAgY29uc3Qgc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzID0gc2hvdWxkVW5pbnN0YWxsU2VydmVyUGFja2FnZXMgfHwgcGFja2FnZXNJbmZvLnNvbWUoKHtpbnN0YWxsU3RhdGV9KSA9PiBbXG4gICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk5PVF9JTlNUQUxMRUQsXG4gICAgICAgIHRoaXMuYWRiLkFQUF9JTlNUQUxMX1NUQVRFLk9MREVSX1ZFUlNJT05fSU5TVEFMTEVELFxuICAgICAgXS5pbmNsdWRlcyhpbnN0YWxsU3RhdGUpKTtcbiAgICAgIHRoaXMubG9nLmluZm8oYFNlcnZlciBwYWNrYWdlcyBhcmUgJHtzaG91bGRJbnN0YWxsU2VydmVyUGFja2FnZXMgPyAnJyA6ICdub3QgJ31nb2luZyB0byBiZSAocmUpaW5zdGFsbGVkYCk7XG4gICAgICBpZiAoc2hvdWxkSW5zdGFsbFNlcnZlclBhY2thZ2VzICYmIHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIHRoaXMubG9nLmluZm8oJ0Z1bGwgcGFja2FnZXMgcmVpbnN0YWxsIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm1lZCcpO1xuICAgICAgfVxuICAgICAgaWYgKHNob3VsZFVuaW5zdGFsbFNlcnZlclBhY2thZ2VzKSB7XG4gICAgICAgIGNvbnN0IHNpbGVudFVuaW5zdGFsbFBrZyA9IGFzeW5jIChwa2dJZCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFkYi51bmluc3RhbGxBcGsocGtnSWQpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhpcy5sb2cuaW5mbyhgQ2Fubm90IHVuaW5zdGFsbCAnJHtwa2dJZH0nOiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgQi5hbGwocGFja2FnZXNJbmZvLm1hcCgoe2FwcElkfSkgPT4gc2lsZW50VW5pbnN0YWxsUGtnKGFwcElkKSkpO1xuICAgICAgfVxuICAgICAgaWYgKHNob3VsZEluc3RhbGxTZXJ2ZXJQYWNrYWdlcykge1xuICAgICAgICBjb25zdCBpbnN0YWxsUGtnID0gYXN5bmMgKHBrZ1BhdGgpID0+IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmFkYi5pbnN0YWxsKHBrZ1BhdGgsIHtcbiAgICAgICAgICAgIG5vSW5jcmVtZW50YWw6IHRydWUsXG4gICAgICAgICAgICByZXBsYWNlOiB0cnVlLFxuICAgICAgICAgICAgdGltZW91dDogaW5zdGFsbFRpbWVvdXQsXG4gICAgICAgICAgICB0aW1lb3V0Q2FwTmFtZTogJ3VpYXV0b21hdG9yMlNlcnZlckluc3RhbGxUaW1lb3V0J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBCLmFsbChwYWNrYWdlc0luZm8ubWFwKCh7YXBwUGF0aH0pID0+IGluc3RhbGxQa2coYXBwUGF0aCkpKTtcbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgZnMucmltcmFmKHRtcFJvb3QpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMudmVyaWZ5U2VydmljZXNBdmFpbGFiaWxpdHkoKTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVNlcnZpY2VzQXZhaWxhYmlsaXR5ICgpIHtcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgV2FpdGluZyB1cCB0byAke1NFUlZJQ0VTX0xBVU5DSF9USU1FT1VUfW1zIGZvciBzZXJ2aWNlcyB0byBiZSBhdmFpbGFibGVgKTtcbiAgICBsZXQgaXNQbVNlcnZpY2VBdmFpbGFibGUgPSBmYWxzZTtcbiAgICBsZXQgcG1PdXRwdXQgPSAnJztcbiAgICBsZXQgcG1FcnJvciA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHdhaXRGb3JDb25kaXRpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoIWlzUG1TZXJ2aWNlQXZhaWxhYmxlKSB7XG4gICAgICAgICAgcG1FcnJvciA9IG51bGw7XG4gICAgICAgICAgcG1PdXRwdXQgPSAnJztcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcG1PdXRwdXQgPSBhd2FpdCB0aGlzLmFkYi5zaGVsbChbJ3BtJywgJ2xpc3QnLCAnaW5zdHJ1bWVudGF0aW9uJ10pO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHBtRXJyb3IgPSBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocG1PdXRwdXQuaW5jbHVkZXMoJ0NvdWxkIG5vdCBhY2Nlc3MgdGhlIFBhY2thZ2UgTWFuYWdlcicpKSB7XG4gICAgICAgICAgICBwbUVycm9yID0gbmV3IEVycm9yKGBQcm9ibGVtIHJ1bm5pbmcgUGFja2FnZSBNYW5hZ2VyOiAke3BtT3V0cHV0fWApO1xuICAgICAgICAgICAgcG1PdXRwdXQgPSAnJzsgLy8gcmVtb3ZlIG91dHB1dCwgc28gaXQgaXMgbm90IHByaW50ZWQgYmVsb3dcbiAgICAgICAgICB9IGVsc2UgaWYgKHBtT3V0cHV0LmluY2x1ZGVzKElOU1RSVU1FTlRBVElPTl9UQVJHRVQpKSB7XG4gICAgICAgICAgICBwbU91dHB1dCA9ICcnOyAvLyByZW1vdmUgb3V0cHV0LCBzbyBpdCBpcyBub3QgcHJpbnRlZCBiZWxvd1xuICAgICAgICAgICAgdGhpcy5sb2cuZGVidWcoYEluc3RydW1lbnRhdGlvbiB0YXJnZXQgJyR7SU5TVFJVTUVOVEFUSU9OX1RBUkdFVH0nIGlzIGF2YWlsYWJsZWApO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXNcbiAgICAgICAgICAgIGlzUG1TZXJ2aWNlQXZhaWxhYmxlID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFwbUVycm9yKSB7XG4gICAgICAgICAgICBwbUVycm9yID0gbmV3IEVycm9yKCdUaGUgaW5zdHJ1bWVudGF0aW9uIHRhcmdldCBpcyBub3QgbGlzdGVkIGJ5IFBhY2thZ2UgTWFuYWdlcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNQbVNlcnZpY2VBdmFpbGFibGU7XG4gICAgICB9LCB7XG4gICAgICAgIHdhaXRNczogU0VSVklDRVNfTEFVTkNIX1RJTUVPVVQsXG4gICAgICAgIGludGVydmFsTXM6IDEwMDAsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKGBVbmFibGUgdG8gZmluZCBpbnN0cnVtZW50YXRpb24gdGFyZ2V0ICcke0lOU1RSVU1FTlRBVElPTl9UQVJHRVR9JzogJHsocG1FcnJvciB8fCB7fSkubWVzc2FnZX1gKTtcbiAgICAgIGlmIChwbU91dHB1dCkge1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZygnQXZhaWxhYmxlIHRhcmdldHM6Jyk7XG4gICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBwbU91dHB1dC5zcGxpdCgnXFxuJykpIHtcbiAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgICAgICR7bGluZS5yZXBsYWNlKCdpbnN0cnVtZW50YXRpb246JywgJycpfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc3RhcnRTZXNzaW9uIChjYXBzKSB7XG4gICAgYXdhaXQgdGhpcy5jbGVhbnVwQXV0b21hdGlvbkxlZnRvdmVycygpO1xuICAgIGlmIChjYXBzLnNraXBTZXJ2ZXJJbnN0YWxsYXRpb24pIHtcbiAgICAgIHRoaXMubG9nLmluZm8oYCdza2lwU2VydmVySW5zdGFsbGF0aW9uJyBpcyBzZXQuIEF0dGVtcHRpbmcgdG8gdXNlIFVJQXV0b21hdG9yMiBzZXJ2ZXIgZnJvbSB0aGUgZGV2aWNlYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLmluZm8oYFN0YXJ0aW5nIFVJQXV0b21hdG9yMiBzZXJ2ZXIgJHtzZXJ2ZXJWZXJzaW9ufWApO1xuICAgICAgdGhpcy5sb2cuaW5mbyhgVXNpbmcgVUlBdXRvbWF0b3IyIHNlcnZlciBmcm9tICcke2Fwa1BhdGh9JyBhbmQgdGVzdCBmcm9tICcke3Rlc3RBcGtQYXRofSdgKTtcbiAgICB9XG5cbiAgICBjb25zdCB0aW1lb3V0ID0gY2Fwcy51aWF1dG9tYXRvcjJTZXJ2ZXJMYXVuY2hUaW1lb3V0IHx8IFNFUlZFUl9MQVVOQ0hfVElNRU9VVDtcbiAgICBjb25zdCB0aW1lciA9IG5ldyB0aW1pbmcuVGltZXIoKS5zdGFydCgpO1xuICAgIGxldCByZXRyaWVzID0gMDtcbiAgICBjb25zdCBtYXhSZXRyaWVzID0gMjtcbiAgICBjb25zdCBkZWxheUJldHdlZW5SZXRyaWVzID0gMzAwMDtcbiAgICB3aGlsZSAocmV0cmllcyA8IG1heFJldHJpZXMpIHtcbiAgICAgIHRoaXMubG9nLmluZm8oYFdhaXRpbmcgdXAgdG8gJHt0aW1lb3V0fW1zIGZvciBVaUF1dG9tYXRvcjIgdG8gYmUgb25saW5lLi4uYCk7XG4gICAgICB0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCA9IGZhbHNlO1xuICAgICAgYXdhaXQgdGhpcy5zdGFydEluc3RydW1lbnRhdGlvblByb2Nlc3MoKTtcbiAgICAgIGlmICghdGhpcy5qd3Byb3h5LmRpZEluc3RydW1lbnRhdGlvbkV4aXQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB3YWl0Rm9yQ29uZGl0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuandwcm94eS5jb21tYW5kKCcvc3RhdHVzJywgJ0dFVCcpO1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAvLyBzaG9ydCBjaXJjdWl0IHRvIHJldHJ5IG9yIGZhaWwgZmFzdFxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qd3Byb3h5LmRpZEluc3RydW1lbnRhdGlvbkV4aXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwge1xuICAgICAgICAgICAgd2FpdE1zOiB0aW1lb3V0LFxuICAgICAgICAgICAgaW50ZXJ2YWxNczogMTAwMCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhpcy5sb2cuZXJyb3JBbmRUaHJvdyhgVGhlIGluc3RydW1lbnRhdGlvbiBwcm9jZXNzIGNhbm5vdCBiZSBpbml0aWFsaXplZCB3aXRoaW4gJHt0aW1lb3V0fW1zIHRpbWVvdXQuIGBcbiAgICAgICAgICAgICsgJ01ha2Ugc3VyZSB0aGUgYXBwbGljYXRpb24gdW5kZXIgdGVzdCBkb2VzIG5vdCBjcmFzaCBhbmQgaW52ZXN0aWdhdGUgdGhlIGxvZ2NhdCBvdXRwdXQuICdcbiAgICAgICAgICAgICsgYFlvdSBjb3VsZCBhbHNvIHRyeSB0byBpbmNyZWFzZSB0aGUgdmFsdWUgb2YgJ3VpYXV0b21hdG9yMlNlcnZlckxhdW5jaFRpbWVvdXQnIGNhcGFiaWxpdHlgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmp3cHJveHkuZGlkSW5zdHJ1bWVudGF0aW9uRXhpdCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmV0cmllcysrO1xuICAgICAgaWYgKHJldHJpZXMgPj0gbWF4UmV0cmllcykge1xuICAgICAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KCdUaGUgaW5zdHJ1bWVudGF0aW9uIHByb2Nlc3MgY2Fubm90IGJlIGluaXRpYWxpemVkLiAnXG4gICAgICAgICAgKyAnTWFrZSBzdXJlIHRoZSBhcHBsaWNhdGlvbiB1bmRlciB0ZXN0IGRvZXMgbm90IGNyYXNoIGFuZCBpbnZlc3RpZ2F0ZSB0aGUgbG9nY2F0IG91dHB1dC4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLndhcm4oYFRoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyBoYXMgYmVlbiB1bmV4cGVjdGVkbHkgdGVybWluYXRlZC4gYFxuICAgICAgICArIGBSZXRyeWluZyBVaUF1dG9tYXRvcjIgc3RhcnR1cCAoIyR7cmV0cmllc30gb2YgJHttYXhSZXRyaWVzIC0gMX0pYCk7XG4gICAgICBhd2FpdCB0aGlzLmNsZWFudXBBdXRvbWF0aW9uTGVmdG92ZXJzKHRydWUpO1xuICAgICAgYXdhaXQgQi5kZWxheShkZWxheUJldHdlZW5SZXRyaWVzKTtcbiAgICB9XG5cbiAgICB0aGlzLmxvZy5kZWJ1ZyhgVGhlIGluaXRpYWxpemF0aW9uIG9mIHRoZSBpbnN0cnVtZW50YXRpb24gcHJvY2VzcyB0b29rIGBcbiAgICAgICsgYCR7dGltZXIuZ2V0RHVyYXRpb24oKS5hc01pbGxpU2Vjb25kcy50b0ZpeGVkKDApfW1zYCk7XG4gICAgYXdhaXQgdGhpcy5qd3Byb3h5LmNvbW1hbmQoJy9zZXNzaW9uJywgJ1BPU1QnLCB7XG4gICAgICBjYXBhYmlsaXRpZXM6IHtcbiAgICAgICAgZmlyc3RNYXRjaDogW2NhcHNdLFxuICAgICAgICBhbHdheXNNYXRjaDoge30sXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzdGFydEluc3RydW1lbnRhdGlvblByb2Nlc3MgKCkge1xuICAgIGNvbnN0IGNtZCA9IFsnYW0nLCAnaW5zdHJ1bWVudCcsICctdyddO1xuICAgIGlmICh0aGlzLmRpc2FibGVXaW5kb3dBbmltYXRpb24pIHtcbiAgICAgIGNtZC5wdXNoKCctLW5vLXdpbmRvdy1hbmltYXRpb24nKTtcbiAgICB9XG4gICAgaWYgKF8uaXNCb29sZWFuKHRoaXMuZGlzYWJsZVN1cHByZXNzQWNjZXNzaWJpbGl0eVNlcnZpY2UpKSB7XG4gICAgICBjbWQucHVzaCgnLWUnLCAnRElTQUJMRV9TVVBQUkVTU19BQ0NFU1NJQklMSVRZX1NFUlZJQ0VTJywgdGhpcy5kaXNhYmxlU3VwcHJlc3NBY2Nlc3NpYmlsaXR5U2VydmljZSk7XG4gICAgfVxuICAgIC8vIERpc2FibGUgR29vZ2xlIGFuYWx5dGljcyB0byBwcmV2ZW50IHBvc3NpYmxlIGZhdGFsIGV4Y2VwdGlvblxuICAgIGNtZC5wdXNoKCctZScsICdkaXNhYmxlQW5hbHl0aWNzJywgdHJ1ZSk7XG4gICAgY21kLnB1c2goSU5TVFJVTUVOVEFUSU9OX1RBUkdFVCk7XG4gICAgY29uc3QgaW5zdHJ1bWVudGF0aW9uUHJvY2VzcyA9IHRoaXMuYWRiLmNyZWF0ZVN1YlByb2Nlc3MoWydzaGVsbCcsIC4uLmNtZF0pO1xuICAgIGluc3RydW1lbnRhdGlvblByb2Nlc3Mub24oJ291dHB1dCcsIChzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0ID0gXy50cmltKHN0ZG91dCB8fCBzdGRlcnIpO1xuICAgICAgaWYgKG91dHB1dCkge1xuICAgICAgICBpbnN0cnVtZW50YXRpb25Mb2dnZXIuZGVidWcob3V0cHV0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpbnN0cnVtZW50YXRpb25Qcm9jZXNzLm9uKCdleGl0JywgKGNvZGUpID0+IHtcbiAgICAgIGluc3RydW1lbnRhdGlvbkxvZ2dlci5kZWJ1ZyhgVGhlIHByb2Nlc3MgaGFzIGV4aXRlZCB3aXRoIGNvZGUgJHtjb2RlfWApO1xuICAgICAgdGhpcy5qd3Byb3h5LmRpZEluc3RydW1lbnRhdGlvbkV4aXQgPSB0cnVlO1xuICAgIH0pO1xuICAgIGF3YWl0IGluc3RydW1lbnRhdGlvblByb2Nlc3Muc3RhcnQoMCk7XG4gIH1cblxuICBhc3luYyBkZWxldGVTZXNzaW9uICgpIHtcbiAgICB0aGlzLmxvZy5kZWJ1ZygnRGVsZXRpbmcgVWlBdXRvbWF0b3IyIHNlcnZlciBzZXNzaW9uJyk7XG4gICAgLy8gcmVseSBvbiBqd3Byb3h5J3MgaW50ZWxsaWdlbmNlIHRvIGtub3cgd2hhdCB3ZSdyZSB0YWxraW5nIGFib3V0IGFuZFxuICAgIC8vIGRlbGV0ZSB0aGUgY3VycmVudCBzZXNzaW9uXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuandwcm94eS5jb21tYW5kKCcvJywgJ0RFTEVURScpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cud2FybihgRGlkIG5vdCBnZXQgY29uZmlybWF0aW9uIFVpQXV0b21hdG9yMiBkZWxldGVTZXNzaW9uIHdvcmtlZDsgYCArXG4gICAgICAgICAgYEVycm9yIHdhczogJHtlcnJ9YCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2xlYW51cEF1dG9tYXRpb25MZWZ0b3ZlcnMgKHN0cmljdENsZWFudXAgPSBmYWxzZSkge1xuICAgIHRoaXMubG9nLmRlYnVnKGBQZXJmb3JtaW5nICR7c3RyaWN0Q2xlYW51cCA/ICdzdHJpY3QnIDogJ3NoYWxsb3cnfSBjbGVhbnVwIG9mIGF1dG9tYXRpb24gbGVmdG92ZXJzYCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qge3ZhbHVlfSA9IChhd2FpdCBheGlvcyh7XG4gICAgICAgIHVybDogYGh0dHA6Ly8ke3RoaXMuaG9zdH06JHt0aGlzLnN5c3RlbVBvcnR9L3Nlc3Npb25zYCxcbiAgICAgICAgdGltZW91dDogNTAwLFxuICAgICAgfSkpLmRhdGE7XG4gICAgICBjb25zdCBhY3RpdmVTZXNzaW9uSWRzID0gdmFsdWUubWFwKCh7aWR9KSA9PiBpZCkuZmlsdGVyKEJvb2xlYW4pO1xuICAgICAgaWYgKGFjdGl2ZVNlc3Npb25JZHMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBUaGUgZm9sbG93aW5nIG9ic29sZXRlIHNlc3Npb25zIGFyZSBzdGlsbCBydW5uaW5nOiAke0pTT04uc3RyaW5naWZ5KGFjdGl2ZVNlc3Npb25JZHMpfWApO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgQ2xlYW5pbmcgdXAgJHt1dGlsLnBsdXJhbGl6ZSgnb2Jzb2xldGUgc2Vzc2lvbicsIGFjdGl2ZVNlc3Npb25JZHMubGVuZ3RoLCB0cnVlKX1gKTtcbiAgICAgICAgYXdhaXQgQi5hbGwoYWN0aXZlU2Vzc2lvbklkc1xuICAgICAgICAgIC5tYXAoKGlkKSA9PiBheGlvcy5kZWxldGUoYGh0dHA6Ly8ke3RoaXMuaG9zdH06JHt0aGlzLnN5c3RlbVBvcnR9L3Nlc3Npb24vJHtpZH1gKSlcbiAgICAgICAgKTtcbiAgICAgICAgLy8gTGV0IGFsbCBzZXNzaW9ucyB0byBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkIGJlZm9yZSBjb250aW51aW5nXG4gICAgICAgIGF3YWl0IEIuZGVsYXkoMTAwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZygnTm8gb2Jzb2xldGUgc2Vzc2lvbnMgaGF2ZSBiZWVuIGRldGVjdGVkJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYE5vIG9ic29sZXRlIHNlc3Npb25zIGhhdmUgYmVlbiBkZXRlY3RlZCAoJHtlLm1lc3NhZ2V9KWApO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5mb3JjZVN0b3AoU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCk7XG4gICAgfSBjYXRjaCAoaWdub3JlKSB7fVxuICAgIGlmICghc3RyaWN0Q2xlYW51cCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYXBwaXVtL2FwcGl1bS9pc3N1ZXMvMTA3NDlcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5hZGIua2lsbFByb2Nlc3Nlc0J5TmFtZSgndWlhdXRvbWF0b3InKTtcbiAgICB9IGNhdGNoIChpZ25vcmUpIHt9XG4gIH1cbn1cblxuZXhwb3J0IHsgVWlBdXRvbWF0b3IyU2VydmVyLCBJTlNUUlVNRU5UQVRJT05fVEFSR0VULCBTRVJWRVJfUEFDS0FHRV9JRCwgU0VSVkVSX1RFU1RfUEFDS0FHRV9JRCB9O1xuZXhwb3J0IGRlZmF1bHQgVWlBdXRvbWF0b3IyU2VydmVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLFNBQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLHlCQUFBLEdBQUFILE9BQUE7QUFLQSxJQUFBSSxRQUFBLEdBQUFKLE9BQUE7QUFHQSxJQUFBSyxTQUFBLEdBQUFOLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBTSxRQUFBLEdBQUFQLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBTyxNQUFBLEdBQUFSLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBUSxLQUFBLEdBQUFULHNCQUFBLENBQUFDLE9BQUE7QUFFQSxNQUFNUyxXQUFXLEdBQUcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLHdCQUF3QixDQUFDO0FBQ25HLE1BQU1DLHFCQUFxQixHQUFHLEtBQUs7QUFDbkMsTUFBTUMsc0JBQXNCLEdBQUcsRUFBRTtBQUNqQyxNQUFNQyx1QkFBdUIsR0FBRyxLQUFLO0FBQ3JDLE1BQU1DLGlCQUFpQixHQUFHLCtCQUErQjtBQUFDQyxPQUFBLENBQUFELGlCQUFBLEdBQUFBLGlCQUFBO0FBQzFELE1BQU1FLHNCQUFzQixHQUFJLEdBQUVGLGlCQUFrQixPQUFNO0FBQUNDLE9BQUEsQ0FBQUMsc0JBQUEsR0FBQUEsc0JBQUE7QUFDM0QsTUFBTUMsc0JBQXNCLEdBQUksR0FBRUQsc0JBQXVCLDBDQUF5QztBQUFDRCxPQUFBLENBQUFFLHNCQUFBLEdBQUFBLHNCQUFBO0FBQ25HLE1BQU1DLHFCQUFxQixHQUFHQyxlQUFNLENBQUNDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQztBQUVqRSxNQUFNQyxTQUFTLFNBQVNDLGVBQU8sQ0FBQztFQUM5QixNQUFNQyxZQUFZQSxDQUFFQyxHQUFHLEVBQUVDLE1BQU0sRUFBRUMsSUFBSSxHQUFHLElBQUksRUFBRTtJQUM1QyxJQUFJLElBQUksQ0FBQ0Msc0JBQXNCLEVBQUU7TUFDL0IsTUFBTSxJQUFJQyxjQUFNLENBQUNDLG1CQUFtQixDQUNqQyxJQUFHSixNQUFPLElBQUdELEdBQUkscURBQW9ELEdBQ3RFLGlFQUFpRSxHQUNqRSxnRUFBZ0UsQ0FBQztJQUNyRTtJQUNBLE9BQU8sTUFBTSxLQUFLLENBQUNELFlBQVksQ0FBQ0MsR0FBRyxFQUFFQyxNQUFNLEVBQUVDLElBQUksQ0FBQztFQUNwRDtBQUNGO0FBRUEsTUFBTUksa0JBQWtCLENBQUM7RUFDdkJDLFdBQVdBLENBQUVDLEdBQUcsRUFBRUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFO0lBQzNCLEtBQUssSUFBSUMsR0FBRyxJQUFJeEIsV0FBVyxFQUFFO01BQzNCLElBQUksQ0FBQ3VCLElBQUksSUFBSSxDQUFDRSxhQUFJLENBQUNDLFFBQVEsQ0FBQ0gsSUFBSSxDQUFDQyxHQUFHLENBQUMsQ0FBQyxFQUFFO1FBQ3RDLE1BQU0sSUFBSUcsS0FBSyxDQUFFLFdBQVVILEdBQUksZ0JBQWUsQ0FBQztNQUNqRDtNQUNBLElBQUksQ0FBQ0EsR0FBRyxDQUFDLEdBQUdELElBQUksQ0FBQ0MsR0FBRyxDQUFDO0lBQ3ZCO0lBQ0EsSUFBSSxDQUFDRixHQUFHLEdBQUdBLEdBQUc7SUFDZCxJQUFJLENBQUNNLG1DQUFtQyxHQUFHTCxJQUFJLENBQUNLLG1DQUFtQztJQUNuRixNQUFNQyxTQUFTLEdBQUc7TUFDaEJQLEdBQUc7TUFDSFEsTUFBTSxFQUFFLElBQUksQ0FBQ0MsSUFBSTtNQUNqQkMsSUFBSSxFQUFFLElBQUksQ0FBQ0MsVUFBVTtNQUNyQkMsU0FBUyxFQUFFO0lBQ2IsQ0FBQztJQUNELElBQUlYLElBQUksQ0FBQ1ksV0FBVyxJQUFJWixJQUFJLENBQUNZLFdBQVcsR0FBRyxDQUFDLEVBQUU7TUFDNUNOLFNBQVMsQ0FBQ08sT0FBTyxHQUFHYixJQUFJLENBQUNZLFdBQVc7SUFDdEM7SUFDQSxJQUFJLENBQUNFLE9BQU8sR0FBRyxJQUFJMUIsU0FBUyxDQUFDa0IsU0FBUyxDQUFDO0lBQ3ZDLElBQUksQ0FBQ1MsV0FBVyxHQUFHLElBQUksQ0FBQ0QsT0FBTyxDQUFDQyxXQUFXLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUNGLE9BQU8sQ0FBQztJQUM5RCxJQUFJLENBQUN4QixZQUFZLEdBQUcsSUFBSSxDQUFDd0IsT0FBTyxDQUFDRyxPQUFPLENBQUNELElBQUksQ0FBQyxJQUFJLENBQUNGLE9BQU8sQ0FBQztJQUMzRCxJQUFJLENBQUNBLE9BQU8sQ0FBQ3BCLHNCQUFzQixHQUFHLEtBQUs7RUFDN0M7RUFFQSxNQUFNd0Isb0JBQW9CQSxDQUFDQyxPQUFPLEVBQUVDLEtBQUssRUFBRUMsT0FBTyxFQUFFO0lBQ2xELE1BQU1DLFVBQVUsR0FBRztNQUNqQkMsU0FBUyxFQUFFLEtBQUs7TUFDaEJDLFlBQVksRUFBRSxJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsaUJBQWlCLENBQUNDLGFBQWE7TUFDdERSLE9BQU87TUFDUEM7SUFDRixDQUFDO0lBRUQsSUFBSSxNQUFNLElBQUksQ0FBQ0ssR0FBRyxDQUFDRyxZQUFZLENBQUNOLFVBQVUsQ0FBQ0gsT0FBTyxFQUFFQyxLQUFLLENBQUMsRUFBRTtNQUMxREUsVUFBVSxDQUFDQyxTQUFTLEdBQUcsSUFBSTtJQUM3QixDQUFDLE1BQU07TUFDTCxJQUFJLEVBQUMsTUFBTU0sZ0JBQU8sQ0FBQ0MsV0FBVyxDQUFDWCxPQUFPLENBQUMsR0FBRTtRQUN2QyxJQUFJLENBQUNwQixHQUFHLENBQUNnQyxJQUFJLENBQ1Ysc0JBQXFCWixPQUFRLHNCQUFxQixHQUNsRCxnREFBK0NFLE9BQVEscUJBQW9CLEdBQzNFLHNHQUNILENBQUM7UUFDRCxNQUFNVyxPQUFPLEdBQUdDLGFBQUksQ0FBQ0MsT0FBTyxDQUFDYixPQUFPLEVBQUVZLGFBQUksQ0FBQ0UsUUFBUSxDQUFDaEIsT0FBTyxDQUFDLENBQUM7UUFDN0QsTUFBTWlCLFdBQUUsQ0FBQ0MsUUFBUSxDQUFDbEIsT0FBTyxFQUFFYSxPQUFPLENBQUM7UUFDbkNWLFVBQVUsQ0FBQ0gsT0FBTyxHQUFHYSxPQUFPO01BQzlCO01BQ0EsTUFBTUgsZ0JBQU8sQ0FBQ1MsT0FBTyxDQUFDLElBQUksQ0FBQ2IsR0FBRyxFQUFFSCxVQUFVLENBQUNILE9BQU8sQ0FBQztJQUNyRDtJQUVBLElBQUlDLEtBQUssS0FBS3JDLHNCQUFzQixLQUFJLE1BQU0sSUFBSSxDQUFDMEMsR0FBRyxDQUFDYyxjQUFjLENBQUNuQixLQUFLLENBQUMsR0FBRTtNQUc1RUUsVUFBVSxDQUFDRSxZQUFZLEdBQUcsSUFBSSxDQUFDQyxHQUFHLENBQUNDLGlCQUFpQixDQUFDYyxzQkFBc0I7SUFDN0UsQ0FBQyxNQUFNLElBQUlwQixLQUFLLEtBQUt2QyxpQkFBaUIsRUFBRTtNQUN0Q3lDLFVBQVUsQ0FBQ0UsWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDQyxHQUFHLENBQUNnQiwwQkFBMEIsQ0FBQ25CLFVBQVUsQ0FBQ0gsT0FBTyxFQUFFQyxLQUFLLENBQUM7SUFDaEc7SUFFQSxPQUFPRSxVQUFVO0VBQ25CO0VBT0EsTUFBTW9CLGdCQUFnQkEsQ0FBRUMsY0FBYyxHQUFHaEUsc0JBQXNCLEdBQUcsSUFBSSxFQUFFO0lBQ3RFLE1BQU0wQyxPQUFPLEdBQUcsTUFBTXVCLGdCQUFPLENBQUNDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLElBQUk7TUFDRixNQUFNQyxZQUFZLEdBQUcsTUFBTUMsaUJBQUMsQ0FBQ0MsR0FBRyxDQUM5QixDQUNFO1FBQ0U3QixPQUFPLEVBQUU4Qix5Q0FBTztRQUNoQjdCLEtBQUssRUFBRXZDO01BQ1QsQ0FBQyxFQUFFO1FBQ0RzQyxPQUFPLEVBQUUrQix1Q0FBVztRQUNwQjlCLEtBQUssRUFBRXJDO01BQ1QsQ0FBQyxDQUNGLENBQUNvRSxHQUFHLENBQUMsQ0FBQztRQUFDaEMsT0FBTztRQUFFQztNQUFLLENBQUMsS0FBSyxJQUFJLENBQUNGLG9CQUFvQixDQUFDQyxPQUFPLEVBQUVDLEtBQUssRUFBRUMsT0FBTyxDQUFDLENBQ2hGLENBQUM7TUFFRCxJQUFJLENBQUN0QixHQUFHLENBQUNxRCxLQUFLLENBQUUsMkJBQTBCQyxJQUFJLENBQUNDLFNBQVMsQ0FBQ1IsWUFBWSxDQUFFLEVBQUMsQ0FBQztNQUd6RSxNQUFNUyw2QkFBNkIsR0FBR1QsWUFBWSxDQUFDVSxJQUFJLENBQUMsQ0FBQztRQUFDakM7TUFBUyxDQUFDLEtBQUssQ0FBQ0EsU0FBUyxDQUFDLElBQzlFdUIsWUFBWSxDQUFDVSxJQUFJLENBQUMsQ0FBQztRQUFDaEM7TUFBWSxDQUFDLEtBQUtBLFlBQVksS0FBSyxJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsaUJBQWlCLENBQUNDLGFBQWEsQ0FBQyxJQUM3RixDQUFDbUIsWUFBWSxDQUFDVyxLQUFLLENBQUMsQ0FBQztRQUFDakM7TUFBWSxDQUFDLEtBQUtBLFlBQVksS0FBSyxJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsaUJBQWlCLENBQUNDLGFBQWEsQ0FBRTtNQUc1RyxNQUFNK0IsMkJBQTJCLEdBQUdILDZCQUE2QixJQUFJVCxZQUFZLENBQUNVLElBQUksQ0FBQyxDQUFDO1FBQUNoQztNQUFZLENBQUMsS0FBSyxDQUN6RyxJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsaUJBQWlCLENBQUNDLGFBQWEsRUFDeEMsSUFBSSxDQUFDRixHQUFHLENBQUNDLGlCQUFpQixDQUFDaUMsdUJBQXVCLENBQ25ELENBQUNDLFFBQVEsQ0FBQ3BDLFlBQVksQ0FBQyxDQUFDO01BQ3pCLElBQUksQ0FBQ3pCLEdBQUcsQ0FBQzhELElBQUksQ0FBRSx1QkFBc0JILDJCQUEyQixHQUFHLEVBQUUsR0FBRyxNQUFPLDJCQUEwQixDQUFDO01BQzFHLElBQUlBLDJCQUEyQixJQUFJSCw2QkFBNkIsRUFBRTtRQUNoRSxJQUFJLENBQUN4RCxHQUFHLENBQUM4RCxJQUFJLENBQUMsa0RBQWtELENBQUM7TUFDbkU7TUFDQSxJQUFJTiw2QkFBNkIsRUFBRTtRQUNqQyxNQUFNTyxrQkFBa0IsR0FBRyxNQUFPQyxLQUFLLElBQUs7VUFDMUMsSUFBSTtZQUNGLE1BQU0sSUFBSSxDQUFDdEMsR0FBRyxDQUFDdUMsWUFBWSxDQUFDRCxLQUFLLENBQUM7VUFDcEMsQ0FBQyxDQUFDLE9BQU9FLEdBQUcsRUFBRTtZQUNaLElBQUksQ0FBQ2xFLEdBQUcsQ0FBQzhELElBQUksQ0FBRSxxQkFBb0JFLEtBQU0sTUFBS0UsR0FBRyxDQUFDQyxPQUFRLEVBQUMsQ0FBQztVQUM5RDtRQUNGLENBQUM7UUFDRCxNQUFNbkIsaUJBQUMsQ0FBQ0MsR0FBRyxDQUFDRixZQUFZLENBQUNLLEdBQUcsQ0FBQyxDQUFDO1VBQUMvQjtRQUFLLENBQUMsS0FBSzBDLGtCQUFrQixDQUFDMUMsS0FBSyxDQUFDLENBQUMsQ0FBQztNQUN2RTtNQUNBLElBQUlzQywyQkFBMkIsRUFBRTtRQUMvQixNQUFNUyxVQUFVLEdBQUcsTUFBT0MsT0FBTyxJQUFLO1VBQ3BDLE1BQU0sSUFBSSxDQUFDM0MsR0FBRyxDQUFDNEMsT0FBTyxDQUFDRCxPQUFPLEVBQUU7WUFDOUJFLGFBQWEsRUFBRSxJQUFJO1lBQ25CQyxPQUFPLEVBQUUsSUFBSTtZQUNiMUQsT0FBTyxFQUFFOEIsY0FBYztZQUN2QjZCLGNBQWMsRUFBRTtVQUNsQixDQUFDLENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTXpCLGlCQUFDLENBQUNDLEdBQUcsQ0FBQ0YsWUFBWSxDQUFDSyxHQUFHLENBQUMsQ0FBQztVQUFDaEM7UUFBTyxDQUFDLEtBQUtnRCxVQUFVLENBQUNoRCxPQUFPLENBQUMsQ0FBQyxDQUFDO01BQ25FO0lBQ0YsQ0FBQyxTQUFTO01BQ1IsTUFBTWlCLFdBQUUsQ0FBQ3FDLE1BQU0sQ0FBQ3BELE9BQU8sQ0FBQztJQUMxQjtJQUVBLE1BQU0sSUFBSSxDQUFDcUQsMEJBQTBCLENBQUMsQ0FBQztFQUN6QztFQUVBLE1BQU1BLDBCQUEwQkEsQ0FBQSxFQUFJO0lBQ2xDLElBQUksQ0FBQzNFLEdBQUcsQ0FBQ3FELEtBQUssQ0FBRSxpQkFBZ0J4RSx1QkFBd0IsaUNBQWdDLENBQUM7SUFDekYsSUFBSStGLG9CQUFvQixHQUFHLEtBQUs7SUFDaEMsSUFBSUMsUUFBUSxHQUFHLEVBQUU7SUFDakIsSUFBSUMsT0FBTyxHQUFHLElBQUk7SUFDbEIsSUFBSTtNQUNGLE1BQU0sSUFBQUMsMEJBQWdCLEVBQUMsWUFBWTtRQUNqQyxJQUFJLENBQUNILG9CQUFvQixFQUFFO1VBQ3pCRSxPQUFPLEdBQUcsSUFBSTtVQUNkRCxRQUFRLEdBQUcsRUFBRTtVQUNiLElBQUk7WUFDRkEsUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDbkQsR0FBRyxDQUFDc0QsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1VBQ3BFLENBQUMsQ0FBQyxPQUFPQyxDQUFDLEVBQUU7WUFDVkgsT0FBTyxHQUFHRyxDQUFDO1VBQ2I7VUFDQSxJQUFJSixRQUFRLENBQUNoQixRQUFRLENBQUMsc0NBQXNDLENBQUMsRUFBRTtZQUM3RGlCLE9BQU8sR0FBRyxJQUFJekUsS0FBSyxDQUFFLG9DQUFtQ3dFLFFBQVMsRUFBQyxDQUFDO1lBQ25FQSxRQUFRLEdBQUcsRUFBRTtVQUNmLENBQUMsTUFBTSxJQUFJQSxRQUFRLENBQUNoQixRQUFRLENBQUM1RSxzQkFBc0IsQ0FBQyxFQUFFO1lBQ3BENEYsUUFBUSxHQUFHLEVBQUU7WUFDYixJQUFJLENBQUM3RSxHQUFHLENBQUNxRCxLQUFLLENBQUUsMkJBQTBCcEUsc0JBQXVCLGdCQUFlLENBQUM7WUFFakYyRixvQkFBb0IsR0FBRyxJQUFJO1VBQzdCLENBQUMsTUFBTSxJQUFJLENBQUNFLE9BQU8sRUFBRTtZQUNuQkEsT0FBTyxHQUFHLElBQUl6RSxLQUFLLENBQUMsNkRBQTZELENBQUM7VUFDcEY7UUFDRjtRQUNBLE9BQU91RSxvQkFBb0I7TUFDN0IsQ0FBQyxFQUFFO1FBQ0RNLE1BQU0sRUFBRXJHLHVCQUF1QjtRQUMvQnNHLFVBQVUsRUFBRTtNQUNkLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQyxPQUFPakIsR0FBRyxFQUFFO01BQ1osSUFBSSxDQUFDbEUsR0FBRyxDQUFDb0YsS0FBSyxDQUFFLDBDQUF5Q25HLHNCQUF1QixNQUFLLENBQUM2RixPQUFPLElBQUksQ0FBQyxDQUFDLEVBQUVYLE9BQVEsRUFBQyxDQUFDO01BQy9HLElBQUlVLFFBQVEsRUFBRTtRQUNaLElBQUksQ0FBQzdFLEdBQUcsQ0FBQ3FELEtBQUssQ0FBQyxvQkFBb0IsQ0FBQztRQUNwQyxLQUFLLE1BQU1nQyxJQUFJLElBQUlSLFFBQVEsQ0FBQ1MsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO1VBQ3ZDLElBQUksQ0FBQ3RGLEdBQUcsQ0FBQ3FELEtBQUssQ0FBRSxPQUFNZ0MsSUFBSSxDQUFDYixPQUFPLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFFLEVBQUMsQ0FBQztRQUMvRDtNQUNGO0lBQ0Y7RUFDRjtFQUVBLE1BQU1lLFlBQVlBLENBQUVDLElBQUksRUFBRTtJQUN4QixNQUFNLElBQUksQ0FBQ0MsMEJBQTBCLENBQUMsQ0FBQztJQUN2QyxJQUFJRCxJQUFJLENBQUNFLHNCQUFzQixFQUFFO01BQy9CLElBQUksQ0FBQzFGLEdBQUcsQ0FBQzhELElBQUksQ0FBRSx3RkFBdUYsQ0FBQztJQUN6RyxDQUFDLE1BQU07TUFDTCxJQUFJLENBQUM5RCxHQUFHLENBQUM4RCxJQUFJLENBQUUsZ0NBQStCNkIsaUNBQWMsRUFBQyxDQUFDO01BQzlELElBQUksQ0FBQzNGLEdBQUcsQ0FBQzhELElBQUksQ0FBRSxtQ0FBa0NaLHlDQUFRLG9CQUFtQkMsdUNBQVksR0FBRSxDQUFDO0lBQzdGO0lBRUEsTUFBTXJDLE9BQU8sR0FBRzBFLElBQUksQ0FBQ0ksK0JBQStCLElBQUlqSCxxQkFBcUI7SUFDN0UsTUFBTWtILEtBQUssR0FBRyxJQUFJQyxlQUFNLENBQUNDLEtBQUssQ0FBQyxDQUFDLENBQUNDLEtBQUssQ0FBQyxDQUFDO0lBQ3hDLElBQUlDLE9BQU8sR0FBRyxDQUFDO0lBQ2YsTUFBTUMsVUFBVSxHQUFHLENBQUM7SUFDcEIsTUFBTUMsbUJBQW1CLEdBQUcsSUFBSTtJQUNoQyxPQUFPRixPQUFPLEdBQUdDLFVBQVUsRUFBRTtNQUMzQixJQUFJLENBQUNsRyxHQUFHLENBQUM4RCxJQUFJLENBQUUsaUJBQWdCaEQsT0FBUSxxQ0FBb0MsQ0FBQztNQUM1RSxJQUFJLENBQUNDLE9BQU8sQ0FBQ3BCLHNCQUFzQixHQUFHLEtBQUs7TUFDM0MsTUFBTSxJQUFJLENBQUN5RywyQkFBMkIsQ0FBQyxDQUFDO01BQ3hDLElBQUksQ0FBQyxJQUFJLENBQUNyRixPQUFPLENBQUNwQixzQkFBc0IsRUFBRTtRQUN4QyxJQUFJO1VBQ0YsTUFBTSxJQUFBb0YsMEJBQWdCLEVBQUMsWUFBWTtZQUNqQyxJQUFJO2NBQ0YsTUFBTSxJQUFJLENBQUNoRSxPQUFPLENBQUNHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDO2NBQzVDLE9BQU8sSUFBSTtZQUNiLENBQUMsQ0FBQyxPQUFPZ0QsR0FBRyxFQUFFO2NBRVosT0FBTyxJQUFJLENBQUNuRCxPQUFPLENBQUNwQixzQkFBc0I7WUFDNUM7VUFDRixDQUFDLEVBQUU7WUFDRHVGLE1BQU0sRUFBRXBFLE9BQU87WUFDZnFFLFVBQVUsRUFBRTtVQUNkLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxPQUFPakIsR0FBRyxFQUFFO1VBQ1osSUFBSSxDQUFDbEUsR0FBRyxDQUFDcUcsYUFBYSxDQUFFLDREQUEyRHZGLE9BQVEsY0FBYSxHQUNwRyx5RkFBeUYsR0FDeEYsMEZBQXlGLENBQUM7UUFDakc7TUFDRjtNQUNBLElBQUksQ0FBQyxJQUFJLENBQUNDLE9BQU8sQ0FBQ3BCLHNCQUFzQixFQUFFO1FBQ3hDO01BQ0Y7TUFFQXNHLE9BQU8sRUFBRTtNQUNULElBQUlBLE9BQU8sSUFBSUMsVUFBVSxFQUFFO1FBQ3pCLElBQUksQ0FBQ2xHLEdBQUcsQ0FBQ3FHLGFBQWEsQ0FBQyxxREFBcUQsR0FDeEUsd0ZBQXdGLENBQUM7TUFDL0Y7TUFDQSxJQUFJLENBQUNyRyxHQUFHLENBQUNnQyxJQUFJLENBQUUsZ0VBQStELEdBQ3pFLG1DQUFrQ2lFLE9BQVEsT0FBTUMsVUFBVSxHQUFHLENBQUUsR0FBRSxDQUFDO01BQ3ZFLE1BQU0sSUFBSSxDQUFDVCwwQkFBMEIsQ0FBQyxJQUFJLENBQUM7TUFDM0MsTUFBTXpDLGlCQUFDLENBQUNzRCxLQUFLLENBQUNILG1CQUFtQixDQUFDO0lBQ3BDO0lBRUEsSUFBSSxDQUFDbkcsR0FBRyxDQUFDcUQsS0FBSyxDQUFFLHlEQUF3RCxHQUNuRSxHQUFFd0MsS0FBSyxDQUFDVSxXQUFXLENBQUMsQ0FBQyxDQUFDQyxjQUFjLENBQUNDLE9BQU8sQ0FBQyxDQUFDLENBQUUsSUFBRyxDQUFDO0lBQ3pELE1BQU0sSUFBSSxDQUFDMUYsT0FBTyxDQUFDRyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRTtNQUM3Q3dGLFlBQVksRUFBRTtRQUNaQyxVQUFVLEVBQUUsQ0FBQ25CLElBQUksQ0FBQztRQUNsQm9CLFdBQVcsRUFBRSxDQUFDO01BQ2hCO0lBQ0YsQ0FBQyxDQUFDO0VBQ0o7RUFFQSxNQUFNUiwyQkFBMkJBLENBQUEsRUFBSTtJQUNuQyxNQUFNUyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQztJQUN0QyxJQUFJLElBQUksQ0FBQ0Msc0JBQXNCLEVBQUU7TUFDL0JELEdBQUcsQ0FBQ0UsSUFBSSxDQUFDLHVCQUF1QixDQUFDO0lBQ25DO0lBQ0EsSUFBSUMsZUFBQyxDQUFDQyxTQUFTLENBQUMsSUFBSSxDQUFDM0csbUNBQW1DLENBQUMsRUFBRTtNQUN6RHVHLEdBQUcsQ0FBQ0UsSUFBSSxDQUFDLElBQUksRUFBRSx5Q0FBeUMsRUFBRSxJQUFJLENBQUN6RyxtQ0FBbUMsQ0FBQztJQUNyRztJQUVBdUcsR0FBRyxDQUFDRSxJQUFJLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFLElBQUksQ0FBQztJQUN4Q0YsR0FBRyxDQUFDRSxJQUFJLENBQUM5SCxzQkFBc0IsQ0FBQztJQUNoQyxNQUFNaUksc0JBQXNCLEdBQUcsSUFBSSxDQUFDeEYsR0FBRyxDQUFDeUYsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBR04sR0FBRyxDQUFDLENBQUM7SUFDM0VLLHNCQUFzQixDQUFDRSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUNDLE1BQU0sRUFBRUMsTUFBTSxLQUFLO01BQ3RELE1BQU1DLE1BQU0sR0FBR1AsZUFBQyxDQUFDUSxJQUFJLENBQUNILE1BQU0sSUFBSUMsTUFBTSxDQUFDO01BQ3ZDLElBQUlDLE1BQU0sRUFBRTtRQUNWckkscUJBQXFCLENBQUNtRSxLQUFLLENBQUNrRSxNQUFNLENBQUM7TUFDckM7SUFDRixDQUFDLENBQUM7SUFDRkwsc0JBQXNCLENBQUNFLEVBQUUsQ0FBQyxNQUFNLEVBQUdLLElBQUksSUFBSztNQUMxQ3ZJLHFCQUFxQixDQUFDbUUsS0FBSyxDQUFFLG9DQUFtQ29FLElBQUssRUFBQyxDQUFDO01BQ3ZFLElBQUksQ0FBQzFHLE9BQU8sQ0FBQ3BCLHNCQUFzQixHQUFHLElBQUk7SUFDNUMsQ0FBQyxDQUFDO0lBQ0YsTUFBTXVILHNCQUFzQixDQUFDbEIsS0FBSyxDQUFDLENBQUMsQ0FBQztFQUN2QztFQUVBLE1BQU0wQixhQUFhQSxDQUFBLEVBQUk7SUFDckIsSUFBSSxDQUFDMUgsR0FBRyxDQUFDcUQsS0FBSyxDQUFDLHNDQUFzQyxDQUFDO0lBR3RELElBQUk7TUFDRixNQUFNLElBQUksQ0FBQ3RDLE9BQU8sQ0FBQ0csT0FBTyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUM7SUFDM0MsQ0FBQyxDQUFDLE9BQU9nRCxHQUFHLEVBQUU7TUFDWixJQUFJLENBQUNsRSxHQUFHLENBQUNnQyxJQUFJLENBQUUsOERBQTZELEdBQ3ZFLGNBQWFrQyxHQUFJLEVBQUMsQ0FBQztJQUMxQjtFQUNGO0VBRUEsTUFBTXVCLDBCQUEwQkEsQ0FBRWtDLGFBQWEsR0FBRyxLQUFLLEVBQUU7SUFDdkQsSUFBSSxDQUFDM0gsR0FBRyxDQUFDcUQsS0FBSyxDQUFFLGNBQWFzRSxhQUFhLEdBQUcsUUFBUSxHQUFHLFNBQVUsa0NBQWlDLENBQUM7SUFFcEcsSUFBSTtNQUNGLE1BQU07UUFBQ0M7TUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUFDLGNBQUssRUFBQztRQUMzQnJJLEdBQUcsRUFBRyxVQUFTLElBQUksQ0FBQ2lCLElBQUssSUFBRyxJQUFJLENBQUNFLFVBQVcsV0FBVTtRQUN0REcsT0FBTyxFQUFFO01BQ1gsQ0FBQyxDQUFDLEVBQUVnSCxJQUFJO01BQ1IsTUFBTUMsZ0JBQWdCLEdBQUdILEtBQUssQ0FBQ3hFLEdBQUcsQ0FBQyxDQUFDO1FBQUM0RTtNQUFFLENBQUMsS0FBS0EsRUFBRSxDQUFDLENBQUNDLE1BQU0sQ0FBQ0MsT0FBTyxDQUFDO01BQ2hFLElBQUlILGdCQUFnQixDQUFDSSxNQUFNLEVBQUU7UUFDM0IsSUFBSSxDQUFDbkksR0FBRyxDQUFDcUQsS0FBSyxDQUFFLHNEQUFxREMsSUFBSSxDQUFDQyxTQUFTLENBQUN3RSxnQkFBZ0IsQ0FBRSxFQUFDLENBQUM7UUFDeEcsSUFBSSxDQUFDL0gsR0FBRyxDQUFDcUQsS0FBSyxDQUFFLGVBQWNsRCxhQUFJLENBQUNpSSxTQUFTLENBQUMsa0JBQWtCLEVBQUVMLGdCQUFnQixDQUFDSSxNQUFNLEVBQUUsSUFBSSxDQUFFLEVBQUMsQ0FBQztRQUNsRyxNQUFNbkYsaUJBQUMsQ0FBQ0MsR0FBRyxDQUFDOEUsZ0JBQWdCLENBQ3pCM0UsR0FBRyxDQUFFNEUsRUFBRSxJQUFLSCxjQUFLLENBQUNRLE1BQU0sQ0FBRSxVQUFTLElBQUksQ0FBQzVILElBQUssSUFBRyxJQUFJLENBQUNFLFVBQVcsWUFBV3FILEVBQUcsRUFBQyxDQUFDLENBQ25GLENBQUM7UUFFRCxNQUFNaEYsaUJBQUMsQ0FBQ3NELEtBQUssQ0FBQyxJQUFJLENBQUM7TUFDckIsQ0FBQyxNQUFNO1FBQ0wsSUFBSSxDQUFDdEcsR0FBRyxDQUFDcUQsS0FBSyxDQUFDLHlDQUF5QyxDQUFDO01BQzNEO0lBQ0YsQ0FBQyxDQUFDLE9BQU80QixDQUFDLEVBQUU7TUFDVixJQUFJLENBQUNqRixHQUFHLENBQUNxRCxLQUFLLENBQUUsNENBQTJDNEIsQ0FBQyxDQUFDZCxPQUFRLEdBQUUsQ0FBQztJQUMxRTtJQUVBLElBQUk7TUFDRixNQUFNLElBQUksQ0FBQ3pDLEdBQUcsQ0FBQzRHLFNBQVMsQ0FBQ3RKLHNCQUFzQixDQUFDO0lBQ2xELENBQUMsQ0FBQyxPQUFPdUosTUFBTSxFQUFFLENBQUM7SUFDbEIsSUFBSSxDQUFDWixhQUFhLEVBQUU7TUFDbEI7SUFDRjtJQUVBLElBQUk7TUFDRixNQUFNLElBQUksQ0FBQ2pHLEdBQUcsQ0FBQzhHLG1CQUFtQixDQUFDLGFBQWEsQ0FBQztJQUNuRCxDQUFDLENBQUMsT0FBT0QsTUFBTSxFQUFFLENBQUM7RUFDcEI7QUFDRjtBQUFDeEosT0FBQSxDQUFBZSxrQkFBQSxHQUFBQSxrQkFBQTtBQUFBLElBQUEySSxRQUFBLEdBR2MzSSxrQkFBa0I7QUFBQWYsT0FBQSxDQUFBMkosT0FBQSxHQUFBRCxRQUFBIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"uiautomator2.js","names":["_lodash","_interopRequireDefault","require","_driver","_asyncbox","_appiumUiautomator2Server","_support","_bluebird","_helpers","_axios","_path","REQD_PARAMS","SERVER_LAUNCH_TIMEOUT","SERVER_INSTALL_RETRIES","SERVICES_LAUNCH_TIMEOUT","SERVER_PACKAGE_ID","exports","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","_default","default"],"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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"}
1
+ {"version":3,"file":"uiautomator2.js","names":["_lodash","_interopRequireDefault","require","_driver","_asyncbox","_appiumUiautomator2Server","_support","_bluebird","_helpers","_axios","_path","REQD_PARAMS","SERVER_LAUNCH_TIMEOUT","SERVER_INSTALL_RETRIES","SERVICES_LAUNCH_TIMEOUT","SERVER_PACKAGE_ID","exports","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","prepareServerPackage","appPath","appId","tmpRoot","resultInfo","wasSigned","installState","adb","APP_INSTALL_STATE","NOT_INSTALLED","checkApkCert","helpers","isWriteable","warn","dstPath","path","resolve","basename","fs","copyFile","signApp","isAppInstalled","SAME_VERSION_INSTALLED","getApplicationInstallState","installServerApk","installTimeout","tempDir","openDir","packagesInfo","B","all","apkPath","testApkPath","map","debug","JSON","stringify","shouldUninstallServerPackages","some","every","shouldInstallServerPackages","OLDER_VERSION_INSTALLED","includes","info","silentUninstallPkg","pkgId","uninstallApk","err","message","installPkg","pkgPath","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","pluralize","delete","forceStop","ignore","killProcessesByName","_default","default"],"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 async prepareServerPackage(appPath, appId, tmpRoot) {\n const resultInfo = {\n wasSigned: false,\n installState: this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n appPath,\n appId,\n };\n\n if (await this.adb.checkApkCert(resultInfo.appPath, appId)) {\n resultInfo.wasSigned = true;\n } else {\n if (!await helpers.isWriteable(appPath)) {\n this.log.warn(\n `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 );\n const dstPath = path.resolve(tmpRoot, path.basename(appPath));\n await fs.copyFile(appPath, dstPath);\n resultInfo.appPath = dstPath;\n }\n await helpers.signApp(this.adb, resultInfo.appPath);\n }\n\n if (appId === SERVER_TEST_PACKAGE_ID && await this.adb.isAppInstalled(appId)) {\n // There is no point in getting the state for the test server,\n // since it does not contain any version info\n resultInfo.installState = this.adb.APP_INSTALL_STATE.SAME_VERSION_INSTALLED;\n } else if (appId === SERVER_PACKAGE_ID) {\n resultInfo.installState = await this.adb.getApplicationInstallState(resultInfo.appPath, appId);\n }\n\n return resultInfo;\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 try {\n const packagesInfo = await B.all(\n [\n {\n appPath: apkPath,\n appId: SERVER_PACKAGE_ID,\n }, {\n appPath: testApkPath,\n appId: SERVER_TEST_PACKAGE_ID,\n },\n ].map(({appPath, appId}) => this.prepareServerPackage(appPath, appId, tmpRoot))\n );\n\n this.log.debug(`Server packages status: ${JSON.stringify(packagesInfo)}`);\n // We want to enforce uninstall in case the current server package has not been signed properly\n // or if any of server packages is not installed, while the other does\n const shouldUninstallServerPackages = packagesInfo.some(({wasSigned}) => !wasSigned)\n || (packagesInfo.some(({installState}) => installState === this.adb.APP_INSTALL_STATE.NOT_INSTALLED)\n && !packagesInfo.every(({installState}) => installState === this.adb.APP_INSTALL_STATE.NOT_INSTALLED));\n // Install must always follow uninstall. Also, perform the install if\n // any of server packages is not installed or is outdated\n const shouldInstallServerPackages = shouldUninstallServerPackages || packagesInfo.some(({installState}) => [\n this.adb.APP_INSTALL_STATE.NOT_INSTALLED,\n this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,\n ].includes(installState));\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 if (shouldUninstallServerPackages) {\n const silentUninstallPkg = async (pkgId) => {\n try {\n await this.adb.uninstallApk(pkgId);\n } catch (err) {\n this.log.info(`Cannot uninstall '${pkgId}': ${err.message}`);\n }\n };\n await B.all(packagesInfo.map(({appId}) => silentUninstallPkg(appId)));\n }\n if (shouldInstallServerPackages) {\n const installPkg = async (pkgPath) => {\n await this.adb.install(pkgPath, {\n noIncremental: true,\n replace: true,\n timeout: installTimeout,\n timeoutCapName: 'uiautomator2ServerInstallTimeout'\n });\n };\n await B.all(packagesInfo.map(({appPath}) => installPkg(appPath)));\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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"}
@@ -60,6 +60,41 @@ class UiAutomator2Server {
60
60
  this.jwproxy.didInstrumentationExit = false;
61
61
  }
62
62
 
63
+ async prepareServerPackage(appPath, appId, tmpRoot) {
64
+ const resultInfo = {
65
+ wasSigned: false,
66
+ installState: this.adb.APP_INSTALL_STATE.NOT_INSTALLED,
67
+ appPath,
68
+ appId,
69
+ };
70
+
71
+ if (await this.adb.checkApkCert(resultInfo.appPath, appId)) {
72
+ resultInfo.wasSigned = true;
73
+ } else {
74
+ if (!await helpers.isWriteable(appPath)) {
75
+ this.log.warn(
76
+ `Server package at '${appPath}' is not writeable. ` +
77
+ `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` +
78
+ `Consider making this file writeable manually in order to improve the performance of session startup.`
79
+ );
80
+ const dstPath = path.resolve(tmpRoot, path.basename(appPath));
81
+ await fs.copyFile(appPath, dstPath);
82
+ resultInfo.appPath = dstPath;
83
+ }
84
+ await helpers.signApp(this.adb, resultInfo.appPath);
85
+ }
86
+
87
+ if (appId === SERVER_TEST_PACKAGE_ID && await this.adb.isAppInstalled(appId)) {
88
+ // There is no point in getting the state for the test server,
89
+ // since it does not contain any version info
90
+ resultInfo.installState = this.adb.APP_INSTALL_STATE.SAME_VERSION_INSTALLED;
91
+ } else if (appId === SERVER_PACKAGE_ID) {
92
+ resultInfo.installState = await this.adb.getApplicationInstallState(resultInfo.appPath, appId);
93
+ }
94
+
95
+ return resultInfo;
96
+ }
97
+
63
98
  /**
64
99
  * Installs the apks on to the device or emulator.
65
100
  *
@@ -67,90 +102,55 @@ class UiAutomator2Server {
67
102
  */
68
103
  async installServerApk (installTimeout = SERVER_INSTALL_RETRIES * 1000) {
69
104
  const tmpRoot = await tempDir.openDir();
70
- const packageInfosMapper = async ({appPath, appId}) => {
71
- if (await helpers.isWriteable(appPath)) {
72
- return { appPath, appId };
73
- }
74
-
75
- this.log.info(`Server package at '${appPath}' is not writeable. ` +
76
- `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` +
77
- `Consider making this file writeable manually in order to improve the performance of session startup.`);
78
- const dstPath = path.resolve(tmpRoot, path.basename(appPath));
79
- await fs.copyFile(appPath, dstPath);
80
- return {
81
- appPath: dstPath,
82
- appId,
83
- };
84
- };
85
-
86
105
  try {
87
- const packagesInfo = await B.all(B.map([
88
- {
89
- appPath: apkPath,
90
- appId: SERVER_PACKAGE_ID,
91
- }, {
92
- appPath: testApkPath,
93
- appId: SERVER_TEST_PACKAGE_ID,
94
- },
95
- ], packageInfosMapper));
96
-
97
- let shouldUninstallServerPackages = false;
98
- let shouldInstallServerPackages = false;
99
- for (const {appId, appPath} of packagesInfo) {
100
- if (appId === SERVER_TEST_PACKAGE_ID) {
101
- const isAppInstalled = await this.adb.isAppInstalled(appId);
102
-
103
- // There is no point in getting the state for test server,
104
- // since it does not contain version info
105
- if (!await this.adb.checkApkCert(appPath, appId)) {
106
- await helpers.signApp(this.adb, appPath);
107
- shouldUninstallServerPackages = shouldUninstallServerPackages || isAppInstalled;
108
- shouldInstallServerPackages = true;
109
- }
110
-
111
- if (!isAppInstalled) {
112
- shouldInstallServerPackages = true;
113
- }
114
- continue;
115
- }
106
+ const packagesInfo = await B.all(
107
+ [
108
+ {
109
+ appPath: apkPath,
110
+ appId: SERVER_PACKAGE_ID,
111
+ }, {
112
+ appPath: testApkPath,
113
+ appId: SERVER_TEST_PACKAGE_ID,
114
+ },
115
+ ].map(({appPath, appId}) => this.prepareServerPackage(appPath, appId, tmpRoot))
116
+ );
116
117
 
117
- const appState = await this.adb.getApplicationInstallState(appPath, appId);
118
- this.log.debug(`${appId} installation state: ${appState}`);
119
- if (await this.adb.checkApkCert(appPath, appId)) {
120
- shouldUninstallServerPackages = shouldUninstallServerPackages || [
121
- this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,
122
- this.adb.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED,
123
- ].includes(appState);
124
- } else {
125
- await helpers.signApp(this.adb, appPath);
126
- shouldUninstallServerPackages = shouldUninstallServerPackages || ![
127
- this.adb.APP_INSTALL_STATE.NOT_INSTALLED,
128
- ].includes(appState);
129
- }
130
- shouldInstallServerPackages = shouldInstallServerPackages || shouldUninstallServerPackages || [
131
- this.adb.APP_INSTALL_STATE.NOT_INSTALLED,
132
- ].includes(appState);
133
- }
118
+ this.log.debug(`Server packages status: ${JSON.stringify(packagesInfo)}`);
119
+ // We want to enforce uninstall in case the current server package has not been signed properly
120
+ // or if any of server packages is not installed, while the other does
121
+ const shouldUninstallServerPackages = packagesInfo.some(({wasSigned}) => !wasSigned)
122
+ || (packagesInfo.some(({installState}) => installState === this.adb.APP_INSTALL_STATE.NOT_INSTALLED)
123
+ && !packagesInfo.every(({installState}) => installState === this.adb.APP_INSTALL_STATE.NOT_INSTALLED));
124
+ // Install must always follow uninstall. Also, perform the install if
125
+ // any of server packages is not installed or is outdated
126
+ const shouldInstallServerPackages = shouldUninstallServerPackages || packagesInfo.some(({installState}) => [
127
+ this.adb.APP_INSTALL_STATE.NOT_INSTALLED,
128
+ this.adb.APP_INSTALL_STATE.OLDER_VERSION_INSTALLED,
129
+ ].includes(installState));
134
130
  this.log.info(`Server packages are ${shouldInstallServerPackages ? '' : 'not '}going to be (re)installed`);
135
131
  if (shouldInstallServerPackages && shouldUninstallServerPackages) {
136
132
  this.log.info('Full packages reinstall is going to be performed');
137
133
  }
138
- for (const {appId, appPath} of packagesInfo) {
139
- if (shouldUninstallServerPackages) {
134
+ if (shouldUninstallServerPackages) {
135
+ const silentUninstallPkg = async (pkgId) => {
140
136
  try {
141
- await this.adb.uninstallApk(appId);
137
+ await this.adb.uninstallApk(pkgId);
142
138
  } catch (err) {
143
- this.log.warn(`Error uninstalling '${appId}': ${err.message}`);
139
+ this.log.info(`Cannot uninstall '${pkgId}': ${err.message}`);
144
140
  }
145
- }
146
- if (shouldInstallServerPackages) {
147
- await this.adb.install(appPath, {
141
+ };
142
+ await B.all(packagesInfo.map(({appId}) => silentUninstallPkg(appId)));
143
+ }
144
+ if (shouldInstallServerPackages) {
145
+ const installPkg = async (pkgPath) => {
146
+ await this.adb.install(pkgPath, {
148
147
  noIncremental: true,
149
148
  replace: true,
150
149
  timeout: installTimeout,
151
150
  timeoutCapName: 'uiautomator2ServerInstallTimeout'
152
151
  });
153
- }
152
+ };
153
+ await B.all(packagesInfo.map(({appPath}) => installPkg(appPath)));
154
154
  }
155
155
  } finally {
156
156
  await fs.rimraf(tmpRoot);
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "appium-uiautomator2-driver",
3
- "version": "2.26.3",
3
+ "version": "2.28.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-uiautomator2-driver",
9
- "version": "2.26.3",
9
+ "version": "2.28.0",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@babel/runtime": "^7.0.0",
13
13
  "appium-adb": "^9.11.5",
14
14
  "appium-android-driver": "^5.14.0",
15
15
  "appium-chromedriver": "^5.3.1",
16
- "appium-uiautomator2-server": "^5.11.1",
16
+ "appium-uiautomator2-server": "^5.12.0",
17
17
  "asyncbox": "^2.3.1",
18
18
  "axios": "^1.x",
19
19
  "bluebird": "^3.5.1",
@@ -910,7 +910,7 @@
910
910
  }
911
911
  },
912
912
  "node_modules/appium-adb": {
913
- "version": "9.12.1",
913
+ "version": "9.13.0",
914
914
  "license": "Apache-2.0",
915
915
  "dependencies": {
916
916
  "@appium/support": "^4.0.0",
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "automated testing",
8
8
  "android"
9
9
  ],
10
- "version": "2.26.3",
10
+ "version": "2.28.0",
11
11
  "author": "Appium Contributors",
12
12
  "license": "Apache-2.0",
13
13
  "repository": {
@@ -60,7 +60,7 @@
60
60
  "appium-adb": "^9.11.5",
61
61
  "appium-android-driver": "^5.14.0",
62
62
  "appium-chromedriver": "^5.3.1",
63
- "appium-uiautomator2-server": "^5.11.1",
63
+ "appium-uiautomator2-server": "^5.12.0",
64
64
  "asyncbox": "^2.3.1",
65
65
  "axios": "^1.x",
66
66
  "bluebird": "^3.5.1",