UNPKG

@kazekyo/nau-graphql-codegen-preset

Version:

A GraphQL Code Generator preset for Nau

332 lines (330 loc) 50.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transform = void 0; var _graphql = require("graphql"); var _graphqlAST = require("../utils/graphqlAST"); var _nonNullable = require("../utils/nonNullable"); function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 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 _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } 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; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } var transform = function transform(_ref) { var documentFiles = _ref.documentFiles; var fragmentDefinitions = (0, _graphqlAST.getFragmentDefinitionsByDocumentFiles)(documentFiles); var changedFragmentDefinitions = []; var files = documentFiles.map(function (file) { if (!file.document) return file; var result = addFields({ documentNode: file.document, fragmentDefinitions: fragmentDefinitions }); file.document = result.documentNode; fragmentDefinitions = result.fragmentDefinitions; changedFragmentDefinitions = mergeFragmentDefinitions(changedFragmentDefinitions, result.changedFragmentDefinitions); return file; }); files = files.map(function (file) { if (!file.document) return file; file.document = (0, _graphql.visit)(file.document, { FragmentDefinition: { leave: function leave(fragmentDefinitionNode) { var fragmentDefinition = changedFragmentDefinitions.find(function (definition) { return definition.name.value === fragmentDefinitionNode.name.value; }); if (!fragmentDefinition) return; return fragmentDefinition; } } }); return file; }); return { documentFiles: files }; }; exports.transform = transform; var addFields = function addFields(_ref2) { var documentNode = _ref2.documentNode, fragmentDefinitions = _ref2.fragmentDefinitions; var newFragmentDefinitions = fragmentDefinitions; var changedFragmentDefinitions = []; var document = (0, _graphql.visit)(documentNode, { SelectionSet: { leave: function leave(selectionSetNode) { var existsConnectionField = false; var selections = selectionSetNode.selections.map(function (selection) { if (selection.kind !== _graphql.Kind.FIELD || !selection.directives) return selection; if ((0, _graphqlAST.getDirectives)({ node: selection, directiveNames: ['pagination'] }).length === 0) return selection; existsConnectionField = true; var newFieldNode = selection; if (newFieldNode.selectionSet) { var result = transformSelectionSet({ targetFieldNames: ['edges', 'pageInfo'], selectionSet: newFieldNode.selectionSet, fragmentDefinitions: newFragmentDefinitions, canAddSelections: true }); newFragmentDefinitions = result.fragmentDefinitions; changedFragmentDefinitions = mergeFragmentDefinitions(changedFragmentDefinitions, result.changedFragmentDefinitions); if (result.hasChangedSelectionSet) { newFieldNode = _objectSpread(_objectSpread({}, newFieldNode), {}, { selectionSet: result.selectionSet }); } } newFieldNode = (0, _graphqlAST.addFieldWithoutDuplication)({ fieldNode: newFieldNode, additionalFields: [_graphqlAST.connectionIdField] }); return newFieldNode; }); if (!existsConnectionField) return; var newSelectionSetNode = (0, _graphqlAST.addFieldToSelectionSetNodeWithoutDuplication)({ selectionSetNode: _objectSpread(_objectSpread({}, selectionSetNode), {}, { selections: selections }), additionalFields: [_graphqlAST.idField, _graphqlAST.typenameField] }); return newSelectionSetNode; } } }); return { documentNode: document, fragmentDefinitions: newFragmentDefinitions, changedFragmentDefinitions: changedFragmentDefinitions }; }; var fieldNameToFieldNode = { id: _graphqlAST.idField, __typename: _graphqlAST.typenameField, node: _graphqlAST.nodeField, cursor: _graphqlAST.cursorField, pageInfo: _graphqlAST.pageInfoField }; var transformSelectionSet = function transformSelectionSet(params) { var targetFieldNames = params.targetFieldNames, canAddSelections = params.canAddSelections; var fragmentDefinitions = params.fragmentDefinitions; var selectionSet = params.selectionSet; var hasChangedSelectionSet = false; var changedFragmentDefinitions = []; var fieldsInExistence = fieldNodesInSelections({ fieldNames: targetFieldNames, selections: selectionSet.selections }); if (fieldsInExistence.length === targetFieldNames.length) { return { selectionSet: selectionSet, fragmentDefinitions: fragmentDefinitions, hasChangedSelectionSet: hasChangedSelectionSet, fieldNamesNotInExistence: [], changedFragmentDefinitions: changedFragmentDefinitions }; } var resultBasedOnSelections = transformSelectionSetBasedOnSelections({ fieldsInExistence: fieldsInExistence, selectionSet: selectionSet, fragmentDefinitions: fragmentDefinitions, canAddSelections: canAddSelections }); selectionSet = resultBasedOnSelections.selectionSet; fragmentDefinitions = resultBasedOnSelections.fragmentDefinitions; hasChangedSelectionSet = resultBasedOnSelections.hasChangedSelectionSet; changedFragmentDefinitions = resultBasedOnSelections.changedFragmentDefinitions; var resultBasedOnSpreadFragments = transformFragmentDefinitionsBasedOnSpreadFragments({ targetFieldNames: targetFieldNames, selectionSet: selectionSet, fragmentDefinitions: fragmentDefinitions }); changedFragmentDefinitions = mergeFragmentDefinitions(changedFragmentDefinitions, resultBasedOnSpreadFragments.changedFragmentDefinitions); fragmentDefinitions = resultBasedOnSpreadFragments.fragmentDefinitions; var fieldNamesNotInExistence = resultBasedOnSpreadFragments.fieldNamesNotInExistence; if (fieldNamesNotInExistence.length === 0 || !canAddSelections) { return { selectionSet: selectionSet, fragmentDefinitions: fragmentDefinitions, hasChangedSelectionSet: hasChangedSelectionSet, fieldNamesNotInExistence: fieldNamesNotInExistence, changedFragmentDefinitions: changedFragmentDefinitions }; } var newSelections = [].concat(_toConsumableArray(selectionSet.selections), _toConsumableArray(fieldNamesNotInExistence.map(function (name) { return name === 'edges' ? null : fieldNameToFieldNode[name]; }).filter(_nonNullable.nonNullable))); return { selectionSet: _objectSpread(_objectSpread({}, selectionSet), {}, { selections: newSelections }), fragmentDefinitions: fragmentDefinitions, hasChangedSelectionSet: true, fieldNamesNotInExistence: [], changedFragmentDefinitions: changedFragmentDefinitions }; }; var fieldNodesInSelections = function fieldNodesInSelections(_ref3) { var fieldNames = _ref3.fieldNames, selections = _ref3.selections; var flattenSelections = flatSelections({ selections: selections }); return flattenSelections.filter(function (selection) { return selection.kind === _graphql.Kind.FIELD && !!fieldNames.find(function (name) { return name === selection.name.value; }); }); }; var transformSelectionSetBasedOnSelections = function transformSelectionSetBasedOnSelections(params) { var fieldsInExistence = params.fieldsInExistence, selectionSet = params.selectionSet; var fragmentDefinitions = params.fragmentDefinitions; var changedFragmentDefinitions = []; var changedFieldNodes = []; fieldsInExistence.forEach(function (field) { var nextSelectionSet = field.selectionSet; if (!nextSelectionSet) return; var result; var nextFunc = function nextFunc(names) { return transformSelectionSet({ targetFieldNames: names, selectionSet: nextSelectionSet, fragmentDefinitions: fragmentDefinitions, canAddSelections: true }); }; if (field.name.value === 'edges') { result = nextFunc(['node', 'cursor']); } else if (field.name.value === 'node') { result = nextFunc(['id', '__typename']); } else if (field.name.value === 'pageInfo') { // If pageInfo exists, do not add its child fields (e.g., hasNextPage). Respect the user's writing. } if (!result) return; fragmentDefinitions = result.fragmentDefinitions; changedFragmentDefinitions = mergeFragmentDefinitions(changedFragmentDefinitions, result.changedFragmentDefinitions); if (result.hasChangedSelectionSet) { changedFieldNodes.push(_objectSpread(_objectSpread({}, field), {}, { selectionSet: result.selectionSet })); } }); if (changedFieldNodes.length === 0) { return { selectionSet: selectionSet, fragmentDefinitions: fragmentDefinitions, changedFragmentDefinitions: changedFragmentDefinitions, hasChangedSelectionSet: false, fieldsInExistence: fieldsInExistence }; } // Apply changedFieldNode to selectionSet.selections var newSelectionSet = (0, _graphql.visit)(selectionSet, { Field: { leave: function leave(field) { if (!field.loc) return; var changedFieldNode = changedFieldNodes.find(function (changedNode) { var _field$loc; return changedNode.loc && changedNode.loc.start === ((_field$loc = field.loc) === null || _field$loc === void 0 ? void 0 : _field$loc.start) && changedNode.loc.end === field.loc.end; }); if (changedFieldNode) return changedFieldNode; } } }); return { selectionSet: newSelectionSet, fragmentDefinitions: fragmentDefinitions, changedFragmentDefinitions: changedFragmentDefinitions, hasChangedSelectionSet: true, fieldsInExistence: fieldsInExistence }; }; var transformFragmentDefinitionsBasedOnSpreadFragments = function transformFragmentDefinitionsBasedOnSpreadFragments(params) { var targetFieldNames = params.targetFieldNames, selectionSet = params.selectionSet; var fragmentDefinitions = params.fragmentDefinitions; var changedFragmentDefinitions = []; var selections = flatSelections({ selections: selectionSet.selections }); var fieldNamesNotInExistence = targetFieldNames.filter(function (name) { return !selections.find(function (selection) { return selection.kind === _graphql.Kind.FIELD && selection.name.value === name; }); }); var fragmentSpreads = selections.filter(function (selection) { return selection.kind === _graphql.Kind.FRAGMENT_SPREAD; }); var foundFieldNames = []; fragmentSpreads.forEach(function (spread) { var definition = (0, _graphqlAST.getFragmentDefinitionByName)({ fragmentName: spread.name.value, fragmentDefinitions: fragmentDefinitions }); if (!definition) return; var result = transformSelectionSet({ selectionSet: definition.selectionSet, targetFieldNames: fieldNamesNotInExistence, fragmentDefinitions: fragmentDefinitions, canAddSelections: false }); fragmentDefinitions = result.fragmentDefinitions; changedFragmentDefinitions = mergeFragmentDefinitions(changedFragmentDefinitions, result.changedFragmentDefinitions); if (result.hasChangedSelectionSet) { var newFragmentDefinition = _objectSpread(_objectSpread({}, definition), {}, { selectionSet: result.selectionSet }); changedFragmentDefinitions = mergeFragmentDefinitions(changedFragmentDefinitions, [newFragmentDefinition]); replaceFragmentDefinition(fragmentDefinitions, newFragmentDefinition); } var resultFoundFieldNames = fieldNamesNotInExistence.filter(function (name) { return !result.fieldNamesNotInExistence.includes(name); }); foundFieldNames = [].concat(_toConsumableArray(foundFieldNames), _toConsumableArray(resultFoundFieldNames)); }); fieldNamesNotInExistence = fieldNamesNotInExistence.filter(function (name) { return !foundFieldNames.includes(name); }); return { fragmentDefinitions: fragmentDefinitions, fieldNamesNotInExistence: fieldNamesNotInExistence, changedFragmentDefinitions: changedFragmentDefinitions }; }; var flatSelections = function flatSelections(_ref4) { var selections = _ref4.selections; return selections.map(function (selection) { if (selection.kind !== _graphql.Kind.INLINE_FRAGMENT) return selection; return flatSelections({ selections: selection.selectionSet.selections }); }).flat(); }; var replaceFragmentDefinition = function replaceFragmentDefinition(fragmentDefinitions, newFragmentDefinition) { var index = fragmentDefinitions.findIndex(function (fragmentDefinition) { return fragmentDefinition.name.value === newFragmentDefinition.name.value; }); if (index >= 0) { fragmentDefinitions[index] = newFragmentDefinition; } }; var mergeFragmentDefinitions = function mergeFragmentDefinitions(a, b) { return [].concat(_toConsumableArray(a.filter(function (aDefinition) { return !b.find(function (bDefinition) { return bDefinition.name.value === aDefinition.name.value; }); })), _toConsumableArray(b)); }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ0cmFuc2Zvcm0iLCJkb2N1bWVudEZpbGVzIiwiZnJhZ21lbnREZWZpbml0aW9ucyIsImdldEZyYWdtZW50RGVmaW5pdGlvbnNCeURvY3VtZW50RmlsZXMiLCJjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyIsImZpbGVzIiwibWFwIiwiZmlsZSIsImRvY3VtZW50IiwicmVzdWx0IiwiYWRkRmllbGRzIiwiZG9jdW1lbnROb2RlIiwibWVyZ2VGcmFnbWVudERlZmluaXRpb25zIiwidmlzaXQiLCJGcmFnbWVudERlZmluaXRpb24iLCJsZWF2ZSIsImZyYWdtZW50RGVmaW5pdGlvbk5vZGUiLCJmcmFnbWVudERlZmluaXRpb24iLCJmaW5kIiwiZGVmaW5pdGlvbiIsIm5hbWUiLCJ2YWx1ZSIsIm5ld0ZyYWdtZW50RGVmaW5pdGlvbnMiLCJTZWxlY3Rpb25TZXQiLCJzZWxlY3Rpb25TZXROb2RlIiwiZXhpc3RzQ29ubmVjdGlvbkZpZWxkIiwic2VsZWN0aW9ucyIsInNlbGVjdGlvbiIsImtpbmQiLCJLaW5kIiwiRklFTEQiLCJkaXJlY3RpdmVzIiwiZ2V0RGlyZWN0aXZlcyIsIm5vZGUiLCJkaXJlY3RpdmVOYW1lcyIsImxlbmd0aCIsIm5ld0ZpZWxkTm9kZSIsInNlbGVjdGlvblNldCIsInRyYW5zZm9ybVNlbGVjdGlvblNldCIsInRhcmdldEZpZWxkTmFtZXMiLCJjYW5BZGRTZWxlY3Rpb25zIiwiaGFzQ2hhbmdlZFNlbGVjdGlvblNldCIsImFkZEZpZWxkV2l0aG91dER1cGxpY2F0aW9uIiwiZmllbGROb2RlIiwiYWRkaXRpb25hbEZpZWxkcyIsImNvbm5lY3Rpb25JZEZpZWxkIiwibmV3U2VsZWN0aW9uU2V0Tm9kZSIsImFkZEZpZWxkVG9TZWxlY3Rpb25TZXROb2RlV2l0aG91dER1cGxpY2F0aW9uIiwiaWRGaWVsZCIsInR5cGVuYW1lRmllbGQiLCJmaWVsZE5hbWVUb0ZpZWxkTm9kZSIsImlkIiwiX190eXBlbmFtZSIsIm5vZGVGaWVsZCIsImN1cnNvciIsImN1cnNvckZpZWxkIiwicGFnZUluZm8iLCJwYWdlSW5mb0ZpZWxkIiwicGFyYW1zIiwiZmllbGRzSW5FeGlzdGVuY2UiLCJmaWVsZE5vZGVzSW5TZWxlY3Rpb25zIiwiZmllbGROYW1lcyIsImZpZWxkTmFtZXNOb3RJbkV4aXN0ZW5jZSIsInJlc3VsdEJhc2VkT25TZWxlY3Rpb25zIiwidHJhbnNmb3JtU2VsZWN0aW9uU2V0QmFzZWRPblNlbGVjdGlvbnMiLCJyZXN1bHRCYXNlZE9uU3ByZWFkRnJhZ21lbnRzIiwidHJhbnNmb3JtRnJhZ21lbnREZWZpbml0aW9uc0Jhc2VkT25TcHJlYWRGcmFnbWVudHMiLCJuZXdTZWxlY3Rpb25zIiwiZmlsdGVyIiwibm9uTnVsbGFibGUiLCJmbGF0dGVuU2VsZWN0aW9ucyIsImZsYXRTZWxlY3Rpb25zIiwiY2hhbmdlZEZpZWxkTm9kZXMiLCJmb3JFYWNoIiwiZmllbGQiLCJuZXh0U2VsZWN0aW9uU2V0IiwibmV4dEZ1bmMiLCJuYW1lcyIsInB1c2giLCJuZXdTZWxlY3Rpb25TZXQiLCJGaWVsZCIsImxvYyIsImNoYW5nZWRGaWVsZE5vZGUiLCJjaGFuZ2VkTm9kZSIsInN0YXJ0IiwiZW5kIiwiZnJhZ21lbnRTcHJlYWRzIiwiRlJBR01FTlRfU1BSRUFEIiwiZm91bmRGaWVsZE5hbWVzIiwic3ByZWFkIiwiZ2V0RnJhZ21lbnREZWZpbml0aW9uQnlOYW1lIiwiZnJhZ21lbnROYW1lIiwibmV3RnJhZ21lbnREZWZpbml0aW9uIiwicmVwbGFjZUZyYWdtZW50RGVmaW5pdGlvbiIsInJlc3VsdEZvdW5kRmllbGROYW1lcyIsImluY2x1ZGVzIiwiSU5MSU5FX0ZSQUdNRU5UIiwiZmxhdCIsImluZGV4IiwiZmluZEluZGV4IiwiYSIsImIiLCJhRGVmaW5pdGlvbiIsImJEZWZpbml0aW9uIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyYW5zZm9ybXMvYWRkUGFnaW5hdGlvbkZpZWxkcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUeXBlcyB9IGZyb20gJ0BncmFwaHFsLWNvZGVnZW4vcGx1Z2luLWhlbHBlcnMnO1xuaW1wb3J0IHtcbiAgRG9jdW1lbnROb2RlLFxuICBGaWVsZE5vZGUsXG4gIEZyYWdtZW50RGVmaW5pdGlvbk5vZGUsXG4gIEZyYWdtZW50U3ByZWFkTm9kZSxcbiAgS2luZCxcbiAgU2VsZWN0aW9uTm9kZSxcbiAgU2VsZWN0aW9uU2V0Tm9kZSxcbiAgdmlzaXQsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHtcbiAgYWRkRmllbGRUb1NlbGVjdGlvblNldE5vZGVXaXRob3V0RHVwbGljYXRpb24sXG4gIGFkZEZpZWxkV2l0aG91dER1cGxpY2F0aW9uLFxuICBjb25uZWN0aW9uSWRGaWVsZCxcbiAgY3Vyc29yRmllbGQsXG4gIGdldERpcmVjdGl2ZXMsXG4gIGdldEZyYWdtZW50RGVmaW5pdGlvbkJ5TmFtZSxcbiAgZ2V0RnJhZ21lbnREZWZpbml0aW9uc0J5RG9jdW1lbnRGaWxlcyxcbiAgaWRGaWVsZCxcbiAgbm9kZUZpZWxkLFxuICBwYWdlSW5mb0ZpZWxkLFxuICB0eXBlbmFtZUZpZWxkLFxufSBmcm9tICcuLi91dGlscy9ncmFwaHFsQVNUJztcbmltcG9ydCB7IG5vbk51bGxhYmxlIH0gZnJvbSAnLi4vdXRpbHMvbm9uTnVsbGFibGUnO1xuXG50eXBlIENvbm5lY3Rpb25SZWxhdGVkRmllbGROYW1lID0gJ2VkZ2VzJyB8ICdub2RlJyB8ICdjdXJzb3InIHwgJ3BhZ2VJbmZvJyB8ICdpZCcgfCAnX190eXBlbmFtZSc7XG5cbmV4cG9ydCBjb25zdCB0cmFuc2Zvcm0gPSAoe1xuICBkb2N1bWVudEZpbGVzLFxufToge1xuICBkb2N1bWVudEZpbGVzOiBUeXBlcy5Eb2N1bWVudEZpbGVbXTtcbn0pOiB7IGRvY3VtZW50RmlsZXM6IFR5cGVzLkRvY3VtZW50RmlsZVtdIH0gPT4ge1xuICBsZXQgZnJhZ21lbnREZWZpbml0aW9ucyA9IGdldEZyYWdtZW50RGVmaW5pdGlvbnNCeURvY3VtZW50RmlsZXMoZG9jdW1lbnRGaWxlcyk7XG4gIGxldCBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9uczogRnJhZ21lbnREZWZpbml0aW9uTm9kZVtdID0gW107XG5cbiAgbGV0IGZpbGVzID0gZG9jdW1lbnRGaWxlcy5tYXAoKGZpbGUpID0+IHtcbiAgICBpZiAoIWZpbGUuZG9jdW1lbnQpIHJldHVybiBmaWxlO1xuICAgIGNvbnN0IHJlc3VsdCA9IGFkZEZpZWxkcyh7IGRvY3VtZW50Tm9kZTogZmlsZS5kb2N1bWVudCwgZnJhZ21lbnREZWZpbml0aW9ucyB9KTtcbiAgICBmaWxlLmRvY3VtZW50ID0gcmVzdWx0LmRvY3VtZW50Tm9kZTtcbiAgICBmcmFnbWVudERlZmluaXRpb25zID0gcmVzdWx0LmZyYWdtZW50RGVmaW5pdGlvbnM7XG4gICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMgPSBtZXJnZUZyYWdtZW50RGVmaW5pdGlvbnMoXG4gICAgICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICAgIHJlc3VsdC5jaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICApO1xuICAgIHJldHVybiBmaWxlO1xuICB9KTtcblxuICBmaWxlcyA9IGZpbGVzLm1hcCgoZmlsZSkgPT4ge1xuICAgIGlmICghZmlsZS5kb2N1bWVudCkgcmV0dXJuIGZpbGU7XG4gICAgZmlsZS5kb2N1bWVudCA9IHZpc2l0KGZpbGUuZG9jdW1lbnQsIHtcbiAgICAgIEZyYWdtZW50RGVmaW5pdGlvbjoge1xuICAgICAgICBsZWF2ZShmcmFnbWVudERlZmluaXRpb25Ob2RlKSB7XG4gICAgICAgICAgY29uc3QgZnJhZ21lbnREZWZpbml0aW9uID0gY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMuZmluZChcbiAgICAgICAgICAgIChkZWZpbml0aW9uKSA9PiBkZWZpbml0aW9uLm5hbWUudmFsdWUgPT09IGZyYWdtZW50RGVmaW5pdGlvbk5vZGUubmFtZS52YWx1ZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmICghZnJhZ21lbnREZWZpbml0aW9uKSByZXR1cm47XG4gICAgICAgICAgcmV0dXJuIGZyYWdtZW50RGVmaW5pdGlvbjtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0pO1xuXG4gIHJldHVybiB7IGRvY3VtZW50RmlsZXM6IGZpbGVzIH07XG59O1xuXG5jb25zdCBhZGRGaWVsZHMgPSAoe1xuICBkb2N1bWVudE5vZGUsXG4gIGZyYWdtZW50RGVmaW5pdGlvbnMsXG59OiB7XG4gIGRvY3VtZW50Tm9kZTogRG9jdW1lbnROb2RlO1xuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG59KToge1xuICBkb2N1bWVudE5vZGU6IERvY3VtZW50Tm9kZTtcbiAgZnJhZ21lbnREZWZpbml0aW9uczogRnJhZ21lbnREZWZpbml0aW9uTm9kZVtdO1xuICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9uczogRnJhZ21lbnREZWZpbml0aW9uTm9kZVtdO1xufSA9PiB7XG4gIGxldCBuZXdGcmFnbWVudERlZmluaXRpb25zID0gZnJhZ21lbnREZWZpbml0aW9ucztcbiAgbGV0IGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW10gPSBbXTtcblxuICBjb25zdCBkb2N1bWVudCA9IHZpc2l0KGRvY3VtZW50Tm9kZSwge1xuICAgIFNlbGVjdGlvblNldDoge1xuICAgICAgbGVhdmUoc2VsZWN0aW9uU2V0Tm9kZSkge1xuICAgICAgICBsZXQgZXhpc3RzQ29ubmVjdGlvbkZpZWxkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHNlbGVjdGlvbnMgPSBzZWxlY3Rpb25TZXROb2RlLnNlbGVjdGlvbnMubWFwKChzZWxlY3Rpb24pID0+IHtcbiAgICAgICAgICBpZiAoc2VsZWN0aW9uLmtpbmQgIT09IEtpbmQuRklFTEQgfHwgIXNlbGVjdGlvbi5kaXJlY3RpdmVzKSByZXR1cm4gc2VsZWN0aW9uO1xuICAgICAgICAgIGlmIChnZXREaXJlY3RpdmVzKHsgbm9kZTogc2VsZWN0aW9uLCBkaXJlY3RpdmVOYW1lczogWydwYWdpbmF0aW9uJ10gfSkubGVuZ3RoID09PSAwKSByZXR1cm4gc2VsZWN0aW9uO1xuXG4gICAgICAgICAgZXhpc3RzQ29ubmVjdGlvbkZpZWxkID0gdHJ1ZTtcblxuICAgICAgICAgIGxldCBuZXdGaWVsZE5vZGUgPSBzZWxlY3Rpb247XG4gICAgICAgICAgaWYgKG5ld0ZpZWxkTm9kZS5zZWxlY3Rpb25TZXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRyYW5zZm9ybVNlbGVjdGlvblNldCh7XG4gICAgICAgICAgICAgIHRhcmdldEZpZWxkTmFtZXM6IFsnZWRnZXMnLCAncGFnZUluZm8nXSxcbiAgICAgICAgICAgICAgc2VsZWN0aW9uU2V0OiBuZXdGaWVsZE5vZGUuc2VsZWN0aW9uU2V0LFxuICAgICAgICAgICAgICBmcmFnbWVudERlZmluaXRpb25zOiBuZXdGcmFnbWVudERlZmluaXRpb25zLFxuICAgICAgICAgICAgICBjYW5BZGRTZWxlY3Rpb25zOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBuZXdGcmFnbWVudERlZmluaXRpb25zID0gcmVzdWx0LmZyYWdtZW50RGVmaW5pdGlvbnM7XG4gICAgICAgICAgICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyA9IG1lcmdlRnJhZ21lbnREZWZpbml0aW9ucyhcbiAgICAgICAgICAgICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgICAgICAgICAgIHJlc3VsdC5jaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAocmVzdWx0Lmhhc0NoYW5nZWRTZWxlY3Rpb25TZXQpIHtcbiAgICAgICAgICAgICAgbmV3RmllbGROb2RlID0geyAuLi5uZXdGaWVsZE5vZGUsIHNlbGVjdGlvblNldDogcmVzdWx0LnNlbGVjdGlvblNldCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG5ld0ZpZWxkTm9kZSA9IGFkZEZpZWxkV2l0aG91dER1cGxpY2F0aW9uKHtcbiAgICAgICAgICAgIGZpZWxkTm9kZTogbmV3RmllbGROb2RlLFxuICAgICAgICAgICAgYWRkaXRpb25hbEZpZWxkczogW2Nvbm5lY3Rpb25JZEZpZWxkXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gbmV3RmllbGROb2RlO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoIWV4aXN0c0Nvbm5lY3Rpb25GaWVsZCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IG5ld1NlbGVjdGlvblNldE5vZGUgPSBhZGRGaWVsZFRvU2VsZWN0aW9uU2V0Tm9kZVdpdGhvdXREdXBsaWNhdGlvbih7XG4gICAgICAgICAgc2VsZWN0aW9uU2V0Tm9kZTogeyAuLi5zZWxlY3Rpb25TZXROb2RlLCBzZWxlY3Rpb25zIH0sXG4gICAgICAgICAgYWRkaXRpb25hbEZpZWxkczogW2lkRmllbGQsIHR5cGVuYW1lRmllbGRdLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3U2VsZWN0aW9uU2V0Tm9kZTtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBkb2N1bWVudE5vZGU6IGRvY3VtZW50LFxuICAgIGZyYWdtZW50RGVmaW5pdGlvbnM6IG5ld0ZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnM6IGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zLFxuICB9O1xufTtcblxuY29uc3QgZmllbGROYW1lVG9GaWVsZE5vZGU6IHsgW2tleSBpbiBFeGNsdWRlPENvbm5lY3Rpb25SZWxhdGVkRmllbGROYW1lLCAnZWRnZXMnPl06IEZpZWxkTm9kZSB9ID0ge1xuICBpZDogaWRGaWVsZCxcbiAgX190eXBlbmFtZTogdHlwZW5hbWVGaWVsZCxcbiAgbm9kZTogbm9kZUZpZWxkLFxuICBjdXJzb3I6IGN1cnNvckZpZWxkLFxuICBwYWdlSW5mbzogcGFnZUluZm9GaWVsZCxcbn07XG5cbmNvbnN0IHRyYW5zZm9ybVNlbGVjdGlvblNldCA9IChwYXJhbXM6IHtcbiAgdGFyZ2V0RmllbGROYW1lczogQ29ubmVjdGlvblJlbGF0ZWRGaWVsZE5hbWVbXTtcbiAgc2VsZWN0aW9uU2V0OiBTZWxlY3Rpb25TZXROb2RlO1xuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG4gIGNhbkFkZFNlbGVjdGlvbnM6IGJvb2xlYW47XG59KToge1xuICBzZWxlY3Rpb25TZXQ6IFNlbGVjdGlvblNldE5vZGU7XG4gIGZyYWdtZW50RGVmaW5pdGlvbnM6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGVbXTtcbiAgaGFzQ2hhbmdlZFNlbGVjdGlvblNldDogYm9vbGVhbjtcbiAgZmllbGROYW1lc05vdEluRXhpc3RlbmNlOiBDb25uZWN0aW9uUmVsYXRlZEZpZWxkTmFtZVtdO1xuICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9uczogRnJhZ21lbnREZWZpbml0aW9uTm9kZVtdO1xufSA9PiB7XG4gIGNvbnN0IHsgdGFyZ2V0RmllbGROYW1lcywgY2FuQWRkU2VsZWN0aW9ucyB9ID0gcGFyYW1zO1xuICBsZXQgZnJhZ21lbnREZWZpbml0aW9ucyA9IHBhcmFtcy5mcmFnbWVudERlZmluaXRpb25zO1xuICBsZXQgc2VsZWN0aW9uU2V0ID0gcGFyYW1zLnNlbGVjdGlvblNldDtcbiAgbGV0IGhhc0NoYW5nZWRTZWxlY3Rpb25TZXQgPSBmYWxzZTtcbiAgbGV0IGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW10gPSBbXTtcblxuICBjb25zdCBmaWVsZHNJbkV4aXN0ZW5jZSA9IGZpZWxkTm9kZXNJblNlbGVjdGlvbnMoe1xuICAgIGZpZWxkTmFtZXM6IHRhcmdldEZpZWxkTmFtZXMsXG4gICAgc2VsZWN0aW9uczogc2VsZWN0aW9uU2V0LnNlbGVjdGlvbnMsXG4gIH0pO1xuICBpZiAoZmllbGRzSW5FeGlzdGVuY2UubGVuZ3RoID09PSB0YXJnZXRGaWVsZE5hbWVzLmxlbmd0aCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZWxlY3Rpb25TZXQsXG4gICAgICBmcmFnbWVudERlZmluaXRpb25zLFxuICAgICAgaGFzQ2hhbmdlZFNlbGVjdGlvblNldCxcbiAgICAgIGZpZWxkTmFtZXNOb3RJbkV4aXN0ZW5jZTogW10sXG4gICAgICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcmVzdWx0QmFzZWRPblNlbGVjdGlvbnMgPSB0cmFuc2Zvcm1TZWxlY3Rpb25TZXRCYXNlZE9uU2VsZWN0aW9ucyh7XG4gICAgZmllbGRzSW5FeGlzdGVuY2UsXG4gICAgc2VsZWN0aW9uU2V0LFxuICAgIGZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgY2FuQWRkU2VsZWN0aW9ucyxcbiAgfSk7XG4gIHNlbGVjdGlvblNldCA9IHJlc3VsdEJhc2VkT25TZWxlY3Rpb25zLnNlbGVjdGlvblNldDtcbiAgZnJhZ21lbnREZWZpbml0aW9ucyA9IHJlc3VsdEJhc2VkT25TZWxlY3Rpb25zLmZyYWdtZW50RGVmaW5pdGlvbnM7XG4gIGhhc0NoYW5nZWRTZWxlY3Rpb25TZXQgPSByZXN1bHRCYXNlZE9uU2VsZWN0aW9ucy5oYXNDaGFuZ2VkU2VsZWN0aW9uU2V0O1xuICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyA9IHJlc3VsdEJhc2VkT25TZWxlY3Rpb25zLmNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zO1xuXG4gIGNvbnN0IHJlc3VsdEJhc2VkT25TcHJlYWRGcmFnbWVudHMgPSB0cmFuc2Zvcm1GcmFnbWVudERlZmluaXRpb25zQmFzZWRPblNwcmVhZEZyYWdtZW50cyh7XG4gICAgdGFyZ2V0RmllbGROYW1lcyxcbiAgICBzZWxlY3Rpb25TZXQsXG4gICAgZnJhZ21lbnREZWZpbml0aW9ucyxcbiAgfSk7XG4gIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zID0gbWVyZ2VGcmFnbWVudERlZmluaXRpb25zKFxuICAgIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zLFxuICAgIHJlc3VsdEJhc2VkT25TcHJlYWRGcmFnbWVudHMuY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICk7XG4gIGZyYWdtZW50RGVmaW5pdGlvbnMgPSByZXN1bHRCYXNlZE9uU3ByZWFkRnJhZ21lbnRzLmZyYWdtZW50RGVmaW5pdGlvbnM7XG4gIGNvbnN0IGZpZWxkTmFtZXNOb3RJbkV4aXN0ZW5jZSA9IHJlc3VsdEJhc2VkT25TcHJlYWRGcmFnbWVudHMuZmllbGROYW1lc05vdEluRXhpc3RlbmNlO1xuXG4gIGlmIChmaWVsZE5hbWVzTm90SW5FeGlzdGVuY2UubGVuZ3RoID09PSAwIHx8ICFjYW5BZGRTZWxlY3Rpb25zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlbGVjdGlvblNldCxcbiAgICAgIGZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgICBoYXNDaGFuZ2VkU2VsZWN0aW9uU2V0LFxuICAgICAgZmllbGROYW1lc05vdEluRXhpc3RlbmNlLFxuICAgICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IG5ld1NlbGVjdGlvbnMgPSBbXG4gICAgLi4uc2VsZWN0aW9uU2V0LnNlbGVjdGlvbnMsXG4gICAgLi4uZmllbGROYW1lc05vdEluRXhpc3RlbmNlXG4gICAgICAubWFwKChuYW1lKSA9PiAobmFtZSA9PT0gJ2VkZ2VzJyA/IG51bGwgOiBmaWVsZE5hbWVUb0ZpZWxkTm9kZVtuYW1lXSkpXG4gICAgICAuZmlsdGVyKG5vbk51bGxhYmxlKSxcbiAgXTtcbiAgcmV0dXJuIHtcbiAgICBzZWxlY3Rpb25TZXQ6IHsgLi4uc2VsZWN0aW9uU2V0LCBzZWxlY3Rpb25zOiBuZXdTZWxlY3Rpb25zIH0sXG4gICAgZnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICBoYXNDaGFuZ2VkU2VsZWN0aW9uU2V0OiB0cnVlLFxuICAgIGZpZWxkTmFtZXNOb3RJbkV4aXN0ZW5jZTogW10sXG4gICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gIH07XG59O1xuXG5jb25zdCBmaWVsZE5vZGVzSW5TZWxlY3Rpb25zID0gKHtcbiAgZmllbGROYW1lcyxcbiAgc2VsZWN0aW9ucyxcbn06IHtcbiAgZmllbGROYW1lczogQ29ubmVjdGlvblJlbGF0ZWRGaWVsZE5hbWVbXTtcbiAgc2VsZWN0aW9uczogcmVhZG9ubHkgU2VsZWN0aW9uTm9kZVtdO1xufSkgPT4ge1xuICBjb25zdCBmbGF0dGVuU2VsZWN0aW9ucyA9IGZsYXRTZWxlY3Rpb25zKHsgc2VsZWN0aW9uczogc2VsZWN0aW9ucyB9KTtcbiAgcmV0dXJuIGZsYXR0ZW5TZWxlY3Rpb25zLmZpbHRlcihcbiAgICAoc2VsZWN0aW9uKTogc2VsZWN0aW9uIGlzIEZpZWxkTm9kZSA9PlxuICAgICAgc2VsZWN0aW9uLmtpbmQgPT09IEtpbmQuRklFTEQgJiYgISFmaWVsZE5hbWVzLmZpbmQoKG5hbWUpID0+IG5hbWUgPT09IHNlbGVjdGlvbi5uYW1lLnZhbHVlKSxcbiAgKTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybVNlbGVjdGlvblNldEJhc2VkT25TZWxlY3Rpb25zID0gKHBhcmFtczoge1xuICBzZWxlY3Rpb25TZXQ6IFNlbGVjdGlvblNldE5vZGU7XG4gIGZpZWxkc0luRXhpc3RlbmNlOiBGaWVsZE5vZGVbXTtcbiAgZnJhZ21lbnREZWZpbml0aW9uczogRnJhZ21lbnREZWZpbml0aW9uTm9kZVtdO1xuICBjYW5BZGRTZWxlY3Rpb25zOiBib29sZWFuO1xufSk6IHtcbiAgc2VsZWN0aW9uU2V0OiBTZWxlY3Rpb25TZXROb2RlO1xuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG4gIGhhc0NoYW5nZWRTZWxlY3Rpb25TZXQ6IGJvb2xlYW47XG4gIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG4gIGZpZWxkc0luRXhpc3RlbmNlOiBGaWVsZE5vZGVbXTtcbn0gPT4ge1xuICBjb25zdCB7IGZpZWxkc0luRXhpc3RlbmNlLCBzZWxlY3Rpb25TZXQgfSA9IHBhcmFtcztcbiAgbGV0IGZyYWdtZW50RGVmaW5pdGlvbnMgPSBwYXJhbXMuZnJhZ21lbnREZWZpbml0aW9ucztcbiAgbGV0IGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW10gPSBbXTtcblxuICBjb25zdCBjaGFuZ2VkRmllbGROb2RlczogRmllbGROb2RlW10gPSBbXTtcblxuICBmaWVsZHNJbkV4aXN0ZW5jZS5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgIGNvbnN0IG5leHRTZWxlY3Rpb25TZXQgPSBmaWVsZC5zZWxlY3Rpb25TZXQ7XG4gICAgaWYgKCFuZXh0U2VsZWN0aW9uU2V0KSByZXR1cm47XG4gICAgbGV0IHJlc3VsdDogUmV0dXJuVHlwZTx0eXBlb2YgdHJhbnNmb3JtU2VsZWN0aW9uU2V0PiB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBuZXh0RnVuYyA9IChuYW1lczogQ29ubmVjdGlvblJlbGF0ZWRGaWVsZE5hbWVbXSkgPT5cbiAgICAgIHRyYW5zZm9ybVNlbGVjdGlvblNldCh7XG4gICAgICAgIHRhcmdldEZpZWxkTmFtZXM6IG5hbWVzLFxuICAgICAgICBzZWxlY3Rpb25TZXQ6IG5leHRTZWxlY3Rpb25TZXQsXG4gICAgICAgIGZyYWdtZW50RGVmaW5pdGlvbnM6IGZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgICAgIGNhbkFkZFNlbGVjdGlvbnM6IHRydWUsXG4gICAgICB9KTtcblxuICAgIGlmIChmaWVsZC5uYW1lLnZhbHVlID09PSAnZWRnZXMnKSB7XG4gICAgICByZXN1bHQgPSBuZXh0RnVuYyhbJ25vZGUnLCAnY3Vyc29yJ10pO1xuICAgIH0gZWxzZSBpZiAoZmllbGQubmFtZS52YWx1ZSA9PT0gJ25vZGUnKSB7XG4gICAgICByZXN1bHQgPSBuZXh0RnVuYyhbJ2lkJywgJ19fdHlwZW5hbWUnXSk7XG4gICAgfSBlbHNlIGlmIChmaWVsZC5uYW1lLnZhbHVlID09PSAncGFnZUluZm8nKSB7XG4gICAgICAvLyBJZiBwYWdlSW5mbyBleGlzdHMsIGRvIG5vdCBhZGQgaXRzIGNoaWxkIGZpZWxkcyAoZS5nLiwgaGFzTmV4dFBhZ2UpLiBSZXNwZWN0IHRoZSB1c2VyJ3Mgd3JpdGluZy5cbiAgICB9XG5cbiAgICBpZiAoIXJlc3VsdCkgcmV0dXJuO1xuXG4gICAgZnJhZ21lbnREZWZpbml0aW9ucyA9IHJlc3VsdC5mcmFnbWVudERlZmluaXRpb25zO1xuICAgIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zID0gbWVyZ2VGcmFnbWVudERlZmluaXRpb25zKFxuICAgICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgICByZXN1bHQuY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgKTtcbiAgICBpZiAocmVzdWx0Lmhhc0NoYW5nZWRTZWxlY3Rpb25TZXQpIHtcbiAgICAgIGNoYW5nZWRGaWVsZE5vZGVzLnB1c2goeyAuLi5maWVsZCwgc2VsZWN0aW9uU2V0OiByZXN1bHQuc2VsZWN0aW9uU2V0IH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKGNoYW5nZWRGaWVsZE5vZGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZWxlY3Rpb25TZXQsXG4gICAgICBmcmFnbWVudERlZmluaXRpb25zLFxuICAgICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgICBoYXNDaGFuZ2VkU2VsZWN0aW9uU2V0OiBmYWxzZSxcbiAgICAgIGZpZWxkc0luRXhpc3RlbmNlLFxuICAgIH07XG4gIH1cblxuICAvLyBBcHBseSBjaGFuZ2VkRmllbGROb2RlIHRvIHNlbGVjdGlvblNldC5zZWxlY3Rpb25zXG4gIGNvbnN0IG5ld1NlbGVjdGlvblNldCA9IHZpc2l0KHNlbGVjdGlvblNldCwge1xuICAgIEZpZWxkOiB7XG4gICAgICBsZWF2ZShmaWVsZCkge1xuICAgICAgICBpZiAoIWZpZWxkLmxvYykgcmV0dXJuO1xuICAgICAgICBjb25zdCBjaGFuZ2VkRmllbGROb2RlID0gY2hhbmdlZEZpZWxkTm9kZXMuZmluZChcbiAgICAgICAgICAoY2hhbmdlZE5vZGUpID0+XG4gICAgICAgICAgICBjaGFuZ2VkTm9kZS5sb2MgJiYgY2hhbmdlZE5vZGUubG9jLnN0YXJ0ID09PSBmaWVsZC5sb2M/LnN0YXJ0ICYmIGNoYW5nZWROb2RlLmxvYy5lbmQgPT09IGZpZWxkLmxvYy5lbmQsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChjaGFuZ2VkRmllbGROb2RlKSByZXR1cm4gY2hhbmdlZEZpZWxkTm9kZTtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBzZWxlY3Rpb25TZXQ6IG5ld1NlbGVjdGlvblNldCxcbiAgICBmcmFnbWVudERlZmluaXRpb25zLFxuICAgIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zLFxuICAgIGhhc0NoYW5nZWRTZWxlY3Rpb25TZXQ6IHRydWUsXG4gICAgZmllbGRzSW5FeGlzdGVuY2UsXG4gIH07XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1GcmFnbWVudERlZmluaXRpb25zQmFzZWRPblNwcmVhZEZyYWdtZW50cyA9IChwYXJhbXM6IHtcbiAgdGFyZ2V0RmllbGROYW1lczogQ29ubmVjdGlvblJlbGF0ZWRGaWVsZE5hbWVbXTtcbiAgc2VsZWN0aW9uU2V0OiBTZWxlY3Rpb25TZXROb2RlO1xuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG59KToge1xuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG4gIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG4gIGZpZWxkTmFtZXNOb3RJbkV4aXN0ZW5jZTogQ29ubmVjdGlvblJlbGF0ZWRGaWVsZE5hbWVbXTtcbn0gPT4ge1xuICBjb25zdCB7IHRhcmdldEZpZWxkTmFtZXMsIHNlbGVjdGlvblNldCB9ID0gcGFyYW1zO1xuICBsZXQgZnJhZ21lbnREZWZpbml0aW9ucyA9IHBhcmFtcy5mcmFnbWVudERlZmluaXRpb25zO1xuICBsZXQgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnM6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGVbXSA9IFtdO1xuXG4gIGNvbnN0IHNlbGVjdGlvbnMgPSBmbGF0U2VsZWN0aW9ucyh7IHNlbGVjdGlvbnM6IHNlbGVjdGlvblNldC5zZWxlY3Rpb25zIH0pO1xuICBsZXQgZmllbGROYW1lc05vdEluRXhpc3RlbmNlID0gdGFyZ2V0RmllbGROYW1lcy5maWx0ZXIoXG4gICAgKG5hbWUpID0+ICFzZWxlY3Rpb25zLmZpbmQoKHNlbGVjdGlvbikgPT4gc2VsZWN0aW9uLmtpbmQgPT09IEtpbmQuRklFTEQgJiYgc2VsZWN0aW9uLm5hbWUudmFsdWUgPT09IG5hbWUpLFxuICApO1xuXG4gIGNvbnN0IGZyYWdtZW50U3ByZWFkcyA9IHNlbGVjdGlvbnMuZmlsdGVyKFxuICAgIChzZWxlY3Rpb24pOiBzZWxlY3Rpb24gaXMgRnJhZ21lbnRTcHJlYWROb2RlID0+IHNlbGVjdGlvbi5raW5kID09PSBLaW5kLkZSQUdNRU5UX1NQUkVBRCxcbiAgKTtcbiAgbGV0IGZvdW5kRmllbGROYW1lczogQ29ubmVjdGlvblJlbGF0ZWRGaWVsZE5hbWVbXSA9IFtdO1xuICBmcmFnbWVudFNwcmVhZHMuZm9yRWFjaCgoc3ByZWFkKSA9PiB7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IGdldEZyYWdtZW50RGVmaW5pdGlvbkJ5TmFtZSh7IGZyYWdtZW50TmFtZTogc3ByZWFkLm5hbWUudmFsdWUsIGZyYWdtZW50RGVmaW5pdGlvbnMgfSk7XG4gICAgaWYgKCFkZWZpbml0aW9uKSByZXR1cm47XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtU2VsZWN0aW9uU2V0KHtcbiAgICAgIHNlbGVjdGlvblNldDogZGVmaW5pdGlvbi5zZWxlY3Rpb25TZXQsXG4gICAgICB0YXJnZXRGaWVsZE5hbWVzOiBmaWVsZE5hbWVzTm90SW5FeGlzdGVuY2UsXG4gICAgICBmcmFnbWVudERlZmluaXRpb25zLFxuICAgICAgY2FuQWRkU2VsZWN0aW9uczogZmFsc2UsXG4gICAgfSk7XG4gICAgZnJhZ21lbnREZWZpbml0aW9ucyA9IHJlc3VsdC5mcmFnbWVudERlZmluaXRpb25zO1xuICAgIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zID0gbWVyZ2VGcmFnbWVudERlZmluaXRpb25zKFxuICAgICAgY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgICByZXN1bHQuY2hhbmdlZEZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgKTtcbiAgICBpZiAocmVzdWx0Lmhhc0NoYW5nZWRTZWxlY3Rpb25TZXQpIHtcbiAgICAgIGNvbnN0IG5ld0ZyYWdtZW50RGVmaW5pdGlvbiA9IHsgLi4uZGVmaW5pdGlvbiwgc2VsZWN0aW9uU2V0OiByZXN1bHQuc2VsZWN0aW9uU2V0IH07XG4gICAgICBjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucyA9IG1lcmdlRnJhZ21lbnREZWZpbml0aW9ucyhjaGFuZ2VkRnJhZ21lbnREZWZpbml0aW9ucywgW25ld0ZyYWdtZW50RGVmaW5pdGlvbl0pO1xuICAgICAgcmVwbGFjZUZyYWdtZW50RGVmaW5pdGlvbihmcmFnbWVudERlZmluaXRpb25zLCBuZXdGcmFnbWVudERlZmluaXRpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdEZvdW5kRmllbGROYW1lcyA9IGZpZWxkTmFtZXNOb3RJbkV4aXN0ZW5jZS5maWx0ZXIoXG4gICAgICAobmFtZSkgPT4gIXJlc3VsdC5maWVsZE5hbWVzTm90SW5FeGlzdGVuY2UuaW5jbHVkZXMobmFtZSksXG4gICAgKTtcbiAgICBmb3VuZEZpZWxkTmFtZXMgPSBbLi4uZm91bmRGaWVsZE5hbWVzLCAuLi5yZXN1bHRGb3VuZEZpZWxkTmFtZXNdO1xuICB9KTtcblxuICBmaWVsZE5hbWVzTm90SW5FeGlzdGVuY2UgPSBmaWVsZE5hbWVzTm90SW5FeGlzdGVuY2UuZmlsdGVyKChuYW1lKSA9PiAhZm91bmRGaWVsZE5hbWVzLmluY2x1ZGVzKG5hbWUpKTtcblxuICByZXR1cm4ge1xuICAgIGZyYWdtZW50RGVmaW5pdGlvbnMsXG4gICAgZmllbGROYW1lc05vdEluRXhpc3RlbmNlLFxuICAgIGNoYW5nZWRGcmFnbWVudERlZmluaXRpb25zLFxuICB9O1xufTtcblxuY29uc3QgZmxhdFNlbGVjdGlvbnMgPSAoeyBzZWxlY3Rpb25zIH06IHsgc2VsZWN0aW9uczogcmVhZG9ubHkgU2VsZWN0aW9uTm9kZVtdIH0pOiBTZWxlY3Rpb25Ob2RlW10gPT4ge1xuICByZXR1cm4gc2VsZWN0aW9uc1xuICAgIC5tYXAoKHNlbGVjdGlvbikgPT4ge1xuICAgICAgaWYgKHNlbGVjdGlvbi5raW5kICE9PSBLaW5kLklOTElORV9GUkFHTUVOVCkgcmV0dXJuIHNlbGVjdGlvbjtcbiAgICAgIHJldHVybiBmbGF0U2VsZWN0aW9ucyh7IHNlbGVjdGlvbnM6IHNlbGVjdGlvbi5zZWxlY3Rpb25TZXQuc2VsZWN0aW9ucyB9KTtcbiAgICB9KVxuICAgIC5mbGF0KCk7XG59O1xuXG5jb25zdCByZXBsYWNlRnJhZ21lbnREZWZpbml0aW9uID0gKFxuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW10sXG4gIG5ld0ZyYWdtZW50RGVmaW5pdGlvbjogRnJhZ21lbnREZWZpbml0aW9uTm9kZSxcbik6IHZvaWQgPT4ge1xuICBjb25zdCBpbmRleCA9IGZyYWdtZW50RGVmaW5pdGlvbnMuZmluZEluZGV4KFxuICAgIChmcmFnbWVudERlZmluaXRpb24pID0+IGZyYWdtZW50RGVmaW5pdGlvbi5uYW1lLnZhbHVlID09PSBuZXdGcmFnbWVudERlZmluaXRpb24ubmFtZS52YWx1ZSxcbiAgKTtcbiAgaWYgKGluZGV4ID49IDApIHtcbiAgICBmcmFnbWVudERlZmluaXRpb25zW2luZGV4XSA9IG5ld0ZyYWdtZW50RGVmaW5pdGlvbjtcbiAgfVxufTtcblxuY29uc3QgbWVyZ2VGcmFnbWVudERlZmluaXRpb25zID0gKFxuICBhOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW10sXG4gIGI6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGVbXSxcbik6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGVbXSA9PiB7XG4gIHJldHVybiBbXG4gICAgLy8gUmVtb3ZlIHNhbWUgbmFtZSBmcmFnbWVudHNcbiAgICAuLi5hLmZpbHRlcigoYURlZmluaXRpb24pID0+ICFiLmZpbmQoKGJEZWZpbml0aW9uKSA9PiBiRGVmaW5pdGlvbi5uYW1lLnZhbHVlID09PSBhRGVmaW5pdGlvbi5uYW1lLnZhbHVlKSksXG4gICAgLi4uYixcbiAgXTtcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBO0FBVUE7QUFhQTtBQUFtRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFJNUMsSUFBTUEsU0FBUyxHQUFHLFNBQVpBLFNBQVMsT0FJeUI7RUFBQSxJQUg3Q0MsYUFBYSxRQUFiQSxhQUFhO0VBSWIsSUFBSUMsbUJBQW1CLEdBQUcsSUFBQUMsaURBQXFDLEVBQUNGLGFBQWEsQ0FBQztFQUM5RSxJQUFJRywwQkFBb0QsR0FBRyxFQUFFO0VBRTdELElBQUlDLEtBQUssR0FBR0osYUFBYSxDQUFDSyxHQUFHLENBQUMsVUFBQ0MsSUFBSSxFQUFLO0lBQ3RDLElBQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFRLEVBQUUsT0FBT0QsSUFBSTtJQUMvQixJQUFNRSxNQUFNLEdBQUdDLFNBQVMsQ0FBQztNQUFFQyxZQUFZLEVBQUVKLElBQUksQ0FBQ0MsUUFBUTtNQUFFTixtQkFBbUIsRUFBbkJBO0lBQW9CLENBQUMsQ0FBQztJQUM5RUssSUFBSSxDQUFDQyxRQUFRLEdBQUdDLE1BQU0sQ0FBQ0UsWUFBWTtJQUNuQ1QsbUJBQW1CLEdBQUdPLE1BQU0sQ0FBQ1AsbUJBQW1CO0lBQ2hERSwwQkFBMEIsR0FBR1Esd0JBQXdCLENBQ25EUiwwQkFBMEIsRUFDMUJLLE1BQU0sQ0FBQ0wsMEJBQTBCLENBQ2xDO0lBQ0QsT0FBT0csSUFBSTtFQUNiLENBQUMsQ0FBQztFQUVGRixLQUFLLEdBQUdBLEtBQUssQ0FBQ0MsR0FBRyxDQUFDLFVBQUNDLElBQUksRUFBSztJQUMxQixJQUFJLENBQUNBLElBQUksQ0FBQ0MsUUFBUSxFQUFFLE9BQU9ELElBQUk7SUFDL0JBLElBQUksQ0FBQ0MsUUFBUSxHQUFHLElBQUFLLGNBQUssRUFBQ04sSUFBSSxDQUFDQyxRQUFRLEVBQUU7TUFDbkNNLGtCQUFrQixFQUFFO1FBQ2xCQyxLQUFLLGlCQUFDQyxzQkFBc0IsRUFBRTtVQUM1QixJQUFNQyxrQkFBa0IsR0FBR2IsMEJBQTBCLENBQUNjLElBQUksQ0FDeEQsVUFBQ0MsVUFBVTtZQUFBLE9BQUtBLFVBQVUsQ0FBQ0MsSUFBSSxDQUFDQyxLQUFLLEtBQUtMLHNCQUFzQixDQUFDSSxJQUFJLENBQUNDLEtBQUs7VUFBQSxFQUM1RTtVQUNELElBQUksQ0FBQ0osa0JBQWtCLEVBQUU7VUFDekIsT0FBT0Esa0JBQWtCO1FBQzNCO01BQ0Y7SUFDRixDQUFDLENBQUM7SUFDRixPQUFPVixJQUFJO0VBQ2IsQ0FBQyxDQUFDO0VBRUYsT0FBTztJQUFFTixhQUFhLEVBQUVJO0VBQU0sQ0FBQztBQUNqQyxDQUFDO0FBQUM7QUFFRixJQUFNSyxTQUFTLEdBQUcsU0FBWkEsU0FBUyxRQVVWO0VBQUEsSUFUSEMsWUFBWSxTQUFaQSxZQUFZO0lBQ1pULG1CQUFtQixTQUFuQkEsbUJBQW1CO0VBU25CLElBQUlvQixzQkFBc0IsR0FBR3BCLG1CQUFtQjtFQUNoRCxJQUFJRSwwQkFBb0QsR0FBRyxFQUFFO0VBRTdELElBQU1JLFFBQVEsR0FBRyxJQUFBSyxjQUFLLEVBQUNGLFlBQVksRUFBRTtJQUNuQ1ksWUFBWSxFQUFFO01BQ1pSLEtBQUssaUJBQUNTLGdCQUFnQixFQUFFO1FBQ3RCLElBQUlDLHFCQUFxQixHQUFHLEtBQUs7UUFDakMsSUFBTUMsVUFBVSxHQUFHRixnQkFBZ0IsQ0FBQ0UsVUFBVSxDQUFDcEIsR0FBRyxDQUFDLFVBQUNxQixTQUFTLEVBQUs7VUFDaEUsSUFBSUEsU0FBUyxDQUFDQyxJQUFJLEtBQUtDLGFBQUksQ0FBQ0MsS0FBSyxJQUFJLENBQUNILFNBQVMsQ0FBQ0ksVUFBVSxFQUFFLE9BQU9KLFNBQVM7VUFDNUUsSUFBSSxJQUFBSyx5QkFBYSxFQUFDO1lBQUVDLElBQUksRUFBRU4sU0FBUztZQUFFTyxjQUFjLEVBQUUsQ0FBQyxZQUFZO1VBQUUsQ0FBQyxDQUFDLENBQUNDLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBT1IsU0FBUztVQUVyR0YscUJBQXFCLEdBQUcsSUFBSTtVQUU1QixJQUFJVyxZQUFZLEdBQUdULFNBQVM7VUFDNUIsSUFBSVMsWUFBWSxDQUFDQyxZQUFZLEVBQUU7WUFDN0IsSUFBTTVCLE1BQU0sR0FBRzZCLHFCQUFxQixDQUFDO2NBQ25DQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUM7Y0FDdkNGLFlBQVksRUFBRUQsWUFBWSxDQUFDQyxZQUFZO2NBQ3ZDbkMsbUJBQW1CLEVBQUVvQixzQkFBc0I7Y0FDM0NrQixnQkFBZ0IsRUFBRTtZQUNwQixDQUFDLENBQUM7WUFDRmxCLHNCQUFzQixHQUFHYixNQUFNLENBQUNQLG1CQUFtQjtZQUNuREUsMEJBQTBCLEdBQUdRLHdCQUF3QixDQUNuRFIsMEJBQTBCLEVBQzFCSyxNQUFNLENBQUNMLDBCQUEwQixDQUNsQztZQUNELElBQUlLLE1BQU0sQ0FBQ2dDLHNCQUFzQixFQUFFO2NBQ2pDTCxZQUFZLG1DQUFRQSxZQUFZO2dCQUFFQyxZQUFZLEVBQUU1QixNQUFNLENBQUM0QjtjQUFZLEVBQUU7WUFDdkU7VUFDRjtVQUVBRCxZQUFZLEdBQUcsSUFBQU0sc0NBQTBCLEVBQUM7WUFDeENDLFNBQVMsRUFBRVAsWUFBWTtZQUN2QlEsZ0JBQWdCLEVBQUUsQ0FBQ0MsNkJBQWlCO1VBQ3RDLENBQUMsQ0FBQztVQUNGLE9BQU9ULFlBQVk7UUFDckIsQ0FBQyxDQUFDO1FBRUYsSUFBSSxDQUFDWCxxQkFBcUIsRUFBRTtRQUU1QixJQUFNcUIsbUJBQW1CLEdBQUcsSUFBQUMsd0RBQTRDLEVBQUM7VUFDdkV2QixnQkFBZ0Isa0NBQU9BLGdCQUFnQjtZQUFFRSxVQUFVLEVBQVZBO1VBQVUsRUFBRTtVQUNyRGtCLGdCQUFnQixFQUFFLENBQUNJLG1CQUFPLEVBQUVDLHlCQUFhO1FBQzNDLENBQUMsQ0FBQztRQUVGLE9BQU9ILG1CQUFtQjtNQUM1QjtJQUNGO0VBQ0YsQ0FBQyxDQUFDO0VBRUYsT0FBTztJQUNMbkMsWUFBWSxFQUFFSCxRQUFRO0lBQ3RCTixtQkFBbUIsRUFBRW9CLHNCQUFzQjtJQUMzQ2xCLDBCQUEwQixFQUFFQTtFQUM5QixDQUFDO0FBQ0gsQ0FBQztBQUVELElBQU04QyxvQkFBMEYsR0FBRztFQUNqR0MsRUFBRSxFQUFFSCxtQkFBTztFQUNYSSxVQUFVLEVBQUVILHlCQUFhO0VBQ3pCaEIsSUFBSSxFQUFFb0IscUJBQVM7RUFDZkMsTUFBTSxFQUFFQyx1QkFBVztFQUNuQkMsUUFBUSxFQUFFQztBQUNaLENBQUM7QUFFRCxJQUFNbkIscUJBQXFCLEdBQUcsU0FBeEJBLHFCQUFxQixDQUFJb0IsTUFLOUIsRUFNSTtFQUNILElBQVFuQixnQkFBZ0IsR0FBdUJtQixNQUFNLENBQTdDbkIsZ0JBQWdCO0lBQUVDLGdCQUFnQixHQUFLa0IsTUFBTSxDQUEzQmxCLGdCQUFnQjtFQUMxQyxJQUFJdEMsbUJBQW1CLEdBQUd3RCxNQUFNLENBQUN4RCxtQkFBbUI7RUFDcEQsSUFBSW1DLFlBQVksR0FBR3FCLE1BQU0sQ0FBQ3JCLFlBQVk7RUFDdEMsSUFBSUksc0JBQXNCLEdBQUcsS0FBSztFQUNsQyxJQUFJckMsMEJBQW9ELEdBQUcsRUFBRTtFQUU3RCxJQUFNdUQsaUJBQWlCLEdBQUdDLHNCQUFzQixDQUFDO0lBQy9DQyxVQUFVLEVBQUV0QixnQkFBZ0I7SUFDNUJiLFVBQVUsRUFBRVcsWUFBWSxDQUFDWDtFQUMzQixDQUFDLENBQUM7RUFDRixJQUFJaUMsaUJBQWlCLENBQUN4QixNQUFNLEtBQUtJLGdCQUFnQixDQUFDSixNQUFNLEVBQUU7SUFDeEQsT0FBTztNQUNMRSxZQUFZLEVBQVpBLFlBQVk7TUFDWm5DLG1CQUFtQixFQUFuQkEsbUJBQW1CO01BQ25CdUMsc0JBQXNCLEVBQXRCQSxzQkFBc0I7TUFDdEJxQix3QkFBd0IsRUFBRSxFQUFFO01BQzVCMUQsMEJBQTBCLEVBQTFCQTtJQUNGLENBQUM7RUFDSDtFQUVBLElBQU0yRCx1QkFBdUIsR0FBR0Msc0NBQXNDLENBQUM7SUFDckVMLGlCQUFpQixFQUFqQkEsaUJBQWlCO0lBQ2pCdEIsWUFBWSxFQUFaQSxZQUFZO0lBQ1puQyxtQkFBbUIsRUFBbkJBLG1CQUFtQjtJQUNuQnNDLGdCQUFnQixFQUFoQkE7RUFDRixDQUFDLENBQUM7RUFDRkgsWUFBWSxHQUFHMEIsdUJBQXVCLENBQUMxQixZQUFZO0VBQ25EbkMsbUJBQW1CLEdBQUc2RCx1QkFBdUIsQ0FBQzdELG1CQUFtQjtFQUNqRXVDLHNCQUFzQixHQUFHc0IsdUJBQXVCLENBQUN0QixzQkFBc0I7RUFDdkVyQywwQkFBMEIsR0FBRzJELHVCQUF1QixDQUFDM0QsMEJBQTBCO0VBRS9FLElBQU02RCw0QkFBNEIsR0FBR0Msa0RBQWtELENBQUM7SUFDdEYzQixnQkFBZ0IsRUFBaEJBLGdCQUFnQjtJQUNoQkYsWUFBWSxFQUFaQSxZQUFZO0lBQ1puQyxtQkFBbUIsRUFBbkJBO0VBQ0YsQ0FBQyxDQUFDO0VBQ0ZFLDBCQUEwQixHQUFHUSx3QkFBd0IsQ0FDbkRSLDBCQUEwQixFQUMxQjZELDRCQUE0QixDQUFDN0QsMEJBQTBCLENBQ3hEO0VBQ0RGLG1CQUFtQixHQUFHK0QsNEJBQTRCLENBQUMvRCxtQkFBbUI7RUFDdEUsSUFBTTRELHdCQUF3QixHQUFHRyw0QkFBNEIsQ0FBQ0gsd0JBQXdCO0VBRXRGLElBQUlBLHdCQUF3QixDQUFDM0IsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDSyxnQkFBZ0IsRUFBRTtJQUM5RCxPQUFPO01BQ0xILFlBQVksRUFBWkEsWUFBWTtNQUNabkMsbUJBQW1CLEVBQW5CQSxtQkFBbUI7TUFDbkJ1QyxzQkFBc0IsRUFBdEJBLHNCQUFzQjtNQUN0QnFCLHdCQUF3QixFQUF4QkEsd0JBQXdCO01BQ3hCMUQsMEJBQTBCLEVBQTFCQTtJQUNGLENBQUM7RUFDSDtFQUVBLElBQU0rRCxhQUFhLGdDQUNkOUIsWUFBWSxDQUFDWCxVQUFVLHNCQUN2Qm9DLHdCQUF3QixDQUN4QnhELEdBQUcsQ0FBQyxVQUFDYyxJQUFJO0lBQUEsT0FBTUEsSUFBSSxLQUFLLE9BQU8sR0FBRyxJQUFJLEdBQUc4QixvQkFBb0IsQ0FBQzlCLElBQUksQ0FBQztFQUFBLENBQUMsQ0FBQyxDQUNyRWdELE1BQU0sQ0FBQ0Msd0JBQVcsQ0FBQyxFQUN2QjtFQUNELE9BQU87SUFDTGhDLFlBQVksa0NBQU9BLFlBQVk7TUFBRVgsVUFBVSxFQUFFeUM7SUFBYSxFQUFFO0lBQzVEakUsbUJBQW1CLEVBQW5CQSxtQkFBbUI7SUFDbkJ1QyxzQkFBc0IsRUFBRSxJQUFJO0lBQzVCcUIsd0JBQXdCLEVBQUUsRUFBRTtJQUM1QjFELDBCQUEwQixFQUExQkE7RUFDRixDQUFDO0FBQ0gsQ0FBQztBQUVELElBQU13RCxzQkFBc0IsR0FBRyxTQUF6QkEsc0JBQXNCLFFBTXRCO0VBQUEsSUFMSkMsVUFBVSxTQUFWQSxVQUFVO0lBQ1ZuQyxVQUFVLFNBQVZBLFVBQVU7RUFLVixJQUFNNEMsaUJBQWlCLEdBQUdDLGNBQWMsQ0FBQztJQUFFN0MsVUFBVSxFQUFFQTtFQUFXLENBQUMsQ0FBQztFQUNwRSxPQUFPNEMsaUJBQWlCLENBQUNGLE1BQU0sQ0FDN0IsVUFBQ3pDLFNBQVM7SUFBQSxPQUNSQSxTQUFTLENBQUNDLElBQUksS0FBS0MsYUFBSSxDQUFDQyxLQUFLLElBQUksQ0FBQyxDQUFDK0IsVUFBVSxDQUFDM0MsSUFBSSxDQUFDLFVBQUNFLElBQUk7TUFBQSxPQUFLQSxJQUFJLEtBQUtPLFNBQVMsQ0FBQ1AsSUFBSSxDQUFDQyxLQUFLO0lBQUEsRUFBQztFQUFBLEVBQzlGO0FBQ0gsQ0FBQztBQUVELElBQU0yQyxzQ0FBc0MsR0FBRyxTQUF6Q0Esc0NBQXNDLENBQUlOLE1BSy9DLEVBTUk7RUFDSCxJQUFRQyxpQkFBaUIsR0FBbUJELE1BQU0sQ0FBMUNDLGlCQUFpQjtJQUFFdEIsWUFBWSxHQUFLcUIsTUFBTSxDQUF2QnJCLFlBQVk7RUFDdkMsSUFBSW5DLG1CQUFtQixHQUFHd0QsTUFBTSxDQUFDeEQsbUJBQW1CO0VBQ3BELElBQUlFLDBCQUFvRCxHQUFHLEVBQUU7RUFFN0QsSUFBTW9FLGlCQUE4QixHQUFHLEVBQUU7RUFFekNiLGlCQUFpQixDQUFDYyxPQUFPLENBQUMsVUFBQ0MsS0FBSyxFQUFLO0lBQ25DLElBQU1DLGdCQUFnQixHQUFHRCxLQUFLLENBQUNyQyxZQUFZO0lBQzNDLElBQUksQ0FBQ3NDLGdCQUFnQixFQUFFO0lBQ3ZCLElBQUlsRSxNQUE0RDtJQUNoRSxJQUFNbUUsUUFBUSxHQUFHLFNBQVhBLFFBQVEsQ0FBSUMsS0FBbUM7TUFBQSxPQUNuRHZDLHFCQUFxQixDQUFDO1FBQ3BCQyxnQkFBZ0IsRUFBRXNDLEtBQUs7UUFDdkJ4QyxZQUFZLEVBQUVzQyxnQkFBZ0I7UUFDOUJ6RSxtQkFBbUIsRUFBRUEsbUJBQW1CO1FBQ3hDc0MsZ0JBQWdCLEVBQUU7TUFDcEIsQ0FBQyxDQUFDO0lBQUE7SUFFSixJQUFJa0MsS0FBSyxDQUFDdEQsSUFBSSxDQUFDQyxLQUFLLEtBQUssT0FBTyxFQUFFO01BQ2hDWixNQUFNLEdBQUdtRSxRQUFRLENBQUMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdkMsQ0FBQyxNQUFNLElBQUlGLEtBQUssQ0FBQ3RELElBQUksQ0FBQ0MsS0FBSyxLQUFLLE1BQU0sRUFBRTtNQUN0Q1osTUFBTSxHQUFHbUUsUUFBUSxDQUFDLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3pDLENBQUMsTUFBTSxJQUFJRixLQUFLLENBQUN0RCxJQUFJLENBQUNDLEtBQUssS0FBSyxVQUFVLEVBQUU7TUFDMUM7SUFBQTtJQUdGLElBQUksQ0FBQ1osTUFBTSxFQUFFO0lBRWJQLG1CQUFtQixHQUFHTyxNQUFNLENBQUNQLG1CQUFtQjtJQUNoREUsMEJBQTBCLEdBQUdRLHdCQUF3QixDQUNuRFIsMEJBQTBCLEVBQzFCSyxNQUFNLENBQUNMLDBCQUEwQixDQUNsQztJQUNELElBQUlLLE1BQU0sQ0FBQ2dDLHNCQUFzQixFQUFFO01BQ2pDK0IsaUJBQWlCLENBQUNNLElBQUksaUNBQU1KLEtBQUs7UUFBRXJDLFlBQVksRUFBRTVCLE1BQU0sQ0FBQzRCO01BQVksR0FBRztJQUN6RTtFQUNGLENBQUMsQ0FBQztFQUVGLElBQUltQyxpQkFBaUIsQ0FBQ3JDLE1BQU0sS0FBSyxDQUFDLEVBQUU7SUFDbEMsT0FBTztNQUNMRSxZQUFZLEVBQVpBLFlBQVk7TUFDWm5DLG1CQUFtQixFQUFuQkEsbUJBQW1CO01BQ25CRSwwQkFBMEIsRUFBMUJBLDBCQUEwQjtNQUMxQnFDLHNCQUFzQixFQUFFLEtBQUs7TUFDN0JrQixpQkFBaUIsRUFBakJBO0lBQ0YsQ0FBQztFQUNIOztFQUVBO0VBQ0EsSUFBTW9CLGVBQWUsR0FBRyxJQUFBbEUsY0FBSyxFQUFDd0IsWUFBWSxFQUFFO0lBQzFDMkMsS0FBSyxFQUFFO01BQ0xqRSxLQUFLLGlCQUFDMkQsS0FBSyxFQUFFO1FBQ1gsSUFBSSxDQUFDQSxLQUFLLENBQUNPLEdBQUcsRUFBRTtRQUNoQixJQUFNQyxnQkFBZ0IsR0FBR1YsaUJBQWlCLENBQUN0RCxJQUFJLENBQzdDLFVBQUNpRSxXQUFXO1VBQUE7VUFBQSxPQUNWQSxXQUFXLENBQUNGLEdBQUcsSUFBSUUsV0FBVyxDQUFDRixHQUFHLENBQUNHLEtBQUssb0JBQUtWLEtBQUssQ0FBQ08sR0FBRywrQ0FBVCxXQUFXRyxLQUFLLEtBQUlELFdBQVcsQ0FBQ0YsR0FBRyxDQUFDSSxHQUFHLEtBQUtYLEtBQUssQ0FBQ08sR0FBRyxDQUFDSSxHQUFHO1FBQUEsRUFDekc7UUFDRCxJQUFJSCxnQkFBZ0IsRUFBRSxPQUFPQSxnQkFBZ0I7TUFDL0M7SUFDRjtFQUNGLENBQUMsQ0FBQztFQUVGLE9BQU87SUFDTDdDLFlBQVksRUFBRTBDLGVBQWU7SUFDN0I3RSxtQkFBbUIsRUFBbkJBLG1CQUFtQjtJQUNuQkUsMEJBQTBCLEVBQTFCQSwwQkFBMEI7SUFDMUJxQyxzQkFBc0IsRUFBRSxJQUFJO0lBQzVCa0IsaUJBQWlCLEVBQWpCQTtFQUNGLENBQUM7QUFDSCxDQUFDO0FBRUQsSUFBTU8sa0RBQWtELEdBQUcsU0FBckRBLGtEQUFrRCxDQUFJUixNQUkzRCxFQUlJO0VBQ0gsSUFBUW5CLGdCQUFnQixHQUFtQm1CLE1BQU0sQ0FBekNuQixnQkFBZ0I7SUFBRUYsWUFBWSxHQUFLcUIsTUFBTSxDQUF2QnJCLFlBQVk7RUFDdEMsSUFBSW5DLG1CQUFtQixHQUFHd0QsTUFBTSxDQUFDeEQsbUJBQW1CO0VBQ3BELElBQUlFLDBCQUFvRCxHQUFHLEVBQUU7RUFFN0QsSUFBTXNCLFVBQVUsR0FBRzZDLGNBQWMsQ0FBQztJQUFFN0MsVUFBVSxFQUFFVyxZQUFZLENBQUNYO0VBQVcsQ0FBQyxDQUFDO0VBQzFFLElBQUlvQyx3QkFBd0IsR0FBR3ZCLGdCQUFnQixDQUFDNkIsTUFBTSxDQUNwRCxVQUFDaEQsSUFBSTtJQUFBLE9BQUssQ0FBQ00sVUFBVSxDQUFDUixJQUFJLENBQUMsVUFBQ1MsU0FBUztNQUFBLE9BQUtBLFNBQVMsQ0FBQ0MsSUFBSSxLQUFLQyxhQUFJLENBQUNDLEtBQUssSUFBSUgsU0FBUyxDQUFDUCxJQUFJLENBQUNDLEtBQUssS0FBS0QsSUFBSTtJQUFBLEVBQUM7RUFBQSxFQUMxRztFQUVELElBQU1rRSxlQUFlLEdBQUc1RCxVQUFVLENBQUMwQyxNQUFNLENBQ3ZDLFVBQUN6QyxTQUFTO0lBQUEsT0FBc0NBLFNBQVMsQ0FBQ0MsSUFBSSxLQUFLQyxhQUFJLENBQUMwRCxlQUFlO0VBQUEsRUFDeEY7RUFDRCxJQUFJQyxlQUE2QyxHQUFHLEVBQUU7RUFDdERGLGVBQWUsQ0FBQ2IsT0FBTyxDQUFDLFVBQUNnQixNQUFNLEVBQUs7SUFDbEMsSUFBTXRFLFVBQVUsR0FBRyxJQUFBdUUsdUNBQTJCLEVBQUM7TUFBRUMsWUFBWSxFQUFFRixNQUFNLENBQUNyRSxJQUFJLENBQUNDLEtBQUs7TUFBRW5CLG1CQUFtQixFQUFuQkE7SUFBb0IsQ0FBQyxDQUFDO0lBQ3hHLElBQUksQ0FBQ2lCLFVBQVUsRUFBRTtJQUNqQixJQUFNVixNQUFNLEdBQUc2QixxQkFBcUIsQ0FBQztNQUNuQ0QsWUFBWSxFQUFFbEIsVUFBVSxDQUFDa0IsWUFBWTtNQUNyQ0UsZ0JBQWdCLEVBQUV1Qix3QkFBd0I7TUFDMUM1RCxtQkFBbUIsRUFBbkJBLG1CQUFtQjtNQUNuQnNDLGdCQUFnQixFQUFFO0lBQ3BCLENBQUMsQ0FBQztJQUNGdEMsbUJBQW1CLEdBQUdPLE1BQU0sQ0FBQ1AsbUJBQW1CO0lBQ2hERSwwQkFBMEIsR0FBR1Esd0JBQXdCLENBQ25EUiwwQkFBMEIsRUFDMUJLLE1BQU0sQ0FBQ0wsMEJBQTBCLENBQ2xDO0lBQ0QsSUFBSUssTUFBTSxDQUFDZ0Msc0JBQXNCLEVBQUU7TUFDakMsSUFBTW1ELHFCQUFxQixtQ0FBUXpFLFVBQVU7UUFBRWtCLFlBQVksRUFBRTVCLE1BQU0sQ0FBQzRCO01BQVksRUFBRTtNQUNsRmpDLDBCQUEwQixHQUFHUSx3QkFBd0IsQ0FBQ1IsMEJBQTBCLEVBQUUsQ0FBQ3dGLHFCQUFxQixDQUFDLENBQUM7TUFDMUdDLHlCQUF5QixDQUFDM0YsbUJBQW1CLEVBQUUwRixxQkFBcUIsQ0FBQztJQUN2RTtJQUVBLElBQU1FLHFCQUFxQixHQUFHaEMsd0JBQXdCLENBQUNNLE1BQU0sQ0FDM0QsVUFBQ2hELElBQUk7TUFBQSxPQUFLLENBQUNYLE1BQU0sQ0FBQ3FELHdCQUF3QixDQUFDaUMsUUFBUSxDQUFDM0UsSUFBSSxDQUFDO0lBQUEsRUFDMUQ7SUFDRG9FLGVBQWUsZ0NBQU9BLGVBQWUsc0JBQUtNLHFCQUFxQixFQUFDO0VBQ2xFLENBQUMsQ0FBQztFQUVGaEMsd0JBQXdCLEdBQUdBLHdCQUF3QixDQUFDTSxNQUFNLENBQUMsVUFBQ2hELElBQUk7SUFBQSxPQUFLLENBQUNvRSxlQUFlLENBQUNPLFFBQVEsQ0FBQzNFLElBQUksQ0FBQztFQUFBLEVBQUM7RUFFckcsT0FBTztJQUNMbEIsbUJBQW1CLEVBQW5CQSxtQkFBbUI7SUFDbkI0RCx3QkFBd0IsRUFBeEJBLHdCQUF3QjtJQUN4QjFELDBCQUEwQixFQUExQkE7RUFDRixDQUFDO0FBQ0gsQ0FBQztBQUVELElBQU1tRSxjQUFjLEdBQUcsU0FBakJBLGNBQWMsUUFBa0Y7RUFBQSxJQUE1RTdDLFVBQVUsU0FBVkEsVUFBVTtFQUNsQyxPQUFPQSxVQUFVLENBQ2RwQixHQUFHLENBQUMsVUFBQ3FCLFNBQVMsRUFBSztJQUNsQixJQUFJQSxTQUFTLENBQUNDLElBQUksS0FBS0MsYUFBSSxDQUFDbUUsZUFBZSxFQUFFLE9BQU9yRSxTQUFTO0lBQzdELE9BQU80QyxjQUFjLENBQUM7TUFBRTdDLFVBQVUsRUFBRUMsU0FBUyxDQUFDVSxZQUFZLENBQUNYO0lBQVcsQ0FBQyxDQUFDO0VBQzFFLENBQUMsQ0FBQyxDQUNEdUUsSUFBSSxFQUFFO0FBQ1gsQ0FBQztBQUVELElBQU1KLHlCQUF5QixHQUFHLFNBQTVCQSx5QkFBeUIsQ0FDN0IzRixtQkFBNkMsRUFDN0MwRixxQkFBNkMsRUFDcEM7RUFDVCxJQUFNTSxLQUFLLEdBQUdoRyxtQkFBbUIsQ0FBQ2lHLFNBQVMsQ0FDekMsVUFBQ2xGLGtCQUFrQjtJQUFBLE9BQUtBLGtCQUFrQixDQUFDRyxJQUFJLENBQUNDLEtBQUssS0FBS3VFLHFCQUFxQixDQUFDeEUsSUFBSSxDQUFDQyxLQUFLO0VBQUEsRUFDM0Y7RUFDRCxJQUFJNkUsS0FBSyxJQUFJLENBQUMsRUFBRTtJQUNkaEcsbUJBQW1CLENBQUNnRyxLQUFLLENBQUMsR0FBR04scUJBQXFCO0VBQ3BEO0FBQ0YsQ0FBQztBQUVELElBQU1oRix3QkFBd0IsR0FBRyxTQUEzQkEsd0JBQXdCLENBQzVCd0YsQ0FBMkIsRUFDM0JDLENBQTJCLEVBQ0U7RUFDN0Isb0NBRUtELENBQUMsQ0FBQ2hDLE1BQU0sQ0FBQyxVQUFDa0MsV0FBVztJQUFBLE9BQUssQ0FBQ0QsQ0FBQyxDQUFDbkYsSUFBSSxDQUFDLFVBQUNxRixXQUFXO01BQUEsT0FBS0EsV0FBVyxDQUFDbk