UNPKG

@bi8/am-dyn-form

Version:

ng update @angular/cli yarn add @angular/cli

121 lines 23.4 kB
import * as tslib_1 from "tslib"; import { Component, OnInit, SkipSelf, Host, Optional, Input, ViewChild, ContentChild, AfterContentInit, AfterViewInit, ContentChildren, ElementRef, QueryList, ViewChildren, Directive, HostBinding } from '@angular/core'; import { ControlContainer, AbstractControl } from '@angular/forms'; import { DynFormGroup } from './dyn-form-group'; import { DynFormArray } from './dyn-form-array'; import { NgSelectComponent } from '@ng-select/ng-select'; import { DynAutoSelectControl } from './dyn-auto-select-control'; //import {LogService, Logger} from "@bi8/am-logger"; /*@Directive({selector: '[class]'}) export class Class { @HostBinding('class') @Input('class') className: string = ''; }*/ let DynFieldComponent = class DynFieldComponent { //@ContentChild('.ng-has-value') stuff; //@ViewChildren(Class, {read: ElementRef}) classes: QueryList<ElementRef>; constructor(controlContainer, elRef) { this.controlContainer = controlContainer; this.elRef = elRef; this.paths = []; this.messages = new Map(); } ngAfterContentInit() { } ngAfterViewInit() { let bling = this.elRef.nativeElement.querySelector('.ng-select-container'); if (bling) { if (this.dfc instanceof DynAutoSelectControl) { this.dfc.element = bling; } } if (this.ngSelect && this.dfc instanceof DynAutoSelectControl) { this.dfc.ngSelectComponent = this.ngSelect; } } /*removeClass(){ if ( this.classes && this.classes.length ) { return this .classes .map((elRef:ElementRef):Element => elRef.nativeElement) .filter( (element: Element) => element.classList.remove('ng-has-value')); } }*/ ngOnInit() { this.dfc = this.controlContainer.control.get(this.name); this.placeholder = this.dfc.config.placeholder; this.hint = this.dfc.config.hint; for (let entry of this.dfc.config.messages) { this.messages.set(entry.key, entry.value); } this.path = this.resolvePath(); } resolvePath() { let paths = [this.dfc.key]; this.resolveParentPath(this.dfc.parent, paths); let resolvedPath = ''; paths.reverse().forEach((path, index) => { if (path) { if (resolvedPath) { resolvedPath += '.'; } resolvedPath += path; this.paths.push(resolvedPath); } }); return resolvedPath; } resolveParentPath(control, paths) { if (control instanceof DynFormGroup) { paths.push(control.key); } else if (control instanceof DynFormArray) { paths.push(control.key); } if (control.parent) { this.resolveParentPath(control.parent, paths); } } resolveValidationMessage(type) { let message = ''; if (this.messages.has(type)) { message = this.messages.get(type); } else if (this.dfc.config.useDefaultErrorMessages) { switch (type) { case 'required': message = 'Value required'; break; case 'pattern': message = 'Invalid format'; break; case 'email': message = 'Invalid email'; break; } } return message; } }; DynFieldComponent.ctorParameters = () => [ { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }, { type: ElementRef } ]; tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], DynFieldComponent.prototype, "name", void 0); tslib_1.__decorate([ ViewChild('ngselect', { static: false }), tslib_1.__metadata("design:type", NgSelectComponent) ], DynFieldComponent.prototype, "ngSelect", void 0); DynFieldComponent = tslib_1.__decorate([ Component({ selector: 'dyn-field', template: "<ng-container [ngSwitch]=\"dfc.type\">\r\n <div fxLayout=\"row\" class=\"am-field-row\">\r\n <!--=====[ AUTO SELECT FIELD ]=====-->\r\n <ng-container *ngSwitchCase=\"'autoselect'\">\r\n <div class=\"am-field-container\" fxLayout=\"row\" fxFlex>\r\n <ng-select #ngselect [items]=\"dfc.items$ | async\"\r\n [formControl]=\"dfc\"\r\n [placeholder]=\"dfc.getCustomPlaceholder()\"\r\n [bindLabel]=\"dfc.bindLabel\"\r\n [typeahead]=\"dfc.typeahead$\"\r\n [loading]=\"dfc.loading\"\r\n [bindValue]=\"dfc.bindValue\"\r\n [multiple]=\"dfc.multiple\"\r\n [searchable]=\"dfc.searchable\"\r\n fxFlex=\"1 1 auto\"\r\n [ngClass]=\"{'am-has-value': dfc.hasValue, 'am-no-value' : !dfc.hasValue}\"\r\n style=\"width: 100px;\">\r\n <ng-template ng-label-tmp let-item=\"item\" *ngIf=\"dfc.labelTemplate\" let-clear=\"clear\">\r\n <ng-container [ngTemplateOutlet]=\"dfc.labelTemplate\" [ngTemplateOutletContext]=\"{item: item, clear: clear}\"></ng-container>\r\n </ng-template>\r\n\r\n <ng-template ng-option-tmp let-item=\"item\" let-index=\"index\" let-search=\"searchTerm\" *ngIf=\"dfc.optionTemplate\">\r\n <ng-container [ngTemplateOutlet]=\"dfc.optionTemplate\" [ngTemplateOutletContext]=\"{item: item, index: index, search: search}\"></ng-container>\r\n </ng-template>\r\n </ng-select>\r\n <span class=\"am-select-error\" *ngIf=\"dfc.hasError('required') && dfc.touched\">{{resolveValidationMessage('required')}}</span>\r\n <span class=\"am-select-error\" *ngIf=\"dfc.hasError('pattern') && dfc.touched\">{{resolveValidationMessage('pattern')}}</span>\r\n <span class=\"am-select-error\" *ngIf=\"dfc.hasError('email') && dfc.touched\">{{resolveValidationMessage('email')}}</span>\r\n <span class=\"am-select-error\" *ngIf=\"dfc.hasError('match') && dfc.touched\">{{resolveValidationMessage('match')}}</span>\r\n <span class=\"am-select-error\" *ngIf=\"dfc.hasError('time') && dfc.touched\">{{resolveValidationMessage('time')}}</span>\r\n <span class=\"am-select-error\" *ngIf=\"dfc.hasError('logical') && dfc.touched\">{{dfc.logicalErrorMessage}}</span>\r\n </div>\r\n </ng-container>\r\n\r\n <!--=====[ TEXT FIELD ]=====-->\r\n <mat-form-field *ngSwitchCase=\"'text'\" [hintLabel]=\"hint\" fxFlex>\r\n <input matInput\r\n hideRequiredMarker=\"false\"\r\n [name]=\"dfc.key\"\r\n [formControl]=\"dfc\"\r\n [type]=\"dfc.config.format\"\r\n [placeholder]=\"placeholder\"\r\n [maxlength]=\"dfc.config.maxlimit\"\r\n [required]=\"dfc.config.required\"\r\n [dir]=\"dfc.config.dir\">\r\n\r\n <mat-hint *ngIf=\"dfc.config.counter && dfc.config.maxlimit\" align=\"end\" class=\"no-text-wrap\">{{dfc.value ? dfc.value.length : 0}} / {{dfc.config.maxlimit}}</mat-hint>\r\n\r\n <mat-error *ngIf=\"dfc.hasError('required')\">{{resolveValidationMessage('required')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('pattern')\">{{resolveValidationMessage('pattern')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('email')\">{{resolveValidationMessage('email')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('match')\">{{resolveValidationMessage('match')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('time')\">{{resolveValidationMessage('time')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('logical')\">{{dfc.logicalErrorMessage}}</mat-error>\r\n </mat-form-field>\r\n\r\n <!--=====[ TEXTAREA FIELD ]=====-->\r\n <mat-form-field *ngSwitchCase=\"'textarea'\" [hintLabel]=\"hint\" fxFlex>\r\n <textarea matInput\r\n hideRequiredMarker=\"false\"\r\n matTextareaAutosize\r\n [matAutosizeMinRows]=\"dfc.config.minRows\"\r\n [matAutosizeMaxRows]=\"dfc.config.maxRows\"\r\n [name]=\"dfc.key\"\r\n [formControl]=\"dfc\"\r\n [placeholder]=\"placeholder\"\r\n [maxlength]=\"dfc.config.maxlimit\"\r\n [required]=\"dfc.config.required\"\r\n [dir]=\"dfc.config.dir\"></textarea>\r\n\r\n <mat-hint *ngIf=\"dfc.config.counter && dfc.config.maxlimit\" align=\"end\" class=\"no-text-wrap\">{{dfc.value ? dfc.value.length : 0}} / {{dfc.config.maxlimit}}</mat-hint>\r\n <mat-error *ngIf=\"dfc.hasError('required')\">{{resolveValidationMessage('required')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('pattern')\">{{resolveValidationMessage('pattern')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('email')\">{{resolveValidationMessage('email')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('match')\">{{resolveValidationMessage('match')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('logical')\">{{dfc.logicalErrorMessage}}</mat-error>\r\n </mat-form-field>\r\n\r\n <!--=====[ AUTOCOMPLETE ]=====-->\r\n <ng-container *ngSwitchCase=\"'auto-complete'\">\r\n <mat-form-field fxFlex>\r\n <input matInput\r\n [name]=\"dfc.key\"\r\n [placeholder]=\"placeholder\"\r\n [matAutocomplete]=\"auto\"\r\n [formControl]=\"dfc\"\r\n [required]=\"dfc.config.required\"\r\n [dir]=\"dfc.config.dir\">\r\n\r\n <mat-error *ngIf=\"dfc.hasError('required')\">{{resolveValidationMessage('required')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('match')\">{{resolveValidationMessage('match')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('logical')\">{{dfc.logicalErrorMessage}}</mat-error>\r\n\r\n <mat-autocomplete #auto=\"matAutocomplete\" [displayWith]=\"dfc.displayFn.bind(dfc)\">\r\n <mat-option *ngFor=\"let opt of dfc.selectOptions$ | async\" [value]=\"opt\">\r\n {{dfc.displayFn(opt)}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n </mat-form-field>\r\n </ng-container>\r\n\r\n <!--=====[ DATE ]=====-->\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n <mat-form-field fxFlex>\r\n <input matInput\r\n hideRequiredMarker=\"false\"\r\n [name]=\"dfc.key\"\r\n [formControl]=\"dfc\"\r\n type=\"text\"\r\n [min]=\"dfc.minDate\"\r\n [max]=\"dfc.maxDate\"\r\n [required]=\"dfc.config.required\"\r\n [matDatepicker]=\"picker\"\r\n [placeholder]=\"placeholder\"\r\n style=\"pointer-events:none;\" />\r\n\r\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\r\n <mat-datepicker #picker></mat-datepicker>\r\n\r\n <mat-error *ngIf=\"dfc.hasError('required')\">{{resolveValidationMessage('required')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('pattern')\">{{resolveValidationMessage('pattern')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('match')\">{{resolveValidationMessage('match')}}</mat-error>\r\n <mat-error *ngIf=\"dfc.hasError('logical')\">{{dfc.logicalErrorMessage}}</mat-error>\r\n </mat-form-field>\r\n </ng-container>\r\n\r\n <!--=====[ DATE ]=====-->\r\n <ng-container *ngSwitchCase=\"'time'\">\r\n <am-timepicker [formControl]=\"dfc\"></am-timepicker>\r\n </ng-container>\r\n\r\n <!--=====[ SELECT FIELD ]=====-->\r\n <ng-container *ngSwitchCase=\"'select'\" >\r\n <mat-form-field fxFlex>\r\n <mat-select [formControl]=\"dfc\"\r\n [placeholder]=\"placeholder\"\r\n [required]=\"dfc.config.required\"\r\n required=\"true\"\r\n [multiple]=\"dfc.multiple\">\r\n <mat-option *ngIf=\"dfc.showNone\" (click)=\"dfc.reset()\">{{dfc.noneLabel}}</mat-option>\r\n <mat-option *ngFor=\"let opt of dfc.selectOptions$ | async\" [value]=\"opt.code\">{{opt.value}}</mat-option>\r\n </mat-select>\r\n <mat-error *ngIf=\"dfc.hasError('required') && dfc.touched\">This option is required</mat-error>\r\n </mat-form-field>\r\n </ng-container>\r\n\r\n <!--=====[ CHECK BOX ]=====-->\r\n <ng-container *ngSwitchCase=\"'checkbox'\">\r\n <mat-checkbox [formControl]=\"dfc\" fxFlex>\r\n {{placeholder}}\r\n </mat-checkbox>\r\n </ng-container>\r\n\r\n <!--=====[ LABEL ]=====-->\r\n <ng-container *ngSwitchCase=\"'label'\">\r\n <div fxFlex>{{placeholder}}</div>\r\n </ng-container>\r\n </div>\r\n</ng-container>\r\n", styles: [""] }), tslib_1.__param(0, Optional()), tslib_1.__param(0, Host()), tslib_1.__param(0, SkipSelf()), tslib_1.__metadata("design:paramtypes", [ControlContainer, ElementRef]) ], DynFieldComponent); export { DynFieldComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluLWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BiaTgvYW0tZHluLWZvcm0vIiwic291cmNlcyI6WyJhcHAvbW9kdWxlcy9hbS1keW4tZm9ybS9keW4tZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULE1BQU0sRUFDTixRQUFRLEVBQ1IsSUFBSSxFQUNKLFFBQVEsRUFDUixLQUFLLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsYUFBYSxFQUNiLGVBQWUsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUM3RSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsZUFBZSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFakUsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxvREFBb0Q7QUFFcEQ7OztHQUdHO0FBT0gsSUFBYSxpQkFBaUIsR0FBOUIsTUFBYSxpQkFBaUI7SUFnQjVCLHVDQUF1QztJQUN2QywwRUFBMEU7SUFFMUUsWUFBbUQsZ0JBQWtDLEVBQVUsS0FBaUI7UUFBN0QscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUFVLFVBQUssR0FBTCxLQUFLLENBQVk7UUFaaEgsVUFBSyxHQUFhLEVBQUUsQ0FBQztRQUlyQixhQUFRLEdBQXdCLElBQUksR0FBRyxFQUFFLENBQUM7SUFTMUMsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksS0FBSyxHQUFHLElBQUks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O2dCQUNaLEtBQUssVUFBVTtvQkFDYixPQUFPLEdBQUcsZ0JBQWdCLENBQUM7b0JBQzNCLE1BQU07Z0JBQ1IsS0FBSyxTQUFTO29CQUNaLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQztvQkFDM0IsTUFBTTtnQkFDUixLQUFLLE9BQU87b0JBQ1YsT0FBTyxHQUFHLGVBQWUsQ0FBQztvQkFDMUIsTUFBTTthQUNUO1NBQ0Y7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0NBQ0YsQ0FBQTs7WUE1RnNFLGdCQUFnQix1QkFBeEUsUUFBUSxZQUFJLElBQUksWUFBSSxRQUFRO1lBQTZELFVBQVU7O0FBakJ2RztJQUFSLEtBQUssRUFBRTs7K0NBQU07QUFZMEI7SUFBdkMsU0FBUyxDQUFDLFVBQVUsRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQztzQ0FBVyxpQkFBaUI7bURBQUM7QUFkekQsaUJBQWlCO0lBTDdCLFNBQVMsQ0FBQztRQUNULFFBQVEsRUFBRSxXQUFXO1FBQ3JCLHNqUkFBeUM7O0tBRTFDLENBQUM7SUFvQmEsbUJBQUEsUUFBUSxFQUFFLENBQUEsRUFBRSxtQkFBQSxJQUFJLEVBQUUsQ0FBQSxFQUFFLG1CQUFBLFFBQVEsRUFBRSxDQUFBOzZDQUEwQixnQkFBZ0IsRUFBaUIsVUFBVTtHQW5CckcsaUJBQWlCLENBK0c3QjtTQS9HWSxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBPbkluaXQsXHJcbiAgU2tpcFNlbGYsXHJcbiAgSG9zdCxcclxuICBPcHRpb25hbCxcclxuICBJbnB1dCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgQ29udGVudENoaWxkLFxyXG4gIEFmdGVyQ29udGVudEluaXQsXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDb250ZW50Q2hpbGRyZW4sIEVsZW1lbnRSZWYsIFF1ZXJ5TGlzdCwgVmlld0NoaWxkcmVuLCBEaXJlY3RpdmUsIEhvc3RCaW5kaW5nXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7Q29udHJvbENvbnRhaW5lciwgQWJzdHJhY3RDb250cm9sfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7RHluRm9ybUNvbnRyb2x9IGZyb20gJy4vZHluLWZvcm0tY29udHJvbCc7XHJcbmltcG9ydCB7RHluRm9ybUdyb3VwfSBmcm9tICcuL2R5bi1mb3JtLWdyb3VwJztcclxuaW1wb3J0IHtEeW5Gb3JtQXJyYXl9IGZyb20gJy4vZHluLWZvcm0tYXJyYXknO1xyXG5pbXBvcnQge05nU2VsZWN0Q29tcG9uZW50fSBmcm9tICdAbmctc2VsZWN0L25nLXNlbGVjdCc7XHJcbmltcG9ydCB7RHluQXV0b1NlbGVjdENvbnRyb2x9IGZyb20gJy4vZHluLWF1dG8tc2VsZWN0LWNvbnRyb2wnO1xyXG4vL2ltcG9ydCB7TG9nU2VydmljZSwgTG9nZ2VyfSBmcm9tIFwiQGJpOC9hbS1sb2dnZXJcIjtcclxuXHJcbi8qQERpcmVjdGl2ZSh7c2VsZWN0b3I6ICdbY2xhc3NdJ30pXHJcbmV4cG9ydCBjbGFzcyBDbGFzcyAge1xyXG4gIEBIb3N0QmluZGluZygnY2xhc3MnKSBASW5wdXQoJ2NsYXNzJykgY2xhc3NOYW1lOiBzdHJpbmcgPSAnJztcclxufSovXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2R5bi1maWVsZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2R5bi1maWVsZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZHluLWZpZWxkLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIER5bkZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0IHtcclxuXHJcbiAgQElucHV0KCkgbmFtZTtcclxuXHJcbiAgLy9sb2dnZXI6IExvZ2dlcjtcclxuICBkZmM6IGFueTtcclxuICBwYXRoOiBzdHJpbmc7XHJcbiAgcGF0aHM6IHN0cmluZ1tdID0gW107XHJcblxyXG4gIHBsYWNlaG9sZGVyOiBzdHJpbmc7XHJcbiAgaGludDogc3RyaW5nO1xyXG4gIG1lc3NhZ2VzOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xyXG5cclxuICAvL0BDb250ZW50Q2hpbGQoJ25nU2VsZWN0JykgbmdTZWxlY3Q6IE5nU2VsZWN0Q29tcG9uZW50O1xyXG4gIEBWaWV3Q2hpbGQoJ25nc2VsZWN0Jywge3N0YXRpYzogZmFsc2V9KSBuZ1NlbGVjdDogTmdTZWxlY3RDb21wb25lbnQ7XHJcblxyXG4gIC8vQENvbnRlbnRDaGlsZCgnLm5nLWhhcy12YWx1ZScpIHN0dWZmO1xyXG4gIC8vQFZpZXdDaGlsZHJlbihDbGFzcywge3JlYWQ6IEVsZW1lbnRSZWZ9KSBjbGFzc2VzOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XHJcblxyXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBIb3N0KCkgQFNraXBTZWxmKCkgcHVibGljIGNvbnRyb2xDb250YWluZXI6IENvbnRyb2xDb250YWluZXIsIHByaXZhdGUgZWxSZWY6IEVsZW1lbnRSZWYpIHtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIGxldCBibGluZyA9IHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcubmctc2VsZWN0LWNvbnRhaW5lcicpO1xyXG4gICAgaWYgKGJsaW5nKSB7XHJcbiAgICAgIGlmICh0aGlzLmRmYyBpbnN0YW5jZW9mIER5bkF1dG9TZWxlY3RDb250cm9sKSB7XHJcbiAgICAgICAgKHRoaXMuZGZjIGFzIER5bkF1dG9TZWxlY3RDb250cm9sKS5lbGVtZW50ID0gYmxpbmc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5uZ1NlbGVjdCAmJiB0aGlzLmRmYyBpbnN0YW5jZW9mIER5bkF1dG9TZWxlY3RDb250cm9sKSB7XHJcbiAgICAgICh0aGlzLmRmYyBhcyBEeW5BdXRvU2VsZWN0Q29udHJvbCkubmdTZWxlY3RDb21wb25lbnQgPSB0aGlzLm5nU2VsZWN0O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLypyZW1vdmVDbGFzcygpe1xyXG4gICAgaWYgKCB0aGlzLmNsYXNzZXMgJiYgdGhpcy5jbGFzc2VzLmxlbmd0aCApIHtcclxuICAgICAgcmV0dXJuIHRoaXNcclxuICAgICAgICAuY2xhc3Nlc1xyXG4gICAgICAgIC5tYXAoKGVsUmVmOkVsZW1lbnRSZWYpOkVsZW1lbnQgPT4gZWxSZWYubmF0aXZlRWxlbWVudClcclxuICAgICAgICAuZmlsdGVyKCAoZWxlbWVudDogRWxlbWVudCkgPT4gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCduZy1oYXMtdmFsdWUnKSk7XHJcbiAgICB9XHJcbiAgfSovXHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5kZmMgPSA8RHluRm9ybUNvbnRyb2w+dGhpcy5jb250cm9sQ29udGFpbmVyLmNvbnRyb2wuZ2V0KHRoaXMubmFtZSk7XHJcbiAgICB0aGlzLnBsYWNlaG9sZGVyID0gdGhpcy5kZmMuY29uZmlnLnBsYWNlaG9sZGVyO1xyXG4gICAgdGhpcy5oaW50ID0gdGhpcy5kZmMuY29uZmlnLmhpbnQ7XHJcblxyXG4gICAgZm9yIChsZXQgZW50cnkgb2YgdGhpcy5kZmMuY29uZmlnLm1lc3NhZ2VzKSB7XHJcbiAgICAgIHRoaXMubWVzc2FnZXMuc2V0KGVudHJ5LmtleSwgZW50cnkudmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVzb2x2ZVBhdGgoKTogc3RyaW5nIHtcclxuICAgIGxldCBwYXRoczogc3RyaW5nW10gPSBbdGhpcy5kZmMua2V5XTtcclxuICAgIHRoaXMucmVzb2x2ZVBhcmVudFBhdGgodGhpcy5kZmMucGFyZW50LCBwYXRocyk7XHJcblxyXG4gICAgbGV0IHJlc29sdmVkUGF0aCA9ICcnO1xyXG5cclxuICAgIHBhdGhzLnJldmVyc2UoKS5mb3JFYWNoKChwYXRoLCBpbmRleCkgPT4ge1xyXG4gICAgICBpZiAocGF0aCkge1xyXG4gICAgICAgIGlmIChyZXNvbHZlZFBhdGgpIHtcclxuICAgICAgICAgIHJlc29sdmVkUGF0aCArPSAnLic7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc29sdmVkUGF0aCArPSBwYXRoO1xyXG4gICAgICAgIHRoaXMucGF0aHMucHVzaChyZXNvbHZlZFBhdGgpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNvbHZlUGFyZW50UGF0aChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIHBhdGhzOiBzdHJpbmdbXSkge1xyXG4gICAgaWYgKGNvbnRyb2wgaW5zdGFuY2VvZiBEeW5Gb3JtR3JvdXApIHtcclxuICAgICAgcGF0aHMucHVzaCgoY29udHJvbCBhcyBEeW5Gb3JtR3JvdXApLmtleSk7XHJcblxyXG4gICAgfSBlbHNlIGlmIChjb250cm9sIGluc3RhbmNlb2YgRHluRm9ybUFycmF5KSB7XHJcbiAgICAgIHBhdGhzLnB1c2goKGNvbnRyb2wgYXMgRHluRm9ybUFycmF5KS5rZXkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjb250cm9sLnBhcmVudCkge1xyXG4gICAgICB0aGlzLnJlc29sdmVQYXJlbnRQYXRoKGNvbnRyb2wucGFyZW50LCBwYXRocyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXNvbHZlVmFsaWRhdGlvbk1lc3NhZ2UodHlwZTogc3RyaW5nKSB7XHJcbiAgICBsZXQgbWVzc2FnZSA9ICcnO1xyXG4gICAgaWYgKHRoaXMubWVzc2FnZXMuaGFzKHR5cGUpKSB7XHJcbiAgICAgIG1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VzLmdldCh0eXBlKVxyXG5cclxuICAgIH0gZWxzZSBpZiAodGhpcy5kZmMuY29uZmlnLnVzZURlZmF1bHRFcnJvck1lc3NhZ2VzKSB7XHJcbiAgICAgIHN3aXRjaCAodHlwZSkge1xyXG4gICAgICAgIGNhc2UgJ3JlcXVpcmVkJzpcclxuICAgICAgICAgIG1lc3NhZ2UgPSAnVmFsdWUgcmVxdWlyZWQnO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSAncGF0dGVybic6XHJcbiAgICAgICAgICBtZXNzYWdlID0gJ0ludmFsaWQgZm9ybWF0JztcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgJ2VtYWlsJzpcclxuICAgICAgICAgIG1lc3NhZ2UgPSAnSW52YWxpZCBlbWFpbCc7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG1lc3NhZ2U7XHJcbiAgfVxyXG59XHJcbiJdfQ==