UNPKG

carbon-components-angular

Version:
217 lines 27.7 kB
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