@ng-select/ng-select
Version:
Angular ng-select - All in One UI Select, Multiselect and Autocomplete
414 lines • 55.4 kB
JavaScript
import { DOCUMENT } from '@angular/common';
import { booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Inject, Input, Optional, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
import { animationFrameScheduler, asapScheduler, fromEvent, merge, Subject } from 'rxjs';
import { auditTime, takeUntil } from 'rxjs/operators';
import { isDefined } from './value-utils';
import * as i0 from "@angular/core";
import * as i1 from "./ng-dropdown-panel.service";
import * as i2 from "@angular/common";
const CSS_POSITIONS = ['top', 'right', 'bottom', 'left'];
const SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;
export class NgDropdownPanelComponent {
constructor(_renderer, _zone, _panelService, _elementRef, _document) {
this._renderer = _renderer;
this._zone = _zone;
this._panelService = _panelService;
this._document = _document;
this.items = [];
this.position = 'auto';
this.virtualScroll = false;
this.filterValue = null;
this.update = new EventEmitter();
this.scroll = new EventEmitter();
this.scrollToEnd = new EventEmitter();
this.outsideClick = new EventEmitter();
this._destroy$ = new Subject();
this._scrollToEndFired = false;
this._updateScrollHeight = false;
this._lastScrollPosition = 0;
this._dropdown = _elementRef.nativeElement;
}
get currentPosition() {
return this._currentPosition;
}
get itemsLength() {
return this._itemsLength;
}
set itemsLength(value) {
if (value !== this._itemsLength) {
this._itemsLength = value;
this._onItemsLengthChanged();
}
}
get _startOffset() {
if (this.markedItem) {
const { itemHeight, panelHeight } = this._panelService.dimensions;
const offset = this.markedItem.index * itemHeight;
return panelHeight > offset ? 0 : offset;
}
return 0;
}
ngOnInit() {
this._select = this._dropdown.parentElement;
this._virtualPadding = this.paddingElementRef.nativeElement;
this._scrollablePanel = this.scrollElementRef.nativeElement;
this._contentPanel = this.contentElementRef.nativeElement;
this._handleScroll();
this._handleOutsideClick();
this._appendDropdown();
this._setupMousedownListener();
}
ngOnChanges(changes) {
if (changes.items) {
const change = changes.items;
this._onItemsChange(change.currentValue, change.firstChange);
}
}
ngOnDestroy() {
this._destroy$.next();
this._destroy$.complete();
this._destroy$.unsubscribe();
if (this.appendTo) {
this._renderer.removeChild(this._dropdown.parentNode, this._dropdown);
}
}
scrollTo(option, startFromOption = false) {
if (!option) {
return;
}
const index = this.items.indexOf(option);
if (index < 0 || index >= this.itemsLength) {
return;
}
let scrollTo;
if (this.virtualScroll) {
const itemHeight = this._panelService.dimensions.itemHeight;
scrollTo = this._panelService.getScrollTo(index * itemHeight, itemHeight, this._lastScrollPosition);
}
else {
const item = this._dropdown.querySelector(`#${option.htmlId}`);
const lastScroll = startFromOption ? item.offsetTop : this._lastScrollPosition;
scrollTo = this._panelService.getScrollTo(item.offsetTop, item.clientHeight, lastScroll);
}
if (isDefined(scrollTo)) {
this._scrollablePanel.scrollTop = scrollTo;
}
}
scrollToTag() {
const panel = this._scrollablePanel;
panel.scrollTop = panel.scrollHeight - panel.clientHeight;
}
adjustPosition() {
this._updateYPosition();
}
_handleDropdownPosition() {
this._currentPosition = this._calculateCurrentPosition(this._dropdown);
if (CSS_POSITIONS.includes(this._currentPosition)) {
this._updateDropdownClass(this._currentPosition);
}
else {
this._updateDropdownClass('bottom');
}
if (this.appendTo) {
this._updateYPosition();
}
this._dropdown.style.opacity = '1';
}
_updateDropdownClass(currentPosition) {
CSS_POSITIONS.forEach((position) => {
const REMOVE_CSS_CLASS = `ng-select-${position}`;
this._renderer.removeClass(this._dropdown, REMOVE_CSS_CLASS);
this._renderer.removeClass(this._select, REMOVE_CSS_CLASS);
});
const ADD_CSS_CLASS = `ng-select-${currentPosition}`;
this._renderer.addClass(this._dropdown, ADD_CSS_CLASS);
this._renderer.addClass(this._select, ADD_CSS_CLASS);
}
_handleScroll() {
this._zone.runOutsideAngular(() => {
fromEvent(this.scrollElementRef.nativeElement, 'scroll')
.pipe(takeUntil(this._destroy$), auditTime(0, SCROLL_SCHEDULER))
.subscribe((e) => {
const path = e.path || (e.composedPath && e.composedPath());
if (!path || (path.length === 0 && !e.target)) {
return;
}
const scrollTop = !path || path.length === 0 ? e.target.scrollTop : path[0].scrollTop;
this._onContentScrolled(scrollTop);
});
});
}
_handleOutsideClick() {
if (!this._document) {
return;
}
this._zone.runOutsideAngular(() => {
merge(fromEvent(this._document, 'touchstart', { capture: true }), fromEvent(this._document, 'click', { capture: true }))
.pipe(takeUntil(this._destroy$))
.subscribe(($event) => this._checkToClose($event));
});
}
_checkToClose($event) {
if (this._select.contains($event.target) || this._dropdown.contains($event.target)) {
return;
}
const path = $event.path || ($event.composedPath && $event.composedPath());
if ($event.target && $event.target.shadowRoot && path && path[0] && this._select.contains(path[0])) {
return;
}
this._zone.run(() => this.outsideClick.emit());
}
_onItemsChange(items, firstChange) {
this.items = items || [];
this._scrollToEndFired = false;
this.itemsLength = items.length;
if (this.virtualScroll) {
this._updateItemsRange(firstChange);
}
else {
this._setVirtualHeight();
this._updateItems(firstChange);
}
}
_updateItems(firstChange) {
this.update.emit(this.items);
if (firstChange === false) {
return;
}
this._zone.runOutsideAngular(() => {
Promise.resolve().then(() => {
const panelHeight = this._scrollablePanel.clientHeight;
this._panelService.setDimensions(0, panelHeight);
this._handleDropdownPosition();
this.scrollTo(this.markedItem, firstChange);
});
});
}
_updateItemsRange(firstChange) {
this._zone.runOutsideAngular(() => {
this._measureDimensions().then(() => {
if (firstChange) {
this._renderItemsRange(this._startOffset);
this._handleDropdownPosition();
}
else {
this._renderItemsRange();
}
});
});
}
_onContentScrolled(scrollTop) {
if (this.virtualScroll) {
this._renderItemsRange(scrollTop);
}
this._lastScrollPosition = scrollTop;
this._fireScrollToEnd(scrollTop);
}
_updateVirtualHeight(height) {
if (this._updateScrollHeight) {
this._virtualPadding.style.height = `${height}px`;
this._updateScrollHeight = false;
}
}
_setVirtualHeight() {
if (!this._virtualPadding) {
return;
}
this._virtualPadding.style.height = `0px`;
}
_onItemsLengthChanged() {
this._updateScrollHeight = true;
}
_renderItemsRange(scrollTop = null) {
if (scrollTop && this._lastScrollPosition === scrollTop) {
return;
}
scrollTop = scrollTop || this._scrollablePanel.scrollTop;
const range = this._panelService.calculateItems(scrollTop, this.itemsLength, this.bufferAmount);
this._updateVirtualHeight(range.scrollHeight);
this._contentPanel.style.transform = `translateY(${range.topPadding}px)`;
this._zone.run(() => {
this.update.emit(this.items.slice(range.start, range.end));
this.scroll.emit({ start: range.start, end: range.end });
});
if (isDefined(scrollTop) && this._lastScrollPosition === 0) {
this._scrollablePanel.scrollTop = scrollTop;
this._lastScrollPosition = scrollTop;
}
}
_measureDimensions() {
if (this._panelService.dimensions.itemHeight > 0 || this.itemsLength === 0) {
return Promise.resolve(this._panelService.dimensions);
}
const [first] = this.items;
this.update.emit([first]);
return Promise.resolve().then(() => {
const option = this._dropdown.querySelector(`#${first.htmlId}`);
const optionHeight = option.clientHeight;
this._virtualPadding.style.height = `${optionHeight * this.itemsLength}px`;
const panelHeight = this._scrollablePanel.clientHeight;
this._panelService.setDimensions(optionHeight, panelHeight);
return this._panelService.dimensions;
});
}
_fireScrollToEnd(scrollTop) {
if (this._scrollToEndFired || scrollTop === 0) {
return;
}
const padding = this.virtualScroll ? this._virtualPadding : this._contentPanel;
if (scrollTop + this._dropdown.clientHeight >= padding.clientHeight - 1) {
this._zone.run(() => this.scrollToEnd.emit());
this._scrollToEndFired = true;
}
}
_calculateCurrentPosition(dropdownEl) {
if (this.position !== 'auto') {
return this.position;
}
const selectRect = this._select.getBoundingClientRect();
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const offsetTop = selectRect.top + window.pageYOffset;
const height = selectRect.height;
const dropdownHeight = dropdownEl.getBoundingClientRect().height;
if (offsetTop + height + dropdownHeight > scrollTop + document.documentElement.clientHeight) {
return 'top';
}
else {
return 'bottom';
}
}
_appendDropdown() {
if (!this.appendTo) {
return;
}
this._parent = document.querySelector(this.appendTo);
if (!this._parent) {
throw new Error(`appendTo selector ${this.appendTo} did not found any parent element`);
}
this._updateXPosition();
this._parent.appendChild(this._dropdown);
}
_updateXPosition() {
const select = this._select.getBoundingClientRect();
const parent = this._parent.getBoundingClientRect();
const offsetLeft = select.left - parent.left;
this._dropdown.style.left = offsetLeft + 'px';
this._dropdown.style.width = select.width + 'px';
this._dropdown.style.minWidth = select.width + 'px';
}
_updateYPosition() {
const select = this._select.getBoundingClientRect();
const parent = this._parent.getBoundingClientRect();
const delta = select.height;
if (this._currentPosition === 'top') {
const offsetBottom = parent.bottom - select.bottom;
this._dropdown.style.bottom = offsetBottom + delta + 'px';
this._dropdown.style.top = 'auto';
}
else if (this._currentPosition === 'bottom') {
const offsetTop = select.top - parent.top;
this._dropdown.style.top = offsetTop + delta + 'px';
this._dropdown.style.bottom = 'auto';
}
}
_setupMousedownListener() {
this._zone.runOutsideAngular(() => {
fromEvent(this._dropdown, 'mousedown')
.pipe(takeUntil(this._destroy$))
.subscribe((event) => {
const target = event.target;
if (target.tagName === 'INPUT') {
return;
}
event.preventDefault();
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgDropdownPanelComponent, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }, { token: i1.NgDropdownPanelService }, { token: i0.ElementRef }, { token: DOCUMENT, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.0", type: NgDropdownPanelComponent, selector: "ng-dropdown-panel", inputs: { items: "items", markedItem: "markedItem", position: "position", appendTo: "appendTo", bufferAmount: "bufferAmount", virtualScroll: ["virtualScroll", "virtualScroll", booleanAttribute], headerTemplate: "headerTemplate", footerTemplate: "footerTemplate", filterValue: "filterValue" }, outputs: { update: "update", scroll: "scroll", scrollToEnd: "scrollToEnd", outsideClick: "outsideClick" }, viewQueries: [{ propertyName: "contentElementRef", first: true, predicate: ["content"], descendants: true, read: ElementRef, static: true }, { propertyName: "scrollElementRef", first: true, predicate: ["scroll"], descendants: true, read: ElementRef, static: true }, { propertyName: "paddingElementRef", first: true, predicate: ["padding"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
@if (headerTemplate) {
<div class="ng-dropdown-header">
<ng-container [ngTemplateOutlet]="headerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
</div>
}
<div #scroll role="listbox" class="ng-dropdown-panel-items scroll-host">
<div #padding [class.total-padding]="virtualScroll"></div>
<div #content [class.scrollable-content]="virtualScroll && items.length">
<ng-content></ng-content>
</div>
</div>
@if (footerTemplate) {
<div class="ng-dropdown-footer">
<ng-container [ngTemplateOutlet]="footerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
</div>
}
`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: NgDropdownPanelComponent, decorators: [{
type: Component,
args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'ng-dropdown-panel',
template: `
@if (headerTemplate) {
<div class="ng-dropdown-header">
<ng-container [ngTemplateOutlet]="headerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
</div>
}
<div #scroll role="listbox" class="ng-dropdown-panel-items scroll-host">
<div #padding [class.total-padding]="virtualScroll"></div>
<div #content [class.scrollable-content]="virtualScroll && items.length">
<ng-content></ng-content>
</div>
</div>
@if (footerTemplate) {
<div class="ng-dropdown-footer">
<ng-container [ngTemplateOutlet]="footerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
</div>
}
`,
}]
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.NgDropdownPanelService }, { type: i0.ElementRef }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { items: [{
type: Input
}], markedItem: [{
type: Input
}], position: [{
type: Input
}], appendTo: [{
type: Input
}], bufferAmount: [{
type: Input
}], virtualScroll: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], headerTemplate: [{
type: Input
}], footerTemplate: [{
type: Input
}], filterValue: [{
type: Input
}], update: [{
type: Output
}], scroll: [{
type: Output
}], scrollToEnd: [{
type: Output
}], outsideClick: [{
type: Output
}], contentElementRef: [{
type: ViewChild,
args: ['content', { read: ElementRef, static: true }]
}], scrollElementRef: [{
type: ViewChild,
args: ['scroll', { read: ElementRef, static: true }]
}], paddingElementRef: [{
type: ViewChild,
args: ['padding', { read: ElementRef, static: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctZHJvcGRvd24tcGFuZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL25nLXNlbGVjdC9saWIvbmctZHJvcGRvd24tcGFuZWwuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ04sZ0JBQWdCLEVBQ2hCLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUtMLFFBQVEsRUFDUixNQUFNLEVBSU4sU0FBUyxFQUNULGlCQUFpQixHQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFLdEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7OztBQUUxQyxNQUFNLGFBQWEsR0FBdUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUM3RSxNQUFNLGdCQUFnQixHQUFHLE9BQU8scUJBQXFCLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO0FBeUJoSCxNQUFNLE9BQU8sd0JBQXdCO0lBK0JwQyxZQUNTLFNBQW9CLEVBQ3BCLEtBQWEsRUFDYixhQUFxQyxFQUM3QyxXQUF1QixFQUNlLFNBQWM7UUFKNUMsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUNwQixVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQ2Isa0JBQWEsR0FBYixhQUFhLENBQXdCO1FBRVAsY0FBUyxHQUFULFNBQVMsQ0FBSztRQW5DNUMs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QUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ0csaUJBQWlCO3NCQUExRSxTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG5cdGJvb2xlYW5BdHRyaWJ1dGUsXG5cdENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuXHRDb21wb25lbnQsXG5cdEVsZW1lbnRSZWYsXG5cdEV2ZW50RW1pdHRlcixcblx0SW5qZWN0LFxuXHRJbnB1dCxcblx0Tmdab25lLFxuXHRPbkNoYW5nZXMsXG5cdE9uRGVzdHJveSxcblx0T25Jbml0LFxuXHRPcHRpb25hbCxcblx0T3V0cHV0LFxuXHRSZW5kZXJlcjIsXG5cdFNpbXBsZUNoYW5nZXMsXG5cdFRlbXBsYXRlUmVmLFxuXHRWaWV3Q2hpbGQsXG5cdFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGFuaW1hdGlvbkZyYW1lU2NoZWR1bGVyLCBhc2FwU2NoZWR1bGVyLCBmcm9tRXZlbnQsIG1lcmdlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBhdWRpdFRpbWUsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IE5nRHJvcGRvd25QYW5lbFNlcnZpY2UsIFBhbmVsRGltZW5zaW9ucyB9IGZyb20gJy4vbmctZHJvcGRvd24tcGFuZWwuc2VydmljZSc7XG5cbmltcG9ydCB7IERyb3Bkb3duUG9zaXRpb24gfSBmcm9tICcuL25nLXNlbGVjdC50eXBlcyc7XG5pbXBvcnQgeyBOZ09wdGlvbiB9IGZyb20gJy4vbmctc2VsZWN0LnR5cGVzJztcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gJy4vdmFsdWUtdXRpbHMnO1xuXG5jb25zdCBDU1NfUE9TSVRJT05TOiBSZWFkb25seTxzdHJpbmdbXT4gPSBbJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCddO1xuY29uc3QgU0NST0xMX1NDSEVEVUxFUiA9IHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgIT09ICd1bmRlZmluZWQnID8gYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIgOiBhc2FwU2NoZWR1bGVyO1xuXG5AQ29tcG9uZW50KHtcblx0Y2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG5cdGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG5cdHNlbGVjdG9yOiAnbmctZHJvcGRvd24tcGFuZWwnLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdEBpZiAoaGVhZGVyVGVtcGxhdGUpIHtcblx0XHRcdDxkaXYgY2xhc3M9XCJuZy1kcm9wZG93bi1oZWFkZXJcIj5cblx0XHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWFkZXJUZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7IHNlYXJjaFRlcm06IGZpbHRlclZhbHVlIH1cIj48L25nLWNvbnRhaW5lcj5cblx0XHRcdDwvZGl2PlxuXHRcdH1cblx0XHQ8ZGl2ICNzY3JvbGwgcm9sZT1cImxpc3Rib3hcIiBjbGFzcz1cIm5nLWRyb3Bkb3duLXBhbmVsLWl0ZW1zIHNjcm9sbC1ob3N0XCI+XG5cdFx0XHQ8ZGl2ICNwYWRkaW5nIFtjbGFzcy50b3RhbC1wYWRkaW5nXT1cInZpcnR1YWxTY3JvbGxcIj48L2Rpdj5cblx0XHRcdDxkaXYgI2NvbnRlbnQgW2NsYXNzLnNjcm9sbGFibGUtY29udGVudF09XCJ2aXJ0dWFsU2Nyb2xsICYmIGl0ZW1zLmxlbmd0aFwiPlxuXHRcdFx0XHQ8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cdFx0XHQ8L2Rpdj5cblx0XHQ8L2Rpdj5cblx0XHRAaWYgKGZvb3RlclRlbXBsYXRlKSB7XG5cdFx0XHQ8ZGl2IGNsYXNzPVwibmctZHJvcGRvd24tZm9vdGVyXCI+XG5cdFx0XHRcdDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiZm9vdGVyVGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBzZWFyY2hUZXJtOiBmaWx0ZXJWYWx1ZSB9XCI+PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8L2Rpdj5cblx0XHR9XG5cdGAsXG59KVxuZXhwb3J0IGNsYXNzIE5nRHJvcGRvd25QYW5lbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXHRASW5wdXQoKSBpdGVtczogTmdPcHRpb25bXSA9IFtdO1xuXHRASW5wdXQoKSBtYXJrZWRJdGVtOiBOZ09wdGlvbjtcblx0QElucHV0KCkgcG9zaXRpb246IERyb3Bkb3duUG9zaXRpb24gPSAnYXV0byc7XG5cdEBJbnB1dCgpIGFwcGVuZFRvOiBzdHJpbmc7XG5cdEBJbnB1dCgpIGJ1ZmZlckFtb3VudDpudW1iZXI7XG5cdEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSB2aXJ0dWFsU2Nyb2xsID0gZmFsc2U7XG5cdEBJbnB1dCgpIGhlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXHRASW5wdXQoKSBmb290ZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55Pjtcblx0QElucHV0KCkgZmlsdGVyVmFsdWU6IHN0cmluZyA9IG51bGw7XG5cblx0QE91dHB1dCgpIHVwZGF0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55W10+KCk7XG5cdEBPdXRwdXQoKSBzY3JvbGwgPSBuZXcgRXZlbnRFbWl0dGVyPHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfT4oKTtcblx0QE91dHB1dCgpIHNjcm9sbFRvRW5kID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXHRAT3V0cHV0KCkgb3V0c2lkZUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG5cdEBWaWV3Q2hpbGQoJ2NvbnRlbnQnLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KSBjb250ZW50RWxlbWVudFJlZjogRWxlbWVudFJlZjtcblx0QFZpZXdDaGlsZCgnc2Nyb2xsJywgeyByZWFkOiBFbGVtZW50UmVmLCBzdGF0aWM6IHRydWUgfSkgc2Nyb2xsRWxlbWVudFJlZjogRWxlbWVudFJlZjtcblx0QFZpZXdDaGlsZCgncGFkZGluZycsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pIHBhZGRpbmdFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xuXG5cdHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblx0cHJpdmF0ZSByZWFkb25seSBfZHJvcGRvd246IEhUTUxFbGVtZW50O1xuXHRwcml2YXRlIF92aXJ0dWFsUGFkZGluZzogSFRNTEVsZW1lbnQ7XG5cdHByaXZhdGUgX3Njcm9sbGFibGVQYW5lbDogSFRNTEVsZW1lbnQ7XG5cdHByaXZhdGUgX2NvbnRlbnRQYW5lbDogSFRNTEVsZW1lbnQ7XG5cdHByaXZhdGUgX3NlbGVjdDogSFRNTEVsZW1lbnQ7XG5cdHByaXZhdGUgX3BhcmVudDogSFRNTEVsZW1lbnQ7XG5cdHByaXZhdGUgX3Njcm9sbFRvRW5kRmlyZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBfdXBkYXRlU2Nyb2xsSGVpZ2h0ID0gZmFsc2U7XG5cdHByaXZhdGUgX2xhc3RTY3JvbGxQb3NpdGlvbiA9IDA7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMixcblx0XHRwcml2YXRlIF96b25lOiBOZ1pvbmUsXG5cdFx0cHJpdmF0ZSBfcGFuZWxTZXJ2aWNlOiBOZ0Ryb3Bkb3duUGFuZWxTZXJ2aWNlLFxuXHRcdF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuXHRcdEBPcHRpb25hbCgpIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgX2RvY3VtZW50OiBhbnksXG5cdCkge1xuXHRcdHRoaXMuX2Ryb3Bkb3duID0gX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblx0fVxuXG5cdHByaXZhdGUgX2N1cnJlbnRQb3NpdGlvbjogRHJvcGRvd25Qb3NpdGlvbjtcblxuXHRnZXQgY3VycmVudFBvc2l0aW9uKCk6IERyb3Bkb3duUG9zaXRpb24ge1xuXHRcdHJldHVybiB0aGlzLl9jdXJyZW50UG9zaXRpb247XG5cdH1cblxuXHRwcml2YXRlIF9pdGVtc0xlbmd0aDogbnVtYmVyO1xuXG5cdHByaXZhdGUgZ2V0IGl0ZW1zTGVuZ3RoKCkge1xuXHRcdHJldHVybiB0aGlzLl9pdGVtc0xlbmd0aDtcblx0fVxuXG5cdHByaXZhdGUgc2V0IGl0ZW1zTGVuZ3RoKHZhbHVlOiBudW1iZXIpIHtcblx0XHRpZiAodmFsdWUgIT09IHRoaXMuX2l0ZW1zTGVuZ3RoKSB7XG5cdFx0XHR0aGlzLl9pdGVtc0xlbmd0aCA9IHZhbHVlO1xuXHRcdFx0dGhpcy5fb25JdGVtc0xlbmd0aENoYW5nZWQoKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGdldCBfc3RhcnRPZmZzZXQoKSB7XG5cdFx0aWYgKHRoaXMubWFya2VkSXRlbSkge1xuXHRcdFx0Y29uc3QgeyBpdGVtSGVpZ2h0LCBwYW5lbEhlaWdodCB9ID0gdGhpcy5fcGFuZWxTZXJ2aWNlLmRpbWVuc2lvbnM7XG5cdFx0XHRjb25zdCBvZmZzZXQgPSB0aGlzLm1hcmtlZEl0ZW0uaW5kZXggKiBpdGVtSGVpZ2h0O1xuXHRcdFx0cmV0dXJuIHBhbmVsSGVpZ2h0ID4gb2Zmc2V0ID8gMCA6IG9mZnNldDtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRuZ09uSW5pdCgpIHtcblx0XHR0aGlzLl9zZWxlY3QgPSB0aGlzLl9kcm9wZG93bi5wYXJlbnRFbGVtZW50O1xuXHRcdHRoaXMuX3ZpcnR1YWxQYWRkaW5nID0gdGhpcy5wYWRkaW5nRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXHRcdHRoaXMuX3Njcm9sbGFibGVQYW5lbCA9IHRoaXMuc2Nyb2xsRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXHRcdHRoaXMuX2NvbnRlbnRQYW5lbCA9IHRoaXMuY29udGVudEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblx0XHR0aGlzLl9oYW5kbGVTY3JvbGwoKTtcblx0XHR0aGlzLl9oYW5kbGVPdXRzaWRlQ2xpY2soKTtcblx0XHR0aGlzLl9hcHBlbmREcm9wZG93bigpO1xuXHRcdHRoaXMuX3NldHVwTW91c2Vkb3duTGlzdGVuZXIoKTtcblx0fVxuXG5cdG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcblx0XHRpZiAoY2hhbmdlcy5pdGVtcykge1xuXHRcdFx0Y29uc3QgY2hhbmdlID0gY2hhbmdlcy5pdGVtcztcblx0XHRcdHRoaXMuX29uSXRlbXNDaGFuZ2UoY2hhbmdlLmN1cnJlbnRWYWx1ZSwgY2hhbmdlLmZpcnN0Q2hhbmdlKTtcblx0XHR9XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLl9kZXN0cm95JC5uZXh0KCk7XG5cdFx0dGhpcy5fZGVzdHJveSQuY29tcGxldGUoKTtcblx0XHR0aGlzLl9kZXN0cm95JC51bnN1YnNjcmliZSgpO1xuXHRcdGlmICh0aGlzLmFwcGVuZFRvKSB7XG5cdFx0XHR0aGlzLl9yZW5kZXJlci5yZW1vdmVDaGlsZCh0aGlzLl9kcm9wZG93bi5wYXJlbnROb2RlLCB0aGlzLl9kcm9wZG93bik7XG5cdFx0fVxuXHR9XG5cblx0c2Nyb2xsVG8ob3B0aW9uOiBOZ09wdGlvbiwgc3RhcnRGcm9tT3B0aW9uID0gZmFsc2UpIHtcblx0XHRpZiAoIW9wdGlvbikge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGluZGV4ID0gdGhpcy5pdGVtcy5pbmRleE9mKG9wdGlvbik7XG5cdFx0aWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLml0ZW1zTGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bGV0IHNjcm9sbFRvO1xuXHRcdGlmICh0aGlzLnZpcnR1YWxTY3JvbGwpIHtcblx0XHRcdGNvbnN0IGl0ZW1IZWlnaHQgPSB0aGlzLl9wYW5lbFNlcnZpY2UuZGltZW5zaW9ucy5pdGVtSGVpZ2h0O1xuXHRcdFx0c2Nyb2xsVG8gPSB0aGlzLl9wYW5lbFNlcnZpY2UuZ2V0U2Nyb2xsVG8oaW5kZXggKiBpdGVtSGVpZ2h0LCBpdGVtSGVpZ2h0LCB0aGlzLl9sYXN0U2Nyb2xsUG9zaXRpb24pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBpdGVtOiBIVE1MRWxlbWVudCA9IHRoaXMuX2Ryb3Bkb3duLnF1ZXJ5U2VsZWN0b3IoYCMke29wdGlvbi5odG1sSWR9YCk7XG5cdFx0XHRjb25zdCBsYXN0U2Nyb2xsID0gc3RhcnRGcm9tT3B0aW9uID8gaXRlbS5vZmZzZXRUb3AgOiB0aGlzLl9sYXN0U2Nyb2xsUG9zaXRpb247XG5cdFx0XHRzY3JvbGxUbyA9IHRoaXMuX3BhbmVsU2VydmljZS5nZXRTY3JvbGxUbyhpdGVtLm9mZnNldFRvcCwgaXRlbS5jbGllbnRIZWlnaHQsIGxhc3RTY3JvbGwpO1xuXHRcdH1cblxuXHRcdGlmIChpc0RlZmluZWQoc2Nyb2xsVG8pKSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxhYmxlUGFuZWwuc2Nyb2xsVG9wID0gc2Nyb2xsVG87XG5cdFx0fVxuXHR9XG5cblx0c2Nyb2xsVG9UYWcoKSB7XG5cdFx0Y29uc3QgcGFuZWwgPSB0aGlzLl9zY3JvbGxhYmxlUGFuZWw7XG5cdFx0cGFuZWwuc2Nyb2xsVG9wID0gcGFuZWwuc2Nyb2xsSGVpZ2h0IC0gcGFuZWwuY2xpZW50SGVpZ2h0O1xuXHR9XG5cblx0YWRqdXN0UG9zaXRpb24oKSB7XG5cdFx0dGhpcy5fdXBkYXRlWVBvc2l0aW9uKCk7XG5cdH1cblxuXHRwcml2YXRlIF9oYW5kbGVEcm9wZG93blBvc2l0aW9uKCkge1xuXHRcdHRoaXMuX2N1cnJlbnRQb3NpdGlvbiA9IHRoaXMuX2NhbGN1bGF0ZUN1cnJlbnRQb3NpdGlvbih0aGlzLl9kcm9wZG93bik7XG5cdFx0aWYgKENTU19QT1NJVElPTlMuaW5jbHVkZXModGhpcy5fY3VycmVudFBvc2l0aW9uKSkge1xuXHRcdFx0dGhpcy5fdXBkYXRlRHJvcGRvd25DbGFzcyh0aGlzLl9jdXJyZW50UG9zaXRpb24pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl91cGRhdGVEcm9wZG93bkNsYXNzKCdib3R0b20nKTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5hcHBlbmRUbykge1xuXHRcdFx0dGhpcy5fdXBkYXRlWVBvc2l0aW9uKCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fZHJvcGRvd24uc3R5bGUub3BhY2l0eSA9ICcxJztcblx0fVxuXG5cdHByaXZhdGUgX3VwZGF0ZURyb3Bkb3duQ2xhc3MoY3VycmVudFBvc2l0aW9uOiBzdHJpbmcpIHtcblx0XHRDU1NfUE9TSVRJT05TLmZvckVhY2goKHBvc2l0aW9uKSA9PiB7XG5cdFx0XHRjb25zdCBSRU1PVkVfQ1NTX0NMQVNTID0gYG5nLXNlbGVjdC0ke3Bvc2l0aW9ufWA7XG5cdFx0XHR0aGlzLl9yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLl9kcm9wZG93biwgUkVNT1ZFX0NTU19DTEFTUyk7XG5cdFx0XHR0aGlzLl9yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLl9zZWxlY3QsIFJFTU9WRV9DU1NfQ0xBU1MpO1xuXHRcdH0pO1xuXG5cdFx0Y29uc3QgQUREX0NTU19DTEFTUyA9IGBuZy1zZWxlY3QtJHtjdXJyZW50UG9zaXRpb259YDtcblx0XHR0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyh0aGlzLl9kcm9wZG93biwgQUREX0NTU19DTEFTUyk7XG5cdFx0dGhpcy5fcmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5fc2VsZWN0LCBBRERfQ1NTX0NMQVNTKTtcblx0fVxuXG5cdHByaXZhdGUgX2hhbmRsZVNjcm9sbCgpIHtcblx0XHR0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcblx0XHRcdGZyb21FdmVudCh0aGlzLnNjcm9sbEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3Njcm9sbCcpXG5cdFx0XHRcdC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksIGF1ZGl0VGltZSgwLCBTQ1JPTExfU0NIRURVTEVSKSlcblx0XHRcdFx0LnN1YnNjcmliZSgoZTogeyBwYXRoOyBjb21wb3NlZFBhdGg7IHRhcmdldCB9KSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgcGF0aCA9IGUucGF0aCB8fCAoZS5jb21wb3NlZFBhdGggJiYgZS5jb21wb3NlZFBhdGgoKSk7XG5cdFx0XHRcdFx0aWYgKCFwYXRoIHx8IChwYXRoLmxlbmd0aCA9PT0gMCAmJiAhZS50YXJnZXQpKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IHNjcm9sbFRvcCA9ICFwYXRoIHx8IHBhdGgubGVuZ3RoID09PSAwID8gZS50YXJnZXQuc2Nyb2xsVG9wIDogcGF0aFswXS5zY3JvbGxUb3A7XG5cdFx0XHRcdFx0dGhpcy5fb25Db250ZW50U2Nyb2xsZWQoc2Nyb2xsVG9wKTtcblx0XHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIF9oYW5kbGVPdXRzaWRlQ2xpY2soKSB7XG5cdFx0aWYgKCF0aGlzLl9kb2N1bWVudCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXHRcdFx0bWVyZ2UoZnJvbUV2ZW50KHRoaXMuX2RvY3VtZW50LCAndG91Y2hzdGFydCcsIHsgY2FwdHVyZTogdHJ1ZSB9KSwgZnJvbUV2ZW50KHRoaXMuX2RvY3VtZW50LCAnY2xpY2snLCB7IGNhcHR1cmU6IHRydWUgfSkpXG5cdFx0XHRcdC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpXG5cdFx0XHRcdC5zdWJzY3JpYmUoKCRldmVudCkgPT4gdGhpcy5fY2hlY2tUb0Nsb3NlKCRldmVudCkpO1xuXHRcdH0pO1xuXHR9XG5cblx0cHJpdmF0ZSBfY2hlY2tUb0Nsb3NlKCRldmVudDogYW55KSB7XG5cdFx0aWYgKHRoaXMuX3NlbGVjdC5jb250YWlucygkZXZlbnQudGFyZ2V0KSB8fCB0aGlzLl9kcm9wZG93bi5jb250YWlucygkZXZlbnQudGFyZ2V0KSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHBhdGggPSAkZXZlbnQucGF0aCB8fCAoJGV2ZW50LmNvbXBvc2VkUGF0aCAmJiAkZXZlbnQuY29tcG9zZWRQYXRoKCkpO1xuXHRcdGlmICgkZXZlbnQudGFyZ2V0ICYmICRldmVudC50YXJnZXQuc2hhZG93Um9vdCAmJiBwYXRoICYmIHBhdGhbMF0gJiYgdGhpcy5fc2VsZWN0LmNvbnRhaW5zKHBhdGhbMF0pKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy5fem9uZS5ydW4oKCkgPT4gdGhpcy5vdXRzaWRlQ2xpY2suZW1pdCgpKTtcblx0fVxuXG5cdHByaXZhdGUgX29uSXRlbXNDaGFuZ2UoaXRlbXM6IE5nT3B0aW9uW10sIGZpcnN0Q2hhbmdlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5pdGVtcyA9IGl0ZW1zIHx8IFtdO1xuXHRcdHRoaXMuX3Njcm9sbFRvRW5kRmlyZWQgPSBmYWxzZTtcblx0XHR0aGlzLml0ZW1zTGVuZ3RoID0gaXRlbXMubGVuZ3RoO1xuXG5cdFx0aWYgKHRoaXMudmlydHVhbFNjcm9sbCkge1xuXHRcdFx0dGhpcy5fdXBkYXRlSXRlbXNSYW5nZShmaXJzdENoYW5nZSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX3NldFZpcnR1YWxIZWlnaHQoKTtcblx0XHRcdHRoaXMuX3VwZGF0ZUl0ZW1zKGZpcnN0Q2hhbmdlKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIF91cGRhdGVJdGVtcyhmaXJzdENoYW5nZTogYm9vbGVhbikge1xuXHRcdHRoaXMudXBkYXRlLmVtaXQodGhpcy5pdGVtcyk7XG5cdFx0aWYgKGZpcnN0Q2hhbmdlID09PSBmYWxzZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXHRcdFx0UHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHBhbmVsSGVpZ2h0ID0gdGhpcy5fc2Nyb2xsYWJsZVBhbmVsLmNsaWVudEhlaWdodDtcblx0XHRcdFx0dGhpcy5fcGFuZWxTZXJ2aWNlLnNldERpbWVuc2lvbnMoMCwgcGFuZWxIZWlnaHQpO1xuXHRcdFx0XHR0aGlzLl9oYW5kbGVEcm9wZG93blBvc2l0aW9uKCk7XG5cdFx0XHRcdHRoaXMuc2Nyb2xsVG8odGhpcy5tYXJrZWRJdGVtLCBmaXJzdENoYW5nZSk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgX3VwZGF0ZUl0ZW1zUmFuZ2UoZmlyc3RDaGFuZ2U6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcblx0XHRcdHRoaXMuX21lYXN1cmVEaW1lbnNpb25zKCkudGhlbigoKSA9PiB7XG5cdFx0XHRcdGlmIChmaXJzdENoYW5nZSkge1xuXHRcdFx0XHRcdHRoaXMuX3JlbmRlckl0ZW1zUmFuZ2UodGhpcy5fc3RhcnRPZmZzZXQpO1xuXHRcdFx0XHRcdHRoaXMuX2hhbmRsZURyb3Bkb3duUG9zaXRpb24oKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLl9yZW5kZXJJdGVtc1JhbmdlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0cHJpdmF0ZSBfb25Db250ZW50U2Nyb2xsZWQoc2Nyb2xsVG9wOiBudW1iZXIpIHtcblx0XHRpZiAodGhpcy52aXJ0dWFsU2Nyb2xsKSB7XG5cdFx0XHR0aGlzLl9yZW5kZXJJdGVtc1JhbmdlKHNjcm9sbFRvcCk7XG5cdFx0fVxuXHRcdHRoaXMuX2xhc3RTY3JvbGxQb3NpdGlvbiA9IHNjcm9sbFRvcDtcblx0XHR0aGlzLl9maXJlU2Nyb2xsVG9FbmQoc2Nyb2xsVG9wKTtcblx0fVxuXG5cdHByaXZhdGUgX3VwZGF0ZVZpcnR1YWxIZWlnaHQoaGVpZ2h0OiBudW1iZXIpIHtcblx0XHRpZiAodGhpcy5fdXBkYXRlU2Nyb2xsSGVpZ2h0KSB7XG5cdFx0XHR0aGlzLl92aXJ0dWFsUGFkZGluZy5zdHlsZS5oZWlnaHQgPSBgJHtoZWlnaHR9cHhgO1xuXHRcdFx0dGhpcy5fdXBkYXRlU2Nyb2xsSGVpZ2h0ID0gZmFsc2U7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBfc2V0VmlydHVhbEhlaWdodCgpIHtcblx0XHRpZiAoIXRoaXMuX3ZpcnR1YWxQYWRkaW5nKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy5fdmlydHVhbFBhZGRpbmcuc3R5bGUuaGVpZ2h0ID0gYDBweGA7XG5cdH1cblxuXHRwcml2YXRlIF9vbkl0ZW1zTGVuZ3RoQ2hhbmdlZCgpIHtcblx0XHR0aGlzLl91cGRhdGVTY3JvbGxIZWlnaHQgPSB0cnVlO1xuXHR9XG5cblx0cHJpdmF0ZSBfcmVuZGVySXRlbXNSYW5nZShzY3JvbGxUb3AgPSBudWxsKSB7XG5cdFx0aWYgKHNjcm9sbFRvcCAmJiB0aGlzLl9sYXN0U2Nyb2xsUG9zaXRpb24gPT09IHNjcm9sbFRvcCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHNjcm9sbFRvcCA9IHNjcm9sbFRvcCB8fCB0aGlzLl9zY3JvbGxhYmxlUGFuZWwuc2Nyb2xsVG9wO1xuXHRcdGNvbnN0IHJhbmdlID0gdGhpcy5fcGFuZWxTZXJ2aWNlLmNhbGN1bGF0ZUl0ZW1zKHNjcm9sbFRvcCwgdGhpcy