@ng-bootstrap/ng-bootstrap
Version:
Angular powered Bootstrap
535 lines • 73 kB
JavaScript
import { ContentChild, ContentChildren, Directive, EventEmitter, forwardRef, Inject, Input, Output, } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { fromEvent, Subject } from 'rxjs';
import { take } from 'rxjs/operators';
import { ngbPositioning } from '../util/positioning';
import { addPopperOffset } from '../util/positioning-util';
import { ngbAutoClose } from '../util/autoclose';
import { Key } from '../util/key';
import { FOCUSABLE_ELEMENTS_SELECTOR } from '../util/focus-trap';
import { getActiveElement } from '../util/util';
import * as i0 from "@angular/core";
import * as i1 from "./dropdown-config";
/**
* @deprecated 14.2.0 this directive isn't useful anymore. You can remove it from your imports
*/
class NgbNavbar {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavbar, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbNavbar, isStandalone: true, selector: ".navbar", ngImport: i0 }); }
}
export { NgbNavbar };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbNavbar, decorators: [{
type: Directive,
args: [{ selector: '.navbar', standalone: true }]
}] });
/**
* A directive you should put on a dropdown item to enable keyboard navigation.
* Arrow keys will move focus between items marked with this directive.
*
* @since 4.1.0
*/
class NgbDropdownItem {
set disabled(value) {
this._disabled = value === '' || value === true; // accept an empty attribute as true
// note: we don't use a host binding for disabled because when used on links, it fails because links don't have a
// disabled property
// setting the property using the renderer, OTOH, works fine in both cases.
this._renderer.setProperty(this.elementRef.nativeElement, 'disabled', this._disabled);
}
get disabled() {
return this._disabled;
}
constructor(elementRef, _renderer) {
this.elementRef = elementRef;
this._renderer = _renderer;
this._disabled = false;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownItem, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbDropdownItem, isStandalone: true, selector: "[ngbDropdownItem]", inputs: { disabled: "disabled" }, host: { properties: { "class.disabled": "disabled", "tabIndex": "disabled ? -1 : 0" }, classAttribute: "dropdown-item" }, ngImport: i0 }); }
}
export { NgbDropdownItem };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownItem, decorators: [{
type: Directive,
args: [{
selector: '[ngbDropdownItem]',
standalone: true,
host: { class: 'dropdown-item', '[class.disabled]': 'disabled', '[tabIndex]': 'disabled ? -1 : 0' },
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { disabled: [{
type: Input
}] } });
/**
* A directive that wraps dropdown menu content and dropdown items.
*/
class NgbDropdownMenu {
constructor(dropdown, _elementRef) {
this.dropdown = dropdown;
this.placement = 'bottom';
this.isOpen = false;
this.nativeElement = _elementRef.nativeElement;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownMenu, deps: [{ token: forwardRef(() => NgbDropdown) }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbDropdownMenu, isStandalone: true, selector: "[ngbDropdownMenu]", host: { listeners: { "keydown.ArrowUp": "dropdown.onKeyDown($event)", "keydown.ArrowDown": "dropdown.onKeyDown($event)", "keydown.Home": "dropdown.onKeyDown($event)", "keydown.End": "dropdown.onKeyDown($event)", "keydown.Enter": "dropdown.onKeyDown($event)", "keydown.Space": "dropdown.onKeyDown($event)", "keydown.Tab": "dropdown.onKeyDown($event)", "keydown.Shift.Tab": "dropdown.onKeyDown($event)" }, properties: { "class.dropdown-menu": "true", "class.show": "dropdown.isOpen()" } }, queries: [{ propertyName: "menuItems", predicate: NgbDropdownItem }], ngImport: i0 }); }
}
export { NgbDropdownMenu };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownMenu, decorators: [{
type: Directive,
args: [{
selector: '[ngbDropdownMenu]',
standalone: true,
host: {
'[class.dropdown-menu]': 'true',
'[class.show]': 'dropdown.isOpen()',
'(keydown.ArrowUp)': 'dropdown.onKeyDown($event)',
'(keydown.ArrowDown)': 'dropdown.onKeyDown($event)',
'(keydown.Home)': 'dropdown.onKeyDown($event)',
'(keydown.End)': 'dropdown.onKeyDown($event)',
'(keydown.Enter)': 'dropdown.onKeyDown($event)',
'(keydown.Space)': 'dropdown.onKeyDown($event)',
'(keydown.Tab)': 'dropdown.onKeyDown($event)',
'(keydown.Shift.Tab)': 'dropdown.onKeyDown($event)',
},
}]
}], ctorParameters: function () { return [{ type: NgbDropdown, decorators: [{
type: Inject,
args: [forwardRef(() => NgbDropdown)]
}] }, { type: i0.ElementRef }]; }, propDecorators: { menuItems: [{
type: ContentChildren,
args: [NgbDropdownItem]
}] } });
/**
* A directive to mark an element to which dropdown menu will be anchored.
*
* This is a simple version of the `NgbDropdownToggle` directive.
* It plays the same role, but doesn't listen to click events to toggle dropdown menu thus enabling support
* for events other than click.
*
* @since 1.1.0
*/
class NgbDropdownAnchor {
constructor(dropdown, _elementRef) {
this.dropdown = dropdown;
this.nativeElement = _elementRef.nativeElement;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownAnchor, deps: [{ token: forwardRef(() => NgbDropdown) }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbDropdownAnchor, isStandalone: true, selector: "[ngbDropdownAnchor]", host: { properties: { "attr.aria-expanded": "dropdown.isOpen()" }, classAttribute: "dropdown-toggle" }, ngImport: i0 }); }
}
export { NgbDropdownAnchor };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownAnchor, decorators: [{
type: Directive,
args: [{
selector: '[ngbDropdownAnchor]',
standalone: true,
host: { class: 'dropdown-toggle', '[attr.aria-expanded]': 'dropdown.isOpen()' },
}]
}], ctorParameters: function () { return [{ type: NgbDropdown, decorators: [{
type: Inject,
args: [forwardRef(() => NgbDropdown)]
}] }, { type: i0.ElementRef }]; } });
/**
* A directive to mark an element that will toggle dropdown via the `click` event.
*
* You can also use `NgbDropdownAnchor` as an alternative.
*/
class NgbDropdownToggle extends NgbDropdownAnchor {
constructor(dropdown, elementRef) {
super(dropdown, elementRef);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownToggle, deps: [{ token: forwardRef(() => NgbDropdown) }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbDropdownToggle, isStandalone: true, selector: "[ngbDropdownToggle]", host: { listeners: { "click": "dropdown.toggle()", "keydown.ArrowUp": "dropdown.onKeyDown($event)", "keydown.ArrowDown": "dropdown.onKeyDown($event)", "keydown.Home": "dropdown.onKeyDown($event)", "keydown.End": "dropdown.onKeyDown($event)", "keydown.Tab": "dropdown.onKeyDown($event)", "keydown.Shift.Tab": "dropdown.onKeyDown($event)" }, properties: { "attr.aria-expanded": "dropdown.isOpen()" }, classAttribute: "dropdown-toggle" }, providers: [{ provide: NgbDropdownAnchor, useExisting: forwardRef(() => NgbDropdownToggle) }], usesInheritance: true, ngImport: i0 }); }
}
export { NgbDropdownToggle };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdownToggle, decorators: [{
type: Directive,
args: [{
selector: '[ngbDropdownToggle]',
standalone: true,
host: {
class: 'dropdown-toggle',
'[attr.aria-expanded]': 'dropdown.isOpen()',
'(click)': 'dropdown.toggle()',
'(keydown.ArrowUp)': 'dropdown.onKeyDown($event)',
'(keydown.ArrowDown)': 'dropdown.onKeyDown($event)',
'(keydown.Home)': 'dropdown.onKeyDown($event)',
'(keydown.End)': 'dropdown.onKeyDown($event)',
'(keydown.Tab)': 'dropdown.onKeyDown($event)',
'(keydown.Shift.Tab)': 'dropdown.onKeyDown($event)',
},
providers: [{ provide: NgbDropdownAnchor, useExisting: forwardRef(() => NgbDropdownToggle) }],
}]
}], ctorParameters: function () { return [{ type: NgbDropdown, decorators: [{
type: Inject,
args: [forwardRef(() => NgbDropdown)]
}] }, { type: i0.ElementRef }]; } });
/**
* A directive that provides contextual overlays for displaying lists of links and more.
*/
class NgbDropdown {
constructor(_changeDetector, config, _document, _ngZone, _elementRef, _renderer) {
this._changeDetector = _changeDetector;
this._document = _document;
this._ngZone = _ngZone;
this._elementRef = _elementRef;
this._renderer = _renderer;
this._destroyCloseHandlers$ = new Subject();
this._bodyContainer = null;
/**
* Defines whether or not the dropdown menu is opened initially.
*/
this._open = false;
/**
* An event fired when the dropdown is opened or closed.
*
* The event payload is a `boolean`:
* * `true` - the dropdown was opened
* * `false` - the dropdown was closed
*/
this.openChange = new EventEmitter();
this.placement = config.placement;
this.popperOptions = config.popperOptions;
this.container = config.container;
this.autoClose = config.autoClose;
this._positioning = ngbPositioning();
}
ngOnInit() {
if (!this.display) {
this.display = this._elementRef.nativeElement.closest('.navbar') ? 'static' : 'dynamic';
}
}
ngAfterContentInit() {
this._ngZone.onStable.pipe(take(1)).subscribe(() => {
this._applyPlacementClasses();
if (this._open) {
this._setCloseHandlers();
}
});
}
ngOnChanges(changes) {
if (changes.container && this._open) {
this._applyContainer(this.container);
}
if (changes.placement && !changes.placement.firstChange) {
this._positioning.setOptions({
hostElement: this._anchor.nativeElement,
targetElement: this._bodyContainer || this._menu.nativeElement,
placement: this.placement,
appendToBody: this.container === 'body',
});
this._applyPlacementClasses();
}
if (changes.dropdownClass) {
const { currentValue, previousValue } = changes.dropdownClass;
this._applyCustomDropdownClass(currentValue, previousValue);
}
if (changes.autoClose && this._open) {
this.autoClose = changes.autoClose.currentValue;
this._setCloseHandlers();
}
}
/**
* Checks if the dropdown menu is open.
*/
isOpen() {
return this._open;
}
/**
* Opens the dropdown menu.
*/
open() {
if (!this._open) {
this._open = true;
this._applyContainer(this.container);
this.openChange.emit(true);
this._setCloseHandlers();
if (this._anchor) {
this._anchor.nativeElement.focus();
if (this.display === 'dynamic') {
this._ngZone.runOutsideAngular(() => {
this._positioning.createPopper({
hostElement: this._anchor.nativeElement,
targetElement: this._bodyContainer || this._menu.nativeElement,
placement: this.placement,
appendToBody: this.container === 'body',
updatePopperOptions: (options) => this.popperOptions(addPopperOffset([0, 2])(options)),
});
this._applyPlacementClasses();
this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positionMenu());
});
}
}
}
}
_setCloseHandlers() {
this._destroyCloseHandlers$.next(); // destroy any existing close handlers
ngbAutoClose(this._ngZone, this._document, this.autoClose, (source) => {
this.close();
if (source === 0 /* SOURCE.ESCAPE */) {
this._anchor.nativeElement.focus();
}
}, this._destroyCloseHandlers$, this._menu ? [this._menu.nativeElement] : [], this._anchor ? [this._anchor.nativeElement] : [], '.dropdown-item,.dropdown-divider');
}
/**
* Closes the dropdown menu.
*/
close() {
if (this._open) {
this._open = false;
this._resetContainer();
this._positioning.destroy();
this._zoneSubscription?.unsubscribe();
this._destroyCloseHandlers$.next();
this.openChange.emit(false);
this._changeDetector.markForCheck();
}
}
/**
* Toggles the dropdown menu.
*/
toggle() {
if (this.isOpen()) {
this.close();
}
else {
this.open();
}
}
ngOnDestroy() {
this.close();
}
onKeyDown(event) {
/* eslint-disable-next-line deprecation/deprecation */
const key = event.which;
const itemElements = this._getMenuElements();
let position = -1;
let itemElement = null;
const isEventFromToggle = this._isEventFromToggle(event);
if (!isEventFromToggle && itemElements.length) {
itemElements.forEach((item, index) => {
if (item.contains(event.target)) {
itemElement = item;
}
if (item === getActiveElement(this._document)) {
position = index;
}
});
}
// closing on Enter / Space
if (key === Key.Space || key === Key.Enter) {
if (itemElement && (this.autoClose === true || this.autoClose === 'inside')) {
// Item is either a button or a link, so click will be triggered by the browser on Enter or Space.
// So we have to register a one-time click handler that will fire after any user defined click handlers
// to close the dropdown
fromEvent(itemElement, 'click')
.pipe(take(1))
.subscribe(() => this.close());
}
return;
}
if (key === Key.Tab) {
if (event.target && this.isOpen() && this.autoClose) {
if (this._anchor.nativeElement === event.target) {
if (this.container === 'body' && !event.shiftKey) {
/* This case is special: user is using [Tab] from the anchor/toggle.
User expects the next focusable element in the dropdown menu to get focus.
But the menu is not a sibling to anchor/toggle, it is at the end of the body.
Trick is to synchronously focus the menu element, and let the [keydown.Tab] go
so that browser will focus the proper element (first one focusable in the menu) */
this._renderer.setAttribute(this._menu.nativeElement, 'tabindex', '0');
this._menu.nativeElement.focus();
this._renderer.removeAttribute(this._menu.nativeElement, 'tabindex');
}
else if (event.shiftKey) {
this.close();
}
return;
}
else if (this.container === 'body') {
const focusableElements = this._menu.nativeElement.querySelectorAll(FOCUSABLE_ELEMENTS_SELECTOR);
if (event.shiftKey && event.target === focusableElements[0]) {
this._anchor.nativeElement.focus();
event.preventDefault();
}
else if (!event.shiftKey && event.target === focusableElements[focusableElements.length - 1]) {
this._anchor.nativeElement.focus();
this.close();
}
}
else {
fromEvent(event.target, 'focusout')
.pipe(take(1))
.subscribe(({ relatedTarget }) => {
if (!this._elementRef.nativeElement.contains(relatedTarget)) {
this.close();
}
});
}
}
return;
}
// opening / navigating
if (isEventFromToggle || itemElement) {
this.open();
if (itemElements.length) {
switch (key) {
case Key.ArrowDown:
position = Math.min(position + 1, itemElements.length - 1);
break;
case Key.ArrowUp:
if (this._isDropup() && position === -1) {
position = itemElements.length - 1;
break;
}
position = Math.max(position - 1, 0);
break;
case Key.Home:
position = 0;
break;
case Key.End:
position = itemElements.length - 1;
break;
}
itemElements[position].focus();
}
event.preventDefault();
}
}
_isDropup() {
return this._elementRef.nativeElement.classList.contains('dropup');
}
_isEventFromToggle(event) {
return this._anchor.nativeElement.contains(event.target);
}
_getMenuElements() {
const menu = this._menu;
if (menu == null) {
return [];
}
return menu.menuItems.filter((item) => !item.disabled).map((item) => item.elementRef.nativeElement);
}
_positionMenu() {
const menu = this._menu;
if (this.isOpen() && menu) {
if (this.display === 'dynamic') {
this._positioning.update();
this._applyPlacementClasses();
}
else {
this._applyPlacementClasses(this._getFirstPlacement(this.placement));
}
}
}
_getFirstPlacement(placement) {
return Array.isArray(placement) ? placement[0] : placement.split(' ')[0];
}
_resetContainer() {
const renderer = this._renderer;
if (this._menu) {
const dropdownElement = this._elementRef.nativeElement;
const dropdownMenuElement = this._menu.nativeElement;
renderer.appendChild(dropdownElement, dropdownMenuElement);
}
if (this._bodyContainer) {
renderer.removeChild(this._document.body, this._bodyContainer);
this._bodyContainer = null;
}
}
_applyContainer(container = null) {
this._resetContainer();
if (container === 'body') {
const renderer = this._renderer;
const dropdownMenuElement = this._menu.nativeElement;
const bodyContainer = (this._bodyContainer = this._bodyContainer || renderer.createElement('div'));
// Override some styles to have the positioning working
renderer.setStyle(bodyContainer, 'position', 'absolute');
renderer.setStyle(dropdownMenuElement, 'position', 'static');
renderer.setStyle(bodyContainer, 'z-index', '1055');
renderer.appendChild(bodyContainer, dropdownMenuElement);
renderer.appendChild(this._document.body, bodyContainer);
}
this._applyCustomDropdownClass(this.dropdownClass);
}
_applyCustomDropdownClass(newClass, oldClass) {
const targetElement = this.container === 'body' ? this._bodyContainer : this._elementRef.nativeElement;
if (targetElement) {
if (oldClass) {
this._renderer.removeClass(targetElement, oldClass);
}
if (newClass) {
this._renderer.addClass(targetElement, newClass);
}
}
}
_applyPlacementClasses(placement) {
const menu = this._menu;
if (menu) {
if (!placement) {
placement = this._getFirstPlacement(this.placement);
}
const renderer = this._renderer;
const dropdownElement = this._elementRef.nativeElement;
// remove the current placement classes
renderer.removeClass(dropdownElement, 'dropup');
renderer.removeClass(dropdownElement, 'dropdown');
const { nativeElement } = menu;
if (this.display === 'static') {
menu.placement = null;
renderer.setAttribute(nativeElement, 'data-bs-popper', 'static');
}
else {
menu.placement = placement;
renderer.removeAttribute(nativeElement, 'data-bs-popper');
}
/*
* apply the new placement
* in case of top use up-arrow or down-arrow otherwise
*/
const dropdownClass = placement.search('^top') !== -1 ? 'dropup' : 'dropdown';
renderer.addClass(dropdownElement, dropdownClass);
const bodyContainer = this._bodyContainer;
if (bodyContainer) {
renderer.removeClass(bodyContainer, 'dropup');
renderer.removeClass(bodyContainer, 'dropdown');
renderer.addClass(bodyContainer, dropdownClass);
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdown, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.NgbDropdownConfig }, { token: DOCUMENT }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.6", type: NgbDropdown, isStandalone: true, selector: "[ngbDropdown]", inputs: { autoClose: "autoClose", dropdownClass: "dropdownClass", _open: ["open", "_open"], placement: "placement", popperOptions: "popperOptions", container: "container", display: "display" }, outputs: { openChange: "openChange" }, host: { properties: { "class.show": "isOpen()" } }, queries: [{ propertyName: "_menu", first: true, predicate: NgbDropdownMenu, descendants: true }, { propertyName: "_anchor", first: true, predicate: NgbDropdownAnchor, descendants: true }], exportAs: ["ngbDropdown"], usesOnChanges: true, ngImport: i0 }); }
}
export { NgbDropdown };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.6", ngImport: i0, type: NgbDropdown, decorators: [{
type: Directive,
args: [{
selector: '[ngbDropdown]',
exportAs: 'ngbDropdown',
standalone: true,
host: { '[class.show]': 'isOpen()' },
}]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.NgbDropdownConfig }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { _menu: [{
type: ContentChild,
args: [NgbDropdownMenu, { static: false }]
}], _anchor: [{
type: ContentChild,
args: [NgbDropdownAnchor, { static: false }]
}], autoClose: [{
type: Input
}], dropdownClass: [{
type: Input
}], _open: [{
type: Input,
args: ['open']
}], placement: [{
type: Input
}], popperOptions: [{
type: Input
}], container: [{
type: Input
}], display: [{
type: Input
}], openChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZHJvcGRvd24vZHJvcGRvd24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdOLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUVULFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFLTCxNQUFNLEdBSU4sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN4RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEMsT0FBTyxFQUFFLGNBQWMsRUFBNkIsTUFBTSxxQkFBcUIsQ0FBQztBQUVoRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFlBQVksRUFBVSxNQUFNLG1CQUFtQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHbEMsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDOzs7QUFFaEQ7O0dBRUc7QUFDSCxNQUNhLFNBQVM7OEdBQVQsU0FBUztrR0FBVCxTQUFTOztTQUFULFNBQVM7MkZBQVQsU0FBUztrQkFEckIsU0FBUzttQkFBQyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRTs7QUFHcEQ7Ozs7O0dBS0c7QUFDSCxNQUthLGVBQWU7SUFLM0IsSUFDSSxRQUFRLENBQUMsS0FBYztRQUMxQixJQUFJLENBQUMsU0FBUyxHQUFRLEtBQUssS0FBSyxFQUFFLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxDQUFDLG9DQUFv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QkFRRyxTQUFTO3NCQUFqQixLQUFLO2dCQVVHLE9BQU87c0JBQWYsS0FBSztnQkFTSSxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0QWZ0ZXJDb250ZW50SW5pdCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbnRlbnRDaGlsZCxcblx0Q29udGVudENoaWxkcmVuLFxuXHREaXJlY3RpdmUsXG5cdEVsZW1lbnRSZWYsXG5cdEV2ZW50RW1pdHRlcixcblx0Zm9yd2FyZFJlZixcblx0SW5qZWN0LFxuXHRJbnB1dCxcblx0Tmdab25lLFxuXHRPbkNoYW5nZXMsXG5cdE9uRGVzdHJveSxcblx0T25Jbml0LFxuXHRPdXRwdXQsXG5cdFF1ZXJ5TGlzdCxcblx0UmVuZGVyZXIyLFxuXHRTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBuZ2JQb3NpdGlvbmluZywgUGxhY2VtZW50LCBQbGFjZW1lbnRBcnJheSB9IGZyb20gJy4uL3V0aWwvcG9zaXRpb25pbmcnO1xuaW1wb3J0IHsgT3B0aW9ucyB9IGZyb20gJ0Bwb3BwZXJqcy9jb3JlJztcbmltcG9ydCB7IGFkZFBvcHBlck9mZnNldCB9IGZyb20gJy4uL3V0aWwvcG9zaXRpb25pbmctdXRpbCc7XG5pbXBvcnQgeyBuZ2JBdXRvQ2xvc2UsIFNPVVJDRSB9IGZyb20gJy4uL3V0aWwvYXV0b2Nsb3NlJztcbmltcG9ydCB7IEtleSB9IGZyb20gJy4uL3V0aWwva2V5JztcblxuaW1wb3J0IHsgTmdiRHJvcGRvd25Db25maWcgfSBmcm9tICcuL2Ryb3Bkb3duLWNvbmZpZyc7XG5pbXBvcnQgeyBGT0NVU0FCTEVfRUxFTUVOVFNfU0VMRUNUT1IgfSBmcm9tICcuLi91dGlsL2ZvY3VzLXRyYXAnO1xuaW1wb3J0IHsgZ2V0QWN0aXZlRWxlbWVudCB9IGZyb20gJy4uL3V0aWwvdXRpbCc7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgMTQuMi4wIHRoaXMgZGlyZWN0aXZlIGlzbid0IHVzZWZ1bCBhbnltb3JlLiBZb3UgY2FuIHJlbW92ZSBpdCBmcm9tIHlvdXIgaW1wb3J0c1xuICovXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICcubmF2YmFyJywgc3RhbmRhbG9uZTogdHJ1ZSB9KVxuZXhwb3J0IGNsYXNzIE5nYk5hdmJhciB7fVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHlvdSBzaG91bGQgcHV0IG9uIGEgZHJvcGRvd24gaXRlbSB0byBlbmFibGUga2V5Ym9hcmQgbmF2aWdhdGlvbi5cbiAqIEFycm93IGtleXMgd2lsbCBtb3ZlIGZvY3VzIGJldHdlZW4gaXRlbXMgbWFya2VkIHdpdGggdGhpcyBkaXJlY3RpdmUuXG4gKlxuICogQHNpbmNlIDQuMS4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tuZ2JEcm9wZG93bkl0ZW1dJyxcblx0c3RhbmRhbG9uZTogdHJ1ZSxcblx0aG9zdDogeyBjbGFzczogJ2Ryb3Bkb3duLWl0ZW0nLCAnW2NsYXNzLmRpc2FibGVkXSc6ICdkaXNhYmxlZCcsICdbdGFiSW5kZXhdJzogJ2Rpc2FibGVkID8gLTEgOiAwJyB9LFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93bkl0ZW0ge1xuXHRzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfZGlzYWJsZWQ6IGJvb2xlYW4gfCAnJztcblxuXHRwcml2YXRlIF9kaXNhYmxlZCA9IGZhbHNlO1xuXG5cdEBJbnB1dCgpXG5cdHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuXHRcdHRoaXMuX2Rpc2FibGVkID0gPGFueT52YWx1ZSA9PT0gJycgfHwgdmFsdWUgPT09IHRydWU7IC8vIGFjY2VwdCBhbiBlbXB0eSBhdHRyaWJ1dGUgYXMgdHJ1ZVxuXHRcdC8vIG5vdGU6IHdlIGRvbid0IHVzZSBhIGhvc3QgYmluZGluZyBmb3IgZGlzYWJsZWQgYmVjYXVzZSB3aGVuIHVzZWQgb24gbGlua3MsIGl0IGZhaWxzIGJlY2F1c2UgbGlua3MgZG9uJ3QgaGF2ZSBhXG5cdFx0Ly8gZGlzYWJsZWQgcHJvcGVydHlcblx0XHQvLyBzZXR0aW5nIHRoZSBwcm9wZXJ0eSB1c2luZyB0aGUgcmVuZGVyZXIsIE9UT0gsIHdvcmtzIGZpbmUgaW4gYm90aCBjYXNlcy5cblx0XHR0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2Rpc2FibGVkJywgdGhpcy5fZGlzYWJsZWQpO1xuXHR9XG5cblx0Z2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLl9kaXNhYmxlZDtcblx0fVxuXG5cdGNvbnN0cnVjdG9yKHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiwgcHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMikge31cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0aGF0IHdyYXBzIGRyb3Bkb3duIG1lbnUgY29udGVudCBhbmQgZHJvcGRvd24gaXRlbXMuXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tuZ2JEcm9wZG93bk1lbnVdJyxcblx0c3RhbmRhbG9uZTogdHJ1ZSxcblx0aG9zdDoge1xuXHRcdCdbY2xhc3MuZHJvcGRvd24tbWVudV0nOiAndHJ1ZScsXG5cdFx0J1tjbGFzcy5zaG93XSc6ICdkcm9wZG93bi5pc09wZW4oKScsXG5cdFx0JyhrZXlkb3duLkFycm93VXApJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uQXJyb3dEb3duKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLkhvbWUpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uRW5kKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLkVudGVyKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLlNwYWNlKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLlRhYiknOiAnZHJvcGRvd24ub25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5TaGlmdC5UYWIpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0fSxcbn0pXG5leHBvcnQgY2xhc3MgTmdiRHJvcGRvd25NZW51IHtcblx0bmF0aXZlRWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cdHBsYWNlbWVudDogUGxhY2VtZW50IHwgbnVsbCA9ICdib3R0b20nO1xuXHRpc09wZW4gPSBmYWxzZTtcblxuXHRAQ29udGVudENoaWxkcmVuKE5nYkRyb3Bkb3duSXRlbSkgbWVudUl0ZW1zOiBRdWVyeUxpc3Q8TmdiRHJvcGRvd25JdGVtPjtcblxuXHRjb25zdHJ1Y3Rvcihcblx0XHRASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gTmdiRHJvcGRvd24pKSBwdWJsaWMgZHJ