UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

608 lines 95.7 kB
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvb3ZlcmxheS9vdmVybGF5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFVakUsT0FBTyxFQUNILGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixVQUFVLEVBQ1YsUUFBUSxFQUNSLElBQUksRUFDSixTQUFTLEVBQ1QsV0FBVyxFQUNYLE1BQU0sRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsMEJBQTBCLEVBQUUscUJBQXFCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2SSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7OztBQUU3RCxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7QUFFekI7OztHQUdHO0FBRUg7SUFnRUksMkJBQ1ksZ0JBQTBDLEVBQzFDLE9BQXVCLEVBQ3ZCLFNBQW1CLEVBQ25CLE9BQXlCLEVBQ1AsUUFBYSxFQUMvQixLQUFhO1FBTnpCLGlCQVFDO1FBUFcscUJBQWdCLEdBQWhCLGdCQUFnQixDQUEwQjtRQUMxQyxZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN2QixjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQ25CLFlB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