'use strict'; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _minimatch = require('minimatch'); var _minimatch2 = _interopRequireDefault(_minimatch); var _importType = require('../core/importType'); var _importType2 = _interopRequireDefault(_importType); var _staticRequire = require('../core/staticRequire'); var _staticRequire2 = _interopRequireDefault(_staticRequire); var _docsUrl = require('../docsUrl'); var _docsUrl2 = _interopRequireDefault(_docsUrl); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const defaultGroups = ['builtin', 'external', 'parent', 'sibling', 'index']; // REPORTING AND FIXING function reverse(array) { return array.map(function (v) { return { name: v.name, rank: -v.rank, node: v.node }; }).reverse(); } function getTokensOrCommentsAfter(sourceCode, node, count) { let currentNodeOrToken = node; const result = []; for (let i = 0; i < count; i++) { currentNodeOrToken = sourceCode.getTokenOrCommentAfter(currentNodeOrToken); if (currentNodeOrToken == null) { break; } result.push(currentNodeOrToken); } return result; } function getTokensOrCommentsBefore(sourceCode, node, count) { let currentNodeOrToken = node; const result = []; for (let i = 0; i < count; i++) { currentNodeOrToken = sourceCode.getTokenOrCommentBefore(currentNodeOrToken); if (currentNodeOrToken == null) { break; } result.push(currentNodeOrToken); } return result.reverse(); } function takeTokensAfterWhile(sourceCode, node, condition) { const tokens = getTokensOrCommentsAfter(sourceCode, node, 100); const result = []; for (let i = 0; i < tokens.length; i++) { if (condition(tokens[i])) { result.push(tokens[i]); } else { break; } } return result; } function takeTokensBeforeWhile(sourceCode, node, condition) { const tokens = getTokensOrCommentsBefore(sourceCode, node, 100); const result = []; for (let i = tokens.length - 1; i >= 0; i--) { if (condition(tokens[i])) { result.push(tokens[i]); } else { break; } } return result.reverse(); } function findOutOfOrder(imported) { if (imported.length === 0) { return []; } let maxSeenRankNode = imported[0]; return imported.filter(function (importedModule) { const res = importedModule.rank < maxSeenRankNode.rank; if (maxSeenRankNode.rank < importedModule.rank) { maxSeenRankNode = importedModule; } return res; }); } function findRootNode(node) { let parent = node; while (parent.parent != null && parent.parent.body == null) { parent = parent.parent; } return parent; } function findEndOfLineWithComments(sourceCode, node) { const tokensToEndOfLine = takeTokensAfterWhile(sourceCode, node, commentOnSameLineAs(node)); let endOfTokens = tokensToEndOfLine.length > 0 ? tokensToEndOfLine[tokensToEndOfLine.length - 1].range[1] : node.range[1]; let result = endOfTokens; for (let i = endOfTokens; i < sourceCode.text.length; i++) { if (sourceCode.text[i] === '\n') { result = i + 1; break; } if (sourceCode.text[i] !== ' ' && sourceCode.text[i] !== '\t' && sourceCode.text[i] !== '\r') { break; } result = i + 1; } return result; } function commentOnSameLineAs(node) { return token => (token.type === 'Block' || token.type === 'Line') && token.loc.start.line === token.loc.end.line && token.loc.end.line === node.loc.end.line; } function findStartOfLineWithComments(sourceCode, node) { const tokensToEndOfLine = takeTokensBeforeWhile(sourceCode, node, commentOnSameLineAs(node)); let startOfTokens = tokensToEndOfLine.length > 0 ? tokensToEndOfLine[0].range[0] : node.range[0]; let result = startOfTokens; for (let i = startOfTokens - 1; i > 0; i--) { if (sourceCode.text[i] !== ' ' && sourceCode.text[i] !== '\t') { break; } result = i; } return result; } function isPlainRequireModule(node) { if (node.type !== 'VariableDeclaration') { return false; } if (node.declarations.length !== 1) { return false; } const decl = node.declarations[0]; const result = decl.id && (decl.id.type === 'Identifier' || decl.id.type === 'ObjectPattern') && decl.init != null && decl.init.type === 'CallExpression' && decl.init.callee != null && decl.init.callee.name === 'require' && decl.init.arguments != null && decl.init.arguments.length === 1 && decl.init.arguments[0].type === 'Literal'; return result; } function isPlainImportModule(node) { return node.type === 'ImportDeclaration' && node.specifiers != null && node.specifiers.length > 0; } function isPlainImportEquals(node) { return node.type === 'TSImportEqualsDeclaration' && node.moduleReference.expression; } function canCrossNodeWhileReorder(node) { return isPlainRequireModule(node) || isPlainImportModule(node) || isPlainImportEquals(node); } function canReorderItems(firstNode, secondNode) { const parent = firstNode.parent; var _sort = [parent.body.indexOf(firstNode), parent.body.indexOf(secondNode)].sort(), _sort2 = _slicedToArray(_sort, 2); const firstIndex = _sort2[0], secondIndex = _sort2[1]; const nodesBetween = parent.body.slice(firstIndex, secondIndex + 1); for (var nodeBetween of nodesBetween) { if (!canCrossNodeWhileReorder(nodeBetween)) { return false; } } return true; } function fixOutOfOrder(context, firstNode, secondNode, order) { const sourceCode = context.getSourceCode(); const firstRoot = findRootNode(firstNode.node); const firstRootStart = findStartOfLineWithComments(sourceCode, firstRoot); const firstRootEnd = findEndOfLineWithComments(sourceCode, firstRoot); const secondRoot = findRootNode(secondNode.node); const secondRootStart = findStartOfLineWithComments(sourceCode, secondRoot); const secondRootEnd = findEndOfLineWithComments(sourceCode, secondRoot); const canFix = canReorderItems(firstRoot, secondRoot); let newCode = sourceCode.text.substring(secondRootStart, secondRootEnd); if (newCode[newCode.length - 1] !== '\n') { newCode = newCode + '\n'; } const message = '`' + secondNode.name + '` import should occur ' + order + ' import of `' + firstNode.name + '`'; if (order === 'before') { context.report({ node: secondNode.node, message: message, fix: canFix && (fixer => fixer.replaceTextRange([firstRootStart, secondRootEnd], newCode + sourceCode.text.substring(firstRootStart, secondRootStart))) }); } else if (order === 'after') { context.report({ node: secondNode.node, message: message, fix: canFix && (fixer => fixer.replaceTextRange([secondRootStart, firstRootEnd], sourceCode.text.substring(secondRootEnd, firstRootEnd) + newCode)) }); } } function reportOutOfOrder(context, imported, outOfOrder, order) { outOfOrder.forEach(function (imp) { const found = imported.find(function hasHigherRank(importedItem) { return importedItem.rank > imp.rank; }); fixOutOfOrder(context, found, imp, order); }); } function makeOutOfOrderReport(context, imported) { const outOfOrder = findOutOfOrder(imported); if (!outOfOrder.length) { return; } // There are things to report. Try to minimize the number of reported errors. const reversedImported = reverse(imported); const reversedOrder = findOutOfOrder(reversedImported); if (reversedOrder.length < outOfOrder.length) { reportOutOfOrder(context, reversedImported, reversedOrder, 'after'); return; } reportOutOfOrder(context, imported, outOfOrder, 'before'); } function getSorter(ascending) { let multiplier = ascending ? 1 : -1; return function importsSorter(importA, importB) { let result; if (importA < importB || importB === null) { result = -1; } else if (importA > importB || importA === null) { result = 1; } else { result = 0; } return result * multiplier; }; } function mutateRanksToAlphabetize(imported, alphabetizeOptions) { const groupedByRanks = imported.reduce(function (acc, importedItem) { if (!Array.isArray(acc[importedItem.rank])) { acc[importedItem.rank] = []; } acc[importedItem.rank].push(importedItem.name); return acc; }, {}); const groupRanks = Object.keys(groupedByRanks); const sorterFn = getSorter(alphabetizeOptions.order === 'asc'); const comparator = alphabetizeOptions.caseInsensitive ? (a, b) => sorterFn(String(a).toLowerCase(), String(b).toLowerCase()) : (a, b) => sorterFn(a, b); // sort imports locally within their group groupRanks.forEach(function (groupRank) { groupedByRanks[groupRank].sort(comparator); }); // assign globally unique rank to each import let newRank = 0; const alphabetizedRanks = groupRanks.sort().reduce(function (acc, groupRank) { groupedByRanks[groupRank].forEach(function (importedItemName) { acc[importedItemName] = parseInt(groupRank, 10) + newRank; newRank += 1; }); return acc; }, {}); // mutate the original group-rank with alphabetized-rank imported.forEach(function (importedItem) { importedItem.rank = alphabetizedRanks[importedItem.name]; }); } // DETECTING function computePathRank(ranks, pathGroups, path, maxPosition) { for (let i = 0, l = pathGroups.length; i < l; i++) { var _pathGroups$i = pathGroups[i]; const pattern = _pathGroups$i.pattern, patternOptions = _pathGroups$i.patternOptions, group = _pathGroups$i.group; var _pathGroups$i$positio = _pathGroups$i.position; const position = _pathGroups$i$positio === undefined ? 1 : _pathGroups$i$positio; if ((0, _minimatch2.default)(path, pattern, patternOptions || { nocomment: true })) { return ranks[group] + position / maxPosition; } } } function computeRank(context, ranks, name, type, excludedImportTypes) { const impType = (0, _importType2.default)(name, context); let rank; if (!excludedImportTypes.has(impType)) { rank = computePathRank(ranks.groups, ranks.pathGroups, name, ranks.maxPosition); } if (typeof rank === 'undefined') { rank = ranks.groups[impType]; } if (type !== 'import') { rank += 100; } return rank; } function registerNode(context, node, name, type, ranks, imported, excludedImportTypes) { const rank = computeRank(context, ranks, name, type, excludedImportTypes); if (rank !== -1) { imported.push({ name, rank, node }); } } function isInVariableDeclarator(node) { return node && (node.type === 'VariableDeclarator' || isInVariableDeclarator(node.parent)); } const types = ['builtin', 'external', 'internal', 'unknown', 'parent', 'sibling', 'index']; // Creates an object with type-rank pairs. // Example: { index: 0, sibling: 1, parent: 1, external: 1, builtin: 2, internal: 2 } // Will throw an error if it contains a type that does not exist, or has a duplicate function convertGroupsToRanks(groups) { const rankObject = groups.reduce(function (res, group, index) { if (typeof group === 'string') { group = [group]; } group.forEach(function (groupItem) { if (types.indexOf(groupItem) === -1) { throw new Error('Incorrect configuration of the rule: Unknown type `' + JSON.stringify(groupItem) + '`'); } if (res[groupItem] !== undefined) { throw new Error('Incorrect configuration of the rule: `' + groupItem + '` is duplicated'); } res[groupItem] = index; }); return res; }, {}); const omittedTypes = types.filter(function (type) { return rankObject[type] === undefined; }); return omittedTypes.reduce(function (res, type) { res[type] = groups.length; return res; }, rankObject); } function convertPathGroupsForRanks(pathGroups) { const after = {}; const before = {}; const transformed = pathGroups.map((pathGroup, index) => { const group = pathGroup.group, positionString = pathGroup.position; let position = 0; if (positionString === 'after') { if (!after[group]) { after[group] = 1; } position = after[group]++; } else if (positionString === 'before') { if (!before[group]) { before[group] = []; } before[group].push(index); } return Object.assign({}, pathGroup, { position }); }); let maxPosition = 1; Object.keys(before).forEach(group => { const groupLength = before[group].length; before[group].forEach((groupIndex, index) => { transformed[groupIndex].position = -1 * (groupLength - index); }); maxPosition = Math.max(maxPosition, groupLength); }); Object.keys(after).forEach(key => { const groupNextPosition = after[key]; maxPosition = Math.max(maxPosition, groupNextPosition - 1); }); return { pathGroups: transformed, maxPosition: maxPosition > 10 ? Math.pow(10, Math.ceil(Math.log10(maxPosition))) : 10 }; } function fixNewLineAfterImport(context, previousImport) { const prevRoot = findRootNode(previousImport.node); const tokensToEndOfLine = takeTokensAfterWhile(context.getSourceCode(), prevRoot, commentOnSameLineAs(prevRoot)); let endOfLine = prevRoot.range[1]; if (tokensToEndOfLine.length > 0) { endOfLine = tokensToEndOfLine[tokensToEndOfLine.length - 1].range[1]; } return fixer => fixer.insertTextAfterRange([prevRoot.range[0], endOfLine], '\n'); } function removeNewLineAfterImport(context, currentImport, previousImport) { const sourceCode = context.getSourceCode(); const prevRoot = findRootNode(previousImport.node); const currRoot = findRootNode(currentImport.node); const rangeToRemove = [findEndOfLineWithComments(sourceCode, prevRoot), findStartOfLineWithComments(sourceCode, currRoot)]; if (/^\s*$/.test(sourceCode.text.substring(rangeToRemove[0], rangeToRemove[1]))) { return fixer => fixer.removeRange(rangeToRemove); } return undefined; } function makeNewlinesBetweenReport(context, imported, newlinesBetweenImports) { const getNumberOfEmptyLinesBetween = (currentImport, previousImport) => { const linesBetweenImports = context.getSourceCode().lines.slice(previousImport.node.loc.end.line, currentImport.node.loc.start.line - 1); return linesBetweenImports.filter(line => !line.trim().length).length; }; let previousImport = imported[0]; imported.slice(1).forEach(function (currentImport) { const emptyLinesBetween = getNumberOfEmptyLinesBetween(currentImport, previousImport); if (newlinesBetweenImports === 'always' || newlinesBetweenImports === 'always-and-inside-groups') { if (currentImport.rank !== previousImport.rank && emptyLinesBetween === 0) { context.report({ node: previousImport.node, message: 'There should be at least one empty line between import groups', fix: fixNewLineAfterImport(context, previousImport) }); } else if (currentImport.rank === previousImport.rank && emptyLinesBetween > 0 && newlinesBetweenImports !== 'always-and-inside-groups') { context.report({ node: previousImport.node, message: 'There should be no empty line within import group', fix: removeNewLineAfterImport(context, currentImport, previousImport) }); } } else if (emptyLinesBetween > 0) { context.report({ node: previousImport.node, message: 'There should be no empty line between import groups', fix: removeNewLineAfterImport(context, currentImport, previousImport) }); } previousImport = currentImport; }); } function getAlphabetizeConfig(options) { const alphabetize = options.alphabetize || {}; const order = alphabetize.order || 'ignore'; const caseInsensitive = alphabetize.caseInsensitive || false; return { order, caseInsensitive }; } module.exports = { meta: { type: 'suggestion', docs: { url: (0, _docsUrl2.default)('order') }, fixable: 'code', schema: [{ type: 'object', properties: { groups: { type: 'array' }, pathGroupsExcludedImportTypes: { type: 'array' }, pathGroups: { type: 'array', items: { type: 'object', properties: { pattern: { type: 'string' }, patternOptions: { type: 'object' }, group: { type: 'string', enum: types }, position: { type: 'string', enum: ['after', 'before'] } }, required: ['pattern', 'group'] } }, 'newlines-between': { enum: ['ignore', 'always', 'always-and-inside-groups', 'never'] }, alphabetize: { type: 'object', properties: { caseInsensitive: { type: 'boolean', default: false }, order: { enum: ['ignore', 'asc', 'desc'], default: 'ignore' } }, additionalProperties: false } }, additionalProperties: false }] }, create: function importOrderRule(context) { const options = context.options[0] || {}; const newlinesBetweenImports = options['newlines-between'] || 'ignore'; const pathGroupsExcludedImportTypes = new Set(options['pathGroupsExcludedImportTypes'] || ['builtin', 'external']); const alphabetize = getAlphabetizeConfig(options); let ranks; try { var _convertPathGroupsFor = convertPathGroupsForRanks(options.pathGroups || []); const pathGroups = _convertPathGroupsFor.pathGroups, maxPosition = _convertPathGroupsFor.maxPosition; ranks = { groups: convertGroupsToRanks(options.groups || defaultGroups), pathGroups, maxPosition }; } catch (error) { // Malformed configuration return { Program: function (node) { context.report(node, error.message); } }; } let imported = []; let level = 0; function incrementLevel() { level++; } function decrementLevel() { level--; } return { ImportDeclaration: function handleImports(node) { if (node.specifiers.length) { // Ignoring unassigned imports const name = node.source.value; registerNode(context, node, name, 'import', ranks, imported, pathGroupsExcludedImportTypes); } }, TSImportEqualsDeclaration: function handleImports(node) { let name; if (node.moduleReference.type === 'TSExternalModuleReference') { name = node.moduleReference.expression.value; } else if (node.isExport) { name = node.moduleReference.name; } else { name = null; } registerNode(context, node, name, 'import', ranks, imported, pathGroupsExcludedImportTypes); }, CallExpression: function handleRequires(node) { if (level !== 0 || !(0, _staticRequire2.default)(node) || !isInVariableDeclarator(node.parent)) { return; } const name = node.arguments[0].value; registerNode(context, node, name, 'require', ranks, imported, pathGroupsExcludedImportTypes); }, 'Program:exit': function reportAndReset() { if (newlinesBetweenImports !== 'ignore') { makeNewlinesBetweenReport(context, imported, newlinesBetweenImports); } if (alphabetize.order !== 'ignore') { mutateRanksToAlphabetize(imported, alphabetize); } makeOutOfOrderReport(context, imported); imported = []; }, FunctionDeclaration: incrementLevel, FunctionExpression: incrementLevel, ArrowFunctionExpression: incrementLevel, BlockStatement: incrementLevel, ObjectExpression: incrementLevel, 'FunctionDeclaration:exit': decrementLevel, 'FunctionExpression:exit': decrementLevel, 'ArrowFunctionExpression:exit': decrementLevel, 'BlockStatement:exit': decrementLevel, 'ObjectExpression:exit': decrementLevel }; } }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9vcmRlci5qcyJdLCJuYW1lcyI6WyJkZWZhdWx0R3JvdXBzIiwicmV2ZXJzZSIsImFycmF5IiwibWFwIiwidiIsIm5hbWUiLCJyYW5rIiwibm9kZSIsImdldFRva2Vuc09yQ29tbWVudHNBZnRlciIsInNvdXJjZUNvZGUiLCJjb3VudCIsImN1cnJlbnROb2RlT3JUb2tlbiIsInJlc3VsdCIsImkiLCJnZXRUb2tlbk9yQ29tbWVudEFmdGVyIiwicHVzaCIsImdldFRva2Vuc09yQ29tbWVudHNCZWZvcmUiLCJnZXRUb2tlbk9yQ29tbWVudEJlZm9yZSIsInRha2VUb2tlbnNBZnRlcldoaWxlIiwiY29uZGl0aW9uIiwidG9rZW5zIiwibGVuZ3RoIiwidGFrZVRva2Vuc0JlZm9yZVdoaWxlIiwiZmluZE91dE9mT3JkZXIiLCJpbXBvcnRlZCIsIm1heFNlZW5SYW5rTm9kZSIsImZpbHRlciIsImltcG9ydGVkTW9kdWxlIiwicmVzIiwiZmluZFJvb3ROb2RlIiwicGFyZW50IiwiYm9keSIsImZpbmRFbmRPZkxpbmVXaXRoQ29tbWVudHMiLCJ0b2tlbnNUb0VuZE9mTGluZSIsImNvbW1lbnRPblNhbWVMaW5lQXMiLCJlbmRPZlRva2VucyIsInJhbmdlIiwidGV4dCIsInRva2VuIiwidHlwZSIsImxvYyIsInN0YXJ0IiwibGluZSIsImVuZCIsImZpbmRTdGFydE9mTGluZVdpdGhDb21tZW50cyIsInN0YXJ0T2ZUb2tlbnMiLCJpc1BsYWluUmVxdWlyZU1vZHVsZSIsImRlY2xhcmF0aW9ucyIsImRlY2wiLCJpZCIsImluaXQiLCJjYWxsZWUiLCJhcmd1bWVudHMiLCJpc1BsYWluSW1wb3J0TW9kdWxlIiwic3BlY2lmaWVycyIsImlzUGxhaW5JbXBvcnRFcXVhbHMiLCJtb2R1bGVSZWZlcmVuY2UiLCJleHByZXNzaW9uIiwiY2FuQ3Jvc3NOb2RlV2hpbGVSZW9yZGVyIiwiY2FuUmVvcmRlckl0ZW1zIiwiZmlyc3ROb2RlIiwic2Vjb25kTm9kZSIsImluZGV4T2YiLCJzb3J0IiwiZmlyc3RJbmRleCIsInNlY29uZEluZGV4Iiwibm9kZXNCZXR3ZWVuIiwic2xpY2UiLCJub2RlQmV0d2VlbiIsImZpeE91dE9mT3JkZXIiLCJjb250ZXh0Iiwib3JkZXIiLCJnZXRTb3VyY2VDb2RlIiwiZmlyc3RSb290IiwiZmlyc3RSb290U3RhcnQiLCJmaXJzdFJvb3RFbmQiLCJzZWNvbmRSb290Iiwic2Vjb25kUm9vdFN0YXJ0Iiwic2Vjb25kUm9vdEVuZCIsImNhbkZpeCIsIm5ld0NvZGUiLCJzdWJzdHJpbmciLCJtZXNzYWdlIiwicmVwb3J0IiwiZml4IiwiZml4ZXIiLCJyZXBsYWNlVGV4dFJhbmdlIiwicmVwb3J0T3V0T2ZPcmRlciIsIm91dE9mT3JkZXIiLCJmb3JFYWNoIiwiaW1wIiwiZm91bmQiLCJmaW5kIiwiaGFzSGlnaGVyUmFuayIsImltcG9ydGVkSXRlbSIsIm1ha2VPdXRPZk9yZGVyUmVwb3J0IiwicmV2ZXJzZWRJbXBvcnRlZCIsInJldmVyc2VkT3JkZXIiLCJnZXRTb3J0ZXIiLCJhc2NlbmRpbmciLCJtdWx0aXBsaWVyIiwiaW1wb3J0c1NvcnRlciIsImltcG9ydEEiLCJpbXBvcnRCIiwibXV0YXRlUmFua3NUb0FscGhhYmV0aXplIiwiYWxwaGFiZXRpemVPcHRpb25zIiwiZ3JvdXBlZEJ5UmFua3MiLCJyZWR1Y2UiLCJhY2MiLCJBcnJheSIsImlzQXJyYXkiLCJncm91cFJhbmtzIiwiT2JqZWN0Iiwia2V5cyIsInNvcnRlckZuIiwiY29tcGFyYXRvciIsImNhc2VJbnNlbnNpdGl2ZSIsImEiLCJiIiwiU3RyaW5nIiwidG9Mb3dlckNhc2UiLCJncm91cFJhbmsiLCJuZXdSYW5rIiwiYWxwaGFiZXRpemVkUmFua3MiLCJpbXBvcnRlZEl0ZW1OYW1lIiwicGFyc2VJbnQiLCJjb21wdXRlUGF0aFJhbmsiLCJyYW5rcyIsInBhdGhHcm91cHMiLCJwYXRoIiwibWF4UG9zaXRpb24iLCJsIiwicGF0dGVybiIsInBhdHRlcm5PcHRpb25zIiwiZ3JvdXAiLCJwb3NpdGlvbiIsIm5vY29tbWVudCIsImNvbXB1dGVSYW5rIiwiZXhjbHVkZWRJbXBvcnRUeXBlcyIsImltcFR5cGUiLCJoYXMiLCJncm91cHMiLCJyZWdpc3Rlck5vZGUiLCJpc0luVmFyaWFibGVEZWNsYXJhdG9yIiwidHlwZXMiLCJjb252ZXJ0R3JvdXBzVG9SYW5rcyIsInJhbmtPYmplY3QiLCJpbmRleCIsImdyb3VwSXRlbSIsIkVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsInVuZGVmaW5lZCIsIm9taXR0ZWRUeXBlcyIsImNvbnZlcnRQYXRoR3JvdXBzRm9yUmFua3MiLCJhZnRlciIsImJlZm9yZSIsInRyYW5zZm9ybWVkIiwicGF0aEdyb3VwIiwicG9zaXRpb25TdHJpbmciLCJhc3NpZ24iLCJncm91cExlbmd0aCIsImdyb3VwSW5kZXgiLCJNYXRoIiwibWF4Iiwia2V5IiwiZ3JvdXBOZXh0UG9zaXRpb24iLCJwb3ciLCJjZWlsIiwibG9nMTAiLCJmaXhOZXdMaW5lQWZ0ZXJJbXBvcnQiLCJwcmV2aW91c0ltcG9ydCIsInByZXZSb290IiwiZW5kT2ZMaW5lIiwiaW5zZXJ0VGV4dEFmdGVyUmFuZ2UiLCJyZW1vdmVOZXdMaW5lQWZ0ZXJJbXBvcnQiLCJjdXJyZW50SW1wb3J0IiwiY3VyclJvb3QiLCJyYW5nZVRvUmVtb3ZlIiwidGVzdCIsInJlbW92ZVJhbmdlIiwibWFrZU5ld2xpbmVzQmV0d2VlblJlcG9ydCIsIm5ld2xpbmVzQmV0d2VlbkltcG9ydHMiLCJnZXROdW1iZXJPZkVtcHR5TGluZXNCZXR3ZWVuIiwibGluZXNCZXR3ZWVuSW1wb3J0cyIsImxpbmVzIiwidHJpbSIsImVtcHR5TGluZXNCZXR3ZWVuIiwiZ2V0QWxwaGFiZXRpemVDb25maWciLCJvcHRpb25zIiwiYWxwaGFiZXRpemUiLCJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJ1cmwiLCJmaXhhYmxlIiwic2NoZW1hIiwicHJvcGVydGllcyIsInBhdGhHcm91cHNFeGNsdWRlZEltcG9ydFR5cGVzIiwiaXRlbXMiLCJlbnVtIiwicmVxdWlyZWQiLCJkZWZhdWx0IiwiYWRkaXRpb25hbFByb3BlcnRpZXMiLCJjcmVhdGUiLCJpbXBvcnRPcmRlclJ1bGUiLCJTZXQiLCJlcnJvciIsIlByb2dyYW0iLCJsZXZlbCIsImluY3JlbWVudExldmVsIiwiZGVjcmVtZW50TGV2ZWwiLCJJbXBvcnREZWNsYXJhdGlvbiIsImhhbmRsZUltcG9ydHMiLCJzb3VyY2UiLCJ2YWx1ZSIsIlRTSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24iLCJpc0V4cG9ydCIsIkNhbGxFeHByZXNzaW9uIiwiaGFuZGxlUmVxdWlyZXMiLCJyZXBvcnRBbmRSZXNldCIsIkZ1bmN0aW9uRGVjbGFyYXRpb24iLCJGdW5jdGlvbkV4cHJlc3Npb24iLCJBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbiIsIkJsb2NrU3RhdGVtZW50IiwiT2JqZWN0RXhwcmVzc2lvbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7QUFFQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsZ0JBQWdCLENBQUMsU0FBRCxFQUFZLFVBQVosRUFBd0IsUUFBeEIsRUFBa0MsU0FBbEMsRUFBNkMsT0FBN0MsQ0FBdEI7O0FBRUE7O0FBRUEsU0FBU0MsT0FBVCxDQUFpQkMsS0FBakIsRUFBd0I7QUFDdEIsU0FBT0EsTUFBTUMsR0FBTixDQUFVLFVBQVVDLENBQVYsRUFBYTtBQUM1QixXQUFPO0FBQ0xDLFlBQU1ELEVBQUVDLElBREg7QUFFTEMsWUFBTSxDQUFDRixFQUFFRSxJQUZKO0FBR0xDLFlBQU1ILEVBQUVHO0FBSEgsS0FBUDtBQUtELEdBTk0sRUFNSk4sT0FOSSxFQUFQO0FBT0Q7O0FBRUQsU0FBU08sd0JBQVQsQ0FBa0NDLFVBQWxDLEVBQThDRixJQUE5QyxFQUFvREcsS0FBcEQsRUFBMkQ7QUFDekQsTUFBSUMscUJBQXFCSixJQUF6QjtBQUNBLFFBQU1LLFNBQVMsRUFBZjtBQUNBLE9BQUssSUFBSUMsSUFBSSxDQUFiLEVBQWdCQSxJQUFJSCxLQUFwQixFQUEy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QWhESTtBQWlETCxzQkFBZ0IsU0FBU3NCLGNBQVQsR0FBMEI7QUFDeEMsWUFBSXZDLDJCQUEyQixRQUEvQixFQUF5QztBQUN2Q0Qsb0NBQTBCL0csT0FBMUIsRUFBbUM5QyxRQUFuQyxFQUE2QzhKLHNCQUE3QztBQUNEOztBQUVELFlBQUlRLFlBQVl2SCxLQUFaLEtBQXNCLFFBQTFCLEVBQW9DO0FBQ2xDaUMsbUNBQXlCaEYsUUFBekIsRUFBbUNzSyxXQUFuQztBQUNEOztBQUVEL0YsNkJBQXFCekIsT0FBckIsRUFBOEI5QyxRQUE5Qjs7QUFFQUEsbUJBQVcsRUFBWDtBQUNELE9BN0RJO0FBOERMc00sMkJBQXFCWCxjQTlEaEI7QUErRExZLDBCQUFvQlosY0EvRGY7QUFnRUxhLCtCQUF5QmIsY0FoRXBCO0FBaUVMYyxzQkFBZ0JkLGNBakVYO0FBa0VMZSx3QkFBa0JmLGNBbEViO0FBbUVMLGtDQUE0QkMsY0FuRXZCO0FBb0VMLGlDQUEyQkEsY0FwRXRCO0FBcUVMLHNDQUFnQ0EsY0FyRTNCO0FBc0VMLDZCQUF1QkEsY0F0RWxCO0FBdUVMLCtCQUF5QkE7QUF2RXBCLEtBQVA7QUF5RUQ7QUE5S2MsQ0FBakIiLCJmaWxlIjoib3JkZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuaW1wb3J0IG1pbmltYXRjaCBmcm9tICdtaW5pbWF0Y2gnXG5pbXBvcnQgaW1wb3J0VHlwZSBmcm9tICcuLi9jb3JlL2ltcG9ydFR5cGUnXG5pbXBvcnQgaXNTdGF0aWNSZXF1aXJlIGZyb20gJy4uL2NvcmUvc3RhdGljUmVxdWlyZSdcbmltcG9ydCBkb2NzVXJsIGZyb20gJy4uL2RvY3NVcmwnXG5cbmNvbnN0IGRlZmF1bHRHcm91cHMgPSBbJ2J1aWx0aW4nLCAnZXh0ZXJuYWwnLCAncGFyZW50JywgJ3NpYmxpbmcnLCAnaW5kZXgnXVxuXG4vLyBSRVBPUlRJTkcgQU5EIEZJWElOR1xuXG5mdW5jdGlvbiByZXZlcnNlKGFycmF5KSB7XG4gIHJldHVybiBhcnJheS5tYXAoZnVuY3Rpb24gKHYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogdi5uYW1lLFxuICAgICAgcmFuazogLXYucmFuayxcbiAgICAgIG5vZGU6IHYubm9kZSxcbiAgICB9XG4gIH0pLnJldmVyc2UoKVxufVxuXG5mdW5jdGlvbiBnZXRUb2tlbnNPckNvbW1lbnRzQWZ0ZXIoc291cmNlQ29kZSwgbm9kZSwgY291bnQpIHtcbiAgbGV0IGN1cnJlbnROb2RlT3JUb2tlbiA9IG5vZGVcbiAgY29uc3QgcmVzdWx0ID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgY3VycmVudE5vZGVPclRva2VuID0gc291cmNlQ29kZS5nZXRUb2tlbk9yQ29tbWVudEFmdGVyKGN1cnJlbnROb2RlT3JUb2tlbilcbiAgICBpZiAoY3VycmVudE5vZGVPclRva2VuID09IG51bGwpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKGN1cnJlbnROb2RlT3JUb2tlbilcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbmZ1bmN0aW9uIGdldFRva2Vuc09yQ29tbWVudHNCZWZvcmUoc291cmNlQ29kZSwgbm9kZSwgY291bnQpIHtcbiAgbGV0IGN1cnJlbnROb2RlT3JUb2tlbiA9IG5vZGVcbiAgY29uc3QgcmVzdWx0ID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgY3VycmVudE5vZGVPclRva2VuID0gc291cmNlQ29kZS5nZXRUb2tlbk9yQ29tbWVudEJlZm9yZShjdXJyZW50Tm9kZU9yVG9rZW4pXG4gICAgaWYgKGN1cnJlbnROb2RlT3JUb2tlbiA9PSBudWxsKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgICByZXN1bHQucHVzaChjdXJyZW50Tm9kZU9yVG9rZW4pXG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5yZXZlcnNlKClcbn1cblxuZnVuY3Rpb24gdGFrZVRva2Vuc0FmdGVyV2hpbGUoc291cmNlQ29kZSwgbm9kZSwgY29uZGl0aW9uKSB7XG4gIGNvbnN0IHRva2VucyA9IGdldFRva2Vuc09yQ29tbWVudHNBZnRlcihzb3VyY2VDb2RlLCBub2RlLCAxMDApXG4gIGNvbnN0IHJlc3VsdCA9IFtdXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGNvbmRpdGlvbih0b2tlbnNbaV0pKSB7XG4gICAgICByZXN1bHQucHVzaCh0b2tlbnNbaV0pXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5mdW5jdGlvbiB0YWtlVG9rZW5zQmVmb3JlV2hpbGUoc291cmNlQ29kZSwgbm9kZSwgY29uZGl0aW9uKSB7XG4gIGNvbnN0IHRva2VucyA9IGdldFRva2Vuc09yQ29tbWVudHNCZWZvcmUoc291cmNlQ29kZSwgbm9kZSwgMTAwKVxuICBjb25zdCByZXN1bHQgPSBbXVxuICBmb3IgKGxldCBpID0gdG9rZW5zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGNvbmRpdGlvbih0b2tlbnNbaV0pKSB7XG4gICAgICByZXN1bHQucHVzaCh0b2tlbnNbaV0pXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5yZXZlcnNlKClcbn1cblxuZnVuY3Rpb24gZmluZE91dE9mT3JkZXIoaW1wb3J0ZWQpIHtcbiAgaWYgKGltcG9ydGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXVxuICB9XG4gIGxldCBtYXhTZWVuUmFua05vZGUgPSBpbXBvcnRlZFswXVxuICByZXR1cm4gaW1wb3J0ZWQuZmlsdGVyKGZ1bmN0aW9uIChpbXBvcnRlZE1vZHVsZSkge1xuICAgIGNvbnN0IHJlcyA9IGltcG9ydGVkTW9kdWxlLnJhbmsgPCBtYXhTZWVuUmFua05vZGUucmFua1xuICAgIGlmIChtYXhTZWVuUmFua05vZGUucmFuayA8IGltcG9ydGVkTW9kdWxlLnJhbmspIHtcbiAgICAgIG1heFNlZW5SYW5rTm9kZSA9IGltcG9ydGVkTW9kdWxlXG4gICAgfVxuICAgIHJldHVybiByZXNcbiAgfSlcbn1cblxuZnVuY3Rpb24gZmluZFJvb3ROb2RlKG5vZGUpIHtcbiAgbGV0IHBhcmVudCA9IG5vZGVcbiAgd2hpbGUgKHBhcmVudC5wYXJlbnQgIT0gbnVsbCAmJiBwYXJlbnQucGFyZW50LmJvZHkgPT0gbnVsbCkge1xuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRcbiAgfVxuICByZXR1cm4gcGFyZW50XG59XG5cbmZ1bmN0aW9uIGZpbmRFbmRPZkxpbmVXaXRoQ29tbWVudHMoc291cmNlQ29kZSwgbm9kZSkge1xuICBjb25zdCB0b2tlbnNUb0VuZE9mTGluZSA9IHRha2VUb2tlbnNBZnRlcldoaWxlKHNvdXJjZUNvZGUsIG5vZGUsIGNvbW1lbnRPblNhbWVMaW5lQXMobm9kZSkpXG4gIGxldCBlbmRPZlRva2VucyA9IHRva2Vuc1RvRW5kT2ZMaW5lLmxlbmd0aCA+IDBcbiAgICA/IHRva2Vuc1RvRW5kT2ZMaW5lW3Rva2Vuc1RvRW5kT2ZMaW5lLmxlbmd0aCAtIDFdLnJhbmdlWzFdXG4gICAgOiBub2RlLnJhbmdlWzFdXG4gIGxldCByZXN1bHQgPSBlbmRPZlRva2Vuc1xuICBmb3IgKGxldCBpID0gZW5kT2ZUb2tlbnM7IGkgPCBzb3VyY2VDb2RlLnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc291cmNlQ29kZS50ZXh0W2ldID09PSAnXFxuJykge1xuICAgICAgcmVzdWx0ID0gaSArIDFcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIGlmIChzb3VyY2VDb2RlLnRleHRbaV0gIT09ICcgJyAmJiBzb3VyY2VDb2RlLnRleHRbaV0gIT09ICdcXHQnICYmIHNvdXJjZUNvZGUudGV4dFtpXSAhPT0gJ1xccicpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIHJlc3VsdCA9IGkgKyAxXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5mdW5jdGlvbiBjb21tZW50T25TYW1lTGluZUFzKG5vZGUpIHtcbiAgcmV0dXJuIHRva2VuID0+ICh0b2tlbi50eXBlID09PSAnQmxvY2snIHx8ICB0b2tlbi50eXBlID09PSAnTGluZScpICYmXG4gICAgICB0b2tlbi5sb2Muc3RhcnQubGluZSA9PT0gdG9rZW4ubG9jLmVuZC5saW5lICYmXG4gICAgICB0b2tlbi5sb2MuZW5kLmxpbmUgPT09IG5vZGUubG9jLmVuZC5saW5lXG59XG5cbmZ1bmN0aW9uIGZpbmRTdGFydE9mTGluZVdpdGhDb21tZW50cyhzb3VyY2VDb2RlLCBub2RlKSB7XG4gIGNvbnN0IHRva2Vuc1RvRW5kT2ZMaW5lID0gdGFrZVRva2Vuc0JlZm9yZVdoaWxlKHNvdXJjZUNvZGUsIG5vZGUsIGNvbW1lbnRPblNhbWVMaW5lQXMobm9kZSkpXG4gIGxldCBzdGFydE9mVG9rZW5zID0gdG9rZW5zVG9FbmRPZkxpbmUubGVuZ3RoID4gMCA/IHRva2Vuc1RvRW5kT2ZMaW5lWzBdLnJhbmdlWzBdIDogbm9kZS5yYW5nZVswXVxuICBsZXQgcmVzdWx0ID0gc3RhcnRPZlRva2Vuc1xuICBmb3IgKGxldCBpID0gc3RhcnRPZlRva2VucyAtIDE7IGkgPiAwOyBpLS0pIHtcbiAgICBpZiAoc291cmNlQ29kZS50ZXh0W2ldICE9PSAnICcgJiYgc291cmNlQ29kZS50ZXh0W2ldICE9PSAnXFx0Jykge1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgcmVzdWx0ID0gaVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuZnVuY3Rpb24gaXNQbGFpblJlcXVpcmVNb2R1bGUobm9kZSkge1xuICBpZiAobm9kZS50eXBlICE9PSAnVmFyaWFibGVEZWNsYXJhdGlvbicpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICBpZiAobm9kZS5kZWNsYXJhdGlvbnMubGVuZ3RoICE9PSAxKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgY29uc3QgZGVjbCA9IG5vZGUuZGVjbGFyYXRpb25zWzBdXG4gIGNvbnN0IHJlc3VsdCA9IGRlY2wuaWQgJiZcbiAgICAoZGVjbC5pZC50eXBlID09PSAnSWRlbnRpZmllcicgfHwgZGVjbC5pZC50eXBlID09PSAnT2JqZWN0UGF0dGVybicpICYmXG4gICAgZGVjbC5pbml0ICE9IG51bGwgJiZcbiAgICBkZWNsLmluaXQudHlwZSA9PT0gJ0NhbGxFeHByZXNzaW9uJyAmJlxuICAgIGRlY2wuaW5pdC5jYWxsZWUgIT0gbnVsbCAmJlxuICAgIGRlY2wuaW5pdC5jYWxsZWUubmFtZSA9PT0gJ3JlcXVpcmUnICYmXG4gICAgZGVjbC5pbml0LmFyZ3VtZW50cyAhPSBudWxsICYmXG4gICAgZGVjbC5pbml0LmFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiZcbiAgICBkZWNsLmluaXQuYXJndW1lbnRzWzBdLnR5cGUgPT09ICdMaXRlcmFsJ1xuICByZXR1cm4gcmVzdWx0XG59XG5cbmZ1bmN0aW9uIGlzUGxhaW5JbXBvcnRNb2R1bGUobm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlID09PSAnSW1wb3J0RGVjbGFyYXRpb24nICYmIG5vZGUuc3BlY2lmaWVycyAhPSBudWxsICYmIG5vZGUuc3BlY2lmaWVycy5sZW5ndGggPiAwXG59XG5cbmZ1bmN0aW9uIGlzUGxhaW5JbXBvcnRFcXVhbHMobm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlID09PSAnVFNJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbicgJiYgbm9kZS5tb2R1bGVSZWZlcmVuY2UuZXhwcmVzc2lvblxufVxuXG5mdW5jdGlvbiBjYW5Dcm9zc05vZGVXaGlsZVJlb3JkZXIobm9kZSkge1xuICByZXR1cm4gaXNQbGFpblJlcXVpcmVNb2R1bGUobm9kZSkgfHwgaXNQbGFpbkltcG9ydE1vZHVsZShub2RlKSB8fCBpc1BsYWluSW1wb3J0RXF1YWxzKG5vZGUpXG59XG5cbmZ1bmN0aW9uIGNhblJlb3JkZXJJdGVtcyhmaXJzdE5vZGUsIHNlY29uZE5vZGUpIHtcbiAgY29uc3QgcGFyZW50ID0gZmlyc3ROb2RlLnBhcmVudFxuICBjb25zdCBbZmlyc3RJbmRleCwgc2Vjb25kSW5kZXhdID0gW1xuICAgIHBhcmVudC5ib2R5LmluZGV4T2YoZmlyc3ROb2RlKSxcbiAgICBwYXJlbnQuYm9keS5pbmRleE9mKHNlY29uZE5vZGUpLFxuICBdLnNvcnQoKVxuICBjb25zdCBub2Rlc0JldHdlZW4gPSBwYXJlbnQuYm9keS5zbGljZShmaXJzdEluZGV4LCBzZWNvbmRJbmRleCArIDEpXG4gIGZvciAodmFyIG5vZGVCZXR3ZWVuIG9mIG5vZGVzQmV0d2Vlbikge1xuICAgIGlmICghY2FuQ3Jvc3NOb2RlV2hpbGVSZW9yZGVyKG5vZGVCZXR3ZWVuKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbmZ1bmN0aW9uIGZpeE91dE9mT3JkZXIoY29udGV4dCwgZmlyc3ROb2RlLCBzZWNvbmROb2RlLCBvcmRlcikge1xuICBjb25zdCBzb3VyY2VDb2RlID0gY29udGV4dC5nZXRTb3VyY2VDb2RlKClcblxuICBjb25zdCBmaXJzdFJvb3QgPSBmaW5kUm9vdE5vZGUoZmlyc3ROb2RlLm5vZGUpXG4gIGNvbnN0IGZpcnN0Um9vdFN0YXJ0ID0gZmluZFN0YXJ0T2ZMaW5lV2l0aENvbW1lbnRzKHNvdXJjZUNvZGUsIGZpcnN0Um9vdClcbiAgY29uc3QgZmlyc3RSb290RW5kID0gZmluZEVuZE9mTGluZVdpdGhDb21tZW50cyhzb3VyY2VDb2RlLCBmaXJzdFJvb3QpXG5cbiAgY29uc3Qgc2Vjb25kUm9vdCA9IGZpbmRSb290Tm9kZShzZWNvbmROb2RlLm5vZGUpXG4gIGNvbnN0IHNlY29uZFJvb3RTdGFydCA9IGZpbmRTdGFydE9mTGluZVdpdGhDb21tZW50cyhzb3VyY2VDb2RlLCBzZWNvbmRSb290KVxuICBjb25zdCBzZWNvbmRSb290RW5kID0gZmluZEVuZE9mTGluZVdpdGhDb21tZW50cyhzb3VyY2VDb2RlLCBzZWNvbmRSb290KVxuICBjb25zdCBjYW5GaXggPSBjYW5SZW9yZGVySXRlbXMoZmlyc3RSb290LCBzZWNvbmRSb290KVxuXG4gIGxldCBuZXdDb2RlID0gc291cmNlQ29kZS50ZXh0LnN1YnN0cmluZyhzZWNvbmRSb290U3RhcnQsIHNlY29uZFJvb3RFbmQpXG4gIGlmIChuZXdDb2RlW25ld0NvZGUubGVuZ3RoIC0gMV0gIT09ICdcXG4nKSB7XG4gICAgbmV3Q29kZSA9IG5ld0NvZGUgKyAnXFxuJ1xuICB9XG5cbiAgY29uc3QgbWVzc2FnZSA9ICdgJyArIHNlY29uZE5vZGUubmFtZSArICdgIGltcG9ydCBzaG91bGQgb2NjdXIgJyArIG9yZGVyICtcbiAgICAgICcgaW1wb3J0IG9mIGAnICsgZmlyc3ROb2RlLm5hbWUgKyAnYCdcblxuICBpZiAob3JkZXIgPT09ICdiZWZvcmUnKSB7XG4gICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgbm9kZTogc2Vjb25kTm9kZS5ub2RlLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIGZpeDogY2FuRml4ICYmIChmaXhlciA9PlxuICAgICAgICBmaXhlci5yZXBsYWNlVGV4dFJhbmdlKFxuICAgICAgICAgIFtmaXJzdFJvb3RTdGFydCwgc2Vjb25kUm9vdEVuZF0sXG4gICAgICAgICAgbmV3Q29kZSArIHNvdXJjZUNvZGUudGV4dC5zdWJzdHJpbmcoZmlyc3RSb290U3RhcnQsIHNlY29uZFJvb3RTdGFydClcbiAgICAgICAgKSksXG4gICAgfSlcbiAgfSBlbHNlIGlmIChvcmRlciA9PT0gJ2FmdGVyJykge1xuICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgIG5vZGU6IHNlY29uZE5vZGUubm9kZSxcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICBmaXg6IGNhbkZpeCAmJiAoZml4ZXIgPT5cbiAgICAgICAgZml4ZXIucmVwbGFjZVRleHRSYW5nZShcbiAgICAgICAgICBbc2Vjb25kUm9vdFN0YXJ0LCBmaXJzdFJvb3RFbmRdLFxuICAgICAgICAgIHNvdXJjZUNvZGUudGV4dC5zdWJzdHJpbmcoc2Vjb25kUm9vdEVuZCwgZmlyc3RSb290RW5kKSArIG5ld0NvZGVcbiAgICAgICAgKSksXG4gICAgfSlcbiAgfVxufVxuXG5mdW5jdGlvbiByZXBvcnRPdXRPZk9yZGVyKGNvbnRleHQsIGltcG9ydGVkLCBvdXRPZk9yZGVyLCBvcmRlcikge1xuICBvdXRPZk9yZGVyLmZvckVhY2goZnVuY3Rpb24gKGltcCkge1xuICAgIGNvbnN0IGZvdW5kID0gaW1wb3J0ZWQuZmluZChmdW5jdGlvbiBoYXNIaWdoZXJSYW5rKGltcG9ydGVkSXRlbSkge1xuICAgICAgcmV0dXJuIGltcG9ydGVkSXRlbS5yYW5rID4gaW1wLnJhbmtcbiAgICB9KVxuICAgIGZpeE91dE9mT3JkZXIoY29udGV4dCwgZm91bmQsIGltcCwgb3JkZXIpXG4gIH0pXG59XG5cbmZ1bmN0aW9uIG1ha2VPdXRPZk9yZGVyUmVwb3J0KGNvbnRleHQsIGltcG9ydGVkKSB7XG4gIGNvbnN0IG91dE9mT3JkZXIgPSBmaW5kT3V0T2ZPcmRlcihpbXBvcnRlZClcbiAgaWYgKCFvdXRPZk9yZGVyLmxlbmd0aCkge1xuICAgIHJldHVyblxuICB9XG4gIC8vIFRoZXJlIGFyZSB0aGluZ3MgdG8gcmVwb3J0LiBUcnkgdG8gbWluaW1pemUgdGhlIG51bWJlciBvZiByZXBvcnRlZCBlcnJvcnMuXG4gIGNvbnN0IHJldmVyc2VkSW1wb3J0ZWQgPSByZXZlcnNlKGltcG9ydGVkKVxuICBjb25zdCByZXZlcnNlZE9yZGVyID0gZmluZE91dE9mT3JkZXIocmV2ZXJzZWRJbXBvcnRlZClcbiAgaWYgKHJldmVyc2VkT3JkZXIubGVuZ3RoIDwgb3V0T2ZPcmRlci5sZW5ndGgpIHtcbiAgICByZXBvcnRPdXRPZk9yZGVyKGNvbnRleHQsIHJldmVyc2VkSW1wb3J0ZWQsIHJldmVyc2VkT3JkZXIsICdhZnRlcicpXG4gICAgcmV0dXJuXG4gIH1cbiAgcmVwb3J0T3V0T2ZPcmRlcihjb250ZXh0LCBpbXBvcnRlZCwgb3V0T2ZPcmRlciwgJ2JlZm9yZScpXG59XG5cbmZ1bmN0aW9uIGdldFNvcnRlcihhc2NlbmRpbmcpIHtcbiAgbGV0IG11bHRpcGxpZXIgPSAoYXNjZW5kaW5nID8gMSA6IC0xKVxuXG4gIHJldHVybiBmdW5jdGlvbiBpbXBvcnRzU29ydGVyKGltcG9ydEEsIGltcG9ydEIpIHtcbiAgICBsZXQgcmVzdWx0XG5cbiAgICBpZiAoKGltcG9ydEEgPCBpbXBvcnRCKSB8fCBpbXBvcnRCID09PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSAtMVxuICAgIH0gZWxzZSBpZiAoKGltcG9ydEEgPiBpbXBvcnRCKSB8fCBpbXBvcnRBID09PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSAxXG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IDBcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0ICogbXVsdGlwbGllclxuICB9XG59XG5cbmZ1bmN0aW9uIG11dGF0ZVJhbmtzVG9BbHBoYWJldGl6ZShpbXBvcnRlZCwgYWxwaGFiZXRpemVPcHRpb25zKSB7XG4gIGNvbnN0IGdyb3VwZWRCeVJhbmtzID0gaW1wb3J0ZWQucmVkdWNlKGZ1bmN0aW9uKGFjYywgaW1wb3J0ZWRJdGVtKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGFjY1tpbXBvcnRlZEl0ZW0ucmFua10pKSB7XG4gICAgICBhY2NbaW1wb3J0ZWRJdGVtLnJhbmtdID0gW11cbiAgICB9XG4gICAgYWNjW2ltcG9ydGVkSXRlbS5yYW5rXS5wdXNoKGltcG9ydGVkSXRlbS5uYW1lKVxuICAgIHJldHVybiBhY2NcbiAgfSwge30pXG5cbiAgY29uc3QgZ3JvdXBSYW5rcyA9IE9iamVjdC5rZXlzKGdyb3VwZWRCeVJhbmtzKVxuXG4gIGNvbnN0IHNvcnRlckZuID0gZ2V0U29ydGVyKGFscGhhYmV0aXplT3B0aW9ucy5vcmRlciA9PT0gJ2FzYycpXG4gIGNvbnN0IGNvbXBhcmF0b3IgPSBhbHBoYWJldGl6ZU9wdGlvbnMuY2FzZUluc2Vuc2l0aXZlID8gKGEsIGIpID0+IHNvcnRlckZuKFN0cmluZyhhKS50b0xvd2VyQ2FzZSgpLCBTdHJpbmcoYikudG9Mb3dlckNhc2UoKSkgOiAoYSwgYikgPT4gc29ydGVyRm4oYSwgYilcbiAgLy8gc29ydCBpbXBvcnRzIGxvY2FsbHkgd2l0aGluIHRoZWlyIGdyb3VwXG4gIGdyb3VwUmFua3MuZm9yRWFjaChmdW5jdGlvbihncm91cFJhbmspIHtcbiAgICBncm91cGVkQnlSYW5rc1tncm91cFJhbmtdLnNvcnQoY29tcGFyYXRvcilcbiAgfSlcblxuICAvLyBhc3NpZ24gZ2xvYmFsbHkgdW5pcXVlIHJhbmsgdG8gZWFjaCBpbXBvcnRcbiAgbGV0IG5ld1JhbmsgPSAwXG4gIGNvbnN0IGFscGhhYmV0aXplZFJhbmtzID0gZ3JvdXBSYW5rcy5zb3J0KCkucmVkdWNlKGZ1bmN0aW9uKGFjYywgZ3JvdXBSYW5rKSB7XG4gICAgZ3JvdXBlZEJ5UmFua3NbZ3JvdXBSYW5rXS5mb3JFYWNoKGZ1bmN0aW9uKGltcG9ydGVkSXRlbU5hbWUpIHtcbiAgICAgIGFjY1tpbXBvcnRlZEl0ZW1OYW1lXSA9IHBhcnNlSW50KGdyb3VwUmFuaywgMTApICsgbmV3UmFua1xuICAgICAgbmV3UmFuayArPSAxXG4gICAgfSlcbiAgICByZXR1cm4gYWNjXG4gIH0sIHt9KVxuXG4gIC8vIG11dGF0ZSB0aGUgb3JpZ2luYWwgZ3JvdXAtcmFuayB3aXRoIGFscGhhYmV0aXplZC1yYW5rXG4gIGltcG9ydGVkLmZvckVhY2goZnVuY3Rpb24oaW1wb3J0ZWRJdGVtKSB7XG4gICAgaW1wb3J0ZWRJdGVtLnJhbmsgPSBhbHBoYWJldGl6ZWRSYW5rc1tpbXBvcnRlZEl0ZW0ubmFtZV1cbiAgfSlcbn1cblxuLy8gREVURUNUSU5HXG5cbmZ1bmN0aW9uIGNvbXB1dGVQYXRoUmFuayhyYW5rcywgcGF0aEdyb3VwcywgcGF0aCwgbWF4UG9zaXRpb24pIHtcbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBwYXRoR3JvdXBzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGNvbnN0IHsgcGF0dGVybiwgcGF0dGVybk9wdGlvbnMsIGdyb3VwLCBwb3NpdGlvbiA9IDEgfSA9IHBhdGhHcm91cHNbaV1cbiAgICBpZiAobWluaW1hdGNoKHBhdGgsIHBhdHRlcm4sIHBhdHRlcm5PcHRpb25zIHx8IHsgbm9jb21tZW50OiB0cnVlIH0pKSB7XG4gICAgICByZXR1cm4gcmFua3NbZ3JvdXBdICsgKHBvc2l0aW9uIC8gbWF4UG9zaXRpb24pXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVSYW5rKGNvbnRleHQsIHJhbmtzLCBuYW1lLCB0eXBlLCBleGNsdWRlZEltcG9ydFR5cGVzKSB7XG4gIGNvbnN0IGltcFR5cGUgPSBpbXBvcnRUeXBlKG5hbWUsIGNvbnRleHQpXG4gIGxldCByYW5rXG4gIGlmICghZXhjbHVkZWRJbXBvcnRUeXBlcy5oYXMoaW1wVHlwZSkpIHtcbiAgICByYW5rID0gY29tcHV0ZVBhdGhSYW5rKHJhbmtzLmdyb3VwcywgcmFua3MucGF0aEdyb3VwcywgbmFtZSwgcmFua3MubWF4UG9zaXRpb24pXG4gIH1cbiAgaWYgKHR5cGVvZiByYW5rID09PSAndW5kZWZpbmVkJykge1xuICAgIHJhbmsgPSByYW5rcy5ncm91cHNbaW1wVHlwZV1cbiAgfVxuICBpZiAodHlwZSAhPT0gJ2ltcG9ydCcpIHtcbiAgICByYW5rICs9IDEwMFxuICB9XG5cbiAgcmV0dXJuIHJhbmtcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJOb2RlKGNvbnRleHQsIG5vZGUsIG5hbWUsIHR5cGUsIHJhbmtzLCBpbXBvcnRlZCwgZXhjbHVkZWRJbXBvcnRUeXBlcykge1xuICBjb25zdCByYW5rID0gY29tcHV0ZVJhbmsoY29udGV4dCwgcmFua3MsIG5hbWUsIHR5cGUsIGV4Y2x1ZGVkSW1wb3J0VHlwZXMpXG4gIGlmIChyYW5rICE9PSAtMSkge1xuICAgIGltcG9ydGVkLnB1c2goe25hbWUsIHJhbmssIG5vZGV9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzSW5WYXJpYWJsZURlY2xhcmF0b3Iobm9kZSkge1xuICByZXR1cm4gbm9kZSAmJlxuICAgIChub2RlLnR5cGUgPT09ICdWYXJpYWJsZURlY2xhcmF0b3InIHx8IGlzSW5WYXJpYWJsZURlY2xhcmF0b3Iobm9kZS5wYXJlbnQpKVxufVxuXG5jb25zdCB0eXBlcyA9IFsnYnVpbHRpbicsICdleHRlcm5hbCcsICdpbnRlcm5hbCcsICd1bmtub3duJywgJ3BhcmVudCcsICdzaWJsaW5nJywgJ2luZGV4J11cblxuLy8gQ3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0eXBlLXJhbmsgcGFpcnMuXG4vLyBFeGFtcGxlOiB7IGluZGV4OiAwLCBzaWJsaW5nOiAxLCBwYXJlbnQ6IDEsIGV4dGVybmFsOiAxLCBidWlsdGluOiAyLCBpbnRlcm5hbDogMiB9XG4vLyBXaWxsIHRocm93IGFuIGVycm9yIGlmIGl0IGNvbnRhaW5zIGEgdHlwZSB0aGF0IGRvZXMgbm90IGV4aXN0LCBvciBoYXMgYSBkdXBsaWNhdGVcbmZ1bmN0aW9uIGNvbnZlcnRHcm91cHNUb1JhbmtzKGdyb3Vwcykge1xuICBjb25zdCByYW5rT2JqZWN0ID0gZ3JvdXBzLnJlZHVjZShmdW5jdGlvbihyZXMsIGdyb3VwLCBpbmRleCkge1xuICAgIGlmICh0eXBlb2YgZ3JvdXAgPT09ICdzdHJpbmcnKSB7XG4gICAgICBncm91cCA9IFtncm91cF1cbiAgICB9XG4gICAgZ3JvdXAuZm9yRWFjaChmdW5jdGlvbihncm91cEl0ZW0pIHtcbiAgICAgIGlmICh0eXBlcy5pbmRleE9mKGdyb3VwSXRlbSkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IGNvbmZpZ3VyYXRpb24gb2YgdGhlIHJ1bGU6IFVua25vd24gdHlwZSBgJyArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZ3JvdXBJdGVtKSArICdgJylcbiAgICAgIH1cbiAgICAgIGlmIChyZXNbZ3JvdXBJdGVtXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IGNvbmZpZ3VyYXRpb24gb2YgdGhlIHJ1bGU6IGAnICsgZ3JvdXBJdGVtICsgJ2AgaXMgZHVwbGljYXRlZCcpXG4gICAgICB9XG4gICAgICByZXNbZ3JvdXBJdGVtXSA9IGluZGV4XG4gICAgfSlcbiAgICByZXR1cm4gcmVzXG4gIH0sIHt9KVxuXG4gIGNvbnN0IG9taXR0ZWRUeXBlcyA9IHR5cGVzLmZpbHRlcihmdW5jdGlvbih0eXBlKSB7XG4gICAgcmV0dXJuIHJhbmtPYmplY3RbdHlwZV0gPT09IHVuZGVmaW5lZFxuICB9KVxuXG4gIHJldHVybiBvbWl0dGVkVHlwZXMucmVkdWNlKGZ1bmN0aW9uKHJlcywgdHlwZSkge1xuICAgIHJlc1t0eXBlXSA9IGdyb3Vwcy5sZW5ndGhcbiAgICByZXR1cm4gcmVzXG4gIH0sIHJhbmtPYmplY3QpXG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRQYXRoR3JvdXBzRm9yUmFua3MocGF0aEdyb3Vwcykge1xuICBjb25zdCBhZnRlciA9IHt9XG4gIGNvbnN0IGJlZm9yZSA9IHt9XG5cbiAgY29uc3QgdHJhbnNmb3JtZWQgPSBwYXRoR3JvdXBzLm1hcCgocGF0aEdyb3VwLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IHsgZ3JvdXAsIHBvc2l0aW9uOiBwb3NpdGlvblN0cmluZyB9ID0gcGF0aEdyb3VwXG4gICAgbGV0IHBvc2l0aW9uID0gMFxuICAgIGlmIChwb3NpdGlvblN0cmluZyA9PT0gJ2FmdGVyJykge1xuICAgICAgaWYgKCFhZnRlcltncm91cF0pIHtcbiAgICAgICAgYWZ0ZXJbZ3JvdXBdID0gMVxuICAgICAgfVxuICAgICAgcG9zaXRpb24gPSBhZnRlcltncm91cF0rK1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb25TdHJpbmcgPT09ICdiZWZvcmUnKSB7XG4gICAgICBpZiAoIWJlZm9yZVtncm91cF0pIHtcbiAgICAgICAgYmVmb3JlW2dyb3VwXSA9IFtdXG4gICAgICB9XG4gICAgICBiZWZvcmVbZ3JvdXBdLnB1c2goaW5kZXgpXG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHBhdGhHcm91cCwgeyBwb3NpdGlvbiB9KVxuICB9KVxuXG4gIGxldCBtYXhQb3NpdGlvbiA9IDFcblxuICBPYmplY3Qua2V5cyhiZWZvcmUpLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBMZW5ndGggPSBiZWZvcmVbZ3JvdXBdLmxlbmd0aFxuICAgIGJlZm9yZVtncm91cF0uZm9yRWFjaCgoZ3JvdXBJbmRleCwgaW5kZXgpID0+IHtcbiAgICAgIHRyYW5zZm9ybWVkW2dyb3VwSW5kZXhdLnBvc2l0aW9uID0gLTEgKiAoZ3JvdXBMZW5ndGggLSBpbmRleClcbiAgICB9KVxuICAgIG1heFBvc2l0aW9uID0gTWF0aC5tYXgobWF4UG9zaXRpb24sIGdyb3VwTGVuZ3RoKVxuICB9KVxuXG4gIE9iamVjdC5rZXlzKGFmdGVyKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICBjb25zdCBncm91cE5leHRQb3NpdGlvbiA9IGFmdGVyW2tleV1cbiAgICBtYXhQb3NpdGlvbiA9IE1hdGgubWF4KG1heFBvc2l0aW9uLCBncm91cE5leHRQb3NpdGlvbiAtIDEpXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBwYXRoR3JvdXBzOiB0cmFuc2Zvcm1lZCxcbiAgICBtYXhQb3NpdGlvbjogbWF4UG9zaXRpb24gPiAxMCA/IE1hdGgucG93KDEwLCBNYXRoLmNlaWwoTWF0aC5sb2cxMChtYXhQb3NpdGlvbikpKSA6IDEwLFxuICB9XG59XG5cbmZ1bmN0aW9uIGZpeE5ld0xpbmVBZnRlckltcG9ydChjb250ZXh0LCBwcmV2aW91c0ltcG9ydCkge1xuICBjb25zdCBwcmV2Um9vdCA9IGZpbmRSb290Tm9kZShwcmV2aW91c0ltcG9ydC5ub2RlKVxuICBjb25zdCB0b2tlbnNUb0VuZE9mTGluZSA9IHRha2VUb2tlbnNBZnRlcldoaWxlKFxuICAgIGNvbnRleHQuZ2V0U291cmNlQ29kZSgpLCBwcmV2Um9vdCwgY29tbWVudE9uU2FtZUxpbmVBcyhwcmV2Um9vdCkpXG5cbiAgbGV0IGVuZE9mTGluZSA9IHByZXZSb290LnJhbmdlWzFdXG4gIGlmICh0b2tlbnNUb0VuZE9mTGluZS5sZW5ndGggPiAwKSB7XG4gICAgZW5kT2ZMaW5lID0gdG9rZW5zVG9FbmRPZkxpbmVbdG9rZW5zVG9FbmRPZkxpbmUubGVuZ3RoIC0gMV0ucmFuZ2VbMV1cbiAgfVxuICByZXR1cm4gKGZpeGVyKSA9PiBmaXhlci5pbnNlcnRUZXh0QWZ0ZXJSYW5nZShbcHJldlJvb3QucmFuZ2VbMF0sIGVuZE9mTGluZV0sICdcXG4nKVxufVxuXG5mdW5jdGlvbiByZW1vdmVOZXdMaW5lQWZ0ZXJJbXBvcnQoY29udGV4dCwgY3VycmVudEltcG9ydCwgcHJldmlvdXNJbXBvcnQpIHtcbiAgY29uc3Qgc291cmNlQ29kZSA9IGNvbnRleHQuZ2V0U291cmNlQ29kZSgpXG4gIGNvbnN0IHByZXZSb290ID0gZmluZFJvb3ROb2RlKHByZXZpb3VzSW1wb3J0Lm5vZGUpXG4gIGNvbnN0IGN1cnJSb290ID0gZmluZFJvb3ROb2RlKGN1cnJlbnRJbXBvcnQubm9kZSlcbiAgY29uc3QgcmFuZ2VUb1JlbW92ZSA9IFtcbiAgICBmaW5kRW5kT2ZMaW5lV2l0aENvbW1lbnRzKHNvdXJjZUNvZGUsIHByZXZSb290KSxcbiAgICBmaW5kU3RhcnRPZkxpbmVXaXRoQ29tbWVudHMoc291cmNlQ29kZSwgY3VyclJvb3QpLFxuICBdXG4gIGlmICgvXlxccyokLy50ZXN0KHNvdXJjZUNvZGUudGV4dC5zdWJzdHJpbmcocmFuZ2VUb1JlbW92ZVswXSwgcmFuZ2VUb1JlbW92ZVsxXSkpKSB7XG4gICAgcmV0dXJuIChmaXhlcikgPT4gZml4ZXIucmVtb3ZlUmFuZ2UocmFuZ2VUb1JlbW92ZSlcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIG1ha2VOZXdsaW5lc0JldHdlZW5SZXBvcnQgKGNvbnRleHQsIGltcG9ydGVkLCBuZXdsaW5lc0JldHdlZW5JbXBvcnRzKSB7XG4gIGNvbnN0IGdldE51bWJlck9mRW1wdHlMaW5lc0JldHdlZW4gPSAoY3VycmVudEltcG9ydCwgcHJldmlvdXNJbXBvcnQpID0+IHtcbiAgICBjb25zdCBsaW5lc0JldHdlZW5JbXBvcnRzID0gY29udGV4dC5nZXRTb3VyY2VDb2RlKCkubGluZXMuc2xpY2UoXG4gICAgICBwcmV2aW91c0ltcG9ydC5ub2RlLmxvYy5lbmQubGluZSxcbiAgICAgIGN1cnJlbnRJbXBvcnQubm9kZS5sb2Muc3RhcnQubGluZSAtIDFcbiAgICApXG5cbiAgICByZXR1cm4gbGluZXNCZXR3ZWVuSW1wb3J0cy5maWx0ZXIoKGxpbmUpID0+ICFsaW5lLnRyaW0oKS5sZW5ndGgpLmxlbmd0aFxuICB9XG4gIGxldCBwcmV2aW91c0ltcG9ydCA9IGltcG9ydGVkWzBdXG5cbiAgaW1wb3J0ZWQuc2xpY2UoMSkuZm9yRWFjaChmdW5jdGlvbihjdXJyZW50SW1wb3J0KSB7XG4gICAgY29uc3QgZW1wdHlMaW5lc0JldHdlZW4gPSBnZXROdW1iZXJPZkVtcHR5TGluZXNCZXR3ZWVuKGN1cnJlbnRJbXBvcnQsIHByZXZpb3VzSW1wb3J0KVxuXG4gICAgaWYgKG5ld2xpbmVzQmV0d2VlbkltcG9ydHMgPT09ICdhbHdheXMnXG4gICAgICAgIHx8IG5ld2xpbmVzQmV0d2VlbkltcG9ydHMgPT09ICdhbHdheXMtYW5kLWluc2lkZS1ncm91cHMnKSB7XG4gICAgICBpZiAoY3VycmVudEltcG9ydC5yYW5rICE9PSBwcmV2aW91c0ltcG9ydC5yYW5rICYmIGVtcHR5TGluZXNCZXR3ZWVuID09PSAwKSB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICBub2RlOiBwcmV2aW91c0ltcG9ydC5ub2RlLFxuICAgICAgICAgIG1lc3NhZ2U6ICdUaGVyZSBzaG91bGQgYmUgYXQgbGVhc3Qgb25lIGVtcHR5IGxpbmUgYmV0d2VlbiBpbXBvcnQgZ3JvdXBzJyxcbiAgICAgICAgICBmaXg6IGZpeE5ld0xpbmVBZnRlckltcG9ydChjb250ZXh0LCBwcmV2aW91c0ltcG9ydCksXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRJbXBvcnQucmFuayA9PT0gcHJldmlvdXNJbXBvcnQucmFua1xuICAgICAgICAmJiBlbXB0eUxpbmVzQmV0d2VlbiA+IDBcbiAgICAgICAgJiYgbmV3bGluZXNCZXR3ZWVuSW1wb3J0cyAhPT0gJ2Fsd2F5cy1hbmQtaW5zaWRlLWdyb3VwcycpIHtcbiAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgIG5vZGU6IHByZXZpb3VzSW1wb3J0Lm5vZGUsXG4gICAgICAgICAgbWVzc2FnZTogJ1RoZXJlIHNob3VsZCBiZSBubyBlbXB0eSBsaW5lIHdpdGhpbiBpbXBvcnQgZ3JvdXAnLFxuICAgICAgICAgIGZpeDogcmVtb3ZlTmV3TGluZUFmdGVySW1wb3J0KGNvbnRleHQsIGN1cnJlbnRJbXBvcnQsIHByZXZpb3VzSW1wb3J0KSxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVtcHR5TGluZXNCZXR3ZWVuID4gMCkge1xuICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICBub2RlOiBwcmV2aW91c0ltcG9ydC5ub2RlLFxuICAgICAgICBtZXNzYWdlOiAnVGhlcmUgc2hvdWxkIGJlIG5vIGVtcHR5IGxpbmUgYmV0d2VlbiBpbXBvcnQgZ3JvdXBzJyxcbiAgICAgICAgZml4OiByZW1vdmVOZXdMaW5lQWZ0ZXJJbXBvcnQoY29udGV4dCwgY3VycmVudEltcG9ydCwgcHJldmlvdXNJbXBvcnQpLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBwcmV2aW91c0ltcG9ydCA9IGN1cnJlbnRJbXBvcnRcbiAgfSlcbn1cblxuZnVuY3Rpb24gZ2V0QWxwaGFiZXRpemVDb25maWcob3B0aW9ucykge1xuICBjb25zdCBhbHBoYWJldGl6ZSA9IG9wdGlvbnMuYWxwaGFiZXRpemUgfHwge31cbiAgY29uc3Qgb3JkZXIgPSBhbHBoYWJldGl6ZS5vcmRlciB8fCAnaWdub3JlJ1xuICBjb25zdCBjYXNlSW5zZW5zaXRpdmUgPSBhbHBoYWJldGl6ZS5jYXNlSW5zZW5zaXRpdmUgfHwgZmFsc2VcblxuICByZXR1cm4ge29yZGVyLCBjYXNlSW5zZW5zaXRpdmV9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIHVybDogZG9jc1VybCgnb3JkZXInKSxcbiAgICB9LFxuXG4gICAgZml4YWJsZTogJ2NvZGUnLFxuICAgIHNjaGVtYTogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGdyb3Vwczoge1xuICAgICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBhdGhHcm91cHNFeGNsdWRlZEltcG9ydFR5cGVzOiB7XG4gICAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcGF0aEdyb3Vwczoge1xuICAgICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgcGF0dGVybjoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBwYXR0ZXJuT3B0aW9uczoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBncm91cDoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICBlbnVtOiB0eXBlcyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgIGVudW06IFsnYWZ0ZXInLCAnYmVmb3JlJ10sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IFsncGF0dGVybicsICdncm91cCddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICduZXdsaW5lcy1iZXR3ZWVuJzoge1xuICAgICAgICAgICAgZW51bTogW1xuICAgICAgICAgICAgICAnaWdub3JlJyxcbiAgICAgICAgICAgICAgJ2Fsd2F5cycsXG4gICAgICAgICAgICAgICdhbHdheXMtYW5kLWluc2lkZS1ncm91cHMnLFxuICAgICAgICAgICAgICAnbmV2ZXInLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFscGhhYmV0aXplOiB7XG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IGZhbHNlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBvcmRlcjoge1xuICAgICAgICAgICAgICAgIGVudW06IFsnaWdub3JlJywgJ2FzYycsICdkZXNjJ10sXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJ2lnbm9yZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcblxuICBjcmVhdGU6IGZ1bmN0aW9uIGltcG9ydE9yZGVyUnVsZSAoY29udGV4dCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb250ZXh0Lm9wdGlvbnNbMF0gfHwge31cbiAgICBjb25zdCBuZXdsaW5lc0JldHdlZW5JbXBvcnRzID0gb3B0aW9uc1snbmV3bGluZXMtYmV0d2VlbiddIHx8ICdpZ25vcmUnXG4gICAgY29uc3QgcGF0aEdyb3Vwc0V4Y2x1ZGVkSW1wb3J0VHlwZXMgPSBuZXcgU2V0KG9wdGlvbnNbJ3BhdGhHcm91cHNFeGNsdWRlZEltcG9ydFR5cGVzJ10gfHwgWydidWlsdGluJywgJ2V4dGVybmFsJ10pXG4gICAgY29uc3QgYWxwaGFiZXRpemUgPSBnZXRBbHBoYWJldGl6ZUNvbmZpZyhvcHRpb25zKVxuICAgIGxldCByYW5rc1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgcGF0aEdyb3VwcywgbWF4UG9zaXRpb24gfSA9IGNvbnZlcnRQYXRoR3JvdXBzRm9yUmFua3Mob3B0aW9ucy5wYXRoR3JvdXBzIHx8IFtdKVxuICAgICAgcmFua3MgPSB7XG4gICAgICAgIGdyb3VwczogY29udmVydEdyb3Vwc1RvUmFua3Mob3B0aW9ucy5ncm91cHMgfHwgZGVmYXVsdEdyb3VwcyksXG4gICAgICAgIHBhdGhHcm91cHMsXG4gICAgICAgIG1heFBvc2l0aW9uLFxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBNYWxmb3JtZWQgY29uZmlndXJhdGlvblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgUHJvZ3JhbTogZnVuY3Rpb24obm9kZSkge1xuICAgICAgICAgIGNvbnRleHQucmVwb3J0KG5vZGUsIGVycm9yLm1lc3NhZ2UpXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgfVxuICAgIGxldCBpbXBvcnRlZCA9IFtdXG4gICAgbGV0IGxldmVsID0gMFxuXG4gICAgZnVuY3Rpb24gaW5jcmVtZW50TGV2ZWwoKSB7XG4gICAgICBsZXZlbCsrXG4gICAgfVxuICAgIGZ1bmN0aW9uIGRlY3JlbWVudExldmVsKCkge1xuICAgICAgbGV2ZWwtLVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBJbXBvcnREZWNsYXJhdGlvbjogZnVuY3Rpb24gaGFuZGxlSW1wb3J0cyhub2RlKSB7XG4gICAgICAgIGlmIChub2RlLnNwZWNpZmllcnMubGVuZ3RoKSB7IC8vIElnbm9yaW5nIHVuYXNzaWduZWQgaW1wb3J0c1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBub2RlLnNvdXJjZS52YWx1ZVxuICAgICAgICAgIHJlZ2lzdGVyTm9kZShcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICdpbXBvcnQnLFxuICAgICAgICAgICAgcmFua3MsXG4gICAgICAgICAgICBpbXBvcnRlZCxcbiAgICAgICAgICAgIHBhdGhHcm91cHNFeGNsdWRlZEltcG9ydFR5cGVzXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgVFNJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbjogZnVuY3Rpb24gaGFuZGxlSW1wb3J0cyhub2RlKSB7XG4gICAgICAgIGxldCBuYW1lXG4gICAgICAgIGlmIChub2RlLm1vZHVsZVJlZmVyZW5jZS50eXBlID09PSAnVFNFeHRlcm5hbE1vZHVsZVJlZmVyZW5jZScpIHtcbiAgICAgICAgICBuYW1lID0gbm9kZS5tb2R1bGVSZWZlcmVuY2UuZXhwcmVzc2lvbi52YWx1ZVxuICAgICAgICB9IGVsc2UgaWYgKG5vZGUuaXNFeHBvcnQpIHtcbiAgICAgICAgICBuYW1lID0gbm9kZS5tb2R1bGVSZWZlcmVuY2UubmFtZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5hbWUgPSBudWxsXG4gICAgICAgIH1cbiAgICAgICAgcmVnaXN0ZXJOb2RlKFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgbm9kZSxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgICdpbXBvcnQnLFxuICAgICAgICAgIHJhbmtzLFxuICAgICAgICAgIGltcG9ydGVkLFxuICAgICAgICAgIHBhdGhHcm91cHNFeGNsdWRlZEltcG9ydFR5cGVzXG4gICAgICAgIClcbiAgICAgIH0sXG4gICAgICBDYWxsRXhwcmVzc2lvbjogZnVuY3Rpb24gaGFuZGxlUmVxdWlyZXMobm9kZSkge1xuICAgICAgICBpZiAobGV2ZWwgIT09IDAgfHwgIWlzU3RhdGljUmVxdWlyZShub2RlKSB8fCAhaXNJblZhcmlhYmxlRGVjbGFyYXRvcihub2RlLnBhcmVudCkpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYW1lID0gbm9kZS5hcmd1bWVudHNbMF0udmFsdWVcbiAgICAgICAgcmVnaXN0ZXJOb2RlKFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgbm9kZSxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgICdyZXF1aXJlJyxcbiAgICAgICAgICByYW5rcyxcbiAgICAgICAgICBpbXBvcnRlZCxcbiAgICAgICAgICBwYXRoR3JvdXBzRXhjbHVkZWRJbXBvcnRUeXBlc1xuICAgICAgICApXG4gICAgICB9LFxuICAgICAgJ1Byb2dyYW06ZXhpdCc6IGZ1bmN0aW9uIHJlcG9ydEFuZFJlc2V0KCkge1xuICAgICAgICBpZiAobmV3bGluZXNCZXR3ZWVuSW1wb3J0cyAhPT0gJ2lnbm9yZScpIHtcbiAgICAgICAgICBtYWtlTmV3bGluZXNCZXR3ZWVuUmVwb3J0KGNvbnRleHQsIGltcG9ydGVkLCBuZXdsaW5lc0JldHdlZW5JbXBvcnRzKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFscGhhYmV0aXplLm9yZGVyICE9PSAnaWdub3JlJykge1xuICAgICAgICAgIG11dGF0ZVJhbmtzVG9BbHBoYWJldGl6ZShpbXBvcnRlZCwgYWxwaGFiZXRpemUpXG4gICAgICAgIH1cblxuICAgICAgICBtYWtlT3V0T2ZPcmRlclJlcG9ydChjb250ZXh0LCBpbXBvcnRlZClcblxuICAgICAgICBpbXBvcnRlZCA9IFtdXG4gICAgICB9LFxuICAgICAgRnVuY3Rpb25EZWNsYXJhdGlvbjogaW5jcmVtZW50TGV2ZWwsXG4gICAgICBGdW5jdGlvbkV4cHJlc3Npb246IGluY3JlbWVudExldmVsLFxuICAgICAgQXJyb3dGdW5jdGlvbkV4cHJlc3Npb246IGluY3JlbWVudExldmVsLFxuICAgICAgQmxvY2tTdGF0ZW1lbnQ6IGluY3JlbWVudExldmVsLFxuICAgICAgT2JqZWN0RXhwcmVzc2lvbjogaW5jcmVtZW50TGV2ZWwsXG4gICAgICAnRnVuY3Rpb25EZWNsYXJhdGlvbjpleGl0JzogZGVjcmVtZW50TGV2ZWwsXG4gICAgICAnRnVuY3Rpb25FeHByZXNzaW9uOmV4aXQnOiBkZWNyZW1lbnRMZXZlbCxcbiAgICAgICdBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbjpleGl0JzogZGVjcmVtZW50TGV2ZWwsXG4gICAgICAnQmxvY2tTdGF0ZW1lbnQ6ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICAgICAgJ09iamVjdEV4cHJlc3Npb246ZXhpdCc6IGRlY3JlbWVudExldmVsLFxuICAgIH1cbiAgfSxcbn1cbiJdfQ==