@esotericsoftware/spine-core
Version:
The official Spine Runtimes for the web.
323 lines • 48.1 kB
JavaScript
/******************************************************************************
* 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 { Inherit } from "./BoneData.js";
import { MathUtils } from "./Utils.js";
/** Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of
* the last bone is as close to the target bone as possible.
*
* See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */
export class IkConstraint {
/** The IK constraint's setup pose data. */
data;
/** The bones that will be modified by this IK constraint. */
bones;
/** The bone that is the IK target. */
target;
/** Controls the bend direction of the IK bones, either 1 or -1. */
bendDirection = 0;
/** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */
compress = false;
/** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained
* and the parent bone has local nonuniform scale, stretch is not applied. */
stretch = false;
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
mix = 1;
/** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */
softness = 0;
active = false;
constructor(data, skeleton) {
if (!data)
throw new Error("data cannot be null.");
if (!skeleton)
throw new Error("skeleton cannot be null.");
this.data = data;
this.bones = new Array();
for (let i = 0; i < data.bones.length; i++) {
let bone = skeleton.findBone(data.bones[i].name);
if (!bone)
throw new Error(`Couldn't find bone ${data.bones[i].name}`);
this.bones.push(bone);
}
let target = skeleton.findBone(data.target.name);
if (!target)
throw new Error(`Couldn't find bone ${data.target.name}`);
this.target = target;
this.mix = data.mix;
this.softness = data.softness;
this.bendDirection = data.bendDirection;
this.compress = data.compress;
this.stretch = data.stretch;
}
isActive() {
return this.active;
}
setToSetupPose() {
const data = this.data;
this.mix = data.mix;
this.softness = data.softness;
this.bendDirection = data.bendDirection;
this.compress = data.compress;
this.stretch = data.stretch;
}
update(physics) {
if (this.mix == 0)
return;
let target = this.target;
let bones = this.bones;
switch (bones.length) {
case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix);
break;
case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.data.uniform, this.softness, this.mix);
break;
}
}
/** Applies 1 bone IK. The target is specified in the world coordinate system. */
apply1(bone, targetX, targetY, compress, stretch, uniform, alpha) {
let p = bone.parent;
if (!p)
throw new Error("IK bone must have parent.");
let pa = p.a, pb = p.b, pc = p.c, pd = p.d;
let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0;
switch (bone.inherit) {
case Inherit.OnlyTranslation:
tx = (targetX - bone.worldX) * MathUtils.signum(bone.skeleton.scaleX);
ty = (targetY - bone.worldY) * MathUtils.signum(bone.skeleton.scaleY);
break;
case Inherit.NoRotationOrReflection:
let s = Math.abs(pa * pd - pb * pc) / Math.max(0.0001, pa * pa + pc * pc);
let sa = pa / bone.skeleton.scaleX;
let sc = pc / bone.skeleton.scaleY;
pb = -sc * s * bone.skeleton.scaleX;
pd = sa * s * bone.skeleton.scaleY;
rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg;
// Fall through
default:
let x = targetX - p.worldX, y = targetY - p.worldY;
let d = pa * pd - pb * pc;
if (Math.abs(d) <= 0.0001) {
tx = 0;
ty = 0;
}
else {
tx = (x * pd - y * pb) / d - bone.ax;
ty = (y * pa - x * pc) / d - bone.ay;
}
}
rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg;
if (bone.ascaleX < 0)
rotationIK += 180;
if (rotationIK > 180)
rotationIK -= 360;
else if (rotationIK < -180)
rotationIK += 360;
let sx = bone.ascaleX, sy = bone.ascaleY;
if (compress || stretch) {
switch (bone.inherit) {
case Inherit.NoScale:
case Inherit.NoScaleOrReflection:
tx = targetX - bone.worldX;
ty = targetY - bone.worldY;
}
const b = bone.data.length * sx;
if (b > 0.0001) {
const dd = tx * tx + ty * ty;
if ((compress && dd < b * b) || (stretch && dd > b * b)) {
const s = (Math.sqrt(dd) / b - 1) * alpha + 1;
sx *= s;
if (uniform)
sy *= s;
}
}
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY);
}
/** Applies 2 bone IK. The target is specified in the world coordinate system.
* @param child A direct descendant of the parent bone. */
apply2(parent, child, targetX, targetY, bendDir, stretch, uniform, softness, alpha) {
if (parent.inherit != Inherit.Normal || child.inherit != Inherit.Normal)
return;
let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX;
let os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) {
psx = -psx;
os1 = 180;
s2 = -1;
}
else {
os1 = 0;
s2 = 1;
}
if (psy < 0) {
psy = -psy;
s2 = -s2;
}
if (csx < 0) {
csx = -csx;
os2 = 180;
}
else
os2 = 0;
let cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d;
let u = Math.abs(psx - psy) <= 0.0001;
if (!u || stretch) {
cy = 0;
cwx = a * cx + parent.worldX;
cwy = c * cx + parent.worldY;
}
else {
cy = child.ay;
cwx = a * cx + b * cy + parent.worldX;
cwy = c * cx + d * cy + parent.worldY;
}
let pp = parent.parent;
if (!pp)
throw new Error("IK parent must itself have a parent.");
a = pp.a;
b = pp.b;
c = pp.c;
d = pp.d;
let id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY;
id = Math.abs(id) <= 0.0001 ? 0 : 1 / id;
let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2;
if (l1 < 0.0001) {
this.apply1(parent, targetX, targetY, false, stretch, false, alpha);
child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
return;
}
x = targetX - pp.worldX;
y = targetY - pp.worldY;
let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
let dd = tx * tx + ty * ty;
if (softness != 0) {
softness *= psx * (csx + 1) * 0.5;
let td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness;
if (sd > 0) {
let p = Math.min(1, sd / (softness * 2)) - 1;
p = (sd - softness * (1 - p * p)) / td;
tx -= p * tx;
ty -= p * ty;
dd = tx * tx + ty * ty;
}
}
outer: if (u) {
l2 *= psx;
let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) {
cos = -1;
a2 = Math.PI * bendDir;
}
else if (cos > 1) {
cos = 1;
a2 = 0;
if (stretch) {
a = (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
sx *= a;
if (uniform)
sy *= a;
}
}
else
a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos;
b = l2 * Math.sin(a2);
a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
}
else {
a = psx * l2;
b = psy * l2;
let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb;
let c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c;
if (d >= 0) {
let q = Math.sqrt(d);
if (c1 < 0)
q = -q;
q = -(c1 + q) * 0.5;
let r0 = q / c2, r1 = c / q;
let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
r0 = dd - r * r;
if (r0 >= 0) {
y = Math.sqrt(r0) * bendDir;
a1 = ta - Math.atan2(y, r);
a2 = Math.atan2(y / psy, (r - l1) / psx);
break outer;
}
}
let minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
c = -a * l1 / (aa - bb);
if (c >= -1 && c <= 1) {
c = Math.acos(c);
x = a * Math.cos(c) + l1;
y = b * Math.sin(c);
d = x * x + y * y;
if (d < minDist) {
minAngle = c;
minDist = d;
minX = x;
minY = y;
}
if (d > maxDist) {
maxAngle = c;
maxDist = d;
maxX = x;
maxY = y;
}
}
if (dd <= (minDist + maxDist) * 0.5) {
a1 = ta - Math.atan2(minY * bendDir, minX);
a2 = minAngle * bendDir;
}
else {
a1 = ta - Math.atan2(maxY * bendDir, maxX);
a2 = maxAngle * bendDir;
}
}
let os = Math.atan2(cy, cx) * s2;
let rotation = parent.arotation;
a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation;
if (a1 > 180)
a1 -= 360;
else if (a1 < -180) //
a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, sy, 0, 0);
rotation = child.arotation;
a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180)
a2 -= 360;
else if (a2 < -180) //
a2 += 360;
child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0lrQ29uc3RyYWludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUl4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXZDOzs7cUdBR3FHO0FBQ3JHLE1BQU0sT0FBTyxZQUFZO0lBQ3hCLDJDQUEyQztJQUMzQyxJQUFJLENBQW1CO0lBRXZCLDZEQUE2RDtJQUM3RCxLQUFLLENBQWM7SUFFbkIsc0NBQXNDO0lBQ3RDLE1BQU0sQ0FBTztJQUViLG1FQUFtRTtJQUNuRSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0lBRWxCLHlIQUF5SDtJQUN6SCxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRWpCO2lGQUM2RTtJQUM3RSxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBRWhCLG9HQUFvRztJQUNwRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRVIsaUdBQWlHO0lBQ2pHLFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDYixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRWYsWUFBYSxJQUFzQixFQUFFLFFBQWtCO1FBQ3RELElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBRWpCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQVEsQ0FBQztRQUMvQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVB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QUNSLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDUixDQUFDO1FBQ0QsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDYixHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDWCxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDVixDQUFDO1FBQ0QsSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDYixHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDWCxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ1gsQ0FBQzs7WUFDQSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1QsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNwRyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUM7UUFDdEMsSUFBSSxDQUFDLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNuQixFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ1AsR0FBRyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUM3QixHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQzlCLENBQUM7YUFBTSxDQUFDO1lBQ1AsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDZCxHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7WUFDdEMsR0FBRyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQ3ZDLENBQUM7UUFDRCxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxFQUFFO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ1QsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDVCxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNULENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ1QsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUM7UUFDakUsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDekMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDbkUsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDNUUsSUFBSSxFQUFFLEdBQUcs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LFFBQVEsR0FBRyxFQUFFLEdBQUcsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzSCxDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IEJvbmUgfSBmcm9tIFwiLi9Cb25lLmpzXCI7XG5pbXBvcnQgeyBJbmhlcml0IH0gZnJvbSBcIi4vQm9uZURhdGEuanNcIjtcbmltcG9ydCB7IElrQ29uc3RyYWludERhdGEgfSBmcm9tIFwiLi9Ja0NvbnN0cmFpbnREYXRhLmpzXCI7XG5pbXBvcnQgeyBQaHlzaWNzLCBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5pbXBvcnQgeyBVcGRhdGFibGUgfSBmcm9tIFwiLi9VcGRhdGFibGUuanNcIjtcbmltcG9ydCB7IE1hdGhVdGlscyB9IGZyb20gXCIuL1V0aWxzLmpzXCI7XG5cbi8qKiBTdG9yZXMgdGhlIGN1cnJlbnQgcG9zZSBmb3IgYW4gSUsgY29uc3RyYWludC4gQW4gSUsgY29uc3RyYWludCBhZGp1c3RzIHRoZSByb3RhdGlvbiBvZiAxIG9yIDIgY29uc3RyYWluZWQgYm9uZXMgc28gdGhlIHRpcCBvZlxuICogdGhlIGxhc3QgYm9uZSBpcyBhcyBjbG9zZSB0byB0aGUgdGFyZ2V0IGJvbmUgYXMgcG9zc2libGUuXG4gKlxuICogU2VlIFtJSyBjb25zdHJhaW50c10oaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWlrLWNvbnN0cmFpbnRzKSBpbiB0aGUgU3BpbmUgVXNlciBHdWlkZS4gKi9cbmV4cG9ydCBjbGFzcyBJa0NvbnN0cmFpbnQgaW1wbGVtZW50cyBVcGRhdGFibGUge1xuXHQvKiogVGhlIElLIGNvbnN0cmFpbnQncyBzZXR1cCBwb3NlIGRhdGEuICovXG5cdGRhdGE6IElrQ29uc3RyYWludERhdGE7XG5cblx0LyoqIFRoZSBib25lcyB0aGF0IHdpbGwgYmUgbW9kaWZpZWQgYnkgdGhpcyBJSyBjb25zdHJhaW50LiAqL1xuXHRib25lczogQXJyYXk8Qm9uZT47XG5cblx0LyoqIFRoZSBib25lIHRoYXQgaXMgdGhlIElLIHRhcmdldC4gKi9cblx0dGFyZ2V0OiBCb25lO1xuXG5cdC8qKiBDb250cm9scyB0aGUgYmVuZCBkaXJlY3Rpb24gb2YgdGhlIElLIGJvbmVzLCBlaXRoZXIgMSBvciAtMS4gKi9cblx0YmVuZERpcmVjdGlvbiA9IDA7XG5cblx0LyoqIFdoZW4gdHJ1ZSBhbmQgb25seSBhIHNpbmdsZSBib25lIGlzIGJlaW5nIGNvbnN0cmFpbmVkLCBpZiB0aGUgdGFyZ2V0IGlzIHRvbyBjbG9zZSwgdGhlIGJvbmUgaXMgc2NhbGVkIHRvIHJlYWNoIGl0LiAqL1xuXHRjb21wcmVzcyA9IGZhbHNlO1xuXG5cdC8qKiBXaGVuIHRydWUsIGlmIHRoZSB0YXJnZXQgaXMgb3V0IG9mIHJhbmdlLCB0aGUgcGFyZW50IGJvbmUgaXMgc2NhbGVkIHRvIHJlYWNoIGl0LiBJZiBtb3JlIHRoYW4gb25lIGJvbmUgaXMgYmVpbmcgY29uc3RyYWluZWRcblx0ICogYW5kIHRoZSBwYXJlbnQgYm9uZSBoYXMgbG9jYWwgbm9udW5pZm9ybSBzY2FsZSwgc3RyZXRjaCBpcyBub3QgYXBwbGllZC4gKi9cblx0c3RyZXRjaCA9IGZhbHNlO1xuXG5cdC8qKiBBIHBlcmNlbnRhZ2UgKDAtMSkgdGhhdCBjb250cm9scyB0aGUgbWl4IGJldHdlZW4gdGhlIGNvbnN0cmFpbmVkIGFuZCB1bmNvbnN0cmFpbmVkIHJvdGF0aW9ucy4gKi9cblx0bWl4ID0gMTtcblxuXHQvKiogRm9yIHR3byBib25lIElLLCB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgbWF4aW11bSByZWFjaCBvZiB0aGUgYm9uZXMgdGhhdCByb3RhdGlvbiB3aWxsIHNsb3cuICovXG5cdHNvZnRuZXNzID0gMDtcblx0YWN0aXZlID0gZmFsc2U7XG5cblx0Y29uc3RydWN0b3IgKGRhdGE6IElrQ29uc3RyYWludERhdGEsIHNrZWxldG9uOiBTa2VsZXRvbikge1xuXHRcdGlmICghZGF0YSkgdGhyb3cgbmV3IEVycm9yKFwiZGF0YSBjYW5ub3QgYmUgbnVsbC5cIik7XG5cdFx0aWYgKCFza2VsZXRvbikgdGhyb3cgbmV3IEVycm9yKFwic2tlbGV0b24gY2Fubm90IGJlIG51bGwuXCIpO1xuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cblx0XHR0aGlzLmJvbmVzID0gbmV3IEFycmF5PEJvbmU+KCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmJvbmVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRsZXQgYm9uZSA9IHNrZWxldG9uLmZpbmRCb25lKGRhdGEuYm9uZXNbaV0ubmFtZSk7XG5cdFx0XHRpZiAoIWJvbmUpIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZmluZCBib25lICR7ZGF0YS5ib25lc1tpXS5uYW1lfWApO1xuXHRcdFx0dGhpcy5ib25lcy5wdXNoKGJvbmUpO1xuXHRcdH1cblx0XHRsZXQgdGFyZ2V0ID0gc2tlbGV0b24uZmluZEJvbmUoZGF0YS50YXJnZXQubmFtZSk7XG5cdFx0aWYgKCF0YXJnZXQpIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZmluZCBib25lICR7ZGF0YS50YXJnZXQubmFtZX1gKTtcblxuXHRcdHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuXHRcdHRoaXMubWl4ID0gZGF0YS5taXg7XG5cdFx0dGhpcy5zb2Z0bmVzcyA9IGRhdGEuc29mdG5lc3M7XG5cdFx0dGhpcy5iZW5kRGlyZWN0aW9uID0gZGF0YS5iZW5kRGlyZWN0aW9uO1xuXHRcdHRoaXMuY29tcHJlc3MgPSBkYXRhLmNvbXByZXNzO1xuXHRcdHRoaXMuc3RyZXRjaCA9IGRhdGEuc3RyZXRjaDtcblx0fVxuXG5cdGlzQWN0aXZlICgpIHtcblx0XHRyZXR1cm4gdGhpcy5hY3RpdmU7XG5cdH1cblxuXHRzZXRUb1NldHVwUG9zZSAoKSB7XG5cdFx0Y29uc3QgZGF0YSA9IHRoaXMuZGF0YTtcblx0XHR0aGlzLm1peCA9IGRhdGEubWl4O1xuXHRcdHRoaXMuc29mdG5lc3MgPSBkYXRhLnNvZnRuZXNzO1xuXHRcdHRoaXMuYmVuZERpcmVjdGlvbiA9IGRhdGEuYmVuZERpcmVjdGlvbjtcblx0XHR0aGlzLmNvbXByZXNzID0gZGF0YS5jb21wcmVzcztcblx0XHR0aGlzLnN0cmV0Y2ggPSBkYXRhLnN0cmV0Y2g7XG5cdH1cblxuXHR1cGRhdGUgKHBoeXNpY3M6IFBoeXNpY3MpIHtcblx0XHRpZiAodGhpcy5taXggPT0gMCkgcmV0dXJuO1xuXHRcdGxldCB0YXJnZXQgPSB0aGlzLnRhcmdldDtcblx0XHRsZXQgYm9uZXMgPSB0aGlzLmJvbmVzO1xuXHRcdHN3aXRjaCAoYm9uZXMubGVuZ3RoKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRoaXMuYXBwbHkxKGJvbmVzWzBdLCB0YXJnZXQud29ybGRYLCB0YXJnZXQud29ybGRZLCB0aGlzLmNvbXByZXNzLCB0aGlzLnN0cmV0Y2gsIHRoaXMuZGF0YS51bmlmb3JtLCB0aGlzLm1peCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0aGlzLmFwcGx5Mihib25lc1swXSwgYm9uZXNbMV0sIHRhcmdldC53b3JsZFgsIHRhcmdldC53b3JsZFksIHRoaXMuYmVuZERpcmVjdGlvbiwgdGhpcy5zdHJldGNoLCB0aGlzLmRhdGEudW5pZm9ybSwgdGhpcy5zb2Z0bmVzcywgdGhpcy5taXgpO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHQvKiogQXBwbGllcyAxIGJvbmUgSUsuIFRoZSB0YXJnZXQgaXMgc3BlY2lmaWVkIGluIHRoZSB3b3JsZCBjb29yZGluYXRlIHN5c3RlbS4gKi9cblx0YXBwbHkxIChib25lOiBCb25lLCB0YXJnZXRYOiBudW1iZXIsIHRhcmdldFk6IG51bWJlciwgY29tcHJlc3M6IGJvb2xlYW4sIHN0cmV0Y2g6IGJvb2xlYW4sIHVuaWZvcm06IGJvb2xlYW4sIGFscGhhOiBudW1iZXIpIHtcblx0XHRsZXQgcCA9IGJvbmUucGFyZW50O1xuXHRcdGlmICghcCkgdGhyb3cgbmV3IEVycm9yKFwiSUsgYm9uZSBtdXN0IGhhdmUgcGFyZW50LlwiKTtcblx0XHRsZXQgcGEgPSBwLmEsIHBiID0gcC5iLCBwYyA9IHAuYywgcGQgPSBwLmQ7XG5cdFx0bGV0IHJvdGF0aW9uSUsgPSAtYm9uZS5hc2hlYXJYIC0gYm9uZS5hcm90YXRpb24sIHR4ID0gMCwgdHkgPSAwO1xuXG5cdFx0c3dpdGNoIChib25lLmluaGVyaXQpIHtcblx0XHRcdGNhc2UgSW5oZXJpdC5Pbmx5VHJhbnNsYXRpb246XG5cdFx0XHRcdHR4ID0gKHRhcmdldFggLSBib25lLndvcmxkWCkgKiBNYXRoVXRpbHMuc2lnbnVtKGJvbmUuc2tlbGV0b24uc2NhbGVYKTtcblx0XHRcdFx0dHkgPSAodGFyZ2V0WSAtIGJvbmUud29ybGRZKSAqIE1hdGhVdGlscy5zaWdudW0oYm9uZS5za2VsZXRvbi5zY2FsZVkpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgSW5oZXJpdC5Ob1JvdGF0aW9uT3JSZWZsZWN0aW9uOlxuXHRcdFx0XHRsZXQgcyA9IE1hdGguYWJzKHBhICogcGQgLSBwYiAqIHBjKSAvIE1hdGgubWF4KDAuMDAwMSwgcGEgKiBwYSArIHBjICogcGMpO1xuXHRcdFx0XHRsZXQgc2EgPSBwYSAvIGJvbmUuc2tlbGV0b24uc2NhbGVYO1xuXHRcdFx0XHRsZXQgc2MgPSBwYyAvIGJvbmUuc2tlbGV0b24uc2NhbGVZO1xuXHRcdFx0XHRwYiA9IC1zYyAqIHMgKiBib25lLnNrZWxldG9uLnNjYWxlWDtcblx0XHRcdFx0cGQgPSBzYSAqIHMgKiBib25lLnNrZWxldG9uLnNjYWxlWTtcblx0XHRcdFx0cm90YXRpb25JSyArPSBNYXRoLmF0YW4yKHNjLCBzYSkgKiBNYXRoVXRpbHMucmFkRGVnO1xuXHRcdFx0Ly8gRmFsbCB0aHJvdWdoXG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRsZXQgeCA9IHRhcmdldFggLSBwLndvcmxkWCwgeSA9IHRhcmdldFkgLSBwLndvcmxkWTtcblx0XHRcdFx0bGV0IGQgPSBwYSAqIHBkIC0gcGIgKiBwYztcblx0XHRcdFx0aWYgKE1hdGguYWJzKGQpIDw9IDAuMDAwMSkge1xuXHRcdFx0XHRcdHR4ID0gMDtcblx0XHRcdFx0XHR0eSA9IDA7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dHggPSAoeCAqIHBkIC0geSAqIHBiKSAvIGQgLSBib25lLmF4O1xuXHRcdFx0XHRcdHR5ID0gKHkgKiBwYSAtIHggKiBwYykgLyBkIC0gYm9uZS5heTtcblx0XHRcdFx0fVxuXHRcdH1cblx0XHRyb3RhdGlvbklLICs9IE1hdGguYXRhbjIodHksIHR4KSAqIE1hdGhVdGlscy5yYWREZWc7XG5cdFx0aWYgKGJvbmUuYXNjYWxlWCA8IDApIHJvdGF0aW9uSUsgKz0gMTgwO1xuXHRcdGlmIChyb3RhdGlvbklLID4gMTgwKVxuXHRcdFx0cm90YXRpb25JSyAtPSAzNjA7XG5cdFx0ZWxzZSBpZiAocm90YXRpb25JSyA8IC0xODApXG5cdFx0XHRyb3RhdGlvbklLICs9IDM2MDtcblx0XHRsZXQgc3ggPSBib25lLmFzY2FsZVgsIHN5ID0gYm9uZS5hc2NhbGVZO1xuXHRcdGlmIChjb21wcmVzcyB8fCBzdHJldGNoKSB7XG5cdFx0XHRzd2l0Y2ggKGJvbmUuaW5oZXJpdCkge1xuXHRcdFx0XHRjYXNlIEluaGVyaXQuTm9TY2FsZTpcblx0XHRcdFx0Y2FzZSBJbmhlcml0Lk5vU2NhbGVPclJlZmxlY3Rpb246XG5cdFx0XHRcdFx0dHggPSB0YXJnZXRYIC0gYm9uZS53b3JsZFg7XG5cdFx0XHRcdFx0dHkgPSB0YXJnZXRZIC0gYm9uZS53b3JsZFk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBiID0gYm9uZS5kYXRhLmxlbmd0aCAqIHN4O1xuXHRcdFx0aWYgKGIgPiAwLjAwMDEpIHtcblx0XHRcdFx0Y29uc3QgZGQgPSB0eCAqIHR4ICsgdHkgKiB0eTtcblx0XHRcdFx0aWYgKChjb21wcmVzcyAmJiBkZCA8IGIgKiBiKSB8fCAoc3RyZXRjaCAmJiBkZCA+IGIgKiBiKSkge1xuXHRcdFx0XHRcdGNvbnN0IHMgPSAoTWF0aC5zcXJ0KGRkKSAvIGIgLSAxKSAqIGFscGhhICsgMTtcblx0XHRcdFx0XHRzeCAqPSBzO1xuXHRcdFx0XHRcdGlmICh1bmlmb3JtKSBzeSAqPSBzO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGJvbmUudXBkYXRlV29ybGRUcmFuc2Zvcm1XaXRoKGJvbmUuYXgsIGJvbmUuYXksIGJvbmUuYXJvdGF0aW9uICsgcm90YXRpb25JSyAqIGFscGhhLCBzeCwgc3ksIGJvbmUuYXNoZWFyWCxcblx0XHRcdGJvbmUuYXNoZWFyWSk7XG5cdH1cblxuXHQvKiogQXBwbGllcyAyIGJvbmUgSUsuIFRoZSB0YXJnZXQgaXMgc3BlY2lmaWVkIGluIHRoZSB3b3JsZCBjb29yZGluYXRlIHN5c3RlbS5cblx0ICogQHBhcmFtIGNoaWxkIEEgZGlyZWN0IGRlc2NlbmRhbnQgb2YgdGhlIHBhcmVudCBib25lLiAqL1xuXHRhcHBseTIgKHBhcmVudDogQm9uZSwgY2hpbGQ6IEJvbmUsIHRhcmdldFg6IG51bWJlciwgdGFyZ2V0WTogbnVtYmVyLCBiZW5kRGlyOiBudW1iZXIsIHN0cmV0Y2g6IGJvb2xlYW4sIHVuaWZvcm06IGJvb2xlYW4sIHNvZnRuZXNzOiBudW1iZXIsIGFscGhhOiBudW1iZXIpIHtcblx0XHRpZiAocGFyZW50LmluaGVyaXQgIT0gSW5oZXJpdC5Ob3JtYWwgfHwgY2hpbGQuaW5oZXJpdCAhPSBJbmhlcml0Lk5vcm1hbCkgcmV0dXJuO1xuXHRcdGxldCBweCA9IHBhcmVudC5heCwgcHkgPSBwYXJlbnQuYXksIHBzeCA9IHBhcmVudC5hc2NhbGVYLCBwc3kgPSBwYXJlbnQuYXNjYWxlWSwgc3ggPSBwc3gsIHN5ID0gcHN5LCBjc3ggPSBjaGlsZC5hc2NhbGVYO1xuXHRcdGxldCBvczEgPSAwLCBvczIgPSAwLCBzMiA9IDA7XG5cdFx0aWYgKHBzeCA8IDApIHtcblx0XHRcdHBzeCA9IC1wc3g7XG5cdFx0XHRvczEgPSAxODA7XG5cdFx0XHRzMiA9IC0xO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvczEgPSAwO1xuXHRcdFx0czIgPSAxO1xuXHRcdH1cblx0XHRpZiAocHN5IDwgMCkge1xuXHRcdFx0cHN5ID0gLXBzeTtcblx0XHRcdHMyID0gLXMyO1xuXHRcdH1cblx0XHRpZiAoY3N4IDwgMCkge1xuXHRcdFx0Y3N4ID0gLWNzeDtcblx0XHRcdG9zMiA9IDE4MDtcblx0XHR9IGVsc2Vcblx0XHRcdG9zMiA9IDA7XG5cdFx0bGV0IGN4ID0gY2hpbGQuYXgsIGN5ID0gMCwgY3d4ID0gMCwgY3d5ID0gMCwgYSA9IHBhcmVudC5hLCBiID0gcGFyZW50LmIsIGMgPSBwYXJlbnQuYywgZCA9IHBhcmVudC5kO1xuXHRcdGxldCB1ID0gTWF0aC5hYnMocHN4IC0gcHN5KSA8PSAwLjAwMDE7XG5cdFx0aWYgKCF1IHx8IHN0cmV0Y2gpIHtcblx0XHRcdGN5ID0gMDtcblx0XHRcdGN3eCA9IGEgKiBjeCArIHBhcmVudC53b3JsZFg7XG5cdFx0XHRjd3kgPSBjICogY3ggKyBwYXJlbnQud29ybGRZO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjeSA9IGNoaWxkLmF5O1xuXHRcdFx0Y3d4ID0gYSAqIGN4ICsgYiAqIGN5ICsgcGFyZW50LndvcmxkWDtcblx0XHRcdGN3eSA9IGMgKiBjeCArIGQgKiBjeSArIHBhcmVudC53b3JsZFk7XG5cdFx0fVxuXHRcdGxldCBwcCA9IHBhcmVudC5wYXJlbnQ7XG5cdFx0aWYgKCFwcCkgdGhyb3cgbmV3IEVycm9yKFwiSUsgcGFyZW50IG11c3QgaXRzZWxmIGhhdmUgYSBwYXJlbnQuXCIpO1xuXHRcdGEgPSBwcC5hO1xuXHRcdGIgPSBwcC5iO1xuXHRcdGMgPSBwcC5jO1xuXHRcdGQgPSBwcC5kO1xuXHRcdGxldCBpZCA9IGEgKiBkIC0gYiAqIGMsIHggPSBjd3ggLSBwcC53b3JsZFgsIHkgPSBjd3kgLSBwcC53b3JsZFk7XG5cdFx0aWQgPSBNYXRoLmFicyhpZCkgPD0gMC4wMDAxID8gMCA6IDEgLyBpZDtcblx0XHRsZXQgZHggPSAoeCAqIGQgLSB5ICogYikgKiBpZCAtIHB4LCBkeSA9ICh5ICogYSAtIHggKiBjKSAqIGlkIC0gcHk7XG5cdFx0bGV0IGwxID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KSwgbDIgPSBjaGlsZC5kYXRhLmxlbmd0aCAqIGNzeCwgYTEsIGEyO1xuXHRcdGlmIChsMSA8IDAuMDAwMSkge1xuXHRcdFx0dGhpcy5hcHBseTEocGFyZW50LCB0YXJnZXRYLCB0YXJnZXRZLCBmYWxzZSwgc3RyZXRjaCwgZmFsc2UsIGFscGhhKTtcblx0XHRcdGNoaWxkLnVwZGF0ZVdvcmxkVHJhbnNmb3JtV2l0aChjeCwgY3ksIDAsIGNoaWxkLmFzY2FsZVgsIGNoaWxkLmFzY2FsZVksIGNoaWxkLmFzaGVhclgsIGNoaWxkLmFzaGVhclkpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR4ID0gdGFyZ2V0WCAtIHBwLndvcmxkWDtcblx0XHR5ID0gdGFyZ2V0WSAtIHBwLndvcmxkWTtcblx0XHRsZXQgdHggPSAoeCAqIGQgLSB5ICogYikgKiBpZCAtIHB4LCB0eSA9ICh5ICogYSAtIHggKiBjKSAqIGlkIC0gcHk7XG5cdFx0bGV0IGRkID0gdHggKiB0eCArIHR5ICogdHk7XG5cdFx0aWYgKHNvZnRuZXNzICE9IDApIHtcblx0XHRcdHNvZnRuZXNzICo9IHBzeCAqIChjc3ggKyAxKSAqIDAuNTtcblx0XHRcdGxldCB0ZCA9IE1hdGguc3FydChkZCksIHNkID0gdGQgLSBsMSAtIGwyICogcHN4ICsgc29mdG5lc3M7XG5cdFx0XHRpZiAoc2QgPiAwKSB7XG5cdFx0XHRcdGxldCBwID0gTWF0aC5taW4oMSwgc2QgLyAoc29mdG5lc3MgKiAyKSkgLSAxO1xuXHRcdFx0XHRwID0gKHNkIC0gc29mdG5lc3MgKiAoMSAtIHAgKiBwKSkgLyB0ZDtcblx0XHRcdFx0dHggLT0gcCAqIHR4O1xuXHRcdFx0XHR0eSAtPSBwICogdHk7XG5cdFx0XHRcdGRkID0gdHggKiB0eCArIHR5ICogdHk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdG91dGVyOlxuXHRcdGlmICh1KSB7XG5cdFx0XHRsMiAqPSBwc3g7XG5cdFx0XHRsZXQgY29zID0gKGRkIC0gbDEgKiBsMSAtIGwyICogbDIpIC8gKDIgKiBsMSAqIGwyKTtcblx0XHRcdGlmIChjb3MgPCAtMSkge1xuXHRcdFx0XHRjb3MgPSAtMTtcblx0XHRcdFx0YTIgPSBNYXRoLlBJICogYmVuZERpcjtcblx0XHRcdH0gZWxzZSBpZiAoY29zID4gMSkge1xuXHRcdFx0XHRjb3MgPSAxO1xuXHRcdFx0XHRhMiA9IDA7XG5cdFx0XHRcdGlmIChzdHJldGNoKSB7XG5cdFx0XHRcdFx0YSA9IChNYXRoLnNxcnQoZGQpIC8gKGwxICsgbDIpIC0gMSkgKiBhbHBoYSArIDE7XG5cdFx0XHRcdFx0c3ggKj0gYTtcblx0XHRcdFx0XHRpZiAodW5pZm9ybSkgc3kgKj0gYTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlXG5cdFx0XHRcdGEyID0gTWF0aC5hY29zKGNvcykgKiBiZW5kRGlyO1xuXHRcdFx0YSA9IGwxICsgbDIgKiBjb3M7XG5cdFx0XHRiID0gbDIgKiBNYXRoLnNpbihhMik7XG5cdFx0XHRhMSA9IE1hdGguYXRhbjIodHkgKiBhIC0gdHggKiBiLCB0eCAqIGEgKyB0eSAqIGIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhID0gcHN4ICogbDI7XG5cdFx0XHRiID0gcHN5ICogbDI7XG5cdFx0XHRsZXQgYWEgPSBhICogYSwgYmIgPSBiICogYiwgdGEgPSBNYXRoLmF0YW4yKHR5LCB0eCk7XG5cdFx0XHRjID0gYmIgKiBsMSAqIGwxICsgYWEgKiBkZCAtIGFhICogYmI7XG5cdFx0XHRsZXQgYzEgPSAtMiAqIGJiICogbDEsIGMyID0gYmIgLSBhYTtcblx0XHRcdGQgPSBjMSAqIGMxIC0gNCAqIGMyICogYztcblx0XHRcdGlmIChkID49IDApIHtcblx0XHRcdFx0bGV0IHEgPSBNYXRoLnNxcnQoZCk7XG5cdFx0XHRcdGlmIChjMSA8IDApIHEgPSAtcTtcblx0XHRcdFx0cSA9IC0oYzEgKyBxKSAqIDAuNTtcblx0XHRcdFx0bGV0IHIwID0gcSAvIGMyLCByMSA9IGMgLyBxO1xuXHRcdFx0XHRsZXQgciA9IE1hdGguYWJzKHIwKSA8IE1hdGguYWJzKHIxKSA/IHIwIDogcjE7XG5cdFx0XHRcdHIwID0gZGQgLSByICogcjtcblx0XHRcdFx0aWYgKHIwID49IDApIHtcblx0XHRcdFx0XHR5ID0gTWF0aC5zcXJ0KHIwKSAqIGJlbmREaXI7XG5cdFx0XHRcdFx0YTEgPSB0YSAtIE1hdGguYXRhbjIoeSwgcik7XG5cdFx0XHRcdFx0YTIgPSBNYXRoLmF0YW4yKHkgLyBwc3ksIChyIC0gbDEpIC8gcHN4KTtcblx0XHRcdFx0XHRicmVhayBvdXRlcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0bGV0IG1pbkFuZ2xlID0gTWF0aFV0aWxzLlBJLCBtaW5YID0gbDEgLSBhLCBtaW5EaXN0ID0gbWluWCAqIG1pblgsIG1pblkgPSAwO1xuXHRcdFx0bGV0IG1heEFuZ2xlID0gMCwgbWF4WCA9IGwxICsgYSwgbWF4RGlzdCA9IG1heFggKiBtYXhYLCBtYXhZID0gMDtcblx0XHRcdGMgPSAtYSAqIGwxIC8gKGFhIC0gYmIpO1xuXHRcdFx0aWYgKGMgPj0gLTEgJiYgYyA8PSAxKSB7XG5cdFx0XHRcdGMgPSBNYXRoLmFjb3MoYyk7XG5cdFx0XHRcdHggPSBhICogTWF0aC5jb3MoYykgKyBsMTtcblx0XHRcdFx0eSA9IGIgKiBNYXRoLnNpbihjKTtcblx0XHRcdFx0ZCA9IHggKiB4ICsgeSAqIHk7XG5cdFx0XHRcdGlmIChkIDwgbWluRGlzdCkge1xuXHRcdFx0XHRcdG1pbkFuZ2xlID0gYztcblx0XHRcdFx0XHRtaW5EaXN0ID0gZDtcblx0XHRcdFx0XHRtaW5YID0geDtcblx0XHRcdFx0XHRtaW5ZID0geTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoZCA+IG1heERpc3QpIHtcblx0XHRcdFx0XHRtYXhBbmdsZSA9IGM7XG5cdFx0XHRcdFx0bWF4RGlzdCA9IGQ7XG5cdFx0XHRcdFx0bWF4WCA9IHg7XG5cdFx0XHRcdFx0bWF4WSA9IHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmIChkZCA8PSAobWluRGlzdCArIG1heERpc3QpICogMC41KSB7XG5cdFx0XHRcdGExID0gdGEgLSBNYXRoLmF0YW4yKG1pblkgKiBiZW5kRGlyLCBtaW5YKTtcblx0XHRcdFx0YTIgPSBtaW5BbmdsZSAqIGJlbmREaXI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRhMSA9IHRhIC0gTWF0aC5hdGFuMihtYXhZICogYmVuZERpciwgbWF4WCk7XG5cdFx0XHRcdGEyID0gbWF4QW5nbGUgKiBiZW5kRGlyO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRsZXQgb3MgPSBNYXRoLmF0YW4yKGN5LCBjeCkgKiBzMjtcblx0XHRsZXQgcm90YXRpb24gPSBwYXJlbnQuYXJvdGF0aW9uO1xuXHRcdGExID0gKGExIC0gb3MpICogTWF0aFV0aWxzLnJhZERlZyArIG9zMSAtIHJvdGF0aW9uO1xuXHRcdGlmIChhMSA+IDE4MClcblx0XHRcdGExIC09IDM2MDtcblx0XHRlbHNlIGlmIChhMSA8IC0xODApIC8vXG5cdFx0XHRhMSArPSAzNjA7XG5cdFx0cGFyZW50LnVwZGF0ZVdvcmxkVHJhbnNmb3JtV2l0aChweCwgcHksIHJvdGF0aW9uICsgYTEgKiBhbHBoYSwgc3gsIHN5LCAwLCAwKTtcblx0XHRyb3RhdGlvbiA9IGNoaWxkLmFyb3RhdGlvbjtcblx0XHRhMiA9ICgoYTIgKyBvcykgKiBNYXRoVXRpbHMucmFkRGVnIC0gY2hpbGQuYXNoZWFyWCkgKiBzMiArIG9zMiAtIHJvdGF0aW9uO1xuXHRcdGlmIChhMiA+IDE4MClcblx0XHRcdGEyIC09IDM2MDtcblx0XHRlbHNlIGlmIChhMiA8IC0xODApIC8vXG5cdFx0XHRhMiArPSAzNjA7XG5cdFx0Y2hpbGQudXBkYXRlV29ybGRUcmFuc2Zvcm1XaXRoKGN4LCBjeSwgcm90YXRpb24gKyBhMiAqIGFscGhhLCBjaGlsZC5hc2NhbGVYLCBjaGlsZC5hc2NhbGVZLCBjaGlsZC5hc2hlYXJYLCBjaGlsZC5hc2hlYXJZKTtcblx0fVxufVxuIl19