UNPKG

ng-zorro-antd-mobile

Version:

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

744 lines 58.6 kB
/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import * as tslib_1 from "tslib";
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;
}
var CalendarComponent = /** @class */ (function () {
    function CalendarComponent(_localeProviderService) {
        var _this = this;
        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 {?}
         */
        function (date, useDateTime, oldState, props) {
            if (useDateTime === void 0) { useDateTime = false; }
            if (oldState === void 0) { oldState = {}; }
            if (props === void 0) { props = _this.props; }
            if (!date) {
                return (/** @type {?} */ ({}));
            }
            /** @type {?} */
            var newState = (/** @type {?} */ ({}));
            var type = props.type, pickTime = props.pickTime, defaultTimeValue = props.defaultTimeValue, _a = props.locale, locale = _a === void 0 ? (/** @type {?} */ ({})) : _a;
            /** @type {?} */
            var newDate = pickTime && !useDateTime ? mergeDateTime(date, defaultTimeValue) : date;
            var startDate = oldState.startDate, endDate = oldState.endDate;
            switch (type) {
                case 'one':
                    newState = tslib_1.__assign({}, newState, { startDate: newDate, disConfirmBtn: false });
                    if (pickTime) {
                        newState = tslib_1.__assign({}, newState, { timePickerTitle: locale.selectTime, showTimePicker: true });
                    }
                    break;
                case 'range':
                    if (!startDate || endDate) {
                        newState = tslib_1.__assign({}, newState, { startDate: newDate, endDate: undefined, disConfirmBtn: true });
                        if (pickTime) {
                            newState = tslib_1.__assign({}, newState, { timePickerTitle: locale.selectStartTime, showTimePicker: true });
                        }
                    }
                    else {
                        newState = tslib_1.__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 {?}
         */
        function (date) {
            var _a = _this.state, startDate = _a.startDate, endDate = _a.endDate;
            var onSelect = _this.props.onSelect;
            if (onSelect) {
                /** @type {?} */
                var value = onSelect(date, [startDate, endDate]);
                if (value) {
                    _this.shortcutSelect(value[0], value[1]);
                    return;
                }
            }
            _this.state = tslib_1.__assign({}, _this.state, _this.selectDate(date, false, { startDate: startDate, endDate: endDate }));
            _this.showClear = !!_this.state.startDate;
        });
        this.triggerSelectHasDisableDate = (/**
         * @param {?} date
         * @return {?}
         */
        function (date) {
            _this.triggerClear();
            if (_this.onSelectHasDisableDate) {
                _this.onSelectHasDisableDate.emit(date);
            }
        });
        this.onClose = (/**
         * @return {?}
         */
        function () {
            _this.state = (/** @type {?} */ ({
                showTimePicker: false,
                timePickerTitle: '',
                startDate: undefined,
                endDate: undefined,
                disConfirmBtn: true,
                clientHight: 0
            }));
            _this.showClear = !!_this.state.startDate;
        });
        this.triggerConfirm = (/**
         * @return {?}
         */
        function () {
            var _a = _this.state, startDate = _a.startDate, endDate = _a.endDate;
            if (startDate && endDate && +startDate > +endDate) {
                _this.onClose();
                return _this.onConfirm && _this.onConfirm.emit({ startDate: endDate, endDate: startDate });
            }
            if (_this.onConfirm) {
                _this.onConfirm.emit({ startDate: startDate, endDate: endDate });
            }
            _this.onClose();
        });
        this.triggerClear = (/**
         * @return {?}
         */
        function () {
            // 清除数据做延迟,否则同步刷新数据导致报错
            setTimeout((/**
             * @return {?}
             */
            function () {
                _this.state = tslib_1.__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 {?}
         */
        function (date) {
            var _a = _this.state, startDate = _a.startDate, endDate = _a.endDate;
            if (endDate) {
                _this.state.endDate = date;
            }
            else if (startDate) {
                _this.state.startDate = date;
            }
        });
        this.shortcutSelect = (/**
         * @param {?} startDate
         * @param {?} endDate
         * @param {?=} props
         * @return {?}
         */
        function (startDate, endDate, props) {
            if (props === void 0) { props = _this.props; }
            _this.state = tslib_1.__assign({}, _this.state, { startDate: startDate, showTimePicker: false }, _this.selectDate(endDate, true, { startDate: startDate }, props));
            _this.showClear = !!_this.state.startDate;
        });
        this.setClientHeight = (/**
         * @param {?} height
         * @return {?}
         */
        function (height) {
            _this.state.clientHight = height;
        });
        this.onChangeFn = (/**
         * @return {?}
         */
        function () { });
        this.onTouchFn = (/**
         * @return {?}
         */
        function () { });
    }
    Object.defineProperty(CalendarComponent.prototype, "locale", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            if (value === 'enUS') {
                this.props.locale = enUS;
            }
            else if (value === 'zhCN') {
                this.props.locale = zhCN;
            }
            this._unsubscribe$.next();
            this._unsubscribe$.complete();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "defaultTimeValue", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            if (value) {
                this.props.defaultTimeValue = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "prefixCls", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            if (value) {
                this.props.prefixCls = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "enterDirection", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this._enterDirection = value;
            if (this._enterDirection === 'horizontal') {
                this.contentAnimateClass = 'slideH-enter slideH-enter-active';
            }
            else {
                this.contentAnimateClass = 'slideV-enter slideV-enter-active';
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "visible", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            var _this = this;
            this.props.visible = value;
            if (value === true || value === 'true') {
                this.showAnimation();
                this.isShow = true;
            }
            else {
                this.hideAnimation();
                setTimeout((/**
                 * @return {?}
                 */
                function () {
                    _this.isShow = false;
                }), 300);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "getDateExtra", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.getDateExtra = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "defaultDate", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.defaultDate = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "minDate", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.minDate = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "maxDate", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.maxDate = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "pickTime", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.pickTime = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "type", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.type = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "showShortcut", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.showShortcut = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "rowSize", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.rowSize = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "infinite", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) { },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "defaultValue", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.defaultValue = value;
            if (value) {
                this.receiveProps(this.props);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CalendarComponent.prototype, "onSelect", {
        set: /**
         * @param {?} value
         * @return {?}
         */
        function (value) {
            this.props.onSelect = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @param {?} value
     * @return {?}
     */
    CalendarComponent.prototype.writeValue = /**
     * @param {?} value
     * @return {?}
     */
    function (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 {?}
     */
    CalendarComponent.prototype.registerOnChange = /**
     * @param {?} fn
     * @return {?}
     */
    function (fn) {
        this.onChangeFn = fn;
    };
    /**
     * @param {?} fn
     * @return {?}
     */
    CalendarComponent.prototype.registerOnTouched = /**
     * @param {?} fn
     * @return {?}
     */
    function (fn) {
        this.onTouchFn = fn;
    };
    /**
     * @param {?} nextProps
     * @return {?}
     */
    CalendarComponent.prototype.receiveProps = /**
     * @param {?} nextProps
     * @return {?}
     */
    function (nextProps) {
        if (nextProps.visible && nextProps.defaultValue) {
            this.shortcutSelect(nextProps.defaultValue[0], nextProps.defaultValue[1], nextProps);
        }
    };
    /**
     * @return {?}
     */
    CalendarComponent.prototype.showAnimation = /**
     * @return {?}
     */
    function () {
        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 {?}
     */
    CalendarComponent.prototype.hideAnimation = /**
     * @return {?}
     */
    function () {
        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 {?}
     */
    CalendarComponent.prototype.writeModelData = /**
     * @param {?} date
     * @return {?}
     */
    function (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 {?}
     */
    CalendarComponent.prototype.triggerCancel = /**
     * @return {?}
     */
    function () {
        if (this.props.onCancel) {
            this.props.onCancel();
        }
        this.onClose();
        if (this.onCancel) {
            this.onCancel.emit();
        }
    };
    /**
     * @return {?}
     */
    CalendarComponent.prototype.ngOnInit = /**
     * @return {?}
     */
    function () {
        var _this = this;
        /** @type {?} */
        var defaultValue = this.props.defaultValue;
        if (defaultValue) {
            this.state = tslib_1.__assign({}, this.state, this.selectDate(defaultValue[1], true, { startDate: defaultValue[0] }, this.props));
        }
        this._localeProviderService.localeChange.pipe(takeUntil(this._unsubscribe$)).subscribe((/**
         * @param {?} _
         * @return {?}
         */
        function (_) {
            _this.props.locale = (/** @type {?} */ (tslib_1.__assign({}, _this._localeProviderService.getLocaleSubObj('Calendar'))));
        }));
    };
    /**
     * @return {?}
     */
    CalendarComponent.prototype.ngOnDestroy = /**
     * @return {?}
     */
    function () {
        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 {?}
                             */
                            function () { return CalendarComponent; })), multi: true }]
                }] }
    ];
    /** @nocollapse */
    CalendarComponent.ctorParameters = function () { return [
        { type: LocaleProviderService }
    ]; };
    CalendarComponent.propDecorators = {
        datepicker: [{ type: ViewChild, args: [CalendarDatePickerComponent,] }],
        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',] }]
    };
    return CalendarComponent;
}());
export { CalendarComponent };
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC1tb2JpbGUvIiwic291cmNlcyI6WyJjYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFHVixpQkFBaUIsRUFDakIsS0FBSyxFQUNMLE1BQU0sRUFDTixXQUFXLEVBQ1gsWUFBWSxFQUNaLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxJQUFJLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEMsT0FBTyxJQUFJLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDbkYsT0FBTyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7QUFJL0IsdUNBT0M7OztJQU5DLDJDQUF3Qjs7SUFDeEIsNENBQXlCOztJQUN6QixzQ0FBaUI7O0lBQ2pCLG9DQUFlOztJQUNmLDBDQUF3Qjs7SUFDeEIsd0NBQXFCOztBQUd2QjtJQWdKRSwyQkFBb0Isc0JBQTZDO1FBQWpFLGlCQUFxRTtRQUFqRCwyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXVCO1FBeklqRSxXQUFNLEdBQVksS0FBSyxDQUFDO1FBR3hCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IsZUFBVSxHQUFhLFVBQVUsQ0FBQztRQUVsQyxVQUFLLEdBQUcsbUJBQUE7WUFDTixPQUFPLEVBQUUsS0FBSztZ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LFNBQUMsT0FBTzs7SUF3UnRCLHdCQUFDO0NBQUEsQUFyYUQsSUFxYUM7U0EvWlksaUJBQWlCOzs7SUFDNUIsbUNBQXdCOztJQUN4QixnREFBNEI7O0lBQzVCLDZDQUF5Qjs7SUFDekIsc0NBQTJCOztJQUMzQix1Q0FBa0M7O0lBRWxDLGtDQVN1Qjs7SUFFdkIsa0NBT3VCOzs7OztJQUV2QiwwQ0FBNEM7Ozs7O0lBQzVDLDRDQUFnQzs7Ozs7SUFDaEMsMkNBQStCOzs7OztJQUMvQiw0Q0FBNkI7Ozs7O0lBQzdCLDJDQUFtQzs7SUFFbkMsdUNBQ3dDOztJQThGeEMscUNBQ3NEOztJQUN0RCxzQ0FDdUQ7O0lBQ3ZELG1EQUNvRTs7SUFFcEUsa0NBQzhCOztJQTZEOUIsdUNBZ0VDOztJQW9DRCwyQ0FrQkM7O0lBRUQsd0RBS0M7O0lBRUQsb0NBVUM7O0lBRUQsMkNBVUM7O0lBWUQseUNBWUM7O0lBRUQseUNBT0M7O0lBRUQsMkNBT0M7O0lBRUQsNENBRUM7Ozs7O0lBcUJELHVDQUFrRTs7Ozs7SUFDbEUsc0NBQWlFOzs7OztJQXBSckQsbURBQXFEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBPbkluaXQsXG4gIE9uRGVzdHJveSxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEhvc3RCaW5kaW5nLFxuICBFdmVudEVtaXR0ZXIsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IERhdGVNb2RlbHMgfSBmcm9tICcuL2RhdGUvRGF0YVR5cGVzJztcbmltcG9ydCB6aENOIGZyb20gJy4vbG9jYWxlL3poX0NOJztcbmltcG9ydCBlblVTIGZyb20gJy4vbG9jYWxlL2VuX1VTJztcbmltcG9ydCB7IENhbGVuZGFyUHJvcHNUeXBlIH0gZnJvbSAnLi9jYWxlbmRhci5wcm9wcy5jb21wb25lbnQnO1xuaW1wb3J0IHsgTG9jYWxlUHJvdmlkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vbG9jYWxlLXByb3ZpZGVyL2xvY2FsZS1wcm92aWRlci5zZXJ2aWNlJztcbmltcG9ydCB7IG1lcmdlRGF0ZVRpbWUsIGlzU2FtZURhdGUgfSBmcm9tICcuL3V0aWwvaW5kZXgnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ2FsZW5kYXJEYXRlUGlja2VyQ29tcG9uZW50IH0gZnJvbSAnLi9kYXRlcGlja2VyL2RhdGVwaWNrZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IHsgQ2FsZW5kYXJQcm9wc1R5cGUgfTtcblxuZXhwb3J0IGludGVyZmFjZSBDYWxlbmRhclN0YXRlVHlwZSB7XG4gIHNob3dUaW1lUGlja2VyOiBib29sZWFuO1xuICB0aW1lUGlja2VyVGl0bGU/OiBzdHJpbmc7XG4gIHN0YXJ0RGF0ZT86IERhdGU7XG4gIGVuZERhdGU/OiBEYXRlO1xuICBkaXNDb25maXJtQnRuPzogYm9vbGVhbjtcbiAgY2xpZW50SGlnaHQ/OiBudW1iZXI7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ0NhbGVuZGFyLCBuem0tY2FsZW5kYXInLFxuICB0ZW1wbGF0ZVVybDogJy4vY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLCB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBDYWxlbmRhckNvbXBvbmVudCksIG11bHRpOiB0cnVlIH1dXG59KVxuZXhwb3J0IGNsYXNzIENhbGVuZGFyQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgaXNTaG93OiBib29sZWFuID0gZmFsc2U7XG4gIGNvbnRlbnRBbmltYXRlQ2xhc3M6IHN0cmluZztcbiAgbWFza0FuaW1hdGVDbGFzczogc3RyaW5nO1xuICBzaG93Q2xlYXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNTYW1lRGF0ZTogRnVuY3Rpb24gPSBpc1NhbWVEYXRlO1xuXG4gIHByb3BzID0ge1xuICAgIHZpc2libGU6IGZhbHNlLFxuICAgIHNob3dIZWFkZXI6IHRydWUsXG4gICAgbG9jYWxlOiB6aENOLFxuICAgIHBpY2tUaW1lOiBmYWxzZSxcbiAgICBzaG93U2hvcnRjdXQ6IGZhbHNlLFxuICAgIHByZWZpeENsczogJ3JtYy1jYWxlbmRhcicsXG4gICAgdHlwZTogJ3JhbmdlJyxcbiAgICBkZWZhdWx0VGltZVZhbHVlOiBuZXcgRGF0ZSgyMDAwLCAwLCAxLCA4KVxuICB9IGFzIENhbGVuZGFyUHJvcHNUeXBlO1xuXG4gIHN0YXRlID0ge1xuICAgIHNob3dUaW1lUGlja2VyOiBmYWxzZSxcbiAgICB0aW1lUGlja2VyVGl0bGU6ICcnLFxuICAgIHN0YXJ0RGF0ZTogdW5kZWZpbmVkLFxuICAgIGVuZERhdGU6IHVuZGVmaW5lZCxcbiAgICBkaXNDb25maXJtQnRuOiB0cnVlLFxuICAgIGNsaWVudEhpZ2h0OiAwXG4gIH0gYXMgQ2FsZW5kYXJTdGF0ZVR5cGU7XG5cbiAgcHJpdmF0ZSBfdW5zdWJzY3JpYmUkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfZW50ZXJEaXJlY3Rpb246IHN0cmluZztcbiAgcHJpdmF0ZSBfZGF0ZU1vZGVsVHlwZTogbnVtYmVyO1xuICBwcml2YXRlIF9kYXRlTW9kZWxWYWx1ZTogYW55O1xuICBwcml2YXRlIF9kYXRlTW9kZWxUaW1lOiBudW1iZXIgPSAwO1xuXG4gIEBWaWV3Q2hpbGQoQ2FsZW5kYXJEYXRlUGlja2VyQ29tcG9uZW50KVxuICBkYXRlcGlja2VyOiBDYWxlbmRhckRhdGVQaWNrZXJDb21wb25lbnQ7XG5cbiAgQElucHV0KClcbiAgc2V0IGxvY2FsZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gJ2VuVVMnKSB7XG4gICAgICB0aGlzLnByb3BzLmxvY2FsZSA9IGVuVVM7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ3poQ04nKSB7XG4gICAgICB0aGlzLnByb3BzLmxvY2FsZSA9IHpoQ047XG4gICAgfVxuXG4gICAgdGhpcy5fdW5zdWJzY3JpYmUkLm5leHQoKTtcbiAgICB0aGlzLl91bnN1YnNjcmliZSQuY29tcGxldGUoKTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgZGVmYXVsdFRpbWVWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5wcm9wcy5kZWZhdWx0VGltZVZhbHVlID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBwcmVmaXhDbHModmFsdWUpIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMucHJvcHMucHJlZml4Q2xzID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBlbnRlckRpcmVjdGlvbih2YWx1ZSkge1xuICAgIHRoaXMuX2VudGVyRGlyZWN0aW9uID0gdmFsdWU7XG4gICAgaWYgKHRoaXMuX2VudGVyRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZUgtZW50ZXIgc2xpZGVILWVudGVyLWFjdGl2ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZVYtZW50ZXIgc2xpZGVWLWVudGVyLWFjdGl2ZSc7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIHNldCB2aXNpYmxlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy52aXNpYmxlID0gdmFsdWU7XG4gICAgaWYgKHZhbHVlID09PSB0cnVlIHx8IHZhbHVlID09PSAndHJ1ZScpIHtcbiAgICAgIHRoaXMuc2hvd0FuaW1hdGlvbigpO1xuICAgICAgdGhpcy5pc1Nob3cgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhpZGVBbmltYXRpb24oKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmlzU2hvdyA9IGZhbHNlO1xuICAgICAgfSwgMzAwKTtcbiAgICB9XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IGdldERhdGVFeHRyYSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMuZ2V0RGF0ZUV4dHJhID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IGRlZmF1bHREYXRlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5kZWZhdWx0RGF0ZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBtaW5EYXRlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5taW5EYXRlID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IG1heERhdGUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLm1heERhdGUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgcGlja1RpbWUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLnBpY2tUaW1lID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHR5cGUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLnR5cGUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgc2hvd1Nob3J0Y3V0KHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5zaG93U2hvcnRjdXQgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgcm93U2l6ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMucm93U2l6ZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBpbmZpbml0ZSh2YWx1ZSkge31cbiAgQElucHV0KClcbiAgc2V0IGRlZmF1bHRWYWx1ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMuZGVmYXVsdFZhbHVlID0gdmFsdWU7XG5cbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMucmVjZWl2ZVByb3BzKHRoaXMucHJvcHMpO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgb25TZWxlY3QodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLm9uU2VsZWN0ID0gdmFsdWU7XG4gIH1cblxuICBAT3V0cHV0KClcbiAgb25DYW5jZWw6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKVxuICBvbkNvbmZpcm06IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKVxuICBvblNlbGVjdEhhc0Rpc2FibGVEYXRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBIb3N0QmluZGluZygnY2xhc3MnKVxuICBjbGFzczogc3RyaW5nID0gJ2FtLWNhbGVuZGFyJztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9sb2NhbGVQcm92aWRlclNlcnZpY2U6IExvY2FsZVByb3ZpZGVyU2VydmljZSkge31cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBEYXRlIHwgQXJyYXk8RGF0ZT4gfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5fZGF0ZU1vZGVsVHlwZSA9IG51bGw7XG4gICAgaWYgKHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignW25nLXpvcnJvLWFudGQtbW9iaWxlXTogY2FsZW5kYXIgbmdNb2RlbCBhcnJheSBuZWVkIHBhcmFtcyEnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucHJvcHMudHlwZSA9PT0gJ29uZScgJiYgdmFsdWUubGVuZ3RoID49IDIpIHtcbiAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVHlwZSA9IDE7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tuZy16b3Jyby1hbnRkLW1vYmlsZV06IHR5cGUgaXMgb25lLCBidXQgbmdtb2RlbCBoYXMgbW9yZSB0aGFuIG9uZSBwYXJhbSwganVzdCB1c2UgZmlyc3Qgb25lJyk7XG4gICAgICAgIHRoaXMub25TZWxlY3RlZERhdGUodmFsdWVbMF0pO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVHlwZSA9IDE7XG4gICAgICAgIHRoaXMub25TZWxlY3RlZERhdGUodmFsdWVbMF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVHlwZSA9IDI7XG4gICAgICAgIHRoaXMub25TZWxlY3RlZERhdGUodmFsdWVbMF0pO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzFdKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgdGhpcy5fZGF0ZU1vZGVsVHlwZSA9IDM7XG4gICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoZGF0ZTogRGF0ZSB8IEFycmF5PERhdGU+KSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZUZuID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaEZuID0gZm47XG4gIH1cblxuICByZWNlaXZlUHJvcHMobmV4dFByb3BzOiBDYWxlbmRhclByb3BzVHlwZSkge1xuICAgIGlmIChuZXh0UHJvcHMudmlzaWJsZSAmJiBuZXh0UHJvcHMuZGVmYXVsdFZhbHVlKSB7XG4gICAgICB0aGlzLnNob3J0Y3V0U2VsZWN0KG5leHRQcm9wcy5kZWZhdWx0VmFsdWVbMF0sIG5leHRQcm9wcy5kZWZhdWx0VmFsdWVbMV0sIG5leHRQcm9wcyk7XG4gICAgfVxuICB9XG5cbiAgc2hvd0FuaW1hdGlvbigpIHtcbiAgICBpZiAodGhpcy5fZW50ZXJEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgdGhpcy5jb250ZW50QW5pbWF0ZUNsYXNzID0gJ3NsaWRlSC1lbnRlciBzbGlkZUgtZW50ZXItYWN0aXZlJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250ZW50QW5pbWF0ZUNsYXNzID0gJ3NsaWRlVi1lbnRlciBzbGlkZVYtZW50ZXItYWN0aXZlJztcbiAgICB9XG4gICAgdGhpcy5tYXNrQW5pbWF0ZUNsYXNzID0gJ2ZhZGUtZW50ZXIgZmFkZS1lbnRlci1hY3RpdmUnO1xuICB9XG5cbiAgaGlkZUFuaW1hdGlvbigpIHtcbiAgICBpZiAodGhpcy5fZW50ZXJEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgdGhpcy5jb250ZW50QW5pbWF0ZUNsYXNzID0gJ3NsaWRlSC1sZWF2ZSBzbGlkZUgtbGVhdmUtYWN0aXZlJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250ZW50QW5pbWF0ZUNsYXNzID0gJ3NsaWRlVi1sZWF2ZSBzbGlkZVYtbGVhdmUtYWN0aXZlJztcbiAgICB9XG4gICAgdGhpcy5tYXNrQW5pbWF0ZUNsYXNzID0gJ2ZhZGUtbGVhdmUgZmFkZS1sZWF2ZS1hY3RpdmUnO1xuICB9XG5cbiAgc2VsZWN0RGF0ZSA9IChcbiAgICBkYXRlOiBEYXRlLFxuICAgIHVzZURhdGVUaW1lID0gZmFsc2UsXG4gICAgb2xkU3RhdGU6IHsgc3RhcnREYXRlPzogRGF0ZTsgZW5kRGF0ZT86IERhdGUgfSA9IHt9LFxuICAgIHByb3BzID0gdGhpcy5wcm9wc1xuICApID0+IHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHJldHVybiB7fSBhcyBDYWxlbmRhclN0YXRlVHlwZTtcbiAgICB9XG4gICAgbGV0IG5ld1N0YXRlID0ge30gYXMgQ2FsZW5kYXJTdGF0ZVR5cGU7XG4gICAgY29uc3QgeyB0eXBlLCBwaWNrVGltZSwgZGVmYXVsdFRpbWVWYWx1ZSwgbG9jYWxlID0ge30gYXMgRGF0ZU1vZGVscy5Mb2NhbGUgfSA9IHByb3BzO1xuICAgIGNvbnN0IG5ld0RhdGUgPSBwaWNrVGltZSAmJiAhdXNlRGF0ZVRpbWUgPyBtZXJnZURhdGVUaW1lKGRhdGUsIGRlZmF1bHRUaW1lVmFsdWUpIDogZGF0ZTtcbiAgICBjb25zdCB7IHN0YXJ0RGF0ZSwgZW5kRGF0ZSB9ID0gb2xkU3RhdGU7XG5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ29uZSc6XG4gICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgIC4uLm5ld1N0YXRlLFxuICAgICAgICAgIHN0YXJ0RGF0ZTogbmV3RGF0ZSxcbiAgICAgICAgICBkaXNDb25maXJtQnRuOiBmYWxzZVxuICAgICAgICB9O1xuICAgICAgICBpZiAocGlja1RpbWUpIHtcbiAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgIC4uLm5ld1N0YXRlLFxuICAgICAgICAgICAgdGltZVBpY2tlclRpdGxlOiBsb2NhbGUuc2VsZWN0VGltZSxcbiAgICAgICAgICAgIHNob3dUaW1lUGlja2VyOiB0cnVlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAncmFuZ2UnOlxuICAgICAgICBpZiAoIXN0YXJ0RGF0ZSB8fCBlbmREYXRlKSB7XG4gICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgIHN0YXJ0RGF0ZTogbmV3RGF0ZSxcbiAgICAgICAgICAgIGVuZERhdGU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGRpc0NvbmZpcm1CdG46IHRydWVcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmIChwaWNrVGltZSkge1xuICAgICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAgIC4uLm5ld1N0YXRlLFxuICAgICAgICAgICAgICB0aW1lUGlja2VyVGl0bGU6IGxvY2FsZS5zZWxlY3RTdGFydFRpbWUsXG4gICAgICAgICAgICAgIHNob3dUaW1lUGlja2VyOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgIC4uLm5ld1N0YXRlLFxuICAgICAgICAgICAgdGltZVBpY2tlclRpdGxlOlxuICAgICAgICAgICAgICArbmV3RGF0ZSA+PSArc3RhcnREYXRlIHx8IHRoaXMuaXNTYW1lRGF0ZShzdGFydERhdGUsIG5ld0RhdGUpXG4gICAgICAgICAgICAgICAgPyBsb2NhbGUuc2VsZWN0RW5kVGltZVxuICAgICAgICAgICAgICAgIDogbG9jYWxlLnNlbGVjdFN0YXJ0VGltZSxcbiAgICAgICAgICAgIGRpc0NvbmZpcm1CdG46IGZhbHNlLFxuICAgICAgICAgICAgZW5kRGF0ZTpcbiAgICAgICAgICAgICAgcGlja1RpbWUgJiYgIXVzZURhdGVUaW1lICYmICgrbmV3RGF0ZSA+PSArc3RhcnREYXRlIHx8IHRoaXMuaXNTYW1lRGF0ZShzdGFydERhdGUsIG5ld0RhdGUpKVxuICAgICAgICAgICAgICAgID8gbmV3IERhdGUoK21lcmdlRGF0ZVRpbWUobmV3RGF0ZSwgc3RhcnREYXRlKSArIDM2MDAwMDApXG4gICAgICAgICAgICAgICAgOiBuZXdEYXRlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLndyaXRlTW9kZWxEYXRhKGRhdGUpO1xuICAgIHJldHVybiBuZXdTdGF0ZTtcbiAgfVxuXG4gIHdyaXRlTW9kZWxEYXRhKGRhdGUpIHtcbiAgICBpZiAodGhpcy5fZGF0ZU1vZGVsVmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgdGhpcy5fZGF0ZU1vZGVsVGltZSA9IHRoaXMuX2RhdGVNb2RlbFZhbHVlLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGF0ZU1vZGVsVGltZSA9IDA7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLl9kYXRlTW9kZWxUeXBlKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlID0gW2RhdGVdO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlRm4odGhpcy5fZGF0ZU1vZGVsVmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaWYgKHRoaXMuX2RhdGVNb2RlbFRpbWUgPT09IDEpIHtcbiAgICAgICAgICBpZiAoK2RhdGUgPCArdGhpcy5fZGF0ZU1vZGVsVmFsdWVbMF0pIHtcbiAgICAgICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlLnVuc2hpZnQoZGF0ZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlLnB1c2goZGF0ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMub25DaGFuZ2VGbih0aGlzLl9kYXRlTW9kZWxWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUgPSBbXTtcbiAgICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZS5wdXNoKGRhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZSA9IGRhdGU7XG4gICAgICAgIHRoaXMub25DaGFuZ2VGbih0aGlzLl9kYXRlTW9kZWxWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgb25TZWxlY3RlZERhdGUgPSAoZGF0ZTogRGF0ZSkgPT4ge1xuICAgIGNvbnN0IHsgc3RhcnREYXRlLCBlbmREYXRlIH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IHsgb25TZWxlY3QgfSA9IHRoaXMucHJvcHM7XG5cbiAgICBpZiAob25TZWxlY3QpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gb25TZWxlY3QoZGF0ZSwgW3N0YXJ0RGF0ZSwgZW5kRGF0ZV0pO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2hvcnRjdXRTZWxlY3QodmFsdWVbMF0sIHZhbHVlWzFdKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgLi4udGhpcy5zZWxlY3REYXRlKGRhdGUsIGZhbHNlLCB7IHN0YXJ0RGF0ZSwgZW5kRGF0ZSB9KVxuICAgIH07XG5cbiAgICB0aGlzLnNob3dDbGVhciA9ICEhdGhpcy5zdGF0ZS5zdGFydERhdGU7XG4gIH1cblxuICB0cmlnZ2VyU2VsZWN0SGFzRGlzYWJsZURhdGUgPSAoZGF0ZTogRGF0ZVtdKSA9PiB7XG4gICAgdGhpcy50cmlnZ2VyQ2xlYXIoKTtcbiAgICBpZiAodGhpcy5vblNlbGVjdEhhc0Rpc2FibGVEYXRlKSB7XG4gICAgICB0aGlzLm9uU2VsZWN0SGFzRGlzYWJsZURhdGUuZW1pdChkYXRlKTtcbiAgICB9XG4gIH1cblxuICBvbkNsb3NlID0gKCkgPT4ge1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBzaG93VGltZVBpY2tlcjogZmFsc2UsXG4gICAgICB0aW1lUGlja2VyVGl0bGU6ICcnLFxuICAgICAgc3RhcnREYXRlOiB1bmRlZmluZWQsXG4gICAgICBlbmREYXRlOiB1bmRlZmluZWQsXG4gICAgICBkaXNDb25maXJtQnRuOiB0cnVlLFxuICAgICAgY2xpZW50SGlnaHQ6IDBcbiAgICB9IGFzIENhbGVuZGFyU3RhdGVUeXBlO1xuICAgIHRoaXMuc2hvd0NsZWFyID0gISF0aGlzLnN0YXRlLnN0YXJ0RGF0ZTtcbiAgfVxuXG4gIHRyaWdnZXJDb25maXJtID0gKCkgPT4ge1xuICAgIGNvbnN0IHsgc3RhcnREYXRlLCBlbmREYXRlIH0gPSB0aGlzLnN0YXRlO1xuICAgIGlmIChzdGFydERhdGUgJiYgZW5kRGF0ZSAmJiArc3RhcnREYXRlID4gK2VuZERhdGUpIHtcbiAgICAgIHRoaXMub25DbG9zZSgpO1xuICAgICAgcmV0dXJuIHRoaXMub25Db25maXJtICYmIHRoaXMub25Db25maXJtLmVtaXQoeyBzdGFydERhdGU6IGVuZERhdGUsIGVuZERhdGU6IHN0YXJ0RGF0ZSB9KTtcbiAgICB9XG4gICAgaWYgKHRoaXMub25Db25maXJtKSB7XG4gICAgICB0aGlzLm9uQ29uZmlybS5lbWl0KHsgc3RhcnREYXRlLCBlbmREYXRlIH0pO1xuICAgIH1cbiAgICB0aGlzLm9uQ2xvc2UoKTtcbiAgfVxuXG4gIHRyaWdnZXJDYW5jZWwoKSB7XG4gICAgaWYgKHRoaXMucHJvcHMub25DYW5jZWwpIHtcbiAgICAgIHRoaXMucHJvcHMub25DYW5jZWwoKTtcbiAgICB9XG4gICAgdGhpcy5vbkNsb3NlKCk7XG4gICAgaWYgKHRoaXMub25DYW5jZWwpIHtcbiAgICAgIHRoaXMub25DYW5jZWwuZW1pdCgpO1xuICAgIH1cbiAgfVxuXG4gIHRyaWdnZXJDbGVhciA9ICgpID0+IHtcbiAgICAvLyDmuIXpmaTmlbDmja7lgZrlu7bov5/vvIzlkKbliJnlkIzmraXliLfmlrDmlbDmja7lr7zoh7TmiqXplJlcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgIC4uLnsgc3RhcnREYXRlOiB1bmRlZmluZWQsIGVuZERhdGU6IHVuZGVmaW5lZCwgc2hvd1RpbWVQaWNrZXI6IGZhbHNlIH1cbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5wcm9wcy5vbkNsZWFyKSB7XG4gICAgICAgIHRoaXMucHJvcHMub25DbGVhcigpO1xuICAgICAgfVxuICAgICAgdGhpcy5zaG93Q2xlYXIgPSAhIXRoaXMuc3RhdGUuc3RhcnREYXRlO1xuICAgIH0sIDApO1xuICB9XG5cbiAgb25UaW1lQ2hhbmdlID0gKGRhdGU6IERhdGUpID0+IHtcbiAgICBjb25zdCB7IHN0YXJ0RGF0ZSwgZW5kRGF0ZSB9ID0gdGhpcy5zdGF0ZTtcbiAgICBpZiAoZW5kRGF0ZSkge1xuICAgICAgdGhpcy5zdGF0ZS5lbmREYXRlID0gZGF0ZTtcbiAgICB9IGVsc2UgaWYgKHN0YXJ0RGF0ZSkge1xuICAgICAgdGhpcy5zdGF0ZS5zdGFydERhdGUgPSBkYXRlO1xuICAgIH1cbiAgfVxuXG4gIHNob3J0Y3V0U2VsZWN0ID0gKHN0YXJ0RGF0ZTogRGF0ZSwgZW5kRGF0ZTogRGF0ZSwgcHJvcHMgPSB0aGlzLnByb3BzKSA9PiB7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAuLi57IHN0YXJ0RGF0ZSwgc2hvd1RpbWVQaWNrZXI6IGZhbHNlIH0sXG4gICAgICAuLi50aGlzLnNlbGVjdERhdGUoZW5kRGF0ZSwgdHJ1ZSwgeyBzdGFydERhdGUgfSwgcHJvcHMpXG4gICAgfTtcbiAgICB0aGlzLnNob3dDbGVhciA9ICEhdGhpcy5zdGF0ZS5zdGFydERhdGU7XG4gIH1cblxuICBzZXRDbGllbnRIZWlnaHQgPSAoaGVpZ2h0OiBudW1iZXIpID0+IHtcbiAgICB0aGlzLnN0YXRlLmNsaWVudEhpZ2h0ID0gaGVpZ2h0O1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5wcm9wcy5kZWZhdWx0VmFsdWU7XG4gICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgICAgLi4udGhpcy5zZWxlY3REYXRlKGRlZmF1bHRWYWx1ZVsxXSwgdHJ1ZSwgeyBzdGFydERhdGU6IGRlZmF1bHRWYWx1ZVswXSB9LCB0aGlzLnByb3BzKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2NhbGVQcm92aWRlclNlcnZpY2UubG9jYWxlQ2hhbmdlLnBpcGUodGFrZVVudGlsKHRoaXMuX3Vuc3Vic2NyaWJlJCkpLnN1YnNjcmliZShfID0+IHtcbiAgICAgIHRoaXMucHJvcHMubG9jYWxlID0geyAuLi50aGlzLl9sb2NhbGVQcm92aWRlclNlcnZpY2UuZ2V0TG9jYWxlU3ViT2JqKCdDYWxlbmRhcicpIH0gYXMgRGF0ZU1vZGVscy5Mb2NhbGU7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl91bnN1YnNjcmliZSQubmV4dCgpO1xuICAgIHRoaXMuX3Vuc3Vic2NyaWJlJC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkNoYW5nZUZuOiAoZGF0ZTogRGF0ZSB8IEFycmF5PERhdGU+KSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHByaXZhdGUgb25Ub3VjaEZuOiAoZGF0ZTogRGF0ZSB8IEFycmF5PERhdGU+KSA9PiB2b2lkID0gKCkgPT4ge307XG59XG4iXX0=