@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
137 lines • 26.7 kB
JavaScript
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';
import { merge, Subject } from 'rxjs';
import { 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 { DateTimePickerService } from '../date-time-picker.service';
import { isDateAfter, isDateBefore } from '../date-time-picker.utils';
import { YearViewService } from './year-view.service';
import * as i0 from "@angular/core";
import * as i1 from "../../../directives/accessibility/focus-indicator/focus-indicator.directive";
import * as i2 from "../../../directives/accessibility/focus-indicator/focus-indicator-origin/focus-indicator-origin.directive";
import * as i3 from "../../../directives/focus-if/focus-if.directive";
import * as i4 from "@angular/common";
export class YearViewComponent {
/** 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;
}
get _minYear() {
return this._datePicker.min$.value ? new Date(this._datePicker.min$.value.getFullYear(), 0) : null;
}
get _maxYear() {
return this._datePicker.max$.value ? new Date(this._datePicker.max$.value.getFullYear(), 0) : null;
}
constructor() {
this.yearService = inject(YearViewService);
this._datePicker = inject(DateTimePickerService);
this._liveAnnouncer = inject(LiveAnnouncer);
this._changeDetector = inject(ChangeDetectorRef);
this._rangeService = inject(DateRangeService, { optional: true });
this._rangeOptions = inject(DateRangeOptions, { optional: true });
this._onDestroy = new Subject();
if (this._rangeService) {
this._rangeService.onRangeChange.pipe(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();
}
select(year) {
this._datePicker.setViewportYear(year);
// show the month picker
this._datePicker.goToChildMode();
}
/** Get the disabled state of a month */
getDisabled(item) {
const date = new Date(item.year, 0);
// if we are not in range mode then it will always be enabled
if (this._isRangeMode) {
// if we are range start and dates are after the range end then they should also be disabled
if (this._isRangeStart && !this._rangeStart && this._rangeEnd && isDateAfter(date, new Date(this._rangeEnd.getFullYear(), 0))) {
return true;
}
// if we are range end and dates are before the range start then they should also be disabled
if (this._isRangeEnd && !this._rangeEnd && this._rangeStart && isDateBefore(date, new Date(this._rangeStart.getFullYear(), 0))) {
return true;
}
}
if (this._minYear && isDateBefore(date, this._minYear)) {
return true;
}
if (this._maxYear && isDateAfter(date, this._maxYear)) {
return true;
}
return false;
}
focusYear(item, yearOffset) {
this.yearService.setFocus(item.year + yearOffset);
}
trackRowByFn(index) {
return index;
}
trackYearByFn(_index, item) {
return item.year;
}
getTabbable(item) {
const focused = this.yearService.focused$.value;
const grid = this.yearService.grid$.value;
// if there is a focused year check if this is it
if (focused) {
// check if the focused year is visible
const isFocusedYearVisible = !!grid.find(row => !!row.find(_item => _item.year === focused));
if (isFocusedYearVisible) {
return focused === item.year;
}
}
// if there is no focusable year then check if there is a selected year
const isSelectedYearVisible = !!grid.find(row => !!row.find(year => year.isActiveYear));
if (isSelectedYearVisible) {
return item.isActiveYear;
}
// otherwise find the first non-disabled month
for (const row of this.yearService.grid$.value) {
for (const column of row) {
if (!this.getDisabled(column)) {
return item === column;
}
}
}
// otherwise make the first month tabbable
return false;
}
/** Announce the date when we focus on a date */
announceRangeMode() {
if (this._isRangeMode) {
this._liveAnnouncer.announce(this._isRangeStart ? this._rangeService.startPickerAriaLabel : this._rangeService.endPickerAriaLabel);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: YearViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: YearViewComponent, selector: "ux-date-time-picker-year-view", providers: [YearViewService], ngImport: i0, template: "<div class=\"calendar\" role=\"grid\">\n @for (row of yearService.grid$ | async; track trackRowByFn($index)) {\n <div class=\"calendar-row\" role=\"row\">\n @for (item of row; track trackYearByFn($index, item)) {\n <button\n uxFocusIndicator\n uxFocusIndicatorOrigin\n [programmaticFocusIndicator]=\"true\"\n type=\"button\"\n role=\"gridcell\"\n class=\"calendar-item\"\n [focusIf]=\"(yearService.focused$ | async) === item.year\"\n [attr.aria-label]=\"item.year\"\n [attr.aria-selected]=\"item.isActiveYear\"\n [class.current]=\"item.isCurrentYear\"\n [class.active]=\"item.isActiveYear && !getDisabled(item)\"\n [disabled]=\"getDisabled(item)\"\n (click)=\"select(item.year); $event.stopPropagation()\"\n (focus)=\"announceRangeMode()\"\n (keydown.ArrowLeft)=\"focusYear(item, -1); $event.preventDefault()\"\n (keydown.ArrowRight)=\"focusYear(item, 1); $event.preventDefault()\"\n (keydown.ArrowUp)=\"focusYear(item, -4); $event.preventDefault()\"\n (keydown.ArrowDown)=\"focusYear(item, 4); $event.preventDefault()\"\n [tabindex]=\"getTabbable(item) ? 0 : -1\">\n {{ item.year }}\n </button>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1.FocusIndicatorDirective, selector: "[uxFocusIndicator]", inputs: ["checkChildren", "mouseFocusIndicator", "touchFocusIndicator", "keyboardFocusIndicator", "programmaticFocusIndicator"], outputs: ["indicator"], exportAs: ["ux-focus-indicator"] }, { kind: "directive", type: i2.FocusIndicatorOriginDirective, selector: "[uxFocusIndicatorOrigin]" }, { kind: "directive", type: i3.FocusIfDirective, selector: "[focusIf]", inputs: ["focusIfDelay", "focusIfScroll", "focusIf"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: YearViewComponent, decorators: [{
type: Component,
args: [{ selector: 'ux-date-time-picker-year-view', providers: [YearViewService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"calendar\" role=\"grid\">\n @for (row of yearService.grid$ | async; track trackRowByFn($index)) {\n <div class=\"calendar-row\" role=\"row\">\n @for (item of row; track trackYearByFn($index, item)) {\n <button\n uxFocusIndicator\n uxFocusIndicatorOrigin\n [programmaticFocusIndicator]=\"true\"\n type=\"button\"\n role=\"gridcell\"\n class=\"calendar-item\"\n [focusIf]=\"(yearService.focused$ | async) === item.year\"\n [attr.aria-label]=\"item.year\"\n [attr.aria-selected]=\"item.isActiveYear\"\n [class.current]=\"item.isCurrentYear\"\n [class.active]=\"item.isActiveYear && !getDisabled(item)\"\n [disabled]=\"getDisabled(item)\"\n (click)=\"select(item.year); $event.stopPropagation()\"\n (focus)=\"announceRangeMode()\"\n (keydown.ArrowLeft)=\"focusYear(item, -1); $event.preventDefault()\"\n (keydown.ArrowRight)=\"focusYear(item, 1); $event.preventDefault()\"\n (keydown.ArrowUp)=\"focusYear(item, -4); $event.preventDefault()\"\n (keydown.ArrowDown)=\"focusYear(item, 4); $event.preventDefault()\"\n [tabindex]=\"getTabbable(item) ? 0 : -1\">\n {{ item.year }}\n </button>\n }\n </div>\n }\n</div>\n" }]
}], ctorParameters: () => [] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieWVhci12aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2RhdGUtdGltZS1waWNrZXIveWVhci12aWV3L3llYXItdmlldy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kYXRlLXRpbWUtcGlja2VyL3llYXItdmlldy95ZWFyLXZpZXcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBaUIsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN4SCxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDdkYsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQy9GLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEUsT0FBTyxFQUFnQixlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7O0FBUXBFLE1BQU0sT0FBTyxpQkFBaUI7SUFhMUIsa0RBQWtEO0lBQ2xELElBQUksWUFBWTtRQUNaLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDaEMsQ0FBQztJQUVELG1EQUFtRDtJQUNuRCxJQUFJLGFBQWE7UUFDYixPQUFPLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLGFB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TyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzdCLENBQUM7UUFFRCw4Q0FBOEM7UUFDOUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM3QyxLQUFLLE1BQU0sTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO29CQUM1QixPQUFPLElBQUksS0FBSyxNQUFNLENBQUM7Z0JBQzNCLENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQztRQUVELDBDQUEwQztRQUMxQyxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQsZ0RBQWdEO0lBQ2hELGlCQUFpQjtRQUNiLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN2SSxDQUFDO0lBQ0wsQ0FBQzsrR0F6SlEsaUJBQWlCO21HQUFqQixpQkFBaUIsd0RBSGYsQ0FBQyxlQUFlLENBQUMsMEJDYmhDLHd6Q0E4QkE7OzRGRGRhLGlCQUFpQjtrQkFON0IsU0FBUzsrQkFDSSwrQkFBK0IsYUFFOUIsQ0FBQyxlQUFlLENBQUMsbUJBQ1gsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExpdmVBbm5vdW5jZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgaW5qZWN0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IG1lcmdlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBEYXRlUmFuZ2VPcHRpb25zIH0gZnJvbSAnLi4vLi4vZGF0ZS1yYW5nZS1waWNrZXIvZGF0ZS1yYW5nZS1waWNrZXIuZGlyZWN0aXZlJztcbmltcG9ydCB7IERhdGVSYW5nZVBpY2tlciwgRGF0ZVJhbmdlU2VydmljZSB9IGZyb20gJy4uLy4uL2RhdGUtcmFuZ2UtcGlja2VyL2RhdGUtcmFuZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlVGltZVBpY2tlclNlcnZpY2UgfSBmcm9tICcuLi9kYXRlLXRpbWUtcGlja2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgaXNEYXRlQWZ0ZXIsIGlzRGF0ZUJlZm9yZSB9IGZyb20gJy4uL2RhdGUtdGltZS1waWNrZXIudXRpbHMnO1xuaW1wb3J0IHsgWWVhclZpZXdJdGVtLCBZZWFyVmlld1NlcnZpY2UgfSBmcm9tICcuL3llYXItdmlldy5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICd1eC1kYXRlLXRpbWUtcGlja2VyLXllYXItdmlldycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3llYXItdmlldy5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbWWVhclZpZXdTZXJ2aWNlXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBZZWFyVmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gICAgcmVhZG9ubHkgeWVhclNlcnZpY2UgPSBpbmplY3QoWWVhclZpZXdTZXJ2aWNlKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2RhdGVQaWNrZXIgPSBpbmplY3QoRGF0ZVRpbWVQaWNrZXJTZXJ2aWNlKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2xpdmVBbm5vdW5jZXIgPSBpbmplY3QoTGl2ZUFubm91bmNlcik7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jaGFuZ2VEZXRlY3RvciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yYW5nZVNlcnZpY2UgPSBpbmplY3QoRGF0ZVJhbmdlU2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3JhbmdlT3B0aW9ucyA9IGluamVjdChEYXRlUmFuZ2VPcHRpb25zLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgLyoqIERldGVybWluZSBpZiB3ZSBhcmUgaW4gcmFuZ2Ugc2VsZWN0aW9uIG1vZGUgKi9cbiAgICBnZXQgX2lzUmFuZ2VNb2RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLl9yYW5nZU9wdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqIERldGVybWluZSBpZiB0aGlzIHBpY2tlciBpcyB0aGUgc3RhcnQgcGlja2VyICovXG4gICAgZ2V0IF9pc1JhbmdlU3RhcnQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1JhbmdlTW9kZSAmJiB0aGlzLl9yYW5nZU9wdGlvbnMucGlja2VyID09PSBEYXRlUmFuZ2VQaWNrZXIuU3RhcnQ7XG4gICAgfVxuXG4gICAgLyoqIERldGVybWluZSBpZiB0aGlzIHBpY2tlciBpcyB0aGUgZW5kIHBpY2tlciAqL1xuICAgIGdldCBfaXNSYW5nZUVuZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzUmFuZ2VNb2RlICYmIHRoaXMuX3JhbmdlT3B0aW9ucy5waWNrZXIgPT09IERhdGVSYW5nZVBpY2tlci5FbmQ7XG4gICAgfVxuXG4gICAgZ2V0IF9yYW5nZVN0YXJ0KCk6IERhdGUgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzUmFuZ2VNb2RlICYmIHRoaXMuX3JhbmdlU2VydmljZSA/IHRoaXMuX3JhbmdlU2VydmljZS5zdGFydCA6IG51bGw7XG4gICAgfVxuXG4gICAgZ2V0IF9yYW5nZUVuZCgpOiBEYXRlIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1JhbmdlTW9kZSAmJiB0aGlzLl9yYW5nZVNlcnZpY2UgPyB0aGlzLl9yYW5nZVNlcnZpY2UuZW5kIDogbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgX21pblllYXIoKTogRGF0ZSB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGF0ZVBpY2tlci5taW4kLnZhbHVlID8gbmV3IERhdGUodGhpcy5fZGF0ZVBpY2tlci5taW4kLnZhbHVlLmdldEZ1bGxZZWFyKCksIDApIDogbnVsbDtcbiAgICB9XG5cbiAgICBnZXQgX21heFllYXIoKTogRGF0ZSB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGF0ZVBpY2tlci5tYXgkLnZhbHVlID8gbmV3IERhdGUodGhpcy5fZGF0ZVBpY2tlci5tYXgkLnZhbHVlLmdldEZ1bGxZZWFyKCksIDApIDogbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG5cbiAgICAgICAgaWYgKHRoaXMuX3JhbmdlU2VydmljZSkge1xuICAgICAgICAgICAgdGhpcy5fcmFuZ2VTZXJ2aWNlLm9uUmFuZ2VDaGFuZ2UucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSkuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2NoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIC8vIHVwZGF0ZSBvbiBtaW4vbWF4IGNoYW5nZXNcbiAgICAgICAgbWVyZ2UodGhpcy5fZGF0ZVBpY2tlci5taW4kLCB0aGlzLl9kYXRlUGlja2VyLm1heCQpLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2NoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKSk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5uZXh0KCk7XG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIHNlbGVjdCh5ZWFyOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fZGF0ZVBpY2tlci5zZXRWaWV3cG9ydFllYXIoeWVhcik7XG5cbiAgICAgICAgLy8gc2hvdyB0aGUgbW9udGggcGlja2VyXG4gICAgICAgIHRoaXMuX2RhdGVQaWNrZXIuZ29Ub0NoaWxkTW9kZSgpO1xuICAgIH1cblxuICAgIC8qKiBHZXQgdGhlIGRpc2FibGVkIHN0YXRlIG9mIGEgbW9udGggKi9cbiAgICBnZXREaXNhYmxlZChpdGVtOiBZZWFyVmlld0l0ZW0pOiBib29sZWFuIHtcblxuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoaXRlbS55ZWFyLCAwKTtcblxuICAgICAgICAvLyBpZiB3ZSBhcmUgbm90IGluIHJhbmdlIG1vZGUgdGhlbiBpdCB3aWxsIGFsd2F5cyBiZSBlbmFibGVkXG4gICAgICAgIGlmICh0aGlzLl9pc1JhbmdlTW9kZSkge1xuXG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgcmFuZ2Ugc3RhcnQgYW5kIGRhdGVzIGFyZSBhZnRlciB0aGUgcmFuZ2UgZW5kIHRoZW4gdGhleSBzaG91bGQgYWxzbyBiZSBkaXNhYmxlZFxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzUmFuZ2VTdGFydCAmJiAhdGhpcy5fcmFuZ2VTdGFydCAmJiB0aGlzLl9yYW5nZUVuZCAmJiBpc0RhdGVBZnRlcihkYXRlLCBuZXcgRGF0ZSh0aGlzLl9yYW5nZUVuZC5nZXRGdWxsWWVhcigpLCAwKSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaWYgd2UgYXJlIHJhbmdlIGVuZCBhbmQgZGF0ZXMgYXJlIGJlZm9yZSB0aGUgcmFuZ2Ugc3RhcnQgdGhlbiB0aGV5IHNob3VsZCBhbHNvIGJlIGRpc2FibGVkXG4gICAgICAgICAgICBpZiAodGhpcy5faXNSYW5nZUVuZCAmJiAhdGhpcy5fcmFuZ2VFbmQgJiYgdGhpcy5fcmFuZ2VTdGFydCAmJiBpc0RhdGVCZWZvcmUoZGF0ZSwgbmV3IERhdGUodGhpcy5fcmFuZ2VTdGFydC5nZXRGdWxsWWVhcigpLCAwKSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9taW5ZZWFyICYmIGlzRGF0ZUJlZm9yZShkYXRlLCB0aGlzLl9taW5ZZWFyKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fbWF4WWVhciAmJiBpc0RhdGVBZnRlcihkYXRlLCB0aGlzLl9tYXhZZWFyKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9jdXNZZWFyKGl0ZW06IFllYXJWaWV3SXRlbSwgeWVhck9mZnNldDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMueWVhclNlcnZpY2Uuc2V0Rm9jdXMoaXRlbS55ZWFyICsgeWVhck9mZnNldCk7XG4gICAgfVxuXG4gICAgdHJhY2tSb3dCeUZuKGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgdHJhY2tZZWFyQnlGbihfaW5kZXg6IG51bWJlciwgaXRlbTogWWVhclZpZXdJdGVtKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIGl0ZW0ueWVhcjtcbiAgICB9XG5cbiAgICBnZXRUYWJiYWJsZShpdGVtOiBZZWFyVmlld0l0ZW0pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgZm9jdXNlZCA9IHRoaXMueWVhclNlcnZpY2UuZm9jdXNlZCQudmFsdWU7XG4gICAgICAgIGNvbnN0IGdyaWQgPSB0aGlzLnllYXJTZXJ2aWNlLmdyaWQkLnZhbHVlO1xuXG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIGEgZm9jdXNlZCB5ZWFyIGNoZWNrIGlmIHRoaXMgaXMgaXRcbiAgICAgICAgaWYgKGZvY3VzZWQpIHtcblxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGZvY3VzZWQgeWVhciBpcyB2aXNpYmxlXG4gICAgICAgICAgICBjb25zdCBpc0ZvY3VzZWRZZWFyVmlzaWJsZSA9ICEhZ3JpZC5maW5kKHJvdyA9PiAhIXJvdy5maW5kKF9pdGVtID0+IF9pdGVtLnllYXIgPT09IGZvY3VzZWQpKTtcblxuICAgICAgICAgICAgaWYgKGlzRm9jdXNlZFllYXJWaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvY3VzZWQgPT09IGl0ZW0ueWVhcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGZvY3VzYWJsZSB5ZWFyIHRoZW4gY2hlY2sgaWYgdGhlcmUgaXMgYSBzZWxlY3RlZCB5ZWFyXG4gICAgICAgIGNvbnN0IGlzU2VsZWN0ZWRZZWFyVmlzaWJsZSA9ICEhZ3JpZC5maW5kKHJvdyA9PiAhIXJvdy5maW5kKHllYXIgPT4geWVhci5pc0FjdGl2ZVllYXIpKTtcblxuICAgICAgICBpZiAoaXNTZWxlY3RlZFllYXJWaXNpYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlbS5pc0FjdGl2ZVllYXI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBvdGhlcndpc2UgZmluZCB0aGUgZmlyc3Qgbm9uLWRpc2FibGVkIG1vbnRoXG4gICAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMueWVhclNlcnZpY2UuZ3JpZCQudmFsdWUpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIHJvdykge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5nZXREaXNhYmxlZChjb2x1bW4pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtID09PSBjb2x1bW47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gb3RoZXJ3aXNlIG1ha2UgdGhlIGZpcnN0IG1vbnRoIHRhYmJhYmxlXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKiogQW5ub3VuY2UgdGhlIGRhdGUgd2hlbiB3ZSBmb2N1cyBvbiBhIGRhdGUgKi9cbiAgICBhbm5vdW5jZVJhbmdlTW9kZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzUmFuZ2VNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLl9saXZlQW5ub3VuY2VyLmFubm91bmNlKHRoaXMuX2lzUmFuZ2VTdGFydCA/IHRoaXMuX3JhbmdlU2VydmljZS5zdGFydFBpY2tlckFyaWFMYWJlbCA6IHRoaXMuX3JhbmdlU2VydmljZS5lbmRQaWNrZXJBcmlhTGFiZWwpO1xuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCI8ZGl2IGNsYXNzPVwiY2FsZW5kYXJcIiByb2xlPVwiZ3JpZFwiPlxuICBAZm9yIChyb3cgb2YgeWVhclNlcnZpY2UuZ3JpZCQgfCBhc3luYzsgdHJhY2sgdHJhY2tSb3dCeUZuKCRpbmRleCkpIHtcbiAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItcm93XCIgcm9sZT1cInJvd1wiPlxuICAgICAgQGZvciAoaXRlbSBvZiByb3c7IHRyYWNrIHRyYWNrWWVhckJ5Rm4oJGluZGV4LCBpdGVtKSkge1xuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdXhGb2N1c0luZGljYXRvclxuICAgICAgICAgIHV4Rm9jdXNJbmRpY2F0b3JPcmlnaW5cbiAgICAgICAgICBbcHJvZ3JhbW1hdGljRm9jdXNJbmRpY2F0b3JdPVwidHJ1ZVwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgcm9sZT1cImdyaWRjZWxsXCJcbiAgICAgICAgICBjbGFzcz1cImNhbGVuZGFyLWl0ZW1cIlxuICAgICAgICAgIFtmb2N1c0lmXT1cIih5ZWFyU2VydmljZS5mb2N1c2VkJCB8IGFzeW5jKSA9PT0gaXRlbS55ZWFyXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIml0ZW0ueWVhclwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJpdGVtLmlzQWN0aXZlWWVhclwiXG4gICAgICAgICAgW2NsYXNzLmN1cnJlbnRdPVwiaXRlbS5pc0N1cnJlbnRZZWFyXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cIml0ZW0uaXNBY3RpdmVZZWFyICYmICFnZXREaXNhYmxlZChpdGVtKVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImdldERpc2FibGVkKGl0ZW0pXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0KGl0ZW0ueWVhcik7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgKGZvY3VzKT1cImFubm91bmNlUmFuZ2VNb2RlKClcIlxuICAgICAgICAgIChrZXlkb3duLkFycm93TGVmdCk9XCJmb2N1c1llYXIoaXRlbSwgLTEpOyAkZXZlbnQucHJldmVudERlZmF1bHQoKVwiXG4gICAgICAgICAgKGtleWRvd24uQXJyb3dSaWdodCk9XCJmb2N1c1llYXIoaXRlbSwgMSk7ICRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCJcbiAgICAgICAgICAoa2V5ZG93bi5BcnJvd1VwKT1cImZvY3VzWWVhcihpdGVtLCAtNCk7ICRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCJcbiAgICAgICAgICAoa2V5ZG93bi5BcnJvd0Rvd24pPVwiZm9jdXNZZWFyKGl0ZW0sIDQpOyAkZXZlbnQucHJldmVudERlZmF1bHQoKVwiXG4gICAgICAgICAgW3RhYmluZGV4XT1cImdldFRhYmJhYmxlKGl0ZW0pID8gMCA6IC0xXCI+XG4gICAgICAgICAge3sgaXRlbS55ZWFyIH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICB9XG48L2Rpdj5cbiJdfQ==