appium-doctor
Version:
Test environment for fitness to run Appium
507 lines (391 loc) • 26.8 kB
JavaScript
;
var _get = require('babel-runtime/helpers/get')['default'];
var _inherits = require('babel-runtime/helpers/inherits')['default'];
var _createClass = require('babel-runtime/helpers/create-class')['default'];
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
var _regeneratorRuntime = require('babel-runtime/regenerator')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
Object.defineProperty(exports, '__esModule', {
value: true
});
var _utils = require('./utils');
var _appiumSupport = require('appium-support');
var _teen_process = require('teen_process');
var _doctor = require('./doctor');
var _logger = require('./logger');
var _logger2 = _interopRequireDefault(_logger);
var _nodeDetector = require('./node-detector');
var _nodeDetector2 = _interopRequireDefault(_nodeDetector);
var _prompt = require('./prompt');
var _env = require('./env');
var _env2 = _interopRequireDefault(_env);
var checks = [];
var fixes = {};
// Check for Xcode.
var XcodeCheck = (function (_DoctorCheck) {
_inherits(XcodeCheck, _DoctorCheck);
function XcodeCheck() {
_classCallCheck(this, XcodeCheck);
_get(Object.getPrototypeOf(XcodeCheck.prototype), 'constructor', this).apply(this, arguments);
}
_createClass(XcodeCheck, [{
key: 'diagnose',
value: function diagnose() {
var xcodePath, _ref, stdout;
return _regeneratorRuntime.async(function diagnose$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
xcodePath = undefined;
context$2$0.prev = 1;
context$2$0.next = 4;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('xcode-select', ['--print-path']));
case 4:
_ref = context$2$0.sent;
stdout = _ref.stdout;
xcodePath = (stdout || '').replace("\n", "");
context$2$0.next = 12;
break;
case 9:
context$2$0.prev = 9;
context$2$0.t0 = context$2$0['catch'](1);
return context$2$0.abrupt('return', (0, _utils.nok)('Xcode is NOT installed!'));
case 12:
context$2$0.t1 = xcodePath;
if (!context$2$0.t1) {
context$2$0.next = 17;
break;
}
context$2$0.next = 16;
return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(xcodePath));
case 16:
context$2$0.t1 = context$2$0.sent;
case 17:
if (!context$2$0.t1) {
context$2$0.next = 21;
break;
}
context$2$0.t2 = (0, _utils.ok)('Xcode is installed at: ' + xcodePath);
context$2$0.next = 22;
break;
case 21:
context$2$0.t2 = (0, _utils.nok)('Xcode cannot be found at \'' + xcodePath + '\'!');
case 22:
return context$2$0.abrupt('return', context$2$0.t2);
case 23:
case 'end':
return context$2$0.stop();
}
}, null, this, [[1, 9]]);
}
}, {
key: 'fix',
value: function fix() {
return _regeneratorRuntime.async(function fix$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
return context$2$0.abrupt('return', 'Manually install Xcode.');
case 1:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}]);
return XcodeCheck;
})(_doctor.DoctorCheck);
checks.push(new XcodeCheck());
// Check for Xcode Command Line Tools.
var XcodeCmdLineToolsCheck = (function (_DoctorCheck2) {
_inherits(XcodeCmdLineToolsCheck, _DoctorCheck2);
function XcodeCmdLineToolsCheck() {
_classCallCheck(this, XcodeCmdLineToolsCheck);
_get(Object.getPrototypeOf(XcodeCmdLineToolsCheck.prototype), 'constructor', this).call(this, { autofix: true });
}
_createClass(XcodeCmdLineToolsCheck, [{
key: 'diagnose',
value: function diagnose() {
var errMess, pkgName, stdout;
return _regeneratorRuntime.async(function diagnose$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
errMess = 'Xcode Command Line Tools are NOT installed!';
context$2$0.next = 3;
return _regeneratorRuntime.awrap(_appiumSupport.system.macOsxVersion());
case 3:
context$2$0.t0 = context$2$0.sent;
if (!(context$2$0.t0 === '10.8')) {
context$2$0.next = 8;
break;
}
context$2$0.t1 = 'com.apple.pkg.DeveloperToolsCLI';
context$2$0.next = 9;
break;
case 8:
context$2$0.t1 = 'com.apple.pkg.CLTools_Executables';
case 9:
pkgName = context$2$0.t1;
stdout = undefined;
context$2$0.prev = 11;
context$2$0.next = 14;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('pkgutil', ['--pkg-info=' + pkgName]));
case 14:
stdout = context$2$0.sent.stdout;
context$2$0.next = 21;
break;
case 17:
context$2$0.prev = 17;
context$2$0.t2 = context$2$0['catch'](11);
_logger2['default'].debug(context$2$0.t2);
return context$2$0.abrupt('return', (0, _utils.nok)(errMess));
case 21:
return context$2$0.abrupt('return', stdout.match(/install-time/) ? (0, _utils.ok)('Xcode Command Line Tools are installed.') : (0, _utils.nok)(errMess));
case 22:
case 'end':
return context$2$0.stop();
}
}, null, this, [[11, 17]]);
}
}, {
key: 'fix',
value: function fix() {
var yesno;
return _regeneratorRuntime.async(function fix$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
_logger2['default'].info('The following command need be executed: xcode-select --install');
context$2$0.next = 3;
return _regeneratorRuntime.awrap((0, _prompt.fixIt)());
case 3:
yesno = context$2$0.sent;
if (!(yesno === 'yes')) {
context$2$0.next = 9;
break;
}
context$2$0.next = 7;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('xcode-select', ['--install']));
case 7:
context$2$0.next = 11;
break;
case 9:
_logger2['default'].info('Skipping you will need to install Xcode manually.');
throw new _doctor.FixSkippedError();
case 11:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}]);
return XcodeCmdLineToolsCheck;
})(_doctor.DoctorCheck);
checks.push(new XcodeCmdLineToolsCheck());
// Automatically run authorize iOS if requested
fixes.authorizeIosFix = function callee$0$0() {
var yesno;
return _regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
_logger2['default'].info('The authorize iOS script need to be run.');
context$1$0.next = 3;
return _regeneratorRuntime.awrap((0, _prompt.fixIt)());
case 3:
yesno = context$1$0.sent;
if (!(yesno === 'yes')) {
context$1$0.next = 9;
break;
}
context$1$0.next = 7;
return _regeneratorRuntime.awrap((0, _utils.authorize)());
case 7:
context$1$0.next = 11;
break;
case 9:
_logger2['default'].info('Skipping you will need to run the authorize iOS manually.');
throw new _doctor.FixSkippedError();
case 11:
case 'end':
return context$1$0.stop();
}
}, null, this);
};
// Dev Tools Security
var DevToolsSecurityCheck = (function (_DoctorCheck3) {
_inherits(DevToolsSecurityCheck, _DoctorCheck3);
function DevToolsSecurityCheck() {
_classCallCheck(this, DevToolsSecurityCheck);
_get(Object.getPrototypeOf(DevToolsSecurityCheck.prototype), 'constructor', this).call(this, { autofix: true });
}
_createClass(DevToolsSecurityCheck, [{
key: 'diagnose',
value: function diagnose() {
var errMess, stdout;
return _regeneratorRuntime.async(function diagnose$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
errMess = 'DevToolsSecurity is NOT enabled!';
stdout = undefined;
context$2$0.prev = 2;
context$2$0.next = 5;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('DevToolsSecurity', []));
case 5:
stdout = context$2$0.sent.stdout;
context$2$0.next = 12;
break;
case 8:
context$2$0.prev = 8;
context$2$0.t0 = context$2$0['catch'](2);
_logger2['default'].debug(context$2$0.t0);
return context$2$0.abrupt('return', (0, _utils.nok)(errMess));
case 12:
return context$2$0.abrupt('return', stdout && stdout.match(/enabled/) ? (0, _utils.ok)('DevToolsSecurity is enabled.') : (0, _utils.nok)(errMess));
case 13:
case 'end':
return context$2$0.stop();
}
}, null, this, [[2, 8]]);
}
}, {
key: 'fix',
value: function fix() {
return _regeneratorRuntime.async(function fix$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(fixes.authorizeIosFix());
case 2:
return context$2$0.abrupt('return', context$2$0.sent);
case 3:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}]);
return DevToolsSecurityCheck;
})(_doctor.DoctorCheck);
checks.push(new DevToolsSecurityCheck());
// Authorization DB
var AuthorizationDbCheck = (function (_DoctorCheck4) {
_inherits(AuthorizationDbCheck, _DoctorCheck4);
function AuthorizationDbCheck() {
_classCallCheck(this, AuthorizationDbCheck);
_get(Object.getPrototypeOf(AuthorizationDbCheck.prototype), 'constructor', this).call(this, { autofix: true });
}
_createClass(AuthorizationDbCheck, [{
key: 'diagnose',
value: function diagnose() {
var successMess, errMess, stdout, data, rg;
return _regeneratorRuntime.async(function diagnose$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
successMess = 'The Authorization DB is set up properly.';
errMess = 'The Authorization DB is NOT set up properly.';
stdout = undefined;
context$2$0.prev = 3;
context$2$0.next = 6;
return _regeneratorRuntime.awrap((0, _teen_process.exec)('security', ['authorizationdb', 'read', 'system.privilege.taskport']));
case 6:
stdout = context$2$0.sent.stdout;
context$2$0.next = 32;
break;
case 9:
context$2$0.prev = 9;
context$2$0.t0 = context$2$0['catch'](3);
context$2$0.next = 13;
return _regeneratorRuntime.awrap(_appiumSupport.system.macOsxVersion());
case 13:
context$2$0.t1 = context$2$0.sent;
if (!(context$2$0.t1 === '10.8')) {
context$2$0.next = 30;
break;
}
data = undefined;
context$2$0.prev = 16;
context$2$0.next = 19;
return _regeneratorRuntime.awrap(_appiumSupport.fs.readFile('/etc/authorization', 'utf8'));
case 19:
data = context$2$0.sent;
context$2$0.next = 26;
break;
case 22:
context$2$0.prev = 22;
context$2$0.t2 = context$2$0['catch'](16);
_logger2['default'].debug(context$2$0.t2);
return context$2$0.abrupt('return', (0, _utils.nok)(errMess));
case 26:
rg = /<key>system.privilege.taskport<\/key>\s*\n\s*<dict>\n\s*<key>allow-root<\/key>\n\s*(<true\/>)/;
return context$2$0.abrupt('return', data && data.match(rg) ? (0, _utils.ok)(successMess) : (0, _utils.nok)(errMess));
case 30:
_logger2['default'].debug(context$2$0.t0);
return context$2$0.abrupt('return', (0, _utils.nok)(errMess));
case 32:
return context$2$0.abrupt('return', stdout && (stdout.match(/is-developer/) || stdout.match(/allow/)) ? (0, _utils.ok)(successMess) : (0, _utils.nok)(errMess));
case 33:
case 'end':
return context$2$0.stop();
}
}, null, this, [[3, 9], [16, 22]]);
}
}, {
key: 'fix',
value: function fix() {
return _regeneratorRuntime.async(function fix$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(fixes.authorizeIosFix());
case 2:
return context$2$0.abrupt('return', context$2$0.sent);
case 3:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}]);
return AuthorizationDbCheck;
})(_doctor.DoctorCheck);
checks.push(new AuthorizationDbCheck());
// Node Binary
var NodeBinaryCheck = (function (_DoctorCheck5) {
_inherits(NodeBinaryCheck, _DoctorCheck5);
function NodeBinaryCheck() {
_classCallCheck(this, NodeBinaryCheck);
_get(Object.getPrototypeOf(NodeBinaryCheck.prototype), 'constructor', this).apply(this, arguments);
}
_createClass(NodeBinaryCheck, [{
key: 'diagnose',
value: function diagnose() {
var nodePath;
return _regeneratorRuntime.async(function diagnose$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return _regeneratorRuntime.awrap(_nodeDetector2['default'].detect());
case 2:
nodePath = context$2$0.sent;
return context$2$0.abrupt('return', nodePath ? (0, _utils.ok)('The Node.js binary was found at: ' + nodePath) : (0, _utils.nok)('The Node.js binary was NOT found!'));
case 4:
case 'end':
return context$2$0.stop();
}
}, null, this);
}
}, {
key: 'fix',
value: function fix() {
return 'Manually setup Node.js.';
}
}]);
return NodeBinaryCheck;
})(_doctor.DoctorCheck);
checks.push(new NodeBinaryCheck());
checks.push(new _env2['default']('HOME'));
exports.fixes = fixes;
exports.XcodeCheck = XcodeCheck;
exports.XcodeCmdLineToolsCheck = XcodeCmdLineToolsCheck;
exports.DevToolsSecurityCheck = DevToolsSecurityCheck;
exports.AuthorizationDbCheck = AuthorizationDbCheck;
exports.NodeBinaryCheck = NodeBinaryCheck;
exports['default'] = checks;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9pb3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O3FCQUFtQyxTQUFTOzs2QkFDakIsZ0JBQWdCOzs0QkFDdEIsY0FBYzs7c0JBQ1AsVUFBVTs7c0JBQ3RCLFVBQVU7Ozs7NEJBRUQsaUJBQWlCOzs7O3NCQUNwQixVQUFVOzttQkFDRCxPQUFPOzs7O0FBR3RDLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztBQUNoQixJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7Ozs7SUFHVCxVQUFVO1lBQVYsVUFBVTs7V0FBVixVQUFVOzBCQUFWLFVBQVU7OytCQUFWLFVBQVU7OztlQUFWLFVBQVU7O1dBQ0E7VUFDUixTQUFTLFFBRU4sTUFBTTs7Ozs7QUFGVCxxQkFBUzs7OzZDQUVVLHdCQUFLLGNBQWMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDOzs7O0FBQXRELGtCQUFNLFFBQU4sTUFBTTs7QUFDWCxxQkFBUyxHQUFHLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQSxDQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7Ozs7Ozs7Z0RBRXRDLGdCQUFJLHlCQUF5QixDQUFDOzs7NkJBRWhDLFNBQVM7Ozs7Ozs7OzZDQUFVLGtCQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Ozs7Ozs7Ozs7OzZCQUFHLDJDQUE2QixTQUFTLENBQUc7Ozs7OzZCQUN4RixnREFBa0MsU0FBUyxTQUFNOzs7Ozs7Ozs7O0tBQ3BEOzs7V0FFUzs7OztnREFDRCx5QkFBeUI7Ozs7Ozs7S0FDakM7OztTQWZHLFVBQVU7OztBQWlCaEIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDLENBQUM7Ozs7SUFHeEIsc0JBQXNCO1lBQXRCLHNCQUFzQjs7QUFDZixXQURQLHNCQUFzQixHQUNaOzBCQURWLHNCQUFzQjs7QUFFeEIsK0JBRkUsc0JBQXNCLDZDQUVsQixFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUMsRUFBRTtHQUN4Qjs7ZUFIRyxzQkFBc0I7O1dBS1g7VUFDUCxPQUFPLEVBQ1QsT0FBTyxFQUNQLE1BQU07Ozs7QUFGSixtQkFBTyxHQUFHLDZDQUE2Qzs7NkNBQ3pDLHNCQUFPLGFBQWEsRUFBRTs7Ozs7cUNBQUssTUFBTTs7Ozs7NkJBQUcsaUNBQWlDOzs7Ozs2QkFBRyxtQ0FBbUM7OztBQUEzSCxtQkFBTztBQUNQLGtCQUFNOzs7NkNBRVEsd0JBQUssU0FBUyxFQUFFLGlCQUFlLE9BQU8sQ0FBRyxDQUFDOzs7QUFBMUQsa0JBQU0sb0JBQXNELE1BQU07Ozs7Ozs7O0FBRWxFLGdDQUFJLEtBQUssZ0JBQUssQ0FBQztnREFDUixnQkFBSSxPQUFPLENBQUM7OztnREFFZCxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFHLGVBQUcseUNBQXlDLENBQUMsR0FDakYsZ0JBQUksT0FBTyxDQUFDOzs7Ozs7O0tBQ2Y7OztXQUVTO1VBRUosS0FBSzs7OztBQURULGdDQUFJLElBQUksa0VBQWtFLENBQUM7OzZDQUN6RCxvQkFBTzs7O0FBQXJCLGlCQUFLOztrQkFDTCxLQUFLLEtBQUssS0FBSyxDQUFBOzs7Ozs7NkNBQ1gsd0JBQUssY0FBYyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7Ozs7Ozs7QUFFekMsZ0NBQUksSUFBSSxDQUFDLG1EQUFtRCxDQUFDLENBQUM7a0JBQ3hELDZCQUFxQjs7Ozs7OztLQUU5Qjs7O1NBNUJHLHNCQUFzQjs7O0FBK0I1QixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksc0JBQXNCLEVBQUUsQ0FBQyxDQUFDOzs7QUFHMUMsS0FBSyxDQUFDLGVBQWUsR0FBRztNQUVsQixLQUFLOzs7O0FBRFQsNEJBQUksSUFBSSw0Q0FBNEMsQ0FBQzs7eUNBQ25DLG9CQUFPOzs7QUFBckIsYUFBSzs7Y0FDTCxLQUFLLEtBQUssS0FBSyxDQUFBOzs7Ozs7eUNBQ1gsdUJBQVc7Ozs7Ozs7QUFFakIsNEJBQUksSUFBSSxDQUFDLDJEQUEyRCxDQUFDLENBQUM7Y0FDaEUsNkJBQXFCOzs7Ozs7O0NBRTlCLENBQUM7Ozs7SUFHSSxxQkFBcUI7WUFBckIscUJBQXFCOztBQUNkLFdBRFAscUJBQXFCLEdBQ1g7MEJBRFYscUJBQXFCOztBQUV2QiwrQkFGRSxxQkFBcUIsNkNBRWpCLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQyxFQUFFO0dBQ3hCOztlQUhHLHFCQUFxQjs7V0FLVjtVQUNQLE9BQU8sRUFDVCxNQUFNOzs7O0FBREosbUJBQU8sR0FBRyxrQ0FBa0M7QUFDOUMsa0JBQU07Ozs2Q0FFUSx3QkFBSyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7OztBQUE1QyxrQkFBTSxvQkFBd0MsTUFBTTs7Ozs7Ozs7QUFFcEQsZ0NBQUksS0FBSyxnQkFBSyxDQUFDO2dEQUNSLGdCQUFJLE9BQU8sQ0FBQzs7O2dEQUVkLE1BQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLGVBQUcsOEJBQThCLENBQUMsR0FDekUsZ0JBQUksT0FBTyxDQUFDOzs7Ozs7O0tBQ2pCOzs7V0FDUzs7Ozs7NkNBQ0ssS0FBSyxDQUFDLGVBQWUsRUFBRTs7Ozs7Ozs7OztLQUNyQzs7O1NBbkJHLHFCQUFxQjs7O0FBcUIzQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUkscUJBQXFCLEVBQUUsQ0FBQyxDQUFDOzs7O0lBR25DLG9CQUFvQjtZQUFwQixvQkFBb0I7O0FBQ2IsV0FEUCxvQkFBb0IsR0FDVjswQkFEVixvQkFBb0I7O0FBRXRCLCtCQUZFLG9CQUFvQiw2Q0FFaEIsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFDLEVBQUU7R0FDeEI7O2VBSEcsb0JBQW9COztXQUtUO1VBQ1AsV0FBVyxFQUNYLE9BQU8sRUFDVCxNQUFNLEVBS0YsSUFBSSxFQU9KLEVBQUU7Ozs7QUFkSix1QkFBVyxHQUFHLDBDQUEwQztBQUN4RCxtQkFBTyxHQUFHLDhDQUE4QztBQUMxRCxrQkFBTTs7OzZDQUVRLHdCQUFLLFVBQVUsRUFBRSxDQUFDLGlCQUFpQixFQUFFLE1BQU0sRUFBRSwyQkFBMkIsQ0FBQyxDQUFDOzs7QUFBMUYsa0JBQU0sb0JBQXNGLE1BQU07Ozs7Ozs7OzZDQUV4RixzQkFBTyxhQUFhLEVBQUU7Ozs7O3FDQUFLLE1BQU07Ozs7O0FBQ3JDLGdCQUFJOzs7NkNBRU8sa0JBQUcsUUFBUSxDQUFDLG9CQUFvQixFQUFFLE1BQU0sQ0FBQzs7O0FBQXRELGdCQUFJOzs7Ozs7OztBQUVKLGdDQUFJLEtBQUssZ0JBQUssQ0FBQztnREFDUixnQkFBSSxPQUFPLENBQUM7OztBQUVqQixjQUFFLEdBQUUsK0ZBQStGO2dEQUNoRyxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxlQUFHLFdBQVcsQ0FBQyxHQUFHLGdCQUFJLE9BQU8sQ0FBQzs7O0FBRTlELGdDQUFJLEtBQUssZ0JBQUssQ0FBQztnREFDUixnQkFBSSxPQUFPLENBQUM7OztnREFHaEIsTUFBTSxLQUFLLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQSxBQUFDLEdBQ3JFLGVBQUcsV0FBVyxDQUFDLEdBQUcsZ0JBQUksT0FBTyxDQUFDOzs7Ozs7O0tBQ2xDOzs7V0FDUzs7Ozs7NkNBQ0ssS0FBSyxDQUFDLGVBQWUsRUFBRTs7Ozs7Ozs7OztLQUNyQzs7O1NBaENHLG9CQUFvQjs7O0FBa0MxQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksb0JBQW9CLEVBQUUsQ0FBQyxDQUFDOzs7O0lBR2xDLGVBQWU7WUFBZixlQUFlOztXQUFmLGVBQWU7MEJBQWYsZUFBZTs7K0JBQWYsZUFBZTs7O2VBQWYsZUFBZTs7V0FDSjtVQUNULFFBQVE7Ozs7OzZDQUFTLDBCQUFhLE1BQU0sRUFBRTs7O0FBQXRDLG9CQUFRO2dEQUNMLFFBQVEsR0FBRyxxREFBdUMsUUFBUSxDQUFHLEdBQ2xFLGdCQUFJLG1DQUFtQyxDQUFDOzs7Ozs7O0tBQzNDOzs7V0FFRSxlQUFHO0FBQ0osdUNBQWlDO0tBQ2xDOzs7U0FURyxlQUFlOzs7QUFXckIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQWUsRUFBRSxDQUFDLENBQUM7O0FBRW5DLE1BQU0sQ0FBQyxJQUFJLENBQUMscUJBQXVCLE1BQU0sQ0FBQyxDQUFDLENBQUM7O1FBRW5DLEtBQUssR0FBTCxLQUFLO1FBQUUsVUFBVSxHQUFWLFVBQVU7UUFBRSxzQkFBc0IsR0FBdEIsc0JBQXNCO1FBQUUscUJBQXFCLEdBQXJCLHFCQUFxQjtRQUNoRSxvQkFBb0IsR0FBcEIsb0JBQW9CO1FBQUUsZUFBZSxHQUFmLGVBQWU7cUJBQy9CLE1BQU0iLCJmaWxlIjoibGliL2lvcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG9rLCBub2ssIGF1dGhvcml6ZSB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgZnMsIHN5c3RlbSB9IGZyb20gJ2FwcGl1bS1zdXBwb3J0JztcbmltcG9ydCB7IGV4ZWMgfSBmcm9tICd0ZWVuX3Byb2Nlc3MnO1xuaW1wb3J0IHsgRG9jdG9yQ2hlY2sgfSBmcm9tICcuL2RvY3Rvcic7XG5pbXBvcnQgbG9nIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7IEZpeFNraXBwZWRFcnJvciB9IGZyb20gJy4vZG9jdG9yJztcbmltcG9ydCBOb2RlRGV0ZWN0b3IgZnJvbSAnLi9ub2RlLWRldGVjdG9yJztcbmltcG9ydCB7IGZpeEl0IH0gZnJvbSAnLi9wcm9tcHQnO1xuaW1wb3J0IEVudlZhckFuZFBhdGhDaGVjayBmcm9tICcuL2Vudic7XG5cblxubGV0IGNoZWNrcyA9IFtdO1xubGV0IGZpeGVzID0ge307XG5cbi8vIENoZWNrIGZvciBYY29kZS5cbmNsYXNzIFhjb2RlQ2hlY2sgZXh0ZW5kcyBEb2N0b3JDaGVjayB7XG4gIGFzeW5jIGRpYWdub3NlKCkge1xuICAgIGxldCB4Y29kZVBhdGg7XG4gICAgdHJ5IHtcbiAgICAgIGxldCB7c3Rkb3V0fSA9IGF3YWl0IGV4ZWMoJ3hjb2RlLXNlbGVjdCcsIFsnLS1wcmludC1wYXRoJ10pO1xuICAgICAgeGNvZGVQYXRoID0gKHN0ZG91dCB8fCAnJykucmVwbGFjZShcIlxcblwiLCBcIlwiKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiBub2soJ1hjb2RlIGlzIE5PVCBpbnN0YWxsZWQhJyk7XG4gICAgfVxuICAgIHJldHVybiB4Y29kZVBhdGggJiYgYXdhaXQgZnMuZXhpc3RzKHhjb2RlUGF0aCkgPyBvayhgWGNvZGUgaXMgaW5zdGFsbGVkIGF0OiAke3hjb2RlUGF0aH1gKSA6XG4gICAgICBub2soYFhjb2RlIGNhbm5vdCBiZSBmb3VuZCBhdCBcXCcke3hjb2RlUGF0aH1cXCchYCk7XG4gIH1cblxuICBhc3luYyBmaXggKCkge1xuICAgIHJldHVybiAnTWFudWFsbHkgaW5zdGFsbCBYY29kZS4nO1xuICB9XG59XG5jaGVja3MucHVzaChuZXcgWGNvZGVDaGVjaygpKTtcblxuLy8gQ2hlY2sgZm9yIFhjb2RlIENvbW1hbmQgTGluZSBUb29scy5cbmNsYXNzIFhjb2RlQ21kTGluZVRvb2xzQ2hlY2sgZXh0ZW5kcyBEb2N0b3JDaGVjayB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKHthdXRvZml4OiB0cnVlfSk7XG4gIH1cblxuICBhc3luYyBkaWFnbm9zZSAoKSB7XG4gICAgY29uc3QgZXJyTWVzcyA9ICdYY29kZSBDb21tYW5kIExpbmUgVG9vbHMgYXJlIE5PVCBpbnN0YWxsZWQhJztcbiAgICBsZXQgcGtnTmFtZSA9IGF3YWl0IHN5c3RlbS5tYWNPc3hWZXJzaW9uKCkgPT09ICcxMC44JyA/ICdjb20uYXBwbGUucGtnLkRldmVsb3BlclRvb2xzQ0xJJyA6ICdjb20uYXBwbGUucGtnLkNMVG9vbHNfRXhlY3V0YWJsZXMnO1xuICAgIGxldCBzdGRvdXQ7XG4gICAgdHJ5IHtcbiAgICAgIHN0ZG91dCA9IChhd2FpdCBleGVjKCdwa2d1dGlsJywgW2AtLXBrZy1pbmZvPSR7cGtnTmFtZX1gXSkpLnN0ZG91dDtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZy5kZWJ1ZyhlcnIpO1xuICAgICAgcmV0dXJuIG5vayhlcnJNZXNzKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0ZG91dC5tYXRjaCgvaW5zdGFsbC10aW1lLykgPyBvaygnWGNvZGUgQ29tbWFuZCBMaW5lIFRvb2xzIGFyZSBpbnN0YWxsZWQuJykgOlxuICAgICAgbm9rKGVyck1lc3MpO1xuICB9XG5cbiAgYXN5bmMgZml4ICgpIHtcbiAgICBsb2cuaW5mbyhgVGhlIGZvbGxvd2luZyBjb21tYW5kIG5lZWQgYmUgZXhlY3V0ZWQ6IHhjb2RlLXNlbGVjdCAtLWluc3RhbGxgKTtcbiAgICBsZXQgeWVzbm8gPSBhd2FpdCBmaXhJdCgpO1xuICAgIGlmICh5ZXNubyA9PT0gJ3llcycpIHtcbiAgICAgIGF3YWl0IGV4ZWMoJ3hjb2RlLXNlbGVjdCcsIFsnLS1pbnN0YWxsJ10pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cuaW5mbygnU2tpcHBpbmcgeW91IHdpbGwgbmVlZCB0byBpbnN0YWxsIFhjb2RlIG1hbnVhbGx5LicpO1xuICAgICAgdGhyb3cgbmV3IEZpeFNraXBwZWRFcnJvcigpO1xuICAgIH1cbiAgfVxufVxuXG5jaGVja3MucHVzaChuZXcgWGNvZGVDbWRMaW5lVG9vbHNDaGVjaygpKTtcblxuLy8gQXV0b21hdGljYWxseSBydW4gYXV0aG9yaXplIGlPUyBpZiByZXF1ZXN0ZWRcbmZpeGVzLmF1dGhvcml6ZUlvc0ZpeCA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgbG9nLmluZm8oYFRoZSBhdXRob3JpemUgaU9TIHNjcmlwdCBuZWVkIHRvIGJlIHJ1bi5gKTtcbiAgbGV0IHllc25vID0gYXdhaXQgZml4SXQoKTtcbiAgaWYgKHllc25vID09PSAneWVzJykge1xuICAgIGF3YWl0IGF1dGhvcml6ZSgpO1xuICB9IGVsc2Uge1xuICAgIGxvZy5pbmZvKCdTa2lwcGluZyB5b3Ugd2lsbCBuZWVkIHRvIHJ1biB0aGUgYXV0aG9yaXplIGlPUyBtYW51YWxseS4nKTtcbiAgICB0aHJvdyBuZXcgRml4U2tpcHBlZEVycm9yKCk7XG4gIH1cbn07XG5cbi8vIERldiBUb29scyBTZWN1cml0eVxuY2xhc3MgRGV2VG9vbHNTZWN1cml0eUNoZWNrIGV4dGVuZHMgRG9jdG9yQ2hlY2sge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcih7YXV0b2ZpeDogdHJ1ZX0pO1xuICB9XG5cbiAgYXN5bmMgZGlhZ25vc2UgKCkge1xuICAgIGNvbnN0IGVyck1lc3MgPSAnRGV2VG9vbHNTZWN1cml0eSBpcyBOT1QgZW5hYmxlZCEnO1xuICAgIGxldCBzdGRvdXQ7XG4gICAgdHJ5IHtcbiAgICAgIHN0ZG91dCA9IChhd2FpdCBleGVjKCdEZXZUb29sc1NlY3VyaXR5JywgW10pKS5zdGRvdXQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2cuZGVidWcoZXJyKTtcbiAgICAgIHJldHVybiBub2soZXJyTWVzcyk7XG4gICAgfVxuICAgIHJldHVybiBzdGRvdXQgJiYgc3Rkb3V0Lm1hdGNoKC9lbmFibGVkLykgPyBvaygnRGV2VG9vbHNTZWN1cml0eSBpcyBlbmFibGVkLicpXG4gICAgICA6IG5vayhlcnJNZXNzKTtcbiAgfVxuICBhc3luYyBmaXggKCkge1xuICAgIHJldHVybiBhd2FpdCBmaXhlcy5hdXRob3JpemVJb3NGaXgoKTtcbiAgfVxufVxuY2hlY2tzLnB1c2gobmV3IERldlRvb2xzU2VjdXJpdHlDaGVjaygpKTtcblxuLy8gQXV0aG9yaXphdGlvbiBEQlxuY2xhc3MgQXV0aG9yaXphdGlvbkRiQ2hlY2sgZXh0ZW5kcyBEb2N0b3JDaGVjayB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKHthdXRvZml4OiB0cnVlfSk7XG4gIH1cblxuICBhc3luYyBkaWFnbm9zZSAoKSB7XG4gICAgY29uc3Qgc3VjY2Vzc01lc3MgPSAnVGhlIEF1dGhvcml6YXRpb24gREIgaXMgc2V0IHVwIHByb3Blcmx5Lic7XG4gICAgY29uc3QgZXJyTWVzcyA9ICdUaGUgQXV0aG9yaXphdGlvbiBEQiBpcyBOT1Qgc2V0IHVwIHByb3Blcmx5Lic7XG4gICAgbGV0IHN0ZG91dDtcbiAgICB0cnkge1xuICAgICAgc3Rkb3V0ID0gKGF3YWl0IGV4ZWMoJ3NlY3VyaXR5JywgWydhdXRob3JpemF0aW9uZGInLCAncmVhZCcsICdzeXN0ZW0ucHJpdmlsZWdlLnRhc2twb3J0J10pKS5zdGRvdXQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoYXdhaXQgc3lzdGVtLm1hY09zeFZlcnNpb24oKSA9PT0gJzEwLjgnKSB7XG4gICAgICAgIGxldCBkYXRhO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGRhdGEgPSBhd2FpdCBmcy5yZWFkRmlsZSgnL2V0Yy9hdXRob3JpemF0aW9uJywgJ3V0ZjgnKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgbG9nLmRlYnVnKGVycik7XG4gICAgICAgICAgcmV0dXJuIG5vayhlcnJNZXNzKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmcgPS88a2V5PnN5c3RlbS5wcml2aWxlZ2UudGFza3BvcnQ8XFwva2V5PlxccypcXG5cXHMqPGRpY3Q+XFxuXFxzKjxrZXk+YWxsb3ctcm9vdDxcXC9rZXk+XFxuXFxzKig8dHJ1ZVxcLz4pLztcbiAgICAgICAgcmV0dXJuIGRhdGEgJiYgZGF0YS5tYXRjaChyZykgPyBvayhzdWNjZXNzTWVzcykgOiBub2soZXJyTWVzcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2cuZGVidWcoZXJyKTtcbiAgICAgICAgcmV0dXJuIG5vayhlcnJNZXNzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0ZG91dCAmJiAoc3Rkb3V0Lm1hdGNoKC9pcy1kZXZlbG9wZXIvKSB8fCBzdGRvdXQubWF0Y2goL2FsbG93LykpID9cbiAgICAgICBvayhzdWNjZXNzTWVzcykgOiBub2soZXJyTWVzcyk7XG4gIH1cbiAgYXN5bmMgZml4ICgpIHtcbiAgICByZXR1cm4gYXdhaXQgZml4ZXMuYXV0aG9yaXplSW9zRml4KCk7XG4gIH1cbn1cbmNoZWNrcy5wdXNoKG5ldyBBdXRob3JpemF0aW9uRGJDaGVjaygpKTtcblxuLy8gTm9kZSBCaW5hcnlcbmNsYXNzIE5vZGVCaW5hcnlDaGVjayBleHRlbmRzIERvY3RvckNoZWNrIHtcbiAgYXN5bmMgZGlhZ25vc2UgKCkge1xuICAgIGxldCBub2RlUGF0aCA9IGF3YWl0IE5vZGVEZXRlY3Rvci5kZXRlY3QoKTtcbiAgICByZXR1cm4gbm9kZVBhdGggPyBvayhgVGhlIE5vZGUuanMgYmluYXJ5IHdhcyBmb3VuZCBhdDogJHtub2RlUGF0aH1gKSA6XG4gICAgICBub2soJ1RoZSBOb2RlLmpzIGJpbmFyeSB3YXMgTk9UIGZvdW5kIScpO1xuICB9XG5cbiAgZml4KCkge1xuICAgIHJldHVybiBgTWFudWFsbHkgc2V0dXAgTm9kZS5qcy5gO1xuICB9XG59XG5jaGVja3MucHVzaChuZXcgTm9kZUJpbmFyeUNoZWNrKCkpO1xuXG5jaGVja3MucHVzaChuZXcgRW52VmFyQW5kUGF0aENoZWNrKCdIT01FJykpO1xuXG5leHBvcnQgeyBmaXhlcywgWGNvZGVDaGVjaywgWGNvZGVDbWRMaW5lVG9vbHNDaGVjaywgRGV2VG9vbHNTZWN1cml0eUNoZWNrLFxuICAgICAgICAgQXV0aG9yaXphdGlvbkRiQ2hlY2ssIE5vZGVCaW5hcnlDaGVjayB9O1xuZXhwb3J0IGRlZmF1bHQgY2hlY2tzO1xuIl19