530 lines
90 KiB
Plaintext
530 lines
90 KiB
Plaintext
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= |