UNPKG

@duoduo-oba/ng-devui

Version:

DevUI components based on Angular

740 lines 62.8 kB
/** * @fileoverview added by tsickle * Generated from: date-range-picker.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { Component, forwardRef, Input, Output, EventEmitter, ElementRef, ViewContainerRef, Renderer2, HostListener, ViewChild, TemplateRef } from '@angular/core'; import { CdkOverlayOrigin } from '@angular/cdk/overlay'; import { SelectDateRangeChangeReason } from './date-range-change-event-args.model'; import { DatePickerConfigService as DatePickerConfig } from './date-picker.config.service'; import { I18nService } from '@duoduo-oba/ng-devui/i18n'; import { DefaultDateConverter } from '@duoduo-oba/ng-devui/utils'; import { cornerFadeInOut } from '@duoduo-oba/ng-devui/utils'; import { Subject, fromEvent } from 'rxjs'; import { distinctUntilChanged, debounceTime } from 'rxjs/operators'; export class DateRangePickerComponent { /** * @param {?} elementRef * @param {?} viewContainerRef * @param {?} renderer * @param {?} datePickerConfig * @param {?} i18n */ constructor(elementRef, viewContainerRef, renderer, datePickerConfig, i18n) { this.elementRef = elementRef; this.viewContainerRef = viewContainerRef; this.renderer = renderer; this.datePickerConfig = datePickerConfig; this.i18n = i18n; this.selectedRange = [null, null]; this.showTime = false; this.hideOnRangeSelected = false; this.splitter = ' - '; this.selectedRangeChange = new EventEmitter(); this._isOpen = false; this.clickShow = false; this.currentCalendars = [null, null]; this.hoverOnDate = new Subject(); this.datepickerPosition = 'bottom'; this.onChange = (/** * @param {?} _ * @return {?} */ (_) => null); this.onTouched = (/** * @return {?} */ () => null); this.chooseDate = (/** * @param {?} range * @return {?} */ (range) => { this.writeValue(range); this.notifyValueChange(range, SelectDateRangeChangeReason.date); if (!this.showTime && this.hideOnRangeSelected) { this.hide(); } }); this.clearAll = (/** * @return {?} */ () => { this.rangeChange({ selectedRange: [null, null] }); }); this._dateConfig = datePickerConfig['dateConfig']; this.dateConverter = datePickerConfig['dateConfig'].dateConverter || new DefaultDateConverter(); this.inputSub = fromEvent(this.elementRef.nativeElement, 'input') .pipe(debounceTime(300)).subscribe((/** * @param {?} event * @return {?} */ event => { this.transUserInputToDatepicker(event); })); } /** * @param {?} dateConfig * @return {?} */ set dateConfig(dateConfig) { if (dateConfig) { this._dateConfig = dateConfig; this._dateFormat = this.showTime ? dateConfig.format.time : dateConfig.format.date; } else { this._dateConfig = this.datePickerConfig.dateConfig; } } /** * @return {?} */ get dateConfig() { return this._dateConfig; } /** * @param {?} dateFormat * @return {?} */ set dateFormat(dateFormat) { if (this._dateFormat !== dateFormat) { this._dateFormat = dateFormat; } } /** * @return {?} */ get dateFormat() { return this._dateFormat; } /** * @param {?} date * @return {?} */ set maxDate(date) { /** @type {?} */ const parseDate = this.convertDate(date); if (parseDate) { this._maxDate = parseDate; } } /** * @return {?} */ get maxDate() { return this._maxDate; } /** * @param {?} date * @return {?} */ set minDate(date) { /** @type {?} */ const parseDate = this.convertDate(date); if (parseDate) { this._minDate = parseDate; } } /** * @return {?} */ get minDate() { return this._minDate; } /** * @param {?} isOpen * @return {?} */ set isOpen(isOpen) { this._isOpen = isOpen; if (!isOpen && !this.rangeEnd) { this.rangeStart = null; } } /** * @return {?} */ get isOpen() { return this._isOpen; } /** * @return {?} */ ngOnInit() { this._minDate = this.minDate ? new Date(this.minDate) : new Date(this.dateConfig.min, 0, 1, 0, 0, 0); this._maxDate = this.maxDate ? new Date(this.maxDate) : new Date(this.dateConfig.max, 11, 31, 23, 59, 59); this.setI18nText(); this.updateCdkConnectedOverlayOrigin(); this.subscribeHoverActions(); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @param {?} selectedRange * @return {?} */ writeValue(selectedRange) { if (selectedRange) { this.selectedRange = selectedRange; if (Array.isArray(this.selectedRange)) { [this.rangeStart, this.rangeEnd] = this.selectedRange; } this.writeModelValue(selectedRange); } } /** * @return {?} */ setI18nText() { this.i18nLocale = this.i18n.getI18nText().locale; this.i18nSubscription = this.i18n.langChange().subscribe((/** * @param {?} data * @return {?} */ (data) => { this.i18nLocale = data.locale; })); } /** * @param {?} data * @return {?} */ rangeChange(data) { this.chooseDate(data.selectedRange); } /** * @return {?} */ updateCdkConnectedOverlayOrigin() { if (this.elementRef.nativeElement) { this.cdkConnectedOverlayOrigin = new CdkOverlayOrigin(this.elementRef.nativeElement); } } /** * @param {?} $event * @param {?=} clickShow * @return {?} */ toggle($event, clickShow) { this.isOpen = !this.isOpen; this.clickShow = clickShow; } /** * @return {?} */ hide() { this.isOpen = false; } /** * @private * @param {?} input * @return {?} */ writeModelValue(input) { if (Array.isArray(input) && input.every((/** * @param {?} _ * @return {?} */ _ => !!_))) { this.renderer.setProperty(this.elementRef.nativeElement, 'value', this.formatDateRange(input)); } else { this.renderer.setProperty(this.elementRef.nativeElement, 'value', ''); } } /** * @private * @param {?} arr * @return {?} */ formatDateRange(arr) { return arr.map((/** * @param {?} date * @param {?} i * @return {?} */ (date, i) => { return date ? this.dateConverter.format(date, this.dateFormat, this.locale || this.i18nLocale) : ['Start', 'End'][i]; })).join(this.splitter); } /** * @param {?} $event * @return {?} */ onBlur($event) { this.onTouched(); } /** * @param {?} $event * @return {?} */ onDocumentClick($event) { if (this.templateWrap && this.templateWrap.nativeElement.contains($event.target) && !this.hideOnRangeSelected) { this.isOpen = true; } else if (this.elementRef.nativeElement !== $event.target && !this.clickShow) { this.isOpen = false; } else { this.clickShow = false; } } /** * @param {?} position * @return {?} */ onPositionChange(position) { switch (position.connectionPair.overlayY) { case 'top': case 'center': this.datepickerPosition = 'bottom'; break; case 'bottom': this.datepickerPosition = 'top'; } } /** * @param {?} date * @return {?} */ convertDate(date) { return date ? this.dateConverter.parse(date, this.dateFormat, this.locale || this.i18nLocale) : null; } /** * @param {?} event * @return {?} */ selectingDate(event) { this.hoverOnDate.next(event); } /** * @return {?} */ subscribeHoverActions() { this.hoverOnDate.pipe(distinctUntilChanged()).subscribe((/** * @param {?} date * @return {?} */ (date) => { this.previewRangeEnd(date); })); } /** * @param {?} date * @return {?} */ previewRangeEnd(date) { if (date) { this.leftPicker['previewEnd'] = date; this.rightPicker['previewEnd'] = date; } } /** * @param {?} rangeStart * @param {?} picker * @return {?} */ syncRangeStart(rangeStart, picker) { picker.selectRange(rangeStart, true); } /** * @param {?} currentCalender * @param {?} orientation * @return {?} */ syncPickerPair(currentCalender, orientation) { switch (orientation) { case 'left': this.currentCalendars[0] = currentCalender; break; case 'right': this.currentCalendars[1] = currentCalender; break; } } /** * @param {?} range * @param {?=} reason * @return {?} */ notifyValueChange(range, reason) { /** @type {?} */ let currentReason; this.onChange(range); if (reason === undefined) { currentReason = SelectDateRangeChangeReason.time; } else { currentReason = reason; } this.selectedRangeChange.emit({ reason: currentReason, selectedRange: range }); } /** * @return {?} */ consolidateTime() { /** @type {?} */ const rangeStart = this.rangeStart; /** @type {?} */ const rangeEnd = this.rangeEnd; /** @type {?} */ const rangeStartTime = this.leftPicker['currentTime']; /** @type {?} */ const rangeEndTime = this.rightPicker['currentTime']; this.rangeStart = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate(), rangeStartTime.hour, rangeStartTime.minute, rangeStartTime.second); this.rangeEnd = new Date(rangeEnd.getFullYear(), rangeEnd.getMonth(), rangeEnd.getDate(), rangeEndTime.hour, rangeEndTime.minute, rangeEndTime.second); /** @type {?} */ const newRange = [this.rangeStart, this.rangeEnd]; this.onTouched(); this.writeValue(newRange); this.notifyValueChange(newRange, SelectDateRangeChangeReason.button); this.hide(); } /** * @private * @param {?} event * @return {?} */ transUserInputToDatepicker(event) { if (!this.showTime && !this.disabled) { /** @type {?} */ const value = event.target.value; if (!value) { this.clearAll(); return; } /** @type {?} */ let valueList = value.split(this.splitter); /** @type {?} */ let valueFormat; // 如果拆出来6个,则为日期间分隔符和年月日间分隔符相同的情况,此情况允许 if (valueList.length === 6 && valueList.every((/** * @param {?} val * @return {?} */ val => !!val))) { /** @type {?} */ const curValueList = []; valueList.forEach((/** * @param {?} val * @param {?} index * @return {?} */ (val, index) => { // 根据下标,前三个组装在一起,后三个组装在一起,不需要考虑分隔符,后面会format if ((index + 1) % 3 === 1) { curValueList.push(val); } else { curValueList[Math.ceil(index / 3) - 1] = curValueList[Math.ceil(index / 3) - 1] + '-' + val; } })); valueList = curValueList; } // 不管拆出来是6还是2个,都需要组装成2个日期 if (valueList.length === 2 && valueList.every((/** * @param {?} val * @return {?} */ val => !!val))) { if (valueList[0] !== valueList[1]) { // 判断前后两日期是否相等 /** @type {?} */ const valueTimeList = valueList.map((/** * @param {?} val * @return {?} */ val => (new Date(`${val} 00:00:00`)).getTime())); valueFormat = this.formatDateRange(valueList.map((/** * @param {?} numValue * @return {?} */ numValue => new Date(numValue)))); if (value === valueFormat && !valueTimeList.every((/** * @param {?} val * @return {?} */ val => val >= this.minDate.getTime() && val <= this.maxDate.getTime()))) { // 判断前后俩日期是否小于最小或大于最大,若是则不合法,恢复之前的 this.writeValue(this.selectedRange); return; } else { // 判断前后俩日期是否大于最小,小于最大,若是则合法,进行如下操作 // 此时包括value为NaN既日期格式不正确的情况,对其进行处理下方判断会过滤掉 valueList = valueList.map((/** * @param {?} val * @return {?} */ val => new Date(val).getTime())).sort((/** * @param {?} a * @param {?} b * @return {?} */ (a, b) => a - b)).map((/** * @param {?} numValue * @return {?} */ numValue => new Date(numValue))); } } else { // 前后相等的情况下恢复之前的 this.writeValue(this.selectedRange); return; } if (valueFormat && value === valueFormat) { this.chooseDate(valueList); } } } else { this.writeValue(this.selectedRange); } } /** * @return {?} */ ngOnDestroy() { this.hide(); if (this.inputSub) { this.inputSub.unsubscribe(); } if (this.i18nSubscription) { this.i18nSubscription.unsubscribe(); } } } DateRangePickerComponent.decorators = [ { type: Component, args: [{ selector: '[dDateRangePicker]', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => DateRangePickerComponent)), multi: true }], exportAs: 'dateRangePicker', template: ` <ng-template cdk-connected-overlay [cdkConnectedOverlayOrigin]="cdkConnectedOverlayOrigin" [cdkConnectedOverlayOpen]="isOpen" (backdropClick)="isOpen=false" (positionChange)="onPositionChange($event)"> <div [@cornerFadeInOut]="isOpen ? datepickerPosition : 'void'" class="devui-date-range-wrapper"> <div class="devui-date-range-picker"> <d-datepicker-range-single [locale]="locale || i18nLocale" class="devui-date-picker" [cssClass]="cssClass" [disabled]="disabled" [dateConverter]="dateConverter" (rangeSelected)="rangeChange($event)" [dateFormat]="dateFormat" [dateConfig]="dateConfig" [maxDate]="maxDate" [minDate]="minDate" (hoverOnDate)="selectingDate($event)" [rangePicker]="true" [selectedRange]="[rangeStart, rangeEnd]" (rangeSelecting)="syncRangeStart($event, rightPicker)" (syncPickerPair)="syncPickerPair($event, 'left')" [currentCalendars]="currentCalendars" [showTime]="showTime" #leftPicker></d-datepicker-range-single> <d-datepicker-range-single [locale]="locale || i18nLocale" class="devui-date-picker" [cssClass]="cssClass" [disabled]="disabled" [dateConverter]="dateConverter" (rangeSelected)="rangeChange($event)" [dateFormat]="dateFormat" [dateConfig]="dateConfig" [maxDate]="maxDate" [minDate]="minDate" (hoverOnDate)="selectingDate($event)" [rangePicker]="true" [selectedRange]="[rangeStart, rangeEnd]" (rangeSelecting)="syncRangeStart($event, leftPicker)" (syncPickerPair)="syncPickerPair($event, 'right')" [isAuxiliary]="true" [currentCalendars]="currentCalendars" [showTime]="showTime" (consolidateTime)="consolidateTime()" #rightPicker></d-datepicker-range-single> </div> <div class="devui-date-range-custom" *ngIf="customViewTemplate" #templateWrap> <ng-template [ngTemplateOutlet]="customViewTemplate" [ngTemplateOutletContext]="{ $implicit: this, clearAll: clearAll, chooseDate: chooseDate, rangeStart: rangeStart, rangeEnd: rangeEnd }" ></ng-template> </div> </div> </ng-template> `, animations: [ cornerFadeInOut ], styles: [".devui-date-range-wrapper{display:-webkit-inline-box!important;display:inline-flex!important;box-shadow:0 4px 8px 0 rgba(41,48,64,.2);background-color:#fff;-webkit-transform:perspective(1px) translate3d(0,0,0);transform:perspective(1px) translate3d(0,0,0);-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column}.devui-date-range-wrapper .devui-date-range-picker{display:-webkit-inline-box!important;display:inline-flex!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.devui-date-range-wrapper .devui-date-range-picker::after{content:'';position:absolute;top:29px;width:100%;height:1px;border-bottom:1px solid #adb0b8}.devui-date-range-wrapper .devui-date-range-custom{width:500px;border-top:1px solid #adb0b8}.devui-date-picker:not(:last-child){margin-right:20px}"] }] } ]; /** @nocollapse */ DateRangePickerComponent.ctorParameters = () => [ { type: ElementRef }, { type: ViewContainerRef }, { type: Renderer2 }, { type: DatePickerConfig }, { type: I18nService } ]; DateRangePickerComponent.propDecorators = { dateConfig: [{ type: Input }], dateFormat: [{ type: Input }], maxDate: [{ type: Input }], minDate: [{ type: Input }], locale: [{ type: Input }], cssClass: [{ type: Input }], disabled: [{ type: Input }], dateConverter: [{ type: Input }], selectedRange: [{ type: Input }], showTime: [{ type: Input }], hideOnRangeSelected: [{ type: Input }], customViewTemplate: [{ type: Input }], splitter: [{ type: Input }], selectedRangeChange: [{ type: Output }], leftPicker: [{ type: ViewChild, args: ['leftPicker', { static: false },] }], rightPicker: [{ type: ViewChild, args: ['rightPicker', { static: false },] }], templateWrap: [{ type: ViewChild, args: ['templateWrap', { static: false },] }], onBlur: [{ type: HostListener, args: ['blur', ['$event'],] }], onDocumentClick: [{ type: HostListener, args: ['document:click', ['$event'],] }] }; if (false) { /** @type {?} */ DateRangePickerComponent.prototype.locale; /** @type {?} */ DateRangePickerComponent.prototype.cssClass; /** @type {?} */ DateRangePickerComponent.prototype.disabled; /** @type {?} */ DateRangePickerComponent.prototype.dateConverter; /** @type {?} */ DateRangePickerComponent.prototype.selectedRange; /** @type {?} */ DateRangePickerComponent.prototype.showTime; /** @type {?} */ DateRangePickerComponent.prototype.hideOnRangeSelected; /** @type {?} */ DateRangePickerComponent.prototype.customViewTemplate; /** @type {?} */ DateRangePickerComponent.prototype.splitter; /** @type {?} */ DateRangePickerComponent.prototype.selectedRangeChange; /** @type {?} */ DateRangePickerComponent.prototype.leftPicker; /** @type {?} */ DateRangePickerComponent.prototype.rightPicker; /** @type {?} */ DateRangePickerComponent.prototype.templateWrap; /** * @type {?} * @private */ DateRangePickerComponent.prototype._isOpen; /** * @type {?} * @private */ DateRangePickerComponent.prototype._dateConfig; /** * @type {?} * @private */ DateRangePickerComponent.prototype._dateFormat; /** * @type {?} * @private */ DateRangePickerComponent.prototype._maxDate; /** * @type {?} * @private */ DateRangePickerComponent.prototype._minDate; /** * @type {?} * @private */ DateRangePickerComponent.prototype.clickShow; /** * @type {?} * @private */ DateRangePickerComponent.prototype.inputSub; /** @type {?} */ DateRangePickerComponent.prototype.currentCalendars; /** @type {?} */ DateRangePickerComponent.prototype.cdkConnectedOverlayOrigin; /** @type {?} */ DateRangePickerComponent.prototype.i18nLocale; /** * @type {?} * @private */ DateRangePickerComponent.prototype.i18nSubscription; /** @type {?} */ DateRangePickerComponent.prototype.hoverOnDate; /** @type {?} */ DateRangePickerComponent.prototype.datepickerPosition; /** @type {?} */ DateRangePickerComponent.prototype.rangeStart; /** @type {?} */ DateRangePickerComponent.prototype.rangeEnd; /** * @type {?} * @private */ DateRangePickerComponent.prototype.onChange; /** * @type {?} * @private */ DateRangePickerComponent.prototype.onTouched; /** @type {?} */ DateRangePickerComponent.prototype.chooseDate; /** @type {?} */ DateRangePickerComponent.prototype.clearAll; /** * @type {?} * @private */ DateRangePickerComponent.prototype.elementRef; /** * @type {?} * @private */ DateRangePickerComponent.prototype.viewContainerRef; /** * @type {?} * @private */ DateRangePickerComponent.prototype.renderer; /** * @type {?} * @private */ DateRangePickerComponent.prototype.datePickerConfig; /** * @type {?} * @private */ DateRangePickerComponent.prototype.i18n; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctZGV2dWkvZGF0ZXBpY2tlci8iLCJzb3VyY2VzIjpbImRhdGUtcmFuZ2UtcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFFVixLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWixVQUFVLEVBQ1YsZ0JBQWdCLEVBQ2hCLFNBQVMsRUFDVCxZQUFZLEVBQ1osU0FBUyxFQUVULFdBQVcsRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQXlELE1BQU0sc0JBQXNCLENBQUM7QUFFL0csT0FBTyxFQUFrQywyQkFBMkIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ25ILE9BQU8sRUFBRSx1QkFBdUIsSUFBSSxnQkFBZ0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNGLE9BQU8sRUFBRSxXQUFXLEVBQWlCLE1BQU0sZUFBZSxDQUFDO0FBQzNELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBOERwRSxNQUFNLE9BQU8sd0JBQXdCOzs7Ozs7OztJQXlGbkMsWUFBb0IsVUFBc0IsRUFBVSxnQkFBa0MsRUFDbEUsUUFBbUIsRUFBVSxnQkFBa0MsRUFBVSxJQUFpQjtRQUQxRixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQVUscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNs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Q0FBdUI7Ozs7O0lBQ3ZCLDRDQUF1Qjs7Ozs7SUFDdkIsNkNBQTBCOzs7OztJQUMxQiw0Q0FBK0I7O0lBQy9CLG9EQUF1Qzs7SUFDdkMsNkRBQXNDOztJQUN0Qyw4Q0FBMkM7Ozs7O0lBQzNDLG9EQUF1Qzs7SUFDdkMsK0NBQXFEOztJQUNyRCxzREFBcUQ7O0lBQ3JELDhDQUFXOztJQUNYLDRDQUFTOzs7OztJQUNULDRDQUFvQzs7Ozs7SUFDcEMsNkNBQStCOztJQW9EL0IsOENBSUM7O0lBNExELDRDQUVDOzs7OztJQXBQVyw4Q0FBOEI7Ozs7O0lBQUUsb0RBQTBDOzs7OztJQUMxRSw0Q0FBMkI7Ozs7O0lBQUUsb0RBQTBDOzs7OztJQUFFLHdDQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgZm9yd2FyZFJlZixcclxuICBPbkluaXQsXHJcbiAgSW5wdXQsXHJcbiAgT3V0cHV0LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBFbGVtZW50UmVmLFxyXG4gIFZpZXdDb250YWluZXJSZWYsXHJcbiAgUmVuZGVyZXIyLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBWaWV3Q2hpbGQsXHJcbiAgT25EZXN0cm95LFxyXG4gIFRlbXBsYXRlUmVmXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENka092ZXJsYXlPcmlnaW4sIENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSwgVmVydGljYWxDb25uZWN0aW9uUG9zIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBEYXRlQ29udmVydGVyIH0gZnJvbSAnbmctZGV2dWkvdXRpbHMnO1xyXG5pbXBvcnQgeyBTZWxlY3REYXRlUmFuZ2VDaGFuZ2VFdmVudEFyZ3MsIFNlbGVjdERhdGVSYW5nZUNoYW5nZVJlYXNvbiB9IGZyb20gJy4vZGF0ZS1yYW5nZS1jaGFuZ2UtZXZlbnQtYXJncy5tb2RlbCc7XHJcbmltcG9ydCB7IERhdGVQaWNrZXJDb25maWdTZXJ2aWNlIGFzIERhdGVQaWNrZXJDb25maWcgfSBmcm9tICcuL2RhdGUtcGlja2VyLmNvbmZpZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSTE4blNlcnZpY2UsIEkxOG5JbnRlcmZhY2UgfSBmcm9tICduZy1kZXZ1aS9pMThuJztcclxuaW1wb3J0IHsgRGVmYXVsdERhdGVDb252ZXJ0ZXIgfSBmcm9tICduZy1kZXZ1aS91dGlscyc7XHJcbmltcG9ydCB7IGNvcm5lckZhZGVJbk91dCB9IGZyb20gJ25nLWRldnVpL3V0aWxzJztcclxuaW1wb3J0IHsgU3ViamVjdCwgZnJvbUV2ZW50LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnW2REYXRlUmFuZ2VQaWNrZXJdJyxcclxuICBwcm92aWRlcnM6IFt7XHJcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERhdGVSYW5nZVBpY2tlckNvbXBvbmVudCksXHJcbiAgICBtdWx0aTogdHJ1ZVxyXG4gIH1dLFxyXG4gIGV4cG9ydEFzOiAnZGF0ZVJhbmdlUGlja2VyJyxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPG5nLXRlbXBsYXRlIGNkay1jb25uZWN0ZWQtb3ZlcmxheVxyXG4gICAgICAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3JpZ2luXT1cImNka0Nvbm5lY3RlZE92ZXJsYXlPcmlnaW5cIlxyXG4gICAgICAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3Blbl09XCJpc09wZW5cIlxyXG4gICAgICAgICAgICAgICAgIChiYWNrZHJvcENsaWNrKT1cImlzT3Blbj1mYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgKHBvc2l0aW9uQ2hhbmdlKT1cIm9uUG9zaXRpb25DaGFuZ2UoJGV2ZW50KVwiPlxyXG4gICAgICA8ZGl2IFtAY29ybmVyRmFkZUluT3V0XT1cImlzT3BlbiA/IGRhdGVwaWNrZXJQb3NpdGlvbiA6ICd2b2lkJ1wiIGNsYXNzPVwiZGV2dWktZGF0ZS1yYW5nZS13cmFwcGVyXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImRldnVpLWRhdGUtcmFuZ2UtcGlja2VyXCI+XHJcbiAgICAgICAgICA8ZC1kYXRlcGlja2VyLXJhbmdlLXNpbmdsZSBbbG9jYWxlXT1cImxvY2FsZSB8fCBpMThuTG9jYWxlXCIgY2xhc3M9XCJkZXZ1aS1kYXRlLXBpY2tlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Nzc0NsYXNzXT1cImNzc0NsYXNzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbZGF0ZUNvbnZlcnRlcl09XCJkYXRlQ29udmVydGVyXCIgKHJhbmdlU2VsZWN0ZWQpPVwicmFuZ2VDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGVGb3JtYXRdPVwiZGF0ZUZvcm1hdFwiIFtkYXRlQ29uZmlnXT1cImRhdGVDb25maWdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhEYXRlXT1cIm1heERhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5EYXRlXT1cIm1pbkRhdGVcIiAoaG92ZXJPbkRhdGUpPVwic2VsZWN0aW5nRGF0ZSgkZXZlbnQpXCIgW3JhbmdlUGlja2VyXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZWxlY3RlZFJhbmdlXT1cIltyYW5nZVN0YXJ0LCByYW5nZUVuZF1cIiAocmFuZ2VTZWxlY3RpbmcpPVwic3luY1JhbmdlU3RhcnQoJGV2ZW50LCByaWdodFBpY2tlcilcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzeW5jUGlja2VyUGFpcik9XCJzeW5jUGlja2VyUGFpcigkZXZlbnQsICdsZWZ0JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjdXJyZW50Q2FsZW5kYXJzXT1cImN1cnJlbnRDYWxlbmRhcnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VGltZV09XCJzaG93VGltZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2xlZnRQaWNrZXI+PC9kLWRhdGVwaWNrZXItcmFuZ2Utc2luZ2xlPlxyXG4gICAgICAgICAgPGQtZGF0ZXBpY2tlci1yYW5nZS1zaW5nbGUgW2xvY2FsZV09XCJsb2NhbGUgfHwgaTE4bkxvY2FsZVwiIGNsYXNzPVwiZGV2dWktZGF0ZS1waWNrZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjc3NDbGFzc109XCJjc3NDbGFzc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgW2RhdGVDb252ZXJ0ZXJdPVwiZGF0ZUNvbnZlcnRlclwiIChyYW5nZVNlbGVjdGVkKT1cInJhbmdlQ2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRlRm9ybWF0XT1cImRhdGVGb3JtYXRcIiBbZGF0ZUNvbmZpZ109XCJkYXRlQ29uZmlnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4RGF0ZV09XCJtYXhEYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluRGF0ZV09XCJtaW5EYXRlXCIgKGhvdmVyT25EYXRlKT1cInNlbGVjdGluZ0RhdGUoJGV2ZW50KVwiIFtyYW5nZVBpY2tlcl09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VsZWN0ZWRSYW5nZV09XCJbcmFuZ2VTdGFydCwgcmFuZ2VFbmRdXCIgKHJhbmdlU2VsZWN0aW5nKT1cInN5bmNSYW5nZVN0YXJ0KCRldmVudCwgbGVmdFBpY2tlcilcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzeW5jUGlja2VyUGFpcik9XCJzeW5jUGlja2VyUGFpcigkZXZlbnQsICdyaWdodCcpXCIgW2lzQXV4aWxpYXJ5XT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjdXJyZW50Q2FsZW5kYXJzXT1cImN1cnJlbnRDYWxlbmRhcnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VGltZV09XCJzaG93VGltZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnNvbGlkYXRlVGltZSk9XCJjb25zb2xpZGF0ZVRpbWUoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI3JpZ2h0UGlja2VyPjwvZC1kYXRlcGlja2VyLXJhbmdlLXNpbmdsZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZGV2dWktZGF0ZS1yYW5nZS1jdXN0b21cIiAqbmdJZj1cImN1c3RvbVZpZXdUZW1wbGF0ZVwiICN0ZW1wbGF0ZVdyYXA+XHJcbiAgICAgICAgICA8bmctdGVtcGxhdGVcclxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tVmlld1RlbXBsYXRlXCJcclxuICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcclxuICAgICAgICAgICAgICAkaW1wbGljaXQ6IHRoaXMsXHJcbiAgICAgICAgICAgICAgY2xlYXJBbGw6IGNsZWFyQWxsLFxyXG4gICAgICAgICAgICAgIGNob29zZURhdGU6IGNob29zZURhdGUsXHJcbiAgICAgICAgICAgICAgcmFuZ2VTdGFydDogcmFuZ2VTdGFydCxcclxuICAgICAgICAgICAgICByYW5nZUVuZDogcmFuZ2VFbmRcclxuICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gIGAsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZGF0ZS1yYW5nZS1waWNrZXIuY29tcG9uZW50LnNjc3MnXSxcclxuICBhbmltYXRpb25zOiBbXHJcbiAgICBjb3JuZXJGYWRlSW5PdXRcclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEYXRlUmFuZ2VQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkRlc3Ryb3kge1xyXG5cclxuICBASW5wdXQoKSBzZXQgZGF0ZUNvbmZpZyhkYXRlQ29uZmlnOiBhbnkpIHtcclxuICAgIGlmIChkYXRlQ29uZmlnKSB7XHJcbiAgICAgIHRoaXMuX2RhdGVDb25maWcgPSBkYXRlQ29uZmlnO1xyXG4gICAgICB0aGlzLl9kYXRlRm9ybWF0ID0gdGhpcy5zaG93VGltZSA/IGRhdGVDb25maWcuZm9ybWF0LnRpbWUgOiBkYXRlQ29uZmlnLmZvcm1hdC5kYXRlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fZGF0ZUNvbmZpZyA9IHRoaXMuZGF0ZVBpY2tlckNvbmZpZy5kYXRlQ29uZmlnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IGRhdGVDb25maWcoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZGF0ZUNvbmZpZztcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIHNldCBkYXRlRm9ybWF0KGRhdGVGb3JtYXQ6IHN0cmluZykge1xyXG4gICAgaWYgKHRoaXMuX2RhdGVGb3JtYXQgIT09IGRhdGVGb3JtYXQpIHtcclxuICAgICAgdGhpcy5fZGF0ZUZvcm1hdCA9IGRhdGVGb3JtYXQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgZGF0ZUZvcm1hdCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9kYXRlRm9ybWF0O1xyXG4gIH1cclxuXHJcbiAgQElucHV0KCkgc2V0IG1heERhdGUoZGF0ZTogRGF0ZSB8IGFueSkge1xyXG4gICAgY29uc3QgcGFyc2VEYXRlID0gdGhpcy5jb252ZXJ0RGF0ZShkYXRlKTtcclxuICAgIGlmIChwYXJzZURhdGUpIHtcclxuICAgICAgdGhpcy5fbWF4RGF0ZSA9IHBhcnNlRGF0ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBtYXhEYXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX21heERhdGU7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKSBzZXQgbWluRGF0ZShkYXRlOiBEYXRlIHwgYW55KSB7XHJcbiAgICBjb25zdCBwYXJzZURhdGUgPSB0aGlzLmNvbnZlcnREYXRlKGRhdGUpO1xyXG4gICAgaWYgKHBhcnNlRGF0ZSkge1xyXG4gICAgICB0aGlzLl9taW5EYXRlID0gcGFyc2VEYXRlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IG1pbkRhdGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWluRGF0ZTtcclxuICB9XHJcblxyXG4gIHNldCBpc09wZW4oaXNPcGVuOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLl9pc09wZW4gPSBpc09wZW47XHJcbiAgICBpZiAoIWlzT3BlbiAmJiAhdGhpcy5yYW5nZUVuZCkge1xyXG4gICAgICB0aGlzLnJhbmdlU3RhcnQgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IGlzT3BlbigpIHtcclxuICAgIHJldHVybiB0aGlzLl9pc09wZW47XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKSBsb2NhbGU6IHN0cmluZztcclxuICBASW5wdXQoKSBjc3NDbGFzczogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGRhdGVDb252ZXJ0ZXI6IERhdGVDb252ZXJ0ZXI7XHJcbiAgQElucHV0KCkgc2VsZWN0ZWRSYW5nZSA9IFtudWxsLCBudWxsXTtcclxuICBASW5wdXQoKSBzaG93VGltZSA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGhpZGVPblJhbmdlU2VsZWN0ZWQgPSBmYWxzZTtcclxuICBASW5wdXQoKSBjdXN0b21WaWV3VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQElucHV0KCkgc3BsaXR0ZXIgPSAnICAtICAnO1xyXG4gIEBPdXRwdXQoKSBzZWxlY3RlZFJhbmdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTZWxlY3REYXRlUmFuZ2VDaGFuZ2VFdmVudEFyZ3M+KCk7XHJcbiAgQFZpZXdDaGlsZCgnbGVmdFBpY2tlcicsIHsgc3RhdGljOiBmYWxzZSB9KSBsZWZ0UGlja2VyOiBFbGVtZW50UmVmO1xyXG4gIEBWaWV3Q2hpbGQoJ3JpZ2h0UGlja2VyJywgeyBzdGF0aWM6IGZhbHNlIH0pIHJpZ2h0UGlja2VyOiBFbGVtZW50UmVmO1xyXG4gIEBWaWV3Q2hpbGQoJ3RlbXBsYXRlV3JhcCcsIHsgc3RhdGljOiBmYWxzZSB9KSB0ZW1wbGF0ZVdyYXA6IEVsZW1lbnRSZWY7XHJcbiAgcHJpdmF0ZSBfaXNPcGVuID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBfZGF0ZUNvbmZpZzogYW55O1xyXG4gIHByaXZhdGU