typed-object-accumulator
Version:
Class capable of accumulation properties and types
182 lines (177 loc) • 20.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["typed-object-accumulator"] = {}));
})(this, (function (exports) { 'use strict';
/**
* @class ObjectAccumulator
* @template T - The type of the accumulated object, extends object
* @description A class that accumulates objects and provides type-safe access to their properties.
* It allows for dynamic addition of properties while maintaining type information.
* @summary Accumulates objects and maintains type information for accumulated properties
* @memberOf utils
*/
class ObjectAccumulator {
constructor() {
Object.defineProperty(this, "__size", {
value: 0,
writable: true,
configurable: false,
enumerable: false,
});
}
/**
* @protected
* @description Expands the accumulator with properties from a new object
* @summary Adds new properties to the accumulator
* @template V - The type of the object being expanded
* @param {V} value - The object to expand with
* @returns {void}
*/
expand(value) {
Object.entries(value).forEach(([k, v]) => {
Object.defineProperty(this, k, {
get: () => v,
set: (val) => {
v = val;
},
configurable: true,
enumerable: true,
});
});
}
/**
* @description Accumulates a new object into the accumulator
* @summary Adds properties from a new object to the accumulator, maintaining type information
* @template V - The type of the object being accumulated
* @param {V} value - The object to accumulate
* @returns A new ObjectAccumulator instance with updated type information
* @mermaid
* sequenceDiagram
* participant A as Accumulator
* participant O as Object
* A->>O: Get entries
* loop For each entry
* A->>A: Define property
* end
* A->>A: Update size
* A->>A: Return updated accumulator
*/
accumulate(value) {
this.expand(value);
this.__size = this.__size + Object.keys(value).length;
return this;
}
/**
* @description Retrieves a value from the accumulator by its key
* @summary Gets a value from the accumulated object using a type-safe key
* @template T - value type
* @template K - The key type, must be a key of this
* @param {K} key - The key of the value to retrieve
* @returns The value associated with the key
*/
get(key) {
if (!(key in this))
throw new Error(`Key ${key} does not exist in accumulator. Available keys: ${this.keys().join(", ")}`);
return this[key];
}
/**
* @description Retrieves a value from the accumulator by its key
* @summary Gets a value from the accumulated object using a type-safe key
* @param {string} key - The key of the value to retrieve
* @param {any} value - The key of the value to retrieve
*/
put(key, value) {
return this.accumulate({ [key]: value });
}
/**
* @description Checks if a key exists in the accumulator
* @summary Determines whether the accumulator contains a specific key
* @param {string} key - The key to check for existence
* @returns {boolean} True if the key exists, false otherwise
*/
has(key) {
return !!this[key];
}
/**
* @description Removes a key-value pair from the accumulator
* @summary Deletes a property from the accumulated object
* @param {string} key - The key of the property to remove
* @returns {} The accumulator instance with the specified property removed
*/
remove(key) {
if (!(key in this))
return this;
delete this[key];
this.__size--;
return this;
}
/**
* @description Retrieves all keys from the accumulator
* @summary Gets an array of all accumulated property keys
* @returns {string[]} An array of keys as strings
*/
keys() {
return Object.keys(this);
}
/**
* @description Retrieves all values from the accumulator
* @summary Gets an array of all accumulated property values
* @returns An array of values
*/
values() {
return Object.values(this);
}
/**
* @description Gets the number of key-value pairs in the accumulator
* @summary Returns the count of accumulated properties
* @returns {number} The number of key-value pairs
*/
size() {
return this.__size;
}
/**
* @description Clears all accumulated key-value pairs
* @summary Removes all properties from the accumulator and returns a new empty instance
* @returns {ObjectAccumulator<never>} A new empty ObjectAccumulator instance
*/
clear() {
return new ObjectAccumulator();
}
/**
* @description Executes a callback for each key-value pair in the accumulator
* @summary Iterates over all accumulated properties, calling a function for each
* @param {function(any, string, number): void} callback - The function to execute for each entry
* @returns {void}
*/
forEach(callback) {
Object.entries(this).forEach(([key, value], i) => callback(value, key, i));
}
/**
* @description Creates a new array with the results of calling a provided function on every element in the accumulator
* @summary Maps each accumulated property to a new value using a callback function
* @template R - The type of the mapped values
* @param {function(any, string,number): R} callback - Function that produces an element of the new array
* @returns {R[]} A new array with each element being the result of the callback function
*/
map(callback) {
return Object.entries(this).map(([key, value], i) => callback(value, key, i));
}
}
/**
* @module typed-object-accumulator
* @description A TypeScript library for accumulating objects with type safety
* @summary This module provides utilities for dynamically accumulating object properties while maintaining type information. It exports the {@link ObjectAccumulator} class and version information.
*/
/**
* @description Represents the current version of the typed-object-accumulator module
* @summary The actual version number is replaced during the build process with the package version
* @const VERSION
* @type {string}
* @memberOf module:typed-object-accumulator
*/
const VERSION = "0.1.4";
exports.ObjectAccumulator = ObjectAccumulator;
exports.VERSION = VERSION;
}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWQtb2JqZWN0LWFjY3VtdWxhdG9yLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2FjY3VtdWxhdG9yLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNsYXNzIE9iamVjdEFjY3VtdWxhdG9yXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIHRoZSBhY2N1bXVsYXRlZCBvYmplY3QsIGV4dGVuZHMgb2JqZWN0XG4gKiBAZGVzY3JpcHRpb24gQSBjbGFzcyB0aGF0IGFjY3VtdWxhdGVzIG9iamVjdHMgYW5kIHByb3ZpZGVzIHR5cGUtc2FmZSBhY2Nlc3MgdG8gdGhlaXIgcHJvcGVydGllcy5cbiAqIEl0IGFsbG93cyBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBwcm9wZXJ0aWVzIHdoaWxlIG1haW50YWluaW5nIHR5cGUgaW5mb3JtYXRpb24uXG4gKiBAc3VtbWFyeSBBY2N1bXVsYXRlcyBvYmplY3RzIGFuZCBtYWludGFpbnMgdHlwZSBpbmZvcm1hdGlvbiBmb3IgYWNjdW11bGF0ZWQgcHJvcGVydGllc1xuICogQG1lbWJlck9mIHV0aWxzXG4gKi9cbmV4cG9ydCBjbGFzcyBPYmplY3RBY2N1bXVsYXRvcjxUIGV4dGVuZHMgb2JqZWN0PiB7XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAZGVzY3JpcHRpb24gVGhlIHNpemUgb2YgdGhlIGFjY3VtdWxhdGVkIG9iamVjdFxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgcHJpdmF0ZSBfX3NpemUhOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiX19zaXplXCIsIHtcbiAgICAgIHZhbHVlOiAwLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAZGVzY3JpcHRpb24gRXhwYW5kcyB0aGUgYWNjdW11bGF0b3Igd2l0aCBwcm9wZXJ0aWVzIGZyb20gYSBuZXcgb2JqZWN0XG4gICAqIEBzdW1tYXJ5IEFkZHMgbmV3IHByb3BlcnRpZXMgdG8gdGhlIGFjY3VtdWxhdG9yXG4gICAqIEB0ZW1wbGF0ZSBWIC0gVGhlIHR5cGUgb2YgdGhlIG9iamVjdCBiZWluZyBleHBhbmRlZFxuICAgKiBAcGFyYW0ge1Z9IHZhbHVlIC0gVGhlIG9iamVjdCB0byBleHBhbmQgd2l0aFxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHByb3RlY3RlZCBleHBhbmQ8ViBleHRlbmRzIG9iamVjdD4odmFsdWU6IFYpOiB2b2lkIHtcbiAgICBPYmplY3QuZW50cmllcyh2YWx1ZSkuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgaywge1xuICAgICAgICBnZXQ6ICgpID0+IHYsXG4gICAgICAgIHNldDogKHZhbDogVltrZXlvZiBWXSkgPT4ge1xuICAgICAgICAgIHYgPSB2YWw7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBY2N1bXVsYXRlcyBhIG5ldyBvYmplY3QgaW50byB0aGUgYWNjdW11bGF0b3JcbiAgICogQHN1bW1hcnkgQWRkcyBwcm9wZXJ0aWVzIGZyb20gYSBuZXcgb2JqZWN0IHRvIHRoZSBhY2N1bXVsYXRvciwgbWFpbnRhaW5pbmcgdHlwZSBpbmZvcm1hdGlvblxuICAgKiBAdGVtcGxhdGUgViAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QgYmVpbmcgYWNjdW11bGF0ZWRcbiAgICogQHBhcmFtIHtWfSB2YWx1ZSAtIFRoZSBvYmplY3QgdG8gYWNjdW11bGF0ZVxuICAgKiBAcmV0dXJucyBBIG5ldyBPYmplY3RBY2N1bXVsYXRvciBpbnN0YW5jZSB3aXRoIHVwZGF0ZWQgdHlwZSBpbmZvcm1hdGlvblxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBBIGFzIEFjY3VtdWxhdG9yXG4gICAqICAgcGFydGljaXBhbnQgTyBhcyBPYmplY3RcbiAgICogICBBLT4+TzogR2V0IGVudHJpZXNcbiAgICogICBsb29wIEZvciBlYWNoIGVudHJ5XG4gICAqICAgICBBLT4+QTogRGVmaW5lIHByb3BlcnR5XG4gICAqICAgZW5kXG4gICAqICAgQS0+PkE6IFVwZGF0ZSBzaXplXG4gICAqICAgQS0+PkE6IFJldHVybiB1cGRhdGVkIGFjY3VtdWxhdG9yXG4gICAqL1xuICBhY2N1bXVsYXRlPFYgZXh0ZW5kcyBvYmplY3Q+KHZhbHVlOiBWKTogVCAmIFYgJiBPYmplY3RBY2N1bXVsYXRvcjxUICYgVj4ge1xuICAgIHRoaXMuZXhwYW5kKHZhbHVlKTtcbiAgICB0aGlzLl9fc2l6ZSA9IHRoaXMuX19zaXplICsgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aDtcbiAgICByZXR1cm4gdGhpcyBhcyB1bmtub3duIGFzIFQgJiBWICYgT2JqZWN0QWNjdW11bGF0b3I8VCAmIFY+O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHRoZSBhY2N1bXVsYXRvciBieSBpdHMga2V5XG4gICAqIEBzdW1tYXJ5IEdldHMgYSB2YWx1ZSBmcm9tIHRoZSBhY2N1bXVsYXRlZCBvYmplY3QgdXNpbmcgYSB0eXBlLXNhZmUga2V5XG4gICAqIEB0ZW1wbGF0ZSBUIC0gdmFsdWUgdHlwZVxuICAgKiBAdGVtcGxhdGUgSyAtIFRoZSBrZXkgdHlwZSwgbXVzdCBiZSBhIGtleSBvZiB0aGlzXG4gICAqIEBwYXJhbSB7S30ga2V5IC0gVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmV0cmlldmVcbiAgICogQHJldHVybnMgVGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUga2V5XG4gICAqL1xuICBnZXQ8SyBleHRlbmRzIGtleW9mIFQ+KGtleTogSyk6IFRbS10ge1xuICAgIGlmICghKGtleSBpbiB0aGlzKSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEtleSAke2tleSBhcyBzdHJpbmd9IGRvZXMgbm90IGV4aXN0IGluIGFjY3VtdWxhdG9yLiBBdmFpbGFibGUga2V5czogJHt0aGlzLmtleXMoKS5qb2luKFxuICAgICAgICAgIFwiLCBcIlxuICAgICAgICApfWBcbiAgICAgICk7XG4gICAgcmV0dXJuICh0aGlzIGFzIGFueSlba2V5IGFzIEtdIGFzIFRbS107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHZhbHVlIGZyb20gdGhlIGFjY3VtdWxhdG9yIGJ5IGl0cyBrZXlcbiAgICogQHN1bW1hcnkgR2V0cyBhIHZhbHVlIGZyb20gdGhlIGFjY3VtdWxhdGVkIG9iamVjdCB1c2luZyBhIHR5cGUtc2FmZSBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJldHJpZXZlXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJldHJpZXZlXG4gICAqL1xuICBwdXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5hY2N1bXVsYXRlKHsgW2tleV06IHZhbHVlIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBrZXkgZXhpc3RzIGluIHRoZSBhY2N1bXVsYXRvclxuICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGFjY3VtdWxhdG9yIGNvbnRhaW5zIGEgc3BlY2lmaWMga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IHRvIGNoZWNrIGZvciBleGlzdGVuY2VcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGtleSBleGlzdHMsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgaGFzKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpc1trZXkgYXMga2V5b2YgdGhpc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlbW92ZXMgYSBrZXktdmFsdWUgcGFpciBmcm9tIHRoZSBhY2N1bXVsYXRvclxuICAgKiBAc3VtbWFyeSBEZWxldGVzIGEgcHJvcGVydHkgZnJvbSB0aGUgYWNjdW11bGF0ZWQgb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byByZW1vdmVcbiAgICogQHJldHVybnMge30gVGhlIGFjY3VtdWxhdG9yIGluc3RhbmNlIHdpdGggdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSByZW1vdmVkXG4gICAqL1xuICByZW1vdmUoXG4gICAga2V5OiBrZXlvZiB0aGlzIHwgc3RyaW5nXG4gICk6XG4gICAgfCAoT21pdDx0aGlzLCB0eXBlb2Yga2V5PiAmIE9iamVjdEFjY3VtdWxhdG9yPE9taXQ8dGhpcywgdHlwZW9mIGtleT4+KVxuICAgIHwgdGhpcyB7XG4gICAgaWYgKCEoa2V5IGluIHRoaXMpKSByZXR1cm4gdGhpcztcblxuICAgIGRlbGV0ZSB0aGlzW2tleSBhcyBrZXlvZiB0aGlzXTtcbiAgICB0aGlzLl9fc2l6ZS0tO1xuICAgIHJldHVybiB0aGlzIGFzIHVua25vd24gYXMgT21pdDx0aGlzLCB0eXBlb2Yga2V5PiAmXG4gICAgICBPYmplY3RBY2N1bXVsYXRvcjxPbWl0PHRoaXMsIHR5cGVvZiBrZXk+PjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFsbCBrZXlzIGZyb20gdGhlIGFjY3VtdWxhdG9yXG4gICAqIEBzdW1tYXJ5IEdldHMgYW4gYXJyYXkgb2YgYWxsIGFjY3VtdWxhdGVkIHByb3BlcnR5IGtleXNcbiAgICogQHJldHVybnMge3N0cmluZ1tdfSBBbiBhcnJheSBvZiBrZXlzIGFzIHN0cmluZ3NcbiAgICovXG4gIGtleXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFsbCB2YWx1ZXMgZnJvbSB0aGUgYWNjdW11bGF0b3JcbiAgICogQHN1bW1hcnkgR2V0cyBhbiBhcnJheSBvZiBhbGwgYWNjdW11bGF0ZWQgcHJvcGVydHkgdmFsdWVzXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHZhbHVlc1xuICAgKi9cbiAgdmFsdWVzKCk6IFRba2V5b2YgVF1bXSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIG51bWJlciBvZiBrZXktdmFsdWUgcGFpcnMgaW4gdGhlIGFjY3VtdWxhdG9yXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGNvdW50IG9mIGFjY3VtdWxhdGVkIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiBrZXktdmFsdWUgcGFpcnNcbiAgICovXG4gIHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fX3NpemU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENsZWFycyBhbGwgYWNjdW11bGF0ZWQga2V5LXZhbHVlIHBhaXJzXG4gICAqIEBzdW1tYXJ5IFJlbW92ZXMgYWxsIHByb3BlcnRpZXMgZnJvbSB0aGUgYWNjdW11bGF0b3IgYW5kIHJldHVybnMgYSBuZXcgZW1wdHkgaW5zdGFuY2VcbiAgICogQHJldHVybnMge09iamVjdEFjY3VtdWxhdG9yPG5ldmVyPn0gQSBuZXcgZW1wdHkgT2JqZWN0QWNjdW11bGF0b3IgaW5zdGFuY2VcbiAgICovXG4gIGNsZWFyKCk6IE9iamVjdEFjY3VtdWxhdG9yPG5ldmVyPiB7XG4gICAgcmV0dXJuIG5ldyBPYmplY3RBY2N1bXVsYXRvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyBhIGNhbGxiYWNrIGZvciBlYWNoIGtleS12YWx1ZSBwYWlyIGluIHRoZSBhY2N1bXVsYXRvclxuICAgKiBAc3VtbWFyeSBJdGVyYXRlcyBvdmVyIGFsbCBhY2N1bXVsYXRlZCBwcm9wZXJ0aWVzLCBjYWxsaW5nIGEgZnVuY3Rpb24gZm9yIGVhY2hcbiAgICogQHBhcmFtIHtmdW5jdGlvbihhbnksIHN0cmluZywgbnVtYmVyKTogdm9pZH0gY2FsbGJhY2sgLSBUaGUgZnVuY3Rpb24gdG8gZXhlY3V0ZSBmb3IgZWFjaCBlbnRyeVxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGZvckVhY2goXG4gICAgY2FsbGJhY2s6ICh2YWx1ZTogdGhpc1trZXlvZiB0aGlzXSwga2V5OiBrZXlvZiB0aGlzLCBpOiBudW1iZXIpID0+IHZvaWRcbiAgKTogdm9pZCB7XG4gICAgT2JqZWN0LmVudHJpZXModGhpcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdLCBpKSA9PlxuICAgICAgY2FsbGJhY2sodmFsdWUsIGtleSBhcyBrZXlvZiB0aGlzLCBpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgYXJyYXkgd2l0aCB0aGUgcmVzdWx0cyBvZiBjYWxsaW5nIGEgcHJvdmlkZWQgZnVuY3Rpb24gb24gZXZlcnkgZWxlbWVudCBpbiB0aGUgYWNjdW11bGF0b3JcbiAgICogQHN1bW1hcnkgTWFwcyBlYWNoIGFjY3VtdWxhdGVkIHByb3BlcnR5IHRvIGEgbmV3IHZhbHVlIHVzaW5nIGEgY2FsbGJhY2sgZnVuY3Rpb25cbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgdHlwZSBvZiB0aGUgbWFwcGVkIHZhbHVlc1xuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGFueSwgc3RyaW5nLG51bWJlcik6IFJ9IGNhbGxiYWNrIC0gRnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhbiBlbGVtZW50IG9mIHRoZSBuZXcgYXJyYXlcbiAgICogQHJldHVybnMge1JbXX0gQSBuZXcgYXJyYXkgd2l0aCBlYWNoIGVsZW1lbnQgYmVpbmcgdGhlIHJlc3VsdCBvZiB0aGUgY2FsbGJhY2sgZnVuY3Rpb25cbiAgICovXG4gIG1hcDxSPihcbiAgICBjYWxsYmFjazogKHZhbHVlOiB0aGlzW2tleW9mIHRoaXNdLCBrZXk6IGtleW9mIHRoaXMsIGk6IG51bWJlcikgPT4gUlxuICApOiBSW10ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0aGlzKS5tYXAoKFtrZXksIHZhbHVlXSwgaSkgPT5cbiAgICAgIGNhbGxiYWNrKHZhbHVlLCBrZXkgYXMga2V5b2YgdGhpcywgaSlcbiAgICApO1xuICB9XG59XG4iLCIvKipcbiAqIEBtb2R1bGUgdHlwZWQtb2JqZWN0LWFjY3VtdWxhdG9yXG4gKiBAZGVzY3JpcHRpb24gQSBUeXBlU2NyaXB0IGxpYnJhcnkgZm9yIGFjY3VtdWxhdGluZyBvYmplY3RzIHdpdGggdHlwZSBzYWZldHlcbiAqIEBzdW1tYXJ5IFRoaXMgbW9kdWxlIHByb3ZpZGVzIHV0aWxpdGllcyBmb3IgZHluYW1pY2FsbHkgYWNjdW11bGF0aW5nIG9iamVjdCBwcm9wZXJ0aWVzIHdoaWxlIG1haW50YWluaW5nIHR5cGUgaW5mb3JtYXRpb24uIEl0IGV4cG9ydHMgdGhlIHtAbGluayBPYmplY3RBY2N1bXVsYXRvcn0gY2xhc3MgYW5kIHZlcnNpb24gaW5mb3JtYXRpb24uXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vYWNjdW11bGF0b3JcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSB0eXBlZC1vYmplY3QtYWNjdW11bGF0b3IgbW9kdWxlXG4gKiBAc3VtbWFyeSBUaGUgYWN0dWFsIHZlcnNpb24gbnVtYmVyIGlzIHJlcGxhY2VkIGR1cmluZyB0aGUgYnVpbGQgcHJvY2VzcyB3aXRoIHRoZSBwYWNrYWdlIHZlcnNpb25cbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAdHlwZSB7c3RyaW5nfVxuICogQG1lbWJlck9mIG1vZHVsZTp0eXBlZC1vYmplY3QtYWNjdW11bGF0b3JcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBQUE7Ozs7Ozs7SUFPRztVQUNVLGlCQUFpQixDQUFBO0lBUTVCLElBQUEsV0FBQSxHQUFBO0lBQ0UsUUFBQSxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7SUFDcEMsWUFBQSxLQUFLLEVBQUUsQ0FBQztJQUNSLFlBQUEsUUFBUSxFQUFFLElBQUk7SUFDZCxZQUFBLFlBQVksRUFBRSxLQUFLO0lBQ25CLFlBQUEsVUFBVSxFQUFFLEtBQUs7SUFDbEIsU0FBQSxDQUFDOztJQUdKOzs7Ozs7O0lBT0c7SUFDTyxJQUFBLE1BQU0sQ0FBbUIsS0FBUSxFQUFBO0lBQ3pDLFFBQUEsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSTtJQUN2QyxZQUFBLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRTtJQUM3QixnQkFBQSxHQUFHLEVBQUUsTUFBTSxDQUFDO0lBQ1osZ0JBQUEsR0FBRyxFQUFFLENBQUMsR0FBZSxLQUFJO3dCQUN2QixDQUFDLEdBQUcsR0FBRztxQkFDUjtJQUNELGdCQUFBLFlBQVksRUFBRSxJQUFJO0lBQ2xCLGdCQUFBLFVBQVUsRUFBRSxJQUFJO0lBQ2pCLGFBQUEsQ0FBQztJQUNKLFNBQUMsQ0FBQzs7SUFHSjs7Ozs7Ozs7Ozs7Ozs7OztJQWdCRztJQUNILElBQUEsVUFBVSxDQUFtQixLQUFRLEVBQUE7SUFDbkMsUUFBQSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUNsQixRQUFBLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU07SUFDckQsUUFBQSxPQUFPLElBQW1EOztJQUc1RDs7Ozs7OztJQU9HO0lBQ0gsSUFBQSxHQUFHLENBQW9CLEdBQU0sRUFBQTtJQUMzQixRQUFBLElBQUksRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDO0lBQ2hCLFlBQUEsTUFBTSxJQUFJLEtBQUssQ0FDYixDQUFPLElBQUEsRUFBQSxHQUFhLG1EQUFtRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUNyRixJQUFJLENBQ0wsQ0FBQSxDQUFFLENBQ0o7SUFDSCxRQUFBLE9BQVEsSUFBWSxDQUFDLEdBQVEsQ0FBUzs7SUFHeEM7Ozs7O0lBS0c7UUFDSCxHQUFHLENBQUMsR0FBVyxFQUFFLEtBQVUsRUFBQTtJQUN6QixRQUFBLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEtBQUssRUFBRSxDQUFDOztJQUcxQzs7Ozs7SUFLRztJQUNILElBQUEsR0FBRyxDQUFDLEdBQVcsRUFBQTtJQUNiLFFBQUEsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQWlCLENBQUM7O0lBR2xDOzs7OztJQUtHO0lBQ0gsSUFBQSxNQUFNLENBQ0osR0FBd0IsRUFBQTtJQUl4QixRQUFBLElBQUksRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDO0lBQUUsWUFBQSxPQUFPLElBQUk7SUFFL0IsUUFBQSxPQUFPLElBQUksQ0FBQyxHQUFpQixDQUFDO1lBQzlCLElBQUksQ0FBQyxNQUFNLEVBQUU7SUFDYixRQUFBLE9BQU8sSUFDb0M7O0lBRzdDOzs7O0lBSUc7UUFDSCxJQUFJLEdBQUE7SUFDRixRQUFBLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7O0lBRzFCOzs7O0lBSUc7UUFDSCxNQUFNLEdBQUE7SUFDSixRQUFBLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7O0lBRzVCOzs7O0lBSUc7UUFDSCxJQUFJLEdBQUE7WUFDRixPQUFPLElBQUksQ0FBQyxNQUFNOztJQUdwQjs7OztJQUlHO1FBQ0gsS0FBSyxHQUFBO1lBQ0gsT0FBTyxJQUFJLGlCQUFpQixFQUFFOztJQUdoQzs7Ozs7SUFLRztJQUNILElBQUEsT0FBTyxDQUNMLFFBQXVFLEVBQUE7SUFFdkUsUUFBQSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FDM0MsUUFBUSxDQUFDLEtBQUssRUFBRSxHQUFpQixFQUFFLENBQUMsQ0FBQyxDQUN0Qzs7SUFHSDs7Ozs7O0lBTUc7SUFDSCxJQUFBLEdBQUcsQ0FDRCxRQUFvRSxFQUFBO0lBRXBFLFFBQUEsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FDOUMsUUFBUSxDQUFDLEtBQUssRUFBRSxHQUFpQixFQUFFLENBQUMsQ0FBQyxDQUN0Qzs7SUFFSjs7SUM5TEQ7Ozs7SUFJRztJQUlIOzs7Ozs7SUFNRztBQUNJLFVBQU0sT0FBTyxHQUFHOzs7Ozs7Ozs7In0=