UNPKG

@ngx-formly/core

Version:

Formly is a dynamic (JSON powered) form library for Angular that bring unmatched maintainability to your application's forms.

250 lines 38.1 kB
import { isObject, isNil, isUndefined, isFunction, defineHiddenProp, observe, getFieldValue, assignFieldValue, hasKey, } from '../../utils'; import { evalExpression, evalStringExpression } from './utils'; import { isObservable, Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; import { unregisterControl, registerControl, updateValidity } from '../field-form/utils'; import { FormArray } from '@angular/forms'; export class FieldExpressionExtension { onPopulate(field) { if (field._expressions) { return; } // cache built expression defineHiddenProp(field, '_expressions', {}); observe(field, ['hide'], ({ currentValue, firstChange }) => { defineHiddenProp(field, '_hide', !!currentValue); if (!firstChange || (firstChange && currentValue === true)) { field.props.hidden = currentValue; field.options._hiddenFieldsForCheck.push(field); } }); if (field.hideExpression) { observe(field, ['hideExpression'], ({ currentValue: expr }) => { field._expressions.hide = this.parseExpressions(field, 'hide', typeof expr === 'boolean' ? () => expr : expr); }); } const evalExpr = (key, expr) => { if (typeof expr === 'string' || isFunction(expr)) { field._expressions[key] = this.parseExpressions(field, key, expr); } else if (expr instanceof Observable) { field._expressions[key] = { value$: expr.pipe(tap((v) => { this.evalExpr(field, key, v); field.options._detectChanges(field); })), }; } }; field.expressions = field.expressions || {}; for (const key of Object.keys(field.expressions)) { observe(field, ['expressions', key], ({ currentValue: expr }) => { evalExpr(key, isFunction(expr) ? (...args) => expr(field, args[3]) : expr); }); } field.expressionProperties = field.expressionProperties || {}; for (const key of Object.keys(field.expressionProperties)) { observe(field, ['expressionProperties', key], ({ currentValue }) => evalExpr(key, currentValue)); } } postPopulate(field) { if (field.parent) { return; } if (!field.options.checkExpressions) { let checkLocked = false; field.options.checkExpressions = (f, ignoreCache) => { if (checkLocked) { return; } checkLocked = true; const fieldChanged = this.checkExpressions(f, ignoreCache); const options = field.options; options._hiddenFieldsForCheck .sort((f) => (f.hide ? -1 : 1)) .forEach((f) => this.changeHideState(f, f.hide, !ignoreCache)); options._hiddenFieldsForCheck = []; if (fieldChanged) { this.checkExpressions(field); } checkLocked = false; }; field.options._checkField = (f, ignoreCache) => { console.warn(`Formly: 'options._checkField' is deprecated since v6.0, use 'options.checkExpressions' instead.`); field.options.checkExpressions(f, ignoreCache); }; } } parseExpressions(field, path, expr) { let parentExpression; if (field.parent && ['hide', 'props.disabled'].includes(path)) { const rootValue = (f) => { return path === 'hide' ? f.hide : f.props.disabled; }; parentExpression = () => { let root = field.parent; while (root.parent && !rootValue(root)) { root = root.parent; } return rootValue(root); }; } expr = expr || (() => false); if (typeof expr === 'string') { expr = evalStringExpression(expr, ['model', 'formState', 'field']); } let currentValue; return { callback: (ignoreCache) => { try { const exprValue = evalExpression(parentExpression ? (...args) => parentExpression(field) || expr(...args) : expr, { field }, [field.model, field.options.formState, field, ignoreCache]); if (ignoreCache || (currentValue !== exprValue && (!isObject(exprValue) || isObservable(exprValue) || JSON.stringify(exprValue) !== JSON.stringify(currentValue)))) { currentValue = exprValue; this.evalExpr(field, path, exprValue); return true; } return false; } catch (error) { error.message = `[Formly Error] [Expression "${path}"] ${error.message}`; throw error; } }, }; } checkExpressions(field, ignoreCache = false) { if (!field) { return false; } let fieldChanged = false; if (field._expressions) { for (const key of Object.keys(field._expressions)) { field._expressions[key].callback?.(ignoreCache) && (fieldChanged = true); } } field.fieldGroup?.forEach((f) => this.checkExpressions(f, ignoreCache) && (fieldChanged = true)); return fieldChanged; } changeDisabledState(field, value) { if (field.fieldGroup) { field.fieldGroup .filter((f) => !f._expressions.hasOwnProperty('props.disabled')) .forEach((f) => this.changeDisabledState(f, value)); } if (hasKey(field) && field.props.disabled !== value) { field.props.disabled = value; } } changeHideState(field, hide, resetOnHide) { if (field.fieldGroup) { field.fieldGroup .filter((f) => !f._expressions.hide) .forEach((f) => this.changeHideState(f, hide, resetOnHide)); } if (field.formControl && hasKey(field)) { defineHiddenProp(field, '_hide', !!(hide || field.hide)); const c = field.formControl; if (c._fields?.length > 1) { updateValidity(c); } if (hide === true && (!c._fields || c._fields.every((f) => !!f._hide))) { unregisterControl(field, true); if (resetOnHide && field.resetOnHide) { assignFieldValue(field, undefined); field.formControl.reset({ value: undefined, disabled: field.formControl.disabled }); field.options.fieldChanges.next({ value: undefined, field, type: 'valueChanges' }); if (field.fieldGroup && field.formControl instanceof FormArray) { field.fieldGroup.length = 0; } } } else if (hide === false) { if (field.resetOnHide && !isUndefined(field.defaultValue) && isUndefined(getFieldValue(field))) { assignFieldValue(field, field.defaultValue); } registerControl(field, undefined, true); if (field.resetOnHide && field.fieldArray && field.fieldGroup?.length !== field.model?.length) { field.options.build(field); } } } if (field.options.fieldChanges) { field.options.fieldChanges.next({ field, type: 'hidden', value: hide }); } } evalExpr(field, prop, value) { if (prop.indexOf('model.') === 0) { const key = prop.replace(/^model\./, ''), parent = field.fieldGroup ? field : field.parent; let control = field?.key === key ? field.formControl : field.form.get(key); if (!control && field.get(key)) { control = field.get(key).formControl; } assignFieldValue({ key, parent, model: field.model }, value); if (control && !(isNil(control.value) && isNil(value)) && control.value !== value) { control.patchValue(value); } } else { try { let target = field; const paths = this._evalExpressionPath(field, prop); const lastIndex = paths.length - 1; for (let i = 0; i < lastIndex; i++) { target = target[paths[i]]; } target[paths[lastIndex]] = value; } catch (error) { error.message = `[Formly Error] [Expression "${prop}"] ${error.message}`; throw error; } if (['templateOptions.disabled', 'props.disabled'].includes(prop) && hasKey(field)) { this.changeDisabledState(field, value); } } this.emitExpressionChanges(field, prop, value); } emitExpressionChanges(field, property, value) { if (!field.options.fieldChanges) { return; } field.options.fieldChanges.next({ field, type: 'expressionChanges', property, value, }); } _evalExpressionPath(field, prop) { if (field._expressions[prop] && field._expressions[prop].paths) { return field._expressions[prop].paths; } let paths = []; if (prop.indexOf('[') === -1) { paths = prop.split('.'); } else { prop .split(/[[\]]{1,2}/) // https://stackoverflow.com/a/20198206 .filter((p) => p) .forEach((path) => { const arrayPath = path.match(/['|"](.*?)['|"]/); if (arrayPath) { paths.push(arrayPath[1]); } else { paths.push(...path.split('.').filter((p) => p)); } }); } if (field._expressions[prop]) { field._expressions[prop].paths = paths; } return paths; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGQtZXhwcmVzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb3JlL3NyYy9saWIvZXh0ZW5zaW9ucy9maWVsZC1leHByZXNzaW9uL2ZpZWxkLWV4cHJlc3Npb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUNMLFFBQVEsRUFDUixLQUFLLEVBQ0wsV0FBVyxFQUNYLFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsT0FBTyxFQUNQLGFBQWEsRUFDYixnQkFBZ0IsRUFDaEIsTUFBTSxHQUNQLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxjQUFjLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXJDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekYsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE1BQU0sT0FBTyx3QkFBd0I7SUFDbkMsVUFBVSxDQUFDLEtBQTZCO1FBQ3RDLElBQUksS0FBSyxDQUFDLFlBQVksRUFBRTtZQUN0QixPQUFPO1NBQ1I7UUFFRCx5QkFBeUI7UUFDekIsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUU1QyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFO1lBQ3pELGdCQUFnQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2pELElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxX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LEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3pCO2FBQU07WUFDTCxJQUFJO2lCQUNELEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyx1Q0FBdUM7aUJBQzNELE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUNoQixPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDaEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLFNBQVMsRUFBRTtvQkFDYixLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUMxQjtxQkFBTTtvQkFDTCxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2pEO1lBQ0gsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM1QixLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7U0FDeEM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZvcm1seVZhbHVlQ2hhbmdlRXZlbnQsIEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xuaW1wb3J0IHtcbiAgaXNPYmplY3QsXG4gIGlzTmlsLFxuICBpc1VuZGVmaW5lZCxcbiAgaXNGdW5jdGlvbixcbiAgZGVmaW5lSGlkZGVuUHJvcCxcbiAgb2JzZXJ2ZSxcbiAgZ2V0RmllbGRWYWx1ZSxcbiAgYXNzaWduRmllbGRWYWx1ZSxcbiAgaGFzS2V5LFxufSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBldmFsRXhwcmVzc2lvbiwgZXZhbFN0cmluZ0V4cHJlc3Npb24gfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IGlzT2JzZXJ2YWJsZSwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRm9ybWx5RXh0ZW5zaW9uIH0gZnJvbSAnLi4vLi4vbW9kZWxzJztcbmltcG9ydCB7IHVucmVnaXN0ZXJDb250cm9sLCByZWdpc3RlckNvbnRyb2wsIHVwZGF0ZVZhbGlkaXR5IH0gZnJvbSAnLi4vZmllbGQtZm9ybS91dGlscyc7XG5pbXBvcnQgeyBGb3JtQXJyYXkgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmV4cG9ydCBjbGFzcyBGaWVsZEV4cHJlc3Npb25FeHRlbnNpb24gaW1wbGVtZW50cyBGb3JtbHlFeHRlbnNpb24ge1xuICBvblBvcHVsYXRlKGZpZWxkOiBGb3JtbHlGaWVsZENvbmZpZ0NhY2hlKSB7XG4gICAgaWYgKGZpZWxkLl9leHByZXNzaW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNhY2hlIGJ1aWx0IGV4cHJlc3Npb25cbiAgICBkZWZpbmVIaWRkZW5Qcm9wKGZpZWxkLCAnX2V4cHJlc3Npb25zJywge30pO1xuXG4gICAgb2JzZXJ2ZShmaWVsZCwgWydoaWRlJ10sICh7IGN1cnJlbnRWYWx1ZSwgZmlyc3RDaGFuZ2UgfSkgPT4ge1xuICAgICAgZGVmaW5lSGlkZGVuUHJvcChmaWVsZCwgJ19oaWRlJywgISFjdXJyZW50VmFsdWUpO1xuICAgICAgaWYgKCFmaXJzdENoYW5nZSB8fCAoZmlyc3RDaGFuZ2UgJiYgY3VycmVudFZhbHVlID09PSB0cnVlKSkge1xuICAgICAgICBmaWVsZC5wcm9wcy5oaWRkZW4gPSBjdXJyZW50VmFsdWU7XG4gICAgICAgIGZpZWxkLm9wdGlvbnMuX2hpZGRlbkZpZWxkc0ZvckNoZWNrLnB1c2goZmllbGQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGZpZWxkLmhpZGVFeHByZXNzaW9uKSB7XG4gICAgICBvYnNlcnZlKGZpZWxkLCBbJ2hpZGVFeHByZXNzaW9uJ10sICh7IGN1cnJlbnRWYWx1ZTogZXhwciB9KSA9PiB7XG4gICAgICAgIGZpZWxkLl9leHByZXNzaW9ucy5oaWRlID0gdGhpcy5wYXJzZUV4cHJlc3Npb25zKGZpZWxkLCAnaGlkZScsIHR5cGVvZiBleHByID09PSAnYm9vbGVhbicgPyAoKSA9PiBleHByIDogZXhwcik7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBldmFsRXhwciA9IChrZXk6IHN0cmluZywgZXhwcjogYW55KSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGV4cHIgPT09ICdzdHJpbmcnIHx8IGlzRnVuY3Rpb24oZXhwcikpIHtcbiAgICAgICAgZmllbGQuX2V4cHJlc3Npb25zW2tleV0gPSB0aGlzLnBhcnNlRXhwcmVzc2lvbnMoZmllbGQsIGtleSwgZXhwcik7XG4gICAgICB9IGVsc2UgaWYgKGV4cHIgaW5zdGFuY2VvZiBPYnNlcnZhYmxlKSB7XG4gICAgICAgIGZpZWxkLl9leHByZXNzaW9uc1trZXldID0ge1xuICAgICAgICAgIHZhbHVlJDogKGV4cHIgYXMgT2JzZXJ2YWJsZTxhbnk+KS5waXBlKFxuICAgICAgICAgICAgdGFwKCh2KSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZXZhbEV4cHIoZmllbGQsIGtleSwgdik7XG4gICAgICAgICAgICAgIGZpZWxkLm9wdGlvbnMuX2RldGVjdENoYW5nZXMoZmllbGQpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZmllbGQuZXhwcmVzc2lvbnMgPSBmaWVsZC5leHByZXNzaW9ucyB8fCB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhmaWVsZC5leHByZXNzaW9ucykpIHtcbiAgICAgIG9ic2VydmUoZmllbGQsIFsnZXhwcmVzc2lvbnMnLCBrZXldLCAoeyBjdXJyZW50VmFsdWU6IGV4cHIgfSkgPT4ge1xuICAgICAgICBldmFsRXhwcihrZXksIGlzRnVuY3Rpb24oZXhwcikgPyAoLi4uYXJnczogYW55KSA9PiBleHByKGZpZWxkLCBhcmdzWzNdKSA6IGV4cHIpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZmllbGQuZXhwcmVzc2lvblByb3BlcnRpZXMgPSBmaWVsZC5leHByZXNzaW9uUHJvcGVydGllcyB8fCB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhmaWVsZC5leHByZXNzaW9uUHJvcGVydGllcykpIHtcbiAgICAgIG9ic2VydmUoZmllbGQsIFsnZXhwcmVzc2lvblByb3BlcnRpZXMnLCBrZXldLCAoeyBjdXJyZW50VmFsdWUgfSkgPT4gZXZhbEV4cHIoa2V5LCBjdXJyZW50VmFsdWUpKTtcbiAgICB9XG4gIH1cblxuICBwb3N0UG9wdWxhdGUoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUpIHtcbiAgICBpZiAoZmllbGQucGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFmaWVsZC5vcHRpb25zLmNoZWNrRXhwcmVzc2lvbnMpIHtcbiAgICAgIGxldCBjaGVja0xvY2tlZCA9IGZhbHNlO1xuICAgICAgZmllbGQub3B0aW9ucy5jaGVja0V4cHJlc3Npb25zID0gKGYsIGlnbm9yZUNhY2hlKSA9PiB7XG4gICAgICAgIGlmIChjaGVja0xvY2tlZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoZWNrTG9ja2VkID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgZmllbGRDaGFuZ2VkID0gdGhpcy5jaGVja0V4cHJlc3Npb25zKGYsIGlnbm9yZUNhY2hlKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGZpZWxkLm9wdGlvbnM7XG4gICAgICAgIG9wdGlvbnMuX2hpZGRlbkZpZWxkc0ZvckNoZWNrXG4gICAgICAgICAgLnNvcnQoKGYpID0+IChmLmhpZGUgPyAtMSA6IDEpKVxuICAgICAgICAgIC5mb3JFYWNoKChmKSA9PiB0aGlzLmNoYW5nZUhpZGVTdGF0ZShmLCBmLmhpZGUsICFpZ25vcmVDYWNoZSkpO1xuICAgICAgICBvcHRpb25zLl9oaWRkZW5GaWVsZHNGb3JDaGVjayA9IFtdO1xuICAgICAgICBpZiAoZmllbGRDaGFuZ2VkKSB7XG4gICAgICAgICAgdGhpcy5jaGVja0V4cHJlc3Npb25zKGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgICBjaGVja0xvY2tlZCA9IGZhbHNlO1xuICAgICAgfTtcbiAgICAgIGZpZWxkLm9wdGlvbnMuX2NoZWNrRmllbGQgPSAoZiwgaWdub3JlQ2FjaGUpID0+IHtcbiAgICAgICAgY29uc29sZS53YXJuKGBGb3JtbHk6ICdvcHRpb25zLl9jaGVja0ZpZWxkJyBpcyBkZXByZWNhdGVkIHNpbmNlIHY2LjAsIHVzZSAnb3B0aW9ucy5jaGVja0V4cHJlc3Npb25zJyBpbnN0ZWFkLmApO1xuICAgICAgICBmaWVsZC5vcHRpb25zLmNoZWNrRXhwcmVzc2lvbnMoZiwgaWdub3JlQ2FjaGUpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRXhwcmVzc2lvbnMoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUsIHBhdGg6IHN0cmluZywgZXhwcjogYW55KSB7XG4gICAgbGV0IHBhcmVudEV4cHJlc3Npb246IGFueTtcbiAgICBpZiAoZmllbGQucGFyZW50ICYmIFsnaGlkZScsICdwcm9wcy5kaXNhYmxlZCddLmluY2x1ZGVzKHBhdGgpKSB7XG4gICAgICBjb25zdCByb290VmFsdWUgPSAoZjogRm9ybWx5RmllbGRDb25maWdDYWNoZSkgPT4ge1xuICAgICAgICByZXR1cm4gcGF0aCA9PT0gJ2hpZGUnID8gZi5oaWRlIDogZi5wcm9wcy5kaXNhYmxlZDtcbiAgICAgIH07XG5cbiAgICAgIHBhcmVudEV4cHJlc3Npb24gPSAoKSA9PiB7XG4gICAgICAgIGxldCByb290ID0gZmllbGQucGFyZW50O1xuICAgICAgICB3aGlsZSAocm9vdC5wYXJlbnQgJiYgIXJvb3RWYWx1ZShyb290KSkge1xuICAgICAgICAgIHJvb3QgPSByb290LnBhcmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByb290VmFsdWUocm9vdCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIGV4cHIgPSBleHByIHx8ICgoKSA9PiBmYWxzZSk7XG4gICAgaWYgKHR5cGVvZiBleHByID09PSAnc3RyaW5nJykge1xuICAgICAgZXhwciA9IGV2YWxTdHJpbmdFeHByZXNzaW9uKGV4cHIsIFsnbW9kZWwnLCAnZm9ybVN0YXRlJywgJ2ZpZWxkJ10pO1xuICAgIH1cblxuICAgIGxldCBjdXJyZW50VmFsdWU6IGFueTtcblxuICAgIHJldHVybiB7XG4gICAgICBjYWxsYmFjazogKGlnbm9yZUNhY2hlPzogYm9vbGVhbikgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGV4cHJWYWx1ZSA9IGV2YWxFeHByZXNzaW9uKFxuICAgICAgICAgICAgcGFyZW50RXhwcmVzc2lvbiA/ICguLi5hcmdzOiBhbnkpID0+IHBhcmVudEV4cHJlc3Npb24oZmllbGQpIHx8IGV4cHIoLi4uYXJncykgOiBleHByLFxuICAgICAgICAgICAgeyBmaWVsZCB9LFxuICAgICAgICAgICAgW2ZpZWxkLm1vZGVsLCBmaWVsZC5vcHRpb25zLmZvcm1TdGF0ZSwgZmllbGQsIGlnbm9yZUNhY2hlXSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaWdub3JlQ2FjaGUgfHxcbiAgICAgICAgICAgIChjdXJyZW50VmFsdWUgIT09IGV4cHJWYWx1ZSAmJlxuICAgICAgICAgICAgICAoIWlzT2JqZWN0KGV4cHJWYWx1ZSkgfHxcbiAgICAgICAgICAgICAgICBpc09ic2VydmFibGUoZXhwclZhbHVlKSB8fFxuICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGV4cHJWYWx1ZSkgIT09IEpTT04uc3RyaW5naWZ5KGN1cnJlbnRWYWx1ZSkpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY3VycmVudFZhbHVlID0gZXhwclZhbHVlO1xuICAgICAgICAgICAgdGhpcy5ldmFsRXhwcihmaWVsZCwgcGF0aCwgZXhwclZhbHVlKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgZXJyb3IubWVzc2FnZSA9IGBbRm9ybWx5IEVycm9yXSBbRXhwcmVzc2lvbiBcIiR7cGF0aH1cIl0gJHtlcnJvci5tZXNzYWdlfWA7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tFeHByZXNzaW9ucyhmaWVsZDogRm9ybWx5RmllbGRDb25maWdDYWNoZSwgaWdub3JlQ2FjaGUgPSBmYWxzZSkge1xuICAgIGlmICghZmllbGQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgZmllbGRDaGFuZ2VkID0gZmFsc2U7XG4gICAgaWYgKGZpZWxkLl9leHByZXNzaW9ucykge1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoZmllbGQuX2V4cHJlc3Npb25zKSkge1xuICAgICAgICBmaWVsZC5fZXhwcmVzc2lvbnNba2V5XS5jYWxsYmFjaz8uKGlnbm9yZUNhY2hlKSAmJiAoZmllbGRDaGFuZ2VkID0gdHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZpZWxkLmZpZWxkR3JvdXA/LmZvckVhY2goKGYpID0+IHRoaXMuY2hlY2tFeHByZXNzaW9ucyhmLCBpZ25vcmVDYWNoZSkgJiYgKGZpZWxkQ2hhbmdlZCA9IHRydWUpKTtcblxuICAgIHJldHVybiBmaWVsZENoYW5nZWQ7XG4gIH1cblxuICBwcml2YXRlIGNoYW5nZURpc2FibGVkU3RhdGUoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUsIHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKGZpZWxkLmZpZWxkR3JvdXApIHtcbiAgICAgIGZpZWxkLmZpZWxkR3JvdXBcbiAgICAgICAgLmZpbHRlcigoZjogRm9ybWx5RmllbGRDb25maWdDYWNoZSkgPT4gIWYuX2V4cHJlc3Npb25zLmhhc093blByb3BlcnR5KCdwcm9wcy5kaXNhYmxlZCcpKVxuICAgICAgICAuZm9yRWFjaCgoZikgPT4gdGhpcy5jaGFuZ2VEaXNhYmxlZFN0YXRlKGYsIHZhbHVlKSk7XG4gICAgfVxuXG4gICAgaWYgKGhhc0tleShmaWVsZCkgJiYgZmllbGQucHJvcHMuZGlzYWJsZWQgIT09IHZhbHVlKSB7XG4gICAgICBmaWVsZC5wcm9wcy5kaXNhYmxlZCA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hhbmdlSGlkZVN0YXRlKGZpZWxkOiBGb3JtbHlGaWVsZENvbmZpZ0NhY2hlLCBoaWRlOiBib29sZWFuLCByZXNldE9uSGlkZTogYm9vbGVhbikge1xuICAgIGlmIChmaWVsZC5maWVsZEdyb3VwKSB7XG4gICAgICBmaWVsZC5maWVsZEdyb3VwXG4gICAgICAgIC5maWx0ZXIoKGY6IEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUpID0+ICFmLl9leHByZXNzaW9ucy5oaWRlKVxuICAgICAgICAuZm9yRWFjaCgoZikgPT4gdGhpcy5jaGFuZ2VIaWRlU3RhdGUoZiwgaGlkZSwgcmVzZXRPbkhpZGUpKTtcbiAgICB9XG5cbiAgICBpZiAoZmllbGQuZm9ybUNvbnRyb2wgJiYgaGFzS2V5KGZpZWxkKSkge1xuICAgICAgZGVmaW5lSGlkZGVuUHJvcChmaWVsZCwgJ19oaWRlJywgISEoaGlkZSB8fCBmaWVsZC5oaWRlKSk7XG4gICAgICBjb25zdCBjID0gZmllbGQuZm9ybUNvbnRyb2w7XG4gICAgICBpZiAoYy5fZmllbGRzPy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHVwZGF0ZVZhbGlkaXR5KGMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaGlkZSA9PT0gdHJ1ZSAmJiAoIWMuX2ZpZWxkcyB8fCBjLl9maWVsZHMuZXZlcnkoKGYpID0+ICEhZi5faGlkZSkpKSB7XG4gICAgICAgIHVucmVnaXN0ZXJDb250cm9sKGZpZWxkLCB0cnVlKTtcbiAgICAgICAgaWYgKHJlc2V0T25IaWRlICYmIGZpZWxkLnJlc2V0T25IaWRlKSB7XG4gICAgICAgICAgYXNzaWduRmllbGRWYWx1ZShmaWVsZCwgdW5kZWZpbmVkKTtcbiAgICAgICAgICBmaWVsZC5mb3JtQ29udHJvbC5yZXNldCh7IHZhbHVlOiB1bmRlZmluZWQsIGRpc2FibGVkOiBmaWVsZC5mb3JtQ29udHJvbC5kaXNhYmxlZCB9KTtcbiAgICAgICAgICBmaWVsZC5vcHRpb25zLmZpZWxkQ2hhbmdlcy5uZXh0KHsgdmFsdWU6IHVuZGVmaW5lZCwgZmllbGQsIHR5cGU6ICd2YWx1ZUNoYW5nZXMnIH0pO1xuICAgICAgICAgIGlmIChmaWVsZC5maWVsZEdyb3VwICYmIGZpZWxkLmZvcm1Db250cm9sIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgICAgICBmaWVsZC5maWVsZEdyb3VwLmxlbmd0aCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGhpZGUgPT09IGZhbHNlKSB7XG4gICAgICAgIGlmIChmaWVsZC5yZXNldE9uSGlkZSAmJiAhaXNVbmRlZmluZWQoZmllbGQuZGVmYXVsdFZhbHVlKSAmJiBpc1VuZGVmaW5lZChnZXRGaWVsZFZhbHVlKGZpZWxkKSkpIHtcbiAgICAgICAgICBhc3NpZ25GaWVsZFZhbHVlKGZpZWxkLCBmaWVsZC5kZWZhdWx0VmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJlZ2lzdGVyQ29udHJvbChmaWVsZCwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICAgICAgaWYgKGZpZWxkLnJlc2V0T25IaWRlICYmIGZpZWxkLmZpZWxkQXJyYXkgJiYgZmllbGQuZmllbGRHcm91cD8ubGVuZ3RoICE9PSBmaWVsZC5tb2RlbD8ubGVuZ3RoKSB7XG4gICAgICAgICAgZmllbGQub3B0aW9ucy5idWlsZChmaWVsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmllbGQub3B0aW9ucy5maWVsZENoYW5nZXMpIHtcbiAgICAgIGZpZWxkLm9wdGlvbnMuZmllbGRDaGFuZ2VzLm5leHQoPEZvcm1seVZhbHVlQ2hhbmdlRXZlbnQ+eyBmaWVsZCwgdHlwZTogJ2hpZGRlbicsIHZhbHVlOiBoaWRlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZXZhbEV4cHIoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUsIHByb3A6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGlmIChwcm9wLmluZGV4T2YoJ21vZGVsLicpID09PSAwKSB7XG4gICAgICBjb25zdCBrZXkgPSBwcm9wLnJlcGxhY2UoL15tb2RlbFxcLi8sICcnKSxcbiAgICAgICAgcGFyZW50ID0gZmllbGQuZmllbGRHcm91cCA/IGZpZWxkIDogZmllbGQucGFyZW50O1xuXG4gICAgICBsZXQgY29udHJvbCA9IGZpZWxkPy5rZXkgPT09IGtleSA/IGZpZWxkLmZvcm1Db250cm9sIDogZmllbGQuZm9ybS5nZXQoa2V5KTtcbiAgICAgIGlmICghY29udHJvbCAmJiBmaWVsZC5nZXQoa2V5KSkge1xuICAgICAgICBjb250cm9sID0gZmllbGQuZ2V0KGtleSkuZm9ybUNvbnRyb2w7XG4gICAgICB9XG4gICAgICBhc3NpZ25GaWVsZFZhbHVlKHsga2V5LCBwYXJlbnQsIG1vZGVsOiBmaWVsZC5tb2RlbCB9LCB2YWx1ZSk7XG4gICAgICBpZiAoY29udHJvbCAmJiAhKGlzTmlsKGNvbnRyb2wudmFsdWUpICYmIGlzTmlsKHZhbHVlKSkgJiYgY29udHJvbC52YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgY29udHJvbC5wYXRjaFZhbHVlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IHRhcmdldDogYW55ID0gZmllbGQ7XG4gICAgICAgIGNvbnN0IHBhdGhzID0gdGhpcy5fZXZhbEV4cHJlc3Npb25QYXRoKGZpZWxkLCBwcm9wKTtcbiAgICAgICAgY29uc3QgbGFzdEluZGV4ID0gcGF0aHMubGVuZ3RoIC0gMTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXN0SW5kZXg7IGkrKykge1xuICAgICAgICAgIHRhcmdldCA9IHRhcmdldFtwYXRoc1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICB0YXJnZXRbcGF0aHNbbGFzdEluZGV4XV0gPSB2YWx1ZTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgZXJyb3IubWVzc2FnZSA9IGBbRm9ybWx5IEVycm9yXSBbRXhwcmVzc2lvbiBcIiR7cHJvcH1cIl0gJHtlcnJvci5tZXNzYWdlfWA7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuXG4gICAgICBpZiAoWyd0ZW1wbGF0ZU9wdGlvbnMuZGlzYWJsZWQnLCAncHJvcHMuZGlzYWJsZWQnXS5pbmNsdWRlcyhwcm9wKSAmJiBoYXNLZXkoZmllbGQpKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlRGlzYWJsZWRTdGF0ZShmaWVsZCwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZW1pdEV4cHJlc3Npb25DaGFuZ2VzKGZpZWxkLCBwcm9wLCB2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRFeHByZXNzaW9uQ2hhbmdlcyhmaWVsZDogRm9ybWx5RmllbGRDb25maWdDYWNoZSwgcHJvcGVydHk6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGlmICghZmllbGQub3B0aW9ucy5maWVsZENoYW5nZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmaWVsZC5vcHRpb25zLmZpZWxkQ2hhbmdlcy5uZXh0KHtcbiAgICAgIGZpZWxkLFxuICAgICAgdHlwZTogJ2V4cHJlc3Npb25DaGFuZ2VzJyxcbiAgICAgIHByb3BlcnR5LFxuICAgICAgdmFsdWUsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9ldmFsRXhwcmVzc2lvblBhdGgoZmllbGQ6IEZvcm1seUZpZWxkQ29uZmlnQ2FjaGUsIHByb3A6IHN0cmluZykge1xuICAgIGlmIChmaWVsZC5fZXhwcmVzc2lvbnNbcHJvcF0gJiYgZmllbGQuX2V4cHJlc3Npb25zW3Byb3BdLnBhdGhzKSB7XG4gICAgICByZXR1cm4gZmllbGQuX2V4cHJlc3Npb25zW3Byb3BdLnBhdGhzO1xuICAgIH1cblxuICAgIGxldCBwYXRoczogc3RyaW5nW10gPSBbXTtcbiAgICBpZiAocHJvcC5pbmRleE9mKCdbJykgPT09IC0xKSB7XG4gICAgICBwYXRocyA9IHByb3Auc3BsaXQoJy4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvcFxuICAgICAgICAuc3BsaXQoL1tbXFxdXXsxLDJ9LykgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIwMTk4MjA2XG4gICAgICAgIC5maWx0ZXIoKHApID0+IHApXG4gICAgICAgIC5mb3JFYWNoKChwYXRoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYXJyYXlQYXRoID0gcGF0aC5tYXRjaCgvWyd8XCJdKC4qPylbJ3xcIl0vKTtcbiAgICAgICAgICBpZiAoYXJyYXlQYXRoKSB7XG4gICAgICAgICAgICBwYXRocy5wdXNoKGFycmF5UGF0aFsxXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhdGhzLnB1c2goLi4ucGF0aC5zcGxpdCgnLicpLmZpbHRlcigocCkgPT4gcCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkLl9leHByZXNzaW9uc1twcm9wXSkge1xuICAgICAgZmllbGQuX2V4cHJlc3Npb25zW3Byb3BdLnBhdGhzID0gcGF0aHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGhzO1xuICB9XG59XG4iXX0=