UNPKG

@tsclean/core

Version:

Plugin for API Rest Full development, based on Clean Architecture, IoC and Dependency Injection.

301 lines 45.4 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstanceWrapper = exports.INSTANCE_ID_SYMBOL = exports.INSTANCE_METADATA_SYMBOL = void 0; const iterare_1 = require("iterare"); const constants_1 = require("./constants"); const contracts_1 = require("../../contracts"); const utils_1 = require("../../utils"); const services_1 = require("../../services"); exports.INSTANCE_METADATA_SYMBOL = Symbol.for('instance_metadata:cache'); exports.INSTANCE_ID_SYMBOL = Symbol.for('instance_metadata:id'); class InstanceWrapper { constructor(metadata = {}) { this.isAlias = false; this.scope = contracts_1.Scope.DEFAULT; this.values = new WeakMap(); this[_a] = {}; this[exports.INSTANCE_ID_SYMBOL] = (0, utils_1.randomStringGenerator)(); this.initialize(metadata); } get id() { return this[exports.INSTANCE_ID_SYMBOL]; } set instance(value) { this.values.set(constants_1.STATIC_CONTEXT, { instance: value }); } get instance() { const instancePerContext = this.getInstanceByContextId(constants_1.STATIC_CONTEXT); return instancePerContext.instance; } get isNotMetatype() { const isFactory = this.metaType && !(0, utils_1.isNil)(this.inject); return !this.metaType || isFactory; } get isTransient() { return this.scope === contracts_1.Scope.TRANSIENT; } getInstanceByContextId(contextId, inquirerId) { if (this.scope === contracts_1.Scope.TRANSIENT && inquirerId) { return this.getInstanceByInquirerId(contextId, inquirerId); } const instancePerContext = this.values.get(contextId); return instancePerContext ? instancePerContext : this.cloneStaticInstance(contextId); } getInstanceByInquirerId(contextId, inquirerId) { let collectionPerContext = this.transientMap.get(inquirerId); if (!collectionPerContext) { collectionPerContext = new WeakMap(); this.transientMap.set(inquirerId, collectionPerContext); } const instancePerContext = collectionPerContext.get(contextId); return instancePerContext ? instancePerContext : this.cloneTransientInstance(contextId, inquirerId); } setInstanceByContextId(contextId, value, inquirerId) { if (this.scope === contracts_1.Scope.TRANSIENT && inquirerId) { return this.setInstanceByInquirerId(contextId, inquirerId, value); } this.values.set(contextId, value); } setInstanceByInquirerId(contextId, inquirerId, value) { let collection = this.transientMap.get(inquirerId); if (!collection) { collection = new WeakMap(); this.transientMap.set(inquirerId, collection); } collection.set(contextId, value); } addCtorMetadata(index, wrapper) { if (!this[exports.INSTANCE_METADATA_SYMBOL].dependencies) { this[exports.INSTANCE_METADATA_SYMBOL].dependencies = []; } this[exports.INSTANCE_METADATA_SYMBOL].dependencies[index] = wrapper; } getCtorMetadata() { return this[exports.INSTANCE_METADATA_SYMBOL].dependencies; } addPropertiesMetadata(key, wrapper) { if (!this[exports.INSTANCE_METADATA_SYMBOL].properties) { this[exports.INSTANCE_METADATA_SYMBOL].properties = []; } this[exports.INSTANCE_METADATA_SYMBOL].properties.push({ key, wrapper }); } getPropertiesMetadata() { return this[exports.INSTANCE_METADATA_SYMBOL].properties; } addEnhancerMetadata(wrapper) { if (!this[exports.INSTANCE_METADATA_SYMBOL].enhancers) { this[exports.INSTANCE_METADATA_SYMBOL].enhancers = []; } this[exports.INSTANCE_METADATA_SYMBOL].enhancers.push(wrapper); } getEnhancersMetadata() { return this[exports.INSTANCE_METADATA_SYMBOL].enhancers; } isDependencyTreeDurable(lookupRegistry = []) { if (!(0, utils_1.isUndefined)(this.isTreeDurable)) { return this.isTreeDurable; } if (this.scope === contracts_1.Scope.REQUEST) { this.isTreeDurable = this.durable === undefined ? false : this.durable; if (this.isTreeDurable) { this.printIntrospectedAsDurable(); } return this.isTreeDurable; } const isStatic = this.isDependencyTreeStatic(); if (isStatic) { return false; } const isTreeNonDurable = this.introspectDepsAttribute((collection, registry) => collection.some((item) => !item.isDependencyTreeStatic() && !item.isDependencyTreeDurable(registry)), lookupRegistry); this.isTreeDurable = !isTreeNonDurable; if (this.isTreeDurable) { this.printIntrospectedAsDurable(); } return this.isTreeDurable; } introspectDepsAttribute(callback, lookupRegistry = []) { if (lookupRegistry.includes(this[exports.INSTANCE_ID_SYMBOL])) { return false; } lookupRegistry = lookupRegistry.concat(this[exports.INSTANCE_ID_SYMBOL]); const { dependencies, properties, enhancers } = this[exports.INSTANCE_METADATA_SYMBOL]; let introspectionResult = dependencies ? callback(dependencies, lookupRegistry) : false; if (introspectionResult || !(properties || enhancers)) { return introspectionResult; } introspectionResult = properties ? callback(properties.map(item => item.wrapper), lookupRegistry) : false; if (introspectionResult || !enhancers) { return introspectionResult; } return enhancers ? callback(enhancers, lookupRegistry) : false; } isDependencyTreeStatic(lookupRegistry = []) { if (!(0, utils_1.isUndefined)(this.isTreeStatic)) { return this.isTreeStatic; } if (this.scope === contracts_1.Scope.REQUEST) { this.isTreeStatic = false; return this.isTreeStatic; } if (lookupRegistry.includes(this[exports.INSTANCE_ID_SYMBOL])) { return true; } lookupRegistry = lookupRegistry.concat(this[exports.INSTANCE_ID_SYMBOL]); const { dependencies, properties, enhancers } = this[exports.INSTANCE_METADATA_SYMBOL]; let isStatic = (dependencies && this.isWrapperListStatic(dependencies, lookupRegistry)) || !dependencies; if (!isStatic || !(properties || enhancers)) { this.isTreeStatic = isStatic; return this.isTreeStatic; } const propertiesHosts = (properties || []).map(item => item.wrapper); isStatic = isStatic && this.isWrapperListStatic(propertiesHosts, lookupRegistry); if (!isStatic || !enhancers) { this.isTreeStatic = isStatic; return this.isTreeStatic; } this.isTreeStatic = this.isWrapperListStatic(enhancers, lookupRegistry); return this.isTreeStatic; } cloneStaticInstance(contextId) { const staticInstance = this.getInstanceByContextId(constants_1.STATIC_CONTEXT); if (this.isDependencyTreeStatic()) { return staticInstance; } const instancePerContext = Object.assign(Object.assign({}, staticInstance), { instance: undefined, isResolved: false, isPending: false }); if (this.isNewable()) { instancePerContext.instance = Object.create(this.metaType.prototype); } this.setInstanceByContextId(contextId, instancePerContext); return instancePerContext; } cloneTransientInstance(contextId, inquirerId) { const staticInstance = this.getInstanceByContextId(constants_1.STATIC_CONTEXT); const instancePerContext = Object.assign(Object.assign({}, staticInstance), { instance: undefined, isResolved: false, isPending: false }); if (this.isNewable()) { instancePerContext.instance = Object.create(this.metaType.prototype); } this.setInstanceByInquirerId(contextId, inquirerId, instancePerContext); return instancePerContext; } createPrototype(contextId) { const host = this.getInstanceByContextId(contextId); if (!this.isNewable() || host.isResolved) { return; } return Object.create(this.metaType.prototype); } isInRequestScope(contextId, inquirer) { const isDependencyTreeStatic = this.isDependencyTreeStatic(); return (!isDependencyTreeStatic && contextId !== constants_1.STATIC_CONTEXT && (!this.isTransient || (this.isTransient && !!inquirer))); } isLazyTransient(contextId, inquirer) { const isInquirerRequestScoped = inquirer && !inquirer.isDependencyTreeStatic(); return (this.isDependencyTreeStatic() && contextId !== constants_1.STATIC_CONTEXT && this.isTransient && isInquirerRequestScoped); } isExplicitlyRequested(contextId, inquirer) { const isSelfRequested = inquirer === this; return (this.isDependencyTreeStatic() && contextId !== constants_1.STATIC_CONTEXT && (isSelfRequested || (inquirer && inquirer.scope === contracts_1.Scope.TRANSIENT))); } isStatic(contextId, inquirer) { const isInquirerRequestScoped = inquirer && !inquirer.isDependencyTreeStatic(); const isStaticTransient = this.isTransient && !isInquirerRequestScoped; return (this.isDependencyTreeStatic() && contextId === constants_1.STATIC_CONTEXT && (!this.isTransient || (isStaticTransient && !!inquirer && !inquirer.isTransient))); } getStaticTransientInstances() { if (!this.transientMap) { return []; } const instances = [...this.transientMap.values()]; return (0, iterare_1.iterate)(instances) .map(item => item.get(constants_1.STATIC_CONTEXT)) .filter(item => !!item) .toArray(); } mergeWith(provider) { if (!(0, utils_1.isUndefined)(provider.useValue)) { this.metaType = null; this.inject = null; this.scope = contracts_1.Scope.DEFAULT; this.setInstanceByContextId(constants_1.STATIC_CONTEXT, { instance: provider.useValue, isResolved: true, isPending: false }); } else if (provider.useClass) { this.inject = null; this.metaType = provider.useClass; } else if (provider.useFactory) { this.metaType = provider.useFactory; this.inject = provider.inject || []; } } isNewable() { return (0, utils_1.isNil)(this.inject) && this.metaType && this.metaType.prototype; } isWrapperListStatic(tree, lookupRegistry) { return tree.every((item) => item.isDependencyTreeStatic(lookupRegistry)); } initialize(metadata) { const { instance, isResolved } = metadata, wrapperPartial = __rest(metadata, ["instance", "isResolved"]); Object.assign(this, wrapperPartial); this.setInstanceByContextId(constants_1.STATIC_CONTEXT, { instance, isResolved }); this.scope === contracts_1.Scope.TRANSIENT && (this.transientMap = new Map()); } isDebugMode() { return !!process.env.CLEAN_DEBUG; } printIntrospectedAsDurable() { if (!this.isDebugMode()) { return; } if ((0, utils_1.isString)(this.name)) { InstanceWrapper.logger.log(`${utils_1.clc.cyanBright(this.name)}${utils_1.clc.green(' introspected as ')}${utils_1.clc.magentaBright('durable')}`); } } } exports.InstanceWrapper = InstanceWrapper; _a = exports.INSTANCE_METADATA_SYMBOL; InstanceWrapper.logger = new services_1.Logger(InstanceWrapper.name); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFuY2Utd3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL2luamVjdG9yL2luc3RhbmNlLXdyYXBwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUEscUNBQWlDO0FBQ2pDLDJDQUE0QztBQUU1QywrQ0FPd0I7QUFDeEIsdUNBTW9CO0FBRXBCLDZDQUFzRDtBQUd6QyxRQUFBLHdCQUF3QixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsQ0FBQTtBQUNoRSxRQUFBLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQTtBQStCcEUsTUFBYSxlQUFlO0lBMEIxQixZQUNFLFdBQXlFLEVBQUU7UUF0QjdELFlBQU8sR0FBWSxLQUFLLENBQUE7UUFHakMsVUFBSyxHQUFXLGlCQUFLLENBQUMsT0FBTyxDQUFBO1FBU25CLFdBQU0sR0FBRyxJQUFJLE9BQU8sRUFBb0MsQ0FBQTtRQUN4RCxRQUEwQixHQUEwQixFQUFFLENBQUE7UUFXckUsSUFBSSxDQUFDLDBCQUFrQixDQUFDLEdBQUcsSUFBQSw2QkFBcUIsR0FBRSxDQUFBO1FBQ2xELElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDM0IsQ0FBQztJQUVELElBQUksRUFBRTtRQUNKLE9BQU8sSUFBSSxDQUFDLDBCQUFrQixDQUFDLENBQUE7SUFDakMsQ0FBQztJQUVELElBQUksUUFBUSxDQUFFLEtBQVE7UUFDcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsMEJBQWMsRUFBRSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBQ3RELENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQywwQkFBYyxDQUFDLENBQUE7UUFDdEUsT0FBTyxrQkFBa0IsQ0FBQyxRQUFR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QUFDLENBQUE7UUFFbkMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLDBCQUFjLEVBQUU7WUFDMUMsUUFBUTtZQUNSLFVBQVU7U0FDWCxDQUFDLENBQUE7UUFDRixJQUFJLENBQUMsS0FBSyxLQUFLLGlCQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUE7SUFDbkUsQ0FBQztJQUVPLFdBQVc7UUFDakIsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUE7SUFDbEMsQ0FBQztJQUVPLDBCQUEwQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDeEIsT0FBTTtRQUNSLENBQUM7UUFDRCxJQUFJLElBQUEsZ0JBQVEsRUFBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN4QixlQUFlLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FDeEIsR0FBRyxXQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxXQUFHLENBQUMsS0FBSyxDQUN0QyxtQkFBbUIsQ0FDcEIsR0FBRyxXQUFHLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQ25DLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQzs7QUFoYUgsMENBaWFDO0tBL1ltQixnQ0FBd0I7QUFIM0Isc0JBQU0sR0FBa0IsSUFBSSxpQkFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQUFBbEQsQ0FBa0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpdGVyYXRlIH0gZnJvbSAnaXRlcmFyZSdcbmltcG9ydCB7IFNUQVRJQ19DT05URVhUIH0gZnJvbSAnLi9jb25zdGFudHMnXG5pbXBvcnQgeyBNb2R1bGUgfSBmcm9tICcuL21vZHVsZSdcbmltcG9ydCB7XG4gIENsYXNzUHJvdmlkZXIsXG4gIEZhY3RvcnlQcm92aWRlcixcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIFNjb3BlLFxuICBUeXBlLFxuICBWYWx1ZVByb3ZpZGVyXG59IGZyb20gJy4uLy4uL2NvbnRyYWN0cydcbmltcG9ydCB7XG4gIHJhbmRvbVN0cmluZ0dlbmVyYXRvcixcbiAgaXNOaWwsXG4gIGlzVW5kZWZpbmVkLFxuICBpc1N0cmluZyxcbiAgY2xjXG59IGZyb20gJy4uLy4uL3V0aWxzJ1xuaW1wb3J0IHsgSW5zdGFuY2VUb2tlblR5cGUsIFByb3ZpZGVyVHlwZSB9IGZyb20gJy4uLy4uL3R5cGVzJ1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMnXG5pbXBvcnQgeyBFbmhhbmNlclN1YnR5cGUgfSBmcm9tICcuLi8uLi9oZWxwZXJzJ1xuXG5leHBvcnQgY29uc3QgSU5TVEFOQ0VfTUVUQURBVEFfU1lNQk9MID0gU3ltYm9sLmZvcignaW5zdGFuY2VfbWV0YWRhdGE6Y2FjaGUnKVxuZXhwb3J0IGNvbnN0IElOU1RBTkNFX0lEX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ2luc3RhbmNlX21ldGFkYXRhOmlkJylcblxuZXhwb3J0IGludGVyZmFjZSBIb3N0Q29tcG9uZW50SW5mbyB7XG4gIHRva2VuOiBJbmplY3Rpb25Ub2tlblxuICBpc1RyZWVEdXJhYmxlOiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dElkIHtcbiAgcmVhZG9ubHkgaWQ6IG51bWJlcixcbiAgcGF5bG9hZD86IHVua25vd247XG4gIGdldFBhcmVudD8oaW5mbzogSG9zdENvbXBvbmVudEluZm8pOiBDb250ZXh0SWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5zdGFuY2VQZXJDb250ZXh0PFQ+IHtcbiAgaW5zdGFuY2U6IFRcbiAgaXNSZXNvbHZlZD86IGJvb2xlYW5cbiAgaXNQZW5kaW5nPzogYm9vbGVhblxuICBkb25lUHJvbWlzZT86IFByb21pc2U8dm9pZD5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9wZXJ0eU1ldGFkYXRhIHtcbiAga2V5OiBzdHJpbmdcbiAgd3JhcHBlcjogSW5zdGFuY2VXcmFwcGVyXG59XG5cbmludGVyZmFjZSBJbnN0YW5jZU1ldGFkYXRhU3RvcmUge1xuICBkZXBlbmRlbmNpZXM/OiBJbnN0YW5jZVdyYXBwZXJbXVxuICBwcm9wZXJ0aWVzPzogUHJvcGVydHlNZXRhZGF0YVtdXG4gIGVuaGFuY2Vycz86IEluc3RhbmNlV3JhcHBlcltdXG59XG5cbmV4cG9ydCBjbGFzcyBJbnN0YW5jZVdyYXBwZXI8VCA9IGFueT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogYW55XG4gIHB1YmxpYyByZWFkb25seSB0b2tlbjogSW5zdGFuY2VUb2tlblR5cGVcbiAgcHVibGljIHJlYWRvbmx5IGFzeW5jPzogYm9vbGVhblxuICBwdWJsaWMgcmVhZG9ubHkgaG9zdD86IE1vZHVsZVxuICBwdWJsaWMgcmVhZG9ubHkgaXNBbGlhczogYm9vbGVhbiA9IGZhbHNlXG4gIHB1YmxpYyByZWFkb25seSBzdWJ0eXBlPzogRW5oYW5jZXJTdWJ0eXBlO1xuXG4gIHB1YmxpYyBzY29wZT86IFNjb3BlID0gU2NvcGUuREVGQVVMVFxuICBwdWJsaWMgbWV0YVR5cGU6IFR5cGU8VD4gfCBGdW5jdGlvblxuICBwdWJsaWMgaW5qZWN0PzogKHN0cmluZyB8IHN5bWJvbCB8IEZ1bmN0aW9uIHwgVHlwZTxhbnk+KVtdXG4gIHB1YmxpYyBkdXJhYmxlPzogYm9vbGVhbjtcbiAgcHVibGljIGluaXRUaW1lPzogbnVtYmVyO1xuICBwdWJsaWMgZm9yd2FyZFJlZj86IGJvb2xlYW5cblxuICBwcml2YXRlIHN0YXRpYyBsb2dnZXI6IExvZ2dlclNlcnZpY2UgPSBuZXcgTG9nZ2VyKEluc3RhbmNlV3JhcHBlci5uYW1lKVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgdmFsdWVzID0gbmV3IFdlYWtNYXA8Q29udGV4dElkLCBJbnN0YW5jZVBlckNvbnRleHQ8VD4+KClcbiAgcHJpdmF0ZSByZWFkb25seSBbSU5TVEFOQ0VfTUVUQURBVEFfU1lNQk9MXTogSW5zdGFuY2VNZXRhZGF0YVN0b3JlID0ge31cbiAgcHJpdmF0ZSByZWFkb25seSBbSU5TVEFOQ0VfSURfU1lNQk9MXTogc3RyaW5nXG4gIHByaXZhdGUgdHJhbnNpZW50TWFwPzpcbiAgICB8IE1hcDxzdHJpbmcsIFdlYWtNYXA8Q29udGV4dElkLCBJbnN0YW5jZVBlckNvbnRleHQ8VD4+PlxuICAgIHwgdW5kZWZpbmVkXG4gIHByaXZhdGUgaXNUcmVlU3RhdGljOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gIHByaXZhdGUgaXNUcmVlRHVyYWJsZTogYm9vbGVhbiB8IHVuZGVmaW5lZFxuXG4gIGNvbnN0cnVjdG9yIChcbiAgICBtZXRhZGF0YTogUGFydGlhbDxJbnN0YW5jZVdyYXBwZXI8VD4+ICYgUGFydGlhbDxJbnN0YW5jZVBlckNvbnRleHQ8VD4+ID0ge31cbiAgKSB7XG4gICAgdGhpc1tJTlNUQU5DRV9JRF9TWU1CT0xdID0gcmFuZG9tU3RyaW5nR2VuZXJhdG9yKClcbiAgICB0aGlzLmluaXRpYWxpemUobWV0YWRhdGEpXG4gIH1cblxuICBnZXQgaWQgKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXNbSU5TVEFOQ0VfSURfU1lNQk9MXVxuICB9XG5cbiAgc2V0IGluc3RhbmNlICh2YWx1ZTogVCkge1xuICAgIHRoaXMudmFsdWVzLnNldChTVEFUSUNfQ09OVEVYVCwgeyBpbnN0YW5jZTogdmFsdWUgfSlcbiAgfVxuXG4gIGdldCBpbnN0YW5jZSAoKTogVCB7XG4gICAgY29uc3QgaW5zdGFuY2VQZXJDb250ZXh0ID0gdGhpcy5nZXRJbnN0YW5jZUJ5Q29udGV4dElkKFNUQVRJQ19DT05URVhUKVxuICAgIHJldHVybiBpbnN0YW5jZVBlckNvbnRleHQuaW5zdGFuY2VcbiAgfVxuXG4gIGdldCBpc05vdE1ldGF0eXBlICgpOiBib29sZWFuIHtcbiAgICBjb25zdCBpc0ZhY3RvcnkgPSB0aGlzLm1ldGFUeXBlICYmICFpc05pbCh0aGlzLmluamVjdClcbiAgICByZXR1cm4gIXRoaXMubWV0YVR5cGUgfHwgaXNGYWN0b3J5XG4gIH1cblxuICBnZXQgaXNUcmFuc2llbnQgKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNjb3BlID09PSBTY29wZS5UUkFOU0lFTlRcbiAgfVxuXG4gIHB1YmxpYyBnZXRJbnN0YW5jZUJ5Q29udGV4dElkIChcbiAgICBjb250ZXh0SWQ6IENvbnRleHRJZCxcbiAgICBpbnF1aXJlcklkPzogc3RyaW5nXG4gICk6IEluc3RhbmNlUGVyQ29udGV4dDxUPiB7XG4gICAgaWYgKHRoaXMuc2NvcGUgPT09IFNjb3BlLlRSQU5TSUVOVCAmJiBpbnF1aXJlcklkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRJbnN0YW5jZUJ5SW5xdWlyZXJJZChjb250ZXh0SWQsIGlucXVpcmVySWQpXG4gICAgfVxuICAgIGNvbnN0IGluc3RhbmNlUGVyQ29udGV4dCA9IHRoaXMudmFsdWVzLmdldChjb250ZXh0SWQpXG4gICAgcmV0dXJuIGluc3RhbmNlUGVyQ29udGV4dFxuICAgICAgPyBpbnN0YW5jZVBlckNvbnRleHRcbiAgICAgIDogdGhpcy5jbG9uZVN0YXRpY0luc3RhbmNlKGNvbnRleHRJZClcbiAgfVxuXG4gIHB1YmxpYyBnZXRJbnN0YW5jZUJ5SW5xdWlyZXJJZCAoXG4gICAgY29udGV4dElkOiBDb250ZXh0SWQsXG4gICAgaW5xdWlyZXJJZDogc3RyaW5nXG4gICk6IEluc3RhbmNlUGVyQ29udGV4dDxUPiB7XG4gICAgbGV0IGNvbGxlY3Rpb25QZXJDb250ZXh0ID0gdGhpcy50cmFuc2llbnRNYXAuZ2V0KGlucXVpcmVySWQpXG4gICAgaWYgKCFjb2xsZWN0aW9uUGVyQ29udGV4dCkge1xuICAgICAgY29sbGVjdGlvblBlckNvbnRleHQgPSBuZXcgV2Vha01hcCgpXG4gICAgICB0aGlzLnRyYW5zaWVudE1hcC5zZXQoaW5xdWlyZXJJZCwgY29sbGVjdGlvblBlckNvbnRleHQpXG4gICAgfVxuICAgIGNvbnN0IGluc3RhbmNlUGVyQ29udGV4dCA9IGNvbGxlY3Rpb25QZXJDb250ZXh0LmdldChjb250ZXh0SWQpXG4gICAgcmV0dXJuIGluc3RhbmNlUGVyQ29udGV4dFxuICAgICAgPyBpbnN0YW5jZVBlckNvbnRleHRcbiAgICAgIDogdGhpcy5jbG9uZVRyYW5zaWVudEluc3RhbmNlKGNvbnRleHRJZCwgaW5xdWlyZXJJZClcbiAgfVxuXG4gIHB1YmxpYyBzZXRJbnN0YW5jZUJ5Q29udGV4dElkIChcbiAgICBjb250ZXh0SWQ6IENvbnRleHRJZCxcbiAgICB2YWx1ZTogSW5zdGFuY2VQZXJDb250ZXh0PFQ+LFxuICAgIGlucXVpcmVySWQ/OiBzdHJpbmdcbiAgKSB7XG4gICAgaWYgKHRoaXMuc2NvcGUgPT09IFNjb3BlLlRSQU5TSUVOVCAmJiBpbnF1aXJlcklkKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRJbnN0YW5jZUJ5SW5xdWlyZXJJZChjb250ZXh0SWQsIGlucXVpcmVySWQsIHZhbHVlKVxuICAgIH1cbiAgICB0aGlzLnZhbHVlcy5zZXQoY29udGV4dElkLCB2YWx1ZSlcbiAgfVxuXG4gIHB1YmxpYyBzZXRJbnN0YW5jZUJ5SW5xdWlyZXJJZCAoXG4gICAgY29udGV4dElkOiBDb250ZXh0SWQsXG4gICAgaW5xdWlyZXJJZDogc3RyaW5nLFxuICAgIHZhbHVlOiBJbnN0YW5jZVBlckNvbnRleHQ8VD5cbiAgKSB7XG4gICAgbGV0IGNvbGxlY3Rpb24gPSB0aGlzLnRyYW5zaWVudE1hcC5nZXQoaW5xdWlyZXJJZClcbiAgICBpZiAoIWNvbGxlY3Rpb24pIHtcbiAgICAgIGNvbGxlY3Rpb24gPSBuZXcgV2Vha01hcCgpXG4gICAgICB0aGlzLnRyYW5zaWVudE1hcC5zZXQoaW5xdWlyZXJJZCwgY29sbGVjdGlvbilcbiAgICB9XG4gICAgY29sbGVjdGlvbi5zZXQoY29udGV4dElkLCB2YWx1ZSlcbiAgfVxuXG4gIHB1YmxpYyBhZGRDdG9yTWV0YWRhdGEgKGluZGV4OiBudW1iZXIsIHdyYXBwZXI6IEluc3RhbmNlV3JhcHBlcikge1xuICAgIGlmICghdGhpc1tJTlNUQU5DRV9NRVRBREFUQV9TWU1CT0xdLmRlcGVuZGVuY2llcykge1xuICAgICAgdGhpc1tJTlNUQU5DRV9NRVRBREFUQV9TWU1CT0xdLmRlcGVuZGVuY2llcyA9IFtdXG4gICAgfVxuICAgIHRoaXNbSU5TVEFOQ0VfTUVUQURBVEFfU1lNQk9MXS5kZXBlbmRlbmNpZXNbaW5kZXhdID0gd3JhcHBlclxuICB9XG5cbiAgcHVibGljIGdldEN0b3JNZXRhZGF0YSAoKTogSW5zdGFuY2VXcmFwcGVyW10ge1xuICAgIHJldHVybiB0aGlzW0lOU1RBTkNFX01FVEFEQVRBX1NZTUJPTF0uZGVwZW5kZW5jaWVzXG4gIH1cblxuICBwdWJsaWMgYWRkUHJvcGVydGllc01ldGFkYXRhIChrZXk6IHN0cmluZywgd3JhcHBlcjogSW5zdGFuY2VXcmFwcGVyKSB7XG4gICAgaWYgKCF0aGlzW0lOU1RBTkNFX01FVEFEQVRBX1NZTUJPTF0ucHJvcGVydGllcykge1xuICAgICAgdGhpc1tJTlNUQU5DRV9NRVRBREFUQV9TWU1CT0xdLnByb3BlcnRpZXMgPSBbXVxuICAgIH1cbiAgICB0aGlzW0lOU1RBTkNFX01FVEFEQVRBX1NZTUJPTF0ucHJvcGVydGllcy5wdXNoKHtcbiAgICAgIGtleSxcbiAgICAgIHdyYXBwZXJcbiAgICB9KVxuICB9XG5cbiAgcHVibGljIGdldFByb3BlcnRpZXNNZXRhZGF0YSAoKTogUHJvcGVydHlNZXRhZGF0YVtdIHtcbiAgICByZXR1cm4gdGhpc1tJTlNUQU5DRV9NRVRBREFUQV9TWU1CT0xdLnByb3BlcnRpZXNcbiAgfVxuXG4gIHB1YmxpYyBhZGRFbmhhbmNlck1ldGFkYXRhICh3cmFwcGVyOiBJbnN0YW5jZVdyYXBwZXIpIHtcbiAgICBpZiAoIXRoaXNbSU5TVEFOQ0VfTUVUQURBVEFfU1lNQk9MXS5lbmhhbmNlcnMpIHtcbiAgICAgIHRoaXNbSU5TVEFOQ0VfTUVUQURBVEFfU1lNQk9MXS5lbmhhbmNlcnMgPSBbXVxuICAgIH1cbiAgICB0aGlzW0lOU1RBTkNFX01FVEFEQVRBX1NZTUJPTF0uZW5oYW5jZXJzLnB1c2god3JhcHBlcilcbiAgfVxuXG4gIHB1YmxpYyBnZXRFbmhhbmNlcnNNZXRhZGF0YSAoKTogSW5zdGFuY2VXcmFwcGVyW10ge1xuICAgIHJldHVybiB0aGlzW0lOU1RBTkNFX01FVEFEQVRBX1NZTUJPTF0uZW5oYW5jZXJzXG4gIH1cblxuICBwdWJsaWMgaXNEZXBlbmRlbmN5VHJlZUR1cmFibGUgKGxvb2t1cFJlZ2lzdHJ5OiBzdHJpbmdbXSA9IFtdKTogYm9vbGVhbiB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLmlzVHJlZUR1cmFibGUpKSB7XG4gICAgICByZXR1cm4gdGhpcy5pc1RyZWVEdXJhYmxlXG4gICAgfVxuICAgIGlmICh0aGlzLnNjb3BlID09PSBTY29wZS5SRVFVRVNUKSB7XG4gICAgICB0aGlzLmlzVHJlZUR1cmFibGUgPSB0aGlzLmR1cmFibGUgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdGhpcy5kdXJhYmxlXG4gICAgICBpZiAodGhpcy5pc1RyZWVEdXJhYmxlKSB7XG4gICAgICAgIHRoaXMucHJpbnRJbnRyb3NwZWN0ZWRBc0R1cmFibGUoKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuaXNUcmVlRHVyYWJsZVxuICAgIH1cbiAgICBjb25zdCBpc1N0YXRpYyA9IHRoaXMuaXNEZXBlbmRlbmN5VHJlZVN0YXRpYygpXG4gICAgaWYgKGlzU3RhdGljKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdCBpc1RyZWVOb25EdXJhYmxlID0gdGhpcy5pbnRyb3NwZWN0RGVwc0F0dHJpYnV0ZShcbiAgICAgIChjb2xsZWN0aW9uLCByZWdpc3RyeSkgPT5cbiAgICAgICAgY29sbGVjdGlvbi5zb21lKFxuICAgICAgICAgIChpdGVtOiBJbnN0YW5jZVdyYXBwZXIpID0+XG4gICAgICAgICAgICAhaXRlbS5pc0RlcGVuZGVuY3lUcmVlU3RhdGljKCkgJiZcbiAgICAgICAgICAgICFpdGVtLmlzRGVwZW5kZW5jeVRyZWVEdXJhYmxlKHJlZ2lzdHJ5KVxuICAgICAgICApLFxuICAgICAgbG9va3VwUmVnaXN0cnlcbiAgICApXG4gICAgdGhpcy5pc1RyZWVEdXJhYmxlID0gIWlzVHJlZU5vbkR1cmFibGVcbiAgICBpZiAodGhpcy5pc1RyZWVEdXJhYmxlKSB7XG4gICAgICB0aGlzLnByaW50SW50cm9zcGVjdGVkQXNEdXJhYmxlKClcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaXNUcmVlRHVyYWJsZVxuICB9XG5cbiAgcHVibGljIGludHJvc3BlY3REZXBzQXR0cmlidXRlIChcbiAgICBjYWxsYmFjazogKFxuICAgICAgY29sbGVjdGlvbjogSW5zdGFuY2VXcmFwcGVyW10sXG4gICAgICBsb29rdXBSZWdpc3RyeTogc3RyaW5nW11cbiAgICApID0+IGJvb2xlYW4sXG4gICAgbG9va3VwUmVnaXN0cnk6IHN0cmluZ1tdID0gW11cbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKGxvb2t1cFJlZ2lzdHJ5LmluY2x1ZGVzKHRoaXNbSU5TVEFOQ0VfSURfU1lNQk9MXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBsb29rdXBSZWdpc3RyeSA9IGxvb2t1cFJlZ2lzdHJ5LmNvbmNhdCh0aGlzW0lOU1RBTkNFX0lEX1NZTUJPTF0pXG5cbiAgICBjb25zdCB7IGRlcGVuZGVuY2llcywgcHJvcGVydGllcywgZW5oYW5jZXJzIH0gPVxuICAgICAgdGhpc1tJTlNUQU5DRV9NRVRBREFUQV9TWU1CT0xdXG5cbiAgICBsZXQgaW50cm9zcGVjdGlvblJlc3VsdCA9IGRlcGVuZGVuY2llc1xuICAgICAgPyBjYWxsYmFjayhkZXBlbmRlbmNpZXMsIGxvb2t1cFJlZ2lzdHJ5KVxuICAgICAgOiBmYWxzZVxuXG4gICAgaWYgKGludHJvc3BlY3Rpb25SZXN1bHQgfHwgIShwcm9wZXJ0aWVzIHx8IGVuaGFuY2VycykpIHtcbiAgICAgIHJldHVybiBpbnRyb3NwZWN0aW9uUmVzdWx0XG4gICAgfVxuICAgIGludHJvc3BlY3Rpb25SZXN1bHQgPSBwcm9wZXJ0aWVzXG4gICAgICA/IGNhbGxiYWNrKFxuICAgICAgICAgIHByb3BlcnRpZXMubWFwKGl0ZW0gPT4gaXRlbS53cmFwcGVyKSxcbiAgICAgICAgICBsb29rdXBSZWdpc3RyeVxuICAgICAgICApXG4gICAgICA6IGZhbHNlXG4gICAgaWYgKGludHJvc3BlY3Rpb25SZXN1bHQgfHwgIWVuaGFuY2Vycykge1xuICAgICAgcmV0dXJuIGludHJvc3BlY3Rpb25SZXN1bHRcbiAgICB9XG4gICAgcmV0dXJuIGVuaGFuY2VycyA/IGNhbGxiYWNrKGVuaGFuY2VycywgbG9va3VwUmVnaXN0cnkpIDogZmFsc2VcbiAgfVxuXG4gIHB1YmxpYyBpc0RlcGVuZGVuY3lUcmVlU3RhdGljIChsb29rdXBSZWdpc3RyeTogc3RyaW5nW10gPSBbXSk6IGJvb2xlYW4ge1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5pc1RyZWVTdGF0aWMpKSB7XG4gICAgICByZXR1cm4gdGhpcy5pc1RyZWVTdGF0aWNcbiAgICB9XG4gICAgaWYgKHRoaXMuc2NvcGUgPT09IFNjb3BlLlJFUVVFU1QpIHtcbiAgICAgIHRoaXMuaXNUcmVlU3RhdGljID0gZmFsc2VcbiAgICAgIHJldHVybiB0aGlzLmlzVHJlZVN0YXRpY1xuICAgIH1cbiAgICBpZiAobG9va3VwUmVnaXN0cnkuaW5jbHVkZXModGhpc1tJTlNUQU5DRV9JRF9TWU1CT0xdKSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgbG9va3VwUmVnaXN0cnkgPSBsb29rdXBSZWdpc3RyeS5jb25jYXQodGhpc1tJTlNUQU5DRV9JRF9TWU1CT0xdKVxuXG4gICAgY29uc3QgeyBkZXBlbmRlbmNpZXMsIHByb3BlcnRpZXMsIGVuaGFuY2VycyB9ID1cbiAgICAgIHRoaXNbSU5TVEFOQ0VfTUVUQURBVEFfU1lNQk9MXVxuICAgIGxldCBpc1N0YXRpYyA9XG4gICAgICAoZGVwZW5kZW5jaWVzICYmXG4gICAgICAgIHRoaXMuaXNXcmFwcGVyTGlzdFN0YXRpYyhkZXBlbmRlbmNpZXMsIGxvb2t1cFJlZ2lzdHJ5KSkgfHxcbiAgICAgICFkZXBlbmRlbmNpZXNcblxuICAgIGlmICghaXNTdGF0aWMgfHwgIShwcm9wZXJ0aWVzIHx8IGVuaGFuY2VycykpIHtcbiAgICAgIHRoaXMuaXNUcmVlU3RhdGljID0gaXNTdGF0aWNcbiAgICAgIHJldHVybiB0aGlzLmlzVHJlZVN0YXRpY1xuICAgIH1cbiAgICBjb25zdCBwcm9wZXJ0aWVzSG9zdHMgPSAocHJvcGVydGllcyB8fCBbXSkubWFwKGl0ZW0gPT4gaXRlbS53cmFwcGVyKVxuICAgIGlzU3RhdGljID1cbiAgICAgIGlzU3RhdGljICYmIHRoaXMuaXNXcmFwcGVyTGlzdFN0YXRpYyhwcm9wZXJ0aWVzSG9zdHMsIGxvb2t1cFJlZ2lzdHJ5KVxuICAgIGlmICghaXNTdGF0aWMgfHwgIWVuaGFuY2Vycykge1xuICAgICAgdGhpcy5pc1RyZWVTdGF0aWMgPSBpc1N0YXRpY1xuICAgICAgcmV0dXJuIHRoaXMuaXNUcmVlU3RhdGljXG4gICAgfVxuICAgIHRoaXMuaXNUcmVlU3RhdGljID0gdGhpcy5pc1dyYXBwZXJMaXN0U3RhdGljKGVuaGFuY2VycywgbG9va3VwUmVnaXN0cnkpXG4gICAgcmV0dXJuIHRoaXMuaXNUcmVlU3RhdGljXG4gIH1cblxuICBwdWJsaWMgY2xvbmVTdGF0aWNJbnN0YW5jZSAoY29udGV4dElkOiBDb250ZXh0SWQpOiBJbnN0YW5jZVBlckNvbnRleHQ8VD4ge1xuICAgIGNvbnN0IHN0YXRpY0luc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZUJ5Q29udGV4dElkKFNUQVRJQ19DT05URVhUKVxuICAgIGlmICh0aGlzLmlzRGVwZW5kZW5jeVRyZWVTdGF0aWMoKSkge1xuICAgICAgcmV0dXJuIHN0YXRpY0luc3RhbmNlXG4gICAgfVxuICAgIGNvbnN0IGluc3RhbmNlUGVyQ29udGV4dDogSW5zdGFuY2VQZXJDb250ZXh0PFQ+ID0ge1xuICAgICAgLi4uc3RhdGljSW5zdGFuY2UsXG4gICAgICBpbnN0YW5jZTogdW5kZWZpbmVkLFxuICAgICAgaXNSZXNvbHZlZDogZmFsc2UsXG4gICAgICBpc1BlbmRpbmc6IGZhbHNlXG4gICAgfVxuICAgIGlmICh0aGlzLmlzTmV3YWJsZSgpKSB7XG4gICAgICBpbnN0YW5jZVBlckNvbnRleHQuaW5zdGFuY2UgPSBPYmplY3QuY3JlYXRlKHRoaXMubWV0YVR5cGUucHJvdG90eXBlKVxuICAgIH1cbiAgICB0aGlzLnNldEluc3RhbmNlQnlDb250ZXh0SWQoY29udGV4dElkLCBpbnN0YW5jZVBlckNvbnRleHQpXG4gICAgcmV0dXJuIGluc3RhbmNlUGVyQ29udGV4dFxuICB9XG5cbiAgcHVibGljIGNsb25lVHJhbnNpZW50SW5zdGFuY2UgKFxuICAgIGNvbnRleHRJZDogQ29udGV4dElkLFxuICAgIGlucXVpcmVySWQ6IHN0cmluZ1xuICApOiBJbnN0YW5jZVBlckNvbnRleHQ8VD4ge1xuICAgIGNvbnN0IHN0YXRpY0luc3RhbmNlID0gdGhpcy5nZXRJbnN0YW5jZUJ5Q29udGV4dElkKFNUQVRJQ19DT05URVhUKVxuICAgIGNvbnN0IGluc3RhbmNlUGVyQ29udGV4dDogSW5zdGFuY2VQZXJDb250ZXh0PFQ+ID0ge1xuICAgICAgLi4uc3RhdGljSW5zdGFuY2UsXG4gICAgICBpbnN0YW5jZTogdW5kZWZpbmVkLFxuICAgICAgaXNSZXNvbHZlZDogZmFsc2UsXG4gICAgICBpc1BlbmRpbmc6IGZhbHNlXG4gICAgfVxuICAgIGlmICh0aGlzLmlzTmV3YWJsZSgpKSB7XG4gICAgICBpbnN0YW5jZVBlckNvbnRleHQuaW5zdGFuY2UgPSBPYmplY3QuY3JlYXRlKHRoaXMubWV0YVR5cGUucHJvdG90eXBlKVxuICAgIH1cbiAgICB0aGlzLnNldEluc3RhbmNlQnlJbnF1aXJlcklkKGNvbnRleHRJZCwgaW5xdWlyZXJJZCwgaW5zdGFuY2VQZXJDb250ZXh0KVxuICAgIHJldHVybiBpbnN0YW5jZVBlckNvbnRleHRcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVQcm90b3R5cGUgKGNvbnRleHRJZDogQ29udGV4dElkKSB7XG4gICAgY29uc3QgaG9zdCA9IHRoaXMuZ2V0SW5zdGFuY2VCeUNvbnRleHRJZChjb250ZXh0SWQpXG4gICAgaWYgKCF0aGlzLmlzTmV3YWJsZSgpIHx8IGhvc3QuaXNSZXNvbHZlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMubWV0YVR5cGUucHJvdG90eXBlKVxuICB9XG5cbiAgcHVibGljIGlzSW5SZXF1ZXN0U2NvcGUgKFxuICAgIGNvbnRleHRJZDogQ29udGV4dElkLFxuICAgIGlucXVpcmVyPzogSW5zdGFuY2VXcmFwcGVyIHwgdW5kZWZpbmVkXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGlzRGVwZW5kZW5jeVRyZWVTdGF0aWMgPSB0aGlzLmlzRGVwZW5kZW5jeVRyZWVTdGF0aWMoKVxuXG4gICAgcmV0dXJuIChcbiAgICAgICFpc0RlcGVuZGVuY3lUcmVlU3RhdGljICYmXG4gICAgICBjb250ZXh0SWQgIT09IFNUQVRJQ19DT05URVhUICYmXG4gICAgICAoIXRoaXMuaXNUcmFuc2llbnQgfHwgKHRoaXMuaXNUcmFuc2llbnQgJiYgISFpbnF1aXJlcikpXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGlzTGF6eVRyYW5zaWVudCAoXG4gICAgY29udGV4dElkOiBDb250ZXh0SWQsXG4gICAgaW5xdWlyZXI6IEluc3RhbmNlV3JhcHBlciB8IHVuZGVmaW5lZFxuICApOiBib29sZWFuIHtcbiAgICBjb25zdCBpc0lucXVpcmVyUmVxdWVzdFNjb3BlZCA9XG4gICAgICBpbnF1aXJlciAmJiAhaW5xdWlyZXIuaXNEZXBlbmRlbmN5VHJlZVN0YXRpYygpXG5cbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5pc0RlcGVuZGVuY3lUcmVlU3RhdGljKCkgJiZcbiAgICAgIGNvbnRleHRJZCAhPT0gU1RBVElDX0NPTlRFWFQgJiZcbiAgICAgIHRoaXMuaXNUcmFuc2llbnQgJiZcbiAgICAgIGlzSW5xdWlyZXJSZXF1ZXN0U2NvcGVkXG4gICAgKVxuICB9XG5cbiAgcHVibGljIGlzRXhwbGljaXRseVJlcXVlc3RlZCAoXG4gICAgY29udGV4dElkOiBDb250ZXh0SWQsXG4gICAgaW5xdWlyZXI/OiBJbnN0YW5jZVdyYXBwZXJcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaXNTZWxmUmVxdWVzdGVkID0gaW5xdWlyZXIgPT09IHRoaXNcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5pc0RlcGVuZGVuY3lUcmVlU3RhdGljKCkgJiZcbiAgICAgIGNvbnRleHRJZCAhPT0gU1RBVElDX0NPTlRFWFQgJiZcbiAgICAgIChpc1NlbGZSZXF1ZXN0ZWQgfHwgKGlucXVpcmVyICYmIGlucXVpcmVyLnNjb3BlID09PSBTY29wZS5UUkFOU0lFTlQpKVxuICAgIClcbiAgfVxuXG4gIHB1YmxpYyBpc1N0YXRpYyAoXG4gICAgY29udGV4dElkOiBDb250ZXh0SWQsXG4gICAgaW5xdWlyZXI6IEluc3RhbmNlV3JhcHBlciB8IHVuZGVmaW5lZFxuICApOiBib29sZWFuIHtcbiAgICBjb25zdCBpc0lucXVpcmVyUmVxdWVzdFNjb3BlZCA9XG4gICAgICBpbnF1aXJlciAmJiAhaW5xdWlyZXIuaXNEZXBlbmRlbmN5VHJlZVN0YXRpYygpXG4gICAgY29uc3QgaXNTdGF0aWNUcmFuc2llbnQgPSB0aGlzLmlzVHJhbnNpZW50ICYmICFpc0lucXVpcmVyUmVxdWVzdFNjb3BlZFxuXG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuaXNEZXBlbmRlbmN5VHJlZVN0YXRpYygpICYmXG4gICAgICBjb250ZXh0SWQgPT09IFNUQVRJQ19DT05URVhUICYmXG4gICAgICAoIXRoaXMuaXNUcmFuc2llbnQgfHxcbiAgICAgICAgKGlzU3RhdGljVHJhbnNpZW50ICYmICEhaW5xdWlyZXIgJiYgIWlucXVpcmVyLmlzVHJhbnNpZW50KSlcbiAgICApXG4gIH1cblxuICBwdWJsaWMgZ2V0U3RhdGljVHJhbnNpZW50SW5zdGFuY2VzICgpIHtcbiAgICBpZiAoIXRoaXMudHJhbnNpZW50TWFwKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG4gICAgY29uc3QgaW5zdGFuY2VzID0gWy4uLnRoaXMudHJhbnNpZW50TWFwLnZhbHVlcygpXVxuICAgIHJldHVybiBpdGVyYXRlKGluc3RhbmNlcylcbiAgICAgIC5tYXAoaXRlbSA9PiBpdGVtLmdldChTVEFUSUNfQ09OVEVYVCkpXG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gISFpdGVtKVxuICAgICAgLnRvQXJyYXkoKVxuICB9XG5cbiAgcHVibGljIG1lcmdlV2l0aCAocHJvdmlkZXI6IFByb3ZpZGVyVHlwZSkge1xuICAgIGlmICghaXNVbmRlZmluZWQoKHByb3ZpZGVyIGFzIFZhbHVlUHJvdmlkZXIpLnVzZVZhbHVlKSkge1xuICAgICAgdGhpcy5tZXRhVHlwZSA9IG51bGxcbiAgICAgIHRoaXMuaW5qZWN0ID0gbnVsbFxuICAgICAgdGhpcy5zY29wZSA9IFNjb3BlLkRFRkFVTFRcblxuICAgICAgdGhpcy5zZXRJbnN0YW5jZUJ5Q29udGV4dElkKFNUQVRJQ19DT05URVhULCB7XG4gICAgICAgIGluc3RhbmNlOiAocHJvdmlkZXIgYXMgVmFsdWVQcm92aWRlcikudXNlVmFsdWUsXG4gICAgICAgIGlzUmVzb2x2ZWQ6IHRydWUsXG4gICAgICAgIGlzUGVuZGluZzogZmFsc2VcbiAgICAgIH0pXG4gICAgfSBlbHNlIGlmICgocHJvdmlkZXIgYXMgQ2xhc3NQcm92aWRlcikudXNlQ2xhc3MpIHtcbiAgICAgIHRoaXMuaW5qZWN0ID0gbnVsbFxuICAgICAgdGhpcy5tZXRhVHlwZSA9IChwcm92aWRlciBhcyBDbGFzc1Byb3ZpZGVyKS51c2VDbGFzc1xuICAgIH0gZWxzZSBpZiAoKHByb3ZpZGVyIGFzIEZhY3RvcnlQcm92aWRlcikudXNlRmFjdG9yeSkge1xuICAgICAgdGhpcy5tZXRhVHlwZSA9IChwcm92aWRlciBhcyBGYWN0b3J5UHJvdmlkZXIpLnVzZUZhY3RvcnlcbiAgICAgIHRoaXMuaW5qZWN0ID0gKHByb3ZpZGVyIGFzIEZhY3RvcnlQcm92aWRlcikuaW5qZWN0IHx8IFtdXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc05ld2FibGUgKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05pbCh0aGlzLmluamVjdCkgJiYgdGhpcy5tZXRhVHlwZSAmJiB0aGlzLm1ldGFUeXBlLnByb3RvdHlwZVxuICB9XG5cbiAgcHJpdmF0ZSBpc1dyYXBwZXJMaXN0U3RhdGljIChcbiAgICB0cmVlOiBJbnN0YW5jZVdyYXBwZXJbXSxcbiAgICBsb29rdXBSZWdpc3RyeTogc3RyaW5nW11cbiAgKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRyZWUuZXZlcnkoKGl0ZW06IEluc3RhbmNlV3JhcHBlcikgPT5cbiAgICAgIGl0ZW0uaXNEZXBlbmRlbmN5VHJlZVN0YXRpYyhsb29rdXBSZWdpc3RyeSlcbiAgICApXG4gIH1cblxuICBwcml2YXRlIGluaXRpYWxpemUgKFxuICAgIG1ldGFkYXRhOiBQYXJ0aWFsPEluc3RhbmNlV3JhcHBlcjxUPj4gJiBQYXJ0aWFsPEluc3RhbmNlUGVyQ29udGV4dDxUPj5cbiAgKSB7XG4gICAgY29uc3QgeyBpbnN0YW5jZSwgaXNSZXNvbHZlZCwgLi4ud3JhcHBlclBhcnRpYWwgfSA9IG1ldGFkYXRhXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCB3cmFwcGVyUGFydGlhbClcblxuICAgIHRoaXMuc2V0SW5zdGFuY2VCeUNvbnRleHRJZChTVEFUSUNfQ09OVEVYVCwge1xuICAgICAgaW5zdGFuY2UsXG4gICAgICBpc1Jlc29sdmVkXG4gICAgfSlcbiAgICB0aGlzLnNjb3BlID09PSBTY29wZS5UUkFOU0lFTlQgJiYgKHRoaXMudHJhbnNpZW50TWFwID0gbmV3IE1hcCgpKVxuICB9XG5cbiAgcHJpdmF0ZSBpc0RlYnVnTW9kZSAoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhcHJvY2Vzcy5lbnYuQ0xFQU5fREVCVUdcbiAgfVxuXG4gIHByaXZhdGUgcHJpbnRJbnRyb3NwZWN0ZWRBc0R1cmFibGUgKCkge1xuICAgIGlmICghdGhpcy5pc0RlYnVnTW9kZSgpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGlzU3RyaW5nKHRoaXMubmFtZSkpIHtcbiAgICAgIEluc3RhbmNlV3JhcHBlci5sb2dnZXIubG9nKFxuICAgICAgICBgJHtjbGMuY3lhbkJyaWdodCh0aGlzLm5hbWUpfSR7Y2xjLmdyZWVuKFxuICAgICAgICAgICcgaW50cm9zcGVjdGVkIGFzICdcbiAgICAgICAgKX0ke2NsYy5tYWdlbnRhQnJpZ2h0KCdkdXJhYmxlJyl9YFxuICAgICAgKVxuICAgIH1cbiAgfVxufVxuIl19