fundamental-ngx
Version:
SAP Fiori Fundamentals, implemented in Angular
536 lines • 38.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { ApplicationRef, ChangeDetectorRef, ComponentFactoryResolver, Directive, ElementRef, EventEmitter, HostListener, Injector, Input, Output, Renderer2 } from '@angular/core';
import { PopoverContainer } from './popover-container';
import Popper from 'popper.js';
/**
* Directive which manages the popper and popover components of the library.
* It can be attached to any element. To bind it to a body, use the following syntax.
* ```html
* <div [fdPopover]="template">Control Element</div>
* <ng-template #template>
* Popover Body
* </ng-template>
* ```
*/
export class PopoverDirective {
/**
* @hidden
* @param {?} elRef
* @param {?} cdRef
* @param {?} resolver
* @param {?} injector
* @param {?} appRef
* @param {?} renderer
*/
constructor(elRef, cdRef, resolver, injector, appRef, renderer) {
this.elRef = elRef;
this.cdRef = cdRef;
this.resolver = resolver;
this.injector = injector;
this.appRef = appRef;
this.renderer = renderer;
/**
* Whether the popover is open. Can be used through two-way binding.
*/
this.isOpen = false;
/**
* The trigger events that will open/close the popover.
* Accepts any [HTML DOM Events](https://www.w3schools.com/jsref/dom_obj_event.asp).
*/
this.triggers = ['click'];
/**
* Whether the popover should display the default arrow.
*/
this.noArrow = true;
/**
* Whether the popover should be focusTrapped.
*/
this.focusTrapped = false;
/**
* Whether the popover should close when the escape key is pressed.
*/
this.closeOnEscapeKey = true;
/**
* Whether the popover is disabled.
*/
this.disabled = false;
/**
* Whether the popover should close when a click is made outside its boundaries.
*/
this.closeOnOutsideClick = true;
/**
* The element to which the popover should be appended.
*/
this.appendTo = 'body';
/**
* The Popper.js options to attach to this popover.
* See the [Popper.js Documentation](https://popper.js.org/popper-documentation.html) for details.
*/
this.options = {
placement: 'bottom-start',
modifiers: {
preventOverflow: {
enabled: true,
escapeWithReference: true,
boundariesElement: 'scrollParent'
}
}
};
/**
* Whether the Popover Body should try to have the same width as the Popover Control.
*/
this.fillControl = false;
/**
* Event emitted when the state of the isOpen property changes.
*/
this.isOpenChange = new EventEmitter();
this.eventRef = [];
this.isSetup = false;
}
/**
* @hidden
* @return {?}
*/
ngOnInit() {
if (this.isOpen) {
this.open();
}
this.initFillControl();
this.initPlacement();
this.addTriggerListeners();
this.isSetup = true;
}
/**
* @hidden
* @return {?}
*/
ngOnDestroy() {
if (this.popper) {
this.popper.destroy();
}
if (this.containerRef) {
this.destroyContainer();
}
this.destroyTriggerListeners();
}
/**
* @hidden
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (!this.isSetup) {
return;
}
if (changes.triggers) {
setTimeout((/**
* @return {?}
*/
() => {
this.destroyTriggerListeners();
this.addTriggerListeners();
}));
}
if (changes.isOpen) {
if (changes.isOpen.currentValue) {
setTimeout((/**
* @return {?}
*/
() => {
this.isOpen = false;
this.open(false);
}));
}
else {
setTimeout((/**
* @return {?}
*/
() => {
this.isOpen = true;
this.close(false);
}));
}
}
if (changes.placement) {
setTimeout((/**
* @return {?}
*/
() => {
this.initPlacement();
}));
}
if (changes.fillControl) {
setTimeout((/**
* @return {?}
*/
() => {
this.initFillControl();
}));
}
}
/**
* Toggles the popover open state.
* @param {?=} fireEvent
* @return {?}
*/
toggle(fireEvent = true) {
if (this.isOpen) {
this.close(fireEvent);
}
else {
this.open(fireEvent);
}
}
/**
* Opens the popover.
* @param {?=} fireEvent
* @return {?}
*/
open(fireEvent = true) {
if (!this.isOpen && !this.disabled) {
this.createContainer();
this.isOpen = true;
if (fireEvent) {
this.isOpenChange.emit(this.isOpen);
}
}
}
/**
* Closes the popover.
* @param {?=} fireEvent
* @return {?}
*/
close(fireEvent = true) {
if (this.isOpen) {
this.destroyContainer();
this.isOpen = false;
if (fireEvent) {
this.isOpenChange.emit(this.isOpen);
}
}
}
/**
* Forces an update of the popover's positioning calculation.
* @return {?}
*/
updatePopper() {
if (this.popper) {
this.popper.scheduleUpdate();
}
}
/**
* @private
* @return {?}
*/
createContainer() {
if (this.containerRef) {
return;
}
/** @type {?} */
const factory = this.resolver.resolveComponentFactory(PopoverContainer);
this.containerRef = factory.create(this.injector);
// Set instance properties
this.containerRef.instance.context = this;
this.containerRef.instance.content = this.content;
this.containerRef.instance.focusTrapped = this.focusTrapped;
this.containerRef.instance.noArrow = this.noArrow;
this.containerRef.instance.closeOnEscapeKey = this.closeOnEscapeKey;
this.appRef.attachView(this.containerRef.hostView);
/** @type {?} */
const setupRef = this.containerRef.instance.isSetup.subscribe((/**
* @return {?}
*/
() => {
this.createPopper();
setupRef.unsubscribe();
}));
/** @type {?} */
const containerEl = (/** @type {?} */ (((/** @type {?} */ (this.containerRef.hostView))).rootNodes[0]));
if (this.appendTo === 'body') {
document.body.appendChild(containerEl);
}
else {
this.appendTo.appendChild(containerEl);
}
}
/**
* @private
* @return {?}
*/
destroyTriggerListeners() {
if (this.eventRef && this.eventRef.length > 0) {
this.eventRef.forEach((/**
* @param {?} event
* @return {?}
*/
event => {
event();
}));
this.eventRef = [];
}
}
/**
* @private
* @return {?}
*/
addTriggerListeners() {
if (this.triggers && this.triggers.length > 0) {
this.triggers.forEach((/**
* @param {?} trigger
* @return {?}
*/
trigger => {
this.eventRef.push(this.renderer.listen(this.elRef.nativeElement, trigger, (/**
* @return {?}
*/
() => {
this.toggle();
})));
}));
}
}
/**
* @private
* @return {?}
*/
destroyContainer() {
if (this.containerRef) {
this.appRef.detachView(this.containerRef.hostView);
this.containerRef.destroy();
this.containerRef = null;
}
if (this.popper) {
this.popper.destroy();
this.popper = null;
}
}
/**
* @private
* @return {?}
*/
createPopper() {
this.popper = new Popper((/** @type {?} */ (this.elRef.nativeElement)), (/** @type {?} */ (this.containerRef.location.nativeElement)), this.options);
}
/**
* @private
* @param {?} data
* @return {?}
*/
fillReference(data) {
data.offsets.popper.left = data.offsets.reference.left;
data.offsets.popper.right = data.offsets.reference.right;
data.offsets.popper.width = data.styles.width = data.offsets.reference.width;
return data;
}
/**
* @private
* @return {?}
*/
initPlacement() {
if (this.placement) {
if (this.options) {
this.options.placement = this.placement;
}
else {
this.options = { placement: this.placement };
}
}
}
/**
* @private
* @return {?}
*/
initFillControl() {
if (this.fillControl) {
if (this.options && this.options.modifiers) {
this.options.modifiers.fillReference = {
enabled: true,
fn: this.fillReference,
order: 840
};
}
else {
this.options = {
modifiers: {
fillReference: {
enabled: true,
fn: this.fillReference,
order: 840
}
}
};
}
}
}
/**
* @hidden
* @param {?} event
* @return {?}
*/
clickHandler(event) {
if (this.containerRef &&
this.isOpen &&
this.closeOnOutsideClick &&
event.target !== this.elRef.nativeElement &&
!this.elRef.nativeElement.contains(event.target) &&
!this.containerRef.location.nativeElement.contains(event.target)) {
event.preventDefault();
event.stopPropagation();
this.close();
}
}
}
PopoverDirective.decorators = [
{ type: Directive, args: [{
selector: '[fdPopover]'
},] }
];
/** @nocollapse */
PopoverDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: ComponentFactoryResolver },
{ type: Injector },
{ type: ApplicationRef },
{ type: Renderer2 }
];
PopoverDirective.propDecorators = {
content: [{ type: Input, args: ['fdPopover',] }],
isOpen: [{ type: Input }],
triggers: [{ type: Input }],
noArrow: [{ type: Input }],
placement: [{ type: Input }],
focusTrapped: [{ type: Input }],
closeOnEscapeKey: [{ type: Input }],
disabled: [{ type: Input }],
closeOnOutsideClick: [{ type: Input }],
appendTo: [{ type: Input }],
options: [{ type: Input }],
fillControl: [{ type: Input }],
isOpenChange: [{ type: Output }],
clickHandler: [{ type: HostListener, args: ['document:click', ['$event'],] }]
};
if (false) {
/**
* Content of the popover. Used through the actual directive tag. Accepts strings or TemplateRefs.
* @type {?}
*/
PopoverDirective.prototype.content;
/**
* Whether the popover is open. Can be used through two-way binding.
* @type {?}
*/
PopoverDirective.prototype.isOpen;
/**
* The trigger events that will open/close the popover.
* Accepts any [HTML DOM Events](https://www.w3schools.com/jsref/dom_obj_event.asp).
* @type {?}
*/
PopoverDirective.prototype.triggers;
/**
* Whether the popover should display the default arrow.
* @type {?}
*/
PopoverDirective.prototype.noArrow;
/**
* The placement of the popover. It can be one of: top, top-start, top-end, bottom,
* bottom-start, bottom-end, right, right-start, right-end, left, left-start, left-end.
* @type {?}
*/
PopoverDirective.prototype.placement;
/**
* Whether the popover should be focusTrapped.
* @type {?}
*/
PopoverDirective.prototype.focusTrapped;
/**
* Whether the popover should close when the escape key is pressed.
* @type {?}
*/
PopoverDirective.prototype.closeOnEscapeKey;
/**
* Whether the popover is disabled.
* @type {?}
*/
PopoverDirective.prototype.disabled;
/**
* Whether the popover should close when a click is made outside its boundaries.
* @type {?}
*/
PopoverDirective.prototype.closeOnOutsideClick;
/**
* The element to which the popover should be appended.
* @type {?}
*/
PopoverDirective.prototype.appendTo;
/**
* The Popper.js options to attach to this popover.
* See the [Popper.js Documentation](https://popper.js.org/popper-documentation.html) for details.
* @type {?}
*/
PopoverDirective.prototype.options;
/**
* Whether the Popover Body should try to have the same width as the Popover Control.
* @type {?}
*/
PopoverDirective.prototype.fillControl;
/**
* Event emitted when the state of the isOpen property changes.
* @type {?}
*/
PopoverDirective.prototype.isOpenChange;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.containerRef;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.popper;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.eventRef;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.isSetup;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.elRef;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.cdRef;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.resolver;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.injector;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.appRef;
/**
* @type {?}
* @private
*/
PopoverDirective.prototype.renderer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wb3Zlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9mdW5kYW1lbnRhbC1uZ3gvIiwic291cmNlcyI6WyJsaWIvcG9wb3Zlci9wb3BvdmVyLWRpcmVjdGl2ZS9wb3BvdmVyLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILGNBQWMsRUFDZCxpQkFBaUIsRUFDakIsd0JBQXdCLEVBRXhCLFNBQVMsRUFDVCxVQUFVLEVBQW1CLFlBQVksRUFBRSxZQUFZLEVBQ3ZELFFBQVEsRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBRSxTQUFTLEVBRW5FLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sTUFBb0MsTUFBTSxXQUFXLENBQUM7Ozs7Ozs7Ozs7O0FBZTdELE1BQU0sT0FBTyxnQkFBZ0I7Ozs7Ozs7Ozs7SUF3RXpCLFlBQW9CLEtBQWlCLEVBQ2pCLEtBQXdCLEVBQ3hCLFFBQWtDLEVBQ2xDLFFBQWtCLEVBQ2xCLE1BQXNCLEVBQ3RCLFFBQW1CO1FBTG5CLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDakIsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDeEIsYUFBUSxHQUFSLFFBQVEsQ0FBMEI7UUFDbEMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixXQUFNLEdBQU4sTUFBTSxDQUFnQjtRQUN0QixhQUFRLEdBQVIsUUFBUSxDQUFXOzs7O1FBckV2QyxXQUFNLEdBQVksS0FBSyxDQUFDOzs7OztRQUt4QixhQUFRLEdBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7OztRQUkvQixZQUFPLEdBQVksSUFBSSxDQUFDOzs7O1FBU3hCLGlCQUFZLEdBQVksS0FBSyxDQUFDOzs7O1FBSTlCLHFCQUFnQixHQUFZLElBQUksQ0FBQzs7OztRQUlqQyxhQUFRLEdBQVksS0FBSyxDQUFDOzs7O1FBSTFCLHdCQUFtQixHQUFZLElBQUksQ0FBQzs7OztRQUlwQyxhQUFRLEdBQXlCLE1BQU0sQ0FBQzs7Ozs7UUFLeEMsWUFBTyxHQUFrQjtZQUNyQixTQUFTLEVBQUUsY0FBYztZQUN6QixTQUFTLEVBQUU7Z0JBQ1AsZUFBZSxFQUFFO29CQUNiLE9BQU8sRUFBRSxJQUFJO29CQUNiLG1CQUFtQixFQUFFLElBQUk7b0JBQ3pCLGlCQUFpQixFQUFFLGNBQWM7aUJBQ3BDO2FBQ0o7U0FDSixDQUFDOzs7O1FBSUYsZ0JBQVcsR0FBWSxLQUFLLENBQUM7Ozs7UUFJN0IsaUJBQVksR0FBMEIsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUkxRCxhQUFRLEdBQWUsRUFBRSxDQUFDO1FBQzFCLFlBQU8sR0FBWSxLQUFLLENBQUM7SUFTakMsQ0FBQzs7Ozs7SUFHRCxRQUFRO1FBQ0osSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2IsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ2Y7UUFFRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXJCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ3hCLENBQUM7Ozs7O0lBR0QsV0FBVztRQUNQLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDekI7UUFFRCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDbkIsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7U0FDM0I7UUFFRCxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztJQUNuQyxDQUFDOzs7Ozs7SUFHRCxXQUFXLENBQUMsT0FBc0I7UUFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDZixPQUFPO1NBQ1Y7UUFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDbEIsVUFBVTs7O1lBQUMsR0FBRyxFQUFFO2dCQUNaLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2dCQUMvQixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMvQixDQUFDLEVBQUMsQ0FBQztTQUNOO1FBRUQsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO1lBQ2hCLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUU7Z0JBQzdCLFVBQVU7OztnQkFBQyxHQUFHLEVBQUU7b0JBQ1osSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7b0JBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3JCLENBQUMsRUFBQyxDQUFDO2FBQ047aUJBQU07Z0JBQ0gsVUFBVTs7O2dCQUFDLEdBQUcsRUFBRTtvQkFDWixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztvQkFDbkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDdEIsQ0FBQyxFQUFDLENBQUM7YUFDTjtTQUNKO1FBRUQsSUFBSSxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQ25CLFVBQVU7OztZQUFDLEdBQUcsRUFBRTtnQkFDWixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDekIsQ0FBQyxFQUFDLENBQUM7U0FDTjtRQUVELElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUNyQixVQUFVOzs7WUFBQyxHQUFHLEVBQUU7Z0JBQ1osSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzNCLENBQUMsRUFBQyxDQUFDO1NBQ047SUFDTCxDQUFDOzs7Ozs7SUFLTSxNQUFNLENBQUMsWUFBcUIsSUFBSTtRQUNuQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3pCO2FBQU07WUFDSCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3hCO0lBQ0wsQ0FBQzs7Ozs7O0lBS00sSUFBSSxDQUFDLFlBQXFCLElBQUk7UUFDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2hDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztZQUVuQixJQUFJLFNBQVMsRUFBRTtnQkFDWCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDdkM7U0FDSjtJQUNMLENBQUM7Ozs7OztJQUtNLEtBQUssQ0FBQyxZQUFxQixJQUFJO1FBQ2xDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBRXBCLElBQUksU0FBUyxFQUFFO2dCQUNYLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUN2QztTQUNKO0lBQ0wsQ0FBQzs7Ozs7SUFLTSxZQUFZO1FBQ2YsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUNoQztJQUNMLENBQUM7Ozs7O0lBRU8sZUFBZTtRQUNuQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDbkIsT0FBTztTQUNWOztjQUVLLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLGdCQUFnQixDQUFDO1FBQ3ZFLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbEQsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDbEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDNUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDbEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRXBFLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7O2NBQzdDLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUzs7O1FBQUMsR0FBRyxFQUFFO1lBQy9ELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQixRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDM0IsQ0FBQyxFQUFDOztjQUVJLFdBQVcsR0FBRyxtQkFBQSxDQUFDLG1CQUFBLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUF3QixDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFlO1FBRXBHLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxNQUFNLEVBQUU7WUFDMUIsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDMUM7YUFBTTtZQUNILElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQzFDO0lBRUwsQ0FBQzs7Ozs7SUFFTyx1QkFBdUI7UUFDM0IsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU87Ozs7WUFBQyxLQUFLLENBQUMsRUFBRTtnQkFDMUIsS0FBSyxFQUFFLENBQUM7WUFDWixDQUFDLEVBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO1NBQ3RCO0lBQ0wsQ0FBQzs7Ozs7SUFFTyxtQkFBbUI7UUFDdkIsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU87Ozs7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsT0FBTzs7O2dCQUFFLEdBQUcsRUFBRTtvQkFDNUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNsQixDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQ1IsQ0FBQyxFQUFDLENBQUM7U0FDTjtJQUNMLENBQUM7Ozs7O0lBRU8sZ0JBQWdCO1FBQ3BCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ25ELElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDNUI7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDYixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1NBQ3RCO0lBQ0wsQ0FBQzs7Ozs7SUFFTyxZQUFZO1FBQ2hCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQ3BCLG1CQUFBLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFlLEVBQ3ZDLG1CQUFBLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBZSxFQUN2RCxJQUFJLENBQUMsT0FBTyxDQUNmLENBQUM7SUFDTixDQUFDOzs7Ozs7SUFFTyxhQUFhLENBQUMsSUFBSTtRQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDekQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUM3RSxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDOzs7OztJQUVPLGFBQWE7UUFDakIsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2hCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtnQkFDZCxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO2FBQzNDO2lCQUFNO2dCQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBQyxDQUFBO2FBQzdDO1NBQ0o7SUFDTCxDQUFDOzs7OztJQUVPLGVBQWU7UUFDbkIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2xCLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRTtnQkFDeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHO29CQUNuQyxPQUFPLEVBQUUsSUFBSTtvQkFDYixFQUFFLEVBQUUsSUFBSSxDQUFDLGFBQWE7b0JBQ3RCLEtBQUssRUFBRSxHQUFHO2lCQUNiLENBQUE7YUFDSjtpQkFBTTtnQkFDSCxJQUFJLENBQUMsT0FBTyxHQUFHO29CQUNYLFNBQVMsRUFBRTt3QkFDUCxhQUFhLEVBQUU7NEJBQ1gsT0FBTyxFQUFFLElBQUk7NEJBQ2IsRUFBRSxFQUFFLElBQUksQ0FBQyxhQUFhOzRCQUN0QixLQUFLLEVBQUUsR0FBRzt5QkFDYjtxQkFDSjtpQkFDSixDQUFDO2FBQ0w7U0FDSjtJQUNMLENBQUM7Ozs7OztJQUlELFlBQVksQ0FBQyxLQUFpQjtRQUMxQixJQUFJLElBQUksQ0FBQyxZQUFZO1lBQ2pCLElBQUksQ0FBQyxNQUFNO1lBQ1gsSUFBSSxDQUFDLG1CQUFtQjtZQUN4QixLQUFLLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYTtZQUN6QyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ2hELENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDbEUsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDaEI7SUFDTCxDQUFDOzs7WUFoVUosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxhQUFhO2FBQzFCOzs7O1lBbkJHLFVBQVU7WUFKVixpQkFBaUI7WUFDakIsd0JBQXdCO1lBSXhCLFFBQVE7WUFOUixjQUFjO1lBTXlDLFNBQVM7OztzQkFzQi9ELEtBQUssU0FBQyxXQUFXO3FCQUlqQixLQUFLO3VCQUtMLEtBQUs7c0JBSUwsS0FBSzt3QkFLTCxLQUFLOzJCQUlMLEtBQUs7K0JBSUwsS0FBSzt1QkFJTCxLQUFLO2tDQUlMLEtBQUs7dUJBSUwsS0FBSztzQkFLTCxLQUFLOzBCQWFMLEtBQUs7MkJBSUwsTUFBTTsyQkFrUE4sWUFBWSxTQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDOzs7Ozs7O0lBOVMxQyxtQ0FDbUM7Ozs7O0lBR25DLGtDQUN3Qjs7Ozs7O0lBSXhCLG9DQUMrQjs7Ozs7SUFHL0IsbUNBQ3dCOzs7Ozs7SUFJeEIscUNBQ3FCOzs7OztJQUdyQix3Q0FDOEI7Ozs7O0lBRzlCLDRDQUNpQzs7Ozs7SUFHakMsb0NBQzBCOzs7OztJQUcxQiwrQ0FDb0M7Ozs7O0lBR3BDLG9DQUN3Qzs7Ozs7O0lBSXhDLG1DQVVFOzs7OztJQUdGLHVDQUM2Qjs7Ozs7SUFHN0Isd0NBQ2tFOzs7OztJQUVsRSx3Q0FBcUQ7Ozs7O0lBQ3JELGtDQUF1Qjs7Ozs7SUFDdkIsb0NBQWtDOzs7OztJQUNsQyxtQ0FBaUM7Ozs7O0lBR3JCLGlDQUF5Qjs7Ozs7SUFDekIsaUNBQWdDOzs7OztJQUNoQyxvQ0FBMEM7Ozs7O0lBQzFDLG9DQUEwQjs7Ozs7SUFDMUIsa0NBQThCOzs7OztJQUM5QixvQ0FBMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIEFwcGxpY2F0aW9uUmVmLFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICBDb21wb25lbnRSZWYsXG4gICAgRGlyZWN0aXZlLFxuICAgIEVsZW1lbnRSZWYsIEVtYmVkZGVkVmlld1JlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsXG4gICAgSW5qZWN0b3IsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFJlbmRlcmVyMiwgU2ltcGxlQ2hhbmdlcyxcbiAgICBUZW1wbGF0ZVJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFBvcG92ZXJDb250YWluZXIgfSBmcm9tICcuL3BvcG92ZXItY29udGFpbmVyJztcbmltcG9ydCBQb3BwZXIsIHsgUGxhY2VtZW50LCBQb3BwZXJPcHRpb25zIH0gZnJvbSAncG9wcGVyLmpzJztcblxuLyoqXG4gKiBEaXJlY3RpdmUgd2hpY2ggbWFuYWdlcyB0aGUgcG9wcGVyIGFuZCBwb3BvdmVyIGNvbXBvbmVudHMgb2YgdGhlIGxpYnJhcnkuXG4gKiBJdCBjYW4gYmUgYXR0YWNoZWQgdG8gYW55IGVsZW1lbnQuIFRvIGJpbmQgaXQgdG8gYSBib2R5LCB1c2UgdGhlIGZvbGxvd2luZyBzeW50YXguXG4gKiBgYGBodG1sXG4gKiA8ZGl2IFtmZFBvcG92ZXJdPVwidGVtcGxhdGVcIj5Db250cm9sIEVsZW1lbnQ8L2Rpdj5cbiAqIDxuZy10ZW1wbGF0ZSAjdGVtcGxhdGU+XG4gKiAgICAgUG9wb3ZlciBCb2R5XG4gKiA8L25nLXRlbXBsYXRlPlxuICogYGBgXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW2ZkUG9wb3Zlcl0nXG59KVxuZXhwb3J0IGNsYXNzIFBvcG92ZXJEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcblxuICAgIC8qKiBDb250ZW50IG9mIHRoZSBwb3BvdmVyLiBVc2VkIHRocm91Z2ggdGhlIGFjdHVhbCBkaXJlY3RpdmUgdGFnLiBBY2NlcHRzIHN0cmluZ3Mgb3IgVGVtcGxhdGVSZWZzLiAqL1xuICAgIEBJbnB1dCgnZmRQb3BvdmVyJylcbiAgICBjb250ZW50OiBUZW1wbGF0ZVJlZjxhbnk+IHwgc3RyaW5nO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgaXMgb3Blbi4gQ2FuIGJlIHVzZWQgdGhyb3VnaCB0d28td2F5IGJpbmRpbmcuICovXG4gICAgQElucHV0KClcbiAgICBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBUaGUgdHJpZ2dlciBldmVudHMgdGhhdCB3aWxsIG9wZW4vY2xvc2UgdGhlIHBvcG92ZXIuXG4gICAgICogIEFjY2VwdHMgYW55IFtIVE1MIERPTSBFdmVudHNdKGh0dHBzOi8vd3d3Lnczc2Nob29scy5jb20vanNyZWYvZG9tX29ial9ldmVudC5hc3ApLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgdHJpZ2dlcnM6IHN0cmluZ1tdID0gWydjbGljayddO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgc2hvdWxkIGRpc3BsYXkgdGhlIGRlZmF1bHQgYXJyb3cuICovXG4gICAgQElucHV0KClcbiAgICBub0Fycm93OiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBUaGUgcGxhY2VtZW50IG9mIHRoZSBwb3BvdmVyLiBJdCBjYW4gYmUgb25lIG9mOiB0b3AsIHRvcC1zdGFydCwgdG9wLWVuZCwgYm90dG9tLFxuICAgICAqICBib3R0b20tc3RhcnQsIGJvdHRvbS1lbmQsIHJpZ2h0LCByaWdodC1zdGFydCwgcmlnaHQtZW5kLCBsZWZ0LCBsZWZ0LXN0YXJ0LCBsZWZ0LWVuZC4gKi9cbiAgICBASW5wdXQoKVxuICAgIHBsYWNlbWVudDogUGxhY2VtZW50O1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgc2hvdWxkIGJlIGZvY3VzVHJhcHBlZC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGZvY3VzVHJhcHBlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgc2hvdWxkIGNsb3NlIHdoZW4gdGhlIGVzY2FwZSBrZXkgaXMgcHJlc3NlZC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGNsb3NlT25Fc2NhcGVLZXk6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgaXMgZGlzYWJsZWQuICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHBvcG92ZXIgc2hvdWxkIGNsb3NlIHdoZW4gYSBjbGljayBpcyBtYWRlIG91dHNpZGUgaXRzIGJvdW5kYXJpZXMuICovXG4gICAgQElucHV0KClcbiAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBUaGUgZWxlbWVudCB0byB3aGljaCB0aGUgcG9wb3ZlciBzaG91bGQgYmUgYXBwZW5kZWQuICovXG4gICAgQElucHV0KClcbiAgICBhcHBlbmRUbzogSFRNTEVsZW1lbnQgfCAnYm9keScgPSAnYm9keSc7XG5cbiAgICAvKiogVGhlIFBvcHBlci5qcyBvcHRpb25zIHRvIGF0dGFjaCB0byB0aGlzIHBvcG92ZXIuXG4gICAgICogU2VlIHRoZSBbUG9wcGVyLmpzIERvY3VtZW50YXRpb25dKGh0dHBzOi8vcG9wcGVyLmpzLm9yZy9wb3BwZXItZG9jdW1lbnRhdGlvbi5odG1sKSBmb3IgZGV0YWlscy4gKi9cbiAgICBASW5wdXQoKVxuICAgIG9wdGlvbnM6IFBvcHBlck9wdGlvbnMgPSB7XG4gICAgICAgIHBsYWNlbWVudDogJ2JvdHRvbS1zdGFydCcsXG4gICAgICAgIG1vZGlmaWVyczoge1xuICAgICAgICAgICAgcHJldmVudE92ZXJmbG93OiB7XG4gICAgICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlc2NhcGVXaXRoUmVmZXJlbmNlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGJvdW5kYXJpZXNFbGVtZW50OiAnc2Nyb2xsUGFyZW50J1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBQb3BvdmVyIEJvZHkgc2hvdWxkIHRyeSB0byBoYXZlIHRoZSBzYW1lIHdpZHRoIGFzIHRoZSBQb3BvdmVyIENvbnRyb2wuICovXG4gICAgQElucHV0KClcbiAgICBmaWxsQ29udHJvbDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIGlzT3BlbiBwcm9wZXJ0eSBjaGFuZ2VzLiAqL1xuICAgIEBPdXRwdXQoKVxuICAgIGlzT3BlbkNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gICAgcHJpdmF0ZSBjb250YWluZXJSZWY6IENvbXBvbmVudFJlZjxQb3BvdmVyQ29udGFpbmVyPjtcbiAgICBwcml2YXRlIHBvcHBlcjogUG9wcGVyO1xuICAgIHByaXZhdGUgZXZlbnRSZWY6IEZ1bmN0aW9uW10gPSBbXTtcbiAgICBwcml2YXRlIGlzU2V0dXA6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgICAgICAgICBwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgICAgICAgICBwcml2YXRlIHJlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBhcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgICAgICAgdGhpcy5vcGVuKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmluaXRGaWxsQ29udHJvbCgpO1xuICAgICAgICB0aGlzLmluaXRQbGFjZW1lbnQoKTtcblxuICAgICAgICB0aGlzLmFkZFRyaWdnZXJMaXN0ZW5lcnMoKTtcbiAgICAgICAgdGhpcy5pc1NldHVwID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wb3BwZXIpIHtcbiAgICAgICAgICAgIHRoaXMucG9wcGVyLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95Q29udGFpbmVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRlc3Ryb3lUcmlnZ2VyTGlzdGVuZXJzKCk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5pc1NldHVwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hhbmdlcy50cmlnZ2Vycykge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95VHJpZ2dlckxpc3RlbmVycygpO1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkVHJpZ2dlckxpc3RlbmVycygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hhbmdlcy5pc09wZW4pIHtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VzLmlzT3Blbi5jdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hhbmdlcy5wbGFjZW1lbnQpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFBsYWNlbWVudCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2hhbmdlcy5maWxsQ29udHJvbCkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0RmlsbENvbnRyb2woKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlcyB0aGUgcG9wb3ZlciBvcGVuIHN0YXRlLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGUoZmlyZUV2ZW50OiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5pc09wZW4pIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoZmlyZUV2ZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3BlbihmaXJlRXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIHBvcG92ZXIuXG4gICAgICovXG4gICAgcHVibGljIG9wZW4oZmlyZUV2ZW50OiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuaXNPcGVuICYmICF0aGlzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUNvbnRhaW5lcigpO1xuICAgICAgICAgICAgdGhpcy5pc09wZW4gPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoZmlyZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc09wZW5DaGFuZ2UuZW1pdCh0aGlzLmlzT3Blbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIHBvcG92ZXIuXG4gICAgICovXG4gICAgcHVibGljIGNsb3NlKGZpcmVFdmVudDogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lDb250YWluZXIoKTtcbiAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChmaXJlRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzT3BlbkNoYW5nZS5lbWl0KHRoaXMuaXNPcGVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBhbiB1cGRhdGUgb2YgdGhlIHBvcG92ZXIncyBwb3NpdGlvbmluZyBjYWxjdWxhdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlUG9wcGVyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wb3BwZXIpIHtcbiAgICAgICAgICAgIHRoaXMucG9wcGVyLnNjaGVkdWxlVXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUNvbnRhaW5lcigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyUmVmKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLnJlc29sdmVyLnJlc29sdmVDb21wb25lbnRGYWN0b3J5KFBvcG92ZXJDb250YWluZXIpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lclJlZiA9IGZhY3RvcnkuY3JlYXRlKHRoaXMuaW5qZWN0b3IpO1xuXG4gICAgICAgIC8vIFNldCBpbnN0YW5jZSBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuY29udGFpbmVyUmVmLmluc3RhbmNlLmNvbnRleHQgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvbnRhaW5lclJlZi5pbnN0YW5jZS5jb250ZW50ID0gdGhpcy5jb250ZW50O1xuICAgICAgICB0aGlzLmNvbnRhaW5lclJlZi5pbnN0YW5jZS5mb2N1c1RyYXBwZWQgPSB0aGlzLmZvY3VzVHJhcHBlZDtcbiAgICAgICAgdGhpcy5jb250YWluZXJSZWYuaW5zdGFuY2Uubm9BcnJvdyA9IHRoaXMubm9BcnJvdztcbiAgICAgICAgdGhpcy5jb250YWluZXJSZWYuaW5zdGFuY2UuY2xvc2VPbkVzY2FwZUtleSA9IHRoaXMuY2xvc2VPbkVzY2FwZUtleTtcblxuICAgICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHRoaXMuY29udGFpbmVyUmVmLmhvc3RWaWV3KTtcbiAgICAgICAgY29uc3Qgc2V0dXBSZWYgPSB0aGlzLmNvbnRhaW5lclJlZi5pbnN0YW5jZS5pc1NldHVwLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVBvcHBlcigpO1xuICAgICAgICAgICAgc2V0dXBSZWYudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY29udGFpbmVyRWwgPSAodGhpcy5jb250YWluZXJSZWYuaG9zdFZpZXcgYXMgRW1iZWRkZWRWaWV3UmVmPGFueT4pLnJvb3ROb2Rlc1swXSBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgICBpZiAodGhpcy5hcHBlbmRUbyA9PT0gJ2JvZHknKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lckVsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kVG8uYXBwZW5kQ2hpbGQoY29udGFpbmVyRWwpO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc3Ryb3lUcmlnZ2VyTGlzdGVuZXJzKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5ldmVudFJlZiAmJiB0aGlzLmV2ZW50UmVmLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuZXZlbnRSZWYuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5ldmVudFJlZiA9IFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRUcmlnZ2VyTGlzdGVuZXJzKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50cmlnZ2VycyAmJiB0aGlzLnRyaWdnZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlcnMuZm9yRWFjaCh0cmlnZ2VyID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50UmVmLnB1c2godGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LCB0cmlnZ2VyLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlKCk7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc3Ryb3lDb250YWluZXIoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lclJlZikge1xuICAgICAgICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh0aGlzLmNvbnRhaW5lclJlZi5ob3N0Vmlldyk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lclJlZi5kZXN0cm95KCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lclJlZiA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wb3BwZXIpIHtcbiAgICAgICAgICAgIHRoaXMucG9wcGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMucG9wcGVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlUG9wcGVyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnBvcHBlciA9IG5ldyBQb3BwZXIoXG4gICAgICAgICAgICB0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQsXG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lclJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5vcHRpb25zXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaWxsUmVmZXJlbmNlKGRhdGEpOiBhbnkge1xuICAgICAgICBkYXRhLm9mZnNldHMucG9wcGVyLmxlZnQgPSBkYXRhLm9mZnNldHMucmVmZXJlbmNlLmxlZnQ7XG4gICAgICAgIGRhdGEub2Zmc2V0cy5wb3BwZXIucmlnaHQgPSBkYXRhLm9mZnNldHMucmVmZXJlbmNlLnJpZ2h0O1xuICAgICAgICBkYXRhLm9mZnNldHMucG9wcGVyLndpZHRoID0gZGF0YS5zdHlsZXMud2lkdGggPSBkYXRhLm9mZnNldHMucmVmZXJlbmNlLndpZHRoO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRQbGFjZW1lbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnBsYWNlbWVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5wbGFjZW1lbnQgPSB0aGlzLnBsYWNlbWVudDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge3BsYWNlbWVudDogdGhpcy5wbGFjZW1lbnR9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRGaWxsQ29udHJvbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZmlsbENvbnRyb2wpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMgJiYgdGhpcy5vcHRpb25zLm1vZGlmaWVycykge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5tb2RpZmllcnMuZmlsbFJlZmVyZW5jZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZm46IHRoaXMuZmlsbFJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgICAgb3JkZXI6IDg0MFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBtb2RpZmllcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGxSZWZlcmVuY2U6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuOiB0aGlzLmZpbGxSZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXI6IDg0MFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICAgIGNsaWNrSGFuZGxlcihldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXJSZWYgJiZcbiAgICAgICAgICAgIHRoaXMuaXNPcGVuICYmXG4gICAgICAgICAgICB0aGlzLmNsb3NlT25PdXRzaWRlQ2xpY2sgJiZcbiAgICAgICAgICAgIGV2ZW50LnRhcmdldCAhPT0gdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50ICYmXG4gICAgICAgICAgICAhdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgJiZcbiAgICAgICAgICAgICF0aGlzLmNvbnRhaW5lclJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==