@duoduo-oba/ng-devui
Version:
DevUI components based on Angular
644 lines • 54.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: datepicker.directive.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Directive, Input, ElementRef, forwardRef, ViewContainerRef, Output, EventEmitter, ComponentFactoryResolver, Renderer2, Injector, HostListener, TemplateRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { DatepickerComponent } from './datepicker.component';
import { SelectDateChangeReason } from './date-change-event-args.model';
import { DatePickerConfigService as DatePickerConfig } from './date-picker.config.service';
import { DefaultDateConverter } from '@duoduo-oba/ng-devui/utils';
import { I18nService } from '@duoduo-oba/ng-devui/i18n';
import { animate, AnimationBuilder, style } from '@angular/animations';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
/** @type {?} */
const easeInQuint = 'cubic-bezier(0.755, 0.05, 0.855, 0.06)';
/** @type {?} */
const easeOutQuint = 'cubic-bezier(0.23, 1, 0.32, 1)';
/** @type {?} */
const animationDuration = '200ms';
export class DatepickerDirective {
/**
* @param {?} elementRef
* @param {?} viewContainerRef
* @param {?} componentFactoryResolver
* @param {?} renderer2
* @param {?} injector
* @param {?} datePickerConfig
* @param {?} i18n
* @param {?} builder
*/
constructor(elementRef, viewContainerRef, componentFactoryResolver, renderer2, injector, datePickerConfig, i18n, builder) {
this.elementRef = elementRef;
this.viewContainerRef = viewContainerRef;
this.componentFactoryResolver = componentFactoryResolver;
this.renderer2 = renderer2;
this.injector = injector;
this.datePickerConfig = datePickerConfig;
this.i18n = i18n;
this.builder = builder;
this.direction = 'down';
this.autoOpen = false;
this.selectedDateChange = new EventEmitter();
this.isOpen = false;
this.onChange = (/**
* @param {?} _
* @return {?}
*/
(_) => null);
this.onTouched = (/**
* @return {?}
*/
() => null);
this._dateConfig = datePickerConfig['dateConfig'];
this.dateConverter = datePickerConfig['dateConfig'].dateConverter || new DefaultDateConverter();
this.selectedDate = null;
/** @type {?} */
const factory = this.componentFactoryResolver.resolveComponentFactory(DatepickerComponent);
this.cmpRef = this.viewContainerRef.createComponent(factory, this.viewContainerRef.length, this.injector);
this.inputSub = fromEvent(this.elementRef.nativeElement, 'input')
.pipe(debounceTime(300)).subscribe((/**
* @param {?} event
* @return {?}
*/
event => {
this.transUserInputToDatepicker(event);
}));
}
/**
* @param {?} dateConfig
* @return {?}
*/
set dateConfig(dateConfig) {
if (dateConfig) {
this._dateConfig = dateConfig;
this._dateFormat = this.showTime ? dateConfig.format.time : dateConfig.format.date;
}
else {
this._dateConfig = this.datePickerConfig.dateConfig;
}
}
/**
* @return {?}
*/
get dateConfig() {
return this._dateConfig;
}
/**
* @param {?} dateFormat
* @return {?}
*/
set dateFormat(dateFormat) {
if (this._dateFormat !== dateFormat) {
this._dateFormat = dateFormat;
this.writeModelValue({ selectedDate: this.selectedDate, reason: SelectDateChangeReason.format });
}
}
/**
* @return {?}
*/
get dateFormat() {
return this._dateFormat;
}
/**
* @param {?} date
* @return {?}
*/
set maxDate(date) {
/** @type {?} */
const parseDate = this.dateConverter.parse(date, this.dateFormat, this.locale || this.i18nLocale);
if (parseDate) {
this._maxDate = parseDate;
}
}
/**
* @return {?}
*/
get maxDate() {
return this._maxDate;
}
/**
* @param {?} date
* @return {?}
*/
set minDate(date) {
/** @type {?} */
const parseDate = this.dateConverter.parse(date, this.dateFormat, this.locale || this.i18nLocale);
if (parseDate) {
this._minDate = parseDate;
}
}
/**
* @return {?}
*/
get minDate() {
return this._minDate;
}
/**
* @return {?}
*/
ngOnInit() {
this.showTime = this.showTime || this.dateConfig.timePicker;
this._minDate = this.minDate ? new Date(this.minDate) : new Date(this.dateConfig.min, 0, 1, 0, 0, 0);
this._maxDate = this.maxDate ? new Date(this.maxDate) : new Date(this.dateConfig.max, 11, 31, 23, 59, 59);
/** @type {?} */
const target = this.cmpRef.location.nativeElement;
this.applyPopupStyling(target);
/** @type {?} */
const component = this.cmpRef.instance;
this.renderer2.setStyle(target, 'display', 'none');
component.writeValue(this.selectedDate);
this.fillPopupData();
component.ngOnInit();
component.registerOnChange((/**
* @param {?} selectedDate
* @return {?}
*/
selectedDate => {
this.writeValue(selectedDate);
this.onChange(selectedDate);
}));
component.selectedDateChange.subscribe((/**
* @param {?} arg
* @return {?}
*/
(arg) => {
if (arg.reason === SelectDateChangeReason.date && !this.showTime ||
arg.reason === SelectDateChangeReason.button) {
this.hide();
}
}));
if (this.autoOpen) {
this.show();
}
this.setI18nText();
}
/**
* @param {?} obj
* @return {?}
*/
writeValue(obj) {
/** @type {?} */
let curDate;
if (obj && typeof obj === 'object' && obj.hasOwnProperty('selectedDate')) {
curDate = obj.selectedDate;
}
else {
curDate = obj;
}
this.selectedDate = curDate ?
this.dateConverter.parse(curDate, this.dateFormat, this.locale || this.i18nLocale) : null;
this.writeModelValue(obj);
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @private
* @return {?}
*/
setI18nText() {
this.i18nLocale = this.i18n.getI18nText().locale;
this.i18nSubscription = this.i18n.langChange().subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.i18nLocale = data.locale;
}));
}
/**
* @private
* @param {?} date
* @param {?} direction
* @return {?}
*/
parseDateFunc(date, direction) {
/** @type {?} */
const parseDate = this.dateConverter.parse(date, this.dateFormat, this.locale || this.i18nLocale);
if (parseDate) {
this[direction] = date;
}
}
/**
* @private
* @param {?} nativeElement
* @return {?}
*/
applyPopupStyling(nativeElement) {
this.renderer2.addClass(nativeElement, 'devui-dropdown-menu');
this.renderer2.setStyle(nativeElement, 'padding', '0px');
if (this.direction === 'up') {
this.renderer2.setStyle(nativeElement, 'top', 'auto');
this.renderer2.setStyle(nativeElement, 'bottom', '100%');
}
}
/**
* @return {?}
*/
hide() {
/** @type {?} */
const playAnimation = this.isOpen !== false;
this.isOpen = false;
if (playAnimation) {
this.playAnimation();
}
}
/**
* @private
* @param {?} selectDateObj
* @return {?}
*/
writeModelValue(selectDateObj) {
/** @type {?} */
let selectDate;
/** @type {?} */
let dateReason = SelectDateChangeReason.time;
if (selectDateObj && typeof selectDateObj === 'object' && selectDateObj.hasOwnProperty('selectedDate')) {
selectDate = selectDateObj.selectedDate;
dateReason = selectDateObj.reason;
}
else {
selectDate = selectDateObj;
}
if (selectDate) {
selectDate = new Date(selectDate);
}
else {
selectDate = null;
}
/** @type {?} */
const value = selectDate ? this.dateConverter.format(selectDate, this.dateFormat, this.locale || this.i18nLocale) : '';
this.renderer2.setProperty(this.elementRef.nativeElement, 'value', value);
if (this.isOpen) {
this.cmpRef.instance.writeValue(this.selectedDate);
}
this.selectedDateChange.emit({
reason: dateReason,
selectedDate: this.selectedDate
});
}
/**
* @return {?}
*/
show() {
/** @type {?} */
const component = this.cmpRef.instance;
component.writeValue(this.selectedDate);
this.fillPopupData();
/** @type {?} */
const playAnimation = this.isOpen !== true;
this.isOpen = true;
if (playAnimation) {
this.playAnimation();
}
}
/**
* @param {?} $event
* @return {?}
*/
toggle($event) {
if ($event) {
$event.stopPropagation();
}
if (this.isOpen) {
this.hide();
return;
}
this.show();
}
/**
* @private
* @return {?}
*/
fillPopupData() {
['showTime', 'maxDate', 'minDate', 'cssClass', 'disabled', 'dateConverter', 'locale', 'dateFormat', 'yearNumber', 'dateConfig',
'customViewTemplate']
.forEach((/**
* @param {?} key
* @return {?}
*/
key => {
if (this[key] !== undefined) {
this.cmpRef.instance[key] = this[key];
}
}));
}
/**
* @param {?} $event
* @return {?}
*/
onBlur($event) {
this.onTouched();
}
/**
* @param {?} $event
* @return {?}
*/
onDocumentClick($event) {
if (this.elementRef.nativeElement !== $event.target) {
this.hide();
}
}
/**
* @return {?}
*/
clearAll() {
this.cmpRef.instance.clearAll();
}
/**
* @private
* @param {?} direction
* @return {?}
*/
popIn(direction) {
switch (direction) {
case 'top':
return [
style({ transform: 'perspective(1px) scale(0.9)', opacity: 0, transformOrigin: '0% 100%', display: 'inline-block' }),
animate(`${animationDuration} ${easeOutQuint}`, style({ transform: 'perspective(1px) scale(1)', opacity: 1, transformOrigin: '0% 100%' })),
];
case 'bottom':
default:
return [
style({ transform: 'perspective(1px) scale(0.9)', opacity: 0, transformOrigin: '0% 0%', display: 'inline-block' }),
animate(`${animationDuration} ${easeOutQuint}`, style({ transform: 'perspective(1px) scale(1)', opacity: 1, transformOrigin: '0% 0%' })),
];
}
}
/**
* @private
* @param {?} direction
* @return {?}
*/
popOut(direction) {
switch (direction) {
case 'top':
return [
style({ transform: 'perspective(1px) scale(1)', opacity: 1, transformOrigin: '0% 100%' }),
animate(`${animationDuration} ${easeInQuint}`, style({ transform: 'perspective(1px) scale(0.9)', opacity: 0, transformOrigin: '0% 100%' }))
];
case 'bottom':
default:
return [
style({ transform: 'perspective(1px) scale(1)', opacity: 1, transformOrigin: '0% 0%' }),
animate(`${animationDuration} ${easeInQuint}`, style({ transform: 'perspective(1px) scale(0.9)', opacity: 0, transformOrigin: '0% 0%' }))
];
}
}
/**
* @private
* @return {?}
*/
playAnimation() {
if (this.player) {
this.player.destroy();
}
/** @type {?} */
let direction = '';
switch (this.direction) {
case 'down':
direction = 'bottom';
break;
case 'up':
direction = 'top';
break;
default:
direction = 'bottom';
}
/** @type {?} */
const metadata = this.isOpen ? this.popIn(direction) : this.popOut(direction);
/** @type {?} */
const factory = this.builder.build(metadata);
this.renderer2.setStyle(this.cmpRef.location.nativeElement, 'display', 'inline-block');
this.player = factory.create(this.cmpRef.location.nativeElement);
this.player.onDone((/**
* @return {?}
*/
() => {
if (!this.isOpen) {
/** @type {?} */
const targetElement = this.cmpRef.location.nativeElement;
this.renderer2.setStyle(targetElement, 'display', 'none');
}
}));
this.player.play();
}
/**
* @private
* @param {?} event
* @return {?}
*/
transUserInputToDatepicker(event) {
if (!this.showTime && !this.disabled) {
/** @type {?} */
const value = event.target.value;
/** @type {?} */
const valueDate = new Date(value);
/** @type {?} */
const valueFormat = this.dateConverter.format(valueDate, this.dateFormat, this.locale || this.i18nLocale);
if (value && value === valueFormat) {
if (valueDate.getTime() < this.minDate.getTime() || valueDate.getTime() > this.maxDate.getTime()) {
this.elementRef.nativeElement.value =
this.dateConverter.format(this.selectedDate, this.dateFormat, this.locale || this.i18nLocale);
}
else {
this.cmpRef.instance.chooseDate(value);
}
}
else if (!value) {
this.clearAll();
}
}
else {
this.elementRef.nativeElement.value =
this.dateConverter.format(this.selectedDate, this.dateFormat, this.locale || this.i18nLocale);
}
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.inputSub) {
this.inputSub.unsubscribe();
}
if (this.i18nSubscription) {
this.i18nSubscription.unsubscribe();
}
}
}
DatepickerDirective.decorators = [
{ type: Directive, args: [{
selector: '[dDatepicker]:not([appendToBody])',
exportAs: 'datepicker',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
() => DatepickerDirective)),
multi: true
}]
},] }
];
/** @nocollapse */
DatepickerDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: ViewContainerRef },
{ type: ComponentFactoryResolver },
{ type: Renderer2 },
{ type: Injector },
{ type: DatePickerConfig },
{ type: I18nService },
{ type: AnimationBuilder }
];
DatepickerDirective.propDecorators = {
dateConfig: [{ type: Input }],
dateFormat: [{ type: Input }],
maxDate: [{ type: Input }],
minDate: [{ type: Input }],
locale: [{ type: Input }],
showTime: [{ type: Input }],
cssClass: [{ type: Input }],
disabled: [{ type: Input }],
dateConverter: [{ type: Input }],
yearNumber: [{ type: Input }],
direction: [{ type: Input }],
customViewTemplate: [{ type: Input }],
autoOpen: [{ type: Input }],
selectedDateChange: [{ type: Output }],
onBlur: [{ type: HostListener, args: ['blur', ['$event'],] }],
onDocumentClick: [{ type: HostListener, args: ['document:click', ['$event'],] }]
};
if (false) {
/** @type {?} */
DatepickerDirective.prototype.locale;
/** @type {?} */
DatepickerDirective.prototype.showTime;
/** @type {?} */
DatepickerDirective.prototype.cssClass;
/** @type {?} */
DatepickerDirective.prototype.disabled;
/** @type {?} */
DatepickerDirective.prototype.dateConverter;
/** @type {?} */
DatepickerDirective.prototype.yearNumber;
/** @type {?} */
DatepickerDirective.prototype.direction;
/** @type {?} */
DatepickerDirective.prototype.customViewTemplate;
/** @type {?} */
DatepickerDirective.prototype.autoOpen;
/** @type {?} */
DatepickerDirective.prototype.selectedDateChange;
/** @type {?} */
DatepickerDirective.prototype.selectedDate;
/** @type {?} */
DatepickerDirective.prototype.isOpen;
/** @type {?} */
DatepickerDirective.prototype._dateConfig;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype._dateFormat;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype._maxDate;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype._minDate;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.cmpRef;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.player;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.inputSub;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.i18nSubscription;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.i18nLocale;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.onChange;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.onTouched;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.elementRef;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.viewContainerRef;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.componentFactoryResolver;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.renderer2;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.injector;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.datePickerConfig;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.i18n;
/**
* @type {?}
* @private
*/
DatepickerDirective.prototype.builder;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy1kZXZ1aS9kYXRlcGlja2VyLyIsInNvdXJjZXMiOlsiZGF0ZXBpY2tlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUFVLEtBQUssRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFnQixnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUN0Ryx3QkFBd0IsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQ3pFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RCxPQUFPLEVBQTZCLHNCQUFzQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkcsT0FBTyxFQUFFLHVCQUF1QixJQUFJLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDM0YsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDM0QsT0FBTyxFQUNMLE9BQU8sRUFDUCxnQkFBZ0IsRUFHaEIsS0FBSyxFQUNOLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLFNBQVMsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOztNQUV4QyxXQUFXLEdBQUcsd0NBQXdDOztNQUN0RCxZQUFZLEdBQUcsZ0NBQWdDOztNQUMvQyxpQkFBaUIsR0FBRyxPQUFPO0FBV2pDLE1BQU0sT0FBTyxtQkFBbUI7Ozs7Ozs7Ozs7O0lBd0U5QixZQUFvQixVQUFzQixFQUFVLGdCQUFrQyxFQUNsRSx3QkFBa0QsRUFBVSxTQUFv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QUs7eUJBQ0wsS0FBSzt3QkFDTCxLQUFLO2lDQUNMLEtBQUs7dUJBQ0wsS0FBSztpQ0FDTCxNQUFNO3FCQTZLTixZQUFZLFNBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDOzhCQUsvQixZQUFZLFNBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Ozs7SUEzTDFDLHFDQUF3Qjs7SUFDeEIsdUNBQTJCOztJQUMzQix1Q0FBMEI7O0lBQzFCLHVDQUEyQjs7SUFDM0IsNENBQXNDOztJQUN0Qyx5Q0FBNEI7O0lBQzVCLHdDQUEyQzs7SUFDM0MsaURBQThDOztJQUM5Qyx1Q0FBMEI7O0lBQzFCLGlEQUE2RTs7SUFDN0UsMkNBQW1COztJQUNuQixxQ0FBZTs7SUFDZiwwQ0FBaUI7Ozs7O0lBQ2pCLDBDQUE0Qjs7Ozs7SUFDNUIsdUNBQXVCOzs7OztJQUN2Qix1Q0FBdUI7Ozs7O0lBQ3ZCLHFDQUFrRDs7Ozs7SUFDbEQscUNBQWdDOzs7OztJQUNoQyx1Q0FBK0I7Ozs7O0lBQy9CLCtDQUF1Qzs7Ozs7SUFDdkMseUNBQTRDOzs7OztJQUM1Qyx1Q0FBb0M7Ozs7O0lBQ3BDLHdDQUErQjs7Ozs7SUFFbkIseUNBQThCOzs7OztJQUFFLCtDQUEwQzs7Ozs7SUFDMUUsdURBQTBEOzs7OztJQUFFLHdDQUE0Qjs7Ozs7SUFDeEYsdUNBQTBCOzs7OztJQUFFLCtDQUEwQzs7Ozs7SUFBRSxtQ0FBeUI7Ozs7O0lBQ2pHLHNDQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgRGlyZWN0aXZlLCBPbkluaXQsIElucHV0LCBFbGVtZW50UmVmLCBmb3J3YXJkUmVmLCBDb21wb25lbnRSZWYsIFZpZXdDb250YWluZXJSZWYsIE91dHB1dCwgRXZlbnRFbWl0dGVyLFxyXG4gIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgUmVuZGVyZXIyLCBJbmplY3RvciwgSG9zdExpc3RlbmVyLCBUZW1wbGF0ZVJlZiwgT25EZXN0cm95XHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgRGF0ZUNvbnZlcnRlciB9IGZyb20gJ25nLWRldnVpL3V0aWxzJztcclxuaW1wb3J0IHsgRGF0ZXBpY2tlckNvbXBvbmVudCB9IGZyb20gJy4vZGF0ZXBpY2tlci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBTZWxlY3REYXRlQ2hhbmdlRXZlbnRBcmdzLCBTZWxlY3REYXRlQ2hhbmdlUmVhc29uIH0gZnJvbSAnLi9kYXRlLWNoYW5nZS1ldmVudC1hcmdzLm1vZGVsJztcclxuaW1wb3J0IHsgRGF0ZVBpY2tlckNvbmZpZ1NlcnZpY2UgYXMgRGF0ZVBpY2tlckNvbmZpZyB9IGZyb20gJy4vZGF0ZS1waWNrZXIuY29uZmlnLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEZWZhdWx0RGF0ZUNvbnZlcnRlciB9IGZyb20gJ25nLWRldnVpL3V0aWxzJztcclxuaW1wb3J0IHsgSTE4blNlcnZpY2UsIEkxOG5JbnRlcmZhY2UgfSBmcm9tICduZy1kZXZ1aS9pMThuJztcclxuaW1wb3J0IHtcclxuICBhbmltYXRlLFxyXG4gIEFuaW1hdGlvbkJ1aWxkZXIsXHJcbiAgQW5pbWF0aW9uTWV0YWRhdGEsXHJcbiAgQW5pbWF0aW9uUGxheWVyLFxyXG4gIHN0eWxlXHJcbn0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XHJcbmltcG9ydCB7IGZyb21FdmVudCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmNvbnN0IGVhc2VJblF1aW50ID0gJ2N1YmljLWJlemllcigwLjc1NSwgMC4wNSwgMC44NTUsIDAuMDYpJztcclxuY29uc3QgZWFzZU91dFF1aW50ID0gJ2N1YmljLWJlemllcigwLjIzLCAxLCAwLjMyLCAxKSc7XHJcbmNvbnN0IGFuaW1hdGlvbkR1cmF0aW9uID0gJzIwMG1zJztcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gIHNlbGVjdG9yOiAnW2REYXRlcGlja2VyXTpub3QoW2FwcGVuZFRvQm9keV0pJyxcclxuICBleHBvcnRBczogJ2RhdGVwaWNrZXInLFxyXG4gIHByb3ZpZGVyczogW3tcclxuICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRGF0ZXBpY2tlckRpcmVjdGl2ZSksXHJcbiAgICBtdWx0aTogdHJ1ZVxyXG4gIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEYXRlcGlja2VyRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcclxuXHJcblxyXG4gIEBJbnB1dCgpIHNldCBkYXRlQ29uZmlnKGRhdGVDb25maWc6IGFueSkge1xyXG4gICAgaWYgKGRhdGVDb25maWcpIHtcclxuICAgICAgdGhpcy5fZGF0ZUNvbmZpZyA9IGRhdGVDb25maWc7XHJcbiAgICAgIHRoaXMuX2RhdGVGb3JtYXQgPSB0aGlzLnNob3dUaW1lID8gZGF0ZUNvbmZpZy5mb3JtYXQudGltZSA6IGRhdGVDb25maWcuZm9ybWF0LmRhdGU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9kYXRlQ29uZmlnID0gdGhpcy5kYXRlUGlja2VyQ29uZmlnLmRhdGVDb25maWc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgZGF0ZUNvbmZpZygpIHtcclxuICAgIHJldHVybiB0aGlzLl9kYXRlQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgQElucHV0KCkgc2V0IGRhdGVGb3JtYXQoZGF0ZUZvcm1hdDogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5fZGF0ZUZvcm1hdCAhPT0gZGF0ZUZvcm1hdCkge1xyXG4gICAgICB0aGlzLl9kYXRlRm9ybWF0ID0gZGF0ZUZvcm1hdDtcclxuICAgICAgdGhpcy53cml0ZU1vZGVsVmFsdWUoe3NlbGVjdGVkRGF0ZTogdGhpcy5zZWxlY3RlZERhdGUsIHJlYXNvbjogU2VsZWN0RGF0ZUNoYW5nZVJlYXNvbi5mb3JtYXR9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBkYXRlRm9ybWF0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2RhdGVGb3JtYXQ7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKSBzZXQgbWF4RGF0ZShkYXRlOiBEYXRlIHwgYW55KSB7XHJcbiAgICBjb25zdCBwYXJzZURhdGUgPSB0aGlzLmRhdGVDb252ZXJ0ZXIucGFyc2UoZGF0ZSwgdGhpcy5kYXRlRm9ybWF0LCB0aGlzLmxvY2FsZSB8fCB0aGlzLmkxOG5Mb2NhbGUpO1xyXG4gICAgaWYgKHBhcnNlRGF0ZSkge1xyXG4gICAgICB0aGlzLl9tYXhEYXRlID0gcGFyc2VEYXRlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IG1heERhdGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWF4RGF0ZTtcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIHNldCBtaW5EYXRlKGRhdGU6IERhdGUgfCBhbnkpIHtcclxuICAgIGNvbnN0IHBhcnNlRGF0ZSA9IHRoaXMuZGF0ZUNvbnZlcnRlci5wYXJzZShkYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubG9jYWxlIHx8IHRoaXMuaTE4bkxvY2FsZSk7XHJcbiAgICBpZiAocGFyc2VEYXRlKSB7XHJcbiAgICAgIHRoaXMuX21pbkRhdGUgPSBwYXJzZURhdGU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgbWluRGF0ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLl9taW5EYXRlO1xyXG4gIH1cclxuICBASW5wdXQoKSBsb2NhbGU6IHN0cmluZztcclxuICBASW5wdXQoKSBzaG93VGltZTogYm9vbGVhbjtcclxuICBASW5wdXQoKSBjc3NDbGFzczogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGRhdGVDb252ZXJ0ZXI6IERhdGVDb252ZXJ0ZXI7XHJcbiAgQElucHV0KCkgeWVhck51bWJlcjogbnVtYmVyO1xyXG4gIEBJbnB1dCgpIGRpcmVjdGlvbjogJ3VwJyB8ICdkb3duJyA9ICdkb3duJztcclxuICBASW5wdXQoKSBjdXN0b21WaWV3VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQElucHV0KCkgYXV0b09wZW4gPSBmYWxzZTtcclxuICBAT3V0cHV0KCkgc2VsZWN0ZWREYXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTZWxlY3REYXRlQ2hhbmdlRXZlbnRBcmdzPigpO1xyXG4gIHNlbGVjdGVkRGF0ZTogRGF0ZTtcclxuICBpc09wZW4gPSBmYWxzZTtcclxuICBfZGF0ZUNvbmZpZzogYW55O1xyXG4gIHByaXZhdGUgX2RhdGVGb3JtYXQ6IHN0cmluZztcclxuICBwcml2YXRlIF9tYXhEYXRlOiBEYXRlO1xyXG4gIHByaXZhdGUgX21pbkRhdGU6IERhdGU7XHJcbiAgcHJpdmF0ZSBjbXBSZWY6IENvbXBvbmVudFJlZjxEYXRlcGlja2VyQ29tcG9uZW50PjtcclxuICBwcml2YXRlIHBsYXllcjogQW5pbWF0aW9uUGxheWVyO1xyXG4gIHByaXZhdGUgaW5wdXRTdWI6IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIGkxOG5TdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIGkxOG5Mb2NhbGU6IEkxOG5JbnRlcmZhY2VbJ2xvY2FsZSddO1xyXG4gIHByaXZhdGUgb25DaGFuZ2UgPSAoXzogYW55KSA9PiBudWxsO1xyXG4gIHByaXZhdGUgb25Ub3VjaGVkID0gKCkgPT4gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgcHJpdmF0ZSByZW5kZXJlcjI6IFJlbmRlcmVyMixcclxuICAgICAgICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvciwgcHJpdmF0ZSBkYXRlUGlja2VyQ29uZmlnOiBEYXRlUGlja2VyQ29uZmlnLCBwcml2YXRlIGkxOG46IEkxOG5TZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgYnVpbGRlcjogQW5pbWF0aW9uQnVpbGRlcikge1xyXG4gICAgdGhpcy5fZGF0ZUNvbmZpZyA9IGRhdGVQaWNrZXJDb25maWdbJ2RhdGVDb25maWcnXTtcclxuICAgIHRoaXMuZGF0ZUNvbnZlcnRlciA9IGRhdGVQaWNrZXJDb25maWdbJ2RhdGVDb25maWcnXS5kYXRlQ29udmVydGVyIHx8IG5ldyBEZWZhdWx0RGF0ZUNvbnZlcnRlcigpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBudWxsO1xyXG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuY29tcG9uZW50RmFjdG9yeVJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KERhdGVwaWNrZXJDb21wb25lbnQpO1xyXG4gICAgdGhpcy5jbXBSZWYgPSB0aGlzLnZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KGZhY3RvcnksIHRoaXMudmlld0NvbnRhaW5lclJlZi5sZW5ndGgsIHRoaXMuaW5qZWN0b3IpO1xyXG5cclxuICAgIHRoaXMuaW5wdXRTdWIgPSBmcm9tRXZlbnQodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdpbnB1dCcpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIGRlYm91bmNlVGltZSgzMDApXHJcbiAgICAgICkuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgICB0aGlzLnRyYW5zVXNlcklucHV0VG9EYXRlcGlja2VyKGV2ZW50KTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuc2hvd1RpbWUgPSB0aGlzLnNob3dUaW1lIHx8IHRoaXMuZGF0ZUNvbmZpZy50aW1lUGlja2VyO1xyXG4gICAgdGhpcy5fbWluRGF0ZSA9IHRoaXMubWluRGF0ZSA/IG5ldyBEYXRlKHRoaXMubWluRGF0ZSkgOiBuZXcgRGF0ZSh0aGlzLmRhdGVDb25maWcubWluLCAwLCAxLCAwLCAwLCAwKTtcclxuICAgIHRoaXMuX21heERhdGUgPSB0aGlzLm1heERhdGUgPyBuZXcgRGF0ZSh0aGlzLm1heERhdGUpIDogbmV3IERhdGUodGhpcy5kYXRlQ29uZmlnLm1heCwgMTEsIDMxLCAyMywgNTksIDU5KTtcclxuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuY21wUmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLmFwcGx5UG9wdXBTdHlsaW5nKHRhcmdldCk7XHJcbiAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLmNtcFJlZi5pbnN0YW5jZTtcclxuICAgIHRoaXMucmVuZGVyZXIyLnNldFN0eWxlKHRhcmdldCwgJ2Rpc3BsYXknLCAnbm9uZScpO1xyXG4gICAgY29tcG9uZW50LndyaXRlVmFsdWUodGhpcy5zZWxlY3RlZERhdGUpO1xyXG4gICAgdGhpcy5maWxsUG9wdXBEYXRhKCk7XHJcbiAgICBjb21wb25lbnQubmdPbkluaXQoKTtcclxuXHJcbiAgICBjb21wb25lbnQucmVnaXN0ZXJPbkNoYW5nZShzZWxlY3RlZERhdGUgPT4ge1xyXG4gICAgICB0aGlzLndyaXRlVmFsdWUoc2VsZWN0ZWREYXRlKTtcclxuICAgICAgdGhpcy5vbkNoYW5nZShzZWxlY3RlZERhdGUpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29tcG9uZW50LnNlbGVjdGVkRGF0ZUNoYW5nZS5zdWJzY3JpYmUoKGFyZzogU2VsZWN0RGF0ZUNoYW5nZUV2ZW50QXJncykgPT4ge1xyXG4gICAgICBpZiAoYXJnLnJlYXNvbiA9PT0gU2VsZWN0RGF0ZUNoYW5nZVJlYXNvbi5kYXRlICYmICF0aGlzLnNob3dUaW1lIHx8XHJcbiAgICAgICBhcmcucmVhc29uID09PSBTZWxlY3REYXRlQ2hhbmdlUmVhc29uLmJ1dHRvbikge1xyXG4gICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAodGhpcy5hdXRvT3Blbikge1xyXG4gICAgICB0aGlzLnNob3coKTtcclxuICAgIH1cclxuICAgIHRoaXMuc2V0STE4blRleHQoKTtcclxuICB9XHJcblxyXG4gIHdyaXRlVmFsdWUob2JqOiBhbnkpOiB2b2lkIHtcclxuICAgIGxldCBjdXJEYXRlO1xyXG4gICAgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmouaGFzT3duUHJvcGVydHkoJ3NlbGVjdGVkRGF0ZScpKSB7XHJcbiAgICAgIGN1ckRhdGUgPSBvYmouc2VsZWN0ZWREYXRlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY3VyRGF0ZSA9IG9iajtcclxuICAgIH1cclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gY3VyRGF0ZSA/XHJcbiAgICAgIHRoaXMuZGF0ZUNvbnZlcnRlci5wYXJzZShjdXJEYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubG9jYWxlIHx8IHRoaXMuaTE4bkxvY2FsZSkgOiBudWxsO1xyXG4gICAgdGhpcy53cml0ZU1vZGVsVmFsdWUob2JqKTtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0STE4blRleHQoKSB7XHJcbiAgICB0aGlzLmkxOG5Mb2NhbGUgPSB0aGlzLmkxOG4uZ2V0STE4blRleHQoKS5sb2NhbGU7XHJcbiAgICB0aGlzLmkxOG5TdWJzY3JpcHRpb24gPSB0aGlzLmkxOG4ubGFuZ0NoYW5nZSgpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xyXG4gICAgICB0aGlzLmkxOG5Mb2NhbGUgPSBkYXRhLmxvY2FsZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwYXJzZURhdGVGdW5jKGRhdGUsIGRpcmVjdGlvbikge1xyXG4gICAgY29uc3QgcGFyc2VEYXRlID0gdGhpcy5kYXRlQ29udmVydGVyLnBhcnNlKGRhdGUsIHRoaXMuZGF0ZUZvcm1hdCwgdGhpcy5sb2NhbGUgfHwgdGhpcy5pMThuTG9jYWxlKVxyXG4gICAgICA7XHJcbiAgICBpZiAocGFyc2VEYXRlKSB7XHJcbiAgICAgIHRoaXNbZGlyZWN0aW9uXSA9IGRhdGVcclxuICAgICAgO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhcHBseVBvcHVwU3R5bGluZyhuYXRpdmVFbGVtZW50OiBhbnkpIHtcclxuICAgIHRoaXMucmVuZGVyZXIyLmFkZENsYXNzKG5hdGl2ZUVsZW1lbnQsICdkZXZ1aS1kcm9wZG93bi1tZW51Jyk7XHJcbiAgICB0aGlzLnJlbmRlcmVyMi5zZXRTdHlsZShuYXRpdmVFbGVtZW50LCAncGFkZGluZycsICcwcHgnKTtcclxuICAgIGlmICh0aGlzLmRpcmVjdGlvbiA9PT0gJ3VwJykge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyMi5zZXRTdHlsZShuYXRpdmVFbGVtZW50LCAndG9wJywgJ2F1dG8nKTtcclxuICAgICAgdGhpcy5yZW5kZXJlcjIuc2V0U3R5bGUobmF0aXZlRWxlbWVudCwgJ2JvdHRvbScsICcxMDAlJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBoaWRlKCkge1xyXG4gICAgY29uc3QgcGxheUFuaW1hdGlvbiA9IHRoaXMuaXNPcGVuICE9PSBmYWxzZTtcclxuICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XHJcbiAgICBpZiAocGxheUFuaW1hdGlvbikge1xyXG4gICAgICB0aGlzLnBsYXlBbmltYXRpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgd3JpdGVNb2RlbFZhbHVlKHNlbGVjdERhdGVPYmo6IGFueSkge1xyXG4gICAgbGV0IHNlbGVjdERhdGU7XHJcbiAgICBsZXQgZGF0ZVJlYXNvbiA9IFNlbGVjdERhdGVDaGFuZ2VSZWFzb24udGltZTtcclxuICAgIGlmIChzZWxlY3REYXRlT2JqICYmIHR5cGVvZiBzZWxlY3REYXRlT2JqID09PSAnb2JqZWN0JyAmJiBzZWxlY3REYXRlT2JqLmhhc093blByb3BlcnR5KCdzZWxlY3RlZERhdGUnKSkge1xyXG4gICAgICBzZWxlY3REYXRlID0gc2VsZWN0RGF0ZU9iai5zZWxlY3RlZERhdGU7XHJcbiAgICAgIGRhdGVSZWFzb24gPSBzZWxlY3REYXRlT2JqLnJlYXNvbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHNlbGVjdERhdGUgPSBzZWxlY3REYXRlT2JqO1xyXG4gICAgfVxyXG4gICAgaWYgKHNlbGVjdERhdGUpIHtcclxuICAgICAgc2VsZWN0RGF0ZSA9IG5ldyBEYXRlKHNlbGVjdERhdGUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2VsZWN0RGF0ZSA9IG51bGw7XHJcbiAgICB9XHJcbiAgICBjb25zdCB2YWx1ZSA9IHNlbGVjdERhdGUgPyB0aGlzLmRhdGVDb252ZXJ0ZXIuZm9ybWF0KHNlbGVjdERhdGUsIHRoaXMuZGF0ZUZvcm1hdCwgdGhpcy5sb2NhbGUgfHwgdGhpcy5pMThuTG9jYWxlKSA6ICcnO1xyXG4gICAgdGhpcy5yZW5kZXJlcjIuc2V0UHJvcGVydHkodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd2YWx1ZScsIHZhbHVlKTtcclxuICAgIGlmICh0aGlzLmlzT3Blbikge1xyXG4gICAgICB0aGlzLmNtcFJlZi5pbnN0YW5jZS53cml0ZVZhbHVlKHRoaXMuc2VsZWN0ZWREYXRlKTtcclxuICAgIH1cclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlQ2hhbmdlLmVtaXQoe1xyXG4gICAgICByZWFzb246IGRhdGVSZWFzb24sXHJcbiAgICAgIHNlbGVjdGVkRGF0ZTogdGhpcy5zZWxlY3RlZERhdGVcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc2hvdygpIHtcclxuICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuY21wUmVmLmluc3RhbmNlO1xyXG4gICAgY29tcG9uZW50LndyaXRlVmFsdWUodGhpcy5zZWxlY3RlZERhdGUpO1xyXG4gICAgdGhpcy5maWxsUG9wdXBEYXRhKCk7XHJcbiAgICBjb25zdCBwbGF5QW5pbWF0aW9uID0gdGhpcy5pc09wZW4gIT09IHRydWU7XHJcbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgICBpZiAocGxheUFuaW1hdGlvbikge1xyXG4gICAgICB0aGlzLnBsYXlBbmltYXRpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRvZ2dsZSgkZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBpZiAoJGV2ZW50KSB7XHJcbiAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmlzT3Blbikge1xyXG4gICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zaG93KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZpbGxQb3B1cERhdGEoKSB7XHJcbiAgICBbJ3Nob3dUaW1lJywgJ21heERhdGUnLCAnbWluRGF0ZScsICdjc3NDbGFzcycsICdkaXNhYmxlZCcsICdkYXRlQ29udmVydGVyJywgJ2xvY2FsZScsICdkYXRlRm9ybWF0JywgJ3llYXJOdW1iZXInLCAnZGF0ZUNvbmZpZycsXHJcbiAgICAnY3VzdG9tVmlld1RlbXBsYXRlJ11cclxuICAgICAgLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICBpZiAodGhpc1trZXldICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgIHRoaXMuY21wUmVmLmluc3RhbmNlW2tleV0gPSB0aGlzW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2JsdXInLCBbJyRldmVudCddKVxyXG4gIG9uQmx1cigkZXZlbnQpIHtcclxuICAgIHRoaXMub25Ub3VjaGVkKCk7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXHJcbiAgICBvbkRvY3VtZW50Q2xpY2soJGV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgIT09ICRldmVudC50YXJnZXQpIHtcclxuICAgICAgdGhpcy5oaWRlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjbGVhckFsbCgpIHtcclxuICAgIHRoaXMuY21wUmVmLmluc3RhbmNlLmNsZWFyQWxsKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHBvcEluKGRpcmVjdGlvbik6IEFuaW1hdGlvbk1ldGFkYXRhW10ge1xyXG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcclxuICAgICAgY2FzZSAndG9wJzpcclxuICAgICAgICByZXR1cm4gW1xyXG4gICAgICAgICAgc3R5bGUoe3RyYW5zZm9ybTogJ3BlcnNwZWN0aXZlKDFweCkgc2NhbGUoMC45KScsIG9wYWNpdHk6IDAsIHRyYW5zZm9ybU9yaWdpbjogJzAlIDEwMCUnLCBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJ30pLFxyXG4gICAgICAgICAgYW5pbWF0ZShgJHthbmltYXRpb25EdXJhdGlvbn0gJHtlYXNlT3V0UXVpbnR9YCxcclxuICAgICAgICAgICAgc3R5bGUoe3RyYW5zZm9ybTogJ3BlcnNwZWN0aXZlKDFweCkgc2NhbGUoMSknLCBvcGFjaXR5OiAxLCB0cmFuc2Zvcm1PcmlnaW46ICcwJSAxMDAlJ30pKSxcclxuICAgICAgICBdO1xyXG4gICAgICBjYXNlICdib3R0b20nOlxyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybiBbXHJcbiAgICAgICAgICBzdHlsZSh7dHJhbnNmb3JtOiAncGVyc3BlY3RpdmUoMXB4KSBzY2FsZSgwLjkpJywgb3BhY2l0eTogMCwgdHJhbnNmb3JtT3JpZ2luOiAnMCUgMCUnLCBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJ30pLFxyXG4gICAgICAgICAgY