UNPKG

@kazekyo/nau-graphql-codegen-preset

Version:

A GraphQL Code Generator preset for Nau

253 lines (251 loc) 38.5 kB
"use strict"; 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); } Object.defineProperty(exports, "__esModule", { value: true }); exports.transform = void 0; var _nau = require("@kazekyo/nau"); var _graphql = require("graphql"); var _lodash = require("lodash"); var _graphqlAST = require("../utils/graphqlAST"); var _util = require("./util"); function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } 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); } 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; } var transform = function transform(_ref) { var documentFiles = _ref.documentFiles; var fragmentDefinitions = (0, _graphqlAST.getFragmentDefinitionsByDocumentFiles)(documentFiles); var files = documentFiles.map(function (file) { if (!file.document) return file; var result = transformDocument({ documentNode: file.document, fragmentDefinitions: fragmentDefinitions }); file.document = result.documentNode; return file; }); return { documentFiles: files }; }; exports.transform = transform; var transformDocument = function transformDocument(params) { var fragmentDefinitions = params.fragmentDefinitions; var documentNode = params.documentNode; var changedOriginalSpreadFragmentNames = []; documentNode.definitions.forEach(function (definition, index) { if (definition.kind !== _graphql.Kind.OPERATION_DEFINITION) return; var transformResult = transformFragmentSpreadFields({ targetDefinition: definition, operationDefinition: definition, documentNode: documentNode, fragmentDefinitions: fragmentDefinitions }); var definitions = _toConsumableArray(transformResult.documentNode.definitions); // Do not change the order of definitions because changing the order of definitions will replace wrong index definitions.splice(index, 1, transformResult.newDefinition); documentNode = _objectSpread(_objectSpread({}, transformResult.documentNode), {}, { definitions: definitions }); changedOriginalSpreadFragmentNames = [].concat(_toConsumableArray(changedOriginalSpreadFragmentNames), _toConsumableArray(transformResult.changedOriginalSpreadFragmentNames)); }); documentNode = removeUnnecessaryFragmentDefinitions({ documentNode: documentNode, changedOriginalSpreadFragmentNames: changedOriginalSpreadFragmentNames }); return { documentNode: documentNode }; }; var getArgumentsDirective = function getArgumentsDirective(node) { var _node$directives; return (_node$directives = node.directives) === null || _node$directives === void 0 ? void 0 : _node$directives.find(function (directiveNode) { return directiveNode.name.value === _nau.ARGUMENTS_DIRECTIVE_NAME; }); }; var getArgumentObject = function getArgumentObject(_ref2) { var argumentNodes = _ref2.argumentNodes; var argumentsData = argumentNodes.map(function (argumentNode) { return [argumentNode.name.value, argumentNode.value]; }); return Object.fromEntries(argumentsData); }; var transformFragmentSpreadFields = function transformFragmentSpreadFields(params) { var targetDefinition = params.targetDefinition, operationDefinition = params.operationDefinition, fragmentDefinitions = params.fragmentDefinitions; var documentNode = params.documentNode; var changedOriginalSpreadFragmentNames = []; var newDefinition = (0, _graphql.visit)(targetDefinition, { FragmentSpread: { leave: function leave(originalNode) { var next = (0, _graphqlAST.getFragmentDefinitionByName)({ fragmentDefinitions: fragmentDefinitions, fragmentName: originalNode.name.value }); if (!next) return; var argumentsDirective = getArgumentsDirective(originalNode); var argumentNodes = (argumentsDirective === null || argumentsDirective === void 0 ? void 0 : argumentsDirective.arguments) || []; var result = transformFragmentDefinition({ targetFragmentDefinition: next, documentNode: documentNode, operationDefinition: operationDefinition, fragmentDefinitions: fragmentDefinitions, passedArguments: argumentNodes.length > 0 ? getArgumentObject({ argumentNodes: argumentNodes }) : undefined }); documentNode = result.documentNode; changedOriginalSpreadFragmentNames = [].concat(_toConsumableArray(changedOriginalSpreadFragmentNames), _toConsumableArray(result.changedOriginalSpreadFragmentNames), [originalNode.name.value]); if (!result.changedFragmentName) return; return _objectSpread(_objectSpread({}, originalNode), {}, { name: _objectSpread(_objectSpread({}, originalNode.name), {}, { value: result.changedFragmentName }) }); } } }); return { documentNode: documentNode, newDefinition: newDefinition, changedOriginalSpreadFragmentNames: changedOriginalSpreadFragmentNames }; }; // Remove a fragment definition if there is no place where the original fragment definition is used. var removeUnnecessaryFragmentDefinitions = function removeUnnecessaryFragmentDefinitions(_ref3) { var documentNode = _ref3.documentNode, changedOriginalSpreadFragmentNames = _ref3.changedOriginalSpreadFragmentNames; var shouldDeleteFragmentNames = (0, _lodash.uniq)(changedOriginalSpreadFragmentNames); (0, _graphql.visit)(documentNode, { FragmentSpread: { leave: function leave(node) { var index = shouldDeleteFragmentNames.findIndex(function (name) { return name === node.name.value; }); if (index !== -1) { shouldDeleteFragmentNames.splice(index, 1); } } } }); documentNode = _objectSpread(_objectSpread({}, documentNode), {}, { definitions: _toConsumableArray(documentNode.definitions.filter(function (definition) { return definition.kind !== _graphql.Kind.FRAGMENT_DEFINITION || !shouldDeleteFragmentNames.includes(definition.name.value); })) }); return documentNode; }; var transformFragmentDefinition = function transformFragmentDefinition(params) { var targetFragmentDefinition = params.targetFragmentDefinition, operationDefinition = params.operationDefinition, passedArguments = params.passedArguments, fragmentDefinitions = params.fragmentDefinitions; var documentNode = params.documentNode; var newFragmentDefinition = getRenamedFragmentDefinition({ node: targetFragmentDefinition, argumentsObject: passedArguments }); var existsFragmentDefinitionInDocument = !!documentNode.definitions.find(function (definition) { return definition.kind === _graphql.Kind.FRAGMENT_DEFINITION && definition.name.value === newFragmentDefinition.name.value; }); var isOriginalName = newFragmentDefinition.name.value === targetFragmentDefinition.name.value; if (!isOriginalName && existsFragmentDefinitionInDocument) { return { documentNode: documentNode, changedOriginalSpreadFragmentNames: [] }; } var valueNodeMap = {}; if (passedArguments) { (0, _graphql.visit)(newFragmentDefinition, { Directive: { enter: function enter(node) { if (node.name.value !== _nau.ARGUMENT_DEFINITIONS_DIRECTIVE_NAME) return; var argumentDataList = (0, _util.getArgumentDefinitionDataList)(node); argumentDataList.forEach(function (data) { // Put the passed arguments into valueMap to fit them where they are used in the fragment. var passedArgumentValue = passedArguments[data.name.value]; if (!passedArgumentValue) return; valueNodeMap[data.name.value] = passedArgumentValue; }); } } }); } newFragmentDefinition = (0, _graphql.visit)(newFragmentDefinition, { Argument: function Argument(node) { if (node.value.kind === 'Variable') { var variableName = node.value.name.value; var valueNode = valueNodeMap[variableName]; if (valueNode) { return _objectSpread(_objectSpread({}, node), {}, { value: valueNode }); } } } }); var transformResult = transformFragmentSpreadFields({ targetDefinition: newFragmentDefinition, operationDefinition: operationDefinition, documentNode: documentNode, fragmentDefinitions: fragmentDefinitions }); newFragmentDefinition = transformResult.newDefinition; documentNode = transformResult.documentNode; if (existsFragmentDefinitionInDocument) { // // Replace the fragment definition documentNode = _objectSpread(_objectSpread({}, documentNode), {}, { definitions: [].concat(_toConsumableArray(documentNode.definitions.filter(function (definition) { return definition.kind !== _graphql.Kind.FRAGMENT_DEFINITION || definition.name.value !== newFragmentDefinition.name.value; })), [newFragmentDefinition]) }); } else { // Add the fragment definition documentNode = _objectSpread(_objectSpread({}, documentNode), {}, { definitions: [].concat(_toConsumableArray(documentNode.definitions), [newFragmentDefinition]) }); } return { documentNode: documentNode, changedOriginalSpreadFragmentNames: transformResult.changedOriginalSpreadFragmentNames, changedFragmentName: newFragmentDefinition.name.value }; }; var getRenamedFragmentDefinition = function getRenamedFragmentDefinition(_ref4) { var node = _ref4.node, argumentsObject = _ref4.argumentsObject; if (!argumentsObject) return node; var str = Object.entries(argumentsObject).sort(function (_ref5, _ref6) { var _ref7 = _slicedToArray(_ref5, 1), nameA = _ref7[0]; var _ref8 = _slicedToArray(_ref6, 1), nameB = _ref8[0]; return nameA.localeCompare(nameB); }).map(function (_ref9) { var _ref10 = _slicedToArray(_ref9, 2), argName = _ref10[0], valueNode = _ref10[1]; return "".concat(argName, ":").concat((0, _graphql.print)(valueNode)); }).join(',').replace(/\s+/g, ''); var name = _objectSpread(_objectSpread({}, node.name), {}, { value: (0, _util.getUniqueFragmentName)(node.name.value, "".concat(_util.FRAGMENT_NAME_INFO_ID_1, ",").concat(str)) }); return _objectSpread(_objectSpread({}, node), {}, { name: name }); }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ0cmFuc2Zvcm0iLCJkb2N1bWVudEZpbGVzIiwiZnJhZ21lbnREZWZpbml0aW9ucyIsImdldEZyYWdtZW50RGVmaW5pdGlvbnNCeURvY3VtZW50RmlsZXMiLCJmaWxlcyIsIm1hcCIsImZpbGUiLCJkb2N1bWVudCIsInJlc3VsdCIsInRyYW5zZm9ybURvY3VtZW50IiwiZG9jdW1lbnROb2RlIiwicGFyYW1zIiwiY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lcyIsImRlZmluaXRpb25zIiwiZm9yRWFjaCIsImRlZmluaXRpb24iLCJpbmRleCIsImtpbmQiLCJLaW5kIiwiT1BFUkFUSU9OX0RFRklOSVRJT04iLCJ0cmFuc2Zvcm1SZXN1bHQiLCJ0cmFuc2Zvcm1GcmFnbWVudFNwcmVhZEZpZWxkcyIsInRhcmdldERlZmluaXRpb24iLCJvcGVyYXRpb25EZWZpbml0aW9uIiwic3BsaWNlIiwibmV3RGVmaW5pdGlvbiIsInJlbW92ZVVubmVjZXNzYXJ5RnJhZ21lbnREZWZpbml0aW9ucyIsImdldEFyZ3VtZW50c0RpcmVjdGl2ZSIsIm5vZGUiLCJkaXJlY3RpdmVzIiwiZmluZCIsImRpcmVjdGl2ZU5vZGUiLCJuYW1lIiwidmFsdWUiLCJBUkdVTUVOVFNfRElSRUNUSVZFX05BTUUiLCJnZXRBcmd1bWVudE9iamVjdCIsImFyZ3VtZW50Tm9kZXMiLCJhcmd1bWVudHNEYXRhIiwiYXJndW1lbnROb2RlIiwiT2JqZWN0IiwiZnJvbUVudHJpZXMiLCJ2aXNpdCIsIkZyYWdtZW50U3ByZWFkIiwibGVhdmUiLCJvcmlnaW5hbE5vZGUiLCJuZXh0IiwiZ2V0RnJhZ21lbnREZWZpbml0aW9uQnlOYW1lIiwiZnJhZ21lbnROYW1lIiwiYXJndW1lbnRzRGlyZWN0aXZlIiwiYXJndW1lbnRzIiwidHJhbnNmb3JtRnJhZ21lbnREZWZpbml0aW9uIiwidGFyZ2V0RnJhZ21lbnREZWZpbml0aW9uIiwicGFzc2VkQXJndW1lbnRzIiwibGVuZ3RoIiwidW5kZWZpbmVkIiwiY2hhbmdlZEZyYWdtZW50TmFtZSIsInNob3VsZERlbGV0ZUZyYWdtZW50TmFtZXMiLCJ1bmlxIiwiZmluZEluZGV4IiwiZmlsdGVyIiwiRlJBR01FTlRfREVGSU5JVElPTiIsImluY2x1ZGVzIiwibmV3RnJhZ21lbnREZWZpbml0aW9uIiwiZ2V0UmVuYW1lZEZyYWdtZW50RGVmaW5pdGlvbiIsImFyZ3VtZW50c09iamVjdCIsImV4aXN0c0ZyYWdtZW50RGVmaW5pdGlvbkluRG9jdW1lbnQiLCJpc09yaWdpbmFsTmFtZSIsInZhbHVlTm9kZU1hcCIsIkRpcmVjdGl2ZSIsImVudGVyIiwiQVJHVU1FTlRfREVGSU5JVElPTlNfRElSRUNUSVZFX05BTUUiLCJhcmd1bWVudERhdGFMaXN0IiwiZ2V0QXJndW1lbnREZWZpbml0aW9uRGF0YUxpc3QiLCJkYXRhIiwicGFzc2VkQXJndW1lbnRWYWx1ZSIsIkFyZ3VtZW50IiwidmFyaWFibGVOYW1lIiwidmFsdWVOb2RlIiwic3RyIiwiZW50cmllcyIsInNvcnQiLCJuYW1lQSIsIm5hbWVCIiwibG9jYWxlQ29tcGFyZSIsImFyZ05hbWUiLCJwcmludCIsImpvaW4iLCJyZXBsYWNlIiwiZ2V0VW5pcXVlRnJhZ21lbnROYW1lIiwiRlJBR01FTlRfTkFNRV9JTkZPX0lEXzEiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdHJhbnNmb3Jtcy9wYXNzQXJndW1lbnRWYWx1ZVRvRnJhZ21lbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVHlwZXMgfSBmcm9tICdAZ3JhcGhxbC1jb2RlZ2VuL3BsdWdpbi1oZWxwZXJzJztcbmltcG9ydCB7IEFSR1VNRU5UU19ESVJFQ1RJVkVfTkFNRSwgQVJHVU1FTlRfREVGSU5JVElPTlNfRElSRUNUSVZFX05BTUUgfSBmcm9tICdAa2F6ZWt5by9uYXUnO1xuaW1wb3J0IHtcbiAgQXJndW1lbnROb2RlLFxuICBBU1ROb2RlLFxuICBEZWZpbml0aW9uTm9kZSxcbiAgRGlyZWN0aXZlTm9kZSxcbiAgRG9jdW1lbnROb2RlLFxuICBGcmFnbWVudERlZmluaXRpb25Ob2RlLFxuICBGcmFnbWVudFNwcmVhZE5vZGUsXG4gIEtpbmQsXG4gIE9wZXJhdGlvbkRlZmluaXRpb25Ob2RlLFxuICBwcmludCxcbiAgVmFsdWVOb2RlLFxuICB2aXNpdCxcbn0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyB1bmlxIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGdldEZyYWdtZW50RGVmaW5pdGlvbkJ5TmFtZSwgZ2V0RnJhZ21lbnREZWZpbml0aW9uc0J5RG9jdW1lbnRGaWxlcyB9IGZyb20gJy4uL3V0aWxzL2dyYXBocWxBU1QnO1xuaW1wb3J0IHsgRlJBR01FTlRfTkFNRV9JTkZPX0lEXzEsIGdldEFyZ3VtZW50RGVmaW5pdGlvbkRhdGFMaXN0LCBnZXRVbmlxdWVGcmFnbWVudE5hbWUgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgY29uc3QgdHJhbnNmb3JtID0gKHtcbiAgZG9jdW1lbnRGaWxlcyxcbn06IHtcbiAgZG9jdW1lbnRGaWxlczogVHlwZXMuRG9jdW1lbnRGaWxlW107XG59KTogeyBkb2N1bWVudEZpbGVzOiBUeXBlcy5Eb2N1bWVudEZpbGVbXSB9ID0+IHtcbiAgY29uc3QgZnJhZ21lbnREZWZpbml0aW9ucyA9IGdldEZyYWdtZW50RGVmaW5pdGlvbnNCeURvY3VtZW50RmlsZXMoZG9jdW1lbnRGaWxlcyk7XG5cbiAgY29uc3QgZmlsZXMgPSBkb2N1bWVudEZpbGVzLm1hcCgoZmlsZSkgPT4ge1xuICAgIGlmICghZmlsZS5kb2N1bWVudCkgcmV0dXJuIGZpbGU7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtRG9jdW1lbnQoeyBkb2N1bWVudE5vZGU6IGZpbGUuZG9jdW1lbnQsIGZyYWdtZW50RGVmaW5pdGlvbnMgfSk7XG4gICAgZmlsZS5kb2N1bWVudCA9IHJlc3VsdC5kb2N1bWVudE5vZGU7XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0pO1xuXG4gIHJldHVybiB7IGRvY3VtZW50RmlsZXM6IGZpbGVzIH07XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1Eb2N1bWVudCA9IChwYXJhbXM6IHtcbiAgZG9jdW1lbnROb2RlOiBEb2N1bWVudE5vZGU7XG4gIGZyYWdtZW50RGVmaW5pdGlvbnM6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGVbXTtcbn0pOiB7IGRvY3VtZW50Tm9kZTogRG9jdW1lbnROb2RlIH0gPT4ge1xuICBjb25zdCB7IGZyYWdtZW50RGVmaW5pdGlvbnMgfSA9IHBhcmFtcztcbiAgbGV0IGRvY3VtZW50Tm9kZSA9IHBhcmFtcy5kb2N1bWVudE5vZGU7XG5cbiAgbGV0IGNoYW5nZWRPcmlnaW5hbFNwcmVhZEZyYWdtZW50TmFtZXM6IHN0cmluZ1tdID0gW107XG4gIGRvY3VtZW50Tm9kZS5kZWZpbml0aW9ucy5mb3JFYWNoKChkZWZpbml0aW9uLCBpbmRleCkgPT4ge1xuICAgIGlmIChkZWZpbml0aW9uLmtpbmQgIT09IEtpbmQuT1BFUkFUSU9OX0RFRklOSVRJT04pIHJldHVybjtcbiAgICBjb25zdCB0cmFuc2Zvcm1SZXN1bHQgPSB0cmFuc2Zvcm1GcmFnbWVudFNwcmVhZEZpZWxkcyh7XG4gICAgICB0YXJnZXREZWZpbml0aW9uOiBkZWZpbml0aW9uLFxuICAgICAgb3BlcmF0aW9uRGVmaW5pdGlvbjogZGVmaW5pdGlvbixcbiAgICAgIGRvY3VtZW50Tm9kZTogZG9jdW1lbnROb2RlLFxuICAgICAgZnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICB9KTtcbiAgICBjb25zdCBkZWZpbml0aW9uczogRGVmaW5pdGlvbk5vZGVbXSA9IFsuLi50cmFuc2Zvcm1SZXN1bHQuZG9jdW1lbnROb2RlLmRlZmluaXRpb25zXTtcbiAgICAvLyBEbyBub3QgY2hhbmdlIHRoZSBvcmRlciBvZiBkZWZpbml0aW9ucyBiZWNhdXNlIGNoYW5naW5nIHRoZSBvcmRlciBvZiBkZWZpbml0aW9ucyB3aWxsIHJlcGxhY2Ugd3JvbmcgaW5kZXhcbiAgICBkZWZpbml0aW9ucy5zcGxpY2UoaW5kZXgsIDEsIHRyYW5zZm9ybVJlc3VsdC5uZXdEZWZpbml0aW9uKTtcbiAgICBkb2N1bWVudE5vZGUgPSB7IC4uLnRyYW5zZm9ybVJlc3VsdC5kb2N1bWVudE5vZGUsIGRlZmluaXRpb25zIH07XG4gICAgY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lcyA9IFtcbiAgICAgIC4uLmNoYW5nZWRPcmlnaW5hbFNwcmVhZEZyYWdtZW50TmFtZXMsXG4gICAgICAuLi50cmFuc2Zvcm1SZXN1bHQuY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lcyxcbiAgICBdO1xuICB9KTtcblxuICBkb2N1bWVudE5vZGUgPSByZW1vdmVVbm5lY2Vzc2FyeUZyYWdtZW50RGVmaW5pdGlvbnMoe1xuICAgIGRvY3VtZW50Tm9kZSxcbiAgICBjaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzLFxuICB9KTtcblxuICByZXR1cm4geyBkb2N1bWVudE5vZGUgfTtcbn07XG5cbmNvbnN0IGdldEFyZ3VtZW50c0RpcmVjdGl2ZSA9IChub2RlOiBGcmFnbWVudFNwcmVhZE5vZGUpOiBEaXJlY3RpdmVOb2RlIHwgdW5kZWZpbmVkID0+XG4gIG5vZGUuZGlyZWN0aXZlcz8uZmluZCgoZGlyZWN0aXZlTm9kZSkgPT4gZGlyZWN0aXZlTm9kZS5uYW1lLnZhbHVlID09PSBBUkdVTUVOVFNfRElSRUNUSVZFX05BTUUpO1xuXG5jb25zdCBnZXRBcmd1bWVudE9iamVjdCA9ICh7XG4gIGFyZ3VtZW50Tm9kZXMsXG59OiB7XG4gIGFyZ3VtZW50Tm9kZXM6IHJlYWRvbmx5IEFyZ3VtZW50Tm9kZVtdO1xufSk6IFJlY29yZDxzdHJpbmcsIFZhbHVlTm9kZT4gPT4ge1xuICBjb25zdCBhcmd1bWVudHNEYXRhOiBBcnJheTxbc3RyaW5nLCBWYWx1ZU5vZGVdPiA9IGFyZ3VtZW50Tm9kZXMubWFwKChhcmd1bWVudE5vZGUpID0+IFtcbiAgICBhcmd1bWVudE5vZGUubmFtZS52YWx1ZSxcbiAgICBhcmd1bWVudE5vZGUudmFsdWUsXG4gIF0pO1xuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKGFyZ3VtZW50c0RhdGEpO1xufTtcblxuY29uc3QgdHJhbnNmb3JtRnJhZ21lbnRTcHJlYWRGaWVsZHMgPSA8VERlZmluaXRpb25Ob2RlIGV4dGVuZHMgQVNUTm9kZT4ocGFyYW1zOiB7XG4gIHRhcmdldERlZmluaXRpb246IFREZWZpbml0aW9uTm9kZTtcbiAgb3BlcmF0aW9uRGVmaW5pdGlvbjogT3BlcmF0aW9uRGVmaW5pdGlvbk5vZGU7XG4gIGRvY3VtZW50Tm9kZTogRG9jdW1lbnROb2RlO1xuICBmcmFnbWVudERlZmluaXRpb25zOiBGcmFnbWVudERlZmluaXRpb25Ob2RlW107XG59KToge1xuICBkb2N1bWVudE5vZGU6IERvY3VtZW50Tm9kZTtcbiAgbmV3RGVmaW5pdGlvbjogVERlZmluaXRpb25Ob2RlO1xuICBjaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzOiBzdHJpbmdbXTtcbn0gPT4ge1xuICBjb25zdCB7IHRhcmdldERlZmluaXRpb24sIG9wZXJhdGlvbkRlZmluaXRpb24sIGZyYWdtZW50RGVmaW5pdGlvbnMgfSA9IHBhcmFtcztcbiAgbGV0IGRvY3VtZW50Tm9kZSA9IHBhcmFtcy5kb2N1bWVudE5vZGU7XG4gIGxldCBjaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBuZXdEZWZpbml0aW9uID0gdmlzaXQodGFyZ2V0RGVmaW5pdGlvbiwge1xuICAgIEZyYWdtZW50U3ByZWFkOiB7XG4gICAgICBsZWF2ZShvcmlnaW5hbE5vZGUpIHtcbiAgICAgICAgY29uc3QgbmV4dCA9IGdldEZyYWdtZW50RGVmaW5pdGlvbkJ5TmFtZSh7IGZyYWdtZW50RGVmaW5pdGlvbnMsIGZyYWdtZW50TmFtZTogb3JpZ2luYWxOb2RlLm5hbWUudmFsdWUgfSk7XG4gICAgICAgIGlmICghbmV4dCkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGFyZ3VtZW50c0RpcmVjdGl2ZSA9IGdldEFyZ3VtZW50c0RpcmVjdGl2ZShvcmlnaW5hbE5vZGUpO1xuICAgICAgICBjb25zdCBhcmd1bWVudE5vZGVzID0gYXJndW1lbnRzRGlyZWN0aXZlPy5hcmd1bWVudHMgfHwgW107XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdHJhbnNmb3JtRnJhZ21lbnREZWZpbml0aW9uKHtcbiAgICAgICAgICB0YXJnZXRGcmFnbWVudERlZmluaXRpb246IG5leHQsXG4gICAgICAgICAgZG9jdW1lbnROb2RlLFxuICAgICAgICAgIG9wZXJhdGlvbkRlZmluaXRpb24sXG4gICAgICAgICAgZnJhZ21lbnREZWZpbml0aW9ucyxcbiAgICAgICAgICBwYXNzZWRBcmd1bWVudHM6IGFyZ3VtZW50Tm9kZXMubGVuZ3RoID4gMCA/IGdldEFyZ3VtZW50T2JqZWN0KHsgYXJndW1lbnROb2RlcyB9KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGRvY3VtZW50Tm9kZSA9IHJlc3VsdC5kb2N1bWVudE5vZGU7XG5cbiAgICAgICAgY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lcyA9IFtcbiAgICAgICAgICAuLi5jaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzLFxuICAgICAgICAgIC4uLnJlc3VsdC5jaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzLFxuICAgICAgICAgIG9yaWdpbmFsTm9kZS5uYW1lLnZhbHVlLFxuICAgICAgICBdO1xuXG4gICAgICAgIGlmICghcmVzdWx0LmNoYW5nZWRGcmFnbWVudE5hbWUpIHJldHVybjtcblxuICAgICAgICByZXR1cm4geyAuLi5vcmlnaW5hbE5vZGUsIG5hbWU6IHsgLi4ub3JpZ2luYWxOb2RlLm5hbWUsIHZhbHVlOiByZXN1bHQuY2hhbmdlZEZyYWdtZW50TmFtZSB9IH07XG4gICAgICB9LFxuICAgIH0sXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZG9jdW1lbnROb2RlLFxuICAgIG5ld0RlZmluaXRpb24sXG4gICAgY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lcyxcbiAgfTtcbn07XG5cbi8vIFJlbW92ZSBhIGZyYWdtZW50IGRlZmluaXRpb24gaWYgdGhlcmUgaXMgbm8gcGxhY2Ugd2hlcmUgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGRlZmluaXRpb24gaXMgdXNlZC5cbmNvbnN0IHJlbW92ZVVubmVjZXNzYXJ5RnJhZ21lbnREZWZpbml0aW9ucyA9ICh7XG4gIGRvY3VtZW50Tm9kZSxcbiAgY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lcyxcbn06IHtcbiAgZG9jdW1lbnROb2RlOiBEb2N1bWVudE5vZGU7XG4gIGNoYW5nZWRPcmlnaW5hbFNwcmVhZEZyYWdtZW50TmFtZXM6IHN0cmluZ1tdO1xufSk6IERvY3VtZW50Tm9kZSA9PiB7XG4gIGNvbnN0IHNob3VsZERlbGV0ZUZyYWdtZW50TmFtZXM6IHN0cmluZ1tdID0gdW5pcShjaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzKTtcbiAgdmlzaXQoZG9jdW1lbnROb2RlLCB7XG4gICAgRnJhZ21lbnRTcHJlYWQ6IHtcbiAgICAgIGxlYXZlKG5vZGUpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBzaG91bGREZWxldGVGcmFnbWVudE5hbWVzLmZpbmRJbmRleCgobmFtZSkgPT4gbmFtZSA9PT0gbm9kZS5uYW1lLnZhbHVlKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgIHNob3VsZERlbGV0ZUZyYWdtZW50TmFtZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbiAgZG9jdW1lbnROb2RlID0ge1xuICAgIC4uLmRvY3VtZW50Tm9kZSxcbiAgICBkZWZpbml0aW9uczogW1xuICAgICAgLi4uZG9jdW1lbnROb2RlLmRlZmluaXRpb25zLmZpbHRlcihcbiAgICAgICAgKGRlZmluaXRpb24pID0+XG4gICAgICAgICAgZGVmaW5pdGlvbi5raW5kICE9PSBLaW5kLkZSQUdNRU5UX0RFRklOSVRJT04gfHwgIXNob3VsZERlbGV0ZUZyYWdtZW50TmFtZXMuaW5jbHVkZXMoZGVmaW5pdGlvbi5uYW1lLnZhbHVlKSxcbiAgICAgICksXG4gICAgXSxcbiAgfTtcbiAgcmV0dXJuIGRvY3VtZW50Tm9kZTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybUZyYWdtZW50RGVmaW5pdGlvbiA9IChwYXJhbXM6IHtcbiAgdGFyZ2V0RnJhZ21lbnREZWZpbml0aW9uOiBGcmFnbWVudERlZmluaXRpb25Ob2RlO1xuICBvcGVyYXRpb25EZWZpbml0aW9uOiBPcGVyYXRpb25EZWZpbml0aW9uTm9kZTtcbiAgZG9jdW1lbnROb2RlOiBEb2N1bWVudE5vZGU7XG4gIGZyYWdtZW50RGVmaW5pdGlvbnM6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGVbXTtcbiAgcGFzc2VkQXJndW1lbnRzPzogUmVjb3JkPHN0cmluZywgVmFsdWVOb2RlPjtcbn0pOiB7XG4gIGRvY3VtZW50Tm9kZTogRG9jdW1lbnROb2RlO1xuICBjaGFuZ2VkT3JpZ2luYWxTcHJlYWRGcmFnbWVudE5hbWVzOiBzdHJpbmdbXTtcbiAgY2hhbmdlZEZyYWdtZW50TmFtZT86IHN0cmluZztcbn0gPT4ge1xuICBjb25zdCB7IHRhcmdldEZyYWdtZW50RGVmaW5pdGlvbiwgb3BlcmF0aW9uRGVmaW5pdGlvbiwgcGFzc2VkQXJndW1lbnRzLCBmcmFnbWVudERlZmluaXRpb25zIH0gPSBwYXJhbXM7XG4gIGxldCBkb2N1bWVudE5vZGUgPSBwYXJhbXMuZG9jdW1lbnROb2RlO1xuXG4gIGxldCBuZXdGcmFnbWVudERlZmluaXRpb24gPSBnZXRSZW5hbWVkRnJhZ21lbnREZWZpbml0aW9uKHtcbiAgICBub2RlOiB0YXJnZXRGcmFnbWVudERlZmluaXRpb24sXG4gICAgYXJndW1lbnRzT2JqZWN0OiBwYXNzZWRBcmd1bWVudHMsXG4gIH0pO1xuICBjb25zdCBleGlzdHNGcmFnbWVudERlZmluaXRpb25JbkRvY3VtZW50ID0gISFkb2N1bWVudE5vZGUuZGVmaW5pdGlvbnMuZmluZChcbiAgICAoZGVmaW5pdGlvbikgPT5cbiAgICAgIGRlZmluaXRpb24ua2luZCA9PT0gS2luZC5GUkFHTUVOVF9ERUZJTklUSU9OICYmIGRlZmluaXRpb24ubmFtZS52YWx1ZSA9PT0gbmV3RnJhZ21lbnREZWZpbml0aW9uLm5hbWUudmFsdWUsXG4gICk7XG4gIGNvbnN0IGlzT3JpZ2luYWxOYW1lID0gbmV3RnJhZ21lbnREZWZpbml0aW9uLm5hbWUudmFsdWUgPT09IHRhcmdldEZyYWdtZW50RGVmaW5pdGlvbi5uYW1lLnZhbHVlO1xuICBpZiAoIWlzT3JpZ2luYWxOYW1lICYmIGV4aXN0c0ZyYWdtZW50RGVmaW5pdGlvbkluRG9jdW1lbnQpIHtcbiAgICByZXR1cm4geyBkb2N1bWVudE5vZGUsIGNoYW5nZWRPcmlnaW5hbFNwcmVhZEZyYWdtZW50TmFtZXM6IFtdIH07XG4gIH1cblxuICBjb25zdCB2YWx1ZU5vZGVNYXA6IFJlY29yZDxzdHJpbmcsIFZhbHVlTm9kZT4gPSB7fTtcbiAgaWYgKHBhc3NlZEFyZ3VtZW50cykge1xuICAgIHZpc2l0KG5ld0ZyYWdtZW50RGVmaW5pdGlvbiwge1xuICAgICAgRGlyZWN0aXZlOiB7XG4gICAgICAgIGVudGVyKG5vZGUpIHtcbiAgICAgICAgICBpZiAobm9kZS5uYW1lLnZhbHVlICE9PSBBUkdVTUVOVF9ERUZJTklUSU9OU19ESVJFQ1RJVkVfTkFNRSkgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IGFyZ3VtZW50RGF0YUxpc3QgPSBnZXRBcmd1bWVudERlZmluaXRpb25EYXRhTGlzdChub2RlKTtcbiAgICAgICAgICBhcmd1bWVudERhdGFMaXN0LmZvckVhY2goKGRhdGEpID0+IHtcbiAgICAgICAgICAgIC8vIFB1dCB0aGUgcGFzc2VkIGFyZ3VtZW50cyBpbnRvIHZhbHVlTWFwIHRvIGZpdCB0aGVtIHdoZXJlIHRoZXkgYXJlIHVzZWQgaW4gdGhlIGZyYWdtZW50LlxuICAgICAgICAgICAgY29uc3QgcGFzc2VkQXJndW1lbnRWYWx1ZSA9IHBhc3NlZEFyZ3VtZW50c1tkYXRhLm5hbWUudmFsdWVdO1xuICAgICAgICAgICAgaWYgKCFwYXNzZWRBcmd1bWVudFZhbHVlKSByZXR1cm47XG4gICAgICAgICAgICB2YWx1ZU5vZGVNYXBbZGF0YS5uYW1lLnZhbHVlXSA9IHBhc3NlZEFyZ3VtZW50VmFsdWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgbmV3RnJhZ21lbnREZWZpbml0aW9uID0gdmlzaXQobmV3RnJhZ21lbnREZWZpbml0aW9uLCB7XG4gICAgQXJndW1lbnQobm9kZSkge1xuICAgICAgaWYgKG5vZGUudmFsdWUua2luZCA9PT0gJ1ZhcmlhYmxlJykge1xuICAgICAgICBjb25zdCB2YXJpYWJsZU5hbWUgPSBub2RlLnZhbHVlLm5hbWUudmFsdWU7XG4gICAgICAgIGNvbnN0IHZhbHVlTm9kZSA9IHZhbHVlTm9kZU1hcFt2YXJpYWJsZU5hbWVdO1xuICAgICAgICBpZiAodmFsdWVOb2RlKSB7XG4gICAgICAgICAgcmV0dXJuIHsgLi4ubm9kZSwgdmFsdWU6IHZhbHVlTm9kZSB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgY29uc3QgdHJhbnNmb3JtUmVzdWx0ID0gdHJhbnNmb3JtRnJhZ21lbnRTcHJlYWRGaWVsZHMoe1xuICAgIHRhcmdldERlZmluaXRpb246IG5ld0ZyYWdtZW50RGVmaW5pdGlvbixcbiAgICBvcGVyYXRpb25EZWZpbml0aW9uLFxuICAgIGRvY3VtZW50Tm9kZSxcbiAgICBmcmFnbWVudERlZmluaXRpb25zLFxuICB9KTtcbiAgbmV3RnJhZ21lbnREZWZpbml0aW9uID0gdHJhbnNmb3JtUmVzdWx0Lm5ld0RlZmluaXRpb247XG4gIGRvY3VtZW50Tm9kZSA9IHRyYW5zZm9ybVJlc3VsdC5kb2N1bWVudE5vZGU7XG5cbiAgaWYgKGV4aXN0c0ZyYWdtZW50RGVmaW5pdGlvbkluRG9jdW1lbnQpIHtcbiAgICAvLyAvLyBSZXBsYWNlIHRoZSBmcmFnbWVudCBkZWZpbml0aW9uXG4gICAgZG9jdW1lbnROb2RlID0ge1xuICAgICAgLi4uZG9jdW1lbnROb2RlLFxuICAgICAgZGVmaW5pdGlvbnM6IFtcbiAgICAgICAgLi4uZG9jdW1lbnROb2RlLmRlZmluaXRpb25zLmZpbHRlcihcbiAgICAgICAgICAoZGVmaW5pdGlvbikgPT5cbiAgICAgICAgICAgIGRlZmluaXRpb24ua2luZCAhPT0gS2luZC5GUkFHTUVOVF9ERUZJTklUSU9OIHx8IGRlZmluaXRpb24ubmFtZS52YWx1ZSAhPT0gbmV3RnJhZ21lbnREZWZpbml0aW9uLm5hbWUudmFsdWUsXG4gICAgICAgICksXG4gICAgICAgIG5ld0ZyYWdtZW50RGVmaW5pdGlvbixcbiAgICAgIF0sXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBBZGQgdGhlIGZyYWdtZW50IGRlZmluaXRpb25cbiAgICBkb2N1bWVudE5vZGUgPSB7XG4gICAgICAuLi5kb2N1bWVudE5vZGUsXG4gICAgICBkZWZpbml0aW9uczogWy4uLmRvY3VtZW50Tm9kZS5kZWZpbml0aW9ucywgbmV3RnJhZ21lbnREZWZpbml0aW9uXSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBkb2N1bWVudE5vZGUsXG4gICAgY2hhbmdlZE9yaWdpbmFsU3ByZWFkRnJhZ21lbnROYW1lczogdHJhbnNmb3JtUmVzdWx0LmNoYW5nZWRPcmlnaW5hbFNwcmVhZEZyYWdtZW50TmFtZXMsXG4gICAgY2hhbmdlZEZyYWdtZW50TmFtZTogbmV3RnJhZ21lbnREZWZpbml0aW9uLm5hbWUudmFsdWUsXG4gIH07XG59O1xuXG5jb25zdCBnZXRSZW5hbWVkRnJhZ21lbnREZWZpbml0aW9uID0gKHtcbiAgbm9kZSxcbiAgYXJndW1lbnRzT2JqZWN0LFxufToge1xuICBub2RlOiBGcmFnbWVudERlZmluaXRpb25Ob2RlO1xuICBhcmd1bWVudHNPYmplY3Q/OiBSZWNvcmQ8c3RyaW5nLCBWYWx1ZU5vZGU+O1xufSk6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGUgPT4ge1xuICBpZiAoIWFyZ3VtZW50c09iamVjdCkgcmV0dXJuIG5vZGU7XG4gIGNvbnN0IHN0ciA9IE9iamVjdC5lbnRyaWVzKGFyZ3VtZW50c09iamVjdClcbiAgICAuc29ydCgoW25hbWVBXSwgW25hbWVCXSkgPT4gbmFtZUEubG9jYWxlQ29tcGFyZShuYW1lQikpXG4gICAgLm1hcCgoW2FyZ05hbWUsIHZhbHVlTm9kZV0pID0+IGAke2FyZ05hbWV9OiR7cHJpbnQodmFsdWVOb2RlKX1gKVxuICAgIC5qb2luKCcsJylcbiAgICAucmVwbGFjZSgvXFxzKy9nLCAnJyk7XG4gIGNvbnN0IG5hbWUgPSB7XG4gICAgLi4ubm9kZS5uYW1lLFxuICAgIHZhbHVlOiBnZXRVbmlxdWVGcmFnbWVudE5hbWUobm9kZS5uYW1lLnZhbHVlLCBgJHtGUkFHTUVOVF9OQU1FX0lORk9fSURfMX0sJHtzdHJ9YCksXG4gIH07XG4gIHJldHVybiB7IC4uLm5vZGUsIG5hbWUgfTtcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTtBQUNBO0FBY0E7QUFDQTtBQUNBO0FBQXVHO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUVoRyxJQUFNQSxTQUFTLEdBQUcsU0FBWkEsU0FBUyxPQUl5QjtFQUFBLElBSDdDQyxhQUFhLFFBQWJBLGFBQWE7RUFJYixJQUFNQyxtQkFBbUIsR0FBRyxJQUFBQyxpREFBcUMsRUFBQ0YsYUFBYSxDQUFDO0VBRWhGLElBQU1HLEtBQUssR0FBR0gsYUFBYSxDQUFDSSxHQUFHLENBQUMsVUFBQ0MsSUFBSSxFQUFLO0lBQ3hDLElBQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFRLEVBQUUsT0FBT0QsSUFBSTtJQUMvQixJQUFNRSxNQUFNLEdBQUdDLGlCQUFpQixDQUFDO01BQUVDLFlBQVksRUFBRUosSUFBSSxDQUFDQyxRQUFRO01BQUVMLG1CQUFtQixFQUFuQkE7SUFBb0IsQ0FBQyxDQUFD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