@clr/angular
Version:
Angular components for Clarity
185 lines • 28.9 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { isPlatformBrowser } from '@angular/common';
import { Inject, Injectable, Optional, PLATFORM_ID, SkipSelf } from '@angular/core';
import { of, ReplaySubject } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { ArrowKeyDirection } from '../../../utils/focus/arrow-key-direction.enum';
import { customFocusableItemProvider } from '../../../utils/focus/focusable-item/custom-focusable-item-provider';
import { Linkers } from '../../../utils/focus/focusable-item/linkers';
import { wrapObservable } from '../../../utils/focus/wrap-observable';
import { uniqueIdFactory } from '../../../utils/id-generator/id-generator.service';
import * as i0 from "@angular/core";
import * as i1 from "../../../utils/popover/providers/popover-toggle.service";
import * as i2 from "../../../utils/focus/focus.service";
export class DropdownFocusHandler {
constructor(renderer, parent, toggleService, focusService, platformId) {
this.renderer = renderer;
this.parent = parent;
this.toggleService = toggleService;
this.focusService = focusService;
this.platformId = platformId;
this.id = uniqueIdFactory();
this.focusBackOnTriggerWhenClosed = false;
this._unlistenFuncs = [];
this.resetChildren();
this.moveToFirstItemWhenOpen();
if (!this.parent) {
this.handleRootFocus();
}
}
get trigger() {
return this._trigger;
}
set trigger(el) {
this._trigger = el;
if (this.parent) {
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowright', event => this.toggleService.toggleWithEvent(event)));
}
else {
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowup', event => this.toggleService.toggleWithEvent(event)));
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.arrowdown', event => this.toggleService.toggleWithEvent(event)));
this.focusService.listenToArrowKeys(el);
}
}
get container() {
return this._container;
}
set container(el) {
this._container = el;
// whether root container or not, tab key should always toggle (i.e. close) the container
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.tab', event => this.toggleService.toggleWithEvent(event)));
if (this.parent) {
// if it's a nested container, pressing escape has the same effect as pressing left key, which closes the current
// popup and moves up to its parent. Here, we stop propagation so that the parent container
// doesn't receive the escape keydown
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.escape', event => {
this.focusService.move(ArrowKeyDirection.LEFT);
event.stopPropagation();
}));
}
else {
// The root container is the only one we register to the focus service, others do not need focus
this.focusService.registerContainer(el);
// The root container will simply close the container when escape key is pressed
this._unlistenFuncs.push(this.renderer.listen(el, 'keydown.escape', event => this.toggleService.toggleWithEvent(event)));
// When the user moves focus outside of the menu, we close the dropdown
this._unlistenFuncs.push(this.renderer.listen(el, 'blur', event => {
// we clear out any existing focus on the items
this.children.pipe(take(1)).subscribe(items => items.forEach(item => item.blur()));
// event.relatedTarget is null in IE11. In that case we use document.activeElement which correctly points
// to the element we want to check. Note that other browsers might point document.activeElement to the
// wrong element. This is ok, because all the other browsers we support relies on event.relatedTarget.
const target = event.relatedTarget || document.activeElement;
// If the user clicks on an item which triggers the blur, we don't want to close it since it may open a submenu.
// In the case of needing to close it (i.e. user selected an item and the dropdown menu is set to close on
// selection), dropdown-item.ts handles it.
if (target && isPlatformBrowser(this.platformId)) {
if (el.contains(target) || target === this.trigger) {
return;
}
}
// We let the user move focus to where the want, we don't force the focus back on the trigger
this.focusBackOnTriggerWhenClosed = false;
this.toggleService.open = false;
}));
}
}
ngOnDestroy() {
this._unlistenFuncs.forEach((unlisten) => unlisten());
this.focusService.detachListeners();
}
/**
* If the dropdown was opened by clicking on the trigger, we automatically move to the first item
*/
moveToFirstItemWhenOpen() {
const subscription = this.toggleService.openChange.subscribe(open => {
if (open && this.toggleService.originalEvent) {
// Even if we properly waited for ngAfterViewInit, the container still wouldn't be attached to the DOM.
// So setTimeout is the only way to wait for the container to be ready to move focus to first item.
setTimeout(() => {
this.focusService.moveTo(this);
if (this.parent) {
this.focusService.move(ArrowKeyDirection.RIGHT);
}
else {
this.focusService.move(ArrowKeyDirection.DOWN);
}
});
}
});
this._unlistenFuncs.push(() => subscription.unsubscribe());
}
/**
* Focus on the menu when it opens, and focus back on the root trigger when the whole dropdown becomes closed
*/
handleRootFocus() {
const subscription = this.toggleService.openChange.subscribe(open => {
if (!open) {
// We reset the state of the focus service both on initialization and when closing.
this.focusService.reset(this);
// But we only actively focus the trigger when closing, not on initialization.
if (this.focusBackOnTriggerWhenClosed) {
this.focus();
}
}
this.focusBackOnTriggerWhenClosed = open;
});
this._unlistenFuncs.push(() => subscription.unsubscribe());
}
focus() {
if (this.trigger && isPlatformBrowser(this.platformId)) {
this.trigger.focus();
}
}
blur() {
if (this.trigger && isPlatformBrowser(this.platformId)) {
this.trigger.blur();
}
}
activate() {
if (isPlatformBrowser(this.platformId)) {
this.trigger.click();
}
}
resetChildren() {
this.children = new ReplaySubject(1);
if (this.parent) {
this.right = this.openAndGetChildren().pipe(map(all => all[0]));
}
else {
this.down = this.openAndGetChildren().pipe(map(all => all[0]));
this.up = this.openAndGetChildren().pipe(map(all => all[all.length - 1]));
}
}
addChildren(children) {
Linkers.linkVertical(children);
if (this.parent) {
Linkers.linkParent(children, this.closeAndGetThis(), ArrowKeyDirection.LEFT);
}
this.children.next(children);
}
openAndGetChildren() {
return wrapObservable(this.children, () => (this.toggleService.open = true));
}
closeAndGetThis() {
return wrapObservable(of(this), () => (this.toggleService.open = false));
}
}
DropdownFocusHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DropdownFocusHandler, deps: [{ token: i0.Renderer2 }, { token: DropdownFocusHandler, optional: true, skipSelf: true }, { token: i1.ClrPopoverToggleService }, { token: i2.FocusService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
DropdownFocusHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DropdownFocusHandler });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: DropdownFocusHandler, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: DropdownFocusHandler, decorators: [{
type: SkipSelf
}, {
type: Optional
}] }, { type: i1.ClrPopoverToggleService }, { type: i2.FocusService }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }]; } });
export const DROPDOWN_FOCUS_HANDLER_PROVIDER = customFocusableItemProvider(DropdownFocusHandler);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24tZm9jdXMtaGFuZGxlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvcG9wb3Zlci9kcm9wZG93bi9wcm92aWRlcnMvZHJvcGRvd24tZm9jdXMtaGFuZGxlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBYSxRQUFRLEVBQUUsV0FBVyxFQUFhLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQWMsRUFBRSxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBRWxGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLG9FQUFvRSxDQUFDO0FBRWpILE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUN0RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtEQUFrRCxDQUFDOzs7O0FBSW5GLE1BQU0sT0FBTyxvQkFBb0I7SUFhL0IsWUFDVSxRQUFtQixFQUduQixNQUE0QixFQUM1QixhQUFzQyxFQUN0QyxZQUEwQixFQUNMLFVBQWU7UUFOcEMsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUduQixXQUFNLEdBQU4sTUFBTSxDQUFzQjtRQUM1QixrQkFBYSxHQUFiLGFBQWEsQ0FBeUI7UUFDdEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDTCxlQUFVLEdBQVYsVUFBVSxDQUFLO1FBbkI5QyxP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QUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzNFO0lBQ0gsQ0FBQztJQUVELFdBQVcsQ0FBQyxRQUF5QjtRQUNuQyxPQUFPLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM5RTtRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFTyxrQkFBa0I7UUFDeEIsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVPLGVBQWU7UUFDckIsT0FBTyxjQUFjLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMzRSxDQUFDOztpSEFuTVUsb0JBQW9CLCtLQW9CckIsV0FBVztxSEFwQlYsb0JBQW9COzJGQUFwQixvQkFBb0I7a0JBRGhDLFVBQVU7OzBCQWdCTixRQUFROzswQkFDUixRQUFROzswQkFJUixNQUFNOzJCQUFDLFdBQVc7O0FBa0x2QixNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRywyQkFBMkIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDIzIFZNd2FyZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZS5cbiAqIFRoZSBmdWxsIGxpY2Vuc2UgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIExJQ0VOU0UgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgcHJvamVjdC5cbiAqL1xuXG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9uRGVzdHJveSwgT3B0aW9uYWwsIFBMQVRGT1JNX0lELCBSZW5kZXJlcjIsIFNraXBTZWxmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiwgUmVwbGF5U3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBBcnJvd0tleURpcmVjdGlvbiB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ZvY3VzL2Fycm93LWtleS1kaXJlY3Rpb24uZW51bSc7XG5pbXBvcnQgeyBGb2N1c1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi91dGlscy9mb2N1cy9mb2N1cy5zZXJ2aWNlJztcbmltcG9ydCB7IGN1c3RvbUZvY3VzYWJsZUl0ZW1Qcm92aWRlciB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ZvY3VzL2ZvY3VzYWJsZS1pdGVtL2N1c3RvbS1mb2N1c2FibGUtaXRlbS1wcm92aWRlcic7XG5pbXBvcnQgeyBGb2N1c2FibGVJdGVtIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvZm9jdXMvZm9jdXNhYmxlLWl0ZW0vZm9jdXNhYmxlLWl0ZW0nO1xuaW1wb3J0IHsgTGlua2VycyB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ZvY3VzL2ZvY3VzYWJsZS1pdGVtL2xpbmtlcnMnO1xuaW1wb3J0IHsgd3JhcE9ic2VydmFibGUgfSBmcm9tICcuLi8uLi8uLi91dGlscy9mb2N1cy93cmFwLW9ic2VydmFibGUnO1xuaW1wb3J0IHsgdW5pcXVlSWRGYWN0b3J5IH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvaWQtZ2VuZXJhdG9yL2lkLWdlbmVyYXRvci5zZXJ2aWNlJztcbmltcG9ydCB7IENsclBvcG92ZXJUb2dnbGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvcG9wb3Zlci9wcm92aWRlcnMvcG9wb3Zlci10b2dnbGUuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEcm9wZG93bkZvY3VzSGFuZGxlciBpbXBsZW1lbnRzIE9uRGVzdHJveSwgRm9jdXNhYmxlSXRlbSB7XG4gIGlkID0gdW5pcXVlSWRGYWN0b3J5KCk7XG4gIGZvY3VzQmFja09uVHJpZ2dlcldoZW5DbG9zZWQgPSBmYWxzZTtcblxuICByaWdodD86IE9ic2VydmFibGU8Rm9jdXNhYmxlSXRlbT47XG4gIGRvd24/OiBPYnNlcnZhYmxlPEZvY3VzYWJsZUl0ZW0+O1xuICB1cD86IE9ic2VydmFibGU8Rm9jdXNhYmxlSXRlbT47XG5cbiAgcHJpdmF0ZSBfdHJpZ2dlcjogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgX2NvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgY2hpbGRyZW46IFJlcGxheVN1YmplY3Q8Rm9jdXNhYmxlSXRlbVtdPjtcbiAgcHJpdmF0ZSBfdW5saXN0ZW5GdW5jczogKCgpID0+IHZvaWQpW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQFNraXBTZWxmKClcbiAgICBAT3B0aW9uYWwoKVxuICAgIHByaXZhdGUgcGFyZW50OiBEcm9wZG93bkZvY3VzSGFuZGxlcixcbiAgICBwcml2YXRlIHRvZ2dsZVNlcnZpY2U6IENsclBvcG92ZXJUb2dnbGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgZm9jdXNTZXJ2aWNlOiBGb2N1c1NlcnZpY2UsXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBhbnlcbiAgKSB7XG4gICAgdGhpcy5yZXNldENoaWxkcmVuKCk7XG4gICAgdGhpcy5tb3ZlVG9GaXJzdEl0ZW1XaGVuT3BlbigpO1xuICAgIGlmICghdGhpcy5wYXJlbnQpIHtcbiAgICAgIHRoaXMuaGFuZGxlUm9vdEZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHRyaWdnZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RyaWdnZXI7XG4gIH1cbiAgc2V0IHRyaWdnZXIoZWw6IEhUTUxFbGVtZW50KSB7XG4gICAgdGhpcy5fdHJpZ2dlciA9IGVsO1xuXG4gICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2goXG4gICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGVsLCAna2V5ZG93bi5hcnJvd3JpZ2h0JywgZXZlbnQgPT4gdGhpcy50b2dnbGVTZXJ2aWNlLnRvZ2dsZVdpdGhFdmVudChldmVudCkpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2goXG4gICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGVsLCAna2V5ZG93bi5hcnJvd3VwJywgZXZlbnQgPT4gdGhpcy50b2dnbGVTZXJ2aWNlLnRvZ2dsZVdpdGhFdmVudChldmVudCkpXG4gICAgICApO1xuICAgICAgdGhpcy5fdW5saXN0ZW5GdW5jcy5wdXNoKFxuICAgICAgICB0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24uYXJyb3dkb3duJywgZXZlbnQgPT4gdGhpcy50b2dnbGVTZXJ2aWNlLnRvZ2dsZVdpdGhFdmVudChldmVudCkpXG4gICAgICApO1xuICAgICAgdGhpcy5mb2N1c1NlcnZpY2UubGlzdGVuVG9BcnJvd0tleXMoZWwpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBjb250YWluZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbnRhaW5lcjtcbiAgfVxuICBzZXQgY29udGFpbmVyKGVsOiBIVE1MRWxlbWVudCkge1xuICAgIHRoaXMuX2NvbnRhaW5lciA9IGVsO1xuXG4gICAgLy8gd2hldGhlciByb290IGNvbnRhaW5lciBvciBub3QsIHRhYiBrZXkgc2hvdWxkIGFsd2F5cyB0b2dnbGUgKGkuZS4gY2xvc2UpIHRoZSBjb250YWluZXJcbiAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2goXG4gICAgICB0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2tleWRvd24udGFiJywgZXZlbnQgPT4gdGhpcy50b2dnbGVTZXJ2aWNlLnRvZ2dsZVdpdGhFdmVudChldmVudCkpXG4gICAgKTtcblxuICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgLy8gaWYgaXQncyBhIG5lc3RlZCBjb250YWluZXIsIHByZXNzaW5nIGVzY2FwZSBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIHByZXNzaW5nIGxlZnQga2V5LCB3aGljaCBjbG9zZXMgdGhlIGN1cnJlbnRcbiAgICAgIC8vIHBvcHVwIGFuZCBtb3ZlcyB1cCB0byBpdHMgcGFyZW50LiBIZXJlLCB3ZSBzdG9wIHByb3BhZ2F0aW9uIHNvIHRoYXQgdGhlIHBhcmVudCBjb250YWluZXJcbiAgICAgIC8vIGRvZXNuJ3QgcmVjZWl2ZSB0aGUgZXNjYXBlIGtleWRvd25cbiAgICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaChcbiAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oZWwsICdrZXlkb3duLmVzY2FwZScsIGV2ZW50ID0+IHtcbiAgICAgICAgICB0aGlzLmZvY3VzU2VydmljZS5tb3ZlKEFycm93S2V5RGlyZWN0aW9uLkxFRlQpO1xuICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHJvb3QgY29udGFpbmVyIGlzIHRoZSBvbmx5IG9uZSB3ZSByZWdpc3RlciB0byB0aGUgZm9jdXMgc2VydmljZSwgb3RoZXJzIGRvIG5vdCBuZWVkIGZvY3VzXG4gICAgICB0aGlzLmZvY3VzU2VydmljZS5yZWdpc3RlckNvbnRhaW5lcihlbCk7XG5cbiAgICAgIC8vIFRoZSByb290IGNvbnRhaW5lciB3aWxsIHNpbXBseSBjbG9zZSB0aGUgY29udGFpbmVyIHdoZW4gZXNjYXBlIGtleSBpcyBwcmVzc2VkXG4gICAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2goXG4gICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGVsLCAna2V5ZG93bi5lc2NhcGUnLCBldmVudCA9PiB0aGlzLnRvZ2dsZVNlcnZpY2UudG9nZ2xlV2l0aEV2ZW50KGV2ZW50KSlcbiAgICAgICk7XG5cbiAgICAgIC8vIFdoZW4gdGhlIHVzZXIgbW92ZXMgZm9jdXMgb3V0c2lkZSBvZiB0aGUgbWVudSwgd2UgY2xvc2UgdGhlIGRyb3Bkb3duXG4gICAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2goXG4gICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGVsLCAnYmx1cicsIGV2ZW50ID0+IHtcbiAgICAgICAgICAvLyB3ZSBjbGVhciBvdXQgYW55IGV4aXN0aW5nIGZvY3VzIG9uIHRoZSBpdGVtc1xuICAgICAgICAgIHRoaXMuY2hpbGRyZW4ucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoaXRlbXMgPT4gaXRlbXMuZm9yRWFjaChpdGVtID0+IGl0ZW0uYmx1cigpKSk7XG5cbiAgICAgICAgICAvLyBldmVudC5yZWxhdGVkVGFyZ2V0IGlzIG51bGwgaW4gSUUxMS4gSW4gdGhhdCBjYXNlIHdlIHVzZSBkb2N1bWVudC5hY3RpdmVFbGVtZW50IHdoaWNoIGNvcnJlY3RseSBwb2ludHNcbiAgICAgICAgICAvLyB0byB0aGUgZWxlbWVudCB3ZSB3YW50IHRvIGNoZWNrLiBOb3RlIHRoYXQgb3RoZXIgYnJvd3NlcnMgbWlnaHQgcG9pbnQgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCB0byB0aGVcbiAgICAgICAgICAvLyB3cm9uZyBlbGVtZW50LiBUaGlzIGlzIG9rLCBiZWNhdXNlIGFsbCB0aGUgb3RoZXIgYnJvd3NlcnMgd2Ugc3VwcG9ydCByZWxpZXMgb24gZXZlbnQucmVsYXRlZFRhcmdldC5cbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBldmVudC5yZWxhdGVkVGFyZ2V0IHx8IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgICAvLyBJZiB0aGUgdXNlciBjbGlja3Mgb24gYW4gaXRlbSB3aGljaCB0cmlnZ2VycyB0aGUgYmx1ciwgd2UgZG9uJ3Qgd2FudCB0byBjbG9zZSBpdCBzaW5jZSBpdCBtYXkgb3BlbiBhIHN1Ym1lbnUuXG4gICAgICAgICAgLy8gSW4gdGhlIGNhc2Ugb2YgbmVlZGluZyB0byBjbG9zZSBpdCAoaS5lLiB1c2VyIHNlbGVjdGVkIGFuIGl0ZW0gYW5kIHRoZSBkcm9wZG93biBtZW51IGlzIHNldCB0byBjbG9zZSBvblxuICAgICAgICAgIC8vIHNlbGVjdGlvbiksIGRyb3Bkb3duLWl0ZW0udHMgaGFuZGxlcyBpdC5cbiAgICAgICAgICBpZiAodGFyZ2V0ICYmIGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIGlmIChlbC5jb250YWlucyh0YXJnZXQpIHx8IHRhcmdldCA9PT0gdGhpcy50cmlnZ2VyKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gV2UgbGV0IHRoZSB1c2VyIG1vdmUgZm9jdXMgdG8gd2hlcmUgdGhlIHdhbnQsIHdlIGRvbid0IGZvcmNlIHRoZSBmb2N1cyBiYWNrIG9uIHRoZSB0cmlnZ2VyXG4gICAgICAgICAgdGhpcy5mb2N1c0JhY2tPblRyaWdnZXJXaGVuQ2xvc2VkID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy50b2dnbGVTZXJ2aWNlLm9wZW4gPSBmYWxzZTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fdW5saXN0ZW5GdW5jcy5mb3JFYWNoKCh1bmxpc3RlbjogKCkgPT4gdm9pZCkgPT4gdW5saXN0ZW4oKSk7XG4gICAgdGhpcy5mb2N1c1NlcnZpY2UuZGV0YWNoTGlzdGVuZXJzKCk7XG4gIH1cblxuICAvKipcbiAgICogSWYgdGhlIGRyb3Bkb3duIHdhcyBvcGVuZWQgYnkgY2xpY2tpbmcgb24gdGhlIHRyaWdnZXIsIHdlIGF1dG9tYXRpY2FsbHkgbW92ZSB0byB0aGUgZmlyc3QgaXRlbVxuICAgKi9cbiAgbW92ZVRvRmlyc3RJdGVtV2hlbk9wZW4oKSB7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gdGhpcy50b2dnbGVTZXJ2aWNlLm9wZW5DaGFuZ2Uuc3Vic2NyaWJlKG9wZW4gPT4ge1xuICAgICAgaWYgKG9wZW4gJiYgdGhpcy50b2dnbGVTZXJ2aWNlLm9yaWdpbmFsRXZlbnQpIHtcbiAgICAgICAgLy8gRXZlbiBpZiB3ZSBwcm9wZXJseSB3YWl0ZWQgZm9yIG5nQWZ0ZXJWaWV3SW5pdCwgdGhlIGNvbnRhaW5lciBzdGlsbCB3b3VsZG4ndCBiZSBhdHRhY2hlZCB0byB0aGUgRE9NLlxuICAgICAgICAvLyBTbyBzZXRUaW1lb3V0IGlzIHRoZSBvbmx5IHdheSB0byB3YWl0IGZvciB0aGUgY29udGFpbmVyIHRvIGJlIHJlYWR5IHRvIG1vdmUgZm9jdXMgdG8gZmlyc3QgaXRlbS5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5mb2N1c1NlcnZpY2UubW92ZVRvKHRoaXMpO1xuICAgICAgICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c1NlcnZpY2UubW92ZShBcnJvd0tleURpcmVjdGlvbi5SSUdIVCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNTZXJ2aWNlLm1vdmUoQXJyb3dLZXlEaXJlY3Rpb24uRE9XTik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuX3VubGlzdGVuRnVuY3MucHVzaCgoKSA9PiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKSk7XG4gIH1cblxuICAvKipcbiAgICogRm9jdXMgb24gdGhlIG1lbnUgd2hlbiBpdCBvcGVucywgYW5kIGZvY3VzIGJhY2sgb24gdGhlIHJvb3QgdHJpZ2dlciB3aGVuIHRoZSB3aG9sZSBkcm9wZG93biBiZWNvbWVzIGNsb3NlZFxuICAgKi9cbiAgaGFuZGxlUm9vdEZvY3VzKCkge1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHRoaXMudG9nZ2xlU2VydmljZS5vcGVuQ2hhbmdlLnN1YnNjcmliZShvcGVuID0+IHtcbiAgICAgIGlmICghb3Blbikge1xuICAgICAgICAvLyBXZSByZXNldCB0aGUgc3RhdGUgb2YgdGhlIGZvY3VzIHNlcnZpY2UgYm90aCBvbiBpbml0aWFsaXphdGlvbiBhbmQgd2hlbiBjbG9zaW5nLlxuICAgICAgICB0aGlzLmZvY3VzU2VydmljZS5yZXNldCh0aGlzKTtcbiAgICAgICAgLy8gQnV0IHdlIG9ubHkgYWN0aXZlbHkgZm9jdXMgdGhlIHRyaWdnZXIgd2hlbiBjbG9zaW5nLCBub3Qgb24gaW5pdGlhbGl6YXRpb24uXG4gICAgICAgIGlmICh0aGlzLmZvY3VzQmFja09uVHJpZ2dlcldoZW5DbG9zZWQpIHtcbiAgICAgICAgICB0aGlzLmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuZm9jdXNCYWNrT25UcmlnZ2VyV2hlbkNsb3NlZCA9IG9wZW47XG4gICAgfSk7XG5cbiAgICB0aGlzLl91bmxpc3RlbkZ1bmNzLnB1c2goKCkgPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuICB9XG5cbiAgZm9jdXMoKSB7XG4gICAgaWYgKHRoaXMudHJpZ2dlciAmJiBpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICB0aGlzLnRyaWdnZXIuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBibHVyKCkge1xuICAgIGlmICh0aGlzLnRyaWdnZXIgJiYgaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgdGhpcy50cmlnZ2VyLmJsdXIoKTtcbiAgICB9XG4gIH1cblxuICBhY3RpdmF0ZSgpIHtcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgdGhpcy50cmlnZ2VyLmNsaWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcmVzZXRDaGlsZHJlbigpIHtcbiAgICB0aGlzLmNoaWxkcmVuID0gbmV3IFJlcGxheVN1YmplY3Q8Rm9jdXNhYmxlSXRlbVtdPigxKTtcbiAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgIHRoaXMucmlnaHQgPSB0aGlzLm9wZW5BbmRHZXRDaGlsZHJlbigpLnBpcGUobWFwKGFsbCA9PiBhbGxbMF0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kb3duID0gdGhpcy5vcGVuQW5kR2V0Q2hpbGRyZW4oKS5waXBlKG1hcChhbGwgPT4gYWxsWzBdKSk7XG4gICAgICB0aGlzLnVwID0gdGhpcy5vcGVuQW5kR2V0Q2hpbGRyZW4oKS5waXBlKG1hcChhbGwgPT4gYWxsW2FsbC5sZW5ndGggLSAxXSkpO1xuICAgIH1cbiAgfVxuXG4gIGFkZENoaWxkcmVuKGNoaWxkcmVuOiBGb2N1c2FibGVJdGVtW10pIHtcbiAgICBMaW5rZXJzLmxpbmtWZXJ0aWNhbChjaGlsZHJlbik7XG4gICAgaWYgKHRoaXMucGFyZW50KSB7XG4gICAgICBMaW5rZXJzLmxpbmtQYXJlbnQoY2hpbGRyZW4sIHRoaXMuY2xvc2VBbmRHZXRUaGlzKCksIEFycm93S2V5RGlyZWN0aW9uLkxFRlQpO1xuICAgIH1cbiAgICB0aGlzLmNoaWxkcmVuLm5leHQoY2hpbGRyZW4pO1xuICB9XG5cbiAgcHJpdmF0ZSBvcGVuQW5kR2V0Q2hpbGRyZW4oKSB7XG4gICAgcmV0dXJuIHdyYXBPYnNlcnZhYmxlKHRoaXMuY2hpbGRyZW4sICgpID0+ICh0aGlzLnRvZ2dsZVNlcnZpY2Uub3BlbiA9IHRydWUpKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VBbmRHZXRUaGlzKCkge1xuICAgIHJldHVybiB3cmFwT2JzZXJ2YWJsZShvZih0aGlzKSwgKCkgPT4gKHRoaXMudG9nZ2xlU2VydmljZS5vcGVuID0gZmFsc2UpKTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgRFJPUERPV05fRk9DVVNfSEFORExFUl9QUk9WSURFUiA9IGN1c3RvbUZvY3VzYWJsZUl0ZW1Qcm92aWRlcihEcm9wZG93bkZvY3VzSGFuZGxlcik7XG4iXX0=