UNPKG

@esotericsoftware/spine-core

Version:
319 lines 46.7 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 { ConstraintData } from "./ConstraintData.js"; import { TransformConstraint } from "./TransformConstraint.js"; import { TransformConstraintPose } from "./TransformConstraintPose.js"; import { MathUtils } from "./Utils.js"; /** Stores the setup pose for a {@link TransformConstraint}. * * See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. */ export class TransformConstraintData extends ConstraintData { static ROTATION = 0; static X = 1; static Y = 2; static SCALEX = 3; static SCALEY = 4; static SHEARY = 5; /** The bones that will be modified by this transform constraint. */ bones = []; /** The bone whose world transform will be copied to the constrained bones. */ set source(source) { this._source = source; } get source() { if (!this._source) throw new Error("BoneData not set."); else return this._source; } _source = null; offsets = [0, 0, 0, 0, 0, 0]; /** An offset added to the constrained bone X translation. */ offsetX = 0; /** An offset added to the constrained bone Y translation. */ offsetY = 0; /** Reads the source bone's local transform instead of its world transform. */ localSource = false; /** Sets the constrained bones' local transforms instead of their world transforms. */ localTarget = false; /** Adds the source bone transform to the constrained bones instead of setting it absolutely. */ additive = false; /** Prevents constrained bones from exceeding the ranged defined by {@link ToProperty.offset} and {@link ToProperty.max}. */ clamp = false; /** The mapping of transform properties to other transform properties. */ properties = []; constructor(name) { super(name, new TransformConstraintPose()); } create(skeleton) { return new TransformConstraint(this, skeleton); } /** An offset added to the constrained bone rotation. */ getOffsetRotation() { return this.offsets[TransformConstraintData.ROTATION]; } setOffsetRotation(offsetRotation) { this.offsets[TransformConstraintData.ROTATION] = offsetRotation; } /** An offset added to the constrained bone X translation. */ getOffsetX() { return this.offsets[TransformConstraintData.X]; } setOffsetX(offsetX) { this.offsets[TransformConstraintData.X] = offsetX; } /** An offset added to the constrained bone Y translation. */ getOffsetY() { return this.offsets[TransformConstraintData.Y]; } setOffsetY(offsetY) { this.offsets[TransformConstraintData.Y] = offsetY; } /** An offset added to the constrained bone scaleX. */ getOffsetScaleX() { return this.offsets[TransformConstraintData.SCALEX]; } setOffsetScaleX(offsetScaleX) { this.offsets[TransformConstraintData.SCALEX] = offsetScaleX; } /** An offset added to the constrained bone scaleY. */ getOffsetScaleY() { return this.offsets[TransformConstraintData.SCALEY]; } setOffsetScaleY(offsetScaleY) { this.offsets[TransformConstraintData.SCALEY] = offsetScaleY; } /** An offset added to the constrained bone shearY. */ getOffsetShearY() { return this.offsets[TransformConstraintData.SHEARY]; } setOffsetShearY(offsetShearY) { this.offsets[TransformConstraintData.SHEARY] = offsetShearY; } } /** Source property for a {@link TransformConstraint}. */ export class FromProperty { /** The value of this property that corresponds to {@link ToProperty.offset}. */ offset = 0; /** Constrained properties. */ to = []; } /** Constrained property for a {@link TransformConstraint}. */ export class ToProperty { /** The value of this property that corresponds to {@link FromProperty.offset}. */ offset = 0; /** The maximum value of this property when {@link TransformConstraintData.clamp clamped}. */ max = 0; /** The scale of the {@link FromProperty} value in relation to this property. */ scale = 0; } export class FromRotate extends FromProperty { value(skeleton, source, local, offsets) { if (local) return source.rotation + offsets[TransformConstraintData.ROTATION]; const sx = skeleton.scaleX, sy = skeleton.scaleY; let value = Math.atan2(source.c / sy, source.a / sx) * MathUtils.radDeg + ((source.a * source.d - source.b * source.c) * sx * sy > 0 ? offsets[TransformConstraintData.ROTATION] : -offsets[TransformConstraintData.ROTATION]); if (value < 0) value += 360; return value; } } export class ToRotate extends ToProperty { mix(pose) { return pose.mixRotate; } apply(skeleton, pose, bone, value, local, additive) { if (local) bone.rotation += (additive ? value : value - bone.rotation) * pose.mixRotate; else { const sx = skeleton.scaleX, sy = skeleton.scaleY, ix = 1 / sx, iy = 1 / sy; const a = bone.a * ix, b = bone.b * ix, c = bone.c * iy, d = bone.d * iy; value *= MathUtils.degRad; if (!additive) value -= Math.atan2(c, a); if (value > MathUtils.PI) value -= MathUtils.PI2; else if (value < -MathUtils.PI) // value += MathUtils.PI2; value *= pose.mixRotate; const cos = Math.cos(value), sin = Math.sin(value); bone.a = (cos * a - sin * c) * sx; bone.b = (cos * b - sin * d) * sx; bone.c = (sin * a + cos * c) * sy; bone.d = (sin * b + cos * d) * sy; } } } export class FromX extends FromProperty { value(skeleton, source, local, offsets) { return local ? source.x + offsets[TransformConstraintData.X] : (offsets[TransformConstraintData.X] * source.a + offsets[TransformConstraintData.Y] * source.b + source.worldX) / skeleton.scaleX; } } export class ToX extends ToProperty { mix(pose) { return pose.mixX; } apply(skeleton, pose, bone, value, local, additive) { if (local) bone.x += (additive ? value : value - bone.x) * pose.mixX; else { if (!additive) value -= bone.worldX / skeleton.scaleX; bone.worldX += value * pose.mixX * skeleton.scaleX; } } } export class FromY extends FromProperty { value(skeleton, source, local, offsets) { return local ? source.y + offsets[TransformConstraintData.Y] : (offsets[TransformConstraintData.X] * source.c + offsets[TransformConstraintData.Y] * source.d + source.worldY) / skeleton.scaleY; } } export class ToY extends ToProperty { mix(pose) { return pose.mixY; } apply(skeleton, pose, bone, value, local, additive) { if (local) bone.y += (additive ? value : value - bone.y) * pose.mixY; else { if (!additive) value -= bone.worldY / skeleton.scaleY; bone.worldY += value * pose.mixY * skeleton.scaleY; } } } export class FromScaleX extends FromProperty { value(skeleton, source, local, offsets) { if (local) return source.scaleX + offsets[TransformConstraintData.SCALEX]; const a = source.a / skeleton.scaleX, c = source.c / skeleton.scaleY; return Math.sqrt(a * a + c * c) + offsets[TransformConstraintData.SCALEX]; } } export class ToScaleX extends ToProperty { mix(pose) { return pose.mixScaleX; } apply(skeleton, pose, bone, value, local, additive) { if (local) { if (additive) bone.scaleX *= 1 + (value - 1) * pose.mixScaleX; else if (bone.scaleX !== 0) // bone.scaleX += (value - bone.scaleX) * pose.mixScaleX; } else if (additive) { const s = 1 + (value - 1) * pose.mixScaleX; bone.a *= s; bone.c *= s; } else { let a = bone.a / skeleton.scaleX, c = bone.c / skeleton.scaleY, s = Math.sqrt(a * a + c * c); if (s !== 0) { s = 1 + (value - s) * pose.mixScaleX / s; bone.a *= s; bone.c *= s; } } } } export class FromScaleY extends FromProperty { value(skeleton, source, local, offsets) { if (local) return source.scaleY + offsets[TransformConstraintData.SCALEY]; const b = source.b / skeleton.scaleX, d = source.d / skeleton.scaleY; return Math.sqrt(b * b + d * d) + offsets[TransformConstraintData.SCALEY]; } } export class ToScaleY extends ToProperty { mix(pose) { return pose.mixScaleY; } apply(skeleton, pose, bone, value, local, additive) { if (local) { if (additive) bone.scaleY *= 1 + (value - 1) * pose.mixScaleY; else if (bone.scaleY !== 0) // bone.scaleY += (value - bone.scaleY) * pose.mixScaleY; } else if (additive) { const s = 1 + (value - 1) * pose.mixScaleY; bone.b *= s; bone.d *= s; } else { let b = bone.b / skeleton.scaleX, d = bone.d / skeleton.scaleY, s = Math.sqrt(b * b + d * d); if (s !== 0) { s = 1 + (value - s) * pose.mixScaleY / s; bone.b *= s; bone.d *= s; } } } } export class FromShearY extends FromProperty { value(skeleton, source, local, offsets) { if (local) return source.shearY + offsets[TransformConstraintData.SHEARY]; const ix = 1 / skeleton.scaleX, iy = 1 / skeleton.scaleY; return (Math.atan2(source.d * iy, source.b * ix) - Math.atan2(source.c * iy, source.a * ix)) * MathUtils.radDeg - 90 + offsets[TransformConstraintData.SHEARY]; } } export class ToShearY extends ToProperty { mix(pose) { return pose.mixShearY; } apply(skeleton, pose, bone, value, local, additive) { if (local) { if (!additive) value -= bone.shearY; bone.shearY += value * pose.mixShearY; } else { const sx = skeleton.scaleX, sy = skeleton.scaleY, b = bone.b / sx, d = bone.d / sy, by = Math.atan2(d, b); value = (value + 90) * MathUtils.degRad; if (additive) value -= MathUtils.PI / 2; else { value -= by - Math.atan2(bone.c / sy, bone.a / sx); if (value > MathUtils.PI) value -= MathUtils.PI2; else if (value < -MathUtils.PI) value += MathUtils.PI2; } value = by + value * pose.mixShearY; const s = Math.sqrt(b * b + d * d); bone.b = Math.cos(value) * s * sx; bone.d = Math.sin(value) * s * sy; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNmb3JtQ29uc3RyYWludERhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvVHJhbnNmb3JtQ29uc3RyYWludERhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSS9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVyRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXZDOzttSEFFbUg7QUFDbkgsTUFBTSxPQUFPLHVCQUF3QixTQUFRLGNBQTREO0lBQ2pHLE1BQU0sQ0FBVSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLE1BQU0sQ0FBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLE1BQU0sQ0FBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLE1BQU0sQ0FBVSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLE1BQU0sQ0FBVSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLE1BQU0sQ0FBVSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRWxDLG9FQUFvRTtJQUNwRSxLQUFLLEdBQUcsRUFBZ0IsQ0FBQztJQUV6Qiw4RUFBOEU7SUFDOUUsSUFBVyxNQUFNLENBQUUsTUFBZ0IsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDL0QsSUFBVyxNQUFNO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTs7WUFDbEQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFDTyxPQUFPLEdBQW9CLElBQUksQ0FBQztJQUV4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QUcsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7Z0JBQ25ELElBQUksS0FBSyxHQUFHLFNBQVMsQ0FBQyxFQUFFO29CQUN2QixLQUFLLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQztxQkFDbkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRTtvQkFDN0IsS0FBSyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUM7WUFDekIsQ0FBQztZQUNELEtBQUssR0FBRyxFQUFFLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDcEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNuQyxDQUFDO0lBQ0YsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgdHlwZSB7IEJvbmVEYXRhIH0gZnJvbSBcIi4vQm9uZURhdGEuanNcIjtcbmltcG9ydCB0eXBlIHsgQm9uZVBvc2UgfSBmcm9tIFwiLi9Cb25lUG9zZS5qc1wiO1xuaW1wb3J0IHsgQ29uc3RyYWludERhdGEgfSBmcm9tIFwiLi9Db25zdHJhaW50RGF0YS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5pbXBvcnQgeyBUcmFuc2Zvcm1Db25zdHJhaW50IH0gZnJvbSBcIi4vVHJhbnNmb3JtQ29uc3RyYWludC5qc1wiO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29uc3RyYWludFBvc2UgfSBmcm9tIFwiLi9UcmFuc2Zvcm1Db25zdHJhaW50UG9zZS5qc1wiO1xuaW1wb3J0IHsgTWF0aFV0aWxzIH0gZnJvbSBcIi4vVXRpbHMuanNcIjtcblxuLyoqIFN0b3JlcyB0aGUgc2V0dXAgcG9zZSBmb3IgYSB7QGxpbmsgVHJhbnNmb3JtQ29uc3RyYWludH0uXG4gKlxuICogU2VlIFtUcmFuc2Zvcm0gY29uc3RyYWludHNdKGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS10cmFuc2Zvcm0tY29uc3RyYWludHMpIGluIHRoZSBTcGluZSBVc2VyIEd1aWRlLiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zZm9ybUNvbnN0cmFpbnREYXRhIGV4dGVuZHMgQ29uc3RyYWludERhdGE8VHJhbnNmb3JtQ29uc3RyYWludCwgVHJhbnNmb3JtQ29uc3RyYWludFBvc2U+IHtcblx0cHVibGljIHN0YXRpYyByZWFkb25seSBST1RBVElPTiA9IDA7XG5cdHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgWCA9IDE7XG5cdHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgWSA9IDI7XG5cdHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgU0NBTEVYID0gMztcblx0cHVibGljIHN0YXRpYyByZWFkb25seSBTQ0FMRVkgPSA0O1xuXHRwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNIRUFSWSA9IDU7XG5cblx0LyoqIFRoZSBib25lcyB0aGF0IHdpbGwgYmUgbW9kaWZpZWQgYnkgdGhpcyB0cmFuc2Zvcm0gY29uc3RyYWludC4gKi9cblx0Ym9uZXMgPSBbXSBhcyBCb25lRGF0YVtdO1xuXG5cdC8qKiBUaGUgYm9uZSB3aG9zZSB3b3JsZCB0cmFuc2Zvcm0gd2lsbCBiZSBjb3BpZWQgdG8gdGhlIGNvbnN0cmFpbmVkIGJvbmVzLiAqL1xuXHRwdWJsaWMgc2V0IHNvdXJjZSAoc291cmNlOiBCb25lRGF0YSkgeyB0aGlzLl9zb3VyY2UgPSBzb3VyY2U7IH1cblx0cHVibGljIGdldCBzb3VyY2UgKCkge1xuXHRcdGlmICghdGhpcy5fc291cmNlKSB0aHJvdyBuZXcgRXJyb3IoXCJCb25lRGF0YSBub3Qgc2V0LlwiKVxuXHRcdGVsc2UgcmV0dXJuIHRoaXMuX3NvdXJjZTtcblx0fVxuXHRwcml2YXRlIF9zb3VyY2U6IEJvbmVEYXRhIHwgbnVsbCA9IG51bGw7XG5cblx0b2Zmc2V0cyA9IFswLCAwLCAwLCAwLCAwLCAwXTtcblxuXHQvKiogQW4gb2Zmc2V0IGFkZGVkIHRvIHRoZSBjb25zdHJhaW5lZCBib25lIFggdHJhbnNsYXRpb24uICovXG5cdG9mZnNldFggPSAwO1xuXG5cdC8qKiBBbiBvZmZzZXQgYWRkZWQgdG8gdGhlIGNvbnN0cmFpbmVkIGJvbmUgWSB0cmFuc2xhdGlvbi4gKi9cblx0b2Zmc2V0WSA9IDA7XG5cblx0LyoqIFJlYWRzIHRoZSBzb3VyY2UgYm9uZSdzIGxvY2FsIHRyYW5zZm9ybSBpbnN0ZWFkIG9mIGl0cyB3b3JsZCB0cmFuc2Zvcm0uICovXG5cdGxvY2FsU291cmNlID0gZmFsc2U7XG5cblx0LyoqIFNldHMgdGhlIGNvbnN0cmFpbmVkIGJvbmVzJyBsb2NhbCB0cmFuc2Zvcm1zIGluc3RlYWQgb2YgdGhlaXIgd29ybGQgdHJhbnNmb3Jtcy4gKi9cblx0bG9jYWxUYXJnZXQgPSBmYWxzZTtcblxuXHQvKiogQWRkcyB0aGUgc291cmNlIGJvbmUgdHJhbnNmb3JtIHRvIHRoZSBjb25zdHJhaW5lZCBib25lcyBpbnN0ZWFkIG9mIHNldHRpbmcgaXQgYWJzb2x1dGVseS4gKi9cblx0YWRkaXRpdmUgPSBmYWxzZTtcblxuXHQvKiogUHJldmVudHMgY29uc3RyYWluZWQgYm9uZXMgZnJvbSBleGNlZWRpbmcgdGhlIHJhbmdlZCBkZWZpbmVkIGJ5IHtAbGluayBUb1Byb3BlcnR5Lm9mZnNldH0gYW5kIHtAbGluayBUb1Byb3BlcnR5Lm1heH0uICovXG5cdGNsYW1wID0gZmFsc2U7XG5cblx0LyoqIFRoZSBtYXBwaW5nIG9mIHRyYW5zZm9ybSBwcm9wZXJ0aWVzIHRvIG90aGVyIHRyYW5zZm9ybSBwcm9wZXJ0aWVzLiAqL1xuXHRyZWFkb25seSBwcm9wZXJ0aWVzOiBBcnJheTxGcm9tUHJvcGVydHk+ID0gW107XG5cblx0Y29uc3RydWN0b3IgKG5hbWU6IHN0cmluZykge1xuXHRcdHN1cGVyKG5hbWUsIG5ldyBUcmFuc2Zvcm1Db25zdHJhaW50UG9zZSgpKTtcblx0fVxuXG5cdHB1YmxpYyBjcmVhdGUgKHNrZWxldG9uOiBTa2VsZXRvbikge1xuXHRcdHJldHVybiBuZXcgVHJhbnNmb3JtQ29uc3RyYWludCh0aGlzLCBza2VsZXRvbik7XG5cdH1cblxuXHQvKiogQW4gb2Zmc2V0IGFkZGVkIHRvIHRoZSBjb25zdHJhaW5lZCBib25lIHJvdGF0aW9uLiAqL1xuXHRnZXRPZmZzZXRSb3RhdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ST1RBVElPTl07XG5cdH1cblxuXHRzZXRPZmZzZXRSb3RhdGlvbiAob2Zmc2V0Um90YXRpb246IG51bWJlcikge1xuXHRcdHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ST1RBVElPTl0gPSBvZmZzZXRSb3RhdGlvbjtcblx0fVxuXG5cdC8qKiBBbiBvZmZzZXQgYWRkZWQgdG8gdGhlIGNvbnN0cmFpbmVkIGJvbmUgWCB0cmFuc2xhdGlvbi4gKi9cblx0Z2V0T2Zmc2V0WCAoKSB7XG5cdFx0cmV0dXJuIHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5YXTtcblx0fVxuXG5cdHNldE9mZnNldFggKG9mZnNldFg6IG51bWJlcikge1xuXHRcdHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5YXSA9IG9mZnNldFg7XG5cdH1cblxuXHQvKiogQW4gb2Zmc2V0IGFkZGVkIHRvIHRoZSBjb25zdHJhaW5lZCBib25lIFkgdHJhbnNsYXRpb24uICovXG5cdGdldE9mZnNldFkgKCkge1xuXHRcdHJldHVybiB0aGlzLm9mZnNldHNbVHJhbnNmb3JtQ29uc3RyYWludERhdGEuWV07XG5cdH1cblxuXHRzZXRPZmZzZXRZIChvZmZzZXRZOiBudW1iZXIpIHtcblx0XHR0aGlzLm9mZnNldHNbVHJhbnNmb3JtQ29uc3RyYWludERhdGEuWV0gPSBvZmZzZXRZO1xuXHR9XG5cblx0LyoqIEFuIG9mZnNldCBhZGRlZCB0byB0aGUgY29uc3RyYWluZWQgYm9uZSBzY2FsZVguICovXG5cdGdldE9mZnNldFNjYWxlWCAoKSB7XG5cdFx0cmV0dXJuIHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TQ0FMRVhdO1xuXHR9XG5cblx0c2V0T2Zmc2V0U2NhbGVYIChvZmZzZXRTY2FsZVg6IG51bWJlcikge1xuXHRcdHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TQ0FMRVhdID0gb2Zmc2V0U2NhbGVYO1xuXHR9XG5cblx0LyoqIEFuIG9mZnNldCBhZGRlZCB0byB0aGUgY29uc3RyYWluZWQgYm9uZSBzY2FsZVkuICovXG5cdGdldE9mZnNldFNjYWxlWSAoKSB7XG5cdFx0cmV0dXJuIHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TQ0FMRVldO1xuXHR9XG5cblx0c2V0T2Zmc2V0U2NhbGVZIChvZmZzZXRTY2FsZVk6IG51bWJlcikge1xuXHRcdHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TQ0FMRVldID0gb2Zmc2V0U2NhbGVZO1xuXHR9XG5cblx0LyoqIEFuIG9mZnNldCBhZGRlZCB0byB0aGUgY29uc3RyYWluZWQgYm9uZSBzaGVhclkuICovXG5cdGdldE9mZnNldFNoZWFyWSAoKSB7XG5cdFx0cmV0dXJuIHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TSEVBUlldO1xuXHR9XG5cblx0c2V0T2Zmc2V0U2hlYXJZIChvZmZzZXRTaGVhclk6IG51bWJlcikge1xuXHRcdHRoaXMub2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TSEVBUlldID0gb2Zmc2V0U2hlYXJZO1xuXHR9XG5cbn1cblxuLyoqIFNvdXJjZSBwcm9wZXJ0eSBmb3IgYSB7QGxpbmsgVHJhbnNmb3JtQ29uc3RyYWludH0uICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRnJvbVByb3BlcnR5IHtcblx0LyoqIFRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IHRoYXQgY29ycmVzcG9uZHMgdG8ge0BsaW5rIFRvUHJvcGVydHkub2Zmc2V0fS4gKi9cblx0b2Zmc2V0ID0gMDtcblxuXHQvKiogQ29uc3RyYWluZWQgcHJvcGVydGllcy4gKi9cblx0cmVhZG9ubHkgdG86IEFycmF5PFRvUHJvcGVydHk+ID0gW107XG5cblx0LyoqIFJlYWRzIHRoaXMgcHJvcGVydHkgZnJvbSB0aGUgc3BlY2lmaWVkIGJvbmUuICovXG5cdGFic3RyYWN0IHZhbHVlIChza2VsZXRvbjogU2tlbGV0b24sIHNvdXJjZTogQm9uZVBvc2UsIGxvY2FsOiBib29sZWFuLCBvZmZzZXRzOiBBcnJheTxudW1iZXI+KTogbnVtYmVyO1xufVxuXG4vKiogQ29uc3RyYWluZWQgcHJvcGVydHkgZm9yIGEge0BsaW5rIFRyYW5zZm9ybUNvbnN0cmFpbnR9LiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRvUHJvcGVydHkge1xuXHQvKiogVGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgdGhhdCBjb3JyZXNwb25kcyB0byB7QGxpbmsgRnJvbVByb3BlcnR5Lm9mZnNldH0uICovXG5cdG9mZnNldCA9IDA7XG5cblx0LyoqIFRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgd2hlbiB7QGxpbmsgVHJhbnNmb3JtQ29uc3RyYWludERhdGEuY2xhbXAgY2xhbXBlZH0uICovXG5cdG1heCA9IDA7XG5cblx0LyoqIFRoZSBzY2FsZSBvZiB0aGUge0BsaW5rIEZyb21Qcm9wZXJ0eX0gdmFsdWUgaW4gcmVsYXRpb24gdG8gdGhpcyBwcm9wZXJ0eS4gKi9cblx0c2NhbGUgPSAwO1xuXG5cdC8qKiBSZWFkcyB0aGUgbWl4IGZvciB0aGlzIHByb3BlcnR5IGZyb20gdGhlIHNwZWNpZmllZCBjb25zdHJhaW50LiAqL1xuXHRhYnN0cmFjdCBtaXggKHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlKTogbnVtYmVyO1xuXG5cdC8qKiBBcHBsaWVzIHRoZSB2YWx1ZSB0byB0aGlzIHByb3BlcnR5LiAqL1xuXHRhYnN0cmFjdCBhcHBseSAoc2tlbGV0b246IFNrZWxldG9uLCBwb3NlOiBUcmFuc2Zvcm1Db25zdHJhaW50UG9zZSwgYm9uZTogQm9uZVBvc2UsIHZhbHVlOiBudW1iZXIsIGxvY2FsOiBib29sZWFuLCBhZGRpdGl2ZTogYm9vbGVhbik6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBGcm9tUm90YXRlIGV4dGVuZHMgRnJvbVByb3BlcnR5IHtcblx0dmFsdWUgKHNrZWxldG9uOiBTa2VsZXRvbiwgc291cmNlOiBCb25lUG9zZSwgbG9jYWw6IGJvb2xlYW4sIG9mZnNldHM6IEFycmF5PG51bWJlcj4pOiBudW1iZXIge1xuXHRcdGlmIChsb2NhbCkgcmV0dXJuIHNvdXJjZS5yb3RhdGlvbiArIG9mZnNldHNbVHJhbnNmb3JtQ29uc3RyYWludERhdGEuUk9UQVRJT05dO1xuXHRcdGNvbnN0IHN4ID0gc2tlbGV0b24uc2NhbGVYLCBzeSA9IHNrZWxldG9uLnNjYWxlWTtcblx0XHRsZXQgdmFsdWUgPSBNYXRoLmF0YW4yKHNvdXJjZS5jIC8gc3ksIHNvdXJjZS5hIC8gc3gpICogTWF0aFV0aWxzLnJhZERlZ1xuXHRcdFx0KyAoKHNvdXJjZS5hICogc291cmNlLmQgLSBzb3VyY2UuYiAqIHNvdXJjZS5jKSAqIHN4ICogc3kgPiAwID8gb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ST1RBVElPTl0gOiAtb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ST1RBVElPTl0pO1xuXHRcdGlmICh2YWx1ZSA8IDApIHZhbHVlICs9IDM2MDtcblx0XHRyZXR1cm4gdmFsdWU7XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFRvUm90YXRlIGV4dGVuZHMgVG9Qcm9wZXJ0eSB7XG5cdG1peCAocG9zZTogVHJhbnNmb3JtQ29uc3RyYWludFBvc2UpOiBudW1iZXIge1xuXHRcdHJldHVybiBwb3NlLm1peFJvdGF0ZTtcblx0fVxuXG5cdGFwcGx5IChza2VsZXRvbjogU2tlbGV0b24sIHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlLCBib25lOiBCb25lUG9zZSwgdmFsdWU6IG51bWJlciwgbG9jYWw6IGJvb2xlYW4sIGFkZGl0aXZlOiBib29sZWFuKTogdm9pZCB7XG5cdFx0aWYgKGxvY2FsKVxuXHRcdFx0Ym9uZS5yb3RhdGlvbiArPSAoYWRkaXRpdmUgPyB2YWx1ZSA6IHZhbHVlIC0gYm9uZS5yb3RhdGlvbikgKiBwb3NlLm1peFJvdGF0ZTtcblx0XHRlbHNlIHtcblx0XHRcdGNvbnN0IHN4ID0gc2tlbGV0b24uc2NhbGVYLCBzeSA9IHNrZWxldG9uLnNjYWxlWSwgaXggPSAxIC8gc3gsIGl5ID0gMSAvIHN5O1xuXHRcdFx0Y29uc3QgYSA9IGJvbmUuYSAqIGl4LCBiID0gYm9uZS5iICogaXgsIGMgPSBib25lLmMgKiBpeSwgZCA9IGJvbmUuZCAqIGl5O1xuXHRcdFx0dmFsdWUgKj0gTWF0aFV0aWxzLmRlZ1JhZDtcblx0XHRcdGlmICghYWRkaXRpdmUpIHZhbHVlIC09IE1hdGguYXRhbjIoYywgYSk7XG5cdFx0XHRpZiAodmFsdWUgPiBNYXRoVXRpbHMuUEkpXG5cdFx0XHRcdHZhbHVlIC09IE1hdGhVdGlscy5QSTI7XG5cdFx0XHRlbHNlIGlmICh2YWx1ZSA8IC1NYXRoVXRpbHMuUEkpIC8vXG5cdFx0XHRcdHZhbHVlICs9IE1hdGhVdGlscy5QSTI7XG5cdFx0XHR2YWx1ZSAqPSBwb3NlLm1peFJvdGF0ZTtcblx0XHRcdGNvbnN0IGNvcyA9IE1hdGguY29zKHZhbHVlKSwgc2luID0gTWF0aC5zaW4odmFsdWUpO1xuXHRcdFx0Ym9uZS5hID0gKGNvcyAqIGEgLSBzaW4gKiBjKSAqIHN4O1xuXHRcdFx0Ym9uZS5iID0gKGNvcyAqIGIgLSBzaW4gKiBkKSAqIHN4O1xuXHRcdFx0Ym9uZS5jID0gKHNpbiAqIGEgKyBjb3MgKiBjKSAqIHN5O1xuXHRcdFx0Ym9uZS5kID0gKHNpbiAqIGIgKyBjb3MgKiBkKSAqIHN5O1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgRnJvbVggZXh0ZW5kcyBGcm9tUHJvcGVydHkge1xuXHR2YWx1ZSAoc2tlbGV0b246IFNrZWxldG9uLCBzb3VyY2U6IEJvbmVQb3NlLCBsb2NhbDogYm9vbGVhbiwgb2Zmc2V0czogQXJyYXk8bnVtYmVyPik6IG51bWJlciB7XG5cdFx0cmV0dXJuIGxvY2FsXG5cdFx0XHQ/IHNvdXJjZS54ICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5YXVxuXHRcdFx0OiAob2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5YXSAqIHNvdXJjZS5hICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ZXSAqIHNvdXJjZS5iICsgc291cmNlLndvcmxkWCkgLyBza2VsZXRvbi5zY2FsZVg7XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFRvWCBleHRlbmRzIFRvUHJvcGVydHkge1xuXHRtaXggKHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gcG9zZS5taXhYO1xuXHR9XG5cblx0YXBwbHkgKHNrZWxldG9uOiBTa2VsZXRvbiwgcG9zZTogVHJhbnNmb3JtQ29uc3RyYWludFBvc2UsIGJvbmU6IEJvbmVQb3NlLCB2YWx1ZTogbnVtYmVyLCBsb2NhbDogYm9vbGVhbiwgYWRkaXRpdmU6IGJvb2xlYW4pOiB2b2lkIHtcblx0XHRpZiAobG9jYWwpXG5cdFx0XHRib25lLnggKz0gKGFkZGl0aXZlID8gdmFsdWUgOiB2YWx1ZSAtIGJvbmUueCkgKiBwb3NlLm1peFg7XG5cdFx0ZWxzZSB7XG5cdFx0XHRpZiAoIWFkZGl0aXZlKSB2YWx1ZSAtPSBib25lLndvcmxkWCAvIHNrZWxldG9uLnNjYWxlWDtcblx0XHRcdGJvbmUud29ybGRYICs9IHZhbHVlICogcG9zZS5taXhYICogc2tlbGV0b24uc2NhbGVYO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgRnJvbVkgZXh0ZW5kcyBGcm9tUHJvcGVydHkge1xuXHR2YWx1ZSAoc2tlbGV0b246IFNrZWxldG9uLCBzb3VyY2U6IEJvbmVQb3NlLCBsb2NhbDogYm9vbGVhbiwgb2Zmc2V0czogQXJyYXk8bnVtYmVyPik6IG51bWJlciB7XG5cdFx0cmV0dXJuIGxvY2FsXG5cdFx0XHQ/IHNvdXJjZS55ICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ZXVxuXHRcdFx0OiAob2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5YXSAqIHNvdXJjZS5jICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5ZXSAqIHNvdXJjZS5kICsgc291cmNlLndvcmxkWSkgLyBza2VsZXRvbi5zY2FsZVk7XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFRvWSBleHRlbmRzIFRvUHJvcGVydHkge1xuXHRtaXggKHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gcG9zZS5taXhZO1xuXHR9XG5cblx0YXBwbHkgKHNrZWxldG9uOiBTa2VsZXRvbiwgcG9zZTogVHJhbnNmb3JtQ29uc3RyYWludFBvc2UsIGJvbmU6IEJvbmVQb3NlLCB2YWx1ZTogbnVtYmVyLCBsb2NhbDogYm9vbGVhbiwgYWRkaXRpdmU6IGJvb2xlYW4pOiB2b2lkIHtcblx0XHRpZiAobG9jYWwpXG5cdFx0XHRib25lLnkgKz0gKGFkZGl0aXZlID8gdmFsdWUgOiB2YWx1ZSAtIGJvbmUueSkgKiBwb3NlLm1peFk7XG5cdFx0ZWxzZSB7XG5cdFx0XHRpZiAoIWFkZGl0aXZlKSB2YWx1ZSAtPSBib25lLndvcmxkWSAvIHNrZWxldG9uLnNjYWxlWTtcblx0XHRcdGJvbmUud29ybGRZICs9IHZhbHVlICogcG9zZS5taXhZICogc2tlbGV0b24uc2NhbGVZO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgRnJvbVNjYWxlWCBleHRlbmRzIEZyb21Qcm9wZXJ0eSB7XG5cdHZhbHVlIChza2VsZXRvbjogU2tlbGV0b24sIHNvdXJjZTogQm9uZVBvc2UsIGxvY2FsOiBib29sZWFuLCBvZmZzZXRzOiBBcnJheTxudW1iZXI+KTogbnVtYmVyIHtcblx0XHRpZiAobG9jYWwpIHJldHVybiBzb3VyY2Uuc2NhbGVYICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TQ0FMRVhdO1xuXHRcdGNvbnN0IGEgPSBzb3VyY2UuYSAvIHNrZWxldG9uLnNjYWxlWCwgYyA9IHNvdXJjZS5jIC8gc2tlbGV0b24uc2NhbGVZO1xuXHRcdHJldHVybiBNYXRoLnNxcnQoYSAqIGEgKyBjICogYykgKyBvZmZzZXRzW1RyYW5zZm9ybUNvbnN0cmFpbnREYXRhLlNDQUxFWF07XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFRvU2NhbGVYIGV4dGVuZHMgVG9Qcm9wZXJ0eSB7XG5cdG1peCAocG9zZTogVHJhbnNmb3JtQ29uc3RyYWludFBvc2UpOiBudW1iZXIge1xuXHRcdHJldHVybiBwb3NlLm1peFNjYWxlWDtcblx0fVxuXG5cdGFwcGx5IChza2VsZXRvbjogU2tlbGV0b24sIHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlLCBib25lOiBCb25lUG9zZSwgdmFsdWU6IG51bWJlciwgbG9jYWw6IGJvb2xlYW4sIGFkZGl0aXZlOiBib29sZWFuKTogdm9pZCB7XG5cdFx0aWYgKGxvY2FsKSB7XG5cdFx0XHRpZiAoYWRkaXRpdmUpXG5cdFx0XHRcdGJvbmUuc2NhbGVYICo9IDEgKyAodmFsdWUgLSAxKSAqIHBvc2UubWl4U2NhbGVYO1xuXHRcdFx0ZWxzZSBpZiAoYm9uZS5zY2FsZVggIT09IDApIC8vXG5cdFx0XHRcdGJvbmUuc2NhbGVYICs9ICh2YWx1ZSAtIGJvbmUuc2NhbGVYKSAqIHBvc2UubWl4U2NhbGVYO1xuXHRcdH0gZWxzZSBpZiAoYWRkaXRpdmUpIHtcblx0XHRcdGNvbnN0IHMgPSAxICsgKHZhbHVlIC0gMSkgKiBwb3NlLm1peFNjYWxlWDtcblx0XHRcdGJvbmUuYSAqPSBzO1xuXHRcdFx0Ym9uZS5jICo9IHM7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBhID0gYm9uZS5hIC8gc2tlbGV0b24uc2NhbGVYLCBjID0gYm9uZS5jIC8gc2tlbGV0b24uc2NhbGVZLCBzID0gTWF0aC5zcXJ0KGEgKiBhICsgYyAqIGMpO1xuXHRcdFx0aWYgKHMgIT09IDApIHtcblx0XHRcdFx0cyA9IDEgKyAodmFsdWUgLSBzKSAqIHBvc2UubWl4U2NhbGVYIC8gcztcblx0XHRcdFx0Ym9uZS5hICo9IHM7XG5cdFx0XHRcdGJvbmUuYyAqPSBzO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgRnJvbVNjYWxlWSBleHRlbmRzIEZyb21Qcm9wZXJ0eSB7XG5cdHZhbHVlIChza2VsZXRvbjogU2tlbGV0b24sIHNvdXJjZTogQm9uZVBvc2UsIGxvY2FsOiBib29sZWFuLCBvZmZzZXRzOiBBcnJheTxudW1iZXI+KTogbnVtYmVyIHtcblx0XHRpZiAobG9jYWwpIHJldHVybiBzb3VyY2Uuc2NhbGVZICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TQ0FMRVldO1xuXHRcdGNvbnN0IGIgPSBzb3VyY2UuYiAvIHNrZWxldG9uLnNjYWxlWCwgZCA9IHNvdXJjZS5kIC8gc2tlbGV0b24uc2NhbGVZO1xuXHRcdHJldHVybiBNYXRoLnNxcnQoYiAqIGIgKyBkICogZCkgKyBvZmZzZXRzW1RyYW5zZm9ybUNvbnN0cmFpbnREYXRhLlNDQUxFWV07XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFRvU2NhbGVZIGV4dGVuZHMgVG9Qcm9wZXJ0eSB7XG5cdG1peCAocG9zZTogVHJhbnNmb3JtQ29uc3RyYWludFBvc2UpOiBudW1iZXIge1xuXHRcdHJldHVybiBwb3NlLm1peFNjYWxlWTtcblx0fVxuXG5cdGFwcGx5IChza2VsZXRvbjogU2tlbGV0b24sIHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlLCBib25lOiBCb25lUG9zZSwgdmFsdWU6IG51bWJlciwgbG9jYWw6IGJvb2xlYW4sIGFkZGl0aXZlOiBib29sZWFuKTogdm9pZCB7XG5cdFx0aWYgKGxvY2FsKSB7XG5cdFx0XHRpZiAoYWRkaXRpdmUpXG5cdFx0XHRcdGJvbmUuc2NhbGVZICo9IDEgKyAodmFsdWUgLSAxKSAqIHBvc2UubWl4U2NhbGVZO1xuXHRcdFx0ZWxzZSBpZiAoYm9uZS5zY2FsZVkgIT09IDApIC8vXG5cdFx0XHRcdGJvbmUuc2NhbGVZICs9ICh2YWx1ZSAtIGJvbmUuc2NhbGVZKSAqIHBvc2UubWl4U2NhbGVZO1xuXHRcdH0gZWxzZSBpZiAoYWRkaXRpdmUpIHtcblx0XHRcdGNvbnN0IHMgPSAxICsgKHZhbHVlIC0gMSkgKiBwb3NlLm1peFNjYWxlWTtcblx0XHRcdGJvbmUuYiAqPSBzO1xuXHRcdFx0Ym9uZS5kICo9IHM7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBiID0gYm9uZS5iIC8gc2tlbGV0b24uc2NhbGVYLCBkID0gYm9uZS5kIC8gc2tlbGV0b24uc2NhbGVZLCBzID0gTWF0aC5zcXJ0KGIgKiBiICsgZCAqIGQpO1xuXHRcdFx0aWYgKHMgIT09IDApIHtcblx0XHRcdFx0cyA9IDEgKyAodmFsdWUgLSBzKSAqIHBvc2UubWl4U2NhbGVZIC8gcztcblx0XHRcdFx0Ym9uZS5iICo9IHM7XG5cdFx0XHRcdGJvbmUuZCAqPSBzO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgRnJvbVNoZWFyWSBleHRlbmRzIEZyb21Qcm9wZXJ0eSB7XG5cdHZhbHVlIChza2VsZXRvbjogU2tlbGV0b24sIHNvdXJjZTogQm9uZVBvc2UsIGxvY2FsOiBib29sZWFuLCBvZmZzZXRzOiBBcnJheTxudW1iZXI+KTogbnVtYmVyIHtcblx0XHRpZiAobG9jYWwpIHJldHVybiBzb3VyY2Uuc2hlYXJZICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TSEVBUlldO1xuXHRcdGNvbnN0IGl4ID0gMSAvIHNrZWxldG9uLnNjYWxlWCwgaXkgPSAxIC8gc2tlbGV0b24uc2NhbGVZO1xuXHRcdHJldHVybiAoTWF0aC5hdGFuMihzb3VyY2UuZCAqIGl5LCBzb3VyY2UuYiAqIGl4KSAtIE1hdGguYXRhbjIoc291cmNlLmMgKiBpeSwgc291cmNlLmEgKiBpeCkpICogTWF0aFV0aWxzLnJhZERlZyAtIDkwICsgb2Zmc2V0c1tUcmFuc2Zvcm1Db25zdHJhaW50RGF0YS5TSEVBUlldO1xuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBUb1NoZWFyWSBleHRlbmRzIFRvUHJvcGVydHkge1xuXHRtaXggKHBvc2U6IFRyYW5zZm9ybUNvbnN0cmFpbnRQb3NlKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gcG9zZS5taXhTaGVhclk7XG5cdH1cblxuXHRhcHBseSAoc2tlbGV0b246IFNrZWxldG9uLCBwb3NlOiBUcmFuc2Zvcm1Db25zdHJhaW50UG9zZSwgYm9uZTogQm9uZVBvc2UsIHZhbHVlOiBudW1iZXIsIGxvY2FsOiBib29sZWFuLCBhZGRpdGl2ZTogYm9vbGVhbik6IHZvaWQge1xuXHRcdGlmIChsb2NhbCkge1xuXHRcdFx0aWYgKCFhZGRpdGl2ZSkgdmFsdWUgLT0gYm9uZS5zaGVhclk7XG5cdFx0XHRib25lLnNoZWFyWSArPSB2YWx1ZSAqIHBvc2UubWl4U2hlYXJZO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBzeCA9IHNrZWxldG9uLnNjYWxlWCwgc3kgPSBza2VsZXRvbi5zY2FsZVksIGIgPSBib25lLmIgLyBzeCwgZCA9IGJvbmUuZCAvIHN5LCBieSA9IE1hdGguYXRhbjIoZCwgYik7XG5cdFx0XHR2YWx1ZSA9ICh2YWx1ZSArIDkwKSAqIE1hdGhVdGlscy5kZWdSYWQ7XG5cdFx0XHRpZiAoYWRkaXRpdmUpXG5cdFx0XHRcdHZhbHVlIC09IE1hdGhVdGlscy5QSSAvIDI7XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0dmFsdWUgLT0gYnkgLSBNYXRoLmF0YW4yKGJvbmUuYyAvIHN5LCBib25lLmEgLyBzeCk7XG5cdFx0XHRcdGlmICh2YWx1ZSA+IE1hdGhVdGlscy5QSSlcblx0XHRcdFx0XHR2YWx1ZSAtPSBNYXRoVXRpbHMuUEkyO1xuXHRcdFx0XHRlbHNlIGlmICh2YWx1ZSA8IC1NYXRoVXRpbHMuUEkpXG5cdFx0XHRcdFx0dmFsdWUgKz0gTWF0aFV0aWxzLlBJMjtcblx0XHRcdH1cblx0XHRcdHZhbHVlID0gYnkgKyB2YWx1ZSAqIHBvc2UubWl4U2hlYXJZO1xuXHRcdFx0Y29uc3QgcyA9IE1hdGguc3FydChiICogYiArIGQgKiBkKTtcblx0XHRcdGJvbmUuYiA9IE1hdGguY29zKHZhbHVlKSAqIHMgKiBzeDtcblx0XHRcdGJvbmUuZCA9IE1hdGguc2luKHZhbHVlKSAqIHMgKiBzeTtcblx0XHR9XG5cdH1cbn1cbiJdfQ==