UNPKG

@doku-dev/doku-fragment

Version:

A new Angular UI library that moving away from Bootstrap and built from scratch.

252 lines 35.1 kB
import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, HostBinding, Input, ViewChild, ViewEncapsulation, } from '@angular/core'; import { ReplaySubject, filter, fromEvent, takeUntil } from 'rxjs'; import { DokuFieldError } from './field-helpers/field-error.component'; import { DokuFieldHint } from './field-helpers/field-hint.component'; import { DokuFieldSuccess } from './field-helpers/field-success.component'; import { DOKU_FORM_FIELD_ACCESSOR } from './token'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class DokuFormField { get shouldShowFieldHelper() { if (this.hasFieldSuccess && this.showSuccessBehavior && this.isSuccess) return this.isSuccess; if (this.hasFieldError && this.isError) return this.isError; if (this.hasFieldHint) return true; return false; } get isError() { return this._isError; } set isError(value) { this._isError = value; this.cdRef.markForCheck(); } get isSuccess() { return this._isSuccess; } set isSuccess(value) { this._isSuccess = value; this.cdRef.markForCheck(); } set isFocus(value) { this._isFocus = this.isDisabled || this.isReadonly ? false : value; } get isFocus() { return this._isFocus; } constructor(cdRef) { this.cdRef = cdRef; /** * Whether to show the success behavior when the validation is valid. * @default false */ this.showSuccessBehavior = false; this.classes = 'd-form-field'; this.hasFieldHint = false; this.hasFieldError = false; this.hasFieldSuccess = false; this._isError = false; this._isSuccess = false; this._isFocus = false; this.isDisabled = false; this.isReadonly = false; this.isTextarea = false; this.destroy$ = new ReplaySubject(); } get inputWrapperElement() { return this.inputWrapperElementRef?.nativeElement; } ngOnChanges(changes) { if (changes['isErrorState']) { this.useCustomErrorStateMatcher(changes['isErrorState'].currentValue); } if (changes['isSuccessState']) { this.useCustomSuccessStateMatcher(changes['isSuccessState'].currentValue); } } ngAfterContentInit() { this.hasFieldHint = !!this.fieldHint?.length; this.hasFieldError = !!this.fieldError?.length; this.hasFieldSuccess = !!this.fieldSuccess?.length; this.handleFormFieldOptions(); this.handleRegisterOnFocus(); this.handleRegisterOnBlur(); this.handleRegisterOnDisable(); this.handleRegisterOnReadonly(); this.handleRegisterOnValidate(); this.handleTextarea(); } ngAfterViewInit() { this.handleOnClickWrapperElement(); } ngOnDestroy() { this.destroy$.next(1); this.destroy$.complete(); } handleFormFieldOptions() { if (!this.formFieldAccessor?.fieldOptions) return; this.fieldOptions = this.formFieldAccessor.fieldOptions; } handleRegisterOnFocus() { if (!this.formFieldAccessor) return; const focusHandler = () => { this.isFocus = true; this.cdRef.markForCheck(); }; this.formFieldAccessor.registerOnFocus?.(focusHandler); } handleRegisterOnBlur() { if (!this.formFieldAccessor) return; const blurHandler = () => { this.isFocus = false; this.cdRef.markForCheck(); }; this.formFieldAccessor.registerOnBlur?.(blurHandler); } handleRegisterOnDisable() { if (!this.formFieldAccessor) return; const disableHandler = (value) => { this.isDisabled = value; this.cdRef.markForCheck(); }; this.formFieldAccessor.registerOnDisable?.(disableHandler); } handleRegisterOnReadonly() { if (!this.formFieldAccessor) return; const readonlyHandler = (value) => { this.isReadonly = value; this.cdRef.markForCheck(); }; this.formFieldAccessor.registerOnReadonly?.(readonlyHandler); } handleRegisterOnValidate() { if (!this.formFieldAccessor) return; const validationHandler = (value, state) => { if (typeof this.isErrorState === 'boolean') return; if (typeof this.isSuccessState === 'boolean') return; const isControlReset = state?.pristine && state.untouched; if (isControlReset) { this.isError = false; this.isSuccess = false; } else if (value === 'valid') { this.isError = false; this.isSuccess = true; } else if (value === 'invalid') { this.isError = true; this.isSuccess = false; } else { this.isError = false; this.isSuccess = false; } }; this.formFieldAccessor.registerOnValidate?.(validationHandler); } handleOnClickWrapperElement() { if (!this.formFieldAccessor) return; fromEvent(this.inputWrapperElement, 'click') .pipe(filter((ev) => !this.isElementPrefixOrSuffixClicked(ev.target)), takeUntil(this.destroy$)) .subscribe((e) => { this.formFieldAccessor?.onClickWrapperElement?.(e); }); } handleTextarea() { if (!this.formFieldAccessor) return; const isTextarea = this.formFieldAccessor.elementRef?.nativeElement?.nodeName?.toLowerCase() === 'textarea'; if (!isTextarea) return; this.isTextarea = true; } isElementPrefixOrSuffixClicked(srcElement) { const prefixElement = this.inputWrapperElement.querySelector('[doku-field-prefix]'); const suffixElement = this.inputWrapperElement.querySelector('[doku-field-suffix]'); let clicked = false; if (prefixElement) clicked = this.checkElementChildren(srcElement, prefixElement); if (clicked) return clicked; if (suffixElement) clicked = this.checkElementChildren(srcElement, suffixElement); return clicked; } checkElementChildren(clickedElement, checkElement) { if (!clickedElement || !checkElement) return false; if (clickedElement === checkElement) return true; if (!checkElement.hasChildNodes()) return false; return Array.from(checkElement.children).some((child) => this.checkElementChildren(clickedElement, child)); } useCustomErrorStateMatcher(value) { this.isError = value; } useCustomSuccessStateMatcher(value) { this.isSuccess = value; } } DokuFormField.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DokuFormField, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); DokuFormField.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: DokuFormField, isStandalone: true, selector: "doku-form-field", inputs: { showSuccessBehavior: "showSuccessBehavior", isErrorState: "isErrorState", isSuccessState: "isSuccessState" }, host: { properties: { "class.d-field-show-success": "this.showSuccessBehavior", "class": "this.classes", "class.d-form-field-error": "this.isError", "class.d-form-field-success": "this.isSuccess", "class.d-field-disabled": "this.isDisabled", "class.d-field-readonly": "this.isReadonly", "class.d-field-textarea": "this.isTextarea" } }, queries: [{ propertyName: "formFieldAccessor", first: true, predicate: DOKU_FORM_FIELD_ACCESSOR, descendants: true }, { propertyName: "fieldHint", predicate: DokuFieldHint }, { propertyName: "fieldError", predicate: DokuFieldError }, { propertyName: "fieldSuccess", predicate: DokuFieldSuccess }], viewQueries: [{ propertyName: "inputWrapperElementRef", first: true, predicate: ["inputWrapper"], descendants: true }], exportAs: ["dokuFormField"], usesOnChanges: true, ngImport: i0, template: "<ng-content select=\"doku-field-label\"></ng-content>\n\n<div\n #inputWrapper\n class=\"d-field-input-wrapper\"\n [class.d-field-focus]=\"isFocus\"\n [class.no-style]=\"fieldOptions?.withoutInputStyle\"\n>\n <ng-content select=\"[doku-field-prefix]\"></ng-content>\n <ng-content></ng-content>\n <ng-content select=\"[doku-field-suffix]\"></ng-content>\n</div>\n\n<div *ngIf=\"shouldShowFieldHelper\" class=\"d-field-helper-text d-text-body-s\">\n <ng-container *ngIf=\"hasFieldHint && !isError && (!isSuccess || !showSuccessBehavior)\">\n <ng-content select=\"doku-field-hint\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"hasFieldError && isError\">\n <ng-content select=\"doku-field-error\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"hasFieldSuccess && isSuccess && showSuccessBehavior\">\n <ng-content select=\"doku-field-success\"></ng-content>\n </ng-container>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DokuFormField, decorators: [{ type: Component, args: [{ selector: 'doku-form-field', exportAs: 'dokuFormField', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content select=\"doku-field-label\"></ng-content>\n\n<div\n #inputWrapper\n class=\"d-field-input-wrapper\"\n [class.d-field-focus]=\"isFocus\"\n [class.no-style]=\"fieldOptions?.withoutInputStyle\"\n>\n <ng-content select=\"[doku-field-prefix]\"></ng-content>\n <ng-content></ng-content>\n <ng-content select=\"[doku-field-suffix]\"></ng-content>\n</div>\n\n<div *ngIf=\"shouldShowFieldHelper\" class=\"d-field-helper-text d-text-body-s\">\n <ng-container *ngIf=\"hasFieldHint && !isError && (!isSuccess || !showSuccessBehavior)\">\n <ng-content select=\"doku-field-hint\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"hasFieldError && isError\">\n <ng-content select=\"doku-field-error\"></ng-content>\n </ng-container>\n <ng-container *ngIf=\"hasFieldSuccess && isSuccess && showSuccessBehavior\">\n <ng-content select=\"doku-field-success\"></ng-content>\n </ng-container>\n</div>\n" }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { showSuccessBehavior: [{ type: HostBinding, args: ['class.d-field-show-success'] }, { type: Input }], isErrorState: [{ type: Input }], isSuccessState: [{ type: Input }], classes: [{ type: HostBinding, args: ['class'] }], isError: [{ type: HostBinding, args: ['class.d-form-field-error'] }], isSuccess: [{ type: HostBinding, args: ['class.d-form-field-success'] }], isDisabled: [{ type: HostBinding, args: ['class.d-field-disabled'] }], isReadonly: [{ type: HostBinding, args: ['class.d-field-readonly'] }], isTextarea: [{ type: HostBinding, args: ['class.d-field-textarea'] }], formFieldAccessor: [{ type: ContentChild, args: [DOKU_FORM_FIELD_ACCESSOR] }], fieldHint: [{ type: ContentChildren, args: [DokuFieldHint, { descendants: false }] }], fieldError: [{ type: ContentChildren, args: [DokuFieldError, { descendants: false }] }], fieldSuccess: [{ type: ContentChildren, args: [DokuFieldSuccess, { descendants: false }] }], inputWrapperElementRef: [{ type: ViewChild, args: ['inputWrapper'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kb2t1LWZyYWdtZW50L3NyYy9saWIvZm9ybS1maWVsZC9mb3JtLWZpZWxkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rva3UtZnJhZ21lbnQvc3JjL2xpYi9mb3JtLWZpZWxkL2Zvcm0tZmllbGQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFHTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBRWYsV0FBVyxFQUNYLEtBQUssRUFLTCxTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNyRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQU8zRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxTQUFTLENBQUM7OztBQVduRCxNQUFNLE9BQU8sYUFBYTtJQTRCeEIsSUFBYyxxQkFBcUI7UUFDakMsSUFBSSxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM5RixJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDNUQsSUFBSSxJQUFJLENBQUMsWUFBWTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ25DLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELElBQ2MsT0FBTztRQUNuQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUNELElBQWMsT0FBTyxDQUFDLEtBQWM7UUFDbEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBR0QsSUFDYyxTQUFTO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBQ0QsSUFBYyxTQUFTLENBQUMsS0FBYztRQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFJRCxJQUFjLE9BQU8sQ0FBQyxLQUFjO1FBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUNyRSxDQUFDO0lBQ0QsSUFBYyxPQUFPO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBd0JELFlBQW9CLEtBQXdCO1FBQXhCLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBcEY1Qzs7O1dBR0c7UUFHSCx3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFjVCxZQUFPLEdBQUcsY0FBYyxDQUFDO1FBSWxDLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBZ0IxQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBVWpCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFbkIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQVNmLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFHbkIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUduQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBYXJCLGFBQVEsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDO0lBRVEsQ0FBQztJQUVoRCxJQUFjLG1CQUFtQjtRQUMvQixPQUFPLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxhQUFhLENBQUM7SUFDcEQsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsMEJBQTBCLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3ZFO1FBQ0QsSUFBSSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtZQUM3QixJQUFJLENBQUMsNEJBQTRCLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDM0U7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDO1FBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDO1FBQy9DLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDO1FBRW5ELElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO0lBQ3JDLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8sc0JBQXNCO1FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsWUFBWTtZQUFFLE9BQU87UUFDbEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDO0lBQzFELENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUI7WUFBRSxPQUFPO1FBQ3BDLE1BQU0sWUFBWSxHQUFHLEdBQUcsRUFBRTtZQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzVCLENBQUMsQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCO1lBQUUsT0FBTztRQUNwQyxNQUFNLFdBQVcsR0FBRyxHQUFHLEVBQUU7WUFDdkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM1QixDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLENBQUMsY0FBYyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVPLHVCQUF1QjtRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtZQUFFLE9BQU87UUFDcEMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFjLEVBQUUsRUFBRTtZQUN4QyxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzVCLENBQUMsQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFTyx3QkFBd0I7UUFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUI7WUFBRSxPQUFPO1FBQ3BDLE1BQU0sZUFBZSxHQUFHLENBQUMsS0FBYyxFQUFFLEVBQUU7WUFDekMsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7WUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM1QixDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsaUJBQWlCLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRU8sd0JBQXdCO1FBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCO1lBQUUsT0FBTztRQUNwQyxNQUFNLGlCQUFpQixHQUFHLENBQ3hCLEtBQTBDLEVBQzFDLEtBQTBDLEVBQzFDLEVBQUU7WUFDRixJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksS0FBSyxTQUFTO2dCQUFFLE9BQU87WUFDbkQsSUFBSSxPQUFPLElBQUksQ0FBQyxjQUFjLEtBQUssU0FBUztnQkFBRSxPQUFPO1lBRXJELE1BQU0sY0FBYyxHQUFHLEtBQUssRUFBRSxRQUFRLElBQUksS0FBSyxDQUFDLFNBQVMsQ0FBQztZQUUxRCxJQUFJLGNBQWMsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2FBQ3hCO2lCQUFNLElBQUksS0FBSyxLQUFLLE9BQU8sRUFBRTtnQkFDNUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2FBQ3ZCO2lCQUFNLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtnQkFDOUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2FBQ3hCO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO2dCQUNyQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQzthQUN4QjtRQUNILENBQUMsQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVPLDJCQUEyQjtRQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtZQUFFLE9BQU87UUFDcEMsU0FBUyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxPQUFPLENBQUM7YUFDekMsSUFBSSxDQUNILE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsRUFBRSxDQUFDLE1BQXFCLENBQUMsQ0FBQyxFQUM5RSxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUN6QjthQUNBLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ2YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sY0FBYztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtZQUFFLE9BQU87UUFDcEMsTUFBTSxVQUFVLEdBQ2IsSUFBSSxDQUFDLGlCQUF5QixDQUFDLFVBQVUsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRTtZQUNsRixVQUFVLENBQUM7UUFDYixJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVPLDhCQUE4QixDQUFDLFVBQXVCO1FBQzVELE1BQU0sYUFBYSxHQUNqQixJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDaEUsTUFBTSxhQUFhLEdBQ2pCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUVoRSxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFFcEIsSUFBSSxhQUFhO1lBQUUsT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDbEYsSUFBSSxPQUFPO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFDNUIsSUFBSSxhQUFhO1lBQUUsT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDbEYsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVPLG9CQUFvQixDQUFDLGNBQTJCLEVBQUUsWUFBMEI7UUFDbEYsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLFlBQVk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNuRCxJQUFJLGNBQWMsS0FBSyxZQUFZO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDakQsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUU7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNoRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQ3RELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxjQUFjLEVBQUUsS0FBb0IsQ0FBQyxDQUNoRSxDQUFDO0lBQ0osQ0FBQztJQUVPLDBCQUEwQixDQUFDLEtBQWM7UUFDL0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDdkIsQ0FBQztJQUVPLDRCQUE0QixDQUFDLEtBQWM7UUFDakQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDekIsQ0FBQzs7MEdBbFBVLGFBQWE7OEZBQWIsYUFBYSxra0JBd0VWLHdCQUF3QiwrREFFckIsYUFBYSw2Q0FFYixjQUFjLCtDQUVkLGdCQUFnQix1TUN0SG5DLDQ1QkF3QkEsMkNEV1ksWUFBWTsyRkFLWCxhQUFhO2tCQVR6QixTQUFTOytCQUNFLGlCQUFpQixZQUNqQixlQUFlLGNBQ2IsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLGlCQUVSLGlCQUFpQixDQUFDLElBQUksbUJBQ3BCLHVCQUF1QixDQUFDLE1BQU07d0dBUy9DLG1CQUFtQjtzQkFGbEIsV0FBVzt1QkFBQyw0QkFBNEI7O3NCQUN4QyxLQUFLO2dCQU9HLFlBQVk7c0JBQXBCLEtBQUs7Z0JBS0csY0FBYztzQkFBdEIsS0FBSztnQkFHYSxPQUFPO3NCQUR6QixXQUFXO3VCQUFDLE9BQU87Z0JBZ0JOLE9BQU87c0JBRHBCLFdBQVc7dUJBQUMsMEJBQTBCO2dCQVd6QixTQUFTO3NCQUR0QixXQUFXO3VCQUFDLDRCQUE0QjtnQkFtQi9CLFVBQVU7c0JBRG5CLFdBQVc7dUJBQUMsd0JBQXdCO2dCQUkzQixVQUFVO3NCQURuQixXQUFXO3VCQUFDLHdCQUF3QjtnQkFJM0IsVUFBVTtzQkFEbkIsV0FBVzt1QkFBQyx3QkFBd0I7Z0JBR1csaUJBQWlCO3NCQUFoRSxZQUFZO3VCQUFDLHdCQUF3QjtnQkFHOUIsU0FBUztzQkFEaEIsZUFBZTt1QkFBQyxhQUFhLEVBQUUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFO2dCQUc5QyxVQUFVO3NCQURqQixlQUFlO3VCQUFDLGNBQWMsRUFBRSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUU7Z0JBRy9DLFlBQVk7c0JBRG5CLGVBQWU7dUJBQUMsZ0JBQWdCLEVBQUUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFO2dCQUd0QixzQkFBc0I7c0JBQXhELFNBQVM7dUJBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIFF1ZXJ5TGlzdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0LCBmaWx0ZXIsIGZyb21FdmVudCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBEb2t1RmllbGRFcnJvciB9IGZyb20gJy4vZmllbGQtaGVscGVycy9maWVsZC1lcnJvci5jb21wb25lbnQnO1xuaW1wb3J0IHsgRG9rdUZpZWxkSGludCB9IGZyb20gJy4vZmllbGQtaGVscGVycy9maWVsZC1oaW50LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEb2t1RmllbGRTdWNjZXNzIH0gZnJvbSAnLi9maWVsZC1oZWxwZXJzL2ZpZWxkLXN1Y2Nlc3MuY29tcG9uZW50JztcbmltcG9ydCB7XG4gIERva3VGb3JtRmllbGRBY2Nlc3NvcixcbiAgRG9rdUZvcm1GaWVsZEFjY2Vzc29yVmFsaWRhdGVTdGF0ZSxcbiAgRG9rdUZvcm1GaWVsZEFjY2Vzc29yVmFsaWRhdGVWYWx1ZSxcbiAgRG9rdUZvcm1GaWVsZE9wdGlvbnMsXG59IGZyb20gJy4vZm9ybS1maWVsZC1hY2Nlc3Nvcic7XG5pbXBvcnQgeyBET0tVX0ZPUk1fRklFTERfQUNDRVNTT1IgfSBmcm9tICcuL3Rva2VuJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZG9rdS1mb3JtLWZpZWxkJyxcbiAgZXhwb3J0QXM6ICdkb2t1Rm9ybUZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9mb3JtLWZpZWxkLmNvbXBvbmVudC5odG1sJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIERva3VGb3JtRmllbGQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNob3cgdGhlIHN1Y2Nlc3MgYmVoYXZpb3Igd2hlbiB0aGUgdmFsaWRhdGlvbiBpcyB2YWxpZC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIEBIb3N0QmluZGluZygnY2xhc3MuZC1maWVsZC1zaG93LXN1Y2Nlc3MnKVxuICBASW5wdXQoKVxuICBzaG93U3VjY2Vzc0JlaGF2aW9yID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIGJ1aWx0LWluIGVycm9yIHN0YXRlIGhhbmRsZXIuXG4gICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgKi9cbiAgQElucHV0KCkgaXNFcnJvclN0YXRlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogT3ZlcnJpZGUgYnVpbHQtaW4gc3VjY2VzcyBzdGF0ZSBoYW5kbGVyLlxuICAgKi9cbiAgQElucHV0KCkgaXNTdWNjZXNzU3RhdGU/OiBib29sZWFuO1xuXG4gIEBIb3N0QmluZGluZygnY2xhc3MnKVxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2xhc3NlcyA9ICdkLWZvcm0tZmllbGQnO1xuXG4gIHByb3RlY3RlZCBmaWVsZE9wdGlvbnM/OiBEb2t1Rm9ybUZpZWxkT3B0aW9ucztcblxuICBwcm90ZWN0ZWQgaGFzRmllbGRIaW50ID0gZmFsc2U7XG4gIHByb3RlY3RlZCBoYXNGaWVsZEVycm9yID0gZmFsc2U7XG4gIHByb3RlY3RlZCBoYXNGaWVsZFN1Y2Nlc3MgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGdldCBzaG91bGRTaG93RmllbGRIZWxwZXIoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuaGFzRmllbGRTdWNjZXNzICYmIHRoaXMuc2hvd1N1Y2Nlc3NCZWhhdmlvciAmJiB0aGlzLmlzU3VjY2VzcykgcmV0dXJuIHRoaXMuaXNTdWNjZXNzO1xuICAgIGlmICh0aGlzLmhhc0ZpZWxkRXJyb3IgJiYgdGhpcy5pc0Vycm9yKSByZXR1cm4gdGhpcy5pc0Vycm9yO1xuICAgIGlmICh0aGlzLmhhc0ZpZWxkSGludCkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5kLWZvcm0tZmllbGQtZXJyb3InKVxuICBwcm90ZWN0ZWQgZ2V0IGlzRXJyb3IoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2lzRXJyb3I7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCBpc0Vycm9yKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faXNFcnJvciA9IHZhbHVlO1xuICAgIHRoaXMuY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cbiAgcHJpdmF0ZSBfaXNFcnJvciA9IGZhbHNlO1xuXG4gIEBIb3N0QmluZGluZygnY2xhc3MuZC1mb3JtLWZpZWxkLXN1Y2Nlc3MnKVxuICBwcm90ZWN0ZWQgZ2V0IGlzU3VjY2VzcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faXNTdWNjZXNzO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgaXNTdWNjZXNzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faXNTdWNjZXNzID0gdmFsdWU7XG4gICAgdGhpcy5jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuICBwcml2YXRlIF9pc1N1Y2Nlc3MgPSBmYWxzZTtcblxuICBwcml2YXRlIF9pc0ZvY3VzID0gZmFsc2U7XG4gIHByb3RlY3RlZCBzZXQgaXNGb2N1cyh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2lzRm9jdXMgPSB0aGlzLmlzRGlzYWJsZWQgfHwgdGhpcy5pc1JlYWRvbmx5ID8gZmFsc2UgOiB2YWx1ZTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0IGlzRm9jdXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2lzRm9jdXM7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmQtZmllbGQtZGlzYWJsZWQnKVxuICBwcm90ZWN0ZWQgaXNEaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBIb3N0QmluZGluZygnY2xhc3MuZC1maWVsZC1yZWFkb25seScpXG4gIHByb3RlY3RlZCBpc1JlYWRvbmx5ID0gZmFsc2U7XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5kLWZpZWxkLXRleHRhcmVhJylcbiAgcHJvdGVjdGVkIGlzVGV4dGFyZWEgPSBmYWxzZTtcblxuICBAQ29udGVudENoaWxkKERPS1VfRk9STV9GSUVMRF9BQ0NFU1NPUikgcHJpdmF0ZSBmb3JtRmllbGRBY2Nlc3Nvcj86IERva3VGb3JtRmllbGRBY2Nlc3NvcjtcblxuICBAQ29udGVudENoaWxkcmVuKERva3VGaWVsZEhpbnQsIHsgZGVzY2VuZGFudHM6IGZhbHNlIH0pXG4gIHByaXZhdGUgZmllbGRIaW50PzogUXVlcnlMaXN0PERva3VGaWVsZEhpbnQ+O1xuICBAQ29udGVudENoaWxkcmVuKERva3VGaWVsZEVycm9yLCB7IGRlc2NlbmRhbnRzOiBmYWxzZSB9KVxuICBwcml2YXRlIGZpZWxkRXJyb3I/OiBRdWVyeUxpc3Q8RG9rdUZpZWxkRXJyb3I+O1xuICBAQ29udGVudENoaWxkcmVuKERva3VGaWVsZFN1Y2Nlc3MsIHsgZGVzY2VuZGFudHM6IGZhbHNlIH0pXG4gIHByaXZhdGUgZmllbGRTdWNjZXNzPzogUXVlcnlMaXN0PERva3VGaWVsZFN1Y2Nlc3M+O1xuXG4gIEBWaWV3Q2hpbGQoJ2lucHV0V3JhcHBlcicpIHByaXZhdGUgaW5wdXRXcmFwcGVyRWxlbWVudFJlZj86IEVsZW1lbnRSZWY7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBSZXBsYXlTdWJqZWN0KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgcHJvdGVjdGVkIGdldCBpbnB1dFdyYXBwZXJFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5pbnB1dFdyYXBwZXJFbGVtZW50UmVmPy5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydpc0Vycm9yU3RhdGUnXSkge1xuICAgICAgdGhpcy51c2VDdXN0b21FcnJvclN0YXRlTWF0Y2hlcihjaGFuZ2VzWydpc0Vycm9yU3RhdGUnXS5jdXJyZW50VmFsdWUpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snaXNTdWNjZXNzU3RhdGUnXSkge1xuICAgICAgdGhpcy51c2VDdXN0b21TdWNjZXNzU3RhdGVNYXRjaGVyKGNoYW5nZXNbJ2lzU3VjY2Vzc1N0YXRlJ10uY3VycmVudFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5oYXNGaWVsZEhpbnQgPSAhIXRoaXMuZmllbGRIaW50Py5sZW5ndGg7XG4gICAgdGhpcy5oYXNGaWVsZEVycm9yID0gISF0aGlzLmZpZWxkRXJyb3I/Lmxlbmd0aDtcbiAgICB0aGlzLmhhc0ZpZWxkU3VjY2VzcyA9ICEhdGhpcy5maWVsZFN1Y2Nlc3M/Lmxlbmd0aDtcblxuICAgIHRoaXMuaGFuZGxlRm9ybUZpZWxkT3B0aW9ucygpO1xuICAgIHRoaXMuaGFuZGxlUmVnaXN0ZXJPbkZvY3VzKCk7XG4gICAgdGhpcy5oYW5kbGVSZWdpc3Rlck9uQmx1cigpO1xuICAgIHRoaXMuaGFuZGxlUmVnaXN0ZXJPbkRpc2FibGUoKTtcbiAgICB0aGlzLmhhbmRsZVJlZ2lzdGVyT25SZWFkb25seSgpO1xuICAgIHRoaXMuaGFuZGxlUmVnaXN0ZXJPblZhbGlkYXRlKCk7XG4gICAgdGhpcy5oYW5kbGVUZXh0YXJlYSgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlT25DbGlja1dyYXBwZXJFbGVtZW50KCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoMSk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVGb3JtRmllbGRPcHRpb25zKCkge1xuICAgIGlmICghdGhpcy5mb3JtRmllbGRBY2Nlc3Nvcj8uZmllbGRPcHRpb25zKSByZXR1cm47XG4gICAgdGhpcy5maWVsZE9wdGlvbnMgPSB0aGlzLmZvcm1GaWVsZEFjY2Vzc29yLmZpZWxkT3B0aW9ucztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlUmVnaXN0ZXJPbkZvY3VzKCkge1xuICAgIGlmICghdGhpcy5mb3JtRmllbGRBY2Nlc3NvcikgcmV0dXJuO1xuICAgIGNvbnN0IGZvY3VzSGFuZGxlciA9ICgpID0+IHtcbiAgICAgIHRoaXMuaXNGb2N1cyA9IHRydWU7XG4gICAgICB0aGlzLmNkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIH07XG4gICAgdGhpcy5mb3JtRmllbGRBY2Nlc3Nvci5yZWdpc3Rlck9uRm9jdXM/Lihmb2N1c0hhbmRsZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVSZWdpc3Rlck9uQmx1cigpIHtcbiAgICBpZiAoIXRoaXMuZm9ybUZpZWxkQWNjZXNzb3IpIHJldHVybjtcbiAgICBjb25zdCBibHVySGFuZGxlciA9ICgpID0+IHtcbiAgICAgIHRoaXMuaXNGb2N1cyA9IGZhbHNlO1xuICAgICAgdGhpcy5jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB9O1xuICAgIHRoaXMuZm9ybUZpZWxkQWNjZXNzb3IucmVnaXN0ZXJPbkJsdXI/LihibHVySGFuZGxlcik7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVJlZ2lzdGVyT25EaXNhYmxlKCkge1xuICAgIGlmICghdGhpcy5mb3JtRmllbGRBY2Nlc3NvcikgcmV0dXJuO1xuICAgIGNvbnN0IGRpc2FibGVIYW5kbGVyID0gKHZhbHVlOiBib29sZWFuKSA9PiB7XG4gICAgICB0aGlzLmlzRGlzYWJsZWQgPSB2YWx1ZTtcbiAgICAgIHRoaXMuY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfTtcbiAgICB0aGlzLmZvcm1GaWVsZEFjY2Vzc29yLnJlZ2lzdGVyT25EaXNhYmxlPy4oZGlzYWJsZUhhbmRsZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVSZWdpc3Rlck9uUmVhZG9ubHkoKSB7XG4gICAgaWYgKCF0aGlzLmZvcm1GaWVsZEFjY2Vzc29yKSByZXR1cm47XG4gICAgY29uc3QgcmVhZG9ubHlIYW5kbGVyID0gKHZhbHVlOiBib29sZWFuKSA9PiB7XG4gICAgICB0aGlzLmlzUmVhZG9ubHkgPSB2YWx1ZTtcbiAgICAgIHRoaXMuY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfTtcbiAgICB0aGlzLmZvcm1GaWVsZEFjY2Vzc29yLnJlZ2lzdGVyT25SZWFkb25seT8uKHJlYWRvbmx5SGFuZGxlcik7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVJlZ2lzdGVyT25WYWxpZGF0ZSgpIHtcbiAgICBpZiAoIXRoaXMuZm9ybUZpZWxkQWNjZXNzb3IpIHJldHVybjtcbiAgICBjb25zdCB2YWxpZGF0aW9uSGFuZGxlciA9IChcbiAgICAgIHZhbHVlPzogRG9rdUZvcm1GaWVsZEFjY2Vzc29yVmFsaWRhdGVWYWx1ZSxcbiAgICAgIHN0YXRlPzogRG9rdUZvcm1GaWVsZEFjY2Vzc29yVmFsaWRhdGVTdGF0ZVxuICAgICkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLmlzRXJyb3JTdGF0ZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm47XG4gICAgICBpZiAodHlwZW9mIHRoaXMuaXNTdWNjZXNzU3RhdGUgPT09ICdib29sZWFuJykgcmV0dXJuO1xuXG4gICAgICBjb25zdCBpc0NvbnRyb2xSZXNldCA9IHN0YXRlPy5wcmlzdGluZSAmJiBzdGF0ZS51bnRvdWNoZWQ7XG5cbiAgICAgIGlmIChpc0NvbnRyb2xSZXNldCkge1xuICAgICAgICB0aGlzLmlzRXJyb3IgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc1N1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICd2YWxpZCcpIHtcbiAgICAgICAgdGhpcy5pc0Vycm9yID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNTdWNjZXNzID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICdpbnZhbGlkJykge1xuICAgICAgICB0aGlzLmlzRXJyb3IgPSB0cnVlO1xuICAgICAgICB0aGlzLmlzU3VjY2VzcyA9IGZhbHNlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pc0Vycm9yID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNTdWNjZXNzID0gZmFsc2U7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aGlzLmZvcm1GaWVsZEFjY2Vzc29yLnJlZ2lzdGVyT25WYWxpZGF0ZT8uKHZhbGlkYXRpb25IYW5kbGVyKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlT25DbGlja1dyYXBwZXJFbGVtZW50KCkge1xuICAgIGlmICghdGhpcy5mb3JtRmllbGRBY2Nlc3NvcikgcmV0dXJuO1xuICAgIGZyb21FdmVudCh0aGlzLmlucHV0V3JhcHBlckVsZW1lbnQsICdjbGljaycpXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKChldikgPT4gIXRoaXMuaXNFbGVtZW50UHJlZml4T3JTdWZmaXhDbGlja2VkKGV2LnRhcmdldCBhcyBIVE1MRWxlbWVudCkpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgICAgdGhpcy5mb3JtRmllbGRBY2Nlc3Nvcj8ub25DbGlja1dyYXBwZXJFbGVtZW50Py4oZSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVGV4dGFyZWEoKSB7XG4gICAgaWYgKCF0aGlzLmZvcm1GaWVsZEFjY2Vzc29yKSByZXR1cm47XG4gICAgY29uc3QgaXNUZXh0YXJlYSA9XG4gICAgICAodGhpcy5mb3JtRmllbGRBY2Nlc3NvciBhcyBhbnkpLmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ/Lm5vZGVOYW1lPy50b0xvd2VyQ2FzZSgpID09PVxuICAgICAgJ3RleHRhcmVhJztcbiAgICBpZiAoIWlzVGV4dGFyZWEpIHJldHVybjtcbiAgICB0aGlzLmlzVGV4dGFyZWEgPSB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0VsZW1lbnRQcmVmaXhPclN1ZmZpeENsaWNrZWQoc3JjRWxlbWVudDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCBwcmVmaXhFbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPVxuICAgICAgdGhpcy5pbnB1dFdyYXBwZXJFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkb2t1LWZpZWxkLXByZWZpeF0nKTtcbiAgICBjb25zdCBzdWZmaXhFbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPVxuICAgICAgdGhpcy5pbnB1dFdyYXBwZXJFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkb2t1LWZpZWxkLXN1ZmZpeF0nKTtcblxuICAgIGxldCBjbGlja2VkID0gZmFsc2U7XG5cbiAgICBpZiAocHJlZml4RWxlbWVudCkgY2xpY2tlZCA9IHRoaXMuY2hlY2tFbGVtZW50Q2hpbGRyZW4oc3JjRWxlbWVudCwgcHJlZml4RWxlbWVudCk7XG4gICAgaWYgKGNsaWNrZWQpIHJldHVybiBjbGlja2VkO1xuICAgIGlmIChzdWZmaXhFbGVtZW50KSBjbGlja2VkID0gdGhpcy5jaGVja0VsZW1lbnRDaGlsZHJlbihzcmNFbGVtZW50LCBzdWZmaXhFbGVtZW50KTtcbiAgICByZXR1cm4gY2xpY2tlZDtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tFbGVtZW50Q2hpbGRyZW4oY2xpY2tlZEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBjaGVja0VsZW1lbnQ/OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGlmICghY2xpY2tlZEVsZW1lbnQgfHwgIWNoZWNrRWxlbWVudCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChjbGlja2VkRWxlbWVudCA9PT0gY2hlY2tFbGVtZW50KSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoIWNoZWNrRWxlbWVudC5oYXNDaGlsZE5vZGVzKCkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShjaGVja0VsZW1lbnQuY2hpbGRyZW4pLnNvbWUoKGNoaWxkKSA9PlxuICAgICAgdGhpcy5jaGVja0VsZW1lbnRDaGlsZHJlbihjbGlja2VkRWxlbWVudCwgY2hpbGQgYXMgSFRNTEVsZW1lbnQpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgdXNlQ3VzdG9tRXJyb3JTdGF0ZU1hdGNoZXIodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmlzRXJyb3IgPSB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgdXNlQ3VzdG9tU3VjY2Vzc1N0YXRlTWF0Y2hlcih2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuaXNTdWNjZXNzID0gdmFsdWU7XG4gIH1cbn1cbiIsIjxuZy1jb250ZW50IHNlbGVjdD1cImRva3UtZmllbGQtbGFiZWxcIj48L25nLWNvbnRlbnQ+XG5cbjxkaXZcbiAgI2lucHV0V3JhcHBlclxuICBjbGFzcz1cImQtZmllbGQtaW5wdXQtd3JhcHBlclwiXG4gIFtjbGFzcy5kLWZpZWxkLWZvY3VzXT1cImlzRm9jdXNcIlxuICBbY2xhc3Mubm8tc3R5bGVdPVwiZmllbGRPcHRpb25zPy53aXRob3V0SW5wdXRTdHlsZVwiXG4+XG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIltkb2t1LWZpZWxkLXByZWZpeF1cIj48L25nLWNvbnRlbnQ+XG4gIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2Rva3UtZmllbGQtc3VmZml4XVwiPjwvbmctY29udGVudD5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwic2hvdWxkU2hvd0ZpZWxkSGVscGVyXCIgY2xhc3M9XCJkLWZpZWxkLWhlbHBlci10ZXh0IGQtdGV4dC1ib2R5LXNcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhhc0ZpZWxkSGludCAmJiAhaXNFcnJvciAmJiAoIWlzU3VjY2VzcyB8fCAhc2hvd1N1Y2Nlc3NCZWhhdmlvcilcIj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJkb2t1LWZpZWxkLWhpbnRcIj48L25nLWNvbnRlbnQ+XG4gIDwvbmctY29udGFpbmVyPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiaGFzRmllbGRFcnJvciAmJiBpc0Vycm9yXCI+XG4gICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiZG9rdS1maWVsZC1lcnJvclwiPjwvbmctY29udGVudD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNGaWVsZFN1Y2Nlc3MgJiYgaXNTdWNjZXNzICYmIHNob3dTdWNjZXNzQmVoYXZpb3JcIj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJkb2t1LWZpZWxkLXN1Y2Nlc3NcIj48L25nLWNvbnRlbnQ+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+XG4iXX0=