UNPKG

typed-object-accumulator

Version:
182 lines (177 loc) 20.4 kB
(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=