@alfresco/adf-content-services
Version:
Alfresco ADF content services
224 lines • 47.1 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, DestroyRef, inject, ViewEncapsulation } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { ADF_DATE_FORMATS, ADF_DATETIME_FORMATS, AdfDateFnsAdapter, AdfDateTimeFnsAdapter, DateFnsUtils } from '@alfresco/adf-core';
import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher';
import { ReplaySubject } from 'rxjs';
import { map } from 'rxjs/operators';
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimepickerModule } from '@mat-datetimepicker/core';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { endOfMinute, isBefore, isValid, parseISO, startOfMinute } from 'date-fns';
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 { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/core";
import * as i2 from "@mat-datetimepicker/core";
import * as i3 from "@angular/common";
import * as i4 from "@angular/forms";
import * as i5 from "@angular/material/form-field";
import * as i6 from "@angular/material/input";
import * as i7 from "@ngx-translate/core";
export const DEFAULT_DATETIME_FORMAT = 'dd/MM/yyyy HH:mm';
export class SearchDatetimeRangeComponent {
constructor(dateAdapter, dateTimeAdapter) {
this.dateAdapter = dateAdapter;
this.dateTimeAdapter = dateTimeAdapter;
this.matcher = new LiveErrorStateMatcher();
this.isActive = false;
this.displayValue$ = new ReplaySubject(1);
this.destroyRef = inject(DestroyRef);
}
getFromValidationMessage() {
return this.from.hasError('invalidOnChange') || this.hasParseError(this.from)
? 'SEARCH.FILTER.VALIDATION.INVALID-DATETIME'
: this.from.hasError('matDatepickerMax')
? 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATETIME'
: this.from.hasError('required')
? 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE'
: '';
}
getToValidationMessage() {
return this.to.hasError('invalidOnChange') || this.hasParseError(this.to)
? 'SEARCH.FILTER.VALIDATION.INVALID-DATETIME'
: this.to.hasError('matDatepickerMin')
? 'SEARCH.FILTER.VALIDATION.NO-DAYS'
: this.to.hasError('matDatepickerMax')
? 'SEARCH.FILTER.VALIDATION.BEYOND-MAX-DATETIME'
: this.to.hasError('required')
? 'SEARCH.FILTER.VALIDATION.REQUIRED-VALUE'
: '';
}
ngOnInit() {
this.datetimePickerFormat = this.settings?.datetimeFormat ? this.settings.datetimeFormat : DEFAULT_DATETIME_FORMAT;
const dateAdapter = this.dateAdapter;
dateAdapter.displayFormat = this.datetimePickerFormat;
const dateTimeAdapter = this.dateTimeAdapter;
dateTimeAdapter.displayFormat = this.datetimePickerFormat;
const validators = Validators.compose([Validators.required]);
if (this.settings?.maxDatetime) {
this.maxDatetime = new Date(this.settings.maxDatetime);
}
if (this.startValue) {
const splitValue = this.startValue.split('||');
const fromValue = this.dateAdapter.parse(splitValue[0], this.datetimePickerFormat);
const toValue = this.dateAdapter.parse(splitValue[1], this.datetimePickerFormat);
this.from = new FormControl(fromValue, validators);
this.to = new FormControl(toValue, validators);
}
else {
this.from = new FormControl(null, validators);
this.to = new FormControl(null, validators);
}
this.form = new FormGroup({
from: this.from,
to: this.to
});
this.setFromMaxDatetime();
this.enableChangeUpdate = this.settings?.allowUpdateOnChange ?? true;
this.context.populateFilters
.asObservable()
.pipe(map((filtersQueries) => filtersQueries[this.id]), takeUntilDestroyed(this.destroyRef))
.subscribe((filterQuery) => {
if (filterQuery) {
const start = parseISO(filterQuery.start);
const end = parseISO(filterQuery.end);
this.form.patchValue({ from: start, to: end });
this.form.markAsDirty();
this.apply({ from: start, to: end }, true, false);
}
else {
this.reset();
}
this.context.filterLoaded.next();
});
}
apply(model, isValidValue, updateContext = true) {
if (isValidValue && this.id && this.context && this.settings && this.settings.field) {
this.isActive = true;
const start = DateFnsUtils.utcToLocal(startOfMinute(model.from)).toISOString();
const end = DateFnsUtils.utcToLocal(endOfMinute(model.to)).toISOString();
this.context.queryFragments[this.id] = `${this.settings.field}:['${start}' TO '${end}']`;
const filterParam = this.context.filterRawParams[this.id] ?? {};
this.context.filterRawParams[this.id] = filterParam;
filterParam.start = start;
filterParam.end = end;
this.updateDisplayValue();
if (updateContext) {
this.context.update();
}
}
}
submitValues() {
this.apply(this.form.value, this.form.valid);
}
hasValidValue() {
return this.form.valid;
}
getCurrentValue() {
return {
from: this.dateAdapter.format(this.form.value.from, this.datetimePickerFormat),
to: this.dateAdapter.format(this.form.value.to, this.datetimePickerFormat)
};
}
updateDisplayValue() {
if (this.form.invalid || this.form.pristine) {
this.displayValue$.next('');
}
else {
this.displayValue$.next(`${this.dateAdapter.format(this.form.value.from, this.datetimePickerFormat)} - ${this.dateAdapter.format(this.form.value.to, this.datetimePickerFormat)}`);
}
}
setValue(parsedDate) {
const splitValue = parsedDate.split('||');
const fromValue = this.dateAdapter.parse(splitValue[0], this.datetimePickerFormat);
const toValue = this.dateAdapter.parse(splitValue[1], this.datetimePickerFormat);
this.from.setValue(fromValue);
this.from.markAsDirty();
this.from.markAsTouched();
this.to.setValue(toValue);
this.to.markAsDirty();
this.to.markAsTouched();
this.submitValues();
}
clear() {
this.isActive = false;
this.form.reset({
from: null,
to: null
});
if (this.id && this.context) {
this.context.queryFragments[this.id] = '';
this.context.filterRawParams[this.id] = undefined;
}
if (this.id && this.context && this.enableChangeUpdate) {
this.updateQuery();
}
this.setFromMaxDatetime();
}
reset() {
this.clear();
this.updateQuery();
}
updateQuery() {
if (this.id && this.context) {
this.updateDisplayValue();
this.context.update();
}
}
onChangedHandler(event, formControl) {
const formatDate = event.value;
if (isValid(formatDate)) {
formControl.setValue(formatDate);
}
else if (formatDate) {
formControl.setErrors({
invalidOnChange: true
});
}
this.setFromMaxDatetime();
}
hasParseError(formControl) {
return formControl.hasError('matDatepickerParse') && formControl.getError('matDatepickerParse').text;
}
forcePlaceholder(event) {
event.target.click();
}
setFromMaxDatetime() {
this.fromMaxDatetime = !this.to.value || (this.maxDatetime && isBefore(this.maxDatetime, this.to.value)) ? this.maxDatetime : this.to.value;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SearchDatetimeRangeComponent, deps: [{ token: i1.DateAdapter }, { token: i2.DatetimeAdapter }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: SearchDatetimeRangeComponent, isStandalone: true, selector: "adf-search-datetime-range", host: { classAttribute: "adf-search-date-range" }, providers: [
{ provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS },
{ provide: MAT_DATETIME_FORMATS, useValue: ADF_DATETIME_FORMATS },
{ provide: DateAdapter, useClass: AdfDateFnsAdapter },
{ provide: DatetimeAdapter, useClass: AdfDateTimeFnsAdapter }
], ngImport: i0, template: "<form [formGroup]=\"form\" novalidate (ngSubmit)=\"apply(form.value, form.valid)\">\n <mat-form-field>\n <input matInput\n (input)=\"forcePlaceholder($event)\"\n [formControl]=\"from\"\n [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.FROM-DATE' | translate }}\"\n [matDatetimepicker]=\"fromDatetimePicker\"\n [max]=\"fromMaxDatetime\"\n (dateChange)=\"onChangedHandler($event, from)\"\n data-automation-id=\"datetime-range-from-input\">\n <mat-datetimepicker-toggle matSuffix [for]=\"fromDatetimePicker\" data-automation-id=\"datetime-range-from-date-toggle\" />\n <mat-datetimepicker #fromDatetimePicker color=\"accent\" type=\"datetime\" />\n <mat-error *ngIf=\"from.invalid\" data-automation-id=\"datetime-range-from-error\">\n {{ getFromValidationMessage() | translate: { requiredFormat: datetimePickerFormat } }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input matInput\n (input)=\"forcePlaceholder($event)\"\n [formControl]=\"to\"\n [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.TO-DATE' | translate }}\"\n [matDatetimepicker]=\"toDatetimePicker\"\n [min]=\"from.value\"\n [max]=\"maxDatetime\"\n (dateChange)=\"onChangedHandler($event, to)\"\n data-automation-id=\"datetime-range-to-input\">\n <mat-datetimepicker-toggle matSuffix [for]=\"toDatetimePicker\" data-automation-id=\"datetime-range-to-date-toggle\" />\n <mat-datetimepicker #toDatetimePicker color=\"accent\" type=\"datetime\" />\n <mat-error *ngIf=\"to.invalid\" data-automation-id=\"datetime-range-to-error\">\n {{ getToValidationMessage() | translate: { requiredFormat: datetimePickerFormat } }}\n </mat-error>\n </mat-form-field>\n</form>\n", styles: [".adf-search-date-range>form{display:inline-flex;flex-direction:column;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.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: i7.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatDatetimepickerModule }, { kind: "component", type: i2.MatDatetimepickerComponent, selector: "mat-datetimepicker", inputs: ["multiYearSelector", "twelvehour", "startView", "mode", "timeInterval", "ariaNextMonthLabel", "ariaPrevMonthLabel", "ariaNextYearLabel", "ariaPrevYearLabel", "preventSameDateTimeSelection", "panelClass", "startAt", "openOnFocus", "type", "touchUi", "disabled"], outputs: ["selectedChanged", "opened", "closed", "viewChanged"], exportAs: ["matDatetimepicker"] }, { kind: "component", type: i2.MatDatetimepickerToggleComponent, selector: "mat-datetimepicker-toggle", inputs: ["for", "disabled"], exportAs: ["matDatetimepickerToggle"] }, { kind: "directive", type: i2.MatDatetimepickerInputDirective, selector: "input[matDatetimepicker]", inputs: ["matDatetimepicker", "matDatepickerFilter", "value", "min", "max", "disabled"], outputs: ["dateChange", "dateInput"], exportAs: ["matDatepickerInput"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SearchDatetimeRangeComponent, decorators: [{
type: Component,
args: [{ selector: 'adf-search-datetime-range', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, TranslateModule, MatDatetimepickerModule], providers: [
{ provide: MAT_DATE_FORMATS, useValue: ADF_DATE_FORMATS },
{ provide: MAT_DATETIME_FORMATS, useValue: ADF_DATETIME_FORMATS },
{ provide: DateAdapter, useClass: AdfDateFnsAdapter },
{ provide: DatetimeAdapter, useClass: AdfDateTimeFnsAdapter }
], encapsulation: ViewEncapsulation.None, host: { class: 'adf-search-date-range' }, template: "<form [formGroup]=\"form\" novalidate (ngSubmit)=\"apply(form.value, form.valid)\">\n <mat-form-field>\n <input matInput\n (input)=\"forcePlaceholder($event)\"\n [formControl]=\"from\"\n [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.FROM-DATE' | translate }}\"\n [matDatetimepicker]=\"fromDatetimePicker\"\n [max]=\"fromMaxDatetime\"\n (dateChange)=\"onChangedHandler($event, from)\"\n data-automation-id=\"datetime-range-from-input\">\n <mat-datetimepicker-toggle matSuffix [for]=\"fromDatetimePicker\" data-automation-id=\"datetime-range-from-date-toggle\" />\n <mat-datetimepicker #fromDatetimePicker color=\"accent\" type=\"datetime\" />\n <mat-error *ngIf=\"from.invalid\" data-automation-id=\"datetime-range-from-error\">\n {{ getFromValidationMessage() | translate: { requiredFormat: datetimePickerFormat } }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field>\n <input matInput\n (input)=\"forcePlaceholder($event)\"\n [formControl]=\"to\"\n [errorStateMatcher]=\"matcher\"\n placeholder=\"{{ 'SEARCH.FILTER.RANGE.TO-DATE' | translate }}\"\n [matDatetimepicker]=\"toDatetimePicker\"\n [min]=\"from.value\"\n [max]=\"maxDatetime\"\n (dateChange)=\"onChangedHandler($event, to)\"\n data-automation-id=\"datetime-range-to-input\">\n <mat-datetimepicker-toggle matSuffix [for]=\"toDatetimePicker\" data-automation-id=\"datetime-range-to-date-toggle\" />\n <mat-datetimepicker #toDatetimePicker color=\"accent\" type=\"datetime\" />\n <mat-error *ngIf=\"to.invalid\" data-automation-id=\"datetime-range-to-error\">\n {{ getToValidationMessage() | translate: { requiredFormat: datetimePickerFormat } }}\n </mat-error>\n </mat-form-field>\n</form>\n", styles: [".adf-search-date-range>form{display:inline-flex;flex-direction:column;width:100%}\n"] }]
}], ctorParameters: () => [{ type: i1.DateAdapter }, { type: i2.DatetimeAdapter }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWRhdGV0aW1lLXJhbmdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYi9jb250ZW50LXNlcnZpY2VzL3NyYy9saWIvc2VhcmNoL2NvbXBvbmVudHMvc2VhcmNoLWRhdGV0aW1lLXJhbmdlL3NlYXJjaC1kYXRldGltZS1yYW5nZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3NlYXJjaC9jb21wb25lbnRzL3NlYXJjaC1kYXRldGltZS1yYW5nZS9zZWFyY2gtZGF0ZXRpbWUtcmFuZ2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFVLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pGLE9BQU8sRUFDSCxnQkFBZ0IsRUFDaEIsb0JBQW9CLEVBQ3BCLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsWUFBWSxFQUNmLE1BQU0sb0JBQW9CLENBQUM7QUFJNUIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUNILGVBQWUsRUFDZixvQkFBb0IsRUFFcEIsdUJBQXVCLEVBQzFCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZFLE9BQU8s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QyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO0lBQ2hKLENBQUM7OEdBbE5RLDRCQUE0QjtrR0FBNUIsNEJBQTRCLDJIQVQxQjtZQUNQLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRTtZQUN6RCxFQUFFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxRQUFRLEVBQUUsb0JBQW9CLEVBQUU7WUFDakUsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRTtZQUNyRCxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLHFCQUFxQixFQUFFO1NBQ2hFLDBCQ3JFTCwwL0RBb0NBLDRJRHlCYyxZQUFZLGtJQUFFLG1CQUFtQiwrOUJBQUUsa0JBQWtCLHVjQUFFLGNBQWMsMFdBQUUsZUFBZSwyRkFBRSx1QkFBdUI7OzJGQVloSCw0QkFBNEI7a0JBZnhDLFNBQVM7K0JBQ0ksMkJBQTJCLGNBQ3pCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLHVCQUF1QixDQUFDLGFBRy9HO3dCQUNQLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRTt3QkFDekQsRUFBRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLG9CQUFvQixFQUFFO3dCQUNqRSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixFQUFFO3dCQUNyRCxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLHFCQUFxQixFQUFFO3FCQUNoRSxpQkFDYyxpQkFBaUIsQ0FBQyxJQUFJLFFBQy9CLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IMKpIDIwMDUtMjAyNSBIeWxhbmQgU29mdHdhcmUsIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBDb21wb25lbnQsIERlc3Ryb3lSZWYsIGluamVjdCwgT25Jbml0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gICAgQURGX0RBVEVfRk9STUFUUyxcbiAgICBBREZfREFURVRJTUVfRk9STUFUUyxcbiAgICBBZGZEYXRlRm5zQWRhcHRlcixcbiAgICBBZGZEYXRlVGltZUZuc0FkYXB0ZXIsXG4gICAgRGF0ZUZuc1V0aWxzXG59IGZyb20gJ0BhbGZyZXNjby9hZGYtY29yZSc7XG5pbXBvcnQgeyBTZWFyY2hXaWRnZXQgfSBmcm9tICcuLi8uLi9tb2RlbHMvc2VhcmNoLXdpZGdldC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgU2VhcmNoV2lkZ2V0U2V0dGluZ3MgfSBmcm9tICcuLi8uLi9tb2RlbHMvc2VhcmNoLXdpZGdldC1zZXR0aW5ncy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgU2VhcmNoUXVlcnlCdWlsZGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3NlYXJjaC1xdWVyeS1idWlsZGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGl2ZUVycm9yU3RhdGVNYXRjaGVyIH0gZnJvbSAnLi4vLi4vZm9ybXMvbGl2ZS1lcnJvci1zdGF0ZS1tYXRjaGVyJztcbmltcG9ydCB7IFJlcGxheVN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gICAgRGF0ZXRpbWVBZGFwdGVyLFxuICAgIE1BVF9EQVRFVElNRV9GT1JNQVRTLFxuICAgIE1hdERhdGV0aW1lcGlja2VySW5wdXRFdmVudCxcbiAgICBNYXREYXRldGltZXBpY2tlck1vZHVsZVxufSBmcm9tICdAbWF0LWRhdGV0aW1lcGlja2VyL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZUFkYXB0ZXIsIE1BVF9EQVRFX0ZPUk1BVFMgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7IGVuZE9mTWludXRlLCBpc0JlZm9yZSwgaXNWYWxpZCwgcGFyc2VJU08sIHN0YXJ0T2ZNaW51dGUgfSBmcm9tICdkYXRlLWZucyc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERhdGV0aW1lUmFuZ2VWYWx1ZSB7XG4gICAgZnJvbTogc3RyaW5nO1xuICAgIHRvOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBGb3JtUHJvcHMge1xuICAgIGZyb206IEZvcm1Db250cm9sPERhdGU+O1xuICAgIHRvOiBGb3JtQ29udHJvbDxEYXRlPjtcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfREFURVRJTUVfRk9STUFUOiBzdHJpbmcgPSAnZGQvTU0veXl5eSBISDptbSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYWRmLXNlYXJjaC1kYXRldGltZS1yYW5nZScsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlLCBNYXRGb3JtRmllbGRNb2R1bGUsIE1hdElucHV0TW9kdWxlLCBUcmFuc2xhdGVNb2R1bGUsIE1hdERhdGV0aW1lcGlja2VyTW9kdWxlXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoLWRhdGV0aW1lLXJhbmdlLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9zZWFyY2gtZGF0ZXRpbWUtcmFuZ2UuY29tcG9uZW50LnNjc3MnXSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgeyBwcm92aWRlOiBNQVRfREFURV9GT1JNQVRTLCB1c2VWYWx1ZTogQURGX0RBVEVfRk9STUFUUyB9LFxuICAgICAgICB7IHByb3ZpZGU6IE1BVF9EQVRFVElNRV9GT1JNQVRTLCB1c2VWYWx1ZTogQURGX0RBVEVUSU1FX0ZPUk1BVFMgfSxcbiAgICAgICAgeyBwcm92aWRlOiBEYXRlQWRhcHRlciwgdXNlQ2xhc3M6IEFkZkRhdGVGbnNBZGFwdGVyIH0sXG4gICAgICAgIHsgcHJvdmlkZTogRGF0ZXRpbWVBZGFwdGVyLCB1c2VDbGFzczogQWRmRGF0ZVRpbWVGbnNBZGFwdGVyIH1cbiAgICBdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gICAgaG9zdDogeyBjbGFzczogJ2FkZi1zZWFyY2gtZGF0ZS1yYW5nZScgfVxufSlcbmV4cG9ydCBjbGFzcyBTZWFyY2hEYXRldGltZVJhbmdlQ29tcG9uZW50IGltcGxlbWVudHMgU2VhcmNoV2lkZ2V0LCBPbkluaXQge1xuICAgIGZyb206IEZvcm1Db250cm9sPERhdGU+O1xuICAgIHRvOiBGb3JtQ29udHJvbDxEYXRlPjtcblxuICAgIGZvcm06IEZvcm1Hcm91cDxGb3JtUHJvcHM+O1xuICAgIG1hdGNoZXIgPSBuZXcgTGl2ZUVycm9yU3RhdGVNYXRjaGVyKCk7XG5cbiAgICBpZDogc3RyaW5nO1xuICAgIHNldHRpbmdzPzogU2VhcmNoV2lkZ2V0U2V0dGluZ3M7XG4gICAgY29udGV4dD86IFNlYXJjaFF1ZXJ5QnVpbGRlclNlcnZpY2U7XG4gICAgZGF0ZXRpbWVQaWNrZXJGb3JtYXQ6IHN0cmluZztcbiAgICBtYXhEYXRldGltZTogYW55O1xuICAgIGZyb21NYXhEYXRldGltZTogYW55O1xuICAgIGlzQWN0aXZlID0gZmFsc2U7XG4gICAgc3RhcnRWYWx1ZTogYW55O1xuICAgIGVuYWJsZUNoYW5nZVVwZGF0ZTogYm9vbGVhbjtcbiAgICBkaXNwbGF5VmFsdWUkID0gbmV3IFJlcGxheVN1YmplY3Q8c3RyaW5nPigxKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0ZUFkYXB0ZXI6IERhdGVBZGFwdGVyPERhdGU+LCBwcml2YXRlIGRhdGVUaW1lQWRhcHRlcjogRGF0ZXRpbWVBZGFwdGVyPERhdGU+KSB7fVxuXG4gICAgZ2V0RnJvbVZhbGlkYXRpb25NZXNzYWdlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb20uaGFzRXJyb3IoJ2ludmFsaWRPbkNoYW5nZScpIHx8IHRoaXMuaGFzUGFyc2VFcnJvcih0aGlzLmZyb20pXG4gICAgICAgICAgICA/ICdTRUFSQ0guRklMVEVSLlZBTElEQVRJT04uSU5WQUxJRC1EQVRFVElNRSdcbiAgICAgICAgICAgIDogdGhpcy5mcm9tLmhhc0Vycm9yKCdtYXREYXRlcGlja2VyTWF4JylcbiAgICAgICAgICAgID8gJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5CRVlPTkQtTUFYLURBVEVUSU1FJ1xuICAgICAgICAgICAgOiB0aGlzLmZyb20uaGFzRXJyb3IoJ3JlcXVpcmVkJylcbiAgICAgICAgICAgID8gJ1NFQVJDSC5GSUxURVIuVkFMSURBVElPTi5SRVFVSVJFRC1WQUxVRSdcbiAgICAgICAgICAgIDogJyc7XG4gICAgfVxuXG4gICAgZ2V0VG9WYWxpZGF0aW9uTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy50by5oYXNFcnJvcignaW52YWxpZE9uQ2hhbmdlJykgfHwgdGhpcy5oYXNQYXJzZUVycm9yKHRoaXMudG8pXG4gICAgICAgICAgICA/ICdTRUFSQ0guRklMVEVSLlZBTElEQVRJT04uSU5WQUxJRC1EQVRFVElNRSdcbiAgICAgICAgICAgIDogdGhpcy50by5oYXNFcnJvcignbWF0RGF0ZXBpY2tlck1pbicpXG4gICAgICAgICAgICA/ICdTRUFSQ0guRklMVEVSLlZBTElEQVRJT04uTk8tREFZUydcbiAgICAgICAgICAgIDogdGhpcy50by5oYXNFcnJvcignbWF0RGF0ZXBpY2tlck1heCcpXG4gICAgICAgICAgICA/ICdTRUFSQ0guRklMVEVSLlZBTElEQVRJT04uQkVZT05ELU1BWC1EQVRFVElNRSdcbiAgICAgICAgICAgIDogdGhpcy50by5oYXNFcnJvcigncmVxdWlyZWQnKVxuICAgICAgICAgICAgPyAnU0VBUkNILkZJTFRFUi5WQUxJREFUSU9OLlJFUVVJUkVELVZBTFVFJ1xuICAgICAgICAgICAgOiAnJztcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5kYXRldGltZVBpY2tlckZvcm1hdCA9IHRoaXMuc2V0dGluZ3M/LmRhdGV0aW1lRm9ybWF0ID8gdGhpcy5zZXR0aW5ncy5kYXRldGltZUZvcm1hdCA6IERFRkFVTFRfREFURVRJTUVfRk9STUFUO1xuXG4gICAgICAgIGNvbnN0IGRhdGVBZGFwdGVyID0gdGhpcy5kYXRlQWRhcHRlciBhcyBBZGZEYXRlRm5zQWRhcHRlcjtcbiAgICAgICAgZGF0ZUFkYXB0ZXIuZGlzcGxheUZvcm1hdCA9IHRoaXMuZGF0ZXRpbWVQaWNrZXJGb3JtYXQ7XG5cbiAgICAgICAgY29uc3QgZGF0ZVRpbWVBZGFwdGVyID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIgYXMgQWRmRGF0ZVRpbWVGbnNBZGFwdGVyO1xuICAgICAgICBkYXRlVGltZUFkYXB0ZXIuZGlzcGxheUZvcm1hdCA9IHRoaXMuZGF0ZXRpbWVQaWNrZXJGb3JtYXQ7XG5cbiAgICAgICAgY29uc3QgdmFsaWRhdG9ycyA9IFZhbGlkYXRvcnMuY29tcG9zZShbVmFsaWRhdG9ycy5yZXF1aXJlZF0pO1xuXG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzPy5tYXhEYXRldGltZSkge1xuICAgICAgICAgICAgdGhpcy5tYXhEYXRldGltZSA9IG5ldyBEYXRlKHRoaXMuc2V0dGluZ3MubWF4RGF0ZXRpbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhcnRWYWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgc3BsaXRWYWx1ZSA9IHRoaXMuc3RhcnRWYWx1ZS5zcGxpdCgnfHwnKTtcbiAgICAgICAgICAgIGNvbnN0IGZyb21WYWx1ZSA9IHRoaXMuZGF0ZUFkYXB0ZXIucGFyc2Uoc3BsaXRWYWx1ZVswXSwgdGhpcy5kYXRldGltZVBpY2tlckZvcm1hdCk7XG4gICAgICAgICAgICBjb25zdCB0b1ZhbHVlID0gdGhpcy5kYXRlQWRhcHRlci5wYXJzZShzcGxpdFZhbHVlWzFdLCB0aGlzLmRhdGV0aW1lUGlja2VyRm9ybWF0KTtcbiAgICAgICAgICAgIHRoaXMuZnJvbSA9IG5ldyBGb3JtQ29udHJvbDxEYXRlPihmcm9tVmFsdWUsIHZhbGlkYXRvcnMpO1xuICAgICAgICAgICAgdGhpcy50byA9IG5ldyBGb3JtQ29udHJvbDxEYXRlPih0b1ZhbHVlLCB2YWxpZGF0b3JzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZnJvbSA9IG5ldyBGb3JtQ29udHJvbDxEYXRlPihudWxsLCB2YWxpZGF0b3JzKTtcbiAgICAgICAgICAgIHRoaXMudG8gPSBuZXcgRm9ybUNvbnRyb2w8RGF0ZT4obnVsbCwgdmFsaWRhdG9ycyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvcm0gPSBuZXcgRm9ybUdyb3VwPEZvcm1Qcm9wcz4oe1xuICAgICAgICAgICAgZnJvbTogdGhpcy5mcm9tLFxuICAgICAgICAgICAgdG86IHRoaXMudG9cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zZXRGcm9tTWF4RGF0ZXRpbWUoKTtcbiAgICAgICAgdGhpcy5lbmFibGVDaGFuZ2VVcGRhdGUgPSB0aGlzLnNldHRpbmdzPy5hbGxvd1VwZGF0ZU9uQ2hhbmdlID8/IHRydWU7XG4gICAgICAgIHRoaXMuY29udGV4dC5wb3B1bGF0ZUZpbHRlcnNcbiAgICAgICAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgbWFwKChmaWx0ZXJzUXVlcmllcykgPT4gZmlsdGVyc1F1ZXJpZXNbdGhpcy5pZF0pLFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChmaWx0ZXJRdWVyeSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJRdWVyeSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGFydCA9IHBhcnNlSVNPKGZpbHRlclF1ZXJ5LnN0YXJ0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5kID0gcGFyc2VJU08oZmlsdGVyUXVlcnkuZW5kKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyBmcm9tOiBzdGFydCwgdG86IGVuZCB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHkoeyBmcm9tOiBzdGFydCwgdG86IGVuZCB9LCB0cnVlLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuZmlsdGVyTG9hZGVkLm5leHQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFwcGx5KG1vZGVsOiBQYXJ0aWFsPHsgZnJvbTogRGF0ZTsgdG86IERhdGUgfT4sIGlzVmFsaWRWYWx1ZTogYm9vbGVhbiwgdXBkYXRlQ29udGV4dCA9IHRydWUpIHtcbiAgICAgICAgaWYgKGlzVmFsaWRWYWx1ZSAmJiB0aGlzLmlkICYmIHRoaXMuY29udGV4dCAmJiB0aGlzLnNldHRpbmdzICYmIHRoaXMuc2V0dGluZ3MuZmllbGQpIHtcbiAgICAgICAgICAgIHRoaXMuaXNBY3RpdmUgPSB0cnVlO1xuXG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IERhdGVGbnNVdGlscy51dGNUb0xvY2FsKHN0YXJ0T2ZNaW51dGUobW9kZWwuZnJvbSkpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSBEYXRlRm5zVXRpbHMudXRjVG9Mb2NhbChlbmRPZk1pbnV0ZShtb2RlbC50bykpLnRvSVNPU3RyaW5nKCk7XG5cbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5xdWVyeUZyYWdtZW50c1t0aGlzLmlkXSA9IGAke3RoaXMuc2V0dGluZ3MuZmllbGR9OlsnJHtzdGFydH0nIFRPICcke2VuZH0nXWA7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJQYXJhbSA9IHRoaXMuY29udGV4dC5maWx0ZXJSYXdQYXJhbXNbdGhpcy5pZF0gPz8ge307XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuZmlsdGVyUmF3UGFyYW1zW3RoaXMuaWRdID0gZmlsdGVyUGFyYW07XG4gICAgICAgICAgICBmaWx0ZXJQYXJhbS5zdGFydCA9IHN0YXJ0O1xuICAgICAgICAgICAgZmlsdGVyUGFyYW0uZW5kID0gZW5kO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVEaXNwbGF5VmFsdWUoKTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3VibWl0VmFsdWVzKCkge1xuICAgICAgICB0aGlzLmFwcGx5KHRoaXMuZm9ybS52YWx1ZSwgdGhpcy5mb3JtLnZhbGlkKTtcbiAgICB9XG5cbiAgICBoYXNWYWxpZFZhbHVlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtLnZhbGlkO1xuICAgIH1cblxuICAgIGdldEN1cnJlbnRWYWx1ZSgpOiBEYXRldGltZVJhbmdlVmFsdWUge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZnJvbTogdGhpcy5kYXRlQWRhcHRlci5mb3JtYXQodGhpcy5mb3JtLnZhbHVlLmZyb20sIHRoaXMuZGF0ZXRpbWVQaWNrZXJGb3JtYXQpLFxuICAgICAgICAgICAgdG86IHRoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KHRoaXMuZm9ybS52YWx1ZS50bywgdGhpcy5kYXRldGltZVBpY2tlckZvcm1hdClcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB1cGRhdGVEaXNwbGF5VmFsdWUoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCB8fCB0aGlzLmZvcm0ucHJpc3RpbmUpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheVZhbHVlJC5uZXh0KCcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheVZhbHVlJC5uZXh0KFxuICAgICAgICAgICAgICAgIGAke3RoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KHRoaXMuZm9ybS52YWx1ZS5mcm9tLCB0aGlzLmRhdGV0aW1lUGlja2VyRm9ybWF0KX0gLSAke3RoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0udmFsdWUudG8sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0ZXRpbWVQaWNrZXJGb3JtYXRcbiAgICAgICAgICAgICAgICApfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRWYWx1ZShwYXJzZWREYXRlOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgc3BsaXRWYWx1ZSA9IHBhcnNlZERhdGUuc3BsaXQoJ3x8Jyk7XG4gICAgICAgIGNvbnN0IGZyb21WYWx1ZSA9IHRoaXMuZGF0ZUFkYXB0ZXIucGFyc2Uoc3BsaXRWYWx1ZVswXSwgdGhpcy5kYXRldGltZVBpY2tlckZvcm1hdCk7XG4gICAgICAgIGNvbnN0IHRvVmFsdWUgPSB0aGlzLmRhdGVBZGFwdGVyLnBhcnNlKHNwbGl0VmFsdWVbMV0sIHRoaXMuZGF0ZXRpbWVQaWNrZXJGb3JtYXQpO1xuICAgICAgICB0aGlzLmZyb20uc2V0VmFsdWUoZnJvbVZhbHVlKTtcbiAgICAgICAgdGhpcy5mcm9tLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgIHRoaXMuZnJvbS5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgIHRoaXMudG8uc2V0VmFsdWUodG9WYWx1ZSk7XG4gICAgICAgIHRoaXMudG8ubWFya0FzRGlydHkoKTtcbiAgICAgICAgdGhpcy50by5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgIHRoaXMuc3VibWl0VmFsdWVzKCk7XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuaXNBY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5mb3JtLnJlc2V0KHtcbiAgICAgICAgICAgIGZyb206IG51bGwsXG4gICAgICAgICAgICB0bzogbnVsbFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuaWQgJiYgdGhpcy5jb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucXVlcnlGcmFnbWVudHNbdGhpcy5pZF0gPSAnJztcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5maWx0ZXJSYXdQYXJhbXNbdGhpcy5pZF0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pZCAmJiB0aGlzLmNvbnRleHQgJiYgdGhpcy5lbmFibGVDaGFuZ2VVcGRhdGUpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUXVlcnkoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldEZyb21NYXhEYXRldGltZSgpO1xuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMudXBkYXRlUXVlcnkoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVF1ZXJ5KCkge1xuICAgICAgICBpZiAodGhpcy5pZCAmJiB0aGlzLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRGlzcGxheVZhbHVlKCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkNoYW5nZWRIYW5kbGVyKGV2ZW50OiBNYXREYXRldGltZXBpY2tlcklucHV0RXZlbnQ8RGF0ZT4sIGZvcm1Db250cm9sOiBGb3JtQ29udHJvbDxEYXRlPikge1xuICAgICAgICBjb25zdCBmb3JtYXREYXRlID0gZXZlbnQudmFsdWU7XG5cbiAgICAgICAgaWYgKGlzVmFsaWQoZm9ybWF0RGF0ZSkpIHtcbiAgICAgICAgICAgIGZvcm1Db250cm9sLnNldFZhbHVlKGZvcm1hdERhdGUpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdERhdGUpIHtcbiAgICAgICAgICAgIGZvcm1Db250cm9sLnNldEVycm9ycyh7XG4gICAgICAgICAgICAgICAgaW52YWxpZE9uQ2hhbmdlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0RnJvbU1heERhdGV0aW1lKCk7XG4gICAgfVxuXG4gICAgaGFzUGFyc2VFcnJvcihmb3JtQ29udHJvbDogRm9ybUNvbnRyb2w8RGF0ZT4pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZvcm1Db250cm9sLmhhc0Vycm9yKCdtYXREYXRlcGlja2VyUGFyc2UnKSAmJiBmb3JtQ29udHJvbC5nZXRFcnJvcignbWF0RGF0ZXBpY2tlclBhcnNlJykudGV4dDtcbiAgICB9XG5cbiAgICBmb3JjZVBsYWNlaG9sZGVyKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgZXZlbnQudGFyZ2V0LmNsaWNrKCk7XG4gICAgfVxuXG4gICAgc2V0RnJvbU1heERhdGV0aW1lKCkge1xuICAgICAgICB0aGlzLmZyb21NYXhEYXRldGltZSA9ICF0aGlzLnRvLnZhbHVlIHx8ICh0aGlzLm1heERhdGV0aW1lICYmIGlzQmVmb3JlKHRoaXMubWF4RGF0ZXRpbWUsIHRoaXMudG8udmFsdWUpKSA/IHRoaXMubWF4RGF0ZXRpbWUgOiB0aGlzLnRvLnZhbHVlO1xuICAgIH1cbn1cbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIG5vdmFsaWRhdGUgKG5nU3VibWl0KT1cImFwcGx5KGZvcm0udmFsdWUsIGZvcm0udmFsaWQpXCI+XG4gICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8aW5wdXQgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAoaW5wdXQpPVwiZm9yY2VQbGFjZWhvbGRlcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZnJvbVwiXG4gICAgICAgICAgICAgICAgW2Vycm9yU3RhdGVNYXRjaGVyXT1cIm1hdGNoZXJcIlxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ1NFQVJDSC5GSUxURVIuUkFOR0UuRlJPTS1EQVRFJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICAgICAgW21hdERhdGV0aW1lcGlja2VyXT1cImZyb21EYXRldGltZVBpY2tlclwiXG4gICAgICAgICAgICAgICAgW21heF09XCJmcm9tTWF4RGF0ZXRpbWVcIlxuICAgICAgICAgICAgICAgIChkYXRlQ2hhbmdlKT1cIm9uQ2hhbmdlZEhhbmRsZXIoJGV2ZW50LCBmcm9tKVwiXG4gICAgICAgICAgICAgICAgZGF0YS1hdXRvbWF0aW9uLWlkPVwiZGF0ZXRpbWUtcmFuZ2UtZnJvbS1pbnB1dFwiPlxuICAgICAgICA8bWF0LWRhdGV0aW1lcGlja2VyLXRvZ2dsZSBtYXRTdWZmaXggW2Zvcl09XCJmcm9tRGF0ZXRpbWVQaWNrZXJcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJkYXRldGltZS1yYW5nZS1mcm9tLWRhdGUtdG9nZ2xlXCIgLz5cbiAgICAgICAgPG1hdC1kYXRldGltZXBpY2tlciAjZnJvbURhdGV0aW1lUGlja2VyIGNvbG9yPVwiYWNjZW50XCIgdHlwZT1cImRhdGV0aW1lXCIgLz5cbiAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZyb20uaW52YWxpZFwiIGRhdGEtYXV0b21hdGlvbi1pZD1cImRhdGV0aW1lLXJhbmdlLWZyb20tZXJyb3JcIj5cbiAgICAgICAgICAgIHt7IGdldEZyb21WYWxpZGF0aW9uTWVzc2FnZSgpIHwgdHJhbnNsYXRlOiB7IHJlcXVpcmVkRm9ybWF0OiBkYXRldGltZVBpY2tlckZvcm1hdCB9IH19XG4gICAgICAgIDwvbWF0LWVycm9yPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dFxuICAgICAgICAgICAgICAgIChpbnB1dCk9XCJmb3JjZVBsYWNlaG9sZGVyKCRldmVudClcIlxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJ0b1wiXG4gICAgICAgICAgICAgICAgW2Vycm9yU3RhdGVNYXRjaGVyXT1cIm1hdGNoZXJcIlxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ1NFQVJDSC5GSUxURVIuUkFOR0UuVE8tREFURScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICAgIFttYXREYXRldGltZXBpY2tlcl09XCJ0b0RhdGV0aW1lUGlja2VyXCJcbiAgICAgICAgICAgICAgICBbbWluXT1cImZyb20udmFsdWVcIlxuICAgICAgICAgICAgICAgIFttYXhdPVwibWF4RGF0ZXRpbWVcIlxuICAgICAgICAgICAgICAgIChkYXRlQ2hhbmdlKT1cIm9uQ2hhbmdlZEhhbmRsZXIoJGV2ZW50LCB0bylcIlxuICAgICAgICAgICAgICAgIGRhdGEtYXV0b21hdGlvbi1pZD1cImRhdGV0aW1lLXJhbmdlLXRvLWlucHV0XCI+XG4gICAgICAgIDxtYXQtZGF0ZXRpbWVwaWNrZXItdG9nZ2xlIG1hdFN1ZmZpeCBbZm9yXT1cInRvRGF0ZXRpbWVQaWNrZXJcIiBkYXRhLWF1dG9tYXRpb24taWQ9XCJkYXRldGltZS1yYW5nZS10by1kYXRlLXRvZ2dsZVwiIC8+XG4gICAgICAgIDxtYXQtZGF0ZXRpbWVwaWNrZXIgI3RvRGF0ZXRpbWVQaWNrZXIgY29sb3I9XCJhY2NlbnRcIiB0eXBlPVwiZGF0ZXRpbWVcIiAvPlxuICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwidG8uaW52YWxpZFwiIGRhdGEtYXV0b21hdGlvbi1pZD1cImRhdGV0aW1lLXJhbmdlLXRvLWVycm9yXCI+XG4gICAgICAgICAgICB7eyBnZXRUb1ZhbGlkYXRpb25NZXNzYWdlKCkgfCB0cmFuc2xhdGU6IHsgcmVxdWlyZWRGb3JtYXQ6IGRhdGV0aW1lUGlja2VyRm9ybWF0IH0gfX1cbiAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgPC9tYXQtZm9ybS1maWVsZD5cbjwvZm9ybT5cbiJdfQ==