UNPKG

@esotericsoftware/spine-webgl

Version:
347 lines 49.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, Vector2, MathUtils } from "@esotericsoftware/spine-core"; import { Mesh, Position2Attribute, ColorAttribute } from "./Mesh.js"; import { ManagedWebGLRenderingContext } from "./WebGL.js"; export class ShapeRenderer { context; isDrawing = false; mesh; shapeType = ShapeType.Filled; color = new Color(1, 1, 1, 1); shader = null; vertexIndex = 0; tmp = new Vector2(); srcColorBlend; srcAlphaBlend; dstBlend; constructor(context, 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); this.mesh = new Mesh(context, [new Position2Attribute(), new ColorAttribute()], maxVertices, 0); 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("ShapeRenderer.begin() has already been called"); this.shader = shader; this.vertexIndex = 0; this.isDrawing = true; let gl = this.context.gl; gl.enable(gl.BLEND); gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend); } setBlendMode(srcColorBlend, srcAlphaBlend, dstBlend) { 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); } } setColor(color) { this.color.setFromColor(color); } setColorWith(r, g, b, a) { this.color.set(r, g, b, a); } point(x, y, color) { this.check(ShapeType.Point, 1); if (!color) color = this.color; this.vertex(x, y, color); } line(x, y, x2, y2, color) { this.check(ShapeType.Line, 2); let vertices = this.mesh.getVertices(); let idx = this.vertexIndex; if (!color) color = this.color; this.vertex(x, y, color); this.vertex(x2, y2, color); } triangle(filled, x, y, x2, y2, x3, y3, color, color2, color3) { this.check(filled ? ShapeType.Filled : ShapeType.Line, 3); let vertices = this.mesh.getVertices(); let idx = this.vertexIndex; if (!color) color = this.color; if (!color2) color2 = this.color; if (!color3) color3 = this.color; if (filled) { this.vertex(x, y, color); this.vertex(x2, y2, color2); this.vertex(x3, y3, color3); } else { this.vertex(x, y, color); this.vertex(x2, y2, color2); this.vertex(x2, y2, color); this.vertex(x3, y3, color2); this.vertex(x3, y3, color); this.vertex(x, y, color2); } } quad(filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4) { this.check(filled ? ShapeType.Filled : ShapeType.Line, 3); let vertices = this.mesh.getVertices(); let idx = this.vertexIndex; if (!color) color = this.color; if (!color2) color2 = this.color; if (!color3) color3 = this.color; if (!color4) color4 = this.color; if (filled) { this.vertex(x, y, color); this.vertex(x2, y2, color2); this.vertex(x3, y3, color3); this.vertex(x3, y3, color3); this.vertex(x4, y4, color4); this.vertex(x, y, color); } else { this.vertex(x, y, color); this.vertex(x2, y2, color2); this.vertex(x2, y2, color2); this.vertex(x3, y3, color3); this.vertex(x3, y3, color3); this.vertex(x4, y4, color4); this.vertex(x4, y4, color4); this.vertex(x, y, color); } } rect(filled, x, y, width, height, color) { this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color); } rectLine(filled, x1, y1, x2, y2, width, color) { this.check(filled ? ShapeType.Filled : ShapeType.Line, 8); if (!color) color = this.color; let t = this.tmp.set(y2 - y1, x1 - x2); t.normalize(); width *= 0.5; let tx = t.x * width; let ty = t.y * width; if (!filled) { this.vertex(x1 + tx, y1 + ty, color); this.vertex(x1 - tx, y1 - ty, color); this.vertex(x2 + tx, y2 + ty, color); this.vertex(x2 - tx, y2 - ty, color); this.vertex(x2 + tx, y2 + ty, color); this.vertex(x1 + tx, y1 + ty, color); this.vertex(x2 - tx, y2 - ty, color); this.vertex(x1 - tx, y1 - ty, color); } else { this.vertex(x1 + tx, y1 + ty, color); this.vertex(x1 - tx, y1 - ty, color); this.vertex(x2 + tx, y2 + ty, color); this.vertex(x2 - tx, y2 - ty, color); this.vertex(x2 + tx, y2 + ty, color); this.vertex(x1 - tx, y1 - ty, color); } } x(x, y, size) { this.line(x - size, y - size, x + size, y + size); this.line(x - size, y + size, x + size, y - size); } polygon(polygonVertices, offset, count, color) { if (count < 3) throw new Error("Polygon must contain at least 3 vertices"); this.check(ShapeType.Line, count * 2); if (!color) color = this.color; let vertices = this.mesh.getVertices(); let idx = this.vertexIndex; offset <<= 1; count <<= 1; let firstX = polygonVertices[offset]; let firstY = polygonVertices[offset + 1]; let last = offset + count; for (let i = offset, n = offset + count - 2; i < n; i += 2) { let x1 = polygonVertices[i]; let y1 = polygonVertices[i + 1]; let x2 = 0; let y2 = 0; if (i + 2 >= last) { x2 = firstX; y2 = firstY; } else { x2 = polygonVertices[i + 2]; y2 = polygonVertices[i + 3]; } this.vertex(x1, y1, color); this.vertex(x2, y2, color); } } circle(filled, x, y, radius, color, segments = 0) { if (segments == 0) segments = Math.max(1, (6 * MathUtils.cbrt(radius)) | 0); if (segments <= 0) throw new Error("segments must be > 0."); if (!color) color = this.color; let angle = 2 * MathUtils.PI / segments; let cos = Math.cos(angle); let sin = Math.sin(angle); let cx = radius, cy = 0; if (!filled) { this.check(ShapeType.Line, segments * 2 + 2); for (let i = 0; i < segments; i++) { this.vertex(x + cx, y + cy, color); let temp = cx; cx = cos * cx - sin * cy; cy = sin * temp + cos * cy; this.vertex(x + cx, y + cy, color); } // Ensure the last segment is identical to the first. this.vertex(x + cx, y + cy, color); } else { this.check(ShapeType.Filled, segments * 3 + 3); segments--; for (let i = 0; i < segments; i++) { this.vertex(x, y, color); this.vertex(x + cx, y + cy, color); let temp = cx; cx = cos * cx - sin * cy; cy = sin * temp + cos * cy; this.vertex(x + cx, y + cy, color); } // Ensure the last segment is identical to the first. this.vertex(x, y, color); this.vertex(x + cx, y + cy, color); } let temp = cx; cx = radius; cy = 0; this.vertex(x + cx, y + cy, color); } curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color) { this.check(ShapeType.Line, segments * 2 + 2); if (!color) color = this.color; // Algorithm from: http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION let subdiv_step = 1 / segments; let subdiv_step2 = subdiv_step * subdiv_step; let subdiv_step3 = subdiv_step * subdiv_step * subdiv_step; let pre1 = 3 * subdiv_step; let pre2 = 3 * subdiv_step2; let pre4 = 6 * subdiv_step2; let pre5 = 6 * subdiv_step3; let tmp1x = x1 - cx1 * 2 + cx2; let tmp1y = y1 - cy1 * 2 + cy2; let tmp2x = (cx1 - cx2) * 3 - x1 + x2; let tmp2y = (cy1 - cy2) * 3 - y1 + y2; let fx = x1; let fy = y1; let dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; let dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; let ddfx = tmp1x * pre4 + tmp2x * pre5; let ddfy = tmp1y * pre4 + tmp2y * pre5; let dddfx = tmp2x * pre5; let dddfy = tmp2y * pre5; while (segments-- > 0) { this.vertex(fx, fy, color); fx += dfx; fy += dfy; dfx += ddfx; dfy += ddfy; ddfx += dddfx; ddfy += dddfy; this.vertex(fx, fy, color); } this.vertex(fx, fy, color); this.vertex(x2, y2, color); } vertex(x, y, color) { let idx = this.vertexIndex; let vertices = this.mesh.getVertices(); vertices[idx++] = x; vertices[idx++] = y; vertices[idx++] = color.r; vertices[idx++] = color.g; vertices[idx++] = color.b; vertices[idx++] = color.a; this.vertexIndex = idx; } end() { if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called"); this.flush(); let gl = this.context.gl; gl.disable(gl.BLEND); this.isDrawing = false; } flush() { if (this.vertexIndex == 0) return; if (!this.shader) throw new Error("No shader set."); this.mesh.setVerticesLength(this.vertexIndex); this.mesh.draw(this.shader, this.shapeType); this.vertexIndex = 0; } check(shapeType, numVertices) { if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called"); if (this.shapeType == shapeType) { if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices) this.flush(); else return; } else { this.flush(); this.shapeType = shapeType; } } dispose() { this.mesh.dispose(); } } export var ShapeType; (function (ShapeType) { ShapeType[ShapeType["Point"] = 0] = "Point"; ShapeType[ShapeType["Line"] = 1] = "Line"; ShapeType[ShapeType["Filled"] = 4] = "Filled"; })(ShapeType || (ShapeType = {})); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2hhcGVSZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9TaGFwZVJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUUvRSxPQUFPLEVBQWMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNyRixPQUFPLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVyRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFMUQsTUFBTSxPQUFPLGFBQWE7SUFDakIsT0FBTyxDQUErQjtJQUN0QyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLElBQUksQ0FBTztJQUNYLFNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQzdCLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5QixNQUFNLEdBQWtCLElBQUksQ0FBQztJQUM3QixXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLEdBQUcsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQ3BCLGFBQWEsQ0FBUztJQUN0QixhQUFhLENBQVM7SUFDdEIsUUFBUSxDQUFTO0lBRXpCLFlBQWEsT0FBNkQsRUFBRSxjQUFzQixLQUFLO1FBQ3RHLElBQUksV0FBVyxHQUFHLEtBQUs7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxHQUFHLFdBQVcsQ0FBQyxDQUFDO1FBQzNHLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxZQUFZLDRCQUE0QixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksNEJBQTRCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckgsSUFBSSxDQUFDLElBQUksR0FBRyxJ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SUFBSSxDQUFDLEtBQUssQ0FBQztRQUNqQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1osSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ25GLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNwRixDQUFDO2FBQU0sQ0FBQztZQUNQLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2RCxDQUFDO0lBQ0YsQ0FBQztJQUVELElBQUksQ0FBRSxNQUFlLEVBQUUsQ0FBUyxFQUFFLENBQVMsRUFBRSxLQUFhLEVBQUUsTUFBYyxFQUFFLEtBQWE7UUFDeEYsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDekcsQ0FBQztJQUVELFFBQVEsQ0FBRSxNQUFlLEVBQUUsRUFBVSxFQUFFLEVBQVUsRUFBRSxFQUFVLEVBQUUsRUFBVSxFQUFFLEtBQWEsRUFBRSxLQUFhO1FBQ3RHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxLQUFLO1lBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDL0IsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2QsS0FBSyxJQUFJLEdBQUcsQ0FBQztRQUNiLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXJDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXJDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLENBQUM7YUFBTSxDQUFDO1lBQ1AsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEMsQ0FBQztJQUNGLENBQUM7SUFFRCxDQUFDLENBQUUsQ0FBUyxFQUFFLENBQVMsRUFBRSxJQUFZO1FBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxPQUFPLENBQUUsZUFBa0MsRUFBRSxNQUFjLEVBQUUsS0FBYSxFQUFFLEtBQWE7UUFDeEYsSUFBSSxLQUFLLEdBQUcsQ0FBQztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxLQUFLO1lBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDL0IsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBRTNCLE1BQU0sS0FBSyxDQUFDLENBQUM7UUFDYixLQUFLLEtBQUssQ0FBQyxDQUFDO1FBRVosSUFBSSxNQUFNLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLElBQUksTUFBTSxHQUFHLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDekMsSUFBSSxJQUFJLEdBQUcsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUUxQixLQUFLLElBQUksQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDNUQsSUFBSSxFQUFFLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLElBQUksRUFBRSxHQUFHLGVBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFaEMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ1gsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRVgsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUNuQixFQUFFLEdBQUcsTUFBTSxDQUFDO2dCQUNaLEVBQUUsR0FBRyxNQUFNLENBQUM7WUFDYixDQUFDO2lCQUFNLENBQUM7Z0JBQ1AsRUFBRSxHQUFHLGVBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQzVCLEVBQUUsR0FBRyxlQUFlLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzdCLENBQUM7WUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQU0sQ0FBQyxDQUFDO1FBQzdCLENBQUM7SUFDRixDQUFDO0lBRUQsTUFBTSxDQUFFLE1BQWUsRUFBRSxDQUFTLEVBQUUsQ0FBUyxFQUFFLE1BQWMsRUFBRSxLQUFhLEVBQUUsV0FBbUIsQ0FBQztRQUNqRyxJQUFJLFFBQVEsSUFBSSxDQUFDO1lBQUUsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLFFBQVEsSUFBSSxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxLQUFLO1lBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDL0IsSUFBSSxLQUFLLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxFQUFFLEdBQUcsUUFBUSxDQUFDO1FBQ3hDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixJQUFJLEVBQUUsR0FBRyxNQUFNLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUM3QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ2QsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDekIsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDcEMsQ0FBQztZQUNELHFEQUFxRDtZQUNyRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNwQyxDQUFDO2FBQU0sQ0FBQztZQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQy9DLFFBQVEsRUFBRSxDQUFDO1lBQ1gsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ2QsRUFBRSxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDekIsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDcEMsQ0FBQztZQUNELHFEQUFxRDtZQUNyRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUVELElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNkLEVBQUUsR0FBRyxNQUFNLENBQUM7UUFDWixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ1AsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELEtBQUssQ0FBRSxFQUFVLEVBQUUsRUFBVSxFQUFFLEdBQVcsRUFBRSxHQUFXLEVBQUUsR0FBVyxFQUFFLEdBQVcsRUFBRSxFQUFVLEVBQUUsRUFBVSxFQUFFLFFBQWdCLEVBQUUsS0FBYTtRQUN6SSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsS0FBSztZQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBRS9CLDhHQUE4RztRQUM5RyxJQUFJLFdBQVcsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBQy9CLElBQUksWUFBWSxHQUFHLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDN0MsSUFBSSxZQUFZLEdBQUcsV0FBVyxHQUFHLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFFM0QsSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQztRQUMzQixJQUFJLElBQUksR0FBRyxDQUFDLEdBQUcsWUFBWSxDQUFDO1FBQzVCLElBQUksSUFBSSxHQUFHLENBQUMsR0FBRyxZQUFZLENBQUM7UUFDNUIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLFlBQVksQ0FBQztRQUU1QixJQUFJLEtBQUssR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDL0IsSUFBSSxLQUFLLEdBQUcsRUFBRSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBRS9CLElBQUksS0FBSyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLElBQUksS0FBSyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBRXRDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNaLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUVaLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxZQUFZLENBQUM7UUFDbEUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLFlBQVksQ0FBQztRQUVsRSxJQUFJLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDdkMsSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBRXZDLElBQUksS0FBSyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxLQUFLLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQztRQUV6QixPQUFPLFFBQVEsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFNLENBQUMsQ0FBQztZQUM1QixFQUFFLElBQUksR0FBRyxDQUFDO1lBQ1YsRUFBRSxJQUFJLEdBQUcsQ0FBQztZQUNWLEdBQUcsSUFBSSxJQUFJLENBQUM7WUFDWixHQUFHLElBQUksSUFBSSxDQUFDO1lBQ1osSUFBSSxJQUFJLEtBQUssQ0FBQztZQUNkLElBQUksSUFBSSxLQUFLLENBQUM7WUFDZCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFNLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBTSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVPLE1BQU0sQ0FBRSxDQUFTLEVBQUUsQ0FBUyxFQUFFLEtBQVk7UUFDakQsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUMzQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQixRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEIsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxQixRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFCLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDMUIsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQztJQUN4QixDQUFDO0lBRUQsR0FBRztRQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUNsRixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDYixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUN6QixFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRU8sS0FBSztRQUNaLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDO1lBQUUsT0FBTztRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDdEIsQ0FBQztJQUVPLEtBQUssQ0FBRSxTQUFvQixFQUFFLFdBQW1CO1FBQ3ZELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUNsRixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsV0FBVztnQkFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7O2dCQUM3RSxPQUFPO1FBQ2IsQ0FBQzthQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUM1QixDQUFDO0lBQ0YsQ0FBQztJQUVELE9BQU87UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLENBQUM7Q0FDRDtBQUVELE1BQU0sQ0FBTixJQUFZLFNBSVg7QUFKRCxXQUFZLFNBQVM7SUFDcEIsMkNBQWMsQ0FBQTtJQUNkLHlDQUFhLENBQUE7SUFDYiw2Q0FBZSxDQUFBO0FBQ2hCLENBQUMsRUFKVyxTQUFTLEtBQVQsU0FBUyxRQUlwQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgRGlzcG9zYWJsZSwgQ29sb3IsIFZlY3RvcjIsIE1hdGhVdGlscyB9IGZyb20gXCJAZXNvdGVyaWNzb2Z0d2FyZS9zcGluZS1jb3JlXCI7XG5pbXBvcnQgeyBNZXNoLCBQb3NpdGlvbjJBdHRyaWJ1dGUsIENvbG9yQXR0cmlidXRlIH0gZnJvbSBcIi4vTWVzaC5qc1wiO1xuaW1wb3J0IHsgU2hhZGVyIH0gZnJvbSBcIi4vU2hhZGVyLmpzXCI7XG5pbXBvcnQgeyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0IH0gZnJvbSBcIi4vV2ViR0wuanNcIjtcblxuZXhwb3J0IGNsYXNzIFNoYXBlUmVuZGVyZXIgaW1wbGVtZW50cyBEaXNwb3NhYmxlIHtcblx0cHJpdmF0ZSBjb250ZXh0OiBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0O1xuXHRwcml2YXRlIGlzRHJhd2luZyA9IGZhbHNlO1xuXHRwcml2YXRlIG1lc2g6IE1lc2g7XG5cdHByaXZhdGUgc2hhcGVUeXBlID0gU2hhcGVUeXBlLkZpbGxlZDtcblx0cHJpdmF0ZSBjb2xvciA9IG5ldyBDb2xvcigxLCAxLCAxLCAxKTtcblx0cHJpdmF0ZSBzaGFkZXI6IFNoYWRlciB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIHZlcnRleEluZGV4ID0gMDtcblx0cHJpdmF0ZSB0bXAgPSBuZXcgVmVjdG9yMigpO1xuXHRwcml2YXRlIHNyY0NvbG9yQmxlbmQ6IG51bWJlcjtcblx0cHJpdmF0ZSBzcmNBbHBoYUJsZW5kOiBudW1iZXI7XG5cdHByaXZhdGUgZHN0QmxlbmQ6IG51bWJlcjtcblxuXHRjb25zdHJ1Y3RvciAoY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dCB8IFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgbWF4VmVydGljZXM6IG51bWJlciA9IDEwOTIwKSB7XG5cdFx0aWYgKG1heFZlcnRpY2VzID4gMTA5MjApIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGhhdmUgbW9yZSB0aGFuIDEwOTIwIHRyaWFuZ2xlcyBwZXIgYmF0Y2g6IFwiICsgbWF4VmVydGljZXMpO1xuXHRcdHRoaXMuY29udGV4dCA9IGNvbnRleHQgaW5zdGFuY2VvZiBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0ID8gY29udGV4dCA6IG5ldyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0KGNvbnRleHQpO1xuXHRcdHRoaXMubWVzaCA9IG5ldyBNZXNoKGNvbnRleHQsIFtuZXcgUG9zaXRpb24yQXR0cmlidXRlKCksIG5ldyBDb2xvckF0dHJpYnV0ZSgpXSwgbWF4VmVydGljZXMsIDApO1xuXHRcdGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcblx0XHR0aGlzLnNyY0NvbG9yQmxlbmQgPSBnbC5TUkNfQUxQSEE7XG5cdFx0dGhpcy5zcmNBbHBoYUJsZW5kID0gZ2wuT05FO1xuXHRcdHRoaXMuZHN0QmxlbmQgPSBnbC5PTkVfTUlOVVNfU1JDX0FMUEhBO1xuXHR9XG5cblx0YmVnaW4gKHNoYWRlcjogU2hhZGVyKSB7XG5cdFx0aWYgKHRoaXMuaXNEcmF3aW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJTaGFwZVJlbmRlcmVyLmJlZ2luKCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWRcIik7XG5cdFx0dGhpcy5zaGFkZXIgPSBzaGFkZXI7XG5cdFx0dGhpcy52ZXJ0ZXhJbmRleCA9IDA7XG5cdFx0dGhpcy5pc0RyYXdpbmcgPSB0cnVlO1xuXG5cdFx0bGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xuXHRcdGdsLmVuYWJsZShnbC5CTEVORCk7XG5cdFx0Z2wuYmxlbmRGdW5jU2VwYXJhdGUodGhpcy5zcmNDb2xvckJsZW5kLCB0aGlzLmRzdEJsZW5kLCB0aGlzLnNyY0FscGhhQmxlbmQsIHRoaXMuZHN0QmxlbmQpO1xuXHR9XG5cblx0c2V0QmxlbmRNb2RlIChzcmNDb2xvckJsZW5kOiBudW1iZXIsIHNyY0FscGhhQmxlbmQ6IG51bWJlciwgZHN0QmxlbmQ6IG51bWJlcikge1xuXHRcdHRoaXMuc3JjQ29sb3JCbGVuZCA9IHNyY0NvbG9yQmxlbmQ7XG5cdFx0dGhpcy5zcmNBbHBoYUJsZW5kID0gc3JjQWxwaGFCbGVuZDtcblx0XHR0aGlzLmRzdEJsZW5kID0gZHN0QmxlbmQ7XG5cdFx0aWYgKHRoaXMuaXNEcmF3aW5nKSB7XG5cdFx0XHR0aGlzLmZsdXNoKCk7XG5cdFx0XHRsZXQgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XG5cdFx0XHRnbC5ibGVuZEZ1bmNTZXBhcmF0ZShzcmNDb2xvckJsZW5kLCBkc3RCbGVuZCwgc3JjQWxwaGFCbGVuZCwgZHN0QmxlbmQpO1xuXHRcdH1cblx0fVxuXG5cdHNldENvbG9yIChjb2xvcjogQ29sb3IpIHtcblx0XHR0aGlzLmNvbG9yLnNldEZyb21Db2xvcihjb2xvcik7XG5cdH1cblxuXHRzZXRDb2xvcldpdGggKHI6IG51bWJlciwgZzogbnVtYmVyLCBiOiBudW1iZXIsIGE6IG51bWJlcikge1xuXHRcdHRoaXMuY29sb3Iuc2V0KHIsIGcsIGIsIGEpO1xuXHR9XG5cblx0cG9pbnQgKHg6IG51bWJlciwgeTogbnVtYmVyLCBjb2xvcj86IENvbG9yKSB7XG5cdFx0dGhpcy5jaGVjayhTaGFwZVR5cGUuUG9pbnQsIDEpO1xuXHRcdGlmICghY29sb3IpIGNvbG9yID0gdGhpcy5jb2xvcjtcblx0XHR0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XG5cdH1cblxuXHRsaW5lICh4OiBudW1iZXIsIHk6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlciwgY29sb3I/OiBDb2xvcikge1xuXHRcdHRoaXMuY2hlY2soU2hhcGVUeXBlLkxpbmUsIDIpO1xuXHRcdGxldCB2ZXJ0aWNlcyA9IHRoaXMubWVzaC5nZXRWZXJ0aWNlcygpO1xuXHRcdGxldCBpZHggPSB0aGlzLnZlcnRleEluZGV4O1xuXHRcdGlmICghY29sb3IpIGNvbG9yID0gdGhpcy5jb2xvcjtcblx0XHR0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XG5cdFx0dGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcik7XG5cdH1cblxuXHR0cmlhbmdsZSAoZmlsbGVkOiBib29sZWFuLCB4OiBudW1iZXIsIHk6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlciwgeDM6IG51bWJlciwgeTM6IG51bWJlciwgY29sb3I/OiBDb2xvciwgY29sb3IyPzogQ29sb3IsIGNvbG9yMz86IENvbG9yKSB7XG5cdFx0dGhpcy5jaGVjayhmaWxsZWQgPyBTaGFwZVR5cGUuRmlsbGVkIDogU2hhcGVUeXBlLkxpbmUsIDMpO1xuXHRcdGxldCB2ZXJ0aWNlcyA9IHRoaXMubWVzaC5nZXRWZXJ0aWNlcygpO1xuXHRcdGxldCBpZHggPSB0aGlzLnZlcnRleEluZGV4O1xuXHRcdGlmICghY29sb3IpIGNvbG9yID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoIWNvbG9yMikgY29sb3IyID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoIWNvbG9yMykgY29sb3IzID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoZmlsbGVkKSB7XG5cdFx0XHR0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XG5cdFx0XHR0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XG5cdFx0XHR0aGlzLnZlcnRleCh4MywgeTMsIGNvbG9yMyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcblx0XHRcdHRoaXMudmVydGV4KHgyLCB5MiwgY29sb3IyKTtcblxuXHRcdFx0dGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcik7XG5cdFx0XHR0aGlzLnZlcnRleCh4MywgeTMsIGNvbG9yMik7XG5cblx0XHRcdHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IyKTtcblx0XHR9XG5cdH1cblxuXHRxdWFkIChmaWxsZWQ6IGJvb2xlYW4sIHg6IG51bWJlciwgeTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCB4MzogbnVtYmVyLCB5MzogbnVtYmVyLCB4NDogbnVtYmVyLCB5NDogbnVtYmVyLCBjb2xvcj86IENvbG9yLCBjb2xvcjI/OiBDb2xvciwgY29sb3IzPzogQ29sb3IsIGNvbG9yND86IENvbG9yKSB7XG5cdFx0dGhpcy5jaGVjayhmaWxsZWQgPyBTaGFwZVR5cGUuRmlsbGVkIDogU2hhcGVUeXBlLkxpbmUsIDMpO1xuXHRcdGxldCB2ZXJ0aWNlcyA9IHRoaXMubWVzaC5nZXRWZXJ0aWNlcygpO1xuXHRcdGxldCBpZHggPSB0aGlzLnZlcnRleEluZGV4O1xuXHRcdGlmICghY29sb3IpIGNvbG9yID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoIWNvbG9yMikgY29sb3IyID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoIWNvbG9yMykgY29sb3IzID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoIWNvbG9yNCkgY29sb3I0ID0gdGhpcy5jb2xvcjtcblx0XHRpZiAoZmlsbGVkKSB7XG5cdFx0XHR0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7IHRoaXMudmVydGV4KHgyLCB5MiwgY29sb3IyKTsgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjMpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjMpOyB0aGlzLnZlcnRleCh4NCwgeTQsIGNvbG9yNCk7IHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpOyB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XG5cdFx0XHR0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7IHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcblx0XHRcdHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTsgdGhpcy52ZXJ0ZXgoeDQsIHk0LCBjb2xvcjQpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeDQsIHk0LCBjb2xvcjQpOyB0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XG5cdFx0fVxuXHR9XG5cblx0cmVjdCAoZmlsbGVkOiBib29sZWFuLCB4OiBudW1iZXIsIHk6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGNvbG9yPzogQ29sb3IpIHtcblx0XHR0aGlzLnF1YWQoZmlsbGVkLCB4LCB5LCB4ICsgd2lkdGgsIHksIHggKyB3aWR0aCwgeSArIGhlaWdodCwgeCwgeSArIGhlaWdodCwgY29sb3IsIGNvbG9yLCBjb2xvciwgY29sb3IpO1xuXHR9XG5cblx0cmVjdExpbmUgKGZpbGxlZDogYm9vbGVhbiwgeDE6IG51bWJlciwgeTE6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlciwgd2lkdGg6IG51bWJlciwgY29sb3I/OiBDb2xvcikge1xuXHRcdHRoaXMuY2hlY2soZmlsbGVkID8gU2hhcGVUeXBlLkZpbGxlZCA6IFNoYXBlVHlwZS5MaW5lLCA4KTtcblx0XHRpZiAoIWNvbG9yKSBjb2xvciA9IHRoaXMuY29sb3I7XG5cdFx0bGV0IHQgPSB0aGlzLnRtcC5zZXQoeTIgLSB5MSwgeDEgLSB4Mik7XG5cdFx0dC5ub3JtYWxpemUoKTtcblx0XHR3aWR0aCAqPSAwLjU7XG5cdFx0bGV0IHR4ID0gdC54ICogd2lkdGg7XG5cdFx0bGV0IHR5ID0gdC55ICogd2lkdGg7XG5cdFx0aWYgKCFmaWxsZWQpIHtcblx0XHRcdHRoaXMudmVydGV4KHgxICsgdHgsIHkxICsgdHksIGNvbG9yKTtcblx0XHRcdHRoaXMudmVydGV4KHgxIC0gdHgsIHkxIC0gdHksIGNvbG9yKTtcblx0XHRcdHRoaXMudmVydGV4KHgyICsgdHgsIHkyICsgdHksIGNvbG9yKTtcblx0XHRcdHRoaXMudmVydGV4KHgyIC0gdHgsIHkyIC0gdHksIGNvbG9yKTtcblxuXHRcdFx0dGhpcy52ZXJ0ZXgoeDIgKyB0eCwgeTIgKyB0eSwgY29sb3IpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeDEgKyB0eCwgeTEgKyB0eSwgY29sb3IpO1xuXG5cdFx0XHR0aGlzLnZlcnRleCh4MiAtIHR4LCB5MiAtIHR5LCBjb2xvcik7XG5cdFx0XHR0aGlzLnZlcnRleCh4MSAtIHR4LCB5MSAtIHR5LCBjb2xvcik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMudmVydGV4KHgxICsgdHgsIHkxICsgdHksIGNvbG9yKTtcblx0XHRcdHRoaXMudmVydGV4KHgxIC0gdHgsIHkxIC0gdHksIGNvbG9yKTtcblx0XHRcdHRoaXMudmVydGV4KHgyICsgdHgsIHkyICsgdHksIGNvbG9yKTtcblxuXHRcdFx0dGhpcy52ZXJ0ZXgoeDIgLSB0eCwgeTIgLSB0eSwgY29sb3IpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeDIgKyB0eCwgeTIgKyB0eSwgY29sb3IpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeDEgLSB0eCwgeTEgLSB0eSwgY29sb3IpO1xuXHRcdH1cblx0fVxuXG5cdHggKHg6IG51bWJlciwgeTogbnVtYmVyLCBzaXplOiBudW1iZXIpIHtcblx0XHR0aGlzLmxpbmUoeCAtIHNpemUsIHkgLSBzaXplLCB4ICsgc2l6ZSwgeSArIHNpemUpO1xuXHRcdHRoaXMubGluZSh4IC0gc2l6ZSwgeSArIHNpemUsIHggKyBzaXplLCB5IC0gc2l6ZSk7XG5cdH1cblxuXHRwb2x5Z29uIChwb2x5Z29uVmVydGljZXM6IEFycmF5TGlrZTxudW1iZXI+LCBvZmZzZXQ6IG51bWJlciwgY291bnQ6IG51bWJlciwgY29sb3I/OiBDb2xvcikge1xuXHRcdGlmIChjb3VudCA8IDMpIHRocm93IG5ldyBFcnJvcihcIlBvbHlnb24gbXVzdCBjb250YWluIGF0IGxlYXN0IDMgdmVydGljZXNcIik7XG5cdFx0dGhpcy5jaGVjayhTaGFwZVR5cGUuTGluZSwgY291bnQgKiAyKTtcblx0XHRpZiAoIWNvbG9yKSBjb2xvciA9IHRoaXMuY29sb3I7XG5cdFx0bGV0IHZlcnRpY2VzID0gdGhpcy5tZXNoLmdldFZlcnRpY2VzKCk7XG5cdFx0bGV0IGlkeCA9IHRoaXMudmVydGV4SW5kZXg7XG5cblx0XHRvZmZzZXQgPDw9IDE7XG5cdFx0Y291bnQgPDw9IDE7XG5cblx0XHRsZXQgZmlyc3RYID0gcG9seWdvblZlcnRpY2VzW29mZnNldF07XG5cdFx0bGV0IGZpcnN0WSA9IHBvbHlnb25WZXJ0aWNlc1tvZmZzZXQgKyAxXTtcblx0XHRsZXQgbGFzdCA9IG9mZnNldCArIGNvdW50O1xuXG5cdFx0Zm9yIChsZXQgaSA9IG9mZnNldCwgbiA9IG9mZnNldCArIGNvdW50IC0gMjsgaSA8IG47IGkgKz0gMikge1xuXHRcdFx0bGV0IHgxID0gcG9seWdvblZlcnRpY2VzW2ldO1xuXHRcdFx0bGV0IHkxID0gcG9seWdvblZlcnRpY2VzW2kgKyAxXTtcblxuXHRcdFx0bGV0IHgyID0gMDtcblx0XHRcdGxldCB5MiA9IDA7XG5cblx0XHRcdGlmIChpICsgMiA+PSBsYXN0KSB7XG5cdFx0XHRcdHgyID0gZmlyc3RYO1xuXHRcdFx0XHR5MiA9IGZpcnN0WTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHgyID0gcG9seWdvblZlcnRpY2VzW2kgKyAyXTtcblx0XHRcdFx0eTIgPSBwb2x5Z29uVmVydGljZXNbaSArIDNdO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnZlcnRleCh4MSwgeTEsIGNvbG9yISk7XG5cdFx0XHR0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yISk7XG5cdFx0fVxuXHR9XG5cblx0Y2lyY2xlIChmaWxsZWQ6IGJvb2xlYW4sIHg6IG51bWJlciwgeTogbnVtYmVyLCByYWRpdXM6IG51bWJlciwgY29sb3I/OiBDb2xvciwgc2VnbWVudHM6IG51bWJlciA9IDApIHtcblx0XHRpZiAoc2VnbWVudHMgPT0gMCkgc2VnbWVudHMgPSBNYXRoLm1heCgxLCAoNiAqIE1hdGhVdGlscy5jYnJ0KHJhZGl1cykpIHwgMCk7XG5cdFx0aWYgKHNlZ21lbnRzIDw9IDApIHRocm93IG5ldyBFcnJvcihcInNlZ21lbnRzIG11c3QgYmUgPiAwLlwiKTtcblx0XHRpZiAoIWNvbG9yKSBjb2xvciA9IHRoaXMuY29sb3I7XG5cdFx0bGV0IGFuZ2xlID0gMiAqIE1hdGhVdGlscy5QSSAvIHNlZ21lbnRzO1xuXHRcdGxldCBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG5cdFx0bGV0IHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcblx0XHRsZXQgY3ggPSByYWRpdXMsIGN5ID0gMDtcblx0XHRpZiAoIWZpbGxlZCkge1xuXHRcdFx0dGhpcy5jaGVjayhTaGFwZVR5cGUuTGluZSwgc2VnbWVudHMgKiAyICsgMik7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHNlZ21lbnRzOyBpKyspIHtcblx0XHRcdFx0dGhpcy52ZXJ0ZXgoeCArIGN4LCB5ICsgY3ksIGNvbG9yKTtcblx0XHRcdFx0bGV0IHRlbXAgPSBjeDtcblx0XHRcdFx0Y3ggPSBjb3MgKiBjeCAtIHNpbiAqIGN5O1xuXHRcdFx0XHRjeSA9IHNpbiAqIHRlbXAgKyBjb3MgKiBjeTtcblx0XHRcdFx0dGhpcy52ZXJ0ZXgoeCArIGN4LCB5ICsgY3ksIGNvbG9yKTtcblx0XHRcdH1cblx0XHRcdC8vIEVuc3VyZSB0aGUgbGFzdCBzZWdtZW50IGlzIGlkZW50aWNhbCB0byB0aGUgZmlyc3QuXG5cdFx0XHR0aGlzLnZlcnRleCh4ICsgY3gsIHkgKyBjeSwgY29sb3IpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmNoZWNrKFNoYXBlVHlwZS5GaWxsZWQsIHNlZ21lbnRzICogMyArIDMpO1xuXHRcdFx0c2VnbWVudHMtLTtcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHM7IGkrKykge1xuXHRcdFx0XHR0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XG5cdFx0XHRcdHRoaXMudmVydGV4KHggKyBjeCwgeSArIGN5LCBjb2xvcik7XG5cdFx0XHRcdGxldCB0ZW1wID0gY3g7XG5cdFx0XHRcdGN4ID0gY29zICogY3ggLSBzaW4gKiBjeTtcblx0XHRcdFx0Y3kgPSBzaW4gKiB0ZW1wICsgY29zICogY3k7XG5cdFx0XHRcdHRoaXMudmVydGV4KHggKyBjeCwgeSArIGN5LCBjb2xvcik7XG5cdFx0XHR9XG5cdFx0XHQvLyBFbnN1cmUgdGhlIGxhc3Qgc2VnbWVudCBpcyBpZGVudGljYWwgdG8gdGhlIGZpcnN0LlxuXHRcdFx0dGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xuXHRcdFx0dGhpcy52ZXJ0ZXgoeCArIGN4LCB5ICsgY3ksIGNvbG9yKTtcblx0XHR9XG5cblx0XHRsZXQgdGVtcCA9IGN4O1xuXHRcdGN4ID0gcmFkaXVzO1xuXHRcdGN5ID0gMDtcblx0XHR0aGlzLnZlcnRleCh4ICsgY3gsIHkgKyBjeSwgY29sb3IpO1xuXHR9XG5cblx0Y3VydmUgKHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIGN4MTogbnVtYmVyLCBjeTE6IG51bWJlciwgY3gyOiBudW1iZXIsIGN5MjogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCBzZWdtZW50czogbnVtYmVyLCBjb2xvcj86IENvbG9yKSB7XG5cdFx0dGhpcy5jaGVjayhTaGFwZVR5cGUuTGluZSwgc2VnbWVudHMgKiAyICsgMik7XG5cdFx0aWYgKCFjb2xvcikgY29sb3IgPSB0aGlzLmNvbG9yO1xuXG5cdFx0Ly8gQWxnb3JpdGhtIGZyb206IGh0dHA6Ly93d3cuYW50aWdyYWluLmNvbS9yZXNlYXJjaC9iZXppZXJfaW50ZXJwb2xhdGlvbi9pbmRleC5odG1sI1BBR0VfQkVaSUVSX0lOVEVSUE9MQVRJT05cblx0XHRsZXQgc3ViZGl2X3N0ZXAgPSAxIC8gc2VnbWVudHM7XG5cdFx0bGV0IHN1YmRpdl9zdGVwMiA9IHN1YmRpdl9zdGVwICogc3ViZGl2X3N0ZXA7XG5cdFx0bGV0IHN1YmRpdl9zdGVwMyA9IHN1YmRpdl9zdGVwICogc3ViZGl2X3N0ZXAgKiBzdWJkaXZfc3RlcDtcblxuXHRcdGxldCBwcmUxID0gMyAqIHN1YmRpdl9zdGVwO1xuXHRcdGxldCBwcmUyID0gMyAqIHN1YmRpdl9zdGVwMjtcblx0XHRsZXQgcHJlNCA9IDYgKiBzdWJkaXZfc3RlcDI7XG5cdFx0bGV0IHByZTUgPSA2ICogc3ViZGl2X3N0ZXAzO1xuXG5cdFx0bGV0IHRtcDF4ID0geDEgLSBjeDEgKiAyICsgY3gyO1xuXHRcdGxldCB0bXAxeSA9IHkxIC0gY3kxICogMiArIGN5MjtcblxuXHRcdGxldCB0bXAyeCA9IChjeDEgLSBjeDIpICogMyAtIHgxICsgeDI7XG5cdFx0bGV0IHRtcDJ5ID0gKGN5MSAtIGN5MikgKiAzIC0geTEgKyB5MjtcblxuXHRcdGxldCBmeCA9IHgxO1xuXHRcdGxldCBmeSA9IHkxO1xuXG5cdFx0bGV0IGRmeCA9IChjeDEgLSB4MSkgKiBwcmUxICsgdG1wMXggKiBwcmUyICsgdG1wMnggKiBzdWJkaXZfc3RlcDM7XG5cdFx0bGV0IGRmeSA9IChjeTEgLSB5MSkgKiBwcmUxICsgdG1wMXkgKiBwcmUyICsgdG1wMnkgKiBzdWJkaXZfc3RlcDM7XG5cblx0XHRsZXQgZGRmeCA9IHRtcDF4ICogcHJlNCArIHRtcDJ4ICogcHJlNTtcblx0XHRsZXQgZGRmeSA9IHRtcDF5ICogcHJlNCArIHRtcDJ5ICogcHJlNTtcblxuXHRcdGxldCBkZGRmeCA9IHRtcDJ4ICogcHJlNTtcblx0XHRsZXQgZGRkZnkgPSB0bXAyeSAqIHByZTU7XG5cblx0XHR3aGlsZSAoc2VnbWVudHMtLSA+IDApIHtcblx0XHRcdHRoaXMudmVydGV4KGZ4LCBmeSwgY29sb3IhKTtcblx0XHRcdGZ4ICs9IGRmeDtcblx0XHRcdGZ5ICs9IGRmeTtcblx0XHRcdGRmeCArPSBkZGZ4O1xuXHRcdFx0ZGZ5ICs9IGRkZnk7XG5cdFx0XHRkZGZ4ICs9IGRkZGZ4O1xuXHRcdFx0ZGRmeSArPSBkZGRmeTtcblx0XHRcdHRoaXMudmVydGV4KGZ4LCBmeSwgY29sb3IhKTtcblx0XHR9XG5cdFx0dGhpcy52ZXJ0ZXgoZngsIGZ5LCBjb2xvciEpO1xuXHRcdHRoaXMudmVydGV4KHgyLCB5MiwgY29sb3IhKTtcblx0fVxuXG5cdHByaXZhdGUgdmVydGV4ICh4OiBudW1iZXIsIHk6IG51bWJlciwgY29sb3I6IENvbG9yKSB7XG5cdFx0bGV0IGlkeCA9IHRoaXMudmVydGV4SW5kZXg7XG5cdFx0bGV0IHZlcnRpY2VzID0gdGhpcy5tZXNoLmdldFZlcnRpY2VzKCk7XG5cdFx0dmVydGljZXNbaWR4KytdID0geDtcblx0XHR2ZXJ0aWNlc1tpZHgrK10gPSB5O1xuXHRcdHZlcnRpY2VzW2lkeCsrXSA9IGNvbG9yLnI7XG5cdFx0dmVydGljZXNbaWR4KytdID0gY29sb3IuZztcblx0XHR2ZXJ0aWNlc1tpZHgrK10gPSBjb2xvci5iO1xuXHRcdHZlcnRpY2VzW2lkeCsrXSA9IGNvbG9yLmE7XG5cdFx0dGhpcy52ZXJ0ZXhJbmRleCA9IGlkeDtcblx0fVxuXG5cdGVuZCAoKSB7XG5cdFx0aWYgKCF0aGlzLmlzRHJhd2luZykgdGhyb3cgbmV3IEVycm9yKFwiU2hhcGVSZW5kZXJlci5iZWdpbigpIGhhcyBub3QgYmVlbiBjYWxsZWRcIik7XG5cdFx0dGhpcy5mbHVzaCgpO1xuXHRcdGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcblx0XHRnbC5kaXNhYmxlKGdsLkJMRU5EKTtcblx0XHR0aGlzLmlzRHJhd2luZyA9IGZhbHNlO1xuXHR9XG5cblx0cHJpdmF0ZSBmbHVzaCAoKSB7XG5cdFx0aWYgKHRoaXMudmVydGV4SW5kZXggPT0gMCkgcmV0dXJuO1xuXHRcdGlmICghdGhpcy5zaGFkZXIpIHRocm93IG5ldyBFcnJvcihcIk5vIHNoYWRlciBzZXQuXCIpO1xuXHRcdHRoaXMubWVzaC5zZXRWZXJ0aWNlc0xlbmd0aCh0aGlzLnZlcnRleEluZGV4KTtcblx0XHR0aGlzLm1lc2guZHJhdyh0aGlzLnNoYWRlciwgdGhpcy5zaGFwZVR5cGUpO1xuXHRcdHRoaXMudmVydGV4SW5kZXggPSAwO1xuXHR9XG5cblx0cHJpdmF0ZSBjaGVjayAoc2hhcGVUeXBlOiBTaGFwZVR5cGUsIG51bVZlcnRpY2VzOiBudW1iZXIpIHtcblx0XHRpZiAoIXRoaXMuaXNEcmF3aW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJTaGFwZVJlbmRlcmVyLmJlZ2luKCkgaGFzIG5vdCBiZWVuIGNhbGxlZFwiKTtcblx0XHRpZiAodGhpcy5zaGFwZVR5cGUgPT0gc2hhcGVUeXBlKSB7XG5cdFx0XHRpZiAodGhpcy5tZXNoLm1heFZlcnRpY2VzKCkgLSB0aGlzLm1lc2gubnVtVmVydGljZXMoKSA8IG51bVZlcnRpY2VzKSB0aGlzLmZsdXNoKCk7XG5cdFx0XHRlbHNlIHJldHVybjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5mbHVzaCgpO1xuXHRcdFx0dGhpcy5zaGFwZVR5cGUgPSBzaGFwZVR5cGU7XG5cdFx0fVxuXHR9XG5cblx0ZGlzcG9zZSAoKSB7XG5cdFx0dGhpcy5tZXNoLmRpc3Bvc2UoKTtcblx0fVxufVxuXG5leHBvcnQgZW51bSBTaGFwZVR5cGUge1xuXHRQb2ludCA9IDB4MDAwMCxcblx0TGluZSA9IDB4MDAwMSxcblx0RmlsbGVkID0gMHgwMDA0XG59XG4iXX0=