testcafe
Version:
Automated browser testing for the modern web development stack.
232 lines • 33.4 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const debug_1 = __importDefault(require("debug"));
const json5_1 = __importDefault(require("json5"));
const lodash_1 = require("lodash");
const promisified_functions_1 = require("../utils/promisified-functions");
const option_1 = __importDefault(require("./option"));
const option_source_1 = __importDefault(require("./option-source"));
const resolve_path_relatively_cwd_1 = __importDefault(require("../utils/resolve-path-relatively-cwd"));
const render_template_1 = __importDefault(require("../utils/render-template"));
const warning_message_1 = __importDefault(require("../notifications/warning-message"));
const log_1 = __importDefault(require("../cli/log"));
const formats_1 = __importDefault(require("./formats"));
const runtime_1 = require("../errors/runtime");
const types_1 = require("../errors/types");
const DEBUG_LOGGER = (0, debug_1.default)('testcafe:configuration');
class Configuration {
constructor(configurationFilesNames) {
var _a;
this._options = {};
this._defaultPaths = this._resolveFilePaths(configurationFilesNames);
this._filePath = (_a = this._defaultPaths) === null || _a === void 0 ? void 0 : _a[0];
this._overriddenOptions = [];
}
static _fromObj(obj) {
const result = Object.create(null);
Object.entries(obj).forEach(([key, value]) => {
result[key] = new option_1.default(key, value);
});
return result;
}
static _showConsoleWarning(message) {
log_1.default.write(message);
}
static _throwReadConfigError(code, error, path, renderCallsite) {
const readConfigError = new runtime_1.ReadConfigFileError(code, error, path, renderCallsite);
DEBUG_LOGGER(readConfigError.message);
DEBUG_LOGGER(error);
throw readConfigError;
}
static _resolveFilePath(path) {
if (!path)
return null;
return (0, path_1.isAbsolute)(path) ? path : (0, resolve_path_relatively_cwd_1.default)(path);
}
_resolveFilePaths(filesNames) {
if (!filesNames)
return void 0;
return (0, lodash_1.castArray)(filesNames).reduce((result, name) => {
const resolveFilePath = Configuration._resolveFilePath(name);
if (resolveFilePath)
result.push(resolveFilePath);
return result;
}, []);
}
async init() {
this._overriddenOptions = [];
}
mergeOptions(options) {
Object.entries(options).map(([key, value]) => {
const option = this._ensureOption(key, value, option_source_1.default.Input);
if (value === void 0)
return;
this._setOptionValue(option, value);
});
}
mergeDeep(option, source) {
(0, lodash_1.mergeWith)(option.value, source, (targetValue, sourceValue, property) => {
this._addOverriddenOptionIfNecessary(targetValue, sourceValue, option.source, `${option.name}.${property}`);
return sourceValue !== void 0 ? sourceValue : targetValue;
});
}
_getOption(key) {
if (!key)
return void 0;
const option = this._options[key];
if (!option)
return void 0;
return option.value;
}
getOption(key) {
return this._getOption(key);
}
getOptions(predicate) {
const result = Object.create(null);
let includeInResult = true;
Object.entries(this._options).forEach(([name, option]) => {
includeInResult = predicate ? predicate(name, option) : true;
if (includeInResult)
result[name] = option.value;
});
return result;
}
clone(nonClonedOptions) {
const configuration = (0, lodash_1.cloneDeep)(this);
if (nonClonedOptions) {
(0, lodash_1.castArray)(nonClonedOptions).forEach(key => {
if (configuration._options[key])
configuration._options[key].value = this._options[key].value;
});
}
return configuration;
}
get filePath() {
return this._filePath;
}
get defaultPaths() {
return this._defaultPaths;
}
async _load() {
var _a;
if (!((_a = this.defaultPaths) === null || _a === void 0 ? void 0 : _a.length))
return null;
const configs = await Promise.all(this.defaultPaths.map(async (filePath) => {
if (!await this._isConfigurationFileExists(filePath))
return { filePath, options: null };
let options = null;
if (this._isJSConfiguration(filePath))
options = this._readJsConfigurationFileContent(filePath);
else {
const configurationFileContent = await this._readConfigurationFileContent(filePath);
if (configurationFileContent)
options = this._parseConfigurationFileContent(configurationFileContent, filePath);
}
return { filePath, options };
}));
const existedConfigs = configs.filter(config => !!config.options);
if (!existedConfigs.length)
return null;
this._filePath = existedConfigs[0].filePath;
if (existedConfigs.length > 1)
Configuration._showConsoleWarning((0, render_template_1.default)(warning_message_1.default.multipleConfigurationFilesFound, this._filePath));
return existedConfigs[0].options;
}
async _isConfigurationFileExists(filePath = this.filePath) {
try {
await (0, promisified_functions_1.stat)(filePath);
return true;
}
catch (error) {
DEBUG_LOGGER((0, render_template_1.default)(warning_message_1.default.cannotFindConfigurationFile, filePath, error.stack));
return false;
}
}
static _hasExtension(filePath, extention) {
return !!filePath && (0, path_1.extname)(filePath) === extention;
}
_isJSConfiguration(filePath = this.filePath) {
return Configuration._hasExtension(filePath, formats_1.default.js) || Configuration._hasExtension(filePath, formats_1.default.cjs);
}
_isJSONConfiguration(filePath = this.filePath) {
return Configuration._hasExtension(filePath, formats_1.default.json);
}
_readJsConfigurationFileContent(filePath = this.filePath) {
if (filePath) {
try {
delete require.cache[filePath];
return require(filePath);
}
catch (error) {
Configuration._throwReadConfigError(types_1.RUNTIME_ERRORS.cannotReadConfigFile, error, filePath, true);
}
}
return null;
}
async _readConfigurationFileContent(filePath = this.filePath) {
try {
return await (0, promisified_functions_1.readFile)(filePath);
}
catch (error) {
Configuration._throwReadConfigError(types_1.RUNTIME_ERRORS.cannotReadConfigFile, error, filePath || '', false);
}
return null;
}
_parseConfigurationFileContent(configurationFileContent, filePath = this.filePath) {
try {
return json5_1.default.parse(configurationFileContent.toString());
}
catch (error) {
Configuration._throwReadConfigError(types_1.RUNTIME_ERRORS.cannotParseConfigFile, error, filePath || '', false);
}
return null;
}
_ensureArrayOption(name) {
const options = this._options[name];
if (!options)
return;
// NOTE: a hack to fix lodash type definitions
// @ts-ignore
options.value = (0, lodash_1.castArray)(options.value);
}
_ensureOption(name, value, source) {
let option = null;
if (name in this._options)
option = this._options[name];
else {
option = new option_1.default(name, value, source);
this._options[name] = option;
}
return option;
}
_ensureOptionWithValue(name, defaultValue, source) {
const option = this._ensureOption(name, defaultValue, source);
if (option.value !== void 0)
return;
option.value = defaultValue;
option.source = source;
}
_addOverriddenOptionIfNecessary(value1, value2, source, optionName) {
if (source === option_source_1.default.Default)
return;
if (value1 === void 0 || value2 === void 0 || value1 === value2 || source !== option_source_1.default.Configuration)
return;
this._overriddenOptions.push(optionName);
}
_setOptionValue(option, value) {
if ((0, lodash_1.isPlainObject)(option.value) && (0, lodash_1.isPlainObject)(value))
this.mergeDeep(option, value);
else {
this._addOverriddenOptionIfNecessary(option.value, value, option.source, option.name);
option.value = value;
}
option.source = option_source_1.default.Input;
}
}
exports.default = Configuration;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZ3VyYXRpb24vY29uZmlndXJhdGlvbi1iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQTJDO0FBQzNDLGtEQUEwQjtBQUMxQixrREFBMEI7QUFFMUIsbUNBS2dCO0FBRWhCLDBFQUFnRTtBQUNoRSxzREFBOEI7QUFDOUIsb0VBQTJDO0FBQzNDLHVHQUE0RTtBQUM1RSwrRUFBc0Q7QUFDdEQsdUZBQWdFO0FBQ2hFLHFEQUE2QjtBQUU3Qix3REFBbUM7QUFDbkMsK0NBQXdEO0FBQ3hELDJDQUFpRDtBQUVqRCxNQUFNLFlBQVksR0FBRyxJQUFBLGVBQUssRUFBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBRXJELE1BQXFCLGFBQWE7SUFNOUIsWUFBb0IsdUJBQWlEOztRQUNqRSxJQUFJLENBQUMsUUFBUSxHQUFhLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsYUFBYSxHQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxTQUFTLEdBQVksTUFBQSxJQUFJLENBQUMsYUFBYSwwQ0FBRyxDQUFDLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFUyxNQUFNLENBQUMsUUFBUSxDQUFFLEdBQVc7UUFDbEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVuQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDekMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksZ0JBQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFD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O1lBQy9CLE9BQU87UUFFWCxJQUFJLE1BQU0sS0FBSyxLQUFLLENBQUMsSUFBSSxNQUFNLEtBQUssS0FBSyxDQUFDLElBQUksTUFBTSxLQUFLLE1BQU0sSUFBSSxNQUFNLEtBQUssdUJBQVksQ0FBQyxhQUFhO1lBQ3BHLE9BQU87UUFFWCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFUyxlQUFlLENBQUUsTUFBYyxFQUFFLEtBQWtCO1FBQ3pELElBQUksSUFBQSxzQkFBYSxFQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFBLHNCQUFhLEVBQUMsS0FBSyxDQUFDO1lBQ25ELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLEtBQWUsQ0FBQyxDQUFDO2FBQ3ZDO1lBQ0QsSUFBSSxDQUFDLCtCQUErQixDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXRGLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1NBQ3hCO1FBRUQsTUFBTSxDQUFDLE1BQU0sR0FBRyx1QkFBWSxDQUFDLEtBQUssQ0FBQztJQUN2QyxDQUFDO0NBQ0o7QUE1UkQsZ0NBNFJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXh0bmFtZSwgaXNBYnNvbHV0ZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IGRlYnVnIGZyb20gJ2RlYnVnJztcbmltcG9ydCBKU09ONSBmcm9tICdqc29uNSc7XG5cbmltcG9ydCB7XG4gICAgY2FzdEFycmF5LFxuICAgIGNsb25lRGVlcCxcbiAgICBpc1BsYWluT2JqZWN0LFxuICAgIG1lcmdlV2l0aCxcbn0gZnJvbSAnbG9kYXNoJztcblxuaW1wb3J0IHsgcmVhZEZpbGUsIHN0YXQgfSBmcm9tICcuLi91dGlscy9wcm9taXNpZmllZC1mdW5jdGlvbnMnO1xuaW1wb3J0IE9wdGlvbiBmcm9tICcuL29wdGlvbic7XG5pbXBvcnQgT3B0aW9uU291cmNlIGZyb20gJy4vb3B0aW9uLXNvdXJjZSc7XG5pbXBvcnQgcmVzb2x2ZVBhdGhSZWxhdGl2ZWx5Q3dkIGZyb20gJy4uL3V0aWxzL3Jlc29sdmUtcGF0aC1yZWxhdGl2ZWx5LWN3ZCc7XG5pbXBvcnQgcmVuZGVyVGVtcGxhdGUgZnJvbSAnLi4vdXRpbHMvcmVuZGVyLXRlbXBsYXRlJztcbmltcG9ydCBXQVJOSU5HX01FU1NBR0VTIGZyb20gJy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1tZXNzYWdlJztcbmltcG9ydCBsb2cgZnJvbSAnLi4vY2xpL2xvZyc7XG5pbXBvcnQgeyBEaWN0aW9uYXJ5IH0gZnJvbSAnLi9pbnRlcmZhY2VzJztcbmltcG9ydCBFeHRlbnNpb25zIGZyb20gJy4vZm9ybWF0cyc7XG5pbXBvcnQgeyBSZWFkQ29uZmlnRmlsZUVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHsgUlVOVElNRV9FUlJPUlMgfSBmcm9tICcuLi9lcnJvcnMvdHlwZXMnO1xuXG5jb25zdCBERUJVR19MT0dHRVIgPSBkZWJ1ZygndGVzdGNhZmU6Y29uZmlndXJhdGlvbicpO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb25maWd1cmF0aW9uIHtcbiAgICBwcm90ZWN0ZWQgX29wdGlvbnM6IERpY3Rpb25hcnk8T3B0aW9uPjtcbiAgICBwcm90ZWN0ZWQgX2ZpbGVQYXRoPzogc3RyaW5nO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfZGVmYXVsdFBhdGhzPzogc3RyaW5nW107XG4gICAgcHJvdGVjdGVkIF9vdmVycmlkZGVuT3B0aW9uczogc3RyaW5nW107XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKGNvbmZpZ3VyYXRpb25GaWxlc05hbWVzOiBzdHJpbmcgfCBudWxsIHwgc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucyAgICAgICAgICAgPSB7fTtcbiAgICAgICAgdGhpcy5fZGVmYXVsdFBhdGhzICAgICAgPSB0aGlzLl9yZXNvbHZlRmlsZVBhdGhzKGNvbmZpZ3VyYXRpb25GaWxlc05hbWVzKTtcbiAgICAgICAgdGhpcy5fZmlsZVBhdGggICAgICAgICAgPSB0aGlzLl9kZWZhdWx0UGF0aHM/LlswXTtcbiAgICAgICAgdGhpcy5fb3ZlcnJpZGRlbk9wdGlvbnMgPSBbXTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF9mcm9tT2JqIChvYmo6IG9iamVjdCk6IERpY3Rpb25hcnk8T3B0aW9uPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICAgICAgT2JqZWN0LmVudHJpZXMob2JqKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgIHJlc3VsdFtrZXldID0gbmV3IE9wdGlvbihrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF9zaG93Q29uc29sZVdhcm5pbmcgKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBsb2cud3JpdGUobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX3Rocm93UmVhZENvbmZpZ0Vycm9yIChjb2RlOiBzdHJpbmcsIGVycm9yOiBFcnJvciwgcGF0aDogc3RyaW5nLCByZW5kZXJDYWxsc2l0ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCByZWFkQ29uZmlnRXJyb3IgPSBuZXcgUmVhZENvbmZpZ0ZpbGVFcnJvcihjb2RlLCBlcnJvciwgcGF0aCwgcmVuZGVyQ2FsbHNpdGUpO1xuXG4gICAgICAgIERFQlVHX0xPR0dFUihyZWFkQ29uZmlnRXJyb3IubWVzc2FnZSk7XG4gICAgICAgIERFQlVHX0xPR0dFUihlcnJvcik7XG5cbiAgICAgICAgdGhyb3cgcmVhZENvbmZpZ0Vycm9yO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIF9yZXNvbHZlRmlsZVBhdGggKHBhdGg6IHN0cmluZyB8IG51bGwpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgICAgaWYgKCFwYXRoKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgcmV0dXJuIGlzQWJzb2x1dGUocGF0aCkgPyBwYXRoIDogcmVzb2x2ZVBhdGhSZWxhdGl2ZWx5Q3dkKHBhdGgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Jlc29sdmVGaWxlUGF0aHMgKGZpbGVzTmFtZXM6IHN0cmluZyB8IG51bGwgfCBzdHJpbmdbXSk6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKCFmaWxlc05hbWVzKVxuICAgICAgICAgICAgcmV0dXJuIHZvaWQgMDtcblxuICAgICAgICByZXR1cm4gY2FzdEFycmF5KGZpbGVzTmFtZXMpLnJlZHVjZSgocmVzdWx0LCBuYW1lKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlRmlsZVBhdGggPSBDb25maWd1cmF0aW9uLl9yZXNvbHZlRmlsZVBhdGgobmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChyZXNvbHZlRmlsZVBhdGgpXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocmVzb2x2ZUZpbGVQYXRoKTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSwgW10gYXMgc3RyaW5nW10pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBpbml0ICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5fb3ZlcnJpZGRlbk9wdGlvbnMgPSBbXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbWVyZ2VPcHRpb25zIChvcHRpb25zOiBvYmplY3QpOiB2b2lkIHtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMob3B0aW9ucykubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuX2Vuc3VyZU9wdGlvbihrZXksIHZhbHVlLCBPcHRpb25Tb3VyY2UuSW5wdXQpO1xuXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IHZvaWQgMClcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvblZhbHVlKG9wdGlvbiwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgbWVyZ2VEZWVwIChvcHRpb246IE9wdGlvbiwgc291cmNlOiBvYmplY3QpOiB2b2lkIHtcbiAgICAgICAgbWVyZ2VXaXRoKG9wdGlvbi52YWx1ZSwgc291cmNlLCAodGFyZ2V0VmFsdWU6IE9wdGlvblZhbHVlLCBzb3VyY2VWYWx1ZTogT3B0aW9uVmFsdWUsIHByb3BlcnR5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2FkZE92ZXJyaWRkZW5PcHRpb25JZk5lY2Vzc2FyeSh0YXJnZXRWYWx1ZSwgc291cmNlVmFsdWUsIG9wdGlvbi5zb3VyY2UsIGAke29wdGlvbi5uYW1lfS4ke3Byb3BlcnR5fWApO1xuXG4gICAgICAgICAgICByZXR1cm4gc291cmNlVmFsdWUgIT09IHZvaWQgMCA/IHNvdXJjZVZhbHVlIDogdGFyZ2V0VmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfZ2V0T3B0aW9uIChrZXk6IHN0cmluZyk6IE9wdGlvblZhbHVlIHtcbiAgICAgICAgaWYgKCFrZXkpXG4gICAgICAgICAgICByZXR1cm4gdm9pZCAwO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuX29wdGlvbnNba2V5XTtcblxuICAgICAgICBpZiAoIW9wdGlvbilcbiAgICAgICAgICAgIHJldHVybiB2b2lkIDA7XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbi52YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0T3B0aW9uPFR5cGU+IChrZXk6IHN0cmluZyk6IFR5cGUge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0T3B0aW9uKGtleSkgYXMgVHlwZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0T3B0aW9ucyAocHJlZGljYXRlPzogKG5hbWU6IHN0cmluZywgb3B0aW9uOiBPcHRpb24pID0+IGJvb2xlYW4pOiBEaWN0aW9uYXJ5PE9wdGlvblZhbHVlPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCAgICAgICAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBsZXQgaW5jbHVkZUluUmVzdWx0ID0gdHJ1ZTtcblxuICAgICAgICBPYmplY3QuZW50cmllcyh0aGlzLl9vcHRpb25zKS5mb3JFYWNoKChbbmFtZSwgb3B0aW9uXSkgPT4ge1xuICAgICAgICAgICAgaW5jbHVkZUluUmVzdWx0ID0gcHJlZGljYXRlID8gcHJlZGljYXRlKG5hbWUsIG9wdGlvbikgOiB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoaW5jbHVkZUluUmVzdWx0KVxuICAgICAgICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IG9wdGlvbi52YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xvbmUgKG5vbkNsb25lZE9wdGlvbnM/OiBzdHJpbmcgfCBzdHJpbmdbXSk6IENvbmZpZ3VyYXRpb24ge1xuICAgICAgICBjb25zdCBjb25maWd1cmF0aW9uID0gY2xvbmVEZWVwKHRoaXMpO1xuXG4gICAgICAgIGlmIChub25DbG9uZWRPcHRpb25zKSB7XG4gICAgICAgICAgICBjYXN0QXJyYXkobm9uQ2xvbmVkT3B0aW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWd1cmF0aW9uLl9vcHRpb25zW2tleV0pXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24uX29wdGlvbnNba2V5XS52YWx1ZSA9IHRoaXMuX29wdGlvbnNba2V5XS52YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZ3VyYXRpb247XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBmaWxlUGF0aCAoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbGVQYXRoO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZGVmYXVsdFBhdGhzICgpOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWZhdWx0UGF0aHM7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIF9sb2FkICgpOiBQcm9taXNlPG51bGwgfCBvYmplY3Q+IHtcbiAgICAgICAgaWYgKCF0aGlzLmRlZmF1bHRQYXRocz8ubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgY29uZmlncyA9IGF3YWl0IFByb21pc2UuYWxsKHRoaXMuZGVmYXVsdFBhdGhzLm1hcChhc3luYyBmaWxlUGF0aCA9PiB7XG4gICAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMuX2lzQ29uZmlndXJhdGlvbkZpbGVFeGlzdHMoZmlsZVBhdGgpKVxuICAgICAgICAgICAgICAgIHJldHVybiB7IGZpbGVQYXRoLCBvcHRpb25zOiBudWxsIH07XG5cbiAgICAgICAgICAgIGxldCBvcHRpb25zID0gbnVsbCBhcyBvYmplY3QgfCBudWxsO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNKU0NvbmZpZ3VyYXRpb24oZmlsZVBhdGgpKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB0aGlzLl9yZWFkSnNDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQoZmlsZVBhdGgpO1xuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uZmlndXJhdGlvbkZpbGVDb250ZW50ID0gYXdhaXQgdGhpcy5fcmVhZENvbmZpZ3VyYXRpb25GaWxlQ29udGVudChmaWxlUGF0aCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbkZpbGVDb250ZW50KVxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gdGhpcy5fcGFyc2VDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQoY29uZmlndXJhdGlvbkZpbGVDb250ZW50LCBmaWxlUGF0aCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7IGZpbGVQYXRoLCBvcHRpb25zIH07XG4gICAgICAgIH0pKTtcblxuICAgICAgICBjb25zdCBleGlzdGVkQ29uZmlncyA9IGNvbmZpZ3MuZmlsdGVyKGNvbmZpZyA9PiAhIWNvbmZpZy5vcHRpb25zKTtcblxuICAgICAgICBpZiAoIWV4aXN0ZWRDb25maWdzLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIHRoaXMuX2ZpbGVQYXRoID0gZXhpc3RlZENvbmZpZ3NbMF0uZmlsZVBhdGg7XG5cbiAgICAgICAgaWYgKGV4aXN0ZWRDb25maWdzLmxlbmd0aCA+IDEpXG4gICAgICAgICAgICBDb25maWd1cmF0aW9uLl9zaG93Q29uc29sZVdhcm5pbmcocmVuZGVyVGVtcGxhdGUoV0FSTklOR19NRVNTQUdFUy5tdWx0aXBsZUNvbmZpZ3VyYXRpb25GaWxlc0ZvdW5kLCB0aGlzLl9maWxlUGF0aCkpO1xuXG4gICAgICAgIHJldHVybiBleGlzdGVkQ29uZmlnc1swXS5vcHRpb25zO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBhc3luYyBfaXNDb25maWd1cmF0aW9uRmlsZUV4aXN0cyAoZmlsZVBhdGggPSB0aGlzLmZpbGVQYXRoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBzdGF0KGZpbGVQYXRoKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIERFQlVHX0xPR0dFUihyZW5kZXJUZW1wbGF0ZShXQVJOSU5HX01FU1NBR0VTLmNhbm5vdEZpbmRDb25maWd1cmF0aW9uRmlsZSwgZmlsZVBhdGgsIGVycm9yLnN0YWNrKSk7XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIF9oYXNFeHRlbnNpb24gKGZpbGVQYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsIGV4dGVudGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIWZpbGVQYXRoICYmIGV4dG5hbWUoZmlsZVBhdGgpID09PSBleHRlbnRpb247XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9pc0pTQ29uZmlndXJhdGlvbiAoZmlsZVBhdGggPSB0aGlzLmZpbGVQYXRoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBDb25maWd1cmF0aW9uLl9oYXNFeHRlbnNpb24oZmlsZVBhdGgsIEV4dGVuc2lvbnMuanMpIHx8IENvbmZpZ3VyYXRpb24uX2hhc0V4dGVuc2lvbihmaWxlUGF0aCwgRXh0ZW5zaW9ucy5janMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfaXNKU09OQ29uZmlndXJhdGlvbiAoZmlsZVBhdGggPSB0aGlzLmZpbGVQYXRoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBDb25maWd1cmF0aW9uLl9oYXNFeHRlbnNpb24oZmlsZVBhdGgsIEV4dGVuc2lvbnMuanNvbik7XG4gICAgfVxuXG4gICAgcHVibGljIF9yZWFkSnNDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQgKGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IG9iamVjdCB8IG51bGwge1xuICAgICAgICBpZiAoZmlsZVBhdGgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbZmlsZVBhdGhdO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVpcmUoZmlsZVBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgICAgICBDb25maWd1cmF0aW9uLl90aHJvd1JlYWRDb25maWdFcnJvcihSVU5USU1FX0VSUk9SUy5jYW5ub3RSZWFkQ29uZmlnRmlsZSwgZXJyb3IsIGZpbGVQYXRoLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBfcmVhZENvbmZpZ3VyYXRpb25GaWxlQ29udGVudCAoZmlsZVBhdGggPSB0aGlzLmZpbGVQYXRoKTogUHJvbWlzZTxCdWZmZXIgfCBudWxsPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBDb25maWd1cmF0aW9uLl90aHJvd1JlYWRDb25maWdFcnJvcihSVU5USU1FX0VSUk9SUy5jYW5ub3RSZWFkQ29uZmlnRmlsZSwgZXJyb3IsIGZpbGVQYXRoIHx8ICcnLCBmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wYXJzZUNvbmZpZ3VyYXRpb25GaWxlQ29udGVudCAoY29uZmlndXJhdGlvbkZpbGVDb250ZW50OiBCdWZmZXIsIGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IG9iamVjdCB8IG51bGwge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT041LnBhcnNlKGNvbmZpZ3VyYXRpb25GaWxlQ29udGVudC50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgICAgQ29uZmlndXJhdGlvbi5fdGhyb3dSZWFkQ29uZmlnRXJyb3IoUlVOVElNRV9FUlJPUlMuY2Fubm90UGFyc2VDb25maWdGaWxlLCBlcnJvciwgZmlsZVBhdGggfHwgJycsIGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfZW5zdXJlQXJyYXlPcHRpb24gKG5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fb3B0aW9uc1tuYW1lXTtcblxuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgLy8gTk9URTogYSBoYWNrIHRvIGZpeCBsb2Rhc2ggdHlwZSBkZWZpbml0aW9uc1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIG9wdGlvbnMudmFsdWUgPSBjYXN0QXJyYXkob3B0aW9ucy52YWx1ZSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9lbnN1cmVPcHRpb24gKG5hbWU6IHN0cmluZywgdmFsdWU6IE9wdGlvblZhbHVlLCBzb3VyY2U6IE9wdGlvblNvdXJjZSk6IE9wdGlvbiB7XG4gICAgICAgIGxldCBvcHRpb24gPSBudWxsO1xuXG4gICAgICAgIGlmIChuYW1lIGluIHRoaXMuX29wdGlvbnMpXG4gICAgICAgICAgICBvcHRpb24gPSB0aGlzLl9vcHRpb25zW25hbWVdO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbiA9IG5ldyBPcHRpb24obmFtZSwgdmFsdWUsIHNvdXJjZSk7XG5cbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnNbbmFtZV0gPSBvcHRpb247XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3B0aW9uO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfZW5zdXJlT3B0aW9uV2l0aFZhbHVlIChuYW1lOiBzdHJpbmcsIGRlZmF1bHRWYWx1ZTogT3B0aW9uVmFsdWUsIHNvdXJjZTogT3B0aW9uU291cmNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuX2Vuc3VyZU9wdGlvbihuYW1lLCBkZWZhdWx0VmFsdWUsIHNvdXJjZSk7XG5cbiAgICAgICAgaWYgKG9wdGlvbi52YWx1ZSAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIG9wdGlvbi52YWx1ZSAgPSBkZWZhdWx0VmFsdWU7XG4gICAgICAgIG9wdGlvbi5zb3VyY2UgPSBzb3VyY2U7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9hZGRPdmVycmlkZGVuT3B0aW9uSWZOZWNlc3NhcnkgKHZhbHVlMTogT3B0aW9uVmFsdWUsIHZhbHVlMjogT3B0aW9uVmFsdWUsIHNvdXJjZTogT3B0aW9uU291cmNlLCBvcHRpb25OYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgaWYgKHNvdXJjZSA9PT0gT3B0aW9uU291cmNlLkRlZmF1bHQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgaWYgKHZhbHVlMSA9PT0gdm9pZCAwIHx8IHZhbHVlMiA9PT0gdm9pZCAwIHx8IHZhbHVlMSA9PT0gdmFsdWUyIHx8IHNvdXJjZSAhPT0gT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5fb3ZlcnJpZGRlbk9wdGlvbnMucHVzaChvcHRpb25OYW1lKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX3NldE9wdGlvblZhbHVlIChvcHRpb246IE9wdGlvbiwgdmFsdWU6IE9wdGlvblZhbHVlKTogdm9pZCB7XG4gICAgICAgIGlmIChpc1BsYWluT2JqZWN0KG9wdGlvbi52YWx1ZSkgJiYgaXNQbGFpbk9iamVjdCh2YWx1ZSkpXG4gICAgICAgICAgICB0aGlzLm1lcmdlRGVlcChvcHRpb24sIHZhbHVlIGFzIG9iamVjdCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYWRkT3ZlcnJpZGRlbk9wdGlvbklmTmVjZXNzYXJ5KG9wdGlvbi52YWx1ZSwgdmFsdWUsIG9wdGlvbi5zb3VyY2UsIG9wdGlvbi5uYW1lKTtcblxuICAgICAgICAgICAgb3B0aW9uLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb24uc291cmNlID0gT3B0aW9uU291cmNlLklucHV0O1xuICAgIH1cbn1cbiJdfQ==