UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

274 lines (264 loc) 32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorCode = void 0; exports.addScope = addScope; Object.defineProperty(exports, "buildToken", { enumerable: true, get: function () { return _utils.buildToken; } }); exports.deleteProperties = deleteProperties; exports.encodeScopedUri = encodeScopedUri; exports.getVersion = getVersion; exports.hasDiffOneKey = hasDiffOneKey; exports.hasLogin = hasLogin; exports.hasTarball = hasTarball; exports.initLogger = initLogger; exports.isObject = void 0; exports.isObjectOrArray = isObjectOrArray; exports.isRelatedToDeprecation = isRelatedToDeprecation; exports.isVersionValid = isVersionValid; exports.logHTTPSWarning = logHTTPSWarning; exports.normalizeDistTags = normalizeDistTags; Object.defineProperty(exports, "parseConfigFile", { enumerable: true, get: function () { return _config.parseConfigFile; } }); exports.parseInterval = parseInterval; exports.parseReadme = parseReadme; exports.resolveConfigPath = void 0; exports.sortByName = sortByName; exports.tagVersion = tagVersion; var _debug = _interopRequireDefault(require("debug")); var _lodash = _interopRequireDefault(require("lodash")); var _nodePath = _interopRequireDefault(require("node:path")); var _semver = _interopRequireDefault(require("semver")); var _config = require("@verdaccio/config"); var _core = require("@verdaccio/core"); var _utils = require("@verdaccio/utils"); var _constants = require("./constants"); var _logger = require("./logger"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const debug = (0, _debug.default)('verdaccio:lib:utils'); const { getBadData, getBadRequest, getCode, getConflict, getForbidden, getInternalError, getNotFound, getServiceUnavailable, getUnauthorized } = _core.errorUtils; function initLogger(logConfig) { if (logConfig.logs) { logConfig.log = logConfig.logs; _core.warningUtils.emit(_core.warningUtils.Codes.VERWAR002); } debug('initializing logger with config: %o', logConfig.log); (0, _logger.setup)(logConfig.log); } function addScope(scope, packageName) { return `@${scope}/${packageName}`; } /** * Check whether an element is an Object * @param {*} obj the element * @return {Boolean} */ const isObject = exports.isObject = _core.validationUtils.isObject; /** * @deprecated not used un v6 */ function isObjectOrArray(obj) { return _lodash.default.isObject(obj) && _lodash.default.isNull(obj) === false; } function tagVersion(data, version, tag) { if (tag && data[_constants.DIST_TAGS][tag] !== version && _semver.default.parse(version, true)) { // valid version - store data[_constants.DIST_TAGS][tag] = version; return true; } return false; } /** * Gets version from a package object taking into account semver weirdness. * @return {String} return the semantic version of a package */ function getVersion(pkg, version) { // this condition must allow cast if (_lodash.default.isNil(pkg.versions[version]) === false) { return pkg.versions[version]; } try { version = _semver.default.parse(version, true); for (const versionItem in pkg.versions) { if (version.compare(_semver.default.parse(versionItem, true)) === 0) { return pkg.versions[versionItem]; } } } catch { return undefined; } } /** * Flatten arrays of tags. * @param {*} data */ function normalizeDistTags(pkg) { let sorted; if (!pkg[_constants.DIST_TAGS].latest) { // overwrite latest with highest known version based on semver sort sorted = _core.pkgUtils.semverSort(Object.keys(pkg.versions)); if (sorted && sorted.length) { pkg[_constants.DIST_TAGS].latest = sorted.pop(); } } for (const tag in pkg[_constants.DIST_TAGS]) { if (_lodash.default.isArray(pkg[_constants.DIST_TAGS][tag])) { if (pkg[_constants.DIST_TAGS][tag].length) { // sort array // FIXME: this is clearly wrong, we need to research why this is like this. sorted = _core.pkgUtils.semverSort(pkg[_constants.DIST_TAGS][tag]); if (sorted.length) { // use highest version based on semver sort pkg[_constants.DIST_TAGS][tag] = sorted.pop(); } } else { delete pkg[_constants.DIST_TAGS][tag]; } } else if (_lodash.default.isString(pkg[_constants.DIST_TAGS][tag])) { if (!_semver.default.parse(pkg[_constants.DIST_TAGS][tag], true)) { // if the version is invalid, delete the dist-tag entry delete pkg[_constants.DIST_TAGS][tag]; } } } } const parseIntervalTable = { '': 1000, ms: 1, s: 1000, m: 60 * 1000, h: 60 * 60 * 1000, d: 86400000, w: 7 * 86400000, M: 30 * 86400000, y: 365 * 86400000 }; /** * Parse an internal string to number * @param {*} interval * @return {Number} */ function parseInterval(interval) { if (typeof interval === 'number') { return interval * 1000; } let result = 0; let last_suffix = Infinity; interval.split(/\s+/).forEach(function (x) { if (!x) { return; } const m = x.match(/^((0|[1-9][0-9]*)(\.[0-9]+)?)(ms|s|m|h|d|w|M|y|)$/); if (!m || parseIntervalTable[m[4]] >= last_suffix || m[4] === '' && last_suffix !== Infinity) { throw Error('invalid interval: ' + interval); } last_suffix = parseIntervalTable[m[4]]; result += Number(m[1]) * parseIntervalTable[m[4]]; }); return result; } const ErrorCode = exports.ErrorCode = { getConflict, getBadData, getBadRequest, getInternalError, getUnauthorized, getForbidden, getServiceUnavailable, getNotFound, getCode }; function sortByName(packages, orderAscending = true) { return packages.slice().sort(function (a, b) { const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase(); return orderAscending ? comparatorNames ? -1 : 1 : comparatorNames ? 1 : -1; }); } function deleteProperties(propertiesToDelete, objectItem) { _lodash.default.forEach(propertiesToDelete, property => { delete objectItem[property]; }); return objectItem; } /** * parse package readme - markdown/ascii * @param {String} packageName name of package * @param {String} readme package readme * @return {String} converted html template */ // TODO: rename, does not parse anymore function parseReadme(packageName, readme) { if (_lodash.default.isEmpty(readme) === false) { return readme; } // logs readme not found error _logger.logger.info({ packageName }, '@{packageName}: No readme found'); return 'ERROR: No README data found!'; } function encodeScopedUri(packageName) { return packageName.replace(/\//g, '%2f'); } function hasDiffOneKey(versions) { return Object.keys(versions).length !== 1; } function isVersionValid(packageMeta, packageVersion) { const hasVersion = typeof packageVersion !== 'undefined'; if (!hasVersion) { return false; } const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion); return hasMatchVersion; } function isRelatedToDeprecation(pkgInfo) { const { versions } = pkgInfo; for (const version in versions) { if (Object.prototype.hasOwnProperty.call(versions[version], 'deprecated')) { return true; } } return false; } const resolveConfigPath = function (storageLocation, file) { return _nodePath.default.resolve(_nodePath.default.dirname(storageLocation), file); }; exports.resolveConfigPath = resolveConfigPath; function logHTTPSWarning(storageLocation) { _logger.logger.fatal(['You have enabled HTTPS and need to specify either ', ' "https.key" and "https.cert" or ', ' "https.pfx" and optionally "https.passphrase" ', 'to run https server', '', // commands are borrowed from node.js docs 'To quickly create self-signed certificate, use:', ' $ openssl genrsa -out ' + resolveConfigPath(storageLocation, _constants.keyPem) + ' 2048', ' $ openssl req -new -sha256 -key ' + resolveConfigPath(storageLocation, _constants.keyPem) + ' -out ' + resolveConfigPath(storageLocation, _constants.csrPem), ' $ openssl x509 -req -in ' + resolveConfigPath(storageLocation, _constants.csrPem) + ' -signkey ' + resolveConfigPath(storageLocation, _constants.keyPem) + ' -out ' + resolveConfigPath(storageLocation, _constants.certPem), '', 'And then add to config file (' + storageLocation + '):', ' https:', ` key: ${resolveConfigPath(storageLocation, _constants.keyPem)}`, ` cert: ${resolveConfigPath(storageLocation, _constants.certPem)}`].join('\n')); process.exit(2); } function hasLogin(config) { return _lodash.default.isNil(config?.web?.login) || config?.web?.login === true; } /** * Check whether any version in a package manifest has a tarball URL * that matches the given filename. */ function hasTarball(pkg, filename) { return Object.values(pkg.versions || {}).some(version => version.dist?.tarball?.endsWith('/' + filename)); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZGVidWciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfbm9kZVBhdGgiLCJfc2VtdmVyIiwiX2NvbmZpZyIsIl9jb3JlIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9sb2dnZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJkZWJ1ZyIsImNyZWF0ZURlYnVnIiwiZ2V0QmFkRGF0YSIsImdldEJhZFJlcXVlc3QiLCJnZXRDb2RlIiwiZ2V0Q29uZmxpY3QiLCJnZXRGb3JiaWRkZW4iLCJnZXRJbnRlcm5hbEVycm9yIiwiZ2V0Tm90Rm91bmQiLCJnZXRTZXJ2aWNlVW5hdmFpbGFibGUiLCJnZXRVbmF1dGhvcml6ZWQiLCJlcnJvclV0aWxzIiwiaW5pdExvZ2dlciIsImxvZ0NvbmZpZyIsImxvZ3MiLCJsb2ciLCJ3YXJuaW5nVXRpbHMiLCJlbWl0IiwiQ29kZXMiLCJWRVJXQVIwMDIiLCJzZXR1cCIsImFkZFNjb3BlIiwic2NvcGUiLCJwYWNrYWdlTmFtZSIsImlzT2JqZWN0IiwiZXhwb3J0cyIsInZhbGlkYXRpb25VdGlscyIsImlzT2JqZWN0T3JBcnJheSIsIm9iaiIsIl8iLCJpc051bGwiLCJ0YWdWZXJzaW9uIiwiZGF0YSIsInZlcnNpb24iLCJ0YWciLCJESVNUX1RBR1MiLCJzZW12ZXIiLCJwYXJzZSIsImdldFZlcnNpb24iLCJwa2ciLCJpc05pbCIsInZlcnNpb25zIiwidmVyc2lvbkl0ZW0iLCJjb21wYXJlIiwidW5kZWZpbmVkIiwibm9ybWFsaXplRGlzdFRhZ3MiLCJzb3J0ZWQiLCJsYXRlc3QiLCJwa2dVdGlscyIsInNlbXZlclNvcnQiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwicG9wIiwiaXNBcnJheSIsImlzU3RyaW5nIiwicGFyc2VJbnRlcnZhbFRhYmxlIiwibXMiLCJzIiwibSIsImgiLCJkIiwidyIsIk0iLCJ5IiwicGFyc2VJbnRlcnZhbCIsImludGVydmFsIiwicmVzdWx0IiwibGFzdF9zdWZmaXgiLCJJbmZpbml0eSIsInNwbGl0IiwiZm9yRWFjaCIsIngiLCJtYXRjaCIsIkVycm9yIiwiTnVtYmVyIiwiRXJyb3JDb2RlIiwic29ydEJ5TmFtZSIsInBhY2thZ2VzIiwib3JkZXJBc2NlbmRpbmciLCJzbGljZSIsInNvcnQiLCJhIiwiYiIsImNvbXBhcmF0b3JOYW1lcyIsIm5hbWUiLCJ0b0xvd2VyQ2FzZSIsImRlbGV0ZVByb3BlcnRpZXMiLCJwcm9wZXJ0aWVzVG9EZWxldGUiLCJvYmplY3RJdGVtIiwicHJvcGVydHkiLCJwYXJzZVJlYWRtZSIsInJlYWRtZSIsImlzRW1wdHkiLCJsb2dnZXIiLCJpbmZvIiwiZW5jb2RlU2NvcGVkVXJpIiwicmVwbGFjZSIsImhhc0RpZmZPbmVLZXkiLCJpc1ZlcnNpb25WYWxpZCIsInBhY2thZ2VNZXRhIiwicGFja2FnZVZlcnNpb24iLCJoYXNWZXJzaW9uIiwiaGFzTWF0Y2hWZXJzaW9uIiwiaW5jbHVkZXMiLCJpc1JlbGF0ZWRUb0RlcHJlY2F0aW9uIiwicGtnSW5mbyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlc29sdmVDb25maWdQYXRoIiwic3RvcmFnZUxvY2F0aW9uIiwiZmlsZSIsInBhdGgiLCJyZXNvbHZlIiwiZGlybmFtZSIsImxvZ0hUVFBTV2FybmluZyIsImZhdGFsIiwia2V5UGVtIiwiY3NyUGVtIiwiY2VydFBlbSIsImpvaW4iLCJwcm9jZXNzIiwiZXhpdCIsImhhc0xvZ2luIiwiY29uZmlnIiwid2ViIiwibG9naW4iLCJoYXNUYXJiYWxsIiwiZmlsZW5hbWUiLCJ2YWx1ZXMiLCJzb21lIiwiZGlzdCIsInRhcmJhbGwiLCJlbmRzV2l0aCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdXRpbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyZWF0ZURlYnVnIGZyb20gJ2RlYnVnJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInO1xuXG5pbXBvcnQgeyBwYXJzZUNvbmZpZ0ZpbGUgfSBmcm9tICdAdmVyZGFjY2lvL2NvbmZpZyc7XG5pbXBvcnQgeyBlcnJvclV0aWxzLCBwa2dVdGlscywgdmFsaWRhdGlvblV0aWxzLCB3YXJuaW5nVXRpbHMgfSBmcm9tICdAdmVyZGFjY2lvL2NvcmUnO1xuaW1wb3J0IHsgQ29uZmlnWWFtbCwgTG9nZ2VyQ29uZmlnSXRlbSwgU3RyaW5nVmFsdWUgfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IENvbmZpZywgTWFuaWZlc3QsIFZlcnNpb24gfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IGJ1aWxkVG9rZW4gYXMgYnVpbGRUb2tlblV0aWwgfSBmcm9tICdAdmVyZGFjY2lvL3V0aWxzJztcblxuaW1wb3J0IHsgRElTVF9UQUdTLCBjZXJ0UGVtLCBjc3JQZW0sIGtleVBlbSB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IGxvZ2dlciwgc2V0dXAgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmNvbnN0IGRlYnVnID0gY3JlYXRlRGVidWcoJ3ZlcmRhY2NpbzpsaWI6dXRpbHMnKTtcblxuY29uc3Qge1xuICBnZXRCYWREYXRhLFxuICBnZXRCYWRSZXF1ZXN0LFxuICBnZXRDb2RlLFxuICBnZXRDb25mbGljdCxcbiAgZ2V0Rm9yYmlkZGVuLFxuICBnZXRJbnRlcm5hbEVycm9yLFxuICBnZXROb3RGb3VuZCxcbiAgZ2V0U2VydmljZVVuYXZhaWxhYmxlLFxuICBnZXRVbmF1dGhvcml6ZWQsXG59ID0gZXJyb3JVdGlscztcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRMb2dnZXIobG9nQ29uZmlnOiBDb25maWdZYW1sKSB7XG4gIGlmIChsb2dDb25maWcubG9ncykge1xuICAgIGxvZ0NvbmZpZy5sb2cgPSBsb2dDb25maWcubG9ncztcbiAgICB3YXJuaW5nVXRpbHMuZW1pdCh3YXJuaW5nVXRpbHMuQ29kZXMuVkVSV0FSMDAyKTtcbiAgfVxuICBkZWJ1ZygnaW5pdGlhbGl6aW5nIGxvZ2dlciB3aXRoIGNvbmZpZzogJW8nLCBsb2dDb25maWcubG9nKTtcbiAgc2V0dXAobG9nQ29uZmlnLmxvZyBhcyBMb2dnZXJDb25maWdJdGVtKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFNjb3BlKHNjb3BlOiBzdHJpbmcsIHBhY2thZ2VOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYEAke3Njb3BlfS8ke3BhY2thZ2VOYW1lfWA7XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciBhbiBlbGVtZW50IGlzIGFuIE9iamVjdFxuICogQHBhcmFtIHsqfSBvYmogdGhlIGVsZW1lbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBpc09iamVjdCA9IHZhbGlkYXRpb25VdGlscy5pc09iamVjdDtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBub3QgdXNlZCB1biB2NlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPYmplY3RPckFycmF5KG9iajogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiBfLmlzT2JqZWN0KG9iaikgJiYgXy5pc051bGwob2JqKSA9PT0gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YWdWZXJzaW9uKGRhdGE6IE1hbmlmZXN0LCB2ZXJzaW9uOiBzdHJpbmcsIHRhZzogU3RyaW5nVmFsdWUpOiBib29sZWFuIHtcbiAgaWYgKHRhZyAmJiBkYXRhW0RJU1RfVEFHU11bdGFnXSAhPT0gdmVyc2lvbiAmJiBzZW12ZXIucGFyc2UodmVyc2lvbiwgdHJ1ZSkpIHtcbiAgICAvLyB2YWxpZCB2ZXJzaW9uIC0gc3RvcmVcbiAgICBkYXRhW0RJU1RfVEFHU11bdGFnXSA9IHZlcnNpb247XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEdldHMgdmVyc2lvbiBmcm9tIGEgcGFja2FnZSBvYmplY3QgdGFraW5nIGludG8gYWNjb3VudCBzZW12ZXIgd2VpcmRuZXNzLlxuICogQHJldHVybiB7U3RyaW5nfSByZXR1cm4gdGhlIHNlbWFudGljIHZlcnNpb24gb2YgYSBwYWNrYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZXJzaW9uKHBrZzogTWFuaWZlc3QsIHZlcnNpb246IGFueSk6IFZlcnNpb24gfCB2b2lkIHtcbiAgLy8gdGhpcyBjb25kaXRpb24gbXVzdCBhbGxvdyBjYXN0XG4gIGlmIChfLmlzTmlsKHBrZy52ZXJzaW9uc1t2ZXJzaW9uXSkgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIHBrZy52ZXJzaW9uc1t2ZXJzaW9uXTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgdmVyc2lvbiA9IHNlbXZlci5wYXJzZSh2ZXJzaW9uLCB0cnVlKTtcbiAgICBmb3IgKGNvbnN0IHZlcnNpb25JdGVtIGluIHBrZy52ZXJzaW9ucykge1xuICAgICAgaWYgKHZlcnNpb24uY29tcGFyZShzZW12ZXIucGFyc2UodmVyc2lvbkl0ZW0sIHRydWUpKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gcGtnLnZlcnNpb25zW3ZlcnNpb25JdGVtXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBGbGF0dGVuIGFycmF5cyBvZiB0YWdzLlxuICogQHBhcmFtIHsqfSBkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEaXN0VGFncyhwa2c6IE1hbmlmZXN0KTogdm9pZCB7XG4gIGxldCBzb3J0ZWQ7XG4gIGlmICghcGtnW0RJU1RfVEFHU10ubGF0ZXN0KSB7XG4gICAgLy8gb3ZlcndyaXRlIGxhdGVzdCB3aXRoIGhpZ2hlc3Qga25vd24gdmVyc2lvbiBiYXNlZCBvbiBzZW12ZXIgc29ydFxuICAgIHNvcnRlZCA9IHBrZ1V0aWxzLnNlbXZlclNvcnQoT2JqZWN0LmtleXMocGtnLnZlcnNpb25zKSk7XG4gICAgaWYgKHNvcnRlZCAmJiBzb3J0ZWQubGVuZ3RoKSB7XG4gICAgICBwa2dbRElTVF9UQUdTXS5sYXRlc3QgPSBzb3J0ZWQucG9wKCk7XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCB0YWcgaW4gcGtnW0RJU1RfVEFHU10pIHtcbiAgICBpZiAoXy5pc0FycmF5KHBrZ1tESVNUX1RBR1NdW3RhZ10pKSB7XG4gICAgICBpZiAocGtnW0RJU1RfVEFHU11bdGFnXS5sZW5ndGgpIHtcbiAgICAgICAgLy8gc29ydCBhcnJheVxuICAgICAgICAvLyBGSVhNRTogdGhpcyBpcyBjbGVhcmx5IHdyb25nLCB3ZSBuZWVkIHRvIHJlc2VhcmNoIHdoeSB0aGlzIGlzIGxpa2UgdGhpcy5cbiAgICAgICAgc29ydGVkID0gcGtnVXRpbHMuc2VtdmVyU29ydChwa2dbRElTVF9UQUdTXVt0YWddKTtcbiAgICAgICAgaWYgKHNvcnRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAvLyB1c2UgaGlnaGVzdCB2ZXJzaW9uIGJhc2VkIG9uIHNlbXZlciBzb3J0XG4gICAgICAgICAgcGtnW0RJU1RfVEFHU11bdGFnXSA9IHNvcnRlZC5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHBrZ1tESVNUX1RBR1NdW3RhZ107XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChfLmlzU3RyaW5nKHBrZ1tESVNUX1RBR1NdW3RhZ10pKSB7XG4gICAgICBpZiAoIXNlbXZlci5wYXJzZShwa2dbRElTVF9UQUdTXVt0YWddLCB0cnVlKSkge1xuICAgICAgICAvLyBpZiB0aGUgdmVyc2lvbiBpcyBpbnZhbGlkLCBkZWxldGUgdGhlIGRpc3QtdGFnIGVudHJ5XG4gICAgICAgIGRlbGV0ZSBwa2dbRElTVF9UQUdTXVt0YWddO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5jb25zdCBwYXJzZUludGVydmFsVGFibGUgPSB7XG4gICcnOiAxMDAwLFxuICBtczogMSxcbiAgczogMTAwMCxcbiAgbTogNjAgKiAxMDAwLFxuICBoOiA2MCAqIDYwICogMTAwMCxcbiAgZDogODY0MDAwMDAsXG4gIHc6IDcgKiA4NjQwMDAwMCxcbiAgTTogMzAgKiA4NjQwMDAwMCxcbiAgeTogMzY1ICogODY0MDAwMDAsXG59O1xuXG4vKipcbiAqIFBhcnNlIGFuIGludGVybmFsIHN0cmluZyB0byBudW1iZXJcbiAqIEBwYXJhbSB7Kn0gaW50ZXJ2YWxcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSW50ZXJ2YWwoaW50ZXJ2YWw6IGFueSk6IG51bWJlciB7XG4gIGlmICh0eXBlb2YgaW50ZXJ2YWwgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIGludGVydmFsICogMTAwMDtcbiAgfVxuICBsZXQgcmVzdWx0ID0gMDtcbiAgbGV0IGxhc3Rfc3VmZml4ID0gSW5maW5pdHk7XG4gIGludGVydmFsLnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoeCk6IHZvaWQge1xuICAgIGlmICgheCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtID0geC5tYXRjaCgvXigoMHxbMS05XVswLTldKikoXFwuWzAtOV0rKT8pKG1zfHN8bXxofGR8d3xNfHl8KSQvKTtcbiAgICBpZiAoXG4gICAgICAhbSB8fFxuICAgICAgcGFyc2VJbnRlcnZhbFRhYmxlW21bNF1dID49IGxhc3Rfc3VmZml4IHx8XG4gICAgICAobVs0XSA9PT0gJycgJiYgbGFzdF9zdWZmaXggIT09IEluZmluaXR5KVxuICAgICkge1xuICAgICAgdGhyb3cgRXJyb3IoJ2ludmFsaWQgaW50ZXJ2YWw6ICcgKyBpbnRlcnZhbCk7XG4gICAgfVxuICAgIGxhc3Rfc3VmZml4ID0gcGFyc2VJbnRlcnZhbFRhYmxlW21bNF1dO1xuICAgIHJlc3VsdCArPSBOdW1iZXIobVsxXSkgKiBwYXJzZUludGVydmFsVGFibGVbbVs0XV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgY29uc3QgRXJyb3JDb2RlID0ge1xuICBnZXRDb25mbGljdCxcbiAgZ2V0QmFkRGF0YSxcbiAgZ2V0QmFkUmVxdWVzdCxcbiAgZ2V0SW50ZXJuYWxFcnJvcixcbiAgZ2V0VW5hdXRob3JpemVkLFxuICBnZXRGb3JiaWRkZW4sXG4gIGdldFNlcnZpY2VVbmF2YWlsYWJsZSxcbiAgZ2V0Tm90Rm91bmQsXG4gIGdldENvZGUsXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc29ydEJ5TmFtZShwYWNrYWdlczogYW55W10sIG9yZGVyQXNjZW5kaW5nOiBib29sZWFuIHwgdm9pZCA9IHRydWUpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBwYWNrYWdlcy5zbGljZSgpLnNvcnQoZnVuY3Rpb24gKGEsIGIpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvbXBhcmF0b3JOYW1lcyA9IGEubmFtZS50b0xvd2VyQ2FzZSgpIDwgYi5uYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICByZXR1cm4gb3JkZXJBc2NlbmRpbmcgPyAoY29tcGFyYXRvck5hbWVzID8gLTEgOiAxKSA6IGNvbXBhcmF0b3JOYW1lcyA/IDEgOiAtMTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVQcm9wZXJ0aWVzKHByb3BlcnRpZXNUb0RlbGV0ZTogc3RyaW5nW10sIG9iamVjdEl0ZW06IGFueSk6IGFueSB7XG4gIF8uZm9yRWFjaChwcm9wZXJ0aWVzVG9EZWxldGUsIChwcm9wZXJ0eSk6IGFueSA9PiB7XG4gICAgZGVsZXRlIG9iamVjdEl0ZW1bcHJvcGVydHldO1xuICB9KTtcblxuICByZXR1cm4gb2JqZWN0SXRlbTtcbn1cblxuLyoqXG4gKiBwYXJzZSBwYWNrYWdlIHJlYWRtZSAtIG1hcmtkb3duL2FzY2lpXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2FnZU5hbWUgbmFtZSBvZiBwYWNrYWdlXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVhZG1lIHBhY2thZ2UgcmVhZG1lXG5cbiAqIEByZXR1cm4ge1N0cmluZ30gY29udmVydGVkIGh0bWwgdGVtcGxhdGVcbiAqL1xuLy8gVE9ETzogcmVuYW1lLCBkb2VzIG5vdCBwYXJzZSBhbnltb3JlXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSZWFkbWUocGFja2FnZU5hbWU6IHN0cmluZywgcmVhZG1lOiBzdHJpbmcpOiBzdHJpbmcgfCB2b2lkIHtcbiAgaWYgKF8uaXNFbXB0eShyZWFkbWUpID09PSBmYWxzZSkge1xuICAgIHJldHVybiByZWFkbWU7XG4gIH1cblxuICAvLyBsb2dzIHJlYWRtZSBub3QgZm91bmQgZXJyb3JcbiAgbG9nZ2VyLmluZm8oeyBwYWNrYWdlTmFtZSB9LCAnQHtwYWNrYWdlTmFtZX06IE5vIHJlYWRtZSBmb3VuZCcpO1xuXG4gIHJldHVybiAnRVJST1I6IE5vIFJFQURNRSBkYXRhIGZvdW5kISc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVTY29wZWRVcmkocGFja2FnZU5hbWUpOiBzdHJpbmcge1xuICByZXR1cm4gcGFja2FnZU5hbWUucmVwbGFjZSgvXFwvL2csICclMmYnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0RpZmZPbmVLZXkodmVyc2lvbnMpOiBib29sZWFuIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHZlcnNpb25zKS5sZW5ndGggIT09IDE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcnNpb25WYWxpZChwYWNrYWdlTWV0YSwgcGFja2FnZVZlcnNpb24pOiBib29sZWFuIHtcbiAgY29uc3QgaGFzVmVyc2lvbiA9IHR5cGVvZiBwYWNrYWdlVmVyc2lvbiAhPT0gJ3VuZGVmaW5lZCc7XG4gIGlmICghaGFzVmVyc2lvbikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGhhc01hdGNoVmVyc2lvbiA9IE9iamVjdC5rZXlzKHBhY2thZ2VNZXRhLnZlcnNpb25zKS5pbmNsdWRlcyhwYWNrYWdlVmVyc2lvbik7XG4gIHJldHVybiBoYXNNYXRjaFZlcnNpb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JlbGF0ZWRUb0RlcHJlY2F0aW9uKHBrZ0luZm86IE1hbmlmZXN0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgdmVyc2lvbnMgfSA9IHBrZ0luZm87XG4gIGZvciAoY29uc3QgdmVyc2lvbiBpbiB2ZXJzaW9ucykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmVyc2lvbnNbdmVyc2lvbl0sICdkZXByZWNhdGVkJykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBjb25zdCByZXNvbHZlQ29uZmlnUGF0aCA9IGZ1bmN0aW9uIChzdG9yYWdlTG9jYXRpb246IHN0cmluZywgZmlsZTogc3RyaW5nKSB7XG4gIHJldHVybiBwYXRoLnJlc29sdmUocGF0aC5kaXJuYW1lKHN0b3JhZ2VMb2NhdGlvbiksIGZpbGUpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ0hUVFBTV2FybmluZyhzdG9yYWdlTG9jYXRpb24pIHtcbiAgbG9nZ2VyLmZhdGFsKFxuICAgIFtcbiAgICAgICdZb3UgaGF2ZSBlbmFibGVkIEhUVFBTIGFuZCBuZWVkIHRvIHNwZWNpZnkgZWl0aGVyICcsXG4gICAgICAnICAgIFwiaHR0cHMua2V5XCIgYW5kIFwiaHR0cHMuY2VydFwiIG9yICcsXG4gICAgICAnICAgIFwiaHR0cHMucGZ4XCIgYW5kIG9wdGlvbmFsbHkgXCJodHRwcy5wYXNzcGhyYXNlXCIgJyxcbiAgICAgICd0byBydW4gaHR0cHMgc2VydmVyJyxcbiAgICAgICcnLFxuICAgICAgLy8gY29tbWFuZHMgYXJlIGJvcnJvd2VkIGZyb20gbm9kZS5qcyBkb2NzXG4gICAgICAnVG8gcXVpY2tseSBjcmVhdGUgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUsIHVzZTonLFxuICAgICAgJyAkIG9wZW5zc2wgZ2VucnNhIC1vdXQgJyArIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArICcgMjA0OCcsXG4gICAgICAnICQgb3BlbnNzbCByZXEgLW5ldyAtc2hhMjU2IC1rZXkgJyArXG4gICAgICAgIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArXG4gICAgICAgICcgLW91dCAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjc3JQZW0pLFxuICAgICAgJyAkIG9wZW5zc2wgeDUwOSAtcmVxIC1pbiAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjc3JQZW0pICtcbiAgICAgICAgJyAtc2lnbmtleSAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBrZXlQZW0pICtcbiAgICAgICAgJyAtb3V0ICcgK1xuICAgICAgICByZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGNlcnRQZW0pLFxuICAgICAgJycsXG4gICAgICAnQW5kIHRoZW4gYWRkIHRvIGNvbmZpZyBmaWxlICgnICsgc3RvcmFnZUxvY2F0aW9uICsgJyk6JyxcbiAgICAgICcgIGh0dHBzOicsXG4gICAgICBgICAgIGtleTogJHtyZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGtleVBlbSl9YCxcbiAgICAgIGAgICAgY2VydDogJHtyZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGNlcnRQZW0pfWAsXG4gICAgXS5qb2luKCdcXG4nKVxuICApO1xuICBwcm9jZXNzLmV4aXQoMik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNMb2dpbihjb25maWc6IENvbmZpZykge1xuICByZXR1cm4gXy5pc05pbChjb25maWc/LndlYj8ubG9naW4pIHx8IGNvbmZpZz8ud2ViPy5sb2dpbiA9PT0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGFueSB2ZXJzaW9uIGluIGEgcGFja2FnZSBtYW5pZmVzdCBoYXMgYSB0YXJiYWxsIFVSTFxuICogdGhhdCBtYXRjaGVzIHRoZSBnaXZlbiBmaWxlbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1RhcmJhbGwocGtnOiBNYW5pZmVzdCwgZmlsZW5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhwa2cudmVyc2lvbnMgfHwge30pLnNvbWUoKHZlcnNpb24pID0+XG4gICAgKHZlcnNpb24gYXMgVmVyc2lvbikuZGlzdD8udGFyYmFsbD8uZW5kc1dpdGgoJy8nICsgZmlsZW5hbWUpXG4gICk7XG59XG5cbmV4cG9ydCB7IGJ1aWxkVG9rZW5VdGlsIGFzIGJ1aWxkVG9rZW4sIHBhcnNlQ29uZmlnRmlsZSB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsSUFBQUEsTUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsU0FBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSixzQkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssS0FBQSxHQUFBTCxPQUFBO0FBR0EsSUFBQU0sTUFBQSxHQUFBTixPQUFBO0FBRUEsSUFBQU8sVUFBQSxHQUFBUCxPQUFBO0FBQ0EsSUFBQVEsT0FBQSxHQUFBUixPQUFBO0FBQXlDLFNBQUFELHVCQUFBVSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRXpDLE1BQU1HLEtBQUssR0FBRyxJQUFBQyxjQUFXLEVBQUMscUJBQXFCLENBQUM7QUFFaEQsTUFBTTtFQUNKQyxVQUFVO0VBQ1ZDLGFBQWE7RUFDYkMsT0FBTztFQUNQQyxXQUFXO0VBQ1hDLFlBQVk7RUFDWkMsZ0JBQWdCO0VBQ2hCQyxXQUFXO0VBQ1hDLHFCQUFxQjtFQUNyQkM7QUFDRixDQUFDLEdBQUdDLGdCQUFVO0FBRVAsU0FBU0MsVUFBVUEsQ0FBQ0MsU0FBcUIsRUFBRTtFQUNoRCxJQUFJQSxTQUFTLENBQUND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