ngx-bootstrap
Version:
Native Angular Bootstrap Components
1,134 lines (1,122 loc) • 99.3 kB
JavaScript
import { Injectable, ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, forwardRef, Input, Output, ViewEncapsulation, NgModule } from '@angular/core';
import { __extends } from 'tslib';
import { BehaviorSubject } from 'rxjs';
import { MiniStore, MiniState } from 'ngx-bootstrap/mini-ngrx';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var TimepickerActions = /** @class */ (function () {
function TimepickerActions() {
}
/**
* @param {?} value
* @return {?}
*/
TimepickerActions.prototype.writeValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
return {
type: TimepickerActions.WRITE_VALUE,
payload: value
};
};
/**
* @param {?} event
* @return {?}
*/
TimepickerActions.prototype.changeHours = /**
* @param {?} event
* @return {?}
*/
function (event) {
return {
type: TimepickerActions.CHANGE_HOURS,
payload: event
};
};
/**
* @param {?} event
* @return {?}
*/
TimepickerActions.prototype.changeMinutes = /**
* @param {?} event
* @return {?}
*/
function (event) {
return {
type: TimepickerActions.CHANGE_MINUTES,
payload: event
};
};
/**
* @param {?} event
* @return {?}
*/
TimepickerActions.prototype.changeSeconds = /**
* @param {?} event
* @return {?}
*/
function (event) {
return {
type: TimepickerActions.CHANGE_SECONDS,
payload: event
};
};
/**
* @param {?} value
* @return {?}
*/
TimepickerActions.prototype.setTime = /**
* @param {?} value
* @return {?}
*/
function (value) {
return {
type: TimepickerActions.SET_TIME_UNIT,
payload: value
};
};
/**
* @param {?} value
* @return {?}
*/
TimepickerActions.prototype.updateControls = /**
* @param {?} value
* @return {?}
*/
function (value) {
return {
type: TimepickerActions.UPDATE_CONTROLS,
payload: value
};
};
TimepickerActions.WRITE_VALUE = '[timepicker] write value from ng model';
TimepickerActions.CHANGE_HOURS = '[timepicker] change hours';
TimepickerActions.CHANGE_MINUTES = '[timepicker] change minutes';
TimepickerActions.CHANGE_SECONDS = '[timepicker] change seconds';
TimepickerActions.SET_TIME_UNIT = '[timepicker] set time unit';
TimepickerActions.UPDATE_CONTROLS = '[timepicker] update controls';
TimepickerActions.decorators = [
{ type: Injectable }
];
return TimepickerActions;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var /** @type {?} */ dex = 10;
var /** @type {?} */ hoursPerDay = 24;
var /** @type {?} */ hoursPerDayHalf = 12;
var /** @type {?} */ minutesPerHour = 60;
var /** @type {?} */ secondsPerMinute = 60;
/**
* @param {?=} value
* @return {?}
*/
function isValidDate(value) {
if (!value) {
return false;
}
if (value instanceof Date && isNaN(value.getHours())) {
return false;
}
if (typeof value === 'string') {
return isValidDate(new Date(value));
}
return true;
}
/**
* @param {?} controls
* @param {?} newDate
* @return {?}
*/
function isValidLimit(controls, newDate) {
if (controls.min && newDate < controls.min) {
return false;
}
if (controls.max && newDate > controls.max) {
return false;
}
return true;
}
/**
* @param {?} value
* @return {?}
*/
function toNumber(value) {
if (typeof value === 'number') {
return value;
}
return parseInt(value, dex);
}
/**
* @param {?} value
* @param {?=} isPM
* @return {?}
*/
function parseHours(value, isPM) {
if (isPM === void 0) { isPM = false; }
var /** @type {?} */ hour = toNumber(value);
if (isNaN(hour) ||
hour < 0 ||
hour > (isPM ? hoursPerDayHalf : hoursPerDay)) {
return NaN;
}
return hour;
}
/**
* @param {?} value
* @return {?}
*/
function parseMinutes(value) {
var /** @type {?} */ minute = toNumber(value);
if (isNaN(minute) || minute < 0 || minute > minutesPerHour) {
return NaN;
}
return minute;
}
/**
* @param {?} value
* @return {?}
*/
function parseSeconds(value) {
var /** @type {?} */ seconds = toNumber(value);
if (isNaN(seconds) || seconds < 0 || seconds > secondsPerMinute) {
return NaN;
}
return seconds;
}
/**
* @param {?} value
* @return {?}
*/
function parseTime(value) {
if (typeof value === 'string') {
return new Date(value);
}
return value;
}
/**
* @param {?} value
* @param {?} diff
* @return {?}
*/
function changeTime(value, diff) {
if (!value) {
return changeTime(createDate(new Date(), 0, 0, 0), diff);
}
var /** @type {?} */ hour = value.getHours();
var /** @type {?} */ minutes = value.getMinutes();
var /** @type {?} */ seconds = value.getSeconds();
if (diff.hour) {
hour = (hour + toNumber(diff.hour)) % hoursPerDay;
if (hour < 0) {
hour += hoursPerDay;
}
}
if (diff.minute) {
minutes = minutes + toNumber(diff.minute);
}
if (diff.seconds) {
seconds = seconds + toNumber(diff.seconds);
}
return createDate(value, hour, minutes, seconds);
}
/**
* @param {?} value
* @param {?} opts
* @return {?}
*/
function setTime(value, opts) {
var /** @type {?} */ hour = parseHours(opts.hour);
var /** @type {?} */ minute = parseMinutes(opts.minute);
var /** @type {?} */ seconds = parseSeconds(opts.seconds) || 0;
if (opts.isPM) {
hour += hoursPerDayHalf;
}
if (!value) {
if (!isNaN(hour) && !isNaN(minute)) {
return createDate(new Date(), hour, minute, seconds);
}
return value;
}
if (isNaN(hour) || isNaN(minute)) {
return value;
}
return createDate(value, hour, minute, seconds);
}
/**
* @param {?} value
* @param {?} hours
* @param {?} minutes
* @param {?} seconds
* @return {?}
*/
function createDate(value, hours, minutes, seconds) {
return new Date(value.getFullYear(), value.getMonth(), value.getDate(), hours, minutes, seconds, value.getMilliseconds());
}
/**
* @param {?} value
* @return {?}
*/
function padNumber(value) {
var /** @type {?} */ _value = value.toString();
if (_value.length > 1) {
return _value;
}
return "0" + _value;
}
/**
* @param {?} hours
* @param {?} isPM
* @return {?}
*/
function isHourInputValid(hours, isPM) {
return !isNaN(parseHours(hours, isPM));
}
/**
* @param {?} minutes
* @return {?}
*/
function isMinuteInputValid(minutes) {
return !isNaN(parseMinutes(minutes));
}
/**
* @param {?} seconds
* @return {?}
*/
function isSecondInputValid(seconds) {
return !isNaN(parseSeconds(seconds));
}
/**
* @param {?} diff
* @param {?} max
* @param {?} min
* @return {?}
*/
function isInputLimitValid(diff, max, min) {
var /** @type {?} */ newDate = changeTime(new Date(), diff);
if (max && newDate > max) {
return false;
}
if (min && newDate < min) {
return false;
}
return true;
}
/**
* @param {?} hours
* @param {?=} minutes
* @param {?=} seconds
* @param {?=} isPM
* @return {?}
*/
function isInputValid(hours, minutes, seconds, isPM) {
if (minutes === void 0) { minutes = '0'; }
if (seconds === void 0) { seconds = '0'; }
return isHourInputValid(hours, isPM)
&& isMinuteInputValid(minutes)
&& isSecondInputValid(seconds);
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @param {?} state
* @param {?=} event
* @return {?}
*/
function canChangeValue(state, event) {
if (state.readonlyInput || state.disabled) {
return false;
}
if (event) {
if (event.source === 'wheel' && !state.mousewheel) {
return false;
}
if (event.source === 'key' && !state.arrowkeys) {
return false;
}
}
return true;
}
/**
* @param {?} event
* @param {?} controls
* @return {?}
*/
function canChangeHours(event, controls) {
if (!event.step) {
return false;
}
if (event.step > 0 && !controls.canIncrementHours) {
return false;
}
if (event.step < 0 && !controls.canDecrementHours) {
return false;
}
return true;
}
/**
* @param {?} event
* @param {?} controls
* @return {?}
*/
function canChangeMinutes(event, controls) {
if (!event.step) {
return false;
}
if (event.step > 0 && !controls.canIncrementMinutes) {
return false;
}
if (event.step < 0 && !controls.canDecrementMinutes) {
return false;
}
return true;
}
/**
* @param {?} event
* @param {?} controls
* @return {?}
*/
function canChangeSeconds(event, controls) {
if (!event.step) {
return false;
}
if (event.step > 0 && !controls.canIncrementSeconds) {
return false;
}
if (event.step < 0 && !controls.canDecrementSeconds) {
return false;
}
return true;
}
/**
* @param {?} state
* @return {?}
*/
function getControlsValue(state) {
var hourStep = state.hourStep, minuteStep = state.minuteStep, secondsStep = state.secondsStep, readonlyInput = state.readonlyInput, disabled = state.disabled, mousewheel = state.mousewheel, arrowkeys = state.arrowkeys, showSpinners = state.showSpinners, showMeridian = state.showMeridian, showSeconds = state.showSeconds, meridians = state.meridians, min = state.min, max = state.max;
return {
hourStep: hourStep,
minuteStep: minuteStep,
secondsStep: secondsStep,
readonlyInput: readonlyInput,
disabled: disabled,
mousewheel: mousewheel,
arrowkeys: arrowkeys,
showSpinners: showSpinners,
showMeridian: showMeridian,
showSeconds: showSeconds,
meridians: meridians,
min: min,
max: max
};
}
/**
* @param {?} value
* @param {?} state
* @return {?}
*/
function timepickerControls(value, state) {
var /** @type {?} */ hoursPerDayHalf = 12;
var min = state.min, max = state.max, hourStep = state.hourStep, minuteStep = state.minuteStep, secondsStep = state.secondsStep, showSeconds = state.showSeconds;
var /** @type {?} */ res = {
canIncrementHours: true,
canIncrementMinutes: true,
canIncrementSeconds: true,
canDecrementHours: true,
canDecrementMinutes: true,
canDecrementSeconds: true,
canToggleMeridian: true
};
if (!value) {
return res;
}
// compare dates
if (max) {
var /** @type {?} */ _newHour = changeTime(value, { hour: hourStep });
res.canIncrementHours = max > _newHour;
if (!res.canIncrementHours) {
var /** @type {?} */ _newMinutes = changeTime(value, { minute: minuteStep });
res.canIncrementMinutes = showSeconds
? max > _newMinutes
: max >= _newMinutes;
}
if (!res.canIncrementMinutes) {
var /** @type {?} */ _newSeconds = changeTime(value, { seconds: secondsStep });
res.canIncrementSeconds = max >= _newSeconds;
}
if (value.getHours() < hoursPerDayHalf) {
res.canToggleMeridian = changeTime(value, { hour: hoursPerDayHalf }) < max;
}
}
if (min) {
var /** @type {?} */ _newHour = changeTime(value, { hour: -hourStep });
res.canDecrementHours = min < _newHour;
if (!res.canDecrementHours) {
var /** @type {?} */ _newMinutes = changeTime(value, { minute: -minuteStep });
res.canDecrementMinutes = showSeconds
? min < _newMinutes
: min <= _newMinutes;
}
if (!res.canDecrementMinutes) {
var /** @type {?} */ _newSeconds = changeTime(value, { seconds: -secondsStep });
res.canDecrementSeconds = min <= _newSeconds;
}
if (value.getHours() >= hoursPerDayHalf) {
res.canToggleMeridian = changeTime(value, { hour: -hoursPerDayHalf }) > min;
}
}
return res;
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Provides default configuration values for timepicker
*/
var TimepickerConfig = /** @class */ (function () {
function TimepickerConfig() {
/**
* hours change step
*/
this.hourStep = 1;
/**
* hours change step
*/
this.minuteStep = 5;
/**
* seconds changes step
*/
this.secondsStep = 10;
/**
* if true works in 12H mode and displays AM/PM. If false works in 24H mode and hides AM/PM
*/
this.showMeridian = true;
/**
* meridian labels based on locale
*/
this.meridians = ['AM', 'PM'];
/**
* if true hours and minutes fields will be readonly
*/
this.readonlyInput = false;
/**
* if true hours and minutes fields will be disabled
*/
this.disabled = false;
/**
* if true scroll inside hours and minutes inputs will change time
*/
this.mousewheel = true;
/**
* if true the values of hours and minutes can be changed using the up/down arrow keys on the keyboard
*/
this.arrowkeys = true;
/**
* if true spinner arrows above and below the inputs will be shown
*/
this.showSpinners = true;
/**
* show seconds in timepicker
*/
this.showSeconds = false;
/**
* show minutes in timepicker
*/
this.showMinutes = true;
}
TimepickerConfig.decorators = [
{ type: Injectable }
];
return TimepickerConfig;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var /** @type {?} */ initialState = {
value: null,
config: new TimepickerConfig(),
controls: {
canIncrementHours: true,
canIncrementMinutes: true,
canIncrementSeconds: true,
canDecrementHours: true,
canDecrementMinutes: true,
canDecrementSeconds: true,
canToggleMeridian: true
}
};
/**
* @param {?=} state
* @param {?=} action
* @return {?}
*/
function timepickerReducer(state, action) {
if (state === void 0) { state = initialState; }
switch (action.type) {
case TimepickerActions.WRITE_VALUE: {
return Object.assign({}, state, { value: action.payload });
}
case TimepickerActions.CHANGE_HOURS: {
if (!canChangeValue(state.config, action.payload) ||
!canChangeHours(action.payload, state.controls)) {
return state;
}
var /** @type {?} */ _newTime = changeTime(state.value, { hour: action.payload.step });
if ((state.config.max || state.config.min) && !isValidLimit(state.config, _newTime)) {
return state;
}
return Object.assign({}, state, { value: _newTime });
}
case TimepickerActions.CHANGE_MINUTES: {
if (!canChangeValue(state.config, action.payload) ||
!canChangeMinutes(action.payload, state.controls)) {
return state;
}
var /** @type {?} */ _newTime = changeTime(state.value, { minute: action.payload.step });
if ((state.config.max || state.config.min) && !isValidLimit(state.config, _newTime)) {
return state;
}
return Object.assign({}, state, { value: _newTime });
}
case TimepickerActions.CHANGE_SECONDS: {
if (!canChangeValue(state.config, action.payload) ||
!canChangeSeconds(action.payload, state.controls)) {
return state;
}
var /** @type {?} */ _newTime = changeTime(state.value, {
seconds: action.payload.step
});
if ((state.config.max || state.config.min) && !isValidLimit(state.config, _newTime)) {
return state;
}
return Object.assign({}, state, { value: _newTime });
}
case TimepickerActions.SET_TIME_UNIT: {
if (!canChangeValue(state.config)) {
return state;
}
var /** @type {?} */ _newTime = setTime(state.value, action.payload);
return Object.assign({}, state, { value: _newTime });
}
case TimepickerActions.UPDATE_CONTROLS: {
var /** @type {?} */ _newControlsState = timepickerControls(state.value, action.payload);
var /** @type {?} */ _newState = {
value: state.value,
config: action.payload,
controls: _newControlsState
};
if (state.config.showMeridian !== _newState.config.showMeridian) {
if (state.value) {
_newState.value = new Date(state.value);
}
}
return Object.assign({}, state, _newState);
}
default:
return state;
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var TimepickerStore = /** @class */ (function (_super) {
__extends(TimepickerStore, _super);
function TimepickerStore() {
var _this = this;
var /** @type {?} */ _dispatcher = new BehaviorSubject({
type: '[mini-ngrx] dispatcher init'
});
var /** @type {?} */ state = new MiniState(initialState, _dispatcher, timepickerReducer);
_this = _super.call(this, _dispatcher, timepickerReducer, state) || this;
return _this;
}
TimepickerStore.decorators = [
{ type: Injectable }
];
/** @nocollapse */
TimepickerStore.ctorParameters = function () { return []; };
return TimepickerStore;
}(MiniStore));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var /** @type {?} */ TIMEPICKER_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
/* tslint:disable-next-line: no-use-before-declare */
useExisting: forwardRef(function () { return TimepickerComponent; }),
multi: true
};
var TimepickerComponent = /** @class */ (function () {
function TimepickerComponent(_config, _cd, _store, _timepickerActions) {
var _this = this;
this._cd = _cd;
this._store = _store;
this._timepickerActions = _timepickerActions;
/**
* emits true if value is a valid date
*/
this.isValid = new EventEmitter();
// min\max validation for input fields
this.invalidHours = false;
this.invalidMinutes = false;
this.invalidSeconds = false;
// control value accessor methods
// tslint:disable-next-line:no-any
this.onChange = Function.prototype;
// tslint:disable-next-line:no-any
this.onTouched = Function.prototype;
Object.assign(this, _config);
this.timepickerSub = _store
.select(function (state) { return state.value; })
.subscribe(function (value) {
// update UI values if date changed
// update UI values if date changed
_this._renderTime(value);
_this.onChange(value);
_this._store.dispatch(_this._timepickerActions.updateControls(getControlsValue(_this)));
});
_store
.select(function (state) { return state.controls; })
.subscribe(function (controlsState) {
_this.isValid.emit(isInputValid(_this.hours, _this.minutes, _this.seconds, _this.isPM()));
Object.assign(_this, controlsState);
_cd.markForCheck();
});
}
Object.defineProperty(TimepickerComponent.prototype, "isSpinnersVisible", {
/** @deprecated - please use `isEditable` instead */
get: /**
* @deprecated - please use `isEditable` instead
* @return {?}
*/
function () {
return this.showSpinners && !this.readonlyInput;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TimepickerComponent.prototype, "isEditable", {
get: /**
* @return {?}
*/
function () {
return !(this.readonlyInput || this.disabled);
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
TimepickerComponent.prototype.resetValidation = /**
* @return {?}
*/
function () {
this.invalidHours = false;
this.invalidMinutes = false;
this.invalidSeconds = false;
};
/**
* @return {?}
*/
TimepickerComponent.prototype.isPM = /**
* @return {?}
*/
function () {
return this.showMeridian && this.meridian === this.meridians[1];
};
/**
* @param {?} $event
* @return {?}
*/
TimepickerComponent.prototype.prevDef = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
$event.preventDefault();
};
/**
* @param {?} $event
* @return {?}
*/
TimepickerComponent.prototype.wheelSign = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
return Math.sign($event.deltaY) * -1;
};
/**
* @param {?} changes
* @return {?}
*/
TimepickerComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
this._store.dispatch(this._timepickerActions.updateControls(getControlsValue(this)));
};
/**
* @param {?} step
* @param {?=} source
* @return {?}
*/
TimepickerComponent.prototype.changeHours = /**
* @param {?} step
* @param {?=} source
* @return {?}
*/
function (step, source) {
if (source === void 0) { source = ''; }
this.resetValidation();
this._store.dispatch(this._timepickerActions.changeHours({ step: step, source: source }));
};
/**
* @param {?} step
* @param {?=} source
* @return {?}
*/
TimepickerComponent.prototype.changeMinutes = /**
* @param {?} step
* @param {?=} source
* @return {?}
*/
function (step, source) {
if (source === void 0) { source = ''; }
this.resetValidation();
this._store.dispatch(this._timepickerActions.changeMinutes({ step: step, source: source }));
};
/**
* @param {?} step
* @param {?=} source
* @return {?}
*/
TimepickerComponent.prototype.changeSeconds = /**
* @param {?} step
* @param {?=} source
* @return {?}
*/
function (step, source) {
if (source === void 0) { source = ''; }
this.resetValidation();
this._store.dispatch(this._timepickerActions.changeSeconds({ step: step, source: source }));
};
/**
* @param {?} hours
* @return {?}
*/
TimepickerComponent.prototype.updateHours = /**
* @param {?} hours
* @return {?}
*/
function (hours) {
this.resetValidation();
this.hours = hours;
var /** @type {?} */ isValid = isHourInputValid(this.hours, this.isPM()) && this.isValidLimit();
if (!isValid) {
this.invalidHours = true;
this.isValid.emit(false);
this.onChange(null);
return;
}
this._updateTime();
};
/**
* @param {?} minutes
* @return {?}
*/
TimepickerComponent.prototype.updateMinutes = /**
* @param {?} minutes
* @return {?}
*/
function (minutes) {
this.resetValidation();
this.minutes = minutes;
var /** @type {?} */ isValid = isMinuteInputValid(this.minutes) && this.isValidLimit();
if (!isValid) {
this.invalidMinutes = true;
this.isValid.emit(false);
this.onChange(null);
return;
}
this._updateTime();
};
/**
* @param {?} seconds
* @return {?}
*/
TimepickerComponent.prototype.updateSeconds = /**
* @param {?} seconds
* @return {?}
*/
function (seconds) {
this.resetValidation();
this.seconds = seconds;
var /** @type {?} */ isValid = isSecondInputValid(this.seconds) && this.isValidLimit();
if (!isValid) {
this.invalidSeconds = true;
this.isValid.emit(false);
this.onChange(null);
return;
}
this._updateTime();
};
/**
* @return {?}
*/
TimepickerComponent.prototype.isValidLimit = /**
* @return {?}
*/
function () {
return isInputLimitValid({
hour: this.hours,
minute: this.minutes,
seconds: this.seconds,
isPM: this.isPM()
}, this.max, this.min);
};
/**
* @return {?}
*/
TimepickerComponent.prototype._updateTime = /**
* @return {?}
*/
function () {
var /** @type {?} */ _seconds = this.showSeconds ? this.seconds : void 0;
var /** @type {?} */ _minutes = this.showMinutes ? this.minutes : void 0;
if (!isInputValid(this.hours, _minutes, _seconds, this.isPM())) {
this.isValid.emit(false);
this.onChange(null);
return;
}
this._store.dispatch(this._timepickerActions.setTime({
hour: this.hours,
minute: this.minutes,
seconds: this.seconds,
isPM: this.isPM()
}));
};
/**
* @return {?}
*/
TimepickerComponent.prototype.toggleMeridian = /**
* @return {?}
*/
function () {
if (!this.showMeridian || !this.isEditable) {
return;
}
var /** @type {?} */ _hoursPerDayHalf = 12;
this._store.dispatch(this._timepickerActions.changeHours({
step: _hoursPerDayHalf,
source: ''
}));
};
/**
* Write a new value to the element.
*/
/**
* Write a new value to the element.
* @param {?} obj
* @return {?}
*/
TimepickerComponent.prototype.writeValue = /**
* Write a new value to the element.
* @param {?} obj
* @return {?}
*/
function (obj) {
if (isValidDate(obj)) {
this._store.dispatch(this._timepickerActions.writeValue(parseTime(obj)));
}
else if (obj == null) {
this._store.dispatch(this._timepickerActions.writeValue(null));
}
};
/**
* Set the function to be called when the control receives a change event.
*/
// tslint:disable-next-line:no-any
/**
* Set the function to be called when the control receives a change event.
* @param {?} fn
* @return {?}
*/
TimepickerComponent.prototype.registerOnChange = /**
* Set the function to be called when the control receives a change event.
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onChange = fn;
};
/**
* Set the function to be called when the control receives a touch event.
*/
/**
* Set the function to be called when the control receives a touch event.
* @param {?} fn
* @return {?}
*/
TimepickerComponent.prototype.registerOnTouched = /**
* Set the function to be called when the control receives a touch event.
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/**
* This function is called when the control status changes to or from "disabled".
* Depending on the value, it will enable or disable the appropriate DOM element.
*
* @param isDisabled
*/
/**
* This function is called when the control status changes to or from "disabled".
* Depending on the value, it will enable or disable the appropriate DOM element.
*
* @param {?} isDisabled
* @return {?}
*/
TimepickerComponent.prototype.setDisabledState = /**
* This function is called when the control status changes to or from "disabled".
* Depending on the value, it will enable or disable the appropriate DOM element.
*
* @param {?} isDisabled
* @return {?}
*/
function (isDisabled) {
this.disabled = isDisabled;
this._cd.markForCheck();
};
/**
* @return {?}
*/
TimepickerComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.timepickerSub.unsubscribe();
};
/**
* @param {?} value
* @return {?}
*/
TimepickerComponent.prototype._renderTime = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (!isValidDate(value)) {
this.hours = '';
this.minutes = '';
this.seconds = '';
this.meridian = this.meridians[0];
return;
}
var /** @type {?} */ _value = parseTime(value);
var /** @type {?} */ _hoursPerDayHalf = 12;
var /** @type {?} */ _hours = _value.getHours();
if (this.showMeridian) {
this.meridian = this.meridians[_hours >= _hoursPerDayHalf ? 1 : 0];
_hours = _hours % _hoursPerDayHalf;
// should be 12 PM, not 00 PM
if (_hours === 0) {
_hours = _hoursPerDayHalf;
}
}
this.hours = padNumber(_hours);
this.minutes = padNumber(_value.getMinutes());
this.seconds = padNumber(_value.getUTCSeconds());
};
TimepickerComponent.decorators = [
{ type: Component, args: [{
selector: 'timepicker',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [TIMEPICKER_CONTROL_VALUE_ACCESSOR, TimepickerStore],
template: "<table>\n <tbody>\n <tr class=\"text-center\" [hidden]=\"!showSpinners\">\n <!-- increment hours button-->\n <td>\n <a class=\"btn btn-link\" [class.disabled]=\"!canIncrementHours || !isEditable\"\n (click)=\"changeHours(hourStep)\"\n ><span class=\"bs-chevron bs-chevron-up\"></span></a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showMinutes\"> </td>\n <!-- increment minutes button -->\n <td *ngIf=\"showMinutes\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canIncrementMinutes || !isEditable\"\n (click)=\"changeMinutes(minuteStep)\"\n ><span class=\"bs-chevron bs-chevron-up\"></span></a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showSeconds\"> </td>\n <!-- increment seconds button -->\n <td *ngIf=\"showSeconds\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canIncrementSeconds || !isEditable\"\n (click)=\"changeSeconds(secondsStep)\">\n <span class=\"bs-chevron bs-chevron-up\"></span>\n </a>\n </td>\n <!-- space between -->\n <td *ngIf=\"showMeridian\"> </td>\n <!-- meridian placeholder-->\n <td *ngIf=\"showMeridian\"></td>\n </tr>\n <tr>\n <!-- hours -->\n <td class=\"form-group\" [class.has-error]=\"invalidHours\">\n <input type=\"text\" [class.is-invalid]=\"invalidHours\"\n class=\"form-control text-center bs-timepicker-field\"\n placeholder=\"HH\"\n maxlength=\"2\"\n [readonly]=\"readonlyInput\"\n [disabled]=\"disabled\"\n [value]=\"hours\"\n (wheel)=\"prevDef($event);changeHours(hourStep * wheelSign($event), 'wheel')\"\n (keydown.ArrowUp)=\"changeHours(hourStep, 'key')\"\n (keydown.ArrowDown)=\"changeHours(-hourStep, 'key')\"\n (change)=\"updateHours($event.target.value)\"></td>\n <!-- divider -->\n <td *ngIf=\"showMinutes\"> : </td>\n <!-- minutes -->\n <td class=\"form-group\" *ngIf=\"showMinutes\" [class.has-error]=\"invalidMinutes\">\n <input type=\"text\" [class.is-invalid]=\"invalidMinutes\"\n class=\"form-control text-center bs-timepicker-field\"\n placeholder=\"MM\"\n maxlength=\"2\"\n [readonly]=\"readonlyInput\"\n [disabled]=\"disabled\"\n [value]=\"minutes\"\n (wheel)=\"prevDef($event);changeMinutes(minuteStep * wheelSign($event), 'wheel')\"\n (keydown.ArrowUp)=\"changeMinutes(minuteStep, 'key')\"\n (keydown.ArrowDown)=\"changeMinutes(-minuteStep, 'key')\"\n (change)=\"updateMinutes($event.target.value)\">\n </td>\n <!-- divider -->\n <td *ngIf=\"showSeconds\"> : </td>\n <!-- seconds -->\n <td class=\"form-group\" *ngIf=\"showSeconds\" [class.has-error]=\"invalidSeconds\">\n <input type=\"text\" [class.is-invalid]=\"invalidSeconds\"\n class=\"form-control text-center bs-timepicker-field\"\n placeholder=\"SS\"\n maxlength=\"2\"\n [readonly]=\"readonlyInput\"\n [disabled]=\"disabled\"\n [value]=\"seconds\"\n (wheel)=\"prevDef($event);changeSeconds(secondsStep * wheelSign($event), 'wheel')\"\n (keydown.ArrowUp)=\"changeSeconds(secondsStep, 'key')\"\n (keydown.ArrowDown)=\"changeSeconds(-secondsStep, 'key')\"\n (change)=\"updateSeconds($event.target.value)\">\n </td>\n <!-- space between -->\n <td *ngIf=\"showMeridian\"> </td>\n <!-- meridian -->\n <td *ngIf=\"showMeridian\">\n <button type=\"button\" class=\"btn btn-default text-center\"\n [disabled]=\"!isEditable || !canToggleMeridian\"\n [class.disabled]=\"!isEditable || !canToggleMeridian\"\n (click)=\"toggleMeridian()\"\n >{{ meridian }}\n </button>\n </td>\n </tr>\n <tr class=\"text-center\" [hidden]=\"!showSpinners\">\n <!-- decrement hours button-->\n <td>\n <a class=\"btn btn-link\" [class.disabled]=\"!canDecrementHours || !isEditable\"\n (click)=\"changeHours(-hourStep)\">\n <span class=\"bs-chevron bs-chevron-down\"></span>\n </a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showMinutes\"> </td>\n <!-- decrement minutes button-->\n <td *ngIf=\"showMinutes\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canDecrementMinutes || !isEditable\"\n (click)=\"changeMinutes(-minuteStep)\">\n <span class=\"bs-chevron bs-chevron-down\"></span>\n </a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showSeconds\"> </td>\n <!-- decrement seconds button-->\n <td *ngIf=\"showSeconds\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canDecrementSeconds || !isEditable\"\n (click)=\"changeSeconds(-secondsStep)\">\n <span class=\"bs-chevron bs-chevron-down\"></span>\n </a>\n </td>\n <!-- space between -->\n <td *ngIf=\"showMeridian\"> </td>\n <!-- meridian placeholder-->\n <td *ngIf=\"showMeridian\"></td>\n </tr>\n </tbody>\n</table>\n",
encapsulation: ViewEncapsulation.None,
styles: ["\n .bs-chevron {\n border-style: solid;\n display: block;\n width: 9px;\n height: 9px;\n position: relative;\n border-width: 3px 0px 0 3px;\n }\n\n .bs-chevron-up {\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n top: 2px;\n }\n\n .bs-chevron-down {\n -webkit-transform: rotate(-135deg);\n transform: rotate(-135deg);\n top: -2px;\n }\n\n .bs-timepicker-field {\n width: 50px;\n }\n "]
}] }
];
/** @nocollapse */
TimepickerComponent.ctorParameters = function () { return [
{ type: TimepickerConfig, },
{ type: ChangeDetectorRef, },
{ type: TimepickerStore, },
{ type: TimepickerActions, },
]; };
TimepickerComponent.propDecorators = {
"hourStep": [{ type: Input },],
"minuteStep": [{ type: Input },],
"secondsStep": [{ type: Input },],
"readonlyInput": [{ type: Input },],
"disabled": [{ type: Input },],
"mousewheel": [{ type: Input },],
"arrowkeys": [{ type: Input },],
"showSpinners": [{ type: Input },],
"showMeridian": [{ type: Input },],
"showMinutes": [{ type: Input },],
"showSeconds": [{ type: Input },],
"meridians": [{ type: Input },],
"min": [{ type: Input },],
"max": [{ type: Input },],
"isValid": [{ type: Output },],
};
return TimepickerComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var TimepickerModule = /** @class */ (function () {
function TimepickerModule() {
}
/**
* @return {?}
*/
TimepickerModule.forRoot = /**
* @return {?}
*/
function () {
return {
ngModule: TimepickerModule,
providers: [TimepickerConfig, TimepickerActions, TimepickerStore]
};
};
TimepickerModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [TimepickerComponent],
exports: [TimepickerComponent]
},] }
];
return TimepickerModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { TimepickerComponent, TimepickerActions, TimepickerStore, TimepickerConfig, TimepickerModule, TIMEPICKER_CONTROL_VALUE_ACCESSOR as ɵa };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWJvb3RzdHJhcC10aW1lcGlja2VyLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9uZ3gtYm9vdHN0cmFwL3RpbWVwaWNrZXIvcmVkdWNlci90aW1lcGlja2VyLmFjdGlvbnMudHMiLCJuZzovL25neC1ib290c3RyYXAvdGltZXBpY2tlci90aW1lcGlja2VyLnV0aWxzLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3RpbWVwaWNrZXIvdGltZXBpY2tlci1jb250cm9scy51dGlsLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3RpbWVwaWNrZXIvdGltZXBpY2tlci5jb25maWcudHMiLCJuZzovL25neC1ib290c3RyYXAvdGltZXBpY2tlci9yZWR1Y2VyL3RpbWVwaWNrZXIucmVkdWNlci50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC90aW1lcGlja2VyL3JlZHVjZXIvdGltZXBpY2tlci5zdG9yZS50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC90aW1lcGlja2VyL3RpbWVwaWNrZXIuY29tcG9uZW50LnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3RpbWVwaWNrZXIvdGltZXBpY2tlci5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC9taW5pLW5ncngnO1xuaW1wb3J0IHtcbiAgVGltZUNoYW5nZUV2ZW50LFxuICBUaW1lcGlja2VyQ29tcG9uZW50U3RhdGUsXG4gIFRpbWVcbn0gZnJvbSAnLi4vdGltZXBpY2tlci5tb2RlbHMnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVGltZXBpY2tlckFjdGlvbnMge1xuICBzdGF0aWMgcmVhZG9ubHkgV1JJVEVfVkFMVUUgPSAnW3RpbWVwaWNrZXJdIHdyaXRlIHZhbHVlIGZyb20gbmcgbW9kZWwnO1xuICBzdGF0aWMgcmVhZG9ubHkgQ0hBTkdFX0hPVVJTID0gJ1t0aW1lcGlja2VyXSBjaGFuZ2UgaG91cnMnO1xuICBzdGF0aWMgcmVhZG9ubHkgQ0hBTkdFX01JTlVURVMgPSAnW3RpbWVwaWNrZXJdIGNoYW5nZSBtaW51dGVzJztcbiAgc3RhdGljIHJlYWRvbmx5IENIQU5HRV9TRUNPTkRTID0gJ1t0aW1lcGlja2VyXSBjaGFuZ2Ugc2Vjb25kcyc7XG4gIHN0YXRpYyByZWFkb25seSBTRVRfVElNRV9VTklUID0gJ1t0aW1lcGlja2VyXSBzZXQgdGltZSB1bml0JztcbiAgc3RhdGljIHJlYWRvbmx5IFVQREFURV9DT05UUk9MUyA9ICdbdGltZXBpY2tlcl0gdXBkYXRlIGNvbnRyb2xzJztcblxuICB3cml0ZVZhbHVlKHZhbHVlOiBEYXRlIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFRpbWVwaWNrZXJBY3Rpb25zLldSSVRFX1ZBTFVFLFxuICAgICAgcGF5bG9hZDogdmFsdWVcbiAgICB9O1xuICB9XG5cbiAgY2hhbmdlSG91cnMoZXZlbnQ6IFRpbWVDaGFuZ2VFdmVudCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBUaW1lcGlja2VyQWN0aW9ucy5DSEFOR0VfSE9VUlMsXG4gICAgICBwYXlsb2FkOiBldmVudFxuICAgIH07XG4gIH1cblxuICBjaGFuZ2VNaW51dGVzKGV2ZW50OiBUaW1lQ2hhbmdlRXZlbnQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogVGltZXBpY2tlckFjdGlvbnMuQ0hBTkdFX01JTlVURVMsXG4gICAgICBwYXlsb2FkOiBldmVudFxuICAgIH07XG4gIH1cblxuICBjaGFuZ2VTZWNvbmRzKGV2ZW50OiBUaW1lQ2hhbmdlRXZlbnQpOiBBY3Rpb24ge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBUaW1lcGlja2VyQWN0aW9ucy5DSEFOR0VfU0VDT05EUyxcbiAgICAgIHBheWxvYWQ6IGV2ZW50XG4gICAgfTtcbiAgfVxuXG4gIHNldFRpbWUodmFsdWU6IFRpbWUpOiBBY3Rpb24ge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBUaW1lcGlja2VyQWN0aW9ucy5TRVRfVElNRV9VTklULFxuICAgICAgcGF5bG9hZDogdmFsdWVcbiAgICB9O1xuICB9XG5cbiAgdXBkYXRlQ29udHJvbHModmFsdWU6IFRpbWVwaWNrZXJDb21wb25lbnRTdGF0ZSk6IEFjdGlvbiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFRpbWVwaWNrZXJBY3Rpb25zLlVQREFURV9DT05UUk9MUyxcbiAgICAgIHBheWxvYWQ6IHZhbHVlXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVGltZSwgVGltZXBpY2tlckNvbXBvbmVudFN0YXRlIH0gZnJvbSAnLi90aW1lcGlja2VyLm1vZGVscyc7XG5cbmNvbnN0IGRleCA9IDEwO1xuY29uc3QgaG91cnNQZXJEYXkgPSAyNDtcbmNvbnN0IGhvdXJzUGVyRGF5SGFsZiA9IDEyO1xuY29uc3QgbWludXRlc1BlckhvdXIgPSA2MDtcbmNvbnN0IHNlY29uZHNQZXJNaW51dGUgPSA2MDtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWREYXRlKHZhbHVlPzogc3RyaW5nIHwgRGF0ZSk6IGJvb2xlYW4ge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiBpc05hTih2YWx1ZS5nZXRIb3VycygpKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGlzVmFsaWREYXRlKG5ldyBEYXRlKHZhbHVlKSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRMaW1pdChjb250cm9sczogVGltZXBpY2tlckNvbXBvbmVudFN0YXRlLCBuZXdEYXRlOiBEYXRlKTogYm9vbGVhbiB7XG4gIGlmIChjb250cm9scy5taW4gJiYgbmV3RGF0ZSA8IGNvbnRyb2xzLm1pbikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChjb250cm9scy5tYXggJiYgbmV3RGF0ZSA+IGNvbnRyb2xzLm1heCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9OdW1iZXIodmFsdWU6IHN0cmluZyB8IG51bWJlcik6IG51bWJlciB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCBkZXgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWU6IHN0cmluZyB8IG51bWJlcik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiAhaXNOYU4odG9OdW1iZXIodmFsdWUpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSG91cnMoXG4gIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIsXG4gIGlzUE0gPSBmYWxzZVxuKTogbnVtYmVyIHtcbiAgY29uc3QgaG91ciA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgaWYgKFxuICAgIGlzTmFOKGhvdXIpIHx8XG4gICAgaG91ciA8IDAgfHxcbiAgICBob3VyID4gKGlzUE0gPyBob3Vyc1BlckRheUhhbGYgOiBob3Vyc1BlckRheSlcbiAgKSB7XG4gICAgcmV0dXJuIE5hTjtcbiAgfVxuXG4gIHJldHVybiBob3VyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VNaW51dGVzKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBtaW51dGUgPSB0b051bWJlcih2YWx1ZSk7XG4gIGlmIChpc05hTihtaW51dGUpIHx8IG1pbnV0ZSA8IDAgfHwgbWludXRlID4gbWludXRlc1BlckhvdXIpIHtcbiAgICByZXR1cm4gTmFOO1xuICB9XG5cbiAgcmV0dXJuIG1pbnV0ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU2Vjb25kcyh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3Qgc2Vjb25kcyA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgaWYgKGlzTmFOKHNlY29uZHMpIHx8IHNlY29uZHMgPCAwIHx8IHNlY29uZHMgPiBzZWNvbmRzUGVyTWludXRlKSB7XG4gICAgcmV0dXJuIE5hTjtcbiAgfVxuXG4gIHJldHVybiBzZWNvbmRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUaW1lKHZhbHVlOiBzdHJpbmcgfCBEYXRlKTogRGF0ZSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoYW5nZVRpbWUodmFsdWU6IERhdGUsIGRpZmY6IFRpbWUpOiBEYXRlIHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiBjaGFuZ2VUaW1lKGNyZWF0ZURhdGUobmV3IERhdGUoKSwgMCwgMCwgMCksIGRpZmYpO1xuICB9XG5cbiAgbGV0IGhvdXIgPSB2YWx1ZS5nZXRIb3VycygpO1xuICBsZXQgbWludXRlcyA9IHZhbHVlLmdldE1pbnV0ZXMoKTtcbiAgbGV0IHNlY29uZHMgPSB2YWx1ZS5nZXRTZWNvbmRzKCk7XG5cbiAgaWYgKGRpZmYuaG91cikge1xuICAgIGhvdXIgPSAoaG91ciArIHRvTnVtYmVyKGRpZmYuaG91cikpICUgaG91cnNQZXJEYXk7XG4gICAgaWYgKGhvdXIgPCAwKSB7XG4gICAgICBob3VyICs9IGhvdXJzUGVyRGF5O1xuICAgIH1cbiAgfVxuXG4gIGlmIChkaWZmLm1pbnV0ZSkge1xuICAgIG1pbnV0ZXMgPSBtaW51dGVzICsgdG9OdW1iZXIoZGlmZi5taW51dGUpO1xuICB9XG5cbiAgaWYgKGRpZmYuc2Vjb25kcykge1xuICAgIHNlY29uZHMgPSBzZWNvbmRzICsgdG9OdW1iZXIoZGlmZi5zZWNvbmRzKTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVEYXRlKHZhbHVlLCBob3VyLCBtaW51dGVzLCBzZWNvbmRzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFRpbWUodmFsdWU6IERhdGUsIG9wdHM6IFRpbWUpOiBEYXRlIHtcbiAgbGV0IGhvdXIgPSBwYXJzZUhvdXJzKG9wdHMuaG91cik7XG4gIGNvbnN0IG1pbnV0ZSA9IHBhcnNlTWludXRlcyhvcHRzLm1pbnV0ZSk7XG4gIGNvbnN0IHNlY29uZHMgPSBwYXJzZVNlY29uZHMob3B0cy5zZWNvbmRzKSB8fCAwO1xuXG4gIGlmIChvcHRzLmlzUE0pIHtcbiAgICBob3VyICs9IGhvdXJzUGVyRGF5SGFsZjtcbiAgfVxuXG4gIGlmICghdmFsdWUpIHtcbiAgICBpZiAoIWlzTmFOKGhvdXIpICYmICFpc05hTihtaW51dGUpKSB7XG4gICAgICByZXR1cm4gY3JlYXRlRGF0ZShuZXcgRGF0ZSgpLCBob3VyLCBtaW51dGUsIHNlY29uZHMpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGlmIChpc05hTihob3VyKSB8fCBpc05hTihtaW51dGUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZURhdGUodmFsdWUsIGhvdXIsIG1pbnV0ZSwgc2Vjb25kcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEYXRlKFxuICB2YWx1ZTogRGF0ZSxcbiAgaG91cnM6IG51bWJlcixcbiAgbWludXRlczogbnVtYmVyLFxuICBzZWNvbmRzOiBudW1iZXJcbik6IERhdGUge1xuICByZXR1cm4gbmV3IERhdGUoXG4gICAgdmFsdWUuZ2V0RnVsbFllYXIoKSxcbiAgICB2YWx1ZS5nZXRNb250aCgpLFxuICAgIHZhbHVlLmdldERhdGUoKSxcbiAgICBob3VycyxcbiAgICBtaW51dGVzLFxuICAgIHNlY29uZHMsXG4gICAgdmFsdWUuZ2V0TWlsbGlzZWNvbmRzKClcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhZE51bWJlcih2YWx1ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgX3ZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgaWYgKF92YWx1ZS5sZW5ndGggPiAxKSB7XG4gICAgcmV0dXJuIF92YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBgMCR7X3ZhbHVlfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0hvdXJJbnB1dFZhbGlkKGhvdXJzOiBzdHJpbmcsIGlzUE06IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgcmV0dXJuICFpc05hTihwYXJzZUhvdXJzKGhvdXJzLCBpc1BNKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01pbnV0ZUlucHV0VmFsaWQobWludXRlczogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAhaXNOYU4ocGFyc2VNaW51dGVzKG1pbnV0ZXMpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2Vjb25kSW5wdXRWYWxpZChzZWNvbmRzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuICFpc05hTihwYXJzZVNlY29uZHMoc2Vjb25kcykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNJbnB1dExpbWl0VmFsaWQoZGlmZjogVGltZSwgbWF4OiBEYXRlLCBtaW46IERhdGUpOiBib29sZWFuIHtcbiAgY29uc3QgbmV3RGF0ZSA9IGNoYW5nZVRpbWUobmV3IERhdGUoKSwgZGlmZik7XG5cbiAgaWYgKG1heCAmJiBuZXdEYXRlID4gbWF4KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKG1pbiAmJiBuZXdEYXRlIDwgbWluKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0lucHV0VmFsaWQoXG4gIGhvdXJzOiBzdHJpbmcsXG4gIG1pbnV0ZXMgPSAnMCcsXG4gIHNlY29uZHMgPSAnMCcsXG4gIGlzUE06IGJvb2xlYW5cbik6IGJvb2xlYW4ge1xuICByZXR1cm4gaXNIb3VySW5wdXRWYWxpZChob3VycywgaXNQTSlcbiAgICAmJiBpc01pbnV0ZUlucHV0VmFsaWQobWludXRlcylcbiAgICAmJiBpc1NlY29uZElucHV0VmFsaWQoc2Vjb25kcyk7XG59XG4iLCJpbXBvcnQgeyBjaGFuZ2VUaW1lIH0gZnJvbSAnLi90aW1lcGlja2VyLnV0aWxzJztcbmltcG9ydCB7XG4gIFRpbWVDaGFuZ2VFdmVudCxcbiAgVGltZXBpY2tlckNvbXBvbmVudFN0YXRlLFxuICBUaW1lcGlja2VyQ29udHJvbHNcbn0gZnJvbSAnLi90aW1lcGlja2VyLm1vZGVscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjYW5DaGFuZ2VWYWx1ZShcbiAgc3RhdGU6IFRpbWVwaWNrZXJDb21wb25lbnRTdGF0ZSxcbiAgZXZlbnQ/OiBUaW1lQ2hhbmdlRXZlbnRcbik6IGJvb2xlYW4ge1xuICBpZiAoc3RhdGUucmVhZG9ubHlJbnB1dCB8fCBzdGF0ZS5kaXNhYmxlZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChldmVudCkge1xuICAgIGlmIChldmVudC5zb3VyY2UgPT09ICd3aGVlbCcgJiYgIXN0YXRlLm1vdXNld2hlZWwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQuc291cmNlID09PSAna2V5JyAmJiAhc3RhdGUuYXJyb3drZXlzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYW5DaGFuZ2VIb3VycyhcbiAgZXZlbnQ6IFRpbWVDaGFuZ2VFdmVudCxcbiAgY29udHJvbHM6IFRpbWVwaWNrZXJDb250cm9sc1xuKTogYm9vbGVhbiB7XG4gIGlmICghZXZlbnQuc3RlcCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChldmVudC5zdGVwID4gMCAmJiAhY29udHJvbHMuY2FuSW5jcmVtZW50SG91cnMpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoZXZlbnQuc3RlcCA8IDAgJiYgIWNvbnRyb2xzLmNhbkRlY3JlbWVudEhvdXJzKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYW5DaGFuZ2VNaW51dGVzKFxuICBldmVudDogVGltZUNoYW5nZUV2ZW50LFxuICBjb250cm9sczogVGltZXBpY2tlckNvbnRyb2xzXG4pOiBib29sZWFuIHtcbiAgaWYgKCFldmVudC5zdGVwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChldmVudC5zdGVwID4gMCAmJiAhY29udHJvbHMuY2FuSW5jcmVtZW50TWludXRlcykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZXZlbnQuc3RlcCA8IDAgJiYgIWNvbnRyb2xzLmNhbkRlY3JlbWVudE1pbnV0ZXMpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbkNoYW5nZVNlY29uZHMoXG4gIGV2ZW50OiBUaW1lQ2hhbmdlRXZlbnQsXG4gIGNvbnRyb2xzOiBUaW1lcGlja2VyQ29udHJvbHNcbik6IGJvb2xlYW4ge1xuICBpZiAoIWV2ZW50LnN0ZXApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGV2ZW50LnN0ZXAgPiAwICYmICFjb250cm9scy5jYW5JbmNyZW1lbnRTZWNvbmRzKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChldmVudC5zdGVwIDwgMCAmJiAhY29udHJvbHMuY2FuRGVjcmVtZW50U2Vjb25kcykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29udHJvbHNWYWx1ZShcbiAgc3RhdGU6IFRpbWVwaWNrZXJDb21wb25lbnRTdGF0ZVxuKTogVGltZXBpY2tlckNvbXBvbmVudFN0YXRlIHtcbiAgY29uc3Qge1xuICAgIGhvdXJTdGVwLFxuICAgIG1pbnV0ZVN0ZXAsXG4gICAgc2Vjb25kc1N0ZXAsXG4gICAgcmVhZG9ubHlJbnB1dCxcbiAgICBkaXNhYmxlZCxcbiAgICBtb3VzZXdoZWVsLFxuICAgIGFycm93a2V5cyxcbiAgICBzaG93U3Bpbm5lcnMsXG4gICAgc2hvd01lcmlkaWFuLFxuICAgIHNob3dTZWNvbmRzLFxuICAgIG1lcmlkaWFucyxcbiAgICBtaW4sXG4gICAgbWF4XG4gIH0gPSBzdGF0ZTtcblxuICByZXR1cm4ge1xuICAgIGhvdXJTdGVwLFxuICAgIG1pbnV0ZVN0ZXAsXG4gICAgc2Vjb25kc1N0ZXAsXG4gICAgcmVhZG9ubHlJbnB1dCxcbiAgICBkaXNhYmxlZCxcbiAgICBtb3VzZXdoZWVsLFxuICAgIGFycm93a2V5cyxcbiAgICBzaG93U3Bpbm5lcnMsXG4gICAgc2hvd01lcmlkaWFuLFxuICAgIHNob3dTZWNvbmRzLFxuICAgIG1lcmlkaWFucyxcbiAgICBtaW4sXG4gICAgbWF4XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0aW1lcGlja2VyQ29udHJvbHMoXG4gIHZhbHVlOiBEYXRlLFxuICBzdGF0ZTogVGltZXBpY2tlckNvbXBvbmVudFN0YXRlXG4pOiBUaW1lcGlja2VyQ29udHJvbHMge1xuICBjb25zdCBob3Vyc1BlckRheUhhbGYgPSAxMjtcbiAgY29uc3QgeyBtaW4sIG1heCwgaG91clN0ZXAsIG1pbnV0ZVN0ZXAsIHNlY29uZHNTdGVwLCBzaG93U2Vjb25kcyB9ID0gc3RhdGU7XG