@alfresco/adf-content-services
Version:
Alfresco ADF content services
155 lines • 33.5 kB
JavaScript
/*!
* @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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3NlYXJjaC9jb21wb25lbnRzL3NlYXJjaC1udW1iZXItcmFuZ2Uvc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3NlYXJjaC9jb21wb25lbnRzL3NlYXJjaC1udW1iZXItcmFuZ2Uvc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFVLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUl2RyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7OztBQVczRCxNQUFNLE9BQU8sMEJBQTBCO0lBVHZDO1FBY0ksWUFBTyxHQUFHLElBQUkscUJBQXFCLEVBQUUsQ0FBQztRQU90QyxXQUFNLEdBQUcsa0JBQWtCLENBQUM7UUFFNUIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUtqQixrQkFBYSxHQUFHLElBQUksYUFBYSxDQUFTLENBQUMsQ0FBQyxDQUFDO0tBcUloRDtJQW5JRyxRQUFRO1FBQ0osSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUNqQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxJQUFJLGtCQUFrQixDQUFDO1FBQzdELENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV4SCxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDN0UsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzdFLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLGtCQUFrQixDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUQsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxnQkFBZ0IsQ0FDNUI7WUFDSSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7U0FDZCxFQUNELElBQUksQ0FBQyxhQUFhLENBQ3JCLENBQUM7UUFFRixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxtQkFBbUIsSUFBSSxJQUFJLENBQUM7UUFDckUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlO2FBQ3ZCLFlBQVksRUFBRTthQUNkLElBQUksQ0FDRCxHQUFHLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDaEQsS0FBSyxFQUFFLENBQ1Y7YUFDQSxTQUFTLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUN2QixJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLFdBQVcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLFdBQVcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDNUUsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEIsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVELGFBQWEsQ0FBQyxTQUEyQjtRQUNyQyxPQUFPLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDM0gsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFtQyxFQUFFLE9BQWdCLEVBQUUsYUFBYSxHQUFHLElBQUk7UUFDN0UsSUFBSSxPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUVyQixNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1lBQ3BELGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRXRDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBRWhFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxFQUFFLENBQUM7WUFDaEUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNoRSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDO1lBQ3BELFdBQVcsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztZQUM5QixXQUFXLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDMUIsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMxQixDQUFDO1FBQ0wsQ0FBQztJQUNMLENBQUM7SUFFTyxZQUFZLENBQUMsR0FBVyxFQUFFLGlCQUFzQztRQUNwRSxJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUM7UUFFakIsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQy9DLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxZQUFZO1FBQ1IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxhQUFhO1FBQ1QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUMzQixDQUFDO0lBRUQsZUFBZTtRQUNYLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDM0IsQ0FBQztJQUVELGtCQUFrQjtRQUNkLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoQyxDQUFDO2FBQU0sQ0FBQztZQUNKLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzNHLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQVU7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsR0FBRyxJQUFJO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBRXRCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ1osSUFBSSxFQUFFLEVBQUU7WUFDUixFQUFFLEVBQUUsRUFBRTtTQUNULENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDO1lBQ2xELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzFCLElBQUksSUFBSSxDQUFDLGtCQUFrQixJQUFJLGFBQWEsRUFBRSxDQUFDO2dCQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzFCLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLEdBQUcsSUFBSTtRQUN0QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDYixJQUFJLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzFCLENBQUM7SUFDTCxDQUFDOzhHQXZKUSwwQkFBMEI7a0dBQTFCLDBCQUEwQix3SUN4Q3ZDLDZpRUF3Q0EsOElETmMsWUFBWSxrSUFBRSxtQkFBbUIsKzlCQUFFLGtCQUFrQixzVUFBRSxjQUFjLDBXQUFFLGVBQWUsMkZBQUUsZUFBZTs7MkZBTXhHLDBCQUEwQjtrQkFUdEMsU0FBUzsrQkFDSSx5QkFBeUIsY0FDdkIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLGlCQUduRyxpQkFBaUIsQ0FBQyxJQUFJLFFBQy9CLEVBQUUsS0FBSyxFQUFFLHlCQUF5QixFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IMKpIDIwMDUtMjAyNSBIeWxhbmQgU29mdHdhcmUsIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJlYWN0aXZlRm9ybXNNb2R1bGUsIFVudHlwZWRGb3JtQ29udHJvbCwgVW50eXBlZEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNlYXJjaFdpZGdldCB9IGZyb20gJy4uLy4uL21vZGVscy9zZWFyY2gtd2lkZ2V0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBTZWFyY2hXaWRnZXRTZXR0aW5ncyB9IGZyb20gJy4uLy4uL21vZGVscy9zZWFyY2gtd2lkZ2V0LXNldHRpbmdzLmludGVyZmFjZSc7XG5pbXBvcnQgeyBTZWFyY2hRdWVyeUJ1aWxkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvc2VhcmNoLXF1ZXJ5LWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBMaXZlRXJyb3JTdGF0ZU1hdGNoZXIgfSBmcm9tICcuLi8uLi9mb3Jtcy9saXZlLWVycm9yLXN0YXRlLW1hdGNoZXInO1xuaW1wb3J0IHsgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlyc3QsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdElucHV0TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2FkZi1zZWFyY2gtbnVtYmVyLXJhbmdlJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIE1hdEZvcm1GaWVsZE1vZHVsZSwgTWF0SW5wdXRNb2R1bGUsIFRyYW5zbGF0ZU1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vc2VhcmNoLW51bWJlci1yYW5nZS5jb21wb25lbnQuc2NzcyddLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gICAgaG9zdDogeyBjbGFzczogJ2FkZi1zZWFyY2gtbnVtYmVyLXJhbmdlJyB9XG59KVxuZXhwb3J0IGNsYXNzIFNlYXJjaE51bWJlclJhbmdlQ29tcG9uZW50IGltcGxlbWVudHMgU2VhcmNoV2lkZ2V0LCBPbkluaXQge1xuICAgIGZyb206IFVudHlwZWRGb3JtQ29udHJvbDtcbiAgICB0bzogVW50eXBlZEZvcm1Db250cm9sO1xuXG4gICAgZm9ybTogVW50eXBlZEZvcm1Hcm91cDtcbiAgICBtYXRjaGVyID0gbmV3IExpdmVFcnJvclN0YXRlTWF0Y2hlcigpO1xuXG4gICAgaWQ6IHN0cmluZztcbiAgICBzZXR0aW5ncz86IFNlYXJjaFdpZGdldFNldHRpbmdzO1xuICAgIGNvbnRleHQ/OiBTZWFyY2hRdWVyeUJ1aWxkZXJTZXJ2aWNlO1xuXG4gICAgZmllbGQ6IHN0cmluZztcbiAgICBmb3JtYXQgPSAnW3tGUk9NfSBUTyB7VE99XSc7XG5cbiAgICBpc0FjdGl2ZSA9IGZhbHNlO1xuICAgIHN0YXJ0VmFsdWU6IGFueTtcblxuICAgIHZhbGlkYXRvcnM6IFZhbGlkYXRvcnM7XG4gICAgZW5hYmxlQ2hhbmdlVXBkYXRlOiBib29sZWFuO1xuICAgIGRpc3BsYXlWYWx1ZSQgPSBuZXcgUmVwbGF5U3ViamVjdDxzdHJpbmc+KDEpO1xuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzKSB7XG4gICAgICAgICAgICB0aGlzLmZpZWxkID0gdGhpcy5zZXR0aW5ncy5maWVsZDtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0ID0gdGhpcy5zZXR0aW5ncy5mb3JtYXQgfHwgJ1t7RlJPTX0gVE8ge1RPfV0nO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52YWxpZGF0b3JzID0gVmFsaWRhdG9ycy5jb21wb3NlKFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLnBhdHRlcm4oL14tPygwfFsxLTldXFxkKik/JC8pLCBWYWxpZGF0b3JzLm1pbigwKV0pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXJ0VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuZnJvbSA9IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2wodGhpcy5zdGFydFZhbHVlWydmcm9tJ10sIHRoaXMudmFsaWRhdG9ycyk7XG4gICAgICAgICAgICB0aGlzLnRvID0gbmV3IFVudHlwZWRGb3JtQ29udHJvbCh0aGlzLnN0YXJ0VmFsdWVbJ3RvJ10sIHRoaXMudmFsaWRhdG9ycyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZyb20gPSBuZXcgVW50eXBlZEZvcm1Db250cm9sKCcnLCB0aGlzLnZhbGlkYXRvcnMpO1xuICAgICAgICAgICAgdGhpcy50byA9IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2woJycsIHRoaXMudmFsaWRhdG9ycyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvcm0gPSBuZXcgVW50eXBlZEZvcm1Hcm91cChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiB0aGlzLmZyb20sXG4gICAgICAgICAgICAgICAgdG86IHRoaXMudG9cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0b3JcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmVuYWJsZUNoYW5nZVVwZGF0ZSA9IHRoaXMuc2V0dGluZ3M/LmFsbG93VXBkYXRlT25DaGFuZ2UgPz8gdHJ1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVEaXNwbGF5VmFsdWUoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnBvcHVsYXRlRmlsdGVyc1xuICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBtYXAoKGZpbHRlcnNRdWVyaWVzKSA9PiBmaWx0ZXJzUXVlcmllc1t0aGlzLmlkXSksXG4gICAgICAgICAgICAgICAgZmlyc3QoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZmlsdGVyUXVlcnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZmlsdGVyUXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBmcm9tOiBmaWx0ZXJRdWVyeS5mcm9tLCB0bzogZmlsdGVyUXVlcnkudG8gfSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5tYXJrQXNEaXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5KHsgZnJvbTogZmlsdGVyUXVlcnkuZnJvbSwgdG86IGZpbHRlclF1ZXJ5LnRvIH0sIHRydWUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmZpbHRlckxvYWRlZC5uZXh0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3JtVmFsaWRhdG9yKGZvcm1Hcm91cDogVW50eXBlZEZvcm1Hcm91cCkge1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQoZm9ybUdyb3VwLmdldCgnZnJvbScpLnZhbHVlLCAxMCkgPCBwYXJzZUludChmb3JtR3JvdXAuZ2V0KCd0bycpLnZhbHVlLCAxMCkgPyBudWxsIDogeyBtaXNtYXRjaDogdHJ1ZSB9O1xuICAgIH1cblxuICAgIGFwcGx5KG1vZGVsOiB7IGZyb206IHN0cmluZzsgdG86IHN0cmluZyB9LCBpc1ZhbGlkOiBib29sZWFuLCB1cGRhdGVDb250ZXh0ID0gdHJ1ZSkge1xuICAgICAgICBpZiAoaXNWYWxpZCAmJiB0aGlzLmlkICYmIHRoaXMuY29udGV4dCAmJiB0aGlzLmZpZWxkKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZURpc3BsYXlWYWx1ZSgpO1xuICAgICAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IHRydWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGRlc3RpbmF0aW9uT2JqZWN0ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uT2JqZWN0LnNldCgnRlJPTScsIG1vZGVsLmZyb20pO1xuICAgICAgICAgICAgZGVzdGluYXRpb25PYmplY3Quc2V0KCdUTycsIG1vZGVsLnRvKTtcblxuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmZvcm1hdFN0cmluZyh0aGlzLmZvcm1hdCwgZGVzdGluYXRpb25PYmplY3QpO1xuXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucXVlcnlGcmFnbWVudHNbdGhpcy5pZF0gPSBgJHt0aGlzLmZpZWxkfToke3ZhbHVlfWA7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJQYXJhbSA9IHRoaXMuY29udGV4dC5maWx0ZXJSYXdQYXJhbXNbdGhpcy5pZF0gPz8ge307XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZmlsdGVyUmF3UGFyYW1zW3RoaXMuaWRdID0gZmlsdGVyUGFyYW07XG4gICAgICAgICAgICBmaWx0ZXJQYXJhbS5mcm9tID0gbW9kZWwuZnJvbTtcbiAgICAgICAgICAgIGZpbHRlclBhcmFtLnRvID0gbW9kZWwudG87XG4gICAgICAgICAgICBpZiAodXBkYXRlQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC51cGRhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZm9ybWF0U3RyaW5nKHN0cjogc3RyaW5nLCBkZXN0aW5hdGlvbk9iamVjdDogTWFwPHN0cmluZywgc3RyaW5nPik6IHN0cmluZyB7XG4gICAgICAgIGxldCByZXN1bHQgPSBzdHI7XG5cbiAgICAgICAgZGVzdGluYXRpb25PYmplY3QuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhwciA9IG5ldyBSZWdFeHAoJ3snICsga2V5ICsgJ30nLCAnZ20nKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKGV4cHIsIHZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBzdWJtaXRWYWx1ZXMoKSB7XG4gICAgICAgIHRoaXMuYXBwbHkodGhpcy5mb3JtLnZhbHVlLCB0aGlzLmZvcm0udmFsaWQpO1xuICAgIH1cblxuICAgIGhhc1ZhbGlkVmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm0udmFsaWQ7XG4gICAgfVxuXG4gICAgZ2V0Q3VycmVudFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtLnZhbHVlO1xuICAgIH1cblxuICAgIHVwZGF0ZURpc3BsYXlWYWx1ZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkIHx8IHRoaXMuZm9ybS5wcmlzdGluZSkge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUkLm5leHQoJycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUkLm5leHQoYCR7dGhpcy5mb3JtLnZhbHVlLmZyb219IC0gJHt0aGlzLmZvcm0udmFsdWUudG99ICR7dGhpcy5zZXR0aW5ncy51bml0ID8/ICcnfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0VmFsdWUodmFsdWU6IGFueSkge1xuICAgICAgICB0aGlzLmZvcm1bJ2Zyb20nXS5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMuZm9ybVsndG8nXS5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgfVxuXG4gICAgY2xlYXIodXBkYXRlQ29udGV4dCA9IHRydWUpIHtcbiAgICAgICAgdGhpcy5pc0FjdGl2ZSA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuZm9ybS5yZXNldCh7XG4gICAgICAgICAgICBmcm9tOiAnJyxcbiAgICAgICAgICAgIHRvOiAnJ1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodGhpcy5pZCAmJiB0aGlzLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5xdWVyeUZyYWdtZW50c1t0aGlzLmlkXSA9ICcnO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmZpbHRlclJhd1BhcmFtc1t0aGlzLmlkXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5lbmFibGVDaGFuZ2VVcGRhdGUgJiYgdXBkYXRlQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC51cGRhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0KHVwZGF0ZUNvbnRleHQgPSB0cnVlKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgaWYgKHRoaXMuaWQgJiYgdGhpcy5jb250ZXh0ICYmIHVwZGF0ZUNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIG5vdmFsaWRhdGUgKG5nU3VibWl0KT1cImFwcGx5KGZvcm0udmFsdWUsIGZvcm0udmFsaWQpXCI+XG5cbiAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cImZyb21cIiBbZXJyb3JTdGF0ZU1hdGNoZXJdPVwibWF0Y2hlclwiXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7ICdTRUFSQ0guRklMVEVSLlJBTkdFLkZST00nIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtZnJvbS1pbnB1dFwiPlxuICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZnJvbS5oYXNFcnJvcigncGF0dGVybicpIHx8IGZyb20uaGFzRXJyb3IoJ21pbicpXCIgZGF0YS1hdXRvbWF0aW9uLWlkPVwibnVtYmVyLXJhbmdlLWZyb20tZXJyb3ItaW52YWxpZFwiPlxuICAgICAgICAgICAge3sgJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5JTlZBTElELUZPUk1BVCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmcm9tLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgZGF0YS1hdXRvbWF0aW9uLWlkPVwibnVtYmVyLXJhbmdlLWZyb20tZXJyb3ItcmVxdWlyZWRcIj5cbiAgICAgICAgICAgIHt7ICdTRUFSQ0guRklMVEVSLlZBTElEQVRJT04uUkVRVUlSRUQtVkFMVUUnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvbWF0LWVycm9yPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgbWF0SW5wdXQgW2Zvcm1Db250cm9sXT1cInRvXCIgW2Vycm9yU3RhdGVNYXRjaGVyXT1cIm1hdGNoZXJcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7eyAnU0VBUkNILkZJTFRFUi5SQU5HRS5UTycgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIGRhdGEtYXV0b21hdGlvbi1pZD1cIm51bWJlci1yYW5nZS10by1pbnB1dFwiPlxuICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwidG8uaGFzRXJyb3IoJ3BhdHRlcm4nKSB8fCB0by5oYXNFcnJvcignbWluJylcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtdG8tZXJyb3ItaW52YWxpZFwiPlxuICAgICAgICAgICAge3sgJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5JTlZBTElELUZPUk1BVCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJ0by5oYXNFcnJvcigncmVxdWlyZWQnKVwiIGRhdGEtYXV0b21hdGlvbi1pZD1cIm51bWJlci1yYW5nZS10by1lcnJvci1yZXF1aXJlZFwiPlxuICAgICAgICAgICAge3sgJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5SRVFVSVJFRC1WQUxVRScgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgPC9tYXQtZm9ybS1maWVsZD5cblxuXG4gICAgPGRpdiBjbGFzcz1cImFkZi1mYWNldC1idXR0b25zXCIgKm5nSWY9XCIhc2V0dGluZ3M/LmhpZGVEZWZhdWx0QWN0aW9uXCI+XG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImNsZWFyKClcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtYnRuLWNsZWFyXCI+XG4gICAgICAgICAgICB7eyAnU0VBUkNILkZJTFRFUi5BQ1RJT05TLkNMRUFSJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwiIWZvcm0udmFsaWRcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJudW1iZXItcmFuZ2UtYnRuLWFwcGx5XCI+XG4gICAgICAgICAgICB7eyAnU0VBUkNILkZJTFRFUi5BQ1RJT05TLkFQUExZJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbjwvZm9ybT5cbiJdfQ==