UNPKG

ngx-spine

Version:

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

517 lines 60.5 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 { Utils } from "./Utils"; import { Triangulator } from "./Triangulator"; export class SkeletonClipping { constructor() { this.triangulator = new Triangulator(); this.clippingPolygon = new Array(); this.clipOutput = new Array(); this.clippedVertices = new Array(); this.clippedTriangles = new Array(); this.scratch = new Array(); } /** * @param {?} slot * @param {?} clip * @return {?} */ clipStart(slot, clip) { if (this.clipAttachment != null) return 0; this.clipAttachment = clip; /** @type {?} */ let n = clip.worldVerticesLength; /** @type {?} */ let vertices = Utils.setArraySize(this.clippingPolygon, n); clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); /** @type {?} */ let clippingPolygon = this.clippingPolygon; SkeletonClipping.makeClockwise(clippingPolygon); /** @type {?} */ let clippingPolygons = (this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon))); for (let i = 0, n = clippingPolygons.length; i < n; i++) { /** @type {?} */ let polygon = clippingPolygons[i]; SkeletonClipping.makeClockwise(polygon); polygon.push(polygon[0]); polygon.push(polygon[1]); } return clippingPolygons.length; } /** * @param {?} slot * @return {?} */ clipEndWithSlot(slot) { if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data) this.clipEnd(); } /** * @return {?} */ clipEnd() { if (this.clipAttachment == null) return; this.clipAttachment = null; this.clippingPolygons = null; this.clippedVertices.length = 0; this.clippedTriangles.length = 0; this.clippingPolygon.length = 0; } /** * @return {?} */ isClipping() { return this.clipAttachment != null; } /** * @param {?} vertices * @param {?} verticesLength * @param {?} triangles * @param {?} trianglesLength * @param {?} uvs * @param {?} light * @param {?} dark * @param {?} twoColor * @return {?} */ clipTriangles(vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) { /** @type {?} */ let clipOutput = this.clipOutput; /** @type {?} */ let clippedVertices = this.clippedVertices; /** @type {?} */ let clippedTriangles = this.clippedTriangles; /** @type {?} */ let polygons = this.clippingPolygons; /** @type {?} */ let polygonsCount = this.clippingPolygons.length; /** @type {?} */ let vertexSize = twoColor ? 12 : 8; /** @type {?} */ let index = 0; clippedVertices.length = 0; clippedTriangles.length = 0; outer: for (let i = 0; i < trianglesLength; i += 3) { /** @type {?} */ let vertexOffset = triangles[i] << 1; /** @type {?} */ let x1 = vertices[vertexOffset]; /** @type {?} */ let y1 = vertices[vertexOffset + 1]; /** @type {?} */ let u1 = uvs[vertexOffset]; /** @type {?} */ let v1 = uvs[vertexOffset + 1]; vertexOffset = triangles[i + 1] << 1; /** @type {?} */ let x2 = vertices[vertexOffset]; /** @type {?} */ let y2 = vertices[vertexOffset + 1]; /** @type {?} */ let u2 = uvs[vertexOffset]; /** @type {?} */ let v2 = uvs[vertexOffset + 1]; vertexOffset = triangles[i + 2] << 1; /** @type {?} */ let x3 = vertices[vertexOffset]; /** @type {?} */ let y3 = vertices[vertexOffset + 1]; /** @type {?} */ let u3 = uvs[vertexOffset]; /** @type {?} */ let v3 = uvs[vertexOffset + 1]; for (let p = 0; p < polygonsCount; p++) { /** @type {?} */ let s = clippedVertices.length; if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { /** @type {?} */ let clipOutputLength = clipOutput.length; if (clipOutputLength == 0) continue; /** @type {?} */ let d0 = y2 - y3; /** @type {?} */ let d1 = x3 - x2; /** @type {?} */ let d2 = x1 - x3; /** @type {?} */ let d4 = y3 - y1; /** @type {?} */ let d = 1 / (d0 * d2 + d1 * (y1 - y3)); /** @type {?} */ let clipOutputCount = clipOutputLength >> 1; /** @type {?} */ let clipOutputItems = this.clipOutput; /** @type {?} */ let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); for (let ii = 0; ii < clipOutputLength; ii += 2) { /** @type {?} */ let x = clipOutputItems[ii]; /** @type {?} */ let y = clipOutputItems[ii + 1]; clippedVerticesItems[s] = x; clippedVerticesItems[s + 1] = y; clippedVerticesItems[s + 2] = light.r; clippedVerticesItems[s + 3] = light.g; clippedVerticesItems[s + 4] = light.b; clippedVerticesItems[s + 5] = light.a; /** @type {?} */ let c0 = x - x3; /** @type {?} */ let c1 = y - y3; /** @type {?} */ let a = (d0 * c0 + d1 * c1) * d; /** @type {?} */ let b = (d4 * c0 + d2 * c1) * d; /** @type {?} */ let c = 1 - a - b; clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c; clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c; if (twoColor) { clippedVerticesItems[s + 8] = dark.r; clippedVerticesItems[s + 9] = dark.g; clippedVerticesItems[s + 10] = dark.b; clippedVerticesItems[s + 11] = dark.a; } s += vertexSize; } s = clippedTriangles.length; /** @type {?} */ let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); clipOutputCount--; for (let ii = 1; ii < clipOutputCount; ii++) { clippedTrianglesItems[s] = index; clippedTrianglesItems[s + 1] = index + ii; clippedTrianglesItems[s + 2] = index + ii + 1; s += 3; } index += clipOutputCount + 1; } else { /** @type {?} */ let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * vertexSize); clippedVerticesItems[s] = x1; clippedVerticesItems[s + 1] = y1; clippedVerticesItems[s + 2] = light.r; clippedVerticesItems[s + 3] = light.g; clippedVerticesItems[s + 4] = light.b; clippedVerticesItems[s + 5] = light.a; if (!twoColor) { clippedVerticesItems[s + 6] = u1; clippedVerticesItems[s + 7] = v1; clippedVerticesItems[s + 8] = x2; clippedVerticesItems[s + 9] = y2; clippedVerticesItems[s + 10] = light.r; clippedVerticesItems[s + 11] = light.g; clippedVerticesItems[s + 12] = light.b; clippedVerticesItems[s + 13] = light.a; clippedVerticesItems[s + 14] = u2; clippedVerticesItems[s + 15] = v2; clippedVerticesItems[s + 16] = x3; clippedVerticesItems[s + 17] = y3; clippedVerticesItems[s + 18] = light.r; clippedVerticesItems[s + 19] = light.g; clippedVerticesItems[s + 20] = light.b; clippedVerticesItems[s + 21] = light.a; clippedVerticesItems[s + 22] = u3; clippedVerticesItems[s + 23] = v3; } else { clippedVerticesItems[s + 6] = u1; clippedVerticesItems[s + 7] = v1; clippedVerticesItems[s + 8] = dark.r; clippedVerticesItems[s + 9] = dark.g; clippedVerticesItems[s + 10] = dark.b; clippedVerticesItems[s + 11] = dark.a; clippedVerticesItems[s + 12] = x2; clippedVerticesItems[s + 13] = y2; clippedVerticesItems[s + 14] = light.r; clippedVerticesItems[s + 15] = light.g; clippedVerticesItems[s + 16] = light.b; clippedVerticesItems[s + 17] = light.a; clippedVerticesItems[s + 18] = u2; clippedVerticesItems[s + 19] = v2; clippedVerticesItems[s + 20] = dark.r; clippedVerticesItems[s + 21] = dark.g; clippedVerticesItems[s + 22] = dark.b; clippedVerticesItems[s + 23] = dark.a; clippedVerticesItems[s + 24] = x3; clippedVerticesItems[s + 25] = y3; clippedVerticesItems[s + 26] = light.r; clippedVerticesItems[s + 27] = light.g; clippedVerticesItems[s + 28] = light.b; clippedVerticesItems[s + 29] = light.a; clippedVerticesItems[s + 30] = u3; clippedVerticesItems[s + 31] = v3; clippedVerticesItems[s + 32] = dark.r; clippedVerticesItems[s + 33] = dark.g; clippedVerticesItems[s + 34] = dark.b; clippedVerticesItems[s + 35] = dark.a; } s = clippedTriangles.length; /** @type {?} */ let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); clippedTrianglesItems[s] = index; clippedTrianglesItems[s + 1] = index + 1; clippedTrianglesItems[s + 2] = index + 2; index += 3; continue outer; } } } } /** * Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @param {?} x3 * @param {?} y3 * @param {?} clippingArea * @param {?} output * @return {?} */ clip(x1, y1, x2, y2, x3, y3, clippingArea, output) { /** @type {?} */ let originalOutput = output; /** @type {?} */ let clipped = false; // Avoid copy at the end. /** @type {?} */ let input = null; if (clippingArea.length % 4 >= 2) { input = output; output = this.scratch; } else input = this.scratch; input.length = 0; input.push(x1); input.push(y1); input.push(x2); input.push(y2); input.push(x3); input.push(y3); input.push(x1); input.push(y1); output.length = 0; /** @type {?} */ let clippingVertices = clippingArea; /** @type {?} */ let clippingVerticesLast = clippingArea.length - 4; for (let i = 0;; i += 2) { /** @type {?} */ let edgeX = clippingVertices[i]; /** @type {?} */ let edgeY = clippingVertices[i + 1]; /** @type {?} */ let edgeX2 = clippingVertices[i + 2]; /** @type {?} */ let edgeY2 = clippingVertices[i + 3]; /** @type {?} */ let deltaX = edgeX - edgeX2; /** @type {?} */ let deltaY = edgeY - edgeY2; /** @type {?} */ let inputVertices = input; /** @type {?} */ let inputVerticesLength = input.length - 2; /** @type {?} */ let outputStart = output.length; for (let ii = 0; ii < inputVerticesLength; ii += 2) { /** @type {?} */ let inputX = inputVertices[ii]; /** @type {?} */ let inputY = inputVertices[ii + 1]; /** @type {?} */ let inputX2 = inputVertices[ii + 2]; /** @type {?} */ let inputY2 = inputVertices[ii + 3]; /** @type {?} */ let side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0; if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) { if (side2) { // v1 inside, v2 inside output.push(inputX2); output.push(inputY2); continue; } // v1 inside, v2 outside /** @type {?} */ let c0 = inputY2 - inputY; /** @type {?} */ let c2 = inputX2 - inputX; /** @type {?} */ let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); if (Math.abs(s) > 0.000001) { /** @type {?} */ let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; output.push(edgeX + (edgeX2 - edgeX) * ua); output.push(edgeY + (edgeY2 - edgeY) * ua); } else { output.push(edgeX); output.push(edgeY); } } else if (side2) { // v1 outside, v2 inside /** @type {?} */ let c0 = inputY2 - inputY; /** @type {?} */ let c2 = inputX2 - inputX; /** @type {?} */ let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); if (Math.abs(s) > 0.000001) { /** @type {?} */ let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; output.push(edgeX + (edgeX2 - edgeX) * ua); output.push(edgeY + (edgeY2 - edgeY) * ua); } else { output.push(edgeX); output.push(edgeY); } output.push(inputX2); output.push(inputY2); } clipped = true; } if (outputStart == output.length) { // All edges outside. originalOutput.length = 0; return true; } output.push(output[0]); output.push(output[1]); if (i == clippingVerticesLast) break; /** @type {?} */ let temp = output; output = input; output.length = 0; input = temp; } if (originalOutput != output) { originalOutput.length = 0; for (let i = 0, n = output.length - 2; i < n; i++) originalOutput[i] = output[i]; } else originalOutput.length = originalOutput.length - 2; return clipped; } /** * @param {?} polygon * @return {?} */ static makeClockwise(polygon) { /** @type {?} */ let vertices = polygon; /** @type {?} */ let verticeslength = polygon.length; /** @type {?} */ let area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1]; /** @type {?} */ let p1x = 0; /** @type {?} */ let p1y = 0; /** @type {?} */ let p2x = 0; /** @type {?} */ let p2y = 0; for (let i = 0, n = verticeslength - 3; i < n; i += 2) { p1x = vertices[i]; p1y = vertices[i + 1]; p2x = vertices[i + 2]; p2y = vertices[i + 3]; area += p1x * p2y - p2x * p1y; } if (area < 0) return; for (let i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { /** @type {?} */ let x = vertices[i]; /** @type {?} */ let y = vertices[i + 1]; /** @type {?} */ let other = lastX - i; vertices[i] = vertices[other]; vertices[i + 1] = vertices[other + 1]; vertices[other] = x; vertices[other + 1] = y; } } } if (false) { /** * @type {?} * @private */ SkeletonClipping.prototype.triangulator; /** * @type {?} * @private */ SkeletonClipping.prototype.clippingPolygon; /** * @type {?} * @private */ SkeletonClipping.prototype.clipOutput; /** @type {?} */ SkeletonClipping.prototype.clippedVertices; /** @type {?} */ SkeletonClipping.prototype.clippedTriangles; /** * @type {?} * @private */ SkeletonClipping.prototype.scratch; /** * @type {?} * @private */ SkeletonClipping.prototype.clipAttachment; /** * @type {?} * @private */ SkeletonClipping.prototype.clippingPolygons; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25DbGlwcGluZy5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1zcGluZS8iLCJzb3VyY2VzIjpbImxpYi9zcGluZS10cy9jb3JlL1NrZWxldG9uQ2xpcHBpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE2QkEsT0FBTyxFQUFhLEtBQUssRUFBUyxNQUFNLFNBQVMsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJOUMsTUFBTSxPQUFPLGdCQUFnQjtJQUE3QjtRQUNVLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNsQyxvQkFBZSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7UUFDdEMsZUFBVSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7UUFDekMsb0JBQWUsR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO1FBQ3RDLHFCQUFnQixHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7UUFDL0IsWUFBTyxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7SUFvWHhDLENBQUM7Ozs7OztJQS9XQyxTQUFTLENBQUMsSUFBVSxFQUFFLElBQXdCO1FBQzVDLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJO1lBQUUsT0FBTyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7O1lBRXZCLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1COztZQUM1QixRQUFRLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7WUFDbEQsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlO1FBQzFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQzs7WUFDNUMsZ0JBQWdCLEdBQUcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQ3pFLGVBQWUsRUFDZixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FDL0MsQ0FBQztRQUNGLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTs7Z0JBQ25ELE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7WUFDakMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMxQjtRQUVELE9BQU8sZ0JBQWdCLENBQUMsTUFBTSxDQUFDO0lBQ2pDLENBQUM7Ozs7O0lBRUQsZUFBZSxDQUFDLElBQVU7UUFDeEIsSUFBSSxJQUFJLENBQUMsY0FBYyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsSUFBSTtZQUN6RSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQzs7OztJQUVELE9BQU87UUFDTCxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSTtZQUFFLE9BQU87UUFDeEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7Ozs7SUFFRCxVQUFVO1FBQ1IsT0FBTyxJQUFJLENBQUMsY0FBYyxJQUFJLElBQUksQ0FBQztJQUNyQyxDQUFDOzs7Ozs7Ozs7Ozs7SUFFRCxhQUFhLENBQ1gsUUFBMkIsRUFDM0IsY0FBc0IsRUFDdEIsU0FBNEIsRUFDNUIsZUFBdUIsRUFDdkIsR0FBc0IsRUFDdEIsS0FBWSxFQUNaLElBQVcsRUFDWCxRQUFpQjs7WUFFYixVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVU7O1lBQzlCLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZTs7WUFDcEMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQjs7WUFDeEMsUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0I7O1lBQ2hDLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTTs7WUFDNUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDOztZQUU5QixLQUFLLEdBQUcsQ0FBQztRQUNiLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDNUIsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxlQUFlLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTs7Z0JBQzlDLFlBQVksR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQzs7Z0JBQ2hDLEVBQUUsR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDOztnQkFDN0IsRUFBRSxHQUFHLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDOztnQkFDN0IsRUFBRSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUM7O2dCQUN4QixFQUFFLEdBQUcsR0FBRyxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7WUFFNUIsWUFBWSxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDOztnQkFDakMsRUFBRSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUM7O2dCQUM3QixFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7O2dCQUM3QixFQUFFLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQzs7Z0JBQ3hCLEVBQUUsR0FBRyxHQUFHLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUU1QixZQUFZLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7O2dCQUNqQyxFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQzs7Z0JBQzdCLEVBQUUsR0FBRyxRQUFRLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQzs7Z0JBQzdCLEVBQUUsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDOztnQkFDeEIsRUFBRSxHQUFHLEdBQUcsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBRTVCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxhQUFhLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O29CQUNsQyxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU07Z0JBQzlCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLEVBQUU7O3dCQUMxRCxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsTUFBTTtvQkFDeEMsSUFBSSxnQkFBZ0IsSUFBSSxDQUFDO3dCQUFFLFNBQVM7O3dCQUNoQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7O3dCQUNkLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRTs7d0JBQ1osRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFOzt3QkFDWixFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUU7O3dCQUNWLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQzs7d0JBRWxDLGVBQWUsR0FBRyxnQkFBZ0IsSUFBSSxDQUFDOzt3QkFDdkMsZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVOzt3QkFDakMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FDM0MsZUFBZSxFQUNmLENBQUMsR0FBRyxlQUFlLEdBQUcsVUFBVSxDQUNqQztvQkFDRCxLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTs7NEJBQzNDLENBQUMsR0FBRyxlQUFlLENBQUMsRUFBRSxDQUFDOzs0QkFDekIsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO3dCQUM3QixvQkFBb0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBQzVCLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBQ2hDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDOzs0QkFDbEMsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFOzs0QkFDYixFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUU7OzRCQUNULENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUM7OzRCQUMzQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDOzs0QkFDM0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQzt3QkFDakIsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO3dCQUN2RCxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7d0JBQ3ZELElBQUksUUFBUSxFQUFFOzRCQUNaLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDOzRCQUNyQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzs0QkFDckMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7NEJBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3lCQUN2Qzt3QkFDRCxDQUFDLElBQUksVUFBVSxDQUFDO3FCQUNqQjtvQkFFRCxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDOzt3QkFDeEIscUJBQXFCLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FDNUMsZ0JBQWdCLEVBQ2hCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLENBQzlCO29CQUNELGVBQWUsRUFBRSxDQUFDO29CQUNsQixLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFO3dCQUMzQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7d0JBQ2pDLHFCQUFxQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO3dCQUMxQyxxQkFBcUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7d0JBQzlDLENBQUMsSUFBSSxDQUFDLENBQUM7cUJBQ1I7b0JBQ0QsS0FBSyxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUM7aUJBQzlCO3FCQUFNOzt3QkFDRCxvQkFBb0IsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUMzQyxlQUFlLEVBQ2YsQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLENBQ25CO29CQUNELG9CQUFvQixDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDN0Isb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ3RDLElBQUksQ0FBQyxRQUFRLEVBQUU7d0JBQ2Isb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFFakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDakMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBRWxDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNsQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3FCQUNuQzt5QkFBTTt3QkFDTCxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNqQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNqQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDckMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ3JDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFFdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ2xDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUV0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNsQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO3dCQUNsQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN2QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQzt3QkFDbEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7d0JBQ3RDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO3dCQUN0QyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDdEMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7cUJBQ3ZDO29CQUVELENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7O3dCQUN4Qixx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O0lBQzlDLHNDQUF5Qzs7SUFDekMsMkNBQXNDOztJQUN0Qyw0Q0FBdUM7Ozs7O0lBQ3ZDLG1DQUFzQzs7Ozs7SUFFdEMsMENBQTJDOzs7OztJQUMzQyw0Q0FBK0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIE1heSAxLCAyMDE5LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTksIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTU1xuICogT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFU1xuICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU5cbiAqIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULFxuICogSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORyxcbiAqIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUywgQlVTSU5FU1NcbiAqIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTllcbiAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElOR1xuICogTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLFxuICogRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgQXJyYXlMaWtlLCBVdGlscywgQ29sb3IgfSBmcm9tIFwiLi9VdGlsc1wiO1xuaW1wb3J0IHsgVHJpYW5ndWxhdG9yIH0gZnJvbSBcIi4vVHJpYW5ndWxhdG9yXCI7XG5pbXBvcnQgeyBDbGlwcGluZ0F0dGFjaG1lbnQgfSBmcm9tIFwiLi9hdHRhY2htZW50cy9DbGlwcGluZ0F0dGFjaG1lbnRcIjtcbmltcG9ydCB7IFNsb3QgfSBmcm9tIFwiLi9TbG90XCI7XG5cbmV4cG9ydCBjbGFzcyBTa2VsZXRvbkNsaXBwaW5nIHtcbiAgcHJpdmF0ZSB0cmlhbmd1bGF0b3IgPSBuZXcgVHJpYW5ndWxhdG9yKCk7XG4gIHByaXZhdGUgY2xpcHBpbmdQb2x5Z29uID0gbmV3IEFycmF5PG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBjbGlwT3V0cHV0ID0gbmV3IEFycmF5PG51bWJlcj4oKTtcbiAgY2xpcHBlZFZlcnRpY2VzID0gbmV3IEFycmF5PG51bWJlcj4oKTtcbiAgY2xpcHBlZFRyaWFuZ2xlcyA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG4gIHByaXZhdGUgc2NyYXRjaCA9IG5ldyBBcnJheTxudW1iZXI+KCk7XG5cbiAgcHJpdmF0ZSBjbGlwQXR0YWNobWVudDogQ2xpcHBpbmdBdHRhY2htZW50O1xuICBwcml2YXRlIGNsaXBwaW5nUG9seWdvbnM6IEFycmF5PEFycmF5PG51bWJlcj4+O1xuXG4gIGNsaXBTdGFydChzbG90OiBTbG90LCBjbGlwOiBDbGlwcGluZ0F0dGFjaG1lbnQpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmNsaXBBdHRhY2htZW50ICE9IG51bGwpIHJldHVybiAwO1xuICAgIHRoaXMuY2xpcEF0dGFjaG1lbnQgPSBjbGlwO1xuXG4gICAgbGV0IG4gPSBjbGlwLndvcmxkVmVydGljZXNMZW5ndGg7XG4gICAgbGV0IHZlcnRpY2VzID0gVXRpbHMuc2V0QXJyYXlTaXplKHRoaXMuY2xpcHBpbmdQb2x5Z29uLCBuKTtcbiAgICBjbGlwLmNvbXB1dGVXb3JsZFZlcnRpY2VzKHNsb3QsIDAsIG4sIHZlcnRpY2VzLCAwLCAyKTtcbiAgICBsZXQgY2xpcHBpbmdQb2x5Z29uID0gdGhpcy5jbGlwcGluZ1BvbHlnb247XG4gICAgU2tlbGV0b25DbGlwcGluZy5tYWtlQ2xvY2t3aXNlKGNsaXBwaW5nUG9seWdvbik7XG4gICAgbGV0IGNsaXBwaW5nUG9seWdvbnMgPSAodGhpcy5jbGlwcGluZ1BvbHlnb25zID0gdGhpcy50cmlhbmd1bGF0b3IuZGVjb21wb3NlKFxuICAgICAgY2xpcHBpbmdQb2x5Z29uLFxuICAgICAgdGhpcy50cmlhbmd1bGF0b3IudHJpYW5ndWxhdGUoY2xpcHBpbmdQb2x5Z29uKVxuICAgICkpO1xuICAgIGZvciAobGV0IGkgPSAwLCBuID0gY2xpcHBpbmdQb2x5Z29ucy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgIGxldCBwb2x5Z29uID0gY2xpcHBpbmdQb2x5Z29uc1tpXTtcbiAgICAgIFNrZWxldG9uQ2xpcHBpbmcubWFrZUNsb2Nrd2lzZShwb2x5Z29uKTtcbiAgICAgIHBvbHlnb24ucHVzaChwb2x5Z29uWzBdKTtcbiAgICAgIHBvbHlnb24ucHVzaChwb2x5Z29uWzFdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2xpcHBpbmdQb2x5Z29ucy5sZW5ndGg7XG4gIH1cblxuICBjbGlwRW5kV2l0aFNsb3Qoc2xvdDogU2xvdCkge1xuICAgIGlmICh0aGlzLmNsaXBBdHRhY2htZW50ICE9IG51bGwgJiYgdGhpcy5jbGlwQXR0YWNobWVudC5lbmRTbG90ID09IHNsb3QuZGF0YSlcbiAgICAgIHRoaXMuY2xpcEVuZCgpO1xuICB9XG5cbiAgY2xpcEVuZCgpIHtcbiAgICBpZiAodGhpcy5jbGlwQXR0YWNobWVudCA9PSBudWxsKSByZXR1cm47XG4gICAgdGhpcy5jbGlwQXR0YWNobWVudCA9IG51bGw7XG4gICAgdGhpcy5jbGlwcGluZ1BvbHlnb25zID0gbnVsbDtcbiAgICB0aGlzLmNsaXBwZWRWZXJ0aWNlcy5sZW5ndGggPSAwO1xuICAgIHRoaXMuY2xpcHBlZFRyaWFuZ2xlcy5sZW5ndGggPSAwO1xuICAgIHRoaXMuY2xpcHBpbmdQb2x5Z29uLmxlbmd0aCA9IDA7XG4gIH1cblxuICBpc0NsaXBwaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNsaXBBdHRhY2htZW50ICE9IG51bGw7XG4gIH1cblxuICBjbGlwVHJpYW5nbGVzKFxuICAgIHZlcnRpY2VzOiBBcnJheUxpa2U8bnVtYmVyPixcbiAgICB2ZXJ0aWNlc0xlbmd0aDogbnVtYmVyLFxuICAgIHRyaWFuZ2xlczogQXJyYXlMaWtlPG51bWJlcj4sXG4gICAgdHJpYW5nbGVzTGVuZ3RoOiBudW1iZXIsXG4gICAgdXZzOiBBcnJheUxpa2U8bnVtYmVyPixcbiAgICBsaWdodDogQ29sb3IsXG4gICAgZGFyazogQ29sb3IsXG4gICAgdHdvQ29sb3I6IGJvb2xlYW5cbiAgKSB7XG4gICAgbGV0IGNsaXBPdXRwdXQgPSB0aGlzLmNsaXBPdXRwdXQsXG4gICAgICBjbGlwcGVkVmVydGljZXMgPSB0aGlzLmNsaXBwZWRWZXJ0aWNlcztcbiAgICBsZXQgY2xpcHBlZFRyaWFuZ2xlcyA9IHRoaXMuY2xpcHBlZFRyaWFuZ2xlcztcbiAgICBsZXQgcG9seWdvbnMgPSB0aGlzLmNsaXBwaW5nUG9seWdvbnM7XG4gICAgbGV0IHBvbHlnb25zQ291bnQgPSB0aGlzLmNsaXBwaW5nUG9seWdvbnMubGVuZ3RoO1xuICAgIGxldCB2ZXJ0ZXhTaXplID0gdHdvQ29sb3IgPyAxMiA6IDg7XG5cbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGNsaXBwZWRWZXJ0aWNlcy5sZW5ndGggPSAwO1xuICAgIGNsaXBwZWRUcmlhbmdsZXMubGVuZ3RoID0gMDtcbiAgICBvdXRlcjogZm9yIChsZXQgaSA9IDA7IGkgPCB0cmlhbmdsZXNMZW5ndGg7IGkgKz0gMykge1xuICAgICAgbGV0IHZlcnRleE9mZnNldCA9IHRyaWFuZ2xlc1tpXSA8PCAxO1xuICAgICAgbGV0IHgxID0gdmVydGljZXNbdmVydGV4T2Zmc2V0XSxcbiAgICAgICAgeTEgPSB2ZXJ0aWNlc1t2ZXJ0ZXhPZmZzZXQgKyAxXTtcbiAgICAgIGxldCB1MSA9IHV2c1t2ZXJ0ZXhPZmZzZXRdLFxuICAgICAgICB2MSA9IHV2c1t2ZXJ0ZXhPZmZzZXQgKyAxXTtcblxuICAgICAgdmVydGV4T2Zmc2V0ID0gdHJpYW5nbGVzW2kgKyAxXSA8PCAxO1xuICAgICAgbGV0IHgyID0gdmVydGljZXNbdmVydGV4T2Zmc2V0XSxcbiAgICAgICAgeTIgPSB2ZXJ0aWNlc1t2ZXJ0ZXhPZmZzZXQgKyAxXTtcbiAgICAgIGxldCB1MiA9IHV2c1t2ZXJ0ZXhPZmZzZXRdLFxuICAgICAgICB2MiA9IHV2c1t2ZXJ0ZXhPZmZzZXQgKyAxXTtcblxuICAgICAgdmVydGV4T2Zmc2V0ID0gdHJpYW5nbGVzW2kgKyAyXSA8PCAxO1xuICAgICAgbGV0IHgzID0gdmVydGljZXNbdmVydGV4T2Zmc2V0XSxcbiAgICAgICAgeTMgPSB2ZXJ0aWNlc1t2ZXJ0ZXhPZmZzZXQgKyAxXTtcbiAgICAgIGxldCB1MyA9IHV2c1t2ZXJ0ZXhPZmZzZXRdLFxuICAgICAgICB2MyA9IHV2c1t2ZXJ0ZXhPZmZzZXQgKyAxXTtcblxuICAgICAgZm9yIChsZXQgcCA9IDA7IHAgPCBwb2x5Z29uc0NvdW50OyBwKyspIHtcbiAgICAgICAgbGV0IHMgPSBjbGlwcGVkVmVydGljZXMubGVuZ3RoO1xuICAgICAgICBpZiAodGhpcy5jbGlwKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHBvbHlnb25zW3BdLCBjbGlwT3V0cHV0KSkge1xuICAgICAgICAgIGxldCBjbGlwT3V0cHV0TGVuZ3RoID0gY2xpcE91dHB1dC5sZW5ndGg7XG4gICAgICAgICAgaWYgKGNsaXBPdXRwdXRMZW5ndGggPT0gMCkgY29udGludWU7XG4gICAgICAgICAgbGV0IGQwID0geTIgLSB5MyxcbiAgICAgICAgICAgIGQxID0geDMgLSB4MixcbiAgICAgICAgICAgIGQyID0geDEgLSB4MyxcbiAgICAgICAgICAgIGQ0ID0geTMgLSB5MTtcbiAgICAgICAgICBsZXQgZCA9IDEgLyAoZDAgKiBkMiArIGQxICogKHkxIC0geTMpKTtcblxuICAgICAgICAgIGxldCBjbGlwT3V0cHV0Q291bnQgPSBjbGlwT3V0cHV0TGVuZ3RoID4+IDE7XG4gICAgICAgICAgbGV0IGNsaXBPdXRwdXRJdGVtcyA9IHRoaXMuY2xpcE91dHB1dDtcbiAgICAgICAgICBsZXQgY2xpcHBlZFZlcnRpY2VzSXRlbXMgPSBVdGlscy5zZXRBcnJheVNpemUoXG4gICAgICAgICAgICBjbGlwcGVkVmVydGljZXMsXG4gICAgICAgICAgICBzICsgY2xpcE91dHB1dENvdW50ICogdmVydGV4U2l6ZVxuICAgICAgICAgICk7XG4gICAgICAgICAgZm9yIChsZXQgaWkgPSAwOyBpaSA8IGNsaXBPdXRwdXRMZW5ndGg7IGlpICs9IDIpIHtcbiAgICAgICAgICAgIGxldCB4ID0gY2xpcE91dHB1dEl0ZW1zW2lpXSxcbiAgICAgICAgICAgICAgeSA9IGNsaXBPdXRwdXRJdGVtc1tpaSArIDFdO1xuICAgICAgICAgICAgY2xpcHBlZFZlcnRpY2VzSXRlbXNbc10gPSB4O1xuICAgICAgICAgICAgY2xpcHBlZFZlcnRpY2VzSXRlbXNbcyArIDFdID0geTtcbiAgICAgICAgICAgIGNsaXBwZWRWZXJ0aWNlc0l0ZW1zW3MgKyAyXSA9IGxpZ2h0LnI7XG4gICAgICAgICAgICBjbGlwcGVkVmVydGljZXNJdGVtc1tzICsgM10gPSBsaWdodC5nO1xuICAgICAgICAgICAgY2xpcHBlZFZlcnRpY2VzSXRlbXNbcyArIDRdID0gbGlnaHQuYjtcbiAgICAgICAgICAgIGNsaXBwZWRWZXJ0aWNlc0l0ZW1zW3MgKyA1XSA9IGxpZ2h0LmE7XG4gICAgICAgICAgICBsZXQgYzAgPSB4IC0geDMsXG4gICAgICAgICAgICAgIGMxID0geSAtIHkzO1xuICAgICAgICAgICAgbGV0IGEgPSAoZDAgKiBjMCArIGQxICogYzEpICogZDtcbiAgICAgICAgICAgIGxldCBiID0gKGQ0ICogYzAgKyBkMiAqIGMxKSAqIGQ7XG4gICAgICAgICAgICBsZXQgYyA9IDEgLSBhIC0gYjtcbiAgICAgICAgICAgIGNsaXBwZWRWZXJ0aWNlc0l0ZW1zW3MgKyA2XSA9IHUxICogYSArIHUyICogYiArIHUzICogYztcbiAgICAgICAgICAgIGNsaXBwZWRWZXJ0aWNlc0l0ZW1zW3MgKyA3XSA9IHYxICogYSArIHYyICogYiArIHYzICogYztcbiAgICAgICAgICAgIGlmICh0d29Db2xvcikge1xuICAgICAgICAgICAgICBjbGlwcGVkVmVydGljZXNJdGVtc1tzICsgOF0gPSBkYXJrLnI7XG4gICAgICAgICAgICAgIGNsaXBwZWRWZXJ0aWNlc0l0ZW1zW3MgKyA5XSA9IGRhcmsuZztcbiAgICAgICAgICAgICAgY2xpcHBlZFZlcnRpY2VzSXRlbXNbcyArIDEwXSA9IGRhcmsuYjtcbiAgICAgICAgICAgICAgY2xpcHBlZFZlcnRpY2VzSXRlbXNbcyArIDExXSA9IGRhcmsuYTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHMgKz0gdmVydGV4U2l6ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzID0gY2xpcHBlZFRyaWFuZ2xlcy5sZW5ndGg7XG4gICAgICAgICAgbGV0IGNsaXBwZWRUcmlhbmdsZXNJdGVtcyA9IFV0aWxzLnNldEFycmF5U2l6ZShcbiAgICAgICAgICAgIGNsaXBwZWRUcmlhbmdsZXMsXG4gICAgICAgICAgICBzICsgMyAqIChjbGlwT3V0cHV0Q291bnQgLSAyKVxuICAgICAgICAgICk7XG4gICAgICAgICAgY2xpcE91dHB1dENvdW50LS07XG4gICAgICAgICAgZm9yIChsZXQgaWkgPSAxOyBpaSA8IGNsaXBPdXRwdXRDb3VudDsgaWkrKykge1xuICAgICAgICAgICAgY2xpcHBlZFRyaWFuZ2xlc0l0ZW1zW3NdID0gaW5kZXg7XG4gICAgICAgICAgICBjbGlwcGVkVHJpYW5nbGVzSXRlbXNbcyArIDFdID0gaW5kZXggKyBpaTtcbiAgICAgICAgICAgIGNsaXBwZWRUcmlhbmdsZXNJdGVtc1tzICsgMl0gPSBpbmRleCArIGlpICsgMTtcbiAgICAgICAgICAgIHMgKz0gMztcbiAgICAgICAgICB9XG4gICAgICAgICAgaW5kZXggKz0gY2xpcE91dHB1dENvdW50ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZXQgY2xpcHBlZFZlcnRpY2VzSXRlbXMgPSBVdGlscy5zZXRBcnJheVNpemUoXG4gICAgICAgICAgICBjbGlwcGVkVmVydGljZXM