@duoduo-oba/ng-devui
Version:
DevUI components based on Angular
740 lines • 62.8 kB
JavaScript
/**
* @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