saturn-datepicker
Version:
Material datepicker with range support ## What is this?
508 lines • 66 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as tslib_1 from "tslib";
import { ComponentPortal } from '@angular/cdk/portal';
import { AfterContentInit, AfterViewChecked, ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, forwardRef, Inject, Input, OnChanges, OnDestroy, Optional, Output, SimpleChanges, ViewChild, ViewEncapsulation, } from '@angular/core';
import { Subject } from 'rxjs';
import { createMissingDateImplError } from './datepicker-errors';
import { SatDatepickerIntl } from './datepicker-intl';
import { SatMonthView } from './month-view';
import { getActiveOffset, isSameMultiYearView, SatMultiYearView, yearsPerPage } from './multi-year-view';
import { SatYearView } from './year-view';
import { DateAdapter } from '../datetime/date-adapter';
import { MAT_DATE_FORMATS } from '../datetime/date-formats';
/** Default header for SatCalendar */
var SatCalendarHeader = /** @class */ (function () {
function SatCalendarHeader(_intl, calendar, _dateAdapter, _dateFormats, changeDetectorRef) {
this._intl = _intl;
this.calendar = calendar;
this._dateAdapter = _dateAdapter;
this._dateFormats = _dateFormats;
this.calendar.stateChanges.subscribe(function () { return changeDetectorRef.markForCheck(); });
}
Object.defineProperty(SatCalendarHeader.prototype, "periodButtonText", {
/** The label for the current calendar view. */
get: function () {
if (this.calendar.currentView == 'month') {
return this._dateAdapter
.format(this.calendar.activeDate, this._dateFormats.display.monthYearLabel)
.toLocaleUpperCase();
}
if (this.calendar.currentView == 'year') {
return this._dateAdapter.getYearName(this.calendar.activeDate);
}
// The offset from the active year to the "slot" for the starting year is the
// *actual* first rendered year in the multi-year view, and the last year is
// just yearsPerPage - 1 away.
var activeYear = this._dateAdapter.getYear(this.calendar.activeDate);
var minYearOfPage = activeYear - getActiveOffset(this._dateAdapter, this.calendar.activeDate, this.calendar.minDate, this.calendar.maxDate);
var maxYearOfPage = minYearOfPage + yearsPerPage - 1;
return minYearOfPage + " \u2013 " + maxYearOfPage;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendarHeader.prototype, "periodButtonLabel", {
get: function () {
return this.calendar.currentView == 'month' ?
this._intl.switchToMultiYearViewLabel : this._intl.switchToMonthViewLabel;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendarHeader.prototype, "prevButtonLabel", {
/** The label for the previous button. */
get: function () {
return {
'month': this._intl.prevMonthLabel,
'year': this._intl.prevYearLabel,
'multi-year': this._intl.prevMultiYearLabel
}[this.calendar.currentView];
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendarHeader.prototype, "nextButtonLabel", {
/** The label for the next button. */
get: function () {
return {
'month': this._intl.nextMonthLabel,
'year': this._intl.nextYearLabel,
'multi-year': this._intl.nextMultiYearLabel
}[this.calendar.currentView];
},
enumerable: true,
configurable: true
});
/** Handles user clicks on the period label.
* Option`calendar.orderPeriodLabel` sort the label period views.
* - Default [multi-year]: multi-year then back to month
* - Month [month]: month > year > multi-year
*/
SatCalendarHeader.prototype.currentPeriodClicked = function () {
var mouthFirstOrder = ['month', 'year', 'multi-year'];
var defaultOrder = ['month', 'multi-year', 'month'];
var orderPeriod = this.calendar.orderPeriodLabel === 'month' ? mouthFirstOrder : defaultOrder;
switch (this.calendar.currentView) {
case 'month':
this.calendar.currentView = orderPeriod[1];
break;
case 'year':
this.calendar.currentView = orderPeriod[2];
break;
default:
this.calendar.currentView = orderPeriod[0];
break;
}
};
/** Handles user clicks on the previous button. */
SatCalendarHeader.prototype.previousClicked = function () {
this.calendar.activeDate = this.calendar.currentView == 'month' ?
this._dateAdapter.addCalendarMonths(this.calendar.activeDate, -1) :
this._dateAdapter.addCalendarYears(this.calendar.activeDate, this.calendar.currentView == 'year' ? -1 : -yearsPerPage);
};
/** Handles user clicks on the next button. */
SatCalendarHeader.prototype.nextClicked = function () {
this.calendar.activeDate = this.calendar.currentView == 'month' ?
this._dateAdapter.addCalendarMonths(this.calendar.activeDate, 1) :
this._dateAdapter.addCalendarYears(this.calendar.activeDate, this.calendar.currentView == 'year' ? 1 : yearsPerPage);
};
/** Whether the previous period button is enabled. */
SatCalendarHeader.prototype.previousEnabled = function () {
if (!this.calendar.minDate) {
return true;
}
return !this.calendar.minDate ||
!this._isSameView(this.calendar.activeDate, this.calendar.minDate);
};
/** Whether the next period button is enabled. */
SatCalendarHeader.prototype.nextEnabled = function () {
return !this.calendar.maxDate ||
!this._isSameView(this.calendar.activeDate, this.calendar.maxDate);
};
/** Whether the two dates represent the same view in the current view mode (month or year). */
SatCalendarHeader.prototype._isSameView = function (date1, date2) {
if (this.calendar.currentView == 'month') {
return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2) &&
this._dateAdapter.getMonth(date1) == this._dateAdapter.getMonth(date2);
}
if (this.calendar.currentView == 'year') {
return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2);
}
// Otherwise we are in 'multi-year' view.
return isSameMultiYearView(this._dateAdapter, date1, date2, this.calendar.minDate, this.calendar.maxDate);
};
SatCalendarHeader.ctorParameters = function () { return [
{ type: SatDatepickerIntl },
{ type: SatCalendar, decorators: [{ type: Inject, args: [forwardRef(function () { return SatCalendar; }),] }] },
{ type: DateAdapter, decorators: [{ type: Optional }] },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DATE_FORMATS,] }] },
{ type: ChangeDetectorRef }
]; };
SatCalendarHeader = tslib_1.__decorate([
Component({
moduleId: module.id,
selector: 'sat-calendar-header',
template: "<div class=\"mat-calendar-header\">\n <div class=\"mat-calendar-controls\">\n <button mat-button type=\"button\" class=\"mat-calendar-period-button\"\n (click)=\"currentPeriodClicked()\" [attr.aria-label]=\"periodButtonLabel\"\n cdkAriaLive=\"polite\">\n {{periodButtonText}}\n <div class=\"mat-calendar-arrow\"\n [class.mat-calendar-invert]=\"calendar.currentView != 'month'\"></div>\n </button>\n\n <div class=\"mat-calendar-spacer\"></div>\n\n <ng-content></ng-content>\n\n <button mat-icon-button type=\"button\" class=\"mat-calendar-previous-button\"\n [disabled]=\"!previousEnabled()\" (click)=\"previousClicked()\"\n [attr.aria-label]=\"prevButtonLabel\">\n </button>\n\n <button mat-icon-button type=\"button\" class=\"mat-calendar-next-button\"\n [disabled]=\"!nextEnabled()\" (click)=\"nextClicked()\"\n [attr.aria-label]=\"nextButtonLabel\">\n </button>\n </div>\n</div>\n",
exportAs: 'matCalendarHeader',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
}),
tslib_1.__param(1, Inject(forwardRef(function () { return SatCalendar; }))),
tslib_1.__param(2, Optional()),
tslib_1.__param(3, Optional()), tslib_1.__param(3, Inject(MAT_DATE_FORMATS))
], SatCalendarHeader);
return SatCalendarHeader;
}());
export { SatCalendarHeader };
/** Default footer for SatCalendar */
var SatCalendarFooter = /** @class */ (function () {
function SatCalendarFooter() {
}
SatCalendarFooter = tslib_1.__decorate([
Component({
moduleId: module.id,
selector: 'sat-calendar-footer',
template: "",
exportAs: 'matCalendarFooter',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
], SatCalendarFooter);
return SatCalendarFooter;
}());
export { SatCalendarFooter };
/**
* A calendar that is used as part of the datepicker.
* @docs-private
*/
var SatCalendar = /** @class */ (function () {
function SatCalendar(_intl, _dateAdapter, _dateFormats, _changeDetectorRef) {
var _this = this;
this._dateAdapter = _dateAdapter;
this._dateFormats = _dateFormats;
this._changeDetectorRef = _changeDetectorRef;
/** Whenever datepicker is for selecting range of dates. */
this.rangeMode = false;
/** Enables datepicker MouseOver effect on range mode */
this.rangeHoverEffect = true;
/** Enables datepicker closing after selection */
this.closeAfterSelection = true;
/** Emits when new pair of dates selected. */
this.dateRangesChange = new EventEmitter();
/** Whenever user already selected start of dates interval. */
this.beginDateSelected = false;
/** Emits when a new start date has been selected in range mode. */
this.beginDateSelectedChange = new EventEmitter();
/**
* Used for scheduling that focus should be moved to the active cell on the next tick.
* We need to schedule it, rather than do it immediately, because we have to wait
* for Angular to re-evaluate the view children.
*/
this._moveFocusOnNextTick = false;
/** Whether the calendar should be started in month or year view. */
this.startView = 'month';
/** Order the views when clicking on period label button */
this.orderPeriodLabel = 'multi-year';
/** Emits when the currently selected date changes. */
this.selectedChange = new EventEmitter();
/**
* Emits the year chosen in multiyear view.
* This doesn't imply a change on the selected date.
*/
this.yearSelected = new EventEmitter();
/**
* Emits the month chosen in year view.
* This doesn't imply a change on the selected date.
*/
this.monthSelected = new EventEmitter();
/** Emits when any date is selected. */
this._userSelection = new EventEmitter();
/**
* Emits whenever there is a state change that the header may need to respond to.
*/
this.stateChanges = new Subject();
if (!this._dateAdapter) {
throw createMissingDateImplError('DateAdapter');
}
if (!this._dateFormats) {
throw createMissingDateImplError('MAT_DATE_FORMATS');
}
this._intlChanges = _intl.changes.subscribe(function () {
_changeDetectorRef.markForCheck();
_this.stateChanges.next();
});
}
Object.defineProperty(SatCalendar.prototype, "beginDate", {
/** Beginning of date range. */
get: function () { return this._beginDate; },
set: function (value) {
this._beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "endDate", {
/** Date range end. */
get: function () { return this._endDate; },
set: function (value) {
this._endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "startAt", {
/** A date representing the period (month or year) to start the calendar in. */
get: function () { return this._startAt; },
set: function (value) {
this._startAt = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "selected", {
/** The currently selected date. */
get: function () { return this._selected; },
set: function (value) {
this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "minDate", {
/** The minimum selectable date. */
get: function () { return this._minDate; },
set: function (value) {
this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "maxDate", {
/** The maximum selectable date. */
get: function () { return this._maxDate; },
set: function (value) {
this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "activeDate", {
/**
* The current active date. This determines which time period is shown and which date is
* highlighted when using keyboard navigation.
*/
get: function () { return this._clampedActiveDate; },
set: function (value) {
this._clampedActiveDate = this._dateAdapter.clampDate(value, this.minDate, this.maxDate);
this.stateChanges.next();
this._changeDetectorRef.markForCheck();
},
enumerable: true,
configurable: true
});
Object.defineProperty(SatCalendar.prototype, "currentView", {
/** Whether the calendar is in month view. */
get: function () { return this._currentView; },
set: function (value) {
this._currentView = value;
this._moveFocusOnNextTick = true;
this._changeDetectorRef.markForCheck();
},
enumerable: true,
configurable: true
});
SatCalendar.prototype.ngAfterContentInit = function () {
this._calendarHeaderPortal = new ComponentPortal(this.headerComponent || SatCalendarHeader);
this._calendarFooterPortal = new ComponentPortal(this.footerComponent || SatCalendarFooter);
this.activeDate = this.startAt || this._dateAdapter.today();
// Assign to the private property since we don't want to move focus on init.
this._currentView = this.startView;
};
SatCalendar.prototype.ngAfterViewChecked = function () {
if (this._moveFocusOnNextTick) {
this._moveFocusOnNextTick = false;
this.focusActiveCell();
}
};
SatCalendar.prototype.ngOnDestroy = function () {
this._intlChanges.unsubscribe();
this.stateChanges.complete();
};
SatCalendar.prototype.ngOnChanges = function (changes) {
var change = changes['minDate'] || changes['maxDate'] || changes['dateFilter'];
if (change && !change.firstChange) {
var view = this._getCurrentViewComponent();
if (view) {
// We need to `detectChanges` manually here, because the `minDate`, `maxDate` etc. are
// passed down to the view via data bindings which won't be up-to-date when we call `_init`.
this._changeDetectorRef.detectChanges();
view._init();
}
}
this.stateChanges.next();
};
SatCalendar.prototype.focusActiveCell = function () {
this._getCurrentViewComponent()._focusActiveCell();
};
/** Updates today's date after an update of the active date */
SatCalendar.prototype.updateTodaysDate = function () {
var view = this.currentView == 'month' ? this.monthView :
(this.currentView == 'year' ? this.yearView : this.multiYearView);
view.ngAfterContentInit();
};
/** Handles date selection in the month view. */
SatCalendar.prototype._dateSelected = function (date) {
if (this.rangeMode) {
if (!this.beginDateSelected) {
this.beginDateSelected = date;
this.beginDate = date;
this.endDate = date;
this.beginDateSelectedChange.emit(date);
}
else {
this.beginDateSelected = false;
if (this._dateAdapter.compareDate(this.beginDate, date) <= 0) {
this.endDate = date;
}
else {
this.endDate = this.beginDate;
this.beginDate = date;
}
this.dateRangesChange.emit({ begin: this.beginDate, end: this.endDate });
}
}
else if (!this._dateAdapter.sameDate(date, this.selected)) {
this.selectedChange.emit(date);
}
};
/** Handles year selection in the multiyear view. */
SatCalendar.prototype._yearSelectedInMultiYearView = function (normalizedYear) {
this.yearSelected.emit(normalizedYear);
};
/** Handles month selection in the year view. */
SatCalendar.prototype._monthSelectedInYearView = function (normalizedMonth) {
this.monthSelected.emit(normalizedMonth);
};
SatCalendar.prototype._userSelected = function () {
this._userSelection.emit();
};
/** Handles year/month selection in the multi-year/year views. */
SatCalendar.prototype._goToDateInView = function (date, view) {
this.activeDate = date;
this.currentView = view;
};
/**
* @param obj The object to check.
* @returns The given object if it is both a date instance and valid, otherwise null.
*/
SatCalendar.prototype._getValidDateOrNull = function (obj) {
return (this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj)) ? obj : null;
};
/** Returns the component instance that corresponds to the current calendar view. */
SatCalendar.prototype._getCurrentViewComponent = function () {
return this.monthView || this.yearView || this.multiYearView;
};
SatCalendar.ctorParameters = function () { return [
{ type: SatDatepickerIntl },
{ type: DateAdapter, decorators: [{ type: Optional }] },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DATE_FORMATS,] }] },
{ type: ChangeDetectorRef }
]; };
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "beginDate", null);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "endDate", null);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "rangeMode", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "rangeHoverEffect", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "closeAfterSelection", void 0);
tslib_1.__decorate([
Output()
], SatCalendar.prototype, "dateRangesChange", void 0);
tslib_1.__decorate([
Output()
], SatCalendar.prototype, "beginDateSelectedChange", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "headerComponent", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "footerComponent", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "startAt", null);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "startView", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "selected", null);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "minDate", null);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "maxDate", null);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "dateFilter", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "dateClass", void 0);
tslib_1.__decorate([
Input()
], SatCalendar.prototype, "orderPeriodLabel", void 0);
tslib_1.__decorate([
Output()
], SatCalendar.prototype, "selectedChange", void 0);
tslib_1.__decorate([
Output()
], SatCalendar.prototype, "yearSelected", void 0);
tslib_1.__decorate([
Output()
], SatCalendar.prototype, "monthSelected", void 0);
tslib_1.__decorate([
Output()
], SatCalendar.prototype, "_userSelection", void 0);
tslib_1.__decorate([
ViewChild(SatMonthView, { static: false })
], SatCalendar.prototype, "monthView", void 0);
tslib_1.__decorate([
ViewChild(SatYearView, { static: false })
], SatCalendar.prototype, "yearView", void 0);
tslib_1.__decorate([
ViewChild(SatMultiYearView, { static: false })
], SatCalendar.prototype, "multiYearView", void 0);
SatCalendar = tslib_1.__decorate([
Component({
moduleId: module.id,
selector: 'sat-calendar',
template: "\n<ng-template [cdkPortalOutlet]=\"_calendarHeaderPortal\"></ng-template>\n\n<div class=\"mat-calendar-content\" [ngSwitch]=\"currentView\" cdkMonitorSubtreeFocus tabindex=\"-1\">\n <sat-month-view\n *ngSwitchCase=\"'month'\"\n [(activeDate)]=\"activeDate\"\n [selected]=\"selected\"\n [beginDate]=\"beginDate\"\n [endDate]=\"endDate\"\n [rangeMode]=\"rangeMode\"\n [closeAfterSelection]=\"closeAfterSelection\"\n [rangeHoverEffect]=\"rangeHoverEffect\"\n [dateFilter]=\"dateFilter\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [dateClass]=\"dateClass\"\n [beginDateSelected]=\"beginDateSelected\"\n (selectedChange)=\"_dateSelected($event)\"\n (_userSelection)=\"_userSelected()\">\n </sat-month-view>\n\n <sat-year-view\n *ngSwitchCase=\"'year'\"\n [(activeDate)]=\"activeDate\"\n [selected]=\"selected\"\n [dateFilter]=\"dateFilter\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n (monthSelected)=\"_monthSelectedInYearView($event)\"\n (selectedChange)=\"_goToDateInView($event, 'month')\">\n </sat-year-view>\n\n <sat-multi-year-view\n *ngSwitchCase=\"'multi-year'\"\n [(activeDate)]=\"activeDate\"\n [selected]=\"selected\"\n [dateFilter]=\"dateFilter\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n (yearSelected)=\"_yearSelectedInMultiYearView($event)\"\n (selectedChange)=\"_goToDateInView($event, 'year')\">\n </sat-multi-year-view>\n</div>\n\n<ng-template [cdkPortalOutlet]=\"_calendarFooterPortal\"></ng-template>\n",
host: {
'class': 'mat-calendar',
},
exportAs: 'matCalendar',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".mat-calendar{display:block}.mat-calendar-header{padding:8px 8px 0}.mat-calendar-content{padding:0 8px 8px;outline:0}.mat-calendar-controls{display:flex;margin:5% calc(33% / 7 - 16px)}.mat-calendar-spacer{flex:1 1 auto}.mat-calendar-period-button{min-width:0}.mat-calendar-arrow{display:inline-block;width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top-width:5px;border-top-style:solid;margin:0 0 0 5px;vertical-align:middle}.mat-calendar-arrow.mat-calendar-invert{transform:rotate(180deg)}[dir=rtl] .mat-calendar-arrow{margin:0 5px 0 0}.mat-calendar-next-button,.mat-calendar-previous-button{position:relative}.mat-calendar-next-button::after,.mat-calendar-previous-button::after{top:0;left:0;right:0;bottom:0;position:absolute;content:'';margin:15.5px;border:0 solid currentColor;border-top-width:2px}[dir=rtl] .mat-calendar-next-button,[dir=rtl] .mat-calendar-previous-button{transform:rotate(180deg)}.mat-calendar-previous-button::after{border-left-width:2px;transform:translateX(2px) rotate(-45deg)}.mat-calendar-next-button::after{border-right-width:2px;transform:translateX(-2px) rotate(45deg)}.mat-calendar-table{border-spacing:0;border-collapse:collapse;width:100%}.mat-calendar-table-header th{text-align:center;padding:0 0 8px}.mat-calendar-table-header-divider{position:relative;height:1px}.mat-calendar-table-header-divider::after{content:'';position:absolute;top:0;left:-8px;right:-8px;height:1px}"]
}),
tslib_1.__param(1, Optional()),
tslib_1.__param(2, Optional()), tslib_1.__param(2, Inject(MAT_DATE_FORMATS))
], SatCalendar);
return SatCalendar;
}());
export { SatCalendar };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9zYXR1cm4tZGF0ZXBpY2tlci8iLCJzb3VyY2VzIjpbImRhdGVwaWNrZXIvY2FsZW5kYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HOztBQUVILE9BQU8sRUFBQyxlQUFlLEVBQXdCLE1BQU0scUJBQXFCLENBQUM7QUFDM0UsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLFNBQVMsRUFDVCxTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sRUFDTixhQUFhLEVBQ2IsU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsT0FBTyxFQUFlLE1BQU0sTUFBTSxDQUFDO0FBRTNDLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQy9ELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUNMLGVBQWUsRUFDZixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLFlBQVksRUFDYixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFHeEMsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBQyxnQkFBZ0IsRUFBaUIsTUFBTSwwQkFBMEIsQ0FBQztBQVExRSxxQ0FBcUM7QUFTckM7SUFDRSwyQkFBb0IsS0FBd0IsRUFDYyxRQUF3QixFQUNsRCxZQUE0QixFQUNGLFlBQTRCLEVBQzFFLGlCQUFvQztRQUo1QixVQUFLLEdBQUwsS0FBSyxDQUFtQjtRQUNjLGFBQVEsR0FBUixRQUFRLENBQWdCO1FBQ2xELGlCQUFZLEdBQVosWUFBWSxDQUFnQjtRQUNGLGlCQUFZLEdBQVosWUFBWSxDQUFnQjtRQUdwRixJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsY0FBTSxPQUFBLGlCQUFpQixDQUFDLFlBQVksRUFBRSxFQUFoQyxDQUFnQyxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUdELHNCQUFJLCtDQUFnQjtRQURwQiwrQ0FBK0M7YUFDL0M7WUFDRSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLE9BQU8sRUFBRTtnQkFDeEMsT0FBTyxJQUFJLENBQUMsWUFBWTtxQkFDbkIsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQztxQkFDdEUsaUJBQWlCLEVBQUUsQ0FBQzthQUM5QjtZQUNELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLElBQUksTUFBTSxFQUFFO2dCQUN2QyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDaEU7WUFFRCw2RUFBNkU7WUFDN0UsNEVBQTRFO1lBQzVFLDhCQUE4QjtZQUM5QixJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3ZFLElBQU0sYUFBYSxHQUFHLFVBQVUsR0FBRyxlQUFlLENBQ2hELElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM3RixJQUFNLGFBQWEsR0FBRyxhQUFhLEdBQUcsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUN2RCxPQUFVLGFBQWEsZ0JBQVcsYUFBZSxDQUFDO1FBQ3BELENBQUM7OztPQUFBO0lBRUQsc0JBQUksZ0RBQWlCO2FBQXJCO1lBQ0UsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQztnQkFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQztRQUNoRixDQUFDOzs7T0FBQTtJQUdELHNCQUFJLDhDQUFlO1FBRG5CLHlDQUF5QzthQUN6QztZQUNFLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYztnQkFDbEMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYTtnQkFDaEMsWUFBWSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO2FBQzVDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvQixDQUFDOzs7T0FBQTtJQUdELHNCQUFJLDhDQUFlO1FBRG5CLHFDQUFxQzthQUNyQztZQUNFLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYztnQkFDbEMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYTtnQkFDaEMsWUFBWSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCO2FBQzVDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvQixDQUFDOzs7T0FBQTtJQUVEOzs7O09BSUc7SUFDSCxnREFBb0IsR0FBcEI7UUFDRSxJQUFNLGVBQWUsR0FBc0IsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQzNFLElBQU0sWUFBWSxHQUFzQixDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDekUsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO1FBQ2hHLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUU7WUFDakMsS0FBSyxPQUFPO2dCQUNWLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0MsTUFBTTtZQUNSLEtBQUssTUFBTTtnQkFDUCxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQzFDLE1BQU07WUFDVjtnQkFDRSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQzFDLE1BQU07U0FDVDtJQUNILENBQUM7SUFFRCxrREFBa0Q7SUFDbEQsMkNBQWUsR0FBZjtRQUNFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9ELElBQUksQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQzlCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUNyRixDQUFDO0lBQ1osQ0FBQztJQUVELDhDQUE4QztJQUM5Qyx1Q0FBVyxHQUFYO1FBQ0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQzlCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUNwQixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUM3RCxDQUFDO0lBQ1osQ0FBQztJQUVELHFEQUFxRDtJQUNyRCwyQ0FBZSxHQUFmO1FBQ0UsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO1lBQ3pCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxpREFBaUQ7SUFDakQsdUNBQVcsR0FBWDtRQUNFLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU87WUFDekIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVELDhGQUE4RjtJQUN0Rix1Q0FBVyxHQUFuQixVQUFvQixLQUFRLEVBQUUsS0FBUTtRQUNwQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLE9BQU8sRUFBRTtZQUN4QyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztnQkFDdkUsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDNUU7UUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLE1BQU0sRUFBRTtZQUN2QyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzdFO1FBQ0QseUNBQXlDO1FBQ3pDLE9BQU8sbUJBQW1CLENBQ3hCLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ25GLENBQUM7O2dCQXpIMEIsaUJBQWlCO2dCQUN3QixXQUFXLHVCQUFsRSxNQUFNLFNBQUMsVUFBVSxDQUFDLGNBQU0sT0FBQSxXQUFXLEVBQVgsQ0FBVyxDQUFDO2dCQUNILFdBQVcsdUJBQTVDLFFBQVE7Z0RBQ1IsUUFBUSxZQUFJLE1BQU0sU0FBQyxnQkFBZ0I7Z0JBQ2pCLGlCQUFpQjs7SUFMckMsaUJBQWlCO1FBUjdCLFNBQVMsQ0FBQztZQUNULFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNuQixRQUFRLEVBQUUscUJBQXFCO1lBQy9CLCsrQkFBbUM7WUFDbkMsUUFBUSxFQUFFLG1CQUFtQjtZQUM3QixhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTtZQUNyQyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtTQUNoRCxDQUFDO1FBR2EsbUJBQUEsTUFBTSxDQUFDLFVBQVUsQ0FBQyxjQUFNLE9BQUEsV0FBVyxFQUFYLENBQVcsQ0FBQyxDQUFDLENBQUE7UUFDckMsbUJBQUEsUUFBUSxFQUFFLENBQUE7UUFDVixtQkFBQSxRQUFRLEVBQUUsQ0FBQSxFQUFFLG1CQUFBLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO09BSnRDLGlCQUFpQixDQTJIN0I7SUFBRCx3QkFBQztDQUFBLEFBM0hELElBMkhDO1NBM0hZLGlCQUFpQjtBQTZIOUIscUNBQXFDO0FBU3JDO0lBQUE7SUFDQSxDQUFDO0lBRFksaUJBQWlCO1FBUjdCLFNBQVMsQ0FBQztZQUNULFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNuQixRQUFRLEVBQUUscUJBQXFCO1lBQy9CLFlBQW1DO1lBQ25DLFFBQVEsRUFBRSxtQkFBbUI7WUFDN0IsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7WUFDckMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07U0FDaEQsQ0FBQztPQUNXLGlCQUFpQixDQUM3QjtJQUFELHdCQUFDO0NBQUEsQUFERCxJQUNDO1NBRFksaUJBQWlCO0FBRzlCOzs7R0FHRztBQWFIO0lBMEpFLHFCQUFZLEtBQXdCLEVBQ0osWUFBNEIsRUFDRixZQUE0QixFQUNsRSxrQkFBcUM7UUFIekQsaUJBaUJDO1FBaEIrQixpQkFBWSxHQUFaLFlBQVksQ0FBZ0I7UUFDRixpQkFBWSxHQUFaLFlBQVksQ0FBZ0I7UUFDbEUsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFtQjtRQTNJdkQsMkRBQTJEO1FBQ2xELGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFM0Isd0RBQXdEO1FBQy9DLHFCQUFnQixHQUFHLElBQUksQ0FBQztRQUVqQyxpREFBaUQ7UUFDeEMsd0JBQW1CLEdBQUcsSUFBSSxDQUFDO1FBRXBDLDZDQUE2QztRQUNuQyxxQkFBZ0IsR0FBRyxJQUFJLFlBQVksRUFBOEIsQ0FBQztRQUU1RSw4REFBOEQ7UUFDOUQsc0JBQWlCLEdBQWdCLEtBQUssQ0FBQztRQUV2QyxtRUFBbUU7UUFDekQsNEJBQXVCLEdBQUcsSUFBSSxZQUFZLEVBQUssQ0FBQztRQWdCNUQ7Ozs7V0FJRztRQUNLLHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQVVyQyxvRUFBb0U7UUFDM0QsY0FBUyxHQUFvQixPQUFPLENBQUM7UUFnQzlDLDJEQUEyRDtRQUNsRCxxQkFBZ0IsR0FBMkIsWUFBWSxDQUFDO1FBRWpFLHNEQUFzRDtRQUNuQyxtQkFBYyxHQUFvQixJQUFJLFlBQVksRUFBSyxDQUFDO1FBRTNFOzs7V0FHRztRQUNnQixpQkFBWSxHQUFvQixJQUFJLFlBQVksRUFBSyxDQUFDO1FBRXpFOzs7V0FHRztRQUNnQixrQkFBYSxHQUFvQixJQUFJLFlBQVksRUFBSyxDQUFDO1FBRTFFLHVDQUF1QztRQUNwQixtQkFBYyxHQUF1QixJQUFJLFlBQVksRUFBUSxDQUFDO1FBZ0NqRjs7V0FFRztRQUNILGlCQUFZLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQU9qQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixNQUFNLDBCQUEwQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQ2pEO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdEIsTUFBTSwwQkFBMEIsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1NBQ3REO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztZQUMxQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNsQyxLQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQXZLQyxzQkFBSSxrQ0FBUztRQUZiLCtCQUErQjthQUUvQixjQUE0QixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2FBQ3JELFVBQWMsS0FBZTtZQUN6QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3JGLENBQUM7OztPQUhvRDtJQVFyRCxzQkFBSSxnQ0FBTztRQUZYLHNCQUFzQjthQUV0QixjQUEwQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2FBQ2pELFVBQVksS0FBZTtZQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ25GLENBQUM7OztPQUhnRDtJQStDbkQsc0JBQUksZ0NBQU87UUFGWCwrRUFBK0U7YUFFL0UsY0FBMEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQzthQUNqRCxVQUFZLEtBQWU7WUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNqRixDQUFDOzs7T0FIZ0Q7SUFXakQsc0JBQUksaUNBQVE7UUFGWixtQ0FBbUM7YUFFbkMsY0FBMkIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQzthQUNuRCxVQUFhLEtBQWU7WUFDMUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNsRixDQUFDOzs7T0FIa0Q7SUFRbkQsc0JBQUksZ0NBQU87UUFGWCxtQ0FBbUM7YUFFbkMsY0FBMEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQzthQUNqRCxVQUFZLEtBQWU7WUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNqRixDQUFDOzs7T0FIZ0Q7SUFRakQsc0JBQUksZ0NBQU87UUFGWCxtQ0FBbUM7YUFFbkMsY0FBMEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQzthQUNqRCxVQUFZLEtBQWU7WUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNqRixDQUFDOzs7T0FIZ0Q7SUE4Q2pELHNCQUFJLG1DQUFVO1FBSmQ7OztXQUdHO2FBQ0gsY0FBc0IsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO2FBQ3ZELFVBQWUsS0FBUTtZQUNyQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3pGLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3pDLENBQUM7OztPQUxzRDtJQVN2RCxzQkFBSSxvQ0FBVztRQURmLDZDQUE2QzthQUM3QyxjQUFxQyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2FBQ2hFLFVBQWdCLEtBQXNCO1lBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1lBQzFCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7WUFDakMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3pDLENBQUM7OztPQUwrRDtJQWdDaEUsd0NBQWtCLEdBQWxCO1FBQ0UsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksaUJBQWlCLENBQUMsQ0FBQztRQUM1RixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxpQkFBaUIsQ0FBQyxDQUFDO1FBQzVGLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRTVELDRFQUE0RTtRQUM1RSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDckMsQ0FBQztJQUVELHdDQUFrQixHQUFsQjtRQUNFLElBQUksSUFBSSxDQUFDLG9CQUFvQixFQUFFO1lBQzdCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFDbEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1NBQ3hCO0lBQ0gsQ0FBQztJQUVELGlDQUFXLEdBQVg7UUFDRSxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELGlDQUFXLEdBQVgsVUFBWSxPQUFzQjtRQUNoQyxJQUFNLE1BQU0sR0FDUixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV0RSxJQUFJLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUU7WUFDakMsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7WUFFN0MsSUFBSSxJQUFJLEVBQUU7Z0JBQ1Isc0ZBQXNGO2dCQUN0Riw0RkFBNEY7Z0JBQzVGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ2Q7U0FDRjtRQUVELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELHFDQUFlLEdBQWY7UUFDRSxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ3JELENBQUM7SUFFRCw4REFBOEQ7SUFDOUQsc0NBQWdCLEdBQWhCO1FBQ0UsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqRCxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFMUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELGdEQUFnRDtJQUNoRCxtQ0FBYSxHQUFiLFVBQWMsSUFBTztRQUNuQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztnQkFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO2dCQUNwQixJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ3pDO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7Z0JBQy9CLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQy9ELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO2lCQUNyQjtxQkFBTTtvQkFDTCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7b0JBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2lCQUN2QjtnQkFDRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUMsS0FBSyxFQUFLLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUMsQ0FBQyxDQUFDO2FBQzNFO1NBQ0o7YUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUMzRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoQztJQUNILENBQUM7SUFFRCxvREFBb0Q7SUFDcEQsa0RBQTRCLEdBQTVCLFVBQTZCLGNBQWlCO1FBQzVDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxnREFBZ0Q7SUFDaEQsOENBQXdCLEdBQXhCLFVBQXlCLGVBQWtCO1FBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxtQ0FBYSxHQUFiO1FBQ0UsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsaUVBQWlFO0lBQ2pFLHFDQUFlLEdBQWYsVUFBZ0IsSUFBTyxFQUFFLElBQXFDO1FBQzVELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQzFCLENBQUM7SUFFRDs7O09BR0c7SUFDSyx5Q0FBbUIsR0FBM0IsVUFBNEIsR0FBUTtRQUNsQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDaEcsQ0FBQztJQUVELG9GQUFvRjtJQUM1RSw4Q0FBd0IsR0FBaEM7UUFDRSxPQUFPLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQy9ELENBQUM7O2dCQTVIa0IsaUJBQWlCO2dCQUNVLFdBQVcsdUJBQTVDLFFBQVE7Z0RBQ1IsUUFBUSxZQUFJLE1BQU0sU0FBQyxnQkFBZ0I7Z0JBQ1IsaUJBQWlCOztJQXpKdkQ7UUFEQyxLQUFLLEVBQUU7Z0RBQzZDO0lBUXJEO1FBREMsS0FBSyxFQUFFOzhDQUN5QztJQU94QztRQUFSLEtBQUssRUFBRTtrREFBbUI7SUFHbEI7UUFBUixLQUFLLEVBQUU7eURBQXlCO0lBR3hCO1FBQVIsS0FBSyxFQUFFOzREQUE0QjtJQUcxQjtRQUFULE1BQU0sRUFBRTt5REFBbUU7SUFNbEU7UUFBVCxNQUFNLEVBQUU7Z0VBQWlEO0lBR25EO1FBQVIsS0FBSyxFQUFFO3dEQUFxQztJQU1wQztRQUFSLEtBQUssRUFBRTt3REFBcUM7SUFnQjdDO1FBREMsS0FBSyxFQUFFOzhDQUN5QztJQU94QztRQUFSLEtBQUssRUFBRTtrREFBc0M7SUFJOUM7UUFEQyxLQUFLLEVBQUU7K0NBQzJDO0lBUW5EO1FBREMsS0FBSyxFQUFFOzhDQUN5QztJQVFqRDtRQURDLEtBQUssRUFBRTs4Q0FDeUM7SUFPeEM7UUFBUixLQUFLLEVBQUU7bURBQWtDO0lBR2pDO1FBQVIsS0FBSyxFQUFFO2tEQUFtRDtJQUdsRDtRQUFSLEtBQUssRUFBRTt5REFBeUQ7SUFHdkQ7UUFBVCxNQUFNLEVBQUU7dURBQWtFO0lBTWpFO1FBQVQsTUFBTSxFQUFFO3FEQUFnRTtJQU0vRDtRQUFULE1BQU0sRUFBRTtzREFBaUU7SUFHaEU7UUFBVCxNQUFNLEVBQUU7dURBQXdFO0lBR3ZDO1FBQXpDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUM7a0RBQTRCO0lBRzVCO1FBQXhDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUM7aURBQTBCO0lBR3BCO1FBQTdDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQztzREFBb0M7SUE5SHRFLFdBQVc7UUFadkIsU0FBUyxDQUFDO1lBQ1QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ25CLFFBQVEsRUFBRSxjQUFjO1lBQ3hCLDRrREFBNEI7WUFFNUIsSUFBSSxFQUFFO2dCQUNKLE9BQU8sRUFBRSxjQUFjO2FBQ3hCO1lBQ0QsUUFBUSxFQUFFLGFBQWE7WUFDdkIsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7WUFDckMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07O1NBQ2hELENBQUM7UUE0SmEsbUJBQUEsUUFBUSxFQUFFLENBQUE7UUFDVixtQkFBQSxRQUFRLEVBQUUsQ0FBQSxFQUFFLG1CQUFBLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO09BNUp0QyxXQUFXLENBdVJ2QjtJQUFELGtCQUFDO0NBQUEsQUF2UkQsSUF1UkM7U0F2UlksV0FBVyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0NvbXBvbmVudFBvcnRhbCwgQ29tcG9uZW50VHlwZSwgUG9ydGFsfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIEFmdGVyVmlld0NoZWNrZWQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7U3ViamVjdCwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7U2F0Q2FsZW5kYXJDZWxsQ3NzQ2xhc3Nlc30gZnJvbSAnLi9jYWxlbmRhci1ib2R5JztcbmltcG9ydCB7Y3JlYXRlTWlzc2luZ0RhdGVJbXBsRXJyb3J9IGZyb20gJy4vZGF0ZXBpY2tlci1lcnJvcnMnO1xuaW1wb3J0IHtTYXREYXRlcGlja2VySW50bH0gZnJvbSAnLi9kYXRlcGlja2VyLWludGwnO1xuaW1wb3J0IHtTYXRNb250aFZpZXd9IGZyb20gJy4vbW9udGgtdmlldyc7XG5pbXBvcnQge1xuICBnZXRBY3RpdmVPZmZzZXQsXG4gIGlzU2FtZU11bHRpWWVhclZpZXcsXG4gIFNhdE11bHRpWWVhclZpZXcsXG4gIHllYXJzUGVyUGFnZVxufSBmcm9tICcuL211bHRpLXllYXItdmlldyc7XG5pbXBvcnQge1NhdFllYXJWaWV3fSBmcm9tICcuL3llYXItdmlldyc7XG5cbmltcG9ydCB7U2F0RGF0ZXBpY2tlclJhbmdlVmFsdWV9IGZyb20gJy4vZGF0ZXBpY2tlci1pbnB1dCc7XG5pbXBvcnQge0RhdGVBZGFwdGVyfSBmcm9tICcuLi9kYXRldGltZS9kYXRlLWFkYXB0ZXInO1xuaW1wb3J0IHtNQVRfREFURV9GT1JNQVRTLCBNYXREYXRlRm9ybWF0c30gZnJvbSAnLi4vZGF0ZXRpbWUvZGF0ZS1mb3JtYXRzJztcblxuLyoqXG4gKiBQb3NzaWJsZSB2aWV3cyBmb3IgdGhlIGNhbGVuZGFyLlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5leHBvcnQgdHlwZSBTYXRDYWxlbmRhclZpZXcgPSAnbW9udGgnIHwgJ3llYXInIHwgJ211bHRpLXllYXInO1xuXG4vKiogRGVmYXVsdCBoZWFkZXIgZm9yIFNhdENhbGVuZGFyICovXG5AQ29tcG9uZW50KHtcbiAgbW9kdWxlSWQ6IG1vZHVsZS5pZCxcbiAgc2VsZWN0b3I6ICdzYXQtY2FsZW5kYXItaGVhZGVyJyxcbiAgdGVtcGxhdGVVcmw6ICdjYWxlbmRhci1oZWFkZXIuaHRtbCcsXG4gIGV4cG9ydEFzOiAnbWF0Q2FsZW5kYXJIZWFkZXInLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2F0Q2FsZW5kYXJIZWFkZXI8RD4ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9pbnRsOiBTYXREYXRlcGlja2VySW50bCxcbiAgICAgICAgICAgICAgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IFNhdENhbGVuZGFyKSkgcHVibGljIGNhbGVuZGFyOiBTYXRDYWxlbmRhcjxEPixcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBfZGF0ZUFkYXB0ZXI6IERhdGVBZGFwdGVyPEQ+LFxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE1BVF9EQVRFX0ZPUk1BVFMpIHByaXZhdGUgX2RhdGVGb3JtYXRzOiBNYXREYXRlRm9ybWF0cyxcbiAgICAgICAgICAgICAgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XG5cbiAgICB0aGlzLmNhbGVuZGFyLnN0YXRlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCkpO1xuICB9XG5cbiAgLyoqIFRoZSBsYWJlbCBmb3IgdGhlIGN1cnJlbnQgY2FsZW5kYXIgdmlldy4gKi9cbiAgZ2V0IHBlcmlvZEJ1dHRvblRleHQoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5jYWxlbmRhci5jdXJyZW50VmlldyA9PSAnbW9udGgnKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZGF0ZUFkYXB0ZXJcbiAgICAgICAgICAuZm9ybWF0KHRoaXMuY2FsZW5kYXIuYWN0aXZlRGF0ZSwgdGhpcy5fZGF0ZUZvcm1hdHMuZGlzcGxheS5tb250aFllYXJMYWJlbClcbiAgICAgICAgICAgICAgLnRvTG9jYWxlVXBwZXJDYXNlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3ID09ICd5ZWFyJykge1xuICAgICAgcmV0dXJuIHRoaXMuX2RhdGVBZGFwdGVyLmdldFllYXJOYW1lKHRoaXMuY2FsZW5kYXIuYWN0aXZlRGF0ZSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIG9mZnNldCBmcm9tIHRoZSBhY3RpdmUgeWVhciB0byB0aGUgXCJzbG90XCIgZm9yIHRoZSBzdGFydGluZyB5ZWFyIGlzIHRoZVxuICAgIC8vICphY3R1YWwqIGZpcnN0IHJlbmRlcmVkIHllYXIgaW4gdGhlIG11bHRpLXllYXIgdmlldywgYW5kIHRoZSBsYXN0IHllYXIgaXNcbiAgICAvLyBqdXN0IHllYXJzUGVyUGFnZSAtIDEgYXdheS5cbiAgICBjb25zdCBhY3RpdmVZZWFyID0gdGhpcy5fZGF0ZUFkYXB0ZXIuZ2V0WWVhcih0aGlzLmNhbGVuZGFyLmFjdGl2ZURhdGUpO1xuICAgIGNvbnN0IG1pblllYXJPZlBhZ2UgPSBhY3RpdmVZZWFyIC0gZ2V0QWN0aXZlT2Zmc2V0KFxuICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIsIHRoaXMuY2FsZW5kYXIuYWN0aXZlRGF0ZSwgdGhpcy5jYWxlbmRhci5taW5EYXRlLCB0aGlzLmNhbGVuZGFyLm1heERhdGUpO1xuICAgIGNvbnN0IG1heFllYXJPZlBhZ2UgPSBtaW5ZZWFyT2ZQYWdlICsgeWVhcnNQZXJQYWdlIC0gMTtcbiAgICByZXR1cm4gYCR7bWluWWVhck9mUGFnZX0gXFx1MjAxMyAke21heFllYXJPZlBhZ2V9YDtcbiAgfVxuXG4gIGdldCBwZXJpb2RCdXR0b25MYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3ID09ICdtb250aCcgP1xuICAgICAgICB0aGlzLl9pbnRsLnN3aXRjaFRvTXVsdGlZZWFyVmlld0xhYmVsIDogdGhpcy5faW50bC5zd2l0Y2hUb01vbnRoVmlld0xhYmVsO1xuICB9XG5cbiAgLyoqIFRoZSBsYWJlbCBmb3IgdGhlIHByZXZpb3VzIGJ1dHRvbi4gKi9cbiAgZ2V0IHByZXZCdXR0b25MYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB7XG4gICAgICAnbW9udGgnOiB0aGlzLl9pbnRsLnByZXZNb250aExhYmVsLFxuICAgICAgJ3llYXInOiB0aGlzLl9pbnRsLnByZXZZZWFyTGFiZWwsXG4gICAgICAnbXVsdGkteWVhcic6IHRoaXMuX2ludGwucHJldk11bHRpWWVhckxhYmVsXG4gICAgfVt0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3XTtcbiAgfVxuXG4gIC8qKiBUaGUgbGFiZWwgZm9yIHRoZSBuZXh0IGJ1dHRvbi4gKi9cbiAgZ2V0IG5leHRCdXR0b25MYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB7XG4gICAgICAnbW9udGgnOiB0aGlzLl9pbnRsLm5leHRNb250aExhYmVsLFxuICAgICAgJ3llYXInOiB0aGlzLl9pbnRsLm5leHRZZWFyTGFiZWwsXG4gICAgICAnbXVsdGkteWVhcic6IHRoaXMuX2ludGwubmV4dE11bHRpWWVhckxhYmVsXG4gICAgfVt0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3XTtcbiAgfVxuXG4gIC8qKiBIYW5kbGVzIHVzZXIgY2xpY2tzIG9uIHRoZSBwZXJpb2QgbGFiZWwuXG4gICAqIE9wdGlvbmBjYWxlbmRhci5vcmRlclBlcmlvZExhYmVsYCBzb3J0IHRoZSBsYWJlbCBwZXJpb2Qgdmlld3MuXG4gICAqIC0gRGVmYXVsdCBbbXVsdGkteWVhcl06IG11bHRpLXllYXIgdGhlbiBiYWNrIHRvIG1vbnRoXG4gICAqIC0gTW9udGggW21vbnRoXTogbW9udGggPiB5ZWFyID4gbXVsdGkteWVhclxuICAgKi9cbiAgY3VycmVudFBlcmlvZENsaWNrZWQoKTogdm9pZCB7XG4gICAgY29uc3QgbW91dGhGaXJzdE9yZGVyOiBTYXRDYWxlbmRhclZpZXdbXSA9IFsnbW9udGgnLCAneWVhcicsICdtdWx0aS15ZWFyJ107XG4gICAgY29uc3QgZGVmYXVsdE9yZGVyOiBTYXRDYWxlbmRhclZpZXdbXSA9IFsnbW9udGgnLCAnbXVsdGkteWVhcicsICdtb250aCddO1xuICAgIGNvbnN0IG9yZGVyUGVyaW9kID0gdGhpcy5jYWxlbmRhci5vcmRlclBlcmlvZExhYmVsID09PSAnbW9udGgnID8gbW91dGhGaXJzdE9yZGVyIDogZGVmYXVsdE9yZGVyO1xuICAgIHN3aXRjaCAodGhpcy5jYWxlbmRhci5jdXJyZW50Vmlldykge1xuICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICB0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3ID0gb3JkZXJQZXJpb2RbMV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgdGhpcy5jYWxlbmRhci5jdXJyZW50VmlldyA9IG9yZGVyUGVyaW9kWzJdXG4gICAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3ID0gb3JkZXJQZXJpb2RbMF1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLyoqIEhhbmRsZXMgdXNlciBjbGlja3Mgb24gdGhlIHByZXZpb3VzIGJ1dHRvbi4gKi9cbiAgcHJldmlvdXNDbGlja2VkKCk6IHZvaWQge1xuICAgIHRoaXMuY2FsZW5kYXIuYWN0aXZlRGF0ZSA9IHRoaXMuY2FsZW5kYXIuY3VycmVudFZpZXcgPT0gJ21vbnRoJyA/XG4gICAgICAgIHRoaXMuX2RhdGVBZGFwdGVyLmFkZENhbGVuZGFyTW9udGhzKHRoaXMuY2FsZW5kYXIuYWN0aXZlRGF0ZSwgLTEpIDpcbiAgICAgICAgICAgIHRoaXMuX2RhdGVBZGFwdGVyLmFkZENhbGVuZGFyWWVhcnMoXG4gICAgICAgICAgICAgICAgdGhpcy5jYWxlbmRhci5hY3RpdmVEYXRlLCB0aGlzLmNhbGVuZGFyLmN1cnJlbnRWaWV3ID09ICd5ZWFyJyA/IC0xIDogLXllYXJzUGVyUGFnZVxuICAgICAgICAgICAgKTtcbiAgfVxuXG4gIC8qKiBIYW5kbGVzIHVzZXIgY2xpY2tzIG9uIHRoZSBuZXh0IGJ1dHRvbi4gKi9cbiAgbmV4dENsaWNrZWQoKTogdm9pZCB7XG4gICAgdGhpcy5jYWxlbmRhci5hY3RpdmVEYXRlID0gdGhpcy5jYWxlbmRhci5jdXJyZW50VmlldyA9PSAnbW9udGgnID9cbiAgICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuYWRkQ2FsZW5kYXJNb250aHModGhpcy5jYWxlbmRhc