UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

265 lines (256 loc) 30.8 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.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; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZGVidWciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfbm9kZVBhdGgiLCJfc2VtdmVyIiwiX2NvbmZpZyIsIl9jb3JlIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9sb2dnZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJkZWJ1ZyIsImNyZWF0ZURlYnVnIiwiZ2V0QmFkRGF0YSIsImdldEJhZFJlcXVlc3QiLCJnZXRDb2RlIiwiZ2V0Q29uZmxpY3QiLCJnZXRGb3JiaWRkZW4iLCJnZXRJbnRlcm5hbEVycm9yIiwiZ2V0Tm90Rm91bmQiLCJnZXRTZXJ2aWNlVW5hdmFpbGFibGUiLCJnZXRVbmF1dGhvcml6ZWQiLCJlcnJvclV0aWxzIiwiaW5pdExvZ2dlciIsImxvZ0NvbmZpZyIsImxvZ3MiLCJsb2ciLCJ3YXJuaW5nVXRpbHMiLCJlbWl0IiwiQ29kZXMiLCJWRVJXQVIwMDIiLCJzZXR1cCIsImFkZFNjb3BlIiwic2NvcGUiLCJwYWNrYWdlTmFtZSIsImlzT2JqZWN0IiwiZXhwb3J0cyIsInZhbGlkYXRpb25VdGlscyIsImlzT2JqZWN0T3JBcnJheSIsIm9iaiIsIl8iLCJpc051bGwiLCJ0YWdWZXJzaW9uIiwiZGF0YSIsInZlcnNpb24iLCJ0YWciLCJESVNUX1RBR1MiLCJzZW12ZXIiLCJwYXJzZSIsImdldFZlcnNpb24iLCJwa2ciLCJpc05pbCIsInZlcnNpb25zIiwidmVyc2lvbkl0ZW0iLCJjb21wYXJlIiwidW5kZWZpbmVkIiwibm9ybWFsaXplRGlzdFRhZ3MiLCJzb3J0ZWQiLCJsYXRlc3QiLCJwa2dVdGlscyIsInNlbXZlclNvcnQiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwicG9wIiwiaXNBcnJheSIsImlzU3RyaW5nIiwicGFyc2VJbnRlcnZhbFRhYmxlIiwibXMiLCJzIiwibSIsImgiLCJkIiwidyIsIk0iLCJ5IiwicGFyc2VJbnRlcnZhbCIsImludGVydmFsIiwicmVzdWx0IiwibGFzdF9zdWZmaXgiLCJJbmZpbml0eSIsInNwbGl0IiwiZm9yRWFjaCIsIngiLCJtYXRjaCIsIkVycm9yIiwiTnVtYmVyIiwiRXJyb3JDb2RlIiwic29ydEJ5TmFtZSIsInBhY2thZ2VzIiwib3JkZXJBc2NlbmRpbmciLCJzbGljZSIsInNvcnQiLCJhIiwiYiIsImNvbXBhcmF0b3JOYW1lcyIsIm5hbWUiLCJ0b0xvd2VyQ2FzZSIsImRlbGV0ZVByb3BlcnRpZXMiLCJwcm9wZXJ0aWVzVG9EZWxldGUiLCJvYmplY3RJdGVtIiwicHJvcGVydHkiLCJwYXJzZVJlYWRtZSIsInJlYWRtZSIsImlzRW1wdHkiLCJsb2dnZXIiLCJpbmZvIiwiZW5jb2RlU2NvcGVkVXJpIiwicmVwbGFjZSIsImhhc0RpZmZPbmVLZXkiLCJpc1ZlcnNpb25WYWxpZCIsInBhY2thZ2VNZXRhIiwicGFja2FnZVZlcnNpb24iLCJoYXNWZXJzaW9uIiwiaGFzTWF0Y2hWZXJzaW9uIiwiaW5jbHVkZXMiLCJpc1JlbGF0ZWRUb0RlcHJlY2F0aW9uIiwicGtnSW5mbyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlc29sdmVDb25maWdQYXRoIiwic3RvcmFnZUxvY2F0aW9uIiwiZmlsZSIsInBhdGgiLCJyZXNvbHZlIiwiZGlybmFtZSIsImxvZ0hUVFBTV2FybmluZyIsImZhdGFsIiwia2V5UGVtIiwiY3NyUGVtIiwiY2VydFBlbSIsImpvaW4iLCJwcm9jZXNzIiwiZXhpdCIsImhhc0xvZ2luIiwiY29uZmlnIiwid2ViIiwibG9naW4iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjcmVhdGVEZWJ1ZyBmcm9tICdkZWJ1Zyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBzZW12ZXIgZnJvbSAnc2VtdmVyJztcblxuaW1wb3J0IHsgcGFyc2VDb25maWdGaWxlIH0gZnJvbSAnQHZlcmRhY2Npby9jb25maWcnO1xuaW1wb3J0IHsgZXJyb3JVdGlscywgcGtnVXRpbHMsIHZhbGlkYXRpb25VdGlscywgd2FybmluZ1V0aWxzIH0gZnJvbSAnQHZlcmRhY2Npby9jb3JlJztcbmltcG9ydCB7IENvbmZpZ1lhbWwsIExvZ2dlckNvbmZpZ0l0ZW0sIFN0cmluZ1ZhbHVlIH0gZnJvbSAnQHZlcmRhY2Npby90eXBlcyc7XG5pbXBvcnQgeyBDb25maWcsIE1hbmlmZXN0LCBWZXJzaW9uIH0gZnJvbSAnQHZlcmRhY2Npby90eXBlcyc7XG5pbXBvcnQgeyBidWlsZFRva2VuIGFzIGJ1aWxkVG9rZW5VdGlsIH0gZnJvbSAnQHZlcmRhY2Npby91dGlscyc7XG5cbmltcG9ydCB7IERJU1RfVEFHUywgY2VydFBlbSwgY3NyUGVtLCBrZXlQZW0gfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBsb2dnZXIsIHNldHVwIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5jb25zdCBkZWJ1ZyA9IGNyZWF0ZURlYnVnKCd2ZXJkYWNjaW86bGliOnV0aWxzJyk7XG5cbmNvbnN0IHtcbiAgZ2V0QmFkRGF0YSxcbiAgZ2V0QmFkUmVxdWVzdCxcbiAgZ2V0Q29kZSxcbiAgZ2V0Q29uZmxpY3QsXG4gIGdldEZvcmJpZGRlbixcbiAgZ2V0SW50ZXJuYWxFcnJvcixcbiAgZ2V0Tm90Rm91bmQsXG4gIGdldFNlcnZpY2VVbmF2YWlsYWJsZSxcbiAgZ2V0VW5hdXRob3JpemVkLFxufSA9IGVycm9yVXRpbHM7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0TG9nZ2VyKGxvZ0NvbmZpZzogQ29uZmlnWWFtbCkge1xuICBpZiAobG9nQ29uZmlnLmxvZ3MpIHtcbiAgICBsb2dDb25maWcubG9nID0gbG9nQ29uZmlnLmxvZ3M7XG4gICAgd2FybmluZ1V0aWxzLmVtaXQod2FybmluZ1V0aWxzLkNvZGVzLlZFUldBUjAwMik7XG4gIH1cbiAgZGVidWcoJ2luaXRpYWxpemluZyBsb2dnZXIgd2l0aCBjb25maWc6ICVvJywgbG9nQ29uZmlnLmxvZyk7XG4gIHNldHVwKGxvZ0NvbmZpZy5sb2cgYXMgTG9nZ2VyQ29uZmlnSXRlbSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRTY29wZShzY29wZTogc3RyaW5nLCBwYWNrYWdlTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBAJHtzY29wZX0vJHtwYWNrYWdlTmFtZX1gO1xufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYW4gZWxlbWVudCBpcyBhbiBPYmplY3RcbiAqIEBwYXJhbSB7Kn0gb2JqIHRoZSBlbGVtZW50XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5leHBvcnQgY29uc3QgaXNPYmplY3QgPSB2YWxpZGF0aW9uVXRpbHMuaXNPYmplY3Q7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgbm90IHVzZWQgdW4gdjZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0T3JBcnJheShvYmo6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gXy5pc09iamVjdChvYmopICYmIF8uaXNOdWxsKG9iaikgPT09IGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGFnVmVyc2lvbihkYXRhOiBNYW5pZmVzdCwgdmVyc2lvbjogc3RyaW5nLCB0YWc6IFN0cmluZ1ZhbHVlKTogYm9vbGVhbiB7XG4gIGlmICh0YWcgJiYgZGF0YVtESVNUX1RBR1NdW3RhZ10gIT09IHZlcnNpb24gJiYgc2VtdmVyLnBhcnNlKHZlcnNpb24sIHRydWUpKSB7XG4gICAgLy8gdmFsaWQgdmVyc2lvbiAtIHN0b3JlXG4gICAgZGF0YVtESVNUX1RBR1NdW3RhZ10gPSB2ZXJzaW9uO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBHZXRzIHZlcnNpb24gZnJvbSBhIHBhY2thZ2Ugb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgc2VtdmVyIHdlaXJkbmVzcy5cbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJuIHRoZSBzZW1hbnRpYyB2ZXJzaW9uIG9mIGEgcGFja2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVyc2lvbihwa2c6IE1hbmlmZXN0LCB2ZXJzaW9uOiBhbnkpOiBWZXJzaW9uIHwgdm9pZCB7XG4gIC8vIHRoaXMgY29uZGl0aW9uIG11c3QgYWxsb3cgY2FzdFxuICBpZiAoXy5pc05pbChwa2cudmVyc2lvbnNbdmVyc2lvbl0pID09PSBmYWxzZSkge1xuICAgIHJldHVybiBwa2cudmVyc2lvbnNbdmVyc2lvbl07XG4gIH1cblxuICB0cnkge1xuICAgIHZlcnNpb24gPSBzZW12ZXIucGFyc2UodmVyc2lvbiwgdHJ1ZSk7XG4gICAgZm9yIChjb25zdCB2ZXJzaW9uSXRlbSBpbiBwa2cudmVyc2lvbnMpIHtcbiAgICAgIGlmICh2ZXJzaW9uLmNvbXBhcmUoc2VtdmVyLnBhcnNlKHZlcnNpb25JdGVtLCB0cnVlKSkgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHBrZy52ZXJzaW9uc1t2ZXJzaW9uSXRlbV07XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogRmxhdHRlbiBhcnJheXMgb2YgdGFncy5cbiAqIEBwYXJhbSB7Kn0gZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplRGlzdFRhZ3MocGtnOiBNYW5pZmVzdCk6IHZvaWQge1xuICBsZXQgc29ydGVkO1xuICBpZiAoIXBrZ1tESVNUX1RBR1NdLmxhdGVzdCkge1xuICAgIC8vIG92ZXJ3cml0ZSBsYXRlc3Qgd2l0aCBoaWdoZXN0IGtub3duIHZlcnNpb24gYmFzZWQgb24gc2VtdmVyIHNvcnRcbiAgICBzb3J0ZWQgPSBwa2dVdGlscy5zZW12ZXJTb3J0KE9iamVjdC5rZXlzKHBrZy52ZXJzaW9ucykpO1xuICAgIGlmIChzb3J0ZWQgJiYgc29ydGVkLmxlbmd0aCkge1xuICAgICAgcGtnW0RJU1RfVEFHU10ubGF0ZXN0ID0gc29ydGVkLnBvcCgpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgdGFnIGluIHBrZ1tESVNUX1RBR1NdKSB7XG4gICAgaWYgKF8uaXNBcnJheShwa2dbRElTVF9UQUdTXVt0YWddKSkge1xuICAgICAgaWYgKHBrZ1tESVNUX1RBR1NdW3RhZ10ubGVuZ3RoKSB7XG4gICAgICAgIC8vIHNvcnQgYXJyYXlcbiAgICAgICAgLy8gRklYTUU6IHRoaXMgaXMgY2xlYXJseSB3cm9uZywgd2UgbmVlZCB0byByZXNlYXJjaCB3aHkgdGhpcyBpcyBsaWtlIHRoaXMuXG4gICAgICAgIHNvcnRlZCA9IHBrZ1V0aWxzLnNlbXZlclNvcnQocGtnW0RJU1RfVEFHU11bdGFnXSk7XG4gICAgICAgIGlmIChzb3J0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdXNlIGhpZ2hlc3QgdmVyc2lvbiBiYXNlZCBvbiBzZW12ZXIgc29ydFxuICAgICAgICAgIHBrZ1tESVNUX1RBR1NdW3RhZ10gPSBzb3J0ZWQucG9wKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBwa2dbRElTVF9UQUdTXVt0YWddO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXy5pc1N0cmluZyhwa2dbRElTVF9UQUdTXVt0YWddKSkge1xuICAgICAgaWYgKCFzZW12ZXIucGFyc2UocGtnW0RJU1RfVEFHU11bdGFnXSwgdHJ1ZSkpIHtcbiAgICAgICAgLy8gaWYgdGhlIHZlcnNpb24gaXMgaW52YWxpZCwgZGVsZXRlIHRoZSBkaXN0LXRhZyBlbnRyeVxuICAgICAgICBkZWxldGUgcGtnW0RJU1RfVEFHU11bdGFnXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuY29uc3QgcGFyc2VJbnRlcnZhbFRhYmxlID0ge1xuICAnJzogMTAwMCxcbiAgbXM6IDEsXG4gIHM6IDEwMDAsXG4gIG06IDYwICogMTAwMCxcbiAgaDogNjAgKiA2MCAqIDEwMDAsXG4gIGQ6IDg2NDAwMDAwLFxuICB3OiA3ICogODY0MDAwMDAsXG4gIE06IDMwICogODY0MDAwMDAsXG4gIHk6IDM2NSAqIDg2NDAwMDAwLFxufTtcblxuLyoqXG4gKiBQYXJzZSBhbiBpbnRlcm5hbCBzdHJpbmcgdG8gbnVtYmVyXG4gKiBAcGFyYW0geyp9IGludGVydmFsXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUludGVydmFsKGludGVydmFsOiBhbnkpOiBudW1iZXIge1xuICBpZiAodHlwZW9mIGludGVydmFsID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBpbnRlcnZhbCAqIDEwMDA7XG4gIH1cbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGxldCBsYXN0X3N1ZmZpeCA9IEluZmluaXR5O1xuICBpbnRlcnZhbC5zcGxpdCgvXFxzKy8pLmZvckVhY2goZnVuY3Rpb24gKHgpOiB2b2lkIHtcbiAgICBpZiAoIXgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbSA9IHgubWF0Y2goL14oKDB8WzEtOV1bMC05XSopKFxcLlswLTldKyk/KShtc3xzfG18aHxkfHd8TXx5fCkkLyk7XG4gICAgaWYgKFxuICAgICAgIW0gfHxcbiAgICAgIHBhcnNlSW50ZXJ2YWxUYWJsZVttWzRdXSA+PSBsYXN0X3N1ZmZpeCB8fFxuICAgICAgKG1bNF0gPT09ICcnICYmIGxhc3Rfc3VmZml4ICE9PSBJbmZpbml0eSlcbiAgICApIHtcbiAgICAgIHRocm93IEVycm9yKCdpbnZhbGlkIGludGVydmFsOiAnICsgaW50ZXJ2YWwpO1xuICAgIH1cbiAgICBsYXN0X3N1ZmZpeCA9IHBhcnNlSW50ZXJ2YWxUYWJsZVttWzRdXTtcbiAgICByZXN1bHQgKz0gTnVtYmVyKG1bMV0pICogcGFyc2VJbnRlcnZhbFRhYmxlW21bNF1dO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGNvbnN0IEVycm9yQ29kZSA9IHtcbiAgZ2V0Q29uZmxpY3QsXG4gIGdldEJhZERhdGEsXG4gIGdldEJhZFJlcXVlc3QsXG4gIGdldEludGVybmFsRXJyb3IsXG4gIGdldFVuYXV0aG9yaXplZCxcbiAgZ2V0Rm9yYmlkZGVuLFxuICBnZXRTZXJ2aWNlVW5hdmFpbGFibGUsXG4gIGdldE5vdEZvdW5kLFxuICBnZXRDb2RlLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNvcnRCeU5hbWUocGFja2FnZXM6IGFueVtdLCBvcmRlckFzY2VuZGluZzogYm9vbGVhbiB8IHZvaWQgPSB0cnVlKTogc3RyaW5nW10ge1xuICByZXR1cm4gcGFja2FnZXMuc2xpY2UoKS5zb3J0KGZ1bmN0aW9uIChhLCBiKTogbnVtYmVyIHtcbiAgICBjb25zdCBjb21wYXJhdG9yTmFtZXMgPSBhLm5hbWUudG9Mb3dlckNhc2UoKSA8IGIubmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgcmV0dXJuIG9yZGVyQXNjZW5kaW5nID8gKGNvbXBhcmF0b3JOYW1lcyA/IC0xIDogMSkgOiBjb21wYXJhdG9yTmFtZXMgPyAxIDogLTE7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlUHJvcGVydGllcyhwcm9wZXJ0aWVzVG9EZWxldGU6IHN0cmluZ1tdLCBvYmplY3RJdGVtOiBhbnkpOiBhbnkge1xuICBfLmZvckVhY2gocHJvcGVydGllc1RvRGVsZXRlLCAocHJvcGVydHkpOiBhbnkgPT4ge1xuICAgIGRlbGV0ZSBvYmplY3RJdGVtW3Byb3BlcnR5XTtcbiAgfSk7XG5cbiAgcmV0dXJuIG9iamVjdEl0ZW07XG59XG5cbi8qKlxuICogcGFyc2UgcGFja2FnZSByZWFkbWUgLSBtYXJrZG93bi9hc2NpaVxuICogQHBhcmFtIHtTdHJpbmd9IHBhY2thZ2VOYW1lIG5hbWUgb2YgcGFja2FnZVxuICogQHBhcmFtIHtTdHJpbmd9IHJlYWRtZSBwYWNrYWdlIHJlYWRtZVxuXG4gKiBAcmV0dXJuIHtTdHJpbmd9IGNvbnZlcnRlZCBodG1sIHRlbXBsYXRlXG4gKi9cbi8vIFRPRE86IHJlbmFtZSwgZG9lcyBub3QgcGFyc2UgYW55bW9yZVxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVhZG1lKHBhY2thZ2VOYW1lOiBzdHJpbmcsIHJlYWRtZTogc3RyaW5nKTogc3RyaW5nIHwgdm9pZCB7XG4gIGlmIChfLmlzRW1wdHkocmVhZG1lKSA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gcmVhZG1lO1xuICB9XG5cbiAgLy8gbG9ncyByZWFkbWUgbm90IGZvdW5kIGVycm9yXG4gIGxvZ2dlci5pbmZvKHsgcGFja2FnZU5hbWUgfSwgJ0B7cGFja2FnZU5hbWV9OiBObyByZWFkbWUgZm91bmQnKTtcblxuICByZXR1cm4gJ0VSUk9SOiBObyBSRUFETUUgZGF0YSBmb3VuZCEnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU2NvcGVkVXJpKHBhY2thZ2VOYW1lKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhY2thZ2VOYW1lLnJlcGxhY2UoL1xcLy9nLCAnJTJmJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNEaWZmT25lS2V5KHZlcnNpb25zKTogYm9vbGVhbiB7XG4gIHJldHVybiBPYmplY3Qua2V5cyh2ZXJzaW9ucykubGVuZ3RoICE9PSAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZXJzaW9uVmFsaWQocGFja2FnZU1ldGEsIHBhY2thZ2VWZXJzaW9uKTogYm9vbGVhbiB7XG4gIGNvbnN0IGhhc1ZlcnNpb24gPSB0eXBlb2YgcGFja2FnZVZlcnNpb24gIT09ICd1bmRlZmluZWQnO1xuICBpZiAoIWhhc1ZlcnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBoYXNNYXRjaFZlcnNpb24gPSBPYmplY3Qua2V5cyhwYWNrYWdlTWV0YS52ZXJzaW9ucykuaW5jbHVkZXMocGFja2FnZVZlcnNpb24pO1xuICByZXR1cm4gaGFzTWF0Y2hWZXJzaW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWxhdGVkVG9EZXByZWNhdGlvbihwa2dJbmZvOiBNYW5pZmVzdCk6IGJvb2xlYW4ge1xuICBjb25zdCB7IHZlcnNpb25zIH0gPSBwa2dJbmZvO1xuICBmb3IgKGNvbnN0IHZlcnNpb24gaW4gdmVyc2lvbnMpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZlcnNpb25zW3ZlcnNpb25dLCAnZGVwcmVjYXRlZCcpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgY29uc3QgcmVzb2x2ZUNvbmZpZ1BhdGggPSBmdW5jdGlvbiAoc3RvcmFnZUxvY2F0aW9uOiBzdHJpbmcsIGZpbGU6IHN0cmluZykge1xuICByZXR1cm4gcGF0aC5yZXNvbHZlKHBhdGguZGlybmFtZShzdG9yYWdlTG9jYXRpb24pLCBmaWxlKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2dIVFRQU1dhcm5pbmcoc3RvcmFnZUxvY2F0aW9uKSB7XG4gIGxvZ2dlci5mYXRhbChcbiAgICBbXG4gICAgICAnWW91IGhhdmUgZW5hYmxlZCBIVFRQUyBhbmQgbmVlZCB0byBzcGVjaWZ5IGVpdGhlciAnLFxuICAgICAgJyAgICBcImh0dHBzLmtleVwiIGFuZCBcImh0dHBzLmNlcnRcIiBvciAnLFxuICAgICAgJyAgICBcImh0dHBzLnBmeFwiIGFuZCBvcHRpb25hbGx5IFwiaHR0cHMucGFzc3BocmFzZVwiICcsXG4gICAgICAndG8gcnVuIGh0dHBzIHNlcnZlcicsXG4gICAgICAnJyxcbiAgICAgIC8vIGNvbW1hbmRzIGFyZSBib3Jyb3dlZCBmcm9tIG5vZGUuanMgZG9jc1xuICAgICAgJ1RvIHF1aWNrbHkgY3JlYXRlIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlLCB1c2U6JyxcbiAgICAgICcgJCBvcGVuc3NsIGdlbnJzYSAtb3V0ICcgKyByZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGtleVBlbSkgKyAnIDIwNDgnLFxuICAgICAgJyAkIG9wZW5zc2wgcmVxIC1uZXcgLXNoYTI1NiAta2V5ICcgK1xuICAgICAgICByZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGtleVBlbSkgK1xuICAgICAgICAnIC1vdXQgJyArXG4gICAgICAgIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwgY3NyUGVtKSxcbiAgICAgICcgJCBvcGVuc3NsIHg1MDkgLXJlcSAtaW4gJyArXG4gICAgICAgIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwgY3NyUGVtKSArXG4gICAgICAgICcgLXNpZ25rZXkgJyArXG4gICAgICAgIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArXG4gICAgICAgICcgLW91dCAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjZXJ0UGVtKSxcbiAgICAgICcnLFxuICAgICAgJ0FuZCB0aGVuIGFkZCB0byBjb25maWcgZmlsZSAoJyArIHN0b3JhZ2VMb2NhdGlvbiArICcpOicsXG4gICAgICAnICBodHRwczonLFxuICAgICAgYCAgICBrZXk6ICR7cmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBrZXlQZW0pfWAsXG4gICAgICBgICAgIGNlcnQ6ICR7cmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjZXJ0UGVtKX1gLFxuICAgIF0uam9pbignXFxuJylcbiAgKTtcbiAgcHJvY2Vzcy5leGl0KDIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzTG9naW4oY29uZmlnOiBDb25maWcpIHtcbiAgcmV0dXJuIF8uaXNOaWwoY29uZmlnPy53ZWI/LmxvZ2luKSB8fCBjb25maWc/LndlYj8ubG9naW4gPT09IHRydWU7XG59XG5cbmV4cG9ydCB7IGJ1aWxkVG9rZW5VdGlsIGFzIGJ1aWxkVG9rZW4sIHBhcnNlQ29uZmlnRmlsZSB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxTQUFBLEdBQUFILHNCQUFBLENBQUFDLE9BQUE7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