@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
608 lines • 95.7 kB
JavaScript
import { __decorate, __metadata, __param } from "tslib";
import { DOCUMENT } from '@angular/common';
import { GlobalPositionStrategy } from './position/global-position-strategy';
import { NoOpScrollStrategy } from './scroll/NoOpScrollStrategy';
import { ApplicationRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, EventEmitter, Inject, Injectable, Injector, Type, OnDestroy, NgModuleRef, NgZone } from '@angular/core';
import { AnimationBuilder, AnimationReferenceMetadata, AnimationMetadataType, AnimationAnimateRefMetadata } from '@angular/animations';
import { fromEvent, Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { showMessage } from '../../core/deprecateDecorators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/animations";
import * as i2 from "@angular/common";
var warningShown = false;
/**
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_main.html)
* The overlay service allows users to show components on overlay div above all other elements in the page.
*/
var IgxOverlayService = /** @class */ (function () {
function IgxOverlayService(_factoryResolver, _appRef, _injector, builder, document, _zone) {
var _this = this;
this._factoryResolver = _factoryResolver;
this._appRef = _appRef;
this._injector = _injector;
this.builder = builder;
this.document = document;
this._zone = _zone;
this._componentId = 0;
this._overlayInfos = [];
this.destroy$ = new Subject();
this._defaultSettings = {
positionStrategy: new GlobalPositionStrategy(),
scrollStrategy: new NoOpScrollStrategy(),
modal: true,
closeOnOutsideClick: true
};
/**
* Emitted before the component is opened.
* ```typescript
* onOpening(event: OverlayCancelableEventArgs){
* const onOpening = event;
* }
* ```
*/
this.onOpening = new EventEmitter();
/**
* Emitted after the component is opened and all animations are finished.
* ```typescript
* onOpened(event: OverlayEventArgs){
* const onOpened = event;
* }
* ```
*/
this.onOpened = new EventEmitter();
/**
* Emitted before the component is closed.
* ```typescript
* onClosing(event: OverlayCancelableEventArgs){
* const onClosing = event;
* }
* ```
*/
this.onClosing = new EventEmitter();
/**
* Emitted after the component is closed and all animations are finished.
* ```typescript
* onClosed(event: OverlayEventArgs){
* const onClosed = event;
* }
* ```
*/
this.onClosed = new EventEmitter();
/**
* Emitted before animation is started
* ```typescript
* onAnimation(event: OverlayAnimationEventArgs){
* const onAnimation = event;
* }
* ```
*/
this.onAnimation = new EventEmitter();
this.documentClicked = function (ev) {
// if we get to modal overlay just return - we should not close anything under it
// if we get to non-modal overlay do the next:
// 1. Check it has close on outside click. If not go on to next overlay;
// 2. If true check if click is on the element. If it is on the element we have closed
// already all previous non-modal with close on outside click elements, so we return. If
// not close the overlay and check next
for (var i = _this._overlayInfos.length; i--;) {
var info = _this._overlayInfos[i];
if (info.settings.modal) {
return;
}
if (info.settings.closeOnOutsideClick) {
var target = ev.target;
// if the click is on the element do not close this overlay
if (!info.elementRef.nativeElement.contains(target)) {
// if we should exclude position target check if the click is over it. If so do not close overlay
var positionTarget = info.settings.positionStrategy.settings.target;
var clickOnPositionTarget = false;
if (positionTarget) {
clickOnPositionTarget = positionTarget.contains(target);
}
if (!(info.settings.excludePositionTarget && clickOnPositionTarget)) {
// if the click is outside click, but close animation has started do nothing
if (!(info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted())) {
_this._hide(info.id, ev);
}
}
}
else {
// TODO: should we return here, or continue with next overlays
return;
}
}
}
};
/** @hidden */
this.repositionAll = function () {
for (var i = _this._overlayInfos.length; i--;) {
_this.reposition(_this._overlayInfos[i].id);
}
};
this._document = this.document;
}
IgxOverlayService.prototype.attach = function (component, settings, moduleRef) {
var info;
info = this.getOverlayInfo(component, moduleRef);
// if there is no info most probably wrong type component was provided and we just go out
if (!info) {
return null;
}
info.id = (this._componentId++).toString();
settings = Object.assign({}, this._defaultSettings, settings);
info.settings = settings;
this._overlayInfos.push(info);
return info.id;
};
IgxOverlayService.prototype.show = function (compOrId, settings) {
var info;
var id;
if (typeof compOrId === 'string') {
id = compOrId;
info = this.getOverlayById(compOrId);
if (!info) {
console.warn('igxOverlay.show was called with wrong id: ' + compOrId);
return null;
}
}
else {
warningShown = showMessage('`show(component, settings?)` overload is deprecated. Use `attach(component)` to obtain an Id.' +
'Then `show(id, settings?)` with provided Id.', warningShown);
id = (this._componentId++).toString();
info = this.getOverlayInfo(compOrId);
// if there is no info most probably wrong type component was provided and we just go out
if (!info) {
return;
}
info.id = id;
}
settings = Object.assign({}, this._defaultSettings, info.settings, settings);
info.settings = settings;
this._show(info);
return id;
};
/**
* Hides the component with the ID provided as a parameter.
* ```typescript
* this.overlay.hide(id);
* ```
*/
IgxOverlayService.prototype.hide = function (id) {
this._hide(id);
};
/**
* Hides all the components and the overlay.
* ```typescript
* this.overlay.hideAll();
* ```
*/
IgxOverlayService.prototype.hideAll = function () {
// since overlays are removed on animation done, que all hides
for (var i = this._overlayInfos.length; i--;) {
this.hide(this._overlayInfos[i].id);
}
};
/**
* Repositions the component with ID provided as a parameter.
* ```typescript
* this.overlay.reposition(id);
* ```
*/
IgxOverlayService.prototype.reposition = function (id) {
var overlayInfo = this.getOverlayById(id);
if (!overlayInfo || !overlayInfo.settings) {
console.error('Wrong id provided in overlay.reposition method. Id: ' + id);
return;
}
var contentElement = overlayInfo.elementRef.nativeElement.parentElement;
var contentElementRect = contentElement.getBoundingClientRect();
overlayInfo.settings.positionStrategy.position(contentElement, {
width: contentElementRect.width,
height: contentElementRect.height
}, this._document, false);
};
/**
* Offsets the content along the corresponding axis by the provided amount
* ```typescript
* this.overlay.setOffset(id, deltaX, deltaY);
* ```
*/
IgxOverlayService.prototype.setOffset = function (id, deltaX, deltaY) {
var info = this.getOverlayById(id);
if (!info) {
return;
}
info.transformX += deltaX;
info.transformY += deltaY;
var transformX = info.transformX;
var transformY = info.transformY;
var translate = "translate(" + transformX + "px, " + transformY + "px)";
info.elementRef.nativeElement.parentElement.style.transform = translate;
};
IgxOverlayService.prototype._show = function (info) {
var eventArgs = { id: info.id, componentRef: info.componentRef, cancel: false };
this.onOpening.emit(eventArgs);
if (eventArgs.cancel) {
if (info.componentRef) {
this._appRef.detachView(info.componentRef.hostView);
info.componentRef.destroy();
}
return;
}
// if there is no close animation player, or there is one but it is not started yet we are in clear
// opening. Otherwise, if there is close animation player playing animation now we should not setup
// overlay this is already done
if (!info.closeAnimationPlayer || (info.closeAnimationPlayer && !info.closeAnimationPlayer.hasStarted())) {
var elementRect = info.elementRef.nativeElement.getBoundingClientRect();
info.initialSize = { width: elementRect.width, height: elementRect.height };
info.hook = this.placeElementHook(info.elementRef.nativeElement);
this.moveElementToOverlay(info);
if (info.componentRef) {
info.componentRef.changeDetectorRef.detectChanges();
}
this.updateSize(info);
if (this._overlayInfos.indexOf(info) === -1) {
this._overlayInfos.push(info);
}
info.settings.positionStrategy.position(info.elementRef.nativeElement.parentElement, { width: info.initialSize.width, height: info.initialSize.height }, document, true);
info.settings.scrollStrategy.initialize(this._document, this, info.id);
info.settings.scrollStrategy.attach();
}
this.addOutsideClickListener(info);
this.addResizeHandler(info.id);
if (info.settings.modal) {
this.setupModalWrapper(info);
}
if (info.settings.positionStrategy.settings.openAnimation) {
this.playOpenAnimation(info);
}
else {
// to eliminate flickering show the element just before onOpened fire
info.elementRef.nativeElement.parentElement.style.visibility = '';
this.onOpened.emit({ id: info.id, componentRef: info.componentRef });
}
};
IgxOverlayService.prototype._hide = function (id, event) {
var info = this.getOverlayById(id);
if (!info) {
console.warn('igxOverlay.hide was called with wrong id: ' + id);
return;
}
var eventArgs = { id: id, componentRef: info.componentRef, cancel: false, event: event };
this.onClosing.emit(eventArgs);
if (eventArgs.cancel) {
return;
}
// TODO: synchronize where these are added/attached and where removed/detached
info.settings.scrollStrategy.detach();
this.removeOutsideClickListener(info);
this.removeResizeHandler(info.id);
var child = info.elementRef.nativeElement;
if (info.settings.modal) {
var parent_1 = child.parentNode.parentNode;
this.applyAnimationParams(parent_1, info.settings.positionStrategy.settings.closeAnimation);
parent_1.classList.remove('igx-overlay__wrapper--modal');
parent_1.classList.add('igx-overlay__wrapper');
}
if (info.settings.positionStrategy.settings.closeAnimation) {
this.playCloseAnimation(info);
}
else {
this.onCloseDone(info);
}
};
IgxOverlayService.prototype.getOverlayInfo = function (component, moduleRef) {
var info = { ngZone: this._zone, transformX: 0, transformY: 0 };
if (component instanceof ElementRef) {
info.elementRef = component;
}
else {
var dynamicFactory = void 0;
var factoryResolver = moduleRef ? moduleRef.componentFactoryResolver : this._factoryResolver;
try {
dynamicFactory = factoryResolver.resolveComponentFactory(component);
}
catch (error) {
console.error(error);
return null;
}
var injector = moduleRef ? moduleRef.injector : this._injector;
var dynamicComponent = dynamicFactory.create(injector);
this._appRef.attachView(dynamicComponent.hostView);
// If the element is newly created from a Component, it is wrapped in 'ng-component' tag - we do not want that.
var element = dynamicComponent.location.nativeElement;
info.elementRef = { nativeElement: element };
info.componentRef = dynamicComponent;
}
return info;
};
IgxOverlayService.prototype.placeElementHook = function (element) {
if (!element.parentElement) {
return null;
}
var hook = this._document.createElement('div');
element.parentElement.insertBefore(hook, element);
return hook;
};
IgxOverlayService.prototype.moveElementToOverlay = function (info) {
var wrapperElement = this.getWrapperElement();
var contentElement = this.getContentElement(wrapperElement, info.settings.modal);
this.getOverlayElement(info).appendChild(wrapperElement);
var elementScrollTop = info.elementRef.nativeElement.scrollTop;
contentElement.appendChild(info.elementRef.nativeElement);
if (elementScrollTop) {
info.elementRef.nativeElement.scrollTop = elementScrollTop;
}
};
IgxOverlayService.prototype.getWrapperElement = function () {
var wrapper = this._document.createElement('div');
wrapper.classList.add('igx-overlay__wrapper');
return wrapper;
};
IgxOverlayService.prototype.getContentElement = function (wrapperElement, modal) {
var content = this._document.createElement('div');
if (modal) {
content.classList.add('igx-overlay__content--modal');
content.addEventListener('click', function (ev) {
ev.stopPropagation();
});
}
else {
content.classList.add('igx-overlay__content');
}
content.addEventListener('scroll', function (ev) {
ev.stopPropagation();
});
// hide element to eliminate flickering. Show the element exactly before animation starts
content.style.visibility = 'hidden';
wrapperElement.appendChild(content);
return content;
};
IgxOverlayService.prototype.getOverlayElement = function (info) {
if (info.settings.outlet) {
return info.settings.outlet.nativeElement;
}
if (!this._overlayElement) {
this._overlayElement = this._document.createElement('div');
this._overlayElement.classList.add('igx-overlay');
this._document.body.appendChild(this._overlayElement);
}
return this._overlayElement;
};
IgxOverlayService.prototype.updateSize = function (info) {
if (info.componentRef) {
// if we are positioning component this is first time it gets visible
// and we can finally get its size
info.initialSize = info.elementRef.nativeElement.getBoundingClientRect();
}
// set content div width only if element to show has width
if (info.initialSize.width !== 0) {
info.elementRef.nativeElement.parentElement.style.width = info.initialSize.width + 'px';
}
};
IgxOverlayService.prototype.setupModalWrapper = function (info) {
var _this = this;
var wrapperElement = info.elementRef.nativeElement.parentElement.parentElement;
fromEvent(wrapperElement, 'keydown').pipe(filter(function (ev) { return ev.key === 'Escape' || ev.key === 'Esc'; }), takeUntil(this.destroy$)).subscribe(function () { return _this.hide(info.id); });
wrapperElement.classList.remove('igx-overlay__wrapper');
this.applyAnimationParams(wrapperElement, info.settings.positionStrategy.settings.openAnimation);
wrapperElement.classList.add('igx-overlay__wrapper--modal');
};
IgxOverlayService.prototype.onCloseDone = function (info) {
this.cleanUp(info);
this.onClosed.emit({ id: info.id, componentRef: info.componentRef });
};
IgxOverlayService.prototype.cleanUp = function (info) {
var child = info.elementRef.nativeElement;
var outlet = this.getOverlayElement(info);
if (!outlet.contains(child)) {
console.warn('Component with id:' + info.id + ' is already removed!');
return;
}
outlet.removeChild(child.parentNode.parentNode);
if (info.componentRef) {
this._appRef.detachView(info.componentRef.hostView);
info.componentRef.destroy();
}
if (info.hook) {
info.hook.parentElement.insertBefore(info.elementRef.nativeElement, info.hook);
info.hook.parentElement.removeChild(info.hook);
}
var index = this._overlayInfos.indexOf(info);
this._overlayInfos.splice(index, 1);
// this._overlayElement.parentElement check just for tests that manually delete the element
if (this._overlayInfos.length === 0 && this._overlayElement && this._overlayElement.parentElement) {
this._overlayElement.parentElement.removeChild(this._overlayElement);
this._overlayElement = null;
}
};
IgxOverlayService.prototype.playOpenAnimation = function (info) {
var _this = this;
if (!info.openAnimationPlayer) {
var animationBuilder = this.builder.build(info.settings.positionStrategy.settings.openAnimation);
info.openAnimationPlayer = animationBuilder.create(info.elementRef.nativeElement);
// AnimationPlayer.getPosition returns always 0. To workaround this we are getting inner WebAnimationPlayer
// and then getting the positions from it.
// This is logged in Angular here - https://github.com/angular/angular/issues/18891
// As soon as this is resolved we can remove this hack
var innerRenderer = info.openAnimationPlayer._renderer;
info.openAnimationInnerPlayer = innerRenderer.engine.players[innerRenderer.engine.players.length - 1];
info.openAnimationPlayer.onDone(function () {
_this.onOpened.emit({ id: info.id, componentRef: info.componentRef });
if (info.openAnimationPlayer) {
info.openAnimationPlayer.reset();
info.openAnimationPlayer = null;
}
if (info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted()) {
info.closeAnimationPlayer.reset();
}
});
}
// if there is opening animation already started do nothing
if (info.openAnimationPlayer.hasStarted()) {
return;
}
// if there is closing animation already started start open animation from where close one has reached
// and remove close animation
if (info.closeAnimationPlayer && info.closeAnimationPlayer.hasStarted()) {
// getPosition() returns what part of the animation is passed, e.g. 0.5 if half the animation
// is done, 0.75 if 3/4 of the animation is done. As we need to start next animation from where
// the previous has finished we need the amount up to 1, therefore we are subtracting what
// getPosition() returns from one
var position = 1 - info.closeAnimationInnerPlayer.getPosition();
info.closeAnimationPlayer.reset();
info.closeAnimationPlayer = null;
info.openAnimationPlayer.init();
info.openAnimationPlayer.setPosition(position);
}
this.onAnimation.emit({ id: info.id, animationPlayer: info.openAnimationPlayer, animationType: 'open' });
// to eliminate flickering show the element just before animation start
info.elementRef.nativeElement.parentElement.style.visibility = '';
info.openAnimationPlayer.play();
};
IgxOverlayService.prototype.playCloseAnimation = function (info) {
var _this = this;
if (!info.closeAnimationPlayer) {
var animationBuilder = this.builder.build(info.settings.positionStrategy.settings.closeAnimation);
info.closeAnimationPlayer = animationBuilder.create(info.elementRef.nativeElement);
// AnimationPlayer.getPosition returns always 0. To workaround this we are getting inner WebAnimationPlayer
// and then getting the positions from it.
// This is logged in Angular here - https://github.com/angular/angular/issues/18891
// As soon as this is resolved we can remove this hack
var innerRenderer = info.closeAnimationPlayer._renderer;
info.closeAnimationInnerPlayer = innerRenderer.engine.players[innerRenderer.engine.players.length - 1];
info.closeAnimationPlayer.onDone(function () {
if (info.closeAnimationPlayer) {
info.closeAnimationPlayer.reset();
info.closeAnimationPlayer = null;
}
if (info.openAnimationPlayer && info.openAnimationPlayer.hasStarted()) {
info.openAnimationPlayer.reset();
}
_this.onCloseDone(info);
});
}
// if there is closing animation already started do nothing
if (info.closeAnimationPlayer.hasStarted()) {
return;
}
// if there is opening animation already started start close animation from where open one has reached
// and remove open animation
if (info.openAnimationPlayer && info.openAnimationPlayer.hasStarted()) {
// getPosition() returns what part of the animation is passed, e.g. 0.5 if half the animation
// is done, 0.75 if 3/4 of the animation is done. As we need to start next animation from where
// the previous has finished we need the amount up to 1, therefore we are subtracting what
// getPosition() returns from one
var position = 1 - info.openAnimationInnerPlayer.getPosition();
info.openAnimationPlayer.reset();
info.openAnimationPlayer = null;
info.closeAnimationPlayer.init();
info.closeAnimationPlayer.setPosition(position);
}
this.onAnimation.emit({ id: info.id, animationPlayer: info.closeAnimationPlayer, animationType: 'close' });
info.closeAnimationPlayer.play();
};
// TODO: check if applyAnimationParams will work with complex animations
IgxOverlayService.prototype.applyAnimationParams = function (wrapperElement, animationOptions) {
if (!animationOptions) {
wrapperElement.style.transitionDuration = '0ms';
return;
}
if (animationOptions.type === 10 /* AnimateRef */) {
animationOptions = animationOptions.animation;
}
if (!animationOptions.options || !animationOptions.options.params) {
return;
}
var params = animationOptions.options.params;
if (params.duration) {
wrapperElement.style.transitionDuration = params.duration;
}
if (params.easing) {
wrapperElement.style.transitionTimingFunction = params.easing;
}
};
/** @hidden @internal */
IgxOverlayService.prototype.getOverlayById = function (id) {
if (!id) {
return null;
}
var info = this._overlayInfos.find(function (e) { return e.id === id; });
return info;
};
IgxOverlayService.prototype.addOutsideClickListener = function (info) {
var _this = this;
if (info.settings.closeOnOutsideClick) {
if (info.settings.modal) {
fromEvent(info.elementRef.nativeElement.parentElement.parentElement, 'click')
.pipe(takeUntil(this.destroy$))
.subscribe(function (e) { return _this._hide(info.id, e); });
}
else if (
// if all overlays minus closing overlays equals one add the handler
this._overlayInfos.filter(function (x) { return x.settings.closeOnOutsideClick && !x.settings.modal; }).length -
this._overlayInfos.filter(function (x) { return x.settings.closeOnOutsideClick && !x.settings.modal &&
x.closeAnimationPlayer &&
x.closeAnimationPlayer.hasStarted(); }).length === 1) {
this._document.addEventListener('click', this.documentClicked, true);
}
}
};
IgxOverlayService.prototype.removeOutsideClickListener = function (info) {
if (info.settings.modal === false) {
var shouldRemoveClickEventListener_1 = true;
this._overlayInfos.forEach(function (o) {
if (o.settings.modal === false && o.id !== info.id) {
shouldRemoveClickEventListener_1 = false;
}
});
if (shouldRemoveClickEventListener_1) {
this._document.removeEventListener('click', this.documentClicked, true);
}
}
};
IgxOverlayService.prototype.addResizeHandler = function (id) {
var closingOverlaysCount = this._overlayInfos
.filter(function (o) { return o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted(); })
.length;
if (this._overlayInfos.length - closingOverlaysCount === 1) {
this._document.defaultView.addEventListener('resize', this.repositionAll);
}
};
IgxOverlayService.prototype.removeResizeHandler = function (id) {
var closingOverlaysCount = this._overlayInfos
.filter(function (o) { return o.closeAnimationPlayer && o.closeAnimationPlayer.hasStarted(); })
.length;
if (this._overlayInfos.length - closingOverlaysCount === 1) {
this._document.defaultView.removeEventListener('resize', this.repositionAll);
}
};
/**
*@hidden
*/
IgxOverlayService.prototype.ngOnDestroy = function () {
this.destroy$.next(true);
this.destroy$.complete();
};
IgxOverlayService.ctorParameters = function () { return [
{ type: ComponentFactoryResolver },
{ type: ApplicationRef },
{ type: Injector },
{ type: AnimationBuilder },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: NgZone }
]; };
IgxOverlayService.ɵprov = i0.ɵɵdefineInjectable({ factory: function IgxOverlayService_Factory() { return new IgxOverlayService(i0.ɵɵinject(i0.ComponentFactoryResolver), i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.AnimationBuilder), i0.ɵɵinject(i2.DOCUMENT), i0.ɵɵinject(i0.NgZone)); }, token: IgxOverlayService, providedIn: "root" });
IgxOverlayService = __decorate([
Injectable({ providedIn: 'root' }),
__param(4, Inject(DOCUMENT)),
__metadata("design:paramtypes", [ComponentFactoryResolver,
ApplicationRef,
Injector,
AnimationBuilder, Object, NgZone])
], IgxOverlayService);
return IgxOverlayService;
}());
export { IgxOverlayService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvb3ZlcmxheS9vdmVybGF5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFVakUsT0FBTyxFQUNILGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixVQUFVLEVBQ1YsUUFBUSxFQUNSLElBQUksRUFDSixTQUFTLEVBQ1QsV0FBVyxFQUNYLE1BQU0sRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsMEJBQTBCLEVBQUUscUJBQXFCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2SSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7OztBQUU3RCxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7QUFFekI7OztHQUdHO0FBRUg7SUFnRUksMkJBQ1ksZ0JBQTBDLEVBQzFDLE9BQXVCLEVBQ3ZCLFNBQW1CLEVBQ25CLE9BQXlCLEVBQ1AsUUFBYSxFQUMvQixLQUFhO1FBTnpCLGlCQVFDO1FBUFcscUJBQWdCLEdBQWhCLGdCQUFnQixDQUEwQjtRQUMxQyxZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN2QixjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQ25CLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBQ1AsYUFBUSxHQUFSLFFBQVEsQ0FBSztRQUMvQixVQUFLLEdBQUwsS0FBSyxDQUFRO1FBckVqQixpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixrQkFBYSxHQUFrQixFQUFFLENBQUM7UUFHbEMsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7UUFFbEMscUJBQWdCLEdBQW9CO1lBQ3hDLGdCQUFnQixFQUFFLElBQUksc0JBQXNCLEVBQUU7WUFDOUMsY0FBYyxFQUFFLElBQUksa0JBQWtCLEVBQUU7WUFDeEMsS0FBSyxFQUFFLElBQUk7WUFDWCxtQkFBbUIsRUFBRSxJQUFJO1NBQzVCLENBQUM7UUFFRjs7Ozs7OztXQU9HO1FBQ0ksY0FBUyxHQUFHLElBQUksWUFBWSxFQUE4QixDQUFDO1FBRWxFOzs7Ozs7O1dBT0c7UUFDSSxhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQW9CLENBQUM7UUFFdkQ7Ozs7Ozs7V0FPRztRQUNJLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBMkIsQ0FBQztRQUUvRDs7Ozs7OztXQU9HO1FBQ0ksYUFBUSxHQUFHLElBQUksWUFBWSxFQUFvQixDQUFDO1FBRXZEOzs7Ozs7O1dBT0c7UUFDSSxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUE2QixDQUFDO1FBcWhCM0Qsb0JBQWUsR0FBRyxVQUFDLEVBQWM7WUFDckMsa0ZBQWtGO1lBQ2xGLCtDQUErQztZQUMvQywwRUFBMEU7WUFDMUUsd0ZBQXdGO1lBQ3hGLHlGQUF5RjtZQUN6Rix3Q0FBd0M7WUFDeEMsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRztnQkFDMUMsSUFBTSxJQUFJLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtvQkFDckIsT0FBTztpQkFDVjtnQkFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLEVBQUU7b0JBQ25DLElBQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFhLENBQUM7b0JBQ2hDLDREQUE0RDtvQkFDNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRTt3QkFDakQsaUdBQWlHO3dCQUNqRyxJQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxNQUFxQixDQUFDO3dCQUNyRixJQUFJLHFCQUFxQixHQUFHLEtBQUssQ0FBQzt3QkFDbEMsSUFBSSxjQUFjLEVBQUU7NEJBQ2hCLHFCQUFxQixHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7eUJBQzNEO3dCQUVELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMscUJBQXFCLElBQUkscUJBQXFCLENBQUMsRUFBRTs0QkFDakUsNkVBQTZFOzRCQUM3RSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUU7Z0NBQ3hFLEtBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQzs2QkFDM0I7eUJBQ0o7cUJBQ0o7eUJBQU07d0JBQ0gsK0RBQStEO3dCQUMvRCxPQUFPO3FCQUNWO2lCQUNKO2FBQ0o7UUFDTCxDQUFDLENBQUE7UUFzREQsY0FBYztRQUNQLGtCQUFhLEdBQUc7WUFDbkIsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRztnQkFDMUMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQzdDO1FBQ0wsQ0FBQyxDQUFBO1FBMW1CRyxJQUFJLENBQUMsU0FBUyxHQUFhLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDN0MsQ0FBQztJQW1CRCxrQ0FBTSxHQUFOLFVBQU8sU0FBaUMsRUFBRSxRQUEwQixFQUNoRSxTQUEyRTtRQUMzRSxJQUFJLElBQWlCLENBQUM7UUFDdEIsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRWpELDBGQUEwRjtRQUMxRixJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1AsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUVELElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzlCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBb0JELGdDQUFJLEdBQUosVUFBSyxRQUF5QyxFQUFFLFFBQTBCO1FBQ3RFLElBQUksSUFBaUIsQ0FBQztRQUN0QixJQUFJLEVBQVUsQ0FBQztRQUNmLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFO1lBQzlCLEVBQUUsR0FBRyxRQUFRLENBQUM7WUFDZCxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNQLE9BQU8sQ0FBQyxJQUFJLENBQUMsNENBQTRDLEdBQUcsUUFBUSxDQUFDLENBQUM7Z0JBQ3RFLE9BQU8sSUFBSSxDQUFDO2FBQ2Y7U0FDSjthQUFNO1lBQ0gsWUFBWSxHQUFHLFdBQVcsQ0FDdEIsK0ZBQStGO2dCQUMvRiw4Q0FBOEMsRUFDOUMsWUFBWSxDQUFDLENBQUM7WUFDbEIsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdEMsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFckMsMEZBQTBGO1lBQzFGLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQ1AsT0FBTzthQUNWO1lBRUQsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7U0FDaEI7UUFFRCxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFFekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQixPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGdDQUFJLEdBQUosVUFBSyxFQUFVO1FBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxtQ0FBTyxHQUFQO1FBQ0ksOERBQThEO1FBQzlELEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEdBQUc7WUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZDO0lBQ0wsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsc0NBQVUsR0FBVixVQUFXLEVBQVU7UUFDakIsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRTtZQUN2QyxPQUFPLENBQUMsS0FBSyxDQUFDLHNEQUFzRCxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLE9BQU87U0FDVjtRQUVELElBQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQztRQUMxRSxJQUFNLGtCQUFrQixHQUFHLGNBQWMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ2xFLFdBQVcsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUMxQyxjQUFjLEVBQ2Q7WUFDSSxLQUFLLEVBQUUsa0JBQWtCLENBQUMsS0FBSztZQUMvQixNQUFNLEVBQUUsa0JBQWtCLENBQUMsTUFBTTtTQUNwQyxFQUNELElBQUksQ0FBQyxTQUFTLEVBQ2QsS0FBSyxDQUFDLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxxQ0FBUyxHQUFULFVBQVUsRUFBVSxFQUFFLE1BQWMsRUFBRSxNQUFjO1FBQ2hELElBQU0sSUFBSSxHQUFnQixJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWxELElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDUixPQUFPO1NBQ1Q7UUFFRCxJQUFJLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQztRQUUxQixJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ25DLElBQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFFbkMsSUFBTSxTQUFTLEdBQUcsZUFBYSxVQUFVLFlBQU8sVUFBVSxRQUFLLENBQUM7UUFDaEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO0lBQzVFLENBQUM7SUFFTyxpQ0FBSyxHQUFiLFVBQWMsSUFBaUI7UUFDM0IsSUFBTSxTQUFTLEdBQStCLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQzlHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9CLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRTtZQUNsQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDL0I7WUFFRCxPQUFPO1NBQ1Y7UUFFRCxvR0FBb0c7UUFDcEcsb0dBQW9HO1FBQ3BHLGdDQUFnQztRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUU7WUFDdEcsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMxRSxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM1RSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRWpFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDdkQ7WUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RCLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2pDO1lBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQ25DLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFDM0MsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEVBQ2xFLFFBQVEsRUFDUixJQUFJLENBQUMsQ0FBQztZQUNWLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDekM7UUFFRCxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUUvQixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1lBQ3JCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoQztRQUVELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFO1lBQ3ZELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoQzthQUFNO1lBQ0gsc0VBQXNFO1lBQ3RFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztZQUNsRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztTQUN4RTtJQUNMLENBQUM7SUFFTyxpQ0FBSyxHQUFiLFVBQWMsRUFBVSxFQUFFLEtBQWE7UUFDbkMsSUFBTSxJQUFJLEdBQWdCLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFbEQsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNQLE9BQU8sQ0FBQyxJQUFJLENBQUMsNENBQTRDLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEUsT0FBTztTQUNWO1FBRUQsSUFBTSxTQUFTLEdBQUcsRUFBRSxFQUFFLElBQUEsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssT0FBQSxFQUFFLENBQUM7UUFDaEYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0IsSUFBSSxTQUFTLENBQUMsTUFBTSxFQUFFO1lBQ2xCLE9BQU87U0FDVjtRQUVELCtFQUErRTtRQUMvRSxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVsQyxJQUFNLEtBQUssR0FBZ0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7UUFDekQsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtZQUNyQixJQUFNLFFBQU0sR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQXlCLENBQUM7WUFDMUQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMxRixRQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQ3ZELFFBQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUM7U0FDaEQ7UUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRTtZQUN4RCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDakM7YUFBTTtZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDMUI7SUFDTCxDQUFDO0lBRU8sMENBQWMsR0FBdEIsVUFBdUIsU0FBYyxFQUFFLFNBQTJFO1FBQzlHLElBQU0sSUFBSSxHQUFnQixFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQy9FLElBQUksU0FBUyxZQUFZLFVBQVUsRUFBRTtZQUNqQyxJQUFJLENBQUMsVUFBVSxHQUFlLFNBQVMsQ0FBQztTQUMzQzthQUFNO1lBQ0gsSUFBSSxjQUFjLFNBQXNCLENBQUM7WUFDekMsSUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztZQUMvRixJQUFJO2dCQUNBLGNBQWMsR0FBRyxlQUFlLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7YUFDdkU7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDWixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyQixPQUFPLElBQUksQ0FBQzthQUNmO1lBRUQsSUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ2pFLElBQU0sZ0JBQWdCLEdBQXFCLGNBQWMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0UsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFbkQsK0dBQStHO1lBQy9HLElBQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7WUFDeEQsSUFBSSxDQUFDLFVBQVUsR0FBZSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUN6RCxJQUFJLENBQUMsWUFBWSxHQUFHLGdCQUFnQixDQUFDO1NBQ3hDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVPLDRDQUFnQixHQUF4QixVQUF5QixPQUFvQjtRQUN6QyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRTtZQUN4QixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakQsT0FBTyxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2xELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFTyxnREFBb0IsR0FBNUIsVUFBNkIsSUFBaUI7UUFDMUMsSUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDaEQsSUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25GLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDekQsSUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUM7UUFDakUsY0FBYyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTFELElBQUksZ0JBQWdCLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLGdCQUFnQixDQUFDO1NBQzlEO0lBQ0wsQ0FBQztJQUVPLDZDQUFpQixHQUF6QjtRQUNJLElBQU0sT0FBTyxHQUFnQixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRSxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzlDLE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFFTyw2Q0FBaUIsR0FBekIsVUFBMEIsY0FBMkIsRUFBRSxLQUFjO1FBQ2pFLElBQU0sT0FBTyxHQUFnQixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRSxJQUFJLEtBQUssRUFBRTtZQUNQLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLDZCQUE2QixDQUFDLENBQUM7WUFDckQsT0FBTyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxVQUFDLEVBQVM7Z0JBQ3hDLEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6QixDQUFDLENBQUMsQ0FBQztTQUNOO2FBQU07WUFDSCxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1NBQ2pEO1FBRUQsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxVQUFDLEVBQVM7WUFDekMsRUFBRSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO1FBRUgsMEZBQTBGO1FBQzFGLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQztRQUVwQyxjQUFjLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFFTyw2Q0FBaUIsR0FBekIsVUFBMEIsSUFBaUI7UUFDdkMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUN0QixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztTQUM3QztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDekQ7UUFFRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7SUFDaEMsQ0FBQztJQUVPLHNDQUFVLEdBQWxCLFVBQW1CLElBQWlCO1FBQ2hDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNuQixzRUFBc0U7WUFDdEUsbUNBQW1DO1lBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMscUJBQXFCLEVBQUUsQ0FBQztTQUM1RTtRQUVELDBEQUEwRDtRQUMxRCxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxLQUFLLENBQUMsRUFBRTtZQUM5QixJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7U0FDM0Y7SUFDTCxDQUFDO0lBRU8sNkNBQWlCLEdBQXpCLFVBQTBCLElBQWlCO1FBQTNDLGlCQVNDO1FBUkcsSUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQztRQUNqRixTQUFTLENBQUMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FDckMsTUFBTSxDQUFDLFVBQUMsRUFBaUIsSUFBSyxPQUFBLEVBQUUsQ0FBQyxHQUFHLEtBQUssUUFBUSxJQUFJLEVBQUUsQ0FBQyxHQUFHLEtBQUssS0FBSyxFQUF2QyxDQUF1QyxDQUFDLEVBQ3RFLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQzNCLENBQUMsU0FBUyxDQUFDLGNBQU0sT0FBQSxLQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBbEIsQ0FBa0IsQ0FBQyxDQUFDO1FBQ3RDLGNBQWMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNqRyxjQUFjLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFTyx1Q0FBVyxHQUFuQixVQUFvQixJQUFpQjtRQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFTyxtQ0FBTyxHQUFmLFVBQWdCLElBQWlCO1FBQzdCLElBQU0sS0FBSyxHQUFnQixJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztRQUN6RCxJQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLHNCQUFzQixDQUFDLENBQUM7WUFDdEUsT0FBTztTQUNWO1FBRUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNuQixJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7U0FDL0I7UUFFRCxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDWCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9FLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDbEQ7UUFFRCxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFcEMsMkZBQTJGO1FBQzNGLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUU7WUFDL0YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNyRSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztTQUMvQjtJQUNMLENBQUM7SUFFTyw2Q0FBaUIsR0FBekIsVUFBMEIsSUFBaUI7UUFBM0MsaUJBZ0RDO1FBL0NHLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDM0IsSUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNuRyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7WUFFbEYsNEdBQTRHO1lBQzVHLDJDQUEyQztZQUMzQyxvRkFBb0Y7WUFDcEYsdURBQXVEO1lBQ3ZELElBQU0sYUFBYSxHQUFTLElBQUksQ0FBQyxtQkFBb0IsQ0FBQyxTQUFTLENBQUM7WUFDaEUsSUFBSSxDQUFDLHdCQUF3QixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN0RyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDO2dCQUM1QixLQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztnQkFDckUsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUU7b0JBQzFCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDakMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztpQkFDbkM7Z0JBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxFQUFFO29CQUNyRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLENBQUM7aUJBQ3JDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELDREQUE0RDtRQUM1RCxJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUN2QyxPQUFPO1NBQ1Y7UUFFRCx1R0FBdUc7UUFDdkcsOEJBQThCO1FBQzlCLElBQUksSUFBSSxDQUFDLG9CQUFvQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUNyRSw4RkFBOEY7WUFDOUYsZ0dBQWdHO1lBQ2hHLDJGQUEyRjtZQUMzRixrQ0FBa0M7WUFDbEMsSUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNsRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztZQUNqQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNsRDtRQUVELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUV6Ryx3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2xFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRU8sOENBQWtCLEdBQTFCLFVBQTJCLElBQWlCO1FBQTVDLGlCQThDQztRQTdDRyxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFO1lBQzVCLElBQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDcEcsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRW5GLDRHQUE0RztZQUM1RywyQ0FBMkM7WUFDM0Msb0ZBQW9GO1lBQ3BGLHVEQUF1RDtZQUN2RCxJQUFNLGFBQWEsR0FBUyxJQUFJLENBQUMsb0JBQXFCLENBQUMsU0FBUyxDQUFDO1lBQ2pFLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFdkcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQztnQkFDN0IsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7b0JBQzNCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDbEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztpQkFDcEM7Z0JBRUQsSUFBSSxJQUFJLENBQUMsbUJBQW1CLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsRUFBRSxFQUFFO29CQUNuRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLENBQUM7aUJBQ3BDO2dCQUNELEtBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUVELDREQUE0RDtRQUM1RCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUN4QyxPQUFPO1NBQ1Y7UUFFRCx1R0FBdUc7UUFDdkcsNkJBQTZCO1FBQzdC