UNPKG

ng-cw-v12

Version:

Angular UI Component Library

376 lines (355 loc) 45.9 kB
import { Component, ViewChild, Input, HostListener } from '@angular/core'; import * as THREE from 'three'; import * as i0 from "@angular/core"; const vertexShader = ` varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); } `; const fragmentShader = ` precision highp float; uniform float uTime; uniform vec3 uResolution; uniform float uSpeed; uniform float uScale; uniform float uBrightness; uniform vec3 uColor1; uniform vec3 uColor2; uniform float uNoiseFreq; uniform float uNoiseAmp; uniform float uBandHeight; uniform float uBandSpread; uniform float uOctaveDecay; uniform float uLayerOffset; uniform float uColorSpeed; uniform vec2 uMouse; uniform float uMouseInfluence; uniform bool uEnableMouse; #define TAU 6.28318 vec3 gradientHash(vec3 p) { p = vec3( dot(p, vec3(127.1, 311.7, 234.6)), dot(p, vec3(269.5, 183.3, 198.3)), dot(p, vec3(169.5, 283.3, 156.9)) ); vec3 h = fract(sin(p) * 43758.5453123); float phi = acos(2.0 * h.x - 1.0); float theta = TAU * h.y; return vec3(cos(theta) * sin(phi), sin(theta) * cos(phi), cos(phi)); } float quinticSmooth(float t) { float t2 = t * t; float t3 = t * t2; return 6.0 * t3 * t2 - 15.0 * t2 * t2 + 10.0 * t3; } vec3 cosineGradient(float t, vec3 a, vec3 b, vec3 c, vec3 d) { return a + b * cos(TAU * (c * t + d)); } float perlin3D(float amplitude, float frequency, float px, float py, float pz) { float x = px * frequency; float y = py * frequency; float fx = floor(x); float fy = floor(y); float fz = floor(pz); float cx = ceil(x); float cy = ceil(y); float cz = ceil(pz); vec3 g000 = gradientHash(vec3(fx, fy, fz)); vec3 g100 = gradientHash(vec3(cx, fy, fz)); vec3 g010 = gradientHash(vec3(fx, cy, fz)); vec3 g110 = gradientHash(vec3(cx, cy, fz)); vec3 g001 = gradientHash(vec3(fx, fy, cz)); vec3 g101 = gradientHash(vec3(cx, fy, cz)); vec3 g011 = gradientHash(vec3(fx, cy, cz)); vec3 g111 = gradientHash(vec3(cx, cy, cz)); float d000 = dot(g000, vec3(x - fx, y - fy, pz - fz)); float d100 = dot(g100, vec3(x - cx, y - fy, pz - fz)); float d010 = dot(g010, vec3(x - fx, y - cy, pz - fz)); float d110 = dot(g110, vec3(x - cx, y - cy, pz - fz)); float d001 = dot(g001, vec3(x - fx, y - fy, pz - cz)); float d101 = dot(g101, vec3(x - cx, y - fy, pz - cz)); float d011 = dot(g011, vec3(x - fx, y - cy, pz - cz)); float d111 = dot(g111, vec3(x - cx, y - cy, pz - cz)); float sx = quinticSmooth(x - fx); float sy = quinticSmooth(y - fy); float sz = quinticSmooth(pz - fz); float lx00 = mix(d000, d100, sx); float lx10 = mix(d010, d110, sx); float lx01 = mix(d001, d101, sx); float lx11 = mix(d011, d111, sx); float ly0 = mix(lx00, lx10, sy); float ly1 = mix(lx01, lx11, sy); return amplitude * mix(ly0, ly1, sz); } float auroraGlow(float t, vec2 shift) { vec2 uv = gl_FragCoord.xy / uResolution.y; uv += shift; float noiseVal = 0.0; float freq = uNoiseFreq; float amp = uNoiseAmp; vec2 samplePos = uv * uScale; for (float i = 0.0; i < 3.0; i += 1.0) { noiseVal += perlin3D(amp, freq, samplePos.x, samplePos.y, t); amp *= uOctaveDecay; freq *= 2.0; } float yBand = uv.y * 10.0 - uBandHeight * 10.0; return 0.3 * max(exp(uBandSpread * (1.0 - 1.1 * abs(noiseVal + yBand))), 0.0); } void main() { vec2 uv = gl_FragCoord.xy / uResolution.xy; float t = uSpeed * 0.4 * uTime; vec2 shift = vec2(0.0); if (uEnableMouse) { shift = (uMouse - 0.5) * uMouseInfluence; } vec3 col = vec3(0.0); col += 0.99 * auroraGlow(t, shift) * cosineGradient(uv.x + uTime * uSpeed * 0.2 * uColorSpeed, vec3(0.5), vec3(0.5), vec3(1.0), vec3(0.3, 0.20, 0.20)) * uColor1; col += 0.99 * auroraGlow(t + uLayerOffset, shift) * cosineGradient(uv.x + uTime * uSpeed * 0.1 * uColorSpeed, vec3(0.5), vec3(0.5), vec3(2.0, 1.0, 0.0), vec3(0.5, 0.20, 0.25)) * uColor2; col *= uBrightness; float alpha = clamp(length(col), 0.0, 1.0); gl_FragColor = vec4(col, alpha); } `; export class SoftAuroraBackgroundComponent { constructor(ngZone) { this.ngZone = ngZone; /** 播放速度(0.1-5) */ this.ncSpeed = 0.6; /** 缩放比例(0.1-3) */ this.ncScale = 1.5; /** 亮度(0.1-3) */ this.ncBrightness = 1.0; /** 光晕颜色1 */ this.ncColor1 = '#f7f7f7'; /** 光晕颜色2 */ this.ncColor2 = '#e100ff'; /** 噪声频率(0.5-10) */ this.ncNoiseFrequency = 2.5; /** 噪声幅度(0.5-10) */ this.ncNoiseAmplitude = 1.0; /** 色带高度位置(0-1) */ this.ncBandHeight = 0.5; /** 色带扩展程度(0.1-3) */ this.ncBandSpread = 1.0; /** 噪声每层的衰减量(0.01-0.5) */ this.ncOctaveDecay = 0.1; /** 两层极光之间的时间差(0-1) */ this.ncLayerOffset = 0; /** 颜色渐变速度(0.1-5) */ this.ncColorSpeed = 1.0; /** 鼠标事件的影响力(0.1-1) */ this.ncMouseInfluence = 0.25; /** 是否启用鼠标交互 */ this._enableMouseInteraction = true; this.animationFrameId = null; this.targetMouse = [0.5, 0.5]; this.currentMouse = [0.5, 0.5]; this.timeOffset = 0; this.lastTime = 0; this.animate = () => { this.animationFrameId = requestAnimationFrame(this.animate); const currentTime = performance.now(); this.timeOffset += (currentTime - this.lastTime); this.lastTime = currentTime; if (this.material) { this.material.uniforms['uTime'].value = this.timeOffset * 0.001; if (this.ncEnableMouseInteraction) { this.currentMouse[0] += 0.05 * (this.targetMouse[0] - this.currentMouse[0]); this.currentMouse[1] += 0.05 * (this.targetMouse[1] - this.currentMouse[1]); this.material.uniforms['uMouse'].value.set(this.currentMouse[0], this.currentMouse[1]); } else { this.material.uniforms['uMouse'].value.set(0.5, 0.5); } this.renderer.render(this.scene, this.camera); } }; } set ncEnableMouseInteraction(val) { this._enableMouseInteraction = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncEnableMouseInteraction() { return this._enableMouseInteraction; } ngOnInit() { } ngAfterViewInit() { this.ngZone.runOutsideAngular(() => { this.initThreeJS(); }); } ngOnDestroy() { this.cleanup(); } ngOnChanges(changes) { if (!this.material) return; if (changes['ncSpeed']) this.material.uniforms['uSpeed'].value = this.ncSpeed; if (changes['ncScale']) this.material.uniforms['uScale'].value = this.ncScale; if (changes['ncBrightness']) this.material.uniforms['uBrightness'].value = this.ncBrightness; if (changes['ncColor1']) this.material.uniforms['uColor1'].value.set(this.ncColor1); if (changes['ncColor2']) this.material.uniforms['uColor2'].value.set(this.ncColor2); if (changes['ncNoiseFrequency']) this.material.uniforms['uNoiseFreq'].value = this.ncNoiseFrequency; if (changes['ncNoiseAmplitude']) this.material.uniforms['uNoiseAmp'].value = this.ncNoiseAmplitude; if (changes['ncBandHeight']) this.material.uniforms['uBandHeight'].value = this.ncBandHeight; if (changes['ncBandSpread']) this.material.uniforms['uBandSpread'].value = this.ncBandSpread; if (changes['ncOctaveDecay']) this.material.uniforms['uOctaveDecay'].value = this.ncOctaveDecay; if (changes['ncLayerOffset']) this.material.uniforms['uLayerOffset'].value = this.ncLayerOffset; if (changes['ncColorSpeed']) this.material.uniforms['uColorSpeed'].value = this.ncColorSpeed; if (changes['ncMouseInfluence']) this.material.uniforms['uMouseInfluence'].value = this.ncMouseInfluence; if (changes['ncEnableMouseInteraction']) this.material.uniforms['uEnableMouse'].value = this.ncEnableMouseInteraction; } onMouseMove(e) { if (!this.ncEnableMouseInteraction || !this.renderer) return; const canvas = this.renderer.domElement; const rect = canvas.getBoundingClientRect(); if (rect.width === 0 || rect.height === 0) return; this.targetMouse = [ (e.clientX - rect.left) / rect.width, 1.0 - (e.clientY - rect.top) / rect.height ]; } onMouseLeave() { if (!this.ncEnableMouseInteraction) return; this.targetMouse = [0.5, 0.5]; } initThreeJS() { const container = this.containerRef.nativeElement; this.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: false, premultipliedAlpha: false }); this.renderer.setClearColor(0x000000, 0); // transparent background this.scene = new THREE.Scene(); this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); this.material = new THREE.ShaderMaterial({ vertexShader, fragmentShader, transparent: true, uniforms: { uTime: { value: 0 }, uResolution: { value: new THREE.Vector3() }, uSpeed: { value: this.ncSpeed }, uScale: { value: this.ncScale }, uBrightness: { value: this.ncBrightness }, uColor1: { value: new THREE.Color(this.ncColor1) }, uColor2: { value: new THREE.Color(this.ncColor2) }, uNoiseFreq: { value: this.ncNoiseFrequency }, uNoiseAmp: { value: this.ncNoiseAmplitude }, uBandHeight: { value: this.ncBandHeight }, uBandSpread: { value: this.ncBandSpread }, uOctaveDecay: { value: this.ncOctaveDecay }, uLayerOffset: { value: this.ncLayerOffset }, uColorSpeed: { value: this.ncColorSpeed }, uMouse: { value: new THREE.Vector2(0.5, 0.5) }, uMouseInfluence: { value: this.ncMouseInfluence }, uEnableMouse: { value: this.ncEnableMouseInteraction } } }); const geometry = new THREE.PlaneGeometry(2, 2); this.mesh = new THREE.Mesh(geometry, this.material); this.scene.add(this.mesh); container.appendChild(this.renderer.domElement); this.resizeObserver = new ResizeObserver(() => this.resize()); this.resizeObserver.observe(container); this.resize(); this.lastTime = performance.now(); this.animate(); } resize() { if (!this.containerRef || !this.renderer) return; const container = this.containerRef.nativeElement; const width = container.offsetWidth; const height = container.offsetHeight; if (width === 0 || height === 0) return; this.renderer.setSize(width, height); if (this.material) { this.material.uniforms['uResolution'].value.set(width, height, width / height); } } cleanup() { if (this.animationFrameId !== null) { cancelAnimationFrame(this.animationFrameId); this.animationFrameId = null; } if (this.resizeObserver) { this.resizeObserver.disconnect(); } if (this.renderer && this.containerRef) { const container = this.containerRef.nativeElement; if (container.contains(this.renderer.domElement)) { container.removeChild(this.renderer.domElement); } this.renderer.dispose(); this.renderer.forceContextLoss(); } if (this.mesh) { if (this.mesh.geometry) this.mesh.geometry.dispose(); if (this.material) this.material.dispose(); } } } SoftAuroraBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SoftAuroraBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); SoftAuroraBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: SoftAuroraBackgroundComponent, selector: "nc-soft-aurora-background", inputs: { ncSpeed: "ncSpeed", ncScale: "ncScale", ncBrightness: "ncBrightness", ncColor1: "ncColor1", ncColor2: "ncColor2", ncNoiseFrequency: "ncNoiseFrequency", ncNoiseAmplitude: "ncNoiseAmplitude", ncBandHeight: "ncBandHeight", ncBandSpread: "ncBandSpread", ncOctaveDecay: "ncOctaveDecay", ncLayerOffset: "ncLayerOffset", ncColorSpeed: "ncColorSpeed", ncMouseInfluence: "ncMouseInfluence", ncEnableMouseInteraction: "ncEnableMouseInteraction" }, host: { listeners: { "mousemove": "onMouseMove($event)", "mouseleave": "onMouseLeave()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-soft-aurora-canvas-container\"></div>\r\n<div class=\"nc-content-wrapper\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}.nc-soft-aurora-canvas-container{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:#000}.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: SoftAuroraBackgroundComponent, decorators: [{ type: Component, args: [{ selector: 'nc-soft-aurora-background', templateUrl: './soft-aurora-background.component.html', styleUrls: ['./soft-aurora-background.component.less'] }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{ type: ViewChild, args: ['container', { static: true }] }], ncSpeed: [{ type: Input }], ncScale: [{ type: Input }], ncBrightness: [{ type: Input }], ncColor1: [{ type: Input }], ncColor2: [{ type: Input }], ncNoiseFrequency: [{ type: Input }], ncNoiseAmplitude: [{ type: Input }], ncBandHeight: [{ type: Input }], ncBandSpread: [{ type: Input }], ncOctaveDecay: [{ type: Input }], ncLayerOffset: [{ type: Input }], ncColorSpeed: [{ type: Input }], ncMouseInfluence: [{ type: Input }], ncEnableMouseInteraction: [{ type: Input }], onMouseMove: [{ type: HostListener, args: ['mousemove', ['$event']] }], onMouseLeave: [{ type: HostListener, args: ['mouseleave'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29mdC1hdXJvcmEtYmFja2dyb3VuZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NvZnQtYXVyb3JhLWJhY2tncm91bmQvc29mdC1hdXJvcmEtYmFja2dyb3VuZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NvZnQtYXVyb3JhLWJhY2tncm91bmQvc29mdC1hdXJvcmEtYmFja2dyb3VuZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUlULFNBQVMsRUFFVCxLQUFLLEVBR0wsWUFBWSxFQUViLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDOztBQUUvQixNQUFNLFlBQVksR0FBRzs7Ozs7O0NBTXBCLENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQXlIdEIsQ0FBQztBQU9GLE1BQU0sT0FBTyw2QkFBNkI7SUFvRHhDLFlBQW9CLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBakRsQyxrQkFBa0I7UUFDVCxZQUFPLEdBQVcsR0FBRyxDQUFDO1FBQy9CLGtCQUFrQjtRQUNULFlBQU8sR0FBVyxHQUFHLENBQUM7UUFDL0IsZ0JBQWdCO1FBQ1AsaUJBQVksR0FBVyxHQUFHLENBQUM7UUFDcEMsWUFBWTtRQUNILGFBQVEsR0FBVyxTQUFTLENBQUM7UUFDdEMsWUFBWTtRQUNILGFBQVEsR0FBVyxTQUFTLENBQUM7UUFDdEMsbUJBQW1CO1FBQ1YscUJBQWdCLEdBQVcsR0FBRyxDQUFDO1FBQ3hDLG1CQUFtQjtR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QUFRLENBQUM7Z0JBZ0JyQyxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIE9uSW5pdCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgRWxlbWVudFJlZixcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBIb3N0TGlzdGVuZXIsXHJcbiAgTmdab25lXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcclxuXHJcbmNvbnN0IHZlcnRleFNoYWRlciA9IGBcclxudmFyeWluZyB2ZWMyIHZVdjtcclxudm9pZCBtYWluKCkge1xyXG4gIHZVdiA9IHV2O1xyXG4gIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMS4wKTtcclxufVxyXG5gO1xyXG5cclxuY29uc3QgZnJhZ21lbnRTaGFkZXIgPSBgXHJcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcclxuXHJcbnVuaWZvcm0gZmxvYXQgdVRpbWU7XHJcbnVuaWZvcm0gdmVjMyB1UmVzb2x1dGlvbjtcclxudW5pZm9ybSBmbG9hdCB1U3BlZWQ7XHJcbnVuaWZvcm0gZmxvYXQgdVNjYWxlO1xyXG51bmlmb3JtIGZsb2F0IHVCcmlnaHRuZXNzO1xyXG51bmlmb3JtIHZlYzMgdUNvbG9yMTtcclxudW5pZm9ybSB2ZWMzIHVDb2xvcjI7XHJcbnVuaWZvcm0gZmxvYXQgdU5vaXNlRnJlcTtcclxudW5pZm9ybSBmbG9hdCB1Tm9pc2VBbXA7XHJcbnVuaWZvcm0gZmxvYXQgdUJhbmRIZWlnaHQ7XHJcbnVuaWZvcm0gZmxvYXQgdUJhbmRTcHJlYWQ7XHJcbnVuaWZvcm0gZmxvYXQgdU9jdGF2ZURlY2F5O1xyXG51bmlmb3JtIGZsb2F0IHVMYXllck9mZnNldDtcclxudW5pZm9ybSBmbG9hdCB1Q29sb3JTcGVlZDtcclxudW5pZm9ybSB2ZWMyIHVNb3VzZTtcclxudW5pZm9ybSBmbG9hdCB1TW91c2VJbmZsdWVuY2U7XHJcbnVuaWZvcm0gYm9vbCB1RW5hYmxlTW91c2U7XHJcblxyXG4jZGVmaW5lIFRBVSA2LjI4MzE4XHJcblxyXG52ZWMzIGdyYWRpZW50SGFzaCh2ZWMzIHApIHtcclxuICBwID0gdmVjMyhcclxuICAgIGRvdChwLCB2ZWMzKDEyNy4xLCAzMTEuNywgMjM0LjYpKSxcclxuICAgIGRvdChwLCB2ZWMzKDI2OS41LCAxODMuMywgMTk4LjMpKSxcclxuICAgIGRvdChwLCB2ZWMzKDE2OS41LCAyODMuMywgMTU2LjkpKVxyXG4gICk7XHJcbiAgdmVjMyBoID0gZnJhY3Qoc2luKHApICogNDM3NTguNTQ1MzEyMyk7XHJcbiAgZmxvYXQgcGhpID0gYWNvcygyLjAgKiBoLnggLSAxLjApO1xyXG4gIGZsb2F0IHRoZXRhID0gVEFVICogaC55O1xyXG4gIHJldHVybiB2ZWMzKGNvcyh0aGV0YSkgKiBzaW4ocGhpKSwgc2luKHRoZXRhKSAqIGNvcyhwaGkpLCBjb3MocGhpKSk7XHJcbn1cclxuXHJcbmZsb2F0IHF1aW50aWNTbW9vdGgoZmxvYXQgdCkge1xyXG4gIGZsb2F0IHQyID0gdCAqIHQ7XHJcbiAgZmxvYXQgdDMgPSB0ICogdDI7XHJcbiAgcmV0dXJuIDYuMCAqIHQzICogdDIgLSAxNS4wICogdDIgKiB0MiArIDEwLjAgKiB0MztcclxufVxyXG5cclxudmVjMyBjb3NpbmVHcmFkaWVudChmbG9hdCB0LCB2ZWMzIGEsIHZlYzMgYiwgdmVjMyBjLCB2ZWMzIGQpIHtcclxuICByZXR1cm4gYSArIGIgKiBjb3MoVEFVICogKGMgKiB0ICsgZCkpO1xyXG59XHJcblxyXG5mbG9hdCBwZXJsaW4zRChmbG9hdCBhbXBsaXR1ZGUsIGZsb2F0IGZyZXF1ZW5jeSwgZmxvYXQgcHgsIGZsb2F0IHB5LCBmbG9hdCBweikge1xyXG4gIGZsb2F0IHggPSBweCAqIGZyZXF1ZW5jeTtcclxuICBmbG9hdCB5ID0gcHkgKiBmcmVxdWVuY3k7XHJcblxyXG4gIGZsb2F0IGZ4ID0gZmxvb3IoeCk7IGZsb2F0IGZ5ID0gZmxvb3IoeSk7IGZsb2F0IGZ6ID0gZmxvb3IocHopO1xyXG4gIGZsb2F0IGN4ID0gY2VpbCh4KTsgIGZsb2F0IGN5ID0gY2VpbCh5KTsgIGZsb2F0IGN6ID0gY2VpbChweik7XHJcblxyXG4gIHZlYzMgZzAwMCA9IGdyYWRpZW50SGFzaCh2ZWMzKGZ4LCBmeSwgZnopKTtcclxuICB2ZWMzIGcxMDAgPSBncmFkaWVudEhhc2godmVjMyhjeCwgZnksIGZ6KSk7XHJcbiAgdmVjMyBnMDEwID0gZ3JhZGllbnRIYXNoKHZlYzMoZngsIGN5LCBmeikpO1xyXG4gIHZlYzMgZzExMCA9IGdyYWRpZW50SGFzaCh2ZWMzKGN4LCBjeSwgZnopKTtcclxuICB2ZWMzIGcwMDEgPSBncmFkaWVudEhhc2godmVjMyhmeCwgZnksIGN6KSk7XHJcbiAgdmVjMyBnMTAxID0gZ3JhZGllbnRIYXNoKHZlYzMoY3gsIGZ5LCBjeikpO1xyXG4gIHZlYzMgZzAxMSA9IGdyYWRpZW50SGFzaCh2ZWMzKGZ4LCBjeSwgY3opKTtcclxuICB2ZWMzIGcxMTEgPSBncmFkaWVudEhhc2godmVjMyhjeCwgY3ksIGN6KSk7XHJcblxyXG4gIGZsb2F0IGQwMDAgPSBkb3QoZzAwMCwgdmVjMyh4IC0gZngsIHkgLSBmeSwgcHogLSBmeikpO1xyXG4gIGZsb2F0IGQxMDAgPSBkb3QoZzEwMCwgdmVjMyh4IC0gY3gsIHkgLSBmeSwgcHogLSBmeikpO1xyXG4gIGZsb2F0IGQwMTAgPSBkb3QoZzAxMCwgdmVjMyh4IC0gZngsIHkgLSBjeSwgcHogLSBmeikpO1xyXG4gIGZsb2F0IGQxMTAgPSBkb3QoZzExMCwgdmVjMyh4IC0gY3gsIHkgLSBjeSwgcHogLSBmeikpO1xyXG4gIGZsb2F0IGQwMDEgPSBkb3QoZzAwMSwgdmVjMyh4IC0gZngsIHkgLSBmeSwgcHogLSBjeikpO1xyXG4gIGZsb2F0IGQxMDEgPSBkb3QoZzEwMSwgdmVjMyh4IC0gY3gsIHkgLSBmeSwgcHogLSBjeikpO1xyXG4gIGZsb2F0IGQwMTEgPSBkb3QoZzAxMSwgdmVjMyh4IC0gZngsIHkgLSBjeSwgcHogLSBjeikpO1xyXG4gIGZsb2F0IGQxMTEgPSBkb3QoZzExMSwgdmVjMyh4IC0gY3gsIHkgLSBjeSwgcHogLSBjeikpO1xyXG5cclxuICBmbG9hdCBzeCA9IHF1aW50aWNTbW9vdGgoeCAtIGZ4KTtcclxuICBmbG9hdCBzeSA9IHF1aW50aWNTbW9vdGgoeSAtIGZ5KTtcclxuICBmbG9hdCBzeiA9IHF1aW50aWNTbW9vdGgocHogLSBmeik7XHJcblxyXG4gIGZsb2F0IGx4MDAgPSBtaXgoZDAwMCwgZDEwMCwgc3gpO1xyXG4gIGZsb2F0IGx4MTAgPSBtaXgoZDAxMCwgZDExMCwgc3gpO1xyXG4gIGZsb2F0IGx4MDEgPSBtaXgoZDAwMSwgZDEwMSwgc3gpO1xyXG4gIGZsb2F0IGx4MTEgPSBtaXgoZDAxMSwgZDExMSwgc3gpO1xyXG5cclxuICBmbG9hdCBseTAgPSBtaXgobHgwMCwgbHgxMCwgc3kpO1xyXG4gIGZsb2F0IGx5MSA9IG1peChseDAxLCBseDExLCBzeSk7XHJcblxyXG4gIHJldHVybiBhbXBsaXR1ZGUgKiBtaXgobHkwLCBseTEsIHN6KTtcclxufVxyXG5cclxuZmxvYXQgYXVyb3JhR2xvdyhmbG9hdCB0LCB2ZWMyIHNoaWZ0KSB7XHJcbiAgdmVjMiB1diA9IGdsX0ZyYWdDb29yZC54eSAvIHVSZXNvbHV0aW9uLnk7XHJcbiAgdXYgKz0gc2hpZnQ7XHJcblxyXG4gIGZsb2F0IG5vaXNlVmFsID0gMC4wO1xyXG4gIGZsb2F0IGZyZXEgPSB1Tm9pc2VGcmVxO1xyXG4gIGZsb2F0IGFtcCA9IHVOb2lzZUFtcDtcclxuICB2ZWMyIHNhbXBsZVBvcyA9IHV2ICogdVNjYWxlO1xyXG5cclxuICBmb3IgKGZsb2F0IGkgPSAwLjA7IGkgPCAzLjA7IGkgKz0gMS4wKSB7XHJcbiAgICBub2lzZVZhbCArPSBwZXJsaW4zRChhbXAsIGZyZXEsIHNhbXBsZVBvcy54LCBzYW1wbGVQb3MueSwgdCk7XHJcbiAgICBhbXAgKj0gdU9jdGF2ZURlY2F5O1xyXG4gICAgZnJlcSAqPSAyLjA7XHJcbiAgfVxyXG5cclxuICBmbG9hdCB5QmFuZCA9IHV2LnkgKiAxMC4wIC0gdUJhbmRIZWlnaHQgKiAxMC4wO1xyXG4gIHJldHVybiAwLjMgKiBtYXgoZXhwKHVCYW5kU3ByZWFkICogKDEuMCAtIDEuMSAqIGFicyhub2lzZVZhbCArIHlCYW5kKSkpLCAwLjApO1xyXG59XHJcblxyXG52b2lkIG1haW4oKSB7XHJcbiAgdmVjMiB1diA9IGdsX0ZyYWdDb29yZC54eSAvIHVSZXNvbHV0aW9uLnh5O1xyXG4gIGZsb2F0IHQgPSB1U3BlZWQgKiAwLjQgKiB1VGltZTtcclxuXHJcbiAgdmVjMiBzaGlmdCA9IHZlYzIoMC4wKTtcclxuICBpZiAodUVuYWJsZU1vdXNlKSB7XHJcbiAgICBzaGlmdCA9ICh1TW91c2UgLSAwLjUpICogdU1vdXNlSW5mbHVlbmNlO1xyXG4gIH1cclxuXHJcbiAgdmVjMyBjb2wgPSB2ZWMzKDAuMCk7XHJcbiAgY29sICs9IDAuOTkgKiBhdXJvcmFHbG93KHQsIHNoaWZ0KSAqIGNvc2luZUdyYWRpZW50KHV2LnggKyB1VGltZSAqIHVTcGVlZCAqIDAuMiAqIHVDb2xvclNwZWVkLCB2ZWMzKDAuNSksIHZlYzMoMC41KSwgdmVjMygxLjApLCB2ZWMzKDAuMywgMC4yMCwgMC4yMCkpICogdUNvbG9yMTtcclxuICBjb2wgKz0gMC45OSAqIGF1cm9yYUdsb3codCArIHVMYXllck9mZnNldCwgc2hpZnQpICogY29zaW5lR3JhZGllbnQodXYueCArIHVUaW1lICogdVNwZWVkICogMC4xICogdUNvbG9yU3BlZWQsIHZlYzMoMC41KSwgdmVjMygwLjUpLCB2ZWMzKDIuMCwgMS4wLCAwLjApLCB2ZWMzKDAuNSwgMC4yMCwgMC4yNSkpICogdUNvbG9yMjtcclxuXHJcbiAgY29sICo9IHVCcmlnaHRuZXNzO1xyXG4gIGZsb2F0IGFscGhhID0gY2xhbXAobGVuZ3RoKGNvbCksIDAuMCwgMS4wKTtcclxuICBnbF9GcmFnQ29sb3IgPSB2ZWM0KGNvbCwgYWxwaGEpO1xyXG59XHJcbmA7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25jLXNvZnQtYXVyb3JhLWJhY2tncm91bmQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9zb2Z0LWF1cm9yYS1iYWNrZ3JvdW5kLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9zb2Z0LWF1cm9yYS1iYWNrZ3JvdW5kLmNvbXBvbmVudC5sZXNzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFNvZnRBdXJvcmFCYWNrZ3JvdW5kQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XHJcbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJywgeyBzdGF0aWM6IHRydWUgfSkgY29udGFpbmVyUmVmITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gIC8qKiDmkq3mlL7pgJ/luqbvvIgwLjEtNe+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jU3BlZWQ6IG51bWJlciA9IDAuNjtcclxuICAvKiog57yp5pS+5q+U5L6L77yIMC4xLTPvvIkgKi9cclxuICBASW5wdXQoKSBuY1NjYWxlOiBudW1iZXIgPSAxLjU7XHJcbiAgLyoqIOS6ruW6pu+8iDAuMS0z77yJICovXHJcbiAgQElucHV0KCkgbmNCcmlnaHRuZXNzOiBudW1iZXIgPSAxLjA7XHJcbiAgLyoqIOWFieaZleminOiJsjEgKi9cclxuICBASW5wdXQoKSBuY0NvbG9yMTogc3RyaW5nID0gJyNmN2Y3ZjcnO1xyXG4gIC8qKiDlhYnmmZXpopzoibIyICovXHJcbiAgQElucHV0KCkgbmNDb2xvcjI6IHN0cmluZyA9ICcjZTEwMGZmJztcclxuICAvKiog5Zmq5aOw6aKR546H77yIMC41LTEw77yJICovXHJcbiAgQElucHV0KCkgbmNOb2lzZUZyZXF1ZW5jeTogbnVtYmVyID0gMi41O1xyXG4gIC8qKiDlmarlo7DluYXluqbvvIgwLjUtMTDvvIkgKi9cclxuICBASW5wdXQoKSBuY05vaXNlQW1wbGl0dWRlOiBudW1iZXIgPSAxLjA7XHJcbiAgLyoqIOiJsuW4pumrmOW6puS9jee9ru+8iDAtMe+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jQmFuZEhlaWdodDogbnVtYmVyID0gMC41O1xyXG4gIC8qKiDoibLluKbmianlsZXnqIvluqbvvIgwLjEtM++8iSAqL1xyXG4gIEBJbnB1dCgpIG5jQmFuZFNwcmVhZDogbnVtYmVyID0gMS4wO1xyXG4gIC8qKiDlmarlo7Dmr4/lsYLnmoToobDlh4/ph4/vvIgwLjAxLTAuNe+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jT2N0YXZlRGVjYXk6IG51bWJlciA9IDAuMTtcclxuICAvKiog5Lik5bGC5p6B5YWJ5LmL6Ze055qE5pe26Ze05beu77yIMC0x77yJICovXHJcbiAgQElucHV0KCkgbmNMYXllck9mZnNldDogbnVtYmVyID0gMDtcclxuICAvKiog6aKc6Imy5riQ5Y+Y6YCf5bqm77yIMC4xLTXvvIkgKi9cclxuICBASW5wdXQoKSBuY0NvbG9yU3BlZWQ6IG51bWJlciA9IDEuMDtcclxuICAvKiog6byg5qCH5LqL5Lu255qE5b2x5ZON5Yqb77yIMC4xLTHvvIkgKi9cclxuICBASW5wdXQoKSBuY01vdXNlSW5mbHVlbmNlOiBudW1iZXIgPSAwLjI1O1xyXG5cclxuICAvKiog5piv5ZCm5ZCv55So6byg5qCH5Lqk5LqSICovXHJcbiAgcHJpdmF0ZSBfZW5hYmxlTW91c2VJbnRlcmFjdGlvbjogYm9vbGVhbiA9IHRydWU7XHJcbiAgQElucHV0KClcclxuICBzZXQgbmNFbmFibGVNb3VzZUludGVyYWN0aW9uKHZhbDogYm9vbGVhbiB8IHN0cmluZykge1xyXG4gICAgdGhpcy5fZW5hYmxlTW91c2VJbnRlcmFjdGlvbiA9IHZhbCAhPT0gbnVsbCAmJiB2YWwgIT09IHVuZGVmaW5lZCAmJiB2YWwgIT09IGZhbHNlICYmIHZhbCAhPT0gJ2ZhbHNlJztcclxuICB9XHJcbiAgZ2V0IG5jRW5hYmxlTW91c2VJbnRlcmFjdGlvbigpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9lbmFibGVNb3VzZUludGVyYWN0aW9uO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZW5kZXJlciE6IFRIUkVFLldlYkdMUmVuZGVyZXI7XHJcbiAgcHJpdmF0ZSBzY2VuZSE6IFRIUkVFLlNjZW5lO1xyXG4gIHByaXZhdGUgY2FtZXJhITogVEhSRUUuT3J0aG9ncmFwaGljQ2FtZXJhO1xyXG4gIHByaXZhdGUgbWF0ZXJpYWwhOiBUSFJFRS5TaGFkZXJNYXRlcmlhbDtcclxuICBwcml2YXRlIG1lc2ghOiBUSFJFRS5NZXNoO1xyXG4gIHByaXZhdGUgYW5pbWF0aW9uRnJhbWVJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSB0YXJnZXRNb3VzZTogW251bWJlciwgbnVtYmVyXSA9IFswLjUsIDAuNV07XHJcbiAgcHJpdmF0ZSBjdXJyZW50TW91c2U6IFtudW1iZXIsIG51bWJlcl0gPSBbMC41LCAwLjVdO1xyXG4gIHByaXZhdGUgcmVzaXplT2JzZXJ2ZXIhOiBSZXNpemVPYnNlcnZlcjtcclxuICBwcml2YXRlIHRpbWVPZmZzZXQ6IG51bWJlciA9IDA7XHJcbiAgcHJpdmF0ZSBsYXN0VGltZTogbnVtYmVyID0gMDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkgeyB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQgeyB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgdGhpcy5pbml0VGhyZWVKUygpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xlYW51cCgpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLm1hdGVyaWFsKSByZXR1cm47XHJcblxyXG4gICAgaWYgKGNoYW5nZXNbJ25jU3BlZWQnXSkgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndVNwZWVkJ10udmFsdWUgPSB0aGlzLm5jU3BlZWQ7XHJcbiAgICBpZiAoY2hhbmdlc1snbmNTY2FsZSddKSB0aGlzLm1hdGVyaWFsLnVuaWZvcm1zWyd1U2NhbGUnXS52YWx1ZSA9IHRoaXMubmNTY2FsZTtcclxuICAgIGlmIChjaGFuZ2VzWyduY0JyaWdodG5lc3MnXSkgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndUJyaWdodG5lc3MnXS52YWx1ZSA9IHRoaXMubmNCcmlnaHRuZXNzO1xyXG4gICAgaWYgKGNoYW5nZXNbJ25jQ29sb3IxJ10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VDb2xvcjEnXS52YWx1ZS5zZXQodGhpcy5uY0NvbG9yMSk7XHJcbiAgICBpZiAoY2hhbmdlc1snbmNDb2xvcjInXSkgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndUNvbG9yMiddLnZhbHVlLnNldCh0aGlzLm5jQ29sb3IyKTtcclxuICAgIGlmIChjaGFuZ2VzWyduY05vaXNlRnJlcXVlbmN5J10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VOb2lzZUZyZXEnXS52YWx1ZSA9IHRoaXMubmNOb2lzZUZyZXF1ZW5jeTtcclxuICAgIGlmIChjaGFuZ2VzWyduY05vaXNlQW1wbGl0dWRlJ10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VOb2lzZUFtcCddLnZhbHVlID0gdGhpcy5uY05vaXNlQW1wbGl0dWRlO1xyXG4gICAgaWYgKGNoYW5nZXNbJ25jQmFuZEhlaWdodCddKSB0aGlzLm1hdGVyaWFsLnVuaWZvcm1zWyd1QmFuZEhlaWdodCddLnZhbHVlID0gdGhpcy5uY0JhbmRIZWlnaHQ7XHJcbiAgICBpZiAoY2hhbmdlc1snbmNCYW5kU3ByZWFkJ10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VCYW5kU3ByZWFkJ10udmFsdWUgPSB0aGlzLm5jQmFuZFNwcmVhZDtcclxuICAgIGlmIChjaGFuZ2VzWyduY09jdGF2ZURlY2F5J10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VPY3RhdmVEZWNheSddLnZhbHVlID0gdGhpcy5uY09jdGF2ZURlY2F5O1xyXG4gICAgaWYgKGNoYW5nZXNbJ25jTGF5ZXJPZmZzZXQnXSkgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndUxheWVyT2Zmc2V0J10udmFsdWUgPSB0aGlzLm5jTGF5ZXJPZmZzZXQ7XHJcbiAgICBpZiAoY2hhbmdlc1snbmNDb2xvclNwZWVkJ10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VDb2xvclNwZWVkJ10udmFsdWUgPSB0aGlzLm5jQ29sb3JTcGVlZDtcclxuICAgIGlmIChjaGFuZ2VzWyduY01vdXNlSW5mbHVlbmNlJ10pIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VNb3VzZUluZmx1ZW5jZSddLnZhbHVlID0gdGhpcy5uY01vdXNlSW5mbHVlbmNlO1xyXG4gICAgaWYgKGNoYW5nZXNbJ25jRW5hYmxlTW91c2VJbnRlcmFjdGlvbiddKSB0aGlzLm1hdGVyaWFsLnVuaWZvcm1zWyd1RW5hYmxlTW91c2UnXS52YWx1ZSA9IHRoaXMubmNFbmFibGVNb3VzZUludGVyYWN0aW9uO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcclxuICBvbk1vdXNlTW92ZShlOiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMubmNFbmFibGVNb3VzZUludGVyYWN0aW9uIHx8ICF0aGlzLnJlbmRlcmVyKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5yZW5kZXJlci5kb21FbGVtZW50O1xyXG4gICAgY29uc3QgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgICBpZiAocmVjdC53aWR0aCA9PT0gMCB8fCByZWN0LmhlaWdodCA9PT0gMCkgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMudGFyZ2V0TW91c2UgPSBbXHJcbiAgICAgIChlLmNsaWVudFggLSByZWN0LmxlZnQpIC8gcmVjdC53aWR0aCxcclxuICAgICAgMS4wIC0gKGUuY2xpZW50WSAtIHJlY3QudG9wKSAvIHJlY3QuaGVpZ2h0XHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScpXHJcbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLm5jRW5hYmxlTW91c2VJbnRlcmFjdGlvbikgcmV0dXJuO1xyXG4gICAgdGhpcy50YXJnZXRNb3VzZSA9IFswLjUsIDAuNV07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRUaHJlZUpTKCk6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5jb250YWluZXJSZWYubmF0aXZlRWxlbWVudDtcclxuXHJcbiAgICB0aGlzLnJlbmRlcmVyID0gbmV3IFRIUkVFLldlYkdMUmVuZGVyZXIoeyBhbHBoYTogdHJ1ZSwgYW50aWFsaWFzOiBmYWxzZSwgcHJlbXVsdGlwbGllZEFscGhhOiBmYWxzZSB9KTtcclxuICAgIHRoaXMucmVuZGVyZXIuc2V0Q2xlYXJDb2xvcigweDAwMDAwMCwgMCk7IC8vIHRyYW5zcGFyZW50IGJhY2tncm91bmRcclxuXHJcbiAgICB0aGlzLnNjZW5lID0gbmV3IFRIUkVFLlNjZW5lKCk7XHJcblxyXG4gICAgdGhpcy5jYW1lcmEgPSBuZXcgVEhSRUUuT3J0aG9ncmFwaGljQ2FtZXJhKC0xLCAxLCAxLCAtMSwgMCwgMSk7XHJcblxyXG4gICAgdGhpcy5tYXRlcmlhbCA9IG5ldyBUSFJFRS5TaGFkZXJNYXRlcmlhbCh7XHJcbiAgICAgIHZlcnRleFNoYWRlcixcclxuICAgICAgZnJhZ21lbnRTaGFkZXIsXHJcbiAgICAgIHRyYW5zcGFyZW50OiB0cnVlLFxyXG4gICAgICB1bmlmb3Jtczoge1xyXG4gICAgICAgIHVUaW1lOiB7IHZhbHVlOiAwIH0sXHJcbiAgICAgICAgdVJlc29sdXRpb246IHsgdmFsdWU6IG5ldyBUSFJFRS5WZWN0b3IzKCkgfSxcclxuICAgICAgICB1U3BlZWQ6IHsgdmFsdWU6IHRoaXMubmNTcGVlZCB9LFxyXG4gICAgICAgIHVTY2FsZTogeyB2YWx1ZTogdGhpcy5uY1NjYWxlIH0sXHJcbiAgICAgICAgdUJyaWdodG5lc3M6IHsgdmFsdWU6IHRoaXMubmNCcmlnaHRuZXNzIH0sXHJcbiAgICAgICAgdUNvbG9yMTogeyB2YWx1ZTogbmV3IFRIUkVFLkNvbG9yKHRoaXMubmNDb2xvcjEpIH0sXHJcbiAgICAgICAgdUNvbG9yMjogeyB2YWx1ZTogbmV3IFRIUkVFLkNvbG9yKHRoaXMubmNDb2xvcjIpIH0sXHJcbiAgICAgICAgdU5vaXNlRnJlcTogeyB2YWx1ZTogdGhpcy5uY05vaXNlRnJlcXVlbmN5IH0sXHJcbiAgICAgICAgdU5vaXNlQW1wOiB7IHZhbHVlOiB0aGlzLm5jTm9pc2VBbXBsaXR1ZGUgfSxcclxuICAgICAgICB1QmFuZEhlaWdodDogeyB2YWx1ZTogdGhpcy5uY0JhbmRIZWlnaHQgfSxcclxuICAgICAgICB1QmFuZFNwcmVhZDogeyB2YWx1ZTogdGhpcy5uY0JhbmRTcHJlYWQgfSxcclxuICAgICAgICB1T2N0YXZlRGVjYXk6IHsgdmFsdWU6IHRoaXMubmNPY3RhdmVEZWNheSB9LFxyXG4gICAgICAgIHVMYXllck9mZnNldDogeyB2YWx1ZTogdGhpcy5uY0xheWVyT2Zmc2V0IH0sXHJcbiAgICAgICAgdUNvbG9yU3BlZWQ6IHsgdmFsdWU6IHRoaXMubmNDb2xvclNwZWVkIH0sXHJcbiAgICAgICAgdU1vdXNlOiB7IHZhbHVlOiBuZXcgVEhSRUUuVmVjdG9yMigwLjUsIDAuNSkgfSxcclxuICAgICAgICB1TW91c2VJbmZsdWVuY2U6IHsgdmFsdWU6IHRoaXMubmNNb3VzZUluZmx1ZW5jZSB9LFxyXG4gICAgICAgIHVFbmFibGVNb3VzZTogeyB2YWx1ZTogdGhpcy5uY0VuYWJsZU1vdXNlSW50ZXJhY3Rpb24gfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBUSFJFRS5QbGFuZUdlb21ldHJ5KDIsIDIpO1xyXG4gICAgdGhpcy5tZXNoID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnksIHRoaXMubWF0ZXJpYWwpO1xyXG4gICAgdGhpcy5zY2VuZS5hZGQodGhpcy5tZXNoKTtcclxuXHJcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5yZW5kZXJlci5kb21FbGVtZW50KTtcclxuXHJcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHRoaXMucmVzaXplKCkpO1xyXG4gICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKGNvbnRhaW5lcik7XHJcbiAgICB0aGlzLnJlc2l6ZSgpO1xyXG5cclxuICAgIHRoaXMubGFzdFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcclxuICAgIHRoaXMuYW5pbWF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNpemUoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuY29udGFpbmVyUmVmIHx8ICF0aGlzLnJlbmRlcmVyKSByZXR1cm47XHJcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3Qgd2lkdGggPSBjb250YWluZXIub2Zmc2V0V2lkdGg7XHJcbiAgICBjb25zdCBoZWlnaHQgPSBjb250YWluZXIub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgIGlmICh3aWR0aCA9PT0gMCB8fCBoZWlnaHQgPT09IDApIHJldHVybjtcclxuXHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFNpemUod2lkdGgsIGhlaWdodCk7XHJcbiAgICBpZiAodGhpcy5tYXRlcmlhbCkge1xyXG4gICAgICB0aGlzLm1hdGVyaWFsLnVuaWZvcm1zWyd1UmVzb2x1dGlvbiddLnZhbHVlLnNldCh3aWR0aCwgaGVpZ2h0LCB3aWR0aCAvIGhlaWdodCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFuaW1hdGUgPSAoKTogdm9pZCA9PiB7XHJcbiAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRlKTtcclxuXHJcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xyXG4gICAgdGhpcy50aW1lT2Zmc2V0ICs9IChjdXJyZW50VGltZSAtIHRoaXMubGFzdFRpbWUpO1xyXG4gICAgdGhpcy5sYXN0VGltZSA9IGN1cnJlbnRUaW1lO1xyXG5cclxuICAgIGlmICh0aGlzLm1hdGVyaWFsKSB7XHJcbiAgICAgIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VUaW1lJ10udmFsdWUgPSB0aGlzLnRpbWVPZmZzZXQgKiAwLjAwMTtcclxuXHJcbiAgICAgIGlmICh0aGlzLm5jRW5hYmxlTW91c2VJbnRlcmFjdGlvbikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudE1vdXNlWzBdICs9IDAuMDUgKiAodGhpcy50YXJnZXRNb3VzZVswXSAtIHRoaXMuY3VycmVudE1vdXNlWzBdKTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRNb3VzZVsxXSArPSAwLjA1ICogKHRoaXMudGFyZ2V0TW91c2VbMV0gLSB0aGlzLmN1cnJlbnRNb3VzZVsxXSk7XHJcbiAgICAgICAgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndU1vdXNlJ10udmFsdWUuc2V0KHRoaXMuY3VycmVudE1vdXNlWzBdLCB0aGlzLmN1cnJlbnRNb3VzZVsxXSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndU1vdXNlJ10udmFsdWUuc2V0KDAuNSwgMC41KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIodGhpcy5zY2VuZSwgdGhpcy5jYW1lcmEpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgY2xlYW51cCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmFuaW1hdGlvbkZyYW1lSWQgIT09IG51bGwpIHtcclxuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRpb25GcmFtZUlkKTtcclxuICAgICAgdGhpcy5hbmltYXRpb25GcmFtZUlkID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5yZXNpemVPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5yZW5kZXJlciAmJiB0aGlzLmNvbnRhaW5lclJlZikge1xyXG4gICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgICBpZiAoY29udGFpbmVyLmNvbnRhaW5zKHRoaXMucmVuZGVyZXIuZG9tRWxlbWVudCkpIHtcclxuICAgICAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy5yZW5kZXJlci5kb21FbGVtZW50KTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnJlbmRlcmVyLmRpc3Bvc2UoKTtcclxuICAgICAgdGhpcy5yZW5kZXJlci5mb3JjZUNvbnRleHRMb3NzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMubWVzaCkge1xyXG4gICAgICBpZiAodGhpcy5tZXNoLmdlb21ldHJ5KSB0aGlzLm1lc2guZ2VvbWV0cnkuZGlzcG9zZSgpO1xyXG4gICAgICBpZiAodGhpcy5tYXRlcmlhbCkgdGhpcy5tYXRlcmlhbC5kaXNwb3NlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgI2NvbnRhaW5lciBjbGFzcz1cIm5jLXNvZnQtYXVyb3JhLWNhbnZhcy1jb250YWluZXJcIj48L2Rpdj5cclxuPGRpdiBjbGFzcz1cIm5jLWNvbnRlbnQtd3JhcHBlclwiPlxyXG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG48L2Rpdj5cclxuIl19