UNPKG

@esotericsoftware/spine-core

Version:
214 lines 30.5 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 { MeshAttachment } from "./attachments/MeshAttachment.js"; import { Color } from "./Utils.js"; /** Stores an entry in the skin consisting of the slot index, name, and attachment **/ export class SkinEntry { /** The {@link Skeleton.slots} index. */ slotIndex = 0; placeholder; /** The attachment for this skin entry. */ attachment; constructor(slotIndex = 0, placeholder, attachment) { this.slotIndex = slotIndex; this.placeholder = placeholder; this.attachment = attachment; } } /** Stores attachments by slot index and placeholder name. Multiple {@link Skeleton} instances can use the same skins. * * See {@link SkeletonData.defaultSkin}, {@link Skeleton.skin}, and * [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. */ export class Skin { /** The skin's name, unique across all skins in the skeleton. * * See {@link SkeletonData.findSkin}. */ name; attachments = []; bones = []; // biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types constraints = []; /** The color of the skin as it was in Spine, or a default color if nonessential data was not exported. */ color = new Color(0.99607843, 0.61960787, 0.30980393, 1); // fe9e4fff constructor(name) { if (!name) throw new Error("name cannot be null."); this.name = name; } /** Adds an attachment to the skin for the specified slot index and name. */ setAttachment(slotIndex, placeholder, attachment) { if (!attachment) throw new Error("attachment cannot be null."); const attachments = this.attachments; if (slotIndex >= attachments.length) attachments.length = slotIndex + 1; if (!attachments[slotIndex]) attachments[slotIndex] = {}; attachments[slotIndex][placeholder] = attachment; } /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ addSkin(skin) { for (let i = 0; i < skin.bones.length; i++) { const bone = skin.bones[i]; let contained = false; for (let ii = 0; ii < this.bones.length; ii++) { if (this.bones[ii] === bone) { contained = true; break; } } if (!contained) this.bones.push(bone); } for (let i = 0; i < skin.constraints.length; i++) { const constraint = skin.constraints[i]; let contained = false; for (let ii = 0; ii < this.constraints.length; ii++) { if (this.constraints[ii] === constraint) { contained = true; break; } } if (!contained) this.constraints.push(constraint); } const attachments = skin.getAttachments(); for (let i = 0; i < attachments.length; i++) { const attachment = attachments[i]; this.setAttachment(attachment.slotIndex, attachment.placeholder, attachment.attachment); } } /** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not * copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */ copySkin(skin) { for (let i = 0; i < skin.bones.length; i++) { const bone = skin.bones[i]; let contained = false; for (let ii = 0; ii < this.bones.length; ii++) { if (this.bones[ii] === bone) { contained = true; break; } } if (!contained) this.bones.push(bone); } for (let i = 0; i < skin.constraints.length; i++) { const constraint = skin.constraints[i]; let contained = false; for (let ii = 0; ii < this.constraints.length; ii++) { if (this.constraints[ii] === constraint) { contained = true; break; } } if (!contained) this.constraints.push(constraint); } const attachments = skin.getAttachments(); for (let i = 0; i < attachments.length; i++) { const attachment = attachments[i]; if (!attachment.attachment) continue; if (attachment.attachment instanceof MeshAttachment) { attachment.attachment = attachment.attachment.newLinkedMesh(); this.setAttachment(attachment.slotIndex, attachment.placeholder, attachment.attachment); } else { attachment.attachment = attachment.attachment.copy(); this.setAttachment(attachment.slotIndex, attachment.placeholder, attachment.attachment); } } } /** Returns the attachment for the specified slot index and placeholder, or null. */ getAttachment(slotIndex, placeholder) { const dictionary = this.attachments[slotIndex]; return dictionary ? dictionary[placeholder] : null; } /** Removes the attachment in the skin for the specified slot index and placeholder, if any. */ removeAttachment(slotIndex, placeholder) { const dictionary = this.attachments[slotIndex]; if (dictionary) delete dictionary[placeholder]; } /** Returns all attachments in this skin. */ getAttachments() { const entries = []; for (let i = 0; i < this.attachments.length; i++) { const slotAttachments = this.attachments[i]; if (slotAttachments) { for (const name in slotAttachments) { const attachment = slotAttachments[name]; if (attachment) entries.push(new SkinEntry(i, name, attachment)); } } } return entries; } /** Returns all attachments in this skin for the specified slot index. */ getAttachmentsForSlot(slotIndex, attachments) { const slotAttachments = this.attachments[slotIndex]; if (slotAttachments) { for (const name in slotAttachments) { const attachment = slotAttachments[name]; if (attachment) attachments.push(new SkinEntry(slotIndex, name, attachment)); } } } /** Clears all attachments, bones, and constraints. */ clear() { this.attachments.length = 0; this.bones.length = 0; this.constraints.length = 0; } /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ attachAll(skeleton, oldSkin) { let slotIndex = 0; for (let i = 0; i < skeleton.slots.length; i++) { const slot = skeleton.slots[i]; const slotAttachment = slot.pose.getAttachment(); if (slotAttachment && slotIndex < oldSkin.attachments.length) { const dictionary = oldSkin.attachments[slotIndex]; for (const placeholder in dictionary) { const skinAttachment = dictionary[placeholder]; if (slotAttachment === skinAttachment) { const attachment = this.getAttachment(slotIndex, placeholder); if (attachment) slot.pose.setAttachment(attachment); break; } } } slotIndex++; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ta2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFLakUsT0FBTyxFQUFFLEtBQUssRUFBa0IsTUFBTSxZQUFZLENBQUM7QUFFbkQsc0ZBQXNGO0FBQ3RGLE1BQU0sT0FBTyxTQUFTO0lBRXJCLHdDQUF3QztJQUN4QyxTQUFTLEdBQVcsQ0FBQyxDQUFDO0lBRXRCLFdBQVcsQ0FBUztJQUVwQiwwQ0FBMEM7SUFDMUMsVUFBVSxDQUFZO0lBRXRCLFlBQWEsWUFBb0IsQ0FBQyxFQUFFLFdBQW1CLEVBQUUsVUFBc0I7UUFDOUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDOUIsQ0FBQztDQUNEO0FBRUQ7OzttR0FHbUc7QUFDbkcsTUFBTSxPQUFPLElBQUk7SUFDaEI7OzRDQUV3QztJQUN4QyxJQUFJLENBQVM7SUFFYixXQUFXLEdBQUcsRUFBNkIsQ0FBQztJQUM1QyxLQUFLLEdBQUcsRUFBZ0IsQ0FBQztJQUN6QixvR0FBb0c7SUFDcEcsV0FBVyxHQUFHLEVBQWdDLENBQUM7SUFFL0MsMEdBQTBHO0lBQzFHLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVc7SUFFckUsWUFBYSxJQUFZO1FBQ3hCLElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLENBQUM7SUFFRCw0RUFB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ZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBBdHRhY2htZW50IH0gZnJvbSBcIi4vYXR0YWNobWVudHMvQXR0YWNobWVudC5qc1wiO1xuaW1wb3J0IHsgTWVzaEF0dGFjaG1lbnQgfSBmcm9tIFwiLi9hdHRhY2htZW50cy9NZXNoQXR0YWNobWVudC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBCb25lRGF0YSB9IGZyb20gXCIuL0JvbmVEYXRhLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENvbnN0cmFpbnREYXRhIH0gZnJvbSBcIi4vQ29uc3RyYWludERhdGEuanNcIjtcbmltcG9ydCB0eXBlIHsgU2tlbGV0b24gfSBmcm9tIFwiLi9Ta2VsZXRvbi5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbkRhdGEgfSBmcm9tIFwiLi9Ta2VsZXRvbkRhdGEuanNcIjtcbmltcG9ydCB7IENvbG9yLCB0eXBlIFN0cmluZ01hcCB9IGZyb20gXCIuL1V0aWxzLmpzXCI7XG5cbi8qKiBTdG9yZXMgYW4gZW50cnkgaW4gdGhlIHNraW4gY29uc2lzdGluZyBvZiB0aGUgc2xvdCBpbmRleCwgbmFtZSwgYW5kIGF0dGFjaG1lbnQgKiovXG5leHBvcnQgY2xhc3MgU2tpbkVudHJ5IHtcblxuXHQvKiogVGhlIHtAbGluayBTa2VsZXRvbi5zbG90c30gaW5kZXguICovXG5cdHNsb3RJbmRleDogbnVtYmVyID0gMDtcblxuXHRwbGFjZWhvbGRlcjogc3RyaW5nO1xuXG5cdC8qKiBUaGUgYXR0YWNobWVudCBmb3IgdGhpcyBza2luIGVudHJ5LiAqL1xuXHRhdHRhY2htZW50OiBBdHRhY2htZW50XG5cblx0Y29uc3RydWN0b3IgKHNsb3RJbmRleDogbnVtYmVyID0gMCwgcGxhY2Vob2xkZXI6IHN0cmluZywgYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuXHRcdHRoaXMuc2xvdEluZGV4ID0gc2xvdEluZGV4O1xuXHRcdHRoaXMucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcblx0XHR0aGlzLmF0dGFjaG1lbnQgPSBhdHRhY2htZW50O1xuXHR9XG59XG5cbi8qKiBTdG9yZXMgYXR0YWNobWVudHMgYnkgc2xvdCBpbmRleCBhbmQgcGxhY2Vob2xkZXIgbmFtZS4gTXVsdGlwbGUge0BsaW5rIFNrZWxldG9ufSBpbnN0YW5jZXMgY2FuIHVzZSB0aGUgc2FtZSBza2lucy5cbiAqXG4gKiBTZWUge0BsaW5rIFNrZWxldG9uRGF0YS5kZWZhdWx0U2tpbn0sIHtAbGluayBTa2VsZXRvbi5za2lufSwgYW5kXG4gKiBbUnVudGltZSBza2luc10oaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLXJ1bnRpbWUtc2tpbnMpIGluIHRoZSBTcGluZSBSdW50aW1lcyBHdWlkZS4gKi9cbmV4cG9ydCBjbGFzcyBTa2luIHtcblx0LyoqIFRoZSBza2luJ3MgbmFtZSwgdW5pcXVlIGFjcm9zcyBhbGwgc2tpbnMgaW4gdGhlIHNrZWxldG9uLlxuXHQgKlxuXHQgKiBTZWUge0BsaW5rIFNrZWxldG9uRGF0YS5maW5kU2tpbn0uICovXG5cdG5hbWU6IHN0cmluZztcblxuXHRhdHRhY2htZW50cyA9IFtdIGFzIFN0cmluZ01hcDxBdHRhY2htZW50PltdO1xuXHRib25lcyA9IFtdIGFzIEJvbmVEYXRhW107XG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogcmVmZXJlbmNlIHJ1bnRpbWUgZG9lcyBub3QgcmVzdHJpY3QgdG8gc3BlY2lmaWMgdHlwZXNcblx0Y29uc3RyYWludHMgPSBbXSBhcyBDb25zdHJhaW50RGF0YTxhbnksIGFueT5bXTtcblxuXHQvKiogVGhlIGNvbG9yIG9mIHRoZSBza2luIGFzIGl0IHdhcyBpbiBTcGluZSwgb3IgYSBkZWZhdWx0IGNvbG9yIGlmIG5vbmVzc2VudGlhbCBkYXRhIHdhcyBub3QgZXhwb3J0ZWQuICovXG5cdGNvbG9yID0gbmV3IENvbG9yKDAuOTk2MDc4NDMsIDAuNjE5NjA3ODcsIDAuMzA5ODAzOTMsIDEpOyAvLyBmZTllNGZmZlxuXG5cdGNvbnN0cnVjdG9yIChuYW1lOiBzdHJpbmcpIHtcblx0XHRpZiAoIW5hbWUpIHRocm93IG5ldyBFcnJvcihcIm5hbWUgY2Fubm90IGJlIG51bGwuXCIpO1xuXHRcdHRoaXMubmFtZSA9IG5hbWU7XG5cdH1cblxuXHQvKiogQWRkcyBhbiBhdHRhY2htZW50IHRvIHRoZSBza2luIGZvciB0aGUgc3BlY2lmaWVkIHNsb3QgaW5kZXggYW5kIG5hbWUuICovXG5cdHNldEF0dGFjaG1lbnQgKHNsb3RJbmRleDogbnVtYmVyLCBwbGFjZWhvbGRlcjogc3RyaW5nLCBhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG5cdFx0aWYgKCFhdHRhY2htZW50KSB0aHJvdyBuZXcgRXJyb3IoXCJhdHRhY2htZW50IGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHRjb25zdCBhdHRhY2htZW50cyA9IHRoaXMuYXR0YWNobWVudHM7XG5cdFx0aWYgKHNsb3RJbmRleCA+PSBhdHRhY2htZW50cy5sZW5ndGgpIGF0dGFjaG1lbnRzLmxlbmd0aCA9IHNsb3RJbmRleCArIDE7XG5cdFx0aWYgKCFhdHRhY2htZW50c1tzbG90SW5kZXhdKSBhdHRhY2htZW50c1tzbG90SW5kZXhdID0ge307XG5cdFx0YXR0YWNobWVudHNbc2xvdEluZGV4XVtwbGFjZWhvbGRlcl0gPSBhdHRhY2htZW50O1xuXHR9XG5cblx0LyoqIEFkZHMgYWxsIGF0dGFjaG1lbnRzLCBib25lcywgYW5kIGNvbnN0cmFpbnRzIGZyb20gdGhlIHNwZWNpZmllZCBza2luIHRvIHRoaXMgc2tpbi4gKi9cblx0YWRkU2tpbiAoc2tpbjogU2tpbikge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc2tpbi5ib25lcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgYm9uZSA9IHNraW4uYm9uZXNbaV07XG5cdFx0XHRsZXQgY29udGFpbmVkID0gZmFsc2U7XG5cdFx0XHRmb3IgKGxldCBpaSA9IDA7IGlpIDwgdGhpcy5ib25lcy5sZW5ndGg7IGlpKyspIHtcblx0XHRcdFx0aWYgKHRoaXMuYm9uZXNbaWldID09PSBib25lKSB7XG5cdFx0XHRcdFx0Y29udGFpbmVkID0gdHJ1ZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKCFjb250YWluZWQpIHRoaXMuYm9uZXMucHVzaChib25lKTtcblx0XHR9XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHNraW4uY29uc3RyYWludHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGNvbnN0cmFpbnQgPSBza2luLmNvbnN0cmFpbnRzW2ldO1xuXHRcdFx0bGV0IGNvbnRhaW5lZCA9IGZhbHNlO1xuXHRcdFx0Zm9yIChsZXQgaWkgPSAwOyBpaSA8IHRoaXMuY29uc3RyYWludHMubGVuZ3RoOyBpaSsrKSB7XG5cdFx0XHRcdGlmICh0aGlzLmNvbnN0cmFpbnRzW2lpXSA9PT0gY29uc3RyYWludCkge1xuXHRcdFx0XHRcdGNvbnRhaW5lZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICghY29udGFpbmVkKSB0aGlzLmNvbnN0cmFpbnRzLnB1c2goY29uc3RyYWludCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgYXR0YWNobWVudHMgPSBza2luLmdldEF0dGFjaG1lbnRzKCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhdHRhY2htZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgYXR0YWNobWVudCA9IGF0dGFjaG1lbnRzW2ldO1xuXHRcdFx0dGhpcy5zZXRBdHRhY2htZW50KGF0dGFjaG1lbnQuc2xvdEluZGV4LCBhdHRhY2htZW50LnBsYWNlaG9sZGVyLCBhdHRhY2htZW50LmF0dGFjaG1lbnQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKiBBZGRzIGFsbCBib25lcyBhbmQgY29uc3RyYWludHMgYW5kIGNvcGllcyBvZiBhbGwgYXR0YWNobWVudHMgZnJvbSB0aGUgc3BlY2lmaWVkIHNraW4gdG8gdGhpcyBza2luLiBNZXNoIGF0dGFjaG1lbnRzIGFyZSBub3Rcblx0ICogY29waWVkLCBpbnN0ZWFkIGEgbmV3IGxpbmtlZCBtZXNoIGlzIGNyZWF0ZWQuIFRoZSBhdHRhY2htZW50IGNvcGllcyBjYW4gYmUgbW9kaWZpZWQgd2l0aG91dCBhZmZlY3RpbmcgdGhlIG9yaWdpbmFscy4gKi9cblx0Y29weVNraW4gKHNraW46IFNraW4pIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHNraW4uYm9uZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGJvbmUgPSBza2luLmJvbmVzW2ldO1xuXHRcdFx0bGV0IGNvbnRhaW5lZCA9IGZhbHNlO1xuXHRcdFx0Zm9yIChsZXQgaWkgPSAwOyBpaSA8IHRoaXMuYm9uZXMubGVuZ3RoOyBpaSsrKSB7XG5cdFx0XHRcdGlmICh0aGlzLmJvbmVzW2lpXSA9PT0gYm9uZSkge1xuXHRcdFx0XHRcdGNvbnRhaW5lZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICghY29udGFpbmVkKSB0aGlzLmJvbmVzLnB1c2goYm9uZSk7XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBza2luLmNvbnN0cmFpbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBjb25zdHJhaW50ID0gc2tpbi5jb25zdHJhaW50c1tpXTtcblx0XHRcdGxldCBjb250YWluZWQgPSBmYWxzZTtcblx0XHRcdGZvciAobGV0IGlpID0gMDsgaWkgPCB0aGlzLmNvbnN0cmFpbnRzLmxlbmd0aDsgaWkrKykge1xuXHRcdFx0XHRpZiAodGhpcy5jb25zdHJhaW50c1tpaV0gPT09IGNvbnN0cmFpbnQpIHtcblx0XHRcdFx0XHRjb250YWluZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoIWNvbnRhaW5lZCkgdGhpcy5jb25zdHJhaW50cy5wdXNoKGNvbnN0cmFpbnQpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGF0dGFjaG1lbnRzID0gc2tpbi5nZXRBdHRhY2htZW50cygpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXR0YWNobWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGF0dGFjaG1lbnQgPSBhdHRhY2htZW50c1tpXTtcblx0XHRcdGlmICghYXR0YWNobWVudC5hdHRhY2htZW50KSBjb250aW51ZTtcblx0XHRcdGlmIChhdHRhY2htZW50LmF0dGFjaG1lbnQgaW5zdGFuY2VvZiBNZXNoQXR0YWNobWVudCkge1xuXHRcdFx0XHRhdHRhY2htZW50LmF0dGFjaG1lbnQgPSBhdHRhY2htZW50LmF0dGFjaG1lbnQubmV3TGlua2VkTWVzaCgpO1xuXHRcdFx0XHR0aGlzLnNldEF0dGFjaG1lbnQoYXR0YWNobWVudC5zbG90SW5kZXgsIGF0dGFjaG1lbnQucGxhY2Vob2xkZXIsIGF0dGFjaG1lbnQuYXR0YWNobWVudCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRhdHRhY2htZW50LmF0dGFjaG1lbnQgPSBhdHRhY2htZW50LmF0dGFjaG1lbnQuY29weSgpO1xuXHRcdFx0XHR0aGlzLnNldEF0dGFjaG1lbnQoYXR0YWNobWVudC5zbG90SW5kZXgsIGF0dGFjaG1lbnQucGxhY2Vob2xkZXIsIGF0dGFjaG1lbnQuYXR0YWNobWVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqIFJldHVybnMgdGhlIGF0dGFjaG1lbnQgZm9yIHRoZSBzcGVjaWZpZWQgc2xvdCBpbmRleCBhbmQgcGxhY2Vob2xkZXIsIG9yIG51bGwuICovXG5cdGdldEF0dGFjaG1lbnQgKHNsb3RJbmRleDogbnVtYmVyLCBwbGFjZWhvbGRlcjogc3RyaW5nKTogQXR0YWNobWVudCB8IG51bGwge1xuXHRcdGNvbnN0IGRpY3Rpb25hcnkgPSB0aGlzLmF0dGFjaG1lbnRzW3Nsb3RJbmRleF07XG5cdFx0cmV0dXJuIGRpY3Rpb25hcnkgPyBkaWN0aW9uYXJ5W3BsYWNlaG9sZGVyXSA6IG51bGw7XG5cdH1cblxuXHQvKiogUmVtb3ZlcyB0aGUgYXR0YWNobWVudCBpbiB0aGUgc2tpbiBmb3IgdGhlIHNwZWNpZmllZCBzbG90IGluZGV4IGFuZCBwbGFjZWhvbGRlciwgaWYgYW55LiAqL1xuXHRyZW1vdmVBdHRhY2htZW50IChzbG90SW5kZXg6IG51bWJlciwgcGxhY2Vob2xkZXI6IHN0cmluZykge1xuXHRcdGNvbnN0IGRpY3Rpb25hcnkgPSB0aGlzLmF0dGFjaG1lbnRzW3Nsb3RJbmRleF07XG5cdFx0aWYgKGRpY3Rpb25hcnkpIGRlbGV0ZSBkaWN0aW9uYXJ5W3BsYWNlaG9sZGVyXTtcblx0fVxuXG5cdC8qKiBSZXR1cm5zIGFsbCBhdHRhY2htZW50cyBpbiB0aGlzIHNraW4uICovXG5cdGdldEF0dGFjaG1lbnRzICgpOiBBcnJheTxTa2luRW50cnk+IHtcblx0XHRjb25zdCBlbnRyaWVzOiBTa2luRW50cnlbXSA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hdHRhY2htZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgc2xvdEF0dGFjaG1lbnRzID0gdGhpcy5hdHRhY2htZW50c1tpXTtcblx0XHRcdGlmIChzbG90QXR0YWNobWVudHMpIHtcblx0XHRcdFx0Zm9yIChjb25zdCBuYW1lIGluIHNsb3RBdHRhY2htZW50cykge1xuXHRcdFx0XHRcdGNvbnN0IGF0dGFjaG1lbnQgPSBzbG90QXR0YWNobWVudHNbbmFtZV07XG5cdFx0XHRcdFx0aWYgKGF0dGFjaG1lbnQpIGVudHJpZXMucHVzaChuZXcgU2tpbkVudHJ5KGksIG5hbWUsIGF0dGFjaG1lbnQpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZW50cmllcztcblx0fVxuXG5cdC8qKiBSZXR1cm5zIGFsbCBhdHRhY2htZW50cyBpbiB0aGlzIHNraW4gZm9yIHRoZSBzcGVjaWZpZWQgc2xvdCBpbmRleC4gKi9cblx0Z2V0QXR0YWNobWVudHNGb3JTbG90IChzbG90SW5kZXg6IG51bWJlciwgYXR0YWNobWVudHM6IEFycmF5PFNraW5FbnRyeT4pIHtcblx0XHRjb25zdCBzbG90QXR0YWNobWVudHMgPSB0aGlzLmF0dGFjaG1lbnRzW3Nsb3RJbmRleF07XG5cdFx0aWYgKHNsb3RBdHRhY2htZW50cykge1xuXHRcdFx0Zm9yIChjb25zdCBuYW1lIGluIHNsb3RBdHRhY2htZW50cykge1xuXHRcdFx0XHRjb25zdCBhdHRhY2htZW50ID0gc2xvdEF0dGFjaG1lbnRzW25hbWVdO1xuXHRcdFx0XHRpZiAoYXR0YWNobWVudCkgYXR0YWNobWVudHMucHVzaChuZXcgU2tpbkVudHJ5KHNsb3RJbmRleCwgbmFtZSwgYXR0YWNobWVudCkpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKiBDbGVhcnMgYWxsIGF0dGFjaG1lbnRzLCBib25lcywgYW5kIGNvbnN0cmFpbnRzLiAqL1xuXHRjbGVhciAoKSB7XG5cdFx0dGhpcy5hdHRhY2htZW50cy5sZW5ndGggPSAwO1xuXHRcdHRoaXMuYm9uZXMubGVuZ3RoID0gMDtcblx0XHR0aGlzLmNvbnN0cmFpbnRzLmxlbmd0aCA9IDA7XG5cdH1cblxuXHQvKiogQXR0YWNoIGVhY2ggYXR0YWNobWVudCBpbiB0aGlzIHNraW4gaWYgdGhlIGNvcnJlc3BvbmRpbmcgYXR0YWNobWVudCBpbiB0aGUgb2xkIHNraW4gaXMgY3VycmVudGx5IGF0dGFjaGVkLiAqL1xuXHRhdHRhY2hBbGwgKHNrZWxldG9uOiBTa2VsZXRvbiwgb2xkU2tpbjogU2tpbikge1xuXHRcdGxldCBzbG90SW5kZXggPSAwO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc2tlbGV0b24uc2xvdHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IHNsb3QgPSBza2VsZXRvbi5zbG90c1tpXTtcblx0XHRcdGNvbnN0IHNsb3RBdHRhY2htZW50ID0gc2xvdC5wb3NlLmdldEF0dGFjaG1lbnQoKTtcblx0XHRcdGlmIChzbG90QXR0YWNobWVudCAmJiBzbG90SW5kZXggPCBvbGRTa2luLmF0dGFjaG1lbnRzLmxlbmd0aCkge1xuXHRcdFx0XHRjb25zdCBkaWN0aW9uYXJ5ID0gb2xkU2tpbi5hdHRhY2htZW50c1tzbG90SW5kZXhdO1xuXHRcdFx0XHRmb3IgKGNvbnN0IHBsYWNlaG9sZGVyIGluIGRpY3Rpb25hcnkpIHtcblx0XHRcdFx0XHRjb25zdCBza2luQXR0YWNobWVudDogQXR0YWNobWVudCA9IGRpY3Rpb25hcnlbcGxhY2Vob2xkZXJdO1xuXHRcdFx0XHRcdGlmIChzbG90QXR0YWNobWVudCA9PT0gc2tpbkF0dGFjaG1lbnQpIHtcblx0XHRcdFx0XHRcdGNvbnN0IGF0dGFjaG1lbnQgPSB0aGlzLmdldEF0dGFjaG1lbnQoc2xvdEluZGV4LCBwbGFjZWhvbGRlcik7XG5cdFx0XHRcdFx0XHRpZiAoYXR0YWNobWVudCkgc2xvdC5wb3NlLnNldEF0dGFjaG1lbnQoYXR0YWNobWVudCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHNsb3RJbmRleCsrO1xuXHRcdH1cblx0fVxufVxuIl19