357 lines
56 KiB
Plaintext
357 lines
56 KiB
Plaintext
import { __assign, __awaiter, __generator } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29";
|
|
import { invariant } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29";
|
|
import { visit, BREAK, isSelectionNode } from "/_nuxt/node_modules/graphql/index.mjs?v=e4f18c29";
|
|
import { argumentsObjectFromField, buildQueryFromSelectionSet, createFragmentMap, getFragmentDefinitions, getMainDefinition, hasDirectives, isField, isInlineFragment, mergeDeep, mergeDeepArray, removeClientSetsFromDocument, resultKeyNameFromField, shouldInclude, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29";
|
|
import { cacheSlot } from "/_nuxt/node_modules/@apollo/client/cache/index.js?v=e4f18c29";
|
|
var LocalState = /** @class */ (function () {
|
|
function LocalState(_a) {
|
|
var cache = _a.cache, client = _a.client, resolvers = _a.resolvers, fragmentMatcher = _a.fragmentMatcher;
|
|
this.selectionsToResolveCache = new WeakMap();
|
|
this.cache = cache;
|
|
if (client) {
|
|
this.client = client;
|
|
}
|
|
if (resolvers) {
|
|
this.addResolvers(resolvers);
|
|
}
|
|
if (fragmentMatcher) {
|
|
this.setFragmentMatcher(fragmentMatcher);
|
|
}
|
|
}
|
|
LocalState.prototype.addResolvers = function (resolvers) {
|
|
var _this = this;
|
|
this.resolvers = this.resolvers || {};
|
|
if (Array.isArray(resolvers)) {
|
|
resolvers.forEach(function (resolverGroup) {
|
|
_this.resolvers = mergeDeep(_this.resolvers, resolverGroup);
|
|
});
|
|
}
|
|
else {
|
|
this.resolvers = mergeDeep(this.resolvers, resolvers);
|
|
}
|
|
};
|
|
LocalState.prototype.setResolvers = function (resolvers) {
|
|
this.resolvers = {};
|
|
this.addResolvers(resolvers);
|
|
};
|
|
LocalState.prototype.getResolvers = function () {
|
|
return this.resolvers || {};
|
|
};
|
|
// Run local client resolvers against the incoming query and remote data.
|
|
// Locally resolved field values are merged with the incoming remote data,
|
|
// and returned. Note that locally resolved fields will overwrite
|
|
// remote data using the same field name.
|
|
LocalState.prototype.runResolvers = function (_a) {
|
|
return __awaiter(this, arguments, void 0, function (_b) {
|
|
var document = _b.document, remoteResult = _b.remoteResult, context = _b.context, variables = _b.variables, _c = _b.onlyRunForcedResolvers, onlyRunForcedResolvers = _c === void 0 ? false : _c;
|
|
return __generator(this, function (_d) {
|
|
if (document) {
|
|
return [2 /*return*/, this.resolveDocument(document, remoteResult.data, context, variables, this.fragmentMatcher, onlyRunForcedResolvers).then(function (localResult) { return (__assign(__assign({}, remoteResult), { data: localResult.result })); })];
|
|
}
|
|
return [2 /*return*/, remoteResult];
|
|
});
|
|
});
|
|
};
|
|
LocalState.prototype.setFragmentMatcher = function (fragmentMatcher) {
|
|
this.fragmentMatcher = fragmentMatcher;
|
|
};
|
|
LocalState.prototype.getFragmentMatcher = function () {
|
|
return this.fragmentMatcher;
|
|
};
|
|
// Client queries contain everything in the incoming document (if a @client
|
|
// directive is found).
|
|
LocalState.prototype.clientQuery = function (document) {
|
|
if (hasDirectives(["client"], document)) {
|
|
if (this.resolvers) {
|
|
return document;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
// Server queries are stripped of all @client based selection sets.
|
|
LocalState.prototype.serverQuery = function (document) {
|
|
return removeClientSetsFromDocument(document);
|
|
};
|
|
LocalState.prototype.prepareContext = function (context) {
|
|
var cache = this.cache;
|
|
return __assign(__assign({}, context), { cache: cache,
|
|
// Getting an entry's cache key is useful for local state resolvers.
|
|
getCacheKey: function (obj) {
|
|
return cache.identify(obj);
|
|
} });
|
|
};
|
|
// To support `@client @export(as: "someVar")` syntax, we'll first resolve
|
|
// @client @export fields locally, then pass the resolved values back to be
|
|
// used alongside the original operation variables.
|
|
LocalState.prototype.addExportedVariables = function (document_1) {
|
|
return __awaiter(this, arguments, void 0, function (document, variables, context) {
|
|
if (variables === void 0) { variables = {}; }
|
|
if (context === void 0) { context = {}; }
|
|
return __generator(this, function (_a) {
|
|
if (document) {
|
|
return [2 /*return*/, this.resolveDocument(document, this.buildRootValueFromCache(document, variables) || {}, this.prepareContext(context), variables).then(function (data) { return (__assign(__assign({}, variables), data.exportedVariables)); })];
|
|
}
|
|
return [2 /*return*/, __assign({}, variables)];
|
|
});
|
|
});
|
|
};
|
|
LocalState.prototype.shouldForceResolvers = function (document) {
|
|
var forceResolvers = false;
|
|
visit(document, {
|
|
Directive: {
|
|
enter: function (node) {
|
|
if (node.name.value === "client" && node.arguments) {
|
|
forceResolvers = node.arguments.some(function (arg) {
|
|
return arg.name.value === "always" &&
|
|
arg.value.kind === "BooleanValue" &&
|
|
arg.value.value === true;
|
|
});
|
|
if (forceResolvers) {
|
|
return BREAK;
|
|
}
|
|
}
|
|
},
|
|
},
|
|
});
|
|
return forceResolvers;
|
|
};
|
|
// Query the cache and return matching data.
|
|
LocalState.prototype.buildRootValueFromCache = function (document, variables) {
|
|
return this.cache.diff({
|
|
query: buildQueryFromSelectionSet(document),
|
|
variables: variables,
|
|
returnPartialData: true,
|
|
optimistic: false,
|
|
}).result;
|
|
};
|
|
LocalState.prototype.resolveDocument = function (document_1, rootValue_1) {
|
|
return __awaiter(this, arguments, void 0, function (document, rootValue, context, variables, fragmentMatcher, onlyRunForcedResolvers) {
|
|
var mainDefinition, fragments, fragmentMap, selectionsToResolve, definitionOperation, defaultOperationType, _a, cache, client, execContext, isClientFieldDescendant;
|
|
if (context === void 0) { context = {}; }
|
|
if (variables === void 0) { variables = {}; }
|
|
if (fragmentMatcher === void 0) { fragmentMatcher = function () { return true; }; }
|
|
if (onlyRunForcedResolvers === void 0) { onlyRunForcedResolvers = false; }
|
|
return __generator(this, function (_b) {
|
|
mainDefinition = getMainDefinition(document);
|
|
fragments = getFragmentDefinitions(document);
|
|
fragmentMap = createFragmentMap(fragments);
|
|
selectionsToResolve = this.collectSelectionsToResolve(mainDefinition, fragmentMap);
|
|
definitionOperation = mainDefinition.operation;
|
|
defaultOperationType = definitionOperation ?
|
|
definitionOperation.charAt(0).toUpperCase() +
|
|
definitionOperation.slice(1)
|
|
: "Query";
|
|
_a = this, cache = _a.cache, client = _a.client;
|
|
execContext = {
|
|
fragmentMap: fragmentMap,
|
|
context: __assign(__assign({}, context), { cache: cache, client: client }),
|
|
variables: variables,
|
|
fragmentMatcher: fragmentMatcher,
|
|
defaultOperationType: defaultOperationType,
|
|
exportedVariables: {},
|
|
selectionsToResolve: selectionsToResolve,
|
|
onlyRunForcedResolvers: onlyRunForcedResolvers,
|
|
};
|
|
isClientFieldDescendant = false;
|
|
return [2 /*return*/, this.resolveSelectionSet(mainDefinition.selectionSet, isClientFieldDescendant, rootValue, execContext).then(function (result) { return ({
|
|
result: result,
|
|
exportedVariables: execContext.exportedVariables,
|
|
}); })];
|
|
});
|
|
});
|
|
};
|
|
LocalState.prototype.resolveSelectionSet = function (selectionSet, isClientFieldDescendant, rootValue, execContext) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var fragmentMap, context, variables, resultsToMerge, execute;
|
|
var _this = this;
|
|
return __generator(this, function (_a) {
|
|
fragmentMap = execContext.fragmentMap, context = execContext.context, variables = execContext.variables;
|
|
resultsToMerge = [rootValue];
|
|
execute = function (selection) { return __awaiter(_this, void 0, void 0, function () {
|
|
var fragment, typeCondition;
|
|
return __generator(this, function (_a) {
|
|
if (!isClientFieldDescendant &&
|
|
!execContext.selectionsToResolve.has(selection)) {
|
|
// Skip selections without @client directives
|
|
// (still processing if one of the ancestors or one of the child fields has @client directive)
|
|
return [2 /*return*/];
|
|
}
|
|
if (!shouldInclude(selection, variables)) {
|
|
// Skip this entirely.
|
|
return [2 /*return*/];
|
|
}
|
|
if (isField(selection)) {
|
|
return [2 /*return*/, this.resolveField(selection, isClientFieldDescendant, rootValue, execContext).then(function (fieldResult) {
|
|
var _a;
|
|
if (typeof fieldResult !== "undefined") {
|
|
resultsToMerge.push((_a = {},
|
|
_a[resultKeyNameFromField(selection)] = fieldResult,
|
|
_a));
|
|
}
|
|
})];
|
|
}
|
|
if (isInlineFragment(selection)) {
|
|
fragment = selection;
|
|
}
|
|
else {
|
|
// This is a named fragment.
|
|
fragment = fragmentMap[selection.name.value];
|
|
invariant(fragment, 19, selection.name.value);
|
|
}
|
|
if (fragment && fragment.typeCondition) {
|
|
typeCondition = fragment.typeCondition.name.value;
|
|
if (execContext.fragmentMatcher(rootValue, typeCondition, context)) {
|
|
return [2 /*return*/, this.resolveSelectionSet(fragment.selectionSet, isClientFieldDescendant, rootValue, execContext).then(function (fragmentResult) {
|
|
resultsToMerge.push(fragmentResult);
|
|
})];
|
|
}
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
}); };
|
|
return [2 /*return*/, Promise.all(selectionSet.selections.map(execute)).then(function () {
|
|
return mergeDeepArray(resultsToMerge);
|
|
})];
|
|
});
|
|
});
|
|
};
|
|
LocalState.prototype.resolveField = function (field, isClientFieldDescendant, rootValue, execContext) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var variables, fieldName, aliasedFieldName, aliasUsed, defaultResult, resultPromise, resolverType, resolverMap, resolve;
|
|
var _this = this;
|
|
return __generator(this, function (_a) {
|
|
if (!rootValue) {
|
|
return [2 /*return*/, null];
|
|
}
|
|
variables = execContext.variables;
|
|
fieldName = field.name.value;
|
|
aliasedFieldName = resultKeyNameFromField(field);
|
|
aliasUsed = fieldName !== aliasedFieldName;
|
|
defaultResult = rootValue[aliasedFieldName] || rootValue[fieldName];
|
|
resultPromise = Promise.resolve(defaultResult);
|
|
// Usually all local resolvers are run when passing through here, but
|
|
// if we've specifically identified that we only want to run forced
|
|
// resolvers (that is, resolvers for fields marked with
|
|
// `@client(always: true)`), then we'll skip running non-forced resolvers.
|
|
if (!execContext.onlyRunForcedResolvers ||
|
|
this.shouldForceResolvers(field)) {
|
|
resolverType = rootValue.__typename || execContext.defaultOperationType;
|
|
resolverMap = this.resolvers && this.resolvers[resolverType];
|
|
if (resolverMap) {
|
|
resolve = resolverMap[aliasUsed ? fieldName : aliasedFieldName];
|
|
if (resolve) {
|
|
resultPromise = Promise.resolve(
|
|
// In case the resolve function accesses reactive variables,
|
|
// set cacheSlot to the current cache instance.
|
|
cacheSlot.withValue(this.cache, resolve, [
|
|
rootValue,
|
|
argumentsObjectFromField(field, variables),
|
|
execContext.context,
|
|
{ field: field, fragmentMap: execContext.fragmentMap },
|
|
]));
|
|
}
|
|
}
|
|
}
|
|
return [2 /*return*/, resultPromise.then(function (result) {
|
|
var _a, _b;
|
|
if (result === void 0) { result = defaultResult; }
|
|
// If an @export directive is associated with the current field, store
|
|
// the `as` export variable name and current result for later use.
|
|
if (field.directives) {
|
|
field.directives.forEach(function (directive) {
|
|
if (directive.name.value === "export" && directive.arguments) {
|
|
directive.arguments.forEach(function (arg) {
|
|
if (arg.name.value === "as" && arg.value.kind === "StringValue") {
|
|
execContext.exportedVariables[arg.value.value] = result;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
// Handle all scalar types here.
|
|
if (!field.selectionSet) {
|
|
return result;
|
|
}
|
|
// From here down, the field has a selection set, which means it's trying
|
|
// to query a GraphQLObjectType.
|
|
if (result == null) {
|
|
// Basically any field in a GraphQL response can be null, or missing
|
|
return result;
|
|
}
|
|
var isClientField = (_b = (_a = field.directives) === null || _a === void 0 ? void 0 : _a.some(function (d) { return d.name.value === "client"; })) !== null && _b !== void 0 ? _b : false;
|
|
if (Array.isArray(result)) {
|
|
return _this.resolveSubSelectedArray(field, isClientFieldDescendant || isClientField, result, execContext);
|
|
}
|
|
// Returned value is an object, and the query has a sub-selection. Recurse.
|
|
if (field.selectionSet) {
|
|
return _this.resolveSelectionSet(field.selectionSet, isClientFieldDescendant || isClientField, result, execContext);
|
|
}
|
|
})];
|
|
});
|
|
});
|
|
};
|
|
LocalState.prototype.resolveSubSelectedArray = function (field, isClientFieldDescendant, result, execContext) {
|
|
var _this = this;
|
|
return Promise.all(result.map(function (item) {
|
|
if (item === null) {
|
|
return null;
|
|
}
|
|
// This is a nested array, recurse.
|
|
if (Array.isArray(item)) {
|
|
return _this.resolveSubSelectedArray(field, isClientFieldDescendant, item, execContext);
|
|
}
|
|
// This is an object, run the selection set on it.
|
|
if (field.selectionSet) {
|
|
return _this.resolveSelectionSet(field.selectionSet, isClientFieldDescendant, item, execContext);
|
|
}
|
|
}));
|
|
};
|
|
// Collect selection nodes on paths from document root down to all @client directives.
|
|
// This function takes into account transitive fragment spreads.
|
|
// Complexity equals to a single `visit` over the full document.
|
|
LocalState.prototype.collectSelectionsToResolve = function (mainDefinition, fragmentMap) {
|
|
var isSingleASTNode = function (node) { return !Array.isArray(node); };
|
|
var selectionsToResolveCache = this.selectionsToResolveCache;
|
|
function collectByDefinition(definitionNode) {
|
|
if (!selectionsToResolveCache.has(definitionNode)) {
|
|
var matches_1 = new Set();
|
|
selectionsToResolveCache.set(definitionNode, matches_1);
|
|
visit(definitionNode, {
|
|
Directive: function (node, _, __, ___, ancestors) {
|
|
if (node.name.value === "client") {
|
|
ancestors.forEach(function (node) {
|
|
if (isSingleASTNode(node) && isSelectionNode(node)) {
|
|
matches_1.add(node);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
FragmentSpread: function (spread, _, __, ___, ancestors) {
|
|
var fragment = fragmentMap[spread.name.value];
|
|
invariant(fragment, 20, spread.name.value);
|
|
var fragmentSelections = collectByDefinition(fragment);
|
|
if (fragmentSelections.size > 0) {
|
|
// Fragment for this spread contains @client directive (either directly or transitively)
|
|
// Collect selection nodes on paths from the root down to fields with the @client directive
|
|
ancestors.forEach(function (node) {
|
|
if (isSingleASTNode(node) && isSelectionNode(node)) {
|
|
matches_1.add(node);
|
|
}
|
|
});
|
|
matches_1.add(spread);
|
|
fragmentSelections.forEach(function (selection) {
|
|
matches_1.add(selection);
|
|
});
|
|
}
|
|
},
|
|
});
|
|
}
|
|
return selectionsToResolveCache.get(definitionNode);
|
|
}
|
|
return collectByDefinition(mainDefinition);
|
|
};
|
|
return LocalState;
|
|
}());
|
|
export { LocalState };
|
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9jYWxTdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL0xvY2FsU3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQWUxRCxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFJeEQsT0FBTyxFQUNMLHdCQUF3QixFQUN4QiwwQkFBMEIsRUFDMUIsaUJBQWlCLEVBQ2pCLHNCQUFzQixFQUN0QixpQkFBaUIsRUFDakIsYUFBYSxFQUNiLE9BQU8sRUFDUCxnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULGNBQWMsRUFDZCw0QkFBNEIsRUFDNUIsc0JBQXNCLEVBQ3RCLGFBQWEsR0FDZCxNQUFNLHVCQUF1QixDQUFDO0FBSS9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQXNDOUM7SUFVRSxvQkFBWSxFQUtxQjtZQUovQixLQUFLLFdBQUEsRUFDTCxNQUFNLFlBQUEsRUFDTixTQUFTLGVBQUEsRUFDVCxlQUFlLHFCQUFBO1FBVFQsNkJBQXdCLEdBQUcsSUFBSSxPQUFPLEVBRzNDLENBQUM7UUFRRixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUVuQixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDdkIsQ0FBQztRQUVELElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFFRCxJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMzQyxDQUFDO0lBQ0gsQ0FBQztJQUVNLGlDQUFZLEdBQW5CLFVBQW9CLFNBQWtDO1FBQXRELGlCQVNDO1FBUkMsSUFBSSxD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QkFDekIsQ0FBQyxDQUFDLENBQUM7d0JBQ0wsQ0FBQztvQkFDSCxDQUFDO2lCQUNGLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxPQUFPLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUUsQ0FBQztRQUN2RCxDQUFDO1FBQ0QsT0FBTyxtQkFBbUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBQ0gsaUJBQUM7QUFBRCxDQUFDLEFBeGVELElBd2VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW52YXJpYW50IH0gZnJvbSBcIi4uL3V0aWxpdGllcy9nbG9iYWxzL2luZGV4LmpzXCI7XG5cbmltcG9ydCB0eXBlIHtcbiAgRG9jdW1lbnROb2RlLFxuICBPcGVyYXRpb25EZWZpbml0aW9uTm9kZSxcbiAgU2VsZWN0aW9uU2V0Tm9kZSxcbiAgU2VsZWN0aW9uTm9kZSxcbiAgSW5saW5lRnJhZ21lbnROb2RlLFxuICBGcmFnbWVudERlZmluaXRpb25Ob2RlLFxuICBGaWVsZE5vZGUsXG4gIEFTVE5vZGUsXG4gIERpcmVjdGl2ZU5vZGUsXG4gIEZyYWdtZW50U3ByZWFkTm9kZSxcbiAgRXhlY3V0YWJsZURlZmluaXRpb25Ob2RlLFxufSBmcm9tIFwiZ3JhcGhxbFwiO1xuaW1wb3J0IHsgdmlzaXQsIEJSRUFLLCBpc1NlbGVjdGlvbk5vZGUgfSBmcm9tIFwiZ3JhcGhxbFwiO1xuXG5pbXBvcnQgdHlwZSB7IEFwb2xsb0NhY2hlIH0gZnJvbSBcIi4uL2NhY2hlL2luZGV4LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEZyYWdtZW50TWFwLCBTdG9yZU9iamVjdCB9IGZyb20gXCIuLi91dGlsaXRpZXMvaW5kZXguanNcIjtcbmltcG9ydCB7XG4gIGFyZ3VtZW50c09iamVjdEZyb21GaWVsZCxcbiAgYnVpbGRRdWVyeUZyb21TZWxlY3Rpb25TZXQsXG4gIGNyZWF0ZUZyYWdtZW50TWFwLFxuICBnZXRGcmFnbWVudERlZmluaXRpb25zLFxuICBnZXRNYWluRGVmaW5pdGlvbixcbiAgaGFzRGlyZWN0aXZlcyxcbiAgaXNGaWVsZCxcbiAgaXNJbmxpbmVGcmFnbWVudCxcbiAgbWVyZ2VEZWVwLFxuICBtZXJnZURlZXBBcnJheSxcbiAgcmVtb3ZlQ2xpZW50U2V0c0Zyb21Eb2N1bWVudCxcbiAgcmVzdWx0S2V5TmFtZUZyb21GaWVsZCxcbiAgc2hvdWxkSW5jbHVkZSxcbn0gZnJvbSBcIi4uL3V0aWxpdGllcy9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBBcG9sbG9DbGllbnQgfSBmcm9tIFwiLi9BcG9sbG9DbGllbnQuanNcIjtcbmltcG9ydCB0eXBlIHsgUmVzb2x2ZXJzLCBPcGVyYXRpb25WYXJpYWJsZXMgfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBGZXRjaFJlc3VsdCB9IGZyb20gXCIuLi9saW5rL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCB7IGNhY2hlU2xvdCB9IGZyb20gXCIuLi9jYWNoZS9pbmRleC5qc1wiO1xuXG5leHBvcnQgdHlwZSBSZXNvbHZlciA9IChcbiAgcm9vdFZhbHVlPzogYW55LFxuICBhcmdzPzogYW55LFxuICBjb250ZXh0PzogYW55LFxuICBpbmZvPzoge1xuICAgIGZpZWxkOiBGaWVsZE5vZGU7XG4gICAgZnJhZ21lbnRNYXA6IEZyYWdtZW50TWFwO1xuICB9XG4pID0+IGFueTtcblxuZXhwb3J0IHR5cGUgVmFyaWFibGVNYXAgPSB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfTtcblxuZXhwb3J0IHR5cGUgRnJhZ21lbnRNYXRjaGVyID0gKFxuICByb290VmFsdWU6IGFueSxcbiAgdHlwZUNvbmRpdGlvbjogc3RyaW5nLFxuICBjb250ZXh0OiBhbnlcbikgPT4gYm9vbGVhbjtcblxuZXhwb3J0IHR5cGUgRXhlY0NvbnRleHQgPSB7XG4gIGZyYWdtZW50TWFwOiBGcmFnbWVudE1hcDtcbiAgY29udGV4dDogYW55O1xuICB2YXJpYWJsZXM6IFZhcmlhYmxlTWFwO1xuICBmcmFnbWVudE1hdGNoZXI6IEZyYWdtZW50TWF0Y2hlcjtcbiAgZGVmYXVsdE9wZXJhdGlvblR5cGU6IHN0cmluZztcbiAgZXhwb3J0ZWRWYXJpYWJsZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIG9ubHlSdW5Gb3JjZWRSZXNvbHZlcnM6IGJvb2xlYW47XG4gIHNlbGVjdGlvbnNUb1Jlc29sdmU6IFNldDxTZWxlY3Rpb25Ob2RlPjtcbn07XG5cbmV4cG9ydCB0eXBlIExvY2FsU3RhdGVPcHRpb25zPFRDYWNoZVNoYXBlPiA9IHtcbiAgY2FjaGU6IEFwb2xsb0NhY2hlPFRDYWNoZVNoYXBlPjtcbiAgY2xpZW50PzogQXBvbGxvQ2xpZW50PFRDYWNoZVNoYXBlPjtcbiAgcmVzb2x2ZXJzPzogUmVzb2x2ZXJzIHwgUmVzb2x2ZXJzW107XG4gIGZyYWdtZW50TWF0Y2hlcj86IEZyYWdtZW50TWF0Y2hlcjtcbn07XG5cbmV4cG9ydCBjbGFzcyBMb2NhbFN0YXRlPFRDYWNoZVNoYXBlPiB7XG4gIHByaXZhdGUgY2FjaGU6IEFwb2xsb0NhY2hlPFRDYWNoZVNoYXBlPjtcbiAgcHJpdmF0ZSBjbGllbnQ/OiBBcG9sbG9DbGllbnQ8VENhY2hlU2hhcGU+O1xuICBwcml2YXRlIHJlc29sdmVycz86IFJlc29sdmVycztcbiAgcHJpdmF0ZSBmcmFnbWVudE1hdGNoZXI/OiBGcmFnbWVudE1hdGNoZXI7XG4gIHByaXZhdGUgc2VsZWN0aW9uc1RvUmVzb2x2ZUNhY2hlID0gbmV3IFdlYWtNYXA8XG4gICAgRXhlY3V0YWJsZURlZmluaXRpb25Ob2RlLFxuICAgIFNldDxTZWxlY3Rpb25Ob2RlPlxuICA+KCk7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGNhY2hlLFxuICAgIGNsaWVudCxcbiAgICByZXNvbHZlcnMsXG4gICAgZnJhZ21lbnRNYXRjaGVyLFxuICB9OiBMb2NhbFN0YXRlT3B0aW9uczxUQ2FjaGVTaGFwZT4pIHtcbiAgICB0aGlzLmNhY2hlID0gY2FjaGU7XG5cbiAgICBpZiAoY2xpZW50KSB7XG4gICAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgICB9XG5cbiAgICBpZiAocmVzb2x2ZXJzKSB7XG4gICAgICB0aGlzLmFkZFJlc29sdmVycyhyZXNvbHZlcnMpO1xuICAgIH1cblxuICAgIGlmIChmcmFnbWVudE1hdGNoZXIpIHtcbiAgICAgIHRoaXMuc2V0RnJhZ21lbnRNYXRjaGVyKGZyYWdtZW50TWF0Y2hlcik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZFJlc29sdmVycyhyZXNvbHZlcnM6IFJlc29sdmVycyB8IFJlc29sdmVyc1tdKSB7XG4gICAgdGhpcy5yZXNvbHZlcnMgPSB0aGlzLnJlc29sdmVycyB8fCB7fTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXNvbHZlcnMpKSB7XG4gICAgICByZXNvbHZlcnMuZm9yRWFjaCgocmVzb2x2ZXJHcm91cCkgPT4ge1xuICAgICAgICB0aGlzLnJlc29sdmVycyA9IG1lcmdlRGVlcCh0aGlzLnJlc29sdmVycywgcmVzb2x2ZXJHcm91cCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZXNvbHZlcnMgPSBtZXJnZURlZXAodGhpcy5yZXNvbHZlcnMsIHJlc29sdmVycyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNldFJlc29sdmVycyhyZXNvbHZlcnM6IFJlc29sdmVycyB8IFJlc29sdmVyc1tdKSB7XG4gICAgdGhpcy5yZXNvbHZlcnMgPSB7fTtcbiAgICB0aGlzLmFkZFJlc29sdmVycyhyZXNvbHZlcnMpO1xuICB9XG5cbiAgcHVibGljIGdldFJlc29sdmVycygpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlcnMgfHwge307XG4gIH1cblxuICAvLyBSdW4gbG9jYWwgY2xpZW50IHJlc29sdmVycyBhZ2FpbnN0IHRoZSBpbmNvbWluZyBxdWVyeSBhbmQgcmVtb3RlIGRhdGEuXG4gIC8vIExvY2FsbHkgcmVzb2x2ZWQgZmllbGQgdmFsdWVzIGFyZSBtZXJnZWQgd2l0aCB0aGUgaW5jb21pbmcgcmVtb3RlIGRhdGEsXG4gIC8vIGFuZCByZXR1cm5lZC4gTm90ZSB0aGF0IGxvY2FsbHkgcmVzb2x2ZWQgZmllbGRzIHdpbGwgb3ZlcndyaXRlXG4gIC8vIHJlbW90ZSBkYXRhIHVzaW5nIHRoZSBzYW1lIGZpZWxkIG5hbWUuXG4gIHB1YmxpYyBhc3luYyBydW5SZXNvbHZlcnM8VERhdGE+KHtcbiAgICBkb2N1bWVudCxcbiAgICByZW1vdGVSZXN1bHQsXG4gICAgY29udGV4dCxcbiAgICB2YXJpYWJsZXMsXG4gICAgb25seVJ1bkZvcmNlZFJlc29sdmVycyA9IGZhbHNlLFxuICB9OiB7XG4gICAgZG9jdW1lbnQ6IERvY3VtZW50Tm9kZSB8IG51bGw7XG4gICAgcmVtb3RlUmVzdWx0OiBGZXRjaFJlc3VsdDxURGF0YT47XG4gICAgY29udGV4dD86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgdmFyaWFibGVzPzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICBvbmx5UnVuRm9yY2VkUmVzb2x2ZXJzPzogYm9vbGVhbjtcbiAgfSk6IFByb21pc2U8RmV0Y2hSZXN1bHQ8VERhdGE+PiB7XG4gICAgaWYgKGRvY3VtZW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXNvbHZlRG9jdW1lbnQoXG4gICAgICAgIGRvY3VtZW50LFxuICAgICAgICByZW1vdGVSZXN1bHQuZGF0YSxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgdmFyaWFibGVzLFxuICAgICAgICB0aGlzLmZyYWdtZW50TWF0Y2hlcixcbiAgICAgICAgb25seVJ1bkZvcmNlZFJlc29sdmVyc1xuICAgICAgKS50aGVuKChsb2NhbFJlc3VsdCkgPT4gKHtcbiAgICAgICAgLi4ucmVtb3RlUmVzdWx0LFxuICAgICAgICBkYXRhOiBsb2NhbFJlc3VsdC5yZXN1bHQsXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlbW90ZVJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRGcmFnbWVudE1hdGNoZXIoZnJhZ21lbnRNYXRjaGVyOiBGcmFnbWVudE1hdGNoZXIpIHtcbiAgICB0aGlzLmZyYWdtZW50TWF0Y2hlciA9IGZyYWdtZW50TWF0Y2hlcjtcbiAgfVxuXG4gIHB1YmxpYyBnZXRGcmFnbWVudE1hdGNoZXIoKTogRnJhZ21lbnRNYXRjaGVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5mcmFnbWVudE1hdGNoZXI7XG4gIH1cblxuICAvLyBDbGllbnQgcXVlcmllcyBjb250YWluIGV2ZXJ5dGhpbmcgaW4gdGhlIGluY29taW5nIGRvY3VtZW50IChpZiBhIEBjbGllbnRcbiAgLy8gZGlyZWN0aXZlIGlzIGZvdW5kKS5cbiAgcHVibGljIGNsaWVudFF1ZXJ5KGRvY3VtZW50OiBEb2N1bWVudE5vZGUpIHtcbiAgICBpZiAoaGFzRGlyZWN0aXZlcyhbXCJjbGllbnRcIl0sIGRvY3VtZW50KSkge1xuICAgICAgaWYgKHRoaXMucmVzb2x2ZXJzKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBTZXJ2ZXIgcXVlcmllcyBhcmUgc3RyaXBwZWQgb2YgYWxsIEBjbGllbnQgYmFzZWQgc2VsZWN0aW9uIHNldHMuXG4gIHB1YmxpYyBzZXJ2ZXJRdWVyeShkb2N1bWVudDogRG9jdW1lbnROb2RlKSB7XG4gICAgcmV0dXJuIHJlbW92ZUNsaWVudFNldHNGcm9tRG9jdW1lbnQoZG9jdW1lbnQpO1xuICB9XG5cbiAgcHVibGljIHByZXBhcmVDb250ZXh0KGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgY29uc3QgeyBjYWNoZSB9ID0gdGhpcztcbiAgICByZXR1cm4ge1xuICAgICAgLi4uY29udGV4dCxcbiAgICAgIGNhY2hlLFxuICAgICAgLy8gR2V0dGluZyBhbiBlbnRyeSdzIGNhY2hlIGtleSBpcyB1c2VmdWwgZm9yIGxvY2FsIHN0YXRlIHJlc29sdmVycy5cbiAgICAgIGdldENhY2hlS2V5KG9iajogU3RvcmVPYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlLmlkZW50aWZ5KG9iaik7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvLyBUbyBzdXBwb3J0IGBAY2xpZW50IEBleHBvcnQoYXM6IFwic29tZVZhclwiKWAgc3ludGF4LCB3ZSdsbCBmaXJzdCByZXNvbHZlXG4gIC8vIEBjbGllbnQgQGV4cG9ydCBmaWVsZHMgbG9jYWxseSwgdGhlbiBwYXNzIHRoZSByZXNvbHZlZCB2YWx1ZXMgYmFjayB0byBiZVxuICAvLyB1c2VkIGFsb25nc2lkZSB0aGUgb3JpZ2luYWwgb3BlcmF0aW9uIHZhcmlhYmxlcy5cbiAgcHVibGljIGFzeW5jIGFkZEV4cG9ydGVkVmFyaWFibGVzPFRWYXJzIGV4dGVuZHMgT3BlcmF0aW9uVmFyaWFibGVzPihcbiAgICBkb2N1bWVudDogRG9jdW1lbnROb2RlLFxuICAgIHZhcmlhYmxlczogVFZhcnMgPSB7fSBhcyBUVmFycyxcbiAgICBjb250ZXh0ID0ge31cbiAgKTogLyogcmV0dXJucyBhdCBsZWFzdCB0aGUgdmFyaWFibGVzIHRoYXQgd2VyZSBwYXNzZWQgaW4gKi8gUHJvbWlzZTxUVmFycz4ge1xuICAgIGlmIChkb2N1bWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZURvY3VtZW50KFxuICAgICAgICBkb2N1bWVudCxcbiAgICAgICAgdGhpcy5idWlsZFJvb3RWYWx1ZUZyb21DYWNoZShkb2N1bWVudCwgdmFyaWFibGVzKSB8fCB7fSxcbiAgICAgICAgdGhpcy5wcmVwYXJlQ29udGV4dChjb250ZXh0KSxcbiAgICAgICAgdmFyaWFibGVzXG4gICAgICApLnRoZW4oKGRhdGEpID0+ICh7XG4gICAgICAgIC4uLnZhcmlhYmxlcyxcbiAgICAgICAgLi4uZGF0YS5leHBvcnRlZFZhcmlhYmxlcyxcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udmFyaWFibGVzLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgc2hvdWxkRm9yY2VSZXNvbHZlcnMoZG9jdW1lbnQ6IEFTVE5vZGUpIHtcbiAgICBsZXQgZm9yY2VSZXNvbHZlcnMgPSBmYWxzZTtcbiAgICB2aXNpdChkb2N1bWVudCwge1xuICAgICAgRGlyZWN0aXZlOiB7XG4gICAgICAgIGVudGVyKG5vZGUpIHtcbiAgICAgICAgICBpZiAobm9kZS5uYW1lLnZhbHVlID09PSBcImNsaWVudFwiICYmIG5vZGUuYXJndW1lbnRzKSB7XG4gICAgICAgICAgICBmb3JjZVJlc29sdmVycyA9IG5vZGUuYXJndW1lbnRzLnNvbWUoXG4gICAgICAgICAgICAgIChhcmcpID0+XG4gICAgICAgICAgICAgICAgYXJnLm5hbWUudmFsdWUgPT09IFwiYWx3YXlzXCIgJiZcbiAgICAgICAgICAgICAgICBhcmcudmFsdWUua2luZCA9PT0gXCJCb29sZWFuVmFsdWVcIiAmJlxuICAgICAgICAgICAgICAgIGFyZy52YWx1ZS52YWx1ZSA9PT0gdHJ1ZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChmb3JjZVJlc29sdmVycykge1xuICAgICAgICAgICAgICByZXR1cm4gQlJFQUs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gZm9yY2VSZXNvbHZlcnM7XG4gIH1cblxuICAvLyBRdWVyeSB0aGUgY2FjaGUgYW5kIHJldHVybiBtYXRjaGluZyBkYXRhLlxuICBwcml2YXRlIGJ1aWxkUm9vdFZhbHVlRnJvbUNhY2hlKFxuICAgIGRvY3VtZW50OiBEb2N1bWVudE5vZGUsXG4gICAgdmFyaWFibGVzPzogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5kaWZmKHtcbiAgICAgIHF1ZXJ5OiBidWlsZFF1ZXJ5RnJvbVNlbGVjdGlvblNldChkb2N1bWVudCksXG4gICAgICB2YXJpYWJsZXMsXG4gICAgICByZXR1cm5QYXJ0aWFsRGF0YTogdHJ1ZSxcbiAgICAgIG9wdGltaXN0aWM6IGZhbHNlLFxuICAgIH0pLnJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZURvY3VtZW50PFREYXRhPihcbiAgICBkb2N1bWVudDogRG9jdW1lbnROb2RlLFxuICAgIHJvb3RWYWx1ZTogVERhdGEsXG4gICAgY29udGV4dDogYW55ID0ge30sXG4gICAgdmFyaWFibGVzOiBWYXJpYWJsZU1hcCA9IHt9LFxuICAgIGZyYWdtZW50TWF0Y2hlcjogRnJhZ21lbnRNYXRjaGVyID0gKCkgPT4gdHJ1ZSxcbiAgICBvbmx5UnVuRm9yY2VkUmVzb2x2ZXJzOiBib29sZWFuID0gZmFsc2VcbiAgKSB7XG4gICAgY29uc3QgbWFpbkRlZmluaXRpb24gPSBnZXRNYWluRGVmaW5pdGlvbihcbiAgICAgIGRvY3VtZW50XG4gICAgKSBhcyBPcGVyYXRpb25EZWZpbml0aW9uTm9kZTtcbiAgICBjb25zdCBmcmFnbWVudHMgPSBnZXRGcmFnbWVudERlZmluaXRpb25zKGRvY3VtZW50KTtcbiAgICBjb25zdCBmcmFnbWVudE1hcCA9IGNyZWF0ZUZyYWdtZW50TWFwKGZyYWdtZW50cyk7XG4gICAgY29uc3Qgc2VsZWN0aW9uc1RvUmVzb2x2ZSA9IHRoaXMuY29sbGVjdFNlbGVjdGlvbnNUb1Jlc29sdmUoXG4gICAgICBtYWluRGVmaW5pdGlvbixcbiAgICAgIGZyYWdtZW50TWFwXG4gICAgKTtcblxuICAgIGNvbnN0IGRlZmluaXRpb25PcGVyYXRpb24gPSBtYWluRGVmaW5pdGlvbi5vcGVyYXRpb247XG5cbiAgICBjb25zdCBkZWZhdWx0T3BlcmF0aW9uVHlwZSA9XG4gICAgICBkZWZpbml0aW9uT3BlcmF0aW9uID9cbiAgICAgICAgZGVmaW5pdGlvbk9wZXJhdGlvbi5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArXG4gICAgICAgIGRlZmluaXRpb25PcGVyYXRpb24uc2xpY2UoMSlcbiAgICAgIDogXCJRdWVyeVwiO1xuXG4gICAgY29uc3QgeyBjYWNoZSwgY2xpZW50IH0gPSB0aGlzO1xuICAgIGNvbnN0IGV4ZWNDb250ZXh0OiBFeGVjQ29udGV4dCA9IHtcbiAgICAgIGZyYWdtZW50TWFwLFxuICAgICAgY29udGV4dDoge1xuICAgICAgICAuLi5jb250ZXh0LFxuICAgICAgICBjYWNoZSxcbiAgICAgICAgY2xpZW50LFxuICAgICAgfSxcbiAgICAgIHZhcmlhYmxlcyxcbiAgICAgIGZyYWdtZW50TWF0Y2hlcixcbiAgICAgIGRlZmF1bHRPcGVyYXRpb25UeXBlLFxuICAgICAgZXhwb3J0ZWRWYXJpYWJsZXM6IHt9LFxuICAgICAgc2VsZWN0aW9uc1RvUmVzb2x2ZSxcbiAgICAgIG9ubHlSdW5Gb3JjZWRSZXNvbHZlcnMsXG4gICAgfTtcbiAgICBjb25zdCBpc0NsaWVudEZpZWxkRGVzY2VuZGFudCA9IGZhbHNlO1xuXG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZVNlbGVjdGlvblNldChcbiAgICAgIG1haW5EZWZpbml0aW9uLnNlbGVjdGlvblNldCxcbiAgICAgIGlzQ2xpZW50RmllbGREZXNjZW5kYW50LFxuICAgICAgcm9vdFZhbHVlLFxuICAgICAgZXhlY0NvbnRleHRcbiAgICApLnRoZW4oKHJlc3VsdCkgPT4gKHtcbiAgICAgIHJlc3VsdCxcbiAgICAgIGV4cG9ydGVkVmFyaWFibGVzOiBleGVjQ29udGV4dC5leHBvcnRlZFZhcmlhYmxlcyxcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlc29sdmVTZWxlY3Rpb25TZXQ8VERhdGE+KFxuICAgIHNlbGVjdGlvblNldDogU2VsZWN0aW9uU2V0Tm9kZSxcbiAgICBpc0NsaWVudEZpZWxkRGVzY2VuZGFudDogYm9vbGVhbixcbiAgICByb290VmFsdWU6IFREYXRhLFxuICAgIGV4ZWNDb250ZXh0OiBFeGVjQ29udGV4dFxuICApIHtcbiAgICBjb25zdCB7IGZyYWdtZW50TWFwLCBjb250ZXh0LCB2YXJpYWJsZXMgfSA9IGV4ZWNDb250ZXh0O1xuICAgIGNvbnN0IHJlc3VsdHNUb01lcmdlOiBURGF0YVtdID0gW3Jvb3RWYWx1ZV07XG5cbiAgICBjb25zdCBleGVjdXRlID0gYXN5bmMgKHNlbGVjdGlvbjogU2VsZWN0aW9uTm9kZSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhaXNDbGllbnRGaWVsZERlc2NlbmRhbnQgJiZcbiAgICAgICAgIWV4ZWNDb250ZXh0LnNlbGVjdGlvbnNUb1Jlc29sdmUuaGFzKHNlbGVjdGlvbilcbiAgICAgICkge1xuICAgICAgICAvLyBTa2lwIHNlbGVjdGlvbnMgd2l0aG91dCBAY2xpZW50IGRpcmVjdGl2ZXNcbiAgICAgICAgLy8gKHN0aWxsIHByb2Nlc3NpbmcgaWYgb25lIG9mIHRoZSBhbmNlc3RvcnMgb3Igb25lIG9mIHRoZSBjaGlsZCBmaWVsZHMgaGFzIEBjbGllbnQgZGlyZWN0aXZlKVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIXNob3VsZEluY2x1ZGUoc2VsZWN0aW9uLCB2YXJpYWJsZXMpKSB7XG4gICAgICAgIC8vIFNraXAgdGhpcyBlbnRpcmVseS5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNGaWVsZChzZWxlY3Rpb24pKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVGaWVsZChcbiAgICAgICAgICBzZWxlY3Rpb24sXG4gICAgICAgICAgaXNDbGllbnRGaWVsZERlc2NlbmRhbnQsXG4gICAgICAgICAgcm9vdFZhbHVlLFxuICAgICAgICAgIGV4ZWNDb250ZXh0XG4gICAgICAgICkudGhlbigoZmllbGRSZXN1bHQpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGZpZWxkUmVzdWx0ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICByZXN1bHRzVG9NZXJnZS5wdXNoKHtcbiAgICAgICAgICAgICAgW3Jlc3VsdEtleU5hbWVGcm9tRmllbGQoc2VsZWN0aW9uKV06IGZpZWxkUmVzdWx0LFxuICAgICAgICAgICAgfSBhcyBURGF0YSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgbGV0IGZyYWdtZW50OiBJbmxpbmVGcmFnbWVudE5vZGUgfCBGcmFnbWVudERlZmluaXRpb25Ob2RlO1xuXG4gICAgICBpZiAoaXNJbmxpbmVGcmFnbWVudChzZWxlY3Rpb24pKSB7XG4gICAgICAgIGZyYWdtZW50ID0gc2VsZWN0aW9uO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIG5hbWVkIGZyYWdtZW50LlxuICAgICAgICBmcmFnbWVudCA9IGZyYWdtZW50TWFwW3NlbGVjdGlvbi5uYW1lLnZhbHVlXTtcbiAgICAgICAgaW52YXJpYW50KGZyYWdtZW50LCBgTm8gZnJhZ21lbnQgbmFtZWQgJXNgLCBzZWxlY3Rpb24ubmFtZS52YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmcmFnbWVudCAmJiBmcmFnbWVudC50eXBlQ29uZGl0aW9uKSB7XG4gICAgICAgIGNvbnN0IHR5cGVDb25kaXRpb24gPSBmcmFnbWVudC50eXBlQ29uZGl0aW9uLm5hbWUudmFsdWU7XG4gICAgICAgIGlmIChleGVjQ29udGV4dC5mcmFnbWVudE1hdGNoZXIocm9vdFZhbHVlLCB0eXBlQ29uZGl0aW9uLCBjb250ZXh0KSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVTZWxlY3Rpb25TZXQoXG4gICAgICAgICAgICBmcmFnbWVudC5zZWxlY3Rpb25TZXQsXG4gICAgICAgICAgICBpc0NsaWVudEZpZWxkRGVzY2VuZGFudCxcbiAgICAgICAgICAgIHJvb3RWYWx1ZSxcbiAgICAgICAgICAgIGV4ZWNDb250ZXh0XG4gICAgICAgICAgKS50aGVuKChmcmFnbWVudFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgcmVzdWx0c1RvTWVyZ2UucHVzaChmcmFnbWVudFJlc3VsdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHNlbGVjdGlvblNldC5zZWxlY3Rpb25zLm1hcChleGVjdXRlKSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gbWVyZ2VEZWVwQXJyYXkocmVzdWx0c1RvTWVyZ2UpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZXNvbHZlRmllbGQoXG4gICAgZmllbGQ6IEZpZWxkTm9kZSxcbiAgICBpc0NsaWVudEZpZWxkRGVzY2VuZGFudDogYm9vbGVhbixcbiAgICByb290VmFsdWU6IGFueSxcbiAgICBleGVjQ29udGV4dDogRXhlY0NvbnRleHRcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAoIXJvb3RWYWx1ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgeyB2YXJpYWJsZXMgfSA9IGV4ZWNDb250ZXh0O1xuICAgIGNvbnN0IGZpZWxkTmFtZSA9IGZpZWxkLm5hbWUudmFsdWU7XG4gICAgY29uc3QgYWxpYXNlZEZpZWxkTmFtZSA9IHJlc3VsdEtleU5hbWVGcm9tRmllbGQoZmllbGQpO1xuICAgIGNvbnN0IGFsaWFzVXNlZCA9IGZpZWxkTmFtZSAhPT0gYWxpYXNlZEZpZWxkTmFtZTtcbiAgICBjb25zdCBkZWZhdWx0UmVzdWx0ID0gcm9vdFZhbHVlW2FsaWFzZWRGaWVsZE5hbWVdIHx8IHJvb3RWYWx1ZVtmaWVsZE5hbWVdO1xuICAgIGxldCByZXN1bHRQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGRlZmF1bHRSZXN1bHQpO1xuXG4gICAgLy8gVXN1YWxseSBhbGwgbG9jYWwgcmVzb2x2ZXJzIGFyZSBydW4gd2hlbiBwYXNzaW5nIHRocm91Z2ggaGVyZSwgYnV0XG4gICAgLy8gaWYgd2UndmUgc3BlY2lmaWNhbGx5IGlkZW50aWZpZWQgdGhhdCB3ZSBvbmx5IHdhbnQgdG8gcnVuIGZvcmNlZFxuICAgIC8vIHJlc29sdmVycyAodGhhdCBpcywgcmVzb2x2ZXJzIGZvciBmaWVsZHMgbWFya2VkIHdpdGhcbiAgICAvLyBgQGNsaWVudChhbHdheXM6IHRydWUpYCksIHRoZW4gd2UnbGwgc2tpcCBydW5uaW5nIG5vbi1mb3JjZWQgcmVzb2x2ZXJzLlxuICAgIGlmIChcbiAgICAgICFleGVjQ29udGV4dC5vbmx5UnVuRm9yY2VkUmVzb2x2ZXJzIHx8XG4gICAgICB0aGlzLnNob3VsZEZvcmNlUmVzb2x2ZXJzKGZpZWxkKVxuICAgICkge1xuICAgICAgY29uc3QgcmVzb2x2ZXJUeXBlID1cbiAgICAgICAgcm9vdFZhbHVlLl9fdHlwZW5hbWUgfHwgZXhlY0NvbnRleHQuZGVmYXVsdE9wZXJhdGlvblR5cGU7XG4gICAgICBjb25zdCByZXNvbHZlck1hcCA9IHRoaXMucmVzb2x2ZXJzICYmIHRoaXMucmVzb2x2ZXJzW3Jlc29sdmVyVHlwZV07XG4gICAgICBpZiAocmVzb2x2ZXJNYXApIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZSA9IHJlc29sdmVyTWFwW2FsaWFzVXNlZCA/IGZpZWxkTmFtZSA6IGFsaWFzZWRGaWVsZE5hbWVdO1xuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgIHJlc3VsdFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgICAgICAvLyBJbiBjYXNlIHRoZSByZXNvbHZlIGZ1bmN0aW9uIGFjY2Vzc2VzIHJlYWN0aXZlIHZhcmlhYmxlcyxcbiAgICAgICAgICAgIC8vIHNldCBjYWNoZVNsb3QgdG8gdGhlIGN1cnJlbnQgY2FjaGUgaW5zdGFuY2UuXG4gICAgICAgICAgICBjYWNoZVNsb3Qud2l0aFZhbHVlKHRoaXMuY2FjaGUsIHJlc29sdmUsIFtcbiAgICAgICAgICAgICAgcm9vdFZhbHVlLFxuICAgICAgICAgICAgICBhcmd1bWVudHNPYmplY3RGcm9tRmllbGQoZmllbGQsIHZhcmlhYmxlcyksXG4gICAgICAgICAgICAgIGV4ZWNDb250ZXh0LmNvbnRleHQsXG4gICAgICAgICAgICAgIHsgZmllbGQsIGZyYWdtZW50TWFwOiBleGVjQ29udGV4dC5mcmFnbWVudE1hcCB9LFxuICAgICAgICAgICAgXSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdFByb21pc2UudGhlbigocmVzdWx0ID0gZGVmYXVsdFJlc3VsdCkgPT4ge1xuICAgICAgLy8gSWYgYW4gQGV4cG9ydCBkaXJlY3RpdmUgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IGZpZWxkLCBzdG9yZVxuICAgICAgLy8gdGhlIGBhc2AgZXhwb3J0IHZhcmlhYmxlIG5hbWUgYW5kIGN1cnJlbnQgcmVzdWx0IGZvciBsYXRlciB1c2UuXG4gICAgICBpZiAoZmllbGQuZGlyZWN0aXZlcykge1xuICAgICAgICBmaWVsZC5kaXJlY3RpdmVzLmZvckVhY2goKGRpcmVjdGl2ZSkgPT4ge1xuICAgICAgICAgIGlmIChkaXJlY3RpdmUubmFtZS52YWx1ZSA9PT0gXCJleHBvcnRcIiAmJiBkaXJlY3RpdmUuYXJndW1lbnRzKSB7XG4gICAgICAgICAgICBkaXJlY3RpdmUuYXJndW1lbnRzLmZvckVhY2goKGFyZykgPT4ge1xuICAgICAgICAgICAgICBpZiAoYXJnLm5hbWUudmFsdWUgPT09IFwiYXNcIiAmJiBhcmcudmFsdWUua2luZCA9PT0gXCJTdHJpbmdWYWx1ZVwiKSB7XG4gICAgICAgICAgICAgICAgZXhlY0NvbnRleHQuZXhwb3J0ZWRWYXJpYWJsZXNbYXJnLnZhbHVlLnZhbHVlXSA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gSGFuZGxlIGFsbCBzY2FsYXIgdHlwZXMgaGVyZS5cbiAgICAgIGlmICghZmllbGQuc2VsZWN0aW9uU2V0KSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIC8vIEZyb20gaGVyZSBkb3duLCB0aGUgZmllbGQgaGFzIGEgc2VsZWN0aW9uIHNldCwgd2hpY2ggbWVhbnMgaXQncyB0cnlpbmdcbiAgICAgIC8vIHRvIHF1ZXJ5IGEgR3JhcGhRTE9iamVjdFR5cGUuXG4gICAgICBpZiAocmVzdWx0ID09IG51bGwpIHtcbiAgICAgICAgLy8gQmFzaWNhbGx5IGFueSBmaWVsZCBpbiBhIEdyYXBoUUwgcmVzcG9uc2UgY2FuIGJlIG51bGwsIG9yIG1pc3NpbmdcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNDbGllbnRGaWVsZCA9XG4gICAgICAgIGZpZWxkLmRpcmVjdGl2ZXM/LnNvbWUoKGQpID0+IGQubmFtZS52YWx1ZSA9PT0gXCJjbGllbnRcIikgPz8gZmFsc2U7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZVN1YlNlbGVjdGVkQXJyYXkoXG4gICAgICAgICAgZmllbGQsXG4gICAgICAgICAgaXNDbGllbnRGaWVsZERlc2NlbmRhbnQgfHwgaXNDbGllbnRGaWVsZCxcbiAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgZXhlY0NvbnRleHRcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmV0dXJuZWQgdmFsdWUgaXMgYW4gb2JqZWN0LCBhbmQgdGhlIHF1ZXJ5IGhhcyBhIHN1Yi1zZWxlY3Rpb24uIFJlY3Vyc2UuXG4gICAgICBpZiAoZmllbGQuc2VsZWN0aW9uU2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVTZWxlY3Rpb25TZXQoXG4gICAgICAgICAgZmllbGQuc2VsZWN0aW9uU2V0LFxuICAgICAgICAgIGlzQ2xpZW50RmllbGREZXNjZW5kYW50IHx8IGlzQ2xpZW50RmllbGQsXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgIGV4ZWNDb250ZXh0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc29sdmVTdWJTZWxlY3RlZEFycmF5KFxuICAgIGZpZWxkOiBGaWVsZE5vZGUsXG4gICAgaXNDbGllbnRGaWVsZERlc2NlbmRhbnQ6IGJvb2xlYW4sXG4gICAgcmVzdWx0OiBhbnlbXSxcbiAgICBleGVjQ29udGV4dDogRXhlY0NvbnRleHRcbiAgKTogYW55IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICByZXN1bHQubWFwKChpdGVtKSA9PiB7XG4gICAgICAgIGlmIChpdGVtID09PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGlzIGlzIGEgbmVzdGVkIGFycmF5LCByZWN1cnNlLlxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShpdGVtKSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVTdWJTZWxlY3RlZEFycmF5KFxuICAgICAgICAgICAgZmllbGQsXG4gICAgICAgICAgICBpc0NsaWVudEZpZWxkRGVzY2VuZGFudCxcbiAgICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgICBleGVjQ29udGV4dFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGlzIGlzIGFuIG9iamVjdCwgcnVuIHRoZSBzZWxlY3Rpb24gc2V0IG9uIGl0LlxuICAgICAgICBpZiAoZmllbGQuc2VsZWN0aW9uU2V0KSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVzb2x2ZVNlbGVjdGlvblNldChcbiAgICAgICAgICAgIGZpZWxkLnNlbGVjdGlvblNldCxcbiAgICAgICAgICAgIGlzQ2xpZW50RmllbGREZXNjZW5kYW50LFxuICAgICAgICAgICAgaXRlbSxcbiAgICAgICAgICAgIGV4ZWNDb250ZXh0XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gQ29sbGVjdCBzZWxlY3Rpb24gbm9kZXMgb24gcGF0aHMgZnJvbSBkb2N1bWVudCByb290IGRvd24gdG8gYWxsIEBjbGllbnQgZGlyZWN0aXZlcy5cbiAgLy8gVGhpcyBmdW5jdGlvbiB0YWtlcyBpbnRvIGFjY291bnQgdHJhbnNpdGl2ZSBmcmFnbWVudCBzcHJlYWRzLlxuICAvLyBDb21wbGV4aXR5IGVxdWFscyB0byBhIHNpbmdsZSBgdmlzaXRgIG92ZXIgdGhlIGZ1bGwgZG9jdW1lbnQuXG4gIHByaXZhdGUgY29sbGVjdFNlbGVjdGlvbnNUb1Jlc29sdmUoXG4gICAgbWFpbkRlZmluaXRpb246IE9wZXJhdGlvbkRlZmluaXRpb25Ob2RlLFxuICAgIGZyYWdtZW50TWFwOiBGcmFnbWVudE1hcFxuICApOiBTZXQ8U2VsZWN0aW9uTm9kZT4ge1xuICAgIGNvbnN0IGlzU2luZ2xlQVNUTm9kZSA9IChcbiAgICAgIG5vZGU6IEFTVE5vZGUgfCByZWFkb25seSBBU1ROb2RlW11cbiAgICApOiBub2RlIGlzIEFTVE5vZGUgPT4gIUFycmF5LmlzQXJyYXkobm9kZSk7XG4gICAgY29uc3Qgc2VsZWN0aW9uc1RvUmVzb2x2ZUNhY2hlID0gdGhpcy5zZWxlY3Rpb25zVG9SZXNvbHZlQ2FjaGU7XG5cbiAgICBmdW5jdGlvbiBjb2xsZWN0QnlEZWZpbml0aW9uKFxuICAgICAgZGVmaW5pdGlvbk5vZGU6IEV4ZWN1dGFibGVEZWZpbml0aW9uTm9kZVxuICAgICk6IFNldDxTZWxlY3Rpb25Ob2RlPiB7XG4gICAgICBpZiAoIXNlbGVjdGlvbnNUb1Jlc29sdmVDYWNoZS5oYXMoZGVmaW5pdGlvbk5vZGUpKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoZXMgPSBuZXcgU2V0PFNlbGVjdGlvbk5vZGU+KCk7XG4gICAgICAgIHNlbGVjdGlvbnNUb1Jlc29sdmVDYWNoZS5zZXQoZGVmaW5pdGlvbk5vZGUsIG1hdGNoZXMpO1xuXG4gICAgICAgIHZpc2l0KGRlZmluaXRpb25Ob2RlLCB7XG4gICAgICAgICAgRGlyZWN0aXZlKG5vZGU6IERpcmVjdGl2ZU5vZGUsIF8sIF9fLCBfX18sIGFuY2VzdG9ycykge1xuICAgICAgICAgICAgaWYgKG5vZGUubmFtZS52YWx1ZSA9PT0gXCJjbGllbnRcIikge1xuICAgICAgICAgICAgICBhbmNlc3RvcnMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1NpbmdsZUFTVE5vZGUobm9kZSkgJiYgaXNTZWxlY3Rpb25Ob2RlKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICBtYXRjaGVzLmFkZChub2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgRnJhZ21lbnRTcHJlYWQoc3ByZWFkOiBGcmFnbWVudFNwcmVhZE5vZGUsIF8sIF9fLCBfX18sIGFuY2VzdG9ycykge1xuICAgICAgICAgICAgY29uc3QgZnJhZ21lbnQgPSBmcmFnbWVudE1hcFtzcHJlYWQubmFtZS52YWx1ZV07XG4gICAgICAgICAgICBpbnZhcmlhbnQoZnJhZ21lbnQsIGBObyBmcmFnbWVudCBuYW1lZCAlc2AsIHNwcmVhZC5uYW1lLnZhbHVlKTtcblxuICAgICAgICAgICAgY29uc3QgZnJhZ21lbnRTZWxlY3Rpb25zID0gY29sbGVjdEJ5RGVmaW5pdGlvbihmcmFnbWVudCk7XG4gICAgICAgICAgICBpZiAoZnJhZ21lbnRTZWxlY3Rpb25zLnNpemUgPiAwKSB7XG4gICAgICAgICAgICAgIC8vIEZyYWdtZW50IGZvciB0aGlzIHNwcmVhZCBjb250YWlucyBAY2xpZW50IGRpcmVjdGl2ZSAoZWl0aGVyIGRpcmVjdGx5IG9yIHRyYW5zaXRpdmVseSlcbiAgICAgICAgICAgICAgLy8gQ29sbGVjdCBzZWxlY3Rpb24gbm9kZXMgb24gcGF0aHMgZnJvbSB0aGUgcm9vdCBkb3duIHRvIGZpZWxkcyB3aXRoIHRoZSBAY2xpZW50IGRpcmVjdGl2ZVxuICAgICAgICAgICAgICBhbmNlc3RvcnMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1NpbmdsZUFTVE5vZGUobm9kZSkgJiYgaXNTZWxlY3Rpb25Ob2RlKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICBtYXRjaGVzLmFkZChub2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBtYXRjaGVzLmFkZChzcHJlYWQpO1xuICAgICAgICAgICAgICBmcmFnbWVudFNlbGVjdGlvbnMuZm9yRWFjaCgoc2VsZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgbWF0Y2hlcy5hZGQoc2VsZWN0aW9uKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2VsZWN0aW9uc1RvUmVzb2x2ZUNhY2hlLmdldChkZWZpbml0aW9uTm9kZSkhO1xuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdEJ5RGVmaW5pdGlvbihtYWluRGVmaW5pdGlvbik7XG4gIH1cbn1cbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF19 |