UNPKG

@esotericsoftware/spine-webgl

Version:
165 lines 25.1 kB
/****************************************************************************** * Spine Runtimes License Agreement * Last updated April 5, 2025. Replaces all prior versions. * * Copyright (c) 2013-2025, Esoteric Software LLC * * Integration of the Spine Runtimes into software or otherwise creating * derivative works of the Spine Runtimes is permitted under the terms and * conditions of Section 2 of the Spine Editor License Agreement: * http://esotericsoftware.com/spine-editor-license * * Otherwise, it is permitted to integrate the Spine Runtimes into software * or otherwise create derivative works of the Spine Runtimes (collectively, * "Products"), provided that each user of the Products must obtain their own * Spine Editor license and redistribution of the Products in any form must * include this license and copyright notice. * * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) 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 * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ import { Mesh, Position2Attribute, ColorAttribute, TexCoordAttribute, Color2Attribute } from "./Mesh.js"; import { ManagedWebGLRenderingContext } from "./WebGL.js"; const GL_ONE = 1; const GL_ONE_MINUS_SRC_COLOR = 0x0301; const GL_SRC_ALPHA = 0x0302; const GL_ONE_MINUS_SRC_ALPHA = 0x0303; const GL_ONE_MINUS_DST_ALPHA = 0x0305; const GL_DST_COLOR = 0x0306; export class PolygonBatcher { static disableCulling = false; context; drawCalls = 0; static globalDrawCalls = 0; isDrawing = false; mesh; shader = null; lastTexture = null; verticesLength = 0; indicesLength = 0; srcColorBlend; srcAlphaBlend; dstBlend; cullWasEnabled = false; constructor(context, twoColorTint = true, maxVertices = 10920) { if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); let attributes = twoColorTint ? [new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute(), new Color2Attribute()] : [new Position2Attribute(), new ColorAttribute(), new TexCoordAttribute()]; this.mesh = new Mesh(context, attributes, maxVertices, maxVertices * 3); let gl = this.context.gl; this.srcColorBlend = gl.SRC_ALPHA; this.srcAlphaBlend = gl.ONE; this.dstBlend = gl.ONE_MINUS_SRC_ALPHA; } begin(shader) { if (this.isDrawing) throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()"); this.drawCalls = 0; this.shader = shader; this.lastTexture = null; this.isDrawing = true; let gl = this.context.gl; gl.enable(gl.BLEND); gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend); if (PolygonBatcher.disableCulling) { this.cullWasEnabled = gl.isEnabled(gl.CULL_FACE); if (this.cullWasEnabled) gl.disable(gl.CULL_FACE); } } static blendModesGL = [ { srcRgb: GL_SRC_ALPHA, srcRgbPma: GL_ONE, dstRgb: GL_ONE_MINUS_SRC_ALPHA, srcAlpha: GL_ONE }, { srcRgb: GL_SRC_ALPHA, srcRgbPma: GL_ONE, dstRgb: GL_ONE, srcAlpha: GL_ONE }, { srcRgb: GL_DST_COLOR, srcRgbPma: GL_DST_COLOR, dstRgb: GL_ONE_MINUS_SRC_ALPHA, srcAlpha: GL_ONE }, { srcRgb: GL_ONE, srcRgbPma: GL_ONE, dstRgb: GL_ONE_MINUS_SRC_COLOR, srcAlpha: GL_ONE } ]; setBlendMode(blendMode, premultipliedAlpha) { const blendModeGL = PolygonBatcher.blendModesGL[blendMode]; const srcColorBlend = premultipliedAlpha ? blendModeGL.srcRgbPma : blendModeGL.srcRgb; const srcAlphaBlend = blendModeGL.srcAlpha; const dstBlend = blendModeGL.dstRgb; if (this.srcColorBlend == srcColorBlend && this.srcAlphaBlend == srcAlphaBlend && this.dstBlend == dstBlend) return; this.srcColorBlend = srcColorBlend; this.srcAlphaBlend = srcAlphaBlend; this.dstBlend = dstBlend; if (this.isDrawing) { this.flush(); } let gl = this.context.gl; gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend); } draw(texture, vertices, indices) { if (texture != this.lastTexture) { this.flush(); this.lastTexture = texture; } else if (this.verticesLength + vertices.length > this.mesh.getVertices().length || this.indicesLength + indices.length > this.mesh.getIndices().length) { this.flush(); } let indexStart = this.mesh.numVertices(); this.mesh.getVertices().set(vertices, this.verticesLength); this.verticesLength += vertices.length; this.mesh.setVerticesLength(this.verticesLength); let indicesArray = this.mesh.getIndices(); for (let i = this.indicesLength, j = 0; j < indices.length; i++, j++) indicesArray[i] = indices[j] + indexStart; this.indicesLength += indices.length; this.mesh.setIndicesLength(this.indicesLength); } flush() { if (this.verticesLength == 0) return; if (!this.lastTexture) throw new Error("No texture set."); if (!this.shader) throw new Error("No shader set."); this.lastTexture.bind(); this.mesh.draw(this.shader, this.context.gl.TRIANGLES); this.verticesLength = 0; this.indicesLength = 0; this.mesh.setVerticesLength(0); this.mesh.setIndicesLength(0); this.drawCalls++; PolygonBatcher.globalDrawCalls++; } end() { if (!this.isDrawing) throw new Error("PolygonBatch is not drawing. Call PolygonBatch.begin() before calling PolygonBatch.end()"); if (this.verticesLength > 0 || this.indicesLength > 0) this.flush(); this.shader = null; this.lastTexture = null; this.isDrawing = false; let gl = this.context.gl; gl.disable(gl.BLEND); if (PolygonBatcher.disableCulling) { if (this.cullWasEnabled) gl.enable(gl.CULL_FACE); } } getDrawCalls() { return this.drawCalls; } static getAndResetGlobalDrawCalls() { let result = PolygonBatcher.globalDrawCalls; PolygonBatcher.globalDrawCalls = 0; return result; } dispose() { this.mesh.dispose(); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9seWdvbkJhdGNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUG9seWdvbkJhdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSS9FLE9BQU8sRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUV6RyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFMUQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDO0FBQ3RDLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQztBQUM1QixNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQztBQUN0QyxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQztBQUN0QyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUM7QUFFNUIsTUFBTSxPQUFPLGNBQWM7SUFDbkIsTUFBTSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFFN0IsT0FBTyxDQUErQjtJQUN0QyxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsTUFBTSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFDbkMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNWLElBQUksQ0FBTztJQUNYLE1BQU0sR0FBa0IsSUFBSSxDQUFDO0lBQzdCLFdBQVcsR0FBcUIsSUFBSSxDQUFDO0lBQ3JDLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDbkIsYUFBYSxHQUFHLENBQUMsQ0FBQztJQUNsQixhQUFhLENBQVM7SUFDdEIsYUFBYSxDQUFTO0lBQ3RCLFFBQVEsQ0FBUztJQUNqQixjQUFjLEdBQUcsS0FBSyxDQUFDO0lBRS9CLFlBQWEsT0FBNkQsRUFBRSxlQUF3QixJQUFJLEVBQUUsY0FBc0IsS0FBSztRQUNwSSxJQUFJLFdBQVcsR0FB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QyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xELENBQUM7SUFDRixDQUFDO0lBRUQsWUFBWTtRQUNYLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN2QixDQUFDO0lBRUQsTUFBTSxDQUFDLDBCQUEwQjtRQUNoQyxJQUFJLE1BQU0sR0FBRyxjQUFjLENBQUMsZUFBZSxDQUFDO1FBQzVDLGNBQWMsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLE9BQU8sTUFBTSxDQUFDO0lBQ2YsQ0FBQztJQUVELE9BQU87UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IEJsZW5kTW9kZSwgRGlzcG9zYWJsZSB9IGZyb20gXCJAZXNvdGVyaWNzb2Z0d2FyZS9zcGluZS1jb3JlXCI7XG5pbXBvcnQgeyBHTFRleHR1cmUgfSBmcm9tIFwiLi9HTFRleHR1cmUuanNcIjtcbmltcG9ydCB7IE1lc2gsIFBvc2l0aW9uMkF0dHJpYnV0ZSwgQ29sb3JBdHRyaWJ1dGUsIFRleENvb3JkQXR0cmlidXRlLCBDb2xvcjJBdHRyaWJ1dGUgfSBmcm9tIFwiLi9NZXNoLmpzXCI7XG5pbXBvcnQgeyBTaGFkZXIgfSBmcm9tIFwiLi9TaGFkZXIuanNcIjtcbmltcG9ydCB7IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQgfSBmcm9tIFwiLi9XZWJHTC5qc1wiO1xuXG5jb25zdCBHTF9PTkUgPSAxO1xuY29uc3QgR0xfT05FX01JTlVTX1NSQ19DT0xPUiA9IDB4MDMwMTtcbmNvbnN0IEdMX1NSQ19BTFBIQSA9IDB4MDMwMjtcbmNvbnN0IEdMX09ORV9NSU5VU19TUkNfQUxQSEEgPSAweDAzMDM7XG5jb25zdCBHTF9PTkVfTUlOVVNfRFNUX0FMUEhBID0gMHgwMzA1O1xuY29uc3QgR0xfRFNUX0NPTE9SID0gMHgwMzA2O1xuXG5leHBvcnQgY2xhc3MgUG9seWdvbkJhdGNoZXIgaW1wbGVtZW50cyBEaXNwb3NhYmxlIHtcblx0cHVibGljIHN0YXRpYyBkaXNhYmxlQ3VsbGluZyA9IGZhbHNlO1xuXG5cdHByaXZhdGUgY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcblx0cHJpdmF0ZSBkcmF3Q2FsbHMgPSAwO1xuXHRwcml2YXRlIHN0YXRpYyBnbG9iYWxEcmF3Q2FsbHMgPSAwO1xuXHRpc0RyYXdpbmcgPSBmYWxzZTtcblx0cHJpdmF0ZSBtZXNoOiBNZXNoO1xuXHRwcml2YXRlIHNoYWRlcjogU2hhZGVyIHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgbGFzdFRleHR1cmU6IEdMVGV4dHVyZSB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIHZlcnRpY2VzTGVuZ3RoID0gMDtcblx0cHJpdmF0ZSBpbmRpY2VzTGVuZ3RoID0gMDtcblx0cHJpdmF0ZSBzcmNDb2xvckJsZW5kOiBudW1iZXI7XG5cdHByaXZhdGUgc3JjQWxwaGFCbGVuZDogbnVtYmVyO1xuXHRwcml2YXRlIGRzdEJsZW5kOiBudW1iZXI7XG5cdHByaXZhdGUgY3VsbFdhc0VuYWJsZWQgPSBmYWxzZTtcblxuXHRjb25zdHJ1Y3RvciAoY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dCB8IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdHdvQ29sb3JUaW50OiBib29sZWFuID0gdHJ1ZSwgbWF4VmVydGljZXM6IG51bWJlciA9IDEwOTIwKSB7XG5cdFx0aWYgKG1heFZlcnRpY2VzID4gMTA5MjApIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGhhdmUgbW9yZSB0aGFuIDEwOTIwIHRyaWFuZ2xlcyBwZXIgYmF0Y2g6IFwiICsgbWF4VmVydGljZXMpO1xuXHRcdHRoaXMuY29udGV4dCA9IGNvbnRleHQgaW5zdGFuY2VvZiBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0ID8gY29udGV4dCA6IG5ldyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0KGNvbnRleHQpO1xuXHRcdGxldCBhdHRyaWJ1dGVzID0gdHdvQ29sb3JUaW50ID9cblx0XHRcdFtuZXcgUG9zaXRpb24yQXR0cmlidXRlKCksIG5ldyBDb2xvckF0dHJpYnV0ZSgpLCBuZXcgVGV4Q29vcmRBdHRyaWJ1dGUoKSwgbmV3IENvbG9yMkF0dHJpYnV0ZSgpXSA6XG5cdFx0XHRbbmV3IFBvc2l0aW9uMkF0dHJpYnV0ZSgpLCBuZXcgQ29sb3JBdHRyaWJ1dGUoKSwgbmV3IFRleENvb3JkQXR0cmlidXRlKCldO1xuXHRcdHRoaXMubWVzaCA9IG5ldyBNZXNoKGNvbnRleHQsIGF0dHJpYnV0ZXMsIG1heFZlcnRpY2VzLCBtYXhWZXJ0aWNlcyAqIDMpO1xuXHRcdGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcblx0XHR0aGlzLnNyY0NvbG9yQmxlbmQgPSBnbC5TUkNfQUxQSEE7XG5cdFx0dGhpcy5zcmNBbHBoYUJsZW5kID0gZ2wuT05FO1xuXHRcdHRoaXMuZHN0QmxlbmQgPSBnbC5PTkVfTUlOVVNfU1JDX0FMUEhBO1xuXHR9XG5cblx0YmVnaW4gKHNoYWRlcjogU2hhZGVyKSB7XG5cdFx0aWYgKHRoaXMuaXNEcmF3aW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJQb2x5Z29uQmF0Y2ggaXMgYWxyZWFkeSBkcmF3aW5nLiBDYWxsIFBvbHlnb25CYXRjaC5lbmQoKSBiZWZvcmUgY2FsbGluZyBQb2x5Z29uQmF0Y2guYmVnaW4oKVwiKTtcblx0XHR0aGlzLmRyYXdDYWxscyA9IDA7XG5cdFx0dGhpcy5zaGFkZXIgPSBzaGFkZXI7XG5cdFx0dGhpcy5sYXN0VGV4dHVyZSA9IG51bGw7XG5cdFx0dGhpcy5pc0RyYXdpbmcgPSB0cnVlO1xuXG5cdFx0bGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuXHRcdGdsLmVuYWJsZShnbC5CTEVORCk7XG5cdFx0Z2wuYmxlbmRGdW5jU2VwYXJhdGUodGhpcy5zcmNDb2xvckJsZW5kLCB0aGlzLmRzdEJsZW5kLCB0aGlzLnNyY0FscGhhQmxlbmQsIHRoaXMuZHN0QmxlbmQpO1xuXG5cdFx0aWYgKFBvbHlnb25CYXRjaGVyLmRpc2FibGVDdWxsaW5nKSB7XG5cdFx0XHR0aGlzLmN1bGxXYXNFbmFibGVkID0gZ2wuaXNFbmFibGVkKGdsLkNVTExfRkFDRSk7XG5cdFx0XHRpZiAodGhpcy5jdWxsV2FzRW5hYmxlZCkgZ2wuZGlzYWJsZShnbC5DVUxMX0ZBQ0UpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgc3RhdGljIGJsZW5kTW9kZXNHTDogeyBzcmNSZ2I6IG51bWJlciwgc3JjUmdiUG1hOiBudW1iZXIsIGRzdFJnYjogbnVtYmVyLCBzcmNBbHBoYTogbnVtYmVyIH1bXSA9IFtcblx0XHR7IHNyY1JnYjogR0xfU1JDX0FMUEhBLCBzcmNSZ2JQbWE6IEdMX09ORSwgZHN0UmdiOiBHTF9PTkVfTUlOVVNfU1JDX0FMUEhBLCBzcmNBbHBoYTogR0xfT05FIH0sXG5cdFx0eyBzcmNSZ2I6IEdMX1NSQ19BTFBIQSwgc3JjUmdiUG1hOiBHTF9PTkUsIGRzdFJnYjogR0xfT05FLCBzcmNBbHBoYTogR0xfT05FIH0sXG5cdFx0eyBzcmNSZ2I6IEdMX0RTVF9DT0xPUiwgc3JjUmdiUG1hOiBHTF9EU1RfQ09MT1IsIGRzdFJnYjogR0xfT05FX01JTlVTX1NSQ19BTFBIQSwgc3JjQWxwaGE6IEdMX09ORSB9LFxuXHRcdHsgc3JjUmdiOiBHTF9PTkUsIHNyY1JnYlBtYTogR0xfT05FLCBkc3RSZ2I6IEdMX09ORV9NSU5VU19TUkNfQ09MT1IsIHNyY0FscGhhOiBHTF9PTkUgfVxuXHRdXG5cblx0c2V0QmxlbmRNb2RlIChibGVuZE1vZGU6IEJsZW5kTW9kZSwgcHJlbXVsdGlwbGllZEFscGhhOiBib29sZWFuKSB7XG5cdFx0Y29uc3QgYmxlbmRNb2RlR0wgPSBQb2x5Z29uQmF0Y2hlci5ibGVuZE1vZGVzR0xbYmxlbmRNb2RlXTtcblx0XHRjb25zdCBzcmNDb2xvckJsZW5kID0gcHJlbXVsdGlwbGllZEFscGhhID8gYmxlbmRNb2RlR0wuc3JjUmdiUG1hIDogYmxlbmRNb2RlR0wuc3JjUmdiO1xuXHRcdGNvbnN0IHNyY0FscGhhQmxlbmQgPSBibGVuZE1vZGVHTC5zcmNBbHBoYTtcblx0XHRjb25zdCBkc3RCbGVuZCA9IGJsZW5kTW9kZUdMLmRzdFJnYjtcblxuXHRcdGlmICh0aGlzLnNyY0NvbG9yQmxlbmQgPT0gc3JjQ29sb3JCbGVuZCAmJiB0aGlzLnNyY0FscGhhQmxlbmQgPT0gc3JjQWxwaGFCbGVuZCAmJiB0aGlzLmRzdEJsZW5kID09IGRzdEJsZW5kKSByZXR1cm47XG5cdFx0dGhpcy5zcmNDb2xvckJsZW5kID0gc3JjQ29sb3JCbGVuZDtcblx0XHR0aGlzLnNyY0FscGhhQmxlbmQgPSBzcmNBbHBoYUJsZW5kO1xuXHRcdHRoaXMuZHN0QmxlbmQgPSBkc3RCbGVuZDtcblx0XHRpZiAodGhpcy5pc0RyYXdpbmcpIHtcblx0XHRcdHRoaXMuZmx1c2goKTtcblx0XHR9XG5cdFx0bGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuXHRcdGdsLmJsZW5kRnVuY1NlcGFyYXRlKHNyY0NvbG9yQmxlbmQsIGRzdEJsZW5kLCBzcmNBbHBoYUJsZW5kLCBkc3RCbGVuZCk7XG5cdH1cblxuXHRkcmF3ICh0ZXh0dXJlOiBHTFRleHR1cmUsIHZlcnRpY2VzOiBBcnJheUxpa2U8bnVtYmVyPiwgaW5kaWNlczogQXJyYXk8bnVtYmVyPikge1xuXHRcdGlmICh0ZXh0dXJlICE9IHRoaXMubGFzdFRleHR1cmUpIHtcblx0XHRcdHRoaXMuZmx1c2goKTtcblx0XHRcdHRoaXMubGFzdFRleHR1cmUgPSB0ZXh0dXJlO1xuXHRcdH0gZWxzZSBpZiAodGhpcy52ZXJ0aWNlc0xlbmd0aCArIHZlcnRpY2VzLmxlbmd0aCA+IHRoaXMubWVzaC5nZXRWZXJ0aWNlcygpLmxlbmd0aCB8fFxuXHRcdFx0dGhpcy5pbmRpY2VzTGVuZ3RoICsgaW5kaWNlcy5sZW5ndGggPiB0aGlzLm1lc2guZ2V0SW5kaWNlcygpLmxlbmd0aCkge1xuXHRcdFx0dGhpcy5mbHVzaCgpO1xuXHRcdH1cblxuXHRcdGxldCBpbmRleFN0YXJ0ID0gdGhpcy5tZXNoLm51bVZlcnRpY2VzKCk7XG5cdFx0dGhpcy5tZXNoLmdldFZlcnRpY2VzKCkuc2V0KHZlcnRpY2VzLCB0aGlzLnZlcnRpY2VzTGVuZ3RoKTtcblx0XHR0aGlzLnZlcnRpY2VzTGVuZ3RoICs9IHZlcnRpY2VzLmxlbmd0aDtcblx0XHR0aGlzLm1lc2guc2V0VmVydGljZXNMZW5ndGgodGhpcy52ZXJ0aWNlc0xlbmd0aClcblxuXHRcdGxldCBpbmRpY2VzQXJyYXkgPSB0aGlzLm1lc2guZ2V0SW5kaWNlcygpO1xuXHRcdGZvciAobGV0IGkgPSB0aGlzLmluZGljZXNMZW5ndGgsIGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGkrKywgaisrKVxuXHRcdFx0aW5kaWNlc0FycmF5W2ldID0gaW5kaWNlc1tqXSArIGluZGV4U3RhcnQ7XG5cdFx0dGhpcy5pbmRpY2VzTGVuZ3RoICs9IGluZGljZXMubGVuZ3RoO1xuXHRcdHRoaXMubWVzaC5zZXRJbmRpY2VzTGVuZ3RoKHRoaXMuaW5kaWNlc0xlbmd0aCk7XG5cdH1cblxuXHRmbHVzaCAoKSB7XG5cdFx0aWYgKHRoaXMudmVydGljZXNMZW5ndGggPT0gMCkgcmV0dXJuO1xuXHRcdGlmICghdGhpcy5sYXN0VGV4dHVyZSkgdGhyb3cgbmV3IEVycm9yKFwiTm8gdGV4dHVyZSBzZXQuXCIpO1xuXHRcdGlmICghdGhpcy5zaGFkZXIpIHRocm93IG5ldyBFcnJvcihcIk5vIHNoYWRlciBzZXQuXCIpO1xuXHRcdHRoaXMubGFzdFRleHR1cmUuYmluZCgpO1xuXHRcdHRoaXMubWVzaC5kcmF3KHRoaXMuc2hhZGVyLCB0aGlzLmNvbnRleHQuZ2wuVFJJQU5HTEVTKTtcblxuXHRcdHRoaXMudmVydGljZXNMZW5ndGggPSAwO1xuXHRcdHRoaXMuaW5kaWNlc0xlbmd0aCA9IDA7XG5cdFx0dGhpcy5tZXNoLnNldFZlcnRpY2VzTGVuZ3RoKDApO1xuXHRcdHRoaXMubWVzaC5zZXRJbmRpY2VzTGVuZ3RoKDApO1xuXHRcdHRoaXMuZHJhd0NhbGxzKys7XG5cdFx0UG9seWdvbkJhdGNoZXIuZ2xvYmFsRHJhd0NhbGxzKys7XG5cdH1cblxuXHRlbmQgKCkge1xuXHRcdGlmICghdGhpcy5pc0RyYXdpbmcpIHRocm93IG5ldyBFcnJvcihcIlBvbHlnb25CYXRjaCBpcyBub3QgZHJhd2luZy4gQ2FsbCBQb2x5Z29uQmF0Y2guYmVnaW4oKSBiZWZvcmUgY2FsbGluZyBQb2x5Z29uQmF0Y2guZW5kKClcIik7XG5cdFx0aWYgKHRoaXMudmVydGljZXNMZW5ndGggPiAwIHx8IHRoaXMuaW5kaWNlc0xlbmd0aCA+IDApIHRoaXMuZmx1c2goKTtcblx0XHR0aGlzLnNoYWRlciA9IG51bGw7XG5cdFx0dGhpcy5sYXN0VGV4dHVyZSA9IG51bGw7XG5cdFx0dGhpcy5pc0RyYXdpbmcgPSBmYWxzZTtcblxuXHRcdGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcblx0XHRnbC5kaXNhYmxlKGdsLkJMRU5EKTtcblx0XHRpZiAoUG9seWdvbkJhdGNoZXIuZGlzYWJsZUN1bGxpbmcpIHtcblx0XHRcdGlmICh0aGlzLmN1bGxXYXNFbmFibGVkKSBnbC5lbmFibGUoZ2wuQ1VMTF9GQUNFKTtcblx0XHR9XG5cdH1cblxuXHRnZXREcmF3Q2FsbHMgKCkge1xuXHRcdHJldHVybiB0aGlzLmRyYXdDYWxscztcblx0fVxuXG5cdHN0YXRpYyBnZXRBbmRSZXNldEdsb2JhbERyYXdDYWxscyAoKSB7XG5cdFx0bGV0IHJlc3VsdCA9IFBvbHlnb25CYXRjaGVyLmdsb2JhbERyYXdDYWxscztcblx0XHRQb2x5Z29uQmF0Y2hlci5nbG9iYWxEcmF3Q2FsbHMgPSAwO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRkaXNwb3NlICgpIHtcblx0XHR0aGlzLm1lc2guZGlzcG9zZSgpO1xuXHR9XG59XG4iXX0=