UNPKG

ng-cw-v12

Version:

Angular UI Component Library

560 lines (542 loc) 70.9 kB
import { Component, ViewChild, Input, HostListener } from '@angular/core'; import * as THREE from 'three'; import * as i0 from "@angular/core"; ; const vertexShader = ` precision highp float; attribute vec3 position; void main() { gl_Position = vec4(position.xy, 0.0, 1.0); } `; const fragmentShader = ` precision highp float; uniform vec2 iResolution; uniform float iTime; uniform float uHeight; uniform float uBaseHalf; uniform mat3 uRot; uniform int uUseBaseWobble; uniform float uGlow; uniform vec2 uOffsetPx; uniform float uNoise; uniform float uSaturation; uniform float uScale; uniform float uHueShift; uniform float uColorFreq; uniform float uBloom; uniform float uCenterShift; uniform float uInvBaseHalf; uniform float uInvHeight; uniform float uMinAxis; uniform float uPxScale; uniform float uTimeScale; vec4 tanh4(vec4 x){ vec4 e2x = exp(2.0*x); return (e2x - 1.0) / (e2x + 1.0); } float rand(vec2 co){ return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453123); } float sdOctaAnisoInv(vec3 p){ vec3 q = vec3(abs(p.x) * uInvBaseHalf, abs(p.y) * uInvHeight, abs(p.z) * uInvBaseHalf); float m = q.x + q.y + q.z - 1.0; return m * uMinAxis * 0.5773502691896258; } float sdPyramidUpInv(vec3 p){ float oct = sdOctaAnisoInv(p); float halfSpace = -p.y; return max(oct, halfSpace); } mat3 hueRotation(float a){ float c = cos(a), s = sin(a); mat3 W = mat3( 0.299, 0.299, 0.299, 0.587, 0.587, 0.587, 0.114, 0.114, 0.114 ); mat3 U = mat3( 0.701, -0.299, -0.300, -0.587, 0.413, -0.588, -0.114, -0.114, 0.886 ); mat3 V = mat3( 0.168, 0.328, -0.497, -0.331, 0.035, 0.296, 0.500, -0.500, 0.201 ); return W + U * c + V * s; } void main(){ vec2 f = (gl_FragCoord.xy - 0.5 * iResolution.xy - uOffsetPx) * uPxScale; float z = 5.0; float d = 0.0; vec3 p; vec4 o = vec4(0.0); float centerShift = uCenterShift; float cf = uColorFreq; mat2 wob = mat2(1.0); if (uUseBaseWobble == 1) { float t = iTime * uTimeScale; float c0 = cos(t + 0.0); float c1 = cos(t + 33.0); float c2 = cos(t + 11.0); wob = mat2(c0, c1, c2, c0); } const int STEPS = 100; for (int i = 0; i < STEPS; i++) { p = vec3(f, z); p.xz = p.xz * wob; p = uRot * p; vec3 q = p; q.y += centerShift; d = 0.1 + 0.2 * abs(sdPyramidUpInv(q)); z -= d; o += (sin((p.y + z) * cf + vec4(0.0, 1.0, 2.0, 3.0)) + 1.0) / d; } o = tanh4(o * o * (uGlow * uBloom) / 1e5); vec3 col = o.rgb; float n = rand(gl_FragCoord.xy + vec2(iTime)); col += (n - 0.5) * uNoise; col = clamp(col, 0.0, 1.0); float L = dot(col, vec3(0.2126, 0.7152, 0.0722)); col = clamp(mix(vec3(L), col, uSaturation), 0.0, 1.0); if(abs(uHueShift) > 0.0001){ col = clamp(hueRotation(uHueShift) * col, 0.0, 1.0); } gl_FragColor = vec4(col, o.a); } `; export class PrismBackgroundComponent { constructor(ngZone) { this.ngZone = ngZone; /** 棱镜高度(1-8) */ this.ncHeight = 3.5; /** 棱镜基础宽度(1-8) */ this.ncBaseWidth = 5.5; /** 动画类型:rotate, hover, 3drotate */ this.ncAnimationType = 'rotate'; /** 发光强度(0-3) */ this.ncGlow = 1; /** 偏移量 {x, y} */ this.ncOffset = { x: 0, y: 0 }; /** 噪点强度(0-1) */ this.ncNoise = 0; /** 画布是否具有 alpha 通道(透明背景) */ this._transparent = true; /** 棱镜在屏幕空间中的整体比例(1-5) */ this.ncScale = 3.6; /** 色相偏移(-3.14-3.14) */ this.ncHueShift = 0; /** 颜色变化频率(0-4) */ this.ncColorFrequency = 1; /** 悬停反馈强度 */ this.ncHoverStrength = 2; /** 悬停缓动系数(0-1,数值越高反应越灵敏) */ this.ncInertia = 0.05; /** 在光泽之上叠加额外的光晕效果(0.5-2) */ this.ncBloom = 1; /** 若不在屏幕中,是否挂起以节省性能 */ this._suspendWhenOffscreen = false; /** 动画速度(0-2) */ this.ncTimeScale = 0.5; /** 背景颜色 */ this.ncBgColor = '#000000'; this.rafId = null; this.dpr = 1; this.pointer = { x: 0, y: 0, inside: false }; this.yaw = 0; this.pitch = 0; this.roll = 0; this.targetYaw = 0; this.targetPitch = 0; this.wX = 0; this.wY = 0; this.wZ = 0; this.phX = 0; this.phZ = 0; this.isVisible = true; this.t0 = performance.now(); this.renderLoop = (t) => { var _a, _b, _c; if (!this.material || !this.renderer) return; const time = (t - this.t0) * 0.001; this.material.uniforms['iTime'].value = time; let continueRAF = true; const NOISE_IS_ZERO = Math.max(0.0, this.ncNoise) < 1e-6; const TS = Math.max(0, (_a = this.ncTimeScale) !== null && _a !== void 0 ? _a : 1); const HOVSTR = Math.max(0, (_b = this.ncHoverStrength) !== null && _b !== void 0 ? _b : 1); const INERT = Math.max(0, Math.min(1, (_c = this.ncInertia) !== null && _c !== void 0 ? _c : 0.12)); if (this.ncAnimationType === 'hover') { this.material.uniforms['uUseBaseWobble'].value = 0; const maxPitch = 0.6 * HOVSTR; const maxYaw = 0.6 * HOVSTR; this.targetYaw = (this.pointer.inside ? -this.pointer.x : 0) * maxYaw; this.targetPitch = (this.pointer.inside ? this.pointer.y : 0) * maxPitch; this.yaw = this.lerp(this.yaw, this.targetYaw, INERT); this.pitch = this.lerp(this.pitch, this.targetPitch, INERT); this.roll = this.lerp(this.roll, 0, 0.1); this.material.uniforms['uRot'].value.copy(this.setMat3FromEuler(this.yaw, this.pitch, this.roll)); if (NOISE_IS_ZERO) { const settled = Math.abs(this.yaw - this.targetYaw) < 1e-4 && Math.abs(this.pitch - this.targetPitch) < 1e-4 && Math.abs(this.roll) < 1e-4; if (settled) continueRAF = false; } } else if (this.ncAnimationType === '3drotate') { this.material.uniforms['uUseBaseWobble'].value = 0; const tScaled = time * TS; this.yaw = tScaled * this.wY; this.pitch = Math.sin(tScaled * this.wX + this.phX) * 0.6; this.roll = Math.sin(tScaled * this.wZ + this.phZ) * 0.5; this.material.uniforms['uRot'].value.copy(this.setMat3FromEuler(this.yaw, this.pitch, this.roll)); if (TS < 1e-6) continueRAF = false; } else { this.material.uniforms['uUseBaseWobble'].value = 1; const mat = new THREE.Matrix3(); mat.identity(); this.material.uniforms['uRot'].value.copy(mat); if (TS < 1e-6) continueRAF = false; } this.renderer.render(this.scene, this.camera); if (continueRAF && this.isVisible) { this.rafId = requestAnimationFrame(this.renderLoop); } else { this.rafId = null; } }; } set ncTransparent(val) { this._transparent = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncTransparent() { return this._transparent; } set ncSuspendWhenOffscreen(val) { this._suspendWhenOffscreen = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncSuspendWhenOffscreen() { return this._suspendWhenOffscreen; } ngOnInit() { const rnd = () => Math.random(); this.wX = 0.3 + rnd() * 0.6; this.wY = 0.2 + rnd() * 0.7; this.wZ = 0.1 + rnd() * 0.5; this.phX = rnd() * Math.PI * 2; this.phZ = rnd() * Math.PI * 2; } ngAfterViewInit() { this.ngZone.runOutsideAngular(() => { this.initWebGL(); }); } ngOnDestroy() { this.cleanup(); } ngOnChanges(changes) { var _a; this.updateUniforms(); // 当参数发生改变时,如果动画不在循环状态下(比如时间缩放由0变回1),应该恢复渲染循环 if (this.isVisible) { this.ngZone.runOutsideAngular(() => this.startRAF()); } // 如果离屏挂起状态改变,需要特殊处理 if (changes['ncSuspendWhenOffscreen']) { if (this.ncSuspendWhenOffscreen && ((_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement)) { if (!this.intersectionObserver) { this.setupIntersectionObserver(this.containerRef.nativeElement); } } else { if (this.intersectionObserver) { this.intersectionObserver.disconnect(); this.intersectionObserver = null; } if (this.renderer) { this.ngZone.runOutsideAngular(() => this.startRAF()); } } } } initWebGL() { var _a, _b, _c, _d; const container = this.containerRef.nativeElement; this.dpr = Math.min(2, window.devicePixelRatio || 1); this.renderer = new THREE.WebGLRenderer({ alpha: this.ncTransparent, antialias: false }); this.renderer.setPixelRatio(this.dpr); Object.assign(this.renderer.domElement.style, { position: 'absolute', inset: '0', width: '100%', height: '100%', display: 'block' }); container.appendChild(this.renderer.domElement); this.scene = new THREE.Scene(); this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); const H = Math.max(0.001, this.ncHeight); const BW = Math.max(0.001, this.ncBaseWidth); const BASE_HALF = BW * 0.5; this.material = new THREE.RawShaderMaterial({ vertexShader, fragmentShader, transparent: this.ncTransparent, depthTest: false, depthWrite: false, uniforms: { iResolution: { value: new THREE.Vector2() }, iTime: { value: 0 }, uHeight: { value: H }, uBaseHalf: { value: BASE_HALF }, uUseBaseWobble: { value: 1 }, uRot: { value: new THREE.Matrix3() }, uGlow: { value: Math.max(0.0, this.ncGlow) }, uOffsetPx: { value: new THREE.Vector2(this.ncOffset.x * this.dpr, this.ncOffset.y * this.dpr) }, uNoise: { value: Math.max(0.0, this.ncNoise) }, uSaturation: { value: this.ncTransparent ? 1.5 : 1 }, uScale: { value: Math.max(0.001, this.ncScale) }, uHueShift: { value: (_a = this.ncHueShift) !== null && _a !== void 0 ? _a : 0 }, uColorFreq: { value: Math.max(0.0, (_b = this.ncColorFrequency) !== null && _b !== void 0 ? _b : 1) }, uBloom: { value: Math.max(0.0, (_c = this.ncBloom) !== null && _c !== void 0 ? _c : 1) }, uCenterShift: { value: H * 0.25 }, uInvBaseHalf: { value: 1 / BASE_HALF }, uInvHeight: { value: 1 / H }, uMinAxis: { value: Math.min(BASE_HALF, H) }, uPxScale: { value: 1 }, uTimeScale: { value: Math.max(0, (_d = this.ncTimeScale) !== null && _d !== void 0 ? _d : 1) } } }); const geometry = new THREE.PlaneGeometry(2, 2); this.mesh = new THREE.Mesh(geometry, this.material); this.scene.add(this.mesh); this.setupResizeObserver(container); if (this.ncSuspendWhenOffscreen) { this.setupIntersectionObserver(container); } else { this.startRAF(); } } updateUniforms() { var _a, _b, _c, _d; if (!this.material) return; const H = Math.max(0.001, this.ncHeight); const BW = Math.max(0.001, this.ncBaseWidth); const BASE_HALF = BW * 0.5; const SCALE = Math.max(0.001, this.ncScale); this.material.uniforms['uHeight'].value = H; this.material.uniforms['uBaseHalf'].value = BASE_HALF; this.material.uniforms['uGlow'].value = Math.max(0.0, this.ncGlow); this.material.uniforms['uOffsetPx'].value.set(this.ncOffset.x * this.dpr, this.ncOffset.y * this.dpr); this.material.uniforms['uNoise'].value = Math.max(0.0, this.ncNoise); this.material.uniforms['uSaturation'].value = this.ncTransparent ? 1.5 : 1; this.material.uniforms['uScale'].value = SCALE; this.material.uniforms['uHueShift'].value = (_a = this.ncHueShift) !== null && _a !== void 0 ? _a : 0; this.material.uniforms['uColorFreq'].value = Math.max(0.0, (_b = this.ncColorFrequency) !== null && _b !== void 0 ? _b : 1); this.material.uniforms['uBloom'].value = Math.max(0.0, (_c = this.ncBloom) !== null && _c !== void 0 ? _c : 1); this.material.uniforms['uCenterShift'].value = H * 0.25; this.material.uniforms['uInvBaseHalf'].value = 1 / BASE_HALF; this.material.uniforms['uInvHeight'].value = 1 / H; this.material.uniforms['uMinAxis'].value = Math.min(BASE_HALF, H); this.material.uniforms['uTimeScale'].value = Math.max(0, (_d = this.ncTimeScale) !== null && _d !== void 0 ? _d : 1); // 更新需要依赖高度和缩放的 uPxScale const canvasHeight = this.renderer.domElement.height || 1; this.material.uniforms['uPxScale'].value = 1 / (canvasHeight * 0.1 * SCALE); // 更新 renderer 的 alpha if (this.renderer) { // 通过直接重建背景是否透明 this.renderer.setClearColor(0x000000, this.ncTransparent ? 0 : 1); this.material.transparent = this.ncTransparent; } } setupResizeObserver(container) { this.resizeObserver = new ResizeObserver(() => { this.ngZone.runOutsideAngular(() => { if (!this.renderer || !container) return; const w = container.clientWidth || 1; const h = container.clientHeight || 1; this.renderer.setSize(w, h, false); const canvas = this.renderer.domElement; this.material.uniforms['iResolution'].value.set(canvas.width, canvas.height); const SCALE = Math.max(0.001, this.ncScale); this.material.uniforms['uPxScale'].value = 1 / ((canvas.height || 1) * 0.1 * SCALE); }); }); this.resizeObserver.observe(container); } setupIntersectionObserver(container) { this.intersectionObserver = new IntersectionObserver(entries => { const vis = entries.some(e => e.isIntersecting); this.isVisible = vis; if (vis) { this.ngZone.runOutsideAngular(() => this.startRAF()); } else { this.stopRAF(); } }); this.intersectionObserver.observe(container); } lerp(a, b, t) { return a + (b - a) * t; } setMat3FromEuler(yawY, pitchX, rollZ) { const cy = Math.cos(yawY), sy = Math.sin(yawY); const cx = Math.cos(pitchX), sx = Math.sin(pitchX); const cz = Math.cos(rollZ), sz = Math.sin(rollZ); const r00 = cy * cz + sy * sx * sz; const r01 = -cy * sz + sy * sx * cz; const r02 = sy * cx; const r10 = cx * sz; const r11 = cx * cz; const r12 = -sx; const r20 = -sy * cz + cy * sx * sz; const r21 = sy * sz + cy * sx * cz; const r22 = cy * cx; const mat = new THREE.Matrix3(); mat.set(r00, r01, r02, r10, r11, r12, r20, r21, r22); return mat; } startRAF() { if (this.rafId === null) { this.rafId = requestAnimationFrame(this.renderLoop); } } stopRAF() { if (this.rafId !== null) { cancelAnimationFrame(this.rafId); this.rafId = null; } } cleanup() { var _a, _b; this.stopRAF(); try { (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); } catch (e) { void 0; } try { (_b = this.intersectionObserver) === null || _b === void 0 ? void 0 : _b.disconnect(); } catch (e) { void 0; } if (this.renderer) { const canvas = this.renderer.domElement; if (canvas && canvas.parentNode) { canvas.parentNode.removeChild(canvas); } this.renderer.dispose(); this.renderer = null; } if (this.geometry) { this.geometry.dispose(); } if (this.material) { this.material.dispose(); } } // 为了能够在 cleanup 中使用 get geometry() { var _a; return (_a = this.mesh) === null || _a === void 0 ? void 0 : _a.geometry; } // ─── 鼠标事件 (HostListener) ──────────────────────────────────────────────── onPointerMove(e) { if (this.ncAnimationType !== 'hover') return; const ww = Math.max(1, window.innerWidth); const wh = Math.max(1, window.innerHeight); const cx = ww * 0.5; const cy = wh * 0.5; const nx = (e.clientX - cx) / (ww * 0.5); const ny = (e.clientY - cy) / (wh * 0.5); this.pointer.x = Math.max(-1, Math.min(1, nx)); this.pointer.y = Math.max(-1, Math.min(1, ny)); this.pointer.inside = true; // 如果动画之前停止了(比如因为 inertia settled),此时重新唤醒 this.ngZone.runOutsideAngular(() => this.startRAF()); } onMouseLeave() { if (this.ncAnimationType !== 'hover') return; this.pointer.inside = false; this.ngZone.runOutsideAngular(() => this.startRAF()); } onBlur() { if (this.ncAnimationType !== 'hover') return; this.pointer.inside = false; this.ngZone.runOutsideAngular(() => this.startRAF()); } } PrismBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: PrismBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); PrismBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: PrismBackgroundComponent, selector: "nc-prism-background", inputs: { ncHeight: "ncHeight", ncBaseWidth: "ncBaseWidth", ncAnimationType: "ncAnimationType", ncGlow: "ncGlow", ncOffset: "ncOffset", ncNoise: "ncNoise", ncTransparent: "ncTransparent", ncScale: "ncScale", ncHueShift: "ncHueShift", ncColorFrequency: "ncColorFrequency", ncHoverStrength: "ncHoverStrength", ncInertia: "ncInertia", ncBloom: "ncBloom", ncSuspendWhenOffscreen: "ncSuspendWhenOffscreen", ncTimeScale: "ncTimeScale", ncBgColor: "ncBgColor" }, host: { listeners: { "window:pointermove": "onPointerMove($event)", "window:mouseleave": "onMouseLeave()", "window:blur": "onBlur()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-prism-canvas-container\" [style.background-color]=\"ncBgColor\"></div>\n<div class=\"nc-content-wrapper\">\n <ng-content></ng-content>\n</div>", styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}.nc-prism-canvas-container{position:absolute;inset:0;z-index:0}.nc-content-wrapper{position:relative;z-index:1;width:100%;height:100%}\n"] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: PrismBackgroundComponent, decorators: [{ type: Component, args: [{ selector: 'nc-prism-background', templateUrl: './prism-background.component.html', styleUrls: ['./prism-background.component.less'] }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{ type: ViewChild, args: ['container', { static: true }] }], ncHeight: [{ type: Input }], ncBaseWidth: [{ type: Input }], ncAnimationType: [{ type: Input }], ncGlow: [{ type: Input }], ncOffset: [{ type: Input }], ncNoise: [{ type: Input }], ncTransparent: [{ type: Input }], ncScale: [{ type: Input }], ncHueShift: [{ type: Input }], ncColorFrequency: [{ type: Input }], ncHoverStrength: [{ type: Input }], ncInertia: [{ type: Input }], ncBloom: [{ type: Input }], ncSuspendWhenOffscreen: [{ type: Input }], ncTimeScale: [{ type: Input }], ncBgColor: [{ type: Input }], onPointerMove: [{ type: HostListener, args: ['window:pointermove', ['$event']] }], onMouseLeave: [{ type: HostListener, args: ['window:mouseleave'] }], onBlur: [{ type: HostListener, args: ['window:blur'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpc20tYmFja2dyb3VuZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3ByaXNtLWJhY2tncm91bmQvcHJpc20tYmFja2dyb3VuZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3ByaXNtLWJhY2tncm91bmQvcHJpc20tYmFja2dyb3VuZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUlULFNBQVMsRUFFVCxLQUFLLEVBR0wsWUFBWSxFQUViLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDOztBQU05QixDQUFDO0FBRUYsTUFBTSxZQUFZLEdBQUc7Ozs7OztDQU1wQixDQUFDO0FBRUYsTUFBTSxjQUFjLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FtSHRCLENBQUM7QUFPRixNQUFNLE9BQU8sd0JBQXdCO0lBNkVuQyxZQUFvQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQTFFbEMsZ0JBQWdCO1FBQ1AsYUFBUSxHQUFXLEdBQUcsQ0FBQztRQUNoQyxrQkFBa0I7UUFDVCxnQkFBVyxHQUFXLEdBQUcsQ0FBQztRQUNuQyxtQ0FBbUM7UUFDMUIsb0JBQWUsR0FBd0IsUUFBUSxDQUFDO1FBQ3pELGdCQUFnQjtRQUNQLFdBQU0sR0FBVyxDQUFDLENBQUM7UUFDNUIsaUJBQWlCO1FBQ1IsYUFBUSxHQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDN0MsZ0JBQWdCO1FBQ1AsWUFBTyxHQUFXLENBQUMs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QUU1QyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7UUFDdEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDL0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsS0FBSyxHQUFHLE1BQUEsSUFBSSxDQUFDLFVBQVUsbUNBQUksQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLEtBQUssR0FBRyxJ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QUFVO3NCQUFsQixLQUFLO2dCQUVHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFFRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUlGLHNCQUFzQjtzQkFEekIsS0FBSztnQkFRRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBbVZOLGFBQWE7c0JBRFosWUFBWTt1QkFBQyxvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFrQjlDLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxtQkFBbUI7Z0JBUWpDLE1BQU07c0JBREwsWUFBWTt1QkFBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIE9uRGVzdHJveSxcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBIb3N0TGlzdGVuZXIsXG4gIE5nWm9uZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcblxuZXhwb3J0IHR5cGUgTmNBbmltYXRpb25UeXBlVHlwZSA9ICdyb3RhdGUnIHwgJ2hvdmVyJyB8ICczZHJvdGF0ZSc7XG5leHBvcnQgaW50ZXJmYWNlIE5jT2Zmc2V0IHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXJcbn07XG5cbmNvbnN0IHZlcnRleFNoYWRlciA9IGBcbiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuICBhdHRyaWJ1dGUgdmVjMyBwb3NpdGlvbjtcbiAgdm9pZCBtYWluKCkge1xuICAgIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbi54eSwgMC4wLCAxLjApO1xuICB9XG5gO1xuXG5jb25zdCBmcmFnbWVudFNoYWRlciA9IGBcbiAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuXG4gIHVuaWZvcm0gdmVjMiAgaVJlc29sdXRpb247XG4gIHVuaWZvcm0gZmxvYXQgaVRpbWU7XG5cbiAgdW5pZm9ybSBmbG9hdCB1SGVpZ2h0O1xuICB1bmlmb3JtIGZsb2F0IHVCYXNlSGFsZjtcbiAgdW5pZm9ybSBtYXQzICB1Um90O1xuICB1bmlmb3JtIGludCAgIHVVc2VCYXNlV29iYmxlO1xuICB1bmlmb3JtIGZsb2F0IHVHbG93O1xuICB1bmlmb3JtIHZlYzIgIHVPZmZzZXRQeDtcbiAgdW5pZm9ybSBmbG9hdCB1Tm9pc2U7XG4gIHVuaWZvcm0gZmxvYXQgdVNhdHVyYXRpb247XG4gIHVuaWZvcm0gZmxvYXQgdVNjYWxlO1xuICB1bmlmb3JtIGZsb2F0IHVIdWVTaGlmdDtcbiAgdW5pZm9ybSBmbG9hdCB1Q29sb3JGcmVxO1xuICB1bmlmb3JtIGZsb2F0IHVCbG9vbTtcbiAgdW5pZm9ybSBmbG9hdCB1Q2VudGVyU2hpZnQ7XG4gIHVuaWZvcm0gZmxvYXQgdUludkJhc2VIYWxmO1xuICB1bmlmb3JtIGZsb2F0IHVJbnZIZWlnaHQ7XG4gIHVuaWZvcm0gZmxvYXQgdU1pbkF4aXM7XG4gIHVuaWZvcm0gZmxvYXQgdVB4U2NhbGU7XG4gIHVuaWZvcm0gZmxvYXQgdVRpbWVTY2FsZTtcblxuICB2ZWM0IHRhbmg0KHZlYzQgeCl7XG4gICAgdmVjNCBlMnggPSBleHAoMi4wKngpO1xuICAgIHJldHVybiAoZTJ4IC0gMS4wKSAvIChlMnggKyAxLjApO1xuICB9XG5cbiAgZmxvYXQgcmFuZCh2ZWMyIGNvKXtcbiAgICByZXR1cm4gZnJhY3Qoc2luKGRvdChjbywgdmVjMigxMi45ODk4LCA3OC4yMzMpKSkgKiA0Mzc1OC41NDUzMTIzKTtcbiAgfVxuXG4gIGZsb2F0IHNkT2N0YUFuaXNvSW52KHZlYzMgcCl7XG4gICAgdmVjMyBxID0gdmVjMyhhYnMocC54KSAqIHVJbnZCYXNlSGFsZiwgYWJzKHAueSkgKiB1SW52SGVpZ2h0LCBhYnMocC56KSAqIHVJbnZCYXNlSGFsZik7XG4gICAgZmxvYXQgbSA9IHEueCArIHEueSArIHEueiAtIDEuMDtcbiAgICByZXR1cm4gbSAqIHVNaW5BeGlzICogMC41NzczNTAyNjkxODk2MjU4O1xuICB9XG5cbiAgZmxvYXQgc2RQeXJhbWlkVXBJbnYodmVjMyBwKXtcbiAgICBmbG9hdCBvY3QgPSBzZE9jdGFBbmlzb0ludihwKTtcbiAgICBmbG9hdCBoYWxmU3BhY2UgPSAtcC55O1xuICAgIHJldHVybiBtYXgob2N0LCBoYWxmU3BhY2UpO1xuICB9XG5cbiAgbWF0MyBodWVSb3RhdGlvbihmbG9hdCBhKXtcbiAgICBmbG9hdCBjID0gY29zKGEpLCBzID0gc2luKGEpO1xuICAgIG1hdDMgVyA9IG1hdDMoXG4gICAgICAwLjI5OSwgMC4yOTksIDAuMjk5LFxuICAgICAgMC41ODcsIDAuNTg3LCAwLjU4NyxcbiAgICAgIDAuMTE0LCAwLjExNCwgMC4xMTRcbiAgICApO1xuICAgIG1hdDMgVSA9IG1hdDMoXG4gICAgICAgMC43MDEsIC0wLjI5OSwgLTAuMzAwLFxuICAgICAgLTAuNTg3LCAgMC40MTMsIC0wLjU4OCxcbiAgICAgIC0wLjExNCwgLTAuMTE0LCAgMC44ODZcbiAgICApO1xuICAgIG1hdDMgViA9IG1hdDMoXG4gICAgICAgMC4xNjgsICAwLjMyOCwgLTAuNDk3LFxuICAgICAgLTAuMzMxLCAgMC4wMzUsICAwLjI5NixcbiAgICAgICAwLjUwMCwgLTAuNTAwLCAgMC4yMDFcbiAgICApO1xuICAgIHJldHVybiBXICsgVSAqIGMgKyBWICogcztcbiAgfVxuXG4gIHZvaWQgbWFpbigpe1xuICAgIHZlYzIgZiA9IChnbF9GcmFnQ29vcmQueHkgLSAwLjUgKiBpUmVzb2x1dGlvbi54eSAtIHVPZmZzZXRQeCkgKiB1UHhTY2FsZTtcblxuICAgIGZsb2F0IHogPSA1LjA7XG4gICAgZmxvYXQgZCA9IDAuMDtcblxuICAgIHZlYzMgcDtcbiAgICB2ZWM0IG8gPSB2ZWM0KDAuMCk7XG5cbiAgICBmbG9hdCBjZW50ZXJTaGlmdCA9IHVDZW50ZXJTaGlmdDtcbiAgICBmbG9hdCBjZiA9IHVDb2xvckZyZXE7XG5cbiAgICBtYXQyIHdvYiA9IG1hdDIoMS4wKTtcbiAgICBpZiAodVVzZUJhc2VXb2JibGUgPT0gMSkge1xuICAgICAgZmxvYXQgdCA9IGlUaW1lICogdVRpbWVTY2FsZTtcbiAgICAgIGZsb2F0IGMwID0gY29zKHQgKyAwLjApO1xuICAgICAgZmxvYXQgYzEgPSBjb3ModCArIDMzLjApO1xuICAgICAgZmxvYXQgYzIgPSBjb3ModCArIDExLjApO1xuICAgICAgd29iID0gbWF0MihjMCwgYzEsIGMyLCBjMCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW50IFNURVBTID0gMTAwO1xuICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU1RFUFM7IGkrKykge1xuICAgICAgcCA9IHZlYzMoZiwgeik7XG4gICAgICBwLnh6ID0gcC54eiAqIHdvYjtcbiAgICAgIHAgPSB1Um90ICogcDtcbiAgICAgIHZlYzMgcSA9IHA7XG4gICAgICBxLnkgKz0gY2VudGVyU2hpZnQ7XG4gICAgICBkID0gMC4xICsgMC4yICogYWJzKHNkUHlyYW1pZFVwSW52KHEpKTtcbiAgICAgIHogLT0gZDtcbiAgICAgIG8gKz0gKHNpbigocC55ICsgeikgKiBjZiArIHZlYzQoMC4wLCAxLjAsIDIuMCwgMy4wKSkgKyAxLjApIC8gZDtcbiAgICB9XG5cbiAgICBvID0gdGFuaDQobyAqIG8gKiAodUdsb3cgKiB1Qmxvb20pIC8gMWU1KTtcblxuICAgIHZlYzMgY29sID0gby5yZ2I7XG4gICAgZmxvYXQgbiA9IHJhbmQoZ2xfRnJhZ0Nvb3JkLnh5ICsgdmVjMihpVGltZSkpO1xuICAgIGNvbCArPSAobiAtIDAuNSkgKiB1Tm9pc2U7XG4gICAgY29sID0gY2xhbXAoY29sLCAwLjAsIDEuMCk7XG5cbiAgICBmbG9hdCBMID0gZG90KGNvbCwgdmVjMygwLjIxMjYsIDAuNzE1MiwgMC4wNzIyKSk7XG4gICAgY29sID0gY2xhbXAobWl4KHZlYzMoTCksIGNvbCwgdVNhdHVyYXRpb24pLCAwLjAsIDEuMCk7XG5cbiAgICBpZihhYnModUh1ZVNoaWZ0KSA+IDAuMDAwMSl7XG4gICAgICBjb2wgPSBjbGFtcChod