UNPKG

@taiga-ui/kit

Version:

Taiga UI Angular main components kit

194 lines 33.9 kB
import { computed, Directive, effect, inject, Input, signal, untracked, } 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) { const reset = this.control.pristine && this.control.untouched && !value; const changed = untracked(() => value !== this.value()); if (changed || reset) { super.writeValue(value); untracked(() => 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; } onBlur(valueWithAffixes) { const [date = '', timeValue = ''] = valueWithAffixes.split(this.options.dateTimeSeparator); if (timeValue && !this.value()) { const time = TuiTime.fromString(timeValue); const newValue = [ TuiDay.normalizeParse(date, this.format().mode), time, ]; this.control?.control?.updateValueAndValidity({ emitEvent: false }); this.onChange(newValue); this.textfield.value.set(this.stringify(newValue)); } } 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"] }, host: { listeners: { "blur": "onBlur($event.target.value)" } }, 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, ], host: { '(blur)': 'onBlur($event.target.value)', }, }] }], propDecorators: { timeModeSetter: [{ type: Input, args: ['timeMode'] }], minSetter: [{ type: Input, args: ['min'] }], maxSetter: [{ type: Input, args: ['max'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGF0ZS10aW1lLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tpdC9jb21wb25lbnRzL2lucHV0LWRhdGUtdGltZS9pbnB1dC1kYXRlLXRpbWUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCxRQUFRLEVBQ1IsU0FBUyxFQUNULE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixTQUFTLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQ3BELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBRWxELE9BQU8sRUFDSCwrQkFBK0IsRUFFL0IsNkJBQTZCLEdBRWhDLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBQyxZQUFZLEVBQUUsdUJBQXVCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RSxPQUFPLEVBQ0gsa0JBQWtCLEVBQ2xCLG1CQUFtQixFQUNuQixNQUFNLEVBQ04sT0FBTyxHQUNWLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUV0RSxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxxQ0FBcUMsQ0FBQztBQUN2RSxPQUFPLEVBQ0gsc0JBQXNCLEVBRXRCLGdCQUFnQixHQUNuQixNQUFNLHFDQUFxQyxDQUFDO0FBQzdDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRSxPQUFPLEVBQUMseUJBQXlCLEVBQUMsTUFBTSwwQ0FBMEMsQ0FBQztBQUNuRixPQUFPLEVBQ0gsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixp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QkFDbkMsU0FBUyxFQUFFO3dCQUNQLGtCQUFrQixDQUFDLGVBQWUsQ0FBQzt3QkFDbkMsWUFBWSwyQkFBMkI7d0JBQ3ZDLHNCQUFzQiwyQkFBMkI7d0JBQ2pELHVCQUF1QixDQUFDLDJCQUEyQixDQUFDO3FCQUN2RDtvQkFDRCxjQUFjLEVBQUU7d0JBQ1osZ0JBQWdCO3dCQUNoQixlQUFlO3dCQUNmLHlCQUF5Qjt3QkFDekIsZ0JBQWdCO3FCQUNuQjtvQkFDRCxJQUFJLEVBQUU7d0JBQ0YsUUFBUSxFQUFFLDZCQUE2QjtxQkFDMUM7aUJBQ0o7OEJBK0NjLGNBQWM7c0JBRHhCLEtBQUs7dUJBQUMsVUFBVTtnQkFNRyxTQUFTO3NCQUQ1QixLQUFLO3VCQUFDLEtBQUs7Z0JBV1EsU0FBUztzQkFENUIsS0FBSzt1QkFBQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBjb21wdXRlZCxcbiAgICBEaXJlY3RpdmUsXG4gICAgZWZmZWN0LFxuICAgIGluamVjdCxcbiAgICBJbnB1dCxcbiAgICBzaWduYWwsXG4gICAgdW50cmFja2VkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7dG9TaWduYWx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7TWFza2l0b0RpcmVjdGl2ZX0gZnJvbSAnQG1hc2tpdG8vYW5ndWxhcic7XG5pbXBvcnQge3R5cGUgTWFza2l0b09wdGlvbnN9IGZyb20gJ0BtYXNraXRvL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBtYXNraXRvRGF0ZVRpbWVPcHRpb25zR2VuZXJhdG9yLFxuICAgIHR5cGUgTWFza2l0b0RhdGVUaW1lUGFyYW1zLFxuICAgIG1hc2tpdG9TZWxlY3Rpb25DaGFuZ2VIYW5kbGVyLFxuICAgIHR5cGUgTWFza2l0b1RpbWVNb2RlLFxufSBmcm9tICdAbWFza2l0by9raXQnO1xuaW1wb3J0IHt0dWlBc0NvbnRyb2wsIHR1aVZhbHVlVHJhbnNmb3JtZXJGcm9tfSBmcm9tICdAdGFpZ2EtdWkvY2RrL2NsYXNzZXMnO1xuaW1wb3J0IHtcbiAgICBEQVRFX0ZJTExFUl9MRU5HVEgsXG4gICAgTUlMTElTRUNPTkRTX0lOX0RBWSxcbiAgICBUdWlEYXksXG4gICAgVHVpVGltZSxcbn0gZnJvbSAnQHRhaWdhLXVpL2Nkay9kYXRlLXRpbWUnO1xuaW1wb3J0IHt0dWlDbGFtcCwgdHVpU3VtfSBmcm9tICdAdGFpZ2EtdWkvY2RrL3V0aWxzL21hdGgnO1xuaW1wb3J0IHt0dWlEaXJlY3RpdmVCaW5kaW5nfSBmcm9tICdAdGFpZ2EtdWkvY2RrL3V0aWxzL21pc2NlbGxhbmVvdXMnO1xuaW1wb3J0IHt0eXBlIFR1aUNhbGVuZGFyfSBmcm9tICdAdGFpZ2EtdWkvY29yZS9jb21wb25lbnRzL2NhbGVuZGFyJztcbmltcG9ydCB7dHVpQXNPcHRpb25Db250ZW50fSBmcm9tICdAdGFpZ2EtdWkvY29yZS9jb21wb25lbnRzL2RhdGEtbGlzdCc7XG5pbXBvcnQge1xuICAgIHR1aUFzVGV4dGZpZWxkQWNjZXNzb3IsXG4gICAgdHlwZSBUdWlUZXh0ZmllbGRBY2Nlc3NvcixcbiAgICBUdWlXaXRoVGV4dGZpZWxkLFxufSBmcm9tICdAdGFpZ2EtdWkvY29yZS9jb21wb25lbnRzL3RleHRmaWVsZCc7XG5pbXBvcnQge1R1aURyb3Bkb3duQXV0b30gZnJvbSAnQHRhaWdhLXVpL2NvcmUvZGlyZWN0aXZlcy9kcm9wZG93bic7XG5pbXBvcnQge1R1aUl0ZW1zSGFuZGxlcnNWYWxpZGF0b3J9IGZyb20gJ0B0YWlnYS11aS9jb3JlL2RpcmVjdGl2ZXMvaXRlbXMtaGFuZGxlcnMnO1xuaW1wb3J0IHtcbiAgICBUVUlfREFURV9BREFQVEVSLFxuICAgIFR1aUlucHV0RGF0ZUJhc2UsXG4gICAgdHVpV2l0aERhdGVGaWxsZXIsXG59IGZyb20gJ0B0YWlnYS11aS9raXQvY29tcG9uZW50cy9pbnB1dC1kYXRlJztcbmltcG9ydCB7VHVpU2VsZWN0T3B0aW9ufSBmcm9tICdAdGFpZ2EtdWkva2l0L2NvbXBvbmVudHMvc2VsZWN0JztcbmltcG9ydCB7VFVJX1RJTUVfVEVYVFN9IGZyb20gJ0B0YWlnYS11aS9raXQvdG9rZW5zJztcbmltcG9ydCB7dHVpTWFza2l0b30gZnJvbSAnQHRhaWdhLXVpL2tpdC91dGlscyc7XG5pbXBvcnQge25vb3B9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1RVSV9JTlBVVF9EQVRFX1RJTUVfT1BUSU9OU30gZnJvbSAnLi9pbnB1dC1kYXRlLXRpbWUub3B0aW9ucyc7XG5cbmNvbnN0IE1JTl9USU1FID0gbmV3IFR1aVRpbWUoMCwgMCk7XG5jb25zdCBNQVhfVElNRSA9IFR1aVRpbWUuZnJvbUFic29sdXRlTWlsbGlzZWNvbmRzKE1JTExJU0VDT05EU19JTl9EQVkgLSAxKTtcblxuQERpcmVjdGl2ZSh7XG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzZWxlY3RvcjogJ2lucHV0W3R1aUlucHV0RGF0ZVRpbWVdJyxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgdHVpQXNPcHRpb25Db250ZW50KFR1aVNlbGVjdE9wdGlvbiksXG4gICAgICAgIHR1aUFzQ29udHJvbChUdWlJbnB1dERhdGVUaW1lRGlyZWN0aXZlKSxcbiAgICAgICAgdHVpQXNUZXh0ZmllbGRBY2Nlc3NvcihUdWlJbnB1dERhdGVUaW1lRGlyZWN0aXZlKSxcbiAgICAgICAgdHVpVmFsdWVUcmFuc2Zvcm1lckZyb20oVFVJX0lOUFVUX0RBVEVfVElNRV9PUFRJT05TKSxcbiAgICBdLFxuICAgIGhvc3REaXJlY3RpdmVzOiBbXG4gICAgICAgIE1hc2tpdG9EaXJlY3RpdmUsXG4gICAgICAgIFR1aURyb3Bkb3duQXV0byxcbiAgICAgICAgVHVpSXRlbXNIYW5kbGVyc1ZhbGlkYXRvcixcbiAgICAgICAgVHVpV2l0aFRleHRmaWVsZCxcbiAgICBdLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJyhibHVyKSc6ICdvbkJsdXIoJGV2ZW50LnRhcmdldC52YWx1ZSknLFxuICAgIH0sXG59KVxuZXhwb3J0IGNsYXNzIFR1aUlucHV0RGF0ZVRpbWVEaXJlY3RpdmVcbiAgICBleHRlbmRzIFR1aUlucHV0RGF0ZUJhc2U8cmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdPlxuICAgIGltcGxlbWVudHMgVHVpVGV4dGZpZWxkQWNjZXNzb3I8cmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdPlxue1xuICAgIHByaXZhdGUgcmVhZG9ubHkgdGltZUZpbGxlcnMgPSB0b1NpZ25hbChpbmplY3QoVFVJX1RJTUVfVEVYVFMpKTtcblxuICAgIHByb3RlY3RlZCBvdmVycmlkZSByZWFkb25seSBvcHRpb25zID0gaW5qZWN0KFRVSV9JTlBVVF9EQVRFX1RJTUVfT1BUSU9OUyk7XG5cbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcmVhZG9ubHkgZmlsbGVyID0gdHVpV2l0aERhdGVGaWxsZXIoKGRhdGUpID0+IHtcbiAgICAgICAgY29uc3QgdGltZSA9IHRoaXMudGltZUZpbGxlcnMoKT8uW3RoaXMudGltZU1vZGUoKV0gPz8gJyc7XG5cbiAgICAgICAgcmV0dXJuIGAke2RhdGV9JHt0aGlzLm9wdGlvbnMuZGF0ZVRpbWVTZXBhcmF0b3J9JHt0aW1lfWA7XG4gICAgfSk7XG5cbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgdmFsdWVFZmZlY3QgPSBlZmZlY3Qobm9vcCk7XG5cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaWRlbnRpdHkgPSB0aGlzLmhhbmRsZXJzLmlkZW50aXR5TWF0Y2hlci5zZXQoXG4gICAgICAgIChhLCBiKSA9PiB0dWlTdW0oLi4uYS5tYXAoTnVtYmVyKSkgPT09IHR1aVN1bSguLi5iLm1hcChOdW1iZXIpKSxcbiAgICApO1xuXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGRpc2FibGVkSXRlbUhhbmRsZXIgPSB0dWlEaXJlY3RpdmVCaW5kaW5nKFxuICAgICAgICBUdWlJdGVtc0hhbmRsZXJzVmFsaWRhdG9yLFxuICAgICAgICAnZGlzYWJsZWRJdGVtSGFuZGxlcicsXG4gICAgICAgICh2YWx1ZTogcmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdIHwgbnVsbCkgPT5cbiAgICAgICAgICAgIEJvb2xlYW4odmFsdWUgJiYgdGhpcy5oYW5kbGVycy5kaXNhYmxlZEl0ZW1IYW5kbGVyKCkodmFsdWUpKSxcbiAgICApO1xuXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG1hc2sgPSB0dWlNYXNraXRvKFxuICAgICAgICBjb21wdXRlZCgoKSA9PlxuICAgICAgICAgICAgdGhpcy5jb21wdXRlTWFzayh7XG4gICAgICAgICAgICAgICAgZGF0ZU1vZGU6IFRVSV9EQVRFX0FEQVBURVJbdGhpcy5mb3JtYXQoKS5tb2RlXSxcbiAgICAgICAgICAgICAgICB0aW1lTW9kZTogdGhpcy50aW1lTW9kZSgpLFxuICAgICAgICAgICAgICAgIG1pbjogdGhpcy50b05hdGl2ZURhdGUoW3RoaXMubWluKCksIHRoaXMubWluVGltZSgpXSksXG4gICAgICAgICAgICAgICAgbWF4OiB0aGlzLnRvTmF0aXZlRGF0ZShbdGhpcy5tYXgoKSwgdGhpcy5tYXhUaW1lKCldKSxcbiAgICAgICAgICAgICAgICBkYXRlU2VwYXJhdG9yOiB0aGlzLmZvcm1hdCgpLnNlcGFyYXRvcixcbiAgICAgICAgICAgICAgICBkYXRlVGltZVNlcGFyYXRvcjogdGhpcy5vcHRpb25zLmRhdGVUaW1lU2VwYXJhdG9yLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgKTtcblxuICAgIHB1YmxpYyByZWFkb25seSB0aW1lTW9kZSA9IHNpZ25hbCh0aGlzLm9wdGlvbnMudGltZU1vZGUpO1xuICAgIHB1YmxpYyByZWFkb25seSBtaW5UaW1lID0gc2lnbmFsKE1JTl9USU1FKTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgbWF4VGltZSA9IHNpZ25hbChNQVhfVElNRSk7XG5cbiAgICAvLyBUT0RPKHY1KTogdXNlIHNpZ25hbCBpbnB1dHNcbiAgICBASW5wdXQoJ3RpbWVNb2RlJylcbiAgICBwdWJsaWMgc2V0IHRpbWVNb2RlU2V0dGVyKHg6IE1hc2tpdG9UaW1lTW9kZSkge1xuICAgICAgICB0aGlzLnRpbWVNb2RlLnNldCh4KTtcbiAgICB9XG5cbiAgICBASW5wdXQoJ21pbicpXG4gICAgcHVibGljIG92ZXJyaWRlIHNldCBtaW5TZXR0ZXIoXG4gICAgICAgIG1pbjogVHVpRGF5IHwgcmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdIHwgbnVsbCxcbiAgICApIHtcbiAgICAgICAgY29uc3QgW2RhdGUsIHRpbWVdID0gQXJyYXkuaXNBcnJheShtaW4pID8gbWluIDogW21pbiwgbnVsbF07XG5cbiAgICAgICAgdGhpcy5taW4uc2V0KGRhdGUgfHwgdGhpcy5vcHRpb25zLm1pbik7XG4gICAgICAgIHRoaXMubWluVGltZS5zZXQodGltZSA/PyBNSU5fVElNRSk7XG4gICAgfVxuXG4gICAgQElucHV0KCdtYXgnKVxuICAgIHB1YmxpYyBvdmVycmlkZSBzZXQgbWF4U2V0dGVyKFxuICAgICAgICBtYXg6IFR1aURheSB8IHJlYWRvbmx5IFtUdWlEYXksIFR1aVRpbWUgfCBudWxsXSB8IG51bGwsXG4gICAgKSB7XG4gICAgICAgIGNvbnN0IFtkYXRlLCB0aW1lXSA9IEFycmF5LmlzQXJyYXkobWF4KSA/IG1heCA6IFttYXgsIG51bGxdO1xuXG4gICAgICAgIHRoaXMubWF4LnNldChkYXRlIHx8IHRoaXMub3B0aW9ucy5tYXgpO1xuICAgICAgICB0aGlzLm1heFRpbWUuc2V0KHRpbWUgPz8gTUFYX1RJTUUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRWYWx1ZSh2YWx1ZTogcmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdIHwgbnVsbCk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKHZhbHVlKTtcbiAgICAgICAgdGhpcy50ZXh0ZmllbGQudmFsdWUuc2V0KHRoaXMuc3RyaW5naWZ5KHZhbHVlKSk7XG4gICAgfVxuXG4gICAgcHVibGljIG92ZXJyaWRlIHNldERhdGUobmV3RGF0ZTogVHVpRGF5KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IFtkYXRlLCB0aW1lXSA9IHRoaXMuY2xhbXBUaW1lKFtuZXdEYXRlLCB0aGlzLnZhbHVlKCk/LlsxXSA/PyBudWxsXSk7XG5cbiAgICAgICAgdGhpcy5zZXRWYWx1ZShbZGF0ZSwgdGltZV0pO1xuICAgICAgICB0aGlzLm9wZW4uc2V0KGZhbHNlKTtcbiAgICAgICAgc2V0VGltZW91dChcbiAgICAgICAgICAgIChjYXJldEluZGV4ID0gREFURV9GSUxMRVJfTEVOR1RIICsgdGhpcy5vcHRpb25zLmRhdGVUaW1lU2VwYXJhdG9yLmxlbmd0aCkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLmVsLnNldFNlbGVjdGlvblJhbmdlKGNhcmV0SW5kZXgsIGNhcmV0SW5kZXgpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBvdmVycmlkZSB3cml0ZVZhbHVlKHZhbHVlOiBbVHVpRGF5LCBUdWlUaW1lIHwgbnVsbF0gfCBudWxsKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHJlc2V0ID0gdGhpcy5jb250cm9sLnByaXN0aW5lICYmIHRoaXMuY29udHJvbC51bnRvdWNoZWQgJiYgIXZhbHVlO1xuICAgICAgICBjb25zdCBjaGFuZ2VkID0gdW50cmFja2VkKCgpID0+IHZhbHVlICE9PSB0aGlzLnZhbHVlKCkpO1xuXG4gICAgICAgIGlmIChjaGFuZ2VkIHx8IHJlc2V0KSB7XG4gICAgICAgICAgICBzdXBlci53cml0ZVZhbHVlKHZhbHVlKTtcbiAgICAgICAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLnRleHRmaWVsZC52YWx1ZS5zZXQodGhpcy5zdHJpbmdpZnkodGhpcy52YWx1ZSgpKSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIG92ZXJyaWRlIHByb2Nlc3NDYWxlbmRhcihjYWxlbmRhcjogVHVpQ2FsZW5kYXIpOiB2b2lkIHtcbiAgICAgICAgc3VwZXIucHJvY2Vzc0NhbGVuZGFyKGNhbGVuZGFyKTtcbiAgICAgICAgY2FsZW5kYXIuZGlzYWJsZWRJdGVtSGFuZGxlciA9IChkYXk6IFR1aURheSkgPT5cbiAgICAgICAgICAgIHRoaXMuaGFuZGxlcnMuZGlzYWJsZWRJdGVtSGFuZGxlcigpKFtkYXksIG51bGxdKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgb25WYWx1ZUNoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGV4dGZpZWxkLnZhbHVlLnNldCh2YWx1ZSk7XG4gICAgICAgIHRoaXMuY29udHJvbD8uY29udHJvbD8udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuXG4gICAgICAgIGNvbnN0IFtkYXRlID0gJycsIHRpbWUgPSAnJ10gPSB2YWx1ZS5zcGxpdCh0aGlzLm9wdGlvbnMuZGF0ZVRpbWVTZXBhcmF0b3IpO1xuICAgICAgICBjb25zdCBwYXJzZWREYXRlID1cbiAgICAgICAgICAgIGRhdGUubGVuZ3RoID49IERBVEVfRklMTEVSX0xFTkdUSFxuICAgICAgICAgICAgICAgID8gVHVpRGF5Lm5vcm1hbGl6ZVBhcnNlKGRhdGUsIHRoaXMuZm9ybWF0KCkubW9kZSlcbiAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIGNvbnN0IHBhcnNlZFRpbWUgPVxuICAgICAgICAgICAgdGltZS5sZW5ndGggPT09IHRoaXMudGltZU1vZGUoKS5sZW5ndGggPyBUdWlUaW1lLmZyb21TdHJpbmcodGltZSkgOiBudWxsO1xuXG4gICAgICAgIGlmICghcGFyc2VkRGF0ZSB8fCAodGltZSAmJiAhcGFyc2VkVGltZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9uQ2hhbmdlKG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgW3ByZXZEYXRlLCBwcmV2VGltZSA9IG51bGxdID0gdGhpcy52YWx1ZSgpID8/IFtdO1xuXG4gICAgICAgIGlmICghcHJldkRhdGU/LmRheVNhbWUocGFyc2VkRGF0ZSkgfHwgTnVtYmVyKHBhcnNlZFRpbWUpICE9PSBOdW1iZXIocHJldlRpbWUpKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKFtwYXJzZWREYXRlLCBwYXJzZWRUaW1lXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgc3RyaW5naWZ5KFxuICAgICAgICB2YWx1ZTogcmVhZG9ubHkgW1R1aURheSwgVHVpVGltZSB8IG51bGxdIHwgbnVsbCxcbiAgICApOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBbZGF0ZSwgdGltZV0gPSB2YWx1ZSA/PyBbXTtcblxuICAgICAgICBjb25zdCBkYXRlU3RyaW5nID1cbiAgICAgICAgICAgIGRhdGU/LnRvU3RyaW5nKHRoaXMuZm9ybWF0KCkubW9kZSwgdGhpcy5mb3JtYXQoKS5zZXBhcmF0b3IpID8/ICcnO1xuICAgICAgICBjb25zdCB0aW1lU3RyaW5nID0gdGltZT8udG9TdHJpbmcodGhpcy50aW1lTW9kZSgpKTtcblxuICAgICAgICByZXR1cm4gdGltZVN0cmluZ1xuICAgICAgICAgICAgPyBgJHtkYXRlU3RyaW5nfSR7dGhpcy5vcHRpb25zLmRhdGVUaW1lU2VwYXJhdG9yfSR7dGltZVN0cmluZ31gXG4gICAgICAgICAgICA6IGRhdGVTdHJpbmc7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIG9uQmx1cih2YWx1ZVdpdGhBZmZpeGVzOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgW2RhdGUgPSAnJywgdGltZVZhbHVlID0gJyddID0gdmFsdWVXaXRoQWZmaXhlcy5zcGxpdChcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kYXRlVGltZVNlcGFyYXRvcixcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGltZVZhbHVlICYmICF0aGlzLnZhbHVlKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbWUgPSBUdWlUaW1lLmZyb21TdHJpbmcodGltZVZhbHVlKTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gW1xuICAgICAgICAgICAgICAgIFR1aURheS5ub3JtYWxpemVQYXJzZShkYXRlLCB0aGlzLmZvcm1hdCgpLm1vZGUpLFxuICAgICAgICAgICAgICAgIHRpbWUsXG4gICAgICAgICAgICBdIGFzIGNvbnN0O1xuXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2w/LmNvbnRyb2w/LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoe2VtaXRFdmVudDogZmFsc2V9KTtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UobmV3VmFsdWUpO1xuICAgICAgICAgICAgdGhpcy50ZXh0ZmllbGQudmFsdWUuc2V0KHRoaXMuc3RyaW5naWZ5KG5ld1ZhbHVlKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNsYW1wVGltZShbZGF0ZSwgdGltZV06IFtUdWlEYXksIFR1aVRpbWUgfCBudWxsXSk6IFtUdWlEYXksIFR1aVRpbWUgfCBudWxsXSB7XG4gICAgICAgIGNvbnN0IG1pbiA9IGRhdGUuZGF5U2FtZSh0aGlzLm1pbigpKVxuICAgICAgICAgICAgPyB0aGlzLm1pblRpbWUoKS50b0Fic29sdXRlTWlsbGlzZWNvbmRzKClcbiAgICAgICAgICAgIDogLUluZmluaXR5O1xuICAgICAgICBjb25zdCBtYXggPSBkYXRlLmRheVNhbWUodGhpcy5tYXgoKSlcbiAgICAgICAgICAgID8gdGhpcy5tYXhUaW1lKCkudG9BYnNvbHV0ZU1pbGxpc2Vjb25kcygpXG4gICAgICAgICAgICA6IEluZmluaXR5O1xuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgdGltZSAmJlxuICAgICAgICAgICAgICAgIFR1aVRpbWUuZnJvbUFic29sdXRlTWlsbGlzZWNvbmRzKFxuICAgICAgICAgICAgICAgICAgICB0dWlDbGFtcCh0aW1lLnRvQWJzb2x1dGVNaWxsaXNlY29uZHMoKSwgbWluLCBtYXgpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21wdXRlTWFzayhcbiAgICAgICAgcGFyYW1zOiBPbWl0PFJlcXVpcmVkPE1hc2tpdG9EYXRlVGltZVBhcmFtcz4sICd0aW1lU3RlcCc+LFxuICAgICk6IE1hc2tpdG9PcHRpb25zIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG1hc2tpdG9EYXRlVGltZU9wdGlvbnNHZW5lcmF0b3IocGFyYW1zKTtcbiAgICAgICAgY29uc3Qge3RpbWVNb2RlLCBkYXRlTW9kZSwgZGF0ZVRpbWVTZXBhcmF0b3J9ID0gcGFyYW1zO1xuICAgICAgICBjb25zdCBpbnB1dE1vZGVTd2l0Y2hQbHVnaW4gPSBtYXNraXRvU2VsZWN0aW9uQ2hhbmdlSGFuZGxlcigoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgZWxlbWVudC5pbnB1dE1vZGUgPVxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2VsZWN0aW9uU3RhcnQhID49XG4gICAgICAgICAgICAgICAgZGF0ZU1vZGUubGVuZ3RoICsgZGF0ZVRpbWVTZXBhcmF0b3IubGVuZ3RoICsgdGltZU1vZGUuaW5kZXhPZignIEFBJylcbiAgICAgICAgICAgICAgICAgICAgPyAndGV4dCdcbiAgICAgICAgICAgICAgICAgICAgOiAnbnVtZXJpYyc7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgcGx1Z2luczogb3B0aW9ucy5wbHVnaW5zLmNvbmNhdChcbiAgICAgICAgICAgICAgICB0aW1lTW9kZS5pbmNsdWRlcygnQUEnKSA/IGlucHV0TW9kZVN3aXRjaFBsdWdpbiA6IFtdLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRvTmF0aXZlRGF0ZShbe3llYXIsIG1vbnRoLCBkYXl9LCB7aG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1zfV06IHJlYWRvbmx5IFtcbiAgICAgICAgVHVpRGF5LFxuICAgICAgICBUdWlUaW1lLFxuICAgIF0pOiBEYXRlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXksIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtcyk7XG4gICAgfVxufVxuIl19