@hxui/angular
Version:
An Angular library based on the [HXUI design system](https://hxui.io).
281 lines • 36.5 kB
JavaScript
import { Overlay } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
import { ContentChild, Directive, ElementRef, EventEmitter, Input, Output, Renderer2, ViewContainerRef } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { DropdownMenuDirective } from './dropdown-menu.directive';
import { DropdownConfig } from './dropdown.config';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/overlay";
import * as i2 from "./dropdown.config";
export class DropdownDirective {
constructor(_elementRef, _viewContainerRef, overlay, _config, renderer) {
this._elementRef = _elementRef;
this._viewContainerRef = _viewContainerRef;
this.overlay = overlay;
this._config = _config;
this.renderer = renderer;
this._destroyed = new Subject();
this.isOpen = false;
this.placement = 'bottom';
this._autoClose = this._config.autoClose;
this.isOpenChange = new EventEmitter();
this.onShown = new EventEmitter();
this.onHidden = new EventEmitter();
this.isDisabled = false;
this.showDelay = this._config.showDelay;
this.hideDelay = this._config.hideDelay;
this.offsetY = 0;
this.offsetX = 0;
this.createClipPathMask = false;
}
set autoClose(value) {
this._autoClose = value;
}
get autoClose() {
return this._autoClose;
}
ngOnDestroy() {
if (this._overlayRef) {
this._overlayRef.dispose();
this._overlayRef = null;
}
this._destroyed.next(true);
this._destroyed.complete();
}
/**
* Toggles an element’s popover. This is considered a “manual” triggering of
* the popover.
*/
toggle(value) {
if (this.isOpen || value === false) {
return this.hide();
}
return this.show();
}
show(delay = this.showDelay) {
if (this.isDisabled || this.isOpen) {
return;
}
const overlayRef = this._createOverlay();
this._detach();
overlayRef.attach(this._portal);
if (this.createClipPathMask) {
this._addClipPathMaskStyles();
}
this._setWidthsRelativeTo(overlayRef);
this.isOpen = true;
this.isOpenChange.emit(this.isOpen);
this.onShown.emit();
}
hide(delay = this.hideDelay) {
this._detach();
this.isOpen = false;
this.isOpenChange.emit(this.isOpen);
this.onHidden.emit();
}
_createOverlay() {
if (this._overlayRef) {
return this._overlayRef;
}
this._portal = new TemplatePortal(this.menu.templateRef, this._viewContainerRef);
const positionStrategy = this.overlay
.position()
.flexibleConnectedTo(this._elementRef)
.withFlexibleDimensions(false)
.withDefaultOffsetX(this.offsetX)
.withDefaultOffsetY(this.offsetY)
.withPositions([
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top' }
])
.withTransformOriginOn('.hxa-dropdown-control');
this._overlayRef = this.overlay.create({
positionStrategy: positionStrategy,
panelClass: [
'hxui-reset',
'hxa-dropdown-panel',
'is-open',
this.minWidthRelativeTo ? 'is-fluid-min-width' : 'not-fuild-min-width'
],
hasBackdrop: true,
backdropClass: 'cdk-overlay-transparent-backdrop'
});
this._updatePosition();
this._overlayRef
.detachments()
.pipe(takeUntil(this._destroyed))
.subscribe(() => this._detach());
this._overlayRef.backdropClick().subscribe(() => this.hide());
const position = this._overlayRef.getConfig()
.positionStrategy;
position.positionChanges.pipe(takeUntil(this._destroyed)).subscribe(pos => {
if (pos.connectionPair.originX === 'start') {
this.placement = 'left';
}
else if (pos.connectionPair.originX === 'end') {
this.placement = 'right';
}
else if (pos.connectionPair.originY === 'top') {
this.placement = 'top';
}
else if (pos.connectionPair.originY === 'bottom') {
this.placement = 'bottom';
}
});
return this._overlayRef;
}
_detach() {
if (this._overlayRef && this._overlayRef.hasAttached()) {
this._overlayRef.detach();
}
}
_setWidthsRelativeTo(overlayRef) {
if (this.maxWidthRelativeTo && this.minWidthRelativeTo) {
const elem = document.getElementById(this.maxWidthRelativeTo);
overlayRef.updateSize({
minWidth: elem.clientWidth,
maxWidth: elem.clientWidth
});
}
else if (this.maxWidthRelativeTo) {
const elem = document.getElementById(this.maxWidthRelativeTo);
overlayRef.updateSize({ maxWidth: elem.clientWidth });
}
else if (this.minWidthRelativeTo) {
const elem = document.getElementById(this.minWidthRelativeTo);
overlayRef.updateSize({ minWidth: elem.clientWidth });
}
}
_updatePosition() {
const position = this._overlayRef.getConfig()
.positionStrategy;
const origin = this._getOrigin();
const overlay = this._getOverlayPosition();
position.withPositions([
{ ...origin.main, ...overlay.main },
{ ...origin.fallback, ...overlay.fallback }
]);
}
/**
* Returns the origin position and a fallback position based on the user's position preference.
* The fallback position is the inverse of the origin (e.g. `'bottom' -> 'top'`).
*/
_getOrigin() {
const placement = this.placement;
let originPlacement;
if (placement === 'top' || placement === 'bottom') {
originPlacement = {
originX: 'start',
originY: placement === 'top' ? 'top' : 'bottom'
};
}
else if (placement === 'left') {
originPlacement = { originX: 'start', originY: 'center' };
}
else if (placement === 'right') {
originPlacement = { originX: 'end', originY: 'center' };
}
else {
console.error('Position error', placement);
}
const { x, y } = this._invertPosition(originPlacement.originX, originPlacement.originY);
return {
main: originPlacement,
fallback: { originX: x, originY: y }
};
}
/** Returns the overlay position and a fallback position based on the user's preference */
_getOverlayPosition() {
const placement = this.placement;
let overlayPlacement;
if (placement === 'top') {
overlayPlacement = { overlayX: 'start', overlayY: 'bottom' };
}
else if (placement === 'bottom') {
overlayPlacement = { overlayX: 'start', overlayY: 'top' };
}
else if (placement === 'left') {
overlayPlacement = { overlayX: 'end', overlayY: 'center' };
}
else if (placement === 'right') {
overlayPlacement = { overlayX: 'start', overlayY: 'center' };
}
else {
console.error('Could not find a position', placement);
}
const { x, y } = this._invertPosition(overlayPlacement.overlayX, overlayPlacement.overlayY);
return {
main: overlayPlacement,
fallback: { overlayX: x, overlayY: y }
};
}
_invertPosition(x, y) {
if (this.placement === 'top' || this.placement === 'bottom') {
if (y === 'top') {
y = 'bottom';
}
else if (y === 'bottom') {
y = 'top';
}
}
else {
if (x === 'end') {
x = 'start';
}
else if (x === 'start') {
x = 'end';
}
}
return { x, y };
}
// Create a clip path mask in the backdrop. The mask is a rectangle, the size of the viewcontainer
// This enables the user to interact with the contents of the viewcontainer without closing the dropdown
_addClipPathMaskStyles() {
const HTMLEl = this._overlayRef.backdropElement;
const viewRefNativeEl = this._viewContainerRef.element.nativeElement;
const elRect = viewRefNativeEl.getBoundingClientRect();
if (elRect) {
const clipPathStyle = `polygon(0% 0%, 0% 100%, ${elRect.left}px 100%, ${elRect.left}px ${elRect.top}px, ${elRect.right}px ${elRect.top}px, ${elRect.right}px ${elRect.bottom}px, ${elRect.left}px ${elRect.bottom}px, ${elRect.left}px 100%, 100% 100%, 100% 0%)`;
this.renderer.setStyle(HTMLEl, 'clip-path', clipPathStyle);
}
}
}
DropdownDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DropdownDirective, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: i2.DropdownConfig }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
DropdownDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: DropdownDirective, selector: "[hxaDropdown],[hxDropdown]", inputs: { placement: "placement", autoClose: "autoClose", isDisabled: "isDisabled", showDelay: "showDelay", hideDelay: "hideDelay", maxWidthRelativeTo: "maxWidthRelativeTo", minWidthRelativeTo: "minWidthRelativeTo", offsetY: "offsetY", offsetX: "offsetX", createClipPathMask: "createClipPathMask" }, outputs: { isOpenChange: "isOpenChange", onShown: "onShown", onHidden: "onHidden" }, queries: [{ propertyName: "menu", first: true, predicate: DropdownMenuDirective, descendants: true }], exportAs: ["hx-dropdown", "hxa-dropdown"], ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DropdownDirective, decorators: [{
type: Directive,
args: [{
selector: '[hxaDropdown],[hxDropdown]',
exportAs: 'hx-dropdown, hxa-dropdown'
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i2.DropdownConfig }, { type: i0.Renderer2 }]; }, propDecorators: { menu: [{
type: ContentChild,
args: [DropdownMenuDirective]
}], placement: [{
type: Input
}], autoClose: [{
type: Input
}], isOpenChange: [{
type: Output
}], onShown: [{
type: Output
}], onHidden: [{
type: Output
}], isDisabled: [{
type: Input
}], showDelay: [{
type: Input
}], hideDelay: [{
type: Input
}], maxWidthRelativeTo: [{
type: Input
}], minWidthRelativeTo: [{
type: Input
}], offsetY: [{
type: Input
}], offsetX: [{
type: Input
}], createClipPathMask: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHgtdWkvc3JjL2xpYi9kcm9wZG93bi9kcm9wZG93bi5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUlMLE9BQU8sRUFJUixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULGdCQUFnQixFQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7QUFNbkQsTUFBTSxPQUFPLGlCQUFpQjtJQW1ENUIsWUFDVSxXQUF1QixFQUN2QixpQkFBbUMsRUFDcEMsT0FBZ0IsRUFDaEIsT0FBdUIsRUFDdEIsUUFBbUI7UUFKbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNwQyxZQUFPLEdBQVAsT0FBTyxDQUFTO1FBQ2hCLFlBQU8sR0FBUCxPQUFPLENBQWdCO1FBQ3RCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFuRFosZUFBVSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDckMsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUd0QixjQUFTLEdBQXdDLFFBQVEsQ0FBQztRQUVsRCxlQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7UUFVbEMsaUJBQVksR0FBMEIsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUVsRSxZQUFPLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7UUFFckQsYUFBUSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBR2hFLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFHbkIsY0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1FBR25DLGNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztRQVNuQyxZQUFPLEdBQUcsQ0FBQyxDQUFDO1FBR1osWUFBTyxHQUFHLENBQUMsQ0FBQztRQUdaLHVCQUFrQixHQUFHLEtBQUssQ0FBQztJQVF4QixDQUFDO0lBN0NKLElBQ0ksU0FBUyxDQUFDLEtBQWM7UUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBd0NELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztTQUN6QjtRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxLQUFlO1FBQ3BCLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxLQUFLLEtBQUssS0FBSyxFQUFFO1lBQ2xDLE9BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3BCO1FBRUQsT0FBTyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVELElBQUksQ0FBQyxRQUFnQixJQUFJLENBQUMsU0FBUztRQUNqQyxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNsQyxPQUFPO1NBQ1I7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2YsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFaEMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFDM0IsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7U0FDL0I7UUFFRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksQ0FBQyxRQUFnQixJQUFJLENBQUMsU0FBUztRQUNqQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRU8sY0FBYztRQUNwQixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQ3pCO1FBRUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGNBQWMsQ0FDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQ3JCLElBQUksQ0FBQyxpQkFBaUIsQ0FDdkIsQ0FBQztRQUVGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE9BQU87YUFDbEMsUUFBUSxFQUFFO2FBQ1YsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQzthQUNyQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUM7YUFDN0Isa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQzthQUNoQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2FBQ2hDLGFBQWEsQ0FBQztZQUNiLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRTtTQUN6RSxDQUFDO2FBQ0QscUJBQXFCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUVsRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQ3JDLGdCQUFnQixFQUFFLGdCQUFnQjtZQUNsQyxVQUFVLEVBQUU7Z0JBQ1YsWUFBWTtnQkFDWixvQkFBb0I7Z0JBQ3BCLFNBQVM7Z0JBQ1QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMscUJBQXFCO2FBQ3ZFO1lBQ0QsV0FBVyxFQUFFLElBQUk7WUFDakIsYUFBYSxFQUFFLGtDQUFrQztTQUNsRCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFdkIsSUFBSSxDQUFDLFdBQVc7YUFDYixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUNoQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFFOUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUU7YUFDMUMsZ0JBQXFELENBQUM7UUFDekQsUUFBUSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN4RSxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsT0FBTyxLQUFLLE9BQU8sRUFBRTtnQkFDMUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7YUFDekI7aUJBQU0sSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLE9BQU8sS0FBSyxLQUFLLEVBQUU7Z0JBQy9DLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO2FBQzFCO2lCQUFNLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEtBQUssS0FBSyxFQUFFO2dCQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQzthQUN4QjtpQkFBTSxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsT0FBTyxLQUFLLFFBQVEsRUFBRTtnQkFDbEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7YUFDM0I7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUMxQixDQUFDO0lBRU8sT0FBTztRQUNiLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3RELElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDM0I7SUFDSCxDQUFDO0lBRU8sb0JBQW9CLENBQUMsVUFBc0I7UUFDakQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3RELE1BQU0sSUFBSSxHQUFZLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDdkUsVUFBVSxDQUFDLFVBQVUsQ0FBQztnQkFDcEIsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUMxQixRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVc7YUFDM0IsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUNsQyxNQUFNLElBQUksR0FBWSxRQUFRLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3ZFLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7U0FDdkQ7YUFBTSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUNsQyxNQUFNLElBQUksR0FBWSxRQUFRLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3ZFLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7U0FDdkQ7SUFDSCxDQUFDO0lBRU8sZUFBZTtRQUNyQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBWSxDQUFDLFNBQVMsRUFBRTthQUMzQyxnQkFBcUQsQ0FBQztRQUN6RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDakMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFFM0MsUUFBUSxDQUFDLGFBQWEsQ0FBQztZQUNyQixFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQUU7WUFDbkMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRyxPQUFPLENBQUMsUUFBUSxFQUFFO1NBQzVDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSyxVQUFVO1FBSWhCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxlQUF5QyxDQUFDO1FBRTlDLElBQUksU0FBUyxLQUFLLEtBQUssSUFBSSxTQUFTLEtBQUssUUFBUSxFQUFFO1lBQ2pELGVBQWUsR0FBRztnQkFDaEIsT0FBTyxFQUFFLE9BQU87Z0JBQ2hCLE9BQU8sRUFBRSxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVE7YUFDaEQsQ0FBQztTQUNIO2FBQU0sSUFBSSxTQUFTLEtBQUssTUFBTSxFQUFFO1lBQy9CLGVBQWUsR0FBRyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQzNEO2FBQU0sSUFBSSxTQUFTLEtBQUssT0FBTyxFQUFFO1lBQ2hDLGVBQWUsR0FBRyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQ3pEO2FBQU07WUFDTCxPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQzVDO1FBRUQsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUNuQyxlQUFlLENBQUMsT0FBTyxFQUN2QixlQUFlLENBQUMsT0FBTyxDQUN4QixDQUFDO1FBRUYsT0FBTztZQUNMLElBQUksRUFBRSxlQUFlO1lBQ3JCLFFBQVEsRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRTtTQUNyQyxDQUFDO0lBQ0osQ0FBQztJQUVELDBGQUEwRjtJQUNsRixtQkFBbUI7UUFJekIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNqQyxJQUFJLGdCQUEyQyxDQUFDO1FBRWhELElBQUksU0FBUyxLQUFLLEtBQUssRUFBRTtZQUN2QixnQkFBZ0IsR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQzlEO2FBQU0sSUFBSSxTQUFTLEtBQUssUUFBUSxFQUFFO1lBQ2pDLGdCQUFnQixHQUFHLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7U0FDM0Q7YUFBTSxJQUFJLFNBQVMsS0FBSyxNQUFNLEVBQUU7WUFDL0IsZ0JBQWdCLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztTQUM1RDthQUFNLElBQUksU0FBUyxLQUFLLE9BQU8sRUFBRTtZQUNoQyxnQkFBZ0IsR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQzlEO2FBQU07WUFDTCxPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3ZEO1FBRUQsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUNuQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQ3pCLGdCQUFnQixDQUFDLFFBQVEsQ0FDMUIsQ0FBQztRQUVGLE9BQU87WUFDTCxJQUFJLEVBQUUsZ0JBQWdCO1lBQ3RCLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRTtTQUN2QyxDQUFDO0lBQ0osQ0FBQztJQUVPLGVBQWUsQ0FDckIsQ0FBMEIsRUFDMUIsQ0FBd0I7UUFFeEIsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRTtZQUMzRCxJQUFJLENBQUMsS0FBSyxLQUFLLEVBQUU7Z0JBQ2YsQ0FBQyxHQUFHLFFBQVEsQ0FBQzthQUNkO2lCQUFNLElBQUksQ0FBQyxLQUFLLFFBQVEsRUFBRTtnQkFDekIsQ0FBQyxHQUFHLEtBQUssQ0FBQzthQUNYO1NBQ0Y7YUFBTTtZQUNMLElBQUksQ0FBQyxLQUFLLEtBQUssRUFBRTtnQkFDZixDQUFDLEdBQUcsT0FBTyxDQUFDO2FBQ2I7aUJBQU0sSUFBSSxDQUFDLEtBQUssT0FBTyxFQUFFO2dCQUN4QixDQUFDLEdBQUcsS0FBSyxDQUFDO2FBQ1g7U0FDRjtRQUVELE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVELGtHQUFrRztJQUNsRyx3R0FBd0c7SUFDaEcsc0JBQXNCO1FBQzVCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDO1FBQ2hELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQ3JFLE1BQU0sTUFBTSxHQUFHLGVBQWUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ3ZELElBQUksTUFBTSxFQUFFO1lBQ1YsTUFBTSxhQUFhLEdBQUcsMkJBQTJCLE1BQU0sQ0FBQyxJQUFJLFlBQVksTUFBTSxDQUFDLElBQUksTUFBTSxNQUFNLENBQUMsR0FBRyxPQUFPLE1BQU0sQ0FBQyxLQUFLLE1BQU0sTUFBTSxDQUFDLEdBQUcsT0FBTyxNQUFNLENBQUMsS0FBSyxNQUFNLE1BQU0sQ0FBQyxNQUFNLE9BQU8sTUFBTSxDQUFDLElBQUksTUFBTSxNQUFNLENBQUMsTUFBTSxPQUFPLE1BQU0sQ0FBQyxJQUFJLDhCQUE4QixDQUFDO1lBQ2xRLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7U0FDNUQ7SUFDSCxDQUFDOzsrR0F4U1UsaUJBQWlCO21HQUFqQixpQkFBaUIscWVBQ2QscUJBQXFCOzRGQUR4QixpQkFBaUI7a0JBSjdCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLDRCQUE0QjtvQkFDdEMsUUFBUSxFQUFFLDJCQUEyQjtpQkFDdEM7Mk1BRXNDLElBQUk7c0JBQXhDLFlBQVk7dUJBQUMscUJBQXFCO2dCQVFuQyxTQUFTO3NCQURSLEtBQUs7Z0JBS0YsU0FBUztzQkFEWixLQUFLO2dCQVNJLFlBQVk7c0JBQXJCLE1BQU07Z0JBRUcsT0FBTztzQkFBaEIsTUFBTTtnQkFFRyxRQUFRO3NCQUFqQixNQUFNO2dCQUdQLFVBQVU7c0JBRFQsS0FBSztnQkFJTixTQUFTO3NCQURSLEtBQUs7Z0JBSU4sU0FBUztzQkFEUixLQUFLO2dCQUlOLGtCQUFrQjtzQkFEakIsS0FBSztnQkFJTixrQkFBa0I7c0JBRGpCLEtBQUs7Z0JBSU4sT0FBTztzQkFETixLQUFLO2dCQUlOLE9BQU87c0JBRE4sS0FBSztnQkFJTixrQkFBa0I7c0JBRGpCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSxcclxuICBIb3Jpem9udGFsQ29ubmVjdGlvblBvcyxcclxuICBPcmlnaW5Db25uZWN0aW9uUG9zaXRpb24sXHJcbiAgT3ZlcmxheSxcclxuICBPdmVybGF5Q29ubmVjdGlvblBvc2l0aW9uLFxyXG4gIE92ZXJsYXlSZWYsXHJcbiAgVmVydGljYWxDb25uZWN0aW9uUG9zXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBUZW1wbGF0ZVBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xyXG5pbXBvcnQge1xyXG4gIENvbnRlbnRDaGlsZCxcclxuICBEaXJlY3RpdmUsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE91dHB1dCxcclxuICBSZW5kZXJlcjIsXHJcbiAgVmlld0NvbnRhaW5lclJlZlxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgRHJvcGRvd25NZW51RGlyZWN0aXZlIH0gZnJvbSAnLi9kcm9wZG93bi1tZW51LmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IERyb3Bkb3duQ29uZmlnIH0gZnJvbSAnLi9kcm9wZG93bi5jb25maWcnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbaHhhRHJvcGRvd25dLFtoeERyb3Bkb3duXScsXHJcbiAgZXhwb3J0QXM6ICdoeC1kcm9wZG93biwgaHhhLWRyb3Bkb3duJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRHJvcGRvd25EaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIEBDb250ZW50Q2hpbGQoRHJvcGRvd25NZW51RGlyZWN0aXZlKSBtZW51OiBEcm9wZG93bk1lbnVEaXJlY3RpdmU7XHJcblxyXG4gIF9vdmVybGF5UmVmOiBPdmVybGF5UmVmIHwgbnVsbDtcclxuICBwcml2YXRlIF9wb3J0YWw6IFRlbXBsYXRlUG9ydGFsO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3llZCA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgcHVibGljIGlzT3BlbiA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHBsYWNlbWVudDogJ3RvcCcgfCAnYm90dG9tJyB8ICdsZWZ0JyB8ICdyaWdodCcgPSAnYm90dG9tJztcclxuXHJcbiAgcHJpdmF0ZSBfYXV0b0Nsb3NlID0gdGhpcy5fY29uZmlnLmF1dG9DbG9zZTtcclxuICBASW5wdXQoKVxyXG4gIHNldCBhdXRvQ2xvc2UodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2F1dG9DbG9zZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGF1dG9DbG9zZSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9hdXRvQ2xvc2U7XHJcbiAgfVxyXG5cclxuICBAT3V0cHV0KCkgaXNPcGVuQ2hhbmdlOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcblxyXG4gIEBPdXRwdXQoKSBvblNob3duOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICBAT3V0cHV0KCkgb25IaWRkZW46IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgaXNEaXNhYmxlZCA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHNob3dEZWxheSA9IHRoaXMuX2NvbmZpZy5zaG93RGVsYXk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgaGlkZURlbGF5ID0gdGhpcy5fY29uZmlnLmhpZGVEZWxheTtcclxuXHJcbiAgQElucHV0KClcclxuICBtYXhXaWR0aFJlbGF0aXZlVG86IHN0cmluZztcclxuXHJcbiAgQElucHV0KClcclxuICBtaW5XaWR0aFJlbGF0aXZlVG86IHN0cmluZztcclxuXHJcbiAgQElucHV0KClcclxuICBvZmZzZXRZID0gMDtcclxuXHJcbiAgQElucHV0KClcclxuICBvZmZzZXRYID0gMDtcclxuXHJcbiAgQElucHV0KClcclxuICBjcmVhdGVDbGlwUGF0aE1hc2sgPSBmYWxzZTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBfdmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZixcclxuICAgIHB1YmxpYyBvdmVybGF5OiBPdmVybGF5LFxyXG4gICAgcHVibGljIF9jb25maWc6IERyb3Bkb3duQ29uZmlnLFxyXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9vdmVybGF5UmVmKSB7XHJcbiAgICAgIHRoaXMuX292ZXJsYXlSZWYuZGlzcG9zZSgpO1xyXG4gICAgICB0aGlzLl9vdmVybGF5UmVmID0gbnVsbDtcclxuICAgIH1cclxuICAgIHRoaXMuX2Rlc3Ryb3llZC5uZXh0KHRydWUpO1xyXG4gICAgdGhpcy5fZGVzdHJveWVkLmNvbXBsZXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGVzIGFuIGVsZW1lbnTigJlzIHBvcG92ZXIuIFRoaXMgaXMgY29uc2lkZXJlZCBhIOKAnG1hbnVhbOKAnSB0cmlnZ2VyaW5nIG9mXHJcbiAgICogdGhlIHBvcG92ZXIuXHJcbiAgICovXHJcbiAgdG9nZ2xlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXNPcGVuIHx8IHZhbHVlID09PSBmYWxzZSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5oaWRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuc2hvdygpO1xyXG4gIH1cclxuXHJcbiAgc2hvdyhkZWxheTogbnVtYmVyID0gdGhpcy5zaG93RGVsYXkpIHtcclxuICAgIGlmICh0aGlzLmlzRGlzYWJsZWQgfHwgdGhpcy5pc09wZW4pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG92ZXJsYXlSZWYgPSB0aGlzLl9jcmVhdGVPdmVybGF5KCk7XHJcbiAgICB0aGlzLl9kZXRhY2goKTtcclxuICAgIG92ZXJsYXlSZWYuYXR0YWNoKHRoaXMuX3BvcnRhbCk7XHJcblxyXG4gICAgaWYgKHRoaXMuY3JlYXRlQ2xpcFBhdGhNYXNrKSB7XHJcbiAgICAgIHRoaXMuX2FkZENsaXBQYXRoTWFza1N0eWxlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3NldFdpZHRoc1JlbGF0aXZlVG8ob3ZlcmxheVJlZik7XHJcbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgICB0aGlzLmlzT3BlbkNoYW5nZS5lbWl0KHRoaXMuaXNPcGVuKTtcclxuICAgIHRoaXMub25TaG93bi5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBoaWRlKGRlbGF5OiBudW1iZXIgPSB0aGlzLmhpZGVEZWxheSkge1xyXG4gICAgdGhpcy5fZGV0YWNoKCk7XHJcbiAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgdGhpcy5pc09wZW5DaGFuZ2UuZW1pdCh0aGlzLmlzT3Blbik7XHJcbiAgICB0aGlzLm9uSGlkZGVuLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NyZWF0ZU92ZXJsYXkoKTogT3ZlcmxheVJlZiB7XHJcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZikge1xyXG4gICAgICByZXR1cm4gdGhpcy5fb3ZlcmxheVJlZjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9wb3J0YWwgPSBuZXcgVGVtcGxhdGVQb3J0YWwoXHJcbiAgICAgIHRoaXMubWVudS50ZW1wbGF0ZVJlZixcclxuICAgICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZlxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBwb3NpdGlvblN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5XHJcbiAgICAgIC5wb3NpdGlvbigpXHJcbiAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMuX2VsZW1lbnRSZWYpXHJcbiAgICAgIC53aXRoRmxleGlibGVEaW1lbnNpb25zKGZhbHNlKVxyXG4gICAgICAud2l0aERlZmF1bHRPZmZzZXRYKHRoaXMub2Zmc2V0WClcclxuICAgICAgLndpdGhEZWZhdWx0T2Zmc2V0WSh0aGlzLm9mZnNldFkpXHJcbiAgICAgIC53aXRoUG9zaXRpb25zKFtcclxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnLCBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICd0b3AnIH1cclxuICAgICAgXSlcclxuICAgICAgLndpdGhUcmFuc2Zvcm1PcmlnaW5PbignLmh4YS1kcm9wZG93bi1jb250cm9sJyk7XHJcblxyXG4gICAgdGhpcy5fb3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheS5jcmVhdGUoe1xyXG4gICAgICBwb3NpdGlvblN0cmF0ZWd5OiBwb3NpdGlvblN0cmF0ZWd5LFxyXG4gICAgICBwYW5lbENsYXNzOiBbXHJcbiAgICAgICAgJ2h4dWktcmVzZXQnLFxyXG4gICAgICAgICdoeGEtZHJvcGRvd24tcGFuZWwnLFxyXG4gICAgICAgICdpcy1vcGVuJyxcclxuICAgICAgICB0aGlzLm1pbldpZHRoUmVsYXRpdmVUbyA/ICdpcy1mbHVpZC1taW4td2lkdGgnIDogJ25vdC1mdWlsZC1taW4td2lkdGgnXHJcbiAgICAgIF0sXHJcbiAgICAgIGhhc0JhY2tkcm9wOiB0cnVlLFxyXG4gICAgICBiYWNrZHJvcENsYXNzOiAnY2RrLW92ZXJsYXktdHJhbnNwYXJlbnQtYmFja2Ryb3AnXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLl91cGRhdGVQb3NpdGlvbigpO1xyXG5cclxuICAgIHRoaXMuX292ZXJsYXlSZWZcclxuICAgICAgLmRldGFjaG1lbnRzKClcclxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fZGV0YWNoKCkpO1xyXG5cclxuICAgIHRoaXMuX292ZXJsYXlSZWYuYmFja2Ryb3BDbGljaygpLnN1YnNjcmliZSgoKSA9PiB0aGlzLmhpZGUoKSk7XHJcblxyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9vdmVybGF5UmVmLmdldENvbmZpZygpXHJcbiAgICAgIC5wb3NpdGlvblN0cmF0ZWd5IGFzIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneTtcclxuICAgIHBvc2l0aW9uLnBvc2l0aW9uQ2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKS5zdWJzY3JpYmUocG9zID0+IHtcclxuICAgICAgaWYgKHBvcy5jb25uZWN0aW9uUGFpci5vcmlnaW5YID09PSAnc3RhcnQnKSB7XHJcbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSAnbGVmdCc7XHJcbiAgICAgIH0gZWxzZSBpZiAocG9zLmNvbm5lY3Rpb25QYWlyLm9yaWdpblggPT09ICdlbmQnKSB7XHJcbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSAncmlnaHQnO1xyXG4gICAgICB9IGVsc2UgaWYgKHBvcy5jb25uZWN0aW9uUGFpci5vcmlnaW5ZID09PSAndG9wJykge1xyXG4gICAgICAgIHRoaXMucGxhY2VtZW50ID0gJ3RvcCc7XHJcbiAgICAgIH0gZWxzZSBpZiAocG9zLmNvbm5lY3Rpb25QYWlyLm9yaWdpblkgPT09ICdib3R0b20nKSB7XHJcbiAgICAgICAgdGhpcy5wbGFjZW1lbnQgPSAnYm90dG9tJztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX292ZXJsYXlSZWY7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9kZXRhY2goKSB7XHJcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZiAmJiB0aGlzLl9vdmVybGF5UmVmLmhhc0F0dGFjaGVkKCkpIHtcclxuICAgICAgdGhpcy5fb3ZlcmxheVJlZi5kZXRhY2goKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NldFdpZHRoc1JlbGF0aXZlVG8ob3ZlcmxheVJlZjogT3ZlcmxheVJlZikge1xyXG4gICAgaWYgKHRoaXMubWF4V2lkdGhSZWxhdGl2ZVRvICYmIHRoaXMubWluV2lkdGhSZWxhdGl2ZVRvKSB7XHJcbiAgICAgIGNvbnN0IGVsZW06IEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1heFdpZHRoUmVsYXRpdmVUbyk7XHJcbiAgICAgIG92ZXJsYXlSZWYudXBkYXRlU2l6ZSh7XHJcbiAgICAgICAgbWluV2lkdGg6IGVsZW0uY2xpZW50V2lkdGgsXHJcbiAgICAgICAgbWF4V2lkdGg6IGVsZW0uY2xpZW50V2lkdGhcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMubWF4V2lkdGhSZWxhdGl2ZVRvKSB7XHJcbiAgICAgIGNvbnN0IGVsZW06IEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1heFdpZHRoUmVsYXRpdmVUbyk7XHJcbiAgICAgIG92ZXJsYXlSZWYudXBkYXRlU2l6ZSh7IG1heFdpZHRoOiBlbGVtLmNsaWVudFdpZHRoIH0pO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm1pbldpZHRoUmVsYXRpdmVUbykge1xyXG4gICAgICBjb25zdCBlbGVtOiBFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5taW5XaWR0aFJlbGF0aXZlVG8pO1xyXG4gICAgICBvdmVybGF5UmVmLnVwZGF0ZVNpemUoeyBtaW5XaWR0aDogZWxlbS5jbGllbnRXaWR0aCB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3VwZGF0ZVBvc2l0aW9uKCkge1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9vdmVybGF5UmVmIS5nZXRDb25maWcoKVxyXG4gICAgICAucG9zaXRpb25TdHJhdGVneSBhcyBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3k7XHJcbiAgICBjb25zdCBvcmlnaW4gPSB0aGlzLl9nZXRPcmlnaW4oKTtcclxuICAgIGNvbnN0IG92ZXJsYXkgPSB0aGlzLl9nZXRPdmVybGF5UG9zaXRpb24oKTtcclxuXHJcbiAgICBwb3NpdGlvbi53aXRoUG9zaXRpb25zKFtcclxuICAgICAgeyAuLi5vcmlnaW4ubWFpbiwgLi4ub3ZlcmxheS5tYWluIH0sXHJcbiAgICAgIHsgLi4ub3JpZ2luLmZhbGxiYWNrLCAuLi5vdmVybGF5LmZhbGxiYWNrIH1cclxuICAgIF0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgb3JpZ2luIHBvc2l0aW9uIGFuZCBhIGZhbGxiYWNrIHBvc2l0aW9uIGJhc2VkIG9uIHRoZSB1c2VyJ3MgcG9zaXRpb24gcHJlZmVyZW5jZS5cclxuICAgKiBUaGUgZmFsbGJhY2sgcG9zaXRpb24gaXMgdGhlIGludmVyc2Ugb2YgdGhlIG9yaWdpbiAoZS5nLiBgJ2JvdHRvbScgLT4gJ3RvcCdgKS5cclxuICAgKi9cclxuICBwcml2YXRlIF9nZXRPcmlnaW4oKToge1xyXG4gICAgbWFpbjogT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uO1xyXG4gICAgZmFsbGJhY2s6IE9yaWdpbkNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuICB9IHtcclxuICAgIGNvbnN0IHBsYWNlbWVudCA9IHRoaXMucGxhY2VtZW50O1xyXG4gICAgbGV0IG9yaWdpblBsYWNlbWVudDogT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uO1xyXG5cclxuICAgIGlmIChwbGFjZW1lbnQgPT09ICd0b3AnIHx8IHBsYWNlbWVudCA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0ge1xyXG4gICAgICAgIG9yaWdpblg6ICdzdGFydCcsXHJcbiAgICAgICAgb3JpZ2luWTogcGxhY2VtZW50ID09PSAndG9wJyA/ICd0b3AnIDogJ2JvdHRvbSdcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSBpZiAocGxhY2VtZW50ID09PSAnbGVmdCcpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0geyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdyaWdodCcpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0geyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Bvc2l0aW9uIGVycm9yJywgcGxhY2VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB7IHgsIHkgfSA9IHRoaXMuX2ludmVydFBvc2l0aW9uKFxyXG4gICAgICBvcmlnaW5QbGFjZW1lbnQub3JpZ2luWCxcclxuICAgICAgb3JpZ2luUGxhY2VtZW50Lm9yaWdpbllcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbWFpbjogb3JpZ2luUGxhY2VtZW50LFxyXG4gICAgICBmYWxsYmFjazogeyBvcmlnaW5YOiB4LCBvcmlnaW5ZOiB5IH1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKiogUmV0dXJucyB0aGUgb3ZlcmxheSBwb3NpdGlvbiBhbmQgYSBmYWxsYmFjayBwb3NpdGlvbiBiYXNlZCBvbiB0aGUgdXNlcidzIHByZWZlcmVuY2UgKi9cclxuICBwcml2YXRlIF9nZXRPdmVybGF5UG9zaXRpb24oKToge1xyXG4gICAgbWFpbjogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuICAgIGZhbGxiYWNrOiBPdmVybGF5Q29ubmVjdGlvblBvc2l0aW9uO1xyXG4gIH0ge1xyXG4gICAgY29uc3QgcGxhY2VtZW50ID0gdGhpcy5wbGFjZW1lbnQ7XHJcbiAgICBsZXQgb3ZlcmxheVBsYWNlbWVudDogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuXHJcbiAgICBpZiAocGxhY2VtZW50ID09PSAndG9wJykge1xyXG4gICAgICBvdmVybGF5UGxhY2VtZW50ID0geyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH07XHJcbiAgICB9IGVsc2UgaWYgKHBsYWNlbWVudCA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudCA9IHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAndG9wJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdsZWZ0Jykge1xyXG4gICAgICBvdmVybGF5UGxhY2VtZW50ID0geyBvdmVybGF5WDogJ2VuZCcsIG92ZXJsYXlZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdyaWdodCcpIHtcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudCA9IHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc29sZS5lcnJvcignQ291bGQgbm90IGZpbmQgYSBwb3NpdGlvbicsIHBsYWNlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgeyB4LCB5IH0gPSB0aGlzLl9pbnZlcnRQb3NpdGlvbihcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudC5vdmVybGF5WCxcclxuICAgICAgb3ZlcmxheVBsYWNlbWVudC5vdmVybGF5WVxyXG4gICAgKTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBtYWluOiBvdmVybGF5UGxhY2VtZW50LFxyXG4gICAgICBmYWxsYmFjazogeyBvdmVybGF5WDogeCwgb3ZlcmxheVk6IHkgfVxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2ludmVydFBvc2l0aW9uKFxyXG4gICAgeDogSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3MsXHJcbiAgICB5OiBWZXJ0aWNhbENvbm5lY3Rpb25Qb3NcclxuICApIHtcclxuICAgIGlmICh0aGlzLnBsYWNlbWVudCA9PT0gJ3RvcCcgfHwgdGhpcy5wbGFjZW1lbnQgPT09ICdib3R0b20nKSB7XHJcbiAgICAgIGlmICh5ID09PSAndG9wJykge1xyXG4gICAgICAgIHkgPSAnYm90dG9tJztcclxuICAgICAgfSBlbHNlIGlmICh5ID09PSAnYm90dG9tJykge1xyXG4gICAgICAgIHkgPSAndG9wJztcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHggPT09ICdlbmQnKSB7XHJcbiAgICAgICAgeCA9ICdzdGFydCc7XHJcbiAgICAgIH0gZWxzZSBpZiAoeCA9PT0gJ3N0YXJ0Jykge1xyXG4gICAgICAgIHggPSAnZW5kJztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IHgsIHkgfTtcclxuICB9XHJcblxyXG4gIC8vIENyZWF0ZSBhIGNsaXAgcGF0aCBtYXNrIGluIHRoZSBiYWNrZHJvcC4gVGhlIG1hc2sgaXMgYSByZWN0YW5nbGUsIHRoZSBzaXplIG9mIHRoZSB2aWV3Y29udGFpbmVyXHJcbiAgLy8gVGhpcyBlbmFibGVzIHRoZSB1c2VyIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbnRlbnRzIG9mIHRoZSB2aWV3Y29udGFpbmVyIHdpdGhvdXQgY2xvc2luZyB0aGUgZHJvcGRvd25cclxuICBwcml2YXRlIF9hZGRDbGlwUGF0aE1hc2tTdHlsZXMoKSB7XHJcbiAgICBjb25zdCBIVE1MRWwgPSB0aGlzLl9vdmVybGF5UmVmLmJhY2tkcm9wRWxlbWVudDtcclxuICAgIGNvbnN0IHZpZXdSZWZOYXRpdmVFbCA9IHRoaXMuX3ZpZXdDb250YWluZXJSZWYuZWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgZWxSZWN0ID0gdmlld1JlZk5hdGl2ZUVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgaWYgKGVsUmVjdCkge1xyXG4gICAgICBjb25zdCBjbGlwUGF0aFN0eWxlID0gYHBvbHlnb24oMCUgMCUsIDAlIDEwMCUsICR7ZWxSZWN0LmxlZnR9cHggMTAwJSwgJHtlbFJlY3QubGVmdH1weCAke2VsUmVjdC50b3B9cHgsICR7ZWxSZWN0LnJpZ2h0fXB4ICR7ZWxSZWN0LnRvcH1weCwgJHtlbFJlY3QucmlnaHR9cHggJHtlbFJlY3QuYm90dG9tfXB4LCAke2VsUmVjdC5sZWZ0fXB4ICR7ZWxSZWN0LmJvdHRvbX1weCwgJHtlbFJlY3QubGVmdH1weCAxMDAlLCAxMDAlIDEwMCUsIDEwMCUgMCUpYDtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShIVE1MRWwsICdjbGlwLXBhdGgnLCBjbGlwUGF0aFN0eWxlKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19