UNPKG

webglimpse

Version:

Webglimpse is a data visualization library for the web.

117 lines 17.8 kB
/* * 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 { hasval } from './util/util'; export class Color { constructor(r, g, b, a = 1) { this._r = r; this._g = g; this._b = b; this._a = a; } get r() { return this._r; } get g() { return this._g; } get b() { return this._b; } get a() { return this._a; } get cssString() { return 'rgba(' + Math.round(255 * this._r) + ',' + Math.round(255 * this._g) + ',' + Math.round(255 * this._b) + ',' + this._a + ')'; } get rgbaString() { return '' + Math.round(255 * this._r) + ',' + Math.round(255 * this._g) + ',' + Math.round(255 * this._b) + ',' + Math.round(255 * this._a); } withAlphaTimes(aFactor) { return new Color(this._r, this._g, this._b, aFactor * this._a); } } export function darker(color, factor) { return new Color(color.r * factor, color.g * factor, color.b * factor, color.a); } export function rgba(r, g, b, a) { return new Color(r, g, b, a); } export function rgb(r, g, b) { return new Color(r, g, b, 1); } export function sameColor(c1, c2) { if (c1 === c2) { return true; } if (!hasval(c1) || !hasval(c2)) { return false; } return (c1.r === c2.r && c1.g === c2.g && c1.b === c2.b && c1.a === c2.a); } export function parseRgba(rgbaString) { const tokens = rgbaString.split(',', 4); return new Color(parseInt(tokens[0], 10) / 255, parseInt(tokens[1], 10) / 255, parseInt(tokens[2], 10) / 255, parseInt(tokens[3], 10) / 255); } /** * Creates a Color object based on a CSS color string. Supports the following notations: * - hex * - rgb/rgba * - hsl/hsla * - named colors * Behavior is undefined for strings that are not in one of the listed notations. * * Optional alphaOverride provided for forcing value of rbga alpha. * * Note that different browsers may use different color values for the named colors. * */ export let parseCssColor = (function () { const canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; const g = canvas.getContext('2d', { willReadFrequently: true }); return function (cssColorString, alphaOverride) { g.clearRect(0, 0, 1, 1); g.fillStyle = cssColorString; g.fillRect(0, 0, 1, 1); const rgbaData = g.getImageData(0, 0, 1, 1).data; const R = rgbaData[0] / 255; const G = rgbaData[1] / 255; const B = rgbaData[2] / 255; const A = hasval(alphaOverride) ? alphaOverride : rgbaData[3] / 255; return rgba(R, G, B, A); }; })(); export function gray(brightness) { return new Color(brightness, brightness, brightness, 1); } // XXX: Make final export let black = rgb(0, 0, 0); export let white = rgb(1, 1, 1); export let red = rgb(1, 0, 0); export let green = rgb(0, 1, 0); export let blue = rgb(0, 0, 1); export let cyan = rgb(0, 1, 1); export let magenta = rgb(1, 0, 1); export let yellow = rgb(1, 1, 0); export let periwinkle = rgb(0.561, 0.561, 0.961); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViZ2xpbXBzZS9jb2xvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFckMsTUFBTSxPQUFPLEtBQUs7SUFtQmQsWUFBWSxDQUFTLEVBQUUsQ0FBUyxFQUFFLENBQVMsRUFBRSxJQUFZLENBQUM7UUFDdEQsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDWixJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNaLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ1osSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDaEIsQ0FBQztJQWxCRCxJQUFJLENBQUMsS0FBYSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ25DLElBQUksQ0FBQyxLQUFhLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkMsSUFBSSxDQUFDLEtBQWEsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNuQyxJQUFJLENBQUMsS0FBYSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRW5DLElBQUksU0FBUztRQUNULE9BQU8sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxD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QUFPLElBQUksS0FBSyxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVELENBQUM7QUFHRCxrQkFBa0I7QUFFbEIsTUFBTSxDQUFDLElBQUksS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLE1BQU0sQ0FBQyxJQUFJLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVoQyxNQUFNLENBQUMsSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDOUIsTUFBTSxDQUFDLElBQUksS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLE1BQU0sQ0FBQyxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUUvQixNQUFNLENBQUMsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0IsTUFBTSxDQUFDLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVqQyxNQUFNLENBQUMsSUFBSSxVQUFVLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE1ldHJvbiwgSW5jLlxyXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKlxyXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLFxyXG4gKiBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XHJcbiAqXHJcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xyXG4gKiAgICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuICpcclxuICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxyXG4gKiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXHJcbiAqICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxyXG4gKlxyXG4gKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBjb3B5cmlnaHQgaG9sZGVyIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xyXG4gKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxyXG4gKiAgICBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXHJcbiAqXHJcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORFxyXG4gKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxyXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXHJcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SXHJcbiAqIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xyXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XHJcbiAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTlxyXG4gKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxyXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJU1xyXG4gKiBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cclxuICovXHJcbmltcG9ydCB7IGhhc3ZhbCB9IGZyb20gJy4vdXRpbC91dGlsJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDb2xvciB7XHJcbiAgICBwcml2YXRlIF9yOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIF9nOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIF9iOiBudW1iZXI7XHJcbiAgICBwcml2YXRlIF9hOiBudW1iZXI7XHJcblxyXG4gICAgZ2V0IHIoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3I7IH1cclxuICAgIGdldCBnKCk6IG51bWJlciB7IHJldHVybiB0aGlzLl9nOyB9XHJcbiAgICBnZXQgYigpOiBudW1iZXIgeyByZXR1cm4gdGhpcy5fYjsgfVxyXG4gICAgZ2V0IGEoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX2E7IH1cclxuXHJcbiAgICBnZXQgY3NzU3RyaW5nKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuICdyZ2JhKCcgKyBNYXRoLnJvdW5kKDI1NSAqIHRoaXMuX3IpICsgJywnICsgTWF0aC5yb3VuZCgyNTUgKiB0aGlzLl9nKSArICcsJyArIE1hdGgucm91bmQoMjU1ICogdGhpcy5fYikgKyAnLCcgKyB0aGlzLl9hICsgJyknO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByZ2JhU3RyaW5nKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuICcnICsgTWF0aC5yb3VuZCgyNTUgKiB0aGlzLl9yKSArICcsJyArIE1hdGgucm91bmQoMjU1ICogdGhpcy5fZykgKyAnLCcgKyBNYXRoLnJvdW5kKDI1NSAqIHRoaXMuX2IpICsgJywnICsgTWF0aC5yb3VuZCgyNTUgKiB0aGlzLl9hKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdHJ1Y3RvcihyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyLCBhOiBudW1iZXIgPSAxKSB7XHJcbiAgICAgICAgdGhpcy5fciA9IHI7XHJcbiAgICAgICAgdGhpcy5fZyA9IGc7XHJcbiAgICAgICAgdGhpcy5fYiA9IGI7XHJcbiAgICAgICAgdGhpcy5fYSA9IGE7XHJcbiAgICB9XHJcblxyXG4gICAgd2l0aEFscGhhVGltZXMoYUZhY3RvcjogbnVtYmVyKTogQ29sb3Ige1xyXG4gICAgICAgIHJldHVybiBuZXcgQ29sb3IodGhpcy5fciwgdGhpcy5fZywgdGhpcy5fYiwgYUZhY3RvciAqIHRoaXMuX2EpO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRhcmtlcihjb2xvcjogQ29sb3IsIGZhY3RvcjogbnVtYmVyKTogQ29sb3Ige1xyXG4gICAgcmV0dXJuIG5ldyBDb2xvcihjb2xvci5yICogZmFjdG9yLCBjb2xvci5nICogZmFjdG9yLCBjb2xvci5iICogZmFjdG9yLCBjb2xvci5hKTtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiByZ2JhKHI6IG51bWJlciwgZzogbnVtYmVyLCBiOiBudW1iZXIsIGE6IG51bWJlcik6IENvbG9yIHtcclxuICAgIHJldHVybiBuZXcgQ29sb3IociwgZywgYiwgYSk7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcmdiKHI6IG51bWJlciwgZzogbnVtYmVyLCBiOiBudW1iZXIpOiBDb2xvciB7XHJcbiAgICByZXR1cm4gbmV3IENvbG9yKHIsIGcsIGIsIDEpO1xyXG59XHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNhbWVDb2xvcihjMTogQ29sb3IsIGMyOiBDb2xvcik6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGMxID09PSBjMikge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgaWYgKCFoYXN2YWwoYzEpIHx8ICFoYXN2YWwoYzIpKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIChjMS5yID09PSBjMi5yICYmIGMxLmcgPT09IGMyLmcgJiYgYzEuYiA9PT0gYzIuYiAmJiBjMS5hID09PSBjMi5hKTtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJnYmEocmdiYVN0cmluZzogc3RyaW5nKTogQ29sb3Ige1xyXG4gICAgY29uc3QgdG9rZW5zID0gcmdiYVN0cmluZy5zcGxpdCgnLCcsIDQpO1xyXG4gICAgcmV0dXJuIG5ldyBDb2xvcihwYXJzZUludCh0b2tlbnNbMF0sIDEwKSAvIDI1NSwgcGFyc2VJbnQodG9rZW5zWzFdLCAxMCkgLyAyNTUsIHBhcnNlSW50KHRva2Vuc1syXSwgMTApIC8gMjU1LCBwYXJzZUludCh0b2tlbnNbM10sIDEwKSAvIDI1NSk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIENvbG9yIG9iamVjdCBiYXNlZCBvbiBhIENTUyBjb2xvciBzdHJpbmcuIFN1cHBvcnRzIHRoZSBmb2xsb3dpbmcgbm90YXRpb25zOlxyXG4gKiAgLSBoZXhcclxuICogIC0gcmdiL3JnYmFcclxuICogIC0gaHNsL2hzbGFcclxuICogIC0gbmFtZWQgY29sb3JzXHJcbiAqIEJlaGF2aW9yIGlzIHVuZGVmaW5lZCBmb3Igc3RyaW5ncyB0aGF0IGFyZSBub3QgaW4gb25lIG9mIHRoZSBsaXN0ZWQgbm90YXRpb25zLlxyXG4gKlxyXG4gKiBPcHRpb25hbCBhbHBoYU92ZXJyaWRlIHByb3ZpZGVkIGZvciBmb3JjaW5nIHZhbHVlIG9mIHJiZ2EgYWxwaGEuXHJcbiAqXHJcbiAqIE5vdGUgdGhhdCBkaWZmZXJlbnQgYnJvd3NlcnMgbWF5IHVzZSBkaWZmZXJlbnQgY29sb3IgdmFsdWVzIGZvciB0aGUgbmFtZWQgY29sb3JzLlxyXG4gKlxyXG4gKi9cclxuZXhwb3J0IGxldCBwYXJzZUNzc0NvbG9yID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xyXG4gICAgY2FudmFzLndpZHRoID0gMTtcclxuICAgIGNhbnZhcy5oZWlnaHQgPSAxO1xyXG4gICAgY29uc3QgZyA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHsgd2lsbFJlYWRGcmVxdWVudGx5OiB0cnVlfSk7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGNzc0NvbG9yU3RyaW5nOiBzdHJpbmcsIGFscGhhT3ZlcnJpZGU/OiBudW1iZXIpOiBDb2xvciB7XHJcbiAgICAgICAgZy5jbGVhclJlY3QoMCwgMCwgMSwgMSk7XHJcbiAgICAgICAgZy5maWxsU3R5bGUgPSBjc3NDb2xvclN0cmluZztcclxuICAgICAgICBnLmZpbGxSZWN0KDAsIDAsIDEsIDEpO1xyXG5cclxuICAgICAgICBjb25zdCByZ2JhRGF0YSA9IGcuZ2V0SW1hZ2VEYXRhKDAsIDAsIDEsIDEpLmRhdGE7XHJcbiAgICAgICAgY29uc3QgUiA9IHJnYmFEYXRhWzBdIC8gMjU1O1xyXG4gICAgICAgIGNvbnN0IEcgPSByZ2JhRGF0YVsxXSAvIDI1NTtcclxuICAgICAgICBjb25zdCBCID0gcmdiYURhdGFbMl0gLyAyNTU7XHJcbiAgICAgICAgY29uc3QgQSA9IGhhc3ZhbChhbHBoYU92ZXJyaWRlKSA/IGFscGhhT3ZlcnJpZGUgOiByZ2JhRGF0YVszXSAvIDI1NTtcclxuICAgICAgICByZXR1cm4gcmdiYShSLCBHLCBCLCBBKTtcclxuICAgIH07XHJcbn0pKCk7XHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdyYXkoYnJpZ2h0bmVzczogbnVtYmVyKTogQ29sb3Ige1xyXG4gICAgcmV0dXJuIG5ldyBDb2xvcihicmlnaHRuZXNzLCBicmlnaHRuZXNzLCBicmlnaHRuZXNzLCAxKTtcclxufVxyXG5cclxuXHJcbi8vIFhYWDogTWFrZSBmaW5hbFxyXG5cclxuZXhwb3J0IGxldCBibGFjayA9IHJnYigwLCAwLCAwKTtcclxuZXhwb3J0IGxldCB3aGl0ZSA9IHJnYigxLCAxLCAxKTtcclxuXHJcbmV4cG9ydCBsZXQgcmVkID0gcmdiKDEsIDAsIDApO1xyXG5leHBvcnQgbGV0IGdyZWVuID0gcmdiKDAsIDEsIDApO1xyXG5leHBvcnQgbGV0IGJsdWUgPSByZ2IoMCwgMCwgMSk7XHJcblxyXG5leHBvcnQgbGV0IGN5YW4gPSByZ2IoMCwgMSwgMSk7XHJcbmV4cG9ydCBsZXQgbWFnZW50YSA9IHJnYigxLCAwLCAxKTtcclxuZXhwb3J0IGxldCB5ZWxsb3cgPSByZ2IoMSwgMSwgMCk7XHJcblxyXG5leHBvcnQgbGV0IHBlcml3aW5rbGUgPSByZ2IoMC41NjEsIDAuNTYxLCAwLjk2MSk7XHJcblxyXG5cclxuIl19