ngnz-time-input
Version:
Material design time input for Angular 8
445 lines • 61.7 kB
JavaScript
import * as tslib_1 from "tslib";
import { FocusMonitor } from '@angular/cdk/a11y';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DoCheck, ElementRef, EventEmitter, HostBinding, HostListener, Input, OnDestroy, OnInit, Optional, Output, Self, } from '@angular/core';
import { ControlValueAccessor, FormControl, FormGroup, NgControl } from '@angular/forms';
import { MatFormFieldControl } from '@angular/material';
import * as moment from 'moment';
import { Subject } from 'rxjs/internal/Subject';
import { debounceTime, filter, takeUntil } from 'rxjs/operators';
import { CssClassCreator } from '../../classes/css-class-creator/css-class-creator';
import { TimeValue } from '../../classes/time-value/time-value';
import { TimeInputMode } from '../../datatypes/time-input-mode.enum';
/**
* Time Input Component.
* The component as a part of UI allows to change time part of Moment data type.
* It looks and uses like a input field.
* It is possible to use mouse wheel and/or control buttons to change time.
* Can be used with [value] attribute or FormControl inside angular reactive form
* @author Aleksey Nazarenko
* @version 0.0.1
*/
var NgnzTimeInputInlineComponent = /** @class */ (function () {
function NgnzTimeInputInlineComponent(_fm, _elRef, _chDetector, ngControl) {
var _this = this;
this._fm = _fm;
this._elRef = _elRef;
this._chDetector = _chDetector;
this.ngControl = ngControl;
this.BUTTON_HOST_ATTRIBUTES = [
'mat-button',
'mat-flat-button',
'mat-icon-button',
'mat-raised-button',
'mat-stroked-button',
'mat-mini-fab',
'mat-fab',
];
this.stateChanges = new Subject();
this._hoursControl = new FormControl(null);
this._minutesControl = new FormControl(null);
this._secondsControl = new FormControl(null);
this.parts = new FormGroup({
hours: this._hoursControl,
minutes: this._minutesControl,
seconds: this._secondsControl,
});
this._required = false;
this._disabled = false;
this._unsubscribe = new Subject();
this._debounceTime = 300;
this._focused = false;
this.controlType = 'ngnz-time-input-inline';
this.id = [
this.controlType,
++NgnzTimeInputInlineComponent_1.nextId,
].join('-');
this.describedBy = '';
this.inputClassesConf = {};
this.buttonDecreaseClassesConf = {};
this.buttonIncreaseClassesConf = {};
// enum defining of time change mode: Limit, Circular, CircularForwarding
this.inputMode = TimeInputMode.CircularForwarding;
// do not show control buttons; normally buttons are shown on focus
this.noButtons = false;
// always show control buttons; normally buttons are shown on focus
this.showButtons = false;
// do not show seconds block if it is not necessary
this.noSeconds = false;
// mat icon name for descrease controll button
this.decreaseBtnIconName = 'remove';
// mat icon name for increase control button
this.increaseBtnIconName = 'add';
this.timeChange = new EventEmitter();
this._timeChange = new EventEmitter();
this._onChange = function (_) { };
this._onTouched = function (_) { };
this._timeValue = new TimeValue();
if (this.ngControl !== null) {
this.ngControl.valueAccessor = this;
}
this._fm
.monitor(this._elRef.nativeElement, true)
.subscribe(function (origin) {
if (origin == null) {
_this._onTouched(_this);
}
_this.focused = !!origin;
_this.detectChangies();
});
this._hoursControl.valueChanges
.pipe(filter(function (data) { return +data !== _this._timeValue.hours; }), takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this._timeValue.setHours(+data);
});
this._timeValue.hoursChanged
.pipe(takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this._hoursControl.setValue(_this.padNumber(data));
_this._timeChange.emit(_this.value);
});
this._minutesControl.valueChanges
.pipe(filter(function (data) { return +data !== _this._timeValue.minutes; }), takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this._timeValue.setMinutes(+data);
});
this._timeValue.minutesChanged
.pipe(takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this._minutesControl.setValue(_this.padNumber(data));
_this._timeChange.emit(_this.value);
});
this._secondsControl.valueChanges
.pipe(filter(function (data) { return +data !== _this._timeValue.seconds; }), takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this._timeValue.setSeconds(+data);
});
this._timeValue.secondsChanged
.pipe(takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this._secondsControl.setValue(_this.padNumber(data));
_this._timeChange.emit(_this.value);
});
this._timeChange
.pipe(debounceTime(this._debounceTime), takeUntil(this._unsubscribe.asObservable()))
.subscribe(function (data) {
_this.timeChange.emit(data);
});
}
NgnzTimeInputInlineComponent_1 = NgnzTimeInputInlineComponent;
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "focused", {
get: function () {
return this._focused;
},
set: function (val) {
this._focused = val;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "shouldLabelFloat", {
get: function () {
return this.focused || !this.empty;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "placeholder", {
// placeholder // FIXME: is to show when value is not set
get: function () {
return this._placeholder;
},
set: function (placeholder) {
this._placeholder = placeholder;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "value", {
get: function () {
var out = moment({
years: this._inputValue.year(),
months: this._inputValue.month(),
days: this._inputValue.date(),
hours: this._timeValue.hours,
minutes: this._timeValue.minutes,
seconds: this._timeValue.seconds,
});
return out;
},
set: function (value) {
this._inputValue = (!!value && moment.isMoment(value) && value) || moment();
var hours = +this._inputValue.hours();
var minutes = +this._inputValue.minutes();
var seconds = +this._inputValue.seconds();
this._timeValue.setHours(hours).setMinutes(minutes).setSeconds(seconds);
this.detectChangies();
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "required", {
get: function () {
return this._required;
},
set: function (req) {
this._required = coerceBooleanProperty(req);
this.detectChangies();
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "disabled", {
get: function () {
return this._disabled;
},
set: function (value) {
this._disabled = coerceBooleanProperty(value);
this._disabled ? this.parts.disable() : this.parts.enable();
this.detectChangies();
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "splitter", {
// one character to separate hours from minutes and minutes from seconds; default is ':'
get: function () {
return this._splitter || ':';
},
set: function (value) {
this._splitter = ('' + value).slice(0);
},
enumerable: true,
configurable: true
});
NgnzTimeInputInlineComponent.prototype.ngOnInit = function () {
this._timeValue.inputMode = this.inputMode;
this._cssClassChange();
};
NgnzTimeInputInlineComponent.prototype.ngDoCheck = function () {
this._cssClassChange();
};
NgnzTimeInputInlineComponent.prototype.ngOnDestroy = function () {
this._unsubscribe.next();
this._unsubscribe.complete();
this._fm.stopMonitoring(this._elRef.nativeElement);
};
NgnzTimeInputInlineComponent.prototype.detectChangies = function () {
this.stateChanges.next();
this._cssClassChange();
this._chDetector.detectChanges();
};
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "errorState", {
get: function () {
return !!(!!this.ngControl &&
this.ngControl.touched &&
this.ngControl.invalid);
},
enumerable: true,
configurable: true
});
Object.defineProperty(NgnzTimeInputInlineComponent.prototype, "empty", {
get: function () {
var value = this.parts.value;
return (!(value.hours && value.hours >= 0) &&
!(value.minutes && value.minutes >= 0) &&
!(value.seconds && value.minutes >= 0));
},
enumerable: true,
configurable: true
});
NgnzTimeInputInlineComponent.prototype.setDescribedByIds = function (ids) {
this.describedBy = ids.join(' ');
};
NgnzTimeInputInlineComponent.prototype.onContainerClick = function (event) {
};
NgnzTimeInputInlineComponent.prototype.writeValue = function (value) {
this.value = value;
};
NgnzTimeInputInlineComponent.prototype.registerOnChange = function (fn) {
this._onChange = function (_) {
fn(_);
};
};
NgnzTimeInputInlineComponent.prototype.registerOnTouched = function (fn) {
this._onTouched = function (_) {
fn(_);
};
};
NgnzTimeInputInlineComponent.prototype.setDisabledState = function (isDisabled) {
this.disabled = isDisabled;
};
NgnzTimeInputInlineComponent.prototype.btnsAction = function (partName, step) {
switch (partName) {
case 'hours':
this._timeValue.setHours(this._timeValue.hours + step);
break;
case 'minutes':
this._timeValue.setMinutes(this._timeValue.minutes + step);
break;
case 'seconds':
this._timeValue.setSeconds(this._timeValue.seconds + step);
break;
}
this.detectChangies();
};
NgnzTimeInputInlineComponent.prototype.btnIncrease = function ($event, partName) {
$event.preventDefault();
$event.stopPropagation();
this.btnsAction(partName, 1);
};
NgnzTimeInputInlineComponent.prototype.btnDecrease = function ($event, partName) {
$event.preventDefault();
$event.stopPropagation();
this.btnsAction(partName, -1);
};
NgnzTimeInputInlineComponent.prototype.padNumber = function (value, places) {
if (places === void 0) { places = 2; }
return String(value).padStart(places, '0');
};
NgnzTimeInputInlineComponent.prototype.wheel = function ($event, partName) {
if (this.focused) {
$event.preventDefault();
$event.stopPropagation();
var step = $event.deltaY > 0 ? -1 : $event.deltaY < 0 ? 1 : 0;
this.btnsAction(partName, step);
}
};
// rearrange additional and conditional classes
NgnzTimeInputInlineComponent.prototype._cssClassChange = function () {
this._defineCssButtons();
this._defineCssInputs();
};
// detect type of control buttons in material design
NgnzTimeInputInlineComponent.prototype._defineMatButtonType = function () {
var _this = this;
var out = this.buttonMatTypeClassName = (!!this.buttonMatType && ('' + this.buttonMatType))
|| this.BUTTON_HOST_ATTRIBUTES.filter(function (attribute) {
return _this._elRef.nativeElement.hasAttribute(attribute);
}).join(' ');
return out;
};
// detect color of control buttons in material design
NgnzTimeInputInlineComponent.prototype._defineMatButtonColor = function () {
return this.colorClassName = !!this.color ? 'mat-' + this.color : '';
};
// combine additional and conditional classes for control buttons
NgnzTimeInputInlineComponent.prototype._defineCssButtons = function () {
var cssClasses = new CssClassCreator()
.appendCssClasses(this.colorClassName || this._defineMatButtonColor())
.appendCssClasses(this.buttonMatTypeClassName || this._defineMatButtonType())
.appendCssClasses(this.buttonsClasses)
.generate();
var cssCreatorLeft = new CssClassCreator()
.appendCssClasses(this.buttonDecreaseClasses)
.appendCssClasses(cssClasses);
var cssCreatorRight = new CssClassCreator()
.appendCssClasses(this.buttonIncreaseClasses)
.appendCssClasses(cssClasses);
Object.assign(this.buttonDecreaseClassesConf, cssCreatorLeft.generate());
Object.assign(this.buttonIncreaseClassesConf, cssCreatorRight.generate());
};
// combine additional and conditional classes for inputs
NgnzTimeInputInlineComponent.prototype._defineCssInputs = function () {
var _this = this;
var cssCreator = new CssClassCreator()
.appendCssClasses({
'ngnz-lr-margin-1em': function () { return (!_this.showButtons && !_this.noButtons && !_this.focused); },
})
.appendCssClasses(this.inputClasses);
Object.assign(this.inputClassesConf, cssCreator.generate());
};
var NgnzTimeInputInlineComponent_1;
NgnzTimeInputInlineComponent.nextId = 0;
NgnzTimeInputInlineComponent.ctorParameters = function () { return [
{ type: FocusMonitor },
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: NgControl, decorators: [{ type: Optional }, { type: Self }] }
]; };
tslib_1.__decorate([
HostBinding()
], NgnzTimeInputInlineComponent.prototype, "id", void 0);
tslib_1.__decorate([
HostBinding('attr.aria-describedby')
], NgnzTimeInputInlineComponent.prototype, "describedBy", void 0);
tslib_1.__decorate([
HostBinding('class.floating')
], NgnzTimeInputInlineComponent.prototype, "shouldLabelFloat", null);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "color", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "buttonMatType", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "inputClasses", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "buttonsClasses", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "buttonDecreaseClasses", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "buttonIncreaseClasses", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "placeholder", null);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "inputMode", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "value", null);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "required", null);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "disabled", null);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "splitter", null);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "noButtons", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "showButtons", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "noSeconds", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "decreaseBtnIconName", void 0);
tslib_1.__decorate([
Input()
], NgnzTimeInputInlineComponent.prototype, "increaseBtnIconName", void 0);
tslib_1.__decorate([
Output()
], NgnzTimeInputInlineComponent.prototype, "timeChange", void 0);
tslib_1.__decorate([
HostListener('timeChange', ['$event']),
HostListener('change', ['$event'])
], NgnzTimeInputInlineComponent.prototype, "_onChange", void 0);
NgnzTimeInputInlineComponent = NgnzTimeInputInlineComponent_1 = tslib_1.__decorate([
Component({
selector: 'ngnz-time-input-inline',
template: "<div class=\"ngnz-time-group\" [formGroup]=\"parts\">\n \n <div class=\"ngnz-hours-block\">\n <button\n *ngIf=\"showButtons || (!noButtons && focused)\"\n class=\"ngnz-button\"\n [ngClass]=\"buttonDecreaseClassesConf\"\n (click)=\"btnDecrease($event, 'hours')\"\n >\n <mat-icon class=\"ngnz-square-1em\">{{\n decreaseBtnIconName\n }}</mat-icon>\n </button>\n <input\n #hours\n class=\"ngnz-hours ngnz-width-2em\"\n formControlName=\"hours\"\n readonly\n [matTooltip]=\"focused ? '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043B\u0435\u0441\u043E \u043F\u0440\u043E\u043A\u0440\u0443\u0442\u043A\u0438' : ''\"\n [ngClass]=\"inputClassesConf\"\n (wheel)=\"wheel($event, 'hours')\"\n />\n <button\n *ngIf=\"showButtons || (!noButtons && focused)\"\n class=\"ngnz-button\"\n [ngClass]=\"buttonIncreaseClassesConf\"\n (click)=\"btnIncrease($event, 'hours')\"\n >\n <mat-icon class=\"ngnz-square-1em\">{{\n increaseBtnIconName\n }}</mat-icon>\n </button>\n </div>\n\n <div class=\"ngnz-splitter\">{{ splitter }}</div>\n\n <div class=\"ngnz-minutes-block\">\n <button\n *ngIf=\"showButtons || (!noButtons && focused)\"\n class=\"ngnz-button\"\n [ngClass]=\"buttonDecreaseClassesConf\"\n (click)=\"btnDecrease($event, 'minutes')\"\n >\n <mat-icon class=\"ngnz-square-1em\">{{\n decreaseBtnIconName\n }}</mat-icon>\n </button>\n <input\n #minutes\n class=\"ngnz-minutes ngnz-width-2em\"\n formControlName=\"minutes\"\n readonly\n [matTooltip]=\"focused ? '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043B\u0435\u0441\u043E \u043F\u0440\u043E\u043A\u0440\u0443\u0442\u043A\u0438' : ''\"\n [ngClass]=\"inputClassesConf\"\n (wheel)=\"wheel($event, 'minutes')\"\n />\n <button\n *ngIf=\"showButtons || (!noButtons && focused)\"\n class=\"ngnz-button\"\n [ngClass]=\"buttonIncreaseClassesConf\"\n (click)=\"btnIncrease($event, 'minutes')\"\n >\n <mat-icon class=\"ngnz-square-1em\">{{\n increaseBtnIconName\n }}</mat-icon>\n </button>\n </div>\n\n <div class=\"ngnz-splitter\" *ngIf=\"!noSeconds\">{{ splitter }}</div>\n\n <div class=\"ngnz-seconds-block\" *ngIf=\"!noSeconds\">\n <button\n *ngIf=\"showButtons || (!noButtons && focused)\"\n class=\"ngnz-button\"\n [ngClass]=\"buttonDecreaseClassesConf\"\n (click)=\"btnDecrease($event, 'seconds')\"\n >\n <mat-icon class=\"ngnz-square-1em\">{{\n decreaseBtnIconName\n }}</mat-icon>\n </button>\n <input\n #seconds\n class=\"ngnz-seconds ngnz-width-2em\"\n formControlName=\"seconds\"\n readonly\n [matTooltip]=\"focused ? '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043B\u0435\u0441\u043E \u043F\u0440\u043E\u043A\u0440\u0443\u0442\u043A\u0438' : ''\"\n [ngClass]=\"inputClassesConf\"\n (wheel)=\"wheel($event, 'seconds')\"\n />\n <button\n *ngIf=\"showButtons || (!noButtons && focused)\"\n class=\"ngnz-button\"\n [ngClass]=\"buttonIncreaseClassesConf\"\n (click)=\"btnIncrease($event, 'seconds')\"\n >\n <mat-icon class=\"ngnz-square-1em\">{{\n increaseBtnIconName\n }}</mat-icon>\n </button>\n </div>\n \n</div>\n",
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{
provide: MatFormFieldControl,
useExisting: NgnzTimeInputInlineComponent_1,
},
],
styles: [".ngnz-time-group{display:flex!important;justify-content:center!important;align-items:center!important;padding:0!important}.ngnz-time-group .ngnz-hours-block,.ngnz-time-group .ngnz-minutes-block,.ngnz-time-group .ngnz-seconds-block,.ngnz-time-group .ngnz-splitter{display:flex!important;align-items:center!important;justify-content:center!important;flex-direction:row!important}.ngnz-time-group .ngnz-hours-block .ngnz-hours,.ngnz-time-group .ngnz-hours-block .ngnz-minutes,.ngnz-time-group .ngnz-hours-block .ngnz-seconds,.ngnz-time-group .ngnz-minutes-block .ngnz-hours,.ngnz-time-group .ngnz-minutes-block .ngnz-minutes,.ngnz-time-group .ngnz-minutes-block .ngnz-seconds,.ngnz-time-group .ngnz-seconds-block .ngnz-hours,.ngnz-time-group .ngnz-seconds-block .ngnz-minutes,.ngnz-time-group .ngnz-seconds-block .ngnz-seconds,.ngnz-time-group .ngnz-splitter .ngnz-hours,.ngnz-time-group .ngnz-splitter .ngnz-minutes,.ngnz-time-group .ngnz-splitter .ngnz-seconds{color:inherit;border:none;outline:0;font:inherit;text-align:center!important;vertical-align:middle!important;padding:0!important}.ngnz-time-group .ngnz-hours-block .ngnz-button,.ngnz-time-group .ngnz-minutes-block .ngnz-button,.ngnz-time-group .ngnz-seconds-block .ngnz-button,.ngnz-time-group .ngnz-splitter .ngnz-button{cursor:pointer;padding:0!important;font-weight:700;display:flex!important;justify-content:center!important;align-items:center!important;line-height:inherit!important;font-size:inherit!important;box-sizing:border-box;position:relative;top:0}.ngnz-time-group .ngnz-hours-block .ngnz-button ::ng-deep .mat-button-wrapper,.ngnz-time-group .ngnz-minutes-block .ngnz-button ::ng-deep .mat-button-wrapper,.ngnz-time-group .ngnz-seconds-block .ngnz-button ::ng-deep .mat-button-wrapper,.ngnz-time-group .ngnz-splitter .ngnz-button ::ng-deep .mat-button-wrapper{line-height:inherit!important;padding:0!important}.ngnz-time-group .ngnz-hours-block .ngnz-button ::ng-deep .mat-button-base,.ngnz-time-group .ngnz-minutes-block .ngnz-button ::ng-deep .mat-button-base,.ngnz-time-group .ngnz-seconds-block .ngnz-button ::ng-deep .mat-button-base,.ngnz-time-group .ngnz-splitter .ngnz-button ::ng-deep .mat-button-base{min-width:inherit!important}.ngnz-time-group .ngnz-splitter{opacity:0;min-width:1em!important;transition:opacity .2s!important}:host.floating .ngnz-splitter{opacity:1}.ngnz-lr-margin-1em{margin-left:1em;margin-right:1em}.ngnz-square-1em,.ngnz-time-group .ngnz-hours-block .ngnz-button,.ngnz-time-group .ngnz-minutes-block .ngnz-button,.ngnz-time-group .ngnz-seconds-block .ngnz-button,.ngnz-time-group .ngnz-splitter .ngnz-button,.ngnz-width-1em{width:1em!important;min-width:1em!important}.ngnz-height-1em,.ngnz-square-1em,.ngnz-time-group .ngnz-hours-block .ngnz-button,.ngnz-time-group .ngnz-minutes-block .ngnz-button,.ngnz-time-group .ngnz-seconds-block .ngnz-button,.ngnz-time-group .ngnz-splitter .ngnz-button{height:1em!important;min-height:1em!important}.ngnz-width-2em{width:2em!important;min-width:2em!important}.ngnz-height-2em{height:2em!important;min-height:2em!important}.material-icons{font-size:inherit!important}"]
}),
tslib_1.__param(3, Optional()), tslib_1.__param(3, Self())
], NgnzTimeInputInlineComponent);
return NgnzTimeInputInlineComponent;
}());
export { NgnzTimeInputInlineComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmduei10aW1lLWlucHV0LWlubGluZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ256LXRpbWUtaW5wdXQvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9uZ256LXRpbWUtaW5wdXQtaW5saW5lL25nbnotdGltZS1pbnB1dC1pbmxpbmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDOUQsT0FBTyxFQUNILHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULE9BQU8sRUFDUCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osS0FBSyxFQUNMLFNBQVMsRUFDVCxNQUFNLEVBQ04sUUFBUSxFQUNSLE1BQU0sRUFDTixJQUFJLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDeEQsT0FBTyxLQUFLLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDakMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUNwRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFHaEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBR3JFOzs7Ozs7OztHQVFHO0FBYUg7SUF5S0ksc0NBQ2MsR0FB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O0lBdEt4RCw0QkFBNEI7UUFaeEMsU0FBUyxDQUFDO1lBQ1AsUUFBUSxFQUFFLHdCQUF3QjtZQUNsQyx1NkhBQXNEO1lBRXRELGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO1lBQy9DLFNBQVMsRUFBRTtnQkFDUDtvQkFDSSxPQUFPLEVBQUUsbUJBQW1CO29CQUM1QixXQUFXLEVBQUUsOEJBQTRCO2lCQUM1QzthQUNKOztTQUNKLENBQUM7UUE4S08sbUJBQUEsUUFBUSxFQUFFLENBQUEsRUFBRSxtQkFBQSxJQUFJLEVBQUUsQ0FBQTtPQTdLZCw0QkFBNEIsQ0FzWXhDO0lBQUQsbUNBQUM7Q0FBQSxBQXRZRCxJQXNZQztTQXRZWSw0QkFBNEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb2N1c01vbml0b3IgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBjb2VyY2VCb29sZWFuUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgRG9DaGVjayxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0QmluZGluZyxcbiAgICBIb3N0TGlzdGVuZXIsXG4gICAgSW5wdXQsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPcHRpb25hbCxcbiAgICBPdXRwdXQsXG4gICAgU2VsZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgTmdDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsJztcbmltcG9ydCAqIGFzIG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMvaW50ZXJuYWwvU3ViamVjdCc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGZpbHRlciwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBDc3NDbGFzc0NyZWF0b3IgfSBmcm9tICcuLi8uLi9jbGFzc2VzL2Nzcy1jbGFzcy1jcmVhdG9yL2Nzcy1jbGFzcy1jcmVhdG9yJztcbmltcG9ydCB7IFRpbWVWYWx1ZSB9IGZyb20gJy4uLy4uL2NsYXNzZXMvdGltZS12YWx1ZS90aW1lLXZhbHVlJztcbmltcG9ydCB7IENzc0NsYXNzZXMgfSBmcm9tICcuLi8uLi9kYXRhdHlwZXMvY3NzLWNsYXNzZXMnO1xuaW1wb3J0IHsgQ3NzQ2xhc3Nlc0RlZmluaXRpb24gfSBmcm9tICcuLi8uLi9kYXRhdHlwZXMvY3NzLWNsYXNzZXMtZGVmaW5pdGlvbic7XG5pbXBvcnQgeyBUaW1lSW5wdXRNb2RlIH0gZnJvbSAnLi4vLi4vZGF0YXR5cGVzL3RpbWUtaW5wdXQtbW9kZS5lbnVtJztcbmltcG9ydCB7IFRpbWVWYWx1ZVR5cGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3RpbWUtdmFsdWUtdHlwZSc7XG5cbi8qKlxuICogVGltZSBJbnB1dCBDb21wb25lbnQuXG4gKiBUaGUgY29tcG9uZW50IGFzIGEgcGFydCBvZiBVSSBhbGxvd3MgdG8gY2hhbmdlIHRpbWUgcGFydCBvZiBNb21lbnQgZGF0YSB0eXBlLlxuICogSXQgbG9va3MgYW5kIHVzZXMgbGlrZSBhIGlucHV0IGZpZWxkLlxuICogSXQgaXMgcG9zc2libGUgdG8gdXNlIG1vdXNlIHdoZWVsIGFuZC9vciBjb250cm9sIGJ1dHRvbnMgdG8gY2hhbmdlIHRpbWUuXG4gKiBDYW4gYmUgdXNlZCB3aXRoIFt2YWx1ZV0gYXR0cmlidXRlIG9yIEZvcm1Db250cm9sIGluc2lkZSBhbmd1bGFyIHJlYWN0aXZlIGZvcm1cbiAqIEBhdXRob3IgQWxla3NleSBOYXphcmVua29cbiAqIEB2ZXJzaW9uIDAuMC4xXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmduei10aW1lLWlucHV0LWlubGluZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL25nbnotdGltZS1pbnB1dC1pbmxpbmUuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL25nbnotdGltZS1pbnB1dC1pbmxpbmUuY29tcG9uZW50LnNjc3MnXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTWF0Rm9ybUZpZWxkQ29udHJvbCxcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBOZ256VGltZUlucHV0SW5saW5lQ29tcG9uZW50LFxuICAgICAgICB9LFxuICAgIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5nbnpUaW1lSW5wdXRJbmxpbmVDb21wb25lbnRcbiAgICBpbXBsZW1lbnRzXG4gICAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXG4gICAgTWF0Rm9ybUZpZWxkQ29udHJvbDxtb21lbnQuTW9tZW50PixcbiAgICBPbkluaXQsXG4gICAgT25EZXN0cm95LFxuICAgIERvQ2hlY2sge1xuICAgIHN0YXRpYyBuZXh0SWQgPSAwO1xuICAgIHJlYWRvbmx5IEJVVFRPTl9IT1NUX0FUVFJJQlVURVMgPSBbXG4gICAgICAgICdtYXQtYnV0dG9uJyxcbiAgICAgICAgJ21hdC1mbGF0LWJ1dHRvbicsXG4gICAgICAgICdtYXQtaWNvbi1idXR0b24nLFxuICAgICAgICAnbWF0LXJhaXNlZC1idXR0b24nLFxuICAgICAgICAnbWF0LXN0cm9rZWQtYnV0dG9uJyxcbiAgICAgICAgJ21hdC1taW5pLWZhYicsXG4gICAgICAgICdtYXQtZmFiJyxcbiAgICBdO1xuICAgIHN0YXRlQ2hhbmdlcyA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gICAgcHJvdGVjdGVkIF90aW1lVmFsdWU6IFRpbWVWYWx1ZTtcbiAgICBwcm90ZWN0ZWQgX2lucHV0VmFsdWU6IG1vbWVudC5Nb21lbnQ7XG5cbiAgICBwcm90ZWN0ZWQgX2hvdXJzQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbChudWxsKTtcbiAgICBwcm90ZWN0ZWQgX21pbnV0ZXNDb250cm9sID0gbmV3IEZvcm1Db250cm9sKG51bGwpO1xuICAgIHByb3RlY3RlZCBfc2Vjb25kc0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2wobnVsbCk7XG4gICAgcHVibGljIHBhcnRzOiBGb3JtR3JvdXAgPSBuZXcgRm9ybUdyb3VwKHtcbiAgICAgICAgaG91cnM6IHRoaXMuX2hvdXJzQ29udHJvbCxcbiAgICAgICAgbWludXRlczogdGhpcy5fbWludXRlc0NvbnRyb2wsXG4gICAgICAgIHNlY29uZHM6IHRoaXMuX3NlY29uZHNDb250cm9sLFxuICAgIH0pO1xuICAgIHByb3RlY3RlZCBfcGxhY2Vob2xkZXI6IHN0cmluZztcbiAgICBwcm90ZWN0ZWQgX3JlcXVpcmVkID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIF9kaXNhYmxlZCA9IGZhbHNlO1xuICAgIHByb3RlY3RlZCBfdW5zdWJzY3JpYmUgPSBuZXcgU3ViamVjdCgpO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfZGVib3VuY2VUaW1lID0gMzAwO1xuICAgIF9mb2N1c2VkID0gZmFsc2U7XG4gICAgZ2V0IGZvY3VzZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb2N1c2VkO1xuICAgIH1cbiAgICBzZXQgZm9jdXNlZCh2YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fZm9jdXNlZCA9IHZhbDtcbiAgICB9XG4gICAgY29udHJvbFR5cGUgPSAnbmduei10aW1lLWlucHV0LWlubGluZSc7XG4gICAgYXV0b2ZpbGxlZD86IGJvb2xlYW47XG4gICAgQEhvc3RCaW5kaW5nKCkgaWQgPSBbXG4gICAgICAgIHRoaXMuY29udHJvbFR5cGUsXG4gICAgICAgICsrTmduelRpbWVJbnB1dElubGluZUNvbXBvbmVudC5uZXh0SWQsXG4gICAgXS5qb2luKCctJyk7XG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtZGVzY3JpYmVkYnknKSBkZXNjcmliZWRCeSA9ICcnO1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuZmxvYXRpbmcnKSBnZXQgc2hvdWxkTGFiZWxGbG9hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9jdXNlZCB8fCAhdGhpcy5lbXB0eTtcbiAgICB9XG5cblxuICAgIC8vIGZyb20gTWF0ZXJpYWwgdGhlbWU6IHByaW1hcnksIGFjY2VudCwgd2FyblxuICAgIEBJbnB1dCgpIGNvbG9yOiBzdHJpbmc7XG4gICAgcHVibGljIGNvbG9yQ2xhc3NOYW1lOiBzdHJpbmc7XG5cbiAgICAvLyB0eXBlIG9mIGNvbnRyb2wgYnV0dG9ucyBpbiBNYXRlcmlhbCBEZXNpZ246IG1hdC1idXR0b24sIG1hdC1yYWlzZWQtYnV0dG9uIGV0Yy5cbiAgICBASW5wdXQoKSBidXR0b25NYXRUeXBlOiBzdHJpbmc7XG4gICAgcHVibGljIGJ1dHRvbk1hdFR5cGVDbGFzc05hbWU6IHN0cmluZztcblxuXG4gICAgLy8gYWRkaXRpb25hbCBjc3MgY2xhc3NlcyBmb3IgaW5wdXQgZmllbGRzIG9mIGhvdXJzLCBtaW51dGVzIGFuZCBzZWNvbmRzXG4gICAgQElucHV0KCkgaW5wdXRDbGFzc2VzOiBDc3NDbGFzc2VzRGVmaW5pdGlvbjtcbiAgICBpbnB1dENsYXNzZXNDb25mOiBDc3NDbGFzc2VzID0ge307XG5cblxuICAgIC8vIGFkZGl0aW9uYWwgY3NzIGNsYXNzZXMgZm9yIGNvbnRyb2wgYnV0dG9uc1xuICAgIEBJbnB1dCgpIGJ1dHRvbnNDbGFzc2VzOiBDc3NDbGFzc2VzRGVmaW5pdGlvbjtcblxuICAgIC8vIGFkZGl0aW9uYWwgY3NzIGNsYXNzZXMgZm9yIGRlY3JlYXNlIGJ1dHRvbiBvbiB0aGUgbGVmdCBzaWRlIG9mIHRoZSBpbnB1dCBmaWVsZWRcbiAgICBASW5wdXQoKSBidXR0b25EZWNyZWFzZUNsYXNzZXM6IENzc0NsYXNzZXNEZWZpbml0aW9uO1xuXG4gICAgLy8gYWRkaXRpb25hbCBjc3MgY2xhc3NlcyBmb3IgaW5jcmVhc2UgYnV0dG9uIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBpbnB1dCBmaWVsZWRcbiAgICBASW5wdXQoKSBidXR0b25JbmNyZWFzZUNsYXNzZXM6IENzc0NsYXNzZXNEZWZpbml0aW9uO1xuICAgIGJ1dHRvbkRlY3JlYXNlQ2xhc3Nlc0NvbmY6IENzc0NsYXNzZXMgPSB7fTtcbiAgICBidXR0b25JbmNyZWFzZUNsYXNzZXNDb25mOiBDc3NDbGFzc2VzID0ge307XG5cbiAgICBwdWJsaWMgY3NzSW5wOiBDc3NDbGFzc2VzO1xuXG5cbiAgICAvLyBwbGFjZWhvbGRlciAvLyBGSVhNRTogaXMgdG8gc2hvdyB3aGVuIHZhbHVlIGlzIG5vdCBzZXRcbiAgICBASW5wdXQoKVxuICAgIGdldCBwbGFjZWhvbGRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYWNlaG9sZGVyO1xuICAgIH1cbiAgICBzZXQgcGxhY2Vob2xkZXIocGxhY2Vob2xkZXIpIHtcbiAgICAgICAgdGhpcy5fcGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgICB9XG5cblxuICAgIC8vIGVudW0gZGVmaW5pbmcgb2YgdGltZSBjaGFuZ2UgbW9kZTogTGltaXQsIENpcmN1bGFyLCBDaXJjdWxhckZvcndhcmRpbmdcbiAgICBASW5wdXQoKSBpbnB1dE1vZGU6IFRpbWVJbnB1dE1vZGUgPSBUaW1lSW5wdXRNb2RlLkNpcmN1bGFyRm9yd2FyZGluZztcblxuICAgIEBJbnB1dCgpXG4gICAgZ2V0IHZhbHVlKCk6IG1vbWVudC5Nb21lbnQge1xuICAgICAgICBjb25zdCBvdXQgPSBtb21lbnQoe1xuICAgICAgICAgICAgeWVhcnM6IHRoaXMuX2lucHV0VmFsdWUueWVhcigpLFxuICAgICAgICAgICAgbW9udGhzOiB0aGlzLl9pbnB1dFZhbHVlLm1vbnRoKCksXG4gICAgICAgICAgICBkYXlzOiB0aGlzLl9pbnB1dFZhbHVlLmRhdGUoKSxcbiAgICAgICAgICAgIGhvdXJzOiB0aGlzLl90aW1lVmFsdWUuaG91cnMsXG4gICAgICAgICAgICBtaW51dGVzOiB0aGlzLl90aW1lVmFsdWUubWludXRlcyxcbiAgICAgICAgICAgIHNlY29uZHM6IHRoaXMuX3RpbWVWYWx1ZS5zZWNvbmRzLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG4gICAgc2V0IHZhbHVlKHZhbHVlOiBtb21lbnQuTW9tZW50KSB7XG4gICAgICAgIHRoaXMuX2lucHV0VmFsdWUgPSAoISF2YWx1ZSAmJiBtb21lbnQuaXNNb21lbnQodmFsdWUpICYmIHZhbHVlKSB8fCBtb21lbnQoKTtcbiAgICAgICAgY29uc3QgaG91cnMgPSArdGhpcy5faW5wdXRWYWx1ZS5ob3VycygpO1xuICAgICAgICBjb25zdCBtaW51dGVzID0gK3RoaXMuX2lucHV0VmFsdWUubWludXRlcygpO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gK3RoaXMuX2lucHV0VmFsdWUuc2Vjb25kcygpO1xuICAgICAgICB0aGlzLl90aW1lVmFsdWUuc2V0SG91cnMoaG91cnMpLnNldE1pbnV0ZXMobWludXRlcykuc2V0U2Vjb25kcyhzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5kZXRlY3RDaGFuZ2llcygpO1xuICAgIH1cbiAgICBASW5wdXQoKVxuICAgIGdldCByZXF1aXJlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlcXVpcmVkO1xuICAgIH1cbiAgICBzZXQgcmVxdWlyZWQocmVxKSB7XG4gICAgICAgIHRoaXMuX3JlcXVpcmVkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHJlcSk7XG4gICAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdpZXMoKTtcbiAgICB9XG4gICAgQElucHV0KClcbiAgICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXNhYmxlZDtcbiAgICB9XG4gICAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX2Rpc2FibGVkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgICAgICAgdGhpcy5fZGlzYWJsZWQgPyB0aGlzLnBhcnRzLmRpc2FibGUoKSA6IHRoaXMucGFydHMuZW5hYmxlKCk7XG4gICAgICAgIHRoaXMuZGV0ZWN0Q2hhbmdpZXMoKTtcbiAgICB9XG5cbiAgICAvLyBvbmUgY2hhcmFjdGVyIHRvIHNlcGFyYXRlIGhvdXJzIGZyb20gbWludXRlcyBhbmQgbWludXRlcyBmcm9tIHNlY29uZHM7IGRlZmF1bHQgaXMgJzonXG4gICAgQElucHV0KClcbiAgICBnZXQgc3BsaXR0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zcGxpdHRlciB8fCAnOic7XG4gICAgf