@nova-ui/bits
Version:
SolarWinds Nova Framework
319 lines • 42 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import { Component, EventEmitter, Input, Output, } from "@angular/core";
import _each from "lodash/each";
import _isNil from "lodash/isNil";
import _uniqueId from "lodash/uniqueId";
import moment from "moment/moment";
import { Subject } from "rxjs";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
/** @ignore */
export class DatePickerInnerComponent {
constructor() {
this.selectionDone = new EventEmitter();
this.update = new EventEmitter();
this.stepDay = {};
this.stepMonth = {};
this.stepYear = {};
this.calendarMoved = new Subject();
this._todayDate = moment();
this.modes = ["day", "month", "year"];
}
get role() {
return this.inline ? "application" : "dialog";
}
get value() {
return this._value;
}
set value(value) {
if (!this.preserveInsignificant && value) {
value.set({ hour: 0, minute: 0, second: 0, millisecond: 0 });
}
this._value = value;
}
ngOnInit() {
this.uniqueId = _uniqueId("date-picker--");
if (this.initDate) {
this.value = moment(this.initDate);
this.selectionDone.emit(this.value);
this.update.emit(this.value);
}
else if (_isNil(this.value)) {
this.value = this._todayDate.clone();
}
}
ngAfterContentInit() {
this.refreshView();
this.isTodayButtonDisabled = this.isDisabled(this._todayDate);
}
// this.refreshView should be called here to reflect the changes on the fly
ngOnChanges(changes) {
if (this.shouldRefreshViewOnChanges(changes)) {
this.refreshView();
}
}
shouldRefreshViewOnChanges(changes) {
let shouldRefreshView;
switch (this.datepickerMode) {
case "day":
shouldRefreshView =
!_isNil(changes.value) &&
!_isNil(this.selectedDate) &&
!changes.value.currentValue.isSame(changes.value.previousValue);
break;
case "month":
shouldRefreshView =
!_isNil(this.value) &&
!_isNil(this.selectedDate) &&
this.value.month() !== this.selectedDate.month();
break;
case "year":
shouldRefreshView =
!_isNil(this.value) &&
!_isNil(this.selectedDate) &&
this.value.year() !== this.selectedDate.year();
break;
default:
shouldRefreshView = false;
}
if (shouldRefreshView) {
_each(changes, (change) => {
shouldRefreshView =
!change.firstChange &&
moment.isMoment(change.currentValue) &&
!change.currentValue.isSame(change.previousValue);
});
}
return shouldRefreshView;
}
setCompareHandler(handler, type) {
if (type === "day") {
this.compareHandlerDay = handler;
}
if (type === "month") {
this.compareHandlerMonth = handler;
}
if (type === "year") {
this.compareHandlerYear = handler;
}
}
compare(date1, date2) {
if (_isNil(date1) || _isNil(date2)) {
return undefined;
}
if (this.datepickerMode === "day" && this.compareHandlerDay) {
return this.compareHandlerDay(date1, date2);
}
if (this.datepickerMode === "month" && this.compareHandlerMonth) {
return this.compareHandlerMonth(date1, date2);
}
if (this.datepickerMode === "year" && this.compareHandlerYear) {
return this.compareHandlerYear(date1, date2);
}
return void 0;
}
setRefreshViewHandler(handler, type) {
if (type === "day") {
this.refreshViewHandlerDay = handler;
}
if (type === "month") {
this.refreshViewHandlerMonth = handler;
}
if (type === "year") {
this.refreshViewHandlerYear = handler;
}
}
refreshView() {
if (this.datepickerMode === "day" && this.refreshViewHandlerDay) {
this.refreshViewHandlerDay();
}
if (this.datepickerMode === "month" && this.refreshViewHandlerMonth) {
this.refreshViewHandlerMonth();
}
if (this.datepickerMode === "year" && this.refreshViewHandlerYear) {
this.refreshViewHandlerYear();
}
}
createDateObject(date, format) {
return {
date: date.clone().toISOString(this.handleTimezone),
label: this.formatDate(date, format),
selected: this.compare(date, this.selectedDate) === 0,
disabled: this.isDisabled(date),
current: this.compare(date, this.value) === 0,
today: this.compare(date, this._todayDate) === 0,
};
}
split(arr, size) {
const arrays = [];
while (arr.length > 0) {
arrays.push(arr.splice(0, size));
}
return arrays;
}
select(date, event) {
this.value = this.handleTimezone
? moment.parseZone(date)
: moment(date);
if (this.datepickerMode === this.minMode) {
this.selectionDone.emit(this.value);
}
else {
this.datepickerMode =
this.modes[this.modes.indexOf(this.datepickerMode) - 1];
event.stopPropagation();
}
this.update.emit(this.value);
this.refreshView();
}
move(direction, event) {
let expectedStep;
if (this.datepickerMode === "day") {
expectedStep = this.stepDay;
}
if (this.datepickerMode === "month") {
expectedStep = this.stepMonth;
}
if (this.datepickerMode === "year") {
expectedStep = this.stepYear;
}
if (expectedStep) {
const activeDateMoment = this.value || moment();
const year = activeDateMoment.year() + direction * (expectedStep.years || 0);
const month = activeDateMoment.month() +
direction * (expectedStep.months || 0);
this.value = activeDateMoment
.clone()
.set({ year: year, month: month, date: 1 });
this.refreshView();
this.calendarMoved.next(this.value);
}
event.stopPropagation();
}
toggleMode(event, _direction) {
const direction = _direction || 1;
if ((this.datepickerMode === this.maxMode && direction === 1) ||
(this.datepickerMode === this.minMode && direction === -1)) {
return;
}
this.datepickerMode =
this.modes[this.modes.indexOf(this.datepickerMode) + direction];
this.refreshView();
event.stopPropagation();
}
isDisabled(date) {
let isDateDisabled = false;
if (this.disabledDates) {
this.disabledDates.forEach((disabledDate) => {
if (this.compareDateDisabled(disabledDate, date) === 0) {
isDateDisabled = true;
}
});
}
if (isDateDisabled) {
return isDateDisabled;
}
const diff1 = this.compare(date, this.minDate);
const diff2 = this.compare(date, this.maxDate);
return ((this.minDate && (diff1 || 0) < 0) ||
(this.maxDate && (diff2 || 0) > 0));
}
formatDate(date, format) {
return moment(date).clone().format(format);
}
compareDateDisabled(date1Disabled, date2) {
if (_isNil(date1Disabled) || _isNil(date2)) {
return undefined;
}
if (date1Disabled.mode === "day" && this.compareHandlerDay) {
return this.compareHandlerDay(date1Disabled.date, date2);
}
if (date1Disabled.mode === "month" && this.compareHandlerMonth) {
return this.compareHandlerMonth(date1Disabled.date, date2);
}
if (date1Disabled.mode === "year" && this.compareHandlerYear) {
return this.compareHandlerYear(date1Disabled.date, date2);
}
return undefined;
}
ngOnDestroy() {
this.calendarMoved.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DatePickerInnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DatePickerInnerComponent, selector: "nui-date-picker-inner", inputs: { locale: "locale", datepickerMode: "datepickerMode", startingDay: "startingDay", yearRange: "yearRange", minDate: "minDate", maxDate: "maxDate", minMode: "minMode", maxMode: "maxMode", showWeeks: "showWeeks", dateFormat: "dateFormat", formatDay: "formatDay", formatMonth: "formatMonth", formatYear: "formatYear", formatDayHeader: "formatDayHeader", formatDayTitle: "formatDayTitle", formatMonthTitle: "formatMonthTitle", onlyCurrentMonth: "onlyCurrentMonth", preserveInsignificant: "preserveInsignificant", disabledDates: "disabledDates", initDate: "initDate", inline: "inline", selectedDate: "selectedDate", handleTimezone: "handleTimezone", value: "value" }, outputs: { selectionDone: "selectionDone", update: "update" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"datepickerMode\" class=\"nui-datepicker-inner\" [attr.role]=\"role\">\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DatePickerInnerComponent, decorators: [{
type: Component,
args: [{ selector: "nui-date-picker-inner", template: "<div *ngIf=\"datepickerMode\" class=\"nui-datepicker-inner\" [attr.role]=\"role\">\n <ng-content></ng-content>\n</div>\n" }]
}], propDecorators: { locale: [{
type: Input
}], datepickerMode: [{
type: Input
}], startingDay: [{
type: Input
}], yearRange: [{
type: Input
}], minDate: [{
type: Input
}], maxDate: [{
type: Input
}], minMode: [{
type: Input
}], maxMode: [{
type: Input
}], showWeeks: [{
type: Input
}], dateFormat: [{
type: Input
}], formatDay: [{
type: Input
}], formatMonth: [{
type: Input
}], formatYear: [{
type: Input
}], formatDayHeader: [{
type: Input
}], formatDayTitle: [{
type: Input
}], formatMonthTitle: [{
type: Input
}], onlyCurrentMonth: [{
type: Input
}], preserveInsignificant: [{
type: Input
}], disabledDates: [{
type: Input
}], initDate: [{
type: Input
}], inline: [{
type: Input
}], selectedDate: [{
type: Input
}], handleTimezone: [{
type: Input
}], selectionDone: [{
type: Output
}], update: [{
type: Output
}], value: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXItaW5uZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9kYXRlLXBpY2tlci9kYXRlLXBpY2tlci1pbm5lci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLWlubmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBRUgsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxHQUVULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUNoQyxPQUFPLE1BQU0sTUFBTSxjQUFjLENBQUM7QUFDbEMsT0FBTyxTQUFTLE1BQU0saUJBQWlCLENBQUM7QUFDeEMsT0FBTyxNQUFNLE1BQU0sZUFBZSxDQUFDO0FBRW5DLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7OztBQUcvQixjQUFjO0FBS2QsTUFBTSxPQUFPLHdCQUF3QjtJQUpyQztRQWlDSSxrQkFBYSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBR2pFLFdBQU0sR0FBeUIsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUVuRCxZQUFPLEdBQVEsRUFBRSxDQUFDO1FBQ2xCLGNBQVMsR0FBUSxFQUFFLENBQUM7UUFDcEIsYUFBUSxHQUFRLEVBQUUs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RFosTUFBTTtnQkFJUCxNQUFNO3NCQURMLE1BQU07Z0JBNkJILEtBQUs7c0JBRFIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQge1xuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBJbnB1dCxcbiAgICBPbkNoYW5nZXMsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG4gICAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCBfZWFjaCBmcm9tIFwibG9kYXNoL2VhY2hcIjtcbmltcG9ydCBfaXNOaWwgZnJvbSBcImxvZGFzaC9pc05pbFwiO1xuaW1wb3J0IF91bmlxdWVJZCBmcm9tIFwibG9kYXNoL3VuaXF1ZUlkXCI7XG5pbXBvcnQgbW9tZW50IGZyb20gXCJtb21lbnQvbW9tZW50XCI7XG5pbXBvcnQgeyBNb21lbnQgfSBmcm9tIFwibW9tZW50L21vbWVudFwiO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCJyeGpzXCI7XG5cbmltcG9ydCB7IElEYXRlUGlja2VyRGlzYWJsZWREYXRlIH0gZnJvbSBcIi4vcHVibGljLWFwaVwiO1xuLyoqIEBpZ25vcmUgKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiBcIm51aS1kYXRlLXBpY2tlci1pbm5lclwiLFxuICAgIHRlbXBsYXRlVXJsOiBcIi4vZGF0ZS1waWNrZXItaW5uZXIuY29tcG9uZW50Lmh0bWxcIixcbn0pXG5leHBvcnQgY2xhc3MgRGF0ZVBpY2tlcklubmVyQ29tcG9uZW50XG4gICAgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95XG57XG4gICAgQElucHV0KCkgbG9jYWxlOiBzdHJpbmc7XG4gICAgQElucHV0KCkgZGF0ZXBpY2tlck1vZGU6IHN0cmluZztcbiAgICBASW5wdXQoKSBzdGFydGluZ0RheTogbnVtYmVyO1xuICAgIEBJbnB1dCgpIHllYXJSYW5nZTogbnVtYmVyO1xuICAgIEBJbnB1dCgpIG1pbkRhdGU6IE1vbWVudDtcbiAgICBASW5wdXQoKSBtYXhEYXRlOiBNb21lbnQ7XG4gICAgQElucHV0KCkgbWluTW9kZTogc3RyaW5nO1xuICAgIEBJbnB1dCgpIG1heE1vZGU6IHN0cmluZztcbiAgICBASW5wdXQoKSBzaG93V2Vla3M6IGJvb2xlYW47XG4gICAgQElucHV0KCkgZGF0ZUZvcm1hdDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIGZvcm1hdERheTogc3RyaW5nO1xuICAgIEBJbnB1dCgpIGZvcm1hdE1vbnRoOiBzdHJpbmc7XG4gICAgQElucHV0KCkgZm9ybWF0WWVhcjogc3RyaW5nO1xuICAgIEBJbnB1dCgpIGZvcm1hdERheUhlYWRlcjogc3RyaW5nO1xuICAgIEBJbnB1dCgpIGZvcm1hdERheVRpdGxlOiBzdHJpbmc7XG4gICAgQElucHV0KCkgZm9ybWF0TW9udGhUaXRsZTogc3RyaW5nO1xuICAgIEBJbnB1dCgpIG9ubHlDdXJyZW50TW9udGg6IGJvb2xlYW47XG4gICAgQElucHV0KCkgcHJlc2VydmVJbnNpZ25pZmljYW50OiBib29sZWFuO1xuICAgIEBJbnB1dCgpIGRpc2FibGVkRGF0ZXM6IElEYXRlUGlja2VyRGlzYWJsZWREYXRlW107XG4gICAgQElucHV0KCkgaW5pdERhdGU6IE1vbWVudDtcbiAgICBASW5wdXQoKSBpbmxpbmU6IGJvb2xlYW47XG4gICAgQElucHV0KCkgc2VsZWN0ZWREYXRlOiBNb21lbnQ7XG4gICAgLyoqIElzIHVzZWQgdG8gaGFuZGxlIHRpbWV6b25lIG9mIGRhdGUgdmFsdWUgKi9cbiAgICBASW5wdXQoKSBoYW5kbGVUaW1lem9uZTogYm9vbGVhbjtcblxuICAgIEBPdXRwdXQoKVxuICAgIHNlbGVjdGlvbkRvbmU6IEV2ZW50RW1pdHRlcjxNb21lbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxNb21lbnQ+KCk7XG5cbiAgICBAT3V0cHV0KClcbiAgICB1cGRhdGU6IEV2ZW50RW1pdHRlcjxNb21lbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxNb21lbnQ+KCk7XG5cbiAgICBwdWJsaWMgc3RlcERheTogYW55ID0ge307XG4gICAgcHVibGljIHN0ZXBNb250aDogYW55ID0ge307XG4gICAgcHVibGljIHN0ZXBZZWFyOiBhbnkgPSB7fTtcblxuICAgIHB1YmxpYyB1bmlxdWVJZDogc3RyaW5nO1xuICAgIHB1YmxpYyBpc1RvZGF5QnV0dG9uRGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgY2FsZW5kYXJNb3ZlZDogU3ViamVjdDxNb21lbnQ+ID0gbmV3IFN1YmplY3Q8TW9tZW50PigpO1xuXG4gICAgcHJvdGVjdGVkIF92YWx1ZTogTW9tZW50IHwgdW5kZWZpbmVkO1xuICAgIHByb3RlY3RlZCBfdG9kYXlEYXRlOiBNb21lbnQgPSBtb21lbnQoKTtcblxuICAgIHByb3RlY3RlZCByZWZyZXNoVmlld0hhbmRsZXJEYXk6IEZ1bmN0aW9uO1xuICAgIHByb3RlY3RlZCBjb21wYXJlSGFuZGxlckRheTogRnVuY3Rpb247XG4gICAgcHJvdGVjdGVkIHJlZnJlc2hWaWV3SGFuZGxlck1vbnRoOiBGdW5jdGlvbjtcbiAgICBwcm90ZWN0ZWQgY29tcGFyZUhhbmRsZXJNb250aDogRnVuY3Rpb247XG4gICAgcHJvdGVjdGVkIHJlZnJlc2hWaWV3SGFuZGxlclllYXI6IEZ1bmN0aW9uO1xuICAgIHByb3RlY3RlZCBjb21wYXJlSGFuZGxlclllYXI6IEZ1bmN0aW9uO1xuXG4gICAgcHJpdmF0ZSBtb2Rlczogc3RyaW5nW10gPSBbXCJkYXlcIiwgXCJtb250aFwiLCBcInllYXJcIl07XG5cbiAgICBnZXQgcm9sZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5pbmxpbmUgPyBcImFwcGxpY2F0aW9uXCIgOiBcImRpYWxvZ1wiO1xuICAgIH1cblxuICAgIEBJbnB1dCgpXG4gICAgZ2V0IHZhbHVlKCk6IE1vbWVudCB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG5cbiAgICBzZXQgdmFsdWUodmFsdWU6IE1vbWVudCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIXRoaXMucHJlc2VydmVJbnNpZ25pZmljYW50ICYmIHZhbHVlKSB7XG4gICAgICAgICAgICB2YWx1ZS5zZXQoeyBob3VyOiAwLCBtaW51dGU6IDAsIHNlY29uZDogMCwgbWlsbGlzZWNvbmQ6IDAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51bmlxdWVJZCA9IF91bmlxdWVJZChcImRhdGUtcGlja2VyLS1cIik7XG5cbiAgICAgICAgaWYgKHRoaXMuaW5pdERhdGUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBtb21lbnQodGhpcy5pbml0RGF0ZSk7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGlvbkRvbmUuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlLmVtaXQodGhpcy52YWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2lzTmlsKHRoaXMudmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5fdG9kYXlEYXRlLmNsb25lKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlZnJlc2hWaWV3KCk7XG4gICAgICAgIHRoaXMuaXNUb2RheUJ1dHRvbkRpc2FibGVkID0gdGhpcy5pc0Rpc2FibGVkKHRoaXMuX3RvZGF5RGF0ZSk7XG4gICAgfVxuXG4gICAgLy8gdGhpcy5yZWZyZXNoVmlldyBzaG91bGQgYmUgY2FsbGVkIGhlcmUgdG8gcmVmbGVjdCB0aGUgY2hhbmdlcyBvbiB0aGUgZmx5XG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkUmVmcmVzaFZpZXdPbkNoYW5nZXMoY2hhbmdlcykpIHtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaFZpZXcoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzaG91bGRSZWZyZXNoVmlld09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzaG91bGRSZWZyZXNoVmlldzogYm9vbGVhbjtcblxuICAgICAgICBzd2l0Y2ggKHRoaXMuZGF0ZXBpY2tlck1vZGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJkYXlcIjpcbiAgICAgICAgICAgICAgICBzaG91bGRSZWZyZXNoVmlldyA9XG4gICAgICAgICAgICAgICAgICAgICFfaXNOaWwoY2hhbmdlcy52YWx1ZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgIV9pc05pbCh0aGlzLnNlbGVjdGVkRGF0ZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgIWNoYW5nZXMudmFsdWUuY3VycmVudFZhbHVlLmlzU2FtZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZXMudmFsdWUucHJldmlvdXNWYWx1ZVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm1vbnRoXCI6XG4gICAgICAgICAgICAgICAgc2hvdWxkUmVmcmVzaFZpZXcgPVxuICAgICAgICAgICAgICAgICAgICAhX2lzTmlsKHRoaXMudmFsdWUpICYmXG4gICAgICAgICAgICAgICAgICAgICFfaXNOaWwodGhpcy5zZWxlY3RlZERhdGUpICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUubW9udGgoKSAhPT0gdGhpcy5zZWxlY3RlZERhdGUubW9udGgoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJ5ZWFyXCI6XG4gICAgICAgICAgICAgICAgc2hvdWxkUmVmcmVzaFZpZXcgPVxuICAgICAgICAgICAgICAgICAgICAhX2lzTmlsKHRoaXMudmFsdWUpICYmXG4gICAgICAgICAgICAgICAgICAgICFfaXNOaWwodGhpcy5zZWxlY3RlZERhdGUpICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUueWVhcigpICE9PSB0aGlzLnNlbGVjdGVkRGF0ZS55ZWFyKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHNob3VsZFJlZnJlc2hWaWV3ID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2hvdWxkUmVmcmVzaFZpZXcpIHtcbiAgICAgICAgICAgIF9lYWNoKGNoYW5nZXMsIChjaGFuZ2UpID0+IHtcbiAgICAgICAgICAgICAgICBzaG91bGRSZWZyZXNoVmlldyA9XG4gICAgICAgICAgICAgICAgICAgICFjaGFuZ2UuZmlyc3RDaGFuZ2UgJiZcbiAgICAgICAgICAgICAgICAgICAgbW9tZW50LmlzTW9tZW50KGNoYW5nZS5jdXJyZW50VmFsdWUpICYmXG4gICAgICAgICAgICAgICAgICAgICFjaGFuZ2UuY3VycmVudFZhbHVlLmlzU2FtZShjaGFuZ2UucHJldmlvdXNWYWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzaG91bGRSZWZyZXNoVmlldztcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Q29tcGFyZUhhbmRsZXIoaGFuZGxlcjogRnVuY3Rpb24sIHR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAodHlwZSA9PT0gXCJkYXlcIikge1xuICAgICAgICAgICAgdGhpcy5jb21wYXJlSGFuZGxlckRheSA9IGhhbmRsZXI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gXCJtb250aFwiKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBhcmVIYW5kbGVyTW9udGggPSBoYW5kbGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09IFwieWVhclwiKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBhcmVIYW5kbGVyWWVhciA9IGhhbmRsZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcGFyZShkYXRlMTogTW9tZW50LCBkYXRlMj86IE1vbWVudCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmIChfaXNOaWwoZGF0ZTEpIHx8IF9pc05pbChkYXRlMikpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kYXRlcGlja2VyTW9kZSA9PT0gXCJkYXlcIiAmJiB0aGlzLmNvbXBhcmVIYW5kbGVyRGF5KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlSGFuZGxlckRheShkYXRlMSwgZGF0ZTIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0ZXBpY2tlck1vZGUgPT09IFwibW9udGhcIiAmJiB0aGlzLmNvbXBhcmVIYW5kbGVyTW9udGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmVIYW5kbGVyTW9udGgoZGF0ZTEsIGRhdGUyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRhdGVwaWNrZXJNb2RlID09PSBcInllYXJcIiAmJiB0aGlzLmNvbXBhcmVIYW5kbGVyWWVhcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZUhhbmRsZXJZZWFyKGRhdGUxLCBkYXRlMik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdm9pZCAwO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRSZWZyZXNoVmlld0hhbmRsZXIoaGFuZGxlcjogRnVuY3Rpb24sIHR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAodHlwZSA9PT0gXCJkYXlcIikge1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoVmlld0hhbmRsZXJEYXkgPSBoYW5kbGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT09IFwibW9udGhcIikge1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoVmlld0hhbmRsZXJNb250aCA9IGhhbmRsZXI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSA9PT0gXCJ5ZWFyXCIpIHtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaFZpZXdIYW5kbGVyWWVhciA9IGhhbmRsZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFZpZXcoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmRhdGVwaWNrZXJNb2RlID09PSBcImRheVwiICYmIHRoaXMucmVmcmVzaFZpZXdIYW5kbGVyRGF5KSB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hWaWV3SGFuZGxlckRheSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0ZXBpY2tlck1vZGUgPT09IFwibW9udGhcIiAmJiB0aGlzLnJlZnJlc2hWaWV3SGFuZGxlck1vbnRoKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hWaWV3SGFuZGxlck1vbnRoKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kYXRlcGlja2VyTW9kZSA9PT0gXCJ5ZWFyXCIgJiYgdGhpcy5yZWZyZXNoVmlld0hhbmRsZXJZZWFyKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hWaWV3SGFuZGxlclllYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVEYXRlT2JqZWN0KGRhdGU6IE1vbWVudCwgZm9ybWF0OiBzdHJpbmcpOiBhbnkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0ZTogZGF0ZS5jbG9uZSgpLnRvSVNPU3RyaW5nKHRoaXMuaGFuZGxlVGltZXpvbmUpLFxuICAgICAgICAgICAgbGFiZWw6IHRoaXMuZm9ybWF0RGF0ZShkYXRlLCBmb3JtYXQpLFxuICAgICAgICAgICAgc2VsZWN0ZWQ6IHRoaXMuY29tcGFyZShkYXRlLCB0aGlzLnNlbGVjdGVkRGF0ZSkgPT09IDAsXG4gICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5pc0Rpc2FibGVkKGRhdGUpLFxuICAgICAgICAgICAgY3VycmVudDogdGhpcy5jb21wYXJlKGRhdGUsIHRoaXMudmFsdWUpID09PSAwLFxuICAgICAgICAgICAgdG9kYXk6IHRoaXMuY29tcGFyZShkYXRlLCB0aGlzLl90b2RheURhdGUpID09PSAwLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBzcGxpdChhcnI6IGFueVtdLCBzaXplOiBudW1iZXIpOiBhbnlbXSB7XG4gICAgICAgIGNvbnN0IGFycmF5czogYW55W10gPSBbXTtcblxuICAgICAgICB3aGlsZSAoYXJyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGFycmF5cy5wdXNoKGFyci5zcGxpY2UoMCwgc2l6ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFycmF5cztcbiAgICB9XG5cbiAgICBwdWJsaWMgc2VsZWN0KGRhdGU6IHN0cmluZywgZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5oYW5kbGVUaW1lem9uZVxuICAgICAgICAgICAgPyBtb21lbnQucGFyc2Vab25lKGRhdGUpXG4gICAgICAgICAgICA6IG1vbWVudChkYXRlKTtcblxuICAgICAgICBpZiAodGhpcy5kYXRlcGlja2VyTW9kZSA9PT0gdGhpcy5taW5Nb2RlKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGlvbkRvbmUuZW1pdCh0aGlzLnZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0ZXBpY2tlck1vZGUgPVxuICAgICAgICAgICAgICAgIHRoaXMubW9kZXNbdGhpcy5tb2Rlcy5pbmRleE9mKHRoaXMuZGF0ZXBpY2tlck1vZGUpIC0gMV07XG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXBkYXRlLmVtaXQodGhpcy52YWx1ZSk7XG4gICAgICAgIHRoaXMucmVmcmVzaFZpZXcoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbW92ZShkaXJlY3Rpb246IG51bWJlciwgZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICBsZXQgZXhwZWN0ZWRTdGVwOiBhbnk7XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0ZXBpY2tlck1vZGUgPT09IFwiZGF5XCIpIHtcbiAgICAgICAgICAgIGV4cGVjdGVkU3RlcCA9IHRoaXMuc3RlcERheTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRhdGVwaWNrZXJNb2RlID09PSBcIm1vbnRoXCIpIHtcbiAgICAgICAgICAgIGV4cGVjdGVkU3RlcCA9IHRoaXMuc3RlcE1vbnRoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0ZXBpY2tlck1vZGUgPT09IFwieWVhclwiKSB7XG4gICAgICAgICAgICBleHBlY3RlZFN0ZXAgPSB0aGlzLnN0ZXBZZWFyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV4cGVjdGVkU3RlcCkge1xuICAgICAgICAgICAgY29uc3QgYWN0aXZlRGF0ZU1vbWVudCA9IHRoaXMudmFsdWUgfHwgbW9tZW50KCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHllYXIgPVxuICAgICAgICAgICAgICAgIGFjdGl2ZURhdGVNb21lbnQueWVhcigpICsgZGlyZWN0aW9uICogKGV4cGVjdGVkU3RlcC55ZWFycyB8fCAwKTtcbiAgICAgICAgICAgIGNvbnN0IG1vbnRoID1cbiAgICAgICAgICAgICAgICBhY3RpdmVEYXRlTW9tZW50Lm1vbnRoKCkgK1xuICAgICAgICAgICAgICAgIGRpcmVjdGlvbiAqIChleHBlY3RlZFN0ZXAubW9udGhzIHx8IDApO1xuXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gYWN0aXZlRGF0ZU1vbWVudFxuICAgICAgICAgICAgICAgIC5jbG9uZSgpXG4gICAgICAgICAgICAgICAgLnNldCh7IHllYXI6IHllYXIsIG1vbnRoOiBtb250aCwgZGF0ZTogMSB9KTtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaFZpZXcoKTtcblxuICAgICAgICAgICAgdGhpcy5jYWxlbmRhck1vdmVkLm5leHQodGhpcy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdG9nZ2xlTW9kZShldmVudDogYW55LCBfZGlyZWN0aW9uPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IF9kaXJlY3Rpb24gfHwgMTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAodGhpcy5kYXRlcGlja2VyTW9kZSA9PT0gdGhpcy5tYXhNb2RlICYmIGRpcmVjdGlvbiA9PT0gMSkgfHxcbiAgICAgICAgICAgICh0aGlzLmRhdGVwaWNrZXJNb2RlID09PSB0aGlzLm1pbk1vZGUgJiYgZGlyZWN0aW9uID09PSAtMSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRhdGVwaWNrZXJNb2RlID1cbiAgICAgICAgICAgIHRoaXMubW9kZXNbdGhpcy5tb2Rlcy5pbmRleE9mKHRoaXMuZGF0ZXBpY2tlck1vZGUpICsgZGlyZWN0aW9uXTtcbiAgICAgICAgdGhpcy5yZWZyZXNoVmlldygpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNEaXNhYmxlZChkYXRlOiBNb21lbnQpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGlzRGF0ZURpc2FibGVkID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZWREYXRlcykge1xuICAgICAgICAgICAgdGhpcy5kaXNhYmxlZERhdGVzLmZvckVhY2goXG4gICAgICAgICAgICAgICAgKGRpc2FibGVkRGF0ZTogeyBkYXRlOiBNb21lbnQ7IG1vZGU6IHN0cmluZyB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbXBhcmVEYXRlRGlzYWJsZWQoZGlzYWJsZWREYXRlLCBkYXRlKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNEYXRlRGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0RhdGVEaXNhYmxlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGlzRGF0ZURpc2FibGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGlmZjE6IG51bWJlciB8IHVuZGVmaW5lZCA9IHRoaXMuY29tcGFyZShkYXRlLCB0aGlzLm1pbkRhdGUpO1xuICAgICAgICBjb25zdCBkaWZmMjogbnVtYmVyIHwgdW5kZWZpbmVkID0gdGhpcy5jb21wYXJlKGRhdGUsIHRoaXMubWF4RGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICh0aGlzLm1pbkRhdGUgJiYgKGRpZmYxIHx8IDApIDwgMCkgfHxcbiAgICAgICAgICAgICh0aGlzLm1heERhdGUgJiYgKGRpZmYyIHx8IDApID4gMClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZm9ybWF0RGF0ZShkYXRlOiBhbnksIGZvcm1hdDogYW55KTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIG1vbWVudChkYXRlKS5jbG9uZSgpLmZvcm1hdChmb3JtYXQpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBjb21wYXJlRGF0ZURpc2FibGVkKFxuICAgICAgICBkYXRlMURpc2FibGVkOiB7IGRhdGU6IE1vbWVudDsgbW9kZTogc3RyaW5nIH0sXG4gICAgICAgIGRhdGUyOiBNb21lbnRcbiAgICApOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAoX2lzTmlsKGRhdGUxRGlzYWJsZWQpIHx8IF9pc05pbChkYXRlMikpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGF0ZTFEaXNhYmxlZC5tb2RlID09PSBcImRheVwiICYmIHRoaXMuY29tcGFyZUhhbmRsZXJEYXkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmVIYW5kbGVyRGF5KGRhdGUxRGlzYWJsZWQuZGF0ZSwgZGF0ZTIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRhdGUxRGlzYWJsZWQubW9kZSA9PT0gXCJtb250aFwiICYmIHRoaXMuY29tcGFyZUhhbmRsZXJNb250aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZUhhbmRsZXJNb250aChkYXRlMURpc2FibGVkLmRhdGUsIGRhdGUyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRlMURpc2FibGVkLm1vZGUgPT09IFwieWVhclwiICYmIHRoaXMuY29tcGFyZUhhbmRsZXJZZWFyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlSGFuZGxlclllYXIoZGF0ZTFEaXNhYmxlZC5kYXRlLCBkYXRlMik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jYWxlbmRhck1vdmVkLmNvbXBsZXRlKCk7XG4gICAgfVxufVxuIiwiPGRpdiAqbmdJZj1cImRhdGVwaWNrZXJNb2RlXCIgY2xhc3M9XCJudWktZGF0ZXBpY2tlci1pbm5lclwiIFthdHRyLnJvbGVdPVwicm9sZVwiPlxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvZGl2PlxuIl19