appium-android-driver 5.13.1 → 5.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/index.js +43 -40
  3. package/build/lib/android-helpers.d.ts +136 -0
  4. package/build/lib/android-helpers.d.ts.map +1 -0
  5. package/build/lib/android-helpers.js +760 -679
  6. package/build/lib/android-helpers.js.map +1 -1
  7. package/build/lib/bootstrap.d.ts +29 -0
  8. package/build/lib/bootstrap.d.ts.map +1 -0
  9. package/build/lib/bootstrap.js +192 -179
  10. package/build/lib/bootstrap.js.map +1 -1
  11. package/build/lib/commands/actions.d.ts +209 -0
  12. package/build/lib/commands/actions.d.ts.map +1 -0
  13. package/build/lib/commands/actions.js +327 -265
  14. package/build/lib/commands/actions.js.map +1 -1
  15. package/build/lib/commands/alert.d.ts +10 -0
  16. package/build/lib/commands/alert.d.ts.map +1 -0
  17. package/build/lib/commands/alert.js +12 -18
  18. package/build/lib/commands/alert.js.map +1 -1
  19. package/build/lib/commands/app-management.d.ts +314 -0
  20. package/build/lib/commands/app-management.d.ts.map +1 -0
  21. package/build/lib/commands/app-management.js +278 -110
  22. package/build/lib/commands/app-management.js.map +1 -1
  23. package/build/lib/commands/context.d.ts +94 -0
  24. package/build/lib/commands/context.d.ts.map +1 -0
  25. package/build/lib/commands/context.js +412 -260
  26. package/build/lib/commands/context.js.map +1 -1
  27. package/build/lib/commands/coverage.d.ts +5 -0
  28. package/build/lib/commands/coverage.d.ts.map +1 -0
  29. package/build/lib/commands/coverage.js +14 -17
  30. package/build/lib/commands/coverage.js.map +1 -1
  31. package/build/lib/commands/element.d.ts +36 -0
  32. package/build/lib/commands/element.d.ts.map +1 -0
  33. package/build/lib/commands/element.js +97 -127
  34. package/build/lib/commands/element.js.map +1 -1
  35. package/build/lib/commands/emu-console.d.ts +49 -0
  36. package/build/lib/commands/emu-console.d.ts.map +1 -0
  37. package/build/lib/commands/emu-console.js +36 -25
  38. package/build/lib/commands/emu-console.js.map +1 -1
  39. package/build/lib/commands/execute.d.ts +6 -0
  40. package/build/lib/commands/execute.d.ts.map +1 -0
  41. package/build/lib/commands/execute.js +68 -69
  42. package/build/lib/commands/execute.js.map +1 -1
  43. package/build/lib/commands/file-actions.d.ts +129 -0
  44. package/build/lib/commands/file-actions.d.ts.map +1 -0
  45. package/build/lib/commands/file-actions.js +321 -178
  46. package/build/lib/commands/file-actions.js.map +1 -1
  47. package/build/lib/commands/find.d.ts +13 -0
  48. package/build/lib/commands/find.d.ts.map +1 -0
  49. package/build/lib/commands/find.js +69 -51
  50. package/build/lib/commands/find.js.map +1 -1
  51. package/build/lib/commands/general.d.ts +133 -0
  52. package/build/lib/commands/general.d.ts.map +1 -0
  53. package/build/lib/commands/general.js +275 -216
  54. package/build/lib/commands/general.js.map +1 -1
  55. package/build/lib/commands/ime.d.ts +11 -0
  56. package/build/lib/commands/ime.d.ts.map +1 -0
  57. package/build/lib/commands/ime.js +27 -33
  58. package/build/lib/commands/ime.js.map +1 -1
  59. package/build/lib/commands/index.d.ts +3 -0
  60. package/build/lib/commands/index.d.ts.map +1 -0
  61. package/build/lib/commands/index.js +32 -35
  62. package/build/lib/commands/index.js.map +1 -1
  63. package/build/lib/commands/intent.d.ts +418 -0
  64. package/build/lib/commands/intent.d.ts.map +1 -0
  65. package/build/lib/commands/intent.js +281 -151
  66. package/build/lib/commands/intent.js.map +1 -1
  67. package/build/lib/commands/keyboard.d.ts +6 -0
  68. package/build/lib/commands/keyboard.d.ts.map +1 -0
  69. package/build/lib/commands/keyboard.js +6 -14
  70. package/build/lib/commands/keyboard.js.map +1 -1
  71. package/build/lib/commands/log.d.ts +45 -0
  72. package/build/lib/commands/log.d.ts.map +1 -0
  73. package/build/lib/commands/log.js +117 -103
  74. package/build/lib/commands/log.js.map +1 -1
  75. package/build/lib/commands/media-projection.d.ts +144 -0
  76. package/build/lib/commands/media-projection.d.ts.map +1 -0
  77. package/build/lib/commands/media-projection.js +228 -171
  78. package/build/lib/commands/media-projection.js.map +1 -1
  79. package/build/lib/commands/network.d.ts +139 -0
  80. package/build/lib/commands/network.d.ts.map +1 -0
  81. package/build/lib/commands/network.js +249 -181
  82. package/build/lib/commands/network.js.map +1 -1
  83. package/build/lib/commands/performance.d.ts +101 -0
  84. package/build/lib/commands/performance.d.ts.map +1 -0
  85. package/build/lib/commands/performance.js +390 -236
  86. package/build/lib/commands/performance.js.map +1 -1
  87. package/build/lib/commands/permissions.d.ts +93 -0
  88. package/build/lib/commands/permissions.d.ts.map +1 -0
  89. package/build/lib/commands/permissions.js +133 -93
  90. package/build/lib/commands/permissions.js.map +1 -1
  91. package/build/lib/commands/recordscreen.d.ts +194 -0
  92. package/build/lib/commands/recordscreen.d.ts.map +1 -0
  93. package/build/lib/commands/recordscreen.js +293 -224
  94. package/build/lib/commands/recordscreen.js.map +1 -1
  95. package/build/lib/commands/shell.d.ts +8 -0
  96. package/build/lib/commands/shell.d.ts.map +1 -0
  97. package/build/lib/commands/shell.js +38 -43
  98. package/build/lib/commands/shell.js.map +1 -1
  99. package/build/lib/commands/streamscreen.d.ts +104 -0
  100. package/build/lib/commands/streamscreen.d.ts.map +1 -0
  101. package/build/lib/commands/streamscreen.js +364 -305
  102. package/build/lib/commands/streamscreen.js.map +1 -1
  103. package/build/lib/commands/system-bars.d.ts +100 -0
  104. package/build/lib/commands/system-bars.d.ts.map +1 -0
  105. package/build/lib/commands/system-bars.js +148 -90
  106. package/build/lib/commands/system-bars.js.map +1 -1
  107. package/build/lib/commands/touch.d.ts +30 -0
  108. package/build/lib/commands/touch.d.ts.map +1 -0
  109. package/build/lib/commands/touch.js +311 -287
  110. package/build/lib/commands/touch.js.map +1 -1
  111. package/build/lib/desired-caps.d.ts +353 -0
  112. package/build/lib/desired-caps.d.ts.map +1 -0
  113. package/build/lib/desired-caps.js +291 -292
  114. package/build/lib/desired-caps.js.map +1 -1
  115. package/build/lib/driver.d.ts +430 -0
  116. package/build/lib/driver.d.ts.map +1 -0
  117. package/build/lib/driver.js +449 -384
  118. package/build/lib/driver.js.map +1 -1
  119. package/build/lib/logger.d.ts +3 -0
  120. package/build/lib/logger.d.ts.map +1 -0
  121. package/build/lib/logger.js +5 -11
  122. package/build/lib/logger.js.map +1 -1
  123. package/build/lib/method-map.d.ts +389 -0
  124. package/build/lib/method-map.d.ts.map +1 -0
  125. package/build/lib/method-map.js +220 -394
  126. package/build/lib/method-map.js.map +1 -1
  127. package/build/lib/stubs.d.ts +8 -0
  128. package/build/lib/stubs.d.ts.map +1 -0
  129. package/build/lib/stubs.js +5 -0
  130. package/build/lib/stubs.js.map +1 -0
  131. package/build/lib/uiautomator.d.ts +24 -0
  132. package/build/lib/uiautomator.d.ts.map +1 -0
  133. package/build/lib/uiautomator.js +86 -82
  134. package/build/lib/uiautomator.js.map +1 -1
  135. package/build/lib/unlock-helpers.d.ts +38 -0
  136. package/build/lib/unlock-helpers.d.ts.map +1 -0
  137. package/build/lib/unlock-helpers.js +228 -204
  138. package/build/lib/unlock-helpers.js.map +1 -1
  139. package/build/lib/utils.d.ts +11 -0
  140. package/build/lib/utils.d.ts.map +1 -0
  141. package/build/lib/utils.js +23 -18
  142. package/build/lib/utils.js.map +1 -1
  143. package/build/lib/webview-helpers.d.ts +223 -0
  144. package/build/lib/webview-helpers.d.ts.map +1 -0
  145. package/build/lib/webview-helpers.js +476 -298
  146. package/build/lib/webview-helpers.js.map +1 -1
  147. package/index.js +3 -1
  148. package/lib/android-helpers.js +2 -1
  149. package/lib/stubs.ts +8 -0
  150. package/lib/unlock-helpers.js +2 -2
  151. package/package.json +23 -14
@@ -1,320 +1,472 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
6
17
  });
7
- exports.setupNewChromedriver = exports.helpers = exports.default = exports.commands = void 0;
8
- require("source-map-support/register");
9
- var _lodash = _interopRequireDefault(require("lodash"));
10
- var _appiumChromedriver = _interopRequireDefault(require("appium-chromedriver"));
11
- var _portfinder = _interopRequireDefault(require("portfinder"));
12
- var _bluebird = _interopRequireDefault(require("bluebird"));
13
- var _support = require("@appium/support");
14
- var _driver = require("appium/driver");
15
- var _webviewHelpers = _interopRequireWildcard(require("../webview-helpers"));
16
- var _androidHelpers = require("../android-helpers");
17
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
18
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.setupNewChromedriver = exports.helpers = exports.commands = void 0;
30
+ const lodash_1 = __importDefault(require("lodash"));
31
+ const appium_chromedriver_1 = __importDefault(require("appium-chromedriver"));
32
+ const portfinder_1 = __importDefault(require("portfinder"));
33
+ const bluebird_1 = __importDefault(require("bluebird"));
34
+ const support_1 = require("@appium/support");
35
+ const driver_1 = require("appium/driver");
36
+ const webview_helpers_1 = __importStar(require("../webview-helpers"));
37
+ const android_helpers_1 = require("../android-helpers");
19
38
  const CHROMEDRIVER_AUTODOWNLOAD_FEATURE = 'chromedriver_autodownload';
20
- let commands = {},
21
- helpers = {},
22
- extensions = {};
23
- exports.helpers = helpers;
39
+ let commands = {}, helpers = {}, extensions = {};
24
40
  exports.commands = commands;
41
+ exports.helpers = helpers;
42
+ /* -------------------------------
43
+ * Actual MJSONWP command handlers
44
+ * ------------------------------- */
25
45
  commands.getCurrentContext = async function getCurrentContext() {
26
- return this.curContext || this.defaultContextName();
46
+ // if the current context is `null`, indicating no context
47
+ // explicitly set, it is the default context
48
+ return this.curContext || this.defaultContextName();
27
49
  };
28
50
  commands.getContexts = async function getContexts() {
29
- const webviewsMapping = await _webviewHelpers.default.getWebViewsMapping(this.adb, this.opts);
30
- return this.assignContexts(webviewsMapping);
51
+ const webviewsMapping = await webview_helpers_1.default.getWebViewsMapping(this.adb, this.opts);
52
+ return this.assignContexts(webviewsMapping);
31
53
  };
32
54
  commands.setContext = async function setContext(name) {
33
- if (!_support.util.hasValue(name)) {
34
- name = this.defaultContextName();
35
- } else if (name === _webviewHelpers.WEBVIEW_WIN) {
36
- name = this.defaultWebviewName();
37
- }
38
- if (name === this.curContext) {
39
- return;
40
- }
41
- const webviewsMapping = await _webviewHelpers.default.getWebViewsMapping(this.adb, this.opts);
42
- const contexts = this.assignContexts(webviewsMapping);
43
- if (!_lodash.default.includes(contexts, name)) {
44
- throw new _driver.errors.NoSuchContextError();
45
- }
46
- await this.switchContext(name, webviewsMapping);
47
- this.curContext = name;
55
+ if (!support_1.util.hasValue(name)) {
56
+ name = this.defaultContextName();
57
+ }
58
+ else if (name === webview_helpers_1.WEBVIEW_WIN) {
59
+ // handle setContext "WEBVIEW"
60
+ name = this.defaultWebviewName();
61
+ }
62
+ // if we're already in the context we want, do nothing
63
+ if (name === this.curContext) {
64
+ return;
65
+ }
66
+ const webviewsMapping = await webview_helpers_1.default.getWebViewsMapping(this.adb, this.opts);
67
+ const contexts = this.assignContexts(webviewsMapping);
68
+ // if the context we want doesn't exist, fail
69
+ if (!lodash_1.default.includes(contexts, name)) {
70
+ throw new driver_1.errors.NoSuchContextError();
71
+ }
72
+ await this.switchContext(name, webviewsMapping);
73
+ this.curContext = name;
48
74
  };
