import { __assign, __extends, __rest } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29"; import { invariant } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29"; import { dep } from "/_nuxt/node_modules/optimism/lib/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 { isReference, makeReference, DeepMerger, maybeDeepFreeze, canUseWeakMap, isNonNullObject, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29"; import { hasOwn, fieldNameFromStoreName } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/helpers.js?v=e4f18c29"; var DELETE = Object.create(null); var delModifier = function () { return DELETE; }; var INVALIDATE = Object.create(null); var EntityStore = /** @class */ (function () { function EntityStore(policies, group) { var _this = this; this.policies = policies; this.group = group; this.data = Object.create(null); // Maps root entity IDs to the number of times they have been retained, minus // the number of times they have been released. Retained entities keep other // entities they reference (even indirectly) from being garbage collected. this.rootIds = Object.create(null); // Lazily tracks { __ref: } strings contained by this.data[dataId]. this.refs = Object.create(null); // Bound function that can be passed around to provide easy access to fields // of Reference objects as well as ordinary objects. this.getFieldValue = function (objectOrReference, storeFieldName) { return maybeDeepFreeze(isReference(objectOrReference) ? _this.get(objectOrReference.__ref, storeFieldName) : objectOrReference && objectOrReference[storeFieldName]); }; // Returns true for non-normalized StoreObjects and non-dangling // References, indicating that readField(name, objOrRef) has a chance of // working. Useful for filtering out dangling references from lists. this.canRead = function (objOrRef) { return isReference(objOrRef) ? _this.has(objOrRef.__ref) : typeof objOrRef === "object"; }; // Bound function that converts an id or an object with a __typename and // primary key fields to a Reference object. If called with a Reference object, // that same Reference object is returned. Pass true for mergeIntoStore to persist // an object into the store. this.toReference = function (objOrIdOrRef, mergeIntoStore) { if (typeof objOrIdOrRef === "string") { return makeReference(objOrIdOrRef); } if (isReference(objOrIdOrRef)) { return objOrIdOrRef; } var id = _this.policies.identify(objOrIdOrRef)[0]; if (id) { var ref = makeReference(id); if (mergeIntoStore) { _this.merge(id, objOrIdOrRef); } return ref; } }; } // Although the EntityStore class is abstract, it contains concrete // implementations of the various NormalizedCache interface methods that // are inherited by the Root and Layer subclasses. EntityStore.prototype.toObject = function () { return __assign({}, this.data); }; EntityStore.prototype.has = function (dataId) { return this.lookup(dataId, true) !== void 0; }; EntityStore.prototype.get = function (dataId, fieldName) { this.group.depend(dataId, fieldName); if (hasOwn.call(this.data, dataId)) { var storeObject = this.data[dataId]; if (storeObject && hasOwn.call(storeObject, fieldName)) { return storeObject[fieldName]; } } if (fieldName === "__typename" && hasOwn.call(this.policies.rootTypenamesById, dataId)) { return this.policies.rootTypenamesById[dataId]; } if (this instanceof Layer) { return this.parent.get(dataId, fieldName); } }; EntityStore.prototype.lookup = function (dataId, dependOnExistence) { // The has method (above) calls lookup with dependOnExistence = true, so // that it can later be invalidated when we add or remove a StoreObject for // this dataId. Any consumer who cares about the contents of the StoreObject // should not rely on this dependency, since the contents could change // without the object being added or removed. if (dependOnExistence) this.group.depend(dataId, "__exists"); if (hasOwn.call(this.data, dataId)) { return this.data[dataId]; } if (this instanceof Layer) { return this.parent.lookup(dataId, dependOnExistence); } if (this.policies.rootTypenamesById[dataId]) { return Object.create(null); } }; EntityStore.prototype.merge = function (older, newer) { var _this = this; var dataId; // Convert unexpected references to ID strings. if (isReference(older)) older = older.__ref; if (isReference(newer)) newer = newer.__ref; var existing = typeof older === "string" ? this.lookup((dataId = older)) : older; var incoming = typeof newer === "string" ? this.lookup((dataId = newer)) : newer; // If newer was a string ID, but that ID was not defined in this store, // then there are no fields to be merged, so we're done. if (!incoming) return; invariant(typeof dataId === "string", 2); var merged = new DeepMerger(storeObjectReconciler).merge(existing, incoming); // Even if merged === existing, existing may have come from a lower // layer, so we always need to set this.data[dataId] on this level. this.data[dataId] = merged; if (merged !== existing) { delete this.refs[dataId]; if (this.group.caching) { var fieldsToDirty_1 = Object.create(null); // If we added a new StoreObject where there was previously none, dirty // anything that depended on the existence of this dataId, such as the // EntityStore#has method. if (!existing) fieldsToDirty_1.__exists = 1; // Now invalidate dependents who called getFieldValue for any fields // that are changing as a result of this merge. Object.keys(incoming).forEach(function (storeFieldName) { if (!existing || existing[storeFieldName] !== merged[storeFieldName]) { // Always dirty the full storeFieldName, which may include // serialized arguments following the fieldName prefix. fieldsToDirty_1[storeFieldName] = 1; // Also dirty fieldNameFromStoreName(storeFieldName) if it's // different from storeFieldName and this field does not have // keyArgs configured, because that means the cache can't make // any assumptions about how field values with the same field // name but different arguments might be interrelated, so it // must err on the side of invalidating all field values that // share the same short fieldName, regardless of arguments. var fieldName = fieldNameFromStoreName(storeFieldName); if (fieldName !== storeFieldName && !_this.policies.hasKeyArgs(merged.__typename, fieldName)) { fieldsToDirty_1[fieldName] = 1; } // If merged[storeFieldName] has become undefined, and this is the // Root layer, actually delete the property from the merged object, // which is guaranteed to have been created fresh in this method. if (merged[storeFieldName] === void 0 && !(_this instanceof Layer)) { delete merged[storeFieldName]; } } }); if (fieldsToDirty_1.__typename && !(existing && existing.__typename) && // Since we return default root __typename strings // automatically from store.get, we don't need to dirty the // ROOT_QUERY.__typename field if merged.__typename is equal // to the default string (usually "Query"). this.policies.rootTypenamesById[dataId] === merged.__typename) { delete fieldsToDirty_1.__typename; } Object.keys(fieldsToDirty_1).forEach(function (fieldName) { return _this.group.dirty(dataId, fieldName); }); } } }; EntityStore.prototype.modify = function (dataId, fields) { var _this = this; var storeObject = this.lookup(dataId); if (storeObject) { var changedFields_1 = Object.create(null); var needToMerge_1 = false; var allDeleted_1 = true; var sharedDetails_1 = { DELETE: DELETE, INVALIDATE: INVALIDATE, isReference: isReference, toReference: this.toReference, canRead: this.canRead, readField: function (fieldNameOrOptions, from) { return _this.policies.readField(typeof fieldNameOrOptions === "string" ? { fieldName: fieldNameOrOptions, from: from || makeReference(dataId), } : fieldNameOrOptions, { store: _this }); }, }; Object.keys(storeObject).forEach(function (storeFieldName) { var fieldName = fieldNameFromStoreName(storeFieldName); var fieldValue = storeObject[storeFieldName]; if (fieldValue === void 0) return; var modify = typeof fields === "function" ? fields : (fields[storeFieldName] || fields[fieldName]); if (modify) { var newValue = modify === delModifier ? DELETE : (modify(maybeDeepFreeze(fieldValue), __assign(__assign({}, sharedDetails_1), { fieldName: fieldName, storeFieldName: storeFieldName, storage: _this.getStorage(dataId, storeFieldName) }))); if (newValue === INVALIDATE) { _this.group.dirty(dataId, storeFieldName); } else { if (newValue === DELETE) newValue = void 0; if (newValue !== fieldValue) { changedFields_1[storeFieldName] = newValue; needToMerge_1 = true; fieldValue = newValue; if (globalThis.__DEV__ !== false) { var checkReference = function (ref) { if (_this.lookup(ref.__ref) === undefined) { globalThis.__DEV__ !== false && invariant.warn(3, ref); return true; } }; if (isReference(newValue)) { checkReference(newValue); } else if (Array.isArray(newValue)) { // Warn about writing "mixed" arrays of Reference and non-Reference objects var seenReference = false; var someNonReference = void 0; for (var _i = 0, newValue_1 = newValue; _i < newValue_1.length; _i++) { var value = newValue_1[_i]; if (isReference(value)) { seenReference = true; if (checkReference(value)) break; } else { // Do not warn on primitive values, since those could never be represented // by a reference. This is a valid (albeit uncommon) use case. if (typeof value === "object" && !!value) { var id = _this.policies.identify(value)[0]; // check if object could even be referenced, otherwise we are not interested in it for this warning if (id) { someNonReference = value; } } } if (seenReference && someNonReference !== undefined) { globalThis.__DEV__ !== false && invariant.warn(4, someNonReference); break; } } } } } } } if (fieldValue !== void 0) { allDeleted_1 = false; } }); if (needToMerge_1) { this.merge(dataId, changedFields_1); if (allDeleted_1) { if (this instanceof Layer) { this.data[dataId] = void 0; } else { delete this.data[dataId]; } this.group.dirty(dataId, "__exists"); } return true; } } return false; }; // If called with only one argument, removes the entire entity // identified by dataId. If called with a fieldName as well, removes all // fields of that entity whose names match fieldName according to the // fieldNameFromStoreName helper function. If called with a fieldName // and variables, removes all fields of that entity whose names match fieldName // and whose arguments when cached exactly match the variables passed. EntityStore.prototype.delete = function (dataId, fieldName, args) { var _a; var storeObject = this.lookup(dataId); if (storeObject) { var typename = this.getFieldValue(storeObject, "__typename"); var storeFieldName = fieldName && args ? this.policies.getStoreFieldName({ typename: typename, fieldName: fieldName, args: args }) : fieldName; return this.modify(dataId, storeFieldName ? (_a = {}, _a[storeFieldName] = delModifier, _a) : delModifier); } return false; }; EntityStore.prototype.evict = function (options, limit) { var evicted = false; if (options.id) { if (hasOwn.call(this.data, options.id)) { evicted = this.delete(options.id, options.fieldName, options.args); } if (this instanceof Layer && this !== limit) { evicted = this.parent.evict(options, limit) || evicted; } // Always invalidate the field to trigger rereading of watched // queries, even if no cache data was modified by the eviction, // because queries may depend on computed fields with custom read // functions, whose values are not stored in the EntityStore. if (options.fieldName || evicted) { this.group.dirty(options.id, options.fieldName || "__exists"); } } return evicted; }; EntityStore.prototype.clear = function () { this.replace(null); }; EntityStore.prototype.extract = function () { var _this = this; var obj = this.toObject(); var extraRootIds = []; this.getRootIdSet().forEach(function (id) { if (!hasOwn.call(_this.policies.rootTypenamesById, id)) { extraRootIds.push(id); } }); if (extraRootIds.length) { obj.__META = { extraRootIds: extraRootIds.sort() }; } return obj; }; EntityStore.prototype.replace = function (newData) { var _this = this; Object.keys(this.data).forEach(function (dataId) { if (!(newData && hasOwn.call(newData, dataId))) { _this.delete(dataId); } }); if (newData) { var __META = newData.__META, rest_1 = __rest(newData, ["__META"]); Object.keys(rest_1).forEach(function (dataId) { _this.merge(dataId, rest_1[dataId]); }); if (__META) { __META.extraRootIds.forEach(this.retain, this); } } }; EntityStore.prototype.retain = function (rootId) { return (this.rootIds[rootId] = (this.rootIds[rootId] || 0) + 1); }; EntityStore.prototype.release = function (rootId) { if (this.rootIds[rootId] > 0) { var count = --this.rootIds[rootId]; if (!count) delete this.rootIds[rootId]; return count; } return 0; }; // Return a Set of all the ID strings that have been retained by // this layer/root *and* any layers/roots beneath it. EntityStore.prototype.getRootIdSet = function (ids) { if (ids === void 0) { ids = new Set(); } Object.keys(this.rootIds).forEach(ids.add, ids); if (this instanceof Layer) { this.parent.getRootIdSet(ids); } else { // Official singleton IDs like ROOT_QUERY and ROOT_MUTATION are // always considered roots for garbage collection, regardless of // their retainment counts in this.rootIds. Object.keys(this.policies.rootTypenamesById).forEach(ids.add, ids); } return ids; }; // The goal of garbage collection is to remove IDs from the Root layer of the // store that are no longer reachable starting from any IDs that have been // explicitly retained (see retain and release, above). Returns an array of // dataId strings that were removed from the store. EntityStore.prototype.gc = function () { var _this = this; var ids = this.getRootIdSet(); var snapshot = this.toObject(); ids.forEach(function (id) { if (hasOwn.call(snapshot, id)) { // Because we are iterating over an ECMAScript Set, the IDs we add here // will be visited in later iterations of the forEach loop only if they // were not previously contained by the Set. Object.keys(_this.findChildRefIds(id)).forEach(ids.add, ids); // By removing IDs from the snapshot object here, we protect them from // getting removed from the root store layer below. delete snapshot[id]; } }); var idsToRemove = Object.keys(snapshot); if (idsToRemove.length) { var root_1 = this; while (root_1 instanceof Layer) root_1 = root_1.parent; idsToRemove.forEach(function (id) { return root_1.delete(id); }); } return idsToRemove; }; EntityStore.prototype.findChildRefIds = function (dataId) { if (!hasOwn.call(this.refs, dataId)) { var found_1 = (this.refs[dataId] = Object.create(null)); var root = this.data[dataId]; if (!root) return found_1; var workSet_1 = new Set([root]); // Within the store, only arrays and objects can contain child entity // references, so we can prune the traversal using this predicate: workSet_1.forEach(function (obj) { if (isReference(obj)) { found_1[obj.__ref] = true; // In rare cases, a { __ref } Reference object may have other fields. // This often indicates a mismerging of References with StoreObjects, // but garbage collection should not be fooled by a stray __ref // property in a StoreObject (ignoring all the other fields just // because the StoreObject looks like a Reference). To avoid this // premature termination of findChildRefIds recursion, we fall through // to the code below, which will handle any other properties of obj. } if (isNonNullObject(obj)) { Object.keys(obj).forEach(function (key) { var child = obj[key]; // No need to add primitive values to the workSet, since they cannot // contain reference objects. if (isNonNullObject(child)) { workSet_1.add(child); } }); } }); } return this.refs[dataId]; }; EntityStore.prototype.makeCacheKey = function () { return this.group.keyMaker.lookupArray(arguments); }; return EntityStore; }()); export { EntityStore }; // A single CacheGroup represents a set of one or more EntityStore objects, // typically the Root store in a CacheGroup by itself, and all active Layer // stores in a group together. A single EntityStore object belongs to only // one CacheGroup, store.group. The CacheGroup is responsible for tracking // dependencies, so store.group is helpful for generating unique keys for // cached results that need to be invalidated when/if those dependencies // change. If we used the EntityStore objects themselves as cache keys (that // is, store rather than store.group), the cache would become unnecessarily // fragmented by all the different Layer objects. Instead, the CacheGroup // approach allows all optimistic Layer objects in the same linked list to // belong to one CacheGroup, with the non-optimistic Root object belonging // to another CacheGroup, allowing resultCaching dependencies to be tracked // separately for optimistic and non-optimistic entity data. var CacheGroup = /** @class */ (function () { function CacheGroup(caching, parent) { if (parent === void 0) { parent = null; } this.caching = caching; this.parent = parent; this.d = null; this.resetCaching(); } CacheGroup.prototype.resetCaching = function () { this.d = this.caching ? dep() : null; this.keyMaker = new Trie(canUseWeakMap); }; CacheGroup.prototype.depend = function (dataId, storeFieldName) { if (this.d) { this.d(makeDepKey(dataId, storeFieldName)); var fieldName = fieldNameFromStoreName(storeFieldName); if (fieldName !== storeFieldName) { // Fields with arguments that contribute extra identifying // information to the fieldName (thus forming the storeFieldName) // depend not only on the full storeFieldName but also on the // short fieldName, so the field can be invalidated using either // level of specificity. this.d(makeDepKey(dataId, fieldName)); } if (this.parent) { this.parent.depend(dataId, storeFieldName); } } }; CacheGroup.prototype.dirty = function (dataId, storeFieldName) { if (this.d) { this.d.dirty(makeDepKey(dataId, storeFieldName), // When storeFieldName === "__exists", that means the entity identified // by dataId has either disappeared from the cache or was newly added, // so the result caching system would do well to "forget everything it // knows" about that object. To achieve that kind of invalidation, we // not only dirty the associated result cache entry, but also remove it // completely from the dependency graph. For the optimism implementation // details, see https://github.com/benjamn/optimism/pull/195. storeFieldName === "__exists" ? "forget" : "setDirty"); } }; return CacheGroup; }()); function makeDepKey(dataId, storeFieldName) { // Since field names cannot have '#' characters in them, this method // of joining the field name and the ID should be unambiguous, and much // cheaper than JSON.stringify([dataId, fieldName]). return storeFieldName + "#" + dataId; } export function maybeDependOnExistenceOfEntity(store, entityId) { if (supportsResultCaching(store)) { // We use this pseudo-field __exists elsewhere in the EntityStore code to // represent changes in the existence of the entity object identified by // entityId. This dependency gets reliably dirtied whenever an object with // this ID is deleted (or newly created) within this group, so any result // cache entries (for example, StoreReader#executeSelectionSet results) that // depend on __exists for this entityId will get dirtied as well, leading to // the eventual recomputation (instead of reuse) of those result objects the // next time someone reads them from the cache. store.group.depend(entityId, "__exists"); } } (function (EntityStore) { // Refer to this class as EntityStore.Root outside this namespace. var Root = /** @class */ (function (_super) { __extends(Root, _super); function Root(_a) { var policies = _a.policies, _b = _a.resultCaching, resultCaching = _b === void 0 ? true : _b, seed = _a.seed; var _this = _super.call(this, policies, new CacheGroup(resultCaching)) || this; _this.stump = new Stump(_this); _this.storageTrie = new Trie(canUseWeakMap); if (seed) _this.replace(seed); return _this; } Root.prototype.addLayer = function (layerId, replay) { // Adding an optimistic Layer on top of the Root actually adds the Layer // on top of the Stump, so the Stump always comes between the Root and // any Layer objects that we've added. return this.stump.addLayer(layerId, replay); }; Root.prototype.removeLayer = function () { // Never remove the root layer. return this; }; Root.prototype.getStorage = function () { return this.storageTrie.lookupArray(arguments); }; return Root; }(EntityStore)); EntityStore.Root = Root; })(EntityStore || (EntityStore = {})); // Not exported, since all Layer instances are created by the addLayer method // of the EntityStore.Root class. var Layer = /** @class */ (function (_super) { __extends(Layer, _super); function Layer(id, parent, replay, group) { var _this = _super.call(this, parent.policies, group) || this; _this.id = id; _this.parent = parent; _this.replay = replay; _this.group = group; replay(_this); return _this; } Layer.prototype.addLayer = function (layerId, replay) { return new Layer(layerId, this, replay, this.group); }; Layer.prototype.removeLayer = function (layerId) { var _this = this; // Remove all instances of the given id, not just the first one. var parent = this.parent.removeLayer(layerId); if (layerId === this.id) { if (this.group.caching) { // Dirty every ID we're removing. Technically we might be able to avoid // dirtying fields that have values in higher layers, but we don't have // easy access to higher layers here, and we're about to recreate those // layers anyway (see parent.addLayer below). Object.keys(this.data).forEach(function (dataId) { var ownStoreObject = _this.data[dataId]; var parentStoreObject = parent["lookup"](dataId); if (!parentStoreObject) { // The StoreObject identified by dataId was defined in this layer // but will be undefined in the parent layer, so we can delete the // whole entity using this.delete(dataId). Since we're about to // throw this layer away, the only goal of this deletion is to dirty // the removed fields. _this.delete(dataId); } else if (!ownStoreObject) { // This layer had an entry for dataId but it was undefined, which // means the entity was deleted in this layer, and it's about to // become undeleted when we remove this layer, so we need to dirty // all fields that are about to be reexposed. _this.group.dirty(dataId, "__exists"); Object.keys(parentStoreObject).forEach(function (storeFieldName) { _this.group.dirty(dataId, storeFieldName); }); } else if (ownStoreObject !== parentStoreObject) { // If ownStoreObject is not exactly the same as parentStoreObject, // dirty any fields whose values will change as a result of this // removal. Object.keys(ownStoreObject).forEach(function (storeFieldName) { if (!equal(ownStoreObject[storeFieldName], parentStoreObject[storeFieldName])) { _this.group.dirty(dataId, storeFieldName); } }); } }); } return parent; } // No changes are necessary if the parent chain remains identical. if (parent === this.parent) return this; // Recreate this layer on top of the new parent. return parent.addLayer(this.id, this.replay); }; Layer.prototype.toObject = function () { return __assign(__assign({}, this.parent.toObject()), this.data); }; Layer.prototype.findChildRefIds = function (dataId) { var fromParent = this.parent.findChildRefIds(dataId); return hasOwn.call(this.data, dataId) ? __assign(__assign({}, fromParent), _super.prototype.findChildRefIds.call(this, dataId)) : fromParent; }; Layer.prototype.getStorage = function () { var p = this.parent; while (p.parent) p = p.parent; return p.getStorage.apply(p, // @ts-expect-error arguments); }; return Layer; }(EntityStore)); // Represents a Layer permanently installed just above the Root, which allows // reading optimistically (and registering optimistic dependencies) even when // no optimistic layers are currently active. The stump.group CacheGroup object // is shared by any/all Layer objects added on top of the Stump. var Stump = /** @class */ (function (_super) { __extends(Stump, _super); function Stump(root) { return _super.call(this, "EntityStore.Stump", root, function () { }, new CacheGroup(root.group.caching, root.group)) || this; } Stump.prototype.removeLayer = function () { // Never remove the Stump layer. return this; }; Stump.prototype.merge = function (older, newer) { // We never want to write any data into the Stump, so we forward any merge // calls to the Root instead. Another option here would be to throw an // exception, but the toReference(object, true) function can sometimes // trigger Stump writes (which used to be Root writes, before the Stump // concept was introduced). return this.parent.merge(older, newer); }; return Stump; }(Layer)); function storeObjectReconciler(existingObject, incomingObject, property) { var existingValue = existingObject[property]; var incomingValue = incomingObject[property]; // Wherever there is a key collision, prefer the incoming value, unless // it is deeply equal to the existing value. It's worth checking deep // equality here (even though blindly returning incoming would be // logically correct) because preserving the referential identity of // existing data can prevent needless rereading and rerendering. return equal(existingValue, incomingValue) ? existingValue : incomingValue; } export function supportsResultCaching(store) { // When result caching is disabled, store.depend will be null. return !!(store instanceof EntityStore && store.group.caching); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5U3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FjaGUvaW5tZW1vcnkvZW50aXR5U3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUU3RCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQU9qQyxPQUFPLEVBQ0wsV0FBVyxFQUNYLGFBQWEsRUFDYixVQUFVLEVBQ1YsZUFBZSxFQUNmLGFBQWEsRUFDYixlQUFlLEdBQ2hCLE1BQU0sMEJBQTBCLENBQUM7QUFFbEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQWdCOUQsSUFBTSxNQUFNLEdBQW1CLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkQsSUFBTSxXQUFXLEdBQWtCLGNBQU0sT0FBQSxNQUFNLEVBQU4sQ0FBTSxDQUFDO0FBQ2hELElBQU0sVUFBVSxHQUF1QixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRTNEO0lBR0UscUJBQ2tCLFFBQWtCLEVBQ2xCLEtBQWlCO1FBRm5DLGlCQUdJO1FBRmMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixVQUFLLEdBQUwsS0FBSyxDQUFZO1FBSnpCLFNBQUksR0FBMEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQTZYNUQsNkVBQTZFO1FBQzdFLDRFQUE0RTtRQUM1RSwwRUFBMEU7UUFDbEUsWUFBTyxHQUVYLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUF5RHhCLDRFQUE0RTtRQUNwRSxTQUFJLEdBRVIsTUFBTSxDQUFDLE1BQU0s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QixjQUEyQixFQUMzQixRQUF5QjtJQUV6QixJQUFNLGFBQWEsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0MsSUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9DLHVFQUF1RTtJQUN2RSxxRUFBcUU7SUFDckUsaUVBQWlFO0lBQ2pFLG9FQUFvRTtJQUNwRSxnRUFBZ0U7SUFDaEUsT0FBTyxLQUFLLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQztBQUM3RSxDQUFDO0FBRUQsTUFBTSxVQUFVLHFCQUFxQixDQUFDLEtBQVU7SUFDOUMsOERBQThEO0lBQzlELE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxZQUFZLFdBQVcsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2pFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbnZhcmlhbnQgfSBmcm9tIFwiLi4vLi4vdXRpbGl0aWVzL2dsb2JhbHMvaW5kZXguanNcIjtcbmltcG9ydCB0eXBlIHsgT3B0aW1pc3RpY0RlcGVuZGVuY3lGdW5jdGlvbiB9IGZyb20gXCJvcHRpbWlzbVwiO1xuaW1wb3J0IHsgZGVwIH0gZnJvbSBcIm9wdGltaXNtXCI7XG5pbXBvcnQgeyBlcXVhbCB9IGZyb20gXCJAd3J5L2VxdWFsaXR5XCI7XG5pbXBvcnQgeyBUcmllIH0gZnJvbSBcIkB3cnkvdHJpZVwiO1xuXG5pbXBvcnQgdHlwZSB7XG4gIFN0b3JlVmFsdWUsXG4gIFN0b3JlT2JqZWN0LFxuICBSZWZlcmVuY2UsXG59IGZyb20gXCIuLi8uLi91dGlsaXRpZXMvaW5kZXguanNcIjtcbmltcG9ydCB7XG4gIGlzUmVmZXJlbmNlLFxuICBtYWtlUmVmZXJlbmNlLFxuICBEZWVwTWVyZ2VyLFxuICBtYXliZURlZXBGcmVlemUsXG4gIGNhblVzZVdlYWtNYXAsXG4gIGlzTm9uTnVsbE9iamVjdCxcbn0gZnJvbSBcIi4uLy4uL3V0aWxpdGllcy9pbmRleC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBOb3JtYWxpemVkQ2FjaGUsIE5vcm1hbGl6ZWRDYWNoZU9iamVjdCB9IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5pbXBvcnQgeyBoYXNPd24sIGZpZWxkTmFtZUZyb21TdG9yZU5hbWUgfSBmcm9tIFwiLi9oZWxwZXJzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFBvbGljaWVzLCBTdG9yYWdlVHlwZSB9IGZyb20gXCIuL3BvbGljaWVzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENhY2hlIH0gZnJvbSBcIi4uL2NvcmUvdHlwZXMvQ2FjaGUuanNcIjtcbmltcG9ydCB0eXBlIHtcbiAgU2FmZVJlYWRvbmx5LFxuICBNb2RpZmllcixcbiAgTW9kaWZpZXJzLFxuICBSZWFkRmllbGRPcHRpb25zLFxuICBUb1JlZmVyZW5jZUZ1bmN0aW9uLFxuICBDYW5SZWFkRnVuY3Rpb24sXG4gIEludmFsaWRhdGVNb2RpZmllcixcbiAgRGVsZXRlTW9kaWZpZXIsXG4gIE1vZGlmaWVyRGV0YWlscyxcbn0gZnJvbSBcIi4uL2NvcmUvdHlwZXMvY29tbW9uLmpzXCI7XG5pbXBvcnQgdHlwZSB7IERvY3VtZW50Tm9kZSwgRmllbGROb2RlLCBTZWxlY3Rpb25TZXROb2RlIH0gZnJvbSBcImdyYXBocWxcIjtcblxuY29uc3QgREVMRVRFOiBEZWxldGVNb2RpZmllciA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5jb25zdCBkZWxNb2RpZmllcjogTW9kaWZpZXI8YW55PiA9ICgpID0+IERFTEVURTtcbmNvbnN0IElOVkFMSURBVEU6IEludmFsaWRhdGVNb2RpZmllciA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFbnRpdHlTdG9yZSBpbXBsZW1lbnRzIE5vcm1hbGl6ZWRDYWNoZSB7XG4gIHByb3RlY3RlZCBkYXRhOiBOb3JtYWxpemVkQ2FjaGVPYmplY3QgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBwb2xpY2llczogUG9saWNpZXMsXG4gICAgcHVibGljIHJlYWRvbmx5IGdyb3VwOiBDYWNoZUdyb3VwXG4gICkge31cblxuICBwdWJsaWMgYWJzdHJhY3QgYWRkTGF5ZXIoXG4gICAgbGF5ZXJJZDogc3RyaW5nLFxuICAgIHJlcGxheTogKGxheWVyOiBFbnRpdHlTdG9yZSkgPT4gYW55XG4gICk6IExheWVyO1xuXG4gIHB1YmxpYyBhYnN0cmFjdCByZW1vdmVMYXllcihsYXllcklkOiBzdHJpbmcpOiBFbnRpdHlTdG9yZTtcblxuICAvLyBBbHRob3VnaCB0aGUgRW50aXR5U3RvcmUgY2xhc3MgaXMgYWJzdHJhY3QsIGl0IGNvbnRhaW5zIGNvbmNyZXRlXG4gIC8vIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgdmFyaW91cyBOb3JtYWxpemVkQ2FjaGUgaW50ZXJmYWNlIG1ldGhvZHMgdGhhdFxuICAvLyBhcmUgaW5oZXJpdGVkIGJ5IHRoZSBSb290IGFuZCBMYXllciBzdWJjbGFzc2VzLlxuXG4gIHB1YmxpYyB0b09iamVjdCgpOiBOb3JtYWxpemVkQ2FjaGVPYmplY3Qge1xuICAgIHJldHVybiB7IC4uLnRoaXMuZGF0YSB9O1xuICB9XG5cbiAgcHVibGljIGhhcyhkYXRhSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmxvb2t1cChkYXRhSWQsIHRydWUpICE9PSB2b2lkIDA7XG4gIH1cblxuICBwdWJsaWMgZ2V0KGRhdGFJZDogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZyk6IFN0b3JlVmFsdWUge1xuICAgIHRoaXMuZ3JvdXAuZGVwZW5kKGRhdGFJZCwgZmllbGROYW1lKTtcbiAgICBpZiAoaGFzT3duLmNhbGwodGhpcy5kYXRhLCBkYXRhSWQpKSB7XG4gICAgICBjb25zdCBzdG9yZU9iamVjdCA9IHRoaXMuZGF0YVtkYXRhSWRdO1xuICAgICAgaWYgKHN0b3JlT2JqZWN0ICYmIGhhc093bi5jYWxsKHN0b3JlT2JqZWN0LCBmaWVsZE5hbWUpKSB7XG4gICAgICAgIHJldHVybiBzdG9yZU9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoXG4gICAgICBmaWVsZE5hbWUgPT09IFwiX190eXBlbmFtZVwiICYmXG4gICAgICBoYXNPd24uY2FsbCh0aGlzLnBvbGljaWVzLnJvb3RUeXBlbmFtZXNCeUlkLCBkYXRhSWQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb2xpY2llcy5yb290VHlwZW5hbWVzQnlJZFtkYXRhSWRdO1xuICAgIH1cbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIExheWVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJlbnQuZ2V0KGRhdGFJZCwgZmllbGROYW1lKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgbG9va3VwKFxuICAgIGRhdGFJZDogc3RyaW5nLFxuICAgIGRlcGVuZE9uRXhpc3RlbmNlPzogYm9vbGVhblxuICApOiBTdG9yZU9iamVjdCB8IHVuZGVmaW5lZCB7XG4gICAgLy8gVGhlIGhhcyBtZXRob2QgKGFib3ZlKSBjYWxscyBsb29rdXAgd2l0aCBkZXBlbmRPbkV4aXN0ZW5jZSA9IHRydWUsIHNvXG4gICAgLy8gdGhhdCBpdCBjYW4gbGF0ZXIgYmUgaW52YWxpZGF0ZWQgd2hlbiB3ZSBhZGQgb3IgcmVtb3ZlIGEgU3RvcmVPYmplY3QgZm9yXG4gICAgLy8gdGhpcyBkYXRhSWQuIEFueSBjb25zdW1lciB3aG8gY2FyZXMgYWJvdXQgdGhlIGNvbnRlbnRzIG9mIHRoZSBTdG9yZU9iamVjdFxuICAgIC8vIHNob3VsZCBub3QgcmVseSBvbiB0aGlzIGRlcGVuZGVuY3ksIHNpbmNlIHRoZSBjb250ZW50cyBjb3VsZCBjaGFuZ2VcbiAgICAvLyB3aXRob3V0IHRoZSBvYmplY3QgYmVpbmcgYWRkZWQgb3IgcmVtb3ZlZC5cbiAgICBpZiAoZGVwZW5kT25FeGlzdGVuY2UpIHRoaXMuZ3JvdXAuZGVwZW5kKGRhdGFJZCwgXCJfX2V4aXN0c1wiKTtcblxuICAgIGlmIChoYXNPd24uY2FsbCh0aGlzLmRhdGEsIGRhdGFJZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmRhdGFbZGF0YUlkXTtcbiAgICB9XG5cbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIExheWVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJlbnQubG9va3VwKGRhdGFJZCwgZGVwZW5kT25FeGlzdGVuY2UpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnBvbGljaWVzLnJvb3RUeXBlbmFtZXNCeUlkW2RhdGFJZF0pIHtcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBtZXJnZShvbGRlcjogc3RyaW5nIHwgU3RvcmVPYmplY3QsIG5ld2VyOiBTdG9yZU9iamVjdCB8IHN0cmluZyk6IHZvaWQge1xuICAgIGxldCBkYXRhSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8vIENvbnZlcnQgdW5leHBlY3RlZCByZWZlcmVuY2VzIHRvIElEIHN0cmluZ3MuXG4gICAgaWYgKGlzUmVmZXJlbmNlKG9sZGVyKSkgb2xkZXIgPSBvbGRlci5fX3JlZjtcbiAgICBpZiAoaXNSZWZlcmVuY2UobmV3ZXIpKSBuZXdlciA9IG5ld2VyLl9fcmVmO1xuXG4gICAgY29uc3QgZXhpc3Rpbmc6IFN0b3JlT2JqZWN0IHwgdW5kZWZpbmVkID1cbiAgICAgIHR5cGVvZiBvbGRlciA9PT0gXCJzdHJpbmdcIiA/IHRoaXMubG9va3VwKChkYXRhSWQgPSBvbGRlcikpIDogb2xkZXI7XG5cbiAgICBjb25zdCBpbmNvbWluZzogU3RvcmVPYmplY3QgfCB1bmRlZmluZWQgPVxuICAgICAgdHlwZW9mIG5ld2VyID09PSBcInN0cmluZ1wiID8gdGhpcy5sb29rdXAoKGRhdGFJZCA9IG5ld2VyKSkgOiBuZXdlcjtcblxuICAgIC8vIElmIG5ld2VyIHdhcyBhIHN0cmluZyBJRCwgYnV0IHRoYXQgSUQgd2FzIG5vdCBkZWZpbmVkIGluIHRoaXMgc3RvcmUsXG4gICAgLy8gdGhlbiB0aGVyZSBhcmUgbm8gZmllbGRzIHRvIGJlIG1lcmdlZCwgc28gd2UncmUgZG9uZS5cbiAgICBpZiAoIWluY29taW5nKSByZXR1cm47XG5cbiAgICBpbnZhcmlhbnQodHlwZW9mIGRhdGFJZCA9PT0gXCJzdHJpbmdcIiwgXCJzdG9yZS5tZXJnZSBleHBlY3RzIGEgc3RyaW5nIElEXCIpO1xuXG4gICAgY29uc3QgbWVyZ2VkOiBTdG9yZU9iamVjdCA9IG5ldyBEZWVwTWVyZ2VyKHN0b3JlT2JqZWN0UmVjb25jaWxlcikubWVyZ2UoXG4gICAgICBleGlzdGluZyxcbiAgICAgIGluY29taW5nXG4gICAgKTtcblxuICAgIC8vIEV2ZW4gaWYgbWVyZ2VkID09PSBleGlzdGluZywgZXhpc3RpbmcgbWF5IGhhdmUgY29tZSBmcm9tIGEgbG93ZXJcbiAgICAvLyBsYXllciwgc28gd2UgYWx3YXlzIG5lZWQgdG8gc2V0IHRoaXMuZGF0YVtkYXRhSWRdIG9uIHRoaXMgbGV2ZWwuXG4gICAgdGhpcy5kYXRhW2RhdGFJZF0gPSBtZXJnZWQ7XG5cbiAgICBpZiAobWVyZ2VkICE9PSBleGlzdGluZykge1xuICAgICAgZGVsZXRlIHRoaXMucmVmc1tkYXRhSWRdO1xuICAgICAgaWYgKHRoaXMuZ3JvdXAuY2FjaGluZykge1xuICAgICAgICBjb25zdCBmaWVsZHNUb0RpcnR5OiBSZWNvcmQ8c3RyaW5nLCAxPiA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICAgICAgLy8gSWYgd2UgYWRkZWQgYSBuZXcgU3RvcmVPYmplY3Qgd2hlcmUgdGhlcmUgd2FzIHByZXZpb3VzbHkgbm9uZSwgZGlydHlcbiAgICAgICAgLy8gYW55dGhpbmcgdGhhdCBkZXBlbmRlZCBvbiB0aGUgZXhpc3RlbmNlIG9mIHRoaXMgZGF0YUlkLCBzdWNoIGFzIHRoZVxuICAgICAgICAvLyBFbnRpdHlTdG9yZSNoYXMgbWV0aG9kLlxuICAgICAgICBpZiAoIWV4aXN0aW5nKSBmaWVsZHNUb0RpcnR5Ll9fZXhpc3RzID0gMTtcblxuICAgICAgICAvLyBOb3cgaW52YWxpZGF0ZSBkZXBlbmRlbnRzIHdobyBjYWxsZWQgZ2V0RmllbGRWYWx1ZSBmb3IgYW55IGZpZWxkc1xuICAgICAgICAvLyB0aGF0IGFyZSBjaGFuZ2luZyBhcyBhIHJlc3VsdCBvZiB0aGlzIG1lcmdlLlxuICAgICAgICBPYmplY3Qua2V5cyhpbmNvbWluZykuZm9yRWFjaCgoc3RvcmVGaWVsZE5hbWUpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhZXhpc3RpbmcgfHxcbiAgICAgICAgICAgIGV4aXN0aW5nW3N0b3JlRmllbGROYW1lXSAhPT0gbWVyZ2VkW3N0b3JlRmllbGROYW1lXVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gQWx3YXlzIGRpcnR5IHRoZSBmdWxsIHN0b3JlRmllbGROYW1lLCB3aGljaCBtYXkgaW5jbHVkZVxuICAgICAgICAgICAgLy8gc2VyaWFsaXplZCBhcmd1bWVudHMgZm9sbG93aW5nIHRoZSBmaWVsZE5hbWUgcHJlZml4LlxuICAgICAgICAgICAgZmllbGRzVG9EaXJ0eVtzdG9yZUZpZWxkTmFtZV0gPSAxO1xuXG4gICAgICAgICAgICAvLyBBbHNvIGRpcnR5IGZpZWxkTmFtZUZyb21TdG9yZU5hbWUoc3RvcmVGaWVsZE5hbWUpIGlmIGl0J3NcbiAgICAgICAgICAgIC8vIGRpZmZlcmVudCBmcm9tIHN0b3JlRmllbGROYW1lIGFuZCB0aGlzIGZpZWxkIGRvZXMgbm90IGhhdmVcbiAgICAgICAgICAgIC8vIGtleUFyZ3MgY29uZmlndXJlZCwgYmVjYXVzZSB0aGF0IG1lYW5zIHRoZSBjYWNoZSBjYW4ndCBtYWtlXG4gICAgICAgICAgICAvLyBhbnkgYXNzdW1wdGlvbnMgYWJvdXQgaG93IGZpZWxkIHZhbHVlcyB3aXRoIHRoZSBzYW1lIGZpZWxkXG4gICAgICAgICAgICAvLyBuYW1lIGJ1dCBkaWZmZXJlbnQgYXJndW1lbnRzIG1pZ2h0IGJlIGludGVycmVsYXRlZCwgc28gaXRcbiAgICAgICAgICAgIC8vIG11c3QgZXJyIG9uIHRoZSBzaWRlIG9mIGludmFsaWRhdGluZyBhbGwgZmllbGQgdmFsdWVzIHRoYXRcbiAgICAgICAgICAgIC8vIHNoYXJlIHRoZSBzYW1lIHNob3J0IGZpZWxkTmFtZSwgcmVnYXJkbGVzcyBvZiBhcmd1bWVudHMuXG4gICAgICAgICAgICBjb25zdCBmaWVsZE5hbWUgPSBmaWVsZE5hbWVGcm9tU3RvcmVOYW1lKHN0b3JlRmllbGROYW1lKTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgZmllbGROYW1lICE9PSBzdG9yZUZpZWxkTmFtZSAmJlxuICAgICAgICAgICAgICAhdGhpcy5wb2xpY2llcy5oYXNLZXlBcmdzKG1lcmdlZC5fX3R5cGVuYW1lLCBmaWVsZE5hbWUpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgZmllbGRzVG9EaXJ0eVtmaWVsZE5hbWVdID0gMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbWVyZ2VkW3N0b3JlRmllbGROYW1lXSBoYXMgYmVjb21lIHVuZGVmaW5lZCwgYW5kIHRoaXMgaXMgdGhlXG4gICAgICAgICAgICAvLyBSb290IGxheWVyLCBhY3R1YWxseSBkZWxldGUgdGhlIHByb3BlcnR5IGZyb20gdGhlIG1lcmdlZCBvYmplY3QsXG4gICAgICAgICAgICAvLyB3aGljaCBpcyBndWFyYW50ZWVkIHRvIGhhdmUgYmVlbiBjcmVhdGVkIGZyZXNoIGluIHRoaXMgbWV0aG9kLlxuICAgICAgICAgICAgaWYgKG1lcmdlZFtzdG9yZUZpZWxkTmFtZV0gPT09IHZvaWQgMCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBMYXllcikpIHtcbiAgICAgICAgICAgICAgZGVsZXRlIG1lcmdlZFtzdG9yZUZpZWxkTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZmllbGRzVG9EaXJ0eS5fX3R5cGVuYW1lICYmXG4gICAgICAgICAgIShleGlzdGluZyAmJiBleGlzdGluZy5fX3R5cGVuYW1lKSAmJlxuICAgICAgICAgIC8vIFNpbmNlIHdlIHJldHVybiBkZWZhdWx0IHJvb3QgX190eXBlbmFtZSBzdHJpbmdzXG4gICAgICAgICAgLy8gYXV0b21hdGljYWxseSBmcm9tIHN0b3JlLmdldCwgd2UgZG9uJ3QgbmVlZCB0byBkaXJ0eSB0aGVcbiAgICAgICAgICAvLyBST09UX1FVRVJZLl9fdHlwZW5hbWUgZmllbGQgaWYgbWVyZ2VkLl9fdHlwZW5hbWUgaXMgZXF1YWxcbiAgICAgICAgICAvLyB0byB0aGUgZGVmYXVsdCBzdHJpbmcgKHVzdWFsbHkgXCJRdWVyeVwiKS5cbiAgICAgICAgICB0aGlzLnBvbGljaWVzLnJvb3RUeXBlbmFtZXNCeUlkW2RhdGFJZF0gPT09IG1lcmdlZC5fX3R5cGVuYW1lXG4gICAgICAgICkge1xuICAgICAgICAgIGRlbGV0ZSBmaWVsZHNUb0RpcnR5Ll9fdHlwZW5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3Qua2V5cyhmaWVsZHNUb0RpcnR5KS5mb3JFYWNoKChmaWVsZE5hbWUpID0+XG4gICAgICAgICAgdGhpcy5ncm91cC5kaXJ0eShkYXRhSWQgYXMgc3RyaW5nLCBmaWVsZE5hbWUpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG1vZGlmeShcbiAgICBkYXRhSWQ6IHN0cmluZyxcbiAgICBmaWVsZHM6IE1vZGlmaWVyPGFueT4gfCBNb2RpZmllcnM8UmVjb3JkPHN0cmluZywgYW55Pj5cbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc3RvcmVPYmplY3QgPSB0aGlzLmxvb2t1cChkYXRhSWQpO1xuXG4gICAgaWYgKHN0b3JlT2JqZWN0KSB7XG4gICAgICBjb25zdCBjaGFuZ2VkRmllbGRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIGxldCBuZWVkVG9NZXJnZSA9IGZhbHNlO1xuICAgICAgbGV0IGFsbERlbGV0ZWQgPSB0cnVlO1xuXG4gICAgICBjb25zdCBzaGFyZWREZXRhaWxzID0ge1xuICAgICAgICBERUxFVEUsXG4gICAgICAgIElOVkFMSURBVEUsXG4gICAgICAgIGlzUmVmZXJlbmNlLFxuICAgICAgICB0b1JlZmVyZW5jZTogdGhpcy50b1JlZmVyZW5jZSxcbiAgICAgICAgY2FuUmVhZDogdGhpcy5jYW5SZWFkLFxuICAgICAgICByZWFkRmllbGQ6IDxWID0gU3RvcmVWYWx1ZT4oXG4gICAgICAgICAgZmllbGROYW1lT3JPcHRpb25zOiBzdHJpbmcgfCBSZWFkRmllbGRPcHRpb25zLFxuICAgICAgICAgIGZyb20/OiBTdG9yZU9iamVjdCB8IFJlZmVyZW5jZVxuICAgICAgICApID0+XG4gICAgICAgICAgdGhpcy5wb2xpY2llcy5yZWFkRmllbGQ8Vj4oXG4gICAgICAgICAgICB0eXBlb2YgZmllbGROYW1lT3JPcHRpb25zID09PSBcInN0cmluZ1wiID9cbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZpZWxkTmFtZTogZmllbGROYW1lT3JPcHRpb25zLFxuICAgICAgICAgICAgICAgIGZyb206IGZyb20gfHwgbWFrZVJlZmVyZW5jZShkYXRhSWQpLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IGZpZWxkTmFtZU9yT3B0aW9ucyxcbiAgICAgICAgICAgIHsgc3RvcmU6IHRoaXMgfVxuICAgICAgICAgICksXG4gICAgICB9IHNhdGlzZmllcyBQYXJ0aWFsPE1vZGlmaWVyRGV0YWlscz47XG5cbiAgICAgIE9iamVjdC5rZXlzKHN0b3JlT2JqZWN0KS5mb3JFYWNoKChzdG9yZUZpZWxkTmFtZSkgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZE5hbWUgPSBmaWVsZE5hbWVGcm9tU3RvcmVOYW1lKHN0b3JlRmllbGROYW1lKTtcbiAgICAgICAgbGV0IGZpZWxkVmFsdWUgPSBzdG9yZU9iamVjdFtzdG9yZUZpZWxkTmFtZV07XG4gICAgICAgIGlmIChmaWVsZFZhbHVlID09PSB2b2lkIDApIHJldHVybjtcbiAgICAgICAgY29uc3QgbW9kaWZ5OiBNb2RpZmllcjxTdG9yZVZhbHVlPiB8IHVuZGVmaW5lZCA9XG4gICAgICAgICAgdHlwZW9mIGZpZWxkcyA9PT0gXCJmdW5jdGlvblwiID8gZmllbGRzIDogKFxuICAgICAgICAgICAgZmllbGRzW3N0b3JlRmllbGROYW1lXSB8fCBmaWVsZHNbZmllbGROYW1lXVxuICAgICAgICAgICk7XG4gICAgICAgIGlmIChtb2RpZnkpIHtcbiAgICAgICAgICBsZXQgbmV3VmFsdWUgPVxuICAgICAgICAgICAgbW9kaWZ5ID09PSBkZWxNb2RpZmllciA/IERFTEVURSA6IChcbiAgICAgICAgICAgICAgbW9kaWZ5KG1heWJlRGVlcEZyZWV6ZShmaWVsZFZhbHVlKSwge1xuICAgICAgICAgICAgICAgIC4uLnNoYXJlZERldGFpbHMsXG4gICAgICAgICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgICAgICAgIHN0b3JlRmllbGROYW1lLFxuICAgICAgICAgICAgICAgIHN0b3JhZ2U6IHRoaXMuZ2V0U3RvcmFnZShkYXRhSWQsIHN0b3JlRmllbGROYW1lKSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSBJTlZBTElEQVRFKSB7XG4gICAgICAgICAgICB0aGlzLmdyb3VwLmRpcnR5KGRhdGFJZCwgc3RvcmVGaWVsZE5hbWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IERFTEVURSkgbmV3VmFsdWUgPSB2b2lkIDA7XG4gICAgICAgICAgICBpZiAobmV3VmFsdWUgIT09IGZpZWxkVmFsdWUpIHtcbiAgICAgICAgICAgICAgY2hhbmdlZEZpZWxkc1tzdG9yZUZpZWxkTmFtZV0gPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgbmVlZFRvTWVyZ2UgPSB0cnVlO1xuICAgICAgICAgICAgICBmaWVsZFZhbHVlID0gbmV3VmFsdWUgYXMgU3RvcmVWYWx1ZTtcblxuICAgICAgICAgICAgICBpZiAoX19ERVZfXykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoZWNrUmVmZXJlbmNlID0gKHJlZjogUmVmZXJlbmNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5sb29rdXAocmVmLl9fcmVmKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGludmFyaWFudC53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgIFwiY2FjaGUubW9kaWZ5OiBZb3UgYXJlIHRyeWluZyB0byB3cml0ZSBhIFJlZmVyZW5jZSB0aGF0IGlzIG5vdCBwYXJ0IG9mIHRoZSBzdG9yZTogJW9cXG5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlBsZWFzZSBtYWtlIHN1cmUgdG8gc2V0IHRoZSBgbWVyZ2VJbnRvU3RvcmVgIHBhcmFtZXRlciB0byBgdHJ1ZWAgd2hlbiBjcmVhdGluZyBhIFJlZmVyZW5jZSB0aGF0IGlzIG5vdCBwYXJ0IG9mIHRoZSBzdG9yZSB5ZXQ6XFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJgdG9SZWZlcmVuY2Uob2JqZWN0LCB0cnVlKWBcIixcbiAgICAgICAgICAgICAgICAgICAgICByZWZcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAoaXNSZWZlcmVuY2UobmV3VmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICBjaGVja1JlZmVyZW5jZShuZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG5ld1ZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgLy8gV2FybiBhYm91dCB3cml0aW5nIFwibWl4ZWRcIiBhcnJheXMgb2YgUmVmZXJlbmNlIGFuZCBub24tUmVmZXJlbmNlIG9iamVjdHNcbiAgICAgICAgICAgICAgICAgIGxldCBzZWVuUmVmZXJlbmNlOiBib29sZWFuID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICBsZXQgc29tZU5vblJlZmVyZW5jZTogdW5rbm93bjtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgbmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzUmVmZXJlbmNlKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgIHNlZW5SZWZlcmVuY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGVja1JlZmVyZW5jZSh2YWx1ZSkpIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCB3YXJuIG9uIHByaW1pdGl2ZSB2YWx1ZXMsIHNpbmNlIHRob3NlIGNvdWxkIG5ldmVyIGJlIHJlcHJlc2VudGVkXG4gICAgICAgICAgICAgICAgICAgICAgLy8gYnkgYSByZWZlcmVuY2UuIFRoaXMgaXMgYSB2YWxpZCAoYWxiZWl0IHVuY29tbW9uKSB1c2UgY2FzZS5cbiAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmICEhdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFtpZF0gPSB0aGlzLnBvbGljaWVzLmlkZW50aWZ5KHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIG9iamVjdCBjb3VsZCBldmVuIGJlIHJlZmVyZW5jZWQsIG90aGVyd2lzZSB3ZSBhcmUgbm90IGludGVyZXN0ZWQgaW4gaXQgZm9yIHRoaXMgd2FybmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNvbWVOb25SZWZlcmVuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlZW5SZWZlcmVuY2UgJiYgc29tZU5vblJlZmVyZW5jZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaW52YXJpYW50Lndhcm4oXG4gICAgICAgICAgICAgICAgICAgICAgICBcImNhY2hlLm1vZGlmeTogV3JpdGluZyBhbiBhcnJheSB3aXRoIGEgbWl4IG9mIGJvdGggUmVmZXJlbmNlcyBhbmQgT2JqZWN0cyB3aWxsIG5vdCByZXN1bHQgaW4gdGhlIE9iamVjdHMgYmVpbmcgbm9ybWFsaXplZCBjb3JyZWN0bHkuXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICBcIlBsZWFzZSBjb252ZXJ0IHRoZSBvYmplY3QgaW5zdGFuY2UgJW8gdG8gYSBSZWZlcmVuY2UgYmVmb3JlIHdyaXRpbmcgaXQgdG8gdGhlIGNhY2hlIGJ5IGNhbGxpbmcgYHRvUmVmZXJlbmNlKG9iamVjdCwgdHJ1ZSlgLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgc29tZU5vblJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpZWxkVmFsdWUgIT09IHZvaWQgMCkge1xuICAgICAgICAgIGFsbERlbGV0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmIChuZWVkVG9NZXJnZSkge1xuICAgICAgICB0aGlzLm1lcmdlKGRhdGFJZCwgY2hhbmdlZEZpZWxkcyk7XG5cbiAgICAgICAgaWYgKGFsbERlbGV0ZWQpIHtcbiAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIExheWVyKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGFbZGF0YUlkXSA9IHZvaWQgMDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuZGF0YVtkYXRhSWRdO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmdyb3VwLmRpcnR5KGRhdGFJZCwgXCJfX2V4aXN0c1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIElmIGNhbGxlZCB3aXRoIG9ubHkgb25lIGFyZ3VtZW50LCByZW1vdmVzIHRoZSBlbnRpcmUgZW50aXR5XG4gIC8vIGlkZW50aWZpZWQgYnkgZGF0YUlkLiBJZiBjYWxsZWQgd2l0aCBhIGZpZWxkTmFtZSBhcyB3ZWxsLCByZW1vdmVzIGFsbFxuICAvLyBmaWVsZHMgb2YgdGhhdCBlbnRpdHkgd2hvc2UgbmFtZXMgbWF0Y2ggZmllbGROYW1lIGFjY29yZGluZyB0byB0aGVcbiAgLy8gZmllbGROYW1lRnJvbVN0b3JlTmFtZSBoZWxwZXIgZnVuY3Rpb24uIElmIGNhbGxlZCB3aXRoIGEgZmllbGROYW1lXG4gIC8vIGFuZCB2YXJpYWJsZXMsIHJlbW92ZXMgYWxsIGZpZWxkcyBvZiB0aGF0IGVudGl0eSB3aG9zZSBuYW1lcyBtYXRjaCBmaWVsZE5hbWVcbiAgLy8gYW5kIHdob3NlIGFyZ3VtZW50cyB3aGVuIGNhY2hlZCBleGFjdGx5IG1hdGNoIHRoZSB2YXJpYWJsZXMgcGFzc2VkLlxuICBwdWJsaWMgZGVsZXRlKFxuICAgIGRhdGFJZDogc3RyaW5nLFxuICAgIGZpZWxkTmFtZT86IHN0cmluZyxcbiAgICBhcmdzPzogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICBjb25zdCBzdG9yZU9iamVjdCA9IHRoaXMubG9va3VwKGRhdGFJZCk7XG4gICAgaWYgKHN0b3JlT2JqZWN0KSB7XG4gICAgICBjb25zdCB0eXBlbmFtZSA9IHRoaXMuZ2V0RmllbGRWYWx1ZTxzdHJpbmc+KHN0b3JlT2JqZWN0LCBcIl9fdHlwZW5hbWVcIik7XG4gICAgICBjb25zdCBzdG9yZUZpZWxkTmFtZSA9XG4gICAgICAgIGZpZWxkTmFtZSAmJiBhcmdzID9cbiAgICAgICAgICB0aGlzLnBvbGljaWVzLmdldFN0b3JlRmllbGROYW1lKHsgdHlwZW5hbWUsIGZpZWxkTmFtZSwgYXJncyB9KVxuICAgICAgICA6IGZpZWxkTmFtZTtcbiAgICAgIHJldHVybiB0aGlzLm1vZGlmeShcbiAgICAgICAgZGF0YUlkLFxuICAgICAgICBzdG9yZUZpZWxkTmFtZSA/XG4gICAgICAgICAge1xuICAgICAgICAgICAgW3N0b3JlRmllbGROYW1lXTogZGVsTW9kaWZpZXIsXG4gICAgICAgICAgfVxuICAgICAgICA6IGRlbE1vZGlmaWVyXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwdWJsaWMgZXZpY3Qob3B0aW9uczogQ2FjaGUuRXZpY3RPcHRpb25zLCBsaW1pdDogRW50aXR5U3RvcmUpOiBib29sZWFuIHtcbiAgICBsZXQgZXZpY3RlZCA9IGZhbHNlO1xuICAgIGlmIChvcHRpb25zLmlkKSB7XG4gICAgICBpZiAoaGFzT3duLmNhbGwodGhpcy5kYXRhLCBvcHRpb25zLmlkKSkge1xuICAgICAgICBldmljdGVkID0gdGhpcy5kZWxldGUob3B0aW9ucy5pZCwgb3B0aW9ucy5maWVsZE5hbWUsIG9wdGlvbnMuYXJncyk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIExheWVyICYmIHRoaXMgIT09IGxpbWl0KSB7XG4gICAgICAgIGV2aWN0ZWQgPSB0aGlzLnBhcmVudC5ldmljdChvcHRpb25zLCBsaW1pdCkgfHwgZXZpY3RlZDtcbiAgICAgIH1cbiAgICAgIC8vIEFsd2F5cyBpbnZhbGlkYXRlIHRoZSBmaWVsZCB0byB0cmlnZ2VyIHJlcmVhZGluZyBvZiB3YXRjaGVkXG4gICAgICAvLyBxdWVyaWVzLCBldmVuIGlmIG5vIGNhY2hlIGRhdGEgd2FzIG1vZGlmaWVkIGJ5IHRoZSBldmljdGlvbixcbiAgICAgIC8vIGJlY2F1c2UgcXVlcmllcyBtYXkgZGVwZW5kIG9uIGNvbXB1dGVkIGZpZWxkcyB3aXRoIGN1c3RvbSByZWFkXG4gICAgICAvLyBmdW5jdGlvbnMsIHdob3NlIHZhbHVlcyBhcmUgbm90IHN0b3JlZCBpbiB0aGUgRW50aXR5U3RvcmUuXG4gICAgICBpZiAob3B0aW9ucy5maWVsZE5hbWUgfHwgZXZpY3RlZCkge1xuICAgICAgICB0aGlzLmdyb3VwLmRpcnR5KG9wdGlvbnMuaWQsIG9wdGlvbnMuZmllbGROYW1lIHx8IFwiX19leGlzdHNcIik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBldmljdGVkO1xuICB9XG5cbiAgcHVibGljIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMucmVwbGFjZShudWxsKTtcbiAgfVxuXG4gIHB1YmxpYyBleHRyYWN0KCk6IE5vcm1hbGl6ZWRDYWNoZU9iamVjdCB7XG4gICAgY29uc3Qgb2JqID0gdGhpcy50b09iamVjdCgpO1xuICAgIGNvbnN0IGV4dHJhUm9vdElkczogc3RyaW5nW10gPSBbXTtcbiAgICB0aGlzLmdldFJvb3RJZFNldCgpLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICBpZiAoIWhhc093bi5jYWxsKHRoaXMucG9saWNpZXMucm9vdFR5cGVuYW1lc0J5SWQsIGlkKSkge1xuICAgICAgICBleHRyYVJvb3RJZHMucHVzaChpZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGV4dHJhUm9vdElkcy5sZW5ndGgpIHtcbiAgICAgIG9iai5fX01FVEEgPSB7IGV4dHJhUm9vdElkczogZXh0cmFSb290SWRzLnNvcnQoKSB9O1xuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgcHVibGljIHJlcGxhY2UobmV3RGF0YTogTm9ybWFsaXplZENhY2hlT2JqZWN0IHwgbnVsbCk6IHZvaWQge1xuICAgIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkuZm9yRWFjaCgoZGF0YUlkKSA9PiB7XG4gICAgICBpZiAoIShuZXdEYXRhICYmIGhhc093bi5jYWxsKG5ld0RhdGEsIGRhdGFJZCkpKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlKGRhdGFJZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKG5ld0RhdGEpIHtcbiAgICAgIGNvbnN0IHsgX19NRVRBLCAuLi5yZXN0IH0gPSBuZXdEYXRhO1xuICAgICAgT2JqZWN0LmtleXMocmVzdCkuZm9yRWFjaCgoZGF0YUlkKSA9PiB7XG4gICAgICAgIHRoaXMubWVyZ2UoZGF0YUlkLCByZXN0W2RhdGFJZF0gYXMgU3RvcmVPYmplY3QpO1xuICAgICAgfSk7XG4gICAgICBpZiAoX19NRVRBKSB7XG4gICAgICAgIF9fTUVUQS5leHRyYVJvb3RJZHMuZm9yRWFjaCh0aGlzLnJldGFpbiwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFic3RyYWN0IGdldFN0b3JhZ2UoXG4gICAgaWRPck9iajogc3RyaW5nIHwgU3RvcmVPYmplY3QsXG4gICAgLi4uc3RvcmVGaWVsZE5hbWVzOiAoc3RyaW5nIHwgbnVtYmVyKVtdXG4gICk6IFN0b3JhZ2VUeXBlO1xuXG4gIC8vIE1hcHMgcm9vdCBlbnRpdHkgSURzIHRvIHRoZSBudW1iZXIgb2YgdGltZXMgdGhleSBoYXZlIGJlZW4gcmV0YWluZWQsIG1pbnVzXG4gIC8vIHRoZSBudW1iZXIgb2YgdGltZXMgdGhleSBoYXZlIGJlZW4gcmVsZWFzZWQuIFJldGFpbmVkIGVudGl0aWVzIGtlZXAgb3RoZXJcbiAgLy8gZW50aXRpZXMgdGhleSByZWZlcmVuY2UgKGV2ZW4gaW5kaXJlY3RseSkgZnJvbSBiZWluZyBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgcHJpdmF0ZSByb290SWRzOiB7XG4gICAgW3Jvb3RJZDogc3RyaW5nXTogbnVtYmVyO1xuICB9ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICBwdWJsaWMgcmV0YWluKHJvb3RJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMucm9vdElkc1tyb290SWRdID0gKHRoaXMucm9vdElkc1tyb290SWRdIHx8IDApICsgMSk7XG4gIH1cblxuICBwdWJsaWMgcmVsZWFzZShyb290SWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMucm9vdElkc1tyb290SWRdID4gMCkge1xuICAgICAgY29uc3QgY291bnQgPSAtLXRoaXMucm9vdElkc1tyb290SWRdO1xuICAgICAgaWYgKCFjb3VudCkgZGVsZXRlIHRoaXMucm9vdElkc1tyb290SWRdO1xuICAgICAgcmV0dXJuIGNvdW50O1xuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8vIFJldHVybiBhIFNldDxzdHJpbmc+IG9mIGFsbCB0aGUgSUQgc3RyaW5ncyB0aGF0IGhhdmUgYmVlbiByZXRhaW5lZCBieVxuICAvLyB0aGlzIGxheWVyL3Jvb3QgKmFuZCogYW55IGxheWVycy9yb290cyBiZW5lYXRoIGl0LlxuICBwdWJsaWMgZ2V0Um9vdElkU2V0KGlkcyA9IG5ldyBTZXQ8c3RyaW5nPigpKSB7XG4gICAgT2JqZWN0LmtleXModGhpcy5yb290SWRzKS5mb3JFYWNoKGlkcy5hZGQsIGlkcyk7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBMYXllcikge1xuICAgICAgdGhpcy5wYXJlbnQuZ2V0Um9vdElkU2V0KGlkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE9mZmljaWFsIHNpbmdsZXRvbiBJRHMgbGlrZSBST09UX1FVRVJZIGFuZCBST09UX01VVEFUSU9OIGFyZVxuICAgICAgLy8gYWx3YXlzIGNvbnNpZGVyZWQgcm9vdHMgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbiwgcmVnYXJkbGVzcyBvZlxuICAgICAgLy8gdGhlaXIgcmV0YWlubWVudCBjb3VudHMgaW4gdGhpcy5yb290SWRzLlxuICAgICAgT2JqZWN0LmtleXModGhpcy5wb2xpY2llcy5yb290VHlwZW5hbWVzQnlJZCkuZm9yRWFjaChpZHMuYWRkLCBpZHMpO1xuICAgIH1cbiAgICByZXR1cm4gaWRzO1xuICB9XG5cbiAgLy8gVGhlIGdvYWwgb2YgZ2FyYmFnZSBjb2xsZWN0aW9uIGlzIHRvIHJlbW92ZSBJRHMgZnJvbSB0aGUgUm9vdCBsYXllciBvZiB0aGVcbiAgLy8gc3RvcmUgdGhhdCBhcmUgbm8gbG9uZ2VyIHJlYWNoYWJsZSBzdGFydGluZyBmcm9tIGFueSBJRHMgdGhhdCBoYXZlIGJlZW5cbiAgLy8gZXhwbGljaXRseSByZXRhaW5lZCAoc2VlIHJldGFpbiBhbmQgcmVsZWFzZSwgYWJvdmUpLiBSZXR1cm5zIGFuIGFycmF5IG9mXG4gIC8vIGRhdGFJZCBzdHJpbmdzIHRoYXQgd2VyZSByZW1vdmVkIGZyb20gdGhlIHN0b3JlLlxuICBwdWJsaWMgZ2MoKSB7XG4gICAgY29uc3QgaWRzID0gdGhpcy5nZXRSb290SWRTZXQoKTtcbiAgICBjb25zdCBzbmFwc2hvdCA9IHRoaXMudG9PYmplY3QoKTtcbiAgICBpZHMuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgIGlmIChoYXNPd24uY2FsbChzbmFwc2hvdCwgaWQpKSB7XG4gICAgICAgIC8vIEJlY2F1c2Ugd2UgYXJlIGl0ZXJhdGluZyBvdmVyIGFuIEVDTUFTY3JpcHQgU2V0LCB0aGUgSURzIHdlIGFkZCBoZXJlXG4gICAgICAgIC8vIHdpbGwgYmUgdmlzaXRlZCBpbiBsYXRlciBpdGVyYXRpb25zIG9mIHRoZSBmb3JFYWNoIGxvb3Agb25seSBpZiB0aGV5XG4gICAgICAgIC8vIHdlcmUgbm90IHByZXZpb3VzbHkgY29udGFpbmVkIGJ5IHRoZSBTZXQuXG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZmluZENoaWxkUmVmSWRzKGlkKSkuZm9yRWFjaChpZHMuYWRkLCBpZHMpO1xuICAgICAgICAvLyBCeSByZW1vdmluZyBJRHMgZnJvbSB0aGUgc25hcHNob3Qgb2JqZWN0IGhlcmUsIHdlIHByb3RlY3QgdGhlbSBmcm9tXG4gICAgICAgIC8vIGdldHRpbmcgcmVtb3ZlZCBmcm9tIHRoZSByb290IHN0b3JlIGxheWVyIGJlbG93LlxuICAgICAgICBkZWxldGUgc25hcHNob3RbaWRdO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IGlkc1RvUmVtb3ZlID0gT2JqZWN0LmtleXMoc25hcHNob3QpO1xuICAgIGlmIChpZHNUb1JlbW92ZS5sZW5ndGgpIHtcbiAgICAgIGxldCByb290OiBFbnRpdHlTdG9yZSA9IHRoaXM7XG4gICAgICB3aGlsZSAocm9vdCBpbnN0YW5jZW9mIExheWVyKSByb290ID0gcm9vdC5wYXJlbnQ7XG4gICAgICBpZHNUb1JlbW92ZS5mb3JFYWNoKChpZCkgPT4gcm9vdC5kZWxldGUoaWQpKTtcbiAgICB9XG4gICAgcmV0dXJuIGlkc1RvUmVtb3ZlO1xuICB9XG5cbiAgLy8gTGF6aWx5IHRyYWNrcyB7IF9fcmVmOiA8ZGF0YUlkPiB9IHN0cmluZ3MgY29udGFpbmVkIGJ5IHRoaXMuZGF0YVtkYXRhSWRdLlxuICBwcml2YXRlIHJlZnM6IHtcbiAgICBbZGF0YUlkOiBzdHJpbmddOiBSZWNvcmQ8c3RyaW5nLCB0cnVlPjtcbiAgfSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgcHVibGljIGZpbmRDaGlsZFJlZklkcyhkYXRhSWQ6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHRydWU+IHtcbiAgICBpZiAoIWhhc093bi5jYWxsKHRoaXMucmVmcywgZGF0YUlkKSkge1xuICAgICAgY29uc3QgZm91bmQgPSAodGhpcy5yZWZzW2RhdGFJZF0gPSBPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICAgIGNvbnN0IHJvb3QgPSB0aGlzLmRhdGFbZGF0YUlkXTtcbiAgICAgIGlmICghcm9vdCkgcmV0dXJuIGZvdW5kO1xuXG4gICAgICBjb25zdCB3b3JrU2V0ID0gbmV3IFNldDxSZWNvcmQ8c3RyaW5nIHwgbnVtYmVyLCBhbnk+Pihbcm9vdF0pO1xuICAgICAgLy8gV2l0aGluIHRoZSBzdG9yZSwgb25seSBhcnJheXMgYW5kIG9iamVjdHMgY2FuIGNvbnRhaW4gY2hpbGQgZW50aXR5XG4gICAgICAvLyByZWZlcmVuY2VzLCBzbyB3ZSBjYW4gcHJ1bmUgdGhlIHRyYXZlcnNhbCB1c2luZyB0aGlzIHByZWRpY2F0ZTpcbiAgICAgIHdvcmtTZXQuZm9yRWFjaCgob2JqKSA9PiB7XG4gICAgICAgIGlmIChpc1JlZmVyZW5jZShvYmopKSB7XG4gICAgICAgICAgZm91bmRbb2JqLl9fcmVmXSA9IHRydWU7XG4gICAgICAgICAgLy8gSW4gcmFyZSBjYXNlcywgYSB7IF9fcmVmIH0gUmVmZXJlbmNlIG9iamVjdCBtYXkgaGF2ZSBvdGhlciBmaWVsZHMuXG4gICAgICAgICAgLy8gVGhpcyBvZnRlbiBpbmRpY2F0ZXMgYSBtaXNtZXJnaW5nIG9mIFJlZmVyZW5jZXMgd2l0aCBTdG9yZU9iamVjdHMsXG4gICAgICAgICAgLy8gYnV0IGdhcmJhZ2UgY29sbGVjdGlvbiBzaG91bGQgbm90IGJlIGZvb2xlZCBieSBhIHN0cmF5IF9fcmVmXG4gICAgICAgICAgLy8gcHJvcGVydHkgaW4gYSBTdG9yZU9iamVjdCAoaWdub3JpbmcgYWxsIHRoZSBvdGhlciBmaWVsZHMganVzdFxuICAgICAgICAgIC8vIGJlY2F1c2UgdGhlIFN0b3JlT2JqZWN0IGxvb2tzIGxpa2UgYSBSZWZlcmVuY2UpLiBUbyBhdm9pZCB0aGlzXG4gICAgICAgICAgLy8gcHJlbWF0dXJlIHRlcm1pbmF0aW9uIG9mIGZpbmRDaGlsZFJlZklkcyByZWN1cnNpb24sIHdlIGZhbGwgdGhyb3VnaFxuICAgICAgICAgIC8vIHRvIHRoZSBjb2RlIGJlbG93LCB3aGljaCB3aWxsIGhhbmRsZSBhbnkgb3RoZXIgcHJvcGVydGllcyBvZiBvYmouXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTm9uTnVsbE9iamVjdChvYmopKSB7XG4gICAgICAgICAgT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gb2JqW2tleV07XG4gICAgICAgICAgICAvLyBObyBuZWVkIHRvIGFkZCBwcmltaXRpdmUgdmFsdWVzIHRvIHRoZSB3b3JrU2V0LCBzaW5jZSB0aGV5IGNhbm5vdFxuICAgICAgICAgICAgLy8gY29udGFpbiByZWZlcmVuY2Ugb2JqZWN0cy5cbiAgICAgICAgICAgIGlmIChpc05vbk51bGxPYmplY3QoY2hpbGQpKSB7XG4gICAgICAgICAgICAgIHdvcmtTZXQuYWRkKGNoaWxkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlZnNbZGF0YUlkXTtcbiAgfVxuXG4gIC8vIFVzZWQgdG8gY29tcHV0ZSBjYWNoZSBrZXlzIHNwZWNpZmljIHRvIHRoaXMuZ3JvdXAuXG4gIC8qKiBvdmVybG9hZCBmb3IgYEluTWVtb3J5Q2FjaGUubWF5YmVCcm9hZGNhc3RXYXRjaGAgKi9cbiAgcHVibGljIG1ha2VDYWNoZUtleShcbiAgICBkb2N1bWVudDogRG9jdW1lbnROb2RlLFxuICAgIGNhbGxiYWNrOiBDYWNoZS5XYXRjaENhbGxiYWNrPGFueT4sXG4gICAgZGV0YWlsczogc3RyaW5nXG4gICk6IG9iamVjdDtcbiAgLyoqIG92ZXJsb2FkIGZvciBgU3RvcmVSZWFkZXIuZXhlY3V0ZVNlbGVjdGlvblNldGAgKi9cbiAgcHVibGljIG1ha2VDYWNoZUtleShcbiAgICBzZWxlY3Rpb25TZXQ6IFNlbGVjdGlvblNldE5vZGUsXG4gICAgcGFyZW50OiBzdHJpbmcgLyogPSAoIFJlZmVyZW5jZS5fX3JlZiApICovIHwgU3RvcmVPYmplY3QsXG4gICAgdmFyU3RyaW5nOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgY2Fub25pemVSZXN1bHRzOiBib29sZWFuXG4gICk6IG9iamVjdDtcbiAgLyoqIG92ZXJsb2FkIGZvciBgU3RvcmVSZWFkZXIuZXhlY3V0ZVN1YlNlbGVjdGVkQXJyYXlgICovXG4gIHB1YmxpYyBtYWtlQ2FjaGVLZXkoXG4gICAgZmllbGQ6IEZpZWxkTm9kZSxcbiAgICBhcnJheTogcmVhZG9ubHkgYW55W10sXG4gICAgdmFyU3RyaW5nOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogb2JqZWN0O1xuICAvKiogQGRlcHJlY2F0ZWQgVGhpcyBpcyBvbmx5IG1lYW50IGZvciBpbnRlcm5hbCB1c2FnZSxcbiAgICogaW4geW91ciBvd24gY29kZSBwbGVhc2UgdXNlIGEgYFRyaWVgIGluc3RhbmNlIGluc3RlYWQuICovXG4gIHB1YmxpYyBtYWtlQ2FjaGVLZXkoLi4uYXJnczogYW55W10pOiBvYmplY3Q7XG4gIHB1YmxpYyBtYWtlQ2FjaGVLZXkoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ3JvdXAua2V5TWFrZXIubG9va3VwQXJyYXkoYXJndW1lbnRzKTtcbiAgfVxuXG4gIC8vIEJvdW5kIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHBhc3NlZCBhcm91bmQgdG8gcHJvdmlkZSBlYXN5IGFjY2VzcyB0byBmaWVsZHNcbiAgLy8gb2YgUmVmZXJlbmNlIG9iamVjdHMgYXMgd2VsbCBhcyBvcmRpbmFyeSBvYmplY3RzLlxuICBwdWJsaWMgZ2V0RmllbGRWYWx1ZSA9IDxUID0gU3RvcmVWYWx1ZT4oXG4gICAgb2JqZWN0T3JSZWZlcmVuY2U6IFN0b3JlT2JqZWN0IHwgUmVmZXJlbmNlIHwgdW5kZWZpbmVkLFxuICAgIHN0b3JlRmllbGROYW1lOiBzdHJpbmdcbiAgKSA9PlxuICAgIG1heWJlRGVlcEZyZWV6ZShcbiAgICAgIGlzUmVmZXJlbmNlKG9iamVjdE9yUmVmZXJlbmNlKSA/XG4gICAgICAgIHRoaXMuZ2V0KG9iamVjdE9yUmVmZXJlbmNlLl9fcmVmLCBzdG9yZUZpZWxkTmFtZSlcbiAgICAgIDogb2JqZWN0T3JSZWZlcmVuY2UgJiYgb2JqZWN0T3JSZWZlcmVuY2Vbc3RvcmVGaWVsZE5hbWVdXG4gICAgKSBhcyBTYWZlUmVhZG9ubHk8VD47XG5cbiAgLy8gUmV0dXJucyB0cnVlIGZvciBub24tbm9ybWFsaXplZCBTdG9yZU9iamVjdHMgYW5kIG5vbi1kYW5nbGluZ1xuICAvLyBSZWZlcmVuY2VzLCBpbmRpY2F0aW5nIHRoYXQgcmVhZEZpZWxkKG5hbWUsIG9iak9yUmVmKSBoYXMgYSBjaGFuY2Ugb2ZcbiAgLy8gd29ya2luZy4gVXNlZnVsIGZvciBmaWx0ZXJpbmcgb3V0IGRhbmdsaW5nIHJlZmVyZW5jZXMgZnJvbSBsaXN0cy5cbiAgcHVibGljIGNhblJlYWQ6IENhblJlYWRGdW5jdGlvbiA9IChvYmpPclJlZikgPT4ge1xuICAgIHJldHVybiBpc1JlZmVyZW5jZShvYmpPclJlZikgP1xuICAgICAgICB0aGlzLmhhcyhvYmpPclJlZi5fX3JlZilcbiAgICAgIDogdHlwZW9mIG9iak9yUmVmID09PSBcIm9iamVjdFwiO1xuICB9O1xuXG4gIC8vIEJvdW5kIGZ1bmN0aW9uIHRoYXQgY29udmVydHMgYW4gaWQgb3IgYW4gb2JqZWN0IHdpdGggYSBfX3R5cGVuYW1lIGFuZFxuICAvLyBwcmltYXJ5IGtleSBmaWVsZHMgdG8gYSBSZWZlcmVuY2Ugb2JqZWN0LiBJZiBjYWxsZWQgd2l0aCBhIFJlZmVyZW5jZSBvYmplY3QsXG4gIC8vIHRoYXQgc2FtZSBSZWZlcmVuY2Ugb2JqZWN0IGlzIHJldHVybmVkLiBQYXNzIHRydWUgZm9yIG1lcmdlSW50b1N0b3JlIHRvIHBlcnNpc3RcbiAgLy8gYW4gb2JqZWN0IGludG8gdGhlIHN0b3JlLlxuICBwdWJsaWMgdG9SZWZlcmVuY2U6IFRvUmVmZXJlbmNlRnVuY3Rpb24gPSAob2JqT3JJZE9yUmVmLCBtZXJnZUludG9TdG9yZSkgPT4ge1xuICAgIGlmICh0eXBlb2Ygb2JqT3JJZE9yUmVmID09PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gbWFrZVJlZmVyZW5jZShvYmpPcklkT3JSZWYpO1xuICAgIH1cblxuICAgIGlmIChpc1JlZmVyZW5jZShvYmpPcklkT3JSZWYpKSB7XG4gICAgICByZXR1cm4gb2JqT3JJZE9yUmVmO1xuICAgIH1cblxuICAgIGNvbnN0IFtpZF0gPSB0aGlzLnBvbGljaWVzLmlkZW50aWZ5KG9iak9ySWRPclJlZik7XG5cbiAgICBpZiAoaWQpIHtcbiAgICAgIGNvbnN0IHJlZiA9IG1ha2VSZWZlcmVuY2UoaWQpO1xuICAgICAgaWYgKG1lcmdlSW50b1N0b3JlKSB7XG4gICAgICAgIHRoaXMubWVyZ2UoaWQsIG9iak9ySWRPclJlZik7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVmO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IHR5cGUgRmllbGRWYWx1ZUdldHRlciA9IEVudGl0eVN0b3JlW1wiZ2V0RmllbGRWYWx1ZVwiXTtcblxuLy8gQSBzaW5nbGUgQ2FjaGVHcm91cCByZXByZXNlbnRzIGEgc2V0IG9mIG9uZSBvciBtb3JlIEVudGl0eVN0b3JlIG9iamVjdHMsXG4vLyB0eXBpY2FsbHkgdGhlIFJvb3Qgc3RvcmUgaW4gYSBDYWNoZUdyb3VwIGJ5IGl0c2VsZiwgYW5kIGFsbCBhY3RpdmUgTGF5ZXJcbi8vIHN0b3JlcyBpbiBhIGdyb3VwIHRvZ2V0aGVyLiBBIHNpbmdsZSBFbnRpdHlTdG9yZSBvYmplY3QgYmVsb25ncyB0byBvbmx5XG4vLyBvbmUgQ2FjaGVHcm91cCwgc3RvcmUuZ3JvdXAuIFRoZSBDYWNoZUdyb3VwIGlzIHJlc3BvbnNpYmxlIGZvciB0cmFja2luZ1xuLy8gZGVwZW5kZW5jaWVzLCBzbyBzdG9yZS5ncm91cCBpcyBoZWxwZnVsIGZvciBnZW5lcmF0aW5nIHVuaXF1ZSBrZXlzIGZvclxuLy8gY2FjaGVkIHJlc3VsdHMgdGhhdCBuZWVkIHRvIGJlIGludmFsaWRhdGVkIHdoZW4vaWYgdGhvc2UgZGVwZW5kZW5jaWVzXG4vLyBjaGFuZ2UuIElmIHdlIHVzZWQgdGhlIEVudGl0eVN0b3JlIG9iamVjdHMgdGhlbXNlbHZlcyBhcyBjYWNoZSBrZXlzICh0aGF0XG4vLyBpcywgc3RvcmUgcmF0aGVyIHRoYW4gc3RvcmUuZ3JvdXApLCB0aGUgY2FjaGUgd291bGQgYmVjb21lIHVubmVjZXNzYXJpbHlcbi8vIGZyYWdtZW50ZWQgYnkgYWxsIHRoZSBkaWZmZXJlbnQgTGF5ZXIgb2JqZWN0cy4gSW5zdGVhZCwgdGhlIENhY2hlR3JvdXBcbi8vIGFwcHJvYWNoIGFsbG93cyBhbGwgb3B0aW1pc3RpYyBMYXllciBvYmplY3RzIGluIHRoZSBzYW1lIGxpbmtlZCBsaXN0IHRvXG4vLyBiZWxvbmcgdG8gb25lIENhY2hlR3JvdXAsIHdpdGggdGhlIG5vbi1vcHRpbWlzdGljIFJvb3Qgb2JqZWN0IGJlbG9uZ2luZ1xuLy8gdG8gYW5vdGhlciBDYWNoZUdyb3VwLCBhbGxvd2luZyByZXN1bHRDYWNoaW5nIGRlcGVuZGVuY2llcyB0byBiZSB0cmFja2VkXG4vLyBzZXBhcmF0ZWx5IGZvciBvcHRpbWlzdGljIGFuZCBub24tb3B0aW1pc3RpYyBlbnRpdHkgZGF0YS5cbmNsYXNzIENhY2hlR3JvdXAge1xuICBwcml2YXRlIGQ6IE9wdGltaXN0aWNEZXBlbmRlbmN5RnVuY3Rpb248c3RyaW5nPiB8IG51bGwgPSBudWxsO1xuXG4gIC8vIFVzZWQgYnkgdGhlIEVudGl0eVN0b3JlI21ha2VDYWNoZUtleSBtZXRob2QgdG8gY29tcHV0ZSBjYWNoZSBrZXlzXG4gIC8vIHNwZWNpZmljIHRvIHRoaXMgQ2FjaGVHcm91cC5cbiAgcHVibGljIGtleU1ha2VyITogVHJpZTxvYmplY3Q+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBjYWNoaW5nOiBib29sZWFuLFxuICAgIHByaXZhdGUgcGFyZW50OiBDYWNoZUdyb3VwIHwgbnVsbCA9IG51bGxcbiAgKSB7XG4gICAgdGhpcy5yZXNldENhY2hpbmcoKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNldENhY2hpbmcoKSB7XG4gICAgdGhpcy5kID0gdGhpcy5jYWNoaW5nID8gZGVwPHN0cmluZz4oKSA6IG51bGw7XG4gICAgdGhpcy5rZXlNYWtlciA9IG5ldyBUcmllKGNhblVzZVdlYWtNYXApO1xuICB9XG5cbiAgcHVibGljIGRlcGVuZChkYXRhSWQ6IHN0cmluZywgc3RvcmVGaWVsZE5hbWU6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmQpIHtcbiAgICAgIHRoaXMuZChtYWtlRGVwS2V5KGRhdGFJZCwgc3RvcmVGaWVsZE5hbWUpKTtcbiAgICAgIGNvbnN0IGZpZWxkTmFtZSA9IGZpZWxkTmFtZUZyb21TdG9yZU5hbWUoc3RvcmVGaWVsZE5hbWUpO1xuICAgICAgaWYgKGZpZWxkTmFtZSAhPT0gc3RvcmVGaWVsZE5hbWUpIHtcbiAgICAgICAgLy8gRmllbGRzIHdpdGggYXJndW1lbnRzIHRoYXQgY29udHJpYnV0ZSBleHRyYSBpZGVudGlmeWluZ1xuICAgICAgICAvLyBpbmZvcm1hdGlvbiB0byB0aGUgZmllbGROYW1lICh0aHVzIGZvcm1pbmcgdGhlIHN0b3JlRmllbGROYW1lKVxuICAgICAgICAvLyBkZXBlbmQgbm90IG9ubHkgb24gdGhlIGZ1bGwgc3RvcmVGaWVsZE5hbWUgYnV0IGFsc28gb24gdGhlXG4gICAgICAgIC8vIHNob3J0IGZpZWxkTmFtZSwgc28gdGhlIGZpZWxkIGNhbiBiZSBpbnZhbGlkYXRlZCB1c2luZyBlaXRoZXJcbiAgICAgICAgLy8gbGV2ZWwgb2Ygc3BlY2lmaWNpdHkuXG4gICAgICAgIHRoaXMuZChtYWtlRGVwS2V5KGRhdGFJZCwgZmllbGROYW1lKSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQuZGVwZW5kKGRhdGFJZCwgc3RvcmVGaWVsZE5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBkaXJ0eShkYXRhSWQ6IHN0cmluZywgc3RvcmVGaWVsZE5hbWU6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmQpIHtcbiAgICAgIHRoaXMuZC5kaXJ0eShcbiAgICAgICAgbWFrZURlcEtleShkYXRhSWQsIHN0b3JlRmllbGROYW1lKSxcbiAgICAgICAgLy8gV2hlbiBzdG9yZUZpZWxkTmFtZSA9PT0gXCJfX2V4aXN0c1wiLCB0aGF0IG1lYW5zIHRoZSBlbnRpdHkgaWRlbnRpZmllZFxuICAgICAgICAvLyBieSBkYXRhSWQgaGFzIGVpdGhlciBkaXNhcHBlYXJlZCBmcm9tIHRoZSBjYWNoZSBvciB3YXMgbmV3bHkgYWRkZWQsXG4gICAgICAgIC8vIHNvIHRoZSByZXN1bHQgY2FjaGluZyBzeXN0ZW0gd291bGQgZG8gd2VsbCB0byBcImZvcmdldCBldmVyeXRoaW5nIGl0XG4gICAgICAgIC8vIGtub3dzXCIgYWJvdXQgdGhhdCBvYmplY3QuIFRvIGFjaGlldmUgdGhhdCBraW5kIG9mIGludmFsaWRhdGlvbiwgd2VcbiAgICAgICAgLy8gbm90IG9ubHkgZGlydHkgdGhlIGFzc29jaWF0ZWQgcmVzdWx0IGNhY2hlIGVudHJ5LCBidXQgYWxzbyByZW1vdmUgaXRcbiAgICAgICAgLy8gY29tcGxldGVseSBmcm9tIHRoZSBkZXBlbmRlbmN5IGdyYXBoLiBGb3IgdGhlIG9wdGltaXNtIGltcGxlbWVudGF0aW9uXG4gICAgICAgIC8vIGRldGFpbHMsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vYmVuamFtbi9vcHRpbWlzbS9wdWxsLzE5NS5cbiAgICAgICAgc3RvcmVGaWVsZE5hbWUgPT09IFwiX19leGlzdHNcIiA/IFwiZm9yZ2V0XCIgOiBcInNldERpcnR5XCJcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VEZXBLZXkoZGF0YUlkOiBzdHJpbmcsIHN0b3JlRmllbGROYW1lOiBzdHJpbmcpIHtcbiAgLy8gU2luY2UgZmllbGQgbmFtZXMgY2Fubm90IGhhdmUgJyMnIGNoYXJhY3RlcnMgaW4gdGhlbSwgdGhpcyBtZXRob2RcbiAgLy8gb2Ygam9pbmluZyB0aGUgZmllbGQgbmFtZSBhbmQgdGhlIElEIHNob3VsZCBiZSB1bmFtYmlndW91cywgYW5kIG11Y2hcbiAgLy8gY2hlYXBlciB0aGFuIEpTT04uc3RyaW5naWZ5KFtkYXRhSWQsIGZpZWxkTmFtZV0pLlxuICByZXR1cm4gc3RvcmVGaWVsZE5hbWUgKyBcIiNcIiArIGRhdGFJZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlRGVwZW5kT25FeGlzdGVuY2VPZkVudGl0eShcbiAgc3RvcmU6IE5vcm1hbGl6ZWRDYWNoZSxcbiAgZW50aXR5SWQ6IHN0cmluZ1xuKSB7XG4gIGlmIChzdXBwb3J0c1Jlc3VsdENhY2hpbmcoc3RvcmUpKSB7XG4gICAgLy8gV2UgdXNlIHRoaXMgcHNldWRvLWZpZWxkIF9fZXhpc3RzIGVsc2V3aGVyZSBpbiB0aGUgRW50aXR5U3RvcmUgY29kZSB0b1xuICAgIC8vIHJlcHJlc2VudCBjaGFuZ2VzIGluIHRoZSBleGlzdGVuY2Ugb2YgdGhlIGVudGl0eSBvYmplY3QgaWRlbnRpZmllZCBieVxuICAgIC8vIGVudGl0eUlkLiBUaGlzIGRlcGVuZGVuY3kgZ2V0cyByZWxpYWJseSBkaXJ0aWVkIHdoZW5ldmVyIGFuIG9iamVjdCB3aXRoXG4gICAgLy8gdGhpcyBJRCBpcyBkZWxldGVkIChvciBuZXdseSBjcmVhdGVkKSB3aXRoaW4gdGhpcyBncm91cCwgc28gYW55IHJlc3VsdFxuICAgIC8vIGNhY2hlIGVudHJpZXMgKGZvciBleGFtcGxlLCBTdG9yZVJlYWRlciNleGVjdXRlU2VsZWN0aW9uU2V0IHJlc3VsdHMpIHRoYXRcbiAgICAvLyBkZXBlbmQgb24gX19leGlzdHMgZm9yIHRoaXMgZW50aXR5SWQgd2lsbCBnZXQgZGlydGllZCBhcyB3ZWxsLCBsZWFkaW5nIHRvXG4gICAgLy8gdGhlIGV2ZW50dWFsIHJlY29tcHV0YXRpb24gKGluc3RlYWQgb2YgcmV1c2UpIG9mIHRob3NlIHJlc3VsdCBvYmplY3RzIHRoZVxuICAgIC8vIG5leHQgdGltZSBzb21lb25lIHJlYWRzIHRoZW0gZnJvbSB0aGUgY2FjaGUuXG4gICAgc3RvcmUuZ3JvdXAuZGVwZW5kKGVudGl0eUlkLCBcIl9fZXhpc3RzXCIpO1xuICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgRW50aXR5U3RvcmUge1xuICAvLyBSZWZlciB0byB0aGlzIGNsYXNzIGFzIEVudGl0eVN0b3JlLlJvb3Qgb3V0c2lkZSB0aGlzIG5hbWVzcGFjZS5cbiAgZXhwb3J0IGNsYXNzIFJvb3QgZXh0ZW5kcyBFbnRpdHlTdG9yZSB7XG4gICAgY29uc3RydWN0b3Ioe1xuICAgICAgcG9saWNpZXMsXG4gICAgICByZXN1bHRDYWNoaW5nID0gdHJ1ZSxcbiAgICAgIHNlZWQsXG4gICAgfToge1xuICAgICAgcG9saWNpZXM6IFBvbGljaWVzO1xuICAgICAgcmVzdWx0Q2FjaGluZz86IGJvb2xlYW47XG4gICAgICBzZWVkPzogTm9ybWFsaXplZENhY2hlT2JqZWN0O1xuICAgIH0pIHtcbiAgICAgIHN1cGVyKHBvbGljaWVzLCBuZXcgQ2FjaGVHcm91cChyZXN1bHRDYWNoaW5nKSk7XG4gICAgICBpZiAoc2VlZCkgdGhpcy5yZXBsYWNlKHNlZWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWFkb25seSBzdHVtcCA9IG5ldyBTdHVtcCh0aGlzKTtcblxuICAgIHB1YmxpYyBhZGRMYXllcihcbiAgICAgIGxheWVySWQ6IHN0cmluZyxcbiAgICAgIHJlcGxheTogKGxheWVyOiBFbnRpdHlTdG9yZSkgPT4gYW55XG4gICAgKTogTGF5ZXIge1xuICAgICAgLy8gQWRkaW5nIGFuIG9wdGltaXN0aWMgTGF5ZXIgb24gdG9wIG9mIHRoZSBSb290IGFjdHVhbGx5IGFkZHMgdGhlIExheWVyXG4gICAgICAvLyBvbiB0b3Agb2YgdGhlIFN0dW1wLCBzbyB0aGUgU3R1bXAgYWx3YXlzIGNvbWVzIGJldHdlZW4gdGhlIFJvb3QgYW5kXG4gICAgICAvLyBhbnkgTGF5ZXIgb2JqZWN0cyB0aGF0IHdlJ3ZlIGFkZGVkLlxuICAgICAgcmV0dXJuIHRoaXMuc3R1bXAuYWRkTGF5ZXIobGF5ZXJJZCwgcmVwbGF5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVtb3ZlTGF5ZXIoKTogUm9vdCB7XG4gICAgICAvLyBOZXZlciByZW1vdmUgdGhlIHJvb3QgbGF5ZXIuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RvcmFnZVRyaWUgPSBuZXcgVHJpZTxTdG9yYWdlVHlwZT4oY2FuVXNlV2Vha01hcCk7XG4gICAgcHVibGljIGdldFN0b3JhZ2UoKTogU3RvcmFnZVR5cGUge1xuICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZVRyaWUubG9va3VwQXJyYXkoYXJndW1lbnRzKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gTm90IGV4cG9ydGVkLCBzaW5jZSBhbGwgTGF5ZXIgaW5zdGFuY2VzIGFyZSBjcmVhdGVkIGJ5IHRoZSBhZGRMYXllciBtZXRob2Rcbi8vIG9mIHRoZSBFbnRpdHlTdG9yZS5Sb290IGNsYXNzLlxuY2xhc3MgTGF5ZXIgZXh0ZW5kcyBFbnRpdHlTdG9yZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBpZDogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBwYXJlbnQ6IEVudGl0eVN0b3JlLFxuICAgIHB1YmxpYyByZWFkb25seSByZXBsYXk6IChsYXllcjogRW50aXR5U3RvcmUpID0+IGFueSxcbiAgICBwdWJsaWMgcmVhZG9ubHkgZ3JvdXA6IENhY2hlR3JvdXBcbiAgKSB7XG4gICAgc3VwZXIocGFyZW50LnBvbGljaWVzLCBncm91cCk7XG4gICAgcmVwbGF5KHRoaXMpO1xuICB9XG5cbiAgcHVibGljIGFkZExheWVyKGxheWVySWQ6IHN0cmluZywgcmVwbGF5OiAobGF5ZXI6IEVudGl0eVN0b3JlKSA9PiBhbnkpOiBMYXllciB7XG4gICAgcmV0dXJuIG5ldyBMYXllcihsYXllcklkLCB0aGlzLCByZXBsYXksIHRoaXMuZ3JvdXApO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZUxheWVyKGxheWVySWQ6IHN0cmluZyk6IEVudGl0eVN0b3JlIHtcbiAgICAvLyBSZW1vdmUgYWxsIGluc3RhbmNlcyBvZiB0aGUgZ2l2ZW4gaWQsIG5vdCBqdXN0IHRoZSBmaXJzdCBvbmUuXG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5wYXJlbnQucmVtb3ZlTGF5ZXIobGF5ZXJJZCk7XG5cbiAgICBpZiAobGF5ZXJJZCA9PT0gdGhpcy5pZCkge1xuICAgICAgaWYgKHRoaXMuZ3JvdXAuY2FjaGluZykge1xuICAgICAgICAvLyBEaXJ0eSBldmVyeSBJRCB3ZSdyZSByZW1vdmluZy4gVGVjaG5pY2FsbHkgd2UgbWlnaHQgYmUgYWJsZSB0byBhdm9pZFxuICAgICAgICAvLyBkaXJ0eWluZyBmaWVsZHMgdGhhdCBoYXZlIHZhbHVlcyBpbiBoaWdoZXIgbGF5ZXJzLCBidXQgd2UgZG9uJ3QgaGF2ZVxuICAgICAgICAvLyBlYXN5IGFjY2VzcyB0byBoaWdoZXIgbGF5ZXJzIGhlcmUsIGFuZCB3ZSdyZSBhYm91dCB0byByZWNyZWF0ZSB0aG9zZVxuICAgICAgICAvLyBsYXllcnMgYW55d2F5IChzZWUgcGFyZW50LmFkZExheWVyIGJlbG93KS5cbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5kYXRhKS5mb3JFYWNoKChkYXRhSWQpID0+IHtcbiAgICAgICAgICBjb25zdCBvd25TdG9yZU9iamVjdCA9IHRoaXMuZGF0YVtkYXRhSWRdO1xuICAgICAgICAgIGNvbnN0IHBhcmVudFN0b3JlT2JqZWN0ID0gcGFyZW50W1wibG9va3VwXCJdKGRhdGFJZCk7XG4gICAgICAgICAgaWYgKCFwYXJlbnRTdG9yZU9iamVjdCkge1xuICAgICAgICAgICAgLy8gVGhlIFN0b3JlT2JqZWN0IGlkZW50aWZpZWQgYnkgZGF0YUlkIHdhcyBkZWZpbmVkIGluIHRoaXMgbGF5ZXJcbiAgICAgICAgICAgIC8vIGJ1dCB3aWxsIGJlIHVuZGVmaW5lZCBpbiB0aGUgcGFyZW50IGxheWVyLCBzbyB3ZSBjYW4gZGVsZXRlIHRoZVxuICAgICAgICAgICAgLy8gd2hvbGUgZW50aXR5IHVzaW5nIHRoaXMuZGVsZXRlKGRhdGFJZCkuIFNpbmNlIHdlJ3JlIGFib3V0IHRvXG4gICAgICAgICAgICAvLyB0aHJvdyB0aGlzIGxheWVyIGF3YXksIHRoZSBvbmx5IGdvYWwgb2YgdGhpcyBkZWxldGlvbiBpcyB0byBkaXJ0eVxuICAgICAgICAgICAgLy8gdGhlIHJlbW92ZWQgZmllbGRzLlxuICAgICAgICAgICAgdGhpcy5kZWxldGUoZGF0YUlkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFvd25TdG9yZU9iamVjdCkge1xuICAgICAgICAgICAgLy8gVGhpcyBsYXllciBoYWQgYW4gZW50cnkgZm9yIGRhdGFJZCBidXQgaXQgd2FzIHVuZGVmaW5lZCwgd2hpY2hcbiAgICAgICAgICAgIC8vIG1lYW5zIHRoZSBlbnRpdHkgd2FzIGRlbGV0ZWQgaW4gdGhpcyBsYXllciwgYW5kIGl0J3MgYWJvdXQgdG9cbiAgICAgICAgICAgIC8vIGJlY29tZSB1bmRlbGV0ZWQgd2hlbiB3ZSByZW1vdmUgdGhpcyBsYXllciwgc28gd2UgbmVlZCB0byBkaXJ0eVxuICAgICAgICAgICAgLy8gYWxsIGZpZWxkcyB0aGF0IGFyZSBhYm91dCB0byBiZSByZWV4cG9zZWQuXG4gICAgICAgICAgICB0aGlzLmdyb3VwLmRpcnR5KGRhdGFJZCwgXCJfX2V4aXN0c1wiKTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHBhcmVudFN0b3JlT2JqZWN0KS5mb3JFYWNoKChzdG9yZUZpZWxkTmFtZSkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmdyb3VwLmRpcnR5KGRhdGFJZCwgc3RvcmVGaWVsZE5hbWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChvd25TdG9yZU9iamVjdCAhPT0gcGFyZW50U3RvcmVPYmplY3QpIHtcbiAgICAgICAgICAgIC8vIElmIG93blN0b3JlT2JqZWN0IGlzIG5vdCBleGFjdGx5IHRoZSBzYW1lIGFzIHBhcmVudFN0b3JlT2JqZWN0LFxuICAgICAgICAgICAgLy8gZGlydHkgYW55IGZpZWxkcyB3aG9zZSB2YWx1ZXMgd2lsbCBjaGFuZ2UgYXMgYSByZXN1bHQgb2YgdGhpc1xuICAgICAgICAgICAgLy8gcmVtb3ZhbC5cbiAgICAgICAgICAgIE9iamVjdC5rZXlzKG93blN0b3JlT2JqZWN0KS5mb3JFYWNoKChzdG9yZUZpZWxkTmFtZSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgIWVxdWFsKFxuICAgICAgICAgICAgICAgICAgb3duU3RvcmVPYmplY3Rbc3RvcmVGaWVsZE5hbWVdLFxuICAgICAgICAgICAgICAgICAgcGFyZW50U3RvcmVPYmplY3Rbc3RvcmVGaWVsZE5hbWVdXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmdyb3VwLmRpcnR5KGRhdGFJZCwgc3RvcmVGaWVsZE5hbWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyZW50O1xuICAgIH1cblxuICAgIC8vIE5vIGNoYW5nZXMgYXJlIG5lY2Vzc2FyeSBpZiB0aGUgcGFyZW50IGNoYWluIHJlbWFpbnMgaWRlbnRpY2FsLlxuICAgIGlmIChwYXJlbnQgPT09IHRoaXMucGFyZW50KSByZXR1cm4gdGhpcztcblxuICAgIC8vIFJlY3JlYXRlIHRoaXMgbGF5ZXIgb24gdG9wIG9mIHRoZSBuZXcgcGFyZW50LlxuICAgIHJldHVybiBwYXJlbnQuYWRkTGF5ZXIodGhpcy5pZCwgdGhpcy5yZXBsYXkpO1xuICB9XG5cbiAgcHVibGljIHRvT2JqZWN0KCk6IE5vcm1hbGl6ZWRDYWNoZU9iamVjdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMucGFyZW50LnRvT2JqZWN0KCksXG4gICAgICAuLi50aGlzLmRhdGEsXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBmaW5kQ2hpbGRSZWZJZHMoZGF0YUlkOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB0cnVlPiB7XG4gICAgY29uc3QgZnJvbVBhcmVudCA9IHRoaXMucGFyZW50LmZpbmRDaGlsZFJlZklkcyhkYXRhSWQpO1xuICAgIHJldHVybiBoYXNPd24uY2FsbCh0aGlzLmRhdGEsIGRhdGFJZCkgP1xuICAgICAgICB7XG4gICAgICAgICAgLi4uZnJvbVBhcmVudCxcbiAgICAgICAgICAuLi5zdXBlci5maW5kQ2hpbGRSZWZJZHMoZGF0YUlkKSxcbiAgICAgICAgfVxuICAgICAgOiBmcm9tUGFyZW50O1xuICB9XG5cbiAgcHVibGljIGdldFN0b3JhZ2UoKTogU3RvcmFnZVR5cGUge1xuICAgIGxldCBwOiBFbnRpdHlTdG9yZSA9IHRoaXMucGFyZW50O1xuICAgIHdoaWxlICgocCBhcyBMYXllcikucGFyZW50KSBwID0gKHAgYXMgTGF5ZXIpLnBhcmVudDtcbiAgICByZXR1cm4gcC5nZXRTdG9yYWdlLmFwcGx5KFxuICAgICAgcCxcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIGFyZ3VtZW50c1xuICAgICk7XG4gIH1cbn1cblxuLy8gUmVwcmVzZW50cyBhIExheWVyIHBlcm1hbmVudGx5IGluc3RhbGxlZCBqdXN0IGFib3ZlIHRoZSBSb290LCB3aGljaCBhbGxvd3Ncbi8vIHJlYWRpbmcgb3B0aW1pc3RpY2FsbHkgKGFuZCByZWdpc3RlcmluZyBvcHRpbWlzdGljIGRlcGVuZGVuY2llcykgZXZlbiB3aGVuXG4vLyBubyBvcHRpbWlzdGljIGxheWVycyBhcmUgY3VycmVudGx5IGFjdGl2ZS4gVGhlIHN0dW1wLmdyb3VwIENhY2hlR3JvdXAgb2JqZWN0XG4vLyBpcyBzaGFyZWQgYnkgYW55L2FsbCBMYXllciBvYmplY3RzIGFkZGVkIG9uIHRvcCBvZiB0aGUgU3R1bXAuXG5jbGFzcyBTdHVtcCBleHRlbmRzIExheWVyIHtcbiAgY29uc3RydWN0b3Iocm9vdDogRW50aXR5U3RvcmUuUm9vdCkge1xuICAgIHN1cGVyKFxuICAgICAgXCJFbnRpdHlTdG9yZS5TdHVtcFwiLFxuICAgICAgcm9vdCxcbiAgICAgICgpID0+IHt9LFxuICAgICAgbmV3IENhY2hlR3JvdXAocm9vdC5ncm91cC5jYWNoaW5nLCByb290Lmdyb3VwKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlTGF5ZXIoKSB7XG4gICAgLy8gTmV2ZXIgcmVtb3ZlIHRoZSBTdHVtcCBsYXllci5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBtZXJnZShvbGRlcjogc3RyaW5nIHwgU3RvcmVPYmplY3QsIG5ld2VyOiBzdHJpbmcgfCBTdG9yZU9iamVjdCkge1xuICAgIC8vIFdlIG5ldmVyIHdhbnQgdG8gd3JpdGUgYW55IGRhdGEgaW50byB0aGUgU3R1bXAsIHNvIHdlIGZvcndhcmQgYW55IG1lcmdlXG4gICAgLy8gY2FsbHMgdG8gdGhlIFJvb3QgaW5zdGVhZC4gQW5vdGhlciBvcHRpb24gaGVyZSB3b3VsZCBiZSB0byB0aHJvdyBhblxuICAgIC8vIGV4Y2VwdGlvbiwgYnV0IHRoZSB0b1JlZmVyZW5jZShvYmplY3QsIHRydWUpIGZ1bmN0aW9uIGNhbiBzb21ldGltZXNcbiAgICAvLyB0cmlnZ2VyIFN0dW1wIHdyaXRlcyAod2hpY2ggdXNlZCB0byBiZSBSb290IHdyaXRlcywgYmVmb3JlIHRoZSBTdHVtcFxuICAgIC8vIGNvbmNlcHQgd2FzIGludHJvZHVjZWQpLlxuICAgIHJldHVybiB0aGlzLnBhcmVudC5tZXJnZShvbGRlciwgbmV3ZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0b3JlT2JqZWN0UmVjb25jaWxlcihcbiAgZXhpc3RpbmdPYmplY3Q6IFN0b3JlT2JqZWN0LFxuICBpbmNvbWluZ09iamVjdDogU3RvcmVPYmplY3QsXG4gIHByb3BlcnR5OiBzdHJpbmcgfCBudW1iZXJcbik6IFN0b3JlVmFsdWUge1xuICBjb25zdCBleGlzdGluZ1ZhbHVlID0gZXhpc3RpbmdPYmplY3RbcHJvcGVydHldO1xuICBjb25zdCBpbmNvbWluZ1ZhbHVlID0gaW5jb21pbmdPYmplY3RbcHJvcGVydHldO1xuICAvLyBXaGVyZXZlciB0aGVyZSBpcyBhIGtleSBjb2xsaXNpb24sIHByZWZlciB0aGUgaW5jb21pbmcgdmFsdWUsIHVubGVzc1xuICAvLyBpdCBpcyBkZWVwbHkgZXF1YWwgdG8gdGhlIGV4aXN0aW5nIHZhbHVlLiBJdCdzIHdvcnRoIGNoZWNraW5nIGRlZXBcbiAgLy8gZXF1YWxpdHkgaGVyZSAoZXZlbiB0aG91Z2ggYmxpbmRseSByZXR1cm5pbmcgaW5jb21pbmcgd291bGQgYmVcbiAgLy8gbG9naWNhbGx5IGNvcnJlY3QpIGJlY2F1c2UgcHJlc2VydmluZyB0aGUgcmVmZXJlbnRpYWwgaWRlbnRpdHkgb2ZcbiAgLy8gZXhpc3RpbmcgZGF0YSBjYW4gcHJldmVudCBuZWVkbGVzcyByZXJlYWRpbmcgYW5kIHJlcmVuZGVyaW5nLlxuICByZXR1cm4gZXF1YWwoZXhpc3RpbmdWYWx1ZSwgaW5jb21pbmdWYWx1ZSkgPyBleGlzdGluZ1ZhbHVlIDogaW5jb21pbmdWYWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRzUmVzdWx0Q2FjaGluZyhzdG9yZTogYW55KTogc3RvcmUgaXMgRW50aXR5U3RvcmUge1xuICAvLyBXaGVuIHJlc3VsdCBjYWNoaW5nIGlzIGRpc2FibGVkLCBzdG9yZS5kZXBlbmQgd2lsbCBiZSBudWxsLlxuICByZXR1cm4gISEoc3RvcmUgaW5zdGFuY2VvZiBFbnRpdHlTdG9yZSAmJiBzdG9yZS5ncm91cC5jYWNoaW5nKTtcbn1cbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF19