ngx-vest-forms
Version:
Opinionated template-driven forms library for Angular
180 lines • 20.1 kB
JavaScript
import { FormArray, FormGroup } from '@angular/forms';
import { ROOT_FORM } from '../constants';
/**
* Recursively calculates the path of a form control
* @param formGroup
* @param control
*/
function getControlPath(formGroup, control) {
for (const key in formGroup.controls) {
if (formGroup.controls.hasOwnProperty(key)) {
const ctrl = formGroup.get(key);
if (ctrl instanceof FormGroup) {
const path = getControlPath(ctrl, control);
if (path) {
return key + '.' + path;
}
}
else if (ctrl === control) {
return key;
}
}
}
return '';
}
/**
* Recursively calculates the path of a form group
* @param formGroup
* @param control
*/
function getGroupPath(formGroup, control) {
for (const key in formGroup.controls) {
if (formGroup.controls.hasOwnProperty(key)) {
const ctrl = formGroup.get(key);
if (ctrl === control) {
return key;
}
if (ctrl instanceof FormGroup) {
const path = getGroupPath(ctrl, control);
if (path) {
return key + '.' + path;
}
}
}
}
return '';
}
/**
* Calculates the field name of a form control: Eg: addresses.shippingAddress.street
* @param rootForm
* @param control
*/
export function getFormControlField(rootForm, control) {
return getControlPath(rootForm, control);
}
/**
* Calcuates the field name of a form group Eg: addresses.shippingAddress
* @param rootForm
* @param control
*/
export function getFormGroupField(rootForm, control) {
return getGroupPath(rootForm, control);
}
/**
* This RxJS operator merges the value of the form with the raw value.
* By doing this we can assure that we don't lose values of disabled form fields
* @param form
*/
export function mergeValuesAndRawValues(form) {
// Retrieve the standard values (respecting references)
const value = { ...form.value };
// Retrieve the raw values (including disabled values)
const rawValue = form.getRawValue();
// Recursive function to merge rawValue into value
function mergeRecursive(target, source) {
Object.keys(source).forEach((key) => {
if (target[key] === undefined) {
// If the key is not in the target, add it directly (for disabled fields)
target[key] = source[key];
}
else if (typeof source[key] === 'object' &&
source[key] !== null &&
!Array.isArray(source[key])) {
// If the value is an object, merge it recursively
mergeRecursive(target[key], source[key]);
}
// If the target already has the key with a primitive value, it's left as is to maintain references
});
}
mergeRecursive(value, rawValue);
return value;
}
function isPrimitive(value) {
return (value === null || (typeof value !== 'object' && typeof value !== 'function'));
}
/**
* Performs a deep-clone of an object
* @param obj
*/
export function cloneDeep(obj) {
// Handle primitives (null, undefined, boolean, string, number, function)
if (isPrimitive(obj)) {
return obj;
}
// Handle Date
if (obj instanceof Date) {
return new Date(obj.getTime());
}
// Handle Array
if (Array.isArray(obj)) {
return obj.map((item) => cloneDeep(item));
}
// Handle Object
if (obj instanceof Object) {
const clonedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = cloneDeep(obj[key]);
}
}
return clonedObj;
}
throw new Error("Unable to copy object! Its type isn't supported.");
}
/**
* Sets a value in an object in the correct path
* @param obj
* @param path
* @param value
*/
export function set(obj, path, value) {
const keys = path.split('.');
let current = obj;
for (let i = 0; i < keys.length - 1; i++) {
const key = keys[i];
if (!current[key]) {
current[key] = {};
}
current = current[key];
}
current[keys[keys.length - 1]] = value;
}
/**
* Traverses the form and returns the errors by path
* @param form
*/
export function getAllFormErrors(form) {
const errors = {};
if (!form) {
return errors;
}
function collect(control, path) {
if (control instanceof FormGroup || control instanceof FormArray) {
Object.keys(control.controls).forEach((key) => {
const childControl = control.get(key);
const controlPath = path ? `${path}.${key}` : key;
if (path && control.errors && control.enabled) {
Object.keys(control.errors).forEach((errorKey) => {
errors[path] = control.errors[errorKey];
});
}
if (childControl) {
collect(childControl, controlPath);
}
});
}
else {
if (control.errors && control.enabled) {
Object.keys(control.errors).forEach((errorKey) => {
errors[path] = control.errors[errorKey];
});
}
}
}
collect(form, '');
if (form.errors && form.errors['errors']) {
errors[ROOT_FORM] = form.errors && form.errors['errors'];
}
return errors;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS11dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12ZXN0LWZvcm1zL3NyYy9saWIvdXRpbHMvZm9ybS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW1CLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXpDOzs7O0dBSUc7QUFDSCxTQUFTLGNBQWMsQ0FDckIsU0FBb0IsRUFDcEIsT0FBd0I7SUFFeEIsS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzNDLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEMsSUFBSSxJQUFJLFlBQVksU0FBUyxFQUFFLENBQUM7Z0JBQzlCLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQzNDLElBQUksSUFBSSxFQUFFLENBQUM7b0JBQ1QsT0FBTyxHQUFHLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQztnQkFDMUIsQ0FBQztZQUNILENBQUM7aUJBQU0sSUFBSSxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQzVCLE9BQU8sR0FBRyxDQUFDO1lBQ2IsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsWUFBWSxDQUFDLFNBQW9CLEVBQUUsT0FBd0I7SUFDbEUsS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckMsSUFBSSxTQUFTLENBQUMsUUFBUSxD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Q3JDLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7b0JBQy9DLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMzQyxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbEIsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtQXJyYXksIEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFJPT1RfRk9STSB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgY2FsY3VsYXRlcyB0aGUgcGF0aCBvZiBhIGZvcm0gY29udHJvbFxuICogQHBhcmFtIGZvcm1Hcm91cFxuICogQHBhcmFtIGNvbnRyb2xcbiAqL1xuZnVuY3Rpb24gZ2V0Q29udHJvbFBhdGgoXG4gIGZvcm1Hcm91cDogRm9ybUdyb3VwLFxuICBjb250cm9sOiBBYnN0cmFjdENvbnRyb2xcbik6IHN0cmluZyB7XG4gIGZvciAoY29uc3Qga2V5IGluIGZvcm1Hcm91cC5jb250cm9scykge1xuICAgIGlmIChmb3JtR3JvdXAuY29udHJvbHMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29uc3QgY3RybCA9IGZvcm1Hcm91cC5nZXQoa2V5KTtcbiAgICAgIGlmIChjdHJsIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBnZXRDb250cm9sUGF0aChjdHJsLCBjb250cm9sKTtcbiAgICAgICAgaWYgKHBhdGgpIHtcbiAgICAgICAgICByZXR1cm4ga2V5ICsgJy4nICsgcGF0aDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjdHJsID09PSBjb250cm9sKSB7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBjYWxjdWxhdGVzIHRoZSBwYXRoIG9mIGEgZm9ybSBncm91cFxuICogQHBhcmFtIGZvcm1Hcm91cFxuICogQHBhcmFtIGNvbnRyb2xcbiAqL1xuZnVuY3Rpb24gZ2V0R3JvdXBQYXRoKGZvcm1Hcm91cDogRm9ybUdyb3VwLCBjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBzdHJpbmcge1xuICBmb3IgKGNvbnN0IGtleSBpbiBmb3JtR3JvdXAuY29udHJvbHMpIHtcbiAgICBpZiAoZm9ybUdyb3VwLmNvbnRyb2xzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnN0IGN0cmwgPSBmb3JtR3JvdXAuZ2V0KGtleSk7XG4gICAgICBpZiAoY3RybCA9PT0gY29udHJvbCkge1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgfVxuICAgICAgaWYgKGN0cmwgaW5zdGFuY2VvZiBGb3JtR3JvdXApIHtcbiAgICAgICAgY29uc3QgcGF0aCA9IGdldEdyb3VwUGF0aChjdHJsLCBjb250cm9sKTtcbiAgICAgICAgaWYgKHBhdGgpIHtcbiAgICAgICAgICByZXR1cm4ga2V5ICsgJy4nICsgcGF0aDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZmllbGQgbmFtZSBvZiBhIGZvcm0gY29udHJvbDogRWc6IGFkZHJlc3Nlcy5zaGlwcGluZ0FkZHJlc3Muc3RyZWV0XG4gKiBAcGFyYW0gcm9vdEZvcm1cbiAqIEBwYXJhbSBjb250cm9sXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtQ29udHJvbEZpZWxkKFxuICByb290Rm9ybTogRm9ybUdyb3VwLFxuICBjb250cm9sOiBBYnN0cmFjdENvbnRyb2xcbik6IHN0cmluZyB7XG4gIHJldHVybiBnZXRDb250cm9sUGF0aChyb290Rm9ybSwgY29udHJvbCk7XG59XG5cbi8qKlxuICogQ2FsY3VhdGVzIHRoZSBmaWVsZCBuYW1lIG9mIGEgZm9ybSBncm91cCBFZzogYWRkcmVzc2VzLnNoaXBwaW5nQWRkcmVzc1xuICogQHBhcmFtIHJvb3RGb3JtXG4gKiBAcGFyYW0gY29udHJvbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybUdyb3VwRmllbGQoXG4gIHJvb3RGb3JtOiBGb3JtR3JvdXAsXG4gIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldEdyb3VwUGF0aChyb290Rm9ybSwgY29udHJvbCk7XG59XG5cbi8qKlxuICogVGhpcyBSeEpTIG9wZXJhdG9yIG1lcmdlcyB0aGUgdmFsdWUgb2YgdGhlIGZvcm0gd2l0aCB0aGUgcmF3IHZhbHVlLlxuICogQnkgZG9pbmcgdGhpcyB3ZSBjYW4gYXNzdXJlIHRoYXQgd2UgZG9uJ3QgbG9zZSB2YWx1ZXMgb2YgZGlzYWJsZWQgZm9ybSBmaWVsZHNcbiAqIEBwYXJhbSBmb3JtXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZVZhbHVlc0FuZFJhd1ZhbHVlczxUPihmb3JtOiBGb3JtR3JvdXApOiBUIHtcbiAgLy8gUmV0cmlldmUgdGhlIHN0YW5kYXJkIHZhbHVlcyAocmVzcGVjdGluZyByZWZlcmVuY2VzKVxuICBjb25zdCB2YWx1ZSA9IHsgLi4uZm9ybS52YWx1ZSB9O1xuXG4gIC8vIFJldHJpZXZlIHRoZSByYXcgdmFsdWVzIChpbmNsdWRpbmcgZGlzYWJsZWQgdmFsdWVzKVxuICBjb25zdCByYXdWYWx1ZSA9IGZvcm0uZ2V0UmF3VmFsdWUoKTtcblxuICAvLyBSZWN1cnNpdmUgZnVuY3Rpb24gdG8gbWVyZ2UgcmF3VmFsdWUgaW50byB2YWx1ZVxuICBmdW5jdGlvbiBtZXJnZVJlY3Vyc2l2ZSh0YXJnZXQ6IGFueSwgc291cmNlOiBhbnkpIHtcbiAgICBPYmplY3Qua2V5cyhzb3VyY2UpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgaWYgKHRhcmdldFtrZXldID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gSWYgdGhlIGtleSBpcyBub3QgaW4gdGhlIHRhcmdldCwgYWRkIGl0IGRpcmVjdGx5IChmb3IgZGlzYWJsZWQgZmllbGRzKVxuICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIHNvdXJjZVtrZXldID09PSAnb2JqZWN0JyAmJlxuICAgICAgICBzb3VyY2Vba2V5XSAhPT0gbnVsbCAmJlxuICAgICAgICAhQXJyYXkuaXNBcnJheShzb3VyY2Vba2V5XSlcbiAgICAgICkge1xuICAgICAgICAvLyBJZiB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0LCBtZXJnZSBpdCByZWN1cnNpdmVseVxuICAgICAgICBtZXJnZVJlY3Vyc2l2ZSh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xuICAgICAgfVxuICAgICAgLy8gSWYgdGhlIHRhcmdldCBhbHJlYWR5IGhhcyB0aGUga2V5IHdpdGggYSBwcmltaXRpdmUgdmFsdWUsIGl0J3MgbGVmdCBhcyBpcyB0byBtYWludGFpbiByZWZlcmVuY2VzXG4gICAgfSk7XG4gIH1cblxuICBtZXJnZVJlY3Vyc2l2ZSh2YWx1ZSwgcmF3VmFsdWUpO1xuICByZXR1cm4gdmFsdWU7XG59XG5cbnR5cGUgUHJpbWl0aXZlID0gdW5kZWZpbmVkIHwgbnVsbCB8IGJvb2xlYW4gfCBzdHJpbmcgfCBudW1iZXIgfCBGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUodmFsdWU6IGFueSk6IHZhbHVlIGlzIFByaW1pdGl2ZSB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgPT09IG51bGwgfHwgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nKVxuICApO1xufVxuXG4vKipcbiAqIFBlcmZvcm1zIGEgZGVlcC1jbG9uZSBvZiBhbiBvYmplY3RcbiAqIEBwYXJhbSBvYmpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lRGVlcDxUPihvYmo6IFQpOiBUIHtcbiAgLy8gSGFuZGxlIHByaW1pdGl2ZXMgKG51bGwsIHVuZGVmaW5lZCwgYm9vbGVhbiwgc3RyaW5nLCBudW1iZXIsIGZ1bmN0aW9uKVxuICBpZiAoaXNQcmltaXRpdmUob2JqKSkge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICAvLyBIYW5kbGUgRGF0ZVxuICBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShvYmouZ2V0VGltZSgpKSBhcyBhbnkgYXMgVDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBBcnJheVxuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIG9iai5tYXAoKGl0ZW0pID0+IGNsb25lRGVlcChpdGVtKSkgYXMgYW55IGFzIFQ7XG4gIH1cblxuICAvLyBIYW5kbGUgT2JqZWN0XG4gIGlmIChvYmogaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICBjb25zdCBjbG9uZWRPYmo6IGFueSA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IGluIG9iaikge1xuICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIGNsb25lZE9ialtrZXldID0gY2xvbmVEZWVwKChvYmogYXMgYW55KVtrZXldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNsb25lZE9iaiBhcyBUO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKFwiVW5hYmxlIHRvIGNvcHkgb2JqZWN0ISBJdHMgdHlwZSBpc24ndCBzdXBwb3J0ZWQuXCIpO1xufVxuXG4vKipcbiAqIFNldHMgYSB2YWx1ZSBpbiBhbiBvYmplY3QgaW4gdGhlIGNvcnJlY3QgcGF0aFxuICogQHBhcmFtIG9ialxuICogQHBhcmFtIHBhdGhcbiAqIEBwYXJhbSB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0KG9iajogb2JqZWN0LCBwYXRoOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoJy4nKTtcbiAgbGV0IGN1cnJlbnQ6IGFueSA9IG9iajtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICBpZiAoIWN1cnJlbnRba2V5XSkge1xuICAgICAgY3VycmVudFtrZXldID0ge307XG4gICAgfVxuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gIH1cblxuICBjdXJyZW50W2tleXNba2V5cy5sZW5ndGggLSAxXV0gPSB2YWx1ZTtcbn1cblxuLyoqXG4gKiBUcmF2ZXJzZXMgdGhlIGZvcm0gYW5kIHJldHVybnMgdGhlIGVycm9ycyBieSBwYXRoXG4gKiBAcGFyYW0gZm9ybVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxsRm9ybUVycm9ycyhcbiAgZm9ybT86IEFic3RyYWN0Q29udHJvbFxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGVycm9yczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBpZiAoIWZvcm0pIHtcbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgZnVuY3Rpb24gY29sbGVjdChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIHBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUdyb3VwIHx8IGNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtQXJyYXkpIHtcbiAgICAgIE9iamVjdC5rZXlzKGNvbnRyb2wuY29udHJvbHMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICBjb25zdCBjaGlsZENvbnRyb2wgPSBjb250cm9sLmdldChrZXkpO1xuICAgICAgICBjb25zdCBjb250cm9sUGF0aCA9IHBhdGggPyBgJHtwYXRofS4ke2tleX1gIDoga2V5O1xuICAgICAgICBpZiAocGF0aCAmJiBjb250cm9sLmVycm9ycyAmJiBjb250cm9sLmVuYWJsZWQpIHtcbiAgICAgICAgICBPYmplY3Qua2V5cyhjb250cm9sLmVycm9ycykuZm9yRWFjaCgoZXJyb3JLZXkpID0+IHtcbiAgICAgICAgICAgIGVycm9yc1twYXRoXSA9IGNvbnRyb2wuZXJyb3JzIVtlcnJvcktleV07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoaWxkQ29udHJvbCkge1xuICAgICAgICAgIGNvbGxlY3QoY2hpbGRDb250cm9sLCBjb250cm9sUGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY29udHJvbC5lcnJvcnMgJiYgY29udHJvbC5lbmFibGVkKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKGNvbnRyb2wuZXJyb3JzKS5mb3JFYWNoKChlcnJvcktleSkgPT4ge1xuICAgICAgICAgIGVycm9yc1twYXRoXSA9IGNvbnRyb2wuZXJyb3JzIVtlcnJvcktleV07XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbGxlY3QoZm9ybSwgJycpO1xuICBpZiAoZm9ybS5lcnJvcnMgJiYgZm9ybS5lcnJvcnMhWydlcnJvcnMnXSkge1xuICAgIGVycm9yc1tST09UX0ZPUk1dID0gZm9ybS5lcnJvcnMgJiYgZm9ybS5lcnJvcnMhWydlcnJvcnMnXTtcbiAgfVxuXG4gIHJldHVybiBlcnJvcnM7XG59XG4iXX0=