appium-xcuitest-driver-conan
Version:
Appium driver for iOS using XCUITest for backend
448 lines (349 loc) • 25.9 kB
JavaScript
;
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 _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _appiumIosDriver = require('appium-ios-driver');
var _teen_process = require('teen_process');
var _appiumXcode = require('appium-xcode');
var _appiumXcode2 = _interopRequireDefault(_appiumXcode);
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _logger = require('./logger');
var _logger2 = _interopRequireDefault(_logger);
var _packageJson = require('../../package.json');
var _packageJson2 = _interopRequireDefault(_packageJson);
// eslint-disable-line import/no-unresolved
var WDA_DERIVED_DATA_SEARCH_SUFFIX = 'Library/Developer/Xcode/DerivedData/WebDriverAgent-*';
var WDA_ATTACHMENTS_FOLDER_RELATIVE_PATH = 'Logs/Test/Attachments';
var DRIVER_VER = _packageJson2['default'].version;
function detectUdid() {
var cmd, args, udid, _ref, stdout, udids;
return _regeneratorRuntime.async(function detectUdid$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_logger2['default'].debug('Auto-detecting real device udid...');
cmd = undefined, args = [];
context$1$0.prev = 2;
context$1$0.next = 5;
return _regeneratorRuntime.awrap(_appiumSupport.fs.which('idevice_id'));
case 5:
cmd = context$1$0.sent;
args.push('-l');
_logger2['default'].debug('Using idevice_id');
context$1$0.next = 14;
break;
case 10:
context$1$0.prev = 10;
context$1$0.t0 = context$1$0['catch'](2);
_logger2['default'].debug('Using udidetect');
cmd = require.resolve('udidetect');
case 14:
udid = undefined;
context$1$0.prev = 15;
context$1$0.next = 18;
return _regeneratorRuntime.awrap((0, _teen_process.exec)(cmd, args, { timeout: 3000 }));
case 18:
_ref = context$1$0.sent;
stdout = _ref.stdout;
udids = _lodash2['default'].filter(stdout.split('\n'), Boolean);
udid = _lodash2['default'].last(udids);
if (udids.length > 1) {
_logger2['default'].warn('Multiple devices found: ' + udids.join(', '));
_logger2['default'].warn('Choosing \'' + udid + '\'. If this is wrong, manually set with \'udid\' desired capability');
}
context$1$0.next = 28;
break;
case 25:
context$1$0.prev = 25;
context$1$0.t1 = context$1$0['catch'](15);
_logger2['default'].errorAndThrow('Error detecting udid: ' + context$1$0.t1.message);
case 28:
if (!(!udid || udid.length <= 2)) {
context$1$0.next = 30;
break;
}
throw new Error('Could not detect udid.');
case 30:
_logger2['default'].debug('Detected real device udid: \'' + udid + '\'');
return context$1$0.abrupt('return', udid);
case 32:
case 'end':
return context$1$0.stop();
}
}, null, this, [[2, 10], [15, 25]]);
}
function getAndCheckXcodeVersion() {
var version;
return _regeneratorRuntime.async(function getAndCheckXcodeVersion$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
version = undefined;
context$1$0.prev = 1;
context$1$0.next = 4;
return _regeneratorRuntime.awrap(_appiumXcode2['default'].getVersion(true));
case 4:
version = context$1$0.sent;
context$1$0.next = 11;
break;
case 7:
context$1$0.prev = 7;
context$1$0.t0 = context$1$0['catch'](1);
_logger2['default'].debug(context$1$0.t0);
_logger2['default'].errorAndThrow('Could not determine Xcode version: ' + context$1$0.t0.message);
case 11:
if (version.toolsVersion) {
context$1$0.next = 20;
break;
}
context$1$0.prev = 12;
context$1$0.next = 15;
return _regeneratorRuntime.awrap(_appiumXcode2['default'].getCommandLineToolsVersion());
case 15:
version.toolsVersion = context$1$0.sent;
context$1$0.next = 20;
break;
case 18:
context$1$0.prev = 18;
context$1$0.t1 = context$1$0['catch'](12);
case 20:
// we do not support Xcodes < 7.3,
if (version.versionFloat < 7.3) {
_logger2['default'].errorAndThrow('Xcode version \'' + version.versionString + '\'. Support for ' + ('Xcode ' + version.versionString + ' is not supported. ') + 'Please upgrade to version 7.3 or higher');
}
return context$1$0.abrupt('return', version);
case 22:
case 'end':
return context$1$0.stop();
}
}, null, this, [[1, 7], [12, 18]]);
}
function getAndCheckIosSdkVersion() {
var versionNumber;
return _regeneratorRuntime.async(function getAndCheckIosSdkVersion$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
versionNumber = undefined;
context$1$0.prev = 1;
context$1$0.next = 4;
return _regeneratorRuntime.awrap(_appiumXcode2['default'].getMaxIOSSDK());
case 4:
versionNumber = context$1$0.sent;
context$1$0.next = 10;
break;
case 7:
context$1$0.prev = 7;
context$1$0.t0 = context$1$0['catch'](1);
_logger2['default'].errorAndThrow('Could not determine iOS SDK version: ' + context$1$0.t0.message);
case 10:
return context$1$0.abrupt('return', versionNumber);
case 11:
case 'end':
return context$1$0.stop();
}
}, null, this, [[1, 7]]);
}
function killAppUsingAppName(udid, appName) {
var psArgs;
return _regeneratorRuntime.async(function killAppUsingAppName$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
psArgs = ['-c', 'ps -ax|grep -i "' + appName + '"|grep -i "' + udid + '"|grep -v grep|awk \'{print "kill -9 " $1}\'|sh'];
context$1$0.prev = 1;
context$1$0.next = 4;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('bash', psArgs));
case 4:
context$1$0.next = 9;
break;
case 6:
context$1$0.prev = 6;
context$1$0.t0 = context$1$0['catch'](1);
_logger2['default'].debug('Error : ' + context$1$0.t0.message);
case 9:
case 'end':
return context$1$0.stop();
}
}, null, this, [[1, 6]]);
}
function adjustWDAAttachmentsPermissions(perms) {
var derivedDataSearchMask, folders, changesMade, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, folder, attachmentsFolder;
return _regeneratorRuntime.async(function adjustWDAAttachmentsPermissions$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
if (process.env.HOME) {
context$1$0.next = 2;
break;
}
throw new Error('Need HOME env var to be set in order to adjust WDA attachments permission');
case 2:
derivedDataSearchMask = _path2['default'].join(process.env.HOME, WDA_DERIVED_DATA_SEARCH_SUFFIX);
context$1$0.next = 5;
return _regeneratorRuntime.awrap(_appiumSupport.fs.glob(derivedDataSearchMask));
case 5:
folders = context$1$0.sent;
changesMade = false;
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
context$1$0.prev = 10;
_iterator = _getIterator(folders);
case 12:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
context$1$0.next = 26;
break;
}
folder = _step.value;
_logger2['default'].debug('Found WDA derived data folder: \'' + folder + '\'');
attachmentsFolder = _path2['default'].join(folder, WDA_ATTACHMENTS_FOLDER_RELATIVE_PATH);
context$1$0.next = 18;
return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(attachmentsFolder));
case 18:
if (!context$1$0.sent) {
context$1$0.next = 23;
break;
}
_logger2['default'].info('Setting \'' + perms + '\' permissions to \'' + attachmentsFolder + '\' folder');
context$1$0.next = 22;
return _regeneratorRuntime.awrap(_appiumSupport.fs.chmod(attachmentsFolder, perms));
case 22:
changesMade = true;
case 23:
_iteratorNormalCompletion = true;
context$1$0.next = 12;
break;
case 26:
context$1$0.next = 32;
break;
case 28:
context$1$0.prev = 28;
context$1$0.t0 = context$1$0['catch'](10);
_didIteratorError = true;
_iteratorError = context$1$0.t0;
case 32:
context$1$0.prev = 32;
context$1$0.prev = 33;
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
case 35:
context$1$0.prev = 35;
if (!_didIteratorError) {
context$1$0.next = 38;
break;
}
throw _iteratorError;
case 38:
return context$1$0.finish(35);
case 39:
return context$1$0.finish(32);
case 40:
if (!changesMade) {
_logger2['default'].info('No WDA derived data folders have been found.');
}
case 41:
case 'end':
return context$1$0.stop();
}
}, null, this, [[10, 28, 32, 40], [33,, 35, 39]]);
}
function clearSystemFiles(wda) {
var toDelete;
return _regeneratorRuntime.async(function clearSystemFiles$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
if (!(!wda || !wda.derivedDataPath)) {
context$1$0.next = 3;
break;
}
_logger2['default'].debug('No WebDriverAgent derived data available, so unable to clear system files');
return context$1$0.abrupt('return');
case 3:
toDelete = [_path2['default'].resolve(wda.derivedDataPath, 'Logs')];
context$1$0.next = 6;
return _regeneratorRuntime.awrap(_appiumIosDriver.utils.clearLogs(toDelete));
case 6:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
function generateXcodeConfigFile(orgId, signingId) {
var contents, xcconfigPath;
return _regeneratorRuntime.async(function generateXcodeConfigFile$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_logger2['default'].debug('Generating xcode config file for orgId \'' + orgId + '\' and signingId ' + ('\'' + signingId + '\''));
contents = 'DEVELOPMENT_TEAM = ' + orgId + '\nCODE_SIGN_IDENTITY = ' + signingId + '\n';
context$1$0.next = 4;
return _regeneratorRuntime.awrap(_appiumSupport.tempDir.path('appium-temp.xcconfig'));
case 4:
xcconfigPath = context$1$0.sent;
_logger2['default'].debug('Writing xcode config file to ' + xcconfigPath);
context$1$0.next = 8;
return _regeneratorRuntime.awrap(_appiumSupport.fs.writeFile(xcconfigPath, contents, "utf8"));
case 8:
return context$1$0.abrupt('return', xcconfigPath);
case 9:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
function checkAppPresent(app) {
return _regeneratorRuntime.async(function checkAppPresent$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_logger2['default'].debug('Checking whether app \'' + app + '\' is actually present on file system');
context$1$0.next = 3;
return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(app));
case 3:
if (context$1$0.sent) {
context$1$0.next = 5;
break;
}
_logger2['default'].errorAndThrow('Could not find app at \'' + app + '\'');
case 5:
_logger2['default'].debug('App is present');
case 6:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
function getDriverInfo() {
var stat, built, info;
return _regeneratorRuntime.async(function getDriverInfo$(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.stat(_path2['default'].resolve(__dirname, '..')));
case 2:
stat = context$1$0.sent;
built = stat.mtime.getTime();
info = {
built: built,
version: DRIVER_VER
};
return context$1$0.abrupt('return', info);
case 6:
case 'end':
return context$1$0.stop();
}
}, null, this);
}
exports.detectUdid = detectUdid;
exports.getAndCheckXcodeVersion = getAndCheckXcodeVersion;
exports.getAndCheckIosSdkVersion = getAndCheckIosSdkVersion;
exports.killAppUsingAppName = killAppUsingAppName;
exports.adjustWDAAttachmentsPermissions = adjustWDAAttachmentsPermissions;
exports.generateXcodeConfigFile = generateXcodeConfigFile;
exports.checkAppPresent = checkAppPresent;
exports.getDriverInfo = getDriverInfo;
exports.clearSystemFiles = clearSystemFiles;
// only want to clear the system files for the particular WDA xcode run
//# sourceMappingURL=data:application/json;charset=utf8;base64,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RUFBRSxJQUFJLENBQUMsQ0FBQzs7O0FBQW5ELFlBQUk7QUFDSixhQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUU7QUFDNUIsWUFBSSxHQUFHO0FBQ1QsZUFBSyxFQUFMLEtBQUs7QUFDTCxpQkFBTyxFQUFFLFVBQVU7U0FDcEI7NENBQ00sSUFBSTs7Ozs7OztDQUNaOztRQUVRLFVBQVUsR0FBVixVQUFVO1FBQUUsdUJBQXVCLEdBQXZCLHVCQUF1QjtRQUFFLHdCQUF3QixHQUF4Qix3QkFBd0I7UUFDN0QsbUJBQW1CLEdBQW5CLG1CQUFtQjtRQUFFLCtCQUErQixHQUEvQiwrQkFBK0I7UUFDcEQsdUJBQXVCLEdBQXZCLHVCQUF1QjtRQUFFLGVBQWUsR0FBZixlQUFlO1FBQUUsYUFBYSxHQUFiLGFBQWE7UUFDdkQsZ0JBQWdCLEdBQWhCLGdCQUFnQiIsImZpbGUiOiJsaWIvdXRpbHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmcywgdGVtcERpciB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgdXRpbHMgYXMgaW9zVXRpbHMgfSBmcm9tICdhcHBpdW0taW9zLWRyaXZlcic7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCB4Y29kZSBmcm9tICdhcHBpdW0teGNvZGUnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHBrZ09iaiBmcm9tICcuLi8uLi9wYWNrYWdlLmpzb24nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGltcG9ydC9uby11bnJlc29sdmVkXG5cblxuY29uc3QgV0RBX0RFUklWRURfREFUQV9TRUFSQ0hfU1VGRklYID0gJ0xpYnJhcnkvRGV2ZWxvcGVyL1hjb2RlL0Rlcml2ZWREYXRhL1dlYkRyaXZlckFnZW50LSonO1xuY29uc3QgV0RBX0FUVEFDSE1FTlRTX0ZPTERFUl9SRUxBVElWRV9QQVRIID0gJ0xvZ3MvVGVzdC9BdHRhY2htZW50cyc7XG5jb25zdCBEUklWRVJfVkVSID0gcGtnT2JqLnZlcnNpb247XG5cblxuYXN5bmMgZnVuY3Rpb24gZGV0ZWN0VWRpZCAoKSB7XG4gIGxvZy5kZWJ1ZygnQXV0by1kZXRlY3RpbmcgcmVhbCBkZXZpY2UgdWRpZC4uLicpO1xuICBsZXQgIGNtZCwgYXJncyA9IFtdO1xuICB0cnkge1xuICAgIGNtZCA9IGF3YWl0IGZzLndoaWNoKCdpZGV2aWNlX2lkJyk7XG4gICAgYXJncy5wdXNoKCctbCcpO1xuICAgIGxvZy5kZWJ1ZygnVXNpbmcgaWRldmljZV9pZCcpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZGVidWcoJ1VzaW5nIHVkaWRldGVjdCcpO1xuICAgIGNtZCA9IHJlcXVpcmUucmVzb2x2ZSgndWRpZGV0ZWN0Jyk7XG4gIH1cbiAgbGV0IHVkaWQ7XG4gIHRyeSB7XG4gICAgbGV0IHtzdGRvdXR9ID0gYXdhaXQgZXhlYyhjbWQsIGFyZ3MsIHt0aW1lb3V0OiAzMDAwfSk7XG4gICAgbGV0IHVkaWRzID0gXy5maWx0ZXIoc3Rkb3V0LnNwbGl0KCdcXG4nKSwgQm9vbGVhbik7XG4gICAgdWRpZCA9IF8ubGFzdCh1ZGlkcyk7XG4gICAgaWYgKHVkaWRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGxvZy53YXJuKGBNdWx0aXBsZSBkZXZpY2VzIGZvdW5kOiAke3VkaWRzLmpvaW4oJywgJyl9YCk7XG4gICAgICBsb2cud2FybihgQ2hvb3NpbmcgJyR7dWRpZH0nLiBJZiB0aGlzIGlzIHdyb25nLCBtYW51YWxseSBzZXQgd2l0aCAndWRpZCcgZGVzaXJlZCBjYXBhYmlsaXR5YCk7XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZXJyb3JBbmRUaHJvdyhgRXJyb3IgZGV0ZWN0aW5nIHVkaWQ6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gIH1cbiAgaWYgKCF1ZGlkIHx8IHVkaWQubGVuZ3RoIDw9IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBkZXRlY3QgdWRpZC4nKTtcbiAgfVxuICBsb2cuZGVidWcoYERldGVjdGVkIHJlYWwgZGV2aWNlIHVkaWQ6ICcke3VkaWR9J2ApO1xuICByZXR1cm4gdWRpZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QW5kQ2hlY2tYY29kZVZlcnNpb24gKCkge1xuICBsZXQgdmVyc2lvbjtcbiAgdHJ5IHtcbiAgICB2ZXJzaW9uID0gYXdhaXQgeGNvZGUuZ2V0VmVyc2lvbih0cnVlKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nLmRlYnVnKGVycik7XG4gICAgbG9nLmVycm9yQW5kVGhyb3coYENvdWxkIG5vdCBkZXRlcm1pbmUgWGNvZGUgdmVyc2lvbjogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmICghdmVyc2lvbi50b29sc1ZlcnNpb24pIHtcbiAgICB0cnkge1xuICAgICAgdmVyc2lvbi50b29sc1ZlcnNpb24gPSBhd2FpdCB4Y29kZS5nZXRDb21tYW5kTGluZVRvb2xzVmVyc2lvbigpO1xuICAgIH0gY2F0Y2ggKGlnbikge31cbiAgfVxuXG4gIC8vIHdlIGRvIG5vdCBzdXBwb3J0IFhjb2RlcyA8IDcuMyxcbiAgaWYgKHZlcnNpb24udmVyc2lvbkZsb2F0IDwgNy4zKSB7XG4gICAgbG9nLmVycm9yQW5kVGhyb3coYFhjb2RlIHZlcnNpb24gJyR7dmVyc2lvbi52ZXJzaW9uU3RyaW5nfScuIFN1cHBvcnQgZm9yIGAgK1xuICAgICAgICAgICAgICAgICAgICAgIGBYY29kZSAke3ZlcnNpb24udmVyc2lvblN0cmluZ30gaXMgbm90IHN1cHBvcnRlZC4gYCArXG4gICAgICAgICAgICAgICAgICAgICAgYFBsZWFzZSB1cGdyYWRlIHRvIHZlcnNpb24gNy4zIG9yIGhpZ2hlcmApO1xuICB9XG4gIHJldHVybiB2ZXJzaW9uO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBbmRDaGVja0lvc1Nka1ZlcnNpb24gKCkge1xuICBsZXQgdmVyc2lvbk51bWJlcjtcbiAgdHJ5IHtcbiAgICB2ZXJzaW9uTnVtYmVyID0gYXdhaXQgeGNvZGUuZ2V0TWF4SU9TU0RLKCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZy5lcnJvckFuZFRocm93KGBDb3VsZCBub3QgZGV0ZXJtaW5lIGlPUyBTREsgdmVyc2lvbjogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxuICByZXR1cm4gdmVyc2lvbk51bWJlcjtcbn1cblxuYXN5bmMgZnVuY3Rpb24ga2lsbEFwcFVzaW5nQXBwTmFtZSAodWRpZCwgYXBwTmFtZSkge1xuICBsZXQgcHNBcmdzID0gW2AtY2AsIGBwcyAtYXh8Z3JlcCAtaSBcIiR7YXBwTmFtZX1cInxncmVwIC1pIFwiJHt1ZGlkfVwifGdyZXAgLXYgZ3JlcHxhd2sgJ3twcmludCBcImtpbGwgLTkgXCIgJDF9J3xzaGBdO1xuICB0cnkge1xuICAgIGF3YWl0IGV4ZWMoYGJhc2hgLCBwc0FyZ3MpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2cuZGVidWcoYEVycm9yIDogJHtlcnIubWVzc2FnZX1gKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBhZGp1c3RXREFBdHRhY2htZW50c1Blcm1pc3Npb25zIChwZXJtcykge1xuICBpZiAoIXByb2Nlc3MuZW52LkhPTUUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05lZWQgSE9NRSBlbnYgdmFyIHRvIGJlIHNldCBpbiBvcmRlciB0byBhZGp1c3QgV0RBIGF0dGFjaG1lbnRzIHBlcm1pc3Npb24nKTtcbiAgfVxuICBsZXQgZGVyaXZlZERhdGFTZWFyY2hNYXNrID0gcGF0aC5qb2luKHByb2Nlc3MuZW52LkhPTUUsIFdEQV9ERVJJVkVEX0RBVEFfU0VBUkNIX1NVRkZJWCk7XG4gIGxldCBmb2xkZXJzID0gYXdhaXQgZnMuZ2xvYihkZXJpdmVkRGF0YVNlYXJjaE1hc2spO1xuICBsZXQgY2hhbmdlc01hZGUgPSBmYWxzZTtcbiAgZm9yIChsZXQgZm9sZGVyIG9mIGZvbGRlcnMpIHtcbiAgICBsb2cuZGVidWcoYEZvdW5kIFdEQSBkZXJpdmVkIGRhdGEgZm9sZGVyOiAnJHtmb2xkZXJ9J2ApO1xuICAgIGxldCBhdHRhY2htZW50c0ZvbGRlciA9IHBhdGguam9pbihmb2xkZXIsIFdEQV9BVFRBQ0hNRU5UU19GT0xERVJfUkVMQVRJVkVfUEFUSCk7XG4gICAgaWYgKGF3YWl0IGZzLmV4aXN0cyhhdHRhY2htZW50c0ZvbGRlcikpIHtcbiAgICAgIGxvZy5pbmZvKGBTZXR0aW5nICcke3Blcm1zfScgcGVybWlzc2lvbnMgdG8gJyR7YXR0YWNobWVudHNGb2xkZXJ9JyBmb2xkZXJgKTtcbiAgICAgIGF3YWl0IGZzLmNobW9kKGF0dGFjaG1lbnRzRm9sZGVyLCBwZXJtcyk7XG4gICAgICBjaGFuZ2VzTWFkZSA9IHRydWU7XG4gICAgfVxuICB9XG4gIGlmICghY2hhbmdlc01hZGUpIHtcbiAgICBsb2cuaW5mbygnTm8gV0RBIGRlcml2ZWQgZGF0YSBmb2xkZXJzIGhhdmUgYmVlbiBmb3VuZC4nKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjbGVhclN5c3RlbUZpbGVzICh3ZGEpIHtcbiAgLy8gb25seSB3YW50IHRvIGNsZWFyIHRoZSBzeXN0ZW0gZmlsZXMgZm9yIHRoZSBwYXJ0aWN1bGFyIFdEQSB4Y29kZSBydW5cbiAgaWYgKCF3ZGEgfHwgIXdkYS5kZXJpdmVkRGF0YVBhdGgpIHtcbiAgICBsb2cuZGVidWcoJ05vIFdlYkRyaXZlckFnZW50IGRlcml2ZWQgZGF0YSBhdmFpbGFibGUsIHNvIHVuYWJsZSB0byBjbGVhciBzeXN0ZW0gZmlsZXMnKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgdG9EZWxldGUgPSBbcGF0aC5yZXNvbHZlKHdkYS5kZXJpdmVkRGF0YVBhdGgsICdMb2dzJyldO1xuICBhd2FpdCBpb3NVdGlscy5jbGVhckxvZ3ModG9EZWxldGUpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVhjb2RlQ29uZmlnRmlsZSAob3JnSWQsIHNpZ25pbmdJZCkge1xuICBsb2cuZGVidWcoYEdlbmVyYXRpbmcgeGNvZGUgY29uZmlnIGZpbGUgZm9yIG9yZ0lkICcke29yZ0lkfScgYW5kIHNpZ25pbmdJZCBgICtcbiAgICAgICAgICAgIGAnJHtzaWduaW5nSWR9J2ApO1xuICBsZXQgY29udGVudHMgPSBgREVWRUxPUE1FTlRfVEVBTSA9ICR7b3JnSWR9XG5DT0RFX1NJR05fSURFTlRJVFkgPSAke3NpZ25pbmdJZH1cbmA7XG4gIGxldCB4Y2NvbmZpZ1BhdGggPSBhd2FpdCB0ZW1wRGlyLnBhdGgoJ2FwcGl1bS10ZW1wLnhjY29uZmlnJyk7XG4gIGxvZy5kZWJ1ZyhgV3JpdGluZyB4Y29kZSBjb25maWcgZmlsZSB0byAke3hjY29uZmlnUGF0aH1gKTtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKHhjY29uZmlnUGF0aCwgY29udGVudHMsIFwidXRmOFwiKTtcbiAgcmV0dXJuIHhjY29uZmlnUGF0aDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY2hlY2tBcHBQcmVzZW50IChhcHApIHtcbiAgbG9nLmRlYnVnKGBDaGVja2luZyB3aGV0aGVyIGFwcCAnJHthcHB9JyBpcyBhY3R1YWxseSBwcmVzZW50IG9uIGZpbGUgc3lzdGVtYCk7XG4gIGlmICghKGF3YWl0IGZzLmV4aXN0cyhhcHApKSkge1xuICAgIGxvZy5lcnJvckFuZFRocm93KGBDb3VsZCBub3QgZmluZCBhcHAgYXQgJyR7YXBwfSdgKTtcbiAgfVxuICBsb2cuZGVidWcoJ0FwcCBpcyBwcmVzZW50Jyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERyaXZlckluZm8gKCkge1xuICBsZXQgc3RhdCA9IGF3YWl0IGZzLnN0YXQocGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJykpO1xuICBsZXQgYnVpbHQgPSBzdGF0Lm10aW1lLmdldFRpbWUoKTtcbiAgbGV0IGluZm8gPSB7XG4gICAgYnVpbHQsXG4gICAgdmVyc2lvbjogRFJJVkVSX1ZFUixcbiAgfTtcbiAgcmV0dXJuIGluZm87XG59XG5cbmV4cG9ydCB7IGRldGVjdFVkaWQsIGdldEFuZENoZWNrWGNvZGVWZXJzaW9uLCBnZXRBbmRDaGVja0lvc1Nka1ZlcnNpb24sXG4gICAgICAgICBraWxsQXBwVXNpbmdBcHBOYW1lLCBhZGp1c3RXREFBdHRhY2htZW50c1Blcm1pc3Npb25zLFxuICAgICAgICAgZ2VuZXJhdGVYY29kZUNvbmZpZ0ZpbGUsIGNoZWNrQXBwUHJlc2VudCwgZ2V0RHJpdmVySW5mbyxcbiAgICAgICAgIGNsZWFyU3lzdGVtRmlsZXMgfTtcbiJdLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==