react-static
Version:
A progressive static site generator for React
392 lines (321 loc) • 45.5 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = getConfig;
exports.buildConfig = buildConfig;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _path = _interopRequireDefault(require("path"));
var _chokidar = _interopRequireDefault(require("chokidar"));
var _resolveFrom = _interopRequireDefault(require("resolve-from"));
var _fsExtra = _interopRequireDefault(require("fs-extra"));
var _utils = require("../utils");
var _plugins = _interopRequireWildcard(require("./plugins"));
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
// the default static.config.js location
var defaultConfig = {};
var DEFAULT_NAME_FOR_STATIC_CONFIG_FILE = 'static.config.js';
var DEFAULT_PATH_FOR_STATIC_CONFIG = _path["default"].resolve(_path["default"].join(process.cwd(), DEFAULT_NAME_FOR_STATIC_CONFIG_FILE));
var DEFAULT_ROUTES = [{
path: '/'
}];
var DEFAULT_ENTRY = 'index.js';
var DEFAULT_EXTENSIONS = ['.js', '.jsx']; // Retrieves the static.config.js from the current project directory
function getConfig(state) {
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(config) {
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (state.debug) {
console.log('getConfig():');
console.log(state);
}
return _context.abrupt("return", config);
case 2:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}();
var configPath = state.configPath || state.packageConfig.config || DEFAULT_PATH_FOR_STATIC_CONFIG;
state = _objectSpread(_objectSpread({}, state), {}, {
originalConfig: configPath
});
var resolvedPath = _path["default"].resolve(configPath);
var noConfig = configPath === DEFAULT_PATH_FOR_STATIC_CONFIG && !resolvedPath;
if (noConfig) {
// last
state = buildConfig(state, defaultConfig);
return callback(state)["catch"](console.error);
}
state = buildConfigFromPath(state, resolvedPath || configPath);
if (state.stage === 'dev') {
_chokidar["default"].watch(resolvedPath, {
ignoreInitial: true
}).on('all', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
console.log('');
console.log("Updating static.config.js");
state = buildConfigFromPath(state, resolvedPath);
callback(state)["catch"](console.error);
case 4:
case "end":
return _context2.stop();
}
}
}, _callee2);
})));
}
return callback(state)["catch"](console.error);
}
function buildConfigFromPath(state, configPath) {
delete require.cache[configPath];
var config = require(configPath)["default"];
return buildConfig(state, config);
}
function buildConfig(state) {
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// Default Paths
var paths = _objectSpread({
root: _path["default"].resolve(process.cwd()),
src: 'src',
dist: 'dist',
temp: 'tmp',
buildArtifacts: 'artifacts',
devDist: 'tmp/dev-server',
"public": 'public',
plugins: 'plugins',
pages: 'src/pages',
nodeModules: 'node_modules',
assets: ''
}, config.paths || {}); // Use the root to resolve all other relative paths
var resolvePath = function resolvePath(relativePath) {
return _path["default"].resolve(paths.root, relativePath);
}; // Resolve and replace all pathss
var DIST = process.env.REACT_STATIC_ENV === 'development' ? resolvePath(paths.devDist || paths.dist) : resolvePath(paths.dist);
var ASSETS = _path["default"].resolve(DIST, paths.assets);
paths = {
ROOT: paths.root,
SRC: resolvePath(paths.src),
DIST: DIST,
ASSETS: ASSETS,
PLUGINS: resolvePath(paths.plugins),
TEMP: resolvePath(paths.temp),
ARTIFACTS: resolvePath(paths.buildArtifacts),
PUBLIC: resolvePath(paths["public"]),
NODE_MODULES: resolvePath(paths.nodeModules),
EXCLUDE_MODULES: paths.excludeResolvedModules || resolvePath(paths.nodeModules),
PACKAGE: resolvePath('package.json'),
HTML_TEMPLATE: _path["default"].join(DIST, 'index.html'),
STATIC_DATA: _path["default"].join(ASSETS, 'staticData')
}; // siteRoot, basePath, publicPath, and assetPath resolution
var siteRoot = '';
var basePath = '';
var assetsPath = '';
if (process.env.REACT_STATIC_ENV === 'development') {
basePath = (0, _utils.cleanSlashes)(config.devBasePath);
assetsPath = config.devAssetsPath || paths.assets || assetsPath;
} else if (state.staging) {
siteRoot = (0, _utils.cutPathToRoot)(config.stagingSiteRoot || '/', '$1');
basePath = (0, _utils.cleanSlashes)(config.stagingBasePath);
assetsPath = config.stagingAssetsPath || paths.assets || assetsPath;
} else {
siteRoot = (0, _utils.cutPathToRoot)(config.siteRoot || '/', '$1');
basePath = (0, _utils.cleanSlashes)(config.basePath);
assetsPath = config.assetsPath || paths.assets || assetsPath;
}
var publicPath = "".concat((0, _utils.cleanSlashes)("".concat(siteRoot, "/").concat(basePath), {
leading: false
}), "/");
if (assetsPath && !(0, _utils.isAbsoluteUrl)(assetsPath)) {
assetsPath = "/".concat((0, _utils.cleanSlashes)("".concat(basePath, "/").concat(assetsPath)), "/");
} // add trailing slash only if assetsPath was supplied, but no trailing slash
if (assetsPath && !assetsPath.endsWith('/')) {
assetsPath = "".concat(assetsPath, "/");
} // Add the project root as a plugin. This allows the dev
// to use the plugin api directory in their project if they want
var plugins = [].concat((0, _toConsumableArray2["default"])(config.plugins || []), [paths.ROOT]); // if (process.env.NODE_ENV !== 'test' && !entry) {
// throw new Error(
// `Could not resolve entry file from location: ${entry} using extensions: ${(
// config.extensions || DEFAULT_EXTENSIONS
// ).join(', ')}`
// )
// }
// Defaults
config = _objectSpread(_objectSpread({
// Defaults
getSiteData: function getSiteData() {
return {};
},
prefetchRate: 5,
maxThreads: Infinity,
disableRoutePrefixing: false,
outputFileRate: 100,
extensions: DEFAULT_EXTENSIONS,
getRoutes: function () {
var _getRoutes = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
return _context3.abrupt("return", DEFAULT_ROUTES);
case 1:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
function getRoutes() {
return _getRoutes.apply(this, arguments);
}
return getRoutes;
}(),
minLoadTime: 200,
disablePreload: false,
disableRuntime: false,
preloadPollInterval: 300,
productionSourceMaps: false,
silent: false,
entry: DEFAULT_ENTRY
}, config), {}, {
// Materialized Overrides
paths: paths,
plugins: plugins,
siteRoot: siteRoot,
basePath: basePath,
publicPath: publicPath,
assetsPath: assetsPath,
extractCssChunks: config.extractCssChunks || false,
inlineCss: config.inlineCss || false,
babelExcludes: config.babelExcludes || [],
devServer: _objectSpread({
host: 'localhost',
port: 3000
}, config.devServer || {})
});
config.terser = config.terser || {};
config.terser.terserOptions = config.terser.terserOptions || {};
config.terser.terserOptions.mangle = config.terser.terserOptions.mangle || {};
config.terser.terserOptions.parse = config.terser.terserOptions.parse || {};
config.terser.terserOptions.compress = config.terser.terserOptions.compress || {};
config.terser.terserOptions.output = config.terser.terserOptions.output || {}; // Set env variables to be used client side
process.env.REACT_STATIC_MIN_LOAD_TIME = config.minLoadTime;
process.env.REACT_STATIC_PREFETCH_RATE = config.prefetchRate;
process.env.REACT_STATIC_DISABLE_ROUTE_PREFIXING = config.disableRoutePrefixing;
process.env.REACT_STATIC_DISABLE_PRELOAD = config.disablePreload;
process.env.REACT_STATIC_DISABLE_RUNTIME = config.disableRuntime;
process.env.REACT_STATIC_PRELOAD_POLL_INTERVAL = config.preloadPollInterval;
process.env.REACT_STATIC_SILENT = config.silent;
process.env.REACT_STATIC_ROOT_PATH_READ_ONLY = paths.ROOT;
process.env.REACT_STATIC_TEMPLATES_PATH = _path["default"].join(paths.ARTIFACTS, 'react-static-templates.js');
process.env.REACT_STATIC_PLUGINS_PATH = _path["default"].join(paths.ARTIFACTS, 'react-static-browser-plugins.js');
var resolvePlugin = function resolvePlugin(originalLocation) {
var options = {};
if (Array.isArray(originalLocation)) {
options = originalLocation[1] || {};
originalLocation = originalLocation[0];
}
var location = [function () {
// Absolute require
try {
var found = require.resolve(originalLocation);
return found.includes('.') ? _path["default"].resolve(found, '../') : found;
} catch (err) {//
}
}, function () {
// Absolute
if (_fsExtra["default"].pathExistsSync(originalLocation)) {
return originalLocation;
}
}, function () {
// Plugins Dir
var found = _path["default"].resolve(paths.PLUGINS, originalLocation);
if (_fsExtra["default"].pathExistsSync(found)) {
return found;
}
}, function () {
// Plugins Dir require
try {
var found = (0, _resolveFrom["default"])(paths.PLUGINS, originalLocation);
return found.includes('.') ? _path["default"].resolve(found, '../') : found;
} catch (err) {//
}
}, function () {
// CWD
var found = _path["default"].resolve(process.cwd(), originalLocation);
if (_fsExtra["default"].pathExistsSync(found)) {
return found;
}
}, function () {
// CWD require
try {
var found = (0, _resolveFrom["default"])(process.cwd(), originalLocation);
return found.includes('.') ? _path["default"].resolve(found, '../') : found;
} catch (err) {//
}
}, function () {
if (process.env.NODE_ENV === 'test') {
// Allow plugins to be mocked
return require('path').resolve('./src/static/__mocks__/mock-plugin');
}
}].reduce(function (prev, curr) {
return prev || curr();
}, null); // TODO: We have to do this because we don't have a good mock for process.cwd() :(
if (!location) {
throw new Error("Could not find a plugin directory for the plugin: \"".concat(originalLocation, "\". We must bail!"));
}
var nodeLocation = _path["default"].join(location, 'node.api.js');
var browserLocation = _path["default"].join(location, 'browser.api.js'); // Detect if the node plugin entry exists, and provide the nodeResolver to it
nodeLocation = _fsExtra["default"].pathExistsSync(nodeLocation) ? nodeLocation : null; // Detect if the browser plugin entry exists, and provide the nodeResolver to it
browserLocation = _fsExtra["default"].pathExistsSync(browserLocation) ? browserLocation : null;
var buildPluginHooks = function buildPluginHooks() {
return {};
};
try {
// Get the hooks for the node api
if (nodeLocation) {
buildPluginHooks = require(nodeLocation)["default"];
} else if (originalLocation !== paths.ROOT && !browserLocation) {
throw new Error("Could not find a valid node.api.js or browser.api.js plugin file in \"".concat(location, "\". \n") + "The original location: \"".concat(originalLocation, "\". \n") + "The root location: \"".concat(paths.ROOT, "\"."));
}
var resolvedPlugin = {
location: location,
nodeLocation: nodeLocation,
browserLocation: browserLocation,
options: options,
hooks: buildPluginHooks(options) || {}
};
(0, _plugins.validatePlugin)(resolvedPlugin); // Recursively resolve plugins
if (resolvedPlugin.plugins) {
resolvedPlugin.plugins = resolvedPlugin.plugins.map(resolvePlugin);
}
return resolvedPlugin;
} catch (err) {
console.error("The following error occurred in the plugin: \"".concat(originalLocation, "\""));
throw err;
}
};
state = _objectSpread(_objectSpread({}, state), {}, {
plugins: config.plugins.map(resolvePlugin),
config: config
});
return _plugins["default"].afterGetConfig(state);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdGF0aWMvZ2V0Q29uZmlnLmpzIl0sIm5hbWVzIjpbImRlZmF1bHRDb25maWciLCJERUZBVUxUX05BTUVfRk9SX1NUQVRJQ19DT05GSUdfRklMRSIsIkRFRkFVTFRfUEFUSF9GT1JfU1RBVElDX0NPTkZJRyIsIm5vZGVQYXRoIiwicmVzb2x2ZSIsImpvaW4iLCJwcm9jZXNzIiwiY3dkIiwiREVGQVVMVF9ST1VURVMiLCJwYXRoIiwiREVGQVVMVF9FTlRSWSIsIkRFRkFVTFRfRVhURU5TSU9OUyIsImdldENvbmZpZyIsInN0YXRlIiwiY2FsbGJhY2siLCJjb25maWciLCJkZWJ1ZyIsImNvbnNvbGUiLCJsb2ciLCJjb25maWdQYXRoIiwicGFja2FnZUNvbmZpZyIsIm9yaWdpbmFsQ29uZmlnIiwicmVzb2x2ZWRQYXRoIiwibm9Db25maWciLCJidWlsZENvbmZpZyIsImVycm9yIiwiYnVpbGRDb25maWdGcm9tUGF0aCIsInN0YWdlIiwiY2hva2lkYXIiLCJ3YXRjaCIsImlnbm9yZUluaXRpYWwiLCJvbiIsInJlcXVpcmUiLCJjYWNoZSIsInBhdGhzIiwicm9vdCIsInNyYyIsImRpc3QiLCJ0ZW1wIiwiYnVpbGRBcnRpZmFjdHMiLCJkZXZEaXN0IiwicGx1Z2lucyIsInBhZ2VzIiwibm9kZU1vZHVsZXMiLCJhc3NldHMiLCJyZXNvbHZlUGF0aCIsInJlbGF0aXZlUGF0aCIsIkRJU1QiLCJlbnYiLCJSRUFDVF9TVEFUSUNfRU5WIiwiQVNTRVRTIiwiUk9PVCIsIlNSQyIsIlBMVUdJTlMiLCJURU1QIiwiQVJUSUZBQ1RTIiwiUFVCTElDIiwiTk9ERV9NT0RVTEVTIiwiRVhDTFVERV9NT0RVTEVTIiwiZXhjbHVkZVJlc29sdmVkTW9kdWxlcyIsIlBBQ0tBR0UiLCJIVE1MX1RFTVBMQVRFIiwiU1RBVElDX0RBVEEiLCJzaXRlUm9vdCIsImJhc2VQYXRoIiwiYXNzZXRzUGF0aCIsImRldkJhc2VQYXRoIiwiZGV2QXNzZXRzUGF0aCIsInN0YWdpbmciLCJzdGFnaW5nU2l0ZVJvb3QiLCJzdGFnaW5nQmFzZVBhdGgiLCJzdGFnaW5nQXNzZXRzUGF0aCIsInB1YmxpY1BhdGgiLCJsZWFkaW5nIiwiZW5kc1dpdGgiLCJnZXRTaXRlRGF0YSIsInByZWZldGNoUmF0ZSIsIm1heFRocmVhZHMiLCJJbmZpbml0eSIsImRpc2FibGVSb3V0ZVByZWZpeGluZyIsIm91dHB1dEZpbGVSYXRlIiwiZXh0ZW5zaW9ucyIsImdldFJvdXRlcyIsIm1pbkxvYWRUaW1lIiwiZGlzYWJsZVByZWxvYWQiLCJkaXNhYmxlUnVudGltZSIsInByZWxvYWRQb2xsSW50ZXJ2YWwiLCJwcm9kdWN0aW9uU291cmNlTWFwcyIsInNpbGVudCIsImVudHJ5IiwiZXh0cmFjdENzc0NodW5rcyIsImlubGluZUNzcyIsImJhYmVsRXhjbHVkZXMiLCJkZXZTZXJ2ZXIiLCJob3N0IiwicG9ydCIsInRlcnNlciIsInRlcnNlck9wdGlvbnMiLCJtYW5nbGUiLCJwYXJzZSIsImNvbXByZXNzIiwib3V0cHV0IiwiUkVBQ1RfU1RBVElDX01JTl9MT0FEX1RJTUUiLCJSRUFDVF9TVEFUSUNfUFJFRkVUQ0hfUkFURSIsIlJFQUNUX1NUQVRJQ19ESVNBQkxFX1JPVVRFX1BSRUZJWElORyIsIlJFQUNUX1NUQVRJQ19ESVNBQkxFX1BSRUxPQUQiLCJSRUFDVF9TVEFUSUNfRElTQUJMRV9SVU5USU1FIiwiUkVBQ1RfU1RBVElDX1BSRUxPQURfUE9MTF9JTlRFUlZBTCIsIlJFQUNUX1NUQVRJQ19TSUxFTlQiLCJSRUFDVF9TVEFUSUNfUk9PVF9QQVRIX1JFQURfT05MWSIsIlJFQUNUX1NUQVRJQ19URU1QTEFURVNfUEFUSCIsIlJFQUNUX1NUQVRJQ19QTFVHSU5TX1BBVEgiLCJyZXNvbHZlUGx1Z2luIiwib3JpZ2luYWxMb2NhdGlvbiIsIm9wdGlvbnMiLCJBcnJheSIsImlzQXJyYXkiLCJsb2NhdGlvbiIsImZvdW5kIiwiaW5jbHVkZXMiLCJlcnIiLCJmcyIsInBhdGhFeGlzdHNTeW5jIiwiTk9ERV9FTlYiLCJyZWR1Y2UiLCJwcmV2IiwiY3VyciIsIkVycm9yIiwibm9kZUxvY2F0aW9uIiwiYnJvd3NlckxvY2F0aW9uIiwiYnVpbGRQbHVnaW5Ib29rcyIsInJlc29sdmVkUGx1Z2luIiwiaG9va3MiLCJtYXAiLCJjb3JlUGx1Z2lucyIsImFmdGVyR2V0Q29uZmlnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOzs7Ozs7QUFFQTtBQUNBLElBQU1BLGFBQWEsR0FBRyxFQUF0QjtBQUNBLElBQU1DLG1DQUFtQyxHQUFHLGtCQUE1Qzs7QUFDQSxJQUFNQyw4QkFBOEIsR0FBR0MsaUJBQVNDLE9BQVQsQ0FDckNELGlCQUFTRSxJQUFULENBQWNDLE9BQU8sQ0FBQ0MsR0FBUixFQUFkLEVBQTZCTixtQ0FBN0IsQ0FEcUMsQ0FBdkM7O0FBR0EsSUFBTU8sY0FBYyxHQUFHLENBQUM7QUFBRUMsRUFBQUEsSUFBSSxFQUFFO0FBQVIsQ0FBRCxDQUF2QjtBQUNBLElBQU1DLGFBQWEsR0FBRyxVQUF0QjtBQUNBLElBQU1DLGtCQUFrQixHQUFHLENBQUMsS0FBRCxFQUFRLE1BQVIsQ0FBM0IsQyxDQUVBOztBQUNlLFNBQVNDLFNBQVQsQ0FDYkMsS0FEYSxFQVNiO0FBQUEsTUFQQUMsUUFPQTtBQUFBLDZGQVBXLGlCQUFNQyxNQUFOO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDVCxrQkFBSUYsS0FBSyxDQUFDRyxLQUFWLEVBQWlCO0FBQ2ZDLGdCQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxjQUFaO0FBQ0FELGdCQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUwsS0FBWjtBQUNEOztBQUpRLCtDQUtGRSxNQUxFOztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEtBT1g7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQSxNQUFNSSxVQUFVLEdBQ2ROLEtBQUssQ0FBQ00sVUFBTixJQUNBTixLQUFLLENBQUNPLGFBQU4sQ0FBb0JMLE1BRHBCLElBRUFiLDhCQUhGO0FBS0FXLEVBQUFBLEtBQUssbUNBQ0FBLEtBREE7QUFFSFEsSUFBQUEsY0FBYyxFQUFFRjtBQUZiLElBQUw7O0FBS0EsTUFBTUcsWUFBWSxHQUFHbkIsaUJBQVNDLE9BQVQsQ0FBaUJlLFVBQWpCLENBQXJCOztBQUVBLE1BQU1JLFFBQVEsR0FDWkosVUFBVSxLQUFLakIsOEJBQWYsSUFBaUQsQ0FBQ29CLFlBRHBEOztBQUdBLE1BQUlDLFFBQUosRUFBYztBQUNaO0FBQ0FWLElBQUFBLEtBQUssR0FBR1csV0FBVyxDQUFDWCxLQUFELEVBQVFiLGFBQVIsQ0FBbkI7QUFDQSxXQUFPYyxRQUFRLENBQUNELEtBQUQsQ0FBUixVQUFzQkksT0FBTyxDQUFDUSxLQUE5QixDQUFQO0FBQ0Q7O0FBRURaLEVBQUFBLEtBQUssR0FBR2EsbUJBQW1CLENBQUNiLEtBQUQsRUFBUVMsWUFBWSxJQUFJSCxVQUF4QixDQUEzQjs7QUFFQSxNQUFJTixLQUFLLENBQUNjLEtBQU4sS0FBZ0IsS0FBcEIsRUFBMkI7QUFDekJDLHlCQUNHQyxLQURILENBQ1NQLFlBRFQsRUFDdUI7QUFDbkJRLE1BQUFBLGFBQWEsRUFBRTtBQURJLEtBRHZCLEVBSUdDLEVBSkgsQ0FJTSxLQUpOLDZGQUlhO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDVGQsY0FBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxjQUFBQSxPQUFPLENBQUNDLEdBQVI7QUFDQUwsY0FBQUEsS0FBSyxHQUFHYSxtQkFBbUIsQ0FBQ2IsS0FBRCxFQUFRUyxZQUFSLENBQTNCO0FBQ0FSLGNBQUFBLFFBQVEsQ0FBQ0QsS0FBRCxDQUFSLFVBQXNCSSxPQUFPLENBQUNRLEtBQTlCOztBQUpTO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEtBSmI7QUFVRDs7QUFFRCxTQUFPWCxRQUFRLENBQUNELEtBQUQsQ0FBUixVQUFzQkksT0FBTyxDQUFDUSxLQUE5QixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0MsbUJBQVQsQ0FBNkJiLEtBQTdCLEVBQW9DTSxVQUFwQyxFQUFnRDtBQUM5QyxTQUFPYSxPQUFPLENBQUNDLEtBQVIsQ0FBY2QsVUFBZCxDQUFQOztBQUNBLE1BQU1KLE1BQU0sR0FBR2lCLE9BQU8sQ0FBQ2IsVUFBRCxDQUFQLFdBQWY7O0FBQ0EsU0FBT0ssV0FBVyxDQUFDWCxLQUFELEVBQVFFLE1BQVIsQ0FBbEI7QUFDRDs7QUFFTSxTQUFTUyxXQUFULENBQXFCWCxLQUFyQixFQUF5QztBQUFBLE1BQWJFLE1BQWEsdUVBQUosRUFBSTs7QUFDOUM7QUFDQSxNQUFJbUIsS0FBSztBQUNQQyxJQUFBQSxJQUFJLEVBQUVoQyxpQkFBU0MsT0FBVCxDQUFpQkUsT0FBTyxDQUFDQyxHQUFSLEVBQWpCLENBREM7QUFFUDZCLElBQUFBLEdBQUcsRUFBRSxLQUZFO0FBR1BDLElBQUFBLElBQUksRUFBRSxNQUhDO0FBSVBDLElBQUFBLElBQUksRUFBRSxLQUpDO0FBS1BDLElBQUFBLGNBQWMsRUFBRSxXQUxUO0FBTVBDLElBQUFBLE9BQU8sRUFBRSxnQkFORjtBQU9QLGNBQVEsUUFQRDtBQVFQQyxJQUFBQSxPQUFPLEVBQUUsU0FSRjtBQVNQQyxJQUFBQSxLQUFLLEVBQUUsV0FUQTtBQVVQQyxJQUFBQSxXQUFXLEVBQUUsY0FWTjtBQVdQQyxJQUFBQSxNQUFNLEVBQUU7QUFYRCxLQVlIN0IsTUFBTSxDQUFDbUIsS0FBUCxJQUFnQixFQVpiLENBQVQsQ0FGOEMsQ0FpQjlDOzs7QUFDQSxNQUFNVyxXQUFXLEdBQUcsU0FBZEEsV0FBYyxDQUFBQyxZQUFZO0FBQUEsV0FBSTNDLGlCQUFTQyxPQUFULENBQWlCOEIsS0FBSyxDQUFDQyxJQUF2QixFQUE2QlcsWUFBN0IsQ0FBSjtBQUFBLEdBQWhDLENBbEI4QyxDQW9COUM7OztBQUNBLE1BQU1DLElBQUksR0FDUnpDLE9BQU8sQ0FBQzBDLEdBQVIsQ0FBWUMsZ0JBQVosS0FBaUMsYUFBakMsR0FDSUosV0FBVyxDQUFDWCxLQUFLLENBQUNNLE9BQU4sSUFBaUJOLEtBQUssQ0FBQ0csSUFBeEIsQ0FEZixHQUVJUSxXQUFXLENBQUNYLEtBQUssQ0FBQ0csSUFBUCxDQUhqQjs7QUFJQSxNQUFNYSxNQUFNLEdBQUcvQyxpQkFBU0MsT0FBVCxDQUFpQjJDLElBQWpCLEVBQXVCYixLQUFLLENBQUNVLE1BQTdCLENBQWY7O0FBRUFWLEVBQUFBLEtBQUssR0FBRztBQUNOaUIsSUFBQUEsSUFBSSxFQUFFakIsS0FBSyxDQUFDQyxJQUROO0FBRU5pQixJQUFBQSxHQUFHLEVBQUVQLFdBQVcsQ0FBQ1gsS0FBSyxDQUFDRSxHQUFQLENBRlY7QUFHTlcsSUFBQUEsSUFBSSxFQUFKQSxJQUhNO0FBSU5HLElBQUFBLE1BQU0sRUFBTkEsTUFKTTtBQUtORyxJQUFBQSxPQUFPLEVBQUVSLFdBQVcsQ0FBQ1gsS0FBSyxDQUFDTyxPQUFQLENBTGQ7QUFNTmEsSUFBQUEsSUFBSSxFQUFFVCxXQUFXLENBQUNYLEtBQUssQ0FBQ0ksSUFBUCxDQU5YO0FBT05pQixJQUFBQSxTQUFTLEVBQUVWLFdBQVcsQ0FBQ1gsS0FBSyxDQUFDSyxjQUFQLENBUGhCO0FBUU5pQixJQUFBQSxNQUFNLEVBQUVYLFdBQVcsQ0FBQ1gsS0FBSyxVQUFOLENBUmI7QUFTTnVCLElBQUFBLFlBQVksRUFBRVosV0FBVyxDQUFDWCxLQUFLLENBQUNTLFdBQVAsQ0FUbkI7QUFVTmUsSUFBQUEsZUFBZSxFQUNieEIsS0FBSyxDQUFDeUIsc0JBQU4sSUFBZ0NkLFdBQVcsQ0FBQ1gsS0FBSyxDQUFDUyxXQUFQLENBWHZDO0FBWU5pQixJQUFBQSxPQUFPLEVBQUVmLFdBQVcsQ0FBQyxjQUFELENBWmQ7QUFhTmdCLElBQUFBLGFBQWEsRUFBRTFELGlCQUFTRSxJQUFULENBQWMwQyxJQUFkLEVBQW9CLFlBQXBCLENBYlQ7QUFjTmUsSUFBQUEsV0FBVyxFQUFFM0QsaUJBQVNFLElBQVQsQ0FBYzZDLE1BQWQsRUFBc0IsWUFBdEI7QUFkUCxHQUFSLENBM0I4QyxDQTRDOUM7O0FBQ0EsTUFBSWEsUUFBUSxHQUFHLEVBQWY7QUFDQSxNQUFJQyxRQUFRLEdBQUcsRUFBZjtBQUNBLE1BQUlDLFVBQVUsR0FBRyxFQUFqQjs7QUFDQSxNQUFJM0QsT0FBTyxDQUFDMEMsR0FBUixDQUFZQyxnQkFBWixLQUFpQyxhQUFyQyxFQUFvRDtBQUNsRGUsSUFBQUEsUUFBUSxHQUFHLHlCQUFhakQsTUFBTSxDQUFDbUQsV0FBcEIsQ0FBWDtBQUNBRCxJQUFBQSxVQUFVLEdBQUdsRCxNQUFNLENBQUNvRCxhQUFQLElBQXdCakMsS0FBSyxDQUFDVSxNQUE5QixJQUF3Q3FCLFVBQXJEO0FBQ0QsR0FIRCxNQUdPLElBQUlwRCxLQUFLLENBQUN1RCxPQUFWLEVBQW1CO0FBQ3hCTCxJQUFBQSxRQUFRLEdBQUcsMEJBQWNoRCxNQUFNLENBQUNzRCxlQUFQLElBQTBCLEdBQXhDLEVBQTZDLElBQTdDLENBQVg7QUFDQUwsSUFBQUEsUUFBUSxHQUFHLHlCQUFhakQsTUFBTSxDQUFDdUQsZUFBcEIsQ0FBWDtBQUNBTCxJQUFBQSxVQUFVLEdBQUdsRCxNQUFNLENBQUN3RCxpQkFBUCxJQUE0QnJDLEtBQUssQ0FBQ1UsTUFBbEMsSUFBNENxQixVQUF6RDtBQUNELEdBSk0sTUFJQTtBQUNMRixJQUFBQSxRQUFRLEdBQUcsMEJBQWNoRCxNQUFNLENBQUNnRCxRQUFQLElBQW1CLEdBQWpDLEVBQXNDLElBQXRDLENBQVg7QUFDQUMsSUFBQUEsUUFBUSxHQUFHLHlCQUFhakQsTUFBTSxDQUFDaUQsUUFBcEIsQ0FBWDtBQUNBQyxJQUFBQSxVQUFVLEdBQUdsRCxNQUFNLENBQUNrRCxVQUFQLElBQXFCL0IsS0FBSyxDQUFDVSxNQUEzQixJQUFxQ3FCLFVBQWxEO0FBQ0Q7O0FBQ0QsTUFBTU8sVUFBVSxhQUFNLG1DQUFnQlQsUUFBaEIsY0FBNEJDLFFBQTVCLEdBQXdDO0FBQzVEUyxJQUFBQSxPQUFPLEVBQUU7QUFEbUQsR0FBeEMsQ0FBTixNQUFoQjs7QUFJQSxNQUFJUixVQUFVLElBQUksQ0FBQywwQkFBY0EsVUFBZCxDQUFuQixFQUE4QztBQUM1Q0EsSUFBQUEsVUFBVSxjQUFPLG1DQUFnQkQsUUFBaEIsY0FBNEJDLFVBQTVCLEVBQVAsTUFBVjtBQUNELEdBbEU2QyxDQW9FOUM7OztBQUNBLE1BQUlBLFVBQVUsSUFBSSxDQUFDQSxVQUFVLENBQUNTLFFBQVgsQ0FBb0IsR0FBcEIsQ0FBbkIsRUFBNkM7QUFDM0NULElBQUFBLFVBQVUsYUFBTUEsVUFBTixNQUFWO0FBQ0QsR0F2RTZDLENBeUU5QztBQUNBOzs7QUFDQSxNQUFNeEIsT0FBTyxpREFBUTFCLE1BQU0sQ0FBQzBCLE9BQVAsSUFBa0IsRUFBMUIsSUFBK0JQLEtBQUssQ0FBQ2lCLElBQXJDLEVBQWIsQ0EzRThDLENBNkU5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUNBcEMsRUFBQUEsTUFBTTtBQUNKO0FBQ0E0RCxJQUFBQSxXQUFXLEVBQUU7QUFBQSxhQUFPLEVBQVA7QUFBQSxLQUZUO0FBR0pDLElBQUFBLFlBQVksRUFBRSxDQUhWO0FBSUpDLElBQUFBLFVBQVUsRUFBRUMsUUFKUjtBQUtKQyxJQUFBQSxxQkFBcUIsRUFBRSxLQUxuQjtBQU1KQyxJQUFBQSxjQUFjLEVBQUUsR0FOWjtBQU9KQyxJQUFBQSxVQUFVLEVBQUV0RSxrQkFQUjtBQVFKdUUsSUFBQUEsU0FBUztBQUFBLHFHQUFFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxrREFBWTFFLGNBQVo7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsT0FBRjs7QUFBQTtBQUFBO0FBQUE7O0FBQUE7QUFBQSxPQVJMO0FBU0oyRSxJQUFBQSxXQUFXLEVBQUUsR0FUVDtBQVVKQyxJQUFBQSxjQUFjLEVBQUUsS0FWWjtBQVdKQyxJQUFBQSxjQUFjLEVBQUUsS0FYWjtBQVlKQyxJQUFBQSxtQkFBbUIsRUFBRSxHQVpqQjtBQWFKQyxJQUFBQSxvQkFBb0IsRUFBRSxLQWJsQjtBQWNKQyxJQUFBQSxNQUFNLEVBQUUsS0FkSjtBQWVKQyxJQUFBQSxLQUFLLEVBQUUvRTtBQWZILEtBa0JESyxNQWxCQztBQW9CSjtBQUNBbUIsSUFBQUEsS0FBSyxFQUFMQSxLQXJCSTtBQXNCSk8sSUFBQUEsT0FBTyxFQUFQQSxPQXRCSTtBQXVCSnNCLElBQUFBLFFBQVEsRUFBUkEsUUF2Qkk7QUF3QkpDLElBQUFBLFFBQVEsRUFBUkEsUUF4Qkk7QUF5QkpRLElBQUFBLFVBQVUsRUFBVkEsVUF6Qkk7QUEwQkpQLElBQUFBLFVBQVUsRUFBVkEsVUExQkk7QUEyQkp5QixJQUFBQSxnQkFBZ0IsRUFBRTNFLE1BQU0sQ0FBQzJFLGdCQUFQLElBQTJCLEtBM0J6QztBQTRCSkMsSUFBQUEsU0FBUyxFQUFFNUUsTUFBTSxDQUFDNEUsU0FBUCxJQUFvQixLQTVCM0I7QUE2QkpDLElBQUFBLGFBQWEsRUFBRTdFLE1BQU0sQ0FBQzZFLGFBQVAsSUFBd0IsRUE3Qm5DO0FBOEJKQyxJQUFBQSxTQUFTO0FBQ1BDLE1BQUFBLElBQUksRUFBRSxXQURDO0FBRVBDLE1BQUFBLElBQUksRUFBRTtBQUZDLE9BR0hoRixNQUFNLENBQUM4RSxTQUFQLElBQW9CLEVBSGpCO0FBOUJMLElBQU47QUFxQ0E5RSxFQUFBQSxNQUFNLENBQUNpRixNQUFQLEdBQWdCakYsTUFBTSxDQUFDaUYsTUFBUCxJQUFpQixFQUFqQztBQUNBakYsRUFBQUEsTUFBTSxDQUFDaUYsTUFBUCxDQUFjQyxhQUFkLEdBQThCbEYsTUFBTSxDQUFDaUYsTUFBUCxDQUFjQyxhQUFkLElBQStCLEVBQTdEO0FBQ0FsRixFQUFBQSxNQUFNLENBQUNpRixNQUFQLENBQWNDLGFBQWQsQ0FBNEJDLE1BQTVCLEdBQXFDbkYsTUFBTSxDQUFDaUYsTUFBUCxDQUFjQyxhQUFkLENBQTRCQyxNQUE1QixJQUFzQyxFQUEzRTtBQUNBbkYsRUFBQUEsTUFBTSxDQUFDaUYsTUFBUCxDQUFjQyxhQUFkLENBQTRCRSxLQUE1QixHQUFvQ3BGLE1BQU0sQ0FBQ2lGLE1BQVAsQ0FBY0MsYUFBZCxDQUE0QkUsS0FBNUIsSUFBcUMsRUFBekU7QUFDQXBGLEVBQUFBLE1BQU0sQ0FBQ2lGLE1BQVAsQ0FBY0MsYUFBZCxDQUE0QkcsUUFBNUIsR0FDRXJGLE1BQU0sQ0FBQ2lGLE1BQVAsQ0FBY0MsYUFBZCxDQUE0QkcsUUFBNUIsSUFBd0MsRUFEMUM7QUFFQXJGLEVBQUFBLE1BQU0sQ0FBQ2lGLE1BQVAsQ0FBY0MsYUFBZCxDQUE0QkksTUFBNUIsR0FBcUN0RixNQUFNLENBQUNpRixNQUFQLENBQWNDLGFBQWQsQ0FBNEJJLE1BQTVCLElBQXNDLEVBQTNFLENBakk4QyxDQW1JOUM7O0FBQ0EvRixFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVlzRCwwQkFBWixHQUF5Q3ZGLE1BQU0sQ0FBQ29FLFdBQWhEO0FBQ0E3RSxFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVl1RCwwQkFBWixHQUF5Q3hGLE1BQU0sQ0FBQzZELFlBQWhEO0FBQ0F0RSxFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVl3RCxvQ0FBWixHQUNFekYsTUFBTSxDQUFDZ0UscUJBRFQ7QUFFQXpFLEVBQUFBLE9BQU8sQ0FBQzBDLEdBQVIsQ0FBWXlELDRCQUFaLEdBQTJDMUYsTUFBTSxDQUFDcUUsY0FBbEQ7QUFDQTlFLEVBQUFBLE9BQU8sQ0FBQzBDLEdBQVIsQ0FBWTBELDRCQUFaLEdBQTJDM0YsTUFBTSxDQUFDc0UsY0FBbEQ7QUFDQS9FLEVBQUFBLE9BQU8sQ0FBQzBDLEdBQVIsQ0FBWTJELGtDQUFaLEdBQWlENUYsTUFBTSxDQUFDdUUsbUJBQXhEO0FBQ0FoRixFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVk0RCxtQkFBWixHQUFrQzdGLE1BQU0sQ0FBQ3lFLE1BQXpDO0FBRUFsRixFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVk2RCxnQ0FBWixHQUErQzNFLEtBQUssQ0FBQ2lCLElBQXJEO0FBRUE3QyxFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVk4RCwyQkFBWixHQUEwQzNHLGlCQUFTRSxJQUFULENBQ3hDNkIsS0FBSyxDQUFDcUIsU0FEa0MsRUFFeEMsMkJBRndDLENBQTFDO0FBSUFqRCxFQUFBQSxPQUFPLENBQUMwQyxHQUFSLENBQVkrRCx5QkFBWixHQUF3QzVHLGlCQUFTRSxJQUFULENBQ3RDNkIsS0FBSyxDQUFDcUIsU0FEZ0MsRUFFdEMsaUNBRnNDLENBQXhDOztBQUtBLE1BQU15RCxhQUFhLEdBQUcsU0FBaEJBLGFBQWdCLENBQUFDLGdCQUFnQixFQUFJO0FBQ3hDLFFBQUlDLE9BQU8sR0FBRyxFQUFkOztBQUNBLFFBQUlDLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxnQkFBZCxDQUFKLEVBQXFDO0FBQ25DQyxNQUFBQSxPQUFPLEdBQUdELGdCQUFnQixDQUFDLENBQUQsQ0FBaEIsSUFBdUIsRUFBakM7QUFDQUEsTUFBQUEsZ0JBQWdCLEdBQUdBLGdCQUFnQixDQUFDLENBQUQsQ0FBbkM7QUFDRDs7QUFFRCxRQUFNSSxRQUFRLEdBQUcsQ0FDZixZQUFNO0FBQ0o7QUFDQSxVQUFJO0FBQ0YsWUFBTUMsS0FBSyxHQUFHdEYsT0FBTyxDQUFDNUIsT0FBUixDQUFnQjZHLGdCQUFoQixDQUFkOztBQUNBLGVBQU9LLEtBQUssQ0FBQ0MsUUFBTixDQUFlLEdBQWYsSUFBc0JwSCxpQkFBU0MsT0FBVCxDQUFpQmtILEtBQWpCLEVBQXdCLEtBQXhCLENBQXRCLEdBQXVEQSxLQUE5RDtBQUNELE9BSEQsQ0FHRSxPQUFPRSxHQUFQLEVBQVksQ0FDWjtBQUNEO0FBQ0YsS0FUYyxFQVVmLFlBQU07QUFDSjtBQUNBLFVBQUlDLG9CQUFHQyxjQUFILENBQWtCVCxnQkFBbEIsQ0FBSixFQUF5QztBQUN2QyxlQUFPQSxnQkFBUDtBQUNEO0FBQ0YsS0FmYyxFQWdCZixZQUFNO0FBQ0o7QUFDQSxVQUFNSyxLQUFLLEdBQUduSCxpQkFBU0MsT0FBVCxDQUFpQjhCLEtBQUssQ0FBQ21CLE9BQXZCLEVBQWdDNEQsZ0JBQWhDLENBQWQ7O0FBQ0EsVUFBSVEsb0JBQUdDLGNBQUgsQ0FBa0JKLEtBQWxCLENBQUosRUFBOEI7QUFDNUIsZUFBT0EsS0FBUDtBQUNEO0FBQ0YsS0F0QmMsRUF1QmYsWUFBTTtBQUNKO0FBQ0EsVUFBSTtBQUNGLFlBQU1BLEtBQUssR0FBRyw2QkFBWXBGLEtBQUssQ0FBQ21CLE9BQWxCLEVBQTJCNEQsZ0JBQTNCLENBQWQ7QUFDQSxlQUFPSyxLQUFLLENBQUNDLFFBQU4sQ0FBZSxHQUFmLElBQXNCcEgsaUJBQVNDLE9BQVQsQ0FBaUJrSCxLQUFqQixFQUF3QixLQUF4QixDQUF0QixHQUF1REEsS0FBOUQ7QUFDRCxPQUhELENBR0UsT0FBT0UsR0FBUCxFQUFZLENBQ1o7QUFDRDtBQUNGLEtBL0JjLEVBZ0NmLFlBQU07QUFDSjtBQUNBLFVBQU1GLEtBQUssR0FBR25ILGlCQUFTQyxPQUFULENBQWlCRSxPQUFPLENBQUNDLEdBQVIsRUFBakIsRUFBZ0MwRyxnQkFBaEMsQ0FBZDs7QUFDQSxVQUFJUSxvQkFBR0MsY0FBSCxDQUFrQkosS0FBbEIsQ0FBSixFQUE4QjtBQUM1QixlQUFPQSxLQUFQO0FBQ0Q7QUFDRixLQXRDYyxFQXVDZixZQUFNO0FBQ0o7QUFDQSxVQUFJO0FBQ0YsWUFBTUEsS0FBSyxHQUFHLDZCQUFZaEgsT0FBTyxDQUFDQyxHQUFSLEVBQVosRUFBMkIwRyxnQkFBM0IsQ0FBZDtBQUNBLGVBQU9LLEtBQUssQ0FBQ0MsUUFBTixDQUFlLEdBQWYsSUFBc0JwSCxpQkFBU0MsT0FBVCxDQUFpQmtILEtBQWpCLEVBQXdCLEtBQXhCLENBQXRCLEdBQXVEQSxLQUE5RDtBQUNELE9BSEQsQ0FHRSxPQUFPRSxHQUFQLEVBQVksQ0FDWjtBQUNEO0FBQ0YsS0EvQ2MsRUFnRGYsWUFBTTtBQUNKLFVBQUlsSCxPQUFPLENBQUMwQyxHQUFSLENBQVkyRSxRQUFaLEtBQXlCLE1BQTdCLEVBQXFDO0FBQ25DO0FBQ0EsZUFBTzNGLE9BQU8sQ0FBQyxNQUFELENBQVAsQ0FBZ0I1QixPQUFoQixDQUF3QixvQ0FBeEIsQ0FBUDtBQUNEO0FBQ0YsS0FyRGMsRUFzRGZ3SCxNQXREZSxDQXNEUixVQUFDQyxJQUFELEVBQU9DLElBQVA7QUFBQSxhQUFnQkQsSUFBSSxJQUFJQyxJQUFJLEVBQTVCO0FBQUEsS0F0RFEsRUFzRHdCLElBdER4QixDQUFqQixDQVB3QyxDQStEeEM7O0FBQ0EsUUFBSSxDQUFDVCxRQUFMLEVBQWU7QUFDYixZQUFNLElBQUlVLEtBQUosK0RBQ2tEZCxnQkFEbEQsdUJBQU47QUFHRDs7QUFFRCxRQUFJZSxZQUFZLEdBQUc3SCxpQkFBU0UsSUFBVCxDQUFjZ0gsUUFBZCxFQUF3QixhQUF4QixDQUFuQjs7QUFDQSxRQUFJWSxlQUFlLEdBQUc5SCxpQkFBU0UsSUFBVCxDQUFjZ0gsUUFBZCxFQUF3QixnQkFBeEIsQ0FBdEIsQ0F2RXdDLENBeUV4Qzs7O0FBQ0FXLElBQUFBLFlBQVksR0FBR1Asb0JBQUdDLGNBQUgsQ0FBa0JNLFlBQWxCLElBQWtDQSxZQUFsQyxHQUFpRCxJQUFoRSxDQTFFd0MsQ0E0RXhDOztBQUNBQyxJQUFBQSxlQUFlLEdBQUdSLG9CQUFHQyxjQUFILENBQWtCTyxlQUFsQixJQUNkQSxlQURjLEdBRWQsSUFGSjs7QUFJQSxRQUFJQyxnQkFBZ0IsR0FBRztBQUFBLGFBQU8sRUFBUDtBQUFBLEtBQXZCOztBQUVBLFFBQUk7QUFDRjtBQUNBLFVBQUlGLFlBQUosRUFBa0I7QUFDaEJFLFFBQUFBLGdCQUFnQixHQUFHbEcsT0FBTyxDQUFDZ0csWUFBRCxDQUFQLFdBQW5CO0FBQ0QsT0FGRCxNQUVPLElBQUlmLGdCQUFnQixLQUFLL0UsS0FBSyxDQUFDaUIsSUFBM0IsSUFBbUMsQ0FBQzhFLGVBQXhDLEVBQXlEO0FBQzlELGNBQU0sSUFBSUYsS0FBSixDQUNKLGdGQUF3RVYsUUFBeEUsaURBQzZCSixnQkFEN0IsNkNBRXlCL0UsS0FBSyxDQUFDaUIsSUFGL0IsUUFESSxDQUFOO0FBS0Q7O0FBRUQsVUFBTWdGLGNBQWMsR0FBRztBQUNyQmQsUUFBQUEsUUFBUSxFQUFSQSxRQURxQjtBQUVyQlcsUUFBQUEsWUFBWSxFQUFaQSxZQUZxQjtBQUdyQkMsUUFBQUEsZUFBZSxFQUFmQSxlQUhxQjtBQUlyQmYsUUFBQUEsT0FBTyxFQUFQQSxPQUpxQjtBQUtyQmtCLFFBQUFBLEtBQUssRUFBRUYsZ0JBQWdCLENBQUNoQixPQUFELENBQWhCLElBQTZCO0FBTGYsT0FBdkI7QUFRQSxtQ0FBZWlCLGNBQWYsRUFwQkUsQ0FzQkY7O0FBQ0EsVUFBSUEsY0FBYyxDQUFDMUYsT0FBbkIsRUFBNEI7QUFDMUIwRixRQUFBQSxjQUFjLENBQUMxRixPQUFmLEdBQXlCMEYsY0FBYyxDQUFDMUYsT0FBZixDQUF1QjRGLEdBQXZCLENBQTJCckIsYUFBM0IsQ0FBekI7QUFDRDs7QUFFRCxhQUFPbUIsY0FBUDtBQUNELEtBNUJELENBNEJFLE9BQU9YLEdBQVAsRUFBWTtBQUNadkcsTUFBQUEsT0FBTyxDQUFDUSxLQUFSLHlEQUNrRHdGLGdCQURsRDtBQUdBLFlBQU1PLEdBQU47QUFDRDtBQUNGLEdBckhEOztBQXVIQTNHLEVBQUFBLEtBQUssbUNBQ0FBLEtBREE7QUFFSDRCLElBQUFBLE9BQU8sRUFBRTFCLE1BQU0sQ0FBQzBCLE9BQVAsQ0FBZTRGLEdBQWYsQ0FBbUJyQixhQUFuQixDQUZOO0FBR0hqRyxJQUFBQSxNQUFNLEVBQU5BO0FBSEcsSUFBTDtBQU1BLFNBQU91SCxvQkFBWUMsY0FBWixDQUEyQjFILEtBQTNCLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1keW5hbWljLXJlcXVpcmUgKi9cblxuaW1wb3J0IG5vZGVQYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInXG5pbXBvcnQgcmVzb2x2ZUZyb20gZnJvbSAncmVzb2x2ZS1mcm9tJ1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuLy9cbmltcG9ydCB7IGNsZWFuU2xhc2hlcywgY3V0UGF0aFRvUm9vdCwgaXNBYnNvbHV0ZVVybCB9IGZyb20gJy4uL3V0aWxzJ1xuaW1wb3J0IGNvcmVQbHVnaW5zLCB7IHZhbGlkYXRlUGx1Z2luIH0gZnJvbSAnLi9wbHVnaW5zJ1xuXG4vLyB0aGUgZGVmYXVsdCBzdGF0aWMuY29uZmlnLmpzIGxvY2F0aW9uXG5jb25zdCBkZWZhdWx0Q29uZmlnID0ge31cbmNvbnN0IERFRkFVTFRfTkFNRV9GT1JfU1RBVElDX0NPTkZJR19GSUxFID0gJ3N0YXRpYy5jb25maWcuanMnXG5jb25zdCBERUZBVUxUX1BBVEhfRk9SX1NUQVRJQ19DT05GSUcgPSBub2RlUGF0aC5yZXNvbHZlKFxuICBub2RlUGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIERFRkFVTFRfTkFNRV9GT1JfU1RBVElDX0NPTkZJR19GSUxFKVxuKVxuY29uc3QgREVGQVVMVF9ST1VURVMgPSBbeyBwYXRoOiAnLycgfV1cbmNvbnN0IERFRkFVTFRfRU5UUlkgPSAnaW5kZXguanMnXG5jb25zdCBERUZBVUxUX0VYVEVOU0lPTlMgPSBbJy5qcycsICcuanN4J11cblxuLy8gUmV0cmlldmVzIHRoZSBzdGF0aWMuY29uZmlnLmpzIGZyb20gdGhlIGN1cnJlbnQgcHJvamVjdCBkaXJlY3RvcnlcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbmZpZyhcbiAgc3RhdGUsXG4gIGNhbGxiYWNrID0gYXN5bmMgY29uZmlnID0+IHtcbiAgICBpZiAoc3RhdGUuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdnZXRDb25maWcoKTonKVxuICAgICAgY29uc29sZS5sb2coc3RhdGUpXG4gICAgfVxuICAgIHJldHVybiBjb25maWdcbiAgfVxuKSB7XG4gIGNvbnN0IGNvbmZpZ1BhdGggPVxuICAgIHN0YXRlLmNvbmZpZ1BhdGggfHxcbiAgICBzdGF0ZS5wYWNrYWdlQ29uZmlnLmNvbmZpZyB8fFxuICAgIERFRkFVTFRfUEFUSF9GT1JfU1RBVElDX0NPTkZJR1xuXG4gIHN0YXRlID0ge1xuICAgIC4uLnN0YXRlLFxuICAgIG9yaWdpbmFsQ29uZmlnOiBjb25maWdQYXRoLFxuICB9XG5cbiAgY29uc3QgcmVzb2x2ZWRQYXRoID0gbm9kZVBhdGgucmVzb2x2ZShjb25maWdQYXRoKVxuXG4gIGNvbnN0IG5vQ29uZmlnID1cbiAgICBjb25maWdQYXRoID09PSBERUZBVUxUX1BBVEhfRk9SX1NUQVRJQ19DT05GSUcgJiYgIXJlc29sdmVkUGF0aFxuXG4gIGlmIChub0NvbmZpZykge1xuICAgIC8vIGxhc3RcbiAgICBzdGF0ZSA9IGJ1aWxkQ29uZmlnKHN0YXRlLCBkZWZhdWx0Q29uZmlnKVxuICAgIHJldHVybiBjYWxsYmFjayhzdGF0ZSkuY2F0Y2goY29uc29sZS5lcnJvcilcbiAgfVxuXG4gIHN0YXRlID0gYnVpbGRDb25maWdGcm9tUGF0aChzdGF0ZSwgcmVzb2x2ZWRQYXRoIHx8IGNvbmZpZ1BhdGgpXG5cbiAgaWYgKHN0YXRlLnN0YWdlID09PSAnZGV2Jykge1xuICAgIGNob2tpZGFyXG4gICAgICAud2F0Y2gocmVzb2x2ZWRQYXRoLCB7XG4gICAgICAgIGlnbm9yZUluaXRpYWw6IHRydWUsXG4gICAgICB9KVxuICAgICAgLm9uKCdhbGwnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgICAgICBjb25zb2xlLmxvZyhgVXBkYXRpbmcgc3RhdGljLmNvbmZpZy5qc2ApXG4gICAgICAgIHN0YXRlID0gYnVpbGRDb25maWdGcm9tUGF0aChzdGF0ZSwgcmVzb2x2ZWRQYXRoKVxuICAgICAgICBjYWxsYmFjayhzdGF0ZSkuY2F0Y2goY29uc29sZS5lcnJvcilcbiAgICAgIH0pXG4gIH1cblxuICByZXR1cm4gY2FsbGJhY2soc3RhdGUpLmNhdGNoKGNvbnNvbGUuZXJyb3IpXG59XG5cbmZ1bmN0aW9uIGJ1aWxkQ29uZmlnRnJvbVBhdGgoc3RhdGUsIGNvbmZpZ1BhdGgpIHtcbiAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbY29uZmlnUGF0aF1cbiAgY29uc3QgY29uZmlnID0gcmVxdWlyZShjb25maWdQYXRoKS5kZWZhdWx0XG4gIHJldHVybiBidWlsZENvbmZpZyhzdGF0ZSwgY29uZmlnKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb25maWcoc3RhdGUsIGNvbmZpZyA9IHt9KSB7XG4gIC8vIERlZmF1bHQgUGF0aHNcbiAgbGV0IHBhdGhzID0ge1xuICAgIHJvb3Q6IG5vZGVQYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSksXG4gICAgc3JjOiAnc3JjJyxcbiAgICBkaXN0OiAnZGlzdCcsXG4gICAgdGVtcDogJ3RtcCcsXG4gICAgYnVpbGRBcnRpZmFjdHM6ICdhcnRpZmFjdHMnLFxuICAgIGRldkRpc3Q6ICd0bXAvZGV2LXNlcnZlcicsXG4gICAgcHVibGljOiAncHVibGljJyxcbiAgICBwbHVnaW5zOiAncGx1Z2lucycsXG4gICAgcGFnZXM6ICdzcmMvcGFnZXMnLFxuICAgIG5vZGVNb2R1bGVzOiAnbm9kZV9tb2R1bGVzJyxcbiAgICBhc3NldHM6ICcnLFxuICAgIC4uLihjb25maWcucGF0aHMgfHwge30pLFxuICB9XG5cbiAgLy8gVXNlIHRoZSByb290IHRvIHJlc29sdmUgYWxsIG90aGVyIHJlbGF0aXZlIHBhdGhzXG4gIGNvbnN0IHJlc29sdmVQYXRoID0gcmVsYXRpdmVQYXRoID0+IG5vZGVQYXRoLnJlc29sdmUocGF0aHMucm9vdCwgcmVsYXRpdmVQYXRoKVxuXG4gIC8vIFJlc29sdmUgYW5kIHJlcGxhY2UgYWxsIHBhdGhzc1xuICBjb25zdCBESVNUID1cbiAgICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfRU5WID09PSAnZGV2ZWxvcG1lbnQnXG4gICAgICA/IHJlc29sdmVQYXRoKHBhdGhzLmRldkRpc3QgfHwgcGF0aHMuZGlzdClcbiAgICAgIDogcmVzb2x2ZVBhdGgocGF0aHMuZGlzdClcbiAgY29uc3QgQVNTRVRTID0gbm9kZVBhdGgucmVzb2x2ZShESVNULCBwYXRocy5hc3NldHMpXG5cbiAgcGF0aHMgPSB7XG4gICAgUk9PVDogcGF0aHMucm9vdCxcbiAgICBTUkM6IHJlc29sdmVQYXRoKHBhdGhzLnNyYyksXG4gICAgRElTVCxcbiAgICBBU1NFVFMsXG4gICAgUExVR0lOUzogcmVzb2x2ZVBhdGgocGF0aHMucGx1Z2lucyksXG4gICAgVEVNUDogcmVzb2x2ZVBhdGgocGF0aHMudGVtcCksXG4gICAgQVJUSUZBQ1RTOiByZXNvbHZlUGF0aChwYXRocy5idWlsZEFydGlmYWN0cyksXG4gICAgUFVCTElDOiByZXNvbHZlUGF0aChwYXRocy5wdWJsaWMpLFxuICAgIE5PREVfTU9EVUxFUzogcmVzb2x2ZVBhdGgocGF0aHMubm9kZU1vZHVsZXMpLFxuICAgIEVYQ0xVREVfTU9EVUxFUzpcbiAgICAgIHBhdGhzLmV4Y2x1ZGVSZXNvbHZlZE1vZHVsZXMgfHwgcmVzb2x2ZVBhdGgocGF0aHMubm9kZU1vZHVsZXMpLFxuICAgIFBBQ0tBR0U6IHJlc29sdmVQYXRoKCdwYWNrYWdlLmpzb24nKSxcbiAgICBIVE1MX1RFTVBMQVRFOiBub2RlUGF0aC5qb2luKERJU1QsICdpbmRleC5odG1sJyksXG4gICAgU1RBVElDX0RBVEE6IG5vZGVQYXRoLmpvaW4oQVNTRVRTLCAnc3RhdGljRGF0YScpLFxuICB9XG5cbiAgLy8gc2l0ZVJvb3QsIGJhc2VQYXRoLCBwdWJsaWNQYXRoLCBhbmQgYXNzZXRQYXRoIHJlc29sdXRpb25cbiAgbGV0IHNpdGVSb290ID0gJydcbiAgbGV0IGJhc2VQYXRoID0gJydcbiAgbGV0IGFzc2V0c1BhdGggPSAnJ1xuICBpZiAocHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0VOViA9PT0gJ2RldmVsb3BtZW50Jykge1xuICAgIGJhc2VQYXRoID0gY2xlYW5TbGFzaGVzKGNvbmZpZy5kZXZCYXNlUGF0aClcbiAgICBhc3NldHNQYXRoID0gY29uZmlnLmRldkFzc2V0c1BhdGggfHwgcGF0aHMuYXNzZXRzIHx8IGFzc2V0c1BhdGhcbiAgfSBlbHNlIGlmIChzdGF0ZS5zdGFnaW5nKSB7XG4gICAgc2l0ZVJvb3QgPSBjdXRQYXRoVG9Sb290KGNvbmZpZy5zdGFnaW5nU2l0ZVJvb3QgfHwgJy8nLCAnJDEnKVxuICAgIGJhc2VQYXRoID0gY2xlYW5TbGFzaGVzKGNvbmZpZy5zdGFnaW5nQmFzZVBhdGgpXG4gICAgYXNzZXRzUGF0aCA9IGNvbmZpZy5zdGFnaW5nQXNzZXRzUGF0aCB8fCBwYXRocy5hc3NldHMgfHwgYXNzZXRzUGF0aFxuICB9IGVsc2Uge1xuICAgIHNpdGVSb290ID0gY3V0UGF0aFRvUm9vdChjb25maWcuc2l0ZVJvb3QgfHwgJy8nLCAnJDEnKVxuICAgIGJhc2VQYXRoID0gY2xlYW5TbGFzaGVzKGNvbmZpZy5iYXNlUGF0aClcbiAgICBhc3NldHNQYXRoID0gY29uZmlnLmFzc2V0c1BhdGggfHwgcGF0aHMuYXNzZXRzIHx8IGFzc2V0c1BhdGhcbiAgfVxuICBjb25zdCBwdWJsaWNQYXRoID0gYCR7Y2xlYW5TbGFzaGVzKGAke3NpdGVSb290fS8ke2Jhc2VQYXRofWAsIHtcbiAgICBsZWFkaW5nOiBmYWxzZSxcbiAgfSl9L2BcblxuICBpZiAoYXNzZXRzUGF0aCAmJiAhaXNBYnNvbHV0ZVVybChhc3NldHNQYXRoKSkge1xuICAgIGFzc2V0c1BhdGggPSBgLyR7Y2xlYW5TbGFzaGVzKGAke2Jhc2VQYXRofS8ke2Fzc2V0c1BhdGh9YCl9L2BcbiAgfVxuXG4gIC8vIGFkZCB0cmFpbGluZyBzbGFzaCBvbmx5IGlmIGFzc2V0c1BhdGggd2FzIHN1cHBsaWVkLCBidXQgbm8gdHJhaWxpbmcgc2xhc2hcbiAgaWYgKGFzc2V0c1BhdGggJiYgIWFzc2V0c1BhdGguZW5kc1dpdGgoJy8nKSkge1xuICAgIGFzc2V0c1BhdGggPSBgJHthc3NldHNQYXRofS9gXG4gIH1cblxuICAvLyBBZGQgdGhlIHByb2plY3Qgcm9vdCBhcyBhIHBsdWdpbi4gVGhpcyBhbGxvd3MgdGhlIGRldlxuICAvLyB0byB1c2UgdGhlIHBsdWdpbiBhcGkgZGlyZWN0b3J5IGluIHRoZWlyIHByb2plY3QgaWYgdGhleSB3YW50XG4gIGNvbnN0IHBsdWdpbnMgPSBbLi4uKGNvbmZpZy5wbHVnaW5zIHx8IFtdKSwgcGF0aHMuUk9PVF1cblxuICAvLyBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0JyAmJiAhZW50cnkpIHtcbiAgLy8gICB0aHJvdyBuZXcgRXJyb3IoXG4gIC8vICAgICBgQ291bGQgbm90IHJlc29sdmUgZW50cnkgZmlsZSBmcm9tIGxvY2F0aW9uOiAke2VudHJ5fSB1c2luZyBleHRlbnNpb25zOiAkeyhcbiAgLy8gICAgICAgY29uZmlnLmV4dGVuc2lvbnMgfHwgREVGQVVMVF9FWFRFTlNJT05TXG4gIC8vICAgICApLmpvaW4oJywgJyl9YFxuICAvLyAgIClcbiAgLy8gfVxuXG4gIC8vIERlZmF1bHRzXG4gIGNvbmZpZyA9IHtcbiAgICAvLyBEZWZhdWx0c1xuICAgIGdldFNpdGVEYXRhOiAoKSA9PiAoe30pLFxuICAgIHByZWZldGNoUmF0ZTogNSxcbiAgICBtYXhUaHJlYWRzOiBJbmZpbml0eSxcbiAgICBkaXNhYmxlUm91dGVQcmVmaXhpbmc6IGZhbHNlLFxuICAgIG91dHB1dEZpbGVSYXRlOiAxMDAsXG4gICAgZXh0ZW5zaW9uczogREVGQVVMVF9FWFRFTlNJT05TLFxuICAgIGdldFJvdXRlczogYXN5bmMgKCkgPT4gREVGQVVMVF9ST1VURVMsXG4gICAgbWluTG9hZFRpbWU6IDIwMCxcbiAgICBkaXNhYmxlUHJlbG9hZDogZmFsc2UsXG4gICAgZGlzYWJsZVJ1bnRpbWU6IGZhbHNlLFxuICAgIHByZWxvYWRQb2xsSW50ZXJ2YWw6IDMwMCxcbiAgICBwcm9kdWN0aW9uU291cmNlTWFwczogZmFsc2UsXG4gICAgc2lsZW50OiBmYWxzZSxcbiAgICBlbnRyeTogREVGQVVMVF9FTlRSWSxcblxuICAgIC8vIENvbmZpZyBPdmVycmlkZXNcbiAgICAuLi5jb25maWcsXG5cbiAgICAvLyBNYXRlcmlhbGl6ZWQgT3ZlcnJpZGVzXG4gICAgcGF0aHMsXG4gICAgcGx1Z2lucyxcbiAgICBzaXRlUm9vdCxcbiAgICBiYXNlUGF0aCxcbiAgICBwdWJsaWNQYXRoLFxuICAgIGFzc2V0c1BhdGgsXG4gICAgZXh0cmFjdENzc0NodW5rczogY29uZmlnLmV4dHJhY3RDc3NDaHVua3MgfHwgZmFsc2UsXG4gICAgaW5saW5lQ3NzOiBjb25maWcuaW5saW5lQ3NzIHx8IGZhbHNlLFxuICAgIGJhYmVsRXhjbHVkZXM6IGNvbmZpZy5iYWJlbEV4Y2x1ZGVzIHx8IFtdLFxuICAgIGRldlNlcnZlcjoge1xuICAgICAgaG9zdDogJ2xvY2FsaG9zdCcsXG4gICAgICBwb3J0OiAzMDAwLFxuICAgICAgLi4uKGNvbmZpZy5kZXZTZXJ2ZXIgfHwge30pLFxuICAgIH0sXG4gIH1cblxuICBjb25maWcudGVyc2VyID0gY29uZmlnLnRlcnNlciB8fCB7fVxuICBjb25maWcudGVyc2VyLnRlcnNlck9wdGlvbnMgPSBjb25maWcudGVyc2VyLnRlcnNlck9wdGlvbnMgfHwge31cbiAgY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLm1hbmdsZSA9IGNvbmZpZy50ZXJzZXIudGVyc2VyT3B0aW9ucy5tYW5nbGUgfHwge31cbiAgY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLnBhcnNlID0gY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLnBhcnNlIHx8IHt9XG4gIGNvbmZpZy50ZXJzZXIudGVyc2VyT3B0aW9ucy5jb21wcmVzcyA9XG4gICAgY29uZmlnLnRlcnNlci50ZXJzZXJPcHRpb25zLmNvbXByZXNzIHx8IHt9XG4gIGNvbmZpZy50ZXJzZXIudGVyc2VyT3B0aW9ucy5vdXRwdXQgPSBjb25maWcudGVyc2VyLnRlcnNlck9wdGlvbnMub3V0cHV0IHx8IHt9XG5cbiAgLy8gU2V0IGVudiB2YXJpYWJsZXMgdG8gYmUgdXNlZCBjbGllbnQgc2lkZVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfTUlOX0xPQURfVElNRSA9IGNvbmZpZy5taW5Mb2FkVGltZVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUFJFRkVUQ0hfUkFURSA9IGNvbmZpZy5wcmVmZXRjaFJhdGVcbiAgcHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0RJU0FCTEVfUk9VVEVfUFJFRklYSU5HID1cbiAgICBjb25maWcuZGlzYWJsZVJvdXRlUHJlZml4aW5nXG4gIHByb2Nlc3MuZW52LlJFQUNUX1NUQVRJQ19ESVNBQkxFX1BSRUxPQUQgPSBjb25maWcuZGlzYWJsZVByZWxvYWRcbiAgcHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0RJU0FCTEVfUlVOVElNRSA9IGNvbmZpZy5kaXNhYmxlUnVudGltZVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUFJFTE9BRF9QT0xMX0lOVEVSVkFMID0gY29uZmlnLnByZWxvYWRQb2xsSW50ZXJ2YWxcbiAgcHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX1NJTEVOVCA9IGNvbmZpZy5zaWxlbnRcblxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUk9PVF9QQVRIX1JFQURfT05MWSA9IHBhdGhzLlJPT1RcblxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfVEVNUExBVEVTX1BBVEggPSBub2RlUGF0aC5qb2luKFxuICAgIHBhdGhzLkFSVElGQUNUUyxcbiAgICAncmVhY3Qtc3RhdGljLXRlbXBsYXRlcy5qcydcbiAgKVxuICBwcm9jZXNzLmVudi5SRUFDVF9TVEFUSUNfUExVR0lOU19QQVRIID0gbm9kZVBhdGguam9pbihcbiAgICBwYXRocy5BUlRJRkFDVFMsXG4gICAgJ3JlYWN0LXN0YXRpYy1icm93c2VyLXBsdWdpbnMuanMnXG4gIClcblxuICBjb25zdCByZXNvbHZlUGx1Z2luID0gb3JpZ2luYWxMb2NhdGlvbiA9PiB7XG4gICAgbGV0IG9wdGlvbnMgPSB7fVxuICAgIGlmIChBcnJheS5pc0FycmF5KG9yaWdpbmFsTG9jYXRpb24pKSB7XG4gICAgICBvcHRpb25zID0gb3JpZ2luYWxMb2NhdGlvblsxXSB8fCB7fVxuICAgICAgb3JpZ2luYWxMb2NhdGlvbiA9IG9yaWdpbmFsTG9jYXRpb25bMF1cbiAgICB9XG5cbiAgICBjb25zdCBsb2NhdGlvbiA9IFtcbiAgICAgICgpID0+IHtcbiAgICAgICAgLy8gQWJzb2x1dGUgcmVxdWlyZVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGZvdW5kID0gcmVxdWlyZS5yZXNvbHZlKG9yaWdpbmFsTG9jYXRpb24pXG4gICAgICAgICAgcmV0dXJuIGZvdW5kLmluY2x1ZGVzKCcuJykgPyBub2RlUGF0aC5yZXNvbHZlKGZvdW5kLCAnLi4vJykgOiBmb3VuZFxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAvL1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBBYnNvbHV0ZVxuICAgICAgICBpZiAoZnMucGF0aEV4aXN0c1N5bmMob3JpZ2luYWxMb2NhdGlvbikpIHtcbiAgICAgICAgICByZXR1cm4gb3JpZ2luYWxMb2NhdGlvblxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBQbHVnaW5zIERpclxuICAgICAgICBjb25zdCBmb3VuZCA9IG5vZGVQYXRoLnJlc29sdmUocGF0aHMuUExVR0lOUywgb3JpZ2luYWxMb2NhdGlvbilcbiAgICAgICAgaWYgKGZzLnBhdGhFeGlzdHNTeW5jKGZvdW5kKSkge1xuICAgICAgICAgIHJldHVybiBmb3VuZFxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBQbHVnaW5zIERpciByZXF1aXJlXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZm91bmQgPSByZXNvbHZlRnJvbShwYXRocy5QTFVHSU5TLCBvcmlnaW5hbExvY2F0aW9uKVxuICAgICAgICAgIHJldHVybiBmb3VuZC5pbmNsdWRlcygnLicpID8gbm9kZVBhdGgucmVzb2x2ZShmb3VuZCwgJy4uLycpIDogZm91bmRcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy9cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgLy8gQ1dEXG4gICAgICAgIGNvbnN0IGZvdW5kID0gbm9kZVBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBvcmlnaW5hbExvY2F0aW9uKVxuICAgICAgICBpZiAoZnMucGF0aEV4aXN0c1N5bmMoZm91bmQpKSB7XG4gICAgICAgICAgcmV0dXJuIGZvdW5kXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIC8vIENXRCByZXF1aXJlXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZm91bmQgPSByZXNvbHZlRnJvbShwcm9jZXNzLmN3ZCgpLCBvcmlnaW5hbExvY2F0aW9uKVxuICAgICAgICAgIHJldHVybiBmb3VuZC5pbmNsdWRlcygnLicpID8gbm9kZVBhdGgucmVzb2x2ZShmb3VuZCwgJy4uLycpIDogZm91bmRcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy9cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAndGVzdCcpIHtcbiAgICAgICAgICAvLyBBbGxvdyBwbHVnaW5zIHRvIGJlIG1vY2tlZFxuICAgICAgICAgIHJldHVybiByZXF1aXJlKCdwYXRoJykucmVzb2x2ZSgnLi9zcmMvc3RhdGljL19fbW9ja3NfXy9tb2NrLXBsdWdpbicpXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgXS5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHByZXYgfHwgY3VycigpLCBudWxsKVxuXG4gICAgLy8gVE9ETzogV2UgaGF2ZSB0byBkbyB0aGlzIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBhIGdvb2QgbW9jayBmb3IgcHJvY2Vzcy5jd2QoKSA6KFxuICAgIGlmICghbG9jYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBmaW5kIGEgcGx1Z2luIGRpcmVjdG9yeSBmb3IgdGhlIHBsdWdpbjogXCIke29yaWdpbmFsTG9jYXRpb259XCIuIFdlIG11c3QgYmFpbCFgXG4gICAgICApXG4gICAgfVxuXG4gICAgbGV0IG5vZGVMb2NhdGlvbiA9IG5vZGVQYXRoLmpvaW4obG9jYXRpb24sICdub2RlLmFwaS5qcycpXG4gICAgbGV0IGJyb3dzZXJMb2NhdGlvbiA9IG5vZGVQYXRoLmpvaW4obG9jYXRpb24sICdicm93c2VyLmFwaS5qcycpXG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIG5vZGUgcGx1Z2luIGVudHJ5IGV4aXN0cywgYW5kIHByb3ZpZGUgdGhlIG5vZGVSZXNvbHZlciB0byBpdFxuICAgIG5vZGVMb2NhdGlvbiA9IGZzLnBhdGhFeGlzdHNTeW5jKG5vZGVMb2NhdGlvbikgPyBub2RlTG9jYXRpb24gOiBudWxsXG5cbiAgICAvLyBEZXRlY3QgaWYgdGhlIGJyb3dzZXIgcGx1Z2luIGVudHJ5IGV4aXN0cywgYW5kIHByb3ZpZGUgdGhlIG5vZGVSZXNvbHZlciB0byBpdFxuICAgIGJyb3dzZXJMb2NhdGlvbiA9IGZzLnBhdGhFeGlzdHNTeW5jKGJyb3dzZXJMb2NhdGlvbilcbiAgICAgID8gYnJvd3NlckxvY2F0aW9uXG4gICAgICA6IG51bGxcblxuICAgIGxldCBidWlsZFBsdWdpbkhvb2tzID0gKCkgPT4gKHt9KVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEdldCB0aGUgaG9va3MgZm9yIHRoZSBub2RlIGFwaVxuICAgICAgaWYgKG5vZGVMb2NhdGlvbikge1xuICAgICAgICBidWlsZFBsdWdpbkhvb2tzID0gcmVxdWlyZShub2RlTG9jYXRpb24pLmRlZmF1bHRcbiAgICAgIH0gZWxzZSBpZiAob3JpZ2luYWxMb2NhdGlvbiAhPT0gcGF0aHMuUk9PVCAmJiAhYnJvd3NlckxvY2F0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ291bGQgbm90IGZpbmQgYSB2YWxpZCBub2RlLmFwaS5qcyBvciBicm93c2VyLmFwaS5qcyBwbHVnaW4gZmlsZSBpbiBcIiR7bG9jYXRpb259XCIuIFxcbmAgK1xuICAgICAgICAgICAgYFRoZSBvcmlnaW5hbCBsb2NhdGlvbjogXCIke29yaWdpbmFsTG9jYXRpb259XCIuIFxcbmAgK1xuICAgICAgICAgICAgYFRoZSByb290IGxvY2F0aW9uOiBcIiR7cGF0aHMuUk9PVH1cIi5gXG4gICAgICAgIClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzb2x2ZWRQbHVnaW4gPSB7XG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICBub2RlTG9jYXRpb24sXG4gICAgICAgIGJyb3dzZXJMb2NhdGlvbixcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgaG9va3M6IGJ1aWxkUGx1Z2luSG9va3Mob3B0aW9ucykgfHwge30sXG4gICAgICB9XG5cbiAgICAgIHZhbGlkYXRlUGx1Z2luKHJlc29sdmVkUGx1Z2luKVxuXG4gICAgICAvLyBSZWN1cnNpdmVseSByZXNvbHZlIHBsdWdpbnNcbiAgICAgIGlmIChyZXNvbHZlZFBsdWdpbi5wbHVnaW5zKSB7XG4gICAgICAgIHJlc29sdmVkUGx1Z2luLnBsdWdpbnMgPSByZXNvbHZlZFBsdWdpbi5wbHVnaW5zLm1hcChyZXNvbHZlUGx1Z2luKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzb2x2ZWRQbHVnaW5cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBUaGUgZm9sbG93aW5nIGVycm9yIG9jY3VycmVkIGluIHRoZSBwbHVnaW46IFwiJHtvcmlnaW5hbExvY2F0aW9ufVwiYFxuICAgICAgKVxuICAgICAgdGhyb3cgZXJyXG4gICAgfVxuICB9XG5cbiAgc3RhdGUgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgcGx1Z2luczogY29uZmlnLnBsdWdpbnMubWFwKHJlc29sdmVQbHVnaW4pLFxuICAgIGNvbmZpZyxcbiAgfVxuXG4gIHJldHVybiBjb3JlUGx1Z2lucy5hZnRlckdldENvbmZpZyhzdGF0ZSlcbn1cbiJdfQ==