appium-webdriveragent 5.6.2 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +7 -0
  3. package/WebDriverAgentLib/Routing/FBElement.h +3 -0
  4. package/WebDriverAgentLib/Utilities/FBMacros.h +4 -0
  5. package/WebDriverAgentLib/Utilities/FBXPath.m +27 -4
  6. package/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m +1 -0
  7. package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +4 -3
  8. package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +1 -1
  9. package/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m +6 -0
  10. package/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h +2 -0
  11. package/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m +2 -0
  12. package/WebDriverAgentTests/UnitTests/FBXPathTests.m +6 -5
  13. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.h +1 -0
  14. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.m +1 -0
  15. package/build/index.js +39 -36
  16. package/build/lib/check-dependencies.d.ts +3 -0
  17. package/build/lib/check-dependencies.d.ts.map +1 -0
  18. package/build/lib/check-dependencies.js +38 -32
  19. package/build/lib/check-dependencies.js.map +1 -1
  20. package/build/lib/constants.d.ts +12 -0
  21. package/build/lib/constants.d.ts.map +1 -0
  22. package/build/lib/constants.js +8 -10
  23. package/build/lib/constants.js.map +1 -1
  24. package/build/lib/logger.d.ts +3 -0
  25. package/build/lib/logger.d.ts.map +1 -0
  26. package/build/lib/logger.js +5 -11
  27. package/build/lib/logger.js.map +1 -1
  28. package/build/lib/no-session-proxy.d.ts +6 -0
  29. package/build/lib/no-session-proxy.d.ts.map +1 -0
  30. package/build/lib/no-session-proxy.js +22 -26
  31. package/build/lib/no-session-proxy.js.map +1 -1
  32. package/build/lib/utils.d.ts +127 -0
  33. package/build/lib/utils.d.ts.map +1 -0
  34. package/build/lib/utils.js +347 -211
  35. package/build/lib/utils.js.map +1 -1
  36. package/build/lib/webdriveragent.d.ts +145 -0
  37. package/build/lib/webdriveragent.d.ts.map +1 -0
  38. package/build/lib/webdriveragent.js +478 -367
  39. package/build/lib/webdriveragent.js.map +1 -1
  40. package/build/lib/xcodebuild.d.ts +58 -0
  41. package/build/lib/xcodebuild.d.ts.map +1 -0
  42. package/build/lib/xcodebuild.js +367 -289
  43. package/build/lib/xcodebuild.js.map +1 -1
  44. package/lib/check-dependencies.js +3 -4
  45. package/lib/utils.js +10 -7
  46. package/lib/webdriveragent.js +14 -9
  47. package/lib/xcodebuild.js +39 -7
  48. package/package.json +28 -18
@@ -1,318 +1,396 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = exports.XcodeBuild = void 0;
8
- require("source-map-support/register");
9
- var _asyncbox = require("asyncbox");
10
- var _teen_process = require("teen_process");
11
- var _support = require("@appium/support");
12
- var _logger = _interopRequireDefault(require("./logger"));
13
- var _bluebird = _interopRequireDefault(require("bluebird"));
14
- var _utils = require("./utils");
15
- var _lodash = _interopRequireDefault(require("lodash"));
16
- var _path = _interopRequireDefault(require("path"));
17
- var _os = require("os");
18
- var _constants = require("./constants");
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.XcodeBuild = void 0;
7
+ const asyncbox_1 = require("asyncbox");
8
+ const teen_process_1 = require("teen_process");
9
+ const support_1 = require("@appium/support");
10
+ const logger_1 = __importDefault(require("./logger"));
11
+ const bluebird_1 = __importDefault(require("bluebird"));
12
+ const utils_1 = require("./utils");
13
+ const lodash_1 = __importDefault(require("lodash"));
14
+ const path_1 = __importDefault(require("path"));
15
+ const os_1 = require("os");
16
+ const constants_1 = require("./constants");
17
+ const node_readline_1 = __importDefault(require("node:readline"));
19
18
  const DEFAULT_SIGNING_ID = 'iPhone Developer';
20
19
  const PREBUILD_DELAY = 0;
21
20
  const RUNNER_SCHEME_IOS = 'WebDriverAgentRunner';
22
21
  const LIB_SCHEME_IOS = 'WebDriverAgentLib';
23
22
  const ERROR_WRITING_ATTACHMENT = 'Error writing attachment data to file';
24
23
  const ERROR_COPYING_ATTACHMENT = 'Error copying testing attachment';
25
- const IGNORED_ERRORS = [ERROR_WRITING_ATTACHMENT, ERROR_COPYING_ATTACHMENT, 'Failed to remove screenshot at path'];
24
+ const IGNORED_ERRORS = [
25
+ ERROR_WRITING_ATTACHMENT,
26
+ ERROR_COPYING_ATTACHMENT,
27
+ 'Failed to remove screenshot at path',
28
+ ];
26
29
  const RUNNER_SCHEME_TV = 'WebDriverAgentRunner_tvOS';
27
30
  const LIB_SCHEME_TV = 'WebDriverAgentLib_tvOS';
