ng-cw-v12
Version:
Angular UI Component Library
237 lines (222 loc) • 26.7 kB
JavaScript
import { Component, ViewChild, Input, HostListener } from '@angular/core';
import * as THREE from 'three';
import * as i0 from "@angular/core";
const VERT = `
attribute vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}
`;
const FRAG = `
precision highp float;
uniform float uTime;
uniform float uAmplitude;
uniform vec3 uColorStops[3];
uniform vec2 uResolution;
uniform float uBlend;
// out vec4 fragColor; eliminated for WebGL1
vec3 permute(vec3 x) {
return mod(((x * 34.0) + 1.0) * x, 289.0);
}
float snoise(vec2 v){
const vec4 C = vec4(
0.211324865405187, 0.366025403784439,
-0.577350269189626, 0.024390243902439
);
vec2 i = floor(v + dot(v, C.yy));
vec2 x0 = v - i + dot(i, C.xx);
vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;
i = mod(i, 289.0);
vec3 p = permute(
permute(i.y + vec3(0.0, i1.y, 1.0))
+ i.x + vec3(0.0, i1.x, 1.0)
);
vec3 m = max(
0.5 - vec3(
dot(x0, x0),
dot(x12.xy, x12.xy),
dot(x12.zw, x12.zw)
),
0.0
);
m = m * m;
m = m * m;
vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;
m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}
void main() {
vec2 uv = gl_FragCoord.xy / uResolution;
vec3 rampColor;
if (uv.x < 0.5) {
rampColor = mix(uColorStops[0], uColorStops[1], uv.x * 2.0);
} else {
rampColor = mix(uColorStops[1], uColorStops[2], (uv.x - 0.5) * 2.0);
}
float height = snoise(vec2(uv.x * 2.0 + uTime * 0.1, uTime * 0.25)) * 0.5 * uAmplitude;
height = exp(height);
height = (uv.y * 2.0 - height + 0.2);
float intensity = 0.6 * height;
float midPoint = 0.20;
float auroraAlpha = smoothstep(midPoint - uBlend * 0.5, midPoint + uBlend * 0.5, intensity);
vec3 auroraColor = intensity * rampColor;
gl_FragColor = vec4(auroraColor * auroraAlpha, auroraAlpha);
}
`;
export class AuroraBackgroundComponent {
constructor(ngZone) {
this.ngZone = ngZone;
/** 颜色断点,默认为 ['#5227FF', '#7cff67', '#5227FF'] */
this.ncColorStops = ['#5227FF', '#7cff67', '#5227FF'];
/** 极光振幅(0-3) */
this.ncAmplitude = 1;
/** 极光混合度(0-1) */
this.ncBlend = 0.5;
/** 极光运动速度(0-2) */
this.ncSpeed = 1;
this.animateId = 0;
this.isDestroyed = false;
}
ngOnInit() { }
ngAfterViewInit() {
this.ngZone.runOutsideAngular(() => {
this.initWebGL();
});
}
ngOnDestroy() {
this.isDestroyed = true;
this.cleanup();
}
ngOnChanges(changes) {
if (this.material) {
if (changes['ncAmplitude']) {
this.material.uniforms['uAmplitude'].value = this.ncAmplitude;
}
if (changes['ncBlend']) {
this.material.uniforms['uBlend'].value = this.ncBlend;
}
if (changes['ncColorStops']) {
this.material.uniforms['uColorStops'].value = this.parseColorStops(this.ncColorStops);
}
// Parameters applied, material automatically updates via uniformity.
}
}
onResize() {
this.resize();
}
parseColorStops(stops) {
const array = stops && stops.length === 3 ? stops : ['#5227FF', '#7cff67', '#5227FF'];
return array.map(hex => {
const c = new THREE.Color(hex);
return new THREE.Vector3(c.r, c.g, c.b);
});
}
initWebGL() {
var _a, _b;
const ctn = this.containerRef.nativeElement;
if (!ctn)
return;
this.renderer = new THREE.WebGLRenderer({
alpha: true,
premultipliedAlpha: true,
antialias: true
});
this.renderer.setClearColor(0x000000, 0);
this.renderer.domElement.style.backgroundColor = 'transparent';
this.renderer.domElement.style.width = '100%';
this.renderer.domElement.style.height = '100%';
ctn.appendChild(this.renderer.domElement);
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
const geometry = new THREE.PlaneGeometry(2, 2);
this.material = new THREE.RawShaderMaterial({
vertexShader: VERT,
fragmentShader: FRAG,
uniforms: {
uTime: { value: 0 },
uAmplitude: { value: (_a = this.ncAmplitude) !== null && _a !== void 0 ? _a : 1.0 },
uColorStops: { value: this.parseColorStops(this.ncColorStops) },
uResolution: { value: new THREE.Vector2(ctn.offsetWidth, ctn.offsetHeight) },
uBlend: { value: (_b = this.ncBlend) !== null && _b !== void 0 ? _b : 0.5 }
},
transparent: true,
blending: THREE.CustomBlending,
blendEquation: THREE.AddEquation,
blendSrc: THREE.OneFactor,
blendDst: THREE.OneMinusSrcAlphaFactor
});
this.mesh = new THREE.Mesh(geometry, this.material);
this.scene.add(this.mesh);
this.resize();
const update = (t) => {
var _a;
if (this.isDestroyed)
return;
this.animateId = requestAnimationFrame(update);
const timeElapsed = t * 0.01;
this.material.uniforms['uTime'].value = timeElapsed * ((_a = this.ncSpeed) !== null && _a !== void 0 ? _a : 1.0) * 0.1;
this.renderer.render(this.scene, this.camera);
};
this.animateId = requestAnimationFrame(update);
}
resize() {
if (!this.containerRef || !this.renderer || !this.material)
return;
const ctn = this.containerRef.nativeElement;
const width = ctn.offsetWidth;
const height = ctn.offsetHeight;
this.renderer.setSize(width, height, false);
this.material.uniforms['uResolution'].value.set(width, height);
}
cleanup() {
if (this.animateId) {
cancelAnimationFrame(this.animateId);
}
if (this.renderer && this.containerRef) {
const ctn = this.containerRef.nativeElement;
if (ctn.contains(this.renderer.domElement)) {
ctn.removeChild(this.renderer.domElement);
}
this.renderer.dispose();
}
if (this.material) {
this.material.dispose();
}
if (this.mesh && this.mesh.geometry) {
this.mesh.geometry.dispose();
}
}
}
AuroraBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: AuroraBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
AuroraBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: AuroraBackgroundComponent, selector: "nc-aurora-background", inputs: { ncColorStops: "ncColorStops", ncAmplitude: "ncAmplitude", ncBlend: "ncBlend", ncSpeed: "ncSpeed" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-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-aurora-canvas-container{position:absolute;inset:0;z-index:0;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: AuroraBackgroundComponent, decorators: [{
type: Component,
args: [{
selector: 'nc-aurora-background',
templateUrl: './aurora-background.component.html',
styleUrls: ['./aurora-background.component.less']
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{
type: ViewChild,
args: ['container', { static: true }]
}], ncColorStops: [{
type: Input
}], ncAmplitude: [{
type: Input
}], ncBlend: [{
type: Input
}], ncSpeed: [{
type: Input
}], onResize: [{
type: HostListener,
args: ['window:resize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVyb3JhLWJhY2tncm91bmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9hdXJvcmEtYmFja2dyb3VuZC9hdXJvcmEtYmFja2dyb3VuZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2F1cm9yYS1iYWNrZ3JvdW5kL2F1cm9yYS1iYWNrZ3JvdW5kLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBSVQsU0FBUyxFQUVULEtBQUssRUFHTCxZQUFZLEVBRWIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxLQUFLLEtBQUssTUFBTSxPQUFPLENBQUM7O0FBRS9CLE1BQU0sSUFBSSxHQUFHOzs7OztDQUtaLENBQUM7QUFFRixNQUFNLElBQUksR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBOEVaLENBQUM7QUFPRixNQUFNLE9BQU8seUJBQXlCO0lBb0JwQyxZQUFvQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQWpCbEMsaURBQWlEO1FBQ3hDLGlCQUFZLEdBQWEsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BFLGdCQUFnQjtRQUNQLGdCQUFXLEdBQVcsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFpQjtRQUNSLFlBQU8sR0FBVyxHQUFHLENBQUM7UUFDL0Isa0JBQWtCO1FBQ1QsWUFBTyxHQUFXLENBQUMsQ0FBQztRQU9yQixjQUFTLEdBQVcsQ0FBQyxDQUFDO1FBQ3RCLGdCQUFXLEdBQVksS0FBSyxDQUFDO0lBRUMsQ0FBQztJQUV2QyxRQUFRLEtBQVcsQ0FBQztJQUVwQixlQUFlO1FBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIs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bnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgT25Jbml0LFxyXG4gIE9uRGVzdHJveSxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIFZpZXdDaGlsZCxcclxuICBFbGVtZW50UmVmLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBOZ1pvbmVcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgVEhSRUUgZnJvbSAndGhyZWUnO1xyXG5cclxuY29uc3QgVkVSVCA9IGBcclxuYXR0cmlidXRlIHZlYzMgcG9zaXRpb247XHJcbnZvaWQgbWFpbigpIHtcclxuICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDEuMCk7XHJcbn1cclxuYDtcclxuXHJcbmNvbnN0IEZSQUcgPSBgXHJcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcclxuXHJcbnVuaWZvcm0gZmxvYXQgdVRpbWU7XHJcbnVuaWZvcm0gZmxvYXQgdUFtcGxpdHVkZTtcclxudW5pZm9ybSB2ZWMzIHVDb2xvclN0b3BzWzNdO1xyXG51bmlmb3JtIHZlYzIgdVJlc29sdXRpb247XHJcbnVuaWZvcm0gZmxvYXQgdUJsZW5kO1xyXG5cclxuLy8gb3V0IHZlYzQgZnJhZ0NvbG9yOyBlbGltaW5hdGVkIGZvciBXZWJHTDFcclxuXHJcblxyXG52ZWMzIHBlcm11dGUodmVjMyB4KSB7XHJcbiAgcmV0dXJuIG1vZCgoKHggKiAzNC4wKSArIDEuMCkgKiB4LCAyODkuMCk7XHJcbn1cclxuXHJcbmZsb2F0IHNub2lzZSh2ZWMyIHYpe1xyXG4gIGNvbnN0IHZlYzQgQyA9IHZlYzQoXHJcbiAgICAgIDAuMjExMzI0ODY1NDA1MTg3LCAwLjM2NjAyNTQwMzc4NDQzOSxcclxuICAgICAgLTAuNTc3MzUwMjY5MTg5NjI2LCAwLjAyNDM5MDI0MzkwMjQzOVxyXG4gICk7XHJcbiAgdmVjMiBpICA9IGZsb29yKHYgKyBkb3QodiwgQy55eSkpO1xyXG4gIHZlYzIgeDAgPSB2IC0gaSArIGRvdChpLCBDLnh4KTtcclxuICB2ZWMyIGkxID0gKHgwLnggPiB4MC55KSA/IHZlYzIoMS4wLCAwLjApIDogdmVjMigwLjAsIDEuMCk7XHJcbiAgdmVjNCB4MTIgPSB4MC54eXh5ICsgQy54eHp6O1xyXG4gIHgxMi54eSAtPSBpMTtcclxuICBpID0gbW9kKGksIDI4OS4wKTtcclxuXHJcbiAgdmVjMyBwID0gcGVybXV0ZShcclxuICAgICAgcGVybXV0ZShpLnkgKyB2ZWMzKDAuMCwgaTEueSwgMS4wKSlcclxuICAgICsgaS54ICsgdmVjMygwLjAsIGkxLngsIDEuMClcclxuICApO1xyXG5cclxuICB2ZWMzIG0gPSBtYXgoXHJcbiAgICAgIDAuNSAtIHZlYzMoXHJcbiAgICAgICAgICBkb3QoeDAsIHgwKSxcclxuICAgICAgICAgIGRvdCh4MTIueHksIHgxMi54eSksXHJcbiAgICAgICAgICBkb3QoeDEyLnp3LCB4MTIuencpXHJcbiAgICAgICksIFxyXG4gICAgICAwLjBcclxuICApO1xyXG4gIG0gPSBtICogbTtcclxuICBtID0gbSAqIG07XHJcblxyXG4gIHZlYzMgeCA9IDIuMCAqIGZyYWN0KHAgKiBDLnd3dykgLSAxLjA7XHJcbiAgdmVjMyBoID0gYWJzKHgpIC0gMC41O1xyXG4gIHZlYzMgb3ggPSBmbG9vcih4ICsgMC41KTtcclxuICB2ZWMzIGEwID0geCAtIG94O1xyXG4gIG0gKj0gMS43OTI4NDI5MTQwMDE1OSAtIDAuODUzNzM0NzIwOTUzMTQgKiAoYTAqYTAgKyBoKmgpO1xyXG5cclxuICB2ZWMzIGc7XHJcbiAgZy54ICA9IGEwLnggICogeDAueCAgKyBoLnggICogeDAueTtcclxuICBnLnl6ID0gYTAueXogKiB4MTIueHogKyBoLnl6ICogeDEyLnl3O1xyXG4gIHJldHVybiAxMzAuMCAqIGRvdChtLCBnKTtcclxufVxyXG5cclxudm9pZCBtYWluKCkge1xyXG4gIHZlYzIgdXYgPSBnbF9GcmFnQ29vcmQueHkgLyB1UmVzb2x1dGlvbjtcclxuICBcclxuICB2ZWMzIHJhbXBDb2xvcjtcclxuICBpZiAodXYueCA8IDAuNSkge1xyXG4gICAgICByYW1wQ29sb3IgPSBtaXgodUNvbG9yU3RvcHNbMF0sIHVDb2xvclN0b3BzWzFdLCB1di54ICogMi4wKTtcclxuICB9IGVsc2Uge1xyXG4gICAgICByYW1wQ29sb3IgPSBtaXgodUNvbG9yU3RvcHNbMV0sIHVDb2xvclN0b3BzWzJdLCAodXYueCAtIDAuNSkgKiAyLjApO1xyXG4gIH1cclxuICBcclxuICBmbG9hdCBoZWlnaHQgPSBzbm9pc2UodmVjMih1di54ICogMi4wICsgdVRpbWUgKiAwLjEsIHVUaW1lICogMC4yNSkpICogMC41ICogdUFtcGxpdHVkZTtcclxuICBoZWlnaHQgPSBleHAoaGVpZ2h0KTtcclxuICBoZWlnaHQgPSAodXYueSAqIDIuMCAtIGhlaWdodCArIDAuMik7XHJcbiAgZmxvYXQgaW50ZW5zaXR5ID0gMC42ICogaGVpZ2h0O1xyXG4gIFxyXG4gIGZsb2F0IG1pZFBvaW50ID0gMC4yMDtcclxuICBmbG9hdCBhdXJvcmFBbHBoYSA9IHNtb290aHN0ZXAobWlkUG9pbnQgLSB1QmxlbmQgKiAwLjUsIG1pZFBvaW50ICsgdUJsZW5kICogMC41LCBpbnRlbnNpdHkpO1xyXG4gIFxyXG4gIHZlYzMgYXVyb3JhQ29sb3IgPSBpbnRlbnNpdHkgKiByYW1wQ29sb3I7XHJcbiAgXHJcbiAgZ2xfRnJhZ0NvbG9yID0gdmVjNChhdXJvcmFDb2xvciAqIGF1cm9yYUFscGhhLCBhdXJvcmFBbHBoYSk7XHJcbn1cclxuYDtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmMtYXVyb3JhLWJhY2tncm91bmQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9hdXJvcmEtYmFja2dyb3VuZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vYXVyb3JhLWJhY2tncm91bmQuY29tcG9uZW50Lmxlc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXVyb3JhQmFja2dyb3VuZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xyXG4gIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pIGNvbnRhaW5lclJlZiE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xyXG5cclxuICAvKiog6aKc6Imy5pat54K577yM6buY6K6k5Li6IFsnIzUyMjdGRicsICcjN2NmZjY3JywgJyM1MjI3RkYnXSAqL1xyXG4gIEBJbnB1dCgpIG5jQ29sb3JTdG9wczogc3RyaW5nW10gPSBbJyM1MjI3RkYnLCAnIzdjZmY2NycsICcjNTIyN0ZGJ107XHJcbiAgLyoqIOaegeWFieaMr+W5he+8iDAtM++8iSAqL1xyXG4gIEBJbnB1dCgpIG5jQW1wbGl0dWRlOiBudW1iZXIgPSAxO1xyXG4gIC8qKiDmnoHlhYnmt7flkIjluqbvvIgwLTHvvIkgKi9cclxuICBASW5wdXQoKSBuY0JsZW5kOiBudW1iZXIgPSAwLjU7XHJcbiAgLyoqIOaegeWFiei/kOWKqOmAn+W6pu+8iDAtMu+8iSAqL1xyXG4gIEBJbnB1dCgpIG5jU3BlZWQ6IG51bWJlciA9IDE7XHJcblxyXG4gIHByaXZhdGUgcmVuZGVyZXIhOiBUSFJFRS5XZWJHTFJlbmRlcmVyO1xyXG4gIHByaXZhdGUgc2NlbmUhOiBUSFJFRS5TY2VuZTtcclxuICBwcml2YXRlIGNhbWVyYSE6IFRIUkVFLk9ydGhvZ3JhcGhpY0NhbWVyYTtcclxuICBwcml2YXRlIG1hdGVyaWFsITogVEhSRUUuUmF3U2hhZGVyTWF0ZXJpYWw7XHJcbiAgcHJpdmF0ZSBtZXNoITogVEhSRUUuTWVzaDtcclxuICBwcml2YXRlIGFuaW1hdGVJZDogbnVtYmVyID0gMDtcclxuICBwcml2YXRlIGlzRGVzdHJveWVkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUpIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHsgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgIHRoaXMuaW5pdFdlYkdMKCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pc0Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICB0aGlzLmNsZWFudXAoKTtcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLm1hdGVyaWFsKSB7XHJcbiAgICAgIGlmIChjaGFuZ2VzWyduY0FtcGxpdHVkZSddKSB7XHJcbiAgICAgICAgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndUFtcGxpdHVkZSddLnZhbHVlID0gdGhpcy5uY0FtcGxpdHVkZTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoY2hhbmdlc1snbmNCbGVuZCddKSB7XHJcbiAgICAgICAgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndUJsZW5kJ10udmFsdWUgPSB0aGlzLm5jQmxlbmQ7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGNoYW5nZXNbJ25jQ29sb3JTdG9wcyddKSB7XHJcbiAgICAgICAgdGhpcy5tYXRlcmlhbC51bmlmb3Jtc1sndUNvbG9yU3RvcHMnXS52YWx1ZSA9IHRoaXMucGFyc2VDb2xvclN0b3BzKHRoaXMubmNDb2xvclN0b3BzKTtcclxuICAgICAgfVxyXG4gICAgICAvLyBQYXJhbWV0ZXJzIGFwcGxpZWQsIG1hdGVyaWFsIGF1dG9tYXRpY2FsbHkgdXBkYXRlcyB2aWEgdW5pZm9ybWl0eS5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxyXG4gIG9uUmVzaXplKCk6IHZvaWQge1xyXG4gICAgdGhpcy5yZXNpemUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcGFyc2VDb2xvclN0b3BzKHN0b3BzOiBzdHJpbmdbXSk6IFRIUkVFLlZlY3RvcjNbXSB7XHJcbiAgICBjb25zdCBhcnJheSA9IHN0b3BzICYmIHN0b3BzLmxlbmd0aCA9PT0gMyA/IHN0b3BzIDogWycjNTIyN0ZGJywgJyM3Y2ZmNjcnLCAnIzUyMjdGRiddO1xyXG4gICAgcmV0dXJuIGFycmF5Lm1hcChoZXggPT4ge1xyXG4gICAgICBjb25zdCBjID0gbmV3IFRIUkVFLkNvbG9yKGhleCk7XHJcbiAgICAgIHJldHVybiBuZXcgVEhSRUUuVmVjdG9yMyhjLnIsIGMuZywgYy5iKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0V2ViR0woKTogdm9pZCB7XHJcbiAgICBjb25zdCBjdG4gPSB0aGlzLmNvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgaWYgKCFjdG4pIHJldHVybjtcclxuXHJcbiAgICB0aGlzLnJlbmRlcmVyID0gbmV3IFRIUkVFLldlYkdMUmVuZGVyZXIoe1xyXG4gICAgICBhbHBoYTogdHJ1ZSxcclxuICAgICAgcHJlbXVsdGlwbGllZEFscGhhOiB0cnVlLFxyXG4gICAgICBhbnRpYWxpYXM6IHRydWVcclxuICAgIH0pO1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRDbGVhckNvbG9yKDB4MDAwMDAwLCAwKTtcclxuICAgIHRoaXMucmVuZGVyZXIuZG9tRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAndHJhbnNwYXJlbnQnO1xyXG4gICAgdGhpcy5yZW5kZXJlci5kb21FbGVtZW50LnN0eWxlLndpZHRoID0gJzEwMCUnO1xyXG4gICAgdGhpcy5yZW5kZXJlci5kb21FbGVtZW50LnN0eWxlLmhlaWdodCA9ICcxMDAlJztcclxuICAgIGN0bi5hcHBlbmRDaGlsZCh0aGlzLnJlbmRlcmVyLmRvbUVsZW1lbnQpO1xyXG5cclxuICAgIHRoaXMuc2NlbmUgPSBuZXcgVEhSRUUuU2NlbmUoKTtcclxuICAgIHRoaXMuY2FtZXJhID0gbmV3IFRIUkVFLk9ydGhvZ3JhcGhpY0NhbWVyYSgtMSwgMSwgMSwgLTEsIDAsIDEpO1xyXG5cclxuICAgIGNvbnN0IGdlb21ldHJ5ID0gbmV3IFRIUkVFLlBsYW5lR2VvbWV0cnkoMiwgMik7XHJcblxyXG4gICAgdGhpcy5tYXRlcmlhbCA9IG5ldyBUSFJFRS5SYXdTaGFkZXJNYXRlcmlhbCh7XHJcbiAgICAgIHZlcnRleFNoYWRlcjogVkVSVCxcclxuICAgICAgZnJhZ21lbnRTaGFkZXI6IEZSQUcsXHJcbiAgICAgIHVuaWZvcm1zOiB7XHJcbiAgICAgICAgdVRpbWU6IHsgdmFsdWU6IDAgfSxcclxuICAgICAgICB1QW1wbGl0dWRlOiB7IHZhbHVlOiB0aGlzLm5jQW1wbGl0dWRlID8/IDEuMCB9LFxyXG4gICAgICAgIHVDb2xvclN0b3BzOiB7IHZhbHVlOiB0aGlzLnBhcnNlQ29sb3JTdG9wcyh0aGlzLm5jQ29sb3JTdG9wcykgfSxcclxuICAgICAgICB1UmVzb2x1dGlvbjogeyB2YWx1ZTogbmV3IFRIUkVFLlZlY3RvcjIoY3RuLm9mZnNldFdpZHRoLCBjdG4ub2Zmc2V0SGVpZ2h0KSB9LFxyXG4gICAgICAgIHVCbGVuZDogeyB2YWx1ZTogdGhpcy5uY0JsZW5kID8/IDAuNSB9XHJcbiAgICAgIH0sXHJcbiAgICAgIHRyYW5zcGFyZW50OiB0cnVlLFxyXG4gICAgICBibGVuZGluZzogVEhSRUUuQ3VzdG9tQmxlbmRpbmcsXHJcbiAgICAgIGJsZW5kRXF1YXRpb246IFRIUkVFLkFkZEVxdWF0aW9uLFxyXG4gICAgICBibGVuZFNyYzogVEhSRUUuT25lRmFjdG9yLFxyXG4gICAgICBibGVuZERzdDogVEhSRUUuT25lTWludXNTcmNBbHBoYUZhY3RvclxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5tZXNoID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnksIHRoaXMubWF0ZXJpYWwpO1xyXG4gICAgdGhpcy5zY2VuZS5hZGQodGhpcy5tZXNoKTtcclxuXHJcbiAgICB0aGlzLnJlc2l6ZSgpO1xyXG5cclxuICAgIGNvbnN0IHVwZGF0ZSA9ICh0OiBudW1iZXIpID0+IHtcclxuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQpIHJldHVybjtcclxuICAgICAgdGhpcy5hbmltYXRlSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodXBkYXRlKTtcclxuXHJcbiAgICAgIGNvbnN0IHRpbWVFbGFwc2VkID0gdCAqIDAuMDE7XHJcbiAgICAgIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VUaW1lJ10udmFsdWUgPSB0aW1lRWxhcHNlZCAqICh0aGlzLm5jU3BlZWQgPz8gMS4wKSAqIDAuMTtcclxuXHJcbiAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKHRoaXMuc2NlbmUsIHRoaXMuY2FtZXJhKTtcclxuICAgIH07XHJcbiAgICB0aGlzLmFuaW1hdGVJZCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh1cGRhdGUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNpemUoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuY29udGFpbmVyUmVmIHx8ICF0aGlzLnJlbmRlcmVyIHx8ICF0aGlzLm1hdGVyaWFsKSByZXR1cm47XHJcbiAgICBjb25zdCBjdG4gPSB0aGlzLmNvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3Qgd2lkdGggPSBjdG4ub2Zmc2V0V2lkdGg7XHJcbiAgICBjb25zdCBoZWlnaHQgPSBjdG4ub2Zmc2V0SGVpZ2h0O1xyXG4gICAgdGhpcy5yZW5kZXJlci5zZXRTaXplKHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcclxuICAgIHRoaXMubWF0ZXJpYWwudW5pZm9ybXNbJ3VSZXNvbHV0aW9uJ10udmFsdWUuc2V0KHdpZHRoLCBoZWlnaHQpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjbGVhbnVwKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuYW5pbWF0ZUlkKSB7XHJcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0ZUlkKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnJlbmRlcmVyICYmIHRoaXMuY29udGFpbmVyUmVmKSB7XHJcbiAgICAgIGNvbnN0IGN0biA9IHRoaXMuY29udGFpbmVyUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgIGlmIChjdG4uY29udGFpbnModGhpcy5yZW5kZXJlci5kb21FbGVtZW50KSkge1xyXG4gICAgICAgIGN0bi5yZW1vdmVDaGlsZCh0aGlzLnJlbmRlcmVyLmRvbUVsZW1lbnQpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMucmVuZGVyZXIuZGlzcG9zZSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMubWF0ZXJpYWwpIHtcclxuICAgICAgdGhpcy5tYXRlcmlhbC5kaXNwb3NlKCk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5tZXNoICYmIHRoaXMubWVzaC5nZW9tZXRyeSkge1xyXG4gICAgICB0aGlzLm1lc2guZ2VvbWV0cnkuZGlzcG9zZSgpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2ICNjb250YWluZXIgY2xhc3M9XCJuYy1hdXJvcmEtY2FudmFzLWNvbnRhaW5lclwiPjwvZGl2PlxyXG48ZGl2IGNsYXNzPVwibmMtY29udGVudC13cmFwcGVyXCI+XHJcbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG4iXX0=