ngx-material-timepicker
Version:
Handy material design timepicker for angular
171 lines • 25.6 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { TimeParserPipe } from '../../../pipes/time-parser.pipe';
import { isDigit } from '../../../utils/timepicker.utils';
import * as i0 from "@angular/core";
import * as i1 from "../../../pipes/time-parser.pipe";
import * as i2 from "@angular/common";
import * as i3 from "@angular/forms";
import * as i4 from "../../../pipes/time-localizer.pipe";
export class NgxTimepickerTimeControlComponent {
constructor(timeParser) {
this.timeParser = timeParser;
this.timeChanged = new EventEmitter();
}
ngOnChanges(changes) {
if (changes.timeList && this.time != null) {
if (this.isSelectedTimeDisabled(this.time)) {
this.setAvailableTime();
}
}
}
changeTime(event) {
event.stopPropagation();
const char = String.fromCharCode(event.keyCode);
const time = concatTime(String(this.time), char);
this.changeTimeIfValid(time);
}
onKeydown(event) {
event.stopPropagation();
if (!isDigit(event)) {
event.preventDefault();
}
switch (event.key) {
case 'ArrowUp':
this.increase();
break;
case 'ArrowDown':
this.decrease();
break;
}
if (this.preventTyping && event.key !== 'Tab') {
event.preventDefault();
}
}
increase() {
if (!this.disabled) {
let nextTime = +this.time + (this.minutesGap || 1);
if (nextTime > this.max) {
nextTime = this.min;
}
if (this.isSelectedTimeDisabled(nextTime)) {
nextTime = this.getAvailableTime(nextTime, this.getNextAvailableTime.bind(this));
}
if (nextTime !== this.time) {
this.timeChanged.emit(nextTime);
}
}
}
decrease() {
if (!this.disabled) {
let previousTime = +this.time - (this.minutesGap || 1);
if (previousTime < this.min) {
previousTime = this.minutesGap ? this.max - (this.minutesGap - 1) : this.max;
}
if (this.isSelectedTimeDisabled(previousTime)) {
previousTime = this.getAvailableTime(previousTime, this.getPrevAvailableTime.bind(this));
}
if (previousTime !== this.time) {
this.timeChanged.emit(previousTime);
}
}
}
onFocus() {
this.isFocused = true;
this.previousTime = this.time;
}
onBlur() {
this.isFocused = false;
if (this.previousTime !== this.time) {
this.changeTimeIfValid(+this.time);
}
}
onModelChange(value) {
this.time = +this.timeParser.transform(value, this.timeUnit);
}
changeTimeIfValid(value) {
if (!isNaN(value)) {
this.time = value;
if (this.time > this.max) {
const timeString = String(value);
this.time = +timeString[timeString.length - 1];
}
if (this.time < this.min) {
this.time = this.min;
}
this.timeChanged.emit(this.time);
}
}
isSelectedTimeDisabled(time) {
return this.timeList.find((faceTime) => faceTime.time === time).disabled;
}
getNextAvailableTime(index) {
const timeCollection = this.timeList;
const maxValue = timeCollection.length;
for (let i = index + 1; i < maxValue; i++) {
const time = timeCollection[i];
if (!time.disabled) {
return time.time;
}
}
}
getPrevAvailableTime(index) {
for (let i = index; i >= 0; i--) {
const time = this.timeList[i];
if (!time.disabled) {
return time.time;
}
}
}
getAvailableTime(currentTime, fn) {
const currentTimeIndex = this.timeList.findIndex(time => time.time === currentTime);
const availableTime = fn(currentTimeIndex);
return availableTime != null ? availableTime : this.time;
}
setAvailableTime() {
const availableTime = this.timeList.find(t => !t.disabled);
if (availableTime != null) {
this.time = availableTime.time;
this.timeChanged.emit(this.time);
}
}
}
NgxTimepickerTimeControlComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: NgxTimepickerTimeControlComponent, deps: [{ token: i1.TimeParserPipe }], target: i0.ɵɵFactoryTarget.Component });
NgxTimepickerTimeControlComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: NgxTimepickerTimeControlComponent, selector: "ngx-timepicker-time-control", inputs: { time: "time", min: "min", max: "max", placeholder: "placeholder", timeUnit: "timeUnit", disabled: "disabled", timeList: "timeList", preventTyping: "preventTyping", minutesGap: "minutesGap" }, outputs: { timeChanged: "timeChanged" }, providers: [TimeParserPipe], usesOnChanges: true, ngImport: i0, template: "<div class=\"ngx-timepicker-control\" [ngClass]=\"{'ngx-timepicker-control--active': isFocused}\">\n <!--suppress HtmlFormInputWithoutLabel -->\n <input class=\"ngx-timepicker-control__input\"\n maxlength=\"2\"\n [ngModel]=\"time | timeParser: timeUnit | timeLocalizer: timeUnit : true\"\n (ngModelChange)=\"onModelChange($event)\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n (keydown)=\"onKeydown($event)\"\n (keypress)=\"changeTime($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\">\n <div class=\"ngx-timepicker-control__arrows\">\n <span class=\"ngx-timepicker-control__arrow\" role=\"button\" (click)=\"increase()\">\n ▲\n </span>\n <span class=\"ngx-timepicker-control__arrow\" role=\"button\" (click)=\"decrease()\">\n ▼\n </span>\n </div>\n</div>\n", styles: [".ngx-timepicker-control{position:relative;display:flex;width:60px;height:30px;padding:0 5px;box-sizing:border-box}.ngx-timepicker-control--active:after{content:\"\";position:absolute;bottom:-2px;left:0;width:100%;height:1px;background-color:#00bfff}.ngx-timepicker-control__input{width:100%;height:100%;padding:0 5px 0 0;border:0;font-size:1rem;color:inherit;outline:none;text-align:center}.ngx-timepicker-control__input:disabled{background-color:transparent}.ngx-timepicker-control__arrows{position:absolute;right:2px;top:0;display:flex;flex-direction:column}.ngx-timepicker-control__arrow{font-size:11px;color:#0006;cursor:pointer;transition:color .2s;-webkit-user-select:none;-moz-user-select:none;user-select:none}.ngx-timepicker-control__arrow:hover{color:#000000e6}\n"], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "timeLocalizer": i4.TimeLocalizerPipe, "timeParser": i1.TimeParserPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: NgxTimepickerTimeControlComponent, decorators: [{
type: Component,
args: [{
selector: 'ngx-timepicker-time-control',
templateUrl: './ngx-timepicker-time-control.component.html',
styleUrls: ['./ngx-timepicker-time-control.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [TimeParserPipe],
}]
}], ctorParameters: function () { return [{ type: i1.TimeParserPipe }]; }, propDecorators: { time: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], placeholder: [{
type: Input
}], timeUnit: [{
type: Input
}], disabled: [{
type: Input
}], timeList: [{
type: Input
}], preventTyping: [{
type: Input
}], minutesGap: [{
type: Input
}], timeChanged: [{
type: Output
}] } });
function concatTime(currentTime, nextTime) {
const isNumber = /\d/.test(nextTime);
if (isNumber) {
const time = currentTime + nextTime;
return +time;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbWF0ZXJpYWwtdGltZXBpY2tlci9jb21wb25lbnRzL3RpbWVwaWNrZXItZmllbGQvdGltZXBpY2tlci10aW1lLWNvbnRyb2wvbmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbWF0ZXJpYWwtdGltZXBpY2tlci9jb21wb25lbnRzL3RpbWVwaWNrZXItZmllbGQvdGltZXBpY2tlci10aW1lLWNvbnRyb2wvbmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQWlCLE1BQU0sZUFBZSxDQUFDO0FBRzFILE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7OztBQVUxRCxNQUFNLE9BQU8saUNBQWlDO0lBa0IxQyxZQUFvQixVQUEwQjtRQUExQixlQUFVLEdBQVYsVUFBVSxDQUFnQjtRQU5wQyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUFPbkQsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUM5QixJQUFJLE9BQU8sQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEVBQUU7WUFDdkMsSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUN4QyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzthQUMzQjtTQUNKO0lBQ0wsQ0FBQztJQUVE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dCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ2xvY2tGYWNlVGltZSB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9jbG9jay1mYWNlLXRpbWUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRpbWVVbml0IH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3RpbWUtdW5pdC5lbnVtJztcbmltcG9ydCB7IFRpbWVQYXJzZXJQaXBlIH0gZnJvbSAnLi4vLi4vLi4vcGlwZXMvdGltZS1wYXJzZXIucGlwZSc7XG5pbXBvcnQgeyBpc0RpZ2l0IH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvdGltZXBpY2tlci51dGlscyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vbmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9uZ3gtdGltZXBpY2tlci10aW1lLWNvbnRyb2wuY29tcG9uZW50LnNjc3MnXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBwcm92aWRlcnM6IFtUaW1lUGFyc2VyUGlwZV0sXG59KVxuXG5leHBvcnQgY2xhc3MgTmd4VGltZXBpY2tlclRpbWVDb250cm9sQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICAgIEBJbnB1dCgpIHRpbWU6IG51bWJlcjtcbiAgICBASW5wdXQoKSBtaW46IG51bWJlcjtcbiAgICBASW5wdXQoKSBtYXg6IG51bWJlcjtcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHRpbWVVbml0OiBUaW1lVW5pdDtcbiAgICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbjtcbiAgICBASW5wdXQoKSB0aW1lTGlzdDogQ2xvY2tGYWNlVGltZVtdO1xuICAgIEBJbnB1dCgpIHByZXZlbnRUeXBpbmc6IGJvb2xlYW47XG4gICAgQElucHV0KCkgbWludXRlc0dhcDogbnVtYmVyO1xuXG4gICAgQE91dHB1dCgpIHRpbWVDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICBpc0ZvY3VzZWQ6IGJvb2xlYW47XG5cbiAgICBwcml2YXRlIHByZXZpb3VzVGltZTogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSB0aW1lUGFyc2VyOiBUaW1lUGFyc2VyUGlwZSkge1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgaWYgKGNoYW5nZXMudGltZUxpc3QgJiYgdGhpcy50aW1lICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzU2VsZWN0ZWRUaW1lRGlzYWJsZWQodGhpcy50aW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0QXZhaWxhYmxlVGltZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2hhbmdlVGltZShldmVudDogYW55KTogdm9pZCB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmtleUNvZGUpO1xuICAgICAgICBjb25zdCB0aW1lID0gY29uY2F0VGltZShTdHJpbmcodGhpcy50aW1lKSwgY2hhcik7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VUaW1lSWZWYWxpZCh0aW1lKTtcbiAgICB9XG5cbiAgICBvbktleWRvd24oZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBpZiAoIWlzRGlnaXQoZXZlbnQpKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICAgICAgICAgIHRoaXMuaW5jcmVhc2UoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgICAgICAgICAgdGhpcy5kZWNyZWFzZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJldmVudFR5cGluZyAmJiBldmVudC5rZXkgIT09ICdUYWInKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaW5jcmVhc2UoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgbGV0IG5leHRUaW1lID0gK3RoaXMudGltZSArICh0aGlzLm1pbnV0ZXNHYXAgfHwgMSk7XG5cbiAgICAgICAgICAgIGlmIChuZXh0VGltZSA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICAgICAgbmV4dFRpbWUgPSB0aGlzLm1pbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuaXNTZWxlY3RlZFRpbWVEaXNhYmxlZChuZXh0VGltZSkpIHtcbiAgICAgICAgICAgICAgICBuZXh0VGltZSA9IHRoaXMuZ2V0QXZhaWxhYmxlVGltZShuZXh0VGltZSwgdGhpcy5nZXROZXh0QXZhaWxhYmxlVGltZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG5leHRUaW1lICE9PSB0aGlzLnRpbWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVDaGFuZ2VkLmVtaXQobmV4dFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGVjcmVhc2UoKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgbGV0IHByZXZpb3VzVGltZSA9ICt0aGlzLnRpbWUgLSAodGhpcy5taW51dGVzR2FwIHx8IDEpO1xuXG4gICAgICAgICAgICBpZiAocHJldmlvdXNUaW1lIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1RpbWUgPSB0aGlzLm1pbnV0ZXNHYXAgPyB0aGlzLm1heCAtICh0aGlzLm1pbnV0ZXNHYXAgLSAxKSA6IHRoaXMubWF4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5pc1NlbGVjdGVkVGltZURpc2FibGVkKHByZXZpb3VzVGltZSkpIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1RpbWUgPSB0aGlzLmdldEF2YWlsYWJsZVRpbWUocHJldmlvdXNUaW1lLCB0aGlzLmdldFByZXZBdmFpbGFibGVUaW1lLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocHJldmlvdXNUaW1lICE9PSB0aGlzLnRpbWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVDaGFuZ2VkLmVtaXQocHJldmlvdXNUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uRm9jdXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNGb2N1c2VkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wcmV2aW91c1RpbWUgPSB0aGlzLnRpbWU7XG4gICAgfVxuXG4gICAgb25CbHVyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmlzRm9jdXNlZCA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh0aGlzLnByZXZpb3VzVGltZSAhPT0gdGhpcy50aW1lKSB7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZVRpbWVJZlZhbGlkKCt0aGlzLnRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb2RlbENoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGltZSA9ICt0aGlzLnRpbWVQYXJzZXIudHJhbnNmb3JtKHZhbHVlLCB0aGlzLnRpbWVVbml0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoYW5nZVRpbWVJZlZhbGlkKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMudGltZSA9IHZhbHVlO1xuXG4gICAgICAgICAgICBpZiAodGhpcy50aW1lID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aW1lU3RyaW5nID0gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWUgPSArdGltZVN0cmluZ1t0aW1lU3RyaW5nLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy50aW1lIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWUgPSB0aGlzLm1pbjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy50aW1lQ2hhbmdlZC5lbWl0KHRoaXMudGltZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzU2VsZWN0ZWRUaW1lRGlzYWJsZWQodGltZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRpbWVMaXN0LmZpbmQoKGZhY2VUaW1lOiBDbG9ja0ZhY2VUaW1lKSA9PiBmYWNlVGltZS50aW1lID09PSB0aW1lKS5kaXNhYmxlZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE5leHRBdmFpbGFibGVUaW1lKGluZGV4OiBudW1iZXIpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICBjb25zdCB0aW1lQ29sbGVjdGlvbiA9IHRoaXMudGltZUxpc3Q7XG4gICAgICAgIGNvbnN0IG1heFZhbHVlID0gdGltZUNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgICBmb3IgKGxldCBpID0gaW5kZXggKyAxOyBpIDwgbWF4VmFsdWU7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgdGltZSA9IHRpbWVDb2xsZWN0aW9uW2ldO1xuICAgICAgICAgICAgaWYgKCF0aW1lLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRpbWUudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UHJldkF2YWlsYWJsZVRpbWUoaW5kZXg6IG51bWJlcik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSBpbmRleDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbWUgPSB0aGlzLnRpbWVMaXN0W2ldO1xuICAgICAgICAgICAgaWYgKCF0aW1lLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRpbWUudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0QXZhaWxhYmxlVGltZShjdXJyZW50VGltZTogbnVtYmVyLCBmbjogKGluZGV4OiBudW1iZXIpID0+IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lSW5kZXggPSB0aGlzLnRpbWVMaXN0LmZpbmRJbmRleCh0aW1lID0+IHRpbWUudGltZSA9PT0gY3VycmVudFRpbWUpO1xuICAgICAgICBjb25zdCBhdmFpbGFibGVUaW1lID0gZm4oY3VycmVudFRpbWVJbmRleCk7XG5cbiAgICAgICAgcmV0dXJuIGF2YWlsYWJsZVRpbWUgIT0gbnVsbCA/IGF2YWlsYWJsZVRpbWUgOiB0aGlzLnRpbWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRBdmFpbGFibGVUaW1lKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBhdmFpbGFibGVUaW1lID0gdGhpcy50aW1lTGlzdC5maW5kKHQgPT4gIXQuZGlzYWJsZWQpO1xuICAgICAgICBpZiAoYXZhaWxhYmxlVGltZSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWUgPSBhdmFpbGFibGVUaW1lLnRpbWU7XG4gICAgICAgICAgICB0aGlzLnRpbWVDaGFuZ2VkLmVtaXQodGhpcy50aW1lKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gY29uY2F0VGltZShjdXJyZW50VGltZTogc3RyaW5nLCBuZXh0VGltZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBpc051bWJlciA9IC9cXGQvLnRlc3QobmV4dFRpbWUpO1xuXG4gICAgaWYgKGlzTnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IHRpbWUgPSBjdXJyZW50VGltZSArIG5leHRUaW1lO1xuICAgICAgICByZXR1cm4gK3RpbWU7XG4gICAgfVxufVxuXG4iLCI8ZGl2IGNsYXNzPVwibmd4LXRpbWVwaWNrZXItY29udHJvbFwiIFtuZ0NsYXNzXT1cInsnbmd4LXRpbWVwaWNrZXItY29udHJvbC0tYWN0aXZlJzogaXNGb2N1c2VkfVwiPlxuICAgIDwhLS1zdXBwcmVzcyBIdG1sRm9ybUlucHV0V2l0aG91dExhYmVsIC0tPlxuICAgIDxpbnB1dCBjbGFzcz1cIm5neC10aW1lcGlja2VyLWNvbnRyb2xfX2lucHV0XCJcbiAgICAgICAgICAgbWF4bGVuZ3RoPVwiMlwiXG4gICAgICAgICAgIFtuZ01vZGVsXT1cInRpbWUgfCB0aW1lUGFyc2VyOiB0aW1lVW5pdCB8IHRpbWVMb2NhbGl6ZXI6IHRpbWVVbml0IDogdHJ1ZVwiXG4gICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgIChrZXlkb3duKT1cIm9uS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgKGtleXByZXNzKT1cImNoYW5nZVRpbWUoJGV2ZW50KVwiXG4gICAgICAgICAgIChmb2N1cyk9XCJvbkZvY3VzKClcIlxuICAgICAgICAgICAoYmx1cik9XCJvbkJsdXIoKVwiPlxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtdGltZXBpY2tlci1jb250cm9sX19hcnJvd3NcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LXRpbWVwaWNrZXItY29udHJvbF9fYXJyb3dcIiByb2xlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImluY3JlYXNlKClcIj5cbiAgICAgICAgICAgICAgICAmIzk2NTA7XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LXRpbWVwaWNrZXItY29udHJvbF9fYXJyb3dcIiByb2xlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImRlY3JlYXNlKClcIj5cbiAgICAgICAgICAgICAgICAmIzk2NjA7XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==