@tricoteuses/arbre-de-la-loi
Version:
Generate ASTs from the French bills & laws; manipulate & export them to Markdown, etc.
377 lines (288 loc) • 30.6 kB
JavaScript
;
require("core-js/modules/es.array.slice.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.function.name.js");
require("core-js/modules/es.array.from.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/es.symbol.js");
require("core-js/modules/es.symbol.description.js");
require("core-js/modules/es.symbol.iterator.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.array.is-array.js");
require("core-js/modules/es.promise.js");
require("regenerator-runtime/runtime.js");
require("core-js/modules/es.array.join.js");
require("core-js/modules/es.array.sort.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.object.values.js");
require("core-js/modules/es.string.starts-with.js");
var _assemblee = require("@tricoteuses/assemblee");
var _loaders = require("@tricoteuses/assemblee/lib/loaders");
var _assert = _interopRequireDefault(require("assert"));
var _child_process = require("child_process");
var _commandLineArgs = _interopRequireDefault(require("command-line-args"));
var _fsExtra = _interopRequireDefault(require("fs-extra"));
var _hastUtilFromParse = _interopRequireDefault(require("hast-util-from-parse5"));
var _parse = _interopRequireDefault(require("parse5"));
var _path = _interopRequireDefault(require("path"));
var _unistUtilRemovePosition = _interopRequireDefault(require("unist-util-remove-position"));
var _vfile = _interopRequireDefault(require("vfile"));
var _assemblee_html_parser = require("../assemblee_html_parser");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var optionsDefinitions = [{
alias: "c",
help: "commit documents",
name: "commit",
type: Boolean
}, {
alias: "l",
defaultValue: "15",
name: "legislature",
type: String
}, {
alias: "o",
help: "convert only one document",
name: "one",
type: Boolean
}, {
alias: "r",
help: "push commit to given remote",
multiple: true,
name: "remote",
type: String
}, {
alias: "s",
help: "don't log anything",
name: "silent",
type: Boolean
}, {
alias: "u",
help: "UID of first Assembl\xE9e's \"texte de loi\" to retrieve",
name: "uid",
type: String
}, {
alias: "v",
help: "verbose logs",
name: "verbose",
type: Boolean
}, {
defaultOption: true,
help: "directory containing Assemblée open data files",
name: "dataDir",
type: String
}];
var options = (0, _commandLineArgs["default"])(optionsDefinitions);
function commitAndPush(repositoryDir, commit, remotes) {
var error = false;
if (commit) {
(0, _child_process.execSync)("git add .", {
cwd: repositoryDir,
env: process.env,
encoding: "utf-8",
stdio: ["ignore", "ignore", "pipe"]
});
try {
(0, _child_process.execSync)('git commit -m "Nouvelle moisson"', {
cwd: repositoryDir,
env: process.env,
encoding: "utf-8"
});
} catch (childProcess) {
if (childProcess.stderr === null || !/nothing to commit/.test(childProcess.stdout)) {
console.error(childProcess.output);
throw childProcess;
}
}
var _iterator = _createForOfIteratorHelper(remotes || []),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var remote = _step.value;
try {
(0, _child_process.execSync)("git push ".concat(remote, " master"), {
cwd: repositoryDir,
env: process.env,
encoding: "utf-8",
stdio: ["ignore", "ignore", "pipe"]
});
} catch (childProcess) {
// Don't stop when push fails.
console.error(childProcess.output);
error = true;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
return error;
}
function convertTextesLois() {
return _convertTextesLois.apply(this, arguments);
}
function _convertTextesLois() {
_convertTextesLois = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var dataDir, _loadAssembleeData, documentByUid, documentsCleanHtmlDir, documentsJsonDir, _iterator2, _step2, filename, textesLois, firstUid, skip, _iterator3, _step3, texteLoi, texteLoiCleanHtmlBasename, texteLoiCleanHtmlFilePath, texteLoiCleanHtml, texteLoiParse5Ast, texteLoiVfile, textLoiHast, documents, texteLoiJsonBasename, texteLoiJsonHtmlFilePath;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
(0, _assert["default"])(!options.commit || options.one, 'Options "commit" & "one" are incompatible');
(0, _assert["default"])(!options.commit || options.uid, 'Options "commit" & "uid" are incompatible');
dataDir = options.dataDir;
_loadAssembleeData = (0, _loaders.loadAssembleeData)(dataDir, _loaders.EnabledDatasets.DossiersLegislatifs, options.legislature), documentByUid = _loadAssembleeData.documentByUid;
documentsCleanHtmlDir = _path["default"].join(dataDir, "documents_html_nettoye");
(0, _assert["default"])(_fsExtra["default"].existsSync(documentsCleanHtmlDir), "Directory \"".concat(documentsCleanHtmlDir, "\" doesn't exist"));
documentsJsonDir = _path["default"].join(dataDir, "textes_lois_json");
_fsExtra["default"].ensureDirSync(documentsJsonDir);
if (!(!options.one && !options.uid)) {
_context.next = 27;
break;
}
_iterator2 = _createForOfIteratorHelper(_fsExtra["default"].readdirSync(documentsJsonDir));
_context.prev = 10;
_iterator2.s();
case 12:
if ((_step2 = _iterator2.n()).done) {
_context.next = 19;
break;
}
filename = _step2.value;
if (!(filename[0] === ".")) {
_context.next = 16;
break;
}
return _context.abrupt("continue", 17);
case 16:
_fsExtra["default"].removeSync(_path["default"].join(documentsJsonDir, filename));
case 17:
_context.next = 12;
break;
case 19:
_context.next = 24;
break;
case 21:
_context.prev = 21;
_context.t0 = _context["catch"](10);
_iterator2.e(_context.t0);
case 24:
_context.prev = 24;
_iterator2.f();
return _context.finish(24);
case 27:
textesLois = Object.values(documentByUid).filter(function (texteLoi) {
return texteLoi.xsiType === _assemblee.TypeDocument.TexteLoiType;
}) // Ignore "textes de lois" from Sénat.
.filter(function (texteLoi) {
return texteLoi.uid.substring(4, 6) !== "SN";
}) // Keep only "lettres rectificatives", "projets de lois" et "propositions de lois".
.filter(function (texteLoi) {
return texteLoi.uid.startsWith("LETT") || texteLoi.uid.startsWith("PION") || texteLoi.uid.startsWith("PRJL");
}).sort(function (a, b) {
return a.uid.localeCompare(b.uid);
});
firstUid = options.uid;
skip = !!firstUid;
_iterator3 = _createForOfIteratorHelper(textesLois);
_context.prev = 31;
_iterator3.s();
case 33:
if ((_step3 = _iterator3.n()).done) {
_context.next = 59;
break;
}
texteLoi = _step3.value;
if (!skip) {
_context.next = 41;
break;
}
if (!(texteLoi.uid === firstUid)) {
_context.next = 40;
break;
}
skip = false;
_context.next = 41;
break;
case 40:
return _context.abrupt("continue", 57);
case 41:
texteLoiCleanHtmlBasename = (0, _loaders.pathFromDocumentUid)(documentsCleanHtmlDir, texteLoi.uid);
texteLoiCleanHtmlFilePath = "".concat(texteLoiCleanHtmlBasename, ".html");
if (_fsExtra["default"].existsSync(texteLoiCleanHtmlFilePath)) {
_context.next = 45;
break;
}
return _context.abrupt("continue", 57);
case 45:
if (!options.silent) {
console.log("Converting bill ".concat(texteLoi.uid, "\u2026"));
}
texteLoiCleanHtml = _fsExtra["default"].readFileSync(texteLoiCleanHtmlFilePath, {
encoding: "utf8"
});
texteLoiParse5Ast = _parse["default"].parse(texteLoiCleanHtml, {
sourceCodeLocationInfo: true
});
texteLoiVfile = (0, _vfile["default"])({
contents: texteLoiCleanHtml,
path: texteLoiCleanHtmlFilePath
});
textLoiHast = (0, _hastUtilFromParse["default"])(texteLoiParse5Ast, {
file: texteLoiVfile
});
documents = (0, _assemblee_html_parser.documentsFromAssembleeHast)(textLoiHast, {
silent: options.silent,
verbose: options.verbose
});
(0, _unistUtilRemovePosition["default"])(textLoiHast);
texteLoiJsonBasename = (0, _loaders.pathFromDocumentUid)(documentsJsonDir, texteLoi.uid);
texteLoiJsonHtmlFilePath = "".concat(texteLoiJsonBasename, ".json");
_fsExtra["default"].writeJsonSync(texteLoiJsonHtmlFilePath, documents, {
encoding: "utf8",
spaces: 2
});
if (!options.one) {
_context.next = 57;
break;
}
return _context.abrupt("break", 59);
case 57:
_context.next = 33;
break;
case 59:
_context.next = 64;
break;
case 61:
_context.prev = 61;
_context.t1 = _context["catch"](31);
_iterator3.e(_context.t1);
case 64:
_context.prev = 64;
_iterator3.f();
return _context.finish(64);
case 67:
if (commitAndPush(documentsJsonDir, options.commit, options.remote)) {
process.exit(1);
}
case 68:
case "end":
return _context.stop();
}
}
}, _callee, null, [[10, 21, 24, 27], [31, 61, 64, 67]]);
}));
return _convertTextesLois.apply(this, arguments);
}
convertTextesLois()["catch"](function (error) {
console.log(error);
process.exit(1);
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JpcHRzL2NvbnZlcnRfYXNzZW1ibGVlX3RleHRlc19sb2lzX3RvX2JpbGxzLnRzIl0sIm5hbWVzIjpbIm9wdGlvbnNEZWZpbml0aW9ucyIsImFsaWFzIiwiaGVscCIsIm5hbWUiLCJ0eXBlIiwiQm9vbGVhbiIsImRlZmF1bHRWYWx1ZSIsIlN0cmluZyIsIm11bHRpcGxlIiwiZGVmYXVsdE9wdGlvbiIsIm9wdGlvbnMiLCJjb21taXRBbmRQdXNoIiwicmVwb3NpdG9yeURpciIsImNvbW1pdCIsInJlbW90ZXMiLCJlcnJvciIsImN3ZCIsImVudiIsInByb2Nlc3MiLCJlbmNvZGluZyIsInN0ZGlvIiwiY2hpbGRQcm9jZXNzIiwic3RkZXJyIiwidGVzdCIsInN0ZG91dCIsImNvbnNvbGUiLCJvdXRwdXQiLCJyZW1vdGUiLCJjb252ZXJ0VGV4dGVzTG9pcyIsIm9uZSIsInVpZCIsImRhdGFEaXIiLCJFbmFibGVkRGF0YXNldHMiLCJEb3NzaWVyc0xlZ2lzbGF0aWZzIiwibGVnaXNsYXR1cmUiLCJkb2N1bWVudEJ5VWlkIiwiZG9jdW1lbnRzQ2xlYW5IdG1sRGlyIiwicGF0aCIsImpvaW4iLCJmcyIsImV4aXN0c1N5bmMiLCJkb2N1bWVudHNKc29uRGlyIiwiZW5zdXJlRGlyU3luYyIsInJlYWRkaXJTeW5jIiwiZmlsZW5hbWUiLCJyZW1vdmVTeW5jIiwidGV4dGVzTG9pcyIsIk9iamVjdCIsInZhbHVlcyIsImZpbHRlciIsInRleHRlTG9pIiwieHNpVHlwZSIsIlR5cGVEb2N1bWVudCIsIlRleHRlTG9pVHlwZSIsInN1YnN0cmluZyIsInN0YXJ0c1dpdGgiLCJzb3J0IiwiYSIsImIiLCJsb2NhbGVDb21wYXJlIiwiZmlyc3RVaWQiLCJza2lwIiwidGV4dGVMb2lDbGVhbkh0bWxCYXNlbmFtZSIsInRleHRlTG9pQ2xlYW5IdG1sRmlsZVBhdGgiLCJzaWxlbnQiLCJsb2ciLCJ0ZXh0ZUxvaUNsZWFuSHRtbCIsInJlYWRGaWxlU3luYyIsInRleHRlTG9pUGFyc2U1QXN0IiwicGFyc2U1IiwicGFyc2UiLCJzb3VyY2VDb2RlTG9jYXRpb25JbmZvIiwidGV4dGVMb2lWZmlsZSIsImNvbnRlbnRzIiwidGV4dExvaUhhc3QiLCJmaWxlIiwiZG9jdW1lbnRzIiwidmVyYm9zZSIsInRleHRlTG9pSnNvbkJhc2VuYW1lIiwidGV4dGVMb2lKc29uSHRtbEZpbGVQYXRoIiwid3JpdGVKc29uU3luYyIsInNwYWNlcyIsImV4aXQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7Ozs7Ozs7Ozs7Ozs7O0FBR0EsSUFBTUEsa0JBQWtCLEdBQUcsQ0FDekI7QUFDRUMsRUFBQUEsS0FBSyxFQUFFLEdBRFQ7QUFFRUMsRUFBQUEsSUFBSSxFQUFFLGtCQUZSO0FBR0VDLEVBQUFBLElBQUksRUFBRSxRQUhSO0FBSUVDLEVBQUFBLElBQUksRUFBRUM7QUFKUixDQUR5QixFQU96QjtBQUNFSixFQUFBQSxLQUFLLEVBQUUsR0FEVDtBQUVFSyxFQUFBQSxZQUFZLEVBQUUsSUFGaEI7QUFHRUgsRUFBQUEsSUFBSSxFQUFFLGFBSFI7QUFJRUMsRUFBQUEsSUFBSSxFQUFFRztBQUpSLENBUHlCLEVBYXpCO0FBQ0VOLEVBQUFBLEtBQUssRUFBRSxHQURUO0FBRUVDLEVBQUFBLElBQUksRUFBRSwyQkFGUjtBQUdFQyxFQUFBQSxJQUFJLEVBQUUsS0FIUjtBQUlFQyxFQUFBQSxJQUFJLEVBQUVDO0FBSlIsQ0FieUIsRUFtQnpCO0FBQ0VKLEVBQUFBLEtBQUssRUFBRSxHQURUO0FBRUVDLEVBQUFBLElBQUksRUFBRSw2QkFGUjtBQUdFTSxFQUFBQSxRQUFRLEVBQUUsSUFIWjtBQUlFTCxFQUFBQSxJQUFJLEVBQUUsUUFKUjtBQUtFQyxFQUFBQSxJQUFJLEVBQUVHO0FBTFIsQ0FuQnlCLEVBMEJ6QjtBQUNFTixFQUFBQSxLQUFLLEVBQUUsR0FEVDtBQUVFQyxFQUFBQSxJQUFJLEVBQUUsb0JBRlI7QUFHRUMsRUFBQUEsSUFBSSxFQUFFLFFBSFI7QUFJRUMsRUFBQUEsSUFBSSxFQUFFQztBQUpSLENBMUJ5QixFQWdDekI7QUFDRUosRUFBQUEsS0FBSyxFQUFFLEdBRFQ7QUFFRUMsRUFBQUEsSUFBSSw0REFGTjtBQUdFQyxFQUFBQSxJQUFJLEVBQUUsS0FIUjtBQUlFQyxFQUFBQSxJQUFJLEVBQUVHO0FBSlIsQ0FoQ3lCLEVBc0N6QjtBQUNFTixFQUFBQSxLQUFLLEVBQUUsR0FEVDtBQUVFQyxFQUFBQSxJQUFJLEVBQUUsY0FGUjtBQUdFQyxFQUFBQSxJQUFJLEVBQUUsU0FIUjtBQUlFQyxFQUFBQSxJQUFJLEVBQUVDO0FBSlIsQ0F0Q3lCLEVBNEN6QjtBQUNFSSxFQUFBQSxhQUFhLEVBQUUsSUFEakI7QUFFRVAsRUFBQUEsSUFBSSxFQUFFLGdEQUZSO0FBR0VDLEVBQUFBLElBQUksRUFBRSxTQUhSO0FBSUVDLEVBQUFBLElBQUksRUFBRUc7QUFKUixDQTVDeUIsQ0FBM0I7QUFtREEsSUFBTUcsT0FBTyxHQUFHLGlDQUFnQlYsa0JBQWhCLENBQWhCOztBQUVBLFNBQVNXLGFBQVQsQ0FDRUMsYUFERixFQUVFQyxNQUZGLEVBR0VDLE9BSEYsRUFJVztBQUNULE1BQUlDLEtBQUssR0FBRyxLQUFaOztBQUNBLE1BQUlGLE1BQUosRUFBWTtBQUNWLGlDQUFTLFdBQVQsRUFBc0I7QUFDcEJHLE1BQUFBLEdBQUcsRUFBRUosYUFEZTtBQUVwQkssTUFBQUEsR0FBRyxFQUFFQyxPQUFPLENBQUNELEdBRk87QUFHcEJFLE1BQUFBLFFBQVEsRUFBRSxPQUhVO0FBSXBCQyxNQUFBQSxLQUFLLEVBQUUsQ0FBQyxRQUFELEVBQVcsUUFBWCxFQUFxQixNQUFyQjtBQUphLEtBQXRCOztBQU1BLFFBQUk7QUFDRixtQ0FBUyxrQ0FBVCxFQUE2QztBQUMzQ0osUUFBQUEsR0FBRyxFQUFFSixhQURzQztBQUUzQ0ssUUFBQUEsR0FBRyxFQUFFQyxPQUFPLENBQUNELEdBRjhCO0FBRzNDRSxRQUFBQSxRQUFRLEVBQUU7QUFIaUMsT0FBN0M7QUFLRCxLQU5ELENBTUUsT0FBT0UsWUFBUCxFQUFxQjtBQUNyQixVQUNFQSxZQUFZLENBQUNDLE1BQWIsS0FBd0IsSUFBeEIsSUFDQSxDQUFDLG9CQUFvQkMsSUFBcEIsQ0FBeUJGLFlBQVksQ0FBQ0csTUFBdEMsQ0FGSCxFQUdFO0FBQ0FDLFFBQUFBLE9BQU8sQ0FBQ1YsS0FBUixDQUFjTSxZQUFZLENBQUNLLE1BQTNCO0FBQ0EsY0FBTUwsWUFBTjtBQUNEO0FBQ0Y7O0FBckJTLCtDQXNCV1AsT0FBTyxJQUFJLEVBdEJ0QjtBQUFBOztBQUFBO0FBc0JWLDBEQUFvQztBQUFBLFlBQXpCYSxNQUF5Qjs7QUFDbEMsWUFBSTtBQUNGLDBEQUFxQkEsTUFBckIsY0FBc0M7QUFDcENYLFlBQUFBLEdBQUcsRUFBRUosYUFEK0I7QUFFcENLLFlBQUFBLEdBQUcsRUFBRUMsT0FBTyxDQUFDRCxHQUZ1QjtBQUdwQ0UsWUFBQUEsUUFBUSxFQUFFLE9BSDBCO0FBSXBDQyxZQUFBQSxLQUFLLEVBQUUsQ0FBQyxRQUFELEVBQVcsUUFBWCxFQUFxQixNQUFyQjtBQUo2QixXQUF0QztBQU1ELFNBUEQsQ0FPRSxPQUFPQyxZQUFQLEVBQXFCO0FBQ3JCO0FBQ0FJLFVBQUFBLE9BQU8sQ0FBQ1YsS0FBUixDQUFjTSxZQUFZLENBQUNLLE1BQTNCO0FBQ0FYLFVBQUFBLEtBQUssR0FBRyxJQUFSO0FBQ0Q7QUFDRjtBQW5DUztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBb0NYOztBQUNELFNBQU9BLEtBQVA7QUFDRDs7U0FFY2EsaUI7Ozs7OytFQUFmO0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDRSxvQ0FDRSxDQUFDbEIsT0FBTyxDQUFDRyxNQUFULElBQW1CSCxPQUFPLENBQUNtQixHQUQ3QixFQUVFLDJDQUZGO0FBSUEsb0NBQ0UsQ0FBQ25CLE9BQU8sQ0FBQ0csTUFBVCxJQUFtQkgsT0FBTyxDQUFDb0IsR0FEN0IsRUFFRSwyQ0FGRjtBQUtNQyxZQUFBQSxPQVZSLEdBVWtCckIsT0FBTyxDQUFDcUIsT0FWMUI7QUFBQSxpQ0FXNEIsZ0NBQ3hCQSxPQUR3QixFQUV4QkMseUJBQWdCQyxtQkFGUSxFQUd4QnZCLE9BQU8sQ0FBQ3dCLFdBSGdCLENBWDVCLEVBV1VDLGFBWFYsc0JBV1VBLGFBWFY7QUFpQlFDLFlBQUFBLHFCQWpCUixHQWlCZ0NDLGlCQUFLQyxJQUFMLENBQVVQLE9BQVYsRUFBbUIsd0JBQW5CLENBakJoQztBQWtCRSxvQ0FDRVEsb0JBQUdDLFVBQUgsQ0FBY0oscUJBQWQsQ0FERix3QkFFZ0JBLHFCQUZoQjtBQUtNSyxZQUFBQSxnQkF2QlIsR0F1QjJCSixpQkFBS0MsSUFBTCxDQUFVUCxPQUFWLEVBQW1CLGtCQUFuQixDQXZCM0I7O0FBd0JFUSxnQ0FBR0csYUFBSCxDQUFpQkQsZ0JBQWpCOztBQXhCRixrQkF5Qk0sQ0FBQy9CLE9BQU8sQ0FBQ21CLEdBQVQsSUFBZ0IsQ0FBQ25CLE9BQU8sQ0FBQ29CLEdBekIvQjtBQUFBO0FBQUE7QUFBQTs7QUFBQSxvREEwQjJCUyxvQkFBR0ksV0FBSCxDQUFlRixnQkFBZixDQTFCM0I7QUFBQTs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQTBCZUcsWUFBQUEsUUExQmY7O0FBQUEsa0JBMkJVQSxRQUFRLENBQUMsQ0FBRCxDQUFSLEtBQWdCLEdBM0IxQjtBQUFBO0FBQUE7QUFBQTs7QUFBQTs7QUFBQTtBQThCTUwsZ0NBQUdNLFVBQUgsQ0FBY1IsaUJBQUtDLElBQUwsQ0FBVUcsZ0JBQVYsRUFBNEJHLFFBQTVCLENBQWQ7O0FBOUJOO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUE7O0FBQUE7QUFBQTtBQUFBOztBQUFBOztBQUFBO0FBQUE7O0FBQUE7O0FBQUE7O0FBQUE7QUFrQ1FFLFlBQUFBLFVBbENSLEdBa0NxQkMsTUFBTSxDQUFDQyxNQUFQLENBQWNiLGFBQWQsRUFDaEJjLE1BRGdCLENBQ1QsVUFBQ0MsUUFBRDtBQUFBLHFCQUFjQSxRQUFRLENBQUNDLE9BQVQsS0FBcUJDLHdCQUFhQyxZQUFoRDtBQUFBLGFBRFMsRUFFakI7QUFGaUIsYUFHaEJKLE1BSGdCLENBR1QsVUFBQ0MsUUFBRDtBQUFBLHFCQUFjQSxRQUFRLENBQUNwQixHQUFULENBQWF3QixTQUFiLENBQXVCLENBQXZCLEVBQTBCLENBQTFCLE1BQWlDLElBQS9DO0FBQUEsYUFIUyxFQUlqQjtBQUppQixhQUtoQkwsTUFMZ0IsQ0FNZixVQUFDQyxRQUFEO0FBQUEscUJBQ0VBLFFBQVEsQ0FBQ3BCLEdBQVQsQ0FBYXlCLFVBQWIsQ0FBd0IsTUFBeEIsS0FDQUwsUUFBUSxDQUFDcEIsR0FBVCxDQUFheUIsVUFBYixDQUF3QixNQUF4QixDQURBLElBRUFMLFFBQVEsQ0FBQ3BCLEdBQVQsQ0FBYXlCLFVBQWIsQ0FBd0IsTUFBeEIsQ0FIRjtBQUFBLGFBTmUsRUFXaEJDLElBWGdCLENBV1gsVUFBQ0MsQ0FBRCxFQUFJQyxDQUFKO0FBQUEscUJBQVVELENBQUMsQ0FBQzNCLEdBQUYsQ0FBTTZCLGFBQU4sQ0FBb0JELENBQUMsQ0FBQzVCLEdBQXRCLENBQVY7QUFBQSxhQVhXLENBbENyQjtBQStDUThCLFlBQUFBLFFBL0NSLEdBK0NtQmxELE9BQU8sQ0FBQ29CLEdBL0MzQjtBQWdETStCLFlBQUFBLElBaEROLEdBZ0RhLENBQUMsQ0FBQ0QsUUFoRGY7QUFBQSxvREFpRHlCZCxVQWpEekI7QUFBQTs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQWlEYUksWUFBQUEsUUFqRGI7O0FBQUEsaUJBa0RRVyxJQWxEUjtBQUFBO0FBQUE7QUFBQTs7QUFBQSxrQkFtRFVYLFFBQVEsQ0FBQ3BCLEdBQVQsS0FBaUI4QixRQW5EM0I7QUFBQTtBQUFBO0FBQUE7O0FBb0RRQyxZQUFBQSxJQUFJLEdBQUcsS0FBUDtBQXBEUjtBQUFBOztBQUFBO0FBQUE7O0FBQUE7QUEwRFVDLFlBQUFBLHlCQTFEVixHQTBEc0Msa0NBQ2hDMUIscUJBRGdDLEVBRWhDYyxRQUFRLENBQUNwQixHQUZ1QixDQTFEdEM7QUE4RFVpQyxZQUFBQSx5QkE5RFYsYUE4RHlDRCx5QkE5RHpDOztBQUFBLGdCQStEU3ZCLG9CQUFHQyxVQUFILENBQWN1Qix5QkFBZCxDQS9EVDtBQUFBO0FBQUE7QUFBQTs7QUFBQTs7QUFBQTtBQW1FSSxnQkFBSSxDQUFDckQsT0FBTyxDQUFDc0QsTUFBYixFQUFxQjtBQUNuQnZDLGNBQUFBLE9BQU8sQ0FBQ3dDLEdBQVIsMkJBQStCZixRQUFRLENBQUNwQixHQUF4QztBQUNEOztBQUVLb0MsWUFBQUEsaUJBdkVWLEdBdUU4QjNCLG9CQUFHNEIsWUFBSCxDQUFnQkoseUJBQWhCLEVBQTJDO0FBQ25FNUMsY0FBQUEsUUFBUSxFQUFFO0FBRHlELGFBQTNDLENBdkU5QjtBQTBFVWlELFlBQUFBLGlCQTFFVixHQTBFOEJDLGtCQUFPQyxLQUFQLENBQWFKLGlCQUFiLEVBQWdDO0FBQ3hESyxjQUFBQSxzQkFBc0IsRUFBRTtBQURnQyxhQUFoQyxDQTFFOUI7QUE2RVVDLFlBQUFBLGFBN0VWLEdBNkUwQix1QkFBTTtBQUMxQkMsY0FBQUEsUUFBUSxFQUFFUCxpQkFEZ0I7QUFFMUI3QixjQUFBQSxJQUFJLEVBQUUwQjtBQUZvQixhQUFOLENBN0UxQjtBQWlGVVcsWUFBQUEsV0FqRlYsR0FpRnlCLG1DQUFlTixpQkFBZixFQUFrQztBQUNyRE8sY0FBQUEsSUFBSSxFQUFFSDtBQUQrQyxhQUFsQyxDQWpGekI7QUFvRlVJLFlBQUFBLFNBcEZWLEdBb0ZzQix1REFBMkJGLFdBQTNCLEVBQXdDO0FBQ3hEVixjQUFBQSxNQUFNLEVBQUV0RCxPQUFPLENBQUNzRCxNQUR3QztBQUV4RGEsY0FBQUEsT0FBTyxFQUFFbkUsT0FBTyxDQUFDbUU7QUFGdUMsYUFBeEMsQ0FwRnRCO0FBd0ZJLHFEQUFvQkgsV0FBcEI7QUFFTUksWUFBQUEsb0JBMUZWLEdBMEZpQyxrQ0FDM0JyQyxnQkFEMkIsRUFFM0JTLFFBQVEsQ0FBQ3BCLEdBRmtCLENBMUZqQztBQThGVWlELFlBQUFBLHdCQTlGVixhQThGd0NELG9CQTlGeEM7O0FBK0ZJdkMsZ0NBQUd5QyxhQUFILENBQWlCRCx3QkFBakIsRUFBMkNILFNBQTNDLEVBQXNEO0FBQ3BEekQsY0FBQUEsUUFBUSxFQUFFLE1BRDBDO0FBRXBEOEQsY0FBQUEsTUFBTSxFQUFFO0FBRjRDLGFBQXREOztBQS9GSixpQkFvR1F2RSxPQUFPLENBQUNtQixHQXBHaEI7QUFBQTtBQUFBO0FBQUE7O0FBQUE7O0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQUFBO0FBQUE7O0FBQUE7O0FBQUE7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQTtBQXlHRSxnQkFBSWxCLGFBQWEsQ0FBQzhCLGdCQUFELEVBQW1CL0IsT0FBTyxDQUFDRyxNQUEzQixFQUFtQ0gsT0FBTyxDQUFDaUIsTUFBM0MsQ0FBakIsRUFBcUU7QUFDbkVULGNBQUFBLE9BQU8sQ0FBQ2dFLElBQVIsQ0FBYSxDQUFiO0FBQ0Q7O0FBM0dIO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEc7Ozs7QUE4R0F0RCxpQkFBaUIsV0FBakIsQ0FBMEIsVUFBQ2IsS0FBRCxFQUFXO0FBQ25DVSxFQUFBQSxPQUFPLENBQUN3QyxHQUFSLENBQVlsRCxLQUFaO0FBQ0FHLEVBQUFBLE9BQU8sQ0FBQ2dFLElBQVIsQ0FBYSxDQUFiO0FBQ0QsQ0FIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFR5cGVEb2N1bWVudCB9IGZyb20gXCJAdHJpY290ZXVzZXMvYXNzZW1ibGVlXCJcbmltcG9ydCB7XG4gIEVuYWJsZWREYXRhc2V0cyxcbiAgbG9hZEFzc2VtYmxlZURhdGEsXG4gIHBhdGhGcm9tRG9jdW1lbnRVaWQsXG59IGZyb20gXCJAdHJpY290ZXVzZXMvYXNzZW1ibGVlL2xpYi9sb2FkZXJzXCJcbmltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiXG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCJcbmltcG9ydCBjb21tYW5kTGluZUFyZ3MgZnJvbSBcImNvbW1hbmQtbGluZS1hcmdzXCJcbmltcG9ydCBmcyBmcm9tIFwiZnMtZXh0cmFcIlxuaW1wb3J0IGhhc3RGcm9tUGFyc2U1IGZyb20gXCJoYXN0LXV0aWwtZnJvbS1wYXJzZTVcIlxuaW1wb3J0IHBhcnNlNSBmcm9tIFwicGFyc2U1XCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB1bmlzdFJlbW92ZVBvc2l0aW9uIGZyb20gXCJ1bmlzdC11dGlsLXJlbW92ZS1wb3NpdGlvblwiXG5pbXBvcnQgdmZpbGUgZnJvbSBcInZmaWxlXCJcblxuaW1wb3J0IHsgZG9jdW1lbnRzRnJvbUFzc2VtYmxlZUhhc3QgfSBmcm9tIFwiLi4vYXNzZW1ibGVlX2h0bWxfcGFyc2VyXCJcbmltcG9ydCB7IEhhc3RSb290IH0gZnJvbSBcIi4uL2hhc3RcIlxuXG5jb25zdCBvcHRpb25zRGVmaW5pdGlvbnMgPSBbXG4gIHtcbiAgICBhbGlhczogXCJjXCIsXG4gICAgaGVscDogXCJjb21taXQgZG9jdW1lbnRzXCIsXG4gICAgbmFtZTogXCJjb21taXRcIixcbiAgICB0eXBlOiBCb29sZWFuLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwibFwiLFxuICAgIGRlZmF1bHRWYWx1ZTogXCIxNVwiLFxuICAgIG5hbWU6IFwibGVnaXNsYXR1cmVcIixcbiAgICB0eXBlOiBTdHJpbmcsXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJvXCIsXG4gICAgaGVscDogXCJjb252ZXJ0IG9ubHkgb25lIGRvY3VtZW50XCIsXG4gICAgbmFtZTogXCJvbmVcIixcbiAgICB0eXBlOiBCb29sZWFuLFxuICB9LFxuICB7XG4gICAgYWxpYXM6IFwiclwiLFxuICAgIGhlbHA6IFwicHVzaCBjb21taXQgdG8gZ2l2ZW4gcmVtb3RlXCIsXG4gICAgbXVsdGlwbGU6IHRydWUsXG4gICAgbmFtZTogXCJyZW1vdGVcIixcbiAgICB0eXBlOiBTdHJpbmcsXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJzXCIsXG4gICAgaGVscDogXCJkb24ndCBsb2cgYW55dGhpbmdcIixcbiAgICBuYW1lOiBcInNpbGVudFwiLFxuICAgIHR5cGU6IEJvb2xlYW4sXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJ1XCIsXG4gICAgaGVscDogYFVJRCBvZiBmaXJzdCBBc3NlbWJsw6llJ3MgXCJ0ZXh0ZSBkZSBsb2lcIiB0byByZXRyaWV2ZWAsXG4gICAgbmFtZTogXCJ1aWRcIixcbiAgICB0eXBlOiBTdHJpbmcsXG4gIH0sXG4gIHtcbiAgICBhbGlhczogXCJ2XCIsXG4gICAgaGVscDogXCJ2ZXJib3NlIGxvZ3NcIixcbiAgICBuYW1lOiBcInZlcmJvc2VcIixcbiAgICB0eXBlOiBCb29sZWFuLFxuICB9LFxuICB7XG4gICAgZGVmYXVsdE9wdGlvbjogdHJ1ZSxcbiAgICBoZWxwOiBcImRpcmVjdG9yeSBjb250YWluaW5nIEFzc2VtYmzDqWUgb3BlbiBkYXRhIGZpbGVzXCIsXG4gICAgbmFtZTogXCJkYXRhRGlyXCIsXG4gICAgdHlwZTogU3RyaW5nLFxuICB9LFxuXVxuY29uc3Qgb3B0aW9ucyA9IGNvbW1hbmRMaW5lQXJncyhvcHRpb25zRGVmaW5pdGlvbnMpXG5cbmZ1bmN0aW9uIGNvbW1pdEFuZFB1c2goXG4gIHJlcG9zaXRvcnlEaXI6IHN0cmluZyxcbiAgY29tbWl0OiBib29sZWFuLFxuICByZW1vdGVzPzogc3RyaW5nW10sXG4pOiBib29sZWFuIHtcbiAgbGV0IGVycm9yID0gZmFsc2VcbiAgaWYgKGNvbW1pdCkge1xuICAgIGV4ZWNTeW5jKFwiZ2l0IGFkZCAuXCIsIHtcbiAgICAgIGN3ZDogcmVwb3NpdG9yeURpcixcbiAgICAgIGVudjogcHJvY2Vzcy5lbnYsXG4gICAgICBlbmNvZGluZzogXCJ1dGYtOFwiLFxuICAgICAgc3RkaW86IFtcImlnbm9yZVwiLCBcImlnbm9yZVwiLCBcInBpcGVcIl0sXG4gICAgfSlcbiAgICB0cnkge1xuICAgICAgZXhlY1N5bmMoJ2dpdCBjb21taXQgLW0gXCJOb3V2ZWxsZSBtb2lzc29uXCInLCB7XG4gICAgICAgIGN3ZDogcmVwb3NpdG9yeURpcixcbiAgICAgICAgZW52OiBwcm9jZXNzLmVudixcbiAgICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoY2hpbGRQcm9jZXNzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGNoaWxkUHJvY2Vzcy5zdGRlcnIgPT09IG51bGwgfHxcbiAgICAgICAgIS9ub3RoaW5nIHRvIGNvbW1pdC8udGVzdChjaGlsZFByb2Nlc3Muc3Rkb3V0KVxuICAgICAgKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hpbGRQcm9jZXNzLm91dHB1dClcbiAgICAgICAgdGhyb3cgY2hpbGRQcm9jZXNzXG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgcmVtb3RlIG9mIHJlbW90ZXMgfHwgW10pIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGV4ZWNTeW5jKGBnaXQgcHVzaCAke3JlbW90ZX0gbWFzdGVyYCwge1xuICAgICAgICAgIGN3ZDogcmVwb3NpdG9yeURpcixcbiAgICAgICAgICBlbnY6IHByb2Nlc3MuZW52LFxuICAgICAgICAgIGVuY29kaW5nOiBcInV0Zi04XCIsXG4gICAgICAgICAgc3RkaW86IFtcImlnbm9yZVwiLCBcImlnbm9yZVwiLCBcInBpcGVcIl0sXG4gICAgICAgIH0pXG4gICAgICB9IGNhdGNoIChjaGlsZFByb2Nlc3MpIHtcbiAgICAgICAgLy8gRG9uJ3Qgc3RvcCB3aGVuIHB1c2ggZmFpbHMuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hpbGRQcm9jZXNzLm91dHB1dClcbiAgICAgICAgZXJyb3IgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBlcnJvclxufVxuXG5hc3luYyBmdW5jdGlvbiBjb252ZXJ0VGV4dGVzTG9pcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXNzZXJ0KFxuICAgICFvcHRpb25zLmNvbW1pdCB8fCBvcHRpb25zLm9uZSxcbiAgICAnT3B0aW9ucyBcImNvbW1pdFwiICYgXCJvbmVcIiBhcmUgaW5jb21wYXRpYmxlJyxcbiAgKVxuICBhc3NlcnQoXG4gICAgIW9wdGlvbnMuY29tbWl0IHx8IG9wdGlvbnMudWlkLFxuICAgICdPcHRpb25zIFwiY29tbWl0XCIgJiBcInVpZFwiIGFyZSBpbmNvbXBhdGlibGUnLFxuICApXG5cbiAgY29uc3QgZGF0YURpciA9IG9wdGlvbnMuZGF0YURpclxuICBjb25zdCB7IGRvY3VtZW50QnlVaWQgfSA9IGxvYWRBc3NlbWJsZWVEYXRhKFxuICAgIGRhdGFEaXIsXG4gICAgRW5hYmxlZERhdGFzZXRzLkRvc3NpZXJzTGVnaXNsYXRpZnMsXG4gICAgb3B0aW9ucy5sZWdpc2xhdHVyZSxcbiAgKVxuXG4gIGNvbnN0IGRvY3VtZW50c0NsZWFuSHRtbERpciA9IHBhdGguam9pbihkYXRhRGlyLCBcImRvY3VtZW50c19odG1sX25ldHRveWVcIilcbiAgYXNzZXJ0KFxuICAgIGZzLmV4aXN0c1N5bmMoZG9jdW1lbnRzQ2xlYW5IdG1sRGlyKSxcbiAgICBgRGlyZWN0b3J5IFwiJHtkb2N1bWVudHNDbGVhbkh0bWxEaXJ9XCIgZG9lc24ndCBleGlzdGAsXG4gIClcblxuICBjb25zdCBkb2N1bWVudHNKc29uRGlyID0gcGF0aC5qb2luKGRhdGFEaXIsIFwidGV4dGVzX2xvaXNfanNvblwiKVxuICBmcy5lbnN1cmVEaXJTeW5jKGRvY3VtZW50c0pzb25EaXIpXG4gIGlmICghb3B0aW9ucy5vbmUgJiYgIW9wdGlvbnMudWlkKSB7XG4gICAgZm9yIChjb25zdCBmaWxlbmFtZSBvZiBmcy5yZWFkZGlyU3luYyhkb2N1bWVudHNKc29uRGlyKSkge1xuICAgICAgaWYgKGZpbGVuYW1lWzBdID09PSBcIi5cIikge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgZnMucmVtb3ZlU3luYyhwYXRoLmpvaW4oZG9jdW1lbnRzSnNvbkRpciwgZmlsZW5hbWUpKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHRleHRlc0xvaXMgPSBPYmplY3QudmFsdWVzKGRvY3VtZW50QnlVaWQpXG4gICAgLmZpbHRlcigodGV4dGVMb2kpID0+IHRleHRlTG9pLnhzaVR5cGUgPT09IFR5cGVEb2N1bWVudC5UZXh0ZUxvaVR5cGUpXG4gICAgLy8gSWdub3JlIFwidGV4dGVzIGRlIGxvaXNcIiBmcm9tIFPDqW5hdC5cbiAgICAuZmlsdGVyKCh0ZXh0ZUxvaSkgPT4gdGV4dGVMb2kudWlkLnN1YnN0cmluZyg0LCA2KSAhPT0gXCJTTlwiKVxuICAgIC8vIEtlZXAgb25seSBcImxldHRyZXMgcmVjdGlmaWNhdGl2ZXNcIiwgXCJwcm9qZXRzIGRlIGxvaXNcIiBldCBcInByb3Bvc2l0aW9ucyBkZSBsb2lzXCIuXG4gICAgLmZpbHRlcihcbiAgICAgICh0ZXh0ZUxvaSkgPT5cbiAgICAgICAgdGV4dGVMb2kudWlkLnN0YXJ0c1dpdGgoXCJMRVRUXCIpIHx8XG4gICAgICAgIHRleHRlTG9pLnVpZC5zdGFydHNXaXRoKFwiUElPTlwiKSB8fFxuICAgICAgICB0ZXh0ZUxvaS51aWQuc3RhcnRzV2l0aChcIlBSSkxcIiksXG4gICAgKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLnVpZC5sb2NhbGVDb21wYXJlKGIudWlkKSlcblxuICBjb25zdCBmaXJzdFVpZCA9IG9wdGlvbnMudWlkXG4gIGxldCBza2lwID0gISFmaXJzdFVpZFxuICBmb3IgKGNvbnN0IHRleHRlTG9pIG9mIHRleHRlc0xvaXMpIHtcbiAgICBpZiAoc2tpcCkge1xuICAgICAgaWYgKHRleHRlTG9pLnVpZCA9PT0gZmlyc3RVaWQpIHtcbiAgICAgICAgc2tpcCA9IGZhbHNlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRleHRlTG9pQ2xlYW5IdG1sQmFzZW5hbWUgPSBwYXRoRnJvbURvY3VtZW50VWlkKFxuICAgICAgZG9jdW1lbnRzQ2xlYW5IdG1sRGlyLFxuICAgICAgdGV4dGVMb2kudWlkLFxuICAgIClcbiAgICBjb25zdCB0ZXh0ZUxvaUNsZWFuSHRtbEZpbGVQYXRoID0gYCR7dGV4dGVMb2lDbGVhbkh0bWxCYXNlbmFtZX0uaHRtbGBcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmModGV4dGVMb2lDbGVhbkh0bWxGaWxlUGF0aCkpIHtcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgY29uc29sZS5sb2coYENvbnZlcnRpbmcgYmlsbCAke3RleHRlTG9pLnVpZH3igKZgKVxuICAgIH1cblxuICAgIGNvbnN0IHRleHRlTG9pQ2xlYW5IdG1sID0gZnMucmVhZEZpbGVTeW5jKHRleHRlTG9pQ2xlYW5IdG1sRmlsZVBhdGgsIHtcbiAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICB9KVxuICAgIGNvbnN0IHRleHRlTG9pUGFyc2U1QXN0ID0gcGFyc2U1LnBhcnNlKHRleHRlTG9pQ2xlYW5IdG1sLCB7XG4gICAgICBzb3VyY2VDb2RlTG9jYXRpb25JbmZvOiB0cnVlLFxuICAgIH0pXG4gICAgY29uc3QgdGV4dGVMb2lWZmlsZSA9IHZmaWxlKHtcbiAgICAgIGNvbnRlbnRzOiB0ZXh0ZUxvaUNsZWFuSHRtbCxcbiAgICAgIHBhdGg6IHRleHRlTG9pQ2xlYW5IdG1sRmlsZVBhdGgsXG4gICAgfSlcbiAgICBjb25zdCB0ZXh0TG9pSGFzdCA9IChoYXN0RnJvbVBhcnNlNSh0ZXh0ZUxvaVBhcnNlNUFzdCwge1xuICAgICAgZmlsZTogdGV4dGVMb2lWZmlsZSxcbiAgICB9KSBhcyB1bmtub3duKSBhcyBIYXN0Um9vdFxuICAgIGNvbnN0IGRvY3VtZW50cyA9IGRvY3VtZW50c0Zyb21Bc3NlbWJsZWVIYXN0KHRleHRMb2lIYXN0LCB7XG4gICAgICBzaWxlbnQ6IG9wdGlvbnMuc2lsZW50LFxuICAgICAgdmVyYm9zZTogb3B0aW9ucy52ZXJib3NlLFxuICAgIH0pXG4gICAgdW5pc3RSZW1vdmVQb3NpdGlvbih0ZXh0TG9pSGFzdClcblxuICAgIGNvbnN0IHRleHRlTG9pSnNvbkJhc2VuYW1lID0gcGF0aEZyb21Eb2N1bWVudFVpZChcbiAgICAgIGRvY3VtZW50c0pzb25EaXIsXG4gICAgICB0ZXh0ZUxvaS51aWQsXG4gICAgKVxuICAgIGNvbnN0IHRleHRlTG9pSnNvbkh0bWxGaWxlUGF0aCA9IGAke3RleHRlTG9pSnNvbkJhc2VuYW1lfS5qc29uYFxuICAgIGZzLndyaXRlSnNvblN5bmModGV4dGVMb2lKc29uSHRtbEZpbGVQYXRoLCBkb2N1bWVudHMsIHtcbiAgICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICAgIHNwYWNlczogMixcbiAgICB9KVxuXG4gICAgaWYgKG9wdGlvbnMub25lKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmIChjb21taXRBbmRQdXNoKGRvY3VtZW50c0pzb25EaXIsIG9wdGlvbnMuY29tbWl0LCBvcHRpb25zLnJlbW90ZSkpIHtcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxufVxuXG5jb252ZXJ0VGV4dGVzTG9pcygpLmNhdGNoKChlcnJvcikgPT4ge1xuICBjb25zb2xlLmxvZyhlcnJvcilcbiAgcHJvY2Vzcy5leGl0KDEpXG59KVxuIl19