Przeglądaj źródła

[ts] Added Canvas backend, also does meshes

badlogic 9 lat temu
rodzic
commit
23f2a50821
34 zmienionych plików z 5030 dodań i 1848 usunięć
  1. 1 715
      spine-ts/build/spine-webgl.d.ts
  2. 20 469
      spine-ts/build/spine-webgl.js
  3. 0 0
      spine-ts/build/spine-webgl.js.map
  4. 160 184
      spine-ts/build/spine-widget.d.ts
  5. 431 457
      spine-ts/build/spine-widget.js
  6. 0 0
      spine-ts/build/spine-widget.js.map
  7. 293 0
      spine-ts/canvas/example/assets/goblins-mesh.atlas
  8. 1082 0
      spine-ts/canvas/example/assets/goblins-mesh.json
  9. BIN
      spine-ts/canvas/example/assets/goblins-mesh.png
  10. 279 0
      spine-ts/canvas/example/assets/raptor.atlas
  11. 361 0
      spine-ts/canvas/example/assets/raptor.json
  12. BIN
      spine-ts/canvas/example/assets/raptor.png
  13. 125 0
      spine-ts/canvas/example/assets/tank.atlas
  14. 1899 0
      spine-ts/canvas/example/assets/tank.json
  15. BIN
      spine-ts/canvas/example/assets/tank.png
  16. 13 0
      spine-ts/canvas/example/assets/test.atlas
  17. 19 0
      spine-ts/canvas/example/assets/test.json
  18. BIN
      spine-ts/canvas/example/assets/test.png
  19. 13 0
      spine-ts/canvas/example/assets/vine.atlas
  20. 41 0
      spine-ts/canvas/example/assets/vine.json
  21. BIN
      spine-ts/canvas/example/assets/vine.png
  22. 96 1
      spine-ts/canvas/example/index.html
  23. 34 1
      spine-ts/canvas/src/CanvasTexture.ts
  24. 138 0
      spine-ts/canvas/src/SkeletonRenderer.ts
  25. 5 3
      spine-ts/core/src/TextureAtlas.ts
  26. 1 1
      spine-ts/core/src/TextureAtlasAttachmentLoader.ts
  27. 1 1
      spine-ts/tsconfig.canvas.json
  28. 1 1
      spine-ts/tsconfig.core.json
  29. 1 1
      spine-ts/tsconfig.json
  30. 1 1
      spine-ts/tsconfig.webgl.json
  31. 1 1
      spine-ts/tsconfig.widget.json
  32. 4 7
      spine-ts/webgl/example/index.html
  33. 1 1
      spine-ts/webgl/src/SkeletonRenderer.ts
  34. 9 4
      spine-ts/widget/src/Widget.ts

Plik diff jest za duży
+ 1 - 715
spine-ts/build/spine-webgl.d.ts


Plik diff jest za duży
+ 20 - 469
spine-ts/build/spine-webgl.js


Plik diff jest za duży
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 160 - 184
spine-ts/build/spine-widget.d.ts

