UNPKG

appium-xcuitest-driver-conan

Version:

Appium driver for iOS using XCUITest for backend

374 lines (290 loc) 22.9 kB
'use strict'; var _regeneratorRuntime = require('babel-runtime/regenerator')['default']; var _getIterator = require('babel-runtime/core-js/get-iterator')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _appiumSupport = require('appium-support'); var _teen_process = require('teen_process'); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); var WDA_RUNNER_BUNDLE_ID = 'com.facebook.WebDriverAgentRunner'; var PROJECT_FILE = 'project.pbxproj'; var XCUICOORDINATE_FILE = 'PrivateHeaders/XCTest/XCUICoordinate.h'; function replaceInFile(file, find, replace) { var contents, newContents; return _regeneratorRuntime.async(function replaceInFile$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(_appiumSupport.fs.readFile(file, 'utf-8')); case 2: contents = context$1$0.sent; newContents = contents.replace(find, replace); if (!(newContents !== contents)) { context$1$0.next = 7; break; } context$1$0.next = 7; return _regeneratorRuntime.awrap(_appiumSupport.fs.writeFile(file, newContents, 'utf-8')); case 7: case 'end': return context$1$0.stop(); } }, null, this); } function updateProjectFile(agentPath, newBundleId) { var projectFilePath; return _regeneratorRuntime.async(function updateProjectFile$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: projectFilePath = agentPath + '/' + PROJECT_FILE; context$1$0.prev = 1; context$1$0.next = 4; return _regeneratorRuntime.awrap(_appiumSupport.fs.copyFile(projectFilePath, projectFilePath + '.old')); case 4: context$1$0.next = 6; return _regeneratorRuntime.awrap(replaceInFile(projectFilePath, new RegExp(WDA_RUNNER_BUNDLE_ID.replace('.', '\.'), 'g'), newBundleId)); case 6: // jshint ignore:line _logger2['default'].debug('Successfully updated \'' + projectFilePath + '\' with bundle id \'' + newBundleId + '\''); context$1$0.next = 13; break; case 9: context$1$0.prev = 9; context$1$0.t0 = context$1$0['catch'](1); _logger2['default'].debug('Error updating project file: ' + context$1$0.t0.message); _logger2['default'].warn('Unable to update project file \'' + projectFilePath + '\' with ' + ('bundle id \'' + newBundleId + '\'. WebDriverAgent may not start')); case 13: case 'end': return context$1$0.stop(); } }, null, this, [[1, 9]]); } function resetProjectFile(agentPath, newBundleId) { var projectFilePath; return _regeneratorRuntime.async(function resetProjectFile$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: projectFilePath = agentPath + '/' + PROJECT_FILE; context$1$0.prev = 1; context$1$0.next = 4; return _regeneratorRuntime.awrap(replaceInFile(projectFilePath, new RegExp(newBundleId.replace('.', '\.'), 'g'), WDA_RUNNER_BUNDLE_ID)); case 4: context$1$0.next = 6; return _regeneratorRuntime.awrap(_appiumSupport.fs.unlink(projectFilePath + '.old')); case 6: _logger2['default'].debug('Successfully reset \'' + projectFilePath + '\' with bundle id \'' + WDA_RUNNER_BUNDLE_ID + '\''); context$1$0.next = 13; break; case 9: context$1$0.prev = 9; context$1$0.t0 = context$1$0['catch'](1); _logger2['default'].debug('Error resetting project file: ' + context$1$0.t0.message); _logger2['default'].warn('Unable to reset project file \'' + projectFilePath + '\' with ' + ('bundle id \'' + WDA_RUNNER_BUNDLE_ID + '\'. WebDriverAgent has been ') + 'modified and not returned to the original state.'); case 13: case 'end': return context$1$0.stop(); } }, null, this, [[1, 9]]); } function checkForDependencies(bootstrapPath) { var useSsl = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var carthagePath, args, _arr, _i, std, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line; return _regeneratorRuntime.async(function checkForDependencies$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.prev = 0; context$1$0.next = 3; return _regeneratorRuntime.awrap(_appiumSupport.fs.which('carthage')); case 3: carthagePath = context$1$0.sent; _logger2['default'].debug('Carthage found: \'' + carthagePath + '\''); context$1$0.next = 10; break; case 7: context$1$0.prev = 7; context$1$0.t0 = context$1$0['catch'](0); _logger2['default'].warn('Carthage not found. Install using `brew install carthage`'); case 10: context$1$0.next = 12; return _regeneratorRuntime.awrap(_appiumSupport.fs.hasAccess(bootstrapPath + '/Carthage')); case 12: if (context$1$0.sent) { context$1$0.next = 59; break; } _logger2['default'].debug('Running WebDriverAgent bootstrap script to install dependencies'); context$1$0.prev = 14; args = useSsl ? ['-d', '-D'] : ['-d']; context$1$0.next = 18; return _regeneratorRuntime.awrap((0, _teen_process.exec)('Scripts/bootstrap.sh', args, { cwd: bootstrapPath })); case 18: context$1$0.next = 59; break; case 20: context$1$0.prev = 20; context$1$0.t1 = context$1$0['catch'](14); _arr = ['stdout', 'stderr']; _i = 0; case 24: if (!(_i < _arr.length)) { context$1$0.next = 56; break; } std = _arr[_i]; _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; context$1$0.prev = 29; _iterator = _getIterator((context$1$0.t1[std] || '').split('\n')); case 31: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { context$1$0.next = 39; break; } line = _step.value; if (line.length) { context$1$0.next = 35; break; } return context$1$0.abrupt('continue', 36); case 35: _logger2['default'].error(line); case 36: _iteratorNormalCompletion = true; context$1$0.next = 31; break; case 39: context$1$0.next = 45; break; case 41: context$1$0.prev = 41; context$1$0.t2 = context$1$0['catch'](29); _didIteratorError = true; _iteratorError = context$1$0.t2; case 45: context$1$0.prev = 45; context$1$0.prev = 46; if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } case 48: context$1$0.prev = 48; if (!_didIteratorError) { context$1$0.next = 51; break; } throw _iteratorError; case 51: return context$1$0.finish(48); case 52: return context$1$0.finish(45); case 53: _i++; context$1$0.next = 24; break; case 56: context$1$0.next = 58; return _regeneratorRuntime.awrap(_appiumSupport.fs.rimraf(bootstrapPath + '/Carthage')); case 58: throw context$1$0.t1; case 59: context$1$0.next = 61; return _regeneratorRuntime.awrap(_appiumSupport.fs.hasAccess(bootstrapPath + '/Resources')); case 61: if (context$1$0.sent) { context$1$0.next = 65; break; } _logger2['default'].debug('Creating WebDriverAgent resources directory'); context$1$0.next = 65; return _regeneratorRuntime.awrap(_appiumSupport.fs.mkdir(bootstrapPath + '/Resources')); case 65: context$1$0.next = 67; return _regeneratorRuntime.awrap(_appiumSupport.fs.hasAccess(bootstrapPath + '/Resources/WebDriverAgent.bundle')); case 67: if (context$1$0.sent) { context$1$0.next = 71; break; } _logger2['default'].debug('Creating WebDriverAgent resource bundle directory'); context$1$0.next = 71; return _regeneratorRuntime.awrap(_appiumSupport.fs.mkdir(bootstrapPath + '/Resources/WebDriverAgent.bundle')); case 71: case 'end': return context$1$0.stop(); } }, null, this, [[0, 7], [14, 20], [29, 41, 45, 53], [46,, 48, 52]]); } function setRealDeviceSecurity(keychainPath, keychainPassword) { return _regeneratorRuntime.async(function setRealDeviceSecurity$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: _logger2['default'].debug('Setting security for iOS device'); context$1$0.next = 3; return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['-v', 'list-keychains', '-s', keychainPath])); case 3: context$1$0.next = 5; return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['-v', 'unlock-keychain', '-p', keychainPassword, keychainPath])); case 5: context$1$0.next = 7; return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['set-keychain-settings', '-t', '3600', '-l', keychainPath])); case 7: case 'end': return context$1$0.stop(); } }, null, this); } function fixXCUICoordinateFile(bootstrapPath) { var initial = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; var file, oldDef, newDef, _ref; return _regeneratorRuntime.async(function fixXCUICoordinateFile$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: file = _path2['default'].resolve(bootstrapPath, XCUICOORDINATE_FILE); oldDef = '- (void)pressForDuration:(double)arg1 thenDragToCoordinate:(id)arg2;'; newDef = '- (void)pressForDuration:(NSTimeInterval)duration thenDragToCoordinate:(XCUICoordinate *)otherCoordinate;'; if (!initial) { _ref = [newDef, oldDef]; oldDef = _ref[0]; newDef = _ref[1]; } context$1$0.next = 6; return _regeneratorRuntime.awrap(replaceInFile(file, oldDef, newDef)); case 6: case 'end': return context$1$0.stop(); } }, null, this); } function fixForXcode7(bootstrapPath) { var initial = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; return _regeneratorRuntime.async(function fixForXcode7$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: context$1$0.next = 2; return _regeneratorRuntime.awrap(fixXCUICoordinateFile(bootstrapPath, initial)); case 2: case 'end': return context$1$0.stop(); } }, null, this); } exports.updateProjectFile = updateProjectFile; exports.resetProjectFile = resetProjectFile; exports.checkForDependencies = checkForDependencies; exports.setRealDeviceSecurity = setRealDeviceSecurity; exports.fixForXcode7 = fixForXcode7; // backup the file, and then update the bundle id for the runner // jshint ignore:line // print out the stdout and stderr reports // remove the carthage directory, or else subsequent runs will see it and // assume the dependencies are already downloaded // the way the updated XCTest headers are in the WDA project, building in // Xcode 8.0 causes a duplicate declaration of method // so fix the offending line in the local headers //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi93ZWJkcml2ZXJhZ2VudC11dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7NkJBQW1CLGdCQUFnQjs7NEJBQ2QsY0FBYzs7b0JBQ2xCLE1BQU07Ozs7c0JBQ1AsVUFBVTs7OztBQUcxQixJQUFNLG9CQUFvQixHQUFHLG1DQUFtQyxDQUFDO0FBQ2pFLElBQU0sWUFBWSxHQUFHLGlCQUFpQixDQUFDO0FBQ3ZDLElBQU0sbUJBQW1CLEdBQUcsd0NBQXdDLENBQUM7O0FBRXJFLFNBQWUsYUFBYSxDQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTztNQUMzQyxRQUFRLEVBRVIsV0FBVzs7Ozs7eUNBRk0sa0JBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7OztBQUEzQyxnQkFBUTtBQUVSLG1CQUFXLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDOztjQUM3QyxXQUFXLEtBQUssUUFBUSxDQUFBOzs7Ozs7eUNBQ3BCLGtCQUFHLFNBQVMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQzs7Ozs7OztDQUVqRDs7QUFFRCxTQUFlLGlCQUFpQixDQUFFLFNBQVMsRUFBRSxXQUFXO01BQ2xELGVBQWU7Ozs7QUFBZix1QkFBZSxHQUFNLFNBQVMsU0FBSSxZQUFZOzs7eUNBRzFDLGtCQUFHLFFBQVEsQ0FBQyxlQUFlLEVBQUssZUFBZSxVQUFPOzs7O3lDQUN0RCxhQUFhLENBQUMsZUFBZSxFQUFFLElBQUksTUFBTSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsV0FBVyxDQUFDOzs7O0FBQzNHLDRCQUFJLEtBQUssNkJBQTBCLGVBQWUsNEJBQXFCLFdBQVcsUUFBSSxDQUFDOzs7Ozs7OztBQUV2Riw0QkFBSSxLQUFLLG1DQUFpQyxlQUFJLE9BQU8sQ0FBRyxDQUFDO0FBQ3pELDRCQUFJLElBQUksQ0FB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QUMsQ0FBQzs7Ozs7OztDQUNwRjs7QUFFRCxTQUFlLHFCQUFxQixDQUFFLGFBQWE7TUFBRSxPQUFPLHlEQUFHLElBQUk7O01BSTNELElBQUksRUFFTixNQUFNLEVBQ04sTUFBTTs7Ozs7QUFISixZQUFJLEdBQUcsa0JBQUssT0FBTyxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQztBQUV6RCxjQUFNLEdBQUcsc0VBQXNFO0FBQy9FLGNBQU0sR0FBRywyR0FBMkc7O0FBQ3hILFlBQUksQ0FBQyxPQUFPLEVBQUU7aUJBQ08sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDO0FBQWxDLGdCQUFNO0FBQUUsZ0JBQU07U0FDaEI7O3lDQUNLLGFBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQzs7Ozs7OztDQUMxQzs7QUFFRCxTQUFlLFlBQVksQ0FBRSxhQUFhO01BQUUsT0FBTyx5REFBRyxJQUFJOzs7Ozt5Q0FDbEQscUJBQXFCLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQzs7Ozs7OztDQUNwRDs7UUFFUSxpQkFBaUIsR0FBakIsaUJBQWlCO1FBQUUsZ0JBQWdCLEdBQWhCLGdCQUFnQjtRQUFFLG9CQUFvQixHQUFwQixvQkFBb0I7UUFDekQscUJBQXFCLEdBQXJCLHFCQUFxQjtRQUFFLFlBQVksR0FBWixZQUFZIiwiZmlsZSI6ImxpYi93ZWJkcml2ZXJhZ2VudC11dGlscy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZzIH0gZnJvbSAnYXBwaXVtLXN1cHBvcnQnO1xuaW1wb3J0IHsgZXhlYyB9IGZyb20gJ3RlZW5fcHJvY2Vzcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuXG5cbmNvbnN0IFdEQV9SVU5ORVJfQlVORExFX0lEID0gJ2NvbS5mYWNlYm9vay5XZWJEcml2ZXJBZ2VudFJ1bm5lcic7XG5jb25zdCBQUk9KRUNUX0ZJTEUgPSAncHJvamVjdC5wYnhwcm9qJztcbmNvbnN0IFhDVUlDT09SRElOQVRFX0ZJTEUgPSAnUHJpdmF0ZUhlYWRlcnMvWENUZXN0L1hDVUlDb29yZGluYXRlLmgnO1xuXG5hc3luYyBmdW5jdGlvbiByZXBsYWNlSW5GaWxlIChmaWxlLCBmaW5kLCByZXBsYWNlKSB7XG4gIGxldCBjb250ZW50cyA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGUsICd1dGYtOCcpO1xuXG4gIGxldCBuZXdDb250ZW50cyA9IGNvbnRlbnRzLnJlcGxhY2UoZmluZCwgcmVwbGFjZSk7XG4gIGlmIChuZXdDb250ZW50cyAhPT0gY29udGVudHMpIHtcbiAgICBhd2FpdCBmcy53cml0ZUZpbGUoZmlsZSwgbmV3Q29udGVudHMsICd1dGYtOCcpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVByb2plY3RGaWxlIChhZ2VudFBhdGgsIG5ld0J1bmRsZUlkKSB7XG4gIGxldCBwcm9qZWN0RmlsZVBhdGggPSBgJHthZ2VudFBhdGh9LyR7UFJPSkVDVF9GSUxFfWA7XG4gIHRyeSB7XG4gICAgLy8gYmFja3VwIHRoZSBmaWxlLCBhbmQgdGhlbiB1cGRhdGUgdGhlIGJ1bmRsZSBpZCBmb3IgdGhlIHJ1bm5lclxuICAgIGF3YWl0IGZzLmNvcHlGaWxlKHByb2plY3RGaWxlUGF0aCwgYCR7cHJvamVjdEZpbGVQYXRofS5vbGRgKTtcbiAgICBhd2FpdCByZXBsYWNlSW5GaWxlKHByb2plY3RGaWxlUGF0aCwgbmV3IFJlZ0V4cChXREFfUlVOTkVSX0JVTkRMRV9JRC5yZXBsYWNlKCcuJywgJ1xcLicpLCAnZycpLCBuZXdCdW5kbGVJZCk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgIGxvZy5kZWJ1ZyhgU3VjY2Vzc2Z1bGx5IHVwZGF0ZWQgJyR7cHJvamVjdEZpbGVQYXRofScgd2l0aCBidW5kbGUgaWQgJyR7bmV3QnVuZGxlSWR9J2ApO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZGVidWcoYEVycm9yIHVwZGF0aW5nIHByb2plY3QgZmlsZTogJHtlcnIubWVzc2FnZX1gKTtcbiAgICBsb2cud2FybihgVW5hYmxlIHRvIHVwZGF0ZSBwcm9qZWN0IGZpbGUgJyR7cHJvamVjdEZpbGVQYXRofScgd2l0aCBgICtcbiAgICAgICAgICAgICBgYnVuZGxlIGlkICcke25ld0J1bmRsZUlkfScuIFdlYkRyaXZlckFnZW50IG1heSBub3Qgc3RhcnRgKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiByZXNldFByb2plY3RGaWxlIChhZ2VudFBhdGgsIG5ld0J1bmRsZUlkKSB7XG4gIGxldCBwcm9qZWN0RmlsZVBhdGggPSBgJHthZ2VudFBhdGh9LyR7UFJPSkVDVF9GSUxFfWA7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVwbGFjZUluRmlsZShwcm9qZWN0RmlsZVBhdGgsIG5ldyBSZWdFeHAobmV3QnVuZGxlSWQucmVwbGFjZSgnLicsICdcXC4nKSwgJ2cnKSwgV0RBX1JVTk5FUl9CVU5ETEVfSUQpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICBhd2FpdCBmcy51bmxpbmsoYCR7cHJvamVjdEZpbGVQYXRofS5vbGRgKTtcbiAgICBsb2cuZGVidWcoYFN1Y2Nlc3NmdWxseSByZXNldCAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGJ1bmRsZSBpZCAnJHtXREFfUlVOTkVSX0JVTkRMRV9JRH0nYCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5kZWJ1ZyhgRXJyb3IgcmVzZXR0aW5nIHByb2plY3QgZmlsZTogJHtlcnIubWVzc2FnZX1gKTtcbiAgICBsb2cud2FybihgVW5hYmxlIHRvIHJlc2V0IHByb2plY3QgZmlsZSAnJHtwcm9qZWN0RmlsZVBhdGh9JyB3aXRoIGAgK1xuICAgICAgICAgICAgIGBidW5kbGUgaWQgJyR7V0RBX1JVTk5FUl9CVU5ETEVfSUR9Jy4gV2ViRHJpdmVyQWdlbnQgaGFzIGJlZW4gYCArXG4gICAgICAgICAgICAgYG1vZGlmaWVkIGFuZCBub3QgcmV0dXJuZWQgdG8gdGhlIG9yaWdpbmFsIHN0YXRlLmApO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNoZWNrRm9yRGVwZW5kZW5jaWVzIChib290c3RyYXBQYXRoLCB1c2VTc2wgPSBmYWxzZSkge1xuICB0cnkge1xuICAgIGxldCBjYXJ0aGFnZVBhdGggPSBhd2FpdCBmcy53aGljaCgnY2FydGhhZ2UnKTtcbiAgICBsb2cuZGVidWcoYENhcnRoYWdlIGZvdW5kOiAnJHtjYXJ0aGFnZVBhdGh9J2ApO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cud2FybignQ2FydGhhZ2Ugbm90IGZvdW5kLiBJbnN0YWxsIHVzaW5nIGBicmV3IGluc3RhbGwgY2FydGhhZ2VgJyk7XG4gIH1cbiAgaWYgKCFhd2FpdCBmcy5oYXNBY2Nlc3MoYCR7Ym9vdHN0cmFwUGF0aH0vQ2FydGhhZ2VgKSkge1xuICAgIGxvZy5kZWJ1ZygnUnVubmluZyBXZWJEcml2ZXJBZ2VudCBib290c3RyYXAgc2NyaXB0IHRvIGluc3RhbGwgZGVwZW5kZW5jaWVzJyk7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBhcmdzID0gdXNlU3NsID8gWyctZCcsICctRCddIDogWyctZCddO1xuICAgICAgYXdhaXQgZXhlYygnU2NyaXB0cy9ib290c3RyYXAuc2gnLCBhcmdzLCB7Y3dkOiBib290c3RyYXBQYXRofSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBwcmludCBvdXQgdGhlIHN0ZG91dCBhbmQgc3RkZXJyIHJlcG9ydHNcbiAgICAgIGZvciAobGV0IHN0ZCBvZiBbJ3N0ZG91dCcsICdzdGRlcnInXSkge1xuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIChlcnJbc3RkXSB8fCAnJykuc3BsaXQoJ1xcbicpKSB7XG4gICAgICAgICAgaWYgKCFsaW5lLmxlbmd0aCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZy5lcnJvcihsaW5lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIHRoZSBjYXJ0aGFnZSBkaXJlY3RvcnksIG9yIGVsc2Ugc3Vic2VxdWVudCBydW5zIHdpbGwgc2VlIGl0IGFuZFxuICAgICAgLy8gYXNzdW1lIHRoZSBkZXBlbmRlbmNpZXMgYXJlIGFscmVhZHkgZG93bmxvYWRlZFxuICAgICAgYXdhaXQgZnMucmltcmFmKGAke2Jvb3RzdHJhcFBhdGh9L0NhcnRoYWdlYCk7XG5cbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gIH1cbiAgaWYgKCFhd2FpdCBmcy5oYXNBY2Nlc3MoYCR7Ym9vdHN0cmFwUGF0aH0vUmVzb3VyY2VzYCkpIHtcbiAgICBsb2cuZGVidWcoJ0NyZWF0aW5nIFdlYkRyaXZlckFnZW50IHJlc291cmNlcyBkaXJlY3RvcnknKTtcbiAgICBhd2FpdCBmcy5ta2RpcihgJHtib290c3RyYXBQYXRofS9SZXNvdXJjZXNgKTtcbiAgfVxuICBpZiAoIWF3YWl0IGZzLmhhc0FjY2VzcyhgJHtib290c3RyYXBQYXRofS9SZXNvdXJjZXMvV2ViRHJpdmVyQWdlbnQuYnVuZGxlYCkpIHtcbiAgICBsb2cuZGVidWcoJ0NyZWF0aW5nIFdlYkRyaXZlckFnZW50IHJlc291cmNlIGJ1bmRsZSBkaXJlY3RvcnknKTtcbiAgICBhd2FpdCBmcy5ta2RpcihgJHtib290c3RyYXBQYXRofS9SZXNvdXJjZXMvV2ViRHJpdmVyQWdlbnQuYnVuZGxlYCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0UmVhbERldmljZVNlY3VyaXR5IChrZXljaGFpblBhdGgsIGtleWNoYWluUGFzc3dvcmQpIHtcbiAgbG9nLmRlYnVnKCdTZXR0aW5nIHNlY3VyaXR5IGZvciBpT1MgZGV2aWNlJyk7XG4gIGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWyctdicsICdsaXN0LWtleWNoYWlucycsICctcycsIGtleWNoYWluUGF0aF0pO1xuICBhd2FpdCBleGVjKCdzZWN1cml0eScsIFsnLXYnLCAndW5sb2NrLWtleWNoYWluJywgJy1wJywga2V5Y2hhaW5QYXNzd29yZCwga2V5Y2hhaW5QYXRoXSk7XG4gIGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWydzZXQta2V5Y2hhaW4tc2V0dGluZ3MnLCAnLXQnLCAnMzYwMCcsICctbCcsIGtleWNoYWluUGF0aF0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaXhYQ1VJQ29vcmRpbmF0ZUZpbGUgKGJvb3RzdHJhcFBhdGgsIGluaXRpYWwgPSB0cnVlKSB7XG4gIC8vIHRoZSB3YXkgdGhlIHVwZGF0ZWQgWENUZXN0IGhlYWRlcnMgYXJlIGluIHRoZSBXREEgcHJvamVjdCwgYnVpbGRpbmcgaW5cbiAgLy8gWGNvZGUgOC4wIGNhdXNlcyBhIGR1cGxpY2F0ZSBkZWNsYXJhdGlvbiBvZiBtZXRob2RcbiAgLy8gc28gZml4IHRoZSBvZmZlbmRpbmcgbGluZSBpbiB0aGUgbG9jYWwgaGVhZGVyc1xuICBjb25zdCBmaWxlID0gcGF0aC5yZXNvbHZlKGJvb3RzdHJhcFBhdGgsIFhDVUlDT09SRElOQVRFX0ZJTEUpO1xuXG4gIGxldCBvbGREZWYgPSAnLSAodm9pZClwcmVzc0ZvckR1cmF0aW9uOihkb3VibGUpYXJnMSB0aGVuRHJhZ1RvQ29vcmRpbmF0ZTooaWQpYXJnMjsnO1xuICBsZXQgbmV3RGVmID0gJy0gKHZvaWQpcHJlc3NGb3JEdXJhdGlvbjooTlNUaW1lSW50ZXJ2YWwpZHVyYXRpb24gdGhlbkRyYWdUb0Nvb3JkaW5hdGU6KFhDVUlDb29yZGluYXRlICopb3RoZXJDb29yZGluYXRlOyc7XG4gIGlmICghaW5pdGlhbCkge1xuICAgIFtvbGREZWYsIG5ld0RlZl0gPSBbbmV3RGVmLCBvbGREZWZdO1xuICB9XG4gIGF3YWl0IHJlcGxhY2VJbkZpbGUoZmlsZSwgb2xkRGVmLCBuZXdEZWYpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmaXhGb3JYY29kZTcgKGJvb3RzdHJhcFBhdGgsIGluaXRpYWwgPSB0cnVlKSB7XG4gIGF3YWl0IGZpeFhDVUlDb29yZGluYXRlRmlsZShib290c3RyYXBQYXRoLCBpbml0aWFsKTtcbn1cblxuZXhwb3J0IHsgdXBkYXRlUHJvamVjdEZpbGUsIHJlc2V0UHJvamVjdEZpbGUsIGNoZWNrRm9yRGVwZW5kZW5jaWVzLFxuICAgICAgICAgc2V0UmVhbERldmljZVNlY3VyaXR5LCBmaXhGb3JYY29kZTcgfTtcbiJdLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==