angular-reactive-validation
Version:
Reactive Forms validation shouldn't require the developer to write lots of HTML to show validation messages. This library makes it easy.
141 lines • 23.3 kB
JavaScript
import { Component, ContentChildren, Input, ViewEncapsulation, Optional, Inject } from '@angular/core';
import { Subscription } from 'rxjs';
import { ValidationMessageComponent } from '../validation-message/validation-message.component';
import { ValidationError } from '../validation-error';
import { getFormControlFromContainer, isControlContainerVoidOrInitialized } from '../get-form-control-from-container';
import { REACTIVE_VALIDATION_MODULE_CONFIGURATION_TOKEN } from '../reactive-validation-module-configuration-token';
import { getControlPath } from '../get-control-path';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "../form/form.directive";
import * as i3 from "@angular/common";
/**
* The ValidationMessagesComponent shows validation messages for one to many FormControls. It either shows
* messages specified within the reactive form model, or shows custom messages declared using the
* ValidationMessageComponent.
*/
export class ValidationMessagesComponent {
constructor(controlContainer, formSubmitDirective, configuration) {
this.controlContainer = controlContainer;
this.configuration = configuration;
this._for = [];
this.messageComponentsChangesSubscription = new Subscription();
this.controlStatusChangesSubscription = new Subscription();
this.formSubmitted = undefined;
this.formSubmittedSubscription = new Subscription();
this.initializeForOnInit = () => { };
if (formSubmitDirective) {
this.formSubmitted = false;
this.formSubmittedSubscription.add(formSubmitDirective.submitted.subscribe(() => {
this.formSubmitted = true;
}));
}
}
ngOnInit() {
this.initializeForOnInit();
}
ngAfterContentInit() {
this.messageComponentsChangesSubscription.add(this.messageComponents?.changes.subscribe(this.validateChildren));
this.validateChildren();
this._for.forEach(control => {
this.handleControlStatusChange(control);
});
}
ngOnDestroy() {
this.messageComponentsChangesSubscription.unsubscribe();
this.formSubmittedSubscription.unsubscribe();
this.controlStatusChangesSubscription.unsubscribe();
}
isValid() {
return this.getFirstErrorPerControl().length === 0;
}
getErrorMessages() {
return this.getFirstErrorPerControl().filter(error => error.hasMessage())
.map(error => error.getMessage());
}
set for(controls) {
if (!isControlContainerVoidOrInitialized(this.controlContainer)) {
this.initializeForOnInit = () => this.for = controls;
return;
}
if (!Array.isArray(controls)) {
controls = controls !== undefined ? [controls] : [];
}
if (controls.length === 0) {
throw new Error(`arv-validation-messages doesn't allow declaring an empty array as input to the 'for' attribute.`);
}
this._for = controls.map(control => typeof control === 'string' ?
getFormControlFromContainer(control, this.controlContainer) : control);
this.validateChildren();
this.controlStatusChangesSubscription.unsubscribe();
this.controlStatusChangesSubscription = new Subscription();
this._for.forEach(control => {
this.controlStatusChangesSubscription.add(control.statusChanges.subscribe(() => {
this.handleControlStatusChange(control);
}));
});
}
getFirstErrorPerControl() {
return this._for.filter(control => this.configuration && this.configuration.displayValidationMessageWhen ?
this.configuration.displayValidationMessageWhen(control, this.formSubmitted) : control.touched || this.formSubmitted).map(ValidationError.fromFirstError).filter(value => value !== undefined);
}
/**
* Validates that the child ValidationMessageComponents declare what FormControl they specify a message for (when needed); and
* that the declared FormControl is actually part of the parent ValidationMessagesComponent 'for' collection (when specified).
*/
validateChildren() {
if (!this.messageComponents) {
return;
}
this.messageComponents.forEach(component => {
if (this._for.length > 1 && component.for === undefined) {
throw new Error(`Specify the FormControl for which the arv-validation-message element with key '${component.key}' ` +
`should show messages.`);
}
if (component.for && this._for.indexOf(component.for) === -1) {
throw new Error(`A arv-validation-messages element with key '${component.key}' attempts to show messages ` +
`for a FormControl that is not declared in the parent arv-validation-messages element.`);
}
});
}
handleControlStatusChange(control) {
if (!this.messageComponents) {
return;
}
this.messageComponents.filter(component => component.for === control || component.for === undefined)
.forEach(component => component.reset());
const error = ValidationError.fromFirstError(control);
if (!error || error.hasMessage()) {
return;
}
const messageComponent = this.messageComponents.find(component => component.canHandle(error));
if (messageComponent) {
messageComponent.show(error);
}
else {
throw new Error(`There is no suitable arv-validation-message element to show the '${error.key}' ` +
`error of '${getControlPath(error.control)}'`);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: ValidationMessagesComponent, deps: [{ token: i1.ControlContainer, optional: true }, { token: i2.FormDirective, optional: true }, { token: REACTIVE_VALIDATION_MODULE_CONFIGURATION_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.2", type: ValidationMessagesComponent, selector: "arv-validation-messages", inputs: { for: "for" }, queries: [{ propertyName: "messageComponents", predicate: ValidationMessageComponent }], ngImport: i0, template: "<div *ngIf=\"!isValid()\">\n <div class=\"invalid-feedback\">\n <p *ngFor=\"let message of getErrorMessages()\">{{message}}</p>\n </div>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: ValidationMessagesComponent, decorators: [{
type: Component,
args: [{ selector: 'arv-validation-messages', encapsulation: ViewEncapsulation.None, template: "<div *ngIf=\"!isValid()\">\n <div class=\"invalid-feedback\">\n <p *ngFor=\"let message of getErrorMessages()\">{{message}}</p>\n </div>\n <ng-content></ng-content>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.ControlContainer, decorators: [{
type: Optional
}] }, { type: i2.FormDirective, decorators: [{
type: Optional
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [REACTIVE_VALIDATION_MODULE_CONFIGURATION_TOKEN]
}] }], propDecorators: { messageComponents: [{
type: ContentChildren,
args: [ValidationMessageComponent]
}], for: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1tZXNzYWdlcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXJlYWN0aXZlLXZhbGlkYXRpb24vc3JjL2xpYi92YWxpZGF0aW9uLW1lc3NhZ2VzL3ZhbGlkYXRpb24tbWVzc2FnZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1yZWFjdGl2ZS12YWxpZGF0aW9uL3NyYy9saWIvdmFsaWRhdGlvbi1tZXNzYWdlcy92YWxpZGF0aW9uLW1lc3NhZ2VzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFhLEtBQUssRUFBRSxpQkFBaUIsRUFDM0QsUUFBUSxFQUFFLE1BQU0sRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUU3RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXBDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLG9EQUFvRCxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsbUNBQW1DLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUd0SCxPQUFPLEVBQUUsOENBQThDLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUNuSCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7Ozs7O0FBT3JEOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sMkJBQTJCO0lBVXRDLFlBQWdDLGdCQUFrQyxFQUFjLG1CQUFrQyxFQUNwQyxhQUFvRDtRQURsRyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ1ksa0JBQWEsR0FBYixhQUFhLENBQXVDO1FBUjFILFNBQUksR0FBeUIsRUFBRSxDQUFDO1FBQ2hDLHlDQUFvQyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDMUQscUNBQWdDLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUV0RCxrQkFBYSxHQUF3QixTQUFTLENBQUM7UUFDL0MsOEJBQXlCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQXdDL0Msd0JBQW1CLEdBQUcsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBcENuQyxJQUFJLG1CQUFtQixFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7WUFDM0IsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtnQkFDOUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1FBQ2hILElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBRXhCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzFCLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3hELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdEQsQ0FBQztJQUVELE9BQU87UUFDTCxPQUFPLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELGdCQUFnQjtRQUNkLE9BQU8sSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO2FBQ3RFLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFJRCxJQUNJLEdBQUcsQ0FBQyxRQUFxRTtRQUMzRSxJQUFJLENBQUMsbUNBQW1DLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUNoRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxRQUFRLENBQUM7WUFDckQsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLFFBQVEsR0FBRyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEQsQ0FBQztRQUVELElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLGlHQUFpRyxDQUFDLENBQUM7UUFDckgsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDO1lBQy9ELDJCQUEyQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFekUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFeEIsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3BELElBQUksQ0FBQyxnQ0FBZ0MsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzFCLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO2dCQUM3RSxJQUFJLENBQUMseUJBQXlCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUlPLHVCQUF1QjtRQUM3QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLDRCQUE0QixDQUFDLENBQUM7WUFDeEcsSUFBSSxDQUFDLGFBQWEsQ0FBQyw0QkFBNEIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQ3JILENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFzQixDQUFDO0lBQ2xHLENBQUM7SUFFRDs7O09BR0c7SUFDSyxnQkFBZ0I7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzVCLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUN6QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxTQUFTLENBQUMsR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN4RCxNQUFNLElBQUksS0FBSyxDQUFDLGtGQUFrRixTQUFTLENBQUMsR0FBRyxJQUFJO29CQUNqSCx1QkFBdUIsQ0FBQyxDQUFDO1lBQzdCLENBQUM7WUFDRCxJQUFJLFNBQVMsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQXlCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNuRixNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxTQUFTLENBQUMsR0FBRyw4QkFBOEI7b0JBQ3hHLHVGQUF1RixDQUFDLENBQUM7WUFDN0YsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHlCQUF5QixDQUFDLE9BQTJCO1FBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUM1QixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxLQUFLLE9BQU8sSUFBSSxTQUFTLENBQUMsR0FBRyxLQUFLLFNBQVMsQ0FBQzthQUNqRyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUUzQyxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUM7WUFDakMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFOUYsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsb0VBQW9FLEtBQUssQ0FBQyxHQUFHLElBQUk7Z0JBQy9GLGFBQWEsY0FBYyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7OEdBaklVLDJCQUEyQiwrR0FXaEIsOENBQThDO2tHQVh6RCwyQkFBMkIseUhBQ3JCLDBCQUEwQiw2QkN4QjdDLHNMQU1BOzsyRkRpQmEsMkJBQTJCO2tCQVZ2QyxTQUFTOytCQUNFLHlCQUF5QixpQkFFcEIsaUJBQWlCLENBQUMsSUFBSTs7MEJBaUJ4QixRQUFROzswQkFBZ0QsUUFBUTs7MEJBQzFFLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsOENBQThDO3lDQVZmLGlCQUFpQjtzQkFBckUsZUFBZTt1QkFBQywwQkFBMEI7Z0JBa0R2QyxHQUFHO3NCQUROLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIENvbnRlbnRDaGlsZHJlbiwgUXVlcnlMaXN0LCBJbnB1dCwgVmlld0VuY2Fwc3VsYXRpb24sIEFmdGVyQ29udGVudEluaXQsXG4gIE9uRGVzdHJveSwgT3B0aW9uYWwsIEluamVjdCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVbnR5cGVkRm9ybUNvbnRyb2wsIENvbnRyb2xDb250YWluZXIgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgVmFsaWRhdGlvbk1lc3NhZ2VDb21wb25lbnQgfSBmcm9tICcuLi92YWxpZGF0aW9uLW1lc3NhZ2UvdmFsaWRhdGlvbi1tZXNzYWdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuLi92YWxpZGF0aW9uLWVycm9yJztcbmltcG9ydCB7IGdldEZvcm1Db250cm9sRnJvbUNvbnRhaW5lciwgaXNDb250cm9sQ29udGFpbmVyVm9pZE9ySW5pdGlhbGl6ZWQgfSBmcm9tICcuLi9nZXQtZm9ybS1jb250cm9sLWZyb20tY29udGFpbmVyJztcbmltcG9ydCB7IEZvcm1EaXJlY3RpdmUgfSBmcm9tICcuLi9mb3JtL2Zvcm0uZGlyZWN0aXZlJztcbmltcG9ydCB7IFJlYWN0aXZlVmFsaWRhdGlvbk1vZHVsZUNvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9yZWFjdGl2ZS12YWxpZGF0aW9uLW1vZHVsZS1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFJFQUNUSVZFX1ZBTElEQVRJT05fTU9EVUxFX0NPTkZJR1VSQVRJT05fVE9LRU4gfSBmcm9tICcuLi9yZWFjdGl2ZS12YWxpZGF0aW9uLW1vZHVsZS1jb25maWd1cmF0aW9uLXRva2VuJztcbmltcG9ydCB7IGdldENvbnRyb2xQYXRoIH0gZnJvbSAnLi4vZ2V0LWNvbnRyb2wtcGF0aCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Fydi12YWxpZGF0aW9uLW1lc3NhZ2VzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3ZhbGlkYXRpb24tbWVzc2FnZXMuY29tcG9uZW50Lmh0bWwnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuLyoqXG4gKiBUaGUgVmFsaWRhdGlvbk1lc3NhZ2VzQ29tcG9uZW50IHNob3dzIHZhbGlkYXRpb24gbWVzc2FnZXMgZm9yIG9uZSB0byBtYW55IEZvcm1Db250cm9scy4gSXQgZWl0aGVyIHNob3dzXG4gKiBtZXNzYWdlcyBzcGVjaWZpZWQgd2l0aGluIHRoZSByZWFjdGl2ZSBmb3JtIG1vZGVsLCBvciBzaG93cyBjdXN0b20gbWVzc2FnZXMgZGVjbGFyZWQgdXNpbmcgdGhlXG4gKiBWYWxpZGF0aW9uTWVzc2FnZUNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25NZXNzYWdlc0NvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSwgT25Jbml0IHtcbiAgQENvbnRlbnRDaGlsZHJlbihWYWxpZGF0aW9uTWVzc2FnZUNvbXBvbmVudCkgcHJpdmF0ZSBtZXNzYWdlQ29tcG9uZW50czogUXVlcnlMaXN0PFZhbGlkYXRpb25NZXNzYWdlQ29tcG9uZW50PiB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIF9mb3I6IFVudHlwZWRGb3JtQ29udHJvbFtdID0gW107XG4gIHByaXZhdGUgbWVzc2FnZUNvbXBvbmVudHNDaGFuZ2VzU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIGNvbnRyb2xTdGF0dXNDaGFuZ2VzU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIHByaXZhdGUgZm9ybVN1Ym1pdHRlZDogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBmb3JtU3VibWl0dGVkU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIHByaXZhdGUgY29udHJvbENvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lciwgQE9wdGlvbmFsKCkgZm9ybVN1Ym1pdERpcmVjdGl2ZTogRm9ybURpcmVjdGl2ZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFJFQUNUSVZFX1ZBTElEQVRJT05fTU9EVUxFX0NPTkZJR1VSQVRJT05fVE9LRU4pIHByaXZhdGUgY29uZmlndXJhdGlvbjogUmVhY3RpdmVWYWxpZGF0aW9uTW9kdWxlQ29uZmlndXJhdGlvbikge1xuICAgICAgaWYgKGZvcm1TdWJtaXREaXJlY3RpdmUpIHtcbiAgICAgICAgdGhpcy5mb3JtU3VibWl0dGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pdHRlZFN1YnNjcmlwdGlvbi5hZGQoZm9ybVN1Ym1pdERpcmVjdGl2ZS5zdWJtaXR0ZWQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmZvcm1TdWJtaXR0ZWQgPSB0cnVlO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmluaXRpYWxpemVGb3JPbkluaXQoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLm1lc3NhZ2VDb21wb25lbnRzQ2hhbmdlc1N1YnNjcmlwdGlvbi5hZGQodGhpcy5tZXNzYWdlQ29tcG9uZW50cz8uY2hhbmdlcy5zdWJzY3JpYmUodGhpcy52YWxpZGF0ZUNoaWxkcmVuKSk7XG4gICAgdGhpcy52YWxpZGF0ZUNoaWxkcmVuKCk7XG5cbiAgICB0aGlzLl9mb3IuZm9yRWFjaChjb250cm9sID0+IHtcbiAgICAgIHRoaXMuaGFuZGxlQ29udHJvbFN0YXR1c0NoYW5nZShjb250cm9sKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMubWVzc2FnZUNvbXBvbmVudHNDaGFuZ2VzU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5mb3JtU3VibWl0dGVkU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5jb250cm9sU3RhdHVzQ2hhbmdlc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgaXNWYWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXRGaXJzdEVycm9yUGVyQ29udHJvbCgpLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIGdldEVycm9yTWVzc2FnZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLmdldEZpcnN0RXJyb3JQZXJDb250cm9sKCkuZmlsdGVyKGVycm9yID0+IGVycm9yLmhhc01lc3NhZ2UoKSlcbiAgICAgIC5tYXAoZXJyb3IgPT4gZXJyb3IuZ2V0TWVzc2FnZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUZvck9uSW5pdCA9ICgpID0+IHt9O1xuXG4gIEBJbnB1dCgpXG4gIHNldCBmb3IoY29udHJvbHM6IFVudHlwZWRGb3JtQ29udHJvbCB8IChVbnR5cGVkRm9ybUNvbnRyb2x8c3RyaW5nKVtdIHwgc3RyaW5nKSB7XG4gICAgaWYgKCFpc0NvbnRyb2xDb250YWluZXJWb2lkT3JJbml0aWFsaXplZCh0aGlzLmNvbnRyb2xDb250YWluZXIpKSB7XG4gICAgICB0aGlzLmluaXRpYWxpemVGb3JPbkluaXQgPSAoKSA9PiB0aGlzLmZvciA9IGNvbnRyb2xzO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShjb250cm9scykpIHtcbiAgICAgIGNvbnRyb2xzID0gY29udHJvbHMgIT09IHVuZGVmaW5lZCA/IFtjb250cm9sc10gOiBbXTtcbiAgICB9XG5cbiAgICBpZiAoY29udHJvbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGFydi12YWxpZGF0aW9uLW1lc3NhZ2VzIGRvZXNuJ3QgYWxsb3cgZGVjbGFyaW5nIGFuIGVtcHR5IGFycmF5IGFzIGlucHV0IHRvIHRoZSAnZm9yJyBhdHRyaWJ1dGUuYCk7XG4gICAgfVxuXG4gICAgdGhpcy5fZm9yID0gY29udHJvbHMubWFwKGNvbnRyb2wgPT4gdHlwZW9mIGNvbnRyb2wgPT09ICdzdHJpbmcnID9cbiAgICAgIGdldEZvcm1Db250cm9sRnJvbUNvbnRhaW5lcihjb250cm9sLCB0aGlzLmNvbnRyb2xDb250YWluZXIpIDogY29udHJvbCk7XG5cbiAgICB0aGlzLnZhbGlkYXRlQ2hpbGRyZW4oKTtcblxuICAgIHRoaXMuY29udHJvbFN0YXR1c0NoYW5nZXNTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmNvbnRyb2xTdGF0dXNDaGFuZ2VzU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICAgIHRoaXMuX2Zvci5mb3JFYWNoKGNvbnRyb2wgPT4ge1xuICAgICAgdGhpcy5jb250cm9sU3RhdHVzQ2hhbmdlc1N1YnNjcmlwdGlvbi5hZGQoY29udHJvbC5zdGF0dXNDaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlQ29udHJvbFN0YXR1c0NoYW5nZShjb250cm9sKTtcbiAgICAgIH0pKTtcbiAgICB9KTtcbiAgfVxuXG5cblxuICBwcml2YXRlIGdldEZpcnN0RXJyb3JQZXJDb250cm9sKCkge1xuICAgIHJldHVybiB0aGlzLl9mb3IuZmlsdGVyKGNvbnRyb2wgPT4gdGhpcy5jb25maWd1cmF0aW9uICYmIHRoaXMuY29uZmlndXJhdGlvbi5kaXNwbGF5VmFsaWRhdGlvbk1lc3NhZ2VXaGVuID9cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5kaXNwbGF5VmFsaWRhdGlvbk1lc3NhZ2VXaGVuKGNvbnRyb2wsIHRoaXMuZm9ybVN1Ym1pdHRlZCkgOiBjb250cm9sLnRvdWNoZWQgfHwgdGhpcy5mb3JtU3VibWl0dGVkXG4gICAgKS5tYXAoVmFsaWRhdGlvbkVycm9yLmZyb21GaXJzdEVycm9yKS5maWx0ZXIodmFsdWUgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCkgYXMgVmFsaWRhdGlvbkVycm9yW107XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoYXQgdGhlIGNoaWxkIFZhbGlkYXRpb25NZXNzYWdlQ29tcG9uZW50cyBkZWNsYXJlIHdoYXQgRm9ybUNvbnRyb2wgdGhleSBzcGVjaWZ5IGEgbWVzc2FnZSBmb3IgKHdoZW4gbmVlZGVkKTsgYW5kXG4gICAqIHRoYXQgdGhlIGRlY2xhcmVkIEZvcm1Db250cm9sIGlzIGFjdHVhbGx5IHBhcnQgb2YgdGhlIHBhcmVudCBWYWxpZGF0aW9uTWVzc2FnZXNDb21wb25lbnQgJ2ZvcicgY29sbGVjdGlvbiAod2hlbiBzcGVjaWZpZWQpLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUNoaWxkcmVuKCkge1xuICAgIGlmICghdGhpcy5tZXNzYWdlQ29tcG9uZW50cykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubWVzc2FnZUNvbXBvbmVudHMuZm9yRWFjaChjb21wb25lbnQgPT4ge1xuICAgICAgaWYgKHRoaXMuX2Zvci5sZW5ndGggPiAxICYmIGNvbXBvbmVudC5mb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNwZWNpZnkgdGhlIEZvcm1Db250cm9sIGZvciB3aGljaCB0aGUgYXJ2LXZhbGlkYXRpb24tbWVzc2FnZSBlbGVtZW50IHdpdGgga2V5ICcke2NvbXBvbmVudC5rZXl9JyBgICtcbiAgICAgICAgICBgc2hvdWxkIHNob3cgbWVzc2FnZXMuYCk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcG9uZW50LmZvciAmJiB0aGlzLl9mb3IuaW5kZXhPZihjb21wb25lbnQuZm9yIGFzIFVudHlwZWRGb3JtQ29udHJvbCkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQSBhcnYtdmFsaWRhdGlvbi1tZXNzYWdlcyBlbGVtZW50IHdpdGgga2V5ICcke2NvbXBvbmVudC5rZXl9JyBhdHRlbXB0cyB0byBzaG93IG1lc3NhZ2VzIGAgK1xuICAgICAgICAgIGBmb3IgYSBGb3JtQ29udHJvbCB0aGF0IGlzIG5vdCBkZWNsYXJlZCBpbiB0aGUgcGFyZW50IGFydi12YWxpZGF0aW9uLW1lc3NhZ2VzIGVsZW1lbnQuYCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNvbnRyb2xTdGF0dXNDaGFuZ2UoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKSB7XG4gICAgaWYgKCF0aGlzLm1lc3NhZ2VDb21wb25lbnRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5tZXNzYWdlQ29tcG9uZW50cy5maWx0ZXIoY29tcG9uZW50ID0+IGNvbXBvbmVudC5mb3IgPT09IGNvbnRyb2wgfHwgY29tcG9uZW50LmZvciA9PT0gdW5kZWZpbmVkKVxuICAgICAgLmZvckVhY2goY29tcG9uZW50ID0+IGNvbXBvbmVudC5yZXNldCgpKTtcblxuICAgIGNvbnN0IGVycm9yID0gVmFsaWRhdGlvbkVycm9yLmZyb21GaXJzdEVycm9yKGNvbnRyb2wpO1xuICAgIGlmICghZXJyb3IgfHwgZXJyb3IuaGFzTWVzc2FnZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbWVzc2FnZUNvbXBvbmVudCA9IHRoaXMubWVzc2FnZUNvbXBvbmVudHMuZmluZChjb21wb25lbnQgPT4gY29tcG9uZW50LmNhbkhhbmRsZShlcnJvcikpO1xuXG4gICAgaWYgKG1lc3NhZ2VDb21wb25lbnQpIHtcbiAgICAgIG1lc3NhZ2VDb21wb25lbnQuc2hvdyhlcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlcmUgaXMgbm8gc3VpdGFibGUgYXJ2LXZhbGlkYXRpb24tbWVzc2FnZSBlbGVtZW50IHRvIHNob3cgdGhlICcke2Vycm9yLmtleX0nIGAgK1xuICAgICAgICBgZXJyb3Igb2YgJyR7Z2V0Q29udHJvbFBhdGgoZXJyb3IuY29udHJvbCl9J2ApO1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdiAqbmdJZj1cIiFpc1ZhbGlkKClcIj5cbiAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICA8cCAqbmdGb3I9XCJsZXQgbWVzc2FnZSBvZiBnZXRFcnJvck1lc3NhZ2VzKClcIj57e21lc3NhZ2V9fTwvcD5cbiAgPC9kaXY+XG4gIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvZGl2PlxuIl19