UNPKG

@esotericsoftware/spine-webgl

Version:
209 lines 32.4 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 { Color, SkeletonClipping, Vector2, Utils, RegionAttachment, MeshAttachment, ClippingAttachment } from "@esotericsoftware/spine-core"; class Renderable { vertices; numVertices; numFloats; constructor(vertices, numVertices, numFloats) { this.vertices = vertices; this.numVertices = numVertices; this.numFloats = numFloats; } } ; export class SkeletonRenderer { static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; premultipliedAlpha = false; tempColor = new Color(); tempColor2 = new Color(); vertices; vertexSize = 2 + 2 + 4; twoColorTint = false; renderable = new Renderable([], 0, 0); clipper = new SkeletonClipping(); temp = new Vector2(); temp2 = new Vector2(); temp3 = new Color(); temp4 = new Color(); constructor(context, twoColorTint = true) { this.twoColorTint = twoColorTint; if (twoColorTint) this.vertexSize += 4; this.vertices = Utils.newFloatArray(this.vertexSize * 1024); } draw(batcher, skeleton, slotRangeStart = -1, slotRangeEnd = -1, transformer = null) { let clipper = this.clipper; let premultipliedAlpha = this.premultipliedAlpha; let twoColorTint = this.twoColorTint; let blendMode = null; let renderable = this.renderable; let uvs; let triangles; let drawOrder = skeleton.drawOrder; let attachmentColor; let skeletonColor = skeleton.color; let vertexSize = twoColorTint ? 12 : 8; let inRange = false; if (slotRangeStart == -1) inRange = true; for (let i = 0, n = drawOrder.length; i < n; i++) { let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize; let slot = drawOrder[i]; if (!slot.bone.active) { clipper.clipEndWithSlot(slot); continue; } if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) { inRange = true; } if (!inRange) { clipper.clipEndWithSlot(slot); continue; } if (slotRangeEnd >= 0 && slotRangeEnd == slot.data.index) { inRange = false; } let attachment = slot.getAttachment(); let texture; if (attachment instanceof RegionAttachment) { let region = attachment; renderable.vertices = this.vertices; renderable.numVertices = 4; renderable.numFloats = clippedVertexSize << 2; region.computeWorldVertices(slot, renderable.vertices, 0, clippedVertexSize); triangles = SkeletonRenderer.QUAD_TRIANGLES; uvs = region.uvs; texture = region.region.texture; attachmentColor = region.color; } else if (attachment instanceof MeshAttachment) { let mesh = attachment; renderable.vertices = this.vertices; renderable.numVertices = (mesh.worldVerticesLength >> 1); renderable.numFloats = renderable.numVertices * clippedVertexSize; if (renderable.numFloats > renderable.vertices.length) { renderable.vertices = this.vertices = Utils.newFloatArray(renderable.numFloats); } mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize); triangles = mesh.triangles; texture = mesh.region.texture; uvs = mesh.uvs; attachmentColor = mesh.color; } else if (attachment instanceof ClippingAttachment) { let clip = (attachment); clipper.clipStart(slot, clip); continue; } else { clipper.clipEndWithSlot(slot); continue; } if (texture) { let slotColor = slot.color; let finalColor = this.tempColor; finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r; finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g; finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b; finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a; if (premultipliedAlpha) { finalColor.r *= finalColor.a; finalColor.g *= finalColor.a; finalColor.b *= finalColor.a; } let darkColor = this.tempColor2; if (!slot.darkColor) darkColor.set(0, 0, 0, 1.0); else { if (premultipliedAlpha) { darkColor.r = slot.darkColor.r * finalColor.a; darkColor.g = slot.darkColor.g * finalColor.a; darkColor.b = slot.darkColor.b * finalColor.a; } else { darkColor.setFromColor(slot.darkColor); } darkColor.a = premultipliedAlpha ? 1.0 : 0.0; } let slotBlendMode = slot.data.blendMode; if (slotBlendMode != blendMode) { blendMode = slotBlendMode; batcher.setBlendMode(blendMode, premultipliedAlpha); } if (clipper.isClipping()) { clipper.clipTriangles(renderable.vertices, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint); let clippedVertices = new Float32Array(clipper.clippedVertices); let clippedTriangles = clipper.clippedTriangles; if (transformer) transformer(clippedVertices, clippedVertices.length, vertexSize); batcher.draw(texture, clippedVertices, clippedTriangles); } else { let verts = renderable.vertices; if (!twoColorTint) { for (let v = 2, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) { verts[v] = finalColor.r; verts[v + 1] = finalColor.g; verts[v + 2] = finalColor.b; verts[v + 3] = finalColor.a; verts[v + 4] = uvs[u]; verts[v + 5] = uvs[u + 1]; } } else { for (let v = 2, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) { verts[v] = finalColor.r; verts[v + 1] = finalColor.g; verts[v + 2] = finalColor.b; verts[v + 3] = finalColor.a; verts[v + 4] = uvs[u]; verts[v + 5] = uvs[u + 1]; verts[v + 6] = darkColor.r; verts[v + 7] = darkColor.g; verts[v + 8] = darkColor.b; verts[v + 9] = darkColor.a; } } let view = renderable.vertices.subarray(0, renderable.numFloats); if (transformer) transformer(renderable.vertices, renderable.numFloats, vertexSize); batcher.draw(texture, view, triangles); } } clipper.clipEndWithSlot(slot); } clipper.clipEnd(); } /** Returns the {@link SkeletonClipping} used by this renderer for use with e.g. {@link Skeleton.getBounds} **/ getSkeletonClipping() { return this.clipper; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25SZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ta2VsZXRvblJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUUvRSxPQUFPLEVBQW1CLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUF1QixnQkFBZ0IsRUFBc0IsY0FBYyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFNdk0sTUFBTSxVQUFVO0lBQ0s7SUFBa0M7SUFBNEI7SUFBbEYsWUFBb0IsUUFBeUIsRUFBUyxXQUFtQixFQUFTLFNBQWlCO1FBQS9FLGFBQVEsR0FBUixRQUFRLENBQWlCO1FBQVMsZ0JBQVcsR0FBWCxXQUFXLENBQVE7UUFBUyxjQUFTLEdBQVQsU0FBUyxDQUFRO0lBQUksQ0FBQztDQUN4RztBQUFBLENBQUM7QUFJRixNQUFNLE9BQU8sZ0JBQWdCO0lBQzVCLE1BQU0sQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTNDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztJQUNuQixTQUFTLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUN4QixVQUFVLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUN6QixRQUFRLENBQWtCO0lBQzFCLFVBQVUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QixZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLFVBQVUsR0FBZSxJQUFJLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xELE9BQU8sR0FBcUIsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO0lBQ25ELElBQUksR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lB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QUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDdEIsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3dCQUMzQixDQUFDO29CQUNGLENBQUM7eUJBQU0sQ0FBQzt3QkFDUCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7NEJBQ2pGLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDOzRCQUN4QixLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUM7NEJBQzVCLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQzs0QkFDNUIsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDOzRCQUM1QixLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDdEIsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDOzRCQUMxQixLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7NEJBQzNCLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQzs0QkFDM0IsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDOzRCQUMzQixLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7d0JBQzVCLENBQUM7b0JBQ0YsQ0FBQztvQkFDRCxJQUFJLElBQUksR0FBSSxVQUFVLENBQUMsUUFBeUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDbkYsSUFBSSxXQUFXO3dCQUFFLFdBQVcsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBQ3BGLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDeEMsQ0FBQztZQUNGLENBQUM7WUFFRCxPQUFPLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFDRCxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVELCtHQUErRztJQUN4RyxtQkFBbUI7UUFDekIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IE51bWJlckFycmF5TGlrZSwgQ29sb3IsIFNrZWxldG9uQ2xpcHBpbmcsIFZlY3RvcjIsIFV0aWxzLCBTa2VsZXRvbiwgQmxlbmRNb2RlLCBSZWdpb25BdHRhY2htZW50LCBUZXh0dXJlQXRsYXNSZWdpb24sIE1lc2hBdHRhY2htZW50LCBDbGlwcGluZ0F0dGFjaG1lbnQgfSBmcm9tIFwiQGVzb3Rlcmljc29mdHdhcmUvc3BpbmUtY29yZVwiO1xuaW1wb3J0IHsgR0xUZXh0dXJlIH0gZnJvbSBcIi4vR0xUZXh0dXJlLmpzXCI7XG5pbXBvcnQgeyBQb2x5Z29uQmF0Y2hlciB9IGZyb20gXCIuL1BvbHlnb25CYXRjaGVyLmpzXCI7XG5pbXBvcnQgeyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0IH0gZnJvbSBcIi4vV2ViR0wuanNcIjtcblxuXG5jbGFzcyBSZW5kZXJhYmxlIHtcblx0Y29uc3RydWN0b3IgKHB1YmxpYyB2ZXJ0aWNlczogTnVtYmVyQXJyYXlMaWtlLCBwdWJsaWMgbnVtVmVydGljZXM6IG51bWJlciwgcHVibGljIG51bUZsb2F0czogbnVtYmVyKSB7IH1cbn07XG5cbmV4cG9ydCB0eXBlIFZlcnRleFRyYW5zZm9ybWVyID0gKHZlcnRpY2VzOiBOdW1iZXJBcnJheUxpa2UsIG51bVZlcnRpY2VzOiBudW1iZXIsIHN0cmlkZTogbnVtYmVyKSA9PiB2b2lkO1xuXG5leHBvcnQgY2xhc3MgU2tlbGV0b25SZW5kZXJlciB7XG5cdHN0YXRpYyBRVUFEX1RSSUFOR0xFUyA9IFswLCAxLCAyLCAyLCAzLCAwXTtcblxuXHRwcmVtdWx0aXBsaWVkQWxwaGEgPSBmYWxzZTtcblx0cHJpdmF0ZSB0ZW1wQ29sb3IgPSBuZXcgQ29sb3IoKTtcblx0cHJpdmF0ZSB0ZW1wQ29sb3IyID0gbmV3IENvbG9yKCk7XG5cdHByaXZhdGUgdmVydGljZXM6IE51bWJlckFycmF5TGlrZTtcblx0cHJpdmF0ZSB2ZXJ0ZXhTaXplID0gMiArIDIgKyA0O1xuXHRwcml2YXRlIHR3b0NvbG9yVGludCA9IGZhbHNlO1xuXHRwcml2YXRlIHJlbmRlcmFibGU6IFJlbmRlcmFibGUgPSBuZXcgUmVuZGVyYWJsZShbXSwgMCwgMCk7XG5cdHByaXZhdGUgY2xpcHBlcjogU2tlbGV0b25DbGlwcGluZyA9IG5ldyBTa2VsZXRvbkNsaXBwaW5nKCk7XG5cdHByaXZhdGUgdGVtcCA9IG5ldyBWZWN0b3IyKCk7XG5cdHByaXZhdGUgdGVtcDIgPSBuZXcgVmVjdG9yMigpO1xuXHRwcml2YXRlIHRlbXAzID0gbmV3IENvbG9yKCk7XG5cdHByaXZhdGUgdGVtcDQgPSBuZXcgQ29sb3IoKTtcblxuXHRjb25zdHJ1Y3RvciAoY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgdHdvQ29sb3JUaW50OiBib29sZWFuID0gdHJ1ZSkge1xuXHRcdHRoaXMudHdvQ29sb3JUaW50ID0gdHdvQ29sb3JUaW50O1xuXHRcdGlmICh0d29Db2xvclRpbnQpXG5cdFx0XHR0aGlzLnZlcnRleFNpemUgKz0gNDtcblx0XHR0aGlzLnZlcnRpY2VzID0gVXRpbHMubmV3RmxvYXRBcnJheSh0aGlzLnZlcnRleFNpemUgKiAxMDI0KTtcblx0fVxuXG5cdGRyYXcgKGJhdGNoZXI6IFBvbHlnb25CYXRjaGVyLCBza2VsZXRvbjogU2tlbGV0b24sIHNsb3RSYW5nZVN0YXJ0OiBudW1iZXIgPSAtMSwgc2xvdFJhbmdlRW5kOiBudW1iZXIgPSAtMSwgdHJhbnNmb3JtZXI6IFZlcnRleFRyYW5zZm9ybWVyIHwgbnVsbCA9IG51bGwpIHtcblx0XHRsZXQgY2xpcHBlciA9IHRoaXMuY2xpcHBlcjtcblx0XHRsZXQgcHJlbXVsdGlwbGllZEFscGhhID0gdGhpcy5wcmVtdWx0aXBsaWVkQWxwaGE7XG5cdFx0bGV0IHR3b0NvbG9yVGludCA9IHRoaXMudHdvQ29sb3JUaW50O1xuXHRcdGxldCBibGVuZE1vZGU6IEJsZW5kTW9kZSB8IG51bGwgPSBudWxsO1xuXG5cdFx0bGV0IHJlbmRlcmFibGU6IFJlbmRlcmFibGUgPSB0aGlzLnJlbmRlcmFibGU7XG5cdFx0bGV0IHV2czogTnVtYmVyQXJyYXlMaWtlO1xuXHRcdGxldCB0cmlhbmdsZXM6IEFycmF5PG51bWJlcj47XG5cdFx0bGV0IGRyYXdPcmRlciA9IHNrZWxldG9uLmRyYXdPcmRlcjtcblx0XHRsZXQgYXR0YWNobWVudENvbG9yOiBDb2xvcjtcblx0XHRsZXQgc2tlbGV0b25Db2xvciA9IHNrZWxldG9uLmNvbG9yO1xuXHRcdGxldCB2ZXJ0ZXhTaXplID0gdHdvQ29sb3JUaW50ID8gMTIgOiA4O1xuXHRcdGxldCBpblJhbmdlID0gZmFsc2U7XG5cdFx0aWYgKHNsb3RSYW5nZVN0YXJ0ID09IC0xKSBpblJhbmdlID0gdHJ1ZTtcblx0XHRmb3IgKGxldCBpID0gMCwgbiA9IGRyYXdPcmRlci5sZW5ndGg7IGkgPCBuOyBpKyspIHtcblx0XHRcdGxldCBjbGlwcGVkVmVydGV4U2l6ZSA9IGNsaXBwZXIuaXNDbGlwcGluZygpID8gMiA6IHZlcnRleFNpemU7XG5cdFx0XHRsZXQgc2xvdCA9IGRyYXdPcmRlcltpXTtcblx0XHRcdGlmICghc2xvdC5ib25lLmFjdGl2ZSkge1xuXHRcdFx0XHRjbGlwcGVyLmNsaXBFbmRXaXRoU2xvdChzbG90KTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzbG90UmFuZ2VTdGFydCA+PSAwICYmIHNsb3RSYW5nZVN0YXJ0ID09IHNsb3QuZGF0YS5pbmRleCkge1xuXHRcdFx0XHRpblJhbmdlID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFpblJhbmdlKSB7XG5cdFx0XHRcdGNsaXBwZXIuY2xpcEVuZFdpdGhTbG90KHNsb3QpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNsb3RSYW5nZUVuZCA+PSAwICYmIHNsb3RSYW5nZUVuZCA9PSBzbG90LmRhdGEuaW5kZXgpIHtcblx0XHRcdFx0aW5SYW5nZSA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgYXR0YWNobWVudCA9IHNsb3QuZ2V0QXR0YWNobWVudCgpO1xuXHRcdFx0bGV0IHRleHR1cmU6IEdMVGV4dHVyZTtcblx0XHRcdGlmIChhdHRhY2htZW50IGluc3RhbmNlb2YgUmVnaW9uQXR0YWNobWVudCkge1xuXHRcdFx0XHRsZXQgcmVnaW9uID0gPFJlZ2lvbkF0dGFjaG1lbnQ+YXR0YWNobWVudDtcblx0XHRcdFx0cmVuZGVyYWJsZS52ZXJ0aWNlcyA9IHRoaXMudmVydGljZXM7XG5cdFx0XHRcdHJlbmRlcmFibGUubnVtVmVydGljZXMgPSA0O1xuXHRcdFx0XHRyZW5kZXJhYmxlLm51bUZsb2F0cyA9IGNsaXBwZWRWZXJ0ZXhTaXplIDw8IDI7XG5cdFx0XHRcdHJlZ2lvbi5jb21wdXRlV29ybGRWZXJ0aWNlcyhzbG90LCByZW5kZXJhYmxlLnZlcnRpY2VzLCAwLCBjbGlwcGVkVmVydGV4U2l6ZSk7XG5cdFx0XHRcdHRyaWFuZ2xlcyA9IFNrZWxldG9uUmVuZGVyZXIuUVVBRF9UUklBTkdMRVM7XG5cdFx0XHRcdHV2cyA9IHJlZ2lvbi51dnM7XG5cdFx0XHRcdHRleHR1cmUgPSA8R0xUZXh0dXJlPnJlZ2lvbi5yZWdpb24hLnRleHR1cmU7XG5cdFx0XHRcdGF0dGFjaG1lbnRDb2xvciA9IHJlZ2lvbi5jb2xvcjtcblx0XHRcdH0gZWxzZSBpZiAoYXR0YWNobWVudCBpbnN0YW5jZW9mIE1lc2hBdHRhY2htZW50KSB7XG5cdFx0XHRcdGxldCBtZXNoID0gPE1lc2hBdHRhY2htZW50PmF0dGFjaG1lbnQ7XG5cdFx0XHRcdHJlbmRlcmFibGUudmVydGljZXMgPSB0aGlzLnZlcnRpY2VzO1xuXHRcdFx0XHRyZW5kZXJhYmxlLm51bVZlcnRpY2VzID0gKG1lc2gud29ybGRWZXJ0aWNlc0xlbmd0aCA+PiAxKTtcblx0XHRcdFx0cmVuZGVyYWJsZS5udW1GbG9hdHMgPSByZW5kZXJhYmxlLm51bVZlcnRpY2VzICogY2xpcHBlZFZlcnRleFNpemU7XG5cdFx0XHRcdGlmIChyZW5kZXJhYmxlLm51bUZsb2F0cyA+IHJlbmRlcmFibGUudmVydGljZXMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0cmVuZGVyYWJsZS52ZXJ0aWNlcyA9IHRoaXMudmVydGljZXMgPSBVdGlscy5uZXdGbG9hdEFycmF5KHJlbmRlcmFibGUubnVtRmxvYXRzKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRtZXNoLmNvbXB1dGVXb3JsZFZlcnRpY2VzKHNsb3QsIDAsIG1lc2gud29ybGRWZXJ0aWNlc0xlbmd0aCwgcmVuZGVyYWJsZS52ZXJ0aWNlcywgMCwgY2xpcHBlZFZlcnRleFNpemUpO1xuXHRcdFx0XHR0cmlhbmdsZXMgPSBtZXNoLnRyaWFuZ2xlcztcblx0XHRcdFx0dGV4dHVyZSA9IDxHTFRleHR1cmU+bWVzaC5yZWdpb24hLnRleHR1cmU7XG5cdFx0XHRcdHV2cyA9IG1lc2gudXZzO1xuXHRcdFx0XHRhdHRhY2htZW50Q29sb3IgPSBtZXNoLmNvbG9yO1xuXHRcdFx0fSBlbHNlIGlmIChhdHRhY2htZW50IGluc3RhbmNlb2YgQ2xpcHBpbmdBdHRhY2htZW50KSB7XG5cdFx0XHRcdGxldCBjbGlwID0gPENsaXBwaW5nQXR0YWNobWVudD4oYXR0YWNobWVudCk7XG5cdFx0XHRcdGNsaXBwZXIuY2xpcFN0YXJ0KHNsb3QsIGNsaXApO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNsaXBwZXIuY2xpcEVuZFdpdGhTbG90KHNsb3QpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRleHR1cmUpIHtcblx0XHRcdFx0bGV0IHNsb3RDb2xvciA9IHNsb3QuY29sb3I7XG5cdFx0XHRcdGxldCBmaW5hbENvbG9yID0gdGhpcy50ZW1wQ29sb3I7XG5cdFx0XHRcdGZpbmFsQ29sb3IuciA9IHNrZWxldG9uQ29sb3IuciAqIHNsb3RDb2xvci5yICogYXR0YWNobWVudENvbG9yLnI7XG5cdFx0XHRcdGZpbmFsQ29sb3IuZyA9IHNrZWxldG9uQ29sb3IuZyAqIHNsb3RDb2xvci5nICogYXR0YWNobWVudENvbG9yLmc7XG5cdFx0XHRcdGZpbmFsQ29sb3IuYiA9IHNrZWxldG9uQ29sb3IuYiAqIHNsb3RDb2xvci5iICogYXR0YWNobWVudENvbG9yLmI7XG5cdFx0XHRcdGZpbmFsQ29sb3IuYSA9IHNrZWxldG9uQ29sb3IuYSAqIHNsb3RDb2xvci5hICogYXR0YWNobWVudENvbG9yLmE7XG5cdFx0XHRcdGlmIChwcmVtdWx0aXBsaWVkQWxwaGEpIHtcblx0XHRcdFx0XHRmaW5hbENvbG9yLnIgKj0gZmluYWxDb2xvci5hO1xuXHRcdFx0XHRcdGZpbmFsQ29sb3IuZyAqPSBmaW5hbENvbG9yLmE7XG5cdFx0XHRcdFx0ZmluYWxDb2xvci5iICo9IGZpbmFsQ29sb3IuYTtcblx0XHRcdFx0fVxuXHRcdFx0XHRsZXQgZGFya0NvbG9yID0gdGhpcy50ZW1wQ29sb3IyO1xuXHRcdFx0XHRpZiAoIXNsb3QuZGFya0NvbG9yKVxuXHRcdFx0XHRcdGRhcmtDb2xvci5zZXQoMCwgMCwgMCwgMS4wKTtcblx0XHRcdFx0ZWxzZSB7XG5cdFx0XHRcdFx0aWYgKHByZW11bHRpcGxpZWRBbHBoYSkge1xuXHRcdFx0XHRcdFx0ZGFya0NvbG9yLnIgPSBzbG90LmRhcmtDb2xvci5yICogZmluYWxDb2xvci5hO1xuXHRcdFx0XHRcdFx0ZGFya0NvbG9yLmcgPSBzbG90LmRhcmtDb2xvci5nICogZmluYWxDb2xvci5hO1xuXHRcdFx0XHRcdFx0ZGFya0NvbG9yLmIgPSBzbG90LmRhcmtDb2xvci5iICogZmluYWxDb2xvci5hO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRkYXJrQ29sb3Iuc2V0RnJvbUNvbG9yKHNsb3QuZGFya0NvbG9yKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZGFya0NvbG9yLmEgPSBwcmVtdWx0aXBsaWVkQWxwaGEgPyAxLjAgOiAwLjA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRsZXQgc2xvdEJsZW5kTW9kZSA9IHNsb3QuZGF0YS5ibGVuZE1vZGU7XG5cdFx0XHRcdGlmIChzbG90QmxlbmRNb2RlICE9IGJsZW5kTW9kZSkge1xuXHRcdFx0XHRcdGJsZW5kTW9kZSA9IHNsb3RCbGVuZE1vZGU7XG5cdFx0XHRcdFx0YmF0Y2hlci5zZXRCbGVuZE1vZGUoYmxlbmRNb2RlLCBwcmVtdWx0aXBsaWVkQWxwaGEpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGNsaXBwZXIuaXNDbGlwcGluZygpKSB7XG5cdFx0XHRcdFx0Y2xpcHBlci5jbGlwVHJpYW5nbGVzKHJlbmRlcmFibGUudmVydGljZXMsIHRyaWFuZ2xlcywgdHJpYW5nbGVzLmxlbmd0aCwgdXZzLCBmaW5hbENvbG9yLCBkYXJrQ29sb3IsIHR3b0NvbG9yVGludCk7XG5cdFx0XHRcdFx0bGV0IGNsaXBwZWRWZXJ0aWNlcyA9IG5ldyBGbG9hdDMyQXJyYXkoY2xpcHBlci5jbGlwcGVkVmVydGljZXMpO1xuXHRcdFx0XHRcdGxldCBjbGlwcGVkVHJpYW5nbGVzID0gY2xpcHBlci5jbGlwcGVkVHJpYW5nbGVzO1xuXHRcdFx0XHRcdGlmICh0cmFuc2Zvcm1lcikgdHJhbnNmb3JtZXIoY2xpcHBlZFZlcnRpY2VzLCBjbGlwcGVkVmVydGljZXMubGVuZ3RoLCB2ZXJ0ZXhTaXplKTtcblx0XHRcdFx0XHRiYXRjaGVyLmRyYXcodGV4dHVyZSwgY2xpcHBlZFZlcnRpY2VzLCBjbGlwcGVkVHJpYW5nbGVzKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsZXQgdmVydHMgPSByZW5kZXJhYmxlLnZlcnRpY2VzO1xuXHRcdFx0XHRcdGlmICghdHdvQ29sb3JUaW50KSB7XG5cdFx0XHRcdFx0XHRmb3IgKGxldCB2ID0gMiwgdSA9IDAsIG4gPSByZW5kZXJhYmxlLm51bUZsb2F0czsgdiA8IG47IHYgKz0gdmVydGV4U2l6ZSwgdSArPSAyKSB7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW3ZdID0gZmluYWxDb2xvci5yO1xuXHRcdFx0XHRcdFx0XHR2ZXJ0c1t2ICsgMV0gPSBmaW5hbENvbG9yLmc7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW3YgKyAyXSA9IGZpbmFsQ29sb3IuYjtcblx0XHRcdFx0XHRcdFx0dmVydHNbdiArIDNdID0gZmluYWxDb2xvci5hO1xuXHRcdFx0XHRcdFx0XHR2ZXJ0c1t2ICsgNF0gPSB1dnNbdV07XG5cdFx0XHRcdFx0XHRcdHZlcnRzW3YgKyA1XSA9IHV2c1t1ICsgMV07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGZvciAobGV0IHYgPSAyLCB1ID0gMCwgbiA9IHJlbmRlcmFibGUubnVtRmxvYXRzOyB2IDwgbjsgdiArPSB2ZXJ0ZXhTaXplLCB1ICs9IDIpIHtcblx0XHRcdFx0XHRcdFx0dmVydHNbdl0gPSBmaW5hbENvbG9yLnI7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW3YgKyAxXSA9IGZpbmFsQ29sb3IuZztcblx0XHRcdFx0XHRcdFx0dmVydHNbdiArIDJdID0gZmluYWxDb2xvci5iO1xuXHRcdFx0XHRcdFx0XHR2ZXJ0c1t2ICsgM10gPSBmaW5hbENvbG9yLmE7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW3YgKyA0XSA9IHV2c1t1XTtcblx0XHRcdFx0XHRcdFx0dmVydHNbdiArIDVdID0gdXZzW3UgKyAxXTtcblx0XHRcdFx0XHRcdFx0dmVydHNbdiArIDZdID0gZGFya0NvbG9yLnI7XG5cdFx0XHRcdFx0XHRcdHZlcnRzW3YgKyA3XSA9IGRhcmtDb2xvci5nO1xuXHRcdFx0XHRcdFx0XHR2ZXJ0c1t2ICsgOF0gPSBkYXJrQ29sb3IuYjtcblx0XHRcdFx0XHRcdFx0dmVydHNbdiArIDldID0gZGFya0NvbG9yLmE7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGxldCB2aWV3ID0gKHJlbmRlcmFibGUudmVydGljZXMgYXMgRmxvYXQzMkFycmF5KS5zdWJhcnJheSgwLCByZW5kZXJhYmxlLm51bUZsb2F0cyk7XG5cdFx0XHRcdFx0aWYgKHRyYW5zZm9ybWVyKSB0cmFuc2Zvcm1lcihyZW5kZXJhYmxlLnZlcnRpY2VzLCByZW5kZXJhYmxlLm51bUZsb2F0cywgdmVydGV4U2l6ZSk7XG5cdFx0XHRcdFx0YmF0Y2hlci5kcmF3KHRleHR1cmUsIHZpZXcsIHRyaWFuZ2xlcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Y2xpcHBlci5jbGlwRW5kV2l0aFNsb3Qoc2xvdCk7XG5cdFx0fVxuXHRcdGNsaXBwZXIuY2xpcEVuZCgpO1xuXHR9XG5cblx0LyoqIFJldHVybnMgdGhlIHtAbGluayBTa2VsZXRvbkNsaXBwaW5nfSB1c2VkIGJ5IHRoaXMgcmVuZGVyZXIgZm9yIHVzZSB3aXRoIGUuZy4ge0BsaW5rIFNrZWxldG9uLmdldEJvdW5kc30gKiovXG5cdHB1YmxpYyBnZXRTa2VsZXRvbkNsaXBwaW5nICgpOiBTa2VsZXRvbkNsaXBwaW5nIHtcblx0XHRyZXR1cm4gdGhpcy5jbGlwcGVyO1xuXHR9XG59XG4iXX0=