UNPKG

@esotericsoftware/spine-core

Version:
178 lines 28.2 kB
/****************************************************************************** * Spine Runtimes License Agreement * Last updated April 5, 2025. Replaces all prior versions. * * Copyright (c) 2013-2025, Esoteric Software LLC * * Integration of the Spine Runtimes into software or otherwise creating * derivative works of the Spine Runtimes is permitted under the terms and * conditions of Section 2 of the Spine Editor License Agreement: * http://esotericsoftware.com/spine-editor-license * * Otherwise, it is permitted to integrate the Spine Runtimes into software * or otherwise create derivative works of the Spine Runtimes (collectively, * "Products"), provided that each user of the Products must obtain their own * Spine Editor license and redistribution of the Products in any form must * include this license and copyright notice. * * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ import { TextureAtlasRegion } from "../TextureAtlas.js"; import { Color, Utils } from "../Utils.js"; import { VertexAttachment } from "./Attachment.js"; /** An attachment that displays a textured mesh. A mesh has hull vertices and internal vertices within the hull. Holes are not * supported. Each vertex has UVs (texture coordinates) and triangles that are used to map an image on to the mesh. * * See [Mesh attachments](http://esotericsoftware.com/spine-meshes) in the Spine User Guide. */ export class MeshAttachment extends VertexAttachment { sequence; /** The UV pair for each vertex, normalized within the texture region. */ regionUVs = []; /** Triplets of vertex indices which describe the mesh's triangulation. */ triangles = []; /** The number of entries at the beginning of {@link vertices} that make up the mesh hull. */ hullLength = 0; /** The name of the texture region for this attachment. */ path; /** The color to tint the mesh. */ color = new Color(1, 1, 1, 1); sourceMesh = null; /** Vertex index pairs describing edges for controlling triangulation, or null if nonessential data was not exported. Mesh * triangles do not never cross edges. Triangulation is not performed at runtime. */ edges = []; /** The width of the mesh's image. Available only when nonessential data was exported. */ width = 0; /** The height of the mesh's image. Available only when nonessential data was exported. */ height = 0; tempColor = new Color(0, 0, 0, 0); constructor(name, sequence) { super(name); this.sequence = sequence; } copy() { if (this.sourceMesh) return this.newLinkedMesh(); const copy = new MeshAttachment(this.name, this.sequence.copy()); copy.path = this.path; copy.color.setFromColor(this.color); this.copyTo(copy); copy.regionUVs = []; Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); copy.triangles = []; Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); copy.hullLength = this.hullLength; // Nonessential. if (this.edges) { copy.edges = []; Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); } copy.width = this.width; copy.height = this.height; return copy; } updateSequence() { this.sequence.update(this); } /** The source mesh if this is a linked mesh, else null. A linked mesh shares the {@link bones}, {@link vertices}, * {@link regionUVs}, {@link triangles}, {@link hullLength}, {@link edges}, {@link width}, and {@link height} with the * source mesh, but may have a different {@link name} or {@link path}, and therefore a different texture region. */ getSourceMesh() { return this.sourceMesh; } setSourceMesh(sourceMesh) { this.sourceMesh = sourceMesh; if (sourceMesh) { this.bones = sourceMesh.bones; this.vertices = sourceMesh.vertices; this.worldVerticesLength = sourceMesh.worldVerticesLength; this.regionUVs = sourceMesh.regionUVs; this.triangles = sourceMesh.triangles; this.hullLength = sourceMesh.hullLength; this.worldVerticesLength = sourceMesh.worldVerticesLength; this.edges = sourceMesh.edges; this.width = sourceMesh.width; this.height = sourceMesh.height; } } /** Returns a new mesh with the {@link sourceMesh} set to this mesh's source mesh, if any, else to this mesh. **/ newLinkedMesh() { const copy = new MeshAttachment(this.name, this.sequence.copy()); copy.timelineAttachment = this.timelineAttachment; copy.path = this.path; copy.color.setFromColor(this.color); copy.setSourceMesh(this.sourceMesh ? this.sourceMesh : this); copy.updateSequence(); return copy; } /** Computes {@link Sequence.getUVs | UVs} for a mesh attachment. * @param uvs Output array for the computed UVs, same length as regionUVs. */ static computeUVs(region, regionUVs, uvs) { if (!region) throw new Error("Region not set."); const n = uvs.length; let u = region.u, v = region.v, width = 0, height = 0; if (region instanceof TextureAtlasRegion) { const page = region.page; const textureWidth = page.width, textureHeight = page.height; switch (region.degrees) { case 90: u -= (region.originalHeight - region.offsetY - region.height) / textureWidth; v -= (region.originalWidth - region.offsetX - region.width) / textureHeight; width = region.originalHeight / textureWidth; height = region.originalWidth / textureHeight; for (let i = 0; i < n; i += 2) { uvs[i] = u + regionUVs[i + 1] * width; uvs[i + 1] = v + (1 - regionUVs[i]) * height; } return; case 180: u -= (region.originalWidth - region.offsetX - region.width) / textureWidth; v -= region.offsetY / textureHeight; width = region.originalWidth / textureWidth; height = region.originalHeight / textureHeight; for (let i = 0; i < n; i += 2) { uvs[i] = u + (1 - regionUVs[i]) * width; uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; } return; case 270: u -= region.offsetY / textureWidth; v -= region.offsetX / textureHeight; width = region.originalHeight / textureWidth; height = region.originalWidth / textureHeight; for (let i = 0; i < n; i += 2) { uvs[i] = u + (1 - regionUVs[i + 1]) * width; uvs[i + 1] = v + regionUVs[i] * height; } return; default: u -= region.offsetX / textureWidth; v -= (region.originalHeight - region.offsetY - region.height) / textureHeight; width = region.originalWidth / textureWidth; height = region.originalHeight / textureHeight; } } else if (!region) { u = v = 0; width = height = 1; } else { width = region.u2 - u; height = region.v2 - v; } for (let i = 0; i < n; i += 2) { uvs[i] = u + regionUVs[i] * width; uvs[i + 1] = v + regionUVs[i + 1] * height; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWVzaEF0dGFjaG1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXR0YWNobWVudHMvTWVzaEF0dGFjaG1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQXdCLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUluRDs7OytGQUcrRjtBQUMvRixNQUFNLE9BQU8sY0FBZSxTQUFRLGdCQUFnQjtJQUMxQyxRQUFRLENBQVc7SUFFNUIseUVBQXlFO0lBQ3pFLFNBQVMsR0FBb0IsRUFBRSxDQUFDO0lBRWhDLDBFQUEwRTtJQUMxRSxTQUFTLEdBQWtCLEVBQUUsQ0FBQztJQUU5Qiw2RkFBNkY7SUFDN0YsVUFBVSxHQUFXLENBQUMsQ0FBQztJQUV2QiwwREFBMEQ7SUFDMUQsSUFBSSxDQUFVO0lBRWQsa0NBQWtDO0lBQ2xDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUV0QixVQUFVLEdBQTBCLElBQUksQ0FBQztJQUVqRDt3RkFDb0Y7SUFDcEYsS0FBSyxHQUFrQixFQUFFLENBQUM7SUFFMUIseUZBQXlGO0lBQ3pGLEtBQUssR0FBVyxDQUFDLENBQUM7SUFFbEIsMEZBQTBGO0lBQzFGLE1BQU0sR0FBVyxDQUFDLENBQUM7SUFFbkIsU0FBUyxHQUFHLElBQUksS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRWxDLFlBQWEsSUFBWSxFQUFFLFFBQWtCO1FBQzVDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNaLElB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QUssR0FBRyxNQUFNLENBQUMsYUFBYSxHQUFHLFlBQVksQ0FBQztvQkFDNUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1lBQ2pELENBQUM7UUFDRixDQUFDO2FBQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3BCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ1YsS0FBSyxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDcEIsQ0FBQzthQUFNLENBQUM7WUFDUCxLQUFLLEdBQUcsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDdEIsTUFBTSxHQUFHLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFFRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMvQixHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDbEMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDNUMsQ0FBQztJQUNGLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBUZXh0dXJlUmVnaW9uIH0gZnJvbSBcIi4uL1RleHR1cmUuanNcIjtcbmltcG9ydCB7IFRleHR1cmVBdGxhc1JlZ2lvbiB9IGZyb20gXCIuLi9UZXh0dXJlQXRsYXMuanNcIjtcbmltcG9ydCB7IENvbG9yLCB0eXBlIE51bWJlckFycmF5TGlrZSwgVXRpbHMgfSBmcm9tIFwiLi4vVXRpbHMuanNcIjtcbmltcG9ydCB7IFZlcnRleEF0dGFjaG1lbnQgfSBmcm9tIFwiLi9BdHRhY2htZW50LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEhhc1NlcXVlbmNlIH0gZnJvbSBcIi4vSGFzU2VxdWVuY2UuanNcIjtcbmltcG9ydCB0eXBlIHsgU2VxdWVuY2UgfSBmcm9tIFwiLi9TZXF1ZW5jZS5qc1wiO1xuXG4vKiogQW4gYXR0YWNobWVudCB0aGF0IGRpc3BsYXlzIGEgdGV4dHVyZWQgbWVzaC4gQSBtZXNoIGhhcyBodWxsIHZlcnRpY2VzIGFuZCBpbnRlcm5hbCB2ZXJ0aWNlcyB3aXRoaW4gdGhlIGh1bGwuIEhvbGVzIGFyZSBub3RcbiAqIHN1cHBvcnRlZC4gRWFjaCB2ZXJ0ZXggaGFzIFVWcyAodGV4dHVyZSBjb29yZGluYXRlcykgYW5kIHRyaWFuZ2xlcyB0aGF0IGFyZSB1c2VkIHRvIG1hcCBhbiBpbWFnZSBvbiB0byB0aGUgbWVzaC5cbiAqXG4gKiBTZWUgW01lc2ggYXR0YWNobWVudHNdKGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1tZXNoZXMpIGluIHRoZSBTcGluZSBVc2VyIEd1aWRlLiAqL1xuZXhwb3J0IGNsYXNzIE1lc2hBdHRhY2htZW50IGV4dGVuZHMgVmVydGV4QXR0YWNobWVudCBpbXBsZW1lbnRzIEhhc1NlcXVlbmNlIHtcblx0cmVhZG9ubHkgc2VxdWVuY2U6IFNlcXVlbmNlO1xuXG5cdC8qKiBUaGUgVVYgcGFpciBmb3IgZWFjaCB2ZXJ0ZXgsIG5vcm1hbGl6ZWQgd2l0aGluIHRoZSB0ZXh0dXJlIHJlZ2lvbi4gKi9cblx0cmVnaW9uVVZzOiBOdW1iZXJBcnJheUxpa2UgPSBbXTtcblxuXHQvKiogVHJpcGxldHMgb2YgdmVydGV4IGluZGljZXMgd2hpY2ggZGVzY3JpYmUgdGhlIG1lc2gncyB0cmlhbmd1bGF0aW9uLiAqL1xuXHR0cmlhbmdsZXM6IEFycmF5PG51bWJlcj4gPSBbXTtcblxuXHQvKiogVGhlIG51bWJlciBvZiBlbnRyaWVzIGF0IHRoZSBiZWdpbm5pbmcgb2Yge0BsaW5rIHZlcnRpY2VzfSB0aGF0IG1ha2UgdXAgdGhlIG1lc2ggaHVsbC4gKi9cblx0aHVsbExlbmd0aDogbnVtYmVyID0gMDtcblxuXHQvKiogVGhlIG5hbWUgb2YgdGhlIHRleHR1cmUgcmVnaW9uIGZvciB0aGlzIGF0dGFjaG1lbnQuICovXG5cdHBhdGg/OiBzdHJpbmc7XG5cblx0LyoqIFRoZSBjb2xvciB0byB0aW50IHRoZSBtZXNoLiAqL1xuXHRjb2xvciA9IG5ldyBDb2xvcigxLCAxLCAxLCAxKTtcblxuXHRwcml2YXRlIHNvdXJjZU1lc2g6IE1lc2hBdHRhY2htZW50IHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIFZlcnRleCBpbmRleCBwYWlycyBkZXNjcmliaW5nIGVkZ2VzIGZvciBjb250cm9sbGluZyB0cmlhbmd1bGF0aW9uLCBvciBudWxsIGlmIG5vbmVzc2VudGlhbCBkYXRhIHdhcyBub3QgZXhwb3J0ZWQuIE1lc2hcblx0ICogdHJpYW5nbGVzIGRvIG5vdCBuZXZlciBjcm9zcyBlZGdlcy4gVHJpYW5ndWxhdGlvbiBpcyBub3QgcGVyZm9ybWVkIGF0IHJ1bnRpbWUuICovXG5cdGVkZ2VzOiBBcnJheTxudW1iZXI+ID0gW107XG5cblx0LyoqIFRoZSB3aWR0aCBvZiB0aGUgbWVzaCdzIGltYWdlLiBBdmFpbGFibGUgb25seSB3aGVuIG5vbmVzc2VudGlhbCBkYXRhIHdhcyBleHBvcnRlZC4gKi9cblx0d2lkdGg6IG51bWJlciA9IDA7XG5cblx0LyoqIFRoZSBoZWlnaHQgb2YgdGhlIG1lc2gncyBpbWFnZS4gQXZhaWxhYmxlIG9ubHkgd2hlbiBub25lc3NlbnRpYWwgZGF0YSB3YXMgZXhwb3J0ZWQuICovXG5cdGhlaWdodDogbnVtYmVyID0gMDtcblxuXHR0ZW1wQ29sb3IgPSBuZXcgQ29sb3IoMCwgMCwgMCwgMCk7XG5cblx0Y29uc3RydWN0b3IgKG5hbWU6IHN0cmluZywgc2VxdWVuY2U6IFNlcXVlbmNlKSB7XG5cdFx0c3VwZXIobmFtZSk7XG5cdFx0dGhpcy5zZXF1ZW5jZSA9IHNlcXVlbmNlO1xuXHR9XG5cblx0Y29weSAoKTogTWVzaEF0dGFjaG1lbnQge1xuXHRcdGlmICh0aGlzLnNvdXJjZU1lc2gpIHJldHVybiB0aGlzLm5ld0xpbmtlZE1lc2goKTtcblxuXHRcdGNvbnN0IGNvcHkgPSBuZXcgTWVzaEF0dGFjaG1lbnQodGhpcy5uYW1lLCB0aGlzLnNlcXVlbmNlLmNvcHkoKSk7XG5cdFx0Y29weS5wYXRoID0gdGhpcy5wYXRoO1xuXHRcdGNvcHkuY29sb3Iuc2V0RnJvbUNvbG9yKHRoaXMuY29sb3IpO1xuXG5cdFx0dGhpcy5jb3B5VG8oY29weSk7XG5cdFx0Y29weS5yZWdpb25VVnMgPSBbXTtcblx0XHRVdGlscy5hcnJheUNvcHkodGhpcy5yZWdpb25VVnMsIDAsIGNvcHkucmVnaW9uVVZzLCAwLCB0aGlzLnJlZ2lvblVWcy5sZW5ndGgpO1xuXHRcdGNvcHkudHJpYW5nbGVzID0gW107XG5cdFx0VXRpbHMuYXJyYXlDb3B5KHRoaXMudHJpYW5nbGVzLCAwLCBjb3B5LnRyaWFuZ2xlcywgMCwgdGhpcy50cmlhbmdsZXMubGVuZ3RoKTtcblx0XHRjb3B5Lmh1bGxMZW5ndGggPSB0aGlzLmh1bGxMZW5ndGg7XG5cblx0XHQvLyBOb25lc3NlbnRpYWwuXG5cdFx0aWYgKHRoaXMuZWRnZXMpIHtcblx0XHRcdGNvcHkuZWRnZXMgPSBbXTtcblx0XHRcdFV0aWxzLmFycmF5Q29weSh0aGlzLmVkZ2VzLCAwLCBjb3B5LmVkZ2VzLCAwLCB0aGlzLmVkZ2VzLmxlbmd0aCk7XG5cdFx0fVxuXHRcdGNvcHkud2lkdGggPSB0aGlzLndpZHRoO1xuXHRcdGNvcHkuaGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG5cblx0XHRyZXR1cm4gY29weTtcblx0fVxuXG5cdHVwZGF0ZVNlcXVlbmNlICgpIHtcblx0XHR0aGlzLnNlcXVlbmNlLnVwZGF0ZSh0aGlzKTtcblx0fVxuXG5cdC8qKiBUaGUgc291cmNlIG1lc2ggaWYgdGhpcyBpcyBhIGxpbmtlZCBtZXNoLCBlbHNlIG51bGwuIEEgbGlua2VkIG1lc2ggc2hhcmVzIHRoZSB7QGxpbmsgYm9uZXN9LCB7QGxpbmsgdmVydGljZXN9LFxuXHQgKiB7QGxpbmsgcmVnaW9uVVZzfSwge0BsaW5rIHRyaWFuZ2xlc30sIHtAbGluayBodWxsTGVuZ3RofSwge0BsaW5rIGVkZ2VzfSwge0BsaW5rIHdpZHRofSwgYW5kIHtAbGluayBoZWlnaHR9IHdpdGggdGhlXG5cdCAqIHNvdXJjZSBtZXNoLCBidXQgbWF5IGhhdmUgYSBkaWZmZXJlbnQge0BsaW5rIG5hbWV9IG9yIHtAbGluayBwYXRofSwgYW5kIHRoZXJlZm9yZSBhIGRpZmZlcmVudCB0ZXh0dXJlIHJlZ2lvbi4gKi9cblx0Z2V0U291cmNlTWVzaCAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc291cmNlTWVzaDtcblx0fVxuXG5cdHNldFNvdXJjZU1lc2ggKHNvdXJjZU1lc2g6IE1lc2hBdHRhY2htZW50IHwgbnVsbCkge1xuXHRcdHRoaXMuc291cmNlTWVzaCA9IHNvdXJjZU1lc2g7XG5cdFx0aWYgKHNvdXJjZU1lc2gpIHtcblx0XHRcdHRoaXMuYm9uZXMgPSBzb3VyY2VNZXNoLmJvbmVzO1xuXHRcdFx0dGhpcy52ZXJ0aWNlcyA9IHNvdXJjZU1lc2gudmVydGljZXM7XG5cdFx0XHR0aGlzLndvcmxkVmVydGljZXNMZW5ndGggPSBzb3VyY2VNZXNoLndvcmxkVmVydGljZXNMZW5ndGg7XG5cdFx0XHR0aGlzLnJlZ2lvblVWcyA9IHNvdXJjZU1lc2gucmVnaW9uVVZzO1xuXHRcdFx0dGhpcy50cmlhbmdsZXMgPSBzb3VyY2VNZXNoLnRyaWFuZ2xlcztcblx0XHRcdHRoaXMuaHVsbExlbmd0aCA9IHNvdXJjZU1lc2guaHVsbExlbmd0aDtcblx0XHRcdHRoaXMud29ybGRWZXJ0aWNlc0xlbmd0aCA9IHNvdXJjZU1lc2gud29ybGRWZXJ0aWNlc0xlbmd0aFxuXHRcdFx0dGhpcy5lZGdlcyA9IHNvdXJjZU1lc2guZWRnZXM7XG5cdFx0XHR0aGlzLndpZHRoID0gc291cmNlTWVzaC53aWR0aDtcblx0XHRcdHRoaXMuaGVpZ2h0ID0gc291cmNlTWVzaC5oZWlnaHQ7XG5cdFx0fVxuXHR9XG5cblx0LyoqIFJldHVybnMgYSBuZXcgbWVzaCB3aXRoIHRoZSB7QGxpbmsgc291cmNlTWVzaH0gc2V0IHRvIHRoaXMgbWVzaCdzIHNvdXJjZSBtZXNoLCBpZiBhbnksIGVsc2UgdG8gdGhpcyBtZXNoLiAqKi9cblx0bmV3TGlua2VkTWVzaCAoKTogTWVzaEF0dGFjaG1lbnQge1xuXHRcdGNvbnN0IGNvcHkgPSBuZXcgTWVzaEF0dGFjaG1lbnQodGhpcy5uYW1lLCB0aGlzLnNlcXVlbmNlLmNvcHkoKSk7XG5cdFx0Y29weS50aW1lbGluZUF0dGFjaG1lbnQgPSB0aGlzLnRpbWVsaW5lQXR0YWNobWVudDtcblx0XHRjb3B5LnBhdGggPSB0aGlzLnBhdGg7XG5cdFx0Y29weS5jb2xvci5zZXRGcm9tQ29sb3IodGhpcy5jb2xvcik7XG5cdFx0Y29weS5zZXRTb3VyY2VNZXNoKHRoaXMuc291cmNlTWVzaCA/IHRoaXMuc291cmNlTWVzaCA6IHRoaXMpO1xuXHRcdGNvcHkudXBkYXRlU2VxdWVuY2UoKTtcblx0XHRyZXR1cm4gY29weTtcblx0fVxuXG5cdC8qKiBDb21wdXRlcyB7QGxpbmsgU2VxdWVuY2UuZ2V0VVZzIHwgVVZzfSBmb3IgYSBtZXNoIGF0dGFjaG1lbnQuXG5cdCAqIEBwYXJhbSB1dnMgT3V0cHV0IGFycmF5IGZvciB0aGUgY29tcHV0ZWQgVVZzLCBzYW1lIGxlbmd0aCBhcyByZWdpb25VVnMuICovXG5cdHN0YXRpYyBjb21wdXRlVVZzIChyZWdpb246IFRleHR1cmVSZWdpb24gfCBudWxsLCByZWdpb25VVnM6IE51bWJlckFycmF5TGlrZSwgdXZzOiBOdW1iZXJBcnJheUxpa2UpOiB2b2lkIHtcblx0XHRpZiAoIXJlZ2lvbikgdGhyb3cgbmV3IEVycm9yKFwiUmVnaW9uIG5vdCBzZXQuXCIpO1xuXHRcdGNvbnN0IG4gPSB1dnMubGVuZ3RoO1xuXHRcdGxldCB1ID0gcmVnaW9uLnUsIHYgPSByZWdpb24udiwgd2lkdGggPSAwLCBoZWlnaHQgPSAwO1xuXHRcdGlmIChyZWdpb24gaW5zdGFuY2VvZiBUZXh0dXJlQXRsYXNSZWdpb24pIHtcblx0XHRcdGNvbnN0IHBhZ2UgPSByZWdpb24ucGFnZTtcblx0XHRcdGNvbnN0IHRleHR1cmVXaWR0aCA9IHBhZ2Uud2lkdGgsIHRleHR1cmVIZWlnaHQgPSBwYWdlLmhlaWdodDtcblx0XHRcdHN3aXRjaCAocmVnaW9uLmRlZ3JlZXMpIHtcblx0XHRcdFx0Y2FzZSA5MDpcblx0XHRcdFx0XHR1IC09IChyZWdpb24ub3JpZ2luYWxIZWlnaHQgLSByZWdpb24ub2Zmc2V0WSAtIHJlZ2lvbi5oZWlnaHQpIC8gdGV4dHVyZVdpZHRoO1xuXHRcdFx0XHRcdHYgLT0gKHJlZ2lvbi5vcmlnaW5hbFdpZHRoIC0gcmVnaW9uLm9mZnNldFggLSByZWdpb24ud2lkdGgpIC8gdGV4dHVyZUhlaWdodDtcblx0XHRcdFx0XHR3aWR0aCA9IHJlZ2lvbi5vcmlnaW5hbEhlaWdodCAvIHRleHR1cmVXaWR0aDtcblx0XHRcdFx0XHRoZWlnaHQgPSByZWdpb24ub3JpZ2luYWxXaWR0aCAvIHRleHR1cmVIZWlnaHQ7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpICs9IDIpIHtcblx0XHRcdFx0XHRcdHV2c1tpXSA9IHUgKyByZWdpb25VVnNbaSArIDFdICogd2lkdGg7XG5cdFx0XHRcdFx0XHR1dnNbaSArIDFdID0gdiArICgxIC0gcmVnaW9uVVZzW2ldKSAqIGhlaWdodDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRjYXNlIDE4MDpcblx0XHRcdFx0XHR1IC09IChyZWdpb24ub3JpZ2luYWxXaWR0aCAtIHJlZ2lvbi5vZmZzZXRYIC0gcmVnaW9uLndpZHRoKSAvIHRleHR1cmVXaWR0aDtcblx0XHRcdFx0XHR2IC09IHJlZ2lvbi5vZmZzZXRZIC8gdGV4dHVyZUhlaWdodDtcblx0XHRcdFx0XHR3aWR0aCA9IHJlZ2lvbi5vcmlnaW5hbFdpZHRoIC8gdGV4dHVyZVdpZHRoO1xuXHRcdFx0XHRcdGhlaWdodCA9IHJlZ2lvbi5vcmlnaW5hbEhlaWdodCAvIHRleHR1cmVIZWlnaHQ7XG5cdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpICs9IDIpIHtcblx0XHRcdFx0XHRcdHV2c1tpXSA9IHUgKyAoMSAtIHJlZ2lvblVWc1tpXSkgKiB3aWR0aDtcblx0XHRcdFx0XHRcdHV2c1tpICsgMV0gPSB2ICsgKDEgLSByZWdpb25VVnNbaSArIDFdKSAqIGhlaWdodDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRjYXNlIDI3MDpcblx0XHRcdFx0XHR1IC09IHJlZ2lvbi5vZmZzZXRZIC8gdGV4dHVyZVdpZHRoO1xuXHRcdFx0XHRcdHYgLT0gcmVnaW9uLm9mZnNldFggLyB0ZXh0dXJlSGVpZ2h0O1xuXHRcdFx0XHRcdHdpZHRoID0gcmVnaW9uLm9yaWdpbmFsSGVpZ2h0IC8gdGV4dHVyZVdpZHRoO1xuXHRcdFx0XHRcdGhlaWdodCA9IHJlZ2lvbi5vcmlnaW5hbFdpZHRoIC8gdGV4dHVyZUhlaWdodDtcblx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG47IGkgKz0gMikge1xuXHRcdFx0XHRcdFx0dXZzW2ldID0gdSArICgxIC0gcmVnaW9uVVZzW2kgKyAxXSkgKiB3aWR0aDtcblx0XHRcdFx0XHRcdHV2c1tpICsgMV0gPSB2ICsgcmVnaW9uVVZzW2ldICogaGVpZ2h0O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0dSAtPSByZWdpb24ub2Zmc2V0WCAvIHRleHR1cmVXaWR0aDtcblx0XHRcdFx0XHR2IC09IChyZWdpb24ub3JpZ2luYWxIZWlnaHQgLSByZWdpb24ub2Zmc2V0WSAtIHJlZ2lvbi5oZWlnaHQpIC8gdGV4dHVyZUhlaWdodDtcblx0XHRcdFx0XHR3aWR0aCA9IHJlZ2lvbi5vcmlnaW5hbFdpZHRoIC8gdGV4dHVyZVdpZHRoO1xuXHRcdFx0XHRcdGhlaWdodCA9IHJlZ2lvbi5vcmlnaW5hbEhlaWdodCAvIHRleHR1cmVIZWlnaHQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICghcmVnaW9uKSB7XG5cdFx0XHR1ID0gdiA9IDA7XG5cdFx0XHR3aWR0aCA9IGhlaWdodCA9IDE7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHdpZHRoID0gcmVnaW9uLnUyIC0gdTtcblx0XHRcdGhlaWdodCA9IHJlZ2lvbi52MiAtIHY7XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpICs9IDIpIHtcblx0XHRcdHV2c1tpXSA9IHUgKyByZWdpb25VVnNbaV0gKiB3aWR0aDtcblx0XHRcdHV2c1tpICsgMV0gPSB2ICsgcmVnaW9uVVZzW2kgKyAxXSAqIGhlaWdodDtcblx0XHR9XG5cdH1cbn1cbiJdfQ==