Эх сурвалжийг харах

Merge branch '3.7-beta' into 3.7-beta-cpp

badlogic 7 жил өмнө
parent
commit
f5cc2933be
42 өөрчлөгдсөн 8824 нэмэгдсэн , 8686 устгасан
  1. 1 1
      spine-c/spine-c/include/spine/Animation.h
  2. 2 1
      spine-c/spine-c/include/spine/IkConstraint.h
  3. 4 0
      spine-c/spine-c/include/spine/IkConstraintData.h
  4. 12 3
      spine-c/spine-c/src/spine/Animation.c
  5. 1 1
      spine-c/spine-c/src/spine/AnimationState.c
  6. 12 6
      spine-c/spine-c/src/spine/IkConstraint.c
  7. 2 0
      spine-c/spine-c/src/spine/IkConstraintData.c
  8. 1 0
      spine-c/spine-c/src/spine/Skeleton.c
  9. 4 1
      spine-c/spine-c/src/spine/SkeletonBinary.c
  10. 3 1
      spine-c/spine-c/src/spine/SkeletonJson.c
  11. 6 1
      spine-cpp/spine-cpp/include/spine/IkConstraint.h
  12. 8 0
      spine-cpp/spine-cpp/include/spine/IkConstraintData.h
  13. 3 3
      spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h
  14. 1 1
      spine-cpp/spine-cpp/src/spine/AnimationState.cpp
  15. 19 5
      spine-cpp/spine-cpp/src/spine/IkConstraint.cpp
  16. 19 0
      spine-cpp/spine-cpp/src/spine/IkConstraintData.cpp
  17. 18 7
      spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp
  18. 1 0
      spine-cpp/spine-cpp/src/spine/Skeleton.cpp
  19. 4 1
      spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp
  20. 4 2
      spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp
  21. 26 8
      spine-csharp/src/Animation.cs
  22. 23 11
      spine-csharp/src/IkConstraint.cs
  23. 23 2
      spine-csharp/src/IkConstraintData.cs
  24. 2 1
      spine-csharp/src/Skeleton.cs
  25. 6 3
      spine-csharp/src/SkeletonBinary.cs
  26. 11 7
      spine-csharp/src/SkeletonJson.cs
  27. 21 6
      spine-lua/Animation.lua
  28. 1 1
      spine-lua/AnimationState.lua
  29. 12 5
      spine-lua/IkConstraint.lua
  30. 2 0
      spine-lua/IkConstraintData.lua
  31. 2 1
      spine-lua/Skeleton.lua
  32. 9 5
      spine-lua/SkeletonJson.lua
  33. 1560 1555
      spine-ts/build/spine-webgl.d.ts
  34. 6961 7031
      spine-ts/build/spine-webgl.js
  35. 0 0
      spine-ts/build/spine-webgl.js.map
  36. 14 5
      spine-ts/core/src/Animation.ts
  37. 1 1
      spine-ts/core/src/AnimationState.ts
  38. 12 6
      spine-ts/core/src/IkConstraint.ts
  39. 2 0
      spine-ts/core/src/IkConstraintData.ts
  40. 2 1
      spine-ts/core/src/Skeleton.ts
  41. 4 2
      spine-ts/core/src/SkeletonJson.ts
  42. 5 1
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs

+ 1 - 1
spine-c/spine-c/include/spine/Animation.h

@@ -452,7 +452,7 @@ typedef struct spIkConstraintTimeline {
 
 SP_API spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount);
 
-SP_API void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /**boolean**/ stretch);
+SP_API void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /*boolean*/ compress, int /**boolean**/ stretch);
 
 #ifdef SPINE_SHORT_NAMES
 typedef spIkConstraintTimeline IkConstraintTimeline;

+ 2 - 1
spine-c/spine-c/include/spine/IkConstraint.h

@@ -49,6 +49,7 @@ typedef struct spIkConstraint {
 
 	spBone* target;
 	int bendDirection;
+	int /*boolean*/ compress;
 	int /*boolean*/ stretch;
 	float mix;
 
@@ -70,7 +71,7 @@ SP_API void spIkConstraint_dispose (spIkConstraint* self);
 
 SP_API void spIkConstraint_apply (spIkConstraint* self);
 
-SP_API void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ stretch, float alpha);
+SP_API void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch, int /*boolean*/ uniform, float alpha);
 SP_API void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDirection, int /*boolean*/ stretch, float alpha);
 
 #ifdef SPINE_SHORT_NAMES

+ 4 - 0
spine-c/spine-c/include/spine/IkConstraintData.h

@@ -46,7 +46,9 @@ typedef struct spIkConstraintData {
 
 	spBoneData* target;
 	int bendDirection;
+	int /*boolean*/ compress;
 	int /*boolean*/ stretch;
+	int /*boolean*/ uniform;
 	float mix;
 
 #ifdef __cplusplus
@@ -56,7 +58,9 @@ typedef struct spIkConstraintData {
 		bones(0),
 		target(0),
 		bendDirection(0),
+		compress(0),
 		stretch(0),
+		uniform(0),
 		mix(0) {
 	}
 #endif

+ 12 - 3
spine-c/spine-c/src/spine/Animation.c

@@ -1282,8 +1282,8 @@ void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIndex, fl
 
 /**/
 
-static const int IKCONSTRAINT_PREV_TIME = -4, IKCONSTRAINT_PREV_MIX = -3, IKCONSTRAINT_PREV_BEND_DIRECTION = -2, IKCONSTRAINT_PREV_STRETCH = -1;
-static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2, IKCONSTRAINT_STRETCH = 3;
+static const int IKCONSTRAINT_PREV_TIME = -5, IKCONSTRAINT_PREV_MIX = -4, IKCONSTRAINT_PREV_BEND_DIRECTION = -3, IKCONSTRAINT_PREV_COMPRESS = -2, IKCONSTRAINT_PREV_STRETCH = -1;
+static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2, IKCONSTRAINT_COMPRESS = 3, IKCONSTRAINT_STRETCH = 4;
 
 void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
 		spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
@@ -1301,11 +1301,13 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
 			case SP_MIX_BLEND_SETUP:
 				constraint->mix = constraint->data->mix;
 				constraint->bendDirection = constraint->data->bendDirection;
+				constraint->compress = constraint->data->compress;
 				constraint->stretch = constraint->data->stretch;
 				return;
 			case SP_MIX_BLEND_FIRST:
 				constraint->mix += (constraint->data->mix - constraint->mix) * alpha;
 				constraint->bendDirection = constraint->data->bendDirection;
+				constraint->compress = constraint->data->compress;
 				constraint->stretch = constraint->data->stretch;
 			case SP_MIX_BLEND_REPLACE:
 			case SP_MIX_BLEND_ADD:
@@ -1321,15 +1323,18 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
 			constraint->mix = constraint->data->mix + (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->data->mix) * alpha;
 			if (direction == SP_MIX_DIRECTION_OUT) {
 				constraint->bendDirection = constraint->data->bendDirection;
+				constraint->compress = constraint->data->compress;
 				constraint->stretch = constraint->data->stretch;
 			} else {
 				constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
+				constraint->compress = frames[framesCount + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
 				constraint->stretch = frames[framesCount + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
 			}
 		} else {
 			constraint->mix += (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->mix) * alpha;
 			if (direction == SP_MIX_DIRECTION_IN) {
 				constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
+				constraint->compress = frames[framesCount + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
 				constraint->stretch = frames[framesCount + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
 			}
 		}
@@ -1346,15 +1351,18 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
 		constraint->mix = constraint->data->mix + (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->data->mix) * alpha;
 		if (direction == SP_MIX_DIRECTION_OUT) {
 			constraint->bendDirection = constraint->data->bendDirection;
+			constraint->compress = constraint->data->compress;
 			constraint->stretch = constraint->data->stretch;
 		} else {
 			constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
+			constraint->compress = frames[frame + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
 			constraint->stretch = frames[frame + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
 		}
 	} else {
 		constraint->mix += (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->mix) * alpha;
 		if (direction == SP_MIX_DIRECTION_IN) {
 			constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
+			constraint->compress = frames[frame + IKCONSTRAINT_PREV_COMPRESS] ? 1 : 0;
 			constraint->stretch = frames[frame + IKCONSTRAINT_PREV_STRETCH] ? 1 : 0;
 		}
 	}
@@ -1372,11 +1380,12 @@ spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount) {
 	return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply, _spIkConstraintTimeline_getPropertyId);
 }
 
-void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /*boolean*/ stretch) {
+void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, int bendDirection, int /*boolean*/ compress, int /*boolean*/ stretch) {
 	frameIndex *= IKCONSTRAINT_ENTRIES;
 	self->frames[frameIndex] = time;
 	self->frames[frameIndex + IKCONSTRAINT_MIX] = mix;
 	self->frames[frameIndex + IKCONSTRAINT_BEND_DIRECTION] = (float)bendDirection;
+	self->frames[frameIndex + IKCONSTRAINT_COMPRESS] = compress ? 1 : 0;
 	self->frames[frameIndex + IKCONSTRAINT_STRETCH] = stretch ? 1 : 0;
 }
 

+ 1 - 1
spine-c/spine-c/src/spine/AnimationState.c

@@ -554,11 +554,11 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
 	/* Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. */
 	r1 = blend == SP_MIX_BLEND_SETUP ? bone->data->rotation : bone->rotation;
 	diff = r2 - r1;
+	diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360;
 	if (diff == 0) {
 		total = timelinesRotation[i];
 	} else {
 		float lastTotal, lastDiff;
-		diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360;
 		if (firstFrame) {
 			lastTotal = 0;
 			lastDiff = diff;

+ 12 - 6
spine-c/spine-c/src/spine/IkConstraint.c

@@ -39,6 +39,7 @@ spIkConstraint *spIkConstraint_create(spIkConstraintData *data, const spSkeleton
 	spIkConstraint *self = NEW(spIkConstraint);
 	CONST_CAST(spIkConstraintData*, self->data) = data;
 	self->bendDirection = data->bendDirection;
+	self->compress = data->compress;
 	self->stretch = data->stretch;
 	self->mix = data->mix;
 
@@ -59,7 +60,7 @@ void spIkConstraint_dispose(spIkConstraint *self) {
 void spIkConstraint_apply(spIkConstraint *self) {
 	switch (self->bonesCount) {
 		case 1:
-			spIkConstraint_apply1(self->bones[0], self->target->worldX, self->target->worldY, self->stretch, self->mix);
+			spIkConstraint_apply1(self->bones[0], self->target->worldX, self->target->worldY, self->compress, self->stretch, self->data->uniform, self->mix);
 			break;
 		case 2:
 			spIkConstraint_apply2(self->bones[0], self->bones[1], self->target->worldX, self->target->worldY, self->bendDirection, self->stretch, self->mix);
@@ -67,9 +68,9 @@ void spIkConstraint_apply(spIkConstraint *self) {
 	}
 }
 
-void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ stretch, float alpha) {
+void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*boolean*/ compress, int /*boolean*/ stretch, int /*boolean*/ uniform, float alpha) {
 	spBone* p = bone->parent;
-	float id, x, y, tx, ty, rotationIK, sx;
+	float id, x, y, tx, ty, rotationIK, sx, sy, s;
 	if (!bone->appliedValid) spBone_updateAppliedTransform(bone);
 	id = 1 / (p->a * p->d - p->b * p->c);
 	x = targetX - p->worldX, y = targetY - p->worldY;
@@ -79,12 +80,17 @@ void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, int /*bo
 	if (rotationIK > 180) rotationIK -= 360;
 	else if (rotationIK < -180) rotationIK += 360;
 	sx = bone->ascaleX;
-	if (stretch) {
+	sy = bone->ascaleY;
+	if (compress || stretch) {
 		float b = bone->data->length * sx, dd = SQRT(tx * tx + ty * ty);
-		if (dd > b && b > 0.0001f) sx *= (dd / b - 1) * alpha - 1;
+		if ((compress && dd < b) || (stretch && dd > b) && (b > 0.0001f)) {
+			s = (dd / b - 1) * alpha + 1;
+			sx *= s;
+			if (uniform) sy *= s;
+		}
 	}
 	spBone_updateWorldTransformWith(bone, bone->ax, bone->ay, bone->arotation + rotationIK * alpha, sx,
-		bone->ascaleY, bone->ashearX, bone->ashearY);
+		sy, bone->ashearX, bone->ashearY);
 }
 
 void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, int /*boolean*/ stretch, float alpha) {

+ 2 - 0
spine-c/spine-c/src/spine/IkConstraintData.c

@@ -35,7 +35,9 @@ spIkConstraintData* spIkConstraintData_create (const char* name) {
 	spIkConstraintData* self = NEW(spIkConstraintData);
 	MALLOC_STR(self->name, name);
 	self->bendDirection = 1;
+	self->compress = 0;
 	self->stretch = 0;
+	self->uniform = 0;
 	self->mix = 1;
 	return self;
 }

+ 1 - 0
spine-c/spine-c/src/spine/Skeleton.c

@@ -436,6 +436,7 @@ void spSkeleton_setBonesToSetupPose (const spSkeleton* self) {
 	for (i = 0; i < self->ikConstraintsCount; ++i) {
 		spIkConstraint* ikConstraint = self->ikConstraints[i];
 		ikConstraint->bendDirection = ikConstraint->data->bendDirection;
+		ikConstraint->compress = ikConstraint->data->compress;
 		ikConstraint->stretch = ikConstraint->data->stretch;
 		ikConstraint->mix = ikConstraint->data->mix;
 	}

+ 4 - 1
spine-c/spine-c/src/spine/SkeletonBinary.c

@@ -392,8 +392,9 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 			float time = readFloat(input);
 			float mix = readFloat(input);
 			signed char bendDirection = readSByte(input);
+			int compress = readBoolean(input);
 			int stretch = readBoolean(input);
-			spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, bendDirection, stretch);
+			spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, bendDirection, compress, stretch);
 			if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
 		}
 		spTimelineArray_add(timelines, (spTimeline*)timeline);
@@ -958,7 +959,9 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
 		data->target = skeletonData->bones[readVarint(input, 1)];
 		data->mix = readFloat(input);
 		data->bendDirection = readSByte(input);
+		data->compress = readBoolean(input);
 		data->stretch = readBoolean(input);
+		data->uniform = readBoolean(input);
 		skeletonData->ikConstraints[i] = data;
 	}
 

+ 3 - 1
spine-c/spine-c/src/spine/SkeletonJson.c

@@ -299,7 +299,7 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
 		}
 		for (valueMap = constraintMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
 			spIkConstraintTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "mix", 1),
-					Json_getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json_getInt(valueMap, "stretch", 0) ? 1 : 0);
+					Json_getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json_getInt(valueMap, "compress", 0) ? 1 : 0, Json_getInt(valueMap, "stretch", 0) ? 1 : 0);
 			readCurve(valueMap, SUPER(timeline), frameIndex);
 		}
 		animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
@@ -737,7 +737,9 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
 			}
 
 			data->bendDirection = Json_getInt(constraintMap, "bendPositive", 1) ? 1 : -1;
+			data->compress = Json_getInt(constraintMap, "compress", 0) ? 1 : 0;
 			data->stretch = Json_getInt(constraintMap, "stretch", 0) ? 1 : 0;
+			data->uniform = Json_getInt(constraintMap, "uniform", 0) ? 1 : 0;
 			data->mix = Json_getFloat(constraintMap, "mix", 1);
 
 			skeletonData->ikConstraints[i] = data;

+ 6 - 1
spine-cpp/spine-cpp/include/spine/IkConstraint.h

@@ -52,7 +52,7 @@ RTTI_DECL
 public:
 	/// Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified
 	/// in the world coordinate system.
-	static void apply(Bone &bone, float targetX, float targetY, bool stretch, float alpha);
+	static void apply(Bone &bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha);
 
 	/// Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as
 	/// possible. The target is specified in the world coordinate system.
@@ -80,6 +80,10 @@ public:
 
 	void setBendDirection(int inValue);
 
+	bool getCompress();
+
+	void setCompress(bool inValue);
+
 	bool getStretch();
 
 	void setStretch(bool inValue);
@@ -92,6 +96,7 @@ private:
 	IkConstraintData &_data;
 	Vector<Bone *> _bones;
 	int _bendDirection;
+	bool _compress;
 	bool _stretch;
 	float _mix;
 	Bone *_target;

+ 8 - 0
spine-cpp/spine-cpp/include/spine/IkConstraintData.h

@@ -65,8 +65,14 @@ namespace spine {
         int getBendDirection();
         void setBendDirection(int inValue);
 
+        bool getCompress();
+        void setCompress(bool inValue);
+
         bool getStretch();
         void setStretch(bool inValue);
+
+        bool getUniform();
+        void setUniform(bool inValue);
         
         float getMix();
         void setMix(float inValue);
@@ -77,7 +83,9 @@ namespace spine {
         Vector<BoneData*> _bones;
         BoneData* _target;
         int _bendDirection;
+        bool _compress;
         bool _stretch;
+        bool _uniform;
         float _mix;
     };
 }

+ 3 - 3
spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h