@@ -354,6 +354,57 @@ declare module spine {
         getMix(from: Animation, to: Animation): number;
     }
 }
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+declare module spine {
+    class AssetManager implements Disposable {
+        private _textureLoader;
+        private _assets;
+        private _errors;
+        private _toLoad;
+        private _loaded;
+        constructor(textureLoader: (image: HTMLImageElement) => any);
+        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;
+        get(path: string): any;
+        remove(path: string): void;
+        removeAll(): void;
+        isLoadingComplete(): boolean;
+        toLoad(): number;
+        loaded(): number;
+        dispose(): void;
+        hasErrors(): boolean;
+        errors(): Map<string>;
+    }
+}
 /******************************************************************************
  * Spine Runtimes Software License
  * Version 2.5
@@ -1206,6 +1257,105 @@ declare module spine {
         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;
+    }
+}
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+declare module spine {
+    class TextureAtlas implements Disposable {
+        pages: TextureAtlasPage[];
+        regions: TextureAtlasRegion[];
+        constructor(atlasText: string, textureLoader: (path: string, minFilter: TextureFilter, magFilter: TextureFilter, uWrap: TextureWrap, vWrap: TextureWrap) => 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;
+    }
+}
 /******************************************************************************
  * Spine Runtimes Software License
  * Version 2.5
@@ -1769,52 +1919,6 @@ declare module spine {
         updateWorldVertices(slot: Slot, premultipliedAlpha: boolean): ArrayLike<number>;
     }
 }
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-declare module spine {
-    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;
-    }
-}
 /******************************************************************************
  * Spine Runtimes Software License
  * Version 2.5
@@ -1846,24 +1950,17 @@ declare module spine {
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 declare module spine.webgl {
-    class AssetManager implements Disposable {
+    class GLTexture extends Texture implements Disposable {
         private _gl;
-        private _assets;
-        private _errors;
-        private _toLoad;
-        private _loaded;
-        constructor(gl: WebGLRenderingContext);
-        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;
-        get(path: string): string | Texture;
-        remove(path: string): void;
-        removeAll(): void;
-        isLoadingComplete(): boolean;
-        toLoad(): number;
-        loaded(): number;
+        private _texture;
+        private _boundUnit;
+        constructor(gl: WebGLRenderingContext, image: HTMLImageElement, useMipMaps?: boolean);
+        setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+        setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+        update(useMipMaps: boolean): void;
+        bind(unit?: number): void;
+        unbind(): void;
         dispose(): void;
-        hasErrors(): boolean;
-        errors(): Map<string>;
     }
 }
 /******************************************************************************
@@ -2060,7 +2157,7 @@ declare module spine.webgl {
         constructor(gl: WebGLRenderingContext, maxVertices?: number);
         begin(shader: Shader): void;
         setBlendMode(srcBlend: number, dstBlend: number): void;
-        draw(texture: Texture, vertices: ArrayLike<number>, indices: Array<number>): void;
+        draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
         private flush();
         end(): void;
         drawCalls(): number;
@@ -2175,127 +2272,6 @@ declare module spine.webgl {
         draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
     }
 }
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-declare module spine.webgl {
-    class Texture implements Disposable {
-        private _gl;
-        private _texture;
-        private _image;
-        private _boundUnit;
-        constructor(gl: WebGLRenderingContext, image: HTMLImageElement, useMipMaps?: boolean);
-        getImage(): HTMLImageElement;
-        setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-        setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-        update(useMipMaps: boolean): void;
-        bind(unit?: number): void;
-        unbind(): void;
-        dispose(): void;
-        static filterFromString(text: string): TextureFilter;
-        static wrapFromString(text: string): TextureWrap;
-    }
-    enum TextureFilter {
-        Nearest,
-        Linear,
-        MipMap,
-        MipMapNearestNearest,
-        MipMapLinearNearest,
-        MipMapNearestLinear,
-        MipMapLinearLinear,
-    }
-    enum TextureWrap {
-        MirroredRepeat,
-        ClampToEdge,
-        Repeat,
-    }
-}
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-declare module spine.webgl {
-    class TextureAtlas implements Disposable {
-        pages: TextureAtlasPage[];
-        regions: TextureAtlasRegion[];
-        constructor(atlasText: string, textureLoader: (path: string) => Texture);
-        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;
-    }
-}
 /******************************************************************************
  * Spine Runtimes Software License
  * Version 2.5

+ 431 - 457
spine-ts/build/spine-widget.js

@@ -1146,6 +1146,133 @@ var spine;
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 var spine;
+(function (spine) {
+    var AssetManager = (function () {
+        function AssetManager(textureLoader) {
+            this._assets = {};
+            this._errors = {};
+            this._toLoad = 0;
+            this._loaded = 0;
+            this._textureLoader = textureLoader;
+        }
+        AssetManager.prototype.loadText = function (path, success, error) {
+            var _this = this;
+            if (success === void 0) { success = null; }
+            if (error === void 0) { error = null; }
+            this._toLoad++;
+            var request = new XMLHttpRequest();
+            request.onreadystatechange = function () {
+                if (request.readyState == XMLHttpRequest.DONE) {
+                    if (request.status >= 200 && request.status < 300) {
+                        if (success)
+                            success(path, request.responseText);
+                        _this._assets[path] = request.responseText;
+                    }
+                    else {
+                        if (error)
+                            error(path, "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText);
+                        _this._errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
+                    }
+                    _this._toLoad--;
+                    _this._loaded++;
+                }
+            };
+            request.open("GET", path, true);
+            request.send();
+        };
+        AssetManager.prototype.loadTexture = function (path, success, error) {
+            var _this = this;
+            if (success === void 0) { success = null; }
+            if (error === void 0) { error = null; }
+            this._toLoad++;
+            var img = new Image();
+            img.src = path;
+            img.onload = function (ev) {
+                if (success)
+                    success(path, img);
+                var texture = _this._textureLoader(img);
+                _this._assets[path] = texture;
+                _this._toLoad--;
+                _this._loaded++;
+            };
+            img.onerror = function (ev) {
+                if (error)
+                    error(path, "Couldn't load image " + path);
+                _this._errors[path] = "Couldn't load image " + path;
+                _this._toLoad--;
+                _this._loaded++;
+            };
+        };
+        AssetManager.prototype.get = function (path) {
+            return this._assets[path];
+        };
+        AssetManager.prototype.remove = function (path) {
+            var asset = this._assets[path];
+            if (asset.dispose)
+                asset.dispose();
+            this._assets[path] = null;
+        };
+        AssetManager.prototype.removeAll = function () {
+            for (var key in this._assets) {
+                var asset = this._assets[key];
+                if (asset.dispose)
+                    asset.dispose();
+            }
+            this._assets = {};
+        };
+        AssetManager.prototype.isLoadingComplete = function () {
+            return this._toLoad == 0;
+        };
+        AssetManager.prototype.toLoad = function () {
+            return this._toLoad;
+        };
+        AssetManager.prototype.loaded = function () {
+            return this._loaded;
+        };
+        AssetManager.prototype.dispose = function () {
+            this.removeAll();
+        };
+        AssetManager.prototype.hasErrors = function () {
+            return Object.keys(this._errors).length > 0;
+        };
+        AssetManager.prototype.errors = function () {
+            return this._errors;
+        };
+        return AssetManager;
+    }());
+    spine.AssetManager = AssetManager;
+})(spine || (spine = {}));
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+var spine;
 (function (spine) {
     (function (BlendMode) {
         BlendMode[BlendMode["Normal"] = 0] = "Normal";
@@ -3997,6 +4124,258 @@ var spine;
     }());
     spine.SlotData = SlotData;
 })(spine || (spine = {}));
+var spine;
+(function (spine) {
+    var Texture = (function () {
+        function Texture(image) {
+            this._image = image;
+        }
+        Texture.prototype.getImage = function () {
+            return this._image;
+        };
+        Texture.filterFromString = function (text) {
+            switch (text.toLowerCase()) {
+                case "nearest": return TextureFilter.Nearest;
+                case "linear": return TextureFilter.Linear;
+                case "mipmap": return TextureFilter.MipMap;
+                case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest;
+                case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
+                case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
+                case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
+                default: throw new Error("Unknown texture filter " + text);
+            }
+        };
+        Texture.wrapFromString = function (text) {
+            switch (text.toLowerCase()) {
+                case "mirroredtepeat": return TextureWrap.MirroredRepeat;
+                case "clamptoedge": return TextureWrap.ClampToEdge;
+                case "repeat": return TextureWrap.Repeat;
+                default: throw new Error("Unknown texture wrap " + text);
+            }
+        };
+        return Texture;
+    }());
+    spine.Texture = Texture;
+    (function (TextureFilter) {
+        TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest";
+        TextureFilter[TextureFilter["Linear"] = 9729] = "Linear";
+        TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap";
+        TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest";
+        TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest";
+        TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear";
+        TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; // WebGLRenderingContext.LINEAR_MIPMAP_LINEAR
+    })(spine.TextureFilter || (spine.TextureFilter = {}));
+    var TextureFilter = spine.TextureFilter;
+    (function (TextureWrap) {
+        TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat";
+        TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge";
+        TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat"; // WebGLRenderingContext.REPEAT
+    })(spine.TextureWrap || (spine.TextureWrap = {}));
+    var TextureWrap = spine.TextureWrap;
+    var TextureRegion = (function () {
+        function TextureRegion() {
+            this.u = 0;
+            this.v = 0;
+            this.u2 = 0;
+            this.v2 = 0;
+            this.width = 0;
+            this.height = 0;
+            this.rotate = false;
+            this.offsetX = 0;
+            this.offsetY = 0;
+            this.originalWidth = 0;
+            this.originalHeight = 0;
+        }
+        return TextureRegion;
+    }());
+    spine.TextureRegion = TextureRegion;
+})(spine || (spine = {}));
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+var spine;
+(function (spine) {
+    var TextureAtlas = (function () {
+        function TextureAtlas(atlasText, textureLoader) {
+            this.pages = new Array();
+            this.regions = new Array();
+            this.load(atlasText, textureLoader);
+        }
+        TextureAtlas.prototype.load = function (atlasText, textureLoader) {
+            if (textureLoader == null)
+                throw new Error("textureLoader cannot be null.");
+            var reader = new TextureAtlasReader(atlasText);
+            var tuple = new Array(4);
+            var page = null;
+            while (true) {
+                var line = reader.readLine();
+                if (line == null)
+                    break;
+                line = line.trim();
+                if (line.length == 0)
+                    page = null;
+                else if (!page) {
+                    page = new TextureAtlasPage();
+                    page.name = line;
+                    if (reader.readTuple(tuple) == 2) {
+                        page.width = parseInt(tuple[0]);
+                        page.height = parseInt(tuple[1]);
+                        reader.readTuple(tuple);
+                    }
+                    // page.format = Format[tuple[0]]; we don't need format in WebGL
+                    reader.readTuple(tuple);
+                    page.minFilter = spine.Texture.filterFromString(tuple[0]);
+                    page.magFilter = spine.Texture.filterFromString(tuple[1]);
+                    var direction = reader.readValue();
+                    page.uWrap = spine.TextureWrap.ClampToEdge;
+                    page.vWrap = spine.TextureWrap.ClampToEdge;
+                    if (direction == "x")
+                        page.uWrap = spine.TextureWrap.Repeat;
+                    else if (direction == "y")
+                        page.vWrap = spine.TextureWrap.Repeat;
+                    else if (direction == "xy")
+                        page.uWrap = page.vWrap = spine.TextureWrap.Repeat;
+                    page.texture = textureLoader(line, page.minFilter, page.magFilter, page.uWrap, page.vWrap);
+                    page.width = page.texture.getImage().width;
+                    page.height = page.texture.getImage().height;
+                    this.pages.push(page);
+                }
+                else {
+                    var region = new TextureAtlasRegion();
+                    region.name = line;
+                    region.page = page;
+                    region.rotate = reader.readValue() == "true";
+                    reader.readTuple(tuple);
+                    var x = parseInt(tuple[0]);
+                    var y = parseInt(tuple[1]);
+                    reader.readTuple(tuple);
+                    var width = parseInt(tuple[0]);
+                    var height = parseInt(tuple[1]);
+                    region.u = x / page.width;
+                    region.v = y / page.height;
+                    if (region.rotate) {
+                        region.u2 = (x + height) / page.width;
+                        region.v2 = (y + width) / page.height;
+                    }
+                    else {
+                        region.u2 = (x + width) / page.width;
+                        region.v2 = (y + height) / page.height;
+                    }
+                    region.x = x;
+                    region.y = y;
+                    region.width = Math.abs(width);
+                    region.height = Math.abs(height);
+                    if (reader.readTuple(tuple) == 4) {
+                        // region.splits = new Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
+                        if (reader.readTuple(tuple) == 4) {
+                            //region.pads = Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
+                            reader.readTuple(tuple);
+                        }
+                    }
+                    region.originalWidth = parseInt(tuple[0]);
+                    region.originalHeight = parseInt(tuple[1]);
+                    reader.readTuple(tuple);
+                    region.offsetX = parseInt(tuple[0]);
+                    region.offsetY = parseInt(tuple[1]);
+                    region.index = parseInt(reader.readValue());
+                    region.texture = page.texture;
+                    this.regions.push(region);
+                }
+            }
+        };
+        TextureAtlas.prototype.findRegion = function (name) {
+            for (var i = 0; i < this.regions.length; i++) {
+                if (this.regions[i].name == name) {
+                    return this.regions[i];
+                }
+            }
+            return null;
+        };
+        TextureAtlas.prototype.dispose = function () {
+            for (var i = 0; i < this.pages.length; i++) {
+                this.pages[i].texture.dispose();
+            }
+        };
+        return TextureAtlas;
+    }());
+    spine.TextureAtlas = TextureAtlas;
+    var TextureAtlasReader = (function () {
+        function TextureAtlasReader(text) {
+            this.index = 0;
+            this.lines = text.split(/\r\n|\r|\n/);
+        }
+        TextureAtlasReader.prototype.readLine = function () {
+            if (this.index >= this.lines.length)
+                return null;
+            return this.lines[this.index++];
+        };
+        TextureAtlasReader.prototype.readValue = function () {
+            var line = this.readLine();
+            var colon = line.indexOf(":");
+            if (colon == -1)
+                throw new Error("Invalid line: " + line);
+            return line.substring(colon + 1).trim();
+        };
+        TextureAtlasReader.prototype.readTuple = function (tuple) {
+            var line = this.readLine();
+            var colon = line.indexOf(":");
+            if (colon == -1)
+                throw new Error("Invalid line: " + line);
+            var i = 0, lastMatch = colon + 1;
+            for (; i < 3; i++) {
+                var comma = line.indexOf(",", lastMatch);
+                if (comma == -1)
+                    break;
+                tuple[i] = line.substr(lastMatch, comma - lastMatch).trim();
+                lastMatch = comma + 1;
+            }
+            tuple[i] = line.substring(lastMatch).trim();
+            return i + 1;
+        };
+        return TextureAtlasReader;
+    }());
+    var TextureAtlasPage = (function () {
+        function TextureAtlasPage() {
+        }
+        return TextureAtlasPage;
+    }());
+    spine.TextureAtlasPage = TextureAtlasPage;
+    var TextureAtlasRegion = (function (_super) {
+        __extends(TextureAtlasRegion, _super);
+        function TextureAtlasRegion() {
+            _super.apply(this, arguments);
+        }
+        return TextureAtlasRegion;
+    }(spine.TextureRegion));
+    spine.TextureAtlasRegion = TextureAtlasRegion;
+})(spine || (spine = {}));
 /******************************************************************************
  * Spine Runtimes Software License
  * Version 2.5
@@ -5061,154 +5440,61 @@ var spine;
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 var spine;
-(function (spine) {
-    var TextureRegion = (function () {
-        function TextureRegion() {
-            this.u = 0;
-            this.v = 0;
-            this.u2 = 0;
-            this.v2 = 0;
-            this.width = 0;
-            this.height = 0;
-            this.rotate = false;
-            this.offsetX = 0;
-            this.offsetY = 0;
-            this.originalWidth = 0;
-            this.originalHeight = 0;
-        }
-        return TextureRegion;
-    }());
-    spine.TextureRegion = TextureRegion;
-})(spine || (spine = {}));
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-var spine;
 (function (spine) {
     var webgl;
     (function (webgl) {
-        var AssetManager = (function () {
-            function AssetManager(gl) {
-                this._assets = {};
-                this._errors = {};
-                this._toLoad = 0;
-                this._loaded = 0;
+        var GLTexture = (function (_super) {
+            __extends(GLTexture, _super);
+            function GLTexture(gl, image, useMipMaps) {
+                if (useMipMaps === void 0) { useMipMaps = false; }
+                _super.call(this, image);
+                this._boundUnit = 0;
                 this._gl = gl;
+                this._texture = gl.createTexture();
+                this.update(useMipMaps);
             }
-            AssetManager.prototype.loadText = function (path, success, error) {
-                var _this = this;
-                if (success === void 0) { success = null; }
-                if (error === void 0) { error = null; }
-                this._toLoad++;
-                var request = new XMLHttpRequest();
-                request.onreadystatechange = function () {
-                    if (request.readyState == XMLHttpRequest.DONE) {
-                        if (request.status >= 200 && request.status < 300) {
-                            if (success)
-                                success(path, request.responseText);
-                            _this._assets[path] = request.responseText;
-                        }
-                        else {
-                            if (error)
-                                error(path, "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText);
-                            _this._errors[path] = "Couldn't load text " + path + ": status " + request.status + ", " + request.responseText;
-                        }
-                        _this._toLoad--;
-                        _this._loaded++;
-                    }
-                };
-                request.open("GET", path, true);
-                request.send();
-            };
-            AssetManager.prototype.loadTexture = function (path, success, error) {
-                var _this = this;
-                if (success === void 0) { success = null; }
-                if (error === void 0) { error = null; }
-                this._toLoad++;
-                var img = new Image();
-                img.src = path;
-                img.onload = function (ev) {
-                    if (success)
-                        success(path, img);
-                    var texture = new webgl.Texture(_this._gl, img);
-                    _this._assets[path] = texture;
-                    _this._toLoad--;
-                    _this._loaded++;
-                };
-                img.onerror = function (ev) {
-                    if (error)
-                        error(path, "Couldn't load image " + path);
-                    _this._errors[path] = "Couldn't load image " + path;
-                    _this._toLoad--;
-                    _this._loaded++;
-                };
-            };
-            AssetManager.prototype.get = function (path) {
-                return this._assets[path];
-            };
-            AssetManager.prototype.remove = function (path) {
-                var asset = this._assets[path];
-                if (asset instanceof webgl.Texture) {
-                    asset.dispose();
-                }
-                this._assets[path] = null;
-            };
-            AssetManager.prototype.removeAll = function () {
-                for (var key in this._assets) {
-                    var asset = this._assets[key];
-                    if (asset instanceof webgl.Texture)
-                        asset.dispose();
-                }
-                this._assets = {};
-            };
-            AssetManager.prototype.isLoadingComplete = function () {
-                return this._toLoad == 0;
+            GLTexture.prototype.setFilters = function (minFilter, magFilter) {
+                var gl = this._gl;
+                this.bind();
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
             };
-            AssetManager.prototype.toLoad = function () {
-                return this._toLoad;
+            GLTexture.prototype.setWraps = function (uWrap, vWrap) {
+                var gl = this._gl;
+                this.bind();
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
             };
-            AssetManager.prototype.loaded = function () {
-                return this._loaded;
+            GLTexture.prototype.update = function (useMipMaps) {
+                var gl = this._gl;
+                this.bind();
+                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useMipMaps ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+                if (useMipMaps)
+                    gl.generateMipmap(gl.TEXTURE_2D);
             };
-            AssetManager.prototype.dispose = function () {
-                this.removeAll();
+            GLTexture.prototype.bind = function (unit) {
+                if (unit === void 0) { unit = 0; }
+                var gl = this._gl;
+                this._boundUnit = unit;
+                gl.activeTexture(gl.TEXTURE0 + unit);
+                gl.bindTexture(gl.TEXTURE_2D, this._texture);
             };
-            AssetManager.prototype.hasErrors = function () {
-                return Object.keys(this._errors).length > 0;
+            GLTexture.prototype.unbind = function () {
+                var gl = this._gl;
+                gl.activeTexture(gl.TEXTURE0 + this._boundUnit);
+                gl.bindTexture(gl.TEXTURE_2D, null);
             };
-            AssetManager.prototype.errors = function () {
-                return this._errors;
+            GLTexture.prototype.dispose = function () {
+                var gl = this._gl;
+                gl.deleteTexture(this._texture);
             };
-            return AssetManager;
-        }());
-        webgl.AssetManager = AssetManager;
+            return GLTexture;
+        }(spine.Texture));
+        webgl.GLTexture = GLTexture;
     })(webgl = spine.webgl || (spine.webgl = {}));
 })(spine || (spine = {}));
 /******************************************************************************
@@ -6095,323 +6381,6 @@ var spine;
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 var spine;
-(function (spine) {
-    var webgl;
-    (function (webgl) {
-        var Texture = (function () {
-            function Texture(gl, image, useMipMaps) {
-                if (useMipMaps === void 0) { useMipMaps = false; }
-                this._boundUnit = 0;
-                this._gl = gl;
-                this._texture = gl.createTexture();
-                this._image = image;
-                this.update(useMipMaps);
-            }
-            Texture.prototype.getImage = function () {
-                return this._image;
-            };
-            Texture.prototype.setFilters = function (minFilter, magFilter) {
-                var gl = this._gl;
-                this.bind();
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
-            };
-            Texture.prototype.setWraps = function (uWrap, vWrap) {
-                var gl = this._gl;
-                this.bind();
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
-            };
-            Texture.prototype.update = function (useMipMaps) {
-                var gl = this._gl;
-                this.bind();
-                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._image);
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, useMipMaps ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-                if (useMipMaps)
-                    gl.generateMipmap(gl.TEXTURE_2D);
-            };
-            Texture.prototype.bind = function (unit) {
-                if (unit === void 0) { unit = 0; }
-                var gl = this._gl;
-                this._boundUnit = unit;
-                gl.activeTexture(gl.TEXTURE0 + unit);
-                gl.bindTexture(gl.TEXTURE_2D, this._texture);
-            };
-            Texture.prototype.unbind = function () {
-                var gl = this._gl;
-                gl.activeTexture(gl.TEXTURE0 + this._boundUnit);
-                gl.bindTexture(gl.TEXTURE_2D, null);
-            };
-            Texture.prototype.dispose = function () {
-                var gl = this._gl;
-                gl.deleteTexture(this._texture);
-            };
-            Texture.filterFromString = function (text) {
-                switch (text.toLowerCase()) {
-                    case "nearest": return TextureFilter.Nearest;
-                    case "linear": return TextureFilter.Linear;
-                    case "mipmap": return TextureFilter.MipMap;
-                    case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest;
-                    case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest;
-                    case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear;
-                    case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear;
-                    default: throw new Error("Unknown texture filter " + text);
-                }
-            };
-            Texture.wrapFromString = function (text) {
-                switch (text.toLowerCase()) {
-                    case "mirroredtepeat": return TextureWrap.MirroredRepeat;
-                    case "clamptoedge": return TextureWrap.ClampToEdge;
-                    case "repeat": return TextureWrap.Repeat;
-                    default: throw new Error("Unknown texture wrap " + text);
-                }
-            };
-            return Texture;
-        }());
-        webgl.Texture = Texture;
-        (function (TextureFilter) {
-            TextureFilter[TextureFilter["Nearest"] = WebGLRenderingContext.NEAREST] = "Nearest";
-            TextureFilter[TextureFilter["Linear"] = WebGLRenderingContext.LINEAR] = "Linear";
-            TextureFilter[TextureFilter["MipMap"] = WebGLRenderingContext.LINEAR_MIPMAP_LINEAR] = "MipMap";
-            TextureFilter[TextureFilter["MipMapNearestNearest"] = WebGLRenderingContext.NEAREST_MIPMAP_NEAREST] = "MipMapNearestNearest";
-            TextureFilter[TextureFilter["MipMapLinearNearest"] = WebGLRenderingContext.LINEAR_MIPMAP_NEAREST] = "MipMapLinearNearest";
-            TextureFilter[TextureFilter["MipMapNearestLinear"] = WebGLRenderingContext.NEAREST_MIPMAP_LINEAR] = "MipMapNearestLinear";
-            TextureFilter[TextureFilter["MipMapLinearLinear"] = WebGLRenderingContext.LINEAR_MIPMAP_LINEAR] = "MipMapLinearLinear";
-        })(webgl.TextureFilter || (webgl.TextureFilter = {}));
-        var TextureFilter = webgl.TextureFilter;
-        (function (TextureWrap) {
-            TextureWrap[TextureWrap["MirroredRepeat"] = WebGLRenderingContext.MIRRORED_REPEAT] = "MirroredRepeat";
-            TextureWrap[TextureWrap["ClampToEdge"] = WebGLRenderingContext.CLAMP_TO_EDGE] = "ClampToEdge";
-            TextureWrap[TextureWrap["Repeat"] = WebGLRenderingContext.REPEAT] = "Repeat";
-        })(webgl.TextureWrap || (webgl.TextureWrap = {}));
-        var TextureWrap = webgl.TextureWrap;
-    })(webgl = spine.webgl || (spine.webgl = {}));
-})(spine || (spine = {}));
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-var spine;
-(function (spine) {
-    var webgl;
-    (function (webgl) {
-        var TextureAtlas = (function () {
-            function TextureAtlas(atlasText, textureLoader) {
-                this.pages = new Array();
-                this.regions = new Array();
-                this.load(atlasText, textureLoader);
-            }
-            TextureAtlas.prototype.load = function (atlasText, textureLoader) {
-                if (textureLoader == null)
-                    throw new Error("textureLoader cannot be null.");
-                var reader = new TextureAtlasReader(atlasText);
-                var tuple = new Array(4);
-                var page = null;
-                while (true) {
-                    var line = reader.readLine();
-                    if (line == null)
-                        break;
-                    line = line.trim();
-                    if (line.length == 0)
-                        page = null;
-                    else if (!page) {
-                        page = new TextureAtlasPage();
-                        page.name = line;
-                        if (reader.readTuple(tuple) == 2) {
-                            page.width = parseInt(tuple[0]);
-                            page.height = parseInt(tuple[1]);
-                            reader.readTuple(tuple);
-                        }
-                        // page.format = Format[tuple[0]]; we don't need format in WebGL
-                        reader.readTuple(tuple);
-                        page.minFilter = webgl.Texture.filterFromString(tuple[0]);
-                        page.magFilter = webgl.Texture.filterFromString(tuple[1]);
-                        var direction = reader.readValue();
-                        page.uWrap = webgl.TextureWrap.ClampToEdge;
-                        page.vWrap = webgl.TextureWrap.ClampToEdge;
-                        if (direction == "x")
-                            page.uWrap = webgl.TextureWrap.Repeat;
-                        else if (direction == "y")
-                            page.vWrap = webgl.TextureWrap.Repeat;
-                        else if (direction == "xy")
-                            page.uWrap = page.vWrap = webgl.TextureWrap.Repeat;
-                        page.texture = textureLoader(line);
-                        page.texture.setFilters(page.minFilter, page.magFilter);
-                        page.texture.setWraps(page.uWrap, page.vWrap);
-                        page.width = page.texture.getImage().width;
-                        page.height = page.texture.getImage().height;
-                        this.pages.push(page);
-                    }
-                    else {
-                        var region = new TextureAtlasRegion();
-                        region.name = line;
-                        region.page = page;
-                        region.rotate = reader.readValue() == "true";
-                        reader.readTuple(tuple);
-                        var x = parseInt(tuple[0]);
-                        var y = parseInt(tuple[1]);
-                        reader.readTuple(tuple);
-                        var width = parseInt(tuple[0]);
-                        var height = parseInt(tuple[1]);
-                        region.u = x / page.width;
-                        region.v = y / page.height;
-                        if (region.rotate) {
-                            region.u2 = (x + height) / page.width;
-                            region.v2 = (y + width) / page.height;
-                        }
-                        else {
-                            region.u2 = (x + width) / page.width;
-                            region.v2 = (y + height) / page.height;
-                        }
-                        region.x = x;
-                        region.y = y;
-                        region.width = Math.abs(width);
-                        region.height = Math.abs(height);
-                        if (reader.readTuple(tuple) == 4) {
-                            // region.splits = new Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
-                            if (reader.readTuple(tuple) == 4) {
-                                //region.pads = Vector.<int>(parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3]));
-                                reader.readTuple(tuple);
-                            }
-                        }
-                        region.originalWidth = parseInt(tuple[0]);
-                        region.originalHeight = parseInt(tuple[1]);
-                        reader.readTuple(tuple);
-                        region.offsetX = parseInt(tuple[0]);
-                        region.offsetY = parseInt(tuple[1]);
-                        region.index = parseInt(reader.readValue());
-                        region.texture = page.texture;
-                        this.regions.push(region);
-                    }
-                }
-            };
-            TextureAtlas.prototype.findRegion = function (name) {
-                for (var i = 0; i < this.regions.length; i++) {
-                    if (this.regions[i].name == name) {
-                        return this.regions[i];
-                    }
-                }
-                return null;
-            };
-            TextureAtlas.prototype.dispose = function () {
-                for (var i = 0; i < this.pages.length; i++) {
-                    this.pages[i].texture.dispose();
-                }
-            };
-            return TextureAtlas;
-        }());
-        webgl.TextureAtlas = TextureAtlas;
-        var TextureAtlasReader = (function () {
-            function TextureAtlasReader(text) {
-                this.index = 0;
-                this.lines = text.split(/\r\n|\r|\n/);
-            }
-            TextureAtlasReader.prototype.readLine = function () {
-                if (this.index >= this.lines.length)
-                    return null;
-                return this.lines[this.index++];
-            };
-            TextureAtlasReader.prototype.readValue = function () {
-                var line = this.readLine();
-                var colon = line.indexOf(":");
-                if (colon == -1)
-                    throw new Error("Invalid line: " + line);
-                return line.substring(colon + 1).trim();
-            };
-            TextureAtlasReader.prototype.readTuple = function (tuple) {
-                var line = this.readLine();
-                var colon = line.indexOf(":");
-                if (colon == -1)
-                    throw new Error("Invalid line: " + line);
-                var i = 0, lastMatch = colon + 1;
-                for (; i < 3; i++) {
-                    var comma = line.indexOf(",", lastMatch);
-                    if (comma == -1)
-                        break;
-                    tuple[i] = line.substr(lastMatch, comma - lastMatch).trim();
-                    lastMatch = comma + 1;
-                }
-                tuple[i] = line.substring(lastMatch).trim();
-                return i + 1;
-            };
-            return TextureAtlasReader;
-        }());
-        var TextureAtlasPage = (function () {
-            function TextureAtlasPage() {
-            }
-            return TextureAtlasPage;
-        }());
-        webgl.TextureAtlasPage = TextureAtlasPage;
-        var TextureAtlasRegion = (function (_super) {
-            __extends(TextureAtlasRegion, _super);
-            function TextureAtlasRegion() {
-                _super.apply(this, arguments);
-            }
-            return TextureAtlasRegion;
-        }(spine.TextureRegion));
-        webgl.TextureAtlasRegion = TextureAtlasRegion;
-    })(webgl = spine.webgl || (spine.webgl = {}));
-})(spine || (spine = {}));
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.5
- *
- * Copyright (c) 2013-2016, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable, and
- * non-transferable license to use, install, execute, and perform the Spine
- * Runtimes software and derivative works solely for personal or internal
- * use. Without the written permission of Esoteric Software (see Section 2 of
- * the Spine Software License Agreement), you may not (a) modify, translate,
- * adapt, or develop new applications using the Spine Runtimes or otherwise
- * create derivative works or improvements of the Spine Runtimes or (b) remove,
- * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
- * or other intellectual property or proprietary rights notices on or in the
- * Software, including any copy thereof. Redistributions in binary or source
- * form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
- * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-var spine;
 (function (spine) {
     var webgl;
     (function (webgl) {
@@ -6673,7 +6642,9 @@ var spine;
             this._batcher = new spine.webgl.PolygonBatcher(gl);
             this._mvp.ortho2d(0, 0, 639, 479);
             this._skeletonRenderer = new spine.webgl.SkeletonRenderer(gl);
-            var assets = this._assetManager = new spine.webgl.AssetManager(gl);
+            var assets = this._assetManager = new spine.AssetManager(function (image) {
+                return new spine.webgl.GLTexture(gl, image);
+            });
             assets.loadText(config.atlas);
             assets.loadText(config.json);
             assets.loadTexture(config.atlas.replace(".atlas", ".png"));
@@ -6728,8 +6699,11 @@ var spine;
                     else
                         throw new Error("Failed to load assets: " + JSON.stringify(assetManager.errors));
                 }
-                var atlas = new spine.webgl.TextureAtlas(this._assetManager.get(this._config.atlas), function (path) {
-                    return assetManager.get(imagesPath + path);
+                var atlas = new spine.TextureAtlas(this._assetManager.get(this._config.atlas), function (path, minFilter, magFilter, uWrap, vWrap) {
+                    var texture = assetManager.get(imagesPath + path);
+                    texture.setFilters(minFilter, magFilter);
+                    texture.setWraps(uWrap, vWrap);
+                    return texture;
                 });
                 var atlasLoader = new spine.webgl.TextureAtlasAttachmentLoader(atlas);
                 var skeletonJson = new spine.SkeletonJson(atlasLoader);

Plik diff jest za duży
+ 0 - 0
spine-ts/build/spine-widget.js.map


+ 293 - 0
spine-ts/canvas/example/assets/goblins-mesh.atlas

@@ -0,0 +1,293 @@
+
+goblins-mesh.png
+size: 1024,128
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+dagger
+  rotate: true
+  xy: 372, 100
+  size: 26, 108
+  orig: 26, 108
+  offset: 0, 0
+  index: -1
+goblin/eyes-closed
+  rotate: false
+  xy: 2, 7
+  size: 34, 12
+  orig: 34, 12
+  offset: 0, 0
+  index: -1
+goblin/head
+  rotate: false
+  xy: 107, 36
+  size: 103, 66
+  orig: 103, 66
+  offset: 0, 0
+  index: -1
+goblin/left-arm
+  rotate: false
+  xy: 901, 56
+  size: 37, 35
+  orig: 37, 35
+  offset: 0, 0
+  index: -1
+goblin/left-foot
+  rotate: false
+  xy: 929, 95
+  size: 65, 31
+  orig: 65, 31
+  offset: 0, 0
+  index: -1
+goblin/left-hand
+  rotate: false
+  xy: 452, 2
+  size: 36, 41
+  orig: 36, 41
+  offset: 0, 0
+  index: -1
+goblin/left-lower-leg
+  rotate: true
+  xy: 713, 93
+  size: 33, 70
+  orig: 33, 70
+  offset: 0, 0
+  index: -1
+goblin/left-shoulder
+  rotate: false
+  xy: 610, 44
+  size: 29, 44
+  orig: 29, 44
+  offset: 0, 0
+  index: -1
+goblin/left-upper-leg
+  rotate: true
+  xy: 638, 93
+  size: 33, 73
+  orig: 33, 73
+  offset: 0, 0
+  index: -1
+goblin/neck
+  rotate: false
+  xy: 490, 2
+  size: 36, 41
+  orig: 36, 41
+  offset: 0, 0
+  index: -1
+goblin/pelvis
+  rotate: false
+  xy: 482, 45
+  size: 62, 43
+  orig: 62, 43
+  offset: 0, 0
+  index: -1
+goblin/right-arm
+  rotate: true
+  xy: 690, 2
+  size: 23, 50
+  orig: 23, 50
+  offset: 0, 0
+  index: -1
+goblin/right-foot
+  rotate: false
+  xy: 771, 58
+  size: 63, 33
+  orig: 63, 33
+  offset: 0, 0
+  index: -1
+goblin/right-hand
+  rotate: false
+  xy: 940, 56
+  size: 36, 37
+  orig: 36, 37
+  offset: 0, 0
+  index: -1
+goblin/right-lower-leg
+  rotate: true
+  xy: 482, 90
+  size: 36, 76
+  orig: 36, 76
+  offset: 0, 0
+  index: -1
+goblin/right-shoulder
+  rotate: true
+  xy: 602, 3
+  size: 39, 45
+  orig: 39, 45
+  offset: 0, 0
+  index: -1
+goblin/right-upper-leg
+  rotate: true
+  xy: 641, 57
+  size: 34, 63
+  orig: 34, 63
+  offset: 0, 0
+  index: -1
+goblin/torso
+  rotate: true
+  xy: 212, 34
+  size: 68, 96
+  orig: 68, 96
+  offset: 0, 0
+  index: -1
+goblin/undie-straps
+  rotate: false
+  xy: 380, 5
+  size: 55, 19
+  orig: 55, 19
+  offset: 0, 0
+  index: -1
+goblin/undies
+  rotate: false
+  xy: 174, 5
+  size: 36, 29
+  orig: 36, 29
+  offset: 0, 0
+  index: -1
+goblingirl/eyes-closed
+  rotate: false
+  xy: 269, 11
+  size: 37, 21
+  orig: 37, 21
+  offset: 0, 0
+  index: -1
+goblingirl/head
+  rotate: false
+  xy: 2, 21
+  size: 103, 81
+  orig: 103, 81
+  offset: 0, 0
+  index: -1
+goblingirl/left-arm
+  rotate: true
+  xy: 978, 56
+  size: 37, 35
+  orig: 37, 35
+  offset: 0, 0
+  index: -1
+goblingirl/left-foot
+  rotate: false
+  xy: 107, 3
+  size: 65, 31
+  orig: 65, 31
+  offset: 0, 0
+  index: -1
+goblingirl/left-hand
+  rotate: false
+  xy: 565, 2
+  size: 35, 40
+  orig: 35, 40
+  offset: 0, 0
+  index: -1
+goblingirl/left-lower-leg
+  rotate: true
+  xy: 785, 93
+  size: 33, 70
+  orig: 33, 70
+  offset: 0, 0
+  index: -1
+goblingirl/left-shoulder
+  rotate: true
+  xy: 690, 27
+  size: 28, 46
+  orig: 28, 46
+  offset: 0, 0
+  index: -1
+goblingirl/left-upper-leg
+  rotate: true
+  xy: 857, 93
+  size: 33, 70
+  orig: 33, 70
+  offset: 0, 0
+  index: -1
+goblingirl/neck
+  rotate: false
+  xy: 528, 2
+  size: 35, 41
+  orig: 35, 41
+  offset: 0, 0
+  index: -1
+goblingirl/pelvis
+  rotate: false
+  xy: 546, 45
+  size: 62, 43
+  orig: 62, 43
+  offset: 0, 0
+  index: -1
+goblingirl/right-arm
+  rotate: false
+  xy: 452, 48
+  size: 28, 50
+  orig: 28, 50
+  offset: 0, 0
+  index: -1
+goblingirl/right-foot
+  rotate: false
+  xy: 836, 58
+  size: 63, 33
+  orig: 63, 33
+  offset: 0, 0
+  index: -1
+goblingirl/right-hand
+  rotate: true
+  xy: 771, 20
+  size: 36, 37
+  orig: 36, 37
+  offset: 0, 0
+  index: -1
+goblingirl/right-lower-leg
+  rotate: true
+  xy: 560, 90
+  size: 36, 76
+  orig: 36, 76
+  offset: 0, 0
+  index: -1
+goblingirl/right-shoulder
+  rotate: false
+  xy: 649, 10
+  size: 39, 45
+  orig: 39, 45
+  offset: 0, 0
+  index: -1
+goblingirl/right-upper-leg
+  rotate: true
+  xy: 706, 57
+  size: 34, 63
+  orig: 34, 63
+  offset: 0, 0
+  index: -1
+goblingirl/torso
+  rotate: false
+  xy: 310, 2
+  size: 68, 96
+  orig: 68, 96
+  offset: 0, 0
+  index: -1
+goblingirl/undie-straps
+  rotate: false
+  xy: 212, 13
+  size: 55, 19
+  orig: 55, 19
+  offset: 0, 0
+  index: -1
+goblingirl/undies
+  rotate: false
+  xy: 810, 27
+  size: 36, 29
+  orig: 36, 29
+  offset: 0, 0
+  index: -1
+shield
+  rotate: false
+  xy: 380, 26
+  size: 70, 72
+  orig: 70, 72
+  offset: 0, 0
+  index: -1
+spear
+  rotate: true
+  xy: 2, 104
+  size: 22, 368
+  orig: 22, 368
+  offset: 0, 0
+  index: -1

+ 1082 - 0
spine-ts/canvas/example/assets/goblins-mesh.json

@@ -0,0 +1,1082 @@
+{
+"skeleton": { "hash": "P7CQ4ImK+tcAICATgSttlZ5HOSM", "spine": "3.4.00", "width": 0, "height": 0, "images": "./images/" },
+"bones": [
+	{ "name": "root" },
+	{ "name": "hip", "parent": "root", "x": 0.64, "y": 114.41 },
+	{ "name": "torso", "parent": "hip", "length": 85.82, "rotation": 93.92, "x": -6.42, "y": 1.97 },
+	{ "name": "neck", "parent": "torso", "length": 18.38, "rotation": -1.51, "x": 81.67, "y": -6.34 },
+	{ "name": "head", "parent": "neck", "length": 68.28, "rotation": -13.92, "x": 20.93, "y": 11.59 },
+	{ "name": "left shoulder", "parent": "torso", "length": 35.43, "rotation": -156.96, "x": 74.04, "y": -20.38 },
+	{ "name": "left arm", "parent": "left shoulder", "length": 35.62, "rotation": 28.16, "x": 37.85, "y": -2.34 },
+	{ "name": "left upper leg", "parent": "hip", "length": 50.39, "rotation": -89.09, "x": 14.45, "y": 2.81 },
+	{ "name": "left lower leg", "parent": "left upper leg", "length": 49.89, "rotation": -16.65, "x": 56.34, "y": 0.98 },
+	{ "name": "left foot", "parent": "left lower leg", "length": 46.5, "rotation": 102.43, "x": 58.94, "y": -7.61 },
+	{ "name": "left hand", "parent": "left arm", "length": 11.52, "rotation": 2.7, "x": 35.62, "y": 0.07 },
+	{ "name": "pelvis", "parent": "hip", "x": 1.41, "y": -6.57 },
+	{ "name": "right shoulder", "parent": "torso", "length": 37.24, "rotation": 133.88, "x": 76.02, "y": 18.14 },
+	{ "name": "right arm", "parent": "right shoulder", "length": 36.74, "rotation": 36.32, "x": 37.6, "y": 0.31 },
+	{ "name": "right upper leg", "parent": "hip", "length": 42.45, "rotation": -97.49, "x": -20.07, "y": -6.83 },
+	{ "name": "right lower leg", "parent": "right upper leg", "length": 58.52, "rotation": -14.34, "x": 42.99, "y": -0.61 },
+	{ "name": "right foot", "parent": "right lower leg", "length": 45.45, "rotation": 110.3, "x": 64.88, "y": 0.04 },
+	{ "name": "right hand", "parent": "right arm", "length": 15.32, "rotation": 2.35, "x": 36.9, "y": 0.34 },
+	{ "name": "spear1", "parent": "left hand", "length": 65.06, "rotation": 102.43, "x": 0.48, "y": 17.03 },
+	{ "name": "spear2", "parent": "spear1", "length": 61.41, "rotation": 0.9, "x": 65.05, "y": 0.04 },
+	{ "name": "spear3", "parent": "spear2", "length": 76.79, "rotation": -0.9, "x": 61.88, "y": 0.57 }
+],
+"slots": [
+	{ "name": "left shoulder", "bone": "left shoulder", "attachment": "left shoulder" },
+	{ "name": "left arm", "bone": "left arm", "attachment": "left arm" },
+	{ "name": "left hand item", "bone": "left hand", "attachment": "spear" },
+	{ "name": "left hand", "bone": "left hand", "attachment": "left hand" },
+	{ "name": "left foot", "bone": "left foot", "attachment": "left foot" },
+	{ "name": "left lower leg", "bone": "left lower leg", "attachment": "left lower leg" },
+	{ "name": "left upper leg", "bone": "left upper leg", "attachment": "left upper leg" },
+	{ "name": "neck", "bone": "neck", "attachment": "neck" },
+	{ "name": "torso", "bone": "torso", "attachment": "torso" },
+	{ "name": "pelvis", "bone": "pelvis", "attachment": "pelvis" },
+	{ "name": "right foot", "bone": "right foot", "attachment": "right foot" },
+	{ "name": "right lower leg", "bone": "right lower leg", "attachment": "right lower leg" },
+	{ "name": "undie straps", "bone": "pelvis", "attachment": "undie straps" },
+	{ "name": "undies", "bone": "pelvis", "attachment": "undies" },
+	{ "name": "right upper leg", "bone": "right upper leg", "attachment": "right upper leg" },
+	{ "name": "head", "bone": "head", "attachment": "head" },
+	{ "name": "eyes", "bone": "head" },
+	{ "name": "right shoulder", "bone": "right shoulder", "attachment": "right shoulder" },
+	{ "name": "right arm", "bone": "right arm", "attachment": "right arm" },
+	{ "name": "right hand thumb", "bone": "right hand", "attachment": "right hand thumb" },
+	{ "name": "right hand item", "bone": "right hand", "attachment": "dagger" },
+	{ "name": "right hand", "bone": "right hand", "attachment": "right hand" },
+	{ "name": "right hand item 2", "bone": "right hand", "attachment": "shield" }
+],
+"skins": {
+	"default": {
+		"left hand item": {
+			"dagger": { "x": 7.88, "y": -23.45, "rotation": 10.47, "width": 26, "height": 108 },
+			"spear": {
+				"type": "mesh",
+				"uvs": [ 1, 0.11236, 0.77096, 0.13278, 0.76608, 0.21781, 0.75642, 0.386, 0.74723, 0.54607, 0.72117, 1, 0.28838, 1, 0.24208, 0.54327, 0.22589, 0.38361, 0.2089, 0.21605, 0.20043, 0.13242, 0, 0.11519, 0.4527, 0, 0.58399, 0 ],
+				"triangles": [ 4, 7, 3, 6, 7, 4, 5, 6, 4, 10, 11, 12, 1, 13, 0, 12, 13, 1, 10, 12, 1, 9, 10, 1, 2, 9, 1, 8, 9, 2, 3, 8, 2, 7, 8, 3 ],
+				"vertices": [ 1, 20, 38.54, -10.88, 1, 1, 20, 30.97, -5.93, 1, 2, 19, 61.48, -5.58, 0.5116, 20, -0.31, -6.16, 0.48839, 2, 18, 64.73, -5.03, 0.50272, 19, -0.4, -5.06, 0.49728, 1, 10, 4.56, 23.91, 1, 1, 10, 41.7, -138.95, 1, 1, 10, 32.41999, -141.1, 1, 1, 10, -6.49, 22.4, 1, 2, 18, 65.48, 6.64, 0.50272, 19, 0.52999, 6.59, 0.49728, 2, 19, 62.18, 6.66, 0.5116, 20, 0.2, 6.09, 0.48839, 1, 20, 30.96, 6.61, 1, 1, 20, 37.25999, 11.09, 1, 1, 20, 79.75, 1.59, 1, 1, 20, 79.78, -1.29, 1 ],
+				"hull": 14,
+				"edges": [ 24, 22, 22, 20, 10, 12, 2, 0, 24, 26, 0, 26, 8, 10, 12, 14, 6, 8, 14, 16, 2, 4, 4, 6, 16, 18, 18, 20, 20, 2 ],
+				"width": 22,
+				"height": 368
+			}
+		},
+		"right hand item": {
+			"dagger": {
+				"type": "mesh",
+				"uvs": [ 0.78091, 0.38453, 1, 0.38405, 1, 0.44881, 0.73953, 0.4687, 0.74641, 0.81344, 0.34022, 1, 0.15434, 1, 0.11303, 0.78858, 0.23007, 0.47367, 0, 0.45047, 0, 0.38621, 0.22367, 0.38573, 0.24384, 0, 1, 0 ],
+				"triangles": [ 0, 12, 13, 11, 12, 0, 0, 1, 2, 9, 10, 11, 3, 11, 0, 3, 0, 2, 8, 11, 3, 9, 11, 8, 5, 6, 7, 4, 5, 8, 4, 8, 3, 5, 7, 8 ],
+				"vertices": [ 15.49, -12.82, 21.13, -13.57, 20.16, -20.49, 13.15, -21.67, 8.13, -58.56, -5.13, -77.04, -9.92, -76.36, -7.79, -53.6, -0.03, -20.36, -5.6, -17.04, -4.63, -10.17, 1.12, -10.93, 7.46, 30.24, 26.93, 27.49 ],
+				"hull": 14,
+				"edges": [ 22, 20, 24, 26, 22, 24, 2, 0, 0, 22, 0, 26, 12, 14, 14, 16, 18, 20, 16, 18, 2, 4, 4, 6, 6, 8, 10, 12, 8, 10 ],
+				"width": 26,
+				"height": 108
+			}
+		},
+		"right hand item 2": {
+			"shield": { "rotation": 93.49, "width": 70, "height": 72 }
+		}
+	},
+	"goblin": {
+		"eyes": {
+			"eyes closed": { "name": "goblin/eyes-closed", "x": 29.19, "y": -24.89, "rotation": -88.92, "width": 34, "height": 12 }
+		},
+		"head": {
+			"head": {
+				"name": "goblin/head",
+				"type": "mesh",
+				"uvs": [ 0, 0.60494, 0.14172, 0.5145, 0.24218, 0.55229, 0.32667, 0.67806, 0.37969, 0.79352, 0.53505, 0.93014, 0.86056, 1, 0.94071, 0.94169, 0.92098, 0.69923, 0.9888, 0.65497, 0.99003, 0.51643, 0.89632, 0.43561, 0.94487, 0.41916, 1, 0.39713, 1, 0.2836, 0.94017, 0.27027, 0.87906, 0.25666, 0.80754, 0.16044, 0.66698, 0.01997, 0.4734, 0.01805, 0.29215, 0.19893, 0.25392, 0.31823, 0.09117, 0.324, 0, 0.44331, 0.43271, 0.69153, 0.466, 0.47794, 0.35996, 0.31246, 0.73473, 0.68593, 0.72215, 0.57425, 0.88179, 0.5583, 0.80267, 0.51015 ],
+				"triangles": [ 5, 27, 6, 7, 27, 8, 7, 6, 27, 4, 24, 5, 5, 24, 27, 4, 3, 24, 27, 29, 8, 8, 29, 9, 24, 28, 27, 24, 25, 28, 24, 3, 25, 29, 28, 30, 29, 27, 28, 25, 2, 26, 25, 3, 2, 9, 29, 10, 0, 23, 1, 28, 25, 30, 29, 11, 10, 29, 30, 11, 2, 21, 26, 2, 1, 21, 23, 22, 1, 1, 22, 21, 30, 16, 11, 30, 17, 16, 30, 25, 17, 17, 26, 18, 18, 26, 19, 26, 17, 25, 11, 15, 12, 11, 16, 15, 12, 15, 13, 15, 14, 13, 21, 20, 26, 26, 20, 19 ],
+				"vertices": [ 14.56, 50.42, 23.12, 35.47, 17.45999, 26.36, 11.57, 16.86, 3.74, 11.71, -5.89, -3.91, -11.83, -37.23, -8.31, -45.63, 7.75, -44.24, 10.39, -51.33, 19.52, -51.82, 25.21, -43.15, 26.12, -47.43, 27.35, -53.16, 34.84, -53.46, 35.96, -47.33, 37.11, -41.08, 43.75, -33.97, 53.58, -19.87, 54.5, 0.03, 43.31, 19.16, 35.59999, 23.41, 35.89, 40.16999, 28.39, 49.87, 10.25, 5.99, 24.2, 2, 35.55, 12.48, 9.39, -25.1, 16.79999, -24.31, 17.2, -40.65, 20.68, -33.02 ],
+				"hull": 24,
+				"edges": [ 0, 2, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 26, 28, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 0, 46, 6, 48, 48, 50, 50, 52, 52, 42, 2, 4, 4, 6, 4, 52, 2, 44, 22, 32, 22, 24, 24, 26, 28, 30, 30, 32, 24, 30, 16, 54, 54, 56, 20, 58, 58, 54, 16, 58, 22, 60, 60, 56, 58, 60 ],
+				"width": 103,
+				"height": 66
+			}
+		},
+		"left arm": {
+			"left arm": {
+				"name": "goblin/left-arm",
+				"type": "mesh",
+				"uvs": [ 0.68992, 0.29284, 1, 0.46364, 1, 0.74643, 0.84089, 1, 0.66344, 1, 0.33765, 0.64284, 0, 0.44124, 0, 0, 0.34295, 0 ],
+				"triangles": [ 3, 4, 2, 4, 5, 2, 5, 0, 2, 0, 1, 2, 0, 5, 8, 5, 6, 8, 6, 7, 8 ],
+				"vertices": [ 18.6, 8.81, 32.18999, 10.31, 38.02, 1.62, 38.08, -9.63, 32.31, -13.49, 14.37, -9.62, -0.75, -10.78, -9.84, 2.77, 1.29, 10.25 ],
+				"hull": 9,
+				"edges": [ 14, 16, 16, 0, 0, 2, 2, 4, 6, 4, 6, 8, 8, 10, 12, 14, 10, 12 ],
+				"width": 37,
+				"height": 35
+			}
+		},
+		"left foot": {
+			"left foot": {
+				"name": "goblin/left-foot",
+				"type": "mesh",
+				"uvs": [ 0.15733, 0.31873, 0.08195, 0.78502, 0.15884, 0.99366, 0.41633, 0.96804, 0.68822, 0.97636, 1, 0.96388, 0.99385, 0.73501, 0.85294, 0.51862, 0.61479, 0.31056, 0.46991, 0, 0.48032, 0.75604, 0.75994, 0.77706 ],
+				"triangles": [ 0, 9, 8, 10, 0, 8, 10, 8, 7, 11, 10, 7, 11, 7, 6, 1, 0, 10, 11, 6, 5, 3, 1, 10, 4, 10, 11, 4, 11, 5, 3, 10, 4, 2, 1, 3 ],
+				"vertices": [ 2.28, 13.07, -1.76, -1.64, 3.59, -7.8, 20.25, -6.04, 37.91, -5.27, 58.12, -3.71, 57.31, 3.34, 47.78, 9.51, 31.95, 15.05, 21.99, 24.11, 24.03, 0.75, 42.21, 1.16 ],
+				"hull": 10,
+				"edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 0, 18, 6, 20, 20, 16, 2, 20, 8, 22, 22, 14, 20, 22, 22, 10 ],
+				"width": 65,
+				"height": 31
+			}
+		},
+		"left hand": {
+			"left hand": {
+				"name": "goblin/left-hand",
+				"type": "mesh",
+				"uvs": [ 0.518, 0.12578, 1, 0.16285, 0.99788, 0.50578, 0.69745, 1, 0.37445, 1, 0, 0.80051, 0, 0.42792, 0.17601, 0, 0.43567, 0 ],
+				"triangles": [ 2, 0, 1, 0, 5, 6, 6, 7, 0, 0, 7, 8, 3, 4, 0, 4, 5, 0, 2, 3, 0 ],
+				"vertices": [ -3.11, 15.42, 10.83, 22.27, 15.5, 14.55, 18.35, -8.96, 9.47999, -14.32, -4.58, -14.3, -11.63, -2.63, -14.89, 13.68, -7.75, 17.99 ],
+				"hull": 9,
+				"edges": [ 16, 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 14, 16, 12, 14 ],
+				"width": 36,
+				"height": 41
+			}
+		},
+		"left lower leg": {
+			"left lower leg": {
+				"name": "goblin/left-lower-leg",
+				"type": "mesh",
+				"uvs": [ 0.95508, 0.20749, 0.81927, 0.65213, 0.94754, 0.77308, 0.67842, 0.97346, 0.46463, 1, 0.26845, 1, 0.04963, 0.90706, 0.2106, 0.60115, 0.07478, 0.40195, 0.18545, 0, 0.28857, 0 ],
+				"triangles": [ 10, 8, 9, 1, 7, 10, 7, 8, 10, 0, 1, 10, 1, 4, 7, 3, 1, 2, 5, 6, 7, 7, 4, 5, 1, 3, 4 ],
+				"vertices": [ -0.19, 6.82, 30.97, 10.96, 37.97, 17.33, 53.88, 12.6, 57.58, 6.31, 59.34, 0.08, 55.04, -8.63, 32.99, -9.33, 20.79, -17.43, -7.27, -21.56, -8.18999, -18.29 ],
+				"hull": 11,
+				"edges": [ 20, 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 18, 20, 16, 18 ],
+				"width": 33,
+				"height": 70
+			}
+		},
+		"left shoulder": {
+			"left shoulder": {
+				"name": "goblin/left-shoulder",
+				"type": "mesh",
+				"uvs": [ 0.7377, 0.40692, 1, 0.75237, 1, 1, 0.62046, 1, 0.26184, 0.56601, 0, 0.29783, 0, 0, 0.44115, 0 ],
+				"triangles": [ 3, 1, 2, 3, 0, 1, 3, 4, 0, 4, 7, 0, 4, 5, 7, 5, 6, 7 ],
+				"vertices": [ 15.18, 5.74, 32.16999, 5.32, 41.79, 0.21, 36.63, -9.5, 14.88, -9.72, 0.9, -10.89, -10.66, -4.73999, -4.66, 6.54 ],
+				"hull": 8,
+				"edges": [ 12, 14, 14, 0, 4, 2, 0, 2, 4, 6, 6, 8, 10, 12, 8, 10 ],
+				"width": 29,
+				"height": 44
+			}
+		},
+		"left upper leg": {
+			"left upper leg": {
+				"name": "goblin/left-upper-leg",
+				"type": "mesh",
+				"uvs": [ 1, 0.12167, 1, 0.54873, 0.91067, 0.78907, 0.76567, 1, 0.3087, 0.9579, 0, 0.68777, 0, 0.219, 0.51961, 0, 0.87552, 0 ],
+				"triangles": [ 7, 8, 0, 5, 6, 7, 0, 1, 7, 4, 5, 7, 1, 4, 7, 2, 4, 1, 3, 4, 2 ],
+				"vertices": [ 2.33, 13.06, 33.5, 12.57, 51, 9.34, 66.32, 4.31, 63, -10.71, 43.13, -20.58, 8.91, -20.04, -6.79, -2.64, -6.61, 9.1 ],
+				"hull": 9,
+				"edges": [ 10, 8, 8, 6, 6, 4, 4, 2, 10, 12, 12, 14, 14, 16, 2, 0, 16, 0 ],
+				"width": 33,
+				"height": 73
+			}
+		},
+		"neck": {
+			"neck": {
+				"name": "goblin/neck",
+				"type": "mesh",
+				"uvs": [ 0.81967, 0.27365, 0.92101, 0.82048, 0.47134, 1, 0.15679, 0.9354, 0, 0.7556, 0.19268, 0.51833, 0.15468, 0.35706, 0, 0.21989, 0.13568, 0, 0.68878, 0, 0.70145, 0.53872 ],
+				"triangles": [ 3, 5, 2, 2, 10, 1, 2, 5, 10, 3, 4, 5, 10, 0, 1, 0, 10, 6, 10, 5, 6, 7, 8, 6, 6, 9, 0, 6, 8, 9 ],
+				"vertices": [ 18.62, -11.65, -3.98, -13.85, -10.28, 2.76, -6.91, 13.89, 0.8, 19.04999, 10.06, 11.51, 16.74, 12.45, 22.71, 17.64, 31.4, 12.19, 30.12, -7.67, 8.05, -6.71 ],
+				"hull": 10,
+				"edges": [ 14, 12, 12, 10, 10, 8, 8, 6, 6, 4, 4, 2, 2, 20, 20, 0, 0, 18, 16, 18, 14, 16, 0, 2 ],
+				"width": 36,
+				"height": 41
+			}
+		},
+		"pelvis": {
+			"pelvis": {
+				"name": "goblin/pelvis",
+				"type": "mesh",
+				"uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ],
+				"triangles": [ 1, 2, 3, 1, 3, 0 ],
+				"vertices": [ 25.38, -20.73, -36.61, -20.73, -36.61, 22.26, 25.38, 22.26 ],
+				"hull": 4,
+				"edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ],
+				"width": 62,
+				"height": 43
+			}
+		},
+		"right arm": {
+			"right arm": {
+				"name": "goblin/right-arm",
+				"type": "mesh",
+				"uvs": [ 1, 0.09223, 1, 0.8501, 0.72058, 1, 0.24384, 1, 0, 0.86558, 0.20822, 0.10919, 0.50903, 0, 0.85342, 0 ],
+				"triangles": [ 1, 2, 6, 6, 2, 5, 1, 6, 0, 4, 5, 3, 2, 3, 5, 6, 7, 0 ],
+				"vertices": [ -4.75, 8.89, 33.03, 11.74, 40.99, 5.89, 41.81, -5.03, 35.53, -11.13, -2.53, -9.2, -8.5, -2.71, -9.09, 5.17999 ],
+				"hull": 8,
+				"edges": [ 8, 6, 4, 6, 4, 2, 12, 14, 2, 0, 14, 0, 10, 12, 8, 10 ],
+				"width": 23,
+				"height": 50
+			}
+		},
+		"right foot": {
+			"right foot": {
+				"name": "goblin/right-foot",
+				"type": "mesh",
+				"uvs": [ 0.40851, 0.0047, 0.59087, 0.33404, 0.75959, 0.48311, 0.88907, 0.59751, 0.97532, 0.89391, 0.90385, 1, 0.6722, 1, 0.38633, 1, 0.08074, 1, 0, 0.88921, 0, 0.65984, 0, 0.46577, 0.0906, 0.0988, 0.305, 0, 0.47461, 0.71257, 0.715, 0.74681 ],
+				"triangles": [ 1, 10, 11, 1, 13, 0, 14, 1, 2, 1, 12, 13, 12, 1, 11, 14, 10, 1, 15, 14, 2, 15, 2, 3, 9, 10, 14, 15, 3, 4, 7, 8, 9, 14, 7, 9, 6, 14, 15, 5, 6, 15, 7, 14, 6, 4, 5, 15 ],
+				"vertices": [ 17.36, 25.99, 29.13, 15.44, 39.89, 10.8, 48.14, 7.24, 53.84, -2.38, 49.43, -6, 34.84, -6.39, 16.84, -6.87, -2.4, -7.38, -7.58, -3.86, -7.78, 3.7, -7.95, 10.1, -2.57, 22.36, 10.84, 25.97, 22.14, 2.75, 37.31, 2.03 ],
+				"hull": 14,
+				"edges": [ 0, 2, 6, 8, 8, 10, 16, 18, 22, 24, 24, 26, 0, 26, 10, 12, 2, 4, 4, 6, 12, 14, 14, 16, 18, 20, 20, 22, 2, 28, 28, 14, 20, 28, 4, 30, 30, 12, 28, 30, 30, 8 ],
+				"width": 63,
+				"height": 33
+			}
+		},
+		"right hand": {
+			"right hand": {
+				"name": "goblin/right-hand",
+				"type": "mesh",
+				"uvs": [ 0.17957, 0, 0, 0.44772, 0, 0.79734, 0.20057, 0.94264, 0.55057, 1, 0.8539, 1, 0.89823, 0.82004, 0.8259, 0.74285, 0.84223, 0.49993, 0.96356, 0.34102, 0.66023, 0 ],
+				"triangles": [ 8, 10, 9, 0, 10, 1, 8, 2, 1, 8, 1, 10, 7, 3, 8, 3, 2, 8, 4, 3, 7, 5, 7, 6, 4, 7, 5 ],
+				"vertices": [ -10.82, -9.45, 5.95, -15.34, 18.87999, -14.9, 24, -7.5, 25.69, 5.16, 25.31, 16.07, 18.61, 17.44, 15.84, 14.74, 6.84, 15.02, 0.81, 19.18, -11.41, 7.83 ],
+				"hull": 11,
+				"edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 0, 20 ],
+				"width": 36,
+				"height": 37
+			}
+		},
+		"right hand thumb": {
+			"right hand thumb": {
+				"name": "goblin/right-hand",
+				"type": "mesh",
+				"uvs": [ 0.88538, 0.22262, 0.76167, 0.3594, 0.75088, 0.78308, 0.95326, 0.84981, 1, 0.60302 ],
+				"triangles": [ 1, 0, 4, 2, 1, 4, 3, 2, 4 ],
+				"vertices": [ -2.82, 15.97, 2.4, 11.71, 18.08, 11.9, 20.27, 19.27, 11.09, 20.62 ],
+				"hull": 5,
+				"edges": [ 2, 4, 4, 6, 6, 8, 2, 0, 0, 8 ],
+				"width": 36,
+				"height": 37
+			}
+		},
+		"right lower leg": {
+			"right lower leg": {
+				"name": "goblin/right-lower-leg",
+				"type": "mesh",
+				"uvs": [ 1, 0.27261, 0.81312, 0.52592, 0.79587, 0.71795, 0.95544, 0.80988, 0.85193, 0.95493, 0.47241, 1, 0.14033, 1, 0, 0.8773, 0.14896, 0.67914, 0.1619, 0.30325, 0.60611, 0 ],
+				"triangles": [ 1, 10, 0, 9, 10, 1, 8, 9, 1, 2, 8, 1, 4, 2, 3, 6, 7, 8, 5, 6, 8, 2, 5, 8, 4, 5, 2 ],
+				"vertices": [ 6.26, 8.46, 23.32, 8.04, 37.09999, 12.89, 41.45, 20.82, 53.07, 21.46, 61.33, 10.06, 65.76999, -1.03, 58.99, -9.18999, 43.02, -9.81, 16.33, -20, -12.79, -9.26 ],
+				"hull": 11,
+				"edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 0, 20, 18, 20 ],
+				"width": 36,
+				"height": 76
+			}
+		},
+		"right shoulder": {
+			"right shoulder": {
+				"name": "goblin/right-shoulder",
+				"type": "mesh",
+				"uvs": [ 0.62008, 0.03708, 0.92131, 0.09048, 1, 0.38319, 0.72049, 0.6937, 0.31656, 1, 0, 1, 0, 0.75106, 0.28233, 0.49988 ],
+				"triangles": [ 4, 6, 7, 4, 7, 3, 4, 5, 6, 7, 0, 3, 2, 0, 1, 2, 3, 0 ],
+				"vertices": [ -3.17, -11.05, -9, -0.57, -1.01, 10.33, 16.69, 11.17, 37.41, 8.2, 45.45, -1.16, 36.95, -8.46, 21.2, -7.47 ],
+				"hull": 8,
+				"edges": [ 10, 12, 12, 14, 14, 0, 0, 2, 2, 4, 4, 6, 8, 10, 6, 8 ],
+				"width": 39,
+				"height": 45
+			}
+		},
+		"right upper leg": {
+			"right upper leg": {
+				"name": "goblin/right-upper-leg",
+				"type": "mesh",
+				"uvs": [ 0.27018, 0, 0.11618, 0.18177, 0, 0.70688, 0, 0.89577, 0.26668, 1, 0.48718, 1, 0.67618, 0.83532, 1, 0.5161, 1, 0.25543, 0.74618, 0.0571 ],
+				"triangles": [ 9, 8, 7, 9, 1, 0, 6, 9, 7, 6, 1, 9, 2, 1, 6, 4, 3, 2, 6, 4, 2, 5, 4, 6 ],
+				"vertices": [ -9.85, -10.37, 2.17, -14.07, 35.49, -13.66, 47.29, -12.11, 52.61, -2.26, 51.63, 5.16, 40.50999, 10.18, 19.12999, 18.46999, 2.85, 16.32, -8.39999, 6.14 ],
+				"hull": 10,
+				"edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 0, 18 ],
+				"width": 34,
+				"height": 63
+			}
+		},
+		"torso": {
+			"torso": {
+				"name": "goblin/torso",
+				"type": "mesh",
+				"uvs": [ 0, 0.33287, 0.15945, 0.46488, 0.15761, 0.60314, 0.15502, 0.79806, 0.32807, 0.93478, 0.6875, 1, 0.80731, 1, 1, 0.77763, 1, 0.66147, 1, 0.56703, 0.93207, 0.4771, 0.86944, 0.39416, 0.83837, 0.226, 0.68085, 0, 0.14836, 0, 0, 0.07199, 0.78734, 0.86249, 0.43679, 0.79649, 0.76738, 0.61733, 0.44345, 0.58747, 0.54329, 0.38316, 0.77692, 0.73446, 0.66478, 0.51012 ],
+				"triangles": [ 5, 16, 6, 6, 16, 7, 4, 17, 5, 5, 17, 16, 4, 3, 17, 17, 21, 16, 16, 21, 7, 3, 2, 17, 21, 19, 18, 21, 17, 19, 17, 2, 19, 21, 8, 7, 21, 18, 8, 18, 9, 8, 19, 22, 18, 18, 10, 9, 18, 22, 10, 2, 1, 19, 19, 20, 22, 19, 1, 20, 22, 11, 10, 22, 20, 11, 20, 1, 14, 20, 12, 11, 1, 0, 14, 20, 13, 12, 20, 14, 13, 0, 15, 14 ],
+				"vertices": [ 56.93, 27.95, 43.37, 18.23, 30.16, 19.5, 11.53, 21.28, -2.55, 10.69, -10.89, -13.12, -11.59, -21.23, 8.54, -36.12, 19.65, -37.08, 28.68, -37.86, 37.68, -34, 45.98, -30.44, 56.4, -29.07, 84.78, -20.92, 87.9, 15.15, 81.87999, 25.79, 1.67, -21.01, 10.03, 2.18, 25.23, -18.25, 29.98, 0, 48.54, -8.39, 13.98, -21.36, 35.9, -15.6 ],
+				"hull": 16,
+				"edges": [ 0, 2, 6, 8, 8, 10, 10, 12, 12, 14, 22, 24, 24, 26, 26, 28, 28, 30, 0, 30, 14, 32, 32, 34, 34, 6, 18, 36, 36, 38, 2, 4, 4, 6, 38, 4, 2, 40, 40, 22, 40, 38, 38, 34, 32, 10, 34, 8, 40, 28, 14, 16, 16, 18, 32, 42, 42, 36, 16, 42, 42, 34, 18, 20, 20, 22, 36, 44, 44, 40, 20, 44 ],
+				"width": 68,
+				"height": 96
+			}
+		},
+		"undie straps": {
+			"undie straps": {
+				"name": "goblin/undie-straps",
+				"type": "mesh",
+				"uvs": [ 0.36097, 0.44959, 0.66297, 0.60591, 1, 0.19486, 1, 0.57117, 0.75897, 1, 0.38697, 1, 0, 0.26433, 0, 0, 0.12497, 0 ],
+				"triangles": [ 6, 7, 8, 6, 8, 0, 3, 1, 2, 5, 0, 1, 6, 0, 5, 4, 1, 3, 5, 1, 4 ],
+				"vertices": [ -10.56, 12.87, 6.53, 9.89999, 25.62, 17.70999, 25.62, 10.56, 11.97, 2.41, -9.09, 2.41, -31, 16.39, -31, 21.41, -23.92, 21.41 ],
+				"hull": 9,
+				"edges": [ 14, 16, 16, 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 12, 14, 10, 12, 0, 10, 2, 8 ],
+				"width": 55,
+				"height": 19
+			}
+		},
+		"undies": {
+			"undies": {
+				"name": "goblin/undies",
+				"type": "mesh",
+				"uvs": [ 0, 0.32029, 0.14893, 0.59457, 0.22437, 1, 0.35909, 1, 0.50998, 1, 0.79559, 0.58453, 0.9842, 0.28015, 1, 0.00588, 0.46957, 0.17646, 0, 0.03933, 0.48843, 0.59122, 0.48114, 0.43099 ],
+				"triangles": [ 6, 8, 7, 0, 9, 8, 11, 8, 6, 0, 8, 11, 5, 11, 6, 10, 11, 5, 1, 0, 11, 1, 11, 10, 3, 2, 1, 10, 3, 1, 4, 10, 5, 3, 10, 4 ],
+				"vertices": [ -13.22, 5.56, -8, -2.47, -5.49, -14.27, -0.64, -14.36, 4.78, -14.45, 15.27, -2.58999, 22.22, 6.11, 22.92, 14.05, 3.75, 9.43999, -13.08, 13.71, 4.21, -2.58999, 4.03, 2.05 ],
+				"hull": 10,
+				"edges": [ 0, 2, 2, 4, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 0, 18, 4, 6, 6, 8, 6, 20, 16, 22, 22, 20, 0, 22, 22, 12, 2, 20, 20, 10 ],
+				"width": 36,
+				"height": 29
+			}
+		}
+	},
+	"goblingirl": {
+		"eyes": {
+			"eyes closed": { "name": "goblingirl/eyes-closed", "x": 28, "y": -25.54, "rotation": -87.04, "width": 37, "height": 21 }
+		},
+		"head": {
+			"head": { "name": "goblingirl/head", "x": 27.71, "y": -4.32, "rotation": -85.58, "width": 103, "height": 81 }
+		},
+		"left arm": {
+			"left arm": { "name": "goblingirl/left-arm", "x": 19.64, "y": -2.42, "rotation": 33.05, "width": 37, "height": 35 }
+		},
+		"left foot": {
+			"left foot": { "name": "goblingirl/left-foot", "x": 25.17, "y": 7.92, "rotation": 3.32, "width": 65, "height": 31 }
+		},
+		"left hand": {
+			"left hand": {
+				"name": "goblingirl/left-hand",
+				"x": 4.34,
+				"y": 2.39,
+				"scaleX": 0.896,
+				"scaleY": 0.896,
+				"rotation": 30.34,
+				"width": 35,
+				"height": 40
+			}
+		},
+		"left lower leg": {
+			"left lower leg": { "name": "goblingirl/left-lower-leg", "x": 25.02, "y": -0.6, "rotation": 105.75, "width": 33, "height": 70 }
+		},
+		"left shoulder": {
+			"left shoulder": { "name": "goblingirl/left-shoulder", "x": 19.8, "y": -0.42, "rotation": 61.21, "width": 28, "height": 46 }
+		},
+		"left upper leg": {
+			"left upper leg": { "name": "goblingirl/left-upper-leg", "x": 30.21, "y": -2.95, "rotation": 89.09, "width": 33, "height": 70 }
+		},
+		"neck": {
+			"neck": { "name": "goblingirl/neck", "x": 6.16, "y": -3.14, "rotation": -98.86, "width": 35, "height": 41 }
+		},
+		"pelvis": {
+			"pelvis": { "name": "goblingirl/pelvis", "x": -3.87, "y": 3.18, "width": 62, "height": 43 }
+		},
+		"right arm": {
+			"right arm": { "name": "goblingirl/right-arm", "x": 16.85, "y": -0.66, "rotation": 93.52, "width": 28, "height": 50 }
+		},
+		"right foot": {
+			"right foot": { "name": "goblingirl/right-foot", "x": 23.46, "y": 9.66, "rotation": 1.52, "width": 63, "height": 33 }
+		},
+		"right hand": {
+			"right hand": { "name": "goblingirl/right-hand", "x": 7.21, "y": 3.43, "rotation": 91.16, "width": 36, "height": 37 }
+		},
+		"right hand thumb": {
+			"right hand thumb": { "name": "goblingirl/right-hand", "x": 7.21, "y": 3.43, "rotation": 91.16, "width": 36, "height": 37 }
+		},
+		"right lower leg": {
+			"right lower leg": { "name": "goblingirl/right-lower-leg", "x": 26.15, "y": -3.27, "rotation": 111.83, "width": 36, "height": 76 }
+		},
+		"right shoulder": {
+			"right shoulder": { "name": "goblingirl/right-shoulder", "x": 14.46, "y": 0.45, "rotation": 129.85, "width": 39, "height": 45 }
+		},
+		"right upper leg": {
+			"right upper leg": { "name": "goblingirl/right-upper-leg", "x": 19.69, "y": 2.13, "rotation": 97.49, "width": 34, "height": 63 }
+		},
+		"torso": {
+			"torso": { "name": "goblingirl/torso", "x": 36.28, "y": -5.14, "rotation": -95.74, "width": 68, "height": 96 }
+		},
+		"undie straps": {
+			"undie straps": { "name": "goblingirl/undie-straps", "x": -1.51, "y": 14.18, "width": 55, "height": 19 }
+		},
+		"undies": {
+			"undies": { "name": "goblingirl/undies", "x": 5.4, "y": 1.7, "width": 36, "height": 29 }
+		}
+	}
+},
+"animations": {
+	"walk": {
+		"slots": {
+			"eyes": {
+				"attachment": [
+					{ "time": 0.7, "name": "eyes closed" },
+					{ "time": 0.8, "name": null }
+				]
+			}
+		},
+		"bones": {
+			"left upper leg": {
+				"rotate": [
+					{ "time": 0, "angle": -26.55 },
+					{ "time": 0.1333, "angle": -8.78 },
+					{ "time": 0.2333, "angle": 9.51 },
+					{ "time": 0.3666, "angle": 30.74 },
+					{ "time": 0.5, "angle": 25.33 },
+					{ "time": 0.6333, "angle": 26.11 },
+					{ "time": 0.7333, "angle": 7.45 },
+					{ "time": 0.8666, "angle": -21.19 },
+					{ "time": 1, "angle": -26.55 }
+				],
+				"translate": [
+					{ "time": 0, "x": -1.32, "y": 1.7 },
+					{ "time": 0.3666, "x": -0.06, "y": 2.42 },
+					{ "time": 1, "x": -1.32, "y": 1.7 }
+				]
+			},
+			"right upper leg": {
+				"rotate": [
+					{ "time": 0, "angle": 42.45 },
+					{
+						"time": 0.1333,
+						"angle": 49.86,
+						"curve": [ 0.414, 0, 0.705, 0.99 ]
+					},
+					{ "time": 0.2333, "angle": 22.51 },
+					{ "time": 0.5, "angle": -16.93 },
+					{ "time": 0.6333, "angle": 1.89 },
+					{
+						"time": 0.7333,
+						"angle": 34.86,
+						"curve": [ 0.462, 0.11, 1, 1 ]
+					},
+					{
+						"time": 0.8666,
+						"angle": 58.68,
+						"curve": [ 0.5, 0.02, 1, 1 ]
+					},
+					{ "time": 1, "angle": 42.45 }
+				],
+				"translate": [
+					{ "time": 0, "x": 6.23, "y": 0 },
+					{ "time": 0.2333, "x": 2.14, "y": 2.4 },
+					{ "time": 0.5, "x": 2.44, "y": 4.8 },
+					{ "time": 1, "x": 6.23, "y": 0 }
+				]
+			},
+			"left lower leg": {
+				"rotate": [
+					{ "time": 0, "angle": -18.05 },
+					{ "time": 0.1333, "angle": -63.5 },
+					{ "time": 0.2333, "angle": -83.01 },
+					{ "time": 0.5, "angle": 5.11 },
+					{ "time": 0.6333, "angle": -28.29 },
+					{ "time": 0.7333, "angle": -27.52 },
+					{ "time": 0.8666, "angle": 3.53 },
+					{ "time": 1, "angle": -18.05 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 },
+					{ "time": 0.2333, "x": 2.55, "y": -0.47 },
+					{ "time": 0.5, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 1, "x": 0, "y": 0 }
+				]
+			},
+			"left foot": {
+				"rotate": [
+					{ "time": 0, "angle": -14.56 },
+					{ "time": 0.1333, "angle": -10.42 },
+					{ "time": 0.2333, "angle": -5.01 },
+					{ "time": 0.3, "angle": 6.67 },
+					{ "time": 0.3666, "angle": 3.87 },
+					{ "time": 0.5, "angle": -3.87 },
+					{ "time": 0.6333, "angle": 2.78 },
+					{ "time": 0.7333, "angle": -11.99 },
+					{ "time": 0.8666, "angle": -12.45 },
+					{ "time": 1, "angle": -14.56 }
+				]
+			},
+			"right shoulder": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 5.29,
+						"curve": [ 0.264, 0, 0.75, 1 ]
+					},
+					{ "time": 0.6333, "angle": 6.65 },
+					{ "time": 1, "angle": 5.29 }
+				]
+			},
+			"right arm": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -4.02,
+						"curve": [ 0.267, 0, 0.804, 0.99 ]
+					},
+					{
+						"time": 0.6333,
+						"angle": 19.78,
+						"curve": [ 0.307, 0, 0.787, 0.99 ]
+					},
+					{ "time": 1, "angle": -4.02 }
+				]
+			},
+			"right hand": {
+				"rotate": [
+					{ "time": 0, "angle": 8.98 },
+					{ "time": 0.6333, "angle": 0.51 },
+					{ "time": 1, "angle": 8.98 }
+				]
+			},
+			"left shoulder": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 6.25,
+						"curve": [ 0.339, 0, 0.683, 1 ]
+					},
+					{
+						"time": 0.5,
+						"angle": -11.78,
+						"curve": [ 0.281, 0, 0.686, 0.99 ]
+					},
+					{ "time": 1, "angle": 6.25 }
+				],
+				"translate": [
+					{ "time": 0, "x": 1.15, "y": 0.23 }
+				]
+			},
+			"left hand": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -21.23,
+						"curve": [ 0.295, 0, 0.755, 0.98 ]
+					},
+					{
+						"time": 0.5,
+						"angle": -27.28,
+						"curve": [ 0.241, 0, 0.75, 0.97 ]
+					},
+					{ "time": 1, "angle": -21.23 }
+				]
+			},
+			"left arm": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 28.37,
+						"curve": [ 0.339, 0, 0.683, 1 ]
+					},
+					{
+						"time": 0.5,
+						"angle": 60.09,
+						"curve": [ 0.281, 0, 0.686, 0.99 ]
+					},
+					{ "time": 1, "angle": 28.37 }
+				]
+			},
+			"torso": {
+				"rotate": [
+					{ "time": 0, "angle": -10.28 },
+					{
+						"time": 0.1333,
+						"angle": -15.38,
+						"curve": [ 0.545, 0, 0.818, 1 ]
+					},
+					{
+						"time": 0.3666,
+						"angle": -9.78,
+						"curve": [ 0.58, 0.17, 0.669, 0.99 ]
+					},
+					{
+						"time": 0.6333,
+						"angle": -15.75,
+						"curve": [ 0.235, 0.01, 0.795, 1 ]
+					},
+					{
+						"time": 0.8666,
+						"angle": -7.06,
+						"curve": [ 0.209, 0, 0.816, 0.98 ]
+					},
+					{ "time": 1, "angle": -10.28 }
+				],
+				"translate": [
+					{ "time": 0, "x": -3.72, "y": -0.01 }
+				]
+			},
+			"right foot": {
+				"rotate": [
+					{ "time": 0, "angle": -5.25 },
+					{ "time": 0.2333, "angle": -17.76 },
+					{ "time": 0.3666, "angle": -20.09 },
+					{ "time": 0.5, "angle": -19.73 },
+					{ "time": 0.7333, "angle": -11.68 },
+					{ "time": 0.8, "angle": 4.46 },
+					{ "time": 0.8666, "angle": 0.46 },
+					{ "time": 1, "angle": -5.25 }
+				]
+			},
+			"right lower leg": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -3.39,
+						"curve": [ 0.316, 0.01, 0.741, 0.98 ]
+					},
+					{
+						"time": 0.1333,
+						"angle": -43.21,
+						"curve": [ 0.414, 0, 0.705, 0.99 ]
+					},
+					{ "time": 0.2333, "angle": -25.98 },
+					{ "time": 0.5, "angle": -19.53 },
+					{ "time": 0.6333, "angle": -64.8 },
+					{
+						"time": 0.7333,
+						"angle": -89.54,
+						"curve": [ 0.557, 0.18, 1, 1 ]
+					},
+					{ "time": 1, "angle": -3.39 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.5, "x": 0, "y": 0 },
+					{ "time": 0.6333, "x": 2.18, "y": 0.21 },
+					{ "time": 1, "x": 0, "y": 0 }
+				]
+			},
+			"hip": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{ "time": 1, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": -8.4 },
+					{
+						"time": 0.1333,
+						"x": 0,
+						"y": -9.35,
+						"curve": [ 0.326, 0.05, 0.674, 0.93 ]
+					},
+					{
+						"time": 0.2333,
+						"x": 0,
+						"y": -0.59,
+						"curve": [ 0.325, 0.39, 0.643, 0.7 ]
+					},
+					{ "time": 0.3666, "x": 0, "y": -3.96 },
+					{ "time": 0.5, "x": 0, "y": -8.4 },
+					{
+						"time": 0.6333,
+						"x": 0,
+						"y": -10,
+						"curve": [ 0.359, 0.47, 0.646, 0.74 ]
+					},
+					{
+						"time": 0.7333,
+						"x": 0,
+						"y": -5.29,
+						"curve": [ 0.333, 0.36, 0.662, 0.69 ]
+					},
+					{
+						"time": 0.8,
+						"x": 0,
+						"y": -2.49,
+						"curve": [ 0.322, 0.35, 0.651, 0.68 ]
+					},
+					{ "time": 0.8666, "x": 0, "y": -3.96 },
+					{ "time": 1, "x": 0, "y": -8.4 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": 3.6 },
+					{ "time": 0.1333, "angle": 17.49 },
+					{ "time": 0.2333, "angle": 6.1 },
+					{ "time": 0.3666, "angle": 3.45 },
+					{ "time": 0.5, "angle": 5.17 },
+					{ "time": 0.6333, "angle": 18.36 },
+					{ "time": 0.7333, "angle": 6.09 },
+					{ "time": 0.8666, "angle": 2.28 },
+					{ "time": 1, "angle": 3.6 }
+				]
+			},
+			"head": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 3.6,
+						"curve": [ 0, 0, 0.704, 1.17 ]
+					},
+					{ "time": 0.1333, "angle": -0.2 },
+					{ "time": 0.2333, "angle": 6.1 },
+					{ "time": 0.3666, "angle": 3.45 },
+					{
+						"time": 0.5,
+						"angle": 5.17,
+						"curve": [ 0, 0, 0.704, 1.61 ]
+					},
+					{ "time": 0.6666, "angle": 1.1 },
+					{ "time": 0.7333, "angle": 6.09 },
+					{ "time": 0.8666, "angle": 2.28 },
+					{ "time": 1, "angle": 3.6 }
+				]
+			},
+			"pelvis": {
+				"rotate": [
+					{ "time": 0, "angle": -1.33 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0.39, "y": -0.78 }
+				]
+			},
+			"spear1": {
+				"rotate": [
+					{ "time": 0, "angle": 1.84 },
+					{ "time": 0.2, "angle": -5.38 },
+					{ "time": 0.5, "angle": 2.95 },
+					{ "time": 0.7333, "angle": -3.67 },
+					{ "time": 1, "angle": 1.84 }
+				]
+			},
+			"spear2": {
+				"rotate": [
+					{ "time": 0, "angle": 1.84 },
+					{ "time": 0.2, "angle": -5.38 },
+					{ "time": 0.5, "angle": 2.95 },
+					{ "time": 0.7333, "angle": -3.67 },
+					{ "time": 1, "angle": 1.84 }
+				]
+			},
+			"spear3": {
+				"rotate": [
+					{ "time": 0, "angle": 3.64 },
+					{ "time": 0.2, "angle": -3.59 },
+					{ "time": 0.5, "angle": 4.74 },
+					{ "time": 0.7333, "angle": -1.87 },
+					{ "time": 1, "angle": 3.64 }
+				]
+			}
+		},
+		"deform": {
+			"default": {
+				"left hand item": {
+					"spear": [
+						{ "time": 0 }
+					]
+				},
+				"right hand item": {
+					"dagger": [
+						{
+							"time": 0,
+							"offset": 26,
+							"vertices": [ 2.34754, 0.14469 ],
+							"curve": [ 0.25, 0, 0.75, 1 ]
+						},
+						{
+							"time": 0.5,
+							"offset": 8,
+							"vertices": [ -1.19415, 4.31531, 0.07279, 6.41351, 1.66048, 6.18882, 1.75232, 3.59555 ],
+							"curve": [ 0.25, 0, 0.75, 1 ]
+						},
+						{
+							"time": 1,
+							"offset": 26,
+							"vertices": [ 2.34754, 0.14469 ]
+						}
+					]
+				}
+			},
+			"goblin": {
+				"head": {
+					"head": [
+						{
+							"time": 0,
+							"curve": [ 0.632, 0, 0.75, 1 ]
+						},
+						{
+							"time": 0.2,
+							"vertices": [ -10.97826, -6.68962, -4.68015, -2.46175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.08534, 0.08391, -1.08534, 0.08391, -1.08534, 0.08391, 0, 0, -2.22324, 2.66465, -4.83295, 2.70084, -5.70553, -0.51941, -3.15962, -1.61501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.64741, 0.81612, -11.82285, -1.34955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.08534, 0.08391 ],
+							"curve": [ 0.25, 0, 0.75, 1 ]
+						},
+						{
+							"time": 0.3666,
+							"vertices": [ 10.69275, 4.05949, 3.66373, 1.85426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.47305, 0.09017, 1.47305, 0.09017, 1.47305, 0.09017, 0, 0, 2.69652, -0.22738, 3.77135, 0.11417, 3.6893, 1.55352, 2.49594, 1.65501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.4588, -3.9113, 9.19593, -1.66854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.47305, 0.09017 ],
+							"curve": [ 0.621, 0, 0.75, 1 ]
+						},
+						{
+							"time": 0.7,
+							"vertices": [ -10.97826, -6.68962, -4.68015, -2.46175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.1755, -0.17183, -1.1755, -0.17182, -1.1755, -0.17183, 0, 0, -2.22324, 2.66465, -4.83295, 2.70084, -5.70553, -0.51941, -3.15962, -1.61501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.64741, 0.81612, -11.82285, -1.34955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.1755, -0.17183 ],
+							"curve": [ 0.25, 0, 0.75, 1 ]
+						},
+						{
+							"time": 0.8666,
+							"vertices": [ 10.69275, 4.05949, 3.66373, 1.85426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.38687, 0.08446, 0.38687, 0.08446, 0.38687, 0.08446, 0, 0, 2.69652, -0.22738, 3.77135, 0.11417, 3.6893, 1.55352, 2.49594, 1.65501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.4588, -3.9113, 9.19593, -1.66854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.38687, 0.08446 ],
+							"curve": [ 0.25, 0, 0.75, 1 ]
+						},
+						{ "time": 1 }
+					]
+				},
+				"left foot": {
+					"left foot": [
+						{
+							"time": 0,
+							"offset": 8,
+							"vertices": [ 3.69298, 2.37572, -7.16969, 18.79732, -12.78161, 14.7778, -12.75775, 6.50514, -3.13475, 1.98906, -0.44401, 0.36629, 0, 0, -3.80085, 2.98474 ]
+						},
+						{ "time": 0.1333 },
+						{
+							"time": 0.2333,
+							"offset": 8,
+							"vertices": [ -3.96072, -2.34594, -5.80445, -12.47629, -2.23129, -12.99037, 2.02941, -9.1036, 0, 0, 0, 0, 0, 0, -1.35254, -5.2883 ]
+						},
+						{
+							"time": 0.3666,
+							"offset": 8,
+							"vertices": [ 0.66504, 0.33548, 0.33902, 2.69014, -0.4817, 2.54524, -1.13592, 1.38562, 0, 0, 0, 0, 0, 0, -0.11907, 0.79273 ]
+						},
+						{ "time": 0.5, "curve": "stepped" },
+						{ "time": 0.6333 },
+						{
+							"time": 0.7333,
+							"offset": 8,
+							"vertices": [ -2.97737, 9.40254, -6.91661, 19.92794, -10.55287, 18.41085, -12.37161, 12.38473, -4.72606, 6.30798, 0, 0, -1.48902, 4.88944, -7.06773, 10.70101 ]
+						},
+						{
+							"time": 0.8333,
+							"offset": 6,
+							"vertices": [ 1.05318, 1.56361, -2.52722, 7.9974, -5.5203, 17.14136, -8.93317, 15.79635, -10.73747, 10.22055, -4.23801, 5.36992, 0, 0, 0, 0, -5.83147, 8.55531 ]
+						},
+						{
+							"time": 1,
+							"offset": 8,
+							"vertices": [ 3.69298, 2.37572, -7.16969, 18.79732, -12.78161, 14.7778, -12.75775, 6.50514, -3.13475, 1.98906, -0.44401, 0.36629, 0, 0, -3.80085, 2.98474 ]
+						}
+					]
+				},
+				"pelvis": {
+					"pelvis": [
+						{ "time": 0 },
+						{
+							"time": 0.1333,
+							"offset": 6,
+							"vertices": [ -0.68989, -4.13283 ]
+						},
+						{
+							"time": 0.3333,
+							"offset": 6,
+							"vertices": [ -1.04945, -3.10476 ]
+						},
+						{
+							"time": 0.7,
+							"offset": 6,
+							"vertices": [ -1.4245, -6.30616 ]
+						},
+						{
+							"time": 0.8666,
+							"offset": 6,
+							"vertices": [ -1.13541, -1.79035 ]
+						},
+						{ "time": 1 }
+					]
+				},
+				"right foot": {
+					"right foot": [
+						{ "time": 0 },
+						{
+							"time": 0.1333,
+							"offset": 2,
+							"vertices": [ -2.81258, 2.63114, -2.35238, 3.89441, -1.99921, 4.8639, -0.93273, 5.57982, -0.48886, 5.09854, -0.34812, 3.42912, -0.17445, 1.36898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.31305, 1.91371, -1.32986, 3.65703 ]
+						},
+						{
+							"time": 0.2333,
+							"offset": 2,
+							"vertices": [ -6.39088, 6.41245, -7.74575, 8.27191, -7.02471, 11.35894, -4.0347, 13.93454, -2.50399, 12.62962, -1.46124, 7.58915, -0.17445, 1.36898, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.84765, 2.61215, -4.53955, 7.92357 ]
+						},
+						{
+							"time": 0.3,
+							"offset": 2,
+							"vertices": [ -8.27184, 6.68821, -9.29764, 10.13797, -8.62231, 14.71339, -4.58629, 18.81939, -2.20304, 17.10709, -0.07794, 9.9046, 2.54451, 1.01642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.94624, 2.38007, -4.59398, 10.01888 ]
+						},
+						{
+							"time": 0.3666,
+							"offset": 2,
+							"vertices": [ -10.47683, 9.44175, -13.36882, 12.40982, -14.32568, 16.94392, -9.24462, 23.55674, -5.51711, 21.51377, -1.19581, 11.53192, 2.54451, 1.01642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.14847, 2.29389, -6.63418, 11.37127 ]
+						},
+						{
+							"time": 0.5,
+							"offset": 2,
+							"vertices": [ -5.42473, 4.36854, -10.59004, 7.04468, -11.64251, 11.55845, -6.19665, 20.12805, -1.45497, 18.05411, 4.86619, 6.41678, 2.81462, 0.27601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.96412, 4.94829 ]
+						},
+						{ "time": 0.6333 },
+						{
+							"time": 0.7333,
+							"offset": 4,
+							"vertices": [ 1.31462, -6.84099, -0.87905, -12.54479, -5.9851, -14.08367, -7.15892, -11.63193, -5.6792, -4.83544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.06163, -6.93844 ]
+						},
+						{
+							"time": 0.8,
+							"offset": 4,
+							"vertices": [ 0.65731, -3.42049, -0.43952, -6.27239, -2.99255, -7.04183, -3.57946, -5.81596, -2.83959, -2.41772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.79687, -1.2802, 0, 0, 0, 0, -1.03081, -3.46922 ]
+						},
+						{ "time": 0.8666 }
+					]
+				},
+				"right hand": {
+					"right hand": [
+						{
+							"time": 0,
+							"offset": 4,
+							"vertices": [ -1.48416, 0.34736, 0, 0, 1.31152, 0.08085, 1.60295, 0.09881, 0.13673, 0.1547, 0, 0, 0, 0, -0.72862, -0.0449 ]
+						},
+						{ "time": 0.5 },
+						{
+							"time": 1,
+							"offset": 4,
+							"vertices": [ -1.48416, 0.34736, 0, 0, 1.31152, 0.08085, 1.60295, 0.09881, 0.13673, 0.1547, 0, 0, 0, 0, -0.72862, -0.0449 ]
+						}
+					]
+				},
+				"right lower leg": {
+					"right lower leg": [
+						{ "time": 0 },
+						{
+							"time": 0.6,
+							"offset": 6,
+							"vertices": [ 1.80396, -1.56552 ]
+						},
+						{ "time": 1 }
+					]
+				},
+				"right upper leg": {
+					"right upper leg": [
+						{
+							"time": 0,
+							"vertices": [ -6.03856, -1.46324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34684, -1.93101, -1.86047, -5.05265, -2.5014, -3.09984 ]
+						},
+						{ "time": 0.3333 },
+						{
+							"time": 0.8666,
+							"offset": 14,
+							"vertices": [ 0.13424, -2.35377, -1.33317, -5.99572, -1.35861, -4.43323 ]
+						},
+						{
+							"time": 1,
+							"vertices": [ -6.03856, -1.46324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34684, -1.93101, -1.86047, -5.05265, -2.5014, -3.09984 ]
+						}
+					]
+				},
+				"torso": {
+					"torso": [
+						{
+							"time": 0,
+							"offset": 14,
+							"vertices": [ -1.48952, -0.24021, -2.72312, -2.15489, -0.51183, -3.39752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0964, -2.61458, 0, 0, 0.57686, -1.24874, 0, 0, 0, 0, -2.11251, -3.29932 ]
+						},
+						{
+							"time": 0.1333,
+							"offset": 14,
+							"vertices": [ 1.31318, -0.59727, -0.97944, -1.62934, 0.74861, -0.6123, -1.44598, 1.97515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.65701, -3.95221, 0, 0, -1.46987, -0.31373, 0, 0, 0, 0, -3.31756, -3.5535, -2.56329, 0.29673 ]
+						},
+						{
+							"time": 0.3,
+							"offset": 14,
+							"vertices": [ 6.03761, -3.13561, 7.55475, -1.38111, 6.79747, 0.31171, 4.23503, 1.14012, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.07575, -5.16824, 0, 0, 4.0041, 0.27245, 0, 0, 0, 0, 3.4376, -3.52286 ]
+						},
+						{
+							"time": 0.5,
+							"offset": 14,
+							"vertices": [ 2.25942, -0.87202, 2.575, -0.56861, 3.17112, -0.57003, 1.48704, 0.9924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.22451, -4.43862, 0, 0, 1.48691, 0.01586, 0, 0, 0, 0, 0.31388, -3.28095, -1.53797, 0.17803 ]
+						},
+						{
+							"time": 0.6333,
+							"offset": 14,
+							"vertices": [ 0.75002, -1.51701, -0.97944, -1.62934, 0.74861, -0.6123, -1.44598, 1.97515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.65701, -3.95221, 0, 0, -1.46987, -0.31373, 0, 0, 0, 0, -3.31756, -3.5535, -2.56329, 0.29673 ]
+						},
+						{
+							"time": 0.8666,
+							"offset": 14,
+							"vertices": [ 0.62202, -1.26262, 0.38489, -2.20701, 3.25048, -0.50042, 2.41108, 2.39315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.6639, -3.10099, 0, 0, 2.30655, -1.15196, 0, 0, 0, 0, -0.07676, -3.63497, -0.9321, 0.1079 ]
+						},
+						{
+							"time": 1,
+							"offset": 14,
+							"vertices": [ -1.48952, -0.24021, -2.72312, -2.15489, -0.51183, -3.39752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0964, -2.61458, 0, 0, 0.57686, -1.24874, 0, 0, 0, 0, -2.11251, -3.29932 ]
+						}
+					]
+				},
+				"undie straps": {
+					"undie straps": [
+						{
+							"time": 0,
+							"offset": 2,
+							"vertices": [ -1.77696, 0.54759, -0.96145, -1.03793, -0.39148, -0.24071, -1.77696, 0.54759 ]
+						},
+						{
+							"time": 0.1333,
+							"offset": 2,
+							"vertices": [ -2.25683, -1.03177, -1.49719, -4.23861, -0.74469, -2.84906, -1.90072, 0.54477 ]
+						},
+						{
+							"time": 0.3333,
+							"offset": 2,
+							"vertices": [ -2.37974, -0.05431, -0.49433, 0.19436, -0.90861, 1.16519, -1.60956, 2.70798, 0.96186, 0.80615 ]
+						},
+						{
+							"time": 0.7,
+							"offset": 2,
+							"vertices": [ -0.91714, -2.76567, -0.62214, -3.63489, -0.8494, -2.26772, -2.56076, 0.5297 ]
+						},
+						{
+							"time": 0.8666,
+							"offset": 2,
+							"vertices": [ -2.56076, 0.5297, -1.58064, 0.32031, -1.3847, 0.32476, -2.56076, 0.5297 ]
+						},
+						{
+							"time": 1,
+							"offset": 2,
+							"vertices": [ -1.77696, 0.54759, -0.80128, 0.53413, -0.80128, 0.53413, -1.77696, 0.54759 ]
+						}
+					]
+				},
+				"undies": {
+					"undies": [
+						{
+							"time": 0,
+							"vertices": [ 0.43098, 0.722, 10.60295, -0.11699, 2.29598, 0, 2.29598, 0, 2.29598, 0, 0.58798, 0.24399, -2.40018, -0.65335, -2.2782, -0.77533, 2.29598, 0, 0.58798, -0.48799, 4.98697, -0.11699, 6.50796, -0.23399 ]
+						},
+						{
+							"time": 0.1333,
+							"vertices": [ 0.72659, 0.43319, 7.20416, -0.1638, 1.37759, 0, 1.37759, 0, 1.37759, 0, 1.25279, 0.0464, -0.99861, -2.95085, -1.37542, -3.07404, 1.37759, 0, 0.35279, -0.29279, 2.99218, -0.07019, 3.90478, -0.14039 ]
+						},
+						{
+							"time": 0.3333,
+							"vertices": [ 1.16999, 0, 2.10599, -0.234, 0, 0, 0, 0, 0, 0, 2.24999, -0.24999, -0.4344, 0.60551, -1.55939, 0.48051 ]
+						},
+						{
+							"time": 0.5333,
+							"vertices": [ 1.16999, 0, -0.234, -0.93599, -2.92499, 0.35099, 0, 0, 0, 0, 0.49999, -0.24999, -0.64078, -2.07914, -0.64078, -2.07914 ]
+						},
+						{
+							"time": 0.7,
+							"vertices": [ 1.8627, -0.11514, 4.66326, -0.09099, -1.76428, 0.21171, 0, 0, -0.56832, 0.32832, -1.13833, -1.1511, -2.19996, -3.47068, -1.29718, -3.47068, 0, 0, 0, 0, 1.58785, -0.04642, 2.65941, 0.16714 ]
+						},
+						{
+							"time": 0.8333,
+							"vertices": [ 2.41687, -0.20725, 8.58108, 0.585, -0.83571, 0.10028, 0, 0, -1.02299, 0.59098, -2.44899, -1.872, -1.62499, 0, 0, 0, 0, 0, 0, 0, 2.85813, -0.08356, 4.78695, 0.30086 ]
+						},
+						{
+							"time": 0.8666,
+							"vertices": [ 2.01969, -0.0214, 8.98545, 0.4446, -0.20937, 0.08022, 0.45919, 0, -0.35919, 0.47279, -1.84159, -1.4488, -0.79153, 1.2642, 0.53285, 1.23981, 0.45919, 0, 0.11759, -0.09759, 3.2839, -0.09025, 5.13115, 0.19388 ]
+						},
+						{
+							"time": 1,
+							"vertices": [ 0.43098, 0.722, 10.60295, -0.11699, 2.29598, 0, 2.29598, 0, 2.29598, 0, 0.58798, 0.24399, -2.40018, -0.65335, -2.2782, -0.77533, 2.29598, 0, 0.58798, -0.48799, 4.98697, -0.11699, 6.50796, -0.23399 ]
+						}
+					]
+				}
+			}
+		}
+	}
+}
+}

BIN
spine-ts/canvas/example/assets/goblins-mesh.png


+ 279 - 0
spine-ts/canvas/example/assets/raptor.atlas

@@ -0,0 +1,279 @@
+
+raptor.png
+size: 1024,1024
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+back_arm
+  rotate: true
+  xy: 140, 191
+  size: 46, 29
+  orig: 46, 29
+  offset: 0, 0
+  index: -1
+back_bracer
+  rotate: true
+  xy: 167, 317
+  size: 39, 28
+  orig: 39, 28
+  offset: 0, 0
+  index: -1
+back_hand
+  rotate: false
+  xy: 167, 358
+  size: 36, 34
+  orig: 36, 34
+  offset: 0, 0
+  index: -1
+back_knee
+  rotate: false
+  xy: 299, 478
+  size: 49, 67
+  orig: 49, 67
+  offset: 0, 0
+  index: -1
+back_thigh
+  rotate: true
+  xy: 167, 437
+  size: 39, 24
+  orig: 39, 24
+  offset: 0, 0
+  index: -1
+eyes_closed
+  rotate: true
+  xy: 2, 2
+  size: 47, 45
+  orig: 47, 45
+  offset: 0, 0
+  index: -1
+eyes_open
+  rotate: true
+  xy: 49, 2
+  size: 47, 45
+  orig: 47, 45
+  offset: 0, 0
+  index: -1
+eyes_surprised
+  rotate: true
+  xy: 96, 2
+  size: 47, 45
+  orig: 47, 45
+  offset: 0, 0
+  index: -1
+front_arm
+  rotate: false
+  xy: 419, 544
+  size: 48, 30
+  orig: 48, 30
+  offset: 0, 0
+  index: -1
+front_bracer
+  rotate: false
+  xy: 880, 695
+  size: 41, 29
+  orig: 41, 29
+  offset: 0, 0
+  index: -1
+front_hand
+  rotate: true
+  xy: 167, 394
+  size: 41, 38
+  orig: 41, 38
+  offset: 0, 0
+  index: -1
+front_open_hand
+  rotate: false
+  xy: 880, 726
+  size: 43, 44
+  orig: 43, 44
+  offset: 0, 0
+  index: -1
+front_thigh
+  rotate: false
+  xy: 360, 545
+  size: 57, 29
+  orig: 57, 29
+  offset: 0, 0
+  index: -1
+gun
+  rotate: false
+  xy: 785, 774
+  size: 107, 103
+  orig: 107, 103
+  offset: 0, 0
+  index: -1
+gun_nohand
+  rotate: false
+  xy: 614, 703
+  size: 105, 102
+  orig: 105, 102
+  offset: 0, 0
+  index: -1
+head
+  rotate: false
+  xy: 2, 137
+  size: 136, 149
+  orig: 136, 149
+  offset: 0, 0
+  index: -1
+lower_leg
+  rotate: true
+  xy: 780, 699
+  size: 73, 98
+  orig: 73, 98
+  offset: 0, 0
+  index: -1
+mouth_grind
+  rotate: false
+  xy: 469, 544
+  size: 47, 30
+  orig: 47, 30
+  offset: 0, 0
+  index: -1
+mouth_oooo
+  rotate: true
+  xy: 894, 772
+  size: 105, 30
+  orig: 105, 30
+  offset: 0, 0
+  index: -1
+mouth_smile
+  rotate: true
+  xy: 140, 239
+  size: 47, 30
+  orig: 47, 30
+  offset: 0, 0
+  index: -1
+neck
+  rotate: true
+  xy: 538, 577
+  size: 18, 21
+  orig: 18, 21
+  offset: 0, 0
+  index: -1
+raptor_arm_back
+  rotate: false
+  xy: 940, 936
+  size: 82, 86
+  orig: 82, 86
+  offset: 0, 0
+  index: -1
+raptor_body
+  rotate: false
+  xy: 2, 737
+  size: 610, 285
+  orig: 610, 285
+  offset: 0, 0
+  index: -1
+raptor_front_arm
+  rotate: true
+  xy: 195, 464
+  size: 81, 102
+  orig: 81, 102
+  offset: 0, 0
+  index: -1
+raptor_front_leg
+  rotate: false
+  xy: 2, 478
+  size: 191, 257
+  orig: 191, 257
+  offset: 0, 0
+  index: -1
+raptor_hindleg_back
+  rotate: false
+  xy: 614, 807
+  size: 169, 215
+  orig: 169, 215
+  offset: 0, 0
+  index: -1
+raptor_horn
+  rotate: false
+  xy: 360, 655
+  size: 182, 80
+  orig: 182, 80
+  offset: 0, 0
+  index: -1
+raptor_horn_back
+  rotate: false
+  xy: 360, 576
+  size: 176, 77
+  orig: 176, 77
+  offset: 0, 0
+  index: -1
+raptor_jaw
+  rotate: false
+  xy: 785, 879
+  size: 153, 143
+  orig: 153, 143
+  offset: 0, 0
+  index: -1
+raptor_saddle_noshadow
+  rotate: false
+  xy: 2, 288
+  size: 163, 188
+  orig: 163, 188
+  offset: 0, 0
+  index: -1
+raptor_saddle_strap_front
+  rotate: false
+  xy: 721, 710
+  size: 57, 95
+  orig: 57, 95
+  offset: 0, 0
+  index: -1
+raptor_saddle_strap_rear
+  rotate: true
+  xy: 940, 880
+  size: 54, 74
+  orig: 54, 74
+  offset: 0, 0
+  index: -1
+raptor_saddle_w_shadow
+  rotate: false
+  xy: 195, 547
+  size: 163, 188
+  orig: 163, 188
+  offset: 0, 0
+  index: -1
+raptor_tongue
+  rotate: true
+  xy: 544, 649
+  size: 86, 64
+  orig: 86, 64
+  offset: 0, 0
+  index: -1
+stirrup_back
+  rotate: true
+  xy: 140, 145
+  size: 44, 35
+  orig: 44, 35
+  offset: 0, 0
+  index: -1
+stirrup_front
+  rotate: false
+  xy: 538, 597
+  size: 45, 50
+  orig: 45, 50
+  offset: 0, 0
+  index: -1
+stirrup_strap
+  rotate: false
+  xy: 350, 497
+  size: 49, 46
+  orig: 49, 46
+  offset: 0, 0
+  index: -1
+torso
+  rotate: true
+  xy: 610, 647
+  size: 54, 91
+  orig: 54, 91
+  offset: 0, 0
+  index: -1
+visor
+  rotate: false
+  xy: 2, 51
+  size: 131, 84
+  orig: 131, 84
+  offset: 0, 0
+  index: -1

Plik diff jest za duży
+ 361 - 0
spine-ts/canvas/example/assets/raptor.json


BIN
spine-ts/canvas/example/assets/raptor.png


+ 125 - 0
spine-ts/canvas/example/assets/tank.atlas

@@ -0,0 +1,125 @@
+
+tank.png
+size: 2048,1024
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+images/antenna
+  rotate: true
+  xy: 1295, 683
+  size: 22, 303
+  orig: 22, 303
+  offset: 0, 0
+  index: -1
+images/cannon
+  rotate: false
+  xy: 2, 93
+  size: 931, 58
+  orig: 931, 58
+  offset: 0, 0
+  index: -1
+images/cannonConnector
+  rotate: true
+  xy: 1676, 455
+  size: 112, 135
+  orig: 112, 135
+  offset: 0, 0
+  index: -1
+images/guntower
+  rotate: false
+  xy: 1295, 707
+  size: 730, 289
+  orig: 730, 289
+  offset: 0, 0
+  index: -1
+images/machinegun
+  rotate: false
+  xy: 2, 34
+  size: 331, 57
+  orig: 331, 57
+  offset: 0, 0
+  index: -1
+images/machinegun-mount
+  rotate: false
+  xy: 1952, 609
+  size: 72, 96
+  orig: 72, 96
+  offset: 0, 0
+  index: -1
+images/rock
+  rotate: false
+  xy: 935, 96
+  size: 252, 55
+  orig: 252, 55
+  offset: 0, 0
+  index: -1
+images/tankBottom
+  rotate: false
+  xy: 2, 377
+  size: 1285, 276
+  orig: 1285, 276
+  offset: 0, 0
+  index: -1
+images/tankBottom-shadow
+  rotate: false
+  xy: 2, 655
+  size: 1291, 341
+  orig: 1291, 341
+  offset: 0, 0
+  index: -1
+images/tankTop
+  rotate: false
+  xy: 2, 153
+  size: 1407, 222
+  orig: 1407, 222
+  offset: 0, 0
+  index: -1
+images/tread
+  rotate: false
+  xy: 2, 2
+  size: 96, 30
+  orig: 96, 30
+  offset: 0, 0
+  index: -1
+images/tread-inside
+  rotate: false
+  xy: 335, 63
+  size: 25, 28
+  orig: 25, 28
+  offset: 0, 0
+  index: -1
+images/wheel-big
+  rotate: false
+  xy: 1295, 490
+  size: 191, 191
+  orig: 191, 191
+  offset: 0, 0
+  index: -1
+images/wheel-big-overlay
+  rotate: false
+  xy: 1488, 495
+  size: 186, 186
+  orig: 186, 186
+  offset: 0, 0
+  index: -1
+images/wheel-mid
+  rotate: false
+  xy: 1676, 569
+  size: 136, 136
+  orig: 136, 136
+  offset: 0, 0
+  index: -1
+images/wheel-mid-overlay
+  rotate: false
+  xy: 1814, 569
+  size: 136, 136
+  orig: 136, 136
+  offset: 0, 0
+  index: -1
+images/wheel-small
+  rotate: false
+  xy: 1813, 496
+  size: 71, 71
+  orig: 71, 71
+  offset: 0, 0
+  index: -1

+ 1899 - 0
spine-ts/canvas/example/assets/tank.json

@@ -0,0 +1,1899 @@
+{
+"skeleton": { "hash": "kgtyty1lpfv5JU2lygtFi2u3oQQ", "spine": "3.3.07", "width": 1914.53, "height": 964.05, "images": "" },
+"bones": [
+	{ "name": "root" },
+	{ "name": "tankRoot", "parent": "root", "y": 200 },
+	{ "name": "tankTreads", "parent": "tankRoot" },
+	{ "name": "tankBody", "parent": "tankTreads", "y": 10 },
+	{ "name": "guntower", "parent": "tankBody", "x": -21.72, "y": 245.47 },
+	{ "name": "antennaRoot", "parent": "guntower", "x": 164.6, "y": 202.52 },
+	{ "name": "antenna1", "parent": "antennaRoot", "length": 40, "rotation": 90, "y": 39.99, "color": "ffee00ff" },
+	{ "name": "antenna2", "parent": "antenna1", "length": 42, "x": 42, "color": "ffee00ff" },
+	{ "name": "antenna3", "parent": "antenna2", "length": 42, "x": 42, "color": "ffee00ff" },
+	{ "name": "antenna4", "parent": "antenna3", "length": 42, "x": 42, "color": "ffee00ff" },
+	{ "name": "antenna5", "parent": "antenna4", "length": 42, "x": 42, "color": "ffee00ff" },
+	{ "name": "antenna6", "parent": "antenna5", "length": 42, "x": 42, "color": "ffee00ff" },
+	{ "name": "cannonConnector", "parent": "guntower", "x": -235.04, "y": 96.07 },
+	{ "name": "cannonTarget", "parent": "tankRoot", "x": -1486.66, "y": 351.82, "color": "ff3f00ff" },
+	{ "name": "cannon", "parent": "cannonConnector", "length": 946.68, "rotation": 180, "color": "ff4000ff" },
+	{ "name": "cannonTip", "parent": "cannon", "x": 946.68, "color": "ff4000ff" },
+	{ "name": "machineGunTarget", "parent": "tankRoot", "x": -1474, "y": 559.42, "color": "ff3f00ff" },
+	{
+		"name": "machinegun-mount",
+		"parent": "guntower",
+		"length": 90.97,
+		"rotation": 90,
+		"x": -123.72,
+		"y": 218.32,
+		"color": "15ff00ff"
+	},
+	{
+		"name": "machinegun",
+		"parent": "machinegun-mount",
+		"length": 208.94,
+		"rotation": 90,
+		"x": 91.52,
+		"y": -1.03,
+		"color": "15ff00ff"
+	},
+	{ "name": "machinegun-tip", "parent": "machinegun", "x": 210.42, "y": -12.2 },
+	{ "name": "rock", "parent": "root", "x": -656.45 },
+	{
+		"name": "tread",
+		"parent": "tankRoot",
+		"length": 82,
+		"rotation": 180,
+		"x": -22.89,
+		"y": 213.85,
+		"scaleX": 0.993,
+		"color": "e64344ff"
+	},
+	{ "name": "tread2", "parent": "tread", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread3", "parent": "tread2", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread4", "parent": "tread3", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread5", "parent": "tread4", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread6", "parent": "tread5", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread7", "parent": "tread6", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread8", "parent": "tread7", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread9", "parent": "tread8", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread10", "parent": "tread9", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread11", "parent": "tread10", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread12", "parent": "tread11", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread13", "parent": "tread12", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread14", "parent": "tread13", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread15", "parent": "tread14", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread16", "parent": "tread15", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread17", "parent": "tread16", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread18", "parent": "tread17", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread19", "parent": "tread18", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread20", "parent": "tread19", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread21", "parent": "tread20", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread22", "parent": "tread21", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread23", "parent": "tread22", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread24", "parent": "tread23", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread25", "parent": "tread24", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread26", "parent": "tread25", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread27", "parent": "tread26", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread28", "parent": "tread27", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread29", "parent": "tread28", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread30", "parent": "tread29", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread31", "parent": "tread30", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread32", "parent": "tread31", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread33", "parent": "tread32", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread34", "parent": "tread33", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread35", "parent": "tread34", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "tread36", "parent": "tread35", "length": 82, "x": 82, "color": "e64344ff" },
+	{ "name": "wheel-midCenter", "parent": "tankRoot", "y": -114.56 },
+	{ "name": "treadCollider1", "parent": "wheel-midCenter", "x": -329.57, "y": -85.44, "color": "ff00fbff" },
+	{ "name": "treadCollider2", "parent": "wheel-midCenter", "x": -165.95, "y": -85.44, "color": "ff00fbff" },
+	{ "name": "treadCollider3", "parent": "wheel-midCenter", "y": -85.44, "color": "ff00fbff" },
+	{ "name": "treadCollider4", "parent": "wheel-midCenter", "x": 163.56, "y": -85.44, "color": "ff00fbff" },
+	{ "name": "treadCollider5", "parent": "wheel-midCenter", "x": 329.12, "y": -85.44, "color": "ff00fbff" },
+	{ "name": "treadGravity1", "parent": "tankRoot", "rotation": 180, "x": -175.35, "y": 109.99, "color": "ff00fbff" },
+	{ "name": "treadGravity2", "parent": "tankRoot", "rotation": 180, "x": 177.88, "y": 105.45, "color": "ff00fbff" },
+	{ "name": "wheel-bigRoot1", "parent": "tankTreads", "x": -549.59, "y": 14.39, "color": "abe323ff" },
+	{ "name": "wheel-big1", "parent": "wheel-bigRoot1", "x": -0.02, "color": "abe323ff" },
+	{ "name": "wheel-bigRoot2", "parent": "tankTreads", "x": 547.33, "y": 14.39 },
+	{ "name": "wheel-big2", "parent": "wheel-bigRoot2" },
+	{ "name": "wheel-midRoot1", "parent": "wheel-midCenter", "x": -410.57, "color": "abe323ff" },
+	{ "name": "wheel-mid1", "parent": "wheel-midRoot1", "color": "abe323ff" },
+	{ "name": "wheel-midRoot2", "parent": "wheel-midCenter", "x": -246.95 },
+	{ "name": "wheel-mid2", "parent": "wheel-midRoot2" },
+	{ "name": "wheel-midRoot3", "parent": "wheel-midCenter", "x": -82.72 },
+	{ "name": "wheel-mid3", "parent": "wheel-midRoot3" },
+	{ "name": "wheel-midRoot4", "parent": "wheel-midCenter", "x": 80.89 },
+	{ "name": "wheel-mid4", "parent": "wheel-midRoot4" },
+	{ "name": "wheel-midRoot5", "parent": "wheel-midCenter", "x": 244.51 },
+	{ "name": "wheel-mid5", "parent": "wheel-midRoot5" },
+	{ "name": "wheel-midRoot6", "parent": "wheel-midCenter", "x": 408.73 },
+	{ "name": "wheel-mid6", "parent": "wheel-midRoot6" },
+	{ "name": "wheel-smallRoot1", "parent": "tankTreads", "x": -337.38, "y": 109.43 },
+	{ "name": "wheel-small1", "parent": "wheel-smallRoot1", "color": "abe323ff" },
+	{ "name": "wheel-smallRoot2", "parent": "tankTreads", "x": 0.08, "y": 109.43 },
+	{ "name": "wheel-small2", "parent": "wheel-smallRoot2" },
+	{ "name": "wheel-smallRoot3", "parent": "tankTreads", "x": 334.68, "y": 109.43 },
+	{ "name": "wheel-small3", "parent": "wheel-smallRoot3" }
+],
+"slots": [
+	{ "name": "tankBody-shadow", "bone": "tankBody", "color": "ffffffb9", "attachment": "images/tankBottom-shadow" },
+	{ "name": "bottom", "bone": "tankBody", "attachment": "images/tankBottom" },
+	{ "name": "tread-inside1", "bone": "tread", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside53", "bone": "tread27", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside27", "bone": "tread14", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside3", "bone": "tread2", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside55", "bone": "tread28", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside29", "bone": "tread15", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside5", "bone": "tread3", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside57", "bone": "tread29", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside31", "bone": "tread16", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside7", "bone": "tread4", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside59", "bone": "tread30", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside33", "bone": "tread17", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside9", "bone": "tread5", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside61", "bone": "tread31", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside35", "bone": "tread18", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside11", "bone": "tread6", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside63", "bone": "tread32", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside37", "bone": "tread19", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside13", "bone": "tread7", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside65", "bone": "tread33", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside39", "bone": "tread20", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside15", "bone": "tread8", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside67", "bone": "tread34", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside69", "bone": "tread35", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside71", "bone": "tread36", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside41", "bone": "tread21", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside17", "bone": "tread9", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside43", "bone": "tread22", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside19", "bone": "tread10", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside45", "bone": "tread23", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside21", "bone": "tread11", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside47", "bone": "tread24", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside23", "bone": "tread12", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside49", "bone": "tread25", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside25", "bone": "tread13", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside51", "bone": "tread26", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside2", "bone": "tread", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside54", "bone": "tread27", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside28", "bone": "tread14", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside4", "bone": "tread2", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside56", "bone": "tread28", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside30", "bone": "tread15", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside6", "bone": "tread3", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside58", "bone": "tread29", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside32", "bone": "tread16", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside8", "bone": "tread4", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside60", "bone": "tread30", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside34", "bone": "tread17", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside10", "bone": "tread5", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside62", "bone": "tread31", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside36", "bone": "tread18", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside12", "bone": "tread6", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside64", "bone": "tread32", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside38", "bone": "tread19", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside14", "bone": "tread7", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside66", "bone": "tread33", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside40", "bone": "tread20", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside16", "bone": "tread8", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside68", "bone": "tread34", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside70", "bone": "tread35", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside72", "bone": "tread36", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside42", "bone": "tread21", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside18", "bone": "tread9", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside44", "bone": "tread22", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside20", "bone": "tread10", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside46", "bone": "tread23", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside22", "bone": "tread11", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside48", "bone": "tread24", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside24", "bone": "tread12", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside50", "bone": "tread25", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside26", "bone": "tread13", "attachment": "images/tread-inside" },
+	{ "name": "tread-inside52", "bone": "tread26", "attachment": "images/tread-inside" },
+	{ "name": "wheel-big", "bone": "wheel-big1", "color": "dbdbdbff", "attachment": "images/wheel-big" },
+	{ "name": "wheel-big2", "bone": "wheel-big2", "color": "dbdbdbff", "attachment": "images/wheel-big" },
+	{ "name": "wheel-mid", "bone": "wheel-mid1", "attachment": "images/wheel-mid" },
+	{ "name": "wheel-mid2", "bone": "wheel-mid2", "attachment": "images/wheel-mid" },
+	{ "name": "wheel-mid3", "bone": "wheel-mid3", "attachment": "images/wheel-mid" },
+	{ "name": "wheel-mid4", "bone": "wheel-mid4", "attachment": "images/wheel-mid" },
+	{ "name": "wheel-mid5", "bone": "wheel-mid5", "attachment": "images/wheel-mid" },
+	{ "name": "wheel-mid6", "bone": "wheel-mid6", "attachment": "images/wheel-mid" },
+	{ "name": "wheel-small", "bone": "wheel-small1", "attachment": "images/wheel-small" },
+	{ "name": "wheel-small2", "bone": "wheel-small2", "attachment": "images/wheel-small" },
+	{ "name": "wheel-small3", "bone": "wheel-small3", "attachment": "images/wheel-small" },
+	{
+		"name": "wheel-mid-overlay",
+		"bone": "wheel-midRoot1",
+		"color": "ffffffec",
+		"attachment": "images/wheel-mid-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-mid-overlay2",
+		"bone": "wheel-midRoot2",
+		"color": "ffffffec",
+		"attachment": "images/wheel-mid-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-mid-overlay3",
+		"bone": "wheel-midRoot3",
+		"color": "ffffffec",
+		"attachment": "images/wheel-mid-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-mid-overlay4",
+		"bone": "wheel-midRoot4",
+		"color": "ffffffec",
+		"attachment": "images/wheel-mid-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-mid-overlay5",
+		"bone": "wheel-midRoot5",
+		"color": "ffffffec",
+		"attachment": "images/wheel-mid-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-mid-overlay6",
+		"bone": "wheel-midRoot6",
+		"color": "ffffffec",
+		"attachment": "images/wheel-mid-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-big-overlay1",
+		"bone": "wheel-bigRoot1",
+		"color": "ffffffe9",
+		"attachment": "images/wheel-big-overlay",
+		"blend": "multiply"
+	},
+	{
+		"name": "wheel-big-overlay2",
+		"bone": "wheel-bigRoot2",
+		"color": "ffffffe9",
+		"attachment": "images/wheel-big-overlay",
+		"blend": "multiply"
+	},
+	{ "name": "treads", "bone": "tankRoot", "attachment": "treads" },
+	{ "name": "tread", "bone": "tread", "color": "c0974fff", "attachment": "images/tread" },
+	{ "name": "tread27", "bone": "tread27", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread14", "bone": "tread14", "attachment": "images/tread" },
+	{ "name": "tread2", "bone": "tread2", "attachment": "images/tread" },
+	{ "name": "tread28", "bone": "tread28", "attachment": "images/tread" },
+	{ "name": "tread15", "bone": "tread15", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread3", "bone": "tread3", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread29", "bone": "tread29", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread16", "bone": "tread16", "attachment": "images/tread" },
+	{ "name": "tread4", "bone": "tread4", "attachment": "images/tread" },
+	{ "name": "tread30", "bone": "tread30", "attachment": "images/tread" },
+	{ "name": "tread17", "bone": "tread17", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread5", "bone": "tread5", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread31", "bone": "tread31", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread18", "bone": "tread18", "attachment": "images/tread" },
+	{ "name": "tread6", "bone": "tread6", "attachment": "images/tread" },
+	{ "name": "tread32", "bone": "tread32", "attachment": "images/tread" },
+	{ "name": "tread19", "bone": "tread19", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread7", "bone": "tread7", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread33", "bone": "tread33", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread20", "bone": "tread20", "attachment": "images/tread" },
+	{ "name": "tread8", "bone": "tread8", "attachment": "images/tread" },
+	{ "name": "tread34", "bone": "tread34", "attachment": "images/tread" },
+	{ "name": "tread35", "bone": "tread35", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread36", "bone": "tread36", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread21", "bone": "tread21", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread9", "bone": "tread9", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread22", "bone": "tread22", "attachment": "images/tread" },
+	{ "name": "tread10", "bone": "tread10", "attachment": "images/tread" },
+	{ "name": "tread23", "bone": "tread23", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread11", "bone": "tread11", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread24", "bone": "tread24", "attachment": "images/tread" },
+	{ "name": "tread12", "bone": "tread12", "attachment": "images/tread" },
+	{ "name": "tread25", "bone": "tread25", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread13", "bone": "tread13", "color": "adc9b8ff", "attachment": "images/tread" },
+	{ "name": "tread26", "bone": "tread26", "attachment": "images/tread" },
+	{ "name": "rock", "bone": "rock", "attachment": "images/rock" },
+	{ "name": "machinegun", "bone": "machinegun", "attachment": "images/machinegun" },
+	{ "name": "machinegun-mount", "bone": "machinegun-mount", "attachment": "images/machinegun-mount" },
+	{ "name": "tankTop", "bone": "tankBody", "attachment": "images/tankTop" },
+	{ "name": "guntower", "bone": "guntower", "attachment": "images/guntower" },
+	{ "name": "cannon", "bone": "cannon", "attachment": "images/cannon" },
+	{ "name": "cannonConnector", "bone": "cannonConnector", "attachment": "images/cannonConnector" },
+	{ "name": "antenna", "bone": "antennaRoot", "attachment": "images/antenna" }
+],
+"ik": [
+	{
+		"name": "cannonTarget",
+		"bones": [ "cannon" ],
+		"target": "cannonTarget"
+	},
+	{
+		"name": "machineGunTarget",
+		"bones": [ "machinegun" ],
+		"target": "machineGunTarget",
+		"mix": 0
+	}
+],
+"transform": [
+	{
+		"name": "wheel-big",
+		"bones": [ "wheel-big2" ],
+		"target": "wheel-big1",
+		"rotation": 65.6,
+		"translateMix": 0,
+		"scaleMix": 0,
+		"shearMix": 0
+	},
+	{
+		"name": "wheel-mid1",
+		"bones": [ "wheel-mid2", "wheel-mid4" ],
+		"target": "wheel-mid1",
+		"rotation": 93,
+		"translateMix": 0,
+		"scaleMix": 0,
+		"shearMix": 0
+	},
+	{
+		"name": "wheel-mid2",
+		"bones": [ "wheel-mid3", "wheel-mid5" ],
+		"target": "wheel-mid1",
+		"rotation": -89,
+		"translateMix": 0,
+		"scaleMix": 0,
+		"shearMix": 0
+	},
+	{
+		"name": "wheel-mid3",
+		"bones": [ "wheel-mid6" ],
+		"target": "wheel-mid1",
+		"rotation": -152.6,
+		"translateMix": 0,
+		"scaleMix": 0,
+		"shearMix": 0
+	},
+	{
+		"name": "wheel-small1",
+		"bones": [ "wheel-small2" ],
+		"target": "wheel-small1",
+		"rotation": 87,
+		"translateMix": 0,
+		"scaleMix": 0,
+		"shearMix": 0
+	},
+	{
+		"name": "wheel-small2",
+		"bones": [ "wheel-small3" ],
+		"target": "wheel-small1",
+		"rotation": 54.9,
+		"translateMix": 0,
+		"scaleMix": 0,
+		"shearMix": 0
+	}
+],
+"path": [
+	{
+		"name": "treads",
+		"bones": [
+			"tread",
+			"tread2",
+			"tread3",
+			"tread4",
+			"tread5",
+			"tread6",
+			"tread7",
+			"tread8",
+			"tread9",
+			"tread10",
+			"tread11",
+			"tread12",
+			"tread13",
+			"tread14",
+			"tread15",
+			"tread16",
+			"tread17",
+			"tread18",
+			"tread19",
+			"tread20",
+			"tread21",
+			"tread22",
+			"tread23",
+			"tread24",
+			"tread25",
+			"tread26",
+			"tread27",
+			"tread28",
+			"tread29",
+			"tread30",
+			"tread31",
+			"tread32",
+			"tread33",
+			"tread34",
+			"tread35",
+			"tread36"
+		],
+		"target": "treads",
+		"rotateMode": "chain"
+	}
+],
+"skins": {
+	"default": {
+		"antenna": {
+			"images/antenna": {
+				"type": "mesh",
+				"uvs": [ 0.64286, 0.07875, 0.65354, 0.15349, 0.66324, 0.22137, 0.67367, 0.29433, 0.68383, 0.36543, 0.69359, 0.43374, 0.7031, 0.50029, 0.71311, 0.5703, 0.72327, 0.64138, 0.73406, 0.71688, 0.7444, 0.78929, 0.75614, 0.8714, 0.76905, 0.9431, 1, 0.9431, 1, 1, 0, 1, 0, 0.9431, 0.20105, 0.9431, 0.20105, 0.87093, 0.21461, 0.78846, 0.22651, 0.71606, 0.23885, 0.64098, 0.25035, 0.57104, 0.26206, 0.49983, 0.27306, 0.4329, 0.2843, 0.36453, 0.29592, 0.29381, 0.308, 0.22037, 0.319, 0.15345, 0.33141, 0.07795, 0.34423, 0, 0.6316, 0 ],
+				"triangles": [ 30, 31, 0, 29, 30, 0, 29, 0, 1, 28, 29, 1, 28, 1, 2, 27, 28, 2, 27, 2, 3, 26, 3, 4, 25, 26, 4, 25, 4, 5, 26, 27, 3, 24, 5, 6, 23, 24, 6, 7, 23, 6, 24, 25, 5, 22, 7, 8, 21, 22, 8, 21, 8, 9, 7, 22, 23, 20, 9, 10, 19, 20, 10, 20, 21, 9, 19, 10, 11, 18, 19, 11, 17, 18, 11, 17, 11, 12, 15, 16, 17, 12, 13, 14, 15, 17, 12, 14, 15, 12 ],
+				"vertices": [ 2, 10, 65.37999, -3.14, 0.3125, 11, 23.38, -3.14, 0.6875, 3, 9, 84.73, -3.37, 0.0625, 10, 42.73, -3.37, 0.625, 11, 0.73, -3.37, 0.3125, 3, 9, 64.16, -3.59, 0.3125, 10, 22.16, -3.59, 0.625, 11, -19.83, -3.59, 0.0625, 3, 8, 84.06, -3.82, 0.0625, 9, 42.06, -3.82, 0.625, 10, 0.06, -3.82, 0.3125, 3, 8, 62.51, -4.04, 0.3125, 9, 20.51, -4.04, 0.625, 10, -21.48, -4.04, 0.0625, 3, 7, 83.81, -4.25, 0.0625, 8, 41.81, -4.25, 0.625, 9, -0.18, -4.25, 0.3125, 3, 7, 63.65, -4.46, 0.3125, 8, 21.65, -4.46, 0.625, 9, -20.34, -4.46, 0.0625, 3, 6, 84.43, -4.67999, 0.0625, 7, 42.43, -4.67999, 0.625, 8, 0.43, -4.67999, 0.3125, 3, 6, 62.9, -4.91, 0.3125, 7, 20.9, -4.91, 0.625, 8, -21.09, -4.91, 0.0625, 3, 5, 5.14, 80.01999, 0.0625, 6, 40.02, -5.14, 0.625, 7, -1.97, -5.14, 0.3125, 3, 5, 5.37, 58.08, 0.375, 6, 18.08, -5.37, 0.5625, 7, -23.91, -5.37, 0.0625, 1, 5, 5.63, 33.2, 1, 1, 5, 5.91, 11.48, 1, 1, 5, 11, 11.48, 1, 1, 5, 10.99, -5.75, 1, 1, 5, -11, -5.75, 1, 1, 5, -10.99, 11.48, 1, 1, 5, -6.57, 11.48, 1, 1, 5, -6.57, 33.34, 1, 3, 5, -6.27, 58.33, 0.375, 6, 18.33, 6.27, 0.5625, 7, -23.66, 6.27, 0.0625, 3, 5, -6.01, 80.26999, 0.0625, 6, 40.27, 6.01, 0.625, 7, -1.72, 6.01, 0.3125, 3, 6, 63.02, 5.74, 0.3125, 7, 21.02, 5.74, 0.625, 8, -20.96999, 5.74, 0.0625, 3, 6, 84.21, 5.49, 0.0625, 7, 42.21, 5.49, 0.625, 8, 0.21, 5.49, 0.3125, 3, 7, 63.79, 5.23, 0.3125, 8, 21.79, 5.23, 0.625, 9, -20.2, 5.23, 0.0625, 3, 7, 84.07, 4.98999, 0.0625, 8, 42.07, 4.98999, 0.625, 9, 0.07, 4.98999, 0.3125, 3, 8, 62.78, 4.73999, 0.3125, 9, 20.78, 4.73999, 0.625, 10, -21.21, 4.73999, 0.0625, 3, 8, 84.21, 4.48, 0.0625, 9, 42.21, 4.48, 0.625, 10, 0.21, 4.48, 0.3125, 3, 9, 64.46, 4.21999, 0.3125, 10, 22.46, 4.21999, 0.625, 11, -19.53, 4.21999, 0.0625, 3, 9, 84.74, 3.98, 0.0625, 10, 42.74, 3.98, 0.625, 11, 0.74, 3.98, 0.3125, 2, 10, 65.62, 3.7, 0.3125, 11, 23.62, 3.7, 0.6875, 1, 11, 47.24, 3.42, 1, 1, 11, 47.24, -2.89, 1 ],
+				"hull": 32,
+				"edges": [ 28, 30, 28, 26, 30, 32, 26, 24, 24, 22, 32, 34, 34, 24, 34, 36, 36, 22, 60, 62, 38, 36, 20, 22, 38, 20, 40, 38, 18, 20, 40, 18, 42, 40, 16, 18, 42, 16, 44, 42, 14, 16, 44, 14, 46, 44, 12, 14, 46, 12, 48, 46, 10, 12, 48, 10, 50, 48, 8, 10, 50, 8, 52, 50, 6, 8, 52, 6, 54, 52, 4, 6, 54, 4, 56, 54, 2, 4, 56, 2, 60, 58, 58, 56, 62, 0, 0, 2, 58, 0 ],
+				"width": 22,
+				"height": 303
+			}
+		},
+		"bottom": {
+			"images/tankBottom": { "x": -16.66, "y": 9.89, "width": 1285, "height": 276 }
+		},
+		"cannon": {
+			"images/cannon": { "x": 481.95, "y": -0.02, "rotation": 179.99, "width": 931, "height": 58 }
+		},
+		"cannonConnector": {
+			"images/cannonConnector": {
+				"type": "mesh",
+				"uvs": [ 1, 0.03236, 1, 0.10602, 0.90987, 0.32859, 0.81975, 0.55116, 0.72962, 0.77372, 0.6395, 0.99629, 0.42157, 0.99629, 0.20364, 0.99629, 0, 0.85433, 0, 0.69901, 0.02267, 0.52884, 0, 0.31444, 0.21601, 0.12998, 0.43367, 0, 0.63546, 0.0037, 0.48407, 0.77059, 0.31496, 0.52496, 0.64132, 0.19648, 0.21516, 0.76765, 0.58345, 0.5647, 0.68444, 0.40146, 0.46758, 0.36649, 0.28934, 0.34603 ],
+				"triangles": [ 21, 22, 12, 11, 12, 22, 17, 21, 13, 17, 13, 14, 21, 12, 13, 21, 17, 20, 16, 22, 21, 10, 11, 22, 10, 22, 16, 19, 21, 20, 16, 21, 19, 18, 10, 16, 9, 10, 18, 15, 16, 19, 18, 16, 15, 8, 9, 18, 7, 8, 18, 6, 18, 15, 7, 18, 6, 14, 0, 1, 17, 14, 1, 2, 17, 1, 20, 17, 2, 3, 20, 2, 19, 20, 3, 4, 19, 3, 15, 19, 4, 5, 15, 4, 6, 15, 5 ],
+				"vertices": [ 1, 12, 35.91, 69.08, 1, 1, 12, 35.91, 59.13, 1, 1, 12, 25.81, 29.09, 1, 1, 12, 15.72, -0.95, 1, 1, 12, 5.63, -31, 1, 1, 12, -4.46, -61.04, 1, 2, 12, -28.87, -61.04, 0.33333, 14, 28.87, 61.03, 0.66666, 1, 14, 53.27, 61.01, 1, 1, 14, 76.08, 41.83, 1, 1, 14, 71.17, 21.62, 1, 1, 14, 72.83, -1.62, 1, 1, 14, 70.37, -29.12, 1, 1, 14, 50.66, -56.13, 1, 2, 12, -28.43, 74.37, 0.41, 14, 28.43, -74.39, 0.58999, 2, 12, -4.91, 72.94999, 0.52, 14, 4.91, -72.94999, 0.48, 2, 12, -21.87, -30.57, 0.49, 14, 21.87, 30.56, 0.51, 1, 14, 40.81, -2.59999, 1, 2, 12, -4.25, 46.92, 0.49, 14, 4.25, -46.92, 0.51, 1, 14, 51.98, 30.15, 1, 2, 12, -10.74, -2.78, 0.49, 14, 10.74, 2.77, 0.51, 2, 12, 0.56, 19.25, 0.49, 14, -0.56, -19.25, 0.51, 1, 14, 23.71, -23.98, 1, 1, 14, 43.68, -26.76, 1 ],
+				"hull": 15,
+				"edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 0 ],
+				"width": 112,
+				"height": 135
+			}
+		},
+		"guntower": {
+			"images/guntower": { "x": 77.22, "y": 122.58, "width": 730, "height": 289 }
+		},
+		"machinegun": {
+			"images/machinegun": { "x": 44.85, "y": -5.72, "rotation": -180, "width": 331, "height": 57 }
+		},
+		"machinegun-mount": {
+			"images/machinegun-mount": { "x": 47.42, "y": -1.53, "rotation": -90, "width": 72, "height": 96 }
+		},
+		"rock": {
+			"images/rock": { "color": "404040ff", "x": 25.23, "y": 27.35, "width": 252, "height": 55 }
+		},
+		"tankBody-shadow": {
+			"images/tankBottom-shadow": { "x": -11.43, "y": -42.88, "width": 1291, "height": 341 }
+		},
+		"tankTop": {
+			"images/tankTop": { "x": 6.8, "y": 168.71, "width": 1407, "height": 222 }
+		},
+		"tread": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread-inside1": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside10": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside11": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside12": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside13": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside14": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside15": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside16": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside17": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside18": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside19": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside2": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside20": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside21": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside22": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside23": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside24": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside25": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside26": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside27": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside28": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside29": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside3": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside30": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside31": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside32": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside33": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside34": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside35": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside36": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside37": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside38": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside39": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside4": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside40": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside41": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside42": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside43": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside44": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside45": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside46": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside47": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside48": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside49": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside5": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside50": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside51": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside52": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside53": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside54": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside55": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside56": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside57": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside58": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside59": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside6": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside60": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside61": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside62": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside63": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside64": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside65": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside66": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside67": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside68": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside69": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside7": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside70": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside71": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside72": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside8": {
+			"images/tread-inside": { "x": 20.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread-inside9": {
+			"images/tread-inside": { "x": 60.1, "y": 12.56, "rotation": -180, "width": 25, "height": 28 }
+		},
+		"tread10": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread11": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread12": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread13": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread14": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread15": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread16": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread17": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread18": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread19": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread2": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread20": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread21": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread22": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread23": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread24": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread25": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread26": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread27": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread28": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread29": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread3": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread30": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread31": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread32": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread33": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread34": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread35": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread36": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread4": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread5": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread6": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread7": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread8": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"tread9": {
+			"images/tread": { "x": 45.47, "y": -8.28, "rotation": -179.99, "width": 96, "height": 30 }
+		},
+		"treads": {
+			"treads": {
+				"type": "path",
+				"closed": true,
+				"lengths": [ 182.41, 349, 472.77, 602.99, 780.46, 1052.96, 1133.44, 1218.43, 1298.34, 1382.7, 1465.57, 1546.11, 1628.02, 1707.73, 1794.36, 1876.75, 2158.69, 2321.34, 2438.56, 2579.42, 2745.35, 2919.23 ],
+				"vertexCount": 66,
+				"vertices": [ 1, 83, 11.23, 41.86, 1, 1, 83, 0.78, 41.93999, 1, 1, 83, -34.72, 42.23, 1, 1, 63, -104.21, 0.41, 1, 1, 63, 0.07, 0.55, 1, 1, 63, 68.8, 0.64, 1, 1, 81, 20.5, 43.47, 1, 1, 81, 1.13, 40.81, 1, 1, 81, -27.38, 36.84, 1, 1, 65, 147.06, 105, 1, 1, 65, 96.21, 96.63, 1, 1, 65, 43.87, 87.71, 1, 1, 65, 16.18, 103.34, 1, 1, 65, -33.66999, 94.2, 1, 1, 65, -99.35, 81.25, 1, 1, 65, -122.04, -1.69, 1, 1, 65, -83.58, -47.92, 1, 1, 65, -33.53, -109.36, 1, 1, 69, -83.56, -66.08999, 1, 1, 69, -2.16, -67.89, 1, 2, 69, 56.68, -41.48, 0.67999, 58, -24.31, -41.49, 0.32, 1, 58, -26.58, 16.69, 1, 1, 58, -2.69, 16.69, 1, 1, 58, 13.51, 16.69, 1, 2, 71, -52.41, -46.51, 0.74399, 58, 30.2, -46.51, 0.256, 1, 71, -0.32, -68.92, 1, 2, 71, 52.09, -44.72, 0.712, 59, -28.9, -44.73, 0.28799, 1, 59, -22.8, 16.24, 1, 1, 59, -1.42, 16.24, 1, 1, 59, 20.46999, 16.24, 1, 2, 73, -47.21, -47.45, 0.744, 59, 36.00999, -47.46, 0.25599, 1, 73, -0.28, -69.65, 1, 2, 73, 45.23, -47.26, 0.736, 60, -37.48, -47.26, 0.26399, 1, 60, -23.76, 15.27, 1, 1, 60, -0.13, 15.27, 1, 1, 60, 24.45, 15.27, 1, 2, 75, -47.36, -48.7, 0.74399, 60, 33.52, -48.7, 0.256, 1, 75, -0.49, -70.39, 1, 2, 75, 49.09, -48.33, 0.744, 61, -33.57, -48.34, 0.25599, 1, 61, -20.89, 15.83, 1, 1, 61, -1.25, 15.83, 1, 1, 61, 15.78, 15.83, 1, 2, 77, -52.49, -48.21, 0.75999, 61, 28.45, -48.21, 0.24, 1, 77, -2.5, -68.92, 1, 2, 77, 55.72, -47.82, 0.752, 62, -28.88, -47.82, 0.248, 1, 62, -21.64, 16.69, 1, 1, 62, -0.48, 16.69, 1, 1, 62, 20.73, 16.69, 1, 2, 79, -53.65, -48.89, 0.76, 62, 25.96, -48.89, 0.23999, 1, 79, 2.27, -69.65, 1, 1, 79, 44.94, -69.74, 1, 1, 65, 1172.98, -85.6, 1, 1, 65, 1190.53, -42.24, 1, 1, 65, 1215.63, 19.75, 1, 1, 65, 1175.55, 76.62, 1, 1, 65, 1134.22, 95.07, 1, 1, 65, 1128.4, 97.66, 1, 1, 65, 1081.79, 87.47, 1, 1, 65, 1017.16, 92.52, 1, 1, 65, 977.9, 95.58, 1, 1, 85, 47.07, 42.29, 1, 1, 85, 0.24, 42.74, 1, 1, 85, -29.63, 43.28, 1, 1, 64, -86.64, 1.35, 1, 1, 64, 0.49, 0.25, 1, 1, 64, 92.42, -0.89, 1 ]
+			}
+		},
+		"wheel-big": {
+			"images/wheel-big": { "width": 191, "height": 191 }
+		},
+		"wheel-big-overlay1": {
+			"images/wheel-big-overlay": { "width": 186, "height": 186 }
+		},
+		"wheel-big-overlay2": {
+			"images/wheel-big-overlay": { "width": 186, "height": 186 }
+		},
+		"wheel-big2": {
+			"images/wheel-big": { "width": 191, "height": 191 }
+		},
+		"wheel-mid": {
+			"images/wheel-mid": { "width": 136, "height": 136 }
+		},
+		"wheel-mid-overlay": {
+			"images/wheel-mid-overlay": { "width": 136, "height": 136 }
+		},
+		"wheel-mid-overlay2": {
+			"images/wheel-mid-overlay": { "width": 136, "height": 136 }
+		},
+		"wheel-mid-overlay3": {
+			"images/wheel-mid-overlay": { "width": 136, "height": 136 }
+		},
+		"wheel-mid-overlay4": {
+			"images/wheel-mid-overlay": { "width": 136, "height": 136 }
+		},
+		"wheel-mid-overlay5": {
+			"images/wheel-mid-overlay": { "width": 136, "height": 136 }
+		},
+		"wheel-mid-overlay6": {
+			"images/wheel-mid-overlay": { "width": 136, "height": 136 }
+		},
+		"wheel-mid2": {
+			"images/wheel-mid": { "width": 136, "height": 136 }
+		},
+		"wheel-mid3": {
+			"images/wheel-mid": { "width": 136, "height": 136 }
+		},
+		"wheel-mid4": {
+			"images/wheel-mid": { "width": 136, "height": 136 }
+		},
+		"wheel-mid5": {
+			"images/wheel-mid": { "width": 136, "height": 136 }
+		},
+		"wheel-mid6": {
+			"images/wheel-mid": { "width": 136, "height": 136 }
+		},
+		"wheel-small": {
+			"images/wheel-small": { "width": 71, "height": 71 }
+		},
+		"wheel-small2": {
+			"images/wheel-small": { "width": 71, "height": 71 }
+		},
+		"wheel-small3": {
+			"images/wheel-small": { "width": 71, "height": 71 }
+		}
+	}
+},
+"animations": {
+	"drive": {
+		"bones": {
+			"tankRoot": {
+				"translate": [
+					{
+						"time": 0,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0.549, 0, 0.907, 0.84 ]
+					},
+					{
+						"time": 3.0333,
+						"x": -1426.14,
+						"y": 0,
+						"curve": [ 0.211, 0.23, 0.851, 0.92 ]
+					},
+					{
+						"time": 4.8666,
+						"x": -2806.98,
+						"y": 0,
+						"curve": [ 0.253, 0.27, 0.625, 0.94 ]
+					},
+					{ "time": 5.3333, "x": -2903.34, "y": 0 }
+				]
+			},
+			"wheel-midRoot1": {
+				"translate": [
+					{ "time": 0.7666, "x": 0, "y": 0 },
+					{
+						"time": 1.1666,
+						"x": 0,
+						"y": 50.95,
+						"curve": [ 0.633, 0, 0.907, 0.82 ]
+					},
+					{ "time": 1.5666, "x": 0, "y": 0 }
+				]
+			},
+			"treadCollider1": {
+				"rotate": [
+					{ "time": 1.1, "angle": 0 },
+					{ "time": 1.2333, "angle": -19.78 },
+					{ "time": 1.4666, "angle": 0 },
+					{ "time": 1.6, "angle": 28.87 },
+					{ "time": 1.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 1.1, "x": 0, "y": 0 },
+					{
+						"time": 1.4666,
+						"x": 0,
+						"y": 58.66,
+						"curve": [ 0.352, 0, 0.828, 0.92 ]
+					},
+					{ "time": 1.8, "x": 0, "y": 0 }
+				]
+			},
+			"wheel-midRoot2": {
+				"translate": [
+					{ "time": 1.2666, "x": 0, "y": 0 },
+					{
+						"time": 1.6333,
+						"x": 0,
+						"y": 55.07,
+						"curve": [ 0.889, 0.01, 0.843, 0.81 ]
+					},
+					{ "time": 1.9333, "x": 0, "y": 0 }
+				]
+			},
+			"treadCollider2": {
+				"rotate": [
+					{ "time": 1.5333, "angle": 0 },
+					{ "time": 1.6333, "angle": -18.67 },
+					{ "time": 1.8, "angle": 0 },
+					{ "time": 1.9, "angle": 29.49 },
+					{ "time": 2.0666, "angle": 0 }
+				],
+				"translate": [
+					{
+						"time": 1.5333,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0.16, 0.25, 0.813, 0.82 ]
+					},
+					{
+						"time": 1.8,
+						"x": 0,
+						"y": 59.03,
+						"curve": [ 0.376, 0.26, 0.879, 0.79 ]
+					},
+					{ "time": 2.0666, "x": 0, "y": 0 }
+				]
+			},
+			"wheel-midRoot3": {
+				"translate": [
+					{ "time": 1.6666, "x": 0, "y": 0 },
+					{
+						"time": 1.9333,
+						"x": 0,
+						"y": 60.17,
+						"curve": [ 0.544, 0, 0.838, 0.77 ]
+					},
+					{ "time": 2.2, "x": 0, "y": 0 }
+				]
+			},
+			"treadCollider3": {
+				"rotate": [
+					{ "time": 1.8666, "angle": 0 },
+					{ "time": 1.9333, "angle": -20.16 },
+					{ "time": 2.0666, "angle": 0.57 },
+					{ "time": 2.1666, "angle": 33.66 },
+					{ "time": 2.3333, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 1.8666, "x": 0, "y": 0 },
+					{
+						"time": 2.0666,
+						"x": 0,
+						"y": 61.53,
+						"curve": [ 0.582, 0, 0.836, 0.77 ]
+					},
+					{ "time": 2.3333, "x": 0, "y": 0 }
+				]
+			},
+			"wheel-midRoot4": {
+				"translate": [
+					{ "time": 1.9333, "x": 0, "y": 0 },
+					{
+						"time": 2.2,
+						"x": 0,
+						"y": 58.89,
+						"curve": [ 0.48, 0, 0.75, 1 ]
+					},
+					{ "time": 2.4666, "x": 0, "y": 0 }
+				]
+			},
+			"treadCollider4": {
+				"rotate": [
+					{ "time": 2.1333, "angle": 0 },
+					{ "time": 2.2, "angle": -20.43 },
+					{ "time": 2.3333, "angle": 4.49 },
+					{ "time": 2.4333, "angle": 35.87 },
+					{ "time": 2.5666, "angle": 0 }
+				],
+				"translate": [
+					{
+						"time": 2.1333,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0.191, 0.49, 0.75, 1 ]
+					},
+					{ "time": 2.3333, "x": 0, "y": 66.64 },
+					{ "time": 2.5666, "x": 0, "y": 0 }
+				]
+			},
+			"wheel-midRoot5": {
+				"translate": [
+					{ "time": 2.2, "x": 0, "y": 0 },
+					{ "time": 2.4333, "x": 0, "y": 60.26 },
+					{ "time": 2.7, "x": 0, "y": 0 }
+				]
+			},
+			"treadCollider5": {
+				"rotate": [
+					{ "time": 2.3333, "angle": 0 },
+					{ "time": 2.4333, "angle": -23.6 },
+					{ "time": 2.5666, "angle": 6.49 },
+					{ "time": 2.6666, "angle": 29.93 },
+					{ "time": 2.8, "angle": -0.13 }
+				],
+				"translate": [
+					{ "time": 2.3333, "x": 0, "y": 0 },
+					{ "time": 2.4333, "x": 0, "y": 36.34 },
+					{ "time": 2.5, "x": 0, "y": 56.39 },
+					{ "time": 2.5666, "x": 0, "y": 61.34 },
+					{ "time": 2.8, "x": 0, "y": 2.04 }
+				]
+			},
+			"wheel-midRoot6": {
+				"translate": [
+					{
+						"time": 2.4333,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0.19, 0.26, 0.804, 0.8 ]
+					},
+					{
+						"time": 2.6333,
+						"x": 0,
+						"y": 51.86,
+						"curve": [ 0.346, 0, 0.852, 0.7 ]
+					},
+					{ "time": 2.8, "x": 0, "y": 0 }
+				]
+			},
+			"wheel-mid1": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 21,
+						"curve": [ 0.504, 0.11, 0.931, 0.71 ]
+					},
+					{ "time": 0.8, "angle": 120 },
+					{ "time": 1.2333, "angle": 240 },
+					{ "time": 1.6, "angle": 0 },
+					{ "time": 1.9, "angle": 120 },
+					{ "time": 2.1666, "angle": 240 },
+					{ "time": 2.4, "angle": 0 },
+					{ "time": 2.5666, "angle": 120 },
+					{ "time": 2.7333, "angle": 240 },
+					{ "time": 2.9333, "angle": 0 },
+					{ "time": 3.1, "angle": 120 },
+					{ "time": 3.2666, "angle": 240 },
+					{ "time": 3.4333, "angle": 0 },
+					{ "time": 3.6333, "angle": 120 },
+					{ "time": 3.8, "angle": 240 },
+					{ "time": 3.9666, "angle": 0 },
+					{ "time": 4.1666, "angle": 120 },
+					{ "time": 4.3333, "angle": 240 },
+					{ "time": 4.5, "angle": 0 },
+					{ "time": 4.7, "angle": 120 },
+					{ "time": 4.8666, "angle": 240 },
+					{ "time": 5.2666, "angle": -67.99 }
+				]
+			},
+			"tankTreads": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0,
+						"curve": [ 0.145, 0.34, 0.75, 1 ]
+					},
+					{ "time": 1.1, "angle": -3.9 },
+					{ "time": 1.3333, "angle": -2.37 },
+					{ "time": 1.6333, "angle": -3.54 },
+					{ "time": 2.1666, "angle": 0.27 },
+					{
+						"time": 2.4666,
+						"angle": 2.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.7,
+						"angle": 3.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 3, "angle": -3.62 },
+					{ "time": 3.2333, "angle": -1.23, "curve": "stepped" },
+					{
+						"time": 4.8666,
+						"angle": -1.23,
+						"curve": [ 0.188, 0.16, 0.75, 1 ]
+					},
+					{
+						"time": 5.2,
+						"angle": 4.47,
+						"curve": [ 0.416, 0.01, 0.75, 1 ]
+					},
+					{
+						"time": 5.5666,
+						"angle": -3.08,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 5.8333, "angle": -1.23 }
+				]
+			},
+			"wheel-big1": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0,
+						"curve": [ 0.504, 0.11, 0.931, 0.71 ]
+					},
+					{ "time": 1.1, "angle": 120 },
+					{ "time": 1.5333, "angle": 240 },
+					{ "time": 1.8, "angle": 360 },
+					{ "time": 2.0333, "angle": 120 },
+					{ "time": 2.2666, "angle": 240 },
+					{ "time": 2.4666, "angle": 360 },
+					{ "time": 2.7, "angle": 120 },
+					{ "time": 2.9333, "angle": 240 },
+					{ "time": 3.1333, "angle": 360 },
+					{ "time": 3.3666, "angle": 120 },
+					{ "time": 3.5666, "angle": 240 },
+					{ "time": 3.8, "angle": -24 },
+					{ "time": 4.0333, "angle": 120 },
+					{ "time": 4.2333, "angle": 240 },
+					{ "time": 4.4666, "angle": -24 },
+					{ "time": 4.7, "angle": 120 },
+					{ "time": 4.8666, "angle": -143.99 },
+					{
+						"time": 5.0666,
+						"angle": -131.4,
+						"curve": [ 0.14, 0.25, 0.75, 1 ]
+					},
+					{ "time": 5.6666, "angle": -76.85 },
+					{ "time": 5.8333, "angle": -72.3 }
+				]
+			},
+			"treadGravity1": {
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 1.4666, "x": 0, "y": 0 },
+					{ "time": 1.8, "x": 0, "y": 29.44 },
+					{ "time": 2.3333, "x": 0, "y": -0.52 },
+					{ "time": 2.5666, "x": 0, "y": 5.2 },
+					{ "time": 2.6666, "x": 0, "y": -11.05, "curve": "stepped" },
+					{ "time": 4.8666, "x": 0, "y": -11.05 },
+					{ "time": 5.0666, "x": 0, "y": -1.91 },
+					{ "time": 5.5333, "x": 0, "y": -6.9 },
+					{ "time": 5.7333, "x": 0, "y": -11.05 }
+				]
+			},
+			"treadGravity2": {
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 1.4666, "x": 0, "y": 0 },
+					{ "time": 1.8, "x": 0, "y": 8.5 },
+					{ "time": 2.3333, "x": 0, "y": 34.74 },
+					{ "time": 2.5666, "x": 0, "y": 5.2 },
+					{ "time": 2.6666, "x": 0, "y": -11.05, "curve": "stepped" },
+					{ "time": 4.8666, "x": 0, "y": -11.05 },
+					{ "time": 5.0666, "x": 0, "y": 3.9 },
+					{ "time": 5.5333, "x": 0, "y": -6.9 },
+					{ "time": 5.7333, "x": 0, "y": -11.05 }
+				]
+			},
+			"wheel-small1": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0,
+						"curve": [ 0.504, 0.11, 0.931, 0.71 ]
+					},
+					{ "time": 0.7, "angle": 120 },
+					{ "time": 1.1, "angle": 240 },
+					{ "time": 1.4666, "angle": 360 },
+					{ "time": 1.7666, "angle": 120 },
+					{ "time": 2.0333, "angle": 240 },
+					{ "time": 2.2666, "angle": 360 },
+					{ "time": 2.4333, "angle": 120 },
+					{ "time": 2.5666, "angle": 240 },
+					{ "time": 2.7, "angle": 360 },
+					{ "time": 2.8333, "angle": 120 },
+					{ "time": 2.9666, "angle": 240 },
+					{ "time": 3.1, "angle": 360 },
+					{ "time": 3.2333, "angle": 120 },
+					{ "time": 3.3666, "angle": 240 },
+					{ "time": 3.5, "angle": 360 },
+					{ "time": 3.6333, "angle": 120 },
+					{ "time": 3.7666, "angle": 240 },
+					{ "time": 3.9, "angle": 360 },
+					{ "time": 4.0333, "angle": 120 },
+					{ "time": 4.1666, "angle": 240 },
+					{ "time": 4.3, "angle": 360 },
+					{ "time": 4.4333, "angle": 120 },
+					{ "time": 4.5666, "angle": 240 },
+					{ "time": 4.7, "angle": 360 },
+					{ "time": 4.8333, "angle": 120 },
+					{ "time": 5, "angle": 240 },
+					{
+						"time": 5.2,
+						"angle": -25.64,
+						"curve": [ 0.181, 0.26, 0.75, 1 ]
+					},
+					{ "time": 5.5666, "angle": 90 }
+				]
+			},
+			"tankBody": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.1666,
+						"angle": -1.41,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.9333,
+						"angle": -0.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3,
+						"angle": 0.84,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -2.33,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.4666,
+						"angle": -0.45,
+						"curve": [ 0.329, 0.32, 0.757, 1 ]
+					},
+					{
+						"time": 4.8666,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3333,
+						"angle": 1.82,
+						"curve": [ 0.324, 0.01, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -1.15,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.0333, "angle": 0 }
+				]
+			},
+			"antenna1": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 0.4333,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -1.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.0666,
+						"angle": -0.68,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.4,
+						"angle": 0.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -0.67, "curve": "stepped" },
+					{
+						"time": 2.1333,
+						"angle": -0.67,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3666,
+						"angle": 0.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.5666,
+						"angle": -1.69,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.8666,
+						"angle": 1.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -1.09,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.2333,
+						"angle": 1.03,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.5,
+						"angle": -0.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 4.6666, "angle": -0.18 },
+					{
+						"time": 5.0333,
+						"angle": -1.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3666,
+						"angle": 9.17,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -3.14,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.9,
+						"angle": 2.96,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 6.1,
+						"angle": -0.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.2666, "angle": 0.96 },
+					{ "time": 6.4, "angle": 0 }
+				]
+			},
+			"antenna2": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 0.4333,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -1.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.0666,
+						"angle": -0.68,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.4,
+						"angle": 0.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -0.67, "curve": "stepped" },
+					{
+						"time": 2.1333,
+						"angle": -0.67,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3666,
+						"angle": 0.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.5666,
+						"angle": -1.69,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.8666,
+						"angle": 1.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -1.09,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.2333,
+						"angle": 1.03,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.5,
+						"angle": -0.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 4.6666, "angle": -0.18 },
+					{
+						"time": 5.0333,
+						"angle": -1.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3666,
+						"angle": 9.17,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -3.14,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.9,
+						"angle": 2.96,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 6.1,
+						"angle": -0.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.2666, "angle": 0.96 },
+					{ "time": 6.4, "angle": 0 }
+				]
+			},
+			"antenna3": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 0.4333,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -1.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.0666,
+						"angle": -0.68,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.4,
+						"angle": 0.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -0.67, "curve": "stepped" },
+					{
+						"time": 2.1333,
+						"angle": -0.67,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3666,
+						"angle": 0.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.5666,
+						"angle": -1.69,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.8666,
+						"angle": 1.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -1.09,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.2333,
+						"angle": 1.03,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.5,
+						"angle": -0.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 4.6666, "angle": -0.18 },
+					{
+						"time": 5.0333,
+						"angle": -1.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3666,
+						"angle": 9.17,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -3.14,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.9,
+						"angle": 2.96,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 6.1,
+						"angle": -0.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.2666, "angle": 0.96 },
+					{ "time": 6.4, "angle": 0 }
+				]
+			},
+			"antenna4": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 0.4333,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -1.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.0666,
+						"angle": -0.68,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.4,
+						"angle": 0.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -0.67, "curve": "stepped" },
+					{
+						"time": 2.1333,
+						"angle": -0.67,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3666,
+						"angle": 0.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.5666,
+						"angle": -1.69,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.8666,
+						"angle": 1.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -1.09,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.2333,
+						"angle": 1.03,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.5,
+						"angle": -0.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 4.6666, "angle": -0.18 },
+					{
+						"time": 5.0333,
+						"angle": -1.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3666,
+						"angle": 9.17,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -3.14,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.9,
+						"angle": 2.96,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 6.1,
+						"angle": -0.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.2666, "angle": 0.96 },
+					{ "time": 6.4, "angle": 0 }
+				]
+			},
+			"antenna5": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 0.4333,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -1.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.0666,
+						"angle": -0.68,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.4,
+						"angle": 0.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -0.67, "curve": "stepped" },
+					{
+						"time": 2.1333,
+						"angle": -0.67,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3666,
+						"angle": 0.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.5666,
+						"angle": -1.69,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.8666,
+						"angle": 1.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -1.09,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.2333,
+						"angle": 1.03,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.5,
+						"angle": -0.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 4.6666, "angle": -0.18 },
+					{
+						"time": 5.0333,
+						"angle": -1.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3666,
+						"angle": 9.17,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -3.14,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.9,
+						"angle": 2.96,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 6.1,
+						"angle": -0.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.2666, "angle": 0.96 },
+					{ "time": 6.4, "angle": 0 }
+				]
+			},
+			"antenna6": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 0.4333,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -1.55,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.0666,
+						"angle": -0.68,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 1.4,
+						"angle": 0.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -0.67, "curve": "stepped" },
+					{
+						"time": 2.1333,
+						"angle": -0.67,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.3666,
+						"angle": 0.88,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.5666,
+						"angle": -1.69,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 2.8666,
+						"angle": 1.18,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.0333,
+						"angle": -1.09,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.2333,
+						"angle": 1.03,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 3.5,
+						"angle": -0.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 4.6666, "angle": -0.18 },
+					{
+						"time": 5.0333,
+						"angle": -1.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.3666,
+						"angle": 9.17,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.6666,
+						"angle": -3.14,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.9,
+						"angle": 2.96,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 6.1,
+						"angle": -0.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.2666, "angle": 0.96 },
+					{ "time": 6.4, "angle": 0 }
+				]
+			},
+			"machinegun": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{
+						"time": 2.8333,
+						"angle": 0,
+						"curve": [ 0.183, 0.17, 0.75, 1 ]
+					},
+					{
+						"time": 3,
+						"angle": -4.43,
+						"curve": [ 0.156, 0.16, 0.75, 1 ]
+					},
+					{
+						"time": 3.1666,
+						"angle": -2.93,
+						"curve": [ 0.156, 0.16, 0.75, 1 ]
+					},
+					{
+						"time": 4.8333,
+						"angle": 0,
+						"curve": [ 0.183, 0.17, 0.75, 1 ]
+					},
+					{
+						"time": 5.1666,
+						"angle": -6.05,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 5.4,
+						"angle": 6.15,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 5.6, "angle": -1.26 }
+				]
+			},
+			"cannon": {
+				"rotate": [
+					{ "time": 0, "angle": 0 }
+				]
+			},
+			"cannonTarget": {
+				"translate": [
+					{
+						"time": 5,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 6.3333, "x": -15.38, "y": 99.99 }
+				]
+			}
+		},
+		"ik": {
+			"cannonTarget": [
+				{ "time": 0, "mix": 0.809, "curve": "stepped" },
+				{ "time": 4.7333, "mix": 0.809 },
+				{ "time": 5.1666, "mix": 0.504 },
+				{ "time": 5.6666 }
+			]
+		},
+		"paths": {
+			"treads": {
+				"position": [
+					{
+						"time": 0,
+						"curve": [ 0.549, 0, 0.907, 0.84 ]
+					},
+					{ "time": 3.0333, "position": 0.51 },
+					{ "time": 4.8666, "position": 0.9794 },
+					{
+						"time": 5.2666,
+						"position": 1,
+						"curve": [ 0.226, 0.15, 0.765, 0.96 ]
+					},
+					{
+						"time": 5.5333,
+						"position": 1.02,
+						"curve": [ 0.279, 0.32, 0.694, 0.99 ]
+					},
+					{ "time": 5.8333, "position": 1.021 }
+				]
+			}
+		}
+	}
+}
+}

BIN
spine-ts/canvas/example/assets/tank.png


+ 13 - 0
spine-ts/canvas/example/assets/test.atlas

@@ -0,0 +1,13 @@
+
+test.png
+size: 512,512
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+badlogic
+  rotate: false
+  xy: 2, 2
+  size: 460, 460
+  orig: 460, 460
+  offset: 0, 0
+  index: -1

+ 19 - 0
spine-ts/canvas/example/assets/test.json

@@ -0,0 +1,19 @@
+{
+"skeleton": { "hash": "lDI/ipVg9yXAdln1ZwTDAuXPGng", "spine": "3.4.02", "width": 650.27, "height": 650.27, "images": "./images/" },
+"bones": [
+	{ "name": "root" }
+],
+"slots": [
+	{ "name": "badlogic", "bone": "root", "attachment": "badlogic" }
+],
+"skins": {
+	"default": {
+		"badlogic": {
+			"badlogic": { "rotation": 43.36, "width": 460, "height": 460 }
+		}
+	}
+},
+"animations": {
+	"animation": {}
+}
+}

BIN
spine-ts/canvas/example/assets/test.png


+ 13 - 0
spine-ts/canvas/example/assets/vine.atlas

@@ -0,0 +1,13 @@
+
+vine.png
+size: 128,1024
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+images/vine
+  rotate: false
+  xy: 2, 2
+  size: 68, 962
+  orig: 68, 962
+  offset: 0, 0
+  index: -1

Plik diff jest za duży
+ 41 - 0
spine-ts/canvas/example/assets/vine.json


BIN
spine-ts/canvas/example/assets/vine.png


+ 96 - 1
spine-ts/canvas/example/index.html

@@ -10,13 +10,108 @@
 
 var lastFrameTime = Date.now() / 1000;
 var canvas;
+var context;
 var assetManager;
+var skeleton;
+var state;
 var skeletonRenderer;
 
 function init () {
+	canvas = document.getElementById("canvas");
+	canvas.width = 640;
+	canvas.height = 480;
+	context = canvas.getContext("2d");
+
+	skeletonRenderer = new spine.canvas.SkeletonRenderer(context);
+
 	assetManager = new spine.AssetManager(function(image) {
-		return CanvasTexture(image);
+		return new spine.canvas.CanvasTexture(image);
+	});
+
+	assetManager.loadText("assets/spineboy.json");
+	assetManager.loadText("assets/spineboy.atlas");
+	assetManager.loadTexture("assets/spineboy.png");
+	assetManager.loadText("assets/test.json");
+	assetManager.loadText("assets/test.atlas");
+	assetManager.loadTexture("assets/test.png");
+	assetManager.loadText("assets/raptor.json");
+	assetManager.loadText("assets/raptor.atlas");
+	assetManager.loadTexture("assets/raptor.png");
+
+	requestAnimationFrame(load);
+}
+
+function load () {
+	if (assetManager.isLoadingComplete()) {
+		var data = loadSkeleton("raptor", 0.3, "walk", 320, 20, "default");
+		skeleton = data.skeleton;
+		state = data.state;		
+		requestAnimationFrame(render);
+	} else {
+		requestAnimationFrame(load);
+	}
+}
+
+function loadSkeleton (name, scale, initialAnimation, positionX, positionY, skin) {
+	if (skin === undefined) skin = "default";
+
+	// Load the texture atlas using name.atlas and name.png from the AssetManager.
+	// The function passed to TextureAtlas is used to resolve relative paths.
+	atlas = new spine.TextureAtlas(assetManager.get("assets/" + name + ".atlas"), function(path) {
+		return assetManager.get("assets/" + path);				
 	});
+
+	// Create a TextureAtlasAttachmentLoader, which is specific to the WebGL backend.
+	atlasLoader = new spine.TextureAtlasAttachmentLoader(atlas);
+
+	// Create a SkeletonJson instance for parsing the .json file.
+	var skeletonJson = new spine.SkeletonJson(atlasLoader);
+	
+	// Set the scale to apply during parsing, parse the file, and create a new skeleton.
+	skeletonJson.scale = scale;
+	var skeletonData = skeletonJson.readSkeletonData(assetManager.get("assets/" + name + ".json"));
+	var skeleton = new spine.Skeleton(skeletonData);
+	skeleton.x = positionX;
+	skeleton.y = positionY;
+	skeleton.setSkinByName(skin);
+
+	// Create an AnimationState, and set the initial animation in looping mode.
+	var animationState = new spine.AnimationState(new spine.AnimationStateData(skeleton.data));
+	animationState.setAnimation(0, initialAnimation, true);
+	animationState.addListener({
+		event: function(trackIndex, event) {
+			// console.log("Event on track " + trackIndex + ": " + JSON.stringify(event));
+		},
+		complete: function(trackIndex, loopCount) {
+			// console.log("Animation on track " + trackIndex + " completed, loop count: " + loopCount);
+		},
+		start: function(trackIndex) {
+			// console.log("Animation on track " + trackIndex + " started");
+		},
+		end: function(trackIndex) {
+			// console.log("Animation on track " + trackIndex + " ended");
+		}
+	})
+
+	// Pack everything up and return to caller.
+	return { skeleton: skeleton, state: animationState };
+}
+
+function render () {
+	var now = Date.now() / 1000;
+	var delta = now - lastFrameTime;
+	lastFrameTime = now;
+	
+	state.update(delta);
+	state.apply(skeleton);
+	skeleton.updateWorldTransform();
+
+	context.fillStyle = "#cccccc";
+	context.fillRect(0, 0, canvas.width, canvas.height);
+
+	skeletonRenderer.draw(skeleton);
+
+	requestAnimationFrame(render);
 }
 
 (function() {

+ 34 - 1
spine-ts/canvas/src/CanvasTexture.ts

@@ -1,4 +1,37 @@
-module spine.canvas {
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/// <reference path="../../core/src/Texture.ts"/>
+
+module spine.canvas {	
 	export class CanvasTexture extends Texture {
 		constructor (image: HTMLImageElement) {
 			super(image);

+ 138 - 0
spine-ts/canvas/src/SkeletonRenderer.ts

@@ -1,5 +1,143 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.5
+ * 
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
 module spine.canvas {
 	export class SkeletonRenderer {
+		static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
+
+		private _ctx: CanvasRenderingContext2D;
 		
+		constructor (context: CanvasRenderingContext2D) {
+			this._ctx = context;
+		}
+
+		draw (skeleton: Skeleton) {			
+			let blendMode: BlendMode = null;
+			let ctx = this._ctx;
+
+			let vertices: ArrayLike<number> = null;
+			let triangles: Array<number>  = null;
+			let drawOrder = skeleton.drawOrder;			
+
+			for (let i = 0, n = drawOrder.length; i < n; i++) {
+				let slot = drawOrder[i];
+				let attachment = slot.getAttachment();
+				let texture: HTMLImageElement = null;
+				let region: TextureAtlasRegion = null;
+				if (attachment instanceof RegionAttachment) {
+					let regionAttachment = <RegionAttachment>attachment;
+					vertices = regionAttachment.updateWorldVertices(slot, false);
+					triangles = SkeletonRenderer.QUAD_TRIANGLES;
+					region = <TextureAtlasRegion>regionAttachment.region;
+					texture = (<CanvasTexture>region.texture).getImage();
+
+				} else if (attachment instanceof MeshAttachment) {
+					let mesh = <MeshAttachment>attachment;
+					vertices = mesh.updateWorldVertices(slot, false);
+					triangles = mesh.triangles;
+					texture = (<TextureAtlasRegion>mesh.region.renderObject).texture.getImage();
+				} else continue;
+
+				if (texture != null) {
+					let slotBlendMode = slot.data.blendMode;
+					if (slotBlendMode != blendMode) {
+						blendMode = slotBlendMode;						
+					}
+
+					this.drawTriangles(texture, vertices, triangles);
+
+					// ctx.drawImage(texture, 0, 0);				
+				}
+			}			
+		}
+
+		drawTriangles(texture: HTMLImageElement, vertices: ArrayLike<number>, triangles: ArrayLike<number>) {
+			let ctx = this._ctx;
+
+			for (var i = 0; i < triangles.length; i+=3) {
+				let t1 = triangles[i] * 8, t2 = triangles[i+1] * 8, t3 = triangles[i+2] * 8;
+
+				let x0 = vertices[t1], y0 = vertices[t1 + 1], u0 = vertices[t1 + 6], v0 = vertices[t1 + 7];
+				let x1 = vertices[t2], y1 = vertices[t2 + 1], u1 = vertices[t2 + 6], v1 = vertices[t2 + 7];
+				let x2 = vertices[t3], y2 = vertices[t3 + 1], u2 = vertices[t3 + 6], v2 = vertices[t3 + 7];				
+
+				this.drawTriangle(texture, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);
+			}
+		}
+
+		drawTriangle(img: HTMLImageElement, x0: number, y0: number, u0: number, v0: number,
+						x1: number, y1: number, u1: number, v1: number,
+						x2: number, y2: number, u2: number, v2: number) {
+			let ctx = this._ctx;
+
+			u0 *= img.width;
+			v0 *= img.height;
+			u1 *= img.width;
+			v1 *= img.height;
+			u2 *= img.width;
+			v2 *= img.height;
+
+			ctx.beginPath();
+			ctx.moveTo(x0, y0);
+			ctx.lineTo(x1, y1);
+			ctx.lineTo(x2, y2);
+			ctx.closePath();
+
+			x1 -= x0;
+			y1 -= y0;
+			x2 -= x0;
+			y2 -= y0;
+
+			u1 -= u0;
+			v1 -= v0;
+			u2 -= u0;
+			v2 -= v0;
+
+			var det = 1 / (u1*v2 - u2*v1),
+
+			// linear transformation
+			a = (v2*x1 - v1*x2) * det,
+			b = (v2*y1 - v1*y2) * det,
+			c = (u1*x2 - u2*x1) * det,
+			d = (u1*y2 - u2*y1) * det,
+
+			// translation
+			e = x0 - a*u0 - c*v0,
+			f = y0 - b*u0 - d*v0;
+
+			ctx.save();
+			ctx.transform(a, b, c, d, e, f);
+			ctx.clip();
+			ctx.drawImage(img, 0, 0);
+			ctx.restore();
+		}
 	}
 }

+ 5 - 3
spine-ts/core/src/TextureAtlas.ts

@@ -34,11 +34,11 @@ module spine {
 		pages = new Array<TextureAtlasPage>();
 		regions = new Array<TextureAtlasRegion>();
 
-		constructor (atlasText: string, textureLoader: (path: string, minFilter: TextureFilter, magFilter: TextureFilter, uWrap: TextureWrap, vWrap: TextureWrap) => any) {
+		constructor (atlasText: string, textureLoader: (path: string) => any) {
 			this.load(atlasText, textureLoader);
 		}
 
-		private load (atlasText: string, textureLoader: (path: string, minFilter: TextureFilter, magFilter: TextureFilter, uWrap: TextureWrap, vWrap: TextureWrap) => any) {
+		private load (atlasText: string, textureLoader: (path: string) => any) {
 			if (textureLoader == null)
 				throw new Error("textureLoader cannot be null.");
 
@@ -77,7 +77,9 @@ module spine {
 					else if (direction == "xy")
 						page.uWrap = page.vWrap = TextureWrap.Repeat;
 
-					page.texture = textureLoader(line, page.minFilter, page.magFilter, page.uWrap, page.vWrap);					
+					page.texture = textureLoader(line);
+					page.texture.setFilters(page.minFilter, page.magFilter);
+					page.texture.setWraps(page.uWrap, page.vWrap);					
 					page.width = page.texture.getImage().width;
 					page.height = page.texture.getImage().height;
 					this.pages.push(page);

+ 1 - 1
spine-ts/webgl/src/TextureAtlasAttachmentLoader.ts → spine-ts/core/src/TextureAtlasAttachmentLoader.ts

@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-module spine.webgl {
+module spine {
 	export class TextureAtlasAttachmentLoader implements AttachmentLoader {
 		atlas: TextureAtlas;
 

+ 1 - 1
spine-ts/tsconfig.canvas.json

@@ -2,7 +2,7 @@
 	"compilerOptions": {
 		"module": "none",
 		"noImplicitAny": true,
-		"removeComments": false,
+		"removeComments": true,
 		"preserveConstEnums": true,
 		"outFile": "build/spine-canvas.js",
 		"sourceMap": true,

+ 1 - 1
spine-ts/tsconfig.core.json

@@ -2,7 +2,7 @@
 	"compilerOptions": {
 		"module": "none",
 		"noImplicitAny": true,
-		"removeComments": false,
+		"removeComments": true,
 		"preserveConstEnums": true,
 		"outFile": "build/spine-core.js",
 		"sourceMap": true,

+ 1 - 1
spine-ts/tsconfig.json

@@ -2,7 +2,7 @@
 	"compilerOptions": {
 		"module": "none",
 		"noImplicitAny": true,
-		"removeComments": false,
+		"removeComments": true,
 		"preserveConstEnums": true,
 		"outFile": "build/spine-all.js",
 		"sourceMap": true,

+ 1 - 1
spine-ts/tsconfig.webgl.json

@@ -2,7 +2,7 @@
 	"compilerOptions": {
 		"module": "none",
 		"noImplicitAny": true,
-		"removeComments": false,
+		"removeComments": true,
 		"preserveConstEnums": true,
 		"outFile": "build/spine-webgl.js",
 		"sourceMap": true,

+ 1 - 1
spine-ts/tsconfig.widget.json

@@ -2,7 +2,7 @@
 	"compilerOptions": {
 		"module": "none",
 		"noImplicitAny": true,
-		"removeComments": false,
+		"removeComments": true,
 		"preserveConstEnums": true,
 		"outFile": "build/spine-widget.js",
 		"sourceMap": true,

+ 4 - 7
spine-ts/webgl/example/index.html

@@ -80,15 +80,12 @@ function loadSkeleton (name, scale, initialAnimation, positionX, positionY, prem
 
 	// Load the texture atlas using name.atlas and name.png from the AssetManager.
 	// The function passed to TextureAtlas is used to resolve relative paths.
-	atlas = new spine.TextureAtlas(assetManager.get("assets/" + name + ".atlas"), function(path, minFilter, magFilter, uWrap, vWrap) {
-		var texture = assetManager.get("assets/" + path);
-		texture.setFilters(minFilter, magFilter);
-		texture.setWraps(uWrap, vWrap);
-		return texture;
+	atlas = new spine.TextureAtlas(assetManager.get("assets/" + name + ".atlas"), function(path) {
+		return assetManager.get("assets/" + path);		
 	});
 
-	// Create a TextureAtlasAttachmentLoader, which is specific to the WebGL backend.
-	atlasLoader = new spine.webgl.TextureAtlasAttachmentLoader(atlas);
+	// Create a TextureAtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
+	atlasLoader = new spine.TextureAtlasAttachmentLoader(atlas);
 
 	// Create a SkeletonJson instance for parsing the .json file.
 	var skeletonJson = new spine.SkeletonJson(atlasLoader);

+ 1 - 1
spine-ts/webgl/src/SkeletonRenderer.ts

@@ -62,7 +62,7 @@ module spine.webgl {
 					vertices = mesh.updateWorldVertices(slot, premultipliedAlpha);
 					triangles = mesh.triangles;
 					texture = <GLTexture>(<TextureAtlasRegion>mesh.region.renderObject).texture;
-				}
+				} else continue;
 
 				if (texture != null) {
 					let slotBlendMode = slot.data.blendMode;

+ 9 - 4
spine-ts/widget/src/Widget.ts

@@ -37,7 +37,7 @@ module spine {
 		canvas: HTMLCanvasElement;		
 
 		private _config: SpineWidgetConfig;
-		private _assetManager: spine.webgl.AssetManager;
+		private _assetManager: spine.AssetManager;
 		private _shader: spine.webgl.Shader;
 		private _batcher: spine.webgl.PolygonBatcher;
 		private _mvp = new spine.webgl.Matrix4();
@@ -69,7 +69,9 @@ module spine {
 			this._mvp.ortho2d(0, 0, 639, 479);
 			this._skeletonRenderer = new spine.webgl.SkeletonRenderer(gl);
 
-			let assets = this._assetManager = new spine.webgl.AssetManager(gl);
+			let assets = this._assetManager = new spine.AssetManager((image: HTMLImageElement) => { 
+				return new spine.webgl.GLTexture(gl, image);
+			});
 			assets.loadText(config.atlas);
 			assets.loadText(config.json);
 			assets.loadTexture(config.atlas.replace(".atlas", ".png"));
@@ -112,8 +114,11 @@ module spine {
 					else throw new Error("Failed to load assets: " + JSON.stringify(assetManager.errors));
 				}
 
-				let atlas = new spine.webgl.TextureAtlas(this._assetManager.get(this._config.atlas) as string, (path) => {
-					return assetManager.get(imagesPath + path) as spine.webgl.Texture;
+				let atlas = new spine.TextureAtlas(this._assetManager.get(this._config.atlas) as string, (path: string, minFilter: TextureFilter, magFilter: TextureFilter, uWrap: TextureWrap, vWrap: TextureWrap) => {
+					let texture = assetManager.get(imagesPath + path) as spine.webgl.GLTexture;
+					texture.setFilters(minFilter, magFilter);
+					texture.setWraps(uWrap, vWrap);
+					return texture;
 				});
 				
 				let atlasLoader = new spine.webgl.TextureAtlasAttachmentLoader(atlas);				

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików