@taiga-ui/kit
Version:
Taiga UI Angular main components kit
174 lines • 30.5 kB
JavaScript
import { computed, Directive, effect, inject, Input, signal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { MaskitoDirective } from '@maskito/angular';
import { maskitoDateTimeOptionsGenerator, maskitoSelectionChangeHandler, } from '@maskito/kit';
import { tuiAsControl, tuiValueTransformerFrom } from '@taiga-ui/cdk/classes';
import { DATE_FILLER_LENGTH, MILLISECONDS_IN_DAY, TuiDay, TuiTime, } from '@taiga-ui/cdk/date-time';
import { tuiClamp, tuiSum } from '@taiga-ui/cdk/utils/math';
import { tuiDirectiveBinding } from '@taiga-ui/cdk/utils/miscellaneous';
import { tuiAsOptionContent } from '@taiga-ui/core/components/data-list';
import { tuiAsTextfieldAccessor, TuiWithTextfield, } from '@taiga-ui/core/components/textfield';
import { TuiDropdownAuto } from '@taiga-ui/core/directives/dropdown';
import { TuiItemsHandlersValidator } from '@taiga-ui/core/directives/items-handlers';
import { TUI_DATE_ADAPTER, TuiInputDateBase, tuiWithDateFiller, } from '@taiga-ui/kit/components/input-date';
import { TuiSelectOption } from '@taiga-ui/kit/components/select';
import { TUI_TIME_TEXTS } from '@taiga-ui/kit/tokens';
import { tuiMaskito } from '@taiga-ui/kit/utils';
import { noop } from 'rxjs';
import { TUI_INPUT_DATE_TIME_OPTIONS } from './input-date-time.options';
import * as i0 from "@angular/core";
import * as i1 from "@maskito/angular";
import * as i2 from "@taiga-ui/core/directives/dropdown";
import * as i3 from "@taiga-ui/core/directives/items-handlers";
import * as i4 from "@taiga-ui/core/components/textfield";
const MIN_TIME = new TuiTime(0, 0);
const MAX_TIME = TuiTime.fromAbsoluteMilliseconds(MILLISECONDS_IN_DAY - 1);
class TuiInputDateTimeDirective extends TuiInputDateBase {
constructor() {
super(...arguments);
this.timeFillers = toSignal(inject(TUI_TIME_TEXTS));
this.options = inject(TUI_INPUT_DATE_TIME_OPTIONS);
this.filler = tuiWithDateFiller((date) => {
const time = this.timeFillers()?.[this.timeMode()] ?? '';
return `${date}${this.options.dateTimeSeparator}${time}`;
});
this.valueEffect = effect(noop);
this.identity = this.handlers.identityMatcher.set((a, b) => tuiSum(...a.map(Number)) === tuiSum(...b.map(Number)));
this.disabledItemHandler = tuiDirectiveBinding(TuiItemsHandlersValidator, 'disabledItemHandler', (value) => Boolean(value && this.handlers.disabledItemHandler()(value)));
this.mask = tuiMaskito(computed(() => this.computeMask({
dateMode: TUI_DATE_ADAPTER[this.format().mode],
timeMode: this.timeMode(),
min: this.toNativeDate([this.min(), this.minTime()]),
max: this.toNativeDate([this.max(), this.maxTime()]),
dateSeparator: this.format().separator,
dateTimeSeparator: this.options.dateTimeSeparator,
})));
this.timeMode = signal(this.options.timeMode);
this.minTime = signal(MIN_TIME);
this.maxTime = signal(MAX_TIME);
}
// TODO(v5): use signal inputs
set timeModeSetter(x) {
this.timeMode.set(x);
}
set minSetter(min) {
const [date, time] = Array.isArray(min) ? min : [min, null];
this.min.set(date || this.options.min);
this.minTime.set(time ?? MIN_TIME);
}
set maxSetter(max) {
const [date, time] = Array.isArray(max) ? max : [max, null];
this.max.set(date || this.options.max);
this.maxTime.set(time ?? MAX_TIME);
}
setValue(value) {
this.onChange(value);
this.textfield.value.set(this.stringify(value));
}
setDate(newDate) {
const [date, time] = this.clampTime([newDate, this.value()?.[1] ?? null]);
this.setValue([date, time]);
this.open.set(false);
setTimeout((caretIndex = DATE_FILLER_LENGTH + this.options.dateTimeSeparator.length) => this.el.setSelectionRange(caretIndex, caretIndex));
}
writeValue(value) {
super.writeValue(value);
this.textfield.value.set(this.stringify(this.value()));
}
processCalendar(calendar) {
super.processCalendar(calendar);
calendar.disabledItemHandler = (day) => this.handlers.disabledItemHandler()([day, null]);
}
onValueChange(value) {
this.textfield.value.set(value);
this.control?.control?.updateValueAndValidity({ emitEvent: false });
const [date = '', time = ''] = value.split(this.options.dateTimeSeparator);
const parsedDate = date.length >= DATE_FILLER_LENGTH
? TuiDay.normalizeParse(date, this.format().mode)
: null;
const parsedTime = time.length === this.timeMode().length ? TuiTime.fromString(time) : null;
if (!parsedDate || (time && !parsedTime)) {
return this.onChange(null);
}
const [prevDate, prevTime = null] = this.value() ?? [];
if (!prevDate?.daySame(parsedDate) || Number(parsedTime) !== Number(prevTime)) {
this.onChange([parsedDate, parsedTime]);
}
}
stringify(value) {
const [date, time] = value ?? [];
const dateString = date?.toString(this.format().mode, this.format().separator) ?? '';
const timeString = time?.toString(this.timeMode());
return timeString
? `${dateString}${this.options.dateTimeSeparator}${timeString}`
: dateString;
}
clampTime([date, time]) {
const min = date.daySame(this.min())
? this.minTime().toAbsoluteMilliseconds()
: -Infinity;
const max = date.daySame(this.max())
? this.maxTime().toAbsoluteMilliseconds()
: Infinity;
return [
date,
time &&
TuiTime.fromAbsoluteMilliseconds(tuiClamp(time.toAbsoluteMilliseconds(), min, max)),
];
}
computeMask(params) {
const options = maskitoDateTimeOptionsGenerator(params);
const { timeMode, dateMode, dateTimeSeparator } = params;
const inputModeSwitchPlugin = maskitoSelectionChangeHandler((element) => {
element.inputMode =
element.selectionStart >=
dateMode.length + dateTimeSeparator.length + timeMode.indexOf(' AA')
? 'text'
: 'numeric';
});
return {
...options,
plugins: options.plugins.concat(timeMode.includes('AA') ? inputModeSwitchPlugin : []),
};
}
toNativeDate([{ year, month, day }, { hours, minutes, seconds, ms }]) {
return new Date(year, month, day, hours, minutes, seconds, ms);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiInputDateTimeDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: TuiInputDateTimeDirective, isStandalone: true, selector: "input[tuiInputDateTime]", inputs: { timeModeSetter: ["timeMode", "timeModeSetter"], minSetter: ["min", "minSetter"], maxSetter: ["max", "maxSetter"] }, providers: [
tuiAsOptionContent(TuiSelectOption),
tuiAsControl(TuiInputDateTimeDirective),
tuiAsTextfieldAccessor(TuiInputDateTimeDirective),
tuiValueTransformerFrom(TUI_INPUT_DATE_TIME_OPTIONS),
], usesInheritance: true, hostDirectives: [{ directive: i1.MaskitoDirective }, { directive: i2.TuiDropdownAuto }, { directive: i3.TuiItemsHandlersValidator }, { directive: i4.TuiWithTextfield }], ngImport: i0 }); }
}
export { TuiInputDateTimeDirective };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TuiInputDateTimeDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: 'input[tuiInputDateTime]',
providers: [
tuiAsOptionContent(TuiSelectOption),
tuiAsControl(TuiInputDateTimeDirective),
tuiAsTextfieldAccessor(TuiInputDateTimeDirective),
tuiValueTransformerFrom(TUI_INPUT_DATE_TIME_OPTIONS),
],
hostDirectives: [
MaskitoDirective,
TuiDropdownAuto,
TuiItemsHandlersValidator,
TuiWithTextfield,
],
}]
}], propDecorators: { timeModeSetter: [{
type: Input,
args: ['timeMode']
}], minSetter: [{
type: Input,
args: ['min']
}], maxSetter: [{
type: Input,
args: ['max']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGF0ZS10aW1lLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tpdC9jb21wb25lbnRzL2lucHV0LWRhdGUtdGltZS9pbnB1dC1kYXRlLXRpbWUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFHbEQsT0FBTyxFQUNILCtCQUErQixFQUMvQiw2QkFBNkIsR0FDaEMsTUFBTSxjQUFjLENBQUM7QUFDdEIsT0FBTyxFQUFDLFlBQVksRUFBRSx1QkFBdUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQzVFLE9BQU8sRUFDSCxrQkFBa0IsRUFDbEIsbUJBQW1CLEVBQ25CLE1BQU0sRUFDTixPQUFPLEdBQ1YsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUMsUUFBUSxFQUFFLE1BQU0sRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLG1DQUFtQyxDQUFDO0FBRXRFLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBRXZFLE9BQU8sRUFDSCxzQkFBc0IsRUFDdEIsZ0JBQWdCLEdBQ25CLE1BQU0scUNBQXFDLENBQUM7QUFDN0MsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQ25FLE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBQ25GLE9BQU8sRUFDSCxnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLGlCQUFpQixHQUNw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bUJBQUM7b0JBQ1AsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLFFBQVEsRUFBRSx5QkFBeUI7b0JBQ25DLFNBQVMsRUFBRTt3QkFDUCxrQkFBa0IsQ0FBQyxlQUFlLENBQUM7d0JBQ25DLFlBQVksMkJBQTJCO3dCQUN2QyxzQkFBc0IsMkJBQTJCO3dCQUNqRCx1QkFBdUIsQ0FBQywyQkFBMkIsQ0FBQztxQkFDdkQ7b0JBQ0QsY0FBYyxFQUFFO3dCQUNaLGdCQUFnQjt3QkFDaEIsZUFBZTt3QkFDZix5QkFBeUI7d0JBQ3pCLGdCQUFnQjtxQkFDbkI7aUJBQ0o7OEJBK0NjLGNBQWM7c0JBRHhCLEtBQUs7dUJBQUMsVUFBVTtnQkFNRyxTQUFTO3NCQUQ1QixLQUFLO3VCQUFDLEtBQUs7Z0JBV1EsU0FBUztzQkFENUIsS0FBSzt1QkFBQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjb21wdXRlZCwgRGlyZWN0aXZlLCBlZmZlY3QsIGluamVjdCwgSW5wdXQsIHNpZ25hbH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge3RvU2lnbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge01hc2tpdG9EaXJlY3RpdmV9IGZyb20gJ0BtYXNraXRvL2FuZ3VsYXInO1xuaW1wb3J0IHR5cGUge01hc2tpdG9PcHRpb25zfSBmcm9tICdAbWFza2l0by9jb3JlJztcbmltcG9ydCB0eXBlIHtNYXNraXRvRGF0ZVRpbWVQYXJhbXMsIE1hc2tpdG9UaW1lTW9kZX0gZnJvbSAnQG1hc2tpdG8va2l0JztcbmltcG9ydCB7XG4gICAgbWFza2l0b0RhdGVUaW1lT3B0aW9uc0dlbmVyYXRvcixcbiAgICBtYXNraXRvU2VsZWN0aW9uQ2hhbmdlSGFuZGxlcixcbn0gZnJvbSAnQG1hc2tpdG8va2l0JztcbmltcG9ydCB7dHVpQXNDb250cm9sLCB0dWlWYWx1ZVRyYW5zZm9ybWVyRnJvbX0gZnJvbSAnQHRhaWdhLXVpL2Nkay9jbGFzc2VzJztcbmltcG9ydCB7XG4gICAgREFURV9GSUxMRVJfTEVOR1RILFxuICAgIE1JTExJU0VDT05EU19JTl9EQVksXG4gICAgVHVpRGF5LFxuICAgIFR1aVRpbWUsXG59IGZyb20gJ0B0YWlnYS11aS9jZGsvZGF0ZS10aW1lJztcbmltcG9ydCB7dHVpQ2xhbXAsIHR1aVN1bX0gZnJvbSAnQHRhaWdhLXVpL2Nkay91dGlscy9tYXRoJztcbmltcG9ydCB7dHVpRGlyZWN0aXZlQmluZGluZ30gZnJvbSAnQHRhaWdhLXVpL2Nkay91dGlscy9taXNjZWxsYW5lb3VzJztcbmltcG9ydCB0eXBlIHtUdWlDYWxlbmRhcn0gZnJvbSAnQHRhaWdhLXVpL2NvcmUvY29tcG9uZW50cy9jYWxlbmRhcic7XG5pbXBvcnQge3R1aUFzT3B0aW9uQ29udGVudH0gZnJvbSAnQHRhaWdhLXVpL2NvcmUvY29tcG9uZW50cy9kYXRhLWxpc3QnO1xuaW1wb3J0IHR5cGUge1R1aVRleHRmaWVsZEFjY2Vzc29yfSBmcm9tICdAdGFpZ2EtdWkvY29yZS9jb21wb25lbnRzL3RleHRmaWVsZCc7XG5pbXBvcnQge1xuICAgIHR1aUFzVGV4dGZpZWxkQWNjZXNzb3IsXG4gICAgVHVpV2l0aFRleHRmaWVsZCxcbn0gZnJvbSAnQHRhaWdhLXVpL2NvcmUvY29tcG9uZW50cy90ZXh0ZmllbGQnO1xuaW1wb3J0IHtUdWlEcm9wZG93bkF1dG99IGZyb20gJ0B0YWlnYS11aS9jb3JlL2RpcmVjdGl2ZXMvZHJvcGRvd24nO1xuaW1wb3J0IHtUdWlJdGVtc0hhbmRsZXJzVmFsaWRhdG9yfSBmcm9tICdAdGFpZ2EtdWkvY29yZS9kaXJlY3RpdmVzL2l0ZW1zLWhhbmRsZXJzJztcbmltcG9ydCB7XG4gICAgVFVJX0RBVEVfQURBUFRFUixcbiAgICBUdWlJbnB1dERhdGVCYXNlLFxuICAgIHR1aVdpdGhEYXRlRmlsbGVyLFxufSBmcm9tICdAdGFpZ2EtdWkva2l0L2NvbXBvbmVudHMvaW5wdXQtZGF0ZSc7XG5pbXBvcnQge1R1aVNlbGVjdE9wdGlvbn0gZnJvbSAnQHRhaWdhLXVpL2tpdC9jb21wb25lbnRzL3NlbGVjdCc7XG5pbXBvcnQge1RVSV9USU1FX1RFWFRTfSBmcm9tICdAdGFpZ2EtdWkva2l0L3Rva2Vucyc7XG5pbXBvcnQge3R1aU1hc2tpdG99IGZyb20gJ0B0YWlnYS11aS9raXQvdXRpbHMnO1xuaW1wb3J0IHtub29wfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtUVUlfSU5QVVRfREFURV9USU1FX09QVElPTlN9IGZyb20gJy4vaW5wdXQtZGF0ZS10aW1lLm9wdGlvbnMnO1xuXG5jb25zdCBNSU5fVElNRSA9IG5ldyBUdWlUaW1lKDAsIDApO1xuY29uc3QgTUFYX1RJTUUgPSBUdWlUaW1lLmZyb21BYnNvbHV0ZU1pbGxpc2Vjb25kcyhNSUxMSVNFQ09ORFNfSU5fREFZIC0gMSk7XG5cbkBEaXJlY3RpdmUoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdpbnB1dFt0dWlJbnB1dERhdGVUaW1lXScsXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHR1aUFzT3B0aW9uQ29udGVudChUdWlTZWxlY3RPcHRpb24pLFxuICAgICAgICB0dWlBc0NvbnRyb2woVHVpSW5wdXREYXRlVGltZURpcmVjdGl2ZSksXG4gICAgICAgIHR1aUFzVGV4dGZpZWxkQWNjZXNzb3IoVHVpSW5wdXREYXRlVGltZURpcmVjdGl2ZSksXG4gICAgICAgIHR1aVZhbHVlVHJhbnNmb3JtZXJGcm9tKFRVSV9JTlBVVF9EQVRFX1RJTUVfT1BUSU9OUyksXG4gICAgXSxcbiAgICBob3N0RGlyZWN0aXZlczogW1xuICAgICAgICBNYXNraXRvRGlyZWN0aXZlLFxuICAgICAgICBUdWlEcm9wZG93bkF1dG8sXG4gICAgICAgIFR1aUl0ZW1zSGFuZGxlcnNWYWxpZGF0b3IsXG4gICAgICAgIFR1aVdpdGhUZXh0ZmllbGQsXG4gICAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVHVpSW5wdXREYXRlVGltZURpcmVjdGl2ZVxuICAgIGV4dGVuZHMgVHVpSW5wdXREYXRlQmFzZTxyZWFkb25seSBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0+XG4gICAgaW1wbGVtZW50cyBUdWlUZXh0ZmllbGRBY2Nlc3NvcjxyZWFkb25seSBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0+XG57XG4gICAgcHJpdmF0ZSByZWFkb25seSB0aW1lRmlsbGVycyA9IHRvU2lnbmFsKGluamVjdChUVUlfVElNRV9URVhUUykpO1xuXG4gICAgcHJvdGVjdGVkIG92ZXJyaWRlIHJlYWRvbmx5IG9wdGlvbnMgPSBpbmplY3QoVFVJX0lOUFVUX0RBVEVfVElNRV9PUFRJT05TKTtcblxuICAgIHByb3RlY3RlZCBvdmVycmlkZSByZWFkb25seSBmaWxsZXIgPSB0dWlXaXRoRGF0ZUZpbGxlcigoZGF0ZSkgPT4ge1xuICAgICAgICBjb25zdCB0aW1lID0gdGhpcy50aW1lRmlsbGVycygpPy5bdGhpcy50aW1lTW9kZSgpXSA/PyAnJztcblxuICAgICAgICByZXR1cm4gYCR7ZGF0ZX0ke3RoaXMub3B0aW9ucy5kYXRlVGltZVNlcGFyYXRvcn0ke3RpbWV9YDtcbiAgICB9KTtcblxuICAgIHByb3RlY3RlZCBvdmVycmlkZSB2YWx1ZUVmZmVjdCA9IGVmZmVjdChub29wKTtcblxuICAgIHByb3RlY3RlZCByZWFkb25seSBpZGVudGl0eSA9IHRoaXMuaGFuZGxlcnMuaWRlbnRpdHlNYXRjaGVyLnNldChcbiAgICAgICAgKGEsIGIpID0+IHR1aVN1bSguLi5hLm1hcChOdW1iZXIpKSA9PT0gdHVpU3VtKC4uLmIubWFwKE51bWJlcikpLFxuICAgICk7XG5cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGlzYWJsZWRJdGVtSGFuZGxlciA9IHR1aURpcmVjdGl2ZUJpbmRpbmcoXG4gICAgICAgIFR1aUl0ZW1zSGFuZGxlcnNWYWxpZGF0b3IsXG4gICAgICAgICdkaXNhYmxlZEl0ZW1IYW5kbGVyJyxcbiAgICAgICAgKHZhbHVlOiByZWFkb25seSBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0gfCBudWxsKSA9PlxuICAgICAgICAgICAgQm9vbGVhbih2YWx1ZSAmJiB0aGlzLmhhbmRsZXJzLmRpc2FibGVkSXRlbUhhbmRsZXIoKSh2YWx1ZSkpLFxuICAgICk7XG5cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgbWFzayA9IHR1aU1hc2tpdG8oXG4gICAgICAgIGNvbXB1dGVkKCgpID0+XG4gICAgICAgICAgICB0aGlzLmNvbXB1dGVNYXNrKHtcbiAgICAgICAgICAgICAgICBkYXRlTW9kZTogVFVJX0RBVEVfQURBUFRFUlt0aGlzLmZvcm1hdCgpLm1vZGVdLFxuICAgICAgICAgICAgICAgIHRpbWVNb2RlOiB0aGlzLnRpbWVNb2RlKCksXG4gICAgICAgICAgICAgICAgbWluOiB0aGlzLnRvTmF0aXZlRGF0ZShbdGhpcy5taW4oKSwgdGhpcy5taW5UaW1lKCldKSxcbiAgICAgICAgICAgICAgICBtYXg6IHRoaXMudG9OYXRpdmVEYXRlKFt0aGlzLm1heCgpLCB0aGlzLm1heFRpbWUoKV0pLFxuICAgICAgICAgICAgICAgIGRhdGVTZXBhcmF0b3I6IHRoaXMuZm9ybWF0KCkuc2VwYXJhdG9yLFxuICAgICAgICAgICAgICAgIGRhdGVUaW1lU2VwYXJhdG9yOiB0aGlzLm9wdGlvbnMuZGF0ZVRpbWVTZXBhcmF0b3IsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICApO1xuXG4gICAgcHVibGljIHJlYWRvbmx5IHRpbWVNb2RlID0gc2lnbmFsKHRoaXMub3B0aW9ucy50aW1lTW9kZSk7XG4gICAgcHVibGljIHJlYWRvbmx5IG1pblRpbWUgPSBzaWduYWwoTUlOX1RJTUUpO1xuICAgIHB1YmxpYyByZWFkb25seSBtYXhUaW1lID0gc2lnbmFsKE1BWF9USU1FKTtcblxuICAgIC8vIFRPRE8odjUpOiB1c2Ugc2lnbmFsIGlucHV0c1xuICAgIEBJbnB1dCgndGltZU1vZGUnKVxuICAgIHB1YmxpYyBzZXQgdGltZU1vZGVTZXR0ZXIoeDogTWFza2l0b1RpbWVNb2RlKSB7XG4gICAgICAgIHRoaXMudGltZU1vZGUuc2V0KHgpO1xuICAgIH1cblxuICAgIEBJbnB1dCgnbWluJylcbiAgICBwdWJsaWMgb3ZlcnJpZGUgc2V0IG1pblNldHRlcihcbiAgICAgICAgbWluOiBUdWlEYXkgfCByZWFkb25seSBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0gfCBudWxsLFxuICAgICkge1xuICAgICAgICBjb25zdCBbZGF0ZSwgdGltZV0gPSBBcnJheS5pc0FycmF5KG1pbikgPyBtaW4gOiBbbWluLCBudWxsXTtcblxuICAgICAgICB0aGlzLm1pbi5zZXQoZGF0ZSB8fCB0aGlzLm9wdGlvbnMubWluKTtcbiAgICAgICAgdGhpcy5taW5UaW1lLnNldCh0aW1lID8/IE1JTl9USU1FKTtcbiAgICB9XG5cbiAgICBASW5wdXQoJ21heCcpXG4gICAgcHVibGljIG92ZXJyaWRlIHNldCBtYXhTZXR0ZXIoXG4gICAgICAgIG1heDogVHVpRGF5IHwgcmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdIHwgbnVsbCxcbiAgICApIHtcbiAgICAgICAgY29uc3QgW2RhdGUsIHRpbWVdID0gQXJyYXkuaXNBcnJheShtYXgpID8gbWF4IDogW21heCwgbnVsbF07XG5cbiAgICAgICAgdGhpcy5tYXguc2V0KGRhdGUgfHwgdGhpcy5vcHRpb25zLm1heCk7XG4gICAgICAgIHRoaXMubWF4VGltZS5zZXQodGltZSA/PyBNQVhfVElNRSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFZhbHVlKHZhbHVlOiByZWFkb25seSBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0gfCBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuICAgICAgICB0aGlzLnRleHRmaWVsZC52YWx1ZS5zZXQodGhpcy5zdHJpbmdpZnkodmFsdWUpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb3ZlcnJpZGUgc2V0RGF0ZShuZXdEYXRlOiBUdWlEYXkpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgW2RhdGUsIHRpbWVdID0gdGhpcy5jbGFtcFRpbWUoW25ld0RhdGUsIHRoaXMudmFsdWUoKT8uWzFdID8/IG51bGxdKTtcblxuICAgICAgICB0aGlzLnNldFZhbHVlKFtkYXRlLCB0aW1lXSk7XG4gICAgICAgIHRoaXMub3Blbi5zZXQoZmFsc2UpO1xuICAgICAgICBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKGNhcmV0SW5kZXggPSBEQVRFX0ZJTExFUl9MRU5HVEggKyB0aGlzLm9wdGlvbnMuZGF0ZVRpbWVTZXBhcmF0b3IubGVuZ3RoKSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuZWwuc2V0U2VsZWN0aW9uUmFuZ2UoY2FyZXRJbmRleCwgY2FyZXRJbmRleCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIG92ZXJyaWRlIHdyaXRlVmFsdWUodmFsdWU6IFtUdWlEYXksIFR1aVRpbWUgfCBudWxsXSB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgc3VwZXIud3JpdGVWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMudGV4dGZpZWxkLnZhbHVlLnNldCh0aGlzLnN0cmluZ2lmeSh0aGlzLnZhbHVlKCkpKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcHJvY2Vzc0NhbGVuZGFyKGNhbGVuZGFyOiBUdWlDYWxlbmRhcik6IHZvaWQge1xuICAgICAgICBzdXBlci5wcm9jZXNzQ2FsZW5kYXIoY2FsZW5kYXIpO1xuICAgICAgICBjYWxlbmRhci5kaXNhYmxlZEl0ZW1IYW5kbGVyID0gKGRheTogVHVpRGF5KSA9PlxuICAgICAgICAgICAgdGhpcy5oYW5kbGVycy5kaXNhYmxlZEl0ZW1IYW5kbGVyKCkoW2RheSwgbnVsbF0pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBvdmVycmlkZSBvblZhbHVlQ2hhbmdlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50ZXh0ZmllbGQudmFsdWUuc2V0KHZhbHVlKTtcbiAgICAgICAgdGhpcy5jb250cm9sPy5jb250cm9sPy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHtlbWl0RXZlbnQ6IGZhbHNlfSk7XG5cbiAgICAgICAgY29uc3QgW2RhdGUgPSAnJywgdGltZSA9ICcnXSA9IHZhbHVlLnNwbGl0KHRoaXMub3B0aW9ucy5kYXRlVGltZVNlcGFyYXRvcik7XG4gICAgICAgIGNvbnN0IHBhcnNlZERhdGUgPVxuICAgICAgICAgICAgZGF0ZS5sZW5ndGggPj0gREFURV9GSUxMRVJfTEVOR1RIXG4gICAgICAgICAgICAgICAgPyBUdWlEYXkubm9ybWFsaXplUGFyc2UoZGF0ZSwgdGhpcy5mb3JtYXQoKS5tb2RlKVxuICAgICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgY29uc3QgcGFyc2VkVGltZSA9XG4gICAgICAgICAgICB0aW1lLmxlbmd0aCA9PT0gdGhpcy50aW1lTW9kZSgpLmxlbmd0aCA/IFR1aVRpbWUuZnJvbVN0cmluZyh0aW1lKSA6IG51bGw7XG5cbiAgICAgICAgaWYgKCFwYXJzZWREYXRlIHx8ICh0aW1lICYmICFwYXJzZWRUaW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub25DaGFuZ2UobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBbcHJldkRhdGUsIHByZXZUaW1lID0gbnVsbF0gPSB0aGlzLnZhbHVlKCkgPz8gW107XG5cbiAgICAgICAgaWYgKCFwcmV2RGF0ZT8uZGF5U2FtZShwYXJzZWREYXRlKSB8fCBOdW1iZXIocGFyc2VkVGltZSkgIT09IE51bWJlcihwcmV2VGltZSkpIHtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoW3BhcnNlZERhdGUsIHBhcnNlZFRpbWVdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBvdmVycmlkZSBzdHJpbmdpZnkoXG4gICAgICAgIHZhbHVlOiByZWFkb25seSBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0gfCBudWxsLFxuICAgICk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IFtkYXRlLCB0aW1lXSA9IHZhbHVlID8/IFtdO1xuXG4gICAgICAgIGNvbnN0IGRhdGVTdHJpbmcgPVxuICAgICAgICAgICAgZGF0ZT8udG9TdHJpbmcodGhpcy5mb3JtYXQoKS5tb2RlLCB0aGlzLmZvcm1hdCgpLnNlcGFyYXRvcikgPz8gJyc7XG4gICAgICAgIGNvbnN0IHRpbWVTdHJpbmcgPSB0aW1lPy50b1N0cmluZyh0aGlzLnRpbWVNb2RlKCkpO1xuXG4gICAgICAgIHJldHVybiB0aW1lU3RyaW5nXG4gICAgICAgICAgICA/IGAke2RhdGVTdHJpbmd9JHt0aGlzLm9wdGlvbnMuZGF0ZVRpbWVTZXBhcmF0b3J9JHt0aW1lU3RyaW5nfWBcbiAgICAgICAgICAgIDogZGF0ZVN0cmluZztcbiAgICB9XG5cbiAgICBwcml2YXRlIGNsYW1wVGltZShbZGF0ZSwgdGltZV06IFtUdWlEYXksIFR1aVRpbWUgfCBudWxsXSk6IFtUdWlEYXksIFR1aVRpbWUgfCBudWxsXSB7XG4gICAgICAgIGNvbnN0IG1pbiA9IGRhdGUuZGF5U2FtZSh0aGlzLm1pbigpKVxuICAgICAgICAgICAgPyB0aGlzLm1pblRpbWUoKS50b0Fic29sdXRlTWlsbGlzZWNvbmRzKClcbiAgICAgICAgICAgIDogLUluZmluaXR5O1xuICAgICAgICBjb25zdCBtYXggPSBkYXRlLmRheVNhbWUodGhpcy5tYXgoKSlcbiAgICAgICAgICAgID8gdGhpcy5tYXhUaW1lKCkudG9BYnNvbHV0ZU1pbGxpc2Vjb25kcygpXG4gICAgICAgICAgICA6IEluZmluaXR5O1xuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgdGltZSAmJlxuICAgICAgICAgICAgICAgIFR1aVRpbWUuZnJvbUFic29sdXRlTWlsbGlzZWNvbmRzKFxuICAgICAgICAgICAgICAgICAgICB0dWlDbGFtcCh0aW1lLnRvQWJzb2x1dGVNaWxsaXNlY29uZHMoKSwgbWluLCBtYXgpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlTWFzayhcbiAgICAgICAgcGFyYW1zOiBPbWl0PFJlcXVpcmVkPE1hc2tpdG9EYXRlVGltZVBhcmFtcz4sICd0aW1lU3RlcCc+LFxuICAgICk6IE1hc2tpdG9PcHRpb25zIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG1hc2tpdG9EYXRlVGltZU9wdGlvbnNHZW5lcmF0b3IocGFyYW1zKTtcbiAgICAgICAgY29uc3Qge3RpbWVNb2RlLCBkYXRlTW9kZSwgZGF0ZVRpbWVTZXBhcmF0b3J9ID0gcGFyYW1zO1xuICAgICAgICBjb25zdCBpbnB1dE1vZGVTd2l0Y2hQbHVnaW4gPSBtYXNraXRvU2VsZWN0aW9uQ2hhbmdlSGFuZGxlcigoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgZWxlbWVudC5pbnB1dE1vZGUgPVxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2VsZWN0aW9uU3RhcnQhID49XG4gICAgICAgICAgICAgICAgZGF0ZU1vZGUubGVuZ3RoICsgZGF0ZVRpbWVTZXBhcmF0b3IubGVuZ3RoICsgdGltZU1vZGUuaW5kZXhPZignIEFBJylcbiAgICAgICAgICAgICAgICAgICAgPyAndGV4dCdcbiAgICAgICAgICAgICAgICAgICAgOiAnbnVtZXJpYyc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgcGx1Z2luczogb3B0aW9ucy5wbHVnaW5zLmNvbmNhdChcbiAgICAgICAgICAgICAgICB0aW1lTW9kZS5pbmNsdWRlcygnQUEnKSA/IGlucHV0TW9kZVN3aXRjaFBsdWdpbiA6IFtdLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRvTmF0aXZlRGF0ZShbe3llYXIsIG1vbnRoLCBkYXl9LCB7aG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1zfV06IHJlYWRvbmx5IFtcbiAgICAgICAgVHVpRGF5LFxuICAgICAgICBUdWlUaW1lLFxuICAgIF0pOiBEYXRlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXksIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtcyk7XG4gICAgfVxufVxuIl19