UNPKG

@duoduo-oba/ng-devui

Version:

DevUI components based on Angular

644 lines 54.1 kB
/** * @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