UNPKG

ngx-spine

Version:

[![Build Status](https://travis-ci.org/PoiScript/ngx-spine.svg?branch=master)](https://travis-ci.org/PoiScript/ngx-spine)

592 lines 55 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /****************************************************************************** * Spine Runtimes License Agreement * Last updated May 1, 2019. Replaces all prior versions. * * Copyright (c) 2013-2019, 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. * * THIS SOFTWARE IS 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 THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ import { ManagedWebGLRenderingContext } from "./WebGL"; import { Mesh, ColorAttribute, Position2Attribute } from "./Mesh"; import { Color, Vector2, MathUtils } from "../core/Utils"; export class ShapeRenderer { /** * @param {?} context * @param {?=} maxVertices */ constructor(context, maxVertices = 10920) { this.isDrawing = false; this.shapeType = ShapeType.Filled; this.color = new Color(1, 1, 1, 1); this.vertexIndex = 0; this.tmp = new Vector2(); 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); this.srcBlend = this.context.gl.SRC_ALPHA; this.dstBlend = this.context.gl.ONE_MINUS_SRC_ALPHA; } /** * @param {?} shader * @return {?} */ begin(shader) { if (this.isDrawing) throw new Error("ShapeRenderer.begin() has already been called"); this.shader = shader; this.vertexIndex = 0; this.isDrawing = true; /** @type {?} */ let gl = this.context.gl; gl.enable(gl.BLEND); gl.blendFunc(this.srcBlend, this.dstBlend); } /** * @param {?} srcBlend * @param {?} dstBlend * @return {?} */ setBlendMode(srcBlend, dstBlend) { /** @type {?} */ let gl = this.context.gl; this.srcBlend = srcBlend; this.dstBlend = dstBlend; if (this.isDrawing) { this.flush(); gl.blendFunc(this.srcBlend, this.dstBlend); } } /** * @param {?} color * @return {?} */ setColor(color) { this.color.setFromColor(color); } /** * @param {?} r * @param {?} g * @param {?} b * @param {?} a * @return {?} */ setColorWith(r, g, b, a) { this.color.set(r, g, b, a); } /** * @param {?} x * @param {?} y * @param {?=} color * @return {?} */ point(x, y, color = null) { this.check(ShapeType.Point, 1); if (color === null) color = this.color; this.vertex(x, y, color); } /** * @param {?} x * @param {?} y * @param {?} x2 * @param {?} y2 * @param {?=} color * @return {?} */ line(x, y, x2, y2, color = null) { this.check(ShapeType.Line, 2); /** @type {?} */ let vertices = this.mesh.getVertices(); /** @type {?} */ let idx = this.vertexIndex; if (color === null) color = this.color; this.vertex(x, y, color); this.vertex(x2, y2, color); } /** * @param {?} filled * @param {?} x * @param {?} y * @param {?} x2 * @param {?} y2 * @param {?} x3 * @param {?} y3 * @param {?=} color * @param {?=} color2 * @param {?=} color3 * @return {?} */ triangle(filled, x, y, x2, y2, x3, y3, color = null, color2 = null, color3 = null) { this.check(filled ? ShapeType.Filled : ShapeType.Line, 3); /** @type {?} */ let vertices = this.mesh.getVertices(); /** @type {?} */ let idx = this.vertexIndex; if (color === null) color = this.color; if (color2 === null) color2 = this.color; if (color3 === null) 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); } } /** * @param {?} filled * @param {?} x * @param {?} y * @param {?} x2 * @param {?} y2 * @param {?} x3 * @param {?} y3 * @param {?} x4 * @param {?} y4 * @param {?=} color * @param {?=} color2 * @param {?=} color3 * @param {?=} color4 * @return {?} */ quad(filled, x, y, x2, y2, x3, y3, x4, y4, color = null, color2 = null, color3 = null, color4 = null) { this.check(filled ? ShapeType.Filled : ShapeType.Line, 3); /** @type {?} */ let vertices = this.mesh.getVertices(); /** @type {?} */ let idx = this.vertexIndex; if (color === null) color = this.color; if (color2 === null) color2 = this.color; if (color3 === null) color3 = this.color; if (color4 === null) 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); } } /** * @param {?} filled * @param {?} x * @param {?} y * @param {?} width * @param {?} height * @param {?=} color * @return {?} */ rect(filled, x, y, width, height, color = null) { this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color); } /** * @param {?} filled * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @param {?} width * @param {?=} color * @return {?} */ rectLine(filled, x1, y1, x2, y2, width, color = null) { this.check(filled ? ShapeType.Filled : ShapeType.Line, 8); if (color === null) color = this.color; /** @type {?} */ let t = this.tmp.set(y2 - y1, x1 - x2); t.normalize(); width *= 0.5; /** @type {?} */ let tx = t.x * width; /** @type {?} */ 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); } } /** * @param {?} x * @param {?} y * @param {?} size * @return {?} */ x(x, y, size) { this.line(x - size, y - size, x + size, y + size); this.line(x - size, y + size, x + size, y - size); } /** * @param {?} polygonVertices * @param {?} offset * @param {?} count * @param {?=} color * @return {?} */ polygon(polygonVertices, offset, count, color = null) { if (count < 3) throw new Error("Polygon must contain at least 3 vertices"); this.check(ShapeType.Line, count * 2); if (color === null) color = this.color; /** @type {?} */ let vertices = this.mesh.getVertices(); /** @type {?} */ let idx = this.vertexIndex; offset <<= 1; count <<= 1; /** @type {?} */ let firstX = polygonVertices[offset]; /** @type {?} */ let firstY = polygonVertices[offset + 1]; /** @type {?} */ let last = offset + count; for (let i = offset, n = offset + count - 2; i < n; i += 2) { /** @type {?} */ let x1 = polygonVertices[i]; /** @type {?} */ let y1 = polygonVertices[i + 1]; /** @type {?} */ let x2 = 0; /** @type {?} */ 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); } } /** * @param {?} filled * @param {?} x * @param {?} y * @param {?} radius * @param {?=} color * @param {?=} segments * @return {?} */ circle(filled, x, y, radius, color = null, 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 === null) color = this.color; /** @type {?} */ let angle = (2 * MathUtils.PI) / segments; /** @type {?} */ let cos = Math.cos(angle); /** @type {?} */ let sin = Math.sin(angle); /** @type {?} */ let cx = radius; /** @type {?} */ let 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); /** @type {?} */ 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); /** @type {?} */ 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); } /** @type {?} */ let temp = cx; cx = radius; cy = 0; this.vertex(x + cx, y + cy, color); } /** * @param {?} x1 * @param {?} y1 * @param {?} cx1 * @param {?} cy1 * @param {?} cx2 * @param {?} cy2 * @param {?} x2 * @param {?} y2 * @param {?} segments * @param {?=} color * @return {?} */ curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color = null) { this.check(ShapeType.Line, segments * 2 + 2); if (color === null) color = this.color; // Algorithm from: http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION /** @type {?} */ let subdiv_step = 1 / segments; /** @type {?} */ let subdiv_step2 = subdiv_step * subdiv_step; /** @type {?} */ let subdiv_step3 = subdiv_step * subdiv_step * subdiv_step; /** @type {?} */ let pre1 = 3 * subdiv_step; /** @type {?} */ let pre2 = 3 * subdiv_step2; /** @type {?} */ let pre4 = 6 * subdiv_step2; /** @type {?} */ let pre5 = 6 * subdiv_step3; /** @type {?} */ let tmp1x = x1 - cx1 * 2 + cx2; /** @type {?} */ let tmp1y = y1 - cy1 * 2 + cy2; /** @type {?} */ let tmp2x = (cx1 - cx2) * 3 - x1 + x2; /** @type {?} */ let tmp2y = (cy1 - cy2) * 3 - y1 + y2; /** @type {?} */ let fx = x1; /** @type {?} */ let fy = y1; /** @type {?} */ let dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; /** @type {?} */ let dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; /** @type {?} */ let ddfx = tmp1x * pre4 + tmp2x * pre5; /** @type {?} */ let ddfy = tmp1y * pre4 + tmp2y * pre5; /** @type {?} */ let dddfx = tmp2x * pre5; /** @type {?} */ 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); } /** * @private * @param {?} x * @param {?} y * @param {?} color * @return {?} */ vertex(x, y, color) { /** @type {?} */ let idx = this.vertexIndex; /** @type {?} */ 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; } /** * @return {?} */ end() { if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called"); this.flush(); this.context.gl.disable(this.context.gl.BLEND); this.isDrawing = false; } /** * @private * @return {?} */ flush() { if (this.vertexIndex == 0) return; this.mesh.setVerticesLength(this.vertexIndex); this.mesh.draw(this.shader, this.shapeType); this.vertexIndex = 0; } /** * @private * @param {?} shapeType * @param {?} numVertices * @return {?} */ 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; } } /** * @return {?} */ dispose() { this.mesh.dispose(); } } if (false) { /** * @type {?} * @private */ ShapeRenderer.prototype.context; /** * @type {?} * @private */ ShapeRenderer.prototype.isDrawing; /** * @type {?} * @private */ ShapeRenderer.prototype.mesh; /** * @type {?} * @private */ ShapeRenderer.prototype.shapeType; /** * @type {?} * @private */ ShapeRenderer.prototype.color; /** * @type {?} * @private */ ShapeRenderer.prototype.shader; /** * @type {?} * @private */ ShapeRenderer.prototype.vertexIndex; /** * @type {?} * @private */ ShapeRenderer.prototype.tmp; /** * @type {?} * @private */ ShapeRenderer.prototype.srcBlend; /** * @type {?} * @private */ ShapeRenderer.prototype.dstBlend; } /** @enum {number} */ const ShapeType = { Point: 0, Line: 1, Filled: 4, }; export { ShapeType }; ShapeType[ShapeType.Point] = 'Point'; ShapeType[ShapeType.Line] = 'Line'; ShapeType[ShapeType.Filled] = 'Filled'; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2hhcGVSZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1zcGluZS8iLCJzb3VyY2VzIjpbImxpYi9zcGluZS10cy93ZWJnbC9TaGFwZVJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNEJBLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2RCxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNsRSxPQUFPLEVBQWMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHdEUsTUFBTSxPQUFPLGFBQWE7Ozs7O0lBV3hCLFlBQ0UsT0FBNkQsRUFDN0QsY0FBc0IsS0FBSztRQVhyQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRWxCLGNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQzdCLFVBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUU5QixnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUNoQixRQUFHLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQU8xQixJQUFJLFdBQVcsR0FBRyxLQUFLO1lBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQ2Isa0RBQWtELEdBQUcsV0FBVyxDQUNqRSxDQUFDO1FBQ0osSUFBSSxDQUFDLE9BQU87WUFDVixPQUFPLFlBQVksNEJBQTRCO2dCQUM3QyxDQUFDLENBQUMsT0FBTztnQkFDVCxDQUFDLENBQUMsSUFBSSw0QkFBNEIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUNsQixPQUFPLEVBQ1AsQ0FBQyxJQUFJLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxjQUFjLEVBQUUsQ0FBQyxFQUNoRCxXQUFXLEVBQ1gsQ0FBQyxDQUNGLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQztRQUMxQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDO0lBQ3RELENBQUM7Ozs7O0lBQ0QsS0FBSyxDQUFDLE1BQWM7UUFDbEIsSUFBSSxJQUFJLENBQUMsU0FBUztZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUM7UUFDbkUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7O1lBQ2xCLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDeEIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM3QyxDQUFDOzs7Ozs7SUFDRCxZQUFZLENBQUMsUUFBZ0IsRUFBRSxRQUFnQjs7WUFDekMsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbEIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2IsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUM1QztJQUNILENBQUM7Ozs7O0lBQ0QsUUFBUSxDQUFDLEtBQVk7UUFDbkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQzs7Ozs7Ozs7SUFDRCxZQUFZLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxDQUFTLEVBQUUsQ0FBUztRQUNyRCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM3QixDQUFDOzs7Ozs7O0lBQ0QsS0FBSyxDQUFDLENBQVMsRUFBRSxDQUFTLEVBQUUsUUFBZSxJQUFJO1FBQzdDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQixJQUFJLEtBQUssS0FBSyxJQUFJO1lBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzNCLENBQUM7Ozs7Ozs7OztJQUNELElBQUksQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQVUsRUFBRSxFQUFVLEVBQUUsUUFBZSxJQUFJO1FBQ3BFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQzs7WUFDMUIsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFOztZQUNsQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVc7UUFDMUIsSUFBSSxLQUFLLEtBQUssSUFBSTtZQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDN0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7SUFDRCxRQUFRLENBQ04sTUFBZSxFQUNmLENBQVMsRUFDVCxDQUFTLEVBQ1QsRUFBVSxFQUNWLEVB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QzVCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUMxQjthQUFNO1lBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUMxQjtJQUNILENBQUM7Ozs7Ozs7Ozs7SUFDRCxJQUFJLENBQ0YsTUFBZSxFQUNmLENBQVMsRUFDVCxDQUFTLEVBQ1QsS0FBYSxFQUNiLE1BQWMsRUFDZCxRQUFlLElBQUk7UUFFbkIsSUFBSSxDQUFDLElBQUksQ0FDUCxNQUFNLEVBQ04sQ0FBQyxFQUNELENBQUMsRUFDRCxDQUFDLEdBQUcsS0FBSyxFQUNULENBQUMsRUFDRCxDQUFDLEdBQUcsS0FBSyxFQUNULENBQUMsR0FBRyxNQUFNLEVBQ1YsQ0FBQyxFQUNELENBQUMsR0FBRyxNQUFNLEVBQ1YsS0FBSyxFQUNMLEtBQUssRUFDTCxLQUFLLEVBQ0wsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDOzs7Ozs7Ozs7OztJQUNELFFBQVEsQ0FDTixNQUFlLEVBQ2YsRUFBVSxFQUNWLEVBQVUsRUFDVixFQUFVLEVBQ1YsRUFBVSxFQUNWLEtBQWEsRUFDYixRQUFlLElBQUk7UUFFbkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUQsSUFBSSxLQUFLLEtBQUssSUFBSTtZQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDOztZQUNuQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNkLEtBQUssSUFBSSxHQUFHLENBQUM7O1lBQ1QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSzs7WUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSztRQUNwQixJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDdEM7YUFBTTtZQUNMLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtB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QVEsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0MsSUFBSSxLQUFLLEtBQUssSUFBSTtZQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDOzs7WUFFbkMsV0FBVyxHQUFHLENBQUMsR0FBRyxRQUFROztZQUMxQixZQUFZLEdBQUcsV0FBVyxHQUFHLFdBQVc7O1lBQ3hDLFlBQVksR0FBRyxXQUFXLEdBQUcsV0FBVyxHQUFHLFdBQVc7O1lBQ3RELElBQUksR0FBRyxDQUFDLEdBQUcsV0FBVzs7WUFDdEIsSUFBSSxHQUFHLENBQUMsR0FBRyxZQUFZOztZQUN2QixJQUFJLEdBQUcsQ0FBQyxHQUFHLFlBQVk7O1lBQ3ZCLElBQUksR0FBRyxDQUFDLEdBQUcsWUFBWTs7WUFDdkIsS0FBSyxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUc7O1lBQzFCLEtBQUssR0FBRyxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHOztZQUMxQixLQUFLLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFOztZQUNqQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFOztZQUNqQyxFQUFFLEdBQUcsRUFBRTs7WUFDUCxFQUFFLEdBQUcsRUFBRTs7WUFDUCxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLFlBQVk7O1lBQzdELEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsWUFBWTs7WUFDN0QsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUk7O1lBQ2xDLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FB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QU07WUFDTCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztTQUM1QjtJQUNILENBQUM7Ozs7SUFDRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN0QixDQUFDO0NBQ0Y7Ozs7OztJQWhYQyxnQ0FBOEM7Ozs7O0lBQzlDLGtDQUEwQjs7Ozs7SUFDMUIsNkJBQW1COzs7OztJQUNuQixrQ0FBcUM7Ozs7O0lBQ3JDLDhCQUFzQzs7Ozs7SUFDdEMsK0JBQXVCOzs7OztJQUN2QixvQ0FBd0I7Ozs7O0lBQ3hCLDRCQUE0Qjs7Ozs7SUFDNUIsaUNBQXlCOzs7OztJQUN6QixpQ0FBeUI7Ozs7SUF5V3pCLFFBQWM7SUFDZCxPQUFhO0lBQ2IsU0FBZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcclxuICogTGFzdCB1cGRhdGVkIE1heSAxLCAyMDE5LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE5LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcclxuICpcclxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXHJcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXHJcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XHJcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxyXG4gKlxyXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcclxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxyXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXHJcbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxyXG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTU1xyXG4gKiBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTXHJcbiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOXHJcbiAqIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULFxyXG4gKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLFxyXG4gKiBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsIEJVU0lORVNTXHJcbiAqIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTllcclxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HXHJcbiAqIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSxcclxuICogRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cclxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG5pbXBvcnQgeyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0IH0gZnJvbSBcIi4vV2ViR0xcIjtcclxuaW1wb3J0IHsgTWVzaCwgQ29sb3JBdHRyaWJ1dGUsIFBvc2l0aW9uMkF0dHJpYnV0ZSB9IGZyb20gXCIuL01lc2hcIjtcclxuaW1wb3J0IHsgRGlzcG9zYWJsZSwgQ29sb3IsIFZlY3RvcjIsIE1hdGhVdGlscyB9IGZyb20gXCIuLi9jb3JlL1V0aWxzXCI7XHJcbmltcG9ydCB7IFNoYWRlciB9IGZyb20gXCIuL1NoYWRlclwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNoYXBlUmVuZGVyZXIgaW1wbGVtZW50cyBEaXNwb3NhYmxlIHtcclxuICBwcml2YXRlIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XHJcbiAgcHJpdmF0ZSBpc0RyYXdpbmcgPSBmYWxzZTtcclxuICBwcml2YXRlIG1lc2g6IE1lc2g7XHJcbiAgcHJpdmF0ZSBzaGFwZVR5cGUgPSBTaGFwZVR5cGUuRmlsbGVkO1xyXG4gIHByaXZhdGUgY29sb3IgPSBuZXcgQ29sb3IoMSwgMSwgMSwgMSk7XHJcbiAgcHJpdmF0ZSBzaGFkZXI6IFNoYWRlcjtcclxuICBwcml2YXRlIHZlcnRleEluZGV4ID0gMDtcclxuICBwcml2YXRlIHRtcCA9IG5ldyBWZWN0b3IyKCk7XHJcbiAgcHJpdmF0ZSBzcmNCbGVuZDogbnVtYmVyO1xyXG4gIHByaXZhdGUgZHN0QmxlbmQ6IG51bWJlcjtcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBXZWJHTFJlbmRlcmluZ0NvbnRleHQsXHJcbiAgICBtYXhWZXJ0aWNlczogbnVtYmVyID0gMTA5MjBcclxuICApIHtcclxuICAgIGlmIChtYXhWZXJ0aWNlcyA+IDEwOTIwKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgXCJDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMDkyMCB0cmlhbmdsZXMgcGVyIGJhdGNoOiBcIiArIG1heFZlcnRpY2VzXHJcbiAgICAgICk7XHJcbiAgICB0aGlzLmNvbnRleHQgPVxyXG4gICAgICBjb250ZXh0IGluc3RhbmNlb2YgTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dFxyXG4gICAgICAgID8gY29udGV4dFxyXG4gICAgICAgIDogbmV3IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQoY29udGV4dCk7XHJcbiAgICB0aGlzLm1lc2ggPSBuZXcgTWVzaChcclxuICAgICAgY29udGV4dCxcclxuICAgICAgW25ldyBQb3NpdGlvbjJBdHRyaWJ1dGUoKSwgbmV3IENvbG9yQXR0cmlidXRlKCldLFxyXG4gICAgICBtYXhWZXJ0aWNlcyxcclxuICAgICAgMFxyXG4gICAgKTtcclxuICAgIHRoaXMuc3JjQmxlbmQgPSB0aGlzLmNvbnRleHQuZ2wuU1JDX0FMUEhBO1xyXG4gICAgdGhpcy5kc3RCbGVuZCA9IHRoaXMuY29udGV4dC5nbC5PTkVfTUlOVVNfU1JDX0FMUEhBO1xyXG4gIH1cclxuICBiZWdpbihzaGFkZXI6IFNoYWRlcikge1xyXG4gICAgaWYgKHRoaXMuaXNEcmF3aW5nKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTaGFwZVJlbmRlcmVyLmJlZ2luKCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWRcIik7XHJcbiAgICB0aGlzLnNoYWRlciA9IHNoYWRlcjtcclxuICAgIHRoaXMudmVydGV4SW5kZXggPSAwO1xyXG4gICAgdGhpcy5pc0RyYXdpbmcgPSB0cnVlO1xyXG4gICAgbGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xyXG4gICAgZ2wuZW5hYmxlKGdsLkJMRU5EKTtcclxuICAgIGdsLmJsZW5kRnVuYyh0aGlzLnNyY0JsZW5kLCB0aGlzLmRzdEJsZW5kKTtcclxuICB9XHJcbiAgc2V0QmxlbmRNb2RlKHNyY0JsZW5kOiBudW1iZXIsIGRzdEJsZW5kOiBudW1iZXIpIHtcclxuICAgIGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcclxuICAgIHRoaXMuc3JjQmxlbmQgPSBzcmNCbGVuZDtcclxuICAgIHRoaXMuZHN0QmxlbmQgPSBkc3RCbGVuZDtcclxuICAgIGlmICh0aGlzLmlzRHJhd2luZykge1xyXG4gICAgICB0aGlzLmZsdXNoKCk7XHJcbiAgICAgIGdsLmJsZW5kRnVuYyh0aGlzLnNyY0JsZW5kLCB0aGlzLmRzdEJsZW5kKTtcclxuICAgIH1cclxuICB9XHJcbiAgc2V0Q29sb3IoY29sb3I6IENvbG9yKSB7XHJcbiAgICB0aGlzLmNvbG9yLnNldEZyb21Db2xvcihjb2xvcik7XHJcbiAgfVxyXG4gIHNldENvbG9yV2l0aChyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyLCBhOiBudW1iZXIpIHtcclxuICAgIHRoaXMuY29sb3Iuc2V0KHIsIGcsIGIsIGEpO1xyXG4gIH1cclxuICBwb2ludCh4OiBudW1iZXIsIHk6IG51bWJlciwgY29sb3I6IENvbG9yID0gbnVsbCkge1xyXG4gICAgdGhpcy5jaGVjayhTaGFwZVR5cGUuUG9pbnQsIDEpO1xyXG4gICAgaWYgKGNvbG9yID09PSBudWxsKSBjb2xvciA9IHRoaXMuY29sb3I7XHJcbiAgICB0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XHJcbiAgfVxyXG4gIGxpbmUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIGNvbG9yOiBDb2xvciA9IG51bGwpIHtcclxuICAgIHRoaXMuY2hlY2soU2hhcGVUeXBlLkxpbmUsIDIpO1xyXG4gICAgbGV0IHZlcnRpY2VzID0gdGhpcy5tZXNoLmdldFZlcnRpY2VzKCk7XHJcbiAgICBsZXQgaWR4ID0gdGhpcy52ZXJ0ZXhJbmRleDtcclxuICAgIGlmIChjb2xvciA9PT0gbnVsbCkgY29sb3IgPSB0aGlzLmNvbG9yO1xyXG4gICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgdGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcik7XHJcbiAgfVxyXG4gIHRyaWFuZ2xlKFxyXG4gICAgZmlsbGVkOiBib29sZWFuLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxyXG4gICAgeDI6IG51bWJlcixcclxuICAgIHkyOiBudW1iZXIsXHJcbiAgICB4MzogbnVtYmVyLFxyXG4gICAgeTM6IG51bWJlcixcclxuICAgIGNvbG9yOiBDb2xvciA9IG51bGwsXHJcbiAgICBjb2xvcjI6IENvbG9yID0gbnVsbCxcclxuICAgIGNvbG9yMzogQ29sb3IgPSBudWxsXHJcbiAgKSB7XHJcbiAgICB0aGlzLmNoZWNrKGZpbGxlZCA/IFNoYXBlVHlwZS5GaWxsZWQgOiBTaGFwZVR5cGUuTGluZSwgMyk7XHJcbiAgICBsZXQgdmVydGljZXMgPSB0aGlzLm1lc2guZ2V0VmVydGljZXMoKTtcclxuICAgIGxldCBpZHggPSB0aGlzLnZlcnRleEluZGV4O1xyXG4gICAgaWYgKGNvbG9yID09PSBudWxsKSBjb2xvciA9IHRoaXMuY29sb3I7XHJcbiAgICBpZiAoY29sb3IyID09PSBudWxsKSBjb2xvcjIgPSB0aGlzLmNvbG9yO1xyXG4gICAgaWYgKGNvbG9yMyA9PT0gbnVsbCkgY29sb3IzID0gdGhpcy5jb2xvcjtcclxuICAgIGlmIChmaWxsZWQpIHtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcjIpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjIpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MywgeTMsIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IyKTtcclxuICAgIH1cclxuICB9XHJcbiAgcXVhZChcclxuICAgIGZpbGxlZDogYm9vbGVhbixcclxuICAgIHg6IG51bWJlcixcclxuICAgIHk6IG51bWJlcixcclxuICAgIHgyOiBudW1iZXIsXHJcbiAgICB5MjogbnVtYmVyLFxyXG4gICAgeDM6IG51bWJlcixcclxuICAgIHkzOiBudW1iZXIsXHJcbiAgICB4NDogbnVtYmVyLFxyXG4gICAgeTQ6IG51bWJlcixcclxuICAgIGNvbG9yOiBDb2xvciA9IG51bGwsXHJcbiAgICBjb2xvcjI6IENvbG9yID0gbnVsbCxcclxuICAgIGNvbG9yMzogQ29sb3IgPSBudWxsLFxyXG4gICAgY29sb3I0OiBDb2xvciA9IG51bGxcclxuICApIHtcclxuICAgIHRoaXMuY2hlY2soZmlsbGVkID8gU2hhcGVUeXBlLkZpbGxlZCA6IFNoYXBlVHlwZS5MaW5lLCAzKTtcclxuICAgIGxldCB2ZXJ0aWNlcyA9IHRoaXMubWVzaC5nZXRWZXJ0aWNlcygpO1xyXG4gICAgbGV0IGlkeCA9IHRoaXMudmVydGV4SW5kZXg7XHJcbiAgICBpZiAoY29sb3IgPT09IG51bGwpIGNvbG9yID0gdGhpcy5jb2xvcjtcclxuICAgIGlmIChjb2xvcjIgPT09IG51bGwpIGNvbG9yMiA9IHRoaXMuY29sb3I7XHJcbiAgICBpZiAoY29sb3IzID09PSBudWxsKSBjb2xvcjMgPSB0aGlzLmNvbG9yO1xyXG4gICAgaWYgKGNvbG9yNCA9PT0gbnVsbCkgY29sb3I0ID0gdGhpcy5jb2xvcjtcclxuICAgIGlmIChmaWxsZWQpIHtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjMpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4NCwgeTQsIGNvbG9yNCk7XHJcbiAgICAgIHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcjIpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjMpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4NCwgeTQsIGNvbG9yNCk7XHJcbiAgICAgIHRoaXMudmVydGV4KHg0LCB5NCwgY29sb3I0KTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuICByZWN0KFxyXG4gICAgZmlsbGVkOiBib29sZWFuLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxyXG4gICAgd2lkdGg6IG51bWJlcixcclxuICAgIGhlaWdodDogbnVtYmVyLFxyXG4gICAgY29sb3I6IENvbG9yID0gbnVsbFxyXG4gICkge1xyXG4gICAgdGhpcy5xdWFkKFxyXG4gICAgICBmaWxsZWQsXHJcbiAgICAgIHgsXHJcbiAgICAgIHksXHJcbiAgICAgIHggKyB3aWR0aCxcclxuICAgICAgeSxcclxuICAgICAgeCArIHdpZHRoLFxyXG4gICAgICB5ICsgaGVpZ2h0LFxyXG4gICAgICB4LFxyXG4gICAgICB5ICsgaGVpZ2h0LFxyXG4gICAgICBjb2xvcixcclxuICAgICAgY29sb3IsXHJcbiAgICAgIGNvbG9yLFxyXG4gICAgICBjb2xvclxyXG4gICAgKTtcclxuICB9XHJcbiAgcmVjdExpbmUoXHJcbiAgICBmaWxsZWQ6IGJvb2xlYW4sXHJcbiAgICB4MTogbnVtYmVyLFxyXG4gICAgeTE6IG51bWJlcixcclxuICAgIHgyOiBudW1iZXIsXHJcbiAgICB5MjogbnVtYmVyLFxyXG4gICAgd2lkdGg6IG51bWJlcixcclxuICAgIGNvbG9yOiBDb2xvciA9IG51bGxcclxuICApIHtcclxuICAgIHRoaXMuY2hlY2soZmlsbGVkID8gU2hhcGVUeXBlLkZpbGxlZCA6IFNoYXBlVHlwZS5MaW5lLCA4KTtcclxuICAgIGlmIChjb2xvciA9PT0gbnVsbCkgY29sb3IgPSB0aGlzLmNvbG9yO1xyXG4gICAgbGV0IHQgPSB0aGlzLnRtcC5zZXQoeTIgLSB5MSwgeDEgLSB4Mik7XHJcbiAgICB0Lm5vcm1hbGl6ZSgpO1xyXG4gICAgd2lkdGggKj0gMC41O1xyXG4gICAgbGV0IHR4ID0gdC54ICogd2lkdGg7XHJcbiAgICBsZXQgdHkgPSB0LnkgKiB3aWR0aDtcclxuICAgIGlmICghZmlsbGVkKSB7XHJcbiAgICAgIHRoaXMudmVydGV4KHgxICsgdHgsIHkxICsgdHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDEgLSB0eCwgeTEgLSB0eSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiArIHR4LCB5MiArIHR5LCBjb2xvcik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgyIC0gdHgsIHkyIC0gdHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDIgKyB0eCwgeTIgKyB0eSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MSArIHR4LCB5MSArIHR5LCBjb2xvcik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgyIC0gdHgsIHkyIC0gdHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDEgLSB0eCwgeTEgLSB0eSwgY29sb3IpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDEgKyB0eCwgeTEgKyB0eSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MSAtIHR4LCB5MSAtIHR5LCBjb2xvcik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgyICsgdHgsIHkyICsgdHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDIgLSB0eCwgeTIgLSB0eSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiArIHR4LCB5MiArIHR5LCBjb2xvcik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgxIC0gdHgsIHkxIC0gdHksIGNvbG9yKTtcclxuICAgIH1cclxuICB9XHJcbiAgeCh4OiBudW1iZXIsIHk6IG51bWJlciwgc2l6ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmxpbmUoeCAtIHNpemUsIHkgLSBzaXplLCB4ICsgc2l6ZSwgeSArIHNpemUpO1xyXG4gICAgdGhpcy5saW5lKHggLSBzaXplLCB5ICsgc2l6ZSwgeCArIHNpemUsIHkgLSBzaXplKTtcclxuICB9XHJcbiAgcG9seWdvbihcclxuICAgIHBvbHlnb25WZXJ0aWNlczogQXJyYXlMaWtlPG51bWJlcj4sXHJcbiAgICBvZmZzZXQ6IG51bWJlcixcclxuICAgIGNvdW50OiBudW1iZXIsXHJcbiAgICBjb2xvcjogQ29sb3IgPSBudWxsXHJcbiAgKSB7XHJcbiAgICBpZiAoY291bnQgPCAzKSB0aHJvdyBuZXcgRXJyb3IoXCJQb2x5Z29uIG11c3QgY29udGFpbiBhdCBsZWFzdCAzIHZlcnRpY2VzXCIpO1xyXG4gICAgdGhpcy5jaGVjayhTaGFwZVR5cGUuTGluZSwgY291bnQgKiAyKTtcclxuICAgIGlmIChjb2xvciA9PT0gbnVsbCkgY29sb3IgPSB0aGlzLmNvbG9yO1xyXG4gICAgbGV0IHZlcnRpY2VzID0gdGhpcy5tZXNoLmdldFZlcnRpY2VzKCk7XHJcbiAgICBsZXQgaWR4ID0gdGhpcy52ZXJ0ZXhJbmRleDtcclxuICAgIG9mZnNldCA8PD0gMTtcclxuICAgIGNvdW50IDw8PSAxO1xyXG4gICAgbGV0IGZpcnN0WCA9IHBvbHlnb25WZXJ0aWNlc1tvZmZzZXRdO1xyXG4gICAgbGV0IGZpcnN0WSA9IHBvbHlnb25WZXJ0aWNlc1tvZmZzZXQgKyAxXTtcclxuICAgIGxldCBsYXN0ID0gb2Zmc2V0ICsgY291bnQ7XHJcbiAgICBmb3IgKGxldCBpID0gb2Zmc2V0LCBuID0gb2Zmc2V0ICsgY291bnQgLSAyOyBpIDwgbjsgaSArPSAyKSB7XHJcbiAgICAgIGxldCB4MSA9IHBvbHlnb25WZXJ0aWNlc1tpXTtcclxuICAgICAgbGV0IHkxID0gcG9seWdvblZlcnRpY2VzW2kgKyAxXTtcclxuICAgICAgbGV0IHgyID0gMDtcclxuICAgICAgbGV0IHkyID0gMDtcclxuICAgICAgaWYgKGkgKyAyID49IGxhc3QpIHtcclxuICAgICAgICB4MiA9IGZpcnN0WDtcclxuICAgICAgICB5MiA9IGZpcnN0WTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB4MiA9IHBvbHlnb25WZXJ0aWNlc1tpICsgMl07XHJcbiAgICAgICAgeTIgPSBwb2x5Z29uVmVydGljZXNbaSArIDNdO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudmVydGV4KHgxLCB5MSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yKTtcclxuICAgIH1cclxuICB9XHJcbiAgY2lyY2xlKFxyXG4gICAgZmlsbGVkOiBib29sZWFuLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxyXG4gICAgcmFkaXVzOiBudW1iZXIsXHJcbiAgICBjb2xvcjogQ29sb3IgPSBudWxsLFxyXG4gICAgc2VnbWVudHM6IG51bWJlciA9IDBcclxuICApIHtcclxuICAgIGlmIChzZWdtZW50cyA9PT0gMClcclxuICAgICAgc2VnbWVudHMgPSBNYXRoLm1heCgxLCAoNiAqIE1hdGhVdGlscy5jYnJ0KHJhZGl1cykpIHwgMCk7XHJcbiAgICBpZiAoc2VnbWVudHMgPD0gMCkgdGhyb3cgbmV3IEVycm9yKFwic2VnbWVudHMgbXVzdCBiZSA+IDAuXCIpO1xyXG4gICAgaWYgKGNvbG9yID09PSBudWxsKSBjb2xvciA9IHRoaXMuY29sb3I7XHJcbiAgICBsZXQgYW5nbGUgPSAoMiAqIE1hdGhVdGlscy5QSSkgLyBzZWdtZW50cztcclxuICAgIGxldCBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XHJcbiAgICBsZXQgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xyXG4gICAgbGV0IGN4ID0gcmFkaXVzLFxyXG4gICAgICBjeSA9IDA7XHJcbiAgICBpZiAoIWZpbGxlZCkge1xyXG4gICAgICB0aGlzLmNoZWNrKFNoYXBlVHlwZS5MaW5lLCBzZWdtZW50cyAqIDIgKyAyKTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdtZW50czsgaSsrKSB7XHJcbiAgICAgICAgdGhpcy52ZXJ0ZXgoeCArIGN4LCB5ICsgY3ksIGNvbG9yKTtcclxuICAgICAgICBsZXQgdGVtcCA9IGN4O1xyXG4gICAgICAgIGN4ID0gY29zICogY3ggLSBzaW4gKiBjeTtcclxuICAgICAgICBjeSA9IHNpbiAqIHRlbXAgKyBjb3MgKiBjeTtcclxuICAgICAgICB0aGlzLnZlcnRleCh4ICsgY3gs