UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

122 lines (118 loc) 14.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createServerFactory = createServerFactory; exports.runServer = runServer; var _constants = _interopRequireDefault(require("constants")); var _debug = _interopRequireDefault(require("debug")); var _fs = _interopRequireDefault(require("fs")); var _http = _interopRequireDefault(require("http")); var _https = _interopRequireDefault(require("https")); var _lodash = require("lodash"); var _config = require("@verdaccio/config"); var _index = _interopRequireDefault(require("../api/index")); var _experiments = require("./experiments"); var _logger = require("./logger"); var _utils = require("./utils"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const debug = (0, _debug.default)('verdaccio:run-server'); /** * Exposes a server factory to be instantiated programmatically. * const app = await runServer(); // default configuration const app = await runServer('./config/config.yaml'); const app = await runServer({ configuration }); app.listen(4000, (event) => { // do something }); * @param config */ async function runServer(config, options) { const configurationParsed = (0, _config.getConfigParsed)(config); (0, _utils.initLogger)(configurationParsed); // merge flags and experiments for backward compatibility const flags = { ...(configurationParsed?.flags || {}), ...(configurationParsed?.experiments || {}) }; (0, _experiments.displayExperimentsInfoBox)(flags); const listen = options?.listenArg ?? configurationParsed?.listen; const address = (0, _config.getListenAddress)(listen, _logger.logger); const app = await (0, _index.default)(configurationParsed); return createServerFactory(configurationParsed, address, app); } /** * Return a native HTTP/HTTPS server instance * @param config * @param addr * @param app */ function createServerFactory(config, addr, app) { let serverFactory; if (addr.proto === 'https') { debug('https enabled'); try { let httpsOptions = { // disable insecure SSLv2 and SSLv3 secureOptions: _constants.default.SSL_OP_NO_SSLv2 | _constants.default.SSL_OP_NO_SSLv3 }; const keyCertConfig = config.https; const pfxConfig = config.https; // https must either have key and cert or a pfx and (optionally) a passphrase if (!(keyCertConfig.key && keyCertConfig.cert || pfxConfig.pfx)) { throw Error('bad format https configuration'); } if (pfxConfig.pfx) { const { pfx, passphrase } = pfxConfig; httpsOptions = (0, _lodash.assign)(httpsOptions, { pfx: _fs.default.readFileSync(pfx), passphrase: passphrase || '' }); } else { const { key, cert, ca } = keyCertConfig; httpsOptions = (0, _lodash.assign)(httpsOptions, { key: _fs.default.readFileSync(key), cert: _fs.default.readFileSync(cert), ...(ca && { ca: _fs.default.readFileSync(ca) }) }); } // TODO: enable http2 as feature // if (config.server.http2) <-- check if force http2 serverFactory = _https.default.createServer(httpsOptions, app); } catch (err) { _logger.logger.fatal({ err: err }, 'cannot create server: @{err.message}'); process.exit(2); } } else { // http debug('http enabled'); serverFactory = _http.default.createServer(app); } if (config.server && typeof config.server.keepAliveTimeout !== 'undefined' && // @ts-ignore config.server.keepAliveTimeout !== 'null') { // library definition for node is not up to date (doesn't contain recent 8.0 changes) serverFactory.keepAliveTimeout = config.server.keepAliveTimeout * 1000; } // FIXE: I could not find the reason of this code. unlinkAddressPath(addr); return serverFactory; } function unlinkAddressPath(addr) { if (addr.path && _fs.default.existsSync(addr.path)) { _fs.default.unlinkSync(addr.path); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc3RhbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZGVidWciLCJfZnMiLCJfaHR0cCIsIl9odHRwcyIsIl9sb2Rhc2giLCJfY29uZmlnIiwiX2luZGV4IiwiX2V4cGVyaW1lbnRzIiwiX2xvZ2dlciIsIl91dGlscyIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImRlYnVnIiwiYnVpbGREZWJ1ZyIsInJ1blNlcnZlciIsImNvbmZpZyIsIm9wdGlvbnMiLCJjb25maWd1cmF0aW9uUGFyc2VkIiwiZ2V0Q29uZmlnUGFyc2VkIiwiaW5pdExvZ2dlciIsImZsYWdzIiwiZXhwZXJpbWVudHMiLCJkaXNwbGF5RXhwZXJpbWVudHNJbmZvQm94IiwibGlzdGVuIiwibGlzdGVuQXJnIiwiYWRkcmVzcyIsImdldExpc3RlbkFkZHJlc3MiLCJsb2dnZXIiLCJhcHAiLCJlbmRQb2ludEFQSSIsImNyZWF0ZVNlcnZlckZhY3RvcnkiLCJhZGRyIiwic2VydmVyRmFjdG9yeSIsInByb3RvIiwiaHR0cHNPcHRpb25zIiwic2VjdXJlT3B0aW9ucyIsImNvbnN0YW50cyIsIlNTTF9PUF9OT19TU0x2MiIsIlNTTF9PUF9OT19TU0x2MyIsImtleUNlcnRDb25maWciLCJodHRwcyIsInBmeENvbmZpZyIsImtleSIsImNlcnQiLCJwZngiLCJFcnJvciIsInBhc3NwaHJhc2UiLCJhc3NpZ24iLCJmcyIsInJlYWRGaWxlU3luYyIsImNhIiwiY3JlYXRlU2VydmVyIiwiZXJyIiwiZmF0YWwiLCJwcm9jZXNzIiwiZXhpdCIsImh0dHAiLCJzZXJ2ZXIiLCJrZWVwQWxpdmVUaW1lb3V0IiwidW5saW5rQWRkcmVzc1BhdGgiLCJwYXRoIiwiZXhpc3RzU3luYyIsInVubGlua1N5bmMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3J1bi1zZXJ2ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNvbnN0YW50cyBmcm9tICdjb25zdGFudHMnO1xuaW1wb3J0IGJ1aWxkRGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBodHRwIGZyb20gJ2h0dHAnO1xuaW1wb3J0IGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ2xvZGFzaCc7XG5cbmltcG9ydCB7IGdldENvbmZpZ1BhcnNlZCwgZ2V0TGlzdGVuQWRkcmVzcyB9IGZyb20gJ0B2ZXJkYWNjaW8vY29uZmlnJztcbmltcG9ydCB7IENvbmZpZ1lhbWwsIEh0dHBzQ29uZktleUNlcnQsIEh0dHBzQ29uZlBmeCB9IGZyb20gJ0B2ZXJkYWNjaW8vdHlwZXMnO1xuXG5pbXBvcnQgZW5kUG9pbnRBUEkgZnJvbSAnLi4vYXBpL2luZGV4JztcbmltcG9ydCB7IGRpc3BsYXlFeHBlcmltZW50c0luZm9Cb3ggfSBmcm9tICcuL2V4cGVyaW1lbnRzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7IGluaXRMb2dnZXIgfSBmcm9tICcuL3V0aWxzJztcblxuY29uc3QgZGVidWcgPSBidWlsZERlYnVnKCd2ZXJkYWNjaW86cnVuLXNlcnZlcicpO1xuXG4vKipcbiAqIEV4cG9zZXMgYSBzZXJ2ZXIgZmFjdG9yeSB0byBiZSBpbnN0YW50aWF0ZWQgcHJvZ3JhbW1hdGljYWxseS5cbiAqXG4gICAgY29uc3QgYXBwID0gYXdhaXQgcnVuU2VydmVyKCk7IC8vIGRlZmF1bHQgY29uZmlndXJhdGlvblxuICAgIGNvbnN0IGFwcCA9IGF3YWl0IHJ1blNlcnZlcignLi9jb25maWcvY29uZmlnLnlhbWwnKTtcbiAgICBjb25zdCBhcHAgPSBhd2FpdCBydW5TZXJ2ZXIoeyBjb25maWd1cmF0aW9uIH0pO1xuICAgIGFwcC5saXN0ZW4oNDAwMCwgKGV2ZW50KSA9PiB7XG4gICAgICAvLyBkbyBzb21ldGhpbmdcbiAgICB9KTtcbiAqIEBwYXJhbSBjb25maWdcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blNlcnZlcihcbiAgY29uZmlnPzogc3RyaW5nIHwgQ29uZmlnWWFtbCxcbiAgb3B0aW9ucz86IHsgbGlzdGVuQXJnPzogc3RyaW5nIH1cbik6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IGNvbmZpZ3VyYXRpb25QYXJzZWQgPSBnZXRDb25maWdQYXJzZWQoY29uZmlnKTtcblxuICBpbml0TG9nZ2VyKGNvbmZpZ3VyYXRpb25QYXJzZWQpO1xuICAvLyBtZXJnZSBmbGFncyBhbmQgZXhwZXJpbWVudHMgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbiAgY29uc3QgZmxhZ3MgPSB7XG4gICAgLi4uKGNvbmZpZ3VyYXRpb25QYXJzZWQ/LmZsYWdzIHx8IHt9KSxcbiAgICAuLi4oY29uZmlndXJhdGlvblBhcnNlZD8uZXhwZXJpbWVudHMgfHwge30pLFxuICB9O1xuICBkaXNwbGF5RXhwZXJpbWVudHNJbmZvQm94KGZsYWdzKTtcblxuICBjb25zdCBsaXN0ZW4gPSBvcHRpb25zPy5saXN0ZW5BcmcgPz8gY29uZmlndXJhdGlvblBhcnNlZD8ubGlzdGVuO1xuICBjb25zdCBhZGRyZXNzID0gZ2V0TGlzdGVuQWRkcmVzcyhsaXN0ZW4sIGxvZ2dlcik7XG5cbiAgY29uc3QgYXBwID0gYXdhaXQgZW5kUG9pbnRBUEkoY29uZmlndXJhdGlvblBhcnNlZCk7XG4gIHJldHVybiBjcmVhdGVTZXJ2ZXJGYWN0b3J5KGNvbmZpZ3VyYXRpb25QYXJzZWQsIGFkZHJlc3MsIGFwcCk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgbmF0aXZlIEhUVFAvSFRUUFMgc2VydmVyIGluc3RhbmNlXG4gKiBAcGFyYW0gY29uZmlnXG4gKiBAcGFyYW0gYWRkclxuICogQHBhcmFtIGFwcFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2VydmVyRmFjdG9yeShjb25maWc6IENvbmZpZ1lhbWwsIGFkZHIsIGFwcCkge1xuICBsZXQgc2VydmVyRmFjdG9yeTtcbiAgaWYgKGFkZHIucHJvdG8gPT09ICdodHRwcycpIHtcbiAgICBkZWJ1ZygnaHR0cHMgZW5hYmxlZCcpO1xuICAgIHRyeSB7XG4gICAgICBsZXQgaHR0cHNPcHRpb25zID0ge1xuICAgICAgICAvLyBkaXNhYmxlIGluc2VjdXJlIFNTTHYyIGFuZCBTU0x2M1xuICAgICAgICBzZWN1cmVPcHRpb25zOiBjb25zdGFudHMuU1NMX09QX05PX1NTTHYyIHwgY29uc3RhbnRzLlNTTF9PUF9OT19TU0x2MyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGtleUNlcnRDb25maWcgPSBjb25maWcuaHR0cHMgYXMgSHR0cHNDb25mS2V5Q2VydDtcbiAgICAgIGNvbnN0IHBmeENvbmZpZyA9IGNvbmZpZy5odHRwcyBhcyBIdHRwc0NvbmZQZng7XG5cbiAgICAgIC8vIGh0dHBzIG11c3QgZWl0aGVyIGhhdmUga2V5IGFuZCBjZXJ0IG9yIGEgcGZ4IGFuZCAob3B0aW9uYWxseSkgYSBwYXNzcGhyYXNlXG4gICAgICBpZiAoISgoa2V5Q2VydENvbmZpZy5rZXkgJiYga2V5Q2VydENvbmZpZy5jZXJ0KSB8fCBwZnhDb25maWcucGZ4KSkge1xuICAgICAgICB0aHJvdyBFcnJvcignYmFkIGZvcm1hdCBodHRwcyBjb25maWd1cmF0aW9uJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwZnhDb25maWcucGZ4KSB7XG4gICAgICAgIGNvbnN0IHsgcGZ4LCBwYXNzcGhyYXNlIH0gPSBwZnhDb25maWc7XG4gICAgICAgIGh0dHBzT3B0aW9ucyA9IGFzc2lnbihodHRwc09wdGlvbnMsIHtcbiAgICAgICAgICBwZng6IGZzLnJlYWRGaWxlU3luYyhwZngpLFxuICAgICAgICAgIHBhc3NwaHJhc2U6IHBhc3NwaHJhc2UgfHwgJycsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgeyBrZXksIGNlcnQsIGNhIH0gPSBrZXlDZXJ0Q29uZmlnO1xuICAgICAgICBodHRwc09wdGlvbnMgPSBhc3NpZ24oaHR0cHNPcHRpb25zLCB7XG4gICAgICAgICAga2V5OiBmcy5yZWFkRmlsZVN5bmMoa2V5KSxcbiAgICAgICAgICBjZXJ0OiBmcy5yZWFkRmlsZVN5bmMoY2VydCksXG4gICAgICAgICAgLi4uKGNhICYmIHtcbiAgICAgICAgICAgIGNhOiBmcy5yZWFkRmlsZVN5bmMoY2EpLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIC8vIFRPRE86IGVuYWJsZSBodHRwMiBhcyBmZWF0dXJlXG4gICAgICAvLyBpZiAoY29uZmlnLnNlcnZlci5odHRwMikgPC0tIGNoZWNrIGlmIGZvcmNlIGh0dHAyXG4gICAgICBzZXJ2ZXJGYWN0b3J5ID0gaHR0cHMuY3JlYXRlU2VydmVyKGh0dHBzT3B0aW9ucywgYXBwKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgbG9nZ2VyLmZhdGFsKHsgZXJyOiBlcnIgfSwgJ2Nhbm5vdCBjcmVhdGUgc2VydmVyOiBAe2Vyci5tZXNzYWdlfScpO1xuICAgICAgcHJvY2Vzcy5leGl0KDIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBodHRwXG4gICAgZGVidWcoJ2h0dHAgZW5hYmxlZCcpO1xuICAgIHNlcnZlckZhY3RvcnkgPSBodHRwLmNyZWF0ZVNlcnZlcihhcHApO1xuICB9XG5cbiAgaWYgKFxuICAgIGNvbmZpZy5zZXJ2ZXIgJiZcbiAgICB0eXBlb2YgY29uZmlnLnNlcnZlci5rZWVwQWxpdmVUaW1lb3V0ICE9PSAndW5kZWZpbmVkJyAmJlxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBjb25maWcuc2VydmVyLmtlZXBBbGl2ZVRpbWVvdXQgIT09ICdudWxsJ1xuICApIHtcbiAgICAvLyBsaWJyYXJ5IGRlZmluaXRpb24gZm9yIG5vZGUgaXMgbm90IHVwIHRvIGRhdGUgKGRvZXNuJ3QgY29udGFpbiByZWNlbnQgOC4wIGNoYW5nZXMpXG4gICAgc2VydmVyRmFjdG9yeS5rZWVwQWxpdmVUaW1lb3V0ID0gY29uZmlnLnNlcnZlci5rZWVwQWxpdmVUaW1lb3V0ICogMTAwMDtcbiAgfVxuICAvLyBGSVhFOiBJIGNvdWxkIG5vdCBmaW5kIHRoZSByZWFzb24gb2YgdGhpcyBjb2RlLlxuICB1bmxpbmtBZGRyZXNzUGF0aChhZGRyKTtcblxuICByZXR1cm4gc2VydmVyRmFjdG9yeTtcbn1cblxuZnVuY3Rpb24gdW5saW5rQWRkcmVzc1BhdGgoYWRkcikge1xuICBpZiAoYWRkci5wYXRoICYmIGZzLmV4aXN0c1N5bmMoYWRkci5wYXRoKSkge1xuICAgIGZzLnVubGlua1N5bmMoYWRkci5wYXRoKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsSUFBQUEsVUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsTUFBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsR0FBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUcsS0FBQSxHQUFBSixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUksTUFBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUssT0FBQSxHQUFBTCxPQUFBO0FBRUEsSUFBQU0sT0FBQSxHQUFBTixPQUFBO0FBR0EsSUFBQU8sTUFBQSxHQUFBUixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVEsWUFBQSxHQUFBUixPQUFBO0FBQ0EsSUFBQVMsT0FBQSxHQUFBVCxPQUFBO0FBQ0EsSUFBQVUsTUFBQSxHQUFBVixPQUFBO0FBQXFDLFNBQUFELHVCQUFBWSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRXJDLE1BQU1HLEtBQUssR0FBRyxJQUFBQyxjQUFVLEVBQUMsc0JBQXNCLENBQUM7O0FBRWhEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxlQUFlQyxTQUFTQSxDQUM3QkMsTUFBNEIsRUFDNUJDLE9BQWdDLEVBQ2xCO0VBQ2QsTUFBTUMsbUJBQW1CLEdBQUcsSUFBQUMsdUJBQWUsRUFBQ0gsTUFBTSxDQUFDO0VBRW5ELElBQUFJLGlCQUFVLEVBQUNGLG1CQUFtQixDQUFDO0VBQy9CO0VBQ0EsTUFBTUcsS0FBSyxHQUFHO0lBQ1osSUFBSUgsbUJBQW1CLEVBQUVHLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNyQyxJQUFJSCxtQkFBbUIsRUFBRUksV0FBVyxJQUFJLENBQUMsQ0FBQztFQUM1QyxDQUFDO0VBQ0QsSUFBQUMsc0NBQXlCLEVBQUNGLEtBQUssQ0FBQztFQUVoQyxNQUFNRyxNQUFNLEdBQUdQLE9BQU8sRUFBRVEsU0FBUyxJQUFJUCxtQkFBbUIsRUFBRU0sTUFBTTtFQUNoRSxNQUFNRSxPQUFPLEdBQUcsSUFBQUMsd0JBQWdCLEVBQUNILE1BQU0sRUFBRUksY0FBTSxDQUFDO0VBRWhELE1BQU1DLEdBQUcsR0FBRyxNQUFNLElBQUFDLGNBQVcsRUFBQ1osbUJBQW1CLENBQUM7RUFDbEQsT0FBT2EsbUJBQW1CLENBQUNiLG1CQUFtQixFQUFFUSxPQUFPLEVBQUVHLEdBQUcsQ0FBQztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTRSxtQkFBbUJBLENBQUNmLE1BQWtCLEVBQUVnQixJQUFJLEVBQUVILEdBQUcsRUFBRTtFQUNqRSxJQUFJSSxhQUFhO0VBQ2pCLElBQUlELElBQUksQ0FBQ0UsS0FBSyxLQUFLLE9BQU8sRUFBRTtJQUMxQnJCLEtBQUssQ0FBQyxlQUFlLENBQUM7SUFDdEIsSUFBSTtNQUNGLElBQUlzQixZQUFZLEdBQUc7UUFDakI7UUFDQUMsYUFBYSxFQUFFQyxrQkFBUyxDQUFDQyxlQUFlLEdBQUdELGtCQUFTLENBQUNFO01BQ3ZELENBQUM7TUFFRCxNQUFNQyxhQUFhLEdBQUd4QixNQUFNLENBQUN5QixLQUF5QjtNQUN0RCxNQUFNQyxTQUFTLEdBQUcxQixNQUFNLENBQUN5QixLQUFxQjs7TUFFOUM7TUFDQSxJQUFJLEVBQUdELGFBQWEsQ0FBQ0csR0FBRyxJQUFJSCxhQUFhLENBQUNJLElBQUksSUFBS0YsU0FBUyxDQUFDRyxHQUFHLENBQUMsRUFBRTtRQUNqRSxNQUFNQyxLQUFLLENBQUMsZ0NBQWdDLENBQUM7TUFDL0M7TUFFQSxJQUFJSixTQUFTLENBQUNHLEdBQUcsRUFBRTtRQUNqQixNQUFNO1VBQUVBLEdBQUc7VUFBRUU7UUFBVyxDQUFDLEdBQUdMLFNBQVM7UUFDckNQLFlBQVksR0FBRyxJQUFBYSxjQUFNLEVBQUNiLFlBQVksRUFBRTtVQUNsQ1UsR0FBRyxFQUFFSSxXQUFFLENBQUNDLFlBQVksQ0FBQ0wsR0FBRyxDQUFDO1VBQ3pCRSxVQUFVLEVBQUVBLFVBQVUsSUFBSTtRQUM1QixDQUFDLENBQUM7TUFDSixDQUFDLE1BQU07UUFDTCxNQUFNO1VBQUVKLEdBQUc7VUFBRUMsSUFBSTtVQUFFTztRQUFHLENBQUMsR0FBR1gsYUFBYTtRQUN2Q0wsWUFBWSxHQUFHLElBQUFhLGNBQU0sRUFBQ2IsWUFBWSxFQUFFO1VBQ2xDUSxHQUFHLEVBQUVNLFdBQUUsQ0FBQ0MsWUFBWSxDQUFDUCxHQUFHLENBQUM7VUFDekJDLElBQUksRUFBRUssV0FBRSxDQUFDQyxZQUFZLENBQUNOLElBQUksQ0FBQztVQUMzQixJQUFJTyxFQUFFLElBQUk7WUFDUkEsRUFBRSxFQUFFRixXQUFFLENBQUNDLFlBQVksQ0FBQ0MsRUFBRTtVQUN4QixDQUFDO1FBQ0gsQ0FBQyxDQUFDO01BQ0o7TUFDQTtNQUNBO01BQ0FsQixhQUFhLEdBQUdRLGNBQUssQ0FBQ1csWUFBWSxDQUFDakIsWUFBWSxFQUFFTixHQUFHLENBQUM7SUFDdkQsQ0FBQyxDQUFDLE9BQU93QixHQUFRLEVBQUU7TUFDakJ6QixjQUFNLENBQUMwQixLQUFLLENBQUM7UUFBRUQsR0FBRyxFQUFFQTtNQUFJLENBQUMsRUFBRSxzQ0FBc0MsQ0FBQztNQUNsRUUsT0FBTyxDQUFDQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2pCO0VBQ0YsQ0FBQyxNQUFNO0lBQ0w7SUFDQTNDLEtBQUssQ0FBQyxjQUFjLENBQUM7SUFDckJvQixhQUFhLEdBQUd3QixhQUFJLENBQUNMLFlBQVksQ0FBQ3ZCLEdBQUcsQ0FBQztFQUN4QztFQUVBLElBQ0ViLE1BQU0sQ0FBQzBDLE1BQU0sSUFDYixPQUFPMUMsTUFBTSxDQUFDMEMsTUFBTSxDQUFDQyxnQkFBZ0IsS0FBSyxXQUFXO0VBQ3JEO0VBQ0EzQyxNQUFNLENBQUMwQyxNQUFNLENBQUNDLGdCQUFnQixLQUFLLE1BQU0sRUFDekM7SUFDQTtJQUNBMUIsYUFBYSxDQUFDMEIsZ0JBQWdCLEdBQUczQyxNQUFNLENBQUMwQyxNQUFNLENBQUNDLGdCQUFnQixHQUFHLElBQUk7RUFDeEU7RUFDQTtFQUNBQyxpQkFBaUIsQ0FBQzVCLElBQUksQ0FBQztFQUV2QixPQUFPQyxhQUFhO0FBQ3RCO0FBRUEsU0FBUzJCLGlCQUFpQkEsQ0FBQzVCLElBQUksRUFBRTtFQUMvQixJQUFJQSxJQUFJLENBQUM2QixJQUFJLElBQUlaLFdBQUUsQ0FBQ2EsVUFBVSxDQUFDOUIsSUFBSSxDQUFDNkIsSUFBSSxDQUFDLEVBQUU7SUFDekNaLFdBQUUsQ0FBQ2MsVUFBVSxDQUFDL0IsSUFBSSxDQUFDNkIsSUFBSSxDQUFDO0VBQzFCO0FBQ0YiLCJpZ25vcmVMaXN0IjpbXX0=