ngx-form-lib
Version:
Dynamic form library for Angular 18 with Material 3 support. Create complex reactive forms easily using JSON configuration with modern Angular 18 control flow syntax.
67 lines • 18.1 kB
JavaScript
import { __decorate } from "tslib";
import { Component, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { AutoUnsubscribe } from '../../../shared/decorators/auto-unsubscribe.decorator';
import * as i0 from "@angular/core";
import * as i1 from "../../services/forms.service";
import * as i2 from "../../../core/services/dependencies.service";
import * as i3 from "@angular/common";
import * as i4 from "../../containers/container.component";
import * as i5 from "@angular/forms";
import * as i6 from "../../../shared/pipes/sort-by-order/sort-by-order.pipe";
let FormComponent = class FormComponent {
set config(configObj) {
this._config = configObj;
}
get config() {
return this._config;
}
constructor(formService, dependenciesService, cdr) {
this.formService = formService;
this.dependenciesService = dependenciesService;
this.cdr = cdr;
this._config = {};
this.valueChanges = new EventEmitter();
this.formSubmit = new EventEmitter();
this.form = {};
this.hiddenFields$ = this.dependenciesService.getHiddenFields();
this.destroy$ = new Subject();
this.hiddenFields$ = this.dependenciesService.getHiddenFields();
}
ngAfterContentChecked() {
this.cdr.detectChanges();
}
ngOnInit() {
this.form.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.valueChanges.emit(this.form.value);
});
}
ngOnChanges(changes) {
if (changes['config'].currentValue) {
this.form = this.formService.initForm(changes['config'].currentValue.sections);
}
}
getFormControl(formGroupName, index) {
return this.form.get(`${formGroupName}.${index}`);
}
onSubmit() {
this.formSubmit.emit();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormComponent, deps: [{ token: i1.FormsService }, { token: i2.DependenciesService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FormComponent, selector: "ngx-form-lib", inputs: { config: "config" }, outputs: { valueChanges: "valueChanges", formSubmit: "formSubmit" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ngf-form-container\">\r\n <h3 class=\"ngf-h3 ngf-form-header\">{{ config.header }}</h3>\r\n @if (form) {\r\n <form class=\"ngf-form\" [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\r\n <ng-container formArrayName=\"sections\">\r\n @for (sectionItem of config.sections; track sectionItem; let i = $index) {\r\n <section class=\"ngf-section-wrapper\" [formGroupName]=\"i\">\r\n @if (sectionItem.sectionHeader) {\r\n <h4 class=\"ngf-h4\">{{ sectionItem.sectionHeader }}</h4>\r\n }\r\n <div class=\"ngf-section\">\r\n @for (configItem of sectionItem.fields | sortByOrder; track\r\n configItem.name) {\r\n <div\r\n [hidden]=\"(hiddenFields$ | async)[configItem.name] || false\"\r\n class=\"ngf-field-container\"\r\n [ngClass]=\"configItem.classes\"\r\n >\r\n <ngf-container\r\n [parentConfig]=\"config.parentConfig\"\r\n [config]=\"configItem\"\r\n [group]=\"getFormControl('sections', i)\"\r\n >\r\n </ngf-container>\r\n </div>\r\n }\r\n </div>\r\n </section>\r\n }\r\n </ng-container>\r\n </form>\r\n }\r\n</div>\r\n", styles: [".ngf-col-12{width:100%}.ngf-col-10{width:83.33%}.ngf-col-8{width:66.67%}.ngf-col-6{width:50%}.ngf-col-4{width:33.33%}.ngf-col-3{width:25%}.ngf-col-2{width:16.67%}.ngf-col-1{width:8.33%}.ngf-fit-content{min-width:fit-content}.ngf-h1,.ngf-h2,.ngf-h3,.ngf-h4,.ngf-h5,.ngf-h6{font-weight:500}.ngf-form-field.mat-form-field{width:100%}.ngf-form-field.mat-form-field .mat-mdc-form-field-focus-overlay{background-color:transparent}.ngf-form-field.mat-form-field .mat-mdc-text-field-wrapper{border-radius:8px}.ngf-form-field.mat-form-field .mat-mdc-form-field-subscript-wrapper{font-size:12px}.ngf-field-error{display:flex;justify-content:space-between;font-size:12px;color:var(--mdc-theme-error)}.mat-mdc-form-field .mat-mdc-form-field-focus-overlay{background-color:transparent}.mat-mdc-form-field .mat-mdc-text-field-wrapper{border-radius:8px}.mat-mdc-button,.mat-mdc-raised-button,.mat-mdc-outlined-button,.mat-mdc-unelevated-button{border-radius:20px;font-weight:500;text-transform:none;transition:all .2s ease-in-out}.mat-mdc-select .mat-mdc-select-trigger{border-radius:8px}.mat-mdc-checkbox .mdc-checkbox{border-radius:4px}.mat-mdc-radio-button .mdc-radio .mdc-radio__background{border-radius:50%}.ngf-form-container{color:#4a4a4a;background-color:#f0f0f0;border-radius:12px;box-shadow:0 1px 3px #0000001f,0 1px 2px #0000003d}.ngf-form-container .ngf-form-header{text-transform:uppercase;padding:25px 15px 20px;color:#e6e6e6;background-color:#3f51b5;border-radius:5px 5px 0 0;margin:0}.ngf-form-container .ngf-form{padding:10px}.ngf-form-container .ngf-form .ngf-section-wrapper{background-color:#fff;border-radius:8px}.ngf-form-container .ngf-form .ngf-section-wrapper .ngf-h4{padding:20px 15px;border-bottom:1px solid #e6e6e6}.ngf-form-container .ngf-form .ngf-section-wrapper .ngf-section{width:100%;display:flex;flex-wrap:wrap;margin:10px 0}.ngf-form-container .ngf-form .ngf-section-wrapper .ngf-section .ngf-field-container{padding:10px 15px;box-sizing:border-box}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i4.ContainerComponent, selector: "ngf-container", inputs: ["config", "group", "parentConfig"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i5.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.SortByOrderPipe, name: "sortByOrder" }], encapsulation: i0.ViewEncapsulation.None }); }
};
FormComponent = __decorate([
AutoUnsubscribe()
], FormComponent);
export { FormComponent };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FormComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-form-lib', encapsulation: ViewEncapsulation.None, template: "<div class=\"ngf-form-container\">\r\n <h3 class=\"ngf-h3 ngf-form-header\">{{ config.header }}</h3>\r\n @if (form) {\r\n <form class=\"ngf-form\" [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\r\n <ng-container formArrayName=\"sections\">\r\n @for (sectionItem of config.sections; track sectionItem; let i = $index) {\r\n <section class=\"ngf-section-wrapper\" [formGroupName]=\"i\">\r\n @if (sectionItem.sectionHeader) {\r\n <h4 class=\"ngf-h4\">{{ sectionItem.sectionHeader }}</h4>\r\n }\r\n <div class=\"ngf-section\">\r\n @for (configItem of sectionItem.fields | sortByOrder; track\r\n configItem.name) {\r\n <div\r\n [hidden]=\"(hiddenFields$ | async)[configItem.name] || false\"\r\n class=\"ngf-field-container\"\r\n [ngClass]=\"configItem.classes\"\r\n >\r\n <ngf-container\r\n [parentConfig]=\"config.parentConfig\"\r\n [config]=\"configItem\"\r\n [group]=\"getFormControl('sections', i)\"\r\n >\r\n </ngf-container>\r\n </div>\r\n }\r\n </div>\r\n </section>\r\n }\r\n </ng-container>\r\n </form>\r\n }\r\n</div>\r\n", styles: [".ngf-col-12{width:100%}.ngf-col-10{width:83.33%}.ngf-col-8{width:66.67%}.ngf-col-6{width:50%}.ngf-col-4{width:33.33%}.ngf-col-3{width:25%}.ngf-col-2{width:16.67%}.ngf-col-1{width:8.33%}.ngf-fit-content{min-width:fit-content}.ngf-h1,.ngf-h2,.ngf-h3,.ngf-h4,.ngf-h5,.ngf-h6{font-weight:500}.ngf-form-field.mat-form-field{width:100%}.ngf-form-field.mat-form-field .mat-mdc-form-field-focus-overlay{background-color:transparent}.ngf-form-field.mat-form-field .mat-mdc-text-field-wrapper{border-radius:8px}.ngf-form-field.mat-form-field .mat-mdc-form-field-subscript-wrapper{font-size:12px}.ngf-field-error{display:flex;justify-content:space-between;font-size:12px;color:var(--mdc-theme-error)}.mat-mdc-form-field .mat-mdc-form-field-focus-overlay{background-color:transparent}.mat-mdc-form-field .mat-mdc-text-field-wrapper{border-radius:8px}.mat-mdc-button,.mat-mdc-raised-button,.mat-mdc-outlined-button,.mat-mdc-unelevated-button{border-radius:20px;font-weight:500;text-transform:none;transition:all .2s ease-in-out}.mat-mdc-select .mat-mdc-select-trigger{border-radius:8px}.mat-mdc-checkbox .mdc-checkbox{border-radius:4px}.mat-mdc-radio-button .mdc-radio .mdc-radio__background{border-radius:50%}.ngf-form-container{color:#4a4a4a;background-color:#f0f0f0;border-radius:12px;box-shadow:0 1px 3px #0000001f,0 1px 2px #0000003d}.ngf-form-container .ngf-form-header{text-transform:uppercase;padding:25px 15px 20px;color:#e6e6e6;background-color:#3f51b5;border-radius:5px 5px 0 0;margin:0}.ngf-form-container .ngf-form{padding:10px}.ngf-form-container .ngf-form .ngf-section-wrapper{background-color:#fff;border-radius:8px}.ngf-form-container .ngf-form .ngf-section-wrapper .ngf-h4{padding:20px 15px;border-bottom:1px solid #e6e6e6}.ngf-form-container .ngf-form .ngf-section-wrapper .ngf-section{width:100%;display:flex;flex-wrap:wrap;margin:10px 0}.ngf-form-container .ngf-form .ngf-section-wrapper .ngf-section .ngf-field-container{padding:10px 15px;box-sizing:border-box}\n"] }]
}], ctorParameters: () => [{ type: i1.FormsService }, { type: i2.DependenciesService }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{
type: Input
}], valueChanges: [{
type: Output
}], formSubmit: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZm9ybS1saWIvc3JjL2xpYi9jb3JlL2NvbXBvbmVudHMvZm9ybS9mb3JtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1mb3JtLWxpYi9zcmMvbGliL2NvcmUvY29tcG9uZW50cy9mb3JtL2Zvcm0uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4saUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBYyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBS3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1REFBdUQsQ0FBQzs7Ozs7Ozs7QUFTakYsSUFBTSxhQUFhLEdBQW5CLE1BQU0sYUFBYTtJQUd4QixJQUFhLE1BQU0sQ0FBQyxTQUEwQjtRQUM1QyxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQW1CLENBQUM7SUFDckMsQ0FBQztJQUVELElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBU0QsWUFDbUIsV0FBeUIsRUFDekIsbUJBQXdDLEVBQ3hDLEdBQXNCO1FBRnRCLGdCQUFXLEdBQVgsV0FBVyxDQUFjO1FBQ3pCLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFwQmpDLFlBQU8sR0FBVyxFQUFZLENBQUM7UUFVN0IsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3ZDLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRWhELFNBQUksR0FBcUIsRUFBc0IsQ0FBQztRQUNoRCxrQkFBYSxHQUFvQixJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDM0QsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFPOUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDbEUsQ0FBQztJQUVELHFCQUFxQjtRQUNuQixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ25FLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQ25DLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUN4QyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxjQUFjLENBQUMsYUFBcUIsRUFBRSxLQUFhO1FBQ2pELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxhQUFhLElBQUksS0FBSyxFQUFFLENBQXFCLENBQUM7SUFDeEUsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7K0dBbERVLGFBQWE7bUdBQWIsYUFBYSw0S0N6QjFCLHN1Q0FpQ0E7O0FEUmEsYUFBYTtJQUR6QixlQUFlLEVBQUU7R0FDTCxhQUFhLENBbUR6Qjs7NEZBbkRZLGFBQWE7a0JBUHpCLFNBQVM7K0JBQ0UsY0FBYyxpQkFHVCxpQkFBaUIsQ0FBQyxJQUFJO21KQU14QixNQUFNO3NCQUFsQixLQUFLO2dCQVFJLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFVudHlwZWRGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL21vZGVscy9jb25maWcubW9kZWwnO1xyXG5pbXBvcnQgeyBGb3Jtc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9mb3Jtcy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRGVwZW5kZW5jaWVzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvc2VydmljZXMvZGVwZW5kZW5jaWVzLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBBdXRvVW5zdWJzY3JpYmUgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZGVjb3JhdG9ycy9hdXRvLXVuc3Vic2NyaWJlLmRlY29yYXRvcic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25neC1mb3JtLWxpYicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2Zvcm0uY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2Zvcm0uY29tcG9uZW50LnNjc3MnXSxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG59KVxyXG5AQXV0b1Vuc3Vic2NyaWJlKClcclxuZXhwb3J0IGNsYXNzIEZvcm1Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIHByaXZhdGUgX2NvbmZpZzogQ29uZmlnID0ge30gYXMgQ29uZmlnO1xyXG5cclxuICBASW5wdXQoKSBzZXQgY29uZmlnKGNvbmZpZ09iajogQ29uZmlnIHwgb2JqZWN0KSB7XHJcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWdPYmogYXMgQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGNvbmZpZygpOiBDb25maWcge1xyXG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcclxuICB9XHJcblxyXG4gIEBPdXRwdXQoKSB2YWx1ZUNoYW5nZXMgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgZm9ybVN1Ym1pdCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgZm9ybTogVW50eXBlZEZvcm1Hcm91cCA9IHt9IGFzIFVudHlwZWRGb3JtR3JvdXA7XHJcbiAgaGlkZGVuRmllbGRzJDogT2JzZXJ2YWJsZTxhbnk+ID0gdGhpcy5kZXBlbmRlbmNpZXNTZXJ2aWNlLmdldEhpZGRlbkZpZWxkcygpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZm9ybVNlcnZpY2U6IEZvcm1zU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVwZW5kZW5jaWVzU2VydmljZTogRGVwZW5kZW5jaWVzU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxyXG4gICkge1xyXG4gICAgdGhpcy5oaWRkZW5GaWVsZHMkID0gdGhpcy5kZXBlbmRlbmNpZXNTZXJ2aWNlLmdldEhpZGRlbkZpZWxkcygpO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRDaGVja2VkKCkge1xyXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlcy5lbWl0KHRoaXMuZm9ybS52YWx1ZSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIGlmIChjaGFuZ2VzWydjb25maWcnXS5jdXJyZW50VmFsdWUpIHtcclxuICAgICAgdGhpcy5mb3JtID0gdGhpcy5mb3JtU2VydmljZS5pbml0Rm9ybShcclxuICAgICAgICBjaGFuZ2VzWydjb25maWcnXS5jdXJyZW50VmFsdWUuc2VjdGlvbnNcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldEZvcm1Db250cm9sKGZvcm1Hcm91cE5hbWU6IHN0cmluZywgaW5kZXg6IG51bWJlcik6IFVudHlwZWRGb3JtR3JvdXAge1xyXG4gICAgcmV0dXJuIHRoaXMuZm9ybS5nZXQoYCR7Zm9ybUdyb3VwTmFtZX0uJHtpbmRleH1gKSBhcyBVbnR5cGVkRm9ybUdyb3VwO1xyXG4gIH1cclxuXHJcbiAgb25TdWJtaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmZvcm1TdWJtaXQuZW1pdCgpO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwibmdmLWZvcm0tY29udGFpbmVyXCI+XHJcbiAgPGgzIGNsYXNzPVwibmdmLWgzIG5nZi1mb3JtLWhlYWRlclwiPnt7IGNvbmZpZy5oZWFkZXIgfX08L2gzPlxyXG4gIEBpZiAoZm9ybSkge1xyXG4gIDxmb3JtIGNsYXNzPVwibmdmLWZvcm1cIiBbZm9ybUdyb3VwXT1cImZvcm1cIiAobmdTdWJtaXQpPVwib25TdWJtaXQoKVwiPlxyXG4gICAgPG5nLWNvbnRhaW5lciBmb3JtQXJyYXlOYW1lPVwic2VjdGlvbnNcIj5cclxuICAgICAgQGZvciAoc2VjdGlvbkl0ZW0gb2YgY29uZmlnLnNlY3Rpb25zOyB0cmFjayBzZWN0aW9uSXRlbTsgbGV0IGkgPSAkaW5kZXgpIHtcclxuICAgICAgPHNlY3Rpb24gY2xhc3M9XCJuZ2Ytc2VjdGlvbi13cmFwcGVyXCIgW2Zvcm1Hcm91cE5hbWVdPVwiaVwiPlxyXG4gICAgICAgIEBpZiAoc2VjdGlvbkl0ZW0uc2VjdGlvbkhlYWRlcikge1xyXG4gICAgICAgIDxoNCBjbGFzcz1cIm5nZi1oNFwiPnt7IHNlY3Rpb25JdGVtLnNlY3Rpb25IZWFkZXIgfX08L2g0PlxyXG4gICAgICAgIH1cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibmdmLXNlY3Rpb25cIj5cclxuICAgICAgICAgIEBmb3IgKGNvbmZpZ0l0ZW0gb2Ygc2VjdGlvbkl0ZW0uZmllbGRzIHwgc29ydEJ5T3JkZXI7IHRyYWNrXHJcbiAgICAgICAgICBjb25maWdJdGVtLm5hbWUpIHtcclxuICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgW2hpZGRlbl09XCIoaGlkZGVuRmllbGRzJCB8IGFzeW5jKVtjb25maWdJdGVtLm5hbWVdIHx8IGZhbHNlXCJcclxuICAgICAgICAgICAgY2xhc3M9XCJuZ2YtZmllbGQtY29udGFpbmVyXCJcclxuICAgICAgICAgICAgW25nQ2xhc3NdPVwiY29uZmlnSXRlbS5jbGFzc2VzXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPG5nZi1jb250YWluZXJcclxuICAgICAgICAgICAgICBbcGFyZW50Q29uZmlnXT1cImNvbmZpZy5wYXJlbnRDb25maWdcIlxyXG4gICAgICAgICAgICAgIFtjb25maWddPVwiY29uZmlnSXRlbVwiXHJcbiAgICAgICAgICAgICAgW2dyb3VwXT1cImdldEZvcm1Db250cm9sKCdzZWN0aW9ucycsIGkpXCJcclxuICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICA8L25nZi1jb250YWluZXI+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9zZWN0aW9uPlxyXG4gICAgICB9XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICA8L2Zvcm0+XHJcbiAgfVxyXG48L2Rpdj5cclxuIl19