@@ -50,11 +50,11 @@ namespace spine {
         virtual int getPropertyId();
         
         /// Sets the time, mix and bend direction of the specified keyframe.
-        void setFrame (int frameIndex, float time, float mix, int bendDirection, bool stretch);
+        void setFrame (int frameIndex, float time, float mix, int bendDirection, bool compress, bool stretch);
         
     private:
-        static const int PREV_TIME, PREV_MIX, PREV_BEND_DIRECTION, PREV_STRETCH;
-        static const int MIX, BEND_DIRECTION, STRETCH;
+        static const int PREV_TIME, PREV_MIX, PREV_BEND_DIRECTION, PREV_COMPRESS, PREV_STRETCH;
+        static const int MIX, BEND_DIRECTION, COMPRESS, STRETCH;
         
         Vector<float> _frames;
         int _ikConstraintIndex;

+ 1 - 1
spine-cpp/spine-cpp/src/spine/AnimationState.cpp

@@ -716,10 +716,10 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
 	// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
 	float r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
 	float total, diff = r2 - r1;
+	diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360;
 	if (diff == 0) {
 		total = timelinesRotation[i];
 	} else {
-		diff -= (16384 - (int) (16384.499999999996 - diff / 360)) * 360;
 		float lastTotal, lastDiff;
 		if (firstFrame) {
 			lastTotal = 0;

+ 19 - 5
spine-cpp/spine-cpp/src/spine/IkConstraint.cpp

@@ -44,7 +44,7 @@ using namespace spine;
 
 RTTI_IMPL(IkConstraint, Constraint)
 
-void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool stretch, float alpha) {
+void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha) {
 	Bone *p = bone.getParent();
 	float id, x, y, tx, ty, rotationIK;
 	if (!bone._appliedValid) bone.updateAppliedTransform();
@@ -57,12 +57,17 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool stretch,
 	if (rotationIK > 180) rotationIK -= 360;
 	else if (rotationIK < -180) rotationIK += 360;
 	float sx = bone._ascaleX;
-	if (stretch) {
+	float sy = bone._ascaleY;
+	if (compress || stretch) {
 		float b = bone._data.getLength() * sx, dd = MathUtil::sqrt(tx * tx + ty * ty);
-		if (dd > b && b > 0.0001f) sx *= (dd / b - 1) * alpha + 1;
+		if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001f) {
+			float s = (dd / b - 1) * alpha + 1;
+			sx *= s;
+			if (uniform) sy *= s;
+		}
 	}
 	bone.updateWorldTransform(bone._ax, bone._ay, bone._arotation + rotationIK * alpha, sx,
-							  bone._ascaleY, bone._ashearX, bone._ashearY);
+							  sy, bone._ashearX, bone._ashearY);
 }
 
 void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY, int bendDir, bool stretch, float alpha) {
@@ -206,6 +211,7 @@ void IkConstraint::apply(Bone &parent, Bone &child, float targetX, float targetY
 IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) : Constraint(),
 																		 _data(data),
 																		 _bendDirection(data.getBendDirection()),
+																		 _compress(data.getCompress()),
 																		 _stretch(data.getStretch()),
 																		 _mix(data.getMix()),
 																		 _target(skeleton.findBone(
@@ -226,7 +232,7 @@ void IkConstraint::update() {
 	switch (_bones.size()) {
 		case 1: {
 			Bone *bone0 = _bones[0];
-			apply(*bone0, _target->getWorldX(), _target->getWorldY(), _stretch, _mix);
+			apply(*bone0, _target->getWorldX(), _target->getWorldY(), _compress, _stretch, _data._uniform, _mix);
 		}
 			break;
 		case 2: {
@@ -281,3 +287,11 @@ bool IkConstraint::getStretch() {
 void IkConstraint::setStretch(bool inValue) {
 	_stretch = inValue;
 }
+
+bool IkConstraint::getCompress() {
+	return _compress;
+}
+
+void IkConstraint::setCompress(bool inValue) {
+	_compress = inValue;
+}

+ 19 - 0
spine-cpp/spine-cpp/src/spine/IkConstraintData.cpp

@@ -43,7 +43,9 @@ IkConstraintData::IkConstraintData(const String &name) :
 		_order(0),
 		_target(NULL),
 		_bendDirection(1),
+		_compress(false),
 		_stretch(false),
+		_uniform(false),
 		_mix(1) {
 }
 
@@ -94,3 +96,20 @@ bool IkConstraintData::getStretch() {
 void IkConstraintData::setStretch(bool inValue) {
 	_stretch = inValue;
 }
+
+bool IkConstraintData::getCompress() {
+	return _compress;
+}
+
+void IkConstraintData::setCompress(bool inValue) {
+	_compress = inValue;
+}
+
+
+bool IkConstraintData::getUniform() {
+	return _uniform;
+}
+
+void IkConstraintData::setUniform(bool inValue) {
+	_uniform = inValue;
+}

+ 18 - 7
spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp

@@ -48,14 +48,16 @@ using namespace spine;
 
 RTTI_IMPL(IkConstraintTimeline, CurveTimeline)
 
-const int IkConstraintTimeline::ENTRIES = 4;
-const int IkConstraintTimeline::PREV_TIME = -4;
-const int IkConstraintTimeline::PREV_MIX = -3;
-const int IkConstraintTimeline::PREV_BEND_DIRECTION = -2;
+const int IkConstraintTimeline::ENTRIES = 5;
+const int IkConstraintTimeline::PREV_TIME = -5;
+const int IkConstraintTimeline::PREV_MIX = -4;
+const int IkConstraintTimeline::PREV_BEND_DIRECTION = -3;
+const int IkConstraintTimeline::PREV_COMPRESS = -2;
 const int IkConstraintTimeline::PREV_STRETCH = -1;
 const int IkConstraintTimeline::MIX = 1;
 const int IkConstraintTimeline::BEND_DIRECTION = 2;
-const int IkConstraintTimeline::STRETCH = 3;
+const int IkConstraintTimeline::COMPRESS = 3;
+const int IkConstraintTimeline::STRETCH = 4;
 
 IkConstraintTimeline::IkConstraintTimeline(int frameCount) : CurveTimeline(frameCount), _ikConstraintIndex(0) {
 	_frames.setSize(frameCount * ENTRIES, 0);
@@ -73,11 +75,13 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time,
 			case MixBlend_Setup:
 				constraint._mix = constraint._data._mix;
 				constraint._bendDirection = constraint._data._bendDirection;
+				constraint._compress = constraint._data._compress;
 				constraint._stretch = constraint._data._stretch;
 				return;
 			case MixBlend_First:
 				constraint._mix += (constraint._data._mix - constraint._mix) * alpha;
 				constraint._bendDirection = constraint._data._bendDirection;
+				constraint._compress = constraint._data._compress;
 				constraint._stretch = constraint._data._stretch;
 				return;
 			default:
@@ -92,15 +96,18 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time,
 					constraint._data._mix + (_frames[_frames.size() + PREV_MIX] - constraint._data._mix) * alpha;
 			if (direction == MixDirection_Out) {
 				constraint._bendDirection = constraint._data._bendDirection;
+				constraint._compress = constraint._data._compress;
 				constraint._stretch = constraint._data._stretch;
 			} else {
 				constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION];
+				constraint._compress = _frames[_frames.size() + PREV_COMPRESS] != 0;
 				constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0;
 			}
 		} else {
 			constraint._mix += (_frames[_frames.size() + PREV_MIX] - constraint._mix) * alpha;
 			if (direction == MixDirection_In) {
 				constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION];
+				constraint._compress = _frames[_frames.size() + PREV_COMPRESS] != 0;
 				constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0;
 			}
 		}
@@ -119,15 +126,18 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time,
 				constraint._data._mix + (mix + (_frames[frame + MIX] - mix) * percent - constraint._data._mix) * alpha;
 		if (direction == MixDirection_Out) {
 			constraint._bendDirection = constraint._data._bendDirection;
+			constraint._compress = constraint._data._compress;
 			constraint._stretch = constraint._data._stretch;
 		} else {
 			constraint._bendDirection = (int) _frames[_frames.size() + PREV_BEND_DIRECTION];
-			constraint._stretch = _frames[_frames.size() + PREV_STRETCH] != 0;
+			constraint._compress = _frames[frame + PREV_COMPRESS] != 0;
+			constraint._stretch = _frames[frame + PREV_STRETCH] != 0;
 		}
 	} else {
 		constraint._mix += (mix + (_frames[frame + MIX] - mix) * percent - constraint._mix) * alpha;
 		if (direction == MixDirection_In) {
 			constraint._bendDirection = (int) _frames[frame + PREV_BEND_DIRECTION];
+			constraint._compress = _frames[frame + PREV_COMPRESS] != 0;
 			constraint._stretch = _frames[frame + PREV_STRETCH] != 0;
 		}
 	}
@@ -137,10 +147,11 @@ int IkConstraintTimeline::getPropertyId() {
 	return ((int) TimelineType_IkConstraint << 24) + _ikConstraintIndex;
 }
 
-void IkConstraintTimeline::setFrame(int frameIndex, float time, float mix, int bendDirection, bool stretch) {
+void IkConstraintTimeline::setFrame(int frameIndex, float time, float mix, int bendDirection, bool compress, bool stretch) {
 	frameIndex *= ENTRIES;
 	_frames[frameIndex] = time;
 	_frames[frameIndex + MIX] = mix;
 	_frames[frameIndex + BEND_DIRECTION] = (float)bendDirection;
+	_frames[frameIndex + COMPRESS] = compress ? 1 : 0;
 	_frames[frameIndex + STRETCH] = stretch ? 1 : 0;
 }

+ 1 - 0
spine-cpp/spine-cpp/src/spine/Skeleton.cpp

@@ -230,6 +230,7 @@ void Skeleton::setBonesToSetupPose() {
 		IkConstraint &constraint = *constraintP;
 
 		constraint._bendDirection = constraint._data._bendDirection;
+		constraint._compress = constraint._data._compress;
 		constraint._stretch = constraint._data._stretch;
 		constraint._mix = constraint._data._mix;
 	}

+ 4 - 1
spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp

@@ -203,7 +203,9 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons
 		data->_target = skeletonData->_bones[readVarint(input, true)];
 		data->_mix = readFloat(input);
 		data->_bendDirection = readSByte(input);
+		data->_compress = readBoolean(input);
 		data->_stretch = readBoolean(input);
+		data->_uniform = readBoolean(input);
 		skeletonData->_ikConstraints[i] = data;
 	}
 
@@ -781,8 +783,9 @@ Animation *SkeletonBinary::readAnimation(const String &name, DataInput *input, S
 			float time = readFloat(input);
 			float mix = readFloat(input);
 			signed char bendDirection = readSByte(input);
+			bool compress = readBoolean(input);
 			bool stretch = readBoolean(input);
-			timeline->setFrame(frameIndex, time, mix, bendDirection, stretch);
+			timeline->setFrame(frameIndex, time, mix, bendDirection, compress, stretch);
 			if (frameIndex < frameCount - 1) {
 				readCurve(input, frameIndex, timeline);
 			}

+ 4 - 2
spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp

@@ -285,9 +285,11 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) {
 				return NULL;
 			}
 
+			data->_mix = Json::getFloat(constraintMap, "mix", 1);
 			data->_bendDirection = Json::getInt(constraintMap, "bendPositive", 1) ? 1 : -1;
+			data->_compress = Json::getInt(constraintMap, "compress", 0) ? true: false;
 			data->_stretch = Json::getInt(constraintMap, "stretch", 0) ? true: false;
-			data->_mix = Json::getFloat(constraintMap, "mix", 1);
+			data->_uniform = Json::getInt(constraintMap, "uniform", 0) ? true: false;
 
 			skeletonData->_ikConstraints[i] = data;
 		}
@@ -932,7 +934,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
 		}
 		for (valueMap = constraintMap->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) {
 			timeline->setFrame(frameIndex, Json::getFloat(valueMap, "time", 0), Json::getFloat(valueMap, "mix", 1),
-							   Json::getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json::getInt(valueMap, "stretch", 0) ? true : false);
+							   Json::getInt(valueMap, "bendPositive", 1) ? 1 : -1, Json::getInt(valueMap, "compress", 0) ? true : false, Json::getInt(valueMap, "stretch", 0) ? true : false);
 			readCurve(valueMap, timeline, frameIndex);
 		}
 		timelines.add(timeline);

+ 26 - 8
spine-csharp/src/Animation.cs

@@ -1210,15 +1210,15 @@ namespace Spine {
 	}
 
 	public class IkConstraintTimeline : CurveTimeline {
-		public const int ENTRIES = 4;
-		private const int PREV_TIME = -4, PREV_MIX = -3, PREV_BEND_DIRECTION = -2, PREV_STRETCH = -1;
-		private const int MIX = 1, BEND_DIRECTION = 2, STRETCH = 3;
+		public const int ENTRIES = 5;
+		private const int PREV_TIME = -5, PREV_MIX = -4, PREV_BEND_DIRECTION = -3, PREV_COMPRESS = -2, PREV_STRETCH = -1;
+		private const int MIX = 1, BEND_DIRECTION = 2, COMPRESS = 3, STRETCH = 4;
 
 		internal int ikConstraintIndex;
 		internal float[] frames;
 
 		public int IkConstraintIndex { get { return ikConstraintIndex; } set { ikConstraintIndex = value; } }
-		public float[] Frames { get { return frames; } set { frames = value; } } // time, mix, bendDirection, ...
+		public float[] Frames { get { return frames; } set { frames = value; } } // time, mix, bendDirection, compress, stretch ...
 
 		override public int PropertyId {
 			get { return ((int)TimelineType.IkConstraint << 24) + ikConstraintIndex; }
@@ -1229,12 +1229,13 @@ namespace Spine {
 			frames = new float[frameCount * ENTRIES];
 		}
 			
-		/// <summary>Sets the time, mix and bend direction of the specified keyframe.</summary>
-		public void SetFrame (int frameIndex, float time, float mix, int bendDirection, bool stretch) {
+		/// <summary>Sets the time, mix, bend direction, compress and stretch of the specified keyframe.</summary>
+		public void SetFrame (int frameIndex, float time, float mix, int bendDirection, bool compress, bool stretch) {
 			frameIndex *= ENTRIES;
 			frames[frameIndex] = time;
 			frames[frameIndex + MIX] = mix;
 			frames[frameIndex + BEND_DIRECTION] = bendDirection;
+			frames[frameIndex + COMPRESS] = compress ? 1 : 0;
 			frames[frameIndex + STRETCH] = stretch ? 1 : 0;
 		}
 
@@ -1246,11 +1247,13 @@ namespace Spine {
 				case MixBlend.Setup:
 					constraint.mix = constraint.data.mix;
 					constraint.bendDirection = constraint.data.bendDirection;
+					constraint.compress = constraint.data.compress;
 					constraint.stretch = constraint.data.stretch;
 					return;
 				case MixBlend.First:
 					constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
 					constraint.bendDirection = constraint.data.bendDirection;
+					constraint.compress = constraint.data.compress;
 					constraint.stretch = constraint.data.stretch;
 					return;
 				}
@@ -1262,15 +1265,18 @@ namespace Spine {
 					constraint.mix = constraint.data.mix + (frames[frames.Length + PREV_MIX] - constraint.data.mix) * alpha;
 					if (direction == MixDirection.Out) {
 						constraint.bendDirection = constraint.data.bendDirection;
+						constraint.compress = constraint.data.compress;
 						constraint.stretch = constraint.data.stretch;
 					} else {
 						constraint.bendDirection = (int)frames[frames.Length + PREV_BEND_DIRECTION];
+						constraint.compress = frames[frames.Length + PREV_COMPRESS] != 0;
 						constraint.stretch = frames[frames.Length + PREV_STRETCH] != 0;
 					}
 				} else {
 					constraint.mix += (frames[frames.Length + PREV_MIX] - constraint.mix) * alpha;
 					if (direction == MixDirection.In) {
 						constraint.bendDirection = (int)frames[frames.Length + PREV_BEND_DIRECTION];
+						constraint.compress = frames[frames.Length + PREV_COMPRESS] != 0;
 						constraint.stretch = frames[frames.Length + PREV_STRETCH] != 0;
 					}
 				}
@@ -1285,10 +1291,22 @@ namespace Spine {
 
 			if (blend == MixBlend.Setup) {
 				constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha;
-				constraint.bendDirection = direction == MixDirection.Out ? constraint.data.bendDirection : (int)frames[frame + PREV_BEND_DIRECTION];
+				if (direction == MixDirection.Out) {
+					constraint.bendDirection = constraint.data.bendDirection;
+					constraint.compress = constraint.data.compress;
+					constraint.stretch = constraint.data.stretch;
+				} else {
+					constraint.bendDirection = (int)frames[frame + PREV_BEND_DIRECTION];
+					constraint.compress = frames[frame + PREV_COMPRESS] != 0;
+					constraint.stretch = frames[frame + PREV_STRETCH] != 0;
+				}
 			} else {
 				constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
-				if (direction == MixDirection.In) constraint.bendDirection = (int)frames[frame + PREV_BEND_DIRECTION];
+				if (direction == MixDirection.In) {
+					constraint.bendDirection = (int)frames[frame + PREV_BEND_DIRECTION];
+					constraint.compress = frames[frame + PREV_COMPRESS] != 0;
+					constraint.stretch = frames[frame + PREV_STRETCH] != 0;
+				}
 			}
 		}
 	}

+ 23 - 11
spine-csharp/src/IkConstraint.cs

@@ -36,7 +36,7 @@ namespace Spine {
 		internal ExposedList<Bone> bones = new ExposedList<Bone>();
 		internal Bone target;
 		internal int bendDirection;
-		internal bool stretch;
+		internal bool compress, stretch;
 		internal float mix;
 
 		public IkConstraintData Data { get { return data; } }
@@ -59,9 +59,17 @@ namespace Spine {
 			set { bendDirection = value; }
 		}
 
+		/// <summary>
+		/// When true and only a single bone is being constrained, 
+		/// if the target is too close, the bone is scaled to reach it.</summary>
+		public bool Compress {
+			get { return compress; }
+			set { compress = value; }
+		}
+
 		/// <summary>
 		/// When true, if the target is out of range, the parent bone is scaled on the X axis to reach it.
-		/// IF the parent bone has nonuniform scale, stretching is not applied.</summary>
+		/// If the parent bone has nonuniform scale, stretching is not applied.</summary>
 		public bool Stretch {
 			get { return stretch; }
 			set { stretch = value; }
@@ -79,6 +87,7 @@ namespace Spine {
 			this.data = data;
 			mix = data.mix;
 			bendDirection = data.bendDirection;
+			compress = data.compress;
 			stretch = data.stretch;
 
 			bones = new ExposedList<Bone>(data.bones.Count);
@@ -97,7 +106,7 @@ namespace Spine {
 			ExposedList<Bone> bones = this.bones;
 			switch (bones.Count) {
 			case 1:
-				Apply(bones.Items[0], target.worldX, target.worldY, stretch, mix);
+				Apply(bones.Items[0], target.worldX, target.worldY, compress, stretch, data.uniform, mix);
 				break;
 			case 2:
 				Apply(bones.Items[0], bones.Items[1], target.worldX, target.worldY, bendDirection, stretch, mix);
@@ -109,9 +118,8 @@ namespace Spine {
 			return data.name;
 		}
 
-		/// <summary>Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified
-		/// in the world coordinate system.</summary>
-		static public void Apply (Bone bone, float targetX, float targetY, bool stretch, float alpha) {
+		/// <summary>Applies 1 bone IK. The target is specified in the world coordinate system.</summary>
+		static public void Apply (Bone bone, float targetX, float targetY, bool compress, bool stretch, bool uniform, float alpha) {
 			if (!bone.appliedValid) bone.UpdateAppliedTransform();
 			Bone p = bone.parent;
 			float id = 1 / (p.a * p.d - p.b * p.c);
@@ -121,14 +129,18 @@ namespace Spine {
 			if (bone.ascaleX < 0) rotationIK += 180;
 			if (rotationIK > 180)
 				rotationIK -= 360;
-			else if (rotationIK < -180)
+			else if (rotationIK < -180) //
 				rotationIK += 360;
-			float sx = bone.ascaleX;
-			if (stretch) {
+			float sx = bone.ascaleX, sy = bone.ascaleY;
+			if (compress || stretch) {
 				float b = bone.data.length * sx, dd = (float)Math.Sqrt(tx * tx + ty * ty);
-				if (dd > b && b > 0.0001f) sx *= (dd / b - 1) * alpha + 1;
+				if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001f) {
+					float s = (dd / b - 1) * alpha + 1;
+					sx *= s;
+					if (uniform) sy *= s;
+				}
 			}
-			bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX,
+			bone.UpdateWorldTransform(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX,
 				bone.ashearY);
 		}
 

+ 23 - 2
spine-csharp/src/IkConstraintData.cs

@@ -39,7 +39,7 @@ namespace Spine {
 		internal List<BoneData> bones = new List<BoneData>();
 		internal BoneData target;
 		internal int bendDirection = 1;
-		internal bool stretch;
+		internal bool compress, stretch, uniform;
 		internal float mix = 1;
 
 		/// <summary>The IK constraint's name, which is unique within the skeleton.</summary>
@@ -63,12 +63,27 @@ namespace Spine {
 			set { target = value; }
 		}
 
+		/// <summary>
+		/// A percentage (0-1) that controls the mix between the constraint and unconstrained rotations.</summary>
+		public float Mix {
+			get { return mix; }
+			set { mix = value; }
+		}
+
 		/// <summary>Controls the bend direction of the IK bones, either 1 or -1.</summary>
 		public int BendDirection {
 			get { return bendDirection; }
 			set { bendDirection = value; }
 		}
 
+		/// <summary>
+		/// When true, and only a single bone is being constrained, 
+		/// if the target is too close, the bone is scaled to reach it. </summary>
+		public bool Compress {
+			get { return compress; }
+			set { compress = value; }
+		}
+
 		/// <summary>
 		/// When true, if the target is out of range, the parent bone is scaled on the X axis to reach it. 
 		/// If the bone has local nonuniform scale, stretching is not applied.</summary>
@@ -77,7 +92,13 @@ namespace Spine {
 			set { stretch = value; }
 		}
 
-		public float Mix { get { return mix; } set { mix = value; } }
+		/// <summary>
+		/// When true, only a single bone is being constrained and Compress or Stretch is used, 
+		/// the bone is scaled both on the X and Y axes.</summary>
+		public bool Uniform {
+			get { return uniform; }
+			set { uniform = value; }
+		}
 
 		public IkConstraintData (string name) {
 			if (name == null) throw new ArgumentNullException("name", "name cannot be null.");

+ 2 - 1
spine-csharp/src/Skeleton.cs

@@ -308,9 +308,10 @@ namespace Spine {
 			var ikConstraintsItems = this.ikConstraints.Items;
 			for (int i = 0, n = ikConstraints.Count; i < n; i++) {
 				IkConstraint constraint = ikConstraintsItems[i];
+				constraint.mix = constraint.data.mix;
 				constraint.bendDirection = constraint.data.bendDirection;
+				constraint.compress = constraint.data.compress;
 				constraint.stretch = constraint.data.stretch;
-				constraint.mix = constraint.data.mix;
 			}
 
 			var transformConstraintsItems = this.transformConstraints.Items;

+ 6 - 3
spine-csharp/src/SkeletonBinary.cs

@@ -210,7 +210,9 @@ namespace Spine {
 				data.target = skeletonData.bones.Items[ReadVarint(input, true)];
 				data.mix = ReadFloat(input);
 				data.bendDirection = ReadSByte(input);
+				data.compress = ReadBoolean(input);
 				data.stretch = ReadBoolean(input);
+				data.uniform = ReadBoolean(input);
 				skeletonData.ikConstraints.Add(data);
 			}
 
@@ -646,10 +648,11 @@ namespace Spine {
 			for (int i = 0, n = ReadVarint(input, true); i < n; i++) {				
 				int index = ReadVarint(input, true);
 				int frameCount = ReadVarint(input, true);
-				IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
-				timeline.ikConstraintIndex = index;
+				IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount) {
+					ikConstraintIndex = index
+				};
 				for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
-					timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input), ReadBoolean(input));
+					timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input), ReadBoolean(input), ReadBoolean(input));
 					if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
 				}
 				timelines.Add(timeline);

+ 11 - 7
spine-csharp/src/SkeletonJson.cs

@@ -180,10 +180,11 @@ namespace Spine {
 					string targetName = (string)constraintMap["target"];
 					data.target = skeletonData.FindBone(targetName);
 					if (data.target == null) throw new Exception("Target bone not found: " + targetName);
-
+					data.mix = GetFloat(constraintMap, "mix", 1);
 					data.bendDirection = GetBoolean(constraintMap, "bendPositive", true) ? 1 : -1;
+					data.compress = GetBoolean(constraintMap, "compress", false);
 					data.stretch = GetBoolean(constraintMap, "stretch", false);
-					data.mix = GetFloat(constraintMap, "mix", 1);
+					data.uniform = GetBoolean(constraintMap, "uniform", false);
 
 					skeletonData.ikConstraints.Add(data);
 				}
@@ -595,11 +596,14 @@ namespace Spine {
 					timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint);
 					int frameIndex = 0;
 					foreach (Dictionary<string, Object> valueMap in values) {
-						float time = (float)valueMap["time"];
-						float mix = GetFloat(valueMap, "mix", 1);
-						bool bendPositive = GetBoolean(valueMap, "bendPositive", true);
-						bool stretch = GetBoolean(valueMap, "stretch", false);
-						timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1, stretch);
+						timeline.SetFrame(
+							frameIndex,
+							(float)valueMap["time"],
+							GetFloat(valueMap, "mix", 1),
+							GetBoolean(valueMap, "bendPositive", true) ? 1 : -1,
+							GetBoolean(valueMap, "compress", true),
+							GetBoolean(valueMap, "stretch", false)
+						);
 						ReadCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}

+ 21 - 6
spine-lua/Animation.lua

@@ -1169,19 +1169,21 @@ function Animation.DrawOrderTimeline.new (frameCount)
 end
 
 Animation.IkConstraintTimeline = {}
-Animation.IkConstraintTimeline.ENTRIES = 4
+Animation.IkConstraintTimeline.ENTRIES = 5
 function Animation.IkConstraintTimeline.new (frameCount)
 	local ENTRIES = Animation.IkConstraintTimeline.ENTRIES
-	local PREV_TIME = -4
-	local PREV_MIX = -3
-	local PREV_BEND_DIRECTION = -2
+	local PREV_TIME = -5
+	local PREV_MIX = -4
+	local PREV_BEND_DIRECTION = -3
+	local PREV_COMPRESS = -2
 	local PREV_STRETCH = -1
 	local MIX = 1
 	local BEND_DIRECTION = 2
+	local COMPRESS = 3
 	local STRETCH = 1
 
 	local self = Animation.CurveTimeline.new(frameCount)
-	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES) -- time, mix, bendDirection, ...
+	self.frames = utils.newNumberArrayZero(frameCount * ENTRIES) -- time, mix, bendDirection, compress, stretch, ...
 	self.ikConstraintIndex = -1
 	self.type = TimelineType.ikConstraint
 	
@@ -1189,11 +1191,16 @@ function Animation.IkConstraintTimeline.new (frameCount)
 		return TimelineType.ikConstraint * SHL_24 + self.ikConstraintIndex
 	end
 
-	function self:setFrame (frameIndex, time, mix, bendDirection, stretch)
+	function self:setFrame (frameIndex, time, mix, bendDirection, compress, stretch)
 		frameIndex = frameIndex * ENTRIES
 		self.frames[frameIndex] = time
 		self.frames[frameIndex + MIX] = mix
 		self.frames[frameIndex + BEND_DIRECTION] = bendDirection
+		if (compress) then
+			self.frames[frameIndex + COMPRESS] = 1
+		else
+			self.frames[frameIndex + COMPRESS] = 0
+		end
 		if (stretch) then
 			self.frames[frameIndex + STRETCH] = 1
 		else
@@ -1209,10 +1216,12 @@ function Animation.IkConstraintTimeline.new (frameCount)
 			if blend == MixBlend.setup then
 				constraint.mix = constraint.data.mix
 				constraint.bendDirection = constraint.data.bendDirection
+				constraint.compress = constraint.data.compress
 				constraint.stretch = constraint.data.stretch
 			elseif blend == MixBlend.first then
 				constraint.mix = constraint.mix + (constraint.data.mix - constraint.mix) * alpha
 				constraint.bendDirection = constraint.data.bendDirection
+				constraint.compress = constraint.data.compress
 				constraint.stretch = constraint.data.stretch
 			end
 			return
@@ -1223,15 +1232,18 @@ function Animation.IkConstraintTimeline.new (frameCount)
 				constraint.mix = constraint.data.mix + (frames[zlen(frames) + PREV_MIX] - constraint.data.mix) * alpha
 				if direction == MixDirection.out then 
 					constraint.bendDirection = constraint.data.bendDirection
+					constraint.compress = constraint.data.compress
 					constraint.stretch = constraint.data.stretch
 				else
 					constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION]);
+					if (math_floor(frames[zlen(frames) + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
 					if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 				end
 			else
 				constraint.mix = constraint.mix + (frames[frames.length + PREV_MIX] - constraint.mix) * alpha;
 				if direction == MixDirection._in then 
 					constraint.bendDirection = math_floor(frames[zlen(frames) + PREV_BEND_DIRECTION])
+					if (math_floor(frames[zlen(frames) + PREV_COMPRES]) == 1) then constraint.compress = true else constraint.compress = false end
 					if (math_floor(frames[zlen(frames) + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 				end
 			end
@@ -1249,15 +1261,18 @@ function Animation.IkConstraintTimeline.new (frameCount)
 			constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha
 			if direction == MixDirection.out then
 				constraint.bendDirection = constraint.data.bendDirection
+				constraint.compress = constraint.data.compress
 				constraint.stretch = constraint.data.stretch
 			else
 				constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
+				if (math_floor(frames[frame + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
 				if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 			end
 		else
 			constraint.mix = constraint.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
 			if direction == MixDirection._in then 
 				constraint.bendDirection = math_floor(frames[frame + PREV_BEND_DIRECTION])
+				if (math_floor(frames[frame + PREV_COMPRESS]) == 1) then constraint.compress = true else constraint.compress = false end
 				if (math_floor(frames[frame + PREV_STRETCH]) == 1) then constraint.stretch = true else constraint.stretch = false end
 			end
 		end

+ 1 - 1
spine-lua/AnimationState.lua

@@ -543,10 +543,10 @@ function AnimationState:applyRotateTimeline (timeline, skeleton, time, alpha, bl
   if blend == MixBlend.setup then r1 = bone.data.rotation end
   local total = 0
   local diff = r2 - r1
+	diff = diff - (16384 - math_floor(16384.499999999996 - diff / 360)) * 360
   if diff == 0 then
     total = timelinesRotation[i]
   else
-    diff = diff - (16384 - math_floor(16384.499999999996 - diff / 360)) * 360
     local lastTotal = 0
     local lastDiff = 0
     if firstFrame then

+ 12 - 5
spine-lua/IkConstraint.lua

@@ -52,6 +52,7 @@ function IkConstraint.new (data, skeleton)
 		bones = {},
 		target = nil,
 		mix = data.mix,
+		compress = data.compress,
 		stretch = data.stretch,
 		bendDirection = data.bendDirection,
 	}
@@ -75,13 +76,13 @@ function IkConstraint:update ()
 	local bones = self.bones
 	local boneCount = #bones
 	if boneCount == 1 then
-		self:apply1(bones[1], target.worldX, target.worldY, self.stretch, self.mix)
+		self:apply1(bones[1], target.worldX, target.worldY, self.compress, self.stretch, self.data.uniform, self.mix)
 	elseif boneCount == 2 then
 		self:apply2(bones[1], bones[2], target.worldX, target.worldY, self.bendDirection, self.stretch, self.mix)
 	end
 end
 
-function IkConstraint:apply1 (bone, targetX, targetY, stretch, alpha)
+function IkConstraint:apply1 (bone, targetX, targetY, compress, stretch, uniform, alpha)
 	if not bone.appliedValid then bone:updateAppliedTransform() end
 	local p = bone.parent
 	local id = 1 / (p.a * p.d - p.b * p.c)
@@ -97,11 +98,17 @@ function IkConstraint:apply1 (bone, targetX, targetY, stretch, alpha)
 		rotationIK = rotationIK + 360
 	end
 	local sx = bone.ascaleX
-	if stretch then
+	local sy = bone.ascaleY
+	if compress or stretch then
+		local b = bone.data.length * sx
 		local dd = math_sqrt(tx * tx + ty * ty)
-		if dd > bone.data.length * sx then sx = sx * ((dd / (bone.data.length * sx) - 1) * alpha + 1) end
+		if (compress and dd < b) or (stretch and dd > b) and b > 0.0001 then
+			local s = (dd / b - 1) * alpha + 1
+			sx = sx * s
+			if uniform then sy = sy * s end
+		end
 	end
-	bone:updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY)
+	bone:updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY)
 end
 
 function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, stretch, alpha)

+ 2 - 0
spine-lua/IkConstraintData.lua

@@ -38,7 +38,9 @@ function IkConstraintData.new (name)
 		bones = {},
 		target = nil,
 		bendDirection = 1,
+		compress = false,
 		stretch = false,
+		uniform = false,
 		mix = 1
 	}
 

+ 2 - 1
spine-lua/Skeleton.lua

@@ -338,9 +338,10 @@ function Skeleton:setBonesToSetupPose ()
 	end
 
 	for _,ikConstraint in ipairs(self.ikConstraints) do
+		ikConstraint.mix = ikConstraint.data.mix
 		ikConstraint.bendDirection = ikConstraint.data.bendDirection
+		ikConstraint.compress = ikConstraint.data.compress
 		ikConstraint.stretch = ikConstraint.data.stretch
-		ikConstraint.mix = ikConstraint.data.mix
 	end
 
 	local transformConstraints = self.transformConstraints

+ 9 - 5
spine-lua/SkeletonJson.lua

@@ -164,9 +164,11 @@ function SkeletonJson.new (attachmentLoader)
 				data.target = skeletonData:findBone(targetName)
 				if not data.target then error("Target bone not found: " .. targetName) end
 
-				if constraintMap["bendPositive"] == false then data.bendDirection = -1 else data.bendDirection = 1 end
-				if constraintMap["stretch"] == false then data.stretch = false else data.stretch = true end
 				data.mix = getValue(constraintMap, "mix", 1)
+				if constraintMap["bendPositive"] == nil or constraintMap["bendPositive"] == false then data.bendDirection = -1 else data.bendDirection = 1 end
+				if constraintMap["compress"] == nil or constraintMap["compress"] == false then data.compress = false else data.compress = true end
+				if constraintMap["stretch"] == nil  or constraintMap["stretch"] == false then data.stretch = false else data.stretch = true end
+				if constraintMap["uniform"] == nil or  constraintMap["uniform"] == false then data.uniform = false else data.uniform = true end
 
 				table_insert(skeletonData.ikConstraints, data)
 			end
@@ -613,9 +615,11 @@ function SkeletonJson.new (attachmentLoader)
 					if valueMap["mix"] ~= nil then mix = valueMap["mix"] end
 					local bendPositive = 1
 					if valueMap["bendPositive"] == false then bendPositive = -1 end
-					local stretch = true
-					if valueMap["stretch"] == false then stretch = false end
-					timeline:setFrame(frameIndex, valueMap["time"], mix, bendPositive, stretch)
+					local stretch = false
+					if valueMap["stretch"] ~= nil then stretch = valueMap["stretch"] end
+					local compress = false
+					if valueMap["compress"] ~= nil then compress = valueMap["compress"] end
+					timeline:setFrame(frameIndex, valueMap["time"], mix, bendPositive, compress, stretch)
 					readCurve(valueMap, timeline, frameIndex)
 					frameIndex = frameIndex + 1
 				end

+ 1560 - 1555
spine-ts/build/spine-webgl.d.ts

@@ -1,1673 +1,1678 @@
 declare module spine {
-	class Animation {
-		name: string;
-		timelines: Array<Timeline>;
-		duration: number;
-		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
-		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
-	}
-	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-		getPropertyId(): number;
-	}
-	enum MixBlend {
-		setup = 0,
-		first = 1,
-		replace = 2,
-		add = 3
-	}
-	enum MixDirection {
-		in = 0,
-		out = 1
-	}
-	enum TimelineType {
-		rotate = 0,
-		translate = 1,
-		scale = 2,
-		shear = 3,
-		attachment = 4,
-		color = 5,
-		deform = 6,
-		event = 7,
-		drawOrder = 8,
-		ikConstraint = 9,
-		transformConstraint = 10,
-		pathConstraintPosition = 11,
-		pathConstraintSpacing = 12,
-		pathConstraintMix = 13,
-		twoColor = 14
-	}
-	abstract class CurveTimeline implements Timeline {
-		static LINEAR: number;
-		static STEPPED: number;
-		static BEZIER: number;
-		static BEZIER_SIZE: number;
-		private curves;
-		abstract getPropertyId(): number;
-		constructor(frameCount: number);
-		getFrameCount(): number;
-		setLinear(frameIndex: number): void;
-		setStepped(frameIndex: number): void;
-		getCurveType(frameIndex: number): number;
-		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
-		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class RotateTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_ROTATION: number;
-		static ROTATION: number;
-		boneIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class TranslateTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_X: number;
-		static PREV_Y: number;
-		static X: number;
-		static Y: number;
-		boneIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class ScaleTimeline extends TranslateTimeline {
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class ShearTimeline extends TranslateTimeline {
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class ColorTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_R: number;
-		static PREV_G: number;
-		static PREV_B: number;
-		static PREV_A: number;
-		static R: number;
-		static G: number;
-		static B: number;
-		static A: number;
-		slotIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class TwoColorTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_R: number;
-		static PREV_G: number;
-		static PREV_B: number;
-		static PREV_A: number;
-		static PREV_R2: number;
-		static PREV_G2: number;
-		static PREV_B2: number;
-		static R: number;
-		static G: number;
-		static B: number;
-		static A: number;
-		static R2: number;
-		static G2: number;
-		static B2: number;
-		slotIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class AttachmentTimeline implements Timeline {
-		slotIndex: number;
-		frames: ArrayLike<number>;
-		attachmentNames: Array<string>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		getFrameCount(): number;
-		setFrame(frameIndex: number, time: number, attachmentName: string): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class DeformTimeline extends CurveTimeline {
-		slotIndex: number;
-		attachment: VertexAttachment;
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class EventTimeline implements Timeline {
-		frames: ArrayLike<number>;
-		events: Array<Event>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		getFrameCount(): number;
-		setFrame(frameIndex: number, event: Event): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class DrawOrderTimeline implements Timeline {
-		frames: ArrayLike<number>;
-		drawOrders: Array<Array<number>>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		getFrameCount(): number;
-		setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class IkConstraintTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_MIX: number;
-		static PREV_BEND_DIRECTION: number;
-		static PREV_STRETCH: number;
-		static MIX: number;
-		static BEND_DIRECTION: number;
-		static STRETCH: number;
-		ikConstraintIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class TransformConstraintTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_ROTATE: number;
-		static PREV_TRANSLATE: number;
-		static PREV_SCALE: number;
-		static PREV_SHEAR: number;
-		static ROTATE: number;
-		static TRANSLATE: number;
-		static SCALE: number;
-		static SHEAR: number;
-		transformConstraintIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class PathConstraintPositionTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_VALUE: number;
-		static VALUE: number;
-		pathConstraintIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, value: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
-	class PathConstraintMixTimeline extends CurveTimeline {
-		static ENTRIES: number;
-		static PREV_TIME: number;
-		static PREV_ROTATE: number;
-		static PREV_TRANSLATE: number;
-		static ROTATE: number;
-		static TRANSLATE: number;
-		pathConstraintIndex: number;
-		frames: ArrayLike<number>;
-		constructor(frameCount: number);
-		getPropertyId(): number;
-		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
-	}
+    class Animation {
+        name: string;
+        timelines: Array<Timeline>;
+        duration: number;
+        constructor(name: string, timelines: Array<Timeline>, duration: number);
+        apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+        static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
+        static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
+    }
+    interface Timeline {
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+        getPropertyId(): number;
+    }
+    enum MixBlend {
+        setup = 0,
+        first = 1,
+        replace = 2,
+        add = 3,
+    }
+    enum MixDirection {
+        in = 0,
+        out = 1,
+    }
+    enum TimelineType {
+        rotate = 0,
+        translate = 1,
+        scale = 2,
+        shear = 3,
+        attachment = 4,
+        color = 5,
+        deform = 6,
+        event = 7,
+        drawOrder = 8,
+        ikConstraint = 9,
+        transformConstraint = 10,
+        pathConstraintPosition = 11,
+        pathConstraintSpacing = 12,
+        pathConstraintMix = 13,
+        twoColor = 14,
+    }
+    abstract class CurveTimeline implements Timeline {
+        static LINEAR: number;
+        static STEPPED: number;
+        static BEZIER: number;
+        static BEZIER_SIZE: number;
+        private curves;
+        abstract getPropertyId(): number;
+        constructor(frameCount: number);
+        getFrameCount(): number;
+        setLinear(frameIndex: number): void;
+        setStepped(frameIndex: number): void;
+        getCurveType(frameIndex: number): number;
+        setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
+        getCurvePercent(frameIndex: number, percent: number): number;
+        abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class RotateTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_ROTATION: number;
+        static ROTATION: number;
+        boneIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, degrees: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class TranslateTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_X: number;
+        static PREV_Y: number;
+        static X: number;
+        static Y: number;
+        boneIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, x: number, y: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class ScaleTimeline extends TranslateTimeline {
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class ShearTimeline extends TranslateTimeline {
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class ColorTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_R: number;
+        static PREV_G: number;
+        static PREV_B: number;
+        static PREV_A: number;
+        static R: number;
+        static G: number;
+        static B: number;
+        static A: number;
+        slotIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class TwoColorTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_R: number;
+        static PREV_G: number;
+        static PREV_B: number;
+        static PREV_A: number;
+        static PREV_R2: number;
+        static PREV_G2: number;
+        static PREV_B2: number;
+        static R: number;
+        static G: number;
+        static B: number;
+        static A: number;
+        static R2: number;
+        static G2: number;
+        static B2: number;
+        slotIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class AttachmentTimeline implements Timeline {
+        slotIndex: number;
+        frames: ArrayLike<number>;
+        attachmentNames: Array<string>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        getFrameCount(): number;
+        setFrame(frameIndex: number, time: number, attachmentName: string): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class DeformTimeline extends CurveTimeline {
+        slotIndex: number;
+        attachment: VertexAttachment;
+        frames: ArrayLike<number>;
+        frameVertices: Array<ArrayLike<number>>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class EventTimeline implements Timeline {
+        frames: ArrayLike<number>;
+        events: Array<Event>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        getFrameCount(): number;
+        setFrame(frameIndex: number, event: Event): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class DrawOrderTimeline implements Timeline {
+        frames: ArrayLike<number>;
+        drawOrders: Array<Array<number>>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        getFrameCount(): number;
+        setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class IkConstraintTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_MIX: number;
+        static PREV_BEND_DIRECTION: number;
+        static PREV_COMPRESS: number;
+        static PREV_STRETCH: number;
+        static MIX: number;
+        static BEND_DIRECTION: number;
+        static COMPRESS: number;
+        static STRETCH: number;
+        ikConstraintIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, compress: boolean, stretch: boolean): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class TransformConstraintTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_ROTATE: number;
+        static PREV_TRANSLATE: number;
+        static PREV_SCALE: number;
+        static PREV_SHEAR: number;
+        static ROTATE: number;
+        static TRANSLATE: number;
+        static SCALE: number;
+        static SHEAR: number;
+        transformConstraintIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class PathConstraintPositionTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_VALUE: number;
+        static VALUE: number;
+        pathConstraintIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, value: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
+    class PathConstraintMixTimeline extends CurveTimeline {
+        static ENTRIES: number;
+        static PREV_TIME: number;
+        static PREV_ROTATE: number;
+        static PREV_TRANSLATE: number;
+        static ROTATE: number;
+        static TRANSLATE: number;
+        pathConstraintIndex: number;
+        frames: ArrayLike<number>;
+        constructor(frameCount: number);
+        getPropertyId(): number;
+        setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
+        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
+    }
 }
 declare module spine {
-	class AnimationState {
-		static emptyAnimation: Animation;
-		static SUBSEQUENT: number;
-		static FIRST: number;
-		static DIP: number;
-		static DIP_MIX: number;
-		data: AnimationStateData;
-		tracks: TrackEntry[];
-		events: Event[];
-		listeners: AnimationStateListener2[];
-		queue: EventQueue;
-		propertyIDs: IntSet;
-		mixingTo: TrackEntry[];
-		animationsChanged: boolean;
-		timeScale: number;
-		trackEntryPool: Pool<TrackEntry>;
-		constructor(data: AnimationStateData);
-		update(delta: number): void;
-		updateMixingFrom(to: TrackEntry, delta: number): boolean;
-		apply(skeleton: Skeleton): boolean;
-		applyMixingFrom(to: TrackEntry, skeleton: Skeleton, blend: MixBlend): number;
-		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, blend: MixBlend, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
-		queueEvents(entry: TrackEntry, animationTime: number): void;
-		clearTracks(): void;
-		clearTrack(trackIndex: number): void;
-		setCurrent(index: number, current: TrackEntry, interrupt: boolean): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
-		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
-		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
-		setEmptyAnimations(mixDuration: number): void;
-		expandToIndex(index: number): TrackEntry;
-		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
-		disposeNext(entry: TrackEntry): void;
-		_animationsChanged(): void;
-		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener2): void;
-		removeListener(listener: AnimationStateListener2): void;
-		clearListeners(): void;
-		clearListenerNotifications(): void;
-	}
-	class TrackEntry {
-		animation: Animation;
-		next: TrackEntry;
-		mixingFrom: TrackEntry;
-		listener: AnimationStateListener2;
-		trackIndex: number;
-		loop: boolean;
-		eventThreshold: number;
-		attachmentThreshold: number;
-		drawOrderThreshold: number;
-		animationStart: number;
-		animationEnd: number;
-		animationLast: number;
-		nextAnimationLast: number;
-		delay: number;
-		trackTime: number;
-		trackLast: number;
-		nextTrackLast: number;
-		trackEnd: number;
-		timeScale: number;
-		alpha: number;
-		mixTime: number;
-		mixDuration: number;
-		interruptAlpha: number;
-		totalAlpha: number;
-		mixBlend: MixBlend;
-		timelineData: number[];
-		timelineDipMix: TrackEntry[];
-		timelinesRotation: number[];
-		reset(): void;
-		setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
-		hasTimeline(id: number): boolean;
-		getAnimationTime(): number;
-		setAnimationLast(animationLast: number): void;
-		isComplete(): boolean;
-		resetRotationDirections(): void;
-	}
-	class EventQueue {
-		objects: Array<any>;
-		drainDisabled: boolean;
-		animState: AnimationState;
-		constructor(animState: AnimationState);
-		start(entry: TrackEntry): void;
-		interrupt(entry: TrackEntry): void;
-		end(entry: TrackEntry): void;
-		dispose(entry: TrackEntry): void;
-		complete(entry: TrackEntry): void;
-		event(entry: TrackEntry, event: Event): void;
-		drain(): void;
-		clear(): void;
-	}
-	enum EventType {
-		start = 0,
-		interrupt = 1,
-		end = 2,
-		dispose = 3,
-		complete = 4,
-		event = 5
-	}
-	interface AnimationStateListener2 {
-		start(entry: TrackEntry): void;
-		interrupt(entry: TrackEntry): void;
-		end(entry: TrackEntry): void;
-		dispose(entry: TrackEntry): void;
-		complete(entry: TrackEntry): void;
-		event(entry: TrackEntry, event: Event): void;
-	}
-	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
-		start(entry: TrackEntry): void;
-		interrupt(entry: TrackEntry): void;
-		end(entry: TrackEntry): void;
-		dispose(entry: TrackEntry): void;
-		complete(entry: TrackEntry): void;
-		event(entry: TrackEntry, event: Event): void;
-	}
+    class AnimationState {
+        static emptyAnimation: Animation;
+        static SUBSEQUENT: number;
+        static FIRST: number;
+        static DIP: number;
+        static DIP_MIX: number;
+        data: AnimationStateData;
+        tracks: TrackEntry[];
+        events: Event[];
+        listeners: AnimationStateListener2[];
+        queue: EventQueue;
+        propertyIDs: IntSet;
+        mixingTo: TrackEntry[];
+        animationsChanged: boolean;
+        timeScale: number;
+        trackEntryPool: Pool<TrackEntry>;
+        constructor(data: AnimationStateData);
+        update(delta: number): void;
+        updateMixingFrom(to: TrackEntry, delta: number): boolean;
+        apply(skeleton: Skeleton): boolean;
+        applyMixingFrom(to: TrackEntry, skeleton: Skeleton, blend: MixBlend): number;
+        applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, blend: MixBlend, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+        queueEvents(entry: TrackEntry, animationTime: number): void;
+        clearTracks(): void;
+        clearTrack(trackIndex: number): void;
+        setCurrent(index: number, current: TrackEntry, interrupt: boolean): void;
+        setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+        setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+        addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+        addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+        setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+        addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+        setEmptyAnimations(mixDuration: number): void;
+        expandToIndex(index: number): TrackEntry;
+        trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+        disposeNext(entry: TrackEntry): void;
+        _animationsChanged(): void;
+        getCurrent(trackIndex: number): TrackEntry;
+        addListener(listener: AnimationStateListener2): void;
+        removeListener(listener: AnimationStateListener2): void;
+        clearListeners(): void;
+        clearListenerNotifications(): void;
+    }
+    class TrackEntry {
+        animation: Animation;
+        next: TrackEntry;
+        mixingFrom: TrackEntry;
+        listener: AnimationStateListener2;
+        trackIndex: number;
+        loop: boolean;
+        eventThreshold: number;
+        attachmentThreshold: number;
+        drawOrderThreshold: number;
+        animationStart: number;
+        animationEnd: number;
+        animationLast: number;
+        nextAnimationLast: number;
+        delay: number;
+        trackTime: number;
+        trackLast: number;
+        nextTrackLast: number;
+        trackEnd: number;
+        timeScale: number;
+        alpha: number;
+        mixTime: number;
+        mixDuration: number;
+        interruptAlpha: number;
+        totalAlpha: number;
+        mixBlend: MixBlend;
+        timelineData: number[];
+        timelineDipMix: TrackEntry[];
+        timelinesRotation: number[];
+        reset(): void;
+        setTimelineData(to: TrackEntry, mixingToArray: Array<TrackEntry>, propertyIDs: IntSet): TrackEntry;
+        hasTimeline(id: number): boolean;
+        getAnimationTime(): number;
+        setAnimationLast(animationLast: number): void;
+        isComplete(): boolean;
+        resetRotationDirections(): void;
+    }
+    class EventQueue {
+        objects: Array<any>;
+        drainDisabled: boolean;
+        animState: AnimationState;
+        constructor(animState: AnimationState);
+        start(entry: TrackEntry): void;
+        interrupt(entry: TrackEntry): void;
+        end(entry: TrackEntry): void;
+        dispose(entry: TrackEntry): void;
+        complete(entry: TrackEntry): void;
+        event(entry: TrackEntry, event: Event): void;
+        drain(): void;
+        clear(): void;
+    }
+    enum EventType {
+        start = 0,
+        interrupt = 1,
+        end = 2,
+        dispose = 3,
+        complete = 4,
+        event = 5,
+    }
+    interface AnimationStateListener2 {
+        start(entry: TrackEntry): void;
+        interrupt(entry: TrackEntry): void;
+        end(entry: TrackEntry): void;
+        dispose(entry: TrackEntry): void;
+        complete(entry: TrackEntry): void;
+        event(entry: TrackEntry, event: Event): void;
+    }
+    abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+        start(entry: TrackEntry): void;
+        interrupt(entry: TrackEntry): void;
+        end(entry: TrackEntry): void;
+        dispose(entry: TrackEntry): void;
+        complete(entry: TrackEntry): void;
+        event(entry: TrackEntry, event: Event): void;
+    }
 }
 declare module spine {
-	class AnimationStateData {
-		skeletonData: SkeletonData;
-		animationToMixTime: Map<number>;
-		defaultMix: number;
-		constructor(skeletonData: SkeletonData);
-		setMix(fromName: string, toName: string, duration: number): void;
-		setMixWith(from: Animation, to: Animation, duration: number): void;
-		getMix(from: Animation, to: Animation): number;
-	}
+    class AnimationStateData {
+        skeletonData: SkeletonData;
+        animationToMixTime: Map<number>;
+        defaultMix: number;
+        constructor(skeletonData: SkeletonData);
+        setMix(fromName: string, toName: string, duration: number): void;
+        setMixWith(from: Animation, to: Animation, duration: number): void;
+        getMix(from: Animation, to: Animation): number;
+    }
 }
 declare module spine {
-	class AssetManager implements Disposable {
-		private pathPrefix;
-		private textureLoader;
-		private assets;
-		private errors;
-		private toLoad;
-		private loaded;
-		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-		private static downloadText;
-		private static downloadBinary;
-		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
-		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-		loadTextureAtlas(path: string, success?: (path: string, atlas: TextureAtlas) => void, error?: (path: string, error: string) => void): void;
-		get(path: string): any;
-		remove(path: string): void;
-		removeAll(): void;
-		isLoadingComplete(): boolean;
-		getToLoad(): number;
-		getLoaded(): number;
-		dispose(): void;
-		hasErrors(): boolean;
-		getErrors(): Map<string>;
-	}
+    class AssetManager implements Disposable {
+        private pathPrefix;
+        private textureLoader;
+        private assets;
+        private errors;
+        private toLoad;
+        private loaded;
+        constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
+        private static downloadText(url, success, error);
+        private static downloadBinary(url, success, error);
+        loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
+        loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+        loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+        loadTextureAtlas(path: string, success?: (path: string, atlas: TextureAtlas) => void, error?: (path: string, error: string) => void): void;
+        get(path: string): any;
+        remove(path: string): void;
+        removeAll(): void;
+        isLoadingComplete(): boolean;
+        getToLoad(): number;
+        getLoaded(): number;
+        dispose(): void;
+        hasErrors(): boolean;
+        getErrors(): Map<string>;
+    }
 }
 declare module spine {
-	class AtlasAttachmentLoader implements AttachmentLoader {
-		atlas: TextureAtlas;
-		constructor(atlas: TextureAtlas);
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
+    class AtlasAttachmentLoader implements AttachmentLoader {
+        atlas: TextureAtlas;
+        constructor(atlas: TextureAtlas);
+        newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+        newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+        newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+        newPathAttachment(skin: Skin, name: string): PathAttachment;
+        newPointAttachment(skin: Skin, name: string): PointAttachment;
+        newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+    }
 }
 declare module spine {
-	enum BlendMode {
-		Normal = 0,
-		Additive = 1,
-		Multiply = 2,
-		Screen = 3
-	}
+    enum BlendMode {
+        Normal = 0,
+        Additive = 1,
+        Multiply = 2,
+        Screen = 3,
+    }
 }
 declare module spine {
-	class Bone implements Updatable {
-		data: BoneData;
-		skeleton: Skeleton;
-		parent: Bone;
-		children: Bone[];
-		x: number;
-		y: number;
-		rotation: number;
-		scaleX: number;
-		scaleY: number;
-		shearX: number;
-		shearY: number;
-		ax: number;
-		ay: number;
-		arotation: number;
-		ascaleX: number;
-		ascaleY: number;
-		ashearX: number;
-		ashearY: number;
-		appliedValid: boolean;
-		a: number;
-		b: number;
-		worldX: number;
-		c: number;
-		d: number;
-		worldY: number;
-		sorted: boolean;
-		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
-		update(): void;
-		updateWorldTransform(): void;
-		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
-		setToSetupPose(): void;
-		getWorldRotationX(): number;
-		getWorldRotationY(): number;
-		getWorldScaleX(): number;
-		getWorldScaleY(): number;
-		updateAppliedTransform(): void;
-		worldToLocal(world: Vector2): Vector2;
-		localToWorld(local: Vector2): Vector2;
-		worldToLocalRotation(worldRotation: number): number;
-		localToWorldRotation(localRotation: number): number;
-		rotateWorld(degrees: number): void;
-	}
+    class Bone implements Updatable {
+        data: BoneData;
+        skeleton: Skeleton;
+        parent: Bone;
+        children: Bone[];
+        x: number;
+        y: number;
+        rotation: number;
+        scaleX: number;
+        scaleY: number;
+        shearX: number;
+        shearY: number;
+        ax: number;
+        ay: number;
+        arotation: number;
+        ascaleX: number;
+        ascaleY: number;
+        ashearX: number;
+        ashearY: number;
+        appliedValid: boolean;
+        a: number;
+        b: number;
+        worldX: number;
+        c: number;
+        d: number;
+        worldY: number;
+        sorted: boolean;
+        constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+        update(): void;
+        updateWorldTransform(): void;
+        updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
+        setToSetupPose(): void;
+        getWorldRotationX(): number;
+        getWorldRotationY(): number;
+        getWorldScaleX(): number;
+        getWorldScaleY(): number;
+        updateAppliedTransform(): void;
+        worldToLocal(world: Vector2): Vector2;
+        localToWorld(local: Vector2): Vector2;
+        worldToLocalRotation(worldRotation: number): number;
+        localToWorldRotation(localRotation: number): number;
+        rotateWorld(degrees: number): void;
+    }
 }
 declare module spine {
-	class BoneData {
-		index: number;
-		name: string;
-		parent: BoneData;
-		length: number;
-		x: number;
-		y: number;
-		rotation: number;
-		scaleX: number;
-		scaleY: number;
-		shearX: number;
-		shearY: number;
-		transformMode: TransformMode;
-		constructor(index: number, name: string, parent: BoneData);
-	}
-	enum TransformMode {
-		Normal = 0,
-		OnlyTranslation = 1,
-		NoRotationOrReflection = 2,
-		NoScale = 3,
-		NoScaleOrReflection = 4
-	}
+    class BoneData {
+        index: number;
+        name: string;
+        parent: BoneData;
+        length: number;
+        x: number;
+        y: number;
+        rotation: number;
+        scaleX: number;
+        scaleY: number;
+        shearX: number;
+        shearY: number;
+        transformMode: TransformMode;
+        constructor(index: number, name: string, parent: BoneData);
+    }
+    enum TransformMode {
+        Normal = 0,
+        OnlyTranslation = 1,
+        NoRotationOrReflection = 2,
+        NoScale = 3,
+        NoScaleOrReflection = 4,
+    }
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
-	}
+    interface Constraint extends Updatable {
+        getOrder(): number;
+    }
 }
 declare module spine {
-	class Event {
-		data: EventData;
-		intValue: number;
-		floatValue: number;
-		stringValue: string;
-		time: number;
-		constructor(time: number, data: EventData);
-	}
+    class Event {
+        data: EventData;
+        intValue: number;
+        floatValue: number;
+        stringValue: string;
+        time: number;
+        constructor(time: number, data: EventData);
+    }
 }
 declare module spine {
-	class EventData {
-		name: string;
-		intValue: number;
-		floatValue: number;
-		stringValue: string;
-		constructor(name: string);
-	}
+    class EventData {
+        name: string;
+        intValue: number;
+        floatValue: number;
+        stringValue: string;
+        constructor(name: string);
+    }
 }
 declare module spine {
-	class IkConstraint implements Constraint {
-		data: IkConstraintData;
-		bones: Array<Bone>;
-		target: Bone;
-		bendDirection: number;
-		stretch: boolean;
-		mix: number;
-		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
-		apply(): void;
-		update(): void;
-		apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
-		apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
-	}
+    class IkConstraint implements Constraint {
+        data: IkConstraintData;
+        bones: Array<Bone>;
+        target: Bone;
+        bendDirection: number;
+        compress: boolean;
+        stretch: boolean;
+        mix: number;
+        constructor(data: IkConstraintData, skeleton: Skeleton);
+        getOrder(): number;
+        apply(): void;
+        update(): void;
+        apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
+        apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
+    }
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
-		bones: BoneData[];
-		target: BoneData;
-		bendDirection: number;
-		stretch: boolean;
-		mix: number;
-		constructor(name: string);
-	}
+    class IkConstraintData {
+        name: string;
+        order: number;
+        bones: BoneData[];
+        target: BoneData;
+        bendDirection: number;
+        compress: boolean;
+        stretch: boolean;
+        uniform: boolean;
+        mix: number;
+        constructor(name: string);
+    }
 }
 declare module spine {
-	class PathConstraint implements Constraint {
-		static NONE: number;
-		static BEFORE: number;
-		static AFTER: number;
-		static epsilon: number;
-		data: PathConstraintData;
-		bones: Array<Bone>;
-		target: Slot;
-		position: number;
-		spacing: number;
-		rotateMix: number;
-		translateMix: number;
-		spaces: number[];
-		positions: number[];
-		world: number[];
-		curves: number[];
-		lengths: number[];
-		segments: number[];
-		constructor(data: PathConstraintData, skeleton: Skeleton);
-		apply(): void;
-		update(): void;
-		computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[];
-		addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
-		addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
-		addCurvePosition(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, out: Array<number>, o: number, tangents: boolean): void;
-		getOrder(): number;
-	}
+    class PathConstraint implements Constraint {
+        static NONE: number;
+        static BEFORE: number;
+        static AFTER: number;
+        static epsilon: number;
+        data: PathConstraintData;
+        bones: Array<Bone>;
+        target: Slot;
+        position: number;
+        spacing: number;
+        rotateMix: number;
+        translateMix: number;
+        spaces: number[];
+        positions: number[];
+        world: number[];
+        curves: number[];
+        lengths: number[];
+        segments: number[];
+        constructor(data: PathConstraintData, skeleton: Skeleton);
+        apply(): void;
+        update(): void;
+        computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[];
+        addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
+        addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
+        addCurvePosition(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, out: Array<number>, o: number, tangents: boolean): void;
+        getOrder(): number;
+    }
 }
 declare module spine {
-	class PathConstraintData {
-		name: string;
-		order: number;
-		bones: BoneData[];
-		target: SlotData;
-		positionMode: PositionMode;
-		spacingMode: SpacingMode;
-		rotateMode: RotateMode;
-		offsetRotation: number;
-		position: number;
-		spacing: number;
-		rotateMix: number;
-		translateMix: number;
-		constructor(name: string);
-	}
-	enum PositionMode {
-		Fixed = 0,
-		Percent = 1
-	}
-	enum SpacingMode {
-		Length = 0,
-		Fixed = 1,
-		Percent = 2
-	}
-	enum RotateMode {
-		Tangent = 0,
-		Chain = 1,
-		ChainScale = 2
-	}
+    class PathConstraintData {
+        name: string;
+        order: number;
+        bones: BoneData[];
+        target: SlotData;
+        positionMode: PositionMode;
+        spacingMode: SpacingMode;
+        rotateMode: RotateMode;
+        offsetRotation: number;
+        position: number;
+        spacing: number;
+        rotateMix: number;
+        translateMix: number;
+        constructor(name: string);
+    }
+    enum PositionMode {
+        Fixed = 0,
+        Percent = 1,
+    }
+    enum SpacingMode {
+        Length = 0,
+        Fixed = 1,
+        Percent = 2,
+    }
+    enum RotateMode {
+        Tangent = 0,
+        Chain = 1,
+        ChainScale = 2,
+    }
 }
 declare module spine {
-	class SharedAssetManager implements Disposable {
-		private pathPrefix;
-		private clientAssets;
-		private queuedAssets;
-		private rawAssets;
-		private errors;
-		constructor(pathPrefix?: string);
-		private queueAsset;
-		loadText(clientId: string, path: string): void;
-		loadJson(clientId: string, path: string): void;
-		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
-		get(clientId: string, path: string): any;
-		private updateClientAssets;
-		isLoadingComplete(clientId: string): boolean;
-		dispose(): void;
-		hasErrors(): boolean;
-		getErrors(): Map<string>;
-	}
+    class SharedAssetManager implements Disposable {
+        private pathPrefix;
+        private clientAssets;
+        private queuedAssets;
+        private rawAssets;
+        private errors;
+        constructor(pathPrefix?: string);
+        private queueAsset(clientId, textureLoader, path);
+        loadText(clientId: string, path: string): void;
+        loadJson(clientId: string, path: string): void;
+        loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
+        get(clientId: string, path: string): any;
+        private updateClientAssets(clientAssets);
+        isLoadingComplete(clientId: string): boolean;
+        dispose(): void;
+        hasErrors(): boolean;
+        getErrors(): Map<string>;
+    }
 }
 declare module spine {
-	class Skeleton {
-		data: SkeletonData;
-		bones: Array<Bone>;
-		slots: Array<Slot>;
-		drawOrder: Array<Slot>;
-		ikConstraints: Array<IkConstraint>;
-		transformConstraints: Array<TransformConstraint>;
-		pathConstraints: Array<PathConstraint>;
-		_updateCache: Updatable[];
-		updateCacheReset: Updatable[];
-		skin: Skin;
-		color: Color;
-		time: number;
-		scaleX: number;
-		scaleY: number;
-		x: number;
-		y: number;
-		constructor(data: SkeletonData);
-		updateCache(): void;
-		sortIkConstraint(constraint: IkConstraint): void;
-		sortPathConstraint(constraint: PathConstraint): void;
-		sortTransformConstraint(constraint: TransformConstraint): void;
-		sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone): void;
-		sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone): void;
-		sortBone(bone: Bone): void;
-		sortReset(bones: Array<Bone>): void;
-		updateWorldTransform(): void;
-		setToSetupPose(): void;
-		setBonesToSetupPose(): void;
-		setSlotsToSetupPose(): void;
-		getRootBone(): Bone;
-		findBone(boneName: string): Bone;
-		findBoneIndex(boneName: string): number;
-		findSlot(slotName: string): Slot;
-		findSlotIndex(slotName: string): number;
-		setSkinByName(skinName: string): void;
-		setSkin(newSkin: Skin): void;
-		getAttachmentByName(slotName: string, attachmentName: string): Attachment;
-		getAttachment(slotIndex: number, attachmentName: string): Attachment;
-		setAttachment(slotName: string, attachmentName: string): void;
-		findIkConstraint(constraintName: string): IkConstraint;
-		findTransformConstraint(constraintName: string): TransformConstraint;
-		findPathConstraint(constraintName: string): PathConstraint;
-		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
-		update(delta: number): void;
-	}
+    class Skeleton {
+        data: SkeletonData;
+        bones: Array<Bone>;
+        slots: Array<Slot>;
+        drawOrder: Array<Slot>;
+        ikConstraints: Array<IkConstraint>;
+        transformConstraints: Array<TransformConstraint>;
+        pathConstraints: Array<PathConstraint>;
+        _updateCache: Updatable[];
+        updateCacheReset: Updatable[];
+        skin: Skin;
+        color: Color;
+        time: number;
+        scaleX: number;
+        scaleY: number;
+        x: number;
+        y: number;
+        constructor(data: SkeletonData);
+        updateCache(): void;
+        sortIkConstraint(constraint: IkConstraint): void;
+        sortPathConstraint(constraint: PathConstraint): void;
+        sortTransformConstraint(constraint: TransformConstraint): void;
+        sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone): void;
+        sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone): void;
+        sortBone(bone: Bone): void;
+        sortReset(bones: Array<Bone>): void;
+        updateWorldTransform(): void;
+        setToSetupPose(): void;
+        setBonesToSetupPose(): void;
+        setSlotsToSetupPose(): void;
+        getRootBone(): Bone;
+        findBone(boneName: string): Bone;
+        findBoneIndex(boneName: string): number;
+        findSlot(slotName: string): Slot;
+        findSlotIndex(slotName: string): number;
+        setSkinByName(skinName: string): void;
+        setSkin(newSkin: Skin): void;
+        getAttachmentByName(slotName: string, attachmentName: string): Attachment;
+        getAttachment(slotIndex: number, attachmentName: string): Attachment;
+        setAttachment(slotName: string, attachmentName: string): void;
+        findIkConstraint(constraintName: string): IkConstraint;
+        findTransformConstraint(constraintName: string): TransformConstraint;
+        findPathConstraint(constraintName: string): PathConstraint;
+        getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+        update(delta: number): void;
+    }
 }
 declare module spine {
-	class SkeletonBounds {
-		minX: number;
-		minY: number;
-		maxX: number;
-		maxY: number;
-		boundingBoxes: BoundingBoxAttachment[];
-		polygons: ArrayLike<number>[];
-		private polygonPool;
-		update(skeleton: Skeleton, updateAabb: boolean): void;
-		aabbCompute(): void;
-		aabbContainsPoint(x: number, y: number): boolean;
-		aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
-		aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
-		containsPoint(x: number, y: number): BoundingBoxAttachment;
-		containsPointPolygon(polygon: ArrayLike<number>, x: number, y: number): boolean;
-		intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment;
-		intersectsSegmentPolygon(polygon: ArrayLike<number>, x1: number, y1: number, x2: number, y2: number): boolean;
-		getPolygon(boundingBox: BoundingBoxAttachment): ArrayLike<number>;
-		getWidth(): number;
-		getHeight(): number;
-	}
+    class SkeletonBounds {
+        minX: number;
+        minY: number;
+        maxX: number;
+        maxY: number;
+        boundingBoxes: BoundingBoxAttachment[];
+        polygons: ArrayLike<number>[];
+        private polygonPool;
+        update(skeleton: Skeleton, updateAabb: boolean): void;
+        aabbCompute(): void;
+        aabbContainsPoint(x: number, y: number): boolean;
+        aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
+        aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
+        containsPoint(x: number, y: number): BoundingBoxAttachment;
+        containsPointPolygon(polygon: ArrayLike<number>, x: number, y: number): boolean;
+        intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment;
+        intersectsSegmentPolygon(polygon: ArrayLike<number>, x1: number, y1: number, x2: number, y2: number): boolean;
+        getPolygon(boundingBox: BoundingBoxAttachment): ArrayLike<number>;
+        getWidth(): number;
+        getHeight(): number;
+    }
 }
 declare module spine {
-	class SkeletonClipping {
-		private triangulator;
-		private clippingPolygon;
-		private clipOutput;
-		clippedVertices: number[];
-		clippedTriangles: number[];
-		private scratch;
-		private clipAttachment;
-		private clippingPolygons;
-		clipStart(slot: Slot, clip: ClippingAttachment): number;
-		clipEndWithSlot(slot: Slot): void;
-		clipEnd(): void;
-		isClipping(): boolean;
-		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
-		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
-		static makeClockwise(polygon: ArrayLike<number>): void;
-	}
+    class SkeletonClipping {
+        private triangulator;
+        private clippingPolygon;
+        private clipOutput;
+        clippedVertices: number[];
+        clippedTriangles: number[];
+        private scratch;
+        private clipAttachment;
+        private clippingPolygons;
+        clipStart(slot: Slot, clip: ClippingAttachment): number;
+        clipEndWithSlot(slot: Slot): void;
+        clipEnd(): void;
+        isClipping(): boolean;
+        clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+        clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+        static makeClockwise(polygon: ArrayLike<number>): void;
+    }
 }
 declare module spine {
-	class SkeletonData {
-		name: string;
-		bones: BoneData[];
-		slots: SlotData[];
-		skins: Skin[];
-		defaultSkin: Skin;
-		events: EventData[];
-		animations: Animation[];
-		ikConstraints: IkConstraintData[];
-		transformConstraints: TransformConstraintData[];
-		pathConstraints: PathConstraintData[];
-		width: number;
-		height: number;
-		version: string;
-		hash: string;
-		fps: number;
-		imagesPath: string;
-		findBone(boneName: string): BoneData;
-		findBoneIndex(boneName: string): number;
-		findSlot(slotName: string): SlotData;
-		findSlotIndex(slotName: string): number;
-		findSkin(skinName: string): Skin;
-		findEvent(eventDataName: string): EventData;
-		findAnimation(animationName: string): Animation;
-		findIkConstraint(constraintName: string): IkConstraintData;
-		findTransformConstraint(constraintName: string): TransformConstraintData;
-		findPathConstraint(constraintName: string): PathConstraintData;
-		findPathConstraintIndex(pathConstraintName: string): number;
-	}
+    class SkeletonData {
+        name: string;
+        bones: BoneData[];
+        slots: SlotData[];
+        skins: Skin[];
+        defaultSkin: Skin;
+        events: EventData[];
+        animations: Animation[];
+        ikConstraints: IkConstraintData[];
+        transformConstraints: TransformConstraintData[];
+        pathConstraints: PathConstraintData[];
+        width: number;
+        height: number;
+        version: string;
+        hash: string;
+        fps: number;
+        imagesPath: string;
+        findBone(boneName: string): BoneData;
+        findBoneIndex(boneName: string): number;
+        findSlot(slotName: string): SlotData;
+        findSlotIndex(slotName: string): number;
+        findSkin(skinName: string): Skin;
+        findEvent(eventDataName: string): EventData;
+        findAnimation(animationName: string): Animation;
+        findIkConstraint(constraintName: string): IkConstraintData;
+        findTransformConstraint(constraintName: string): TransformConstraintData;
+        findPathConstraint(constraintName: string): PathConstraintData;
+        findPathConstraintIndex(pathConstraintName: string): number;
+    }
 }
 declare module spine {
-	class SkeletonJson {
-		attachmentLoader: AttachmentLoader;
-		scale: number;
-		private linkedMeshes;
-		constructor(attachmentLoader: AttachmentLoader);
-		readSkeletonData(json: string | any): SkeletonData;
-		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
-		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
-		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
-		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
-		getValue(map: any, prop: string, defaultValue: any): any;
-		static blendModeFromString(str: string): BlendMode;
-		static positionModeFromString(str: string): PositionMode;
-		static spacingModeFromString(str: string): SpacingMode;
-		static rotateModeFromString(str: string): RotateMode;
-		static transformModeFromString(str: string): TransformMode;
-	}
+    class SkeletonJson {
+        attachmentLoader: AttachmentLoader;
+        scale: number;
+        private linkedMeshes;
+        constructor(attachmentLoader: AttachmentLoader);
+        readSkeletonData(json: string | any): SkeletonData;
+        readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
+        readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
+        readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
+        readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
+        getValue(map: any, prop: string, defaultValue: any): any;
+        static blendModeFromString(str: string): BlendMode;
+        static positionModeFromString(str: string): PositionMode;
+        static spacingModeFromString(str: string): SpacingMode;
+        static rotateModeFromString(str: string): RotateMode;
+        static transformModeFromString(str: string): TransformMode;
+    }
 }
 declare module spine {
-	class Skin {
-		name: string;
-		attachments: Map<Attachment>[];
-		constructor(name: string);
-		addAttachment(slotIndex: number, name: string, attachment: Attachment): void;
-		getAttachment(slotIndex: number, name: string): Attachment;
-		attachAll(skeleton: Skeleton, oldSkin: Skin): void;
-	}
+    class Skin {
+        name: string;
+        attachments: Map<Attachment>[];
+        constructor(name: string);
+        addAttachment(slotIndex: number, name: string, attachment: Attachment): void;
+        getAttachment(slotIndex: number, name: string): Attachment;
+        attachAll(skeleton: Skeleton, oldSkin: Skin): void;
+    }
 }
 declare module spine {
-	class Slot {
-		data: SlotData;
-		bone: Bone;
-		color: Color;
-		darkColor: Color;
-		private attachment;
-		private attachmentTime;
-		attachmentVertices: number[];
-		constructor(data: SlotData, bone: Bone);
-		getAttachment(): Attachment;
-		setAttachment(attachment: Attachment): void;
-		setAttachmentTime(time: number): void;
-		getAttachmentTime(): number;
-		setToSetupPose(): void;
-	}
+    class Slot {
+        data: SlotData;
+        bone: Bone;
+        color: Color;
+        darkColor: Color;
+        private attachment;
+        private attachmentTime;
+        attachmentVertices: number[];
+        constructor(data: SlotData, bone: Bone);
+        getAttachment(): Attachment;
+        setAttachment(attachment: Attachment): void;
+        setAttachmentTime(time: number): void;
+        getAttachmentTime(): number;
+        setToSetupPose(): void;
+    }
 }
 declare module spine {
-	class SlotData {
-		index: number;
-		name: string;
-		boneData: BoneData;
-		color: Color;
-		darkColor: Color;
-		attachmentName: string;
-		blendMode: BlendMode;
-		constructor(index: number, name: string, boneData: BoneData);
-	}
+    class SlotData {
+        index: number;
+        name: string;
+        boneData: BoneData;
+        color: Color;
+        darkColor: Color;
+        attachmentName: string;
+        blendMode: BlendMode;
+        constructor(index: number, name: string, boneData: BoneData);
+    }
 }
 declare module spine {
-	abstract class Texture {
-		protected _image: HTMLImageElement;
-		constructor(image: HTMLImageElement);
-		getImage(): HTMLImageElement;
-		abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		abstract dispose(): void;
-		static filterFromString(text: string): TextureFilter;
-		static wrapFromString(text: string): TextureWrap;
-	}
-	enum TextureFilter {
-		Nearest = 9728,
-		Linear = 9729,
-		MipMap = 9987,
-		MipMapNearestNearest = 9984,
-		MipMapLinearNearest = 9985,
-		MipMapNearestLinear = 9986,
-		MipMapLinearLinear = 9987
-	}
-	enum TextureWrap {
-		MirroredRepeat = 33648,
-		ClampToEdge = 33071,
-		Repeat = 10497
-	}
-	class TextureRegion {
-		renderObject: any;
-		u: number;
-		v: number;
-		u2: number;
-		v2: number;
-		width: number;
-		height: number;
-		rotate: boolean;
-		offsetX: number;
-		offsetY: number;
-		originalWidth: number;
-		originalHeight: number;
-	}
-	class FakeTexture extends spine.Texture {
-		setFilters(minFilter: spine.TextureFilter, magFilter: spine.TextureFilter): void;
-		setWraps(uWrap: spine.TextureWrap, vWrap: spine.TextureWrap): void;
-		dispose(): void;
-	}
+    abstract class Texture {
+        protected _image: HTMLImageElement;
+        constructor(image: HTMLImageElement);
+        getImage(): HTMLImageElement;
+        abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+        abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+        abstract dispose(): void;
+        static filterFromString(text: string): TextureFilter;
+        static wrapFromString(text: string): TextureWrap;
+    }
+    enum TextureFilter {
+        Nearest = 9728,
+        Linear = 9729,
+        MipMap = 9987,
+        MipMapNearestNearest = 9984,
+        MipMapLinearNearest = 9985,
+        MipMapNearestLinear = 9986,
+        MipMapLinearLinear = 9987,
+    }
+    enum TextureWrap {
+        MirroredRepeat = 33648,
+        ClampToEdge = 33071,
+        Repeat = 10497,
+    }
+    class TextureRegion {
+        renderObject: any;
+        u: number;
+        v: number;
+        u2: number;
+        v2: number;
+        width: number;
+        height: number;
+        rotate: boolean;
+        offsetX: number;
+        offsetY: number;
+        originalWidth: number;
+        originalHeight: number;
+    }
+    class FakeTexture extends spine.Texture {
+        setFilters(minFilter: spine.TextureFilter, magFilter: spine.TextureFilter): void;
+        setWraps(uWrap: spine.TextureWrap, vWrap: spine.TextureWrap): void;
+        dispose(): void;
+    }
 }
 declare module spine {
-	class TextureAtlas implements Disposable {
-		pages: TextureAtlasPage[];
-		regions: TextureAtlasRegion[];
-		constructor(atlasText: string, textureLoader: (path: string) => any);
-		private load;
-		findRegion(name: string): TextureAtlasRegion;
-		dispose(): void;
-	}
-	class TextureAtlasPage {
-		name: string;
-		minFilter: TextureFilter;
-		magFilter: TextureFilter;
-		uWrap: TextureWrap;
-		vWrap: TextureWrap;
-		texture: Texture;
-		width: number;
-		height: number;
-	}
-	class TextureAtlasRegion extends TextureRegion {
-		page: TextureAtlasPage;
-		name: string;
-		x: number;
-		y: number;
-		index: number;
-		rotate: boolean;
-		texture: Texture;
-	}
+    class TextureAtlas implements Disposable {
+        pages: TextureAtlasPage[];
+        regions: TextureAtlasRegion[];
+        constructor(atlasText: string, textureLoader: (path: string) => any);
+        private load(atlasText, textureLoader);
+        findRegion(name: string): TextureAtlasRegion;
+        dispose(): void;
+    }
+    class TextureAtlasPage {
+        name: string;
+        minFilter: TextureFilter;
+        magFilter: TextureFilter;
+        uWrap: TextureWrap;
+        vWrap: TextureWrap;
+        texture: Texture;
+        width: number;
+        height: number;
+    }
+    class TextureAtlasRegion extends TextureRegion {
+        page: TextureAtlasPage;
+        name: string;
+        x: number;
+        y: number;
+        index: number;
+        rotate: boolean;
+        texture: Texture;
+    }
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
-		data: TransformConstraintData;
-		bones: Array<Bone>;
-		target: Bone;
-		rotateMix: number;
-		translateMix: number;
-		scaleMix: number;
-		shearMix: number;
-		temp: Vector2;
-		constructor(data: TransformConstraintData, skeleton: Skeleton);
-		apply(): void;
-		update(): void;
-		applyAbsoluteWorld(): void;
-		applyRelativeWorld(): void;
-		applyAbsoluteLocal(): void;
-		applyRelativeLocal(): void;
-		getOrder(): number;
-	}
+    class TransformConstraint implements Constraint {
+        data: TransformConstraintData;
+        bones: Array<Bone>;
+        target: Bone;
+        rotateMix: number;
+        translateMix: number;
+        scaleMix: number;
+        shearMix: number;
+        temp: Vector2;
+        constructor(data: TransformConstraintData, skeleton: Skeleton);
+        apply(): void;
+        update(): void;
+        applyAbsoluteWorld(): void;
+        applyRelativeWorld(): void;
+        applyAbsoluteLocal(): void;
+        applyRelativeLocal(): void;
+        getOrder(): number;
+    }
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
-		bones: BoneData[];
-		target: BoneData;
-		rotateMix: number;
-		translateMix: number;
-		scaleMix: number;
-		shearMix: number;
-		offsetRotation: number;
-		offsetX: number;
-		offsetY: number;
-		offsetScaleX: number;
-		offsetScaleY: number;
-		offsetShearY: number;
-		relative: boolean;
-		local: boolean;
-		constructor(name: string);
-	}
+    class TransformConstraintData {
+        name: string;
+        order: number;
+        bones: BoneData[];
+        target: BoneData;
+        rotateMix: number;
+        translateMix: number;
+        scaleMix: number;
+        shearMix: number;
+        offsetRotation: number;
+        offsetX: number;
+        offsetY: number;
+        offsetScaleX: number;
+        offsetScaleY: number;
+        offsetShearY: number;
+        relative: boolean;
+        local: boolean;
+        constructor(name: string);
+    }
 }
 declare module spine {
-	class Triangulator {
-		private convexPolygons;
-		private convexPolygonsIndices;
-		private indicesArray;
-		private isConcaveArray;
-		private triangles;
-		private polygonPool;
-		private polygonIndicesPool;
-		triangulate(verticesArray: ArrayLike<number>): Array<number>;
-		decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
-		private static isConcave;
-		private static positiveArea;
-		private static winding;
-	}
+    class Triangulator {
+        private convexPolygons;
+        private convexPolygonsIndices;
+        private indicesArray;
+        private isConcaveArray;
+        private triangles;
+        private polygonPool;
+        private polygonIndicesPool;
+        triangulate(verticesArray: ArrayLike<number>): Array<number>;
+        decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>>;
+        private static isConcave(index, vertexCount, vertices, indices);
+        private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+        private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+    }
 }
 declare module spine {
-	interface Updatable {
-		update(): void;
-	}
+    interface Updatable {
+        update(): void;
+    }
 }
 declare module spine {
-	interface Map<T> {
-		[key: string]: T;
-	}
-	class IntSet {
-		array: number[];
-		add(value: number): boolean;
-		contains(value: number): boolean;
-		remove(value: number): void;
-		clear(): void;
-	}
-	interface Disposable {
-		dispose(): void;
-	}
-	interface Restorable {
-		restore(): void;
-	}
-	class Color {
-		r: number;
-		g: number;
-		b: number;
-		a: number;
-		static WHITE: Color;
-		static RED: Color;
-		static GREEN: Color;
-		static BLUE: Color;
-		static MAGENTA: Color;
-		constructor(r?: number, g?: number, b?: number, a?: number);
-		set(r: number, g: number, b: number, a: number): this;
-		setFromColor(c: Color): this;
-		setFromString(hex: string): this;
-		add(r: number, g: number, b: number, a: number): this;
-		clamp(): this;
-	}
-	class MathUtils {
-		static PI: number;
-		static PI2: number;
-		static radiansToDegrees: number;
-		static radDeg: number;
-		static degreesToRadians: number;
-		static degRad: number;
-		static clamp(value: number, min: number, max: number): number;
-		static cosDeg(degrees: number): number;
-		static sinDeg(degrees: number): number;
-		static signum(value: number): number;
-		static toInt(x: number): number;
-		static cbrt(x: number): number;
-		static randomTriangular(min: number, max: number): number;
-		static randomTriangularWith(min: number, max: number, mode: number): number;
-	}
-	abstract class Interpolation {
-		protected abstract applyInternal(a: number): number;
-		apply(start: number, end: number, a: number): number;
-	}
-	class Pow extends Interpolation {
-		protected power: number;
-		constructor(power: number);
-		applyInternal(a: number): number;
-	}
-	class PowOut extends Pow {
-		constructor(power: number);
-		applyInternal(a: number): number;
-	}
-	class Utils {
-		static SUPPORTS_TYPED_ARRAYS: boolean;
-		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
-		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
-		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
-		static newArray<T>(size: number, defaultValue: T): Array<T>;
-		static newFloatArray(size: number): ArrayLike<number>;
-		static newShortArray(size: number): ArrayLike<number>;
-		static toFloatArray(array: Array<number>): number[] | Float32Array;
-		static toSinglePrecision(value: number): number;
-		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
-	}
-	class DebugUtils {
-		static logBones(skeleton: Skeleton): void;
-	}
-	class Pool<T> {
-		private items;
-		private instantiator;
-		constructor(instantiator: () => T);
-		obtain(): T;
-		free(item: T): void;
-		freeAll(items: ArrayLike<T>): void;
-		clear(): void;
-	}
-	class Vector2 {
-		x: number;
-		y: number;
-		constructor(x?: number, y?: number);
-		set(x: number, y: number): Vector2;
-		length(): number;
-		normalize(): this;
-	}
-	class TimeKeeper {
-		maxDelta: number;
-		framesPerSecond: number;
-		delta: number;
-		totalTime: number;
-		private lastTime;
-		private frameCount;
-		private frameTime;
-		update(): void;
-	}
-	interface ArrayLike<T> {
-		length: number;
-		[n: number]: T;
-	}
-	class WindowedMean {
-		values: Array<number>;
-		addedValues: number;
-		lastValue: number;
-		mean: number;
-		dirty: boolean;
-		constructor(windowSize?: number);
-		hasEnoughData(): boolean;
-		addValue(value: number): void;
-		getMean(): number;
-	}
+    interface Map<T> {
+        [key: string]: T;
+    }
+    class IntSet {
+        array: number[];
+        add(value: number): boolean;
+        contains(value: number): boolean;
+        remove(value: number): void;
+        clear(): void;
+    }
+    interface Disposable {
+        dispose(): void;
+    }
+    interface Restorable {
+        restore(): void;
+    }
+    class Color {
+        r: number;
+        g: number;
+        b: number;
+        a: number;
+        static WHITE: Color;
+        static RED: Color;
+        static GREEN: Color;
+        static BLUE: Color;
+        static MAGENTA: Color;
+        constructor(r?: number, g?: number, b?: number, a?: number);
+        set(r: number, g: number, b: number, a: number): this;
+        setFromColor(c: Color): this;
+        setFromString(hex: string): this;
+        add(r: number, g: number, b: number, a: number): this;
+        clamp(): this;
+    }
+    class MathUtils {
+        static PI: number;
+        static PI2: number;
+        static radiansToDegrees: number;
+        static radDeg: number;
+        static degreesToRadians: number;
+        static degRad: number;
+        static clamp(value: number, min: number, max: number): number;
+        static cosDeg(degrees: number): number;
+        static sinDeg(degrees: number): number;
+        static signum(value: number): number;
+        static toInt(x: number): number;
+        static cbrt(x: number): number;
+        static randomTriangular(min: number, max: number): number;
+        static randomTriangularWith(min: number, max: number, mode: number): number;
+    }
+    abstract class Interpolation {
+        protected abstract applyInternal(a: number): number;
+        apply(start: number, end: number, a: number): number;
+    }
+    class Pow extends Interpolation {
+        protected power: number;
+        constructor(power: number);
+        applyInternal(a: number): number;
+    }
+    class PowOut extends Pow {
+        constructor(power: number);
+        applyInternal(a: number): number;
+    }
+    class Utils {
+        static SUPPORTS_TYPED_ARRAYS: boolean;
+        static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
+        static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+        static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
+        static newArray<T>(size: number, defaultValue: T): Array<T>;
+        static newFloatArray(size: number): ArrayLike<number>;
+        static newShortArray(size: number): ArrayLike<number>;
+        static toFloatArray(array: Array<number>): number[] | Float32Array;
+        static toSinglePrecision(value: number): number;
+        static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+    }
+    class DebugUtils {
+        static logBones(skeleton: Skeleton): void;
+    }
+    class Pool<T> {
+        private items;
+        private instantiator;
+        constructor(instantiator: () => T);
+        obtain(): T;
+        free(item: T): void;
+        freeAll(items: ArrayLike<T>): void;
+        clear(): void;
+    }
+    class Vector2 {
+        x: number;
+        y: number;
+        constructor(x?: number, y?: number);
+        set(x: number, y: number): Vector2;
+        length(): number;
+        normalize(): this;
+    }
+    class TimeKeeper {
+        maxDelta: number;
+        framesPerSecond: number;
+        delta: number;
+        totalTime: number;
+        private lastTime;
+        private frameCount;
+        private frameTime;
+        update(): void;
+    }
+    interface ArrayLike<T> {
+        length: number;
+        [n: number]: T;
+    }
+    class WindowedMean {
+        values: Array<number>;
+        addedValues: number;
+        lastValue: number;
+        mean: number;
+        dirty: boolean;
+        constructor(windowSize?: number);
+        hasEnoughData(): boolean;
+        addValue(value: number): void;
+        getMean(): number;
+    }
 }
 declare module spine {
-	interface VertexEffect {
-		begin(skeleton: Skeleton): void;
-		transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void;
-		end(): void;
-	}
+    interface VertexEffect {
+        begin(skeleton: Skeleton): void;
+        transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void;
+        end(): void;
+    }
 }
 interface Math {
-	fround(n: number): number;
+    fround(n: number): number;
 }
 declare module spine {
-	abstract class Attachment {
-		name: string;
-		constructor(name: string);
-	}
-	abstract class VertexAttachment extends Attachment {
-		private static nextID;
-		id: number;
-		bones: Array<number>;
-		vertices: ArrayLike<number>;
-		worldVerticesLength: number;
-		constructor(name: string);
-		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-	}
+    abstract class Attachment {
+        name: string;
+        constructor(name: string);
+    }
+    abstract class VertexAttachment extends Attachment {
+        private static nextID;
+        id: number;
+        bones: Array<number>;
+        vertices: ArrayLike<number>;
+        worldVerticesLength: number;
+        constructor(name: string);
+        computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+        applyDeform(sourceAttachment: VertexAttachment): boolean;
+    }
 }
 declare module spine {
-	interface AttachmentLoader {
-		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-		newPathAttachment(skin: Skin, name: string): PathAttachment;
-		newPointAttachment(skin: Skin, name: string): PointAttachment;
-		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-	}
+    interface AttachmentLoader {
+        newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+        newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+        newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+        newPathAttachment(skin: Skin, name: string): PathAttachment;
+        newPointAttachment(skin: Skin, name: string): PointAttachment;
+        newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+    }
 }
 declare module spine {
-	enum AttachmentType {
-		Region = 0,
-		BoundingBox = 1,
-		Mesh = 2,
-		LinkedMesh = 3,
-		Path = 4,
-		Point = 5
-	}
+    enum AttachmentType {
+        Region = 0,
+        BoundingBox = 1,
+        Mesh = 2,
+        LinkedMesh = 3,
+        Path = 4,
+        Point = 5,
+    }
 }
 declare module spine {
-	class BoundingBoxAttachment extends VertexAttachment {
-		color: Color;
-		constructor(name: string);
-	}
+    class BoundingBoxAttachment extends VertexAttachment {
+        color: Color;
+        constructor(name: string);
+    }
 }
 declare module spine {
-	class ClippingAttachment extends VertexAttachment {
-		endSlot: SlotData;
-		color: Color;
-		constructor(name: string);
-	}
+    class ClippingAttachment extends VertexAttachment {
+        endSlot: SlotData;
+        color: Color;
+        constructor(name: string);
+    }
 }
 declare module spine {
-	class MeshAttachment extends VertexAttachment {
-		region: TextureRegion;
-		path: string;
-		regionUVs: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		triangles: Array<number>;
-		color: Color;
-		hullLength: number;
-		private parentMesh;
-		inheritDeform: boolean;
-		tempColor: Color;
-		constructor(name: string);
-		updateUVs(): void;
-		applyDeform(sourceAttachment: VertexAttachment): boolean;
-		getParentMesh(): MeshAttachment;
-		setParentMesh(parentMesh: MeshAttachment): void;
-	}
+    class MeshAttachment extends VertexAttachment {
+        region: TextureRegion;
+        path: string;
+        regionUVs: ArrayLike<number>;
+        uvs: ArrayLike<number>;
+        triangles: Array<number>;
+        color: Color;
+        hullLength: number;
+        private parentMesh;
+        inheritDeform: boolean;
+        tempColor: Color;
+        constructor(name: string);
+        updateUVs(): void;
+        applyDeform(sourceAttachment: VertexAttachment): boolean;
+        getParentMesh(): MeshAttachment;
+        setParentMesh(parentMesh: MeshAttachment): void;
+    }
 }
 declare module spine {
-	class PathAttachment extends VertexAttachment {
-		lengths: Array<number>;
-		closed: boolean;
-		constantSpeed: boolean;
-		color: Color;
-		constructor(name: string);
-	}
+    class PathAttachment extends VertexAttachment {
+        lengths: Array<number>;
+        closed: boolean;
+        constantSpeed: boolean;
+        color: Color;
+        constructor(name: string);
+    }
 }
 declare module spine {
-	class PointAttachment extends VertexAttachment {
-		x: number;
-		y: number;
-		rotation: number;
-		color: Color;
-		constructor(name: string);
-		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-		computeWorldRotation(bone: Bone): number;
-	}
+    class PointAttachment extends VertexAttachment {
+        x: number;
+        y: number;
+        rotation: number;
+        color: Color;
+        constructor(name: string);
+        computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+        computeWorldRotation(bone: Bone): number;
+    }
 }
 declare module spine {
-	class RegionAttachment extends Attachment {
-		static OX1: number;
-		static OY1: number;
-		static OX2: number;
-		static OY2: number;
-		static OX3: number;
-		static OY3: number;
-		static OX4: number;
-		static OY4: number;
-		static X1: number;
-		static Y1: number;
-		static C1R: number;
-		static C1G: number;
-		static C1B: number;
-		static C1A: number;
-		static U1: number;
-		static V1: number;
-		static X2: number;
-		static Y2: number;
-		static C2R: number;
-		static C2G: number;
-		static C2B: number;
-		static C2A: number;
-		static U2: number;
-		static V2: number;
-		static X3: number;
-		static Y3: number;
-		static C3R: number;
-		static C3G: number;
-		static C3B: number;
-		static C3A: number;
-		static U3: number;
-		static V3: number;
-		static X4: number;
-		static Y4: number;
-		static C4R: number;
-		static C4G: number;
-		static C4B: number;
-		static C4A: number;
-		static U4: number;
-		static V4: number;
-		x: number;
-		y: number;
-		scaleX: number;
-		scaleY: number;
-		rotation: number;
-		width: number;
-		height: number;
-		color: Color;
-		path: string;
-		rendererObject: any;
-		region: TextureRegion;
-		offset: ArrayLike<number>;
-		uvs: ArrayLike<number>;
-		tempColor: Color;
-		constructor(name: string);
-		updateOffset(): void;
-		setRegion(region: TextureRegion): void;
-		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-	}
+    class RegionAttachment extends Attachment {
+        static OX1: number;
+        static OY1: number;
+        static OX2: number;
+        static OY2: number;
+        static OX3: number;
+        static OY3: number;
+        static OX4: number;
+        static OY4: number;
+        static X1: number;
+        static Y1: number;
+        static C1R: number;
+        static C1G: number;
+        static C1B: number;
+        static C1A: number;
+        static U1: number;
+        static V1: number;
+        static X2: number;
+        static Y2: number;
+        static C2R: number;
+        static C2G: number;
+        static C2B: number;
+        static C2A: number;
+        static U2: number;
+        static V2: number;
+        static X3: number;
+        static Y3: number;
+        static C3R: number;
+        static C3G: number;
+        static C3B: number;
+        static C3A: number;
+        static U3: number;
+        static V3: number;
+        static X4: number;
+        static Y4: number;
+        static C4R: number;
+        static C4G: number;
+        static C4B: number;
+        static C4A: number;
+        static U4: number;
+        static V4: number;
+        x: number;
+        y: number;
+        scaleX: number;
+        scaleY: number;
+        rotation: number;
+        width: number;
+        height: number;
+        color: Color;
+        path: string;
+        rendererObject: any;
+        region: TextureRegion;
+        offset: ArrayLike<number>;
+        uvs: ArrayLike<number>;
+        tempColor: Color;
+        constructor(name: string);
+        updateOffset(): void;
+        setRegion(region: TextureRegion): void;
+        computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+    }
 }
 declare module spine {
-	class JitterEffect implements VertexEffect {
-		jitterX: number;
-		jitterY: number;
-		constructor(jitterX: number, jitterY: number);
-		begin(skeleton: Skeleton): void;
-		transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void;
-		end(): void;
-	}
+    class JitterEffect implements VertexEffect {
+        jitterX: number;
+        jitterY: number;
+        constructor(jitterX: number, jitterY: number);
+        begin(skeleton: Skeleton): void;
+        transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void;
+        end(): void;
+    }
 }
 declare module spine {
-	class SwirlEffect implements VertexEffect {
-		static interpolation: PowOut;
-		centerX: number;
-		centerY: number;
-		radius: number;
-		angle: number;
-		private worldX;
-		private worldY;
-		constructor(radius: number);
-		begin(skeleton: Skeleton): void;
-		transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void;
-		end(): void;
-	}
+    class SwirlEffect implements VertexEffect {
+        static interpolation: PowOut;
+        centerX: number;
+        centerY: number;
+        radius: number;
+        angle: number;
+        private worldX;
+        private worldY;
+        constructor(radius: number);
+        begin(skeleton: Skeleton): void;
+        transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void;
+        end(): void;
+    }
 }
 declare module spine.webgl {
-	class AssetManager extends spine.AssetManager {
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, pathPrefix?: string);
-	}
+    class AssetManager extends spine.AssetManager {
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, pathPrefix?: string);
+    }
 }
 declare module spine.webgl {
-	class OrthoCamera {
-		position: Vector3;
-		direction: Vector3;
-		up: Vector3;
-		near: number;
-		far: number;
-		zoom: number;
-		viewportWidth: number;
-		viewportHeight: number;
-		projectionView: Matrix4;
-		inverseProjectionView: Matrix4;
-		projection: Matrix4;
-		view: Matrix4;
-		private tmp;
-		constructor(viewportWidth: number, viewportHeight: number);
-		update(): void;
-		screenToWorld(screenCoords: Vector3, screenWidth: number, screenHeight: number): Vector3;
-		setViewport(viewportWidth: number, viewportHeight: number): void;
-	}
+    class OrthoCamera {
+        position: Vector3;
+        direction: Vector3;
+        up: Vector3;
+        near: number;
+        far: number;
+        zoom: number;
+        viewportWidth: number;
+        viewportHeight: number;
+        projectionView: Matrix4;
+        inverseProjectionView: Matrix4;
+        projection: Matrix4;
+        view: Matrix4;
+        private tmp;
+        constructor(viewportWidth: number, viewportHeight: number);
+        update(): void;
+        screenToWorld(screenCoords: Vector3, screenWidth: number, screenHeight: number): Vector3;
+        setViewport(viewportWidth: number, viewportHeight: number): void;
+    }
 }
 declare module spine.webgl {
-	class GLTexture extends Texture implements Disposable, Restorable {
-		private context;
-		private texture;
-		private boundUnit;
-		private useMipMaps;
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement, useMipMaps?: boolean);
-		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-		update(useMipMaps: boolean): void;
-		restore(): void;
-		bind(unit?: number): void;
-		unbind(): void;
-		dispose(): void;
-	}
+    class GLTexture extends Texture implements Disposable, Restorable {
+        private context;
+        private texture;
+        private boundUnit;
+        private useMipMaps;
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement, useMipMaps?: boolean);
+        setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+        setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+        update(useMipMaps: boolean): void;
+        restore(): void;
+        bind(unit?: number): void;
+        unbind(): void;
+        dispose(): void;
+    }
 }
 declare module spine.webgl {
-	class Input {
-		element: HTMLElement;
-		lastX: number;
-		lastY: number;
-		buttonDown: boolean;
-		currTouch: Touch;
-		touchesPool: Pool<Touch>;
-		private listeners;
-		constructor(element: HTMLElement);
-		private setupCallbacks;
-		addListener(listener: InputListener): void;
-		removeListener(listener: InputListener): void;
-	}
-	class Touch {
-		identifier: number;
-		x: number;
-		y: number;
-		constructor(identifier: number, x: number, y: number);
-	}
-	interface InputListener {
-		down(x: number, y: number): void;
-		up(x: number, y: number): void;
-		moved(x: number, y: number): void;
-		dragged(x: number, y: number): void;
-	}
+    class Input {
+        element: HTMLElement;
+        lastX: number;
+        lastY: number;
+        buttonDown: boolean;
+        currTouch: Touch;
+        touchesPool: Pool<Touch>;
+        private listeners;
+        constructor(element: HTMLElement);
+        private setupCallbacks(element);
+        addListener(listener: InputListener): void;
+        removeListener(listener: InputListener): void;
+    }
+    class Touch {
+        identifier: number;
+        x: number;
+        y: number;
+        constructor(identifier: number, x: number, y: number);
+    }
+    interface InputListener {
+        down(x: number, y: number): void;
+        up(x: number, y: number): void;
+        moved(x: number, y: number): void;
+        dragged(x: number, y: number): void;
+    }
 }
 declare module spine.webgl {
-	class LoadingScreen {
-		static FADE_SECONDS: number;
-		private static loaded;
-		private static spinnerImg;
-		private static logoImg;
-		private renderer;
-		private logo;
-		private spinner;
-		private angle;
-		private fadeOut;
-		private timeKeeper;
-		backgroundColor: Color;
-		private tempColor;
-		private firstDraw;
-		private static SPINNER_DATA;
-		private static SPINE_LOGO_DATA;
-		constructor(renderer: SceneRenderer);
-		draw(complete?: boolean): void;
-	}
+    class LoadingScreen {
+        static FADE_SECONDS: number;
+        private static loaded;
+        private static spinnerImg;
+        private static logoImg;
+        private renderer;
+        private logo;
+        private spinner;
+        private angle;
+        private fadeOut;
+        private timeKeeper;
+        backgroundColor: Color;
+        private tempColor;
+        private firstDraw;
+        private static SPINNER_DATA;
+        private static SPINE_LOGO_DATA;
+        constructor(renderer: SceneRenderer);
+        draw(complete?: boolean): void;
+    }
 }
 declare module spine.webgl {
-	const M00 = 0;
-	const M01 = 4;
-	const M02 = 8;
-	const M03 = 12;
-	const M10 = 1;
-	const M11 = 5;
-	const M12 = 9;
-	const M13 = 13;
-	const M20 = 2;
-	const M21 = 6;
-	const M22 = 10;
-	const M23 = 14;
-	const M30 = 3;
-	const M31 = 7;
-	const M32 = 11;
-	const M33 = 15;
-	class Matrix4 {
-		temp: Float32Array;
-		values: Float32Array;
-		private static xAxis;
-		private static yAxis;
-		private static zAxis;
-		private static tmpMatrix;
-		constructor();
-		set(values: ArrayLike<number>): Matrix4;
-		transpose(): Matrix4;
-		identity(): Matrix4;
-		invert(): Matrix4;
-		determinant(): number;
-		translate(x: number, y: number, z: number): Matrix4;
-		copy(): Matrix4;
-		projection(near: number, far: number, fovy: number, aspectRatio: number): Matrix4;
-		ortho2d(x: number, y: number, width: number, height: number): Matrix4;
-		ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4;
-		multiply(matrix: Matrix4): Matrix4;
-		multiplyLeft(matrix: Matrix4): Matrix4;
-		lookAt(position: Vector3, direction: Vector3, up: Vector3): this;
-		static initTemps(): void;
-	}
+    const M00 = 0;
+    const M01 = 4;
+    const M02 = 8;
+    const M03 = 12;
+    const M10 = 1;
+    const M11 = 5;
+    const M12 = 9;
+    const M13 = 13;
+    const M20 = 2;
+    const M21 = 6;
+    const M22 = 10;
+    const M23 = 14;
+    const M30 = 3;
+    const M31 = 7;
+    const M32 = 11;
+    const M33 = 15;
+    class Matrix4 {
+        temp: Float32Array;
+        values: Float32Array;
+        private static xAxis;
+        private static yAxis;
+        private static zAxis;
+        private static tmpMatrix;
+        constructor();
+        set(values: ArrayLike<number>): Matrix4;
+        transpose(): Matrix4;
+        identity(): Matrix4;
+        invert(): Matrix4;
+        determinant(): number;
+        translate(x: number, y: number, z: number): Matrix4;
+        copy(): Matrix4;
+        projection(near: number, far: number, fovy: number, aspectRatio: number): Matrix4;
+        ortho2d(x: number, y: number, width: number, height: number): Matrix4;
+        ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4;
+        multiply(matrix: Matrix4): Matrix4;
+        multiplyLeft(matrix: Matrix4): Matrix4;
+        lookAt(position: Vector3, direction: Vector3, up: Vector3): this;
+        static initTemps(): void;
+    }
 }
 declare module spine.webgl {
-	class Mesh implements Disposable, Restorable {
-		private attributes;
-		private context;
-		private vertices;
-		private verticesBuffer;
-		private verticesLength;
-		private dirtyVertices;
-		private indices;
-		private indicesBuffer;
-		private indicesLength;
-		private dirtyIndices;
-		private elementsPerVertex;
-		getAttributes(): VertexAttribute[];
-		maxVertices(): number;
-		numVertices(): number;
-		setVerticesLength(length: number): void;
-		getVertices(): Float32Array;
-		maxIndices(): number;
-		numIndices(): number;
-		setIndicesLength(length: number): void;
-		getIndices(): Uint16Array;
-		getVertexSizeInFloats(): number;
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
-		setVertices(vertices: Array<number>): void;
-		setIndices(indices: Array<number>): void;
-		draw(shader: Shader, primitiveType: number): void;
-		drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
-		bind(shader: Shader): void;
-		unbind(shader: Shader): void;
-		private update;
-		restore(): void;
-		dispose(): void;
-	}
-	class VertexAttribute {
-		name: string;
-		type: VertexAttributeType;
-		numElements: number;
-		constructor(name: string, type: VertexAttributeType, numElements: number);
-	}
-	class Position2Attribute extends VertexAttribute {
-		constructor();
-	}
-	class Position3Attribute extends VertexAttribute {
-		constructor();
-	}
-	class TexCoordAttribute extends VertexAttribute {
-		constructor(unit?: number);
-	}
-	class ColorAttribute extends VertexAttribute {
-		constructor();
-	}
-	class Color2Attribute extends VertexAttribute {
-		constructor();
-	}
-	enum VertexAttributeType {
-		Float = 0
-	}
+    class Mesh implements Disposable, Restorable {
+        private attributes;
+        private context;
+        private vertices;
+        private verticesBuffer;
+        private verticesLength;
+        private dirtyVertices;
+        private indices;
+        private indicesBuffer;
+        private indicesLength;
+        private dirtyIndices;
+        private elementsPerVertex;
+        getAttributes(): VertexAttribute[];
+        maxVertices(): number;
+        numVertices(): number;
+        setVerticesLength(length: number): void;
+        getVertices(): Float32Array;
+        maxIndices(): number;
+        numIndices(): number;
+        setIndicesLength(length: number): void;
+        getIndices(): Uint16Array;
+        getVertexSizeInFloats(): number;
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
+        setVertices(vertices: Array<number>): void;
+        setIndices(indices: Array<number>): void;
+        draw(shader: Shader, primitiveType: number): void;
+        drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
+        bind(shader: Shader): void;
+        unbind(shader: Shader): void;
+        private update();
+        restore(): void;
+        dispose(): void;
+    }
+    class VertexAttribute {
+        name: string;
+        type: VertexAttributeType;
+        numElements: number;
+        constructor(name: string, type: VertexAttributeType, numElements: number);
+    }
+    class Position2Attribute extends VertexAttribute {
+        constructor();
+    }
+    class Position3Attribute extends VertexAttribute {
+        constructor();
+    }
+    class TexCoordAttribute extends VertexAttribute {
+        constructor(unit?: number);
+    }
+    class ColorAttribute extends VertexAttribute {
+        constructor();
+    }
+    class Color2Attribute extends VertexAttribute {
+        constructor();
+    }
+    enum VertexAttributeType {
+        Float = 0,
+    }
 }
 declare module spine.webgl {
-	class PolygonBatcher implements Disposable {
-		private context;
-		private drawCalls;
-		private isDrawing;
-		private mesh;
-		private shader;
-		private lastTexture;
-		private verticesLength;
-		private indicesLength;
-		private srcBlend;
-		private dstBlend;
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
-		begin(shader: Shader): void;
-		setBlendMode(srcBlend: number, dstBlend: number): void;
-		draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
-		private flush;
-		end(): void;
-		getDrawCalls(): number;
-		dispose(): void;
-	}
+    class PolygonBatcher implements Disposable {
+        private context;
+        private drawCalls;
+        private isDrawing;
+        private mesh;
+        private shader;
+        private lastTexture;
+        private verticesLength;
+        private indicesLength;
+        private srcBlend;
+        private dstBlend;
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
+        begin(shader: Shader): void;
+        setBlendMode(srcBlend: number, dstBlend: number): void;
+        draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
+        private flush();
+        end(): void;
+        getDrawCalls(): number;
+        dispose(): void;
+    }
 }
 declare module spine.webgl {
-	class SceneRenderer implements Disposable {
-		context: ManagedWebGLRenderingContext;
-		canvas: HTMLCanvasElement;
-		camera: OrthoCamera;
-		batcher: PolygonBatcher;
-		private twoColorTint;
-		private batcherShader;
-		private shapes;
-		private shapesShader;
-		private activeRenderer;
-		skeletonRenderer: SkeletonRenderer;
-		skeletonDebugRenderer: SkeletonDebugRenderer;
-		private QUAD;
-		private QUAD_TRIANGLES;
-		private WHITE;
-		constructor(canvas: HTMLCanvasElement, context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint?: boolean);
-		begin(): void;
-		drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean, slotRangeStart?: number, slotRangeEnd?: number): void;
-		drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
-		drawTexture(texture: GLTexture, x: number, y: number, width: number, height: number, color?: Color): void;
-		drawTextureUV(texture: GLTexture, x: number, y: number, width: number, height: number, u: number, v: number, u2: number, v2: number, color?: Color): void;
-		drawTextureRotated(texture: GLTexture, x: number, y: number, width: number, height: number, pivotX: number, pivotY: number, angle: number, color?: Color, premultipliedAlpha?: boolean): void;
-		drawRegion(region: TextureAtlasRegion, x: number, y: number, width: number, height: number, color?: Color, premultipliedAlpha?: boolean): void;
-		line(x: number, y: number, x2: number, y2: number, color?: Color, color2?: Color): void;
-		triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
-		quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
-		rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
-		rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
-		polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
-		circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
-		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-		end(): void;
-		resize(resizeMode: ResizeMode): void;
-		private enableRenderer;
-		dispose(): void;
-	}
-	enum ResizeMode {
-		Stretch = 0,
-		Expand = 1,
-		Fit = 2
-	}
+    class SceneRenderer implements Disposable {
+        context: ManagedWebGLRenderingContext;
+        canvas: HTMLCanvasElement;
+        camera: OrthoCamera;
+        batcher: PolygonBatcher;
+        private twoColorTint;
+        private batcherShader;
+        private shapes;
+        private shapesShader;
+        private activeRenderer;
+        skeletonRenderer: SkeletonRenderer;
+        skeletonDebugRenderer: SkeletonDebugRenderer;
+        private QUAD;
+        private QUAD_TRIANGLES;
+        private WHITE;
+        constructor(canvas: HTMLCanvasElement, context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint?: boolean);
+        begin(): void;
+        drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean, slotRangeStart?: number, slotRangeEnd?: number): void;
+        drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
+        drawTexture(texture: GLTexture, x: number, y: number, width: number, height: number, color?: Color): void;
+        drawTextureUV(texture: GLTexture, x: number, y: number, width: number, height: number, u: number, v: number, u2: number, v2: number, color?: Color): void;
+        drawTextureRotated(texture: GLTexture, x: number, y: number, width: number, height: number, pivotX: number, pivotY: number, angle: number, color?: Color, premultipliedAlpha?: boolean): void;
+        drawRegion(region: TextureAtlasRegion, x: number, y: number, width: number, height: number, color?: Color, premultipliedAlpha?: boolean): void;
+        line(x: number, y: number, x2: number, y2: number, color?: Color, color2?: Color): void;
+        triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
+        quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
+        rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
+        rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
+        polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
+        circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
+        curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
+        end(): void;
+        resize(resizeMode: ResizeMode): void;
+        private enableRenderer(renderer);
+        dispose(): void;
+    }
+    enum ResizeMode {
+        Stretch = 0,
+        Expand = 1,
+        Fit = 2,
+    }
 }
 declare module spine.webgl {
-	class Shader implements Disposable, Restorable {
-		private vertexShader;
-		private fragmentShader;
-		static MVP_MATRIX: string;
-		static POSITION: string;
-		static COLOR: string;
-		static COLOR2: string;
-		static TEXCOORDS: string;
-		static SAMPLER: string;
-		private context;
-		private vs;
-		private vsSource;
-		private fs;
-		private fsSource;
-		private program;
-		private tmp2x2;
-		private tmp3x3;
-		private tmp4x4;
-		getProgram(): WebGLProgram;
-		getVertexShader(): string;
-		getFragmentShader(): string;
-		getVertexShaderSource(): string;
-		getFragmentSource(): string;
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string);
-		private compile;
-		private compileShader;
-		private compileProgram;
-		restore(): void;
-		bind(): void;
-		unbind(): void;
-		setUniformi(uniform: string, value: number): void;
-		setUniformf(uniform: string, value: number): void;
-		setUniform2f(uniform: string, value: number, value2: number): void;
-		setUniform3f(uniform: string, value: number, value2: number, value3: number): void;
-		setUniform4f(uniform: string, value: number, value2: number, value3: number, value4: number): void;
-		setUniform2x2f(uniform: string, value: ArrayLike<number>): void;
-		setUniform3x3f(uniform: string, value: ArrayLike<number>): void;
-		setUniform4x4f(uniform: string, value: ArrayLike<number>): void;
-		getUniformLocation(uniform: string): WebGLUniformLocation;
-		getAttributeLocation(attribute: string): number;
-		dispose(): void;
-		static newColoredTextured(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader;
-		static newTwoColoredTextured(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader;
-		static newColored(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader;
-	}
+    class Shader implements Disposable, Restorable {
+        private vertexShader;
+        private fragmentShader;
+        static MVP_MATRIX: string;
+        static POSITION: string;
+        static COLOR: string;
+        static COLOR2: string;
+        static TEXCOORDS: string;
+        static SAMPLER: string;
+        private context;
+        private vs;
+        private vsSource;
+        private fs;
+        private fsSource;
+        private program;
+        private tmp2x2;
+        private tmp3x3;
+        private tmp4x4;
+        getProgram(): WebGLProgram;
+        getVertexShader(): string;
+        getFragmentShader(): string;
+        getVertexShaderSource(): string;
+        getFragmentSource(): string;
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, vertexShader: string, fragmentShader: string);
+        private compile();
+        private compileShader(type, source);
+        private compileProgram(vs, fs);
+        restore(): void;
+        bind(): void;
+        unbind(): void;
+        setUniformi(uniform: string, value: number): void;
+        setUniformf(uniform: string, value: number): void;
+        setUniform2f(uniform: string, value: number, value2: number): void;
+        setUniform3f(uniform: string, value: number, value2: number, value3: number): void;
+        setUniform4f(uniform: string, value: number, value2: number, value3: number, value4: number): void;
+        setUniform2x2f(uniform: string, value: ArrayLike<number>): void;
+        setUniform3x3f(uniform: string, value: ArrayLike<number>): void;
+        setUniform4x4f(uniform: string, value: ArrayLike<number>): void;
+        getUniformLocation(uniform: string): WebGLUniformLocation;
+        getAttributeLocation(attribute: string): number;
+        dispose(): void;
+        static newColoredTextured(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader;
+        static newTwoColoredTextured(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader;
+        static newColored(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader;
+    }
 }
 declare module spine.webgl {
-	class ShapeRenderer implements Disposable {
-		private context;
-		private isDrawing;
-		private mesh;
-		private shapeType;
-		private color;
-		private shader;
-		private vertexIndex;
-		private tmp;
-		private srcBlend;
-		private dstBlend;
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, maxVertices?: number);
-		begin(shader: Shader): void;
-		setBlendMode(srcBlend: number, dstBlend: number): void;
-		setColor(color: Color): void;
-		setColorWith(r: number, g: number, b: number, a: number): void;
-		point(x: number, y: number, color?: Color): void;
-		line(x: number, y: number, x2: number, y2: number, color?: Color): void;
-		triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
-		quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
-		rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
-		rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
-		x(x: number, y: number, size: number): void;
-		polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
-		circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
-		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-		private vertex;
-		end(): void;
-		private flush;
-		private check;
-		dispose(): void;
-	}
-	enum ShapeType {
-		Point = 0,
-		Line = 1,
-		Filled = 4
-	}
+    class ShapeRenderer implements Disposable {
+        private context;
+        private isDrawing;
+        private mesh;
+        private shapeType;
+        private color;
+        private shader;
+        private vertexIndex;
+        private tmp;
+        private srcBlend;
+        private dstBlend;
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, maxVertices?: number);
+        begin(shader: Shader): void;
+        setBlendMode(srcBlend: number, dstBlend: number): void;
+        setColor(color: Color): void;
+        setColorWith(r: number, g: number, b: number, a: number): void;
+        point(x: number, y: number, color?: Color): void;
+        line(x: number, y: number, x2: number, y2: number, color?: Color): void;
+        triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
+        quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
+        rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
+        rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
+        x(x: number, y: number, size: number): void;
+        polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
+        circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
+        curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
+        private vertex(x, y, color);
+        end(): void;
+        private flush();
+        private check(shapeType, numVertices);
+        dispose(): void;
+    }
+    enum ShapeType {
+        Point = 0,
+        Line = 1,
+        Filled = 4,
+    }
 }
 declare module spine.webgl {
-	class SkeletonDebugRenderer implements Disposable {
-		boneLineColor: Color;
-		boneOriginColor: Color;
-		attachmentLineColor: Color;
-		triangleLineColor: Color;
-		pathColor: Color;
-		clipColor: Color;
-		aabbColor: Color;
-		drawBones: boolean;
-		drawRegionAttachments: boolean;
-		drawBoundingBoxes: boolean;
-		drawMeshHull: boolean;
-		drawMeshTriangles: boolean;
-		drawPaths: boolean;
-		drawSkeletonXY: boolean;
-		drawClipping: boolean;
-		premultipliedAlpha: boolean;
-		scale: number;
-		boneWidth: number;
-		private context;
-		private bounds;
-		private temp;
-		private vertices;
-		private static LIGHT_GRAY;
-		private static GREEN;
-		constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext);
-		draw(shapes: ShapeRenderer, skeleton: Skeleton, ignoredBones?: Array<string>): void;
-		dispose(): void;
-	}
+    class SkeletonDebugRenderer implements Disposable {
+        boneLineColor: Color;
+        boneOriginColor: Color;
+        attachmentLineColor: Color;
+        triangleLineColor: Color;
+        pathColor: Color;
+        clipColor: Color;
+        aabbColor: Color;
+        drawBones: boolean;
+        drawRegionAttachments: boolean;
+        drawBoundingBoxes: boolean;
+        drawMeshHull: boolean;
+        drawMeshTriangles: boolean;
+        drawPaths: boolean;
+        drawSkeletonXY: boolean;
+        drawClipping: boolean;
+        premultipliedAlpha: boolean;
+        scale: number;
+        boneWidth: number;
+        private context;
+        private bounds;
+        private temp;
+        private vertices;
+        private static LIGHT_GRAY;
+        private static GREEN;
+        constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext);
+        draw(shapes: ShapeRenderer, skeleton: Skeleton, ignoredBones?: Array<string>): void;
+        dispose(): void;
+    }
 }
 declare module spine.webgl {
-	class SkeletonRenderer {
-		static QUAD_TRIANGLES: number[];
-		premultipliedAlpha: boolean;
-		vertexEffect: VertexEffect;
-		private tempColor;
-		private tempColor2;
-		private vertices;
-		private vertexSize;
-		private twoColorTint;
-		private renderable;
-		private clipper;
-		private temp;
-		private temp2;
-		private temp3;
-		private temp4;
-		constructor(context: ManagedWebGLRenderingContext, twoColorTint?: boolean);
-		draw(batcher: PolygonBatcher, skeleton: Skeleton, slotRangeStart?: number, slotRangeEnd?: number): void;
-	}
+    class SkeletonRenderer {
+        static QUAD_TRIANGLES: number[];
+        premultipliedAlpha: boolean;
+        vertexEffect: VertexEffect;
+        private tempColor;
+        private tempColor2;
+        private vertices;
+        private vertexSize;
+        private twoColorTint;
+        private renderable;
+        private clipper;
+        private temp;
+        private temp2;
+        private temp3;
+        private temp4;
+        constructor(context: ManagedWebGLRenderingContext, twoColorTint?: boolean);
+        draw(batcher: PolygonBatcher, skeleton: Skeleton, slotRangeStart?: number, slotRangeEnd?: number): void;
+    }
 }
 declare module spine.webgl {
-	class Vector3 {
-		x: number;
-		y: number;
-		z: number;
-		constructor(x?: number, y?: number, z?: number);
-		setFrom(v: Vector3): Vector3;
-		set(x: number, y: number, z: number): Vector3;
-		add(v: Vector3): Vector3;
-		sub(v: Vector3): Vector3;
-		scale(s: number): Vector3;
-		normalize(): Vector3;
-		cross(v: Vector3): Vector3;
-		multiply(matrix: Matrix4): Vector3;
-		project(matrix: Matrix4): Vector3;
-		dot(v: Vector3): number;
-		length(): number;
-		distance(v: Vector3): number;
-	}
+    class Vector3 {
+        x: number;
+        y: number;
+        z: number;
+        constructor(x?: number, y?: number, z?: number);
+        setFrom(v: Vector3): Vector3;
+        set(x: number, y: number, z: number): Vector3;
+        add(v: Vector3): Vector3;
+        sub(v: Vector3): Vector3;
+        scale(s: number): Vector3;
+        normalize(): Vector3;
+        cross(v: Vector3): Vector3;
+        multiply(matrix: Matrix4): Vector3;
+        project(matrix: Matrix4): Vector3;
+        dot(v: Vector3): number;
+        length(): number;
+        distance(v: Vector3): number;
+    }
 }
 declare module spine.webgl {
-	class ManagedWebGLRenderingContext {
-		canvas: HTMLCanvasElement;
-		gl: WebGLRenderingContext;
-		private restorables;
-		constructor(canvasOrContext: HTMLCanvasElement | WebGLRenderingContext, contextConfig?: any);
-		addRestorable(restorable: Restorable): void;
-		removeRestorable(restorable: Restorable): void;
-	}
-	class WebGLBlendModeConverter {
-		static ZERO: number;
-		static ONE: number;
-		static SRC_COLOR: number;
-		static ONE_MINUS_SRC_COLOR: number;
-		static SRC_ALPHA: number;
-		static ONE_MINUS_SRC_ALPHA: number;
-		static DST_ALPHA: number;
-		static ONE_MINUS_DST_ALPHA: number;
-		static DST_COLOR: number;
-		static getDestGLBlendMode(blendMode: BlendMode): number;
-		static getSourceGLBlendMode(blendMode: BlendMode, premultipliedAlpha?: boolean): number;
-	}
+    class ManagedWebGLRenderingContext {
+        canvas: HTMLCanvasElement;
+        gl: WebGLRenderingContext;
+        private restorables;
+        constructor(canvasOrContext: HTMLCanvasElement | WebGLRenderingContext, contextConfig?: any);
+        addRestorable(restorable: Restorable): void;
+        removeRestorable(restorable: Restorable): void;
+    }
+    class WebGLBlendModeConverter {
+        static ZERO: number;
+        static ONE: number;
+        static SRC_COLOR: number;
+        static ONE_MINUS_SRC_COLOR: number;
+        static SRC_ALPHA: number;
+        static ONE_MINUS_SRC_ALPHA: number;
+        static DST_ALPHA: number;
+        static ONE_MINUS_DST_ALPHA: number;
+        static DST_COLOR: number;
+        static getDestGLBlendMode(blendMode: BlendMode): number;
+        static getSourceGLBlendMode(blendMode: BlendMode, premultipliedAlpha?: boolean): number;
+    }
 }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 6961 - 7031
spine-ts/build/spine-webgl.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 14 - 5
spine-ts/core/src/Animation.ts

@@ -1037,12 +1037,12 @@ module spine {
 	}
 
 	export class IkConstraintTimeline extends CurveTimeline {
-		static ENTRIES = 4;
-		static PREV_TIME = -4; static PREV_MIX = -3; static PREV_BEND_DIRECTION = -2; static PREV_STRETCH = -1;
-		static MIX = 1; static BEND_DIRECTION = 2; static STRETCH = 3;
+		static ENTRIES = 5;
+		static PREV_TIME = -5; static PREV_MIX = -4; static PREV_BEND_DIRECTION = -3; static PREV_COMPRESS = -2; static PREV_STRETCH = -1;
+		static MIX = 1; static BEND_DIRECTION = 2; static COMPRESS = 3; static STRETCH = 4;
 
 		ikConstraintIndex: number;
-		frames: ArrayLike<number>; // time, mix, bendDirection, ...
+		frames: ArrayLike<number>; // time, mix, bendDirection, compress, stretch, ...
 
 		constructor (frameCount: number) {
 			super(frameCount);
@@ -1054,11 +1054,12 @@ module spine {
 		}
 
 		/** Sets the time, mix and bend direction of the specified keyframe. */
-		setFrame (frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean) {
+		setFrame (frameIndex: number, time: number, mix: number, bendDirection: number, compress: boolean, stretch: boolean) {
 			frameIndex *= IkConstraintTimeline.ENTRIES;
 			this.frames[frameIndex] = time;
 			this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
 			this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
+			this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0;
 			this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
 		}
 
@@ -1070,11 +1071,13 @@ module spine {
 				case MixBlend.setup:
 					constraint.mix = constraint.data.mix;
 					constraint.bendDirection = constraint.data.bendDirection;
+					constraint.compress = constraint.data.compress;
 					constraint.stretch = constraint.data.stretch;
 					return;
 				case MixBlend.first:
 					constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
 					constraint.bendDirection = constraint.data.bendDirection;
+					constraint.compress = constraint.data.compress;
 					constraint.stretch = constraint.data.stretch;
 				}
 				return;
@@ -1085,15 +1088,18 @@ module spine {
 					constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
 					if (direction == MixDirection.out) {
 						constraint.bendDirection = constraint.data.bendDirection;
+						constraint.compress = constraint.data.compress;
 						constraint.stretch = constraint.data.stretch;
 					} else {
 						constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]
+						constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0;
 						constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
 					}
 				} else {
 					constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
 					if (direction == MixDirection.in) {
 						constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+						constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0;
 						constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
 					}
 				}
@@ -1111,15 +1117,18 @@ module spine {
 				constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
 				if (direction == MixDirection.out) {
 					constraint.bendDirection = constraint.data.bendDirection;
+					constraint.compress = constraint.data.compress;
 					constraint.stretch = constraint.data.stretch;
 				} else {
 					constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+					constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0;
 					constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
 				}
 			} else {
 				constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
 				if (direction == MixDirection.in) {
 					constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+					constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0;
 					constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
 				}
 			}

+ 1 - 1
spine-ts/core/src/AnimationState.ts

@@ -304,10 +304,10 @@ module spine {
 			// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
 			let r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
 			let total = 0, diff = r2 - r1;
+			diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
 			if (diff == 0) {
 				total = timelinesRotation[i];
 			} else {
-				diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
 				let lastTotal = 0, lastDiff = 0;
 				if (firstFrame) {
 					lastTotal = 0;

+ 12 - 6
spine-ts/core/src/IkConstraint.ts

@@ -34,6 +34,7 @@ module spine {
 		bones: Array<Bone>;
 		target: Bone;
 		bendDirection = 0;
+		compress = false;
 		stretch = false;
 		mix = 1;
 
@@ -43,6 +44,7 @@ module spine {
 			this.data = data;
 			this.mix = data.mix;
 			this.bendDirection = data.bendDirection;
+			this.compress = data.compress;
 			this.stretch = data.stretch;
 
 			this.bones = new Array<Bone>();
@@ -64,7 +66,7 @@ module spine {
 			let bones = this.bones;
 			switch (bones.length) {
 			case 1:
-				this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
+				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.mix);
@@ -74,7 +76,7 @@ module spine {
 
 		/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
 		 * coordinate system. */
-		apply1 (bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number) {
+		apply1 (bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number) {
 			if (!bone.appliedValid) bone.updateAppliedTransform();
 			let p = bone.parent;
 			let id = 1 / (p.a * p.d - p.b * p.c);
@@ -85,12 +87,16 @@ module spine {
 			if (rotationIK > 180)
 				rotationIK -= 360;
 			else if (rotationIK < -180) rotationIK += 360;
-			let sx = bone.ascaleX;
-			if (stretch) {
+			let sx = bone.ascaleX, sy = bone.ascaleY;
+			if (compress || stretch) {
 				let b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
-				if (dd > b && b > 0.0001) sx *= (dd / b - 1) * alpha + 1;
+				if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) {
+					let s = (dd / b - 1) * alpha + 1;
+					sx *= s;
+					if (uniform) sy *= s;
+				}
 			}
-			bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX,
+			bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX,
 				bone.ashearY);
 		}
 

+ 2 - 0
spine-ts/core/src/IkConstraintData.ts

@@ -35,7 +35,9 @@ module spine {
 		bones = new Array<BoneData>();
 		target: BoneData;
 		bendDirection = 1;
+		compress = false;
 		stretch = false;
+		uniform = false;
 		mix = 1;
 
 		constructor (name: string) {

+ 2 - 1
spine-ts/core/src/Skeleton.ts

@@ -286,9 +286,10 @@ module spine {
 			let ikConstraints = this.ikConstraints;
 			for (let i = 0, n = ikConstraints.length; i < n; i++) {
 				let constraint = ikConstraints[i];
+				constraint.mix = constraint.data.mix;
 				constraint.bendDirection = constraint.data.bendDirection;
+				constraint.compress = constraint.data.compress;
 				constraint.stretch = constraint.data.stretch;
-				constraint.mix = constraint.data.mix;
 			}
 
 			let transformConstraints = this.transformConstraints;

+ 4 - 2
spine-ts/core/src/SkeletonJson.ts

@@ -123,9 +123,11 @@ module spine {
 					data.target = skeletonData.findBone(targetName);
 					if (data.target == null) throw new Error("IK target bone not found: " + targetName);
 
+					data.mix = this.getValue(constraintMap, "mix", 1);
 					data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
+					data.compress = this.getValue(constraintMap, "compress", false);
 					data.stretch = this.getValue(constraintMap, "stretch", false);
-					data.mix = this.getValue(constraintMap, "mix", 1);
+					data.uniform = this.getValue(constraintMap, "uniform", false);
 
 					skeletonData.ikConstraints.push(data);
 				}
@@ -521,7 +523,7 @@ module spine {
 					for (let i = 0; i < constraintMap.length; i++) {
 						let valueMap = constraintMap[i];
 						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1),
-							this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
+							this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}

+ 5 - 1
spine-unity/Assets/Spine/Editor/spine-unity/Editor/SkeletonDebugWindow.cs

@@ -371,12 +371,16 @@ namespace Spine.Unity.Editor {
 									foreach (var c in skeleton.IkConstraints) {
 										EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(c.Data.Name, Icons.constraintIK));
 										FalseDropDown("Goal", c.Data.Target.Name, Icons.bone, true);
+										using (new EditorGUI.DisabledGroupScope(true)) {
+											EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Data.Uniform", tooltip: "Uniformly scales a bone when Ik stretches or compresses."), c.Data.Uniform);
+										}
 
 										EditorGUI.BeginChangeCheck();
 										c.Mix = EditorGUILayout.Slider("Mix", c.Mix, MixMin, MixMax);
 										c.BendDirection = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bend Clockwise", tooltip: "IkConstraint.BendDirection == 1 if clockwise; -1 if counterclockwise."), c.BendDirection > 0) ? 1 : -1;
+										c.Compress = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Compress", tooltip: "Compress single bone IK when the target too close. Not applied when parent bone has nonuniform scale."), c.Compress);
 										c.Stretch = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Stretch", tooltip: "Stretch the parent bone when the target is out of range. Not applied when parent bone has nonuniform scale."), c.Stretch);
-										if (EditorGUI.EndChangeCheck())	requireRepaint = true;
+										if (EditorGUI.EndChangeCheck()) requireRepaint = true;
 
 										EditorGUILayout.Space();
 									}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно