UNPKG

webglimpse

Version:

Webglimpse is a data visualization library for the web.

144 lines 19.2 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 { sameColor } from './color'; import { createTextTextureFactory, getTextWidth } from './text'; import { TextureRenderer } from './texture'; import { GL, hasval } from './util/util'; export class Label { constructor(text, font, fgColor, bgColor) { this._font = font; this._text = text; this._fgColor = fgColor; this._bgColor = bgColor; } get font() { return this._font; } set font(font) { if (this._font !== font) { this._font = font; this._textureFactory = null; if (this._texture) { this._texture.dispose(); this._texture = null; } } } // retained for backwards compatibility, should use fgColor get color() { return this._fgColor; } // retained for backwards compatibility, should use fgColor set color(fgColor) { if (!sameColor(this._fgColor, fgColor)) { this._fgColor = fgColor; if (this._texture) { this._texture.dispose(); this._texture = null; } } } get fgColor() { return this._fgColor; } set fgColor(fgColor) { if (!sameColor(this._fgColor, fgColor)) { this._fgColor = fgColor; if (this._texture) { this._texture.dispose(); this._texture = null; } } } get bgColor() { return this._bgColor; } set bgColor(bgColor) { if (!sameColor(this._bgColor, bgColor)) { this._bgColor = bgColor; } } get text() { return this._text; } set text(text) { if (this._text !== text) { this._text = text; if (this._texture) { this._texture.dispose(); this._texture = null; } } } get texture() { if (!this._textureFactory) { this._textureFactory = (this._font ? createTextTextureFactory(this._font) : null); } if (!this._texture) { this._texture = (this._fgColor && this._text ? this._textureFactory(this._fgColor, this._text) : null); } return this._texture; } } export function fitToLabel(label) { return function (parentPrefSize) { const texture = label.texture; parentPrefSize.w = (texture ? texture.w : 0); parentPrefSize.h = (texture ? texture.h : 0); }; } export function newLabelPainter(label, xFrac, yFrac, xAnchor, yAnchor, rotation_CCWRAD, truncateLabel) { const textureRenderer = new TextureRenderer(); return function (gl, viewport) { if (hasval(label.bgColor)) { gl.clearColor(label.bgColor.r, label.bgColor.g, label.bgColor.b, label.bgColor.a); gl.clear(GL.COLOR_BUFFER_BIT); } let labelText = label.text; if (truncateLabel) { const xRight = viewport.w - 2 / viewport.w; while (labelText && labelText !== '...') { if (getTextWidth(label.font, labelText) > xRight) { labelText = labelText.substring(0, labelText.length - 4).concat('...'); } else { break; } } } label.text = labelText; if (label.texture) { textureRenderer.begin(gl, viewport); textureRenderer.draw(gl, label.texture, xFrac, yFrac, { xAnchor: xAnchor, yAnchor: label.texture.yAnchor(yAnchor), rotation_CCWRAD: rotation_CCWRAD }); textureRenderer.end(gl); } }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFiZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2ViZ2xpbXBzZS9sYWJlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBUSxTQUFTLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDekMsT0FBTyxFQUFvQyx3QkFBd0IsRUFBRSxZQUFZLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFFakcsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUMxQyxPQUFPLEVBQUMsRUFBRSxFQUFFLE1BQU0sRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUd2QyxNQUFNLE9BQU8sS0FBSztJQVFkLFlBQVksSUFBYSxFQUFFLElBQWEsRUFBRSxPQUFlLEVBQUUsT0FBZTtRQUN0RSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ0osT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxJQUFZO1FBQ2pCLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7WUFDckIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDbEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7WUFDNUIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO2FBQ3hCO1NBQ0o7SUFDTCxDQUFDO0lBRUQsMkRBQTJEO0lB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QUFDO1FBQ3ZCLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNmLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3BDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZKLGVBQWUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDM0I7SUFDTCxDQUFDLENBQUM7QUFDTixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQ29weXJpZ2h0IChjKSAyMDE0LCBNZXRyb24sIEluYy5cclxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuICpcclxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbixcclxuICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gKlxyXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcclxuICogICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXHJcbiAqXHJcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcclxuICogICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxyXG4gKiAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cclxuICpcclxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcclxuICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcclxuICogICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxyXG4gKlxyXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkRcclxuICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcclxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxyXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUlxyXG4gKiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcclxuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xyXG4gKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT05cclxuICogQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcclxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVNcclxuICogU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXHJcbiAqL1xyXG5pbXBvcnQge0NvbG9yLCBzYW1lQ29sb3J9IGZyb20gJy4vY29sb3InO1xyXG5pbXBvcnQge1RleHRUZXh0dXJlRmFjdG9yeSwgVGV4dFRleHR1cmUyRCwgY3JlYXRlVGV4dFRleHR1cmVGYWN0b3J5LCBnZXRUZXh0V2lkdGh9IGZyb20gJy4vdGV4dCc7XHJcbmltcG9ydCB7U2l6ZSwgQm91bmRzVW5tb2RpZmlhYmxlfSBmcm9tICcuL2JvdW5kcyc7XHJcbmltcG9ydCB7VGV4dHVyZVJlbmRlcmVyfSBmcm9tICcuL3RleHR1cmUnO1xyXG5pbXBvcnQge0dMLCBoYXN2YWx9IGZyb20gJy4vdXRpbC91dGlsJztcclxuaW1wb3J0IHtMYXlvdXRQaGFzZTF9IGZyb20gJy4vY29yZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgTGFiZWwge1xyXG4gICAgcHJpdmF0ZSBfZm9udDogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBfZmdDb2xvcjogQ29sb3I7XHJcbiAgICBwcml2YXRlIF9iZ0NvbG9yOiBDb2xvcjtcclxuICAgIHByaXZhdGUgX3RleHQ6IHN0cmluZztcclxuICAgIHByaXZhdGUgX3RleHR1cmVGYWN0b3J5OiBUZXh0VGV4dHVyZUZhY3Rvcnk7XHJcbiAgICBwcml2YXRlIF90ZXh0dXJlOiBUZXh0VGV4dHVyZTJEO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHRleHQ/OiBzdHJpbmcsIGZvbnQ/OiBzdHJpbmcsIGZnQ29sb3I/OiBDb2xvciwgYmdDb2xvcj86IENvbG9yKSB7XHJcbiAgICAgICAgdGhpcy5fZm9udCA9IGZvbnQ7XHJcbiAgICAgICAgdGhpcy5fdGV4dCA9IHRleHQ7XHJcbiAgICAgICAgdGhpcy5fZmdDb2xvciA9IGZnQ29sb3I7XHJcbiAgICAgICAgdGhpcy5fYmdDb2xvciA9IGJnQ29sb3I7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGZvbnQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZm9udDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgZm9udChmb250OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodGhpcy5fZm9udCAhPT0gZm9udCkge1xyXG4gICAgICAgICAgICB0aGlzLl9mb250ID0gZm9udDtcclxuICAgICAgICAgICAgdGhpcy5fdGV4dHVyZUZhY3RvcnkgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fdGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyByZXRhaW5lZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIHNob3VsZCB1c2UgZmdDb2xvclxyXG4gICAgZ2V0IGNvbG9yKCk6IENvbG9yIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmdDb2xvcjtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZXRhaW5lZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIHNob3VsZCB1c2UgZmdDb2xvclxyXG4gICAgc2V0IGNvbG9yKGZnQ29sb3I6IENvbG9yKSB7XHJcbiAgICAgICAgaWYgKCFzYW1lQ29sb3IodGhpcy5fZmdDb2xvciwgZmdDb2xvcikpIHtcclxuICAgICAgICAgICAgdGhpcy5fZmdDb2xvciA9IGZnQ29sb3I7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl90ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RleHR1cmUgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBmZ0NvbG9yKCk6IENvbG9yIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmdDb2xvcjtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgZmdDb2xvcihmZ0NvbG9yOiBDb2xvcikge1xyXG4gICAgICAgIGlmICghc2FtZUNvbG9yKHRoaXMuX2ZnQ29sb3IsIGZnQ29sb3IpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZnQ29sb3IgPSBmZ0NvbG9yO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fdGV4dHVyZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXh0dXJlID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgYmdDb2xvcigpOiBDb2xvciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JnQ29sb3I7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IGJnQ29sb3IoYmdDb2xvcjogQ29sb3IpIHtcclxuICAgICAgICBpZiAoIXNhbWVDb2xvcih0aGlzLl9iZ0NvbG9yLCBiZ0NvbG9yKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9iZ0NvbG9yID0gYmdDb2xvcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRleHQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdGV4dDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgdGV4dCh0ZXh0OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodGhpcy5fdGV4dCAhPT0gdGV4dCkge1xyXG4gICAgICAgICAgICB0aGlzLl90ZXh0ID0gdGV4dDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3RleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RleHR1cmUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdGV4dHVyZSA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRleHR1cmUoKTogVGV4dFRleHR1cmUyRCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl90ZXh0dXJlRmFjdG9yeSkge1xyXG4gICAgICAgICAgICB0aGlzLl90ZXh0dXJlRmFjdG9yeSA9ICh0aGlzLl9mb250ID8gY3JlYXRlVGV4dFRleHR1cmVGYWN0b3J5KHRoaXMuX2ZvbnQpIDogbnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5fdGV4dHVyZSkge1xyXG4gICAgICAgICAgICB0aGlzLl90ZXh0dXJlID0gKHRoaXMuX2ZnQ29sb3IgJiYgdGhpcy5fdGV4dCA/IHRoaXMuX3RleHR1cmVGYWN0b3J5KHRoaXMuX2ZnQ29sb3IsIHRoaXMuX3RleHQpIDogbnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLl90ZXh0dXJlO1xyXG4gICAgfVxyXG5cclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBmaXRUb0xhYmVsKGxhYmVsOiBMYWJlbCk6IExheW91dFBoYXNlMSB7XHJcbiAgICByZXR1cm4gPExheW91dFBoYXNlMT5mdW5jdGlvbiAocGFyZW50UHJlZlNpemU6IFNpemUpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCB0ZXh0dXJlID0gbGFiZWwudGV4dHVyZTtcclxuICAgICAgICBwYXJlbnRQcmVmU2l6ZS53ID0gKHRleHR1cmUgPyB0ZXh0dXJlLncgOiAwKTtcclxuICAgICAgICBwYXJlbnRQcmVmU2l6ZS5oID0gKHRleHR1cmUgPyB0ZXh0dXJlLmggOiAwKTtcclxuICAgIH07XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3TGFiZWxQYWludGVyKGxhYmVsOiBMYWJlbCwgeEZyYWM6IG51bWJlciwgeUZyYWM6IG51bWJlciwgeEFuY2hvcj86IG51bWJlciwgeUFuY2hvcj86IG51bWJlciwgcm90YXRpb25fQ0NXUkFEPzogbnVtYmVyLCB0cnVuY2F0ZUxhYmVsPzogYm9vbGVhbikge1xyXG4gICAgY29uc3QgdGV4dHVyZVJlbmRlcmVyID0gbmV3IFRleHR1cmVSZW5kZXJlcigpO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0LCB2aWV3cG9ydDogQm91bmRzVW5tb2RpZmlhYmxlKSB7XHJcblxyXG4gICAgICAgIGlmIChoYXN2YWwobGFiZWwuYmdDb2xvcikpIHtcclxuICAgICAgICAgICAgZ2wuY2xlYXJDb2xvcihsYWJlbC5iZ0NvbG9yLnIsIGxhYmVsLmJnQ29sb3IuZywgbGFiZWwuYmdDb2xvci5iLCBsYWJlbC5iZ0NvbG9yLmEpO1xyXG4gICAgICAgICAgICBnbC5jbGVhcihHTC5DT0xPUl9CVUZGRVJfQklUKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBsYWJlbFRleHQgPSBsYWJlbC50ZXh0O1xyXG4gICAgICAgIGlmICh0cnVuY2F0ZUxhYmVsKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHhSaWdodCA9IHZpZXdwb3J0LncgLSAyIC8gdmlld3BvcnQudztcclxuICAgICAgICAgICAgd2hpbGUgKGxhYmVsVGV4dCAmJiBsYWJlbFRleHQgIT09ICcuLi4nKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ2V0VGV4dFdpZHRoKGxhYmVsLmZvbnQsIGxhYmVsVGV4dCkgPiB4UmlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBsYWJlbFRleHQgPSBsYWJlbFRleHQuc3Vic3RyaW5nKDAsIGxhYmVsVGV4dC5sZW5ndGggLSA0KS5jb25jYXQoJy4uLicpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGFiZWwudGV4dCA9IGxhYmVsVGV4dDtcclxuICAgICAgICBpZiAobGFiZWwudGV4dHVyZSkge1xyXG4gICAgICAgICAgICB0ZXh0dXJlUmVuZGVyZXIuYmVnaW4oZ2wsIHZpZXdwb3J0KTtcclxuICAgICAgICAgICAgdGV4dHVyZVJlbmRlcmVyLmRyYXcoZ2wsIGxhYmVsLnRleHR1cmUsIHhGcmFjLCB5RnJhYywgeyB4QW5jaG9yOiB4QW5jaG9yLCB5QW5jaG9yOiBsYWJlbC50ZXh0dXJlLnlBbmNob3IoeUFuY2hvciksIHJvdGF0aW9uX0NDV1JBRDogcm90YXRpb25fQ0NXUkFEIH0pO1xyXG4gICAgICAgICAgICB0ZXh0dXJlUmVuZGVyZXIuZW5kKGdsKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5cclxuXHJcbiJdfQ==