carbon-components-angular
Version:
Next generation components
217 lines • 27.7 kB
JavaScript
import { Component, Input, Output, EventEmitter, ViewChild, HostListener, Optional } from "@angular/core";
import { Subscription } from "rxjs";
// the AbsolutePosition is required to import the declaration correctly
import Position, { position } from "@carbon/utils-position";
import { cycleTabs, getFocusElementList } from "carbon-components-angular/common";
import { CloseReasons } from "./dialog-config.interface";
import * as i0 from "@angular/core";
import * as i1 from "carbon-components-angular/utils";
/**
* Implements a `Dialog` that can be positioned anywhere on the page.
* Used to implement a popover or tooltip.
*/
export class Dialog {
/**
* Creates an instance of `Dialog`.
* @param elementRef
* @param elementService
*/
constructor(elementRef, elementService, animationFrameService = null) {
this.elementRef = elementRef;
this.elementService = elementService;
this.animationFrameService = animationFrameService;
/**
* Emits event that handles the closing of a `Dialog` object.
*/
this.close = new EventEmitter();
/**
* Stores the data received from `dialogConfig`.
*/
this.data = {};
this.visibilitySubscription = new Subscription();
this.animationFrameSubscription = new Subscription();
/**
* Handles offsetting the `Dialog` item based on the defined position
* to not obscure the content beneath.
*/
this.addGap = {
"left": pos => position.addOffset(pos, 0, -this.dialogConfig.gap),
"right": pos => position.addOffset(pos, 0, this.dialogConfig.gap),
"top": pos => position.addOffset(pos, -this.dialogConfig.gap),
"bottom": pos => position.addOffset(pos, this.dialogConfig.gap),
"left-bottom": pos => position.addOffset(pos, 0, -this.dialogConfig.gap),
"right-bottom": pos => position.addOffset(pos, 0, this.dialogConfig.gap)
};
/**
* Extra placements. Child classes can add to this for use in `placeDialog`.
*/
this.placements = {};
}
/**
* Initialize the `Dialog`, set the placement and gap, and add a `Subscription` to resize events.
*/
ngOnInit() {
this.placement = this.dialogConfig.placement.split(",")[0];
this.data = this.dialogConfig.data;
// run any additional initialization code that consuming classes may have
this.onDialogInit();
}
/**
* After the DOM is ready, focus is set and dialog is placed
* in respect to the parent element.
*/
ngAfterViewInit() {
const dialogElement = this.dialog.nativeElement;
// split the wrapper class list and apply separately to avoid IE
// 1. throwing an error due to assigning a readonly property (classList)
// 2. throwing a SyntaxError due to passing an empty string to `add`
if (this.dialogConfig.wrapperClass) {
for (const extraClass of this.dialogConfig.wrapperClass.split(" ")) {
dialogElement.classList.add(extraClass);
}
}
// only focus the dialog if there are focusable elements within the dialog
if (getFocusElementList(this.dialog.nativeElement).length > 0) {
dialogElement.focus();
}
const parentElement = this.dialogConfig.parentRef.nativeElement;
if (this.animationFrameService) {
this.animationFrameSubscription = this.animationFrameService.tick.subscribe(() => {
this.placeDialog();
});
}
if (this.dialogConfig.closeWhenHidden) {
this.visibilitySubscription = this.elementService
.visibility(parentElement, parentElement)
.subscribe(value => {
this.placeDialog();
if (!value.visible) {
this.doClose({
reason: CloseReasons.hidden
});
}
});
}
this.placeDialog();
// run afterDialogViewInit on the next tick
setTimeout(() => this.afterDialogViewInit());
}
/**
* Empty method to be overridden by consuming classes to run any additional initialization code.
*/
onDialogInit() { }
/**
* Empty method to be overridden by consuming classes to run any additional initialization code after the view is available.
* NOTE: this does _not_ guarantee the dialog will be positioned, simply that it will exist in the DOM
*/
afterDialogViewInit() { }
/**
* Uses the position service to position the `Dialog` in screen space
*/
placeDialog() {
const positionService = new Position(this.placements);
// helper to find the position based on the current/given environment
const findPosition = (reference, target, placement) => {
let pos;
if (this.dialogConfig.appendInline) {
pos = this.addGap[placement](positionService.findRelative(reference, target, placement));
}
else {
pos = this.addGap[placement](positionService.findAbsolute(reference, target, placement));
}
if (this.dialogConfig.offset) {
// Apply vertical and horizontal offsets given through the dialogConfig
pos.top = pos.top + this.dialogConfig.offset.y;
pos.left = pos.left + this.dialogConfig.offset.x;
}
return pos;
};
let parentEl = this.dialogConfig.parentRef.nativeElement;
let el = this.dialog.nativeElement;
let dialogPlacement = this.placement;
// split always returns an array, so we can just use the auto position logic
// for single positions too
const placements = this.dialogConfig.placement.split(",");
// find the best placement
dialogPlacement = positionService.findBestPlacement(parentEl, el, placements);
// calculate the final position
const pos = findPosition(parentEl, el, dialogPlacement);
// update the element
positionService.setElement(el, pos);
setTimeout(() => { this.placement = dialogPlacement; });
}
/**
* Sets up a KeyboardEvent to close `Dialog` with Escape key.
* @param event
*/
escapeClose(event) {
switch (event.key) {
case "Escape": {
event.stopImmediatePropagation();
this.doClose({
reason: CloseReasons.interaction,
target: event.target
});
break;
}
case "Tab": {
cycleTabs(event, this.elementRef.nativeElement);
break;
}
}
}
/**
* Sets up a event Listener to close `Dialog` if click event occurs outside
* `Dialog` object.
* @param event
*/
clickClose(event) {
if (!this.elementRef.nativeElement.contains(event.target)
&& !this.dialogConfig.parentRef.nativeElement.contains(event.target)) {
this.doClose({
reason: CloseReasons.interaction,
target: event.target
});
}
}
/**
* Closes `Dialog` object by emitting the close event upwards to parents.
*/
doClose(meta = { reason: CloseReasons.interaction }) {
this.close.emit(meta);
}
/**
* At destruction of component, `Dialog` unsubscribes from all the subscriptions.
*/
ngOnDestroy() {
this.visibilitySubscription.unsubscribe();
if (this.animationFrameSubscription) {
this.animationFrameSubscription.unsubscribe();
}
}
}
Dialog.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Dialog, deps: [{ token: i0.ElementRef }, { token: i1.ElementService }, { token: i1.AnimationFrameService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
Dialog.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Dialog, selector: "cds-dialog, ibm-dialog", inputs: { dialogConfig: "dialogConfig" }, outputs: { close: "close" }, host: { listeners: { "keydown": "escapeClose($event)", "document:click": "clickClose($event)" } }, viewQueries: [{ propertyName: "dialog", first: true, predicate: ["dialog"], descendants: true }], ngImport: i0, template: "", isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Dialog, decorators: [{
type: Component,
args: [{
selector: "cds-dialog, ibm-dialog",
template: ""
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.ElementService }, { type: i1.AnimationFrameService, decorators: [{
type: Optional
}] }]; }, propDecorators: { close: [{
type: Output
}], dialogConfig: [{
type: Input
}], dialog: [{
type: ViewChild,
args: ["dialog"]
}], escapeClose: [{
type: HostListener,
args: ["keydown", ["$event"]]
}], clickClose: [{
type: HostListener,
args: ["document:click", ["$event"]]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9kaWFsb2cvZGlhbG9nLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUVaLFNBQVMsRUFJVCxZQUFZLEVBQ1osUUFBUSxFQUNSLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTixZQUFZLEVBQ1osTUFBTSxNQUFNLENBQUM7QUFDZCx1RUFBdUU7QUFDdkUsT0FBTyxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQStCLE1BQU0sd0JBQXdCLENBQUM7QUFDekYsT0FBTyxFQUFFLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ2xGLE9BQU8sRUFBYSxZQUFZLEVBQWdCLE1BQU0sMkJBQTJCLENBQUM7OztBQUdsRjs7O0dBR0c7QUFLSCxNQUFNLE9BQU8sTUFBTTtJQStDbEI7Ozs7T0FJRztJQUNILFlBQ1csVUFBc0IsRUFDdEIsY0FBOEIsRUFDbEIsd0JBQStDLElBQUk7UUFGL0QsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDbEIsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUE4QjtRQXREMUU7O1dBRUc7UUFDTyxVQUFLLEdBQTRCLElBQUksWUFBWSxFQUFFLENBQUM7UUFXOUQ7O1dBRUc7UUFDSSxTQUFJLEdBQUcsRUFBRSxDQUFDO1FBT1AsMkJBQXNCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUU1QywrQkFBMEIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBRTFEOzs7V0FHRztRQUNPLFdBQU0sR0FBRztZQUNsQixNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENB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QUFFLENBQUMsUUFBUSxDQUFDO2dCQXdCbkMsVUFBVTtzQkFEVCxZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0Q29tcG9uZW50LFxuXHRJbnB1dCxcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXIsXG5cdEVsZW1lbnRSZWYsXG5cdFZpZXdDaGlsZCxcblx0T25Jbml0LFxuXHRBZnRlclZpZXdJbml0LFxuXHRPbkRlc3Ryb3ksXG5cdEhvc3RMaXN0ZW5lcixcblx0T3B0aW9uYWxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7XG5cdE9ic2VydmFibGUsXG5cdFN1YnNjcmlwdGlvblxufSBmcm9tIFwicnhqc1wiO1xuLy8gdGhlIEFic29sdXRlUG9zaXRpb24gaXMgcmVxdWlyZWQgdG8gaW1wb3J0IHRoZSBkZWNsYXJhdGlvbiBjb3JyZWN0bHlcbmltcG9ydCBQb3NpdGlvbiwgeyBwb3NpdGlvbiwgQWJzb2x1dGVQb3NpdGlvbiwgUG9zaXRpb25zIH0gZnJvbSBcIkBjYXJib24vdXRpbHMtcG9zaXRpb25cIjtcbmltcG9ydCB7IGN5Y2xlVGFicywgZ2V0Rm9jdXNFbGVtZW50TGlzdCB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgQ2xvc2VNZXRhLCBDbG9zZVJlYXNvbnMsIERpYWxvZ0NvbmZpZyB9IGZyb20gXCIuL2RpYWxvZy1jb25maWcuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBbmltYXRpb25GcmFtZVNlcnZpY2UsIEVsZW1lbnRTZXJ2aWNlIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvdXRpbHNcIjtcblxuLyoqXG4gKiBJbXBsZW1lbnRzIGEgYERpYWxvZ2AgdGhhdCBjYW4gYmUgcG9zaXRpb25lZCBhbnl3aGVyZSBvbiB0aGUgcGFnZS5cbiAqIFVzZWQgdG8gaW1wbGVtZW50IGEgcG9wb3ZlciBvciB0b29sdGlwLlxuICovXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6IFwiY2RzLWRpYWxvZywgaWJtLWRpYWxvZ1wiLFxuXHR0ZW1wbGF0ZTogXCJcIlxufSlcbmV4cG9ydCBjbGFzcyBEaWFsb2cgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG5cdC8qKlxuXHQgKiBFbWl0cyBldmVudCB0aGF0IGhhbmRsZXMgdGhlIGNsb3Npbmcgb2YgYSBgRGlhbG9nYCBvYmplY3QuXG5cdCAqL1xuXHRAT3V0cHV0KCkgY2xvc2U6IEV2ZW50RW1pdHRlcjxDbG9zZU1ldGE+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHQvKipcblx0ICogUmVjZWl2ZXMgYERpYWxvZ0NvbmZpZ2AgaW50ZXJmYWNlIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgb2YgYERpYWxvZ2Bcblx0ICogZXhwbGljaXRseSBkZWZpbmVkLlxuXHQgKi9cblx0QElucHV0KCkgZGlhbG9nQ29uZmlnOiBEaWFsb2dDb25maWc7XG5cdC8qKlxuXHQgKiBNYWludGFpbnMgYSByZWZlcmVuY2UgdG8gdGhlIHZpZXcgRE9NIGVsZW1lbnQgb2YgdGhlIGBEaWFsb2dgLlxuXHQgKi9cblx0QFZpZXdDaGlsZChcImRpYWxvZ1wiKSBkaWFsb2c6IEVsZW1lbnRSZWY7XG5cblx0LyoqXG5cdCAqIFN0b3JlcyB0aGUgZGF0YSByZWNlaXZlZCBmcm9tIGBkaWFsb2dDb25maWdgLlxuXHQgKi9cblx0cHVibGljIGRhdGEgPSB7fTtcblxuXHQvKipcblx0ICogVGhlIHBsYWNlbWVudCBvZiB0aGUgYERpYWxvZ2AgaXMgcmVjZWl2ZWQgZnJvbSB0aGUgYFBvc2l0aW9uYCBzZXJ2aWNlLlxuXHQgKi9cblx0cHVibGljIHBsYWNlbWVudDogc3RyaW5nO1xuXG5cdHByb3RlY3RlZCB2aXNpYmlsaXR5U3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG5cdHByb3RlY3RlZCBhbmltYXRpb25GcmFtZVN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuXHQvKipcblx0ICogSGFuZGxlcyBvZmZzZXR0aW5nIHRoZSBgRGlhbG9nYCBpdGVtIGJhc2VkIG9uIHRoZSBkZWZpbmVkIHBvc2l0aW9uXG5cdCAqIHRvIG5vdCBvYnNjdXJlIHRoZSBjb250ZW50IGJlbmVhdGguXG5cdCAqL1xuXHRwcm90ZWN0ZWQgYWRkR2FwID0ge1xuXHRcdFwibGVmdFwiOiBwb3MgPT4gcG9zaXRpb24uYWRkT2Zmc2V0KHBvcywgMCwgLXRoaXMuZGlhbG9nQ29uZmlnLmdhcCksXG5cdFx0XCJyaWdodFwiOiBwb3MgPT4gcG9zaXRpb24uYWRkT2Zmc2V0KHBvcywgMCwgdGhpcy5kaWFsb2dDb25maWcuZ2FwKSxcblx0XHRcInRvcFwiOiBwb3MgPT4gcG9zaXRpb24uYWRkT2Zmc2V0KHBvcywgLXRoaXMuZGlhbG9nQ29uZmlnLmdhcCksXG5cdFx0XCJib3R0b21cIjogcG9zID0+IHBvc2l0aW9uLmFkZE9mZnNldChwb3MsIHRoaXMuZGlhbG9nQ29uZmlnLmdhcCksXG5cdFx0XCJsZWZ0LWJvdHRvbVwiOiBwb3MgPT4gcG9zaXRpb24uYWRkT2Zmc2V0KHBvcywgMCwgLXRoaXMuZGlhbG9nQ29uZmlnLmdhcCksXG5cdFx0XCJyaWdodC1ib3R0b21cIjogcG9zID0+IHBvc2l0aW9uLmFkZE9mZnNldChwb3MsIDAsIHRoaXMuZGlhbG9nQ29uZmlnLmdhcClcblx0fTtcblxuXHQvKipcblx0ICogRXh0cmEgcGxhY2VtZW50cy4gQ2hpbGQgY2xhc3NlcyBjYW4gYWRkIHRvIHRoaXMgZm9yIHVzZSBpbiBgcGxhY2VEaWFsb2dgLlxuXHQgKi9cblx0cHJvdGVjdGVkIHBsYWNlbWVudHM6IFBvc2l0aW9ucyA9IHt9O1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGBEaWFsb2dgLlxuXHQgKiBAcGFyYW0gZWxlbWVudFJlZlxuXHQgKiBAcGFyYW0gZWxlbWVudFNlcnZpY2Vcblx0ICovXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByb3RlY3RlZCBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuXHRcdHByb3RlY3RlZCBlbGVtZW50U2VydmljZTogRWxlbWVudFNlcnZpY2UsXG5cdFx0QE9wdGlvbmFsKCkgcHJvdGVjdGVkIGFuaW1hdGlvbkZyYW1lU2VydmljZTogQW5pbWF0aW9uRnJhbWVTZXJ2aWNlID0gbnVsbFxuXHQpIHt9XG5cblx0LyoqXG5cdCAqIEluaXRpYWxpemUgdGhlIGBEaWFsb2dgLCBzZXQgdGhlIHBsYWNlbWVudCBhbmQgZ2FwLCBhbmQgYWRkIGEgYFN1YnNjcmlwdGlvbmAgdG8gcmVzaXplIGV2ZW50cy5cblx0ICovXG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMucGxhY2VtZW50ID0gdGhpcy5kaWFsb2dDb25maWcucGxhY2VtZW50LnNwbGl0KFwiLFwiKVswXTtcblx0XHR0aGlzLmRhdGEgPSB0aGlzLmRpYWxvZ0NvbmZpZy5kYXRhO1xuXG5cdFx0Ly8gcnVuIGFueSBhZGRpdGlvbmFsIGluaXRpYWxpemF0aW9uIGNvZGUgdGhhdCBjb25zdW1pbmcgY2xhc3NlcyBtYXkgaGF2ZVxuXHRcdHRoaXMub25EaWFsb2dJbml0KCk7XG5cdH1cblxuXHQvKipcblx0ICogQWZ0ZXIgdGhlIERPTSBpcyByZWFkeSwgZm9jdXMgaXMgc2V0IGFuZCBkaWFsb2cgaXMgcGxhY2VkXG5cdCAqIGluIHJlc3BlY3QgdG8gdGhlIHBhcmVudCBlbGVtZW50LlxuXHQgKi9cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdGNvbnN0IGRpYWxvZ0VsZW1lbnQgPSB0aGlzLmRpYWxvZy5uYXRpdmVFbGVtZW50O1xuXHRcdC8vIHNwbGl0IHRoZSB3cmFwcGVyIGNsYXNzIGxpc3QgYW5kIGFwcGx5IHNlcGFyYXRlbHkgdG8gYXZvaWQgSUVcblx0XHQvLyAxLiB0aHJvd2luZyBhbiBlcnJvciBkdWUgdG8gYXNzaWduaW5nIGEgcmVhZG9ubHkgcHJvcGVydHkgKGNsYXNzTGlzdClcblx0XHQvLyAyLiB0aHJvd2luZyBhIFN5bnRheEVycm9yIGR1ZSB0byBwYXNzaW5nIGFuIGVtcHR5IHN0cmluZyB0byBgYWRkYFxuXHRcdGlmICh0aGlzLmRpYWxvZ0NvbmZpZy53cmFwcGVyQ2xhc3MpIHtcblx0XHRcdGZvciAoY29uc3QgZXh0cmFDbGFzcyBvZiB0aGlzLmRpYWxvZ0NvbmZpZy53cmFwcGVyQ2xhc3Muc3BsaXQoXCIgXCIpKSB7XG5cdFx0XHRcdGRpYWxvZ0VsZW1lbnQuY2xhc3NMaXN0LmFkZChleHRyYUNsYXNzKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBvbmx5IGZvY3VzIHRoZSBkaWFsb2cgaWYgdGhlcmUgYXJlIGZvY3VzYWJsZSBlbGVtZW50cyB3aXRoaW4gdGhlIGRpYWxvZ1xuXHRcdGlmIChnZXRGb2N1c0VsZW1lbnRMaXN0KHRoaXMuZGlhbG9nLm5hdGl2ZUVsZW1lbnQpLmxlbmd0aCA+IDApIHtcblx0XHRcdGRpYWxvZ0VsZW1lbnQuZm9jdXMoKTtcblx0XHR9XG5cblx0XHRjb25zdCBwYXJlbnRFbGVtZW50ID0gdGhpcy5kaWFsb2dDb25maWcucGFyZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG5cblx0XHRpZiAodGhpcy5hbmltYXRpb25GcmFtZVNlcnZpY2UpIHtcblx0XHRcdHRoaXMuYW5pbWF0aW9uRnJhbWVTdWJzY3JpcHRpb24gPSB0aGlzLmFuaW1hdGlvbkZyYW1lU2VydmljZS50aWNrLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGxhY2VEaWFsb2coKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmRpYWxvZ0NvbmZpZy5jbG9zZVdoZW5IaWRkZW4pIHtcblx0XHRcdHRoaXMudmlzaWJpbGl0eVN1YnNjcmlwdGlvbiA9IHRoaXMuZWxlbWVudFNlcnZpY2Vcblx0XHRcdFx0LnZpc2liaWxpdHkocGFyZW50RWxlbWVudCwgcGFyZW50RWxlbWVudClcblx0XHRcdFx0LnN1YnNjcmliZSh2YWx1ZSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbGFjZURpYWxvZygpO1xuXHRcdFx0XHRcdGlmICghdmFsdWUudmlzaWJsZSkge1xuXHRcdFx0XHRcdFx0dGhpcy5kb0Nsb3NlKHtcblx0XHRcdFx0XHRcdFx0cmVhc29uOiBDbG9zZVJlYXNvbnMuaGlkZGVuXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5wbGFjZURpYWxvZygpO1xuXHRcdC8vIHJ1biBhZnRlckRpYWxvZ1ZpZXdJbml0IG9uIHRoZSBuZXh0IHRpY2tcblx0XHRzZXRUaW1lb3V0KCgpID0+IHRoaXMuYWZ0ZXJEaWFsb2dWaWV3SW5pdCgpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBFbXB0eSBtZXRob2QgdG8gYmUgb3ZlcnJpZGRlbiBieSBjb25zdW1pbmcgY2xhc3NlcyB0byBydW4gYW55IGFkZGl0aW9uYWwgaW5pdGlhbGl6YXRpb24gY29kZS5cblx0ICovXG5cdG9uRGlhbG9nSW5pdCgpIHt9XG5cblx0LyoqXG5cdCAqIEVtcHR5IG1ldGhvZCB0byBiZSBvdmVycmlkZGVuIGJ5IGNvbnN1bWluZyBjbGFzc2VzIHRvIHJ1biBhbnkgYWRkaXRpb25hbCBpbml0aWFsaXphdGlvbiBjb2RlIGFmdGVyIHRoZSB2aWV3IGlzIGF2YWlsYWJsZS5cblx0ICogTk9URTogdGhpcyBkb2VzIF9ub3RfIGd1YXJhbnRlZSB0aGUgZGlhbG9nIHdpbGwgYmUgcG9zaXRpb25lZCwgc2ltcGx5IHRoYXQgaXQgd2lsbCBleGlzdCBpbiB0aGUgRE9NXG5cdCAqL1xuXHRhZnRlckRpYWxvZ1ZpZXdJbml0KCkge31cblxuXHQvKipcblx0ICogVXNlcyB0aGUgcG9zaXRpb24gc2VydmljZSB0byBwb3NpdGlvbiB0aGUgYERpYWxvZ2AgaW4gc2NyZWVuIHNwYWNlXG5cdCAqL1xuXHRwbGFjZURpYWxvZygpOiB2b2lkIHtcblx0XHRjb25zdCBwb3NpdGlvblNlcnZpY2UgPSBuZXcgUG9zaXRpb24odGhpcy5wbGFjZW1lbnRzKTtcblx0XHQvLyBoZWxwZXIgdG8gZmluZCB0aGUgcG9zaXRpb24gYmFzZWQgb24gdGhlIGN1cnJlbnQvZ2l2ZW4gZW52aXJvbm1lbnRcblx0XHRjb25zdCBmaW5kUG9zaXRpb24gPSAocmVmZXJlbmNlLCB0YXJnZXQsIHBsYWNlbWVudCkgPT4ge1xuXHRcdFx0bGV0IHBvcztcblx0XHRcdGlmICh0aGlzLmRpYWxvZ0NvbmZpZy5hcHBlbmRJbmxpbmUpIHtcblx0XHRcdFx0cG9zID0gdGhpcy5hZGRHYXBbcGxhY2VtZW50XShwb3NpdGlvblNlcnZpY2UuZmluZFJlbGF0aXZlKHJlZmVyZW5jZSwgdGFyZ2V0LCBwbGFjZW1lbnQpKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBvcyA9IHRoaXMuYWRkR2FwW3BsYWNlbWVudF0ocG9zaXRpb25TZXJ2aWNlLmZpbmRBYnNvbHV0ZShyZWZlcmVuY2UsIHRhcmdldCwgcGxhY2VtZW50KSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLmRpYWxvZ0NvbmZpZy5vZmZzZXQpIHtcblx0XHRcdFx0Ly8gQXBwbHkgdmVydGljYWwgYW5kIGhvcml6b250YWwgb2Zmc2V0cyBnaXZlbiB0aHJvdWdoIHRoZSBkaWFsb2dDb25maWdcblx0XHRcdFx0cG9zLnRvcCA9IHBvcy50b3AgKyB0aGlzLmRpYWxvZ0NvbmZpZy5vZmZzZXQueTtcblx0XHRcdFx0cG9zLmxlZnQgPSBwb3MubGVmdCArIHRoaXMuZGlhbG9nQ29uZmlnLm9mZnNldC54O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcG9zO1xuXHRcdH07XG5cblx0XHRsZXQgcGFyZW50RWwgPSB0aGlzLmRpYWxvZ0NvbmZpZy5wYXJlbnRSZWYubmF0aXZlRWxlbWVudDtcblx0XHRsZXQgZWwgPSB0aGlzLmRpYWxvZy5uYXRpdmVFbGVtZW50O1xuXHRcdGxldCBkaWFsb2dQbGFjZW1lbnQgPSB0aGlzLnBsYWNlbWVudDtcblxuXHRcdC8vIHNwbGl0IGFsd2F5cyByZXR1cm5zIGFuIGFycmF5LCBzbyB3ZSBjYW4ganVzdCB1c2UgdGhlIGF1dG8gcG9zaXRpb24gbG9naWNcblx0XHQvLyBmb3Igc2luZ2xlIHBvc2l0aW9ucyB0b29cblx0XHRjb25zdCBwbGFjZW1lbnRzID0gdGhpcy5kaWFsb2dDb25maWcucGxhY2VtZW50LnNwbGl0KFwiLFwiKTtcblxuXHRcdC8vIGZpbmQgdGhlIGJlc3QgcGxhY2VtZW50XG5cdFx0ZGlhbG9nUGxhY2VtZW50ID0gcG9zaXRpb25TZXJ2aWNlLmZpbmRCZXN0UGxhY2VtZW50KHBhcmVudEVsLCBlbCwgcGxhY2VtZW50cyk7XG5cblx0XHQvLyBjYWxjdWxhdGUgdGhlIGZpbmFsIHBvc2l0aW9uXG5cdFx0Y29uc3QgcG9zID0gZmluZFBvc2l0aW9uKHBhcmVudEVsLCBlbCwgZGlhbG9nUGxhY2VtZW50KTtcblxuXHRcdC8vIHVwZGF0ZSB0aGUgZWxlbWVudFxuXHRcdHBvc2l0aW9uU2VydmljZS5zZXRFbGVtZW50KGVsLCBwb3MpO1xuXHRcdHNldFRpbWVvdXQoKCkgPT4geyB0aGlzLnBsYWNlbWVudCA9IGRpYWxvZ1BsYWNlbWVudDsgfSk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB1cCBhIEtleWJvYXJkRXZlbnQgdG8gY2xvc2UgYERpYWxvZ2Agd2l0aCBFc2NhcGUga2V5LlxuXHQgKiBAcGFyYW0gZXZlbnRcblx0ICovXG5cdEBIb3N0TGlzdGVuZXIoXCJrZXlkb3duXCIsIFtcIiRldmVudFwiXSlcblx0ZXNjYXBlQ2xvc2UoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcblx0XHRzd2l0Y2ggKGV2ZW50LmtleSkge1xuXHRcdFx0Y2FzZSBcIkVzY2FwZVwiOiB7XG5cdFx0XHRcdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHR0aGlzLmRvQ2xvc2Uoe1xuXHRcdFx0XHRcdHJlYXNvbjogQ2xvc2VSZWFzb25zLmludGVyYWN0aW9uLFxuXHRcdFx0XHRcdHRhcmdldDogZXZlbnQudGFyZ2V0XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJUYWJcIjoge1xuXHRcdFx0XHRjeWNsZVRhYnMoZXZlbnQsIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdXAgYSBldmVudCBMaXN0ZW5lciB0byBjbG9zZSBgRGlhbG9nYCBpZiBjbGljayBldmVudCBvY2N1cnMgb3V0c2lkZVxuXHQgKiBgRGlhbG9nYCBvYmplY3QuXG5cdCAqIEBwYXJhbSBldmVudFxuXHQgKi9cblx0QEhvc3RMaXN0ZW5lcihcImRvY3VtZW50OmNsaWNrXCIsIFtcIiRldmVudFwiXSlcblx0Y2xpY2tDbG9zZShldmVudCkge1xuXHRcdGlmICghdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KVxuXHRcdFx0JiYgIXRoaXMuZGlhbG9nQ29uZmlnLnBhcmVudFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgKSB7XG5cdFx0XHR0aGlzLmRvQ2xvc2Uoe1xuXHRcdFx0XHRyZWFzb246IENsb3NlUmVhc29ucy5pbnRlcmFjdGlvbixcblx0XHRcdFx0dGFyZ2V0OiBldmVudC50YXJnZXRcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9zZXMgYERpYWxvZ2Agb2JqZWN0IGJ5IGVtaXR0aW5nIHRoZSBjbG9zZSBldmVudCB1cHdhcmRzIHRvIHBhcmVudHMuXG5cdCAqL1xuXHRwdWJsaWMgZG9DbG9zZShtZXRhOiBDbG9zZU1ldGEgPSB7IHJlYXNvbjogQ2xvc2VSZWFzb25zLmludGVyYWN0aW9uIH0pIHtcblx0XHR0aGlzLmNsb3NlLmVtaXQobWV0YSk7XG5cdH1cblxuXHQvKipcblx0ICogQXQgZGVzdHJ1Y3Rpb24gb2YgY29tcG9uZW50LCBgRGlhbG9nYCB1bnN1YnNjcmliZXMgZnJvbSBhbGwgdGhlIHN1YnNjcmlwdGlvbnMuXG5cdCAqL1xuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLnZpc2liaWxpdHlTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblx0XHRpZiAodGhpcy5hbmltYXRpb25GcmFtZVN1YnNjcmlwdGlvbikge1xuXHRcdFx0dGhpcy5hbmltYXRpb25GcmFtZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuXHRcdH1cblx0fVxufVxuIl19