@alauda-fe/common
Version:
Alauda frontend team common codes.
288 lines • 48.5 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { observeResizeOn } from '@alauda/ui';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EventEmitter, Inject, Input, NgZone, Output, QueryList, Renderer2, ViewContainerRef, ViewEncapsulation, } from '@angular/core';
import { cloneDeep } from 'lodash-es';
import { combineLatest, distinctUntilChanged, exhaustMap, map, merge, NEVER, Observable, startWith, Subject, switchMap, takeUntil, } from 'rxjs';
import { isEqual, ObservableInput } from '../../../core/public-api';
import { DEFAULT_GUTTER, DEFAULT_LAYOUT_COLUMNS, DEFAULT_ROW_HEIGHT, } from '../../constant';
import { GridLayoutService } from '../../grid-layout.service';
import { GridPlaceholderService } from '../../grid-placeholder.service';
import { GridCompactType, } from '../../type';
import { getClientRectSnapshot } from '../../utils/client-rect.utils';
import { compactGridLayout, getDragResizeEventData, } from '../../utils/grid.utils';
import { getMouseEnd$, getMouseMove$ } from '../../utils/mouse.utils';
import { runOutsideZone$ } from '../../utils/operator';
import { scrollIfNearElementClientRect$ } from '../../utils/scroll.utils';
import { GridItemComponent } from '../grid-items/component';
import * as i0 from "@angular/core";
import * as i1 from "../../grid-placeholder.service";
import * as i2 from "../../grid-layout.service";
const _c0 = ["*"];
export class GridLayoutComponent {
get config() {
return {
cols: this.cols,
rowHeight: this.rowHeight,
layout: this.lastLayout,
preventCollision: this.preventCollision,
gutter: this.gutter,
};
}
get hostElement() {
return this.elementRef.nativeElement;
}
constructor(elementRef, viewContainerRef, renderer, ngZone, gridPlaceholderService, document, gridLayoutService) {
this.elementRef = elementRef;
this.viewContainerRef = viewContainerRef;
this.renderer = renderer;
this.ngZone = ngZone;
this.gridPlaceholderService = gridPlaceholderService;
this.document = document;
this.gridLayoutService = gridLayoutService;
this.layoutUpdated = new EventEmitter();
this.dragStarted = new EventEmitter();
this.resizeStarted = new EventEmitter();
this.dragEnded = new EventEmitter();
this.resizeEnded = new EventEmitter();
this.gridItemResize = new EventEmitter();
// Parent element that contains the scroll. If an string is provided it would search that element by id on the dom.
// use this to compensate dragging point and scroll difference
this.scrollableParent = null;
this.preventCollision = false;
this.scrollSpeed = 2;
this.compactType = GridCompactType.VERTICAL;
this.rowHeight = DEFAULT_ROW_HEIGHT;
this.cols = DEFAULT_LAYOUT_COLUMNS;
this.gutter = DEFAULT_GUTTER;
this.destroy$$ = new Subject();
this.markLayoutIdChange = false;
// we use this pattern to avoid too many property passing
this.gridLayoutService.registerGridComponent(this);
}
ngOnInit() {
observeResizeOn(this.hostElement)
.pipe(takeUntil(this.destroy$$))
.subscribe(() => {
this.gridLayoutService.calculateRenderData();
this.gridLayoutService.flushRenderData(true);
});
this.gridLayoutService.gridRenderHeight$$
.pipe(takeUntil(this.destroy$$), distinctUntilChanged(isEqual))
.subscribe(height => {
this.renderer.setStyle(this.hostElement, 'height', `${height}px`);
});
}
ngOnChanges(changes) {
let needsCompactLayout = false;
let needsRecalculateRenderData = false;
// Compact layout whenever some dependent prop changes.
if (changes.compactType || changes.cols || changes.layout || changes.id) {
needsCompactLayout = true;
}
if (changes.layout) {
this.lastLayout = changes.layout.currentValue;
}
if (changes.id) {
if (this.lastLayoutId && this.lastLayoutId !== changes.id.currentValue) {
this.markLayoutIdChange = true;
}
this.lastLayoutId = changes.id.currentValue;
}
// Check if wee need to recalculate rendering data.
if (needsCompactLayout ||
changes.rowHeight ||
changes.gutter ||
changes.layout) {
needsRecalculateRenderData = true;
}
const markLayoutIdChange = this.markLayoutIdChange;
if (needsRecalculateRenderData) {
// let ngOnChanges pass, we can use input props, and when props change, let grid-component destroy first
requestAnimationFrame(() => {
if (needsCompactLayout) {
this.compactLayout(markLayoutIdChange);
}
this.gridLayoutService.calculateRenderData();
// Do not need animation when total layout config change, which is dashId changing
this.gridLayoutService.flushRenderData(!markLayoutIdChange);
});
}
}
ngAfterContentInit() {
this.initSubscriptions();
}
ngAfterContentChecked() {
this.gridLayoutService.calculateRenderData();
this.gridLayoutService.flushRenderData(!this.markLayoutIdChange);
}
ngOnDestroy() {
this.destroy$$.next();
this.destroy$$.complete();
}
refreshLayout(dashIdChange) {
return dashIdChange
? this.lastLayout
: this.lastLayout?.map(layoutItem => ({
...layoutItem,
...this.gridLayoutService.lastLayout?.find(({ id }) => layoutItem.id === id),
}));
}
compactLayout(dashIdChange) {
this.lastLayout = compactGridLayout(this.refreshLayout(dashIdChange), this.compactType, this.cols);
}
getItemRenderData(itemId) {
return this.gridLayoutService.gridItemsRenderData[itemId];
}
initSubscriptions() {
this.gridItems.changes.pipe(takeUntil(this.destroy$$)).subscribe(() => {
const markLayoutIdChange = this.markLayoutIdChange;
// need this Raf to make this.lastLayout to be last
requestAnimationFrame(() => {
this.markLayoutIdChange = false;
this.compactLayout(!markLayoutIdChange);
this.gridLayoutService.calculateRenderData();
this.gridLayoutService.flushRenderData(!markLayoutIdChange);
});
});
this.gridItems.changes
.pipe(takeUntil(this.destroy$$), startWith(this.gridItems), switchMap((gridItems) => merge(...gridItems.map(gridItem => gridItem.dragStart$.pipe(map(event => ({
event,
gridItem,
type: 'drag',
})))), ...gridItems.map(gridItem => gridItem.resizeStart$.pipe(map(event => ({
event,
gridItem,
type: 'resize',
}))))).pipe(exhaustMap(({ event, gridItem, type }) => {
this.ngZone.run(() => (type === 'drag' ? this.dragStarted : this.resizeStarted).emit(getDragResizeEventData(gridItem, this.lastLayout)));
return this.handleAction$(gridItem, event, type).pipe(map(layout => ({ layout, gridItem, type })));
}))))
.subscribe(({ layout, gridItem, type }) => {
this.lastLayout = layout;
(type === 'drag' ? this.dragEnded : this.resizeEnded).emit(getDragResizeEventData(gridItem, layout));
this.layoutUpdated.emit(layout);
});
}
handleAction$(gridItem, pointerDownEvent, type) {
return new Observable((observer) => {
// Retrieve grid (parent) and gridItem (draggedElem) client rects.
const gridElemClientRectSnapshot = getClientRectSnapshot(this.elementRef.nativeElement);
const dragElemClientRectSnapshot = getClientRectSnapshot(gridItem.elementRef.nativeElement);
const scrollableParent = typeof this.scrollableParent === 'string'
? document.querySelector(this.scrollableParent)
: this.scrollableParent;
this.renderer.addClass(gridItem.elementRef.nativeElement, 'no-transitions');
this.renderer.addClass(gridItem.elementRef.nativeElement, 'grid-item-dragging');
const placeholderClientRect = {
...dragElemClientRectSnapshot,
left: dragElemClientRectSnapshot.left - gridElemClientRectSnapshot.left,
top: dragElemClientRectSnapshot.top - gridElemClientRectSnapshot.top,
};
this.gridPlaceholderService.createPlaceholderElement(placeholderClientRect, this.elementRef, this.viewContainerRef, gridItem.placeholder);
let newLayout;
(scrollableParent
? getMouseMove$(this.document.documentElement).pipe(runOutsideZone$(this.ngZone), takeUntil(this.destroy$$), scrollIfNearElementClientRect$(scrollableParent, {
scrollStep: this.scrollSpeed,
}))
: NEVER)
.pipe(takeUntil(getMouseEnd$(this.document.documentElement)))
.subscribe();
merge(combineLatest([
getMouseMove$(this.document.documentElement),
this.gridLayoutService.scrollDifference$,
]))
.pipe(runOutsideZone$(this.ngZone), takeUntil(getMouseEnd$(this.document.documentElement)), takeUntil(this.destroy$$))
.subscribe(([pointerDragEvent, scrollDifference]) => {
pointerDragEvent.preventDefault();
const gridItemId = gridItem.id;
const { gridData, layout } = this.gridLayoutService.layoutWhenAction(gridItem, type, {
pointerDownEvent,
pointerDragEvent,
}, scrollDifference, dragElemClientRectSnapshot, gridElemClientRectSnapshot);
this.gridLayoutService.flushRenderData();
newLayout = cloneDeep(layout);
const newItemGridData = { ...gridData[gridItemId] };
// put the grid normalize position to the placeholder element
this.gridPlaceholderService.updatePlaceHolder(newItemGridData);
type === 'resize' &&
this.gridItemResize.emit({
width: newItemGridData.width,
height: newItemGridData.height,
gridItemRef: getDragResizeEventData(gridItem, newLayout)
.gridItemRef,
});
}, error => observer.error(error), () => {
this.ngZone.run(() => {
this.renderer.removeClass(gridItem.elementRef.nativeElement, 'no-transitions');
this.renderer.removeClass(gridItem.elementRef.nativeElement, 'grid-item-dragging');
// when action is done, use another relayout to make sure everything is fine
this.compactLayout(false);
this.gridLayoutService.calculateRenderData();
this.gridLayoutService.flushRenderData();
this.gridPlaceholderService.destroyPlaceholder();
if (newLayout) {
observer.next(cloneDeep(newLayout));
}
observer.complete();
});
});
});
}
static { this.ɵfac = function GridLayoutComponent_Factory(t) { return new (t || GridLayoutComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i1.GridPlaceholderService), i0.ɵɵdirectiveInject(DOCUMENT), i0.ɵɵdirectiveInject(i2.GridLayoutService)); }; }
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: GridLayoutComponent, selectors: [["acl-grid-layout"]], contentQueries: function GridLayoutComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
i0.ɵɵcontentQuery(dirIndex, GridItemComponent, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.gridItems = _t);
} }, inputs: { scrollableParent: "scrollableParent", id: "id", preventCollision: "preventCollision", scrollSpeed: "scrollSpeed", compactType: "compactType", rowHeight: "rowHeight", cols: "cols", layout: "layout", gutter: "gutter" }, outputs: { layoutUpdated: "layoutUpdated", dragStarted: "dragStarted", resizeStarted: "resizeStarted", dragEnded: "dragEnded", resizeEnded: "resizeEnded", gridItemResize: "gridItemResize" }, features: [i0.ɵɵProvidersFeature([GridPlaceholderService, GridLayoutService]), i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c0, decls: 1, vars: 0, template: function GridLayoutComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0);
} }, styles: ["acl-grid-layout{display:block;position:relative;width:100%}acl-grid-layout acl-grid-item.grid-item-dragging{z-index:500}acl-grid-layout acl-grid-item.no-transitions{transition:none!important}acl-grid-layout .grid-item-placeholder-default{transition:all .15s ease;position:absolute;background-color:rgb(var(--aui-color-p-6));z-index:0;border-radius:var(--aui-border-radius-l);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;border:1px dashed rgb(var(--aui-color-primary))}\n"], encapsulation: 2, changeDetection: 0 }); }
}
__decorate([
ObservableInput(),
__metadata("design:type", Observable)
], GridLayoutComponent.prototype, "scrollableParent$", void 0);
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(GridLayoutComponent, [{
type: Component,
args: [{ selector: 'acl-grid-layout', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [GridPlaceholderService, GridLayoutService], template: "<ng-content></ng-content>\n", styles: ["acl-grid-layout{display:block;position:relative;width:100%}acl-grid-layout acl-grid-item.grid-item-dragging{z-index:500}acl-grid-layout acl-grid-item.no-transitions{transition:none!important}acl-grid-layout .grid-item-placeholder-default{transition:all .15s ease;position:absolute;background-color:rgb(var(--aui-color-p-6));z-index:0;border-radius:var(--aui-border-radius-l);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;border:1px dashed rgb(var(--aui-color-primary))}\n"] }]
}], () => [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.GridPlaceholderService }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i2.GridLayoutService }], { gridItems: [{
type: ContentChildren,
args: [GridItemComponent, { descendants: true }]
}], layoutUpdated: [{
type: Output
}], dragStarted: [{
type: Output
}], resizeStarted: [{
type: Output
}], dragEnded: [{
type: Output
}], resizeEnded: [{
type: Output
}], gridItemResize: [{
type: Output
}], scrollableParent: [{
type: Input
}], scrollableParent$: [], id: [{
type: Input
}], preventCollision: [{
type: Input
}], scrollSpeed: [{
type: Input
}], compactType: [{
type: Input
}], rowHeight: [{
type: Input
}], cols: [{
type: Input
}], layout: [{
type: Input
}], gutter: [{
type: Input
}] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(GridLayoutComponent, { className: "GridLayoutComponent" }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21tb24vc3JjL2dyaWQtbGF5b3V0L2NvbXBvbmVudHMvZ3JpZC9jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvZ3JpZC1sYXlvdXQvY29tcG9uZW50cy9ncmlkL3RlbXBsYXRlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDN0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFHTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULGVBQWUsRUFDZixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUlOLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUVULGdCQUFnQixFQUNoQixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN0QyxPQUFPLEVBQ0wsYUFBYSxFQUNiLG9CQUFvQixFQUNwQixVQUFVLEVBQ1YsR0FBRyxFQUNILEtBQUssRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUVWLFNBQVMsRUFDVCxPQUFPLEVBQ1AsU0FBUyxFQUNULFNBQVMsR0FDVixNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDcEUsT0FBTyxFQUNMLGNBQWMsRUFDZCxzQkFBc0IsRUFDdEIsa0JBQWtCLEdBQ25CLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDOUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFD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QUFpQixFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtZQUcvQyxhQUFhO2tCQUF0QixNQUFNO1lBR0csV0FBVztrQkFBcEIsTUFBTTtZQUdHLGFBQWE7a0JBQXRCLE1BQU07WUFHRyxTQUFTO2tCQUFsQixNQUFNO1lBR0csV0FBVztrQkFBcEIsTUFBTTtZQUdHLGNBQWM7a0JBQXZCLE1BQU07WUFLRSxnQkFBZ0I7a0JBQXhCLEtBQUs7WUFDYSxpQkFBaUIsTUFLcEMsRUFBRTtrQkFERCxLQUFLO1lBSU4sZ0JBQWdCO2tCQURmLEtBQUs7WUFJTixXQUFXO2tCQURWLEtBQUs7WUFJTixXQUFXO2tCQURWLEtBQUs7WUFJTixTQUFTO2tCQURSLEtBQUs7WUFJTixJQUFJO2tCQURILEtBQUs7WUFJTixNQUFNO2tCQURMLEtBQUs7WUFJTixNQUFNO2tCQURMLEtBQUs7O2tGQTFESyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBvYnNlcnZlUmVzaXplT24gfSBmcm9tICdAYWxhdWRhL3VpJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudENoZWNrZWQsXG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNsb25lRGVlcCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQge1xuICBjb21iaW5lTGF0ZXN0LFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZXhoYXVzdE1hcCxcbiAgbWFwLFxuICBtZXJnZSxcbiAgTkVWRVIsXG4gIE9ic2VydmFibGUsXG4gIE9ic2VydmVyLFxuICBzdGFydFdpdGgsXG4gIFN1YmplY3QsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZVVudGlsLFxufSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgaXNFcXVhbCwgT2JzZXJ2YWJsZUlucHV0IH0gZnJvbSAnLi4vLi4vLi4vY29yZS9wdWJsaWMtYXBpJztcbmltcG9ydCB7XG4gIERFRkFVTFRfR1VUVEVSLFxuICBERUZBVUxUX0xBWU9VVF9DT0xVTU5TLFxuICBERUZBVUxUX1JPV19IRUlHSFQsXG59IGZyb20gJy4uLy4uL2NvbnN0YW50JztcbmltcG9ydCB7IEdyaWRMYXlvdXRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZ3JpZC1sYXlvdXQuc2VydmljZSc7XG5pbXBvcnQgeyBHcmlkUGxhY2Vob2xkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZ3JpZC1wbGFjZWhvbGRlci5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIEdyaWRDb21wYWN0VHlwZSxcbiAgRHJhZ0VuZEV2ZW50LFxuICBEcmFnU3RhcnRFdmVudCxcbiAgR3JpZExheW91dCxcbiAgR3JpZExheW91dEl0ZW0sXG4gIFJlc2l6ZVN0YXJ0RXZlbnQsXG4gIEdyaWRDZmcsXG4gIEdyaWRJdGVtUmVuZGVyRGF0YSxcbiAgR3JpZEl0ZW1DbGllbnRSZWN0LFxuICBEcmFnQWN0aW9uVHlwZSxcbiAgUmVzaXplRW5kRXZlbnQsXG4gIEl0ZW1SZXNpemVFdmVudCxcbn0gZnJvbSAnLi4vLi4vdHlwZSc7XG5pbXBvcnQgeyBnZXRDbGllbnRSZWN0U25hcHNob3QgfSBmcm9tICcuLi8uLi91dGlscy9jbGllbnQtcmVjdC51dGlscyc7XG5pbXBvcnQge1xuICBjb21wYWN0R3JpZExheW91dCxcbiAgZ2V0RHJhZ1Jlc2l6ZUV2ZW50RGF0YSxcbn0gZnJvbSAnLi4vLi4vdXRpbHMvZ3JpZC51dGlscyc7XG5pbXBvcnQgeyBnZXRNb3VzZUVuZCQsIGdldE1vdXNlTW92ZSQgfSBmcm9tICcuLi8uLi91dGlscy9tb3VzZS51dGlscyc7XG5pbXBvcnQgeyBydW5PdXRzaWRlWm9uZSQgfSBmcm9tICcuLi8uLi91dGlscy9vcGVyYXRvcic7XG5pbXBvcnQgeyBzY3JvbGxJZk5lYXJFbGVtZW50Q2xpZW50UmVjdCQgfSBmcm9tICcuLi8uLi91dGlscy9zY3JvbGwudXRpbHMnO1xuaW1wb3J0IHsgR3JpZEl0ZW1Db21wb25lbnQgfSBmcm9tICcuLi9ncmlkLWl0ZW1zL2NvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FjbC1ncmlkLWxheW91dCcsXG4gIHRlbXBsYXRlVXJsOiAnLi90ZW1wbGF0ZS5odG1sJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc3R5bGVVcmxzOiBbJy4vc3R5bGUuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbR3JpZFBsYWNlaG9sZGVyU2VydmljZSwgR3JpZExheW91dFNlcnZpY2VdLFxufSlcbmV4cG9ydCBjbGFzcyBHcmlkTGF5b3V0Q29tcG9uZW50XG4gIGltcGxlbWVudHNcbiAgICBPbkluaXQsXG4gICAgT25DaGFuZ2VzLFxuICAgIEFmdGVyQ29udGVudENoZWNrZWQsXG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBPbkRlc3Ryb3lcbntcbiAgLyoqIFF1ZXJ5IGxpc3Qgb2YgZ3JpZCBpdGVtcyB0aGF0IGFyZSBiZWluZyByZW5kZXJlZC4gKi9cbiAgQENvbnRlbnRDaGlsZHJlbihHcmlkSXRlbUNvbXBvbmVudCwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KVxuICBncmlkSXRlbXM6IFF1ZXJ5TGlzdDxHcmlkSXRlbUNvbXBvbmVudD47XG5cbiAgQE91dHB1dCgpIGxheW91dFVwZGF0ZWQ6IEV2ZW50RW1pdHRlcjxHcmlkTGF5b3V0PiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxHcmlkTGF5b3V0PigpO1xuXG4gIEBPdXRwdXQoKSBkcmFnU3RhcnRlZDogRXZlbnRFbWl0dGVyPERyYWdTdGFydEV2ZW50PiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxEcmFnU3RhcnRFdmVudD4oKTtcblxuICBAT3V0cHV0KCkgcmVzaXplU3RhcnRlZDogRXZlbnRFbWl0dGVyPFJlc2l6ZVN0YXJ0RXZlbnQ+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPFJlc2l6ZVN0YXJ0RXZlbnQ+KCk7XG5cbiAgQE91dHB1dCgpIGRyYWdFbmRlZDogRXZlbnRFbWl0dGVyPERyYWdFbmRFdmVudD4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8RHJhZ0VuZEV2ZW50PigpO1xuXG4gIEBPdXRwdXQoKSByZXNpemVFbmRlZDogRXZlbnRFbWl0dGVyPFJlc2l6ZUVuZEV2ZW50PiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxSZXNpemVFbmRFdmVudD4oKTtcblxuICBAT3V0cHV0KCkgZ3JpZEl0ZW1SZXNpemU6IEV2ZW50RW1pdHRlcjxJdGVtUmVzaXplRXZlbnQ+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPEl0ZW1SZXNpemVFdmVudD4oKTtcblxuICAvLyBQYXJlbnQgZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRoZSBzY3JvbGwuIElmIGFuIHN0cmluZyBpcyBwcm92aWRlZCBpdCB3b3VsZCBzZWFyY2ggdGhhdCBlbGVtZW50IGJ5IGlkIG9uIHRoZSBkb20uXG4gIC8vIHVzZSB0aGlzIHRvIGNvbXBlbnNhdGUgZHJhZ2dpbmcgcG9pbnQgYW5kIHNjcm9sbCBkaWZmZXJlbmNlXG4gIEBJbnB1dCgpIHNjcm9sbGFibGVQYXJlbnQ6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgfCBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgQE9ic2VydmFibGVJbnB1dCgpIHNjcm9sbGFibGVQYXJlbnQkOiBPYnNlcnZhYmxlPFxuICAgIEhUTUxFbGVtZW50IHwgRG9jdW1lbnQgfCBzdHJpbmcgfCBudWxsXG4gID47XG5cbiAgQElucHV0KClcbiAgaWQ6IHN0cmluZztcblxuICBASW5wdXQoKVxuICBwcmV2ZW50Q29sbGlzaW9uID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgc2Nyb2xsU3BlZWQgPSAyO1xuXG4gIEBJbnB1dCgpXG4gIGNvbXBhY3RUeXBlID0gR3JpZENvbXBhY3RUeXBlLlZFUlRJQ0FMO1xuXG4gIEBJbnB1dCgpXG4gIHJvd0hlaWdodDogbnVtYmVyID0gREVGQVVMVF9ST1dfSEVJR0hUO1xuXG4gIEBJbnB1dCgpXG4gIGNvbHM6IG51bWJlciA9IERFRkFVTFRfTEFZT1VUX0NPTFVNTlM7XG5cbiAgQElucHV0KClcbiAgbGF5b3V0OiBHcmlkTGF5b3V0O1xuXG4gIEBJbnB1dCgpXG4gIGd1dHRlcjogbnVtYmVyID0gREVGQVVMVF9HVVRURVI7XG5cbiAgcHJpdmF0ZSBsYXN0TGF5b3V0OiBHcmlkTGF5b3V0O1xuXG4gIGRlc3Ryb3kkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgZ2V0IGNvbmZpZygpOiBHcmlkQ2ZnIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sczogdGhpcy5jb2xzLFxuICAgICAgcm93SGVpZ2h0OiB0aGlzLnJvd0hlaWdodCxcbiAgICAgIGxheW91dDogdGhpcy5sYXN0TGF5b3V0LFxuICAgICAgcHJldmVudENvbGxpc2lvbjogdGhpcy5wcmV2ZW50Q29sbGlzaW9uLFxuICAgICAgZ3V0dGVyOiB0aGlzLmd1dHRlcixcbiAgICB9O1xuICB9XG5cbiAgZ2V0IGhvc3RFbGVtZW50KCkge1xuICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHB1YmxpYyB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ3JpZFBsYWNlaG9sZGVyU2VydmljZTogR3JpZFBsYWNlaG9sZGVyU2VydmljZSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIHJlYWRvbmx5IGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdyaWRMYXlvdXRTZXJ2aWNlOiBHcmlkTGF5b3V0U2VydmljZSxcbiAgKSB7XG4gICAgLy8gd2UgdXNlIHRoaXMgcGF0dGVybiB0byBhdm9pZCB0b28gbWFueSBwcm9wZXJ0eSBwYXNzaW5nXG4gICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5yZWdpc3RlckdyaWRDb21wb25lbnQodGhpcyk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBvYnNlcnZlUmVzaXplT24odGhpcy5ob3N0RWxlbWVudClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkJCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5jYWxjdWxhdGVSZW5kZXJEYXRhKCk7XG4gICAgICAgIHRoaXMuZ3JpZExheW91dFNlcnZpY2UuZmx1c2hSZW5kZXJEYXRhKHRydWUpO1xuICAgICAgfSk7XG4gICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5ncmlkUmVuZGVySGVpZ2h0JCRcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkJCksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGlzRXF1YWwpKVxuICAgICAgLnN1YnNjcmliZShoZWlnaHQgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuaG9zdEVsZW1lbnQsICdoZWlnaHQnLCBgJHtoZWlnaHR9cHhgKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBsYXN0TGF5b3V0SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBtYXJrTGF5b3V0SWRDaGFuZ2UgPSBmYWxzZTtcblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgbGV0IG5lZWRzQ29tcGFjdExheW91dCA9IGZhbHNlO1xuICAgIGxldCBuZWVkc1JlY2FsY3VsYXRlUmVuZGVyRGF0YSA9IGZhbHNlO1xuICAgIC8vIENvbXBhY3QgbGF5b3V0IHdoZW5ldmVyIHNvbWUgZGVwZW5kZW50IHByb3AgY2hhbmdlcy5cbiAgICBpZiAoY2hhbmdlcy5jb21wYWN0VHlwZSB8fCBjaGFuZ2VzLmNvbHMgfHwgY2hhbmdlcy5sYXlvdXQgfHwgY2hhbmdlcy5pZCkge1xuICAgICAgbmVlZHNDb21wYWN0TGF5b3V0ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmxhc3RMYXlvdXQgPSBjaGFuZ2VzLmxheW91dC5jdXJyZW50VmFsdWU7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzLmlkKSB7XG4gICAgICBpZiAodGhpcy5sYXN0TGF5b3V0SWQgJiYgdGhpcy5sYXN0TGF5b3V0SWQgIT09IGNoYW5nZXMuaWQuY3VycmVudFZhbHVlKSB7XG4gICAgICAgIHRoaXMubWFya0xheW91dElkQ2hhbmdlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMubGFzdExheW91dElkID0gY2hhbmdlcy5pZC5jdXJyZW50VmFsdWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgd2VlIG5lZWQgdG8gcmVjYWxjdWxhdGUgcmVuZGVyaW5nIGRhdGEuXG4gICAgaWYgKFxuICAgICAgbmVlZHNDb21wYWN0TGF5b3V0IHx8XG4gICAgICBjaGFuZ2VzLnJvd0hlaWdodCB8fFxuICAgICAgY2hhbmdlcy5ndXR0ZXIgfHxcbiAgICAgIGNoYW5nZXMubGF5b3V0XG4gICAgKSB7XG4gICAgICBuZWVkc1JlY2FsY3VsYXRlUmVuZGVyRGF0YSA9IHRydWU7XG4gICAgfVxuICAgIGNvbnN0IG1hcmtMYXlvdXRJZENoYW5nZSA9IHRoaXMubWFya0xheW91dElkQ2hhbmdlO1xuICAgIGlmIChuZWVkc1JlY2FsY3VsYXRlUmVuZGVyRGF0YSkge1xuICAgICAgLy8gbGV0IG5nT25DaGFuZ2VzIHBhc3MsIHdlIGNhbiB1c2UgaW5wdXQgcHJvcHMsIGFuZCB3aGVuIHByb3BzIGNoYW5nZSwgbGV0IGdyaWQtY29tcG9uZW50IGRlc3Ryb3kgZmlyc3RcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIGlmIChuZWVkc0NvbXBhY3RMYXlvdXQpIHtcbiAgICAgICAgICB0aGlzLmNvbXBhY3RMYXlvdXQobWFya0xheW91dElkQ2hhbmdlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdyaWRMYXlvdXRTZXJ2aWNlLmNhbGN1bGF0ZVJlbmRlckRhdGEoKTtcbiAgICAgICAgLy8gRG8gbm90IG5lZWQgYW5pbWF0aW9uIHdoZW4gdG90YWwgbGF5b3V0IGNvbmZpZyBjaGFuZ2UsIHdoaWNoIGlzIGRhc2hJZCBjaGFuZ2luZ1xuICAgICAgICB0aGlzLmdyaWRMYXlvdXRTZXJ2aWNlLmZsdXNoUmVuZGVyRGF0YSghbWFya0xheW91dElkQ2hhbmdlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLmluaXRTdWJzY3JpcHRpb25zKCk7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG4gICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5jYWxjdWxhdGVSZW5kZXJEYXRhKCk7XG4gICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5mbHVzaFJlbmRlckRhdGEoIXRoaXMubWFya0xheW91dElkQ2hhbmdlKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveSQkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkJC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcmVmcmVzaExheW91dChkYXNoSWRDaGFuZ2U6IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gZGFzaElkQ2hhbmdlXG4gICAgICA/IHRoaXMubGFzdExheW91dFxuICAgICAgOiB0aGlzLmxhc3RMYXlvdXQ/Lm1hcChsYXlvdXRJdGVtID0+ICh7XG4gICAgICAgICAgLi4ubGF5b3V0SXRlbSxcbiAgICAgICAgICAuLi50aGlzLmdyaWRMYXlvdXRTZXJ2aWNlLmxhc3RMYXlvdXQ/LmZpbmQoXG4gICAgICAgICAgICAoeyBpZCB9KSA9PiBsYXlvdXRJdGVtLmlkID09PSBpZCxcbiAgICAgICAgICApLFxuICAgICAgICB9KSk7XG4gIH1cblxuICBjb21wYWN0TGF5b3V0KGRhc2hJZENoYW5nZTogYm9vbGVhbikge1xuICAgIHRoaXMubGFzdExheW91dCA9IGNvbXBhY3RHcmlkTGF5b3V0KFxuICAgICAgdGhpcy5yZWZyZXNoTGF5b3V0KGRhc2hJZENoYW5nZSksXG4gICAgICB0aGlzLmNvbXBhY3RUeXBlLFxuICAgICAgdGhpcy5jb2xzLFxuICAgICk7XG4gIH1cblxuICBnZXRJdGVtUmVuZGVyRGF0YShpdGVtSWQ6IHN0cmluZyk6IEdyaWRJdGVtUmVuZGVyRGF0YSB7XG4gICAgcmV0dXJuIHRoaXMuZ3JpZExheW91dFNlcnZpY2UuZ3JpZEl0ZW1zUmVuZGVyRGF0YVtpdGVtSWRdO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0U3Vic2NyaXB0aW9ucygpIHtcbiAgICB0aGlzLmdyaWRJdGVtcy5jaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IG1hcmtMYXlvdXRJZENoYW5nZSA9IHRoaXMubWFya0xheW91dElkQ2hhbmdlO1xuICAgICAgLy8gbmVlZCB0aGlzIFJhZiB0byBtYWtlIHRoaXMubGFzdExheW91dCB0byBiZSBsYXN0XG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB0aGlzLm1hcmtMYXlvdXRJZENoYW5nZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNvbXBhY3RMYXlvdXQoIW1hcmtMYXlvdXRJZENoYW5nZSk7XG4gICAgICAgIHRoaXMuZ3JpZExheW91dFNlcnZpY2UuY2FsY3VsYXRlUmVuZGVyRGF0YSgpO1xuICAgICAgICB0aGlzLmdyaWRMYXlvdXRTZXJ2aWNlLmZsdXNoUmVuZGVyRGF0YSghbWFya0xheW91dElkQ2hhbmdlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMuZ3JpZEl0ZW1zLmNoYW5nZXNcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95JCQpLFxuICAgICAgICBzdGFydFdpdGgodGhpcy5ncmlkSXRlbXMpLFxuICAgICAgICBzd2l0Y2hNYXAoKGdyaWRJdGVtczogUXVlcnlMaXN0PEdyaWRJdGVtQ29tcG9uZW50PikgPT5cbiAgICAgICAgICBtZXJnZShcbiAgICAgICAgICAgIC4uLmdyaWRJdGVtcy5tYXAoZ3JpZEl0ZW0gPT5cbiAgICAgICAgICAgICAgZ3JpZEl0ZW0uZHJhZ1N0YXJ0JC5waXBlKFxuICAgICAgICAgICAgICAgIG1hcChldmVudCA9PiAoe1xuICAgICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgICBncmlkSXRlbSxcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdkcmFnJyBhcyBEcmFnQWN0aW9uVHlwZSxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgLi4uZ3JpZEl0ZW1zLm1hcChncmlkSXRlbSA9PlxuICAgICAgICAgICAgICBncmlkSXRlbS5yZXNpemVTdGFydCQucGlwZShcbiAgICAgICAgICAgICAgICBtYXAoZXZlbnQgPT4gKHtcbiAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgZ3JpZEl0ZW0sXG4gICAgICAgICAgICAgICAgICB0eXBlOiAncmVzaXplJyBhcyBEcmFnQWN0aW9uVHlwZSxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICkucGlwZShcbiAgICAgICAgICAgIGV4aGF1c3RNYXAoKHsgZXZlbnQsIGdyaWRJdGVtLCB0eXBlIH0pID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+XG4gICAgICAgICAgICAgICAgKHR5cGUgPT09ICdkcmFnJyA/IHRoaXMuZHJhZ1N0YXJ0ZWQgOiB0aGlzLnJlc2l6ZVN0YXJ0ZWQpLmVtaXQoXG4gICAgICAgICAgICAgICAgICBnZXREcmFnUmVzaXplRXZlbnREYXRhKGdyaWRJdGVtLCB0aGlzLmxhc3RMYXlvdXQpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZUFjdGlvbiQoZ3JpZEl0ZW0sIGV2ZW50LCB0eXBlKS5waXBlKFxuICAgICAgICAgICAgICAgIG1hcChsYXlvdXQgPT4gKHsgbGF5b3V0LCBncmlkSXRlbSwgdHlwZSB9KSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoeyBsYXlvdXQsIGdyaWRJdGVtLCB0eXBlIH0pID0+IHtcbiAgICAgICAgdGhpcy5sYXN0TGF5b3V0ID0gbGF5b3V0O1xuICAgICAgICAodHlwZSA9PT0gJ2RyYWcnID8gdGhpcy5kcmFnRW5kZWQgOiB0aGlzLnJlc2l6ZUVuZGVkKS5lbWl0KFxuICAgICAgICAgIGdldERyYWdSZXNpemVFdmVudERhdGEoZ3JpZEl0ZW0sIGxheW91dCksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubGF5b3V0VXBkYXRlZC5lbWl0KGxheW91dCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQWN0aW9uJChcbiAgICBncmlkSXRlbTogR3JpZEl0ZW1Db21wb25lbnQsXG4gICAgcG9pbnRlckRvd25FdmVudDogTW91c2VFdmVudCxcbiAgICB0eXBlOiBEcmFnQWN0aW9uVHlwZSxcbiAgKTogT2JzZXJ2YWJsZTxHcmlkTGF5b3V0PiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlPEdyaWRMYXlvdXQ+KChvYnNlcnZlcjogT2JzZXJ2ZXI8R3JpZExheW91dD4pID0+IHtcbiAgICAgIC8vIFJldHJpZXZlIGdyaWQgKHBhcmVudCkgYW5kIGdyaWRJdGVtIChkcmFnZ2VkRWxlbSkgY2xpZW50IHJlY3RzLlxuICAgICAgY29uc3QgZ3JpZEVsZW1DbGllbnRSZWN0U25hcHNob3Q6IEdyaWRJdGVtQ2xpZW50UmVjdCA9XG4gICAgICAgIGdldENsaWVudFJlY3RTbmFwc2hvdCh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCk7XG4gICAgICBjb25zdCBkcmFnRWxlbUNsaWVudFJlY3RTbmFwc2hvdDogR3JpZEl0ZW1DbGllbnRSZWN0ID1cbiAgICAgICAgZ2V0Q2xpZW50UmVjdFNuYXBzaG90KGdyaWRJdGVtLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCk7XG5cbiAgICAgIGNvbnN0IHNjcm9sbGFibGVQYXJlbnQgPVxuICAgICAgICB0eXBlb2YgdGhpcy5zY3JvbGxhYmxlUGFyZW50ID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLnNjcm9sbGFibGVQYXJlbnQpXG4gICAgICAgICAgOiB0aGlzLnNjcm9sbGFibGVQYXJlbnQ7XG5cbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3MoXG4gICAgICAgIGdyaWRJdGVtLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgJ25vLXRyYW5zaXRpb25zJyxcbiAgICAgICk7XG4gICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKFxuICAgICAgICBncmlkSXRlbS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICdncmlkLWl0ZW0tZHJhZ2dpbmcnLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgcGxhY2Vob2xkZXJDbGllbnRSZWN0OiBHcmlkSXRlbUNsaWVudFJlY3QgPSB7XG4gICAgICAgIC4uLmRyYWdFbGVtQ2xpZW50UmVjdFNuYXBzaG90LFxuICAgICAgICBsZWZ0OiBkcmFnRWxlbUNsaWVudFJlY3RTbmFwc2hvdC5sZWZ0IC0gZ3JpZEVsZW1DbGllbnRSZWN0U25hcHNob3QubGVmdCxcbiAgICAgICAgdG9wOiBkcmFnRWxlbUNsaWVudFJlY3RTbmFwc2hvdC50b3AgLSBncmlkRWxlbUNsaWVudFJlY3RTbmFwc2hvdC50b3AsXG4gICAgICB9O1xuICAgICAgdGhpcy5ncmlkUGxhY2Vob2xkZXJTZXJ2aWNlLmNyZWF0ZVBsYWNlaG9sZGVyRWxlbWVudChcbiAgICAgICAgcGxhY2Vob2xkZXJDbGllbnRSZWN0LFxuICAgICAgICB0aGlzLmVsZW1lbnRSZWYsXG4gICAgICAgIHRoaXMudmlld0NvbnRhaW5lclJlZixcbiAgICAgICAgZ3JpZEl0ZW0ucGxhY2Vob2xkZXIsXG4gICAgICApO1xuXG4gICAgICBsZXQgbmV3TGF5b3V0OiBHcmlkTGF5b3V0SXRlbVtdO1xuXG4gICAgICAoc2Nyb2xsYWJsZVBhcmVudFxuICAgICAgICA/IGdldE1vdXNlTW92ZSQodGhpcy5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLnBpcGUoXG4gICAgICAgICAgICBydW5PdXRzaWRlWm9uZSQodGhpcy5uZ1pvbmUpLFxuICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQkKSxcbiAgICAgICAgICAgIHNjcm9sbElmTmVhckVsZW1lbnRDbGllbnRSZWN0JChzY3JvbGxhYmxlUGFyZW50LCB7XG4gICAgICAgICAgICAgIHNjcm9sbFN0ZXA6IHRoaXMuc2Nyb2xsU3BlZWQsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApXG4gICAgICAgIDogTkVWRVJcbiAgICAgIClcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKGdldE1vdXNlRW5kJCh0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkpKVxuICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgICBtZXJnZShcbiAgICAgICAgY29tYmluZUxhdGVzdChbXG4gICAgICAgICAgZ2V0TW91c2VNb3ZlJCh0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCksXG4gICAgICAgICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5zY3JvbGxEaWZmZXJlbmNlJCxcbiAgICAgICAgXSksXG4gICAgICApXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHJ1bk91dHNpZGVab25lJCh0aGlzLm5nWm9uZSksXG4gICAgICAgICAgdGFrZVVudGlsKGdldE1vdXNlRW5kJCh0aGlzLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkpLFxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkJCksXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAoW3BvaW50ZXJEcmFnRXZlbnQsIHNjcm9sbERpZmZlcmVuY2VdOiBbXG4gICAgICAgICAgICBNb3VzZUV2ZW50LFxuICAgICAgICAgICAgeyB0b3A6IG51bWJlcjsgbGVmdDogbnVtYmVyIH0sXG4gICAgICAgICAgXSkgPT4ge1xuICAgICAgICAgICAgcG9pbnRlckRyYWdFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgY29uc3QgZ3JpZEl0ZW1JZCA9IGdyaWRJdGVtLmlkO1xuICAgICAgICAgICAgY29uc3QgeyBncmlkRGF0YSwgbGF5b3V0IH0gPVxuICAgICAgICAgICAgICB0aGlzLmdyaWRMYXlvdXRTZXJ2aWNlLmxheW91dFdoZW5BY3Rpb24oXG4gICAgICAgICAgICAgICAgZ3JpZEl0ZW0sXG4gICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBwb2ludGVyRG93bkV2ZW50LFxuICAgICAgICAgICAgICAgICAgcG9pbnRlckRyYWdFdmVudCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHNjcm9sbERpZmZlcmVuY2UsXG4gICAgICAgICAgICAgICAgZHJhZ0VsZW1DbGllbnRSZWN0U25hcHNob3QsXG4gICAgICAgICAgICAgICAgZ3JpZEVsZW1DbGllbnRSZWN0U25hcHNob3QsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmdyaWRMYXlvdXRTZXJ2aWNlLmZsdXNoUmVuZGVyRGF0YSgpO1xuICAgICAgICAgICAgbmV3TGF5b3V0ID0gY2xvbmVEZWVwKGxheW91dCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG5ld0l0ZW1HcmlkRGF0YSA9IHsgLi4uZ3JpZERhdGFbZ3JpZEl0ZW1JZF0gfTtcblxuICAgICAgICAgICAgLy8gcHV0IHRoZSBncmlkIG5vcm1hbGl6ZSBwb3NpdGlvbiB0byB0aGUgcGxhY2Vob2xkZXIgZWxlbWVudFxuICAgICAgICAgICAgdGhpcy5ncmlkUGxhY2Vob2xkZXJTZXJ2aWNlLnVwZGF0ZVBsYWNlSG9sZGVyKG5ld0l0ZW1HcmlkRGF0YSk7XG5cbiAgICAgICAgICAgIHR5cGUgPT09ICdyZXNpemUnICYmXG4gICAgICAgICAgICAgIHRoaXMuZ3JpZEl0ZW1SZXNpemUuZW1pdCh7XG4gICAgICAgICAgICAgICAgd2lkdGg6IG5ld0l0ZW1HcmlkRGF0YS53aWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IG5ld0l0ZW1HcmlkRGF0YS5oZWlnaHQsXG4gICAgICAgICAgICAgICAgZ3JpZEl0ZW1SZWY6IGdldERyYWdSZXNpemVFdmVudERhdGEoZ3JpZEl0ZW0sIG5ld0xheW91dClcbiAgICAgICAgICAgICAgICAgIC5ncmlkSXRlbVJlZixcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvciA9PiBvYnNlcnZlci5lcnJvcihlcnJvciksXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhcbiAgICAgICAgICAgICAgICBncmlkSXRlbS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAgICAgJ25vLXRyYW5zaXRpb25zJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhcbiAgICAgICAgICAgICAgICBncmlkSXRlbS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAgICAgJ2dyaWQtaXRlbS1kcmFnZ2luZycsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIC8vIHdoZW4gYWN0aW9uIGlzIGRvbmUsIHVzZSBhbm90aGVyIHJlbGF5b3V0IHRvIG1ha2Ugc3VyZSBldmVyeXRoaW5nIGlzIGZpbmVcbiAgICAgICAgICAgICAgdGhpcy5jb21wYWN0TGF5b3V0KGZhbHNlKTtcbiAgICAgICAgICAgICAgdGhpcy5ncmlkTGF5b3V0U2VydmljZS5jYWxjdWxhdGVSZW5kZXJEYXRhKCk7XG4gICAgICAgICAgICAgIHRoaXMuZ3JpZExheW91dFNlcnZpY2UuZmx1c2hSZW5kZXJEYXRhKCk7XG5cbiAgICAgICAgICAgICAgdGhpcy5ncmlkUGxhY2Vob2xkZXJTZXJ2aWNlLmRlc3Ryb3lQbGFjZWhvbGRlcigpO1xuICAgICAgICAgICAgICBpZiAobmV3TGF5b3V0KSB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChjbG9uZURlZXAobmV3TGF5b3V0KSBhcyBHcmlkTGF5b3V0KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuIl19