carbon-components-angular
Version:
Next generation components
165 lines • 19.9 kB
JavaScript
import { Component, HostListener, Optional } from "@angular/core";
import { Dialog } from "../dialog.component";
import { position } from "@carbon/utils-position";
import { isFocusInLastItem, isFocusInFirstItem } from "carbon-components-angular/common";
import { CloseReasons } from "../dialog-config.interface";
import { closestAttr } from "carbon-components-angular/utils";
import * as i0 from "@angular/core";
import * as i1 from "carbon-components-angular/i18n";
import * as i2 from "carbon-components-angular/experimental";
import * as i3 from "carbon-components-angular/utils";
import * as i4 from "@angular/common";
/**
* Extend the `Dialog` component to create an overflow menu.
*
* Not used directly. See overflow-menu.component and overflow-menu.directive for more
*/
export class OverflowMenuPane extends Dialog {
constructor(elementRef, i18n, experimental, animationFrameService = null,
// mark `elementService` as optional since making it mandatory would be a breaking change
elementService = null) {
super(elementRef, elementService, animationFrameService);
this.elementRef = elementRef;
this.i18n = i18n;
this.experimental = experimental;
this.animationFrameService = animationFrameService;
this.elementService = elementService;
}
onDialogInit() {
const positionOverflowMenu = pos => {
let offset;
/*
* 20 is half the width of the overflow menu trigger element.
* we also move the element by half of it's own width, since
* position service will try and center everything
*/
const closestRel = closestAttr("position", ["relative", "fixed", "absolute"], this.elementRef.nativeElement);
const topFix = closestRel ? closestRel.getBoundingClientRect().top * -1 : 0;
const leftFix = closestRel ? closestRel.getBoundingClientRect().left * -1 : 0;
offset = Math.round(this.dialog.nativeElement.offsetWidth / 2) - 20;
if (this.dialogConfig.flip) {
return position.addOffset(pos, topFix, (-offset + leftFix));
}
return position.addOffset(pos, topFix, (offset + leftFix));
};
this.addGap["bottom"] = positionOverflowMenu;
this.addGap["top"] = positionOverflowMenu;
if (!this.dialogConfig.menuLabel) {
this.dialogConfig.menuLabel = this.i18n.get().OVERFLOW_MENU.OVERFLOW;
}
}
hostkeys(event) {
const listItems = this.listItems();
switch (event.key) {
case "ArrowDown":
event.preventDefault();
if (!isFocusInLastItem(event, listItems)) {
const index = listItems.findIndex(item => item === event.target);
listItems[index + 1].focus();
}
else {
listItems[0].focus();
}
break;
case "ArrowUp":
event.preventDefault();
if (!isFocusInFirstItem(event, listItems)) {
const index = listItems.findIndex(item => item === event.target);
listItems[index - 1].focus();
}
else {
listItems[listItems.length - 1].focus();
}
break;
case "Home":
event.preventDefault();
listItems[0].focus();
break;
case "End":
event.preventDefault();
listItems[listItems.length - 1].focus();
break;
case "Escape":
case "Tab":
event.stopImmediatePropagation();
this.doClose({
reason: CloseReasons.interaction,
target: event.target
});
break;
default: break;
}
}
onClose(event) {
this.doClose({
reason: CloseReasons.interaction,
target: event.target
});
}
afterDialogViewInit() {
const focusElementList = this.listItems();
focusElementList.forEach(button => {
// Allows user to set tabindex to 0.
if (button.getAttribute("tabindex") === null) {
button.tabIndex = -1;
}
});
if (focusElementList[0]) {
focusElementList[0].tabIndex = 0;
focusElementList[0].focus();
}
}
listItems() {
const selector = ".cds--overflow-menu-options__option:not([disabled]) .cds--overflow-menu-options__btn";
return Array.from(this.elementRef.nativeElement.querySelectorAll(selector));
}
}
OverflowMenuPane.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OverflowMenuPane, deps: [{ token: i0.ElementRef }, { token: i1.I18n }, { token: i2.ExperimentalService }, { token: i3.AnimationFrameService, optional: true }, { token: i3.ElementService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
OverflowMenuPane.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: OverflowMenuPane, selector: "cds-overflow-menu-pane, ibm-overflow-menu-pane", host: { listeners: { "keydown": "hostkeys($event)" } }, usesInheritance: true, ngImport: i0, template: `
<ul
[attr.id]="dialogConfig.compID"
[attr.aria-label]="dialogConfig.menuLabel"
[attr.data-floating-menu-direction]="placement ? placement : null"
[ngClass]="{'cds--overflow-menu--flip': dialogConfig.flip}"
role="menu"
#dialog
class="cds--overflow-menu-options cds--overflow-menu-options--open"
(click)="onClose($event)"
[attr.aria-label]="dialogConfig.menuLabel">
<ng-template
[ngTemplateOutlet]="dialogConfig.content"
[ngTemplateOutletContext]="{overflowMenu: this}">
</ng-template>
</ul>
`, isInline: true, dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OverflowMenuPane, decorators: [{
type: Component,
args: [{
selector: "cds-overflow-menu-pane, ibm-overflow-menu-pane",
template: `
<ul
[attr.id]="dialogConfig.compID"
[attr.aria-label]="dialogConfig.menuLabel"
[attr.data-floating-menu-direction]="placement ? placement : null"
[ngClass]="{'cds--overflow-menu--flip': dialogConfig.flip}"
role="menu"
#dialog
class="cds--overflow-menu-options cds--overflow-menu-options--open"
(click)="onClose($event)"
[attr.aria-label]="dialogConfig.menuLabel">
<ng-template
[ngTemplateOutlet]="dialogConfig.content"
[ngTemplateOutletContext]="{overflowMenu: this}">
</ng-template>
</ul>
`
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.I18n }, { type: i2.ExperimentalService }, { type: i3.AnimationFrameService, decorators: [{
type: Optional
}] }, { type: i3.ElementService, decorators: [{
type: Optional
}] }]; }, propDecorators: { hostkeys: [{
type: HostListener,
args: ["keydown", ["$event"]]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmZsb3ctbWVudS1wYW5lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kaWFsb2cvb3ZlcmZsb3ctbWVudS9vdmVyZmxvdy1tZW51LXBhbmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTixTQUFTLEVBQ1QsWUFBWSxFQUdaLFFBQVEsRUFDUixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBSXpGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7OztBQUU5RDs7OztHQUlHO0FBcUJILE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxNQUFNO0lBQzNDLFlBQ1csVUFBc0IsRUFDdEIsSUFBVSxFQUNWLFlBQWlDLEVBQ3JCLHdCQUErQyxJQUFJO0lBQ3pFLHlGQUF5RjtJQUNuRSxpQkFBaUMsSUFBSTtRQUMzRCxLQUFLLENBQUMsVUFBVSxFQUFFLGNBQWMsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1FBTi9DLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsU0FBSSxHQUFKLElBQUksQ0FBTTtRQUNWLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQUNyQiwwQkFBcUIsR0FBckIscUJBQXFCLENBQThCO1FBRW5ELG1CQUFjLEdBQWQsY0FBYyxDQUF1QjtJQUU1RCxDQUFDO0lBRUQsWUFBWTtRQUNYLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxDQUFDLEVBQUU7WUFDbEMsSUFBSSxNQUFNLENBQUM7WUFDWDs7OztjQUlFO1lBQ0YsTUFBTSxV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UztRQUNsQixNQUFNLFFBQVEsR0FBRyxzRkFBc0YsQ0FBQztRQUN4RyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQWMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDOzs2R0E5R1csZ0JBQWdCO2lHQUFoQixnQkFBZ0IscUtBbEJsQjs7Ozs7Ozs7Ozs7Ozs7OztFQWdCVDsyRkFFVyxnQkFBZ0I7a0JBcEI1QixTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSxnREFBZ0Q7b0JBQzFELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7OztFQWdCVDtpQkFDRDs7MEJBTUUsUUFBUTs7MEJBRVIsUUFBUTs0Q0FpQ1YsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SG9zdExpc3RlbmVyLFxuXHRFbGVtZW50UmVmLFxuXHRBZnRlclZpZXdJbml0LFxuXHRPcHRpb25hbFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRGlhbG9nIH0gZnJvbSBcIi4uL2RpYWxvZy5jb21wb25lbnRcIjtcbmltcG9ydCB7IHBvc2l0aW9uIH0gZnJvbSBcIkBjYXJib24vdXRpbHMtcG9zaXRpb25cIjtcbmltcG9ydCB7IGlzRm9jdXNJbkxhc3RJdGVtLCBpc0ZvY3VzSW5GaXJzdEl0ZW0gfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IEkxOG4gfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci9pMThuXCI7XG5pbXBvcnQgeyBFeHBlcmltZW50YWxTZXJ2aWNlIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvZXhwZXJpbWVudGFsXCI7XG5pbXBvcnQgeyBBbmltYXRpb25GcmFtZVNlcnZpY2UsIEVsZW1lbnRTZXJ2aWNlIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvdXRpbHNcIjtcbmltcG9ydCB7IENsb3NlUmVhc29ucyB9IGZyb20gXCIuLi9kaWFsb2ctY29uZmlnLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgY2xvc2VzdEF0dHIgfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci91dGlsc1wiO1xuXG4vKipcbiAqIEV4dGVuZCB0aGUgYERpYWxvZ2AgY29tcG9uZW50IHRvIGNyZWF0ZSBhbiBvdmVyZmxvdyBtZW51LlxuICpcbiAqIE5vdCB1c2VkIGRpcmVjdGx5LiBTZWUgb3ZlcmZsb3ctbWVudS5jb21wb25lbnQgYW5kIG92ZXJmbG93LW1lbnUuZGlyZWN0aXZlIGZvciBtb3JlXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtb3ZlcmZsb3ctbWVudS1wYW5lLCBpYm0tb3ZlcmZsb3ctbWVudS1wYW5lXCIsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PHVsXG5cdFx0XHRbYXR0ci5pZF09XCJkaWFsb2dDb25maWcuY29tcElEXCJcblx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwiZGlhbG9nQ29uZmlnLm1lbnVMYWJlbFwiXG5cdFx0XHRbYXR0ci5kYXRhLWZsb2F0aW5nLW1lbnUtZGlyZWN0aW9uXT1cInBsYWNlbWVudCA/IHBsYWNlbWVudCA6IG51bGxcIlxuXHRcdFx0W25nQ2xhc3NdPVwieydjZHMtLW92ZXJmbG93LW1lbnUtLWZsaXAnOiBkaWFsb2dDb25maWcuZmxpcH1cIlxuXHRcdFx0cm9sZT1cIm1lbnVcIlxuXHRcdFx0I2RpYWxvZ1xuXHRcdFx0Y2xhc3M9XCJjZHMtLW92ZXJmbG93LW1lbnUtb3B0aW9ucyBjZHMtLW92ZXJmbG93LW1lbnUtb3B0aW9ucy0tb3BlblwiXG5cdFx0XHQoY2xpY2spPVwib25DbG9zZSgkZXZlbnQpXCJcblx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwiZGlhbG9nQ29uZmlnLm1lbnVMYWJlbFwiPlxuXHRcdFx0PG5nLXRlbXBsYXRlXG5cdFx0XHRcdFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRpYWxvZ0NvbmZpZy5jb250ZW50XCJcblx0XHRcdFx0W25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntvdmVyZmxvd01lbnU6IHRoaXN9XCI+XG5cdFx0XHQ8L25nLXRlbXBsYXRlPlxuXHRcdDwvdWw+XG5cdGBcbn0pXG5leHBvcnQgY2xhc3MgT3ZlcmZsb3dNZW51UGFuZSBleHRlbmRzIERpYWxvZyBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZixcblx0XHRwcm90ZWN0ZWQgaTE4bjogSTE4bixcblx0XHRwcm90ZWN0ZWQgZXhwZXJpbWVudGFsOiBFeHBlcmltZW50YWxTZXJ2aWNlLFxuXHRcdEBPcHRpb25hbCgpIHByb3RlY3RlZCBhbmltYXRpb25GcmFtZVNlcnZpY2U6IEFuaW1hdGlvbkZyYW1lU2VydmljZSA9IG51bGwsXG5cdFx0Ly8gbWFyayBgZWxlbWVudFNlcnZpY2VgIGFzIG9wdGlvbmFsIHNpbmNlIG1ha2luZyBpdCBtYW5kYXRvcnkgd291bGQgYmUgYSBicmVha2luZyBjaGFuZ2Vcblx0XHRAT3B0aW9uYWwoKSBwcm90ZWN0ZWQgZWxlbWVudFNlcnZpY2U6IEVsZW1lbnRTZXJ2aWNlID0gbnVsbCkge1xuXHRcdHN1cGVyKGVsZW1lbnRSZWYsIGVsZW1lbnRTZXJ2aWNlLCBhbmltYXRpb25GcmFtZVNlcnZpY2UpO1xuXHR9XG5cblx0b25EaWFsb2dJbml0KCkge1xuXHRcdGNvbnN0IHBvc2l0aW9uT3ZlcmZsb3dNZW51ID0gcG9zID0+IHtcblx0XHRcdGxldCBvZmZzZXQ7XG5cdFx0XHQvKlxuXHRcdFx0KiAyMCBpcyBoYWxmIHRoZSB3aWR0aCBvZiB0aGUgb3ZlcmZsb3cgbWVudSB0cmlnZ2VyIGVsZW1lbnQuXG5cdFx0XHQqIHdlIGFsc28gbW92ZSB0aGUgZWxlbWVudCBieSBoYWxmIG9mIGl0J3Mgb3duIHdpZHRoLCBzaW5jZVxuXHRcdFx0KiBwb3NpdGlvbiBzZXJ2aWNlIHdpbGwgdHJ5IGFuZCBjZW50ZXIgZXZlcnl0aGluZ1xuXHRcdFx0Ki9cblx0XHRcdGNvbnN0IGNsb3Nlc3RSZWwgPSBjbG9zZXN0QXR0cihcInBvc2l0aW9uXCIsIFtcInJlbGF0aXZlXCIsIFwiZml4ZWRcIiwgXCJhYnNvbHV0ZVwiXSwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuXHRcdFx0Y29uc3QgdG9wRml4ID0gY2xvc2VzdFJlbCA/IGNsb3Nlc3RSZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wICogLTEgOiAwO1xuXHRcdFx0Y29uc3QgbGVmdEZpeCA9IGNsb3Nlc3RSZWwgPyBjbG9zZXN0UmVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgKiAtMSA6IDA7XG5cblx0XHRcdG9mZnNldCA9IE1hdGgucm91bmQodGhpcy5kaWFsb2cubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCAvIDIpIC0gMjA7XG5cdFx0XHRpZiAodGhpcy5kaWFsb2dDb25maWcuZmxpcCkge1xuXHRcdFx0XHRyZXR1cm4gcG9zaXRpb24uYWRkT2Zmc2V0KHBvcywgdG9wRml4LCAoLW9mZnNldCArIGxlZnRGaXgpKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBwb3NpdGlvbi5hZGRPZmZzZXQocG9zLCB0b3BGaXgsIChvZmZzZXQgKyBsZWZ0Rml4KSk7XG5cdFx0fTtcblxuXHRcdHRoaXMuYWRkR2FwW1wiYm90dG9tXCJdID0gcG9zaXRpb25PdmVyZmxvd01lbnU7XG5cblx0XHR0aGlzLmFkZEdhcFtcInRvcFwiXSA9IHBvc2l0aW9uT3ZlcmZsb3dNZW51O1xuXG5cdFx0aWYgKCF0aGlzLmRpYWxvZ0NvbmZpZy5tZW51TGFiZWwpIHtcblx0XHRcdHRoaXMuZGlhbG9nQ29uZmlnLm1lbnVMYWJlbCA9IHRoaXMuaTE4bi5nZXQoKS5PVkVSRkxPV19NRU5VLk9WRVJGTE9XO1xuXHRcdH1cblx0fVxuXG5cdEBIb3N0TGlzdGVuZXIoXCJrZXlkb3duXCIsIFtcIiRldmVudFwiXSlcblx0aG9zdGtleXMoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcblx0XHRjb25zdCBsaXN0SXRlbXMgPSB0aGlzLmxpc3RJdGVtcygpO1xuXG5cdFx0c3dpdGNoIChldmVudC5rZXkpIHtcblx0XHRcdGNhc2UgXCJBcnJvd0Rvd25cIjpcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0aWYgKCFpc0ZvY3VzSW5MYXN0SXRlbShldmVudCwgbGlzdEl0ZW1zKSkgIHtcblx0XHRcdFx0XHRjb25zdCBpbmRleCA9IGxpc3RJdGVtcy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtID09PSBldmVudC50YXJnZXQpO1xuXHRcdFx0XHRcdGxpc3RJdGVtc1tpbmRleCArIDFdLmZvY3VzKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bGlzdEl0ZW1zWzBdLmZvY3VzKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgXCJBcnJvd1VwXCI6XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGlmICghaXNGb2N1c0luRmlyc3RJdGVtKGV2ZW50LCBsaXN0SXRlbXMpKSAge1xuXHRcdFx0XHRcdGNvbnN0IGluZGV4ID0gbGlzdEl0ZW1zLmZpbmRJbmRleChpdGVtID0+IGl0ZW0gPT09IGV2ZW50LnRhcmdldCk7XG5cdFx0XHRcdFx0bGlzdEl0ZW1zW2luZGV4IC0gMV0uZm9jdXMoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsaXN0SXRlbXNbbGlzdEl0ZW1zLmxlbmd0aCAtIDFdLmZvY3VzKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdGNhc2UgXCJIb21lXCI6XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGxpc3RJdGVtc1swXS5mb2N1cygpO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0Y2FzZSBcIkVuZFwiOlxuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRsaXN0SXRlbXNbbGlzdEl0ZW1zLmxlbmd0aCAtIDFdLmZvY3VzKCk7XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlIFwiRXNjYXBlXCI6XG5cdFx0XHRjYXNlIFwiVGFiXCI6XG5cdFx0XHRcdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHR0aGlzLmRvQ2xvc2Uoe1xuXHRcdFx0XHRcdHJlYXNvbjogQ2xvc2VSZWFzb25zLmludGVyYWN0aW9uLFxuXHRcdFx0XHRcdHRhcmdldDogZXZlbnQudGFyZ2V0XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6IGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdG9uQ2xvc2UoZXZlbnQpIHtcblx0XHR0aGlzLmRvQ2xvc2Uoe1xuXHRcdFx0cmVhc29uOiBDbG9zZVJlYXNvbnMuaW50ZXJhY3Rpb24sXG5cdFx0XHR0YXJnZXQ6IGV2ZW50LnRhcmdldFxuXHRcdH0pO1xuXHR9XG5cblx0YWZ0ZXJEaWFsb2dWaWV3SW5pdCgpIHtcblx0XHRjb25zdCBmb2N1c0VsZW1lbnRMaXN0ID0gdGhpcy5saXN0SXRlbXMoKTtcblx0XHRmb2N1c0VsZW1lbnRMaXN0LmZvckVhY2goYnV0dG9uID0+IHtcblx0XHRcdC8vIEFsbG93cyB1c2VyIHRvIHNldCB0YWJpbmRleCB0byAwLlxuXHRcdFx0aWYgKGJ1dHRvbi5nZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKSA9PT0gbnVsbCkge1xuXHRcdFx0XHRidXR0b24udGFiSW5kZXggPSAtMTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpZiAoZm9jdXNFbGVtZW50TGlzdFswXSkge1xuXHRcdFx0Zm9jdXNFbGVtZW50TGlzdFswXS50YWJJbmRleCA9IDA7XG5cdFx0XHRmb2N1c0VsZW1lbnRMaXN0WzBdLmZvY3VzKCk7XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIGxpc3RJdGVtcygpIHtcblx0XHRjb25zdCBzZWxlY3RvciA9IFwiLmNkcy0tb3ZlcmZsb3ctbWVudS1vcHRpb25zX19vcHRpb246bm90KFtkaXNhYmxlZF0pIC5jZHMtLW92ZXJmbG93LW1lbnUtb3B0aW9uc19fYnRuXCI7XG5cdFx0cmV0dXJuIEFycmF5LmZyb208SFRNTEVsZW1lbnQ+KHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTtcblx0fVxufVxuIl19