verdaccio
Version:
A lightweight private npm proxy registry
913 lines (734 loc) • 98.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _assert = _interopRequireDefault(require("assert"));
var _url = _interopRequireDefault(require("url"));
var _lodash = _interopRequireDefault(require("lodash"));
var _localStorage = _interopRequireDefault(require("@verdaccio/local-storage"));
var _streams = require("@verdaccio/streams");
var _pluginLoader = _interopRequireDefault(require("../lib/plugin-loader"));
var _utils = require("./utils");
var _storageUtils = require("./storage-utils");
var _constants = require("./constants");
var _cryptoUtils = require("./crypto-utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).
*/
class LocalStorage {
constructor(config, logger) {
_defineProperty(this, "config", void 0);
_defineProperty(this, "storagePlugin", void 0);
_defineProperty(this, "logger", void 0);
this.logger = logger.child({
sub: 'fs'
});
this.config = config;
this.storagePlugin = this._loadStorage(config, logger);
}
addPackage(name, pkg, callback) {
const storage = this._getLocalStorage(name);
if (_lodash.default.isNil(storage)) {
return callback(_utils.ErrorCode.getNotFound('this package cannot be added'));
}
storage.createPackage(name, (0, _storageUtils.generatePackageTemplate)(name), err => {
// FIXME: it will be fixed here https://github.com/verdaccio/verdaccio/pull/1360
// @ts-ignore
if (_lodash.default.isNull(err) === false && (err.code === _constants.STORAGE.FILE_EXIST_ERROR || err.code === _constants.HTTP_STATUS.CONFLICT)) {
return callback(_utils.ErrorCode.getConflict());
}
const latest = (0, _utils.getLatestVersion)(pkg);
if (_lodash.default.isNil(latest) === false && pkg.versions[latest]) {
return callback(null, pkg.versions[latest]);
}
return callback();
});
}
/**
* Remove package.
* @param {*} name
* @param {*} callback
* @return {Function}
*/
removePackage(name, callback) {
const storage = this._getLocalStorage(name);
this.logger.debug({
name
}, `[storage] removing package @{name}`);
if (_lodash.default.isNil(storage)) {
return callback(_utils.ErrorCode.getNotFound());
}
storage.readPackage(name, (err, data) => {
if (_lodash.default.isNil(err) === false) {
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
return callback(_utils.ErrorCode.getNotFound());
}
return callback(err);
}
data = (0, _storageUtils.normalizePackage)(data);
this.storagePlugin.remove(name, removeFailed => {
if (removeFailed) {
// This will happen when database is locked
this.logger.debug({
name
}, `[storage/removePackage] the database is locked, removed has failed for @{name}`);
return callback(_utils.ErrorCode.getBadData(removeFailed.message));
}
storage.deletePackage(_constants.STORAGE.PACKAGE_FILE_NAME, err => {
if (err) {
return callback(err);
}
const attachments = Object.keys(data._attachments);
this._deleteAttachments(storage, attachments, callback);
});
});
});
}
/**
* Synchronize remote package info with the local one
* @param {*} name
* @param {*} packageInfo
* @param {*} callback
*/
updateVersions(name, packageInfo, callback) {
this._readCreatePackage(name, (err, packageLocalJson) => {
if (err) {
return callback(err);
}
let change = false; // updating readme
packageLocalJson.readme = (0, _storageUtils.getLatestReadme)(packageInfo);
if (packageInfo.readme !== packageLocalJson.readme) {
change = true;
}
for (const versionId in packageInfo.versions) {
if (_lodash.default.isNil(packageLocalJson.versions[versionId])) {
let version = packageInfo.versions[versionId]; // we don't keep readme for package versions,
// only one readme per package
version = (0, _storageUtils.cleanUpReadme)(version);
version.contributors = (0, _storageUtils.normalizeContributors)(version.contributors);
change = true;
packageLocalJson.versions[versionId] = version;
if (version.dist && version.dist.tarball) {
const urlObject = _url.default.parse(version.dist.tarball);
const filename = urlObject.pathname.replace(/^.*\//, ''); // we do NOT overwrite any existing records
if (_lodash.default.isNil(packageLocalJson._distfiles[filename])) {
const hash = packageLocalJson._distfiles[filename] = {
url: version.dist.tarball,
sha: version.dist.shasum
};
/* eslint spaced-comment: 0 */
// $FlowFixMe
const upLink = version[Symbol.for('__verdaccio_uplink')];
if (_lodash.default.isNil(upLink) === false) {
this._updateUplinkToRemoteProtocol(hash, upLink);
}
}
}
}
}
for (const tag in packageInfo[_constants.DIST_TAGS]) {
if (!packageLocalJson[_constants.DIST_TAGS][tag] || packageLocalJson[_constants.DIST_TAGS][tag] !== packageInfo[_constants.DIST_TAGS][tag]) {
change = true;
packageLocalJson[_constants.DIST_TAGS][tag] = packageInfo[_constants.DIST_TAGS][tag];
}
}
for (const up in packageInfo._uplinks) {
if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {
const need_change = !(0, _utils.isObject)(packageLocalJson._uplinks[up]) || packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag || packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched;
if (need_change) {
change = true;
packageLocalJson._uplinks[up] = packageInfo._uplinks[up];
}
}
}
if ('time' in packageInfo && !_lodash.default.isEqual(packageLocalJson.time, packageInfo.time)) {
packageLocalJson.time = packageInfo.time;
change = true;
}
if (change) {
this.logger.debug({
name
}, 'updating package @{name} info');
this._writePackage(name, packageLocalJson, function (err) {
callback(err, packageLocalJson);
});
} else {
callback(null, packageLocalJson);
}
});
}
/**
* Add a new version to a previous local package.
* @param {*} name
* @param {*} version
* @param {*} metadata
* @param {*} tag
* @param {*} callback
*/
addVersion(name, version, metadata, tag, callback) {
this._updatePackage(name, (data, cb) => {
// keep only one readme per package
data.readme = metadata.readme; // TODO: lodash remove
metadata = (0, _storageUtils.cleanUpReadme)(metadata);
metadata.contributors = (0, _storageUtils.normalizeContributors)(metadata.contributors);
const hasVersion = data.versions[version] != null;
if (hasVersion) {
return cb(_utils.ErrorCode.getConflict());
} // if uploaded tarball has a different shasum, it's very likely that we have some kind of error
if ((0, _utils.isObject)(metadata.dist) && _lodash.default.isString(metadata.dist.tarball)) {
const tarball = metadata.dist.tarball.replace(/.*\//, '');
if ((0, _utils.isObject)(data._attachments[tarball])) {
if (_lodash.default.isNil(data._attachments[tarball].shasum) === false && _lodash.default.isNil(metadata.dist.shasum) === false) {
if (data._attachments[tarball].shasum != metadata.dist.shasum) {
const errorMessage = `shasum error, ${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
return cb(_utils.ErrorCode.getBadRequest(errorMessage));
}
}
const currentDate = new Date().toISOString(); // some old storage do not have this field #740
if (_lodash.default.isNil(data.time)) {
data.time = {};
}
data.time['modified'] = currentDate;
if ('created' in data.time === false) {
data.time.created = currentDate;
}
data.time[version] = currentDate;
data._attachments[tarball].version = version;
}
}
data.versions[version] = metadata;
(0, _utils.tagVersion)(data, version, tag);
this.storagePlugin.add(name, addFailed => {
if (addFailed) {
return cb(_utils.ErrorCode.getBadData(addFailed.message));
}
cb();
});
}, callback);
}
/**
* Merge a new list of tags for a local packages with the existing one.
* @param {*} pkgName
* @param {*} tags
* @param {*} callback
*/
mergeTags(pkgName, tags, callback) {
this._updatePackage(pkgName, (data, cb) => {
/* eslint guard-for-in: 0 */
for (const tag in tags) {
// this handle dist-tag rm command
if (_lodash.default.isNull(tags[tag])) {
delete data[_constants.DIST_TAGS][tag];
continue;
}
if (_lodash.default.isNil(data.versions[tags[tag]])) {
return cb(this._getVersionNotFound());
}
const version = tags[tag];
(0, _utils.tagVersion)(data, version, tag);
}
cb(null);
}, callback);
}
/**
* Return version not found
* @return {String}
* @private
*/
_getVersionNotFound() {
return _utils.ErrorCode.getNotFound(_constants.API_ERROR.VERSION_NOT_EXIST);
}
/**
* Return file no available
* @return {String}
* @private
*/
_getFileNotAvailable() {
return _utils.ErrorCode.getNotFound('no such file available');
}
/**
* Update the package metadata, tags and attachments (tarballs).
* Note: Currently supports unpublishing and deprecation.
* @param {*} name
* @param {*} incomingPkg
* @param {*} revision
* @param {*} callback
* @return {Function}
*/
changePackage(name, incomingPkg, revision, callback) {
if (!(0, _utils.isObject)(incomingPkg.versions) || !(0, _utils.isObject)(incomingPkg[_constants.DIST_TAGS])) {
this.logger.debug({
name
}, `changePackage bad data for @{name}`);
return callback(_utils.ErrorCode.getBadData());
}
this.logger.debug({
name
}, `changePackage udapting package for @{name}`);
this._updatePackage(name, (localData, cb) => {
for (const version in localData.versions) {
const incomingVersion = incomingPkg.versions[version];
if (_lodash.default.isNil(incomingVersion)) {
this.logger.info({
name: name,
version: version
}, 'unpublishing @{name}@@{version}'); // FIXME: I prefer return a new object rather mutate the metadata
delete localData.versions[version];
delete localData.time[version];
for (const file in localData._attachments) {
if (localData._attachments[file].version === version) {
delete localData._attachments[file].version;
}
}
} else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {
const incomingDeprecated = incomingVersion.deprecated;
if (incomingDeprecated != localData.versions[version].deprecated) {
if (!incomingDeprecated) {
this.logger.info({
name: name,
version: version
}, 'undeprecating @{name}@@{version}');
delete localData.versions[version].deprecated;
} else {
this.logger.info({
name: name,
version: version
}, 'deprecating @{name}@@{version}');
localData.versions[version].deprecated = incomingDeprecated;
}
localData.time.modified = new Date().toISOString();
}
}
}
localData[_constants.USERS] = incomingPkg[_constants.USERS];
localData[_constants.DIST_TAGS] = incomingPkg[_constants.DIST_TAGS];
cb(null);
}, function (err) {
if (err) {
return callback(err);
}
callback();
});
}
/**
* Remove a tarball.
* @param {*} name
* @param {*} filename
* @param {*} revision
* @param {*} callback
*/
removeTarball(name, filename, revision, callback) {
(0, _assert.default)((0, _utils.validateName)(filename));
this._updatePackage(name, (data, cb) => {
if (data._attachments[filename]) {
delete data._attachments[filename];
cb(null);
} else {
cb(this._getFileNotAvailable());
}
}, err => {
if (err) {
return callback(err);
}
const storage = this._getLocalStorage(name);
if (storage) {
storage.deletePackage(filename, callback);
}
});
}
/**
* Add a tarball.
* @param {String} name
* @param {String} filename
* @return {Stream}
*/
addTarball(name, filename) {
(0, _assert.default)((0, _utils.validateName)(filename));
let length = 0;
const shaOneHash = (0, _cryptoUtils.createTarballHash)();
const uploadStream = new _streams.UploadTarball({});
const _transform = uploadStream._transform;
const storage = this._getLocalStorage(name);
uploadStream.abort = function () {};
uploadStream.done = function () {};
uploadStream._transform = function (data, ...args) {
shaOneHash.update(data); // measure the length for validation reasons
length += data.length;
const appliedData = [data, ...args]; // FIXME: not sure about this approach, tsc complains
// @ts-ignore
_transform.apply(uploadStream, appliedData);
};
if (name === '__proto__') {
process.nextTick(() => {
uploadStream.emit('error', _utils.ErrorCode.getForbidden());
});
return uploadStream;
}
if (!storage) {
process.nextTick(() => {
uploadStream.emit('error', "can't upload this package");
});
return uploadStream;
}
const writeStream = storage.writeTarball(filename);
writeStream.on('error', err => {
// @ts-ignore
if (err.code === _constants.STORAGE.FILE_EXIST_ERROR || err.code === _constants.HTTP_STATUS.CONFLICT) {
uploadStream.emit('error', _utils.ErrorCode.getConflict());
uploadStream.abort(); // @ts-ignore
} else if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
// check if package exists to throw an appropriate message
this.getPackageMetadata(name, function (_err, _res) {
if (_err) {
uploadStream.emit('error', _err);
} else {
uploadStream.emit('error', err);
}
});
} else {
uploadStream.emit('error', err);
}
});
writeStream.on('open', function () {
// re-emitting open because it's handled in storage.js
uploadStream.emit('open');
});
writeStream.on('success', () => {
this._updatePackage(name, function updater(data, cb) {
data._attachments[filename] = {
shasum: shaOneHash.digest('hex')
};
cb(null);
}, function (err) {
if (err) {
uploadStream.emit('error', err);
} else {
uploadStream.emit('success');
}
});
});
uploadStream.abort = function () {
writeStream.abort();
};
uploadStream.done = function () {
if (!length) {
uploadStream.emit('error', _utils.ErrorCode.getBadData('refusing to accept zero-length file'));
writeStream.abort();
} else {
writeStream.done();
}
};
uploadStream.pipe(writeStream);
return uploadStream;
}
/**
* Get a tarball.
* @param {*} name
* @param {*} filename
* @return {ReadTarball}
*/
getTarball(name, filename) {
(0, _assert.default)((0, _utils.validateName)(filename));
const storage = this._getLocalStorage(name);
if (_lodash.default.isNil(storage)) {
return this._createFailureStreamResponse();
}
return this._streamSuccessReadTarBall(storage, filename);
}
/**
* Return a stream that emits a read failure.
* @private
* @return {ReadTarball}
*/
_createFailureStreamResponse() {
const stream = new _streams.ReadTarball({});
process.nextTick(() => {
stream.emit('error', this._getFileNotAvailable());
});
return stream;
}
/**
* Return a stream that emits the tarball data
* @param {Object} storage
* @param {String} filename
* @private
* @return {ReadTarball}
*/
_streamSuccessReadTarBall(storage, filename) {
const stream = new _streams.ReadTarball({});
const readTarballStream = storage.readTarball(filename);
const e404 = _utils.ErrorCode.getNotFound;
stream.abort = function () {
if (_lodash.default.isNil(readTarballStream) === false) {
readTarballStream.abort();
}
};
readTarballStream.on('error', function (err) {
// @ts-ignore
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
stream.emit('error', e404('no such file available'));
} else {
stream.emit('error', err);
}
});
readTarballStream.on('content-length', function (content) {
stream.emit('content-length', content);
});
readTarballStream.on('open', function () {
// re-emitting open because it's handled in storage.js
stream.emit('open');
readTarballStream.pipe(stream);
});
return stream;
}
/**
* Retrieve a package by name.
* @param {*} name
* @param {*} callback
* @return {Function}
*/
getPackageMetadata(name, callback = () => {}) {
const storage = this._getLocalStorage(name);
if (_lodash.default.isNil(storage)) {
return callback(_utils.ErrorCode.getNotFound());
}
this._readPackage(name, storage, callback);
}
/**
* Search a local package.
* @param {*} startKey
* @param {*} options
* @return {Function}
*/
search(startKey, options) {
const stream = new _streams.ReadTarball({
objectMode: true
});
this._searchEachPackage((item, cb) => {
// @ts-ignore
if (item.time > parseInt(startKey, 10)) {
this.getPackageMetadata(item.name, (err, data) => {
if (err) {
return cb(err);
} // @ts-ignore
const time = new Date(item.time).toISOString();
const result = (0, _storageUtils.prepareSearchPackage)(data, time);
if (_lodash.default.isNil(result) === false) {
stream.push(result);
}
cb(null);
});
} else {
cb(null);
}
}, function onEnd(err) {
if (err) {
stream.emit('error', err);
return;
}
stream.end();
});
return stream;
}
/**
* Retrieve a wrapper that provide access to the package location.
* @param {Object} pkgName package name.
* @return {Object}
*/
_getLocalStorage(pkgName) {
return this.storagePlugin.getPackageStorage(pkgName);
}
/**
* Read a json file from storage.
* @param {Object} storage
* @param {Function} callback
*/
_readPackage(name, storage, callback) {
storage.readPackage(name, (err, result) => {
if (err) {
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
return callback(_utils.ErrorCode.getNotFound());
}
return callback(this._internalError(err, _constants.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
}
callback(err, (0, _storageUtils.normalizePackage)(result));
});
}
/**
* Walks through each package and calls `on_package` on them.
* @param {*} onPackage
* @param {*} onEnd
*/
_searchEachPackage(onPackage, onEnd) {
// save wait whether plugin still do not support search functionality
if (_lodash.default.isNil(this.storagePlugin.search)) {
this.logger.warn('plugin search not implemented yet');
onEnd();
} else {
this.storagePlugin.search(onPackage, onEnd, _utils.validateName);
}
}
/**
* Retrieve either a previous created local package or a boilerplate.
* @param {*} pkgName
* @param {*} callback
* @return {Function}
*/
_readCreatePackage(pkgName, callback) {
const storage = this._getLocalStorage(pkgName);
if (_lodash.default.isNil(storage)) {
this._createNewPackage(pkgName, callback);
return;
}
storage.readPackage(pkgName, (err, data) => {
// TODO: race condition
if (_lodash.default.isNil(err) === false) {
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
data = (0, _storageUtils.generatePackageTemplate)(pkgName);
} else {
return callback(this._internalError(err, _constants.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
}
}
callback(null, (0, _storageUtils.normalizePackage)(data));
});
}
_createNewPackage(name, callback) {
return callback(null, (0, _storageUtils.normalizePackage)((0, _storageUtils.generatePackageTemplate)(name)));
}
/**
* Handle internal error
* @param {*} err
* @param {*} file
* @param {*} message
* @return {Object} Error instance
*/
_internalError(err, file, message) {
this.logger.error({
err: err,
file: file
}, `${message} @{file}: @{!err.message}`);
return _utils.ErrorCode.getInternalError();
}
/**
* @param {*} name package name
* @param {*} updateHandler function(package, cb) - update function
* @param {*} callback callback that gets invoked after it's all updated
* @return {Function}
*/
_updatePackage(name, updateHandler, callback) {
const storage = this._getLocalStorage(name);
if (!storage) {
return callback(_utils.ErrorCode.getNotFound());
}
storage.updatePackage(name, updateHandler, this._writePackage.bind(this), _storageUtils.normalizePackage, callback);
}
/**
* Update the revision (_rev) string for a package.
* @param {*} name
* @param {*} json
* @param {*} callback
* @return {Function}
*/
_writePackage(name, json, callback) {
const storage = this._getLocalStorage(name);
if (_lodash.default.isNil(storage)) {
return callback();
}
storage.savePackage(name, this._setDefaultRevision(json), callback);
}
_setDefaultRevision(json) {
// calculate revision from couch db
if (_lodash.default.isString(json._rev) === false) {
json._rev = _constants.STORAGE.DEFAULT_REVISION;
} // this is intended in debug mode we do not want modify the store revision
if (_lodash.default.isNil(this.config._debug)) {
json._rev = (0, _storageUtils.generateRevision)(json._rev);
}
return json;
}
_deleteAttachments(storage, attachments, callback) {
this.logger.debug({
l: attachments.length
}, `[storage/_deleteAttachments] delete attachments total: @{l}`);
const unlinkNext = function (cb) {
if (_lodash.default.isEmpty(attachments)) {
return cb();
}
const attachment = attachments.shift();
storage.deletePackage(attachment, function () {
unlinkNext(cb);
});
};
unlinkNext(function () {
// try to unlink the directory, but ignore errors because it can fail
storage.removePackage(function (err) {
callback(err);
});
});
}
/**
* Ensure the dist file remains as the same protocol
* @param {Object} hash metadata
* @param {String} upLinkKey registry key
* @private
*/
_updateUplinkToRemoteProtocol(hash, upLinkKey) {
// if we got this information from a known registry,
// use the same protocol for the tarball
//
// see https://github.com/rlidwka/sinopia/issues/166
const tarballUrl = _url.default.parse(hash.url);
const uplinkUrl = _url.default.parse(this.config.uplinks[upLinkKey].url);
if (uplinkUrl.host === tarballUrl.host) {
tarballUrl.protocol = uplinkUrl.protocol;
hash.registry = upLinkKey;
hash.url = _url.default.format(tarballUrl);
}
}
async getSecret(config) {
const secretKey = await this.storagePlugin.getSecret();
return this.storagePlugin.setSecret(config.checkSecretKey(secretKey));
}
_loadStorage(config, logger) {
const Storage = this._loadStorePlugin();
if (_lodash.default.isNil(Storage)) {
(0, _assert.default)(this.config.storage, 'CONFIG: storage path not defined');
return new _localStorage.default(this.config, logger);
}
return Storage;
}
_loadStorePlugin() {
const plugin_params = {
config: this.config,
logger: this.logger
}; // eslint-disable-next-line max-len
const plugins = (0, _pluginLoader.default)(this.config, this.config.store, plugin_params, plugin => {
return plugin.getPackageStorage;
});
return _lodash.default.head(plugins);
}
saveToken(token) {
if (_lodash.default.isFunction(this.storagePlugin.saveToken) === false) {
return Promise.reject(_utils.ErrorCode.getCode(_constants.HTTP_STATUS.SERVICE_UNAVAILABLE, _constants.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
}
return this.storagePlugin.saveToken(token);
}
deleteToken(user, tokenKey) {
if (_lodash.default.isFunction(this.storagePlugin.deleteToken) === false) {
return Promise.reject(_utils.ErrorCode.getCode(_constants.HTTP_STATUS.SERVICE_UNAVAILABLE, _constants.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
}
return this.storagePlugin.deleteToken(user, tokenKey);
}
readTokens(filter) {
if (_lodash.default.isFunction(this.storagePlugin.readTokens) === false) {
return Promise.reject(_utils.ErrorCode.getCode(_constants.HTTP_STATUS.SERVICE_UNAVAILABLE, _constants.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
}
return this.storagePlugin.readTokens(filter);
}
}
var _default = LocalStorage;
exports.default = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvbG9jYWwtc3RvcmFnZS50cyJdLCJuYW1lcyI6WyJMb2NhbFN0b3JhZ2UiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImxvZ2dlciIsImNoaWxkIiwic3ViIiwic3RvcmFnZVBsdWdpbiIsIl9sb2FkU3RvcmFnZSIsImFkZFBhY2thZ2UiLCJuYW1lIiwicGtnIiwiY2FsbGJhY2siLCJzdG9yYWdlIiwiX2dldExvY2FsU3RvcmFnZSIsIl8iLCJpc05pbCIsIkVycm9yQ29kZSIsImdldE5vdEZvdW5kIiwiY3JlYXRlUGFja2FnZSIsImVyciIsImlzTnVsbCIsImNvZGUiLCJTVE9SQUdFIiwiRklMRV9FWElTVF9FUlJPUiIsIkhUVFBfU1RBVFVTIiwiQ09ORkxJQ1QiLCJnZXRDb25mbGljdCIsImxhdGVzdCIsInZlcnNpb25zIiwicmVtb3ZlUGFja2FnZSIsImRlYnVnIiwicmVhZFBhY2thZ2UiLCJkYXRhIiwiTk9fU1VDSF9GSUxFX0VSUk9SIiwiTk9UX0ZPVU5EIiwicmVtb3ZlIiwicmVtb3ZlRmFpbGVkIiwiZ2V0QmFkRGF0YSIsIm1lc3NhZ2UiLCJkZWxldGVQYWNrYWdlIiwiUEFDS0FHRV9GSUxFX05BTUUiLCJhdHRhY2htZW50cyIsIk9iamVjdCIsImtleXMiLCJfYXR0YWNobWVudHMiLCJfZGVsZXRlQXR0YWNobWVudHMiLCJ1cGRhdGVWZXJzaW9ucyIsInBhY2thZ2VJbmZvIiwiX3JlYWRDcmVhdGVQYWNrYWdlIiwicGFja2FnZUxvY2FsSnNvbiIsImNoYW5nZSIsInJlYWRtZSIsInZlcnNpb25JZCIsInZlcnNpb24iLCJjb250cmlidXRvcnMiLCJkaXN0IiwidGFyYmFsbCIsInVybE9iamVjdCIsIlVybE5vZGUiLCJwYXJzZSIsImZpbGVuYW1lIiwicGF0aG5hbWUiLCJyZXBsYWNlIiwiX2Rpc3RmaWxlcyIsImhhc2giLCJ1cmwiLCJzaGEiLCJzaGFzdW0iLCJ1cExpbmsiLCJTeW1ib2wiLCJmb3IiLCJfdXBkYXRlVXBsaW5rVG9SZW1vdGVQcm90b2NvbCIsInRhZyIsIkRJU1RfVEFHUyIsInVwIiwiX3VwbGlua3MiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJuZWVkX2NoYW5nZSIsImV0YWciLCJmZXRjaGVkIiwiaXNFcXVhbCIsInRpbWUiLCJfd3JpdGVQYWNrYWdlIiwiYWRkVmVyc2lvbiIsIm1ldGFkYXRhIiwiX3VwZGF0ZVBhY2thZ2UiLCJjYiIsImhhc1ZlcnNpb24iLCJpc1N0cmluZyIsImVycm9yTWVzc2FnZSIsImdldEJhZFJlcXVlc3QiLCJjdXJyZW50RGF0ZSIsIkRhdGUiLCJ0b0lTT1N0cmluZyIsImNyZWF0ZWQiLCJhZGQiLCJhZGRGYWlsZWQiLCJtZXJnZVRhZ3MiLCJwa2dOYW1lIiwidGFncyIsIl9nZXRWZXJzaW9uTm90Rm91bmQiLCJBUElfRVJST1IiLCJWRVJTSU9OX05PVF9FWElTVCIsIl9nZXRGaWxlTm90QXZhaWxhYmxlIiwiY2hhbmdlUGFja2FnZSIsImluY29taW5nUGtnIiwicmV2aXNpb24iLCJsb2NhbERhdGEiLCJpbmNvbWluZ1ZlcnNpb24iLCJpbmZvIiwiZmlsZSIsImluY29taW5nRGVwcmVjYXRlZCIsImRlcHJlY2F0ZWQiLCJtb2RpZmllZCIsIlVTRVJTIiwicmVtb3ZlVGFyYmFsbCIsImFkZFRhcmJhbGwiLCJsZW5ndGgiLCJzaGFPbmVIYXNoIiwidXBsb2FkU3RyZWFtIiwiVXBsb2FkVGFyYmFsbCIsIl90cmFuc2Zvcm0iLCJhYm9ydCIsImRvbmUiLCJhcmdzIiwidXBkYXRlIiwiYXBwbGllZERhdGEiLCJhcHBseSIsInByb2Nlc3MiLCJuZXh0VGljayIsImVtaXQiLCJnZXRGb3JiaWRkZW4iLCJ3cml0ZVN0cmVhbSIsIndyaXRlVGFyYmFsbCIsIm9uIiwiZ2V0UGFja2FnZU1ldGFkYXRhIiwiX2VyciIsIl9yZXMiLCJ1cGRhdGVyIiwiZGlnZXN0IiwicGlwZSIsImdldFRhcmJhbGwiLCJfY3JlYXRlRmFpbHVyZVN0cmVhbVJlc3BvbnNlIiwiX3N0cmVhbVN1Y2Nlc3NSZWFkVGFyQmFsbCIsInN0cmVhbSIsIlJlYWRUYXJiYWxsIiwicmVhZFRhcmJhbGxTdHJlYW0iLCJyZWFkVGFyYmFsbCIsImU0MDQiLCJjb250ZW50IiwiX3JlYWRQYWNrYWdlIiwic2VhcmNoIiwic3RhcnRLZXkiLCJvcHRpb25zIiwib2JqZWN0TW9kZSIsIl9zZWFyY2hFYWNoUGFja2FnZSIsIml0ZW0iLCJwYXJzZUludCIsInJlc3VsdCIsInB1c2giLCJvbkVuZCIsImVuZCIsImdldFBhY2thZ2VTdG9yYWdlIiwiX2ludGVybmFsRXJyb3IiLCJvblBhY2thZ2UiLCJ3YXJuIiwidmFsaWRhdGVOYW1lIiwiX2NyZWF0ZU5ld1BhY2thZ2UiLCJlcnJvciIsImdldEludGVybmFsRXJyb3IiLCJ1cGRhdGVIYW5kbGVyIiwidXBkYXRlUGFja2FnZSIsImJpbmQiLCJub3JtYWxpemVQYWNrYWdlIiwianNvbiIsInNhdmVQYWNrYWdlIiwiX3NldERlZmF1bHRSZXZpc2lvbiIsIl9yZXYiLCJERUZBVUxUX1JFVklTSU9OIiwiX2RlYnVnIiwibCIsInVubGlua05leHQiLCJpc0VtcHR5IiwiYXR0YWNobWVudCIsInNoaWZ0IiwidXBMaW5rS2V5IiwidGFyYmFsbFVybCIsInVwbGlua1VybCIsInVwbGlua3MiLCJob3N0IiwicHJvdG9jb2wiLCJyZWdpc3RyeSIsImZvcm1hdCIsImdldFNlY3JldCIsInNlY3JldEtleSIsInNldFNlY3JldCIsImNoZWNrU2VjcmV0S2V5IiwiU3RvcmFnZSIsIl9sb2FkU3RvcmVQbHVnaW4iLCJMb2NhbERhdGFiYXNlIiwicGx1Z2luX3BhcmFtcyIsInBsdWdpbnMiLCJzdG9yZSIsInBsdWdpbiIsImhlYWQiLCJzYXZlVG9rZW4iLCJ0b2tlbiIsImlzRnVuY3Rpb24iLCJQcm9taXNlIiwicmVqZWN0IiwiZ2V0Q29kZSIsIlNFUlZJQ0VfVU5BVkFJTEFCTEUiLCJTVVBQT1JUX0VSUk9SUyIsIlBMVUdJTl9NSVNTSU5HX0lOVEVSRkFDRSIsImRlbGV0ZVRva2VuIiwidXNl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