UNPKG

appium-doctor

Version:

Test environment for fitness to run Appium

369 lines (286 loc) 18.2 kB
'use strict'; 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 _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 _logger = require('./logger'); var _logger2 = _interopRequireDefault(_logger); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var NODE_COMMON_PATHS = [process.env.NODE_BIN, '/usr/local/bin/node', '/opt/local/bin/node']; // Look for node var NodeDetector = (function () { function NodeDetector() { _classCallCheck(this, NodeDetector); } _createClass(NodeDetector, null, [{ key: 'retrieveInCommonPlaces', value: function retrieveInCommonPlaces() { var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, p; return _regeneratorRuntime.async(function retrieveInCommonPlaces$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; context$2$0.prev = 3; _iterator = _getIterator(NODE_COMMON_PATHS); case 5: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { context$2$0.next = 18; break; } p = _step.value; context$2$0.t0 = p; if (!context$2$0.t0) { context$2$0.next = 12; break; } context$2$0.next = 11; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(p)); case 11: context$2$0.t0 = context$2$0.sent; case 12: if (!context$2$0.t0) { context$2$0.next = 15; break; } _logger2['default'].debug('Node binary found at common place: ' + p); return context$2$0.abrupt('return', p); case 15: _iteratorNormalCompletion = true; context$2$0.next = 5; break; case 18: context$2$0.next = 24; break; case 20: context$2$0.prev = 20; context$2$0.t1 = context$2$0['catch'](3); _didIteratorError = true; _iteratorError = context$2$0.t1; case 24: context$2$0.prev = 24; context$2$0.prev = 25; if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } case 27: context$2$0.prev = 27; if (!_didIteratorError) { context$2$0.next = 30; break; } throw _iteratorError; case 30: return context$2$0.finish(27); case 31: return context$2$0.finish(24); case 32: _logger2['default'].debug('Node binary wasn\'t found at common places.'); return context$2$0.abrupt('return', null); case 34: case 'end': return context$2$0.stop(); } }, null, this, [[3, 20, 24, 32], [25,, 27, 31]]); } }, { key: 'retrieveUsingWhichCommand', value: function retrieveUsingWhichCommand() { var stdout, nodePath; return _regeneratorRuntime.async(function retrieveUsingWhichCommand$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: stdout = undefined; context$2$0.prev = 1; context$2$0.next = 4; return _regeneratorRuntime.awrap((0, _teen_process.exec)('which', ['node'])); case 4: stdout = context$2$0.sent.stdout; context$2$0.next = 9; break; case 7: context$2$0.prev = 7; context$2$0.t0 = context$2$0['catch'](1); case 9: nodePath = stdout.replace("\n", ""); context$2$0.next = 12; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(nodePath)); case 12: if (!context$2$0.sent) { context$2$0.next = 17; break; } _logger2['default'].debug('Node binary found using which command at: ' + nodePath); return context$2$0.abrupt('return', nodePath); case 17: _logger2['default'].debug('Node binary not found using the which command.'); return context$2$0.abrupt('return', null); case 19: case 'end': return context$2$0.stop(); } }, null, this, [[1, 7]]); } }, { key: 'retrieveUsingAppleScript', value: function retrieveUsingAppleScript() { var appScript, stdout, nodePath; return _regeneratorRuntime.async(function retrieveUsingAppleScript$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: appScript = ['try', ' set appiumIsRunning to false', ' tell application "System Events"', ' set appiumIsRunning to name of every process contains "Appium"', ' end tell', ' if appiumIsRunning then', ' tell application "Appium" to return node path', ' end if', 'end try', 'return "NULL"'].join("\n"); stdout = undefined; context$2$0.prev = 2; context$2$0.next = 5; return _regeneratorRuntime.awrap((0, _teen_process.exec)('osascript', ['-e', appScript])); case 5: stdout = context$2$0.sent.stdout; context$2$0.next = 10; break; case 8: context$2$0.prev = 8; context$2$0.t0 = context$2$0['catch'](2); case 10: nodePath = stdout.replace("\n", ""); context$2$0.next = 13; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(nodePath)); case 13: if (!context$2$0.sent) { context$2$0.next = 18; break; } _logger2['default'].debug('Node binary found using AppleScript at: ' + nodePath); return context$2$0.abrupt('return', nodePath); case 18: _logger2['default'].debug('Node binary not found using AppleScript.'); return context$2$0.abrupt('return', null); case 20: case 'end': return context$2$0.stop(); } }, null, this, [[2, 8]]); } }, { key: 'retrieveUsingAppiumConfigFile', value: function retrieveUsingAppiumConfigFile() { var jsonobj, appiumConfigPath; return _regeneratorRuntime.async(function retrieveUsingAppiumConfigFile$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: jsonobj = undefined; context$2$0.prev = 1; appiumConfigPath = _path2['default'].resolve(__dirname, '..', '..', '.appiumconfig.json'); context$2$0.next = 5; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(appiumConfigPath)); case 5: if (!context$2$0.sent) { context$2$0.next = 11; break; } context$2$0.t0 = JSON; context$2$0.next = 9; return _regeneratorRuntime.awrap(_appiumSupport.fs.readFile(appiumConfigPath, 'utf8')); case 9: context$2$0.t1 = context$2$0.sent; jsonobj = context$2$0.t0.parse.call(context$2$0.t0, context$2$0.t1); case 11: context$2$0.next = 15; break; case 13: context$2$0.prev = 13; context$2$0.t2 = context$2$0['catch'](1); case 15: context$2$0.t3 = jsonobj && jsonobj.node_bin; if (!context$2$0.t3) { context$2$0.next = 20; break; } context$2$0.next = 19; return _regeneratorRuntime.awrap(_appiumSupport.fs.exists(jsonobj.node_bin)); case 19: context$2$0.t3 = context$2$0.sent; case 20: if (!context$2$0.t3) { context$2$0.next = 25; break; } _logger2['default'].debug('Node binary found using .appiumconfig.json at: ' + jsonobj.node_bin); return context$2$0.abrupt('return', jsonobj.node_bin); case 25: _logger2['default'].debug('Node binary not found in the .appiumconfig.json file.'); return context$2$0.abrupt('return', null); case 27: case 'end': return context$2$0.stop(); } }, null, this, [[1, 13]]); } }, { key: 'detect', value: function detect() { var nodePath; return _regeneratorRuntime.async(function detect$(context$2$0) { while (1) switch (context$2$0.prev = context$2$0.next) { case 0: context$2$0.next = 2; return _regeneratorRuntime.awrap(this.retrieveInCommonPlaces()); case 2: context$2$0.t2 = context$2$0.sent; if (context$2$0.t2) { context$2$0.next = 7; break; } context$2$0.next = 6; return _regeneratorRuntime.awrap(NodeDetector.retrieveUsingWhichCommand()); case 6: context$2$0.t2 = context$2$0.sent; case 7: context$2$0.t1 = context$2$0.t2; if (context$2$0.t1) { context$2$0.next = 12; break; } context$2$0.next = 11; return _regeneratorRuntime.awrap(NodeDetector.retrieveUsingAppleScript()); case 11: context$2$0.t1 = context$2$0.sent; case 12: context$2$0.t0 = context$2$0.t1; if (context$2$0.t0) { context$2$0.next = 17; break; } context$2$0.next = 16; return _regeneratorRuntime.awrap(NodeDetector.retrieveUsingAppiumConfigFile()); case 16: context$2$0.t0 = context$2$0.sent; case 17: nodePath = context$2$0.t0; if (!nodePath) { context$2$0.next = 22; break; } return context$2$0.abrupt('return', nodePath); case 22: _logger2['default'].warn('The node binary could not be found.'); return context$2$0.abrupt('return', null); case 24: case 'end': return context$2$0.stop(); } }, null, this); } }]); return NodeDetector; })(); exports['default'] = NodeDetector; module.exports = exports['default']; //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9ub2RlLWRldGVjdG9yLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7NkJBQW1CLGdCQUFnQjs7NEJBQ2QsY0FBYzs7c0JBQ25CLFVBQVU7Ozs7b0JBQ1QsTUFBTTs7OztBQUV2QixJQUFNLGlCQUFpQixHQUFHLENBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUNwQixxQkFBcUIsRUFDckIscUJBQXFCLENBQ3RCLENBQUM7Ozs7SUFHSSxZQUFZO1dBQVosWUFBWTswQkFBWixZQUFZOzs7ZUFBWixZQUFZOztXQUNvQjswRkFDekIsQ0FBQzs7Ozs7Ozs7O3FDQUFJLGlCQUFpQjs7Ozs7Ozs7QUFBdEIsYUFBQzs2QkFDSixDQUFDOzs7Ozs7Ozs2Q0FBVSxrQkFBRyxNQUFNLENBQUMsQ0FBQyxDQUFDOzs7Ozs7Ozs7OztBQUN6QixnQ0FBSSxLQUFLLHlDQUF1QyxDQUFDLENBQUcsQ0FBQztnREFDOUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR1osZ0NBQUksS0FBSyxDQUFDLDZDQUE2QyxDQUFDLENBQUM7Z0RBQ2xELElBQUk7Ozs7Ozs7S0FDWjs7O1dBRXNDO1VBQ2pDLE1BQU0sRUFJTixRQUFROzs7O0FBSlIsa0JBQU07Ozs2Q0FFUSx3QkFBSyxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQzs7O0FBQXZDLGtCQUFNLG9CQUFtQyxNQUFNOzs7Ozs7Ozs7QUFFN0Msb0JBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7OzZDQUM3QixrQkFBRyxNQUFNLENBQUMsUUFBUSxDQUFDOzs7Ozs7OztBQUMzQixnQ0FBSSxLQUFLLGdEQUE4QyxRQUFRLENBQUcsQ0FBQztnREFDNUQsUUFBUTs7O0FBRWYsZ0NBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7Z0RBQ3JELElBQUk7Ozs7Ozs7S0FFZDs7O1dBRXFDO1VBQ2hDLFNBQVMsRUFZVCxNQUFNLEVBSU4sUUFBUTs7OztBQWhCUixxQkFBUyxHQUFHLENBQ2QsS0FBSyxFQUNILGdDQUFnQyxFQUNoQyxvQ0FBb0MsRUFDcEMsb0VBQW9FLEVBQ3BFLFlBQVksRUFDWiwyQkFBMkIsRUFDM0IsbURBQW1ELEVBQ25ELFVBQVUsRUFDVixTQUFTLEVBQ1QsZUFBZSxDQUNsQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDUixrQkFBTTs7OzZDQUVRLHdCQUFLLFdBQVcsRUFBRSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQzs7O0FBQXBELGtCQUFNLG9CQUFnRCxNQUFNOzs7Ozs7Ozs7QUFFMUQsb0JBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7OzZDQUM3QixrQkFBRyxNQUFNLENBQUMsUUFBUSxDQUFDOzs7Ozs7OztBQUMzQixnQ0FBSSxLQUFLLDhDQUE0QyxRQUFRLENBQUcsQ0FBQztnREFDMUQsUUFBUTs7O0FBRWYsZ0NBQUksS0FBSyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7Z0RBQy9DLElBQUk7Ozs7Ozs7S0FFZDs7O1dBRTBDO1VBQ3JDLE9BQU8sRUFFTCxnQkFBZ0I7Ozs7QUFGbEIsbUJBQU87O0FBRUwsNEJBQWdCLEdBQUcsa0JBQUssT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixDQUFDOzs2Q0FDdEUsa0JBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDOzs7Ozs7Ozs2QkFDekIsSUFBSTs7NkNBQWEsa0JBQUcsUUFBUSxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQzs7OztBQUFoRSxtQkFBTyxrQkFBUSxLQUFLOzs7Ozs7Ozs7Ozs2QkFHcEIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxRQUFROzs7Ozs7Ozs2Q0FBVSxrQkFBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQzs7Ozs7Ozs7Ozs7QUFDbEUsZ0NBQUksS0FBSyxxREFBbUQsT0FBTyxDQUFDLFFBQVEsQ0FBRyxDQUFDO2dEQUN6RSxPQUFPLENBQUMsUUFBUTs7O0FBRXZCLGdDQUFJLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO2dEQUM1RCxJQUFJOzs7Ozs7O0tBRWQ7OztXQUVtQjtVQUNkLFFBQVE7Ozs7OzZDQUFTLElBQUksQ0FBQyxzQkFBc0IsRUFBRTs7Ozs7Ozs7Ozs7NkNBQzFDLFlBQVksQ0FBQyx5QkFBeUIsRUFBRTs7Ozs7Ozs7Ozs7Ozs7NkNBQ3hDLFlBQVksQ0FBQyx3QkFBd0IsRUFBRTs7Ozs7Ozs7Ozs7Ozs7NkNBQ3ZDLFlBQVksQ0FBQyw2QkFBNkIsRUFBRTs7Ozs7O0FBSGhELG9CQUFROztpQkFJUixRQUFROzs7OztnREFDSCxRQUFROzs7QUFFZixnQ0FBSSxJQUFJLENBQUMscUNBQXFDLENBQUMsQ0FBQztnREFDekMsSUFBSTs7Ozs7OztLQUVkOzs7U0FsRkcsWUFBWTs7O3FCQXFGSCxZQUFZIiwiZmlsZSI6ImxpYi9ub2RlLWRldGVjdG9yLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnMgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBsb2cgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbmNvbnN0IE5PREVfQ09NTU9OX1BBVEhTID0gW1xuICBwcm9jZXNzLmVudi5OT0RFX0JJTixcbiAgJy91c3IvbG9jYWwvYmluL25vZGUnLFxuICAnL29wdC9sb2NhbC9iaW4vbm9kZScsXG5dO1xuXG4vLyBMb29rIGZvciBub2RlXG5jbGFzcyBOb2RlRGV0ZWN0b3Ige1xuICBzdGF0aWMgYXN5bmMgcmV0cmlldmVJbkNvbW1vblBsYWNlcyAoKSB7XG4gICAgZm9yIChsZXQgcCBvZiBOT0RFX0NPTU1PTl9QQVRIUykge1xuICAgICAgaWYgKHAgJiYgYXdhaXQgZnMuZXhpc3RzKHApKSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhgTm9kZSBiaW5hcnkgZm91bmQgYXQgY29tbW9uIHBsYWNlOiAke3B9YCk7XG4gICAgICAgIHJldHVybiBwO1xuICAgICAgfVxuICAgIH1cbiAgICBsb2cuZGVidWcoJ05vZGUgYmluYXJ5IHdhc25cXCd0IGZvdW5kIGF0IGNvbW1vbiBwbGFjZXMuJyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgcmV0cmlldmVVc2luZ1doaWNoQ29tbWFuZCAoKSB7XG4gICAgbGV0IHN0ZG91dDtcbiAgICB0cnkge1xuICAgICAgc3Rkb3V0ID0gKGF3YWl0IGV4ZWMoJ3doaWNoJywgWydub2RlJ10pKS5zdGRvdXQ7XG4gICAgfSBjYXRjaCAoaWduKSB7fVxuICAgIGxldCBub2RlUGF0aCA9IHN0ZG91dC5yZXBsYWNlKFwiXFxuXCIsIFwiXCIpO1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMobm9kZVBhdGgpKSB7XG4gICAgICBsb2cuZGVidWcoYE5vZGUgYmluYXJ5IGZvdW5kIHVzaW5nIHdoaWNoIGNvbW1hbmQgYXQ6ICR7bm9kZVBhdGh9YCk7XG4gICAgICByZXR1cm4gbm9kZVBhdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZy5kZWJ1ZygnTm9kZSBiaW5hcnkgbm90IGZvdW5kIHVzaW5nIHRoZSB3aGljaCBjb21tYW5kLicpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGFzeW5jIHJldHJpZXZlVXNpbmdBcHBsZVNjcmlwdCAoKSB7XG4gICAgdmFyIGFwcFNjcmlwdCA9IFtcbiAgICAgICd0cnknXG4gICAgICAsICcgIHNldCBhcHBpdW1Jc1J1bm5pbmcgdG8gZmFsc2UnXG4gICAgICAsICcgIHRlbGwgYXBwbGljYXRpb24gXCJTeXN0ZW0gRXZlbnRzXCInXG4gICAgICAsICcgICAgc2V0IGFwcGl1bUlzUnVubmluZyB0byBuYW1lIG9mIGV2ZXJ5IHByb2Nlc3MgY29udGFpbnMgXCJBcHBpdW1cIidcbiAgICAgICwgJyAgZW5kIHRlbGwnXG4gICAgICAsICcgIGlmIGFwcGl1bUlzUnVubmluZyB0aGVuJ1xuICAgICAgLCAnICAgIHRlbGwgYXBwbGljYXRpb24gXCJBcHBpdW1cIiB0byByZXR1cm4gbm9kZSBwYXRoJ1xuICAgICAgLCAnICBlbmQgaWYnXG4gICAgICAsICdlbmQgdHJ5J1xuICAgICAgLCAncmV0dXJuIFwiTlVMTFwiJ1xuICAgIF0uam9pbihcIlxcblwiKTtcbiAgICBsZXQgc3Rkb3V0O1xuICAgIHRyeSB7XG4gICAgICBzdGRvdXQgPSAoYXdhaXQgZXhlYygnb3Nhc2NyaXB0JywgWyctZScsIGFwcFNjcmlwdF0pKS5zdGRvdXQ7XG4gICAgfSBjYXRjaCAoaWduKSB7fVxuICAgIGxldCBub2RlUGF0aCA9IHN0ZG91dC5yZXBsYWNlKFwiXFxuXCIsIFwiXCIpO1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMobm9kZVBhdGgpKSB7XG4gICAgICBsb2cuZGVidWcoYE5vZGUgYmluYXJ5IGZvdW5kIHVzaW5nIEFwcGxlU2NyaXB0IGF0OiAke25vZGVQYXRofWApO1xuICAgICAgcmV0dXJuIG5vZGVQYXRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cuZGVidWcoJ05vZGUgYmluYXJ5IG5vdCBmb3VuZCB1c2luZyBBcHBsZVNjcmlwdC4nKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhc3luYyByZXRyaWV2ZVVzaW5nQXBwaXVtQ29uZmlnRmlsZSAoKSB7XG4gICAgbGV0IGpzb25vYmo7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBhcHBpdW1Db25maWdQYXRoID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJy5hcHBpdW1jb25maWcuanNvbicpO1xuICAgICAgaWYgKGF3YWl0IGZzLmV4aXN0cyhhcHBpdW1Db25maWdQYXRoKSkge1xuICAgICAgICBqc29ub2JqID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShhcHBpdW1Db25maWdQYXRoLCAndXRmOCcpKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChpZ24pIHt9XG4gICAgaWYgKGpzb25vYmogJiYganNvbm9iai5ub2RlX2JpbiAmJiBhd2FpdCBmcy5leGlzdHMoanNvbm9iai5ub2RlX2JpbikgKSB7XG4gICAgICBsb2cuZGVidWcoYE5vZGUgYmluYXJ5IGZvdW5kIHVzaW5nIC5hcHBpdW1jb25maWcuanNvbiBhdDogJHtqc29ub2JqLm5vZGVfYmlufWApO1xuICAgICAgcmV0dXJuIGpzb25vYmoubm9kZV9iaW47XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZy5kZWJ1ZygnTm9kZSBiaW5hcnkgbm90IGZvdW5kIGluIHRoZSAuYXBwaXVtY29uZmlnLmpzb24gZmlsZS4nKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBkZXRlY3QgKCkge1xuICAgIGxldCBub2RlUGF0aCA9IGF3YWl0IHRoaXMucmV0cmlldmVJbkNvbW1vblBsYWNlcygpIHx8XG4gICAgICBhd2FpdCBOb2RlRGV0ZWN0b3IucmV0cmlldmVVc2luZ1doaWNoQ29tbWFuZCgpIHx8XG4gICAgICBhd2FpdCBOb2RlRGV0ZWN0b3IucmV0cmlldmVVc2luZ0FwcGxlU2NyaXB0KCkgfHxcbiAgICAgIGF3YWl0IE5vZGVEZXRlY3Rvci5yZXRyaWV2ZVVzaW5nQXBwaXVtQ29uZmlnRmlsZSgpO1xuICAgIGlmIChub2RlUGF0aCkge1xuICAgICAgcmV0dXJuIG5vZGVQYXRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cud2FybignVGhlIG5vZGUgYmluYXJ5IGNvdWxkIG5vdCBiZSBmb3VuZC4nKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBOb2RlRGV0ZWN0b3I7XG4iXSwic291cmNlUm9vdCI6Ii4uLy4uIn0=