import { __assign } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29"; import { invariant, newInvariantError } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29"; import { equal } from "/_nuxt/node_modules/@wry/equality/lib/index.js?v=e4f18c29"; import { Trie } from "/_nuxt/node_modules/@wry/trie/lib/index.js?v=e4f18c29"; import { Kind } from "/_nuxt/node_modules/graphql/index.mjs?v=e4f18c29"; import { getFragmentFromSelection, getDefaultValues, getOperationDefinition, getTypenameFromResult, makeReference, isField, resultKeyNameFromField, isReference, shouldInclude, cloneDeep, addTypenameToDocument, isNonEmptyArray, argumentsObjectFromField, canonicalStringify, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { isArray, makeProcessedFieldsMerger, fieldNameFromStoreName, storeValueIsStoreObject, extractFragmentContext, } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/helpers.js?v=e4f18c29"; import { normalizeReadFieldOptions } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/policies.js?v=e4f18c29"; // Since there are only four possible combinations of context.clientOnly and // context.deferred values, we should need at most four "flavors" of any given // WriteContext. To avoid creating multiple copies of the same context, we cache // the contexts in the context.flavors Map (shared by all flavors) according to // their clientOnly and deferred values (always in that order). function getContextFlavor(context, clientOnly, deferred) { var key = "".concat(clientOnly).concat(deferred); var flavored = context.flavors.get(key); if (!flavored) { context.flavors.set(key, (flavored = context.clientOnly === clientOnly && context.deferred === deferred ? context : __assign(__assign({}, context), { clientOnly: clientOnly, deferred: deferred }))); } return flavored; } var StoreWriter = /** @class */ (function () { function StoreWriter(cache, reader, fragments) { this.cache = cache; this.reader = reader; this.fragments = fragments; } StoreWriter.prototype.writeToStore = function (store, _a) { var _this = this; var query = _a.query, result = _a.result, dataId = _a.dataId, variables = _a.variables, overwrite = _a.overwrite; var operationDefinition = getOperationDefinition(query); var merger = makeProcessedFieldsMerger(); variables = __assign(__assign({}, getDefaultValues(operationDefinition)), variables); var context = __assign(__assign({ store: store, written: Object.create(null), merge: function (existing, incoming) { return merger.merge(existing, incoming); }, variables: variables, varString: canonicalStringify(variables) }, extractFragmentContext(query, this.fragments)), { overwrite: !!overwrite, incomingById: new Map(), clientOnly: false, deferred: false, flavors: new Map() }); var ref = this.processSelectionSet({ result: result || Object.create(null), dataId: dataId, selectionSet: operationDefinition.selectionSet, mergeTree: { map: new Map() }, context: context, }); if (!isReference(ref)) { throw newInvariantError(12, result); } // So far, the store has not been modified, so now it's time to process // context.incomingById and merge those incoming fields into context.store. context.incomingById.forEach(function (_a, dataId) { var storeObject = _a.storeObject, mergeTree = _a.mergeTree, fieldNodeSet = _a.fieldNodeSet; var entityRef = makeReference(dataId); if (mergeTree && mergeTree.map.size) { var applied = _this.applyMerges(mergeTree, entityRef, storeObject, context); if (isReference(applied)) { // Assume References returned by applyMerges have already been merged // into the store. See makeMergeObjectsFunction in policies.ts for an // example of how this can happen. return; } // Otherwise, applyMerges returned a StoreObject, whose fields we should // merge into the store (see store.merge statement below). storeObject = applied; } if (globalThis.__DEV__ !== false && !context.overwrite) { var fieldsWithSelectionSets_1 = Object.create(null); fieldNodeSet.forEach(function (field) { if (field.selectionSet) { fieldsWithSelectionSets_1[field.name.value] = true; } }); var hasSelectionSet_1 = function (storeFieldName) { return fieldsWithSelectionSets_1[fieldNameFromStoreName(storeFieldName)] === true; }; var hasMergeFunction_1 = function (storeFieldName) { var childTree = mergeTree && mergeTree.map.get(storeFieldName); return Boolean(childTree && childTree.info && childTree.info.merge); }; Object.keys(storeObject).forEach(function (storeFieldName) { // If a merge function was defined for this field, trust that it // did the right thing about (not) clobbering data. If the field // has no selection set, it's a scalar field, so it doesn't need // a merge function (even if it's an object, like JSON data). if (hasSelectionSet_1(storeFieldName) && !hasMergeFunction_1(storeFieldName)) { warnAboutDataLoss(entityRef, storeObject, storeFieldName, context.store); } }); } store.merge(dataId, storeObject); }); // Any IDs written explicitly to the cache will be retained as // reachable root IDs for garbage collection purposes. Although this // logic includes root IDs like ROOT_QUERY and ROOT_MUTATION, their // retainment counts are effectively ignored because cache.gc() always // includes them in its root ID set. store.retain(ref.__ref); return ref; }; StoreWriter.prototype.processSelectionSet = function (_a) { var _this = this; var dataId = _a.dataId, result = _a.result, selectionSet = _a.selectionSet, context = _a.context, // This object allows processSelectionSet to report useful information // to its callers without explicitly returning that information. mergeTree = _a.mergeTree; var policies = this.cache.policies; // This variable will be repeatedly updated using context.merge to // accumulate all fields that need to be written into the store. var incoming = Object.create(null); // If typename was not passed in, infer it. Note that typename is // always passed in for tricky-to-infer cases such as "Query" for // ROOT_QUERY. var typename = (dataId && policies.rootTypenamesById[dataId]) || getTypenameFromResult(result, selectionSet, context.fragmentMap) || (dataId && context.store.get(dataId, "__typename")); if ("string" === typeof typename) { incoming.__typename = typename; } // This readField function will be passed as context.readField in the // KeyFieldsContext object created within policies.identify (called below). // In addition to reading from the existing context.store (thanks to the // policies.readField(options, context) line at the very bottom), this // version of readField can read from Reference objects that are currently // pending in context.incomingById, which is important whenever keyFields // need to be extracted from a child object that processSelectionSet has // turned into a Reference. var readField = function () { var options = normalizeReadFieldOptions(arguments, incoming, context.variables); if (isReference(options.from)) { var info = context.incomingById.get(options.from.__ref); if (info) { var result_1 = policies.readField(__assign(__assign({}, options), { from: info.storeObject }), context); if (result_1 !== void 0) { return result_1; } } } return policies.readField(options, context); }; var fieldNodeSet = new Set(); this.flattenFields(selectionSet, result, // This WriteContext will be the default context value for fields returned // by the flattenFields method, but some fields may be assigned a modified // context, depending on the presence of @client and other directives. context, typename).forEach(function (context, field) { var _a; var resultFieldKey = resultKeyNameFromField(field); var value = result[resultFieldKey]; fieldNodeSet.add(field); if (value !== void 0) { var storeFieldName = policies.getStoreFieldName({ typename: typename, fieldName: field.name.value, field: field, variables: context.variables, }); var childTree = getChildMergeTree(mergeTree, storeFieldName); var incomingValue = _this.processFieldValue(value, field, // Reset context.clientOnly and context.deferred to their default // values before processing nested selection sets. field.selectionSet ? getContextFlavor(context, false, false) : context, childTree); // To determine if this field holds a child object with a merge function // defined in its type policy (see PR #7070), we need to figure out the // child object's __typename. var childTypename = void 0; // The field's value can be an object that has a __typename only if the // field has a selection set. Otherwise incomingValue is scalar. if (field.selectionSet && (isReference(incomingValue) || storeValueIsStoreObject(incomingValue))) { childTypename = readField("__typename", incomingValue); } var merge = policies.getMergeFunction(typename, field.name.value, childTypename); if (merge) { childTree.info = { // TODO Check compatibility against any existing childTree.field? field: field, typename: typename, merge: merge, }; } else { maybeRecycleChildMergeTree(mergeTree, storeFieldName); } incoming = context.merge(incoming, (_a = {}, _a[storeFieldName] = incomingValue, _a)); } else if (globalThis.__DEV__ !== false && !context.clientOnly && !context.deferred && !addTypenameToDocument.added(field) && // If the field has a read function, it may be a synthetic field or // provide a default value, so its absence from the written data should // not be cause for alarm. !policies.getReadFunction(typename, field.name.value)) { globalThis.__DEV__ !== false && invariant.error(13, resultKeyNameFromField(field), result); } }); // Identify the result object, even if dataId was already provided, // since we always need keyObject below. try { var _b = policies.identify(result, { typename: typename, selectionSet: selectionSet, fragmentMap: context.fragmentMap, storeObject: incoming, readField: readField, }), id = _b[0], keyObject = _b[1]; // If dataId was not provided, fall back to the id just generated by // policies.identify. dataId = dataId || id; // Write any key fields that were used during identification, even if // they were not mentioned in the original query. if (keyObject) { // TODO Reverse the order of the arguments? incoming = context.merge(incoming, keyObject); } } catch (e) { // If dataId was provided, tolerate failure of policies.identify. if (!dataId) throw e; } if ("string" === typeof dataId) { var dataRef = makeReference(dataId); // Avoid processing the same entity object using the same selection // set more than once. We use an array instead of a Set since most // entity IDs will be written using only one selection set, so the // size of this array is likely to be very small, meaning indexOf is // likely to be faster than Set.prototype.has. var sets = context.written[dataId] || (context.written[dataId] = []); if (sets.indexOf(selectionSet) >= 0) return dataRef; sets.push(selectionSet); // If we're about to write a result object into the store, but we // happen to know that the exact same (===) result object would be // returned if we were to reread the result with the same inputs, // then we can skip the rest of the processSelectionSet work for // this object, and immediately return a Reference to it. if (this.reader && this.reader.isFresh(result, dataRef, selectionSet, context)) { return dataRef; } var previous_1 = context.incomingById.get(dataId); if (previous_1) { previous_1.storeObject = context.merge(previous_1.storeObject, incoming); previous_1.mergeTree = mergeMergeTrees(previous_1.mergeTree, mergeTree); fieldNodeSet.forEach(function (field) { return previous_1.fieldNodeSet.add(field); }); } else { context.incomingById.set(dataId, { storeObject: incoming, // Save a reference to mergeTree only if it is not empty, because // empty MergeTrees may be recycled by maybeRecycleChildMergeTree and // reused for entirely different parts of the result tree. mergeTree: mergeTreeIsEmpty(mergeTree) ? void 0 : mergeTree, fieldNodeSet: fieldNodeSet, }); } return dataRef; } return incoming; }; StoreWriter.prototype.processFieldValue = function (value, field, context, mergeTree) { var _this = this; if (!field.selectionSet || value === null) { // In development, we need to clone scalar values so that they can be // safely frozen with maybeDeepFreeze in readFromStore.ts. In production, // it's cheaper to store the scalar values directly in the cache. return globalThis.__DEV__ !== false ? cloneDeep(value) : value; } if (isArray(value)) { return value.map(function (item, i) { var value = _this.processFieldValue(item, field, context, getChildMergeTree(mergeTree, i)); maybeRecycleChildMergeTree(mergeTree, i); return value; }); } return this.processSelectionSet({ result: value, selectionSet: field.selectionSet, context: context, mergeTree: mergeTree, }); }; // Implements https://spec.graphql.org/draft/#sec-Field-Collection, but with // some additions for tracking @client and @defer directives. StoreWriter.prototype.flattenFields = function (selectionSet, result, context, typename) { if (typename === void 0) { typename = getTypenameFromResult(result, selectionSet, context.fragmentMap); } var fieldMap = new Map(); var policies = this.cache.policies; var limitingTrie = new Trie(false); // No need for WeakMap, since limitingTrie does not escape. (function flatten(selectionSet, inheritedContext) { var visitedNode = limitingTrie.lookup(selectionSet, // Because we take inheritedClientOnly and inheritedDeferred into // consideration here (in addition to selectionSet), it's possible for // the same selection set to be flattened more than once, if it appears // in the query with different @client and/or @directive configurations. inheritedContext.clientOnly, inheritedContext.deferred); if (visitedNode.visited) return; visitedNode.visited = true; selectionSet.selections.forEach(function (selection) { if (!shouldInclude(selection, context.variables)) return; var clientOnly = inheritedContext.clientOnly, deferred = inheritedContext.deferred; if ( // Since the presence of @client or @defer on this field can only // cause clientOnly or deferred to become true, we can skip the // forEach loop if both clientOnly and deferred are already true. !(clientOnly && deferred) && isNonEmptyArray(selection.directives)) { selection.directives.forEach(function (dir) { var name = dir.name.value; if (name === "client") clientOnly = true; if (name === "defer") { var args = argumentsObjectFromField(dir, context.variables); // The @defer directive takes an optional args.if boolean // argument, similar to @include(if: boolean). Note that // @defer(if: false) does not make context.deferred false, but // instead behaves as if there was no @defer directive. if (!args || args.if !== false) { deferred = true; } // TODO In the future, we may want to record args.label using // context.deferred, if a label is specified. } }); } if (isField(selection)) { var existing = fieldMap.get(selection); if (existing) { // If this field has been visited along another recursive path // before, the final context should have clientOnly or deferred set // to true only if *all* paths have the directive (hence the &&). clientOnly = clientOnly && existing.clientOnly; deferred = deferred && existing.deferred; } fieldMap.set(selection, getContextFlavor(context, clientOnly, deferred)); } else { var fragment = getFragmentFromSelection(selection, context.lookupFragment); if (!fragment && selection.kind === Kind.FRAGMENT_SPREAD) { throw newInvariantError(14, selection.name.value); } if (fragment && policies.fragmentMatches(fragment, typename, result, context.variables)) { flatten(fragment.selectionSet, getContextFlavor(context, clientOnly, deferred)); } } }); })(selectionSet, context); return fieldMap; }; StoreWriter.prototype.applyMerges = function (mergeTree, existing, incoming, context, getStorageArgs) { var _a; var _this = this; if (mergeTree.map.size && !isReference(incoming)) { var e_1 = // Items in the same position in different arrays are not // necessarily related to each other, so when incoming is an array // we process its elements as if there was no existing data. (!isArray(incoming) && // Likewise, existing must be either a Reference or a StoreObject // in order for its fields to be safe to merge with the fields of // the incoming object. (isReference(existing) || storeValueIsStoreObject(existing))) ? existing : void 0; // This narrowing is implied by mergeTree.map.size > 0 and // !isReference(incoming), though TypeScript understandably cannot // hope to infer this type. var i_1 = incoming; // The options.storage objects provided to read and merge functions // are derived from the identity of the parent object plus a // sequence of storeFieldName strings/numbers identifying the nested // field name path of each field value to be merged. if (e_1 && !getStorageArgs) { getStorageArgs = [isReference(e_1) ? e_1.__ref : e_1]; } // It's possible that applying merge functions to this subtree will // not change the incoming data, so this variable tracks the fields // that did change, so we can create a new incoming object when (and // only when) at least one incoming field has changed. We use a Map // to preserve the type of numeric keys. var changedFields_1; var getValue_1 = function (from, name) { return (isArray(from) ? typeof name === "number" ? from[name] : void 0 : context.store.getFieldValue(from, String(name))); }; mergeTree.map.forEach(function (childTree, storeFieldName) { var eVal = getValue_1(e_1, storeFieldName); var iVal = getValue_1(i_1, storeFieldName); // If we have no incoming data, leave any existing data untouched. if (void 0 === iVal) return; if (getStorageArgs) { getStorageArgs.push(storeFieldName); } var aVal = _this.applyMerges(childTree, eVal, iVal, context, getStorageArgs); if (aVal !== iVal) { changedFields_1 = changedFields_1 || new Map(); changedFields_1.set(storeFieldName, aVal); } if (getStorageArgs) { invariant(getStorageArgs.pop() === storeFieldName); } }); if (changedFields_1) { // Shallow clone i so we can add changed fields to it. incoming = (isArray(i_1) ? i_1.slice(0) : __assign({}, i_1)); changedFields_1.forEach(function (value, name) { incoming[name] = value; }); } } if (mergeTree.info) { return this.cache.policies.runMergeFunction(existing, incoming, mergeTree.info, context, getStorageArgs && (_a = context.store).getStorage.apply(_a, getStorageArgs)); } return incoming; }; return StoreWriter; }()); export { StoreWriter }; var emptyMergeTreePool = []; function getChildMergeTree(_a, name) { var map = _a.map; if (!map.has(name)) { map.set(name, emptyMergeTreePool.pop() || { map: new Map() }); } return map.get(name); } function mergeMergeTrees(left, right) { if (left === right || !right || mergeTreeIsEmpty(right)) return left; if (!left || mergeTreeIsEmpty(left)) return right; var info = left.info && right.info ? __assign(__assign({}, left.info), right.info) : left.info || right.info; var needToMergeMaps = left.map.size && right.map.size; var map = needToMergeMaps ? new Map() : left.map.size ? left.map : right.map; var merged = { info: info, map: map }; if (needToMergeMaps) { var remainingRightKeys_1 = new Set(right.map.keys()); left.map.forEach(function (leftTree, key) { merged.map.set(key, mergeMergeTrees(leftTree, right.map.get(key))); remainingRightKeys_1.delete(key); }); remainingRightKeys_1.forEach(function (key) { merged.map.set(key, mergeMergeTrees(right.map.get(key), left.map.get(key))); }); } return merged; } function mergeTreeIsEmpty(tree) { return !tree || !(tree.info || tree.map.size); } function maybeRecycleChildMergeTree(_a, name) { var map = _a.map; var childTree = map.get(name); if (childTree && mergeTreeIsEmpty(childTree)) { emptyMergeTreePool.push(childTree); map.delete(name); } } var warnings = new Set(); // Note that this function is unused in production, and thus should be // pruned by any well-configured minifier. function warnAboutDataLoss(existingRef, incomingObj, storeFieldName, store) { var getChild = function (objOrRef) { var child = store.getFieldValue(objOrRef, storeFieldName); return typeof child === "object" && child; }; var existing = getChild(existingRef); if (!existing) return; var incoming = getChild(incomingObj); if (!incoming) return; // It's always safe to replace a reference, since it refers to data // safely stored elsewhere. if (isReference(existing)) return; // If the values are structurally equivalent, we do not need to worry // about incoming replacing existing. if (equal(existing, incoming)) return; // If we're replacing every key of the existing object, then the // existing data would be overwritten even if the objects were // normalized, so warning would not be helpful here. if (Object.keys(existing).every(function (key) { return store.getFieldValue(incoming, key) !== void 0; })) { return; } var parentType = store.getFieldValue(existingRef, "__typename") || store.getFieldValue(incomingObj, "__typename"); var fieldName = fieldNameFromStoreName(storeFieldName); var typeDotName = "".concat(parentType, ".").concat(fieldName); // Avoid warning more than once for the same type and field name. if (warnings.has(typeDotName)) return; warnings.add(typeDotName); var childTypenames = []; // Arrays do not have __typename fields, and always need a custom merge // function, even if their elements are normalized entities. if (!isArray(existing) && !isArray(incoming)) { [existing, incoming].forEach(function (child) { var typename = store.getFieldValue(child, "__typename"); if (typeof typename === "string" && !childTypenames.includes(typename)) { childTypenames.push(typename); } }); } globalThis.__DEV__ !== false && invariant.warn(15, fieldName, parentType, childTypenames.length ? "either ensure all objects of type " + childTypenames.join(" and ") + " have an ID or a custom merge function, or " : "", typeDotName, __assign({}, existing), __assign({}, incoming)); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGVUb1N0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NhY2hlL2lubWVtb3J5L3dyaXRlVG9TdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVqQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBUy9CLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsZ0JBQWdCLEVBQ2hCLHNCQUFzQixFQUN0QixxQkFBcUIsRUFDckIsYUFBYSxFQUNiLE9BQU8sRUFDUCxzQkFBc0IsRUFDdEIsV0FBVyxFQUNYLGFBQWEsRUFDYixTQUFTLEVBQ1QscUJBQXFCLEVBQ3JCLGVBQWUsRUFDZix3QkFBd0IsRUFDeEIsa0JBQWtCLEdBQ25CLE1BQU0sMEJBQTBCLENBQUM7QUFRbEMsT0FBTyxFQUNMLE9BQU8sRUFDUCx5QkFBeUIsRUFDekIsc0JBQXNCLEVBQ3RCLHVCQUF1QixFQUN2QixzQkFBc0IsR0FDdkIsTUFBTSxjQUFjLENBQUM7QUFLdEIsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBa0MxRCw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLGdGQUFnRjtBQUNoRiwrRUFBK0U7QUFDL0UsK0RBQStEO0FBQy9ELFNBQVMsZ0JBQWdCLENBQ3ZCLE9BQWlCLEVBQ2pCLFVBQWtDLEVBQ2xDLFFBQThCO0lBRTlCLElBQU0sR0FBRyxHQUFHLFVBQUcsVUFBVSxTQUFHLFFBQVEsQ0FBRSxDQUFDO0lBQ3ZDLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLElBQUksQ0FBQyxR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QVcsR0FBRyxVQUFHLFVBQVUsY0FBSSxTQUFTLENBQUUsQ0FBQztJQUNqRCxpRUFBaUU7SUFDakUsSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQztRQUFFLE9BQU87SUFDdEMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUUxQixJQUFNLGNBQWMsR0FBYSxFQUFFLENBQUM7SUFDcEMsdUVBQXVFO0lBQ3ZFLDREQUE0RDtJQUM1RCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDN0MsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUNqQyxJQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztZQUMxRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDdkUsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsU0FBUyxDQUFDLElBQUksQ0FDWix3b0JBYUgsRUFDRyxTQUFTLEVBQ1QsVUFBVSxFQUNWLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNyQixvQ0FBb0M7WUFDbEMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDNUIsNkNBQTZDO1FBQ2pELENBQUMsQ0FBQyxFQUFFLEVBQ0osV0FBVyxlQUNOLFFBQVEsZ0JBQ1IsUUFBUSxFQUNkLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW52YXJpYW50LCBuZXdJbnZhcmlhbnRFcnJvciB9IGZyb20gXCIuLi8uLi91dGlsaXRpZXMvZ2xvYmFscy9pbmRleC5qc1wiO1xuaW1wb3J0IHsgZXF1YWwgfSBmcm9tIFwiQHdyeS9lcXVhbGl0eVwiO1xuaW1wb3J0IHsgVHJpZSB9IGZyb20gXCJAd3J5L3RyaWVcIjtcbmltcG9ydCB0eXBlIHsgU2VsZWN0aW9uU2V0Tm9kZSwgRmllbGROb2RlIH0gZnJvbSBcImdyYXBocWxcIjtcbmltcG9ydCB7IEtpbmQgfSBmcm9tIFwiZ3JhcGhxbFwiO1xuXG5pbXBvcnQgdHlwZSB7XG4gIEZyYWdtZW50TWFwLFxuICBGcmFnbWVudE1hcEZ1bmN0aW9uLFxuICBTdG9yZVZhbHVlLFxuICBTdG9yZU9iamVjdCxcbiAgUmVmZXJlbmNlLFxufSBmcm9tIFwiLi4vLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQge1xuICBnZXRGcmFnbWVudEZyb21TZWxlY3Rpb24sXG4gIGdldERlZmF1bHRWYWx1ZXMsXG4gIGdldE9wZXJhdGlvbkRlZmluaXRpb24sXG4gIGdldFR5cGVuYW1lRnJvbVJlc3VsdCxcbiAgbWFrZVJlZmVyZW5jZSxcbiAgaXNGaWVsZCxcbiAgcmVzdWx0S2V5TmFtZUZyb21GaWVsZCxcbiAgaXNSZWZlcmVuY2UsXG4gIHNob3VsZEluY2x1ZGUsXG4gIGNsb25lRGVlcCxcbiAgYWRkVHlwZW5hbWVUb0RvY3VtZW50LFxuICBpc05vbkVtcHR5QXJyYXksXG4gIGFyZ3VtZW50c09iamVjdEZyb21GaWVsZCxcbiAgY2Fub25pY2FsU3RyaW5naWZ5LFxufSBmcm9tIFwiLi4vLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5cbmltcG9ydCB0eXBlIHtcbiAgTm9ybWFsaXplZENhY2hlLFxuICBSZWFkTWVyZ2VNb2RpZnlDb250ZXh0LFxuICBNZXJnZVRyZWUsXG4gIEluTWVtb3J5Q2FjaGVDb25maWcsXG59IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5pbXBvcnQge1xuICBpc0FycmF5LFxuICBtYWtlUHJvY2Vzc2VkRmllbGRzTWVyZ2VyLFxuICBmaWVsZE5hbWVGcm9tU3RvcmVOYW1lLFxuICBzdG9yZVZhbHVlSXNTdG9yZU9iamVjdCxcbiAgZXh0cmFjdEZyYWdtZW50Q29udGV4dCxcbn0gZnJvbSBcIi4vaGVscGVycy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTdG9yZVJlYWRlciB9IGZyb20gXCIuL3JlYWRGcm9tU3RvcmUuanNcIjtcbmltcG9ydCB0eXBlIHsgSW5NZW1vcnlDYWNoZSB9IGZyb20gXCIuL2luTWVtb3J5Q2FjaGUuanNcIjtcbmltcG9ydCB0eXBlIHsgRW50aXR5U3RvcmUgfSBmcm9tIFwiLi9lbnRpdHlTdG9yZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBDYWNoZSB9IGZyb20gXCIuLi8uLi9jb3JlL2luZGV4LmpzXCI7XG5pbXBvcnQgeyBub3JtYWxpemVSZWFkRmllbGRPcHRpb25zIH0gZnJvbSBcIi4vcG9saWNpZXMuanNcIjtcbmltcG9ydCB0eXBlIHsgUmVhZEZpZWxkRnVuY3Rpb24gfSBmcm9tIFwiLi4vY29yZS90eXBlcy9jb21tb24uanNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBXcml0ZUNvbnRleHQgZXh0ZW5kcyBSZWFkTWVyZ2VNb2RpZnlDb250ZXh0IHtcbiAgcmVhZG9ubHkgd3JpdHRlbjoge1xuICAgIFtkYXRhSWQ6IHN0cmluZ106IFNlbGVjdGlvblNldE5vZGVbXTtcbiAgfTtcbiAgcmVhZG9ubHkgZnJhZ21lbnRNYXA6IEZyYWdtZW50TWFwO1xuICBsb29rdXBGcmFnbWVudDogRnJhZ21lbnRNYXBGdW5jdGlvbjtcbiAgLy8gR2VuZXJhbC1wdXJwb3NlIGRlZXAtbWVyZ2UgZnVuY3Rpb24gZm9yIHVzZSBkdXJpbmcgd3JpdGVzLlxuICBtZXJnZTxUPihleGlzdGluZzogVCwgaW5jb21pbmc6IFQpOiBUO1xuICAvLyBJZiB0cnVlLCBtZXJnZSBmdW5jdGlvbnMgd2lsbCBiZSBjYWxsZWQgd2l0aCB1bmRlZmluZWQgZXhpc3RpbmcgZGF0YS5cbiAgb3ZlcndyaXRlOiBib29sZWFuO1xuICBpbmNvbWluZ0J5SWQ6IE1hcDxcbiAgICBzdHJpbmcsXG4gICAge1xuICAgICAgc3RvcmVPYmplY3Q6IFN0b3JlT2JqZWN0O1xuICAgICAgbWVyZ2VUcmVlPzogTWVyZ2VUcmVlO1xuICAgICAgZmllbGROb2RlU2V0OiBTZXQ8RmllbGROb2RlPjtcbiAgICB9XG4gID47XG4gIC8vIERpcmVjdGl2ZSBtZXRhZGF0YSBmb3IgQGNsaWVudCBhbmQgQGRlZmVyLiBXZSBjb3VsZCB1c2UgYSBiaXRmaWVsZCBmb3IgdGhpc1xuICAvLyBpbmZvcm1hdGlvbiB0byBzYXZlIHNvbWUgc3BhY2UsIGFuZCB1c2UgdGhhdCBiaXRmaWVsZCBudW1iZXIgYXMgdGhlIGtleXMgaW5cbiAgLy8gdGhlIGNvbnRleHQuZmxhdm9ycyBNYXAuXG4gIGNsaWVudE9ubHk6IGJvb2xlYW47XG4gIGRlZmVycmVkOiBib29sZWFuO1xuICBmbGF2b3JzOiBNYXA8c3RyaW5nLCBGbGF2b3JhYmxlV3JpdGVDb250ZXh0Pjtcbn1cblxudHlwZSBGbGF2b3JhYmxlV3JpdGVDb250ZXh0ID0gUGljazxcbiAgV3JpdGVDb250ZXh0LFxuICBcImNsaWVudE9ubHlcIiB8IFwiZGVmZXJyZWRcIiB8IFwiZmxhdm9yc1wiXG4+O1xuXG4vLyBTaW5jZSB0aGVyZSBhcmUgb25seSBmb3VyIHBvc3NpYmxlIGNvbWJpbmF0aW9ucyBvZiBjb250ZXh0LmNsaWVudE9ubHkgYW5kXG4vLyBjb250ZXh0LmRlZmVycmVkIHZhbHVlcywgd2Ugc2hvdWxkIG5lZWQgYXQgbW9zdCBmb3VyIFwiZmxhdm9yc1wiIG9mIGFueSBnaXZlblxuLy8gV3JpdGVDb250ZXh0LiBUbyBhdm9pZCBjcmVhdGluZyBtdWx0aXBsZSBjb3BpZXMgb2YgdGhlIHNhbWUgY29udGV4dCwgd2UgY2FjaGVcbi8vIHRoZSBjb250ZXh0cyBpbiB0aGUgY29udGV4dC5mbGF2b3JzIE1hcCAoc2hhcmVkIGJ5IGFsbCBmbGF2b3JzKSBhY2NvcmRpbmcgdG9cbi8vIHRoZWlyIGNsaWVudE9ubHkgYW5kIGRlZmVycmVkIHZhbHVlcyAoYWx3YXlzIGluIHRoYXQgb3JkZXIpLlxuZnVuY3Rpb24gZ2V0Q29udGV4dEZsYXZvcjxUQ29udGV4dCBleHRlbmRzIEZsYXZvcmFibGVXcml0ZUNvbnRleHQ+KFxuICBjb250ZXh0OiBUQ29udGV4dCxcbiAgY2xpZW50T25seTogVENvbnRleHRbXCJjbGllbnRPbmx5XCJdLFxuICBkZWZlcnJlZDogVENvbnRleHRbXCJkZWZlcnJlZFwiXVxuKTogVENvbnRleHQge1xuICBjb25zdCBrZXkgPSBgJHtjbGllbnRPbmx5fSR7ZGVmZXJyZWR9YDtcbiAgbGV0IGZsYXZvcmVkID0gY29udGV4dC5mbGF2b3JzLmdldChrZXkpO1xuICBpZiAoIWZsYXZvcmVkKSB7XG4gICAgY29udGV4dC5mbGF2b3JzLnNldChcbiAgICAgIGtleSxcbiAgICAgIChmbGF2b3JlZCA9XG4gICAgICAgIGNvbnRleHQuY2xpZW50T25seSA9PT0gY2xpZW50T25seSAmJiBjb250ZXh0LmRlZmVycmVkID09PSBkZWZlcnJlZCA/XG4gICAgICAgICAgY29udGV4dFxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC4uLmNvbnRleHQsXG4gICAgICAgICAgICBjbGllbnRPbmx5LFxuICAgICAgICAgICAgZGVmZXJyZWQsXG4gICAgICAgICAgfSlcbiAgICApO1xuICB9XG4gIHJldHVybiBmbGF2b3JlZCBhcyBUQ29udGV4dDtcbn1cblxuaW50ZXJmYWNlIFByb2Nlc3NTZWxlY3Rpb25TZXRPcHRpb25zIHtcbiAgZGF0YUlkPzogc3RyaW5nO1xuICByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIHNlbGVjdGlvblNldDogU2VsZWN0aW9uU2V0Tm9kZTtcbiAgY29udGV4dDogV3JpdGVDb250ZXh0O1xuICBtZXJnZVRyZWU6IE1lcmdlVHJlZTtcbn1cblxuZXhwb3J0IGNsYXNzIFN0b3JlV3JpdGVyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGNhY2hlOiBJbk1lbW9yeUNhY2hlLFxuICAgIHByaXZhdGUgcmVhZGVyPzogU3RvcmVSZWFkZXIsXG4gICAgcHJpdmF0ZSBmcmFnbWVudHM/OiBJbk1lbW9yeUNhY2hlQ29uZmlnW1wiZnJhZ21lbnRzXCJdXG4gICkge31cblxuICBwdWJsaWMgd3JpdGVUb1N0b3JlKFxuICAgIHN0b3JlOiBOb3JtYWxpemVkQ2FjaGUsXG4gICAgeyBxdWVyeSwgcmVzdWx0LCBkYXRhSWQsIHZhcmlhYmxlcywgb3ZlcndyaXRlIH06IENhY2hlLldyaXRlT3B0aW9uc1xuICApOiBSZWZlcmVuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG9wZXJhdGlvbkRlZmluaXRpb24gPSBnZXRPcGVyYXRpb25EZWZpbml0aW9uKHF1ZXJ5KSE7XG4gICAgY29uc3QgbWVyZ2VyID0gbWFrZVByb2Nlc3NlZEZpZWxkc01lcmdlcigpO1xuXG4gICAgdmFyaWFibGVzID0ge1xuICAgICAgLi4uZ2V0RGVmYXVsdFZhbHVlcyhvcGVyYXRpb25EZWZpbml0aW9uKSxcbiAgICAgIC4uLnZhcmlhYmxlcyEsXG4gICAgfTtcblxuICAgIGNvbnN0IGNvbnRleHQ6IFdyaXRlQ29udGV4dCA9IHtcbiAgICAgIHN0b3JlLFxuICAgICAgd3JpdHRlbjogT2JqZWN0LmNyZWF0ZShudWxsKSxcbiAgICAgIG1lcmdlPFQ+KGV4aXN0aW5nOiBULCBpbmNvbWluZzogVCkge1xuICAgICAgICByZXR1cm4gbWVyZ2VyLm1lcmdlKGV4aXN0aW5nLCBpbmNvbWluZykgYXMgVDtcbiAgICAgIH0sXG4gICAgICB2YXJpYWJsZXMsXG4gICAgICB2YXJTdHJpbmc6IGNhbm9uaWNhbFN0cmluZ2lmeSh2YXJpYWJsZXMpLFxuICAgICAgLi4uZXh0cmFjdEZyYWdtZW50Q29udGV4dChxdWVyeSwgdGhpcy5mcmFnbWVudHMpLFxuICAgICAgb3ZlcndyaXRlOiAhIW92ZXJ3cml0ZSxcbiAgICAgIGluY29taW5nQnlJZDogbmV3IE1hcCgpLFxuICAgICAgY2xpZW50T25seTogZmFsc2UsXG4gICAgICBkZWZlcnJlZDogZmFsc2UsXG4gICAgICBmbGF2b3JzOiBuZXcgTWFwKCksXG4gICAgfTtcblxuICAgIGNvbnN0IHJlZiA9IHRoaXMucHJvY2Vzc1NlbGVjdGlvblNldCh7XG4gICAgICByZXN1bHQ6IHJlc3VsdCB8fCBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgZGF0YUlkLFxuICAgICAgc2VsZWN0aW9uU2V0OiBvcGVyYXRpb25EZWZpbml0aW9uLnNlbGVjdGlvblNldCxcbiAgICAgIG1lcmdlVHJlZTogeyBtYXA6IG5ldyBNYXAoKSB9LFxuICAgICAgY29udGV4dCxcbiAgICB9KTtcblxuICAgIGlmICghaXNSZWZlcmVuY2UocmVmKSkge1xuICAgICAgdGhyb3cgbmV3SW52YXJpYW50RXJyb3IoYENvdWxkIG5vdCBpZGVudGlmeSBvYmplY3QgJXNgLCByZXN1bHQpO1xuICAgIH1cblxuICAgIC8vIFNvIGZhciwgdGhlIHN0b3JlIGhhcyBub3QgYmVlbiBtb2RpZmllZCwgc28gbm93IGl0J3MgdGltZSB0byBwcm9jZXNzXG4gICAgLy8gY29udGV4dC5pbmNvbWluZ0J5SWQgYW5kIG1lcmdlIHRob3NlIGluY29taW5nIGZpZWxkcyBpbnRvIGNvbnRleHQuc3RvcmUuXG4gICAgY29udGV4dC5pbmNvbWluZ0J5SWQuZm9yRWFjaChcbiAgICAgICh7IHN0b3JlT2JqZWN0LCBtZXJnZVRyZWUsIGZpZWxkTm9kZVNldCB9LCBkYXRhSWQpID0+IHtcbiAgICAgICAgY29uc3QgZW50aXR5UmVmID0gbWFrZVJlZmVyZW5jZShkYXRhSWQpO1xuXG4gICAgICAgIGlmIChtZXJnZVRyZWUgJiYgbWVyZ2VUcmVlLm1hcC5zaXplKSB7XG4gICAgICAgICAgY29uc3QgYXBwbGllZCA9IHRoaXMuYXBwbHlNZXJnZXMoXG4gICAgICAgICAgICBtZXJnZVRyZWUsXG4gICAgICAgICAgICBlbnRpdHlSZWYsXG4gICAgICAgICAgICBzdG9yZU9iamVjdCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChpc1JlZmVyZW5jZShhcHBsaWVkKSkge1xuICAgICAgICAgICAgLy8gQXNzdW1lIFJlZmVyZW5jZXMgcmV0dXJuZWQgYnkgYXBwbHlNZXJnZXMgaGF2ZSBhbHJlYWR5IGJlZW4gbWVyZ2VkXG4gICAgICAgICAgICAvLyBpbnRvIHRoZSBzdG9yZS4gU2VlIG1ha2VNZXJnZU9iamVjdHNGdW5jdGlvbiBpbiBwb2xpY2llcy50cyBmb3IgYW5cbiAgICAgICAgICAgIC8vIGV4YW1wbGUgb2YgaG93IHRoaXMgY2FuIGhhcHBlbi5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlLCBhcHBseU1lcmdlcyByZXR1cm5lZCBhIFN0b3JlT2JqZWN0LCB3aG9zZSBmaWVsZHMgd2Ugc2hvdWxkXG4gICAgICAgICAgLy8gbWVyZ2UgaW50byB0aGUgc3RvcmUgKHNlZSBzdG9yZS5tZXJnZSBzdGF0ZW1lbnQgYmVsb3cpLlxuICAgICAgICAgIHN0b3JlT2JqZWN0ID0gYXBwbGllZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfX0RFVl9fICYmICFjb250ZXh0Lm92ZXJ3cml0ZSkge1xuICAgICAgICAgIGNvbnN0IGZpZWxkc1dpdGhTZWxlY3Rpb25TZXRzOiBSZWNvcmQ8c3RyaW5nLCB0cnVlPiA9XG4gICAgICAgICAgICBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGZpZWxkTm9kZVNldC5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgICAgICAgICAgaWYgKGZpZWxkLnNlbGVjdGlvblNldCkge1xuICAgICAgICAgICAgICBmaWVsZHNXaXRoU2VsZWN0aW9uU2V0c1tmaWVsZC5uYW1lLnZhbHVlXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBoYXNTZWxlY3Rpb25TZXQgPSAoc3RvcmVGaWVsZE5hbWU6IHN0cmluZykgPT5cbiAgICAgICAgICAgIGZpZWxkc1dpdGhTZWxlY3Rpb25TZXRzW2ZpZWxkTmFtZUZyb21TdG9yZU5hbWUoc3RvcmVGaWVsZE5hbWUpXSA9PT1cbiAgICAgICAgICAgIHRydWU7XG5cbiAgICAgICAgICBjb25zdCBoYXNNZXJnZUZ1bmN0aW9uID0gKHN0b3JlRmllbGROYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkVHJlZSA9IG1lcmdlVHJlZSAmJiBtZXJnZVRyZWUubWFwLmdldChzdG9yZUZpZWxkTmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gQm9vbGVhbihjaGlsZFRyZWUgJiYgY2hpbGRUcmVlLmluZm8gJiYgY2hpbGRUcmVlLmluZm8ubWVyZ2UpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBPYmplY3Qua2V5cyhzdG9yZU9iamVjdCkuZm9yRWFjaCgoc3RvcmVGaWVsZE5hbWUpID0+IHtcbiAgICAgICAgICAgIC8vIElmIGEgbWVyZ2UgZnVuY3Rpb24gd2FzIGRlZmluZWQgZm9yIHRoaXMgZmllbGQsIHRydXN0IHRoYXQgaXRcbiAgICAgICAgICAgIC8vIGRpZCB0aGUgcmlnaHQgdGhpbmcgYWJvdXQgKG5vdCkgY2xvYmJlcmluZyBkYXRhLiBJZiB0aGUgZmllbGRcbiAgICAgICAgICAgIC8vIGhhcyBubyBzZWxlY3Rpb24gc2V0LCBpdCdzIGEgc2NhbGFyIGZpZWxkLCBzbyBpdCBkb2Vzbid0IG5lZWRcbiAgICAgICAgICAgIC8vIGEgbWVyZ2UgZnVuY3Rpb24gKGV2ZW4gaWYgaXQncyBhbiBvYmplY3QsIGxpa2UgSlNPTiBkYXRhKS5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgaGFzU2VsZWN0aW9uU2V0KHN0b3JlRmllbGROYW1lKSAmJlxuICAgICAgICAgICAgICAhaGFzTWVyZ2VGdW5jdGlvbihzdG9yZUZpZWxkTmFtZSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB3YXJuQWJvdXREYXRhTG9zcyhcbiAgICAgICAgICAgICAgICBlbnRpdHlSZWYsXG4gICAgICAgICAgICAgICAgc3RvcmVPYmplY3QsXG4gICAgICAgICAgICAgICAgc3RvcmVGaWVsZE5hbWUsXG4gICAgICAgICAgICAgICAgY29udGV4dC5zdG9yZVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RvcmUubWVyZ2UoZGF0YUlkLCBzdG9yZU9iamVjdCk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIEFueSBJRHMgd3JpdHRlbiBleHBsaWNpdGx5IHRvIHRoZSBjYWNoZSB3aWxsIGJlIHJldGFpbmVkIGFzXG4gICAgLy8gcmVhY2hhYmxlIHJvb3QgSURzIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24gcHVycG9zZXMuIEFsdGhvdWdoIHRoaXNcbiAgICAvLyBsb2dpYyBpbmNsdWRlcyByb290IElEcyBsaWtlIFJPT1RfUVVFUlkgYW5kIFJPT1RfTVVUQVRJT04sIHRoZWlyXG4gICAgLy8gcmV0YWlubWVudCBjb3VudHMgYXJlIGVmZmVjdGl2ZWx5IGlnbm9yZWQgYmVjYXVzZSBjYWNoZS5nYygpIGFsd2F5c1xuICAgIC8vIGluY2x1ZGVzIHRoZW0gaW4gaXRzIHJvb3QgSUQgc2V0LlxuICAgIHN0b3JlLnJldGFpbihyZWYuX19yZWYpO1xuXG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuXG4gIHByaXZhdGUgcHJvY2Vzc1NlbGVjdGlvblNldCh7XG4gICAgZGF0YUlkLFxuICAgIHJlc3VsdCxcbiAgICBzZWxlY3Rpb25TZXQsXG4gICAgY29udGV4dCxcbiAgICAvLyBUaGlzIG9iamVjdCBhbGxvd3MgcHJvY2Vzc1NlbGVjdGlvblNldCB0byByZXBvcnQgdXNlZnVsIGluZm9ybWF0aW9uXG4gICAgLy8gdG8gaXRzIGNhbGxlcnMgd2l0aG91dCBleHBsaWNpdGx5IHJldHVybmluZyB0aGF0IGluZm9ybWF0aW9uLlxuICAgIG1lcmdlVHJlZSxcbiAgfTogUHJvY2Vzc1NlbGVjdGlvblNldE9wdGlvbnMpOiBTdG9yZU9iamVjdCB8IFJlZmVyZW5jZSB7XG4gICAgY29uc3QgeyBwb2xpY2llcyB9ID0gdGhpcy5jYWNoZTtcblxuICAgIC8vIFRoaXMgdmFyaWFibGUgd2lsbCBiZSByZXBlYXRlZGx5IHVwZGF0ZWQgdXNpbmcgY29udGV4dC5tZXJnZSB0b1xuICAgIC8vIGFjY3VtdWxhdGUgYWxsIGZpZWxkcyB0aGF0IG5lZWQgdG8gYmUgd3JpdHRlbiBpbnRvIHRoZSBzdG9yZS5cbiAgICBsZXQgaW5jb21pbmc6IFN0b3JlT2JqZWN0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgIC8vIElmIHR5cGVuYW1lIHdhcyBub3QgcGFzc2VkIGluLCBpbmZlciBpdC4gTm90ZSB0aGF0IHR5cGVuYW1lIGlzXG4gICAgLy8gYWx3YXlzIHBhc3NlZCBpbiBmb3IgdHJpY2t5LXRvLWluZmVyIGNhc2VzIHN1Y2ggYXMgXCJRdWVyeVwiIGZvclxuICAgIC8vIFJPT1RfUVVFUlkuXG4gICAgY29uc3QgdHlwZW5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZCA9XG4gICAgICAoZGF0YUlkICYmIHBvbGljaWVzLnJvb3RUeXBlbmFtZXNCeUlkW2RhdGFJZF0pIHx8XG4gICAgICBnZXRUeXBlbmFtZUZyb21SZXN1bHQocmVzdWx0LCBzZWxlY3Rpb25TZXQsIGNvbnRleHQuZnJhZ21lbnRNYXApIHx8XG4gICAgICAoZGF0YUlkICYmIChjb250ZXh0LnN0b3JlLmdldChkYXRhSWQsIFwiX190eXBlbmFtZVwiKSBhcyBzdHJpbmcpKTtcblxuICAgIGlmIChcInN0cmluZ1wiID09PSB0eXBlb2YgdHlwZW5hbWUpIHtcbiAgICAgIGluY29taW5nLl9fdHlwZW5hbWUgPSB0eXBlbmFtZTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIHJlYWRGaWVsZCBmdW5jdGlvbiB3aWxsIGJlIHBhc3NlZCBhcyBjb250ZXh0LnJlYWRGaWVsZCBpbiB0aGVcbiAgICAvLyBLZXlGaWVsZHNDb250ZXh0IG9iamVjdCBjcmVhdGVkIHdpdGhpbiBwb2xpY2llcy5pZGVudGlmeSAoY2FsbGVkIGJlbG93KS5cbiAgICAvLyBJbiBhZGRpdGlvbiB0byByZWFkaW5nIGZyb20gdGhlIGV4aXN0aW5nIGNvbnRleHQuc3RvcmUgKHRoYW5rcyB0byB0aGVcbiAgICAvLyBwb2xpY2llcy5yZWFkRmllbGQob3B0aW9ucywgY29udGV4dCkgbGluZSBhdCB0aGUgdmVyeSBib3R0b20pLCB0aGlzXG4gICAgLy8gdmVyc2lvbiBvZiByZWFkRmllbGQgY2FuIHJlYWQgZnJvbSBSZWZlcmVuY2Ugb2JqZWN0cyB0aGF0IGFyZSBjdXJyZW50bHlcbiAgICAvLyBwZW5kaW5nIGluIGNvbnRleHQuaW5jb21pbmdCeUlkLCB3aGljaCBpcyBpbXBvcnRhbnQgd2hlbmV2ZXIga2V5RmllbGRzXG4gICAgLy8gbmVlZCB0byBiZSBleHRyYWN0ZWQgZnJvbSBhIGNoaWxkIG9iamVjdCB0aGF0IHByb2Nlc3NTZWxlY3Rpb25TZXQgaGFzXG4gICAgLy8gdHVybmVkIGludG8gYSBSZWZlcmVuY2UuXG4gICAgY29uc3QgcmVhZEZpZWxkOiBSZWFkRmllbGRGdW5jdGlvbiA9IGZ1bmN0aW9uICh0aGlzOiB2b2lkKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gbm9ybWFsaXplUmVhZEZpZWxkT3B0aW9ucyhcbiAgICAgICAgYXJndW1lbnRzLFxuICAgICAgICBpbmNvbWluZyxcbiAgICAgICAgY29udGV4dC52YXJpYWJsZXNcbiAgICAgICk7XG5cbiAgICAgIGlmIChpc1JlZmVyZW5jZShvcHRpb25zLmZyb20pKSB7XG4gICAgICAgIGNvbnN0IGluZm8gPSBjb250ZXh0LmluY29taW5nQnlJZC5nZXQob3B0aW9ucy5mcm9tLl9fcmVmKTtcbiAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBwb2xpY2llcy5yZWFkRmllbGQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICAgIGZyb206IGluZm8uc3RvcmVPYmplY3QsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAocmVzdWx0ICE9PSB2b2lkIDApIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwb2xpY2llcy5yZWFkRmllbGQob3B0aW9ucywgY29udGV4dCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGZpZWxkTm9kZVNldCA9IG5ldyBTZXQ8RmllbGROb2RlPigpO1xuXG4gICAgdGhpcy5mbGF0dGVuRmllbGRzKFxuICAgICAgc2VsZWN0aW9uU2V0LFxuICAgICAgcmVzdWx0LFxuICAgICAgLy8gVGhpcyBXcml0ZUNvbnRleHQgd2lsbCBiZSB0aGUgZGVmYXVsdCBjb250ZXh0IHZhbHVlIGZvciBmaWVsZHMgcmV0dXJuZWRcbiAgICAgIC8vIGJ5IHRoZSBmbGF0dGVuRmllbGRzIG1ldGhvZCwgYnV0IHNvbWUgZmllbGRzIG1heSBiZSBhc3NpZ25lZCBhIG1vZGlmaWVkXG4gICAgICAvLyBjb250ZXh0LCBkZXBlbmRpbmcgb24gdGhlIHByZXNlbmNlIG9mIEBjbGllbnQgYW5kIG90aGVyIGRpcmVjdGl2ZXMuXG4gICAgICBjb250ZXh0LFxuICAgICAgdHlwZW5hbWVcbiAgICApLmZvckVhY2goKGNvbnRleHQsIGZpZWxkKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHRGaWVsZEtleSA9IHJlc3VsdEtleU5hbWVGcm9tRmllbGQoZmllbGQpO1xuICAgICAgY29uc3QgdmFsdWUgPSByZXN1bHRbcmVzdWx0RmllbGRLZXldO1xuXG4gICAgICBmaWVsZE5vZGVTZXQuYWRkKGZpZWxkKTtcblxuICAgICAgaWYgKHZhbHVlICE9PSB2b2lkIDApIHtcbiAgICAgICAgY29uc3Qgc3RvcmVGaWVsZE5hbWUgPSBwb2xpY2llcy5nZXRTdG9yZUZpZWxkTmFtZSh7XG4gICAgICAgICAgdHlwZW5hbWUsXG4gICAgICAgICAgZmllbGROYW1lOiBmaWVsZC5uYW1lLnZhbHVlLFxuICAgICAgICAgIGZpZWxkLFxuICAgICAgICAgIHZhcmlhYmxlczogY29udGV4dC52YXJpYWJsZXMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHJlZSA9IGdldENoaWxkTWVyZ2VUcmVlKG1lcmdlVHJlZSwgc3RvcmVGaWVsZE5hbWUpO1xuXG4gICAgICAgIGxldCBpbmNvbWluZ1ZhbHVlID0gdGhpcy5wcm9jZXNzRmllbGRWYWx1ZShcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICAvLyBSZXNldCBjb250ZXh0LmNsaWVudE9ubHkgYW5kIGNvbnRleHQuZGVmZXJyZWQgdG8gdGhlaXIgZGVmYXVsdFxuICAgICAgICAgIC8vIHZhbHVlcyBiZWZvcmUgcHJvY2Vzc2luZyBuZXN0ZWQgc2VsZWN0aW9uIHNldHMuXG4gICAgICAgICAgZmllbGQuc2VsZWN0aW9uU2V0ID9cbiAgICAgICAgICAgIGdldENvbnRleHRGbGF2b3IoY29udGV4dCwgZmFsc2UsIGZhbHNlKVxuICAgICAgICAgIDogY29udGV4dCxcbiAgICAgICAgICBjaGlsZFRyZWVcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBUbyBkZXRlcm1pbmUgaWYgdGhpcyBmaWVsZCBob2xkcyBhIGNoaWxkIG9iamVjdCB3aXRoIGEgbWVyZ2UgZnVuY3Rpb25cbiAgICAgICAgLy8gZGVmaW5lZCBpbiBpdHMgdHlwZSBwb2xpY3kgKHNlZSBQUiAjNzA3MCksIHdlIG5lZWQgdG8gZmlndXJlIG91dCB0aGVcbiAgICAgICAgLy8gY2hpbGQgb2JqZWN0J3MgX190eXBlbmFtZS5cbiAgICAgICAgbGV0IGNoaWxkVHlwZW5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgICAgICAvLyBUaGUgZmllbGQncyB2YWx1ZSBjYW4gYmUgYW4gb2JqZWN0IHRoYXQgaGFzIGEgX190eXBlbmFtZSBvbmx5IGlmIHRoZVxuICAgICAgICAvLyBmaWVsZCBoYXMgYSBzZWxlY3Rpb24gc2V0LiBPdGhlcndpc2UgaW5jb21pbmdWYWx1ZSBpcyBzY2FsYXIuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBmaWVsZC5zZWxlY3Rpb25TZXQgJiZcbiAgICAgICAgICAoaXNSZWZlcmVuY2UoaW5jb21pbmdWYWx1ZSkgfHwgc3RvcmVWYWx1ZUlzU3RvcmVPYmplY3QoaW5jb21pbmdWYWx1ZSkpXG4gICAgICAgICkge1xuICAgICAgICAgIGNoaWxkVHlwZW5hbWUgPSByZWFkRmllbGQ8c3RyaW5nPihcIl9fdHlwZW5hbWVcIiwgaW5jb21pbmdWYWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtZXJnZSA9IHBvbGljaWVzLmdldE1lcmdlRnVuY3Rpb24oXG4gICAgICAgICAgdHlwZW5hbWUsXG4gICAgICAgICAgZmllbGQubmFtZS52YWx1ZSxcbiAgICAgICAgICBjaGlsZFR5cGVuYW1lXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKG1lcmdlKSB7XG4gICAgICAgICAgY2hpbGRUcmVlLmluZm8gPSB7XG4gICAgICAgICAgICAvLyBUT0RPIENoZWNrIGNvbXBhdGliaWxpdHkgYWdhaW5zdCBhbnkgZXhpc3RpbmcgY2hpbGRUcmVlLmZpZWxkP1xuICAgICAgICAgICAgZmllbGQsXG4gICAgICAgICAgICB0eXBlbmFtZSxcbiAgICAgICAgICAgIG1lcmdlLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF5YmVSZWN5Y2xlQ2hpbGRNZXJnZVRyZWUobWVyZ2VUcmVlLCBzdG9yZUZpZWxkTmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpbmNvbWluZyA9IGNvbnRleHQubWVyZ2UoaW5jb21pbmcsIHtcbiAgICAgICAgICBbc3RvcmVGaWVsZE5hbWVdOiBpbmNvbWluZ1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIF9fREVWX18gJiZcbiAgICAgICAgIWNvbnRleHQuY2xpZW50T25seSAmJlxuICAgICAgICAhY29udGV4dC5kZWZlcnJlZCAmJlxuICAgICAgICAhYWRkVHlwZW5hbWVUb0RvY3VtZW50LmFkZGVkKGZpZWxkKSAmJlxuICAgICAgICAvLyBJZiB0aGUgZmllbGQgaGFzIGEgcmVhZCBmdW5jdGlvbiwgaXQgbWF5IGJlIGEgc3ludGhldGljIGZpZWxkIG9yXG4gICAgICAgIC8vIHByb3ZpZGUgYSBkZWZhdWx0IHZhbHVlLCBzbyBpdHMgYWJzZW5jZSBmcm9tIHRoZSB3cml0dGVuIGRhdGEgc2hvdWxkXG4gICAgICAgIC8vIG5vdCBiZSBjYXVzZSBmb3IgYWxhcm0uXG4gICAgICAgICFwb2xpY2llcy5nZXRSZWFkRnVuY3Rpb24odHlwZW5hbWUsIGZpZWxkLm5hbWUudmFsdWUpXG4gICAgICApIHtcbiAgICAgICAgaW52YXJpYW50LmVycm9yKFxuICAgICAgICAgIGBNaXNzaW5nIGZpZWxkICclcycgd2hpbGUgd3JpdGluZyByZXN1bHQgJW9gLFxuICAgICAgICAgIHJlc3VsdEtleU5hbWVGcm9tRmllbGQoZmllbGQpLFxuICAgICAgICAgIHJlc3VsdFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gSWRlbnRpZnkgdGhlIHJlc3VsdCBvYmplY3QsIGV2ZW4gaWYgZGF0YUlkIHdhcyBhbHJlYWR5IHByb3ZpZGVkLFxuICAgIC8vIHNpbmNlIHdlIGFsd2F5cyBuZWVkIGtleU9iamVjdCBiZWxvdy5cbiAgICB0cnkge1xuICAgICAgY29uc3QgW2lkLCBrZXlPYmplY3RdID0gcG9saWNpZXMuaWRlbnRpZnkocmVzdWx0LCB7XG4gICAgICAgIHR5cGVuYW1lLFxuICAgICAgICBzZWxlY3Rpb25TZXQsXG4gICAgICAgIGZyYWdtZW50TWFwOiBjb250ZXh0LmZyYWdtZW50TWFwLFxuICAgICAgICBzdG9yZU9iamVjdDogaW5jb21pbmcsXG4gICAgICAgIHJlYWRGaWVsZCxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBJZiBkYXRhSWQgd2FzIG5vdCBwcm92aWRlZCwgZmFsbCBiYWNrIHRvIHRoZSBpZCBqdXN0IGdlbmVyYXRlZCBieVxuICAgICAgLy8gcG9saWNpZXMuaWRlbnRpZnkuXG4gICAgICBkYXRhSWQgPSBkYXRhSWQgfHwgaWQ7XG5cbiAgICAgIC8vIFdyaXRlIGFueSBrZXkgZmllbGRzIHRoYXQgd2VyZSB1c2VkIGR1cmluZyBpZGVudGlmaWNhdGlvbiwgZXZlbiBpZlxuICAgICAgLy8gdGhleSB3ZXJlIG5vdCBtZW50aW9uZWQgaW4gdGhlIG9yaWdpbmFsIHF1ZXJ5LlxuICAgICAgaWYgKGtleU9iamVjdCkge1xuICAgICAgICAvLyBUT0RPIFJldmVyc2UgdGhlIG9yZGVyIG9mIHRoZSBhcmd1bWVudHM/XG4gICAgICAgIGluY29taW5nID0gY29udGV4dC5tZXJnZShpbmNvbWluZywga2V5T2JqZWN0KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBJZiBkYXRhSWQgd2FzIHByb3ZpZGVkLCB0b2xlcmF0ZSBmYWlsdXJlIG9mIHBvbGljaWVzLmlkZW50aWZ5LlxuICAgICAgaWYgKCFkYXRhSWQpIHRocm93IGU7XG4gICAgfVxuXG4gICAgaWYgKFwic3RyaW5nXCIgPT09IHR5cGVvZiBkYXRhSWQpIHtcbiAgICAgIGNvbnN0IGRhdGFSZWYgPSBtYWtlUmVmZXJlbmNlKGRhdGFJZCk7XG5cbiAgICAgIC8vIEF2b2lkIHByb2Nlc3NpbmcgdGhlIHNhbWUgZW50aXR5IG9iamVjdCB1c2luZyB0aGUgc2FtZSBzZWxlY3Rpb25cbiAgICAgIC8vIHNldCBtb3JlIHRoYW4gb25jZS4gV2UgdXNlIGFuIGFycmF5IGluc3RlYWQgb2YgYSBTZXQgc2luY2UgbW9zdFxuICAgICAgLy8gZW50aXR5IElEcyB3aWxsIGJlIHdyaXR0ZW4gdXNpbmcgb25seSBvbmUgc2VsZWN0aW9uIHNldCwgc28gdGhlXG4gICAgICAvLyBzaXplIG9mIHRoaXMgYXJyYXkgaXMgbGlrZWx5IHRvIGJlIHZlcnkgc21hbGwsIG1lYW5pbmcgaW5kZXhPZiBpc1xuICAgICAgLy8gbGlrZWx5IHRvIGJlIGZhc3RlciB0aGFuIFNldC5wcm90b3R5cGUuaGFzLlxuICAgICAgY29uc3Qgc2V0cyA9IGNvbnRleHQud3JpdHRlbltkYXRhSWRdIHx8IChjb250ZXh0LndyaXR0ZW5bZGF0YUlkXSA9IFtdKTtcbiAgICAgIGlmIChzZXRzLmluZGV4T2Yoc2VsZWN0aW9uU2V0KSA+PSAwKSByZXR1cm4gZGF0YVJlZjtcbiAgICAgIHNldHMucHVzaChzZWxlY3Rpb25TZXQpO1xuXG4gICAgICAvLyBJZiB3ZSdyZSBhYm91dCB0byB3cml0ZSBhIHJlc3VsdCBvYmplY3QgaW50byB0aGUgc3RvcmUsIGJ1dCB3ZVxuICAgICAgLy8gaGFwcGVuIHRvIGtub3cgdGhhdCB0aGUgZXhhY3Qgc2FtZSAoPT09KSByZXN1bHQgb2JqZWN0IHdvdWxkIGJlXG4gICAgICAvLyByZXR1cm5lZCBpZiB3ZSB3ZXJlIHRvIHJlcmVhZCB0aGUgcmVzdWx0IHdpdGggdGhlIHNhbWUgaW5wdXRzLFxuICAgICAgLy8gdGhlbiB3ZSBjYW4gc2tpcCB0aGUgcmVzdCBvZiB0aGUgcHJvY2Vzc1NlbGVjdGlvblNldCB3b3JrIGZvclxuICAgICAgLy8gdGhpcyBvYmplY3QsIGFuZCBpbW1lZGlhdGVseSByZXR1cm4gYSBSZWZlcmVuY2UgdG8gaXQuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMucmVhZGVyICYmXG4gICAgICAgIHRoaXMucmVhZGVyLmlzRnJlc2gocmVzdWx0LCBkYXRhUmVmLCBzZWxlY3Rpb25TZXQsIGNvbnRleHQpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGRhdGFSZWY7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByZXZpb3VzID0gY29udGV4dC5pbmNvbWluZ0J5SWQuZ2V0KGRhdGFJZCk7XG4gICAgICBpZiAocHJldmlvdXMpIHtcbiAgICAgICAgcHJldmlvdXMuc3RvcmVPYmplY3QgPSBjb250ZXh0Lm1lcmdlKHByZXZpb3VzLnN0b3JlT2JqZWN0LCBpbmNvbWluZyk7XG4gICAgICAgIHByZXZpb3VzLm1lcmdlVHJlZSA9IG1lcmdlTWVyZ2VUcmVlcyhwcmV2aW91cy5tZXJnZVRyZWUsIG1lcmdlVHJlZSk7XG4gICAgICAgIGZpZWxkTm9kZVNldC5mb3JFYWNoKChmaWVsZCkgPT4gcHJldmlvdXMuZmllbGROb2RlU2V0LmFkZChmaWVsZCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGV4dC5pbmNvbWluZ0J5SWQuc2V0KGRhdGFJZCwge1xuICAgICAgICAgIHN0b3JlT2JqZWN0OiBpbmNvbWluZyxcbiAgICAgICAgICAvLyBTYXZlIGEgcmVmZXJlbmNlIHRvIG1lcmdlVHJlZSBvbmx5IGlmIGl0IGlzIG5vdCBlbXB0eSwgYmVjYXVzZVxuICAgICAgICAgIC8vIGVtcHR5IE1lcmdlVHJlZXMgbWF5IGJlIHJlY3ljbGVkIGJ5IG1heWJlUmVjeWNsZUNoaWxkTWVyZ2VUcmVlIGFuZFxuICAgICAgICAgIC8vIHJldXNlZCBmb3IgZW50aXJlbHkgZGlmZmVyZW50IHBhcnRzIG9mIHRoZSByZXN1bHQgdHJlZS5cbiAgICAgICAgICBtZXJnZVRyZWU6IG1lcmdlVHJlZUlzRW1wdHkobWVyZ2VUcmVlKSA/IHZvaWQgMCA6IG1lcmdlVHJlZSxcbiAgICAgICAgICBmaWVsZE5vZGVTZXQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZGF0YVJlZjtcbiAgICB9XG5cbiAgICByZXR1cm4gaW5jb21pbmc7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NGaWVsZFZhbHVlKFxuICAgIHZhbHVlOiBhbnksXG4gICAgZmllbGQ6IEZpZWxkTm9kZSxcbiAgICBjb250ZXh0OiBXcml0ZUNvbnRleHQsXG4gICAgbWVyZ2VUcmVlOiBNZXJnZVRyZWVcbiAgKTogU3RvcmVWYWx1ZSB7XG4gICAgaWYgKCFmaWVsZC5zZWxlY3Rpb25TZXQgfHwgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgIC8vIEluIGRldmVsb3BtZW50LCB3ZSBuZWVkIHRvIGNsb25lIHNjYWxhciB2YWx1ZXMgc28gdGhhdCB0aGV5IGNhbiBiZVxuICAgICAgLy8gc2FmZWx5IGZyb3plbiB3aXRoIG1heWJlRGVlcEZyZWV6ZSBpbiByZWFkRnJvbVN0b3JlLnRzLiBJbiBwcm9kdWN0aW9uLFxuICAgICAgLy8gaXQncyBjaGVhcGVyIHRvIHN0b3JlIHRoZSBzY2FsYXIgdmFsdWVzIGRpcmVjdGx5IGluIHRoZSBjYWNoZS5cbiAgICAgIHJldHVybiBfX0RFVl9fID8gY2xvbmVEZWVwKHZhbHVlKSA6IHZhbHVlO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlLm1hcCgoaXRlbSwgaSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucHJvY2Vzc0ZpZWxkVmFsdWUoXG4gICAgICAgICAgaXRlbSxcbiAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIGdldENoaWxkTWVyZ2VUcmVlKG1lcmdlVHJlZSwgaSlcbiAgICAgICAgKTtcbiAgICAgICAgbWF5YmVSZWN5Y2xlQ2hpbGRNZXJnZVRyZWUobWVyZ2VUcmVlLCBpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucHJvY2Vzc1NlbGVjdGlvblNldCh7XG4gICAgICByZXN1bHQ6IHZhbHVlLFxuICAgICAgc2VsZWN0aW9uU2V0OiBmaWVsZC5zZWxlY3Rpb25TZXQsXG4gICAgICBjb250ZXh0LFxuICAgICAgbWVyZ2VUcmVlLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gSW1wbGVtZW50cyBodHRwczovL3NwZWMuZ3JhcGhxbC5vcmcvZHJhZnQvI3NlYy1GaWVsZC1Db2xsZWN0aW9uLCBidXQgd2l0aFxuICAvLyBzb21lIGFkZGl0aW9ucyBmb3IgdHJhY2tpbmcgQGNsaWVudCBhbmQgQGRlZmVyIGRpcmVjdGl2ZXMuXG4gIHByaXZhdGUgZmxhdHRlbkZpZWxkczxcbiAgICBUQ29udGV4dCBleHRlbmRzIFBpY2s8XG4gICAgICBXcml0ZUNvbnRleHQsXG4gICAgICB8IFwiY2xpZW50T25seVwiXG4gICAgICB8IFwiZGVmZXJyZWRcIlxuICAgICAgfCBcImZsYXZvcnNcIlxuICAgICAgfCBcImZyYWdtZW50TWFwXCJcbiAgICAgIHwgXCJsb29rdXBGcmFnbWVudFwiXG4gICAgICB8IFwidmFyaWFibGVzXCJcbiAgICA+LFxuICA+KFxuICAgIHNlbGVjdGlvblNldDogU2VsZWN0aW9uU2V0Tm9kZSxcbiAgICByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgY29udGV4dDogVENvbnRleHQsXG4gICAgdHlwZW5hbWUgPSBnZXRUeXBlbmFtZUZyb21SZXN1bHQocmVzdWx0LCBzZWxlY3Rpb25TZXQsIGNvbnRleHQuZnJhZ21lbnRNYXApXG4gICk6IE1hcDxGaWVsZE5vZGUsIFRDb250ZXh0PiB7XG4gICAgY29uc3QgZmllbGRNYXAgPSBuZXcgTWFwPEZpZWxkTm9kZSwgVENvbnRleHQ+KCk7XG4gICAgY29uc3QgeyBwb2xpY2llcyB9ID0gdGhpcy5jYWNoZTtcblxuICAgIGNvbnN0IGxpbWl0aW5nVHJpZSA9IG5ldyBUcmllPHtcbiAgICAgIC8vIFRyYWNrcyB3aGV0aGVyIChzZWxlY3Rpb25TZXQsIGNsaWVudE9ubHksIGRlZmVycmVkKSBoYXMgYmVlbiBmbGF0dGVuZWRcbiAgICAgIC8vIGJlZm9yZS4gVGhlIEdyYXBoUUwgc3BlY2lmaWNhdGlvbiBvbmx5IHVzZXMgdGhlIGZyYWdtZW50IG5hbWUgZm9yXG4gICAgICAvLyBza2lwcGluZyBwcmV2aW91c2x5IHZpc2l0ZWQgZnJhZ21lbnRzLCBidXQgdGhlIHRvcC1sZXZlbCBmcmFnbWVudFxuICAgICAgLy8gc2VsZWN0aW9uIHNldCBjb3JyZXNwb25kcyAxOjEgd2l0aCB0aGUgZmFnbWVudCBuYW1lIChhbmQgaXMgc2xpZ2h0bHlcbiAgICAgIC8vIGVhc2llciB0b28gd29yayB3aXRoKSwgYW5kIHdlIG5lZWQgdG8gY29uc2lkZXIgY2xpZW50T25seSBhbmQgZGVmZXJyZWRcbiAgICAgIC8vIHZhbHVlcyBhcyB3ZWxsLCBwb3RlbnRpYWxseSByZXZpc2l0aW5nIHNlbGVjdGlvbiBzZXRzIHRoYXQgd2VyZVxuICAgICAgLy8gcHJldmlvdXNseSB2aXNpdGVkIHdpdGggZGlmZmVyZW50IGluaGVyaXRlZCBjb25maWd1cmF0aW9ucyBvZiB0aG9zZVxuICAgICAgLy8gZGlyZWN0aXZlcy5cbiAgICAgIHZpc2l0ZWQ/OiBib29sZWFuO1xuICAgIH0+KGZhbHNlKTsgLy8gTm8gbmVlZCBmb3IgV2Vha01hcCwgc2luY2UgbGltaXRpbmdUcmllIGRvZXMgbm90IGVzY2FwZS5cblxuICAgIChmdW5jdGlvbiBmbGF0dGVuKFxuICAgICAgdGhpczogdm9pZCxcbiAgICAgIHNlbGVjdGlvblNldDogU2VsZWN0aW9uU2V0Tm9kZSxcbiAgICAgIGluaGVyaXRlZENvbnRleHQ6IFRDb250ZXh0XG4gICAgKSB7XG4gICAgICBjb25zdCB2aXNpdGVkTm9kZSA9IGxpbWl0aW5nVHJpZS5sb29rdXAoXG4gICAgICAgIHNlbGVjdGlvblNldCxcbiAgICAgICAgLy8gQmVjYXVzZSB3ZSB0YWtlIGluaGVyaXRlZENsaWVudE9ubHkgYW5kIGluaGVyaXRlZERlZmVycmVkIGludG9cbiAgICAgICAgLy8gY29uc2lkZXJhdGlvbiBoZXJlIChpbiBhZGRpdGlvbiB0byBzZWxlY3Rpb25TZXQpLCBpdCdzIHBvc3NpYmxlIGZvclxuICAgICAgICAvLyB0aGUgc2FtZSBzZWxlY3Rpb24gc2V0IHRvIGJlIGZsYXR0ZW5lZCBtb3JlIHRoYW4gb25jZSwgaWYgaXQgYXBwZWFyc1xuICAgICAgICAvLyBpbiB0aGUgcXVlcnkgd2l0aCBkaWZmZXJlbnQgQGNsaWVudCBhbmQvb3IgQGRpcmVjdGl2ZSBjb25maWd1cmF0aW9ucy5cbiAgICAgICAgaW5oZXJpdGVkQ29udGV4dC5jbGllbnRPbmx5LFxuICAgICAgICBpbmhlcml0ZWRDb250ZXh0LmRlZmVycmVkXG4gICAgICApO1xuICAgICAgaWYgKHZpc2l0ZWROb2RlLnZpc2l0ZWQpIHJldHVybjtcbiAgICAgIHZpc2l0ZWROb2RlLnZpc2l0ZWQgPSB0cnVlO1xuXG4gICAgICBzZWxlY3Rpb25TZXQuc2VsZWN0aW9ucy5mb3JFYWNoKChzZWxlY3Rpb24pID0+IHtcbiAgICAgICAgaWYgKCFzaG91bGRJbmNsdWRlKHNlbGVjdGlvbiwgY29udGV4dC52YXJpYWJsZXMpKSByZXR1cm47XG5cbiAgICAgICAgbGV0IHsgY2xpZW50T25seSwgZGVmZXJyZWQgfSA9IGluaGVyaXRlZENvbnRleHQ7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAvLyBTaW5jZSB0aGUgcHJlc2VuY2Ugb2YgQGNsaWVudCBvciBAZGVmZXIgb24gdGhpcyBmaWVsZCBjYW4gb25seVxuICAgICAgICAgIC8vIGNhdXNlIGNsaWVudE9ubHkgb3IgZGVmZXJyZWQgdG8gYmVjb21lIHRydWUsIHdlIGNhbiBza2lwIHRoZVxuICAgICAgICAgIC8vIGZvckVhY2ggbG9vcCBpZiBib3RoIGNsaWVudE9ubHkgYW5kIGRlZmVycmVkIGFyZSBhbHJlYWR5IHRydWUuXG4gICAgICAgICAgIShjbGllbnRPbmx5ICYmIGRlZmVycmVkKSAmJlxuICAgICAgICAgIGlzTm9uRW1wdHlBcnJheShzZWxlY3Rpb24uZGlyZWN0aXZlcylcbiAgICAgICAgKSB7XG4gICAgICAgICAgc2VsZWN0aW9uLmRpcmVjdGl2ZXMuZm9yRWFjaCgoZGlyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gZGlyLm5hbWUudmFsdWU7XG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gXCJjbGllbnRcIikgY2xpZW50T25seSA9IHRydWU7XG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gXCJkZWZlclwiKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBhcmd1bWVudHNPYmplY3RGcm9tRmllbGQoZGlyLCBjb250ZXh0LnZhcmlhYmxlcyk7XG4gICAgICAgICAgICAgIC8vIFRoZSBAZGVmZXIgZGlyZWN0aXZlIHRha2VzIGFuIG9wdGlvbmFsIGFyZ3MuaWYgYm9vbGVhblxuICAgICAgICAgICAgICAvLyBhcmd1bWVudCwgc2ltaWxhciB0byBAaW5jbHVkZShpZjogYm9vbGVhbikuIE5vdGUgdGhhdFxuICAgICAgICAgICAgICAvLyBAZGVmZXIoaWY6IGZhbHNlKSBkb2VzIG5vdCBtYWtlIGNvbnRleHQuZGVmZXJyZWQgZmFsc2UsIGJ1dFxuICAgICAgICAgICAgICAvLyBpbnN0ZWFkIGJlaGF2ZXMgYXMgaWYgdGhlcmUgd2FzIG5vIEBkZWZlciBkaXJlY3RpdmUuXG4gICAgICAgICAgICAgIGlmICghYXJncyB8fCAoYXJncyBhcyB7IGlmPzogYm9vbGVhbiB9KS5pZiAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBkZWZlcnJlZCA9IHRydWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gVE9ETyBJbiB0aGUgZnV0dXJlLCB3ZSBtYXkgd2FudCB0byByZWNvcmQgYXJncy5sYWJlbCB1c2luZ1xuICAgICAgICAgICAgICAvLyBjb250ZXh0LmRlZmVycmVkLCBpZiBhIGxhYmVsIGlzIHNwZWNpZmllZC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0ZpZWxkKHNlbGVjdGlvbikpIHtcbiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IGZpZWxkTWFwLmdldChzZWxlY3Rpb24pO1xuICAgICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgICAgLy8gSWYgdGhpcyBmaWVsZCBoYXMgYmVlbiB2aXNpdGVkIGFsb25nIGFub3RoZXIgcmVjdXJzaXZlIHBhdGhcbiAgICAgICAgICAgIC8vIGJlZm9yZSwgdGhlIGZpbmFsIGNvbnRleHQgc2hvdWxkIGhhdmUgY2xpZW50T25seSBvciBkZWZlcnJlZCBzZXRcbiAgICAgICAgICAgIC8vIHRvIHRydWUgb25seSBpZiAqYWxsKiBwYXRocyBoYXZlIHRoZSBkaXJlY3RpdmUgKGhlbmNlIHRoZSAmJikuXG4gICAgICAgICAgICBjbGllbnRPbmx5ID0gY2xpZW50T25seSAmJiBleGlzdGluZy5jbGllbnRPbmx5O1xuICAgICAgICAgICAgZGVmZXJyZWQgPSBkZWZlcnJlZCAmJiBleGlzdGluZy5kZWZlcnJlZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmaWVsZE1hcC5zZXQoXG4gICAgICAgICAgICBzZWxlY3Rpb24sXG4gICAgICAgICAgICBnZXRDb250ZXh0Rmxhdm9yKGNvbnRleHQsIGNsaWVudE9ubHksIGRlZmVycmVkKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZnJhZ21lbnQgPSBnZXRGcmFnbWVudEZyb21TZWxlY3Rpb24oXG4gICAgICAgICAgICBzZWxlY3Rpb24sXG4gICAgICAgICAgICBjb250ZXh0Lmxvb2t1cEZyYWdtZW50XG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmICghZnJhZ21lbnQgJiYgc2VsZWN0aW9uLmtpbmQgPT09IEtpbmQuRlJBR01FTlRfU1BSRUFEKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXdJbnZhcmlhbnRFcnJvcihcbiAgICAgICAgICAgICAgYE5vIGZyYWdtZW50IG5hbWVkICVzYCxcbiAgICAgICAgICAgICAgc2VsZWN0aW9uLm5hbWUudmFsdWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZnJhZ21lbnQgJiZcbiAgICAgICAgICAgIHBvbGljaWVzLmZyYWdtZW50TWF0Y2hlcyhcbiAgICAgICAgICAgICAgZnJhZ21lbnQsXG4gICAgICAgICAgICAgIHR5cGVuYW1lLFxuICAgICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICAgIGNvbnRleHQudmFyaWFibGVzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBmbGF0dGVuKFxuICAgICAgICAgICAgICBmcmFnbWVudC5zZWxlY3Rpb25TZXQsXG4gICAgICAgICAgICAgIGdldENvbnRleHRGbGF2b3IoY29udGV4dCwgY2xpZW50T25seSwgZGVmZXJyZWQpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSkoc2VsZWN0aW9uU2V0LCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmaWVsZE1hcDtcbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlNZXJnZXM8VCBleHRlbmRzIFN0b3JlVmFsdWU+KFxuICAgIG1lcmdlVHJlZTogTWVyZ2VUcmVlLFxuICAgIGV4aXN0aW5nOiBTdG9yZVZhbHVlLFxuICAgIGluY29taW5nOiBULFxuICAgIGNvbnRleHQ6IFdyaXRlQ29udGV4dCxcbiAgICBnZXRTdG9yYWdlQXJncz86IFBhcmFtZXRlcnM8RW50aXR5U3RvcmVbXCJnZXRTdG9yYWdlXCJdPlxuICApOiBUIHwgUmVmZXJlbmNlIHtcbiAgICBpZiAobWVyZ2VUcmVlLm1hcC5zaXplICYmICFpc1JlZmVyZW5jZShpbmNvbWluZykpIHtcbiAgICAgIGNvbnN0IGU6IFN0b3JlT2JqZWN0IHwgUmVmZXJlbmNlIHwgdW5kZWZpbmVkID1cbiAgICAgICAgLy8gSXRlbXMgaW4gdGhlIHNhbWUgcG9zaXRpb24gaW4gZGlmZmVyZW50IGFycmF5cyBhcmUgbm90XG4gICAgICAgIC8vIG5lY2Vzc2FyaWx5IHJlbGF0ZWQgdG8gZWFjaCBvdGhlciwgc28gd2hlbiBpbmNvbWluZyBpcyBhbiBhcnJheVxuICAgICAgICAvLyB3ZSBwcm9jZXNzIGl0cyBlbGVtZW50cyBhcyBpZiB0aGVyZSB3YXMgbm8gZXhpc3RpbmcgZGF0YS5cbiAgICAgICAgKFxuICAgICAgICAgICFpc0FycmF5KGluY29taW5nKSAmJlxuICAgICAgICAgIC8vIExpa2V3aXNlLCBleGlzdGluZyBtdXN0IGJlIGVpdGhlciBhIFJlZmVyZW5jZSBvciBhIFN0b3JlT2JqZWN0XG4gICAgICAgICAgLy8gaW4gb3JkZXIgZm9yIGl0cyBmaWVsZHMgdG8gYmUgc2FmZSB0byBtZXJnZSB3aXRoIHRoZSBmaWVsZHMgb2ZcbiAgICAgICAgICAvLyB0aGUgaW5jb21pbmcgb2JqZWN0LlxuICAgICAgICAgIChpc1JlZmVyZW5jZShleGlzdGluZykgfHwgc3RvcmVWYWx1ZUlzU3RvcmVPYmplY3QoZXhpc3RpbmcpKVxuICAgICAgICApID9cbiAgICAgICAgICBleGlzdGluZ1xuICAgICAgICA6IHZvaWQgMDtcblxuICAgICAgLy8gVGhpcyBuYXJyb3dpbmcgaXMgaW1wbGllZCBieSBtZXJnZVRyZWUubWFwLnNpemUgPiAwIGFuZFxuICAgICAgLy8gIWlzUmVmZXJlbmNlKGluY29taW5nKSwgdGhvdWdoIFR5cGVTY3JpcHQgdW5kZXJzdGFuZGFibHkgY2Fubm90XG4gICAgICAvLyBob3BlIHRvIGluZmVyIHRoaXMgdHlwZS5cbiAgICAgIGNvbnN0IGkgPSBpbmNvbWluZyBhcyBTdG9yZU9iamVjdCB8IFN0b3JlVmFsdWVbXTtcblxuICAgICAgLy8gVGhlIG9wdGlvbnMuc3RvcmFnZSBvYmplY3RzIHByb3ZpZGVkIHRvIHJlYWQgYW5kIG1lcmdlIGZ1bmN0aW9uc1xuICAgICAgLy8gYXJlIGRlcml2ZWQgZnJvbSB0aGUgaWRlbnRpdHkgb2YgdGhlIHBhcmVudCBvYmplY3QgcGx1cyBhXG4gICAgICAvLyBzZXF1ZW5jZSBvZiBzdG9yZUZpZWxkTmFtZSBzdHJpbmdzL251bWJlcnMgaWRlbnRpZnlpbmcgdGhlIG5lc3RlZFxuICAgICAgLy8gZmllbGQgbmFtZSBwYXRoIG9mIGVhY2ggZmllbGQgdmFsdWUgdG8gYmUgbWVyZ2VkLlxuICAgICAgaWYgKGUgJiYgIWdldFN0b3JhZ2VBcmdzKSB7XG4gICAgICAgIGdldFN0b3JhZ2VBcmdzID0gW2lzUmVmZXJlbmNlKGUpID8gZS5fX3JlZiA6IGVdO1xuICAgICAgfVxuXG4gICAgICAvLyBJdCdzIHBvc3NpYmxlIHRoYXQgYXBwbHlpbmcgbWVyZ2UgZnVuY3Rpb25zIHRvIHRoaXMgc3VidHJlZSB3aWxsXG4gICAgICAvLyBub3QgY2hhbmdlIHRoZSBpbmNvbWluZyBkYXRhLCBzbyB0aGlzIHZhcmlhYmxlIHRyYWNrcyB0aGUgZmllbGRzXG4gICAgICAvLyB0aGF0IGRpZCBjaGFuZ2UsIHNvIHdlIGNhbiBjcmVhdGUgYSBuZXcgaW5jb21pbmcgb2JqZWN0IHdoZW4gKGFuZFxuICAgICAgLy8gb25seSB3aGVuKSBhdCBsZWFzdCBvbmUgaW5jb21pbmcgZmllbGQgaGFzIGNoYW5nZWQuIFdlIHVzZSBhIE1hcFxuICAgICAgLy8gdG8gcHJlc2VydmUgdGhlIHR5cGUgb2YgbnVtZXJpYyBrZXlzLlxuICAgICAgbGV0IGNoYW5nZWRGaWVsZHM6IE1hcDxzdHJpbmcgfCBudW1iZXIsIFN0b3JlVmFsdWU+IHwgdW5kZWZpbmVkO1xuXG4gICAgICBjb25zdCBnZXRWYWx1ZSA9IChcbiAgICAgICAgZnJvbTogdHlwZW9mIGUgfCB0eXBlb2YgaSxcbiAgICAgICAgbmFtZTogc3RyaW5nIHwgbnVtYmVyXG4gICAgICApOiBTdG9yZVZhbHVlID0+IHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBpc0FycmF5KGZyb20pID9cbiAgICAgICAgICAgIHR5cGVvZiBuYW1lID09PSBcIm51bWJlclwiID9cbiAgICAgICAgICAgICAgZnJvbVtuYW1lXVxuICAgICAgICAgICAgOiB2b2lkIDBcbiAgICAgICAgICA6IGNvbnRleHQuc3RvcmUuZ2V0RmllbGRWYWx1ZShmcm9tLCBTdHJpbmcobmFtZSkpXG4gICAgICAgICk7XG4gICAgICB9O1xuXG4gICAgICBtZXJnZVRyZWUubWFwLmZvckVhY2goKGNoaWxkVHJlZSwgc3RvcmVGaWVsZE5hbWUpID0+IHtcbiAgICAgICAgY29uc3QgZVZhbCA9IGdldFZhbHVlKGUsIHN0b3JlRmllbGROYW1lKTtcbiAgICAgICAgY29uc3QgaVZhbCA9IGdldFZhbHVlKGksIHN0b3JlRmllbGROYW1lKTtcbiAgICAgICAgLy8gSWYgd2UgaGF2ZSBubyBpbmNvbWluZyBkYXRhLCBsZWF2ZSBhbnkgZXhpc3RpbmcgZGF0YSB1bnRvdWNoZWQuXG4gICAgICAgIGlmICh2b2lkIDAgPT09IGlWYWwpIHJldHVybjtcbiAgICAgICAgaWYgKGdldFN0b3JhZ2VBcmdzKSB7XG4gICAgICAgICAgZ2V0U3RvcmFnZUFyZ3MucHVzaChzdG9yZUZpZWxkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYVZhbCA9IHRoaXMuYXBwbHlNZXJnZXMoXG4gICAgICAgICAgY2hpbGRUcmVlLFxuICAgICAgICAgIGVWYWwsXG4gICAgICAgICAgaVZhbCxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIGdldFN0b3JhZ2VBcmdzXG4gICAgICAgICk7XG4gICAgICAgIGlmIChhVmFsICE9PSBpVmFsKSB7XG4gICAgICAgICAgY2hhbmdlZEZpZWxkcyA9IGNoYW5nZWRGaWVsZHMgfHwgbmV3IE1hcCgpO1xuICAgICAgICAgIGNoYW5nZWRGaWVsZHMuc2V0KHN0b3JlRmllbGROYW1lLCBhVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ2V0U3RvcmFnZUFyZ3MpIHtcbiAgICAgICAgICBpbnZhcmlhbnQoZ2V0U3RvcmFnZUFyZ3MucG9wKCkgPT09IHN0b3JlRmllbGROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChjaGFuZ2VkRmllbGRzKSB7XG4gICAgICAgIC8vIFNoYWxsb3cgY2xvbmUgaSBzbyB3ZSBjYW4gYWRkIGNoYW5nZWQgZmllbGRzIHRvIGl0LlxuICAgICAgICBpbmNvbWluZyA9IChpc0FycmF5KGkpID8gaS5zbGljZSgwKSA6IHsgLi4uaSB9KSBhcyBUO1xuICAgICAgICBjaGFuZ2VkRmllbGRzLmZvckVhY2goKHZhbHVlLCBuYW1lKSA9PiB7XG4gICAgICAgICAgKGluY29taW5nIGFzIGFueSlbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1lcmdlVHJlZS5pbmZvKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZS5wb2xpY2llcy5ydW5NZXJnZUZ1bmN0aW9uKFxuICAgICAgICBleGlzdGluZyxcbiAgICAgICAgaW5jb21pbmcsXG4gICAgICAgIG1lcmdlVHJlZS5pbmZvLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICBnZXRTdG9yYWdlQXJncyAmJiBjb250ZXh0LnN0b3JlLmdldFN0b3JhZ2UoLi4uZ2V0U3RvcmFnZUFyZ3MpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBpbmNvbWluZztcbiAgfVxufVxuXG5jb25zdCBlbXB0eU1lcmdlVHJlZVBvb2w6IE1lcmdlVHJlZVtdID0gW107XG5cbmZ1bmN0aW9uIGdldENoaWxkTWVyZ2VUcmVlKFxuICB7IG1hcCB9OiBNZXJnZVRyZWUsXG4gIG5hbWU6IHN0cmluZyB8IG51bWJlclxuKTogTWVyZ2VUcmVlIHtcbiAgaWYgKCFtYXAuaGFzKG5hbWUpKSB7XG4gICAgbWFwLnNldChuYW1lLCBlbXB0eU1lcmdlVHJlZVBvb2wucG9wKCkgfHwgeyBtYXA6IG5ldyBNYXAoKSB9KTtcbiAgfVxuICByZXR1cm4gbWFwLmdldChuYW1lKSE7XG59XG5cbmZ1bmN0aW9uIG1lcmdlTWVyZ2VUcmVlcyhcbiAgbGVmdDogTWVyZ2VUcmVlIHwgdW5kZWZpbmVkLFxuICByaWdodDogTWVyZ2VUcmVlIHwgdW5kZWZpbmVkXG4pOiBNZXJnZVRyZWUge1xuICBpZiAobGVmdCA9PT0gcmlnaHQgfHwgIXJpZ2h0IHx8IG1lcmdlVHJlZUlzRW1wdHkocmlnaHQpKSByZXR1cm4gbGVmdCE7XG4gIGlmICghbGVmdCB8fCBtZXJnZVRyZWVJc0VtcHR5KGxlZnQpKSByZXR1cm4gcmlnaHQ7XG5cbiAgY29uc3QgaW5mbyA9XG4gICAgbGVmdC5pbmZvICYmIHJpZ2h0LmluZm8gP1xuICAgICAge1xuICAgICAgICAuLi5sZWZ0LmluZm8sXG4gICAgICAgIC4uLnJpZ2h0LmluZm8sXG4gICAgICB9XG4gICAgOiBsZWZ0LmluZm8gfHwgcmlnaHQuaW5mbztcblxuICBjb25zdCBuZWVkVG9NZXJnZU1hcHMgPSBsZWZ0Lm1hcC5zaXplICYmIHJpZ2h0Lm1hcC5zaXplO1xuICBjb25zdCBtYXAgPVxuICAgIG5lZWRUb01lcmdlTWFwcyA/IG5ldyBNYXAoKVxuICAgIDogbGVmdC5tYXAuc2l6ZSA/IGxlZnQubWFwXG4gICAgOiByaWdodC5tYXA7XG5cbiAgY29uc3QgbWVyZ2VkID0geyBpbmZvLCBtYXAgfTtcblxuICBpZiAobmVlZFRvTWVyZ2VNYXBzKSB7XG4gICAgY29uc3QgcmVtYWluaW5nUmlnaHRLZXlzID0gbmV3IFNldChyaWdodC5tYXAua2V5cygpKTtcblxuICAgIGxlZnQubWFwLmZvckVhY2goKGxlZnRUcmVlLCBrZXkpID0+IHtcbiAgICAgIG1lcmdlZC5tYXAuc2V0KGtleSwgbWVyZ2VNZXJnZVRyZWVzKGxlZnRUcmVlLCByaWdodC5tYXAuZ2V0KGtleSkpKTtcbiAgICAgIHJlbWFpbmluZ1JpZ2h0S2V5cy5kZWxldGUoa2V5KTtcbiAgICB9KTtcblxuICAgIHJlbWFpbmluZ1JpZ2h0S2V5cy5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIG1lcmdlZC5tYXAuc2V0KFxuICAgICAgICBrZXksXG4gICAgICAgIG1lcmdlTWVyZ2VUcmVlcyhyaWdodC5tYXAuZ2V0KGtleSksIGxlZnQubWFwLmdldChrZXkpKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBtZXJnZWQ7XG59XG5cbmZ1bmN0aW9uIG1lcmdlVHJlZUlzRW1wdHkodHJlZTogTWVyZ2VUcmVlIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiAhdHJlZSB8fCAhKHRyZWUuaW5mbyB8fCB0cmVlLm1hcC5zaXplKTtcbn1cblxuZnVuY3Rpb24gbWF5YmVSZWN5Y2xlQ2hpbGRNZXJnZVRyZWUoeyBtYXAgfTogTWVyZ2VUcmVlLCBuYW1lOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgY29uc3QgY2hpbGRUcmVlID0gbWFwLmdldChuYW1lKTtcbiAgaWYgKGNoaWxkVHJlZSAmJiBtZXJnZVRyZWVJc0VtcHR5KGNoaWxkVHJlZSkpIHtcbiAgICBlbXB0eU1lcmdlVHJlZVBvb2wucHVzaChjaGlsZFRyZWUpO1xuICAgIG1hcC5kZWxldGUobmFtZSk7XG4gIH1cbn1cblxuY29uc3Qgd2FybmluZ3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLy8gTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgdW51c2VkIGluIHByb2R1Y3Rpb24sIGFuZCB0aHVzIHNob3VsZCBiZVxuLy8gcHJ1bmVkIGJ5IGFueSB3ZWxsLWNvbmZpZ3VyZWQgbWluaWZpZXIuXG5mdW5jdGlvbiB3YXJuQWJvdXREYXRhTG9zcyhcbiAgZXhpc3RpbmdSZWY6IFJlZmVyZW5jZSxcbiAgaW5jb21pbmdPYmo6IFN0b3JlT2JqZWN0LFxuICBzdG9yZUZpZWxkTmFtZTogc3RyaW5nLFxuICBzdG9yZTogTm9ybWFsaXplZENhY2hlXG4pIHtcbiAgY29uc3QgZ2V0Q2hpbGQgPSAob2JqT3JSZWY6IFN0b3JlT2JqZWN0IHwgUmVmZXJlbmNlKTogU3RvcmVPYmplY3QgfCBmYWxzZSA9PiB7XG4gICAgY29uc3QgY2hpbGQgPSBzdG9yZS5nZXRGaWVsZFZhbHVlPFN0b3JlT2JqZWN0PihvYmpPclJlZiwgc3RvcmVGaWVsZE5hbWUpO1xuICAgIHJldHVybiB0eXBlb2YgY2hpbGQgPT09IFwib2JqZWN0XCIgJiYgY2hpbGQ7XG4gIH07XG5cbiAgY29uc3QgZXhpc3RpbmcgPSBnZXRDaGlsZChleGlzdGluZ1JlZik7XG4gIGlmICghZXhpc3RpbmcpIHJldHVybjtcblxuICBjb25zdCBpbmNvbWluZyA9IGdldENoaWxkKGluY29taW5nT2JqKTtcbiAgaWYgKCFpbmNvbWluZykgcmV0dXJuO1xuXG4gIC8vIEl0J3MgYWx3YXlzIHNhZmUgdG8gcmVwbGFjZSBhIHJlZmVyZW5jZSwgc2luY2UgaXQgcmVmZXJzIHRvIGRhdGFcbiAgLy8gc2FmZWx5IHN0b3JlZCBlbHNld2hlcmUuXG4gIGlmIChpc1JlZmVyZW5jZShleGlzdGluZykpIHJldHVybjtcblxuICAvLyBJZiB0aGUgdmFsdWVzIGFyZSBzdHJ1Y3R1cmFsbHkgZXF1aXZhbGVudCwgd2UgZG8gbm90IG5lZWQgdG8gd29ycnlcbiAgLy8gYWJvdXQgaW5jb21pbmcgcmVwbGFjaW5nIGV4aXN0aW5nLlxuICBpZiAoZXF1YWwoZXhpc3RpbmcsIGluY29taW5nKSkgcmV0dXJuO1xuXG4gIC8vIElmIHdlJ3JlIHJlcGxhY2luZyBldmVyeSBrZXkgb2YgdGhlIGV4aXN0aW5nIG9iamVjdCwgdGhlbiB0aGVcbiAgLy8gZXhpc3RpbmcgZGF0YSB3b3VsZCBiZSBvdmVyd3JpdHRlbiBldmVuIGlmIHRoZSBvYmplY3RzIHdlcmVcbiAgLy8gbm9ybWFsaXplZCwgc28gd2FybmluZyB3b3VsZCBub3QgYmUgaGVscGZ1bCBoZXJlLlxuICBpZiAoXG4gICAgT2JqZWN0LmtleXMoZXhpc3RpbmcpLmV2ZXJ5KFxuICAgICAgKGtleSkgPT4gc3RvcmUuZ2V0RmllbGRWYWx1ZShpbmNvbWluZywga2V5KSAhPT0gdm9pZCAwXG4gICAgKVxuICApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBwYXJlbnRUeXBlID1cbiAgICBzdG9yZS5nZXRGaWVsZFZhbHVlPHN0cmluZz4oZXhpc3RpbmdSZWYsIFwiX190eXBlbmFtZVwiKSB8fFxuICAgIHN0b3JlLmdldEZpZWxkVmFsdWU8c3RyaW5nPihpbmNvbWluZ09iaiwgXCJfX3R5cGVuYW1lXCIpO1xuICBjb25zdCBmaWVsZE5hbWUgPSBmaWVsZE5hbWVGcm9tU3RvcmVOYW1lKHN0b3JlRmllbGROYW1lKTtcbiAgY29uc3QgdHlwZURvdE5hbWUgPSBgJHtwYXJlbnRUeXBlfS4ke2ZpZWxkTmFtZX1gO1xuICAvLyBBdm9pZCB3YXJuaW5nIG1vcmUgdGhhbiBvbmNlIGZvciB0aGUgc2FtZSB0eXBlIGFuZCBmaWVsZCBuYW1lLlxuICBpZiAod2FybmluZ3MuaGFzKHR5cGVEb3ROYW1lKSkgcmV0dXJuO1xuICB3YXJuaW5ncy5hZGQodHlwZURvdE5hbWUpO1xuXG4gIGNvbnN0IGNoaWxkVHlwZW5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAvLyBBcnJheXMgZG8gbm90IGhhdmUgX190eXBlbmFtZSBmaWVsZHMsIGFuZCBhbHdheXMgbmVlZCBhIGN1c3RvbSBtZXJnZVxuICAvLyBmdW5jdGlvbiwgZXZlbiBpZiB0aGVpciBlbGVtZW50cyBhcmUgbm9ybWFsaXplZCBlbnRpdGllcy5cbiAgaWYgKCFpc0FycmF5KGV4aXN0aW5nKSAmJiAhaXNBcnJheShpbmNvbWluZykpIHtcbiAgICBbZXhpc3RpbmcsIGluY29taW5nXS5mb3JFYWNoKChjaGlsZCkgPT4ge1xuICAgICAgY29uc3QgdHlwZW5hbWUgPSBzdG9yZS5nZXRGaWVsZFZhbHVlKGNoaWxkLCBcIl9fdHlwZW5hbWVcIik7XG4gICAgICBpZiAodHlwZW9mIHR5cGVuYW1lID09PSBcInN0cmluZ1wiICYmICFjaGlsZFR5cGVuYW1lcy5pbmNsdWRlcyh0eXBlbmFtZSkpIHtcbiAgICAgICAgY2hpbGRUeXBlbmFtZXMucHVzaCh0eXBlbmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpbnZhcmlhbnQud2FybihcbiAgICBgQ2FjaGUgZGF0YSBtYXkgYmUgbG9zdCB3aGVuIHJlcGxhY2luZyB0aGUgJXMgZmllbGQgb2YgYSAlcyBvYmplY3QuXG5cblRoaXMgY291bGQgY2F1c2UgYWRkaXRpb25hbCAodXN1YWxseSBhdm9pZGFibGUpIG5ldHdvcmsgcmVxdWVzdHMgdG8gZmV0Y2ggZGF0YSB0aGF0IHdlcmUgb3RoZXJ3aXNlIGNhY2hlZC5cblxuVG8gYWRkcmVzcyB0aGlzIHByb2JsZW0gKHdoaWNoIGlzIG5vdCBhIGJ1ZyBpbiBBcG9sbG8gQ2xpZW50KSwgJXNkZWZpbmUgYSBjdXN0b20gbWVyZ2UgZnVuY3Rpb24gZm9yIHRoZSAlcyBmaWVsZCwgc28gSW5NZW1vcnlDYWNoZSBjYW4gc2FmZWx5IG1lcmdlIHRoZXNlIG9iamVjdHM6XG5cbiAgZXhpc3Rpbmc6ICVvXG4gIGluY29taW5nOiAlb1xuXG5Gb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGVzZSBvcHRpb25zLCBwbGVhc2UgcmVmZXIgdG8gdGhlIGRvY3VtZW50YXRpb246XG5cbiAgKiBFbnN1cmluZyBlbnRpdHkgb2JqZWN0cyBoYXZlIElEczogaHR0cHM6Ly9nby5hcG9sbG8uZGV2L2MvZ2VuZXJhdGluZy11bmlxdWUtaWRlbnRpZmllcnNcbiAgKiBEZWZpbmluZyBjdXN0b20gbWVyZ2UgZnVuY3Rpb25zOiBodHRwczovL2dvLmFwb2xsby5kZXYvYy9tZXJnaW5nLW5vbi1ub3JtYWxpemVkLW9iamVjdHNcbmAsXG4gICAgZmllbGROYW1lLFxuICAgIHBhcmVudFR5cGUsXG4gICAgY2hpbGRUeXBlbmFtZXMubGVuZ3RoID9cbiAgICAgIFwiZWl0aGVyIGVuc3VyZSBhbGwgb2JqZWN0cyBvZiB0eXBlIFwiICtcbiAgICAgICAgY2hpbGRUeXBlbmFtZXMuam9pbihcIiBhbmQgXCIpICtcbiAgICAgICAgXCIgaGF2ZSBhbiBJRCBvciBhIGN1c3RvbSBtZXJnZSBmdW5jdGlvbiwgb3IgXCJcbiAgICA6IFwiXCIsXG4gICAgdHlwZURvdE5hbWUsXG4gICAgeyAuLi5leGlzdGluZyB9LFxuICAgIHsgLi4uaW5jb21pbmcgfVxuICApO1xufVxuIl0sInhfZ29vZ2xlX2lnbm9yZUxpc3QiOlswXX0=