@danielmoncada/angular-datetime-picker
Version:
Angular Date Time Picker
292 lines • 40.7 kB
JavaScript
/**
* timer.component
*/
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Optional, Output } from '@angular/core';
import { take } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "./date-time-picker-intl.service";
import * as i2 from "./adapter/date-time-adapter.class";
import * as i3 from "@angular/common";
import * as i4 from "./timer-box.component";
export class OwlTimerComponent {
get pickerMoment() {
return this._pickerMoment;
}
set pickerMoment(value) {
value = this.dateTimeAdapter.deserialize(value);
this._pickerMoment =
this.getValidDate(value) || this.dateTimeAdapter.now();
}
get minDateTime() {
return this._minDateTime;
}
set minDateTime(value) {
value = this.dateTimeAdapter.deserialize(value);
this._minDateTime = this.getValidDate(value);
}
get maxDateTime() {
return this._maxDateTime;
}
set maxDateTime(value) {
value = this.dateTimeAdapter.deserialize(value);
this._maxDateTime = this.getValidDate(value);
}
get hourValue() {
return this.dateTimeAdapter.getHours(this.pickerMoment);
}
/**
* The value would be displayed in hourBox.
* We need this because the value displayed in hourBox it not
* the same as the hourValue when the timer is in hour12Timer mode.
* */
get hourBoxValue() {
let hours = this.hourValue;
if (!this.hour12Timer) {
return hours;
}
else {
if (hours === 0) {
hours = 12;
this.isPM = false;
}
else if (hours > 0 && hours < 12) {
this.isPM = false;
}
else if (hours === 12) {
this.isPM = true;
}
else if (hours > 12 && hours < 24) {
hours = hours - 12;
this.isPM = true;
}
return hours;
}
}
get minuteValue() {
return this.dateTimeAdapter.getMinutes(this.pickerMoment);
}
get secondValue() {
return this.dateTimeAdapter.getSeconds(this.pickerMoment);
}
get upHourButtonLabel() {
return this.pickerIntl.upHourLabel;
}
get downHourButtonLabel() {
return this.pickerIntl.downHourLabel;
}
get upMinuteButtonLabel() {
return this.pickerIntl.upMinuteLabel;
}
get downMinuteButtonLabel() {
return this.pickerIntl.downMinuteLabel;
}
get upSecondButtonLabel() {
return this.pickerIntl.upSecondLabel;
}
get downSecondButtonLabel() {
return this.pickerIntl.downSecondLabel;
}
get hour12ButtonLabel() {
return this.isPM
? this.pickerIntl.hour12PMLabel
: this.pickerIntl.hour12AMLabel;
}
get owlDTTimerClass() {
return true;
}
get owlDTTimeTabIndex() {
return -1;
}
constructor(ngZone, elmRef, pickerIntl, cdRef, dateTimeAdapter) {
this.ngZone = ngZone;
this.elmRef = elmRef;
this.pickerIntl = pickerIntl;
this.cdRef = cdRef;
this.dateTimeAdapter = dateTimeAdapter;
this.isPM = false; // a flag indicates the current timer moment is in PM or AM
/**
* Hours to change per step
*/
this.stepHour = 1;
/**
* Minutes to change per step
*/
this.stepMinute = 1;
/**
* Seconds to change per step
*/
this.stepSecond = 1;
this.selectedChange = new EventEmitter();
}
ngOnInit() { }
/**
* Focus to the host element
* */
focus() {
this.ngZone.runOutsideAngular(() => {
this.ngZone.onStable
.asObservable()
.pipe(take(1))
.subscribe(() => {
this.elmRef.nativeElement.focus();
});
});
}
/**
* Set the hour value via typing into timer box input
* We need this to handle the hour value when the timer is in hour12 mode
* */
setHourValueViaInput(hours) {
if (this.hour12Timer && this.isPM && hours >= 1 && hours <= 11) {
hours = hours + 12;
}
else if (this.hour12Timer && !this.isPM && hours === 12) {
hours = 0;
}
this.setHourValue(hours);
}
setHourValue(hours) {
const m = this.dateTimeAdapter.setHours(this.pickerMoment, hours);
this.selectedChange.emit(m);
this.cdRef.markForCheck();
}
setMinuteValue(minutes) {
const m = this.dateTimeAdapter.setMinutes(this.pickerMoment, minutes);
this.selectedChange.emit(m);
this.cdRef.markForCheck();
}
setSecondValue(seconds) {
const m = this.dateTimeAdapter.setSeconds(this.pickerMoment, seconds);
this.selectedChange.emit(m);
this.cdRef.markForCheck();
}
setMeridiem(event) {
this.isPM = !this.isPM;
let hours = this.hourValue;
if (this.isPM) {
hours = hours + 12;
}
else {
hours = hours - 12;
}
if (hours >= 0 && hours <= 23) {
this.setHourValue(hours);
}
this.cdRef.markForCheck();
event.preventDefault();
}
/**
* Check if the up hour button is enabled
*/
upHourEnabled() {
return (!this.maxDateTime ||
this.compareHours(this.stepHour, this.maxDateTime) < 1);
}
/**
* Check if the down hour button is enabled
*/
downHourEnabled() {
return (!this.minDateTime ||
this.compareHours(-this.stepHour, this.minDateTime) > -1);
}
/**
* Check if the up minute button is enabled
*/
upMinuteEnabled() {
return (!this.maxDateTime ||
this.compareMinutes(this.stepMinute, this.maxDateTime) < 1);
}
/**
* Check if the down minute button is enabled
*/
downMinuteEnabled() {
return (!this.minDateTime ||
this.compareMinutes(-this.stepMinute, this.minDateTime) > -1);
}
/**
* Check if the up second button is enabled
*/
upSecondEnabled() {
return (!this.maxDateTime ||
this.compareSeconds(this.stepSecond, this.maxDateTime) < 1);
}
/**
* Check if the down second button is enabled
*/
downSecondEnabled() {
return (!this.minDateTime ||
this.compareSeconds(-this.stepSecond, this.minDateTime) > -1);
}
/**
* PickerMoment's hour value +/- certain amount and compare it to the give date
* 1 is after the comparedDate
* -1 is before the comparedDate
* 0 is equal the comparedDate
* */
compareHours(amount, comparedDate) {
const hours = this.dateTimeAdapter.getHours(this.pickerMoment) + amount;
const result = this.dateTimeAdapter.setHours(this.pickerMoment, hours);
return this.dateTimeAdapter.compare(result, comparedDate);
}
/**
* PickerMoment's minute value +/- certain amount and compare it to the give date
* 1 is after the comparedDate
* -1 is before the comparedDate
* 0 is equal the comparedDate
* */
compareMinutes(amount, comparedDate) {
const minutes = this.dateTimeAdapter.getMinutes(this.pickerMoment) + amount;
const result = this.dateTimeAdapter.setMinutes(this.pickerMoment, minutes);
return this.dateTimeAdapter.compare(result, comparedDate);
}
/**
* PickerMoment's second value +/- certain amount and compare it to the give date
* 1 is after the comparedDate
* -1 is before the comparedDate
* 0 is equal the comparedDate
* */
compareSeconds(amount, comparedDate) {
const seconds = this.dateTimeAdapter.getSeconds(this.pickerMoment) + amount;
const result = this.dateTimeAdapter.setSeconds(this.pickerMoment, seconds);
return this.dateTimeAdapter.compare(result, comparedDate);
}
/**
* Get a valid date object
*/
getValidDate(obj) {
return this.dateTimeAdapter.isDateInstance(obj) &&
this.dateTimeAdapter.isValid(obj)
? obj
: null;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: OwlTimerComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i1.OwlDateTimeIntl }, { token: i0.ChangeDetectorRef }, { token: i2.DateTimeAdapter, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.5", type: OwlTimerComponent, selector: "owl-date-time-timer", inputs: { pickerMoment: "pickerMoment", minDateTime: "minDateTime", maxDateTime: "maxDateTime", showSecondsTimer: "showSecondsTimer", hour12Timer: "hour12Timer", stepHour: "stepHour", stepMinute: "stepMinute", stepSecond: "stepSecond" }, outputs: { selectedChange: "selectedChange" }, host: { properties: { "class.owl-dt-timer": "owlDTTimerClass", "attr.tabindex": "owlDTTimeTabIndex" } }, exportAs: ["owlDateTimeTimer"], ngImport: i0, template: "<owl-date-time-timer-box\n [upBtnAriaLabel]=\"upHourButtonLabel\"\n [downBtnAriaLabel]=\"downHourButtonLabel\"\n [upBtnDisabled]=\"!upHourEnabled()\"\n [downBtnDisabled]=\"!downHourEnabled()\"\n [boxValue]=\"hourBoxValue\"\n [value]=\"hourValue\" [min]=\"0\" [max]=\"23\"\n [step]=\"stepHour\" [inputLabel]=\"'Hour'\"\n (inputChange)=\"setHourValueViaInput($event)\"\n (valueChange)=\"setHourValue($event)\"></owl-date-time-timer-box>\n<owl-date-time-timer-box\n [showDivider]=\"true\"\n [upBtnAriaLabel]=\"upMinuteButtonLabel\"\n [downBtnAriaLabel]=\"downMinuteButtonLabel\"\n [upBtnDisabled]=\"!upMinuteEnabled()\"\n [downBtnDisabled]=\"!downMinuteEnabled()\"\n [value]=\"minuteValue\" [min]=\"0\" [max]=\"59\"\n [step]=\"stepMinute\" [inputLabel]=\"'Minute'\"\n (inputChange)=\"setMinuteValue($event)\"\n (valueChange)=\"setMinuteValue($event)\"></owl-date-time-timer-box>\n<owl-date-time-timer-box\n *ngIf=\"showSecondsTimer\"\n [showDivider]=\"true\"\n [upBtnAriaLabel]=\"upSecondButtonLabel\"\n [downBtnAriaLabel]=\"downSecondButtonLabel\"\n [upBtnDisabled]=\"!upSecondEnabled()\"\n [downBtnDisabled]=\"!downSecondEnabled()\"\n [value]=\"secondValue\" [min]=\"0\" [max]=\"59\"\n [step]=\"stepSecond\" [inputLabel]=\"'Second'\"\n (inputChange)=\"setSecondValue($event)\"\n (valueChange)=\"setSecondValue($event)\"></owl-date-time-timer-box>\n\n<div *ngIf=\"hour12Timer\" class=\"owl-dt-timer-hour12\">\n <button class=\"owl-dt-control-button owl-dt-timer-hour12-box\"\n type=\"button\" tabindex=\"0\"\n (click)=\"setMeridiem($event)\">\n <span class=\"owl-dt-control-button-content\" tabindex=\"-1\">\n {{hour12ButtonLabel}}\n </span>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.OwlTimerBoxComponent, selector: "owl-date-time-timer-box", inputs: ["showDivider", "upBtnAriaLabel", "upBtnDisabled", "downBtnAriaLabel", "downBtnDisabled", "boxValue", "value", "min", "max", "step", "inputLabel"], outputs: ["valueChange", "inputChange"], exportAs: ["owlDateTimeTimerBox"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: OwlTimerComponent, decorators: [{
type: Component,
args: [{ exportAs: 'owlDateTimeTimer', selector: 'owl-date-time-timer', preserveWhitespaces: false, standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, host: {
'[class.owl-dt-timer]': 'owlDTTimerClass',
'[attr.tabindex]': 'owlDTTimeTabIndex'
}, template: "<owl-date-time-timer-box\n [upBtnAriaLabel]=\"upHourButtonLabel\"\n [downBtnAriaLabel]=\"downHourButtonLabel\"\n [upBtnDisabled]=\"!upHourEnabled()\"\n [downBtnDisabled]=\"!downHourEnabled()\"\n [boxValue]=\"hourBoxValue\"\n [value]=\"hourValue\" [min]=\"0\" [max]=\"23\"\n [step]=\"stepHour\" [inputLabel]=\"'Hour'\"\n (inputChange)=\"setHourValueViaInput($event)\"\n (valueChange)=\"setHourValue($event)\"></owl-date-time-timer-box>\n<owl-date-time-timer-box\n [showDivider]=\"true\"\n [upBtnAriaLabel]=\"upMinuteButtonLabel\"\n [downBtnAriaLabel]=\"downMinuteButtonLabel\"\n [upBtnDisabled]=\"!upMinuteEnabled()\"\n [downBtnDisabled]=\"!downMinuteEnabled()\"\n [value]=\"minuteValue\" [min]=\"0\" [max]=\"59\"\n [step]=\"stepMinute\" [inputLabel]=\"'Minute'\"\n (inputChange)=\"setMinuteValue($event)\"\n (valueChange)=\"setMinuteValue($event)\"></owl-date-time-timer-box>\n<owl-date-time-timer-box\n *ngIf=\"showSecondsTimer\"\n [showDivider]=\"true\"\n [upBtnAriaLabel]=\"upSecondButtonLabel\"\n [downBtnAriaLabel]=\"downSecondButtonLabel\"\n [upBtnDisabled]=\"!upSecondEnabled()\"\n [downBtnDisabled]=\"!downSecondEnabled()\"\n [value]=\"secondValue\" [min]=\"0\" [max]=\"59\"\n [step]=\"stepSecond\" [inputLabel]=\"'Second'\"\n (inputChange)=\"setSecondValue($event)\"\n (valueChange)=\"setSecondValue($event)\"></owl-date-time-timer-box>\n\n<div *ngIf=\"hour12Timer\" class=\"owl-dt-timer-hour12\">\n <button class=\"owl-dt-control-button owl-dt-timer-hour12-box\"\n type=\"button\" tabindex=\"0\"\n (click)=\"setMeridiem($event)\">\n <span class=\"owl-dt-control-button-content\" tabindex=\"-1\">\n {{hour12ButtonLabel}}\n </span>\n </button>\n</div>\n" }]
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i1.OwlDateTimeIntl }, { type: i0.ChangeDetectorRef }, { type: i2.DateTimeAdapter, decorators: [{
type: Optional
}] }], propDecorators: { pickerMoment: [{
type: Input
}], minDateTime: [{
type: Input
}], maxDateTime: [{
type: Input
}], showSecondsTimer: [{
type: Input
}], hour12Timer: [{
type: Input
}], stepHour: [{
type: Input
}], stepMinute: [{
type: Input
}], stepSecond: [{
type: Input
}], selectedChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcGlja2VyL3NyYy9saWIvZGF0ZS10aW1lL3RpbWVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3BpY2tlci9zcmMvbGliL2RhdGUtdGltZS90aW1lci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFDSCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQWV0QyxNQUFNLE9BQU8saUJBQWlCO0lBRzFCLElBQ0ksWUFBWTtRQUNaLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM5QixDQUFDO0lBRUQsSUFBSSxZQUFZLENBQUMsS0FBUTtRQUNyQixLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLGFBQWE7WUFDZCxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDL0QsQ0FBQztJQUlELElBQ0ksV0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBSSxXQUFXLENBQUMsS0FBZTtRQUMzQixLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFJRCxJQUNJLFdBQVc7UUFDWCxPQUFPLElB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Q29udGVudCI6WyIvKipcbiAqIHRpbWVyLmNvbXBvbmVudFxuICovXG5cbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIElucHV0LFxuICAgIE5nWm9uZSxcbiAgICBPbkluaXQsXG4gICAgT3B0aW9uYWwsXG4gICAgT3V0cHV0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT3dsRGF0ZVRpbWVJbnRsIH0gZnJvbSAnLi9kYXRlLXRpbWUtcGlja2VyLWludGwuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlVGltZUFkYXB0ZXIgfSBmcm9tICcuL2FkYXB0ZXIvZGF0ZS10aW1lLWFkYXB0ZXIuY2xhc3MnO1xuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuQENvbXBvbmVudCh7XG4gICAgZXhwb3J0QXM6ICdvd2xEYXRlVGltZVRpbWVyJyxcbiAgICBzZWxlY3RvcjogJ293bC1kYXRlLXRpbWUtdGltZXInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi90aW1lci5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdGltZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgICBzdGFuZGFsb25lOiBmYWxzZSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBob3N0OiB7XG4gICAgICAgICdbY2xhc3Mub3dsLWR0LXRpbWVyXSc6ICdvd2xEVFRpbWVyQ2xhc3MnLFxuICAgICAgICAnW2F0dHIudGFiaW5kZXhdJzogJ293bERUVGltZVRhYkluZGV4J1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgT3dsVGltZXJDb21wb25lbnQ8VD4gaW1wbGVtZW50cyBPbkluaXQge1xuICAgIC8qKiBUaGUgY3VycmVudCBwaWNrZXIgbW9tZW50ICovXG4gICAgcHJpdmF0ZSBfcGlja2VyTW9tZW50OiBUO1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IHBpY2tlck1vbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BpY2tlck1vbWVudDtcbiAgICB9XG5cbiAgICBzZXQgcGlja2VyTW9tZW50KHZhbHVlOiBUKSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZGVzZXJpYWxpemUodmFsdWUpO1xuICAgICAgICB0aGlzLl9waWNrZXJNb21lbnQgPVxuICAgICAgICAgICAgdGhpcy5nZXRWYWxpZERhdGUodmFsdWUpIHx8IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLm5vdygpO1xuICAgIH1cblxuICAgIC8qKiBUaGUgbWluaW11bSBzZWxlY3RhYmxlIGRhdGUgdGltZS4gKi9cbiAgICBwcml2YXRlIF9taW5EYXRlVGltZTogVCB8IG51bGw7XG4gICAgQElucHV0KClcbiAgICBnZXQgbWluRGF0ZVRpbWUoKTogVCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWluRGF0ZVRpbWU7XG4gICAgfVxuXG4gICAgc2V0IG1pbkRhdGVUaW1lKHZhbHVlOiBUIHwgbnVsbCkge1xuICAgICAgICB2YWx1ZSA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmRlc2VyaWFsaXplKHZhbHVlKTtcbiAgICAgICAgdGhpcy5fbWluRGF0ZVRpbWUgPSB0aGlzLmdldFZhbGlkRGF0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqIFRoZSBtYXhpbXVtIHNlbGVjdGFibGUgZGF0ZSB0aW1lLiAqL1xuICAgIHByaXZhdGUgX21heERhdGVUaW1lOiBUIHwgbnVsbDtcbiAgICBASW5wdXQoKVxuICAgIGdldCBtYXhEYXRlVGltZSgpOiBUIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXhEYXRlVGltZTtcbiAgICB9XG5cbiAgICBzZXQgbWF4RGF0ZVRpbWUodmFsdWU6IFQgfCBudWxsKSB7XG4gICAgICAgIHZhbHVlID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZGVzZXJpYWxpemUodmFsdWUpO1xuICAgICAgICB0aGlzLl9tYXhEYXRlVGltZSA9IHRoaXMuZ2V0VmFsaWREYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUE0gPSBmYWxzZTsgLy8gYSBmbGFnIGluZGljYXRlcyB0aGUgY3VycmVudCB0aW1lciBtb21lbnQgaXMgaW4gUE0gb3IgQU1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gc2hvdyB0aGUgc2Vjb25kJ3MgdGltZXJcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHNob3dTZWNvbmRzVGltZXI6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSB0aW1lciBpcyBpbiBob3VyMTIgZm9ybWF0XG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBob3VyMTJUaW1lcjogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEhvdXJzIHRvIGNoYW5nZSBwZXIgc3RlcFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgc3RlcEhvdXIgPSAxO1xuXG4gICAgLyoqXG4gICAgICogTWludXRlcyB0byBjaGFuZ2UgcGVyIHN0ZXBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHN0ZXBNaW51dGUgPSAxO1xuXG4gICAgLyoqXG4gICAgICogU2Vjb25kcyB0byBjaGFuZ2UgcGVyIHN0ZXBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHN0ZXBTZWNvbmQgPSAxO1xuXG4gICAgZ2V0IGhvdXJWYWx1ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0SG91cnModGhpcy5waWNrZXJNb21lbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSB3b3VsZCBiZSBkaXNwbGF5ZWQgaW4gaG91ckJveC5cbiAgICAgKiBXZSBuZWVkIHRoaXMgYmVjYXVzZSB0aGUgdmFsdWUgZGlzcGxheWVkIGluIGhvdXJCb3ggaXQgbm90XG4gICAgICogdGhlIHNhbWUgYXMgdGhlIGhvdXJWYWx1ZSB3aGVuIHRoZSB0aW1lciBpcyBpbiBob3VyMTJUaW1lciBtb2RlLlxuICAgICAqICovXG4gICAgZ2V0IGhvdXJCb3hWYWx1ZSgpOiBudW1iZXIge1xuICAgICAgICBsZXQgaG91cnMgPSB0aGlzLmhvdXJWYWx1ZTtcblxuICAgICAgICBpZiAoIXRoaXMuaG91cjEyVGltZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBob3VycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChob3VycyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGhvdXJzID0gMTI7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1BNID0gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGhvdXJzID4gMCAmJiBob3VycyA8IDEyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1BNID0gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGhvdXJzID09PSAxMikge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNQTSA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGhvdXJzID4gMTIgJiYgaG91cnMgPCAyNCkge1xuICAgICAgICAgICAgICAgIGhvdXJzID0gaG91cnMgLSAxMjtcbiAgICAgICAgICAgICAgICB0aGlzLmlzUE0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaG91cnM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgbWludXRlVmFsdWUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldE1pbnV0ZXModGhpcy5waWNrZXJNb21lbnQpO1xuICAgIH1cblxuICAgIGdldCBzZWNvbmRWYWx1ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0U2Vjb25kcyh0aGlzLnBpY2tlck1vbWVudCk7XG4gICAgfVxuXG4gICAgZ2V0IHVwSG91ckJ1dHRvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpY2tlckludGwudXBIb3VyTGFiZWw7XG4gICAgfVxuXG4gICAgZ2V0IGRvd25Ib3VyQnV0dG9uTGFiZWwoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGlja2VySW50bC5kb3duSG91ckxhYmVsO1xuICAgIH1cblxuICAgIGdldCB1cE1pbnV0ZUJ1dHRvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpY2tlckludGwudXBNaW51dGVMYWJlbDtcbiAgICB9XG5cbiAgICBnZXQgZG93bk1pbnV0ZUJ1dHRvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpY2tlckludGwuZG93bk1pbnV0ZUxhYmVsO1xuICAgIH1cblxuICAgIGdldCB1cFNlY29uZEJ1dHRvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpY2tlckludGwudXBTZWNvbmRMYWJlbDtcbiAgICB9XG5cbiAgICBnZXQgZG93blNlY29uZEJ1dHRvbkxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpY2tlckludGwuZG93blNlY29uZExhYmVsO1xuICAgIH1cblxuICAgIGdldCBob3VyMTJCdXR0b25MYWJlbCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1BNXG4gICAgICAgICAgICA/IHRoaXMucGlja2VySW50bC5ob3VyMTJQTUxhYmVsXG4gICAgICAgICAgICA6IHRoaXMucGlja2VySW50bC5ob3VyMTJBTUxhYmVsO1xuICAgIH1cblxuICAgIEBPdXRwdXQoKVxuICAgIHNlbGVjdGVkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxUPigpO1xuXG4gICAgZ2V0IG93bERUVGltZXJDbGFzcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZ2V0IG93bERUVGltZVRhYkluZGV4KCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICAgICAgcHJpdmF0ZSBlbG1SZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByaXZhdGUgcGlja2VySW50bDogT3dsRGF0ZVRpbWVJbnRsLFxuICAgICAgICBwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkYXRlVGltZUFkYXB0ZXI6IERhdGVUaW1lQWRhcHRlcjxUPlxuICAgICkge31cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHt9XG5cbiAgICAvKipcbiAgICAgKiBGb2N1cyB0byB0aGUgaG9zdCBlbGVtZW50XG4gICAgICogKi9cbiAgICBwdWJsaWMgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMubmdab25lLm9uU3RhYmxlXG4gICAgICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbG1SZWYubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGhvdXIgdmFsdWUgdmlhIHR5cGluZyBpbnRvIHRpbWVyIGJveCBpbnB1dFxuICAgICAqIFdlIG5lZWQgdGhpcyB0byBoYW5kbGUgdGhlIGhvdXIgdmFsdWUgd2hlbiB0aGUgdGltZXIgaXMgaW4gaG91cjEyIG1vZGVcbiAgICAgKiAqL1xuICAgIHB1YmxpYyBzZXRIb3VyVmFsdWVWaWFJbnB1dChob3VyczogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmhvdXIxMlRpbWVyICYmIHRoaXMuaXNQTSAmJiBob3VycyA+PSAxICYmIGhvdXJzIDw9IDExKSB7XG4gICAgICAgICAgICBob3VycyA9IGhvdXJzICsgMTI7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5ob3VyMTJUaW1lciAmJiAhdGhpcy5pc1BNICYmIGhvdXJzID09PSAxMikge1xuICAgICAgICAgICAgaG91cnMgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRIb3VyVmFsdWUoaG91cnMpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRIb3VyVmFsdWUoaG91cnM6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBtID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuc2V0SG91cnModGhpcy5waWNrZXJNb21lbnQsIGhvdXJzKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZENoYW5nZS5lbWl0KG0pO1xuICAgICAgICB0aGlzLmNkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRNaW51dGVWYWx1ZShtaW51dGVzOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbSA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLnNldE1pbnV0ZXModGhpcy5waWNrZXJNb21lbnQsIG1pbnV0ZXMpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ2hhbmdlLmVtaXQobSk7XG4gICAgICAgIHRoaXMuY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFNlY29uZFZhbHVlKHNlY29uZHM6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBtID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuc2V0U2Vjb25kcyh0aGlzLnBpY2tlck1vbWVudCwgc2Vjb25kcyk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDaGFuZ2UuZW1pdChtKTtcbiAgICAgICAgdGhpcy5jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0TWVyaWRpZW0oZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLmlzUE0gPSAhdGhpcy5pc1BNO1xuXG4gICAgICAgIGxldCBob3VycyA9IHRoaXMuaG91clZhbHVlO1xuICAgICAgICBpZiAodGhpcy5pc1BNKSB7XG4gICAgICAgICAgICBob3VycyA9IGhvdXJzICsgMTI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBob3VycyA9IGhvdXJzIC0gMTI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaG91cnMgPj0gMCAmJiBob3VycyA8PSAyMykge1xuICAgICAgICAgICAgdGhpcy5zZXRIb3VyVmFsdWUoaG91cnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiB0aGUgdXAgaG91ciBidXR0b24gaXMgZW5hYmxlZFxuICAgICAqL1xuICAgIHB1YmxpYyB1cEhvdXJFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgIXRoaXMubWF4RGF0ZVRpbWUgfHxcbiAgICAgICAgICAgIHRoaXMuY29tcGFyZUhvdXJzKHRoaXMuc3RlcEhvdXIsIHRoaXMubWF4RGF0ZVRpbWUpIDwgMVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHRoZSBkb3duIGhvdXIgYnV0dG9uIGlzIGVuYWJsZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgZG93bkhvdXJFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgIXRoaXMubWluRGF0ZVRpbWUgfHxcbiAgICAgICAgICAgIHRoaXMuY29tcGFyZUhvdXJzKC10aGlzLnN0ZXBIb3VyLCB0aGlzLm1pbkRhdGVUaW1lKSA+IC0xXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgdGhlIHVwIG1pbnV0ZSBidXR0b24gaXMgZW5hYmxlZFxuICAgICAqL1xuICAgIHB1YmxpYyB1cE1pbnV0ZUVuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAhdGhpcy5tYXhEYXRlVGltZSB8fFxuICAgICAgICAgICAgdGhpcy5jb21wYXJlTWludXRlcyh0aGlzLnN0ZXBNaW51dGUsIHRoaXMubWF4RGF0ZVRpbWUpIDwgMVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHRoZSBkb3duIG1pbnV0ZSBidXR0b24gaXMgZW5hYmxlZFxuICAgICAqL1xuICAgIHB1YmxpYyBkb3duTWludXRlRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICF0aGlzLm1pbkRhdGVUaW1lIHx8XG4gICAgICAgICAgICB0aGlzLmNvbXBhcmVNaW51dGVzKC10aGlzLnN0ZXBNaW51dGUsIHRoaXMubWluRGF0ZVRpbWUpID4gLTFcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiB0aGUgdXAgc2Vjb25kIGJ1dHRvbiBpcyBlbmFibGVkXG4gICAgICovXG4gICAgcHVibGljIHVwU2Vjb25kRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICF0aGlzLm1heERhdGVUaW1lIHx8XG4gICAgICAgICAgICB0aGlzLmNvbXBhcmVTZWNvbmRzKHRoaXMuc3RlcFNlY29uZCwgdGhpcy5tYXhEYXRlVGltZSkgPCAxXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgdGhlIGRvd24gc2Vjb25kIGJ1dHRvbiBpcyBlbmFibGVkXG4gICAgICovXG4gICAgcHVibGljIGRvd25TZWNvbmRFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgIXRoaXMubWluRGF0ZVRpbWUgfHxcbiAgICAgICAgICAgIHRoaXMuY29tcGFyZVNlY29uZHMoLXRoaXMuc3RlcFNlY29uZCwgdGhpcy5taW5EYXRlVGltZSkgPiAtMVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tlck1vbWVudCdzIGhvdXIgdmFsdWUgKy8tIGNlcnRhaW4gYW1vdW50IGFuZCBjb21wYXJlIGl0IHRvIHRoZSBnaXZlIGRhdGVcbiAgICAgKiAxIGlzIGFmdGVyIHRoZSBjb21wYXJlZERhdGVcbiAgICAgKiAtMSBpcyBiZWZvcmUgdGhlIGNvbXBhcmVkRGF0ZVxuICAgICAqIDAgaXMgZXF1YWwgdGhlIGNvbXBhcmVkRGF0ZVxuICAgICAqICovXG4gICAgcHJpdmF0ZSBjb21wYXJlSG91cnMoYW1vdW50OiBudW1iZXIsIGNvbXBhcmVkRGF0ZTogVCk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGhvdXJzID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0SG91cnModGhpcy5waWNrZXJNb21lbnQpICsgYW1vdW50O1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5zZXRIb3Vycyh0aGlzLnBpY2tlck1vbWVudCwgaG91cnMpO1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlVGltZUFkYXB0ZXIuY29tcGFyZShyZXN1bHQsIGNvbXBhcmVkRGF0ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja2VyTW9tZW50J3MgbWludXRlIHZhbHVlICsvLSBjZXJ0YWluIGFtb3VudCBhbmQgY29tcGFyZSBpdCB0byB0aGUgZ2l2ZSBkYXRlXG4gICAgICogMSBpcyBhZnRlciB0aGUgY29tcGFyZWREYXRlXG4gICAgICogLTEgaXMgYmVmb3JlIHRoZSBjb21wYXJlZERhdGVcbiAgICAgKiAwIGlzIGVxdWFsIHRoZSBjb21wYXJlZERhdGVcbiAgICAgKiAqL1xuICAgIHByaXZhdGUgY29tcGFyZU1pbnV0ZXMoYW1vdW50OiBudW1iZXIsIGNvbXBhcmVkRGF0ZTogVCk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPVxuICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0TWludXRlcyh0aGlzLnBpY2tlck1vbWVudCkgKyBhbW91bnQ7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLnNldE1pbnV0ZXMoXG4gICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudCxcbiAgICAgICAgICAgIG1pbnV0ZXNcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmNvbXBhcmUocmVzdWx0LCBjb21wYXJlZERhdGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tlck1vbWVudCdzIHNlY29uZCB2YWx1ZSArLy0gY2VydGFpbiBhbW91bnQgYW5kIGNvbXBhcmUgaXQgdG8gdGhlIGdpdmUgZGF0ZVxuICAgICAqIDEgaXMgYWZ0ZXIgdGhlIGNvbXBhcmVkRGF0ZVxuICAgICAqIC0xIGlzIGJlZm9yZSB0aGUgY29tcGFyZWREYXRlXG4gICAgICogMCBpcyBlcXVhbCB0aGUgY29tcGFyZWREYXRlXG4gICAgICogKi9cbiAgICBwcml2YXRlIGNvbXBhcmVTZWNvbmRzKGFtb3VudDogbnVtYmVyLCBjb21wYXJlZERhdGU6IFQpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBzZWNvbmRzID1cbiAgICAgICAgICAgIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldFNlY29uZHModGhpcy5waWNrZXJNb21lbnQpICsgYW1vdW50O1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5zZXRTZWNvbmRzKFxuICAgICAgICAgICAgdGhpcy5waWNrZXJNb21lbnQsXG4gICAgICAgICAgICBzZWNvbmRzXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVUaW1lQWRhcHRlci5jb21wYXJlKHJlc3VsdCwgY29tcGFyZWREYXRlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYSB2YWxpZCBkYXRlIG9iamVjdFxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0VmFsaWREYXRlKG9iajogYW55KTogVCB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlVGltZUFkYXB0ZXIuaXNEYXRlSW5zdGFuY2Uob2JqKSAmJlxuICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuaXNWYWxpZChvYmopXG4gICAgICAgICAgICA/IG9ialxuICAgICAgICAgICAgOiBudWxsO1xuICAgIH1cbn1cbiIsIjxvd2wtZGF0ZS10aW1lLXRpbWVyLWJveFxuICAgICAgICBbdXBCdG5BcmlhTGFiZWxdPVwidXBIb3VyQnV0dG9uTGFiZWxcIlxuICAgICAgICBbZG93bkJ0bkFyaWFMYWJlbF09XCJkb3duSG91ckJ1dHRvbkxhYmVsXCJcbiAgICAgICAgW3VwQnRuRGlzYWJsZWRdPVwiIXVwSG91ckVuYWJsZWQoKVwiXG4gICAgICAgIFtkb3duQnRuRGlzYWJsZWRdPVwiIWRvd25Ib3VyRW5hYmxlZCgpXCJcbiAgICAgICAgW2JveFZhbHVlXT1cImhvdXJCb3hWYWx1ZVwiXG4gICAgICAgIFt2YWx1ZV09XCJob3VyVmFsdWVcIiBbbWluXT1cIjBcIiBbbWF4XT1cIjIzXCJcbiAgICAgICAgW3N0ZXBdPVwic3RlcEhvdXJcIiBbaW5wdXRMYWJlbF09XCInSG91cidcIlxuICAgICAgICAoaW5wdXRDaGFuZ2UpPVwic2V0SG91clZhbHVlVmlhSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICh2YWx1ZUNoYW5nZSk9XCJzZXRIb3VyVmFsdWUoJGV2ZW50KVwiPjwvb3dsLWRhdGUtdGltZS10aW1lci1ib3g+XG48b3dsLWRhdGUtdGltZS10aW1lci1ib3hcbiAgICAgICAgW3Nob3dEaXZpZGVyXT1cInRydWVcIlxuICAgICAgICBbdXBCdG5BcmlhTGFiZWxdPVwidXBNaW51dGVCdXR0b25MYWJlbFwiXG4gICAgICAgIFtkb3duQnRuQXJpYUxhYmVsXT1cImRvd25NaW51dGVCdXR0b25MYWJlbFwiXG4gICAgICAgIFt1cEJ0bkRpc2FibGVkXT1cIiF1cE1pbnV0ZUVuYWJsZWQoKVwiXG4gICAgICAgIFtkb3duQnRuRGlzYWJsZWRdPVwiIWRvd25NaW51dGVFbmFibGVkKClcIlxuICAgICAgICBbdmFsdWVdPVwibWludXRlVmFsdWVcIiBbbWluXT1cIjBcIiBbbWF4XT1cIjU5XCJcbiAgICAgICAgW3N0ZXBdPVwic3RlcE1pbnV0ZVwiIFtpbnB1dExhYmVsXT1cIidNaW51dGUnXCJcbiAgICAgICAgKGlucHV0Q2hhbmdlKT1cInNldE1pbnV0ZVZhbHVlKCRldmVudClcIlxuICAgICAgICAodmFsdWVDaGFuZ2UpPVwic2V0TWludXRlVmFsdWUoJGV2ZW50KVwiPjwvb3dsLWRhdGUtdGltZS10aW1lci1ib3g+XG48b3dsLWRhdGUtdGltZS10aW1lci1ib3hcbiAgICAgICAgKm5nSWY9XCJzaG93U2Vjb25kc1RpbWVyXCJcbiAgICAgICAgW3Nob3dEaXZpZGVyXT1cInRydWVcIlxuICAgICAgICBbdXBCdG5BcmlhTGFiZWxdPVwidXBTZWNvbmRCdXR0b25MYWJlbFwiXG4gICAgICAgIFtkb3duQnRuQXJpYUxhYmVsXT1cImRvd25TZWNvbmRCdXR0b25MYWJlbFwiXG4gICAgICAgIFt1cEJ0bkRpc2FibGVkXT1cIiF1cFNlY29uZEVuYWJsZWQoKVwiXG4gICAgICAgIFtkb3duQnRuRGlzYWJsZWRdPVwiIWRvd25TZWNvbmRFbmFibGVkKClcIlxuICAgICAgICBbdmFsdWVdPVwic2Vjb25kVmFsdWVcIiBbbWluXT1cIjBcIiBbbWF4XT1cIjU5XCJcbiAgICAgICAgW3N0ZXBdPVwic3RlcFNlY29uZFwiIFtpbnB1dExhYmVsXT1cIidTZWNvbmQnXCJcbiAgICAgICAgKGlucHV0Q2hhbmdlKT1cInNldFNlY29uZFZhbHVlKCRldmVudClcIlxuICAgICAgICAodmFsdWVDaGFuZ2UpPVwic2V0U2Vjb25kVmFsdWUoJGV2ZW50KVwiPjwvb3dsLWRhdGUtdGltZS10aW1lci1ib3g+XG5cbjxkaXYgKm5nSWY9XCJob3VyMTJUaW1lclwiIGNsYXNzPVwib3dsLWR0LXRpbWVyLWhvdXIxMlwiPlxuICAgIDxidXR0b24gY2xhc3M9XCJvd2wtZHQtY29udHJvbC1idXR0b24gb3dsLWR0LXRpbWVyLWhvdXIxMi1ib3hcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAoY2xpY2spPVwic2V0TWVyaWRpZW0oJGV2ZW50KVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm93bC1kdC1jb250cm9sLWJ1dHRvbi1jb250ZW50XCIgdGFiaW5kZXg9XCItMVwiPlxuICAgICAgICAgICAge3tob3VyMTJCdXR0b25MYWJlbH19XG4gICAgICAgIDwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbjwvZGl2PlxuIl19