@hxui/angular
Version:
An Angular library based on the [HXUI design system](https://hxui.io).
270 lines • 34.2 kB
JavaScript
import { Directionality } from '@angular/cdk/bidi';
import { Overlay, ScrollDispatcher } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { ComponentFactoryResolver, ContentChild, Directive, ElementRef, HostBinding, HostListener, Input, NgZone, Optional, ViewContainerRef } from '@angular/core';
import { Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
import { Context } from '../enums';
import { TooltipContentComponent } from './tooltip-content.component';
import { TooltipDynamicContentDirective } from './tooltip-dynamic-content.directive';
import { TooltipConfig } from './tooltip.config';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/overlay";
import * as i2 from "./tooltip.config";
import * as i3 from "@angular/cdk/bidi";
export class TooltipDirective {
constructor(_elementRef, _viewContainerRef, overlay, _ngZone, _scrollDispatcher, _componentFactoryResolver, _config, _dir) {
this._elementRef = _elementRef;
this._viewContainerRef = _viewContainerRef;
this.overlay = overlay;
this._ngZone = _ngZone;
this._scrollDispatcher = _scrollDispatcher;
this._componentFactoryResolver = _componentFactoryResolver;
this._config = _config;
this._dir = _dir;
this._destroyed = new Subject();
this.position = 'relative';
this.placement = 'bottom';
this.showDelay = this._config.showDelay;
this.hideDelay = this._config.hideDelay;
this.context = Context.None;
this.maxWidth = 200;
this.autoClose = true;
Object.assign(this, _config);
}
show() {
this._show();
}
close() {
if (this.autoClose) {
this._hide();
}
}
/**
* Dispose the tooltip when destroyed.
*/
ngOnDestroy() {
if (this._overlayRef) {
this._overlayRef.dispose();
this._tooltipInstance = null;
}
this._destroyed.next(true);
this._destroyed.complete();
}
hide() {
this._hide();
}
_show(delay = this.showDelay) {
if (this.disabled || (!this.content && !this.dynamicContent)) {
return;
}
const overlayRef = this._createOverlay();
this._detach();
this._portal =
this._portal ||
new ComponentPortal(TooltipContentComponent, this._viewContainerRef);
this._tooltipInstance = overlayRef.attach(this._portal).instance;
this._tooltipInstance
.afterHidden()
.pipe(takeUntil(this._destroyed))
.subscribe(() => this._detach());
this._updateTooltipContent();
this._tooltipInstance.show(delay);
}
_hide(delay = this.hideDelay) {
if (this._tooltipInstance) {
this._tooltipInstance.hide(delay);
}
}
_createOverlay() {
if (this._overlayRef) {
return this._overlayRef;
}
const positionStrategy = this.overlay
.position()
.flexibleConnectedTo(this._elementRef)
.withTransformOriginOn('.hx-tooltip')
.withFlexibleDimensions(false);
this._overlayRef = this.overlay.create({
positionStrategy: positionStrategy,
panelClass: 'hxa-tooltip-panel',
scrollStrategy: this.overlay.scrollStrategies.reposition(),
hasBackdrop: !this.autoClose,
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';
}
this._updateTooltipContent();
});
return this._overlayRef;
}
_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: 'center',
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: 'center', overlayY: 'bottom' };
}
else if (placement === 'bottom') {
overlayPlacement = { overlayX: 'center', 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.position === 'top' || this.position === '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 };
}
_detach() {
if (this._overlayRef && this._overlayRef.hasAttached()) {
this._overlayRef.detach();
}
this._tooltipInstance = null;
}
/** Updates the tooltip content and repositions the overlay according to the new content length */
_updateTooltipContent() {
// Must wait for the content to be painted to the tooltip so that the overlay can properly
// calculate the correct positioning based on the size of its contents.
if (this._tooltipInstance) {
this._tooltipInstance.content = this.content;
this._tooltipInstance.placement = this.placement;
this._tooltipInstance.context = this.context;
this._tooltipInstance.maxWidth = this.maxWidth;
if (this.dynamicContent) {
this._tooltipInstance.dynamicContent = this.dynamicContent.templateRef;
}
this._ngZone.onMicrotaskEmpty
.asObservable()
.pipe(take(1), takeUntil(this._destroyed))
.subscribe(() => {
if (this._tooltipInstance) {
this._overlayRef.updatePosition();
}
});
}
}
}
TooltipDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: TooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.Overlay }, { token: i0.NgZone }, { token: i1.ScrollDispatcher }, { token: i0.ComponentFactoryResolver }, { token: i2.TooltipConfig }, { token: i3.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
TooltipDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: TooltipDirective, selector: "[hxTooltip], [hxaTooltip]", inputs: { content: ["hxTooltip", "content"], disabled: "disabled", placement: "placement", showDelay: "showDelay", hideDelay: "hideDelay", context: "context", maxWidth: "maxWidth", autoClose: "autoClose" }, host: { listeners: { "focusin": "show()", "mouseenter": "show()", "focusout": "close()", "mouseleave": "close()" }, properties: { "style.position": "this.position" } }, queries: [{ propertyName: "dynamicContent", first: true, predicate: TooltipDynamicContentDirective, descendants: true }], ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: TooltipDirective, decorators: [{
type: Directive,
args: [{
selector: '[hxTooltip], [hxaTooltip]'
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.Overlay }, { type: i0.NgZone }, { type: i1.ScrollDispatcher }, { type: i0.ComponentFactoryResolver }, { type: i2.TooltipConfig }, { type: i3.Directionality, decorators: [{
type: Optional
}] }]; }, propDecorators: { dynamicContent: [{
type: ContentChild,
args: [TooltipDynamicContentDirective]
}], position: [{
type: HostBinding,
args: ['style.position']
}], content: [{
type: Input,
args: ['hxTooltip']
}], disabled: [{
type: Input
}], placement: [{
type: Input
}], showDelay: [{
type: Input
}], hideDelay: [{
type: Input
}], context: [{
type: Input
}], maxWidth: [{
type: Input
}], autoClose: [{
type: Input
}], show: [{
type: HostListener,
args: ['focusin']
}, {
type: HostListener,
args: ['mouseenter']
}], close: [{
type: HostListener,
args: ['focusout']
}, {
type: HostListener,
args: ['mouseleave']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9oeC11aS9zcmMvbGliL3Rvb2x0aXAvdG9vbHRpcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFJTCxPQUFPLEVBR1AsZ0JBQWdCLEVBRWpCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUVOLFFBQVEsRUFDUixnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDbkMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDckYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDOzs7OztBQUtqRCxNQUFNLE9BQU8sZ0JBQWdCO0lBbUQzQixZQUNVLFdBQXVCLEVBQ3ZCLGlCQUFtQyxFQUNwQyxPQUFnQixFQUNmLE9BQWUsRUFDZixpQkFBbUMsRUFDbkMseUJBQW1ELEVBQ25ELE9BQXNCLEVBQ1YsSUFBb0I7UUFQaEMsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNw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QVE7c0JBRFAsS0FBSztnQkFJTixTQUFTO3NCQURSLEtBQUs7Z0JBSU4sU0FBUztzQkFEUixLQUFLO2dCQUlOLFNBQVM7c0JBRFIsS0FBSztnQkFJTixPQUFPO3NCQUROLEtBQUs7Z0JBSU4sUUFBUTtzQkFEUCxLQUFLO2dCQUlOLFNBQVM7c0JBRFIsS0FBSztnQkFLTixJQUFJO3NCQUZILFlBQVk7dUJBQUMsU0FBUzs7c0JBQ3RCLFlBQVk7dUJBQUMsWUFBWTtnQkFPMUIsS0FBSztzQkFGSixZQUFZO3VCQUFDLFVBQVU7O3NCQUN2QixZQUFZO3VCQUFDLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcclxuaW1wb3J0IHtcclxuICBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3ksXHJcbiAgSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3MsXHJcbiAgT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uLFxyXG4gIE92ZXJsYXksXHJcbiAgT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbixcclxuICBPdmVybGF5UmVmLFxyXG4gIFNjcm9sbERpc3BhdGNoZXIsXHJcbiAgVmVydGljYWxDb25uZWN0aW9uUG9zXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBDb21wb25lbnRQb3J0YWwgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcclxuaW1wb3J0IHtcclxuICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXHJcbiAgQ29udGVudENoaWxkLFxyXG4gIERpcmVjdGl2ZSxcclxuICBFbGVtZW50UmVmLFxyXG4gIEhvc3RCaW5kaW5nLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBJbnB1dCxcclxuICBOZ1pvbmUsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9wdGlvbmFsLFxyXG4gIFZpZXdDb250YWluZXJSZWZcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyB0YWtlLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi9lbnVtcyc7XHJcbmltcG9ydCB7IFRvb2x0aXBDb250ZW50Q29tcG9uZW50IH0gZnJvbSAnLi90b29sdGlwLWNvbnRlbnQuY29tcG9uZW50JztcclxuaW1wb3J0IHsgVG9vbHRpcER5bmFtaWNDb250ZW50RGlyZWN0aXZlIH0gZnJvbSAnLi90b29sdGlwLWR5bmFtaWMtY29udGVudC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBUb29sdGlwQ29uZmlnIH0gZnJvbSAnLi90b29sdGlwLmNvbmZpZyc7XHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICBzZWxlY3RvcjogJ1toeFRvb2x0aXBdLCBbaHhhVG9vbHRpcF0nXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUb29sdGlwRGlyZWN0aXZlIGltcGxlbWVudHMgT25EZXN0cm95IHtcclxuICBAQ29udGVudENoaWxkKFRvb2x0aXBEeW5hbWljQ29udGVudERpcmVjdGl2ZSlcclxuICBkeW5hbWljQ29udGVudDogVG9vbHRpcER5bmFtaWNDb250ZW50RGlyZWN0aXZlO1xyXG5cclxuICBfb3ZlcmxheVJlZjogT3ZlcmxheVJlZiB8IG51bGw7XHJcbiAgX3Rvb2x0aXBJbnN0YW5jZTogVG9vbHRpcENvbnRlbnRDb21wb25lbnQgfCBudWxsO1xyXG5cclxuICBwcml2YXRlIF9wb3J0YWw6IENvbXBvbmVudFBvcnRhbDxUb29sdGlwQ29udGVudENvbXBvbmVudD47XHJcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveWVkID0gbmV3IFN1YmplY3QoKTtcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS5wb3NpdGlvbicpXHJcbiAgcG9zaXRpb24gPSAncmVsYXRpdmUnO1xyXG5cclxuICBASW5wdXQoJ2h4VG9vbHRpcCcpXHJcbiAgY29udGVudDogc3RyaW5nO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIGRpc2FibGVkOiBib29sZWFuO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIHBsYWNlbWVudDogJ3RvcCcgfCAnYm90dG9tJyB8ICdsZWZ0JyB8ICdyaWdodCcgPSAnYm90dG9tJztcclxuXHJcbiAgQElucHV0KClcclxuICBzaG93RGVsYXkgPSB0aGlzLl9jb25maWcuc2hvd0RlbGF5O1xyXG5cclxuICBASW5wdXQoKVxyXG4gIGhpZGVEZWxheSA9IHRoaXMuX2NvbmZpZy5oaWRlRGVsYXk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgY29udGV4dDogQ29udGV4dCA9IENvbnRleHQuTm9uZTtcclxuXHJcbiAgQElucHV0KClcclxuICBtYXhXaWR0aCA9IDIwMDtcclxuXHJcbiAgQElucHV0KClcclxuICBhdXRvQ2xvc2UgPSB0cnVlO1xyXG5cclxuICBASG9zdExpc3RlbmVyKCdmb2N1c2luJylcclxuICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJylcclxuICBzaG93KCkge1xyXG4gICAgdGhpcy5fc2hvdygpO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignZm9jdXNvdXQnKVxyXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxyXG4gIGNsb3NlKCkge1xyXG4gICAgaWYgKHRoaXMuYXV0b0Nsb3NlKSB7XHJcbiAgICAgIHRoaXMuX2hpZGUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBfZWxlbWVudFJlZjogRWxlbWVudFJlZixcclxuICAgIHByaXZhdGUgX3ZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXHJcbiAgICBwdWJsaWMgb3ZlcmxheTogT3ZlcmxheSxcclxuICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxyXG4gICAgcHJpdmF0ZSBfc2Nyb2xsRGlzcGF0Y2hlcjogU2Nyb2xsRGlzcGF0Y2hlcixcclxuICAgIHByaXZhdGUgX2NvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxyXG4gICAgcHJpdmF0ZSBfY29uZmlnOiBUb29sdGlwQ29uZmlnLFxyXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBfZGlyOiBEaXJlY3Rpb25hbGl0eVxyXG4gICkge1xyXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBfY29uZmlnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc3Bvc2UgdGhlIHRvb2x0aXAgd2hlbiBkZXN0cm95ZWQuXHJcbiAgICovXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZikge1xyXG4gICAgICB0aGlzLl9vdmVybGF5UmVmLmRpc3Bvc2UoKTtcclxuICAgICAgdGhpcy5fdG9vbHRpcEluc3RhbmNlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kZXN0cm95ZWQubmV4dCh0cnVlKTtcclxuICAgIHRoaXMuX2Rlc3Ryb3llZC5jb21wbGV0ZSgpO1xyXG4gIH1cclxuXHJcbiAgaGlkZSgpIHtcclxuICAgIHRoaXMuX2hpZGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3Nob3coZGVsYXk6IG51bWJlciA9IHRoaXMuc2hvd0RlbGF5KSB7XHJcbiAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCAoIXRoaXMuY29udGVudCAmJiAhdGhpcy5keW5hbWljQ29udGVudCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG92ZXJsYXlSZWYgPSB0aGlzLl9jcmVhdGVPdmVybGF5KCk7XHJcblxyXG4gICAgdGhpcy5fZGV0YWNoKCk7XHJcbiAgICB0aGlzLl9wb3J0YWwgPVxyXG4gICAgICB0aGlzLl9wb3J0YWwgfHxcclxuICAgICAgbmV3IENvbXBvbmVudFBvcnRhbChUb29sdGlwQ29udGVudENvbXBvbmVudCwgdGhpcy5fdmlld0NvbnRhaW5lclJlZik7XHJcbiAgICB0aGlzLl90b29sdGlwSW5zdGFuY2UgPSBvdmVybGF5UmVmLmF0dGFjaCh0aGlzLl9wb3J0YWwpLmluc3RhbmNlO1xyXG4gICAgdGhpcy5fdG9vbHRpcEluc3RhbmNlXHJcbiAgICAgIC5hZnRlckhpZGRlbigpXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxyXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2RldGFjaCgpKTtcclxuXHJcbiAgICB0aGlzLl91cGRhdGVUb29sdGlwQ29udGVudCgpO1xyXG4gICAgdGhpcy5fdG9vbHRpcEluc3RhbmNlIS5zaG93KGRlbGF5KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hpZGUoZGVsYXk6IG51bWJlciA9IHRoaXMuaGlkZURlbGF5KSB7XHJcbiAgICBpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XHJcbiAgICAgIHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5oaWRlKGRlbGF5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NyZWF0ZU92ZXJsYXkoKTogT3ZlcmxheVJlZiB7XHJcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZikge1xyXG4gICAgICByZXR1cm4gdGhpcy5fb3ZlcmxheVJlZjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBwb3NpdGlvblN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5XHJcbiAgICAgIC5wb3NpdGlvbigpXHJcbiAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMuX2VsZW1lbnRSZWYpXHJcbiAgICAgIC53aXRoVHJhbnNmb3JtT3JpZ2luT24oJy5oeC10b29sdGlwJylcclxuICAgICAgLndpdGhGbGV4aWJsZURpbWVuc2lvbnMoZmFsc2UpO1xyXG5cclxuICAgIHRoaXMuX292ZXJsYXlSZWYgPSB0aGlzLm92ZXJsYXkuY3JlYXRlKHtcclxuICAgICAgcG9zaXRpb25TdHJhdGVneTogcG9zaXRpb25TdHJhdGVneSxcclxuICAgICAgcGFuZWxDbGFzczogJ2h4YS10b29sdGlwLXBhbmVsJyxcclxuICAgICAgc2Nyb2xsU3RyYXRlZ3k6IHRoaXMub3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLnJlcG9zaXRpb24oKSxcclxuICAgICAgaGFzQmFja2Ryb3A6ICF0aGlzLmF1dG9DbG9zZSxcclxuICAgICAgYmFja2Ryb3BDbGFzczogJ2Nkay1vdmVybGF5LXRyYW5zcGFyZW50LWJhY2tkcm9wJ1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5fdXBkYXRlUG9zaXRpb24oKTtcclxuXHJcbiAgICB0aGlzLl9vdmVybGF5UmVmXHJcbiAgICAgIC5kZXRhY2htZW50cygpXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxyXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2RldGFjaCgpKTtcclxuXHJcbiAgICB0aGlzLl9vdmVybGF5UmVmLmJhY2tkcm9wQ2xpY2soKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5faGlkZSgpKTtcclxuXHJcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuX292ZXJsYXlSZWYuZ2V0Q29uZmlnKClcclxuICAgICAgLnBvc2l0aW9uU3RyYXRlZ3kgYXMgRmxleGlibGVDb25uZWN0ZWRQb3NpdGlvblN0cmF0ZWd5O1xyXG4gICAgcG9zaXRpb24ucG9zaXRpb25DaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpLnN1YnNjcmliZShwb3MgPT4ge1xyXG4gICAgICBpZiAocG9zLmNvbm5lY3Rpb25QYWlyLm9yaWdpblggPT09ICdzdGFydCcpIHtcclxuICAgICAgICB0aGlzLnBsYWNlbWVudCA9ICdsZWZ0JztcclxuICAgICAgfSBlbHNlIGlmIChwb3MuY29ubmVjdGlvblBhaXIub3JpZ2luWCA9PT0gJ2VuZCcpIHtcclxuICAgICAgICB0aGlzLnBsYWNlbWVudCA9ICdyaWdodCc7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5fdXBkYXRlVG9vbHRpcENvbnRlbnQoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzLl9vdmVybGF5UmVmO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdXBkYXRlUG9zaXRpb24oKSB7XHJcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuX292ZXJsYXlSZWYhLmdldENvbmZpZygpXHJcbiAgICAgIC5wb3NpdGlvblN0cmF0ZWd5IGFzIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneTtcclxuICAgIGNvbnN0IG9yaWdpbiA9IHRoaXMuX2dldE9yaWdpbigpO1xyXG4gICAgY29uc3Qgb3ZlcmxheSA9IHRoaXMuX2dldE92ZXJsYXlQb3NpdGlvbigpO1xyXG5cclxuICAgIHBvc2l0aW9uLndpdGhQb3NpdGlvbnMoW1xyXG4gICAgICB7IC4uLm9yaWdpbi5tYWluLCAuLi5vdmVybGF5Lm1haW4gfSxcclxuICAgICAgeyAuLi5vcmlnaW4uZmFsbGJhY2ssIC4uLm92ZXJsYXkuZmFsbGJhY2sgfVxyXG4gICAgXSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIHRoZSBvcmlnaW4gcG9zaXRpb24gYW5kIGEgZmFsbGJhY2sgcG9zaXRpb24gYmFzZWQgb24gdGhlIHVzZXIncyBwb3NpdGlvbiBwcmVmZXJlbmNlLlxyXG4gICAqIFRoZSBmYWxsYmFjayBwb3NpdGlvbiBpcyB0aGUgaW52ZXJzZSBvZiB0aGUgb3JpZ2luIChlLmcuIGAnYm90dG9tJyAtPiAndG9wJ2ApLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgX2dldE9yaWdpbigpOiB7XHJcbiAgICBtYWluOiBPcmlnaW5Db25uZWN0aW9uUG9zaXRpb247XHJcbiAgICBmYWxsYmFjazogT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uO1xyXG4gIH0ge1xyXG4gICAgY29uc3QgcGxhY2VtZW50ID0gdGhpcy5wbGFjZW1lbnQ7XHJcbiAgICBsZXQgb3JpZ2luUGxhY2VtZW50OiBPcmlnaW5Db25uZWN0aW9uUG9zaXRpb247XHJcblxyXG4gICAgaWYgKHBsYWNlbWVudCA9PT0gJ3RvcCcgfHwgcGxhY2VtZW50ID09PSAnYm90dG9tJykge1xyXG4gICAgICBvcmlnaW5QbGFjZW1lbnQgPSB7XHJcbiAgICAgICAgb3JpZ2luWDogJ2NlbnRlcicsXHJcbiAgICAgICAgb3JpZ2luWTogcGxhY2VtZW50ID09PSAndG9wJyA/ICd0b3AnIDogJ2JvdHRvbSdcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSBpZiAocGxhY2VtZW50ID09PSAnbGVmdCcpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0geyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdyaWdodCcpIHtcclxuICAgICAgb3JpZ2luUGxhY2VtZW50ID0geyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1Bvc2l0aW9uIGVycm9yJywgcGxhY2VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB7IHgsIHkgfSA9IHRoaXMuX2ludmVydFBvc2l0aW9uKFxyXG4gICAgICBvcmlnaW5QbGFjZW1lbnQub3JpZ2luWCxcclxuICAgICAgb3JpZ2luUGxhY2VtZW50Lm9yaWdpbllcclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbWFpbjogb3JpZ2luUGxhY2VtZW50LFxyXG4gICAgICBmYWxsYmFjazogeyBvcmlnaW5YOiB4LCBvcmlnaW5ZOiB5IH1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKiogUmV0dXJucyB0aGUgb3ZlcmxheSBwb3NpdGlvbiBhbmQgYSBmYWxsYmFjayBwb3NpdGlvbiBiYXNlZCBvbiB0aGUgdXNlcidzIHByZWZlcmVuY2UgKi9cclxuICBwcml2YXRlIF9nZXRPdmVybGF5UG9zaXRpb24oKToge1xyXG4gICAgbWFpbjogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuICAgIGZhbGxiYWNrOiBPdmVybGF5Q29ubmVjdGlvblBvc2l0aW9uO1xyXG4gIH0ge1xyXG4gICAgY29uc3QgcGxhY2VtZW50ID0gdGhpcy5wbGFjZW1lbnQ7XHJcbiAgICBsZXQgb3ZlcmxheVBsYWNlbWVudDogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcclxuXHJcbiAgICBpZiAocGxhY2VtZW50ID09PSAndG9wJykge1xyXG4gICAgICBvdmVybGF5UGxhY2VtZW50ID0geyBvdmVybGF5WDogJ2NlbnRlcicsIG92ZXJsYXlZOiAnYm90dG9tJyB9O1xyXG4gICAgfSBlbHNlIGlmIChwbGFjZW1lbnQgPT09ICdib3R0b20nKSB7XHJcbiAgICAgIG92ZXJsYXlQbGFjZW1lbnQgPSB7IG92ZXJsYXlYOiAnY2VudGVyJywgb3ZlcmxheVk6ICd0b3AnIH07XHJcbiAgICB9IGVsc2UgaWYgKHBsYWNlbWVudCA9PT0gJ2xlZnQnKSB7XHJcbiAgICAgIG92ZXJsYXlQbGFjZW1lbnQgPSB7IG92ZXJsYXlYOiAnZW5kJywgb3ZlcmxheVk6ICdjZW50ZXInIH07XHJcbiAgICB9IGVsc2UgaWYgKHBsYWNlbWVudCA9PT0gJ3JpZ2h0Jykge1xyXG4gICAgICBvdmVybGF5UGxhY2VtZW50ID0geyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdjZW50ZXInIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdDb3VsZCBub3QgZmluZCBhIHBvc2l0aW9uJywgcGxhY2VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB7IHgsIHkgfSA9IHRoaXMuX2ludmVydFBvc2l0aW9uKFxyXG4gICAgICBvdmVybGF5UGxhY2VtZW50Lm92ZXJsYXlYLFxyXG4gICAgICBvdmVybGF5UGxhY2VtZW50Lm92ZXJsYXlZXHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIG1haW46IG92ZXJsYXlQbGFjZW1lbnQsXHJcbiAgICAgIGZhbGxiYWNrOiB7IG92ZXJsYXlYOiB4LCBvdmVybGF5WTogeSB9XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW52ZXJ0UG9zaXRpb24oXHJcbiAgICB4OiBIb3Jpem9udGFsQ29ubmVjdGlvblBvcyxcclxuICAgIHk6IFZlcnRpY2FsQ29ubmVjdGlvblBvc1xyXG4gICkge1xyXG4gICAgaWYgKHRoaXMucG9zaXRpb24gPT09ICd0b3AnIHx8IHRoaXMucG9zaXRpb24gPT09ICdib3R0b20nKSB7XHJcbiAgICAgIGlmICh5ID09PSAndG9wJykge1xyXG4gICAgICAgIHkgPSAnYm90dG9tJztcclxuICAgICAgfSBlbHNlIGlmICh5ID09PSAnYm90dG9tJykge1xyXG4gICAgICAgIHkgPSAndG9wJztcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHggPT09ICdlbmQnKSB7XHJcbiAgICAgICAgeCA9ICdzdGFydCc7XHJcbiAgICAgIH0gZWxzZSBpZiAoeCA9PT0gJ3N0YXJ0Jykge1xyXG4gICAgICAgIHggPSAnZW5kJztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IHgsIHkgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2RldGFjaCgpIHtcclxuICAgIGlmICh0aGlzLl9vdmVybGF5UmVmICYmIHRoaXMuX292ZXJsYXlSZWYuaGFzQXR0YWNoZWQoKSkge1xyXG4gICAgICB0aGlzLl9vdmVybGF5UmVmLmRldGFjaCgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fdG9vbHRpcEluc3RhbmNlID0gbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKiBVcGRhdGVzIHRoZSB0b29sdGlwIGNvbnRlbnQgYW5kIHJlcG9zaXRpb25zIHRoZSBvdmVybGF5IGFjY29yZGluZyB0byB0aGUgbmV3IGNvbnRlbnQgbGVuZ3RoICovXHJcbiAgcHJpdmF0ZSBfdXBkYXRlVG9vbHRpcENvbnRlbnQoKSB7XHJcbiAgICAvLyBNdXN0IHdhaXQgZm9yIHRoZSBjb250ZW50IHRvIGJlIHBhaW50ZWQgdG8gdGhlIHRvb2x0aXAgc28gdGhhdCB0aGUgb3ZlcmxheSBjYW4gcHJvcGVybHlcclxuICAgIC8vIGNhbGN1bGF0ZSB0aGUgY29ycmVjdCBwb3NpdGlvbmluZyBiYXNlZCBvbiB0aGUgc2l6ZSBvZiBpdHMgY29udGVudHMuXHJcbiAgICBpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XHJcbiAgICAgIHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5jb250ZW50ID0gdGhpcy5jb250ZW50O1xyXG4gICAgICB0aGlzLl90b29sdGlwSW5zdGFuY2UucGxhY2VtZW50ID0gdGhpcy5wbGFjZW1lbnQ7XHJcbiAgICAgIHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5jb250ZXh0ID0gdGhpcy5jb250ZXh0O1xyXG4gICAgICB0aGlzLl90b29sdGlwSW5zdGFuY2UubWF4V2lkdGggPSB0aGlzLm1heFdpZHRoO1xyXG4gICAgICBpZiAodGhpcy5keW5hbWljQ29udGVudCkge1xyXG4gICAgICAgIHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5keW5hbWljQ29udGVudCA9IHRoaXMuZHluYW1pY0NvbnRlbnQudGVtcGxhdGVSZWY7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuX25nWm9uZS5vbk1pY3JvdGFza0VtcHR5XHJcbiAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXHJcbiAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXHJcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICBpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX292ZXJsYXlSZWYhLnVwZGF0ZVBvc2l0aW9uKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiJdfQ==