UNPKG

@data-client/endpoint

Version:

Declarative Network Interface Definitions

204 lines (194 loc) 33.9 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { consistentSerialize } from './consistentSerialize.js'; import { Values, Array as ArraySchema } from '../schema.js'; const pushMerge = (existing, incoming) => { return [...existing, ...incoming]; }; const unshiftMerge = (existing, incoming) => { return [...incoming, ...existing]; }; const valuesMerge = (existing, incoming) => { return _extends({}, existing, incoming); }; const createArray = value => [...value]; const createValue = value => _extends({}, value); /** * Entities but for Arrays instead of classes * @see https://dataclient.io/rest/api/Collection */ export default class CollectionSchema { addWith(merge, createCollectionFilter) { return CreateAdder(this, merge, createCollectionFilter); } // this adds to any list *in store* that has same members as the urlParams // so fetch(create, { userId: 'bob', completed: true }, data) // would possibly add to {}, {userId: 'bob'}, {completed: true}, {userId: 'bob', completed: true } - but only those already in the store // it ignores keys that start with sort as those are presumed to not filter results createCollectionFilter(...args) { return collectionKey => Object.entries(collectionKey).every(([key, value]) => { var _args$; return this.nonFilterArgumentKeys(key) || // strings are canonical form. See pk() above for value transformation `${args[0][key]}` === value || `${(_args$ = args[1]) == null ? void 0 : _args$[key]}` === value; }); } nonFilterArgumentKeys(key) { return key.startsWith('order'); } constructor(schema, options) { this.schema = Array.isArray(schema) ? new ArraySchema(schema[0]) : schema; if (!options) { this.argsKey = params => _extends({}, params); } else { if ('nestKey' in options) { this.nestKey = options.nestKey; } else if ('argsKey' in options) { this.argsKey = options.argsKey; } else { this.argsKey = params => _extends({}, params); } } this.key = keyFromSchema(this.schema); if (options != null && options.nonFilterArgumentKeys) { const { nonFilterArgumentKeys } = options; if (typeof nonFilterArgumentKeys === 'function') { this.nonFilterArgumentKeys = nonFilterArgumentKeys; } else if (nonFilterArgumentKeys instanceof RegExp) { this.nonFilterArgumentKeys = key => nonFilterArgumentKeys.test(key); } else { this.nonFilterArgumentKeys = key => nonFilterArgumentKeys.includes(key); } } else if (options != null && options.createCollectionFilter) // TODO(breaking): rename to filterCollections this.createCollectionFilter = options.createCollectionFilter.bind(this); // >>>>>>>>>>>>>>CREATION<<<<<<<<<<<<<< if (this.schema instanceof ArraySchema) { this.createIfValid = createArray; this.push = CreateAdder(this, pushMerge); this.unshift = CreateAdder(this, unshiftMerge); } else if (schema instanceof Values) { this.createIfValid = createValue; this.assign = CreateAdder(this, valuesMerge); } } get cacheWith() { return this.schema.schema; } toString() { return this.key; } toJSON() { return { key: this.key, schema: this.schema.schema.toJSON() }; } pk(value, parent, key, args) { const obj = this.argsKey ? this.argsKey(...args) : this.nestKey(parent, key); for (const key in obj) { if (['number', 'boolean'].includes(typeof obj[key])) obj[key] = `${obj[key]}`; } return consistentSerialize(obj); } // >>>>>>>>>>>>>>NORMALIZE<<<<<<<<<<<<<< normalize(input, parent, key, args, visit, addEntity, getEntity, checkLoop) { const normalizedValue = this.schema.normalize(input, parent, key, args, visit, addEntity, getEntity, checkLoop); const id = this.pk(normalizedValue, parent, key, args); addEntity(this, normalizedValue, id); return id; } // always replace merge(existing, incoming) { return incoming; } shouldReorder(existingMeta, incomingMeta, existing, incoming) { return incomingMeta.fetchedAt < existingMeta.fetchedAt; } mergeWithStore(existingMeta, incomingMeta, existing, incoming) { return this.shouldReorder(existingMeta, incomingMeta, existing, incoming) ? this.merge(incoming, existing) : this.merge(existing, incoming); } mergeMetaWithStore(existingMeta, incomingMeta, existing, incoming) { return this.shouldReorder(existingMeta, incomingMeta, existing, incoming) ? existingMeta : incomingMeta; } // >>>>>>>>>>>>>>DENORMALIZE<<<<<<<<<<<<<< queryKey(args, queryKey, getEntity, getIndex) { if (this.argsKey) { const id = this.pk(undefined, undefined, '', args); // ensure this actually has entity or we shouldn't try to use it in our query if (getEntity(this.key, id)) return id; } } denormalize(input, args, unvisit) { return this.schema.denormalize(input, args, unvisit); } } function CreateAdder(collection, merge, createCollectionFilter) { const properties = { merge: { value: merge }, normalize: { value: normalizeCreate }, queryKey: { value: queryKeyCreate } }; if (collection.schema instanceof ArraySchema) { properties.createIfValid = { value: createIfValid }; properties.denormalize = { value: denormalize }; } if (createCollectionFilter) { properties.createCollectionFilter = { value: createCollectionFilter }; } return Object.create(collection, properties); } function queryKeyCreate() {} function normalizeCreate(input, parent, key, args, visit, addEntity, getEntity, checkLoop) { if (process.env.NODE_ENV !== 'production') { // means 'this is a creation endpoint' - so real PKs are not required // this is used by Entity.normalize() to determine whether to allow empty pks // visit instances are created on each normalize call so this will safely be reset visit.creating = true; } const normalizedValue = this.schema.normalize(!(this.schema instanceof ArraySchema) || Array.isArray(input) ? input : [input], parent, key, args, visit, addEntity, getEntity, checkLoop); // parent is args when not nested const filterCollections = this.createCollectionFilter(...args); // add to any collections that match this const entities = getEntity(this.key); if (entities) Object.keys(entities).forEach(collectionPk => { if (!filterCollections(JSON.parse(collectionPk))) return; addEntity(this, normalizedValue, collectionPk); }); return normalizedValue; } function createIfValid(value) { return Array.isArray(value) ? [...value] : _extends({}, value); } // only for arrays function denormalize(input, args, unvisit) { return Array.isArray(input) ? this.schema.denormalize(input, args, unvisit) : this.schema.denormalize([input], args, unvisit)[0]; } /** * We call schema.denormalize and schema.normalize directly * instead of visit/unvisit as we are not operating on new data * so the additional checks in those methods are redundant */ function keyFromSchema(schema) { if (schema instanceof ArraySchema) { // this assumes the definition of Array/Values is Entity return `[${schema.schemaKey()}]`; } else if (schema instanceof Values) { return `{${schema.schemaKey()}}`; } return `(${schema.schemaKey()})`; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb25zaXN0ZW50U2VyaWFsaXplIiwiVmFsdWVzIiwiQXJyYXkiLCJBcnJheVNjaGVtYSIsInB1c2hNZXJnZSIsImV4aXN0aW5nIiwiaW5jb21pbmciLCJ1bnNoaWZ0TWVyZ2UiLCJ2YWx1ZXNNZXJnZSIsIl9leHRlbmRzIiwiY3JlYXRlQXJyYXkiLCJ2YWx1ZSIsImNyZWF0ZVZhbHVlIiwiQ29sbGVjdGlvblNjaGVtYSIsImFkZFdpdGgiLCJtZXJnZSIsImNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXIiLCJDcmVhdGVBZGRlciIsImFyZ3MiLCJjb2xsZWN0aW9uS2V5IiwiT2JqZWN0IiwiZW50cmllcyIsImV2ZXJ5Iiwia2V5IiwiX2FyZ3MkIiwibm9uRmlsdGVyQXJndW1lbnRLZXlzIiwic3RhcnRzV2l0aCIsImNvbnN0cnVjdG9yIiwic2NoZW1hIiwib3B0aW9ucyIsImlzQXJyYXkiLCJhcmdzS2V5IiwicGFyYW1zIiwibmVzdEtleSIsImtleUZyb21TY2hlbWEiLCJSZWdFeHAiLCJ0ZXN0IiwiaW5jbHVkZXMiLCJiaW5kIiwiY3JlYXRlSWZWYWxpZCIsInB1c2giLCJ1bnNoaWZ0IiwiYXNzaWduIiwiY2FjaGVXaXRoIiwidG9TdHJpbmciLCJ0b0pTT04iLCJwayIsInBhcmVudCIsIm9iaiIsIm5vcm1hbGl6ZSIsImlucHV0IiwidmlzaXQiLCJhZGRFbnRpdHkiLCJnZXRFbnRpdHkiLCJjaGVja0xvb3AiLCJub3JtYWxpemVkVmFsdWUiLCJpZCIsInNob3VsZFJlb3JkZXIiLCJleGlzdGluZ01ldGEiLCJpbmNvbWluZ01ldGEiLCJmZXRjaGVkQXQiLCJtZXJnZVdpdGhTdG9yZSIsIm1lcmdlTWV0YVdpdGhTdG9yZSIsInF1ZXJ5S2V5IiwiZ2V0SW5kZXgiLCJ1bmRlZmluZWQiLCJkZW5vcm1hbGl6ZSIsInVudmlzaXQiLCJjb2xsZWN0aW9uIiwicHJvcGVydGllcyIsIm5vcm1hbGl6ZUNyZWF0ZSIsInF1ZXJ5S2V5Q3JlYXRlIiwiY3JlYXRlIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwiY3JlYXRpbmciLCJmaWx0ZXJDb2xsZWN0aW9ucyIsImVudGl0aWVzIiwia2V5cyIsImZvckVhY2giLCJjb2xsZWN0aW9uUGsiLCJKU09OIiwicGFyc2UiLCJzY2hlbWFLZXkiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NoZW1hcy9Db2xsZWN0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbnNpc3RlbnRTZXJpYWxpemUgfSBmcm9tICcuL2NvbnNpc3RlbnRTZXJpYWxpemUuanMnO1xuaW1wb3J0IHsgQ2hlY2tMb29wLCBHZXRFbnRpdHksIFBvbHltb3JwaGljSW50ZXJmYWNlIH0gZnJvbSAnLi4vaW50ZXJmYWNlLmpzJztcbmltcG9ydCB7IFZhbHVlcywgQXJyYXkgYXMgQXJyYXlTY2hlbWEgfSBmcm9tICcuLi9zY2hlbWEuanMnO1xuaW1wb3J0IHR5cGUgeyBEZWZhdWx0QXJncywgRW50aXR5SW50ZXJmYWNlIH0gZnJvbSAnLi4vc2NoZW1hVHlwZXMuanMnO1xuXG5jb25zdCBwdXNoTWVyZ2UgPSAoZXhpc3Rpbmc6IGFueSwgaW5jb21pbmc6IGFueSkgPT4ge1xuICByZXR1cm4gWy4uLmV4aXN0aW5nLCAuLi5pbmNvbWluZ107XG59O1xuY29uc3QgdW5zaGlmdE1lcmdlID0gKGV4aXN0aW5nOiBhbnksIGluY29taW5nOiBhbnkpID0+IHtcbiAgcmV0dXJuIFsuLi5pbmNvbWluZywgLi4uZXhpc3RpbmddO1xufTtcbmNvbnN0IHZhbHVlc01lcmdlID0gKGV4aXN0aW5nOiBhbnksIGluY29taW5nOiBhbnkpID0+IHtcbiAgcmV0dXJuIHsgLi4uZXhpc3RpbmcsIC4uLmluY29taW5nIH07XG59O1xuY29uc3QgY3JlYXRlQXJyYXkgPSAodmFsdWU6IGFueSkgPT4gWy4uLnZhbHVlXTtcbmNvbnN0IGNyZWF0ZVZhbHVlID0gKHZhbHVlOiBhbnkpID0+ICh7IC4uLnZhbHVlIH0pO1xuXG4vKipcbiAqIEVudGl0aWVzIGJ1dCBmb3IgQXJyYXlzIGluc3RlYWQgb2YgY2xhc3Nlc1xuICogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vcmVzdC9hcGkvQ29sbGVjdGlvblxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xsZWN0aW9uU2NoZW1hPFxuICBTIGV4dGVuZHMgUG9seW1vcnBoaWNJbnRlcmZhY2UgPSBhbnksXG4gIEFyZ3MgZXh0ZW5kcyBhbnlbXSA9IERlZmF1bHRBcmdzLFxuICBQYXJlbnQgPSBhbnksXG4+IHtcbiAgZGVjbGFyZSBwcm90ZWN0ZWQgbmVzdEtleTogKHBhcmVudDogYW55LCBrZXk6IHN0cmluZykgPT4gUmVjb3JkPHN0cmluZywgYW55PjtcblxuICBkZWNsYXJlIHByb3RlY3RlZCBhcmdzS2V5PzogKC4uLmFyZ3M6IGFueSkgPT4gUmVjb3JkPHN0cmluZywgYW55PjtcblxuICBkZWNsYXJlIHJlYWRvbmx5IHNjaGVtYTogUztcblxuICBkZWNsYXJlIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuXG4gIGRlY2xhcmUgcHVzaDogUyBleHRlbmRzIEFycmF5U2NoZW1hPGFueT4gPyBDb2xsZWN0aW9uU2NoZW1hPFMsIEFyZ3MsIFBhcmVudD5cbiAgOiB1bmRlZmluZWQ7XG5cbiAgZGVjbGFyZSB1bnNoaWZ0OiBTIGV4dGVuZHMgQXJyYXlTY2hlbWE8YW55PiA/XG4gICAgQ29sbGVjdGlvblNjaGVtYTxTLCBBcmdzLCBQYXJlbnQ+XG4gIDogdW5kZWZpbmVkO1xuXG4gIGRlY2xhcmUgYXNzaWduOiBTIGV4dGVuZHMgVmFsdWVzPGFueT4gPyBDb2xsZWN0aW9uU2NoZW1hPFMsIEFyZ3MsIFBhcmVudD5cbiAgOiB1bmRlZmluZWQ7XG5cbiAgYWRkV2l0aDxQIGV4dGVuZHMgYW55W10gPSBBcmdzPihcbiAgICBtZXJnZTogKGV4aXN0aW5nOiBhbnksIGluY29taW5nOiBhbnkpID0+IGFueSxcbiAgICBjcmVhdGVDb2xsZWN0aW9uRmlsdGVyPzogKFxuICAgICAgLi4uYXJnczogUFxuICAgICkgPT4gKGNvbGxlY3Rpb25LZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID0+IGJvb2xlYW4sXG4gICk6IENvbGxlY3Rpb25TY2hlbWE8UywgUD4ge1xuICAgIHJldHVybiBDcmVhdGVBZGRlcih0aGlzLCBtZXJnZSwgY3JlYXRlQ29sbGVjdGlvbkZpbHRlcik7XG4gIH1cblxuICAvLyB0aGlzIGFkZHMgdG8gYW55IGxpc3QgKmluIHN0b3JlKiB0aGF0IGhhcyBzYW1lIG1lbWJlcnMgYXMgdGhlIHVybFBhcmFtc1xuICAvLyBzbyBmZXRjaChjcmVhdGUsIHsgdXNlcklkOiAnYm9iJywgY29tcGxldGVkOiB0cnVlIH0sIGRhdGEpXG4gIC8vIHdvdWxkIHBvc3NpYmx5IGFkZCB0byB7fSwge3VzZXJJZDogJ2JvYid9LCB7Y29tcGxldGVkOiB0cnVlfSwge3VzZXJJZDogJ2JvYicsIGNvbXBsZXRlZDogdHJ1ZSB9IC0gYnV0IG9ubHkgdGhvc2UgYWxyZWFkeSBpbiB0aGUgc3RvcmVcbiAgLy8gaXQgaWdub3JlcyBrZXlzIHRoYXQgc3RhcnQgd2l0aCBzb3J0IGFzIHRob3NlIGFyZSBwcmVzdW1lZCB0byBub3QgZmlsdGVyIHJlc3VsdHNcbiAgcHJvdGVjdGVkIGNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXIoLi4uYXJnczogQXJncykge1xuICAgIHJldHVybiAoY29sbGVjdGlvbktleTogUmVjb3JkPHN0cmluZywgc3RyaW5nPikgPT5cbiAgICAgIE9iamVjdC5lbnRyaWVzKGNvbGxlY3Rpb25LZXkpLmV2ZXJ5KFxuICAgICAgICAoW2tleSwgdmFsdWVdKSA9PlxuICAgICAgICAgIHRoaXMubm9uRmlsdGVyQXJndW1lbnRLZXlzKGtleSkgfHxcbiAgICAgICAgICAvLyBzdHJpbmdzIGFyZSBjYW5vbmljYWwgZm9ybS4gU2VlIHBrKCkgYWJvdmUgZm9yIHZhbHVlIHRyYW5zZm9ybWF0aW9uXG4gICAgICAgICAgYCR7YXJnc1swXVtrZXldfWAgPT09IHZhbHVlIHx8XG4gICAgICAgICAgYCR7YXJnc1sxXT8uW2tleV19YCA9PT0gdmFsdWUsXG4gICAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIG5vbkZpbHRlckFyZ3VtZW50S2V5cyhrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBrZXkuc3RhcnRzV2l0aCgnb3JkZXInKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHNjaGVtYTogUywgb3B0aW9ucz86IENvbGxlY3Rpb25PcHRpb25zPEFyZ3MsIFBhcmVudD4pIHtcbiAgICB0aGlzLnNjaGVtYSA9XG4gICAgICBBcnJheS5pc0FycmF5KHNjaGVtYSkgPyAobmV3IEFycmF5U2NoZW1hKHNjaGVtYVswXSkgYXMgYW55KSA6IHNjaGVtYTtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHRoaXMuYXJnc0tleSA9IHBhcmFtcyA9PiAoeyAuLi5wYXJhbXMgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICgnbmVzdEtleScgaW4gb3B0aW9ucykge1xuICAgICAgICAodGhpcyBhcyBhbnkpLm5lc3RLZXkgPSBvcHRpb25zLm5lc3RLZXk7XG4gICAgICB9IGVsc2UgaWYgKCdhcmdzS2V5JyBpbiBvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuYXJnc0tleSA9IG9wdGlvbnMuYXJnc0tleTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYXJnc0tleSA9IHBhcmFtcyA9PiAoeyAuLi5wYXJhbXMgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMua2V5ID0ga2V5RnJvbVNjaGVtYSh0aGlzLnNjaGVtYSk7XG4gICAgaWYgKChvcHRpb25zIGFzIGFueSk/Lm5vbkZpbHRlckFyZ3VtZW50S2V5cykge1xuICAgICAgY29uc3QgeyBub25GaWx0ZXJBcmd1bWVudEtleXMgfSA9IG9wdGlvbnMgYXMge1xuICAgICAgICBub25GaWx0ZXJBcmd1bWVudEtleXM6ICgoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW4pIHwgc3RyaW5nW10gfCBSZWdFeHA7XG4gICAgICB9O1xuICAgICAgaWYgKHR5cGVvZiBub25GaWx0ZXJBcmd1bWVudEtleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5ub25GaWx0ZXJBcmd1bWVudEtleXMgPSBub25GaWx0ZXJBcmd1bWVudEtleXM7XG4gICAgICB9IGVsc2UgaWYgKG5vbkZpbHRlckFyZ3VtZW50S2V5cyBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICB0aGlzLm5vbkZpbHRlckFyZ3VtZW50S2V5cyA9IGtleSA9PiBub25GaWx0ZXJBcmd1bWVudEtleXMudGVzdChrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ub25GaWx0ZXJBcmd1bWVudEtleXMgPSBrZXkgPT4gbm9uRmlsdGVyQXJndW1lbnRLZXlzLmluY2x1ZGVzKGtleSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICgob3B0aW9ucyBhcyBhbnkpPy5jcmVhdGVDb2xsZWN0aW9uRmlsdGVyKVxuICAgICAgLy8gVE9ETyhicmVha2luZyk6IHJlbmFtZSB0byBmaWx0ZXJDb2xsZWN0aW9uc1xuICAgICAgdGhpcy5jcmVhdGVDb2xsZWN0aW9uRmlsdGVyID0gKFxuICAgICAgICBvcHRpb25zIGFzIGFueSBhcyB7XG4gICAgICAgICAgY3JlYXRlQ29sbGVjdGlvbkZpbHRlcjogKFxuICAgICAgICAgICAgLi4uYXJnczogQXJnc1xuICAgICAgICAgICkgPT4gKGNvbGxlY3Rpb25LZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID0+IGJvb2xlYW47XG4gICAgICAgIH1cbiAgICAgICkuY3JlYXRlQ29sbGVjdGlvbkZpbHRlci5iaW5kKHRoaXMpIGFzIGFueTtcblxuICAgIC8vID4+Pj4+Pj4+Pj4+Pj4+Q1JFQVRJT048PDw8PDw8PDw8PDw8PFxuICAgIGlmICh0aGlzLnNjaGVtYSBpbnN0YW5jZW9mIEFycmF5U2NoZW1hKSB7XG4gICAgICB0aGlzLmNyZWF0ZUlmVmFsaWQgPSBjcmVhdGVBcnJheTtcbiAgICAgIHRoaXMucHVzaCA9IENyZWF0ZUFkZGVyKHRoaXMsIHB1c2hNZXJnZSk7XG4gICAgICB0aGlzLnVuc2hpZnQgPSBDcmVhdGVBZGRlcih0aGlzLCB1bnNoaWZ0TWVyZ2UpO1xuICAgIH0gZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgVmFsdWVzKSB7XG4gICAgICB0aGlzLmNyZWF0ZUlmVmFsaWQgPSBjcmVhdGVWYWx1ZTtcbiAgICAgIHRoaXMuYXNzaWduID0gQ3JlYXRlQWRkZXIodGhpcywgdmFsdWVzTWVyZ2UpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBjYWNoZVdpdGgoKTogb2JqZWN0IHtcbiAgICByZXR1cm4gdGhpcy5zY2hlbWEuc2NoZW1hO1xuICB9XG5cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMua2V5O1xuICB9XG5cbiAgdG9KU09OKCkge1xuICAgIHJldHVybiB7XG4gICAgICBrZXk6IHRoaXMua2V5LFxuICAgICAgc2NoZW1hOiB0aGlzLnNjaGVtYS5zY2hlbWEudG9KU09OKCksXG4gICAgfTtcbiAgfVxuXG4gIHBrKHZhbHVlOiBhbnksIHBhcmVudDogYW55LCBrZXk6IHN0cmluZywgYXJnczogcmVhZG9ubHkgYW55W10pIHtcbiAgICBjb25zdCBvYmogPVxuICAgICAgdGhpcy5hcmdzS2V5ID8gdGhpcy5hcmdzS2V5KC4uLmFyZ3MpIDogdGhpcy5uZXN0S2V5KHBhcmVudCwga2V5KTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICAgIGlmIChbJ251bWJlcicsICdib29sZWFuJ10uaW5jbHVkZXModHlwZW9mIG9ialtrZXldKSlcbiAgICAgICAgb2JqW2tleV0gPSBgJHtvYmpba2V5XX1gO1xuICAgIH1cbiAgICByZXR1cm4gY29uc2lzdGVudFNlcmlhbGl6ZShvYmopO1xuICB9XG5cbiAgLy8gPj4+Pj4+Pj4+Pj4+Pj5OT1JNQUxJWkU8PDw8PDw8PDw8PDw8PFxuXG4gIG5vcm1hbGl6ZShcbiAgICBpbnB1dDogYW55LFxuICAgIHBhcmVudDogUGFyZW50LFxuICAgIGtleTogc3RyaW5nLFxuICAgIGFyZ3M6IGFueVtdLFxuICAgIHZpc2l0OiAoLi4uYXJnczogYW55KSA9PiBhbnksXG4gICAgYWRkRW50aXR5OiAoLi4uYXJnczogYW55KSA9PiBhbnksXG4gICAgZ2V0RW50aXR5OiBhbnksXG4gICAgY2hlY2tMb29wOiBhbnksXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3Qgbm9ybWFsaXplZFZhbHVlID0gdGhpcy5zY2hlbWEubm9ybWFsaXplKFxuICAgICAgaW5wdXQsXG4gICAgICBwYXJlbnQsXG4gICAgICBrZXksXG4gICAgICBhcmdzLFxuICAgICAgdmlzaXQsXG4gICAgICBhZGRFbnRpdHksXG4gICAgICBnZXRFbnRpdHksXG4gICAgICBjaGVja0xvb3AsXG4gICAgKTtcbiAgICBjb25zdCBpZCA9IHRoaXMucGsobm9ybWFsaXplZFZhbHVlLCBwYXJlbnQsIGtleSwgYXJncyk7XG5cbiAgICBhZGRFbnRpdHkodGhpcywgbm9ybWFsaXplZFZhbHVlLCBpZCk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLy8gYWx3YXlzIHJlcGxhY2VcbiAgbWVyZ2UoZXhpc3Rpbmc6IGFueSwgaW5jb21pbmc6IGFueSkge1xuICAgIHJldHVybiBpbmNvbWluZztcbiAgfVxuXG4gIHNob3VsZFJlb3JkZXIoXG4gICAgZXhpc3RpbmdNZXRhOiB7IGRhdGU6IG51bWJlcjsgZmV0Y2hlZEF0OiBudW1iZXIgfSxcbiAgICBpbmNvbWluZ01ldGE6IHsgZGF0ZTogbnVtYmVyOyBmZXRjaGVkQXQ6IG51bWJlciB9LFxuICAgIGV4aXN0aW5nOiBhbnksXG4gICAgaW5jb21pbmc6IGFueSxcbiAgKSB7XG4gICAgcmV0dXJuIGluY29taW5nTWV0YS5mZXRjaGVkQXQgPCBleGlzdGluZ01ldGEuZmV0Y2hlZEF0O1xuICB9XG5cbiAgbWVyZ2VXaXRoU3RvcmUoXG4gICAgZXhpc3RpbmdNZXRhOiB7XG4gICAgICBkYXRlOiBudW1iZXI7XG4gICAgICBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgICB9LFxuICAgIGluY29taW5nTWV0YTogeyBkYXRlOiBudW1iZXI7IGZldGNoZWRBdDogbnVtYmVyIH0sXG4gICAgZXhpc3Rpbmc6IGFueSxcbiAgICBpbmNvbWluZzogYW55LFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5zaG91bGRSZW9yZGVyKGV4aXN0aW5nTWV0YSwgaW5jb21pbmdNZXRhLCBleGlzdGluZywgaW5jb21pbmcpID9cbiAgICAgICAgdGhpcy5tZXJnZShpbmNvbWluZywgZXhpc3RpbmcpXG4gICAgICA6IHRoaXMubWVyZ2UoZXhpc3RpbmcsIGluY29taW5nKTtcbiAgfVxuXG4gIG1lcmdlTWV0YVdpdGhTdG9yZShcbiAgICBleGlzdGluZ01ldGE6IHtcbiAgICAgIGZldGNoZWRBdDogbnVtYmVyO1xuICAgICAgZGF0ZTogbnVtYmVyO1xuICAgICAgZXhwaXJlc0F0OiBudW1iZXI7XG4gICAgfSxcbiAgICBpbmNvbWluZ01ldGE6IHsgZmV0Y2hlZEF0OiBudW1iZXI7IGRhdGU6IG51bWJlcjsgZXhwaXJlc0F0OiBudW1iZXIgfSxcbiAgICBleGlzdGluZzogYW55LFxuICAgIGluY29taW5nOiBhbnksXG4gICkge1xuICAgIHJldHVybiB0aGlzLnNob3VsZFJlb3JkZXIoZXhpc3RpbmdNZXRhLCBpbmNvbWluZ01ldGEsIGV4aXN0aW5nLCBpbmNvbWluZykgP1xuICAgICAgICBleGlzdGluZ01ldGFcbiAgICAgIDogaW5jb21pbmdNZXRhO1xuICB9XG5cbiAgLy8gPj4+Pj4+Pj4+Pj4+Pj5ERU5PUk1BTElaRTw8PDw8PDw8PDw8PDw8XG5cbiAgcXVlcnlLZXkoXG4gICAgYXJnczogQXJncyxcbiAgICBxdWVyeUtleTogdW5rbm93bixcbiAgICBnZXRFbnRpdHk6IEdldEVudGl0eSxcbiAgICBnZXRJbmRleDogdW5rbm93bixcbiAgKTogYW55IHtcbiAgICBpZiAodGhpcy5hcmdzS2V5KSB7XG4gICAgICBjb25zdCBpZCA9IHRoaXMucGsodW5kZWZpbmVkLCB1bmRlZmluZWQsICcnLCBhcmdzKTtcbiAgICAgIC8vIGVuc3VyZSB0aGlzIGFjdHVhbGx5IGhhcyBlbnRpdHkgb3Igd2Ugc2hvdWxkbid0IHRyeSB0byB1c2UgaXQgaW4gb3VyIHF1ZXJ5XG4gICAgICBpZiAoZ2V0RW50aXR5KHRoaXMua2V5LCBpZCkpIHJldHVybiBpZDtcbiAgICB9XG4gIH1cblxuICBkZWNsYXJlIGNyZWF0ZUlmVmFsaWQ6ICh2YWx1ZTogYW55KSA9PiBhbnkgfCB1bmRlZmluZWQ7XG5cbiAgZGVub3JtYWxpemUoXG4gICAgaW5wdXQ6IGFueSxcbiAgICBhcmdzOiByZWFkb25seSBhbnlbXSxcbiAgICB1bnZpc2l0OiAoc2NoZW1hOiBhbnksIGlucHV0OiBhbnkpID0+IGFueSxcbiAgKTogUmV0dXJuVHlwZTxTWydkZW5vcm1hbGl6ZSddPiB7XG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hLmRlbm9ybWFsaXplKGlucHV0LCBhcmdzLCB1bnZpc2l0KSBhcyBhbnk7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgQ29sbGVjdGlvbk9wdGlvbnM8XG4gIEFyZ3MgZXh0ZW5kcyBhbnlbXSA9IERlZmF1bHRBcmdzLFxuICBQYXJlbnQgPSBhbnksXG4+ID0gKFxuICB8IHtcbiAgICAgIC8qKiBEZWZpbmVzIGxvb2t1cHMgZm9yIENvbGxlY3Rpb25zIG5lc3RlZCBpbiBvdGhlciBzY2hlbWFzLlxuICAgICAgICpcbiAgICAgICAqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL3Jlc3QvYXBpL0NvbGxlY3Rpb24jbmVzdEtleVxuICAgICAgICovXG4gICAgICBuZXN0S2V5PzogKHBhcmVudDogUGFyZW50LCBrZXk6IHN0cmluZykgPT4gUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICB9XG4gIHwge1xuICAgICAgLyoqIERlZmluZXMgbG9va3VwcyB0b3AtbGV2ZWwgQ29sbGVjdGlvbnMgdXNpbmcgLi4uYXJncy5cbiAgICAgICAqXG4gICAgICAgKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9Db2xsZWN0aW9uI2FyZ3NLZXlcbiAgICAgICAqL1xuICAgICAgYXJnc0tleT86ICguLi5hcmdzOiBBcmdzKSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIH1cbikgJlxuICAoXG4gICAgfCB7XG4gICAgICAgIC8qKiBTZXRzIGEgZGVmYXVsdCBjcmVhdGVDb2xsZWN0aW9uRmlsdGVyIGZvciBhZGRXaXRoKCksIHB1c2gsIHVuc2hpZnQsIGFuZCBhc3NpZ24uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL3Jlc3QvYXBpL0NvbGxlY3Rpb24jY3JlYXRlY29sbGVjdGlvbmZpbHRlclxuICAgICAgICAgKi9cbiAgICAgICAgY3JlYXRlQ29sbGVjdGlvbkZpbHRlcj86IChcbiAgICAgICAgICAuLi5hcmdzOiBBcmdzXG4gICAgICAgICkgPT4gKGNvbGxlY3Rpb25LZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID0+IGJvb2xlYW47XG4gICAgICB9XG4gICAgfCB7XG4gICAgICAgIC8qKiBUZXN0IHRvIGRldGVybWluZSB3aGljaCBhcmcga2V5cyBzaG91bGQgKipub3QqKiBiZSB1c2VkIGZvciBmaWx0ZXJpbmcgcmVzdWx0cy5cbiAgICAgICAgICpcbiAgICAgICAgICogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vcmVzdC9hcGkvQ29sbGVjdGlvbiNub25maWx0ZXJhcmd1bWVudGtleXNcbiAgICAgICAgICovXG4gICAgICAgIG5vbkZpbHRlckFyZ3VtZW50S2V5cz86ICgoa2V5OiBzdHJpbmcpID0+IGJvb2xlYW4pIHwgc3RyaW5nW10gfCBSZWdFeHA7XG4gICAgICB9XG4gICk7XG5cbmZ1bmN0aW9uIENyZWF0ZUFkZGVyPEMgZXh0ZW5kcyBDb2xsZWN0aW9uU2NoZW1hPGFueSwgYW55PiwgUCBleHRlbmRzIGFueVtdPihcbiAgY29sbGVjdGlvbjogQyxcbiAgbWVyZ2U6IChleGlzdGluZzogYW55LCBpbmNvbWluZzogYW55KSA9PiBhbnlbXSxcbiAgY3JlYXRlQ29sbGVjdGlvbkZpbHRlcj86IChcbiAgICAuLi5hcmdzOiBQXG4gICkgPT4gKGNvbGxlY3Rpb25LZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID0+IGJvb2xlYW4sXG4pIHtcbiAgY29uc3QgcHJvcGVydGllczogUHJvcGVydHlEZXNjcmlwdG9yTWFwID0ge1xuICAgIG1lcmdlOiB7IHZhbHVlOiBtZXJnZSB9LFxuICAgIG5vcm1hbGl6ZTogeyB2YWx1ZTogbm9ybWFsaXplQ3JlYXRlIH0sXG4gICAgcXVlcnlLZXk6IHsgdmFsdWU6IHF1ZXJ5S2V5Q3JlYXRlIH0sXG4gIH07XG4gIGlmIChjb2xsZWN0aW9uLnNjaGVtYSBpbnN0YW5jZW9mIEFycmF5U2NoZW1hKSB7XG4gICAgcHJvcGVydGllcy5jcmVhdGVJZlZhbGlkID0geyB2YWx1ZTogY3JlYXRlSWZWYWxpZCB9O1xuICAgIHByb3BlcnRpZXMuZGVub3JtYWxpemUgPSB7IHZhbHVlOiBkZW5vcm1hbGl6ZSB9O1xuICB9XG4gIGlmIChjcmVhdGVDb2xsZWN0aW9uRmlsdGVyKSB7XG4gICAgcHJvcGVydGllcy5jcmVhdGVDb2xsZWN0aW9uRmlsdGVyID0geyB2YWx1ZTogY3JlYXRlQ29sbGVjdGlvbkZpbHRlciB9O1xuICB9XG4gIHJldHVybiBPYmplY3QuY3JlYXRlKGNvbGxlY3Rpb24sIHByb3BlcnRpZXMpO1xufVxuXG5mdW5jdGlvbiBxdWVyeUtleUNyZWF0ZSgpIHt9XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUNyZWF0ZShcbiAgdGhpczogQ29sbGVjdGlvblNjaGVtYTxhbnksIGFueT4sXG4gIGlucHV0OiBhbnksXG4gIHBhcmVudDogYW55LFxuICBrZXk6IHN0cmluZyxcbiAgYXJnczogcmVhZG9ubHkgYW55W10sXG4gIHZpc2l0OiAoKC4uLmFyZ3M6IGFueSkgPT4gYW55KSAmIHsgY3JlYXRpbmc/OiBib29sZWFuIH0sXG4gIGFkZEVudGl0eTogKHNjaGVtYTogYW55LCBwcm9jZXNzZWRFbnRpdHk6IGFueSwgaWQ6IHN0cmluZykgPT4gdm9pZCxcbiAgZ2V0RW50aXR5OiBHZXRFbnRpdHksXG4gIGNoZWNrTG9vcDogQ2hlY2tMb29wLFxuKTogYW55IHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBtZWFucyAndGhpcyBpcyBhIGNyZWF0aW9uIGVuZHBvaW50JyAtIHNvIHJlYWwgUEtzIGFyZSBub3QgcmVxdWlyZWRcbiAgICAvLyB0aGlzIGlzIHVzZWQgYnkgRW50aXR5Lm5vcm1hbGl6ZSgpIHRvIGRldGVybWluZSB3aGV0aGVyIHRvIGFsbG93IGVtcHR5IHBrc1xuICAgIC8vIHZpc2l0IGluc3RhbmNlcyBhcmUgY3JlYXRlZCBvbiBlYWNoIG5vcm1hbGl6ZSBjYWxsIHNvIHRoaXMgd2lsbCBzYWZlbHkgYmUgcmVzZXRcbiAgICB2aXNpdC5jcmVhdGluZyA9IHRydWU7XG4gIH1cbiAgY29uc3Qgbm9ybWFsaXplZFZhbHVlID0gdGhpcy5zY2hlbWEubm9ybWFsaXplKFxuICAgICEodGhpcy5zY2hlbWEgaW5zdGFuY2VvZiBBcnJheVNjaGVtYSkgfHwgQXJyYXkuaXNBcnJheShpbnB1dCkgP1xuICAgICAgaW5wdXRcbiAgICA6IFtpbnB1dF0sXG4gICAgcGFyZW50LFxuICAgIGtleSxcbiAgICBhcmdzLFxuICAgIHZpc2l0LFxuICAgIGFkZEVudGl0eSxcbiAgICBnZXRFbnRpdHksXG4gICAgY2hlY2tMb29wLFxuICApO1xuICAvLyBwYXJlbnQgaXMgYXJncyB3aGVuIG5vdCBuZXN0ZWRcbiAgY29uc3QgZmlsdGVyQ29sbGVjdGlvbnMgPSAodGhpcy5jcmVhdGVDb2xsZWN0aW9uRmlsdGVyIGFzIGFueSkoLi4uYXJncyk7XG4gIC8vIGFkZCB0byBhbnkgY29sbGVjdGlvbnMgdGhhdCBtYXRjaCB0aGlzXG4gIGNvbnN0IGVudGl0aWVzID0gZ2V0RW50aXR5KHRoaXMua2V5KTtcbiAgaWYgKGVudGl0aWVzKVxuICAgIE9iamVjdC5rZXlzKGVudGl0aWVzKS5mb3JFYWNoKGNvbGxlY3Rpb25QayA9PiB7XG4gICAgICBpZiAoIWZpbHRlckNvbGxlY3Rpb25zKEpTT04ucGFyc2UoY29sbGVjdGlvblBrKSkpIHJldHVybjtcbiAgICAgIGFkZEVudGl0eSh0aGlzLCBub3JtYWxpemVkVmFsdWUsIGNvbGxlY3Rpb25Qayk7XG4gICAgfSk7XG4gIHJldHVybiBub3JtYWxpemVkVmFsdWUgYXMgYW55O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVJZlZhbGlkKHZhbHVlOiBvYmplY3QpOiBhbnkgfCB1bmRlZmluZWQge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBbLi4udmFsdWVdIDogeyAuLi52YWx1ZSB9O1xufVxuXG4vLyBvbmx5IGZvciBhcnJheXNcbmZ1bmN0aW9uIGRlbm9ybWFsaXplKFxuICB0aGlzOiBDb2xsZWN0aW9uU2NoZW1hPGFueSwgYW55PixcbiAgaW5wdXQ6IGFueSxcbiAgYXJnczogcmVhZG9ubHkgYW55W10sXG4gIHVudmlzaXQ6IChzY2hlbWE6IGFueSwgaW5wdXQ6IGFueSkgPT4gYW55LFxuKTogYW55IHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoaW5wdXQpID9cbiAgICAgICh0aGlzLnNjaGVtYS5kZW5vcm1hbGl6ZShpbnB1dCwgYXJncywgdW52aXNpdCkgYXMgYW55KVxuICAgIDogKHRoaXMuc2NoZW1hLmRlbm9ybWFsaXplKFtpbnB1dF0sIGFyZ3MsIHVudmlzaXQpWzBdIGFzIGFueSk7XG59XG4vKipcbiAqIFdlIGNhbGwgc2NoZW1hLmRlbm9ybWFsaXplIGFuZCBzY2hlbWEubm9ybWFsaXplIGRpcmVjdGx5XG4gKiBpbnN0ZWFkIG9mIHZpc2l0L3VudmlzaXQgYXMgd2UgYXJlIG5vdCBvcGVyYXRpbmcgb24gbmV3IGRhdGFcbiAqIHNvIHRoZSBhZGRpdGlvbmFsIGNoZWNrcyBpbiB0aG9zZSBtZXRob2RzIGFyZSByZWR1bmRhbnRcbiAqL1xuXG5mdW5jdGlvbiBrZXlGcm9tU2NoZW1hKHNjaGVtYTogUG9seW1vcnBoaWNJbnRlcmZhY2UpIHtcbiAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIEFycmF5U2NoZW1hKSB7XG4gICAgLy8gdGhpcyBhc3N1bWVzIHRoZSBkZWZpbml0aW9uIG9mIEFycmF5L1ZhbHVlcyBpcyBFbnRpdHlcbiAgICByZXR1cm4gYFske3NjaGVtYS5zY2hlbWFLZXkoKX1dYDtcbiAgfSBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBWYWx1ZXMpIHtcbiAgICByZXR1cm4gYHske3NjaGVtYS5zY2hlbWFLZXkoKX19YDtcbiAgfVxuICByZXR1cm4gYCgke3NjaGVtYS5zY2hlbWFLZXkoKX0pYDtcbn1cbiJdLCJtYXBwaW5ncyI6IjtBQUFBLFNBQVNBLG1CQUFtQixRQUFRLDBCQUEwQjtBQUU5RCxTQUFTQyxNQUFNLEVBQUVDLEtBQUssSUFBSUMsV0FBVyxRQUFRLGNBQWM7QUFHM0QsTUFBTUMsU0FBUyxHQUFHQSxDQUFDQyxRQUFhLEVBQUVDLFFBQWEsS0FBSztFQUNsRCxPQUFPLENBQUMsR0FBR0QsUUFBUSxFQUFFLEdBQUdDLFFBQVEsQ0FBQztBQUNuQyxDQUFDO0FBQ0QsTUFBTUMsWUFBWSxHQUFHQSxDQUFDRixRQUFhLEVBQUVDLFFBQWEsS0FBSztFQUNyRCxPQUFPLENBQUMsR0FBR0EsUUFBUSxFQUFFLEdBQUdELFFBQVEsQ0FBQztBQUNuQyxDQUFDO0FBQ0QsTUFBTUcsV0FBVyxHQUFHQSxDQUFDSCxRQUFhLEVBQUVDLFFBQWEsS0FBSztFQUNwRCxPQUFBRyxRQUFBLEtBQVlKLFFBQVEsRUFBS0MsUUFBUTtBQUNuQyxDQUFDO0FBQ0QsTUFBTUksV0FBVyxHQUFJQyxLQUFVLElBQUssQ0FBQyxHQUFHQSxLQUFLLENBQUM7QUFDOUMsTUFBTUMsV0FBVyxHQUFJRCxLQUFVLElBQUFGLFFBQUEsS0FBV0UsS0FBSyxDQUFHOztBQUVsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsTUFBTUUsZ0JBQWdCLENBSW5DO0VBbUJBQyxPQUFPQSxDQUNMQyxLQUE0QyxFQUM1Q0Msc0JBRXVELEVBQy9CO0lBQ3hCLE9BQU9DLFdBQVcsQ0FBQyxJQUFJLEVBQUVGLEtBQUssRUFBRUMsc0JBQXNCLENBQUM7RUFDekQ7O0VBRUE7RUFDQTtFQUNBO0VB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