@yoozly/ngx-parallax
Version:
Use parallax effect with Angular 16-17 compatible universal (standalone and ngModule)
137 lines • 16.4 kB
JavaScript
import { Directive, Input } from '@angular/core';
import { fromEvent, of, Subject } from 'rxjs';
import { takeUntil, filter, map, debounceTime, mergeMap } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "./services/windowref.service";
export class ParallaxDirective {
hostElement;
renderer;
wr;
speed = 30;
axe = 'y';
property = 'transform';
propertyValue = 'translate3d';
active = true;
inViewport = true;
observer;
element;
initialPosition;
componentDestroy$ = new Subject();
windowScroll$;
windowResize$;
constructor(hostElement, renderer, wr) {
this.hostElement = hostElement;
this.renderer = renderer;
this.wr = wr;
}
ngAfterViewInit() {
this.element = this.hostElement.nativeElement;
if (this.element && this.wr.nativeWindow && !this.observer) {
this.initParallax();
}
}
initParallax() {
this.observer = this.createObserver(0);
this.observer.observe(this.element);
const parallax$ = of('').pipe(takeUntil(this.componentDestroy$), filter(() => this.active && this.inViewport), map(() => {
const coef = this.calculateCoef();
this.renderParallax(coef);
return coef;
}));
this.windowScroll$ = fromEvent(this.wr.nativeWindow, 'scroll').pipe(mergeMap(() => parallax$));
this.windowResize$ = fromEvent(this.wr.nativeWindow, 'resize').pipe(debounceTime(500), mergeMap(() => parallax$));
}
startParallax() {
this.inViewport = true;
if (this.wr.nativeWindow && this.initialPosition === undefined) {
this.initialPosition = this.wr.nativeWindow.pageYOffset;
this.windowScroll$.subscribe();
this.windowResize$.subscribe();
}
}
destroyParallax() {
this.inViewport = false;
}
calculateCoef() {
return ((this.wr.nativeWindow.pageYOffset - this.initialPosition) *
(this.speed / 100));
}
renderParallax(coef) {
this.renderer.setStyle(this.element, this.property, this.getPropertyValue(coef));
}
getPropertyValue(coef) {
let result = `${coef}px`;
if (this.property === 'transform') {
switch (this.propertyValue) {
case 'translate3d':
result = `translate3d(${this.getAxe(coef)})`;
break;
case 'scale':
result = `scale(${coef})`;
break;
case 'rotate':
result = `rotate(${coef}deg)`;
break;
}
}
switch (this.property) {
case 'opacity':
result = `${coef}`;
break;
}
return result;
}
getAxe(coef) {
let axe = [0, coef, 0];
if (this.axe === 'x') {
axe = [coef, 0, 0];
}
else if (this.axe === 'z') {
axe = [0, 0, coef];
}
return `${axe[0]}px, ${axe[1]}px, ${axe[2]}px`;
}
createObserver(pourcent) {
const options = {
rootMargin: '0px',
threshold: pourcent / 100
};
const isIntersecting = (entry) => entry.isIntersecting || entry.intersectionRatio > 0;
return new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (isIntersecting(entry)) {
this.startParallax();
}
else {
this.destroyParallax();
}
});
}, options);
}
ngOnDestroy() {
this.componentDestroy$.next(false);
this.componentDestroy$.complete();
if (this.wr.nativeWindow) {
this.observer.disconnect();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.3", ngImport: i0, type: ParallaxDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.BrowserWindowRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.3", type: ParallaxDirective, selector: "[ngx-parallax]", inputs: { speed: "speed", axe: "axe", property: "property", propertyValue: "propertyValue", active: "active" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.3", ngImport: i0, type: ParallaxDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngx-parallax]'
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.BrowserWindowRef }], propDecorators: { speed: [{
type: Input
}], axe: [{
type: Input
}], property: [{
type: Input
}], propertyValue: [{
type: Input
}], active: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXBhcmFsbGF4LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1wYXJhbGxheC9zcmMvbGliL25neC1wYXJhbGxheC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBS04sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQU9oRixNQUFNLE9BQU8saUJBQWlCO0lBZ0JsQjtJQUNBO0lBQ0E7SUFqQkQsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNYLEdBQUcsR0FBRyxHQUFHLENBQUM7SUFDVixRQUFRLEdBQUcsV0FBVyxDQUFDO0lBQ3ZCLGFBQWEsR0FBRyxhQUFhLENBQUM7SUFDOUIsTUFBTSxHQUFHLElBQUksQ0FBQztJQUVmLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDbEIsUUFBUSxDQUF1QjtJQUMvQixPQUFPLENBQWM7SUFDckIsZUFBZSxDQUFTO0lBQ3hCLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7SUFDM0MsYUFBYSxDQUFxQjtJQUNsQyxhQUFhLENBQXFCO0lBRTFDLFlBQ1UsV0FBdUIsRUFDdkIsUUFBbUIsRUFDbkIsRUFBb0I7UUFGcEIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdkIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixPQUFFLEdBQUYsRUFBRSxDQUFrQjtJQUMzQixDQUFDO0lBRUosZUFBZTtRQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7UUFFOUMsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzNELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVwQyxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUMzQixTQUFTLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQ2pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsRUFDNUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNQLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FDakUsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUMxQixDQUFDO1FBRUYsSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUNqRSxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQ2pCLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FDMUIsQ0FBQztJQUNKLENBQUM7SUFFTyxhQUFhO1FBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBRXZCLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMvRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQztZQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFFTyxlQUFlO1FBQ3JCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFTyxhQUFhO1FBQ25CLE9BQU8sQ0FDTCxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQ3pELENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FDbkIsQ0FBQztJQUNKLENBQUM7SUFFTyxjQUFjLENBQUMsSUFBWTtRQUNqQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FDcEIsSUFBSSxDQUFDLE9BQU8sRUFDWixJQUFJLENBQUMsUUFBUSxFQUNiLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxJQUFZO1FBQ25DLElBQUksTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLENBQUM7UUFFekIsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLFFBQVEsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUMzQixLQUFLLGFBQWE7b0JBQ2hCLE1BQU0sR0FBRyxlQUFlLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztvQkFDN0MsTUFBTTtnQkFDUixLQUFLLE9BQU87b0JBQ1YsTUFBTSxHQUFHLFNBQVMsSUFBSSxHQUFHLENBQUM7b0JBQzFCLE1BQU07Z0JBQ1IsS0FBSyxRQUFRO29CQUNYLE1BQU0sR0FBRyxVQUFVLElBQUksTUFBTSxDQUFDO29CQUM5QixNQUFNO1lBQ1YsQ0FBQztRQUNILENBQUM7UUFFRCxRQUFRLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN0QixLQUFLLFNBQVM7Z0JBQ1osTUFBTSxHQUFHLEdBQUcsSUFBSSxFQUFFLENBQUM7Z0JBQ25CLE1BQU07UUFDVixDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVPLE1BQU0sQ0FBQyxJQUFZO1FBQ3pCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV2QixJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDckIsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyQixDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzVCLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDckIsQ0FBQztRQUVELE9BQU8sR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2pELENBQUM7SUFFTyxjQUFjLENBQUMsUUFBZ0I7UUFDckMsTUFBTSxPQUFPLEdBQUc7WUFDZCxVQUFVLEVBQUUsS0FBSztZQUNqQixTQUFTLEVBQUUsUUFBUSxHQUFHLEdBQUc7U0FDMUIsQ0FBQztRQUVGLE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBZ0MsRUFBRSxFQUFFLENBQzFELEtBQUssQ0FBQyxjQUFjLElBQUksS0FBSyxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztRQUV0RCxPQUFPLElBQUksb0JBQW9CLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDcEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUN4QixJQUFJLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUMxQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3ZCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3pCLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNkLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEMsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7dUdBbEpVLGlCQUFpQjsyRkFBakIsaUJBQWlCOzsyRkFBakIsaUJBQWlCO2tCQUg3QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxnQkFBZ0I7aUJBQzNCO3NJQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIERpcmVjdGl2ZSxcbiAgSW5wdXQsXG4gIEVsZW1lbnRSZWYsXG4gIFJlbmRlcmVyMixcbiAgT25EZXN0cm95LFxuICBBZnRlclZpZXdJbml0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsLCBmaWx0ZXIsIG1hcCwgZGVib3VuY2VUaW1lLCBtZXJnZU1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgQnJvd3NlcldpbmRvd1JlZiB9IGZyb20gJy4vc2VydmljZXMvd2luZG93cmVmLnNlcnZpY2UnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbbmd4LXBhcmFsbGF4XSdcbn0pXG5leHBvcnQgY2xhc3MgUGFyYWxsYXhEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBzcGVlZCA9IDMwO1xuICBASW5wdXQoKSBheGUgPSAneSc7XG4gIEBJbnB1dCgpIHByb3BlcnR5ID0gJ3RyYW5zZm9ybSc7XG4gIEBJbnB1dCgpIHByb3BlcnR5VmFsdWUgPSAndHJhbnNsYXRlM2QnO1xuICBASW5wdXQoKSBhY3RpdmUgPSB0cnVlO1xuXG4gIHByaXZhdGUgaW5WaWV3cG9ydCA9IHRydWU7XG4gIHByaXZhdGUgb2JzZXJ2ZXI6IEludGVyc2VjdGlvbk9ic2VydmVyO1xuICBwcml2YXRlIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIGluaXRpYWxQb3NpdGlvbjogbnVtYmVyO1xuICBwcml2YXRlIGNvbXBvbmVudERlc3Ryb3kkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgcHJpdmF0ZSB3aW5kb3dTY3JvbGwkOiBPYnNlcnZhYmxlPG51bWJlcj47XG4gIHByaXZhdGUgd2luZG93UmVzaXplJDogT2JzZXJ2YWJsZTxudW1iZXI+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaG9zdEVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgd3I6IEJyb3dzZXJXaW5kb3dSZWZcbiAgKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmhvc3RFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBpZiAodGhpcy5lbGVtZW50ICYmIHRoaXMud3IubmF0aXZlV2luZG93ICYmICF0aGlzLm9ic2VydmVyKSB7XG4gICAgICB0aGlzLmluaXRQYXJhbGxheCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdFBhcmFsbGF4KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIgPSB0aGlzLmNyZWF0ZU9ic2VydmVyKDApO1xuICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQpO1xuXG4gICAgY29uc3QgcGFyYWxsYXgkID0gb2YoJycpLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95JCksXG4gICAgICBmaWx0ZXIoKCkgPT4gdGhpcy5hY3RpdmUgJiYgdGhpcy5pblZpZXdwb3J0KSxcbiAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvZWYgPSB0aGlzLmNhbGN1bGF0ZUNvZWYoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJQYXJhbGxheChjb2VmKTtcbiAgICAgICAgcmV0dXJuIGNvZWY7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLndpbmRvd1Njcm9sbCQgPSBmcm9tRXZlbnQodGhpcy53ci5uYXRpdmVXaW5kb3csICdzY3JvbGwnKS5waXBlKFxuICAgICAgbWVyZ2VNYXAoKCkgPT4gcGFyYWxsYXgkKVxuICAgICk7XG5cbiAgICB0aGlzLndpbmRvd1Jlc2l6ZSQgPSBmcm9tRXZlbnQodGhpcy53ci5uYXRpdmVXaW5kb3csICdyZXNpemUnKS5waXBlKFxuICAgICAgZGVib3VuY2VUaW1lKDUwMCksXG4gICAgICBtZXJnZU1hcCgoKSA9PiBwYXJhbGxheCQpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRQYXJhbGxheCgpOiB2b2lkIHtcbiAgICB0aGlzLmluVmlld3BvcnQgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMud3IubmF0aXZlV2luZG93ICYmIHRoaXMuaW5pdGlhbFBvc2l0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaW5pdGlhbFBvc2l0aW9uID0gdGhpcy53ci5uYXRpdmVXaW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgICB0aGlzLndpbmRvd1Njcm9sbCQuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLndpbmRvd1Jlc2l6ZSQuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZXN0cm95UGFyYWxsYXgoKTogdm9pZCB7XG4gICAgdGhpcy5pblZpZXdwb3J0ID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0ZUNvZWYoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHRoaXMud3IubmF0aXZlV2luZG93LnBhZ2VZT2Zmc2V0IC0gdGhpcy5pbml0aWFsUG9zaXRpb24pICpcbiAgICAgICh0aGlzLnNwZWVkIC8gMTAwKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlclBhcmFsbGF4KGNvZWY6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICB0aGlzLmVsZW1lbnQsXG4gICAgICB0aGlzLnByb3BlcnR5LFxuICAgICAgdGhpcy5nZXRQcm9wZXJ0eVZhbHVlKGNvZWYpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UHJvcGVydHlWYWx1ZShjb2VmOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGxldCByZXN1bHQgPSBgJHtjb2VmfXB4YDtcblxuICAgIGlmICh0aGlzLnByb3BlcnR5ID09PSAndHJhbnNmb3JtJykge1xuICAgICAgc3dpdGNoICh0aGlzLnByb3BlcnR5VmFsdWUpIHtcbiAgICAgICAgY2FzZSAndHJhbnNsYXRlM2QnOlxuICAgICAgICAgIHJlc3VsdCA9IGB0cmFuc2xhdGUzZCgke3RoaXMuZ2V0QXhlKGNvZWYpfSlgO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdzY2FsZSc6XG4gICAgICAgICAgcmVzdWx0ID0gYHNjYWxlKCR7Y29lZn0pYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncm90YXRlJzpcbiAgICAgICAgICByZXN1bHQgPSBgcm90YXRlKCR7Y29lZn1kZWcpYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMucHJvcGVydHkpIHtcbiAgICAgIGNhc2UgJ29wYWNpdHknOlxuICAgICAgICByZXN1bHQgPSBgJHtjb2VmfWA7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGdldEF4ZShjb2VmOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGxldCBheGUgPSBbMCwgY29lZiwgMF07XG5cbiAgICBpZiAodGhpcy5heGUgPT09ICd4Jykge1xuICAgICAgYXhlID0gW2NvZWYsIDAsIDBdO1xuICAgIH0gZWxzZSBpZiAodGhpcy5heGUgPT09ICd6Jykge1xuICAgICAgYXhlID0gWzAsIDAsIGNvZWZdO1xuICAgIH1cblxuICAgIHJldHVybiBgJHtheGVbMF19cHgsICR7YXhlWzFdfXB4LCAke2F4ZVsyXX1weGA7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU9ic2VydmVyKHBvdXJjZW50OiBudW1iZXIpIHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgcm9vdE1hcmdpbjogJzBweCcsXG4gICAgICB0aHJlc2hvbGQ6IHBvdXJjZW50IC8gMTAwXG4gICAgfTtcblxuICAgIGNvbnN0IGlzSW50ZXJzZWN0aW5nID0gKGVudHJ5OiBJbnRlcnNlY3Rpb25PYnNlcnZlckVudHJ5KSA9PlxuICAgICAgZW50cnkuaXNJbnRlcnNlY3RpbmcgfHwgZW50cnkuaW50ZXJzZWN0aW9uUmF0aW8gPiAwO1xuXG4gICAgcmV0dXJuIG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcigoZW50cmllcywgb2JzZXJ2ZXIpID0+IHtcbiAgICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgaWYgKGlzSW50ZXJzZWN0aW5nKGVudHJ5KSkge1xuICAgICAgICAgIHRoaXMuc3RhcnRQYXJhbGxheCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZGVzdHJveVBhcmFsbGF4KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sIG9wdGlvbnMpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5jb21wb25lbnREZXN0cm95JC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLmNvbXBvbmVudERlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgaWYgKHRoaXMud3IubmF0aXZlV2luZG93KSB7XG4gICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==