@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
176 lines • 29.6 kB
JavaScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';
import { merge, Subject } from 'rxjs';
import { delay, map, takeUntil } from 'rxjs/operators';
import { DateRangeOptions } from '../../date-range-picker/date-range-picker.directive';
import { DateRangePicker, DateRangeService } from '../../date-range-picker/date-range.service';
import { DatePickerMode, DateTimePickerService } from '../date-time-picker.service';
import * as i0 from "@angular/core";
import * as i1 from "../../../directives/accessibility/focus-indicator/focus-indicator.directive";
import * as i2 from "../../icon/icon.component";
import * as i3 from "@angular/common";
export class HeaderComponent {
/** Determine if we are in range selection mode */
get _isRangeMode() {
return !!this._rangeOptions;
}
/** Determine if this picker is the start picker */
get _isRangeStart() {
return this._isRangeMode && this._rangeOptions.picker === DateRangePicker.Start;
}
/** Determine if this picker is the end picker */
get _isRangeEnd() {
return this._isRangeMode && this._rangeOptions.picker === DateRangePicker.End;
}
get _rangeStart() {
return this._isRangeMode && this._rangeService ? this._rangeService.start : null;
}
get _rangeEnd() {
return this._isRangeMode && this._rangeService ? this._rangeService.end : null;
}
constructor() {
this.datepicker = inject(DateTimePickerService);
this._changeDetector = inject(ChangeDetectorRef);
this._rangeService = inject(DateRangeService, { optional: true });
this._rangeOptions = inject(DateRangeOptions, { optional: true });
this.canAscend$ = this.datepicker.mode$.pipe(map(mode => mode !== DatePickerMode.Year));
this.mode$ = this.datepicker.mode$.pipe(map(mode => {
switch (mode) {
case DatePickerMode.Day:
return 'Day';
case DatePickerMode.Month:
return 'Month';
case DatePickerMode.Year:
return 'Year';
}
}));
this.headerAria$ = this.datepicker.mode$.pipe(map(mode => {
switch (mode) {
case DatePickerMode.Day:
return 'Switch to show months in the year';
case DatePickerMode.Month:
return 'Switch to show years in the decade';
case DatePickerMode.Year:
return '';
}
}));
this.previousAria$ = this.datepicker.mode$.pipe(map(mode => {
switch (mode) {
case DatePickerMode.Day:
return 'Previous month';
case DatePickerMode.Month:
return 'Previous year';
case DatePickerMode.Year:
return 'Previous decade';
}
}));
this.nextAria$ = this.datepicker.mode$.pipe(map(mode => {
switch (mode) {
case DatePickerMode.Day:
return 'Next month';
case DatePickerMode.Month:
return 'Next year';
case DatePickerMode.Year:
return 'Next decade';
}
}));
/** Unsubscribe from all observables */
this._onDestroy = new Subject();
if (this._rangeService) {
// delay required to allow all ui to update elsewhere
this._rangeService.onRangeChange.pipe(delay(100), takeUntil(this._onDestroy))
.subscribe(() => this._changeDetector.detectChanges());
}
}
ngAfterViewInit() {
// update on min/max changes
merge(this.datepicker.min$, this.datepicker.max$).pipe(takeUntil(this._onDestroy))
.subscribe(() => this._changeDetector.detectChanges());
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
/** Navigate to the previous day, month or year */
previous() {
this.datepicker.goToPrevious();
}
/** Navigate to the larger scale, eg. Days -> Months, Months -> Years */
ascend() {
this.datepicker.goToParentMode();
}
/** Navigate to the previous day, month or year */
next() {
this.datepicker.goToNext();
}
/** Determine if the previous button is enabled */
isPreviousDisabled() {
const min = this.datepicker.min$.value;
if (min && this._isBeforeView(min)) {
return true;
}
// if we are not in range mode or there are no disabled items then we can navigate back
if (!this._isRangeMode || this._rangeStart && this._rangeEnd ||
!this._rangeStart && !this._rangeEnd || this._isRangeStart
|| this._isRangeEnd && this._rangeEnd) {
return false;
}
if (this._isBeforeView(this._rangeStart)) {
return true;
}
return false;
}
/** Determine if the previous button is enabled */
isNextDisabled() {
const max = this.datepicker.max$.value;
if (max && this._isAfterView(max)) {
return true;
}
// if we are not in range mode or there are no disabled items then we can navigate back
if (!this._isRangeMode || this._rangeStart && this._rangeEnd ||
!this._rangeStart && !this._rangeEnd || this._isRangeStart && this._rangeStart
|| this._isRangeEnd) {
return false;
}
if (this._isAfterView(this._rangeEnd)) {
return true;
}
return false;
}
_isBeforeView(date) {
const month = this.datepicker.month$.value;
const year = this.datepicker.year$.value;
const mode = this.datepicker.mode$.value;
const yearRange = this.datepicker.yearRange;
if (mode === DatePickerMode.Day) {
return year <= date.getFullYear() && month <= date.getMonth();
}
if (mode === DatePickerMode.Month) {
return year <= date.getFullYear();
}
if (mode === DatePickerMode.Year) {
return yearRange.start <= date.getFullYear();
}
}
_isAfterView(date) {
const month = this.datepicker.month$.value;
const year = this.datepicker.year$.value;
const mode = this.datepicker.mode$.value;
const yearRange = this.datepicker.yearRange;
if (mode === DatePickerMode.Day) {
return year >= date.getFullYear() && month >= date.getMonth();
}
if (mode === DatePickerMode.Month) {
return year >= date.getFullYear();
}
if (mode === DatePickerMode.Year) {
return yearRange.end >= date.getFullYear();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: HeaderComponent, selector: "ux-date-time-picker-header", ngImport: i0, template: "<header class=\"header\">\n\n <button type=\"button\"\n uxFocusIndicator\n [disabled]=\"isPreviousDisabled()\"\n class=\"header-navigation\"\n (click)=\"previous(); $event.stopPropagation()\"\n [attr.aria-label]=\"previousAria$ | async\"\n tabindex=\"0\">\n\n <ux-icon name=\"previous\" class=\"header-navigation-previous-icon\"></ux-icon>\n </button>\n\n <button type=\"button\"\n uxFocusIndicator\n class=\"header-title\"\n [attr.aria-label]=\"headerAria$ | async\"\n [class.active]=\"canAscend$ | async\"\n (click)=\"ascend(); $event.stopPropagation()\"\n [tabindex]=\"(canAscend$ | async) ? 0 : -1\">\n {{ datepicker.header$ | async }}\n </button>\n\n <button type=\"button\"\n uxFocusIndicator\n [disabled]=\"isNextDisabled()\"\n class=\"header-navigation\"\n (click)=\"next(); $event.stopPropagation()\"\n [attr.aria-label]=\"nextAria$ | async\"\n tabindex=\"0\">\n\n <ux-icon name=\"next\" class=\"header-navigation-next-icon\"></ux-icon>\n </button>\n</header>", dependencies: [{ kind: "directive", type: i1.FocusIndicatorDirective, selector: "[uxFocusIndicator]", inputs: ["checkChildren", "mouseFocusIndicator", "touchFocusIndicator", "keyboardFocusIndicator", "programmaticFocusIndicator"], outputs: ["indicator"], exportAs: ["ux-focus-indicator"] }, { kind: "component", type: i2.IconComponent, selector: "ux-icon", inputs: ["name", "size", "rotate", "flipHorizontal", "flipVertical"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: HeaderComponent, decorators: [{
type: Component,
args: [{ selector: 'ux-date-time-picker-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header\">\n\n <button type=\"button\"\n uxFocusIndicator\n [disabled]=\"isPreviousDisabled()\"\n class=\"header-navigation\"\n (click)=\"previous(); $event.stopPropagation()\"\n [attr.aria-label]=\"previousAria$ | async\"\n tabindex=\"0\">\n\n <ux-icon name=\"previous\" class=\"header-navigation-previous-icon\"></ux-icon>\n </button>\n\n <button type=\"button\"\n uxFocusIndicator\n class=\"header-title\"\n [attr.aria-label]=\"headerAria$ | async\"\n [class.active]=\"canAscend$ | async\"\n (click)=\"ascend(); $event.stopPropagation()\"\n [tabindex]=\"(canAscend$ | async) ? 0 : -1\">\n {{ datepicker.header$ | async }}\n </button>\n\n <button type=\"button\"\n uxFocusIndicator\n [disabled]=\"isNextDisabled()\"\n class=\"header-navigation\"\n (click)=\"next(); $event.stopPropagation()\"\n [attr.aria-label]=\"nextAria$ | async\"\n tabindex=\"0\">\n\n <ux-icon name=\"next\" class=\"header-navigation-next-icon\"></ux-icon>\n </button>\n</header>" }]
}], ctorParameters: () => [] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2RhdGUtdGltZS1waWNrZXIvaGVhZGVyL2hlYWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kYXRlLXRpbWUtcGlja2VyL2hlYWRlci9oZWFkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQix1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQ3hILE9BQU8sRUFBRSxLQUFLLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xELE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUMvRixPQUFPLEVBQUUsY0FBYyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7Ozs7O0FBT3BGLE1BQU0sT0FBTyxlQUFlO0lBdUR4QixrREFBa0Q7SUFDbEQsSUFBSSxZQUFZO1FBQ1osT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUNoQyxDQUFDO0lBRUQsbURBQW1EO0lBQ25ELElBQUksYUFBYTtRQUNiLE9BQU8sSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sS0FBSyxlQUFlLENBQUMsS0FBSyxDQUFDO0lBQ3BGLENBQUM7SUFFRCxpREFBaUQ7SUFDakQsSUFBSSxXQUFXO1FBQ1gsT0FBTyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMs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VUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDekMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDO1FBRTVDLElBQUksSUFBSSxLQUFLLGNBQWMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM5QixPQUFPLElBQUksSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNsRSxDQUFDO1FBRUQsSUFBSSxJQUFJLEtBQUssY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hDLE9BQU8sSUFBSSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN0QyxDQUFDO1FBRUQsSUFBSSxJQUFJLEtBQUssY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQy9CLE9BQU8sU0FBUyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDL0MsQ0FBQztJQUNMLENBQUM7K0dBdk1RLGVBQWU7bUdBQWYsZUFBZSxrRUNaNUIsOG5DQWlDUzs7NEZEckJJLGVBQWU7a0JBTDNCLFNBQVM7K0JBQ0ksNEJBQTRCLG1CQUVyQix1QkFBdUIsQ0FBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIGluamVjdCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBtZXJnZSwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVsYXksIG1hcCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRGF0ZVJhbmdlT3B0aW9ucyB9IGZyb20gJy4uLy4uL2RhdGUtcmFuZ2UtcGlja2VyL2RhdGUtcmFuZ2UtcGlja2VyLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBEYXRlUmFuZ2VQaWNrZXIsIERhdGVSYW5nZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9kYXRlLXJhbmdlLXBpY2tlci9kYXRlLXJhbmdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGF0ZVBpY2tlck1vZGUsIERhdGVUaW1lUGlja2VyU2VydmljZSB9IGZyb20gJy4uL2RhdGUtdGltZS1waWNrZXIuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAndXgtZGF0ZS10aW1lLXBpY2tlci1oZWFkZXInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9oZWFkZXIuY29tcG9uZW50Lmh0bWwnLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBIZWFkZXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAgIHJlYWRvbmx5IGRhdGVwaWNrZXIgPSBpbmplY3QoRGF0ZVRpbWVQaWNrZXJTZXJ2aWNlKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2NoYW5nZURldGVjdG9yID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3JhbmdlU2VydmljZSA9IGluamVjdChEYXRlUmFuZ2VTZXJ2aWNlLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcmFuZ2VPcHRpb25zID0gaW5qZWN0KERhdGVSYW5nZU9wdGlvbnMsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgICBjYW5Bc2NlbmQkOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy5kYXRlcGlja2VyLm1vZGUkLnBpcGUobWFwKG1vZGUgPT4gbW9kZSAhPT0gRGF0ZVBpY2tlck1vZGUuWWVhcikpO1xuXG4gICAgbW9kZSQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuZGF0ZXBpY2tlci5tb2RlJC5waXBlKG1hcChtb2RlID0+IHtcbiAgICAgICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICAgICAgICBjYXNlIERhdGVQaWNrZXJNb2RlLkRheTpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ0RheSc7XG4gICAgICAgICAgICBjYXNlIERhdGVQaWNrZXJNb2RlLk1vbnRoOlxuICAgICAgICAgICAgICAgIHJldHVybiAnTW9udGgnO1xuICAgICAgICAgICAgY2FzZSBEYXRlUGlja2VyTW9kZS5ZZWFyOlxuICAgICAgICAgICAgICAgIHJldHVybiAnWWVhcic7XG4gICAgICAgIH1cbiAgICB9KSk7XG5cbiAgICBoZWFkZXJBcmlhJDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5kYXRlcGlja2VyLm1vZGUkLnBpcGUobWFwKG1vZGUgPT4ge1xuICAgICAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgRGF0ZVBpY2tlck1vZGUuRGF5OlxuICAgICAgICAgICAgICAgIHJldHVybiAnU3dpdGNoIHRvIHNob3cgbW9udGhzIGluIHRoZSB5ZWFyJztcbiAgICAgICAgICAgIGNhc2UgRGF0ZVBpY2tlck1vZGUuTW9udGg6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdTd2l0Y2ggdG8gc2hvdyB5ZWFycyBpbiB0aGUgZGVjYWRlJztcbiAgICAgICAgICAgIGNhc2UgRGF0ZVBpY2tlck1vZGUuWWVhcjpcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cbiAgICB9KSk7XG5cbiAgICBwcmV2aW91c0FyaWEkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLmRhdGVwaWNrZXIubW9kZSQucGlwZShtYXAobW9kZSA9PiB7XG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xuICAgICAgICAgICAgY2FzZSBEYXRlUGlja2VyTW9kZS5EYXk6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdQcmV2aW91cyBtb250aCc7XG4gICAgICAgICAgICBjYXNlIERhdGVQaWNrZXJNb2RlLk1vbnRoOlxuICAgICAgICAgICAgICAgIHJldHVybiAnUHJldmlvdXMgeWVhcic7XG4gICAgICAgICAgICBjYXNlIERhdGVQaWNrZXJNb2RlLlllYXI6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdQcmV2aW91cyBkZWNhZGUnO1xuICAgICAgICB9XG4gICAgfSkpO1xuXG4gICAgbmV4dEFyaWEkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLmRhdGVwaWNrZXIubW9kZSQucGlwZShtYXAobW9kZSA9PiB7XG4gICAgICAgIHN3aXRjaCAobW9kZSkge1xuICAgICAgICAgICAgY2FzZSBEYXRlUGlja2VyTW9kZS5EYXk6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdOZXh0IG1vbnRoJztcbiAgICAgICAgICAgIGNhc2UgRGF0ZVBpY2tlck1vZGUuTW9udGg6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdOZXh0IHllYXInO1xuICAgICAgICAgICAgY2FzZSBEYXRlUGlja2VyTW9kZS5ZZWFyOlxuICAgICAgICAgICAgICAgIHJldHVybiAnTmV4dCBkZWNhZGUnO1xuICAgICAgICB9XG4gICAgfSkpO1xuXG4gICAgLyoqIERldGVybWluZSBpZiB3ZSBhcmUgaW4gcmFuZ2Ugc2VsZWN0aW9uIG1vZGUgKi9cbiAgICBnZXQgX2lzUmFuZ2VNb2RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9yYW5nZU9wdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqIERldGVybWluZSBpZiB0aGlzIHBpY2tlciBpcyB0aGUgc3RhcnQgcGlja2VyICovXG4gICAgZ2V0IF9pc1JhbmdlU3RhcnQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1JhbmdlTW9kZSAmJiB0aGlzLl9yYW5nZU9wdGlvbnMucGlja2VyID09PSBEYXRlUmFuZ2VQaWNrZXIuU3RhcnQ7XG4gICAgfVxuXG4gICAgLyoqIERldGVybWluZSBpZiB0aGlzIHBpY2tlciBpcyB0aGUgZW5kIHBpY2tlciAqL1xuICAgIGdldCBfaXNSYW5nZUVuZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzUmFuZ2VNb2RlICYmIHRoaXMuX3JhbmdlT3B0aW9ucy5waWNrZXIgPT09IERhdGVSYW5nZVBpY2tlci5FbmQ7XG4gICAgfVxuXG4gICAgZ2V0IF9yYW5nZVN0YXJ0KCk6IERhdGUgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzUmFuZ2VNb2RlICYmIHRoaXMuX3JhbmdlU2VydmljZSA/IHRoaXMuX3JhbmdlU2VydmljZS5zdGFydCA6IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0IF9yYW5nZUVuZCgpOiBEYXRlIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1JhbmdlTW9kZSAmJiB0aGlzLl9yYW5nZVNlcnZpY2UgPyB0aGlzLl9yYW5nZVNlcnZpY2UuZW5kIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKiogVW5zdWJzY3JpYmUgZnJvbSBhbGwgb2JzZXJ2YWJsZXMgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGlmICh0aGlzLl9yYW5nZVNlcnZpY2UpIHtcbiAgICAgICAgICAgIC8vIGRlbGF5IHJlcXVpcmVkIHRvIGFsbG93IGFsbCB1aSB0byB1cGRhdGUgZWxzZXdoZXJlXG4gICAgICAgICAgICB0aGlzLl9yYW5nZVNlcnZpY2Uub25SYW5nZUNoYW5nZS5waXBlKGRlbGF5KDEwMCksIHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgLy8gdXBkYXRlIG9uIG1pbi9tYXggY2hhbmdlc1xuICAgICAgICBtZXJnZSh0aGlzLmRhdGVwaWNrZXIubWluJCwgdGhpcy5kYXRlcGlja2VyLm1heCQpLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2NoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKSk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5uZXh0KCk7XG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8qKiBOYXZpZ2F0ZSB0byB0aGUgcHJldmlvdXMgZGF5LCBtb250aCBvciB5ZWFyICovXG4gICAgcHJldmlvdXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGF0ZXBpY2tlci5nb1RvUHJldmlvdXMoKTtcbiAgICB9XG5cbiAgICAvKiogTmF2aWdhdGUgdG8gdGhlIGxhcmdlciBzY2FsZSwgZWcuIERheXMgLT4gTW9udGhzLCBNb250aHMgLT4gWWVhcnMgKi9cbiAgICBhc2NlbmQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGF0ZXBpY2tlci5nb1RvUGFyZW50TW9kZSgpO1xuICAgIH1cblxuICAgIC8qKiBOYXZpZ2F0ZSB0byB0aGUgcHJldmlvdXMgZGF5LCBtb250aCBvciB5ZWFyICovXG4gICAgbmV4dCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kYXRlcGlja2VyLmdvVG9OZXh0KCk7XG4gICAgfVxuXG4gICAgLyoqIERldGVybWluZSBpZiB0aGUgcHJldmlvdXMgYnV0dG9uIGlzIGVuYWJsZWQgKi9cbiAgICBpc1ByZXZpb3VzRGlzYWJsZWQoKTogYm9vbGVhbiB7XG5cbiAgICAgICAgY29uc3QgbWluID0gdGhpcy5kYXRlcGlja2VyLm1pbiQudmFsdWU7XG5cbiAgICAgICAgaWYgKG1pbiAmJiB0aGlzLl9pc0JlZm9yZVZpZXcobWluKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB3ZSBhcmUgbm90IGluIHJhbmdlIG1vZGUgb3IgdGhlcmUgYXJlIG5vIGRpc2FibGVkIGl0ZW1zIHRoZW4gd2UgY2FuIG5hdmlnYXRlIGJhY2tcbiAgICAgICAgaWYgKCF0aGlzLl9pc1JhbmdlTW9kZSB8fCB0aGlzLl9yYW5nZVN0YXJ0ICYmIHRoaXMuX3JhbmdlRW5kIHx8XG4gICAgICAgICAgICAhdGhpcy5fcmFuZ2VTdGFydCAmJiAhdGhpcy5fcmFuZ2VFbmQgfHwgdGhpcy5faXNSYW5nZVN0YXJ0XG4gICAgICAgICAgICB8fCB0aGlzLl9pc1JhbmdlRW5kICYmIHRoaXMuX3JhbmdlRW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5faXNCZWZvcmVWaWV3KHRoaXMuX3JhbmdlU3RhcnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKiogRGV0ZXJtaW5lIGlmIHRoZSBwcmV2aW91cyBidXR0b24gaXMgZW5hYmxlZCAqL1xuICAgIGlzTmV4dERpc2FibGVkKCk6IGJvb2xlYW4ge1xuXG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuZGF0ZXBpY2tlci5tYXgkLnZhbHVlO1xuXG4gICAgICAgIGlmIChtYXggJiYgdGhpcy5faXNBZnRlclZpZXcobWF4KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB3ZSBhcmUgbm90IGluIHJhbmdlIG1vZGUgb3IgdGhlcmUgYXJlIG5vIGRpc2FibGVkIGl0ZW1zIHRoZW4gd2UgY2FuIG5hdmlnYXRlIGJhY2tcbiAgICAgICAgaWYgKCF0aGlzLl9pc1JhbmdlTW9kZSB8fCB0aGlzLl9yYW5nZVN0YXJ0ICYmIHRoaXMuX3JhbmdlRW5kIHx8XG4gICAgICAgICAgICAhdGhpcy5fcmFuZ2VTdGFydCAmJiAhdGhpcy5fcmFuZ2VFbmQgfHwgdGhpcy5faXNSYW5nZVN0YXJ0ICYmIHRoaXMuX3JhbmdlU3RhcnRcbiAgICAgICAgICAgIHx8IHRoaXMuX2lzUmFuZ2VFbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9pc0FmdGVyVmlldyh0aGlzLl9yYW5nZUVuZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2lzQmVmb3JlVmlldyhkYXRlOiBEYXRlKTogYm9vbGVhbiB7XG5cbiAgICAgICAgY29uc3QgbW9udGggPSB0aGlzLmRhdGVwaWNrZXIubW9udGgkLnZhbHVlO1xuICAgICAgICBjb25zdCB5ZWFyID0gdGhpcy5kYXRlcGlja2VyLnllYXIkLnZhbHVlO1xuICAgICAgICBjb25zdCBtb2RlID0gdGhpcy5kYXRlcGlja2VyLm1vZGUkLnZhbHVlO1xuICAgICAgICBjb25zdCB5ZWFyUmFuZ2UgPSB0aGlzLmRhdGVwaWNrZXIueWVhclJhbmdlO1xuXG4gICAgICAgIGlmIChtb2RlID09PSBEYXRlUGlja2VyTW9kZS5EYXkpIHtcbiAgICAgICAgICAgIHJldHVybiB5ZWFyIDw9IGRhdGUuZ2V0RnVsbFllYXIoKSAmJiBtb250aCA8PSBkYXRlLmdldE1vbnRoKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobW9kZSA9PT0gRGF0ZVBpY2tlck1vZGUuTW9udGgpIHtcbiAgICAgICAgICAgIHJldHVybiB5ZWFyIDw9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb2RlID09PSBEYXRlUGlja2VyTW9kZS5ZZWFyKSB7XG4gICAgICAgICAgICByZXR1cm4geWVhclJhbmdlLnN0YXJ0IDw9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2lzQWZ0ZXJWaWV3KGRhdGU6IERhdGUpOiBib29sZWFuIHtcblxuICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuZGF0ZXBpY2tlci5tb250aCQudmFsdWU7XG4gICAgICAgIGNvbnN0IHllYXIgPSB0aGlzLmRhdGVwaWNrZXIueWVhciQudmFsdWU7XG4gICAgICAgIGNvbnN0IG1vZGUgPSB0aGlzLmRhdGVwaWNrZXIubW9kZSQudmFsdWU7XG4gICAgICAgIGNvbnN0IHllYXJSYW5nZSA9IHRoaXMuZGF0ZXBpY2tlci55ZWFyUmFuZ2U7XG5cbiAgICAgICAgaWYgKG1vZGUgPT09IERhdGVQaWNrZXJNb2RlLkRheSkge1xuICAgICAgICAgICAgcmV0dXJuIHllYXIgPj0gZGF0ZS5nZXRGdWxsWWVhcigpICYmIG1vbnRoID49IGRhdGUuZ2V0TW9udGgoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtb2RlID09PSBEYXRlUGlja2VyTW9kZS5Nb250aCkge1xuICAgICAgICAgICAgcmV0dXJuIHllYXIgPj0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1vZGUgPT09IERhdGVQaWNrZXJNb2RlLlllYXIpIHtcbiAgICAgICAgICAgIHJldHVybiB5ZWFyUmFuZ2UuZW5kID49IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgfVxuICAgIH1cbn0iLCI8aGVhZGVyIGNsYXNzPVwiaGVhZGVyXCI+XG5cbiAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICB1eEZvY3VzSW5kaWNhdG9yXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImlzUHJldmlvdXNEaXNhYmxlZCgpXCJcbiAgICAgICAgICBjbGFzcz1cImhlYWRlci1uYXZpZ2F0aW9uXCJcbiAgICAgICAgICAoY2xpY2spPVwicHJldmlvdXMoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInByZXZpb3VzQXJpYSQgfCBhc3luY1wiXG4gICAgICAgICAgdGFiaW5kZXg9XCIwXCI+XG5cbiAgICA8dXgtaWNvbiBuYW1lPVwicHJldmlvdXNcIiBjbGFzcz1cImhlYWRlci1uYXZpZ2F0aW9uLXByZXZpb3VzLWljb25cIj48L3V4LWljb24+XG4gIDwvYnV0dG9uPlxuXG4gIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgdXhGb2N1c0luZGljYXRvclxuICAgICAgICAgIGNsYXNzPVwiaGVhZGVyLXRpdGxlXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImhlYWRlckFyaWEkIHwgYXN5bmNcIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiY2FuQXNjZW5kJCB8IGFzeW5jXCJcbiAgICAgICAgICAoY2xpY2spPVwiYXNjZW5kKCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgW3RhYmluZGV4XT1cIihjYW5Bc2NlbmQkIHwgYXN5bmMpID8gMCA6IC0xXCI+XG4gICAgICAge3sgZGF0ZXBpY2tlci5oZWFkZXIkIHwgYXN5bmMgfX1cbiAgPC9idXR0b24+XG5cbiAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICB1eEZvY3VzSW5kaWNhdG9yXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImlzTmV4dERpc2FibGVkKClcIlxuICAgICAgICAgIGNsYXNzPVwiaGVhZGVyLW5hdmlnYXRpb25cIlxuICAgICAgICAgIChjbGljayk9XCJuZXh0KCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJuZXh0QXJpYSQgfCBhc3luY1wiXG4gICAgICAgICAgdGFiaW5kZXg9XCIwXCI+XG5cbiAgICA8dXgtaWNvbiBuYW1lPVwibmV4dFwiIGNsYXNzPVwiaGVhZGVyLW5hdmlnYXRpb24tbmV4dC1pY29uXCI+PC91eC1pY29uPlxuICA8L2J1dHRvbj5cbjwvaGVhZGVyPiJdfQ==