xui
Version:
xUI Components for Angular
185 lines • 29.8 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, Input, Optional, Self, ViewChild } from '@angular/core';
import { DateTime } from 'luxon';
import { NgControl } from '@angular/forms';
import { InputBoolean } from '../utils';
import { InputComponent } from '../input';
import { DATE_PICKER_MODULE, WithConfig, XuiConfigService } from '../config';
import * as i0 from "@angular/core";
import * as i1 from "../config";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/common";
import * as i4 from "../icon/icon.component";
import * as i5 from "@angular/cdk/overlay";
import * as i6 from "@angular/cdk/a11y";
export class DatePickerComponent {
get value() {
return this._value?.toISODate() ?? null;
}
set value(v) {
if (!v) {
this._value = null;
this.input.value = null;
this.onChange?.(v);
this.cdr.markForCheck();
return;
}
const date = DateTime.fromISO(v).startOf('day');
if (this._value !== date) {
this._value = date;
this.focus = date;
this.input.value = date.setLocale('en-us').toLocaleString(DateTime.DATE_MED); // TODO: use globally defined locale
this.onChange?.(v);
this.cdr.markForCheck();
}
}
get styles() {
const ret = {
'x-datepicker': true
};
ret[`x-datepicker-${this.color}`] = true;
ret[`x-datepicker-${this.size}`] = true;
return ret;
}
constructor(configService, cdr, control) {
this.configService = configService;
this.cdr = cdr;
this.control = control;
this._moduleName = DATE_PICKER_MODULE;
this._value = null;
this.indices = Array.from(Array(7 * 6)).map((x, i) => i);
this.isOpen = false;
this.isFocus = false;
this.mouseDown = false;
this.disabled = false;
this.readOnly = false;
this.color = 'light';
this.size = 'large';
if (this.control) {
this.control.valueAccessor = this;
}
}
ngOnInit() {
this.control?.statusChanges?.subscribe(() => this.cdr.markForCheck());
}
getDay(index) {
return this.focus
.startOf('month')
.startOf('week')
.plus({ days: index - 1 });
}
isSelected(index) {
return this._value?.toISODate() === this.getDay(index).toISODate();
}
isOutsideOfMonth(index) {
const day = this.getDay(index);
return day < this.focus.startOf('month') || day > this.focus.endOf('month');
}
updateMonth(add) {
this.focus = this.focus.plus({ month: add ? 1 : -1 });
}
onClick(index) {
const day = this.getDay(index);
if (this.disabledDate?.(day)) {
return;
}
this.value = day.toISODate();
this.close();
}
writeValue(source) {
this.value = source;
}
registerOnChange(onChange) {
this.onChange = onChange;
}
registerOnTouched(onTouched) {
this.onTouched = onTouched;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
_focusOut() {
this.onTouched?.();
}
_keyPress(event) {
event?.preventDefault();
this.open();
}
isFocused(index) {
return this.focus.toISODate() === this.getDay(index).toISODate();
}
focusMove(days) {
const day = this.focus.plus({ days });
if (this.disabledDate?.(day)) {
return;
}
this.focus = day;
}
applyFocused() {
this.value = this.focus.toISODate();
this.close();
}
open() {
this.focus = this._value ?? DateTime.now().startOf('day');
this.isOpen = !this.readOnly && !this.disabled;
}
close() {
this.isOpen = false;
this.isFocus = false;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: DatePickerComponent, deps: [{ token: i1.XuiConfigService }, { token: i0.ChangeDetectorRef }, { token: i2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.1", type: DatePickerComponent, selector: "xui-date-picker", inputs: { allowClear: "allowClear", disabledDate: "disabledDate", placeholder: "placeholder", disabled: "disabled", readOnly: "readOnly", color: "color", size: "size", value: "value" }, host: { listeners: { "focusout": "_focusOut()", "keydown.enter": "_keyPress($event)", "keydown.space": "_keyPress($event)" } }, viewQueries: [{ propertyName: "input", first: true, predicate: InputComponent, descendants: true, static: true }], ngImport: i0, template: "<div [ngClass]=\"styles\" [tabindex]=\"disabled ? -1 : 0\" cdkOverlayOrigin #trigger=\"cdkOverlayOrigin\">\n <input\n tabindex=\"-1\"\n type=\"text\"\n readonly\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder ?? ''\"\n [value]=\"value\"\n (click)=\"open()\"\n />\n <xui-icon>calendar</xui-icon>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent'\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n (backdropClick)=\"isOpen = false\"\n>\n <div class=\"x-datepicker-popup\" cdkTrapFocus>\n <div class=\"x-datepicker-header\">\n <div\n class=\"x-datepicker-button\"\n tabindex=\"0\"\n (click)=\"updateMonth(false)\"\n (keydown.enter)=\"updateMonth(false)\"\n (keydown.space)=\"updateMonth(false)\"\n >\n <xui-icon>chevron-left</xui-icon>\n </div>\n {{ focus.toFormat('MMMM yyyy') }}\n <div\n class=\"x-datepicker-button\"\n tabindex=\"0\"\n (click)=\"updateMonth(true)\"\n (keydown.enter)=\"updateMonth(true)\"\n (keydown.space)=\"updateMonth(true)\"\n >\n <xui-icon>chevron-right</xui-icon>\n </div>\n </div>\n\n <div class=\"x-datepicker-title\">\n <div>SU</div>\n <div>MO</div>\n <div>TU</div>\n <div>WE</div>\n <div>TH</div>\n <div>FR</div>\n <div>SA</div>\n </div>\n <div\n class=\"x-datepicker-calendar\"\n tabindex=\"0\"\n (mousedown)=\"mouseDown = true\"\n (mouseup)=\"mouseDown = false\"\n (keydown.enter)=\"applyFocused()\"\n (keydown.space)=\"applyFocused()\"\n (keydown.arrowUp)=\"focusMove(-7)\"\n (keydown.arrowDown)=\"focusMove(7)\"\n (keydown.arrowLeft)=\"focusMove(-1)\"\n (keydown.arrowRight)=\"focusMove(1)\"\n (focusin)=\"isFocus = !mouseDown\"\n (focusout)=\"isFocus = false\"\n >\n <div\n *ngFor=\"let index of indices\"\n class=\"x-datepicker-day\"\n [class.x-datepicker--outside]=\"isOutsideOfMonth(index)\"\n [class.x-datepicker--disabled]=\"disabledDate?.(getDay(index))\"\n [class.x-datepicker--selected]=\"isSelected(index)\"\n [class.x-datepicker--focused]=\"isFocused(index) && isFocus\"\n (click)=\"onClick(index)\"\n >\n {{ getDay(index).day }}\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i4.IconComponent, selector: "xui-icon" }, { kind: "directive", type: i5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i6.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "disabled", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], DatePickerComponent.prototype, "readOnly", void 0);
__decorate([
WithConfig(),
__metadata("design:type", String)
], DatePickerComponent.prototype, "color", void 0);
__decorate([
WithConfig(),
__metadata("design:type", String)
], DatePickerComponent.prototype, "size", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: DatePickerComponent, decorators: [{
type: Component,
args: [{ selector: 'xui-date-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"styles\" [tabindex]=\"disabled ? -1 : 0\" cdkOverlayOrigin #trigger=\"cdkOverlayOrigin\">\n <input\n tabindex=\"-1\"\n type=\"text\"\n readonly\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder ?? ''\"\n [value]=\"value\"\n (click)=\"open()\"\n />\n <xui-icon>calendar</xui-icon>\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent'\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n (backdropClick)=\"isOpen = false\"\n>\n <div class=\"x-datepicker-popup\" cdkTrapFocus>\n <div class=\"x-datepicker-header\">\n <div\n class=\"x-datepicker-button\"\n tabindex=\"0\"\n (click)=\"updateMonth(false)\"\n (keydown.enter)=\"updateMonth(false)\"\n (keydown.space)=\"updateMonth(false)\"\n >\n <xui-icon>chevron-left</xui-icon>\n </div>\n {{ focus.toFormat('MMMM yyyy') }}\n <div\n class=\"x-datepicker-button\"\n tabindex=\"0\"\n (click)=\"updateMonth(true)\"\n (keydown.enter)=\"updateMonth(true)\"\n (keydown.space)=\"updateMonth(true)\"\n >\n <xui-icon>chevron-right</xui-icon>\n </div>\n </div>\n\n <div class=\"x-datepicker-title\">\n <div>SU</div>\n <div>MO</div>\n <div>TU</div>\n <div>WE</div>\n <div>TH</div>\n <div>FR</div>\n <div>SA</div>\n </div>\n <div\n class=\"x-datepicker-calendar\"\n tabindex=\"0\"\n (mousedown)=\"mouseDown = true\"\n (mouseup)=\"mouseDown = false\"\n (keydown.enter)=\"applyFocused()\"\n (keydown.space)=\"applyFocused()\"\n (keydown.arrowUp)=\"focusMove(-7)\"\n (keydown.arrowDown)=\"focusMove(7)\"\n (keydown.arrowLeft)=\"focusMove(-1)\"\n (keydown.arrowRight)=\"focusMove(1)\"\n (focusin)=\"isFocus = !mouseDown\"\n (focusout)=\"isFocus = false\"\n >\n <div\n *ngFor=\"let index of indices\"\n class=\"x-datepicker-day\"\n [class.x-datepicker--outside]=\"isOutsideOfMonth(index)\"\n [class.x-datepicker--disabled]=\"disabledDate?.(getDay(index))\"\n [class.x-datepicker--selected]=\"isSelected(index)\"\n [class.x-datepicker--focused]=\"isFocused(index) && isFocus\"\n (click)=\"onClick(index)\"\n >\n {{ getDay(index).day }}\n </div>\n </div>\n </div>\n</ng-template>\n" }]
}], ctorParameters: function () { return [{ type: i1.XuiConfigService }, { type: i0.ChangeDetectorRef }, { type: i2.NgControl, decorators: [{
type: Self
}, {
type: Optional
}] }]; }, propDecorators: { allowClear: [{
type: Input
}], disabledDate: [{
type: Input
}], placeholder: [{
type: Input
}], disabled: [{
type: Input
}], readOnly: [{
type: Input
}], color: [{
type: Input
}], size: [{
type: Input
}], input: [{
type: ViewChild,
args: [InputComponent, { static: true }]
}], value: [{
type: Input
}], _focusOut: [{
type: HostListener,
args: ['focusout']
}], _keyPress: [{
type: HostListener,
args: ['keydown.enter', ['$event']]
}, {
type: HostListener,
args: ['keydown.space', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy94dWkvc3JjL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMveHVpL3NyYy9kYXRlLXBpY2tlci9kYXRlLXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBRUwsUUFBUSxFQUNSLElBQUksRUFDSixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUNqQyxPQUFPLEVBQXdCLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDeEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUcxQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sV0FBVyxDQUFDOzs7Ozs7OztBQU83RSxNQUFNLE9BQU8sbUJBQW1CO0lBeUI5QixJQUNJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksSUFBSSxDQUFDO0lBQzFDLENBQUM7SUFFRCxJQUFJLEtBQUssQ0FBQyxDQUFDO1FBQ1QsSUFBSSxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ25CLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztZQUN4QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZ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VSxFQUFFOztpREFBZ0M7MkZBckIzQyxtQkFBbUI7a0JBTC9CLFNBQVM7K0JBQ0UsaUJBQWlCLG1CQUNWLHVCQUF1QixDQUFDLE1BQU07OzBCQWtFNUMsSUFBSTs7MEJBQUksUUFBUTs0Q0FoRFYsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ21CLFFBQVE7c0JBQWhDLEtBQUs7Z0JBQ21CLFFBQVE7c0JBQWhDLEtBQUs7Z0JBQ2lCLEtBQUs7c0JBQTNCLEtBQUs7Z0JBQ2lCLElBQUk7c0JBQTFCLEtBQUs7Z0JBRXVDLEtBQUs7c0JBQWpELFNBQVM7dUJBQUMsY0FBYyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFHdkMsS0FBSztzQkFEUixLQUFLO2dCQWdHRSxTQUFTO3NCQURoQixZQUFZO3VCQUFDLFVBQVU7Z0JBT2hCLFNBQVM7c0JBRmhCLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDOztzQkFDeEMsWUFBWTt1QkFBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgU2VsZixcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICdsdXhvbic7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTmdDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSW5wdXRCb29sZWFuIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgSW5wdXRDb21wb25lbnQgfSBmcm9tICcuLi9pbnB1dCc7XG5pbXBvcnQgeyBCb29sZWFuSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgRGF0ZVBpY2tlckNvbG9yLCBEYXRlUGlja2VyU2l6ZSB9IGZyb20gJy4vZGF0ZS1waWNrZXIudHlwZXMnO1xuaW1wb3J0IHsgREFURV9QSUNLRVJfTU9EVUxFLCBXaXRoQ29uZmlnLCBYdWlDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vY29uZmlnJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAneHVpLWRhdGUtcGlja2VyJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLXBpY2tlci5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgRGF0ZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQge1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfZGlzYWJsZWQ6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX3JlYWRPbmx5OiBCb29sZWFuSW5wdXQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgX21vZHVsZU5hbWUgPSBEQVRFX1BJQ0tFUl9NT0RVTEU7XG5cbiAgcHJpdmF0ZSBvbkNoYW5nZT86IChzb3VyY2U6IHN0cmluZyB8IG51bGwpID0+IHZvaWQ7XG4gIHByaXZhdGUgb25Ub3VjaGVkPzogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBfdmFsdWU6IERhdGVUaW1lIHwgbnVsbCA9IG51bGw7XG5cbiAgZm9jdXMhOiBEYXRlVGltZTtcbiAgaW5kaWNlcyA9IEFycmF5LmZyb20oQXJyYXkoNyAqIDYpKS5tYXAoKHgsIGkpID0+IGkpO1xuICBpc09wZW4gPSBmYWxzZTtcbiAgaXNGb2N1cyA9IGZhbHNlO1xuICBtb3VzZURvd24gPSBmYWxzZTtcblxuICBASW5wdXQoKSBhbGxvd0NsZWFyPzogYm9vbGVhbjsgLy8gVE9ET1xuICBASW5wdXQoKSBkaXNhYmxlZERhdGU/OiAoY3VycmVudDogRGF0ZVRpbWUpID0+IGJvb2xlYW47XG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyPzogc3RyaW5nO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIHJlYWRPbmx5ID0gZmFsc2U7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgY29sb3I6IERhdGVQaWNrZXJDb2xvciA9ICdsaWdodCc7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgc2l6ZTogRGF0ZVBpY2tlclNpemUgPSAnbGFyZ2UnO1xuXG4gIEBWaWV3Q2hpbGQoSW5wdXRDb21wb25lbnQsIHsgc3RhdGljOiB0cnVlIH0pIGlucHV0ITogSW5wdXRDb21wb25lbnQ7XG5cbiAgQElucHV0KClcbiAgZ2V0IHZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZT8udG9JU09EYXRlKCkgPz8gbnVsbDtcbiAgfVxuXG4gIHNldCB2YWx1ZSh2KSB7XG4gICAgaWYgKCF2KSB7XG4gICAgICB0aGlzLl92YWx1ZSA9IG51bGw7XG4gICAgICB0aGlzLmlucHV0LnZhbHVlID0gbnVsbDtcbiAgICAgIHRoaXMub25DaGFuZ2U/Lih2KTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGF0ZSA9IERhdGVUaW1lLmZyb21JU08odikuc3RhcnRPZignZGF5Jyk7XG4gICAgaWYgKHRoaXMuX3ZhbHVlICE9PSBkYXRlKSB7XG4gICAgICB0aGlzLl92YWx1ZSA9IGRhdGU7XG4gICAgICB0aGlzLmZvY3VzID0gZGF0ZTtcbiAgICAgIHRoaXMuaW5wdXQudmFsdWUgPSBkYXRlLnNldExvY2FsZSgnZW4tdXMnKS50b0xvY2FsZVN0cmluZyhEYXRlVGltZS5EQVRFX01FRCk7IC8vIFRPRE86IHVzZSBnbG9iYWxseSBkZWZpbmVkIGxvY2FsZVxuICAgICAgdGhpcy5vbkNoYW5nZT8uKHYpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHN0eWxlcygpIHtcbiAgICBjb25zdCByZXQ6IHsgW2tsYXNzOiBzdHJpbmddOiBib29sZWFuIH0gPSB7XG4gICAgICAneC1kYXRlcGlja2VyJzogdHJ1ZVxuICAgIH07XG5cbiAgICByZXRbYHgtZGF0ZXBpY2tlci0ke3RoaXMuY29sb3J9YF0gPSB0cnVlO1xuICAgIHJldFtgeC1kYXRlcGlja2VyLSR7dGhpcy5zaXplfWBdID0gdHJ1ZTtcbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjb25maWdTZXJ2aWNlOiBYdWlDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAU2VsZigpIEBPcHRpb25hbCgpIHB1YmxpYyBjb250cm9sPzogTmdDb250cm9sXG4gICkge1xuICAgIGlmICh0aGlzLmNvbnRyb2wpIHtcbiAgICAgIHRoaXMuY29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmNvbnRyb2w/LnN0YXR1c0NoYW5nZXM/LnN1YnNjcmliZSgoKSA9PiB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKSk7XG4gIH1cblxuICBnZXREYXkoaW5kZXg6IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLmZvY3VzXG4gICAgICAuc3RhcnRPZignbW9udGgnKVxuICAgICAgLnN0YXJ0T2YoJ3dlZWsnKVxuICAgICAgLnBsdXMoeyBkYXlzOiBpbmRleCAtIDEgfSk7XG4gIH1cblxuICBpc1NlbGVjdGVkKGluZGV4OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWU/LnRvSVNPRGF0ZSgpID09PSB0aGlzLmdldERheShpbmRleCkudG9JU09EYXRlKCk7XG4gIH1cblxuICBpc091dHNpZGVPZk1vbnRoKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBkYXkgPSB0aGlzLmdldERheShpbmRleCk7XG4gICAgcmV0dXJuIGRheSA8IHRoaXMuZm9jdXMuc3RhcnRPZignbW9udGgnKSB8fCBkYXkgPiB0aGlzLmZvY3VzLmVuZE9mKCdtb250aCcpO1xuICB9XG5cbiAgdXBkYXRlTW9udGgoYWRkOiBib29sZWFuKSB7XG4gICAgdGhpcy5mb2N1cyA9IHRoaXMuZm9jdXMucGx1cyh7IG1vbnRoOiBhZGQgPyAxIDogLTEgfSk7XG4gIH1cblxuICBvbkNsaWNrKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBkYXkgPSB0aGlzLmdldERheShpbmRleCk7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWREYXRlPy4oZGF5KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWUgPSBkYXkudG9JU09EYXRlKCk7XG4gICAgdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZShzb3VyY2U6IHN0cmluZykge1xuICAgIHRoaXMudmFsdWUgPSBzb3VyY2U7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKG9uQ2hhbmdlOiAoc291cmNlOiBzdHJpbmcgfCBudWxsKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IG9uQ2hhbmdlO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQob25Ub3VjaGVkOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBvblRvdWNoZWQ7XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2ZvY3Vzb3V0JylcbiAgcHJpdmF0ZSBfZm9jdXNPdXQoKSB7XG4gICAgdGhpcy5vblRvdWNoZWQ/LigpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bi5lbnRlcicsIFsnJGV2ZW50J10pXG4gIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24uc3BhY2UnLCBbJyRldmVudCddKVxuICBwcml2YXRlIF9rZXlQcmVzcyhldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGV2ZW50Py5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICB9XG5cbiAgaXNGb2N1c2VkKGluZGV4OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5mb2N1cy50b0lTT0RhdGUoKSA9PT0gdGhpcy5nZXREYXkoaW5kZXgpLnRvSVNPRGF0ZSgpO1xuICB9XG5cbiAgZm9jdXNNb3ZlKGRheXM6IG51bWJlcikge1xuICAgIGNvbnN0IGRheSA9IHRoaXMuZm9jdXMucGx1cyh7IGRheXMgfSk7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWREYXRlPy4oZGF5KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZm9jdXMgPSBkYXk7XG4gIH1cblxuICBhcHBseUZvY3VzZWQoKSB7XG4gICAgdGhpcy52YWx1ZSA9IHRoaXMuZm9jdXMudG9JU09EYXRlKCk7XG4gICAgdGhpcy5jbG9zZSgpO1xuICB9XG5cbiAgb3BlbigpIHtcbiAgICB0aGlzLmZvY3VzID0gdGhpcy5fdmFsdWUgPz8gRGF0ZVRpbWUubm93KCkuc3RhcnRPZignZGF5Jyk7XG4gICAgdGhpcy5pc09wZW4gPSAhdGhpcy5yZWFkT25seSAmJiAhdGhpcy5kaXNhYmxlZDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2UoKSB7XG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmlzRm9jdXMgPSBmYWxzZTtcbiAgfVxufVxuIiwiPGRpdiBbbmdDbGFzc109XCJzdHlsZXNcIiBbdGFiaW5kZXhdPVwiZGlzYWJsZWQgPyAtMSA6IDBcIiBjZGtPdmVybGF5T3JpZ2luICN0cmlnZ2VyPVwiY2RrT3ZlcmxheU9yaWdpblwiPlxuICA8aW5wdXRcbiAgICB0YWJpbmRleD1cIi0xXCJcbiAgICB0eXBlPVwidGV4dFwiXG4gICAgcmVhZG9ubHlcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlciA/PyAnJ1wiXG4gICAgW3ZhbHVlXT1cInZhbHVlXCJcbiAgICAoY2xpY2spPVwib3BlbigpXCJcbiAgLz5cbiAgPHh1aS1pY29uPmNhbGVuZGFyPC94dWktaWNvbj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGVcbiAgY2RrQ29ubmVjdGVkT3ZlcmxheVxuICBjZGtDb25uZWN0ZWRPdmVybGF5SGFzQmFja2Ryb3BcbiAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlCYWNrZHJvcENsYXNzXT1cIidjZGstb3ZlcmxheS10cmFuc3BhcmVudCdcIlxuICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJ0cmlnZ2VyXCJcbiAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlPcGVuXT1cImlzT3BlblwiXG4gIChiYWNrZHJvcENsaWNrKT1cImlzT3BlbiA9IGZhbHNlXCJcbj5cbiAgPGRpdiBjbGFzcz1cIngtZGF0ZXBpY2tlci1wb3B1cFwiIGNka1RyYXBGb2N1cz5cbiAgICA8ZGl2IGNsYXNzPVwieC1kYXRlcGlja2VyLWhlYWRlclwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cIngtZGF0ZXBpY2tlci1idXR0b25cIlxuICAgICAgICB0YWJpbmRleD1cIjBcIlxuICAgICAgICAoY2xpY2spPVwidXBkYXRlTW9udGgoZmFsc2UpXCJcbiAgICAgICAgKGtleWRvd24uZW50ZXIpPVwidXBkYXRlTW9udGgoZmFsc2UpXCJcbiAgICAgICAgKGtleWRvd24uc3BhY2UpPVwidXBkYXRlTW9udGgoZmFsc2UpXCJcbiAgICAgID5cbiAgICAgICAgPHh1aS1pY29uPmNoZXZyb24tbGVmdDwveHVpLWljb24+XG4gICAgICA8L2Rpdj5cbiAgICAgIHt7IGZvY3VzLnRvRm9ybWF0KCdNTU1NIHl5eXknKSB9fVxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cIngtZGF0ZXBpY2tlci1idXR0b25cIlxuICAgICAgICB0YWJpbmRleD1cIjBcIlxuICAgICAgICAoY2xpY2spPVwidXBkYXRlTW9udGgodHJ1ZSlcIlxuICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJ1cGRhdGVNb250aCh0cnVlKVwiXG4gICAgICAgIChrZXlkb3duLnNwYWNlKT1cInVwZGF0ZU1vbnRoKHRydWUpXCJcbiAgICAgID5cbiAgICAgICAgPHh1aS1pY29uPmNoZXZyb24tcmlnaHQ8L3h1aS1pY29uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwieC1kYXRlcGlja2VyLXRpdGxlXCI+XG4gICAgICA8ZGl2PlNVPC9kaXY+XG4gICAgICA8ZGl2Pk1PPC9kaXY+XG4gICAgICA8ZGl2PlRVPC9kaXY+XG4gICAgICA8ZGl2PldFPC9kaXY+XG4gICAgICA8ZGl2PlRIPC9kaXY+XG4gICAgICA8ZGl2PkZSPC9kaXY+XG4gICAgICA8ZGl2PlNBPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJ4LWRhdGVwaWNrZXItY2FsZW5kYXJcIlxuICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgIChtb3VzZWRvd24pPVwibW91c2VEb3duID0gdHJ1ZVwiXG4gICAgICAobW91c2V1cCk9XCJtb3VzZURvd24gPSBmYWxzZVwiXG4gICAgICAoa2V5ZG93bi5lbnRlcik9XCJhcHBseUZvY3VzZWQoKVwiXG4gICAgICAoa2V5ZG93bi5zcGFjZSk9XCJhcHBseUZvY3VzZWQoKVwiXG4gICAgICAoa2V5ZG93bi5hcnJvd1VwKT1cImZvY3VzTW92ZSgtNylcIlxuICAgICAgKGtleWRvd24uYXJyb3dEb3duKT1cImZvY3VzTW92ZSg3KVwiXG4gICAgICAoa2V5ZG93bi5hcnJvd0xlZnQpPVwiZm9jdXNNb3ZlKC0xKVwiXG4gICAgICAoa2V5ZG93bi5hcnJvd1JpZ2h0KT1cImZvY3VzTW92ZSgxKVwiXG4gICAgICAoZm9jdXNpbik9XCJpc0ZvY3VzID0gIW1vdXNlRG93blwiXG4gICAgICAoZm9jdXNvdXQpPVwiaXNGb2N1cyA9IGZhbHNlXCJcbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0Zvcj1cImxldCBpbmRleCBvZiBpbmRpY2VzXCJcbiAgICAgICAgY2xhc3M9XCJ4LWRhdGVwaWNrZXItZGF5XCJcbiAgICAgICAgW2NsYXNzLngtZGF0ZXBpY2tlci0tb3V0c2lkZV09XCJpc091dHNpZGVPZk1vbnRoKGluZGV4KVwiXG4gICAgICAgIFtjbGFzcy54LWRhdGVwaWNrZXItLWRpc2FibGVkXT1cImRpc2FibGVkRGF0ZT8uKGdldERheShpbmRleCkpXCJcbiAgICAgICAgW2NsYXNzLngtZGF0ZXBpY2tlci0tc2VsZWN0ZWRdPVwiaXNTZWxlY3RlZChpbmRleClcIlxuICAgICAgICBbY2xhc3MueC1kYXRlcGlja2VyLS1mb2N1c2VkXT1cImlzRm9jdXNlZChpbmRleCkgJiYgaXNGb2N1c1wiXG4gICAgICAgIChjbGljayk9XCJvbkNsaWNrKGluZGV4KVwiXG4gICAgICA+XG4gICAgICAgIHt7IGdldERheShpbmRleCkuZGF5IH19XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19