ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
541 lines (535 loc) • 66 kB
JavaScript
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { fromEvent, merge, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CandyDate, cloneDate, wrongSortOrder } from 'ng-zorro-antd/core/time';
import { CalendarFooterComponent } from './calendar-footer.component';
import { InnerPopupComponent } from './inner-popup.component';
import { getTimeConfig, isAllowedDate, PREFIX_CLASS } from './util';
import * as i0 from "@angular/core";
import * as i1 from "./date-picker.service";
export class DateRangePopupComponent {
get hasTimePicker() {
return !!this.showTime;
}
get hasFooter() {
return this.showToday || this.hasTimePicker || !!this.extraFooter || !!this.ranges;
}
get arrowPosition() {
return this.dir === 'rtl'
? { right: `${this.datePickerService?.arrowLeft}px` }
: { left: `${this.datePickerService?.arrowLeft}px` };
}
constructor(datePickerService, cdr, ngZone, host) {
this.datePickerService = datePickerService;
this.cdr = cdr;
this.ngZone = ngZone;
this.host = host;
this.inline = false;
this.dir = 'ltr';
this.panelModeChange = new EventEmitter();
this.calendarChange = new EventEmitter();
this.resultOk = new EventEmitter(); // Emitted when done with date selecting
this.prefixCls = PREFIX_CLASS;
this.endPanelMode = 'date';
this.timeOptions = null;
this.hoverValue = []; // Range ONLY
this.checkedPartArr = [false, false];
this.destroy$ = new Subject();
this.disabledStartTime = (value) => this.disabledTime && this.disabledTime(value, 'start');
this.disabledEndTime = (value) => this.disabledTime && this.disabledTime(value, 'end');
}
ngOnInit() {
merge(this.datePickerService.valueChange$, this.datePickerService.inputPartChange$)
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.updateActiveDate();
this.cdr.markForCheck();
});
this.ngZone.runOutsideAngular(() => {
fromEvent(this.host.nativeElement, 'mousedown')
.pipe(takeUntil(this.destroy$))
.subscribe(event => event.preventDefault());
});
}
ngOnChanges(changes) {
// Parse showTime options
if (changes.showTime || changes.disabledTime) {
if (this.showTime) {
this.buildTimeOptions();
}
}
if (changes.panelMode) {
this.endPanelMode = this.panelMode;
}
if (changes.defaultPickerValue) {
this.updateActiveDate();
}
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
updateActiveDate() {
const activeDate = this.datePickerService.hasValue()
? this.datePickerService.value
: this.datePickerService.makeValue(this.defaultPickerValue);
this.datePickerService.setActiveDate(activeDate, this.hasTimePicker, this.getPanelMode(this.endPanelMode));
}
onClickOk() {
const inputIndex = { left: 0, right: 1 }[this.datePickerService.activeInput];
const value = this.isRange
? this.datePickerService.value[inputIndex]
: this.datePickerService.value;
this.changeValueFromSelect(value);
this.resultOk.emit();
}
onClickToday(value) {
this.changeValueFromSelect(value, !this.showTime);
}
onCellHover(value) {
if (!this.isRange) {
return;
}
const otherInputIndex = { left: 1, right: 0 }[this.datePickerService.activeInput];
const base = this.datePickerService.value[otherInputIndex];
if (base) {
if (base.isBeforeDay(value)) {
this.hoverValue = [base, value];
}
else {
this.hoverValue = [value, base];
}
}
}
onPanelModeChange(mode, partType) {
if (this.isRange) {
const index = this.datePickerService.getActiveIndex(partType);
if (index === 0) {
this.panelMode = [mode, this.panelMode[1]];
}
else {
this.panelMode = [this.panelMode[0], mode];
}
}
else {
this.panelMode = mode;
}
this.panelModeChange.emit(this.panelMode);
}
onActiveDateChange(value, partType) {
if (this.isRange) {
const activeDate = [];
activeDate[this.datePickerService.getActiveIndex(partType)] = value;
this.datePickerService.setActiveDate(activeDate, this.hasTimePicker, this.getPanelMode(this.endPanelMode, partType));
}
else {
this.datePickerService.setActiveDate(value);
}
}
onSelectTime(value, partType) {
if (this.isRange) {
const newValue = cloneDate(this.datePickerService.value);
const index = this.datePickerService.getActiveIndex(partType);
newValue[index] = this.overrideHms(value, newValue[index]);
this.datePickerService.setValue(newValue);
}
else {
const newValue = this.overrideHms(value, this.datePickerService.value);
this.datePickerService.setValue(newValue); // If not select a date currently, use today
}
this.datePickerService.inputPartChange$.next(null);
this.buildTimeOptions();
}
changeValueFromSelect(value, emitValue = true) {
if (this.isRange) {
const selectedValue = cloneDate(this.datePickerService.value);
const checkedPart = this.datePickerService.activeInput;
let nextPart = checkedPart;
selectedValue[this.datePickerService.getActiveIndex(checkedPart)] = value;
this.checkedPartArr[this.datePickerService.getActiveIndex(checkedPart)] = true;
this.hoverValue = selectedValue;
if (emitValue) {
if (this.inline) {
// For UE, Should always be reversed, and clear vaue when next part is right
nextPart = this.reversedPart(checkedPart);
if (nextPart === 'right') {
selectedValue[this.datePickerService.getActiveIndex(nextPart)] = null;
this.checkedPartArr[this.datePickerService.getActiveIndex(nextPart)] = false;
}
this.datePickerService.setValue(selectedValue);
this.calendarChange.emit(selectedValue);
if (this.isBothAllowed(selectedValue) && this.checkedPartArr[0] && this.checkedPartArr[1]) {
this.clearHoverValue();
this.datePickerService.emitValue$.next();
}
}
else {
/**
* if sort order is wrong, clear the other part's value
*/
if (wrongSortOrder(selectedValue)) {
nextPart = this.reversedPart(checkedPart);
selectedValue[this.datePickerService.getActiveIndex(nextPart)] = null;
this.checkedPartArr[this.datePickerService.getActiveIndex(nextPart)] = false;
}
this.datePickerService.setValue(selectedValue);
/**
* range date usually selected paired,
* so we emit the date value only both date is allowed and both part are checked
*/
if (this.isBothAllowed(selectedValue) && this.checkedPartArr[0] && this.checkedPartArr[1]) {
this.calendarChange.emit(selectedValue);
this.clearHoverValue();
this.datePickerService.emitValue$.next();
}
else if (this.isAllowed(selectedValue)) {
nextPart = this.reversedPart(checkedPart);
this.calendarChange.emit([value.clone()]);
}
}
}
else {
this.datePickerService.setValue(selectedValue);
}
this.datePickerService.inputPartChange$.next(nextPart);
}
else {
this.datePickerService.setValue(value);
this.datePickerService.inputPartChange$.next(null);
if (emitValue && this.isAllowed(value)) {
this.datePickerService.emitValue$.next();
}
}
this.buildTimeOptions();
}
reversedPart(part) {
return part === 'left' ? 'right' : 'left';
}
getPanelMode(panelMode, partType) {
if (this.isRange) {
return panelMode[this.datePickerService.getActiveIndex(partType)];
}
else {
return panelMode;
}
}
// Get single value or part value of a range
getValue(partType) {
if (this.isRange) {
return (this.datePickerService.value || [])[this.datePickerService.getActiveIndex(partType)];
}
else {
return this.datePickerService.value;
}
}
getActiveDate(partType) {
if (this.isRange) {
return this.datePickerService.activeDate[this.datePickerService.getActiveIndex(partType)];
}
else {
return this.datePickerService.activeDate;
}
}
isOneAllowed(selectedValue) {
const index = this.datePickerService.getActiveIndex();
const disabledTimeArr = [this.disabledStartTime, this.disabledEndTime];
return isAllowedDate(selectedValue[index], this.disabledDate, disabledTimeArr[index]);
}
isBothAllowed(selectedValue) {
return (isAllowedDate(selectedValue[0], this.disabledDate, this.disabledStartTime) &&
isAllowedDate(selectedValue[1], this.disabledDate, this.disabledEndTime));
}
isAllowed(value, isBoth = false) {
if (this.isRange) {
return isBoth ? this.isBothAllowed(value) : this.isOneAllowed(value);
}
else {
return isAllowedDate(value, this.disabledDate, this.disabledTime);
}
}
getTimeOptions(partType) {
if (this.showTime && this.timeOptions) {
return this.timeOptions instanceof Array
? this.timeOptions[this.datePickerService.getActiveIndex(partType)]
: this.timeOptions;
}
return null;
}
onClickPresetRange(val) {
const value = typeof val === 'function' ? val() : val;
if (value) {
this.datePickerService.setValue([new CandyDate(value[0]), new CandyDate(value[1])]);
this.datePickerService.emitValue$.next();
}
}
onPresetRangeMouseLeave() {
this.clearHoverValue();
}
onHoverPresetRange(val) {
if (typeof val !== 'function') {
this.hoverValue = [new CandyDate(val[0]), new CandyDate(val[1])];
}
}
getObjectKeys(obj) {
return obj ? Object.keys(obj) : [];
}
show(partType) {
const hide = this.showTime && this.isRange && this.datePickerService.activeInput !== partType;
return !hide;
}
clearHoverValue() {
this.hoverValue = [];
}
buildTimeOptions() {
if (this.showTime) {
const showTime = typeof this.showTime === 'object' ? this.showTime : {};
if (this.isRange) {
const value = this.datePickerService.value;
this.timeOptions = [
this.overrideTimeOptions(showTime, value[0], 'start'),
this.overrideTimeOptions(showTime, value[1], 'end')
];
}
else {
this.timeOptions = this.overrideTimeOptions(showTime, this.datePickerService.value);
}
}
else {
this.timeOptions = null;
}
}
overrideTimeOptions(origin, value, partial) {
let disabledTimeFn;
if (partial) {
disabledTimeFn = partial === 'start' ? this.disabledStartTime : this.disabledEndTime;
}
else {
disabledTimeFn = this.disabledTime;
}
return { ...origin, ...getTimeConfig(value, disabledTimeFn) };
}
overrideHms(newValue, oldValue) {
newValue = newValue || new CandyDate();
oldValue = oldValue || new CandyDate();
return oldValue.setHms(newValue.getHours(), newValue.getMinutes(), newValue.getSeconds());
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: DateRangePopupComponent, deps: [{ token: i1.DatePickerService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.1", type: DateRangePopupComponent, isStandalone: true, selector: "date-range-popup", inputs: { isRange: "isRange", inline: "inline", showWeek: "showWeek", locale: "locale", disabledDate: "disabledDate", disabledTime: "disabledTime", showToday: "showToday", showNow: "showNow", showTime: "showTime", extraFooter: "extraFooter", ranges: "ranges", dateRender: "dateRender", panelMode: "panelMode", defaultPickerValue: "defaultPickerValue", dir: "dir" }, outputs: { panelModeChange: "panelModeChange", calendarChange: "calendarChange", resultOk: "resultOk" }, exportAs: ["dateRangePopup"], usesOnChanges: true, ngImport: i0, template: `
@if (isRange) {
<div class="{{ prefixCls }}-range-wrapper {{ prefixCls }}-date-range-wrapper">
<div class="{{ prefixCls }}-range-arrow" [style]="arrowPosition"></div>
<div class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }}">
<div class="{{ prefixCls }}-panels">
@if (hasTimePicker) {
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: datePickerService.activeInput }" />
} @else {
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'left' }" />
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'right' }" />
}
</div>
<ng-container *ngTemplateOutlet="tplFooter" />
</div>
</div>
} @else {
<div
class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }} {{
hasTimePicker ? prefixCls + '-time' : ''
}} {{ isRange ? prefixCls + '-range' : '' }}"
>
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'" tabindex="-1">
<!-- Single ONLY -->
<ng-container *ngTemplateOutlet="tplInnerPopup" />
<ng-container *ngTemplateOutlet="tplFooter" />
</div>
</div>
}
<ng-template #tplInnerPopup let-partType="partType">
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'">
<!-- TODO(@wenqi73) [selectedValue] [hoverValue] types-->
<inner-popup
[showWeek]="showWeek"
[endPanelMode]="getPanelMode(endPanelMode, partType)"
[partType]="partType"
[locale]="locale!"
[showTimePicker]="hasTimePicker"
[timeOptions]="getTimeOptions(partType)"
[panelMode]="getPanelMode(panelMode, partType)"
(panelModeChange)="onPanelModeChange($event, partType)"
[activeDate]="getActiveDate(partType)"
[value]="getValue(partType)"
[disabledDate]="disabledDate"
[dateRender]="dateRender"
[selectedValue]="$any(datePickerService?.value)"
[hoverValue]="$any(hoverValue)"
(cellHover)="onCellHover($event)"
(selectDate)="changeValueFromSelect($event, !showTime)"
(selectTime)="onSelectTime($event, partType)"
(headerChange)="onActiveDateChange($event, partType)"
/>
</div>
</ng-template>
<ng-template #tplFooter>
@if (hasFooter) {
<calendar-footer
[locale]="locale!"
[isRange]="isRange"
[showToday]="showToday"
[showNow]="showNow"
[hasTimePicker]="hasTimePicker"
[okDisabled]="!isAllowed($any(datePickerService?.value))"
[extraFooter]="extraFooter"
[rangeQuickSelector]="ranges ? tplRangeQuickSelector : null"
(clickOk)="onClickOk()"
(clickToday)="onClickToday($event)"
/>
}
</ng-template>
<!-- Range ONLY: Range Quick Selector -->
<ng-template #tplRangeQuickSelector>
@for (name of getObjectKeys(ranges); track name) {
<li
class="{{ prefixCls }}-preset"
(click)="onClickPresetRange(ranges![name])"
(mouseenter)="onHoverPresetRange(ranges![name])"
(mouseleave)="onPresetRangeMouseLeave()"
>
<span class="ant-tag ant-tag-blue">{{ name }}</span>
</li>
}
</ng-template>
`, isInline: true, dependencies: [{ kind: "component", type: InnerPopupComponent, selector: "inner-popup", inputs: ["activeDate", "endPanelMode", "panelMode", "showWeek", "locale", "showTimePicker", "timeOptions", "disabledDate", "dateRender", "selectedValue", "hoverValue", "value", "partType"], outputs: ["panelModeChange", "headerChange", "selectDate", "selectTime", "cellHover"], exportAs: ["innerPopup"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CalendarFooterComponent, selector: "calendar-footer", inputs: ["locale", "showToday", "showNow", "hasTimePicker", "isRange", "okDisabled", "disabledDate", "extraFooter", "rangeQuickSelector"], outputs: ["clickOk", "clickToday"], exportAs: ["calendarFooter"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.1", ngImport: i0, type: DateRangePopupComponent, decorators: [{
type: Component,
args: [{
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'date-range-popup',
exportAs: 'dateRangePopup',
template: `
@if (isRange) {
<div class="{{ prefixCls }}-range-wrapper {{ prefixCls }}-date-range-wrapper">
<div class="{{ prefixCls }}-range-arrow" [style]="arrowPosition"></div>
<div class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }}">
<div class="{{ prefixCls }}-panels">
@if (hasTimePicker) {
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: datePickerService.activeInput }" />
} @else {
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'left' }" />
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'right' }" />
}
</div>
<ng-container *ngTemplateOutlet="tplFooter" />
</div>
</div>
} @else {
<div
class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }} {{
hasTimePicker ? prefixCls + '-time' : ''
}} {{ isRange ? prefixCls + '-range' : '' }}"
>
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'" tabindex="-1">
<!-- Single ONLY -->
<ng-container *ngTemplateOutlet="tplInnerPopup" />
<ng-container *ngTemplateOutlet="tplFooter" />
</div>
</div>
}
<ng-template #tplInnerPopup let-partType="partType">
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'">
<!-- TODO(@wenqi73) [selectedValue] [hoverValue] types-->
<inner-popup
[showWeek]="showWeek"
[endPanelMode]="getPanelMode(endPanelMode, partType)"
[partType]="partType"
[locale]="locale!"
[showTimePicker]="hasTimePicker"
[timeOptions]="getTimeOptions(partType)"
[panelMode]="getPanelMode(panelMode, partType)"
(panelModeChange)="onPanelModeChange($event, partType)"
[activeDate]="getActiveDate(partType)"
[value]="getValue(partType)"
[disabledDate]="disabledDate"
[dateRender]="dateRender"
[selectedValue]="$any(datePickerService?.value)"
[hoverValue]="$any(hoverValue)"
(cellHover)="onCellHover($event)"
(selectDate)="changeValueFromSelect($event, !showTime)"
(selectTime)="onSelectTime($event, partType)"
(headerChange)="onActiveDateChange($event, partType)"
/>
</div>
</ng-template>
<ng-template #tplFooter>
@if (hasFooter) {
<calendar-footer
[locale]="locale!"
[isRange]="isRange"
[showToday]="showToday"
[showNow]="showNow"
[hasTimePicker]="hasTimePicker"
[okDisabled]="!isAllowed($any(datePickerService?.value))"
[extraFooter]="extraFooter"
[rangeQuickSelector]="ranges ? tplRangeQuickSelector : null"
(clickOk)="onClickOk()"
(clickToday)="onClickToday($event)"
/>
}
</ng-template>
<!-- Range ONLY: Range Quick Selector -->
<ng-template #tplRangeQuickSelector>
@for (name of getObjectKeys(ranges); track name) {
<li
class="{{ prefixCls }}-preset"
(click)="onClickPresetRange(ranges![name])"
(mouseenter)="onHoverPresetRange(ranges![name])"
(mouseleave)="onPresetRangeMouseLeave()"
>
<span class="ant-tag ant-tag-blue">{{ name }}</span>
</li>
}
</ng-template>
`,
imports: [InnerPopupComponent, NgTemplateOutlet, CalendarFooterComponent],
standalone: true
}]
}], ctorParameters: () => [{ type: i1.DatePickerService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.ElementRef }], propDecorators: { isRange: [{
type: Input
}], inline: [{
type: Input
}], showWeek: [{
type: Input
}], locale: [{
type: Input
}], disabledDate: [{
type: Input
}], disabledTime: [{
type: Input
}], showToday: [{
type: Input
}], showNow: [{
type: Input
}], showTime: [{
type: Input
}], extraFooter: [{
type: Input
}], ranges: [{
type: Input
}], dateRender: [{
type: Input
}], panelMode: [{
type: Input
}], defaultPickerValue: [{
type: Input
}], dir: [{
type: Input
}], panelModeChange: [{
type: Output
}], calendarChange: [{
type: Output
}], resultOk: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1wb3B1cC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL2RhdGUtcGlja2VyL2RhdGUtcmFuZ2UtcG9wdXAuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBS0wsTUFBTSxFQUdOLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsU0FBUyxFQUlULGNBQWMsRUFDZixNQUFNLHlCQUF5QixDQUFDO0FBSWpDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXRFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBVzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQzs7O0FBa0dwRSxNQUFNLE9BQU8sdUJBQXVCO0lBNEJsQyxJQUFJLGFBQWE7UUFDZixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyRixDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsR0FBRyxLQUFL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LGdCQUFnQixFQUFFLHVCQUF1QixDQUFDO29CQUN6RSxVQUFVLEVBQUUsSUFBSTtpQkFDakI7b0tBRVUsT0FBTztzQkFBZixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFFYSxlQUFlO3NCQUFqQyxNQUFNO2dCQUNZLGNBQWM7c0JBQWhDLE1BQU07Z0JBQ1ksUUFBUTtzQkFBMUIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IERpcmVjdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIG1lcmdlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIENhbmR5RGF0ZSxcbiAgY2xvbmVEYXRlLFxuICBDb21wYXRpYmxlVmFsdWUsXG4gIE5vcm1hbGl6ZWRNb2RlLFxuICBTaW5nbGVWYWx1ZSxcbiAgd3JvbmdTb3J0T3JkZXJcbn0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3RpbWUnO1xuaW1wb3J0IHsgRnVuY3Rpb25Qcm9wIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IE56Q2FsZW5kYXJJMThuSW50ZXJmYWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pMThuJztcblxuaW1wb3J0IHsgQ2FsZW5kYXJGb290ZXJDb21wb25lbnQgfSBmcm9tICcuL2NhbGVuZGFyLWZvb3Rlci5jb21wb25lbnQnO1xuaW1wb3J0IHsgRGF0ZVBpY2tlclNlcnZpY2UgfSBmcm9tICcuL2RhdGUtcGlja2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgSW5uZXJQb3B1cENvbXBvbmVudCB9IGZyb20gJy4vaW5uZXItcG9wdXAuY29tcG9uZW50JztcbmltcG9ydCB7XG4gIENvbXBhdGlibGVEYXRlLFxuICBEaXNhYmxlZERhdGVGbixcbiAgRGlzYWJsZWRUaW1lRm4sXG4gIERpc2FibGVkVGltZVBhcnRpYWwsXG4gIE56RGF0ZU1vZGUsXG4gIFByZXNldFJhbmdlcyxcbiAgUmFuZ2VQYXJ0VHlwZSxcbiAgU3VwcG9ydFRpbWVPcHRpb25zXG59IGZyb20gJy4vc3RhbmRhcmQtdHlwZXMnO1xuaW1wb3J0IHsgZ2V0VGltZUNvbmZpZywgaXNBbGxvd2VkRGF0ZSwgUFJFRklYX0NMQVNTIH0gZnJvbSAnLi91dGlsJztcblxuQENvbXBvbmVudCh7XG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvclxuICBzZWxlY3RvcjogJ2RhdGUtcmFuZ2UtcG9wdXAnLFxuICBleHBvcnRBczogJ2RhdGVSYW5nZVBvcHVwJyxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKGlzUmFuZ2UpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tcmFuZ2Utd3JhcHBlciB7eyBwcmVmaXhDbHMgfX0tZGF0ZS1yYW5nZS13cmFwcGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tcmFuZ2UtYXJyb3dcIiBbc3R5bGVdPVwiYXJyb3dQb3NpdGlvblwiPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXBhbmVsLWNvbnRhaW5lciB7eyBzaG93V2VlayA/IHByZWZpeENscyArICctd2Vlay1udW1iZXInIDogJycgfX1cIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXBhbmVsc1wiPlxuICAgICAgICAgICAgQGlmIChoYXNUaW1lUGlja2VyKSB7XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxJbm5lclBvcHVwOyBjb250ZXh0OiB7IHBhcnRUeXBlOiBkYXRlUGlja2VyU2VydmljZS5hY3RpdmVJbnB1dCB9XCIgLz5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsSW5uZXJQb3B1cDsgY29udGV4dDogeyBwYXJ0VHlwZTogJ2xlZnQnIH1cIiAvPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsSW5uZXJQb3B1cDsgY29udGV4dDogeyBwYXJ0VHlwZTogJ3JpZ2h0JyB9XCIgLz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsRm9vdGVyXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICB9IEBlbHNlIHtcbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tcGFuZWwtY29udGFpbmVyIHt7IHNob3dXZWVrID8gcHJlZml4Q2xzICsgJy13ZWVrLW51bWJlcicgOiAnJyB9fSB7e1xuICAgICAgICAgIGhhc1RpbWVQaWNrZXIgPyBwcmVmaXhDbHMgKyAnLXRpbWUnIDogJydcbiAgICAgICAgfX0ge3sgaXNSYW5nZSA/IHByZWZpeENscyArICctcmFuZ2UnIDogJycgfX1cIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXBhbmVsXCIgW2NsYXNzLmFudC1waWNrZXItcGFuZWwtcnRsXT1cImRpciA9PT0gJ3J0bCdcIiB0YWJpbmRleD1cIi0xXCI+XG4gICAgICAgICAgPCEtLSBTaW5nbGUgT05MWSAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsSW5uZXJQb3B1cFwiIC8+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRwbEZvb3RlclwiIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPG5nLXRlbXBsYXRlICN0cGxJbm5lclBvcHVwIGxldC1wYXJ0VHlwZT1cInBhcnRUeXBlXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXBhbmVsXCIgW2NsYXNzLmFudC1waWNrZXItcGFuZWwtcnRsXT1cImRpciA9PT0gJ3J0bCdcIj5cbiAgICAgICAgPCEtLSBUT0RPKEB3ZW5xaTczKSBbc2VsZWN0ZWRWYWx1ZV0gW2hvdmVyVmFsdWVdIHR5cGVzLS0+XG4gICAgICAgIDxpbm5lci1wb3B1cFxuICAgICAgICAgIFtzaG93V2Vla109XCJzaG93V2Vla1wiXG4gICAgICAgICAgW2VuZFBhbmVsTW9kZV09XCJnZXRQYW5lbE1vZGUoZW5kUGFuZWxNb2RlLCBwYXJ0VHlwZSlcIlxuICAgICAgICAgIFtwYXJ0VHlwZV09XCJwYXJ0VHlwZVwiXG4gICAgICAgICAgW2xvY2FsZV09XCJsb2NhbGUhXCJcbiAgICAgICAgICBbc2hvd1RpbWVQaWNrZXJdPVwiaGFzVGltZVBpY2tlclwiXG4gICAgICAgICAgW3RpbWVPcHRpb25zXT1cImdldFRpbWVPcHRpb25zKHBhcnRUeXBlKVwiXG4gICAgICAgICAgW3BhbmVsTW9kZV09XCJnZXRQYW5lbE1vZGUocGFuZWxNb2RlLCBwYXJ0VHlwZSlcIlxuICAgICAgICAgIChwYW5lbE1vZGVDaGFuZ2UpPVwib25QYW5lbE1vZGVDaGFuZ2UoJGV2ZW50LCBwYXJ0VHlwZSlcIlxuICAgICAgICAgIFthY3RpdmVEYXRlXT1cImdldEFjdGl2ZURhdGUocGFydFR5cGUpXCJcbiAgICAgICAgICBbdmFsdWVdPVwiZ2V0VmFsdWUocGFydFR5cGUpXCJcbiAgICAgICAgICBbZGlzYWJsZWREYXRlXT1cImRpc2FibGVkRGF0ZVwiXG4gICAgICAgICAgW2RhdGVSZW5kZXJdPVwiZGF0ZVJlbmRlclwiXG4gICAgICAgICAgW3NlbGVjdGVkVmFsdWVdPVwiJGFueShkYXRlUGlja2VyU2VydmljZT8udmFsdWUpXCJcbiAgICAgICAgICBbaG92ZXJWYWx1ZV09XCIkYW55KGhvdmVyVmFsdWUpXCJcbiAgICAgICAgICAoY2VsbEhvdmVyKT1cIm9uQ2VsbEhvdmVyKCRldmVudClcIlxuICAgICAgICAgIChzZWxlY3REYXRlKT1cImNoYW5nZVZhbHVlRnJvbVNlbGVjdCgkZXZlbnQsICFzaG93VGltZSlcIlxuICAgICAgICAgIChzZWxlY3RUaW1lKT1cIm9uU2VsZWN0VGltZSgkZXZlbnQsIHBhcnRUeXBlKVwiXG4gICAgICAgICAgKGhlYWRlckNoYW5nZSk9XCJvbkFjdGl2ZURhdGVDaGFuZ2UoJGV2ZW50LCBwYXJ0VHlwZSlcIlxuICAgICAgICAvPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxuZy10ZW1wbGF0ZSAjdHBsRm9vdGVyPlxuICAgICAgQGlmIChoYXNGb290ZXIpIHtcbiAgICAgICAgPGNhbGVuZGFyLWZvb3RlclxuICAgICAgICAgIFtsb2NhbGVdPVwibG9jYWxlIVwiXG4gICAgICAgICAgW2lzUmFuZ2VdPVwiaXNSYW5nZVwiXG4gICAgICAgICAgW3Nob3dUb2RheV09XCJzaG93VG9kYXlcIlxuICAgICAgICAgIFtzaG93Tm93XT1cInNob3dOb3dcIlxuICAgICAgICAgIFtoYXNUaW1lUGlja2VyXT1cImhhc1RpbWVQaWNrZXJcIlxuICAgICAgICAgIFtva0Rpc2FibGVkXT1cIiFpc0FsbG93ZWQoJGFueShkYXRlUGlja2VyU2VydmljZT8udmFsdWUpKVwiXG4gICAgICAgICAgW2V4dHJhRm9vdGVyXT1cImV4dHJhRm9vdGVyXCJcbiAgICAgICAgICBbcmFuZ2VRdWlja1NlbGVjdG9yXT1cInJhbmdlcyA/IHRwbFJhbmdlUXVpY2tTZWxlY3RvciA6IG51bGxcIlxuICAgICAgICAgIChjbGlja09rKT1cIm9uQ2xpY2tPaygpXCJcbiAgICAgICAgICAoY2xpY2tUb2RheSk9XCJvbkNsaWNrVG9kYXkoJGV2ZW50KVwiXG4gICAgICAgIC8+XG4gICAgICB9XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDwhLS0gUmFuZ2UgT05MWTogUmFuZ2UgUXVpY2sgU2VsZWN0b3IgLS0+XG4gICAgPG5nLXRlbXBsYXRlICN0cGxSYW5nZVF1aWNrU2VsZWN0b3I+XG4gICAgICBAZm9yIChuYW1lIG9mIGdldE9iamVjdEtleXMocmFuZ2VzKTsgdHJhY2sgbmFtZSkge1xuICAgICAgICA8bGlcbiAgICAgICAgICBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wcmVzZXRcIlxuICAgICAgICAgIChjbGljayk9XCJvbkNsaWNrUHJlc2V0UmFuZ2UocmFuZ2VzIVtuYW1lXSlcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uSG92ZXJQcmVzZXRSYW5nZShyYW5nZXMhW25hbWVdKVwiXG4gICAgICAgICAgKG1vdXNlbGVhdmUpPVwib25QcmVzZXRSYW5nZU1vdXNlTGVhdmUoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImFudC10YWcgYW50LXRhZy1ibHVlXCI+e3sgbmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgPC9saT5cbiAgICAgIH1cbiAgICA8L25nLXRlbXBsYXRlPlxuICBgLFxuICBpbXBvcnRzOiBbSW5uZXJQb3B1cENvbXBvbmVudCwgTmdUZW1wbGF0ZU91dGxldCwgQ2FsZW5kYXJGb290ZXJDb21wb25lbnRdLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIERhdGVSYW5nZVBvcHVwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGlzUmFuZ2UhOiBib29sZWFuO1xuICBASW5wdXQoKSBpbmxpbmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd1dlZWshOiBib29sZWFuO1xuICBASW5wdXQoKSBsb2NhbGUhOiBOekNhbGVuZGFySTE4bkludGVyZmFjZSB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgZGlzYWJsZWREYXRlPzogRGlzYWJsZWREYXRlRm47XG4gIEBJbnB1dCgpIGRpc2FibGVkVGltZT86IERpc2FibGVkVGltZUZuOyAvLyBUaGlzIHdpbGwgbGVhZCB0byByZWJ1aWxkIHRpbWUgb3B0aW9uc1xuICBASW5wdXQoKSBzaG93VG9kYXkhOiBib29sZWFuO1xuICBASW5wdXQoKSBzaG93Tm93ITogYm9vbGVhbjtcbiAgQElucHV0KCkgc2hvd1RpbWUhOiBTdXBwb3J0VGltZU9wdGlvbnMgfCBib29sZWFuO1xuICBASW5wdXQoKSBleHRyYUZvb3Rlcj86IFRlbXBsYXRlUmVmPHZvaWQ+IHwgc3RyaW5nO1xuICBASW5wdXQoKSByYW5nZXM/OiBQcmVzZXRSYW5nZXM7XG4gIEBJbnB1dCgpIGRhdGVSZW5kZXI/OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxEYXRlPiB8IEZ1bmN0aW9uUHJvcDxUZW1wbGF0ZVJlZjxEYXRlPiB8IHN0cmluZz47XG4gIEBJbnB1dCgpIHBhbmVsTW9kZSE6IE56RGF0ZU1vZGUgfCBOekRhdGVNb2RlW107XG4gIEBJbnB1dCgpIGRlZmF1bHRQaWNrZXJWYWx1ZSE6IENvbXBhdGlibGVEYXRlIHwgdW5kZWZpbmVkIHwgbnVsbDtcbiAgQElucHV0KCkgZGlyOiBEaXJlY3Rpb24gPSAnbHRyJztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgcGFuZWxNb2RlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxOekRhdGVNb2RlIHwgTnpEYXRlTW9kZVtdPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgY2FsZW5kYXJDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPENvbXBhdGlibGVWYWx1ZT4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IHJlc3VsdE9rID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpOyAvLyBFbWl0dGVkIHdoZW4gZG9uZSB3aXRoIGRhdGUgc2VsZWN0aW5nXG5cbiAgcHJlZml4Q2xzOiBzdHJpbmcgPSBQUkVGSVhfQ0xBU1M7XG4gIGVuZFBhbmVsTW9kZTogTnpEYXRlTW9kZSB8IE56RGF0ZU1vZGVbXSA9ICdkYXRlJztcbiAgdGl