carbon-components-angular
Version:
Next generation components
282 lines • 34.8 kB
JavaScript
import { Directive, EventEmitter, HostBinding, Input, Output } from "@angular/core";
import { arrow, autoUpdate, computePosition, flip, offset } from "@floating-ui/dom";
import * as i0 from "@angular/core";
export class PopoverContainer {
constructor(elementRef, ngZone, renderer, changeDetectorRef) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.renderer = renderer;
this.changeDetectorRef = changeDetectorRef;
this._align = "bottom";
this.alignmentClassPrefix = "cds--popover--";
/**
* Emits an event when the dialog is closed
*/
this.onClose = new EventEmitter();
/**
* Emits an event when the dialog is opened
*/
this.onOpen = new EventEmitter();
/**
* Emits an event when the state of `isOpen` changes. Allows `isOpen` to be double bound
*/
this.isOpenChange = new EventEmitter();
/**
* Show caret at the alignment position
*/
this.caret = true;
/**
* Enable drop shadow around the popover container
*/
this.dropShadow = true;
/**
* Enable high contrast for popover container
*/
this.highContrast = false;
/**
* **Experimental**: Use floating-ui to position the tooltip
* This is not toggleable - should be assigned once
*/
this.autoAlign = false;
this.containerClass = true;
this.isOpen = false;
}
/**
* Set alignment of popover
* As of v5, `oldPlacements` are now deprecated in favor of Placements
*
* When `autoAlign` is set to `true`, alignment may change for best placement
*/
set align(alignment) {
// If alignment is not passed, the default value will be `undefined`.
if (!alignment) {
return;
}
const previousAlignment = this._align;
switch (alignment) {
case "top-left":
this._align = "top-start";
break;
case "top-right":
this._align = "top-end";
break;
case "bottom-left":
this._align = "bottom-start";
break;
case "bottom-right":
this._align = "bottom-end";
break;
case "left-top":
this._align = "left-start";
break;
case "left-bottom":
this._align = "left-end";
break;
case "right-top":
this._align = "right-start";
break;
case "right-bottom":
this._align = "right-end";
break;
default:
this._align = alignment;
break;
}
this.updateAlignmentClass(this._align, previousAlignment);
}
/**
* Handles emitting open/close event
* @param open - Is the popover container open
* @param event - Event
*/
handleChange(open, event) {
// We only emit the event when parameter has an event to keep existing behavior
if ((this.isOpen !== open) && event) {
this.isOpenChange.emit(open);
}
if (open) {
if (event) {
this.onOpen.emit(event);
}
// when auto alignment is enabled, use auto update to set the placement for the element
if (this.autoAlign) {
if (this.caretRef) {
// Get caret offset/height property
// Getting computed styles once every open, otherwise expensive.
const computedStyle = getComputedStyle(this.caretRef);
const offset = computedStyle.getPropertyValue("--cds-popover-offset");
const height = computedStyle.getPropertyValue("--cds-popover-caret-height");
this.caretOffset = (offset?.includes("px") ? Number(offset.split("px", 1)[0]) : Number(offset.split("rem", 1)[0]) * 16) || 10;
this.caretHeight = (height?.includes("px") ? Number(height.split("px", 1)[0]) : Number(height.split("rem", 1)[0]) * 16) || 6;
}
if (this.elementRef.nativeElement && this.popoverContentRef) {
this.unmountFloatingElement = autoUpdate(this.elementRef.nativeElement, this.popoverContentRef, this.recomputePosition.bind(this));
}
}
}
else {
this.cleanUp();
if (event) {
this.onClose.emit(event);
}
}
this.isOpen = open;
this.changeDetectorRef.markForCheck();
}
roundByDPR(value) {
const dpr = window.devicePixelRatio || 1;
return Math.round(value * dpr) / dpr;
}
/**
* Compute position of tooltip when autoAlign is enabled
*/
recomputePosition() {
// Run outside of angular zone to avoid unnecessary change detection and rely on floating-ui
this.ngZone.runOutsideAngular(async () => {
const { x, y, placement, middlewareData } = await computePosition(this.elementRef.nativeElement, this.popoverContentRef, {
placement: this._align,
strategy: "fixed",
middleware: [
offset(this.caretOffset),
flip({ fallbackAxisSideDirection: "start" }),
arrow({ element: this.caretRef })
]
});
const previousAlignment = this._align;
this._align = placement;
this.updateAlignmentClass(this._align, previousAlignment);
// Using CSSOM to manipulate CSS to avoid content security policy inline-src
// https://github.com/w3c/webappsec-csp/issues/212
Object.assign(this.popoverContentRef.style, {
position: "fixed",
top: "0",
left: "0",
// Using transform instead of top/left position to improve performance
transform: `translate(${this.roundByDPR(x)}px,${this.roundByDPR(y)}px)`
});
if (middlewareData.arrow) {
const { x: arrowX, y: arrowY } = middlewareData.arrow;
const staticSide = {
top: "bottom",
right: "left",
bottom: "top",
left: "right"
}[placement.split("-")[0]];
this.caretRef.style.left = arrowX != null ? `${arrowX}px` : "";
this.caretRef.style.top = arrowY != null ? `${arrowY}px` : "";
this.caretRef.style.right = "";
this.caretRef.style.bottom = "";
if (staticSide) {
this.caretRef.style[staticSide] = `${-this.caretHeight}px`;
}
}
});
}
/**
* Close the popover and reopen it with updated values without emitting an event
* @param changes
*/
ngOnChanges(changes) {
// Close and reopen the popover, handle alignment/programmatic open/close
const originalState = this.isOpen;
this.handleChange(false);
// Ignore first change since content is not initialized
if (changes.autoAlign && !changes.autoAlign.firstChange) {
// Reset the inline styles
this.popoverContentRef = this.elementRef.nativeElement.querySelector(".cds--popover-content");
this.popoverContentRef.setAttribute("style", "");
this.caretRef = this.elementRef.nativeElement.querySelector("span.cds--popover-caret");
}
this.handleChange(originalState);
}
/**
* Handle initialization of element
*/
ngAfterViewInit() {
this.initializeReferences();
}
initializeReferences() {
this.updateAlignmentClass(this._align);
// Initialize html references since they will not change and are required for popover components
this.popoverContentRef = this.elementRef.nativeElement.querySelector(".cds--popover-content");
this.caretRef = this.elementRef.nativeElement.querySelector("span.cds--popover-caret");
// Handle initial isOpen
this.handleChange(this.isOpen);
}
/**
* Clean up
*/
ngOnDestroy() {
this.cleanUp();
}
/**
* Clean up `autoUpdate` if auto alignment is enabled
*/
cleanUp() {
if (this.unmountFloatingElement) {
this.unmountFloatingElement();
}
this.unmountFloatingElement = undefined;
}
/**
* Replace existing previous alignment class with new
* @param previousAlignment
*/
updateAlignmentClass(newAlignment, previousAlignment) {
if (this.elementRef.nativeElement && previousAlignment !== newAlignment) {
const regexp = new RegExp("right|top|left|bottom");
// Since we are constantly switching, it's safer to delete all matching class names
this.elementRef.nativeElement.classList.forEach(className => {
if (regexp.test(className)) {
this.renderer.removeClass(this.elementRef.nativeElement, `${className}`);
}
});
this.renderer.addClass(this.elementRef.nativeElement, `${this.alignmentClassPrefix}${newAlignment}`);
}
}
}
PopoverContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PopoverContainer, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
PopoverContainer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: PopoverContainer, selector: "[cdsPopover], [ibmPopover]", inputs: { align: "align", caret: "caret", dropShadow: "dropShadow", highContrast: "highContrast", autoAlign: "autoAlign", isOpen: "isOpen" }, outputs: { onClose: "onClose", onOpen: "onOpen", isOpenChange: "isOpenChange" }, host: { properties: { "class.cds--popover--caret": "this.caret", "class.cds--popover--drop-shadow": "this.dropShadow", "class.cds--popover--high-contrast": "this.highContrast", "class.cds--popover--auto-align": "this.autoAlign", "class.cds--popover-container": "this.containerClass", "class.cds--popover--open": "this.isOpen" } }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PopoverContainer, decorators: [{
type: Directive,
args: [{
selector: "[cdsPopover], [ibmPopover]"
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { align: [{
type: Input
}], onClose: [{
type: Output
}], onOpen: [{
type: Output
}], isOpenChange: [{
type: Output
}], caret: [{
type: HostBinding,
args: ["class.cds--popover--caret"]
}, {
type: Input
}], dropShadow: [{
type: HostBinding,
args: ["class.cds--popover--drop-shadow"]
}, {
type: Input
}], highContrast: [{
type: HostBinding,
args: ["class.cds--popover--high-contrast"]
}, {
type: Input
}], autoAlign: [{
type: HostBinding,
args: ["class.cds--popover--auto-align"]
}, {
type: Input
}], containerClass: [{
type: HostBinding,
args: ["class.cds--popover-container"]
}], isOpen: [{
type: Input
}, {
type: HostBinding,
args: ["class.cds--popover--open"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wb3Zlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcG9wb3Zlci9wb3BvdmVyLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR04sU0FBUyxFQUVULFlBQVksRUFDWixXQUFXLEVBQ1gsS0FBSyxFQUlMLE1BQU0sRUFHTixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ04sS0FBSyxFQUNMLFVBQVUsRUFDVixlQUFlLEVBQ2YsSUFBSSxFQUNKLE1BQU0sRUFFTixNQUFNLGtCQUFrQixDQUFDOztBQWUxQixNQUFNLE9BQU8sZ0JBQWdCO0lBdUY1QixZQUNXLFVBQXNCLEVBQ3RCLE1BQWMsRUFDZCxRQUFtQixFQUNuQixpQkFBb0M7UUFIcEMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBN0MvQyxXQUFNLEdBQWMsUUFBUSxDQUFDO1FBQ3BCLHlCQUFvQixHQUFHLGdCQUFnQixDQUFDO1FBRWpEOztXQUVHO1FBQ08sWUFBTyxHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzVEOztXQUVHO1FBQ08sV0FBTSxHQUF3QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzNEOztXQUVHO1FBQ08saUJBQVksR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBQ3JEOztXQUVHO1FBQ2dELFVBQUssR0FBRyxJQUFJLENBQUM7UUFDaEU7O1dBRUc7UUFDc0QsZUFBVSxHQUFHLElBQUksQ0FBQztRQUMzRTs7V0FFRztRQUN3RCxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNoRjs7O1dBR0c7UUFDcUQsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUM3QixtQkFBYyxHQUFHLElBQUksQ0FBQztRQUNqQixXQUFNLEdBQUcsS0FBSyxDQUFDO0lBYTlE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RixJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFO2dCQUMzRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUU7b0JBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLEdBQUcsU0FBUyxFQUFFLENBQUMsQ0FBQztpQkFDekU7WUFDRixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFlBQVksRUFBRSxDQUFDLENBQUM7U0FDckc7SUFDRixDQUFDOzs2R0E3UVcsZ0JBQWdCO2lHQUFoQixnQkFBZ0I7MkZBQWhCLGdCQUFnQjtrQkFINUIsU0FBUzttQkFBQztvQkFDVixRQUFRLEVBQUUsNEJBQTRCO2lCQUN0Qzs4S0FRYSxLQUFLO3NCQUFqQixLQUFLO2dCQTZDSSxPQUFPO3NCQUFoQixNQUFNO2dCQUlHLE1BQU07c0JBQWYsTUFBTTtnQkFJRyxZQUFZO3NCQUFyQixNQUFNO2dCQUk0QyxLQUFLO3NCQUF2RCxXQUFXO3VCQUFDLDJCQUEyQjs7c0JBQUcsS0FBSztnQkFJUyxVQUFVO3NCQUFsRSxXQUFXO3VCQUFDLGlDQUFpQzs7c0JBQUcsS0FBSztnQkFJSyxZQUFZO3NCQUF0RSxXQUFXO3VCQUFDLG1DQUFtQzs7c0JBQUcsS0FBSztnQkFLQSxTQUFTO3NCQUFoRSxXQUFXO3VCQUFDLGdDQUFnQzs7c0JBQUcsS0FBSztnQkFDUixjQUFjO3NCQUExRCxXQUFXO3VCQUFDLDhCQUE4QjtnQkFDTyxNQUFNO3NCQUF2RCxLQUFLOztzQkFBSSxXQUFXO3VCQUFDLDBCQUEwQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdEFmdGVyVmlld0luaXQsXG5cdENoYW5nZURldGVjdG9yUmVmLFxuXHREaXJlY3RpdmUsXG5cdEVsZW1lbnRSZWYsXG5cdEV2ZW50RW1pdHRlcixcblx0SG9zdEJpbmRpbmcsXG5cdElucHV0LFxuXHROZ1pvbmUsXG5cdE9uQ2hhbmdlcyxcblx0T25EZXN0cm95LFxuXHRPdXRwdXQsXG5cdFJlbmRlcmVyMixcblx0U2ltcGxlQ2hhbmdlc1xufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcblx0YXJyb3csXG5cdGF1dG9VcGRhdGUsXG5cdGNvbXB1dGVQb3NpdGlvbixcblx0ZmxpcCxcblx0b2Zmc2V0LFxuXHRQbGFjZW1lbnRcbn0gZnJvbSBcIkBmbG9hdGluZy11aS9kb21cIjtcblxuLy8gRGVwcmVjYXRlZCBwb3BvdmVyIGFsaWdubWVudHNcbnR5cGUgb2xkUGxhY2VtZW50ID0gXCJ0b3AtbGVmdFwiXG5cdHwgXCJ0b3AtcmlnaHRcIlxuXHR8IFwiYm90dG9tLWxlZnRcIlxuXHR8IFwiYm90dG9tLXJpZ2h0XCJcblx0fCBcImxlZnQtYm90dG9tXCJcblx0fCBcImxlZnQtdG9wXCJcblx0fCBcInJpZ2h0LWJvdHRvbVwiXG5cdHwgXCJyaWdodC10b3BcIjtcblxuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiBcIltjZHNQb3BvdmVyXSwgW2libVBvcG92ZXJdXCJcbn0pXG5leHBvcnQgY2xhc3MgUG9wb3ZlckNvbnRhaW5lciBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblx0LyoqXG5cdCAqIFNldCBhbGlnbm1lbnQgb2YgcG9wb3ZlclxuXHQgKiBBcyBvZiB2NSwgYG9sZFBsYWNlbWVudHNgIGFyZSBub3cgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBQbGFjZW1lbnRzXG5cdCAqXG5cdCAqIFdoZW4gYGF1dG9BbGlnbmAgaXMgc2V0IHRvIGB0cnVlYCwgYWxpZ25tZW50IG1heSBjaGFuZ2UgZm9yIGJlc3QgcGxhY2VtZW50XG5cdCAqL1xuXHRASW5wdXQoKSBzZXQgYWxpZ24oYWxpZ25tZW50OiBvbGRQbGFjZW1lbnQgfCBQbGFjZW1lbnQpIHtcblx0XHQvLyBJZiBhbGlnbm1lbnQgaXMgbm90IHBhc3NlZCwgdGhlIGRlZmF1bHQgdmFsdWUgd2lsbCBiZSBgdW5kZWZpbmVkYC5cblx0XHRpZiAoIWFsaWdubWVudCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHByZXZpb3VzQWxpZ25tZW50ID0gdGhpcy5fYWxpZ247XG5cdFx0c3dpdGNoIChhbGlnbm1lbnQpIHtcblx0XHRcdGNhc2UgXCJ0b3AtbGVmdFwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwidG9wLXN0YXJ0XCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcInRvcC1yaWdodFwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwidG9wLWVuZFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJib3R0b20tbGVmdFwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwiYm90dG9tLXN0YXJ0XCI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcImJvdHRvbS1yaWdodFwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwiYm90dG9tLWVuZFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJsZWZ0LXRvcFwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwibGVmdC1zdGFydFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJsZWZ0LWJvdHRvbVwiOlxuXHRcdFx0XHR0aGlzLl9hbGlnbiA9IFwibGVmdC1lbmRcIjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwicmlnaHQtdG9wXCI6XG5cdFx0XHRcdHRoaXMuX2FsaWduID0gXCJyaWdodC1zdGFydFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJyaWdodC1ib3R0b21cIjpcblx0XHRcdFx0dGhpcy5fYWxpZ24gPSBcInJpZ2h0LWVuZFwiO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdHRoaXMuX2FsaWduID0gYWxpZ25tZW50IGFzIFBsYWNlbWVudDtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdHRoaXMudXBkYXRlQWxpZ25tZW50Q2xhc3ModGhpcy5fYWxpZ24sIHByZXZpb3VzQWxpZ25tZW50KTtcblx0fVxuXG5cdF9hbGlnbjogUGxhY2VtZW50ID0gXCJib3R0b21cIjtcblx0cmVhZG9ubHkgYWxpZ25tZW50Q2xhc3NQcmVmaXggPSBcImNkcy0tcG9wb3Zlci0tXCI7XG5cblx0LyoqXG5cdCAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIGRpYWxvZyBpcyBjbG9zZWRcblx0ICovXG5cdEBPdXRwdXQoKSBvbkNsb3NlOiBFdmVudEVtaXR0ZXI8RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHQvKipcblx0ICogRW1pdHMgYW4gZXZlbnQgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZFxuXHQgKi9cblx0QE91dHB1dCgpIG9uT3BlbjogRXZlbnRFbWl0dGVyPEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblx0LyoqXG5cdCAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIHN0YXRlIG9mIGBpc09wZW5gIGNoYW5nZXMuIEFsbG93cyBgaXNPcGVuYCB0byBiZSBkb3VibGUgYm91bmRcblx0ICovXG5cdEBPdXRwdXQoKSBpc09wZW5DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cdC8qKlxuXHQgKiBTaG93IGNhcmV0IGF0IHRoZSBhbGlnbm1lbnQgcG9zaXRpb25cblx0ICovXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tcG9wb3Zlci0tY2FyZXRcIikgQElucHV0KCkgY2FyZXQgPSB0cnVlO1xuXHQvKipcblx0ICogRW5hYmxlIGRyb3Agc2hhZG93IGFyb3VuZCB0aGUgcG9wb3ZlciBjb250YWluZXJcblx0ICovXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tcG9wb3Zlci0tZHJvcC1zaGFkb3dcIikgQElucHV0KCkgZHJvcFNoYWRvdyA9IHRydWU7XG5cdC8qKlxuXHQgKiBFbmFibGUgaGlnaCBjb250cmFzdCBmb3IgcG9wb3ZlciBjb250YWluZXJcblx0ICovXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tcG9wb3Zlci0taGlnaC1jb250cmFzdFwiKSBASW5wdXQoKSBoaWdoQ29udHJhc3QgPSBmYWxzZTtcblx0LyoqXG5cdCAqICoqRXhwZXJpbWVudGFsKio6IFVzZSBmbG9hdGluZy11aSB0byBwb3NpdGlvbiB0aGUgdG9vbHRpcFxuXHQgKiBUaGlzIGlzIG5vdCB0b2dnbGVhYmxlIC0gc2hvdWxkIGJlIGFzc2lnbmVkIG9uY2Vcblx0ICovXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tcG9wb3Zlci0tYXV0by1hbGlnblwiKSBASW5wdXQoKSBhdXRvQWxpZ24gPSBmYWxzZTtcblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS1wb3BvdmVyLWNvbnRhaW5lclwiKSBjb250YWluZXJDbGFzcyA9IHRydWU7XG5cdEBJbnB1dCgpIEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tcG9wb3Zlci0tb3BlblwiKSBpc09wZW4gPSBmYWxzZTtcblxuXHRwcm90ZWN0ZWQgcG9wb3ZlckNvbnRlbnRSZWY6IEhUTUxFbGVtZW50O1xuXHRwcm90ZWN0ZWQgY2FyZXRSZWY6IEhUTUxFbGVtZW50O1xuXHRwcm90ZWN0ZWQgY2FyZXRPZmZzZXQ6IG51bWJlcjtcblx0cHJvdGVjdGVkIGNhcmV0SGVpZ2h0OiBudW1iZXI7XG5cdHByb3RlY3RlZCB1bm1vdW50RmxvYXRpbmdFbGVtZW50OiBGdW5jdGlvbjtcblxuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZixcblx0XHRwcm90ZWN0ZWQgbmdab25lOiBOZ1pvbmUsXG5cdFx0cHJvdGVjdGVkIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG5cdFx0cHJvdGVjdGVkIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZlxuXHQpIHt9XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgZW1pdHRpbmcgb3Blbi9jbG9zZSBldmVudFxuXHQgKiBAcGFyYW0gb3BlbiAtIElzIHRoZSBwb3BvdmVyIGNvbnRhaW5lciBvcGVuXG5cdCAqIEBwYXJhbSBldmVudCAtIEV2ZW50XG5cdCAqL1xuXHRoYW5kbGVDaGFuZ2Uob3BlbjogYm9vbGVhbiwgZXZlbnQ/OiBFdmVudCkge1xuXHRcdC8vIFdlIG9ubHkgZW1pdCB0aGUgZXZlbnQgd2hlbiBwYXJhbWV0ZXIgaGFzIGFuIGV2ZW50IHRvIGtlZXAgZXhpc3RpbmcgYmVoYXZpb3Jcblx0XHRpZiAoKHRoaXMuaXNPcGVuICE9PSBvcGVuKSAmJiBldmVudCkge1xuXHRcdFx0dGhpcy5pc09wZW5DaGFuZ2UuZW1pdChvcGVuKTtcblx0XHR9XG5cblx0XHRpZiAob3Blbikge1xuXHRcdFx0aWYgKGV2ZW50KSB7XG5cdFx0XHRcdHRoaXMub25PcGVuLmVtaXQoZXZlbnQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyB3aGVuIGF1dG8gYWxpZ25tZW50IGlzIGVuYWJsZWQsIHVzZSBhdXRvIHVwZGF0ZSB0byBzZXQgdGhlIHBsYWNlbWVudCBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICh0aGlzLmF1dG9BbGlnbikge1xuXHRcdFx0XHRpZiAodGhpcy5jYXJldFJlZikge1xuXHRcdFx0XHRcdC8vIEdldCBjYXJldCBvZmZzZXQvaGVpZ2h0IHByb3BlcnR5XG5cdFx0XHRcdFx0Ly8gR2V0dGluZyBjb21wdXRlZCBzdHlsZXMgb25jZSBldmVyeSBvcGVuLCBvdGhlcndpc2UgZXhwZW5zaXZlLlxuXHRcdFx0XHRcdGNvbnN0IGNvbXB1dGVkU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMuY2FyZXRSZWYpO1xuXHRcdFx0XHRcdGNvbnN0IG9mZnNldCA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY2RzLXBvcG92ZXItb2Zmc2V0XCIpO1xuXHRcdFx0XHRcdGNvbnN0IGhlaWdodCA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY2RzLXBvcG92ZXItY2FyZXQtaGVpZ2h0XCIpO1xuXHRcdFx0XHRcdHRoaXMuY2FyZXRPZmZzZXQgPSAob2Zmc2V0Py5pbmNsdWRlcyhcInB4XCIpID8gTnVtYmVyKG9mZnNldC5zcGxpdChcInB4XCIsIDEpWzBdKSA6IE51bWJlcihvZmZzZXQuc3BsaXQoXCJyZW1cIiwgMSlbMF0pICogMTYpIHx8IDEwO1xuXHRcdFx0XHRcdHRoaXMuY2FyZXRIZWlnaHQgPSAoaGVpZ2h0Py5pbmNsdWRlcyhcInB4XCIpID8gTnVtYmVyKGhlaWdodC5zcGxpdChcInB4XCIsIDEpWzBdKSA6IE51bWJlcihoZWlnaHQuc3BsaXQoXCJyZW1cIiwgMSlbMF0pICogMTYpIHx8IDY7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50ICYmIHRoaXMucG9wb3ZlckNvbnRlbnRSZWYpIHtcblx0XHRcdFx0XHR0aGlzLnVubW91bnRGbG9hdGluZ0VsZW1lbnQgPSBhdXRvVXBkYXRlKFxuXHRcdFx0XHRcdFx0dGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG5cdFx0XHRcdFx0XHR0aGlzLnBvcG92ZXJDb250ZW50UmVmLFxuXHRcdFx0XHRcdFx0dGhpcy5yZWNvbXB1dGVQb3NpdGlvbi5iaW5kKHRoaXMpXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmNsZWFuVXAoKTtcblx0XHRcdGlmIChldmVudCkge1xuXHRcdFx0XHR0aGlzLm9uQ2xvc2UuZW1pdChldmVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuaXNPcGVuID0gb3Blbjtcblx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuXHR9XG5cblx0cm91bmRCeURQUih2YWx1ZSkge1xuXHRcdGNvbnN0IGRwciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7XG5cdFx0cmV0dXJuIE1hdGgucm91bmQodmFsdWUgKiBkcHIpIC8gZHByO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbXB1dGUgcG9zaXRpb24gb2YgdG9vbHRpcCB3aGVuIGF1dG9BbGlnbiBpcyBlbmFibGVkXG5cdCAqL1xuXHRyZWNvbXB1dGVQb3NpdGlvbigpIHtcblx0XHQvLyBSdW4gb3V0c2lkZSBvZiBhbmd1bGFyIHpvbmUgdG8gYXZvaWQgdW5uZWNlc3NhcnkgY2hhbmdlIGRldGVjdGlvbiBhbmQgcmVseSBvbiBmbG9hdGluZy11aVxuXHRcdHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKGFzeW5jICgpID0+IHtcblx0XHRcdGNvbnN0IHsgeCwgeSwgcGxhY2VtZW50LCBtaWRkbGV3YXJlRGF0YSB9ID0gYXdhaXQgY29tcHV0ZVBvc2l0aW9uKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcblx0XHRcdFx0dGhpcy5wb3BvdmVyQ29udGVudFJlZixcblx0XHRcdFx0e1xuXHRcdFx0XHRcdHBsYWNlbWVudDogdGhpcy5fYWxpZ24sXG5cdFx0XHRcdFx0c3RyYXRlZ3k6IFwiZml4ZWRcIixcblx0XHRcdFx0XHRtaWRkbGV3YXJlOiBbXG5cdFx0XHRcdFx0XHRvZmZzZXQodGhpcy5jYXJldE9mZnNldCksXG5cdFx0XHRcdFx0XHRmbGlwKHsgZmFsbGJhY2tBeGlzU2lkZURpcmVjdGlvbjogXCJzdGFydFwiIH0pLFxuXHRcdFx0XHRcdFx0YXJyb3coeyBlbGVtZW50OiB0aGlzLmNhcmV0UmVmIH0pXG5cdFx0XHRcdFx0XVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0Y29uc3QgcHJldmlvdXNBbGlnbm1lbnQgPSB0aGlzLl9hbGlnbjtcblx0XHRcdHRoaXMuX2FsaWduID0gcGxhY2VtZW50O1xuXHRcdFx0dGhpcy51cGRhdGVBbGlnbm1lbnRDbGFzcyh0aGlzLl9hbGlnbiwgcHJldmlvdXNBbGlnbm1lbnQpO1xuXG5cdFx0XHQvLyBVc2luZyBDU1NPTSB0byBtYW5pcHVsYXRlIENTUyB0byBhdm9pZCBjb250ZW50IHNlY3VyaXR5IHBvbGljeSBpbmxpbmUtc3JjXG5cdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vdzNjL3dlYmFwcHNlYy1jc3AvaXNzdWVzLzIxMlxuXHRcdFx0T2JqZWN0LmFzc2lnbih0aGlzLnBvcG92ZXJDb250ZW50UmVmLnN0eWxlLCB7XG5cdFx0XHRcdHBvc2l0aW9uOiBcImZpeGVkXCIsXG5cdFx0XHRcdHRvcDogXCIwXCIsXG5cdFx0XHRcdGxlZnQ6IFwiMFwiLFxuXHRcdFx0XHQvLyBVc2luZyB0cmFuc2Zvcm0gaW5zdGVhZCBvZiB0b3AvbGVmdCBwb3NpdGlvbiB0byBpbXByb3ZlIHBlcmZvcm1hbmNlXG5cdFx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgke3RoaXMucm91bmRCeURQUih4KX1weCwke3RoaXMucm91bmRCeURQUih5KX1weClgXG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKG1pZGRsZXdhcmVEYXRhLmFycm93KSB7XG5cdFx0XHRcdGNvbnN0IHsgeDogYXJyb3dYLCB5OiBhcnJvd1kgfSA9IG1pZGRsZXdhcmVEYXRhLmFycm93O1xuXG5cdFx0XHRcdGNvbnN0IHN0YXRpY1NpZGUgPSB7XG5cdFx0XHRcdFx0dG9wOiBcImJvdHRvbVwiLFxuXHRcdFx0XHRcdHJpZ2h0OiBcImxlZnRcIixcblx0XHRcdFx0XHRib3R0b206IFwidG9wXCIsXG5cdFx0XHRcdFx0bGVmdDogXCJyaWdodFwiXG5cdFx0XHRcdH1bcGxhY2VtZW50LnNwbGl0KFwiLVwiKVswXV07XG5cblx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZS5sZWZ0ID0gYXJyb3dYICE9IG51bGwgPyBgJHthcnJvd1h9cHhgIDogXCJcIjtcblx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZS50b3AgPSBhcnJvd1kgIT0gbnVsbCA/IGAke2Fycm93WX1weGAgOiBcIlwiO1xuXHRcdFx0XHR0aGlzLmNhcmV0UmVmLnN0eWxlLnJpZ2h0ID0gXCJcIjtcblx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZS5ib3R0b20gPSBcIlwiO1xuXG5cdFx0XHRcdGlmIChzdGF0aWNTaWRlKSB7XG5cdFx0XHRcdFx0dGhpcy5jYXJldFJlZi5zdHlsZVtzdGF0aWNTaWRlXSA9IGAkey10aGlzLmNhcmV0SGVpZ2h0fXB4YDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsb3NlIHRoZSBwb3BvdmVyIGFuZCByZW9wZW4gaXQgd2l0aCB1cGRhdGVkIHZhbHVlcyB3aXRob3V0IGVtaXR0aW5nIGFuIGV2ZW50XG5cdCAqIEBwYXJhbSBjaGFuZ2VzXG5cdCAqL1xuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG5cdFx0Ly8gQ2xvc2UgYW5kIHJlb3BlbiB0aGUgcG9wb3ZlciwgaGFuZGxlIGFsaWdubWVudC9wcm9ncmFtbWF0aWMgb3Blbi9jbG9zZVxuXHRcdGNvbnN0IG9yaWdpbmFsU3RhdGUgPSB0aGlzLmlzT3Blbjtcblx0XHR0aGlzLmhhbmRsZUNoYW5nZShmYWxzZSk7XG5cblx0XHQvLyBJZ25vcmUgZmlyc3QgY2hhbmdlIHNpbmNlIGNvbnRlbnQgaXMgbm90IGluaXRpYWxpemVkXG5cdFx0aWYgKGNoYW5nZXMuYXV0b0FsaWduICYmICFjaGFuZ2VzLmF1dG9BbGlnbi5maXJzdENoYW5nZSkge1xuXHRcdFx0Ly8gUmVzZXQgdGhlIGlubGluZSBzdHlsZXNcblx0XHRcdHRoaXMucG9wb3ZlckNvbnRlbnRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiLmNkcy0tcG9wb3Zlci1jb250ZW50XCIpO1xuXHRcdFx0dGhpcy5wb3BvdmVyQ29udGVudFJlZi5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBcIlwiKTtcblx0XHRcdHRoaXMuY2FyZXRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwic3Bhbi5jZHMtLXBvcG92ZXItY2FyZXRcIik7XG5cdFx0fVxuXG5cdFx0dGhpcy5oYW5kbGVDaGFuZ2Uob3JpZ2luYWxTdGF0ZSk7XG5cdH1cblxuXHQvKipcblx0ICogSGFuZGxlIGluaXRpYWxpemF0aW9uIG9mIGVsZW1lbnRcblx0ICovXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcblx0XHR0aGlzLmluaXRpYWxpemVSZWZlcmVuY2VzKCk7XG5cdH1cblxuXHRpbml0aWFsaXplUmVmZXJlbmNlcygpOiB2b2lkIHtcblx0XHR0aGlzLnVwZGF0ZUFsaWdubWVudENsYXNzKHRoaXMuX2FsaWduKTtcblxuXHRcdC8vIEluaXRpYWxpemUgaHRtbCByZWZlcmVuY2VzIHNpbmNlIHRoZXkgd2lsbCBub3QgY2hhbmdlIGFuZCBhcmUgcmVxdWlyZWQgZm9yIHBvcG92ZXIgY29tcG9uZW50c1xuXHRcdHRoaXMucG9wb3ZlckNvbnRlbnRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwiLmNkcy0tcG9wb3Zlci1jb250ZW50XCIpO1xuXHRcdHRoaXMuY2FyZXRSZWYgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKFwic3Bhbi5jZHMtLXBvcG92ZXItY2FyZXRcIik7XG5cblx0XHQvLyBIYW5kbGUgaW5pdGlhbCBpc09wZW5cblx0XHR0aGlzLmhhbmRsZUNoYW5nZSh0aGlzLmlzT3Blbik7XG5cdH1cblxuXHQvKipcblx0ICogQ2xlYW4gdXBcblx0ICovXG5cdG5nT25EZXN0cm95KCk6IHZvaWQge1xuXHRcdHRoaXMuY2xlYW5VcCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENsZWFuIHVwIGBhdXRvVXBkYXRlYCBpZiBhdXRvIGFsaWdubWVudCBpcyBlbmFibGVkXG5cdCAqL1xuXHRjbGVhblVwKCkge1xuXHRcdGlmICh0aGlzLnVubW91bnRGbG9hdGluZ0VsZW1lbnQpIHtcblx0XHRcdHRoaXMudW5tb3VudEZsb2F0aW5nRWxlbWVudCgpO1xuXHRcdH1cblx0XHR0aGlzLnVubW91bnRGbG9hdGluZ0VsZW1lbnQgPSB1bmRlZmluZWQ7XG5cdH1cblxuXHQvKipcblx0ICogUmVwbGFjZSBleGlzdGluZyBwcmV2aW91cyBhbGlnbm1lbnQgY2xhc3Mgd2l0aCBuZXdcblx0ICogQHBhcmFtIHByZXZpb3VzQWxpZ25tZW50XG5cdCAqL1xuXHR1cGRhdGVBbGlnbm1lbnRDbGFzcyhuZXdBbGlnbm1lbnQ6IHN0cmluZywgcHJldmlvdXNBbGlnbm1lbnQ/OiBzdHJpbmcpIHtcblx0XHRpZiAodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgJiYgcHJldmlvdXNBbGlnbm1lbnQgIT09IG5ld0FsaWdubWVudCkge1xuXHRcdFx0Y29uc3QgcmVnZXhwID0gbmV3IFJlZ0V4cChcInJpZ2h0fHRvcHxsZWZ0fGJvdHRvbVwiKTtcblx0XHRcdC8vIFNpbmNlIHdlIGFyZSBjb25zdGFudGx5IHN3aXRjaGluZywgaXQncyBzYWZlciB0byBkZWxldGUgYWxsIG1hdGNoaW5nIGNsYXNzIG5hbWVzXG5cdFx0XHR0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuXHRcdFx0XHRpZiAocmVnZXhwLnRlc3QoY2xhc3NOYW1lKSkge1xuXHRcdFx0XHRcdHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIGAke2NsYXNzTmFtZX1gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBgJHt0aGlzLmFsaWdubWVudENsYXNzUHJlZml4fSR7bmV3QWxpZ25tZW50fWApO1xuXHRcdH1cblx0fVxufVxuIl19