webglimpse
Version:
Webglimpse is a data visualization library for the web.
97 lines • 23.2 kB
JavaScript
/*
* Copyright (c) 2014, Metron, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import { concatLines, GL, hasval } from '../util/util';
import { FloatDataTexture2D } from '../texture';
import { Program, UniformMatrix4f, UniformSampler2D, Uniform1f, Attribute } from '../shader';
import { newStaticBuffer } from '../buffer';
import { glOrthoAxis } from '../matrix';
export let heatmap_VERTSHADER = concatLines(' ', ' uniform mat4 u_modelViewMatrix; ', ' attribute vec4 a_vertCoord; ', ' attribute vec2 a_texCoord; ', ' varying vec2 v_texCoord; ', ' ', ' void main( ) { ', ' gl_Position = u_modelViewMatrix * a_vertCoord; ', ' v_texCoord = a_texCoord; ', ' } ', ' ');
export let heatmap_FRAGSHADER = concatLines(' ', ' precision highp float; ', ' uniform sampler2D u_dataTex; ', ' uniform sampler2D u_colorTex; ', ' uniform float u_dataMin; ', ' uniform float u_dataMax; ', ' ', ' varying vec2 v_texCoord; ', ' ', ' void main() ', ' { ', ' float dataVal = texture2D( u_dataTex, v_texCoord ).r; ', ' float normalizedVal = ( dataVal - u_dataMin ) / ( u_dataMax - u_dataMin ); ', ' clamp( normalizedVal, 0.0, 1.0 ); ', ' ', ' vec4 color = texture2D( u_colorTex, vec2( normalizedVal, 0 ) ); ', ' gl_FragColor = color; ', ' gl_FragColor.a = 1.0; ', ' } ');
/**
* Simple heatmap painter which displays a 2d matrix of static data
*/
export function newHeatmapPainter(axis, colorAxis, data, colorTexture, options) {
const blend = (hasval(options) && hasval(options.blend) ? options.blend : false);
// only GL_RGBA is supported with GL_FLOAT texture type in webgl (see texture.ts)
// we we currently need an array 4 times bigger than necessary in order to use FLOATS
// to store the matrix data in a texture
const array = new Float32Array(data.xSize * data.ySize * 4);
for (let x = 0; x < data.xSize; x++) {
for (let y = 0; y < data.ySize; y++) {
const index = x * data.ySize + y;
const value = data.array[index];
array[4 * index] = value;
array[4 * index + 1] = value;
array[4 * index + 2] = value;
array[4 * index + 3] = value;
}
}
data.array = array;
const program = new Program(heatmap_VERTSHADER, heatmap_FRAGSHADER);
const u_modelViewMatrix = new UniformMatrix4f(program, 'u_modelViewMatrix');
const u_dataTexture = new UniformSampler2D(program, 'u_dataTex');
const u_colorTexture = new UniformSampler2D(program, 'u_colorTex');
const u_dataMin = new Uniform1f(program, 'u_dataMin');
const u_dataMax = new Uniform1f(program, 'u_dataMax');
const a_vertCoord = new Attribute(program, 'a_vertCoord');
const a_texCoord = new Attribute(program, 'a_texCoord');
const texture = new FloatDataTexture2D(data.xSize, data.ySize, data.array);
// points in triangle strip
const vertCoordArray = [data.xMin, data.yMax, data.xMax, data.yMax, data.xMin, data.yMin, data.xMax, data.yMin];
const vertCoordFloatArray = new Float32Array(vertCoordArray);
const vertCoordBuffer = newStaticBuffer(vertCoordFloatArray);
// texture coordinates
const texCoordArray = [0, 1, 1, 1, 0, 0, 1, 0];
const texCoordFloatArray = new Float32Array(texCoordArray);
const texCoordBuffer = newStaticBuffer(texCoordFloatArray);
const dim = 2;
const vertexCount = 4;
return function (gl, viewport) {
if (blend) {
gl.blendFuncSeparate(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ONE, GL.ONE_MINUS_SRC_ALPHA);
gl.enable(GL.BLEND);
}
program.use(gl);
u_dataTexture.setDataAndBind(gl, 0, texture);
u_colorTexture.setDataAndBind(gl, 1, colorTexture);
u_modelViewMatrix.setData(gl, glOrthoAxis(axis));
u_dataMin.setData(gl, colorAxis.vMin);
u_dataMax.setData(gl, colorAxis.vMax);
a_vertCoord.setDataAndEnable(gl, vertCoordBuffer, dim, GL.FLOAT);
a_texCoord.setDataAndEnable(gl, texCoordBuffer, dim, GL.FLOAT);
gl.drawArrays(GL.TRIANGLE_STRIP, 0, vertexCount);
a_vertCoord.disable(gl);
a_texCoord.disable(gl);
u_dataTexture.unbind(gl);
u_colorTexture.unbind(gl);
program.endUse(gl);
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhdG1hcF9wYWludGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3dlYmdsaW1wc2UvcGxvdC9oZWF0bWFwX3BhaW50ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E0Qkc7QUFDSCxPQUFPLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdkQsT0FBTyxFQUFXLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXpELE9BQU8sRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDN0YsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU1QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBdUJ4QyxNQUFNLENBQUMsSUFBSSxrQkFBa0IsR0FBRyxXQUFXLENBQ3ZDLDREQUE0RCxFQUM1RCw0REFBNEQsRUFDNUQsNERBQTRELEVBQzVELDREQUE0RCxFQUM1RCw0REFBNEQsRUFDNUQsNERBQTRELEVBQzVELDREQUE0RCxFQUM1RCw0REFBNEQsRUFDNUQsNERBQTRELEVBQzVELDREQUE0RCxFQUM1RCw0REFBNEQsQ0FDL0QsQ0FBQztBQUdGLE1BQU0sQ0FBQyxJQUFJLGtCQUFrQixHQUFHLFdBQVcsQ0FDdkMsbUNBQW1DLEVBQ25DLG1DQUFtQyxFQUNuQyxtQ0FBbUMsRUFDbkMsbUNBQW1DLEVBQ25DLG1DQUFtQyxFQUNuQyxtQ0FBbUMsRUFDbkMsbUNBQW1DLEVBQ25DLG1DQUFtQyxFQUNuQyxxRkFBcUYsRUFDckYscUZBQXFGLEVBQ3JGLHFGQUFxRixFQUNyRixxRkFBcUYsRUFDckYscUZBQXFGLEVBQ3JGLHFGQUFxRixFQUNyRixxRkFBcUYsRUFDckYscUZBQXFGLEVBQ3JGLHFGQUFx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QUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV0QyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFL0QsRUFBRSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUVqRCxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkIsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QixjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzFCLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkIsQ0FBQyxDQUFDO0FBQ04sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNCwgTWV0cm9uLCBJbmMuXHJcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb24sXHJcbiAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcclxuICpcclxuICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXHJcbiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxyXG4gKlxyXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXHJcbiAqICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cclxuICogICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAqXHJcbiAqIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzXHJcbiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0XHJcbiAqICAgIHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCIgQU5EXHJcbiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXHJcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcclxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1JcclxuICogQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXHJcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcclxuICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OXHJcbiAqIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXHJcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTXHJcbiAqIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxyXG4gKi9cclxuaW1wb3J0IHsgY29uY2F0TGluZXMsIEdMLCBoYXN2YWwgfSBmcm9tICcuLi91dGlsL3V0aWwnO1xyXG5pbXBvcnQgeyBBeGlzMkQsIEF4aXMxRCB9IGZyb20gJy4vYXhpcyc7XHJcbmltcG9ydCB7IFRleHR1cmUsIEZsb2F0RGF0YVRleHR1cmUyRCB9IGZyb20gJy4uL3RleHR1cmUnO1xyXG5pbXBvcnQgeyBQYWludGVyIH0gZnJvbSAnLi4vY29yZSc7XHJcbmltcG9ydCB7IFByb2dyYW0sIFVuaWZvcm1NYXRyaXg0ZiwgVW5pZm9ybVNhbXBsZXIyRCwgVW5pZm9ybTFmLCBBdHRyaWJ1dGUgfSBmcm9tICcuLi9zaGFkZXInO1xyXG5pbXBvcnQgeyBuZXdTdGF0aWNCdWZmZXIgfSBmcm9tICcuLi9idWZmZXInO1xyXG5pbXBvcnQgeyBCb3VuZHNVbm1vZGlmaWFibGUgfSBmcm9tICcuLi9ib3VuZHMnO1xyXG5pbXBvcnQgeyBnbE9ydGhvQXhpcyB9IGZyb20gJy4uL21hdHJpeCc7XHJcblxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBIZWF0bWFwUGFpbnRlck9wdGlvbnMge1xyXG4gICAgYmxlbmQ/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEhlYXRNYXBEYXRhIHtcclxuICAgIC8vIG1hdHJpeCBkYXRhIHN0b3JlZCB4LW1ham9yXHJcbiAgICBhcnJheTogRmxvYXQzMkFycmF5O1xyXG5cclxuICAgIC8vIHNpemUgb2YgdGhlIG1hdHJpeFxyXG4gICAgeFNpemU6IG51bWJlcjtcclxuICAgIHlTaXplOiBudW1iZXI7XHJcblxyXG4gICAgLy8gYm91bmRzIG9mIHRoZSBtYXRyaXggaW4gYXhpcyBjb29yZGluYXRlc1xyXG4gICAgeE1pbjogbnVtYmVyO1xyXG4gICAgeE1heDogbnVtYmVyO1xyXG4gICAgeU1pbjogbnVtYmVyO1xyXG4gICAgeU1heDogbnVtYmVyO1xyXG59XHJcblxyXG5cclxuZXhwb3J0IGxldCBoZWF0bWFwX1ZFUlRTSEFERVIgPSBjb25jYXRMaW5lcyhcclxuICAgICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4OyAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgYXR0cmlidXRlIHZlYzQgYV92ZXJ0Q29vcmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgYXR0cmlidXRlIHZlYzIgYV90ZXhDb29yZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgdmFyeWluZyB2ZWMyIHZfdGV4Q29vcmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgdm9pZCBtYWluKCApIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgICAgIGdsX1Bvc2l0aW9uID0gdV9tb2RlbFZpZXdNYXRyaXggKiBhX3ZlcnRDb29yZDsgICAgJyxcclxuICAgICcgICAgICAgIHZfdGV4Q29vcmQgPSBhX3RleENvb3JkOyAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xyXG4pO1xyXG5cclxuXHJcbmV4cG9ydCBsZXQgaGVhdG1hcF9GUkFHU0hBREVSID0gY29uY2F0TGluZXMoXHJcbiAgICAnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIHByZWNpc2lvbiBoaWdocCBmbG9hdDsgICAgICAgICAnLFxyXG4gICAgJyAgdW5pZm9ybSBzYW1wbGVyMkQgdV9kYXRhVGV4OyAgICcsXHJcbiAgICAnICB1bmlmb3JtIHNhbXBsZXIyRCB1X2NvbG9yVGV4OyAgJyxcclxuICAgICcgIHVuaWZvcm0gZmxvYXQgdV9kYXRhTWluOyAgICAgICAnLFxyXG4gICAgJyAgdW5pZm9ybSBmbG9hdCB1X2RhdGFNYXg7ICAgICAgICcsXHJcbiAgICAnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIHZhcnlpbmcgdmVjMiB2X3RleENvb3JkOyAgICAgICAnLFxyXG4gICAgJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIHZvaWQgbWFpbigpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcsXHJcbiAgICAnICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLFxyXG4gICAgJyAgICAgZmxvYXQgZGF0YVZhbCA9IHRleHR1cmUyRCggdV9kYXRhVGV4LCB2X3RleENvb3JkICkucjsgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgIGZsb2F0IG5vcm1hbGl6ZWRWYWwgPSAoIGRhdGFWYWwgLSB1X2RhdGFNaW4gKSAvICggdV9kYXRhTWF4IC0gdV9kYXRhTWluICk7ICAgICcsXHJcbiAgICAnICAgICBjbGFtcCggbm9ybWFsaXplZFZhbCwgMC4wLCAxLjAgKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLFxyXG4gICAgJyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgICAgIHZlYzQgY29sb3IgPSB0ZXh0dXJlMkQoIHVfY29sb3JUZXgsIHZlYzIoIG5vcm1hbGl6ZWRWYWwsIDAgKSApOyAgICAgICAgICAgICAgICcsXHJcbiAgICAnICAgICBnbF9GcmFnQ29sb3IgPSBjb2xvcjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnLFxyXG4gICAgJyAgICAgZ2xfRnJhZ0NvbG9yLmEgPSAxLjA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyxcclxuICAgICcgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcclxuKTtcclxuXHJcbi8qKlxyXG4gKiBTaW1wbGUgaGVhdG1hcCBwYWludGVyIHdoaWNoIGRpc3BsYXlzIGEgMmQgbWF0cml4IG9mIHN0YXRpYyBkYXRhXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbmV3SGVhdG1hcFBhaW50ZXIoYXhpczogQXhpczJELCBjb2xvckF4aXM6IEF4aXMxRCwgZGF0YTogSGVhdE1hcERhdGEsIGNvbG9yVGV4dHVyZTogVGV4dHVyZSwgb3B0aW9ucz86IEhlYXRtYXBQYWludGVyT3B0aW9ucyk6IFBhaW50ZXIge1xyXG5cclxuICAgIGNvbnN0IGJsZW5kID0gKGhhc3ZhbChvcHRpb25zKSAmJiBoYXN2YWwob3B0aW9ucy5ibGVuZCkgPyBvcHRpb25zLmJsZW5kIDogZmFsc2UpO1xyXG5cclxuICAgIC8vIG9ubHkgR0xfUkdCQSBpcyBzdXBwb3J0ZWQgd2l0aCBHTF9GTE9BVCB0ZXh0dXJlIHR5cGUgaW4gd2ViZ2wgKHNlZSB0ZXh0dXJlLnRzKVxyXG4gICAgLy8gd2Ugd2UgY3VycmVudGx5IG5lZWQgYW4gYXJyYXkgNCB0aW1lcyBiaWdnZXIgdGhhbiBuZWNlc3NhcnkgaW4gb3JkZXIgdG8gdXNlIEZMT0FUU1xyXG4gICAgLy8gdG8gc3RvcmUgdGhlIG1hdHJpeCBkYXRhIGluIGEgdGV4dHVyZVxyXG4gICAgY29uc3QgYXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGRhdGEueFNpemUgKiBkYXRhLnlTaXplICogNCk7XHJcbiAgICBmb3IgKGxldCB4ID0gMDsgeCA8IGRhdGEueFNpemU7IHgrKykge1xyXG4gICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgZGF0YS55U2l6ZTsgeSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0geCAqIGRhdGEueVNpemUgKyB5O1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGRhdGEuYXJyYXlbaW5kZXhdO1xyXG5cclxuICAgICAgICAgICAgYXJyYXlbNCAqIGluZGV4XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICBhcnJheVs0ICogaW5kZXggKyAxXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICBhcnJheVs0ICogaW5kZXggKyAyXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICBhcnJheVs0ICogaW5kZXggKyAzXSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGRhdGEuYXJyYXkgPSBhcnJheTtcclxuXHJcbiAgICBjb25zdCBwcm9ncmFtID0gbmV3IFByb2dyYW0oaGVhdG1hcF9WRVJUU0hBREVSLCBoZWF0bWFwX0ZSQUdTSEFERVIpO1xyXG4gICAgY29uc3QgdV9tb2RlbFZpZXdNYXRyaXggPSBuZXcgVW5pZm9ybU1hdHJpeDRmKHByb2dyYW0sICd1X21vZGVsVmlld01hdHJpeCcpO1xyXG4gICAgY29uc3QgdV9kYXRhVGV4dHVyZSA9IG5ldyBVbmlmb3JtU2FtcGxlcjJEKHByb2dyYW0sICd1X2RhdGFUZXgnKTtcclxuICAgIGNvbnN0IHVfY29sb3JUZXh0dXJlID0gbmV3IFVuaWZvcm1TYW1wbGVyMkQocHJvZ3JhbSwgJ3VfY29sb3JUZXgnKTtcclxuICAgIGNvbnN0IHVfZGF0YU1pbiA9IG5ldyBVbmlmb3JtMWYocHJvZ3JhbSwgJ3VfZGF0YU1pbicpO1xyXG4gICAgY29uc3QgdV9kYXRhTWF4ID0gbmV3IFVuaWZvcm0xZihwcm9ncmFtLCAndV9kYXRhTWF4Jyk7XHJcbiAgICBjb25zdCBhX3ZlcnRDb29yZCA9IG5ldyBBdHRyaWJ1dGUocHJvZ3JhbSwgJ2FfdmVydENvb3JkJyk7XHJcbiAgICBjb25zdCBhX3RleENvb3JkID0gbmV3IEF0dHJpYnV0ZShwcm9ncmFtLCAnYV90ZXhDb29yZCcpO1xyXG5cclxuICAgIGNvbnN0IHRleHR1cmUgPSBuZXcgRmxvYXREYXRhVGV4dHVyZTJEKGRhdGEueFNpemUsIGRhdGEueVNpemUsIGRhdGEuYXJyYXkpO1xyXG5cclxuICAgIC8vIHBvaW50cyBpbiB0cmlhbmdsZSBzdHJpcFxyXG4gICAgY29uc3QgdmVydENvb3JkQXJyYXkgPSBbZGF0YS54TWluLCBkYXRhLnlNYXgsIGRhdGEueE1heCwgZGF0YS55TWF4LCBkYXRhLnhNaW4sIGRhdGEueU1pbiwgZGF0YS54TWF4LCBkYXRhLnlNaW5dO1xyXG4gICAgY29uc3QgdmVydENvb3JkRmxvYXRBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkodmVydENvb3JkQXJyYXkpO1xyXG4gICAgY29uc3QgdmVydENvb3JkQnVmZmVyID0gbmV3U3RhdGljQnVmZmVyKHZlcnRDb29yZEZsb2F0QXJyYXkpO1xyXG5cclxuICAgIC8vIHRleHR1cmUgY29vcmRpbmF0ZXNcclxuICAgIGNvbnN0IHRleENvb3JkQXJyYXkgPSBbMCwgMSwgMSwgMSwgMCwgMCwgMSwgMF07XHJcbiAgICBjb25zdCB0ZXhDb29yZEZsb2F0QXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KHRleENvb3JkQXJyYXkpO1xyXG4gICAgY29uc3QgdGV4Q29vcmRCdWZmZXIgPSBuZXdTdGF0aWNCdWZmZXIodGV4Q29vcmRGbG9hdEFycmF5KTtcclxuXHJcbiAgICBjb25zdCBkaW0gPSAyO1xyXG4gICAgY29uc3QgdmVydGV4Q291bnQgPSA0O1xyXG5cclxuICAgIHJldHVybiBmdW5jdGlvbiAoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdmlld3BvcnQ6IEJvdW5kc1VubW9kaWZpYWJsZSkge1xyXG5cclxuICAgICAgICBpZiAoYmxlbmQpIHtcclxuICAgICAgICAgICAgZ2wuYmxlbmRGdW5jU2VwYXJhdGUoR0wuU1JDX0FMUEhBLCBHTC5PTkVfTUlOVVNfU1JDX0FMUEhBLCBHTC5PTkUsIEdMLk9ORV9NSU5VU19TUkNfQUxQSEEpO1xyXG4gICAgICAgICAgICBnbC5lbmFibGUoR0wuQkxFTkQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcHJvZ3JhbS51c2UoZ2wpO1xyXG4gICAgICAgIHVfZGF0YVRleHR1cmUuc2V0RGF0YUFuZEJpbmQoZ2wsIDAsIHRleHR1cmUpO1xyXG4gICAgICAgIHVfY29sb3JUZXh0dXJlLnNldERhdGFBbmRCaW5kKGdsLCAxLCBjb2xvclRleHR1cmUpO1xyXG4gICAgICAgIHVfbW9kZWxWaWV3TWF0cml4LnNldERhdGEoZ2wsIGdsT3J0aG9BeGlzKGF4aXMpKTtcclxuXHJcbiAgICAgICAgdV9kYXRhTWluLnNldERhdGEoZ2wsIGNvbG9yQXhpcy52TWluKTtcclxuICAgICAgICB1X2RhdGFNYXguc2V0RGF0YShnbCwgY29sb3JBeGlzLnZNYXgpO1xyXG5cclxuICAgICAgICBhX3ZlcnRDb29yZC5zZXREYXRhQW5kRW5hYmxlKGdsLCB2ZXJ0Q29vcmRCdWZmZXIsIGRpbSwgR0wuRkxPQVQpO1xyXG4gICAgICAgIGFfdGV4Q29vcmQuc2V0RGF0YUFuZEVuYWJsZShnbCwgdGV4Q29vcmRCdWZmZXIsIGRpbSwgR0wuRkxPQVQpO1xyXG5cclxuICAgICAgICBnbC5kcmF3QXJyYXlzKEdMLlRSSUFOR0xFX1NUUklQLCAwLCB2ZXJ0ZXhDb3VudCk7XHJcblxyXG4gICAgICAgIGFfdmVydENvb3JkLmRpc2FibGUoZ2wpO1xyXG4gICAgICAgIGFfdGV4Q29vcmQuZGlzYWJsZShnbCk7XHJcbiAgICAgICAgdV9kYXRhVGV4dHVyZS51bmJpbmQoZ2wpO1xyXG4gICAgICAgIHVfY29sb3JUZXh0dXJlLnVuYmluZChnbCk7XHJcbiAgICAgICAgcHJvZ3JhbS5lbmRVc2UoZ2wpO1xyXG4gICAgfTtcclxufVxyXG4iXX0=