UNPKG

ng-zorro-antd-mobile

Version:

An enterprise-class mobile UI components based on Ant Design and Angular

638 lines 53.8 kB
/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import { Component, forwardRef, ViewEncapsulation, Input, Output, HostBinding, EventEmitter, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import zhCN from './locale/zh_CN';
import enUS from './locale/en_US';
import { LocaleProviderService } from '../locale-provider/locale-provider.service';
import { mergeDateTime, isSameDate } from './util/index';
import { takeUntil } from 'rxjs/operators';
import { CalendarDatePickerComponent } from './datepicker/datepicker.component';
import { Subject } from 'rxjs';
/**
 * @record
 */
export function CalendarStateType() { }
if (false) {
    /** @type {?} */
    CalendarStateType.prototype.showTimePicker;
    /** @type {?|undefined} */
    CalendarStateType.prototype.timePickerTitle;
    /** @type {?|undefined} */
    CalendarStateType.prototype.startDate;
    /** @type {?|undefined} */
    CalendarStateType.prototype.endDate;
    /** @type {?|undefined} */
    CalendarStateType.prototype.disConfirmBtn;
    /** @type {?|undefined} */
    CalendarStateType.prototype.clientHight;
}
export class CalendarComponent {
    /**
     * @param {?} _localeProviderService
     */
    constructor(_localeProviderService) {
        this._localeProviderService = _localeProviderService;
        this.isShow = false;
        this.showClear = false;
        this.isSameDate = isSameDate;
        this.props = (/** @type {?} */ ({
            visible: false,
            showHeader: true,
            locale: zhCN,
            pickTime: false,
            showShortcut: false,
            prefixCls: 'rmc-calendar',
            type: 'range',
            defaultTimeValue: new Date(2000, 0, 1, 8)
        }));
        this.state = (/** @type {?} */ ({
            showTimePicker: false,
            timePickerTitle: '',
            startDate: undefined,
            endDate: undefined,
            disConfirmBtn: true,
            clientHight: 0
        }));
        this._unsubscribe$ = new Subject();
        this._dateModelTime = 0;
        this.onCancel = new EventEmitter();
        this.onConfirm = new EventEmitter();
        this.onSelectHasDisableDate = new EventEmitter();
        this.class = 'am-calendar';
        this.selectDate = (/**
         * @param {?} date
         * @param {?=} useDateTime
         * @param {?=} oldState
         * @param {?=} props
         * @return {?}
         */
        (date, useDateTime = false, oldState = {}, props = this.props) => {
            if (!date) {
                return (/** @type {?} */ ({}));
            }
            /** @type {?} */
            let newState = (/** @type {?} */ ({}));
            const { type, pickTime, defaultTimeValue, locale = (/** @type {?} */ ({})) } = props;
            /** @type {?} */
            const newDate = pickTime && !useDateTime ? mergeDateTime(date, defaultTimeValue) : date;
            const { startDate, endDate } = oldState;
            switch (type) {
                case 'one':
                    newState = Object.assign({}, newState, { startDate: newDate, disConfirmBtn: false });
                    if (pickTime) {
                        newState = Object.assign({}, newState, { timePickerTitle: locale.selectTime, showTimePicker: true });
                    }
                    break;
                case 'range':
                    if (!startDate || endDate) {
                        newState = Object.assign({}, newState, { startDate: newDate, endDate: undefined, disConfirmBtn: true });
                        if (pickTime) {
                            newState = Object.assign({}, newState, { timePickerTitle: locale.selectStartTime, showTimePicker: true });
                        }
                    }
                    else {
                        newState = Object.assign({}, newState, { timePickerTitle: +newDate >= +startDate || this.isSameDate(startDate, newDate)
                                ? locale.selectEndTime
                                : locale.selectStartTime, disConfirmBtn: false, endDate: pickTime && !useDateTime && (+newDate >= +startDate || this.isSameDate(startDate, newDate))
                                ? new Date(+mergeDateTime(newDate, startDate) + 3600000)
                                : newDate });
                    }
                    break;
            }
            this.writeModelData(date);
            return newState;
        });
        this.onSelectedDate = (/**
         * @param {?} date
         * @return {?}
         */
        (date) => {
            const { startDate, endDate } = this.state;
            const { onSelect } = this.props;
            if (onSelect) {
                /** @type {?} */
                const value = onSelect(date, [startDate, endDate]);
                if (value) {
                    this.shortcutSelect(value[0], value[1]);
                    return;
                }
            }
            this.state = Object.assign({}, this.state, this.selectDate(date, false, { startDate, endDate }));
            this.showClear = !!this.state.startDate;
        });
        this.triggerSelectHasDisableDate = (/**
         * @param {?} date
         * @return {?}
         */
        (date) => {
            this.triggerClear();
            if (this.onSelectHasDisableDate) {
                this.onSelectHasDisableDate.emit(date);
            }
        });
        this.onClose = (/**
         * @return {?}
         */
        () => {
            this.state = (/** @type {?} */ ({
                showTimePicker: false,
                timePickerTitle: '',
                startDate: undefined,
                endDate: undefined,
                disConfirmBtn: true,
                clientHight: 0
            }));
            this.showClear = !!this.state.startDate;
        });
        this.triggerConfirm = (/**
         * @return {?}
         */
        () => {
            const { startDate, endDate } = this.state;
            if (startDate && endDate && +startDate > +endDate) {
                this.onClose();
                return this.onConfirm && this.onConfirm.emit({ startDate: endDate, endDate: startDate });
            }
            if (this.onConfirm) {
                this.onConfirm.emit({ startDate, endDate });
            }
            this.onClose();
        });
        this.triggerClear = (/**
         * @return {?}
         */
        () => {
            // 清除数据做延迟,否则同步刷新数据导致报错
            setTimeout((/**
             * @return {?}
             */
            () => {
                this.state = Object.assign({}, this.state, { startDate: undefined, endDate: undefined, showTimePicker: false });
                if (this.props.onClear) {
                    this.props.onClear();
                }
                this.showClear = !!this.state.startDate;
            }), 0);
        });
        this.onTimeChange = (/**
         * @param {?} date
         * @return {?}
         */
        (date) => {
            const { startDate, endDate } = this.state;
            if (endDate) {
                this.state.endDate = date;
            }
            else if (startDate) {
                this.state.startDate = date;
            }
        });
        this.shortcutSelect = (/**
         * @param {?} startDate
         * @param {?} endDate
         * @param {?=} props
         * @return {?}
         */
        (startDate, endDate, props = this.props) => {
            this.state = Object.assign({}, this.state, { startDate, showTimePicker: false }, this.selectDate(endDate, true, { startDate }, props));
            this.showClear = !!this.state.startDate;
        });
        this.setClientHeight = (/**
         * @param {?} height
         * @return {?}
         */
        (height) => {
            this.state.clientHight = height;
        });
        this.onChangeFn = (/**
         * @return {?}
         */
        () => { });
        this.onTouchFn = (/**
         * @return {?}
         */
        () => { });
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set locale(value) {
        if (value === 'enUS') {
            this.props.locale = enUS;
        }
        else if (value === 'zhCN') {
            this.props.locale = zhCN;
        }
        this._unsubscribe$.next();
        this._unsubscribe$.complete();
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set defaultTimeValue(value) {
        if (value) {
            this.props.defaultTimeValue = value;
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set prefixCls(value) {
        if (value) {
            this.props.prefixCls = value;
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set enterDirection(value) {
        this._enterDirection = value;
        if (this._enterDirection === 'horizontal') {
            this.contentAnimateClass = 'slideH-enter slideH-enter-active';
        }
        else {
            this.contentAnimateClass = 'slideV-enter slideV-enter-active';
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set visible(value) {
        this.props.visible = value;
        if (value === true || value === 'true') {
            this.showAnimation();
            this.isShow = true;
        }
        else {
            this.hideAnimation();
            setTimeout((/**
             * @return {?}
             */
            () => {
                this.isShow = false;
            }), 300);
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set getDateExtra(value) {
        this.props.getDateExtra = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set defaultDate(value) {
        this.props.defaultDate = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set minDate(value) {
        this.props.minDate = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set maxDate(value) {
        this.props.maxDate = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set pickTime(value) {
        this.props.pickTime = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set type(value) {
        this.props.type = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set showShortcut(value) {
        this.props.showShortcut = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set rowSize(value) {
        this.props.rowSize = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set infinite(value) { }
    /**
     * @param {?} value
     * @return {?}
     */
    set defaultValue(value) {
        this.props.defaultValue = value;
        if (value) {
            this.receiveProps(this.props);
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set onSelect(value) {
        this.props.onSelect = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    writeValue(value) {
        this._dateModelType = null;
        if (value && value instanceof Array) {
            if (value.length === 0) {
                console.error('[ng-zorro-antd-mobile]: calendar ngModel array need params!');
                return;
            }
            if (this.props.type === 'one' && value.length >= 2) {
                this._dateModelType = 1;
                console.error('[ng-zorro-antd-mobile]: type is one, but ngmodel has more than one param, just use first one');
                this.onSelectedDate(value[0]);
            }
            else if (value.length === 1) {
                this._dateModelType = 1;
                this.onSelectedDate(value[0]);
            }
            else {
                this._dateModelType = 2;
                this.onSelectedDate(value[0]);
                this.onSelectedDate(value[1]);
            }
        }
        else if (value && value instanceof Date) {
            this._dateModelType = 3;
            this.onSelectedDate(value);
        }
    }
    /**
     * @param {?} fn
     * @return {?}
     */
    registerOnChange(fn) {
        this.onChangeFn = fn;
    }
    /**
     * @param {?} fn
     * @return {?}
     */
    registerOnTouched(fn) {
        this.onTouchFn = fn;
    }
    /**
     * @param {?} nextProps
     * @return {?}
     */
    receiveProps(nextProps) {
        if (nextProps.visible && nextProps.defaultValue) {
            this.shortcutSelect(nextProps.defaultValue[0], nextProps.defaultValue[1], nextProps);
        }
    }
    /**
     * @return {?}
     */
    showAnimation() {
        if (this._enterDirection === 'horizontal') {
            this.contentAnimateClass = 'slideH-enter slideH-enter-active';
        }
        else {
            this.contentAnimateClass = 'slideV-enter slideV-enter-active';
        }
        this.maskAnimateClass = 'fade-enter fade-enter-active';
    }
    /**
     * @return {?}
     */
    hideAnimation() {
        if (this._enterDirection === 'horizontal') {
            this.contentAnimateClass = 'slideH-leave slideH-leave-active';
        }
        else {
            this.contentAnimateClass = 'slideV-leave slideV-leave-active';
        }
        this.maskAnimateClass = 'fade-leave fade-leave-active';
    }
    /**
     * @param {?} date
     * @return {?}
     */
    writeModelData(date) {
        if (this._dateModelValue instanceof Array) {
            this._dateModelTime = this._dateModelValue.length;
        }
        else {
            this._dateModelTime = 0;
        }
        switch (this._dateModelType) {
            case 1:
                this._dateModelValue = [date];
                this.onChangeFn(this._dateModelValue);
                break;
            case 2:
                if (this._dateModelTime === 1) {
                    if (+date < +this._dateModelValue[0]) {
                        this._dateModelValue.unshift(date);
                    }
                    else {
                        this._dateModelValue.push(date);
                    }
                    this.onChangeFn(this._dateModelValue);
                }
                else {
                    this._dateModelValue = [];
                    this._dateModelValue.push(date);
                }
                break;
            case 3:
                this._dateModelValue = date;
                this.onChangeFn(this._dateModelValue);
                break;
            default:
                break;
        }
    }
    /**
     * @return {?}
     */
    triggerCancel() {
        if (this.props.onCancel) {
            this.props.onCancel();
        }
        this.onClose();
        if (this.onCancel) {
            this.onCancel.emit();
        }
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        /** @type {?} */
        const defaultValue = this.props.defaultValue;
        if (defaultValue) {
            this.state = Object.assign({}, this.state, this.selectDate(defaultValue[1], true, { startDate: defaultValue[0] }, this.props));
        }
        this._localeProviderService.localeChange.pipe(takeUntil(this._unsubscribe$)).subscribe((/**
         * @param {?} _
         * @return {?}
         */
        _ => {
            this.props.locale = (/** @type {?} */ (Object.assign({}, this._localeProviderService.getLocaleSubObj('Calendar'))));
        }));
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this._unsubscribe$.next();
        this._unsubscribe$.complete();
    }
}
CalendarComponent.decorators = [
    { type: Component, args: [{
                selector: 'Calendar, nzm-calendar',
                template: "<span *ngIf=\"isShow\">\n  <div class=\"{{ 'mask ' + maskAnimateClass }}\"></div>\n</span>\n<span *ngIf=\"isShow\">\n  <div class=\"{{ 'content animate ' + contentAnimateClass }}\">\n    <CalendarHeader\n      [locale]=\"props.locale\"\n      [closeIcon]=\"closeIconHtml\"\n      [showClear]=\"showClear\"\n      (onCancel)=\"triggerCancel()\"\n      (onClear)=\"triggerClear()\"\n    ></CalendarHeader>\n    <CalendarDatePicker\n      [propsData]=\"props\"\n      [endDate]=\"state.endDate\"\n      [startDate]=\"state.startDate\"\n      [onCellClick]=\"onSelectedDate\"\n      [onSelectHasDisableDate]=\"triggerSelectHasDisableDate\"\n      [onLayout]=\"setClientHeight\"\n    ></CalendarDatePicker>\n    <CalendarTimePicker\n      *ngIf=\"state.showTimePicker\"\n      [propsData]=\"props\"\n      [title]=\"state.timePickerTitle\"\n      [clientHeight]=\"state.clientHight\"\n      [prefixCls]=\"props.timePickerPrefixCls\"\n      [defaultValue]=\"props.defaultTimeValue\"\n      [pickerPrefixCls]=\"props.timePickerPickerPrefixCls\"\n      [value]=\"state.endDate ? state.endDate : state.startDate\"\n      [onValueChange]=\"onTimeChange\"\n    ></CalendarTimePicker>\n    <CalendarShortcutPanel\n      *ngIf=\"props.showShortcut && !state.showTimePicker\"\n      [locale]=\"props.locale\"\n      [onSelect]=\"shortcutSelect\"\n    ></CalendarShortcutPanel>\n    <CalendarConfirmPanel\n      *ngIf=\"state.startDate\"\n      [startDateTime]=\"state.startDate\"\n      [endDateTime]=\"state.endDate\"\n      [propsData]=\"props\"\n      [disableBtn]=\"state.disConfirmBtn\"\n      [formatStr]=\"props.pickTime ? props.locale.dateTimeFormat : props.locale.dateFormat\"\n      [onConfirm]=\"triggerConfirm\"\n    ></CalendarConfirmPanel>\n  </div>\n</span>\n<ng-template #closeIconHtml>\n  <Icon [type]=\"'cross'\"></Icon>\n</ng-template>\n",
                encapsulation: ViewEncapsulation.None,
                providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/**
                         * @return {?}
                         */
                        () => CalendarComponent)), multi: true }]
            }] }
];
/** @nocollapse */
CalendarComponent.ctorParameters = () => [
    { type: LocaleProviderService }
];
CalendarComponent.propDecorators = {
    datepicker: [{ type: ViewChild, args: [CalendarDatePickerComponent, { static: false },] }],
    locale: [{ type: Input }],
    defaultTimeValue: [{ type: Input }],
    prefixCls: [{ type: Input }],
    enterDirection: [{ type: Input }],
    visible: [{ type: Input }],
    getDateExtra: [{ type: Input }],
    defaultDate: [{ type: Input }],
    minDate: [{ type: Input }],
    maxDate: [{ type: Input }],
    pickTime: [{ type: Input }],
    type: [{ type: Input }],
    showShortcut: [{ type: Input }],
    rowSize: [{ type: Input }],
    infinite: [{ type: Input }],
    defaultValue: [{ type: Input }],
    onSelect: [{ type: Input }],
    onCancel: [{ type: Output }],
    onConfirm: [{ type: Output }],
    onSelectHasDisableDate: [{ type: Output }],
    class: [{ type: HostBinding, args: ['class',] }]
};
if (false) {
    /** @type {?} */
    CalendarComponent.prototype.isShow;
    /** @type {?} */
    CalendarComponent.prototype.contentAnimateClass;
    /** @type {?} */
    CalendarComponent.prototype.maskAnimateClass;
    /** @type {?} */
    CalendarComponent.prototype.showClear;
    /** @type {?} */
    CalendarComponent.prototype.isSameDate;
    /** @type {?} */
    CalendarComponent.prototype.props;
    /** @type {?} */
    CalendarComponent.prototype.state;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._unsubscribe$;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._enterDirection;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._dateModelType;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._dateModelValue;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._dateModelTime;
    /** @type {?} */
    CalendarComponent.prototype.datepicker;
    /** @type {?} */
    CalendarComponent.prototype.onCancel;
    /** @type {?} */
    CalendarComponent.prototype.onConfirm;
    /** @type {?} */
    CalendarComponent.prototype.onSelectHasDisableDate;
    /** @type {?} */
    CalendarComponent.prototype.class;
    /** @type {?} */
    CalendarComponent.prototype.selectDate;
    /** @type {?} */
    CalendarComponent.prototype.onSelectedDate;
    /** @type {?} */
    CalendarComponent.prototype.triggerSelectHasDisableDate;
    /** @type {?} */
    CalendarComponent.prototype.onClose;
    /** @type {?} */
    CalendarComponent.prototype.triggerConfirm;
    /** @type {?} */
    CalendarComponent.prototype.triggerClear;
    /** @type {?} */
    CalendarComponent.prototype.onTimeChange;
    /** @type {?} */
    CalendarComponent.prototype.shortcutSelect;
    /** @type {?} */
    CalendarComponent.prototype.setClientHeight;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype.onChangeFn;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype.onTouchFn;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._localeProviderService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC1tb2JpbGUvIiwic291cmNlcyI6WyJjYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUdWLGlCQUFpQixFQUNqQixLQUFLLEVBQ0wsTUFBTSxFQUNOLFdBQVcsRUFDWCxZQUFZLEVBQ1osU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUNsQyxPQUFPLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUVsQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNuRixPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDaEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7OztBQUkvQix1Q0FPQzs7O0lBTkMsMkNBQXdCOztJQUN4Qiw0Q0FBeUI7O0lBQ3pCLHNDQUFpQjs7SUFDakIsb0NBQWU7O0lBQ2YsMENBQXdCOztJQUN4Qix3Q0FBcUI7O0FBU3ZCLE1BQU0sT0FBTyxpQkFBaUI7Ozs7SUEwSTVCLFlBQW9CLHNCQUE2QztRQUE3QywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXVCO1FBeklqRSxXQUFNLEdBQVksS0FBSyxDQUFDO1FBR3hCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IsZUFBVSxHQUFhLFVBQVUsQ0FBQztRQUVsQyxVQUFLLEdBQUcsbUJBQUE7WUFDTixPQUFPLEVBQUUs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QUN3Qzs7SUE4RnhDLHFDQUNzRDs7SUFDdEQsc0NBQ3VEOztJQUN2RCxtREFDb0U7O0lBRXBFLGtDQUM4Qjs7SUE2RDlCLHVDQWdFQzs7SUFvQ0QsMkNBa0JDOztJQUVELHdEQUtDOztJQUVELG9DQVVDOztJQUVELDJDQVVDOztJQVlELHlDQVlDOztJQUVELHlDQU9DOztJQUVELDJDQU9DOztJQUVELDRDQUVDOzs7OztJQXFCRCx1Q0FBa0U7Ozs7O0lBQ2xFLHNDQUFpRTs7Ozs7SUFwUnJELG1EQUFxRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgZm9yd2FyZFJlZixcbiAgT25Jbml0LFxuICBPbkRlc3Ryb3ksXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBIb3N0QmluZGluZyxcbiAgRXZlbnRFbWl0dGVyLFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEYXRlTW9kZWxzIH0gZnJvbSAnLi9kYXRlL0RhdGFUeXBlcyc7XG5pbXBvcnQgemhDTiBmcm9tICcuL2xvY2FsZS96aF9DTic7XG5pbXBvcnQgZW5VUyBmcm9tICcuL2xvY2FsZS9lbl9VUyc7XG5pbXBvcnQgeyBDYWxlbmRhclByb3BzVHlwZSB9IGZyb20gJy4vY2FsZW5kYXIucHJvcHMuY29tcG9uZW50JztcbmltcG9ydCB7IExvY2FsZVByb3ZpZGVyU2VydmljZSB9IGZyb20gJy4uL2xvY2FsZS1wcm92aWRlci9sb2NhbGUtcHJvdmlkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBtZXJnZURhdGVUaW1lLCBpc1NhbWVEYXRlIH0gZnJvbSAnLi91dGlsL2luZGV4JztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudCB9IGZyb20gJy4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCB7IENhbGVuZGFyUHJvcHNUeXBlIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJTdGF0ZVR5cGUge1xuICBzaG93VGltZVBpY2tlcjogYm9vbGVhbjtcbiAgdGltZVBpY2tlclRpdGxlPzogc3RyaW5nO1xuICBzdGFydERhdGU/OiBEYXRlO1xuICBlbmREYXRlPzogRGF0ZTtcbiAgZGlzQ29uZmlybUJ0bj86IGJvb2xlYW47XG4gIGNsaWVudEhpZ2h0PzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdDYWxlbmRhciwgbnptLWNhbGVuZGFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gQ2FsZW5kYXJDb21wb25lbnQpLCBtdWx0aTogdHJ1ZSB9XVxufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGlzU2hvdzogYm9vbGVhbiA9IGZhbHNlO1xuICBjb250ZW50QW5pbWF0ZUNsYXNzOiBzdHJpbmc7XG4gIG1hc2tBbmltYXRlQ2xhc3M6IHN0cmluZztcbiAgc2hvd0NsZWFyOiBib29sZWFuID0gZmFsc2U7XG4gIGlzU2FtZURhdGU6IEZ1bmN0aW9uID0gaXNTYW1lRGF0ZTtcblxuICBwcm9wcyA9IHtcbiAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICBzaG93SGVhZGVyOiB0cnVlLFxuICAgIGxvY2FsZTogemhDTixcbiAgICBwaWNrVGltZTogZmFsc2UsXG4gICAgc2hvd1Nob3J0Y3V0OiBmYWxzZSxcbiAgICBwcmVmaXhDbHM6ICdybWMtY2FsZW5kYXInLFxuICAgIHR5cGU6ICdyYW5nZScsXG4gICAgZGVmYXVsdFRpbWVWYWx1ZTogbmV3IERhdGUoMjAwMCwgMCwgMSwgOClcbiAgfSBhcyBDYWxlbmRhclByb3BzVHlwZTtcblxuICBzdGF0ZSA9IHtcbiAgICBzaG93VGltZVBpY2tlcjogZmFsc2UsXG4gICAgdGltZVBpY2tlclRpdGxlOiAnJyxcbiAgICBzdGFydERhdGU6IHVuZGVmaW5lZCxcbiAgICBlbmREYXRlOiB1bmRlZmluZWQsXG4gICAgZGlzQ29uZmlybUJ0bjogdHJ1ZSxcbiAgICBjbGllbnRIaWdodDogMFxuICB9IGFzIENhbGVuZGFyU3RhdGVUeXBlO1xuXG4gIHByaXZhdGUgX3Vuc3Vic2NyaWJlJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgX2VudGVyRGlyZWN0aW9uOiBzdHJpbmc7XG4gIHByaXZhdGUgX2RhdGVNb2RlbFR5cGU6IG51bWJlcjtcbiAgcHJpdmF0ZSBfZGF0ZU1vZGVsVmFsdWU6IGFueTtcbiAgcHJpdmF0ZSBfZGF0ZU1vZGVsVGltZTogbnVtYmVyID0gMDtcblxuICBAVmlld0NoaWxkKENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudCwgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIGRhdGVwaWNrZXI6IENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudDtcblxuICBASW5wdXQoKVxuICBzZXQgbG9jYWxlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSAnZW5VUycpIHtcbiAgICAgIHRoaXMucHJvcHMubG9jYWxlID0gZW5VUztcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnemhDTicpIHtcbiAgICAgIHRoaXMucHJvcHMubG9jYWxlID0gemhDTjtcbiAgICB9XG5cbiAgICB0aGlzLl91bnN1YnNjcmliZSQubmV4dCgpO1xuICAgIHRoaXMuX3Vuc3Vic2NyaWJlJC5jb21wbGV0ZSgpO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBkZWZhdWx0VGltZVZhbHVlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnByb3BzLmRlZmF1bHRUaW1lVmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHByZWZpeENscyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5wcm9wcy5wcmVmaXhDbHMgPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IGVudGVyRGlyZWN0aW9uKHZhbHVlKSB7XG4gICAgdGhpcy5fZW50ZXJEaXJlY3Rpb24gPSB2YWx1ZTtcbiAgICBpZiAodGhpcy5fZW50ZXJEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgdGhpcy5jb250ZW50QW5pbWF0ZUNsYXNzID0gJ3NsaWRlSC1lbnRlciBzbGlkZUgtZW50ZXItYWN0aXZlJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250ZW50QW5pbWF0ZUNsYXNzID0gJ3NsaWRlVi1lbnRlciBzbGlkZVYtZW50ZXItYWN0aXZlJztcbiAgICB9XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHZpc2libGUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLnZpc2libGUgPSB2YWx1ZTtcbiAgICBpZiAodmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09ICd0cnVlJykge1xuICAgICAgdGhpcy5zaG93QW5pbWF0aW9uKCk7XG4gICAgICB0aGlzLmlzU2hvdyA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGlkZUFuaW1hdGlvbigpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNTaG93ID0gZmFsc2U7XG4gICAgICB9LCAzMDApO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgZ2V0RGF0ZUV4dHJhKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5nZXREYXRlRXh0cmEgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgZGVmYXVsdERhdGUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLmRlZmF1bHREYXRlID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IG1pbkRhdGUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLm1pbkRhdGUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgbWF4RGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMubWF4RGF0ZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBwaWNrVGltZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMucGlja1RpbWUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgdHlwZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMudHlwZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBzaG93U2hvcnRjdXQodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLnNob3dTaG9ydGN1dCA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCByb3dTaXplKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5yb3dTaXplID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IGluZmluaXRlKHZhbHVlKSB7fVxuICBASW5wdXQoKVxuICBzZXQgZGVmYXVsdFZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5kZWZhdWx0VmFsdWUgPSB2YWx1ZTtcblxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5yZWNlaXZlUHJvcHModGhpcy5wcm9wcyk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBvblNlbGVjdCh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMub25TZWxlY3QgPSB2YWx1ZTtcbiAgfVxuXG4gIEBPdXRwdXQoKVxuICBvbkNhbmNlbDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpXG4gIG9uQ29uZmlybTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpXG4gIG9uU2VsZWN0SGFzRGlzYWJsZURhdGU6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpXG4gIGNsYXNzOiBzdHJpbmcgPSAnYW0tY2FsZW5kYXInO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2xvY2FsZVByb3ZpZGVyU2VydmljZTogTG9jYWxlUHJvdmlkZXJTZXJ2aWNlKSB7fVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IERhdGUgfCBBcnJheTxEYXRlPiB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9kYXRlTW9kZWxUeXBlID0gbnVsbDtcbiAgICBpZiAodmFsdWUgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbbmctem9ycm8tYW50ZC1tb2JpbGVdOiBjYWxlbmRhciBuZ01vZGVsIGFycmF5IG5lZWQgcGFyYW1zIScpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5wcm9wcy50eXBlID09PSAnb25lJyAmJiB2YWx1ZS5sZW5ndGggPj0gMikge1xuICAgICAgICB0aGlzLl9kYXRlTW9kZWxUeXBlID0gMTtcbiAgICAgICAgY29uc29sZS5lcnJvcignW25nLXpvcnJvLWFudGQtbW9iaWxlXTogdHlwZSBpcyBvbmUsIGJ1dCBuZ21vZGVsIGhhcyBtb3JlIHRoYW4gb25lIHBhcmFtLCBqdXN0IHVzZSBmaXJzdCBvbmUnKTtcbiAgICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZVswXSk7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICB0aGlzLl9kYXRlTW9kZWxUeXBlID0gMTtcbiAgICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZVswXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9kYXRlTW9kZWxUeXBlID0gMjtcbiAgICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZVswXSk7XG4gICAgICAgIHRoaXMub25TZWxlY3RlZERhdGUodmFsdWVbMV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodmFsdWUgJiYgdmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICB0aGlzLl9kYXRlTW9kZWxUeXBlID0gMztcbiAgICAgIHRoaXMub25TZWxlY3RlZERhdGUodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IChkYXRlOiBEYXRlIHwgQXJyYXk8RGF0ZT4pID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlRm4gPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoRm4gPSBmbjtcbiAgfVxuXG4gIHJlY2VpdmVQcm9wcyhuZXh0UHJvcHM6IENhbGVuZGFyUHJvcHNUeXBlKSB7XG4gICAgaWYgKG5leHRQcm9wcy52aXNpYmxlICYmIG5leHRQcm9wcy5kZWZhdWx0VmFsdWUpIHtcbiAgICAgIHRoaXMuc2hvcnRjdXRTZWxlY3QobmV4dFByb3BzLmRlZmF1bHRWYWx1ZVswXSwgbmV4dFByb3BzLmRlZmF1bHRWYWx1ZVsxXSwgbmV4dFByb3BzKTtcbiAgICB9XG4gIH1cblxuICBzaG93QW5pbWF0aW9uKCkge1xuICAgIGlmICh0aGlzLl9lbnRlckRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVILWVudGVyIHNsaWRlSC1lbnRlci1hY3RpdmUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVWLWVudGVyIHNsaWRlVi1lbnRlci1hY3RpdmUnO1xuICAgIH1cbiAgICB0aGlzLm1hc2tBbmltYXRlQ2xhc3MgPSAnZmFkZS1lbnRlciBmYWRlLWVudGVyLWFjdGl2ZSc7XG4gIH1cblxuICBoaWRlQW5pbWF0aW9uKCkge1xuICAgIGlmICh0aGlzLl9lbnRlckRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVILWxlYXZlIHNsaWRlSC1sZWF2ZS1hY3RpdmUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVWLWxlYXZlIHNsaWRlVi1sZWF2ZS1hY3RpdmUnO1xuICAgIH1cbiAgICB0aGlzLm1hc2tBbmltYXRlQ2xhc3MgPSAnZmFkZS1sZWF2ZSBmYWRlLWxlYXZlLWFjdGl2ZSc7XG4gIH1cblxuICBzZWxlY3REYXRlID0gKFxuICAgIGRhdGU6IERhdGUsXG4gICAgdXNlRGF0ZVRpbWUgPSBmYWxzZSxcbiAgICBvbGRTdGF0ZTogeyBzdGFydERhdGU/OiBEYXRlOyBlbmREYXRlPzogRGF0ZSB9ID0ge30sXG4gICAgcHJvcHMgPSB0aGlzLnByb3BzXG4gICkgPT4ge1xuICAgIGlmICghZGF0ZSkge1xuICAgICAgcmV0dXJuIHt9IGFzIENhbGVuZGFyU3RhdGVUeXBlO1xuICAgIH1cbiAgICBsZXQgbmV3U3RhdGUgPSB7fSBhcyBDYWxlbmRhclN0YXRlVHlwZTtcbiAgICBjb25zdCB7IHR5cGUsIHBpY2tUaW1lLCBkZWZhdWx0VGltZVZhbHVlLCBsb2NhbGUgPSB7fSBhcyBEYXRlTW9kZWxzLkxvY2FsZSB9ID0gcHJvcHM7XG4gICAgY29uc3QgbmV3RGF0ZSA9IHBpY2tUaW1lICYmICF1c2VEYXRlVGltZSA/IG1lcmdlRGF0ZVRpbWUoZGF0ZSwgZGVmYXVsdFRpbWVWYWx1ZSkgOiBkYXRlO1xuICAgIGNvbnN0IHsgc3RhcnREYXRlLCBlbmREYXRlIH0gPSBvbGRTdGF0ZTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnb25lJzpcbiAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICAgICAgc3RhcnREYXRlOiBuZXdEYXRlLFxuICAgICAgICAgIGRpc0NvbmZpcm1CdG46IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIGlmIChwaWNrVGltZSkge1xuICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICAgICAgICB0aW1lUGlja2VyVGl0bGU6IGxvY2FsZS5zZWxlY3RUaW1lLFxuICAgICAgICAgICAgc2hvd1RpbWVQaWNrZXI6IHRydWVcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdyYW5nZSc6XG4gICAgICAgIGlmICghc3RhcnREYXRlIHx8IGVuZERhdGUpIHtcbiAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgIC4uLm5ld1N0YXRlLFxuICAgICAgICAgICAgc3RhcnREYXRlOiBuZXdEYXRlLFxuICAgICAgICAgICAgZW5kRGF0ZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZGlzQ29uZmlybUJ0bjogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHBpY2tUaW1lKSB7XG4gICAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICAgICAgICAgIHRpbWVQaWNrZXJUaXRsZTogbG9jYWxlLnNlbGVjdFN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgc2hvd1RpbWVQaWNrZXI6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICAgICAgICB0aW1lUGlja2VyVGl0bGU6XG4gICAgICAgICAgICAgICtuZXdEYXRlID49ICtzdGFydERhdGUgfHwgdGhpcy5pc1NhbWVEYXRlKHN0YXJ0RGF0ZSwgbmV3RGF0ZSlcbiAgICAgICAgICAgICAgICA/IGxvY2FsZS5zZWxlY3RFbmRUaW1lXG4gICAgICAgICAgICAgICAgOiBsb2NhbGUuc2VsZWN0U3RhcnRUaW1lLFxuICAgICAgICAgICAgZGlzQ29uZmlybUJ0bjogZmFsc2UsXG4gICAgICAgICAgICBlbmREYXRlOlxuICAgICAgICAgICAgICBwaWNrVGltZSAmJiAhdXNlRGF0ZVRpbWUgJiYgKCtuZXdEYXRlID49ICtzdGFydERhdGUgfHwgdGhpcy5pc1NhbWVEYXRlKHN0YXJ0RGF0ZSwgbmV3RGF0ZSkpXG4gICAgICAgICAgICAgICAgPyBuZXcgRGF0ZSgrbWVyZ2VEYXRlVGltZShuZXdEYXRlLCBzdGFydERhdGUpICsgMzYwMDAwMClcbiAgICAgICAgICAgICAgICA6IG5ld0RhdGVcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMud3JpdGVNb2RlbERhdGEoZGF0ZSk7XG4gICAgcmV0dXJuIG5ld1N0YXRlO1xuICB9XG5cbiAgd3JpdGVNb2RlbERhdGEoZGF0ZSkge1xuICAgIGlmICh0aGlzLl9kYXRlTW9kZWxWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICB0aGlzLl9kYXRlTW9kZWxUaW1lID0gdGhpcy5fZGF0ZU1vZGVsVmFsdWUubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYXRlTW9kZWxUaW1lID0gMDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuX2RhdGVNb2RlbFR5cGUpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUgPSBbZGF0ZV07XG4gICAgICAgIHRoaXMub25DaGFuZ2VGbih0aGlzLl9kYXRlTW9kZWxWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBpZiAodGhpcy5fZGF0ZU1vZGVsVGltZSA9PT0gMSkge1xuICAgICAgICAgIGlmICgrZGF0ZSA8ICt0aGlzLl9kYXRlTW9kZWxWYWx1ZVswXSkge1xuICAgICAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUudW5zaGlmdChkYXRlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUucHVzaChkYXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5vbkNoYW5nZUZuKHRoaXMuX2RhdGVNb2RlbFZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZSA9IFtdO1xuICAgICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlLnB1c2goZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlID0gZGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZUZuKHRoaXMuX2RhdGVNb2RlbFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBvblNlbGVjdGVkRGF0ZSA9IChkYXRlOiBEYXRlKSA9PiB7XG4gICAgY29uc3QgeyBzdGFydERhdGUsIGVuZERhdGUgfSA9IHRoaXMuc3RhdGU7XG4gICAgY29uc3QgeyBvblNlbGVjdCB9ID0gdGhpcy5wcm9wcztcblxuICAgIGlmIChvblNlbGVjdCkge1xuICAgICAgY29uc3QgdmFsdWUgPSBvblNlbGVjdChkYXRlLCBbc3RhcnREYXRlLCBlbmREYXRlXSk7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5zaG9ydGN1dFNlbGVjdCh2YWx1ZVswXSwgdmFsdWVbMV0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAuLi50aGlzLnNlbGVjdERhdGUoZGF0ZSwgZmFsc2UsIHsgc3RhcnREYXRlLCBlbmREYXRlIH0pXG4gICAgfTtcblxuICAgIHRoaXMuc2hvd0NsZWFyID0gISF0aGlzLnN0YXRlLnN0YXJ0RGF0ZTtcbiAgfVxuXG4gIHRyaWdnZXJTZWxlY3RIYXNEaXNhYmxlRGF0ZSA9IChkYXRlOiBEYXRlW10pID0+IHtcbiAgICB0aGlzLnRyaWdnZXJDbGVhcigpO1xuICAgIGlmICh0aGlzLm9uU2VsZWN0SGFzRGlzYWJsZURhdGUpIHtcbiAgICAgIHRoaXMub25TZWxlY3RIYXNEaXNhYmxlRGF0ZS5lbWl0KGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIG9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHNob3dUaW1lUGlja2VyOiBmYWxzZSxcbiAgICAgIHRpbWVQaWNrZXJUaXRsZTogJycsXG4gICAgICBzdGFydERhdGU6IHVuZGVmaW5lZCxcbiAgICAgIGVuZERhdGU6IHVuZGVmaW5lZCxcbiAgICAgIGRpc0NvbmZpcm1CdG46IHRydWUsXG4gICAgICBjbGllbnRIaWdodDogMFxuICAgIH0gYXMgQ2FsZW5kYXJTdGF0ZVR5cGU7XG4gICAgdGhpcy5zaG93Q2xlYXIgPSAhIXRoaXMuc3RhdGUuc3RhcnREYXRlO1xuICB9XG5cbiAgdHJpZ2dlckNvbmZpcm0gPSAoKSA9PiB7XG4gICAgY29uc3QgeyBzdGFydERhdGUsIGVuZERhdGUgfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKHN0YXJ0RGF0ZSAmJiBlbmREYXRlICYmICtzdGFydERhdGUgPiArZW5kRGF0ZSkge1xuICAgICAgdGhpcy5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gdGhpcy5vbkNvbmZpcm0gJiYgdGhpcy5vbkNvbmZpcm0uZW1pdCh7IHN0YXJ0RGF0ZTogZW5kRGF0ZSwgZW5kRGF0ZTogc3RhcnREYXRlIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5vbkNvbmZpcm0pIHtcbiAgICAgIHRoaXMub25Db25maXJtLmVtaXQoeyBzdGFydERhdGUsIGVuZERhdGUgfSk7XG4gICAgfVxuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgdHJpZ2dlckNhbmNlbCgpIHtcbiAgICBpZiAodGhpcy5wcm9wcy5vbkNhbmNlbCkge1xuICAgICAgdGhpcy5wcm9wcy5vbkNhbmNlbCgpO1xuICAgIH1cbiAgICB0aGlzLm9uQ2xvc2UoKTtcbiAgICBpZiAodGhpcy5vbkNhbmNlbCkge1xuICAgICAgdGhpcy5vbkNhbmNlbC5lbWl0KCk7XG4gICAgfVxuICB9XG5cbiAgdHJpZ2dlckNsZWFyID0gKCkgPT4ge1xuICAgIC8vIOa4hemZpOaVsOaNruWBmuW7tui/n++8jOWQpuWImeWQjOatpeWIt+aWsOaVsOaNruWvvOiHtOaKpemUmVxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgLi4ueyBzdGFydERhdGU6IHVuZGVmaW5lZCwgZW5kRGF0ZTogdW5kZWZpbmVkLCBzaG93VGltZVBpY2tlcjogZmFsc2UgfVxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLnByb3BzLm9uQ2xlYXIpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNsZWFyKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNob3dDbGVhciA9ICEhdGhpcy5zdGF0ZS5zdGFydERhdGU7XG4gICAgfSwgMCk7XG4gIH1cblxuICBvblRpbWVDaGFuZ2UgPSAoZGF0ZTogRGF0ZSkgPT4ge1xuICAgIGNvbnN0IHsgc3RhcnREYXRlLCBlbmREYXRlIH0gPSB0aGlzLnN0YXRlO1xuICAgIGlmIChlbmREYXRlKSB7XG4gICAgICB0aGlzLnN0YXRlLmVuZERhdGUgPSBkYXRlO1xuICAgIH0gZWxzZSBpZiAoc3RhcnREYXRlKSB7XG4gICAgICB0aGlzLnN0YXRlLnN0YXJ0RGF0ZSA9IGRhdGU7XG4gICAgfVxuICB9XG5cbiAgc2hvcnRjdXRTZWxlY3QgPSAoc3RhcnREYXRlOiBEYXRlLCBlbmREYXRlOiBEYXRlLCBwcm9wcyA9IHRoaXMucHJvcHMpID0+IHtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgIC4uLnsgc3RhcnREYXRlLCBzaG93VGltZVBpY2tlcjogZmFsc2UgfSxcbiAgICAgIC4uLnRoaXMuc2VsZWN0RGF0ZShlbmREYXRlLCB0cnVlLCB7IHN0YXJ0RGF0ZSB9LCBwcm9wcylcbiAgICB9O1xuICAgIHRoaXMuc2hvd0NsZWFyID0gISF0aGlzLnN0YXRlLnN0YXJ0RGF0ZTtcbiAgfVxuXG4gIHNldENsaWVudEhlaWdodCA9IChoZWlnaHQ6IG51bWJlcikgPT4ge1xuICAgIHRoaXMuc3RhdGUuY2xpZW50SGlnaHQgPSBoZWlnaHQ7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSB0aGlzLnByb3BzLmRlZmF1bHRWYWx1ZTtcbiAgICBpZiAoZGVmYXVsdFZhbHVlKSB7XG4gICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgICAuLi50aGlzLnNlbGVjdERhdGUoZGVmYXVsdFZhbHVlWzFdLCB0cnVlLCB7IHN0YXJ0RGF0ZTogZGVmYXVsdFZhbHVlWzBdIH0sIHRoaXMucHJvcHMpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuX2xvY2FsZVByb3ZpZGVyU2VydmljZS5sb2NhbGVDaGFuZ2UucGlwZSh0YWtlVW50aWwodGhpcy5fdW5zdWJzY3JpYmUkKSkuc3Vic2NyaWJlKF8gPT4ge1xuICAgICAgdGhpcy5wcm9wcy5sb2NhbGUgPSB7IC4uLnRoaXMuX2xvY2FsZVByb3ZpZGVyU2VydmljZS5nZXRMb2NhbGVTdWJPYmooJ0NhbGVuZGFyJykgfSBhcyBEYXRlTW9kZWxzLkxvY2FsZTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3Vuc3Vic2NyaWJlJC5uZXh0KCk7XG4gICAgdGhpcy5fdW5zdWJzY3JpYmUkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwcml2YXRlIG9uQ2hhbmdlRm46IChkYXRlOiBEYXRlIHwgQXJyYXk8RGF0ZT4pID0+IHZvaWQgPSAoKSA9PiB7fTtcbiAgcHJpdmF0ZSBvblRvdWNoRm46IChkYXRlOiBEYXRlIHwgQXJyYXk8RGF0ZT4pID0+IHZvaWQgPSAoKSA9PiB7fTtcbn1cbiJdfQ==