@jsbailey/reactive-form-validators
Version:
[](https://badge.fury.io/js/%40rxweb%2Freactive-form-validators) [](https://gitter.im/rxweb-project/rxweb?utm_source=badge
320 lines (319 loc) • 50.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Injectable } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { alphaNumericValidator, alphaValidator, compareValidator, emailValidator, hexColorValidator, lowercaseValidator, maxDateValidator, maxNumberValidator, minDateValidator, minNumberValidator, containsValidator, uppercaseValidator, rangeValidator, patternValidator, requiredValidator, creditCardValidator, digitValidator, maxLengthValidator, minLengthValidator, passwordValidator, timeValidator, urlValidator, jsonValidator, greaterThanEqualToValidator, greaterThanValidator, lessThanEqualToValidator, lessThanValidator } from '../reactive-form-validators';
import { defaultContainer } from '../core/defaultContainer';
import { FormBuilderConfiguration } from "../models";
import { ARRAY_PROPERTY, OBJECT_PROPERTY, PROPERTY } from "../const";
import { AnnotationTypes } from "../core/validator.static";
import { conditionalChangeValidator } from "../reactive-form-validators/conditional-change.validator";
import { Linq } from '../util/linq';
/** @type {?} */
const APP_VALIDATORS = {
"alphaNumeric": alphaNumericValidator,
"alpha": alphaValidator,
"compare": compareValidator,
"email": emailValidator,
"hexColor": hexColorValidator,
"lowerCase": lowercaseValidator,
"maxDate": maxDateValidator,
"maxNumber": maxNumberValidator,
"minDate": minDateValidator,
"minNumber": minNumberValidator,
"contains": containsValidator,
"upperCase": uppercaseValidator,
"maxLength": maxLengthValidator,
"minLength": minLengthValidator,
"password": passwordValidator,
"range": rangeValidator,
"required": requiredValidator,
"creditCard": creditCardValidator,
"digit": digitValidator,
"pattern": patternValidator,
"time": timeValidator,
"url": urlValidator,
"json": jsonValidator,
"greaterThan": greaterThanValidator,
"greaterThanEqualTo": greaterThanEqualToValidator,
"lessThan": lessThanValidator,
"lessThanEqualTo": lessThanEqualToValidator
};
export class RxFormBuilder {
/**
* @param {?} formBuilder
*/
constructor(formBuilder) {
this.formBuilder = formBuilder;
this.conditionalObjectProps = [];
this.conditionalValidationInstance = {};
this.builderConfigurationConditionalObjectProps = [];
this.isNested = false;
}
/**
* @param {?} instanceFunc
* @return {?}
*/
getInstanceContainer(instanceFunc) {
return defaultContainer.get(instanceFunc);
}
/**
* @param {?} formGroup
* @param {?} object
* @return {?}
*/
setValue(formGroup, object) {
for (var col in object) {
/** @type {?} */
var control = formGroup.get([col]);
control.setValue(object[col]);
control.updateValueAndValidity();
}
}
/**
* @param {?} fomrBuilderConfiguration
* @return {?}
*/
extractExpressions(fomrBuilderConfiguration) {
if (fomrBuilderConfiguration && fomrBuilderConfiguration.validations) {
for (var property in fomrBuilderConfiguration.validations) {
for (var decorator in fomrBuilderConfiguration.validations[property]) {
if (fomrBuilderConfiguration.validations[property][decorator].conditionalExpression) {
/** @type {?} */
let columns = Linq.expressionColumns(fomrBuilderConfiguration.validations[property][decorator].conditionalExpression);
defaultContainer.addChangeValidation(this.conditionalValidationInstance, property, columns);
}
}
}
}
return null;
}
/**
* @param {?} property
* @param {?} propertyValidators
* @param {?} propValidationConfig
* @param {?} instance
* @return {?}
*/
addFormControl(property, propertyValidators, propValidationConfig, instance) {
/** @type {?} */
let validators = [];
/** @type {?} */
let columns = [];
if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name]) || (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name])) {
/** @type {?} */
let props = [];
if ((instance.conditionalValidationProps && instance.conditionalValidationProps[property.name]))
instance.conditionalValidationProps[property.name].forEach(t => props.push(t));
if (this.conditionalValidationInstance.conditionalValidationProps && this.conditionalValidationInstance.conditionalValidationProps[property.name])
this.conditionalValidationInstance.conditionalValidationProps[property.name].forEach(t => props.push(t));
validators.push(conditionalChangeValidator(props));
}
if (this.conditionalObjectProps.length > 0 || this.builderConfigurationConditionalObjectProps.length > 0) {
/** @type {?} */
let propConditions = [];
if (this.conditionalObjectProps)
propConditions = this.conditionalObjectProps.filter(t => t.propName == property.name);
if (this.builderConfigurationConditionalObjectProps)
this.builderConfigurationConditionalObjectProps.filter(t => t.propName == property.name).forEach(t => propConditions.push(t));
propConditions.forEach(t => {
if (t.referencePropName && columns.indexOf(t.referencePropName) == -1)
columns.push(t.referencePropName);
});
if (columns.length > 0)
validators.push(conditionalChangeValidator(columns));
}
for (let propertyValidator of propertyValidators) {
validators.push(APP_VALIDATORS[propertyValidator.annotationType](propertyValidator.config));
}
if (propValidationConfig)
this.additionalValidation(validators, propValidationConfig);
return validators;
}
/**
* @param {?} validations
* @param {?} propValidationConfig
* @return {?}
*/
additionalValidation(validations, propValidationConfig) {
for (var col in AnnotationTypes) {
if (propValidationConfig[AnnotationTypes[col]] && col != "custom") {
validations.push(APP_VALIDATORS[AnnotationTypes[col]](propValidationConfig[AnnotationTypes[col]]));
}
else if (col == AnnotationTypes["custom"] && propValidationConfig[AnnotationTypes[col]])
validations.push(propValidationConfig[col]);
}
}
/**
* @template T
* @param {?} instanceContainer
* @param {?} object
* @return {?}
*/
checkObjectPropAdditionalValidation(instanceContainer, object) {
/** @type {?} */
var props = instanceContainer.properties.filter(t => t.propertyType == OBJECT_PROPERTY || t.propertyType == ARRAY_PROPERTY);
props.forEach(t => {
/** @type {?} */
let instance = this.getInstanceContainer(t.entity);
if (instance.conditionalValidationProps) {
for (var key in instance.conditionalValidationProps) {
/** @type {?} */
var prop = instance.properties.filter(t => t.name == key)[0];
if (!prop)
prop = instanceContainer.properties.filter(t => t.name == key)[0];
if (prop) {
if (!instanceContainer.conditionalValidationProps) {
instanceContainer.conditionalValidationProps = {};
}
if (!instanceContainer.conditionalValidationProps[key]) {
instanceContainer.conditionalValidationProps[key] = [];
}
instance.conditionalValidationProps[key].forEach(x => {
if (t.propertyType != ARRAY_PROPERTY)
instanceContainer.conditionalValidationProps[key].push([t.name, x].join('.'));
else
instanceContainer.conditionalValidationProps[key].push([t.name, x].join('[]'));
});
}
}
}
});
}
/**
* @param {?} model
* @param {?=} entityObject
* @param {?=} formBuilderConfiguration
* @return {?}
*/
getObject(model, entityObject, formBuilderConfiguration) {
/** @type {?} */
let json = {};
if (typeof model == "function")
json["model"] = model;
if (entityObject && !(entityObject instanceof FormBuilderConfiguration))
json["entityObject"] = entityObject;
if (entityObject instanceof FormBuilderConfiguration && !formBuilderConfiguration)
json["formBuilderConfiguration"] = entityObject;
else if (!(entityObject instanceof FormBuilderConfiguration) && formBuilderConfiguration)
json["formBuilderConfiguration"] = formBuilderConfiguration;
if (!entityObject) {
json["entityObject"] = model;
if (typeof model == "object")
json["model"] = model.constructor;
}
else if (model && (entityObject instanceof FormBuilderConfiguration) && (typeof model == "object")) {
json["entityObject"] = model;
json["model"] = model.constructor;
}
return json;
}
/**
* @template T
* @param {?} model
* @param {?=} entityObject
* @param {?=} formBuilderConfiguration
* @return {?}
*/
formGroup(model, entityObject, formBuilderConfiguration) {
/** @type {?} */
let json = this.getObject(model, entityObject, formBuilderConfiguration);
model = json["model"];
entityObject = json["entityObject"];
formBuilderConfiguration = json["formBuilderConfiguration"];
if (formBuilderConfiguration)
this.extractExpressions(formBuilderConfiguration);
/** @type {?} */
let instanceContainer = this.getInstanceContainer(model);
this.checkObjectPropAdditionalValidation(instanceContainer, entityObject);
/** @type {?} */
let formGroupObject = {};
/** @type {?} */
let formChildGroup = undefined;
/** @type {?} */
let formArrayGroup = undefined;
/** @type {?} */
var additionalValidations = {};
instanceContainer.properties.forEach(property => {
/** @type {?} */
let isIncludeProp = true;
if (formBuilderConfiguration && formBuilderConfiguration.excludeProps && formBuilderConfiguration.excludeProps.length > 0)
isIncludeProp = formBuilderConfiguration.excludeProps.indexOf(property.name) == -1;
if (formBuilderConfiguration && formBuilderConfiguration.validations)
additionalValidations = formBuilderConfiguration.validations;
if (isIncludeProp) {
switch (property.propertyType) {
case PROPERTY:
/** @type {?} */
var propertyValidators = instanceContainer.propertyAnnotations.filter(t => t.propertyName == property.name);
formGroupObject[property.name] = [entityObject[property.name], this.addFormControl(property, propertyValidators, additionalValidations[property.name], instanceContainer)];
this.isNested = false;
break;
case OBJECT_PROPERTY:
if (entityObject[property.name] && entityObject[property.name] instanceof Object) {
this.isNested = true;
if (instanceContainer && instanceContainer.conditionalObjectProps)
this.conditionalObjectProps = instanceContainer.conditionalObjectProps["filter"](t => t.objectPropName == property.name);
if (this.conditionalValidationInstance && this.conditionalValidationInstance.conditionalObjectProps)
this.builderConfigurationConditionalObjectProps = this.conditionalValidationInstance.conditionalObjectProps.filter(t => t.objectPropName == property.name);
formGroupObject[property.name] = this.formGroup(property.entity, entityObject[property.name], formBuilderConfiguration);
this.conditionalObjectProps = [];
this.builderConfigurationConditionalObjectProps = [];
this.isNested = false;
}
break;
case ARRAY_PROPERTY:
if (entityObject[property.name] && entityObject[property.name] instanceof Array) {
this.isNested = true;
/** @type {?} */
var formArrayGroup = [];
/** @type {?} */
let index = 0;
for (let subObject of entityObject[property.name]) {
if (instanceContainer && instanceContainer.conditionalObjectProps)
this.conditionalObjectProps = instanceContainer.conditionalObjectProps["filter"](t => t.objectPropName == property.name && t.arrayIndex == index);
if (this.conditionalValidationInstance && this.conditionalValidationInstance.conditionalObjectProps)
this.builderConfigurationConditionalObjectProps = this.conditionalValidationInstance.conditionalObjectProps.filter(t => t.objectPropName == property.name && t.arrayIndex == index);
formArrayGroup.push(this.formGroup(property.entity, subObject, formBuilderConfiguration));
index++;
this.conditionalObjectProps = [];
this.builderConfigurationConditionalObjectProps = [];
}
formGroupObject[property.name] = this.formBuilder.array(formArrayGroup);
this.isNested = false;
}
break;
}
}
});
if (!this.isNested) {
this.conditionalValidationInstance = {};
this.builderConfigurationConditionalObjectProps = [];
}
return this.formBuilder.group(formGroupObject);
}
}
RxFormBuilder.decorators = [
{ type: Injectable }
];
/** @nocollapse */
RxFormBuilder.ctorParameters = () => [
{ type: FormBuilder }
];
if (false) {
/** @type {?} */
RxFormBuilder.prototype.nestedProp;
/** @type {?} */
RxFormBuilder.prototype.conditionalObjectProps;
/** @type {?} */
RxFormBuilder.prototype.conditionalValidationInstance;
/** @type {?} */
RxFormBuilder.prototype.builderConfigurationConditionalObjectProps;
/** @type {?} */
RxFormBuilder.prototype.isNested;
/** @type {?} */
RxFormBuilder.prototype.formBuilder;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicngtZm9ybS1idWlsZGVyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGpzYmFpbGV5L3JlYWN0aXZlLWZvcm0tdmFsaWRhdG9ycy8iLCJzb3VyY2VzIjpbInNlcnZpY2VzL3J4LWZvcm0tYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsV0FBVyxFQUF5QixNQUFNLGdCQUFnQixDQUFBO0FBRW5FLE9BQU8sRUFDSCxxQkFBcUIsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUM5RyxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsRUFDakgsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFDeEYsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQ3JHLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLHdCQUF3QixFQUFFLGlCQUFpQixFQUNqRyxNQUFNLDZCQUE2QixDQUFDO0FBRXJDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTVELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFFcEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDBEQUEwRCxDQUFDO0FBQ3RHLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxjQUFjLENBQUE7O0FBR25DLE1BQU0sY0FBYyxHQUFnQztJ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MEMsR0FBRyxFQUFFLENBQUM7U0FDeEQ7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7S0FDbEQ7OztZQXJNSixVQUFVOzs7O1lBcERGLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIlxyXG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgRm9ybUdyb3VwLCBWYWxpZGF0b3JzIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCJcclxuaW1wb3J0IHsgVHlwZSwgRGVjb3JhdG9yTmFtZSB9IGZyb20gXCIuLi91dGlsXCJcclxuaW1wb3J0IHtcclxuICAgIGFscGhhTnVtZXJpY1ZhbGlkYXRvciwgYWxwaGFWYWxpZGF0b3IsIGNvbXBhcmVWYWxpZGF0b3IsIGVtYWlsVmFsaWRhdG9yLCBoZXhDb2xvclZhbGlkYXRvciwgbG93ZXJjYXNlVmFsaWRhdG9yLFxyXG4gICAgbWF4RGF0ZVZhbGlkYXRvciwgbWF4TnVtYmVyVmFsaWRhdG9yLCBtaW5EYXRlVmFsaWRhdG9yLCBtaW5OdW1iZXJWYWxpZGF0b3IsIGNvbnRhaW5zVmFsaWRhdG9yLCB1cHBlcmNhc2VWYWxpZGF0b3IsXHJcbiAgICByYW5nZVZhbGlkYXRvciwgcGF0dGVyblZhbGlkYXRvciwgcmVxdWlyZWRWYWxpZGF0b3IsIGNyZWRpdENhcmRWYWxpZGF0b3IsIGRpZ2l0VmFsaWRhdG9yLFxyXG4gICAgbWF4TGVuZ3RoVmFsaWRhdG9yLCBtaW5MZW5ndGhWYWxpZGF0b3IsIHBhc3N3b3JkVmFsaWRhdG9yLCB0aW1lVmFsaWRhdG9yLCB1cmxWYWxpZGF0b3IsIGpzb25WYWxpZGF0b3IsXHJcbiAgICBncmVhdGVyVGhhbkVxdWFsVG9WYWxpZGF0b3IsIGdyZWF0ZXJUaGFuVmFsaWRhdG9yLCBsZXNzVGhhbkVxdWFsVG9WYWxpZGF0b3IsIGxlc3NUaGFuVmFsaWRhdG9yXHJcbn0gZnJvbSAnLi4vcmVhY3RpdmUtZm9ybS12YWxpZGF0b3JzJztcclxuXHJcbmltcG9ydCB7IGRlZmF1bHRDb250YWluZXIgfSBmcm9tICcuLi9jb3JlL2RlZmF1bHRDb250YWluZXInO1xyXG5pbXBvcnQgeyBEZWNvcmF0b3JDb25maWd1cmF0aW9uLCBJbnN0YW5jZUNvbnRhaW5lciwgUHJvcGVydHlJbmZvIH0gZnJvbSAnLi4vY29yZS92YWxpZGF0b3IuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uIH0gZnJvbSBcIi4uL21vZGVsc1wiXHJcbmltcG9ydCB7IEFSUkFZX1BST1BFUlRZLCBPQkpFQ1RfUFJPUEVSVFksIFBST1BFUlRZIH0gZnJvbSBcIi4uL2NvbnN0XCJcclxuaW1wb3J0IHsgUHJvcFZhbGlkYXRpb25Db25maWcgfSBmcm9tIFwiLi4vbW9kZWxzL3Byb3AtdmFsaWRhdGlvbi1jb25maWdcIjtcclxuaW1wb3J0IHsgQW5ub3RhdGlvblR5cGVzIH0gZnJvbSBcIi4uL2NvcmUvdmFsaWRhdG9yLnN0YXRpY1wiO1xyXG5pbXBvcnQgeyBjb25kaXRpb25hbENoYW5nZVZhbGlkYXRvciB9IGZyb20gXCIuLi9yZWFjdGl2ZS1mb3JtLXZhbGlkYXRvcnMvY29uZGl0aW9uYWwtY2hhbmdlLnZhbGlkYXRvclwiO1xyXG5pbXBvcnQgeyBMaW5xIH0gZnJvbSAnLi4vdXRpbC9saW5xJ1xyXG5cclxuXHJcbmNvbnN0IEFQUF9WQUxJREFUT1JTOiB7IFtrZXk6IHN0cmluZ106IEZ1bmN0aW9uIH0gPSB7XHJcbiAgICBcImFscGhhTnVtZXJpY1wiOiBhbHBoYU51bWVyaWNWYWxpZGF0b3IsXHJcbiAgICBcImFscGhhXCI6IGFscGhhVmFsaWRhdG9yLFxyXG4gICAgXCJjb21wYXJlXCI6IGNvbXBhcmVWYWxpZGF0b3IsXHJcbiAgICBcImVtYWlsXCI6IGVtYWlsVmFsaWRhdG9yLFxyXG4gICAgXCJoZXhDb2xvclwiOiBoZXhDb2xvclZhbGlkYXRvcixcclxuICAgIFwibG93ZXJDYXNlXCI6IGxvd2VyY2FzZVZhbGlkYXRvcixcclxuICAgIFwibWF4RGF0ZVwiOiBtYXhEYXRlVmFsaWRhdG9yLFxyXG4gICAgXCJtYXhOdW1iZXJcIjogbWF4TnVtYmVyVmFsaWRhdG9yLFxyXG4gICAgXCJtaW5EYXRlXCI6IG1pbkRhdGVWYWxpZGF0b3IsXHJcbiAgICBcIm1pbk51bWJlclwiOiBtaW5OdW1iZXJWYWxpZGF0b3IsXHJcbiAgICBcImNvbnRhaW5zXCI6IGNvbnRhaW5zVmFsaWRhdG9yLFxyXG4gICAgXCJ1cHBlckNhc2VcIjogdXBwZXJjYXNlVmFsaWRhdG9yLFxyXG4gICAgXCJtYXhMZW5ndGhcIjogbWF4TGVuZ3RoVmFsaWRhdG9yLFxyXG4gICAgXCJtaW5MZW5ndGhcIjogbWluTGVuZ3RoVmFsaWRhdG9yLFxyXG4gICAgXCJwYXNzd29yZFwiOiBwYXNzd29yZFZhbGlkYXRvcixcclxuICAgIFwicmFuZ2VcIjogcmFuZ2VWYWxpZGF0b3IsXHJcbiAgICBcInJlcXVpcmVkXCI6IHJlcXVpcmVkVmFsaWRhdG9yLFxyXG4gICAgXCJjcmVkaXRDYXJkXCI6IGNyZWRpdENhcmRWYWxpZGF0b3IsXHJcbiAgICBcImRpZ2l0XCI6IGRpZ2l0VmFsaWRhdG9yLFxyXG4gICAgXCJwYXR0ZXJuXCI6IHBhdHRlcm5WYWxpZGF0b3IsXHJcbiAgICBcInRpbWVcIjogdGltZVZhbGlkYXRvcixcclxuICAgIFwidXJsXCI6IHVybFZhbGlkYXRvcixcclxuICAgIFwianNvblwiOiBqc29uVmFsaWRhdG9yLFxyXG4gICAgXCJncmVhdGVyVGhhblwiOiBncmVhdGVyVGhhblZhbGlkYXRvcixcclxuICAgIFwiZ3JlYXRlclRoYW5FcXVhbFRvXCI6IGdyZWF0ZXJUaGFuRXF1YWxUb1ZhbGlkYXRvcixcclxuICAgIFwibGVzc1RoYW5cIjogbGVzc1RoYW5WYWxpZGF0b3IsXHJcbiAgICBcImxlc3NUaGFuRXF1YWxUb1wiOiBsZXNzVGhhbkVxdWFsVG9WYWxpZGF0b3JcclxufVxyXG5cclxuXHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBSeEZvcm1CdWlsZGVyIHtcclxuICAgIHByaXZhdGUgbmVzdGVkUHJvcDogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBjb25kaXRpb25hbE9iamVjdFByb3BzOiBhbnlbXSA9IFtdO1xyXG4gICAgcHJpdmF0ZSBjb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZTogYW55ID0ge307XHJcbiAgICBwcml2YXRlIGJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wczogYW55W10gPSBbXTtcclxuICAgIHByaXZhdGUgaXNOZXN0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyKSB7IH1cclxuXHJcbiAgICBwcml2YXRlIGdldEluc3RhbmNlQ29udGFpbmVyKGluc3RhbmNlRnVuYzogYW55KTogSW5zdGFuY2VDb250YWluZXIge1xyXG4gICAgICAgIHJldHVybiBkZWZhdWx0Q29udGFpbmVyLmdldChpbnN0YW5jZUZ1bmMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0VmFsdWUoZm9ybUdyb3VwOiBGb3JtR3JvdXAsIG9iamVjdDogYW55KTogdm9pZCB7XHJcbiAgICAgICAgZm9yICh2YXIgY29sIGluIG9iamVjdCkge1xyXG4gICAgICAgICAgICB2YXIgY29udHJvbCA9IGZvcm1Hcm91cC5nZXQoW2NvbF0pO1xyXG4gICAgICAgICAgICBjb250cm9sLnNldFZhbHVlKG9iamVjdFtjb2xdKTtcclxuICAgICAgICAgICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZXh0cmFjdEV4cHJlc3Npb25zKGZvbXJCdWlsZGVyQ29uZmlndXJhdGlvbjogRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9IHtcclxuICAgICAgICBpZiAoZm9tckJ1aWxkZXJDb25maWd1cmF0aW9uICYmIGZvbXJCdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9ucykge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBmb21yQnVpbGRlckNvbmZpZ3VyYXRpb24udmFsaWRhdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGRlY29yYXRvciBpbiBmb21yQnVpbGRlckNvbmZpZ3VyYXRpb24udmFsaWRhdGlvbnNbcHJvcGVydHldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvbXJCdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9uc1twcm9wZXJ0eV1bZGVjb3JhdG9yXS5jb25kaXRpb25hbEV4cHJlc3Npb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbHVtbnMgPSBMaW5xLmV4cHJlc3Npb25Db2x1bW5zKGZvbXJCdWlsZGVyQ29uZmlndXJhdGlvbi52YWxpZGF0aW9uc1twcm9wZXJ0eV1bZGVjb3JhdG9yXS5jb25kaXRpb25hbEV4cHJlc3Npb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Q29udGFpbmVyLmFkZENoYW5nZVZhbGlkYXRpb24odGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZSwgcHJvcGVydHksIGNvbHVtbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFkZEZvcm1Db250cm9sKHByb3BlcnR5OiBQcm9wZXJ0eUluZm8sIHByb3BlcnR5VmFsaWRhdG9yczogRGVjb3JhdG9yQ29uZmlndXJhdGlvbltdLCBwcm9wVmFsaWRhdGlvbkNvbmZpZzogUHJvcFZhbGlkYXRpb25Db25maWcsIGluc3RhbmNlOiBJbnN0YW5jZUNvbnRhaW5lcikge1xyXG4gICAgICAgIGxldCB2YWxpZGF0b3JzID0gW107XHJcbiAgICAgICAgbGV0IGNvbHVtbnMgPSBbXTtcclxuICAgICAgICBpZiAoKGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzICYmIGluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdKSB8fCAodGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyAmJiB0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW3Byb3BlcnR5Lm5hbWVdKSkge1xyXG4gICAgICAgICAgICBsZXQgcHJvcHMgPSBbXTtcclxuICAgICAgICAgICAgaWYgKChpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcyAmJiBpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXSkpXHJcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXS5mb3JFYWNoKHQgPT4gcHJvcHMucHVzaCh0KSlcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMgJiYgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1twcm9wZXJ0eS5uYW1lXSlcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNbcHJvcGVydHkubmFtZV0uZm9yRWFjaCh0ID0+IHByb3BzLnB1c2godCkpO1xyXG4gICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goY29uZGl0aW9uYWxDaGFuZ2VWYWxpZGF0b3IocHJvcHMpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcy5sZW5ndGggPiAwIHx8IHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGV0IHByb3BDb25kaXRpb25zID0gW107XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMpXHJcbiAgICAgICAgICAgICAgICBwcm9wQ29uZGl0aW9ucyA9IHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcy5maWx0ZXIodCA9PiB0LnByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5idWlsZGVyQ29uZmlndXJhdGlvbkNvbmRpdGlvbmFsT2JqZWN0UHJvcHMpXHJcbiAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wcy5maWx0ZXIodCA9PiB0LnByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUpLmZvckVhY2godCA9PiBwcm9wQ29uZGl0aW9ucy5wdXNoKHQpKTtcclxuICAgICAgICAgICAgcHJvcENvbmRpdGlvbnMuZm9yRWFjaCh0ID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0LnJlZmVyZW5jZVByb3BOYW1lICYmIGNvbHVtbnMuaW5kZXhPZih0LnJlZmVyZW5jZVByb3BOYW1lKSA9PSAtMSlcclxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zLnB1c2godC5yZWZlcmVuY2VQcm9wTmFtZSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIGlmIChjb2x1bW5zLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goY29uZGl0aW9uYWxDaGFuZ2VWYWxpZGF0b3IoY29sdW1ucykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBwcm9wZXJ0eVZhbGlkYXRvciBvZiBwcm9wZXJ0eVZhbGlkYXRvcnMpIHtcclxuICAgICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKEFQUF9WQUxJREFUT1JTW3Byb3BlcnR5VmFsaWRhdG9yLmFubm90YXRpb25UeXBlXShwcm9wZXJ0eVZhbGlkYXRvci5jb25maWcsICkpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwcm9wVmFsaWRhdGlvbkNvbmZpZylcclxuICAgICAgICAgICAgdGhpcy5hZGRpdGlvbmFsVmFsaWRhdGlvbih2YWxpZGF0b3JzLCBwcm9wVmFsaWRhdGlvbkNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRvcnM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhZGRpdGlvbmFsVmFsaWRhdGlvbih2YWxpZGF0aW9uczogYW55W10sIHByb3BWYWxpZGF0aW9uQ29uZmlnOiBQcm9wVmFsaWRhdGlvbkNvbmZpZykge1xyXG4gICAgICAgIGZvciAodmFyIGNvbCBpbiBBbm5vdGF0aW9uVHlwZXMpIHtcclxuICAgICAgICAgICAgaWYgKHByb3BWYWxpZGF0aW9uQ29uZmlnW0Fubm90YXRpb25UeXBlc1tjb2xdXSAmJiBjb2wgIT0gXCJjdXN0b21cIikge1xyXG4gICAgICAgICAgICAgICAgdmFsaWRhdGlvbnMucHVzaChBUFBfVkFMSURBVE9SU1tBbm5vdGF0aW9uVHlwZXNbY29sXV0ocHJvcFZhbGlkYXRpb25Db25maWdbQW5ub3RhdGlvblR5cGVzW2NvbF1dKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoY29sID09IEFubm90YXRpb25UeXBlcy5jdXN0b20gJiYgcHJvcFZhbGlkYXRpb25Db25maWdbQW5ub3RhdGlvblR5cGVzW2NvbF1dKVxyXG4gICAgICAgICAgICAgICAgdmFsaWRhdGlvbnMucHVzaChwcm9wVmFsaWRhdGlvbkNvbmZpZ1tjb2xdKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjaGVja09iamVjdFByb3BBZGRpdGlvbmFsVmFsaWRhdGlvbjxUPihpbnN0YW5jZUNvbnRhaW5lcjogSW5zdGFuY2VDb250YWluZXIsIG9iamVjdDogVCkge1xyXG4gICAgICAgIHZhciBwcm9wcyA9IGluc3RhbmNlQ29udGFpbmVyLnByb3BlcnRpZXMuZmlsdGVyKHQgPT4gdC5wcm9wZXJ0eVR5cGUgPT0gT0JKRUNUX1BST1BFUlRZIHx8IHQucHJvcGVydHlUeXBlID09IEFSUkFZX1BST1BFUlRZKVxyXG4gICAgICAgIHByb3BzLmZvckVhY2godCA9PiB7XHJcbiAgICAgICAgICAgIGxldCBpbnN0YW5jZSA9IHRoaXMuZ2V0SW5zdGFuY2VDb250YWluZXIodC5lbnRpdHkpO1xyXG4gICAgICAgICAgICBpZiAoaW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBpbnN0YW5jZS5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm9wID0gaW5zdGFuY2UucHJvcGVydGllcy5maWx0ZXIodCA9PiB0Lm5hbWUgPT0ga2V5KVswXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXByb3ApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3AgPSBpbnN0YW5jZUNvbnRhaW5lci5wcm9wZXJ0aWVzLmZpbHRlcih0ID0+IHQubmFtZSA9PSBrZXkpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1trZXldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbFZhbGlkYXRpb25Qcm9wc1trZXldID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNba2V5XS5mb3JFYWNoKHggPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQucHJvcGVydHlUeXBlICE9IEFSUkFZX1BST1BFUlRZKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsVmFsaWRhdGlvblByb3BzW2tleV0ucHVzaChbdC5uYW1lLCB4XS5qb2luKCcuJykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxWYWxpZGF0aW9uUHJvcHNba2V5XS5wdXNoKFt0Lm5hbWUsIHhdLmpvaW4oJ1tdJykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgZ2V0T2JqZWN0KG1vZGVsOiBhbnkgfCB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBlbnRpdHlPYmplY3Q/OiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHwgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uLCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24/OiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pOiB7W2tleTpzdHJpbmddOmFueX0ge1xyXG4gICAgICAgIGxldCBqc29uOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgICAgICBqc29uLm1vZGVsID0gbW9kZWw7XHJcblxyXG4gICAgICAgIGlmIChlbnRpdHlPYmplY3QgJiYgIShlbnRpdHlPYmplY3QgaW5zdGFuY2VvZiBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pKVxyXG4gICAgICAgICAgICBqc29uLmVudGl0eU9iamVjdCA9IGVudGl0eU9iamVjdDtcclxuXHJcbiAgICAgICAgaWYgKGVudGl0eU9iamVjdCBpbnN0YW5jZW9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiAmJiAhZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKVxyXG4gICAgICAgICAgICBqc29uLmZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiA9IGVudGl0eU9iamVjdDtcclxuICAgICAgICBlbHNlIGlmICghKGVudGl0eU9iamVjdCBpbnN0YW5jZW9mIEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbikgJiYgZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKVxyXG4gICAgICAgICAgICBqc29uLmZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiA9IGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbjtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoIWVudGl0eU9iamVjdCkge1xyXG4gICAgICAgICAgICBqc29uLmVudGl0eU9iamVjdCA9IG1vZGVsO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG1vZGVsID09IFwib2JqZWN0XCIpXHJcbiAgICAgICAgICAgICAgICBqc29uLm1vZGVsID0gbW9kZWwuY29uc3RydWN0b3I7XHJcbiAgICAgICAgfSBlbHNlIGlmIChtb2RlbCAmJiAoZW50aXR5T2JqZWN0IGluc3RhbmNlb2YgRm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKSAmJiAodHlwZW9mIG1vZGVsID09IFwib2JqZWN0XCIpKSB7XHJcbiAgICAgICAgICAgIGpzb25bXCJlbnRpdHlPYmplY3RcIl0gPSBtb2RlbDtcclxuICAgICAgICAgICAganNvbltcIm1vZGVsXCJdID0gbW9kZWwuY29uc3RydWN0b3I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBqc29uO1xyXG4gICAgfVxyXG5cclxuICAgIGZvcm1Hcm91cDxUPihtb2RlbDogVHlwZTxUPiB8IHsgW2tleTogc3RyaW5nXTogYW55IH0sIGVudGl0eU9iamVjdD86IHsgW2tleTogc3RyaW5nXTogYW55IH0gfCBGb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24sIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbj86IEZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbik6IEZvcm1Hcm91cCB7XHJcbiAgICAgICAgbGV0IGpzb24gPSB0aGlzLmdldE9iamVjdChtb2RlbCwgZW50aXR5T2JqZWN0LCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pO1xyXG4gICAgICAgIG1vZGVsID0ganNvbi5tb2RlbDtcclxuICAgICAgICBlbnRpdHlPYmplY3QgPSBqc29uLmVudGl0eU9iamVjdDtcclxuICAgICAgICBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24gPSBqc29uLmZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbjtcclxuICAgICAgICBpZiAoZm9ybUJ1aWxkZXJDb25maWd1cmF0aW9uKVxyXG4gICAgICAgICAgICB0aGlzLmV4dHJhY3RFeHByZXNzaW9ucyhmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pO1xyXG4gICAgICAgIGxldCBpbnN0YW5jZUNvbnRhaW5lcjogSW5zdGFuY2VDb250YWluZXIgPSB0aGlzLmdldEluc3RhbmNlQ29udGFpbmVyKG1vZGVsKTtcclxuICAgICAgICB0aGlzLmNoZWNrT2JqZWN0UHJvcEFkZGl0aW9uYWxWYWxpZGF0aW9uKGluc3RhbmNlQ29udGFpbmVyLCBlbnRpdHlPYmplY3QpO1xyXG4gICAgICAgIGxldCBmb3JtR3JvdXBPYmplY3QgPSB7fTtcclxuICAgICAgICBsZXQgZm9ybUNoaWxkR3JvdXAgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgbGV0IGZvcm1BcnJheUdyb3VwID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHZhciBhZGRpdGlvbmFsVmFsaWRhdGlvbnM6IHsgW2tleTogc3RyaW5nXTogUHJvcFZhbGlkYXRpb25Db25maWcgfSA9IHt9O1xyXG4gICAgICAgIGluc3RhbmNlQ29udGFpbmVyLnByb3BlcnRpZXMuZm9yRWFjaChwcm9wZXJ0eSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBpc0luY2x1ZGVQcm9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uZXhjbHVkZVByb3BzICYmIGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbi5leGNsdWRlUHJvcHMubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgICAgIGlzSW5jbHVkZVByb3AgPSBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24uZXhjbHVkZVByb3BzLmluZGV4T2YocHJvcGVydHkubmFtZSkgPT0gLTFcclxuICAgICAgICAgICAgaWYgKGZvcm1CdWlsZGVyQ29uZmlndXJhdGlvbiAmJiBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24udmFsaWRhdGlvbnMpXHJcbiAgICAgICAgICAgICAgICBhZGRpdGlvbmFsVmFsaWRhdGlvbnMgPSBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24udmFsaWRhdGlvbnM7XHJcbiAgICAgICAgICAgIGlmIChpc0luY2x1ZGVQcm9wKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHByb3BlcnR5LnByb3BlcnR5VHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgUFJPUEVSVFk6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0eVZhbGlkYXRvcnMgPSBpbnN0YW5jZUNvbnRhaW5lci5wcm9wZXJ0eUFubm90YXRpb25zLmZpbHRlcih0ID0+IHQucHJvcGVydHlOYW1lID09IHByb3BlcnR5Lm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JtR3JvdXBPYmplY3RbcHJvcGVydHkubmFtZV0gPSBbZW50aXR5T2JqZWN0W3Byb3BlcnR5Lm5hbWVdLCB0aGlzLmFkZEZvcm1Db250cm9sKHByb3BlcnR5LCBwcm9wZXJ0eVZhbGlkYXRvcnMsIGFkZGl0aW9uYWxWYWxpZGF0aW9uc1twcm9wZXJ0eS5uYW1lXSwgaW5zdGFuY2VDb250YWluZXIpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIE9CSkVDVF9QUk9QRVJUWTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudGl0eU9iamVjdFtwcm9wZXJ0eS5uYW1lXSAmJiBlbnRpdHlPYmplY3RbcHJvcGVydHkubmFtZV0gaW5zdGFuY2VvZiBPYmplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNOZXN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlQ29udGFpbmVyICYmIGluc3RhbmNlQ29udGFpbmVyLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb25hbE9iamVjdFByb3BzID0gaW5zdGFuY2VDb250YWluZXIuY29uZGl0aW9uYWxPYmplY3RQcm9wcy5maWx0ZXIodCA9PiB0Lm9iamVjdFByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZSAmJiB0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsZGVyQ29uZmlndXJhdGlvbkNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgPSB0aGlzLmNvbmRpdGlvbmFsVmFsaWRhdGlvbkluc3RhbmNlLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMuZmlsdGVyKHQgPT4gdC5vYmplY3RQcm9wTmFtZSA9PSBwcm9wZXJ0eS5uYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Hcm91cE9iamVjdFtwcm9wZXJ0eS5uYW1lXSA9IHRoaXMuZm9ybUdyb3VwKHByb3BlcnR5LmVudGl0eSwgZW50aXR5T2JqZWN0W3Byb3BlcnR5Lm5hbWVdLCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb25hbE9iamVjdFByb3BzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQVJSQVlfUFJPUEVSVFk6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnRpdHlPYmplY3RbcHJvcGVydHkubmFtZV0gJiYgZW50aXR5T2JqZWN0W3Byb3BlcnR5Lm5hbWVdIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNOZXN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvcm1BcnJheUdyb3VwID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgc3ViT2JqZWN0IG9mIGVudGl0eU9iamVjdFtwcm9wZXJ0eS5uYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZUNvbnRhaW5lciAmJiBpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbE9iamVjdFByb3BzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbmFsT2JqZWN0UHJvcHMgPSBpbnN0YW5jZUNvbnRhaW5lci5jb25kaXRpb25hbE9iamVjdFByb3BzLmZpbHRlcih0ID0+IHQub2JqZWN0UHJvcE5hbWUgPT0gcHJvcGVydHkubmFtZSAmJiB0LmFycmF5SW5kZXggPT0gaW5kZXgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UgJiYgdGhpcy5jb25kaXRpb25hbFZhbGlkYXRpb25JbnN0YW5jZS5jb25kaXRpb25hbE9iamVjdFByb3BzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkZXJDb25maWd1cmF0aW9uQ29uZGl0aW9uYWxPYmplY3RQcm9wcyA9IHRoaXMuY29uZGl0aW9uYWxWYWxpZGF0aW9uSW5zdGFuY2UuY29uZGl0aW9uYWxPYmplY3RQcm9wcy5maWx0ZXIodCA9PiB0Lm9iamVjdFByb3BOYW1lID09IHByb3BlcnR5Lm5hbWUgJiYgdC5hcnJheUluZGV4ID09IGluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQXJyYXlHcm91cC5wdXNoKHRoaXMuZm9ybUdyb3VwKHByb3BlcnR5LmVudGl0eSwgc3ViT2JqZWN0LCBmb3JtQnVpbGRlckNvbmZpZ3VyYXRpb24pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCsrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uYWxPYmplY3RQcm9wcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRlckNvbmZpZ3VyYXRpb25Db25kaXRpb25hbE9iamVjdFByb3BzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtR3JvdXBPYmplY3RbcHJvcGVydHkubmFtZV0gPSB0aGlzLmZvcm1CdWlsZGVyLmFycmF5KGZvcm1BcnJheUdyb3VwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNOZXN0ZWQgP