UNPKG

@alfresco/adf-content-services

Version:
155 lines 33.5 kB
/*! * @license * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Component, ViewEncapsulation } from '@angular/core'; import { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher'; import { ReplaySubject } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { CommonModule } from '@angular/common'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { TranslateModule } from '@ngx-translate/core'; import { MatButtonModule } from '@angular/material/button'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "@angular/material/form-field"; import * as i4 from "@angular/material/input"; import * as i5 from "@ngx-translate/core"; import * as i6 from "@angular/material/button"; export class SearchNumberRangeComponent { constructor() { this.matcher = new LiveErrorStateMatcher(); this.format = '[{FROM} TO {TO}]'; this.isActive = false; this.displayValue$ = new ReplaySubject(1); } ngOnInit() { if (this.settings) { this.field = this.settings.field; this.format = this.settings.format || '[{FROM} TO {TO}]'; } this.validators = Validators.compose([Validators.required, Validators.pattern(/^-?(0|[1-9]\d*)?$/), Validators.min(0)]); if (this.startValue) { this.from = new UntypedFormControl(this.startValue['from'], this.validators); this.to = new UntypedFormControl(this.startValue['to'], this.validators); } else { this.from = new UntypedFormControl('', this.validators); this.to = new UntypedFormControl('', this.validators); } this.form = new UntypedFormGroup({ from: this.from, to: this.to }, this.formValidator); this.enableChangeUpdate = this.settings?.allowUpdateOnChange ?? true; this.updateDisplayValue(); this.context.populateFilters .asObservable() .pipe(map((filtersQueries) => filtersQueries[this.id]), first()) .subscribe((filterQuery) => { if (filterQuery) { this.form.patchValue({ from: filterQuery.from, to: filterQuery.to }); this.form.markAsDirty(); this.apply({ from: filterQuery.from, to: filterQuery.to }, true, false); } else { this.reset(false); } this.context.filterLoaded.next(); }); } formValidator(formGroup) { return parseInt(formGroup.get('from').value, 10) < parseInt(formGroup.get('to').value, 10) ? null : { mismatch: true }; } apply(model, isValid, updateContext = true) { if (isValid && this.id && this.context && this.field) { this.updateDisplayValue(); this.isActive = true; const destinationObject = new Map(); destinationObject.set('FROM', model.from); destinationObject.set('TO', model.to); const value = this.formatString(this.format, destinationObject); this.context.queryFragments[this.id] = `${this.field}:${value}`; const filterParam = this.context.filterRawParams[this.id] ?? {}; this.context.filterRawParams[this.id] = filterParam; filterParam.from = model.from; filterParam.to = model.to; if (updateContext) { this.context.update(); } } } formatString(str, destinationObject) { let result = str; destinationObject.forEach((value, key) => { const expr = new RegExp('{' + key + '}', 'gm'); result = result.replace(expr, value); }); return result; } submitValues() { this.apply(this.form.value, this.form.valid); } hasValidValue() { return this.form.valid; } getCurrentValue() { return this.form.value; } updateDisplayValue() { if (this.form.invalid || this.form.pristine) { this.displayValue$.next(''); } else { this.displayValue$.next(`${this.form.value.from} - ${this.form.value.to} ${this.settings.unit ?? ''}`); } } setValue(value) { this.form['from'].setValue(value); this.form['to'].setValue(value); this.updateDisplayValue(); } clear(updateContext = true) { this.isActive = false; this.form.reset({ from: '', to: '' }); if (this.id && this.context) { this.context.queryFragments[this.id] = ''; this.context.filterRawParams[this.id] = undefined; this.updateDisplayValue(); if (this.enableChangeUpdate && updateContext) { this.context.update(); } } } reset(updateContext = true) { this.clear(); if (this.id && this.context && updateContext) { this.context.update(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SearchNumberRangeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: SearchNumberRangeComponent, isStandalone: true, selector: "adf-search-number-range", host: { classAttribute: "adf-search-number-range" }, ngImport: i0, template: "<form [formGroup]=\"form\" novalidate (ngSubmit)=\"apply(form.value, form.valid)\">\n\n <mat-form-field>\n <input\n matInput [formControl]=\"from\" [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.FROM' | translate }}\"\n autocomplete=\"off\"\n data-automation-id=\"number-range-from-input\">\n <mat-error *ngIf=\"from.hasError('pattern') || from.hasError('min')\" data-automation-id=\"number-range-from-error-invalid\">\n {{ 'SEARCH.FILTER.VALIDATION.INVALID-FORMAT' | translate }}\n </mat-error>\n <mat-error *ngIf=\"from.hasError('required')\" data-automation-id=\"number-range-from-error-required\">\n {{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput [formControl]=\"to\" [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.TO' | translate }}\"\n autocomplete=\"off\"\n data-automation-id=\"number-range-to-input\">\n <mat-error *ngIf=\"to.hasError('pattern') || to.hasError('min')\" data-automation-id=\"number-range-to-error-invalid\">\n {{ 'SEARCH.FILTER.VALIDATION.INVALID-FORMAT' | translate }}\n </mat-error>\n <mat-error *ngIf=\"to.hasError('required')\" data-automation-id=\"number-range-to-error-required\">\n {{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}\n </mat-error>\n </mat-form-field>\n\n\n <div class=\"adf-facet-buttons\" *ngIf=\"!settings?.hideDefaultAction\">\n <button mat-button color=\"primary\" type=\"button\" (click)=\"clear()\" data-automation-id=\"number-range-btn-clear\">\n {{ 'SEARCH.FILTER.ACTIONS.CLEAR' | translate }}\n </button>\n <button mat-button color=\"primary\" type=\"submit\" [disabled]=\"!form.valid\" data-automation-id=\"number-range-btn-apply\">\n {{ 'SEARCH.FILTER.ACTIONS.APPLY' | translate }}\n </button>\n </div>\n</form>\n", styles: [".adf-search-number-range>form{display:inline-flex;flex-direction:column;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SearchNumberRangeComponent, decorators: [{ type: Component, args: [{ selector: 'adf-search-number-range', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, TranslateModule, MatButtonModule], encapsulation: ViewEncapsulation.None, host: { class: 'adf-search-number-range' }, template: "<form [formGroup]=\"form\" novalidate (ngSubmit)=\"apply(form.value, form.valid)\">\n\n <mat-form-field>\n <input\n matInput [formControl]=\"from\" [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.FROM' | translate }}\"\n autocomplete=\"off\"\n data-automation-id=\"number-range-from-input\">\n <mat-error *ngIf=\"from.hasError('pattern') || from.hasError('min')\" data-automation-id=\"number-range-from-error-invalid\">\n {{ 'SEARCH.FILTER.VALIDATION.INVALID-FORMAT' | translate }}\n </mat-error>\n <mat-error *ngIf=\"from.hasError('required')\" data-automation-id=\"number-range-from-error-required\">\n {{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput [formControl]=\"to\" [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.TO' | translate }}\"\n autocomplete=\"off\"\n data-automation-id=\"number-range-to-input\">\n <mat-error *ngIf=\"to.hasError('pattern') || to.hasError('min')\" data-automation-id=\"number-range-to-error-invalid\">\n {{ 'SEARCH.FILTER.VALIDATION.INVALID-FORMAT' | translate }}\n </mat-error>\n <mat-error *ngIf=\"to.hasError('required')\" data-automation-id=\"number-range-to-error-required\">\n {{ 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE' | translate }}\n </mat-error>\n </mat-form-field>\n\n\n <div class=\"adf-facet-buttons\" *ngIf=\"!settings?.hideDefaultAction\">\n <button mat-button color=\"primary\" type=\"button\" (click)=\"clear()\" data-automation-id=\"number-range-btn-clear\">\n {{ 'SEARCH.FILTER.ACTIONS.CLEAR' | translate }}\n </button>\n <button mat-button color=\"primary\" type=\"submit\" [disabled]=\"!form.valid\" data-automation-id=\"number-range-btn-apply\">\n {{ 'SEARCH.FILTER.ACTIONS.APPLY' | translate }}\n </button>\n </div>\n</form>\n", styles: [".adf-search-number-range>form{display:inline-flex;flex-direction:column;width:100%}\n"] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3NlYXJjaC9jb21wb25lbnRzL3NlYXJjaC1udW1iZXItcmFuZ2Uvc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3NlYXJjaC9jb21wb25lbnRzL3NlYXJjaC1udW1iZXItcmFuZ2Uvc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFVLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUl2RyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7OztBQVczRCxNQUFNLE9BQU8sMEJBQTBC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LE1BQU0sRUFBRSxDQUFDO1lBQzFCLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLEdBQUcsSUFBSTtRQUN0QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDYixJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzFCLENBQUM7SUFDTCxDQUFDOzhHQXZKUSwwQkFBMEI7a0dBQTFCLDBCQUEwQix3SUN4Q3ZDLDZpRUF3Q0EsOElETmMsWUFBWSxrSUFBRSxtQkFBbUIsKzlCQUFFLGtCQUFrQixzVUFBRSxjQUFjLDBXQUFFLGVBQWUsMkZBQUUsZUFBZTs7MkZBTXhHLDBCQUEwQjtrQkFUdEMsU0FBUzsrQkFDSSx5QkFBeUIsY0FDdkIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLGlCQUduRyxpQkFBaUIsQ0FBQyxJQUFJLFFBQy9CLEVBQUUsS0FBSyxFQUFFLHlCQUF5QixFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IMKpIDIwMDUtMjAyNSBIeWxhbmQgU29mdHdhcmUsIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJlYWN0aXZlRm9ybXNNb2R1bGUsIFVudHlwZWRGb3JtQ29udHJvbCwgVW50eXBlZEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNlYXJjaFdpZGdldCB9IGZyb20gJy4uLy4uL21vZGVscy9zZWFyY2gtd2lkZ2V0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBTZWFyY2hXaWRnZXRTZXR0aW5ncyB9IGZyb20gJy4uLy4uL21vZGVscy9zZWFyY2gtd2lkZ2V0LXNldHRpbmdzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBTZWFyY2hRdWVyeUJ1aWxkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc2VhcmNoLXF1ZXJ5LWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBMaXZlRXJyb3JTdGF0ZU1hdGNoZXIgfSBmcm9tICcuLi8uLi9mb3Jtcy9saXZlLWVycm9yLXN0YXRlLW1hdGNoZXInO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlyc3QsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdElucHV0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2FkZi1zZWFyY2gtbnVtYmVyLXJhbmdlJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIE1hdEZvcm1GaWVsZE1vZHVsZSwgTWF0SW5wdXRNb2R1bGUsIFRyYW5zbGF0ZU1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuc2NzcyddLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gICAgaG9zdDogeyBjbGFzczogJ2FkZi1zZWFyY2gtbnVtYmVyLXJhbmdlJyB9XG59KVxuZXhwb3J0IGNsYXNzIFNlYXJjaE51bWJlclJhbmdlQ29tcG9uZW50IGltcGxlbWVudHMgU2VhcmNoV2lkZ2V0LCBPbkluaXQge1xuICAgIGZyb206IFVudHlwZWRGb3JtQ29udHJvbDtcbiAgICB0bzogVW50eXBlZEZvcm1Db250cm9sO1xuXG4gICAgZm9ybTogVW50eXBlZEZvcm1Hcm91cDtcbiAgICBtYXRjaGVyID0gbmV3IExpdmVFcnJvclN0YXRlTWF0Y2hlcigpO1xuXG4gICAgaWQ6IHN0cmluZztcbiAgICBzZXR0aW5ncz86IFNlYXJjaFdpZGdldFNldHRpbmdzO1xuICAgIGNvbnRleHQ/OiBTZWFyY2hRdWVyeUJ1aWxkZXJTZXJ2aWNlO1xuXG4gICAgZmllbGQ6IHN0cmluZztcbiAgICBmb3JtYXQgPSAnW3tGUk9NfSBUTyB7VE99XSc7XG5cbiAgICBpc0FjdGl2ZSA9IGZhbHNlO1xuICAgIHN0YXJ0VmFsdWU6IGFueTtcblxuICAgIHZhbGlkYXRvcnM6IFZhbGlkYXRvcnM7XG4gICAgZW5hYmxlQ2hhbmdlVXBkYXRlOiBib29sZWFuO1xuICAgIGRpc3BsYXlWYWx1ZSQgPSBuZXcgUmVwbGF5U3ViamVjdDxzdHJpbmc+KDEpO1xuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzKSB7XG4gICAgICAgICAgICB0aGlzLmZpZWxkID0gdGhpcy5zZXR0aW5ncy5maWVsZDtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gdGhpcy5zZXR0aW5ncy5mb3JtYXQgfHwgJ1t7RlJPTX0gVE8ge1RPfV0nO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52YWxpZGF0b3JzID0gVmFsaWRhdG9ycy5jb21wb3NlKFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLnBhdHRlcm4oL14tPygwfFsxLTldXFxkKik/JC8pLCBWYWxpZGF0b3JzLm1pbigwKV0pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXJ0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuZnJvbSA9IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2wodGhpcy5zdGFydFZhbHVlWydmcm9tJ10sIHRoaXMudmFsaWRhdG9ycyk7XG4gICAgICAgICAgICB0aGlzLnRvID0gbmV3IFVudHlwZWRGb3JtQ29udHJvbCh0aGlzLnN0YXJ0VmFsdWVbJ3RvJ10sIHRoaXMudmFsaWRhdG9ycyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZyb20gPSBuZXcgVW50eXBlZEZvcm1Db250cm9sKCcnLCB0aGlzLnZhbGlkYXRvcnMpO1xuICAgICAgICAgICAgdGhpcy50byA9IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2woJycsIHRoaXMudmFsaWRhdG9ycyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvcm0gPSBuZXcgVW50eXBlZEZvcm1Hcm91cChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiB0aGlzLmZyb20sXG4gICAgICAgICAgICAgICAgdG86IHRoaXMudG9cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0b3JcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmVuYWJsZUNoYW5nZVVwZGF0ZSA9IHRoaXMuc2V0dGluZ3M/LmFsbG93VXBkYXRlT25DaGFuZ2UgPz8gdHJ1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVEaXNwbGF5VmFsdWUoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnBvcHVsYXRlRmlsdGVyc1xuICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBtYXAoKGZpbHRlcnNRdWVyaWVzKSA9PiBmaWx0ZXJzUXVlcmllc1t0aGlzLmlkXSksXG4gICAgICAgICAgICAgICAgZmlyc3QoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZmlsdGVyUXVlcnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZmlsdGVyUXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBmcm9tOiBmaWx0ZXJRdWVyeS5mcm9tLCB0bzogZmlsdGVyUXVlcnkudG8gfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5tYXJrQXNEaXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5KHsgZnJvbTogZmlsdGVyUXVlcnkuZnJvbSwgdG86IGZpbHRlclF1ZXJ5LnRvIH0sIHRydWUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmZpbHRlckxvYWRlZC5uZXh0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3JtVmFsaWRhdG9yKGZvcm1Hcm91cDogVW50eXBlZEZvcm1Hcm91cCkge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQoZm9ybUdyb3VwLmdldCgnZnJvbScpLnZhbHVlLCAxMCkgPCBwYXJzZUludChmb3JtR3JvdXAuZ2V0KCd0bycpLnZhbHVlLCAxMCkgPyBudWxsIDogeyBtaXNtYXRjaDogdHJ1ZSB9O1xuICAgIH1cblxuICAgIGFwcGx5KG1vZGVsOiB7IGZyb206IHN0cmluZzsgdG86IHN0cmluZyB9LCBpc1ZhbGlkOiBib29sZWFuLCB1cGRhdGVDb250ZXh0ID0gdHJ1ZSkge1xuICAgICAgICBpZiAoaXNWYWxpZCAmJiB0aGlzLmlkICYmIHRoaXMuY29udGV4dCAmJiB0aGlzLmZpZWxkKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZURpc3BsYXlWYWx1ZSgpO1xuICAgICAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGRlc3RpbmF0aW9uT2JqZWN0ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uT2JqZWN0LnNldCgnRlJPTScsIG1vZGVsLmZyb20pO1xuICAgICAgICAgICAgZGVzdGluYXRpb25PYmplY3Quc2V0KCdUTycsIG1vZGVsLnRvKTtcblxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZvcm1hdFN0cmluZyh0aGlzLmZvcm1hdCwgZGVzdGluYXRpb25PYmplY3QpO1xuXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucXVlcnlGcmFnbWVudHNbdGhpcy5pZF0gPSBgJHt0aGlzLmZpZWxkfToke3ZhbHVlfWA7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJQYXJhbSA9IHRoaXMuY29udGV4dC5maWx0ZXJSYXdQYXJhbXNbdGhpcy5pZF0gPz8ge307XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZmlsdGVyUmF3UGFyYW1zW3RoaXMuaWRdID0gZmlsdGVyUGFyYW07XG4gICAgICAgICAgICBmaWx0ZXJQYXJhbS5mcm9tID0gbW9kZWwuZnJvbTtcbiAgICAgICAgICAgIGZpbHRlclBhcmFtLnRvID0gbW9kZWwudG87XG4gICAgICAgICAgICBpZiAodXBkYXRlQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC51cGRhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZm9ybWF0U3RyaW5nKHN0cjogc3RyaW5nLCBkZXN0aW5hdGlvbk9iamVjdDogTWFwPHN0cmluZywgc3RyaW5nPik6IHN0cmluZyB7XG4gICAgICAgIGxldCByZXN1bHQgPSBzdHI7XG5cbiAgICAgICAgZGVzdGluYXRpb25PYmplY3QuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhwciA9IG5ldyBSZWdFeHAoJ3snICsga2V5ICsgJ30nLCAnZ20nKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKGV4cHIsIHZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBzdWJtaXRWYWx1ZXMoKSB7XG4gICAgICAgIHRoaXMuYXBwbHkodGhpcy5mb3JtLnZhbHVlLCB0aGlzLmZvcm0udmFsaWQpO1xuICAgIH1cblxuICAgIGhhc1ZhbGlkVmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm0udmFsaWQ7XG4gICAgfVxuXG4gICAgZ2V0Q3VycmVudFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtLnZhbHVlO1xuICAgIH1cblxuICAgIHVwZGF0ZURpc3BsYXlWYWx1ZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkIHx8IHRoaXMuZm9ybS5wcmlzdGluZSkge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUkLm5leHQoJycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUkLm5leHQoYCR7dGhpcy5mb3JtLnZhbHVlLmZyb219IC0gJHt0aGlzLmZvcm0udmFsdWUudG99ICR7dGhpcy5zZXR0aW5ncy51bml0ID8/ICcnfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0VmFsdWUodmFsdWU6IGFueSkge1xuICAgICAgICB0aGlzLmZvcm1bJ2Zyb20nXS5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMuZm9ybVsndG8nXS5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgfVxuXG4gICAgY2xlYXIodXBkYXRlQ29udGV4dCA9IHRydWUpIHtcbiAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuZm9ybS5yZXNldCh7XG4gICAgICAgICAgICBmcm9tOiAnJyxcbiAgICAgICAgICAgIHRvOiAnJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5pZCAmJiB0aGlzLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5xdWVyeUZyYWdtZW50c1t0aGlzLmlkXSA9ICcnO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmZpbHRlclJhd1BhcmFtc1t0aGlzLmlkXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5lbmFibGVDaGFuZ2VVcGRhdGUgJiYgdXBkYXRlQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC51cGRhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0KHVwZGF0ZUNvbnRleHQgPSB0cnVlKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgaWYgKHRoaXMuaWQgJiYgdGhpcy5jb250ZXh0ICYmIHVwZGF0ZUNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIG5vdmFsaWRhdGUgKG5nU3VibWl0KT1cImFwcGx5KGZvcm0udmFsdWUsIGZvcm0udmFsaWQpXCI+XG5cbiAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cImZyb21cIiBbZXJyb3JTdGF0ZU1hdGNoZXJdPVwibWF0Y2hlclwiXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7ICdTRUFSQ0guRklMVEVSLlJBTkdFLkZST00nIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtZnJvbS1pbnB1dFwiPlxuICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZnJvbS5oYXNFcnJvcigncGF0dGVybicpIHx8IGZyb20uaGFzRXJyb3IoJ21pbicpXCIgZGF0YS1hdXRvbWF0aW9uLWlkPVwibnVtYmVyLXJhbmdlLWZyb20tZXJyb3ItaW52YWxpZFwiPlxuICAgICAgICAgICAge3sgJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5JTlZBTElELUZPUk1BVCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmcm9tLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgZGF0YS1hdXRvbWF0aW9uLWlkPVwibnVtYmVyLXJhbmdlLWZyb20tZXJyb3ItcmVxdWlyZWRcIj5cbiAgICAgICAgICAgIHt7ICdTRUFSQ0guRklMVEVSLlZBTElEQVRJT04uUkVRVUlSRUQtVkFMVUUnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvbWF0LWVycm9yPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cInRvXCIgW2Vycm9yU3RhdGVNYXRjaGVyXT1cIm1hdGNoZXJcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7eyAnU0VBUkNILkZJTFRFUi5SQU5HRS5UTycgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIGRhdGEtYXV0b21hdGlvbi1pZD1cIm51bWJlci1yYW5nZS10by1pbnB1dFwiPlxuICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwidG8uaGFzRXJyb3IoJ3BhdHRlcm4nKSB8fCB0by5oYXNFcnJvcignbWluJylcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtdG8tZXJyb3ItaW52YWxpZFwiPlxuICAgICAgICAgICAge3sgJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5JTlZBTElELUZPUk1BVCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJ0by5oYXNFcnJvcigncmVxdWlyZWQnKVwiIGRhdGEtYXV0b21hdGlvbi1pZD1cIm51bWJlci1yYW5nZS10by1lcnJvci1yZXF1aXJlZFwiPlxuICAgICAgICAgICAge3sgJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5SRVFVSVJFRC1WQUxVRScgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgPC9tYXQtZm9ybS1maWVsZD5cblxuXG4gICAgPGRpdiBjbGFzcz1cImFkZi1mYWNldC1idXR0b25zXCIgKm5nSWY9XCIhc2V0dGluZ3M/LmhpZGVEZWZhdWx0QWN0aW9uXCI+XG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNsZWFyKClcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtYnRuLWNsZWFyXCI+XG4gICAgICAgICAgICB7eyAnU0VBUkNILkZJTFRFUi5BQ1RJT05TLkNMRUFSJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWZvcm0udmFsaWRcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtYnRuLWFwcGx5XCI+XG4gICAgICAgICAgICB7eyAnU0VBUkNILkZJTFRFUi5BQ1RJT05TLkFQUExZJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbjwvZm9ybT5cbiJdfQ==