75
+ /**
76
+ * @typedef {Object} WebviewsMapping
77
+ * @property {string} proc The name of the Devtools Unix socket
78
+ * @property {string} webview The web view alias. Looks like `WEBVIEW_`
79
+ * prefix plus PID or package name
80
+ * @property {?Object} info Webview information as it is retrieved by
81
+ * /json/version CDP endpoint
82
+ * @property {?Array<Object>} pages Webview pages list as it is retrieved by
83
+ * /json/list CDP endpoint
84
+ * @propery {?string} webviewName An actual webview name for switching context.
85
+ * This value becomes null when failing to find a PID for a webview.
86
+ *
87
+ * The following json demonstrates the example of WebviewsMapping object.
88
+ * Note that `description` in `page` can be an empty string most likely when it comes to Mobile Chrome)
89
+ * {
90
+ * "proc": "@webview_devtools_remote_22138",
91
+ * "webview": "WEBVIEW_22138",
92
+ * "info": {
93
+ * "Android-Package": "io.appium.settings",
94
+ * "Browser": "Chrome/74.0.3729.185",
95
+ * "Protocol-Version": "1.3",
96
+ * "User-Agent": "Mozilla/5.0 (Linux; Android 10; Android SDK built for x86 Build/QSR1.190920.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.185 Mobile Safari/537.36",
97
+ * "V8-Version": "7.4.288.28",
98
+ * "WebKit-Version": "537.36 (@22955682f94ce09336197bfb8dffea991fa32f0d)",
99
+ * "webSocketDebuggerUrl": "ws://127.0.0.1:10900/devtools/browser"
100
+ * },
101
+ * "pages": [
102
+ * {
103
+ * "description": "{\"attached\":true,\"empty\":false,\"height\":1458,\"screenX\":0,\"screenY\":336,\"visible\":true,\"width\":1080}",
104
+ * "devtoolsFrontendUrl": "http://chrome-devtools-frontend.appspot.com/serve_rev/@22955682f94ce09336197bfb8dffea991fa32f0d/inspector.html?ws=127.0.0.1:10900/devtools/page/27325CC50B600D31B233F45E09487B1F",
105
+ * "id": "27325CC50B600D31B233F45E09487B1F",
106
+ * "title": "Releases · appium/appium · GitHub",
107
+ * "type": "page",
108
+ * "url": "https://github.com/appium/appium/releases",
109
+ * "webSocketDebuggerUrl": "ws://127.0.0.1:10900/devtools/page/27325CC50B600D31B233F45E09487B1F"
110
+ * }
111
+ * ],
112
+ * "webviewName": "WEBVIEW_com.io.appium.setting"
113
+ * }
114
+ */
115
+ /**
116
+ * Returns a webviewsMapping based on CDP endpoints
117
+ *
118
+ * @return {Array<WebviewsMapping>} webviewsMapping
119
+ */
49
120
  commands.mobileGetContexts = async function mobileGetContexts() {
50
- const opts = {
51
- androidDeviceSocket: this.opts.androidDeviceSocket,
52
- ensureWebviewsHavePages: true,
53
- webviewDevtoolsPort: this.opts.webviewDevtoolsPort,
54
- enableWebviewDetailsCollection: true
55
- };
56
- return await _webviewHelpers.default.getWebViewsMapping(this.adb, opts);
121
+ const opts = {
122
+ androidDeviceSocket: this.opts.androidDeviceSocket,
123
+ ensureWebviewsHavePages: true,
124
+ webviewDevtoolsPort: this.opts.webviewDevtoolsPort,
125
+ enableWebviewDetailsCollection: true
126
+ };
127
+ return await webview_helpers_1.default.getWebViewsMapping(this.adb, opts);
57
128
  };
58
129
  helpers.assignContexts = function assignContexts(webviewsMapping) {
59
- const opts = Object.assign({
60
- isChromeSession: this.isChromeSession
61
- }, this.opts);
62
- const webviews = _webviewHelpers.default.parseWebviewNames(webviewsMapping, opts);
63
- this.contexts = [_webviewHelpers.NATIVE_WIN, ...webviews];
64
- this.log.debug(`Available contexts: ${JSON.stringify(this.contexts)}`);
65
- return this.contexts;
130
+ const opts = Object.assign({ isChromeSession: this.isChromeSession }, this.opts);
131
+ const webviews = webview_helpers_1.default.parseWebviewNames(webviewsMapping, opts);
132
+ this.contexts = [webview_helpers_1.NATIVE_WIN, ...webviews];
133
+ this.log.debug(`Available contexts: ${JSON.stringify(this.contexts)}`);
134
+ return this.contexts;
66
135
  };
