UNPKG

@testim/testim-cli

Version:

Command line interface for running Testing on you CI

222 lines (178 loc) 16.7 kB
'use strict'; var _createClass = require('babel-runtime/helpers/create-class')['default']; var _classCallCheck = require('babel-runtime/helpers/class-call-check')['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 _path = require('path'); var _path2 = _interopRequireDefault(_path); var _glob = require('glob'); var _glob2 = _interopRequireDefault(_glob); var _deepmerge = require('deepmerge'); var _deepmerge2 = _interopRequireDefault(_deepmerge); var _helpersDetectSeleniumBackend = require('../helpers/detectSeleniumBackend'); var _helpersDetectSeleniumBackend2 = _interopRequireDefault(_helpersDetectSeleniumBackend); var DEFAULT_TIMEOUT = 10000; var NOOP = function NOOP() {}; var DEFAULT_CONFIGS = { specs: [], exclude: [], logLevel: 'silent', coloredLogs: true, baseUrl: null, waitforTimeout: 1000, framework: 'mocha', reporter: 'dot', mochaOpts: { timeout: DEFAULT_TIMEOUT }, jasmineNodeOpts: { defaultTimeoutInterval: DEFAULT_TIMEOUT }, updateJob: true, maxInstances: 1, onPrepare: NOOP, before: NOOP, after: NOOP, onComplete: NOOP }; var ConfigParser = (function () { function ConfigParser() { _classCallCheck(this, ConfigParser); this._config = DEFAULT_CONFIGS; this._capabilities = []; } /** * merges config file with default values * @param {String} filename path of file relative to current directory */ _createClass(ConfigParser, [{ key: 'addConfigFile', value: function addConfigFile(filename) { if (typeof filename !== 'string') { throw new Error('addConfigFile requires filepath'); } var filePath = _path2['default'].resolve(process.cwd(), filename); try { var fileConfig = require(filePath).config; if (typeof fileConfig !== 'object') { throw new Error('configuration file exports no config object'); } /** * merge capabilities */ this._capabilities = (0, _deepmerge2['default'])(this._capabilities, fileConfig.capabilities); delete fileConfig.capabilities; this._config = (0, _deepmerge2['default'])(this._config, fileConfig); /** * detect Selenium backend */ this._config = (0, _deepmerge2['default'])((0, _helpersDetectSeleniumBackend2['default'])(this._config), this._config); } catch (e) { console.error('Failed loading configuration file: ', filePath); throw e; } } /** * merge external object with config object * @param {Object} object desired object to merge into the config object */ }, { key: 'merge', value: function merge(object) { this._config = (0, _deepmerge2['default'])(this._config, object); /** * user and key could get added via cli arguments so we need to detect again * Note: cli arguments are on the right and overwrite config */ this._config = (0, _deepmerge2['default'])((0, _helpersDetectSeleniumBackend2['default'])(this._config), this._config); } /** * get excluded files from config pattern */ }, { key: 'getSpecs', value: function getSpecs(capSpecs, capExclude) { var specs = ConfigParser.getFilePaths(this._config.specs); var exclude = ConfigParser.getFilePaths(this._config.exclude); if (Array.isArray(capSpecs)) { specs = specs.concat(capSpecs); } if (Array.isArray(capExclude)) { exclude = exclude.concat(capExclude); } return specs.filter(function (spec) { return exclude.indexOf(spec) < 0; }); } /** * return configs */ }, { key: 'getConfig', value: function getConfig() { return this._config; } /** * return capabilities */ }, { key: 'getCapabilities', value: function getCapabilities(i) { if (typeof i === 'number' && this._capabilities[i]) { return this._capabilities[i]; } return this._capabilities; } /** * returns a flatten list of globed files * * @param {String[]} filenames list of files to glob * @return {String[]} list of files */ }], [{ key: 'getFilePaths', value: function getFilePaths(patterns, omitWarnings) { var files = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = _getIterator(patterns), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var pattern = _step.value; var filenames = _glob2['default'].sync(pattern); filenames = filenames.filter(function (path) { return path.slice(-3) === '.js' || path.slice(-8) === '.feature' || path.slice(-7) === '.coffee'; }); filenames = filenames.map(function (path) { return process.cwd() + '/' + path; }); if (filenames.length === 0 && !omitWarnings) { console.warn('pattern', pattern, 'did not match any file'); } files = (0, _deepmerge2['default'])(files, filenames); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator['return']) { _iterator['return'](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return files; } }]); return ConfigParser; })(); exports['default'] = ConfigParser; module.exports = exports['default']; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi91dGlscy9Db25maWdQYXJzZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7b0JBQWlCLE1BQU07Ozs7b0JBQ04sTUFBTTs7Ozt5QkFDTCxXQUFXOzs7OzRDQUVLLGtDQUFrQzs7OztBQUVwRSxJQUFNLGVBQWUsR0FBRyxLQUFLLENBQUE7QUFDN0IsSUFBTSxJQUFJLEdBQUcsU0FBUCxJQUFJLEdBQWUsRUFBRSxDQUFBO0FBQzNCLElBQU0sZUFBZSxHQUFHO0FBQ3BCLFNBQUssRUFBRSxFQUFFO0FBQ1QsV0FBTyxFQUFFLEVBQUU7QUFDWCxZQUFRLEVBQUUsUUFBUTtBQUNsQixlQUFXLEVBQUUsSUFBSTtBQUNqQixXQUFPLEVBQUUsSUFBSTtBQUNiLGtCQUFjLEVBQUUsSUFBSTtBQUNwQixhQUFTLEVBQUUsT0FBTztBQUNsQixZQUFRLEVBQUUsS0FBSztBQUNmLGFBQVMsRUFBRTtBQUNQLGVBQU8sRUFBRSxlQUFlO0tBQzNCO0FBQ0QsbUJBQWUsRUFBRTtBQUNiLDhCQUFzQixFQUFFLGVBQWU7S0FDMUM7QUFDRCxhQUFTLEVBQUUsSUFBSTtBQUNmLGdCQUFZLEVBQUUsQ0FBQztBQUNmLGFBQVMsRUFBRSxJQUFJO0FBQ2YsVUFBTSxFQUFFLElBQUk7QUFDWixTQUFLLEVBQUUsSUFBSTtBQUNYLGNBQVUsRUFBRSxJQUFJO0NBQ25CLENBQUE7O0lBRUssWUFBWTtBQUNGLGFBRFYsWUFBWSxHQUNDOzhCQURiLFlBQVk7O0FBRVYsWUFBSSxDQUFDLE9BQU8sR0FBRyxlQUFlLENBQUE7QUFDOUIsWUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUE7S0FDMUI7Ozs7Ozs7aUJBSkMsWUFBWTs7ZUFVQSx1QkFBQyxRQUFRLEVBQUU7QUFDckIsZ0JBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFO0FBQzlCLHNCQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUE7YUFDckQ7O0FBRUQsZ0JBQUksUUFBUSxHQUFHLGtCQUFLLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUE7O0FBRXBELGdCQUFJO0FBQ0Esb0JBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUE7O0FBRXpDLG9CQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtBQUNoQywwQkFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFBO2lCQUNqRTs7Ozs7QUFLRCxvQkFBSSxDQUFDLGFBQWEsR0FBRyw0QkFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUN2RSx1QkFBTyxVQUFVLENBQUMsWUFBWSxDQUFBOztBQUU5QixvQkFBSSxDQUFDLE9BQU8sR0FBRyw0QkFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFBOzs7OztBQUs5QyxvQkFBSSxDQUFDLE9BQU8sR0FBRyw0QkFBTSwrQ0FBc0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTthQUMxRSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQ1IsdUJBQU8sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEVBQUUsUUFBUSxDQUFDLENBQUE7QUFDOUQsc0JBQU0sQ0FBQyxDQUFBO2FBQ1Y7U0FDSjs7Ozs7Ozs7ZUFNSyxlQUFDLE1BQU0sRUFBRTtBQUNYLGdCQUFJLENBQUMsT0FBTyxHQUFHLDRCQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUE7Ozs7OztBQU0xQyxnQkFBSSxDQUFDLE9BQU8sR0FBRyw0QkFBTSwrQ0FBc0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtTQUMxRTs7Ozs7OztlQUtRLGtCQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUU7QUFDNUIsZ0JBQUksS0FBSyxHQUFHLFlBQVksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUN6RCxnQkFBSSxPQUFPLEdBQUcsWUFBWSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBOztBQUU3RCxnQkFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQ3pCLHFCQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQTthQUNqQztBQUNELGdCQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUU7QUFDM0IsdUJBQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFBO2FBQ3ZDOztBQUVELG1CQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBQSxJQUFJO3VCQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQzthQUFBLENBQUMsQ0FBQTtTQUN6RDs7Ozs7OztlQUtTLHFCQUFHO0FBQ1QsbUJBQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQTtTQUN0Qjs7Ozs7OztlQUtlLHlCQUFDLENBQUMsRUFBRTtBQUNoQixnQkFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRTtBQUNoRCx1QkFBTyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFBO2FBQy9COztBQUVELG1CQUFPLElBQUksQ0FBQyxhQUFhLENBQUE7U0FDNUI7Ozs7Ozs7Ozs7ZUFRbUIsc0JBQUMsUUFBUSxFQUFFLFlBQVksRUFBRTtBQUN6QyxnQkFBSSxLQUFLLEdBQUcsRUFBRSxDQUFBOzs7Ozs7O0FBRWQsa0RBQW9CLFFBQVEsNEdBQUU7d0JBQXJCLE9BQU87O0FBQ1osd0JBQUksU0FBUyxHQUFHLGtCQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTs7QUFFbEMsNkJBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQUEsSUFBSTsrQkFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssSUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLFVBQVUsSUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVM7cUJBQUEsQ0FBQyxDQUFBOztBQUVqQyw2QkFBUyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsVUFBQSxJQUFJOytCQUMxQixPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLElBQUk7cUJBQUEsQ0FBQyxDQUFBOztBQUUvQix3QkFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtBQUN6QywrQkFBTyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLHdCQUF3QixDQUFDLENBQUE7cUJBQzdEOztBQUVELHlCQUFLLEdBQUcsNEJBQU0sS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFBO2lCQUNsQzs7Ozs7Ozs7Ozs7Ozs7OztBQUVELG1CQUFPLEtBQUssQ0FBQTtTQUNmOzs7V0F2SEMsWUFBWTs7O3FCQTBISCxZQUFZIiwiZmlsZSI6IkNvbmZpZ1BhcnNlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgZ2xvYiBmcm9tICdnbG9iJ1xuaW1wb3J0IG1lcmdlIGZyb20gJ2RlZXBtZXJnZSdcblxuaW1wb3J0IGRldGVjdFNlbGVuaXVtQmFja2VuZCBmcm9tICcuLi9oZWxwZXJzL2RldGVjdFNlbGVuaXVtQmFja2VuZCdcblxuY29uc3QgREVGQVVMVF9USU1FT1VUID0gMTAwMDBcbmNvbnN0IE5PT1AgPSBmdW5jdGlvbiAoKSB7fVxuY29uc3QgREVGQVVMVF9DT05GSUdTID0ge1xuICAgIHNwZWNzOiBbXSxcbiAgICBleGNsdWRlOiBbXSxcbiAgICBsb2dMZXZlbDogJ3NpbGVudCcsXG4gICAgY29sb3JlZExvZ3M6IHRydWUsXG4gICAgYmFzZVVybDogbnVsbCxcbiAgICB3YWl0Zm9yVGltZW91dDogMTAwMCxcbiAgICBmcmFtZXdvcms6ICdtb2NoYScsXG4gICAgcmVwb3J0ZXI6ICdkb3QnLFxuICAgIG1vY2hhT3B0czoge1xuICAgICAgICB0aW1lb3V0OiBERUZBVUxUX1RJTUVPVVRcbiAgICB9LFxuICAgIGphc21pbmVOb2RlT3B0czoge1xuICAgICAgICBkZWZhdWx0VGltZW91dEludGVydmFsOiBERUZBVUxUX1RJTUVPVVRcbiAgICB9LFxuICAgIHVwZGF0ZUpvYjogdHJ1ZSxcbiAgICBtYXhJbnN0YW5jZXM6IDEsXG4gICAgb25QcmVwYXJlOiBOT09QLFxuICAgIGJlZm9yZTogTk9PUCxcbiAgICBhZnRlcjogTk9PUCxcbiAgICBvbkNvbXBsZXRlOiBOT09QXG59XG5cbmNsYXNzIENvbmZpZ1BhcnNlciB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICB0aGlzLl9jb25maWcgPSBERUZBVUxUX0NPTkZJR1NcbiAgICAgICAgdGhpcy5fY2FwYWJpbGl0aWVzID0gW11cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBtZXJnZXMgY29uZmlnIGZpbGUgd2l0aCBkZWZhdWx0IHZhbHVlc1xuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBmaWxlbmFtZSBwYXRoIG9mIGZpbGUgcmVsYXRpdmUgdG8gY3VycmVudCBkaXJlY3RvcnlcbiAgICAgKi9cbiAgICBhZGRDb25maWdGaWxlIChmaWxlbmFtZSkge1xuICAgICAgICBpZiAodHlwZW9mIGZpbGVuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhZGRDb25maWdGaWxlIHJlcXVpcmVzIGZpbGVwYXRoJylcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBmaWxlUGF0aCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBmaWxlbmFtZSlcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIGZpbGVDb25maWcgPSByZXF1aXJlKGZpbGVQYXRoKS5jb25maWdcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBmaWxlQ29uZmlnICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY29uZmlndXJhdGlvbiBmaWxlIGV4cG9ydHMgbm8gY29uZmlnIG9iamVjdCcpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogbWVyZ2UgY2FwYWJpbGl0aWVzXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuX2NhcGFiaWxpdGllcyA9IG1lcmdlKHRoaXMuX2NhcGFiaWxpdGllcywgZmlsZUNvbmZpZy5jYXBhYmlsaXRpZXMpXG4gICAgICAgICAgICBkZWxldGUgZmlsZUNvbmZpZy5jYXBhYmlsaXRpZXNcblxuICAgICAgICAgICAgdGhpcy5fY29uZmlnID0gbWVyZ2UodGhpcy5fY29uZmlnLCBmaWxlQ29uZmlnKVxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIGRldGVjdCBTZWxlbml1bSBiYWNrZW5kXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuX2NvbmZpZyA9IG1lcmdlKGRldGVjdFNlbGVuaXVtQmFja2VuZCh0aGlzLl9jb25maWcpLCB0aGlzLl9jb25maWcpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCBsb2FkaW5nIGNvbmZpZ3VyYXRpb24gZmlsZTogJywgZmlsZVBhdGgpXG4gICAgICAgICAgICB0aHJvdyBlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBtZXJnZSBleHRlcm5hbCBvYmplY3Qgd2l0aCBjb25maWcgb2JqZWN0XG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBvYmplY3QgIGRlc2lyZWQgb2JqZWN0IHRvIG1lcmdlIGludG8gdGhlIGNvbmZpZyBvYmplY3RcbiAgICAgKi9cbiAgICBtZXJnZSAob2JqZWN0KSB7XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IG1lcmdlKHRoaXMuX2NvbmZpZywgb2JqZWN0KVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiB1c2VyIGFuZCBrZXkgY291bGQgZ2V0IGFkZGVkIHZpYSBjbGkgYXJndW1lbnRzIHNvIHdlIG5lZWQgdG8gZGV0ZWN0IGFnYWluXG4gICAgICAgICAqIE5vdGU6IGNsaSBhcmd1bWVudHMgYXJlIG9uIHRoZSByaWdodCBhbmQgb3ZlcndyaXRlIGNvbmZpZ1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29uZmlnID0gbWVyZ2UoZGV0ZWN0U2VsZW5pdW1CYWNrZW5kKHRoaXMuX2NvbmZpZyksIHRoaXMuX2NvbmZpZylcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBnZXQgZXhjbHVkZWQgZmlsZXMgZnJvbSBjb25maWcgcGF0dGVyblxuICAgICAqL1xuICAgIGdldFNwZWNzIChjYXBTcGVjcywgY2FwRXhjbHVkZSkge1xuICAgICAgICBsZXQgc3BlY3MgPSBDb25maWdQYXJzZXIuZ2V0RmlsZVBhdGhzKHRoaXMuX2NvbmZpZy5zcGVjcylcbiAgICAgICAgbGV0IGV4Y2x1ZGUgPSBDb25maWdQYXJzZXIuZ2V0RmlsZVBhdGhzKHRoaXMuX2NvbmZpZy5leGNsdWRlKVxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNhcFNwZWNzKSkge1xuICAgICAgICAgICAgc3BlY3MgPSBzcGVjcy5jb25jYXQoY2FwU3BlY3MpXG4gICAgICAgIH1cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2FwRXhjbHVkZSkpIHtcbiAgICAgICAgICAgIGV4Y2x1ZGUgPSBleGNsdWRlLmNvbmNhdChjYXBFeGNsdWRlKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNwZWNzLmZpbHRlcihzcGVjID0+IGV4Y2x1ZGUuaW5kZXhPZihzcGVjKSA8IDApXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmV0dXJuIGNvbmZpZ3NcbiAgICAgKi9cbiAgICBnZXRDb25maWcgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmV0dXJuIGNhcGFiaWxpdGllc1xuICAgICAqL1xuICAgIGdldENhcGFiaWxpdGllcyAoaSkge1xuICAgICAgICBpZiAodHlwZW9mIGkgPT09ICdudW1iZXInICYmIHRoaXMuX2NhcGFiaWxpdGllc1tpXSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NhcGFiaWxpdGllc1tpXVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcGFiaWxpdGllc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgYSBmbGF0dGVuIGxpc3Qgb2YgZ2xvYmVkIGZpbGVzXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmdbXX0gZmlsZW5hbWVzICBsaXN0IG9mIGZpbGVzIHRvIGdsb2JcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmdbXX0gbGlzdCBvZiBmaWxlc1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRGaWxlUGF0aHMgKHBhdHRlcm5zLCBvbWl0V2FybmluZ3MpIHtcbiAgICAgICAgbGV0IGZpbGVzID0gW11cblxuICAgICAgICBmb3IgKGxldCBwYXR0ZXJuIG9mIHBhdHRlcm5zKSB7XG4gICAgICAgICAgICBsZXQgZmlsZW5hbWVzID0gZ2xvYi5zeW5jKHBhdHRlcm4pXG5cbiAgICAgICAgICAgIGZpbGVuYW1lcyA9IGZpbGVuYW1lcy5maWx0ZXIocGF0aCA9PlxuICAgICAgICAgICAgICAgIHBhdGguc2xpY2UoLTMpID09PSAnLmpzJyB8fFxuICAgICAgICAgICAgICAgIHBhdGguc2xpY2UoLTgpID09PSAnLmZlYXR1cmUnIHx8XG4gICAgICAgICAgICAgICAgcGF0aC5zbGljZSgtNykgPT09ICcuY29mZmVlJylcblxuICAgICAgICAgICAgZmlsZW5hbWVzID0gZmlsZW5hbWVzLm1hcChwYXRoID0+XG4gICAgICAgICAgICAgICAgcHJvY2Vzcy5jd2QoKSArICcvJyArIHBhdGgpXG5cbiAgICAgICAgICAgIGlmIChmaWxlbmFtZXMubGVuZ3RoID09PSAwICYmICFvbWl0V2FybmluZ3MpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ3BhdHRlcm4nLCBwYXR0ZXJuLCAnZGlkIG5vdCBtYXRjaCBhbnkgZmlsZScpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZpbGVzID0gbWVyZ2UoZmlsZXMsIGZpbGVuYW1lcylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmaWxlc1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29uZmlnUGFyc2VyXG4iXX0=