UNPKG

@wizdm/animate

Version:

On Scroll Animation for Angular

154 lines 22.9 kB
import { Component, Input, Output, EventEmitter, HostBinding, HostListener, ElementRef, Renderer2 } from '@angular/core'; import { startWith, map, takeWhile, delay, distinctUntilChanged } from 'rxjs/operators'; import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion'; import { Subject } from 'rxjs'; import { trigger } from '@angular/animations'; import { AnimateService } from './animate.service'; // Animations import { beat, bounce, headShake, heartBeat, pulse, rubberBand, shake, swing, wobble, jello, tada, flip } from './attention-seekers'; import { bumpIn, bounceIn, fadeIn, flipIn, jackInTheBox, landing, rollIn, zoomIn } from './entrances'; import { bounceOut, fadeOut, hinge, rollOut, zoomOut } from './exits'; import { state, style } from '@angular/animations'; export class AnimateComponent { constructor(elm, scroll, renderer) { this.elm = elm; this.scroll = scroll; this.renderer = renderer; this.replay$ = new Subject(); // Animating properties this.animating = false; this.animated = false; this.disabled = false; /** Emits at the end of the animation */ this.start = new EventEmitter(); /** Emits at the end of the animation */ this.done = new EventEmitter(); this.paused = false; this.threshold = 0; this.once = false; } get idle() { return { value: `idle-${this.animate}` }; } get play() { const params = {}; // Builds the params object, so, leaving to the default values when undefined if (!!this.timing) { params['timing'] = this.timing; } if (!!this.delay) { params['delay'] = this.delay; } return { value: this.animate, params }; } /** Speeds up or slows down the animation */ set speed(speed) { // Turns the requested speed into a valid timing this.timing = { slower: '3s', slow: '2s', normal: '1s', fast: '500ms', faster: '300ms' }[speed || 'normal'] || '1s'; } /** Delays the animation */ set postpone(delay) { // Coerces the input into a number first const value = coerceNumberProperty(delay, 0); if (value) { // Turns a valid number into a ms delay this.delay = `${value}ms`; } else { // Test the string for a valid delay combination this.delay = /^\d+(?:ms|s)$/.test(delay) ? delay : ''; } } /** Disables the animation */ set disableAnimation(value) { this.disabled = coerceBooleanProperty(value); } animationStart() { this.animating = true; this.animated = false; this.start.emit(); } animationDone() { this.animating = false; this.animated = true; this.done.emit(); /** * Removes spurious 'animation' style from the element once done with the animation. * This behaviour has been observed when running on iOS devices where for some reason * the animation engine do not properly clean-up the animation style using cubic-bezier() * as its timing function. The issue do not appear with ease-in/out and others. * */ this.renderer.removeStyle(this.elm.nativeElement, 'animation'); } /** When true, keeps the animation idle until the next replay triggers */ set pauseAnimation(value) { this.paused = coerceBooleanProperty(value); } /** When defined, triggers the animation on element scrolling in the viewport by the specified amount. Amount defaults to 50% when not specified */ set enableAOS(value) { this.threshold = coerceNumberProperty(value, 0.5); } /** When true, triggers the animation on element scrolling in the viewport */ set aosOnce(value) { this.once = coerceBooleanProperty(value); } /** Replays the animation */ set replay(replay) { // Re-triggers the animation again on request (skipping the very fist value) if (!!this.trigger && coerceBooleanProperty(replay)) { this.trigger = this.idle; this.replay$.next(true); } } ngOnInit() { // Triggers the animation based on the input flags this.sub = this.replay$.pipe( // Waits the next round to re-trigger delay(0), // Triggers immediately when not paused startWith(!this.paused), // Builds the AOS observable from the common service this.scroll.trigger(this.elm, this.threshold), // Stop taking the first on trigger when aosOnce is set takeWhile(trigger => !trigger || !this.once, true), // Maps the trigger into animation states map(trigger => trigger ? this.play : this.idle), // Always start with idle startWith(this.idle), // Eliminates multiple triggers distinctUntilChanged()).subscribe(trigger => this.trigger = trigger); } // Disposes of the observable ngOnDestroy() { this.sub.unsubscribe(); } } AnimateComponent.decorators = [ { type: Component, args: [{ selector: '[wmAnimate]', template: '<ng-content></ng-content>', animations: [trigger('animate', [ // Attention seekers ...beat, ...bounce, ...flip, ...headShake, ...heartBeat, ...jello, ...pulse, ...rubberBand, ...shake, ...swing, ...tada, ...wobble, // Entrances ...bumpIn, ...bounceIn, ...fadeIn, ...flipIn, ...jackInTheBox, ...landing, ...rollIn, ...zoomIn, // Exits ...bounceOut, ...fadeOut, ...hinge, ...rollOut, ...zoomOut, // None state('none', style('*')), state('idle-none', style('*')) ])] },] } ]; /** @nocollapse */ AnimateComponent.ctorParameters = () => [ { type: ElementRef }, { type: AnimateService }, { type: Renderer2 } ]; AnimateComponent.propDecorators = { trigger: [{ type: HostBinding, args: ['@animate',] }], animate: [{ type: Input, args: ['wmAnimate',] }], speed: [{ type: Input }], postpone: [{ type: Input, args: ['delay',] }], disableAnimation: [{ type: Input, args: ['disabled',] }], disabled: [{ type: HostBinding, args: ['@.disabled',] }], start: [{ type: Output }], animationStart: [{ type: HostListener, args: ['@animate.start',] }], done: [{ type: Output }], animationDone: [{ type: HostListener, args: ['@animate.done',] }], pauseAnimation: [{ type: Input, args: ['paused',] }], enableAOS: [{ type: Input, args: ['aos',] }], aosOnce: [{ type: Input, args: ['once',] }], replay: [{ type: Input }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9hbmltYXRlL3NyYy9saWIvYW5pbWF0ZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVJLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRixPQUFPLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELGFBQWE7QUFDYixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNySSxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN0RyxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0RSxPQUFPLEVBQUUsS0FB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LE1BQU0sRUFBQyxHQUFHLE1BQU07d0JBQ3hGLFFBQVE7d0JBQ1IsR0FBRyxTQUFTLEVBQUMsR0FBRyxPQUFPLEVBQUMsR0FBRyxLQUFLLEVBQUMsR0FBRyxPQUFPLEVBQUMsR0FBRyxPQUFPO3dCQUN0RCxPQUFPO3dCQUNQLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7cUJBQzFELENBQUMsQ0FBQzthQUNKOzs7O1lBcEM4RixVQUFVO1lBS2hHLGNBQWM7WUFMb0YsU0FBUzs7O3NCQW9EakgsV0FBVyxTQUFDLFVBQVU7c0JBZXRCLEtBQUssU0FBQyxXQUFXO29CQUdqQixLQUFLO3VCQVlMLEtBQUssU0FBQyxPQUFPOytCQWNiLEtBQUssU0FBQyxVQUFVO3VCQUNoQixXQUFXLFNBQUMsWUFBWTtvQkFJeEIsTUFBTTs2QkFDTixZQUFZLFNBQUMsZ0JBQWdCO21CQUk3QixNQUFNOzRCQUNOLFlBQVksU0FBQyxlQUFlOzZCQWU1QixLQUFLLFNBQUMsUUFBUTt3QkFJZCxLQUFLLFNBQUMsS0FBSztzQkFJWCxLQUFLLFNBQUMsTUFBTTtxQkFJWixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIE9uRGVzdHJveSwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgSG9zdExpc3RlbmVyLCBFbGVtZW50UmVmLCBSZW5kZXJlcjIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHN0YXJ0V2l0aCwgbWFwLCB0YWtlV2hpbGUsIGRlbGF5LCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSwgY29lcmNlTnVtYmVyUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0cmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBBbmltYXRlU2VydmljZSB9IGZyb20gJy4vYW5pbWF0ZS5zZXJ2aWNlJztcbi8vIEFuaW1hdGlvbnNcbmltcG9ydCB7IGJlYXQsIGJvdW5jZSwgaGVhZFNoYWtlLCBoZWFydEJlYXQsIHB1bHNlLCBydWJiZXJCYW5kLCBzaGFrZSwgc3dpbmcsIHdvYmJsZSwgamVsbG8sIHRhZGEsIGZsaXAgfSBmcm9tICcuL2F0dGVudGlvbi1zZWVrZXJzJztcbmltcG9ydCB7IGJ1bXBJbiwgYm91bmNlSW4sIGZhZGVJbiwgZmxpcEluLCBqYWNrSW5UaGVCb3gsIGxhbmRpbmcsIHJvbGxJbiwgem9vbUluIH0gZnJvbSAnLi9lbnRyYW5jZXMnO1xuaW1wb3J0IHsgYm91bmNlT3V0LCBmYWRlT3V0LCBoaW5nZSwgcm9sbE91dCwgem9vbU91dCB9IGZyb20gJy4vZXhpdHMnO1xuaW1wb3J0IHsgc3RhdGUsIHN0eWxlIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5cbmV4cG9ydCB0eXBlIHdtQW5pbWF0ZVNwZWVkID0gJ3Nsb3dlcid8J3Nsb3cnfCdub3JtYWwnfCdmYXN0J3wnZmFzdGVyJztcbmV4cG9ydCB0eXBlIHdtQW5pbWF0aW9ucyA9IFxuICAvLyBBdHRlbnRpb24gc2Vla2Vyc1xuICAnYmVhdCd8J2JvdW5jZSd8J2ZsaXAnfCdoZWFkU2hha2UnfCdoZWFydEJlYXQnfCdqZWxsbyd8J3B1bHNlJ3wncnViYmVyQmFuZCd8J3NoYWtlJ3wnc3dpbmcnfCd0YWRhJ3wnd29iYmxlJ3xcbiAgLy8gRW50cmFuY2VzXG4gICdidW1wSW4nfCdib3VuY2VJbid8J2JvdW5jZUluRG93bid8J2JvdW5jZUluTGVmdCd8J2JvdW5jZUluVXAnfCdib3VuY2VJblJpZ2h0J3wnZmFkZUluJ3wnZmFkZUluUmlnaHQnfCdmYWRlSW5MZWZ0J3wnZmFkZUluVXAnfCdmYWRlSW5Eb3duJ3wnZmxpcEluWCd8J2ZsaXBJblknfCdqYWNrSW5UaGVCb3gnfCdsYW5kaW5nJ3wncm9sbEluJ3wnem9vbUluJ3wnem9vbUluRG93bid8J3pvb21JbkxlZnQnfCd6b29tSW5VcCd8J3pvb21JblJpZ2h0J3xcbiAgLy8gRXhpdHNcbiAgJ2JvdW5jZU91dCd8J2JvdW5jZU91dERvd24nfCdib3VuY2VPdXRVcCd8J2JvdW5jZU91dFJpZ2h0J3wnYm91bmNlT3V0TGVmdCd8J2ZhZGVPdXQnfCdmYWRlT3V0UmlnaHQnfCdmYWRlT3V0TGVmdCd8J2ZhZGVPdXREb3duJ3wnZmFkZU91dFVwJ3wnaGluZ2UnfCdyb2xsT3V0J3wnem9vbU91dCd8J3pvb21PdXREb3duJ3wnem9vbU91dFJpZ2h0J3wnem9vbU91dFVwJ3wnem9vbU91dExlZnQnfFxuICAvLyBOb25lXG4gICdub25lJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnW3dtQW5pbWF0ZV0nLFxuICB0ZW1wbGF0ZTogJzxuZy1jb250ZW50PjwvbmctY29udGVudD4nLFxuICBhbmltYXRpb25zOiBbIHRyaWdnZXIoJ2FuaW1hdGUnLCBbXG4gICAgLy8gQXR0ZW50aW9uIHNlZWtlcnNcbiAgICAuLi5iZWF0LC4uLmJvdW5jZSwuLi5mbGlwLC4uLmhlYWRTaGFrZSwuLi5oZWFydEJlYXQsLi4uamVsbG8sLi4ucHVsc2UsLi4ucnViYmVyQmFuZCwuLi5zaGFrZSwuLi5zd2luZywuLi50YWRhLC4uLndvYmJsZSxcbiAgICAvLyBFbnRyYW5jZXNcbiAgICAuLi5idW1wSW4sLi4uYm91bmNlSW4sLi4uZmFkZUluLC4uLmZsaXBJbiwuLi5qYWNrSW5UaGVCb3gsLi4ubGFuZGluZywuLi5yb2xsSW4sLi4uem9vbUluLFxuICAgIC8vIEV4aXRzXG4gICAgLi4uYm91bmNlT3V0LC4uLmZhZGVPdXQsLi4uaGluZ2UsLi4ucm9sbE91dCwuLi56b29tT3V0LFxuICAgIC8vIE5vbmVcbiAgICBzdGF0ZSgnbm9uZScsIHN0eWxlKCcqJykpLCBzdGF0ZSgnaWRsZS1ub25lJywgc3R5bGUoJyonKSlcbiAgXSldXG59KVxuZXhwb3J0IGNsYXNzIEFuaW1hdGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSByZXBsYXkkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSBzdWI6IFN1YnNjcmlwdGlvbjtcblxuICAvLyBBbmltYXRpbmcgcGFyYW1ldGVyc1xuICBwcml2YXRlIHRpbWluZzogc3RyaW5nO1xuICBwcml2YXRlIGRlbGF5OiBzdHJpbmc7XG4gIFxuICAvLyBBbmltYXRpbmcgcHJvcGVydGllc1xuICBwdWJsaWMgYW5pbWF0aW5nID0gZmFsc2U7XG4gIHB1YmxpYyBhbmltYXRlZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxtOiBFbGVtZW50UmVmLCBwcml2YXRlIHNjcm9sbDogQW5pbWF0ZVNlcnZpY2UsIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge31cblxuICBASG9zdEJpbmRpbmcoJ0BhbmltYXRlJykgXG4gIHB1YmxpYyB0cmlnZ2VyO1xuXG4gIHByaXZhdGUgZ2V0IGlkbGUoKSB7IHJldHVybiB7IHZhbHVlOiBgaWRsZS0ke3RoaXMuYW5pbWF0ZX1gIH07IH1cbiAgcHJpdmF0ZSBnZXQgcGxheSgpIHtcblxuICAgIGNvbnN0IHBhcmFtcyA9IHt9OyBcbiAgICAvLyBCdWlsZHMgdGhlIHBhcmFtcyBvYmplY3QsIHNvLCBsZWF2aW5nIHRvIHRoZSBkZWZhdWx0IHZhbHVlcyB3aGVuIHVuZGVmaW5lZFxuICAgIGlmKCEhdGhpcy50aW1pbmcpIHsgcGFyYW1zWyd0aW1pbmcnXSA9IHRoaXMudGltaW5nOyB9XG4gICAgaWYoISF0aGlzLmRlbGF5KSB7IHBhcmFtc1snZGVsYXknXSA9IHRoaXMuZGVsYXk7IH0gIFxuICAgIFxuICAgIHJldHVybiB7IHZhbHVlOiB0aGlzLmFuaW1hdGUsIHBhcmFtcyB9O1xuICB9XG5cbiAgLyoqIFNlbGVjdHMgdGhlIGFuaW1hdGlvbiB0byBiZSBwbGF5ZWQgKi9cbiAgQElucHV0KCd3bUFuaW1hdGUnKSBhbmltYXRlOiB3bUFuaW1hdGlvbnM7XG5cbiAgLyoqIFNwZWVkcyB1cCBvciBzbG93cyBkb3duIHRoZSBhbmltYXRpb24gKi9cbiAgQElucHV0KCkgc2V0IHNwZWVkKHNwZWVkOiB3bUFuaW1hdGVTcGVlZCkge1xuICAgIC8vIFR1cm5zIHRoZSByZXF1ZXN0ZWQgc3BlZWQgaW50byBhIHZhbGlkIHRpbWluZ1xuICAgIHRoaXMudGltaW5nID0geyBcbiAgICAgIHNsb3dlcjogJzNzJywgXG4gICAgICBzbG93OiAnMnMnLCBcbiAgICAgIG5vcm1hbDogJzFzJywgXG4gICAgICBmYXN0OiAnNTAwbXMnLCBcbiAgICAgIGZhc3RlcjogJzMwMG1zJyBcbiAgICB9W3NwZWVkIHx8ICdub3JtYWwnXSB8fCAnMXMnO1xuICB9XG5cbiAgLyoqIERlbGF5cyB0aGUgYW5pbWF0aW9uICovXG4gIEBJbnB1dCgnZGVsYXknKSBzZXQgcG9zdHBvbmUoZGVsYXk6IHN0cmluZykge1xuICAgIC8vIENvZXJjZXMgdGhlIGlucHV0IGludG8gYSBudW1iZXIgZmlyc3RcbiAgICBjb25zdCB2YWx1ZSA9IGNvZXJjZU51bWJlclByb3BlcnR5KGRlbGF5LCAwKTtcbiAgICBpZih2YWx1ZSkgeyBcbiAgICAgIC8vIFR1cm5zIGEgdmFsaWQgbnVtYmVyIGludG8gYSBtcyBkZWxheVxuICAgICAgdGhpcy5kZWxheSA9IGAke3ZhbHVlfW1zYDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAvLyBUZXN0IHRoZSBzdHJpbmcgZm9yIGEgdmFsaWQgZGVsYXkgY29tYmluYXRpb25cbiAgICAgIHRoaXMuZGVsYXkgPSAvXlxcZCsoPzptc3xzKSQvLnRlc3QoZGVsYXkpID8gZGVsYXkgOiAnJztcbiAgICB9XG4gIH1cblxuICAvKiogRGlzYWJsZXMgdGhlIGFuaW1hdGlvbiAqL1xuICBASW5wdXQoJ2Rpc2FibGVkJykgc2V0IGRpc2FibGVBbmltYXRpb24odmFsdWU6IGJvb2xlYW4pIHsgdGhpcy5kaXNhYmxlZCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7IH1cbiAgQEhvc3RCaW5kaW5nKCdALmRpc2FibGVkJykgXG4gIHB1YmxpYyBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIC8qKiBFbWl0cyBhdCB0aGUgZW5kIG9mIHRoZSBhbmltYXRpb24gKi9cbiAgQE91dHB1dCgpIHN0YXJ0ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpOyAgXG4gIEBIb3N0TGlzdGVuZXIoJ0BhbmltYXRlLnN0YXJ0JykgXG4gIHB1YmxpYyBhbmltYXRpb25TdGFydCgpIHsgdGhpcy5hbmltYXRpbmcgPSB0cnVlOyB0aGlzLmFuaW1hdGVkID0gZmFsc2U7IHRoaXMuc3RhcnQuZW1pdCgpOyB9XG5cbiAgLyoqIEVtaXRzIGF0IHRoZSBlbmQgb2YgdGhlIGFuaW1hdGlvbiAqL1xuICBAT3V0cHV0KCkgZG9uZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTsgIFxuICBASG9zdExpc3RlbmVyKCdAYW5pbWF0ZS5kb25lJykgXG4gIHB1YmxpYyBhbmltYXRpb25Eb25lKCkgeyBcbiAgICBcbiAgICB0aGlzLmFuaW1hdGluZyA9IGZhbHNlOyB0aGlzLmFuaW1hdGVkID0gdHJ1ZTsgdGhpcy5kb25lLmVtaXQoKTsgXG5cbiAgICAvKiogXG4gICAgICogUmVtb3ZlcyBzcHVyaW91cyAnYW5pbWF0aW9uJyBzdHlsZSBmcm9tIHRoZSBlbGVtZW50IG9uY2UgZG9uZSB3aXRoIHRoZSBhbmltYXRpb24uIFxuICAgICAqIFRoaXMgYmVoYXZpb3VyIGhhcyBiZWVuIG9ic2VydmVkIHdoZW4gcnVubmluZyBvbiBpT1MgZGV2aWNlcyB3aGVyZSBmb3Igc29tZSByZWFzb24gXG4gICAgICogdGhlIGFuaW1hdGlvbiBlbmdpbmUgZG8gbm90IHByb3Blcmx5IGNsZWFuLXVwIHRoZSBhbmltYXRpb24gc3R5bGUgdXNpbmcgY3ViaWMtYmV6aWVyKClcbiAgICAgKiBhcyBpdHMgdGltaW5nIGZ1bmN0aW9uLiBUaGUgaXNzdWUgZG8gbm90IGFwcGVhciB3aXRoIGVhc2UtaW4vb3V0IGFuZCBvdGhlcnMuXG4gICAgICogKi9cbiAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZVN0eWxlKHRoaXMuZWxtLm5hdGl2ZUVsZW1lbnQsICdhbmltYXRpb24nKTtcbiAgfVxuXG4gIC8qKiBXaGVuIHRydWUsIGtlZXBzIHRoZSBhbmltYXRpb24gaWRsZSB1bnRpbCB0aGUgbmV4dCByZXBsYXkgdHJpZ2dlcnMgKi9cbiAgQElucHV0KCdwYXVzZWQnKSBzZXQgcGF1c2VBbmltYXRpb24odmFsdWU6IGJvb2xlYW4pIHsgdGhpcy5wYXVzZWQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpOyB9XG4gIHB1YmxpYyBwYXVzZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogV2hlbiBkZWZpbmVkLCB0cmlnZ2VycyB0aGUgYW5pbWF0aW9uIG9uIGVsZW1lbnQgc2Nyb2xsaW5nIGluIHRoZSB2aWV3cG9ydCBieSB0aGUgc3BlY2lmaWVkIGFtb3VudC4gQW1vdW50IGRlZmF1bHRzIHRvIDUwJSB3aGVuIG5vdCBzcGVjaWZpZWQgKi9cbiAgQElucHV0KCdhb3MnKSBzZXQgZW5hYmxlQU9TKHZhbHVlOiBudW1iZXIpIHsgdGhpcy50aHJlc2hvbGQgPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2YWx1ZSwgMC41KTsgfVxuICBwcml2YXRlIHRocmVzaG9sZDogbnVtYmVyID0gMDtcblxuICAvKiogV2hlbiB0cnVlLCB0cmlnZ2VycyB0aGUgYW5pbWF0aW9uIG9uIGVsZW1lbnQgc2Nyb2xsaW5nIGluIHRoZSB2aWV3cG9ydCAqL1xuICBASW5wdXQoJ29uY2UnKSBzZXQgYW9zT25jZSh2YWx1ZTogYm9vbGVhbikgeyB0aGlzLm9uY2UgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpOyB9XG4gIHB1YmxpYyBvbmNlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIFJlcGxheXMgdGhlIGFuaW1hdGlvbiAqL1xuICBASW5wdXQoKSBzZXQgcmVwbGF5KHJlcGxheTogYW55KSB7XG5cbiAgICAvLyBSZS10cmlnZ2VycyB0aGUgYW5pbWF0aW9uIGFnYWluIG9uIHJlcXVlc3QgKHNraXBwaW5nIHRoZSB2ZXJ5IGZpc3QgdmFsdWUpXG4gICAgaWYoISF0aGlzLnRyaWdnZXIgJiYgY29lcmNlQm9vbGVhblByb3BlcnR5KHJlcGxheSkpIHtcbiAgICAgIFxuICAgICAgdGhpcy50cmlnZ2VyID0gdGhpcy5pZGxlO1xuICAgICAgdGhpcy5yZXBsYXkkLm5leHQodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG5cbiAgICAvLyBUcmlnZ2VycyB0aGUgYW5pbWF0aW9uIGJhc2VkIG9uIHRoZSBpbnB1dCBmbGFnc1xuICAgIHRoaXMuc3ViID0gdGhpcy5yZXBsYXkkLnBpcGUoIFxuICAgICAgXG4gICAgICAvLyBXYWl0cyB0aGUgbmV4dCByb3VuZCB0byByZS10cmlnZ2VyXG4gICAgICBkZWxheSgwKSwgXG4gICAgICBcbiAgICAgIC8vIFRyaWdnZXJzIGltbWVkaWF0ZWx5IHdoZW4gbm90IHBhdXNlZFxuICAgICAgc3RhcnRXaXRoKCF0aGlzLnBhdXNlZCksXG4gICAgICBcbiAgICAgIC8vIEJ1aWxkcyB0aGUgQU9TIG9ic2VydmFibGUgZnJvbSB0aGUgY29tbW9uIHNlcnZpY2VcbiAgICAgIHRoaXMuc2Nyb2xsLnRyaWdnZXIodGhpcy5lbG0sIHRoaXMudGhyZXNob2xkKSwgICAgICBcbiAgICAgIFxuICAgICAgLy8gU3RvcCB0YWtpbmcgdGhlIGZpcnN0IG9uIHRyaWdnZXIgd2hlbiBhb3NPbmNlIGlzIHNldFxuICAgICAgdGFrZVdoaWxlKHRyaWdnZXIgPT4gIXRyaWdnZXIgfHwgIXRoaXMub25jZSwgdHJ1ZSksXG5cbiAgICAgIC8vIE1hcHMgdGhlIHRyaWdnZXIgaW50byBhbmltYXRpb24gc3RhdGVzXG4gICAgICBtYXAoIHRyaWdnZXIgPT4gdHJpZ2dlciA/IHRoaXMucGxheSA6IHRoaXMuaWRsZSApLFxuXG4gICAgICAvLyBBbHdheXMgc3RhcnQgd2l0aCBpZGxlXG4gICAgICBzdGFydFdpdGgodGhpcy5pZGxlKSxcblxuICAgICAgLy8gRWxpbWluYXRlcyBtdWx0aXBsZSB0cmlnZ2Vyc1xuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcblxuICAgICAgLy8gVHJpZ2dlcnMgdGhlIGFuaW1hdGlvbiB0byBwbGF5IG9yIHRvIGlkbGVcbiAgICApLnN1YnNjcmliZSggdHJpZ2dlciA9PiB0aGlzLnRyaWdnZXIgPSB0cmlnZ2VyICk7XG4gIH1cblxuICAvLyBEaXNwb3NlcyBvZiB0aGUgb2JzZXJ2YWJsZVxuICBuZ09uRGVzdHJveSgpIHsgdGhpcy5zdWIudW5zdWJzY3JpYmUoKTsgfVxufSJdfQ==