67
136
  helpers.switchContext = async function switchContext(name, webviewsMapping) {
68
- if (this.isChromedriverContext(name)) {
69
- await this.startChromedriverProxy(name, webviewsMapping);
70
- } else if (this.isChromedriverContext(this.curContext)) {
71
- if (this.opts.recreateChromeDriverSessions) {
72
- this.log.debug('recreateChromeDriverSessions set to true; killing existing chromedrivers');
73
- await this.stopChromedriverProxies();
74
- } else {
75
- await this.suspendChromedriverProxy();
137
+ // We have some options when it comes to webviews. If we want a
138
+ // Chromedriver webview, we can only control one at a time.
139
+ if (this.isChromedriverContext(name)) {
140
+ // start proxying commands directly to chromedriver
141
+ await this.startChromedriverProxy(name, webviewsMapping);
142
+ }
143
+ else if (this.isChromedriverContext(this.curContext)) {
144
+ // if we're moving to a non-chromedriver webview, and our current context
145
+ // _is_ a chromedriver webview, if caps recreateChromeDriverSessions is set
146
+ // to true then kill chromedriver session using stopChromedriverProxies or
147
+ // else simply suspend proxying to the latter
148
+ if (this.opts.recreateChromeDriverSessions) {
149
+ this.log.debug('recreateChromeDriverSessions set to true; killing existing chromedrivers');
150
+ await this.stopChromedriverProxies();
151
+ }
152
+ else {
153
+ await this.suspendChromedriverProxy();
154
+ }
155
+ }
156
+ else {
157
+ throw new Error(`Didn't know how to handle switching to context '${name}'`);
76
158
  }
77
- } else {
78
- throw new Error(`Didn't know how to handle switching to context '${name}'`);
79
- }
80
159
  };
160
+ /* ---------------------------------
161
+ * On-object context-related helpers
162
+ * --------------------------------- */
163
+ // The reason this is a function and not just a constant is that both android-
164
+ // driver and selendroid-driver use this logic, and each one returns
165
+ // a different default context name
81
166
  helpers.defaultContextName = function defaultContextName() {
82
- return _webviewHelpers.NATIVE_WIN;
167
+ return webview_helpers_1.NATIVE_WIN;
83
168
  };
84
169
  helpers.defaultWebviewName = function defaultWebviewName() {
85
- return _webviewHelpers.WEBVIEW_BASE + (this.opts.autoWebviewName || this.opts.appPackage);
170
+ return webview_helpers_1.WEBVIEW_BASE + (this.opts.autoWebviewName || this.opts.appPackage);
86
171
  };
87
172
  helpers.isWebContext = function isWebContext() {
88
- return this.curContext !== null && this.curContext !== _webviewHelpers.NATIVE_WIN;
173
+ return this.curContext !== null && this.curContext !== webview_helpers_1.NATIVE_WIN;
89
174
  };
175
+ // Turn on proxying to an existing Chromedriver session or a new one
90
176
  helpers.startChromedriverProxy = async function startChromedriverProxy(context, webviewsMapping) {
91
- this.log.debug(`Connecting to chrome-backed webview context '${context}'`);
92
- let cd;
93
- if (this.sessionChromedrivers[context]) {
94
- this.log.debug(`Found existing Chromedriver for context '${context}'. Using it.`);
95
- cd = this.sessionChromedrivers[context];
96
- await setupExistingChromedriver(this.log, cd);
97
- } else {
98
- let opts = _lodash.default.cloneDeep(this.opts);
99
- opts.chromeUseRunningApp = true;
100
- if (opts.extractChromeAndroidPackageFromContextName || context === `${_webviewHelpers.WEBVIEW_BASE}chrome`) {
101
- let androidPackage = context.match(`${_webviewHelpers.WEBVIEW_BASE}(.+)`);
102
- if (androidPackage && androidPackage.length > 0) {
103
- opts.chromeAndroidPackage = androidPackage[1];
104
- }
105
- if (!opts.extractChromeAndroidPackageFromContextName) {
106
- if (_lodash.default.has(this.opts, 'enableWebviewDetailsCollection') && !this.opts.enableWebviewDetailsCollection) {
107
- const contexts = webviewsMapping.map(wm => wm.webviewName);
108
- for (const knownPackage of _webviewHelpers.KNOWN_CHROME_PACKAGE_NAMES) {
109
- if (_lodash.default.includes(contexts, `${_webviewHelpers.WEBVIEW_BASE}${knownPackage}`)) {
110
- continue;
111
- }
112
- const appState = await this.queryAppState(knownPackage);
113
- if (_lodash.default.includes([_androidHelpers.APP_STATE.RUNNING_IN_BACKGROUND, _androidHelpers.APP_STATE.RUNNING_IN_FOREGROUND], appState)) {
114
- opts.chromeAndroidPackage = knownPackage;
115
- this.log.debug(`Identified chromeAndroidPackage as '${opts.chromeAndroidPackage}' ` + `for context '${context}' by querying states of Chrome app packages`);
116
- break;
177
+ this.log.debug(`Connecting to chrome-backed webview context '${context}'`);
178
+ let cd;
179
+ if (this.sessionChromedrivers[context]) {
180
+ // in the case where we've already set up a chromedriver for a context,
181
+ // we want to reconnect to it, not create a whole new one
182
+ this.log.debug(`Found existing Chromedriver for context '${context}'. Using it.`);
183
+ cd = this.sessionChromedrivers[context];
184
+ await setupExistingChromedriver(this.log, cd);
185
+ }
186
+ else {
187
+ let opts = lodash_1.default.cloneDeep(this.opts);
188
+ opts.chromeUseRunningApp = true;
189
+ // if requested, tell chromedriver to attach to the android package we have
190
+ // associated with the context name, rather than the package of the AUT.
191
+ // And turn this on by default for chrome--if chrome pops up with a webview
192
+ // and someone wants to switch to it, we should let chromedriver connect to
193
+ // chrome rather than staying stuck on the AUT
194
+ if (opts.extractChromeAndroidPackageFromContextName || context === `${webview_helpers_1.WEBVIEW_BASE}chrome`) {
195
+ let androidPackage = context.match(`${webview_helpers_1.WEBVIEW_BASE}(.+)`);
196
+ if (androidPackage && androidPackage.length > 0) {
197
+ opts.chromeAndroidPackage = androidPackage[1];
117
198
  }
118
- }
119
- } else {
120
- for (const wm of webviewsMapping) {
121
- if (wm.webviewName === context && _lodash.default.has(wm === null || wm === void 0 ? void 0 : wm.info, 'Android-Package')) {
122
- opts.chromeAndroidPackage = wm.info['Android-Package'];
123
- this.log.debug(`Identified chromeAndroidPackage as '${opts.chromeAndroidPackage}' ` + `for context '${context}' by CDP`);
124
- break;
199
+ if (!opts.extractChromeAndroidPackageFromContextName) {
200
+ if (lodash_1.default.has(this.opts, 'enableWebviewDetailsCollection') && !this.opts.enableWebviewDetailsCollection) {
201
+ // When enableWebviewDetailsCollection capability is explicitly disabled, try to identify
202
+ // chromeAndroidPackage based on contexts, known chrome variant packages and queryAppState result
203
+ // since webviewsMapping does not have info object
204
+ const contexts = webviewsMapping.map((wm) => wm.webviewName);
205
+ for (const knownPackage of webview_helpers_1.KNOWN_CHROME_PACKAGE_NAMES) {
206
+ if (lodash_1.default.includes(contexts, `${webview_helpers_1.WEBVIEW_BASE}${knownPackage}`)) {
207
+ continue;
208
+ }
209
+ const appState = await this.queryAppState(knownPackage);
210
+ if (lodash_1.default.includes([android_helpers_1.APP_STATE.RUNNING_IN_BACKGROUND, android_helpers_1.APP_STATE.RUNNING_IN_FOREGROUND], appState)) {
211
+ opts.chromeAndroidPackage = knownPackage;
212
+ this.log.debug(`Identified chromeAndroidPackage as '${opts.chromeAndroidPackage}' ` +
213
+ `for context '${context}' by querying states of Chrome app packages`);
214
+ break;
215
+ }
216
+ }
217
+ }
218
+ else {
219
+ for (const wm of webviewsMapping) {
220
+ if (wm.webviewName === context && lodash_1.default.has(wm?.info, 'Android-Package')) {
221
+ opts.chromeAndroidPackage = wm.info['Android-Package'];
222
+ this.log.debug(`Identified chromeAndroidPackage as '${opts.chromeAndroidPackage}' ` +
223
+ `for context '${context}' by CDP`);
224
+ break;
225
+ }
226
+ }
227
+ }
125
228
  }
126
- }
127
229
  }
128
- }
230
+ cd = await this.setupNewChromedriver(opts, this.adb.curDeviceId, this.adb, context);
231
+ // bind our stop/exit handler, passing in context so we know which
232
+ // one stopped unexpectedly
233
+ cd.on(appium_chromedriver_1.default.EVENT_CHANGED, (msg) => {
234
+ if (msg.state === appium_chromedriver_1.default.STATE_STOPPED) {
235
+ this.onChromedriverStop(context);
236
+ }
237
+ });
238
+ // save the chromedriver object under the context
239
+ this.sessionChromedrivers[context] = cd;
129
240
  }
130
- cd = await this.setupNewChromedriver(opts, this.adb.curDeviceId, this.adb, context);
131
- cd.on(_appiumChromedriver.default.EVENT_CHANGED, msg => {
132
- if (msg.state === _appiumChromedriver.default.STATE_STOPPED) {
133
- this.onChromedriverStop(context);
134
- }
135
- });
136
- this.sessionChromedrivers[context] = cd;
137
- }
138
- this.chromedriver = cd;
139
- this.proxyReqRes = this.chromedriver.proxyReq.bind(this.chromedriver);
140
- this.proxyCommand = this.chromedriver.jwproxy.command.bind(this.chromedriver.jwproxy);
141
- this.jwpProxyActive = true;
241
+ // hook up the local variables so we can proxy this biz
242
+ this.chromedriver = cd;
243
+ this.proxyReqRes = this.chromedriver.proxyReq.bind(this.chromedriver);
244
+ this.proxyCommand = this.chromedriver.jwproxy.command.bind(this.chromedriver.jwproxy);
245
+ this.jwpProxyActive = true;
142
246
  };
247
+ // Stop proxying to any Chromedriver
143
248
  helpers.suspendChromedriverProxy = function suspendChromedriverProxy() {
144
- this.chromedriver = null;
145
- this.proxyReqRes = null;
146
- this.proxyCommand = null;
147
- this.jwpProxyActive = false;
249
+ this.chromedriver = null;
250
+ this.proxyReqRes = null;
251
+ this.proxyCommand = null;
252
+ this.jwpProxyActive = false;
148
253
  };
254
+ // Handle an out-of-band Chromedriver stop event
149
255
  helpers.onChromedriverStop = async function onChromedriverStop(context) {
150
- this.log.warn(`Chromedriver for context ${context} stopped unexpectedly`);
151
- if (context === this.curContext) {
152
- let err = new Error('Chromedriver quit unexpectedly during session');
153
- await this.startUnexpectedShutdown(err);
154
- } else {
155
- this.log.warn("Chromedriver quit unexpectedly, but it wasn't the active " + 'context, ignoring');
156
- delete this.sessionChromedrivers[context];
157
- }
256
+ this.log.warn(`Chromedriver for context ${context} stopped unexpectedly`);
257
+ if (context === this.curContext) {
258
+ // we exited unexpectedly while automating the current context and so want
259
+ // to shut down the session and respond with an error
260
+ let err = new Error('Chromedriver quit unexpectedly during session');
261
+ await this.startUnexpectedShutdown(err);
262
+ }
263
+ else {
264
+ // if a Chromedriver in the non-active context barfs, we don't really
265
+ // care, we'll just make a new one next time we need the context.
266
+ this.log.warn("Chromedriver quit unexpectedly, but it wasn't the active " +
267
+ 'context, ignoring');
268
+ delete this.sessionChromedrivers[context];
269
+ }
158
270
  };
271
+ // Intentionally stop all the chromedrivers currently active, and ignore
272
+ // their exit events
159
273
  helpers.stopChromedriverProxies = async function stopChromedriverProxies() {
160
- this.suspendChromedriverProxy();
161
- for (let context of _lodash.default.keys(this.sessionChromedrivers)) {
162
- let cd = this.sessionChromedrivers[context];
163
- this.log.debug(`Stopping chromedriver for context ${context}`);
164
- cd.removeAllListeners(_appiumChromedriver.default.EVENT_CHANGED);
165
- try {
166
- await cd.stop();
167
- } catch (err) {
168
- this.log.warn(`Error stopping Chromedriver: ${err.message}`);
274
+ this.suspendChromedriverProxy(); // make sure we turn off the proxy flag
275
+ for (let context of lodash_1.default.keys(this.sessionChromedrivers)) {
276
+ let cd = this.sessionChromedrivers[context];
277
+ this.log.debug(`Stopping chromedriver for context ${context}`);
278
+ // stop listening for the stopped state event
279
+ cd.removeAllListeners(appium_chromedriver_1.default.EVENT_CHANGED);
280
+ try {
281
+ await cd.stop();
282
+ }
283
+ catch (err) {
284
+ this.log.warn(`Error stopping Chromedriver: ${err.message}`);
285
+ }
286
+ delete this.sessionChromedrivers[context];
169
287
  }
170
- delete this.sessionChromedrivers[context];
171
- }
172
288
  };
173
289
  helpers.isChromedriverContext = function isChromedriverContext(viewName) {
174
- return _lodash.default.includes(viewName, _webviewHelpers.WEBVIEW_WIN) || viewName === _webviewHelpers.CHROMIUM_WIN;
290
+ return lodash_1.default.includes(viewName, webview_helpers_1.WEBVIEW_WIN) || viewName === webview_helpers_1.CHROMIUM_WIN;
175
291
  };
176
292
  helpers.shouldDismissChromeWelcome = function shouldDismissChromeWelcome() {
177
- return !!this.opts.chromeOptions && _lodash.default.isArray(this.opts.chromeOptions.args) && this.opts.chromeOptions.args.includes('--no-first-run');
293
+ return !!this.opts.chromeOptions &&
294
+ lodash_1.default.isArray(this.opts.chromeOptions.args) &&
295
+ this.opts.chromeOptions.args.includes('--no-first-run');
178
296
  };
179
297
  helpers.dismissChromeWelcome = async function dismissChromeWelcome() {
180
- this.log.info('Trying to dismiss Chrome welcome');
181
- let activity = await this.getCurrentActivity();
182
- if (activity !== 'org.chromium.chrome.browser.firstrun.FirstRunActivity') {
183
- this.log.info('Chrome welcome dialog never showed up! Continuing');
184
- return;
185
- }
186
- let el = await this.findElOrEls('id', 'com.android.chrome:id/terms_accept', false);
187
- await this.click(el.ELEMENT);
188
- try {
189
- let el = await this.findElOrEls('id', 'com.android.chrome:id/negative_button', false);
298
+ this.log.info('Trying to dismiss Chrome welcome');
299
+ let activity = await this.getCurrentActivity();
300
+ if (activity !== 'org.chromium.chrome.browser.firstrun.FirstRunActivity') {
301
+ this.log.info('Chrome welcome dialog never showed up! Continuing');
302
+ return;
303
+ }
304
+ let el = await this.findElOrEls('id', 'com.android.chrome:id/terms_accept', false);
190
305
  await this.click(el.ELEMENT);
191
- } catch (e) {
192
- this.log.warn(`This device did not show Chrome SignIn dialog, ${e.message}`);
193
- }
306
+ try {
307
+ let el = await this.findElOrEls('id', 'com.android.chrome:id/negative_button', false);
308
+ await this.click(el.ELEMENT);
309
+ }
310
+ catch (e) {
311
+ // DO NOTHING, THIS DEVICE DIDNT LAUNCH THE SIGNIN DIALOG
312
+ // IT MUST BE A NON GMS DEVICE
313
+ this.log.warn(`This device did not show Chrome SignIn dialog, ${e.message}`);
314
+ }
194
315
  };
195
316
  helpers.startChromeSession = async function startChromeSession() {
196
- this.log.info('Starting a chrome-based browser session');
197
- let opts = _lodash.default.cloneDeep(this.opts);
198
- const knownPackages = ['org.chromium.chrome.shell', 'com.android.chrome', 'com.chrome.beta', 'org.chromium.chrome', 'org.chromium.webview_shell'];
199
- if (_lodash.default.includes(knownPackages, this.opts.appPackage)) {
200
- opts.chromeBundleId = this.opts.appPackage;
201
- } else {
202
- opts.chromeAndroidActivity = this.opts.appActivity;
203
- }
204
- this.chromedriver = await this.setupNewChromedriver(opts, this.adb.curDeviceId, this.adb);
205
- this.chromedriver.on(_appiumChromedriver.default.EVENT_CHANGED, msg => {
206
- if (msg.state === _appiumChromedriver.default.STATE_STOPPED) {
207
- this.onChromedriverStop(_webviewHelpers.CHROMIUM_WIN);
317
+ this.log.info('Starting a chrome-based browser session');
318
+ let opts = lodash_1.default.cloneDeep(this.opts);
319
+ const knownPackages = [
320
+ 'org.chromium.chrome.shell',
321
+ 'com.android.chrome',
322
+ 'com.chrome.beta',
323
+ 'org.chromium.chrome',
324
+ 'org.chromium.webview_shell',
325
+ ];
326
+ if (lodash_1.default.includes(knownPackages, this.opts.appPackage)) {
327
+ opts.chromeBundleId = this.opts.appPackage;
328
+ }
329
+ else {
330
+ opts.chromeAndroidActivity = this.opts.appActivity;
331
+ }
332
+ this.chromedriver = await this.setupNewChromedriver(opts, this.adb.curDeviceId, this.adb);
333
+ this.chromedriver.on(appium_chromedriver_1.default.EVENT_CHANGED, (msg) => {
334
+ if (msg.state === appium_chromedriver_1.default.STATE_STOPPED) {
335
+ this.onChromedriverStop(webview_helpers_1.CHROMIUM_WIN);
336
+ }
337
+ });
338
+ // Now that we have a Chrome session, we ensure that the context is
339
+ // appropriately set and that this chromedriver is added to the list
340
+ // of session chromedrivers so we can switch back and forth
341
+ this.curContext = webview_helpers_1.CHROMIUM_WIN;
342
+ this.sessionChromedrivers[webview_helpers_1.CHROMIUM_WIN] = this.chromedriver;
343
+ this.proxyReqRes = this.chromedriver.proxyReq.bind(this.chromedriver);
344
+ this.proxyCommand = this.chromedriver.jwproxy.command.bind(this.chromedriver.jwproxy);
345
+ this.jwpProxyActive = true;
346
+ if (this.shouldDismissChromeWelcome()) {
347
+ // dismiss Chrome welcome dialog
348
+ await this.dismissChromeWelcome();
208
349
  }
209
- });
210
- this.curContext = _webviewHelpers.CHROMIUM_WIN;
211
- this.sessionChromedrivers[_webviewHelpers.CHROMIUM_WIN] = this.chromedriver;
212
- this.proxyReqRes = this.chromedriver.proxyReq.bind(this.chromedriver);
213
- this.proxyCommand = this.chromedriver.jwproxy.command.bind(this.chromedriver.jwproxy);
214
- this.jwpProxyActive = true;
215
- if (this.shouldDismissChromeWelcome()) {
216
- await this.dismissChromeWelcome();
217
- }
218
350
  };
351
+ /* --------------------------
352
+ * Internal library functions
353
+ * -------------------------- */
219
354
  async function setupExistingChromedriver(log, chromedriver) {
220
- if (!(await chromedriver.hasWorkingWebview())) {
221
- log.debug('ChromeDriver is not associated with a window. ' + 'Re-initializing the session.');
222
- await chromedriver.restart();
223
- }
224
- return chromedriver;
355
+ // check the status by sending a simple window-based command to ChromeDriver
356
+ // if there is an error, we want to recreate the ChromeDriver session
357
+ if (!await chromedriver.hasWorkingWebview()) {
358
+ log.debug('ChromeDriver is not associated with a window. ' +
359
+ 'Re-initializing the session.');
360
+ await chromedriver.restart();
361
+ }
362
+ return chromedriver;
225
363
  }
364
+ /**
365
+ * Find a free port to have Chromedriver listen on.
366
+ *
367
+ * @param {array} portSpec - Array which is a list of ports. A list item may
368
+ * also itself be an array of length 2 specifying a start and end port of
369
+ * a range. Some valid port specs:
370
+ * - [8000, 8001, 8002]
371
+ * - [[8000, 8005]]
372
+ * - [8000, [9000, 9100]]
373
+ * @param {Object?} log Logger instance
374
+ *
375
+ * @return {number} A free port
376
+ */
226
377
  async function getChromedriverPort(portSpec, log = null) {
227
- const getPort = _bluebird.default.promisify(_portfinder.default.getPort, {
228
- context: _portfinder.default
229
- });
230
- if (!portSpec) {
231
- const port = await getPort();
232
- log === null || log === void 0 ? void 0 : log.debug(`A port was not given, using random free port: ${port}`);
233
- return port;
234
- }
235
- log === null || log === void 0 ? void 0 : log.debug(`Finding a free port for chromedriver using spec ${JSON.stringify(portSpec)}`);
236
- let foundPort = null;
237
- for (const potentialPort of portSpec) {
238
- let port, stopPort;
239
- if (_lodash.default.isArray(potentialPort)) {
240
- [port, stopPort] = potentialPort;
241
- } else {
242
- port = parseInt(potentialPort, 10);
243
- stopPort = port;
378
+ const getPort = bluebird_1.default.promisify(portfinder_1.default.getPort, { context: portfinder_1.default });
379
+ // if the user didn't give us any specific information about chromedriver
380
+ // port ranges, just find any free port
381
+ if (!portSpec) {
382
+ const port = await getPort();
383
+ log?.debug(`A port was not given, using random free port: ${port}`);
384
+ return port;
244
385
  }
245
- try {
246
- log === null || log === void 0 ? void 0 : log.debug(`Checking port range ${port}:${stopPort}`);
247
- foundPort = await getPort({
248
- port,
249
- stopPort
250
- });
251
- break;
252
- } catch (e) {
253
- log === null || log === void 0 ? void 0 : log.debug(`Nothing in port range ${port}:${stopPort} was available`);
386
+ // otherwise find the free port based on a list or range provided by the user
387
+ log?.debug(`Finding a free port for chromedriver using spec ${JSON.stringify(portSpec)}`);
388
+ let foundPort = null;
389
+ for (const potentialPort of portSpec) {
390
+ let port, stopPort;
391
+ if (lodash_1.default.isArray(potentialPort)) {
392
+ ([port, stopPort] = potentialPort);
393
+ }
394
+ else {
395
+ port = parseInt(potentialPort, 10); // ensure we have a number and not a string
396
+ stopPort = port;
397
+ }
398
+ try {
399
+ log?.debug(`Checking port range ${port}:${stopPort}`);
400
+ foundPort = await getPort({ port, stopPort });
401
+ break;
402
+ }
403
+ catch (e) {
404
+ log?.debug(`Nothing in port range ${port}:${stopPort} was available`);
405
+ }
254
406
  }
255
- }
256
- if (foundPort === null) {
257
- throw new Error(`Could not find a free port for chromedriver using ` + `chromedriverPorts spec ${JSON.stringify(portSpec)}`);
258
- }
259
- log === null || log === void 0 ? void 0 : log.debug(`Using free port ${foundPort} for chromedriver`);
260
- return foundPort;
407
+ if (foundPort === null) {
408
+ throw new Error(`Could not find a free port for chromedriver using ` +
409
+ `chromedriverPorts spec ${JSON.stringify(portSpec)}`);
410
+ }
411
+ log?.debug(`Using free port ${foundPort} for chromedriver`);
412
+ return foundPort;
261
413
  }
262
414
  helpers.isChromedriverAutodownloadEnabled = function isChromedriverAutodownloadEnabled() {
263
- var _this$log;
264
- if (this.isFeatureEnabled(CHROMEDRIVER_AUTODOWNLOAD_FEATURE)) {
265
- return true;
266
- }
267
- this === null || this === void 0 ? void 0 : (_this$log = this.log) === null || _this$log === void 0 ? void 0 : _this$log.debug(`Automated Chromedriver download is disabled. ` + `Use '${CHROMEDRIVER_AUTODOWNLOAD_FEATURE}' server feature to enable it`);
268
- return false;
415
+ if (this.isFeatureEnabled(CHROMEDRIVER_AUTODOWNLOAD_FEATURE)) {
416
+ return true;
417
+ }
418
+ this?.log?.debug(`Automated Chromedriver download is disabled. ` +
419
+ `Use '${CHROMEDRIVER_AUTODOWNLOAD_FEATURE}' server feature to enable it`);
420
+ return false;
269
421
  };
270
422
  helpers.setupNewChromedriver = async function setupNewChromedriver(opts, curDeviceId, adb, context = null) {
271
- var _this$isChromedriverA, _this$log6;
272
- if (opts.chromeDriverPort) {
273
- var _this$log2;
274
- this === null || this === void 0 ? void 0 : (_this$log2 = this.log) === null || _this$log2 === void 0 ? void 0 : _this$log2.warn(`The 'chromeDriverPort' capability is deprecated. Please use 'chromedriverPort' instead`);
275
- opts.chromedriverPort = opts.chromeDriverPort;
276
- }
277
- if (opts.chromedriverPort) {
278
- var _this$log3;
279
- this === null || this === void 0 ? void 0 : (_this$log3 = this.log) === null || _this$log3 === void 0 ? void 0 : _this$log3.debug(`Using user-specified port ${opts.chromedriverPort} for chromedriver`);
280
- } else {
281
- opts.chromedriverPort = await getChromedriverPort(opts.chromedriverPorts, this === null || this === void 0 ? void 0 : this.log);
282
- }
283
- const details = context ? _webviewHelpers.default.getWebviewDetails(adb, context) : undefined;
284
- if (!_lodash.default.isEmpty(details)) {
285
- var _this$log4;
286
- this === null || this === void 0 ? void 0 : (_this$log4 = this.log) === null || _this$log4 === void 0 ? void 0 : _this$log4.debug('Passing web view details to the Chromedriver constructor: ' + JSON.stringify(details, null, 2));
287
- }
288
- const chromedriver = new _appiumChromedriver.default({
289
- port: opts.chromedriverPort,
290
- executable: opts.chromedriverExecutable,
291
- adb,
292
- cmdArgs: opts.chromedriverArgs,
293
- verbose: !!opts.showChromedriverLog,
294
- executableDir: opts.chromedriverExecutableDir,
295
- mappingPath: opts.chromedriverChromeMappingFile,
296
- bundleId: opts.chromeBundleId,
297
- useSystemExecutable: opts.chromedriverUseSystemExecutable,
298
- disableBuildCheck: opts.chromedriverDisableBuildCheck,
299
- details,
300
- isAutodownloadEnabled: this === null || this === void 0 ? void 0 : (_this$isChromedriverA = this.isChromedriverAutodownloadEnabled) === null || _this$isChromedriverA === void 0 ? void 0 : _this$isChromedriverA.call(this)
301
- });
302
- opts.chromeOptions = opts.chromeOptions || {};
303
- for (const opt of _lodash.default.keys(opts)) {
304
- if (opt.endsWith(':chromeOptions')) {
305
- var _this$log5;
306
- this === null || this === void 0 ? void 0 : (_this$log5 = this.log) === null || _this$log5 === void 0 ? void 0 : _this$log5.warn(`Merging '${opt}' into 'chromeOptions'. This may cause unexpected behavior`);
307
- _lodash.default.merge(opts.chromeOptions, opts[opt]);
423
+ if (opts.chromeDriverPort) {
424
+ this?.log?.warn(`The 'chromeDriverPort' capability is deprecated. Please use 'chromedriverPort' instead`);
425
+ opts.chromedriverPort = opts.chromeDriverPort;
426
+ }
427
+ if (opts.chromedriverPort) {
428
+ this?.log?.debug(`Using user-specified port ${opts.chromedriverPort} for chromedriver`);
429
+ }
430
+ else {
431
+ // if a single port wasn't given, we'll look for a free one
432
+ opts.chromedriverPort = await getChromedriverPort(opts.chromedriverPorts, this?.log);
433
+ }
434
+ const details = context ? webview_helpers_1.default.getWebviewDetails(adb, context) : undefined;
435
+ if (!lodash_1.default.isEmpty(details)) {
436
+ this?.log?.debug('Passing web view details to the Chromedriver constructor: ' +
437
+ JSON.stringify(details, null, 2));
438
+ }
439
+ const chromedriver = new appium_chromedriver_1.default({
440
+ port: opts.chromedriverPort,
441
+ executable: opts.chromedriverExecutable,
442
+ adb,
443
+ cmdArgs: opts.chromedriverArgs,
444
+ verbose: !!opts.showChromedriverLog,
445
+ executableDir: opts.chromedriverExecutableDir,
446
+ mappingPath: opts.chromedriverChromeMappingFile,
447
+ bundleId: opts.chromeBundleId,
448
+ useSystemExecutable: opts.chromedriverUseSystemExecutable,
449
+ disableBuildCheck: opts.chromedriverDisableBuildCheck,
450
+ details,
451
+ isAutodownloadEnabled: this?.isChromedriverAutodownloadEnabled?.()
452
+ });
453
+ // make sure there are chromeOptions
454
+ opts.chromeOptions = opts.chromeOptions || {};
455
+ // try out any prefixed chromeOptions,
456
+ // and strip the prefix
457
+ for (const opt of lodash_1.default.keys(opts)) {
458
+ if (opt.endsWith(':chromeOptions')) {
459
+ this?.log?.warn(`Merging '${opt}' into 'chromeOptions'. This may cause unexpected behavior`);
460
+ lodash_1.default.merge(opts.chromeOptions, opts[opt]);
461
+ }
308
462
  }
309
- }
310
- const caps = _webviewHelpers.default.createChromedriverCaps(opts, curDeviceId, details);
311
- this === null || this === void 0 ? void 0 : (_this$log6 = this.log) === null || _this$log6 === void 0 ? void 0 : _this$log6.debug(`Before starting chromedriver, androidPackage is '${caps.chromeOptions.androidPackage}'`);
312
- await chromedriver.start(caps);
313
- return chromedriver;
463
+ const caps = webview_helpers_1.default.createChromedriverCaps(opts, curDeviceId, details);
464
+ this?.log?.debug(`Before starting chromedriver, androidPackage is '${caps.chromeOptions.androidPackage}'`);
465
+ await chromedriver.start(caps);
466
+ return chromedriver;
314
467
  };
315
468
  const setupNewChromedriver = helpers.setupNewChromedriver;
316
469
  exports.setupNewChromedriver = setupNewChromedriver;
317
470
  Object.assign(extensions, commands, helpers);
318
- var _default = extensions;
319
- exports.default = _default;
320
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfYXBwaXVtQ2hyb21lZHJpdmVyIiwiX3BvcnRmaW5kZXIiLCJfYmx1ZWJpcmQiLCJfc3VwcG9ydCIsIl9kcml2ZXIiLCJfd2Vidmlld0hlbHBlcnMiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIl9hbmRyb2lkSGVscGVycyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsIm5vZGVJbnRlcm9wIiwiV2Vha01hcCIsImNhY2hlQmFiZWxJbnRlcm9wIiwiY2FjaGVOb2RlSW50ZXJvcCIsIm9iaiIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiY2FjaGUiLCJoYXMiLCJnZXQiLCJuZXdPYmoiLCJoYXNQcm9wZXJ0eURlc2NyaXB0b3IiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImRlc2MiLCJzZXQiLCJDSFJPTUVEUklWRVJfQVVUT0RPV05MT0FEX0ZFQVRVUkUiLCJjb21tYW5kcyIsImhlbHBlcnMiLCJleHRlbnNpb25zIiwiZXhwb3J0cyIsImdldEN1cnJlbnRDb250ZXh0IiwiY3VyQ29udGV4dCIsImRlZmF1bHRDb250ZXh0TmFtZSIsImdldENvbnRleHRzIiwid2Vidmlld3NNYXBwaW5nIiwid2Vidmlld0hlbHBlcnMiLCJnZXRXZWJWaWV3c01hcHBpbmciLCJhZGIiLCJvcHRzIiwiYXNzaWduQ29udGV4dHMiLCJzZXRDb250ZXh0IiwibmFtZSIsInV0aWwiLCJoYXNWYWx1ZSIsIldFQlZJRVdfV0lOIiwiZGVmYXVsdFdlYnZpZXdOYW1lIiwiY29udGV4dHMiLCJfIiwiaW5jbHVkZXMiLCJlcnJvcnMiLCJOb1N1Y2hDb250ZXh0RXJyb3IiLCJzd2l0Y2hDb250ZXh0IiwibW9iaWxlR2V0Q29udGV4dHMiLCJhbmRyb2lkRGV2aWNlU29ja2V0IiwiZW5zdXJlV2Vidmlld3NIYXZlUGFnZXMiLCJ3ZWJ2aWV3RGV2dG9vbHNQb3J0IiwiZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uIiwiYXNzaWduIiwiaXNDaHJvbWVTZXNzaW9uIiwid2Vidmlld3MiLCJwYXJzZVdlYnZpZXdOYW1lcyIsIk5BVElWRV9XSU4iLCJsb2ciLCJkZWJ1ZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJpc0Nocm9tZWRyaXZlckNvbnRleHQiLCJzdGFydENocm9tZWRyaXZlclByb3h5IiwicmVjcmVhdGVDaHJvbWVEcml2ZXJTZXNzaW9ucyIsInN0b3BDaHJvbWVkcml2ZXJQcm94aWVzIiwic3VzcGVuZENocm9tZWRyaXZlclByb3h5IiwiRXJyb3IiLCJXRUJWSUVXX0JBU0UiLCJhdXRvV2Vidmlld05hbWUiLCJhcHBQYWNrYWdlIiwiaXNXZWJDb250ZXh0IiwiY29udGV4dCIsImNkIiwic2Vzc2lvbkNocm9tZWRyaXZlcnMiLCJzZXR1cEV4aXN0aW5nQ2hyb21lZHJpdmVyIiwiY2xvbmVEZWVwIiwiY2hyb21lVXNlUnVubmluZ0FwcCIsImV4dHJhY3RDaHJvbWVBbmRyb2lkUGFja2FnZUZyb21Db250ZXh0TmFtZSIsImFuZHJvaWRQYWNrYWdlIiwibWF0Y2giLCJsZW5ndGgiLCJjaHJvbWVBbmRyb2lkUGFja2FnZSIsIm1hcCIsIndtIiwid2Vidmlld05hbWUiLCJrbm93blBhY2thZ2UiLCJLTk9XTl9DSFJPTUVfUEFDS0FHRV9OQU1FUyIsImFwcFN0YXRlIiwicXVlcnlBcHBTdGF0ZSIsIkFQUF9TVEFURSIsIlJVTk5JTkdfSU5fQkFDS0dST1VORCIsIlJVTk5JTkdfSU5fRk9SRUdST1VORCIsImluZm8iLCJzZXR1cE5ld0Nocm9tZWRyaXZlciIsImN1ckRldmljZUlkIiwib24iLCJDaHJvbWVkcml2ZXIiLCJFVkVOVF9DSEFOR0VEIiwibXNnIiwic3RhdGUiLCJTVEFURV9TVE9QUEVEIiwib25DaHJvbWVkcml2ZXJTdG9wIiwiY2hyb21lZHJpdmVyIiwicHJveHlSZXFSZXMiLCJwcm94eVJlcSIsImJpbmQiLCJwcm94eUNvbW1hbmQiLCJqd3Byb3h5IiwiY29tbWFuZCIsImp3cFByb3h5QWN0aXZlIiwid2FybiIsImVyciIsInN0YXJ0VW5leHBlY3RlZFNodXRkb3duIiwia2V5cyIsInJlbW92ZUFsbExpc3RlbmVycyIsInN0b3AiLCJtZXNzYWdlIiwidmlld05hbWUiLCJDSFJPTUlVTV9XSU4iLCJzaG91bGREaXNtaXNzQ2hyb21lV2VsY29tZSIsImNocm9tZU9wdGlvbnMiLCJpc0FycmF5IiwiYXJncyIsImRpc21pc3NDaHJvbWVXZWxjb21lIiwiYWN0aXZpdHkiLCJnZXRDdXJyZW50QWN0aXZpdHkiLCJlbCIsImZpbmRFbE9yRWxzIiwiY2xpY2siLCJFTEVNRU5UIiwiZSIsInN0YXJ0Q2hyb21lU2Vzc2lvbiIsImtub3duUGFja2FnZXMiLCJjaHJvbWVCdW5kbGVJZCIsImNocm9tZUFuZHJvaWRBY3Rpdml0eSIsImFwcEFjdGl2aXR5IiwiaGFzV29ya2luZ1dlYnZpZXciLCJyZXN0YXJ0IiwiZ2V0Q2hyb21lZHJpdmVyUG9ydCIsInBvcnRTcGVjIiwiZ2V0UG9ydCIsIkIiLCJwcm9taXNpZnkiLCJQb3J0RmluZGVyIiwicG9ydCIsImZvdW5kUG9ydCIsInBvdGVudGlhbFBvcnQiLCJzdG9wUG9ydCIsInBhcnNlSW50IiwiaXNDaHJvbWVkcml2ZXJBdXRvZG93bmxvYWRFbmFibGVkIiwiX3RoaXMkbG9nIiwiaXNGZWF0dXJlRW5hYmxlZCIsIl90aGlzJGlzQ2hyb21lZHJpdmVyQSIsIl90aGlzJGxvZzYiLCJjaHJvbWVEcml2ZXJQb3J0IiwiX3RoaXMkbG9nMiIsImNocm9tZWRyaXZlclBvcnQiLCJfdGhpcyRsb2czIiwiY2hyb21lZHJpdmVyUG9ydHMiLCJkZXRhaWxzIiwiZ2V0V2Vidmlld0RldGFpbHMiLCJ1bmRlZmluZWQiLCJpc0VtcHR5IiwiX3RoaXMkbG9nNCIsImV4ZWN1dGFibGUiLCJjaHJvbWVkcml2ZXJFeGVjdXRhYmxlIiwiY21kQXJncyIsImNocm9tZWRyaXZlckFyZ3MiLCJ2ZXJib3NlIiwic2hvd0Nocm9tZWRyaXZlckxvZyIsImV4ZWN1dGFibGVEaXIiLCJjaHJvbWVkcml2ZXJFeGVjdXRhYmxlRGlyIiwibWFwcGluZ1BhdGgiLCJjaHJvbWVkcml2ZXJDaHJvbWVNYXBwaW5nRmlsZSIsImJ1bmRsZUlkIiwidXNlU3lzdGVtRXhlY3V0YWJsZSIsImNocm9tZWRyaXZlclVzZVN5c3RlbUV4ZWN1dGFibGUiLCJkaXNhYmxlQnVpbGRDaGVjayIsImNocm9tZWRyaXZlckRpc2FibGVCdWlsZENoZWNrIiwiaXNBdXRvZG93bmxvYWRFbmFibGVkIiwib3B0IiwiZW5kc1dpdGgiLCJfdGhpcyRsb2c1IiwibWVyZ2UiLCJjYXBzIiwiY3JlYXRlQ2hyb21lZHJpdmVyQ2FwcyIsInN0YXJ0IiwiX2RlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvY29tbWFuZHMvY29udGV4dC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IENocm9tZWRyaXZlciBmcm9tICdhcHBpdW0tY2hyb21lZHJpdmVyJztcbmltcG9ydCBQb3J0RmluZGVyIGZyb20gJ3BvcnRmaW5kZXInO1xuaW1wb3J0IEIgZnJvbSAnYmx1ZWJpcmQnO1xuaW1wb3J0IHsgdXRpbCB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBlcnJvcnMgfSBmcm9tICdhcHBpdW0vZHJpdmVyJztcbmltcG9ydCB7XG4gIGRlZmF1bHQgYXMgd2Vidmlld0hlbHBlcnMsXG4gIE5BVElWRV9XSU4sIFdFQlZJRVdfQkFTRSwgV0VCVklFV19XSU4sIENIUk9NSVVNX1dJTiwgS05PV05fQ0hST01FX1BBQ0tBR0VfTkFNRVNcbn0gZnJvbSAnLi4vd2Vidmlldy1oZWxwZXJzJztcbmltcG9ydCB7IEFQUF9TVEFURSB9IGZyb20gJy4uL2FuZHJvaWQtaGVscGVycyc7XG5cbmNvbnN0IENIUk9NRURSSVZFUl9BVVRPRE9XTkxPQURfRkVBVFVSRSA9ICdjaHJvbWVkcml2ZXJfYXV0b2Rvd25sb2FkJztcblxubGV0IGNvbW1hbmRzID0ge30sIGhlbHBlcnMgPSB7fSwgZXh0ZW5zaW9ucyA9IHt9O1xuXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEFjdHVhbCBNSlNPTldQIGNvbW1hbmQgaGFuZGxlcnNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmNvbW1hbmRzLmdldEN1cnJlbnRDb250ZXh0ID0gYXN5bmMgZnVuY3Rpb24gZ2V0Q3VycmVudENvbnRleHQgKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlcXVpcmUtYXdhaXRcbiAgLy8gaWYgdGhlIGN1cnJlbnQgY29udGV4dCBpcyBgbnVsbGAsIGluZGljYXRpbmcgbm8gY29udGV4dFxuICAvLyBleHBsaWNpdGx5IHNldCwgaXQgaXMgdGhlIGRlZmF1bHQgY29udGV4dFxuICByZXR1cm4gdGhpcy5jdXJDb250ZXh0IHx8IHRoaXMuZGVmYXVsdENvbnRleHROYW1lKCk7XG59O1xuXG5jb21tYW5kcy5nZXRDb250ZXh0cyA9IGFzeW5jIGZ1bmN0aW9uIGdldENvbnRleHRzICgpIHtcbiAgY29uc3Qgd2Vidmlld3NNYXBwaW5nID0gYXdhaXQgd2Vidmlld0hlbHBlcnMuZ2V0V2ViVmlld3NNYXBwaW5nKHRoaXMuYWRiLCB0aGlzLm9wdHMpO1xuICByZXR1cm4gdGhpcy5hc3NpZ25Db250ZXh0cyh3ZWJ2aWV3c01hcHBpbmcpO1xufTtcblxuY29tbWFuZHMuc2V0Q29udGV4dCA9IGFzeW5jIGZ1bmN0aW9uIHNldENvbnRleHQgKG5hbWUpIHtcbiAgaWYgKCF1dGlsLmhhc1ZhbHVlKG5hbWUpKSB7XG4gICAgbmFtZSA9IHRoaXMuZGVmYXVsdENvbnRleHROYW1lKCk7XG4gIH0gZWxzZSBpZiAobmFtZSA9PT0gV0VCVklFV19XSU4pIHtcbiAgICAvLyBoYW5kbGUgc2V0Q29udGV4dCBcIldFQlZJRVdcIlxuICAgIG5hbWUgPSB0aGlzLmRlZmF1bHRXZWJ2aWV3TmFtZSgpO1xuICB9XG4gIC8vIGlmIHdlJ3JlIGFscmVhZHkgaW4gdGhlIGNvbnRleHQgd2Ugd2FudCwgZG8gbm90aGluZ1xuICBpZiAobmFtZSA9PT0gdGhpcy5jdXJDb250ZXh0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgd2Vidmlld3NNYXBwaW5nID0gYXdhaXQgd2Vidmlld0hlbHBlcnMuZ2V0V2ViVmlld3NNYXBwaW5nKHRoaXMuYWRiLCB0aGlzLm9wdHMpO1xuICBjb25zdCBjb250ZXh0cyA9IHRoaXMuYXNzaWduQ29udGV4dHMod2Vidmlld3NNYXBwaW5nKTtcbiAgLy8gaWYgdGhlIGNvbnRleHQgd2Ugd2FudCBkb2Vzbid0IGV4aXN0LCBmYWlsXG4gIGlmICghXy5pbmNsdWRlcyhjb250ZXh0cywgbmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgZXJyb3JzLk5vU3VjaENvbnRleHRFcnJvcigpO1xuICB9XG5cbiAgYXdhaXQgdGhpcy5zd2l0Y2hDb250ZXh0KG5hbWUsIHdlYnZpZXdzTWFwcGluZyk7XG4gIHRoaXMuY3VyQ29udGV4dCA9IG5hbWU7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFdlYnZpZXdzTWFwcGluZ1xuICogQHByb3BlcnR5IHtzdHJpbmd9IHByb2MgVGhlIG5hbWUgb2YgdGhlIERldnRvb2xzIFVuaXggc29ja2V0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gd2VidmlldyBUaGUgd2ViIHZpZXcgYWxpYXMuIExvb2tzIGxpa2UgYFdFQlZJRVdfYFxuICogcHJlZml4IHBsdXMgUElEIG9yIHBhY2thZ2UgbmFtZVxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBpbmZvIFdlYnZpZXcgaW5mb3JtYXRpb24gYXMgaXQgaXMgcmV0cmlldmVkIGJ5XG4gKiAvanNvbi92ZXJzaW9uIENEUCBlbmRwb2ludFxuICogQHByb3BlcnR5IHs/QXJyYXk8T2JqZWN0Pn0gcGFnZXMgV2VidmlldyBwYWdlcyBsaXN0IGFzIGl0IGlzIHJldHJpZXZlZCBieVxuICogL2pzb24vbGlzdCBDRFAgZW5kcG9pbnRcbiAqIEBwcm9wZXJ5IHs/c3RyaW5nfSB3ZWJ2aWV3TmFtZSBBbiBhY3R1YWwgd2VidmlldyBuYW1lIGZvciBzd2l0Y2hpbmcgY29udGV4dC5cbiAqIFRoaXMgdmFsdWUgYmVjb21lcyBudWxsIHdoZW4gZmFpbGluZyB0byBmaW5kIGEgUElEIGZvciBhIHdlYnZpZXcuXG4gKlxuICogVGhlIGZvbGxvd2luZyBqc29uIGRlbW9uc3RyYXRlcyB0aGUgZXhhbXBsZSBvZiBXZWJ2aWV3c01hcHBpbmcgb2JqZWN0LlxuICogTm90ZSB0aGF0IGBkZXNjcmlwdGlvbmAgaW4gYHBhZ2VgIGNhbiBiZSBhbiBlbXB0eSBzdHJpbmcgbW9zdCBsaWtlbHkgd2hlbiBpdCBjb21lcyB0byBNb2JpbGUgQ2hyb21lKVxuICoge1xuICogICBcInByb2NcIjogXCJAd2Vidmlld19kZXZ0b29sc19yZW1vdGVfMjIxMzhcIixcbiAqICAgXCJ3ZWJ2aWV3XCI6IFwiV0VCVklFV18yMjEzOFwiLFxuICogICBcImluZm9cIjoge1xuICogICAgIFwiQW5kcm9pZC1QYWNrYWdlXCI6IFwiaW8uYXBwaXVtLnNldHRpbmdzXCIsXG4gKiAgICAgXCJCcm93c2VyXCI6IFwiQ2hyb21lLzc0LjAuMzcyOS4xODVcIixcbiAqICAgICBcIlByb3RvY29sLVZlcnNpb25cIjogXCIxLjNcIixcbiAqICAgICBcIlVzZXItQWdlbnRcIjogXCJNb3ppbGxhLzUuMCAoTGludXg7IEFuZHJvaWQgMTA7IEFuZHJvaWQgU0RLIGJ1aWx0IGZvciB4ODYgQnVpbGQvUVNSMS4xOTA5MjAuMDAxOyB3dikgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgVmVyc2lvbi80LjAgQ2hyb21lLzc0LjAuMzcyOS4xODUgTW9iaWxlIFNhZmFyaS81MzcuMzZcIixcbiAqICAgICBcIlY4LVZlcnNpb25cIjogXCI3LjQuMjg4LjI4XCIsXG4gKiAgICAgXCJXZWJLaXQtVmVyc2lvblwiOiBcIjUzNy4zNiAoQDIyOTU1NjgyZjk0Y2UwOTMzNjE5N2JmYjhkZmZlYTk5MWZhMzJmMGQpXCIsXG4gKiAgICAgXCJ3ZWJTb2NrZXREZWJ1Z2dlclVybFwiOiBcIndzOi8vMTI3LjAuMC4xOjEwOTAwL2RldnRvb2xzL2Jyb3dzZXJcIlxuICogICB9LFxuICogICBcInBhZ2VzXCI6IFtcbiAqICAgICB7XG4gKiAgICAgICBcImRlc2NyaXB0aW9uXCI6IFwie1xcXCJhdHRhY2hlZFxcXCI6dHJ1ZSxcXFwiZW1wdHlcXFwiOmZhbHNlLFxcXCJoZWlnaHRcXFwiOjE0NTgsXFxcInNjcmVlblhcXFwiOjAsXFxcInNjcmVlbllcXFwiOjMzNixcXFwidmlzaWJsZVxcXCI6dHJ1ZSxcXFwid2lkdGhcXFwiOjEwODB9XCIsXG4gKiAgICAgICBcImRldnRvb2xzRnJvbnRlbmRVcmxcIjogXCJodHRwOi8vY2hyb21lLWRldnRvb2xzLWZyb250ZW5kLmFwcHNwb3QuY29tL3NlcnZlX3Jldi9AMjI5NTU2ODJmOTRjZTA5MzM2MTk3YmZiOGRmZmVhOTkxZmEzMmYwZC9pbnNwZWN0b3IuaHRtbD93cz0xMjcuMC4wLjE6MTA5MDAvZGV2dG9vbHMvcGFnZS8yNzMyNUNDNTBCNjAwRDMxQjIzM0Y0NUUwOTQ4N0IxRlwiLFxuICogICAgICAgXCJpZFwiOiBcIjI3MzI1Q0M1MEI2MDBEMzFCMjMzRjQ1RTA5NDg3QjFGXCIsXG4gKiAgICAgICBcInRpdGxlXCI6IFwiUmVsZWFzZXMgwrcgYXBwaXVtL2FwcGl1bSDCtyBHaXRIdWJcIixcbiAqICAgICAgIFwidHlwZVwiOiBcInBhZ2VcIixcbiAqICAgICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2FwcGl1bS9hcHBpdW0vcmVsZWFzZXNcIixcbiAqICAgICAgIFwid2ViU29ja2V0RGVidWdnZXJVcmxcIjogXCJ3czovLzEyNy4wLjAuMToxMDkwMC9kZXZ0b29scy9wYWdlLzI3MzI1Q0M1MEI2MDBEMzFCMjMzRjQ1RTA5NDg3QjFGXCJcbiAqICAgICB9XG4gKiAgIF0sXG4gKiAgIFwid2Vidmlld05hbWVcIjogXCJXRUJWSUVXX2NvbS5pby5hcHBpdW0uc2V0dGluZ1wiXG4gKiB9XG4gKi9cblxuLyoqXG4gKiBSZXR1cm5zIGEgd2Vidmlld3NNYXBwaW5nIGJhc2VkIG9uIENEUCBlbmRwb2ludHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxXZWJ2aWV3c01hcHBpbmc+fSB3ZWJ2aWV3c01hcHBpbmdcbiAqL1xuY29tbWFuZHMubW9iaWxlR2V0Q29udGV4dHMgPSBhc3luYyBmdW5jdGlvbiBtb2JpbGVHZXRDb250ZXh0cyAoKSB7XG4gIGNvbnN0IG9wdHMgPSB7XG4gICAgYW5kcm9pZERldmljZVNvY2tldDogdGhpcy5vcHRzLmFuZHJvaWREZXZpY2VTb2NrZXQsXG4gICAgZW5zdXJlV2Vidmlld3NIYXZlUGFnZXM6IHRydWUsXG4gICAgd2Vidmlld0RldnRvb2xzUG9ydDogdGhpcy5vcHRzLndlYnZpZXdEZXZ0b29sc1BvcnQsXG4gICAgZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uOiB0cnVlXG4gIH07XG4gIHJldHVybiBhd2FpdCB3ZWJ2aWV3SGVscGVycy5nZXRXZWJWaWV3c01hcHBpbmcodGhpcy5hZGIsIG9wdHMpO1xufTtcblxuaGVscGVycy5hc3NpZ25Db250ZXh0cyA9IGZ1bmN0aW9uIGFzc2lnbkNvbnRleHRzICh3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgY29uc3Qgb3B0cyA9IE9iamVjdC5hc3NpZ24oe2lzQ2hyb21lU2Vzc2lvbjogdGhpcy5pc0Nocm9tZVNlc3Npb259LCB0aGlzLm9wdHMpO1xuICBjb25zdCB3ZWJ2aWV3cyA9IHdlYnZpZXdIZWxwZXJzLnBhcnNlV2Vidmlld05hbWVzKHdlYnZpZXdzTWFwcGluZywgb3B0cyk7XG4gIHRoaXMuY29udGV4dHMgPSBbTkFUSVZFX1dJTiwgLi4ud2Vidmlld3NdO1xuICB0aGlzLmxvZy5kZWJ1ZyhgQXZhaWxhYmxlIGNvbnRleHRzOiAke0pTT04uc3RyaW5naWZ5KHRoaXMuY29udGV4dHMpfWApO1xuICByZXR1cm4gdGhpcy5jb250ZXh0cztcbn07XG5cbmhlbHBlcnMuc3dpdGNoQ29udGV4dCA9IGFzeW5jIGZ1bmN0aW9uIHN3aXRjaENvbnRleHQgKG5hbWUsIHdlYnZpZXdzTWFwcGluZykge1xuICAvLyBXZSBoYXZlIHNvbWUgb3B0aW9ucyB3aGVuIGl0IGNvbWVzIHRvIHdlYnZpZXdzLiBJZiB3ZSB3YW50IGFcbiAgLy8gQ2hyb21lZHJpdmVyIHdlYnZpZXcsIHdlIGNhbiBvbmx5IGNvbnRyb2wgb25lIGF0IGEgdGltZS5cbiAgaWYgKHRoaXMuaXNDaHJvbWVkcml2ZXJDb250ZXh0KG5hbWUpKSB7XG4gICAgLy8gc3RhcnQgcHJveHlpbmcgY29tbWFuZHMgZGlyZWN0bHkgdG8gY2hyb21lZHJpdmVyXG4gICAgYXdhaXQgdGhpcy5zdGFydENocm9tZWRyaXZlclByb3h5KG5hbWUsIHdlYnZpZXdzTWFwcGluZyk7XG4gIH0gZWxzZSBpZiAodGhpcy5pc0Nocm9tZWRyaXZlckNvbnRleHQodGhpcy5jdXJDb250ZXh0KSkge1xuICAgIC8vIGlmIHdlJ3JlIG1vdmluZyB0byBhIG5vbi1jaHJvbWVkcml2ZXIgd2VidmlldywgYW5kIG91ciBjdXJyZW50IGNvbnRleHRcbiAgICAvLyBfaXNfIGEgY2hyb21lZHJpdmVyIHdlYnZpZXcsIGlmIGNhcHMgcmVjcmVhdGVDaHJvbWVEcml2ZXJTZXNzaW9ucyBpcyBzZXRcbiAgICAvLyB0byB0cnVlIHRoZW4ga2lsbCBjaHJvbWVkcml2ZXIgc2Vzc2lvbiB1c2luZyBzdG9wQ2hyb21lZHJpdmVyUHJveGllcyBvclxuICAgIC8vIGVsc2Ugc2ltcGx5IHN1c3BlbmQgcHJveHlpbmcgdG8gdGhlIGxhdHRlclxuICAgIGlmICh0aGlzLm9wdHMucmVjcmVhdGVDaHJvbWVEcml2ZXJTZXNzaW9ucykge1xuICAgICAgdGhpcy5sb2cuZGVidWcoJ3JlY3JlYXRlQ2hyb21lRHJpdmVyU2Vzc2lvbnMgc2V0IHRvIHRydWU7IGtpbGxpbmcgZXhpc3RpbmcgY2hyb21lZHJpdmVycycpO1xuICAgICAgYXdhaXQgdGhpcy5zdG9wQ2hyb21lZHJpdmVyUHJveGllcygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0aGlzLnN1c3BlbmRDaHJvbWVkcml2ZXJQcm94eSgpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYERpZG4ndCBrbm93IGhvdyB0byBoYW5kbGUgc3dpdGNoaW5nIHRvIGNvbnRleHQgJyR7bmFtZX0nYCk7XG4gIH1cbn07XG5cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBPbi1vYmplY3QgY29udGV4dC1yZWxhdGVkIGhlbHBlcnNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vLyBUaGUgcmVhc29uIHRoaXMgaXMgYSBmdW5jdGlvbiBhbmQgbm90IGp1c3QgYSBjb25zdGFudCBpcyB0aGF0IGJvdGggYW5kcm9pZC1cbi8vIGRyaXZlciBhbmQgc2VsZW5kcm9pZC1kcml2ZXIgdXNlIHRoaXMgbG9naWMsIGFuZCBlYWNoIG9uZSByZXR1cm5zXG4vLyBhIGRpZmZlcmVudCBkZWZhdWx0IGNvbnRleHQgbmFtZVxuaGVscGVycy5kZWZhdWx0Q29udGV4dE5hbWUgPSBmdW5jdGlvbiBkZWZhdWx0Q29udGV4dE5hbWUgKCkge1xuICByZXR1cm4gTkFUSVZFX1dJTjtcbn07XG5cbmhlbHBlcnMuZGVmYXVsdFdlYnZpZXdOYW1lID0gZnVuY3Rpb24gZGVmYXVsdFdlYnZpZXdOYW1lICgpIHtcbiAgcmV0dXJuIFdFQlZJRVdfQkFTRSArICh0aGlzLm9wdHMuYXV0b1dlYnZpZXdOYW1lIHx8IHRoaXMub3B0cy5hcHBQYWNrYWdlKTtcbn07XG5cbmhlbHBlcnMuaXNXZWJDb250ZXh0ID0gZnVuY3Rpb24gaXNXZWJDb250ZXh0ICgpIHtcbiAgcmV0dXJuIHRoaXMuY3VyQ29udGV4dCAhPT0gbnVsbCAmJiB0aGlzLmN1ckNvbnRleHQgIT09IE5BVElWRV9XSU47XG59O1xuXG4vLyBUdXJuIG9uIHByb3h5aW5nIHRvIGFuIGV4aXN0aW5nIENocm9tZWRyaXZlciBzZXNzaW9uIG9yIGEgbmV3IG9uZVxuaGVscGVycy5zdGFydENocm9tZWRyaXZlclByb3h5ID0gYXN5bmMgZnVuY3Rpb24gc3RhcnRDaHJvbWVkcml2ZXJQcm94eSAoY29udGV4dCwgd2Vidmlld3NNYXBwaW5nKSB7XG4gIHRoaXMubG9nLmRlYnVnKGBDb25uZWN0aW5nIHRvIGNocm9tZS1iYWNrZWQgd2VidmlldyBjb250ZXh0ICcke2NvbnRleHR9J2ApO1xuXG4gIGxldCBjZDtcbiAgaWYgKHRoaXMuc2Vzc2lvbkNocm9tZWRyaXZlcnNbY29udGV4dF0pIHtcbiAgICAvLyBpbiB0aGUgY2FzZSB3aGVyZSB3ZSd2ZSBhbHJlYWR5IHNldCB1cCBhIGNocm9tZWRyaXZlciBmb3IgYSBjb250ZXh0LFxuICAgIC8vIHdlIHdhbnQgdG8gcmVjb25uZWN0IHRvIGl0LCBub3QgY3JlYXRlIGEgd2hvbGUgbmV3IG9uZVxuICAgIHRoaXMubG9nLmRlYnVnKGBGb3VuZCBleGlzdGluZyBDaHJvbWVkcml2ZXIgZm9yIGNvbnRleHQgJyR7Y29udGV4dH0nLiBVc2luZyBpdC5gKTtcbiAgICBjZCA9IHRoaXMuc2Vzc2lvbkNocm9tZWRyaXZlcnNbY29udGV4dF07XG4gICAgYXdhaXQgc2V0dXBFeGlzdGluZ0Nocm9tZWRyaXZlcih0aGlzLmxvZywgY2QpO1xuICB9IGVsc2Uge1xuICAgIGxldCBvcHRzID0gXy5jbG9uZURlZXAodGhpcy5vcHRzKTtcbiAgICBvcHRzLmNocm9tZVVzZVJ1bm5pbmdBcHAgPSB0cnVlO1xuXG4gICAgLy8gaWYgcmVxdWVzdGVkLCB0ZWxsIGNocm9tZWRyaXZlciB0byBhdHRhY2ggdG8gdGhlIGFuZHJvaWQgcGFja2FnZSB3ZSBoYXZlXG4gICAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoZSBjb250ZXh0IG5hbWUsIHJhdGhlciB0aGFuIHRoZSBwYWNrYWdlIG9mIHRoZSBBVVQuXG4gICAgLy8gQW5kIHR1cm4gdGhpcyBvbiBieSBkZWZhdWx0IGZvciBjaHJvbWUtLWlmIGNocm9tZSBwb3BzIHVwIHdpdGggYSB3ZWJ2aWV3XG4gICAgLy8gYW5kIHNvbWVvbmUgd2FudHMgdG8gc3dpdGNoIHRvIGl0LCB3ZSBzaG91bGQgbGV0IGNocm9tZWRyaXZlciBjb25uZWN0IHRvXG4gICAgLy8gY2hyb21lIHJhdGhlciB0aGFuIHN0YXlpbmcgc3R1Y2sgb24gdGhlIEFVVFxuICAgIGlmIChvcHRzLmV4dHJhY3RDaHJvbWVBbmRyb2lkUGFja2FnZUZyb21Db250ZXh0TmFtZSB8fCBjb250ZXh0ID09PSBgJHtXRUJWSUVXX0JBU0V9Y2hyb21lYCkge1xuICAgICAgbGV0IGFuZHJvaWRQYWNrYWdlID0gY29udGV4dC5tYXRjaChgJHtXRUJWSUVXX0JBU0V9KC4rKWApO1xuICAgICAgaWYgKGFuZHJvaWRQYWNrYWdlICYmIGFuZHJvaWRQYWNrYWdlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgb3B0cy5jaHJvbWVBbmRyb2lkUGFja2FnZSA9IGFuZHJvaWRQYWNrYWdlWzFdO1xuICAgICAgfVxuICAgICAgaWYgKCFvcHRzLmV4dHJhY3RDaHJvbWVBbmRyb2lkUGFja2FnZUZyb21Db250ZXh0TmFtZSkge1xuICAgICAgICBpZiAoXy5oYXModGhpcy5vcHRzLCAnZW5hYmxlV2Vidmlld0RldGFpbHNDb2xsZWN0aW9uJykgJiYgIXRoaXMub3B0cy5lbmFibGVXZWJ2aWV3RGV0YWlsc0NvbGxlY3Rpb24pIHtcbiAgICAgICAgICAvLyBXaGVuIGVuYWJsZVdlYnZpZXdEZXRhaWxzQ29sbGVjdGlvbiBjYXBhYmlsaXR5IGlzIGV4cGxpY2l0bHkgZGlzYWJsZWQsIHRyeSB0byBpZGVudGlmeVxuICAgICAgICAgIC8vIGNocm9tZUFuZHJvaWRQYWNrYWdlIGJhc2VkIG9uIGNvbnRleHRzLCBrbm93biBjaHJvbWUgdmFyaWFudCBwYWNrYWdlcyBhbmQgcXVlcnlBcHBTdGF0ZSByZXN1bHRcbiAgICAgICAgICAvLyBzaW5jZSB3ZWJ2aWV3c01hcHBpbmcgZG9lcyBub3QgaGF2ZSBpbmZvIG9iamVjdFxuICAgICAgICAgIGNvbnN0IGNvbnRleHRzID0gd2Vidmlld3NNYXBwaW5nLm1hcCgod20pID0+IHdtLndlYnZpZXdOYW1lKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGtub3duUGFja2FnZSBvZiBLTk9XTl9DSFJPTUVfUEFDS0FHRV9OQU1FUykge1xuICAgICAgICAgICAgaWYgKF8uaW5jbHVkZXMoY29udGV4dHMsIGAke1dFQlZJRVdfQkFTRX0ke2tub3duUGFja2FnZX1gKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFwcFN0YXRlID0gYXdhaXQgdGhpcy5xdWVyeUFwcFN0YXRlKGtub3duUGFja2FnZSk7XG4gICAgICAgICAgICBpZiAoXy5pbmNsdWRlcyhbQVBQX1NUQVRFLlJVTk5JTkdfSU5fQkFDS0dST1VORCwgQVBQX1NUQVRFLlJVTk5JTkdfSU5fRk9SRUdST1VORF0sIGFwcFN0YXRlKSkge1xuICAgICAgICAgICAgICBvcHRzLmNocm9tZUFuZHJvaWRQYWNrYWdlID0ga25vd25QYWNrYWdlO1xuICAgICAgICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgSWRlbnRpZmllZCBjaHJvbWVBbmRyb2lkUGFja2FnZSBhcyAnJHtvcHRzLmNocm9tZUFuZHJvaWRQYWNrYWdlfScgYCArXG4gICAgICAgICAgICAgICAgYGZvciBjb250ZXh0ICcke2NvbnRleHR9JyBieSBxdWVyeWluZyBzdGF0ZXMgb2YgQ2hyb21lIGFwcCBwYWNrYWdlc2ApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChjb25zdCB3bSBvZiB3ZWJ2aWV3c01hcHBpbmcpIHtcbiAgICAgICAgICAgIGlmICh3bS53ZWJ2aWV3TmFtZSA9PT0gY29udGV4dCAmJiBfLmhhcyh3bT8uaW5mbywgJ0FuZHJvaWQtUGFja2FnZScpKSB7XG4gICAgICAgICAgICAgIG9wdHMuY2hyb21lQW5kcm9pZFBhY2thZ2UgPSB3bS5pbmZvWydBbmRyb2lkLVBhY2thZ2UnXTtcbiAgICAgICAgICAgICAgdGhpcy5sb2cuZGVidWcoYElkZW50aWZpZWQgY2hyb21lQW5kcm9pZFBhY2thZ2UgYXMgJyR7b3B0cy5jaHJvbWVBbmRyb2lkUGFja2FnZX0nIGAgK1xuICAgICAgICAgICAgICAgIGBmb3IgY29udGV4dCAnJHtjb250ZXh0fScgYnkgQ0RQYCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNkID0gYXdhaXQgdGhpcy5zZXR1cE5ld0Nocm9tZWRyaXZlcihvcHRzLCB0aGlzLmFkYi5jdXJEZXZpY2VJZCwgdGhpcy5hZGIsIGNvbnRleHQpO1xuICAgIC8vIGJpbmQgb3VyIHN0b3AvZXhpdCBoYW5kbGVyLCBwYXNzaW5nIGluIGNvbnRleHQgc28gd2Uga25vdyB3aGljaFxuICAgIC8vIG9uZSBzdG9wcGVkIHVuZXhwZWN0ZWRseVxuICAgIGNkLm9uKENocm9tZWRyaXZlci5FVkVOVF9DSEFOR0VELCAobXNnKSA9PiB7XG4gICAgICBpZiAobXNnLnN0YXRlID09PSBDaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBFRCkge1xuICAgICAgICB0aGlzLm9uQ2hyb21lZHJpdmVyU3RvcChjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBzYXZlIHRoZSBjaHJvbWVkcml2ZXIgb2JqZWN0IHVuZGVyIHRoZSBjb250ZXh0XG4gICAgdGhpcy5zZXNzaW9uQ2hyb21lZHJpdmVyc1tjb250ZXh0XSA9IGNkO1xuICB9XG4gIC8vIGhvb2sgdXAgdGhlIGxvY2FsIHZhcmlhYmxlcyBzbyB3ZSBjYW4gcHJveHkgdGhpcyBiaXpcbiAgdGhpcy5jaHJvbWVkcml2ZXIgPSBjZDtcbiAgdGhpcy5wcm94eVJlcVJlcyA9IHRoaXMuY2hyb21lZHJpdmVyLnByb3h5UmVxLmJpbmQodGhpcy5jaHJvbWVkcml2ZXIpO1xuICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuY2hyb21lZHJpdmVyLmp3cHJveHkuY29tbWFuZC5iaW5kKHRoaXMuY2hyb21lZHJpdmVyLmp3cHJveHkpO1xuICB0aGlzLmp3cFByb3h5QWN0aXZlID0gdHJ1ZTtcbn07XG5cbi8vIFN0b3AgcHJveHlpbmcgdG8gYW55IENocm9tZWRyaXZlclxuaGVscGVycy5zdXNwZW5kQ2hyb21lZHJpdmVyUHJveHkgPSBmdW5jdGlvbiBzdXNwZW5kQ2hyb21lZHJpdmVyUHJveHkgKCkge1xuICB0aGlzLmNocm9tZWRyaXZlciA9IG51bGw7XG4gIHRoaXMucHJveHlSZXFSZXMgPSBudWxsO1xuICB0aGlzLnByb3h5Q29tbWFuZCA9IG51bGw7XG4gIHRoaXMuandwUHJveHlBY3RpdmUgPSBmYWxzZTtcbn07XG5cbi8vIEhhbmRsZSBhbiBvdXQtb2YtYmFuZCBDaHJvbWVkcml2ZXIgc3RvcCBldmVudFxuaGVscGVycy5vbkNocm9tZWRyaXZlclN0b3AgPSBhc3luYyBmdW5jdGlvbiBvbkNocm9tZWRyaXZlclN0b3AgKGNvbnRleHQpIHtcbiAgdGhpcy5sb2cud2FybihgQ2hyb21lZHJpdmVyIGZvciBjb250ZXh0ICR7Y29udGV4dH0gc3RvcHBlZCB1bmV4cGVjdGVkbHlgKTtcbiAgaWYgKGNvbnRleHQgPT09IHRoaXMuY3VyQ29udGV4dCkge1xuICAgIC8vIHdlIGV4aXRlZCB1bmV4cGVjdGVkbHkgd2hpbGUgYXV0b21hdGluZyB0aGUgY3VycmVudCBjb250ZXh0IGFuZCBzbyB3YW50XG4gICAgLy8gdG8gc2h1dCBkb3duIHRoZSBzZXNzaW9uIGFuZCByZXNwb25kIHdpdGggYW4gZXJyb3JcbiAgICBsZXQgZXJyID0gbmV3IEVycm9yKCdDaHJvbWVkcml2ZXIgcXVpdCB1bmV4cGVjdGVkbHkgZHVyaW5nIHNlc3Npb24nKTtcbiAgICBhd2FpdCB0aGlzLnN0YXJ0VW5leHBlY3RlZFNodXRkb3duKGVycik7XG4gIH0gZWxzZSB7XG4gICAgLy8gaWYgYSBDaHJvbWVkcml2ZXIgaW4gdGhlIG5vbi1hY3RpdmUgY29udGV4dCBiYXJmcywgd2UgZG9uJ3QgcmVhbGx5XG4gICAgLy8gY2FyZSwgd2UnbGwganVzdCBtYWtlIGEgbmV3IG9uZSBuZXh0IHRpbWUgd2UgbmVlZCB0aGUgY29udGV4dC5cbiAgICB0aGlzLmxvZy53YXJuKFwiQ2hyb21lZHJpdmVyIHF1aXQgdW5leHBlY3RlZGx5LCBidXQgaXQgd2Fzbid0IHRoZSBhY3RpdmUgXCIgK1xuICAgICAgJ2NvbnRleHQsIGlnbm9yaW5nJyk7XG4gICAgZGVsZXRlIHRoaXMuc2Vzc2lvbkNocm9tZWRyaXZlcnNbY29udGV4dF07XG4gIH1cbn07XG5cbi8vIEludGVudGlvbmFsbHkgc3RvcCBhbGwgdGhlIGNocm9tZWRyaXZlcnMgY3VycmVudGx5IGFjdGl2ZSwgYW5kIGlnbm9yZVxuLy8gdGhlaXIgZXhpdCBldmVudHNcbmhlbHBlcnMuc3RvcENocm9tZWRyaXZlclByb3hpZXMgPSBhc3luYyBmdW5jdGlvbiBzdG9wQ2hyb21lZHJpdmVyUHJveGllcyAoKSB7XG4gIHRoaXMuc3VzcGVuZENocm9tZWRyaXZlclByb3h5KCk7IC8vIG1ha2Ugc3VyZSB3ZSB0dXJuIG9mZiB0aGUgcHJveHkgZmxhZ1xuICBmb3IgKGxldCBjb250ZXh0IG9mIF8ua2V5cyh0aGlzLnNlc3Npb25DaHJvbWVkcml2ZXJzKSkge1xuICAgIGxldCBjZCA9IHRoaXMuc2Vzc2lvbkNocm9tZWRyaXZlcnNbY29udGV4dF07XG4gICAgdGhpcy5sb2cuZGVidWcoYFN0b3BwaW5nIGNocm9tZWRyaXZlciBmb3IgY29udGV4dCAke2NvbnRleHR9YCk7XG4gICAgLy8gc3RvcCBsaXN0ZW5pbmcgZm9yIHRoZSBzdG9wcGVkIHN0YXRlIGV2ZW50XG4gICAgY2QucmVtb3ZlQWxsTGlzdGVuZXJzKENocm9tZWRyaXZlci5FVkVOVF9DSEFOR0VEKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY2Quc3RvcCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5sb2cud2FybihgRXJyb3Igc3RvcHBpbmcgQ2hyb21lZHJpdmVyOiAke2Vyci5tZXNzYWdlfWApO1xuICAgIH1cbiAgICBkZWxldGUgdGhpcy5zZXNzaW9uQ2hyb21lZHJpdmVyc1tjb250ZXh0XTtcbiAgfVxufTtcblxuaGVscGVycy5pc0Nocm9tZWRyaXZlckNvbnRleHQgPSBmdW5jdGlvbiBpc0Nocm9tZWRyaXZlckNvbnRleHQgKHZpZXdOYW1lKSB7XG4gIHJldHVybiBfLmluY2x1ZGVzKHZpZXdOYW1lLCBXRUJWSUVXX1dJTikgfHwgdmlld05hbWUgPT09IENIUk9NSVVNX1dJTjtcbn07XG5cbmhlbHBlcnMuc2hvdWxkRGlzbWlzc0Nocm9tZVdlbGNvbWUgPSBmdW5jdGlvbiBzaG91bGREaXNtaXNzQ2hyb21lV2VsY29tZSAoKSB7XG4gIHJldHVybiAhIXRoaXMub3B0cy5jaHJvbWVPcHRpb25zICYmXG4gICAgICAgICBfLmlzQXJyYXkodGhpcy5vcHRzLmNocm9tZU9wdGlvbnMuYXJncykgJiZcbiAgICAgICAgIHRoaXMub3B0cy5jaHJvbWVPcHRpb25zLmFyZ3MuaW5jbHVkZXMoJy0tbm8tZmlyc3QtcnVuJyk7XG59O1xuXG5oZWxwZXJzLmRpc21pc3NDaHJvbWVXZWxjb21lID0gYXN5bmMgZnVuY3Rpb24gZGlzbWlzc0Nocm9tZVdlbGNvbWUgKCkge1xuICB0aGlzLmxvZy5pbmZvKCdUcnlpbmcgdG8gZGlzbWlzcyBDaHJvbWUgd2VsY29tZScpO1xuICBsZXQgYWN0aXZpdHkgPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRBY3Rpdml0eSgpO1xuICBpZiAoYWN0aXZpdHkgIT09ICdvcmcuY2hyb21pdW0uY2hyb21lLmJyb3dzZXIuZmlyc3RydW4uRmlyc3RSdW5BY3Rpdml0eScpIHtcbiAgICB0aGlzLmxvZy5pbmZvKCdDaHJvbWUgd2VsY29tZSBkaWFsb2cgbmV2ZXIgc2hvd2VkIHVwISBDb250aW51aW5nJyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBlbCA9IGF3YWl0IHRoaXMuZmluZEVsT3JFbHMoJ2lkJywgJ2NvbS5hbmRyb2lkLmNocm9tZTppZC90ZXJtc19hY2NlcHQnLCBmYWxzZSk7XG4gIGF3YWl0IHRoaXMuY2xpY2soZWwuRUxFTUVOVCk7XG4gIHRyeSB7XG4gICAgbGV0IGVsID0gYXdhaXQgdGhpcy5maW5kRWxPckVscygnaWQnLCAnY29tLmFuZHJvaWQuY2hyb21lOmlkL25lZ2F0aXZlX2J1dHRvbicsIGZhbHNlKTtcbiAgICBhd2FpdCB0aGlzLmNsaWNrKGVsLkVMRU1FTlQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gRE8gTk9USElORywgVEhJUyBERVZJQ0UgRElETlQgTEFVTkNIIFRIRSBTSUdOSU4gRElBTE9HXG4gICAgLy8gSVQgTVVTVCBCRSBBIE5PTiBHTVMgREVWSUNFXG4gICAgdGhpcy5sb2cud2FybihgVGhpcyBkZXZpY2UgZGlkIG5vdCBzaG93IENocm9tZSBTaWduSW4gZGlhbG9nLCAke2UubWVzc2FnZX1gKTtcbiAgfVxufTtcblxuaGVscGVycy5zdGFydENocm9tZVNlc3Npb24gPSBhc3luYyBmdW5jdGlvbiBzdGFydENocm9tZVNlc3Npb24gKCkge1xuICB0aGlzLmxvZy5pbmZvKCdTdGFydGluZyBhIGNocm9tZS1iYXNlZCBicm93c2VyIHNlc3Npb24nKTtcbiAgbGV0IG9wdHMgPSBfLmNsb25lRGVlcCh0aGlzLm9wdHMpO1xuXG4gIGNvbnN0IGtub3duUGFja2FnZXMgPSBbXG4gICAgJ29yZy5jaHJvbWl1bS5jaHJvbWUuc2hlbGwnLFxuICAgICdjb20uYW5kcm9pZC5jaHJvbWUnLFxuICAgICdjb20uY2hyb21lLmJldGEnLFxuICAgICdvcmcuY2hyb21pdW0uY2hyb21lJyxcbiAgICAnb3JnLmNocm9taXVtLndlYnZpZXdfc2hlbGwnLFxuICBdO1xuXG4gIGlmIChfLmluY2x1ZGVzKGtub3duUGFja2FnZXMsIHRoaXMub3B0cy5hcHBQYWNrYWdlKSkge1xuICAgIG9wdHMuY2hyb21lQnVuZGxlSWQgPSB0aGlzLm9wdHMuYXBwUGFja2FnZTtcbiAgfSBlbHNlIHtcbiAgICBvcHRzLmNocm9tZUFuZHJvaWRBY3Rpdml0eSA9IHRoaXMub3B0cy5hcHBBY3Rpdml0eTtcbiAgfVxuICB0aGlzLmNocm9tZWRyaXZlciA9IGF3YWl0IHRoaXMuc2V0dXBOZXdDaHJvbWVkcml2ZXIob3B0cywgdGhpcy5hZGIuY3VyRGV2aWNlSWQsIHRoaXMuYWRiKTtcbiAgdGhpcy5jaHJvbWVkcml2ZXIub24oQ2hyb21lZHJpdmVyLkVWRU5UX0NIQU5HRUQsIChtc2cpID0+IHtcbiAgICBpZiAobXNnLnN0YXRlID09PSBDaHJvbWVkcml2ZXIuU1RBVEVfU1RPUFBFRCkge1xuICAgICAgdGhpcy5vbkNocm9tZWRyaXZlclN0b3AoQ0hST01JVU1fV0lOKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIE5vdyB0aGF0IHdlIGhhdmUgYSBDaHJvbWUgc2Vzc2lvbiwgd2UgZW5zdXJlIHRoYXQgdGhlIGNvbnRleHQgaXNcbiAgLy8gYXBwcm9wcmlhdGVseSBzZXQgYW5kIHRoYXQgdGhpcyBjaHJvbWVkcml2ZXIgaXMgYWRkZWQgdG8gdGhlIGxpc3RcbiAgLy8gb2Ygc2Vzc2lvbiBjaHJvbWVkcml2ZXJzIHNvIHdlIGNhbiBzd2l0Y2ggYmFjayBhbmQgZm9ydGhcbiAgdGhpcy5jdXJDb250ZXh0ID0gQ0hST01JVU1fV0lOO1xuICB0aGlzLnNlc3Npb25DaHJvbWVkcml2ZXJzW0NIUk9NSVVNX1dJTl0gPSB0aGlzLmNocm9tZWRyaXZlcjtcbiAgdGhpcy5wcm94eVJlcVJlcyA9IHRoaXMuY2hyb21lZHJpdmVyLnByb3h5UmVxLmJpbmQodGhpcy5jaHJvbWVkcml2ZXIpO1xuICB0aGlzLnByb3h5Q29tbWFuZCA9IHRoaXMuY2hyb21lZHJpdmVyLmp3cHJveHkuY29tbWFuZC5iaW5kKHRoaXMuY2hyb21lZHJpdmVyLmp3cHJveHkpO1xuICB0aGlzLmp3cFByb3h5QWN0aXZlID0gdHJ1ZTtcblxuICBpZiAodGhpcy5zaG91bGREaXNtaXNzQ2hyb21lV2VsY29tZSgpKSB7XG4gICAgLy8gZGlzbWlzcyBDaHJvbWUgd2VsY29tZSBkaWFsb2dcbiAgICBhd2FpdCB0aGlzLmRpc21pc3NDaHJvbWVXZWxjb21lKCk7XG4gIH1cbn07XG5cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEludGVybmFsIGxpYnJhcnkgZnVuY3Rpb25zXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5hc3luYyBmdW5jdGlvbiBzZXR1cEV4aXN0aW5nQ2hyb21lZHJpdmVyIChsb2csIGNocm9tZWRyaXZlcikge1xuICAvLyBjaGVjayB0aGUgc3RhdHVzIGJ5IHNlbmRpbmcgYSBzaW1wbGUgd2luZG93LWJhc2VkIGNvbW1hbmQgdG8gQ2hyb21lRHJpdmVyXG4gIC8vIGlmIHRoZXJlIGlzIGFuIGVycm9yLCB3ZSB3YW50IHRvIHJlY3JlYXRlIHRoZSBDaHJvbWVEcml2ZXIgc2Vzc2lvblxuICBpZiAoIWF3YWl0IGNocm9tZWRyaXZlci5oYXNXb3JraW5nV2VidmlldygpKSB7XG4gICAgbG9nLmRlYnVnKCdDaHJvbWVEcml2ZXIgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhIHdpbmRvdy4gJyArXG4gICAgICAgICAgICAgICAgICdSZS1pbml0aWFsaXppbmcgdGhlIHNlc3Npb24uJyk7XG4gICAgYXdhaXQgY2hyb21lZHJpdmVyLnJlc3RhcnQoKTtcbiAgfVxuICByZXR1cm4gY2hyb21lZHJpdmVyO1xufVxuXG4vKipcbiAqIEZpbmQgYSBmcmVlIHBvcnQgdG8gaGF2ZSBDaHJvbWVkcml2ZXIgbGlzdGVuIG9uLlxuICpcbiAqIEBwYXJhbSB7YXJyYXl9IHBvcnRTcGVjIC0gQXJyYXkgd2hpY2ggaXMgYSBsaXN0IG9mIHBvcnRzLiBBIGxpc3QgaXRlbSBtYXlcbiAqIGFsc28gaXRzZWxmIGJlIGFuIGFycmF5IG9mIGxlbmd0aCAyIHNwZWNpZnlpbmcgYSBzdGFydCBhbmQgZW5kIHBvcnQgb2ZcbiAqIGEgcmFuZ2UuIFNvbWUgdmFsaWQgcG9ydCBzcGVjczpcbiAqICAgIC0gWzgwMDAsIDgwMDEsIDgwMDJdXG4gKiAgICAtIFtbODAwMCwgODAwNV1dXG4gKiAgICAtIFs4MDAwLCBbOTAwMCwgOTEwMF1dXG4gKiBAcGFyYW0ge09iamVjdD99IGxvZyBMb2dnZXIgaW5zdGFuY2VcbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEEgZnJlZSBwb3J0XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldENocm9tZWRyaXZlclBvcnQgKHBvcnRTcGVjLCBsb2cgPSBudWxsKSB7XG4gIGNvbnN0IGdldFBvcnQgPSBCLnByb21pc2lmeShQb3J0RmluZGVyLmdldFBvcnQsIHtjb250ZXh0OiBQb3J0RmluZGVyfSk7XG5cbiAgLy8gaWYgdGhlIHVzZXIgZGlkbid0IGdpdmUgdXMgYW55IHNwZWNpZmljIGluZm9ybWF0aW9uIGFib3V0IGNocm9tZWRyaXZlclxuICAvLyBwb3J0IHJhbmdlcywganVzdCBmaW5kIGFueSBmcmVlIHBvcnRcbiAgaWYgKCFwb3J0U3BlYykge1xuICAgIGNvbnN0IHBvcnQgPSBhd2FpdCBnZXRQb3J0KCk7XG4gICAgbG9nPy5kZWJ1ZyhgQSBwb3J0IHdhcyBub3QgZ2l2ZW4sIHVzaW5nIHJhbmRvbSBmcmVlIHBvcnQ6ICR7cG9ydH1gKTtcbiAgICByZXR1cm4gcG9ydDtcbiAgfVxuXG4gIC8vIG90aGVyd2lzZSBmaW5kIHRoZSBmcmVlIHBvcnQgYmFzZWQgb24gYSBsaXN0IG9yIHJhbmdlIHByb3ZpZGVkIGJ5IHRoZSB1c2VyXG4gIGxvZz8uZGVidWcoYEZpbmRpbmcgYSBmcmVlIHBvcnQgZm9yIGNocm9tZWRyaXZlciB1c2luZyBzcGVjICR7SlNPTi5zdHJpbmdpZnkocG9ydFNwZWMpfWApO1xuICBsZXQgZm91bmRQb3J0ID0gbnVsbDtcbiAgZm9yIChjb25zdCBwb3RlbnRpYWxQb3J0IG9mIHBvcnRTcGVjKSB7XG4gICAgbGV0IHBvcnQsIHN0b3BQb3J0O1xuICAgIGlmIChfLmlzQXJyYXkocG90ZW50aWFsUG9ydCkpIHtcbiAgICAgIChbcG9ydCwgc3RvcFBvcnRdID0gcG90ZW50aWFsUG9ydCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvcnQgPSBwYXJzZUludChwb3RlbnRpYWxQb3J0LCAxMCk7IC8vIGVuc3VyZSB3ZSBoYXZlIGEgbnVtYmVyIGFuZCBub3QgYSBzdHJpbmdcbiAgICAgIHN0b3BQb3J0ID0gcG9ydDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGxvZz8uZGVidWcoYENoZWNraW5nIHBvcnQgcmFuZ2UgJHtwb3J0fToke3N0b3BQb3J0fWApO1xuICAgICAgZm91bmRQb3J0ID0gYXdhaXQgZ2V0UG9ydCh7cG9ydCwgc3RvcFBvcnR9KTtcbiAgICAgIGJyZWFrO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZz8uZGVidWcoYE5vdGhpbmcgaW4gcG9ydCByYW5nZSAke3BvcnR9OiR7c3RvcFBvcnR9IHdhcyBhdmFpbGFibGVgKTtcbiAgICB9XG4gIH1cblxuICBpZiAoZm91bmRQb3J0ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZmluZCBhIGZyZWUgcG9ydCBmb3IgY2hyb21lZHJpdmVyIHVzaW5nIGAgK1xuICAgICAgICAgICAgICAgICAgICBgY2hyb21lZHJpdmVyUG9ydHMgc3BlYyAke0pTT04uc3RyaW5naWZ5KHBvcnRTcGVjKX1gKTtcbiAgfVxuXG4gIGxvZz8uZGVidWcoYFVzaW5nIGZyZWUgcG9ydCAke2ZvdW5kUG9ydH0gZm9yIGNocm9tZWRyaXZlcmApO1xuICByZXR1cm4gZm91bmRQb3J0O1xufVxuXG5oZWxwZXJzLmlzQ2hyb21lZHJpdmVyQXV0b2Rvd25sb2FkRW5hYmxlZCA9IGZ1bmN0aW9uIGlzQ2hyb21lZHJpdmVyQXV0b2Rvd25sb2FkRW5hYmxlZCAoKSB7XG4gIGlmICh0aGlzLmlzRmVhdHVyZUVuYWJsZWQoQ0hST01FRFJJVkVSX0FVVE9ET1dOTE9BRF9GRUFUVVJFKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHRoaXM/LmxvZz8uZGVidWcoYEF1dG9tYXRlZCBDaHJvbWVkcml2ZXIgZG93bmxvYWQgaXMgZGlzYWJsZWQuIGAgK1xuICAgIGBVc2UgJyR7Q0hST01FRFJJVkVSX0FVVE9ET1dOTE9BRF9GRUFUVVJFfScgc2VydmVyIGZlYXR1cmUgdG8gZW5hYmxlIGl0YCk7XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmhlbHBlcnMuc2V0dXBOZXdDaHJvbWVkcml2ZXIgPSBhc3luYyBmdW5jdGlvbiBzZXR1cE5ld0Nocm9tZWRyaXZlciAob3B0cywgY3VyRGV2aWNlSWQsIGFkYiwgY29udGV4dCA9IG51bGwpIHtcbiAgaWYgKG9wdHMuY2hyb21lRHJpdmVyUG9ydCkge1xuICAgIHRoaXM/LmxvZz8ud2FybihgVGhlICdjaHJvbWVEcml2ZXJQb3J0JyBjYXBhYmlsaXR5IGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgJ2Nocm9tZWRyaXZlclBvcnQnIGluc3RlYWRgKTtcbiAgICBvcHRzLmNocm9tZWRyaXZlclBvcnQgPSBvcHRzLmNocm9tZURyaXZlclBvcnQ7XG4gIH1cblxuICBpZiAob3B0cy5jaHJvbWVkcml2ZXJQb3J0KSB7XG4gICAgdGhpcz8ubG9nPy5kZWJ1ZyhgVXNpbmcgdXNlci1zcGVjaWZpZWQgcG9ydCAke29wdHMuY2hyb21lZHJpdmVyUG9ydH0gZm9yIGNocm9tZWRyaXZlcmApO1xuICB9IGVsc2Uge1xuICAgIC8vIGlmIGEgc2luZ2xlIHBvcnQgd2Fzbid0IGdpdmVuLCB3ZSdsbCBsb29rIGZvciBhIGZyZWUgb25lXG4gICAgb3B0cy5jaHJvbWVkcml2ZXJQb3J0ID0gYXdhaXQgZ2V0Q2hyb21lZHJpdmVyUG9ydChvcHRzLmNocm9tZWRyaXZlclBvcnRzLCB0aGlzPy5sb2cpO1xuICB9XG5cbiAgY29uc3QgZGV0YWlscyA9IGNvbnRleHQgPyB3ZWJ2aWV3SGVscGVycy5nZXRXZWJ2aWV3RGV0YWlscyhhZGIsIGNvbnRleHQpIDogdW5kZWZpbmVkO1xuICBpZiAoIV8uaXNFbXB0eShkZXRhaWxzKSkge1xuICAgIHRoaXM/LmxvZz8uZGVidWcoJ1Bhc3Npbmcgd2ViIHZpZXcgZGV0YWlscyB0byB0aGUgQ2hyb21lZHJpdmVyIGNvbnN0cnVjdG9yOiAnICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KGRldGFpbHMsIG51bGwsIDIpKTtcbiAgfVxuXG4gIGNvbnN0IGNocm9tZWRyaXZlciA9IG5ldyBDaHJvbWVkcml2ZXIoe1xuICAgIHBvcnQ6IG9wdHMuY2hyb21lZHJpdmVyUG9ydCxcbiAgICBleGVjdXRhYmxlOiBvcHRzLmNocm9tZWRyaXZlckV4ZWN1dGFibGUsXG4gICAgYWRiLFxuICAgIGNtZEFyZ3M6IG9wdHMuY2hyb21lZHJpdmVyQXJncyxcbiAgICB2ZXJib3NlOiAhIW9wdHMuc2hvd0Nocm9tZWRyaXZlckxvZyxcbiAgICBleGVjdXRhYmxlRGlyOiBvcHRzLmNocm9tZWRyaXZlckV4ZWN1dGFibGVEaXIsXG4gICAgbWFwcGluZ1BhdGg6IG9wdHMuY2hyb21lZHJpdmVyQ2hyb21lTWFwcGluZ0ZpbGUsXG4gICAgYnVuZGxlSWQ6IG9wdHMuY2hyb21lQnVuZGxlSWQsXG4gICAgdXNlU3lzdGVtRXhlY3V0YWJsZTogb3B0cy5jaHJvbWVkcml2ZXJVc2VTeXN0ZW1FeGVjdXRhYmxlLFxuICAgIGRpc2FibGVCdWlsZENoZWNrOiBvcHRzLmNocm9tZWRyaXZlckRpc2FibGVCdWlsZENoZWNrLFxuICAgIGRldGFpbHMsXG4gICAgaXNBdXRvZG93bmxvYWRFbmFibGVkOiB0aGlzPy5pc0Nocm9tZWRyaXZlckF1dG9kb3dubG9hZEVuYWJsZWQ/LigpXG4gIH0pO1xuXG4gIC8vIG1ha2Ugc3VyZSB0aGVyZSBhcmUgY2hyb21lT3B0aW9uc1xuICBvcHRzLmNocm9tZU9wdGlvbnMgPSBvcHRzLmNocm9tZU9wdGlvbnMgfHwge307XG4gIC8vIHRyeSBvdXQgYW55IHByZWZpeGVkIGNocm9tZU9wdGlvbnMsXG4gIC8vIGFuZCBzdHJpcCB0aGUgcHJlZml4XG4gIGZvciAoY29uc3Qgb3B0IG9mIF8ua2V5cyhvcHRzKSkge1xuICAgIGlmIChvcHQuZW5kc1dpdGgoJzpjaHJvbWVPcHRpb25zJykpIHtcbiAgICAgIHRoaXM/LmxvZz8ud2FybihgTWVyZ2luZyAnJHtvcHR9JyBpbnRvICdjaHJvbWVPcHRpb25zJy4gVGhpcyBtYXkgY2F1c2UgdW5leHBlY3RlZCBiZWhhdmlvcmApO1xuICAgICAgXy5tZXJnZShvcHRzLmNocm9tZU9wdGlvbnMsIG9wdHNbb3B0XSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgY2FwcyA9IHdlYnZpZXdIZWxwZXJzLmNyZWF0ZUNocm9tZWRyaXZlckNhcHMob3B0cywgY3VyRGV2aWNlSWQsIGRldGFpbHMpO1xuICB0aGlzPy5sb2c/LmRlYnVnKGBCZWZvcmUgc3RhcnRpbmcgY2hyb21lZHJpdmVyLCBhbmRyb2lkUGFja2FnZSBpcyAnJHtjYXBzLmNocm9tZU9wdGlvbnMuYW5kcm9pZFBhY2thZ2V9J2ApO1xuICBhd2FpdCBjaHJvbWVkcml2ZXIuc3RhcnQoY2Fwcyk7XG4gIHJldHVybiBjaHJvbWVkcml2ZXI7XG59O1xuY29uc3Qgc2V0dXBOZXdDaHJvbWVkcml2ZXIgPSBoZWxwZXJzLnNldHVwTmV3Q2hyb21lZHJpdmVyO1xuXG5cbk9iamVjdC5hc3NpZ24oZXh0ZW5zaW9ucywgY29tbWFuZHMsIGhlbHBlcnMpO1xuZXhwb3J0IHsgY29tbWFuZHMsIGhlbHBlcnMsIHNldHVwTmV3Q2hyb21lZHJpdmVyIH07XG5leHBvcnQgZGVmYXVsdCBleHRlbnNpb25zO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLG1CQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxXQUFBLEdBQUFILHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRyxTQUFBLEdBQUFKLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBSSxRQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxPQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxlQUFB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
471
+ exports.default = extensions;
472
+ //# sourceMappingURL=context.js.map