UNPKG

@versatiledatakit/shared

Version:

Versatile Data Kit Shared library enables reusability of shared features like: NgRx Redux, Error Handlers, Utils, Generic Components, etc.

386 lines • 43.5 kB
/* * Copyright 2023-2025 Broadcom * SPDX-License-Identifier: Apache-2.0 */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { cloneDeep, isEqual } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; /** * ** Utility Class for Collections. */ export class CollectionsUtil { /** * ** Check if value is of type undefined. */ static isUndefined(value) { return typeof value === 'undefined'; } /** * ** Check if value has value null. */ static isNull(value) { return value === null; } /** * ** Check if value is undefined or null. */ static isNil(value) { return CollectionsUtil.isNull(value) || CollectionsUtil.isUndefined(value); } /** * ** Check if value is defined (opposite of isNil). * * - Not null. * - Not undefined. */ static isDefined(value) { return !CollectionsUtil.isNull(value) && !CollectionsUtil.isUndefined(value); } /** * ** Check if value T is of type Number. */ static isNumber(num) { return typeof num === 'number'; } /** * ** Check if value T is of type String. */ static isString(str) { return typeof str === 'string'; } /** * ** Check if value T is of type Boolean. */ static isBoolean(bool) { return typeof bool === 'boolean'; } /** * ** Check if value is Primitive. * * - String, Number, Boolean, null or undefined. */ static isPrimitive(value) { return (CollectionsUtil.isString(value) || CollectionsUtil.isBoolean(value) || CollectionsUtil.isNumber(value) || CollectionsUtil.isUndefined(value)); } /** * ** Check if value is NaN. */ static isNaN(value) { return Number.isNaN(value); } /** * ** Check if value is of type Date. */ static isDate(value) { return value instanceof Date; } /** * ** Check if value is Primitive or Date. * * - String, Number, Boolean, null, undefined or Date. */ static isPrimitiveOrDate(value) { return CollectionsUtil.isPrimitive(value) || CollectionsUtil.isDate(value); } /** * ** Check if value T is a reference that points to function (Class/Method). */ // eslint-disable-next-line static isFunction(value) { return typeof value === 'function'; } /** * ** Check if value T is of type Object. */ static isObject(obj) { return typeof obj === 'object'; } /** * ** Check if value T is instance of Array. */ static isArray(arr) { return arr instanceof Array; } /** * ** Check if value T is not instance of Array or there are no elements in Array. */ static isArrayEmpty(arr) { return !CollectionsUtil.isArray(arr) || arr.length === 0; } /** * ** Returns new Array where items will be filtered by reference and will leave distinct values. */ static uniqueArray(arr) { return arr.filter((value, index, self) => { return self.indexOf(value) === index; }); } /** * ** Check if value is Map. */ static isMap(obj) { return obj instanceof Map; } /** * ** Check if value is WeakMap. */ static isWeakMap(obj) { return obj instanceof WeakMap; } /** * ** Check if value is Set. */ static isSet(obj) { return obj instanceof Set; } /** * ** Check if value T is of type String and has length bigger than 0 after whitespace trim. */ static isStringWithContent(str) { return CollectionsUtil.isString(str) && str.trim().length > 0; } /** * ** Check if value is Collection (literal Object, Array, Map, WeakMap or Set). */ static isCollection(obj) { return (CollectionsUtil.isArray(obj) || CollectionsUtil.isMap(obj) || CollectionsUtil.isWeakMap(obj) || CollectionsUtil.isSet(obj) || CollectionsUtil.isLiteralObject(obj)); } /** * ** Check if value is of type Object and not null. */ static isObjectNotNull(obj) { return CollectionsUtil.isObject(obj) && !CollectionsUtil.isNull(obj); } /** * ** Check if some variable is of type Boolean and is true. */ static isBooleanAndTrue(bool) { return CollectionsUtil.isBoolean(bool) && bool; } /** * ** Check if value is literal Object or null. * * - Not an Array, Map, WeakMap or Set. */ static isLiteralObjectOrNull(obj) { return (CollectionsUtil.isObject(obj) && !CollectionsUtil.isArray(obj) && !CollectionsUtil.isMap(obj) && !CollectionsUtil.isWeakMap(obj) && !CollectionsUtil.isSet(obj)); } /** * ** Check if provided value is literal Object. * * - Not and Array, Map, WeakMap, Set or null. */ static isLiteralObject(obj) { return CollectionsUtil.isLiteralObjectOrNull(obj) && !CollectionsUtil.isNull(obj); } /** * ** Check if value is Object and has properties. */ static isObjectWithProperties(obj) { return CollectionsUtil.isObjectNotNull(obj) && Object.keys(obj).length > 0; } /** * ** Return current Date in ISO string format. */ static dateISO() { return new Date().toISOString(); } /** * ** Return current Date milliseconds from 1970. */ static dateNow() { return Date.now(); } /** * ** Performs deep comparison between two values to determine if the are equivalent. */ static isEqual(value1, value2) { return isEqual(value1, value2); } /** * ** Create recursive deep cloned value from provided one. */ static cloneDeep(value) { return cloneDeep(value); } /** * ** Generate UUID that meats RFC4122 compliance. */ static generateUUID() { // eslint-disable-next-line @typescript-eslint/no-unsafe-call return uuidv4(); } /** * ** Generate Object UUID that meats RFC4122 compliance and also has Class name identifier inside. * * <br/> * <i>pattern</i>: * <p> * <Class Name><strong>_</strong><UUID RFC4122> * </p> */ static generateObjectUUID(className) { return `${className}_${CollectionsUtil.generateUUID()}`; } /** * ** Creates random string. */ static generateRandomString() { return (Math.random() + 1).toString(36).substring(2); } /** * ** Iterates own enumerable properties in Object. * * - use Object.keys method for extraction, and executes provided iteratorFn. * - if iteratorFn returns false or -1 it will break iteration. * - all other return values continue until last property. * * - flag as third parameter is optional: * - Without flag or with flag and has value 'plainObject, method will iterate only through literal Objects. * - With flag and has value 'objectLookLike', method will try to iterate through everything * that passes type value === 'object' (literal Object, Array, Map, Set, WeakMap, etc..). */ static iterateObject(obj, iteratorFn, flag = 'plainObject') { if (!CollectionsUtil.isFunction(iteratorFn)) { return null; } if (flag === 'objectLookLike') { if (!CollectionsUtil.isObjectNotNull(obj)) { return null; } } else { if (!CollectionsUtil.isLiteralObject(obj)) { return null; } } const objectKeys = Object.keys(obj); for (const key of objectKeys) { const resultOfIteratorFn = iteratorFn(obj[key], key, obj); if (resultOfIteratorFn === false || resultOfIteratorFn === -1) { break; } } return obj; } /** * ** Check if value is Literal Object and has properties. */ static isLiteralObjectWithProperties(obj) { return CollectionsUtil.isLiteralObject(obj) && Object.keys(obj).length > 0; } /** * ** Iterates over object properties and return Array of its values. */ static objectValues(obj) { const _result = []; CollectionsUtil.iterateObject(obj, (value) => { _result.push(value); }); return _result; } /** * ** Transform given Map to Object. */ static transformMapToObject(map) { const obj = {}; map.forEach((value, key) => (obj[key] = value)); return obj; } /** * ** Transform given Object to Map. */ static transformObjectToMap(obj) { const map = new Map(); CollectionsUtil.iterateObject(obj, (value, key) => { map.set(key, value); }); return map; } /** * ** Iterates over object properties and return Array of its keys/values in pairs. * <p> * - Returns Array of subArrays that have 2 elements each, first element key and second element value. */ static objectPairs(obj) { if (!CollectionsUtil.isLiteralObject(obj)) { return []; } return Object.entries(obj); } /** * ** Return own property Descriptor from provided object/function. */ static getObjectPropertyDescriptor(obj, key) { if (!((CollectionsUtil.isFunction(obj) || CollectionsUtil.isObject(obj)) && CollectionsUtil.isString(key))) { return null; } return Object.getOwnPropertyDescriptor(obj, key); } /** * ** Iterates own enumerable properties (statics) of Function (Class). * * - use Object.getOwnPropertyDescriptors method for extraction, and executes provided iteratorFn. * - if iteratorFn returns false or -1 will break iteration. * - all other return values means continue until last property. */ static iterateClassStatics(fn, iteratorFn) { if (!CollectionsUtil.isFunction(fn) || !CollectionsUtil.isFunction(iteratorFn)) { return null; } const descriptors = Object.getOwnPropertyDescriptors(fn); CollectionsUtil.iterateObject(descriptors, (descriptor, key) => iteratorFn(descriptor, key, fn)); return fn; } /** * ** Check if two Maps are Equal. * * - They are equal if they have same references. * - They are equal if they have same keys and same values for compared keys. */ static areMapsEqual(m1, m2) { const evaluateDeepComparison = () => { for (const [key, val] of m1) { const compareVal = m2.get(key); if (CollectionsUtil.isMap(val)) { if (!CollectionsUtil.areMapsEqual(val, compareVal)) { return false; } continue; } if (!CollectionsUtil.isEqual(val, compareVal) || (CollectionsUtil.isUndefined(compareVal) && !m2.has(key))) { return false; } } return true; }; return CollectionsUtil.isMap(m1) && CollectionsUtil.isMap(m2) && (m1 === m2 || (m1.size === m2.size && evaluateDeepComparison())); } /** * @inheritDoc */ static interpolateString(target, ...replacers) { let response = target; replacers.forEach((replacer) => { if (CollectionsUtil.isString(replacer)) { response = response.replace('%s', replacer); } else { response = response.replace(replacer.searchValue, replacer.replaceValue); } }); return response; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdGlvbnMtdXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NoYXJlZC9zcmMvbGliL3V0aWxzL2NvbGxlY3Rpb25zL2NvbGxlY3Rpb25zLXV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsdURBQXVEO0FBRXZELE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRTVDLE9BQU8sRUFBRSxFQUFFLElBQUksTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBTXBDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDeEI7O09BRUc7SUFDSCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQVU7UUFDekIsT0FBTyxPQUFPLEtBQUssS0FBSyxXQUFXLENBQUM7SUFDeEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFVO1FBQ3BCLE9BQU8sS0FBSyxLQUFLLElBQUksQ0FBQztJQUMxQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQVU7UUFDbkIsT0FBTyxlQUFlLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLGVBQWUsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLFNBQVMsQ0FBSSxLQUFRO1FBQ3hCLE9BQU8sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsUUFBUSxDQUFtQixHQUFZO1FBQzFDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUSxDQUFDO0lBQ25DLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxR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QUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7b0JBQ3hHLE9BQU8sS0FBSyxDQUFDO2lCQUNoQjthQUNKO1lBRUQsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQyxDQUFDO1FBRUYsT0FBTyxlQUFlLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsSUFBSSxJQUFJLHNCQUFzQixFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RJLENBQUM7SUFlRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFjLEVBQUUsR0FBRyxTQUE2QztRQUNyRixJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUM7UUFFdEIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQW1DLEVBQUUsRUFBRTtZQUN0RCxJQUFJLGVBQWUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBQ3BDLFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQzthQUMvQztpQkFBTTtnQkFDSCxRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUM1RTtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDIzLTIwMjUgQnJvYWRjb21cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuXG5pbXBvcnQgeyBjbG9uZURlZXAsIGlzRXF1YWwgfSBmcm9tICdsb2Rhc2gnO1xuXG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcblxuaW1wb3J0IHsgUmVwbGFjZXIgfSBmcm9tICcuLi8uLi9jb21tb24nO1xuXG5pbXBvcnQgeyBDb2xsZWN0aW9ucywgSXRlcmF0b3JGblJlc3VsdCwgTGl0ZXJhbE9iamVjdE9yTnVsbCwgTmlsLCBPYmplY3RJdGVyYXRvciwgUHJpbWl0aXZlcywgUHJpbWl0aXZlc0RhdGUsIFN1YnRyYWN0IH0gZnJvbSAnLi4vbW9kZWwnO1xuXG4vKipcbiAqICoqIFV0aWxpdHkgQ2xhc3MgZm9yIENvbGxlY3Rpb25zLlxuICovXG5leHBvcnQgY2xhc3MgQ29sbGVjdGlvbnNVdGlsIHtcbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBpcyBvZiB0eXBlIHVuZGVmaW5lZC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNVbmRlZmluZWQodmFsdWU6IGFueSk6IHZhbHVlIGlzIHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGhhcyB2YWx1ZSBudWxsLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc051bGwodmFsdWU6IGFueSk6IHZhbHVlIGlzIG51bGwge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogQ2hlY2sgaWYgdmFsdWUgaXMgdW5kZWZpbmVkIG9yIG51bGwuXG4gICAgICovXG4gICAgc3RhdGljIGlzTmlsKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBOaWwge1xuICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnNVdGlsLmlzTnVsbCh2YWx1ZSkgfHwgQ29sbGVjdGlvbnNVdGlsLmlzVW5kZWZpbmVkKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBpcyBkZWZpbmVkIChvcHBvc2l0ZSBvZiBpc05pbCkuXG4gICAgICpcbiAgICAgKiAgICAgLSBOb3QgbnVsbC5cbiAgICAgKiAgICAgLSBOb3QgdW5kZWZpbmVkLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc0RlZmluZWQ8VD4odmFsdWU6IFQpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICFDb2xsZWN0aW9uc1V0aWwuaXNOdWxsKHZhbHVlKSAmJiAhQ29sbGVjdGlvbnNVdGlsLmlzVW5kZWZpbmVkKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBUIGlzIG9mIHR5cGUgTnVtYmVyLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc051bWJlcjxUIGV4dGVuZHMgbnVtYmVyPihudW06IFQgfCBhbnkpOiBudW0gaXMgbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBudW0gPT09ICdudW1iZXInO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIFQgaXMgb2YgdHlwZSBTdHJpbmcuXG4gICAgICovXG4gICAgc3RhdGljIGlzU3RyaW5nPFQgZXh0ZW5kcyBzdHJpbmc+KHN0cjogVCB8IGFueSk6IHN0ciBpcyBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHN0ciA9PT0gJ3N0cmluZyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogQ2hlY2sgaWYgdmFsdWUgVCBpcyBvZiB0eXBlIEJvb2xlYW4uXG4gICAgICovXG4gICAgc3RhdGljIGlzQm9vbGVhbjxUIGV4dGVuZHMgYm9vbGVhbj4oYm9vbDogVCB8IGFueSk6IGJvb2wgaXMgYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgYm9vbCA9PT0gJ2Jvb2xlYW4nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGlzIFByaW1pdGl2ZS5cbiAgICAgKlxuICAgICAqICAgICAtIFN0cmluZywgTnVtYmVyLCBCb29sZWFuLCBudWxsIG9yIHVuZGVmaW5lZC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNQcmltaXRpdmUodmFsdWU6IGFueSk6IHZhbHVlIGlzIFByaW1pdGl2ZXMgfCBOaWwge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgQ29sbGVjdGlvbnNVdGlsLmlzU3RyaW5nKHZhbHVlKSB8fFxuICAgICAgICAgICAgQ29sbGVjdGlvbnNVdGlsLmlzQm9vbGVhbih2YWx1ZSkgfHxcbiAgICAgICAgICAgIENvbGxlY3Rpb25zVXRpbC5pc051bWJlcih2YWx1ZSkgfHxcbiAgICAgICAgICAgIENvbGxlY3Rpb25zVXRpbC5pc1VuZGVmaW5lZCh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBpcyBOYU4uXG4gICAgICovXG4gICAgc3RhdGljIGlzTmFOPFQgZXh0ZW5kcyBudW1iZXI+KHZhbHVlOiBUIHwgYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4odmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGlzIG9mIHR5cGUgRGF0ZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNEYXRlKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBEYXRlIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgRGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBpcyBQcmltaXRpdmUgb3IgRGF0ZS5cbiAgICAgKlxuICAgICAqICAgICAtIFN0cmluZywgTnVtYmVyLCBCb29sZWFuLCBudWxsLCB1bmRlZmluZWQgb3IgRGF0ZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNQcmltaXRpdmVPckRhdGU8VCBleHRlbmRzIFByaW1pdGl2ZXNEYXRlPih2YWx1ZTogVCB8IGFueSk6IHZhbHVlIGlzIFByaW1pdGl2ZXMgfCBOaWwgfCBEYXRlIHtcbiAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zVXRpbC5pc1ByaW1pdGl2ZSh2YWx1ZSkgfHwgQ29sbGVjdGlvbnNVdGlsLmlzRGF0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogICoqIENoZWNrIGlmIHZhbHVlIFQgaXMgYSByZWZlcmVuY2UgdGhhdCBwb2ludHMgdG8gZnVuY3Rpb24gKENsYXNzL01ldGhvZCkuXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgc3RhdGljIGlzRnVuY3Rpb248VCBleHRlbmRzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55Pih2YWx1ZTogVCB8IGFueSk6IHZhbHVlIGlzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55IHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBUIGlzIG9mIHR5cGUgT2JqZWN0LlxuICAgICAqL1xuICAgIHN0YXRpYyBpc09iamVjdDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KG9iajogVCB8IGFueSk6IG9iaiBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgICAgIHJldHVybiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBUIGlzIGluc3RhbmNlIG9mIEFycmF5LlxuICAgICAqL1xuICAgIHN0YXRpYyBpc0FycmF5PFQ+KGFycjogVCB8IGFueSk6IGFyciBpcyBUIGV4dGVuZHMgYW55W10gPyBUIDogYW55W10ge1xuICAgICAgICByZXR1cm4gYXJyIGluc3RhbmNlb2YgQXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogQ2hlY2sgaWYgdmFsdWUgVCBpcyBub3QgaW5zdGFuY2Ugb2YgQXJyYXkgb3IgdGhlcmUgYXJlIG5vIGVsZW1lbnRzIGluIEFycmF5LlxuICAgICAqL1xuICAgIHN0YXRpYyBpc0FycmF5RW1wdHk8VD4oYXJyOiBUIHwgYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhQ29sbGVjdGlvbnNVdGlsLmlzQXJyYXkoYXJyKSB8fCBhcnIubGVuZ3RoID09PSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIFJldHVybnMgbmV3IEFycmF5IHdoZXJlIGl0ZW1zIHdpbGwgYmUgZmlsdGVyZWQgYnkgcmVmZXJlbmNlIGFuZCB3aWxsIGxlYXZlIGRpc3RpbmN0IHZhbHVlcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgdW5pcXVlQXJyYXk8VCBleHRlbmRzIGFueVtdPihhcnI6IFQpOiBUIHtcbiAgICAgICAgcmV0dXJuIGFyci5maWx0ZXIoKHZhbHVlLCBpbmRleCwgc2VsZikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuaW5kZXhPZih2YWx1ZSkgPT09IGluZGV4O1xuICAgICAgICB9KSBhcyBUO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGlzIE1hcC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNNYXAob2JqOiBNYXA8YW55LCBhbnk+IHwgYW55KTogb2JqIGlzIE1hcDxhbnksIGFueT4ge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTWFwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGlzIFdlYWtNYXAuXG4gICAgICovXG4gICAgc3RhdGljIGlzV2Vha01hcChvYmo6IFdlYWtNYXA8YW55LCBhbnk+IHwgYW55KTogb2JqIGlzIFdlYWtNYXA8YW55LCBhbnk+IHtcbiAgICAgICAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIFdlYWtNYXA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogQ2hlY2sgaWYgdmFsdWUgaXMgU2V0LlxuICAgICAqL1xuICAgIHN0YXRpYyBpc1NldChvYmo6IFNldDxhbnk+IHwgYW55KTogb2JqIGlzIFNldDxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIFNldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBUIGlzIG9mIHR5cGUgU3RyaW5nIGFuZCBoYXMgbGVuZ3RoIGJpZ2dlciB0aGFuIDAgYWZ0ZXIgd2hpdGVzcGFjZSB0cmltLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc1N0cmluZ1dpdGhDb250ZW50PFQgZXh0ZW5kcyBzdHJpbmc+KHN0cjogVCB8IGFueSk6IHN0ciBpcyBzdHJpbmcge1xuICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnNVdGlsLmlzU3RyaW5nKHN0cikgJiYgc3RyLnRyaW0oKS5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGlzIENvbGxlY3Rpb24gKGxpdGVyYWwgT2JqZWN0LCBBcnJheSwgTWFwLCBXZWFrTWFwIG9yIFNldCkuXG4gICAgICovXG4gICAgc3RhdGljIGlzQ29sbGVjdGlvbihvYmo6IENvbGxlY3Rpb25zIHwgYW55KTogb2JqIGlzIENvbGxlY3Rpb25zIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIENvbGxlY3Rpb25zVXRpbC5pc0FycmF5KG9iaikgfHxcbiAgICAgICAgICAgIENvbGxlY3Rpb25zVXRpbC5pc01hcChvYmopIHx8XG4gICAgICAgICAgICBDb2xsZWN0aW9uc1V0aWwuaXNXZWFrTWFwKG9iaikgfHxcbiAgICAgICAgICAgIENvbGxlY3Rpb25zVXRpbC5pc1NldChvYmopIHx8XG4gICAgICAgICAgICBDb2xsZWN0aW9uc1V0aWwuaXNMaXRlcmFsT2JqZWN0KG9iailcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBpcyBvZiB0eXBlIE9iamVjdCBhbmQgbm90IG51bGwuXG4gICAgICovXG4gICAgc3RhdGljIGlzT2JqZWN0Tm90TnVsbDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICAgICAgICBvYmo6IFQgfCBhbnlcbiAgICApOiBvYmogaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gJiBTdWJ0cmFjdDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgbnVsbD4ge1xuICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnNVdGlsLmlzT2JqZWN0PFQ+KG9iaikgJiYgIUNvbGxlY3Rpb25zVXRpbC5pc051bGwob2JqKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiBzb21lIHZhcmlhYmxlIGlzIG9mIHR5cGUgQm9vbGVhbiBhbmQgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNCb29sZWFuQW5kVHJ1ZShib29sOiBib29sZWFuIHwgYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBDb2xsZWN0aW9uc1V0aWwuaXNCb29sZWFuKGJvb2wpICYmIGJvb2w7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogQ2hlY2sgaWYgdmFsdWUgaXMgbGl0ZXJhbCBPYmplY3Qgb3IgbnVsbC5cbiAgICAgKlxuICAgICAqICAgICAtIE5vdCBhbiBBcnJheSwgTWFwLCBXZWFrTWFwIG9yIFNldC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNMaXRlcmFsT2JqZWN0T3JOdWxsPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ob2JqOiBUIHwgYW55KTogb2JqIGlzIExpdGVyYWxPYmplY3RPck51bGwge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgQ29sbGVjdGlvbnNVdGlsLmlzT2JqZWN0KG9iaikgJiZcbiAgICAgICAgICAgICFDb2xsZWN0aW9uc1V0aWwuaXNBcnJheShvYmopICYmXG4gICAgICAgICAgICAhQ29sbGVjdGlvbnNVdGlsLmlzTWFwKG9iaikgJiZcbiAgICAgICAgICAgICFDb2xsZWN0aW9uc1V0aWwuaXNXZWFrTWFwKG9iaikgJiZcbiAgICAgICAgICAgICFDb2xsZWN0aW9uc1V0aWwuaXNTZXQob2JqKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHByb3ZpZGVkIHZhbHVlIGlzIGxpdGVyYWwgT2JqZWN0LlxuICAgICAqXG4gICAgICogICAgIC0gTm90IGFuZCBBcnJheSwgTWFwLCBXZWFrTWFwLCBTZXQgb3IgbnVsbC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNMaXRlcmFsT2JqZWN0PFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ob2JqOiBUIHwgYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBDb2xsZWN0aW9uc1V0aWwuaXNMaXRlcmFsT2JqZWN0T3JOdWxsKG9iaikgJiYgIUNvbGxlY3Rpb25zVXRpbC5pc051bGwob2JqKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDaGVjayBpZiB2YWx1ZSBpcyBPYmplY3QgYW5kIGhhcyBwcm9wZXJ0aWVzLlxuICAgICAqL1xuICAgIHN0YXRpYyBpc09iamVjdFdpdGhQcm9wZXJ0aWVzPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ob2JqOiBUIHwgYW55KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBDb2xsZWN0aW9uc1V0aWwuaXNPYmplY3ROb3ROdWxsKG9iaikgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIFJldHVybiBjdXJyZW50IERhdGUgaW4gSVNPIHN0cmluZyBmb3JtYXQuXG4gICAgICovXG4gICAgc3RhdGljIGRhdGVJU08oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBSZXR1cm4gY3VycmVudCBEYXRlIG1pbGxpc2Vjb25kcyBmcm9tIDE5NzAuXG4gICAgICovXG4gICAgc3RhdGljIGRhdGVOb3coKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIERhdGUubm93KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogUGVyZm9ybXMgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhlIGFyZSBlcXVpdmFsZW50LlxuICAgICAqL1xuICAgIHN0YXRpYyBpc0VxdWFsKHZhbHVlMTogYW55LCB2YWx1ZTI6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gaXNFcXVhbCh2YWx1ZTEsIHZhbHVlMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogQ3JlYXRlIHJlY3Vyc2l2ZSBkZWVwIGNsb25lZCB2YWx1ZSBmcm9tIHByb3ZpZGVkIG9uZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgY2xvbmVEZWVwPFQ+KHZhbHVlOiBUKTogVCB7XG4gICAgICAgIHJldHVybiBjbG9uZURlZXAodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIEdlbmVyYXRlIFVVSUQgdGhhdCBtZWF0cyBSRkM0MTIyIGNvbXBsaWFuY2UuXG4gICAgICovXG4gICAgc3RhdGljIGdlbmVyYXRlVVVJRCgpOiBzdHJpbmcge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsXG4gICAgICAgIHJldHVybiB1dWlkdjQoKSBhcyBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogR2VuZXJhdGUgT2JqZWN0IFVVSUQgdGhhdCBtZWF0cyBSRkM0MTIyIGNvbXBsaWFuY2UgYW5kIGFsc28gaGFzIENsYXNzIG5hbWUgaWRlbnRpZmllciBpbnNpZGUuXG4gICAgICpcbiAgICAgKiA8YnIvPlxuICAgICAqIDxpPnBhdHRlcm48L2k+OlxuICAgICAqIDxwPlxuICAgICAqICAgICA8Q2xhc3MgTmFtZT48c3Ryb25nPl88L3N0cm9uZz48VVVJRCBSRkM0MTIyPlxuICAgICAqIDwvcD5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2VuZXJhdGVPYmplY3RVVUlEKGNsYXNzTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGAke2NsYXNzTmFtZX1fJHtDb2xsZWN0aW9uc1V0aWwuZ2VuZXJhdGVVVUlEKCl9YDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBDcmVhdGVzIHJhbmRvbSBzdHJpbmcuXG4gICAgICovXG4gICAgc3RhdGljIGdlbmVyYXRlUmFuZG9tU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAoTWF0aC5yYW5kb20oKSArIDEpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogSXRlcmF0ZXMgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBpbiBPYmplY3QuXG4gICAgICpcbiAgICAgKiAgICAgLSB1c2UgT2JqZWN0LmtleXMgbWV0aG9kIGZvciBleHRyYWN0aW9uLCBhbmQgZXhlY3V0ZXMgcHJvdmlkZWQgaXRlcmF0b3JGbi5cbiAgICAgKiAgICAgLSBpZiBpdGVyYXRvckZuIHJldHVybnMgZmFsc2Ugb3IgLTEgaXQgd2lsbCBicmVhayBpdGVyYXRpb24uXG4gICAgICogICAgIC0gYWxsIG90aGVyIHJldHVybiB2YWx1ZXMgY29udGludWUgdW50aWwgbGFzdCBwcm9wZXJ0eS5cbiAgICAgKlxuICAgICAqICAgICAtIGZsYWcgYXMgdGhpcmQgcGFyYW1ldGVyIGlzIG9wdGlvbmFsOlxuICAgICAqICAgICAgICAgIC0gV2l0aG91dCBmbGFnIG9yIHdpdGggZmxhZyBhbmQgaGFzIHZhbHVlICdwbGFpbk9iamVjdCwgbWV0aG9kIHdpbGwgaXRlcmF0ZSBvbmx5IHRocm91Z2ggbGl0ZXJhbCBPYmplY3RzLlxuICAgICAqICAgICAgICAgIC0gV2l0aCBmbGFnIGFuZCBoYXMgdmFsdWUgJ29iamVjdExvb2tMaWtlJywgbWV0aG9kIHdpbGwgdHJ5IHRvIGl0ZXJhdGUgdGhyb3VnaCBldmVyeXRoaW5nXG4gICAgICogICAgICAgICAgICAgICAgICB0aGF0IHBhc3NlcyB0eXBlIHZhbHVlID09PSAnb2JqZWN0JyAobGl0ZXJhbCBPYmplY3QsIEFycmF5LCBNYXAsIFNldCwgV2Vha01hcCwgZXRjLi4pLlxuICAgICAqL1xuICAgIHN0YXRpYyBpdGVyYXRlT2JqZWN0PFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgICAgIG9iajogVCxcbiAgICAgICAgaXRlcmF0b3JGbjogT2JqZWN0SXRlcmF0b3I8VCwgSXRlcmF0b3JGblJlc3VsdD4sXG4gICAgICAgIGZsYWc6ICdwbGFpbk9iamVjdCcgfCAnb2JqZWN0TG9va0xpa2UnID0gJ3BsYWluT2JqZWN0J1xuICAgICk6IFQgfCBudWxsIHtcbiAgICAgICAgaWYgKCFDb2xsZWN0aW9uc1V0aWwuaXNGdW5jdGlvbihpdGVyYXRvckZuKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmxhZyA9PT0gJ29iamVjdExvb2tMaWtlJykge1xuICAgICAgICAgICAgaWYgKCFDb2xsZWN0aW9uc1V0aWwuaXNPYmplY3ROb3ROdWxsKG9iaikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghQ29sbGVjdGlvbnNVdGlsLmlzTGl0ZXJhbE9iamVjdChvYmopKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2Ygb2JqZWN0S2V5cykge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0T2ZJdGVyYXRvckZuID0gaXRlcmF0b3JGbihvYmpba2V5XSBhcyBUW2tleW9mIFRdLCBrZXksIG9iaik7XG4gICAgICAgICAgICBpZiAocmVzdWx0T2ZJdGVyYXRvckZuID09PSBmYWxzZSB8fCByZXN1bHRPZkl0ZXJhdG9yRm4gPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHZhbHVlIGlzIExpdGVyYWwgT2JqZWN0IGFuZCBoYXMgcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNMaXRlcmFsT2JqZWN0V2l0aFByb3BlcnRpZXM8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+PihvYmo6IFQgfCB1bmtub3duKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBDb2xsZWN0aW9uc1V0aWwuaXNMaXRlcmFsT2JqZWN0PFQ+KG9iaikgJiYgT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIEl0ZXJhdGVzIG92ZXIgb2JqZWN0IHByb3BlcnRpZXMgYW5kIHJldHVybiBBcnJheSBvZiBpdHMgdmFsdWVzLlxuICAgICAqL1xuICAgIHN0YXRpYyBvYmplY3RWYWx1ZXM8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+KG9iajogVCB8IG51bGwgfCB1bmRlZmluZWQpOiBBcnJheTxUW2tleW9mIFRdPiB7XG4gICAgICAgIGNvbnN0IF9yZXN1bHQ6IEFycmF5PFRba2V5b2YgVF0+ID0gW107XG5cbiAgICAgICAgQ29sbGVjdGlvbnNVdGlsLml0ZXJhdGVPYmplY3Qob2JqLCAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIF9yZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBfcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIFRyYW5zZm9ybSBnaXZlbiBNYXAgdG8gT2JqZWN0LlxuICAgICAqL1xuICAgIHN0YXRpYyB0cmFuc2Zvcm1NYXBUb09iamVjdDxUIGV4dGVuZHMgTWFwPHN0cmluZywgdW5rbm93bj4+KG1hcDogVCk6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9IHtcbiAgICAgICAgY29uc3Qgb2JqOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG5cbiAgICAgICAgbWFwLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IChvYmpba2V5XSA9IHZhbHVlKSk7XG5cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBUcmFuc2Zvcm0gZ2l2ZW4gT2JqZWN0IHRvIE1hcC5cbiAgICAgKi9cbiAgICBzdGF0aWMgdHJhbnNmb3JtT2JqZWN0VG9NYXA8VCBleHRlbmRzIHsgW2tleTogc3RyaW5nXTogYW55IH0+KG9iajogVCk6IE1hcDxzdHJpbmcsIGFueT4ge1xuICAgICAgICBjb25zdCBtYXAgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuXG4gICAgICAgIENvbGxlY3Rpb25zVXRpbC5pdGVyYXRlT2JqZWN0KG9iaiwgKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgIG1hcC5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBtYXA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogSXRlcmF0ZXMgb3ZlciBvYmplY3QgcHJvcGVydGllcyBhbmQgcmV0dXJuIEFycmF5IG9mIGl0cyBrZXlzL3ZhbHVlcyBpbiBwYWlycy5cbiAgICAgKiA8cD5cbiAgICAgKiAgICAgLSBSZXR1cm5zIEFycmF5IG9mIHN1YkFycmF5cyB0aGF0IGhhdmUgMiBlbGVtZW50cyBlYWNoLCBmaXJzdCBlbGVtZW50IGtleSBhbmQgc2Vjb25kIGVsZW1lbnQgdmFsdWUuXG4gICAgICovXG4gICAgc3RhdGljIG9iamVjdFBhaXJzPFQgZXh0ZW5kcyBSZWNvcmQ8a2V5b2YgVCwgVFtrZXlvZiBUXT4+KG9iajogVCB8IG51bGwgfCB1bmRlZmluZWQpOiBBcnJheTxba2V5b2YgVCwgVFtrZXlvZiBUXV0+IHtcbiAgICAgICAgaWYgKCFDb2xsZWN0aW9uc1V0aWwuaXNMaXRlcmFsT2JqZWN0KG9iaikpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyhvYmopIGFzIEFycmF5PFtrZXlvZiBULCBUW2tleW9mIFRdXT47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogKiogUmV0dXJuIG93biBwcm9wZXJ0eSBEZXNjcmlwdG9yIGZyb20gcHJvdmlkZWQgb2JqZWN0L2Z1bmN0aW9uLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRPYmplY3RQcm9wZXJ0eURlc2NyaXB0b3I8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+KG9iajogVCwga2V5OiBzdHJpbmcpOiBQcm9wZXJ0eURlc2NyaXB0b3Ige1xuICAgICAgICBpZiAoISgoQ29sbGVjdGlvbnNVdGlsLmlzRnVuY3Rpb24ob2JqKSB8fCBDb2xsZWN0aW9uc1V0aWwuaXNPYmplY3Qob2JqKSkgJiYgQ29sbGVjdGlvbnNVdGlsLmlzU3RyaW5nKGtleSkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqKiBJdGVyYXRlcyBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIChzdGF0aWNzKSBvZiBGdW5jdGlvbiAoQ2xhc3MpLlxuICAgICAqXG4gICAgICogICAgIC0gdXNlIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIG1ldGhvZCBmb3IgZXh0cmFjdGlvbiwgYW5kIGV4ZWN1dGVzIHByb3ZpZGVkIGl0ZXJhdG9yRm4uXG4gICAgICogICAgIC0gaWYgaXRlcmF0b3JGbiByZXR1cm5zIGZhbHNlIG9yIC0xIHdpbGwgYnJlYWsgaXRlcmF0aW9uLlxuICAgICAqICAgICAtIGFsbCBvdGhlciByZXR1cm4gdmFsdWVzIG1lYW5zIGNvbnRpbnVlIHVudGlsIGxhc3QgcHJvcGVydHkuXG4gICAgICovXG4gICAgc3RhdGljIGl0ZXJhdGVDbGFzc1N0YXRpY3M8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+KFxuICAgICAgICBmbjogVCxcbiAgICAgICAgaXRlcmF0b3JGbjogKGRlc2NyaXB0b3I6IFByb3BlcnR5RGVzY3JpcHRvciwga2V5OiBzdHJpbmcsIGZuOiBUKSA9PiBJdGVyYXRvckZuUmVzdWx0XG4gICAgKSB7XG4gICAgICAgIGlmICghQ29sbGVjdGlvbnNVdGlsLmlzRnVuY3Rpb24oZm4pIHx8ICFDb2xsZWN0aW9uc1V0aWwuaXNGdW5jdGlvbihpdGVyYXRvckZuKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZXNjcmlwdG9ycyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKGZuKTtcbiAgICAgICAgQ29sbGVjdGlvbnNVdGlsLml0ZXJhdGVPYmplY3QoZGVzY3JpcHRvcnMsIChkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3IsIGtleSkgPT4gaXRlcmF0b3JGbihkZXNjcmlwdG9yLCBrZXksIGZuKSk7XG5cbiAgICAgICAgcmV0dXJuIGZuO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIENoZWNrIGlmIHR3byBNYXBzIGFyZSBFcXVhbC5cbiAgICAgKlxuICAgICAqICAgLSBUaGV5IGFyZSBlcXVhbCBpZiB0aGV5IGhhdmUgc2FtZSByZWZlcmVuY2VzLlxuICAgICAqICAgLSBUaGV5IGFyZSBlcXVhbCBpZiB0aGV5IGhhdmUgc2FtZSBrZXlzIGFuZCBzYW1lIHZhbHVlcyBmb3IgY29tcGFyZWQga2V5cy5cbiAgICAgKi9cbiAgICBzdGF0aWMgYXJlTWFwc0VxdWFsKG0xOiBNYXA8dW5rbm93biwgdW5rbm93bj4sIG0yOiBNYXA8dW5rbm93biwgdW5rbm93bj4pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgZXZhbHVhdGVEZWVwQ29tcGFyaXNvbiA9ICgpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsXSBvZiBtMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBhcmVWYWwgPSBtMi5nZXQoa2V5KTtcblxuICAgICAgICAgICAgICAgIGlmIChDb2xsZWN0aW9uc1V0aWwuaXNNYXAodmFsKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIUNvbGxlY3Rpb25zVXRpbC5hcmVNYXBzRXF1YWwodmFsLCBjb21wYXJlVmFsIGFzIE1hcDx1bmtub3duLCB1bmtub3duPikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghQ29sbGVjdGlvbnNVdGlsLmlzRXF1YWwodmFsLCBjb21wYXJlVmFsKSB8fCAoQ29sbGVjdGlvbnNVdGlsLmlzVW5kZWZpbmVkKGNvbXBhcmVWYWwpICYmICFtMi5oYXMoa2V5KSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zVXRpbC5pc01hcChtMSkgJiYgQ29sbGVjdGlvbnNVdGlsLmlzTWFwKG0yKSAmJiAobTEgPT09IG0yIHx8IChtMS5zaXplID09PSBtMi5zaXplICYmIGV2YWx1YXRlRGVlcENvbXBhcmlzb24oKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqICoqIEludGVycG9sYXRlIHN0cmluZyBhbmQgcmVwbGFjZSB3aGlsZSBpdGVyYXRpbmcgdGhyb3VnaCBwcm92aWRlZCBzdHJpbmdzLlxuICAgICAqXG4gICAgICogICAgICAtIFJlcGxhY2VycyBhcmUgc3RyaW5ncyB0aGF0IGFyZSByZXBsYWNlZCBvbiBldmVyeSBwbGFjZSB3aGVyZSAlcyBpcyBmb3VuZCBzdGFydGluZyBmcm9tIGluZGV4IDAuXG4gICAgICovXG4gICAgc3RhdGljIGludGVycG9sYXRlU3RyaW5nKHRhcmdldDogc3RyaW5nLCAuLi5yZXBsYWNlcnM6IHN0cmluZ1tdKTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqICoqIEludGVycG9sYXRlIHRleHQgYW5kIHJlcGxhY2Ugd2hpbGUgaXRlcmF0aW5nIHRocm91Z2ggcHJvdmlkZWQgcmVwbGFjZXJzLlxuICAgICAqXG4gICAgICogICAgICAtIFJlcGxhY2VycyBhcmUgb2JqZWN0cyBvZlR5cGUge0BsaW5rIFJlcGxhY2VyfSB0aGF0IGFyZSBpdGVyYXRlcyBhbmQgY29uc3VtZXMsXG4gICAgICogICAgICAgICAgICAgIHNlYXJjaFZhbHVlIGlzIG1hdGNoZXIgYW5kIHJlcGxhY2VWYWx1ZSBpcyB2YWx1ZSB0aGF0IGlzIHBsYWNlZCBvbiBtYXRjaC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaW50ZXJwb2xhdGVTdHJpbmcodGFyZ2V0OiBzdHJpbmcsIC4uLnJlcGxhY2VyczogQXJyYXk8UmVwbGFjZXI8c3RyaW5nPj4pOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQGluaGVyaXREb2NcbiAgICAgKi9cbiAgICBzdGF0aWMgaW50ZXJwb2xhdGVTdHJpbmcodGFyZ2V0OiBzdHJpbmcsIC4uLnJlcGxhY2Vyczogc3RyaW5nW10gfCBBcnJheTxSZXBsYWNlcjxzdHJpbmc+Pik6IHN0cmluZyB7XG4gICAgICAgIGxldCByZXNwb25zZSA9IHRhcmdldDtcblxuICAgICAgICByZXBsYWNlcnMuZm9yRWFjaCgocmVwbGFjZXI6IHN0cmluZyB8IFJlcGxhY2VyPHN0cmluZz4pID0+IHtcbiAgICAgICAgICAgIGlmIChDb2xsZWN0aW9uc1V0aWwuaXNTdHJpbmcocmVwbGFjZXIpKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5yZXBsYWNlKCclcycsIHJlcGxhY2VyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5yZXBsYWNlKHJlcGxhY2VyLnNlYXJjaFZhbHVlLCByZXBsYWNlci5yZXBsYWNlVmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxufVxuIl19