507 lines
No EOL
47 KiB
JavaScript
507 lines
No EOL
47 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.recursivePatternCapture = recursivePatternCapture;
|
|
|
|
var _fs = require('fs');
|
|
|
|
var _fs2 = _interopRequireDefault(_fs);
|
|
|
|
var _doctrine = require('doctrine');
|
|
|
|
var _doctrine2 = _interopRequireDefault(_doctrine);
|
|
|
|
var _debug = require('debug');
|
|
|
|
var _debug2 = _interopRequireDefault(_debug);
|
|
|
|
var _parse = require('eslint-module-utils/parse');
|
|
|
|
var _parse2 = _interopRequireDefault(_parse);
|
|
|
|
var _resolve = require('eslint-module-utils/resolve');
|
|
|
|
var _resolve2 = _interopRequireDefault(_resolve);
|
|
|
|
var _ignore = require('eslint-module-utils/ignore');
|
|
|
|
var _ignore2 = _interopRequireDefault(_ignore);
|
|
|
|
var _hash = require('eslint-module-utils/hash');
|
|
|
|
var _unambiguous = require('eslint-module-utils/unambiguous');
|
|
|
|
var unambiguous = _interopRequireWildcard(_unambiguous);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
const log = (0, _debug2.default)('eslint-plugin-import:ExportMap');
|
|
|
|
const exportCache = new Map();
|
|
|
|
class ExportMap {
|
|
constructor(path) {
|
|
this.path = path;
|
|
this.namespace = new Map();
|
|
// todo: restructure to key on path, value is resolver + map of names
|
|
this.reexports = new Map();
|
|
this.dependencies = new Map();
|
|
this.errors = [];
|
|
}
|
|
|
|
get hasDefault() {
|
|
return this.get('default') != null;
|
|
} // stronger than this.has
|
|
|
|
get size() {
|
|
let size = this.namespace.size + this.reexports.size;
|
|
this.dependencies.forEach(dep => size += dep().size);
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Note that this does not check explicitly re-exported names for existence
|
|
* in the base namespace, but it will expand all `export * from '...'` exports
|
|
* if not found in the explicit namespace.
|
|
* @param {string} name
|
|
* @return {Boolean} true if `name` is exported by this module.
|
|
*/
|
|
has(name) {
|
|
if (this.namespace.has(name)) return true;
|
|
if (this.reexports.has(name)) return true;
|
|
|
|
// default exports must be explicitly re-exported (#328)
|
|
if (name !== 'default') {
|
|
for (let dep of this.dependencies.values()) {
|
|
let innerMap = dep();
|
|
|
|
// todo: report as unresolved?
|
|
if (!innerMap) continue;
|
|
|
|
if (innerMap.has(name)) return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* ensure that imported name fully resolves.
|
|
* @param {[type]} name [description]
|
|
* @return {Boolean} [description]
|
|
*/
|
|
hasDeep(name) {
|
|
if (this.namespace.has(name)) return { found: true, path: [this] };
|
|
|
|
if (this.reexports.has(name)) {
|
|
const reexports = this.reexports.get(name),
|
|
imported = reexports.getImport();
|
|
|
|
// if import is ignored, return explicit 'null'
|
|
if (imported == null) return { found: true, path: [this] };
|
|
|
|
// safeguard against cycles, only if name matches
|
|
if (imported.path === this.path && reexports.local === name) {
|
|
return { found: false, path: [this] };
|
|
}
|
|
|
|
const deep = imported.hasDeep(reexports.local);
|
|
deep.path.unshift(this);
|
|
|
|
return deep;
|
|
}
|
|
|
|
// default exports must be explicitly re-exported (#328)
|
|
if (name !== 'default') {
|
|
for (let dep of this.dependencies.values()) {
|
|
let innerMap = dep();
|
|
// todo: report as unresolved?
|
|
if (!innerMap) continue;
|
|
|
|
// safeguard against cycles
|
|
if (innerMap.path === this.path) continue;
|
|
|
|
let innerValue = innerMap.hasDeep(name);
|
|
if (innerValue.found) {
|
|
innerValue.path.unshift(this);
|
|
return innerValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
return { found: false, path: [this] };
|
|
}
|
|
|
|
get(name) {
|
|
if (this.namespace.has(name)) return this.namespace.get(name);
|
|
|
|
if (this.reexports.has(name)) {
|
|
const reexports = this.reexports.get(name),
|
|
imported = reexports.getImport();
|
|
|
|
// if import is ignored, return explicit 'null'
|
|
if (imported == null) return null;
|
|
|
|
// safeguard against cycles, only if name matches
|
|
if (imported.path === this.path && reexports.local === name) return undefined;
|
|
|
|
return imported.get(reexports.local);
|
|
}
|
|
|
|
// default exports must be explicitly re-exported (#328)
|
|
if (name !== 'default') {
|
|
for (let dep of this.dependencies.values()) {
|
|
let innerMap = dep();
|
|
// todo: report as unresolved?
|
|
if (!innerMap) continue;
|
|
|
|
// safeguard against cycles
|
|
if (innerMap.path === this.path) continue;
|
|
|
|
let innerValue = innerMap.get(name);
|
|
if (innerValue !== undefined) return innerValue;
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
forEach(callback, thisArg) {
|
|
this.namespace.forEach((v, n) => callback.call(thisArg, v, n, this));
|
|
|
|
this.reexports.forEach((reexports, name) => {
|
|
const reexported = reexports.getImport();
|
|
// can't look up meta for ignored re-exports (#348)
|
|
callback.call(thisArg, reexported && reexported.get(reexports.local), name, this);
|
|
});
|
|
|
|
this.dependencies.forEach(dep => {
|
|
const d = dep();
|
|
// CJS / ignored dependencies won't exist (#717)
|
|
if (d == null) return;
|
|
|
|
d.forEach((v, n) => n !== 'default' && callback.call(thisArg, v, n, this));
|
|
});
|
|
}
|
|
|
|
// todo: keys, values, entries?
|
|
|
|
reportErrors(context, declaration) {
|
|
context.report({
|
|
node: declaration.source,
|
|
message: `Parse errors in imported module '${declaration.source.value}': ` + `${this.errors.map(e => `${e.message} (${e.lineNumber}:${e.column})`).join(', ')}`
|
|
});
|
|
}
|
|
}
|
|
|
|
exports.default = ExportMap; /**
|
|
* parse docs from the first node that has leading comments
|
|
* @param {...[type]} nodes [description]
|
|
* @return {{doc: object}}
|
|
*/
|
|
|
|
function captureDoc(docStyleParsers) {
|
|
const metadata = {},
|
|
nodes = Array.prototype.slice.call(arguments, 1);
|
|
|
|
// 'some' short-circuits on first 'true'
|
|
nodes.some(n => {
|
|
if (!n.leadingComments) return false;
|
|
|
|
for (let name in docStyleParsers) {
|
|
const doc = docStyleParsers[name](n.leadingComments);
|
|
if (doc) {
|
|
metadata.doc = doc;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
return metadata;
|
|
}
|
|
|
|
const availableDocStyleParsers = {
|
|
jsdoc: captureJsDoc,
|
|
tomdoc: captureTomDoc
|
|
};
|
|
|
|
/**
|
|
* parse JSDoc from leading comments
|
|
* @param {...[type]} comments [description]
|
|
* @return {{doc: object}}
|
|
*/
|
|
function captureJsDoc(comments) {
|
|
let doc;
|
|
|
|
// capture XSDoc
|
|
comments.forEach(comment => {
|
|
// skip non-block comments
|
|
if (comment.value.slice(0, 4) !== '*\n *') return;
|
|
try {
|
|
doc = _doctrine2.default.parse(comment.value, { unwrap: true });
|
|
} catch (err) {
|
|
/* don't care, for now? maybe add to `errors?` */
|
|
}
|
|
});
|
|
|
|
return doc;
|
|
}
|
|
|
|
/**
|
|
* parse TomDoc section from comments
|
|
*/
|
|
function captureTomDoc(comments) {
|
|
// collect lines up to first paragraph break
|
|
const lines = [];
|
|
for (let i = 0; i < comments.length; i++) {
|
|
const comment = comments[i];
|
|
if (comment.value.match(/^\s*$/)) break;
|
|
lines.push(comment.value.trim());
|
|
}
|
|
|
|
// return doctrine-like object
|
|
const statusMatch = lines.join(' ').match(/^(Public|Internal|Deprecated):\s*(.+)/);
|
|
if (statusMatch) {
|
|
return {
|
|
description: statusMatch[2],
|
|
tags: [{
|
|
title: statusMatch[1].toLowerCase(),
|
|
description: statusMatch[2]
|
|
}]
|
|
};
|
|
}
|
|
}
|
|
|
|
ExportMap.get = function (source, context) {
|
|
const path = (0, _resolve2.default)(source, context);
|
|
if (path == null) return null;
|
|
|
|
return ExportMap.for(path, context);
|
|
};
|
|
|
|
ExportMap.for = function (path, context) {
|
|
let exportMap;
|
|
|
|
const cacheKey = (0, _hash.hashObject)({
|
|
settings: context.settings,
|
|
parserPath: context.parserPath,
|
|
parserOptions: context.parserOptions,
|
|
path
|
|
}).digest('hex');
|
|
|
|
exportMap = exportCache.get(cacheKey);
|
|
|
|
// return cached ignore
|
|
if (exportMap === null) return null;
|
|
|
|
const stats = _fs2.default.statSync(path);
|
|
if (exportMap != null) {
|
|
// date equality check
|
|
if (exportMap.mtime - stats.mtime === 0) {
|
|
return exportMap;
|
|
}
|
|
// future: check content equality?
|
|
}
|
|
|
|
// check valid extensions first
|
|
if (!(0, _ignore.hasValidExtension)(path, context)) {
|
|
exportCache.set(cacheKey, null);
|
|
return null;
|
|
}
|
|
|
|
const content = _fs2.default.readFileSync(path, { encoding: 'utf8' });
|
|
|
|
// check for and cache ignore
|
|
if ((0, _ignore2.default)(path, context) || !unambiguous.test(content)) {
|
|
log('ignored path due to unambiguous regex or ignore settings:', path);
|
|
exportCache.set(cacheKey, null);
|
|
return null;
|
|
}
|
|
|
|
exportMap = ExportMap.parse(path, content, context);
|
|
|
|
// ambiguous modules return null
|
|
if (exportMap == null) return null;
|
|
|
|
exportMap.mtime = stats.mtime;
|
|
|
|
exportCache.set(cacheKey, exportMap);
|
|
return exportMap;
|
|
};
|
|
|
|
ExportMap.parse = function (path, content, context) {
|
|
var m = new ExportMap(path);
|
|
|
|
try {
|
|
var ast = (0, _parse2.default)(path, content, context);
|
|
} catch (err) {
|
|
log('parse error:', path, err);
|
|
m.errors.push(err);
|
|
return m; // can't continue
|
|
}
|
|
|
|
if (!unambiguous.isModule(ast)) return null;
|
|
|
|
const docstyle = context.settings && context.settings['import/docstyle'] || ['jsdoc'];
|
|
const docStyleParsers = {};
|
|
docstyle.forEach(style => {
|
|
docStyleParsers[style] = availableDocStyleParsers[style];
|
|
});
|
|
|
|
// attempt to collect module doc
|
|
if (ast.comments) {
|
|
ast.comments.some(c => {
|
|
if (c.type !== 'Block') return false;
|
|
try {
|
|
const doc = _doctrine2.default.parse(c.value, { unwrap: true });
|
|
if (doc.tags.some(t => t.title === 'module')) {
|
|
m.doc = doc;
|
|
return true;
|
|
}
|
|
} catch (err) {/* ignore */}
|
|
return false;
|
|
});
|
|
}
|
|
|
|
const namespaces = new Map();
|
|
|
|
function remotePath(node) {
|
|
return _resolve2.default.relative(node.source.value, path, context.settings);
|
|
}
|
|
|
|
function resolveImport(node) {
|
|
const rp = remotePath(node);
|
|
if (rp == null) return null;
|
|
return ExportMap.for(rp, context);
|
|
}
|
|
|
|
function getNamespace(identifier) {
|
|
if (!namespaces.has(identifier.name)) return;
|
|
|
|
return function () {
|
|
return resolveImport(namespaces.get(identifier.name));
|
|
};
|
|
}
|
|
|
|
function addNamespace(object, identifier) {
|
|
const nsfn = getNamespace(identifier);
|
|
if (nsfn) {
|
|
Object.defineProperty(object, 'namespace', { get: nsfn });
|
|
}
|
|
|
|
return object;
|
|
}
|
|
|
|
ast.body.forEach(function (n) {
|
|
|
|
if (n.type === 'ExportDefaultDeclaration') {
|
|
const exportMeta = captureDoc(docStyleParsers, n);
|
|
if (n.declaration.type === 'Identifier') {
|
|
addNamespace(exportMeta, n.declaration);
|
|
}
|
|
m.namespace.set('default', exportMeta);
|
|
return;
|
|
}
|
|
|
|
if (n.type === 'ExportAllDeclaration') {
|
|
let remoteMap = remotePath(n);
|
|
if (remoteMap == null) return;
|
|
m.dependencies.set(remoteMap, () => ExportMap.for(remoteMap, context));
|
|
return;
|
|
}
|
|
|
|
// capture namespaces in case of later export
|
|
if (n.type === 'ImportDeclaration') {
|
|
let ns;
|
|
if (n.specifiers.some(s => s.type === 'ImportNamespaceSpecifier' && (ns = s))) {
|
|
namespaces.set(ns.local.name, n);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (n.type === 'ExportNamedDeclaration') {
|
|
// capture declaration
|
|
if (n.declaration != null) {
|
|
switch (n.declaration.type) {
|
|
case 'FunctionDeclaration':
|
|
case 'ClassDeclaration':
|
|
case 'TypeAlias': // flowtype with babel-eslint parser
|
|
case 'InterfaceDeclaration':
|
|
m.namespace.set(n.declaration.id.name, captureDoc(docStyleParsers, n));
|
|
break;
|
|
case 'VariableDeclaration':
|
|
n.declaration.declarations.forEach(d => recursivePatternCapture(d.id, id => m.namespace.set(id.name, captureDoc(docStyleParsers, d, n))));
|
|
break;
|
|
}
|
|
}
|
|
|
|
n.specifiers.forEach(s => {
|
|
const exportMeta = {};
|
|
let local;
|
|
|
|
switch (s.type) {
|
|
case 'ExportDefaultSpecifier':
|
|
if (!n.source) return;
|
|
local = 'default';
|
|
break;
|
|
case 'ExportNamespaceSpecifier':
|
|
m.namespace.set(s.exported.name, Object.defineProperty(exportMeta, 'namespace', {
|
|
get() {
|
|
return resolveImport(n);
|
|
}
|
|
}));
|
|
return;
|
|
case 'ExportSpecifier':
|
|
if (!n.source) {
|
|
m.namespace.set(s.exported.name, addNamespace(exportMeta, s.local));
|
|
return;
|
|
}
|
|
// else falls through
|
|
default:
|
|
local = s.local.name;
|
|
break;
|
|
}
|
|
|
|
// todo: JSDoc
|
|
m.reexports.set(s.exported.name, { local, getImport: () => resolveImport(n) });
|
|
});
|
|
}
|
|
});
|
|
|
|
return m;
|
|
};
|
|
|
|
/**
|
|
* Traverse a pattern/identifier node, calling 'callback'
|
|
* for each leaf identifier.
|
|
* @param {node} pattern
|
|
* @param {Function} callback
|
|
* @return {void}
|
|
*/
|
|
function recursivePatternCapture(pattern, callback) {
|
|
switch (pattern.type) {
|
|
case 'Identifier':
|
|
// base case
|
|
callback(pattern);
|
|
break;
|
|
|
|
case 'ObjectPattern':
|
|
pattern.properties.forEach(p => {
|
|
recursivePatternCapture(p.value, callback);
|
|
});
|
|
break;
|
|
|
|
case 'ArrayPattern':
|
|
pattern.elements.forEach(element => {
|
|
if (element == null) return;
|
|
recursivePatternCapture(element, callback);
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkV4cG9ydE1hcC5qcyJdLCJuYW1lcyI6WyJyZWN1cnNpdmVQYXR0ZXJuQ2FwdHVyZSIsInVuYW1iaWd1b3VzIiwibG9nIiwiZXhwb3J0Q2FjaGUiLCJNYXAiLCJFeHBvcnRNYXAiLCJjb25zdHJ1Y3RvciIsInBhdGgiLCJuYW1lc3BhY2UiLCJyZWV4cG9ydHMiLCJkZXBlbmRlbmNpZXMiLCJlcnJvcnMiLCJoYXNEZWZhdWx0IiwiZ2V0Iiwic2l6ZSIsImZvckVhY2giLCJkZXAiLCJoYXMiLCJuYW1lIiwidmFsdWVzIiwiaW5uZXJNYXAiLCJoYXNEZWVwIiwiZm91bmQiLCJpbXBvcnRlZCIsImdldEltcG9ydCIsImxvY2FsIiwiZGVlcCIsInVuc2hpZnQiLCJpbm5lclZhbHVlIiwidW5kZWZpbmVkIiwiY2FsbGJhY2siLCJ0aGlzQXJnIiwidiIsIm4iLCJjYWxsIiwicmVleHBvcnRlZCIsImQiLCJyZXBvcnRFcnJvcnMiLCJjb250ZXh0IiwiZGVjbGFyYXRpb24iLCJyZXBvcnQiLCJub2RlIiwic291cmNlIiwibWVzc2FnZSIsInZhbHVlIiwibWFwIiwiZSIsImxpbmVOdW1iZXIiLCJjb2x1bW4iLCJqb2luIiwiY2FwdHVyZURvYyIsImRvY1N0eWxlUGFyc2VycyIsIm1ldGFkYXRhIiwibm9kZXMiLCJBcnJheSIsInByb3RvdHlwZSIsInNsaWNlIiwiYXJndW1lbnRzIiwic29tZSIsImxlYWRpbmdDb21tZW50cyIsImRvYyIsImF2YWlsYWJsZURvY1N0eWxlUGFyc2VycyIsImpzZG9jIiwiY2FwdHVyZUpzRG9jIiwidG9tZG9jIiwiY2FwdHVyZVRvbURvYyIsImNvbW1lbnRzIiwiY29tbWVudCIsInBhcnNlIiwidW53cmFwIiwiZXJyIiwibGluZXMiLCJpIiwibGVuZ3RoIiwibWF0Y2giLCJwdXNoIiwidHJpbSIsInN0YXR1c01hdGNoIiwiZGVzY3JpcHRpb24iLCJ0YWdzIiwidGl0bGUiLCJ0b0xvd2VyQ2FzZSIsImZvciIsImV4cG9ydE1hcCIsImNhY2hlS2V5Iiwic2V0dGluZ3MiLCJwYXJzZXJQYXRoIiwicGFyc2VyT3B0aW9ucyIsImRpZ2VzdCIsInN0YXRzIiwic3RhdFN5bmMiLCJtdGltZSIsInNldCIsImNvbnRlbnQiLCJyZWFkRmlsZVN5bmMiLCJlbmNvZGluZyIsInRlc3QiLCJtIiwiYXN0IiwiaXNNb2R1bGUiLCJkb2NzdHlsZSIsInN0eWxlIiwiYyIsInR5cGUiLCJ0IiwibmFtZXNwYWNlcyIsInJlbW90ZVBhdGgiLCJyZWxhdGl2ZSIsInJlc29sdmVJbXBvcnQiLCJycCIsImdldE5hbWVzcGFjZSIsImlkZW50aWZpZXIiLCJhZGROYW1lc3BhY2UiLCJvYmplY3QiLCJuc2ZuIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJib2R5IiwiZXhwb3J0TWV0YSIsInJlbW90ZU1hcCIsIm5zIiwic3BlY2lmaWVycyIsInMiLCJpZCIsImRlY2xhcmF0aW9ucyIsImV4cG9ydGVkIiwicGF0dGVybiIsInByb3BlcnRpZXMiLCJwIiwiZWxlbWVudHMiLCJlbGVtZW50Il0sIm1hcHBpbmdzIjoiOzs7OztRQStjZ0JBLHVCLEdBQUFBLHVCOztBQS9jaEI7Ozs7QUFFQTs7OztBQUVBOzs7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUE7O0FBQ0E7O0lBQVlDLFc7Ozs7OztBQUVaLE1BQU1DLE1BQU0scUJBQU0sZ0NBQU4sQ0FBWjs7QUFFQSxNQUFNQyxjQUFjLElBQUlDLEdBQUosRUFBcEI7O0FBRWUsTUFBTUMsU0FBTixDQUFnQjtBQUM3QkMsY0FBWUMsSUFBWixFQUFrQjtBQUNoQixTQUFLQSxJQUFMLEdBQVlBLElBQVo7QUFDQSxTQUFLQyxTQUFMLEdBQWlCLElBQUlKLEdBQUosRUFBakI7QUFDQTtBQUNBLFNBQUtLLFNBQUwsR0FBaUIsSUFBSUwsR0FBSixFQUFqQjtBQUNBLFNBQUtNLFlBQUwsR0FBb0IsSUFBSU4sR0FBSixFQUFwQjtBQUNBLFNBQUtPLE1BQUwsR0FBYyxFQUFkO0FBQ0Q7O0FBRUQsTUFBSUMsVUFBSixHQUFpQjtBQUFFLFdBQU8sS0FBS0MsR0FBTCxDQUFTLFNBQVQsS0FBdUIsSUFBOUI7QUFBb0MsR0FWMUIsQ0FVMkI7O0FBRXhELE1BQUlDLElBQUosR0FBVztBQUNULFFBQUlBLE9BQU8sS0FBS04sU0FBTCxDQUFlTSxJQUFmLEdBQXNCLEtBQUtMLFNBQUwsQ0FBZUssSUFBaEQ7QUFDQSxTQUFLSixZQUFMLENBQWtCSyxPQUFsQixDQUEwQkMsT0FBT0YsUUFBUUUsTUFBTUYsSUFBL0M7QUFDQSxXQUFPQSxJQUFQO0FBQ0Q7O0FBRUQ7Ozs7Ozs7QUFPQUcsTUFBSUMsSUFBSixFQUFVO0FBQ1IsUUFBSSxLQUFLVixTQUFMLENBQWVTLEdBQWYsQ0FBbUJDLElBQW5CLENBQUosRUFBOEIsT0FBTyxJQUFQO0FBQzlCLFFBQUksS0FBS1QsU0FBTCxDQUFlUSxHQUFmLENBQW1CQyxJQUFuQixDQUFKLEVBQThCLE9BQU8sSUFBUDs7QUFFOUI7QUFDQSxRQUFJQSxTQUFTLFNBQWIsRUFBd0I7QUFDdEIsV0FBSyxJQUFJRixHQUFULElBQWdCLEtBQUtOLFlBQUwsQ0FBa0JTLE1BQWxCLEVBQWhCLEVBQTRDO0FBQzFDLFlBQUlDLFdBQVdKLEtBQWY7O0FBRUE7QUFDQSxZQUFJLENBQUNJLFFBQUwsRUFBZTs7QUFFZixZQUFJQSxTQUFTSCxHQUFULENBQWFDLElBQWIsQ0FBSixFQUF3QixPQUFPLElBQVA7QUFDekI7QUFDRjs7QUFFRCxXQUFPLEtBQVA7QUFDRDs7QUFFRDs7Ozs7QUFLQUcsVUFBUUgsSUFBUixFQUFjO0FBQ1osUUFBSSxLQUFLVixTQUFMLENBQWVTLEdBQWYsQ0FBbUJDLElBQW5CLENBQUosRUFBOEIsT0FBTyxFQUFFSSxPQUFPLElBQVQsRUFBZWYsTUFBTSxDQUFDLElBQUQsQ0FBckIsRUFBUDs7QUFFOUIsUUFBSSxLQUFLRSxTQUFMLENBQWVRLEdBQWYsQ0FBbUJDLElBQW5CLENBQUosRUFBOEI7QUFDNUIsWUFBTVQsWUFBWSxLQUFLQSxTQUFMLENBQWVJLEdBQWYsQ0FBbUJLLElBQW5CLENBQWxCO0FBQUEsWUFDTUssV0FBV2QsVUFBVWUsU0FBVixFQURqQjs7QUFHQTtBQUNBLFVBQUlELFlBQVksSUFBaEIsRUFBc0IsT0FBTyxFQUFFRCxPQUFPLElBQVQsRUFBZWYsTUFBTSxDQUFDLElBQUQsQ0FBckIsRUFBUDs7QUFFdEI7QUFDQSxVQUFJZ0IsU0FBU2hCLElBQVQsS0FBa0IsS0FBS0EsSUFBdkIsSUFBK0JFLFVBQVVnQixLQUFWLEtBQW9CUCxJQUF2RCxFQUE2RDtBQUMzRCxlQUFPLEVBQUVJLE9BQU8sS0FBVCxFQUFnQmYsTUFBTSxDQUFDLElBQUQsQ0FBdEIsRUFBUDtBQUNEOztBQUVELFlBQU1tQixPQUFPSCxTQUFTRixPQUFULENBQWlCWixVQUFVZ0IsS0FBM0IsQ0FBYjtBQUNBQyxXQUFLbkIsSUFBTCxDQUFVb0IsT0FBVixDQUFrQixJQUFsQjs7QUFFQSxhQUFPRCxJQUFQO0FBQ0Q7O0FBR0Q7QUFDQSxRQUFJUixTQUFTLFNBQWIsRUFBd0I7QUFDdEIsV0FBSyxJQUFJRixHQUFULElBQWdCLEtBQUtOLFlBQUwsQ0FBa0JTLE1BQWxCLEVBQWhCLEVBQTRDO0FBQzFDLFlBQUlDLFdBQVdKLEtBQWY7QUFDQTtBQUNBLFlBQUksQ0FBQ0ksUUFBTCxFQUFlOztBQUVmO0FBQ0EsWUFBSUEsU0FBU2IsSUFBVCxLQUFrQixLQUFLQSxJQUEzQixFQUFpQzs7QUFFakMsWUFBSXFCLGFBQWFSLFNBQVNDLE9BQVQsQ0FBaUJILElBQWpCLENBQWpCO0FBQ0EsWUFBSVUsV0FBV04sS0FBZixFQUFzQjtBQUNwQk0scUJBQVdyQixJQUFYLENBQWdCb0IsT0FBaEIsQ0FBd0IsSUFBeEI7QUFDQSxpQkFBT0MsVUFBUDtBQUNEO0FBQ0Y7QUFDRjs7QUFFRCxXQUFPLEVBQUVOLE9BQU8sS0FBVCxFQUFnQmYsTUFBTSxDQUFDLElBQUQsQ0FBdEIsRUFBUDtBQUNEOztBQUVETSxNQUFJSyxJQUFKLEVBQVU7QUFDUixRQUFJLEtBQUtWLFNBQUwsQ0FBZVMsR0FBZixDQUFtQkMsSUFBbkIsQ0FBSixFQUE4QixPQUFPLEtBQUtWLFNBQUwsQ0FBZUssR0FBZixDQUFtQkssSUFBbkIsQ0FBUDs7QUFFOUIsUUFBSSxLQUFLVCxTQUFMLENBQWVRLEdBQWYsQ0FBbUJDLElBQW5CLENBQUosRUFBOEI7QUFDNUIsWUFBTVQsWUFBWSxLQUFLQSxTQUFMLENBQWVJLEdBQWYsQ0FBbUJLLElBQW5CLENBQWxCO0FBQUEsWUFDTUssV0FBV2QsVUFBVWUsU0FBVixFQURqQjs7QUFHQTtBQUNBLFVBQUlELFlBQVksSUFBaEIsRUFBc0IsT0FBTyxJQUFQOztBQUV0QjtBQUNBLFVBQUlBLFNBQVNoQixJQUFULEtBQWtCLEtBQUtBLElBQXZCLElBQStCRSxVQUFVZ0IsS0FBVixLQUFvQlAsSUFBdkQsRUFBNkQsT0FBT1csU0FBUDs7QUFFN0QsYUFBT04sU0FBU1YsR0FBVCxDQUFhSixVQUFVZ0IsS0FBdkIsQ0FBUDtBQUNEOztBQUVEO0FBQ0EsUUFBSVAsU0FBUyxTQUFiLEVBQXdCO0FBQ3RCLFdBQUssSUFBSUYsR0FBVCxJQUFnQixLQUFLTixZQUFMLENBQWtCUyxNQUFsQixFQUFoQixFQUE0QztBQUMxQyxZQUFJQyxXQUFXSixLQUFmO0FBQ0E7QUFDQSxZQUFJLENBQUNJLFFBQUwsRUFBZTs7QUFFZjtBQUNBLFlBQUlBLFNBQVNiLElBQVQsS0FBa0IsS0FBS0EsSUFBM0IsRUFBaUM7O0FBRWpDLFlBQUlxQixhQUFhUixTQUFTUCxHQUFULENBQWFLLElBQWIsQ0FBakI7QUFDQSxZQUFJVSxlQUFlQyxTQUFuQixFQUE4QixPQUFPRCxVQUFQO0FBQy9CO0FBQ0Y7O0FBRUQsV0FBT0MsU0FBUDtBQUNEOztBQUVEZCxVQUFRZSxRQUFSLEVBQWtCQyxPQUFsQixFQUEyQjtBQUN6QixTQUFLdkIsU0FBTCxDQUFlTyxPQUFmLENBQXVCLENBQUNpQixDQUFELEVBQUlDLENBQUosS0FDckJILFNBQVNJLElBQVQsQ0FBY0gsT0FBZCxFQUF1QkMsQ0FBdkIsRUFBMEJDLENBQTFCLEVBQTZCLElBQTdCLENBREY7O0FBR0EsU0FBS3hCLFNBQUwsQ0FBZU0sT0FBZixDQUF1QixDQUFDTixTQUFELEVBQVlTLElBQVosS0FBcUI7QUFDMUMsWUFBTWlCLGFBQWExQixVQUFVZSxTQUFWLEVBQW5CO0FBQ0E7QUFDQU0sZUFBU0ksSUFBVCxDQUFjSCxPQUFkLEVBQXVCSSxjQUFjQSxXQUFXdEIsR0FBWCxDQUFlSixVQUFVZ0IsS0FBekIsQ0FBckMsRUFBc0VQLElBQXRFLEVBQTRFLElBQTVFO0FBQ0QsS0FKRDs7QUFNQSxTQUFLUixZQUFMLENBQWtCSyxPQUFsQixDQUEwQkMsT0FBTztBQUMvQixZQUFNb0IsSUFBSXBCLEtBQVY7QUFDQTtBQUNBLFVBQUlvQixLQUFLLElBQVQsRUFBZTs7QUFFZkEsUUFBRXJCLE9BQUYsQ0FBVSxDQUFDaUIsQ0FBRCxFQUFJQyxDQUFKLEtBQ1JBLE1BQU0sU0FBTixJQUFtQkgsU0FBU0ksSUFBVCxDQUFjSCxPQUFkLEVBQXVCQyxDQUF2QixFQUEwQkMsQ0FBMUIsRUFBNkIsSUFBN0IsQ0FEckI7QUFFRCxLQVBEO0FBUUQ7O0FBRUQ7O0FBRUFJLGVBQWFDLE9BQWIsRUFBc0JDLFdBQXRCLEVBQW1DO0FBQ2pDRCxZQUFRRSxNQUFSLENBQWU7QUFDYkMsWUFBTUYsWUFBWUcsTUFETDtBQUViQyxlQUFVLG9DQUFtQ0osWUFBWUcsTUFBWixDQUFtQkUsS0FBTSxLQUE3RCxHQUNJLEdBQUUsS0FBS2pDLE1BQUwsQ0FDSWtDLEdBREosQ0FDUUMsS0FBTSxHQUFFQSxFQUFFSCxPQUFRLEtBQUlHLEVBQUVDLFVBQVcsSUFBR0QsRUFBRUUsTUFBTyxHQUR2RCxFQUVJQyxJQUZKLENBRVMsSUFGVCxDQUVlO0FBTGpCLEtBQWY7QUFPRDtBQTVKNEI7O2tCQUFWNUMsUyxFQStKckI7Ozs7OztBQUtBLFNBQVM2QyxVQUFULENBQW9CQyxlQUFwQixFQUFxQztBQUNuQyxRQUFNQyxXQUFXLEVBQWpCO0FBQUEsUUFDT0MsUUFBUUMsTUFBTUMsU0FBTixDQUFnQkMsS0FBaEIsQ0FBc0J0QixJQUF0QixDQUEyQnVCLFNBQTNCLEVBQXNDLENBQXRDLENBRGY7O0FBR0E7QUFDQUosUUFBTUssSUFBTixDQUFXekIsS0FBSztBQUNkLFFBQUksQ0FBQ0EsRUFBRTBCLGVBQVAsRUFBd0IsT0FBTyxLQUFQOztBQUV4QixTQUFLLElBQUl6QyxJQUFULElBQWlCaUMsZUFBakIsRUFBa0M7QUFDaEMsWUFBTVMsTUFBTVQsZ0JBQWdCakMsSUFBaEIsRUFBc0JlLEVBQUUwQixlQUF4QixDQUFaO0FBQ0EsVUFBSUMsR0FBSixFQUFTO0FBQ1BSLGlCQUFTUSxHQUFULEdBQWVBLEdBQWY7QUFDRDtBQUNGOztBQUVELFdBQU8sSUFBUDtBQUNELEdBWEQ7O0FBYUEsU0FBT1IsUUFBUDtBQUNEOztBQUVELE1BQU1TLDJCQUEyQjtBQUMvQkMsU0FBT0MsWUFEd0I7QUFFL0JDLFVBQVFDO0FBRnVCLENBQWpDOztBQUtBOzs7OztBQUtBLFNBQVNGLFlBQVQsQ0FBc0JHLFFBQXRCLEVBQWdDO0FBQzlCLE1BQUlOLEdBQUo7O0FBRUE7QUFDQU0sV0FBU25ELE9BQVQsQ0FBaUJvRCxXQUFXO0FBQzFCO0FBQ0EsUUFBSUEsUUFBUXZCLEtBQVIsQ0FBY1ksS0FBZCxDQUFvQixDQUFwQixFQUF1QixDQUF2QixNQUE4QixPQUFsQyxFQUEyQztBQUMzQyxRQUFJO0FBQ0ZJLFlBQU0sbUJBQVNRLEtBQVQsQ0FBZUQsUUFBUXZCLEtBQXZCLEVBQThCLEVBQUV5QixRQUFRLElBQVYsRUFBOUIsQ0FBTjtBQUNELEtBRkQsQ0FFRSxPQUFPQyxHQUFQLEVBQVk7QUFDWjtBQUNEO0FBQ0YsR0FSRDs7QUFVQSxTQUFPVixHQUFQO0FBQ0Q7O0FBRUQ7OztBQUdBLFNBQVNLLGFBQVQsQ0FBdUJDLFFBQXZCLEVBQWlDO0FBQy9CO0FBQ0EsUUFBTUssUUFBUSxFQUFkO0FBQ0EsT0FBSyxJQUFJQyxJQUFJLENBQWIsRUFBZ0JBLElBQUlOLFNBQVNPLE1BQTdCLEVBQXFDRCxHQUFyQyxFQUEwQztBQUN4QyxVQUFNTCxVQUFVRCxTQUFTTSxDQUFULENBQWhCO0FBQ0EsUUFBSUwsUUFBUXZCLEtBQVIsQ0FBYzhCLEtBQWQsQ0FBb0IsT0FBcEIsQ0FBSixFQUFrQztBQUNsQ0gsVUFBTUksSUFBTixDQUFXUixRQUFRdkIsS0FBUixDQUFjZ0MsSUFBZCxFQUFYO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFNQyxjQUFjTixNQUFNdEIsSUFBTixDQUFXLEdBQVgsRUFBZ0J5QixLQUFoQixDQUFzQix1Q0FBdEIsQ0FBcEI7QUFDQSxNQUFJRyxXQUFKLEVBQWlCO0FBQ2YsV0FBTztBQUNMQyxtQkFBYUQsWUFBWSxDQUFaLENBRFI7QUFFTEUsWUFBTSxDQUFDO0FBQ0xDLGVBQU9ILFlBQVksQ0FBWixFQUFlSSxXQUFmLEVBREY7QUFFTEgscUJBQWFELFlBQVksQ0FBWjtBQUZSLE9BQUQ7QUFGRCxLQUFQO0FBT0Q7QUFDRjs7QUFFRHhFLFVBQVVRLEdBQVYsR0FBZ0IsVUFBVTZCLE1BQVYsRUFBa0JKLE9BQWxCLEVBQTJCO0FBQ3pDLFFBQU0vQixPQUFPLHVCQUFRbUMsTUFBUixFQUFnQkosT0FBaEIsQ0FBYjtBQUNBLE1BQUkvQixRQUFRLElBQVosRUFBa0IsT0FBTyxJQUFQOztBQUVsQixTQUFPRixVQUFVNkUsR0FBVixDQUFjM0UsSUFBZCxFQUFvQitCLE9BQXBCLENBQVA7QUFDRCxDQUxEOztBQU9BakMsVUFBVTZFLEdBQVYsR0FBZ0IsVUFBVTNFLElBQVYsRUFBZ0IrQixPQUFoQixFQUF5QjtBQUN2QyxNQUFJNkMsU0FBSjs7QUFFQSxRQUFNQyxXQUFXLHNCQUFXO0FBQzFCQyxjQUFVL0MsUUFBUStDLFFBRFE7QUFFMUJDLGdCQUFZaEQsUUFBUWdELFVBRk07QUFHMUJDLG1CQUFlakQsUUFBUWlELGFBSEc7QUFJMUJoRjtBQUowQixHQUFYLEVBS2RpRixNQUxjLENBS1AsS0FMTyxDQUFqQjs7QUFPQUwsY0FBWWhGLFlBQVlVLEdBQVosQ0FBZ0J1RSxRQUFoQixDQUFaOztBQUVBO0FBQ0EsTUFBSUQsY0FBYyxJQUFsQixFQUF3QixPQUFPLElBQVA7O0FBRXhCLFFBQU1NLFFBQVEsYUFBR0MsUUFBSCxDQUFZbkYsSUFBWixDQUFkO0FBQ0EsTUFBSTRFLGFBQWEsSUFBakIsRUFBdUI7QUFDckI7QUFDQSxRQUFJQSxVQUFVUSxLQUFWLEdBQWtCRixNQUFNRSxLQUF4QixLQUFrQyxDQUF0QyxFQUF5QztBQUN2QyxhQUFPUixTQUFQO0FBQ0Q7QUFDRDtBQUNEOztBQUVEO0FBQ0EsTUFBSSxDQUFDLCtCQUFrQjVFLElBQWxCLEVBQXdCK0IsT0FBeEIsQ0FBTCxFQUF1QztBQUNyQ25DLGdCQUFZeUYsR0FBWixDQUFnQlIsUUFBaEIsRUFBMEIsSUFBMUI7QUFDQSxXQUFPLElBQVA7QUFDRDs7QUFFRCxRQUFNUyxVQUFVLGFBQUdDLFlBQUgsQ0FBZ0J2RixJQUFoQixFQUFzQixFQUFFd0YsVUFBVSxNQUFaLEVBQXRCLENBQWhCOztBQUVBO0FBQ0EsTUFBSSxzQkFBVXhGLElBQVYsRUFBZ0IrQixPQUFoQixLQUE0QixDQUFDckMsWUFBWStGLElBQVosQ0FBaUJILE9BQWpCLENBQWpDLEVBQTREO0FBQzFEM0YsUUFBSSwyREFBSixFQUFpRUssSUFBakU7QUFDQUosZ0JBQVl5RixHQUFaLENBQWdCUixRQUFoQixFQUEwQixJQUExQjtBQUNBLFdBQU8sSUFBUDtBQUNEOztBQUVERCxjQUFZOUUsVUFBVStELEtBQVYsQ0FBZ0I3RCxJQUFoQixFQUFzQnNGLE9BQXRCLEVBQStCdkQsT0FBL0IsQ0FBWjs7QUFFQTtBQUNBLE1BQUk2QyxhQUFhLElBQWpCLEVBQXVCLE9BQU8sSUFBUDs7QUFFdkJBLFlBQVVRLEtBQVYsR0FBa0JGLE1BQU1FLEtBQXhCOztBQUVBeEYsY0FBWXlGLEdBQVosQ0FBZ0JSLFFBQWhCLEVBQTBCRCxTQUExQjtBQUNBLFNBQU9BLFNBQVA7QUFDRCxDQWhERDs7QUFtREE5RSxVQUFVK0QsS0FBVixHQUFrQixVQUFVN0QsSUFBVixFQUFnQnNGLE9BQWhCLEVBQXlCdkQsT0FBekIsRUFBa0M7QUFDbEQsTUFBSTJELElBQUksSUFBSTVGLFNBQUosQ0FBY0UsSUFBZCxDQUFSOztBQUVBLE1BQUk7QUFDRixRQUFJMkYsTUFBTSxxQkFBTTNGLElBQU4sRUFBWXNGLE9BQVosRUFBcUJ2RCxPQUFyQixDQUFWO0FBQ0QsR0FGRCxDQUVFLE9BQU9nQyxHQUFQLEVBQVk7QUFDWnBFLFFBQUksY0FBSixFQUFvQkssSUFBcEIsRUFBMEIrRCxHQUExQjtBQUNBMkIsTUFBRXRGLE1BQUYsQ0FBU2dFLElBQVQsQ0FBY0wsR0FBZDtBQUNBLFdBQU8yQixDQUFQLENBSFksQ0FHSDtBQUNWOztBQUVELE1BQUksQ0FBQ2hHLFlBQVlrRyxRQUFaLENBQXFCRCxHQUFyQixDQUFMLEVBQWdDLE9BQU8sSUFBUDs7QUFFaEMsUUFBTUUsV0FBWTlELFFBQVErQyxRQUFSLElBQW9CL0MsUUFBUStDLFFBQVIsQ0FBaUIsaUJBQWpCLENBQXJCLElBQTZELENBQUMsT0FBRCxDQUE5RTtBQUNBLFFBQU1sQyxrQkFBa0IsRUFBeEI7QUFDQWlELFdBQVNyRixPQUFULENBQWlCc0YsU0FBUztBQUN4QmxELG9CQUFnQmtELEtBQWhCLElBQXlCeEMseUJBQXlCd0MsS0FBekIsQ0FBekI7QUFDRCxHQUZEOztBQUlBO0FBQ0EsTUFBSUgsSUFBSWhDLFFBQVIsRUFBa0I7QUFDaEJnQyxRQUFJaEMsUUFBSixDQUFhUixJQUFiLENBQWtCNEMsS0FBSztBQUNyQixVQUFJQSxFQUFFQyxJQUFGLEtBQVcsT0FBZixFQUF3QixPQUFPLEtBQVA7QUFDeEIsVUFBSTtBQUNGLGNBQU0zQyxNQUFNLG1CQUFTUSxLQUFULENBQWVrQyxFQUFFMUQsS0FBakIsRUFBd0IsRUFBRXlCLFFBQVEsSUFBVixFQUF4QixDQUFaO0FBQ0EsWUFBSVQsSUFBSW1CLElBQUosQ0FBU3JCLElBQVQsQ0FBYzhDLEtBQUtBLEVBQUV4QixLQUFGLEtBQVksUUFBL0IsQ0FBSixFQUE4QztBQUM1Q2lCLFlBQUVyQyxHQUFGLEdBQVFBLEdBQVI7QUFDQSxpQkFBTyxJQUFQO0FBQ0Q7QUFDRixPQU5ELENBTUUsT0FBT1UsR0FBUCxFQUFZLENBQUUsWUFBYztBQUM5QixhQUFPLEtBQVA7QUFDRCxLQVZEO0FBV0Q7O0FBRUQsUUFBTW1DLGFBQWEsSUFBSXJHLEdBQUosRUFBbkI7O0FBRUEsV0FBU3NHLFVBQVQsQ0FBb0JqRSxJQUFwQixFQUEwQjtBQUN4QixXQUFPLGtCQUFRa0UsUUFBUixDQUFpQmxFLEtBQUtDLE1BQUwsQ0FBWUUsS0FBN0IsRUFBb0NyQyxJQUFwQyxFQUEwQytCLFFBQVErQyxRQUFsRCxDQUFQO0FBQ0Q7O0FBRUQsV0FBU3VCLGFBQVQsQ0FBdUJuRSxJQUF2QixFQUE2QjtBQUMzQixVQUFNb0UsS0FBS0gsV0FBV2pFLElBQVgsQ0FBWDtBQUNBLFFBQUlvRSxNQUFNLElBQVYsRUFBZ0IsT0FBTyxJQUFQO0FBQ2hCLFdBQU94RyxVQUFVNkUsR0FBVixDQUFjMkIsRUFBZCxFQUFrQnZFLE9BQWxCLENBQVA7QUFDRDs7QUFFRCxXQUFTd0UsWUFBVCxDQUFzQkMsVUFBdEIsRUFBa0M7QUFDaEMsUUFBSSxDQUFDTixXQUFXeEYsR0FBWCxDQUFlOEYsV0FBVzdGLElBQTFCLENBQUwsRUFBc0M7O0FBRXRDLFdBQU8sWUFBWTtBQUNqQixhQUFPMEYsY0FBY0gsV0FBVzVGLEdBQVgsQ0FBZWtHLFdBQVc3RixJQUExQixDQUFkLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBRUQsV0FBUzhGLFlBQVQsQ0FBc0JDLE1BQXRCLEVBQThCRixVQUE5QixFQUEwQztBQUN4QyxVQUFNRyxPQUFPSixhQUFhQyxVQUFiLENBQWI7QUFDQSxRQUFJRyxJQUFKLEVBQVU7QUFDUkMsYUFBT0MsY0FBUCxDQUFzQkgsTUFBdEIsRUFBOEIsV0FBOUIsRUFBMkMsRUFBRXBHLEtBQUtxRyxJQUFQLEVBQTNDO0FBQ0Q7O0FBRUQsV0FBT0QsTUFBUDtBQUNEOztBQUdEZixNQUFJbUIsSUFBSixDQUFTdEcsT0FBVCxDQUFpQixVQUFVa0IsQ0FBVixFQUFhOztBQUU1QixRQUFJQSxFQUFFc0UsSUFBRixLQUFXLDBCQUFmLEVBQTJDO0FBQ3pDLFlBQU1lLGFBQWFwRSxXQUFXQyxlQUFYLEVBQTRCbEIsQ0FBNUIsQ0FBbkI7QUFDQSxVQUFJQSxFQUFFTSxXQUFGLENBQWNnRSxJQUFkLEtBQXVCLFlBQTNCLEVBQXlDO0FBQ3ZDUyxxQkFBYU0sVUFBYixFQUF5QnJGLEVBQUVNLFdBQTNCO0FBQ0Q7QUFDRDBELFFBQUV6RixTQUFGLENBQVlvRixHQUFaLENBQWdCLFNBQWhCLEVBQTJCMEIsVUFBM0I7QUFDQTtBQUNEOztBQUVELFFBQUlyRixFQUFFc0UsSUFBRixLQUFXLHNCQUFmLEVBQXVDO0FBQ3JDLFVBQUlnQixZQUFZYixXQUFXekUsQ0FBWCxDQUFoQjtBQUNBLFVBQUlzRixhQUFhLElBQWpCLEVBQXVCO0FBQ3ZCdEIsUUFBRXZGLFlBQUYsQ0FBZWtGLEdBQWYsQ0FBbUIyQixTQUFuQixFQUE4QixNQUFNbEgsVUFBVTZFLEdBQVYsQ0FBY3FDLFNBQWQsRUFBeUJqRixPQUF6QixDQUFwQztBQUNBO0FBQ0Q7O0FBRUQ7QUFDQSxRQUFJTCxFQUFFc0UsSUFBRixLQUFXLG1CQUFmLEVBQW9DO0FBQ2xDLFVBQUlpQixFQUFKO0FBQ0EsVUFBSXZGLEVBQUV3RixVQUFGLENBQWEvRCxJQUFiLENBQWtCZ0UsS0FBS0EsRUFBRW5CLElBQUYsS0FBVywwQkFBWCxLQUEwQ2lCLEtBQUtFLENBQS9DLENBQXZCLENBQUosRUFBK0U7QUFDN0VqQixtQkFBV2IsR0FBWCxDQUFlNEIsR0FBRy9GLEtBQUgsQ0FBU1AsSUFBeEIsRUFBOEJlLENBQTlCO0FBQ0Q7QUFDRDtBQUNEOztBQUVELFFBQUlBLEVBQUVzRSxJQUFGLEtBQVcsd0JBQWYsRUFBd0M7QUFDdEM7QUFDQSxVQUFJdEUsRUFBRU0sV0FBRixJQUFpQixJQUFyQixFQUEyQjtBQUN6QixnQkFBUU4sRUFBRU0sV0FBRixDQUFjZ0UsSUFBdEI7QUFDRSxlQUFLLHFCQUFMO0FBQ0EsZUFBSyxrQkFBTDtBQUNBLGVBQUssV0FBTCxDQUhGLENBR29CO0FBQ2xCLGVBQUssc0JBQUw7QUFDRU4sY0FBRXpGLFNBQUYsQ0FBWW9GLEdBQVosQ0FBZ0IzRCxFQUFFTSxXQUFGLENBQWNvRixFQUFkLENBQWlCekcsSUFBakMsRUFBdUNnQyxXQUFXQyxlQUFYLEVBQTRCbEIsQ0FBNUIsQ0FBdkM7QUFDQTtBQUNGLGVBQUsscUJBQUw7QUFDRUEsY0FBRU0sV0FBRixDQUFjcUYsWUFBZCxDQUEyQjdHLE9BQTNCLENBQW9DcUIsQ0FBRCxJQUNqQ3BDLHdCQUF3Qm9DLEVBQUV1RixFQUExQixFQUNFQSxNQUFNMUIsRUFBRXpGLFNBQUYsQ0FBWW9GLEdBQVosQ0FBZ0IrQixHQUFHekcsSUFBbkIsRUFBeUJnQyxXQUFXQyxlQUFYLEVBQTRCZixDQUE1QixFQUErQkgsQ0FBL0IsQ0FBekIsQ0FEUixDQURGO0FBR0E7QUFYSjtBQWFEOztBQUVEQSxRQUFFd0YsVUFBRixDQUFhMUcsT0FBYixDQUFzQjJHLENBQUQsSUFBTztBQUMxQixjQUFNSixhQUFhLEVBQW5CO0FBQ0EsWUFBSTdGLEtBQUo7O0FBRUEsZ0JBQVFpRyxFQUFFbkIsSUFBVjtBQUNFLGVBQUssd0JBQUw7QUFDRSxnQkFBSSxDQUFDdEUsRUFBRVMsTUFBUCxFQUFlO0FBQ2ZqQixvQkFBUSxTQUFSO0FBQ0E7QUFDRixlQUFLLDBCQUFMO0FBQ0V3RSxjQUFFekYsU0FBRixDQUFZb0YsR0FBWixDQUFnQjhCLEVBQUVHLFFBQUYsQ0FBVzNHLElBQTNCLEVBQWlDaUcsT0FBT0MsY0FBUCxDQUFzQkUsVUFBdEIsRUFBa0MsV0FBbEMsRUFBK0M7QUFDOUV6RyxvQkFBTTtBQUFFLHVCQUFPK0YsY0FBYzNFLENBQWQsQ0FBUDtBQUF5QjtBQUQ2QyxhQUEvQyxDQUFqQztBQUdBO0FBQ0YsZUFBSyxpQkFBTDtBQUNFLGdCQUFJLENBQUNBLEVBQUVTLE1BQVAsRUFBZTtBQUNidUQsZ0JBQUV6RixTQUFGLENBQVlvRixHQUFaLENBQWdCOEIsRUFBRUcsUUFBRixDQUFXM0csSUFBM0IsRUFBaUM4RixhQUFhTSxVQUFiLEVBQXlCSSxFQUFFakcsS0FBM0IsQ0FBakM7QUFDQTtBQUNEO0FBQ0Q7QUFDRjtBQUNFQSxvQkFBUWlHLEVBQUVqRyxLQUFGLENBQVFQLElBQWhCO0FBQ0E7QUFsQko7O0FBcUJBO0FBQ0ErRSxVQUFFeEYsU0FBRixDQUFZbUYsR0FBWixDQUFnQjhCLEVBQUVHLFFBQUYsQ0FBVzNHLElBQTNCLEVBQWlDLEVBQUVPLEtBQUYsRUFBU0QsV0FBVyxNQUFNb0YsY0FBYzNFLENBQWQsQ0FBMUIsRUFBakM7QUFDRCxPQTNCRDtBQTRCRDtBQUNGLEdBMUVEOztBQTRFQSxTQUFPZ0UsQ0FBUDtBQUNELENBN0lEOztBQWdKQTs7Ozs7OztBQU9PLFNBQVNqRyx1QkFBVCxDQUFpQzhILE9BQWpDLEVBQTBDaEcsUUFBMUMsRUFBb0Q7QUFDekQsVUFBUWdHLFFBQVF2QixJQUFoQjtBQUNFLFNBQUssWUFBTDtBQUFtQjtBQUNqQnpFLGVBQVNnRyxPQUFUO0FBQ0E7O0FBRUYsU0FBSyxlQUFMO0FBQ0VBLGNBQVFDLFVBQVIsQ0FBbUJoSCxPQUFuQixDQUEyQmlILEtBQUs7QUFDOUJoSSxnQ0FBd0JnSSxFQUFFcEYsS0FBMUIsRUFBaUNkLFFBQWpDO0FBQ0QsT0FGRDtBQUdBOztBQUVGLFNBQUssY0FBTDtBQUNFZ0csY0FBUUcsUUFBUixDQUFpQmxILE9BQWpCLENBQTBCbUgsT0FBRCxJQUFhO0FBQ3BDLFlBQUlBLFdBQVcsSUFBZixFQUFxQjtBQUNyQmxJLGdDQUF3QmtJLE9BQXhCLEVBQWlDcEcsUUFBakM7QUFDRCxPQUhEO0FBSUE7QUFoQko7QUFrQkQiLCJmaWxlIjoiRXhwb3J0TWFwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gJ2ZzJ1xuXG5pbXBvcnQgZG9jdHJpbmUgZnJvbSAnZG9jdHJpbmUnXG5cbmltcG9ydCBkZWJ1ZyBmcm9tICdkZWJ1ZydcblxuaW1wb3J0IHBhcnNlIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvcGFyc2UnXG5pbXBvcnQgcmVzb2x2ZSBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL3Jlc29sdmUnXG5pbXBvcnQgaXNJZ25vcmVkLCB7IGhhc1ZhbGlkRXh0ZW5zaW9uIH0gZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy9pZ25vcmUnXG5cbmltcG9ydCB7IGhhc2hPYmplY3QgfSBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL2hhc2gnXG5pbXBvcnQgKiBhcyB1bmFtYmlndW91cyBmcm9tICdlc2xpbnQtbW9kdWxlLXV0aWxzL3VuYW1iaWd1b3VzJ1xuXG5jb25zdCBsb2cgPSBkZWJ1ZygnZXNsaW50LXBsdWdpbi1pbXBvcnQ6RXhwb3J0TWFwJylcblxuY29uc3QgZXhwb3J0Q2FjaGUgPSBuZXcgTWFwKClcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhwb3J0TWFwIHtcbiAgY29uc3RydWN0b3IocGF0aCkge1xuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgICB0aGlzLm5hbWVzcGFjZSA9IG5ldyBNYXAoKVxuICAgIC8vIHRvZG86IHJlc3RydWN0dXJlIHRvIGtleSBvbiBwYXRoLCB2YWx1ZSBpcyByZXNvbHZlciArIG1hcCBvZiBuYW1lc1xuICAgIHRoaXMucmVleHBvcnRzID0gbmV3IE1hcCgpXG4gICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBuZXcgTWFwKClcbiAgICB0aGlzLmVycm9ycyA9IFtdXG4gIH1cblxuICBnZXQgaGFzRGVmYXVsdCgpIHsgcmV0dXJuIHRoaXMuZ2V0KCdkZWZhdWx0JykgIT0gbnVsbCB9IC8vIHN0cm9uZ2VyIHRoYW4gdGhpcy5oYXNcblxuICBnZXQgc2l6ZSgpIHtcbiAgICBsZXQgc2l6ZSA9IHRoaXMubmFtZXNwYWNlLnNpemUgKyB0aGlzLnJlZXhwb3J0cy5zaXplXG4gICAgdGhpcy5kZXBlbmRlbmNpZXMuZm9yRWFjaChkZXAgPT4gc2l6ZSArPSBkZXAoKS5zaXplKVxuICAgIHJldHVybiBzaXplXG4gIH1cblxuICAvKipcbiAgICogTm90ZSB0aGF0IHRoaXMgZG9lcyBub3QgY2hlY2sgZXhwbGljaXRseSByZS1leHBvcnRlZCBuYW1lcyBmb3IgZXhpc3RlbmNlXG4gICAqIGluIHRoZSBiYXNlIG5hbWVzcGFjZSwgYnV0IGl0IHdpbGwgZXhwYW5kIGFsbCBgZXhwb3J0ICogZnJvbSAnLi4uJ2AgZXhwb3J0c1xuICAgKiBpZiBub3QgZm91bmQgaW4gdGhlIGV4cGxpY2l0IG5hbWVzcGFjZS5cbiAgICogQHBhcmFtICB7c3RyaW5nfSAgbmFtZVxuICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIGBuYW1lYCBpcyBleHBvcnRlZCBieSB0aGlzIG1vZHVsZS5cbiAgICovXG4gIGhhcyhuYW1lKSB7XG4gICAgaWYgKHRoaXMubmFtZXNwYWNlLmhhcyhuYW1lKSkgcmV0dXJuIHRydWVcbiAgICBpZiAodGhpcy5yZWV4cG9ydHMuaGFzKG5hbWUpKSByZXR1cm4gdHJ1ZVxuXG4gICAgLy8gZGVmYXVsdCBleHBvcnRzIG11c3QgYmUgZXhwbGljaXRseSByZS1leHBvcnRlZCAoIzMyOClcbiAgICBpZiAobmFtZSAhPT0gJ2RlZmF1bHQnKSB7XG4gICAgICBmb3IgKGxldCBkZXAgb2YgdGhpcy5kZXBlbmRlbmNpZXMudmFsdWVzKCkpIHtcbiAgICAgICAgbGV0IGlubmVyTWFwID0gZGVwKClcblxuICAgICAgICAvLyB0b2RvOiByZXBvcnQgYXMgdW5yZXNvbHZlZD9cbiAgICAgICAgaWYgKCFpbm5lck1hcCkgY29udGludWVcblxuICAgICAgICBpZiAoaW5uZXJNYXAuaGFzKG5hbWUpKSByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIGVuc3VyZSB0aGF0IGltcG9ydGVkIG5hbWUgZnVsbHkgcmVzb2x2ZXMuXG4gICAqIEBwYXJhbSAge1t0eXBlXX0gIG5hbWUgW2Rlc2NyaXB0aW9uXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufSAgICAgIFtkZXNjcmlwdGlvbl1cbiAgICovXG4gIGhhc0RlZXAobmFtZSkge1xuICAgIGlmICh0aGlzLm5hbWVzcGFjZS5oYXMobmFtZSkpIHJldHVybiB7IGZvdW5kOiB0cnVlLCBwYXRoOiBbdGhpc10gfVxuXG4gICAgaWYgKHRoaXMucmVleHBvcnRzLmhhcyhuYW1lKSkge1xuICAgICAgY29uc3QgcmVleHBvcnRzID0gdGhpcy5yZWV4cG9ydHMuZ2V0KG5hbWUpXG4gICAgICAgICAgLCBpbXBvcnRlZCA9IHJlZXhwb3J0cy5nZXRJbXBvcnQoKVxuXG4gICAgICAvLyBpZiBpbXBvcnQgaXMgaWdub3JlZCwgcmV0dXJuIGV4cGxpY2l0ICdudWxsJ1xuICAgICAgaWYgKGltcG9ydGVkID09IG51bGwpIHJldHVybiB7IGZvdW5kOiB0cnVlLCBwYXRoOiBbdGhpc10gfVxuXG4gICAgICAvLyBzYWZlZ3VhcmQgYWdhaW5zdCBjeWNsZXMsIG9ubHkgaWYgbmFtZSBtYXRjaGVzXG4gICAgICBpZiAoaW1wb3J0ZWQucGF0aCA9PT0gdGhpcy5wYXRoICYmIHJlZXhwb3J0cy5sb2NhbCA9PT0gbmFtZSkge1xuICAgICAgICByZXR1cm4geyBmb3VuZDogZmFsc2UsIHBhdGg6IFt0aGlzXSB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlZXAgPSBpbXBvcnRlZC5oYXNEZWVwKHJlZXhwb3J0cy5sb2NhbClcbiAgICAgIGRlZXAucGF0aC51bnNoaWZ0KHRoaXMpXG5cbiAgICAgIHJldHVybiBkZWVwXG4gICAgfVxuXG5cbiAgICAvLyBkZWZhdWx0IGV4cG9ydHMgbXVzdCBiZSBleHBsaWNpdGx5IHJlLWV4cG9ydGVkICgjMzI4KVxuICAgIGlmIChuYW1lICE9PSAnZGVmYXVsdCcpIHtcbiAgICAgIGZvciAobGV0IGRlcCBvZiB0aGlzLmRlcGVuZGVuY2llcy52YWx1ZXMoKSkge1xuICAgICAgICBsZXQgaW5uZXJNYXAgPSBkZXAoKVxuICAgICAgICAvLyB0b2RvOiByZXBvcnQgYXMgdW5yZXNvbHZlZD9cbiAgICAgICAgaWYgKCFpbm5lck1hcCkgY29udGludWVcblxuICAgICAgICAvLyBzYWZlZ3VhcmQgYWdhaW5zdCBjeWNsZXNcbiAgICAgICAgaWYgKGlubmVyTWFwLnBhdGggPT09IHRoaXMucGF0aCkgY29udGludWVcblxuICAgICAgICBsZXQgaW5uZXJWYWx1ZSA9IGlubmVyTWFwLmhhc0RlZXAobmFtZSlcbiAgICAgICAgaWYgKGlubmVyVmFsdWUuZm91bmQpIHtcbiAgICAgICAgICBpbm5lclZhbHVlLnBhdGgudW5zaGlmdCh0aGlzKVxuICAgICAgICAgIHJldHVybiBpbm5lclZhbHVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBmb3VuZDogZmFsc2UsIHBhdGg6IFt0aGlzXSB9XG4gIH1cblxuICBnZXQobmFtZSkge1xuICAgIGlmICh0aGlzLm5hbWVzcGFjZS5oYXMobmFtZSkpIHJldHVybiB0aGlzLm5hbWVzcGFjZS5nZXQobmFtZSlcblxuICAgIGlmICh0aGlzLnJlZXhwb3J0cy5oYXMobmFtZSkpIHtcbiAgICAgIGNvbnN0IHJlZXhwb3J0cyA9IHRoaXMucmVleHBvcnRzLmdldChuYW1lKVxuICAgICAgICAgICwgaW1wb3J0ZWQgPSByZWV4cG9ydHMuZ2V0SW1wb3J0KClcblxuICAgICAgLy8gaWYgaW1wb3J0IGlzIGlnbm9yZWQsIHJldHVybiBleHBsaWNpdCAnbnVsbCdcbiAgICAgIGlmIChpbXBvcnRlZCA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gICAgICAvLyBzYWZlZ3VhcmQgYWdhaW5zdCBjeWNsZXMsIG9ubHkgaWYgbmFtZSBtYXRjaGVzXG4gICAgICBpZiAoaW1wb3J0ZWQucGF0aCA9PT0gdGhpcy5wYXRoICYmIHJlZXhwb3J0cy5sb2NhbCA9PT0gbmFtZSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgICByZXR1cm4gaW1wb3J0ZWQuZ2V0KHJlZXhwb3J0cy5sb2NhbClcbiAgICB9XG5cbiAgICAvLyBkZWZhdWx0IGV4cG9ydHMgbXVzdCBiZSBleHBsaWNpdGx5IHJlLWV4cG9ydGVkICgjMzI4KVxuICAgIGlmIChuYW1lICE9PSAnZGVmYXVsdCcpIHtcbiAgICAgIGZvciAobGV0IGRlcCBvZiB0aGlzLmRlcGVuZGVuY2llcy52YWx1ZXMoKSkge1xuICAgICAgICBsZXQgaW5uZXJNYXAgPSBkZXAoKVxuICAgICAgICAvLyB0b2RvOiByZXBvcnQgYXMgdW5yZXNvbHZlZD9cbiAgICAgICAgaWYgKCFpbm5lck1hcCkgY29udGludWVcblxuICAgICAgICAvLyBzYWZlZ3VhcmQgYWdhaW5zdCBjeWNsZXNcbiAgICAgICAgaWYgKGlubmVyTWFwLnBhdGggPT09IHRoaXMucGF0aCkgY29udGludWVcblxuICAgICAgICBsZXQgaW5uZXJWYWx1ZSA9IGlubmVyTWFwLmdldChuYW1lKVxuICAgICAgICBpZiAoaW5uZXJWYWx1ZSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gaW5uZXJWYWx1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICB0aGlzLm5hbWVzcGFjZS5mb3JFYWNoKCh2LCBuKSA9PlxuICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2LCBuLCB0aGlzKSlcblxuICAgIHRoaXMucmVleHBvcnRzLmZvckVhY2goKHJlZXhwb3J0cywgbmFtZSkgPT4ge1xuICAgICAgY29uc3QgcmVleHBvcnRlZCA9IHJlZXhwb3J0cy5nZXRJbXBvcnQoKVxuICAgICAgLy8gY2FuJ3QgbG9vayB1cCBtZXRhIGZvciBpZ25vcmVkIHJlLWV4cG9ydHMgKCMzNDgpXG4gICAgICBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHJlZXhwb3J0ZWQgJiYgcmVleHBvcnRlZC5nZXQocmVleHBvcnRzLmxvY2FsKSwgbmFtZSwgdGhpcylcbiAgICB9KVxuXG4gICAgdGhpcy5kZXBlbmRlbmNpZXMuZm9yRWFjaChkZXAgPT4ge1xuICAgICAgY29uc3QgZCA9IGRlcCgpXG4gICAgICAvLyBDSlMgLyBpZ25vcmVkIGRlcGVuZGVuY2llcyB3b24ndCBleGlzdCAoIzcxNylcbiAgICAgIGlmIChkID09IG51bGwpIHJldHVyblxuXG4gICAgICBkLmZvckVhY2goKHYsIG4pID0+XG4gICAgICAgIG4gIT09ICdkZWZhdWx0JyAmJiBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHYsIG4sIHRoaXMpKVxuICAgIH0pXG4gIH1cblxuICAvLyB0b2RvOiBrZXlzLCB2YWx1ZXMsIGVudHJpZXM/XG5cbiAgcmVwb3J0RXJyb3JzKGNvbnRleHQsIGRlY2xhcmF0aW9uKSB7XG4gICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgbm9kZTogZGVjbGFyYXRpb24uc291cmNlLFxuICAgICAgbWVzc2FnZTogYFBhcnNlIGVycm9ycyBpbiBpbXBvcnRlZCBtb2R1bGUgJyR7ZGVjbGFyYXRpb24uc291cmNlLnZhbHVlfSc6IGAgK1xuICAgICAgICAgICAgICAgICAgYCR7dGhpcy5lcnJvcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoZSA9PiBgJHtlLm1lc3NhZ2V9ICgke2UubGluZU51bWJlcn06JHtlLmNvbHVtbn0pYClcbiAgICAgICAgICAgICAgICAgICAgICAgIC5qb2luKCcsICcpfWAsXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIHBhcnNlIGRvY3MgZnJvbSB0aGUgZmlyc3Qgbm9kZSB0aGF0IGhhcyBsZWFkaW5nIGNvbW1lbnRzXG4gKiBAcGFyYW0gIHsuLi5bdHlwZV19IG5vZGVzIFtkZXNjcmlwdGlvbl1cbiAqIEByZXR1cm4ge3tkb2M6IG9iamVjdH19XG4gKi9cbmZ1bmN0aW9uIGNhcHR1cmVEb2MoZG9jU3R5bGVQYXJzZXJzKSB7XG4gIGNvbnN0IG1ldGFkYXRhID0ge31cbiAgICAgICAsIG5vZGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuXG4gIC8vICdzb21lJyBzaG9ydC1jaXJjdWl0cyBvbiBmaXJzdCAndHJ1ZSdcbiAgbm9kZXMuc29tZShuID0+IHtcbiAgICBpZiAoIW4ubGVhZGluZ0NvbW1lbnRzKSByZXR1cm4gZmFsc2VcblxuICAgIGZvciAobGV0IG5hbWUgaW4gZG9jU3R5bGVQYXJzZXJzKSB7XG4gICAgICBjb25zdCBkb2MgPSBkb2NTdHlsZVBhcnNlcnNbbmFtZV0obi5sZWFkaW5nQ29tbWVudHMpXG4gICAgICBpZiAoZG9jKSB7XG4gICAgICAgIG1ldGFkYXRhLmRvYyA9IGRvY1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH0pXG5cbiAgcmV0dXJuIG1ldGFkYXRhXG59XG5cbmNvbnN0IGF2YWlsYWJsZURvY1N0eWxlUGFyc2VycyA9IHtcbiAganNkb2M6IGNhcHR1cmVKc0RvYyxcbiAgdG9tZG9jOiBjYXB0dXJlVG9tRG9jLFxufVxuXG4vKipcbiAqIHBhcnNlIEpTRG9jIGZyb20gbGVhZGluZyBjb21tZW50c1xuICogQHBhcmFtICB7Li4uW3R5cGVdfSBjb21tZW50cyBbZGVzY3JpcHRpb25dXG4gKiBAcmV0dXJuIHt7ZG9jOiBvYmplY3R9fVxuICovXG5mdW5jdGlvbiBjYXB0dXJlSnNEb2MoY29tbWVudHMpIHtcbiAgbGV0IGRvY1xuXG4gIC8vIGNhcHR1cmUgWFNEb2NcbiAgY29tbWVudHMuZm9yRWFjaChjb21tZW50ID0+IHtcbiAgICAvLyBza2lwIG5vbi1ibG9jayBjb21tZW50c1xuICAgIGlmIChjb21tZW50LnZhbHVlLnNsaWNlKDAsIDQpICE9PSAnKlxcbiAqJykgcmV0dXJuXG4gICAgdHJ5IHtcbiAgICAgIGRvYyA9IGRvY3RyaW5lLnBhcnNlKGNvbW1lbnQudmFsdWUsIHsgdW53cmFwOiB0cnVlIH0pXG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvKiBkb24ndCBjYXJlLCBmb3Igbm93PyBtYXliZSBhZGQgdG8gYGVycm9ycz9gICovXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBkb2Ncbn1cblxuLyoqXG4gICogcGFyc2UgVG9tRG9jIHNlY3Rpb24gZnJvbSBjb21tZW50c1xuICAqL1xuZnVuY3Rpb24gY2FwdHVyZVRvbURvYyhjb21tZW50cykge1xuICAvLyBjb2xsZWN0IGxpbmVzIHVwIHRvIGZpcnN0IHBhcmFncmFwaCBicmVha1xuICBjb25zdCBsaW5lcyA9IFtdXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29tbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjb21tZW50ID0gY29tbWVudHNbaV1cbiAgICBpZiAoY29tbWVudC52YWx1ZS5tYXRjaCgvXlxccyokLykpIGJyZWFrXG4gICAgbGluZXMucHVzaChjb21tZW50LnZhbHVlLnRyaW0oKSlcbiAgfVxuXG4gIC8vIHJldHVybiBkb2N0cmluZS1saWtlIG9iamVjdFxuICBjb25zdCBzdGF0dXNNYXRjaCA9IGxpbmVzLmpvaW4oJyAnKS5tYXRjaCgvXihQdWJsaWN8SW50ZXJuYWx8RGVwcmVjYXRlZCk6XFxzKiguKykvKVxuICBpZiAoc3RhdHVzTWF0Y2gpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGVzY3JpcHRpb246IHN0YXR1c01hdGNoWzJdLFxuICAgICAgdGFnczogW3tcbiAgICAgICAgdGl0bGU6IHN0YXR1c01hdGNoWzFdLnRvTG93ZXJDYXNlKCksXG4gICAgICAgIGRlc2NyaXB0aW9uOiBzdGF0dXNNYXRjaFsyXSxcbiAgICAgIH1dLFxuICAgIH1cbiAgfVxufVxuXG5FeHBvcnRNYXAuZ2V0ID0gZnVuY3Rpb24gKHNvdXJjZSwgY29udGV4dCkge1xuICBjb25zdCBwYXRoID0gcmVzb2x2ZShzb3VyY2UsIGNvbnRleHQpXG4gIGlmIChwYXRoID09IG51bGwpIHJldHVybiBudWxsXG5cbiAgcmV0dXJuIEV4cG9ydE1hcC5mb3IocGF0aCwgY29udGV4dClcbn1cblxuRXhwb3J0TWFwLmZvciA9IGZ1bmN0aW9uIChwYXRoLCBjb250ZXh0KSB7XG4gIGxldCBleHBvcnRNYXBcblxuICBjb25zdCBjYWNoZUtleSA9IGhhc2hPYmplY3Qoe1xuICAgIHNldHRpbmdzOiBjb250ZXh0LnNldHRpbmdzLFxuICAgIHBhcnNlclBhdGg6IGNvbnRleHQucGFyc2VyUGF0aCxcbiAgICBwYXJzZXJPcHRpb25zOiBjb250ZXh0LnBhcnNlck9wdGlvbnMsXG4gICAgcGF0aCxcbiAgfSkuZGlnZXN0KCdoZXgnKVxuXG4gIGV4cG9ydE1hcCA9IGV4cG9ydENhY2hlLmdldChjYWNoZUtleSlcblxuICAvLyByZXR1cm4gY2FjaGVkIGlnbm9yZVxuICBpZiAoZXhwb3J0TWFwID09PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gIGNvbnN0IHN0YXRzID0gZnMuc3RhdFN5bmMocGF0aClcbiAgaWYgKGV4cG9ydE1hcCAhPSBudWxsKSB7XG4gICAgLy8gZGF0ZSBlcXVhbGl0eSBjaGVja1xuICAgIGlmIChleHBvcnRNYXAubXRpbWUgLSBzdGF0cy5tdGltZSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGV4cG9ydE1hcFxuICAgIH1cbiAgICAvLyBmdXR1cmU6IGNoZWNrIGNvbnRlbnQgZXF1YWxpdHk/XG4gIH1cblxuICAvLyBjaGVjayB2YWxpZCBleHRlbnNpb25zIGZpcnN0XG4gIGlmICghaGFzVmFsaWRFeHRlbnNpb24ocGF0aCwgY29udGV4dCkpIHtcbiAgICBleHBvcnRDYWNoZS5zZXQoY2FjaGVLZXksIG51bGwpXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMocGF0aCwgeyBlbmNvZGluZzogJ3V0ZjgnIH0pXG5cbiAgLy8gY2hlY2sgZm9yIGFuZCBjYWNoZSBpZ25vcmVcbiAgaWYgKGlzSWdub3JlZChwYXRoLCBjb250ZXh0KSB8fCAhdW5hbWJpZ3VvdXMudGVzdChjb250ZW50KSkge1xuICAgIGxvZygnaWdub3JlZCBwYXRoIGR1ZSB0byB1bmFtYmlndW91cyByZWdleCBvciBpZ25vcmUgc2V0dGluZ3M6JywgcGF0aClcbiAgICBleHBvcnRDYWNoZS5zZXQoY2FjaGVLZXksIG51bGwpXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGV4cG9ydE1hcCA9IEV4cG9ydE1hcC5wYXJzZShwYXRoLCBjb250ZW50LCBjb250ZXh0KVxuXG4gIC8vIGFtYmlndW91cyBtb2R1bGVzIHJldHVybiBudWxsXG4gIGlmIChleHBvcnRNYXAgPT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICBleHBvcnRNYXAubXRpbWUgPSBzdGF0cy5tdGltZVxuXG4gIGV4cG9ydENhY2hlLnNldChjYWNoZUtleSwgZXhwb3J0TWFwKVxuICByZXR1cm4gZXhwb3J0TWFwXG59XG5cblxuRXhwb3J0TWFwLnBhcnNlID0gZnVuY3Rpb24gKHBhdGgsIGNvbnRlbnQsIGNvbnRleHQpIHtcbiAgdmFyIG0gPSBuZXcgRXhwb3J0TWFwKHBhdGgpXG5cbiAgdHJ5IHtcbiAgICB2YXIgYXN0ID0gcGFyc2UocGF0aCwgY29udGVudCwgY29udGV4dClcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nKCdwYXJzZSBlcnJvcjonLCBwYXRoLCBlcnIpXG4gICAgbS5lcnJvcnMucHVzaChlcnIpXG4gICAgcmV0dXJuIG0gLy8gY2FuJ3QgY29udGludWVcbiAgfVxuXG4gIGlmICghdW5hbWJpZ3VvdXMuaXNNb2R1bGUoYXN0KSkgcmV0dXJuIG51bGxcblxuICBjb25zdCBkb2NzdHlsZSA9IChjb250ZXh0LnNldHRpbmdzICYmIGNvbnRleHQuc2V0dGluZ3NbJ2ltcG9ydC9kb2NzdHlsZSddKSB8fCBbJ2pzZG9jJ11cbiAgY29uc3QgZG9jU3R5bGVQYXJzZXJzID0ge31cbiAgZG9jc3R5bGUuZm9yRWFjaChzdHlsZSA9PiB7XG4gICAgZG9jU3R5bGVQYXJzZXJzW3N0eWxlXSA9IGF2YWlsYWJsZURvY1N0eWxlUGFyc2Vyc1tzdHlsZV1cbiAgfSlcblxuICAvLyBhdHRlbXB0IHRvIGNvbGxlY3QgbW9kdWxlIGRvY1xuICBpZiAoYXN0LmNvbW1lbnRzKSB7XG4gICAgYXN0LmNvbW1lbnRzLnNvbWUoYyA9PiB7XG4gICAgICBpZiAoYy50eXBlICE9PSAnQmxvY2snKSByZXR1cm4gZmFsc2VcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRvYyA9IGRvY3RyaW5lLnBhcnNlKGMudmFsdWUsIHsgdW53cmFwOiB0cnVlIH0pXG4gICAgICAgIGlmIChkb2MudGFncy5zb21lKHQgPT4gdC50aXRsZSA9PT0gJ21vZHVsZScpKSB7XG4gICAgICAgICAgbS5kb2MgPSBkb2NcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHsgLyogaWdub3JlICovIH1cbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBuYW1lc3BhY2VzID0gbmV3IE1hcCgpXG5cbiAgZnVuY3Rpb24gcmVtb3RlUGF0aChub2RlKSB7XG4gICAgcmV0dXJuIHJlc29sdmUucmVsYXRpdmUobm9kZS5zb3VyY2UudmFsdWUsIHBhdGgsIGNvbnRleHQuc2V0dGluZ3MpXG4gIH1cblxuICBmdW5jdGlvbiByZXNvbHZlSW1wb3J0KG5vZGUpIHtcbiAgICBjb25zdCBycCA9IHJlbW90ZVBhdGgobm9kZSlcbiAgICBpZiAocnAgPT0gbnVsbCkgcmV0dXJuIG51bGxcbiAgICByZXR1cm4gRXhwb3J0TWFwLmZvcihycCwgY29udGV4dClcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE5hbWVzcGFjZShpZGVudGlmaWVyKSB7XG4gICAgaWYgKCFuYW1lc3BhY2VzLmhhcyhpZGVudGlmaWVyLm5hbWUpKSByZXR1cm5cblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZUltcG9ydChuYW1lc3BhY2VzLmdldChpZGVudGlmaWVyLm5hbWUpKVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZE5hbWVzcGFjZShvYmplY3QsIGlkZW50aWZpZXIpIHtcbiAgICBjb25zdCBuc2ZuID0gZ2V0TmFtZXNwYWNlKGlkZW50aWZpZXIpXG4gICAgaWYgKG5zZm4pIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmplY3QsICduYW1lc3BhY2UnLCB7IGdldDogbnNmbiB9KVxuICAgIH1cblxuICAgIHJldHVybiBvYmplY3RcbiAgfVxuXG5cbiAgYXN0LmJvZHkuZm9yRWFjaChmdW5jdGlvbiAobikge1xuXG4gICAgaWYgKG4udHlwZSA9PT0gJ0V4cG9ydERlZmF1bHREZWNsYXJhdGlvbicpIHtcbiAgICAgIGNvbnN0IGV4cG9ydE1ldGEgPSBjYXB0dXJlRG9jKGRvY1N0eWxlUGFyc2VycywgbilcbiAgICAgIGlmIChuLmRlY2xhcmF0aW9uLnR5cGUgPT09ICdJZGVudGlmaWVyJykge1xuICAgICAgICBhZGROYW1lc3BhY2UoZXhwb3J0TWV0YSwgbi5kZWNsYXJhdGlvbilcbiAgICAgIH1cbiAgICAgIG0ubmFtZXNwYWNlLnNldCgnZGVmYXVsdCcsIGV4cG9ydE1ldGEpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAobi50eXBlID09PSAnRXhwb3J0QWxsRGVjbGFyYXRpb24nKSB7XG4gICAgICBsZXQgcmVtb3RlTWFwID0gcmVtb3RlUGF0aChuKVxuICAgICAgaWYgKHJlbW90ZU1hcCA9PSBudWxsKSByZXR1cm5cbiAgICAgIG0uZGVwZW5kZW5jaWVzLnNldChyZW1vdGVNYXAsICgpID0+IEV4cG9ydE1hcC5mb3IocmVtb3RlTWFwLCBjb250ZXh0KSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIGNhcHR1cmUgbmFtZXNwYWNlcyBpbiBjYXNlIG9mIGxhdGVyIGV4cG9ydFxuICAgIGlmIChuLnR5cGUgPT09ICdJbXBvcnREZWNsYXJhdGlvbicpIHtcbiAgICAgIGxldCBuc1xuICAgICAgaWYgKG4uc3BlY2lmaWVycy5zb21lKHMgPT4gcy50eXBlID09PSAnSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyJyAmJiAobnMgPSBzKSkpIHtcbiAgICAgICAgbmFtZXNwYWNlcy5zZXQobnMubG9jYWwubmFtZSwgbilcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChuLnR5cGUgPT09ICdFeHBvcnROYW1lZERlY2xhcmF0aW9uJyl7XG4gICAgICAvLyBjYXB0dXJlIGRlY2xhcmF0aW9uXG4gICAgICBpZiAobi5kZWNsYXJhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgIHN3aXRjaCAobi5kZWNsYXJhdGlvbi50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnRnVuY3Rpb25EZWNsYXJhdGlvbic6XG4gICAgICAgICAgY2FzZSAnQ2xhc3NEZWNsYXJhdGlvbic6XG4gICAgICAgICAgY2FzZSAnVHlwZUFsaWFzJzogLy8gZmxvd3R5cGUgd2l0aCBiYWJlbC1lc2xpbnQgcGFyc2VyXG4gICAgICAgICAgY2FzZSAnSW50ZXJmYWNlRGVjbGFyYXRpb24nOlxuICAgICAgICAgICAgbS5uYW1lc3BhY2Uuc2V0KG4uZGVjbGFyYXRpb24uaWQubmFtZSwgY2FwdHVyZURvYyhkb2NTdHlsZVBhcnNlcnMsIG4pKVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICBjYXNlICdWYXJpYWJsZURlY2xhcmF0aW9uJzpcbiAgICAgICAgICAgIG4uZGVjbGFyYXRpb24uZGVjbGFyYXRpb25zLmZvckVhY2goKGQpID0+XG4gICAgICAgICAgICAgIHJlY3Vyc2l2ZVBhdHRlcm5DYXB0dXJlKGQuaWQsXG4gICAgICAgICAgICAgICAgaWQgPT4gbS5uYW1lc3BhY2Uuc2V0KGlkLm5hbWUsIGNhcHR1cmVEb2MoZG9jU3R5bGVQYXJzZXJzLCBkLCBuKSkpKVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuLnNwZWNpZmllcnMuZm9yRWFjaCgocykgPT4ge1xuICAgICAgICBjb25zdCBleHBvcnRNZXRhID0ge31cbiAgICAgICAgbGV0IGxvY2FsXG5cbiAgICAgICAgc3dpdGNoIChzLnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdFeHBvcnREZWZhdWx0U3BlY2lmaWVyJzpcbiAgICAgICAgICAgIGlmICghbi5zb3VyY2UpIHJldHVyblxuICAgICAgICAgICAgbG9jYWwgPSAnZGVmYXVsdCdcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSAnRXhwb3J0TmFtZXNwYWNlU3BlY2lmaWVyJzpcbiAgICAgICAgICAgIG0ubmFtZXNwYWNlLnNldChzLmV4cG9ydGVkLm5hbWUsIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRNZXRhLCAnbmFtZXNwYWNlJywge1xuICAgICAgICAgICAgICBnZXQoKSB7IHJldHVybiByZXNvbHZlSW1wb3J0KG4pIH0sXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIGNhc2UgJ0V4cG9ydFNwZWNpZmllcic6XG4gICAgICAgICAgICBpZiAoIW4uc291cmNlKSB7XG4gICAgICAgICAgICAgIG0ubmFtZXNwYWNlLnNldChzLmV4cG9ydGVkLm5hbWUsIGFkZE5hbWVzcGFjZShleHBvcnRNZXRhLCBzLmxvY2FsKSlcbiAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBlbHNlIGZhbGxzIHRocm91Z2hcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgbG9jYWwgPSBzLmxvY2FsLm5hbWVcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cblxuICAgICAgICAvLyB0b2RvOiBKU0RvY1xuICAgICAgICBtLnJlZXhwb3J0cy5zZXQocy5leHBvcnRlZC5uYW1lLCB7IGxvY2FsLCBnZXRJbXBvcnQ6ICgpID0+IHJlc29sdmVJbXBvcnQobikgfSlcbiAgICAgIH0pXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBtXG59XG5cblxuLyoqXG4gKiBUcmF2ZXJzZSBhIHBhdHRlcm4vaWRlbnRpZmllciBub2RlLCBjYWxsaW5nICdjYWxsYmFjaydcbiAqIGZvciBlYWNoIGxlYWYgaWRlbnRpZmllci5cbiAqIEBwYXJhbSAge25vZGV9ICAgcGF0dGVyblxuICogQHBhcmFtICB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjdXJzaXZlUGF0dGVybkNhcHR1cmUocGF0dGVybiwgY2FsbGJhY2spIHtcbiAgc3dpdGNoIChwYXR0ZXJuLnR5cGUpIHtcbiAgICBjYXNlICdJZGVudGlmaWVyJzogLy8gYmFzZSBjYXNlXG4gICAgICBjYWxsYmFjayhwYXR0ZXJuKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ09iamVjdFBhdHRlcm4nOlxuICAgICAgcGF0dGVybi5wcm9wZXJ0aWVzLmZvckVhY2gocCA9PiB7XG4gICAgICAgIHJlY3Vyc2l2ZVBhdHRlcm5DYXB0dXJlKHAudmFsdWUsIGNhbGxiYWNrKVxuICAgICAgfSlcbiAgICAgIGJyZWFrXG5cbiAgICBjYXNlICdBcnJheVBhdHRlcm4nOlxuICAgICAgcGF0dGVybi5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgIGlmIChlbGVtZW50ID09IG51bGwpIHJldHVyblxuICAgICAgICByZWN1cnNpdmVQYXR0ZXJuQ2FwdHVyZShlbGVtZW50LCBjYWxsYmFjaylcbiAgICAgIH0pXG4gICAgICBicmVha1xuICB9XG59XG4iXX0=
|