28
- const xcodeLog = _support.logger.getLogger('Xcode');
31
+ const xcodeLog = support_1.logger.getLogger('Xcode');
29
32
  class XcodeBuild {
30
- constructor(xcodeVersion, device, args = {}, log = null) {
31
- this.xcodeVersion = xcodeVersion;
32
- this.device = device;
33
- this.log = log ?? _logger.default;
34
- this.realDevice = args.realDevice;
35
- this.agentPath = args.agentPath;
36
- this.bootstrapPath = args.bootstrapPath;
37
- this.platformVersion = args.platformVersion;
38
- this.platformName = args.platformName;
39
- this.iosSdkVersion = args.iosSdkVersion;
40
- this.showXcodeLog = args.showXcodeLog;
41
- this.xcodeConfigFile = args.xcodeConfigFile;
42
- this.xcodeOrgId = args.xcodeOrgId;
43
- this.xcodeSigningId = args.xcodeSigningId || DEFAULT_SIGNING_ID;
44
- this.keychainPath = args.keychainPath;
45
- this.keychainPassword = args.keychainPassword;
46
- this.prebuildWDA = args.prebuildWDA;
47
- this.usePrebuiltWDA = args.usePrebuiltWDA;
48
- this.useSimpleBuildTest = args.useSimpleBuildTest;
49
- this.useXctestrunFile = args.useXctestrunFile;
50
- this.launchTimeout = args.launchTimeout;
51
- this.wdaRemotePort = args.wdaRemotePort;
52
- this.updatedWDABundleId = args.updatedWDABundleId;
53
- this.derivedDataPath = args.derivedDataPath;
54
- this.mjpegServerPort = args.mjpegServerPort;
55
- this.prebuildDelay = _lodash.default.isNumber(args.prebuildDelay) ? args.prebuildDelay : PREBUILD_DELAY;
56
- this.allowProvisioningDeviceRegistration = args.allowProvisioningDeviceRegistration;
57
- this.resultBundlePath = args.resultBundlePath;
58
- this.resultBundleVersion = args.resultBundleVersion;
59
- }
60
- async init(noSessionProxy) {
61
- this.noSessionProxy = noSessionProxy;
62
- if (this.useXctestrunFile) {
63
- const deviveInfo = {
64
- isRealDevice: this.realDevice,
65
- udid: this.device.udid,
66
- platformVersion: this.platformVersion,
67
- platformName: this.platformName
68
- };
69
- this.xctestrunFilePath = await (0, _utils.setXctestrunFile)(deviveInfo, this.iosSdkVersion, this.bootstrapPath, this.wdaRemotePort);
70
- return;
33
+ /**
34
+ * @param {string} xcodeVersion
35
+ * @param {any} device
36
+ * @param {any} args
37
+ * @param {import('@appium/types').AppiumLogger?} log
38
+ */
39
+ constructor(xcodeVersion, device, args = {}, log = null) {
40
+ this.xcodeVersion = xcodeVersion;
41
+ this.device = device;
42
+ this.log = log ?? logger_1.default;
43
+ this.realDevice = args.realDevice;
44
+ this.agentPath = args.agentPath;
45
+ this.bootstrapPath = args.bootstrapPath;
46
+ this.platformVersion = args.platformVersion;
47
+ this.platformName = args.platformName;
48
+ this.iosSdkVersion = args.iosSdkVersion;
49
+ this.showXcodeLog = args.showXcodeLog;
50
+ this.xcodeConfigFile = args.xcodeConfigFile;
51
+ this.xcodeOrgId = args.xcodeOrgId;
52
+ this.xcodeSigningId = args.xcodeSigningId || DEFAULT_SIGNING_ID;
53
+ this.keychainPath = args.keychainPath;
54
+ this.keychainPassword = args.keychainPassword;
55
+ this.prebuildWDA = args.prebuildWDA;
56
+ this.usePrebuiltWDA = args.usePrebuiltWDA;
57
+ this.useSimpleBuildTest = args.useSimpleBuildTest;
58
+ this.useXctestrunFile = args.useXctestrunFile;
59
+ this.launchTimeout = args.launchTimeout;
60
+ this.wdaRemotePort = args.wdaRemotePort;
61
+ this.updatedWDABundleId = args.updatedWDABundleId;
62
+ this.derivedDataPath = args.derivedDataPath;
63
+ this.mjpegServerPort = args.mjpegServerPort;
64
+ this.prebuildDelay = lodash_1.default.isNumber(args.prebuildDelay) ? args.prebuildDelay : PREBUILD_DELAY;
65
+ this.allowProvisioningDeviceRegistration = args.allowProvisioningDeviceRegistration;
66
+ this.resultBundlePath = args.resultBundlePath;
67
+ this.resultBundleVersion = args.resultBundleVersion;
71
68
  }
72
- if (this.realDevice) {
73
- await (0, _utils.resetProjectFile)(this.agentPath);
74
- if (this.updatedWDABundleId) {
75
- await (0, _utils.updateProjectFile)(this.agentPath, this.updatedWDABundleId);
76
- }
77
- }
78
- }
79
- async retrieveDerivedDataPath() {
80
- if (this.derivedDataPath) {
81
- return this.derivedDataPath;
82
- }
83
- if (this._derivedDataPathPromise) {
84
- return await this._derivedDataPathPromise;
85
- }
86
- this._derivedDataPathPromise = (async () => {
87
- let stdout;
88
- try {
89
- ({
90
- stdout
91
- } = await (0, _teen_process.exec)('xcodebuild', ['-project', this.agentPath, '-showBuildSettings']));
92
- } catch (err) {
93
- this.log.warn(`Cannot retrieve WDA build settings. Original error: ${err.message}`);
94
- return;
95
- }
96
- const pattern = /^\s*BUILD_DIR\s+=\s+(\/.*)/m;
97
- const match = pattern.exec(stdout);
98
- if (!match) {
99
- this.log.warn(`Cannot parse WDA build dir from ${_lodash.default.truncate(stdout, {
100
- length: 300
101
- })}`);
102
- return;
103
- }
104
- this.log.debug(`Parsed BUILD_DIR configuration value: '${match[1]}'`);
105
- this.derivedDataPath = _path.default.dirname(_path.default.dirname(_path.default.normalize(match[1])));
106
- this.log.debug(`Got derived data root: '${this.derivedDataPath}'`);
107
- return this.derivedDataPath;
108
- })();
109
- return await this._derivedDataPathPromise;
110
- }
111
- async reset() {
112
- if (this.realDevice && this.updatedWDABundleId) {
113
- await (0, _utils.resetProjectFile)(this.agentPath);
114
- }
115
- }
116
- async prebuild() {
117
- this.log.debug('Pre-building WDA before launching test');
118
- this.usePrebuiltWDA = true;
119
- await this.start(true);
120
- this.xcodebuild = null;
121
- await _bluebird.default.delay(this.prebuildDelay);
122
- }
123
- async cleanProject() {
124
- const libScheme = (0, _utils.isTvOS)(this.platformName) ? LIB_SCHEME_TV : LIB_SCHEME_IOS;
125
- const runnerScheme = (0, _utils.isTvOS)(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS;
126
- for (const scheme of [libScheme, runnerScheme]) {
127
- this.log.debug(`Cleaning the project scheme '${scheme}' to make sure there are no leftovers from previous installs`);
128
- await (0, _teen_process.exec)('xcodebuild', ['clean', '-project', this.agentPath, '-scheme', scheme]);
129
- }
130
- }
131
- getCommand(buildOnly = false) {
132
- let cmd = 'xcodebuild';
133
- let args;
134
- const [buildCmd, testCmd] = this.useSimpleBuildTest ? ['build', 'test'] : ['build-for-testing', 'test-without-building'];
135
- if (buildOnly) {
136
- args = [buildCmd];
137
- } else if (this.usePrebuiltWDA || this.useXctestrunFile) {
138
- args = [testCmd];
139
- } else {
140
- args = [buildCmd, testCmd];
141
- }
142
- if (this.allowProvisioningDeviceRegistration) {
143
- args.push('-allowProvisioningUpdates', '-allowProvisioningDeviceRegistration');
144
- }
145
- if (this.resultBundlePath) {
146
- args.push('-resultBundlePath', this.resultBundlePath);
147
- }
148
- if (this.resultBundleVersion) {
149
- args.push('-resultBundleVersion', this.resultBundleVersion);
150
- }
151
- if (this.useXctestrunFile) {
152
- args.push('-xctestrun', this.xctestrunFilePath);
153
- } else {
154
- const runnerScheme = (0, _utils.isTvOS)(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS;
155
- args.push('-project', this.agentPath, '-scheme', runnerScheme);
156
- if (this.derivedDataPath) {
157
- args.push('-derivedDataPath', this.derivedDataPath);
158
- }
159
- }
160
- args.push('-destination', `id=${this.device.udid}`);
161
- const versionMatch = new RegExp(/^(\d+)\.(\d+)/).exec(this.platformVersion);
162
- if (versionMatch) {
163
- args.push(`${(0, _utils.isTvOS)(this.platformName) ? 'TV' : 'IPHONE'}OS_DEPLOYMENT_TARGET=${versionMatch[1]}.${versionMatch[2]}`);
164
- } else {
165
- this.log.warn(`Cannot parse major and minor version numbers from platformVersion "${this.platformVersion}". ` + 'Will build for the default platform instead');
166
- }
167
- if (this.realDevice && this.xcodeConfigFile) {
168
- this.log.debug(`Using Xcode configuration file: '${this.xcodeConfigFile}'`);
169
- args.push('-xcconfig', this.xcodeConfigFile);
69
+ async init(noSessionProxy) {
70
+ this.noSessionProxy = noSessionProxy;
71
+ if (this.useXctestrunFile) {
72
+ const deviveInfo = {
73
+ isRealDevice: this.realDevice,
74
+ udid: this.device.udid,
75
+ platformVersion: this.platformVersion,
76
+ platformName: this.platformName
77
+ };
78
+ this.xctestrunFilePath = await (0, utils_1.setXctestrunFile)(deviveInfo, this.iosSdkVersion, this.bootstrapPath, this.wdaRemotePort);
79
+ return;
80
+ }
81
+ // if necessary, update the bundleId to user's specification
82
+ if (this.realDevice) {
83
+ // In case the project still has the user specific bundle ID, reset the project file first.
84
+ // - We do this reset even if updatedWDABundleId is not specified,
85
+ // since the previous updatedWDABundleId test has generated the user specific bundle ID project file.
86
+ // - We don't call resetProjectFile for simulator,
87
+ // since simulator test run will work with any user specific bundle ID.
88
+ await (0, utils_1.resetProjectFile)(this.agentPath);
89
+ if (this.updatedWDABundleId) {
90
+ await (0, utils_1.updateProjectFile)(this.agentPath, this.updatedWDABundleId);
91
+ }
92
+ }
170
93
  }
171
- if (!process.env.APPIUM_XCUITEST_TREAT_WARNINGS_AS_ERRORS) {
172
- args.push('GCC_TREAT_WARNINGS_AS_ERRORS=0');
94
+ async retrieveDerivedDataPath() {
95
+ if (this.derivedDataPath) {
96
+ return this.derivedDataPath;
97
+ }
98
+ // avoid race conditions
99
+ if (this._derivedDataPathPromise) {
100
+ return await this._derivedDataPathPromise;
101
+ }
102
+ this._derivedDataPathPromise = (async () => {
103
+ let stdout;
104
+ try {
105
+ ({ stdout } = await (0, teen_process_1.exec)('xcodebuild', ['-project', this.agentPath, '-showBuildSettings']));
106
+ }
107
+ catch (err) {
108
+ this.log.warn(`Cannot retrieve WDA build settings. Original error: ${err.message}`);
109
+ return;
110
+ }
111
+ const pattern = /^\s*BUILD_DIR\s+=\s+(\/.*)/m;
112
+ const match = pattern.exec(stdout);
113
+ if (!match) {
114
+ this.log.warn(`Cannot parse WDA build dir from ${lodash_1.default.truncate(stdout, { length: 300 })}`);
115
+ return;
116
+ }
117
+ this.log.debug(`Parsed BUILD_DIR configuration value: '${match[1]}'`);
118
+ // Derived data root is two levels higher over the build dir
119
+ this.derivedDataPath = path_1.default.dirname(path_1.default.dirname(path_1.default.normalize(match[1])));
120
+ this.log.debug(`Got derived data root: '${this.derivedDataPath}'`);
121
+ return this.derivedDataPath;
122
+ })();
123
+ return await this._derivedDataPathPromise;
173
124
  }
174
- args.push('COMPILER_INDEX_STORE_ENABLE=NO');
175
- return {
176
- cmd,
177
- args
178
- };
179
- }
180
- async createSubProcess(buildOnly = false) {
181
- if (!this.useXctestrunFile && this.realDevice) {
182
- if (this.keychainPath && this.keychainPassword) {
183
- await (0, _utils.setRealDeviceSecurity)(this.keychainPath, this.keychainPassword);
184
- }
185
- if (this.xcodeOrgId && this.xcodeSigningId && !this.xcodeConfigFile) {
186
- this.xcodeConfigFile = await (0, _utils.generateXcodeConfigFile)(this.xcodeOrgId, this.xcodeSigningId);
187
- }
125
+ async reset() {
126
+ // if necessary, reset the bundleId to original value
127
+ if (this.realDevice && this.updatedWDABundleId) {
128
+ await (0, utils_1.resetProjectFile)(this.agentPath);
129
+ }
188
130
  }
189
- const {
190
- cmd,
191
- args
192
- } = this.getCommand(buildOnly);
193
- this.log.debug(`Beginning ${buildOnly ? 'build' : 'test'} with command '${cmd} ${args.join(' ')}' ` + `in directory '${this.bootstrapPath}'`);
194
- const env = Object.assign({}, process.env, {
195
- USE_PORT: this.wdaRemotePort,
196
- WDA_PRODUCT_BUNDLE_IDENTIFIER: this.updatedWDABundleId || _constants.WDA_RUNNER_BUNDLE_ID
197
- });
198
- if (this.mjpegServerPort) {
199
- env.MJPEG_SERVER_PORT = this.mjpegServerPort;
131
+ async prebuild() {
132
+ // first do a build phase
133
+ this.log.debug('Pre-building WDA before launching test');
134
+ this.usePrebuiltWDA = true;
135
+ await this.start(true);
136
+ this.xcodebuild = null;
137
+ // pause a moment
138
+ await bluebird_1.default.delay(this.prebuildDelay);
200
139
  }
201
- const upgradeTimestamp = await (0, _utils.getWDAUpgradeTimestamp)(this.bootstrapPath);
202
- if (upgradeTimestamp) {
203
- env.UPGRADE_TIMESTAMP = upgradeTimestamp;
140
+ async cleanProject() {
141
+ const libScheme = (0, utils_1.isTvOS)(this.platformName) ? LIB_SCHEME_TV : LIB_SCHEME_IOS;
142
+ const runnerScheme = (0, utils_1.isTvOS)(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS;
143
+ for (const scheme of [libScheme, runnerScheme]) {
144
+ this.log.debug(`Cleaning the project scheme '${scheme}' to make sure there are no leftovers from previous installs`);
145
+ await (0, teen_process_1.exec)('xcodebuild', [
146
+ 'clean',
147
+ '-project', this.agentPath,
148
+ '-scheme', scheme,
149
+ ]);
150
+ }
204
151
  }
205
- const xcodebuild = new _teen_process.SubProcess(cmd, args, {
206
- cwd: this.bootstrapPath,
207
- env,
208
- detached: true,
209
- stdio: ['ignore', 'pipe', 'pipe']
210
- });
211
- let logXcodeOutput = !!this.showXcodeLog;
212
- const logMsg = _lodash.default.isBoolean(this.showXcodeLog) ? `Output from xcodebuild ${this.showXcodeLog ? 'will' : 'will not'} be logged` : 'Output from xcodebuild will only be logged if any errors are present there';
213
- this.log.debug(`${logMsg}. To change this, use 'showXcodeLog' desired capability`);
214
- xcodebuild.on('output', (stdout, stderr) => {
215
- let out = stdout || stderr;
216
- if (out.includes('Writing diagnostic log for test session to')) {
217
- xcodebuild.logLocation = _lodash.default.first(_lodash.default.remove(out.trim().split('\n'), v => v.startsWith(_path.default.sep)));
218
- xcodeLog.debug(`Log file for xcodebuild test: ${xcodebuild.logLocation}`);
219
- }
220
- const ignoreError = IGNORED_ERRORS.some(x => out.includes(x));
221
- if (this.showXcodeLog !== false && out.includes('Error Domain=') && !ignoreError) {
222
- logXcodeOutput = true;
223
- xcodebuild._wda_error_occurred = true;
224
- }
225
- if (logXcodeOutput && !ignoreError) {
226
- for (const line of out.split(_os.EOL)) {
227
- xcodeLog.error(line);
228
- if (line) {
229
- xcodebuild._wda_error_message += `${_os.EOL}${line}`;
230
- }
152
+ getCommand(buildOnly = false) {
153
+ let cmd = 'xcodebuild';
154
+ let args;
155
+ // figure out the targets for xcodebuild
156
+ const [buildCmd, testCmd] = this.useSimpleBuildTest ? ['build', 'test'] : ['build-for-testing', 'test-without-building'];
157
+ if (buildOnly) {
158
+ args = [buildCmd];
231
159
  }
232
- }
233
- });
234
- return xcodebuild;
235
- }
236
- async start(buildOnly = false) {
237
- this.xcodebuild = await this.createSubProcess(buildOnly);
238
- this.xcodebuild._wda_error_message = '';
239
- return await new _bluebird.default((resolve, reject) => {
240
- this.xcodebuild.on('exit', async (code, signal) => {
241
- xcodeLog.error(`xcodebuild exited with code '${code}' and signal '${signal}'`);
242
- if (this.showXcodeLog && this.xcodebuild.logLocation) {
243
- xcodeLog.error(`Contents of xcodebuild log file '${this.xcodebuild.logLocation}':`);
244
- try {
245
- let data = await _support.fs.readFile(this.xcodebuild.logLocation, 'utf8');
246
- for (let line of data.split('\n')) {
247
- xcodeLog.error(line);
160
+ else if (this.usePrebuiltWDA || this.useXctestrunFile) {
161
+ args = [testCmd];
162
+ }
163
+ else {
164
+ args = [buildCmd, testCmd];
165
+ }
166
+ if (this.allowProvisioningDeviceRegistration) {
167
+ // To -allowProvisioningDeviceRegistration flag takes effect, -allowProvisioningUpdates needs to be passed as well.
168
+ args.push('-allowProvisioningUpdates', '-allowProvisioningDeviceRegistration');
169
+ }
170
+ if (this.resultBundlePath) {
171
+ args.push('-resultBundlePath', this.resultBundlePath);
172
+ }
173
+ if (this.resultBundleVersion) {
174
+ args.push('-resultBundleVersion', this.resultBundleVersion);
175
+ }
176
+ if (this.useXctestrunFile && this.xctestrunFilePath) {
177
+ args.push('-xctestrun', this.xctestrunFilePath);
178
+ }
179
+ else {
180
+ const runnerScheme = (0, utils_1.isTvOS)(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS;
181
+ args.push('-project', this.agentPath, '-scheme', runnerScheme);
182
+ if (this.derivedDataPath) {
183
+ args.push('-derivedDataPath', this.derivedDataPath);
248
184
  }
249
- } catch (err) {
250
- xcodeLog.error(`Unable to access xcodebuild log file: '${err.message}'`);
251
- }
252
185
  }
253
- this.xcodebuild.processExited = true;
254
- if (this.xcodebuild._wda_error_occurred || !signal && code !== 0) {
255
- return reject(new Error(`xcodebuild failed with code ${code}${_os.EOL}` + `xcodebuild error message:${_os.EOL}${this.xcodebuild._wda_error_message}`));
186
+ args.push('-destination', `id=${this.device.udid}`);
187
+ const versionMatch = new RegExp(/^(\d+)\.(\d+)/).exec(this.platformVersion);
188
+ if (versionMatch) {
189
+ args.push(`${(0, utils_1.isTvOS)(this.platformName) ? 'TV' : 'IPHONE'}OS_DEPLOYMENT_TARGET=${versionMatch[1]}.${versionMatch[2]}`);
256
190
  }
257
- if (buildOnly) {
258
- return resolve();
191
+ else {
192
+ this.log.warn(`Cannot parse major and minor version numbers from platformVersion "${this.platformVersion}". ` +
193
+ 'Will build for the default platform instead');
259
194
  }
260
- });
261
- return (async () => {
262
- try {
263
- const timer = new _support.timing.Timer().start();
264
- await this.xcodebuild.start(true);
265
- if (!buildOnly) {
266
- let status = await this.waitForStart(timer);
267
- resolve(status);
268
- }
269
- } catch (err) {
270
- let msg = `Unable to start WebDriverAgent: ${err}`;
271
- this.log.error(msg);
272
- reject(new Error(msg));
195
+ if (this.realDevice && this.xcodeConfigFile) {
196
+ this.log.debug(`Using Xcode configuration file: '${this.xcodeConfigFile}'`);
197
+ args.push('-xcconfig', this.xcodeConfigFile);
198
+ }
199
+ if (!process.env.APPIUM_XCUITEST_TREAT_WARNINGS_AS_ERRORS) {
200
+ // This sometimes helps to survive Xcode updates
201
+ args.push('GCC_TREAT_WARNINGS_AS_ERRORS=0');
202
+ }
203
+ // Below option slightly reduces build time in debug build
204
+ // with preventing to generate `/Index/DataStore` which is used by development
205
+ args.push('COMPILER_INDEX_STORE_ENABLE=NO');
206
+ return { cmd, args };
207
+ }
208
+ async createSubProcess(buildOnly = false) {
209
+ if (!this.useXctestrunFile && this.realDevice) {
210
+ if (this.keychainPath && this.keychainPassword) {
211
+ await (0, utils_1.setRealDeviceSecurity)(this.keychainPath, this.keychainPassword);
212
+ }
213
+ if (this.xcodeOrgId && this.xcodeSigningId && !this.xcodeConfigFile) {
214
+ this.xcodeConfigFile = await (0, utils_1.generateXcodeConfigFile)(this.xcodeOrgId, this.xcodeSigningId);
215
+ }
216
+ }
217
+ const { cmd, args } = this.getCommand(buildOnly);
218
+ this.log.debug(`Beginning ${buildOnly ? 'build' : 'test'} with command '${cmd} ${args.join(' ')}' ` +
219
+ `in directory '${this.bootstrapPath}'`);
220
+ /** @type {Record<string, any>} */
221
+ const env = Object.assign({}, process.env, {
222
+ USE_PORT: this.wdaRemotePort,
223
+ WDA_PRODUCT_BUNDLE_IDENTIFIER: this.updatedWDABundleId || constants_1.WDA_RUNNER_BUNDLE_ID,
224
+ });
225
+ if (this.mjpegServerPort) {
226
+ // https://github.com/appium/WebDriverAgent/pull/105
227
+ env.MJPEG_SERVER_PORT = this.mjpegServerPort;
273
228
  }
274
- })();
275
- });
276
- }
277
- async waitForStart(timer) {
278
- this.log.debug(`Waiting up to ${this.launchTimeout}ms for WebDriverAgent to start`);
279
- let currentStatus = null;
280
- try {
281
- let retries = parseInt(this.launchTimeout / 500, 10);
282
- await (0, _asyncbox.retryInterval)(retries, 1000, async () => {
283
- if (this.xcodebuild.processExited) {
284
- return;
229
+ const upgradeTimestamp = await (0, utils_1.getWDAUpgradeTimestamp)();
230
+ if (upgradeTimestamp) {
231
+ env.UPGRADE_TIMESTAMP = upgradeTimestamp;
285
232
  }
286
- const proxyTimeout = this.noSessionProxy.timeout;
287
- this.noSessionProxy.timeout = 1000;
233
+ const xcodebuild = new teen_process_1.SubProcess(cmd, args, {
234
+ cwd: this.bootstrapPath,
235
+ env,
236
+ detached: true,
237
+ stdio: ['ignore', 'pipe', 'pipe'],
238
+ });
239
+ let logXcodeOutput = !!this.showXcodeLog;
240
+ const logMsg = lodash_1.default.isBoolean(this.showXcodeLog)
241
+ ? `Output from xcodebuild ${this.showXcodeLog ? 'will' : 'will not'} be logged`
242
+ : 'Output from xcodebuild will only be logged if any errors are present there';
243
+ this.log.debug(`${logMsg}. To change this, use 'showXcodeLog' desired capability`);
244
+ xcodebuild.on('output', (stdout, stderr) => {
245
+ let out = stdout || stderr;
246
+ // we want to pull out the log file that is created, and highlight it
247
+ // for diagnostic purposes
248
+ if (out.includes('Writing diagnostic log for test session to')) {
249
+ // pull out the first line that begins with the path separator
250
+ // which *should* be the line indicating the log file generated
251
+ // @ts-ignore logLocation is a custom property
252
+ xcodebuild.logLocation = lodash_1.default.first(lodash_1.default.remove(out.trim().split('\n'), (v) => v.startsWith(path_1.default.sep)));
253
+ // @ts-ignore logLocation is a custom property
254
+ xcodeLog.debug(`Log file for xcodebuild test: ${xcodebuild.logLocation}`);
255
+ }
256
+ // if we have an error we want to output the logs
257
+ // otherwise the failure is inscrutible
258
+ // but do not log permission errors from trying to write to attachments folder
259
+ const ignoreError = IGNORED_ERRORS.some((x) => out.includes(x));
260
+ if (this.showXcodeLog !== false && out.includes('Error Domain=') && !ignoreError) {
261
+ logXcodeOutput = true;
262
+ // terrible hack to handle case where xcode return 0 but is failing
263
+ // @ts-ignore _wda_error_occurred is a custom property
264
+ xcodebuild._wda_error_occurred = true;
265
+ }
266
+ // do not log permission errors from trying to write to attachments folder
267
+ if (logXcodeOutput && !ignoreError) {
268
+ for (const line of out.split(os_1.EOL)) {
269
+ xcodeLog.error(line);
270
+ if (line) {
271
+ // @ts-ignore _wda_error_message is a custom property
272
+ xcodebuild._wda_error_message += `${os_1.EOL}${line}`;
273
+ }
274
+ }
275
+ }
276
+ });
277
+ return xcodebuild;
278
+ }
279
+ async start(buildOnly = false) {
280
+ this.xcodebuild = await this.createSubProcess(buildOnly);
281
+ // Store xcodebuild message
282
+ // @ts-ignore _wda_error_message is a custom property
283
+ this.xcodebuild._wda_error_message = '';
284
+ // wrap the start procedure in a promise so that we can catch, and report,
285
+ // any startup errors that are thrown as events
286
+ return await new bluebird_1.default((resolve, reject) => {
287
+ // @ts-ignore xcodebuild must be present here
288
+ this.xcodebuild.on('exit', async (code, signal) => {
289
+ xcodeLog.error(`xcodebuild exited with code '${code}' and signal '${signal}'`);
290
+ // print out the xcodebuild file if users have asked for it
291
+ // @ts-ignore logLocation is a custom property
292
+ if (this.showXcodeLog && this.xcodebuild?.logLocation) {
293
+ // @ts-ignore logLocation is a custom property
294
+ xcodeLog.error(`Contents of xcodebuild log file '${this.xcodebuild.logLocation}':`);
295
+ try {
296
+ const logFile = node_readline_1.default.createInterface({
297
+ // @ts-ignore logLocation is a custom property
298
+ input: support_1.fs.createReadStream(this.xcodebuild.logLocation),
299
+ terminal: false
300
+ });
301
+ logFile.on('line', (line) => {
302
+ xcodeLog.error(line);
303
+ });
304
+ await new bluebird_1.default((_resolve) => {
305
+ logFile.once('close', () => {
306
+ logFile.removeAllListeners();
307
+ _resolve();
308
+ });
309
+ });
310
+ }
311
+ catch (err) {
312
+ xcodeLog.error(`Unable to access xcodebuild log file: '${err.message}'`);
313
+ }
314
+ }
315
+ // @ts-ignore processExited is a custom property
316
+ this.xcodebuild.processExited = true;
317
+ // @ts-ignore _wda_error_occurred is a custom property
318
+ if (this.xcodebuild._wda_error_occurred || (!signal && code !== 0)) {
319
+ return reject(new Error(`xcodebuild failed with code ${code}${os_1.EOL}` +
320
+ // @ts-ignore _wda_error_message is a custom property
321
+ `xcodebuild error message:${os_1.EOL}${this.xcodebuild._wda_error_message}`));
322
+ }
323
+ // in the case of just building, the process will exit and that is our finish
324
+ if (buildOnly) {
325
+ return resolve();
326
+ }
327
+ });
328
+ return (async () => {
329
+ try {
330
+ const timer = new support_1.timing.Timer().start();
331
+ // @ts-ignore this.xcodebuild must be defined
332
+ await this.xcodebuild.start(true);
333
+ if (!buildOnly) {
334
+ let status = await this.waitForStart(timer);
335
+ resolve(status);
336
+ }
337
+ }
338
+ catch (err) {
339
+ let msg = `Unable to start WebDriverAgent: ${err}`;
340
+ this.log.error(msg);
341
+ reject(new Error(msg));
342
+ }
343
+ })();
344
+ });
345
+ }
346
+ async waitForStart(timer) {
347
+ // try to connect once every 0.5 seconds, until `launchTimeout` is up
348
+ this.log.debug(`Waiting up to ${this.launchTimeout}ms for WebDriverAgent to start`);
349
+ let currentStatus = null;
288
350
  try {
289
- currentStatus = await this.noSessionProxy.command('/status', 'GET');
290
- if (currentStatus && currentStatus.ios && currentStatus.ios.ip) {
291
- this.agentUrl = currentStatus.ios.ip;
292
- }
293
- this.log.debug(`WebDriverAgent information:`);
294
- this.log.debug(JSON.stringify(currentStatus, null, 2));
295
- } catch (err) {
296
- throw new Error(`Unable to connect to running WebDriverAgent: ${err.message}`);
297
- } finally {
298
- this.noSessionProxy.timeout = proxyTimeout;
351
+ let retries = parseInt(`${this.launchTimeout / 500}`, 10);
352
+ await (0, asyncbox_1.retryInterval)(retries, 1000, async () => {
353
+ // @ts-ignore processExited is a custom property
354
+ if (this.xcodebuild.processExited) {
355
+ // there has been an error elsewhere and we need to short-circuit
356
+ return;
357
+ }
358
+ const proxyTimeout = this.noSessionProxy.timeout;
359
+ this.noSessionProxy.timeout = 1000;
360
+ try {
361
+ currentStatus = await this.noSessionProxy.command('/status', 'GET');
362
+ if (currentStatus && currentStatus.ios && currentStatus.ios.ip) {
363
+ this.agentUrl = currentStatus.ios.ip;
364
+ }
365
+ this.log.debug(`WebDriverAgent information:`);
366
+ this.log.debug(JSON.stringify(currentStatus, null, 2));
367
+ }
368
+ catch (err) {
369
+ throw new Error(`Unable to connect to running WebDriverAgent: ${err.message}`);
370
+ }
371
+ finally {
372
+ this.noSessionProxy.timeout = proxyTimeout;
373
+ }
374
+ });
375
+ // @ts-ignore processExited is a custom property
376
+ if (this.xcodebuild.processExited) {
377
+ // there has been an error elsewhere and we need to short-circuit
378
+ return currentStatus;
379
+ }
380
+ this.log.debug(`WebDriverAgent successfully started after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
381
+ }
382
+ catch (err) {
383
+ // at this point, if we have not had any errors from xcode itself (reported
384
+ // elsewhere), we can let this go through and try to create the session
385
+ this.log.debug(err.message);
386
+ this.log.warn(`Getting status of WebDriverAgent on device timed out. Continuing`);
299
387
  }
300
- });
301
- if (this.xcodebuild.processExited) {
302
388
  return currentStatus;
303
- }
304
- this.log.debug(`WebDriverAgent successfully started after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
305
- } catch (err) {
306
- this.log.debug(err.message);
307
- this.log.warn(`Getting status of WebDriverAgent on device timed out. Continuing`);
308
389
  }
309
- return currentStatus;
310
- }
311
- async quit() {
312
- await (0, _utils.killProcess)('xcodebuild', this.xcodebuild);
313
- }
390
+ async quit() {
391
+ await (0, utils_1.killProcess)('xcodebuild', this.xcodebuild);
392
+ }
314
393
  }
315
394
  exports.XcodeBuild = XcodeBuild;
316
- var _default = XcodeBuild;
317
- exports.default = _default;
318
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYXN5bmNib3giLCJyZXF1aXJlIiwiX3RlZW5fcHJvY2VzcyIsIl9zdXBwb3J0IiwiX2xvZ2dlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfYmx1ZWJpcmQiLCJfdXRpbHMiLCJfbG9kYXNoIiwiX3BhdGgiLCJfb3MiLCJfY29uc3RhbnRzIiwiREVGQVVMVF9TSUdOSU5HX0lEIiwiUFJFQlVJTERfREVMQVkiLCJSVU5ORVJfU0NIRU1FX0lPUyIsIkxJQl9TQ0hFTUVfSU9TIiwiRVJST1JfV1JJVElOR19BVFRBQ0hNRU5UIiwiRVJST1JfQ09QWUlOR19BVFRBQ0hNRU5UIiwiSUdOT1JFRF9FUlJPUlMiLCJSVU5ORVJfU0NIRU1FX1RWIiwiTElCX1NDSEVNRV9UViIsInhjb2RlTG9nIiwibG9nZ2VyIiwiZ2V0TG9nZ2VyIiwiWGNvZGVCdWlsZCIsImNvbnN0cnVjdG9yIiwieGNvZGVWZXJzaW9uIiwiZGV2aWNlIiwiYXJncyIsImxvZyIsImRlZmF1bHRMb2dnZXIiLCJyZWFsRGV2aWNlIiwiYWdlbnRQYXRoIiwiYm9vdHN0cmFwUGF0aCIsInBsYXRmb3JtVmVyc2lvbiIsInBsYXRmb3JtTmFtZSIsImlvc1Nka1ZlcnNpb24iLCJzaG93WGNvZGVMb2ciLCJ4Y29kZUNvbmZpZ0ZpbGUiLCJ4Y29kZU9yZ0lkIiwieGNvZGVTaWduaW5nSWQiLCJrZXljaGFpblBhdGgiLCJrZXljaGFpblBhc3N3b3JkIiwicHJlYnVpbGRXREEiLCJ1c2VQcmVidWlsdFdEQSIsInVzZVNpbXBsZUJ1aWxkVGVzdCIsInVzZVhjdGVzdHJ1bkZpbGUiLCJsYXVuY2hUaW1lb3V0Iiwid2RhUmVtb3RlUG9ydCIsInVwZGF0ZWRXREFCdW5kbGVJZCIsImRlcml2ZWREYXRhUGF0aCIsIm1qcGVnU2VydmVyUG9ydCIsInByZWJ1aWxkRGVsYXkiLCJfIiwiaXNOdW1iZXIiLCJhbGxvd1Byb3Zpc2lvbmluZ0RldmljZVJlZ2lzdHJhdGlvbiIsInJlc3VsdEJ1bmRsZVBhdGgiLCJyZXN1bHRCdW5kbGVWZXJzaW9uIiwiaW5pdCIsIm5vU2Vzc2lvblByb3h5IiwiZGV2aXZlSW5mbyIsImlzUmVhbERldmljZSIsInVkaWQiLCJ4Y3Rlc3RydW5GaWxlUGF0aCIsInNldFhjdGVzdHJ1bkZpbGUiLCJyZXNldFByb2plY3RGaWxlIiwidXBkYXRlUHJvamVjdEZpbGUiLCJyZXRyaWV2ZURlcml2ZWREYXRhUGF0aCIsIl9kZXJpdmVkRGF0YVBhdGhQcm9taXNlIiwic3Rkb3V0IiwiZXhlYyIsImVyciIsIndhcm4iLCJtZXNzYWdlIiwicGF0dGVybiIsIm1hdGNoIiwidHJ1bmNhdGUiLCJsZW5ndGgiLCJkZWJ1ZyIsInBhdGgiLCJkaXJuYW1lIiwibm9ybWFsaXplIiwicmVzZXQiLCJwcmVidWlsZCIsInN0YXJ0IiwieGNvZGVidWlsZCIsIkIiLCJkZWxheSIsImNsZWFuUHJvamVjdCIsImxpYlNjaGVtZSIsImlzVHZPUyIsInJ1bm5lclNjaGVtZSIsInNjaGVtZSIsImdldENvbW1hbmQiLCJidWlsZE9ubHkiLCJjbWQiLCJidWlsZENtZCIsInRlc3RDbWQiLCJwdXNoIiwidmVyc2lvbk1hdGNoIiwiUmVnRXhwIiwicHJvY2VzcyIsImVudiIsIkFQUElVTV9YQ1VJVEVTVF9UUkVBVF9XQVJOSU5HU19BU19FUlJPUlMiLCJjcmVhdGVTdWJQcm9jZXNzIiwic2V0UmVhbERldmljZVNlY3VyaXR5IiwiZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUiLCJqb2luIiwiT2JqZWN0IiwiYXNzaWduIiwiVVNFX1BPUlQiLCJXREFfUFJPRFVDVF9CVU5ETEVfSURFTlRJRklFUiIsIldEQV9SVU5ORVJfQlVORExFX0lEIiwiTUpQRUdfU0VSVkVSX1BPUlQiLCJ1cGdyYWRlVGltZXN0YW1wIiwiZ2V0V0RBVXBncmFkZVRpbWVzdGFtcCIsIlVQR1JBREVfVElNRVNUQU1QIiwiU3ViUHJvY2VzcyIsImN3ZCIsImRldGFjaGVkIiwic3RkaW8iLCJsb2dYY29kZU91dHB1dCIsImxvZ01zZyIsImlzQm9vbGVhbiIsIm9uIiwic3RkZXJyIiwib3V0IiwiaW5jbHVkZXMiLCJsb2dMb2NhdGlvbiIsImZpcnN0IiwicmVtb3ZlIiwidHJpbSIsInNwbGl0IiwidiIsInN0YXJ0c1dpdGgiLCJzZXAiLCJpZ25vcmVFcnJvciIsInNvbWUiLCJ4IiwiX3dkYV9lcnJvcl9vY2N1cnJlZCIsImxpbmUiLCJFT0wiLCJlcnJvciIsIl93ZGFfZXJyb3JfbWVzc2FnZSIsInJlc29sdmUiLCJyZWplY3QiLCJjb2RlIiwic2lnbmFsIiwiZGF0YSIsImZzIiwicmVhZEZpbGUiLCJwcm9jZXNzRXhpdGVkIiwiRXJyb3IiLCJ0aW1lciIsInRpbWluZyIsIlRpbWVyIiwic3RhdHVzIiwid2FpdEZvclN0YXJ0IiwibXNnIiwiY3VycmVudFN0YXR1cyIsInJldHJpZXMiLCJwYXJzZUludCIsInJldHJ5SW50ZXJ2YWwiLCJwcm94eVRpbWVvdXQiLCJ0aW1lb3V0IiwiY29tbWFuZCIsImlvcyIsImlwIiwiYWdlbnRVcmwiLCJKU09OIiwic3RyaW5naWZ5IiwiZ2V0RHVyYXRpb24iLCJhc01pbGxpU2Vjb25kcyIsInRvRml4ZWQiLCJxdWl0Iiwia2lsbFByb2Nlc3MiLCJleHBvcnRzIiwiX2RlZmF1bHQiLCJkZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3hjb2RlYnVpbGQuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmV0cnlJbnRlcnZhbCB9IGZyb20gJ2FzeW5jYm94JztcbmltcG9ydCB7IFN1YlByb2Nlc3MsIGV4ZWMgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IHsgZnMsIGxvZ2dlciwgdGltaW5nIH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCBkZWZhdWx0TG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCB7XG4gIHNldFJlYWxEZXZpY2VTZWN1cml0eSwgZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUsIHNldFhjdGVzdHJ1bkZpbGUsXG4gIHVwZGF0ZVByb2plY3RGaWxlLCByZXNldFByb2plY3RGaWxlLCBraWxsUHJvY2VzcyxcbiAgZ2V0V0RBVXBncmFkZVRpbWVzdGFtcCwgaXNUdk9TIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBFT0wgfSBmcm9tICdvcyc7XG5pbXBvcnQgeyBXREFfUlVOTkVSX0JVTkRMRV9JRCB9IGZyb20gJy4vY29uc3RhbnRzJztcblxuXG5jb25zdCBERUZBVUxUX1NJR05JTkdfSUQgPSAnaVBob25lIERldmVsb3Blcic7XG5jb25zdCBQUkVCVUlMRF9ERUxBWSA9IDA7XG5jb25zdCBSVU5ORVJfU0NIRU1FX0lPUyA9ICdXZWJEcml2ZXJBZ2VudFJ1bm5lcic7XG5jb25zdCBMSUJfU0NIRU1FX0lPUyA9ICdXZWJEcml2ZXJBZ2VudExpYic7XG5cbmNvbnN0IEVSUk9SX1dSSVRJTkdfQVRUQUNITUVOVCA9ICdFcnJvciB3cml0aW5nIGF0dGFjaG1lbnQgZGF0YSB0byBmaWxlJztcbmNvbnN0IEVSUk9SX0NPUFlJTkdfQVRUQUNITUVOVCA9ICdFcnJvciBjb3B5aW5nIHRlc3RpbmcgYXR0YWNobWVudCc7XG5jb25zdCBJR05PUkVEX0VSUk9SUyA9IFtcbiAgRVJST1JfV1JJVElOR19BVFRBQ0hNRU5ULFxuICBFUlJPUl9DT1BZSU5HX0FUVEFDSE1FTlQsXG4gICdGYWlsZWQgdG8gcmVtb3ZlIHNjcmVlbnNob3QgYXQgcGF0aCcsXG5dO1xuXG5jb25zdCBSVU5ORVJfU0NIRU1FX1RWID0gJ1dlYkRyaXZlckFnZW50UnVubmVyX3R2T1MnO1xuY29uc3QgTElCX1NDSEVNRV9UViA9ICdXZWJEcml2ZXJBZ2VudExpYl90dk9TJztcblxuY29uc3QgeGNvZGVMb2cgPSBsb2dnZXIuZ2V0TG9nZ2VyKCdYY29kZScpO1xuXG5cbmNsYXNzIFhjb2RlQnVpbGQge1xuICBjb25zdHJ1Y3RvciAoeGNvZGVWZXJzaW9uLCBkZXZpY2UsIGFyZ3MgPSB7fSwgbG9nID0gbnVsbCkge1xuICAgIHRoaXMueGNvZGVWZXJzaW9uID0geGNvZGVWZXJzaW9uO1xuXG4gICAgdGhpcy5kZXZpY2UgPSBkZXZpY2U7XG4gICAgdGhpcy5sb2cgPSBsb2cgPz8gZGVmYXVsdExvZ2dlcjtcblxuICAgIHRoaXMucmVhbERldmljZSA9IGFyZ3MucmVhbERldmljZTtcblxuICAgIHRoaXMuYWdlbnRQYXRoID0gYXJncy5hZ2VudFBhdGg7XG4gICAgdGhpcy5ib290c3RyYXBQYXRoID0gYXJncy5ib290c3RyYXBQYXRoO1xuXG4gICAgdGhpcy5wbGF0Zm9ybVZlcnNpb24gPSBhcmdzLnBsYXRmb3JtVmVyc2lvbjtcbiAgICB0aGlzLnBsYXRmb3JtTmFtZSA9IGFyZ3MucGxhdGZvcm1OYW1lO1xuICAgIHRoaXMuaW9zU2RrVmVyc2lvbiA9IGFyZ3MuaW9zU2RrVmVyc2lvbjtcblxuICAgIHRoaXMuc2hvd1hjb2RlTG9nID0gYXJncy5zaG93WGNvZGVMb2c7XG5cbiAgICB0aGlzLnhjb2RlQ29uZmlnRmlsZSA9IGFyZ3MueGNvZGVDb25maWdGaWxlO1xuICAgIHRoaXMueGNvZGVPcmdJZCA9IGFyZ3MueGNvZGVPcmdJZDtcbiAgICB0aGlzLnhjb2RlU2lnbmluZ0lkID0gYXJncy54Y29kZVNpZ25pbmdJZCB8fCBERUZBVUxUX1NJR05JTkdfSUQ7XG4gICAgdGhpcy5rZXljaGFpblBhdGggPSBhcmdzLmtleWNoYWluUGF0aDtcbiAgICB0aGlzLmtleWNoYWluUGFzc3dvcmQgPSBhcmdzLmtleWNoYWluUGFzc3dvcmQ7XG5cbiAgICB0aGlzLnByZWJ1aWxkV0RBID0gYXJncy5wcmVidWlsZFdEQTtcbiAgICB0aGlzLnVzZVByZWJ1aWx0V0RBID0gYXJncy51c2VQcmVidWlsdFdEQTtcbiAgICB0aGlzLnVzZVNpbXBsZUJ1aWxkVGVzdCA9IGFyZ3MudXNlU2ltcGxlQnVpbGRUZXN0O1xuXG4gICAgdGhpcy51c2VYY3Rlc3RydW5GaWxlID0gYXJncy51c2VYY3Rlc3RydW5GaWxlO1xuXG4gICAgdGhpcy5sYXVuY2hUaW1lb3V0ID0gYXJncy5sYXVuY2hUaW1lb3V0O1xuXG4gICAgdGhpcy53ZGFSZW1vdGVQb3J0ID0gYXJncy53ZGFSZW1vdGVQb3J0O1xuXG4gICAgdGhpcy51cGRhdGVkV0RBQnVuZGxlSWQgPSBhcmdzLnVwZGF0ZWRXREFCdW5kbGVJZDtcbiAgICB0aGlzLmRlcml2ZWREYXRhUGF0aCA9IGFyZ3MuZGVyaXZlZERhdGFQYXRoO1xuXG4gICAgdGhpcy5tanBlZ1NlcnZlclBvcnQgPSBhcmdzLm1qcGVnU2VydmVyUG9ydDtcblxuICAgIHRoaXMucHJlYnVpbGREZWxheSA9IF8uaXNOdW1iZXIoYXJncy5wcmVidWlsZERlbGF5KSA/IGFyZ3MucHJlYnVpbGREZWxheSA6IFBSRUJVSUxEX0RFTEFZO1xuXG4gICAgdGhpcy5hbGxvd1Byb3Zpc2lvbmluZ0RldmljZVJlZ2lzdHJhdGlvbiA9IGFyZ3MuYWxsb3dQcm92aXNpb25pbmdEZXZpY2VSZWdpc3RyYXRpb247XG5cbiAgICB0aGlzLnJlc3VsdEJ1bmRsZVBhdGggPSBhcmdzLnJlc3VsdEJ1bmRsZVBhdGg7XG4gICAgdGhpcy5yZXN1bHRCdW5kbGVWZXJzaW9uID0gYXJncy5yZXN1bHRCdW5kbGVWZXJzaW9uO1xuICB9XG5cbiAgYXN5bmMgaW5pdCAobm9TZXNzaW9uUHJveHkpIHtcbiAgICB0aGlzLm5vU2Vzc2lvblByb3h5ID0gbm9TZXNzaW9uUHJveHk7XG5cbiAgICBpZiAodGhpcy51c2VYY3Rlc3RydW5GaWxlKSB7XG4gICAgICBjb25zdCBkZXZpdmVJbmZvID0ge1xuICAgICAgICBpc1JlYWxEZXZpY2U6IHRoaXMucmVhbERldmljZSxcbiAgICAgICAgdWRpZDogdGhpcy5kZXZpY2UudWRpZCxcbiAgICAgICAgcGxhdGZvcm1WZXJzaW9uOiB0aGlzLnBsYXRmb3JtVmVyc2lvbixcbiAgICAgICAgcGxhdGZvcm1OYW1lOiB0aGlzLnBsYXRmb3JtTmFtZVxuICAgICAgfTtcbiAgICAgIHRoaXMueGN0ZXN0cnVuRmlsZVBhdGggPSBhd2FpdCBzZXRYY3Rlc3RydW5GaWxlKGRldml2ZUluZm8sIHRoaXMuaW9zU2RrVmVyc2lvbiwgdGhpcy5ib290c3RyYXBQYXRoLCB0aGlzLndkYVJlbW90ZVBvcnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGlmIG5lY2Vzc2FyeSwgdXBkYXRlIHRoZSBidW5kbGVJZCB0byB1c2VyJ3Mgc3BlY2lmaWNhdGlvblxuICAgIGlmICh0aGlzLnJlYWxEZXZpY2UpIHtcbiAgICAgIC8vIEluIGNhc2UgdGhlIHByb2plY3Qgc3RpbGwgaGFzIHRoZSB1c2VyIHNwZWNpZmljIGJ1bmRsZSBJRCwgcmVzZXQgdGhlIHByb2plY3QgZmlsZSBmaXJzdC5cbiAgICAgIC8vIC0gV2UgZG8gdGhpcyByZXNldCBldmVuIGlmIHVwZGF0ZWRXREFCdW5kbGVJZCBpcyBub3Qgc3BlY2lmaWVkLFxuICAgICAgLy8gICBzaW5jZSB0aGUgcHJldmlvdXMgdXBkYXRlZFdEQUJ1bmRsZUlkIHRlc3QgaGFzIGdlbmVyYXRlZCB0aGUgdXNlciBzcGVjaWZpYyBidW5kbGUgSUQgcHJvamVjdCBmaWxlLlxuICAgICAgLy8gLSBXZSBkb24ndCBjYWxsIHJlc2V0UHJvamVjdEZpbGUgZm9yIHNpbXVsYXRvcixcbiAgICAgIC8vICAgc2luY2Ugc2ltdWxhdG9yIHRlc3QgcnVuIHdpbGwgd29yayB3aXRoIGFueSB1c2VyIHNwZWNpZmljIGJ1bmRsZSBJRC5cbiAgICAgIGF3YWl0IHJlc2V0UHJvamVjdEZpbGUodGhpcy5hZ2VudFBhdGgpO1xuICAgICAgaWYgKHRoaXMudXBkYXRlZFdEQUJ1bmRsZUlkKSB7XG4gICAgICAgIGF3YWl0IHVwZGF0ZVByb2plY3RGaWxlKHRoaXMuYWdlbnRQYXRoLCB0aGlzLnVwZGF0ZWRXREFCdW5kbGVJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcmV0cmlldmVEZXJpdmVkRGF0YVBhdGggKCkge1xuICAgIGlmICh0aGlzLmRlcml2ZWREYXRhUGF0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVyaXZlZERhdGFQYXRoO1xuICAgIH1cblxuICAgIC8vIGF2b2lkIHJhY2UgY29uZGl0aW9uc1xuICAgIGlmICh0aGlzLl9kZXJpdmVkRGF0YVBhdGhQcm9taXNlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZGVyaXZlZERhdGFQYXRoUHJvbWlzZTtcbiAgICB9XG5cbiAgICB0aGlzLl9kZXJpdmVkRGF0YVBhdGhQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBzdGRvdXQ7XG4gICAgICB0cnkge1xuICAgICAgICAoe3N0ZG91dH0gPSBhd2FpdCBleGVjKCd4Y29kZWJ1aWxkJywgWyctcHJvamVjdCcsIHRoaXMuYWdlbnRQYXRoLCAnLXNob3dCdWlsZFNldHRpbmdzJ10pKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aGlzLmxvZy53YXJuKGBDYW5ub3QgcmV0cmlldmUgV0RBIGJ1aWxkIHNldHRpbmdzLiBPcmlnaW5hbCBlcnJvcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXR0ZXJuID0gL15cXHMqQlVJTERfRElSXFxzKz1cXHMrKFxcLy4qKS9tO1xuICAgICAgY29uc3QgbWF0Y2ggPSBwYXR0ZXJuLmV4ZWMoc3Rkb3V0KTtcbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgdGhpcy5sb2cud2FybihgQ2Fubm90IHBhcnNlIFdEQSBidWlsZCBkaXIgZnJvbSAke18udHJ1bmNhdGUoc3Rkb3V0LCB7bGVuZ3RoOiAzMDB9KX1gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cuZGVidWcoYFBhcnNlZCBCVUlMRF9ESVIgY29uZmlndXJhdGlvbiB2YWx1ZTogJyR7bWF0Y2hbMV19J2ApO1xuICAgICAgLy8gRGVyaXZlZCBkYXRhIHJvb3QgaXMgdHdvIGxldmVscyBoaWdoZXIgb3ZlciB0aGUgYnVpbGQgZGlyXG4gICAgICB0aGlzLmRlcml2ZWREYXRhUGF0aCA9IHBhdGguZGlybmFtZShwYXRoLmRpcm5hbWUocGF0aC5ub3JtYWxpemUobWF0Y2hbMV0pKSk7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgR290IGRlcml2ZWQgZGF0YSByb290OiAnJHt0aGlzLmRlcml2ZWREYXRhUGF0aH0nYCk7XG4gICAgICByZXR1cm4gdGhpcy5kZXJpdmVkRGF0YVBhdGg7XG4gICAgfSkoKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fZGVyaXZlZERhdGFQYXRoUHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIHJlc2V0ICgpIHtcbiAgICAvLyBpZiBuZWNlc3NhcnksIHJlc2V0IHRoZSBidW5kbGVJZCB0byBvcmlnaW5hbCB2YWx1ZVxuICAgIGlmICh0aGlzLnJlYWxEZXZpY2UgJiYgdGhpcy51cGRhdGVkV0RBQnVuZGxlSWQpIHtcbiAgICAgIGF3YWl0IHJlc2V0UHJvamVjdEZpbGUodGhpcy5hZ2VudFBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHByZWJ1aWxkICgpIHtcbiAgICAvLyBmaXJzdCBkbyBhIGJ1aWxkIHBoYXNlXG4gICAgdGhpcy5sb2cuZGVidWcoJ1ByZS1idWlsZGluZyBXREEgYmVmb3JlIGxhdW5jaGluZyB0ZXN0Jyk7XG4gICAgdGhpcy51c2VQcmVidWlsdFdEQSA9IHRydWU7XG4gICAgYXdhaXQgdGhpcy5zdGFydCh0cnVlKTtcblxuICAgIHRoaXMueGNvZGVidWlsZCA9IG51bGw7XG5cbiAgICAvLyBwYXVzZSBhIG1vbWVudFxuICAgIGF3YWl0IEIuZGVsYXkodGhpcy5wcmVidWlsZERlbGF5KTtcbiAgfVxuXG4gIGFzeW5jIGNsZWFuUHJvamVjdCAoKSB7XG4gICAgY29uc3QgbGliU2NoZW1lID0gaXNUdk9TKHRoaXMucGxhdGZvcm1OYW1lKSA/IExJQl9TQ0hFTUVfVFYgOiBMSUJfU0NIRU1FX0lPUztcbiAgICBjb25zdCBydW5uZXJTY2hlbWUgPSBpc1R2T1ModGhpcy5wbGF0Zm9ybU5hbWUpID8gUlVOTkVSX1NDSEVNRV9UViA6IFJVTk5FUl9TQ0hFTUVfSU9TO1xuXG4gICAgZm9yIChjb25zdCBzY2hlbWUgb2YgW2xpYlNjaGVtZSwgcnVubmVyU2NoZW1lXSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYENsZWFuaW5nIHRoZSBwcm9qZWN0IHNjaGVtZSAnJHtzY2hlbWV9JyB0byBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vIGxlZnRvdmVycyBmcm9tIHByZXZpb3VzIGluc3RhbGxzYCk7XG4gICAgICBhd2FpdCBleGVjKCd4Y29kZWJ1aWxkJywgW1xuICAgICAgICAnY2xlYW4nLFxuICAgICAgICAnLXByb2plY3QnLCB0aGlzLmFnZW50UGF0aCxcbiAgICAgICAgJy1zY2hlbWUnLCBzY2hlbWUsXG4gICAgICBdKTtcbiAgICB9XG4gIH1cblxuICBnZXRDb21tYW5kIChidWlsZE9ubHkgPSBmYWxzZSkge1xuICAgIGxldCBjbWQgPSAneGNvZGVidWlsZCc7XG4gICAgbGV0IGFyZ3M7XG5cbiAgICAvLyBmaWd1cmUgb3V0IHRoZSB0YXJnZXRzIGZvciB4Y29kZWJ1aWxkXG4gICAgY29uc3QgW2J1aWxkQ21kLCB0ZXN0Q21kXSA9IHRoaXMudXNlU2ltcGxlQnVpbGRUZXN0ID8gWydidWlsZCcsICd0ZXN0J10gOiBbJ2J1aWxkLWZvci10ZXN0aW5nJywgJ3Rlc3Qtd2l0aG91dC1idWlsZGluZyddO1xuICAgIGlmIChidWlsZE9ubHkpIHtcbiAgICAgIGFyZ3MgPSBbYnVpbGRDbWRdO1xuICAgIH0gZWxzZSBpZiAodGhpcy51c2VQcmVidWlsdFdEQSB8fCB0aGlzLnVzZVhjdGVzdHJ1bkZpbGUpIHtcbiAgICAgIGFyZ3MgPSBbdGVzdENtZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyZ3MgPSBbYnVpbGRDbWQsIHRlc3RDbWRdO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmFsbG93UHJvdmlzaW9uaW5nRGV2aWNlUmVnaXN0cmF0aW9uKSB7XG4gICAgICAvLyBUbyAtYWxsb3dQcm92aXNpb25pbmdEZXZpY2VSZWdpc3RyYXRpb24gZmxhZyB0YWtlcyBlZmZlY3QsIC1hbGxvd1Byb3Zpc2lvbmluZ1VwZGF0ZXMgbmVlZHMgdG8gYmUgcGFzc2VkIGFzIHdlbGwuXG4gICAgICBhcmdzLnB1c2goJy1hbGxvd1Byb3Zpc2lvbmluZ1VwZGF0ZXMnLCAnLWFsbG93UHJvdmlzaW9uaW5nRGV2aWNlUmVnaXN0cmF0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVzdWx0QnVuZGxlUGF0aCkge1xuICAgICAgYXJncy5wdXNoKCctcmVzdWx0QnVuZGxlUGF0aCcsIHRoaXMucmVzdWx0QnVuZGxlUGF0aCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVzdWx0QnVuZGxlVmVyc2lvbikge1xuICAgICAgYXJncy5wdXNoKCctcmVzdWx0QnVuZGxlVmVyc2lvbicsIHRoaXMucmVzdWx0QnVuZGxlVmVyc2lvbik7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudXNlWGN0ZXN0cnVuRmlsZSkge1xuICAgICAgYXJncy5wdXNoKCcteGN0ZXN0cnVuJywgdGhpcy54Y3Rlc3RydW5GaWxlUGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJ1bm5lclNjaGVtZSA9IGlzVHZPUyh0aGlzLnBsYXRmb3JtTmFtZSkgPyBSVU5ORVJfU0NIRU1FX1RWIDogUlVOTkVSX1NDSEVNRV9JT1M7XG4gICAgICBhcmdzLnB1c2goJy1wcm9qZWN0JywgdGhpcy5hZ2VudFBhdGgsICctc2NoZW1lJywgcnVubmVyU2NoZW1lKTtcbiAgICAgIGlmICh0aGlzLmRlcml2ZWREYXRhUGF0aCkge1xuICAgICAgICBhcmdzLnB1c2goJy1kZXJpdmVkRGF0YVBhdGgnLCB0aGlzLmRlcml2ZWREYXRhUGF0aCk7XG4gICAgICB9XG4gICAgfVxuICAgIGFyZ3MucHVzaCgnLWRlc3RpbmF0aW9uJywgYGlkPSR7dGhpcy5kZXZpY2UudWRpZH1gKTtcblxuICAgIGNvbnN0IHZlcnNpb25NYXRjaCA9IG5ldyBSZWdFeHAoL14oXFxkKylcXC4oXFxkKykvKS5leGVjKHRoaXMucGxhdGZvcm1WZXJzaW9uKTtcbiAgICBpZiAodmVyc2lvbk1hdGNoKSB7XG4gICAgICBhcmdzLnB1c2goXG4gICAgICAgIGAke2lzVHZPUyh0aGlzLnBsYXRmb3JtTmFtZSkgPyAnVFYnIDogJ0lQSE9ORSd9T1NfREVQTE9ZTUVOVF9UQVJHRVQ9JHt2ZXJzaW9uTWF0Y2hbMV19LiR7dmVyc2lvbk1hdGNoWzJdfWBcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLndhcm4oYENhbm5vdCBwYXJzZSBtYWpvciBhbmQgbWlub3IgdmVyc2lvbiBudW1iZXJzIGZyb20gcGxhdGZvcm1WZXJzaW9uIFwiJHt0aGlzLnBsYXRmb3JtVmVyc2lvbn1cIi4gYCArXG4gICAgICAgICdXaWxsIGJ1aWxkIGZvciB0aGUgZGVmYXVsdCBwbGF0Zm9ybSBpbnN0ZWFkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVhbERldmljZSAmJiB0aGlzLnhjb2RlQ29uZmlnRmlsZSkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFVzaW5nIFhjb2RlIGNvbmZpZ3VyYXRpb24gZmlsZTogJyR7dGhpcy54Y29kZUNvbmZpZ0ZpbGV9J2ApO1xuICAgICAgYXJncy5wdXNoKCcteGNjb25maWcnLCB0aGlzLnhjb2RlQ29uZmlnRmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKCFwcm9jZXNzLmVudi5BUFBJVU1fWENVSVRFU1RfVFJFQVRfV0FSTklOR1NfQVNfRVJST1JTKSB7XG4gICAgICAvLyBUaGlzIHNvbWV0aW1lcyBoZWxwcyB0byBzdXJ2aXZlIFhjb2RlIHVwZGF0ZXNcbiAgICAgIGFyZ3MucHVzaCgnR0NDX1RSRUFUX1dBUk5JTkdTX0FTX0VSUk9SUz0wJyk7XG4gICAgfVxuXG4gICAgLy8gQmVsb3cgb3B0aW9uIHNsaWdodGx5IHJlZHVjZXMgYnVpbGQgdGltZSBpbiBkZWJ1ZyBidWlsZFxuICAgIC8vIHdpdGggcHJldmVudGluZyB0byBnZW5lcmF0ZSBgL0luZGV4L0RhdGFTdG9yZWAgd2hpY2ggaXMgdXNlZCBieSBkZXZlbG9wbWVudFxuICAgIGFyZ3MucHVzaCgnQ09NUElMRVJfSU5ERVhfU1RPUkVfRU5BQkxFPU5PJyk7XG5cbiAgICByZXR1cm4ge2NtZCwgYXJnc307XG4gIH1cblxuICBhc3luYyBjcmVhdGVTdWJQcm9jZXNzIChidWlsZE9ubHkgPSBmYWxzZSkge1xuICAgIGlmICghdGhpcy51c2VYY3Rlc3RydW5GaWxlICYmIHRoaXMucmVhbERldmljZSkge1xuICAgICAgaWYgKHRoaXMua2V5Y2hhaW5QYXRoICYmIHRoaXMua2V5Y2hhaW5QYXNzd29yZCkge1xuICAgICAgICBhd2FpdCBzZXRSZWFsRGV2aWNlU2VjdXJpdHkodGhpcy5rZXljaGFpblBhdGgsIHRoaXMua2V5Y2hhaW5QYXNzd29yZCk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy54Y29kZU9yZ0lkICYmIHRoaXMueGNvZGVTaWduaW5nSWQgJiYgIXRoaXMueGNvZGVDb25maWdGaWxlKSB7XG4gICAgICAgIHRoaXMueGNvZGVDb25maWdGaWxlID0gYXdhaXQgZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUodGhpcy54Y29kZU9yZ0lkLCB0aGlzLnhjb2RlU2lnbmluZ0lkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB7Y21kLCBhcmdzfSA9IHRoaXMuZ2V0Q29tbWFuZChidWlsZE9ubHkpO1xuICAgIHRoaXMubG9nLmRlYnVnKGBCZWdpbm5pbmcgJHtidWlsZE9ubHkgPyAnYnVpbGQnIDogJ3Rlc3QnfSB3aXRoIGNvbW1hbmQgJyR7Y21kfSAke2FyZ3Muam9pbignICcpfScgYCArXG4gICAgICBgaW4gZGlyZWN0b3J5ICcke3RoaXMuYm9vdHN0cmFwUGF0aH0nYCk7XG4gICAgY29uc3QgZW52ID0gT2JqZWN0LmFzc2lnbih7fSwgcHJvY2Vzcy5lbnYsIHtcbiAgICAgIFVTRV9QT1JUOiB0aGlzLndkYVJlbW90ZVBvcnQsXG4gICAgICBXREFfUFJPRFVDVF9CVU5ETEVfSURFTlRJRklFUjogdGhpcy51cGRhdGVkV0RBQnVuZGxlSWQgfHwgV0RBX1JVTk5FUl9CVU5ETEVfSUQsXG4gICAgfSk7XG4gICAgaWYgKHRoaXMubWpwZWdTZXJ2ZXJQb3J0KSB7XG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYXBwaXVtL1dlYkRyaXZlckFnZW50L3B1bGwvMTA1XG4gICAgICBlbnYuTUpQRUdfU0VSVkVSX1BPUlQgPSB0aGlzLm1qcGVnU2VydmVyUG9ydDtcbiAgICB9XG4gICAgY29uc3QgdXBncmFkZVRpbWVzdGFtcCA9IGF3YWl0IGdldFdEQVVwZ3JhZGVUaW1lc3RhbXAodGhpcy5ib290c3RyYXBQYXRoKTtcbiAgICBpZiAodXBncmFkZVRpbWVzdGFtcCkge1xuICAgICAgZW52LlVQR1JBREVfVElNRVNUQU1QID0gdXBncmFkZVRpbWVzdGFtcDtcbiAgICB9XG4gICAgY29uc3QgeGNvZGVidWlsZCA9IG5ldyBTdWJQcm9jZXNzKGNtZCwgYXJncywge1xuICAgICAgY3dkOiB0aGlzLmJvb3RzdHJhcFBhdGgsXG4gICAgICBlbnYsXG4gICAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgICAgIHN0ZGlvOiBbJ2lnbm9yZScsICdwaXBlJywgJ3BpcGUnXSxcbiAgICB9KTtcblxuICAgIGxldCBsb2dYY29kZU91dHB1dCA9ICEhdGhpcy5zaG93WGNvZGVMb2c7XG4gICAgY29uc3QgbG9nTXNnID0gXy5pc0Jvb2xlYW4odGhpcy5zaG93WGNvZGVMb2cpXG4gICAgICA/IGBPdXRwdXQgZnJvbSB4Y29kZWJ1aWxkICR7dGhpcy5zaG93WGNvZGVMb2cgPyAnd2lsbCcgOiAnd2lsbCBub3QnfSBiZSBsb2dnZWRgXG4gICAgICA6ICdPdXRwdXQgZnJvbSB4Y29kZWJ1aWxkIHdpbGwgb25seSBiZSBsb2dnZWQgaWYgYW55IGVycm9ycyBhcmUgcHJlc2VudCB0aGVyZSc7XG4gICAgdGhpcy5sb2cuZGVidWcoYCR7bG9nTXNnfS4gVG8gY2hhbmdlIHRoaXMsIHVzZSAnc2hvd1hjb2RlTG9nJyBkZXNpcmVkIGNhcGFiaWxpdHlgKTtcbiAgICB4Y29kZWJ1aWxkLm9uKCdvdXRwdXQnLCAoc3Rkb3V0LCBzdGRlcnIpID0+IHtcbiAgICAgIGxldCBvdXQgPSBzdGRvdXQgfHwgc3RkZXJyO1xuICAgICAgLy8gd2Ugd2FudCB0byBwdWxsIG91dCB0aGUgbG9nIGZpbGUgdGhhdCBpcyBjcmVhdGVkLCBhbmQgaGlnaGxpZ2h0IGl0XG4gICAgICAvLyBmb3IgZGlhZ25vc3RpYyBwdXJwb3Nlc1xuICAgICAgaWYgKG91dC5pbmNsdWRlcygnV3JpdGluZyBkaWFnbm9zdGljIGxvZyBmb3IgdGVzdCBzZXNzaW9uIHRvJykpIHtcbiAgICAgICAgLy8gcHVsbCBvdXQgdGhlIGZpcnN0IGxpbmUgdGhhdCBiZWdpbnMgd2l0aCB0aGUgcGF0aCBzZXBhcmF0b3JcbiAgICAgICAgLy8gd2hpY2ggKnNob3VsZCogYmUgdGhlIGxpbmUgaW5kaWNhdGluZyB0aGUgbG9nIGZpbGUgZ2VuZXJhdGVkXG4gICAgICAgIHhjb2RlYnVpbGQubG9nTG9jYXRpb24gPSBfLmZpcnN0KF8ucmVtb3ZlKG91dC50cmltKCkuc3BsaXQoJ1xcbicpLCAodikgPT4gdi5zdGFydHNXaXRoKHBhdGguc2VwKSkpO1xuICAgICAgICB4Y29kZUxvZy5kZWJ1ZyhgTG9nIGZpbGUgZm9yIHhjb2RlYnVpbGQgdGVzdDogJHt4Y29kZWJ1aWxkLmxvZ0xvY2F0aW9ufWApO1xuICAgICAgfVxuXG4gICAgICAvLyBpZiB3ZSBoYXZlIGFuIGVycm9yIHdlIHdhbnQgdG8gb3V0cHV0IHRoZSBsb2dzXG4gICAgICAvLyBvdGhlcndpc2UgdGhlIGZhaWx1cmUgaXMgaW5zY3J1dGlibGVcbiAgICAgIC8vIGJ1dCBkbyBub3QgbG9nIHBlcm1pc3Npb24gZXJyb3JzIGZyb20gdHJ5aW5nIHRvIHdyaXRlIHRvIGF0dGFjaG1lbnRzIGZvbGRlclxuICAgICAgY29uc3QgaWdub3JlRXJyb3IgPSBJR05PUkVEX0VSUk9SUy5zb21lKCh4KSA9PiBvdXQuaW5jbHVkZXMoeCkpO1xuICAgICAgaWYgKHRoaXMuc2hvd1hjb2RlTG9nICE9PSBmYWxzZSAmJiBvdXQuaW5jbHVkZXMoJ0Vycm9yIERvbWFpbj0nKSAmJiAhaWdub3JlRXJyb3IpIHtcbiAgICAgICAgbG9nWGNvZGVPdXRwdXQgPSB0cnVlO1xuXG4gICAgICAgIC8vIHRlcnJpYmxlIGhhY2sgdG8gaGFuZGxlIGNhc2Ugd2hlcmUgeGNvZGUgcmV0dXJuIDAgYnV0IGlzIGZhaWxpbmdcbiAgICAgICAgeGNvZGVidWlsZC5fd2RhX2Vycm9yX29jY3VycmVkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZG8gbm90IGxvZyBwZXJtaXNzaW9uIGVycm9ycyBmcm9tIHRyeWluZyB0byB3cml0ZSB0byBhdHRhY2htZW50cyBmb2xkZXJcbiAgICAgIGlmIChsb2dYY29kZU91dHB1dCAmJiAhaWdub3JlRXJyb3IpIHtcbiAgICAgICAgZm9yIChjb25zdCBsaW5lIG9mIG91dC5zcGxpdChFT0wpKSB7XG4gICAgICAgICAgeGNvZGVMb2cuZXJyb3IobGluZSk7XG4gICAgICAgICAgaWYgKGxpbmUpIHtcbiAgICAgICAgICAgIHhjb2RlYnVpbGQuX3dkYV9lcnJvcl9tZXNzYWdlICs9IGAke0VPTH0ke2xpbmV9YDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB4Y29kZWJ1aWxkO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQgKGJ1aWxkT25seSA9IGZhbHNlKSB7XG4gICAgdGhpcy54Y29kZWJ1aWxkID0gYXdhaXQgdGhpcy5jcmVhdGVTdWJQcm9jZXNzKGJ1aWxkT25seSk7XG4gICAgLy8gU3RvcmUgeGNvZGVidWlsZCBtZXNzYWdlXG4gICAgdGhpcy54Y29kZWJ1aWxkLl93ZGFfZXJyb3JfbWVzc2FnZSA9ICcnO1xuXG4gICAgLy8gd3JhcCB0aGUgc3RhcnQgcHJvY2VkdXJlIGluIGEgcHJvbWlzZSBzbyB0aGF0IHdlIGNhbiBjYXRjaCwgYW5kIHJlcG9ydCxcbiAgICAvLyBhbnkgc3RhcnR1cCBlcnJvcnMgdGhhdCBhcmUgdGhyb3duIGFzIGV2ZW50c1xuICAgIHJldHVybiBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnhjb2RlYnVpbGQub24oJ2V4aXQnLCBhc3luYyAoY29kZSwgc2lnbmFsKSA9PiB7XG4gICAgICAgIHhjb2RlTG9nLmVycm9yKGB4Y29kZWJ1aWxkIGV4aXRlZCB3aXRoIGNvZGUgJyR7Y29kZX0nIGFuZCBzaWduYWwgJyR7c2lnbmFsfSdgKTtcbiAgICAgICAgLy8gcHJpbnQgb3V0IHRoZSB4Y29kZWJ1aWxkIGZpbGUgaWYgdXNlcnMgaGF2ZSBhc2tlZCBmb3IgaXRcbiAgICAgICAgaWYgKHRoaXMuc2hvd1hjb2RlTG9nICYmIHRoaXMueGNvZGVidWlsZC5sb2dMb2NhdGlvbikge1xuICAgICAgICAgIHhjb2RlTG9nLmVycm9yKGBDb250ZW50cyBvZiB4Y29kZWJ1aWxkIGxvZyBmaWxlICcke3RoaXMueGNvZGVidWlsZC5sb2dMb2NhdGlvbn0nOmApO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IGZzLnJlYWRGaWxlKHRoaXMueGNvZGVidWlsZC5sb2dMb2NhdGlvbiwgJ3V0ZjgnKTtcbiAgICAgICAgICAgIGZvciAobGV0IGxpbmUgb2YgZGF0YS5zcGxpdCgnXFxuJykpIHtcbiAgICAgICAgICAgICAgeGNvZGVMb2cuZXJyb3IobGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB4Y29kZUxvZy5lcnJvcihgVW5hYmxlIHRvIGFjY2VzcyB4Y29kZWJ1aWxkIGxvZyBmaWxlOiAnJHtlcnIubWVzc2FnZX0nYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMueGNvZGVidWlsZC5wcm9jZXNzRXhpdGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMueGNvZGVidWlsZC5fd2RhX2Vycm9yX29jY3VycmVkIHx8ICghc2lnbmFsICYmIGNvZGUgIT09IDApKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoYHhjb2RlYnVpbGQgZmFpbGVkIHdpdGggY29kZSAke2NvZGV9JHtFT0x9YCArXG4gICAgICAgICAgICBgeGNvZGVidWlsZCBlcnJvciBtZXNzYWdlOiR7RU9MfSR7dGhpcy54Y29kZWJ1aWxkLl93ZGFfZXJyb3JfbWVzc2FnZX1gKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW4gdGhlIGNhc2Ugb2YganVzdCBidWlsZGluZywgdGhlIHByb2Nlc3Mgd2lsbCBleGl0IGFuZCB0aGF0IGlzIG91ciBmaW5pc2hcbiAgICAgICAgaWYgKGJ1aWxkT25seSkge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gKGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0aW1lciA9IG5ldyB0aW1pbmcuVGltZXIoKS5zdGFydCgpO1xuICAgICAgICAgIGF3YWl0IHRoaXMueGNvZGVidWlsZC5zdGFydCh0cnVlKTtcbiAgICAgICAgICBpZiAoIWJ1aWxkT25seSkge1xuICAgICAgICAgICAgbGV0IHN0YXR1cyA9IGF3YWl0IHRoaXMud2FpdEZvclN0YXJ0KHRpbWVyKTtcbiAgICAgICAgICAgIHJlc29sdmUoc3RhdHVzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGxldCBtc2cgPSBgVW5hYmxlIHRvIHN0YXJ0IFdlYkRyaXZlckFnZW50OiAke2Vycn1gO1xuICAgICAgICAgIHRoaXMubG9nLmVycm9yKG1zZyk7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihtc2cpKTtcbiAgICAgICAgfVxuICAgICAgfSkoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JTdGFydCAodGltZXIpIHtcbiAgICAvLyB0cnkgdG8gY29ubmVjdCBvbmNlIGV2ZXJ5IDAuNSBzZWNvbmRzLCB1bnRpbCBgbGF1bmNoVGltZW91dGAgaXMgdXBcbiAgICB0aGlzLmxvZy5kZWJ1ZyhgV2FpdGluZyB1cCB0byAke3RoaXMubGF1bmNoVGltZW91dH1tcyBmb3IgV2ViRHJpdmVyQWdlbnQgdG8gc3RhcnRgKTtcbiAgICBsZXQgY3VycmVudFN0YXR1cyA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIGxldCByZXRyaWVzID0gcGFyc2VJbnQodGhpcy5sYXVuY2hUaW1lb3V0IC8gNTAwLCAxMCk7XG4gICAgICBhd2FpdCByZXRyeUludGVydmFsKHJldHJpZXMsIDEwMDAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMueGNvZGVidWlsZC5wcm9jZXNzRXhpdGVkKSB7XG4gICAgICAgICAgLy8gdGhlcmUgaGFzIGJlZW4gYW4gZXJyb3IgZWxzZXdoZXJlIGFuZCB3ZSBuZWVkIHRvIHNob3J0LWNpcmN1aXRcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJveHlUaW1lb3V0ID0gdGhpcy5ub1Nlc3Npb25Qcm94eS50aW1lb3V0O1xuICAgICAgICB0aGlzLm5vU2Vzc2lvblByb3h5LnRpbWVvdXQgPSAxMDAwO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGN1cnJlbnRTdGF0dXMgPSBhd2FpdCB0aGlzLm5vU2Vzc2lvblByb3h5LmNvbW1hbmQoJy9zdGF0dXMnLCAnR0VUJyk7XG4gICAgICAgICAgaWYgKGN1cnJlbnRTdGF0dXMgJiYgY3VycmVudFN0YXR1cy5pb3MgJiYgY3VycmVudFN0YXR1cy5pb3MuaXApIHtcbiAgICAgICAgICAgIHRoaXMuYWdlbnRVcmwgPSBjdXJyZW50U3RhdHVzLmlvcy5pcDtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5sb2cuZGVidWcoYFdlYkRyaXZlckFnZW50IGluZm9ybWF0aW9uOmApO1xuICAgICAgICAgIHRoaXMubG9nLmRlYnVnKEpTT04uc3RyaW5naWZ5KGN1cnJlbnRTdGF0dXMsIG51bGwsIDIpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gY29ubmVjdCB0byBydW5uaW5nIFdlYkRyaXZlckFnZW50OiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRoaXMubm9TZXNzaW9uUHJveHkudGltZW91dCA9IHByb3h5VGltZW91dDtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0aGlzLnhjb2RlYnVpbGQucHJvY2Vzc0V4aXRlZCkge1xuICAgICAgICAvLyB0aGVyZSBoYXMgYmVlbiBhbiBlcnJvciBlbHNld2hlcmUgYW5kIHdlIG5lZWQgdG8gc2hvcnQtY2lyY3VpdFxuICAgICAgICByZXR1cm4gY3VycmVudFN0YXR1cztcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2cuZGVidWcoYFdlYkRyaXZlckFnZW50IHN1Y2Nlc3NmdWxseSBzdGFydGVkIGFmdGVyICR7dGltZXIuZ2V0RHVyYXRpb24oKS5hc01pbGxpU2Vjb25kcy50b0ZpeGVkKDApfW1zYCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBhdCB0aGlzIHBvaW50LCBpZiB3ZSBoYXZlIG5vdCBoYWQgYW55IGVycm9ycyBmcm9tIHhjb2RlIGl0c2VsZiAocmVwb3J0ZWRcbiAgICAgIC8vIGVsc2V3aGVyZSksIHdlIGNhbiBsZXQgdGhpcyBnbyB0aHJvdWdoIGFuZCB0cnkgdG8gY3JlYXRlIHRoZSBzZXNzaW9uXG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhlcnIubWVzc2FnZSk7XG4gICAgICB0aGlzLmxvZy53YXJuKGBHZXR0aW5nIHN0YXR1cyBvZiBXZWJEcml2ZXJBZ2VudCBvbiBkZXZpY2UgdGltZWQgb3V0LiBDb250aW51aW5nYCk7XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50U3RhdHVzO1xuICB9XG5cbiAgYXN5bmMgcXVpdCAoKSB7XG4gICAgYXdhaXQga2lsbFByb2Nlc3MoJ3hjb2RlYnVpbGQnLCB0aGlzLnhjb2RlYnVpbGQpO1xuICB9XG59XG5cbmV4cG9ydCB7IFhjb2RlQnVpbGQgfTtcbmV4cG9ydCBkZWZhdWx0IFhjb2RlQnVpbGQ7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUEsSUFBQUEsU0FBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsYUFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsUUFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBQyxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQUssU0FBQSxHQUFBRCxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQU0sTUFBQSxHQUFBTixPQUFBO0FBSUEsSUFBQU8sT0FBQSxHQUFBSCxzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQVEsS0FBQSxHQUFBSixzQkFBQSxDQUFBSixPQUFBO0FBQ0EsSUFBQVMsR0FBQSxHQUFBVCxPQUFBO0FBQ0EsSUFBQVUsVUFBQSxHQUFBVixPQUFBO0FBR0EsTUFBTVcsa0JBQWtCLEdBQUcsa0JBQWtCO0FBQzdDLE1BQU1DLGNBQWMsR0FBRyxDQUFDO0FBQ3hCLE1BQU1DLGlCQUFpQixHQUFHLHNCQUFzQjtBQUNoRCxNQUFNQyxjQUFjLEdBQUcsbUJBQW1CO0FBRTFDLE1BQU1DLHdCQUF3QixHQUFHLHVDQUF1QztBQUN4RSxNQUFNQyx3QkFBd0IsR0FBRyxrQ0FBa0M7QUFDbkUsTUFBTUMsY0FBYyxHQUFHLENBQ3JCRix3QkFBd0IsRUFDeEJDLHdCQUF3QixFQUN4QixxQ0FBcUMsQ0FDdEM7QUFFRCxNQUFNRSxnQkFBZ0IsR0FBRywyQkFBMkI7QUFDcEQsTUFBTUMsYUFBYSxHQUFHLHdCQUF3QjtBQUU5QyxNQUFNQyxRQUFRLEdBQUdDLGVBQU0sQ0FBQ0MsU0FBUyxDQUFDLE9BQU8sQ0FBQztBQUcxQyxNQUFNQyxVQUFVLENBQUM7RUFDZkMsV0FBV0EsQ0FBRUMsWUFBWSxFQUFFQyxNQUFNLEVBQUVDLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRUMsR0FBRyxHQUFHLElBQUksRUFBRTtJQUN4RCxJQUFJLENB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
395
+ exports.default = XcodeBuild;
396
+ //# sourceMappingURL=xcodebuild.js.map