UNPKG

ngx-spine

Version:

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

443 lines 39 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 { Pool, Utils } from "./Utils"; import { BoundingBoxAttachment } from "./attachments/BoundingBoxAttachment"; var SkeletonBounds = /** @class */ (function () { function SkeletonBounds() { this.minX = 0; this.minY = 0; this.maxX = 0; this.maxY = 0; this.boundingBoxes = new Array(); this.polygons = new Array(); this.polygonPool = new Pool((/** * @return {?} */ function () { return Utils.newFloatArray(16); })); } /** * @param {?} skeleton * @param {?} updateAabb * @return {?} */ SkeletonBounds.prototype.update = /** * @param {?} skeleton * @param {?} updateAabb * @return {?} */ function (skeleton, updateAabb) { if (skeleton == null) throw new Error("skeleton cannot be null."); /** @type {?} */ var boundingBoxes = this.boundingBoxes; /** @type {?} */ var polygons = this.polygons; /** @type {?} */ var polygonPool = this.polygonPool; /** @type {?} */ var slots = skeleton.slots; /** @type {?} */ var slotCount = slots.length; boundingBoxes.length = 0; polygonPool.freeAll(polygons); polygons.length = 0; for (var i = 0; i < slotCount; i++) { /** @type {?} */ var slot = slots[i]; if (!slot.bone.active) continue; /** @type {?} */ var attachment = slot.getAttachment(); if (attachment instanceof BoundingBoxAttachment) { /** @type {?} */ var boundingBox = (/** @type {?} */ (attachment)); boundingBoxes.push(boundingBox); /** @type {?} */ var polygon = polygonPool.obtain(); if (polygon.length != boundingBox.worldVerticesLength) { polygon = Utils.newFloatArray(boundingBox.worldVerticesLength); } polygons.push(polygon); boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); } } if (updateAabb) { this.aabbCompute(); } else { this.minX = Number.POSITIVE_INFINITY; this.minY = Number.POSITIVE_INFINITY; this.maxX = Number.NEGATIVE_INFINITY; this.maxY = Number.NEGATIVE_INFINITY; } }; /** * @return {?} */ SkeletonBounds.prototype.aabbCompute = /** * @return {?} */ function () { /** @type {?} */ var minX = Number.POSITIVE_INFINITY; /** @type {?} */ var minY = Number.POSITIVE_INFINITY; /** @type {?} */ var maxX = Number.NEGATIVE_INFINITY; /** @type {?} */ var maxY = Number.NEGATIVE_INFINITY; /** @type {?} */ var polygons = this.polygons; for (var i = 0, n = polygons.length; i < n; i++) { /** @type {?} */ var polygon = polygons[i]; /** @type {?} */ var vertices = polygon; for (var ii = 0, nn = polygon.length; ii < nn; ii += 2) { /** @type {?} */ var x = vertices[ii]; /** @type {?} */ var y = vertices[ii + 1]; minX = Math.min(minX, x); minY = Math.min(minY, y); maxX = Math.max(maxX, x); maxY = Math.max(maxY, y); } } this.minX = minX; this.minY = minY; this.maxX = maxX; this.maxY = maxY; }; /** Returns true if the axis aligned bounding box contains the point. */ /** * Returns true if the axis aligned bounding box contains the point. * @param {?} x * @param {?} y * @return {?} */ SkeletonBounds.prototype.aabbContainsPoint = /** * Returns true if the axis aligned bounding box contains the point. * @param {?} x * @param {?} y * @return {?} */ function (x, y) { return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; }; /** Returns true if the axis aligned bounding box intersects the line segment. */ /** * Returns true if the axis aligned bounding box intersects the line segment. * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @return {?} */ SkeletonBounds.prototype.aabbIntersectsSegment = /** * Returns true if the axis aligned bounding box intersects the line segment. * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @return {?} */ function (x1, y1, x2, y2) { /** @type {?} */ var minX = this.minX; /** @type {?} */ var minY = this.minY; /** @type {?} */ var maxX = this.maxX; /** @type {?} */ var maxY = this.maxY; if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) return false; /** @type {?} */ var m = (y2 - y1) / (x2 - x1); /** @type {?} */ var y = m * (minX - x1) + y1; if (y > minY && y < maxY) return true; y = m * (maxX - x1) + y1; if (y > minY && y < maxY) return true; /** @type {?} */ var x = (minY - y1) / m + x1; if (x > minX && x < maxX) return true; x = (maxY - y1) / m + x1; if (x > minX && x < maxX) return true; return false; }; /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ /** * Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. * @param {?} bounds * @return {?} */ SkeletonBounds.prototype.aabbIntersectsSkeleton = /** * Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. * @param {?} bounds * @return {?} */ function (bounds) { return (this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY); }; /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */ /** * Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more * efficient to only call this method if {\@link #aabbContainsPoint(float, float)} returns true. * @param {?} x * @param {?} y * @return {?} */ SkeletonBounds.prototype.containsPoint = /** * Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more * efficient to only call this method if {\@link #aabbContainsPoint(float, float)} returns true. * @param {?} x * @param {?} y * @return {?} */ function (x, y) { /** @type {?} */ var polygons = this.polygons; for (var i = 0, n = polygons.length; i < n; i++) if (this.containsPointPolygon(polygons[i], x, y)) return this.boundingBoxes[i]; return null; }; /** Returns true if the polygon contains the point. */ /** * Returns true if the polygon contains the point. * @param {?} polygon * @param {?} x * @param {?} y * @return {?} */ SkeletonBounds.prototype.containsPointPolygon = /** * Returns true if the polygon contains the point. * @param {?} polygon * @param {?} x * @param {?} y * @return {?} */ function (polygon, x, y) { /** @type {?} */ var vertices = polygon; /** @type {?} */ var nn = polygon.length; /** @type {?} */ var prevIndex = nn - 2; /** @type {?} */ var inside = false; for (var ii = 0; ii < nn; ii += 2) { /** @type {?} */ var vertexY = vertices[ii + 1]; /** @type {?} */ var prevY = vertices[prevIndex + 1]; if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { /** @type {?} */ var vertexX = vertices[ii]; if (vertexX + ((y - vertexY) / (prevY - vertexY)) * (vertices[prevIndex] - vertexX) < x) inside = !inside; } prevIndex = ii; } return inside; }; /** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it * is usually more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns * true. */ /** * Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it * is usually more efficient to only call this method if {\@link #aabbIntersectsSegment(float, float, float, float)} returns * true. * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @return {?} */ SkeletonBounds.prototype.intersectsSegment = /** * Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it * is usually more efficient to only call this method if {\@link #aabbIntersectsSegment(float, float, float, float)} returns * true. * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @return {?} */ function (x1, y1, x2, y2) { /** @type {?} */ var polygons = this.polygons; for (var i = 0, n = polygons.length; i < n; i++) if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) return this.boundingBoxes[i]; return null; }; /** Returns true if the polygon contains any part of the line segment. */ /** * Returns true if the polygon contains any part of the line segment. * @param {?} polygon * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @return {?} */ SkeletonBounds.prototype.intersectsSegmentPolygon = /** * Returns true if the polygon contains any part of the line segment. * @param {?} polygon * @param {?} x1 * @param {?} y1 * @param {?} x2 * @param {?} y2 * @return {?} */ function (polygon, x1, y1, x2, y2) { /** @type {?} */ var vertices = polygon; /** @type {?} */ var nn = polygon.length; /** @type {?} */ var width12 = x1 - x2; /** @type {?} */ var height12 = y1 - y2; /** @type {?} */ var det1 = x1 * y2 - y1 * x2; /** @type {?} */ var x3 = vertices[nn - 2]; /** @type {?} */ var y3 = vertices[nn - 1]; for (var ii = 0; ii < nn; ii += 2) { /** @type {?} */ var x4 = vertices[ii]; /** @type {?} */ var y4 = vertices[ii + 1]; /** @type {?} */ var det2 = x3 * y4 - y3 * x4; /** @type {?} */ var width34 = x3 - x4; /** @type {?} */ var height34 = y3 - y4; /** @type {?} */ var det3 = width12 * height34 - height12 * width34; /** @type {?} */ var x = (det1 * width34 - width12 * det2) / det3; if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { /** @type {?} */ var y = (det1 * height34 - height12 * det2) / det3; if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true; } x3 = x4; y3 = y4; } return false; }; /** Returns the polygon for the specified bounding box, or null. */ /** * Returns the polygon for the specified bounding box, or null. * @param {?} boundingBox * @return {?} */ SkeletonBounds.prototype.getPolygon = /** * Returns the polygon for the specified bounding box, or null. * @param {?} boundingBox * @return {?} */ function (boundingBox) { if (boundingBox == null) throw new Error("boundingBox cannot be null."); /** @type {?} */ var index = this.boundingBoxes.indexOf(boundingBox); return index == -1 ? null : this.polygons[index]; }; /** * @return {?} */ SkeletonBounds.prototype.getWidth = /** * @return {?} */ function () { return this.maxX - this.minX; }; /** * @return {?} */ SkeletonBounds.prototype.getHeight = /** * @return {?} */ function () { return this.maxY - this.minY; }; return SkeletonBounds; }()); export { SkeletonBounds }; if (false) { /** @type {?} */ SkeletonBounds.prototype.minX; /** @type {?} */ SkeletonBounds.prototype.minY; /** @type {?} */ SkeletonBounds.prototype.maxX; /** @type {?} */ SkeletonBounds.prototype.maxY; /** @type {?} */ SkeletonBounds.prototype.boundingBoxes; /** @type {?} */ SkeletonBounds.prototype.polygons; /** * @type {?} * @private */ SkeletonBounds.prototype.polygonPool; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25Cb3VuZHMuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtc3BpbmUvIiwic291cmNlcyI6WyJsaWIvc3BpbmUtdHMvY29yZS9Ta2VsZXRvbkJvdW5kcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTZCQSxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUc1RTtJQUFBO1FBQ0UsU0FBSSxHQUFHLENBQUMsQ0FBQztRQUNULFNBQUksR0FBRyxDQUFDLENBQUM7UUFDVCxTQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ1QsU0FBSSxHQUFHLENBQUMsQ0FBQztRQUNULGtCQUFhLEdBQUcsSUFBSSxLQUFLLEVBQXlCLENBQUM7UUFDbkQsYUFBUSxHQUFHLElBQUksS0FBSyxFQUFxQixDQUFDO1FBQ2xDLGdCQUFXLEdBQUcsSUFBSSxJQUFJOzs7UUFBb0I7WUFDaEQsT0FBTyxLQUFLLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsRUFBQyxDQUFDO0lBbU1MLENBQUM7Ozs7OztJQWxNQywrQkFBTTs7Ozs7SUFBTixVQUFPLFFBQWtCLEVBQUUsVUFBbUI7UUFDNUMsSUFBSSxRQUFRLElBQUksSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQzs7WUFDOUQsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhOztZQUNsQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVE7O1lBQ3hCLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVzs7WUFDOUIsS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLOztZQUN0QixTQUFTLEdBQUcsS0FBSyxDQUFDLE1BQU07UUFDNUIsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDekIsV0FBVyxDQUFDLE9B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QUFDO1NBQ1Q7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxtRUFBbUU7Ozs7OztJQUNuRSxtQ0FBVTs7Ozs7SUFBVixVQUFXLFdBQWtDO1FBQzNDLElBQUksV0FBVyxJQUFJLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7O1lBQ3BFLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFDbkQsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNuRCxDQUFDOzs7O0lBQ0QsaUNBQVE7OztJQUFSO1FBQ0UsT0FBTyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDL0IsQ0FBQzs7OztJQUNELGtDQUFTOzs7SUFBVDtRQUNFLE9BQU8sSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQy9CLENBQUM7SUFDSCxxQkFBQztBQUFELENBQUMsQUE1TUQsSUE0TUM7Ozs7SUEzTUMsOEJBQVM7O0lBQ1QsOEJBQVM7O0lBQ1QsOEJBQVM7O0lBQ1QsOEJBQVM7O0lBQ1QsdUNBQW1EOztJQUNuRCxrQ0FBMEM7Ozs7O0lBQzFDLHFDQUVHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxyXG4gKiBMYXN0IHVwZGF0ZWQgTWF5IDEsIDIwMTkuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cclxuICpcclxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTksIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xyXG4gKlxyXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcclxuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcclxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcclxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXHJcbiAqXHJcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxyXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXHJcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cclxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XHJcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxyXG4gKlxyXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWSBFWFBSRVNTXHJcbiAqIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVNcclxuICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU5cclxuICogTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsXHJcbiAqIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsXHJcbiAqIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUywgQlVTSU5FU1NcclxuICogSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWVxyXG4gKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkdcclxuICogTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLFxyXG4gKiBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxyXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXHJcblxyXG5pbXBvcnQgeyBQb29sLCBVdGlscyB9IGZyb20gXCIuL1V0aWxzXCI7XHJcbmltcG9ydCB7IEJvdW5kaW5nQm94QXR0YWNobWVudCB9IGZyb20gXCIuL2F0dGFjaG1lbnRzL0JvdW5kaW5nQm94QXR0YWNobWVudFwiO1xyXG5pbXBvcnQgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgU2tlbGV0b25Cb3VuZHMge1xyXG4gIG1pblggPSAwO1xyXG4gIG1pblkgPSAwO1xyXG4gIG1heFggPSAwO1xyXG4gIG1heFkgPSAwO1xyXG4gIGJvdW5kaW5nQm94ZXMgPSBuZXcgQXJyYXk8Qm91bmRpbmdCb3hBdHRhY2htZW50PigpO1xyXG4gIHBvbHlnb25zID0gbmV3IEFycmF5PEFycmF5TGlrZTxudW1iZXI+PigpO1xyXG4gIHByaXZhdGUgcG9seWdvblBvb2wgPSBuZXcgUG9vbDxBcnJheUxpa2U8bnVtYmVyPj4oKCkgPT4ge1xyXG4gICAgcmV0dXJuIFV0aWxzLm5ld0Zsb2F0QXJyYXkoMTYpO1xyXG4gIH0pO1xyXG4gIHVwZGF0ZShza2VsZXRvbjogU2tlbGV0b24sIHVwZGF0ZUFhYmI6IGJvb2xlYW4pIHtcclxuICAgIGlmIChza2VsZXRvbiA9PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoXCJza2VsZXRvbiBjYW5ub3QgYmUgbnVsbC5cIik7XHJcbiAgICBsZXQgYm91bmRpbmdCb3hlcyA9IHRoaXMuYm91bmRpbmdCb3hlcztcclxuICAgIGxldCBwb2x5Z29ucyA9IHRoaXMucG9seWdvbnM7XHJcbiAgICBsZXQgcG9seWdvblBvb2wgPSB0aGlzLnBvbHlnb25Qb29sO1xyXG4gICAgbGV0IHNsb3RzID0gc2tlbGV0b24uc2xvdHM7XHJcbiAgICBsZXQgc2xvdENvdW50ID0gc2xvdHMubGVuZ3RoO1xyXG4gICAgYm91bmRpbmdCb3hlcy5sZW5ndGggPSAwO1xyXG4gICAgcG9seWdvblBvb2wuZnJlZUFsbChwb2x5Z29ucyk7XHJcbiAgICBwb2x5Z29ucy5sZW5ndGggPSAwO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbG90Q291bnQ7IGkrKykge1xyXG4gICAgICBsZXQgc2xvdCA9IHNsb3RzW2ldO1xyXG4gICAgICBpZiAoIXNsb3QuYm9uZS5hY3RpdmUpIGNvbnRpbnVlO1xyXG4gICAgICBsZXQgYXR0YWNobWVudCA9IHNsb3QuZ2V0QXR0YWNobWVudCgpO1xyXG4gICAgICBpZiAoYXR0YWNobWVudCBpbnN0YW5jZW9mIEJvdW5kaW5nQm94QXR0YWNobWVudCkge1xyXG4gICAgICAgIGxldCBib3VuZGluZ0JveCA9IGF0dGFjaG1lbnQgYXMgQm91bmRpbmdCb3hBdHRhY2htZW50O1xyXG4gICAgICAgIGJvdW5kaW5nQm94ZXMucHVzaChib3VuZGluZ0JveCk7XHJcbiAgICAgICAgbGV0IHBvbHlnb24gPSBwb2x5Z29uUG9vbC5vYnRhaW4oKTtcclxuICAgICAgICBpZiAocG9seWdvbi5sZW5ndGggIT0gYm91bmRpbmdCb3gud29ybGRWZXJ0aWNlc0xlbmd0aCkge1xyXG4gICAgICAgICAgcG9seWdvbiA9IFV0aWxzLm5ld0Zsb2F0QXJyYXkoYm91bmRpbmdCb3gud29ybGRWZXJ0aWNlc0xlbmd0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHBvbHlnb25zLnB1c2gocG9seWdvbik7XHJcbiAgICAgICAgYm91bmRpbmdCb3guY29tcHV0ZVdvcmxkVmVydGljZXMoXHJcbiAgICAgICAgICBzbG90LFxyXG4gICAgICAgICAgMCxcclxuICAgICAgICAgIGJvdW5kaW5nQm94LndvcmxkVmVydGljZXNMZW5ndGgsXHJcbiAgICAgICAgICBwb2x5Z29uLFxyXG4gICAgICAgICAgMCxcclxuICAgICAgICAgIDJcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodXBkYXRlQWFiYikge1xyXG4gICAgICB0aGlzLmFhYmJDb21wdXRlKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm1pblggPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XHJcbiAgICAgIHRoaXMubWluWSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcclxuICAgICAgdGhpcy5tYXhYID0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xyXG4gICAgICB0aGlzLm1heFkgPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGFhYmJDb21wdXRlKCkge1xyXG4gICAgbGV0IG1pblggPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksXHJcbiAgICAgIG1pblkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksXHJcbiAgICAgIG1heFggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksXHJcbiAgICAgIG1heFkgPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XHJcbiAgICBsZXQgcG9seWdvbnMgPSB0aGlzLnBvbHlnb25zO1xyXG4gICAgZm9yIChsZXQgaSA9IDAsIG4gPSBwb2x5Z29ucy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgbGV0IHBvbHlnb24gPSBwb2x5Z29uc1tpXTtcclxuICAgICAgbGV0IHZlcnRpY2VzID0gcG9seWdvbjtcclxuICAgICAgZm9yIChsZXQgaWkgPSAwLCBubiA9IHBvbHlnb24ubGVuZ3RoOyBpaSA8IG5uOyBpaSArPSAyKSB7XHJcbiAgICAgICAgbGV0IHggPSB2ZXJ0aWNlc1tpaV07XHJcbiAgICAgICAgbGV0IHkgPSB2ZXJ0aWNlc1tpaSArIDFdO1xyXG4gICAgICAgIG1pblggPSBNYXRoLm1pbihtaW5YLCB4KTtcclxuICAgICAgICBtaW5ZID0gTWF0aC5taW4obWluWSwgeSk7XHJcbiAgICAgICAgbWF4WCA9IE1hdGgubWF4KG1heFgsIHgpO1xyXG4gICAgICAgIG1heFkgPSBNYXRoLm1heChtYXhZLCB5KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5taW5YID0gbWluWDtcclxuICAgIHRoaXMubWluWSA9IG1pblk7XHJcbiAgICB0aGlzLm1heFggPSBtYXhYO1xyXG4gICAgdGhpcy5tYXhZID0gbWF4WTtcclxuICB9XHJcbiAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXhpcyBhbGlnbmVkIGJvdW5kaW5nIGJveCBjb250YWlucyB0aGUgcG9pbnQuICovXHJcbiAgYWFiYkNvbnRhaW5zUG9pbnQoeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcclxuICAgIHJldHVybiB4ID49IHRoaXMubWluWCAmJiB4IDw9IHRoaXMubWF4WCAmJiB5ID49IHRoaXMubWluWSAmJiB5IDw9IHRoaXMubWF4WTtcclxuICB9XHJcbiAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXhpcyBhbGlnbmVkIGJvdW5kaW5nIGJveCBpbnRlcnNlY3RzIHRoZSBsaW5lIHNlZ21lbnQuICovXHJcbiAgYWFiYkludGVyc2VjdHNTZWdtZW50KHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIpIHtcclxuICAgIGxldCBtaW5YID0gdGhpcy5taW5YO1xyXG4gICAgbGV0IG1pblkgPSB0aGlzLm1pblk7XHJcbiAgICBsZXQgbWF4WCA9IHRoaXMubWF4WDtcclxuICAgIGxldCBtYXhZID0gdGhpcy5tYXhZO1xyXG4gICAgaWYgKFxyXG4gICAgICAoeDEgPD0gbWluWCAmJiB4MiA8PSBtaW5YKSB8fFxyXG4gICAgICAoeTEgPD0gbWluWSAmJiB5MiA8PSBtaW5ZKSB8fFxyXG4gICAgICAoeDEgPj0gbWF4WCAmJiB4MiA+PSBtYXhYKSB8fFxyXG4gICAgICAoeTEgPj0gbWF4WSAmJiB5MiA+PSBtYXhZKVxyXG4gICAgKVxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICBsZXQgbSA9ICh5MiAtIHkxKSAvICh4MiAtIHgxKTtcclxuICAgIGxldCB5ID0gbSAqIChtaW5YIC0geDEpICsgeTE7XHJcbiAgICBpZiAoeSA+IG1pblkgJiYgeSA8IG1heFkpIHJldHVybiB0cnVlO1xyXG4gICAgeSA9IG0gKiAobWF4WCAtIHgxKSArIHkxO1xyXG4gICAgaWYgKHkgPiBtaW5ZICYmIHkgPCBtYXhZKSByZXR1cm4gdHJ1ZTtcclxuICAgIGxldCB4ID0gKG1pblkgLSB5MSkgLyBtICsgeDE7XHJcbiAgICBpZiAoeCA+IG1pblggJiYgeCA8IG1heFgpIHJldHVybiB0cnVlO1xyXG4gICAgeCA9IChtYXhZIC0geTEpIC8gbSArIHgxO1xyXG4gICAgaWYgKHggPiBtaW5YICYmIHggPCBtYXhYKSByZXR1cm4gdHJ1ZTtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbiAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXhpcyBhbGlnbmVkIGJvdW5kaW5nIGJveCBpbnRlcnNlY3RzIHRoZSBheGlzIGFsaWduZWQgYm91bmRpbmcgYm94IG9mIHRoZSBzcGVjaWZpZWQgYm91bmRzLiAqL1xyXG4gIGFhYmJJbnRlcnNlY3RzU2tlbGV0b24oYm91bmRzOiBTa2VsZXRvbkJvdW5kcykge1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgdGhpcy5taW5YIDwgYm91bmRzLm1heFggJiZcclxuICAgICAgdGhpcy5tYXhYID4gYm91bmRzLm1pblggJiZcclxuICAgICAgdGhpcy5taW5ZIDwgYm91bmRzLm1heFkgJiZcclxuICAgICAgdGhpcy5tYXhZID4gYm91bmRzLm1pbllcclxuICAgICk7XHJcbiAgfVxyXG4gIC8qKiBSZXR1cm5zIHRoZSBmaXJzdCBib3VuZGluZyBib3ggYXR0YWNobWVudCB0aGF0IGNvbnRhaW5zIHRoZSBwb2ludCwgb3IgbnVsbC4gV2hlbiBkb2luZyBtYW55IGNoZWNrcywgaXQgaXMgdXN1YWxseSBtb3JlXHJcbiAgICogZWZmaWNpZW50IHRvIG9ubHkgY2FsbCB0aGlzIG1ldGhvZCBpZiB7QGxpbmsgI2FhYmJDb250YWluc1BvaW50KGZsb2F0LCBmbG9hdCl9IHJldHVybnMgdHJ1ZS4gKi9cclxuICBjb250YWluc1BvaW50KHg6IG51bWJlciwgeTogbnVtYmVyKTogQm91bmRpbmdCb3hBdHRhY2htZW50IHtcclxuICAgIGxldCBwb2x5Z29ucyA9IHRoaXMucG9seWdvbnM7XHJcbiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvbHlnb25zLmxlbmd0aDsgaSA8IG47IGkrKylcclxuICAgICAgaWYgKHRoaXMuY29udGFpbnNQb2ludFBvbHlnb24ocG9seWdvbnNbaV0sIHgsIHkpKVxyXG4gICAgICAgIHJldHVybiB0aGlzLmJvdW5kaW5nQm94ZXNbaV07XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbiAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcG9seWdvbiBjb250YWlucyB0aGUgcG9pbnQuICovXHJcbiAgY29udGFpbnNQb2ludFBvbHlnb24ocG9seWdvbjogQXJyYXlMaWtlPG51bWJlcj4sIHg6IG51bWJlciwgeTogbnVtYmVyKSB7XHJcbiAgICBsZXQgdmVydGljZXMgPSBwb2x5Z29uO1xyXG4gICAgbGV0IG5uID0gcG9seWdvbi5sZW5ndGg7XHJcbiAgICBsZXQgcHJldkluZGV4ID0gbm4gLSAyO1xyXG4gICAgbGV0IGluc2lkZSA9IGZhbHNlO1xyXG4gICAgZm9yIChsZXQgaWkgPSAwOyBpaSA8IG5uOyBpaSArPSAyKSB7XHJcbiAgICAgIGxldCB2ZXJ0ZXhZID0gdmVydGljZXNbaWkgKyAxXTtcclxuICAgICAgbGV0IHByZXZZID0gdmVydGljZXNbcHJldkluZGV4ICsgMV07XHJcbiAgICAgIGlmICgodmVydGV4WSA8IHkgJiYgcHJldlkgPj0geSkgfHwgKHByZXZZIDwgeSAmJiB2ZXJ0ZXhZID49IHkpKSB7XHJcbiAgICAgICAgbGV0IHZlcnRleFggPSB2ZXJ0aWNlc1tpaV07XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgdmVydGV4WCArXHJcbiAgICAgICAgICAgICgoeSAtIHZlcnRleFkpIC8gKHByZXZZIC0gdmVydGV4WSkpICpcclxuICAgICAgICAgICAgICAodmVydGljZXNbcHJldkluZGV4XSAtIHZlcnRleFgpIDxcclxuICAgICAgICAgIHhcclxuICAgICAgICApXHJcbiAgICAgICAgICBpbnNpZGUgPSAhaW5zaWRlO1xyXG4gICAgICB9XHJcbiAgICAgIHByZXZJbmRleCA9IGlpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGluc2lkZTtcclxuICB9XHJcbiAgLyoqIFJldHVybnMgdGhlIGZpcnN0IGJvdW5kaW5nIGJveCBhdHRhY2htZW50IHRoYXQgY29udGFpbnMgYW55IHBhcnQgb2YgdGhlIGxpbmUgc2VnbWVudCwgb3IgbnVsbC4gV2hlbiBkb2luZyBtYW55IGNoZWNrcywgaXRcclxuICAgKiBpcyB1c3VhbGx5IG1vcmUgZWZmaWNpZW50IHRvIG9ubHkgY2FsbCB0aGlzIG1ldGhvZCBpZiB7QGxpbmsgI2FhYmJJbnRlcnNlY3RzU2VnbWVudChmbG9hdCwgZmxvYXQsIGZsb2F0LCBmbG9hdCl9IHJldHVybnNcclxuICAgKiB0cnVlLiAqL1xyXG4gIGludGVyc2VjdHNTZWdtZW50KHgxOiBudW1iZXIsIHkxOiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIpIHtcclxuICAgIGxldCBwb2x5Z29ucyA9IHRoaXMucG9seWdvbnM7XHJcbiAgICBmb3IgKGxldCBpID0gMCwgbiA9IHBvbHlnb25zLmxlbmd0aDsgaSA8IG47IGkrKylcclxuICAgICAgaWYgKHRoaXMuaW50ZXJzZWN0c1NlZ21lbnRQb2x5Z29uKHBvbHlnb25zW2ldLCB4MSwgeTEsIHgyLCB5MikpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYm91bmRpbmdCb3hlc1tpXTtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBwb2x5Z29uIGNvbnRhaW5zIGFueSBwYXJ0IG9mIHRoZSBsaW5lIHNlZ21lbnQuICovXHJcbiAgaW50ZXJzZWN0c1NlZ21lbnRQb2x5Z29uKFxyXG4gICAgcG9seWdvbjogQXJyYXlMaWtlPG51bWJlcj4sXHJcbiAgICB4MTogbnVtYmVyLFxyXG4gICAgeTE6IG51bWJlcixcclxuICAgIHgyOiBudW1iZXIsXHJcbiAgICB5MjogbnVtYmVyXHJcbiAgKSB7XHJcbiAgICBsZXQgdmVydGljZXMgPSBwb2x5Z29uO1xyXG4gICAgbGV0IG5uID0gcG9seWdvbi5sZW5ndGg7XHJcbiAgICBsZXQgd2lkdGgxMiA9IHgxIC0geDIsXHJcbiAgICAgIGhlaWdodDEyID0geTEgLSB5MjtcclxuICAgIGxldCBkZXQxID0geDEgKiB5MiAtIHkxICogeDI7XHJcbiAgICBsZXQgeDMgPSB2ZXJ0aWNlc1tubiAtIDJdLFxyXG4gICAgICB5MyA9IHZlcnRpY2VzW25uIC0gMV07XHJcbiAgICBmb3IgKGxldCBpaSA9IDA7IGlpIDwgbm47IGlpICs9IDIpIHtcclxuICAgICAgbGV0IHg0ID0gdmVydGljZXNbaWldLFxyXG4gICAgICAgIHk0ID0gdmVydGljZXNbaWkgKyAxXTtcclxuICAgICAgbGV0IGRldDIgPSB4MyAqIHk0IC0geTMgKiB4NDtcclxuICAgICAgbGV0IHdpZHRoMzQgPSB4MyAtIHg0LFxyXG4gICAgICAgIGhlaWdodDM0ID0geTMgLSB5NDtcclxuICAgICAgbGV0IGRldDMgPSB3aWR0aDEyICogaGVpZ2h0MzQgLSBoZWlnaHQxMiAqIHdpZHRoMzQ7XHJcbiAgICAgIGxldCB4ID0gKGRldDEgKiB3aWR0aDM0IC0gd2lkdGgxMiAqIGRldDIpIC8gZGV0MztcclxuICAgICAgaWYgKFxyXG4gICAgICAgICgoeCA+PSB4MyAmJiB4IDw9IHg0KSB8fCAoeCA+PSB4NCAmJiB4IDw9IHgzKSkgJiZcclxuICAgICAgICAoKHggPj0geDEgJiYgeCA8PSB4MikgfHwgKHggPj0geDIgJiYgeCA8PSB4MSkpXHJcbiAgICAgICkge1xyXG4gICAgICAgIGxldCB5ID0gKGRldDEgKiBoZWlnaHQzNCAtIGhlaWdodDEyICogZGV0MikgLyBkZXQzO1xyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgICgoeSA+PSB5MyAmJiB5IDw9IHk0KSB8fCAoeSA+PSB5NCAmJiB5IDw9IHkzKSkgJiZcclxuICAgICAgICAgICgoeSA+PSB5MSAmJiB5IDw9IHkyKSB8fCAoeSA+PSB5MiAmJiB5IDw9IHkxKSlcclxuICAgICAgICApXHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgICB4MyA9IHg0O1xyXG4gICAgICB5MyA9IHk0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICAvKiogUmV0dXJucyB0aGUgcG9seWdvbiBmb3IgdGhlIHNwZWNpZmllZCBib3VuZGluZyBib3gsIG9yIG51bGwuICovXHJcbiAgZ2V0UG9seWdvbihib3VuZGluZ0JveDogQm91bmRpbmdCb3hBdHRhY2htZW50KSB7XHJcbiAgICBpZiAoYm91bmRpbmdCb3ggPT0gbnVsbCkgdGhyb3cgbmV3IEVycm9yKFwiYm91bmRpbmdCb3ggY2Fubm90IGJlIG51bGwuXCIpO1xyXG4gICAgbGV0IGluZGV4ID0gdGhpcy5ib3VuZGluZ0JveGVzLmluZGV4T2YoYm91bmRpbmdCb3gpO1xyXG4gICAgcmV0dXJuIGluZGV4ID09IC0xID8gbnVsbCA6IHRoaXMucG9seWdvbnNbaW5kZXhdO1xyXG4gIH1cclxuICBnZXRXaWR0aCgpIHtcclxuICAgIHJldHVybiB0aGlzLm1heFggLSB0aGlzLm1pblg7XHJcbiAgfVxyXG4gIGdldEhlaWdodCgpIHtcclxuICAgIHJldHVybiB0aGlzLm1heFkgLSB0aGlzLm1pblk7XHJcbiAgfVxyXG59XHJcbiJdfQ==