diff --git a/codes/games/client/Edit/Settings.ini b/codes/games/client/Edit/Settings.ini index 078f3de..bc93c87 100644 --- a/codes/games/client/Edit/Settings.ini +++ b/codes/games/client/Edit/Settings.ini @@ -123,16 +123,16 @@ DocumentTypeKeyWordsFile1= DocumentTypeFunctionRegExp1= [MRUFiles] -MRUItem1=G:\Works\YouleGames\games\games\Projects\clinet\gamehall\js\gamemain.js -MRUItem2=G:\Works\YouleGames\games\games\Projects\clinet\zpy\js\gamemain.js -MRUItem3=G:\Works\YouleGames\games\games\Projects\Project1\js\gamemain.js -MRUItem4=G:\Works\YouleGames\games\games\Projects\clinet\sangelaok\js\gamemain.js -MRUItem5=G:\Works\YouleGames\games\games\Projects\clinet\niuniu\js\gamemain.js -MRUItem6=G:\Works\YouleGames\games\games\Projects\clinet\guanpai-jx\js\gamemain.js -MRUItem7=G:\Works\YouleGames\games\games\Projects\clinet\doudizhu\js\gamemain.js -MRUItem8=G:\Works\JinXianProjects\JinXianMahjong\Projects\client\js\gamemain.js -MRUItem9=G:\Works\JinXianProjects\JinXianMahjong\Projects\Project1\js\gamemain.js -MRUItem10=G:\Works\JinXianProjects\JinXianMahjong\Projects\client\js\client_Event.js +MRUItem1=G:\Works\YouleGames\codes\games\client\Projects\Project1\js\gamemain.js +MRUItem2=G:\Works\YouleGames\codes\games\client\Projects\Spine\js\gamemain.js +MRUItem3=G:\Works\YouleGames\codes\games\client\Projects\Spine\index.html +MRUItem4=G:\Works\YouleGames\games\games\Projects\clinet\gamehall\js\gamemain.js +MRUItem5=G:\Works\YouleGames\games\games\Projects\clinet\zpy\js\gamemain.js +MRUItem6=G:\Works\YouleGames\games\games\Projects\Project1\js\gamemain.js +MRUItem7=G:\Works\YouleGames\games\games\Projects\clinet\sangelaok\js\gamemain.js +MRUItem8=G:\Works\YouleGames\games\games\Projects\clinet\niuniu\js\gamemain.js +MRUItem9=G:\Works\YouleGames\games\games\Projects\clinet\guanpai-jx\js\gamemain.js +MRUItem10=G:\Works\YouleGames\games\games\Projects\clinet\doudizhu\js\gamemain.js [MRUFindText] MRUItem1=ÅäÖà diff --git a/codes/games/client/History.txt b/codes/games/client/History.txt index 7a17c9a..af6822f 100644 --- a/codes/games/client/History.txt +++ b/codes/games/client/History.txt @@ -1,3 +1,5 @@ +G:\Works\YouleGames\codes\games\client\Projects\Spine\ +G:\Works\YouleGames\codes\games\client\Projects\Project1\ G:\Works\YouleGames\games\games\Projects\clinet\gamehall\ G:\Works\YouleGames\games\games\Projects\clinet\zpy\ G:\Works\YouleGames\games\games\Projects\clinet\sangelaok\ diff --git a/codes/games/client/Projects/Game_Surface_3/docs/SpineåŠ¨ç”»é›†æˆæ‰‹å†Œ.md b/codes/games/client/Projects/Game_Surface_3/docs/SpineåŠ¨ç”»é›†æˆæ‰‹å†Œ.md new file mode 100644 index 0000000..e7398eb --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/docs/SpineåŠ¨ç”»é›†æˆæ‰‹å†Œ.md @@ -0,0 +1,806 @@ +# Spine åŠ¨ç”»é›†æˆæ‰‹å†Œ + +> 本手册针对 **gameabc 引擎** çš„ Spine 项目,说明如何在 Canvas 2D 游æˆä¸­åŠ è½½ã€ +> æŽ§åˆ¶å’Œç®¡ç† Spine 骨骼动画。 +> è¿è¡Œæ—¶ç‰ˆæœ¬ï¼š**spine-canvas 4.2** | 引擎:**gameabc** + +--- + +## 目录 + +1. [项目结构总览](#1-项目结构总览) +2. [快速开始:5 分钟跑通](#2-快速开始5-分钟跑通) +3. [从 Spine 编辑器导出资æº](#3-从-spine-编辑器导出资æº) +4. [SpineMgr 完整 API å‚考](#4-spinemgr-完整-api-å‚考) +5. [事件系统](#5-事件系统) +6. [常è§ç”¨æ³•示例](#6-常è§ç”¨æ³•示例) +7. [与 gameabc ç²¾çµç³»ç»Ÿé…åˆ](#7-与-gameabc-ç²¾çµç³»ç»Ÿé…åˆ) +8. [性能优化建议](#8-性能优化建议) +9. [常è§é—®é¢˜æŽ’查](#9-常è§é—®é¢˜æŽ’查) +10. [附录:文件加载顺åº](#10-附录文件加载顺åº) + +--- + +## 1. 项目结构总览 + +``` +Projects/Spine/ +├── index.html â† å…¥å£ HTML +├── js/ +│ ├── spine-canvas.js ↠Spine Canvas 2D è¿è¡Œæ—¶ (第三方库) +│ ├── gameabc.min.js ↠gameabc 游æˆå¼•擎 +│ ├── SpineMgr.js ↠★ Spine 动画管ç†å™¨ï¼ˆç‹¬ç«‹æ–‡ä»¶ï¼Œè‡ªåŠ¨æŒ‚é’©æ¸²æŸ“ï¼‰ +│ ├── gamemain.js ↠游æˆä¸»é€»è¾‘(无需修改) +│ ├── Spine_Event.js ↠Spine 事件回调 (complete / event) +│ └── Project1_Event.js ↠精çµäº‹ä»¶å•å…ƒ +├── assets/ +│ ├── bmp/ ↠gameabc å›¾ç‰‡èµ„æº +│ └── spine/ ↠★ Spine 资æºç›®å½• +│ ├── xxx.json â† éª¨éª¼æ•°æ® (Spine 编辑器导出) +│ ├── xxx.atlas ↠图集æè¿°æ–‡ä»¶ +│ └── xxx.png ↠图集纹ç†å›¾ç‰‡ +├── output/ ↠gameabc 编译输出的é…ç½®æ•°æ® +├── save/ ↠gameabc 编辑器ä¿å­˜çš„ XML +└── docs/ ↠本文档所在目录 +``` + +### 关键文件说明 + +| 文件 | 作用 | 需è¦ä¿®æ”¹ | +|------|------|----------| +| `js/spine-canvas.js` | Spine 4.2 Canvas 渲染è¿è¡Œæ—¶ | ✗ ä¸è¦ä¿®æ”¹ | +| `js/SpineMgr.js` | Spine 动画管ç†å™¨ï¼Œè‡ªåЍåˆå§‹åŒ–+自动渲染 | ✗ ä¸éœ€è¦ä¿®æ”¹ | +| `js/gamemain.js` | 游æˆä¸»é€»è¾‘ï¼ˆä¿æŒåŽŸæ ·ï¼‰ | ✗ ä¸éœ€è¦ä¿®æ”¹ | +| `js/Spine_Event.js` | Spine 动画完æˆ/自定义事件回调 | ✓ 处ç†åŠ¨ç”»äº‹ä»¶ | +| `assets/spine/*` | Spine å¯¼å‡ºçš„èµ„æºæ–‡ä»¶ | ✓ æ”¾å…¥ä½ çš„èµ„æº | + +--- + +## 2. 快速开始:5 分钟跑通 + +### 第一步:准备 Spine èµ„æº + +å°† Spine 编辑器导出的 3 个文件å¤åˆ¶åˆ° `assets/spine/` 目录: + +``` +assets/spine/ +├── hero.json ↠骨骼 JSON +├── hero.atlas ↠图集æè¿° +└── hero.png â† å›¾é›†çº¹ç† +``` + +### 第二步:在任æ„ä½ç½®è°ƒç”¨ API 播放动画 + +**无需手动 `load`**,直接调用 `setAnimation` å³å¯ã€‚如果该 Spine å®žä¾‹å°šæœªåŠ è½½ï¼Œä¼šè‡ªåŠ¨æ ¹æ® id 查找资æºï¼ˆçº¦å®šæ–‡ä»¶å id.json / id.atlas)并创建实例。 +渲染也已自动挂钩到 `gameenddraw`,开å‘者无需编写任何渲染代ç ã€‚ + +在任何 gameabc 事件回调中直接调用å³å¯ï¼š + +```javascript +// 设置ä½ç½® + 播放动画,无需先 load +gameabc_face.spineMgr.setPosition("hero", 640, 500); +gameabc_face.spineMgr.setAnimation("hero", "idle", true); + +// 之åŽåˆ‡æ¢åŠ¨ç”» +gameabc_face.spineMgr.setAnimation("hero", "attack", false); +``` + +> **约定**:id å¿…é¡»ä¸Žèµ„æºæ–‡ä»¶å一致(ä¸å«æ‰©å±•å)。例如 id 为 `"hero"`, +> åˆ™éœ€è¦ `assets/spine/hero.json`ã€`hero.atlas`ã€`hero.png`。 +> +> **å¯é€‰**:如果资æºä¸åœ¨é»˜è®¤è·¯å¾„ `assets/spine/`ï¼Œå¯æ‰‹åŠ¨è°ƒç”¨ä¸€æ¬¡ `init()`: +> ```javascript +> gameabc_face.spineMgr.init("other/path/"); +> ``` + +### 第三步:打开 index.html å³å¯è¿è¡Œ + +用æµè§ˆå™¨æ‰“å¼€ `index.html`ï¼ˆéœ€è¦ HTTP æœåŠ¡å™¨çŽ¯å¢ƒï¼Œä¸èƒ½ç›´æŽ¥ `file://`): + +```bash +# 简易方法:在项目目录下å¯åЍ HTTP æœåŠ¡ +cd codes/games/client/Projects/Spine +npx http-server -p 8080 +# æµè§ˆå™¨è®¿é—® http://localhost:8080 +``` + +或者使用 gameabc 自带的预览环境。 + +--- + +## 3. 从 Spine ç¼–è¾‘å™¨å¯¼å‡ºèµ„æº + +### 导出设置(Spine 编辑器 → Export) + +1. 打开 Spine 编辑器,加载你的 `.spine` 项目 +2. 点击èœå• **Spine → Export...** +3. 左侧选择 **JSON** æ ¼å¼ +4. é…置项: + +| 设置项 | 推è值 | 说明 | +|--------|--------|------| +| Output folder | `assets/spine/` | 直接导出到项目目录 | +| Extension | `.json` | éª¨éª¼æ•°æ®æ ¼å¼ | +| Create atlas | ✓ 勾选 | åŒæ—¶ç”Ÿæˆå›¾é›† | +| Atlas extension | `.atlas` | 图集æè¿°æ ¼å¼ | +| Images folder | (默认) | çº¹ç†æ¥æº | +| Max width/height | 2048 / 2048 | å›¾é›†çº¹ç†æœ€å¤§å°ºå¯¸ | +| Pack settings → Power of two | ✓ 勾选 | 纹ç†å°ºå¯¸ä¸º 2 的幂 | +| Pack settings → Premultiply alpha | ✗ ä¸å‹¾é€‰ | Canvas 2D ä¸éœ€è¦é¢„乘 | + +5. 点击 **Export** 按钮 + +### 导出åŽå¾—到的文件 + +``` +hero.json ↠骨骼数æ®ï¼ŒåŒ…å«éª¨éª¼ã€æ’æ§½ã€åŠ¨ç”»ç­‰ +hero.atlas ↠图集æè¿°ï¼Œè®°å½•æ¯ä¸ªåŒºåŸŸåœ¨çº¹ç†ä¸­çš„ä½ç½® +hero.png ↠图集纹ç†å›¾ç‰‡ +``` + +> **注æ„**:如果图集很大被拆分æˆå¤šå¼ ï¼ˆ`hero.png`ã€`hero2.png`),所有 `.png` +> éƒ½éœ€è¦æ”¾åˆ° `assets/spine/` 目录中。`.atlas` 文件会自动引用它们。 + +--- + +## 4. SpineMgr 完整 API å‚考 + +`SpineMgr` 挂载在 `gameabc_face.spineMgr` 上,所有调用形如: + +```javascript +gameabc_face.spineMgr.方法å(傿•°); +``` + +--- + +### 4.1 init(basePath) *(å¯é€‰)* + +**æ‰‹åŠ¨è®¾ç½®èµ„æºæ ¹è·¯å¾„。通常无需调用——`load()` 会自动以默认路径 `"assets/spine/"` åˆå§‹åŒ–。** +ä»…åœ¨èµ„æºæ”¾åœ¨å…¶ä»–目录时æ‰éœ€è¦è°ƒç”¨ï¼š + +```javascript +gameabc_face.spineMgr.init("other/spine/path/"); +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `basePath` | string | Spine èµ„æºæ–‡ä»¶çš„æ ¹ç›®å½•路径,需è¦ä»¥ `/` 结尾。çœç•¥åˆ™ä½¿ç”¨é»˜è®¤å€¼ `"assets/spine/"` | + +--- + +### 4.2 load(id, jsonFile, atlasFile, option) *(å¯é€‰)* + +**手动加载一组 Spine 资æºå¹¶æ³¨å†Œä¸ºä¸€ä¸ªå®žä¾‹ã€‚通常无需调用——所有 API 在实例ä¸å­˜åœ¨æ—¶ä¼šè‡ªåŠ¨åŠ è½½ã€‚** + +ä»…åœ¨ä»¥ä¸‹æƒ…å†µéœ€è¦æ‰‹åŠ¨è°ƒç”¨ `load()`: +- id 与文件åä¸ä¸€è‡´ï¼ˆå¦‚ id 为 `"mj"` 但文件为 `mj_gangshangkaihua.json`) +- 需è¦åœ¨åŠ è½½æ—¶æŒ‡å®š skinã€scale ç­‰åˆå§‹å‚æ•° + +```javascript +gameabc_face.spineMgr.load("hero", "hero.json", "hero.atlas", { + x: 640, + y: 500, + scale: 0.5, + skin: "default", + animation: "idle", + loop: true, + mixDuration: 0.2 +}); +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `id` | string | 唯一标识,åŽç»­æ‰€æœ‰æ“作通过此 id 引用 | +| `jsonFile` | string | 骨骼 JSON 文件å(相对于 basePath) | +| `atlasFile` | string | 图集 atlas 文件å(相对于 basePath) | +| `option` | object | å¯é€‰é…置对象 | + +**option 字段:** + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `x` | number | 0 | Canvas X åæ ‡ | +| `y` | number | 0 | Canvas Y åæ ‡ | +| `scale` | number | 1 | åˆå§‹ç¼©æ”¾æ¯”例 | +| `skin` | string | `"default"` | åˆå§‹çš®è‚¤åç§° | +| `animation` | string | null | 加载完æˆåŽè‡ªåŠ¨æ’­æ”¾çš„åŠ¨ç”»å | +| `loop` | boolean | true | 默认动画是å¦å¾ªçޝ | +| `mixDuration` | number | 0.2 | åŠ¨ç”»åˆ‡æ¢æ—¶çš„è¿‡æ¸¡æ··åˆæ—¶é•¿ï¼ˆç§’) | + +--- + +### 4.3 setAnimation(id, animName, loop, track) + +**切æ¢åŠ¨ç”»ã€‚ç«‹å³æ›¿æ¢æŒ‡å®šè½¨é“上的当å‰åŠ¨ç”»ã€‚å¦‚æžœå®žä¾‹å°šæœªåŠ è½½ï¼Œä¼šè‡ªåŠ¨æ ¹æ® id 加载资æºå¹¶åœ¨å°±ç»ªåŽæ’­æ”¾ã€‚** + +```javascript +// 无需先 load,直接调用å³å¯ +gameabc_face.spineMgr.setAnimation("hero", "attack", false); +gameabc_face.spineMgr.setAnimation("hero", "run", true, 0); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animName` | string | - | 动画å称(必须在 Spine 中存在) | +| `loop` | boolean | true | 是å¦å¾ªçŽ¯æ’­æ”¾ | +| `track` | number | 0 | 轨é“å·ï¼ˆå¤šè½¨é“å¯å åŠ åŠ¨ç”»ï¼‰ | + +**返回值:** `TrackEntry` 对象,å¯ç”¨äºŽè¿›ä¸€æ­¥æŽ§åˆ¶ï¼›åŠ è½½æœªå®Œæˆæ—¶è¿”回 `null`。 + +--- + +### 4.4 addAnimation(id, animName, loop, delay, track) + +**将动画添加到播放队列,在当å‰åŠ¨ç”»ç»“æŸåŽè‡ªåŠ¨æ’­æ”¾ã€‚** + +```javascript +// 先播放 attack,attack 完æˆåŽè‡ªåŠ¨åˆ‡æ¢åˆ° idle +gameabc_face.spineMgr.setAnimation("hero", "attack", false); +gameabc_face.spineMgr.addAnimation("hero", "idle", true, 0); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animName` | string | - | 队列中的下一个动画 | +| `loop` | boolean | true | 是å¦å¾ªçޝ | +| `delay` | number | 0 | 延迟秒数(0 = ä¸Šä¸€åŠ¨ç”»ç»“æŸæ—¶ç«‹å³å¼€å§‹ï¼‰ | +| `track` | number | 0 | 轨é“å· | + +--- + +### 4.5 setPosition(id, x, y) + +**设置 Spine 实例在 Canvas 上的ä½ç½®ã€‚** + +```javascript +gameabc_face.spineMgr.setPosition("hero", 640, 500); +``` + +> Spine çš„åæ ‡åŽŸç‚¹åœ¨éª¨éª¼çš„æ ¹éª¨éª¼å¤„ã€‚Y è½´å‘上为正(与 Canvas çš„ Y è½´æ–¹å‘相å), +> spine-canvas è¿è¡Œæ—¶å·²åšäº†å†…部转æ¢ã€‚ + +--- + +### 4.6 setScale(id, sx, sy) + +**设置缩放。** + +```javascript +gameabc_face.spineMgr.setScale("hero", 0.5); // 等比缩放 +gameabc_face.spineMgr.setScale("hero", 0.5, 0.8); // 分别设置 X/Y +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `sx` | number | X æ–¹å‘缩放 | +| `sy` | number | Y æ–¹å‘缩放(çœç•¥åˆ™ç­‰äºŽ sx) | + +--- + +### 4.7 setFlip(id, flipX, flipY) + +**æ°´å¹³/垂直翻转。** + +```javascript +gameabc_face.spineMgr.setFlip("hero", true, false); // 水平翻转 +``` + +--- + +### 4.8 setVisible(id, visible) + +**显示或éšè— Spine 实例。** + +```javascript +gameabc_face.spineMgr.setVisible("hero", false); // éšè— +gameabc_face.spineMgr.setVisible("hero", true); // 显示 +``` + +--- + +### 4.9 setSkin(id, skinName) + +**切æ¢çš®è‚¤ã€‚** + +```javascript +gameabc_face.spineMgr.setSkin("hero", "warrior"); +``` + +> 切æ¢çš®è‚¤åŽä¼šè‡ªåЍé‡ç½®æ’槽到 Setup Pose。皮肤å必须在 Spine 编辑器中预定义。 + +--- + +### 4.10 getAnimations(id) + +**获å–该实例所有å¯ç”¨åŠ¨ç”»å称列表。** + +```javascript +var anims = gameabc_face.spineMgr.getAnimations("hero"); +// 返回: ["idle", "walk", "run", "attack", "die"] +logmessage("动画列表: " + anims.join(", ")); +``` + +--- + +### 4.11 getSkins(id) + +**获å–该实例所有å¯ç”¨çš®è‚¤å称列表。** + +```javascript +var skins = gameabc_face.spineMgr.getSkins("hero"); +// 返回: ["default", "warrior", "mage"] +``` + +--- + +### 4.12 playOnce(id, animName, track) + +**播放一次动画åŽè‡ªåЍéšè—。** è‡ªåŠ¨æ˜¾ç¤ºå®žä¾‹ã€æ’­æ”¾æŒ‡å®šåŠ¨ç”»ï¼ˆä¸å¾ªçŽ¯ï¼‰ï¼ŒåŠ¨ç”»å®ŒæˆåŽè‡ªåŠ¨è®¾ç½® `visible = false`。 + +```javascript +// 播放一次攻击动画,播完自动éšè— +gameabc_face.spineMgr.playOnce("hero", "attack"); + +// æŒ‡å®šè½¨é“ +gameabc_face.spineMgr.playOnce("hero", "attack", 0); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animName` | string | - | 动画åç§° | +| `track` | number | 0 | 轨é“å· | + +--- + +### 4.13 playQueue(id, animList, hideOnComplete) + +**æŒ‰é¡ºåºæ’­æ”¾ä¸€ç»„动画(队列),全部播完åŽå¯é€‰æ‹©éšè—æˆ–ä¿æŒæ˜¾ç¤ºã€‚** 自动显示实例,队列中æ¯ä¸ªåŠ¨ç”»å‡æ’­æ”¾ä¸€æ¬¡ï¼ˆä¸å¾ªçŽ¯ï¼‰ï¼Œä¾æ¬¡æ’­æ”¾ã€‚ + +```javascript +// 播放 attack → die,全部播完åŽè‡ªåЍéšè—(默认) +gameabc_face.spineMgr.playQueue("hero", ["attack", "die"]); + +// 播放 intro → idle,全部播完åŽä¿æŒæ˜¾ç¤º +gameabc_face.spineMgr.playQueue("hero", ["intro", "idle"], false); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animList` | string[] | - | 动画å称数组,按顺åºä¾æ¬¡æ’­æ”¾ | +| `hideOnComplete` | boolean | true | `true` = 队列全部播完åŽè‡ªåЍéšè—ï¼›`false` = ä¿æŒæ˜¾ç¤º | + +--- + +### 4.14 remove(id) + +**é”€æ¯æŒ‡å®š Spine 实例,释放内存。** + +```javascript +gameabc_face.spineMgr.remove("hero"); +``` + +--- + +### 4.15 removeAll() + +**é”€æ¯æ‰€æœ‰ Spine 实例。** + +```javascript +gameabc_face.spineMgr.removeAll(); +``` + +### 4.16 spine_onComplete(spineId, animName, trackIndex) *(事件回调)* + +**动画完æˆå›žè°ƒã€‚æ¯æ¬¡åŠ¨ç”»æ’­æ”¾ä¸€è½®ç»“æŸæ—¶è§¦å‘。** 在 `js/Spine_Event.js` 中定义。 + +```javascript +// 在 Spine_Event.js 中定义 +gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { + // ç¤ºä¾‹ï¼šæ”»å‡»æ’­å®ŒåŽæ¢å¤ idle + if (animName === "attack") { + gameabc_face.spineMgr.setAnimation(spineId, "idle", true); + } +}; +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `spineId` | string | å®žä¾‹æ ‡è¯†ï¼ˆå³ load / autoLoad æ—¶çš„ id) | +| `animName` | string | 刚完æˆçš„动画åç§° | +| `trackIndex` | number | 轨é“å·ï¼ˆé€šå¸¸ä¸º 0) | + +> **注æ„**ï¼šå¾ªçŽ¯åŠ¨ç”»æ¯æ’­å®Œä¸€è½®ä¹Ÿä¼šè§¦å‘。`playOnce` / `playQueue` 的自动éšè—在此回调**之å‰**执行, +> 因此回调中å¯ä»¥æ£€æŸ¥ `visible` çŠ¶æ€æˆ–釿–°æ˜¾ç¤ºå®žä¾‹ã€‚ + +--- + +### 4.17 spine_onEvent(spineId, eventName, intValue, floatValue, stringValue) *(事件回调)* + +**自定义事件回调。当动画播放到 Spine 编辑器中定义的 Event 关键帧时触å‘。** 在 `js/Spine_Event.js` 中定义。 + +```javascript +// 在 Spine_Event.js 中定义 +gameabc_face.spine_onEvent = function(spineId, eventName, intValue, floatValue, stringValue) { + if (eventName === "footstep") { + // 播放脚步声 + } + if (eventName === "hit") { + // 产生伤害判定 + } +}; +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `spineId` | string | 实例标识 | +| `eventName` | string | Spine 编辑器中定义的事件å | +| `intValue` | number | äº‹ä»¶çš„æ•´æ•°å‚æ•° | +| `floatValue` | number | äº‹ä»¶çš„æµ®ç‚¹å‚æ•° | +| `stringValue` | string | äº‹ä»¶çš„å­—ç¬¦ä¸²å‚æ•° | + +> 事件需è¦åœ¨ Spine 编辑器的时间线中预先添加 Event Key,导出 JSON åŽè¿è¡Œæ—¶è‡ªåŠ¨è§£æžã€‚ + +--- + +## 5. 事件系统(详细说明) + +Spine 动画在è¿è¡Œæ—¶ä¼šè§¦å‘两类事件,回调定义在 `js/Spine_Event.js` 中。 +API ç­¾åè§ [4.16](#416-spine_oncompletespineid-animname-trackindex--事件回调) å’Œ [4.17](#417-spine_oneventspineid-eventname-intvalue-floatvalue-stringvalue--事件回调)。 + +### 5.1 动画完æˆäº‹ä»¶ spine_onComplete + +**æ¯æ¬¡åŠ¨ç”»å¾ªçŽ¯æ’­æ”¾ä¸€è½®ç»“æŸæ—¶è§¦å‘。** + +```javascript +// 在 Spine_Event.js 中 +gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { + // spineId : load 时的唯一标识, 如 "hero" + // animName : 完æˆçš„动画å, 如 "attack" + // trackIndex : 轨é“å· (通常为 0) + + // 示例:éžå¾ªçŽ¯æ”»å‡»åŠ¨ç”»æ’­å®ŒåŽæ¢å¤ idle + if (animName === "attack") { + gameabc_face.spineMgr.setAnimation(spineId, "idle", true); + } +}; +``` + +### 5.2 自定义事件 spine_onEvent + +**当动画播放到 Spine 编辑器中定义的 Event 关键帧时触å‘。** + +```javascript +// 在 Spine_Event.js 中 +gameabc_face.spine_onEvent = function(spineId, eventName, intValue, floatValue, stringValue) { + // spineId : 唯一标识 + // eventName : Spine 编辑器中定义的事件å + // intValue : æ•´æ•°å‚æ•° + // floatValue : æµ®ç‚¹å‚æ•° + // stringValue : å­—ç¬¦ä¸²å‚æ•° + + if (eventName === "footstep") { + // 播放脚步声 + } + if (eventName === "hit") { + // 产生伤害判定 + } +}; +``` + +### 如何在 Spine 编辑器中添加事件 + +1. 打开 Spine 编辑器,选中动画 +2. 在时间线底部点击å³é”® → **Add Event Key** +3. 在 **Tree** 颿¿ä¸­åˆ›å»ºå¹¶å‘½å事件(如 `hit`ã€`footstep`) +4. å¯ä¸ºäº‹ä»¶è®¾ç½® int / float / string 傿•° +5. 导出 JSON åŽï¼Œè¿è¡Œæ—¶ä¼šè‡ªåŠ¨è§£æžå¹¶è§¦å‘回调 + +--- + +## 6. 常è§ç”¨æ³•示例 + +### 6.1 加载多个角色 + +```javascript +// 在 gamestart æˆ–ä»»æ„æ—¶æœºï¼Œç›´æŽ¥è®¾ç½®ä½ç½®å¹¶æ’­æ”¾ï¼ˆè‡ªåŠ¨åŠ è½½ï¼‰ +gameabc_face.spineMgr.setPosition("hero", 640, 500); +gameabc_face.spineMgr.setAnimation("hero", "idle", true); + +gameabc_face.spineMgr.setPosition("npc", 300, 500); +gameabc_face.spineMgr.setAnimation("npc", "idle", true); + +gameabc_face.spineMgr.setPosition("monster", 900, 500); +gameabc_face.spineMgr.setAnimation("monster", "walk", true); +``` + +### 6.2 播放一次åŽéšè— / 队列播放 + +```javascript +// 播放一次攻击动画,完æˆåŽè‡ªåЍéšè— +gameabc_face.spineMgr.setPosition("effect", 640, 400); +gameabc_face.spineMgr.playOnce("effect", "explode"); + +// 队列播放:攻击 → 死亡,全部播完åŽè‡ªåЍéšè— +gameabc_face.spineMgr.playQueue("monster", ["hit", "die"]); + +// 队列播放:入场 → 待机,全部播完åŽä¿æŒæ˜¾ç¤º +gameabc_face.spineMgr.playQueue("hero", ["intro", "idle"], false); +``` + +### 6.3 点击切æ¢åŠ¨ç”»ï¼ˆæ”»å‡»â†’æ¢å¤ï¼‰ + +```javascript +gameabc_face.mousedown = function(gameid, spid, downx, downy) { + // 点击播放攻击(éžå¾ªçŽ¯ï¼‰ + gameabc_face.spineMgr.setAnimation("hero", "attack", false); + // 攻击完自动切回 idle + gameabc_face.spineMgr.addAnimation("hero", "idle", true, 0); +}; +``` + +### 6.4 角色移动 + 动画è”动 + +```javascript +var heroState = "idle"; + +gameabc_face.mousedown = function(gameid, spid, downx, downy) { + heroState = "run"; + gameabc_face.spineMgr.setAnimation("hero", "run", true); +}; + +gameabc_face.mouseup = function(gameid, spid_down, downx, downy, spid_up, upx, upy) { + heroState = "idle"; + gameabc_face.spineMgr.setAnimation("hero", "idle", true); +}; + +gameabc_face.mousemove = function(gameid, spid, downx, downy, movex, movey, timelong, offmovex, offmovey) { + // 通过拖拽移动角色 + var mgr = gameabc_face.spineMgr; + var entry = mgr._entries["hero"]; + if (entry) { + mgr.setPosition("hero", entry.x + offmovex, entry.y + offmovey); + // æ ¹æ®ç§»åŠ¨æ–¹å‘翻转 + mgr.setFlip("hero", offmovex < 0, false); + } +}; +``` + +### 6.5 多轨é“å åŠ ï¼ˆèµ°è·¯ + 射击) + +Spine 支æŒå¤šè½¨é“åŒæ—¶æ’­æ”¾åŠ¨ç”»ã€‚ä½Žè½¨é“(track 0)为基础动画,高轨é“覆盖部分骨骼: + +```javascript +// track 0: 下åŠèº«èµ°è·¯ +gameabc_face.spineMgr.setAnimation("hero", "walk", true, 0); + +// track 1: 上åŠèº«å°„击(在 Spine 编辑器中åªè®¾ç½®ä¸ŠåŠèº«éª¨éª¼çš„关键帧) +gameabc_face.spineMgr.setAnimation("hero", "shoot", false, 1); +``` + +### 6.6 动æ€åˆ‡æ¢çš®è‚¤ï¼ˆæ¢è£…系统) + +```javascript +// 查看有哪些皮肤 +var skins = gameabc_face.spineMgr.getSkins("hero"); +logmessage("å¯ç”¨çš®è‚¤: " + skins.join(", ")); + +// 切æ¢åˆ°æˆ˜å£«çš®è‚¤ +gameabc_face.spineMgr.setSkin("hero", "warrior"); + +// 切æ¢åˆ°æ³•师皮肤 +gameabc_face.spineMgr.setSkin("hero", "mage"); +``` + +### 6.7 è¿è¡Œæ—¶æŸ¥è¯¢åŠ¨ç”»åˆ—è¡¨ + +```javascript +gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { + var anims = gameabc_face.spineMgr.getAnimations(spineId); + logmessage(spineId + " 拥有的动画: " + anims.join(", ")); +}; +``` + +--- + +## 7. 与 gameabc ç²¾çµç³»ç»Ÿé…åˆ + +### æ¸²æŸ“æ—¶åº + +``` +gameabc 引擎循环 (æ¯å¸§) + │ + ├── gamebegindraw() ↠帧开始 + ├── é历 Layer → æ¯ä¸ªç²¾çµ: + │ ├── gamemydrawbegin() + │ ├── ç²¾çµè‡ªç»˜ (图片/文字) + │ └── gamemydraw() + ├── gameenddraw() ↠用户自定义逻辑 + │ └── (自动) spineMgr.updateAndDraw(ctx) ↠★ 通过 defineProperty 自动追加 + └── å¸§ç»“æŸ +``` + +Spine 动画在 `gameenddraw` 末尾**自动渲染**(通过 `Object.defineProperty` 拦截实现, +无论开å‘è€…å¦‚ä½•é‡æ–°å®šä¹‰ `gameenddraw`,Spine 渲染都ä¸ä¼šä¸¢å¤±ï¼‰ï¼Œ +因此会**覆盖在所有 gameabc ç²¾çµä¹‹ä¸Š**。 +å¼€å‘者在 `gameenddraw` 中编写的自定义逻辑会先执行,Spine 渲染在其åŽè‡ªåŠ¨æ‰§è¡Œã€‚ + +### å¦‚æžœéœ€è¦ Spine 在精çµä¹‹ä¸‹æ¸²æŸ“ + +å¯ä»¥é€šè¿‡æ‰‹åŠ¨æŽ§åˆ¶æ¸²æŸ“æ—¶æœºæ¥å®žçŽ°ã€‚åœ¨ `gamebegindraw` 中手动调用渲染,并ç¦ç”¨è‡ªåŠ¨æ¸²æŸ“ï¼š + +```javascript +// æ–¹å¼ï¼šåœ¨ gamebegindraw 中手动渲染 +gameabc_face.gamebegindraw = function(gameid, spid, times, timelong) { + var ctx = gameabc_face.dc; + if (ctx) { + gameabc_face.spineMgr.updateAndDraw(ctx); + } + // 标记自动渲染跳过(因为已在此手动渲染) + gameabc_face.spineMgr._rendered = true; +}; +``` + +> 注æ„:当å‰è‡ªåŠ¨æŒ‚é’©åœ¨ gameenddraw 末尾,如需精细控制层级, +> å¯å°† SpineMgr._inited 临时置 false 跳过自动渲染,手动选择渲染时机。 + +### 让 Spine è·ŸéšæŸä¸ªç²¾çµç§»åЍ + +```javascript +gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { + // 让 Spine 角色跟éšç²¾çµ 1 çš„ä½ç½® + if (spid === 1) { + var sx = get_self(1, 18, 0, 0, 0); // 获å–ç²¾çµ 1 çš„ X + var sy = get_self(1, 19, 0, 0, 0); // 获å–ç²¾çµ 1 çš„ Y + gameabc_face.spineMgr.setPosition("hero", sx, sy); + } +}; +``` + +--- + +## 8. 性能优化建议 + +### 8.1 å›¾é›†çº¹ç† + +- 纹ç†å°ºå¯¸å»ºè®®ä¸è¶…过 **2048×2048** +- 导出时勾选 **Power of two** ç¡®ä¿å°ºå¯¸ä¸º 2 的幂 +- ä¸è¦å‹¾é€‰ **Premultiply alpha**(Canvas 2D ä¸éœ€è¦é¢„乘 Alpha) + +### 8.2 æŽ§åˆ¶å®žä¾‹æ•°é‡ + +- Canvas 2D 渲染性能有é™ï¼Œå»ºè®®åŒå± Spine 实例ä¸è¶…过 **5-8 个** +- ä¸å¯è§çš„实例调用 `setVisible(id, false)`,跳过渲染和更新 +- ä¸å†éœ€è¦çš„实例调用 `remove(id)` 释放内存 + +### 8.3 å‡å°‘éª¨éª¼å¤æ‚度 + +- 骨骼数é‡å»ºè®®æŽ§åˆ¶åœ¨ **50 个**以内 +- å‡å°‘网格å˜å½¢ï¼ˆMesh Deform),对 Canvas 2D å½±å“较大 +- 使用è£å‰ªï¼ˆClipping)时性能开销大,谨慎使用 + +### 8.4 åŠ¨ç”»æ··åˆæ—¶é•¿ + +`mixDuration` 越长,过渡越平滑,但在切æ¢çž¬é—´éœ€è¦åŒæ—¶è®¡ç®—两个动画。 +建议设为 **0.1 ~ 0.3 ç§’**。 + +--- + +## 9. 常è§é—®é¢˜æŽ’查 + +### Q1: ç”»é¢ä¸Šçœ‹ä¸åˆ° Spine 动画 + +**检查清å•:** + +1. **æ–‡ä»¶è·¯å¾„æ˜¯å¦æ­£ç¡®ï¼Ÿ** + - 确认 `assets/spine/` 目录下有 `.json`ã€`.atlas`ã€`.png` + - 文件å大å°å†™å¿…须一致(Linux/Mac æœåŠ¡å™¨åŒºåˆ†å¤§å°å†™ï¼‰ + +2. **是å¦é€šè¿‡ HTTP 访问?** + - `file://` å议无法加载跨域资æºï¼Œå¿…须使用 HTTP æœåС噍 + +3. **打开æµè§ˆå™¨æŽ§åˆ¶å°ï¼ˆF12)看报错** + - 404 错误:文件路径有误 + - JSON è§£æžé”™è¯¯ï¼š`.json` 文件格å¼å¼‚常 + - `spine is not defined`:`spine-canvas.js` 未正确加载 + +4. **åæ ‡æ˜¯å¦åœ¨å¯è§èŒƒå›´å†…?** + - 项目设计尺寸为 1280×720,检查 `x` å’Œ `y` 是å¦åœ¨æ­¤èŒƒå›´ + +5. **logmessage è¾“å‡ºæ˜¯å¦æœ‰ "[SpineMgr] xxx 构建完æˆ"?** + - 有 → 加载æˆåŠŸï¼Œæ£€æŸ¥åæ ‡å’Œç¼©æ”¾ + - 有 "构建失败" → æŸ¥çœ‹å…·ä½“é”™è¯¯ä¿¡æ¯ + - 没有 → 资æºè¿˜åœ¨åŠ è½½ä¸­æˆ–è·¯å¾„é”™è¯¯ + +### Q2: 动画显示ä½ç½®ä¸å¯¹ + +- Spine 编辑器中设置骨骼原点的ä½ç½®ä¼šå½±å“è¿è¡Œæ—¶çš„锚点 +- 调整 `setPosition` çš„åæ ‡ï¼Œæˆ–在 Spine 编辑器中修改根骨骼ä½ç½® +- æ³¨æ„ Spine çš„ Y 轴与 Canvas Y è½´æ–¹å‘å¯èƒ½ä¸åŒ + +### Q3: 动画速度太快或太慢 + +- 检查 `gameabc_Project` 中的 `fps` 设置(默认 30) +- SpineMgr 内部是用 `Date.now()` 计算真实时间差的,ä¸ä¾èµ–帧率 +- 如果需è¦å€é€Ÿæ’­æ”¾ï¼Œä¿®æ”¹ `state.timeScale`: + ```javascript + var entry = gameabc_face.spineMgr._entries["hero"]; + entry.state.timeScale = 2.0; // 2 å€é€Ÿ + ``` + +### Q4: 切æ¢åŠ¨ç”»æ—¶æœ‰è·³å¸§ + +- 增大 `mixDuration`(加载时的 option 或修改 `stateData.defaultMix`) +- 使用 `addAnimation` æŽ’é˜Ÿè€Œä¸æ˜¯ç›´æŽ¥ `setAnimation` 打断 + +### Q5: 多个 Spine 实例é‡å æ—¶é—ªçƒ + +- 确认没有åŒä¸€ä¸ª id 加载两次 +- 检查 `ctx.save()` / `ctx.restore()` 是å¦é…对(SpineMgr 内部已处ç†ï¼‰ + +### Q6: spine-canvas.js 版本与 Spine 编辑器版本ä¸åŒ¹é… + +- **spine-canvas.js 4.2** 需æ­é… **Spine 编辑器 4.2.x** å¯¼å‡ºçš„æ•°æ® +- 如果使用 Spine 4.1 编辑器,请下载对应版本的è¿è¡Œæ—¶ï¼š + ``` + https://unpkg.com/@esotericsoftware/spine-canvas@4.1/dist/iife/spine-canvas.js + ``` + +--- + +## 10. é™„å½•ï¼šæ–‡ä»¶åŠ è½½é¡ºåº + +`index.html` 中的 script 标签加载顺åºè‡³å…³é‡è¦ï¼š + +``` +1. spine-canvas.js ↠先加载 Spine è¿è¡Œæ—¶ (定义 window.spine) +2. gameabc.min.js ↠å†åŠ è½½æ¸¸æˆå¼•擎 +3. SpineMgr.js ↠Spine 管ç†å™¨ + defineProperty 自动挂钩渲染 +4. gamemain.js ↠游æˆä¸»é€»è¾‘(ä¸éœ€ä¿®æ”¹ï¼Œç›´æŽ¥è°ƒç”¨ API å³å¯ï¼‰ +5. Spine_Event.js ↠Spine 事件回调 (ä¾èµ– gameabc_face) +6. Project1_Event.js ↠精çµäº‹ä»¶ +7. gameabc_data.min.js ↠项目é…ç½®æ•°æ® (引擎åˆå§‹åŒ–) +``` + +> **ä¸èƒ½è°ƒæ¢é¡ºåº**,`SpineMgr.js` 必须在 `gamemain.js` 之å‰åŠ è½½ï¼Œ +> å¦åˆ™ä¼šå‡ºçް `spine is not defined` 或 `gameabc_face.spineMgr is undefined` 的错误。 + +--- + +## 附录:完整最å°ç¤ºä¾‹ gamemain.js + +`gamemain.js` **ä¸éœ€è¦ä»»ä½•修改**ï¼Œä¿æŒåŽŸæ ·å³å¯ã€‚在任æ„事件回调中直接调用 `gameabc_face.spineMgr` çš„ API: + +```javascript +// gamemain.js —— 无需修改框架,åªéœ€åœ¨å›žè°ƒä¸­è°ƒç”¨ API + +gameabc_face.gamestart = function(gameid) { + // 直接设置ä½ç½®å¹¶æ’­æ”¾åŠ¨ç”»ï¼ˆè‡ªåŠ¨åŠ è½½ï¼Œæ— éœ€ load) + gameabc_face.spineMgr.setPosition("mj_gangshangkaihua", 640, 500); + gameabc_face.spineMgr.setAnimation("mj_gangshangkaihua", "animation", true); +}; + +// gameenddraw ä¿æŒåŽŸæ ·ï¼ŒSpine 渲染由 SpineMgr.js è‡ªåŠ¨å¤„ç† +gameabc_face.gameenddraw = function(gameid, spid, times, timelong) { + // 这里写其他自定义绘制逻辑,或留空 +}; + +gameabc_face.mousedown = function(gameid, spid, downx, downy) { + // 点击播放动画 + gameabc_face.spineMgr.setAnimation("mj_gangshangkaihua", "animation", false); +}; +``` + +> **é‡è¦**:`SpineMgr.js` 是独立文件,通过 `Object.defineProperty` 自动拦截 `gameenddraw`, +> 无论 `gamemain.js` 如何定义 `gameenddraw`,Spine æ¸²æŸ“éƒ½ä¼šè‡ªåŠ¨è¿½åŠ åœ¨å…¶åŽæ‰§è¡Œã€‚ +> `gamemain.js` 完全ä¸éœ€è¦ä¿®æ”¹ã€‚ + +--- + +> **å‚考链接** +> - Spine 官方è¿è¡Œæ—¶æ–‡æ¡£: https://zh.esotericsoftware.com/spine-api-reference +> - Spine Player 在线演示: https://jp.esotericsoftware.com/spine-player +> - spine-canvas npm 包: https://www.npmjs.com/package/@esotericsoftware/spine-canvas diff --git a/codes/games/client/Projects/Game_Surface_3/generated/spine_assets.js b/codes/games/client/Projects/Game_Surface_3/generated/spine_assets.js new file mode 100644 index 0000000..6866ab1 --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/generated/spine_assets.js @@ -0,0 +1,4 @@ +// Spine resource list (auto-generated, do not edit manually) +gameabc_face.spineAssets = [ + "gamestart" +]; diff --git a/codes/games/client/Projects/Game_Surface_3/generated/spine_data.js b/codes/games/client/Projects/Game_Surface_3/generated/spine_data.js new file mode 100644 index 0000000..26135da --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/generated/spine_data.js @@ -0,0 +1,5 @@ +// Spine text data (auto-generated, do not edit manually) +// Embeds .json/.atlas content into JS to bypass file:// XHR CORS +gameabc_face.spineTextData = {}; +gameabc_face.spineTextData['gamestart.json'] = '{"skeleton":{"hash":"Cs22lzcwV3A","spine":"4.2.43","x":-862.3,"y":-188.35,"width":1724.6,"height":375.11,"images":"./0/","audio":"I:\\\\游æˆç´ ææ”¶é›†\\\\棋牌\\\\é—²æ¥æ–—地主\\\\spine\\\\UI\\\\pipei_fx"},"bones":[{"name":"root"},{"name":"loading","parent":"root"},{"name":"pipeizhong","parent":"root"},{"name":"zhong","parent":"pipeizhong","length":35.15,"rotation":88.12,"x":97.58,"y":5.54},{"name":"pi","parent":"pipeizhong","x":-86.85,"y":2.78},{"name":"pei","parent":"pipeizhong","x":0.58,"y":-3.86},{"name":"lizi","parent":"root","length":9.44,"rotation":5.19,"x":187.44,"y":25.51},{"name":"lizi2","parent":"root","length":9.44,"rotation":5.19,"x":-235.41,"y":-103.34,"scaleX":0.9,"scaleY":0.9},{"name":"lizi3","parent":"root","length":9.44,"rotation":5.19,"x":91.71,"y":-113.98,"scaleX":0.8,"scaleY":0.8},{"name":"lizi4","parent":"root","length":9.44,"rotation":5.19,"x":-202.78,"y":94.66},{"name":"lizi5","parent":"root","length":9.44,"rotation":5.19,"x":167.97,"y":36.8,"scaleX":0.5,"scaleY":0.5},{"name":"lizi6","parent":"root","length":9.44,"rotation":5.19,"x":-162.19,"y":6.78,"scaleX":0.5,"scaleY":0.5},{"name":"taoxin_zong","parent":"root"},{"name":"glow_y","parent":"root"},{"name":"fangkuai","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.8,"scaleY":0.8},{"name":"tiao_new","parent":"root"},{"name":"heitao","parent":"tiao_new"},{"name":"heitao2","parent":"tiao_new"},{"name":"lizi7","parent":"root","length":9.44,"rotation":5.19,"x":60.86,"y":77.88},{"name":"lizi8","parent":"root","length":9.44,"rotation":5.19,"x":-73.19,"y":-90.44,"scaleX":1.5,"scaleY":1.5},{"name":"glow_y2","parent":"root"},{"name":"star","parent":"root","length":17.48,"x":14.55,"y":40.7},{"name":"fangkuai2","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.4,"scaleY":0.4},{"name":"fangkuai3","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.6,"scaleY":0.6},{"name":"fangkuai4","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.7,"scaleY":0.7},{"name":"lizi9","parent":"root","length":9.44,"rotation":5.19,"x":-92.32,"y":75.72,"scaleX":1.2,"scaleY":1.2},{"name":"fangkuai5","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.6,"scaleY":0.6},{"name":"fangkuai6","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.4,"scaleY":0.4},{"name":"fangkuai7","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.5,"scaleY":0.5},{"name":"fangkuai8","parent":"root","length":28.56,"x":343.36,"y":-3.03},{"name":"fangkuai9","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.8,"scaleY":0.8},{"name":"star4","parent":"root","length":17.48,"x":202.79,"y":-34.6},{"name":"lizi10","parent":"root","length":9.44,"rotation":5.19,"x":-179.89,"y":22.58,"scaleX":0.5,"scaleY":0.5},{"name":"glow_bian","parent":"tiao_new"},{"name":"glow_bian2","parent":"tiao_new"},{"name":"success2","parent":"root"},{"name":"dian","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"dian2","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"dian3","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"tiao","parent":"tiao_new","scaleX":1.2928}],"slots":[{"name":"BG","bone":"root"},{"name":"ck_new","bone":"root"},{"name":"new_tiao_orange","bone":"tiao","attachment":"new_tiao_orange"},{"name":"heitao_01","bone":"heitao","attachment":"heitao_01"},{"name":"heitao_2","bone":"heitao2","attachment":"heitao_02"},{"name":"glow_bian","bone":"glow_bian","blend":"additive"},{"name":"glow_bian2","bone":"glow_bian2","blend":"additive"},{"name":"loading_aixin","bone":"loading"},{"name":"pi","bone":"pi","attachment":"pi"},{"name":"pei","bone":"pei","attachment":"pei"},{"name":"zhong","bone":"zhong","attachment":"zhong"},{"name":"lizi_1","bone":"lizi","attachment":"lizi_1","blend":"additive"},{"name":"lizi_7","bone":"lizi7","attachment":"lizi_1","blend":"additive"},{"name":"lizi_9","bone":"lizi9","attachment":"lizi_1","blend":"additive"},{"name":"lizi_5","bone":"lizi5","attachment":"lizi_1","blend":"additive"},{"name":"lizi_10","bone":"lizi10","attachment":"lizi_1","blend":"additive"},{"name":"lizi_6","bone":"lizi6","attachment":"lizi_1","blend":"additive"},{"name":"lizi_3","bone":"lizi3","attachment":"lizi_1","blend":"additive"},{"name":"lizi_4","bone":"lizi4","attachment":"lizi_1","blend":"additive"},{"name":"lizi_8","bone":"lizi8","attachment":"lizi_1","blend":"additive"},{"name":"lizi_2","bone":"lizi2","attachment":"lizi_1","blend":"additive"},{"name":"lamp_glow3","bone":"glow_y","attachment":"lamp_glow","blend":"additive"},{"name":"fangkuai6","bone":"fangkuai","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai5","bone":"fangkuai5","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai4","bone":"fangkuai4","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai11","bone":"fangkuai8","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai12","bone":"fangkuai9","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai2","bone":"fangkuai2","blend":"additive"},{"name":"fangkuai7","bone":"fangkuai6","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai3","bone":"fangkuai3","blend":"additive"},{"name":"fangkuai9","bone":"fangkuai7","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai_kuang6","bone":"fangkuai","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang5","bone":"fangkuai5","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang4","bone":"fangkuai4","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang11","bone":"fangkuai8","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang12","bone":"fangkuai9","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang2","bone":"fangkuai2","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang7","bone":"fangkuai6","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang3","bone":"fangkuai3","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang9","bone":"fangkuai7","attachment":"fangkuai_kuang","blend":"screen"},{"name":"duijukaishi","bone":"success2","attachment":"duijukaishi"},{"name":"duijukaishi2","bone":"success2","attachment":"duijukaishi","blend":"additive"},{"name":"lamp_glow4","bone":"glow_y2","attachment":"lamp_glow","blend":"additive"},{"name":"lamp_glow5","bone":"glow_y2","attachment":"lamp_glow","blend":"additive"},{"name":"star2","bone":"star","attachment":"xingguang","blend":"additive"},{"name":"star8","bone":"star4","attachment":"xingguang","blend":"additive"},{"name":"dian","bone":"dian","attachment":"dian"},{"name":"dian2","bone":"dian2","attachment":"dian"},{"name":"dian3","bone":"dian3","attachment":"dian"},{"name":"ck_waiting","bone":"root","color":"ffffff86"}],"skins":[{"name":"default","attachments":{"dian":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"dian2":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"dian3":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"duijukaishi":{"duijukaishi":{"width":380,"height":92}},"duijukaishi2":{"duijukaishi":{"width":380,"height":92}},"fangkuai2":{"fangkuai":{"width":32,"height":32}},"fangkuai3":{"fangkuai":{"width":32,"height":32}},"fangkuai4":{"fangkuai":{"width":32,"height":32}},"fangkuai5":{"fangkuai":{"width":32,"height":32}},"fangkuai6":{"fangkuai":{"width":32,"height":32}},"fangkuai7":{"fangkuai":{"width":32,"height":32}},"fangkuai9":{"fangkuai":{"width":32,"height":32}},"fangkuai11":{"fangkuai":{"width":32,"height":32}},"fangkuai12":{"fangkuai":{"width":32,"height":32}},"fangkuai_kuang2":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang3":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang4":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang5":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang6":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang7":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang9":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang11":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang12":{"fangkuai_kuang":{"width":32,"height":32}},"glow_bian":{"glow_bian":{"x":422.12,"y":-69.57,"scaleX":1.2,"scaleY":0.6,"width":330,"height":9}},"glow_bian2":{"glow_bian":{"x":422.12,"y":64.41,"scaleX":1.2,"scaleY":0.6,"width":330,"height":9}},"heitao_01":{"heitao_01":{"y":-1.9,"width":236,"height":218}},"heitao_2":{"heitao_02":{"y":-2.2,"width":442,"height":219}},"lamp_glow3":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"scaleY":2.0276,"width":198,"height":185}},"lamp_glow4":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"scaleY":2.0276,"width":198,"height":185}},"lamp_glow5":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"width":198,"height":185}},"lizi_1":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_2":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_3":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_4":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_5":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_6":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_7":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_8":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_9":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_10":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"loading_aixin":{"loading_aixin":{"x":103.12,"y":81.11,"width":28,"height":28}},"new_tiao_orange":{"new_tiao_orange":{"y":-2.26,"scaleX":2,"width":667,"height":217}},"pei":{"dai":{"x":5.24,"y":2.96,"width":96,"height":90},"pei":{"x":3.04,"y":2.96,"width":105,"height":92}},"pi":{"deng":{"x":-1.03,"y":-4.17,"width":101,"height":90},"pi":{"x":-1.03,"y":-4.17,"width":104,"height":89}},"star2":{"xingguang":{"x":0.34,"scaleX":0.3,"scaleY":0.3,"width":256,"height":256}},"star8":{"xingguang":{"scaleX":0.2,"scaleY":0.2,"width":256,"height":256}},"zhong":{"zhong":{"x":-6.91,"y":-0.76,"rotation":-88.12,"width":98,"height":93}}}}],"animations":{"start":{"slots":{"duijukaishi":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.1667,"color":"ffffff00"},{"time":0.3,"color":"ffffffff"}]},"duijukaishi2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff","curve":"stepped"},{"time":0.4,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai2":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"time":0.4667,"name":"fangkuai"},{"time":0.6}]},"fangkuai3":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}],"attachment":[{"time":0.6333,"name":"fangkuai"},{"time":0.7667}]},"fangkuai4":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}],"attachment":[{"time":0.3},{"time":0.4333,"name":"fangkuai"}]},"fangkuai5":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}],"attachment":[{"time":0.4},{"time":0.5333,"name":"fangkuai"}]},"fangkuai6":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}],"attachment":[{"time":0.5333},{"time":0.7,"name":"fangkuai"}]},"fangkuai7":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"time":0.6}]},"fangkuai9":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}],"attachment":[{"time":0.5},{"time":0.6333,"name":"fangkuai"}]},"fangkuai11":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}],"attachment":[{"time":0.2667},{"time":0.4,"name":"fangkuai"},{"time":0.5333}]},"fangkuai12":{"rgba":[{"time":0.7333,"color":"ffffffff"},{"time":0.9667,"color":"ffffff00"}],"attachment":[{"time":0.5667},{"time":0.7,"name":"fangkuai"},{"time":0.8333}]},"fangkuai_kuang2":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}]},"fangkuai_kuang3":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}]},"fangkuai_kuang4":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai_kuang5":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}]},"fangkuai_kuang6":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}]},"fangkuai_kuang7":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}]},"fangkuai_kuang9":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}]},"fangkuai_kuang11":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai_kuang12":{"rgba":[{"time":0.7333,"color":"ffffffff"},{"time":0.9667,"color":"ffffff00"}]},"glow_bian":{"rgba":[{"time":0.7667,"color":"ffffffff"},{"time":0.9,"color":"ffffff00"}],"attachment":[{"time":0.3667,"name":"glow_bian"}]},"glow_bian2":{"rgba":[{"time":0.7667,"color":"ffffffff"},{"time":0.9,"color":"ffffff00"}],"attachment":[{"time":0.3667,"name":"glow_bian"}]},"heitao_01":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.2,"color":"ffffff00","curve":[0.242,1,0.325,1,0.242,1,0.325,1,0.242,1,0.325,1,0.242,0,0.325,1]},{"time":0.3667,"color":"ffffffff"}]},"heitao_2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3,"color":"ffffff00","curve":[0.342,1,0.425,1,0.342,1,0.425,1,0.342,1,0.425,1,0.342,0,0.425,1]},{"time":0.4667,"color":"ffffffff"}]},"lamp_glow3":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.0667,"color":"ffffffb4"},{"time":0.2,"color":"ffffff00"}],"attachment":[{}]},"lamp_glow4":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.4,"color":"ffffffb4"},{"time":0.5,"color":"ffffff00"}]},"lamp_glow5":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.4,"color":"ffffffb4"},{"time":0.5,"color":"ffffff00"}]},"lizi_7":{"rgba":[{"color":"ffdf63ff"}]},"lizi_8":{"rgba":[{"color":"ffdf63ff"}]},"lizi_9":{"rgba":[{"color":"ffdf64ff"}]},"lizi_10":{"attachment":[{}]},"new_tiao_orange":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.0667,"color":"ffffff00"},{"time":0.1333,"color":"ffffffff"}]},"pei":{"attachment":[{"name":"dai"}]},"pi":{"attachment":[{"name":"deng"}]},"star2":{"attachment":[{},{"time":0.4333,"name":"xingguang"},{"time":0.7667}]},"star8":{"attachment":[{},{"time":0.6,"name":"xingguang"}]}},"bones":{"fangkuai5":{"rotate":[{"time":0.3},{"time":0.7667,"value":-44.88}],"translate":[{"x":-504.35,"y":11.18,"curve":"stepped"},{"time":0.3,"x":-504.35,"y":11.18},{"time":0.7667,"x":-599.14,"y":28.32}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3,"x":0,"y":0},{"time":0.4},{"time":0.5333,"x":0.5,"y":0.5},{"time":0.6333},{"time":0.7667,"x":0.5,"y":0.5}]},"fangkuai6":{"rotate":[{"value":-44.88,"curve":"stepped"},{"time":0.3667,"value":-44.88},{"time":0.8333}],"translate":[{"x":-517.09,"y":-15.18,"curve":"stepped"},{"time":0.3667,"x":-517.09,"y":-15.18},{"time":0.8333,"x":-624.16,"y":-31.78}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3667,"x":0,"y":0},{"time":0.4667},{"time":0.6,"x":0.5,"y":0.5},{"time":0.7},{"time":0.8333,"x":0.5,"y":0.5}]},"fangkuai7":{"rotate":[{"value":30,"curve":"stepped"},{"time":0.4,"value":30},{"time":0.8667,"value":-90}],"translate":[{"x":-498.9,"y":4.26,"curve":"stepped"},{"time":0.4,"x":-498.9,"y":4.26},{"time":0.8667,"x":-570.14,"y":-1.69}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.4,"x":0,"y":0},{"time":0.5},{"time":0.6333,"x":0.5,"y":0.5},{"time":0.7333},{"time":0.8667,"x":0.5,"y":0.5}]},"success2":{"scale":[{"x":2.7,"y":2.2,"curve":"stepped"},{"time":0.1667,"x":2.7,"y":2.2},{"time":0.2,"x":2.51,"y":1.363},{"time":0.2333,"x":2.32,"y":1.92},{"time":0.3333,"x":0.8,"y":0.8},{"time":0.5,"x":1.06,"y":1.06},{"time":0.6667}]},"glow_y2":{"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2667,"x":0,"y":0},{"time":0.3333,"x":1.5,"y":1.2},{"time":0.5,"x":2,"y":0}]},"pei":{"translate":[{"x":-40.85}]},"star":{"rotate":[{"time":0.4333},{"time":0.7667,"value":-60}],"translate":[{"x":1.77,"y":0.73}],"scale":[{"time":0.4333},{"time":0.7667,"x":0,"y":0}]},"fangkuai3":{"rotate":[{"value":30,"curve":"stepped"},{"time":0.4,"value":30},{"time":0.8667,"value":-90}],"translate":[{"x":-148.5,"y":26.53,"curve":"stepped"},{"time":0.4,"x":-148.5,"y":26.53},{"time":0.8667,"x":-28.24,"y":27.97}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.4,"x":0,"y":0},{"time":0.5},{"time":0.6333,"x":0.5,"y":0.5},{"time":0.7333},{"time":0.8667,"x":0.5,"y":0.5}]},"fangkuai2":{"rotate":[{"value":-44.88,"curve":"stepped"},{"time":0.3667,"value":-44.88},{"time":0.8333}],"translate":[{"x":-169.32,"y":-17.49,"curve":"stepped"},{"time":0.3667,"x":-169.32,"y":-17.49},{"time":0.8333,"x":-73.95,"y":-28.46}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3667,"x":0,"y":0},{"time":0.4667},{"time":0.6,"x":0.5,"y":0.5},{"time":0.7},{"time":0.8333,"x":0.5,"y":0.5}]},"fangkuai4":{"rotate":[{"time":0.2},{"time":0.6667,"value":-44.88}],"translate":[{"x":-135.94,"y":12.14,"curve":"stepped"},{"time":0.2,"x":-135.94,"y":12.14},{"time":0.6667,"x":0.5,"y":13.65}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2,"x":0,"y":0},{"time":0.3},{"time":0.4333,"x":0.5,"y":0.5},{"time":0.5333},{"time":0.6667,"x":0.5,"y":0.5}]},"star4":{"rotate":[{"value":-60,"curve":"stepped"},{"time":0.6,"value":-60},{"time":0.9333}],"translate":[{"x":-23.34,"y":-3.43}],"scale":[{"time":0.6},{"time":0.9333,"x":0,"y":0}]},"glow_y":{"scale":[{"x":0,"y":0},{"time":0.0667,"y":1.3},{"time":0.2,"x":2,"y":0}]},"fangkuai9":{"rotate":[{"time":0.5},{"time":0.9667,"value":-44.88}],"translate":[{"x":-510.8,"y":-9.98,"curve":"stepped"},{"time":0.5,"x":-510.8,"y":-9.98},{"time":0.9667,"x":-682.69,"y":-0.2}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.5,"x":0,"y":0},{"time":0.6},{"time":0.7333,"x":0.5,"y":0.5},{"time":0.8333},{"time":0.9667,"x":0.5,"y":0.5}]},"lizi9":{"translate":[{"x":23.12,"y":-46.87,"curve":"stepped"},{"time":0.1333,"x":23.12,"y":-46.87},{"time":0.8,"x":-32.53,"y":36.07}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.1333,"x":0,"y":0},{"time":0.3},{"time":0.4667,"x":0,"y":0},{"time":0.6333},{"time":0.8,"x":0,"y":0}]},"lizi7":{"translate":[{"x":27.53,"y":-8.06},{"time":0.9667,"x":78.87,"y":21.58}],"scale":[{"x":0,"y":0},{"time":0.1333},{"time":0.3,"x":0,"y":0},{"time":0.4667},{"time":0.6333,"x":0,"y":0},{"time":0.8},{"time":0.9667,"x":0,"y":0}]},"lizi8":{"translate":[{"x":40.95,"y":12.56},{"time":0.6333,"x":4.64,"y":-14.33}],"scale":[{"x":0,"y":0},{"time":0.1333},{"time":0.3,"x":0,"y":0},{"time":0.4667},{"time":0.6333,"x":0,"y":0}]},"glow_bian":{"translate":[{"x":-72.21,"curve":"stepped"},{"time":0.3667,"x":-72.21,"curve":[0.5,-72.21,0.767,-804.76,0.5,0,0.767,0]},{"time":0.9,"x":-804.76}]},"heitao":{"scale":[{"x":3,"curve":"stepped"},{"time":0.2,"x":3,"curve":[0.242,3,0.325,0.8,0.242,1,0.325,1]},{"time":0.3667,"x":0.8,"curve":[0.408,0.8,0.492,1.4,0.408,1,0.492,1]},{"time":0.5333,"x":1.4,"curve":[0.583,1.4,0.683,1,0.583,1,0.683,1]},{"time":0.7333}]},"glow_bian2":{"translate":[{"x":-656,"curve":"stepped"},{"time":0.3667,"x":-656,"curve":[0.5,-656,0.767,97.85,0.5,0,0.767,0]},{"time":0.9,"x":97.85}]},"pi":{"translate":[{"x":-41.74}]},"fangkuai8":{"rotate":[{"time":0.2},{"time":0.6667,"value":-44.88}],"translate":[{"x":-535.78,"y":-2.96,"curve":"stepped"},{"time":0.2,"x":-535.78,"y":-2.96},{"time":0.6667,"x":-641.17,"y":-6.75}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2,"x":0,"y":0},{"time":0.3},{"time":0.4333,"x":0.5,"y":0.5},{"time":0.5333},{"time":0.6667,"x":0.5,"y":0.5}]},"fangkuai":{"rotate":[{"time":0.3},{"time":0.7667,"value":-44.88}],"translate":[{"x":-153,"curve":"stepped"},{"time":0.3,"x":-153},{"time":0.7667,"x":-13.01}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3,"x":0,"y":0},{"time":0.4},{"time":0.5333,"x":0.5,"y":0.5},{"time":0.6333},{"time":0.7667,"x":0.5,"y":0.5}]},"heitao2":{"scale":[{"x":3,"curve":"stepped"},{"time":0.3,"x":3,"curve":[0.342,3,0.425,0.8,0.342,1,0.425,1]},{"time":0.4667,"x":0.8,"curve":[0.508,0.8,0.592,1.4,0.508,1,0.592,1]},{"time":0.6333,"x":1.4,"curve":[0.683,1.4,0.783,1,0.683,1,0.783,1]},{"time":0.8333}]},"lizi":{"scale":[{"x":0,"y":0}]},"lizi2":{"translate":[{"x":-3.71,"y":-20.79}],"scale":[{"x":0,"y":0}]},"lizi3":{"translate":[{"x":39.37,"y":-38.75}],"scale":[{"x":0,"y":0}]},"lizi4":{"scale":[{"x":0,"y":0}]},"lizi5":{"translate":[{"x":27.61,"y":27.45}],"scale":[{"x":0,"y":0}]},"lizi6":{"translate":[{"x":-51.66,"y":-60.09}],"scale":[{"x":0,"y":0}]},"pipeizhong":{"scale":[{},{"time":0.1,"x":0,"y":0}]},"tiao_new":{"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.0667,"x":0,"y":0},{"time":0.1333,"y":0.1},{"time":0.2333,"y":1.3},{"time":0.3667,"y":0.9},{"time":0.5}]},"zhong":{"translate":[{"x":-41.29}]},"dian":{"translate":[{"x":-83.49,"y":2.22}]},"dian2":{"translate":[{"x":-57.12,"y":2.22}]},"dian3":{"translate":[{"x":-31.53,"y":2.22}]}}}}}'; +gameabc_face.spineTextData['gamestart.atlas'] = 'gamestart.png\nsize:2048,512\nfilter:Linear,Linear\ndai\nbounds:1521,395,96,90\ndeng\nbounds:1418,395,101,90\ndian\nbounds:1167,183,24,22\nduijukaishi\nbounds:929,393,380,92\nfangkuai\nbounds:446,47,32,32\nfangkuai_kuang\nbounds:2,2,32,32\nglow_bian\nbounds:2,36,330,9\nheitao_01\nbounds:929,173,236,218\nheitao_02\nbounds:2,47,442,219\nlamp_glow\nbounds:446,81,198,185\nlizi_1\nbounds:646,247,19,19\nloading_aixin\nbounds:1273,363,28,28\nnew_tiao_orange\nbounds:2,268,667,217\npei\nbounds:1311,393,105,92\npi\nbounds:1167,302,104,89\nxingguang\nbounds:671,229,256,256\nzhong\nbounds:1167,207,98,93\n'; diff --git a/codes/games/client/Projects/Game_Surface_3/index.html b/codes/games/client/Projects/Game_Surface_3/index.html index 848c1c2..9b80c86 100644 --- a/codes/games/client/Projects/Game_Surface_3/index.html +++ b/codes/games/client/Projects/Game_Surface_3/index.html @@ -1,144 +1,125 @@ + - - - - - -gameabc - + } + -
- -

Your browser does not support the canvas element.

-
+
+ +

Your browser does not support the canvas element.

+
-
- -

Your browser does not support the canvas element.

-
+
+ +

Your browser does not support the canvas element.

+
-
- -

Your browser does not support the canvas element.

-
+
+ +

Your browser does not support the canvas element.

+
- -

Your browser does not support the canvas element.

-
+ +

Your browser does not support the canvas element.

+
- - - - - + - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js b/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js new file mode 100644 index 0000000..db3fd98 --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/js/SpineMgr.js @@ -0,0 +1,416 @@ +// ============================================================ +// SpineMgr —— Spine 动画管ç†å™¨ï¼ˆç‹¬ç«‹æ–‡ä»¶ï¼‰ +// 集æˆåˆ° gameabc Canvas 2D 绘制循环,零侵入 gamemain.js +// 在 index.html 中置于 gameabc.min.js 之åŽã€gamemain.js 之å‰åŠ è½½ +// ============================================================ +(function(){ + +var SpineMgr = { + + // --- å†…éƒ¨çŠ¶æ€ --- + _entries: {}, // {id: EntryObject} + _assetManager: null, + _renderer: null, // spine.SkeletonRenderer (Canvas 2D) + _lastTime: 0, // 上一帧时间戳(ms) + _inited: false, + _loadedPaths: {}, // 已请求加载的资æºè·¯å¾„,é¿å…é‡å¤è¯·æ±‚ + _pendingCmds: {}, // {id: [{method, args}]} ç­‰å¾…å®žä¾‹å°±ç»ªåŽæ‰§è¡Œçš„命令队列 + + // é»˜è®¤èµ„æºæ ¹è·¯å¾„(å¯é€šè¿‡ init 覆盖) + _basePath: "assets/spine/", + + // ---------------------------------------------------------- + // init(basePath) 手动åˆå§‹åŒ–(å¯é€‰ï¼‰ + // 如ä¸è°ƒç”¨ï¼Œload 时会自动以默认路径 "assets/spine/" åˆå§‹åŒ– + // ---------------------------------------------------------- + init: function(basePath) { + if (!window.spine) { + logmessage("[SpineMgr] spine-canvas.js 未加载,请检查引用"); + return; + } + this._basePath = basePath || this._basePath; + this._assetManager = new spine.AssetManager(this._basePath); + this._lastTime = Date.now(); + this._inited = true; + }, + + // (内部) ç¡®ä¿å·²åˆå§‹åŒ– + _ensureInit: function() { + if (!this._inited) { + this.init(this._basePath); + } + }, + + // (内部) è‡ªåŠ¨åŠ è½½ï¼šæ ¹æ® id 约定文件å id.json / id.atlas + _autoLoad: function(id) { + if (this._entries[id]) return; + this.load(id, id + ".json", id + ".atlas", {}); + }, + + // (内部) 将命令加入等待队列 + _queueCmd: function(id, method, args) { + if (!this._pendingCmds[id]) this._pendingCmds[id] = []; + this._pendingCmds[id].push({method: method, args: args}); + }, + + // (内部) å®žä¾‹å°±ç»ªåŽæ‰§è¡Œé˜Ÿåˆ—中的命令 + _flushCmds: function(id) { + var cmds = this._pendingCmds[id]; + if (!cmds || cmds.length === 0) return; + delete this._pendingCmds[id]; + for (var i = 0; i < cmds.length; i++) { + var cmd = cmds[i]; + this[cmd.method].apply(this, [id].concat(cmd.args)); + } + }, + + // ---------------------------------------------------------- + // load(id, jsonFile, atlasFile, option) + // 加载一组 Spine 资æº, id 为自定义标识 + // option: {x, y, scale, skin, animation, loop, mixDuration} + // ---------------------------------------------------------- + load: function(id, jsonFile, atlasFile, option) { + this._ensureInit(); + if (!this._inited) return; + var opt = option || {}; + // åªåŠ è½½å°šæœªè¯·æ±‚è¿‡çš„èµ„æºï¼ˆé¢„加载过的会跳过) + if (!this._loadedPaths[jsonFile]) { + this._assetManager.loadText(jsonFile); + this._loadedPaths[jsonFile] = true; + } + if (!this._loadedPaths[atlasFile]) { + this._assetManager.loadTextureAtlas(atlasFile); + this._loadedPaths[atlasFile] = true; + } + this._entries[id] = { + jsonFile: jsonFile, + atlasFile: atlasFile, + skeleton: null, + state: null, + x: opt.x || 0, + y: opt.y || 0, + scale: opt.scale || 1, + skin: opt.skin || "default", + defAnim: opt.animation || null, + defLoop: opt.loop !== undefined ? opt.loop : true, + mixDur: opt.mixDuration || 0.2, + visible: true, + ready: false, + _hideOnComplete: false, // 播放完æˆåŽæ˜¯å¦è‡ªåЍéšè— + _hideAfterCompletes: 0 // 剩余多少次 complete åŽè§¦å‘éšè— + }; + }, + + // ---------------------------------------------------------- + // (内部) 资æºåŠ è½½å®ŒæˆåŽå®žä¾‹åŒ–骨骼 + // ---------------------------------------------------------- + _buildEntry: function(entry) { + var atlas = this._assetManager.require(entry.atlasFile); + var loader = new spine.AtlasAttachmentLoader(atlas); + var skelJson = new spine.SkeletonJson(loader); + skelJson.scale = entry.scale; + + var skelData = skelJson.readSkeletonData( + this._assetManager.require(entry.jsonFile) + ); + entry.skeleton = new spine.Skeleton(skelData); + + // 设置皮肤 + if (entry.skin && entry.skin !== "default") { + entry.skeleton.setSkinByName(entry.skin); + } + entry.skeleton.setToSetupPose(); + + // AnimationState + var stateData = new spine.AnimationStateData(skelData); + stateData.defaultMix = entry.mixDur; + entry.state = new spine.AnimationState(stateData); + + // 绑定事件回调 —— 转å‘到 Spine_Event.js + entry.state.addListener({ + complete: function(trackEntry) { + // 自动éšè—:playOnce / playQueue 设置的计数器 + if (entry._hideOnComplete && !trackEntry.loop) { + entry._hideAfterCompletes--; + if (entry._hideAfterCompletes <= 0) { + entry.visible = false; + entry._hideOnComplete = false; + } + } + if (gameabc_face.spine_onComplete) { + gameabc_face.spine_onComplete(entry._id, trackEntry.animation.name, trackEntry.trackIndex); + } + }, + event: function(trackEntry, event) { + if (gameabc_face.spine_onEvent) { + gameabc_face.spine_onEvent(entry._id, event.data.name, event.intValue, event.floatValue, event.stringValue); + } + } + }); + + // 默认动画 + if (entry.defAnim) { + entry.state.setAnimation(0, entry.defAnim, entry.defLoop); + } + entry.ready = true; + }, + + // ---------------------------------------------------------- + // (内部) æ¯å¸§è°ƒç”¨ï¼šç¡®ä¿æ‰€æœ‰èµ„æºå°±ç»ª + // ---------------------------------------------------------- + _tryBuild: function() { + if (!this._assetManager.isLoadingComplete()) return false; + for (var id in this._entries) { + var e = this._entries[id]; + if (!e.ready) { + e._id = id; + try { + this._buildEntry(e); + logmessage("[SpineMgr] " + id + " 构建完æˆ"); + this._flushCmds(id); + } catch(err) { + logmessage("[SpineMgr] " + id + " 构建失败: " + err.message); + e.ready = false; + } + } + } + return true; + }, + + // ---------------------------------------------------------- + // updateAndDraw(ctx) æ¯å¸§è‡ªåŠ¨è°ƒç”¨ + // ctx: gameabc_face.dc (Canvas 2D Context) + // ---------------------------------------------------------- + updateAndDraw: function(ctx) { + if (!this._inited) return; + this._tryBuild(); + + var now = Date.now(); + var dt = (now - this._lastTime) / 1000; + this._lastTime = now; + if (dt <= 0 || dt > 0.5) dt = 1/30; + + if (!this._renderer) { + this._renderer = new spine.SkeletonRenderer(ctx); + this._renderer.triangleRendering = true; // ★ å¯ç”¨ä¸‰è§’å½¢æ¸²æŸ“ä»¥æ”¯æŒ Mesh 网格附件 + } + // ç¡®ä¿ renderer ç”¨çš„æ˜¯å½“å‰ ctx (gameabcå¯èƒ½é‡å»º) + this._renderer.ctx = ctx; + + for (var id in this._entries) { + var e = this._entries[id]; + if (!e.ready || !e.visible) continue; + + e.state.update(dt); + e.state.apply(e.skeleton); + // 骨骼ä½ç½®å½’零,由 ctx.translate 控制实际ä½ç½® + e.skeleton.x = 0; + e.skeleton.y = 0; + e.skeleton.updateWorldTransform(spine.Physics.update); + + ctx.save(); + ctx.translate(e.x, e.y); + ctx.scale(1, -1); // ★ Spine Y-up → Canvas Y-down + this._renderer.draw(e.skeleton); + ctx.restore(); + } + }, + + // ========================================================== + // 公开控制 API + // ========================================================== + + setAnimation: function(id, animName, loop, track) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setAnimation", [animName, loop, track]); + return null; + } + if (!e.ready) { + this._queueCmd(id, "setAnimation", [animName, loop, track]); + return null; + } + return e.state.setAnimation(track || 0, animName, loop !== false); + }, + + addAnimation: function(id, animName, loop, delay, track) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "addAnimation", [animName, loop, delay, track]); + return null; + } + if (!e.ready) { + this._queueCmd(id, "addAnimation", [animName, loop, delay, track]); + return null; + } + return e.state.addAnimation(track || 0, animName, loop !== false, delay || 0); + }, + + setPosition: function(id, x, y) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + e = this._entries[id]; + } + e.x = x; e.y = y; + }, + + setScale: function(id, sx, sy) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setScale", [sx, sy]); + return; + } + if (!e.skeleton) { + this._queueCmd(id, "setScale", [sx, sy]); + return; + } + e.skeleton.scaleX = sx; + e.skeleton.scaleY = sy !== undefined ? sy : sx; + }, + + setFlip: function(id, flipX, flipY) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setFlip", [flipX, flipY]); + return; + } + if (!e.skeleton) { + this._queueCmd(id, "setFlip", [flipX, flipY]); + return; + } + e.skeleton.scaleX = Math.abs(e.skeleton.scaleX) * (flipX ? -1 : 1); + e.skeleton.scaleY = Math.abs(e.skeleton.scaleY) * (flipY ? -1 : 1); + }, + + setVisible: function(id, visible) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + e = this._entries[id]; + } + e.visible = !!visible; + }, + + setSkin: function(id, skinName) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setSkin", [skinName]); + return; + } + if (!e.ready) { + this._queueCmd(id, "setSkin", [skinName]); + return; + } + e.skeleton.setSkinByName(skinName); + e.skeleton.setSlotsToSetupPose(); + }, + + getAnimations: function(id) { + var e = this._entries[id]; + if (!e) { this._autoLoad(id); return []; } + if (!e.ready) return []; + var anims = e.skeleton.data.animations; + var names = []; + for (var i = 0; i < anims.length; i++) names.push(anims[i].name); + return names; + }, + + getSkins: function(id) { + var e = this._entries[id]; + if (!e) { this._autoLoad(id); return []; } + if (!e.ready) return []; + var skins = e.skeleton.data.skins; + var names = []; + for (var i = 0; i < skins.length; i++) names.push(skins[i].name); + return names; + }, + + playOnce: function(id, animName, track) { + this.setVisible(id, true); + this.setAnimation(id, animName, false, track); + var e = this._entries[id]; + if (e) { + e._hideOnComplete = true; + e._hideAfterCompletes = 1; + } + }, + + playQueue: function(id, animList, hideOnComplete) { + if (!animList || animList.length === 0) return; + this.setVisible(id, true); + this.setAnimation(id, animList[0], false, 0); + for (var i = 1; i < animList.length; i++) { + this.addAnimation(id, animList[i], false, 0, 0); + } + var e = this._entries[id]; + if (e) { + e._hideOnComplete = hideOnComplete !== false; + e._hideAfterCompletes = animList.length; + } + }, + + remove: function(id) { + delete this._entries[id]; + }, + + removeAll: function() { + this._entries = {}; + } +}; + +// 挂载到 gameabc_face 上 +gameabc_face.spineMgr = SpineMgr; + +// ★ è‡ªåŠ¨é¢„åŠ è½½ï¼šè¯»å– gameabc_face.spineAssets 清å•,在引擎å¯åЍå‰é¢„加载所有 Spine èµ„æº +// 如果存在 spineTextData(嵌入文本数æ®ï¼‰ï¼Œåˆ™é€šè¿‡ setRawDataURI 注入, +// 彻底é¿å… file:// å议下 XHR CORS 拦截问题 +if (gameabc_face.spineAssets && gameabc_face.spineAssets.length > 0) { + SpineMgr._ensureInit(); + var list = gameabc_face.spineAssets; + var textData = gameabc_face.spineTextData || {}; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + var jsonKey = name + ".json"; + var atlasKey = name + ".atlas"; + // å°†åµŒå…¥æ–‡æœ¬æ•°æ®æ³¨å†Œä¸º rawDataURI,Spine Downloader ä¼šä¼˜å…ˆä»Žå†…å­˜è¯»å– + if (textData[jsonKey]) { + SpineMgr._assetManager.setRawDataURI(jsonKey, "data:," + textData[jsonKey]); + } + if (textData[atlasKey]) { + SpineMgr._assetManager.setRawDataURI(atlasKey, "data:," + textData[atlasKey]); + } + SpineMgr._assetManager.loadText(jsonKey); + SpineMgr._loadedPaths[jsonKey] = true; + SpineMgr._assetManager.loadTextureAtlas(atlasKey); + SpineMgr._loadedPaths[atlasKey] = true; + } + logmessage("[SpineMgr] 预加载 " + list.length + " 组 Spine 资æº" + + (Object.keys(textData).length > 0 ? "(使用嵌入数æ®ï¼‰" : "(使用网络请求)")); +} + +// ★ 用 defineProperty 拦截 gameenddraw 赋值 +// 无论 gamemain.js 或其他代ç å¦‚何定义 gameenddraw, +// Spine æ¸²æŸ“éƒ½ä¼šè‡ªåŠ¨è¿½åŠ åœ¨ç”¨æˆ·é€»è¾‘ä¹‹åŽ +var _userEndDraw = gameabc_face.gameenddraw || null; +var _wrappedEndDraw = function(gameid, spid, times, timelong) { + if (typeof _userEndDraw === "function") { + _userEndDraw(gameid, spid, times, timelong); + } + var ctx = gameabc_face.dc; + if (ctx && SpineMgr._inited) { + SpineMgr.updateAndDraw(ctx); + } +}; +Object.defineProperty(gameabc_face, "gameenddraw", { + configurable: true, + get: function() { return _wrappedEndDraw; }, + set: function(fn) { _userEndDraw = fn; } +}); + +})(); diff --git a/codes/games/client/Projects/Game_Surface_3/js/spine-canvas.js b/codes/games/client/Projects/Game_Surface_3/js/spine-canvas.js new file mode 100644 index 0000000..8690e14 --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/js/spine-canvas.js @@ -0,0 +1,11710 @@ +"use strict"; +var spine = (() => { + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + + // spine-canvas/src/index.ts + var index_exports = {}; + __export(index_exports, { + AlphaTimeline: () => AlphaTimeline, + Animation: () => Animation, + AnimationState: () => AnimationState, + AnimationStateAdapter: () => AnimationStateAdapter, + AnimationStateData: () => AnimationStateData, + AssetCache: () => AssetCache, + AssetManager: () => AssetManager, + AssetManagerBase: () => AssetManagerBase, + AtlasAttachmentLoader: () => AtlasAttachmentLoader, + Attachment: () => Attachment, + AttachmentTimeline: () => AttachmentTimeline, + BinaryInput: () => BinaryInput, + BlendMode: () => BlendMode, + Bone: () => Bone, + BoneData: () => BoneData, + BoundingBoxAttachment: () => BoundingBoxAttachment, + CURRENT: () => CURRENT, + CanvasTexture: () => CanvasTexture, + ClippingAttachment: () => ClippingAttachment, + Color: () => Color, + ConstraintData: () => ConstraintData, + CurveTimeline: () => CurveTimeline, + CurveTimeline1: () => CurveTimeline1, + CurveTimeline2: () => CurveTimeline2, + DebugUtils: () => DebugUtils, + DeformTimeline: () => DeformTimeline, + Downloader: () => Downloader, + DrawOrderTimeline: () => DrawOrderTimeline, + Event: () => Event, + EventData: () => EventData, + EventQueue: () => EventQueue, + EventTimeline: () => EventTimeline, + EventType: () => EventType, + FIRST: () => FIRST, + FakeTexture: () => FakeTexture, + HOLD_FIRST: () => HOLD_FIRST, + HOLD_MIX: () => HOLD_MIX, + HOLD_SUBSEQUENT: () => HOLD_SUBSEQUENT, + IkConstraint: () => IkConstraint, + IkConstraintData: () => IkConstraintData, + IkConstraintTimeline: () => IkConstraintTimeline, + Inherit: () => Inherit, + InheritTimeline: () => InheritTimeline, + IntSet: () => IntSet, + Interpolation: () => Interpolation, + MathUtils: () => MathUtils, + MeshAttachment: () => MeshAttachment, + MixBlend: () => MixBlend, + MixDirection: () => MixDirection, + PathAttachment: () => PathAttachment, + PathConstraint: () => PathConstraint, + PathConstraintData: () => PathConstraintData, + PathConstraintMixTimeline: () => PathConstraintMixTimeline, + PathConstraintPositionTimeline: () => PathConstraintPositionTimeline, + PathConstraintSpacingTimeline: () => PathConstraintSpacingTimeline, + Physics: () => Physics, + PhysicsConstraintDampingTimeline: () => PhysicsConstraintDampingTimeline, + PhysicsConstraintGravityTimeline: () => PhysicsConstraintGravityTimeline, + PhysicsConstraintInertiaTimeline: () => PhysicsConstraintInertiaTimeline, + PhysicsConstraintMassTimeline: () => PhysicsConstraintMassTimeline, + PhysicsConstraintMixTimeline: () => PhysicsConstraintMixTimeline, + PhysicsConstraintResetTimeline: () => PhysicsConstraintResetTimeline, + PhysicsConstraintStrengthTimeline: () => PhysicsConstraintStrengthTimeline, + PhysicsConstraintTimeline: () => PhysicsConstraintTimeline, + PhysicsConstraintWindTimeline: () => PhysicsConstraintWindTimeline, + PointAttachment: () => PointAttachment, + Pool: () => Pool, + PositionMode: () => PositionMode, + Pow: () => Pow, + PowOut: () => PowOut, + RGB2Timeline: () => RGB2Timeline, + RGBA2Timeline: () => RGBA2Timeline, + RGBATimeline: () => RGBATimeline, + RGBTimeline: () => RGBTimeline, + RegionAttachment: () => RegionAttachment, + RotateMode: () => RotateMode, + RotateTimeline: () => RotateTimeline, + SETUP: () => SETUP, + SUBSEQUENT: () => SUBSEQUENT, + ScaleTimeline: () => ScaleTimeline, + ScaleXTimeline: () => ScaleXTimeline, + ScaleYTimeline: () => ScaleYTimeline, + SequenceTimeline: () => SequenceTimeline, + ShearTimeline: () => ShearTimeline, + ShearXTimeline: () => ShearXTimeline, + ShearYTimeline: () => ShearYTimeline, + Skeleton: () => Skeleton, + SkeletonBinary: () => SkeletonBinary, + SkeletonBounds: () => SkeletonBounds, + SkeletonClipping: () => SkeletonClipping, + SkeletonData: () => SkeletonData, + SkeletonJson: () => SkeletonJson, + SkeletonRenderer: () => SkeletonRenderer, + Skin: () => Skin, + SkinEntry: () => SkinEntry, + Slot: () => Slot, + SlotData: () => SlotData, + SpacingMode: () => SpacingMode, + StringSet: () => StringSet, + Texture: () => Texture, + TextureAtlas: () => TextureAtlas, + TextureAtlasPage: () => TextureAtlasPage, + TextureAtlasRegion: () => TextureAtlasRegion, + TextureFilter: () => TextureFilter, + TextureRegion: () => TextureRegion, + TextureWrap: () => TextureWrap, + TimeKeeper: () => TimeKeeper, + Timeline: () => Timeline, + TrackEntry: () => TrackEntry, + TransformConstraint: () => TransformConstraint, + TransformConstraintData: () => TransformConstraintData, + TransformConstraintTimeline: () => TransformConstraintTimeline, + TranslateTimeline: () => TranslateTimeline, + TranslateXTimeline: () => TranslateXTimeline, + TranslateYTimeline: () => TranslateYTimeline, + Triangulator: () => Triangulator, + Utils: () => Utils, + Vector2: () => Vector2, + VertexAttachment: () => VertexAttachment, + WindowedMean: () => WindowedMean + }); + + // spine-core/src/Utils.ts + var IntSet = class { + array = new Array(); + add(value) { + let contains = this.contains(value); + this.array[value | 0] = value | 0; + return !contains; + } + contains(value) { + return this.array[value | 0] != void 0; + } + remove(value) { + this.array[value | 0] = void 0; + } + clear() { + this.array.length = 0; + } + }; + var StringSet = class { + entries = {}; + size = 0; + add(value) { + let contains = this.entries[value]; + this.entries[value] = true; + if (!contains) { + this.size++; + return true; + } + return false; + } + addAll(values) { + let oldSize = this.size; + for (var i = 0, n = values.length; i < n; i++) + this.add(values[i]); + return oldSize != this.size; + } + contains(value) { + return this.entries[value]; + } + clear() { + this.entries = {}; + this.size = 0; + } + }; + var Color = class _Color { + constructor(r = 0, g = 0, b = 0, a = 0) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + static WHITE = new _Color(1, 1, 1, 1); + static RED = new _Color(1, 0, 0, 1); + static GREEN = new _Color(0, 1, 0, 1); + static BLUE = new _Color(0, 0, 1, 1); + static MAGENTA = new _Color(1, 0, 1, 1); + set(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + return this.clamp(); + } + setFromColor(c) { + this.r = c.r; + this.g = c.g; + this.b = c.b; + this.a = c.a; + return this; + } + setFromString(hex) { + hex = hex.charAt(0) == "#" ? hex.substr(1) : hex; + this.r = parseInt(hex.substr(0, 2), 16) / 255; + this.g = parseInt(hex.substr(2, 2), 16) / 255; + this.b = parseInt(hex.substr(4, 2), 16) / 255; + this.a = hex.length != 8 ? 1 : parseInt(hex.substr(6, 2), 16) / 255; + return this; + } + add(r, g, b, a) { + this.r += r; + this.g += g; + this.b += b; + this.a += a; + return this.clamp(); + } + clamp() { + if (this.r < 0) this.r = 0; + else if (this.r > 1) this.r = 1; + if (this.g < 0) this.g = 0; + else if (this.g > 1) this.g = 1; + if (this.b < 0) this.b = 0; + else if (this.b > 1) this.b = 1; + if (this.a < 0) this.a = 0; + else if (this.a > 1) this.a = 1; + return this; + } + static rgba8888ToColor(color, value) { + color.r = ((value & 4278190080) >>> 24) / 255; + color.g = ((value & 16711680) >>> 16) / 255; + color.b = ((value & 65280) >>> 8) / 255; + color.a = (value & 255) / 255; + } + static rgb888ToColor(color, value) { + color.r = ((value & 16711680) >>> 16) / 255; + color.g = ((value & 65280) >>> 8) / 255; + color.b = (value & 255) / 255; + } + toRgb888() { + const hex = (x) => ("0" + (x * 255).toString(16)).slice(-2); + return Number("0x" + hex(this.r) + hex(this.g) + hex(this.b)); + } + static fromString(hex, color = new _Color()) { + return color.setFromString(hex); + } + }; + var MathUtils = class _MathUtils { + static PI = 3.1415927; + static PI2 = _MathUtils.PI * 2; + static invPI2 = 1 / _MathUtils.PI2; + static radiansToDegrees = 180 / _MathUtils.PI; + static radDeg = _MathUtils.radiansToDegrees; + static degreesToRadians = _MathUtils.PI / 180; + static degRad = _MathUtils.degreesToRadians; + static clamp(value, min, max) { + if (value < min) return min; + if (value > max) return max; + return value; + } + static cosDeg(degrees) { + return Math.cos(degrees * _MathUtils.degRad); + } + static sinDeg(degrees) { + return Math.sin(degrees * _MathUtils.degRad); + } + static atan2Deg(y, x) { + return Math.atan2(y, x) * _MathUtils.degRad; + } + static signum(value) { + return value > 0 ? 1 : value < 0 ? -1 : 0; + } + static toInt(x) { + return x > 0 ? Math.floor(x) : Math.ceil(x); + } + static cbrt(x) { + let y = Math.pow(Math.abs(x), 1 / 3); + return x < 0 ? -y : y; + } + static randomTriangular(min, max) { + return _MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); + } + static randomTriangularWith(min, max, mode) { + let u = Math.random(); + let d = max - min; + if (u <= (mode - min) / d) return min + Math.sqrt(u * d * (mode - min)); + return max - Math.sqrt((1 - u) * d * (max - mode)); + } + static isPowerOfTwo(value) { + return value && (value & value - 1) === 0; + } + }; + var Interpolation = class { + apply(start, end, a) { + return start + (end - start) * this.applyInternal(a); + } + }; + var Pow = class extends Interpolation { + power = 2; + constructor(power) { + super(); + this.power = power; + } + applyInternal(a) { + if (a <= 0.5) return Math.pow(a * 2, this.power) / 2; + return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; + } + }; + var PowOut = class extends Pow { + constructor(power) { + super(power); + } + applyInternal(a) { + return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; + } + }; + var Utils = class _Utils { + static SUPPORTS_TYPED_ARRAYS = typeof Float32Array !== "undefined"; + static arrayCopy(source, sourceStart, dest, destStart, numElements) { + for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { + dest[j] = source[i]; + } + } + static arrayFill(array, fromIndex, toIndex, value) { + for (let i = fromIndex; i < toIndex; i++) + array[i] = value; + } + static setArraySize(array, size, value = 0) { + let oldSize = array.length; + if (oldSize == size) return array; + array.length = size; + if (oldSize < size) { + for (let i = oldSize; i < size; i++) array[i] = value; + } + return array; + } + static ensureArrayCapacity(array, size, value = 0) { + if (array.length >= size) return array; + return _Utils.setArraySize(array, size, value); + } + static newArray(size, defaultValue) { + let array = new Array(size); + for (let i = 0; i < size; i++) array[i] = defaultValue; + return array; + } + static newFloatArray(size) { + if (_Utils.SUPPORTS_TYPED_ARRAYS) + return new Float32Array(size); + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) array[i] = 0; + return array; + } + } + static newShortArray(size) { + if (_Utils.SUPPORTS_TYPED_ARRAYS) + return new Int16Array(size); + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) array[i] = 0; + return array; + } + } + static toFloatArray(array) { + return _Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; + } + static toSinglePrecision(value) { + return _Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value; + } + // This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + static webkit602BugfixHelper(alpha, blend) { + } + static contains(array, element, identity = true) { + for (var i = 0; i < array.length; i++) + if (array[i] == element) return true; + return false; + } + static enumValue(type, name) { + return type[name[0].toUpperCase() + name.slice(1)]; + } + }; + var DebugUtils = class { + static logBones(skeleton) { + for (let i = 0; i < skeleton.bones.length; i++) { + let bone = skeleton.bones[i]; + console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY); + } + } + }; + var Pool = class { + items = new Array(); + instantiator; + constructor(instantiator) { + this.instantiator = instantiator; + } + obtain() { + return this.items.length > 0 ? this.items.pop() : this.instantiator(); + } + free(item) { + if (item.reset) item.reset(); + this.items.push(item); + } + freeAll(items) { + for (let i = 0; i < items.length; i++) + this.free(items[i]); + } + clear() { + this.items.length = 0; + } + }; + var Vector2 = class { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + set(x, y) { + this.x = x; + this.y = y; + return this; + } + length() { + let x = this.x; + let y = this.y; + return Math.sqrt(x * x + y * y); + } + normalize() { + let len = this.length(); + if (len != 0) { + this.x /= len; + this.y /= len; + } + return this; + } + }; + var TimeKeeper = class { + maxDelta = 0.064; + framesPerSecond = 0; + delta = 0; + totalTime = 0; + lastTime = Date.now() / 1e3; + frameCount = 0; + frameTime = 0; + update() { + let now = Date.now() / 1e3; + this.delta = now - this.lastTime; + this.frameTime += this.delta; + this.totalTime += this.delta; + if (this.delta > this.maxDelta) this.delta = this.maxDelta; + this.lastTime = now; + this.frameCount++; + if (this.frameTime > 1) { + this.framesPerSecond = this.frameCount / this.frameTime; + this.frameTime = 0; + this.frameCount = 0; + } + } + }; + var WindowedMean = class { + values; + addedValues = 0; + lastValue = 0; + mean = 0; + dirty = true; + constructor(windowSize = 32) { + this.values = new Array(windowSize); + } + hasEnoughData() { + return this.addedValues >= this.values.length; + } + addValue(value) { + if (this.addedValues < this.values.length) this.addedValues++; + this.values[this.lastValue++] = value; + if (this.lastValue > this.values.length - 1) this.lastValue = 0; + this.dirty = true; + } + getMean() { + if (this.hasEnoughData()) { + if (this.dirty) { + let mean = 0; + for (let i = 0; i < this.values.length; i++) + mean += this.values[i]; + this.mean = mean / this.values.length; + this.dirty = false; + } + return this.mean; + } + return 0; + } + }; + + // spine-core/src/attachments/Attachment.ts + var Attachment = class { + name; + constructor(name) { + if (!name) throw new Error("name cannot be null."); + this.name = name; + } + }; + var VertexAttachment = class _VertexAttachment extends Attachment { + static nextID = 0; + /** The unique ID for this attachment. */ + id = _VertexAttachment.nextID++; + /** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting + * the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#bones}. Will be null + * if this attachment has no weights. */ + bones = null; + /** The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are `x,y` + * entries for each vertex. For a weighted attachment, the values are `x,y,weight` entries for each bone affecting + * each vertex. */ + vertices = []; + /** The maximum number of world vertex values that can be output by + * {@link #computeWorldVertices()} using the `count` parameter. */ + worldVerticesLength = 0; + /** Timelines for the timeline attachment are also applied to this attachment. + * May be null if no attachment-specific timelines should be applied. */ + timelineAttachment = this; + constructor(name) { + super(name); + } + /** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} is + * not empty, it is used to deform the vertices. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. + * @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y. + * @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`. + * @param worldVertices The output world vertices. Must have a length >= `offset` + `count` * + * `stride` / 2. + * @param offset The `worldVertices` index to begin writing values. + * @param stride The number of `worldVertices` entries between the value pairs written. */ + computeWorldVertices(slot, start, count, worldVertices2, offset, stride) { + count = offset + (count >> 1) * stride; + let skeleton = slot.bone.skeleton; + let deformArray = slot.deform; + let vertices = this.vertices; + let bones = this.bones; + if (!bones) { + if (deformArray.length > 0) vertices = deformArray; + let bone = slot.bone; + let x = bone.worldX; + let y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + for (let v2 = start, w = offset; w < count; v2 += 2, w += stride) { + let vx = vertices[v2], vy = vertices[v2 + 1]; + worldVertices2[w] = vx * a + vy * b + x; + worldVertices2[w + 1] = vx * c + vy * d + y; + } + return; + } + let v = 0, skip = 0; + for (let i = 0; i < start; i += 2) { + let n = bones[v]; + v += n + 1; + skip += n; + } + let skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (let w = offset, b = skip * 3; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices2[w] = wx; + worldVertices2[w + 1] = wy; + } + } else { + let deform = deformArray; + for (let w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices2[w] = wx; + worldVertices2[w + 1] = wy; + } + } + } + /** Does not copy id (generated) or name (set on construction). **/ + copyTo(attachment) { + if (this.bones) { + attachment.bones = new Array(this.bones.length); + Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); + } else + attachment.bones = null; + if (this.vertices) { + attachment.vertices = Utils.newFloatArray(this.vertices.length); + Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); + } + attachment.worldVerticesLength = this.worldVerticesLength; + attachment.timelineAttachment = this.timelineAttachment; + } + }; + + // spine-core/src/attachments/Sequence.ts + var Sequence = class _Sequence { + static _nextID = 0; + id = _Sequence.nextID(); + regions; + start = 0; + digits = 0; + /** The index of the region to show for the setup pose. */ + setupIndex = 0; + constructor(count) { + this.regions = new Array(count); + } + copy() { + let copy = new _Sequence(this.regions.length); + Utils.arrayCopy(this.regions, 0, copy.regions, 0, this.regions.length); + copy.start = this.start; + copy.digits = this.digits; + copy.setupIndex = this.setupIndex; + return copy; + } + apply(slot, attachment) { + let index = slot.sequenceIndex; + if (index == -1) index = this.setupIndex; + if (index >= this.regions.length) index = this.regions.length - 1; + let region = this.regions[index]; + if (attachment.region != region) { + attachment.region = region; + attachment.updateRegion(); + } + } + getPath(basePath, index) { + let result = basePath; + let frame = (this.start + index).toString(); + for (let i = this.digits - frame.length; i > 0; i--) + result += "0"; + result += frame; + return result; + } + static nextID() { + return _Sequence._nextID++; + } + }; + var SequenceMode = /* @__PURE__ */ ((SequenceMode2) => { + SequenceMode2[SequenceMode2["hold"] = 0] = "hold"; + SequenceMode2[SequenceMode2["once"] = 1] = "once"; + SequenceMode2[SequenceMode2["loop"] = 2] = "loop"; + SequenceMode2[SequenceMode2["pingpong"] = 3] = "pingpong"; + SequenceMode2[SequenceMode2["onceReverse"] = 4] = "onceReverse"; + SequenceMode2[SequenceMode2["loopReverse"] = 5] = "loopReverse"; + SequenceMode2[SequenceMode2["pingpongReverse"] = 6] = "pingpongReverse"; + return SequenceMode2; + })(SequenceMode || {}); + var SequenceModeValues = [ + 0 /* hold */, + 1 /* once */, + 2 /* loop */, + 3 /* pingpong */, + 4 /* onceReverse */, + 5 /* loopReverse */, + 6 /* pingpongReverse */ + ]; + + // spine-core/src/Animation.ts + var Animation = class { + /** The animation's name, which is unique across all animations in the skeleton. */ + name; + timelines = []; + timelineIds = new StringSet(); + /** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */ + duration; + constructor(name, timelines, duration) { + if (!name) throw new Error("name cannot be null."); + this.name = name; + this.setTimelines(timelines); + this.duration = duration; + } + setTimelines(timelines) { + if (!timelines) throw new Error("timelines cannot be null."); + this.timelines = timelines; + this.timelineIds.clear(); + for (var i = 0; i < timelines.length; i++) + this.timelineIds.addAll(timelines[i].getPropertyIds()); + } + hasTimeline(ids) { + for (let i = 0; i < ids.length; i++) + if (this.timelineIds.contains(ids[i])) return true; + return false; + } + /** Applies all the animation's timelines to the specified skeleton. + * + * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. + * @param loop If true, the animation repeats after {@link #getDuration()}. + * @param events May be null to ignore fired events. */ + apply(skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (!skeleton) throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) lastTime %= this.duration; + } + let timelines = this.timelines; + for (let i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + } + }; + var MixBlend = /* @__PURE__ */ ((MixBlend2) => { + MixBlend2[MixBlend2["setup"] = 0] = "setup"; + MixBlend2[MixBlend2["first"] = 1] = "first"; + MixBlend2[MixBlend2["replace"] = 2] = "replace"; + MixBlend2[MixBlend2["add"] = 3] = "add"; + return MixBlend2; + })(MixBlend || {}); + var MixDirection = /* @__PURE__ */ ((MixDirection2) => { + MixDirection2[MixDirection2["mixIn"] = 0] = "mixIn"; + MixDirection2[MixDirection2["mixOut"] = 1] = "mixOut"; + return MixDirection2; + })(MixDirection || {}); + var Property = { + rotate: 0, + x: 1, + y: 2, + scaleX: 3, + scaleY: 4, + shearX: 5, + shearY: 6, + inherit: 7, + rgb: 8, + alpha: 9, + rgb2: 10, + attachment: 11, + deform: 12, + event: 13, + drawOrder: 14, + ikConstraint: 15, + transformConstraint: 16, + pathConstraintPosition: 17, + pathConstraintSpacing: 18, + pathConstraintMix: 19, + physicsConstraintInertia: 20, + physicsConstraintStrength: 21, + physicsConstraintDamping: 22, + physicsConstraintMass: 23, + physicsConstraintWind: 24, + physicsConstraintGravity: 25, + physicsConstraintMix: 26, + physicsConstraintReset: 27, + sequence: 28 + }; + var Timeline = class { + propertyIds; + frames; + constructor(frameCount, propertyIds) { + this.propertyIds = propertyIds; + this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries()); + } + getPropertyIds() { + return this.propertyIds; + } + getFrameEntries() { + return 1; + } + getFrameCount() { + return this.frames.length / this.getFrameEntries(); + } + getDuration() { + return this.frames[this.frames.length - this.getFrameEntries()]; + } + static search1(frames, time) { + let n = frames.length; + for (let i = 1; i < n; i++) + if (frames[i] > time) return i - 1; + return n - 1; + } + static search(frames, time, step) { + let n = frames.length; + for (let i = step; i < n; i += step) + if (frames[i] > time) return i - step; + return n - step; + } + }; + var CurveTimeline = class extends Timeline { + curves; + // type, x, y, ... + constructor(frameCount, bezierCount, propertyIds) { + super(frameCount, propertyIds); + this.curves = Utils.newFloatArray( + frameCount + bezierCount * 18 + /*BEZIER_SIZE*/ + ); + this.curves[frameCount - 1] = 1; + } + /** Sets the specified key frame to linear interpolation. */ + setLinear(frame) { + this.curves[frame] = 0; + } + /** Sets the specified key frame to stepped interpolation. */ + setStepped(frame) { + this.curves[frame] = 1; + } + /** Shrinks the storage for Bezier curves, for use when bezierCount (specified in the constructor) was larger + * than the actual number of Bezier curves. */ + shrink(bezierCount) { + let size = this.getFrameCount() + bezierCount * 18; + if (this.curves.length > size) { + let newCurves = Utils.newFloatArray(size); + Utils.arrayCopy(this.curves, 0, newCurves, 0, size); + this.curves = newCurves; + } + } + /** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than + * one curve per frame. + * @param bezier The ordinal of this Bezier curve for this timeline, between 0 and bezierCount - 1 (specified + * in the constructor), inclusive. + * @param frame Between 0 and frameCount - 1, inclusive. + * @param value The index of the value for this frame that this curve is used for. + * @param time1 The time for the first key. + * @param value1 The value for the first key. + * @param cx1 The time for the first Bezier handle. + * @param cy1 The value for the first Bezier handle. + * @param cx2 The time of the second Bezier handle. + * @param cy2 The value for the second Bezier handle. + * @param time2 The time for the second key. + * @param value2 The value for the second key. */ + setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { + let curves = this.curves; + let i = this.getFrameCount() + bezier * 18; + if (value == 0) curves[frame] = 2 + i; + let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03; + let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 6e-3, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 6e-3; + let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667; + let x = time1 + dx, y = value1 + dy; + for (let n = i + 18; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dx += ddx; + dy += ddy; + ddx += dddx; + ddy += dddy; + x += dx; + y += dy; + } + } + /** Returns the Bezier interpolated value for the specified time. + * @param frameIndex The index into {@link #getFrames()} for the values of the frame before time. + * @param valueOffset The offset from frameIndex to the value this curve is used for. + * @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */ + getBezierValue(time, frameIndex, valueOffset, i) { + let curves = this.curves; + if (curves[i] > time) { + let x2 = this.frames[frameIndex], y2 = this.frames[frameIndex + valueOffset]; + return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2); + } + let n = i + 18; + for (i += 2; i < n; i += 2) { + if (curves[i] >= time) { + let x2 = curves[i - 2], y2 = curves[i - 1]; + return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2); + } + } + frameIndex += this.getFrameEntries(); + let x = curves[n - 2], y = curves[n - 1]; + return y + (time - x) / (this.frames[frameIndex] - x) * (this.frames[frameIndex + valueOffset] - y); + } + }; + var CurveTimeline1 = class extends CurveTimeline { + constructor(frameCount, bezierCount, propertyId) { + super(frameCount, bezierCount, [propertyId]); + } + getFrameEntries() { + return 2; + } + /** Sets the time and value for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + setFrame(frame, time, value) { + frame <<= 1; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*VALUE*/ + ] = value; + } + /** Returns the interpolated value for the specified time. */ + getCurveValue(time) { + let frames = this.frames; + let i = frames.length - 2; + for (let ii = 2; ii <= i; ii += 2) { + if (frames[ii] > time) { + i = ii - 2; + break; + } + } + let curveType = this.curves[i >> 1]; + switch (curveType) { + case 0: + let before = frames[i], value = frames[ + i + 1 + /*VALUE*/ + ]; + return value + (time - before) / (frames[ + i + 2 + /*ENTRIES*/ + ] - before) * (frames[ + i + 2 + 1 + /*VALUE*/ + ] - value); + case 1: + return frames[ + i + 1 + /*VALUE*/ + ]; + } + return this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + } + getRelativeValue(time, alpha, blend, current, setup) { + if (time < this.frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + let value = this.getCurveValue(time); + switch (blend) { + case 0 /* setup */: + return setup + value * alpha; + case 1 /* first */: + case 2 /* replace */: + value += setup - current; + } + return current + value * alpha; + } + getAbsoluteValue(time, alpha, blend, current, setup) { + if (time < this.frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + let value = this.getCurveValue(time); + if (blend == 0 /* setup */) return setup + (value - setup) * alpha; + return current + (value - current) * alpha; + } + getAbsoluteValue2(time, alpha, blend, current, setup, value) { + if (time < this.frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + if (blend == 0 /* setup */) return setup + (value - setup) * alpha; + return current + (value - current) * alpha; + } + getScaleValue(time, alpha, blend, direction, current, setup) { + const frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + let value = this.getCurveValue(time) * setup; + if (alpha == 1) { + if (blend == 3 /* add */) return current + value - setup; + return value; + } + if (direction == 1 /* mixOut */) { + switch (blend) { + case 0 /* setup */: + return setup + (Math.abs(value) * MathUtils.signum(setup) - setup) * alpha; + case 1 /* first */: + case 2 /* replace */: + return current + (Math.abs(value) * MathUtils.signum(current) - current) * alpha; + } + } else { + let s = 0; + switch (blend) { + case 0 /* setup */: + s = Math.abs(setup) * MathUtils.signum(value); + return s + (value - s) * alpha; + case 1 /* first */: + case 2 /* replace */: + s = Math.abs(current) * MathUtils.signum(value); + return s + (value - s) * alpha; + } + } + return current + (value - setup) * alpha; + } + }; + var CurveTimeline2 = class extends CurveTimeline { + /** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}. + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ + constructor(frameCount, bezierCount, propertyId1, propertyId2) { + super(frameCount, bezierCount, [propertyId1, propertyId2]); + } + getFrameEntries() { + return 3; + } + /** Sets the time and values for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + setFrame(frame, time, value1, value2) { + frame *= 3; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*VALUE1*/ + ] = value1; + this.frames[ + frame + 2 + /*VALUE2*/ + ] = value2; + } + }; + var RotateTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.rotate + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.rotation = this.getRelativeValue(time, alpha, blend, bone.rotation, bone.data.rotation); + } + }; + var TranslateTimeline = class extends CurveTimeline2 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super( + frameCount, + bezierCount, + Property.x + "|" + boneIndex, + Property.y + "|" + boneIndex + ); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case 1 /* first */: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + let x = 0, y = 0; + let i = Timeline.search( + frames, + time, + 3 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 3 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + let t = (time - before) / (frames[ + i + 3 + /*ENTRIES*/ + ] - before); + x += (frames[ + i + 3 + 1 + /*VALUE1*/ + ] - x) * t; + y += (frames[ + i + 3 + 2 + /*VALUE2*/ + ] - y) * t; + break; + case 1: + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + break; + default: + x = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + switch (blend) { + case 0 /* setup */: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case 3 /* add */: + bone.x += x * alpha; + bone.y += y * alpha; + } + } + }; + var TranslateXTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.x + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.x = this.getRelativeValue(time, alpha, blend, bone.x, bone.data.x); + } + }; + var TranslateYTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.y + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.y = this.getRelativeValue(time, alpha, blend, bone.y, bone.data.y); + } + }; + var ScaleTimeline = class extends CurveTimeline2 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super( + frameCount, + bezierCount, + Property.scaleX + "|" + boneIndex, + Property.scaleY + "|" + boneIndex + ); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case 1 /* first */: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + let x, y; + let i = Timeline.search( + frames, + time, + 3 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 3 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + let t = (time - before) / (frames[ + i + 3 + /*ENTRIES*/ + ] - before); + x += (frames[ + i + 3 + 1 + /*VALUE1*/ + ] - x) * t; + y += (frames[ + i + 3 + 2 + /*VALUE2*/ + ] - y) * t; + break; + case 1: + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + break; + default: + x = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + x *= bone.data.scaleX; + y *= bone.data.scaleY; + if (alpha == 1) { + if (blend == 3 /* add */) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } else { + bone.scaleX = x; + bone.scaleY = y; + } + } else { + let bx = 0, by = 0; + if (direction == 1 /* mixOut */) { + switch (blend) { + case 0 /* setup */: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case 3 /* add */: + bone.scaleX += (x - bone.data.scaleX) * alpha; + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } else { + switch (blend) { + case 0 /* setup */: + bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bx = Math.abs(bone.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case 3 /* add */: + bone.scaleX += (x - bone.data.scaleX) * alpha; + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } + } + } + }; + var ScaleXTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.scaleX + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.scaleX = this.getScaleValue(time, alpha, blend, direction, bone.scaleX, bone.data.scaleX); + } + }; + var ScaleYTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.scaleY + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.scaleY = this.getScaleValue(time, alpha, blend, direction, bone.scaleY, bone.data.scaleY); + } + }; + var ShearTimeline = class extends CurveTimeline2 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super( + frameCount, + bezierCount, + Property.shearX + "|" + boneIndex, + Property.shearY + "|" + boneIndex + ); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case 1 /* first */: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + let x = 0, y = 0; + let i = Timeline.search( + frames, + time, + 3 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 3 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + let t = (time - before) / (frames[ + i + 3 + /*ENTRIES*/ + ] - before); + x += (frames[ + i + 3 + 1 + /*VALUE1*/ + ] - x) * t; + y += (frames[ + i + 3 + 2 + /*VALUE2*/ + ] - y) * t; + break; + case 1: + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + break; + default: + x = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + switch (blend) { + case 0 /* setup */: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case 3 /* add */: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + } + }; + var ShearXTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.shearX + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.shearX = this.getRelativeValue(time, alpha, blend, bone.shearX, bone.data.shearX); + } + }; + var ShearYTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.shearY + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.shearY = this.getRelativeValue(time, alpha, blend, bone.shearY, bone.data.shearY); + } + }; + var InheritTimeline = class extends Timeline { + boneIndex = 0; + constructor(frameCount, boneIndex) { + super(frameCount, [Property.inherit + "|" + boneIndex]); + this.boneIndex = boneIndex; + } + getFrameEntries() { + return 2; + } + /** Sets the transform mode for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + setFrame(frame, time, inherit) { + frame *= 2; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*INHERIT*/ + ] = inherit; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) bone.inherit = bone.data.inherit; + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) bone.inherit = bone.data.inherit; + return; + } + bone.inherit = this.frames[ + Timeline.search( + frames, + time, + 2 + /*ENTRIES*/ + ) + 1 + /*INHERIT*/ + ]; + } + }; + var RGBATimeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.alpha + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 5; + } + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + setFrame(frame, time, r, g, b, a) { + frame *= 5; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + this.frames[ + frame + 4 + /*A*/ + ] = a; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let color = slot.color; + if (time < frames[0]) { + let setup = slot.data.color; + switch (blend) { + case 0 /* setup */: + color.setFromColor(setup); + return; + case 1 /* first */: + color.add( + (setup.r - color.r) * alpha, + (setup.g - color.g) * alpha, + (setup.b - color.b) * alpha, + (setup.a - color.a) * alpha + ); + } + return; + } + let r = 0, g = 0, b = 0, a = 0; + let i = Timeline.search( + frames, + time, + 5 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 5 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + let t = (time - before) / (frames[ + i + 5 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 5 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 5 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 5 + 3 + /*B*/ + ] - b) * t; + a += (frames[ + i + 5 + 4 + /*A*/ + ] - a) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + a = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) + color.set(r, g, b, a); + else { + if (blend == 0 /* setup */) color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + } + }; + var RGBTimeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 4; + } + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + setFrame(frame, time, r, g, b) { + frame <<= 2; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let color = slot.color; + if (time < frames[0]) { + let setup = slot.data.color; + switch (blend) { + case 0 /* setup */: + color.r = setup.r; + color.g = setup.g; + color.b = setup.b; + return; + case 1 /* first */: + color.r += (setup.r - color.r) * alpha; + color.g += (setup.g - color.g) * alpha; + color.b += (setup.b - color.b) * alpha; + } + return; + } + let r = 0, g = 0, b = 0; + let i = Timeline.search( + frames, + time, + 4 + /*ENTRIES*/ + ); + let curveType = this.curves[i >> 2]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + let t = (time - before) / (frames[ + i + 4 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 4 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 4 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 4 + 3 + /*B*/ + ] - b) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) { + color.r = r; + color.g = g; + color.b = b; + } else { + if (blend == 0 /* setup */) { + let setup = slot.data.color; + color.r = setup.r; + color.g = setup.g; + color.b = setup.b; + } + color.r += (r - color.r) * alpha; + color.g += (g - color.g) * alpha; + color.b += (b - color.b) * alpha; + } + } + }; + var AlphaTimeline = class extends CurveTimeline1 { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, Property.alpha + "|" + slotIndex); + this.slotIndex = slotIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let color = slot.color; + if (time < this.frames[0]) { + let setup = slot.data.color; + switch (blend) { + case 0 /* setup */: + color.a = setup.a; + return; + case 1 /* first */: + color.a += (setup.a - color.a) * alpha; + } + return; + } + let a = this.getCurveValue(time); + if (alpha == 1) + color.a = a; + else { + if (blend == 0 /* setup */) color.a = slot.data.color.a; + color.a += (a - color.a) * alpha; + } + } + }; + var RGBA2Timeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.alpha + "|" + slotIndex, + Property.rgb2 + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 8; + } + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + setFrame(frame, time, r, g, b, a, r2, g2, b2) { + frame <<= 3; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + this.frames[ + frame + 4 + /*A*/ + ] = a; + this.frames[ + frame + 5 + /*R2*/ + ] = r2; + this.frames[ + frame + 6 + /*G2*/ + ] = g2; + this.frames[ + frame + 7 + /*B2*/ + ] = b2; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let light = slot.color, dark = slot.darkColor; + if (time < frames[0]) { + let setupLight = slot.data.color, setupDark = slot.data.darkColor; + switch (blend) { + case 0 /* setup */: + light.setFromColor(setupLight); + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + return; + case 1 /* first */: + light.add( + (setupLight.r - light.r) * alpha, + (setupLight.g - light.g) * alpha, + (setupLight.b - light.b) * alpha, + (setupLight.a - light.a) * alpha + ); + dark.r += (setupDark.r - dark.r) * alpha; + dark.g += (setupDark.g - dark.g) * alpha; + dark.b += (setupDark.b - dark.b) * alpha; + } + return; + } + let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + let i = Timeline.search( + frames, + time, + 8 + /*ENTRIES*/ + ); + let curveType = this.curves[i >> 3]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + r2 = frames[ + i + 5 + /*R2*/ + ]; + g2 = frames[ + i + 6 + /*G2*/ + ]; + b2 = frames[ + i + 7 + /*B2*/ + ]; + let t = (time - before) / (frames[ + i + 8 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 8 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 8 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 8 + 3 + /*B*/ + ] - b) * t; + a += (frames[ + i + 8 + 4 + /*A*/ + ] - a) * t; + r2 += (frames[ + i + 8 + 5 + /*R2*/ + ] - r2) * t; + g2 += (frames[ + i + 8 + 6 + /*G2*/ + ] - g2) * t; + b2 += (frames[ + i + 8 + 7 + /*B2*/ + ] - b2) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + r2 = frames[ + i + 5 + /*R2*/ + ]; + g2 = frames[ + i + 6 + /*G2*/ + ]; + b2 = frames[ + i + 7 + /*B2*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + a = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + r2 = this.getBezierValue( + time, + i, + 5, + curveType + 18 * 4 - 2 + /*BEZIER*/ + ); + g2 = this.getBezierValue( + time, + i, + 6, + curveType + 18 * 5 - 2 + /*BEZIER*/ + ); + b2 = this.getBezierValue( + time, + i, + 7, + curveType + 18 * 6 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) { + light.set(r, g, b, a); + dark.r = r2; + dark.g = g2; + dark.b = b2; + } else { + if (blend == 0 /* setup */) { + light.setFromColor(slot.data.color); + let setupDark = slot.data.darkColor; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.r += (r2 - dark.r) * alpha; + dark.g += (g2 - dark.g) * alpha; + dark.b += (b2 - dark.b) * alpha; + } + } + }; + var RGB2Timeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.rgb2 + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 7; + } + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + setFrame(frame, time, r, g, b, r2, g2, b2) { + frame *= 7; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + this.frames[ + frame + 4 + /*R2*/ + ] = r2; + this.frames[ + frame + 5 + /*G2*/ + ] = g2; + this.frames[ + frame + 6 + /*B2*/ + ] = b2; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let light = slot.color, dark = slot.darkColor; + if (time < frames[0]) { + let setupLight = slot.data.color, setupDark = slot.data.darkColor; + switch (blend) { + case 0 /* setup */: + light.r = setupLight.r; + light.g = setupLight.g; + light.b = setupLight.b; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + return; + case 1 /* first */: + light.r += (setupLight.r - light.r) * alpha; + light.g += (setupLight.g - light.g) * alpha; + light.b += (setupLight.b - light.b) * alpha; + dark.r += (setupDark.r - dark.r) * alpha; + dark.g += (setupDark.g - dark.g) * alpha; + dark.b += (setupDark.b - dark.b) * alpha; + } + return; + } + let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + let i = Timeline.search( + frames, + time, + 7 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 7 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + r2 = frames[ + i + 4 + /*R2*/ + ]; + g2 = frames[ + i + 5 + /*G2*/ + ]; + b2 = frames[ + i + 6 + /*B2*/ + ]; + let t = (time - before) / (frames[ + i + 7 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 7 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 7 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 7 + 3 + /*B*/ + ] - b) * t; + r2 += (frames[ + i + 7 + 4 + /*R2*/ + ] - r2) * t; + g2 += (frames[ + i + 7 + 5 + /*G2*/ + ] - g2) * t; + b2 += (frames[ + i + 7 + 6 + /*B2*/ + ] - b2) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + r2 = frames[ + i + 4 + /*R2*/ + ]; + g2 = frames[ + i + 5 + /*G2*/ + ]; + b2 = frames[ + i + 6 + /*B2*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + r2 = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + g2 = this.getBezierValue( + time, + i, + 5, + curveType + 18 * 4 - 2 + /*BEZIER*/ + ); + b2 = this.getBezierValue( + time, + i, + 6, + curveType + 18 * 5 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) { + light.r = r; + light.g = g; + light.b = b; + dark.r = r2; + dark.g = g2; + dark.b = b2; + } else { + if (blend == 0 /* setup */) { + let setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.r = setupLight.r; + light.g = setupLight.g; + light.b = setupLight.b; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + } + light.r += (r - light.r) * alpha; + light.g += (g - light.g) * alpha; + light.b += (b - light.b) * alpha; + dark.r += (r2 - dark.r) * alpha; + dark.g += (g2 - dark.g) * alpha; + dark.b += (b2 - dark.b) * alpha; + } + } + }; + var AttachmentTimeline = class extends Timeline { + slotIndex = 0; + /** The attachment name for each key frame. May contain null values to clear the attachment. */ + attachmentNames; + constructor(frameCount, slotIndex) { + super(frameCount, [ + Property.attachment + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + this.attachmentNames = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the attachment name for the specified key frame. */ + setFrame(frame, time, attachmentName) { + this.frames[frame] = time; + this.attachmentNames[frame] = attachmentName; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + if (time < this.frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]); + } + setAttachment(skeleton, slot, attachmentName) { + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + } + }; + var DeformTimeline = class extends CurveTimeline { + slotIndex = 0; + /** The attachment that will be deformed. */ + attachment; + /** The vertices for each key frame. */ + vertices; + constructor(frameCount, bezierCount, slotIndex, attachment) { + super(frameCount, bezierCount, [ + Property.deform + "|" + slotIndex + "|" + attachment.id + ]); + this.slotIndex = slotIndex; + this.attachment = attachment; + this.vertices = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the vertices for the specified key frame. + * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ + setFrame(frame, time, vertices) { + this.frames[frame] = time; + this.vertices[frame] = vertices; + } + /** @param value1 Ignored (0 is used for a deform timeline). + * @param value2 Ignored (1 is used for a deform timeline). */ + setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { + let curves = this.curves; + let i = this.getFrameCount() + bezier * 18; + if (value == 0) curves[frame] = 2 + i; + let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06; + let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 6e-3, dddy = (cy1 - cy2 + 0.33333333) * 0.018; + let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = cy1 * 0.3 + tmpy + dddy * 0.16666667; + let x = time1 + dx, y = dy; + for (let n = i + 18; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dx += ddx; + dy += ddy; + ddx += dddx; + ddy += dddy; + x += dx; + y += dy; + } + } + getCurvePercent(time, frame) { + let curves = this.curves; + let i = curves[frame]; + switch (i) { + case 0: + let x2 = this.frames[frame]; + return (time - x2) / (this.frames[frame + this.getFrameEntries()] - x2); + case 1: + return 0; + } + i -= 2; + if (curves[i] > time) { + let x2 = this.frames[frame]; + return curves[i + 1] * (time - x2) / (curves[i] - x2); + } + let n = i + 18; + for (i += 2; i < n; i += 2) { + if (curves[i] >= time) { + let x2 = curves[i - 2], y2 = curves[i - 1]; + return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2); + } + } + let x = curves[n - 2], y = curves[n - 1]; + return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x); + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let slotAttachment = slot.getAttachment(); + if (!slotAttachment) return; + if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != this.attachment) return; + let deform = slot.deform; + if (deform.length == 0) blend = 0 /* setup */; + let vertices = this.vertices; + let vertexCount = vertices[0].length; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + deform.length = 0; + return; + case 1 /* first */: + if (alpha == 1) { + deform.length = 0; + return; + } + deform.length = vertexCount; + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + deform[i] += (setupVertices[i] - deform[i]) * alpha; + } else { + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + deform[i] *= alpha; + } + } + return; + } + deform.length = vertexCount; + if (time >= frames[frames.length - 1]) { + let lastVertices = vertices[frames.length - 1]; + if (alpha == 1) { + if (blend == 3 /* add */) { + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += lastVertices[i2] - setupVertices[i2]; + } else { + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += lastVertices[i2]; + } + } else + Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); + } else { + switch (blend) { + case 0 /* setup */: { + let vertexAttachment2 = slotAttachment; + if (!vertexAttachment2.bones) { + let setupVertices = vertexAttachment2.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let setup = setupVertices[i2]; + deform[i2] = setup + (lastVertices[i2] - setup) * alpha; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] = lastVertices[i2] * alpha; + } + break; + } + case 1 /* first */: + case 2 /* replace */: + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += (lastVertices[i2] - deform[i2]) * alpha; + break; + case 3 /* add */: + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += (lastVertices[i2] - setupVertices[i2]) * alpha; + } else { + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += lastVertices[i2] * alpha; + } + } + } + return; + } + let frame = Timeline.search1(frames, time); + let percent = this.getCurvePercent(time, frame); + let prevVertices = vertices[frame]; + let nextVertices = vertices[frame + 1]; + if (alpha == 1) { + if (blend == 3 /* add */) { + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += prev + (nextVertices[i2] - prev) * percent - setupVertices[i2]; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += prev + (nextVertices[i2] - prev) * percent; + } + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] = prev + (nextVertices[i2] - prev) * percent; + } + } + } else { + switch (blend) { + case 0 /* setup */: { + let vertexAttachment2 = slotAttachment; + if (!vertexAttachment2.bones) { + let setupVertices = vertexAttachment2.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2], setup = setupVertices[i2]; + deform[i2] = setup + (prev + (nextVertices[i2] - prev) * percent - setup) * alpha; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] = (prev + (nextVertices[i2] - prev) * percent) * alpha; + } + } + break; + } + case 1 /* first */: + case 2 /* replace */: + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += (prev + (nextVertices[i2] - prev) * percent - deform[i2]) * alpha; + } + break; + case 3 /* add */: + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += (prev + (nextVertices[i2] - prev) * percent - setupVertices[i2]) * alpha; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += (prev + (nextVertices[i2] - prev) * percent) * alpha; + } + } + } + } + } + }; + var EventTimeline = class _EventTimeline extends Timeline { + static propertyIds = ["" + Property.event]; + /** The event for each key frame. */ + events; + constructor(frameCount) { + super(frameCount, _EventTimeline.propertyIds); + this.events = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the event for the specified key frame. */ + setFrame(frame, event) { + this.frames[frame] = event.time; + this.events[frame] = event; + } + /** Fires events for frames > `lastTime` and <= `time`. */ + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (!firedEvents) return; + let frames = this.frames; + let frameCount = this.frames.length; + if (lastTime > time) { + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } else if (lastTime >= frames[frameCount - 1]) + return; + if (time < frames[0]) return; + let i = 0; + if (lastTime < frames[0]) + i = 0; + else { + i = Timeline.search1(frames, lastTime) + 1; + let frameTime = frames[i]; + while (i > 0) { + if (frames[i - 1] != frameTime) break; + i--; + } + } + for (; i < frameCount && time >= frames[i]; i++) + firedEvents.push(this.events[i]); + } + }; + var DrawOrderTimeline = class _DrawOrderTimeline extends Timeline { + static propertyIds = ["" + Property.drawOrder]; + /** The draw order for each key frame. See {@link #setFrame(int, float, int[])}. */ + drawOrders; + constructor(frameCount) { + super(frameCount, _DrawOrderTimeline.propertyIds); + this.drawOrders = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the draw order for the specified key frame. + * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose + * draw order. */ + setFrame(frame, time, drawOrder) { + this.frames[frame] = time; + this.drawOrders[frame] = drawOrder; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + if (time < this.frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + let idx = Timeline.search1(this.frames, time); + let drawOrderToSetupIndex = this.drawOrders[idx]; + if (!drawOrderToSetupIndex) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + else { + let drawOrder = skeleton.drawOrder; + let slots = skeleton.slots; + for (let i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + } + }; + var IkConstraintTimeline = class extends CurveTimeline { + /** The index of the IK constraint in {@link Skeleton#getIkConstraints()} that will be changed when this timeline is applied */ + constraintIndex = 0; + constructor(frameCount, bezierCount, ikConstraintIndex) { + super(frameCount, bezierCount, [ + Property.ikConstraint + "|" + ikConstraintIndex + ]); + this.constraintIndex = ikConstraintIndex; + } + getFrameEntries() { + return 6; + } + /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ + setFrame(frame, time, mix, softness, bendDirection, compress, stretch) { + frame *= 6; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*MIX*/ + ] = mix; + this.frames[ + frame + 2 + /*SOFTNESS*/ + ] = softness; + this.frames[ + frame + 3 + /*BEND_DIRECTION*/ + ] = bendDirection; + this.frames[ + frame + 4 + /*COMPRESS*/ + ] = compress ? 1 : 0; + this.frames[ + frame + 5 + /*STRETCH*/ + ] = stretch ? 1 : 0; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.ikConstraints[this.constraintIndex]; + if (!constraint.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case 1 /* first */: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.softness += (constraint.data.softness - constraint.softness) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + let mix = 0, softness = 0; + let i = Timeline.search( + frames, + time, + 6 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 6 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + mix = frames[ + i + 1 + /*MIX*/ + ]; + softness = frames[ + i + 2 + /*SOFTNESS*/ + ]; + let t = (time - before) / (frames[ + i + 6 + /*ENTRIES*/ + ] - before); + mix += (frames[ + i + 6 + 1 + /*MIX*/ + ] - mix) * t; + softness += (frames[ + i + 6 + 2 + /*SOFTNESS*/ + ] - softness) * t; + break; + case 1: + mix = frames[ + i + 1 + /*MIX*/ + ]; + softness = frames[ + i + 2 + /*SOFTNESS*/ + ]; + break; + default: + mix = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + softness = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + if (blend == 0 /* setup */) { + constraint.mix = constraint.data.mix + (mix - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + (softness - constraint.data.softness) * alpha; + if (direction == 1 /* mixOut */) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } else { + constraint.bendDirection = frames[ + i + 3 + /*BEND_DIRECTION*/ + ]; + constraint.compress = frames[ + i + 4 + /*COMPRESS*/ + ] != 0; + constraint.stretch = frames[ + i + 5 + /*STRETCH*/ + ] != 0; + } + } else { + constraint.mix += (mix - constraint.mix) * alpha; + constraint.softness += (softness - constraint.softness) * alpha; + if (direction == 0 /* mixIn */) { + constraint.bendDirection = frames[ + i + 3 + /*BEND_DIRECTION*/ + ]; + constraint.compress = frames[ + i + 4 + /*COMPRESS*/ + ] != 0; + constraint.stretch = frames[ + i + 5 + /*STRETCH*/ + ] != 0; + } + } + } + }; + var TransformConstraintTimeline = class extends CurveTimeline { + /** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, transformConstraintIndex) { + super(frameCount, bezierCount, [ + Property.transformConstraint + "|" + transformConstraintIndex + ]); + this.constraintIndex = transformConstraintIndex; + } + getFrameEntries() { + return 7; + } + /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ + setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY) { + let frames = this.frames; + frame *= 7; + frames[frame] = time; + frames[ + frame + 1 + /*ROTATE*/ + ] = mixRotate; + frames[ + frame + 2 + /*X*/ + ] = mixX; + frames[ + frame + 3 + /*Y*/ + ] = mixY; + frames[ + frame + 4 + /*SCALEX*/ + ] = mixScaleX; + frames[ + frame + 5 + /*SCALEY*/ + ] = mixScaleY; + frames[ + frame + 6 + /*SHEARY*/ + ] = mixShearY; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.transformConstraints[this.constraintIndex]; + if (!constraint.active) return; + let frames = this.frames; + if (time < frames[0]) { + let data = constraint.data; + switch (blend) { + case 0 /* setup */: + constraint.mixRotate = data.mixRotate; + constraint.mixX = data.mixX; + constraint.mixY = data.mixY; + constraint.mixScaleX = data.mixScaleX; + constraint.mixScaleY = data.mixScaleY; + constraint.mixShearY = data.mixShearY; + return; + case 1 /* first */: + constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (data.mixX - constraint.mixX) * alpha; + constraint.mixY += (data.mixY - constraint.mixY) * alpha; + constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha; + } + return; + } + let rotate, x, y, scaleX, scaleY, shearY; + let i = Timeline.search( + frames, + time, + 7 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 7 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + scaleX = frames[ + i + 4 + /*SCALEX*/ + ]; + scaleY = frames[ + i + 5 + /*SCALEY*/ + ]; + shearY = frames[ + i + 6 + /*SHEARY*/ + ]; + let t = (time - before) / (frames[ + i + 7 + /*ENTRIES*/ + ] - before); + rotate += (frames[ + i + 7 + 1 + /*ROTATE*/ + ] - rotate) * t; + x += (frames[ + i + 7 + 2 + /*X*/ + ] - x) * t; + y += (frames[ + i + 7 + 3 + /*Y*/ + ] - y) * t; + scaleX += (frames[ + i + 7 + 4 + /*SCALEX*/ + ] - scaleX) * t; + scaleY += (frames[ + i + 7 + 5 + /*SCALEY*/ + ] - scaleY) * t; + shearY += (frames[ + i + 7 + 6 + /*SHEARY*/ + ] - shearY) * t; + break; + case 1: + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + scaleX = frames[ + i + 4 + /*SCALEX*/ + ]; + scaleY = frames[ + i + 5 + /*SCALEY*/ + ]; + shearY = frames[ + i + 6 + /*SHEARY*/ + ]; + break; + default: + rotate = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + x = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + scaleX = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + scaleY = this.getBezierValue( + time, + i, + 5, + curveType + 18 * 4 - 2 + /*BEZIER*/ + ); + shearY = this.getBezierValue( + time, + i, + 6, + curveType + 18 * 5 - 2 + /*BEZIER*/ + ); + } + if (blend == 0 /* setup */) { + let data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha; + constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha; + constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha; + } else { + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (shearY - constraint.mixShearY) * alpha; + } + } + }; + var PathConstraintPositionTimeline = class extends CurveTimeline1 { + /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is + * applied. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, pathConstraintIndex) { + super(frameCount, bezierCount, Property.pathConstraintPosition + "|" + pathConstraintIndex); + this.constraintIndex = pathConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.pathConstraints[this.constraintIndex]; + if (constraint.active) + constraint.position = this.getAbsoluteValue(time, alpha, blend, constraint.position, constraint.data.position); + } + }; + var PathConstraintSpacingTimeline = class extends CurveTimeline1 { + /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is + * applied. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, pathConstraintIndex) { + super(frameCount, bezierCount, Property.pathConstraintSpacing + "|" + pathConstraintIndex); + this.constraintIndex = pathConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.pathConstraints[this.constraintIndex]; + if (constraint.active) + constraint.spacing = this.getAbsoluteValue(time, alpha, blend, constraint.spacing, constraint.data.spacing); + } + }; + var PathConstraintMixTimeline = class extends CurveTimeline { + /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is + * applied. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, pathConstraintIndex) { + super(frameCount, bezierCount, [ + Property.pathConstraintMix + "|" + pathConstraintIndex + ]); + this.constraintIndex = pathConstraintIndex; + } + getFrameEntries() { + return 4; + } + setFrame(frame, time, mixRotate, mixX, mixY) { + let frames = this.frames; + frame <<= 2; + frames[frame] = time; + frames[ + frame + 1 + /*ROTATE*/ + ] = mixRotate; + frames[ + frame + 2 + /*X*/ + ] = mixX; + frames[ + frame + 3 + /*Y*/ + ] = mixY; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.pathConstraints[this.constraintIndex]; + if (!constraint.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + constraint.mixRotate = constraint.data.mixRotate; + constraint.mixX = constraint.data.mixX; + constraint.mixY = constraint.data.mixY; + return; + case 1 /* first */: + constraint.mixRotate += (constraint.data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (constraint.data.mixX - constraint.mixX) * alpha; + constraint.mixY += (constraint.data.mixY - constraint.mixY) * alpha; + } + return; + } + let rotate, x, y; + let i = Timeline.search( + frames, + time, + 4 + /*ENTRIES*/ + ); + let curveType = this.curves[i >> 2]; + switch (curveType) { + case 0: + let before = frames[i]; + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + let t = (time - before) / (frames[ + i + 4 + /*ENTRIES*/ + ] - before); + rotate += (frames[ + i + 4 + 1 + /*ROTATE*/ + ] - rotate) * t; + x += (frames[ + i + 4 + 2 + /*X*/ + ] - x) * t; + y += (frames[ + i + 4 + 3 + /*Y*/ + ] - y) * t; + break; + case 1: + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + break; + default: + rotate = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + x = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + } + if (blend == 0 /* setup */) { + let data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + } else { + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + } + } + }; + var PhysicsConstraintTimeline = class extends CurveTimeline1 { + /** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be changed when this timeline + * is applied, or -1 if all physics constraints in the skeleton will be changed. */ + constraintIndex = 0; + /** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */ + constructor(frameCount, bezierCount, physicsConstraintIndex, property) { + super(frameCount, bezierCount, property + "|" + physicsConstraintIndex); + this.constraintIndex = physicsConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint; + if (this.constraintIndex == -1) { + const value = time >= this.frames[0] ? this.getCurveValue(time) : 0; + for (const constraint2 of skeleton.physicsConstraints) { + if (constraint2.active && this.global(constraint2.data)) + this.set(constraint2, this.getAbsoluteValue2(time, alpha, blend, this.get(constraint2), this.setup(constraint2), value)); + } + } else { + constraint = skeleton.physicsConstraints[this.constraintIndex]; + if (constraint.active) this.set(constraint, this.getAbsoluteValue(time, alpha, blend, this.get(constraint), this.setup(constraint))); + } + } + }; + var PhysicsConstraintInertiaTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia); + } + setup(constraint) { + return constraint.data.inertia; + } + get(constraint) { + return constraint.inertia; + } + set(constraint, value) { + constraint.inertia = value; + } + global(constraint) { + return constraint.inertiaGlobal; + } + }; + var PhysicsConstraintStrengthTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength); + } + setup(constraint) { + return constraint.data.strength; + } + get(constraint) { + return constraint.strength; + } + set(constraint, value) { + constraint.strength = value; + } + global(constraint) { + return constraint.strengthGlobal; + } + }; + var PhysicsConstraintDampingTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping); + } + setup(constraint) { + return constraint.data.damping; + } + get(constraint) { + return constraint.damping; + } + set(constraint, value) { + constraint.damping = value; + } + global(constraint) { + return constraint.dampingGlobal; + } + }; + var PhysicsConstraintMassTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass); + } + setup(constraint) { + return 1 / constraint.data.massInverse; + } + get(constraint) { + return 1 / constraint.massInverse; + } + set(constraint, value) { + constraint.massInverse = 1 / value; + } + global(constraint) { + return constraint.massGlobal; + } + }; + var PhysicsConstraintWindTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind); + } + setup(constraint) { + return constraint.data.wind; + } + get(constraint) { + return constraint.wind; + } + set(constraint, value) { + constraint.wind = value; + } + global(constraint) { + return constraint.windGlobal; + } + }; + var PhysicsConstraintGravityTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity); + } + setup(constraint) { + return constraint.data.gravity; + } + get(constraint) { + return constraint.gravity; + } + set(constraint, value) { + constraint.gravity = value; + } + global(constraint) { + return constraint.gravityGlobal; + } + }; + var PhysicsConstraintMixTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix); + } + setup(constraint) { + return constraint.data.mix; + } + get(constraint) { + return constraint.mix; + } + set(constraint, value) { + constraint.mix = value; + } + global(constraint) { + return constraint.mixGlobal; + } + }; + var PhysicsConstraintResetTimeline = class _PhysicsConstraintResetTimeline extends Timeline { + static propertyIds = [Property.physicsConstraintReset.toString()]; + /** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset when this timeline is + * applied, or -1 if all physics constraints in the skeleton will be reset. */ + constraintIndex; + /** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */ + constructor(frameCount, physicsConstraintIndex) { + super(frameCount, _PhysicsConstraintResetTimeline.propertyIds); + this.constraintIndex = physicsConstraintIndex; + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time for the specified frame. + * @param frame Between 0 and frameCount, inclusive. */ + setFrame(frame, time) { + this.frames[frame] = time; + } + /** Resets the physics constraint when frames > lastTime and <= time. */ + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint; + if (this.constraintIndex != -1) { + constraint = skeleton.physicsConstraints[this.constraintIndex]; + if (!constraint.active) return; + } + const frames = this.frames; + if (lastTime > time) { + this.apply(skeleton, lastTime, Number.MAX_VALUE, [], alpha, blend, direction); + lastTime = -1; + } else if (lastTime >= frames[frames.length - 1]) + return; + if (time < frames[0]) return; + if (lastTime < frames[0] || time >= frames[Timeline.search1(frames, lastTime) + 1]) { + if (constraint != null) + constraint.reset(); + else { + for (const constraint2 of skeleton.physicsConstraints) { + if (constraint2.active) constraint2.reset(); + } + } + } + } + }; + var SequenceTimeline = class _SequenceTimeline extends Timeline { + static ENTRIES = 3; + static MODE = 1; + static DELAY = 2; + slotIndex; + attachment; + constructor(frameCount, slotIndex, attachment) { + super(frameCount, [ + Property.sequence + "|" + slotIndex + "|" + attachment.sequence.id + ]); + this.slotIndex = slotIndex; + this.attachment = attachment; + } + getFrameEntries() { + return _SequenceTimeline.ENTRIES; + } + getSlotIndex() { + return this.slotIndex; + } + getAttachment() { + return this.attachment; + } + /** Sets the time, mode, index, and frame time for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time Seconds between frames. */ + setFrame(frame, time, mode, index, delay) { + let frames = this.frames; + frame *= _SequenceTimeline.ENTRIES; + frames[frame] = time; + frames[frame + _SequenceTimeline.MODE] = mode | index << 4; + frames[frame + _SequenceTimeline.DELAY] = delay; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let slotAttachment = slot.attachment; + let attachment = this.attachment; + if (slotAttachment != attachment) { + if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != attachment) return; + } + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) slot.sequenceIndex = -1; + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) slot.sequenceIndex = -1; + return; + } + let i = Timeline.search(frames, time, _SequenceTimeline.ENTRIES); + let before = frames[i]; + let modeAndIndex = frames[i + _SequenceTimeline.MODE]; + let delay = frames[i + _SequenceTimeline.DELAY]; + if (!this.attachment.sequence) return; + let index = modeAndIndex >> 4, count = this.attachment.sequence.regions.length; + let mode = SequenceModeValues[modeAndIndex & 15]; + if (mode != 0 /* hold */) { + index += (time - before) / delay + 1e-5 | 0; + switch (mode) { + case 1 /* once */: + index = Math.min(count - 1, index); + break; + case 2 /* loop */: + index %= count; + break; + case 3 /* pingpong */: { + let n = (count << 1) - 2; + index = n == 0 ? 0 : index % n; + if (index >= count) index = n - index; + break; + } + case 4 /* onceReverse */: + index = Math.max(count - 1 - index, 0); + break; + case 5 /* loopReverse */: + index = count - 1 - index % count; + break; + case 6 /* pingpongReverse */: { + let n = (count << 1) - 2; + index = n == 0 ? 0 : (index + count - 1) % n; + if (index >= count) index = n - index; + } + } + } + slot.sequenceIndex = index; + } + }; + + // spine-core/src/AnimationState.ts + var AnimationState = class _AnimationState { + static _emptyAnimation = new Animation("", [], 0); + static emptyAnimation() { + return _AnimationState._emptyAnimation; + } + /** The AnimationStateData to look up mix durations. */ + data; + /** The list of tracks that currently have animations, which may contain null entries. */ + tracks = new Array(); + /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower + * or faster. Defaults to 1. + * + * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */ + timeScale = 1; + unkeyedState = 0; + events = new Array(); + listeners = new Array(); + queue = new EventQueue(this); + propertyIDs = new StringSet(); + animationsChanged = false; + trackEntryPool = new Pool(() => new TrackEntry()); + constructor(data) { + this.data = data; + } + /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ + update(delta) { + delta *= this.timeScale; + let tracks = this.tracks; + for (let i = 0, n = tracks.length; i < n; i++) { + let current = tracks[i]; + if (!current) continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + let currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) continue; + currentDelta = -current.delay; + current.delay = 0; + } + let next = current.next; + if (next) { + let nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } else if (current.trackLast >= current.trackEnd && !current.mixingFrom) { + tracks[i] = null; + this.queue.end(current); + this.clearNext(current); + continue; + } + if (current.mixingFrom && this.updateMixingFrom(current, delta)) { + let from = current.mixingFrom; + current.mixingFrom = null; + if (from) from.mixingTo = null; + while (from) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + } + /** Returns true when all mixing from entries are complete. */ + updateMixingFrom(to, delta) { + let from = to.mixingFrom; + if (!from) return true; + let finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + if (to.nextTrackLast != -1 && to.mixTime >= to.mixDuration) { + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + } + /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the + * animation state can be applied to multiple skeletons to pose them identically. + * @returns True if any animations were applied. */ + apply(skeleton) { + if (!skeleton) throw new Error("skeleton cannot be null."); + if (this.animationsChanged) this._animationsChanged(); + let events = this.events; + let tracks = this.tracks; + let applied = false; + for (let i2 = 0, n2 = tracks.length; i2 < n2; i2++) { + let current = tracks[i2]; + if (!current || current.delay > 0) continue; + applied = true; + let blend = i2 == 0 ? 1 /* first */ : current.mixBlend; + let alpha = current.alpha; + if (current.mixingFrom) + alpha *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && !current.next) + alpha = 0; + let attachments = alpha >= current.alphaAttachmentThreshold; + let animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime; + let applyEvents = events; + if (current.reverse) { + applyTime = current.animation.duration - applyTime; + applyEvents = null; + } + let timelines = current.animation.timelines; + let timelineCount = timelines.length; + if (i2 == 0 && alpha == 1 || blend == 3 /* add */) { + if (i2 == 0) attachments = true; + for (let ii = 0; ii < timelineCount; ii++) { + Utils.webkit602BugfixHelper(alpha, blend); + var timeline = timelines[ii]; + if (timeline instanceof AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, attachments); + else + timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, blend, 0 /* mixIn */); + } + } else { + let timelineMode = current.timelineMode; + let shortestRotation = current.shortestRotation; + let firstFrame = !shortestRotation && current.timelinesRotation.length != timelineCount << 1; + if (firstFrame) current.timelinesRotation.length = timelineCount << 1; + for (let ii = 0; ii < timelineCount; ii++) { + let timeline2 = timelines[ii]; + let timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : 0 /* setup */; + if (!shortestRotation && timeline2 instanceof RotateTimeline) { + this.applyRotateTimeline(timeline2, skeleton, applyTime, alpha, timelineBlend, current.timelinesRotation, ii << 1, firstFrame); + } else if (timeline2 instanceof AttachmentTimeline) { + this.applyAttachmentTimeline(timeline2, skeleton, applyTime, blend, attachments); + } else { + Utils.webkit602BugfixHelper(alpha, blend); + timeline2.apply(skeleton, animationLast, applyTime, applyEvents, alpha, timelineBlend, 0 /* mixIn */); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + var setupState = this.unkeyedState + SETUP; + var slots = skeleton.slots; + for (var i = 0, n = skeleton.slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.attachmentState == setupState) { + var attachmentName = slot.data.attachmentName; + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + } + } + this.unkeyedState += 2; + this.queue.drain(); + return applied; + } + applyMixingFrom(to, skeleton, blend) { + let from = to.mixingFrom; + if (from.mixingFrom) this.applyMixingFrom(from, skeleton, blend); + let mix = 0; + if (to.mixDuration == 0) { + mix = 1; + if (blend == 1 /* first */) blend = 0 /* setup */; + } else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) mix = 1; + if (blend != 1 /* first */) blend = from.mixBlend; + } + let attachments = mix < from.mixAttachmentThreshold, drawOrder = mix < from.mixDrawOrderThreshold; + let timelines = from.animation.timelines; + let timelineCount = timelines.length; + let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + let animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime; + let events = null; + if (from.reverse) + applyTime = from.animation.duration - applyTime; + else if (mix < from.eventThreshold) + events = this.events; + if (blend == 3 /* add */) { + for (let i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, 1 /* mixOut */); + } else { + let timelineMode = from.timelineMode; + let timelineHoldMix = from.timelineHoldMix; + let shortestRotation = from.shortestRotation; + let firstFrame = !shortestRotation && from.timelinesRotation.length != timelineCount << 1; + if (firstFrame) from.timelinesRotation.length = timelineCount << 1; + from.totalAlpha = 0; + for (let i = 0; i < timelineCount; i++) { + let timeline = timelines[i]; + let direction = 1 /* mixOut */; + let timelineBlend; + let alpha = 0; + switch (timelineMode[i]) { + case SUBSEQUENT: + if (!drawOrder && timeline instanceof DrawOrderTimeline) continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case FIRST: + timelineBlend = 0 /* setup */; + alpha = alphaMix; + break; + case HOLD_SUBSEQUENT: + timelineBlend = blend; + alpha = alphaHold; + break; + case HOLD_FIRST: + timelineBlend = 0 /* setup */; + alpha = alphaHold; + break; + default: + timelineBlend = 0 /* setup */; + let holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (!shortestRotation && timeline instanceof RotateTimeline) + this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, from.timelinesRotation, i << 1, firstFrame); + else if (timeline instanceof AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments && alpha >= from.alphaAttachmentThreshold); + else { + Utils.webkit602BugfixHelper(alpha, blend); + if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == 0 /* setup */) + direction = 0 /* mixIn */; + timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + } + applyAttachmentTimeline(timeline, skeleton, time, blend, attachments) { + var slot = skeleton.slots[timeline.slotIndex]; + if (!slot.bone.active) return; + if (time < timeline.frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) + this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); + } else + this.setAttachment(skeleton, slot, timeline.attachmentNames[Timeline.search1(timeline.frames, time)], attachments); + if (slot.attachmentState <= this.unkeyedState) slot.attachmentState = this.unkeyedState + SETUP; + } + setAttachment(skeleton, slot, attachmentName, attachments) { + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + if (attachments) slot.attachmentState = this.unkeyedState + CURRENT; + } + applyRotateTimeline(timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, 0 /* mixIn */); + return; + } + let bone = skeleton.bones[timeline.boneIndex]; + if (!bone.active) return; + let frames = timeline.frames; + let r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.rotation = bone.data.rotation; + default: + return; + case 1 /* first */: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } else { + r1 = blend == 0 /* setup */ ? bone.data.rotation : bone.rotation; + r2 = bone.data.rotation + timeline.getCurveValue(time); + } + let total = 0, diff = r2 - r1; + diff -= Math.ceil(diff / 360 - 0.5) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } else { + let lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } else { + lastTotal = timelinesRotation[i]; + lastDiff = timelinesRotation[i + 1]; + } + let loops = lastTotal - lastTotal % 360; + total = diff + loops; + let current = diff >= 0, dir = lastTotal >= 0; + if (Math.abs(lastDiff) <= 90 && MathUtils.signum(lastDiff) != MathUtils.signum(diff)) { + if (Math.abs(lastTotal - loops) > 180) { + total += 360 * MathUtils.signum(lastTotal); + dir = current; + } else if (loops != 0) + total -= 360 * MathUtils.signum(lastTotal); + else + dir = current; + } + if (dir != current) total += 360 * MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + bone.rotation = r1 + total * alpha; + } + queueEvents(entry, animationTime) { + let animationStart = entry.animationStart, animationEnd = entry.animationEnd; + let duration = animationEnd - animationStart; + let trackLastWrapped = entry.trackLast % duration; + let events = this.events; + let i = 0, n = events.length; + for (; i < n; i++) { + let event = events[i]; + if (event.time < trackLastWrapped) break; + if (event.time > animationEnd) continue; + this.queue.event(entry, event); + } + let complete = false; + if (entry.loop) { + if (duration == 0) + complete = true; + else { + const cycles = Math.floor(entry.trackTime / duration); + complete = cycles > 0 && cycles > Math.floor(entry.trackLast / duration); + } + } else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) this.queue.complete(entry); + for (; i < n; i++) { + let event = events[i]; + if (event.time < animationStart) continue; + this.queue.event(entry, event); + } + } + /** Removes all animations from all tracks, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + clearTracks() { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + /** Removes all animations from the track, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + clearTrack(trackIndex) { + if (trackIndex >= this.tracks.length) return; + let current = this.tracks[trackIndex]; + if (!current) return; + this.queue.end(current); + this.clearNext(current); + let entry = current; + while (true) { + let from = entry.mixingFrom; + if (!from) break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + } + setCurrent(index, current, interrupt) { + let from = this.expandToIndex(index); + this.tracks[index] = current; + current.previous = null; + if (from) { + if (interrupt) this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + if (from.mixingFrom && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; + } + this.queue.start(current); + } + /** Sets an animation by name. + * + * See {@link #setAnimationWith()}. */ + setAnimation(trackIndex, animationName, loop = false) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + } + /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never + * applied to a skeleton, it is replaced (not mixed from). + * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + setAnimationWith(trackIndex, animation, loop = false) { + if (!animation) throw new Error("animation cannot be null."); + let interrupt = true; + let current = this.expandToIndex(trackIndex); + if (current) { + if (current.nextTrackLast == -1) { + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.clearNext(current); + current = current.mixingFrom; + interrupt = false; + } else + this.clearNext(current); + } + let entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + } + /** Queues an animation by name. + * + * See {@link #addAnimationWith()}. */ + addAnimation(trackIndex, animationName, loop = false, delay = 0) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + } + /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is + * equivalent to calling {@link #setAnimationWith()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix + * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the + * previous entry is looping, its next loop completion is used instead of its duration. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + addAnimationWith(trackIndex, animation, loop = false, delay = 0) { + if (!animation) throw new Error("animation cannot be null."); + let last = this.expandToIndex(trackIndex); + if (last) { + while (last.next) + last = last.next; + } + let entry = this.trackEntry(trackIndex, animation, loop, last); + if (!last) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + if (delay < 0) delay = 0; + } else { + last.next = entry; + entry.previous = last; + if (delay <= 0) delay = Math.max(delay + last.getTrackComplete() - entry.mixDuration, 0); + } + entry.delay = delay; + return entry; + } + /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's + * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out. + * + * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()}, + * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes + * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation + * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of + * 0 still mixes out over one frame. + * + * Mixing in is done by first setting an empty animation, then adding an animation using + * {@link #addAnimation()} and on the returned track entry, set the + * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and + * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the + * setup pose value if no lower tracks key the property to the value keyed in the new animation. */ + setEmptyAnimation(trackIndex, mixDuration = 0) { + let entry = this.setAnimationWith(trackIndex, _AnimationState.emptyAnimation(), false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's + * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling + * {@link #setEmptyAnimation()}. + * + * See {@link #setEmptyAnimation()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or + * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next + * loop completion is used instead of its duration. + * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + addEmptyAnimation(trackIndex, mixDuration = 0, delay = 0) { + let entry = this.addAnimationWith(trackIndex, _AnimationState.emptyAnimation(), false, delay); + if (delay <= 0) entry.delay = Math.max(entry.delay + entry.mixDuration - mixDuration, 0); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix + * duration. */ + setEmptyAnimations(mixDuration = 0) { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) { + let current = this.tracks[i]; + if (current) this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + expandToIndex(index) { + if (index < this.tracks.length) return this.tracks[index]; + Utils.ensureArrayCapacity(this.tracks, index + 1, null); + this.tracks.length = index + 1; + return null; + } + /** @param last May be null. */ + trackEntry(trackIndex, animation, loop, last) { + let entry = this.trackEntryPool.obtain(); + entry.reset(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.reverse = false; + entry.shortestRotation = false; + entry.eventThreshold = 0; + entry.alphaAttachmentThreshold = 0; + entry.mixAttachmentThreshold = 0; + entry.mixDrawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.mixTime = 0; + entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation); + entry.interruptAlpha = 1; + entry.totalAlpha = 0; + entry.mixBlend = 2 /* replace */; + return entry; + } + /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */ + clearNext(entry) { + let next = entry.next; + while (next) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + } + _animationsChanged() { + this.animationsChanged = false; + this.propertyIDs.clear(); + let tracks = this.tracks; + for (let i = 0, n = tracks.length; i < n; i++) { + let entry = tracks[i]; + if (!entry) continue; + while (entry.mixingFrom) + entry = entry.mixingFrom; + do { + if (!entry.mixingTo || entry.mixBlend != 3 /* add */) this.computeHold(entry); + entry = entry.mixingTo; + } while (entry); + } + } + computeHold(entry) { + let to = entry.mixingTo; + let timelines = entry.animation.timelines; + let timelinesCount = entry.animation.timelines.length; + let timelineMode = entry.timelineMode; + timelineMode.length = timelinesCount; + let timelineHoldMix = entry.timelineHoldMix; + timelineHoldMix.length = 0; + let propertyIDs = this.propertyIDs; + if (to && to.holdPrevious) { + for (let i = 0; i < timelinesCount; i++) + timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT; + return; + } + outer: + for (let i = 0; i < timelinesCount; i++) { + let timeline = timelines[i]; + let ids = timeline.getPropertyIds(); + if (!propertyIDs.addAll(ids)) + timelineMode[i] = SUBSEQUENT; + else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) { + timelineMode[i] = FIRST; + } else { + for (let next = to.mixingTo; next; next = next.mixingTo) { + if (next.animation.hasTimeline(ids)) continue; + if (entry.mixDuration > 0) { + timelineMode[i] = HOLD_MIX; + timelineHoldMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = HOLD_FIRST; + } + } + } + /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ + getCurrent(trackIndex) { + if (trackIndex >= this.tracks.length) return null; + return this.tracks[trackIndex]; + } + /** Adds a listener to receive events for all track entries. */ + addListener(listener) { + if (!listener) throw new Error("listener cannot be null."); + this.listeners.push(listener); + } + /** Removes the listener added with {@link #addListener()}. */ + removeListener(listener) { + let index = this.listeners.indexOf(listener); + if (index >= 0) this.listeners.splice(index, 1); + } + /** Removes all listeners added with {@link #addListener()}. */ + clearListeners() { + this.listeners.length = 0; + } + /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an + * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery + * are not wanted because new animations are being set. */ + clearListenerNotifications() { + this.queue.clear(); + } + }; + var TrackEntry = class { + /** The animation to apply for this track entry. */ + animation = null; + previous = null; + /** The animation queued to start after this animation, or null. `next` makes up a linked list. */ + next = null; + /** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no + * mixing is currently occuring. When mixing from multiple animations, `mixingFrom` makes up a linked list. */ + mixingFrom = null; + /** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is + * currently occuring. When mixing to multiple animations, `mixingTo` makes up a linked list. */ + mixingTo = null; + /** The listener for events generated by this track entry, or null. + * + * A track entry returned from {@link AnimationState#setAnimation()} is already the current animation + * for the track, so the track entry listener {@link AnimationStateListener#start()} will not be called. */ + listener = null; + /** The index of the track where this track entry is either current or queued. + * + * See {@link AnimationState#getCurrent()}. */ + trackIndex = 0; + /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. */ + loop = false; + /** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead + * of being mixed out. + * + * When mixing between animations that key the same property, if a lower track also keys that property then the value will + * briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0% + * while the second animation mixes from 0% to 100%. Setting `holdPrevious` to true applies the first animation + * at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which + * keys the property, only when a higher track also keys the property. + * + * Snapping will occur if `holdPrevious` is true and this animation does not key all the same properties as the + * previous animation. */ + holdPrevious = false; + reverse = false; + shortestRotation = false; + /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the + * `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event + * timelines are not applied while this animation is being mixed out. */ + eventThreshold = 0; + /** When the mix percentage ({@link #mixtime} / {@link #mixDuration}) is less than the + * `attachmentThreshold`, attachment timelines are applied while this animation is being mixed out. Defaults to + * 0, so attachment timelines are not applied while this animation is being mixed out. */ + mixAttachmentThreshold = 0; + /** When {@link #getAlpha()} is greater than alphaAttachmentThreshold, attachment timelines are applied. + * Defaults to 0, so attachment timelines are always applied. */ + alphaAttachmentThreshold = 0; + /** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the + * mixDrawOrderThreshold, draw order timelines are applied while this animation is being mixed out. Defaults to + * 0, so draw order timelines are not applied while this animation is being mixed out. */ + mixDrawOrderThreshold = 0; + /** Seconds when this animation starts, both initially and after looping. Defaults to 0. + * + * When changing the `animationStart` time, it often makes sense to set {@link #animationLast} to the same + * value to prevent timeline keys before the start time from triggering. */ + animationStart = 0; + /** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will + * loop back to {@link #animationStart} at this time. Defaults to the animation {@link Animation#duration}. */ + animationEnd = 0; + /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this + * animation is applied, event timelines will fire all events between the `animationLast` time (exclusive) and + * `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation + * is applied. */ + animationLast = 0; + nextAnimationLast = 0; + /** Seconds to postpone playing the animation. When this track entry is the current track entry, `delay` + * postpones incrementing the {@link #trackTime}. When this track entry is queued, `delay` is the time from + * the start of the previous animation to when this track entry will become the current track entry (ie when the previous + * track entry {@link TrackEntry#trackTime} >= this track entry's `delay`). + * + * {@link #timeScale} affects the delay. */ + delay = 0; + /** Current time in seconds this track entry has been the current track entry. The track time determines + * {@link #animationTime}. The track time can be set to start the animation at a time other than 0, without affecting + * looping. */ + trackTime = 0; + trackLast = 0; + nextTrackLast = 0; + /** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float + * value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time + * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the + * properties keyed by the animation are set to the setup pose and the track is cleared. + * + * It may be desired to use {@link AnimationState#addEmptyAnimation()} rather than have the animation + * abruptly cease being applied. */ + trackEnd = 0; + /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or + * faster. Defaults to 1. + * + * {@link #mixTime} is not affected by track entry time scale, so {@link #mixDuration} may need to be adjusted to + * match the animation speed. + * + * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the + * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If + * the time scale is not 1, the delay may need to be adjusted. + * + * See AnimationState {@link AnimationState#timeScale} for affecting all animations. */ + timeScale = 0; + /** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults + * to 1, which overwrites the skeleton's current pose with this animation. + * + * Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to + * use alpha on track 0 if the skeleton pose is from the last frame render. */ + alpha = 0; + /** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be + * slightly more than `mixDuration` when the mix is complete. */ + mixTime = 0; + /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData + * {@link AnimationStateData#getMix()} based on the animation before this animation (if any). + * + * A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the + * properties it was animating. + * + * The `mixDuration` can be set manually rather than use the value from + * {@link AnimationStateData#getMix()}. In that case, the `mixDuration` can be set for a new + * track entry only before {@link AnimationState#update(float)} is first called. + * + * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the + * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, not a mix duration set + * afterward. */ + _mixDuration = 0; + interruptAlpha = 0; + totalAlpha = 0; + get mixDuration() { + return this._mixDuration; + } + set mixDuration(mixDuration) { + this._mixDuration = mixDuration; + } + setMixDurationWithDelay(mixDuration, delay) { + this._mixDuration = mixDuration; + if (delay <= 0) { + if (this.previous != null) + delay = Math.max(delay + this.previous.getTrackComplete() - mixDuration, 0); + else + delay = 0; + } + this.delay = delay; + } + /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which + * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to + * the values from the lower tracks. + * + * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first + * called. */ + mixBlend = 2 /* replace */; + timelineMode = new Array(); + timelineHoldMix = new Array(); + timelinesRotation = new Array(); + reset() { + this.next = null; + this.previous = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + } + /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} + * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the + * `animationStart` time. */ + getAnimationTime() { + if (this.loop) { + let duration = this.animationEnd - this.animationStart; + if (duration == 0) return this.animationStart; + return this.trackTime % duration + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + } + setAnimationLast(animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + } + /** Returns true if at least one loop has been completed. + * + * See {@link AnimationStateListener#complete()}. */ + isComplete() { + return this.trackTime >= this.animationEnd - this.animationStart; + } + /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the + * long way around when using {@link #alpha} and starting animations on other tracks. + * + * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions: + * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long + * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the + * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ + resetRotationDirections() { + this.timelinesRotation.length = 0; + } + getTrackComplete() { + let duration = this.animationEnd - this.animationStart; + if (duration != 0) { + if (this.loop) return duration * (1 + (this.trackTime / duration | 0)); + if (this.trackTime < duration) return duration; + } + return this.trackTime; + } + /** Returns true if this track entry has been applied at least once. + *

+ * See {@link AnimationState#apply(Skeleton)}. */ + wasApplied() { + return this.nextTrackLast != -1; + } + /** Returns true if there is a {@link #getNext()} track entry and it will become the current track entry during the next + * {@link AnimationState#update(float)}. */ + isNextReady() { + return this.next != null && this.nextTrackLast - this.next.delay >= 0; + } + }; + var EventQueue = class { + objects = []; + drainDisabled = false; + animState; + constructor(animState) { + this.animState = animState; + } + start(entry) { + this.objects.push(0 /* start */); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + interrupt(entry) { + this.objects.push(1 /* interrupt */); + this.objects.push(entry); + } + end(entry) { + this.objects.push(2 /* end */); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + dispose(entry) { + this.objects.push(3 /* dispose */); + this.objects.push(entry); + } + complete(entry) { + this.objects.push(4 /* complete */); + this.objects.push(entry); + } + event(entry, event) { + this.objects.push(5 /* event */); + this.objects.push(entry); + this.objects.push(event); + } + drain() { + if (this.drainDisabled) return; + this.drainDisabled = true; + let objects = this.objects; + let listeners = this.animState.listeners; + for (let i = 0; i < objects.length; i += 2) { + let type = objects[i]; + let entry = objects[i + 1]; + switch (type) { + case 0 /* start */: + if (entry.listener && entry.listener.start) entry.listener.start(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.start) listener.start(entry); + } + break; + case 1 /* interrupt */: + if (entry.listener && entry.listener.interrupt) entry.listener.interrupt(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.interrupt) listener.interrupt(entry); + } + break; + case 2 /* end */: + if (entry.listener && entry.listener.end) entry.listener.end(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.end) listener.end(entry); + } + // Fall through. + case 3 /* dispose */: + if (entry.listener && entry.listener.dispose) entry.listener.dispose(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.dispose) listener.dispose(entry); + } + this.animState.trackEntryPool.free(entry); + break; + case 4 /* complete */: + if (entry.listener && entry.listener.complete) entry.listener.complete(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.complete) listener.complete(entry); + } + break; + case 5 /* event */: + let event = objects[i++ + 2]; + if (entry.listener && entry.listener.event) entry.listener.event(entry, event); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.event) listener.event(entry, event); + } + break; + } + } + this.clear(); + this.drainDisabled = false; + } + clear() { + this.objects.length = 0; + } + }; + var EventType = /* @__PURE__ */ ((EventType2) => { + EventType2[EventType2["start"] = 0] = "start"; + EventType2[EventType2["interrupt"] = 1] = "interrupt"; + EventType2[EventType2["end"] = 2] = "end"; + EventType2[EventType2["dispose"] = 3] = "dispose"; + EventType2[EventType2["complete"] = 4] = "complete"; + EventType2[EventType2["event"] = 5] = "event"; + return EventType2; + })(EventType || {}); + var AnimationStateAdapter = class { + start(entry) { + } + interrupt(entry) { + } + end(entry) { + } + dispose(entry) { + } + complete(entry) { + } + event(entry, event) { + } + }; + var SUBSEQUENT = 0; + var FIRST = 1; + var HOLD_SUBSEQUENT = 2; + var HOLD_FIRST = 3; + var HOLD_MIX = 4; + var SETUP = 1; + var CURRENT = 2; + + // spine-core/src/AnimationStateData.ts + var AnimationStateData = class { + /** The SkeletonData to look up animations when they are specified by name. */ + skeletonData; + animationToMixTime = {}; + /** The mix duration to use when no mix duration has been defined between two animations. */ + defaultMix = 0; + constructor(skeletonData) { + if (!skeletonData) throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + /** Sets a mix duration by animation name. + * + * See {@link #setMixWith()}. */ + setMix(fromName, toName, duration) { + let from = this.skeletonData.findAnimation(fromName); + if (!from) throw new Error("Animation not found: " + fromName); + let to = this.skeletonData.findAnimation(toName); + if (!to) throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + } + /** Sets the mix duration when changing from the specified animation to the other. + * + * See {@link TrackEntry#mixDuration}. */ + setMixWith(from, to, duration) { + if (!from) throw new Error("from cannot be null."); + if (!to) throw new Error("to cannot be null."); + let key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + } + /** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if + * no mix duration has been set. */ + getMix(from, to) { + let key = from.name + "." + to.name; + let value = this.animationToMixTime[key]; + return value === void 0 ? this.defaultMix : value; + } + }; + + // spine-core/src/attachments/BoundingBoxAttachment.ts + var BoundingBoxAttachment = class _BoundingBoxAttachment extends VertexAttachment { + color = new Color(1, 1, 1, 1); + constructor(name) { + super(name); + } + copy() { + let copy = new _BoundingBoxAttachment(this.name); + this.copyTo(copy); + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/attachments/ClippingAttachment.ts + var ClippingAttachment = class _ClippingAttachment extends VertexAttachment { + /** Clipping is performed between the clipping polygon's slot and the end slot. Returns null if clipping is done until the end of + * the skeleton's rendering. */ + endSlot = null; + // Nonessential. + /** The color of the clipping polygon as it was in Spine. Available only when nonessential data was exported. Clipping polygons + * are not usually rendered at runtime. */ + color = new Color(0.2275, 0.2275, 0.8078, 1); + // ce3a3aff + constructor(name) { + super(name); + } + copy() { + let copy = new _ClippingAttachment(this.name); + this.copyTo(copy); + copy.endSlot = this.endSlot; + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/Texture.ts + var Texture = class { + _image; + constructor(image) { + this._image = image; + } + getImage() { + return this._image; + } + }; + var TextureFilter = /* @__PURE__ */ ((TextureFilter3) => { + TextureFilter3[TextureFilter3["Nearest"] = 9728] = "Nearest"; + TextureFilter3[TextureFilter3["Linear"] = 9729] = "Linear"; + TextureFilter3[TextureFilter3["MipMap"] = 9987] = "MipMap"; + TextureFilter3[TextureFilter3["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest"; + TextureFilter3[TextureFilter3["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; + TextureFilter3[TextureFilter3["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; + TextureFilter3[TextureFilter3["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; + return TextureFilter3; + })(TextureFilter || {}); + var TextureWrap = /* @__PURE__ */ ((TextureWrap3) => { + TextureWrap3[TextureWrap3["MirroredRepeat"] = 33648] = "MirroredRepeat"; + TextureWrap3[TextureWrap3["ClampToEdge"] = 33071] = "ClampToEdge"; + TextureWrap3[TextureWrap3["Repeat"] = 10497] = "Repeat"; + return TextureWrap3; + })(TextureWrap || {}); + var TextureRegion = class { + texture; + u = 0; + v = 0; + u2 = 0; + v2 = 0; + width = 0; + height = 0; + degrees = 0; + offsetX = 0; + offsetY = 0; + originalWidth = 0; + originalHeight = 0; + }; + var FakeTexture = class extends Texture { + setFilters(minFilter, magFilter) { + } + setWraps(uWrap, vWrap) { + } + dispose() { + } + }; + + // spine-core/src/TextureAtlas.ts + var TextureAtlas = class { + pages = new Array(); + regions = new Array(); + constructor(atlasText) { + let reader = new TextureAtlasReader(atlasText); + let entry = new Array(4); + let pageFields = {}; + pageFields["size"] = (page2) => { + page2.width = parseInt(entry[1]); + page2.height = parseInt(entry[2]); + }; + pageFields["format"] = () => { + }; + pageFields["filter"] = (page2) => { + page2.minFilter = Utils.enumValue(TextureFilter, entry[1]); + page2.magFilter = Utils.enumValue(TextureFilter, entry[2]); + }; + pageFields["repeat"] = (page2) => { + if (entry[1].indexOf("x") != -1) page2.uWrap = 10497 /* Repeat */; + if (entry[1].indexOf("y") != -1) page2.vWrap = 10497 /* Repeat */; + }; + pageFields["pma"] = (page2) => { + page2.pma = entry[1] == "true"; + }; + var regionFields = {}; + regionFields["xy"] = (region) => { + region.x = parseInt(entry[1]); + region.y = parseInt(entry[2]); + }; + regionFields["size"] = (region) => { + region.width = parseInt(entry[1]); + region.height = parseInt(entry[2]); + }; + regionFields["bounds"] = (region) => { + region.x = parseInt(entry[1]); + region.y = parseInt(entry[2]); + region.width = parseInt(entry[3]); + region.height = parseInt(entry[4]); + }; + regionFields["offset"] = (region) => { + region.offsetX = parseInt(entry[1]); + region.offsetY = parseInt(entry[2]); + }; + regionFields["orig"] = (region) => { + region.originalWidth = parseInt(entry[1]); + region.originalHeight = parseInt(entry[2]); + }; + regionFields["offsets"] = (region) => { + region.offsetX = parseInt(entry[1]); + region.offsetY = parseInt(entry[2]); + region.originalWidth = parseInt(entry[3]); + region.originalHeight = parseInt(entry[4]); + }; + regionFields["rotate"] = (region) => { + let value = entry[1]; + if (value == "true") + region.degrees = 90; + else if (value != "false") + region.degrees = parseInt(value); + }; + regionFields["index"] = (region) => { + region.index = parseInt(entry[1]); + }; + let line = reader.readLine(); + while (line && line.trim().length == 0) + line = reader.readLine(); + while (true) { + if (!line || line.trim().length == 0) break; + if (reader.readEntry(entry, line) == 0) break; + line = reader.readLine(); + } + let page = null; + let names = null; + let values = null; + while (true) { + if (line === null) break; + if (line.trim().length == 0) { + page = null; + line = reader.readLine(); + } else if (!page) { + page = new TextureAtlasPage(line.trim()); + while (true) { + if (reader.readEntry(entry, line = reader.readLine()) == 0) break; + let field = pageFields[entry[0]]; + if (field) field(page); + } + this.pages.push(page); + } else { + let region = new TextureAtlasRegion(page, line); + while (true) { + let count = reader.readEntry(entry, line = reader.readLine()); + if (count == 0) break; + let field = regionFields[entry[0]]; + if (field) + field(region); + else { + if (!names) names = []; + if (!values) values = []; + names.push(entry[0]); + let entryValues = []; + for (let i = 0; i < count; i++) + entryValues.push(parseInt(entry[i + 1])); + values.push(entryValues); + } + } + if (region.originalWidth == 0 && region.originalHeight == 0) { + region.originalWidth = region.width; + region.originalHeight = region.height; + } + if (names && names.length > 0 && values && values.length > 0) { + region.names = names; + region.values = values; + names = null; + values = null; + } + region.u = region.x / page.width; + region.v = region.y / page.height; + if (region.degrees == 90) { + region.u2 = (region.x + region.height) / page.width; + region.v2 = (region.y + region.width) / page.height; + } else { + region.u2 = (region.x + region.width) / page.width; + region.v2 = (region.y + region.height) / page.height; + } + this.regions.push(region); + } + } + } + findRegion(name) { + for (let i = 0; i < this.regions.length; i++) { + if (this.regions[i].name == name) { + return this.regions[i]; + } + } + return null; + } + setTextures(assetManager, pathPrefix = "") { + for (let page of this.pages) + page.setTexture(assetManager.get(pathPrefix + page.name)); + } + dispose() { + for (let i = 0; i < this.pages.length; i++) { + this.pages[i].texture?.dispose(); + } + } + }; + var TextureAtlasReader = class { + lines; + index = 0; + constructor(text) { + this.lines = text.split(/\r\n|\r|\n/); + } + readLine() { + if (this.index >= this.lines.length) + return null; + return this.lines[this.index++]; + } + readEntry(entry, line) { + if (!line) return 0; + line = line.trim(); + if (line.length == 0) return 0; + let colon = line.indexOf(":"); + if (colon == -1) return 0; + entry[0] = line.substr(0, colon).trim(); + for (let i = 1, lastMatch = colon + 1; ; i++) { + let comma = line.indexOf(",", lastMatch); + if (comma == -1) { + entry[i] = line.substr(lastMatch).trim(); + return i; + } + entry[i] = line.substr(lastMatch, comma - lastMatch).trim(); + lastMatch = comma + 1; + if (i == 4) return 4; + } + } + }; + var TextureAtlasPage = class { + name; + minFilter = 9728 /* Nearest */; + magFilter = 9728 /* Nearest */; + uWrap = 33071 /* ClampToEdge */; + vWrap = 33071 /* ClampToEdge */; + texture = null; + width = 0; + height = 0; + pma = false; + regions = new Array(); + constructor(name) { + this.name = name; + } + setTexture(texture) { + this.texture = texture; + texture.setFilters(this.minFilter, this.magFilter); + texture.setWraps(this.uWrap, this.vWrap); + for (let region of this.regions) + region.texture = texture; + } + }; + var TextureAtlasRegion = class extends TextureRegion { + page; + name; + x = 0; + y = 0; + offsetX = 0; + offsetY = 0; + originalWidth = 0; + originalHeight = 0; + index = 0; + degrees = 0; + names = null; + values = null; + constructor(page, name) { + super(); + this.page = page; + this.name = name; + page.regions.push(this); + } + }; + + // spine-core/src/attachments/MeshAttachment.ts + var MeshAttachment = class _MeshAttachment extends VertexAttachment { + region = null; + /** The name of the texture region for this attachment. */ + path; + /** The UV pair for each vertex, normalized within the texture region. */ + regionUVs = []; + /** The UV pair for each vertex, normalized within the entire texture. + * + * See {@link #updateUVs}. */ + uvs = []; + /** Triplets of vertex indices which describe the mesh's triangulation. */ + triangles = []; + /** The color to tint the mesh. */ + color = new Color(1, 1, 1, 1); + /** The width of the mesh's image. Available only when nonessential data was exported. */ + width = 0; + /** The height of the mesh's image. Available only when nonessential data was exported. */ + height = 0; + /** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */ + hullLength = 0; + /** Vertex index pairs describing edges for controling triangulation. Mesh triangles will never cross edges. Only available if + * nonessential data was exported. Triangulation is not performed at runtime. */ + edges = []; + parentMesh = null; + sequence = null; + tempColor = new Color(0, 0, 0, 0); + constructor(name, path) { + super(name); + this.path = path; + } + /** Calculates {@link #uvs} using the {@link #regionUVs} and region. Must be called if the region, the region's properties, or + * the {@link #regionUVs} are changed. */ + updateRegion() { + if (!this.region) throw new Error("Region not set."); + let regionUVs = this.regionUVs; + if (!this.uvs || this.uvs.length != regionUVs.length) this.uvs = Utils.newFloatArray(regionUVs.length); + let uvs = this.uvs; + let n = this.uvs.length; + let u = this.region.u, v = this.region.v, width = 0, height = 0; + if (this.region instanceof TextureAtlasRegion) { + let region = this.region, page = region.page; + let textureWidth = page.width, textureHeight = page.height; + switch (region.degrees) { + case 90: + u -= (region.originalHeight - region.offsetY - region.height) / textureWidth; + v -= (region.originalWidth - region.offsetX - region.width) / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + (1 - regionUVs[i]) * height; + } + return; + case 180: + u -= (region.originalWidth - region.offsetX - region.width) / textureWidth; + v -= region.offsetY / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i]) * width; + uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; + } + return; + case 270: + u -= region.offsetY / textureWidth; + v -= region.offsetX / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i + 1]) * width; + uvs[i + 1] = v + regionUVs[i] * height; + } + return; + } + u -= region.offsetX / textureWidth; + v -= (region.originalHeight - region.offsetY - region.height) / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + } else if (!this.region) { + u = v = 0; + width = height = 1; + } else { + width = this.region.u2 - u; + height = this.region.v2 - v; + } + for (let i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; + } + } + /** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices}, + * {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the + * parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */ + getParentMesh() { + return this.parentMesh; + } + /** @param parentMesh May be null. */ + setParentMesh(parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + } + copy() { + if (this.parentMesh) return this.newLinkedMesh(); + let copy = new _MeshAttachment(this.name, this.path); + copy.region = this.region; + copy.color.setFromColor(this.color); + this.copyTo(copy); + copy.regionUVs = new Array(this.regionUVs.length); + Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); + copy.uvs = this.uvs instanceof Float32Array ? Utils.newFloatArray(this.uvs.length) : new Array(this.uvs.length); + Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, this.uvs.length); + copy.triangles = new Array(this.triangles.length); + Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); + copy.hullLength = this.hullLength; + copy.sequence = this.sequence != null ? this.sequence.copy() : null; + if (this.edges) { + copy.edges = new Array(this.edges.length); + Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); + } + copy.width = this.width; + copy.height = this.height; + return copy; + } + computeWorldVertices(slot, start, count, worldVertices2, offset, stride) { + if (this.sequence != null) this.sequence.apply(slot, this); + super.computeWorldVertices(slot, start, count, worldVertices2, offset, stride); + } + /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/ + newLinkedMesh() { + let copy = new _MeshAttachment(this.name, this.path); + copy.region = this.region; + copy.color.setFromColor(this.color); + copy.timelineAttachment = this.timelineAttachment; + copy.setParentMesh(this.parentMesh ? this.parentMesh : this); + if (copy.region != null) copy.updateRegion(); + return copy; + } + }; + + // spine-core/src/attachments/PathAttachment.ts + var PathAttachment = class _PathAttachment extends VertexAttachment { + /** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */ + lengths = []; + /** If true, the start and end knots are connected. */ + closed = false; + /** If true, additional calculations are performed to make calculating positions along the path more accurate. If false, fewer + * calculations are performed but calculating positions along the path is less accurate. */ + constantSpeed = false; + /** The color of the path as it was in Spine. Available only when nonessential data was exported. Paths are not usually + * rendered at runtime. */ + color = new Color(1, 1, 1, 1); + constructor(name) { + super(name); + } + copy() { + let copy = new _PathAttachment(this.name); + this.copyTo(copy); + copy.lengths = new Array(this.lengths.length); + Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); + copy.closed = closed; + copy.constantSpeed = this.constantSpeed; + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/attachments/PointAttachment.ts + var PointAttachment = class _PointAttachment extends VertexAttachment { + x = 0; + y = 0; + rotation = 0; + /** The color of the point attachment as it was in Spine. Available only when nonessential data was exported. Point attachments + * are not usually rendered at runtime. */ + color = new Color(0.38, 0.94, 0, 1); + constructor(name) { + super(name); + } + computeWorldPosition(bone, point) { + point.x = this.x * bone.a + this.y * bone.b + bone.worldX; + point.y = this.x * bone.c + this.y * bone.d + bone.worldY; + return point; + } + computeWorldRotation(bone) { + const r = this.rotation * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r); + const x = cos * bone.a + sin * bone.b; + const y = cos * bone.c + sin * bone.d; + return MathUtils.atan2Deg(y, x); + } + copy() { + let copy = new _PointAttachment(this.name); + copy.x = this.x; + copy.y = this.y; + copy.rotation = this.rotation; + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/attachments/RegionAttachment.ts + var RegionAttachment = class _RegionAttachment extends Attachment { + /** The local x translation. */ + x = 0; + /** The local y translation. */ + y = 0; + /** The local scaleX. */ + scaleX = 1; + /** The local scaleY. */ + scaleY = 1; + /** The local rotation. */ + rotation = 0; + /** The width of the region attachment in Spine. */ + width = 0; + /** The height of the region attachment in Spine. */ + height = 0; + /** The color to tint the region attachment. */ + color = new Color(1, 1, 1, 1); + /** The name of the texture region for this attachment. */ + path; + region = null; + sequence = null; + /** For each of the 4 vertices, a pair of x,y values that is the local position of the vertex. + * + * See {@link #updateOffset()}. */ + offset = Utils.newFloatArray(8); + uvs = Utils.newFloatArray(8); + tempColor = new Color(1, 1, 1, 1); + constructor(name, path) { + super(name); + this.path = path; + } + /** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */ + updateRegion() { + if (!this.region) throw new Error("Region not set."); + let region = this.region; + let uvs = this.uvs; + if (region == null) { + uvs[0] = 0; + uvs[1] = 0; + uvs[2] = 0; + uvs[3] = 1; + uvs[4] = 1; + uvs[5] = 1; + uvs[6] = 1; + uvs[7] = 0; + return; + } + let regionScaleX = this.width / this.region.originalWidth * this.scaleX; + let regionScaleY = this.height / this.region.originalHeight * this.scaleY; + let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + let localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + let localX2 = localX + this.region.width * regionScaleX; + let localY2 = localY + this.region.height * regionScaleY; + let radians = this.rotation * MathUtils.degRad; + let cos = Math.cos(radians); + let sin = Math.sin(radians); + let x = this.x, y = this.y; + let localXCos = localX * cos + x; + let localXSin = localX * sin; + let localYCos = localY * cos + y; + let localYSin = localY * sin; + let localX2Cos = localX2 * cos + x; + let localX2Sin = localX2 * sin; + let localY2Cos = localY2 * cos + y; + let localY2Sin = localY2 * sin; + let offset = this.offset; + offset[0] = localXCos - localYSin; + offset[1] = localYCos + localXSin; + offset[2] = localXCos - localY2Sin; + offset[3] = localY2Cos + localXSin; + offset[4] = localX2Cos - localY2Sin; + offset[5] = localY2Cos + localX2Sin; + offset[6] = localX2Cos - localYSin; + offset[7] = localYCos + localX2Sin; + if (region.degrees == 90) { + uvs[0] = region.u2; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + } else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + } + /** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the region may + * be changed. + *

+ * See World transforms in the Spine + * Runtimes Guide. + * @param worldVertices The output world vertices. Must have a length >= offset + 8. + * @param offset The worldVertices index to begin writing values. + * @param stride The number of worldVertices entries between the value pairs written. */ + computeWorldVertices(slot, worldVertices2, offset, stride) { + if (this.sequence != null) + this.sequence.apply(slot, this); + let bone = slot.bone; + let vertexOffset = this.offset; + let x = bone.worldX, y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let offsetX = 0, offsetY = 0; + offsetX = vertexOffset[0]; + offsetY = vertexOffset[1]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[2]; + offsetY = vertexOffset[3]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[4]; + offsetY = vertexOffset[5]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[6]; + offsetY = vertexOffset[7]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + } + copy() { + let copy = new _RegionAttachment(this.name, this.path); + copy.region = this.region; + copy.x = this.x; + copy.y = this.y; + copy.scaleX = this.scaleX; + copy.scaleY = this.scaleY; + copy.rotation = this.rotation; + copy.width = this.width; + copy.height = this.height; + Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); + Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); + copy.color.setFromColor(this.color); + copy.sequence = this.sequence != null ? this.sequence.copy() : null; + return copy; + } + static X1 = 0; + static Y1 = 1; + static C1R = 2; + static C1G = 3; + static C1B = 4; + static C1A = 5; + static U1 = 6; + static V1 = 7; + static X2 = 8; + static Y2 = 9; + static C2R = 10; + static C2G = 11; + static C2B = 12; + static C2A = 13; + static U2 = 14; + static V2 = 15; + static X3 = 16; + static Y3 = 17; + static C3R = 18; + static C3G = 19; + static C3B = 20; + static C3A = 21; + static U3 = 22; + static V3 = 23; + static X4 = 24; + static Y4 = 25; + static C4R = 26; + static C4G = 27; + static C4B = 28; + static C4A = 29; + static U4 = 30; + static V4 = 31; + }; + + // spine-core/src/AtlasAttachmentLoader.ts + var AtlasAttachmentLoader = class { + atlas; + constructor(atlas) { + this.atlas = atlas; + } + loadSequence(name, basePath, sequence) { + let regions = sequence.regions; + for (let i = 0, n = regions.length; i < n; i++) { + let path = sequence.getPath(basePath, i); + let region = this.atlas.findRegion(path); + if (region == null) throw new Error("Region not found in atlas: " + path + " (sequence: " + name + ")"); + regions[i] = region; + } + } + newRegionAttachment(skin, name, path, sequence) { + let attachment = new RegionAttachment(name, path); + if (sequence != null) { + this.loadSequence(name, path, sequence); + } else { + let region = this.atlas.findRegion(path); + if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + attachment.region = region; + } + return attachment; + } + newMeshAttachment(skin, name, path, sequence) { + let attachment = new MeshAttachment(name, path); + if (sequence != null) { + this.loadSequence(name, path, sequence); + } else { + let region = this.atlas.findRegion(path); + if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + attachment.region = region; + } + return attachment; + } + newBoundingBoxAttachment(skin, name) { + return new BoundingBoxAttachment(name); + } + newPathAttachment(skin, name) { + return new PathAttachment(name); + } + newPointAttachment(skin, name) { + return new PointAttachment(name); + } + newClippingAttachment(skin, name) { + return new ClippingAttachment(name); + } + }; + + // spine-core/src/BoneData.ts + var BoneData = class { + /** The index of the bone in {@link Skeleton#getBones()}. */ + index = 0; + /** The name of the bone, which is unique across all bones in the skeleton. */ + name; + /** @returns May be null. */ + parent = null; + /** The bone's length. */ + length = 0; + /** The local x translation. */ + x = 0; + /** The local y translation. */ + y = 0; + /** The local rotation in degrees, counter clockwise. */ + rotation = 0; + /** The local scaleX. */ + scaleX = 1; + /** The local scaleY. */ + scaleY = 1; + /** The local shearX. */ + shearX = 0; + /** The local shearX. */ + shearY = 0; + /** The transform mode for how parent world transforms affect this bone. */ + inherit = 0 /* Normal */; + /** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#skin} contains this + * bone. + * @see Skin#bones */ + skinRequired = false; + /** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually + * rendered at runtime. */ + color = new Color(); + /** The bone icon as it was in Spine, or null if nonessential data was not exported. */ + icon; + /** False if the bone was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */ + visible = false; + constructor(index, name, parent) { + if (index < 0) throw new Error("index must be >= 0."); + if (!name) throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + }; + var Inherit = /* @__PURE__ */ ((Inherit2) => { + Inherit2[Inherit2["Normal"] = 0] = "Normal"; + Inherit2[Inherit2["OnlyTranslation"] = 1] = "OnlyTranslation"; + Inherit2[Inherit2["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; + Inherit2[Inherit2["NoScale"] = 3] = "NoScale"; + Inherit2[Inherit2["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; + return Inherit2; + })(Inherit || {}); + + // spine-core/src/Bone.ts + var Bone = class { + /** The bone's setup pose data. */ + data; + /** The skeleton this bone belongs to. */ + skeleton; + /** The parent bone, or null if this is the root bone. */ + parent = null; + /** The immediate children of this bone. */ + children = new Array(); + /** The local x translation. */ + x = 0; + /** The local y translation. */ + y = 0; + /** The local rotation in degrees, counter clockwise. */ + rotation = 0; + /** The local scaleX. */ + scaleX = 0; + /** The local scaleY. */ + scaleY = 0; + /** The local shearX. */ + shearX = 0; + /** The local shearY. */ + shearY = 0; + /** The applied local x translation. */ + ax = 0; + /** The applied local y translation. */ + ay = 0; + /** The applied local rotation in degrees, counter clockwise. */ + arotation = 0; + /** The applied local scaleX. */ + ascaleX = 0; + /** The applied local scaleY. */ + ascaleY = 0; + /** The applied local shearX. */ + ashearX = 0; + /** The applied local shearY. */ + ashearY = 0; + /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */ + a = 0; + /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */ + b = 0; + /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */ + c = 0; + /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */ + d = 0; + /** The world X position. If changed, {@link #updateAppliedTransform()} should be called. */ + worldY = 0; + /** The world Y position. If changed, {@link #updateAppliedTransform()} should be called. */ + worldX = 0; + inherit = 0 /* Normal */; + sorted = false; + active = false; + /** @param parent May be null. */ + constructor(data, skeleton, parent) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + /** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the + * {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */ + isActive() { + return this.active; + } + /** Computes the world transform using the parent bone and this bone's local applied transform. */ + update(physics) { + this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY); + } + /** Computes the world transform using the parent bone and this bone's local transform. + * + * See {@link #updateWorldTransformWith()}. */ + updateWorldTransform() { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + } + /** Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the + * specified local transform. Child bones are not updated. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. */ + updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + let parent = this.parent; + if (!parent) { + let skeleton = this.skeleton; + const sx = skeleton.scaleX, sy = skeleton.scaleY; + const rx = (rotation + shearX) * MathUtils.degRad; + const ry = (rotation + 90 + shearY) * MathUtils.degRad; + this.a = Math.cos(rx) * scaleX * sx; + this.b = Math.cos(ry) * scaleY * sx; + this.c = Math.sin(rx) * scaleX * sy; + this.d = Math.sin(ry) * scaleY * sy; + this.worldX = x * sx + skeleton.x; + this.worldY = y * sy + skeleton.y; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + this.worldX = pa * x + pb * y + parent.worldX; + this.worldY = pc * x + pd * y + parent.worldY; + switch (this.inherit) { + case 0 /* Normal */: { + const rx = (rotation + shearX) * MathUtils.degRad; + const ry = (rotation + 90 + shearY) * MathUtils.degRad; + const la = Math.cos(rx) * scaleX; + const lb = Math.cos(ry) * scaleY; + const lc = Math.sin(rx) * scaleX; + const ld = Math.sin(ry) * scaleY; + this.a = pa * la + pb * lc; + this.b = pa * lb + pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + return; + } + case 1 /* OnlyTranslation */: { + const rx = (rotation + shearX) * MathUtils.degRad; + const ry = (rotation + 90 + shearY) * MathUtils.degRad; + this.a = Math.cos(rx) * scaleX; + this.b = Math.cos(ry) * scaleY; + this.c = Math.sin(rx) * scaleX; + this.d = Math.sin(ry) * scaleY; + break; + } + case 2 /* NoRotationOrReflection */: { + let sx = 1 / this.skeleton.scaleX, sy = 1 / this.skeleton.scaleY; + pa *= sx; + pc *= sy; + let s = pa * pa + pc * pc; + let prx = 0; + if (s > 1e-4) { + s = Math.abs(pa * pd * sy - pb * sx * pc) / s; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * MathUtils.radDeg; + } else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; + } + const rx = (rotation + shearX - prx) * MathUtils.degRad; + const ry = (rotation + shearY - prx + 90) * MathUtils.degRad; + const la = Math.cos(rx) * scaleX; + const lb = Math.cos(ry) * scaleY; + const lc = Math.sin(rx) * scaleX; + const ld = Math.sin(ry) * scaleY; + this.a = pa * la - pb * lc; + this.b = pa * lb - pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + break; + } + case 3 /* NoScale */: + case 4 /* NoScaleOrReflection */: { + rotation *= MathUtils.degRad; + const cos = Math.cos(rotation), sin = Math.sin(rotation); + let za = (pa * cos + pb * sin) / this.skeleton.scaleX; + let zc = (pc * cos + pd * sin) / this.skeleton.scaleY; + let s = Math.sqrt(za * za + zc * zc); + if (s > 1e-5) s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.inherit == 3 /* NoScale */ && pa * pd - pb * pc < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s; + rotation = Math.PI / 2 + Math.atan2(zc, za); + const zb = Math.cos(rotation) * s; + const zd = Math.sin(rotation) * s; + shearX *= MathUtils.degRad; + shearY = (90 + shearY) * MathUtils.degRad; + const la = Math.cos(shearX) * scaleX; + const lb = Math.cos(shearY) * scaleY; + const lc = Math.sin(shearX) * scaleX; + const ld = Math.sin(shearY) * scaleY; + this.a = za * la + zb * lc; + this.b = za * lb + zb * ld; + this.c = zc * la + zd * lc; + this.d = zc * lb + zd * ld; + break; + } + } + this.a *= this.skeleton.scaleX; + this.b *= this.skeleton.scaleX; + this.c *= this.skeleton.scaleY; + this.d *= this.skeleton.scaleY; + } + /** Sets this bone's local transform to the setup pose. */ + setToSetupPose() { + let data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + this.inherit = data.inherit; + } + /** Computes the applied transform values from the world transform. + * + * If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, etc) then this method should be called so + * the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply other + * constraints). + * + * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after + * calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */ + updateAppliedTransform() { + let parent = this.parent; + if (!parent) { + this.ax = this.worldX - this.skeleton.x; + this.ay = this.worldY - this.skeleton.y; + this.arotation = Math.atan2(this.c, this.a) * MathUtils.radDeg; + this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c); + this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d); + this.ashearX = 0; + this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * MathUtils.radDeg; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + let pid = 1 / (pa * pd - pb * pc); + let ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid; + let dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY; + this.ax = dx * ia - dy * ib; + this.ay = dy * id - dx * ic; + let ra, rb, rc, rd; + if (this.inherit == 1 /* OnlyTranslation */) { + ra = this.a; + rb = this.b; + rc = this.c; + rd = this.d; + } else { + switch (this.inherit) { + case 2 /* NoRotationOrReflection */: { + let s2 = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); + pb = -pc * this.skeleton.scaleX * s2 / this.skeleton.scaleY; + pd = pa * this.skeleton.scaleY * s2 / this.skeleton.scaleX; + pid = 1 / (pa * pd - pb * pc); + ia = pd * pid; + ib = pb * pid; + break; + } + case 3 /* NoScale */: + case 4 /* NoScaleOrReflection */: + let cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); + pa = (pa * cos + pb * sin) / this.skeleton.scaleX; + pc = (pc * cos + pd * sin) / this.skeleton.scaleY; + let s = Math.sqrt(pa * pa + pc * pc); + if (s > 1e-5) s = 1 / s; + pa *= s; + pc *= s; + s = Math.sqrt(pa * pa + pc * pc); + if (this.inherit == 3 /* NoScale */ && pid < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s; + let r = MathUtils.PI / 2 + Math.atan2(pc, pa); + pb = Math.cos(r) * s; + pd = Math.sin(r) * s; + pid = 1 / (pa * pd - pb * pc); + ia = pd * pid; + ib = pb * pid; + ic = pc * pid; + id = pa * pid; + } + ra = ia * this.a - ib * this.c; + rb = ia * this.b - ib * this.d; + rc = id * this.c - ic * this.a; + rd = id * this.d - ic * this.b; + } + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 1e-4) { + let det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = -Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; + } else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; + } + } + /** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */ + getWorldRotationX() { + return Math.atan2(this.c, this.a) * MathUtils.radDeg; + } + /** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */ + getWorldRotationY() { + return Math.atan2(this.d, this.b) * MathUtils.radDeg; + } + /** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */ + getWorldScaleX() { + return Math.sqrt(this.a * this.a + this.c * this.c); + } + /** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */ + getWorldScaleY() { + return Math.sqrt(this.b * this.b + this.d * this.d); + } + /** Transforms a point from world coordinates to the bone's local coordinates. */ + worldToLocal(world) { + let invDet = 1 / (this.a * this.d - this.b * this.c); + let x = world.x - this.worldX, y = world.y - this.worldY; + world.x = x * this.d * invDet - y * this.b * invDet; + world.y = y * this.a * invDet - x * this.c * invDet; + return world; + } + /** Transforms a point from the bone's local coordinates to world coordinates. */ + localToWorld(local) { + let x = local.x, y = local.y; + local.x = x * this.a + y * this.b + this.worldX; + local.y = x * this.c + y * this.d + this.worldY; + return local; + } + /** Transforms a point from world coordinates to the parent bone's local coordinates. */ + worldToParent(world) { + if (world == null) throw new Error("world cannot be null."); + return this.parent == null ? world : this.parent.worldToLocal(world); + } + /** Transforms a point from the parent bone's coordinates to world coordinates. */ + parentToWorld(world) { + if (world == null) throw new Error("world cannot be null."); + return this.parent == null ? world : this.parent.localToWorld(world); + } + /** Transforms a world rotation to a local rotation. */ + worldToLocalRotation(worldRotation) { + let sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); + return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * MathUtils.radDeg + this.rotation - this.shearX; + } + /** Transforms a local rotation to a world rotation. */ + localToWorldRotation(localRotation) { + localRotation -= this.rotation - this.shearX; + let sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); + return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg; + } + /** Rotates the world transform the specified amount. + *

+ * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and + * {@link #update(Physics)} will need to be called on any child bones, recursively. */ + rotateWorld(degrees) { + degrees *= MathUtils.degRad; + const sin = Math.sin(degrees), cos = Math.cos(degrees); + const ra = this.a, rb = this.b; + this.a = cos * ra - sin * this.c; + this.b = cos * rb - sin * this.d; + this.c = sin * ra + cos * this.c; + this.d = sin * rb + cos * this.d; + } + }; + + // spine-core/src/ConstraintData.ts + var ConstraintData = class { + constructor(name, order, skinRequired) { + this.name = name; + this.order = order; + this.skinRequired = skinRequired; + } + }; + + // spine-core/src/AssetManagerBase.ts + var AssetManagerBase = class { + pathPrefix = ""; + textureLoader; + downloader; + cache; + errors = {}; + toLoad = 0; + loaded = 0; + constructor(textureLoader, pathPrefix = "", downloader = new Downloader(), cache = new AssetCache()) { + this.textureLoader = textureLoader; + this.pathPrefix = pathPrefix; + this.downloader = downloader; + this.cache = cache; + } + start(path) { + this.toLoad++; + return this.pathPrefix + path; + } + success(callback, path, asset) { + this.toLoad--; + this.loaded++; + this.cache.assets[path] = asset; + this.cache.assetsRefCount[path] = (this.cache.assetsRefCount[path] || 0) + 1; + if (callback) callback(path, asset); + } + error(callback, path, message) { + this.toLoad--; + this.loaded++; + this.errors[path] = message; + if (callback) callback(path, message); + } + loadAll() { + let promise = new Promise((resolve, reject) => { + let check = () => { + if (this.isLoadingComplete()) { + if (this.hasErrors()) reject(this.errors); + else resolve(this); + return; + } + requestAnimationFrame(check); + }; + requestAnimationFrame(check); + }); + return promise; + } + setRawDataURI(path, data) { + this.downloader.rawDataUris[this.pathPrefix + path] = data; + } + loadBinary(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadBinary(path, (data) => { + this.success(success, path, data); + resolve(data); + }, (status, responseText) => { + const errorMsg = `Couldn't load binary ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + loadText(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + this.downloader.downloadText(path, (data) => { + this.success(success, path, data); + }, (status, responseText) => { + this.error(error, path, `Couldn't load text ${path}: status ${status}, ${responseText}`); + }); + } + loadJson(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadJson(path, (data) => { + this.success(success, path, data); + resolve(data); + }, (status, responseText) => { + const errorMsg = `Couldn't load JSON ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + reuseAssets(path, success = () => { + }, error = () => { + }) { + const loadedStatus = this.cache.assetsLoaded[path]; + const alreadyExistsOrLoading = loadedStatus !== void 0; + if (alreadyExistsOrLoading) { + this.cache.assetsLoaded[path] = loadedStatus.then((data) => { + data = data instanceof Image || data instanceof ImageBitmap ? this.textureLoader(data) : data; + this.success(success, path, data); + return data; + }).catch((errorMsg) => this.error(error, path, errorMsg)); + } + return alreadyExistsOrLoading; + } + loadTexture(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + let isBrowser = !!(typeof window !== "undefined" && typeof navigator !== "undefined" && window.document); + let isWebWorker = !isBrowser; + if (isWebWorker) { + fetch(path, { mode: "cors" }).then((response) => { + if (response.ok) return response.blob(); + const errorMsg = `Couldn't load image: ${path}`; + this.error(error, path, `Couldn't load image: ${path}`); + reject(errorMsg); + }).then((blob) => { + return blob ? createImageBitmap(blob, { premultiplyAlpha: "none", colorSpaceConversion: "none" }) : null; + }).then((bitmap) => { + if (bitmap) { + const texture = this.createTexture(path, bitmap); + this.success(success, path, texture); + resolve(texture); + } + ; + }); + } else { + let image = new Image(); + if (typeof location === "undefined" || location.protocol !== "file:") + image.crossOrigin = "anonymous"; + image.onload = () => { + const texture = this.createTexture(path, image); + this.success(success, path, texture); + resolve(texture); + }; + image.onerror = () => { + const errorMsg = `Couldn't load image: ${path}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }; + if (this.downloader.rawDataUris[path]) path = this.downloader.rawDataUris[path]; + image.src = path; + } + }); + } + loadTextureAtlas(path, success = () => { + }, error = () => { + }, fileAlias) { + let index = path.lastIndexOf("/"); + let parent = index >= 0 ? path.substring(0, index + 1) : ""; + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadText(path, (atlasText) => { + try { + const atlas = this.createTextureAtlas(path, atlasText); + let toLoad = atlas.pages.length, abort = false; + for (let page of atlas.pages) { + this.loadTexture( + !fileAlias ? parent + page.name : fileAlias[page.name], + (imagePath, texture) => { + if (!abort) { + page.setTexture(texture); + if (--toLoad == 0) { + this.success(success, path, atlas); + resolve(atlas); + } + } + }, + (imagePath, message) => { + if (!abort) { + const errorMsg = `Couldn't load texture ${path} page image: ${imagePath}`; + this.error(error, path, errorMsg); + reject(errorMsg); + } + abort = true; + } + ); + } + } catch (e) { + const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`; + this.error(error, path, errorMsg); + reject(errorMsg); + } + }, (status, responseText) => { + const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + loadTextureAtlasButNoTextures(path, success = () => { + }, error = () => { + }, fileAlias) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadText(path, (atlasText) => { + try { + const atlas = this.createTextureAtlas(path, atlasText); + this.success(success, path, atlas); + resolve(atlas); + } catch (e) { + const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`; + this.error(error, path, errorMsg); + reject(errorMsg); + } + }, (status, responseText) => { + const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + // Promisified versions of load function + async loadBinaryAsync(path) { + return new Promise((resolve, reject) => { + this.loadBinary( + path, + (_, binary) => resolve(binary), + (_, message) => reject(message) + ); + }); + } + async loadJsonAsync(path) { + return new Promise((resolve, reject) => { + this.loadJson( + path, + (_, object) => resolve(object), + (_, message) => reject(message) + ); + }); + } + async loadTextureAsync(path) { + return new Promise((resolve, reject) => { + this.loadTexture( + path, + (_, texture) => resolve(texture), + (_, message) => reject(message) + ); + }); + } + async loadTextureAtlasAsync(path) { + return new Promise((resolve, reject) => { + this.loadTextureAtlas( + path, + (_, atlas) => resolve(atlas), + (_, message) => reject(message) + ); + }); + } + async loadTextureAtlasButNoTexturesAsync(path) { + return new Promise((resolve, reject) => { + this.loadTextureAtlasButNoTextures( + path, + (_, atlas) => resolve(atlas), + (_, message) => reject(message) + ); + }); + } + setCache(cache) { + this.cache = cache; + } + get(path) { + return this.cache.assets[this.pathPrefix + path]; + } + require(path) { + path = this.pathPrefix + path; + let asset = this.cache.assets[path]; + if (asset) return asset; + let error = this.errors[path]; + throw Error("Asset not found: " + path + (error ? "\n" + error : "")); + } + remove(path) { + path = this.pathPrefix + path; + let asset = this.cache.assets[path]; + if (asset.dispose) asset.dispose(); + delete this.cache.assets[path]; + delete this.cache.assetsRefCount[path]; + delete this.cache.assetsLoaded[path]; + return asset; + } + removeAll() { + for (let path in this.cache.assets) { + let asset = this.cache.assets[path]; + if (asset.dispose) asset.dispose(); + } + this.cache.assets = {}; + this.cache.assetsLoaded = {}; + this.cache.assetsRefCount = {}; + } + isLoadingComplete() { + return this.toLoad == 0; + } + getToLoad() { + return this.toLoad; + } + getLoaded() { + return this.loaded; + } + dispose() { + this.removeAll(); + } + // dispose asset only if it's not used by others + disposeAsset(path) { + const asset = this.cache.assets[path]; + if (asset instanceof TextureAtlas) { + asset.dispose(); + return; + } + this.disposeAssetInternal(path); + } + hasErrors() { + return Object.keys(this.errors).length > 0; + } + getErrors() { + return this.errors; + } + disposeAssetInternal(path) { + if (this.cache.assetsRefCount[path] > 0 && --this.cache.assetsRefCount[path] === 0) { + return this.remove(path); + } + } + createTextureAtlas(path, atlasText) { + const atlas = new TextureAtlas(atlasText); + atlas.dispose = () => { + if (this.cache.assetsRefCount[path] <= 0) return; + this.disposeAssetInternal(path); + for (const page of atlas.pages) { + page.texture?.dispose(); + } + }; + return atlas; + } + createTexture(path, image) { + const texture = this.textureLoader(image); + const textureDispose = texture.dispose.bind(texture); + texture.dispose = () => { + if (this.disposeAssetInternal(path)) textureDispose(); + }; + return texture; + } + }; + var AssetCache = class _AssetCache { + assets = {}; + assetsRefCount = {}; + assetsLoaded = {}; + static AVAILABLE_CACHES = /* @__PURE__ */ new Map(); + static getCache(id) { + const cache = _AssetCache.AVAILABLE_CACHES.get(id); + if (cache) return cache; + const newCache = new _AssetCache(); + _AssetCache.AVAILABLE_CACHES.set(id, newCache); + return newCache; + } + async addAsset(path, asset) { + this.assetsLoaded[path] = Promise.resolve(asset); + this.assets[path] = await asset; + } + }; + var Downloader = class { + callbacks = {}; + rawDataUris = {}; + dataUriToString(dataUri) { + if (!dataUri.startsWith("data:")) { + throw new Error("Not a data URI."); + } + let base64Idx = dataUri.indexOf("base64,"); + if (base64Idx != -1) { + base64Idx += "base64,".length; + return atob(dataUri.substr(base64Idx)); + } else { + return dataUri.substr(dataUri.indexOf(",") + 1); + } + } + base64ToUint8Array(base64) { + var binary_string = window.atob(base64); + var len = binary_string.length; + var bytes = new Uint8Array(len); + for (var i = 0; i < len; i++) { + bytes[i] = binary_string.charCodeAt(i); + } + return bytes; + } + dataUriToUint8Array(dataUri) { + if (!dataUri.startsWith("data:")) { + throw new Error("Not a data URI."); + } + let base64Idx = dataUri.indexOf("base64,"); + if (base64Idx == -1) throw new Error("Not a binary data URI."); + base64Idx += "base64,".length; + return this.base64ToUint8Array(dataUri.substr(base64Idx)); + } + downloadText(url, success, error) { + if (this.start(url, success, error)) return; + const rawDataUri = this.rawDataUris[url]; + if (rawDataUri && rawDataUri.startsWith("data:")) { + try { + this.finish(url, 200, this.dataUriToString(rawDataUri)); + } catch (e) { + this.finish(url, 400, JSON.stringify(e)); + } + return; + } + let request = new XMLHttpRequest(); + request.overrideMimeType("text/html"); + request.open("GET", rawDataUri ? rawDataUri : url, true); + let done = () => { + this.finish(url, request.status, request.responseText); + }; + request.onload = done; + request.onerror = done; + request.send(); + } + downloadJson(url, success, error) { + this.downloadText(url, (data) => { + success(JSON.parse(data)); + }, error); + } + downloadBinary(url, success, error) { + if (this.start(url, success, error)) return; + const rawDataUri = this.rawDataUris[url]; + if (rawDataUri && !rawDataUri.includes(".")) { + try { + this.finish(url, 200, this.dataUriToUint8Array(rawDataUri)); + } catch (e) { + this.finish(url, 400, JSON.stringify(e)); + } + return; + } + let request = new XMLHttpRequest(); + request.open("GET", rawDataUri ? rawDataUri : url, true); + request.responseType = "arraybuffer"; + let onerror = () => { + this.finish(url, request.status, request.response); + }; + request.onload = () => { + if (request.status == 200 || request.status == 0) + this.finish(url, 200, new Uint8Array(request.response)); + else + onerror(); + }; + request.onerror = onerror; + request.send(); + } + start(url, success, error) { + let callbacks = this.callbacks[url]; + try { + if (callbacks) return true; + this.callbacks[url] = callbacks = []; + } finally { + callbacks.push(success, error); + } + } + finish(url, status, data) { + let callbacks = this.callbacks[url]; + delete this.callbacks[url]; + let args = status == 200 || status == 0 ? [data] : [status, data]; + for (let i = args.length - 1, n = callbacks.length; i < n; i += 2) + callbacks[i].apply(null, args); + } + }; + + // spine-core/src/Event.ts + var Event = class { + data; + intValue = 0; + floatValue = 0; + stringValue = null; + time = 0; + volume = 0; + balance = 0; + constructor(time, data) { + if (!data) throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + }; + + // spine-core/src/EventData.ts + var EventData = class { + name; + intValue = 0; + floatValue = 0; + stringValue = null; + audioPath = null; + volume = 0; + balance = 0; + constructor(name) { + this.name = name; + } + }; + + // spine-core/src/IkConstraint.ts + var IkConstraint = class { + /** The IK constraint's setup pose data. */ + data; + /** The bones that will be modified by this IK constraint. */ + bones; + /** The bone that is the IK target. */ + target; + /** Controls the bend direction of the IK bones, either 1 or -1. */ + bendDirection = 0; + /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ + compress = false; + /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + * and the parent bone has local nonuniform scale, stretch is not applied. */ + stretch = false; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ + mix = 1; + /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ + softness = 0; + active = false; + constructor(data, skeleton) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let bone = skeleton.findBone(data.bones[i].name); + if (!bone) throw new Error(`Couldn't find bone ${data.bones[i].name}`); + this.bones.push(bone); + } + let target = skeleton.findBone(data.target.name); + if (!target) throw new Error(`Couldn't find bone ${data.target.name}`); + this.target = target; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + } + isActive() { + return this.active; + } + setToSetupPose() { + const data = this.data; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + } + update(physics) { + if (this.mix == 0) return; + let target = this.target; + let bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.data.uniform, this.softness, this.mix); + break; + } + } + /** Applies 1 bone IK. The target is specified in the world coordinate system. */ + apply1(bone, targetX, targetY, compress, stretch, uniform, alpha) { + let p = bone.parent; + if (!p) throw new Error("IK bone must have parent."); + let pa = p.a, pb = p.b, pc = p.c, pd = p.d; + let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; + switch (bone.inherit) { + case 1 /* OnlyTranslation */: + tx = (targetX - bone.worldX) * MathUtils.signum(bone.skeleton.scaleX); + ty = (targetY - bone.worldY) * MathUtils.signum(bone.skeleton.scaleY); + break; + case 2 /* NoRotationOrReflection */: + let s = Math.abs(pa * pd - pb * pc) / Math.max(1e-4, pa * pa + pc * pc); + let sa = pa / bone.skeleton.scaleX; + let sc = pc / bone.skeleton.scaleY; + pb = -sc * s * bone.skeleton.scaleX; + pd = sa * s * bone.skeleton.scaleY; + rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg; + // Fall through + default: + let x = targetX - p.worldX, y = targetY - p.worldY; + let d = pa * pd - pb * pc; + if (Math.abs(d) <= 1e-4) { + tx = 0; + ty = 0; + } else { + tx = (x * pd - y * pb) / d - bone.ax; + ty = (y * pa - x * pc) / d - bone.ay; + } + } + rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg; + if (bone.ascaleX < 0) rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + let sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + switch (bone.inherit) { + case 3 /* NoScale */: + case 4 /* NoScaleOrReflection */: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + } + const b = bone.data.length * sx; + if (b > 1e-4) { + const dd = tx * tx + ty * ty; + if (compress && dd < b * b || stretch && dd > b * b) { + const s = (Math.sqrt(dd) / b - 1) * alpha + 1; + sx *= s; + if (uniform) sy *= s; + } + } + } + bone.updateWorldTransformWith( + bone.ax, + bone.ay, + bone.arotation + rotationIK * alpha, + sx, + sy, + bone.ashearX, + bone.ashearY + ); + } + /** Applies 2 bone IK. The target is specified in the world coordinate system. + * @param child A direct descendant of the parent bone. */ + apply2(parent, child, targetX, targetY, bendDir, stretch, uniform, softness, alpha) { + if (parent.inherit != 0 /* Normal */ || child.inherit != 0 /* Normal */) return; + let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX; + let os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } else + os2 = 0; + let cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d; + let u = Math.abs(psx - psy) <= 1e-4; + if (!u || stretch) { + cy = 0; + cwx = a * cx + parent.worldX; + cwy = c * cx + parent.worldY; + } else { + cy = child.ay; + cwx = a * cx + b * cy + parent.worldX; + cwy = c * cx + d * cy + parent.worldY; + } + let pp = parent.parent; + if (!pp) throw new Error("IK parent must itself have a parent."); + a = pp.a; + b = pp.b; + c = pp.c; + d = pp.d; + let id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY; + id = Math.abs(id) <= 1e-4 ? 0 : 1 / id; + let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; + if (l1 < 1e-4) { + this.apply1(parent, targetX, targetY, false, stretch, false, alpha); + child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + return; + } + x = targetX - pp.worldX; + y = targetY - pp.worldY; + let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; + let dd = tx * tx + ty * ty; + if (softness != 0) { + softness *= psx * (csx + 1) * 0.5; + let td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; + if (sd > 0) { + let p = Math.min(1, sd / (softness * 2)) - 1; + p = (sd - softness * (1 - p * p)) / td; + tx -= p * tx; + ty -= p * ty; + dd = tx * tx + ty * ty; + } + } + outer: + if (u) { + l2 *= psx; + let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) { + cos = -1; + a2 = Math.PI * bendDir; + } else if (cos > 1) { + cos = 1; + a2 = 0; + if (stretch) { + a = (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + sx *= a; + if (uniform) sy *= a; + } + } else + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } else { + a = psx * l2; + b = psy * l2; + let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + let c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + let q = Math.sqrt(d); + if (c1 < 0) q = -q; + q = -(c1 + q) * 0.5; + let r0 = q / c2, r1 = c / q; + let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + r0 = dd - r * r; + if (r0 >= 0) { + y = Math.sqrt(r0) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + let minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) * 0.5) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + let os = Math.atan2(cy, cx) * s2; + let rotation = parent.arotation; + a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, sy, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + } + }; + + // spine-core/src/IkConstraintData.ts + var IkConstraintData = class extends ConstraintData { + /** The bones that are constrained by this IK constraint. */ + bones = new Array(); + /** The bone that is the IK target. */ + _target = null; + set target(boneData) { + this._target = boneData; + } + get target() { + if (!this._target) throw new Error("BoneData not set."); + else return this._target; + } + /** Controls the bend direction of the IK bones, either 1 or -1. */ + bendDirection = 0; + /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ + compress = false; + /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + * and the parent bone has local nonuniform scale, stretch is not applied. */ + stretch = false; + /** When true, only a single bone is being constrained, and {@link #getCompress()} or {@link #getStretch()} is used, the bone + * is scaled on both the X and Y axes. */ + uniform = false; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ + mix = 0; + /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ + softness = 0; + constructor(name) { + super(name, 0, false); + } + }; + + // spine-core/src/PathConstraintData.ts + var PathConstraintData = class extends ConstraintData { + /** The bones that will be modified by this path constraint. */ + bones = new Array(); + /** The slot whose path attachment will be used to constrained the bones. */ + _target = null; + set target(slotData) { + this._target = slotData; + } + get target() { + if (!this._target) throw new Error("SlotData not set."); + else return this._target; + } + /** The mode for positioning the first bone on the path. */ + positionMode = 0 /* Fixed */; + /** The mode for positioning the bones after the first bone on the path. */ + spacingMode = 1 /* Fixed */; + /** The mode for adjusting the rotation of the bones. */ + rotateMode = 1 /* Chain */; + /** An offset added to the constrained bone rotation. */ + offsetRotation = 0; + /** The position along the path. */ + position = 0; + /** The spacing between bones. */ + spacing = 0; + mixRotate = 0; + mixX = 0; + mixY = 0; + constructor(name) { + super(name, 0, false); + } + }; + var PositionMode = /* @__PURE__ */ ((PositionMode2) => { + PositionMode2[PositionMode2["Fixed"] = 0] = "Fixed"; + PositionMode2[PositionMode2["Percent"] = 1] = "Percent"; + return PositionMode2; + })(PositionMode || {}); + var SpacingMode = /* @__PURE__ */ ((SpacingMode2) => { + SpacingMode2[SpacingMode2["Length"] = 0] = "Length"; + SpacingMode2[SpacingMode2["Fixed"] = 1] = "Fixed"; + SpacingMode2[SpacingMode2["Percent"] = 2] = "Percent"; + SpacingMode2[SpacingMode2["Proportional"] = 3] = "Proportional"; + return SpacingMode2; + })(SpacingMode || {}); + var RotateMode = /* @__PURE__ */ ((RotateMode2) => { + RotateMode2[RotateMode2["Tangent"] = 0] = "Tangent"; + RotateMode2[RotateMode2["Chain"] = 1] = "Chain"; + RotateMode2[RotateMode2["ChainScale"] = 2] = "ChainScale"; + return RotateMode2; + })(RotateMode || {}); + + // spine-core/src/PathConstraint.ts + var PathConstraint = class _PathConstraint { + static NONE = -1; + static BEFORE = -2; + static AFTER = -3; + static epsilon = 1e-5; + /** The path constraint's setup pose data. */ + data; + /** The bones that will be modified by this path constraint. */ + bones; + /** The slot whose path attachment will be used to constrained the bones. */ + target; + /** The position along the path. */ + position = 0; + /** The spacing between bones. */ + spacing = 0; + mixRotate = 0; + mixX = 0; + mixY = 0; + spaces = new Array(); + positions = new Array(); + world = new Array(); + curves = new Array(); + lengths = new Array(); + segments = new Array(); + active = false; + constructor(data, skeleton) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0, n = data.bones.length; i < n; i++) { + let bone = skeleton.findBone(data.bones[i].name); + if (!bone) throw new Error(`Couldn't find bone ${data.bones[i].name}.`); + this.bones.push(bone); + } + let target = skeleton.findSlot(data.target.name); + if (!target) throw new Error(`Couldn't find target bone ${data.target.name}`); + this.target = target; + this.position = data.position; + this.spacing = data.spacing; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + } + isActive() { + return this.active; + } + setToSetupPose() { + const data = this.data; + this.position = data.position; + this.spacing = data.spacing; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + } + update(physics) { + let attachment = this.target.getAttachment(); + if (!(attachment instanceof PathAttachment)) return; + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; + if (mixRotate == 0 && mixX == 0 && mixY == 0) return; + let data = this.data; + let tangents = data.rotateMode == 0 /* Tangent */, scale = data.rotateMode == 2 /* ChainScale */; + let bones = this.bones; + let boneCount = bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + let spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = scale ? this.lengths = Utils.setArraySize(this.lengths, boneCount) : []; + let spacing = this.spacing; + switch (data.spacingMode) { + case 2 /* Percent */: + if (scale) { + for (let i = 0, n = spacesCount - 1; i < n; i++) { + let bone = bones[i]; + let setupLength = bone.data.length; + let x = setupLength * bone.a, y = setupLength * bone.c; + lengths[i] = Math.sqrt(x * x + y * y); + } + } + Utils.arrayFill(spaces, 1, spacesCount, spacing); + break; + case 3 /* Proportional */: + let sum = 0; + for (let i = 0, n = spacesCount - 1; i < n; ) { + let bone = bones[i]; + let setupLength = bone.data.length; + if (setupLength < _PathConstraint.epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = spacing; + } else { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + if (scale) lengths[i] = length; + spaces[++i] = length; + sum += length; + } + } + if (sum > 0) { + sum = spacesCount / sum * spacing; + for (let i = 1; i < spacesCount; i++) + spaces[i] *= sum; + } + break; + default: + let lengthSpacing = data.spacingMode == 0 /* Length */; + for (let i = 0, n = spacesCount - 1; i < n; ) { + let bone = bones[i]; + let setupLength = bone.data.length; + if (setupLength < _PathConstraint.epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = spacing; + } else { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + if (scale) lengths[i] = length; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + } + let positions = this.computeWorldPositions(attachment, spacesCount, tangents); + let boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + let tip = false; + if (offsetRotation == 0) + tip = data.rotateMode == 1 /* Chain */; + else { + tip = false; + let p = this.target.bone; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; + } + for (let i = 0, p = 3; i < boneCount; i++, p += 3) { + let bone = bones[i]; + bone.worldX += (boneX - bone.worldX) * mixX; + bone.worldY += (boneY - bone.worldY) * mixY; + let x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + let length = lengths[i]; + if (length != 0) { + let s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1; + bone.a *= s; + bone.c *= s; + } + } + boneX = x; + boneY = y; + if (mixRotate > 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + let length = bone.data.length; + boneX += (length * (cos * a - sin * c) - dx) * mixRotate; + boneY += (length * (sin * a + cos * c) - dy) * mixRotate; + } else { + r += offsetRotation; + } + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= mixRotate; + cos = Math.cos(r); + sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + bone.updateAppliedTransform(); + } + } + computeWorldPositions(path, spacesCount, tangents) { + let target = this.target; + let position = this.position; + let spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = this.world; + let closed2 = path.closed; + let verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = _PathConstraint.NONE; + if (!path.constantSpeed) { + let lengths = path.lengths; + curveCount -= closed2 ? 1 : 2; + let pathLength2 = lengths[curveCount]; + if (this.data.positionMode == 1 /* Percent */) position *= pathLength2; + let multiplier2; + switch (this.data.spacingMode) { + case 2 /* Percent */: + multiplier2 = pathLength2; + break; + case 3 /* Proportional */: + multiplier2 = pathLength2 / spacesCount; + break; + default: + multiplier2 = 1; + } + world = Utils.setArraySize(this.world, 8); + for (let i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i] * multiplier2; + position += space; + let p = position; + if (closed2) { + p %= pathLength2; + if (p < 0) p += pathLength2; + curve = 0; + } else if (p < 0) { + if (prevCurve != _PathConstraint.BEFORE) { + prevCurve = _PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } else if (p > pathLength2) { + if (prevCurve != _PathConstraint.AFTER) { + prevCurve = _PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength2, world, 0, out, o); + continue; + } + for (; ; curve++) { + let length = lengths[curve]; + if (p > length) continue; + if (curve == 0) + p /= length; + else { + let prev = lengths[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed2 && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition( + p, + world[0], + world[1], + world[2], + world[3], + world[4], + world[5], + world[6], + world[7], + out, + o, + tangents || i > 0 && space == 0 + ); + } + return out; + } + if (closed2) { + verticesLength += 2; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } else { + curveCount--; + verticesLength -= 4; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + let curves = Utils.setArraySize(this.curves, curveCount); + let pathLength = 0; + let x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + let tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (let i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (this.data.positionMode == 1 /* Percent */) position *= pathLength; + let multiplier; + switch (this.data.spacingMode) { + case 2 /* Percent */: + multiplier = pathLength; + break; + case 3 /* Proportional */: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + } + let segments = this.segments; + let curveLength = 0; + for (let i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i] * multiplier; + position += space; + let p = position; + if (closed2) { + p %= pathLength; + if (p < 0) p += pathLength; + curve = 0; + } else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + for (; ; curve++) { + let length = curves[curve]; + if (p > length) continue; + if (curve == 0) + p /= length; + else { + let prev = curves[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + let ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 6e-3; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 6e-3; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + p *= curveLength; + for (; ; segment++) { + let length = segments[segment]; + if (p > length) continue; + if (segment == 0) + p /= length; + else { + let prev = segments[segment - 1]; + p = segment + (p - prev) / (length - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || i > 0 && space == 0); + } + return out; + } + addBeforePosition(p, temp, i, out, o) { + let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addAfterPosition(p, temp, i, out, o) { + let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) { + out[o] = x1; + out[o + 1] = y1; + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + return; + } + let tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + let ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + let x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) { + if (p < 1e-3) + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + else + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + } + }; + + // spine-core/src/PhysicsConstraint.ts + var PhysicsConstraint = class { + data; + _bone = null; + /** The bone constrained by this physics constraint. */ + set bone(bone) { + this._bone = bone; + } + get bone() { + if (!this._bone) throw new Error("Bone not set."); + else return this._bone; + } + inertia = 0; + strength = 0; + damping = 0; + massInverse = 0; + wind = 0; + gravity = 0; + mix = 0; + _reset = true; + ux = 0; + uy = 0; + cx = 0; + cy = 0; + tx = 0; + ty = 0; + xOffset = 0; + xVelocity = 0; + yOffset = 0; + yVelocity = 0; + rotateOffset = 0; + rotateVelocity = 0; + scaleOffset = 0; + scaleVelocity = 0; + active = false; + skeleton; + remaining = 0; + lastTime = 0; + constructor(data, skeleton) { + this.data = data; + this.skeleton = skeleton; + this.bone = skeleton.bones[data.bone.index]; + this.inertia = data.inertia; + this.strength = data.strength; + this.damping = data.damping; + this.massInverse = data.massInverse; + this.wind = data.wind; + this.gravity = data.gravity; + this.mix = data.mix; + } + reset() { + this.remaining = 0; + this.lastTime = this.skeleton.time; + this._reset = true; + this.xOffset = 0; + this.xVelocity = 0; + this.yOffset = 0; + this.yVelocity = 0; + this.rotateOffset = 0; + this.rotateVelocity = 0; + this.scaleOffset = 0; + this.scaleVelocity = 0; + } + setToSetupPose() { + const data = this.data; + this.inertia = data.inertia; + this.strength = data.strength; + this.damping = data.damping; + this.massInverse = data.massInverse; + this.wind = data.wind; + this.gravity = data.gravity; + this.mix = data.mix; + } + isActive() { + return this.active; + } + /** Applies the constraint to the constrained bones. */ + update(physics) { + const mix = this.mix; + if (mix == 0) return; + const x = this.data.x > 0, y = this.data.y > 0, rotateOrShearX = this.data.rotate > 0 || this.data.shearX > 0, scaleX = this.data.scaleX > 0; + const bone = this.bone; + const l = bone.data.length; + switch (physics) { + case 0 /* none */: + return; + case 1 /* reset */: + this.reset(); + // Fall through. + case 2 /* update */: + const skeleton = this.skeleton; + const delta = Math.max(this.skeleton.time - this.lastTime, 0); + this.remaining += delta; + this.lastTime = skeleton.time; + const bx = bone.worldX, by = bone.worldY; + if (this._reset) { + this._reset = false; + this.ux = bx; + this.uy = by; + } else { + let a = this.remaining, i = this.inertia, t = this.data.step, f = this.skeleton.data.referenceScale, d = -1; + let qx = this.data.limit * delta, qy = qx * Math.abs(skeleton.scaleY); + qx *= Math.abs(skeleton.scaleX); + if (x || y) { + if (x) { + const u = (this.ux - bx) * i; + this.xOffset += u > qx ? qx : u < -qx ? -qx : u; + this.ux = bx; + } + if (y) { + const u = (this.uy - by) * i; + this.yOffset += u > qy ? qy : u < -qy ? -qy : u; + this.uy = by; + } + if (a >= t) { + d = Math.pow(this.damping, 60 * t); + const m = this.massInverse * t, e = this.strength, w = this.wind * f * skeleton.scaleX, g = this.gravity * f * skeleton.scaleY; + do { + if (x) { + this.xVelocity += (w - this.xOffset * e) * m; + this.xOffset += this.xVelocity * t; + this.xVelocity *= d; + } + if (y) { + this.yVelocity -= (g + this.yOffset * e) * m; + this.yOffset += this.yVelocity * t; + this.yVelocity *= d; + } + a -= t; + } while (a >= t); + } + if (x) bone.worldX += this.xOffset * mix * this.data.x; + if (y) bone.worldY += this.yOffset * mix * this.data.y; + } + if (rotateOrShearX || scaleX) { + let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0; + let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY; + if (dx > qx) + dx = qx; + else if (dx < -qx) + dx = -qx; + if (dy > qy) + dy = qy; + else if (dy < -qy) + dy = -qy; + if (rotateOrShearX) { + mr = (this.data.rotate + this.data.shearX) * mix; + let r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr; + this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i; + r = this.rotateOffset * mr + ca; + c = Math.cos(r); + s = Math.sin(r); + if (scaleX) { + r = l * bone.getWorldScaleX(); + if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r; + } + } else { + c = Math.cos(ca); + s = Math.sin(ca); + const r = l * bone.getWorldScaleX(); + if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r; + } + a = this.remaining; + if (a >= t) { + if (d == -1) d = Math.pow(this.damping, 60 * t); + const m = this.massInverse * t, e = this.strength, w = this.wind, g = Skeleton.yDown ? -this.gravity : this.gravity, h = l / f; + while (true) { + a -= t; + if (scaleX) { + this.scaleVelocity += (w * c - g * s - this.scaleOffset * e) * m; + this.scaleOffset += this.scaleVelocity * t; + this.scaleVelocity *= d; + } + if (rotateOrShearX) { + this.rotateVelocity -= ((w * s + g * c) * h + this.rotateOffset * e) * m; + this.rotateOffset += this.rotateVelocity * t; + this.rotateVelocity *= d; + if (a < t) break; + const r = this.rotateOffset * mr + ca; + c = Math.cos(r); + s = Math.sin(r); + } else if (a < t) + break; + } + } + } + this.remaining = a; + } + this.cx = bone.worldX; + this.cy = bone.worldY; + break; + case 3 /* pose */: + if (x) bone.worldX += this.xOffset * mix * this.data.x; + if (y) bone.worldY += this.yOffset * mix * this.data.y; + } + if (rotateOrShearX) { + let o = this.rotateOffset * mix, s = 0, c = 0, a = 0; + if (this.data.shearX > 0) { + let r = 0; + if (this.data.rotate > 0) { + r = o * this.data.rotate; + s = Math.sin(r); + c = Math.cos(r); + a = bone.b; + bone.b = c * a - s * bone.d; + bone.d = s * a + c * bone.d; + } + r += o * this.data.shearX; + s = Math.sin(r); + c = Math.cos(r); + a = bone.a; + bone.a = c * a - s * bone.c; + bone.c = s * a + c * bone.c; + } else { + o *= this.data.rotate; + s = Math.sin(o); + c = Math.cos(o); + a = bone.a; + bone.a = c * a - s * bone.c; + bone.c = s * a + c * bone.c; + a = bone.b; + bone.b = c * a - s * bone.d; + bone.d = s * a + c * bone.d; + } + } + if (scaleX) { + const s = 1 + this.scaleOffset * mix * this.data.scaleX; + bone.a *= s; + bone.c *= s; + } + if (physics != 3 /* pose */) { + this.tx = l * bone.a; + this.ty = l * bone.c; + } + bone.updateAppliedTransform(); + } + /** Translates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone moved an additional + * amount in world space. */ + translate(x, y) { + this.ux -= x; + this.uy -= y; + this.cx -= x; + this.cy -= y; + } + /** Rotates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone rotated around the + * specified point in world space. */ + rotate(x, y, degrees) { + const r = degrees * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r); + const dx = this.cx - x, dy = this.cy - y; + this.translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy); + } + }; + + // spine-core/src/Slot.ts + var Slot = class { + /** The slot's setup pose data. */ + data; + /** The bone this slot belongs to. */ + bone; + /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two + * color tinting. */ + color; + /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark + * color's alpha is not used. */ + darkColor = null; + attachment = null; + attachmentState = 0; + /** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the + * {@link Sequence#getSetupIndex()}. */ + sequenceIndex = -1; + /** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a + * weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. + * + * See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */ + deform = new Array(); + constructor(data, bone) { + if (!data) throw new Error("data cannot be null."); + if (!bone) throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new Color(); + this.darkColor = !data.darkColor ? null : new Color(); + this.setToSetupPose(); + } + /** The skeleton this slot belongs to. */ + getSkeleton() { + return this.bone.skeleton; + } + /** The current attachment for the slot, or null if the slot has no attachment. */ + getAttachment() { + return this.attachment; + } + /** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}. + * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the + * specified attachment. */ + setAttachment(attachment) { + if (this.attachment == attachment) return; + if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment) || attachment.timelineAttachment != this.attachment.timelineAttachment) { + this.deform.length = 0; + } + this.attachment = attachment; + this.sequenceIndex = -1; + } + /** Sets this slot to the setup pose. */ + setToSetupPose() { + this.color.setFromColor(this.data.color); + if (this.darkColor) this.darkColor.setFromColor(this.data.darkColor); + if (!this.data.attachmentName) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + } + }; + + // spine-core/src/TransformConstraint.ts + var TransformConstraint = class { + /** The transform constraint's setup pose data. */ + data; + /** The bones that will be modified by this transform constraint. */ + bones; + /** The target bone whose world transform will be copied to the constrained bones. */ + target; + mixRotate = 0; + mixX = 0; + mixY = 0; + mixScaleX = 0; + mixScaleY = 0; + mixShearY = 0; + temp = new Vector2(); + active = false; + constructor(data, skeleton) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let bone = skeleton.findBone(data.bones[i].name); + if (!bone) throw new Error(`Couldn't find bone ${data.bones[i].name}.`); + this.bones.push(bone); + } + let target = skeleton.findBone(data.target.name); + if (!target) throw new Error(`Couldn't find target bone ${data.target.name}.`); + this.target = target; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + this.mixScaleX = data.mixScaleX; + this.mixScaleY = data.mixScaleY; + this.mixShearY = data.mixShearY; + } + isActive() { + return this.active; + } + setToSetupPose() { + const data = this.data; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + this.mixScaleX = data.mixScaleX; + this.mixScaleY = data.mixScaleY; + this.mixShearY = data.mixShearY; + } + update(physics) { + if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleY == 0 && this.mixShearY == 0) return; + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + } + applyAbsoluteWorld() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let translate = mixX != 0 || mixY != 0; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect; + let offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (mixRotate != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= mixRotate; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + if (translate) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += (temp.x - bone.worldX) * mixX; + bone.worldY += (temp.y - bone.worldY) * mixY; + } + if (mixScaleX != 0) { + let s = Math.sqrt(bone.a * bone.a + bone.c * bone.c); + if (s != 0) s = (s + (Math.sqrt(ta * ta + tc * tc) - s + this.data.offsetScaleX) * mixScaleX) / s; + bone.a *= s; + bone.c *= s; + } + if (mixScaleY != 0) { + let s = Math.sqrt(bone.b * bone.b + bone.d * bone.d); + if (s != 0) s = (s + (Math.sqrt(tb * tb + td * td) - s + this.data.offsetScaleY) * mixScaleY) / s; + bone.b *= s; + bone.d *= s; + } + if (mixShearY > 0) { + let b = bone.b, d = bone.d; + let by = Math.atan2(d, b); + let r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a)); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r = by + (r + offsetShearY) * mixShearY; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + } + bone.updateAppliedTransform(); + } + } + applyRelativeWorld() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let translate = mixX != 0 || mixY != 0; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (mixRotate != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= mixRotate; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + if (translate) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += temp.x * mixX; + bone.worldY += temp.y * mixY; + } + if (mixScaleX != 0) { + let s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * mixScaleX + 1; + bone.a *= s; + bone.c *= s; + } + if (mixScaleY != 0) { + let s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * mixScaleY + 1; + bone.b *= s; + bone.d *= s; + } + if (mixShearY > 0) { + let r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + let b = bone.b, d = bone.d; + r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * mixShearY; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + } + bone.updateAppliedTransform(); + } + } + applyAbsoluteLocal() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let target = this.target; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let rotation = bone.arotation; + if (mixRotate != 0) rotation += (target.arotation - rotation + this.data.offsetRotation) * mixRotate; + let x = bone.ax, y = bone.ay; + x += (target.ax - x + this.data.offsetX) * mixX; + y += (target.ay - y + this.data.offsetY) * mixY; + let scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (mixScaleX != 0 && scaleX != 0) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * mixScaleX) / scaleX; + if (mixScaleY != 0 && scaleY != 0) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * mixScaleY) / scaleY; + let shearY = bone.ashearY; + if (mixShearY != 0) shearY += (target.ashearY - shearY + this.data.offsetShearY) * mixShearY; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + applyRelativeLocal() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let target = this.target; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate; + let x = bone.ax + (target.ax + this.data.offsetX) * mixX; + let y = bone.ay + (target.ay + this.data.offsetY) * mixY; + let scaleX = bone.ascaleX * ((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX + 1); + let scaleY = bone.ascaleY * ((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY + 1); + let shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + }; + + // spine-core/src/Skeleton.ts + var Skeleton = class _Skeleton { + static quadTriangles = [0, 1, 2, 2, 3, 0]; + static yDown = false; + /** The skeleton's setup pose data. */ + data; + /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ + bones; + /** The skeleton's slots in the setup pose draw order. */ + slots; + /** The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. */ + drawOrder; + /** The skeleton's IK constraints. */ + ikConstraints; + /** The skeleton's transform constraints. */ + transformConstraints; + /** The skeleton's path constraints. */ + pathConstraints; + /** The skeleton's physics constraints. */ + physicsConstraints; + /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */ + _updateCache = new Array(); + /** The skeleton's current skin. May be null. */ + skin = null; + /** The color to tint all the skeleton's attachments. */ + color; + /** Scales the entire skeleton on the X axis. This affects all bones, even if the bone's transform mode disallows scale + * inheritance. */ + scaleX = 1; + /** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale + * inheritance. */ + _scaleY = 1; + get scaleY() { + return _Skeleton.yDown ? -this._scaleY : this._scaleY; + } + set scaleY(scaleY) { + this._scaleY = scaleY; + } + /** Sets the skeleton X position, which is added to the root bone worldX position. */ + x = 0; + /** Sets the skeleton Y position, which is added to the root bone worldY position. */ + y = 0; + /** Returns the skeleton's time. This is used for time-based manipulations, such as {@link PhysicsConstraint}. + *

+ * See {@link #update(float)}. */ + time = 0; + constructor(data) { + if (!data) throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let boneData = data.bones[i]; + let bone; + if (!boneData.parent) + bone = new Bone(boneData, this, null); + else { + let parent = this.bones[boneData.parent.index]; + bone = new Bone(boneData, this, parent); + parent.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (let i = 0; i < data.slots.length; i++) { + let slotData = data.slots[i]; + let bone = this.bones[slotData.boneData.index]; + let slot = new Slot(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (let i = 0; i < data.ikConstraints.length; i++) { + let ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new IkConstraint(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (let i = 0; i < data.transformConstraints.length; i++) { + let transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new TransformConstraint(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (let i = 0; i < data.pathConstraints.length; i++) { + let pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new PathConstraint(pathConstraintData, this)); + } + this.physicsConstraints = new Array(); + for (let i = 0; i < data.physicsConstraints.length; i++) { + let physicsConstraintData = data.physicsConstraints[i]; + this.physicsConstraints.push(new PhysicsConstraint(physicsConstraintData, this)); + } + this.color = new Color(1, 1, 1, 1); + this.updateCache(); + } + /** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones, + * constraints, or weighted path attachments are added or removed. */ + updateCache() { + let updateCache = this._updateCache; + updateCache.length = 0; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (this.skin) { + let skinBones = this.skin.bones; + for (let i = 0, n = this.skin.bones.length; i < n; i++) { + let bone = this.bones[skinBones[i].index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone); + } + } + let ikConstraints = this.ikConstraints; + let transformConstraints = this.transformConstraints; + let pathConstraints = this.pathConstraints; + let physicsConstraints = this.physicsConstraints; + let ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length, physicsCount = this.physicsConstraints.length; + let constraintCount = ikCount + transformCount + pathCount + physicsCount; + outer: + for (let i = 0; i < constraintCount; i++) { + for (let ii = 0; ii < ikCount; ii++) { + let constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < transformCount; ii++) { + let constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < pathCount; ii++) { + let constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < physicsCount; ii++) { + const constraint = physicsConstraints[ii]; + if (constraint.data.order == i) { + this.sortPhysicsConstraint(constraint); + continue outer; + } + } + } + for (let i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + } + sortIkConstraint(constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || this.skin && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + let target = constraint.target; + this.sortBone(target); + let constrained = constraint.bones; + let parent = constrained[0]; + this.sortBone(parent); + if (constrained.length == 1) { + this._updateCache.push(constraint); + this.sortReset(parent.children); + } else { + let child = constrained[constrained.length - 1]; + this.sortBone(child); + this._updateCache.push(constraint); + this.sortReset(parent.children); + child.sorted = true; + } + } + sortPathConstraint(constraint) { + constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || this.skin && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + let slot = constraint.target; + let slotIndex = slot.data.index; + let slotBone = slot.bone; + if (this.skin) this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (let i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + let attachment = slot.getAttachment(); + if (attachment instanceof PathAttachment) this.sortPathConstraintAttachmentWith(attachment, slotBone); + let constrained = constraint.bones; + let boneCount = constrained.length; + for (let i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (let i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (let i = 0; i < boneCount; i++) + constrained[i].sorted = true; + } + sortTransformConstraint(constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || this.skin && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + this.sortBone(constraint.target); + let constrained = constraint.bones; + let boneCount = constrained.length; + if (constraint.data.local) { + for (let i = 0; i < boneCount; i++) { + let child = constrained[i]; + this.sortBone(child.parent); + this.sortBone(child); + } + } else { + for (let i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (let i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (let i = 0; i < boneCount; i++) + constrained[i].sorted = true; + } + sortPathConstraintAttachment(skin, slotIndex, slotBone) { + let attachments = skin.attachments[slotIndex]; + if (!attachments) return; + for (let key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + } + sortPathConstraintAttachmentWith(attachment, slotBone) { + if (!(attachment instanceof PathAttachment)) return; + let pathBones = attachment.bones; + if (!pathBones) + this.sortBone(slotBone); + else { + let bones = this.bones; + for (let i = 0, n = pathBones.length; i < n; ) { + let nn = pathBones[i++]; + nn += i; + while (i < nn) + this.sortBone(bones[pathBones[i++]]); + } + } + } + sortPhysicsConstraint(constraint) { + const bone = constraint.bone; + constraint.active = bone.active && (!constraint.data.skinRequired || this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + this.sortBone(bone); + this._updateCache.push(constraint); + this.sortReset(bone.children); + bone.sorted = true; + } + sortBone(bone) { + if (!bone) return; + if (bone.sorted) return; + let parent = bone.parent; + if (parent) this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + } + sortReset(bones) { + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.active) continue; + if (bone.sorted) this.sortReset(bone.children); + bone.sorted = false; + } + } + /** Updates the world transform for each bone and applies all constraints. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. */ + updateWorldTransform(physics) { + if (physics === void 0 || physics === null) throw new Error("physics is undefined"); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + } + let updateCache = this._updateCache; + for (let i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(physics); + } + updateWorldTransformWith(physics, parent) { + if (!parent) throw new Error("parent cannot be null."); + let bones = this.bones; + for (let i = 1, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + } + let rootBone = this.getRootBone(); + if (!rootBone) throw new Error("Root bone must not be null."); + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + rootBone.worldX = pa * this.x + pb * this.y + parent.worldX; + rootBone.worldY = pc * this.x + pd * this.y + parent.worldY; + const rx = (rootBone.rotation + rootBone.shearX) * MathUtils.degRad; + const ry = (rootBone.rotation + 90 + rootBone.shearY) * MathUtils.degRad; + const la = Math.cos(rx) * rootBone.scaleX; + const lb = Math.cos(ry) * rootBone.scaleY; + const lc = Math.sin(rx) * rootBone.scaleX; + const ld = Math.sin(ry) * rootBone.scaleY; + rootBone.a = (pa * la + pb * lc) * this.scaleX; + rootBone.b = (pa * lb + pb * ld) * this.scaleX; + rootBone.c = (pc * la + pd * lc) * this.scaleY; + rootBone.d = (pc * lb + pd * ld) * this.scaleY; + let updateCache = this._updateCache; + for (let i = 0, n = updateCache.length; i < n; i++) { + let updatable = updateCache[i]; + if (updatable != rootBone) updatable.update(physics); + } + } + /** Sets the bones, constraints, and slots to their setup pose values. */ + setToSetupPose() { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + } + /** Sets the bones and constraints to their setup pose values. */ + setBonesToSetupPose() { + for (const bone of this.bones) bone.setToSetupPose(); + for (const constraint of this.ikConstraints) constraint.setToSetupPose(); + for (const constraint of this.transformConstraints) constraint.setToSetupPose(); + for (const constraint of this.pathConstraints) constraint.setToSetupPose(); + for (const constraint of this.physicsConstraints) constraint.setToSetupPose(); + } + /** Sets the slots and draw order to their setup pose values. */ + setSlotsToSetupPose() { + let slots = this.slots; + Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (let i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + } + /** @returns May return null. */ + getRootBone() { + if (this.bones.length == 0) return null; + return this.bones[0]; + } + /** @returns May be null. */ + findBone(boneName) { + if (!boneName) throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.data.name == boneName) return bone; + } + return null; + } + /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it + * repeatedly. + * @returns May be null. */ + findSlot(slotName) { + if (!slotName) throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) return slot; + } + return null; + } + /** Sets a skin by name. + * + * See {@link #setSkin()}. */ + setSkinByName(skinName) { + let skin = this.data.findSkin(skinName); + if (!skin) throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + } + /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#defaultSkin default skin}. If the + * skin is changed, {@link #updateCache()} is called. + * + * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no + * old skin, each slot's setup mode attachment is attached from the new skin. + * + * After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling + * {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the + * skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. + * @param newSkin May be null. */ + setSkin(newSkin) { + if (newSkin == this.skin) return; + if (newSkin) { + if (this.skin) + newSkin.attachAll(this, this.skin); + else { + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + let name = slot.data.attachmentName; + if (name) { + let attachment = newSkin.getAttachment(i, name); + if (attachment) slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + this.updateCache(); + } + /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment + * name. + * + * See {@link #getAttachment()}. + * @returns May be null. */ + getAttachmentByName(slotName, attachmentName) { + let slot = this.data.findSlot(slotName); + if (!slot) throw new Error(`Can't find slot with name ${slotName}`); + return this.getAttachment(slot.index, attachmentName); + } + /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and + * attachment name. First the skin is checked and if the attachment was not found, the default skin is checked. + * + * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. + * @returns May be null. */ + getAttachment(slotIndex, attachmentName) { + if (!attachmentName) throw new Error("attachmentName cannot be null."); + if (this.skin) { + let attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment) return attachment; + } + if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + } + /** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with + * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}. + * @param attachmentName May be null to clear the slot's attachment. */ + setAttachment(slotName, attachmentName) { + if (!slotName) throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) { + let attachment = null; + if (attachmentName) { + attachment = this.getAttachment(i, attachmentName); + if (!attachment) throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + } + /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method + * than to call it repeatedly. + * @return May be null. */ + findIkConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + return this.ikConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of + * this method than to call it repeatedly. + * @return May be null. */ + findTransformConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + return this.transformConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method + * than to call it repeatedly. + * @return May be null. */ + findPathConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + return this.pathConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this + * method than to call it repeatedly. */ + findPhysicsConstraint(constraintName) { + if (constraintName == null) throw new Error("constraintName cannot be null."); + return this.physicsConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose as `{ x: number, y: number, width: number, height: number }`. + * Note that this method will create temporary objects which can add to garbage collection pressure. Use `getBounds()` if garbage collection is a concern. */ + getBoundsRect(clipper) { + let offset = new Vector2(); + let size = new Vector2(); + this.getBounds(offset, size, void 0, clipper); + return { x: offset.x, y: offset.y, width: size.x, height: size.y }; + } + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB. + * @param size An output value, the width and height of the AABB. + * @param temp Working memory to temporarily store attachments' computed world vertices. + * @param clipper {@link SkeletonClipping} to use. If null, no clipping is applied. */ + getBounds(offset, size, temp = new Array(2), clipper = null) { + if (!offset) throw new Error("offset cannot be null."); + if (!size) throw new Error("size cannot be null."); + let drawOrder = this.drawOrder; + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + if (!slot.bone.active) continue; + let verticesLength = 0; + let vertices = null; + let triangles = null; + let attachment = slot.getAttachment(); + if (attachment instanceof RegionAttachment) { + verticesLength = 8; + vertices = Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot, vertices, 0, 2); + triangles = _Skeleton.quadTriangles; + } else if (attachment instanceof MeshAttachment) { + let mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + triangles = mesh.triangles; + } else if (attachment instanceof ClippingAttachment && clipper != null) { + clipper.clipStart(slot, attachment); + continue; + } + if (vertices && triangles) { + if (clipper != null && clipper.isClipping()) { + clipper.clipTriangles(vertices, triangles, triangles.length); + vertices = clipper.clippedVertices; + verticesLength = clipper.clippedVertices.length; + } + for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) { + let x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + if (clipper != null) clipper.clipEndWithSlot(slot); + } + if (clipper != null) clipper.clipEnd(); + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + } + /** Increments the skeleton's {@link #time}. */ + update(delta) { + this.time += delta; + } + physicsTranslate(x, y) { + const physicsConstraints = this.physicsConstraints; + for (let i = 0, n = physicsConstraints.length; i < n; i++) + physicsConstraints[i].translate(x, y); + } + /** Calls {@link PhysicsConstraint#rotate(float, float, float)} for each physics constraint. */ + physicsRotate(x, y, degrees) { + const physicsConstraints = this.physicsConstraints; + for (let i = 0, n = physicsConstraints.length; i < n; i++) + physicsConstraints[i].rotate(x, y, degrees); + } + }; + var Physics = /* @__PURE__ */ ((Physics2) => { + Physics2[Physics2["none"] = 0] = "none"; + Physics2[Physics2["reset"] = 1] = "reset"; + Physics2[Physics2["update"] = 2] = "update"; + Physics2[Physics2["pose"] = 3] = "pose"; + return Physics2; + })(Physics || {}); + + // spine-core/src/PhysicsConstraintData.ts + var PhysicsConstraintData = class extends ConstraintData { + _bone = null; + /** The bone constrained by this physics constraint. */ + set bone(boneData) { + this._bone = boneData; + } + get bone() { + if (!this._bone) throw new Error("BoneData not set."); + else return this._bone; + } + x = 0; + y = 0; + rotate = 0; + scaleX = 0; + shearX = 0; + limit = 0; + step = 0; + inertia = 0; + strength = 0; + damping = 0; + massInverse = 0; + wind = 0; + gravity = 0; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */ + mix = 0; + inertiaGlobal = false; + strengthGlobal = false; + dampingGlobal = false; + massGlobal = false; + windGlobal = false; + gravityGlobal = false; + mixGlobal = false; + constructor(name) { + super(name, 0, false); + } + }; + + // spine-core/src/SkeletonData.ts + var SkeletonData = class { + /** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */ + name = null; + /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ + bones = new Array(); + // Ordered parents first. + /** The skeleton's slots in the setup pose draw order. */ + slots = new Array(); + // Setup pose draw order. + skins = new Array(); + /** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine. + * + * See {@link Skeleton#getAttachmentByName()}. + * May be null. */ + defaultSkin = null; + /** The skeleton's events. */ + events = new Array(); + /** The skeleton's animations. */ + animations = new Array(); + /** The skeleton's IK constraints. */ + ikConstraints = new Array(); + /** The skeleton's transform constraints. */ + transformConstraints = new Array(); + /** The skeleton's path constraints. */ + pathConstraints = new Array(); + /** The skeleton's physics constraints. */ + physicsConstraints = new Array(); + /** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + x = 0; + /** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + y = 0; + /** The width of the skeleton's axis aligned bounding box in the setup pose. */ + width = 0; + /** The height of the skeleton's axis aligned bounding box in the setup pose. */ + height = 0; + /** Baseline scale factor for applying distance-dependent effects on non-scalable properties, such as angle or scale. Default + * is 100. */ + referenceScale = 100; + /** The Spine version used to export the skeleton data, or null. */ + version = null; + /** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */ + hash = null; + // Nonessential + /** The dopesheet FPS in Spine. Available only when nonessential data was exported. */ + fps = 0; + /** The path to the images directory as defined in Spine. Available only when nonessential data was exported. May be null. */ + imagesPath = null; + /** The path to the audio directory as defined in Spine. Available only when nonessential data was exported. May be null. */ + audioPath = null; + /** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findBone(boneName) { + if (!boneName) throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.name == boneName) return bone; + } + return null; + } + /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findSlot(slotName) { + if (!slotName) throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.name == slotName) return slot; + } + return null; + } + /** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findSkin(skinName) { + if (!skinName) throw new Error("skinName cannot be null."); + let skins = this.skins; + for (let i = 0, n = skins.length; i < n; i++) { + let skin = skins[i]; + if (skin.name == skinName) return skin; + } + return null; + } + /** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findEvent(eventDataName) { + if (!eventDataName) throw new Error("eventDataName cannot be null."); + let events = this.events; + for (let i = 0, n = events.length; i < n; i++) { + let event = events[i]; + if (event.name == eventDataName) return event; + } + return null; + } + /** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to + * call it multiple times. + * @returns May be null. */ + findAnimation(animationName) { + if (!animationName) throw new Error("animationName cannot be null."); + let animations = this.animations; + for (let i = 0, n = animations.length; i < n; i++) { + let animation = animations[i]; + if (animation.name == animationName) return animation; + } + return null; + } + /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method + * than to call it multiple times. + * @return May be null. */ + findIkConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + const constraint = ikConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of + * this method than to call it multiple times. + * @return May be null. */ + findTransformConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + const constraint = transformConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method + * than to call it multiple times. + * @return May be null. */ + findPathConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + const constraint = pathConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + /** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this method + * than to call it multiple times. + * @return May be null. */ + findPhysicsConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const physicsConstraints = this.physicsConstraints; + for (let i = 0, n = physicsConstraints.length; i < n; i++) { + const constraint = physicsConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + }; + + // spine-core/src/Skin.ts + var SkinEntry = class { + constructor(slotIndex = 0, name, attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + } + }; + var Skin = class { + /** The skin's name, which is unique across all skins in the skeleton. */ + name; + attachments = new Array(); + bones = Array(); + constraints = new Array(); + /** The color of the skin as it was in Spine, or a default color if nonessential data was not exported. */ + color = new Color(0.99607843, 0.61960787, 0.30980393, 1); + // fe9e4fff + constructor(name) { + if (!name) throw new Error("name cannot be null."); + this.name = name; + } + /** Adds an attachment to the skin for the specified slot index and name. */ + setAttachment(slotIndex, name, attachment) { + if (!attachment) throw new Error("attachment cannot be null."); + let attachments = this.attachments; + if (slotIndex >= attachments.length) attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + } + /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ + addSkin(skin) { + for (let i = 0; i < skin.bones.length; i++) { + let bone = skin.bones[i]; + let contained = false; + for (let ii = 0; ii < this.bones.length; ii++) { + if (this.bones[ii] == bone) { + contained = true; + break; + } + } + if (!contained) this.bones.push(bone); + } + for (let i = 0; i < skin.constraints.length; i++) { + let constraint = skin.constraints[i]; + let contained = false; + for (let ii = 0; ii < this.constraints.length; ii++) { + if (this.constraints[ii] == constraint) { + contained = true; + break; + } + } + if (!contained) this.constraints.push(constraint); + } + let attachments = skin.getAttachments(); + for (let i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + /** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not + * copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */ + copySkin(skin) { + for (let i = 0; i < skin.bones.length; i++) { + let bone = skin.bones[i]; + let contained = false; + for (let ii = 0; ii < this.bones.length; ii++) { + if (this.bones[ii] == bone) { + contained = true; + break; + } + } + if (!contained) this.bones.push(bone); + } + for (let i = 0; i < skin.constraints.length; i++) { + let constraint = skin.constraints[i]; + let contained = false; + for (let ii = 0; ii < this.constraints.length; ii++) { + if (this.constraints[ii] == constraint) { + contained = true; + break; + } + } + if (!contained) this.constraints.push(constraint); + } + let attachments = skin.getAttachments(); + for (let i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + if (!attachment.attachment) continue; + if (attachment.attachment instanceof MeshAttachment) { + attachment.attachment = attachment.attachment.newLinkedMesh(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } else { + attachment.attachment = attachment.attachment.copy(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + } + /** Returns the attachment for the specified slot index and name, or null. */ + getAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + } + /** Removes the attachment in the skin for the specified slot index and name, if any. */ + removeAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + if (dictionary) delete dictionary[name]; + } + /** Returns all attachments in this skin. */ + getAttachments() { + let entries = new Array(); + for (var i = 0; i < this.attachments.length; i++) { + let slotAttachments = this.attachments[i]; + if (slotAttachments) { + for (let name in slotAttachments) { + let attachment = slotAttachments[name]; + if (attachment) entries.push(new SkinEntry(i, name, attachment)); + } + } + } + return entries; + } + /** Returns all attachments in this skin for the specified slot index. */ + getAttachmentsForSlot(slotIndex, attachments) { + let slotAttachments = this.attachments[slotIndex]; + if (slotAttachments) { + for (let name in slotAttachments) { + let attachment = slotAttachments[name]; + if (attachment) attachments.push(new SkinEntry(slotIndex, name, attachment)); + } + } + } + /** Clears all attachments, bones, and constraints. */ + clear() { + this.attachments.length = 0; + this.bones.length = 0; + this.constraints.length = 0; + } + /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ + attachAll(skeleton, oldSkin) { + let slotIndex = 0; + for (let i = 0; i < skeleton.slots.length; i++) { + let slot = skeleton.slots[i]; + let slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + let dictionary = oldSkin.attachments[slotIndex]; + for (let key in dictionary) { + let skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + let attachment = this.getAttachment(slotIndex, key); + if (attachment) slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + } + }; + + // spine-core/src/SlotData.ts + var SlotData = class { + /** The index of the slot in {@link Skeleton#getSlots()}. */ + index = 0; + /** The name of the slot, which is unique across all slots in the skeleton. */ + name; + /** The bone this slot belongs to. */ + boneData; + /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two + * color tinting. */ + color = new Color(1, 1, 1, 1); + /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark + * color's alpha is not used. */ + darkColor = null; + /** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */ + attachmentName = null; + /** The blend mode for drawing the slot's attachment. */ + blendMode = 0 /* Normal */; + /** False if the slot was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */ + visible = true; + constructor(index, name, boneData) { + if (index < 0) throw new Error("index must be >= 0."); + if (!name) throw new Error("name cannot be null."); + if (!boneData) throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + }; + var BlendMode = /* @__PURE__ */ ((BlendMode3) => { + BlendMode3[BlendMode3["Normal"] = 0] = "Normal"; + BlendMode3[BlendMode3["Additive"] = 1] = "Additive"; + BlendMode3[BlendMode3["Multiply"] = 2] = "Multiply"; + BlendMode3[BlendMode3["Screen"] = 3] = "Screen"; + return BlendMode3; + })(BlendMode || {}); + + // spine-core/src/TransformConstraintData.ts + var TransformConstraintData = class extends ConstraintData { + /** The bones that will be modified by this transform constraint. */ + bones = new Array(); + /** The target bone whose world transform will be copied to the constrained bones. */ + _target = null; + set target(boneData) { + this._target = boneData; + } + get target() { + if (!this._target) throw new Error("BoneData not set."); + else return this._target; + } + mixRotate = 0; + mixX = 0; + mixY = 0; + mixScaleX = 0; + mixScaleY = 0; + mixShearY = 0; + /** An offset added to the constrained bone rotation. */ + offsetRotation = 0; + /** An offset added to the constrained bone X translation. */ + offsetX = 0; + /** An offset added to the constrained bone Y translation. */ + offsetY = 0; + /** An offset added to the constrained bone scaleX. */ + offsetScaleX = 0; + /** An offset added to the constrained bone scaleY. */ + offsetScaleY = 0; + /** An offset added to the constrained bone shearY. */ + offsetShearY = 0; + relative = false; + local = false; + constructor(name) { + super(name, 0, false); + } + }; + + // spine-core/src/SkeletonBinary.ts + var SkeletonBinary = class { + /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at + * runtime than were used in Spine. + * + * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ + scale = 1; + attachmentLoader; + linkedMeshes = new Array(); + constructor(attachmentLoader) { + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(binary) { + let scale = this.scale; + let skeletonData = new SkeletonData(); + skeletonData.name = ""; + let input = new BinaryInput(binary); + let lowHash = input.readInt32(); + let highHash = input.readInt32(); + skeletonData.hash = highHash == 0 && lowHash == 0 ? null : highHash.toString(16) + lowHash.toString(16); + skeletonData.version = input.readString(); + skeletonData.x = input.readFloat(); + skeletonData.y = input.readFloat(); + skeletonData.width = input.readFloat(); + skeletonData.height = input.readFloat(); + skeletonData.referenceScale = input.readFloat() * scale; + let nonessential = input.readBoolean(); + if (nonessential) { + skeletonData.fps = input.readFloat(); + skeletonData.imagesPath = input.readString(); + skeletonData.audioPath = input.readString(); + } + let n = 0; + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let str = input.readString(); + if (!str) throw new Error("String in string table must not be null."); + input.strings.push(str); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("Bone name must not be null."); + let parent = i == 0 ? null : skeletonData.bones[input.readInt(true)]; + let data = new BoneData(i, name, parent); + data.rotation = input.readFloat(); + data.x = input.readFloat() * scale; + data.y = input.readFloat() * scale; + data.scaleX = input.readFloat(); + data.scaleY = input.readFloat(); + data.shearX = input.readFloat(); + data.shearY = input.readFloat(); + data.length = input.readFloat() * scale; + data.inherit = input.readByte(); + data.skinRequired = input.readBoolean(); + if (nonessential) { + Color.rgba8888ToColor(data.color, input.readInt32()); + data.icon = input.readString() ?? void 0; + data.visible = input.readBoolean(); + } + skeletonData.bones.push(data); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let slotName = input.readString(); + if (!slotName) throw new Error("Slot name must not be null."); + let boneData = skeletonData.bones[input.readInt(true)]; + let data = new SlotData(i, slotName, boneData); + Color.rgba8888ToColor(data.color, input.readInt32()); + let darkColor = input.readInt32(); + if (darkColor != -1) Color.rgb888ToColor(data.darkColor = new Color(), darkColor); + data.attachmentName = input.readStringRef(); + data.blendMode = input.readInt(true); + if (nonessential) data.visible = input.readBoolean(); + skeletonData.slots.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("IK constraint data name must not be null."); + let data = new IkConstraintData(name); + data.order = input.readInt(true); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + let flags = input.readByte(); + data.skinRequired = (flags & 1) != 0; + data.bendDirection = (flags & 2) != 0 ? 1 : -1; + data.compress = (flags & 4) != 0; + data.stretch = (flags & 8) != 0; + data.uniform = (flags & 16) != 0; + if ((flags & 32) != 0) data.mix = (flags & 64) != 0 ? input.readFloat() : 1; + if ((flags & 128) != 0) data.softness = input.readFloat() * scale; + skeletonData.ikConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("Transform constraint data name must not be null."); + let data = new TransformConstraintData(name); + data.order = input.readInt(true); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + let flags = input.readByte(); + data.skinRequired = (flags & 1) != 0; + data.local = (flags & 2) != 0; + data.relative = (flags & 4) != 0; + if ((flags & 8) != 0) data.offsetRotation = input.readFloat(); + if ((flags & 16) != 0) data.offsetX = input.readFloat() * scale; + if ((flags & 32) != 0) data.offsetY = input.readFloat() * scale; + if ((flags & 64) != 0) data.offsetScaleX = input.readFloat(); + if ((flags & 128) != 0) data.offsetScaleY = input.readFloat(); + flags = input.readByte(); + if ((flags & 1) != 0) data.offsetShearY = input.readFloat(); + if ((flags & 2) != 0) data.mixRotate = input.readFloat(); + if ((flags & 4) != 0) data.mixX = input.readFloat(); + if ((flags & 8) != 0) data.mixY = input.readFloat(); + if ((flags & 16) != 0) data.mixScaleX = input.readFloat(); + if ((flags & 32) != 0) data.mixScaleY = input.readFloat(); + if ((flags & 64) != 0) data.mixShearY = input.readFloat(); + skeletonData.transformConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("Path constraint data name must not be null."); + let data = new PathConstraintData(name); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.slots[input.readInt(true)]; + const flags = input.readByte(); + data.positionMode = flags & 1; + data.spacingMode = flags >> 1 & 3; + data.rotateMode = flags >> 3 & 3; + if ((flags & 128) != 0) data.offsetRotation = input.readFloat(); + data.position = input.readFloat(); + if (data.positionMode == 0 /* Fixed */) data.position *= scale; + data.spacing = input.readFloat(); + if (data.spacingMode == 0 /* Length */ || data.spacingMode == 1 /* Fixed */) data.spacing *= scale; + data.mixRotate = input.readFloat(); + data.mixX = input.readFloat(); + data.mixY = input.readFloat(); + skeletonData.pathConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + const name = input.readString(); + if (!name) throw new Error("Physics constraint data name must not be null."); + const data = new PhysicsConstraintData(name); + data.order = input.readInt(true); + data.bone = skeletonData.bones[input.readInt(true)]; + let flags = input.readByte(); + data.skinRequired = (flags & 1) != 0; + if ((flags & 2) != 0) data.x = input.readFloat(); + if ((flags & 4) != 0) data.y = input.readFloat(); + if ((flags & 8) != 0) data.rotate = input.readFloat(); + if ((flags & 16) != 0) data.scaleX = input.readFloat(); + if ((flags & 32) != 0) data.shearX = input.readFloat(); + data.limit = ((flags & 64) != 0 ? input.readFloat() : 5e3) * scale; + data.step = 1 / input.readUnsignedByte(); + data.inertia = input.readFloat(); + data.strength = input.readFloat(); + data.damping = input.readFloat(); + data.massInverse = (flags & 128) != 0 ? input.readFloat() : 1; + data.wind = input.readFloat(); + data.gravity = input.readFloat(); + flags = input.readByte(); + if ((flags & 1) != 0) data.inertiaGlobal = true; + if ((flags & 2) != 0) data.strengthGlobal = true; + if ((flags & 4) != 0) data.dampingGlobal = true; + if ((flags & 8) != 0) data.massGlobal = true; + if ((flags & 16) != 0) data.windGlobal = true; + if ((flags & 32) != 0) data.gravityGlobal = true; + if ((flags & 64) != 0) data.mixGlobal = true; + data.mix = (flags & 128) != 0 ? input.readFloat() : 1; + skeletonData.physicsConstraints.push(data); + } + let defaultSkin = this.readSkin(input, skeletonData, true, nonessential); + if (defaultSkin) { + skeletonData.defaultSkin = defaultSkin; + skeletonData.skins.push(defaultSkin); + } + { + let i = skeletonData.skins.length; + Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); + for (; i < n; i++) { + let skin = this.readSkin(input, skeletonData, false, nonessential); + if (!skin) throw new Error("readSkin() should not have returned null."); + skeletonData.skins[i] = skin; + } + } + n = this.linkedMeshes.length; + for (let i = 0; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + const skin = skeletonData.skins[linkedMesh.skinIndex]; + if (!linkedMesh.parent) throw new Error("Linked mesh parent must not be null"); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (!parent) throw new Error(`Parent mesh not found: ${linkedMesh.parent}`); + linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent); + if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); + } + this.linkedMeshes.length = 0; + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let eventName = input.readString(); + if (!eventName) throw new Error("Event data name must not be null"); + let data = new EventData(eventName); + data.intValue = input.readInt(false); + data.floatValue = input.readFloat(); + data.stringValue = input.readString(); + data.audioPath = input.readString(); + if (data.audioPath) { + data.volume = input.readFloat(); + data.balance = input.readFloat(); + } + skeletonData.events.push(data); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let animationName = input.readString(); + if (!animationName) throw new Error("Animatio name must not be null."); + skeletonData.animations.push(this.readAnimation(input, animationName, skeletonData)); + } + return skeletonData; + } + readSkin(input, skeletonData, defaultSkin, nonessential) { + let skin = null; + let slotCount = 0; + if (defaultSkin) { + slotCount = input.readInt(true); + if (slotCount == 0) return null; + skin = new Skin("default"); + } else { + let skinName = input.readString(); + if (!skinName) throw new Error("Skin name must not be null."); + skin = new Skin(skinName); + if (nonessential) Color.rgba8888ToColor(skin.color, input.readInt32()); + skin.bones.length = input.readInt(true); + for (let i = 0, n = skin.bones.length; i < n; i++) + skin.bones[i] = skeletonData.bones[input.readInt(true)]; + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.physicsConstraints[input.readInt(true)]); + slotCount = input.readInt(true); + } + for (let i = 0; i < slotCount; i++) { + let slotIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let name = input.readStringRef(); + if (!name) + throw new Error("Attachment name must not be null"); + let attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name, nonessential); + if (attachment) skin.setAttachment(slotIndex, name, attachment); + } + } + return skin; + } + readAttachment(input, skeletonData, skin, slotIndex, attachmentName, nonessential) { + let scale = this.scale; + let flags = input.readByte(); + const name = (flags & 8) != 0 ? input.readStringRef() : attachmentName; + if (!name) throw new Error("Attachment name must not be null"); + switch (flags & 7) { + // BUG? + case 0 /* Region */: { + let path = (flags & 16) != 0 ? input.readStringRef() : null; + const color = (flags & 32) != 0 ? input.readInt32() : 4294967295; + const sequence = (flags & 64) != 0 ? this.readSequence(input) : null; + let rotation = (flags & 128) != 0 ? input.readFloat() : 0; + let x = input.readFloat(); + let y = input.readFloat(); + let scaleX = input.readFloat(); + let scaleY = input.readFloat(); + let width = input.readFloat(); + let height = input.readFloat(); + if (!path) path = name; + let region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); + if (!region) return null; + region.path = path; + region.x = x * scale; + region.y = y * scale; + region.scaleX = scaleX; + region.scaleY = scaleY; + region.rotation = rotation; + region.width = width * scale; + region.height = height * scale; + Color.rgba8888ToColor(region.color, color); + region.sequence = sequence; + if (sequence == null) region.updateRegion(); + return region; + } + case 1 /* BoundingBox */: { + let vertices = this.readVertices(input, (flags & 16) != 0); + let color = nonessential ? input.readInt32() : 0; + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (!box) return null; + box.worldVerticesLength = vertices.length; + box.vertices = vertices.vertices; + box.bones = vertices.bones; + if (nonessential) Color.rgba8888ToColor(box.color, color); + return box; + } + case 2 /* Mesh */: { + let path = (flags & 16) != 0 ? input.readStringRef() : name; + const color = (flags & 32) != 0 ? input.readInt32() : 4294967295; + const sequence = (flags & 64) != 0 ? this.readSequence(input) : null; + const hullLength = input.readInt(true); + const vertices = this.readVertices(input, (flags & 128) != 0); + const uvs = this.readFloatArray(input, vertices.length, 1); + const triangles = this.readShortArray(input, (vertices.length - hullLength - 2) * 3); + let edges = []; + let width = 0, height = 0; + if (nonessential) { + edges = this.readShortArray(input, input.readInt(true)); + width = input.readFloat(); + height = input.readFloat(); + } + if (!path) path = name; + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.bones = vertices.bones; + mesh.vertices = vertices.vertices; + mesh.worldVerticesLength = vertices.length; + mesh.triangles = triangles; + mesh.regionUVs = uvs; + if (sequence == null) mesh.updateRegion(); + mesh.hullLength = hullLength << 1; + mesh.sequence = sequence; + if (nonessential) { + mesh.edges = edges; + mesh.width = width * scale; + mesh.height = height * scale; + } + return mesh; + } + case 3 /* LinkedMesh */: { + const path = (flags & 16) != 0 ? input.readStringRef() : name; + if (path == null) throw new Error("Path of linked mesh must not be null"); + const color = (flags & 32) != 0 ? input.readInt32() : 4294967295; + const sequence = (flags & 64) != 0 ? this.readSequence(input) : null; + const inheritTimelines = (flags & 128) != 0; + const skinIndex = input.readInt(true); + const parent = input.readStringRef(); + let width = 0, height = 0; + if (nonessential) { + width = input.readFloat(); + height = input.readFloat(); + } + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.sequence = sequence; + if (nonessential) { + mesh.width = width * scale; + mesh.height = height * scale; + } + this.linkedMeshes.push(new LinkedMesh(mesh, skinIndex, slotIndex, parent, inheritTimelines)); + return mesh; + } + case 4 /* Path */: { + const closed2 = (flags & 16) != 0; + const constantSpeed = (flags & 32) != 0; + const vertices = this.readVertices(input, (flags & 64) != 0); + const lengths = Utils.newArray(vertices.length / 6, 0); + for (let i = 0, n = lengths.length; i < n; i++) + lengths[i] = input.readFloat() * scale; + const color = nonessential ? input.readInt32() : 0; + const path = this.attachmentLoader.newPathAttachment(skin, name); + if (!path) return null; + path.closed = closed2; + path.constantSpeed = constantSpeed; + path.worldVerticesLength = vertices.length; + path.vertices = vertices.vertices; + path.bones = vertices.bones; + path.lengths = lengths; + if (nonessential) Color.rgba8888ToColor(path.color, color); + return path; + } + case 5 /* Point */: { + const rotation = input.readFloat(); + const x = input.readFloat(); + const y = input.readFloat(); + const color = nonessential ? input.readInt32() : 0; + const point = this.attachmentLoader.newPointAttachment(skin, name); + if (!point) return null; + point.x = x * scale; + point.y = y * scale; + point.rotation = rotation; + if (nonessential) Color.rgba8888ToColor(point.color, color); + return point; + } + case 6 /* Clipping */: { + const endSlotIndex = input.readInt(true); + const vertices = this.readVertices(input, (flags & 16) != 0); + let color = nonessential ? input.readInt32() : 0; + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (!clip) return null; + clip.endSlot = skeletonData.slots[endSlotIndex]; + clip.worldVerticesLength = vertices.length; + clip.vertices = vertices.vertices; + clip.bones = vertices.bones; + if (nonessential) Color.rgba8888ToColor(clip.color, color); + return clip; + } + } + return null; + } + readSequence(input) { + let sequence = new Sequence(input.readInt(true)); + sequence.start = input.readInt(true); + sequence.digits = input.readInt(true); + sequence.setupIndex = input.readInt(true); + return sequence; + } + readVertices(input, weighted) { + const scale = this.scale; + const vertexCount = input.readInt(true); + const vertices = new Vertices(); + vertices.length = vertexCount << 1; + if (!weighted) { + vertices.vertices = this.readFloatArray(input, vertices.length, scale); + return vertices; + } + let weights = new Array(); + let bonesArray = new Array(); + for (let i = 0; i < vertexCount; i++) { + let boneCount = input.readInt(true); + bonesArray.push(boneCount); + for (let ii = 0; ii < boneCount; ii++) { + bonesArray.push(input.readInt(true)); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat()); + } + } + vertices.vertices = Utils.toFloatArray(weights); + vertices.bones = bonesArray; + return vertices; + } + readFloatArray(input, n, scale) { + let array = new Array(n); + if (scale == 1) { + for (let i = 0; i < n; i++) + array[i] = input.readFloat(); + } else { + for (let i = 0; i < n; i++) + array[i] = input.readFloat() * scale; + } + return array; + } + readShortArray(input, n) { + let array = new Array(n); + for (let i = 0; i < n; i++) + array[i] = input.readInt(true); + return array; + } + readAnimation(input, name, skeletonData) { + input.readInt(true); + let timelines = new Array(); + let scale = this.scale; + for (let i = 0, n = input.readInt(true); i < n; i++) { + let slotIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + let frameLast = frameCount - 1; + switch (timelineType) { + case SLOT_ATTACHMENT: { + let timeline = new AttachmentTimeline(frameCount, slotIndex); + for (let frame = 0; frame < frameCount; frame++) + timeline.setFrame(frame, input.readFloat(), input.readStringRef()); + timelines.push(timeline); + break; + } + case SLOT_RGBA: { + let bezierCount = input.readInt(true); + let timeline = new RGBATimeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + let a = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b, a); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + let a2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1); + } + time = time2; + r = r2; + g = g2; + b = b2; + a = a2; + } + timelines.push(timeline); + break; + } + case SLOT_RGB: { + let bezierCount = input.readInt(true); + let timeline = new RGBTimeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); + } + time = time2; + r = r2; + g = g2; + b = b2; + } + timelines.push(timeline); + break; + } + case SLOT_RGBA2: { + let bezierCount = input.readInt(true); + let timeline = new RGBA2Timeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + let a = input.readUnsignedByte() / 255; + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let nr = input.readUnsignedByte() / 255; + let ng = input.readUnsignedByte() / 255; + let nb = input.readUnsignedByte() / 255; + let na = input.readUnsignedByte() / 255; + let nr2 = input.readUnsignedByte() / 255; + let ng2 = input.readUnsignedByte() / 255; + let nb2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1); + setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1); + } + time = time2; + r = nr; + g = ng; + b = nb; + a = na; + r2 = nr2; + g2 = ng2; + b2 = nb2; + } + timelines.push(timeline); + break; + } + case SLOT_RGB2: { + let bezierCount = input.readInt(true); + let timeline = new RGB2Timeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b, r2, g2, b2); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let nr = input.readUnsignedByte() / 255; + let ng = input.readUnsignedByte() / 255; + let nb = input.readUnsignedByte() / 255; + let nr2 = input.readUnsignedByte() / 255; + let ng2 = input.readUnsignedByte() / 255; + let nb2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, r2, nr2, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, g2, ng2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, b2, nb2, 1); + } + time = time2; + r = nr; + g = ng; + b = nb; + r2 = nr2; + g2 = ng2; + b2 = nb2; + } + timelines.push(timeline); + break; + } + case SLOT_ALPHA: { + let timeline = new AlphaTimeline(frameCount, input.readInt(true), slotIndex); + let time = input.readFloat(), a = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, a); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let a2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, a, a2, 1); + } + time = time2; + a = a2; + } + timelines.push(timeline); + } + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let boneIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let type = input.readByte(), frameCount = input.readInt(true); + if (type == BONE_INHERIT) { + let timeline = new InheritTimeline(frameCount, boneIndex); + for (let frame = 0; frame < frameCount; frame++) { + timeline.setFrame(frame, input.readFloat(), input.readByte()); + } + timelines.push(timeline); + continue; + } + let bezierCount = input.readInt(true); + switch (type) { + case BONE_ROTATE: + timelines.push(readTimeline1(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_TRANSLATE: + timelines.push(readTimeline2(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_TRANSLATEX: + timelines.push(readTimeline1(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_TRANSLATEY: + timelines.push(readTimeline1(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_SCALE: + timelines.push(readTimeline2(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SCALEX: + timelines.push(readTimeline1(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SCALEY: + timelines.push(readTimeline1(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEAR: + timelines.push(readTimeline2(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEARX: + timelines.push(readTimeline1(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEARY: + timelines.push(readTimeline1(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1)); + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; + let timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index); + let flags = input.readByte(); + let time = input.readFloat(), mix = (flags & 1) != 0 ? (flags & 2) != 0 ? input.readFloat() : 1 : 0; + let softness = (flags & 4) != 0 ? input.readFloat() * scale : 0; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mix, softness, (flags & 8) != 0 ? 1 : -1, (flags & 16) != 0, (flags & 32) != 0); + if (frame == frameLast) break; + flags = input.readByte(); + const time2 = input.readFloat(), mix2 = (flags & 1) != 0 ? (flags & 2) != 0 ? input.readFloat() : 1 : 0; + const softness2 = (flags & 4) != 0 ? input.readFloat() * scale : 0; + if ((flags & 64) != 0) { + timeline.setStepped(frame); + } else if ((flags & 128) != 0) { + setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale); + } + time = time2; + mix = mix2; + softness = softness2; + } + timelines.push(timeline); + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; + let timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index); + let time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(), mixScaleX = input.readFloat(), mixScaleY = input.readFloat(), mixShearY = input.readFloat(); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); + if (frame == frameLast) break; + let time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(), mixScaleX2 = input.readFloat(), mixScaleY2 = input.readFloat(), mixShearY2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixShearY = mixShearY2; + } + timelines.push(timeline); + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true); + let data = skeletonData.pathConstraints[index]; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + const type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true); + switch (type) { + case PATH_POSITION: + timelines.push(readTimeline1( + input, + new PathConstraintPositionTimeline(frameCount, bezierCount, index), + data.positionMode == 0 /* Fixed */ ? scale : 1 + )); + break; + case PATH_SPACING: + timelines.push(readTimeline1( + input, + new PathConstraintSpacingTimeline(frameCount, bezierCount, index), + data.spacingMode == 0 /* Length */ || data.spacingMode == 1 /* Fixed */ ? scale : 1 + )); + break; + case PATH_MIX: + let timeline = new PathConstraintMixTimeline(frameCount, bezierCount, index); + let time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(); + for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY); + if (frame == frameLast) break; + let time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + } + timelines.push(timeline); + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + const index = input.readInt(true) - 1; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + const type = input.readByte(), frameCount = input.readInt(true); + if (type == PHYSICS_RESET) { + const timeline = new PhysicsConstraintResetTimeline(frameCount, index); + for (let frame = 0; frame < frameCount; frame++) + timeline.setFrame(frame, input.readFloat()); + timelines.push(timeline); + continue; + } + const bezierCount = input.readInt(true); + switch (type) { + case PHYSICS_INERTIA: + timelines.push(readTimeline1(input, new PhysicsConstraintInertiaTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_STRENGTH: + timelines.push(readTimeline1(input, new PhysicsConstraintStrengthTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_DAMPING: + timelines.push(readTimeline1(input, new PhysicsConstraintDampingTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_MASS: + timelines.push(readTimeline1(input, new PhysicsConstraintMassTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_WIND: + timelines.push(readTimeline1(input, new PhysicsConstraintWindTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_GRAVITY: + timelines.push(readTimeline1(input, new PhysicsConstraintGravityTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_MIX: + timelines.push(readTimeline1(input, new PhysicsConstraintMixTimeline(frameCount, bezierCount, index), 1)); + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let skin = skeletonData.skins[input.readInt(true)]; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let slotIndex = input.readInt(true); + for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { + let attachmentName = input.readStringRef(); + if (!attachmentName) throw new Error("attachmentName must not be null."); + let attachment = skin.getAttachment(slotIndex, attachmentName); + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + let frameLast = frameCount - 1; + switch (timelineType) { + case ATTACHMENT_DEFORM: { + let vertexAttachment = attachment; + let weighted = vertexAttachment.bones; + let vertices = vertexAttachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let bezierCount = input.readInt(true); + let timeline = new DeformTimeline(frameCount, bezierCount, slotIndex, vertexAttachment); + let time = input.readFloat(); + for (let frame = 0, bezier = 0; ; frame++) { + let deform; + let end = input.readInt(true); + if (end == 0) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + let start = input.readInt(true); + end += start; + if (scale == 1) { + for (let v = start; v < end; v++) + deform[v] = input.readFloat(); + } else { + for (let v = start; v < end; v++) + deform[v] = input.readFloat() * scale; + } + if (!weighted) { + for (let v = 0, vn = deform.length; v < vn; v++) + deform[v] += vertices[v]; + } + } + timeline.setFrame(frame, time, deform); + if (frame == frameLast) break; + let time2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1); + } + time = time2; + } + timelines.push(timeline); + break; + } + case ATTACHMENT_SEQUENCE: { + let timeline = new SequenceTimeline(frameCount, slotIndex, attachment); + for (let frame = 0; frame < frameCount; frame++) { + let time = input.readFloat(); + let modeAndIndex = input.readInt32(); + timeline.setFrame( + frame, + time, + SequenceModeValues[modeAndIndex & 15], + modeAndIndex >> 4, + input.readFloat() + ); + } + timelines.push(timeline); + break; + } + } + } + } + } + let drawOrderCount = input.readInt(true); + if (drawOrderCount > 0) { + let timeline = new DrawOrderTimeline(drawOrderCount); + let slotCount = skeletonData.slots.length; + for (let i = 0; i < drawOrderCount; i++) { + let time = input.readFloat(); + let offsetCount = input.readInt(true); + let drawOrder = Utils.newArray(slotCount, 0); + for (let ii = slotCount - 1; ii >= 0; ii--) + drawOrder[ii] = -1; + let unchanged = Utils.newArray(slotCount - offsetCount, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let ii = 0; ii < offsetCount; ii++) { + let slotIndex = input.readInt(true); + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + input.readInt(true)] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; + timeline.setFrame(i, time, drawOrder); + } + timelines.push(timeline); + } + let eventCount = input.readInt(true); + if (eventCount > 0) { + let timeline = new EventTimeline(eventCount); + for (let i = 0; i < eventCount; i++) { + let time = input.readFloat(); + let eventData = skeletonData.events[input.readInt(true)]; + let event = new Event(time, eventData); + event.intValue = input.readInt(false); + event.floatValue = input.readFloat(); + event.stringValue = input.readString(); + if (event.stringValue == null) event.stringValue = eventData.stringValue; + if (event.data.audioPath) { + event.volume = input.readFloat(); + event.balance = input.readFloat(); + } + timeline.setFrame(i, event); + } + timelines.push(timeline); + } + let duration = 0; + for (let i = 0, n = timelines.length; i < n; i++) + duration = Math.max(duration, timelines[i].getDuration()); + return new Animation(name, timelines, duration); + } + }; + var BinaryInput = class { + constructor(data, strings = new Array(), index = 0, buffer = new DataView(data instanceof ArrayBuffer ? data : data.buffer)) { + this.strings = strings; + this.index = index; + this.buffer = buffer; + } + readByte() { + return this.buffer.getInt8(this.index++); + } + readUnsignedByte() { + return this.buffer.getUint8(this.index++); + } + readShort() { + let value = this.buffer.getInt16(this.index); + this.index += 2; + return value; + } + readInt32() { + let value = this.buffer.getInt32(this.index); + this.index += 4; + return value; + } + readInt(optimizePositive) { + let b = this.readByte(); + let result = b & 127; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 7; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 14; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 21; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 28; + } + } + } + } + return optimizePositive ? result : result >>> 1 ^ -(result & 1); + } + readStringRef() { + let index = this.readInt(true); + return index == 0 ? null : this.strings[index - 1]; + } + readString() { + let byteCount = this.readInt(true); + switch (byteCount) { + case 0: + return null; + case 1: + return ""; + } + byteCount--; + let chars = ""; + let charCount = 0; + for (let i = 0; i < byteCount; ) { + let b = this.readUnsignedByte(); + switch (b >> 4) { + case 12: + case 13: + chars += String.fromCharCode((b & 31) << 6 | this.readByte() & 63); + i += 2; + break; + case 14: + chars += String.fromCharCode((b & 15) << 12 | (this.readByte() & 63) << 6 | this.readByte() & 63); + i += 3; + break; + default: + chars += String.fromCharCode(b); + i++; + } + } + return chars; + } + readFloat() { + let value = this.buffer.getFloat32(this.index); + this.index += 4; + return value; + } + readBoolean() { + return this.readByte() != 0; + } + }; + var LinkedMesh = class { + parent; + skinIndex; + slotIndex; + mesh; + inheritTimeline; + constructor(mesh, skinIndex, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skinIndex = skinIndex; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritTimeline = inheritDeform; + } + }; + var Vertices = class { + constructor(bones = null, vertices = null, length = 0) { + this.bones = bones; + this.vertices = vertices; + this.length = length; + } + }; + function readTimeline1(input, timeline, scale) { + let time = input.readFloat(), value = input.readFloat() * scale; + for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { + timeline.setFrame(frame, time, value); + if (frame == frameLast) break; + let time2 = input.readFloat(), value2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, scale); + } + time = time2; + value = value2; + } + return timeline; + } + function readTimeline2(input, timeline, scale) { + let time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale; + for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { + timeline.setFrame(frame, time, value1, value2); + if (frame == frameLast) break; + let time2 = input.readFloat(), nvalue1 = input.readFloat() * scale, nvalue2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale); + setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale); + } + time = time2; + value1 = nvalue1; + value2 = nvalue2; + } + return timeline; + } + function setBezier(input, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { + timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2); + } + var BONE_ROTATE = 0; + var BONE_TRANSLATE = 1; + var BONE_TRANSLATEX = 2; + var BONE_TRANSLATEY = 3; + var BONE_SCALE = 4; + var BONE_SCALEX = 5; + var BONE_SCALEY = 6; + var BONE_SHEAR = 7; + var BONE_SHEARX = 8; + var BONE_SHEARY = 9; + var BONE_INHERIT = 10; + var SLOT_ATTACHMENT = 0; + var SLOT_RGBA = 1; + var SLOT_RGB = 2; + var SLOT_RGBA2 = 3; + var SLOT_RGB2 = 4; + var SLOT_ALPHA = 5; + var ATTACHMENT_DEFORM = 0; + var ATTACHMENT_SEQUENCE = 1; + var PATH_POSITION = 0; + var PATH_SPACING = 1; + var PATH_MIX = 2; + var PHYSICS_INERTIA = 0; + var PHYSICS_STRENGTH = 1; + var PHYSICS_DAMPING = 2; + var PHYSICS_MASS = 4; + var PHYSICS_WIND = 5; + var PHYSICS_GRAVITY = 6; + var PHYSICS_MIX = 7; + var PHYSICS_RESET = 8; + var CURVE_STEPPED = 1; + var CURVE_BEZIER = 2; + + // spine-core/src/SkeletonBounds.ts + var SkeletonBounds = class { + /** The left edge of the axis aligned bounding box. */ + minX = 0; + /** The bottom edge of the axis aligned bounding box. */ + minY = 0; + /** The right edge of the axis aligned bounding box. */ + maxX = 0; + /** The top edge of the axis aligned bounding box. */ + maxY = 0; + /** The visible bounding boxes. */ + boundingBoxes = new Array(); + /** The world vertices for the bounding box polygons. */ + polygons = new Array(); + polygonPool = new Pool(() => { + return Utils.newFloatArray(16); + }); + /** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding + * box's polygon. + * @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the + * SkeletonBounds AABB methods will always return true. */ + update(skeleton, updateAabb) { + if (!skeleton) throw new Error("skeleton cannot be null."); + let boundingBoxes = this.boundingBoxes; + let polygons = this.polygons; + let polygonPool = this.polygonPool; + let slots = skeleton.slots; + let slotCount = slots.length; + boundingBoxes.length = 0; + polygonPool.freeAll(polygons); + polygons.length = 0; + for (let i = 0; i < slotCount; i++) { + let slot = slots[i]; + if (!slot.bone.active) continue; + let attachment = slot.getAttachment(); + if (attachment instanceof BoundingBoxAttachment) { + let boundingBox = attachment; + boundingBoxes.push(boundingBox); + let polygon = polygonPool.obtain(); + if (polygon.length != boundingBox.worldVerticesLength) { + polygon = Utils.newFloatArray(boundingBox.worldVerticesLength); + } + polygons.push(polygon); + boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); + } + } + if (updateAabb) { + this.aabbCompute(); + } else { + this.minX = Number.POSITIVE_INFINITY; + this.minY = Number.POSITIVE_INFINITY; + this.maxX = Number.NEGATIVE_INFINITY; + this.maxY = Number.NEGATIVE_INFINITY; + } + } + aabbCompute() { + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) { + let polygon = polygons[i]; + let vertices = polygon; + for (let ii = 0, nn = polygon.length; ii < nn; ii += 2) { + let x = vertices[ii]; + let y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + /** Returns true if the axis aligned bounding box contains the point. */ + aabbContainsPoint(x, y) { + return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; + } + /** Returns true if the axis aligned bounding box intersects the line segment. */ + aabbIntersectsSegment(x1, y1, x2, y2) { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + if (x1 <= minX && x2 <= minX || y1 <= minY && y2 <= minY || x1 >= maxX && x2 >= maxX || y1 >= maxY && y2 >= maxY) + return false; + let m = (y2 - y1) / (x2 - x1); + let y = m * (minX - x1) + y1; + if (y > minY && y < maxY) return true; + y = m * (maxX - x1) + y1; + if (y > minY && y < maxY) return true; + let x = (minY - y1) / m + x1; + if (x > minX && x < maxX) return true; + x = (maxY - y1) / m + x1; + if (x > minX && x < maxX) return true; + return false; + } + /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ + aabbIntersectsSkeleton(bounds) { + return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; + } + /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more + * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */ + containsPoint(x, y) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.containsPointPolygon(polygons[i], x, y)) return this.boundingBoxes[i]; + return null; + } + /** Returns true if the polygon contains the point. */ + containsPointPolygon(polygon, x, y) { + let vertices = polygon; + let nn = polygon.length; + let prevIndex = nn - 2; + let inside = false; + for (let ii = 0; ii < nn; ii += 2) { + let vertexY = vertices[ii + 1]; + let prevY = vertices[prevIndex + 1]; + if (vertexY < y && prevY >= y || prevY < y && vertexY >= y) { + let vertexX = vertices[ii]; + if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) inside = !inside; + } + prevIndex = ii; + } + return inside; + } + /** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it + * is usually more efficient to only call this method if {@link #aabbIntersectsSegment()} returns + * true. */ + intersectsSegment(x1, y1, x2, y2) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) return this.boundingBoxes[i]; + return null; + } + /** Returns true if the polygon contains any part of the line segment. */ + intersectsSegmentPolygon(polygon, x1, y1, x2, y2) { + let vertices = polygon; + let nn = polygon.length; + let width12 = x1 - x2, height12 = y1 - y2; + let det1 = x1 * y2 - y1 * x2; + let x3 = vertices[nn - 2], y3 = vertices[nn - 1]; + for (let ii = 0; ii < nn; ii += 2) { + let x4 = vertices[ii], y4 = vertices[ii + 1]; + let det2 = x3 * y4 - y3 * x4; + let width34 = x3 - x4, height34 = y3 - y4; + let det3 = width12 * height34 - height12 * width34; + let x = (det1 * width34 - width12 * det2) / det3; + if ((x >= x3 && x <= x4 || x >= x4 && x <= x3) && (x >= x1 && x <= x2 || x >= x2 && x <= x1)) { + let y = (det1 * height34 - height12 * det2) / det3; + if ((y >= y3 && y <= y4 || y >= y4 && y <= y3) && (y >= y1 && y <= y2 || y >= y2 && y <= y1)) return true; + } + x3 = x4; + y3 = y4; + } + return false; + } + /** Returns the polygon for the specified bounding box, or null. */ + getPolygon(boundingBox) { + if (!boundingBox) throw new Error("boundingBox cannot be null."); + let index = this.boundingBoxes.indexOf(boundingBox); + return index == -1 ? null : this.polygons[index]; + } + /** The width of the axis aligned bounding box. */ + getWidth() { + return this.maxX - this.minX; + } + /** The height of the axis aligned bounding box. */ + getHeight() { + return this.maxY - this.minY; + } + }; + + // spine-core/src/Triangulator.ts + var Triangulator = class _Triangulator { + convexPolygons = new Array(); + convexPolygonsIndices = new Array(); + indicesArray = new Array(); + isConcaveArray = new Array(); + triangles = new Array(); + polygonPool = new Pool(() => { + return new Array(); + }); + polygonIndicesPool = new Pool(() => { + return new Array(); + }); + triangulate(verticesArray) { + let vertices = verticesArray; + let vertexCount = verticesArray.length >> 1; + let indices = this.indicesArray; + indices.length = 0; + for (let i = 0; i < vertexCount; i++) + indices[i] = i; + let isConcave = this.isConcaveArray; + isConcave.length = 0; + for (let i = 0, n = vertexCount; i < n; ++i) + isConcave[i] = _Triangulator.isConcave(i, vertexCount, vertices, indices); + let triangles = this.triangles; + triangles.length = 0; + while (vertexCount > 3) { + let previous = vertexCount - 1, i = 0, next = 1; + while (true) { + outer: + if (!isConcave[i]) { + let p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1; + let p1x = vertices[p1], p1y = vertices[p1 + 1]; + let p2x = vertices[p2], p2y = vertices[p2 + 1]; + let p3x = vertices[p3], p3y = vertices[p3 + 1]; + for (let ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) { + if (!isConcave[ii]) continue; + let v = indices[ii] << 1; + let vx = vertices[v], vy = vertices[v + 1]; + if (_Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) { + if (_Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) { + if (_Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy)) break outer; + } + } + } + break; + } + if (next == 0) { + do { + if (!isConcave[i]) break; + i--; + } while (i > 0); + break; + } + previous = i; + i = next; + next = (next + 1) % vertexCount; + } + triangles.push(indices[(vertexCount + i - 1) % vertexCount]); + triangles.push(indices[i]); + triangles.push(indices[(i + 1) % vertexCount]); + indices.splice(i, 1); + isConcave.splice(i, 1); + vertexCount--; + let previousIndex = (vertexCount + i - 1) % vertexCount; + let nextIndex = i == vertexCount ? 0 : i; + isConcave[previousIndex] = _Triangulator.isConcave(previousIndex, vertexCount, vertices, indices); + isConcave[nextIndex] = _Triangulator.isConcave(nextIndex, vertexCount, vertices, indices); + } + if (vertexCount == 3) { + triangles.push(indices[2]); + triangles.push(indices[0]); + triangles.push(indices[1]); + } + return triangles; + } + decompose(verticesArray, triangles) { + let vertices = verticesArray; + let convexPolygons = this.convexPolygons; + this.polygonPool.freeAll(convexPolygons); + convexPolygons.length = 0; + let convexPolygonsIndices = this.convexPolygonsIndices; + this.polygonIndicesPool.freeAll(convexPolygonsIndices); + convexPolygonsIndices.length = 0; + let polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + let polygon = this.polygonPool.obtain(); + polygon.length = 0; + let fanBaseIndex = -1, lastWinding = 0; + for (let i = 0, n = triangles.length; i < n; i += 3) { + let t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1; + let x1 = vertices[t1], y1 = vertices[t1 + 1]; + let x2 = vertices[t2], y2 = vertices[t2 + 1]; + let x3 = vertices[t3], y3 = vertices[t3 + 1]; + let merged = false; + if (fanBaseIndex == t1) { + let o = polygon.length - 4; + let winding1 = _Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3); + let winding2 = _Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]); + if (winding1 == lastWinding && winding2 == lastWinding) { + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(t3); + merged = true; + } + } + if (!merged) { + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } else { + this.polygonPool.free(polygon); + this.polygonIndicesPool.free(polygonIndices); + } + polygon = this.polygonPool.obtain(); + polygon.length = 0; + polygon.push(x1); + polygon.push(y1); + polygon.push(x2); + polygon.push(y2); + polygon.push(x3); + polygon.push(y3); + polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + polygonIndices.push(t1); + polygonIndices.push(t2); + polygonIndices.push(t3); + lastWinding = _Triangulator.winding(x1, y1, x2, y2, x3, y3); + fanBaseIndex = t1; + } + } + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + for (let i = 0, n = convexPolygons.length; i < n; i++) { + polygonIndices = convexPolygonsIndices[i]; + if (polygonIndices.length == 0) continue; + let firstIndex = polygonIndices[0]; + let lastIndex = polygonIndices[polygonIndices.length - 1]; + polygon = convexPolygons[i]; + let o = polygon.length - 4; + let prevPrevX = polygon[o], prevPrevY = polygon[o + 1]; + let prevX = polygon[o + 2], prevY = polygon[o + 3]; + let firstX = polygon[0], firstY = polygon[1]; + let secondX = polygon[2], secondY = polygon[3]; + let winding = _Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY); + for (let ii = 0; ii < n; ii++) { + if (ii == i) continue; + let otherIndices = convexPolygonsIndices[ii]; + if (otherIndices.length != 3) continue; + let otherFirstIndex = otherIndices[0]; + let otherSecondIndex = otherIndices[1]; + let otherLastIndex = otherIndices[2]; + let otherPoly = convexPolygons[ii]; + let x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1]; + if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) continue; + let winding1 = _Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3); + let winding2 = _Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY); + if (winding1 == winding && winding2 == winding) { + otherPoly.length = 0; + otherIndices.length = 0; + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(otherLastIndex); + prevPrevX = prevX; + prevPrevY = prevY; + prevX = x3; + prevY = y3; + ii = 0; + } + } + } + for (let i = convexPolygons.length - 1; i >= 0; i--) { + polygon = convexPolygons[i]; + if (polygon.length == 0) { + convexPolygons.splice(i, 1); + this.polygonPool.free(polygon); + polygonIndices = convexPolygonsIndices[i]; + convexPolygonsIndices.splice(i, 1); + this.polygonIndicesPool.free(polygonIndices); + } + } + return convexPolygons; + } + static isConcave(index, vertexCount, vertices, indices) { + let previous = indices[(vertexCount + index - 1) % vertexCount] << 1; + let current = indices[index] << 1; + let next = indices[(index + 1) % vertexCount] << 1; + return !this.positiveArea( + vertices[previous], + vertices[previous + 1], + vertices[current], + vertices[current + 1], + vertices[next], + vertices[next + 1] + ); + } + static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y) { + return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; + } + static winding(p1x, p1y, p2x, p2y, p3x, p3y) { + let px = p2x - p1x, py = p2y - p1y; + return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; + } + }; + + // spine-core/src/SkeletonClipping.ts + var SkeletonClipping = class _SkeletonClipping { + triangulator = new Triangulator(); + clippingPolygon = new Array(); + clipOutput = new Array(); + clippedVertices = new Array(); + clippedUVs = new Array(); + clippedTriangles = new Array(); + scratch = new Array(); + clipAttachment = null; + clippingPolygons = null; + clipStart(slot, clip) { + if (this.clipAttachment) return 0; + this.clipAttachment = clip; + let n = clip.worldVerticesLength; + let vertices = Utils.setArraySize(this.clippingPolygon, n); + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + let clippingPolygon = this.clippingPolygon; + _SkeletonClipping.makeClockwise(clippingPolygon); + let clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon)); + for (let i = 0, n2 = clippingPolygons.length; i < n2; i++) { + let polygon = clippingPolygons[i]; + _SkeletonClipping.makeClockwise(polygon); + polygon.push(polygon[0]); + polygon.push(polygon[1]); + } + return clippingPolygons.length; + } + clipEndWithSlot(slot) { + if (this.clipAttachment && this.clipAttachment.endSlot == slot.data) this.clipEnd(); + } + clipEnd() { + if (!this.clipAttachment) return; + this.clipAttachment = null; + this.clippingPolygons = null; + this.clippedVertices.length = 0; + this.clippedTriangles.length = 0; + this.clippingPolygon.length = 0; + } + isClipping() { + return this.clipAttachment != null; + } + clipTriangles(vertices, verticesLengthOrTriangles, trianglesOrTrianglesLength, trianglesLengthOrUvs, uvsOrLight, lightOrDark, darkOrTwoColor, twoColorParam) { + let triangles; + let trianglesLength; + let uvs; + let light; + let dark; + let twoColor; + if (typeof verticesLengthOrTriangles === "number") { + triangles = trianglesOrTrianglesLength; + trianglesLength = trianglesLengthOrUvs; + uvs = uvsOrLight; + light = lightOrDark; + dark = darkOrTwoColor; + twoColor = twoColorParam; + } else { + triangles = verticesLengthOrTriangles; + trianglesLength = trianglesOrTrianglesLength; + uvs = trianglesLengthOrUvs; + light = uvsOrLight; + dark = lightOrDark; + twoColor = darkOrTwoColor; + } + if (uvs && light && dark && typeof twoColor === "boolean") + this.clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor); + else + this.clipTrianglesNoRender(vertices, triangles, trianglesLength); + } + clipTrianglesNoRender(vertices, triangles, trianglesLength) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = polygons.length; + let index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) continue; + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * 2); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += 2) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++, s += 3) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + } + index += clipOutputCount + 1; + } else { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * 2); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = x2; + clippedVerticesItems[s + 3] = y2; + clippedVerticesItems[s + 4] = x3; + clippedVerticesItems[s + 5] = y3; + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; + } + } + } + } + clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = polygons.length; + let vertexSize = twoColor ? 12 : 8; + let index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) continue; + let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + let d = 1 / (d0 * d2 + d1 * (y1 - y3)); + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += vertexSize) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + let c0 = x - x3, c1 = y - y3; + let a = (d0 * c0 + d1 * c1) * d; + let b = (d4 * c0 + d2 * c1) * d; + let c = 1 - a - b; + clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c; + clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c; + if (twoColor) { + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + } + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++, s += 3) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + } + index += clipOutputCount + 1; + } else { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * vertexSize); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + if (!twoColor) { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = x2; + clippedVerticesItems[s + 9] = y2; + clippedVerticesItems[s + 10] = light.r; + clippedVerticesItems[s + 11] = light.g; + clippedVerticesItems[s + 12] = light.b; + clippedVerticesItems[s + 13] = light.a; + clippedVerticesItems[s + 14] = u2; + clippedVerticesItems[s + 15] = v2; + clippedVerticesItems[s + 16] = x3; + clippedVerticesItems[s + 17] = y3; + clippedVerticesItems[s + 18] = light.r; + clippedVerticesItems[s + 19] = light.g; + clippedVerticesItems[s + 20] = light.b; + clippedVerticesItems[s + 21] = light.a; + clippedVerticesItems[s + 22] = u3; + clippedVerticesItems[s + 23] = v3; + } else { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + clippedVerticesItems[s + 12] = x2; + clippedVerticesItems[s + 13] = y2; + clippedVerticesItems[s + 14] = light.r; + clippedVerticesItems[s + 15] = light.g; + clippedVerticesItems[s + 16] = light.b; + clippedVerticesItems[s + 17] = light.a; + clippedVerticesItems[s + 18] = u2; + clippedVerticesItems[s + 19] = v2; + clippedVerticesItems[s + 20] = dark.r; + clippedVerticesItems[s + 21] = dark.g; + clippedVerticesItems[s + 22] = dark.b; + clippedVerticesItems[s + 23] = dark.a; + clippedVerticesItems[s + 24] = x3; + clippedVerticesItems[s + 25] = y3; + clippedVerticesItems[s + 26] = light.r; + clippedVerticesItems[s + 27] = light.g; + clippedVerticesItems[s + 28] = light.b; + clippedVerticesItems[s + 29] = light.a; + clippedVerticesItems[s + 30] = u3; + clippedVerticesItems[s + 31] = v3; + clippedVerticesItems[s + 32] = dark.r; + clippedVerticesItems[s + 33] = dark.g; + clippedVerticesItems[s + 34] = dark.b; + clippedVerticesItems[s + 35] = dark.a; + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; + } + } + } + } + clipTrianglesUnpacked(vertices, triangles, trianglesLength, uvs) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices, clippedUVs = this.clippedUVs; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = polygons.length; + let index = 0; + clippedVertices.length = 0; + clippedUVs.length = 0; + clippedTriangles.length = 0; + for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) continue; + let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + let d = 1 / (d0 * d2 + d1 * (y1 - y3)); + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * 2); + let clippedUVsItems = Utils.setArraySize(clippedUVs, s + clipOutputCount * 2); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += 2) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + let c0 = x - x3, c1 = y - y3; + let a = (d0 * c0 + d1 * c1) * d; + let b = (d4 * c0 + d2 * c1) * d; + let c = 1 - a - b; + clippedUVsItems[s] = u1 * a + u2 * b + u3 * c; + clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c; + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++, s += 3) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + } + index += clipOutputCount + 1; + } else { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * 2); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = x2; + clippedVerticesItems[s + 3] = y2; + clippedVerticesItems[s + 4] = x3; + clippedVerticesItems[s + 5] = y3; + let clippedUVSItems = Utils.setArraySize(clippedUVs, s + 3 * 2); + clippedUVSItems[s] = u1; + clippedUVSItems[s + 1] = v1; + clippedUVSItems[s + 2] = u2; + clippedUVSItems[s + 3] = v2; + clippedUVSItems[s + 4] = u3; + clippedUVSItems[s + 5] = v3; + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; + } + } + } + } + /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping + * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */ + clip(x1, y1, x2, y2, x3, y3, clippingArea, output) { + let originalOutput = output; + let clipped = false; + let input; + if (clippingArea.length % 4 >= 2) { + input = output; + output = this.scratch; + } else + input = this.scratch; + input.length = 0; + input.push(x1); + input.push(y1); + input.push(x2); + input.push(y2); + input.push(x3); + input.push(y3); + input.push(x1); + input.push(y1); + output.length = 0; + let clippingVerticesLast = clippingArea.length - 4; + let clippingVertices = clippingArea; + for (let i = 0; ; i += 2) { + let edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; + let ex = edgeX - clippingVertices[i + 2], ey = edgeY - clippingVertices[i + 3]; + let outputStart = output.length; + let inputVertices = input; + for (let ii = 0, nn = input.length - 2; ii < nn; ) { + let inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; + ii += 2; + let inputX2 = inputVertices[ii], inputY2 = inputVertices[ii + 1]; + let s2 = ey * (edgeX - inputX2) > ex * (edgeY - inputY2); + let s1 = ey * (edgeX - inputX) - ex * (edgeY - inputY); + if (s1 > 0) { + if (s2) { + output.push(inputX2); + output.push(inputY2); + continue; + } + let ix = inputX2 - inputX, iy = inputY2 - inputY, t = s1 / (ix * ey - iy * ex); + if (t >= 0 && t <= 1) { + output.push(inputX + ix * t); + output.push(inputY + iy * t); + } else { + output.push(inputX2); + output.push(inputY2); + continue; + } + } else if (s2) { + let ix = inputX2 - inputX, iy = inputY2 - inputY, t = s1 / (ix * ey - iy * ex); + if (t >= 0 && t <= 1) { + output.push(inputX + ix * t); + output.push(inputY + iy * t); + output.push(inputX2); + output.push(inputY2); + } else { + output.push(inputX2); + output.push(inputY2); + continue; + } + } + clipped = true; + } + if (outputStart == output.length) { + originalOutput.length = 0; + return true; + } + output.push(output[0]); + output.push(output[1]); + if (i == clippingVerticesLast) break; + let temp = output; + output = input; + output.length = 0; + input = temp; + } + if (originalOutput != output) { + originalOutput.length = 0; + for (let i = 0, n = output.length - 2; i < n; i++) + originalOutput[i] = output[i]; + } else + originalOutput.length = originalOutput.length - 2; + return clipped; + } + static makeClockwise(polygon) { + let vertices = polygon; + let verticeslength = polygon.length; + let area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0; + for (let i = 0, n = verticeslength - 3; i < n; i += 2) { + p1x = vertices[i]; + p1y = vertices[i + 1]; + p2x = vertices[i + 2]; + p2y = vertices[i + 3]; + area += p1x * p2y - p2x * p1y; + } + if (area < 0) return; + for (let i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { + let x = vertices[i], y = vertices[i + 1]; + let other = lastX - i; + vertices[i] = vertices[other]; + vertices[i + 1] = vertices[other + 1]; + vertices[other] = x; + vertices[other + 1] = y; + } + } + }; + + // spine-core/src/SkeletonJson.ts + var SkeletonJson = class { + attachmentLoader; + /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at + * runtime than were used in Spine. + * + * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ + scale = 1; + linkedMeshes = new Array(); + constructor(attachmentLoader) { + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(json) { + let scale = this.scale; + let skeletonData = new SkeletonData(); + let root = typeof json === "string" ? JSON.parse(json) : json; + let skeletonMap = root.skeleton; + if (skeletonMap) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + skeletonData.x = skeletonMap.x; + skeletonData.y = skeletonMap.y; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.referenceScale = getValue(skeletonMap, "referenceScale", 100) * scale; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images ?? null; + skeletonData.audioPath = skeletonMap.audio ?? null; + } + if (root.bones) { + for (let i = 0; i < root.bones.length; i++) { + let boneMap = root.bones[i]; + let parent = null; + let parentName = getValue(boneMap, "parent", null); + if (parentName) parent = skeletonData.findBone(parentName); + let data = new BoneData(skeletonData.bones.length, boneMap.name, parent); + data.length = getValue(boneMap, "length", 0) * scale; + data.x = getValue(boneMap, "x", 0) * scale; + data.y = getValue(boneMap, "y", 0) * scale; + data.rotation = getValue(boneMap, "rotation", 0); + data.scaleX = getValue(boneMap, "scaleX", 1); + data.scaleY = getValue(boneMap, "scaleY", 1); + data.shearX = getValue(boneMap, "shearX", 0); + data.shearY = getValue(boneMap, "shearY", 0); + data.inherit = Utils.enumValue(Inherit, getValue(boneMap, "inherit", "Normal")); + data.skinRequired = getValue(boneMap, "skin", false); + let color = getValue(boneMap, "color", null); + if (color) data.color.setFromString(color); + skeletonData.bones.push(data); + } + } + if (root.slots) { + for (let i = 0; i < root.slots.length; i++) { + let slotMap = root.slots[i]; + let slotName = slotMap.name; + let boneData = skeletonData.findBone(slotMap.bone); + if (!boneData) throw new Error(`Couldn't find bone ${slotMap.bone} for slot ${slotName}`); + let data = new SlotData(skeletonData.slots.length, slotName, boneData); + let color = getValue(slotMap, "color", null); + if (color) data.color.setFromString(color); + let dark = getValue(slotMap, "dark", null); + if (dark) data.darkColor = Color.fromString(dark); + data.attachmentName = getValue(slotMap, "attachment", null); + data.blendMode = Utils.enumValue(BlendMode, getValue(slotMap, "blend", "normal")); + data.visible = getValue(slotMap, "visible", true); + skeletonData.slots.push(data); + } + } + if (root.ik) { + for (let i = 0; i < root.ik.length; i++) { + let constraintMap = root.ik[i]; + let data = new IkConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (let ii = 0; ii < constraintMap.bones.length; ii++) { + let bone = skeletonData.findBone(constraintMap.bones[ii]); + if (!bone) throw new Error(`Couldn't find bone ${constraintMap.bones[ii]} for IK constraint ${constraintMap.name}.`); + data.bones.push(bone); + } + let target = skeletonData.findBone(constraintMap.target); + ; + if (!target) throw new Error(`Couldn't find target bone ${constraintMap.target} for IK constraint ${constraintMap.name}.`); + data.target = target; + data.mix = getValue(constraintMap, "mix", 1); + data.softness = getValue(constraintMap, "softness", 0) * scale; + data.bendDirection = getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = getValue(constraintMap, "compress", false); + data.stretch = getValue(constraintMap, "stretch", false); + data.uniform = getValue(constraintMap, "uniform", false); + skeletonData.ikConstraints.push(data); + } + } + if (root.transform) { + for (let i = 0; i < root.transform.length; i++) { + let constraintMap = root.transform[i]; + let data = new TransformConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (let ii = 0; ii < constraintMap.bones.length; ii++) { + let boneName = constraintMap.bones[ii]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error(`Couldn't find bone ${boneName} for transform constraint ${constraintMap.name}.`); + data.bones.push(bone); + } + let targetName = constraintMap.target; + let target = skeletonData.findBone(targetName); + if (!target) throw new Error(`Couldn't find target bone ${targetName} for transform constraint ${constraintMap.name}.`); + data.target = target; + data.local = getValue(constraintMap, "local", false); + data.relative = getValue(constraintMap, "relative", false); + data.offsetRotation = getValue(constraintMap, "rotation", 0); + data.offsetX = getValue(constraintMap, "x", 0) * scale; + data.offsetY = getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = getValue(constraintMap, "scaleY", 0); + data.offsetShearY = getValue(constraintMap, "shearY", 0); + data.mixRotate = getValue(constraintMap, "mixRotate", 1); + data.mixX = getValue(constraintMap, "mixX", 1); + data.mixY = getValue(constraintMap, "mixY", data.mixX); + data.mixScaleX = getValue(constraintMap, "mixScaleX", 1); + data.mixScaleY = getValue(constraintMap, "mixScaleY", data.mixScaleX); + data.mixShearY = getValue(constraintMap, "mixShearY", 1); + skeletonData.transformConstraints.push(data); + } + } + if (root.path) { + for (let i = 0; i < root.path.length; i++) { + let constraintMap = root.path[i]; + let data = new PathConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (let ii = 0; ii < constraintMap.bones.length; ii++) { + let boneName = constraintMap.bones[ii]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error(`Couldn't find bone ${boneName} for path constraint ${constraintMap.name}.`); + data.bones.push(bone); + } + let targetName = constraintMap.target; + let target = skeletonData.findSlot(targetName); + if (!target) throw new Error(`Couldn't find target slot ${targetName} for path constraint ${constraintMap.name}.`); + data.target = target; + data.positionMode = Utils.enumValue(PositionMode, getValue(constraintMap, "positionMode", "Percent")); + data.spacingMode = Utils.enumValue(SpacingMode, getValue(constraintMap, "spacingMode", "Length")); + data.rotateMode = Utils.enumValue(RotateMode, getValue(constraintMap, "rotateMode", "Tangent")); + data.offsetRotation = getValue(constraintMap, "rotation", 0); + data.position = getValue(constraintMap, "position", 0); + if (data.positionMode == 0 /* Fixed */) data.position *= scale; + data.spacing = getValue(constraintMap, "spacing", 0); + if (data.spacingMode == 0 /* Length */ || data.spacingMode == 1 /* Fixed */) data.spacing *= scale; + data.mixRotate = getValue(constraintMap, "mixRotate", 1); + data.mixX = getValue(constraintMap, "mixX", 1); + data.mixY = getValue(constraintMap, "mixY", data.mixX); + skeletonData.pathConstraints.push(data); + } + } + if (root.physics) { + for (let i = 0; i < root.physics.length; i++) { + const constraintMap = root.physics[i]; + const data = new PhysicsConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + const boneName = constraintMap.bone; + const bone = skeletonData.findBone(boneName); + if (bone == null) throw new Error("Physics bone not found: " + boneName); + data.bone = bone; + data.x = getValue(constraintMap, "x", 0); + data.y = getValue(constraintMap, "y", 0); + data.rotate = getValue(constraintMap, "rotate", 0); + data.scaleX = getValue(constraintMap, "scaleX", 0); + data.shearX = getValue(constraintMap, "shearX", 0); + data.limit = getValue(constraintMap, "limit", 5e3) * scale; + data.step = 1 / getValue(constraintMap, "fps", 60); + data.inertia = getValue(constraintMap, "inertia", 1); + data.strength = getValue(constraintMap, "strength", 100); + data.damping = getValue(constraintMap, "damping", 1); + data.massInverse = 1 / getValue(constraintMap, "mass", 1); + data.wind = getValue(constraintMap, "wind", 0); + data.gravity = getValue(constraintMap, "gravity", 0); + data.mix = getValue(constraintMap, "mix", 1); + data.inertiaGlobal = getValue(constraintMap, "inertiaGlobal", false); + data.strengthGlobal = getValue(constraintMap, "strengthGlobal", false); + data.dampingGlobal = getValue(constraintMap, "dampingGlobal", false); + data.massGlobal = getValue(constraintMap, "massGlobal", false); + data.windGlobal = getValue(constraintMap, "windGlobal", false); + data.gravityGlobal = getValue(constraintMap, "gravityGlobal", false); + data.mixGlobal = getValue(constraintMap, "mixGlobal", false); + skeletonData.physicsConstraints.push(data); + } + } + if (root.skins) { + for (let i = 0; i < root.skins.length; i++) { + let skinMap = root.skins[i]; + let skin = new Skin(skinMap.name); + if (skinMap.bones) { + for (let ii = 0; ii < skinMap.bones.length; ii++) { + let boneName = skinMap.bones[ii]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error(`Couldn't find bone ${boneName} for skin ${skinMap.name}.`); + skin.bones.push(bone); + } + } + if (skinMap.ik) { + for (let ii = 0; ii < skinMap.ik.length; ii++) { + let constraintName = skinMap.ik[ii]; + let constraint = skeletonData.findIkConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find IK constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + if (skinMap.transform) { + for (let ii = 0; ii < skinMap.transform.length; ii++) { + let constraintName = skinMap.transform[ii]; + let constraint = skeletonData.findTransformConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find transform constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + if (skinMap.path) { + for (let ii = 0; ii < skinMap.path.length; ii++) { + let constraintName = skinMap.path[ii]; + let constraint = skeletonData.findPathConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find path constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + if (skinMap.physics) { + for (let ii = 0; ii < skinMap.physics.length; ii++) { + let constraintName = skinMap.physics[ii]; + let constraint = skeletonData.findPhysicsConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find physics constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + for (let slotName in skinMap.attachments) { + let slot = skeletonData.findSlot(slotName); + if (!slot) throw new Error(`Couldn't find slot ${slotName} for skin ${skinMap.name}.`); + let slotMap = skinMap.attachments[slotName]; + for (let entryName in slotMap) { + let attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); + if (attachment) skin.setAttachment(slot.index, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") skeletonData.defaultSkin = skin; + } + } + for (let i = 0, n = this.linkedMeshes.length; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + let skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (!skin) throw new Error(`Skin not found: ${linkedMesh.skin}`); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (!parent) throw new Error(`Parent mesh not found: ${linkedMesh.parent}`); + linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent); + if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); + } + this.linkedMeshes.length = 0; + if (root.events) { + for (let eventName in root.events) { + let eventMap = root.events[eventName]; + let data = new EventData(eventName); + data.intValue = getValue(eventMap, "int", 0); + data.floatValue = getValue(eventMap, "float", 0); + data.stringValue = getValue(eventMap, "string", ""); + data.audioPath = getValue(eventMap, "audio", null); + if (data.audioPath) { + data.volume = getValue(eventMap, "volume", 1); + data.balance = getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + if (root.animations) { + for (let animationName in root.animations) { + let animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + } + readAttachment(map, skin, slotIndex, name, skeletonData) { + let scale = this.scale; + name = getValue(map, "name", name); + switch (getValue(map, "type", "region")) { + case "region": { + let path = getValue(map, "path", name); + let sequence = this.readSequence(getValue(map, "sequence", null)); + let region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); + if (!region) return null; + region.path = path; + region.x = getValue(map, "x", 0) * scale; + region.y = getValue(map, "y", 0) * scale; + region.scaleX = getValue(map, "scaleX", 1); + region.scaleY = getValue(map, "scaleY", 1); + region.rotation = getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + region.sequence = sequence; + let color = getValue(map, "color", null); + if (color) region.color.setFromString(color); + if (region.region != null) region.updateRegion(); + return region; + } + case "boundingbox": { + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (!box) return null; + this.readVertices(map, box, map.vertexCount << 1); + let color = getValue(map, "color", null); + if (color) box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + let path = getValue(map, "path", name); + let sequence = this.readSequence(getValue(map, "sequence", null)); + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) return null; + mesh.path = path; + let color = getValue(map, "color", null); + if (color) mesh.color.setFromString(color); + mesh.width = getValue(map, "width", 0) * scale; + mesh.height = getValue(map, "height", 0) * scale; + mesh.sequence = sequence; + let parent = getValue(map, "parent", null); + if (parent) { + this.linkedMeshes.push(new LinkedMesh2(mesh, getValue(map, "skin", null), slotIndex, parent, getValue(map, "timelines", true))); + return mesh; + } + let uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = uvs; + if (mesh.region != null) mesh.updateRegion(); + mesh.edges = getValue(map, "edges", null); + mesh.hullLength = getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + let path = this.attachmentLoader.newPathAttachment(skin, name); + if (!path) return null; + path.closed = getValue(map, "closed", false); + path.constantSpeed = getValue(map, "constantSpeed", true); + let vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + let lengths = Utils.newArray(vertexCount / 3, 0); + for (let i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + let color = getValue(map, "color", null); + if (color) path.color.setFromString(color); + return path; + } + case "point": { + let point = this.attachmentLoader.newPointAttachment(skin, name); + if (!point) return null; + point.x = getValue(map, "x", 0) * scale; + point.y = getValue(map, "y", 0) * scale; + point.rotation = getValue(map, "rotation", 0); + let color = getValue(map, "color", null); + if (color) point.color.setFromString(color); + return point; + } + case "clipping": { + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (!clip) return null; + let end = getValue(map, "end", null); + if (end) clip.endSlot = skeletonData.findSlot(end); + let vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + let color = getValue(map, "color", null); + if (color) clip.color.setFromString(color); + return clip; + } + } + return null; + } + readSequence(map) { + if (map == null) return null; + let sequence = new Sequence(getValue(map, "count", 0)); + sequence.start = getValue(map, "start", 1); + sequence.digits = getValue(map, "digits", 0); + sequence.setupIndex = getValue(map, "setup", 0); + return sequence; + } + readVertices(map, attachment, verticesLength) { + let scale = this.scale; + attachment.worldVerticesLength = verticesLength; + let vertices = map.vertices; + if (verticesLength == vertices.length) { + let scaledVertices = Utils.toFloatArray(vertices); + if (scale != 1) { + for (let i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + let weights = new Array(); + let bones = new Array(); + for (let i = 0, n = vertices.length; i < n; ) { + let boneCount = vertices[i++]; + bones.push(boneCount); + for (let nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = Utils.toFloatArray(weights); + } + readAnimation(map, name, skeletonData) { + let scale = this.scale; + let timelines = new Array(); + if (map.slots) { + for (let slotName in map.slots) { + let slotMap = map.slots[slotName]; + let slot = skeletonData.findSlot(slotName); + if (!slot) throw new Error("Slot not found: " + slotName); + let slotIndex = slot.index; + for (let timelineName in slotMap) { + let timelineMap = slotMap[timelineName]; + if (!timelineMap) continue; + let frames = timelineMap.length; + if (timelineName == "attachment") { + let timeline = new AttachmentTimeline(frames, slotIndex); + for (let frame = 0; frame < frames; frame++) { + let keyMap = timelineMap[frame]; + timeline.setFrame(frame, getValue(keyMap, "time", 0), getValue(keyMap, "name", null)); + } + timelines.push(timeline); + } else if (timelineName == "rgba") { + let timeline = new RGBATimeline(frames, frames << 2, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.color); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color.a); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.color); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); + } + time = time2; + color = newColor; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineName == "rgb") { + let timeline = new RGBTimeline(frames, frames * 3, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.color); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.color); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + } + time = time2; + color = newColor; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineName == "alpha") { + timelines.push(readTimeline12(timelineMap, new AlphaTimeline(frames, frames, slotIndex), 0, 1)); + } else if (timelineName == "rgba2") { + let timeline = new RGBA2Timeline(frames, frames * 7, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.light); + let color2 = Color.fromString(keyMap.dark); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.light); + let newColor2 = Color.fromString(nextMap.dark); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1); + } + time = time2; + color = newColor; + color2 = newColor2; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineName == "rgb2") { + let timeline = new RGB2Timeline(frames, frames * 6, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.light); + let color2 = Color.fromString(keyMap.dark); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color2.r, color2.g, color2.b); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.light); + let newColor2 = Color.fromString(nextMap.dark); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1); + } + time = time2; + color = newColor; + color2 = newColor2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + } + } + if (map.bones) { + for (let boneName in map.bones) { + let boneMap = map.bones[boneName]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error("Bone not found: " + boneName); + let boneIndex = bone.index; + for (let timelineName in boneMap) { + let timelineMap = boneMap[timelineName]; + let frames = timelineMap.length; + if (frames == 0) continue; + if (timelineName === "rotate") { + timelines.push(readTimeline12(timelineMap, new RotateTimeline(frames, frames, boneIndex), 0, 1)); + } else if (timelineName === "translate") { + let timeline = new TranslateTimeline(frames, frames << 1, boneIndex); + timelines.push(readTimeline22(timelineMap, timeline, "x", "y", 0, scale)); + } else if (timelineName === "translatex") { + let timeline = new TranslateXTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, scale)); + } else if (timelineName === "translatey") { + let timeline = new TranslateYTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, scale)); + } else if (timelineName === "scale") { + let timeline = new ScaleTimeline(frames, frames << 1, boneIndex); + timelines.push(readTimeline22(timelineMap, timeline, "x", "y", 1, 1)); + } else if (timelineName === "scalex") { + let timeline = new ScaleXTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 1, 1)); + } else if (timelineName === "scaley") { + let timeline = new ScaleYTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 1, 1)); + } else if (timelineName === "shear") { + let timeline = new ShearTimeline(frames, frames << 1, boneIndex); + timelines.push(readTimeline22(timelineMap, timeline, "x", "y", 0, 1)); + } else if (timelineName === "shearx") { + let timeline = new ShearXTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, 1)); + } else if (timelineName === "sheary") { + let timeline = new ShearYTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, 1)); + } else if (timelineName === "inherit") { + let timeline = new InheritTimeline(frames, bone.index); + for (let frame = 0; frame < timelineMap.length; frame++) { + let aFrame = timelineMap[frame]; + timeline.setFrame(frame, getValue(aFrame, "time", 0), Utils.enumValue(Inherit, getValue(aFrame, "inherit", "Normal"))); + } + timelines.push(timeline); + } + } + } + } + if (map.ik) { + for (let constraintName in map.ik) { + let constraintMap = map.ik[constraintName]; + let keyMap = constraintMap[0]; + if (!keyMap) continue; + let constraint = skeletonData.findIkConstraint(constraintName); + if (!constraint) throw new Error("IK Constraint not found: " + constraintName); + let constraintIndex = skeletonData.ikConstraints.indexOf(constraint); + let timeline = new IkConstraintTimeline(constraintMap.length, constraintMap.length << 1, constraintIndex); + let time = getValue(keyMap, "time", 0); + let mix = getValue(keyMap, "mix", 1); + let softness = getValue(keyMap, "softness", 0) * scale; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mix, softness, getValue(keyMap, "bendPositive", true) ? 1 : -1, getValue(keyMap, "compress", false), getValue(keyMap, "stretch", false)); + let nextMap = constraintMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let mix2 = getValue(nextMap, "mix", 1); + let softness2 = getValue(nextMap, "softness", 0) * scale; + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, scale); + } + time = time2; + mix = mix2; + softness = softness2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + if (map.transform) { + for (let constraintName in map.transform) { + let timelineMap = map.transform[constraintName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + let constraint = skeletonData.findTransformConstraint(constraintName); + if (!constraint) throw new Error("Transform constraint not found: " + constraintName); + let constraintIndex = skeletonData.transformConstraints.indexOf(constraint); + let timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, constraintIndex); + let time = getValue(keyMap, "time", 0); + let mixRotate = getValue(keyMap, "mixRotate", 1); + let mixX = getValue(keyMap, "mixX", 1); + let mixY = getValue(keyMap, "mixY", mixX); + let mixScaleX = getValue(keyMap, "mixScaleX", 1); + let mixScaleY = getValue(keyMap, "mixScaleY", mixScaleX); + let mixShearY = getValue(keyMap, "mixShearY", 1); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let mixRotate2 = getValue(nextMap, "mixRotate", 1); + let mixX2 = getValue(nextMap, "mixX", 1); + let mixY2 = getValue(nextMap, "mixY", mixX2); + let mixScaleX2 = getValue(nextMap, "mixScaleX", 1); + let mixScaleY2 = getValue(nextMap, "mixScaleY", mixScaleX2); + let mixShearY2 = getValue(nextMap, "mixShearY", 1); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixScaleX = mixScaleX2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + if (map.path) { + for (let constraintName in map.path) { + let constraintMap = map.path[constraintName]; + let constraint = skeletonData.findPathConstraint(constraintName); + if (!constraint) throw new Error("Path constraint not found: " + constraintName); + let constraintIndex = skeletonData.pathConstraints.indexOf(constraint); + for (let timelineName in constraintMap) { + let timelineMap = constraintMap[timelineName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + let frames = timelineMap.length; + if (timelineName === "position") { + let timeline = new PathConstraintPositionTimeline(frames, frames, constraintIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, constraint.positionMode == 0 /* Fixed */ ? scale : 1)); + } else if (timelineName === "spacing") { + let timeline = new PathConstraintSpacingTimeline(frames, frames, constraintIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, constraint.spacingMode == 0 /* Length */ || constraint.spacingMode == 1 /* Fixed */ ? scale : 1)); + } else if (timelineName === "mix") { + let timeline = new PathConstraintMixTimeline(frames, frames * 3, constraintIndex); + let time = getValue(keyMap, "time", 0); + let mixRotate = getValue(keyMap, "mixRotate", 1); + let mixX = getValue(keyMap, "mixX", 1); + let mixY = getValue(keyMap, "mixY", mixX); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let mixRotate2 = getValue(nextMap, "mixRotate", 1); + let mixX2 = getValue(nextMap, "mixX", 1); + let mixY2 = getValue(nextMap, "mixY", mixX2); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + } + } + if (map.physics) { + for (let constraintName in map.physics) { + let constraintMap = map.physics[constraintName]; + let constraintIndex = -1; + if (constraintName.length > 0) { + let constraint = skeletonData.findPhysicsConstraint(constraintName); + if (!constraint) throw new Error("Physics constraint not found: " + constraintName); + constraintIndex = skeletonData.physicsConstraints.indexOf(constraint); + } + for (let timelineName in constraintMap) { + let timelineMap = constraintMap[timelineName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + let frames = timelineMap.length; + if (timelineName == "reset") { + const timeline2 = new PhysicsConstraintResetTimeline(frames, constraintIndex); + for (let frame = 0; keyMap != null; keyMap = timelineMap[frame + 1], frame++) + timeline2.setFrame(frame, getValue(keyMap, "time", 0)); + timelines.push(timeline2); + continue; + } + let timeline; + if (timelineName == "inertia") + timeline = new PhysicsConstraintInertiaTimeline(frames, frames, constraintIndex); + else if (timelineName == "strength") + timeline = new PhysicsConstraintStrengthTimeline(frames, frames, constraintIndex); + else if (timelineName == "damping") + timeline = new PhysicsConstraintDampingTimeline(frames, frames, constraintIndex); + else if (timelineName == "mass") + timeline = new PhysicsConstraintMassTimeline(frames, frames, constraintIndex); + else if (timelineName == "wind") + timeline = new PhysicsConstraintWindTimeline(frames, frames, constraintIndex); + else if (timelineName == "gravity") + timeline = new PhysicsConstraintGravityTimeline(frames, frames, constraintIndex); + else if (timelineName == "mix") + timeline = new PhysicsConstraintMixTimeline(frames, frames, constraintIndex); + else + continue; + timelines.push(readTimeline12(timelineMap, timeline, 0, 1)); + } + } + } + if (map.attachments) { + for (let attachmentsName in map.attachments) { + let attachmentsMap = map.attachments[attachmentsName]; + let skin = skeletonData.findSkin(attachmentsName); + if (!skin) throw new Error("Skin not found: " + attachmentsName); + for (let slotMapName in attachmentsMap) { + let slotMap = attachmentsMap[slotMapName]; + let slot = skeletonData.findSlot(slotMapName); + if (!slot) throw new Error("Slot not found: " + slotMapName); + let slotIndex = slot.index; + for (let attachmentMapName in slotMap) { + let attachmentMap = slotMap[attachmentMapName]; + let attachment = skin.getAttachment(slotIndex, attachmentMapName); + for (let timelineMapName in attachmentMap) { + let timelineMap = attachmentMap[timelineMapName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + if (timelineMapName == "deform") { + let weighted = attachment.bones; + let vertices = attachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment); + let time = getValue(keyMap, "time", 0); + for (let frame = 0, bezier = 0; ; frame++) { + let deform; + let verticesValue = getValue(keyMap, "vertices", null); + if (!verticesValue) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + let start = getValue(keyMap, "offset", 0); + Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (let i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (let i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frame, time, deform); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let curve = keyMap.curve; + if (curve) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1); + time = time2; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineMapName == "sequence") { + let timeline = new SequenceTimeline(timelineMap.length, slotIndex, attachment); + let lastDelay = 0; + for (let frame = 0; frame < timelineMap.length; frame++) { + let delay = getValue(keyMap, "delay", lastDelay); + let time = getValue(keyMap, "time", 0); + let mode = SequenceMode[getValue(keyMap, "mode", "hold")]; + let index = getValue(keyMap, "index", 0); + timeline.setFrame(frame, time, mode, index, delay); + lastDelay = delay; + keyMap = timelineMap[frame + 1]; + } + timelines.push(timeline); + } + } + } + } + } + } + if (map.drawOrder) { + let timeline = new DrawOrderTimeline(map.drawOrder.length); + let slotCount = skeletonData.slots.length; + let frame = 0; + for (let i = 0; i < map.drawOrder.length; i++, frame++) { + let drawOrderMap = map.drawOrder[i]; + let drawOrder = null; + let offsets = getValue(drawOrderMap, "offsets", null); + if (offsets) { + drawOrder = Utils.newArray(slotCount, -1); + let unchanged = Utils.newArray(slotCount - offsets.length, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let ii = 0; ii < offsets.length; ii++) { + let offsetMap = offsets[ii]; + let slot = skeletonData.findSlot(offsetMap.slot); + if (!slot) throw new Error("Slot not found: " + slot); + let slotIndex = slot.index; + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frame, getValue(drawOrderMap, "time", 0), drawOrder); + } + timelines.push(timeline); + } + if (map.events) { + let timeline = new EventTimeline(map.events.length); + let frame = 0; + for (let i = 0; i < map.events.length; i++, frame++) { + let eventMap = map.events[i]; + let eventData = skeletonData.findEvent(eventMap.name); + if (!eventData) throw new Error("Event not found: " + eventMap.name); + let event = new Event(Utils.toSinglePrecision(getValue(eventMap, "time", 0)), eventData); + event.intValue = getValue(eventMap, "int", eventData.intValue); + event.floatValue = getValue(eventMap, "float", eventData.floatValue); + event.stringValue = getValue(eventMap, "string", eventData.stringValue); + if (event.data.audioPath) { + event.volume = getValue(eventMap, "volume", 1); + event.balance = getValue(eventMap, "balance", 0); + } + timeline.setFrame(frame, event); + } + timelines.push(timeline); + } + let duration = 0; + for (let i = 0, n = timelines.length; i < n; i++) + duration = Math.max(duration, timelines[i].getDuration()); + skeletonData.animations.push(new Animation(name, timelines, duration)); + } + }; + var LinkedMesh2 = class { + parent; + skin; + slotIndex; + mesh; + inheritTimeline; + constructor(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritTimeline = inheritDeform; + } + }; + function readTimeline12(keys, timeline, defaultValue, scale) { + let keyMap = keys[0]; + let time = getValue(keyMap, "time", 0); + let value = getValue(keyMap, "value", defaultValue) * scale; + let bezier = 0; + for (let frame = 0; ; frame++) { + timeline.setFrame(frame, time, value); + let nextMap = keys[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + return timeline; + } + let time2 = getValue(nextMap, "time", 0); + let value2 = getValue(nextMap, "value", defaultValue) * scale; + if (keyMap.curve) bezier = readCurve(keyMap.curve, timeline, bezier, frame, 0, time, time2, value, value2, scale); + time = time2; + value = value2; + keyMap = nextMap; + } + } + function readTimeline22(keys, timeline, name1, name2, defaultValue, scale) { + let keyMap = keys[0]; + let time = getValue(keyMap, "time", 0); + let value1 = getValue(keyMap, name1, defaultValue) * scale; + let value2 = getValue(keyMap, name2, defaultValue) * scale; + let bezier = 0; + for (let frame = 0; ; frame++) { + timeline.setFrame(frame, time, value1, value2); + let nextMap = keys[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + return timeline; + } + let time2 = getValue(nextMap, "time", 0); + let nvalue1 = getValue(nextMap, name1, defaultValue) * scale; + let nvalue2 = getValue(nextMap, name2, defaultValue) * scale; + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale); + } + time = time2; + value1 = nvalue1; + value2 = nvalue2; + keyMap = nextMap; + } + } + function readCurve(curve, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { + if (curve == "stepped") { + timeline.setStepped(frame); + return bezier; + } + let i = value << 2; + let cx1 = curve[i]; + let cy1 = curve[i + 1] * scale; + let cx2 = curve[i + 2]; + let cy2 = curve[i + 3] * scale; + timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2); + return bezier + 1; + } + function getValue(map, property, defaultValue) { + return map[property] !== void 0 ? map[property] : defaultValue; + } + + // spine-core/src/polyfills.ts + (() => { + if (typeof Math.fround === "undefined") { + Math.fround = /* @__PURE__ */ function(array) { + return function(x) { + return array[0] = x, array[0]; + }; + }(new Float32Array(1)); + } + })(); + + // spine-canvas/src/CanvasTexture.ts + var CanvasTexture = class extends Texture { + constructor(image) { + super(image); + } + setFilters(minFilter, magFilter) { + } + setWraps(uWrap, vWrap) { + } + dispose() { + } + }; + + // spine-canvas/src/AssetManager.ts + var AssetManager = class extends AssetManagerBase { + constructor(pathPrefix = "", downloader = new Downloader()) { + super((image) => { + return new CanvasTexture(image); + }, pathPrefix, downloader); + } + }; + + // spine-canvas/src/SkeletonRenderer.ts + var worldVertices = Utils.newFloatArray(8); + var SkeletonRenderer = class _SkeletonRenderer { + static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; + static VERTEX_SIZE = 2 + 2 + 4; + ctx; + triangleRendering = false; + debugRendering = false; + vertices = Utils.newFloatArray(8 * 1024); + tempColor = new Color(); + constructor(context) { + this.ctx = context; + } + draw(skeleton) { + if (this.triangleRendering) this.drawTriangles(skeleton); + else this.drawImages(skeleton); + } + drawImages(skeleton) { + let ctx = this.ctx; + let color = this.tempColor; + let skeletonColor = skeleton.color; + let drawOrder = skeleton.drawOrder; + if (this.debugRendering) ctx.strokeStyle = "green"; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + let bone = slot.bone; + if (!bone.active) continue; + let attachment = slot.getAttachment(); + if (!(attachment instanceof RegionAttachment)) continue; + attachment.computeWorldVertices(slot, worldVertices, 0, 2); + let region = attachment.region; + let image = region.texture.getImage(); + let slotColor = slot.color; + let regionColor = attachment.color; + color.set( + skeletonColor.r * slotColor.r * regionColor.r, + skeletonColor.g * slotColor.g * regionColor.g, + skeletonColor.b * slotColor.b * regionColor.b, + skeletonColor.a * slotColor.a * regionColor.a + ); + ctx.save(); + ctx.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY); + ctx.translate(attachment.offset[0], attachment.offset[1]); + ctx.rotate(attachment.rotation * Math.PI / 180); + let atlasScale = attachment.width / region.originalWidth; + ctx.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY); + let w = region.width, h = region.height; + ctx.translate(w / 2, h / 2); + if (attachment.region.degrees == 90) { + let t = w; + w = h; + h = t; + ctx.rotate(-Math.PI / 2); + } + ctx.scale(1, -1); + ctx.translate(-w / 2, -h / 2); + ctx.globalAlpha = color.a; + ctx.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h); + if (this.debugRendering) ctx.strokeRect(0, 0, w, h); + ctx.restore(); + } + } + drawTriangles(skeleton) { + let ctx = this.ctx; + let color = this.tempColor; + let skeletonColor = skeleton.color; + let drawOrder = skeleton.drawOrder; + let blendMode = null; + let vertices = this.vertices; + let triangles = null; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + let attachment = slot.getAttachment(); + let texture; + let region; + if (attachment instanceof RegionAttachment) { + let regionAttachment = attachment; + vertices = this.computeRegionVertices(slot, regionAttachment, false); + triangles = _SkeletonRenderer.QUAD_TRIANGLES; + texture = regionAttachment.region.texture.getImage(); + } else if (attachment instanceof MeshAttachment) { + let mesh = attachment; + vertices = this.computeMeshVertices(slot, mesh, false); + triangles = mesh.triangles; + texture = mesh.region.texture.getImage(); + } else + continue; + if (texture) { + if (slot.data.blendMode != blendMode) blendMode = slot.data.blendMode; + let slotColor = slot.color; + let attachmentColor = attachment.color; + color.set( + skeletonColor.r * slotColor.r * attachmentColor.r, + skeletonColor.g * slotColor.g * attachmentColor.g, + skeletonColor.b * slotColor.b * attachmentColor.b, + skeletonColor.a * slotColor.a * attachmentColor.a + ); + ctx.globalAlpha = color.a; + for (var j = 0; j < triangles.length; j += 3) { + let t1 = triangles[j] * 8, t2 = triangles[j + 1] * 8, t3 = triangles[j + 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); + if (this.debugRendering) { + ctx.strokeStyle = "green"; + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.lineTo(x0, y0); + ctx.stroke(); + } + } + } + } + this.ctx.globalAlpha = 1; + } + // Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120 + // Apache 2 licensed + drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) { + let ctx = this.ctx; + const width = img.width - 1; + const height = img.height - 1; + u0 *= width; + v0 *= height; + u1 *= width; + v1 *= height; + u2 *= width; + v2 *= 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; + let det = u1 * v2 - u2 * v1; + if (det == 0) return; + det = 1 / det; + const a = (v2 * x1 - v1 * x2) * det; + const b = (v2 * y1 - v1 * y2) * det; + const c = (u1 * x2 - u2 * x1) * det; + const d = (u1 * y2 - u2 * y1) * det; + const e = x0 - a * u0 - c * v0; + const 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(); + } + computeRegionVertices(slot, region, pma) { + let skeletonColor = slot.bone.skeleton.color; + let slotColor = slot.color; + let regionColor = region.color; + let alpha = skeletonColor.a * slotColor.a * regionColor.a; + let multiplier = pma ? alpha : 1; + let color = this.tempColor; + color.set( + skeletonColor.r * slotColor.r * regionColor.r * multiplier, + skeletonColor.g * slotColor.g * regionColor.g * multiplier, + skeletonColor.b * slotColor.b * regionColor.b * multiplier, + alpha + ); + region.computeWorldVertices(slot, this.vertices, 0, _SkeletonRenderer.VERTEX_SIZE); + let vertices = this.vertices; + let uvs = region.uvs; + vertices[RegionAttachment.C1R] = color.r; + vertices[RegionAttachment.C1G] = color.g; + vertices[RegionAttachment.C1B] = color.b; + vertices[RegionAttachment.C1A] = color.a; + vertices[RegionAttachment.U1] = uvs[0]; + vertices[RegionAttachment.V1] = uvs[1]; + vertices[RegionAttachment.C2R] = color.r; + vertices[RegionAttachment.C2G] = color.g; + vertices[RegionAttachment.C2B] = color.b; + vertices[RegionAttachment.C2A] = color.a; + vertices[RegionAttachment.U2] = uvs[2]; + vertices[RegionAttachment.V2] = uvs[3]; + vertices[RegionAttachment.C3R] = color.r; + vertices[RegionAttachment.C3G] = color.g; + vertices[RegionAttachment.C3B] = color.b; + vertices[RegionAttachment.C3A] = color.a; + vertices[RegionAttachment.U3] = uvs[4]; + vertices[RegionAttachment.V3] = uvs[5]; + vertices[RegionAttachment.C4R] = color.r; + vertices[RegionAttachment.C4G] = color.g; + vertices[RegionAttachment.C4B] = color.b; + vertices[RegionAttachment.C4A] = color.a; + vertices[RegionAttachment.U4] = uvs[6]; + vertices[RegionAttachment.V4] = uvs[7]; + return vertices; + } + computeMeshVertices(slot, mesh, pma) { + let skeletonColor = slot.bone.skeleton.color; + let slotColor = slot.color; + let regionColor = mesh.color; + let alpha = skeletonColor.a * slotColor.a * regionColor.a; + let multiplier = pma ? alpha : 1; + let color = this.tempColor; + color.set( + skeletonColor.r * slotColor.r * regionColor.r * multiplier, + skeletonColor.g * slotColor.g * regionColor.g * multiplier, + skeletonColor.b * slotColor.b * regionColor.b * multiplier, + alpha + ); + let vertexCount = mesh.worldVerticesLength / 2; + let vertices = this.vertices; + if (vertices.length < mesh.worldVerticesLength) this.vertices = vertices = Utils.newFloatArray(mesh.worldVerticesLength); + mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, _SkeletonRenderer.VERTEX_SIZE); + let uvs = mesh.uvs; + for (let i = 0, u = 0, v = 2; i < vertexCount; i++) { + vertices[v++] = color.r; + vertices[v++] = color.g; + vertices[v++] = color.b; + vertices[v++] = color.a; + vertices[v++] = uvs[u++]; + vertices[v++] = uvs[u++]; + v += 2; + } + return vertices; + } + }; + return __toCommonJS(index_exports); +})(); +//# sourceMappingURL=spine-canvas.js.map diff --git a/codes/games/client/Projects/Game_Surface_3/scripts/build_spine_data.cmd b/codes/games/client/Projects/Game_Surface_3/scripts/build_spine_data.cmd new file mode 100644 index 0000000..98bc802 --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/scripts/build_spine_data.cmd @@ -0,0 +1,17 @@ +@echo off +chcp 65001 >nul +REM ============================================================ +REM Spine èµ„æºæ•°æ®ç”Ÿæˆè„šæœ¬ +REM 扫æ assets/spine/ 目录,自动生æˆï¼š +REM generated/spine_assets.js — 资æºåæ¸…å• +REM generated/spine_data.js — .json/.atlas 文本内容嵌入 +REM +REM 用法:åŒå‡»è¿è¡Œï¼Œæˆ–在命令行执行: +REM cd codes\games\client\Projects\Spine\scripts +REM build_spine_data.cmd +REM ============================================================ + +pushd "%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0build_spine_data.ps1" +popd +pause diff --git a/codes/games/client/Projects/Game_Surface_3/scripts/build_spine_data.ps1 b/codes/games/client/Projects/Game_Surface_3/scripts/build_spine_data.ps1 new file mode 100644 index 0000000..8d73558 --- /dev/null +++ b/codes/games/client/Projects/Game_Surface_3/scripts/build_spine_data.ps1 @@ -0,0 +1,99 @@ +# Spine resource data generation script +# Scans assets/spine/ directory and generates: +# generated/spine_assets.js - resource name list +# generated/spine_data.js - .json/.atlas text content embedded (file:// CORS fix) + +$ErrorActionPreference = "Stop" + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$projectDir = Split-Path -Parent $scriptDir +$spineDir = Join-Path $projectDir "assets\spine" +$outDir = Join-Path $projectDir "generated" +$assetsOut = Join-Path $outDir "spine_assets.js" +$dataOut = Join-Path $outDir "spine_data.js" + +if (-not (Test-Path $outDir)) { + New-Item -ItemType Directory -Path $outDir | Out-Null +} + +if (-not (Test-Path $spineDir)) { + Write-Host "[WARN] Spine assets directory not found: $spineDir — generating empty files" -ForegroundColor Yellow + $jsonFiles = @() +} else { + $jsonFiles = Get-ChildItem $spineDir -Filter "*.json" | Sort-Object Name +} + +if ($jsonFiles.Count -eq 0) { + Write-Host "[INFO] No .json files found — generating empty placeholder files" -ForegroundColor Yellow + + $utf8NoBom = New-Object System.Text.UTF8Encoding($false) + [System.IO.File]::WriteAllText($assetsOut, "// Spine resource list (auto-generated, do not edit manually)`ngameabc_face.spineAssets = [];`n", $utf8NoBom) + [System.IO.File]::WriteAllText($dataOut, "// Spine text data (auto-generated, do not edit manually)`ngameabc_face.spineTextData = {};`n", $utf8NoBom) + + Write-Host "[OK] $assetsOut (empty)" -ForegroundColor Green + Write-Host "[OK] $dataOut (empty)" -ForegroundColor Green + exit 0 +} + +$names = @() +foreach ($f in $jsonFiles) { + $names += $f.BaseName +} + +Write-Host "Found $($names.Count) Spine resource(s): $($names -join ', ')" -ForegroundColor Cyan + +# ==================== spine_assets.js ==================== +$assetsSB = [System.Text.StringBuilder]::new() +[void]$assetsSB.AppendLine('// Spine resource list (auto-generated, do not edit manually)') +[void]$assetsSB.Append('gameabc_face.spineAssets = [') + +for ($i = 0; $i -lt $names.Count; $i++) { + if ($i -gt 0) { [void]$assetsSB.Append(',') } + [void]$assetsSB.AppendLine('') + [void]$assetsSB.Append("`t`"$($names[$i])`"") +} + +[void]$assetsSB.AppendLine('') +[void]$assetsSB.AppendLine('];') + +$utf8NoBom = New-Object System.Text.UTF8Encoding($false) +[System.IO.File]::WriteAllText($assetsOut, $assetsSB.ToString(), $utf8NoBom) +Write-Host "[OK] $assetsOut" -ForegroundColor Green + +# ==================== spine_data.js ==================== +$dataSB = [System.Text.StringBuilder]::new() +[void]$dataSB.AppendLine('// Spine text data (auto-generated, do not edit manually)') +[void]$dataSB.AppendLine('// Embeds .json/.atlas content into JS to bypass file:// XHR CORS') +[void]$dataSB.AppendLine('gameabc_face.spineTextData = {};') + +$totalOriginal = 0 + +foreach ($name in $names) { + foreach ($ext in '.json', '.atlas') { + $filePath = Join-Path $spineDir "$name$ext" + if (-not (Test-Path $filePath)) { + Write-Host "[WARN] Missing file: $name$ext" -ForegroundColor Yellow + continue + } + + $raw = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::UTF8) + $totalOriginal += (Get-Item $filePath).Length + + $escaped = $raw.Replace('\', '\\').Replace("'", "\'") + $escaped = $escaped.Replace("`r`n", '\n').Replace("`n", '\n').Replace("`r", '') + + [void]$dataSB.AppendLine("gameabc_face.spineTextData['$name$ext'] = '$escaped';") + } +} + +[System.IO.File]::WriteAllText($dataOut, $dataSB.ToString(), $utf8NoBom) + +$dataSize = (Get-Item $dataOut).Length +$overhead = $dataSize - $totalOriginal + +Write-Host "[OK] $dataOut" -ForegroundColor Green +Write-Host '' +Write-Host '=== Summary ===' -ForegroundColor Cyan +Write-Host " Resources: $($names.Count)" +Write-Host " Original size: $([math]::Round($totalOriginal/1024, 1)) KB" +Write-Host " Output size: $([math]::Round($dataSize/1024, 1)) KB (overhead: $overhead bytes)" \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/FilesOrd.txt b/codes/games/client/Projects/Spine/FilesOrd.txt new file mode 100644 index 0000000..6ab68d1 --- /dev/null +++ b/codes/games/client/Projects/Spine/FilesOrd.txt @@ -0,0 +1,2 @@ +G:\Works\YouleGames\codes\games\client\Projects\Project1\js\gamemain.js +G:\Works\YouleGames\codes\games\client\Projects\Project1\js\Project1_Event.js diff --git a/codes/games/client/Projects/Spine/Project.txt b/codes/games/client/Projects/Spine/Project.txt new file mode 100644 index 0000000..cff55f8 --- /dev/null +++ b/codes/games/client/Projects/Spine/Project.txt @@ -0,0 +1,6 @@ +LayerStartID=1 +SpiritStartID=1 +ImgResStartID=1 +TxtResStartID=1 +VoiResStartID=1 +OpenLayerList=1 diff --git a/codes/games/client/Projects/Spine/assets/bmp/00001.png b/codes/games/client/Projects/Spine/assets/bmp/00001.png new file mode 100644 index 0000000..eafcedf Binary files /dev/null and b/codes/games/client/Projects/Spine/assets/bmp/00001.png differ diff --git a/codes/games/client/Projects/Spine/assets/bmp/00002.png b/codes/games/client/Projects/Spine/assets/bmp/00002.png new file mode 100644 index 0000000..5b4186f Binary files /dev/null and b/codes/games/client/Projects/Spine/assets/bmp/00002.png differ diff --git a/codes/games/client/Projects/Spine/assets/bmp/gameabc_data.js b/codes/games/client/Projects/Spine/assets/bmp/gameabc_data.js new file mode 100644 index 0000000..2322732 --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/bmp/gameabc_data.js @@ -0,0 +1,255 @@ +var gameabc_Project = +{ + "Property": { + "ProjectName": "Spine", + "ScreenWidth": 1280, + "ScreenHeight": 720, + "GameSceneWidth": 2337, + "GameSceneHeight": 1800, + "ScreenFitMode": 0, + "TcpIP": "", + "TcpPort": "", + "Http": "", + "title": "" + }, + "Event": { + "gamestart": 0, + "gamebegindraw": 0, + "gameenddraw": 0, + "mousedown": 0, + "mousedown_nomove": 0, + "mouseup": 0, + "mousemove": 0, + "gamemydraw": 0, + "gamemydrawbegin": 0, + "chongzhi": 0, + "tcpconnected": 0, + "tcpdisconnected": 0, + "tcpmessage": 0, + "tcperror": 0, + "httpmessage": 0, + "ani_doend": 0, + "box_doend": 0, + "onresize": 0, + "ontimer": 0, + "onloadurl": 0 + }, + "Option": { + "fps": 30, + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "showmodel": 0 + } +} +; +var gameabc_Layer = +{ + "LayerList": [ + {},{ + "Property": { + "LayerID": 1, + "LayerName": "Layer1" + }, + "ObjectList": [ + 1,2,3] + }] +} +; +var gameabc_GroupList = +{ + "GroupList": [] +} +; +var gameabc_Object = +{ + "ObjectList": [ + {},{ + "Property": { + "ObjectID": 1, + "ObjectType": 4, + "ObjectName": "Spirit1", + "Left": -668, + "Top": 19, + "Width": 79, + "Height": 35, + "BelongLayerID": 1, + "IndexOfLayer": 1, + "Text": "Spirit1", + "FontSize": 20, + "FontBold": 0, + "FontColorR": 0, + "FontColorG": 0, + "FontColorB": 0, + "FontColor": "#000000", + "BackColorR": 255, + "BackColorG": 255, + "BackColorB": 255, + "BackColorA": 0, + "BackColor": "#FFFFFF", + "GameTxtStyle": 0, + "LineSpace": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": -668, + "offY": 19 + }, + "Event": { + "mousedown": 1, + "mouseup": 1, + "mousemove": 1, + "ontimer": 1 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + },{ + "Property": { + "ObjectID": 2, + "ObjectType": 2, + "ObjectName": "Spirit2", + "Left": 0, + "Top": 0, + "Width": 1280, + "Height": 720, + "BelongLayerID": 1, + "IndexOfLayer": 2, + "ImageFileID": 1, + "FrameStyle": 0, + "FrameIndex": 0, + "TextFrames": "", + "L9": 0, + "T9": 0, + "R9": 0, + "B9": 0, + "VoiceFileID": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": 0, + "offY": 0 + }, + "Event": { + "mousedown": 2, + "mouseup": 2, + "mousemove": 2, + "ontimer": 2 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + },{ + "Property": { + "ObjectID": 3, + "ObjectType": 2, + "ObjectName": "Spirit3", + "Left": 393, + "Top": 412, + "Width": 560, + "Height": 148, + "BelongLayerID": 1, + "IndexOfLayer": 3, + "ImageFileID": 2, + "FrameStyle": 0, + "FrameIndex": 0, + "TextFrames": "", + "L9": 0, + "T9": 0, + "R9": 0, + "B9": 0, + "VoiceFileID": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": 393, + "offY": 412 + }, + "Event": { + "mousedown": 3, + "mouseup": 3, + "mousemove": 3, + "ontimer": 3 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + }] +} +; +var gameabc_Image = +{ + "ImageFileList": [ + {},{ + "id": 1, + "w_all": 1280, + "h_all": 720, + "w": 1, + "h": 1, + "frame_all": 1, + "bmp": "00001.png", + "w1": 1280, + "h1": 720 + },{ + "id": 2, + "w_all": 1920, + "h_all": 740, + "w": 1, + "h": 1, + "frame_all": 1, + "bmp": "00002.png", + "w1": 1920, + "h1": 740 + }] +} +; +var gameabc_GameTxt = +{ + "GameTxtList": [] +} +; +var gameabc_Voice = +{ + "VoiceFileList": [] +} +; diff --git a/codes/games/client/Projects/Spine/assets/bmp/gameabc_data.min.js b/codes/games/client/Projects/Spine/assets/bmp/gameabc_data.min.js new file mode 100644 index 0000000..b544c1c --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/bmp/gameabc_data.min.js @@ -0,0 +1 @@ +var gameabc_Project = { "Property": { "ProjectName": "Spine", "ScreenWidth": 1280, "ScreenHeight": 720, "GameSceneWidth": 2337, "GameSceneHeight": 1800, "ScreenFitMode": 0, "TcpIP": "", "TcpPort": "", "Http": "", "title": "" }, "Event": { "gamestart": 0, "gamebegindraw": 0, "gameenddraw": 0, "mousedown": 0, "mousedown_nomove": 0, "mouseup": 0, "mousemove": 0, "gamemydraw": 0, "gamemydrawbegin": 0, "chongzhi": 0, "tcpconnected": 0, "tcpdisconnected": 0, "tcpmessage": 0, "tcperror": 0, "httpmessage": 0, "ani_doend": 0, "box_doend": 0, "onresize": 0, "ontimer": 0, "onloadurl": 0 }, "Option": { "fps": 30, "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "showmodel": 0 }};var gameabc_Layer = { "LayerList": [ {},{ "Property": { "LayerID": 1, "LayerName": "Layer1" }, "ObjectList": [ 1,2,3] }]};var gameabc_GroupList = { "GroupList": []};var gameabc_Object = { "ObjectList": [ {},{ "Property": { "ObjectID": 1, "ObjectType": 4, "ObjectName": "Spirit1", "Left": -668, "Top": 19, "Width": 79, "Height": 35, "BelongLayerID": 1, "IndexOfLayer": 1, "Text": "Spirit1", "FontSize": 20, "FontBold": 0, "FontColorR": 0, "FontColorG": 0, "FontColorB": 0, "FontColor": "#000000", "BackColorR": 255, "BackColorG": 255, "BackColorB": 255, "BackColorA": 0, "BackColor": "#FFFFFF", "GameTxtStyle": 0, "LineSpace": 0, "GroupID": 0, "TimerInterval": 0, "Data": "", "Parent": 0, "OriginID": 0, "OriginPos": 1, "SelfPos": 1, "offX": -668, "offY": 19 }, "Event": { "mousedown": 1, "mouseup": 1, "mousemove": 1, "ontimer": 1 }, "Option": { "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "vx": 0, "vy": 0, "vw": 0, "vh": 0, "canclick": 1, "visbale": 1 } },{ "Property": { "ObjectID": 2, "ObjectType": 2, "ObjectName": "Spirit2", "Left": 0, "Top": 0, "Width": 1280, "Height": 720, "BelongLayerID": 1, "IndexOfLayer": 2, "ImageFileID": 1, "FrameStyle": 0, "FrameIndex": 0, "TextFrames": "", "L9": 0, "T9": 0, "R9": 0, "B9": 0, "VoiceFileID": 0, "GroupID": 0, "TimerInterval": 0, "Data": "", "Parent": 0, "OriginID": 0, "OriginPos": 1, "SelfPos": 1, "offX": 0, "offY": 0 }, "Event": { "mousedown": 2, "mouseup": 2, "mousemove": 2, "ontimer": 2 }, "Option": { "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "vx": 0, "vy": 0, "vw": 0, "vh": 0, "canclick": 1, "visbale": 1 } },{ "Property": { "ObjectID": 3, "ObjectType": 2, "ObjectName": "Spirit3", "Left": 393, "Top": 412, "Width": 560, "Height": 148, "BelongLayerID": 1, "IndexOfLayer": 3, "ImageFileID": 2, "FrameStyle": 0, "FrameIndex": 0, "TextFrames": "", "L9": 0, "T9": 0, "R9": 0, "B9": 0, "VoiceFileID": 0, "GroupID": 0, "TimerInterval": 0, "Data": "", "Parent": 0, "OriginID": 0, "OriginPos": 1, "SelfPos": 1, "offX": 393, "offY": 412 }, "Event": { "mousedown": 3, "mouseup": 3, "mousemove": 3, "ontimer": 3 }, "Option": { "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "vx": 0, "vy": 0, "vw": 0, "vh": 0, "canclick": 1, "visbale": 1 } }]};var gameabc_Image = { "ImageFileList": [ {},{ "id": 1, "w_all": 1280, "h_all": 720, "w": 1, "h": 1, "frame_all": 1, "bmp": "00001.png", "w1": 1280, "h1": 720 },{ "id": 2, "w_all": 1920, "h_all": 740, "w": 1, "h": 1, "frame_all": 1, "bmp": "00002.png", "w1": 1920, "h1": 740 }]};var gameabc_GameTxt = { "GameTxtList": []};var gameabc_Voice = { "VoiceFileList": []}; diff --git a/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.atlas b/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.atlas new file mode 100644 index 0000000..3d0454f --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.atlas @@ -0,0 +1,35 @@ +Zaijiezaili.png +size:2048,512 +filter:Linear,Linear +fennu +bounds:1006,307,176,171 +lei +bounds:576,164,53,73 +lei1 +bounds:519,108,55,129 +lianhong +bounds:2,285,526,193 +majiang +bounds:530,239,222,239 +meimao +bounds:754,251,141,67 +meimaozuo +bounds:361,5,142,109 +shaizi +bounds:1682,368,108,110 +shitou +bounds:754,320,250,158 +toufa +bounds:1184,353,207,125 +yanjing +bounds:1792,408,111,70 +youjiao +bounds:1393,346,187,132 +youshou +bounds:1582,300,98,178 +zuiba +bounds:1682,319,98,47 +zuojiao +bounds:361,116,156,167 +zuoshou +bounds:2,2,357,281 diff --git a/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.json b/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.json new file mode 100644 index 0000000..abf3e7f --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.json @@ -0,0 +1 @@ +{"skeleton":{"hash":"YQ68cRyF7vg","spine":"4.2.43","x":-137.99,"y":-23.46,"width":273.57,"height":299.64,"images":"./0/","audio":"I:\\游æˆç´ ææ”¶é›†\\棋牌\\指间四å·éº»å°†\\spine1\\Zaijiezaili"},"bones":[{"name":"root"},{"name":"zhengti","parent":"root","scaleX":0.33,"scaleY":0.33},{"name":"zuoshou","parent":"zhengti","length":153.45,"rotation":-132.81,"x":283.03,"y":320.9},{"name":"zuoshou2","parent":"zuoshou","length":89.64,"rotation":-23,"x":153.45},{"name":"zuoshou3","parent":"zuoshou2","length":136.48,"rotation":-3.87,"x":89.64},{"name":"majiang","parent":"zhengti","length":349.64,"rotation":74.27,"x":-83.13,"y":8.06},{"name":"majiang2","parent":"majiang","length":424.47,"rotation":13.81,"x":349.64},{"name":"toufa","parent":"majiang2","length":55.4,"rotation":133.45,"x":401.91,"y":-56.48},{"name":"toufa2","parent":"toufa","length":64.53,"rotation":4.21,"x":55.4},{"name":"yanjing","parent":"majiang2","length":102.74,"rotation":-5.37,"x":97.32,"y":81.52},{"name":"zuiba","parent":"majiang2","length":28.54,"rotation":177.16,"x":68.93,"y":79.38},{"name":"lei","parent":"majiang2","length":55.09,"rotation":-159.26,"x":70.14,"y":-62.86},{"name":"lei1","parent":"majiang2","length":109.25,"rotation":179.5,"x":64.67,"y":-80.5},{"name":"meimao","parent":"majiang2","length":28.83,"rotation":11.38,"x":249.29,"y":181.46},{"name":"meimaozuo","parent":"majiang2","length":33.01,"rotation":-19.12,"x":204.64,"y":-42.94},{"name":"fennu","parent":"majiang2","length":127.88,"rotation":9.37,"x":415.06,"y":-271.83},{"name":"shaizi","parent":"zhengti","length":247.68,"rotation":90.55,"x":-166.08,"y":25.1},{"name":"zuojiao","parent":"majiang","length":150.2,"rotation":161.67,"x":113.74,"y":-126.77},{"name":"youjiao","parent":"majiang","length":170.46,"rotation":114.93,"x":66.88,"y":183.81},{"name":"youshou","parent":"majiang","length":159.04,"rotation":-156.56,"x":325.57,"y":283.77},{"name":"lei2","parent":"majiang2","length":55.09,"rotation":132.86,"x":104.64,"y":211.59},{"name":"lei3","parent":"majiang2","length":109.25,"rotation":179.5,"x":103.57,"y":230.15,"scaleY":-1}],"slots":[{"name":"yinying","bone":"zhengti"},{"name":"shitou2","bone":"zhengti","attachment":"shitou"},{"name":"shitou","bone":"zhengti"},{"name":"majiang","bone":"majiang","attachment":"majiang"},{"name":"youjiao","bone":"youjiao","attachment":"youjiao"},{"name":"youshou","bone":"youshou","attachment":"youshou"},{"name":"lianhong","bone":"majiang2","attachment":"lianhong"},{"name":"lei3","bone":"lei3","attachment":"lei1"},{"name":"shaizi","bone":"shaizi","attachment":"shaizi"},{"name":"zuojiao","bone":"zuojiao","attachment":"zuojiao"},{"name":"meimao","bone":"meimao","attachment":"meimao"},{"name":"meimaozuo","bone":"meimaozuo","attachment":"meimaozuo"},{"name":"yanjing","bone":"yanjing","attachment":"yanjing"},{"name":"zuiba","bone":"zuiba","attachment":"zuiba"},{"name":"lei1","bone":"lei1","attachment":"lei1"},{"name":"lei","bone":"lei","attachment":"lei"},{"name":"lei2","bone":"lei2","attachment":"lei"},{"name":"toufa","bone":"toufa","attachment":"toufa"},{"name":"zuoshou","bone":"zuoshou","attachment":"zuoshou"},{"name":"fennu","bone":"fennu","attachment":"fennu"}],"skins":[{"name":"default","attachments":{"fennu":{"fennu":{"x":0.62,"y":-3.71,"rotation":-97.45,"width":176,"height":171}},"lei":{"lei":{"x":24.68,"y":0.57,"rotation":71.18,"width":53,"height":73}},"lei1":{"lei1":{"x":53.68,"y":-4.93,"rotation":102.53,"width":55,"height":129}},"lei2":{"lei":{"x":23.4,"y":3.39,"scaleX":0.9866,"rotation":81.81,"width":53,"height":73}},"lei3":{"lei1":{"x":53.68,"y":-4.93,"rotation":102.53,"width":55,"height":129}},"lianhong":{"lianhong":{"x":33.73,"y":62.99,"rotation":-88.08,"width":526,"height":193}},"majiang":{"majiang":{"type":"mesh","uvs":[0.55292,0,0.80146,0.0316,0.96859,0.09786,0.99866,0.18316,0.99208,0.54246,0.99217,0.59235,0.98321,0.65035,0.95986,0.74151,0.8828,0.88017,0.70514,0.9961,0.39641,0.95353,0.1743,0.91079,0.10958,0.86867,0.1032,0.79716,0.17551,0.53933,0.18123,0.48867,0.18632,0.44363,0.18253,0.13643,0.41176,0],"triangles":[9,10,8,8,10,13,13,10,11,14,7,8,13,11,12,8,13,14,7,14,6,6,14,5,5,14,15,5,15,4,15,16,4,4,16,0,3,1,2,16,18,0,0,1,4,4,1,3,16,17,18],"vertices":[1,6,435.13,13.03,1,1,6,415.81,-172.63,1,1,6,366.46,-298.7,1,1,6,298.33,-323.37,1,2,6,8.01,-328.2,0.126,5,435.77,-316.8,0.874,2,6,-32.27,-329.62,0.504,5,396.99,-327.79,0.496,1,5,350.07,-334.08,1,1,5,274.47,-337.33,1,1,5,151.08,-312.53,1,1,5,25.08,-210.69,1,1,5,-4.09,19.72,1,1,5,-15.66,188.15,1,1,5,4.05,243.72,1,1,5,58.37,263.96,1,1,5,273.49,268.66,1,2,6,31.24,276.19,0.504,5,314.03,275.66,0.496,2,6,67.74,273.62,0.126,5,350.09,281.88,0.874,1,6,315.72,284.76,1,1,6,431.61,117.99,1],"hull":19,"edges":[0,36,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,30,30,32,32,34,34,36],"width":222,"height":239}},"meimao":{"meimao":{"x":0.96,"y":2.18,"rotation":-99.46,"width":141,"height":67}},"meimaozuo":{"meimaozuo":{"x":5.14,"y":2.61,"rotation":-68.96,"width":142,"height":109}},"shaizi":{"shaizi":{"type":"mesh","uvs":[1,1,0,1,0,0,1,0],"triangles":[1,2,3,1,3,0],"vertices":[-89.79,-168.08,-86.36,190.91,277.62,187.42,274.19,-171.56],"hull":4,"edges":[0,6,0,2,2,4,4,6],"width":108,"height":110}},"shitou2":{"shitou":{"x":285.85,"y":7.92,"width":250,"height":158}},"toufa":{"toufa":{"type":"mesh","uvs":[0.99148,0.02227,0.99966,0.66804,0.88208,1,0.79701,1,0,0.56577,0,0.52294,0.11656,0.1786,0.26577,0.11842,0.55225,0.00289],"triangles":[7,4,5,7,5,6,3,4,7,8,0,1,7,8,1,3,7,1,2,3,1],"vertices":[2,7,-34.29,25.38,0.94779,8,-87.59,31.9,0.05221,2,7,17.96,86.93,0.7463,8,-30.96,89.44,0.2537,2,7,63.69,101.85,0.91243,8,15.75,100.97,0.08757,2,7,76.87,90.18,0.58268,8,28.04,88.36,0.41732,2,7,164.39,-59.84,0.28341,8,104.29,-67.69,0.71659,2,7,160.84,-63.85,0.00525,8,100.46,-71.42,0.99475,2,7,114.24,-80.07,0.03797,8,52.79,-84.18,0.96203,2,7,86.13,-65.23,0.48932,8,25.85,-67.31,0.51068,2,7,32.16,-36.72,0.65075,8,-25.88,-34.91,0.34925],"hull":9,"edges":[0,16,0,2,2,4,4,6,6,8,8,10,10,12,12,14,14,16],"width":207,"height":125}},"yanjing":{"yanjing":{"type":"mesh","uvs":[1,1,0,1,0,0,1,0],"triangles":[1,2,3,1,3,0],"vertices":[-65.15,-205.31,-112.35,163.68,121.75,193.62,168.94,-175.37],"hull":4,"edges":[0,6,0,2,2,4,4,6],"width":111,"height":70}},"youjiao":{"youjiao":{"x":84.44,"y":3.9,"rotation":170.8,"width":187,"height":132}},"youshou":{"youshou":{"x":82.04,"y":-1.18,"rotation":82.29,"width":98,"height":178}},"zuiba":{"zuiba":{"x":11.59,"y":2.17,"rotation":94.76,"width":98,"height":47}},"zuojiao":{"zuojiao":{"x":81,"y":-0.62,"rotation":124.07,"width":156,"height":167}},"zuoshou":{"zuoshou":{"type":"mesh","uvs":[0.98971,0,0.75334,0,0.59918,0.20428,0.55807,0.25215,0.50668,0.30003,0.39706,0.42189,0.02707,0.3392,0,0.65256,0,1,0.31484,1,0.47242,0.77878,0.67112,0.67868,0.72936,0.64386,0.78759,0.60469,1,0.35225,1,0,0.63473,0.26018],"triangles":[7,6,5,7,5,10,9,8,7,10,9,7,12,4,3,11,4,12,5,4,11,10,5,11,16,2,1,3,2,16,0,15,14,1,14,16,14,1,0,13,16,14,12,16,13,3,16,12],"vertices":[1,2,-25.76,-4.59,1,2,2,31.58,-66.5,0.99983,3,-86.2,-108.83,1.7E-4,2,2,111.09,-67.86,0.80126,3,-12.48,-79.02,0.19874,2,2,130.93,-69.49,0.59796,3,6.42,-72.76,0.40204,3,2,153.27,-73.8,0.337,3,28.67,-68.01,0.66105,4,-56.24,-71.97,0.00195,3,2,204.99,-79.24,0.0166,3,78.4,-52.81,0.63444,4,-7.65,-53.45,0.34896,1,4,108.14,-121.11,1,1,4,147.79,-41.9,1,1,4,181.7,49.65,1,1,4,76.3,88.69,1,2,3,94.96,49.69,0.44283,4,1.95,49.94,0.55717,2,2,191.44,41.57,0.15017,3,18.72,53.1,0.84983,2,2,170.13,50.17,0.46073,3,-4.25,52.7,0.53927,2,2,147.93,57.94,0.7932,3,-27.73,51.18,0.2068,1,2,44.36,65.37,1,1,2,-28.26,-1.9,1,2,2,113.99,-47.88,0.8182,3,-17.62,-59.49,0.1818],"hull":16,"edges":[0,30,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,30],"width":357,"height":281}}}}],"animations":{"animation":{"slots":{"lei":{"rgba":[{"time":0.3333,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00","curve":"stepped"},{"time":0.9667,"color":"ffffff00"},{"time":1,"color":"ffffffff","curve":"stepped"},{"time":1.3,"color":"ffffffff"},{"time":1.3333,"color":"ffffff00"}]},"lei1":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3333,"color":"ffffff00"},{"time":0.3667,"color":"ffffffff","curve":"stepped"},{"time":0.5667,"color":"ffffffff"},{"time":0.6,"color":"ffffff00","curve":"stepped"},{"time":1.3,"color":"ffffff00"},{"time":1.3333,"color":"ffffffff","curve":"stepped"},{"time":1.5333,"color":"ffffffff"},{"time":1.5667,"color":"ffffff00"}]},"lei2":{"rgba":[{"color":"ffffff00"},{"time":0.0333,"color":"ffffffff","curve":"stepped"},{"time":0.3333,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00"},{"time":1.0333,"color":"ffffffff","curve":"stepped"},{"time":1.3333,"color":"ffffffff"},{"time":1.3667,"color":"ffffff00"}]},"lei3":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3333,"color":"ffffff00"},{"time":0.3667,"color":"ffffffff","curve":"stepped"},{"time":0.5667,"color":"ffffffff"},{"time":0.6,"color":"ffffff00","curve":"stepped"},{"time":1.3333,"color":"ffffff00"},{"time":1.3667,"color":"ffffffff","curve":"stepped"},{"time":1.5667,"color":"ffffffff"},{"time":1.6,"color":"ffffff00"}]}},"bones":{"lei1":{"translate":[{"time":0.3667},{"time":0.6,"x":-179.67,"y":1.57},{"time":0.9667,"curve":"stepped"},{"time":1.3333},{"time":1.5667,"x":-179.67,"y":1.57}]},"lei2":{"scale":[{"x":0.657},{"time":0.3333},{"time":1,"x":0.657},{"time":1.3333}]},"lei":{"scale":[{"x":0.666},{"time":0.3333},{"time":0.9667,"x":0.666},{"time":1.3}]},"lei3":{"translate":[{"time":0.3667},{"time":0.6,"x":-191.75,"y":1.68},{"time":1,"curve":"stepped"},{"time":1.3667},{"time":1.6,"x":-191.75,"y":1.68}]},"zuoshou":{"rotate":[{"curve":[0.208,0,0.625,-2.28]},{"time":0.8333,"value":-2.28,"curve":[1.042,-2.28,1.458,0]},{"time":1.6667}]},"zuoshou2":{"rotate":[{"curve":[0.208,0,0.625,-2.28]},{"time":0.8333,"value":-2.28,"curve":[1.042,-2.28,1.458,0]},{"time":1.6667}]},"zuoshou3":{"rotate":[{"value":-2.09,"curve":[0.076,-0.84,0.145,0]},{"time":0.2,"curve":[0.408,0,0.825,-12.04]},{"time":1.0333,"value":-12.04,"curve":[1.187,-12.04,1.457,-5.27]},{"time":1.6667,"value":-2.09}]},"majiang2":{"rotate":[{"curve":[0.1,0,0.3,2.79]},{"time":0.4,"value":2.79,"curve":[0.425,2.79,0.475,-2.73]},{"time":0.5,"value":-2.73,"curve":[0.575,-2.73,0.725,1.1]},{"time":0.8,"value":1.1,"curve":[0.825,1.1,0.875,-2.73]},{"time":0.9,"value":-2.73,"curve":[0.936,-2.73,0.983,-1.55]},{"time":1.0333,"value":0.16,"curve":[1.068,-0.88,1.109,-2.73]},{"time":1.1333,"value":-2.73,"curve":[1.278,-2.73,1.463,-1.61]},{"time":1.6667}],"scale":[{"time":0.4},{"time":0.5,"x":1.027},{"time":0.8},{"time":0.9,"x":1.027},{"time":1.0333},{"time":1.1333,"x":1.027},{"time":1.6667}]},"toufa":{"rotate":[{"time":0.4,"curve":[0.442,0,0.525,-5.53]},{"time":0.5667,"value":-5.53,"curve":[0.633,-5.53,0.767,0]},{"time":0.8333,"curve":[0.867,0,0.933,-3.81]},{"time":0.9667,"value":-3.81,"curve":[1,-3.81,1.067,-1.31]},{"time":1.1,"value":-1.31,"curve":[1.142,-1.31,1.225,-7.41]},{"time":1.2667,"value":-7.41,"curve":[1.367,-7.41,1.567,0]},{"time":1.6667}]},"toufa2":{"rotate":[{"value":-1.37,"curve":[0.038,-0.55,0.072,0]},{"time":0.1,"curve":"stepped"},{"time":0.5,"curve":[0.542,0,0.625,-5.53]},{"time":0.6667,"value":-5.53,"curve":[0.733,-5.53,0.867,0]},{"time":0.9333,"curve":[0.967,0,1.033,-3.81]},{"time":1.0667,"value":-3.81,"curve":[1.1,-3.81,1.167,-1.31]},{"time":1.2,"value":-1.31,"curve":[1.242,-1.31,1.325,-7.41]},{"time":1.3667,"value":-7.41,"curve":[1.439,-7.41,1.567,-3.36]},{"time":1.6667,"value":-1.37}]},"zuiba":{"scale":[{"time":0.4333},{"time":0.5,"y":0.865},{"time":0.8},{"time":0.8667,"y":0.865,"curve":"stepped"},{"time":1.2,"y":0.865},{"time":1.6667}]},"meimao":{"rotate":[{"time":0.4},{"time":0.5,"value":-6.29},{"time":0.8},{"time":0.9,"value":-6.29},{"time":1.0667},{"time":1.1667,"value":-6.29},{"time":1.6667}]},"meimaozuo":{"rotate":[{"time":0.4},{"time":0.5,"value":4.64},{"time":0.8},{"time":0.9,"value":4.64},{"time":1.0667},{"time":1.1667,"value":4.64},{"time":1.6667}]},"fennu":{"scale":[{"x":0.994,"y":0.994,"curve":[0.012,0.998,0.023,1,0.012,0.998,0.023,1]},{"time":0.0333,"curve":"stepped"},{"time":0.4333,"curve":[0.458,1,0.508,0.574,0.458,1,0.508,0.574]},{"time":0.5333,"x":0.574,"y":0.574,"curve":[0.608,0.574,0.758,1,0.608,0.574,0.758,1]},{"time":0.8333,"curve":[0.858,1,0.908,0.724,0.858,1,0.908,0.724]},{"time":0.9333,"x":0.724,"y":0.724,"curve":[0.975,0.724,1.058,1,0.975,0.724,1.058,1]},{"time":1.1,"curve":[1.125,1,1.175,0.749,1.125,1,1.175,0.749]},{"time":1.2,"x":0.749,"y":0.749,"curve":[1.315,0.749,1.537,0.965,1.315,0.749,1.537,0.965]},{"time":1.6667,"x":0.994,"y":0.994}]},"shaizi":{"rotate":[{"value":0.3,"curve":[0.063,0.11,0.119,0]},{"time":0.1667,"curve":[0.375,0,0.792,2.32]},{"time":1,"value":2.32,"curve":[1.162,2.32,1.453,0.89]},{"time":1.6667,"value":0.3}],"scale":[{"x":0.988,"curve":[0.204,0.973,0.454,0.945,0.204,1,0.454,1]},{"time":0.6,"x":0.945,"curve":[0.808,0.945,1.225,1,0.808,1,1.225,1]},{"time":1.4333,"curve":[1.497,1,1.578,0.995,1.497,1,1.578,1]},{"time":1.6667,"x":0.988}]},"zuojiao":{"rotate":[{"curve":[0.208,0,0.625,-5.86]},{"time":0.8333,"value":-5.86,"curve":[1.042,-5.86,1.458,0]},{"time":1.6667}]},"youjiao":{"rotate":[{"value":1.71,"curve":[0.115,0.75,0.221,0]},{"time":0.3,"curve":[0.508,0,0.925,5.41]},{"time":1.1333,"value":5.41,"curve":[1.263,5.41,1.477,3.26]},{"time":1.6667,"value":1.71}]},"youshou":{"rotate":[{"curve":[0.208,0,0.625,-5.51]},{"time":0.8333,"value":-5.51,"curve":[1.042,-5.51,1.458,0]},{"time":1.6667}]},"yanjing":{"scale":[{"time":0.4333,"curve":[0.458,1,0.508,0.935,0.458,1,0.508,1]},{"time":0.5333,"x":0.935,"curve":[0.6,0.935,0.733,1,0.6,1,0.733,1]},{"time":0.8,"curve":[0.825,1,0.875,0.918,0.825,1,0.875,1]},{"time":0.9,"x":0.918,"curve":[0.942,0.918,1.025,1,0.942,1,1.025,1]},{"time":1.0667,"curve":[1.092,1,1.142,0.87,1.092,1,1.142,1]},{"time":1.1667,"x":0.87,"curve":[1.258,0.87,1.442,1,1.258,1,1.442,1]},{"time":1.5333}]}}}}} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.png b/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.png new file mode 100644 index 0000000..4aab00d Binary files /dev/null and b/codes/games/client/Projects/Spine/assets/spine/Zaijiezaili.png differ diff --git a/codes/games/client/Projects/Spine/assets/spine/chipengganghu.atlas b/codes/games/client/Projects/Spine/assets/spine/chipengganghu.atlas new file mode 100644 index 0000000..b65951d --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/spine/chipengganghu.atlas @@ -0,0 +1,79 @@ +chipengganghu.png +size:2048,512 +filter:Linear,Linear +Dda_Jt03 +bounds:1947,288,92,92 +Dda_Jt03-1 +bounds:311,343,138,138 +Dda_Jt05 +bounds:1134,353,128,128 +banyuanguangquan (4) +bounds:1947,382,99,99 +chi1 +bounds:609,244,108,100 +chi2 +bounds:572,22,24,18 +chi4 +bounds:726,347,134,134 +gang1 +bounds:609,144,108,98 +gang2 +bounds:862,347,134,134 +guo1 +bounds:1356,284,85,77 +guo2 +bounds:1385,369,112,112 +hu1 +bounds:2,5,23,26 +hu7 +bounds:475,8,95,101 +hu8 +bounds:590,346,134,135 +peng1 +bounds:150,149,113,93 +quan-002 +bounds:572,42,100,100 +saoguang_00000 +bounds:1499,370,110,111 +saoguang_00001 +bounds:1611,370,110,111 +saoguang_00002 +bounds:1723,370,110,111 +saoguang_00003 +bounds:1835,370,110,111 +saoguang_00004 +bounds:275,230,110,111 +saoguang_00005 +bounds:141,36,110,111 +saoguang_00006 +bounds:265,117,110,111 +saoguang_00007 +bounds:253,4,110,111 +saoguang_00008 +bounds:387,224,110,111 +saoguang_00009 +bounds:377,111,110,111 +åƒ +bounds:365,2,108,107 +å¬ +bounds:674,45,94,97 +图层 10 +bounds:1264,363,119,118 +图层 3 +bounds:157,345,152,136 +图层 4 +bounds:2,327,153,154 +图层 7 æ‹·è´ +bounds:2,179,146,146 +图层 9 +bounds:998,349,134,132 +æ  +bounds:499,227,108,108 +碰 +bounds:157,244,116,99 +组 12 +bounds:2,33,137,144 +组 13 +bounds:451,337,137,144 +过 +bounds:1264,279,90,82 diff --git a/codes/games/client/Projects/Spine/assets/spine/chipengganghu.json b/codes/games/client/Projects/Spine/assets/spine/chipengganghu.json new file mode 100644 index 0000000..cb4954c --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/spine/chipengganghu.json @@ -0,0 +1 @@ +{"skeleton":{"hash":"r/nxLpWd57U","spine":"4.2.43","x":-68.5,"y":-72,"width":137,"height":144,"images":"./0/","audio":""},"bones":[{"name":"root"},{"name":"bone","parent":"root"},{"name":"pai","parent":"bone"},{"name":"piaodong","parent":"pai"},{"name":"1","parent":"piaodong","length":23.81,"rotation":-139.82,"x":52.63,"y":63.93,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"2","parent":"piaodong","length":23.81,"rotation":-139.82,"x":88.75,"y":1.41,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"3","parent":"piaodong","length":23.81,"rotation":-139.82,"x":-2.23,"y":86.89,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"4","parent":"piaodong","length":23.81,"rotation":-139.82,"x":-1.54,"y":59.45,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"5","parent":"piaodong","length":23.81,"rotation":-139.82,"x":80.95,"y":46.13,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"6","parent":"piaodong","length":23.81,"rotation":-139.82,"x":38.7,"y":70.09,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"7","parent":"piaodong","length":23.81,"rotation":-139.82,"x":79.23,"y":30.89,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"bone2","parent":"1","rotation":-31.82,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"bone3","parent":"2","rotation":-105.69,"x":11.76,"y":0.18},{"name":"bone4","parent":"3","rotation":-101.42,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"bone5","parent":"4","rotation":115.97,"x":11.76,"y":0.18},{"name":"bone6","parent":"5","rotation":-69.6,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"bone7","parent":"6","rotation":115.97,"x":11.76,"y":0.18},{"name":"bone8","parent":"7","rotation":-170.14,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"di","parent":"pai"},{"name":"bone9","parent":"di","y":4},{"name":"di2","parent":"di","y":3},{"name":"qian1","parent":"di2","color":"fff700ff"},{"name":"qian4","parent":"di2","color":"fff700ff"},{"name":"qian5","parent":"di2","color":"fff700ff"},{"name":"zhuan","parent":"di"},{"name":"zi","parent":"pai"}],"slots":[{"name":"chi4","bone":"di","attachment":"组 13"},{"name":"saoguang_00000","bone":"bone9","blend":"additive"},{"name":"chi1","bone":"zi"},{"name":"chi2","bone":"bone2","blend":"additive"},{"name":"chi3","bone":"bone3","blend":"additive"},{"name":"chi5","bone":"bone4","blend":"additive"},{"name":"chi6","bone":"bone5","blend":"additive"},{"name":"chi7","bone":"bone6","blend":"additive"},{"name":"chi8","bone":"bone7","blend":"additive"},{"name":"chi9","bone":"bone8","blend":"additive"},{"name":"quan-002","bone":"qian4","blend":"additive"},{"name":"quan-2","bone":"qian5","blend":"additive"},{"name":"Dda_Jt03","bone":"qian1","blend":"additive"},{"name":"banyuanguangquan (4)","bone":"zhuan","blend":"additive"},{"name":"banyuanguangquan (4)2","bone":"zhuan","blend":"additive"}],"skins":[{"name":"default","attachments":{"banyuanguangquan (4)":{"banyuanguangquan (4)":{"width":99,"height":99}},"banyuanguangquan (4)2":{"banyuanguangquan (4)":{"rotation":180,"width":99,"height":99}},"chi1":{"chi1":{"x":-2,"y":4,"width":108,"height":100},"gang1":{"x":1,"y":4,"width":108,"height":98},"guo1":{"x":1.99,"y":3,"width":85,"height":77},"hu7":{"x":-2.99,"y":2,"width":95,"height":101},"peng1":{"x":-0.99,"y":7,"width":113,"height":93},"åƒ":{"width":108,"height":107},"å¬":{"width":94,"height":97},"æ ":{"width":108,"height":108},"碰":{"width":116,"height":99},"过":{"width":90,"height":82}},"chi2":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi3":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi4":{"chi4":{"width":134,"height":134},"gang2":{"width":134,"height":134},"guo2":{"width":112,"height":112},"hu8":{"width":134,"height":135},"图层 3":{"width":152,"height":136},"图层 4":{"width":153,"height":154},"图层 7 æ‹·è´":{"width":146,"height":146},"图层 9":{"width":134,"height":132},"图层 10":{"width":119,"height":118},"组 12":{"width":137,"height":144},"组 13":{"width":137,"height":144}},"chi5":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi6":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi7":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi8":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi9":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"Dda_Jt03":{"Dda_Jt03":{"width":92,"height":92},"Dda_Jt05":{"width":128,"height":128}},"quan-2":{"Dda_Jt03-1":{"width":138,"height":138},"quan-002":{"width":100,"height":100}},"quan-002":{"Dda_Jt03-1":{"width":138,"height":138},"quan-002":{"width":100,"height":100}},"saoguang_00000":{"saoguang_00000":{"width":110,"height":111},"saoguang_00001":{"width":110,"height":111},"saoguang_00002":{"width":110,"height":111},"saoguang_00003":{"width":110,"height":111},"saoguang_00004":{"width":110,"height":111},"saoguang_00005":{"width":110,"height":111},"saoguang_00006":{"width":110,"height":111},"saoguang_00007":{"width":110,"height":111},"saoguang_00008":{"width":110,"height":111},"saoguang_00009":{"width":110,"height":111}}}}],"animations":{"chi1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"chi1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"chi4"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"chi2":{"slots":{"chi1":{"attachment":[{"name":"chi1"}]},"chi4":{"attachment":[{"name":"chi4"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"chi3":{"slots":{"chi1":{"attachment":[{"name":"åƒ"}]},"chi4":{"attachment":[{"name":"组 12"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"gang1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"gang1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"gang2"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"gang2":{"slots":{"chi1":{"attachment":[{"name":"æ "}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"chi2"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi4":{"attachment":[{"name":"gang2"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"chi2"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"chi2"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"chi2"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]}}},"guo1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"guo1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"guo2"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"guo2":{"slots":{"chi1":{"attachment":[{"name":"guo1"}]},"chi4":{"attachment":[{"name":"guo2"}]}}},"guo3":{"slots":{"banyuanguangquan (4)":{"attachment":[{"name":"banyuanguangquan (4)"}]},"chi1":{"attachment":[{"name":"过"}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"chi2"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi4":{"attachment":[{"name":"图层 9"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"chi2"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"chi2"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"chi2"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"di":{"scale":[{"x":1.2,"y":1.2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]},"zhuan":{"rotate":[{},{"time":2,"value":360}]}}},"guo4":{"slots":{"chi1":{"attachment":[{"name":"过"}]},"chi4":{"attachment":[{"name":"图层 9"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"guo5":{"slots":{"chi1":{"attachment":[{"name":"过"}]},"chi4":{"attachment":[{"name":"图层 9"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"},{"time":0.0333}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,1.583,1,0.501,1,1.583,1,0.5,1,1.583,1,0.5,0,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"scale":[{"x":1.486,"y":1.486}]},"pai":{"scale":[{"time":2}]}}},"hu1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"hu7"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"hu8"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"hu2":{"slots":{"banyuanguangquan (4)":{"attachment":[{"name":"banyuanguangquan (4)"}]},"banyuanguangquan (4)2":{"attachment":[{"name":"banyuanguangquan (4)"}]},"chi1":{"attachment":[{"name":"hu7"}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"hu1"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi4":{"attachment":[{"name":"hu8"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"hu1"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"hu1"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt05"}]},"quan-2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.542,1,0.625,1,0.542,1,0.625,1,0.542,1,0.625,1,0.542,0,0.625,1]},{"time":0.6667,"color":"ffffffff","curve":"stepped"},{"time":1.1667,"color":"ffffffff","curve":[1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"saoguang_00000":{"rgba":[{"color":"ffffff00","curve":[0.117,1,0.35,1,0.117,1,0.35,0.56,0.117,1,0.35,0.58,0.117,0,0.35,0.58]},{"time":0.4667,"color":"ff909495","curve":[0.6,1,0.867,1,0.6,0.56,0.867,1,0.6,0.58,0.867,1,0.6,0.58,0.867,0]},{"time":1,"color":"ffffff00"}],"attachment":[{"time":0.0333,"name":"saoguang_00000"},{"time":0.1333,"name":"saoguang_00001"},{"time":0.2333,"name":"saoguang_00002"},{"time":0.3333,"name":"saoguang_00003"},{"time":0.4333,"name":"saoguang_00004"},{"time":0.5333,"name":"saoguang_00005"},{"time":0.6333,"name":"saoguang_00006"},{"time":0.7333,"name":"saoguang_00007"},{"time":0.8333,"name":"saoguang_00008"},{"time":0.9333,"name":"saoguang_00009"},{"time":1}]}},"bones":{"qian1":{"scale":[{"x":1.37,"y":1.37,"curve":[0.208,1.37,0.625,1.542,0.208,1.37,0.625,1.542]},{"time":0.8333,"x":1.542,"y":1.542}]},"zhuan":{"rotate":[{},{"time":0.5,"value":90},{"time":1,"value":180},{"time":1.5,"value":270},{"time":2,"value":360}],"translate":[{"y":3}],"scale":[{"x":1.212,"y":1.212}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}],"scale":[{"x":0.589,"y":0.589}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}],"scale":[{"x":1.954,"y":1.954}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"y":0.06}],"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.327,1.509,1.627,0.927,1.327,1.509,1.627]},{"time":1.8333,"x":1.627,"y":1.627}]},"qian5":{"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.237,1.509,1.307,0.927,1.237,1.509,1.307]},{"time":1.8333,"x":1.307,"y":1.307}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]}}},"peng1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"peng1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"chi4"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"peng2":{"slots":{"chi1":{"attachment":[{"name":"碰"}]},"chi4":{"attachment":[{"name":"图层 7 æ‹·è´"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"ting":{"slots":{"banyuanguangquan (4)":{"attachment":[{"name":"banyuanguangquan (4)"}]},"banyuanguangquan (4)2":{"attachment":[{"name":"banyuanguangquan (4)"}]},"chi1":{"attachment":[{"name":"å¬"}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"hu1"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi4":{"attachment":[{"name":"图层 4"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"hu1"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"hu1"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt05"}]},"quan-2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.542,1,0.625,1,0.542,1,0.625,1,0.542,1,0.625,1,0.542,0,0.625,1]},{"time":0.6667,"color":"ffffffff","curve":"stepped"},{"time":1.1667,"color":"ffffffff","curve":[1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"saoguang_00000":{"rgba":[{"color":"ffffff00","curve":[0.117,1,0.35,1,0.117,1,0.35,0.56,0.117,1,0.35,0.58,0.117,0,0.35,0.58]},{"time":0.4667,"color":"ff909495","curve":[0.6,1,0.867,1,0.6,0.56,0.867,1,0.6,0.58,0.867,1,0.6,0.58,0.867,0]},{"time":1,"color":"ffffff00"}],"attachment":[{"time":0.0333,"name":"saoguang_00000"},{"time":0.1333,"name":"saoguang_00001"},{"time":0.2333,"name":"saoguang_00002"},{"time":0.3333,"name":"saoguang_00003"},{"time":0.4333,"name":"saoguang_00004"},{"time":0.5333,"name":"saoguang_00005"},{"time":0.6333,"name":"saoguang_00006"},{"time":0.7333,"name":"saoguang_00007"},{"time":0.8333,"name":"saoguang_00008"},{"time":0.9333,"name":"saoguang_00009"},{"time":1}]}},"bones":{"qian1":{"scale":[{"x":1.37,"y":1.37,"curve":[0.208,1.37,0.625,1.542,0.208,1.37,0.625,1.542]},{"time":0.8333,"x":1.542,"y":1.542}]},"zhuan":{"rotate":[{},{"time":0.5,"value":90},{"time":1,"value":180},{"time":1.5,"value":270},{"time":2,"value":360}],"translate":[{"y":3}],"scale":[{"x":1.212,"y":1.212}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}],"scale":[{"x":0.589,"y":0.589}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}],"scale":[{"x":1.954,"y":1.954}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"y":0.06}],"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.327,1.509,1.627,0.927,1.327,1.509,1.627]},{"time":1.8333,"x":1.627,"y":1.627}]},"qian5":{"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.237,1.509,1.307,0.927,1.237,1.509,1.307]},{"time":1.8333,"x":1.307,"y":1.307}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]},"pai":{"scale":[{"x":1.6,"y":1.6}]}}},"ting2":{"slots":{"chi1":{"attachment":[{"name":"å¬"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}}}} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/assets/spine/chipengganghu.png b/codes/games/client/Projects/Spine/assets/spine/chipengganghu.png new file mode 100644 index 0000000..36c7460 Binary files /dev/null and b/codes/games/client/Projects/Spine/assets/spine/chipengganghu.png differ diff --git a/codes/games/client/Projects/Spine/assets/spine/gamestart.atlas b/codes/games/client/Projects/Spine/assets/spine/gamestart.atlas new file mode 100644 index 0000000..ae43b80 --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/spine/gamestart.atlas @@ -0,0 +1,37 @@ +gamestart.png +size:2048,512 +filter:Linear,Linear +dai +bounds:1521,395,96,90 +deng +bounds:1418,395,101,90 +dian +bounds:1167,183,24,22 +duijukaishi +bounds:929,393,380,92 +fangkuai +bounds:446,47,32,32 +fangkuai_kuang +bounds:2,2,32,32 +glow_bian +bounds:2,36,330,9 +heitao_01 +bounds:929,173,236,218 +heitao_02 +bounds:2,47,442,219 +lamp_glow +bounds:446,81,198,185 +lizi_1 +bounds:646,247,19,19 +loading_aixin +bounds:1273,363,28,28 +new_tiao_orange +bounds:2,268,667,217 +pei +bounds:1311,393,105,92 +pi +bounds:1167,302,104,89 +xingguang +bounds:671,229,256,256 +zhong +bounds:1167,207,98,93 diff --git a/codes/games/client/Projects/Spine/assets/spine/gamestart.json b/codes/games/client/Projects/Spine/assets/spine/gamestart.json new file mode 100644 index 0000000..7627b08 --- /dev/null +++ b/codes/games/client/Projects/Spine/assets/spine/gamestart.json @@ -0,0 +1 @@ +{"skeleton":{"hash":"Cs22lzcwV3A","spine":"4.2.43","x":-862.3,"y":-188.35,"width":1724.6,"height":375.11,"images":"./0/","audio":"I:\\游æˆç´ ææ”¶é›†\\棋牌\\é—²æ¥æ–—地主\\spine\\UI\\pipei_fx"},"bones":[{"name":"root"},{"name":"loading","parent":"root"},{"name":"pipeizhong","parent":"root"},{"name":"zhong","parent":"pipeizhong","length":35.15,"rotation":88.12,"x":97.58,"y":5.54},{"name":"pi","parent":"pipeizhong","x":-86.85,"y":2.78},{"name":"pei","parent":"pipeizhong","x":0.58,"y":-3.86},{"name":"lizi","parent":"root","length":9.44,"rotation":5.19,"x":187.44,"y":25.51},{"name":"lizi2","parent":"root","length":9.44,"rotation":5.19,"x":-235.41,"y":-103.34,"scaleX":0.9,"scaleY":0.9},{"name":"lizi3","parent":"root","length":9.44,"rotation":5.19,"x":91.71,"y":-113.98,"scaleX":0.8,"scaleY":0.8},{"name":"lizi4","parent":"root","length":9.44,"rotation":5.19,"x":-202.78,"y":94.66},{"name":"lizi5","parent":"root","length":9.44,"rotation":5.19,"x":167.97,"y":36.8,"scaleX":0.5,"scaleY":0.5},{"name":"lizi6","parent":"root","length":9.44,"rotation":5.19,"x":-162.19,"y":6.78,"scaleX":0.5,"scaleY":0.5},{"name":"taoxin_zong","parent":"root"},{"name":"glow_y","parent":"root"},{"name":"fangkuai","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.8,"scaleY":0.8},{"name":"tiao_new","parent":"root"},{"name":"heitao","parent":"tiao_new"},{"name":"heitao2","parent":"tiao_new"},{"name":"lizi7","parent":"root","length":9.44,"rotation":5.19,"x":60.86,"y":77.88},{"name":"lizi8","parent":"root","length":9.44,"rotation":5.19,"x":-73.19,"y":-90.44,"scaleX":1.5,"scaleY":1.5},{"name":"glow_y2","parent":"root"},{"name":"star","parent":"root","length":17.48,"x":14.55,"y":40.7},{"name":"fangkuai2","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.4,"scaleY":0.4},{"name":"fangkuai3","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.6,"scaleY":0.6},{"name":"fangkuai4","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.7,"scaleY":0.7},{"name":"lizi9","parent":"root","length":9.44,"rotation":5.19,"x":-92.32,"y":75.72,"scaleX":1.2,"scaleY":1.2},{"name":"fangkuai5","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.6,"scaleY":0.6},{"name":"fangkuai6","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.4,"scaleY":0.4},{"name":"fangkuai7","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.5,"scaleY":0.5},{"name":"fangkuai8","parent":"root","length":28.56,"x":343.36,"y":-3.03},{"name":"fangkuai9","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.8,"scaleY":0.8},{"name":"star4","parent":"root","length":17.48,"x":202.79,"y":-34.6},{"name":"lizi10","parent":"root","length":9.44,"rotation":5.19,"x":-179.89,"y":22.58,"scaleX":0.5,"scaleY":0.5},{"name":"glow_bian","parent":"tiao_new"},{"name":"glow_bian2","parent":"tiao_new"},{"name":"success2","parent":"root"},{"name":"dian","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"dian2","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"dian3","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"tiao","parent":"tiao_new","scaleX":1.2928}],"slots":[{"name":"BG","bone":"root"},{"name":"ck_new","bone":"root"},{"name":"new_tiao_orange","bone":"tiao","attachment":"new_tiao_orange"},{"name":"heitao_01","bone":"heitao","attachment":"heitao_01"},{"name":"heitao_2","bone":"heitao2","attachment":"heitao_02"},{"name":"glow_bian","bone":"glow_bian","blend":"additive"},{"name":"glow_bian2","bone":"glow_bian2","blend":"additive"},{"name":"loading_aixin","bone":"loading"},{"name":"pi","bone":"pi","attachment":"pi"},{"name":"pei","bone":"pei","attachment":"pei"},{"name":"zhong","bone":"zhong","attachment":"zhong"},{"name":"lizi_1","bone":"lizi","attachment":"lizi_1","blend":"additive"},{"name":"lizi_7","bone":"lizi7","attachment":"lizi_1","blend":"additive"},{"name":"lizi_9","bone":"lizi9","attachment":"lizi_1","blend":"additive"},{"name":"lizi_5","bone":"lizi5","attachment":"lizi_1","blend":"additive"},{"name":"lizi_10","bone":"lizi10","attachment":"lizi_1","blend":"additive"},{"name":"lizi_6","bone":"lizi6","attachment":"lizi_1","blend":"additive"},{"name":"lizi_3","bone":"lizi3","attachment":"lizi_1","blend":"additive"},{"name":"lizi_4","bone":"lizi4","attachment":"lizi_1","blend":"additive"},{"name":"lizi_8","bone":"lizi8","attachment":"lizi_1","blend":"additive"},{"name":"lizi_2","bone":"lizi2","attachment":"lizi_1","blend":"additive"},{"name":"lamp_glow3","bone":"glow_y","attachment":"lamp_glow","blend":"additive"},{"name":"fangkuai6","bone":"fangkuai","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai5","bone":"fangkuai5","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai4","bone":"fangkuai4","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai11","bone":"fangkuai8","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai12","bone":"fangkuai9","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai2","bone":"fangkuai2","blend":"additive"},{"name":"fangkuai7","bone":"fangkuai6","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai3","bone":"fangkuai3","blend":"additive"},{"name":"fangkuai9","bone":"fangkuai7","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai_kuang6","bone":"fangkuai","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang5","bone":"fangkuai5","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang4","bone":"fangkuai4","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang11","bone":"fangkuai8","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang12","bone":"fangkuai9","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang2","bone":"fangkuai2","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang7","bone":"fangkuai6","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang3","bone":"fangkuai3","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang9","bone":"fangkuai7","attachment":"fangkuai_kuang","blend":"screen"},{"name":"duijukaishi","bone":"success2","attachment":"duijukaishi"},{"name":"duijukaishi2","bone":"success2","attachment":"duijukaishi","blend":"additive"},{"name":"lamp_glow4","bone":"glow_y2","attachment":"lamp_glow","blend":"additive"},{"name":"lamp_glow5","bone":"glow_y2","attachment":"lamp_glow","blend":"additive"},{"name":"star2","bone":"star","attachment":"xingguang","blend":"additive"},{"name":"star8","bone":"star4","attachment":"xingguang","blend":"additive"},{"name":"dian","bone":"dian","attachment":"dian"},{"name":"dian2","bone":"dian2","attachment":"dian"},{"name":"dian3","bone":"dian3","attachment":"dian"},{"name":"ck_waiting","bone":"root","color":"ffffff86"}],"skins":[{"name":"default","attachments":{"dian":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"dian2":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"dian3":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"duijukaishi":{"duijukaishi":{"width":380,"height":92}},"duijukaishi2":{"duijukaishi":{"width":380,"height":92}},"fangkuai2":{"fangkuai":{"width":32,"height":32}},"fangkuai3":{"fangkuai":{"width":32,"height":32}},"fangkuai4":{"fangkuai":{"width":32,"height":32}},"fangkuai5":{"fangkuai":{"width":32,"height":32}},"fangkuai6":{"fangkuai":{"width":32,"height":32}},"fangkuai7":{"fangkuai":{"width":32,"height":32}},"fangkuai9":{"fangkuai":{"width":32,"height":32}},"fangkuai11":{"fangkuai":{"width":32,"height":32}},"fangkuai12":{"fangkuai":{"width":32,"height":32}},"fangkuai_kuang2":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang3":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang4":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang5":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang6":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang7":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang9":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang11":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang12":{"fangkuai_kuang":{"width":32,"height":32}},"glow_bian":{"glow_bian":{"x":422.12,"y":-69.57,"scaleX":1.2,"scaleY":0.6,"width":330,"height":9}},"glow_bian2":{"glow_bian":{"x":422.12,"y":64.41,"scaleX":1.2,"scaleY":0.6,"width":330,"height":9}},"heitao_01":{"heitao_01":{"y":-1.9,"width":236,"height":218}},"heitao_2":{"heitao_02":{"y":-2.2,"width":442,"height":219}},"lamp_glow3":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"scaleY":2.0276,"width":198,"height":185}},"lamp_glow4":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"scaleY":2.0276,"width":198,"height":185}},"lamp_glow5":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"width":198,"height":185}},"lizi_1":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_2":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_3":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_4":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_5":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_6":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_7":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_8":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_9":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_10":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"loading_aixin":{"loading_aixin":{"x":103.12,"y":81.11,"width":28,"height":28}},"new_tiao_orange":{"new_tiao_orange":{"y":-2.26,"scaleX":2,"width":667,"height":217}},"pei":{"dai":{"x":5.24,"y":2.96,"width":96,"height":90},"pei":{"x":3.04,"y":2.96,"width":105,"height":92}},"pi":{"deng":{"x":-1.03,"y":-4.17,"width":101,"height":90},"pi":{"x":-1.03,"y":-4.17,"width":104,"height":89}},"star2":{"xingguang":{"x":0.34,"scaleX":0.3,"scaleY":0.3,"width":256,"height":256}},"star8":{"xingguang":{"scaleX":0.2,"scaleY":0.2,"width":256,"height":256}},"zhong":{"zhong":{"x":-6.91,"y":-0.76,"rotation":-88.12,"width":98,"height":93}}}}],"animations":{"start":{"slots":{"duijukaishi":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.1667,"color":"ffffff00"},{"time":0.3,"color":"ffffffff"}]},"duijukaishi2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff","curve":"stepped"},{"time":0.4,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai2":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"time":0.4667,"name":"fangkuai"},{"time":0.6}]},"fangkuai3":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}],"attachment":[{"time":0.6333,"name":"fangkuai"},{"time":0.7667}]},"fangkuai4":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}],"attachment":[{"time":0.3},{"time":0.4333,"name":"fangkuai"}]},"fangkuai5":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}],"attachment":[{"time":0.4},{"time":0.5333,"name":"fangkuai"}]},"fangkuai6":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}],"attachment":[{"time":0.5333},{"time":0.7,"name":"fangkuai"}]},"fangkuai7":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"time":0.6}]},"fangkuai9":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}],"attachment":[{"time":0.5},{"time":0.6333,"name":"fangkuai"}]},"fangkuai11":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}],"attachment":[{"time":0.2667},{"time":0.4,"name":"fangkuai"},{"time":0.5333}]},"fangkuai12":{"rgba":[{"time":0.7333,"color":"ffffffff"},{"time":0.9667,"color":"ffffff00"}],"attachment":[{"time":0.5667},{"time":0.7,"name":"fangkuai"},{"time":0.8333}]},"fangkuai_kuang2":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}]},"fangkuai_kuang3":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}]},"fangkuai_kuang4":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai_kuang5":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}]},"fangkuai_kuang6":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}]},"fangkuai_kuang7":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}]},"fangkuai_kuang9":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}]},"fangkuai_kuang11":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai_kuang12":{"rgba":[{"time":0.7333,"color":"ffffffff"},{"time":0.9667,"color":"ffffff00"}]},"glow_bian":{"rgba":[{"time":0.7667,"color":"ffffffff"},{"time":0.9,"color":"ffffff00"}],"attachment":[{"time":0.3667,"name":"glow_bian"}]},"glow_bian2":{"rgba":[{"time":0.7667,"color":"ffffffff"},{"time":0.9,"color":"ffffff00"}],"attachment":[{"time":0.3667,"name":"glow_bian"}]},"heitao_01":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.2,"color":"ffffff00","curve":[0.242,1,0.325,1,0.242,1,0.325,1,0.242,1,0.325,1,0.242,0,0.325,1]},{"time":0.3667,"color":"ffffffff"}]},"heitao_2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3,"color":"ffffff00","curve":[0.342,1,0.425,1,0.342,1,0.425,1,0.342,1,0.425,1,0.342,0,0.425,1]},{"time":0.4667,"color":"ffffffff"}]},"lamp_glow3":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.0667,"color":"ffffffb4"},{"time":0.2,"color":"ffffff00"}],"attachment":[{}]},"lamp_glow4":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.4,"color":"ffffffb4"},{"time":0.5,"color":"ffffff00"}]},"lamp_glow5":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.4,"color":"ffffffb4"},{"time":0.5,"color":"ffffff00"}]},"lizi_7":{"rgba":[{"color":"ffdf63ff"}]},"lizi_8":{"rgba":[{"color":"ffdf63ff"}]},"lizi_9":{"rgba":[{"color":"ffdf64ff"}]},"lizi_10":{"attachment":[{}]},"new_tiao_orange":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.0667,"color":"ffffff00"},{"time":0.1333,"color":"ffffffff"}]},"pei":{"attachment":[{"name":"dai"}]},"pi":{"attachment":[{"name":"deng"}]},"star2":{"attachment":[{},{"time":0.4333,"name":"xingguang"},{"time":0.7667}]},"star8":{"attachment":[{},{"time":0.6,"name":"xingguang"}]}},"bones":{"fangkuai5":{"rotate":[{"time":0.3},{"time":0.7667,"value":-44.88}],"translate":[{"x":-504.35,"y":11.18,"curve":"stepped"},{"time":0.3,"x":-504.35,"y":11.18},{"time":0.7667,"x":-599.14,"y":28.32}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3,"x":0,"y":0},{"time":0.4},{"time":0.5333,"x":0.5,"y":0.5},{"time":0.6333},{"time":0.7667,"x":0.5,"y":0.5}]},"fangkuai6":{"rotate":[{"value":-44.88,"curve":"stepped"},{"time":0.3667,"value":-44.88},{"time":0.8333}],"translate":[{"x":-517.09,"y":-15.18,"curve":"stepped"},{"time":0.3667,"x":-517.09,"y":-15.18},{"time":0.8333,"x":-624.16,"y":-31.78}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3667,"x":0,"y":0},{"time":0.4667},{"time":0.6,"x":0.5,"y":0.5},{"time":0.7},{"time":0.8333,"x":0.5,"y":0.5}]},"fangkuai7":{"rotate":[{"value":30,"curve":"stepped"},{"time":0.4,"value":30},{"time":0.8667,"value":-90}],"translate":[{"x":-498.9,"y":4.26,"curve":"stepped"},{"time":0.4,"x":-498.9,"y":4.26},{"time":0.8667,"x":-570.14,"y":-1.69}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.4,"x":0,"y":0},{"time":0.5},{"time":0.6333,"x":0.5,"y":0.5},{"time":0.7333},{"time":0.8667,"x":0.5,"y":0.5}]},"success2":{"scale":[{"x":2.7,"y":2.2,"curve":"stepped"},{"time":0.1667,"x":2.7,"y":2.2},{"time":0.2,"x":2.51,"y":1.363},{"time":0.2333,"x":2.32,"y":1.92},{"time":0.3333,"x":0.8,"y":0.8},{"time":0.5,"x":1.06,"y":1.06},{"time":0.6667}]},"glow_y2":{"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2667,"x":0,"y":0},{"time":0.3333,"x":1.5,"y":1.2},{"time":0.5,"x":2,"y":0}]},"pei":{"translate":[{"x":-40.85}]},"star":{"rotate":[{"time":0.4333},{"time":0.7667,"value":-60}],"translate":[{"x":1.77,"y":0.73}],"scale":[{"time":0.4333},{"time":0.7667,"x":0,"y":0}]},"fangkuai3":{"rotate":[{"value":30,"curve":"stepped"},{"time":0.4,"value":30},{"time":0.8667,"value":-90}],"translate":[{"x":-148.5,"y":26.53,"curve":"stepped"},{"time":0.4,"x":-148.5,"y":26.53},{"time":0.8667,"x":-28.24,"y":27.97}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.4,"x":0,"y":0},{"time":0.5},{"time":0.6333,"x":0.5,"y":0.5},{"time":0.7333},{"time":0.8667,"x":0.5,"y":0.5}]},"fangkuai2":{"rotate":[{"value":-44.88,"curve":"stepped"},{"time":0.3667,"value":-44.88},{"time":0.8333}],"translate":[{"x":-169.32,"y":-17.49,"curve":"stepped"},{"time":0.3667,"x":-169.32,"y":-17.49},{"time":0.8333,"x":-73.95,"y":-28.46}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3667,"x":0,"y":0},{"time":0.4667},{"time":0.6,"x":0.5,"y":0.5},{"time":0.7},{"time":0.8333,"x":0.5,"y":0.5}]},"fangkuai4":{"rotate":[{"time":0.2},{"time":0.6667,"value":-44.88}],"translate":[{"x":-135.94,"y":12.14,"curve":"stepped"},{"time":0.2,"x":-135.94,"y":12.14},{"time":0.6667,"x":0.5,"y":13.65}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2,"x":0,"y":0},{"time":0.3},{"time":0.4333,"x":0.5,"y":0.5},{"time":0.5333},{"time":0.6667,"x":0.5,"y":0.5}]},"star4":{"rotate":[{"value":-60,"curve":"stepped"},{"time":0.6,"value":-60},{"time":0.9333}],"translate":[{"x":-23.34,"y":-3.43}],"scale":[{"time":0.6},{"time":0.9333,"x":0,"y":0}]},"glow_y":{"scale":[{"x":0,"y":0},{"time":0.0667,"y":1.3},{"time":0.2,"x":2,"y":0}]},"fangkuai9":{"rotate":[{"time":0.5},{"time":0.9667,"value":-44.88}],"translate":[{"x":-510.8,"y":-9.98,"curve":"stepped"},{"time":0.5,"x":-510.8,"y":-9.98},{"time":0.9667,"x":-682.69,"y":-0.2}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.5,"x":0,"y":0},{"time":0.6},{"time":0.7333,"x":0.5,"y":0.5},{"time":0.8333},{"time":0.9667,"x":0.5,"y":0.5}]},"lizi9":{"translate":[{"x":23.12,"y":-46.87,"curve":"stepped"},{"time":0.1333,"x":23.12,"y":-46.87},{"time":0.8,"x":-32.53,"y":36.07}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.1333,"x":0,"y":0},{"time":0.3},{"time":0.4667,"x":0,"y":0},{"time":0.6333},{"time":0.8,"x":0,"y":0}]},"lizi7":{"translate":[{"x":27.53,"y":-8.06},{"time":0.9667,"x":78.87,"y":21.58}],"scale":[{"x":0,"y":0},{"time":0.1333},{"time":0.3,"x":0,"y":0},{"time":0.4667},{"time":0.6333,"x":0,"y":0},{"time":0.8},{"time":0.9667,"x":0,"y":0}]},"lizi8":{"translate":[{"x":40.95,"y":12.56},{"time":0.6333,"x":4.64,"y":-14.33}],"scale":[{"x":0,"y":0},{"time":0.1333},{"time":0.3,"x":0,"y":0},{"time":0.4667},{"time":0.6333,"x":0,"y":0}]},"glow_bian":{"translate":[{"x":-72.21,"curve":"stepped"},{"time":0.3667,"x":-72.21,"curve":[0.5,-72.21,0.767,-804.76,0.5,0,0.767,0]},{"time":0.9,"x":-804.76}]},"heitao":{"scale":[{"x":3,"curve":"stepped"},{"time":0.2,"x":3,"curve":[0.242,3,0.325,0.8,0.242,1,0.325,1]},{"time":0.3667,"x":0.8,"curve":[0.408,0.8,0.492,1.4,0.408,1,0.492,1]},{"time":0.5333,"x":1.4,"curve":[0.583,1.4,0.683,1,0.583,1,0.683,1]},{"time":0.7333}]},"glow_bian2":{"translate":[{"x":-656,"curve":"stepped"},{"time":0.3667,"x":-656,"curve":[0.5,-656,0.767,97.85,0.5,0,0.767,0]},{"time":0.9,"x":97.85}]},"pi":{"translate":[{"x":-41.74}]},"fangkuai8":{"rotate":[{"time":0.2},{"time":0.6667,"value":-44.88}],"translate":[{"x":-535.78,"y":-2.96,"curve":"stepped"},{"time":0.2,"x":-535.78,"y":-2.96},{"time":0.6667,"x":-641.17,"y":-6.75}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2,"x":0,"y":0},{"time":0.3},{"time":0.4333,"x":0.5,"y":0.5},{"time":0.5333},{"time":0.6667,"x":0.5,"y":0.5}]},"fangkuai":{"rotate":[{"time":0.3},{"time":0.7667,"value":-44.88}],"translate":[{"x":-153,"curve":"stepped"},{"time":0.3,"x":-153},{"time":0.7667,"x":-13.01}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3,"x":0,"y":0},{"time":0.4},{"time":0.5333,"x":0.5,"y":0.5},{"time":0.6333},{"time":0.7667,"x":0.5,"y":0.5}]},"heitao2":{"scale":[{"x":3,"curve":"stepped"},{"time":0.3,"x":3,"curve":[0.342,3,0.425,0.8,0.342,1,0.425,1]},{"time":0.4667,"x":0.8,"curve":[0.508,0.8,0.592,1.4,0.508,1,0.592,1]},{"time":0.6333,"x":1.4,"curve":[0.683,1.4,0.783,1,0.683,1,0.783,1]},{"time":0.8333}]},"lizi":{"scale":[{"x":0,"y":0}]},"lizi2":{"translate":[{"x":-3.71,"y":-20.79}],"scale":[{"x":0,"y":0}]},"lizi3":{"translate":[{"x":39.37,"y":-38.75}],"scale":[{"x":0,"y":0}]},"lizi4":{"scale":[{"x":0,"y":0}]},"lizi5":{"translate":[{"x":27.61,"y":27.45}],"scale":[{"x":0,"y":0}]},"lizi6":{"translate":[{"x":-51.66,"y":-60.09}],"scale":[{"x":0,"y":0}]},"pipeizhong":{"scale":[{},{"time":0.1,"x":0,"y":0}]},"tiao_new":{"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.0667,"x":0,"y":0},{"time":0.1333,"y":0.1},{"time":0.2333,"y":1.3},{"time":0.3667,"y":0.9},{"time":0.5}]},"zhong":{"translate":[{"x":-41.29}]},"dian":{"translate":[{"x":-83.49,"y":2.22}]},"dian2":{"translate":[{"x":-57.12,"y":2.22}]},"dian3":{"translate":[{"x":-31.53,"y":2.22}]}}}}} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/assets/spine/gamestart.png b/codes/games/client/Projects/Spine/assets/spine/gamestart.png new file mode 100644 index 0000000..eb795dd Binary files /dev/null and b/codes/games/client/Projects/Spine/assets/spine/gamestart.png differ diff --git a/codes/games/client/Projects/Spine/docs/SpineåŠ¨ç”»é›†æˆæ‰‹å†Œ.md b/codes/games/client/Projects/Spine/docs/SpineåŠ¨ç”»é›†æˆæ‰‹å†Œ.md new file mode 100644 index 0000000..e7398eb --- /dev/null +++ b/codes/games/client/Projects/Spine/docs/SpineåŠ¨ç”»é›†æˆæ‰‹å†Œ.md @@ -0,0 +1,806 @@ +# Spine åŠ¨ç”»é›†æˆæ‰‹å†Œ + +> 本手册针对 **gameabc 引擎** çš„ Spine 项目,说明如何在 Canvas 2D 游æˆä¸­åŠ è½½ã€ +> æŽ§åˆ¶å’Œç®¡ç† Spine 骨骼动画。 +> è¿è¡Œæ—¶ç‰ˆæœ¬ï¼š**spine-canvas 4.2** | 引擎:**gameabc** + +--- + +## 目录 + +1. [项目结构总览](#1-项目结构总览) +2. [快速开始:5 分钟跑通](#2-快速开始5-分钟跑通) +3. [从 Spine 编辑器导出资æº](#3-从-spine-编辑器导出资æº) +4. [SpineMgr 完整 API å‚考](#4-spinemgr-完整-api-å‚考) +5. [事件系统](#5-事件系统) +6. [常è§ç”¨æ³•示例](#6-常è§ç”¨æ³•示例) +7. [与 gameabc ç²¾çµç³»ç»Ÿé…åˆ](#7-与-gameabc-ç²¾çµç³»ç»Ÿé…åˆ) +8. [性能优化建议](#8-性能优化建议) +9. [常è§é—®é¢˜æŽ’查](#9-常è§é—®é¢˜æŽ’查) +10. [附录:文件加载顺åº](#10-附录文件加载顺åº) + +--- + +## 1. 项目结构总览 + +``` +Projects/Spine/ +├── index.html â† å…¥å£ HTML +├── js/ +│ ├── spine-canvas.js ↠Spine Canvas 2D è¿è¡Œæ—¶ (第三方库) +│ ├── gameabc.min.js ↠gameabc 游æˆå¼•擎 +│ ├── SpineMgr.js ↠★ Spine 动画管ç†å™¨ï¼ˆç‹¬ç«‹æ–‡ä»¶ï¼Œè‡ªåŠ¨æŒ‚é’©æ¸²æŸ“ï¼‰ +│ ├── gamemain.js ↠游æˆä¸»é€»è¾‘(无需修改) +│ ├── Spine_Event.js ↠Spine 事件回调 (complete / event) +│ └── Project1_Event.js ↠精çµäº‹ä»¶å•å…ƒ +├── assets/ +│ ├── bmp/ ↠gameabc å›¾ç‰‡èµ„æº +│ └── spine/ ↠★ Spine 资æºç›®å½• +│ ├── xxx.json â† éª¨éª¼æ•°æ® (Spine 编辑器导出) +│ ├── xxx.atlas ↠图集æè¿°æ–‡ä»¶ +│ └── xxx.png ↠图集纹ç†å›¾ç‰‡ +├── output/ ↠gameabc 编译输出的é…ç½®æ•°æ® +├── save/ ↠gameabc 编辑器ä¿å­˜çš„ XML +└── docs/ ↠本文档所在目录 +``` + +### 关键文件说明 + +| 文件 | 作用 | 需è¦ä¿®æ”¹ | +|------|------|----------| +| `js/spine-canvas.js` | Spine 4.2 Canvas 渲染è¿è¡Œæ—¶ | ✗ ä¸è¦ä¿®æ”¹ | +| `js/SpineMgr.js` | Spine 动画管ç†å™¨ï¼Œè‡ªåЍåˆå§‹åŒ–+自动渲染 | ✗ ä¸éœ€è¦ä¿®æ”¹ | +| `js/gamemain.js` | 游æˆä¸»é€»è¾‘ï¼ˆä¿æŒåŽŸæ ·ï¼‰ | ✗ ä¸éœ€è¦ä¿®æ”¹ | +| `js/Spine_Event.js` | Spine 动画完æˆ/自定义事件回调 | ✓ 处ç†åŠ¨ç”»äº‹ä»¶ | +| `assets/spine/*` | Spine å¯¼å‡ºçš„èµ„æºæ–‡ä»¶ | ✓ æ”¾å…¥ä½ çš„èµ„æº | + +--- + +## 2. 快速开始:5 分钟跑通 + +### 第一步:准备 Spine èµ„æº + +å°† Spine 编辑器导出的 3 个文件å¤åˆ¶åˆ° `assets/spine/` 目录: + +``` +assets/spine/ +├── hero.json ↠骨骼 JSON +├── hero.atlas ↠图集æè¿° +└── hero.png â† å›¾é›†çº¹ç† +``` + +### 第二步:在任æ„ä½ç½®è°ƒç”¨ API 播放动画 + +**无需手动 `load`**,直接调用 `setAnimation` å³å¯ã€‚如果该 Spine å®žä¾‹å°šæœªåŠ è½½ï¼Œä¼šè‡ªåŠ¨æ ¹æ® id 查找资æºï¼ˆçº¦å®šæ–‡ä»¶å id.json / id.atlas)并创建实例。 +渲染也已自动挂钩到 `gameenddraw`,开å‘者无需编写任何渲染代ç ã€‚ + +在任何 gameabc 事件回调中直接调用å³å¯ï¼š + +```javascript +// 设置ä½ç½® + 播放动画,无需先 load +gameabc_face.spineMgr.setPosition("hero", 640, 500); +gameabc_face.spineMgr.setAnimation("hero", "idle", true); + +// 之åŽåˆ‡æ¢åŠ¨ç”» +gameabc_face.spineMgr.setAnimation("hero", "attack", false); +``` + +> **约定**:id å¿…é¡»ä¸Žèµ„æºæ–‡ä»¶å一致(ä¸å«æ‰©å±•å)。例如 id 为 `"hero"`, +> åˆ™éœ€è¦ `assets/spine/hero.json`ã€`hero.atlas`ã€`hero.png`。 +> +> **å¯é€‰**:如果资æºä¸åœ¨é»˜è®¤è·¯å¾„ `assets/spine/`ï¼Œå¯æ‰‹åŠ¨è°ƒç”¨ä¸€æ¬¡ `init()`: +> ```javascript +> gameabc_face.spineMgr.init("other/path/"); +> ``` + +### 第三步:打开 index.html å³å¯è¿è¡Œ + +用æµè§ˆå™¨æ‰“å¼€ `index.html`ï¼ˆéœ€è¦ HTTP æœåŠ¡å™¨çŽ¯å¢ƒï¼Œä¸èƒ½ç›´æŽ¥ `file://`): + +```bash +# 简易方法:在项目目录下å¯åЍ HTTP æœåŠ¡ +cd codes/games/client/Projects/Spine +npx http-server -p 8080 +# æµè§ˆå™¨è®¿é—® http://localhost:8080 +``` + +或者使用 gameabc 自带的预览环境。 + +--- + +## 3. 从 Spine ç¼–è¾‘å™¨å¯¼å‡ºèµ„æº + +### 导出设置(Spine 编辑器 → Export) + +1. 打开 Spine 编辑器,加载你的 `.spine` 项目 +2. 点击èœå• **Spine → Export...** +3. 左侧选择 **JSON** æ ¼å¼ +4. é…置项: + +| 设置项 | 推è值 | 说明 | +|--------|--------|------| +| Output folder | `assets/spine/` | 直接导出到项目目录 | +| Extension | `.json` | éª¨éª¼æ•°æ®æ ¼å¼ | +| Create atlas | ✓ 勾选 | åŒæ—¶ç”Ÿæˆå›¾é›† | +| Atlas extension | `.atlas` | 图集æè¿°æ ¼å¼ | +| Images folder | (默认) | çº¹ç†æ¥æº | +| Max width/height | 2048 / 2048 | å›¾é›†çº¹ç†æœ€å¤§å°ºå¯¸ | +| Pack settings → Power of two | ✓ 勾选 | 纹ç†å°ºå¯¸ä¸º 2 的幂 | +| Pack settings → Premultiply alpha | ✗ ä¸å‹¾é€‰ | Canvas 2D ä¸éœ€è¦é¢„乘 | + +5. 点击 **Export** 按钮 + +### 导出åŽå¾—到的文件 + +``` +hero.json ↠骨骼数æ®ï¼ŒåŒ…å«éª¨éª¼ã€æ’æ§½ã€åŠ¨ç”»ç­‰ +hero.atlas ↠图集æè¿°ï¼Œè®°å½•æ¯ä¸ªåŒºåŸŸåœ¨çº¹ç†ä¸­çš„ä½ç½® +hero.png ↠图集纹ç†å›¾ç‰‡ +``` + +> **注æ„**:如果图集很大被拆分æˆå¤šå¼ ï¼ˆ`hero.png`ã€`hero2.png`),所有 `.png` +> éƒ½éœ€è¦æ”¾åˆ° `assets/spine/` 目录中。`.atlas` 文件会自动引用它们。 + +--- + +## 4. SpineMgr 完整 API å‚考 + +`SpineMgr` 挂载在 `gameabc_face.spineMgr` 上,所有调用形如: + +```javascript +gameabc_face.spineMgr.方法å(傿•°); +``` + +--- + +### 4.1 init(basePath) *(å¯é€‰)* + +**æ‰‹åŠ¨è®¾ç½®èµ„æºæ ¹è·¯å¾„。通常无需调用——`load()` 会自动以默认路径 `"assets/spine/"` åˆå§‹åŒ–。** +ä»…åœ¨èµ„æºæ”¾åœ¨å…¶ä»–目录时æ‰éœ€è¦è°ƒç”¨ï¼š + +```javascript +gameabc_face.spineMgr.init("other/spine/path/"); +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `basePath` | string | Spine èµ„æºæ–‡ä»¶çš„æ ¹ç›®å½•路径,需è¦ä»¥ `/` 结尾。çœç•¥åˆ™ä½¿ç”¨é»˜è®¤å€¼ `"assets/spine/"` | + +--- + +### 4.2 load(id, jsonFile, atlasFile, option) *(å¯é€‰)* + +**手动加载一组 Spine 资æºå¹¶æ³¨å†Œä¸ºä¸€ä¸ªå®žä¾‹ã€‚通常无需调用——所有 API 在实例ä¸å­˜åœ¨æ—¶ä¼šè‡ªåŠ¨åŠ è½½ã€‚** + +ä»…åœ¨ä»¥ä¸‹æƒ…å†µéœ€è¦æ‰‹åŠ¨è°ƒç”¨ `load()`: +- id 与文件åä¸ä¸€è‡´ï¼ˆå¦‚ id 为 `"mj"` 但文件为 `mj_gangshangkaihua.json`) +- 需è¦åœ¨åŠ è½½æ—¶æŒ‡å®š skinã€scale ç­‰åˆå§‹å‚æ•° + +```javascript +gameabc_face.spineMgr.load("hero", "hero.json", "hero.atlas", { + x: 640, + y: 500, + scale: 0.5, + skin: "default", + animation: "idle", + loop: true, + mixDuration: 0.2 +}); +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `id` | string | 唯一标识,åŽç»­æ‰€æœ‰æ“作通过此 id 引用 | +| `jsonFile` | string | 骨骼 JSON 文件å(相对于 basePath) | +| `atlasFile` | string | 图集 atlas 文件å(相对于 basePath) | +| `option` | object | å¯é€‰é…置对象 | + +**option 字段:** + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `x` | number | 0 | Canvas X åæ ‡ | +| `y` | number | 0 | Canvas Y åæ ‡ | +| `scale` | number | 1 | åˆå§‹ç¼©æ”¾æ¯”例 | +| `skin` | string | `"default"` | åˆå§‹çš®è‚¤åç§° | +| `animation` | string | null | 加载完æˆåŽè‡ªåŠ¨æ’­æ”¾çš„åŠ¨ç”»å | +| `loop` | boolean | true | 默认动画是å¦å¾ªçޝ | +| `mixDuration` | number | 0.2 | åŠ¨ç”»åˆ‡æ¢æ—¶çš„è¿‡æ¸¡æ··åˆæ—¶é•¿ï¼ˆç§’) | + +--- + +### 4.3 setAnimation(id, animName, loop, track) + +**切æ¢åŠ¨ç”»ã€‚ç«‹å³æ›¿æ¢æŒ‡å®šè½¨é“上的当å‰åŠ¨ç”»ã€‚å¦‚æžœå®žä¾‹å°šæœªåŠ è½½ï¼Œä¼šè‡ªåŠ¨æ ¹æ® id 加载资æºå¹¶åœ¨å°±ç»ªåŽæ’­æ”¾ã€‚** + +```javascript +// 无需先 load,直接调用å³å¯ +gameabc_face.spineMgr.setAnimation("hero", "attack", false); +gameabc_face.spineMgr.setAnimation("hero", "run", true, 0); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animName` | string | - | 动画å称(必须在 Spine 中存在) | +| `loop` | boolean | true | 是å¦å¾ªçŽ¯æ’­æ”¾ | +| `track` | number | 0 | 轨é“å·ï¼ˆå¤šè½¨é“å¯å åŠ åŠ¨ç”»ï¼‰ | + +**返回值:** `TrackEntry` 对象,å¯ç”¨äºŽè¿›ä¸€æ­¥æŽ§åˆ¶ï¼›åŠ è½½æœªå®Œæˆæ—¶è¿”回 `null`。 + +--- + +### 4.4 addAnimation(id, animName, loop, delay, track) + +**将动画添加到播放队列,在当å‰åŠ¨ç”»ç»“æŸåŽè‡ªåŠ¨æ’­æ”¾ã€‚** + +```javascript +// 先播放 attack,attack 完æˆåŽè‡ªåŠ¨åˆ‡æ¢åˆ° idle +gameabc_face.spineMgr.setAnimation("hero", "attack", false); +gameabc_face.spineMgr.addAnimation("hero", "idle", true, 0); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animName` | string | - | 队列中的下一个动画 | +| `loop` | boolean | true | 是å¦å¾ªçޝ | +| `delay` | number | 0 | 延迟秒数(0 = ä¸Šä¸€åŠ¨ç”»ç»“æŸæ—¶ç«‹å³å¼€å§‹ï¼‰ | +| `track` | number | 0 | 轨é“å· | + +--- + +### 4.5 setPosition(id, x, y) + +**设置 Spine 实例在 Canvas 上的ä½ç½®ã€‚** + +```javascript +gameabc_face.spineMgr.setPosition("hero", 640, 500); +``` + +> Spine çš„åæ ‡åŽŸç‚¹åœ¨éª¨éª¼çš„æ ¹éª¨éª¼å¤„ã€‚Y è½´å‘上为正(与 Canvas çš„ Y è½´æ–¹å‘相å), +> spine-canvas è¿è¡Œæ—¶å·²åšäº†å†…部转æ¢ã€‚ + +--- + +### 4.6 setScale(id, sx, sy) + +**设置缩放。** + +```javascript +gameabc_face.spineMgr.setScale("hero", 0.5); // 等比缩放 +gameabc_face.spineMgr.setScale("hero", 0.5, 0.8); // 分别设置 X/Y +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `sx` | number | X æ–¹å‘缩放 | +| `sy` | number | Y æ–¹å‘缩放(çœç•¥åˆ™ç­‰äºŽ sx) | + +--- + +### 4.7 setFlip(id, flipX, flipY) + +**æ°´å¹³/垂直翻转。** + +```javascript +gameabc_face.spineMgr.setFlip("hero", true, false); // 水平翻转 +``` + +--- + +### 4.8 setVisible(id, visible) + +**显示或éšè— Spine 实例。** + +```javascript +gameabc_face.spineMgr.setVisible("hero", false); // éšè— +gameabc_face.spineMgr.setVisible("hero", true); // 显示 +``` + +--- + +### 4.9 setSkin(id, skinName) + +**切æ¢çš®è‚¤ã€‚** + +```javascript +gameabc_face.spineMgr.setSkin("hero", "warrior"); +``` + +> 切æ¢çš®è‚¤åŽä¼šè‡ªåЍé‡ç½®æ’槽到 Setup Pose。皮肤å必须在 Spine 编辑器中预定义。 + +--- + +### 4.10 getAnimations(id) + +**获å–该实例所有å¯ç”¨åŠ¨ç”»å称列表。** + +```javascript +var anims = gameabc_face.spineMgr.getAnimations("hero"); +// 返回: ["idle", "walk", "run", "attack", "die"] +logmessage("动画列表: " + anims.join(", ")); +``` + +--- + +### 4.11 getSkins(id) + +**获å–该实例所有å¯ç”¨çš®è‚¤å称列表。** + +```javascript +var skins = gameabc_face.spineMgr.getSkins("hero"); +// 返回: ["default", "warrior", "mage"] +``` + +--- + +### 4.12 playOnce(id, animName, track) + +**播放一次动画åŽè‡ªåЍéšè—。** è‡ªåŠ¨æ˜¾ç¤ºå®žä¾‹ã€æ’­æ”¾æŒ‡å®šåŠ¨ç”»ï¼ˆä¸å¾ªçŽ¯ï¼‰ï¼ŒåŠ¨ç”»å®ŒæˆåŽè‡ªåŠ¨è®¾ç½® `visible = false`。 + +```javascript +// 播放一次攻击动画,播完自动éšè— +gameabc_face.spineMgr.playOnce("hero", "attack"); + +// æŒ‡å®šè½¨é“ +gameabc_face.spineMgr.playOnce("hero", "attack", 0); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animName` | string | - | 动画åç§° | +| `track` | number | 0 | 轨é“å· | + +--- + +### 4.13 playQueue(id, animList, hideOnComplete) + +**æŒ‰é¡ºåºæ’­æ”¾ä¸€ç»„动画(队列),全部播完åŽå¯é€‰æ‹©éšè—æˆ–ä¿æŒæ˜¾ç¤ºã€‚** 自动显示实例,队列中æ¯ä¸ªåŠ¨ç”»å‡æ’­æ”¾ä¸€æ¬¡ï¼ˆä¸å¾ªçŽ¯ï¼‰ï¼Œä¾æ¬¡æ’­æ”¾ã€‚ + +```javascript +// 播放 attack → die,全部播完åŽè‡ªåЍéšè—(默认) +gameabc_face.spineMgr.playQueue("hero", ["attack", "die"]); + +// 播放 intro → idle,全部播完åŽä¿æŒæ˜¾ç¤º +gameabc_face.spineMgr.playQueue("hero", ["intro", "idle"], false); +``` + +| 傿•° | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `id` | string | - | 实例标识 | +| `animList` | string[] | - | 动画å称数组,按顺åºä¾æ¬¡æ’­æ”¾ | +| `hideOnComplete` | boolean | true | `true` = 队列全部播完åŽè‡ªåЍéšè—ï¼›`false` = ä¿æŒæ˜¾ç¤º | + +--- + +### 4.14 remove(id) + +**é”€æ¯æŒ‡å®š Spine 实例,释放内存。** + +```javascript +gameabc_face.spineMgr.remove("hero"); +``` + +--- + +### 4.15 removeAll() + +**é”€æ¯æ‰€æœ‰ Spine 实例。** + +```javascript +gameabc_face.spineMgr.removeAll(); +``` + +### 4.16 spine_onComplete(spineId, animName, trackIndex) *(事件回调)* + +**动画完æˆå›žè°ƒã€‚æ¯æ¬¡åŠ¨ç”»æ’­æ”¾ä¸€è½®ç»“æŸæ—¶è§¦å‘。** 在 `js/Spine_Event.js` 中定义。 + +```javascript +// 在 Spine_Event.js 中定义 +gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { + // ç¤ºä¾‹ï¼šæ”»å‡»æ’­å®ŒåŽæ¢å¤ idle + if (animName === "attack") { + gameabc_face.spineMgr.setAnimation(spineId, "idle", true); + } +}; +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `spineId` | string | å®žä¾‹æ ‡è¯†ï¼ˆå³ load / autoLoad æ—¶çš„ id) | +| `animName` | string | 刚完æˆçš„动画åç§° | +| `trackIndex` | number | 轨é“å·ï¼ˆé€šå¸¸ä¸º 0) | + +> **注æ„**ï¼šå¾ªçŽ¯åŠ¨ç”»æ¯æ’­å®Œä¸€è½®ä¹Ÿä¼šè§¦å‘。`playOnce` / `playQueue` 的自动éšè—在此回调**之å‰**执行, +> 因此回调中å¯ä»¥æ£€æŸ¥ `visible` çŠ¶æ€æˆ–釿–°æ˜¾ç¤ºå®žä¾‹ã€‚ + +--- + +### 4.17 spine_onEvent(spineId, eventName, intValue, floatValue, stringValue) *(事件回调)* + +**自定义事件回调。当动画播放到 Spine 编辑器中定义的 Event 关键帧时触å‘。** 在 `js/Spine_Event.js` 中定义。 + +```javascript +// 在 Spine_Event.js 中定义 +gameabc_face.spine_onEvent = function(spineId, eventName, intValue, floatValue, stringValue) { + if (eventName === "footstep") { + // 播放脚步声 + } + if (eventName === "hit") { + // 产生伤害判定 + } +}; +``` + +| 傿•° | 类型 | 说明 | +|------|------|------| +| `spineId` | string | 实例标识 | +| `eventName` | string | Spine 编辑器中定义的事件å | +| `intValue` | number | äº‹ä»¶çš„æ•´æ•°å‚æ•° | +| `floatValue` | number | äº‹ä»¶çš„æµ®ç‚¹å‚æ•° | +| `stringValue` | string | äº‹ä»¶çš„å­—ç¬¦ä¸²å‚æ•° | + +> 事件需è¦åœ¨ Spine 编辑器的时间线中预先添加 Event Key,导出 JSON åŽè¿è¡Œæ—¶è‡ªåŠ¨è§£æžã€‚ + +--- + +## 5. 事件系统(详细说明) + +Spine 动画在è¿è¡Œæ—¶ä¼šè§¦å‘两类事件,回调定义在 `js/Spine_Event.js` 中。 +API ç­¾åè§ [4.16](#416-spine_oncompletespineid-animname-trackindex--事件回调) å’Œ [4.17](#417-spine_oneventspineid-eventname-intvalue-floatvalue-stringvalue--事件回调)。 + +### 5.1 动画完æˆäº‹ä»¶ spine_onComplete + +**æ¯æ¬¡åŠ¨ç”»å¾ªçŽ¯æ’­æ”¾ä¸€è½®ç»“æŸæ—¶è§¦å‘。** + +```javascript +// 在 Spine_Event.js 中 +gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { + // spineId : load 时的唯一标识, 如 "hero" + // animName : 完æˆçš„动画å, 如 "attack" + // trackIndex : 轨é“å· (通常为 0) + + // 示例:éžå¾ªçŽ¯æ”»å‡»åŠ¨ç”»æ’­å®ŒåŽæ¢å¤ idle + if (animName === "attack") { + gameabc_face.spineMgr.setAnimation(spineId, "idle", true); + } +}; +``` + +### 5.2 自定义事件 spine_onEvent + +**当动画播放到 Spine 编辑器中定义的 Event 关键帧时触å‘。** + +```javascript +// 在 Spine_Event.js 中 +gameabc_face.spine_onEvent = function(spineId, eventName, intValue, floatValue, stringValue) { + // spineId : 唯一标识 + // eventName : Spine 编辑器中定义的事件å + // intValue : æ•´æ•°å‚æ•° + // floatValue : æµ®ç‚¹å‚æ•° + // stringValue : å­—ç¬¦ä¸²å‚æ•° + + if (eventName === "footstep") { + // 播放脚步声 + } + if (eventName === "hit") { + // 产生伤害判定 + } +}; +``` + +### 如何在 Spine 编辑器中添加事件 + +1. 打开 Spine 编辑器,选中动画 +2. 在时间线底部点击å³é”® → **Add Event Key** +3. 在 **Tree** 颿¿ä¸­åˆ›å»ºå¹¶å‘½å事件(如 `hit`ã€`footstep`) +4. å¯ä¸ºäº‹ä»¶è®¾ç½® int / float / string 傿•° +5. 导出 JSON åŽï¼Œè¿è¡Œæ—¶ä¼šè‡ªåŠ¨è§£æžå¹¶è§¦å‘回调 + +--- + +## 6. 常è§ç”¨æ³•示例 + +### 6.1 加载多个角色 + +```javascript +// 在 gamestart æˆ–ä»»æ„æ—¶æœºï¼Œç›´æŽ¥è®¾ç½®ä½ç½®å¹¶æ’­æ”¾ï¼ˆè‡ªåŠ¨åŠ è½½ï¼‰ +gameabc_face.spineMgr.setPosition("hero", 640, 500); +gameabc_face.spineMgr.setAnimation("hero", "idle", true); + +gameabc_face.spineMgr.setPosition("npc", 300, 500); +gameabc_face.spineMgr.setAnimation("npc", "idle", true); + +gameabc_face.spineMgr.setPosition("monster", 900, 500); +gameabc_face.spineMgr.setAnimation("monster", "walk", true); +``` + +### 6.2 播放一次åŽéšè— / 队列播放 + +```javascript +// 播放一次攻击动画,完æˆåŽè‡ªåЍéšè— +gameabc_face.spineMgr.setPosition("effect", 640, 400); +gameabc_face.spineMgr.playOnce("effect", "explode"); + +// 队列播放:攻击 → 死亡,全部播完åŽè‡ªåЍéšè— +gameabc_face.spineMgr.playQueue("monster", ["hit", "die"]); + +// 队列播放:入场 → 待机,全部播完åŽä¿æŒæ˜¾ç¤º +gameabc_face.spineMgr.playQueue("hero", ["intro", "idle"], false); +``` + +### 6.3 点击切æ¢åŠ¨ç”»ï¼ˆæ”»å‡»â†’æ¢å¤ï¼‰ + +```javascript +gameabc_face.mousedown = function(gameid, spid, downx, downy) { + // 点击播放攻击(éžå¾ªçŽ¯ï¼‰ + gameabc_face.spineMgr.setAnimation("hero", "attack", false); + // 攻击完自动切回 idle + gameabc_face.spineMgr.addAnimation("hero", "idle", true, 0); +}; +``` + +### 6.4 角色移动 + 动画è”动 + +```javascript +var heroState = "idle"; + +gameabc_face.mousedown = function(gameid, spid, downx, downy) { + heroState = "run"; + gameabc_face.spineMgr.setAnimation("hero", "run", true); +}; + +gameabc_face.mouseup = function(gameid, spid_down, downx, downy, spid_up, upx, upy) { + heroState = "idle"; + gameabc_face.spineMgr.setAnimation("hero", "idle", true); +}; + +gameabc_face.mousemove = function(gameid, spid, downx, downy, movex, movey, timelong, offmovex, offmovey) { + // 通过拖拽移动角色 + var mgr = gameabc_face.spineMgr; + var entry = mgr._entries["hero"]; + if (entry) { + mgr.setPosition("hero", entry.x + offmovex, entry.y + offmovey); + // æ ¹æ®ç§»åŠ¨æ–¹å‘翻转 + mgr.setFlip("hero", offmovex < 0, false); + } +}; +``` + +### 6.5 多轨é“å åŠ ï¼ˆèµ°è·¯ + 射击) + +Spine 支æŒå¤šè½¨é“åŒæ—¶æ’­æ”¾åŠ¨ç”»ã€‚ä½Žè½¨é“(track 0)为基础动画,高轨é“覆盖部分骨骼: + +```javascript +// track 0: 下åŠèº«èµ°è·¯ +gameabc_face.spineMgr.setAnimation("hero", "walk", true, 0); + +// track 1: 上åŠèº«å°„击(在 Spine 编辑器中åªè®¾ç½®ä¸ŠåŠèº«éª¨éª¼çš„关键帧) +gameabc_face.spineMgr.setAnimation("hero", "shoot", false, 1); +``` + +### 6.6 动æ€åˆ‡æ¢çš®è‚¤ï¼ˆæ¢è£…系统) + +```javascript +// 查看有哪些皮肤 +var skins = gameabc_face.spineMgr.getSkins("hero"); +logmessage("å¯ç”¨çš®è‚¤: " + skins.join(", ")); + +// 切æ¢åˆ°æˆ˜å£«çš®è‚¤ +gameabc_face.spineMgr.setSkin("hero", "warrior"); + +// 切æ¢åˆ°æ³•师皮肤 +gameabc_face.spineMgr.setSkin("hero", "mage"); +``` + +### 6.7 è¿è¡Œæ—¶æŸ¥è¯¢åŠ¨ç”»åˆ—è¡¨ + +```javascript +gameabc_face.spine_onComplete = function(spineId, animName, trackIndex) { + var anims = gameabc_face.spineMgr.getAnimations(spineId); + logmessage(spineId + " 拥有的动画: " + anims.join(", ")); +}; +``` + +--- + +## 7. 与 gameabc ç²¾çµç³»ç»Ÿé…åˆ + +### æ¸²æŸ“æ—¶åº + +``` +gameabc 引擎循环 (æ¯å¸§) + │ + ├── gamebegindraw() ↠帧开始 + ├── é历 Layer → æ¯ä¸ªç²¾çµ: + │ ├── gamemydrawbegin() + │ ├── ç²¾çµè‡ªç»˜ (图片/文字) + │ └── gamemydraw() + ├── gameenddraw() ↠用户自定义逻辑 + │ └── (自动) spineMgr.updateAndDraw(ctx) ↠★ 通过 defineProperty 自动追加 + └── å¸§ç»“æŸ +``` + +Spine 动画在 `gameenddraw` 末尾**自动渲染**(通过 `Object.defineProperty` 拦截实现, +无论开å‘è€…å¦‚ä½•é‡æ–°å®šä¹‰ `gameenddraw`,Spine 渲染都ä¸ä¼šä¸¢å¤±ï¼‰ï¼Œ +因此会**覆盖在所有 gameabc ç²¾çµä¹‹ä¸Š**。 +å¼€å‘者在 `gameenddraw` 中编写的自定义逻辑会先执行,Spine 渲染在其åŽè‡ªåŠ¨æ‰§è¡Œã€‚ + +### å¦‚æžœéœ€è¦ Spine 在精çµä¹‹ä¸‹æ¸²æŸ“ + +å¯ä»¥é€šè¿‡æ‰‹åŠ¨æŽ§åˆ¶æ¸²æŸ“æ—¶æœºæ¥å®žçŽ°ã€‚åœ¨ `gamebegindraw` 中手动调用渲染,并ç¦ç”¨è‡ªåŠ¨æ¸²æŸ“ï¼š + +```javascript +// æ–¹å¼ï¼šåœ¨ gamebegindraw 中手动渲染 +gameabc_face.gamebegindraw = function(gameid, spid, times, timelong) { + var ctx = gameabc_face.dc; + if (ctx) { + gameabc_face.spineMgr.updateAndDraw(ctx); + } + // 标记自动渲染跳过(因为已在此手动渲染) + gameabc_face.spineMgr._rendered = true; +}; +``` + +> 注æ„:当å‰è‡ªåŠ¨æŒ‚é’©åœ¨ gameenddraw 末尾,如需精细控制层级, +> å¯å°† SpineMgr._inited 临时置 false 跳过自动渲染,手动选择渲染时机。 + +### 让 Spine è·ŸéšæŸä¸ªç²¾çµç§»åЍ + +```javascript +gameabc_face.gamemydraw = function(gameid, spid, times, timelong) { + // 让 Spine 角色跟éšç²¾çµ 1 çš„ä½ç½® + if (spid === 1) { + var sx = get_self(1, 18, 0, 0, 0); // 获å–ç²¾çµ 1 çš„ X + var sy = get_self(1, 19, 0, 0, 0); // 获å–ç²¾çµ 1 çš„ Y + gameabc_face.spineMgr.setPosition("hero", sx, sy); + } +}; +``` + +--- + +## 8. 性能优化建议 + +### 8.1 å›¾é›†çº¹ç† + +- 纹ç†å°ºå¯¸å»ºè®®ä¸è¶…过 **2048×2048** +- 导出时勾选 **Power of two** ç¡®ä¿å°ºå¯¸ä¸º 2 的幂 +- ä¸è¦å‹¾é€‰ **Premultiply alpha**(Canvas 2D ä¸éœ€è¦é¢„乘 Alpha) + +### 8.2 æŽ§åˆ¶å®žä¾‹æ•°é‡ + +- Canvas 2D 渲染性能有é™ï¼Œå»ºè®®åŒå± Spine 实例ä¸è¶…过 **5-8 个** +- ä¸å¯è§çš„实例调用 `setVisible(id, false)`,跳过渲染和更新 +- ä¸å†éœ€è¦çš„实例调用 `remove(id)` 释放内存 + +### 8.3 å‡å°‘éª¨éª¼å¤æ‚度 + +- 骨骼数é‡å»ºè®®æŽ§åˆ¶åœ¨ **50 个**以内 +- å‡å°‘网格å˜å½¢ï¼ˆMesh Deform),对 Canvas 2D å½±å“较大 +- 使用è£å‰ªï¼ˆClipping)时性能开销大,谨慎使用 + +### 8.4 åŠ¨ç”»æ··åˆæ—¶é•¿ + +`mixDuration` 越长,过渡越平滑,但在切æ¢çž¬é—´éœ€è¦åŒæ—¶è®¡ç®—两个动画。 +建议设为 **0.1 ~ 0.3 ç§’**。 + +--- + +## 9. 常è§é—®é¢˜æŽ’查 + +### Q1: ç”»é¢ä¸Šçœ‹ä¸åˆ° Spine 动画 + +**检查清å•:** + +1. **æ–‡ä»¶è·¯å¾„æ˜¯å¦æ­£ç¡®ï¼Ÿ** + - 确认 `assets/spine/` 目录下有 `.json`ã€`.atlas`ã€`.png` + - 文件å大å°å†™å¿…须一致(Linux/Mac æœåŠ¡å™¨åŒºåˆ†å¤§å°å†™ï¼‰ + +2. **是å¦é€šè¿‡ HTTP 访问?** + - `file://` å议无法加载跨域资æºï¼Œå¿…须使用 HTTP æœåС噍 + +3. **打开æµè§ˆå™¨æŽ§åˆ¶å°ï¼ˆF12)看报错** + - 404 错误:文件路径有误 + - JSON è§£æžé”™è¯¯ï¼š`.json` 文件格å¼å¼‚常 + - `spine is not defined`:`spine-canvas.js` 未正确加载 + +4. **åæ ‡æ˜¯å¦åœ¨å¯è§èŒƒå›´å†…?** + - 项目设计尺寸为 1280×720,检查 `x` å’Œ `y` 是å¦åœ¨æ­¤èŒƒå›´ + +5. **logmessage è¾“å‡ºæ˜¯å¦æœ‰ "[SpineMgr] xxx 构建完æˆ"?** + - 有 → 加载æˆåŠŸï¼Œæ£€æŸ¥åæ ‡å’Œç¼©æ”¾ + - 有 "构建失败" → æŸ¥çœ‹å…·ä½“é”™è¯¯ä¿¡æ¯ + - 没有 → 资æºè¿˜åœ¨åŠ è½½ä¸­æˆ–è·¯å¾„é”™è¯¯ + +### Q2: 动画显示ä½ç½®ä¸å¯¹ + +- Spine 编辑器中设置骨骼原点的ä½ç½®ä¼šå½±å“è¿è¡Œæ—¶çš„锚点 +- 调整 `setPosition` çš„åæ ‡ï¼Œæˆ–在 Spine 编辑器中修改根骨骼ä½ç½® +- æ³¨æ„ Spine çš„ Y 轴与 Canvas Y è½´æ–¹å‘å¯èƒ½ä¸åŒ + +### Q3: 动画速度太快或太慢 + +- 检查 `gameabc_Project` 中的 `fps` 设置(默认 30) +- SpineMgr 内部是用 `Date.now()` 计算真实时间差的,ä¸ä¾èµ–帧率 +- 如果需è¦å€é€Ÿæ’­æ”¾ï¼Œä¿®æ”¹ `state.timeScale`: + ```javascript + var entry = gameabc_face.spineMgr._entries["hero"]; + entry.state.timeScale = 2.0; // 2 å€é€Ÿ + ``` + +### Q4: 切æ¢åŠ¨ç”»æ—¶æœ‰è·³å¸§ + +- 增大 `mixDuration`(加载时的 option 或修改 `stateData.defaultMix`) +- 使用 `addAnimation` æŽ’é˜Ÿè€Œä¸æ˜¯ç›´æŽ¥ `setAnimation` 打断 + +### Q5: 多个 Spine 实例é‡å æ—¶é—ªçƒ + +- 确认没有åŒä¸€ä¸ª id 加载两次 +- 检查 `ctx.save()` / `ctx.restore()` 是å¦é…对(SpineMgr 内部已处ç†ï¼‰ + +### Q6: spine-canvas.js 版本与 Spine 编辑器版本ä¸åŒ¹é… + +- **spine-canvas.js 4.2** 需æ­é… **Spine 编辑器 4.2.x** å¯¼å‡ºçš„æ•°æ® +- 如果使用 Spine 4.1 编辑器,请下载对应版本的è¿è¡Œæ—¶ï¼š + ``` + https://unpkg.com/@esotericsoftware/spine-canvas@4.1/dist/iife/spine-canvas.js + ``` + +--- + +## 10. é™„å½•ï¼šæ–‡ä»¶åŠ è½½é¡ºåº + +`index.html` 中的 script 标签加载顺åºè‡³å…³é‡è¦ï¼š + +``` +1. spine-canvas.js ↠先加载 Spine è¿è¡Œæ—¶ (定义 window.spine) +2. gameabc.min.js ↠å†åŠ è½½æ¸¸æˆå¼•擎 +3. SpineMgr.js ↠Spine 管ç†å™¨ + defineProperty 自动挂钩渲染 +4. gamemain.js ↠游æˆä¸»é€»è¾‘(ä¸éœ€ä¿®æ”¹ï¼Œç›´æŽ¥è°ƒç”¨ API å³å¯ï¼‰ +5. Spine_Event.js ↠Spine 事件回调 (ä¾èµ– gameabc_face) +6. Project1_Event.js ↠精çµäº‹ä»¶ +7. gameabc_data.min.js ↠项目é…ç½®æ•°æ® (引擎åˆå§‹åŒ–) +``` + +> **ä¸èƒ½è°ƒæ¢é¡ºåº**,`SpineMgr.js` 必须在 `gamemain.js` 之å‰åŠ è½½ï¼Œ +> å¦åˆ™ä¼šå‡ºçް `spine is not defined` 或 `gameabc_face.spineMgr is undefined` 的错误。 + +--- + +## 附录:完整最å°ç¤ºä¾‹ gamemain.js + +`gamemain.js` **ä¸éœ€è¦ä»»ä½•修改**ï¼Œä¿æŒåŽŸæ ·å³å¯ã€‚在任æ„事件回调中直接调用 `gameabc_face.spineMgr` çš„ API: + +```javascript +// gamemain.js —— 无需修改框架,åªéœ€åœ¨å›žè°ƒä¸­è°ƒç”¨ API + +gameabc_face.gamestart = function(gameid) { + // 直接设置ä½ç½®å¹¶æ’­æ”¾åŠ¨ç”»ï¼ˆè‡ªåŠ¨åŠ è½½ï¼Œæ— éœ€ load) + gameabc_face.spineMgr.setPosition("mj_gangshangkaihua", 640, 500); + gameabc_face.spineMgr.setAnimation("mj_gangshangkaihua", "animation", true); +}; + +// gameenddraw ä¿æŒåŽŸæ ·ï¼ŒSpine 渲染由 SpineMgr.js è‡ªåŠ¨å¤„ç† +gameabc_face.gameenddraw = function(gameid, spid, times, timelong) { + // 这里写其他自定义绘制逻辑,或留空 +}; + +gameabc_face.mousedown = function(gameid, spid, downx, downy) { + // 点击播放动画 + gameabc_face.spineMgr.setAnimation("mj_gangshangkaihua", "animation", false); +}; +``` + +> **é‡è¦**:`SpineMgr.js` 是独立文件,通过 `Object.defineProperty` 自动拦截 `gameenddraw`, +> 无论 `gamemain.js` 如何定义 `gameenddraw`,Spine æ¸²æŸ“éƒ½ä¼šè‡ªåŠ¨è¿½åŠ åœ¨å…¶åŽæ‰§è¡Œã€‚ +> `gamemain.js` 完全ä¸éœ€è¦ä¿®æ”¹ã€‚ + +--- + +> **å‚考链接** +> - Spine 官方è¿è¡Œæ—¶æ–‡æ¡£: https://zh.esotericsoftware.com/spine-api-reference +> - Spine Player 在线演示: https://jp.esotericsoftware.com/spine-player +> - spine-canvas npm 包: https://www.npmjs.com/package/@esotericsoftware/spine-canvas diff --git a/codes/games/client/Projects/Spine/generated/spine_assets.js b/codes/games/client/Projects/Spine/generated/spine_assets.js new file mode 100644 index 0000000..daf5863 --- /dev/null +++ b/codes/games/client/Projects/Spine/generated/spine_assets.js @@ -0,0 +1,6 @@ +// Spine resource list (auto-generated, do not edit manually) +gameabc_face.spineAssets = [ + "chipengganghu", + "gamestart", + "Zaijiezaili" +]; diff --git a/codes/games/client/Projects/Spine/generated/spine_data.js b/codes/games/client/Projects/Spine/generated/spine_data.js new file mode 100644 index 0000000..c6d5474 --- /dev/null +++ b/codes/games/client/Projects/Spine/generated/spine_data.js @@ -0,0 +1,9 @@ +// Spine text data (auto-generated, do not edit manually) +// Embeds .json/.atlas content into JS to bypass file:// XHR CORS +gameabc_face.spineTextData = {}; +gameabc_face.spineTextData['chipengganghu.json'] = '{"skeleton":{"hash":"r/nxLpWd57U","spine":"4.2.43","x":-68.5,"y":-72,"width":137,"height":144,"images":"./0/","audio":""},"bones":[{"name":"root"},{"name":"bone","parent":"root"},{"name":"pai","parent":"bone"},{"name":"piaodong","parent":"pai"},{"name":"1","parent":"piaodong","length":23.81,"rotation":-139.82,"x":52.63,"y":63.93,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"2","parent":"piaodong","length":23.81,"rotation":-139.82,"x":88.75,"y":1.41,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"3","parent":"piaodong","length":23.81,"rotation":-139.82,"x":-2.23,"y":86.89,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"4","parent":"piaodong","length":23.81,"rotation":-139.82,"x":-1.54,"y":59.45,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"5","parent":"piaodong","length":23.81,"rotation":-139.82,"x":80.95,"y":46.13,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"6","parent":"piaodong","length":23.81,"rotation":-139.82,"x":38.7,"y":70.09,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"7","parent":"piaodong","length":23.81,"rotation":-139.82,"x":79.23,"y":30.89,"scaleX":0.869,"scaleY":0.869,"color":"0c009cff"},{"name":"bone2","parent":"1","rotation":-31.82,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"bone3","parent":"2","rotation":-105.69,"x":11.76,"y":0.18},{"name":"bone4","parent":"3","rotation":-101.42,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"bone5","parent":"4","rotation":115.97,"x":11.76,"y":0.18},{"name":"bone6","parent":"5","rotation":-69.6,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"bone7","parent":"6","rotation":115.97,"x":11.76,"y":0.18},{"name":"bone8","parent":"7","rotation":-170.14,"x":11.76,"y":0.18,"scaleX":0.7,"scaleY":0.7},{"name":"di","parent":"pai"},{"name":"bone9","parent":"di","y":4},{"name":"di2","parent":"di","y":3},{"name":"qian1","parent":"di2","color":"fff700ff"},{"name":"qian4","parent":"di2","color":"fff700ff"},{"name":"qian5","parent":"di2","color":"fff700ff"},{"name":"zhuan","parent":"di"},{"name":"zi","parent":"pai"}],"slots":[{"name":"chi4","bone":"di","attachment":"组 13"},{"name":"saoguang_00000","bone":"bone9","blend":"additive"},{"name":"chi1","bone":"zi"},{"name":"chi2","bone":"bone2","blend":"additive"},{"name":"chi3","bone":"bone3","blend":"additive"},{"name":"chi5","bone":"bone4","blend":"additive"},{"name":"chi6","bone":"bone5","blend":"additive"},{"name":"chi7","bone":"bone6","blend":"additive"},{"name":"chi8","bone":"bone7","blend":"additive"},{"name":"chi9","bone":"bone8","blend":"additive"},{"name":"quan-002","bone":"qian4","blend":"additive"},{"name":"quan-2","bone":"qian5","blend":"additive"},{"name":"Dda_Jt03","bone":"qian1","blend":"additive"},{"name":"banyuanguangquan (4)","bone":"zhuan","blend":"additive"},{"name":"banyuanguangquan (4)2","bone":"zhuan","blend":"additive"}],"skins":[{"name":"default","attachments":{"banyuanguangquan (4)":{"banyuanguangquan (4)":{"width":99,"height":99}},"banyuanguangquan (4)2":{"banyuanguangquan (4)":{"rotation":180,"width":99,"height":99}},"chi1":{"chi1":{"x":-2,"y":4,"width":108,"height":100},"gang1":{"x":1,"y":4,"width":108,"height":98},"guo1":{"x":1.99,"y":3,"width":85,"height":77},"hu7":{"x":-2.99,"y":2,"width":95,"height":101},"peng1":{"x":-0.99,"y":7,"width":113,"height":93},"åƒ":{"width":108,"height":107},"å¬":{"width":94,"height":97},"æ ":{"width":108,"height":108},"碰":{"width":116,"height":99},"过":{"width":90,"height":82}},"chi2":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi3":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi4":{"chi4":{"width":134,"height":134},"gang2":{"width":134,"height":134},"guo2":{"width":112,"height":112},"hu8":{"width":134,"height":135},"图层 3":{"width":152,"height":136},"图层 4":{"width":153,"height":154},"图层 7 æ‹·è´":{"width":146,"height":146},"图层 9":{"width":134,"height":132},"图层 10":{"width":119,"height":118},"组 12":{"width":137,"height":144},"组 13":{"width":137,"height":144}},"chi5":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi6":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi7":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi8":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"chi9":{"chi2":{"x":-0.05,"y":-1.24,"rotation":132.91,"width":24,"height":18},"hu1":{"x":0.03,"y":-0.39,"rotation":132.91,"width":23,"height":26}},"Dda_Jt03":{"Dda_Jt03":{"width":92,"height":92},"Dda_Jt05":{"width":128,"height":128}},"quan-2":{"Dda_Jt03-1":{"width":138,"height":138},"quan-002":{"width":100,"height":100}},"quan-002":{"Dda_Jt03-1":{"width":138,"height":138},"quan-002":{"width":100,"height":100}},"saoguang_00000":{"saoguang_00000":{"width":110,"height":111},"saoguang_00001":{"width":110,"height":111},"saoguang_00002":{"width":110,"height":111},"saoguang_00003":{"width":110,"height":111},"saoguang_00004":{"width":110,"height":111},"saoguang_00005":{"width":110,"height":111},"saoguang_00006":{"width":110,"height":111},"saoguang_00007":{"width":110,"height":111},"saoguang_00008":{"width":110,"height":111},"saoguang_00009":{"width":110,"height":111}}}}],"animations":{"chi1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"chi1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"chi4"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"chi2":{"slots":{"chi1":{"attachment":[{"name":"chi1"}]},"chi4":{"attachment":[{"name":"chi4"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"chi3":{"slots":{"chi1":{"attachment":[{"name":"åƒ"}]},"chi4":{"attachment":[{"name":"组 12"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"gang1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"gang1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"gang2"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"gang2":{"slots":{"chi1":{"attachment":[{"name":"æ "}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"chi2"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi4":{"attachment":[{"name":"gang2"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"chi2"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"chi2"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"chi2"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]}}},"guo1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"guo1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"guo2"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"guo2":{"slots":{"chi1":{"attachment":[{"name":"guo1"}]},"chi4":{"attachment":[{"name":"guo2"}]}}},"guo3":{"slots":{"banyuanguangquan (4)":{"attachment":[{"name":"banyuanguangquan (4)"}]},"chi1":{"attachment":[{"name":"过"}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"chi2"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi4":{"attachment":[{"name":"图层 9"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"chi2"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"chi2"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"chi2"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"chi2"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"di":{"scale":[{"x":1.2,"y":1.2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]},"zhuan":{"rotate":[{},{"time":2,"value":360}]}}},"guo4":{"slots":{"chi1":{"attachment":[{"name":"过"}]},"chi4":{"attachment":[{"name":"图层 9"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"guo5":{"slots":{"chi1":{"attachment":[{"name":"过"}]},"chi4":{"attachment":[{"name":"图层 9"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"},{"time":0.0333}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,1.583,1,0.501,1,1.583,1,0.5,1,1.583,1,0.5,0,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"scale":[{"x":1.486,"y":1.486}]},"pai":{"scale":[{"time":2}]}}},"hu1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"hu7"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"hu8"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"hu2":{"slots":{"banyuanguangquan (4)":{"attachment":[{"name":"banyuanguangquan (4)"}]},"banyuanguangquan (4)2":{"attachment":[{"name":"banyuanguangquan (4)"}]},"chi1":{"attachment":[{"name":"hu7"}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"hu1"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi4":{"attachment":[{"name":"hu8"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"hu1"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"hu1"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt05"}]},"quan-2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.542,1,0.625,1,0.542,1,0.625,1,0.542,1,0.625,1,0.542,0,0.625,1]},{"time":0.6667,"color":"ffffffff","curve":"stepped"},{"time":1.1667,"color":"ffffffff","curve":[1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"saoguang_00000":{"rgba":[{"color":"ffffff00","curve":[0.117,1,0.35,1,0.117,1,0.35,0.56,0.117,1,0.35,0.58,0.117,0,0.35,0.58]},{"time":0.4667,"color":"ff909495","curve":[0.6,1,0.867,1,0.6,0.56,0.867,1,0.6,0.58,0.867,1,0.6,0.58,0.867,0]},{"time":1,"color":"ffffff00"}],"attachment":[{"time":0.0333,"name":"saoguang_00000"},{"time":0.1333,"name":"saoguang_00001"},{"time":0.2333,"name":"saoguang_00002"},{"time":0.3333,"name":"saoguang_00003"},{"time":0.4333,"name":"saoguang_00004"},{"time":0.5333,"name":"saoguang_00005"},{"time":0.6333,"name":"saoguang_00006"},{"time":0.7333,"name":"saoguang_00007"},{"time":0.8333,"name":"saoguang_00008"},{"time":0.9333,"name":"saoguang_00009"},{"time":1}]}},"bones":{"qian1":{"scale":[{"x":1.37,"y":1.37,"curve":[0.208,1.37,0.625,1.542,0.208,1.37,0.625,1.542]},{"time":0.8333,"x":1.542,"y":1.542}]},"zhuan":{"rotate":[{},{"time":0.5,"value":90},{"time":1,"value":180},{"time":1.5,"value":270},{"time":2,"value":360}],"translate":[{"y":3}],"scale":[{"x":1.212,"y":1.212}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}],"scale":[{"x":0.589,"y":0.589}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}],"scale":[{"x":1.954,"y":1.954}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"y":0.06}],"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.327,1.509,1.627,0.927,1.327,1.509,1.627]},{"time":1.8333,"x":1.627,"y":1.627}]},"qian5":{"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.237,1.509,1.307,0.927,1.237,1.509,1.307]},{"time":1.8333,"x":1.307,"y":1.307}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]}}},"peng1":{"slots":{"chi1":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"peng1"}]},"chi4":{"rgba":[{"color":"ffffff00"},{"time":0.3333,"color":"ffffffff"}],"attachment":[{"name":"chi4"}]}},"bones":{"pai":{"scale":[{"x":0.1,"y":0.1,"curve":[0,1.18,0.231,1.171,0,1.18,0.231,1.171]},{"time":1}]}}},"peng2":{"slots":{"chi1":{"attachment":[{"name":"碰"}]},"chi4":{"attachment":[{"name":"图层 7 æ‹·è´"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}},"ting":{"slots":{"banyuanguangquan (4)":{"attachment":[{"name":"banyuanguangquan (4)"}]},"banyuanguangquan (4)2":{"attachment":[{"name":"banyuanguangquan (4)"}]},"chi1":{"attachment":[{"name":"å¬"}]},"chi2":{"rgba":[{"color":"ffffffff","curve":[0.356,1,0.682,1,0.356,1,0.682,1,0.356,1,0.682,1,0.356,0.38,0.682,0]},{"time":0.9667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00","curve":[1.25,1,1.75,1,1.25,1,1.75,1,1.25,1,1.75,1,1.25,0,1.75,1]},{"time":2,"color":"ffffffff"}],"attachment":[{"name":"hu1"}]},"chi3":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi4":{"attachment":[{"name":"图层 4"}]},"chi5":{"rgba":[{"color":"ffffff00","curve":[0.25,1,0.75,1,0.25,1,0.75,1,0.25,1,0.75,1,0.25,0,0.75,1]},{"time":1,"color":"ffffffff","curve":[1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,1,1.242,1,1.725,0]},{"time":1.9667,"color":"ffffff00"}],"attachment":[{"name":"hu1"}]},"chi6":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"chi7":{"rgba":[{"color":"ffffff48","curve":[0.234,1,0.504,1,0.234,1,0.504,1,0.234,1,0.504,1,0.234,0.57,0.504,1]},{"time":0.6667,"color":"ffffffff","curve":[0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,1,0.908,1,1.392,0]},{"time":1.6333,"color":"ffffff00","curve":"stepped"},{"time":1.6667,"color":"ffffff00","curve":[1.755,1,1.872,1,1.755,1,1.872,1,1.755,1,1.872,1,1.755,0,1.872,0.12]},{"time":2,"color":"ffffff48"}],"attachment":[{"name":"hu1"}]},"chi8":{"rgba":[{"color":"ffffff79","curve":[0.175,1,0.349,1,0.175,1,0.349,1,0.175,1,0.349,1,0.175,0.24,0.349,0]},{"time":0.4667,"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00"},{"time":1.5,"color":"ffffffff","curve":[1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,1,1.624,1,1.813,0.74]},{"time":2,"color":"ffffff79"}],"attachment":[{"name":"hu1"}]},"chi9":{"rgba":[{"color":"ffffff7f","curve":[0.188,1,0.375,1,0.188,1,0.375,1,0.188,1,0.375,1,0.188,0.75,0.375,1]},{"time":0.5,"color":"ffffffff","curve":[0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,1,0.742,1,1.225,0]},{"time":1.4667,"color":"ffffff00","curve":"stepped"},{"time":1.5,"color":"ffffff00","curve":[1.625,1,1.813,1,1.625,1,1.813,1,1.625,1,1.813,1,1.625,0,1.813,0.25]},{"time":2,"color":"ffffff7f"}],"attachment":[{"name":"hu1"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt05"}]},"quan-2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.542,1,0.625,1,0.542,1,0.625,1,0.542,1,0.625,1,0.542,0,0.625,1]},{"time":0.6667,"color":"ffffffff","curve":"stepped"},{"time":1.1667,"color":"ffffffff","curve":[1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,1,1.333,1,1.667,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03-1"}]},"saoguang_00000":{"rgba":[{"color":"ffffff00","curve":[0.117,1,0.35,1,0.117,1,0.35,0.56,0.117,1,0.35,0.58,0.117,0,0.35,0.58]},{"time":0.4667,"color":"ff909495","curve":[0.6,1,0.867,1,0.6,0.56,0.867,1,0.6,0.58,0.867,1,0.6,0.58,0.867,0]},{"time":1,"color":"ffffff00"}],"attachment":[{"time":0.0333,"name":"saoguang_00000"},{"time":0.1333,"name":"saoguang_00001"},{"time":0.2333,"name":"saoguang_00002"},{"time":0.3333,"name":"saoguang_00003"},{"time":0.4333,"name":"saoguang_00004"},{"time":0.5333,"name":"saoguang_00005"},{"time":0.6333,"name":"saoguang_00006"},{"time":0.7333,"name":"saoguang_00007"},{"time":0.8333,"name":"saoguang_00008"},{"time":0.9333,"name":"saoguang_00009"},{"time":1}]}},"bones":{"qian1":{"scale":[{"x":1.37,"y":1.37,"curve":[0.208,1.37,0.625,1.542,0.208,1.37,0.625,1.542]},{"time":0.8333,"x":1.542,"y":1.542}]},"zhuan":{"rotate":[{},{"time":0.5,"value":90},{"time":1,"value":180},{"time":1.5,"value":270},{"time":2,"value":360}],"translate":[{"y":3}],"scale":[{"x":1.212,"y":1.212}]},"bone2":{"rotate":[{"value":93.82},{"time":0.9667,"value":170.91,"curve":[0.975,170.91,0.988,66.65]},{"time":1},{"time":2,"value":93.82}]},"bone3":{"rotate":[{"curve":[0.492,0,1.475,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone4":{"rotate":[{"curve":[0.25,0,0.75,87.37]},{"time":1,"value":87.37,"curve":[1.242,87.37,1.725,170.91]},{"time":1.9667,"value":170.91,"curve":[1.975,170.91,1.992,0]},{"time":2}]},"bone5":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}],"scale":[{"x":0.589,"y":0.589}]},"bone6":{"rotate":[{"value":16.87,"curve":[0.508,55.38,1.235,170.91]},{"time":1.6333,"value":170.91,"curve":[1.642,170.91,1.658,0]},{"time":1.6667},{"time":2,"value":16.87}],"scale":[{"x":1.954,"y":1.954}]},"bone7":{"rotate":[{"value":141.75,"curve":[0.176,159.25,0.337,170.91]},{"time":0.4667,"value":170.91,"curve":[0.475,170.91,0.492,0]},{"time":0.5},{"time":2,"value":141.75}]},"bone8":{"rotate":[{"value":32.31,"curve":[0.49,78.05,1.11,170.91]},{"time":1.4667,"value":170.91,"curve":[1.475,170.91,1.492,0]},{"time":1.5},{"time":2,"value":32.31}]},"qian4":{"translate":[{"y":0.06}],"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.327,1.509,1.627,0.927,1.327,1.509,1.627]},{"time":1.8333,"x":1.627,"y":1.627}]},"qian5":{"scale":[{"x":1.21,"y":1.21,"curve":"stepped"},{"time":0.5,"x":1.21,"y":1.21,"curve":[0.927,1.237,1.509,1.307,0.927,1.237,1.509,1.307]},{"time":1.8333,"x":1.307,"y":1.307}]},"2":{"translate":[{"curve":[0.492,0,1.475,-70.67,0.492,0,1.475,-59.66]},{"time":1.9667,"x":-70.67,"y":-59.66,"curve":[1.975,-70.67,1.992,0,1.975,-59.66,1.992,0]},{"time":2}]},"4":{"translate":[{"x":-2.47,"y":-2.09,"curve":[0.49,-19.97,1.11,-55.5,0.49,-16.86,1.11,-46.85]},{"time":1.4667,"x":-55.5,"y":-46.85,"curve":[1.475,-55.5,1.492,9.88,1.475,-46.85,1.492,8.34]},{"time":1.5,"x":9.88,"y":8.34,"curve":[1.625,9.88,1.875,-2.47,1.625,8.34,1.875,-2.09]},{"time":2,"x":-2.47,"y":-2.09}]},"6":{"translate":[{"x":-85.52,"y":-72.2,"curve":[0.176,-96.08,0.337,-103.12,0.176,-81.11,0.337,-87.05]},{"time":0.4667,"x":-103.12,"y":-87.05,"curve":[0.475,-103.12,0.492,0,0.475,-87.05,0.492,0]},{"time":0.5,"curve":[0.863,0,1.504,-57.3,0.863,0,1.504,-48.37]},{"time":2,"x":-85.52,"y":-72.2}]},"5":{"translate":[{"x":-10.18,"y":-8.59,"curve":[0.508,-33.42,1.235,-103.12,0.508,-28.21,1.235,-87.05]},{"time":1.6333,"x":-103.12,"y":-87.05,"curve":[1.642,-103.12,1.658,0,1.642,-87.05,1.658,0]},{"time":1.6667,"curve":[1.763,0,1.876,-3.77,1.763,0,1.876,-3.18]},{"time":2,"x":-10.18,"y":-8.59}]},"1":{"translate":[{"x":-56.61,"y":-47.79},{"time":0.9667,"x":-103.12,"y":-87.05,"curve":[0.979,-39.19,0.99,0,0.979,-33.08,0.99,0]},{"time":1},{"time":2,"x":-56.61,"y":-47.79}]},"7":{"translate":[{"x":-19.49,"y":-16.46,"curve":[0.49,-47.09,1.11,-103.12,0.49,-39.75,1.11,-87.05]},{"time":1.4667,"x":-103.12,"y":-87.05,"curve":[1.475,-103.12,1.492,0,1.475,-87.05,1.492,0]},{"time":1.5},{"time":2,"x":-19.49,"y":-16.46}]},"3":{"translate":[{"curve":[0.492,0,1.475,-63.3,0.492,0,1.475,-53.44]},{"time":1.9667,"x":-63.3,"y":-53.44,"curve":[1.975,-63.3,1.992,0,1.975,-53.44,1.992,0]},{"time":2}]},"pai":{"scale":[{"x":1.6,"y":1.6}]}}},"ting2":{"slots":{"chi1":{"attachment":[{"name":"å¬"}]},"Dda_Jt03":{"rgba":[{"color":"ffffff00","curve":[0.042,1,0.125,1,0.042,1,0.125,1,0.042,1,0.125,1,0.042,0,0.125,1]},{"time":0.1667,"color":"ffffffff","curve":[0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,1,0.333,1,0.667,0]},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"name":"Dda_Jt03"}]},"quan-002":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.5,"color":"ffffff00","curve":[0.583,1,0.75,1,0.583,1,0.75,1,0.583,1,0.75,1,0.583,0,0.75,1]},{"time":0.8333,"color":"ffffffff","curve":[1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,1,1.083,1,1.583,0]},{"time":1.8333,"color":"ffffff00"}],"attachment":[{"name":"quan-002"}]}},"bones":{"qian1":{"scale":[{"curve":[0.208,1,0.625,1.229,0.208,1,0.625,1.229]},{"time":0.8333,"x":1.229,"y":1.229}]},"qian4":{"translate":[{"x":-0.96,"y":1.98}],"scale":[{"x":1.486,"y":1.486,"curve":"stepped"},{"time":0.5,"x":1.486,"y":1.486,"curve":[0.833,1.486,1.5,1.75,0.833,1.486,1.5,1.75]},{"time":1.8333,"x":1.75,"y":1.75}]},"pai":{"scale":[{"curve":[0.083,1,0.25,1.1,0.083,1,0.25,1.1]},{"time":0.3333,"x":1.1,"y":1.1,"curve":[0.75,1.1,1.583,1,0.75,1.1,1.583,1]},{"time":2}]}}}}}'; +gameabc_face.spineTextData['chipengganghu.atlas'] = 'chipengganghu.png\nsize:2048,512\nfilter:Linear,Linear\nDda_Jt03\nbounds:1947,288,92,92\nDda_Jt03-1\nbounds:311,343,138,138\nDda_Jt05\nbounds:1134,353,128,128\nbanyuanguangquan (4)\nbounds:1947,382,99,99\nchi1\nbounds:609,244,108,100\nchi2\nbounds:572,22,24,18\nchi4\nbounds:726,347,134,134\ngang1\nbounds:609,144,108,98\ngang2\nbounds:862,347,134,134\nguo1\nbounds:1356,284,85,77\nguo2\nbounds:1385,369,112,112\nhu1\nbounds:2,5,23,26\nhu7\nbounds:475,8,95,101\nhu8\nbounds:590,346,134,135\npeng1\nbounds:150,149,113,93\nquan-002\nbounds:572,42,100,100\nsaoguang_00000\nbounds:1499,370,110,111\nsaoguang_00001\nbounds:1611,370,110,111\nsaoguang_00002\nbounds:1723,370,110,111\nsaoguang_00003\nbounds:1835,370,110,111\nsaoguang_00004\nbounds:275,230,110,111\nsaoguang_00005\nbounds:141,36,110,111\nsaoguang_00006\nbounds:265,117,110,111\nsaoguang_00007\nbounds:253,4,110,111\nsaoguang_00008\nbounds:387,224,110,111\nsaoguang_00009\nbounds:377,111,110,111\nåƒ\nbounds:365,2,108,107\nå¬\nbounds:674,45,94,97\n图层 10\nbounds:1264,363,119,118\n图层 3\nbounds:157,345,152,136\n图层 4\nbounds:2,327,153,154\n图层 7 æ‹·è´\nbounds:2,179,146,146\n图层 9\nbounds:998,349,134,132\næ \nbounds:499,227,108,108\n碰\nbounds:157,244,116,99\n组 12\nbounds:2,33,137,144\n组 13\nbounds:451,337,137,144\n过\nbounds:1264,279,90,82\n'; +gameabc_face.spineTextData['gamestart.json'] = '{"skeleton":{"hash":"Cs22lzcwV3A","spine":"4.2.43","x":-862.3,"y":-188.35,"width":1724.6,"height":375.11,"images":"./0/","audio":"I:\\\\游æˆç´ ææ”¶é›†\\\\棋牌\\\\é—²æ¥æ–—地主\\\\spine\\\\UI\\\\pipei_fx"},"bones":[{"name":"root"},{"name":"loading","parent":"root"},{"name":"pipeizhong","parent":"root"},{"name":"zhong","parent":"pipeizhong","length":35.15,"rotation":88.12,"x":97.58,"y":5.54},{"name":"pi","parent":"pipeizhong","x":-86.85,"y":2.78},{"name":"pei","parent":"pipeizhong","x":0.58,"y":-3.86},{"name":"lizi","parent":"root","length":9.44,"rotation":5.19,"x":187.44,"y":25.51},{"name":"lizi2","parent":"root","length":9.44,"rotation":5.19,"x":-235.41,"y":-103.34,"scaleX":0.9,"scaleY":0.9},{"name":"lizi3","parent":"root","length":9.44,"rotation":5.19,"x":91.71,"y":-113.98,"scaleX":0.8,"scaleY":0.8},{"name":"lizi4","parent":"root","length":9.44,"rotation":5.19,"x":-202.78,"y":94.66},{"name":"lizi5","parent":"root","length":9.44,"rotation":5.19,"x":167.97,"y":36.8,"scaleX":0.5,"scaleY":0.5},{"name":"lizi6","parent":"root","length":9.44,"rotation":5.19,"x":-162.19,"y":6.78,"scaleX":0.5,"scaleY":0.5},{"name":"taoxin_zong","parent":"root"},{"name":"glow_y","parent":"root"},{"name":"fangkuai","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.8,"scaleY":0.8},{"name":"tiao_new","parent":"root"},{"name":"heitao","parent":"tiao_new"},{"name":"heitao2","parent":"tiao_new"},{"name":"lizi7","parent":"root","length":9.44,"rotation":5.19,"x":60.86,"y":77.88},{"name":"lizi8","parent":"root","length":9.44,"rotation":5.19,"x":-73.19,"y":-90.44,"scaleX":1.5,"scaleY":1.5},{"name":"glow_y2","parent":"root"},{"name":"star","parent":"root","length":17.48,"x":14.55,"y":40.7},{"name":"fangkuai2","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.4,"scaleY":0.4},{"name":"fangkuai3","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.6,"scaleY":0.6},{"name":"fangkuai4","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.7,"scaleY":0.7},{"name":"lizi9","parent":"root","length":9.44,"rotation":5.19,"x":-92.32,"y":75.72,"scaleX":1.2,"scaleY":1.2},{"name":"fangkuai5","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.6,"scaleY":0.6},{"name":"fangkuai6","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.4,"scaleY":0.4},{"name":"fangkuai7","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.5,"scaleY":0.5},{"name":"fangkuai8","parent":"root","length":28.56,"x":343.36,"y":-3.03},{"name":"fangkuai9","parent":"root","length":28.56,"x":343.36,"y":-3.03,"scaleX":0.8,"scaleY":0.8},{"name":"star4","parent":"root","length":17.48,"x":202.79,"y":-34.6},{"name":"lizi10","parent":"root","length":9.44,"rotation":5.19,"x":-179.89,"y":22.58,"scaleX":0.5,"scaleY":0.5},{"name":"glow_bian","parent":"tiao_new"},{"name":"glow_bian2","parent":"tiao_new"},{"name":"success2","parent":"root"},{"name":"dian","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"dian2","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"dian3","parent":"pipeizhong","x":203.82,"y":-32.74},{"name":"tiao","parent":"tiao_new","scaleX":1.2928}],"slots":[{"name":"BG","bone":"root"},{"name":"ck_new","bone":"root"},{"name":"new_tiao_orange","bone":"tiao","attachment":"new_tiao_orange"},{"name":"heitao_01","bone":"heitao","attachment":"heitao_01"},{"name":"heitao_2","bone":"heitao2","attachment":"heitao_02"},{"name":"glow_bian","bone":"glow_bian","blend":"additive"},{"name":"glow_bian2","bone":"glow_bian2","blend":"additive"},{"name":"loading_aixin","bone":"loading"},{"name":"pi","bone":"pi","attachment":"pi"},{"name":"pei","bone":"pei","attachment":"pei"},{"name":"zhong","bone":"zhong","attachment":"zhong"},{"name":"lizi_1","bone":"lizi","attachment":"lizi_1","blend":"additive"},{"name":"lizi_7","bone":"lizi7","attachment":"lizi_1","blend":"additive"},{"name":"lizi_9","bone":"lizi9","attachment":"lizi_1","blend":"additive"},{"name":"lizi_5","bone":"lizi5","attachment":"lizi_1","blend":"additive"},{"name":"lizi_10","bone":"lizi10","attachment":"lizi_1","blend":"additive"},{"name":"lizi_6","bone":"lizi6","attachment":"lizi_1","blend":"additive"},{"name":"lizi_3","bone":"lizi3","attachment":"lizi_1","blend":"additive"},{"name":"lizi_4","bone":"lizi4","attachment":"lizi_1","blend":"additive"},{"name":"lizi_8","bone":"lizi8","attachment":"lizi_1","blend":"additive"},{"name":"lizi_2","bone":"lizi2","attachment":"lizi_1","blend":"additive"},{"name":"lamp_glow3","bone":"glow_y","attachment":"lamp_glow","blend":"additive"},{"name":"fangkuai6","bone":"fangkuai","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai5","bone":"fangkuai5","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai4","bone":"fangkuai4","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai11","bone":"fangkuai8","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai12","bone":"fangkuai9","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai2","bone":"fangkuai2","blend":"additive"},{"name":"fangkuai7","bone":"fangkuai6","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai3","bone":"fangkuai3","blend":"additive"},{"name":"fangkuai9","bone":"fangkuai7","attachment":"fangkuai","blend":"additive"},{"name":"fangkuai_kuang6","bone":"fangkuai","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang5","bone":"fangkuai5","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang4","bone":"fangkuai4","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang11","bone":"fangkuai8","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang12","bone":"fangkuai9","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang2","bone":"fangkuai2","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang7","bone":"fangkuai6","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang3","bone":"fangkuai3","attachment":"fangkuai_kuang","blend":"screen"},{"name":"fangkuai_kuang9","bone":"fangkuai7","attachment":"fangkuai_kuang","blend":"screen"},{"name":"duijukaishi","bone":"success2","attachment":"duijukaishi"},{"name":"duijukaishi2","bone":"success2","attachment":"duijukaishi","blend":"additive"},{"name":"lamp_glow4","bone":"glow_y2","attachment":"lamp_glow","blend":"additive"},{"name":"lamp_glow5","bone":"glow_y2","attachment":"lamp_glow","blend":"additive"},{"name":"star2","bone":"star","attachment":"xingguang","blend":"additive"},{"name":"star8","bone":"star4","attachment":"xingguang","blend":"additive"},{"name":"dian","bone":"dian","attachment":"dian"},{"name":"dian2","bone":"dian2","attachment":"dian"},{"name":"dian3","bone":"dian3","attachment":"dian"},{"name":"ck_waiting","bone":"root","color":"ffffff86"}],"skins":[{"name":"default","attachments":{"dian":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"dian2":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"dian3":{"dian":{"x":0.27,"y":1.25,"width":24,"height":22}},"duijukaishi":{"duijukaishi":{"width":380,"height":92}},"duijukaishi2":{"duijukaishi":{"width":380,"height":92}},"fangkuai2":{"fangkuai":{"width":32,"height":32}},"fangkuai3":{"fangkuai":{"width":32,"height":32}},"fangkuai4":{"fangkuai":{"width":32,"height":32}},"fangkuai5":{"fangkuai":{"width":32,"height":32}},"fangkuai6":{"fangkuai":{"width":32,"height":32}},"fangkuai7":{"fangkuai":{"width":32,"height":32}},"fangkuai9":{"fangkuai":{"width":32,"height":32}},"fangkuai11":{"fangkuai":{"width":32,"height":32}},"fangkuai12":{"fangkuai":{"width":32,"height":32}},"fangkuai_kuang2":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang3":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang4":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang5":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang6":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang7":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang9":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang11":{"fangkuai_kuang":{"width":32,"height":32}},"fangkuai_kuang12":{"fangkuai_kuang":{"width":32,"height":32}},"glow_bian":{"glow_bian":{"x":422.12,"y":-69.57,"scaleX":1.2,"scaleY":0.6,"width":330,"height":9}},"glow_bian2":{"glow_bian":{"x":422.12,"y":64.41,"scaleX":1.2,"scaleY":0.6,"width":330,"height":9}},"heitao_01":{"heitao_01":{"y":-1.9,"width":236,"height":218}},"heitao_2":{"heitao_02":{"y":-2.2,"width":442,"height":219}},"lamp_glow3":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"scaleY":2.0276,"width":198,"height":185}},"lamp_glow4":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"scaleY":2.0276,"width":198,"height":185}},"lamp_glow5":{"lamp_glow":{"x":-1.8,"y":-0.8,"scaleX":2.0276,"width":198,"height":185}},"lizi_1":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_2":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_3":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_4":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_5":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_6":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_7":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_8":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_9":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"lizi_10":{"lizi_1":{"x":0.05,"y":0.07,"rotation":-5.19,"width":19,"height":19}},"loading_aixin":{"loading_aixin":{"x":103.12,"y":81.11,"width":28,"height":28}},"new_tiao_orange":{"new_tiao_orange":{"y":-2.26,"scaleX":2,"width":667,"height":217}},"pei":{"dai":{"x":5.24,"y":2.96,"width":96,"height":90},"pei":{"x":3.04,"y":2.96,"width":105,"height":92}},"pi":{"deng":{"x":-1.03,"y":-4.17,"width":101,"height":90},"pi":{"x":-1.03,"y":-4.17,"width":104,"height":89}},"star2":{"xingguang":{"x":0.34,"scaleX":0.3,"scaleY":0.3,"width":256,"height":256}},"star8":{"xingguang":{"scaleX":0.2,"scaleY":0.2,"width":256,"height":256}},"zhong":{"zhong":{"x":-6.91,"y":-0.76,"rotation":-88.12,"width":98,"height":93}}}}],"animations":{"start":{"slots":{"duijukaishi":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.1667,"color":"ffffff00"},{"time":0.3,"color":"ffffffff"}]},"duijukaishi2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3,"color":"ffffff00"},{"time":0.3333,"color":"ffffffff","curve":"stepped"},{"time":0.4,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai2":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"time":0.4667,"name":"fangkuai"},{"time":0.6}]},"fangkuai3":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}],"attachment":[{"time":0.6333,"name":"fangkuai"},{"time":0.7667}]},"fangkuai4":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}],"attachment":[{"time":0.3},{"time":0.4333,"name":"fangkuai"}]},"fangkuai5":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}],"attachment":[{"time":0.4},{"time":0.5333,"name":"fangkuai"}]},"fangkuai6":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}],"attachment":[{"time":0.5333},{"time":0.7,"name":"fangkuai"}]},"fangkuai7":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}],"attachment":[{"time":0.6}]},"fangkuai9":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}],"attachment":[{"time":0.5},{"time":0.6333,"name":"fangkuai"}]},"fangkuai11":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}],"attachment":[{"time":0.2667},{"time":0.4,"name":"fangkuai"},{"time":0.5333}]},"fangkuai12":{"rgba":[{"time":0.7333,"color":"ffffffff"},{"time":0.9667,"color":"ffffff00"}],"attachment":[{"time":0.5667},{"time":0.7,"name":"fangkuai"},{"time":0.8333}]},"fangkuai_kuang2":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}]},"fangkuai_kuang3":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}]},"fangkuai_kuang4":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai_kuang5":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}]},"fangkuai_kuang6":{"rgba":[{"time":0.5333,"color":"ffffffff"},{"time":0.7667,"color":"ffffff00"}]},"fangkuai_kuang7":{"rgba":[{"time":0.7,"color":"ffffffff"},{"time":0.8333,"color":"ffffff00"}]},"fangkuai_kuang9":{"rgba":[{"time":0.6333,"color":"ffffffff"},{"time":0.8667,"color":"ffffff00"}]},"fangkuai_kuang11":{"rgba":[{"time":0.4333,"color":"ffffffff"},{"time":0.6667,"color":"ffffff00"}]},"fangkuai_kuang12":{"rgba":[{"time":0.7333,"color":"ffffffff"},{"time":0.9667,"color":"ffffff00"}]},"glow_bian":{"rgba":[{"time":0.7667,"color":"ffffffff"},{"time":0.9,"color":"ffffff00"}],"attachment":[{"time":0.3667,"name":"glow_bian"}]},"glow_bian2":{"rgba":[{"time":0.7667,"color":"ffffffff"},{"time":0.9,"color":"ffffff00"}],"attachment":[{"time":0.3667,"name":"glow_bian"}]},"heitao_01":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.2,"color":"ffffff00","curve":[0.242,1,0.325,1,0.242,1,0.325,1,0.242,1,0.325,1,0.242,0,0.325,1]},{"time":0.3667,"color":"ffffffff"}]},"heitao_2":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3,"color":"ffffff00","curve":[0.342,1,0.425,1,0.342,1,0.425,1,0.342,1,0.425,1,0.342,0,0.425,1]},{"time":0.4667,"color":"ffffffff"}]},"lamp_glow3":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.0667,"color":"ffffffb4"},{"time":0.2,"color":"ffffff00"}],"attachment":[{}]},"lamp_glow4":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.4,"color":"ffffffb4"},{"time":0.5,"color":"ffffff00"}]},"lamp_glow5":{"rgba":[{"color":"ffffffb4","curve":"stepped"},{"time":0.4,"color":"ffffffb4"},{"time":0.5,"color":"ffffff00"}]},"lizi_7":{"rgba":[{"color":"ffdf63ff"}]},"lizi_8":{"rgba":[{"color":"ffdf63ff"}]},"lizi_9":{"rgba":[{"color":"ffdf64ff"}]},"lizi_10":{"attachment":[{}]},"new_tiao_orange":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.0667,"color":"ffffff00"},{"time":0.1333,"color":"ffffffff"}]},"pei":{"attachment":[{"name":"dai"}]},"pi":{"attachment":[{"name":"deng"}]},"star2":{"attachment":[{},{"time":0.4333,"name":"xingguang"},{"time":0.7667}]},"star8":{"attachment":[{},{"time":0.6,"name":"xingguang"}]}},"bones":{"fangkuai5":{"rotate":[{"time":0.3},{"time":0.7667,"value":-44.88}],"translate":[{"x":-504.35,"y":11.18,"curve":"stepped"},{"time":0.3,"x":-504.35,"y":11.18},{"time":0.7667,"x":-599.14,"y":28.32}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3,"x":0,"y":0},{"time":0.4},{"time":0.5333,"x":0.5,"y":0.5},{"time":0.6333},{"time":0.7667,"x":0.5,"y":0.5}]},"fangkuai6":{"rotate":[{"value":-44.88,"curve":"stepped"},{"time":0.3667,"value":-44.88},{"time":0.8333}],"translate":[{"x":-517.09,"y":-15.18,"curve":"stepped"},{"time":0.3667,"x":-517.09,"y":-15.18},{"time":0.8333,"x":-624.16,"y":-31.78}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3667,"x":0,"y":0},{"time":0.4667},{"time":0.6,"x":0.5,"y":0.5},{"time":0.7},{"time":0.8333,"x":0.5,"y":0.5}]},"fangkuai7":{"rotate":[{"value":30,"curve":"stepped"},{"time":0.4,"value":30},{"time":0.8667,"value":-90}],"translate":[{"x":-498.9,"y":4.26,"curve":"stepped"},{"time":0.4,"x":-498.9,"y":4.26},{"time":0.8667,"x":-570.14,"y":-1.69}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.4,"x":0,"y":0},{"time":0.5},{"time":0.6333,"x":0.5,"y":0.5},{"time":0.7333},{"time":0.8667,"x":0.5,"y":0.5}]},"success2":{"scale":[{"x":2.7,"y":2.2,"curve":"stepped"},{"time":0.1667,"x":2.7,"y":2.2},{"time":0.2,"x":2.51,"y":1.363},{"time":0.2333,"x":2.32,"y":1.92},{"time":0.3333,"x":0.8,"y":0.8},{"time":0.5,"x":1.06,"y":1.06},{"time":0.6667}]},"glow_y2":{"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2667,"x":0,"y":0},{"time":0.3333,"x":1.5,"y":1.2},{"time":0.5,"x":2,"y":0}]},"pei":{"translate":[{"x":-40.85}]},"star":{"rotate":[{"time":0.4333},{"time":0.7667,"value":-60}],"translate":[{"x":1.77,"y":0.73}],"scale":[{"time":0.4333},{"time":0.7667,"x":0,"y":0}]},"fangkuai3":{"rotate":[{"value":30,"curve":"stepped"},{"time":0.4,"value":30},{"time":0.8667,"value":-90}],"translate":[{"x":-148.5,"y":26.53,"curve":"stepped"},{"time":0.4,"x":-148.5,"y":26.53},{"time":0.8667,"x":-28.24,"y":27.97}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.4,"x":0,"y":0},{"time":0.5},{"time":0.6333,"x":0.5,"y":0.5},{"time":0.7333},{"time":0.8667,"x":0.5,"y":0.5}]},"fangkuai2":{"rotate":[{"value":-44.88,"curve":"stepped"},{"time":0.3667,"value":-44.88},{"time":0.8333}],"translate":[{"x":-169.32,"y":-17.49,"curve":"stepped"},{"time":0.3667,"x":-169.32,"y":-17.49},{"time":0.8333,"x":-73.95,"y":-28.46}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3667,"x":0,"y":0},{"time":0.4667},{"time":0.6,"x":0.5,"y":0.5},{"time":0.7},{"time":0.8333,"x":0.5,"y":0.5}]},"fangkuai4":{"rotate":[{"time":0.2},{"time":0.6667,"value":-44.88}],"translate":[{"x":-135.94,"y":12.14,"curve":"stepped"},{"time":0.2,"x":-135.94,"y":12.14},{"time":0.6667,"x":0.5,"y":13.65}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2,"x":0,"y":0},{"time":0.3},{"time":0.4333,"x":0.5,"y":0.5},{"time":0.5333},{"time":0.6667,"x":0.5,"y":0.5}]},"star4":{"rotate":[{"value":-60,"curve":"stepped"},{"time":0.6,"value":-60},{"time":0.9333}],"translate":[{"x":-23.34,"y":-3.43}],"scale":[{"time":0.6},{"time":0.9333,"x":0,"y":0}]},"glow_y":{"scale":[{"x":0,"y":0},{"time":0.0667,"y":1.3},{"time":0.2,"x":2,"y":0}]},"fangkuai9":{"rotate":[{"time":0.5},{"time":0.9667,"value":-44.88}],"translate":[{"x":-510.8,"y":-9.98,"curve":"stepped"},{"time":0.5,"x":-510.8,"y":-9.98},{"time":0.9667,"x":-682.69,"y":-0.2}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.5,"x":0,"y":0},{"time":0.6},{"time":0.7333,"x":0.5,"y":0.5},{"time":0.8333},{"time":0.9667,"x":0.5,"y":0.5}]},"lizi9":{"translate":[{"x":23.12,"y":-46.87,"curve":"stepped"},{"time":0.1333,"x":23.12,"y":-46.87},{"time":0.8,"x":-32.53,"y":36.07}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.1333,"x":0,"y":0},{"time":0.3},{"time":0.4667,"x":0,"y":0},{"time":0.6333},{"time":0.8,"x":0,"y":0}]},"lizi7":{"translate":[{"x":27.53,"y":-8.06},{"time":0.9667,"x":78.87,"y":21.58}],"scale":[{"x":0,"y":0},{"time":0.1333},{"time":0.3,"x":0,"y":0},{"time":0.4667},{"time":0.6333,"x":0,"y":0},{"time":0.8},{"time":0.9667,"x":0,"y":0}]},"lizi8":{"translate":[{"x":40.95,"y":12.56},{"time":0.6333,"x":4.64,"y":-14.33}],"scale":[{"x":0,"y":0},{"time":0.1333},{"time":0.3,"x":0,"y":0},{"time":0.4667},{"time":0.6333,"x":0,"y":0}]},"glow_bian":{"translate":[{"x":-72.21,"curve":"stepped"},{"time":0.3667,"x":-72.21,"curve":[0.5,-72.21,0.767,-804.76,0.5,0,0.767,0]},{"time":0.9,"x":-804.76}]},"heitao":{"scale":[{"x":3,"curve":"stepped"},{"time":0.2,"x":3,"curve":[0.242,3,0.325,0.8,0.242,1,0.325,1]},{"time":0.3667,"x":0.8,"curve":[0.408,0.8,0.492,1.4,0.408,1,0.492,1]},{"time":0.5333,"x":1.4,"curve":[0.583,1.4,0.683,1,0.583,1,0.683,1]},{"time":0.7333}]},"glow_bian2":{"translate":[{"x":-656,"curve":"stepped"},{"time":0.3667,"x":-656,"curve":[0.5,-656,0.767,97.85,0.5,0,0.767,0]},{"time":0.9,"x":97.85}]},"pi":{"translate":[{"x":-41.74}]},"fangkuai8":{"rotate":[{"time":0.2},{"time":0.6667,"value":-44.88}],"translate":[{"x":-535.78,"y":-2.96,"curve":"stepped"},{"time":0.2,"x":-535.78,"y":-2.96},{"time":0.6667,"x":-641.17,"y":-6.75}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.2,"x":0,"y":0},{"time":0.3},{"time":0.4333,"x":0.5,"y":0.5},{"time":0.5333},{"time":0.6667,"x":0.5,"y":0.5}]},"fangkuai":{"rotate":[{"time":0.3},{"time":0.7667,"value":-44.88}],"translate":[{"x":-153,"curve":"stepped"},{"time":0.3,"x":-153},{"time":0.7667,"x":-13.01}],"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.3,"x":0,"y":0},{"time":0.4},{"time":0.5333,"x":0.5,"y":0.5},{"time":0.6333},{"time":0.7667,"x":0.5,"y":0.5}]},"heitao2":{"scale":[{"x":3,"curve":"stepped"},{"time":0.3,"x":3,"curve":[0.342,3,0.425,0.8,0.342,1,0.425,1]},{"time":0.4667,"x":0.8,"curve":[0.508,0.8,0.592,1.4,0.508,1,0.592,1]},{"time":0.6333,"x":1.4,"curve":[0.683,1.4,0.783,1,0.683,1,0.783,1]},{"time":0.8333}]},"lizi":{"scale":[{"x":0,"y":0}]},"lizi2":{"translate":[{"x":-3.71,"y":-20.79}],"scale":[{"x":0,"y":0}]},"lizi3":{"translate":[{"x":39.37,"y":-38.75}],"scale":[{"x":0,"y":0}]},"lizi4":{"scale":[{"x":0,"y":0}]},"lizi5":{"translate":[{"x":27.61,"y":27.45}],"scale":[{"x":0,"y":0}]},"lizi6":{"translate":[{"x":-51.66,"y":-60.09}],"scale":[{"x":0,"y":0}]},"pipeizhong":{"scale":[{},{"time":0.1,"x":0,"y":0}]},"tiao_new":{"scale":[{"x":0,"y":0,"curve":"stepped"},{"time":0.0667,"x":0,"y":0},{"time":0.1333,"y":0.1},{"time":0.2333,"y":1.3},{"time":0.3667,"y":0.9},{"time":0.5}]},"zhong":{"translate":[{"x":-41.29}]},"dian":{"translate":[{"x":-83.49,"y":2.22}]},"dian2":{"translate":[{"x":-57.12,"y":2.22}]},"dian3":{"translate":[{"x":-31.53,"y":2.22}]}}}}}'; +gameabc_face.spineTextData['gamestart.atlas'] = 'gamestart.png\nsize:2048,512\nfilter:Linear,Linear\ndai\nbounds:1521,395,96,90\ndeng\nbounds:1418,395,101,90\ndian\nbounds:1167,183,24,22\nduijukaishi\nbounds:929,393,380,92\nfangkuai\nbounds:446,47,32,32\nfangkuai_kuang\nbounds:2,2,32,32\nglow_bian\nbounds:2,36,330,9\nheitao_01\nbounds:929,173,236,218\nheitao_02\nbounds:2,47,442,219\nlamp_glow\nbounds:446,81,198,185\nlizi_1\nbounds:646,247,19,19\nloading_aixin\nbounds:1273,363,28,28\nnew_tiao_orange\nbounds:2,268,667,217\npei\nbounds:1311,393,105,92\npi\nbounds:1167,302,104,89\nxingguang\nbounds:671,229,256,256\nzhong\nbounds:1167,207,98,93\n'; +gameabc_face.spineTextData['Zaijiezaili.json'] = '{"skeleton":{"hash":"YQ68cRyF7vg","spine":"4.2.43","x":-137.99,"y":-23.46,"width":273.57,"height":299.64,"images":"./0/","audio":"I:\\\\游æˆç´ ææ”¶é›†\\\\棋牌\\\\指间四å·éº»å°†\\\\spine1\\\\Zaijiezaili"},"bones":[{"name":"root"},{"name":"zhengti","parent":"root","scaleX":0.33,"scaleY":0.33},{"name":"zuoshou","parent":"zhengti","length":153.45,"rotation":-132.81,"x":283.03,"y":320.9},{"name":"zuoshou2","parent":"zuoshou","length":89.64,"rotation":-23,"x":153.45},{"name":"zuoshou3","parent":"zuoshou2","length":136.48,"rotation":-3.87,"x":89.64},{"name":"majiang","parent":"zhengti","length":349.64,"rotation":74.27,"x":-83.13,"y":8.06},{"name":"majiang2","parent":"majiang","length":424.47,"rotation":13.81,"x":349.64},{"name":"toufa","parent":"majiang2","length":55.4,"rotation":133.45,"x":401.91,"y":-56.48},{"name":"toufa2","parent":"toufa","length":64.53,"rotation":4.21,"x":55.4},{"name":"yanjing","parent":"majiang2","length":102.74,"rotation":-5.37,"x":97.32,"y":81.52},{"name":"zuiba","parent":"majiang2","length":28.54,"rotation":177.16,"x":68.93,"y":79.38},{"name":"lei","parent":"majiang2","length":55.09,"rotation":-159.26,"x":70.14,"y":-62.86},{"name":"lei1","parent":"majiang2","length":109.25,"rotation":179.5,"x":64.67,"y":-80.5},{"name":"meimao","parent":"majiang2","length":28.83,"rotation":11.38,"x":249.29,"y":181.46},{"name":"meimaozuo","parent":"majiang2","length":33.01,"rotation":-19.12,"x":204.64,"y":-42.94},{"name":"fennu","parent":"majiang2","length":127.88,"rotation":9.37,"x":415.06,"y":-271.83},{"name":"shaizi","parent":"zhengti","length":247.68,"rotation":90.55,"x":-166.08,"y":25.1},{"name":"zuojiao","parent":"majiang","length":150.2,"rotation":161.67,"x":113.74,"y":-126.77},{"name":"youjiao","parent":"majiang","length":170.46,"rotation":114.93,"x":66.88,"y":183.81},{"name":"youshou","parent":"majiang","length":159.04,"rotation":-156.56,"x":325.57,"y":283.77},{"name":"lei2","parent":"majiang2","length":55.09,"rotation":132.86,"x":104.64,"y":211.59},{"name":"lei3","parent":"majiang2","length":109.25,"rotation":179.5,"x":103.57,"y":230.15,"scaleY":-1}],"slots":[{"name":"yinying","bone":"zhengti"},{"name":"shitou2","bone":"zhengti","attachment":"shitou"},{"name":"shitou","bone":"zhengti"},{"name":"majiang","bone":"majiang","attachment":"majiang"},{"name":"youjiao","bone":"youjiao","attachment":"youjiao"},{"name":"youshou","bone":"youshou","attachment":"youshou"},{"name":"lianhong","bone":"majiang2","attachment":"lianhong"},{"name":"lei3","bone":"lei3","attachment":"lei1"},{"name":"shaizi","bone":"shaizi","attachment":"shaizi"},{"name":"zuojiao","bone":"zuojiao","attachment":"zuojiao"},{"name":"meimao","bone":"meimao","attachment":"meimao"},{"name":"meimaozuo","bone":"meimaozuo","attachment":"meimaozuo"},{"name":"yanjing","bone":"yanjing","attachment":"yanjing"},{"name":"zuiba","bone":"zuiba","attachment":"zuiba"},{"name":"lei1","bone":"lei1","attachment":"lei1"},{"name":"lei","bone":"lei","attachment":"lei"},{"name":"lei2","bone":"lei2","attachment":"lei"},{"name":"toufa","bone":"toufa","attachment":"toufa"},{"name":"zuoshou","bone":"zuoshou","attachment":"zuoshou"},{"name":"fennu","bone":"fennu","attachment":"fennu"}],"skins":[{"name":"default","attachments":{"fennu":{"fennu":{"x":0.62,"y":-3.71,"rotation":-97.45,"width":176,"height":171}},"lei":{"lei":{"x":24.68,"y":0.57,"rotation":71.18,"width":53,"height":73}},"lei1":{"lei1":{"x":53.68,"y":-4.93,"rotation":102.53,"width":55,"height":129}},"lei2":{"lei":{"x":23.4,"y":3.39,"scaleX":0.9866,"rotation":81.81,"width":53,"height":73}},"lei3":{"lei1":{"x":53.68,"y":-4.93,"rotation":102.53,"width":55,"height":129}},"lianhong":{"lianhong":{"x":33.73,"y":62.99,"rotation":-88.08,"width":526,"height":193}},"majiang":{"majiang":{"type":"mesh","uvs":[0.55292,0,0.80146,0.0316,0.96859,0.09786,0.99866,0.18316,0.99208,0.54246,0.99217,0.59235,0.98321,0.65035,0.95986,0.74151,0.8828,0.88017,0.70514,0.9961,0.39641,0.95353,0.1743,0.91079,0.10958,0.86867,0.1032,0.79716,0.17551,0.53933,0.18123,0.48867,0.18632,0.44363,0.18253,0.13643,0.41176,0],"triangles":[9,10,8,8,10,13,13,10,11,14,7,8,13,11,12,8,13,14,7,14,6,6,14,5,5,14,15,5,15,4,15,16,4,4,16,0,3,1,2,16,18,0,0,1,4,4,1,3,16,17,18],"vertices":[1,6,435.13,13.03,1,1,6,415.81,-172.63,1,1,6,366.46,-298.7,1,1,6,298.33,-323.37,1,2,6,8.01,-328.2,0.126,5,435.77,-316.8,0.874,2,6,-32.27,-329.62,0.504,5,396.99,-327.79,0.496,1,5,350.07,-334.08,1,1,5,274.47,-337.33,1,1,5,151.08,-312.53,1,1,5,25.08,-210.69,1,1,5,-4.09,19.72,1,1,5,-15.66,188.15,1,1,5,4.05,243.72,1,1,5,58.37,263.96,1,1,5,273.49,268.66,1,2,6,31.24,276.19,0.504,5,314.03,275.66,0.496,2,6,67.74,273.62,0.126,5,350.09,281.88,0.874,1,6,315.72,284.76,1,1,6,431.61,117.99,1],"hull":19,"edges":[0,36,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,30,30,32,32,34,34,36],"width":222,"height":239}},"meimao":{"meimao":{"x":0.96,"y":2.18,"rotation":-99.46,"width":141,"height":67}},"meimaozuo":{"meimaozuo":{"x":5.14,"y":2.61,"rotation":-68.96,"width":142,"height":109}},"shaizi":{"shaizi":{"type":"mesh","uvs":[1,1,0,1,0,0,1,0],"triangles":[1,2,3,1,3,0],"vertices":[-89.79,-168.08,-86.36,190.91,277.62,187.42,274.19,-171.56],"hull":4,"edges":[0,6,0,2,2,4,4,6],"width":108,"height":110}},"shitou2":{"shitou":{"x":285.85,"y":7.92,"width":250,"height":158}},"toufa":{"toufa":{"type":"mesh","uvs":[0.99148,0.02227,0.99966,0.66804,0.88208,1,0.79701,1,0,0.56577,0,0.52294,0.11656,0.1786,0.26577,0.11842,0.55225,0.00289],"triangles":[7,4,5,7,5,6,3,4,7,8,0,1,7,8,1,3,7,1,2,3,1],"vertices":[2,7,-34.29,25.38,0.94779,8,-87.59,31.9,0.05221,2,7,17.96,86.93,0.7463,8,-30.96,89.44,0.2537,2,7,63.69,101.85,0.91243,8,15.75,100.97,0.08757,2,7,76.87,90.18,0.58268,8,28.04,88.36,0.41732,2,7,164.39,-59.84,0.28341,8,104.29,-67.69,0.71659,2,7,160.84,-63.85,0.00525,8,100.46,-71.42,0.99475,2,7,114.24,-80.07,0.03797,8,52.79,-84.18,0.96203,2,7,86.13,-65.23,0.48932,8,25.85,-67.31,0.51068,2,7,32.16,-36.72,0.65075,8,-25.88,-34.91,0.34925],"hull":9,"edges":[0,16,0,2,2,4,4,6,6,8,8,10,10,12,12,14,14,16],"width":207,"height":125}},"yanjing":{"yanjing":{"type":"mesh","uvs":[1,1,0,1,0,0,1,0],"triangles":[1,2,3,1,3,0],"vertices":[-65.15,-205.31,-112.35,163.68,121.75,193.62,168.94,-175.37],"hull":4,"edges":[0,6,0,2,2,4,4,6],"width":111,"height":70}},"youjiao":{"youjiao":{"x":84.44,"y":3.9,"rotation":170.8,"width":187,"height":132}},"youshou":{"youshou":{"x":82.04,"y":-1.18,"rotation":82.29,"width":98,"height":178}},"zuiba":{"zuiba":{"x":11.59,"y":2.17,"rotation":94.76,"width":98,"height":47}},"zuojiao":{"zuojiao":{"x":81,"y":-0.62,"rotation":124.07,"width":156,"height":167}},"zuoshou":{"zuoshou":{"type":"mesh","uvs":[0.98971,0,0.75334,0,0.59918,0.20428,0.55807,0.25215,0.50668,0.30003,0.39706,0.42189,0.02707,0.3392,0,0.65256,0,1,0.31484,1,0.47242,0.77878,0.67112,0.67868,0.72936,0.64386,0.78759,0.60469,1,0.35225,1,0,0.63473,0.26018],"triangles":[7,6,5,7,5,10,9,8,7,10,9,7,12,4,3,11,4,12,5,4,11,10,5,11,16,2,1,3,2,16,0,15,14,1,14,16,14,1,0,13,16,14,12,16,13,3,16,12],"vertices":[1,2,-25.76,-4.59,1,2,2,31.58,-66.5,0.99983,3,-86.2,-108.83,1.7E-4,2,2,111.09,-67.86,0.80126,3,-12.48,-79.02,0.19874,2,2,130.93,-69.49,0.59796,3,6.42,-72.76,0.40204,3,2,153.27,-73.8,0.337,3,28.67,-68.01,0.66105,4,-56.24,-71.97,0.00195,3,2,204.99,-79.24,0.0166,3,78.4,-52.81,0.63444,4,-7.65,-53.45,0.34896,1,4,108.14,-121.11,1,1,4,147.79,-41.9,1,1,4,181.7,49.65,1,1,4,76.3,88.69,1,2,3,94.96,49.69,0.44283,4,1.95,49.94,0.55717,2,2,191.44,41.57,0.15017,3,18.72,53.1,0.84983,2,2,170.13,50.17,0.46073,3,-4.25,52.7,0.53927,2,2,147.93,57.94,0.7932,3,-27.73,51.18,0.2068,1,2,44.36,65.37,1,1,2,-28.26,-1.9,1,2,2,113.99,-47.88,0.8182,3,-17.62,-59.49,0.1818],"hull":16,"edges":[0,30,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,30],"width":357,"height":281}}}}],"animations":{"animation":{"slots":{"lei":{"rgba":[{"time":0.3333,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00","curve":"stepped"},{"time":0.9667,"color":"ffffff00"},{"time":1,"color":"ffffffff","curve":"stepped"},{"time":1.3,"color":"ffffffff"},{"time":1.3333,"color":"ffffff00"}]},"lei1":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3333,"color":"ffffff00"},{"time":0.3667,"color":"ffffffff","curve":"stepped"},{"time":0.5667,"color":"ffffffff"},{"time":0.6,"color":"ffffff00","curve":"stepped"},{"time":1.3,"color":"ffffff00"},{"time":1.3333,"color":"ffffffff","curve":"stepped"},{"time":1.5333,"color":"ffffffff"},{"time":1.5667,"color":"ffffff00"}]},"lei2":{"rgba":[{"color":"ffffff00"},{"time":0.0333,"color":"ffffffff","curve":"stepped"},{"time":0.3333,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00","curve":"stepped"},{"time":1,"color":"ffffff00"},{"time":1.0333,"color":"ffffffff","curve":"stepped"},{"time":1.3333,"color":"ffffffff"},{"time":1.3667,"color":"ffffff00"}]},"lei3":{"rgba":[{"color":"ffffff00","curve":"stepped"},{"time":0.3333,"color":"ffffff00"},{"time":0.3667,"color":"ffffffff","curve":"stepped"},{"time":0.5667,"color":"ffffffff"},{"time":0.6,"color":"ffffff00","curve":"stepped"},{"time":1.3333,"color":"ffffff00"},{"time":1.3667,"color":"ffffffff","curve":"stepped"},{"time":1.5667,"color":"ffffffff"},{"time":1.6,"color":"ffffff00"}]}},"bones":{"lei1":{"translate":[{"time":0.3667},{"time":0.6,"x":-179.67,"y":1.57},{"time":0.9667,"curve":"stepped"},{"time":1.3333},{"time":1.5667,"x":-179.67,"y":1.57}]},"lei2":{"scale":[{"x":0.657},{"time":0.3333},{"time":1,"x":0.657},{"time":1.3333}]},"lei":{"scale":[{"x":0.666},{"time":0.3333},{"time":0.9667,"x":0.666},{"time":1.3}]},"lei3":{"translate":[{"time":0.3667},{"time":0.6,"x":-191.75,"y":1.68},{"time":1,"curve":"stepped"},{"time":1.3667},{"time":1.6,"x":-191.75,"y":1.68}]},"zuoshou":{"rotate":[{"curve":[0.208,0,0.625,-2.28]},{"time":0.8333,"value":-2.28,"curve":[1.042,-2.28,1.458,0]},{"time":1.6667}]},"zuoshou2":{"rotate":[{"curve":[0.208,0,0.625,-2.28]},{"time":0.8333,"value":-2.28,"curve":[1.042,-2.28,1.458,0]},{"time":1.6667}]},"zuoshou3":{"rotate":[{"value":-2.09,"curve":[0.076,-0.84,0.145,0]},{"time":0.2,"curve":[0.408,0,0.825,-12.04]},{"time":1.0333,"value":-12.04,"curve":[1.187,-12.04,1.457,-5.27]},{"time":1.6667,"value":-2.09}]},"majiang2":{"rotate":[{"curve":[0.1,0,0.3,2.79]},{"time":0.4,"value":2.79,"curve":[0.425,2.79,0.475,-2.73]},{"time":0.5,"value":-2.73,"curve":[0.575,-2.73,0.725,1.1]},{"time":0.8,"value":1.1,"curve":[0.825,1.1,0.875,-2.73]},{"time":0.9,"value":-2.73,"curve":[0.936,-2.73,0.983,-1.55]},{"time":1.0333,"value":0.16,"curve":[1.068,-0.88,1.109,-2.73]},{"time":1.1333,"value":-2.73,"curve":[1.278,-2.73,1.463,-1.61]},{"time":1.6667}],"scale":[{"time":0.4},{"time":0.5,"x":1.027},{"time":0.8},{"time":0.9,"x":1.027},{"time":1.0333},{"time":1.1333,"x":1.027},{"time":1.6667}]},"toufa":{"rotate":[{"time":0.4,"curve":[0.442,0,0.525,-5.53]},{"time":0.5667,"value":-5.53,"curve":[0.633,-5.53,0.767,0]},{"time":0.8333,"curve":[0.867,0,0.933,-3.81]},{"time":0.9667,"value":-3.81,"curve":[1,-3.81,1.067,-1.31]},{"time":1.1,"value":-1.31,"curve":[1.142,-1.31,1.225,-7.41]},{"time":1.2667,"value":-7.41,"curve":[1.367,-7.41,1.567,0]},{"time":1.6667}]},"toufa2":{"rotate":[{"value":-1.37,"curve":[0.038,-0.55,0.072,0]},{"time":0.1,"curve":"stepped"},{"time":0.5,"curve":[0.542,0,0.625,-5.53]},{"time":0.6667,"value":-5.53,"curve":[0.733,-5.53,0.867,0]},{"time":0.9333,"curve":[0.967,0,1.033,-3.81]},{"time":1.0667,"value":-3.81,"curve":[1.1,-3.81,1.167,-1.31]},{"time":1.2,"value":-1.31,"curve":[1.242,-1.31,1.325,-7.41]},{"time":1.3667,"value":-7.41,"curve":[1.439,-7.41,1.567,-3.36]},{"time":1.6667,"value":-1.37}]},"zuiba":{"scale":[{"time":0.4333},{"time":0.5,"y":0.865},{"time":0.8},{"time":0.8667,"y":0.865,"curve":"stepped"},{"time":1.2,"y":0.865},{"time":1.6667}]},"meimao":{"rotate":[{"time":0.4},{"time":0.5,"value":-6.29},{"time":0.8},{"time":0.9,"value":-6.29},{"time":1.0667},{"time":1.1667,"value":-6.29},{"time":1.6667}]},"meimaozuo":{"rotate":[{"time":0.4},{"time":0.5,"value":4.64},{"time":0.8},{"time":0.9,"value":4.64},{"time":1.0667},{"time":1.1667,"value":4.64},{"time":1.6667}]},"fennu":{"scale":[{"x":0.994,"y":0.994,"curve":[0.012,0.998,0.023,1,0.012,0.998,0.023,1]},{"time":0.0333,"curve":"stepped"},{"time":0.4333,"curve":[0.458,1,0.508,0.574,0.458,1,0.508,0.574]},{"time":0.5333,"x":0.574,"y":0.574,"curve":[0.608,0.574,0.758,1,0.608,0.574,0.758,1]},{"time":0.8333,"curve":[0.858,1,0.908,0.724,0.858,1,0.908,0.724]},{"time":0.9333,"x":0.724,"y":0.724,"curve":[0.975,0.724,1.058,1,0.975,0.724,1.058,1]},{"time":1.1,"curve":[1.125,1,1.175,0.749,1.125,1,1.175,0.749]},{"time":1.2,"x":0.749,"y":0.749,"curve":[1.315,0.749,1.537,0.965,1.315,0.749,1.537,0.965]},{"time":1.6667,"x":0.994,"y":0.994}]},"shaizi":{"rotate":[{"value":0.3,"curve":[0.063,0.11,0.119,0]},{"time":0.1667,"curve":[0.375,0,0.792,2.32]},{"time":1,"value":2.32,"curve":[1.162,2.32,1.453,0.89]},{"time":1.6667,"value":0.3}],"scale":[{"x":0.988,"curve":[0.204,0.973,0.454,0.945,0.204,1,0.454,1]},{"time":0.6,"x":0.945,"curve":[0.808,0.945,1.225,1,0.808,1,1.225,1]},{"time":1.4333,"curve":[1.497,1,1.578,0.995,1.497,1,1.578,1]},{"time":1.6667,"x":0.988}]},"zuojiao":{"rotate":[{"curve":[0.208,0,0.625,-5.86]},{"time":0.8333,"value":-5.86,"curve":[1.042,-5.86,1.458,0]},{"time":1.6667}]},"youjiao":{"rotate":[{"value":1.71,"curve":[0.115,0.75,0.221,0]},{"time":0.3,"curve":[0.508,0,0.925,5.41]},{"time":1.1333,"value":5.41,"curve":[1.263,5.41,1.477,3.26]},{"time":1.6667,"value":1.71}]},"youshou":{"rotate":[{"curve":[0.208,0,0.625,-5.51]},{"time":0.8333,"value":-5.51,"curve":[1.042,-5.51,1.458,0]},{"time":1.6667}]},"yanjing":{"scale":[{"time":0.4333,"curve":[0.458,1,0.508,0.935,0.458,1,0.508,1]},{"time":0.5333,"x":0.935,"curve":[0.6,0.935,0.733,1,0.6,1,0.733,1]},{"time":0.8,"curve":[0.825,1,0.875,0.918,0.825,1,0.875,1]},{"time":0.9,"x":0.918,"curve":[0.942,0.918,1.025,1,0.942,1,1.025,1]},{"time":1.0667,"curve":[1.092,1,1.142,0.87,1.092,1,1.142,1]},{"time":1.1667,"x":0.87,"curve":[1.258,0.87,1.442,1,1.258,1,1.442,1]},{"time":1.5333}]}}}}}'; +gameabc_face.spineTextData['Zaijiezaili.atlas'] = 'Zaijiezaili.png\nsize:2048,512\nfilter:Linear,Linear\nfennu\nbounds:1006,307,176,171\nlei\nbounds:576,164,53,73\nlei1\nbounds:519,108,55,129\nlianhong\nbounds:2,285,526,193\nmajiang\nbounds:530,239,222,239\nmeimao\nbounds:754,251,141,67\nmeimaozuo\nbounds:361,5,142,109\nshaizi\nbounds:1682,368,108,110\nshitou\nbounds:754,320,250,158\ntoufa\nbounds:1184,353,207,125\nyanjing\nbounds:1792,408,111,70\nyoujiao\nbounds:1393,346,187,132\nyoushou\nbounds:1582,300,98,178\nzuiba\nbounds:1682,319,98,47\nzuojiao\nbounds:361,116,156,167\nzuoshou\nbounds:2,2,357,281\n'; diff --git a/codes/games/client/Projects/Spine/index.html b/codes/games/client/Projects/Spine/index.html new file mode 100644 index 0000000..216aab3 --- /dev/null +++ b/codes/games/client/Projects/Spine/index.html @@ -0,0 +1,66 @@ + + + + + + + + +gameabc + + + + + +

+ +

Your browser does not support the canvas element.

+
+
+
+ +

Your browser does not support the canvas element.

+
+
+
+ +

Your browser does not support the canvas element.

+
+
+
+ +

Your browser does not support the canvas element.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codes/games/client/Projects/Spine/js/SpineMgr.js b/codes/games/client/Projects/Spine/js/SpineMgr.js new file mode 100644 index 0000000..db3fd98 --- /dev/null +++ b/codes/games/client/Projects/Spine/js/SpineMgr.js @@ -0,0 +1,416 @@ +// ============================================================ +// SpineMgr —— Spine 动画管ç†å™¨ï¼ˆç‹¬ç«‹æ–‡ä»¶ï¼‰ +// 集æˆåˆ° gameabc Canvas 2D 绘制循环,零侵入 gamemain.js +// 在 index.html 中置于 gameabc.min.js 之åŽã€gamemain.js 之å‰åŠ è½½ +// ============================================================ +(function(){ + +var SpineMgr = { + + // --- å†…éƒ¨çŠ¶æ€ --- + _entries: {}, // {id: EntryObject} + _assetManager: null, + _renderer: null, // spine.SkeletonRenderer (Canvas 2D) + _lastTime: 0, // 上一帧时间戳(ms) + _inited: false, + _loadedPaths: {}, // 已请求加载的资æºè·¯å¾„,é¿å…é‡å¤è¯·æ±‚ + _pendingCmds: {}, // {id: [{method, args}]} ç­‰å¾…å®žä¾‹å°±ç»ªåŽæ‰§è¡Œçš„命令队列 + + // é»˜è®¤èµ„æºæ ¹è·¯å¾„(å¯é€šè¿‡ init 覆盖) + _basePath: "assets/spine/", + + // ---------------------------------------------------------- + // init(basePath) 手动åˆå§‹åŒ–(å¯é€‰ï¼‰ + // 如ä¸è°ƒç”¨ï¼Œload 时会自动以默认路径 "assets/spine/" åˆå§‹åŒ– + // ---------------------------------------------------------- + init: function(basePath) { + if (!window.spine) { + logmessage("[SpineMgr] spine-canvas.js 未加载,请检查引用"); + return; + } + this._basePath = basePath || this._basePath; + this._assetManager = new spine.AssetManager(this._basePath); + this._lastTime = Date.now(); + this._inited = true; + }, + + // (内部) ç¡®ä¿å·²åˆå§‹åŒ– + _ensureInit: function() { + if (!this._inited) { + this.init(this._basePath); + } + }, + + // (内部) è‡ªåŠ¨åŠ è½½ï¼šæ ¹æ® id 约定文件å id.json / id.atlas + _autoLoad: function(id) { + if (this._entries[id]) return; + this.load(id, id + ".json", id + ".atlas", {}); + }, + + // (内部) 将命令加入等待队列 + _queueCmd: function(id, method, args) { + if (!this._pendingCmds[id]) this._pendingCmds[id] = []; + this._pendingCmds[id].push({method: method, args: args}); + }, + + // (内部) å®žä¾‹å°±ç»ªåŽæ‰§è¡Œé˜Ÿåˆ—中的命令 + _flushCmds: function(id) { + var cmds = this._pendingCmds[id]; + if (!cmds || cmds.length === 0) return; + delete this._pendingCmds[id]; + for (var i = 0; i < cmds.length; i++) { + var cmd = cmds[i]; + this[cmd.method].apply(this, [id].concat(cmd.args)); + } + }, + + // ---------------------------------------------------------- + // load(id, jsonFile, atlasFile, option) + // 加载一组 Spine 资æº, id 为自定义标识 + // option: {x, y, scale, skin, animation, loop, mixDuration} + // ---------------------------------------------------------- + load: function(id, jsonFile, atlasFile, option) { + this._ensureInit(); + if (!this._inited) return; + var opt = option || {}; + // åªåŠ è½½å°šæœªè¯·æ±‚è¿‡çš„èµ„æºï¼ˆé¢„加载过的会跳过) + if (!this._loadedPaths[jsonFile]) { + this._assetManager.loadText(jsonFile); + this._loadedPaths[jsonFile] = true; + } + if (!this._loadedPaths[atlasFile]) { + this._assetManager.loadTextureAtlas(atlasFile); + this._loadedPaths[atlasFile] = true; + } + this._entries[id] = { + jsonFile: jsonFile, + atlasFile: atlasFile, + skeleton: null, + state: null, + x: opt.x || 0, + y: opt.y || 0, + scale: opt.scale || 1, + skin: opt.skin || "default", + defAnim: opt.animation || null, + defLoop: opt.loop !== undefined ? opt.loop : true, + mixDur: opt.mixDuration || 0.2, + visible: true, + ready: false, + _hideOnComplete: false, // 播放完æˆåŽæ˜¯å¦è‡ªåЍéšè— + _hideAfterCompletes: 0 // 剩余多少次 complete åŽè§¦å‘éšè— + }; + }, + + // ---------------------------------------------------------- + // (内部) 资æºåŠ è½½å®ŒæˆåŽå®žä¾‹åŒ–骨骼 + // ---------------------------------------------------------- + _buildEntry: function(entry) { + var atlas = this._assetManager.require(entry.atlasFile); + var loader = new spine.AtlasAttachmentLoader(atlas); + var skelJson = new spine.SkeletonJson(loader); + skelJson.scale = entry.scale; + + var skelData = skelJson.readSkeletonData( + this._assetManager.require(entry.jsonFile) + ); + entry.skeleton = new spine.Skeleton(skelData); + + // 设置皮肤 + if (entry.skin && entry.skin !== "default") { + entry.skeleton.setSkinByName(entry.skin); + } + entry.skeleton.setToSetupPose(); + + // AnimationState + var stateData = new spine.AnimationStateData(skelData); + stateData.defaultMix = entry.mixDur; + entry.state = new spine.AnimationState(stateData); + + // 绑定事件回调 —— 转å‘到 Spine_Event.js + entry.state.addListener({ + complete: function(trackEntry) { + // 自动éšè—:playOnce / playQueue 设置的计数器 + if (entry._hideOnComplete && !trackEntry.loop) { + entry._hideAfterCompletes--; + if (entry._hideAfterCompletes <= 0) { + entry.visible = false; + entry._hideOnComplete = false; + } + } + if (gameabc_face.spine_onComplete) { + gameabc_face.spine_onComplete(entry._id, trackEntry.animation.name, trackEntry.trackIndex); + } + }, + event: function(trackEntry, event) { + if (gameabc_face.spine_onEvent) { + gameabc_face.spine_onEvent(entry._id, event.data.name, event.intValue, event.floatValue, event.stringValue); + } + } + }); + + // 默认动画 + if (entry.defAnim) { + entry.state.setAnimation(0, entry.defAnim, entry.defLoop); + } + entry.ready = true; + }, + + // ---------------------------------------------------------- + // (内部) æ¯å¸§è°ƒç”¨ï¼šç¡®ä¿æ‰€æœ‰èµ„æºå°±ç»ª + // ---------------------------------------------------------- + _tryBuild: function() { + if (!this._assetManager.isLoadingComplete()) return false; + for (var id in this._entries) { + var e = this._entries[id]; + if (!e.ready) { + e._id = id; + try { + this._buildEntry(e); + logmessage("[SpineMgr] " + id + " 构建完æˆ"); + this._flushCmds(id); + } catch(err) { + logmessage("[SpineMgr] " + id + " 构建失败: " + err.message); + e.ready = false; + } + } + } + return true; + }, + + // ---------------------------------------------------------- + // updateAndDraw(ctx) æ¯å¸§è‡ªåŠ¨è°ƒç”¨ + // ctx: gameabc_face.dc (Canvas 2D Context) + // ---------------------------------------------------------- + updateAndDraw: function(ctx) { + if (!this._inited) return; + this._tryBuild(); + + var now = Date.now(); + var dt = (now - this._lastTime) / 1000; + this._lastTime = now; + if (dt <= 0 || dt > 0.5) dt = 1/30; + + if (!this._renderer) { + this._renderer = new spine.SkeletonRenderer(ctx); + this._renderer.triangleRendering = true; // ★ å¯ç”¨ä¸‰è§’å½¢æ¸²æŸ“ä»¥æ”¯æŒ Mesh 网格附件 + } + // ç¡®ä¿ renderer ç”¨çš„æ˜¯å½“å‰ ctx (gameabcå¯èƒ½é‡å»º) + this._renderer.ctx = ctx; + + for (var id in this._entries) { + var e = this._entries[id]; + if (!e.ready || !e.visible) continue; + + e.state.update(dt); + e.state.apply(e.skeleton); + // 骨骼ä½ç½®å½’零,由 ctx.translate 控制实际ä½ç½® + e.skeleton.x = 0; + e.skeleton.y = 0; + e.skeleton.updateWorldTransform(spine.Physics.update); + + ctx.save(); + ctx.translate(e.x, e.y); + ctx.scale(1, -1); // ★ Spine Y-up → Canvas Y-down + this._renderer.draw(e.skeleton); + ctx.restore(); + } + }, + + // ========================================================== + // 公开控制 API + // ========================================================== + + setAnimation: function(id, animName, loop, track) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setAnimation", [animName, loop, track]); + return null; + } + if (!e.ready) { + this._queueCmd(id, "setAnimation", [animName, loop, track]); + return null; + } + return e.state.setAnimation(track || 0, animName, loop !== false); + }, + + addAnimation: function(id, animName, loop, delay, track) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "addAnimation", [animName, loop, delay, track]); + return null; + } + if (!e.ready) { + this._queueCmd(id, "addAnimation", [animName, loop, delay, track]); + return null; + } + return e.state.addAnimation(track || 0, animName, loop !== false, delay || 0); + }, + + setPosition: function(id, x, y) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + e = this._entries[id]; + } + e.x = x; e.y = y; + }, + + setScale: function(id, sx, sy) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setScale", [sx, sy]); + return; + } + if (!e.skeleton) { + this._queueCmd(id, "setScale", [sx, sy]); + return; + } + e.skeleton.scaleX = sx; + e.skeleton.scaleY = sy !== undefined ? sy : sx; + }, + + setFlip: function(id, flipX, flipY) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setFlip", [flipX, flipY]); + return; + } + if (!e.skeleton) { + this._queueCmd(id, "setFlip", [flipX, flipY]); + return; + } + e.skeleton.scaleX = Math.abs(e.skeleton.scaleX) * (flipX ? -1 : 1); + e.skeleton.scaleY = Math.abs(e.skeleton.scaleY) * (flipY ? -1 : 1); + }, + + setVisible: function(id, visible) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + e = this._entries[id]; + } + e.visible = !!visible; + }, + + setSkin: function(id, skinName) { + var e = this._entries[id]; + if (!e) { + this._autoLoad(id); + this._queueCmd(id, "setSkin", [skinName]); + return; + } + if (!e.ready) { + this._queueCmd(id, "setSkin", [skinName]); + return; + } + e.skeleton.setSkinByName(skinName); + e.skeleton.setSlotsToSetupPose(); + }, + + getAnimations: function(id) { + var e = this._entries[id]; + if (!e) { this._autoLoad(id); return []; } + if (!e.ready) return []; + var anims = e.skeleton.data.animations; + var names = []; + for (var i = 0; i < anims.length; i++) names.push(anims[i].name); + return names; + }, + + getSkins: function(id) { + var e = this._entries[id]; + if (!e) { this._autoLoad(id); return []; } + if (!e.ready) return []; + var skins = e.skeleton.data.skins; + var names = []; + for (var i = 0; i < skins.length; i++) names.push(skins[i].name); + return names; + }, + + playOnce: function(id, animName, track) { + this.setVisible(id, true); + this.setAnimation(id, animName, false, track); + var e = this._entries[id]; + if (e) { + e._hideOnComplete = true; + e._hideAfterCompletes = 1; + } + }, + + playQueue: function(id, animList, hideOnComplete) { + if (!animList || animList.length === 0) return; + this.setVisible(id, true); + this.setAnimation(id, animList[0], false, 0); + for (var i = 1; i < animList.length; i++) { + this.addAnimation(id, animList[i], false, 0, 0); + } + var e = this._entries[id]; + if (e) { + e._hideOnComplete = hideOnComplete !== false; + e._hideAfterCompletes = animList.length; + } + }, + + remove: function(id) { + delete this._entries[id]; + }, + + removeAll: function() { + this._entries = {}; + } +}; + +// 挂载到 gameabc_face 上 +gameabc_face.spineMgr = SpineMgr; + +// ★ è‡ªåŠ¨é¢„åŠ è½½ï¼šè¯»å– gameabc_face.spineAssets 清å•,在引擎å¯åЍå‰é¢„加载所有 Spine èµ„æº +// 如果存在 spineTextData(嵌入文本数æ®ï¼‰ï¼Œåˆ™é€šè¿‡ setRawDataURI 注入, +// 彻底é¿å… file:// å议下 XHR CORS 拦截问题 +if (gameabc_face.spineAssets && gameabc_face.spineAssets.length > 0) { + SpineMgr._ensureInit(); + var list = gameabc_face.spineAssets; + var textData = gameabc_face.spineTextData || {}; + for (var i = 0; i < list.length; i++) { + var name = list[i]; + var jsonKey = name + ".json"; + var atlasKey = name + ".atlas"; + // å°†åµŒå…¥æ–‡æœ¬æ•°æ®æ³¨å†Œä¸º rawDataURI,Spine Downloader ä¼šä¼˜å…ˆä»Žå†…å­˜è¯»å– + if (textData[jsonKey]) { + SpineMgr._assetManager.setRawDataURI(jsonKey, "data:," + textData[jsonKey]); + } + if (textData[atlasKey]) { + SpineMgr._assetManager.setRawDataURI(atlasKey, "data:," + textData[atlasKey]); + } + SpineMgr._assetManager.loadText(jsonKey); + SpineMgr._loadedPaths[jsonKey] = true; + SpineMgr._assetManager.loadTextureAtlas(atlasKey); + SpineMgr._loadedPaths[atlasKey] = true; + } + logmessage("[SpineMgr] 预加载 " + list.length + " 组 Spine 资æº" + + (Object.keys(textData).length > 0 ? "(使用嵌入数æ®ï¼‰" : "(使用网络请求)")); +} + +// ★ 用 defineProperty 拦截 gameenddraw 赋值 +// 无论 gamemain.js 或其他代ç å¦‚何定义 gameenddraw, +// Spine æ¸²æŸ“éƒ½ä¼šè‡ªåŠ¨è¿½åŠ åœ¨ç”¨æˆ·é€»è¾‘ä¹‹åŽ +var _userEndDraw = gameabc_face.gameenddraw || null; +var _wrappedEndDraw = function(gameid, spid, times, timelong) { + if (typeof _userEndDraw === "function") { + _userEndDraw(gameid, spid, times, timelong); + } + var ctx = gameabc_face.dc; + if (ctx && SpineMgr._inited) { + SpineMgr.updateAndDraw(ctx); + } +}; +Object.defineProperty(gameabc_face, "gameenddraw", { + configurable: true, + get: function() { return _wrappedEndDraw; }, + set: function(fn) { _userEndDraw = fn; } +}); + +})(); diff --git a/codes/games/client/Projects/Spine/js/gameabc.min.js b/codes/games/client/Projects/Spine/js/gameabc.min.js new file mode 100644 index 0000000..a561ba8 --- /dev/null +++ b/codes/games/client/Projects/Spine/js/gameabc.min.js @@ -0,0 +1,5544 @@ +var gameabc_senderror = 0; +var gameabc = function() { + function s(SIt2, L$qig3, Qf4) { + var PzF5, IKcga6, d7; + for (IKcga6 = 0; IKcga6 < 30; IKcga6++) + for (PzF5 = 0; PzF5 < 73; PzF5++) + d7 = (PzF5 + IKcga6 * 74) * 4, + SIt2[d7] = SIt2[d7 + 4], + SIt2[d7 + 1] = SIt2[d7 + 5], + SIt2[d7 + 2] = SIt2[d7 + 6]; + for (IKcga6 = 0; IKcga6 < 30; IKcga6++) + d7 = (73 + IKcga6 * 74) * 4, + IKcga6 < L$qig3 ? (SIt2[d7] = b[Qf4]["\x62\x67"]["\x72"], + SIt2[d7 + 1] = b[Qf4]["\x62\x67"]["\x67"], + SIt2[d7 + 2] = b[Qf4]["\x62\x67"]["\x62"]) : (SIt2[d7] = b[Qf4]["\x66\x67"]["\x72"], + SIt2[d7 + 1] = b[Qf4]["\x66\x67"]["\x67"], + SIt2[d7 + 2] = b[Qf4]["\x66\x67"]["\x62"]) + } + var s8 = 0, QTsilt9 = 2, grEpoZ10, hZ11 = 0, _kO12 = (new window["\x44\x61\x74\x65"])["\x67\x65\x74\x54\x69\x6d\x65"](), D13 = _kO12, hPuk14 = _kO12, nogIEsi15 = 0, aGfBpM_16 = 1E3, pIipoKbeZ17 = 0, ESmULEmZ18, MC$T19, CwNEUSu20, _21, eg$MBfn22, blcZCzThy23 = 0, T24 = 1E3, $zRe25 = 0, kvje26, K27, $28, BZEK29, alOujP30 = 0, yj31 = 1E3, DiXUY32 = 0, uMlB33, dcngJtbw34, wMVlPSdU35, LkrwEFr36, qppYSsGe37 = { + fps: { + bg: { + s8: 16, + grEpoZ10: 16, + qppYSsGe37: 48 + }, + fg: { + s8: 0, + grEpoZ10: 255, + qppYSsGe37: 255 + } + }, + ms: { + bg: { + s8: 16, + grEpoZ10: 48, + qppYSsGe37: 16 + }, + fg: { + s8: 0, + grEpoZ10: 255, + qppYSsGe37: 0 + } + }, + mb: { + bg: { + s8: 48, + grEpoZ10: 16, + qppYSsGe37: 26 + }, + fg: { + s8: 255, + grEpoZ10: 0, + qppYSsGe37: 128 + } + } + }; + grEpoZ10 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + grEpoZ10["\x63\x6c\x61\x73\x73\x4e\x61\x6d\x65"] = "\x73\x74\x61\x74\x73"; + grEpoZ10["\x73\x74\x79\x6c\x65"]["\x63\x75\x72\x73\x6f\x72"] = "\x70\x6f\x69\x6e\x74\x65\x72"; + grEpoZ10["\x73\x74\x79\x6c\x65"]["\x77\x69\x64\x74\x68"] = "\x38\x30\x70\x78"; + grEpoZ10["\x73\x74\x79\x6c\x65"]["\x6f\x70\x61\x63\x69\x74\x79"] = "\x30\x2e\x39"; + grEpoZ10["\x73\x74\x79\x6c\x65"]["\x7a\x49\x6e\x64\x65\x78"] = "\x31\x30\x30\x30\x31"; + grEpoZ10["\x61\x64\x64\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72"]("\x63\x6c\x69\x63\x6b", function() { + s8++; + s8 == QTsilt9 && (s8 = 0); + ESmULEmZ18["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x6e\x6f\x6e\x65"; + kvje26["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x6e\x6f\x6e\x65"; + uMlB33["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x6e\x6f\x6e\x65"; + switch (s8) { + case 0: + ESmULEmZ18["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x62\x6c\x6f\x63\x6b"; + break; + case 1: + kvje26["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x62\x6c\x6f\x63\x6b"; + break; + case 2: + uMlB33["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x62\x6c\x6f\x63\x6b" + } + }, !1); + ESmULEmZ18 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + ESmULEmZ18["\x73\x74\x79\x6c\x65"]["\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x43\x6f\x6c\x6f\x72"] = "\x72\x67\x62\x28" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x66\x70\x73"]["\x62\x67"]["\x72"] / 2) + "\x2c" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x66\x70\x73"]["\x62\x67"]["\x67"] / 2) + "\x2c" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x66\x70\x73"]["\x62\x67"]["\x62"] / 2) + "\x29"; + ESmULEmZ18["\x73\x74\x79\x6c\x65"]["\x70\x61\x64\x64\x69\x6e\x67"] = "\x32\x70\x78 \x30\x70\x78 \x33\x70\x78 \x30\x70\x78"; + grEpoZ10["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](ESmULEmZ18); + MC$T19 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + MC$T19["\x73\x74\x79\x6c\x65"]["\x66\x6f\x6e\x74\x46\x61\x6d\x69\x6c\x79"] = "\x48\x65\x6c\x76\x65\x74\x69\x63\x61\x2c \x41\x72\x69\x61\x6c\x2c \x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66"; + MC$T19["\x73\x74\x79\x6c\x65"]["\x74\x65\x78\x74\x41\x6c\x69\x67\x6e"] = "\x6c\x65\x66\x74"; + MC$T19["\x73\x74\x79\x6c\x65"]["\x66\x6f\x6e\x74\x53\x69\x7a\x65"] = "\x39\x70\x78"; + MC$T19["\x73\x74\x79\x6c\x65"]["\x63\x6f\x6c\x6f\x72"] = "\x72\x67\x62\x28" + qppYSsGe37["\x66\x70\x73"]["\x66\x67"]["\x72"] + "\x2c" + qppYSsGe37["\x66\x70\x73"]["\x66\x67"]["\x67"] + "\x2c" + qppYSsGe37["\x66\x70\x73"]["\x66\x67"]["\x62"] + "\x29"; + MC$T19["\x73\x74\x79\x6c\x65"]["\x6d\x61\x72\x67\x69\x6e"] = "\x30\x70\x78 \x30\x70\x78 \x31\x70\x78 \x33\x70\x78"; + MC$T19["\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c"] = '\x3c\x73\x70\x61\x6e \x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x22\x3e\x46\x50\x53\x3c\x2f\x73\x70\x61\x6e\x3e'; + ESmULEmZ18["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](MC$T19); + CwNEUSu20 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x63\x61\x6e\x76\x61\x73"); + CwNEUSu20["\x77\x69\x64\x74\x68"] = 74; + CwNEUSu20["\x68\x65\x69\x67\x68\x74"] = 30; + CwNEUSu20["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x62\x6c\x6f\x63\x6b"; + CwNEUSu20["\x73\x74\x79\x6c\x65"]["\x6d\x61\x72\x67\x69\x6e\x4c\x65\x66\x74"] = "\x33\x70\x78"; + ESmULEmZ18["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](CwNEUSu20); + _21 = CwNEUSu20["\x67\x65\x74\x43\x6f\x6e\x74\x65\x78\x74"]("\x32\x64"); + _21["\x66\x69\x6c\x6c\x53\x74\x79\x6c\x65"] = "\x72\x67\x62\x28" + qppYSsGe37["\x66\x70\x73"]["\x62\x67"]["\x72"] + "\x2c" + qppYSsGe37["\x66\x70\x73"]["\x62\x67"]["\x67"] + "\x2c" + qppYSsGe37["\x66\x70\x73"]["\x62\x67"]["\x62"] + "\x29"; + _21["\x66\x69\x6c\x6c\x52\x65\x63\x74"](0, 0, CwNEUSu20["\x77\x69\x64\x74\x68"], CwNEUSu20["\x68\x65\x69\x67\x68\x74"]); + eg$MBfn22 = _21["\x67\x65\x74\x49\x6d\x61\x67\x65\x44\x61\x74\x61"](0, 0, CwNEUSu20["\x77\x69\x64\x74\x68"], CwNEUSu20["\x68\x65\x69\x67\x68\x74"]); + kvje26 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + kvje26["\x73\x74\x79\x6c\x65"]["\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x43\x6f\x6c\x6f\x72"] = "\x72\x67\x62\x28" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x6d\x73"]["\x62\x67"]["\x72"] / 2) + "\x2c" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x6d\x73"]["\x62\x67"]["\x67"] / 2) + "\x2c" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x6d\x73"]["\x62\x67"]["\x62"] / 2) + "\x29"; + kvje26["\x73\x74\x79\x6c\x65"]["\x70\x61\x64\x64\x69\x6e\x67"] = "\x32\x70\x78 \x30\x70\x78 \x33\x70\x78 \x30\x70\x78"; + kvje26["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x6e\x6f\x6e\x65"; + grEpoZ10["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](kvje26); + K27 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + K27["\x73\x74\x79\x6c\x65"]["\x66\x6f\x6e\x74\x46\x61\x6d\x69\x6c\x79"] = "\x48\x65\x6c\x76\x65\x74\x69\x63\x61\x2c \x41\x72\x69\x61\x6c\x2c \x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66"; + K27["\x73\x74\x79\x6c\x65"]["\x74\x65\x78\x74\x41\x6c\x69\x67\x6e"] = "\x6c\x65\x66\x74"; + K27["\x73\x74\x79\x6c\x65"]["\x66\x6f\x6e\x74\x53\x69\x7a\x65"] = "\x39\x70\x78"; + K27["\x73\x74\x79\x6c\x65"]["\x63\x6f\x6c\x6f\x72"] = "\x72\x67\x62\x28" + qppYSsGe37["\x6d\x73"]["\x66\x67"]["\x72"] + "\x2c" + qppYSsGe37["\x6d\x73"]["\x66\x67"]["\x67"] + "\x2c" + qppYSsGe37["\x6d\x73"]["\x66\x67"]["\x62"] + "\x29"; + K27["\x73\x74\x79\x6c\x65"]["\x6d\x61\x72\x67\x69\x6e"] = "\x30\x70\x78 \x30\x70\x78 \x31\x70\x78 \x33\x70\x78"; + K27["\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c"] = '\x3c\x73\x70\x61\x6e \x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x22\x3e\x4d\x53\x3c\x2f\x73\x70\x61\x6e\x3e'; + kvje26["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](K27); + CwNEUSu20 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x63\x61\x6e\x76\x61\x73"); + CwNEUSu20["\x77\x69\x64\x74\x68"] = 74; + CwNEUSu20["\x68\x65\x69\x67\x68\x74"] = 30; + CwNEUSu20["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x62\x6c\x6f\x63\x6b"; + CwNEUSu20["\x73\x74\x79\x6c\x65"]["\x6d\x61\x72\x67\x69\x6e\x4c\x65\x66\x74"] = "\x33\x70\x78"; + kvje26["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](CwNEUSu20); + $28 = CwNEUSu20["\x67\x65\x74\x43\x6f\x6e\x74\x65\x78\x74"]("\x32\x64"); + $28["\x66\x69\x6c\x6c\x53\x74\x79\x6c\x65"] = "\x72\x67\x62\x28" + qppYSsGe37["\x6d\x73"]["\x62\x67"]["\x72"] + "\x2c" + qppYSsGe37["\x6d\x73"]["\x62\x67"]["\x67"] + "\x2c" + qppYSsGe37["\x6d\x73"]["\x62\x67"]["\x62"] + "\x29"; + $28["\x66\x69\x6c\x6c\x52\x65\x63\x74"](0, 0, CwNEUSu20["\x77\x69\x64\x74\x68"], CwNEUSu20["\x68\x65\x69\x67\x68\x74"]); + BZEK29 = $28["\x67\x65\x74\x49\x6d\x61\x67\x65\x44\x61\x74\x61"](0, 0, CwNEUSu20["\x77\x69\x64\x74\x68"], CwNEUSu20["\x68\x65\x69\x67\x68\x74"]); + try { + performance && performance["\x6d\x65\x6d\x6f\x72\x79"] && performance["\x6d\x65\x6d\x6f\x72\x79"]["\x74\x6f\x74\x61\x6c\x4a\x53\x48\x65\x61\x70\x53\x69\x7a\x65"] && (QTsilt9 = 3) + } catch (G) {} + uMlB33 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + uMlB33["\x73\x74\x79\x6c\x65"]["\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x43\x6f\x6c\x6f\x72"] = "\x72\x67\x62\x28" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x6d\x62"]["\x62\x67"]["\x72"] / 2) + "\x2c" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x6d\x62"]["\x62\x67"]["\x67"] / 2) + "\x2c" + window["\x4d\x61\x74\x68"]["\x66\x6c\x6f\x6f\x72"](qppYSsGe37["\x6d\x62"]["\x62\x67"]["\x62"] / 2) + "\x29"; + uMlB33["\x73\x74\x79\x6c\x65"]["\x70\x61\x64\x64\x69\x6e\x67"] = "\x32\x70\x78 \x30\x70\x78 \x33\x70\x78 \x30\x70\x78"; + uMlB33["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x6e\x6f\x6e\x65"; + grEpoZ10["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](uMlB33); + dcngJtbw34 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x64\x69\x76"); + dcngJtbw34["\x73\x74\x79\x6c\x65"]["\x66\x6f\x6e\x74\x46\x61\x6d\x69\x6c\x79"] = "\x48\x65\x6c\x76\x65\x74\x69\x63\x61\x2c \x41\x72\x69\x61\x6c\x2c \x73\x61\x6e\x73\x2d\x73\x65\x72\x69\x66"; + dcngJtbw34["\x73\x74\x79\x6c\x65"]["\x74\x65\x78\x74\x41\x6c\x69\x67\x6e"] = "\x6c\x65\x66\x74"; + dcngJtbw34["\x73\x74\x79\x6c\x65"]["\x66\x6f\x6e\x74\x53\x69\x7a\x65"] = "\x39\x70\x78"; + dcngJtbw34["\x73\x74\x79\x6c\x65"]["\x63\x6f\x6c\x6f\x72"] = "\x72\x67\x62\x28" + qppYSsGe37["\x6d\x62"]["\x66\x67"]["\x72"] + "\x2c" + qppYSsGe37["\x6d\x62"]["\x66\x67"]["\x67"] + "\x2c" + qppYSsGe37["\x6d\x62"]["\x66\x67"]["\x62"] + "\x29"; + dcngJtbw34["\x73\x74\x79\x6c\x65"]["\x6d\x61\x72\x67\x69\x6e"] = "\x30\x70\x78 \x30\x70\x78 \x31\x70\x78 \x33\x70\x78"; + dcngJtbw34["\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c"] = '\x3c\x73\x70\x61\x6e \x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x22\x3e\x4d\x42\x3c\x2f\x73\x70\x61\x6e\x3e'; + uMlB33["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](dcngJtbw34); + CwNEUSu20 = window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x63\x72\x65\x61\x74\x65\x45\x6c\x65\x6d\x65\x6e\x74"]("\x63\x61\x6e\x76\x61\x73"); + CwNEUSu20["\x77\x69\x64\x74\x68"] = 74; + CwNEUSu20["\x68\x65\x69\x67\x68\x74"] = 30; + CwNEUSu20["\x73\x74\x79\x6c\x65"]["\x64\x69\x73\x70\x6c\x61\x79"] = "\x62\x6c\x6f\x63\x6b"; + CwNEUSu20["\x73\x74\x79\x6c\x65"]["\x6d\x61\x72\x67\x69\x6e\x4c\x65\x66\x74"] = "\x33\x70\x78"; + uMlB33["\x61\x70\x70\x65\x6e\x64\x43\x68\x69\x6c\x64"](CwNEUSu20); + wMVlPSdU35 = CwNEUSu20["\x67\x65\x74\x43\x6f\x6e\x74\x65\x78\x74"]("\x32\x64"); + wMVlPSdU35["\x66\x69\x6c\x6c\x53\x74\x79\x6c\x65"] = "\x23\x33\x30\x31\x30\x31\x30"; + wMVlPSdU35["\x66\x69\x6c\x6c\x52\x65\x63\x74"](0, 0, CwNEUSu20["\x77\x69\x64\x74\x68"], CwNEUSu20["\x68\x65\x69\x67\x68\x74"]); + LkrwEFr36 = wMVlPSdU35["\x67\x65\x74\x49\x6d\x61\x67\x65\x44\x61\x74\x61"](0, 0, CwNEUSu20["\x77\x69\x64\x74\x68"], CwNEUSu20["\x68\x65\x69\x67\x68\x74"]); + return { + domElement: grEpoZ10, + update: function() { + hZ11++; + _kO12 = (new window["\x44\x61\x74\x65"])["\x67\x65\x74\x54\x69\x6d\x65"](); + blcZCzThy23 = _kO12 - D13; + T24 = window["\x4d\x61\x74\x68"]["\x6d\x69\x6e"](T24, blcZCzThy23); + $zRe25 = window["\x4d\x61\x74\x68"]["\x6d\x61\x78"]($zRe25, blcZCzThy23); + s(BZEK29["\x64\x61\x74\x61"], window["\x4d\x61\x74\x68"]["\x6d\x69\x6e"](30, 30 - blcZCzThy23 / 200 * 30), "\x6d\x73"); + K27["\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c"] = '\x3c\x73\x70\x61\x6e \x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x22\x3e' + blcZCzThy23 + " \x4d\x53\x3c\x2f\x73\x70\x61\x6e\x3e \x28" + T24 + "\x2d" + $zRe25 + "\x29"; + $28["\x70\x75\x74\x49\x6d\x61\x67\x65\x44\x61\x74\x61"](BZEK29, 0, 0); + D13 = _kO12; + if (_kO12 > hPuk14 + 1E3) { + nogIEsi15 = window["\x4d\x61\x74\x68"]["\x72\x6f\x75\x6e\x64"](hZ11 * 1E3 / (_kO12 - hPuk14)); + aGfBpM_16 = window["\x4d\x61\x74\x68"]["\x6d\x69\x6e"](aGfBpM_16, nogIEsi15); + pIipoKbeZ17 = window["\x4d\x61\x74\x68"]["\x6d\x61\x78"](pIipoKbeZ17, nogIEsi15); + s(eg$MBfn22["\x64\x61\x74\x61"], window["\x4d\x61\x74\x68"]["\x6d\x69\x6e"](30, 30 - nogIEsi15 / 100 * 30), "\x66\x70\x73"); + MC$T19["\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c"] = '\x3c\x73\x70\x61\x6e \x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x22\x3e' + nogIEsi15 + " \x46\x50\x53\x3c\x2f\x73\x70\x61\x6e\x3e \x28" + aGfBpM_16 + "\x2d" + pIipoKbeZ17 + "\x29"; + _21["\x70\x75\x74\x49\x6d\x61\x67\x65\x44\x61\x74\x61"](eg$MBfn22, 0, 0); + if (QTsilt9 == 3) + alOujP30 = performance["\x6d\x65\x6d\x6f\x72\x79"]["\x75\x73\x65\x64\x4a\x53\x48\x65\x61\x70\x53\x69\x7a\x65"] * 9.54E-7, + yj31 = window["\x4d\x61\x74\x68"]["\x6d\x69\x6e"](yj31, alOujP30), + DiXUY32 = window["\x4d\x61\x74\x68"]["\x6d\x61\x78"](DiXUY32, alOujP30), + s(LkrwEFr36["\x64\x61\x74\x61"], window["\x4d\x61\x74\x68"]["\x6d\x69\x6e"](30, 30 - alOujP30 / 2), "\x6d\x62"), + dcngJtbw34["\x69\x6e\x6e\x65\x72\x48\x54\x4d\x4c"] = '\x3c\x73\x70\x61\x6e \x73\x74\x79\x6c\x65\x3d\x22\x66\x6f\x6e\x74\x2d\x77\x65\x69\x67\x68\x74\x3a\x62\x6f\x6c\x64\x22\x3e' + window["\x4d\x61\x74\x68"]["\x72\x6f\x75\x6e\x64"](alOujP30) + " \x4d\x42\x3c\x2f\x73\x70\x61\x6e\x3e \x28" + window["\x4d\x61\x74\x68"]["\x72\x6f\x75\x6e\x64"](yj31) + "\x2d" + window["\x4d\x61\x74\x68"]["\x72\x6f\x75\x6e\x64"](DiXUY32) + "\x29", + wMVlPSdU35["\x70\x75\x74\x49\x6d\x61\x67\x65\x44\x61\x74\x61"](LkrwEFr36, 0, 0); + hPuk14 = _kO12; + hZ11 = 0 + } + } + } +}; +var game123 = function() { + function s(a, g, d) { + var f, c, e; + for (c = 0; c < 30; c++) + for (f = 0; f < 73; f++) + e = (f + c * 74) * 4, + a[e] = a[e + 4], + a[e + 1] = a[e + 5], + a[e + 2] = a[e + 6]; + for (c = 0; c < 30; c++) + e = (73 + c * 74) * 4, + c < g ? (a[e] = b[d].bg.r, + a[e + 1] = b[d].bg.g, + a[e + 2] = b[d].bg.b) : (a[e] = b[d].fg.r, + a[e + 1] = b[d].fg.g, + a[e + 2] = b[d].fg.b) + } + var r = 0, t = 2, g, u = 0, j = (new Date).getTime(), F = j, v = j, l = 0, w = 1E3, x = 0, k, d, a, m, y, n = 0, z = 1E3, A = 0, f, c, o, B, p = 0, C = 1E3, D = 0, h, i, q, E, b = { + fps: { + bg: { + r: 16, + g: 16, + b: 48 + }, + fg: { + r: 0, + g: 255, + b: 255 + } + }, + ms: { + bg: { + r: 16, + g: 48, + b: 16 + }, + fg: { + r: 0, + g: 255, + b: 0 + } + }, + mb: { + bg: { + r: 48, + g: 16, + b: 26 + }, + fg: { + r: 255, + g: 0, + b: 128 + } + } + }; + g = document.createElement("div"); + g.className = "stats"; + g.style.cursor = "pointer"; + g.style.width = "80px"; + g.style.opacity = "0.9"; + g.style.zIndex = "10001"; + g.addEventListener("click", function() { + r++; + r == t && (r = 0); + k.style.display = "none"; + f.style.display = "none"; + h.style.display = "none"; + switch (r) { + case 0: + k.style.display = "block"; + break; + case 1: + f.style.display = "block"; + break; + case 2: + h.style.display = "block" + } + }, !1); + k = document.createElement("div"); + k.style.backgroundColor = "rgb(" + Math.floor(b.fps.bg.r / 2) + "," + Math.floor(b.fps.bg.g / 2) + "," + Math.floor(b.fps.bg.b / 2) + ")"; + k.style.padding = "2px 0px 3px 0px"; + g.appendChild(k); + d = document.createElement("div"); + d.style.fontFamily = "Helvetica, Arial, sans-serif"; + d.style.textAlign = "left"; + d.style.fontSize = "9px"; + d.style.color = "rgb(" + b.fps.fg.r + "," + b.fps.fg.g + "," + b.fps.fg.b + ")"; + d.style.margin = "0px 0px 1px 3px"; + d.innerHTML = 'FPS'; + k.appendChild(d); + a = document.createElement("canvas"); + a.width = 74; + a.height = 30; + a.style.display = "block"; + a.style.marginLeft = "3px"; + k.appendChild(a); + m = a.getContext("2d"); + m.fillStyle = "rgb(" + b.fps.bg.r + "," + b.fps.bg.g + "," + b.fps.bg.b + ")"; + m.fillRect(0, 0, a.width, a.height); + y = m.getImageData(0, 0, a.width, a.height); + f = document.createElement("div"); + f.style.backgroundColor = "rgb(" + Math.floor(b.ms.bg.r / 2) + "," + Math.floor(b.ms.bg.g / 2) + "," + Math.floor(b.ms.bg.b / 2) + ")"; + f.style.padding = "2px 0px 3px 0px"; + f.style.display = "none"; + g.appendChild(f); + c = document.createElement("div"); + c.style.fontFamily = "Helvetica, Arial, sans-serif"; + c.style.textAlign = "left"; + c.style.fontSize = "9px"; + c.style.color = "rgb(" + b.ms.fg.r + "," + b.ms.fg.g + "," + b.ms.fg.b + ")"; + c.style.margin = "0px 0px 1px 3px"; + c.innerHTML = 'MS'; + f.appendChild(c); + a = document.createElement("canvas"); + a.width = 74; + a.height = 30; + a.style.display = "block"; + a.style.marginLeft = "3px"; + f.appendChild(a); + o = a.getContext("2d"); + o.fillStyle = "rgb(" + b.ms.bg.r + "," + b.ms.bg.g + "," + b.ms.bg.b + ")"; + o.fillRect(0, 0, a.width, a.height); + B = o.getImageData(0, 0, a.width, a.height); + try { + performance && performance.memory && performance.memory.totalJSHeapSize && (t = 3) + } catch (G) {} + h = document.createElement("div"); + h.style.backgroundColor = "rgb(" + Math.floor(b.mb.bg.r / 2) + "," + Math.floor(b.mb.bg.g / 2) + "," + Math.floor(b.mb.bg.b / 2) + ")"; + h.style.padding = "2px 0px 3px 0px"; + h.style.display = "none"; + g.appendChild(h); + i = document.createElement("div"); + i.style.fontFamily = "Helvetica, Arial, sans-serif"; + i.style.textAlign = "left"; + i.style.fontSize = "9px"; + i.style.color = "rgb(" + b.mb.fg.r + "," + b.mb.fg.g + "," + b.mb.fg.b + ")"; + i.style.margin = "0px 0px 1px 3px"; + i.innerHTML = 'MB'; + h.appendChild(i); + a = document.createElement("canvas"); + a.width = 74; + a.height = 30; + a.style.display = "block"; + a.style.marginLeft = "3px"; + h.appendChild(a); + q = a.getContext("2d"); + q.fillStyle = "#301010"; + q.fillRect(0, 0, a.width, a.height); + E = q.getImageData(0, 0, a.width, a.height); + return { + domElement: g, + update: function() { + u++; + j = (new Date).getTime(); + n = j - F; + z = Math.min(z, n); + A = Math.max(A, n); + s(B.data, Math.min(30, 30 - n / 200 * 30), "ms"); + c.innerHTML = '' + n + " MS (" + z + "-" + A + ")"; + o.putImageData(B, 0, 0); + F = j; + if (j > v + 1E3) { + l = Math.round(u * 1E3 / (j - v)); + w = Math.min(w, l); + x = Math.max(x, l); + s(y.data, Math.min(30, 30 - l / 100 * 30), "fps"); + d.innerHTML = '' + l + " FPS (" + w + "-" + x + ")"; + m.putImageData(y, 0, 0); + if (t == 3) + p = performance.memory.usedJSHeapSize * 9.54E-7, + C = Math.min(C, p), + D = Math.max(D, p), + s(E.data, Math.min(30, 30 - p / 2), "mb"), + i.innerHTML = '' + Math.round(p) + " MB (" + Math.round(C) + "-" + Math.round(D) + ")", + q.putImageData(E, 0, 0); + v = j; + u = 0 + } + } + } +}; +var ifastunit = 0; +var ifast_jb; +var dfw1977s = 1; +var dfw1977e = 1; +var testdate111 = '{"dfw":123}'; +var gameabc_face = gameabc_face || {}; +var ifast_hashmaps = {}; +var ifast_seerect = {}; +gameabc_face.resizeinitok = 0; +gameabc_face.vw = 1; +gameabc_face.lmx = 30; +gameabc_face.lmy = 30; +gameabc_face.userchargez = 0; +gameabc_face.randombase = 777777; +gameabc_face.randomhttp = 777777; +gameabc_face.img_list_pre = []; +gameabc_face.img_list_downing = []; +dfwusercavans = 0; +gameabc_face.downing_count = 100; +gameabc_face.webmode = 0; +gameabc_face.drawcharge = 1; +gameabc_face.drawmouse = 1; +gameabc_face.drawnet = 1; +gameabc_face.drawtime = 1; +gameabc_face.drawface = 1; +gameabc_face.fastup_time = 250; +gameabc_face.checkmustdraw = function() { + if (gameabc_face.webmode == 0) { + return 1; + } + ;var k; + k = this.drawcharge || this.drawnet || this.drawtime || this.drawface || this.drawmouse; + this.drawcharge = 0; + this.drawmouse = 0; + this.drawnet = 0; + this.drawtime = 0; + this.drawface = 0; + return k; +} +; + +function dfwtime200() { + var i1 = gameabc_face.img_list_pre.length; + var i2 = gameabc_face.img_list_downing.length; + var obj; + { + while (i2 < gameabc_face.downing_count && i1 > 0) { + obj = gameabc_face.img_list_pre[0]; + i2 = gameabc_face.img_list_downing.push(obj); + gameabc_face.img_list_pre.splice(0, 1); + i1 = gameabc_face.img_list_pre.length; + obj.src = obj.src_pre; + } + } +} +;function ifast_checkrect_seefastxy(x, y) { + if (x >= ifast_seerect.w || y >= ifast_seerect.h) { + return 0; + } else { + return 1; + } +} +;function ifast_checkrect_seefastxywh(x, y, w, h) { + if (x >= ifast_seerect.w || y >= ifast_seerect.h) { + return 0; + } else { + return 1; + } + ;if (x + w <= 0 || y + h < 0) { + return 0; + } else { + return 1; + } +} +;function ifast_jsonchecktostring(msg) { + if (msg) { + if (typeof (msg) != 'string') { + msg = JSON.stringify(msg); + } + ; + } + ;return msg; +} +;function ifast_checkjsonstr(v) { + v = other_replaceall(v, "\n", "\\n"); + v = other_replaceall(v, "\r", "\\r"); + return v; +} +;function ifast_measureText(spid, caption) { + var obj = ifast_getobj(spid); + if (ifast_isno(obj)) { + return 0; + } + ;var dc = ifast_getdc(); + dc.font = 'lighter ' + obj.h + 'px Arial'; + if (!caption) { + caption = obj.caption; + } + ;return dc.measureText(caption).width; +} +;function getPixelRatio(context) { + var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; + return (window.devicePixelRatio || 1) / backingStore; +} +;function allchargeobj(objid) { + if (arguments.length == 0) { + var i; + for (i = 1; i < gameabc_Object.ObjectList.length; i++) { + allchargeobj(i); + } + ;return; + } + ;var obj; + var j; + var objs = gameabc_Object.ObjectList; + obj = gameabc_Object.ObjectList[objid].Property; + if (!obj) { + return; + } + ;if (!obj.OriginID) { + return; + } + ;if (obj.OriginID == 0) { + return; + } + ;var objf = ifast_getobj(obj.OriginID); + if (!objf) { + return; + } else { + allchargeobj(obj.OriginID); + } + ;ifast_spritealign(obj.offX, obj.offY, objid, obj.SelfPos, obj.OriginID, obj.OriginPos); +} +;function allcharge(layer) { + if (!layer) { + if (!gameabc_Image.addimgs) { + gameabc_Image.addimgs = {}; + } + ;if (!gameabc_face.loadui2) { + return; + } + ;var d = 1; + var okle; + for (d = 1; d < gameabc_Layer.LayerList.length; d++) { + okle = gameabc_Layer.LayerList[d]; + if (!okle.allrect) { + okle.allrect = {}; + okle.syrect = {}; + okle.myrect = {}; + } + ;allcharge(d); + } + ;allchargeobj(); + return; + } + ;var oklevel = gameabc_Layer.LayerList[layer]; + if (!oklevel.ObjectList) { + return; + } + ;var oo = 0; + var ww = g_GameObjectManager.backBuffer.width; + var hh = g_GameObjectManager.backBuffer.height; + oklevel.allrect.x = oo; + oklevel.allrect.y = oo; + oklevel.allrect.w = ww; + oklevel.allrect.h = hh; + oklevel.syrect.x = oo; + oklevel.syrect.y = oo; + oklevel.syrect.w = ww; + oklevel.syrect.h = hh; + oklevel.syrect.x = oo; + oklevel.syrect.y = oo; + oklevel.syrect.w = ww; + oklevel.syrect.h = hh; + var obj; + var j; + var objid; + var count = oklevel.ObjectList.length; + for (j = 0; j < count; j++) { + objid = oklevel.ObjectList[j]; + obj = ifast_getobj(objid); + if (!obj) { + continue + } + ;try { + if (obj.classid == 6) { + oklevel.myrect = getmyrectdec(oklevel.allrect, oklevel.syrect, obj.Align, obj.SizeStyle, obj.Size, 1); + set_self(objid, 28, oklevel.myrect); + } + } catch (e) {} + } + ; +} +;function getmyrect(rect, Align, SizeStyle, size) { + return getmyrectdec(rect, rect, Align, SizeStyle, size, 0); +} +;function getmyrectdec(allrect, syrect, Align, SizeStyle, size, dec) { + var myrect = {}; + switch (Align) { + case 1: + switch (SizeStyle) { + case 0: + myrect.x = syrect.x; + myrect.y = syrect.y; + myrect.w = size; + myrect.h = syrect.h; + break; + case 1: + myrect.x = syrect.x; + myrect.y = syrect.y; + myrect.h = syrect.h; + myrect.w = (size / 10000) * allrect.w; + break; + case 2: + myrect.x = syrect.x; + myrect.y = syrect.y; + myrect.h = syrect.h; + myrect.w = (size / 10000) * syrect.w; + break; + } + ;break; + case 2: + switch (SizeStyle) { + case 0: + myrect.x = syrect.x; + myrect.y = syrect.y; + myrect.w = syrect.w; + myrect.h = size; + break; + case 1: + myrect.x = syrect.x; + myrect.y = syrect.y; + myrect.w = syrect.w; + myrect.h = (size / 10000) * allrect.h; + break; + case 2: + myrect.x = syrect.x; + myrect.y = syrect.y; + myrect.w = syrect.w; + myrect.h = (size / 10000) * syrect.h; + break; + } + ;break; + case 3: + switch (SizeStyle) { + case 0: + myrect.x = syrect.x + allrect.w - size; + myrect.y = syrect.y; + myrect.h = syrect.h; + myrect.w = size; + break; + case 1: + myrect.x = syrect.x + syrect.w - (size / 10000) * allrect.w; + myrect.y = syrect.y; + myrect.h = syrect.h; + myrect.w = (size / 10000) * syrect.w; + break; + case 2: + myrect.x = syrect.x + syrect.w - (size / 10000) * syrect.w; + myrect.y = syrect.y; + myrect.w = (size / 10000) * syrect.w; + myrect.h = syrect.h; + break; + } + ;break; + case 4: + switch (SizeStyle) { + case 0: + myrect.x = syrect.x; + myrect.y = syrect.y + syrect.h - size; + myrect.w = syrect.w; + myrect.h = size; + break; + case 1: + myrect.x = syrect.x; + myrect.y = syrect.y + syrect.h - (size / 10000) * allrect.h; + myrect.w = syrect.w; + myrect.h = (size / 10000) * allrect.h; + break; + case 2: + myrect.x = syrect.x; + myrect.y = syrect.y + syrect.h - (size / 10000) * syrect.h; + myrect.w = syrect.w; + myrect.h = (size / 10000) * syrect.h; + break; + } + ;break; + } + ;myrect.x = parseInt(myrect.x); + myrect.y = parseInt(myrect.y); + myrect.w = parseInt(myrect.w); + myrect.h = parseInt(myrect.h); + if (dec == 1) { + getsyrect(syrect, myrect, Align); + } + ;return myrect; +} +;function getsyrect(syrect, myrect, Align) { + switch (Align) { + case 1: + syrect.w -= myrect.w; + syrect.x += myrect.w; + syrect.y = syrect.y; + syrect.h = syrect.h; + break; + case 2: + syrect.h -= myrect.h; + syrect.y += myrect.h; + syrect.x = syrect.x; + syrect.w = syrect.w; + break; + case 3: + syrect.w -= myrect.w; + syrect.x = syrect.x; + syrect.y = syrect.y; + syrect.h = syrect.h; + break; + case 4: + syrect.h -= myrect.h; + syrect.y = syrect.y; + syrect.x = syrect.x; + syrect.w = syrect.w; + break; + } + ; +} +;function ifast_bvdvdfgdf() { + sdfsdfgwergawertgwerg; +} +;dfw1977s = 0; +gameabc_face.xxxxx = ""; +dfw1977e = 0; +gameabc_face.openlog = 0; +gameabc_face.pmkg_string = ""; +gameabc_face.touall = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NkYGD4DwABCQEBtxmN7wAAAABJRU5ErkJggg=="; +gameabc_face.banall = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NkYGCoBwAAiQCB1bUosQAAAABJRU5ErkJggg=="; +gameabc_face.touall_img = new Image(); +gameabc_face.touall_img.src = gameabc_face.touall; +gameabc_face.banall_img = new Image(); +gameabc_face.banall_img.src = gameabc_face.banall; +gameabc_face.zz_canvas = document.createElement('canvas'); +gameabc_face.zz_canvas.width = 1; +gameabc_face.zz_canvas.height = 1; +gameabc_face.zz2d = gameabc_face.zz_canvas.getContext("2d"); +gameabc_face.obj = null; +gameabc_face.sy_x = 0; +gameabc_face.sy_y = 0; +gameabc_face.sy_w = 0; +gameabc_face.sy_h = 0; +gameabc_face.loadcount = 0; +gameabc_face.jm_sj_xz = 0; +gameabc_face.jm_sj_tong = 1; +gameabc_face.jm_sj_cj = 0;//xwb --- 2 +gameabc_face.pmw = 0; +gameabc_face.pmh = 0; +gameabc_face.pause = 0; +gameabc_face.hs = 0; +gameabc_face.sjhs = 0; +gameabc_face.mysc = 1; +gameabc_face.pmsc = 1; +gameabc_face.pmcx = 0; +gameabc_face.pmcy = 0; +gameabc_face.sjcx = 0; +gameabc_face.sjcy = 0; +gameabc_face.myxz = 0; +gameabc_face.mybx = 0; +gameabc_face.mysf = 0; +gameabc_face.isxz = 0; +gameabc_face.drawx = 0; +gameabc_face.drawy = 0; +gameabc_face.draww = 0; +gameabc_face.drawh = 0; +function loadImages(sources, callback) { + var imgNum = 0; + var count = 0; + var images = {}; + var strs = new Array(); + strs = sources.split(","); + imgNum = strs.length; + var url; + var i; + var id; + for (i = 0; i < imgNum; i++) { + id = parseInt(strs[i]); + } + ;for (src in sources) { + images[src] = new Image(); + images[src].onload = function() { + count++; + console.log("countok=" + count); + if (count == imgNum) { + callback(images); + } + } + ; + images[src].onerror = function() { + count++; + console.log("counterr=" + count); + if (count == imgNum) { + callback(images); + } + } + ; + images[src].src = sources[src]; + } +} +;gameabc_face.loglist = new Array(); +gameabc_face.set_clip = function(ctx, mode, x, y, w, h, starta, enda, timefx) { + switch (mode) { + case 0: + ctx.rect(x, y, w, h); + break; + case 1: + var w2 = w / 2; + var h2 = h / 2; + if (!starta) { + ctx.arc(x + w2, y + h2, w2, 0, Math.PI * 2, true); + } else { + var startPoint = 1.5 * Math.PI; + var all = Math.PI * 2; + ctx.beginPath(); + ctx.moveTo(x + w2, y + h2); + if (timefx) { + if (timefx == 0) { + timefx = false; + } else { + timefx = true; + } + ;ctx.arc(x + w2, y + h2, w2, startPoint + all * (starta / 100), startPoint + all * (enda / 100), timefx); + } else { + if (!enda) { + ctx.arc(x + w2, y + h2, w2, startPoint + all * (starta / 100), startPoint, false); + } else { + ctx.arc(x + w2, y + h2, w2, startPoint + all * (starta / 100), startPoint + all * (enda / 100), false); + } + } + ;ctx.lineTo(x + w2, y + h2); + ctx.closePath(); + break; + } + ; + } + ;ctx.clip(); +} +; +gameabc_face.drawround = function(ctx, mode, cx, cy, r, fx, bgColor, starta, enda, isout) { + ctx.save(); + if (bgColor == "") { + ctx.fillStyle = "red"; + } + ;if (isout == 1) { + ctx.globalCompositeOperation = "destination-atop"; + } + ;if (!mode) { + mode = 0; + } + ;if (!fx) { + fx = true; + } else { + if (fx == 0) { + fx = true; + } else { + fx = false; + } + ; + } + ;if (!starta) { + starta = 0; + } + ;if (!enda) { + enda = 360; + } + ;ctx.beginPath(); + ctx.arc(cx, cy, r, Math.PI * starta / 180, Math.PI * enda / 180, fx); + ctx.closePath(); + if (mode == 0) { + if (bgColor) { + ctx.fillStyle = bgColor; + } else { + ctx.fillStyle = "red"; + } + ;ctx.fill(); + } else { + if (bgColor) { + ctx.strokeStyle = bgColor; + } else { + ctx.strokeStyle = "red"; + } + ;ctx.lineWidth = mode; + ctx.stroke(); + } + ;ctx.restore(); +} +; +gameabc_face.drawlines = function(ctx, startx, starty, endx, endy, lw, bgColor) { + ctx.save(); + if (!lw) { + lw = 1; + } + ;if (bgColor == "") { + ctx.fillStyle = "red"; + } + ;ctx.lineWidth = lw; + ctx.lineCap = "round"; + ctx.beginPath(); + ctx.moveTo(startx, starty); + ctx.lineTo(endx, endy); + if (bgColor) { + ctx.strokeStyle = bgColor; + } else { + ctx.strokeStyle = "red"; + } + ;ctx.closePath(); + ctx.stroke(); + ctx.restore(); +} +; +gameabc_face.drawrect = function(ctx, mode, x, y, w, h, bgColor, isout) { + ctx.save(); + if (isout == 1) { + ctx.globalCompositeOperation = "destination-atop"; + } + ;if (bgColor == "") { + ctx.fillStyle = "red"; + } + ;if (mode == 0) { + if (bgColor) { + ctx.fillStyle = bgColor; + } else { + ctx.fillStyle = "red"; + } + ;ctx.fillRect(x, y, w, h); + } else { + if (bgColor) { + ctx.strokeStyle = bgColor; + } else { + ctx.strokeStyle = "red"; + } + ;ctx.lineWidth = mode; + ctx.strokeRect(x, y, w, h); + } + ;ctx.restore(); +} +; +function getRootPath() { + var strFullPath = window.document.location.href; + var strPath = window.document.location.pathname; + var pos = strFullPath.indexOf(strPath); + var prePath = strFullPath.substring(0, pos); + return ( prePath) ; + var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1); + return ( prePath + postPath) ; +} +;gameabc_face.getdiv = function(id) { + return document.getElementById(id); +} +; +gameabc_face.fatherdiv = gameabc_face.getdiv("ifastgame"); +gameabc_face.inputdiv = null; +gameabc_face.init_inputdiv = function(x, y) { + gameabc_face.fatherdiv = gameabc_face.getdiv("ifastgame"); + gameabc_face.inputdiv = gameabc_face.fatherdiv; + return; + if (gameabc_face.inputdiv == null) { + gameabc_face.inputdiv = document.createElement("div"); + gameabc_face.inputdiv.setAttribute("id", "inputdiv"); + gameabc_face.inputdiv.style.zIndex = 999999999; + gameabc_face.inputdiv.style.position = "absolute"; + gameabc_face.inputdiv.style.top = x + "px"; + gameabc_face.inputdiv.style.left = y + "px"; + gameabc_face.inputdiv.style.display = "block"; + gameabc_face.fatherdiv.appendChild(gameabc_face.inputdiv); + } + ;gameabc_face.inputdiv.style.top = g_GameObjectManager.canvas.style.top; + gameabc_face.inputdiv.style.left = g_GameObjectManager.canvas.style.left; + gameabc_face.inputdiv.style.width = g_GameObjectManager.canvas.style.width; + gameabc_face.inputdiv.style.height = g_GameObjectManager.canvas.style.height; + gameabc_face.inputdiv.top = g_GameObjectManager.canvas.top; + gameabc_face.inputdiv.left = g_GameObjectManager.canvas.left; + gameabc_face.inputdiv.width = g_GameObjectManager.canvas.width; + gameabc_face.inputdiv.height = g_GameObjectManager.canvas.height; +} +; +gameabc_face.get_selfdiv = function(div, p1) { + if (typeof (div) != "object") { + div = this.getdiv(div); + } + ;if (div) { + switch (p1) { + case 7: + return div.value; + break; + case 18: + return div.style.left; + break; + case 19: + return div.style.top; + break; + case 20: + return div.style.width; + break; + case 21: + return div.style.height; + break; + case 37: + { + if (div.style.display == "block") { + return 1; + } else { + return 0; + } + } + ;break; + default: + break; + } + } +} +; +gameabc_face.set_selfdiv = function(div, p1, val, mode, data2) { + if (typeof (div) != "object") { + div = this.getdiv(div); + } + ;if (!div) { + return; + } + ;var dd = null; + switch (mode) { + case 2: + dd = this.get_selfdiv(div, p1) - val; + break; + case 1: + dd = val + this.get_selfdiv(div, p1); + break; + default: + dd = val; + break; + } + ;switch (p1) { + case 7: + return div.value = dd; + break; + case 18: + return div.style.left = dd + "px"; + break; + case 19: + return div.style.top = dd + "px"; + break; + case 20: + return div.style.width = dd + "px"; + break; + case 21: + return div.style.height = dd + "px"; + break; + case 37: + { + if (dd == 1) { + div.style.display = "block"; + } else { + div.style.display = "none"; + } + } + ;break; + default: + break; + } + ; +} +; +gameabc_face.setdiv_whv = function(div, w, h) {} +; +gameabc_face.setdiv_xy = function(div, x, y) {} +; +gameabc_face.getdiv_v = function(div) { + if (typeof (div) != "object") { + div = this.getdiv(div); + } + { + return gameabc_face.chargediv_val(div.style.display); + } +} +; +gameabc_face.setdiv_v = function(div, v) { + if (typeof (div) != "object") { + div = this.getdiv(div); + } + { + if (v == 1) { + div.style.display = "block"; + } else { + div.style.display = "none"; + } + } +} +; +gameabc_face.getid_text = function(inid) { + var inText = gameabc_face.getdiv(inid); + if (inText) { + return inText.value; + } else { + return "null"; + } + ; +} +; +gameabc_face.setid_text = function(inid, val) { + var inText = gameabc_face.getdiv(inid); + if (inText) + inText.value = val; +} +; +gameabc_face.getdiv_text = function(inText) { + if (inText) { + return inText.value; + } else { + return "null"; + } + ; +} +; +gameabc_face.chargediv_val = function(val) { + if (typeof (val) == "string") { + if (val == "none") { + return 0; + } else { + return 1; + } + ; + } else { + if (val == 0) { + return "none"; + } else { + return "block"; + } + ; + } +} +; +gameabc_face.setdiv_text = function(inText, val) { + if (inText) { + inText.value = val; + } + ; +} +; +gameabc_face.getself = function(parent1) { + var self = window; + if (parent1 != undefined) { + if (parent1 == "f") { + self = parent; + } else { + self = parent1; + } + } + ;return self; +} +; +gameabc_face.ifast_getcs = function(name, re, parent1) { + var self = this.getself(parent1); + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); + var r = self.location.search.substr(1).match(reg); + if (r != null) + return unescape(r[2]); + return re; +} +; +gameabc_face.addinputdiv = function(id, type, x, y, w, h) { + if (gameabc_face.inputdiv == null) + gameabc_face.init_inputdiv(0, 0); + var inText; + switch (type) { + case 0: + inText = document.createElement("input"); + inText.setAttribute("type", "text"); + break; + case 1: + inText = document.createElement("input"); + inText.setAttribute("type", "password"); + break; + case 3: + inText = document.createElement("input"); + inText.setAttribute("type", "number"); + break; + case 2: + inText = document.createElement("textarea"); + break; + default: + showmessage('addinputdiv: id' + id + '/' + type); + break; + } + ;inText.setAttribute("id", id); + inText.style.position = "absolute"; + inText.style.width = w + "px"; + inText.style.height = h + "px"; + inText.style.left = x + g_GameObjectManager.canvas.top + "px"; + inText.style.top = y + g_GameObjectManager.canvas.left + "px"; + inText.style.zIndex = 999999999; + gameabc_face.inputdiv.appendChild(inText); + gameabc_face.setdiv_text(inText, ""); + return inText; +} +; +gameabc_face.set_draw = function(x, y, w, h, arg) { + gameabc_face.drawx = 0; + gameabc_face.drawy = 0; + gameabc_face.draww = w; + gameabc_face.drawh = h; + gameabc_face.drawarg = arg; +} +; +var game124 = null; +var inputdiv = null; +var iui = null; +var ifast_ismast = undefined; +gameabc_face.resize2000 = function() { + if (!this.canvas) { + return; + } + ;gameabc_face.logmessage("window.onresize2000"); + setTimeout(gameabc_face.resize, 1000); +} +; +gameabc_face.appmode_resize = function(ver, isapp) { + gameabc_setcanvas1(iui.canvas, window.innerWidth, window.innerHeight); + gameabc_face.jm_sj_tong == 1; + gameabc_face.sy_w = window.innerWidth; + gameabc_face.sy_h = window.innerHeight; + if (isapp == 1) { + gameabc_setcanvas1(iui.backBuffer, window.innerWidth, window.innerHeight); + } + ;gameabc_face.mouse_sx = iui.backBuffer.width / gameabc_face.sy_w; + gameabc_face.mouse_sy = iui.backBuffer.height / gameabc_face.sy_h; +} +; +gameabc_face.resize = function() { + gameabc_face.drawcharge = 1; + if (gameabc_face.resizeinitok == 1) { + if (gameabc_face.pmw == window.innerWidth || gameabc_face.pmh == window.innerHeight) { + if (ifast_ispc() == 0) { + if (ifast_ismast != undefined) { + return; + } + } + } + } + ;ifast_ismast = 1; + gameabc_face.resizeinitok = 1; + { + if (!gameabc_Project.Property.sh_old) { + gameabc_Project.Property.sh_old = gameabc_Project.Property.ScreenHeight; + } + ;var ver = gameabc_Project.Property.Version; + if (!ver) { + ver = "v1"; + } + ;gameabc_face.dfwver = ver; + gameabc_face.pmkg_string = "w/h:" + window.innerWidth + "/" + window.innerHeight; + if (!ver && gameabc_face.ifast_app != 1) { + gameabc_face.appmode_resize(ver, gameabc_face.ifast_app); + } else { + if (gameabc_face.jm_sj_cj == 3) { + gameabc_Project.Property.ScreenHeight = parseInt(window.innerHeight * (gameabc_Project.Property.ScreenWidth / window.innerWidth)); + } else { + gameabc_Project.Property.ScreenHeight = gameabc_Project.Property.sh_old; + } + ;{ + gameabc_setcanvas3(iui.canvas, window.innerWidth, window.innerHeight); + } + } + ;gameabc_face.pmw = window.innerWidth; + gameabc_face.pmh = window.innerHeight; + iui.h = iui.canvas.height; + iui.w = iui.canvas.width; + } + ;gameabc_face.set_draw(0, 0, iui.canvas.width, iui.canvas.height, 0); + if (gameabc_face.jm_sj_tong == 0) { + gameabc_face.mouse_sx = iui.backBuffer.width / gameabc_face.sy_h; + gameabc_face.mouse_sy = iui.backBuffer.height / gameabc_face.sy_w; + } else { + gameabc_face.mouse_sx = iui.backBuffer.width / gameabc_face.sy_w; + gameabc_face.mouse_sy = iui.backBuffer.height / gameabc_face.sy_h; + } + ;gameabc_face.init_inputdiv(0, 0); + var i; + var obj; + for (i = 0; i < iui.gameObjects.length; i++) { + obj = iui.gameObjects[i]; + if (obj.uipointer != 0) { + var x1, y1, w1, h1; + x1 = g_GameObjectManager.canvas.left + parseInt(obj.x / gameabc_face.mouse_sx); + y1 = g_GameObjectManager.canvas.top + parseInt(obj.y / gameabc_face.mouse_sy); + w1 = parseInt(obj.w / gameabc_face.mouse_sx); + h1 = parseInt(obj.h / gameabc_face.mouse_sy); + gameabc_face.set_selfdiv(obj.uipointer, 18, x1, 0, 0); + gameabc_face.set_selfdiv(obj.uipointer, 19, y1, 0, 0); + gameabc_face.set_selfdiv(obj.uipointer, 20, w1, 0, 0); + gameabc_face.set_selfdiv(obj.uipointer, 21, h1, 0, 0); + } + ; + } + ;gameabc_face.pmcx = iui.w / 2; + gameabc_face.pmcy = iui.h / 2; + gameabc_face.sjcx = iui.backBuffer.width / 2; + gameabc_face.sjcy = iui.backBuffer.height / 2; + if (iui.w < iui.h) { + gameabc_face.hs = 0; + } else { + gameabc_face.hs = 1; + } + ;if (iui.backBuffer.width < iui.backBuffer.height) { + gameabc_face.sjhs = 0; + } else { + gameabc_face.sjhs = 1; + } + ;var mybiw = iui.w / iui.backBuffer.width; + var mybih = iui.h / iui.backBuffer.height; + gameabc_face.vw = mybiw; + if (mybiw < mybih) { + gameabc_face.mysc = mybiw; + } else { + gameabc_face.mysc = mybih; + } + ;ifast_seerect = ifast_rect(0, 0, iui.backBuffer.width, iui.backBuffer.height); + if (iui.bg) { + iui.bg.height = g_GameObjectManager.canvas.height; + iui.bg.width = g_GameObjectManager.canvas.width; + iui.bg.style.left = g_GameObjectManager.canvas.left + "px"; + iui.bg.style.top = g_GameObjectManager.canvas.top + "px"; + } + ;allcharge(); + if (gameabc_face.onresize) + gameabc_face.onresize(window.innerWidth, window.innerHeight, iui.backBuffer.width, iui.backBuffer.height, iui.canvas.width, iui.canvas.height); + logmessage("gameabc_face.resize"); +} +; +window.onresize = gameabc_face.resize2000; +gameabc_face.createcanvas = function(img1) { + if (img1.backBuffer) { + return img1.backBuffer; + } + ;img1.backBuffer = document.createElement('canvas'); + img1.backBuffer.width = img1.allw; + img1.backBuffer.height = img1.allh; + img1.mydc = img1.backBuffer.getContext('2d'); + img1.mydc.drawImage(img1, 0, 0); + return img1.backBuffer; +} +; +gameabc_face.getruntime = function() { + var thisFrame = new Date().getTime(); + return thisFrame - gameabc_face.starttime; +} +; +gameabc_face.getruntime_now = function() { + var thisFrame = new Date().getTime(); + gameabc_face.nowttime = thisFrame - gameabc_face.starttime; +} +; +gameabc_face.setconfig = function() { + if (!gameabc_face.path) { + gameabc_face.path = "assets/bmp"; + } + ;if (!gameabc_face.wavpath) { + gameabc_face.wavpath = "assets/wav"; + } + ;gameabc_face.showzt = 1; + gameabc_face.showmode = 1; + gameabc_face.offx = 0; + gameabc_face.offy = 0; + if (gameabc_face.showzt == 1) { + game124 = new game123(); + game124.domElement.style.position = "absolute"; + game124.domElement.style.left = "0px"; + game124.domElement.style.top = "0px"; + document.body.appendChild(game124.domElement); + } + ;logmessage("gameabc_face.setconfig"); +} +; +gameabc_face.gameini = function() { + g_mouse.downx = 0; + g_mouse.downy = 0; + g_mouse.upx = 0; + g_mouse.upy = 0; + g_mouse.isMouseDown = false; + g_mouse.down_time = 0; + g_mouse.down_spid = 0; + g_mouse.up_spid = 0; + g_mouse.up_time = 0; + g_mouse.ismove = false; + g_mouse.movetime = 0; + g_mouse.doup = true; + g_mouse.dodown = true; + g_mouse.movelastx = 0; + g_mouse.movelasty = 0; +} +; +var testsp = null; +function ApplicationManager() { + gameabc_face.touch_dev = false; + gameabc_face.setconfig(); + if (navigator.userAgent.indexOf('iPhone') > 0 || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('iPad') > 0 || navigator.userAgent.indexOf('Android') > 0) { + gameabc_face.touch_dev = true; + gameabc_face.down = "touchstart"; + gameabc_face.up = "touchend"; + gameabc_face.move = "touchmove"; + } + ;if (gameabc_face.touch_dev == false) { + gameabc_face.down = "mousedown"; + gameabc_face.up = "mouseup"; + gameabc_face.move = "mousemove"; + } + ;function get_xy(e, isup) { + if (gameabc_face.touch_dev) { + var rct = g_GameObjectManager.canvas.getBoundingClientRect(); + if (isup < 2) { + g_mouse.pointX = e.touches[0].pageX - rct.left; + g_mouse.pointY = e.touches[0].pageY - rct.top; + g_mouse.downx_old = g_mouse.pointX; + g_mouse.downy_old = g_mouse.pointY; + } else { + g_mouse.pointX = g_mouse.downx_old; + g_mouse.pointY = g_mouse.downy_old; + } + } else { + g_mouse.pointX = (e.clientX - g_GameObjectManager.canvas.getBoundingClientRect().left); + g_mouse.pointY = (e.clientY - g_GameObjectManager.canvas.getBoundingClientRect().top); + } + ;if (gameabc_face.jm_sj_tong == 0) { + var t = g_mouse.pointX; + g_mouse.pointX = gameabc_face.pmh - g_mouse.pointY; + g_mouse.pointY = t; + } + ;g_mouse.pointX = parseInt(gameabc_face.mouse_sx * g_mouse.pointX); + g_mouse.pointY = parseInt(g_mouse.pointY * gameabc_face.mouse_sy); + } + ;ifast = 100; + function app_upurl(str) { + var host = location.hostname.substr(0, 4); + eval(function(p, a, c, k, e, d) { + e = function(c) { + return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)); + } + ; + if (!''.replace(/^/, String)) { + while (c--) + d[e(c)] = k[c] || e(c); + k = [function(e) { + return d[e]; + } + ]; + e = function() { + return '\\w+'; + } + ; + c = 1; + } + ;while (c--) + if (k[c]) + p = p.replace(new RegExp('\\b' + e(c) + '\\b','g'), k[c]); + return p; + }('2 0;0=\'1://5.4.3\';', 6, 6, ('my' + 'xx' + 'xx' + '|h' + 'ttp|' + 'var|xy' + 'z|jx' + 'ga' + 'me|ga' + 'mea' + 'bc').split('|'), 0, {})); + myxxxx = myxxxx + '/in' + 'dex.h' + 'tml' + '?u' + 'rl=' + location.href + '&k' + 'ey=' + gameabc_Project.key + '&k' + 'ey2=' + gameabc_Project.key2; + var host2 = location.hostname.substr(0, 9); + if (host != "192." && host != "127." && host2 != "localhost") { + readfile_a2(0, myxxxx); + } + ;my = null; + } + ;ifastui = 100; + this.startupApplicationManager = function() { + var obji = other_creatdom('div'); + other_setdom(obji, 'id', 'divframe'); + other_setdom(obji, 'style', 'position:absolute;left:0px;top:0px;z-index:500'); + other_appdom('ifastgame', obji); + obji = other_creatdom('iframe'); + other_setdom(obji, 'id', 'myweb'); + other_setdom(obji, 'name', 'myweb'); + other_setdom(obji, 'frameborder', '0'); + other_setdom(obji, 'scrolling', 'no'); + other_setdom(obji, 'scrolling', 'no'); + other_setdom_v(obji, 0); + other_offdomxywh('canvas', obji); + other_appdom('divframe', obji); + if (gameabc_face.onloadurl) { + if (obji.attachEvent) { + obji.attachEvent("onload", function() { + gameabc_face.onloadurl('myweb', 'myweb', obji.src); + }); + } else { + obji.onload = function() { + gameabc_face.onloadurl('myweb', 'myweb', obji.src); + } + ; + } + } + ;g_GameObjectManager.canvas.addEventListener(gameabc_face.down, function(e) { + e.preventDefault(); + if (gameabc_face.obj.canclick == 0) { + return; + } + ;g_mouse.isMouseDown = true; + g_mouse.ismove = false; + g_mouse.move_time = 0; + g_mouse.up_time = 0; + g_mouse.doup = true; + get_xy(e, 0); + g_mouse.downx = g_mouse.pointX; + g_mouse.downy = g_mouse.pointY; + g_mouse.dodown = false; + g_mouse.down_time = gameabc_face.getruntime(); + g_mouse.down_spid = gameabc_check_click(g_mouse.downx, g_mouse.downy); + g_mouse.movelastx = g_mouse.pointX; + g_mouse.movelasty = g_mouse.pointY; + }, false); + g_GameObjectManager.canvas.addEventListener(gameabc_face.up, function(e) { + e.preventDefault(); + if (gameabc_face.obj.canclick == 0) { + return; + } + ;g_mouse.movelastx = 0; + g_mouse.movelasty = 0; + g_mouse.isMouseDown = false; + g_mouse.move_time = 0; + get_xy(e, 2); + g_mouse.upx = g_mouse.pointX; + g_mouse.upy = g_mouse.pointY; + g_mouse.doup = false; + g_mouse.up_time = gameabc_face.getruntime(); + g_mouse.up_spid = gameabc_check_click(g_mouse.pointX, g_mouse.pointY); + logmessage('//' + g_mouse.upx + ':' + g_mouse.upy); + }, false); + g_GameObjectManager.canvas.addEventListener(gameabc_face.move, function(e) { + e.preventDefault(); + if (gameabc_face.obj.canclick == 0) { + return; + } + ;gameabc_face.getruntime(); + if (g_mouse.isMouseDown) { + g_mouse.ismove = true; + g_mouse.move_time = gameabc_face.getruntime() - g_mouse.down_time; + get_xy(e, 1); + } + }, false); + gameabc_Object.ObjectList[0].Property = {}; + gameabc_face.obj = gameabc_Object.ObjectList[0].Property; + gameabc_face.obj.color = 0; + gameabc_face.obj.caption = ""; + gameabc_face.obj.canclick = 1; + gameabc_face.obj.uipointer = 0; + if (gameabc_face.onloadurl) { + gameabc_face.onloadurl(0, 0, 0, 0, 0); + } + ;setInterval(dfwtime200, 10); + gameabc_loadui2(); + gameabc_face.starttime = new Date().getTime(); + gameabc_face.nowttime = 0; + gameabc_face.chargez = 0; + gameabc_face.resize(); + if (gameabc_Project.Property.title) { + logmessage(gameabc_Project.Property.title, 2); + } + ;if (gameabc_face.gamestart) { + gameabc_face.gamestart(); + } + ;return this; + } + ; +} +;ifastunit = 1; +function GameObject() { + this.data = {}; + this.rec = {}; + this.other = {}; + this.Property = null; + this.recid = 0; + this.uipointer = 0; + this.classid = 0; + this.objid = 0; + this.clickid = 0; + this.imagecavans = 0; + this.caption = ""; + this.mydataid = 0; + this.tag = 0; + this.tag1 = 0; + this.tag2 = 0; + this.tag3 = 0; + this.rec1 = 0; + this.rec2 = 0; + this.rec3 = 0; + this.f = 0; + this.child = 0; + this.x = 0; + this.y = 0; + this.w = 0; + this.h = 0; + this.z = 0; + this.z_Order = 0; + this.offx = 0; + this.offy = 0; + this.fx = 0; + this.fy = 0; + this.fz = 0; + this.sx = 0; + this.sy = 0; + this.sz = 0; + this.sf = 0; + this.scale = 100; + this.arge = 0; + this.ap = 255; + this.hu = 0; + this.visbale = 1; + this.draw = 0; + this.life = 0; + this.drawtime = 0; + this.canclick = 1; + this.charging = 0; + this.frame = 0; + this.groupid = 0; + this.cx = 0; + this.cy = 0; + this.frame_all = 0; + this.dj = 0; + this.dj_all = 0; + this.bz = 0; + this.jx = 0; + this.fx8 = 0; + this.zt = 0; + this.z_index = 0; + this.click_time = 0; + this.canscroll = 0; + this.ontime = 0; + this.color = 0; + this.xlifemax = 0; + this.xlife = 0; + this.maskrecid = 0; + this.canvas = null; + this.maska = 0; + this.mask_uipointer = 0; + this.mask_frame = 0; + this.dig_frame = 0; + this.game_other = 0; + this.startupGameObject = function(x, y, z) { + this.zOrder = z; + this.x = x; + this.y = y; + g_GameObjectManager.addGameObject(this); + return this; + } + ; + this.dllpritefromspritecopy = function(tag) { + this[this.objid + 'add' + tag] = null; + delete this[this.objid + 'add' + tag]; + delete gameabc_Object["sp" + this.objid + 'add' + tag]; + if (!this.addlist) { + this.addlist = new Array(); + } + ;this.addlist.removeObject(this.objid + 'add' + tag); + } + ; + this.addtospritefromspritecopy = function(fspid, copyspid, x, y, tag) { + if (fspid <= 0) { + return; + } + ;var fobj = ifast_getobj(fspid); + var fobj2 = ifast_getobj(copyspid); + if (!fobj.addlist) { + fobj.addlist = new Array(); + } + ;this.copyme(fobj2, this); + this.x = x; + this.y = y; + this.add_fatag = tag; + this.image = fobj2.image; + this.uidata = fobj2.uidata; + fobj[fspid + 'add' + tag] = this; + gameabc_Object["sp" + fspid + 'add' + tag] = this; + fobj.addlist.push(fspid + 'add' + tag); + return this; + } + ; + this.copyme = function(f, m) { + m.recid = f.recid; + m.uipointer = f.uipointer; + m.classid = f.classid; + m.objid = f.objid; + m.clickid = f.clickid; + m.imagecavans = f.imagecavans; + m.caption = f.caption; + m.mydataid = f.mydataid; + m.tag = f.tag; + m.tag1 = f.tag1; + m.tag2 = f.tag2; + m.tag3 = f.tag3; + m.rec1 = f.rec1; + m.rec2 = f.rec2; + m.rec3 = f.rec3; + m.f = f.f; + m.child = f.child; + m.x = f.x; + m.y = f.y; + m.w = f.w; + m.h = f.h; + m.z = f.z; + m.z_Order = f.z_Order; + m.offx = f.offx; + m.offy = f.offy; + m.fx = f.fx; + m.fy = f.fy; + m.fz = f.fz; + m.sx = f.sx; + m.sy = f.sy; + m.sz = f.sz; + m.sf = f.sf; + m.scale = f.scale; + m.arge = f.arge; + m.ap = f.ap; + m.hu = f.hu; + m.visbale = f.visbale; + m.draw = f.draw; + m.life = f.life; + m.drawtime = f.drawtime; + m.canclick = f.canclick; + m.charging = f.charging; + m.frame = f.frame; + m.groupid = f.groupid; + m.cx = f.cx; + m.cy = f.cy; + m.frame_all = f.frame_all; + m.dj = f.dj; + m.dj_all = f.dj_all; + m.bz = f.bz; + m.jx = f.jx; + m.fx8 = f.fx8; + m.zt = f.zt; + m.z_index = f.z_index; + m.click_time = f.click_time; + m.canscroll = f.canscroll; + m.ontime = f.ontime; + m.color = f.color; + m.xlifemax = f.xlifemax; + m.xlife = f.xlife; + m.maskrecid = f.maskrecid; + m.mask_vasbale = f.mask_vasbale; + m.maska = f.maska; + m.mask_uipointer = f.mask_uipointer; + m.mask_frame = f.mask_frame; + m.dig_frame = f.dig_frame; + m.game_other = f.game_other; + } + ; + this.shutdownGameObject = function() { + g_GameObjectManager.removeGameObject(this); + } + ; +} +;ifastunit = 2; +function GameObjectManager() { + this.gameObjects = new Array(); + this.lastFrame = new Date().getTime(); + this.xScroll = 0; + this.yScroll = 0; + this.applicationManager = null; + this.canvas = null; + this.context2D = null; + this.backBuffer = null; + this.backBufferContext2D = null; + this.drawstart = 0; + this.drawdc = null; + this.crorle1 = 'rgba(0,0,0,0)'; + this.crorle2 = 'white'; + this.userbj = 0; + function g_toclient(mode, ctx) { + if (mode == 1) { + ctx.translate(g_GameObjectManager.canvas.width / 2, g_GameObjectManager.canvas.height / 2); + } else { + ctx.translate(-g_GameObjectManager.canvas.width / 2, -g_GameObjectManager.canvas.height / 2); + } + ; + } + ;this.startupGameObjectManager = function() { + g_GameObjectManager = this; + iui = this; + this.bg1 = null; + this.bg2 = null; + this.d2dbj1 = null; + this.d2dbj2 = null; + this.bg = null; + this.d2dbg = null; + this.bg = document.getElementById('ifastgame_bg'); + if (this.bg) { + this.bg.style.position = "absolute"; + this.bg.style.left = "0px"; + this.bg.style.top = "0px"; + this.d2dbj = this.bg.getContext('2d'); + this.d2dbj.fillStyle = "red"; + this.d2dbj.clearRect(0, 0, this.bg.width, this.bg.height); + this.d2dbj.fillStyle = "white"; + this.d2dbj.textBaseline = "top"; + this.bg.x = 0; + this.bg.y = 0; + this.bg.w = 0; + this.bg.h = 0; + } + ;this.bg1 = document.getElementById('bg1'); + if (this.bg1) { + this.bg1.style.position = "absolute"; + this.bg1.style.left = "0px"; + this.bg1.style.top = "0px"; + this.d2dbj1 = this.bg1.getContext('2d'); + this.d2dbj1.fillStyle = "red"; + this.d2dbj1.clearRect(0, 0, this.bg1.width, this.bg1.height); + this.d2dbj1.fillStyle = "white"; + this.d2dbj1.textBaseline = "top"; + this.bg1.x = 0; + this.bg1.y = 0; + this.bg1.w = 0; + this.bg1.h = 0; + } + ;this.bg2 = document.getElementById('bg2'); + if (this.bg2) { + this.bg2.style.position = "absolute"; + this.bg2.style.left = "0px"; + this.bg2.style.top = "0px"; + this.d2dbj2 = this.bg2.getContext('2d'); + this.d2dbj2.fillStyle = "yellow"; + this.d2dbj2.clearRect(0, 0, this.bg2.width, this.bg2.height); + this.d2dbj2.fillStyle = "white"; + this.d2dbj2.textBaseline = "top"; + this.bg2.x = 0; + this.bg2.y = 0; + this.bg2.w = 0; + this.bg2.h = 0; + } + ;this.canvas = document.getElementById('canvas'); + if (!this.canvas) { + if (gameabc_face.gamestart) { + gameabc_face.gamestart(); + } + ;return; + } + ;this.canvas.style.position = "absolute"; + this.canvas.style.left = "0px"; + this.canvas.style.top = "0px"; + this.context2D = this.canvas.getContext('2d'); + this.ratio = getPixelRatio(this.context2D); + gameabc_face.ratio = this.ratio; + if (!gameabc_face.dfwgao_max) { + gameabc_face.dfwgao_max = 2; + } + ;if (gameabc_face.dfwgao_max) { + if (this.ratio > gameabc_face.dfwgao_max) + (this.ratio = gameabc_face.dfwgao_max) + } + ;gameabc_face.useratio = this.ratio; + this.backBuffer = document.createElement('canvas'); + this.backBuffer.width = this.canvas.width; + this.backBuffer.height = this.canvas.height; + if (gameabc_face.showmode == 0) { + gameabc_setcanvas2(this.canvas); + } else { + gameabc_setcanvas2(this.backBuffer); + } + ;if (gameabc_face.showmode == 100) {} + ;this.backBufferContext2D = this.backBuffer.getContext('2d'); + gameabc_face.dc = this.backBufferContext2D; + ifast_jb = this.backBufferContext2D.createLinearGradient(0, 0, 170, 0); + ifast_jb.addColorStop("0", "magenta"); + ifast_jb.addColorStop("0.5", "blue"); + ifast_jb.addColorStop("1.0", "red"); + this.applicationManager = new ApplicationManager().startupApplicationManager(); + myyyyycheck(); + if (!window.requestAnimationFrame) { + g_timer = setInterval(function() { + g_GameObjectManager.draw(); + }, SECONDS_BETWEEN_FRAMES2); + } else { + this.now = Date.now(); + ;this.then = Date.now(); + this.delta = Date.now(); + g_GameObjectManager.hhhh = 0; + setInterval(this.checkrun, 2000); + this.tick(); + } + ;return this; + } + ; + function myyyyycheck() { + var vendors = ['ms', 'moz', 'webkit', 'o']; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; + } + } + ;this.checkrun = function() { + if (window.requestAnimationFrame) { + g_GameObjectManager.now = Date.now(); + g_GameObjectManager.delta = g_GameObjectManager.now - g_GameObjectManager.then; + if (g_GameObjectManager.delta > 1000) { + g_GameObjectManager.now = Date.now(); + ;g_GameObjectManager.then = Date.now() - SECONDS_BETWEEN_FRAMES; + g_GameObjectManager.delta = Date.now(); + window.cancelAnimationFrame(g_GameObjectManager.hhhh); + g_GameObjectManager.tick(); + } + ; + } + ; + } + ; + this.drawone = function(obj, dfwts, dfwdt, dt) { + if (arguments.length == 4) { + if (obj.draw) { + if (obj.levelobj) { + if (obj.ontime > 0) { + if (obj.click_time == 0) { + obj.click_time = gameabc_face.nowttime; + obj.lasttime_ontimer = obj.click_time; + } else { + var ttt = gameabc_face.nowttime - obj.lasttime_ontimer; + if (ttt >= obj.ontime) { + obj.lasttime_ontimer = gameabc_face.nowttime; + var iii = ifast_div(ttt, obj.ontime); + var fun0 = gameabc_face["ontimer"]; + if (fun0) { + gameabc_face.drawtime = 1; + fun0(0, obj.objid, iii, ttt, gameabc_face.nowttime - obj.click_time); + } + ;var fun = gameabc_face["ontimer_" + obj.objid]; + if (fun) { + gameabc_face.drawtime = 1; + fun(obj.objid, obj.objid, iii, ttt, gameabc_face.nowttime - obj.click_time); + } + ; + } + } + } + ;if (obj.levelobj.vsb > 0 && obj.visbale != 0) { + this.backBufferContext2D.save(); + this.backBufferContext2D.beginPath(); + if (obj.f) { + this.backBufferContext2D.translate(obj.f.x, obj.f.y); + } + ;if (gameabc_face.gamemydrawbegin) { + gameabc_face.gamemydrawbegin(0, obj.objid, dfwts, dfwdt); + } + ;obj.draw(dt, this.backBufferContext2D, this.xScroll, this.yScroll); + var yyy1; + var obj2; + var r2; + var ll; + var objlis; + if (obj.addlist) { + objlist = obj.addlist; + ll = objlist.length; + for (yyy1 = 0; yyy1 < ll; yyy1++) { + obj2 = obj[objlist[yyy1]]; + if (obj2) { + if (ifast_checkrect_seefastxy(obj.x + obj2.x, obj.y + obj2.y) == 0) { + continue; + } + ;if (ifast_checkrect_seefastxywh(obj.x + obj2.x, obj.y + obj2.y, obj.x + obj2.x + obj2.w, obj.y + obj2.y + obj2.h) == 0) { + continue; + } + ;ifast_mydrawsprite(obj, obj2); + continue; + r2 = ifast_rect(obj.x + obj2.x, obj.y + obj2.y, obj.x + obj2.x + obj2.w, obj.y + obj2.y + obj2.h); + if (ifast_checkrect(ifast_seerect, r2) == 1) { + ifast_mydrawsprite(obj, obj2); + } + } + } + } + ;gameabc_face.gamemydraw(0, obj.objid, dfwts, dfwdt); + this.backBufferContext2D.restore(); + } + ; + } else {} + ; + } + ;return; + } + ;var x; + for (x in this.gameObjects) { + obj = this.gameObjects[x]; + this.drawone(obj, dfwts, dfwdt, dt); + } + ; + } + ; + this.tick = function() { + var uu; + if (window.requestAnimationFrame) { + g_GameObjectManager.hhhh = requestAnimationFrame(g_GameObjectManager.tick); + g_GameObjectManager.now = Date.now(); + g_GameObjectManager.delta = g_GameObjectManager.now - g_GameObjectManager.then; + if (g_GameObjectManager.delta >= SECONDS_BETWEEN_FRAMES) { + g_GameObjectManager.then = g_GameObjectManager.now - (g_GameObjectManager.delta % SECONDS_BETWEEN_FRAMES); + g_GameObjectManager.draw(); + } + } else { + setTimeout(g_GameObjectManager.tick, SECONDS_BETWEEN_FRAMES); + g_GameObjectManager.draw(); + } + ; + } + ; + this.clearcanvas = function() {//---xwb--------------------- + this.backBufferContext2D.save(); + this.backBufferContext2D.beginPath(); + // this.backBufferContext2D.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height); + // if (gameabc_Object.ObjectList.length < 20 && (!gameabc_face.dfwtou)) { + // this.backBufferContext2D.fillStyle = "white"; + // this.backBufferContext2D.fillRect(0, 0, this.backBuffer.width, this.backBuffer.height); + // } else {} + } + ; + this.draw = function() {//---xwb--------------------- + try{ + + var bugi=0; + var thisFrame = new Date().getTime(); + var dfwdt = (thisFrame - this.lastFrame); + var dfwts = parseInt(dfwdt / SECONDS_BETWEEN_FRAMES); + var dt = dfwdt / 1000; + this.lastFrame = thisFrame; + var clickid1 = 0; + gameabc_face.getruntime_now(); + gameabc_runani(); + bugi=1; + gameabc_runbox(); + bugi=2; + if (g_mouse.doup == false) { + var tt = gameabc_face.nowttime - g_mouse.down_time; + if (tt < gameabc_face.fastup_time) { + gameabc_face.fastup = g_mouse.down_spid; + } + } + ;if (!g_mouse.dodown) { + logmessage("mousedown/" + g_mouse.down_spid + "/" + g_mouse.downx + "/" + g_mouse.downy); + gameabc_face.mousedown(0, g_mouse.down_spid, g_mouse.downx, g_mouse.downy); + g_mouse.dodown = true; + if (gameabc_face["mousedown_" + g_mouse.down_spid]) { + gameabc_face["mousedown_" + g_mouse.down_spid](g_mouse.down_spid, g_mouse.down_spid, g_mouse.downx, g_mouse.downy); + } + ; + } + ;if (g_mouse.isMouseDown) { + gameabc_face.drawmouse = 1; + var tt = gameabc_face.nowttime - g_mouse.down_time; + if (g_mouse.ismove == false) { + logmessage("mousedown_nomove/" + g_mouse.down_spid + "/" + g_mouse.downx + "/" + g_mouse.downy + "/" + tt); + gameabc_face.mousedown_nomove(0, g_mouse.down_spid, g_mouse.downx, g_mouse.downy, tt); + if (gameabc_face["mousedown_nomove_" + g_mouse.down_spid]) { + gameabc_face["mousedown_nomove_" + g_mouse.down_spid](g_mouse.down_spid, g_mouse.down_spid, g_mouse.downx, g_mouse.downy, tt); + } + } else { + logmessage("mousemove/" + g_mouse.down_spid + "/" + g_mouse.downx + "/" + g_mouse.downy + "/" + tt + "/" + (g_mouse.pointX - g_mouse.downx) + "/" + (g_mouse.pointY - g_mouse.downy)); + gameabc_face.mousemove(0, g_mouse.down_spid, g_mouse.downx, g_mouse.downy, g_mouse.pointX, g_mouse.pointY, tt, g_mouse.pointX - g_mouse.movelastx, g_mouse.pointY - g_mouse.movelasty); + if (gameabc_face["mousemove_" + g_mouse.down_spid]) { + gameabc_face["mousemove_" + g_mouse.down_spid](g_mouse.down_spid, g_mouse.down_spid, g_mouse.downx, g_mouse.downy, g_mouse.pointX, g_mouse.pointY, tt, g_mouse.pointX - g_mouse.movelastx, g_mouse.pointY - g_mouse.movelasty); + } + ;g_mouse.movelastx = g_mouse.pointX; + g_mouse.movelasty = g_mouse.pointY; + } + } + ;if (g_mouse.doup == false) { + gameabc_face.drawmouse = 1; + var tt2 = gameabc_face.nowttime - g_mouse.down_time; + clickid1 = g_mouse.up_spid; + if (clickid1 > 0) { + gameabc_face.clickid = clickid1; + g_mouse.up_spid = clickid1; + } + { + gameabc_face.mouseup(0, g_mouse.down_spid, g_mouse.downx, g_mouse.downy, clickid1, g_mouse.upx, g_mouse.upy, tt2); + if (gameabc_face["mouseup_" + g_mouse.down_spid]) { + gameabc_face["mouseup_" + g_mouse.down_spid](g_mouse.down_spid, g_mouse.down_spid, g_mouse.downx, g_mouse.downy, clickid1, g_mouse.upx, g_mouse.upy, tt2); + } + ;logmessage("mouseup/" + g_mouse.down_spid + "/" + g_mouse.downx + "/" + g_mouse.downy + "/" + clickid1 + "/" + g_mouse.upx + "/" + g_mouse.upy + "/" + tt2); + } + ;g_mouse.doup = true; + gameabc_face.fastup = -1; + } + ;if (gameabc_face.userchargez == 1) { + if (gameabc_face.chargez == 1) { + this.gameObjects.sort(function(a, b) { + return a.zOrder - b.zOrder; + }); + gameabc_face.chargez = 0; + } + ; + } + ;this.clearcanvas(); + bugi=3; + gameabc_face.gamebegindraw(0, 0, dfwts, dfwdt); + if (gameabc_face.userchargez == 1) { + this.drawone(dfwts, dfwdt, dt); + } else { + var obj; + var tid; + var yy; + var le = gameabc_Layer.LayerList; + var timelist = gameabc_Layer.showtimelist; + var showorder = gameabc_Layer.showorder; + var xx; + var yy1; + var pp; + for (yy1 = 0; yy1 < timelist.length; yy1++) { + yy = timelist[yy1]; + pp = le[yy].ontimelist; + if (pp.length > 0) { + for (xx = 0; xx < pp.length; xx++) { + obj = gameabc_Object["sp" + pp[xx]]; + if (obj) { + this.drawone(obj, dfwts, dfwdt, dt); + } else { + if (!gameabc_face.tsbb) { + showmessage('版本å¯èƒ½æœªæ³¨å†Œï¼'); + gameabc_face.tsbb = 1; + } + } + } + ; + } else { + continue; + } + ; + } + ;for (yy1 = 0; yy1 < showorder.length; yy1++) { + yy = showorder[yy1]; + if (!le[yy].Property) { + continue; + } + ;pp = le[yy].ObjectList; + for (xx = 0; xx < pp.length; xx++) { + obj = gameabc_Object["sp" + pp[xx]]; + if (obj) { + this.drawone(obj, dfwts, dfwdt, dt); + } else { + if (!gameabc_face.tsbb) { + showmessage('版本å¯èƒ½æœªæ³¨å†Œï¼'); + gameabc_face.tsbb = 1; + } + } + } + ; + } + ; + } + ;gameabc_face.gameenddraw(0, 0, dfwts, dfwdt); + bugi=4; + if (gameabc_face.showzt == 1) { + game124.update(); + } + ;if (gameabc_face.loglist.length > 0) { + var yyyy; + var uu = gameabc_face.loglist.length - 1; + for (yyyy = uu; yyyy >= 0; yyyy--) { + this.backBufferContext2D.textBaseline = "top"; + this.backBufferContext2D.fillStyle = "red"; + this.backBufferContext2D.font = 32 + 'px' + ' bold san-serif'; + this.backBufferContext2D.fillText(gameabc_face.loglist[yyyy], 10, 80 + (uu - yyyy) * 32); + } + ; + } + ;if (gameabc_face.obj.color != 0) { + gameabc_face.zz2d.clearRect(0, 0, 1, 1); + gameabc_face.zz2d.fillStyle = gameabc_face.obj.color; + gameabc_face.zz2d.fillRect(0, 0, 1, 1); + this.backBufferContext2D.drawImage(gameabc_face.zz_canvas, 0, 0, 1, 1, 0, 0, this.backBuffer.width, this.backBuffer.height); + } + ;if (gameabc_face.obj.caption != "") { + this.backBufferContext2D.fillStyle = "white"; + this.backBufferContext2D.font = parseInt(24 * this.backBuffer.width / 480) + "px" + ' bold san-serif'; + this.backBufferContext2D.fillText(gameabc_face.obj.caption, parseInt(this.backBuffer.width / 2) - 50, parseInt(this.backBuffer.height / 2) + 100); + } + ;if (gameabc_face.checkmustdraw() == 0) { + return; + } + bugi=5; + ;this.context2D.fillStyle = this.crorle1; + // this.context2D.clearRect(0, 0, this.canvas.width, this.canvas.height);//--xwb-- + if (gameabc_face.showmode == 0) { + if (gameabc_face.jm_sj_tong == 0) { + this.context2D.save(); + this.context2D.translate(this.backBuffer.width / 2, this.backBuffer.height / 2); + this.context2D.rotate(-90 * Math.PI / 180); + this.context2D.translate(-this.backBuffer.height / 2, -this.backBuffer.width / 2); + this.context2D.drawImage(this.backBuffer, 0, 0, this.backBuffer.width, this.backBuffer.height, gameabc_face.drawx, gameabc_face.drawy, gameabc_face.drawh, gameabc_face.draww); + this.context2D.restore(); + } else { + this.context2D.drawImage(this.backBuffer, 0, 0, this.backBuffer.width, this.backBuffer.height, 0, 0, this.canvas.width, this.canvas.height); + } + ; + } else { + this.context2D.drawImage(this.backBuffer, 0, 0, this.backBuffer.width, this.backBuffer.height, gameabc_face.drawx, gameabc_face.drawy, gameabc_face.draww, gameabc_face.drawh); + } + bugi=6; + ;this.backBufferContext2D.restore(); + bugi=7; + }catch(e){ + // if(Net){ + // if(Net.submit_error){ + // if(gameabc_senderror == 0){ + // gameabc_senderror = 1; + // Net.submit_error("uidebug",bugi+':::'+e.stack);//xwb--------------- + // } + + // } + // } + console.log(e.stack); + } + } + ; + this.addGameObject = function(gameObject) { + this.gameObjects.push(gameObject); + this.gameObjects.sort(function(a, b) { + return a.zOrder - b.zOrder; + }); + } + ; + this.removeGameObject = function(gameObject) { + this.gameObjects.removeObject(gameObject); + } + ; +} +;ifastunit = 4; +Array.prototype.remove = function(from, to) { + var rest = this.slice((to || from) + 1 || this.length); + this.length = from < 0 ? this.length + from : from; + return this.push.apply(this, rest); +} +; +Array.prototype.removeObject = function(object) { + for (var i = 0; i < this.length; ++i) { + if (this[i] === object) { + this.remove(i); + break; + } + } +} +; +Array.prototype.indexofval = function(val) { + for (var i = 0; i < this.length; i++) { + if (this[i] == val) + return i; + } + ;return -1; +} +; +Array.prototype.removeval = function(val) { + var index = this.indexOf(val); + if (index > -1) { + this.splice(index, 1); + } +} +; +ifastunit = 5; +function VisualGameObject() { + this.image = null; + this.draw = function(dt, context, xScroll, yScroll) { + context.drawImage(this.image, this.x - xScroll, this.y - yScroll); + } + ; + this.startupVisualGameObject = function(image, x, y, z) { + this.startupGameObject(x, y, z); + this.image = image; + return this; + } + ; + this.shutdownVisualGameObject = function() { + this.shutdownGameObject(); + } + ; +} +;VisualGameObject.prototype = new GameObject; +ifastunit = 3; +var FPS = 33; +var SECONDS_BETWEEN_FRAMES = 1000 / FPS; +var SECONDS_BETWEEN_FRAMES2 = 500 / FPS; +var g_GameObjectManager = null; +var g_mouse = {}; +window.onload = init; +function init() { + gameabc_face.gameini(); + gameabc_face.fastup = -1; + new GameObjectManager().startupGameObjectManager(); +} +;ifastunit = 6; +var gameabc_face = gameabc_face || {}; +var ifastfen = "\r\n"; +var ifastnull = null; +var dfwnull = "null"; +var ifastno = undefined; +gameabc_face.showmessage = function(str, mode) { + if (arguments.length == 1) { + alert(str); + } else { + var s = prompt(str); + return s; + } +} +; +gameabc_face.logmessage = function(str) { + console.info(str); +} +; +function ifast_float(f, r) { + if (arguments.length == 1) { + r = gameabc_face.vw; + } + ;return parseFloat(i * r); +} +;function ifast_int(i, r) { + if (arguments.length == 1) { + r = gameabc_face.vw; + } + ;return parseInt(i * r); +} +;function ifast_inttostr(i) { + return i.toString(); +} +;function ifast_strtoint(s, def) { + var u = parseInt(s); + if (u == 0) { + return 0; + } + ;if (!u) { + if (!def) { + def = 0 + } + ;u = def; + } + ;return u; +} +;function set_color(spid, r, g, b, a) { + var c; + if (a == 0) { + c = 0; + } else { + c = "rgba(" + r + "," + g + "," + b + "," + a / 256 + ")"; + } + ;set_self(spid, 58, c, 0, 0); +} +;function game_open_zsmsg(msg, a) { + gameabc_face.drawcharge = 1; + set_self(0, 7, msg, 0, 0); + if (!a) { + a = 32; + } + ;if (gameabc_face.obj.color == 0) { + set_color(0, 0, 0, 0, 128 + a); + } + ;gameabc_face.obj.canclick = 0; +} +;function game_close_zsmsg() { + gameabc_face.drawcharge = 1; + set_self(0, 7, "", 0, 0); + set_self(0, 58, 0, 0, 0); + gameabc_face.obj.canclick = 1; +} +;function open_load(bmprec, wavrec, urlrec) { + if (wavrec) { + ifast_wav.loadall(wavrec); + } + ; +} +;function ifast_strtotime(str) { + return Date.parse(str); +} +;function ifast_getonlyid() { + var timestamp3 = new Date().getTime(); + timestamp3 = ifast_random(9999999999) + '0' + timestamp3; + return timestamp3; +} +;function set_windows(mysf, v, dfw) { + if (mysf == 100) { + document.body.style.background = "url(" + v + ")"; + return; + } + ;if (mysf == 101) { + gameabc_face.dfwgao = 1; + return; + } + ;if (mysf == 102) { + gameabc_face.dfwtou = 1; + return; + } + ;//gameabc_face.jm_sj_cj = mysf; + gameabc_Project.Property.Version = v; + ifast_ismast = 1; + if (dfw == 1977) { + game124.domElement.style.left = "1111110px"; + } + ;gameabc_face.resize2000(); +} +;function charge_windows(sjw, sjh, winw, winh) { + gameabc_face.isxz = 0; + gameabc_face.drawx = 0; + gameabc_face.drawy = 0; + gameabc_face.draww = 0; + gameabc_face.drawh = 0; +} +;function addinputdiv(id, type, x, y, w, h) { + return gameabc_face.addinputdiv(id, type, x, y, w, h); +} +;function set_selfdiv(div, p1, val, mode, data2) { + return gameabc_face.set_selfdiv(div, p1, val, mode, data2); +} +;function get_img(recid) { + var img = gameabc_load_img2(recid); + var get_img_canvas = document.createElement("canvas"); + var ctx = get_img_canvas.getContext("2d"); + get_img_canvas.width = img.width; + get_img_canvas.height = img.height; + ctx.drawImage(img, 0, 0); + return get_img_canvas.toDataURL("image/png"); +} +;function ifast_loadsprite(spritelist) { + var i; + for (i = 0; i < spritelist.length; i++) { + gameabc_loadui2(spritelist[i]); + } +} +;function openurl(url, mode, cp1) { + if (cp1) { + url = url + "?" + cp1; + } + ;switch (mode) { + case 0: + window.location.href = url; + break; + case 1: + break; + default: + window.location.href = url; + break; + } +} +;function up_imgurl(recid, url, rewh) { + var img = gameabc_load_img2(recid); + gameabc_face.img_list_downing.removeObject(img); + if (rewh == 1) { + img.rewh = 1; + } + ;img.onload = function() { + gameabc_face.drawcharge = 1; + if (this.rewh == 1) { + ifast_checkimg(recid, 1); + } else { + var obj = gameabc_Image.ImageFileList[recid]; + if ((obj.img.allh < img.height) || (obj.img.allw < img.width)) { + ifast_checkimg(recid, 1); + } + } + ;img.rewh = 0; + } + ; + img.src = url; + //img.crossOrigin = '*';//??????,????????,??? anonymous +} +;function up_imgdata(recid, data) { + gameabc_face.drawcharge = 1; + var img = gameabc_load_img2(recid); + if (data.substring(0, 4) != "data") { + img.src = "data:image/jpeg;base64," + data; + return; + } + ;img.src = data; +} +;function get_selfdiv(div, p1) { + gameabc_face.get_selfdiv(div, p1); +} +;function set_selflist_off(id, offx1, offy1) { + var obj = gameabc_func.getobj(id); + if (ifast_isno(obj)) { + return; + } + ;obj.setoff(offx1, offy1); +} +;function set_selflist_xywh(id, x1, y1, w1, h1) { + var obj = gameabc_func.getobj(id); + if (ifast_isno(obj)) { + return; + } + ;obj.x = x1; + obj.y = y1; + obj.w = w1; + obj.h = h1; + obj.charge(x1, y1, w1, h1); +} +;function ifast_random(b) { + return parseInt(Math.random() * b); +} +;function ifast_abs(b) { + return Math.abs(b); +} +;function ifast_tcp_open(tcpid, weburl) { + ifast_wss.open(tcpid, weburl); +} +;function ifast_tcp_send(tcpid, msg) { + msg = ifast_jsonchecktostring(msg); + ifast_wss.send(tcpid, msg); +} +;function ifast_tcp_close(tcpid) { + ifast_wss.close(tcpid); +} +;function set_jm_xx(jms) { + var arr1 = jms.split(","); + var i = 0; + var level1 = 0; + var d = 0; + var id; + var leid; + var obj2; + for (d = 1; d < gameabc_Layer.LayerList.length; d++) { + gameabc_Layer.LayerList[d].vsb = 0; + } + ;gameabc_face.chargez = 1; + for (i = 0; i < arr1.length; i++) { + level1 = arr1[i]; + leid = gameabc_Layer.LayerList[level1]; + if (!leid) { + continue; + } + ;leid.vsb = 1; + for (d = 0; d < leid.ObjectList.length; d++) { + id = leid.ObjectList[d]; + obj2 = ifast_getobj(id); + if (obj2) { + obj2.zOrder = i * 10000 + obj2.uidata.IndexOfLayer; + } + } + ; + } + ; +} +;function ifast_ajax(myid, url, postcs, mode, fun) {} +;function ifast_http(myid, url, postcs, mode, fun) { + postcs = ifast_jsonchecktostring(postcs); + var temp = url.substr(url.length - 4); + if (temp == '.txt' || temp == '.html' || postcs) {} else { + if ((temp[0] != '.') || (temp != '.txt' && temp != '.html')) { + if (gameabc_face.randomhttp > 0) { + url = url + '&dfwhttp=' + ifast_random(gameabc_face.randomhttp) + ifast_random(gameabc_face.randomhttp); + } + ; + } + } + ;var pos = url.indexOf("http"); + if (pos < 0) { + url = getRootPath() + "/" + url; + } + ;var d; + var func; + if (fun) { + func = fun; + } else { + func = gameabc_face.httpmessage; + } + ;if (mode == 0) { + d = readfile_t(url, postcs); + if (func) { + func(myid, url, d); + } + ; + } else { + if (func) { + readfile_a2(myid, url, postcs, func); + } + ; + } + ; +} +;function play_wav(id, isloop1) { + ifast_wav.playwav(id, isloop1); +} +;function ifast_getcs(name, daf) { + return gameabc_face.ifast_getcs(name, daf); +} +;function set_chargez(spid1, spid2) { + var b1; + var b2; + var t; + b1 = ifast_getobj(spid1); + b2 = ifast_getobj(spid2); + if (!b1) + return; + if (!b2) + return; + t = b1.zOrder; + b1.zOrder = b2.zOrder; + b2.zOrder = t; + gameabc_face.chargez = 1; + gameabc_face.userchargez = 1; + gameabc_face.drawcharge = 1; +} +;function readfile_key(key) { + return localStorage.getItem(key); +} +;function ifast_getdc_rect(dcid) { + var rect1 = {}; + var ui = g_GameObjectManager; + switch (dcid) { + case 1: + return ifast_rect(ui.bg1.x, ui.bg1.y, ui.bg1.width, ui.bg1.height); + break; + case 2: + return ifast_rect(ui.bg2.x, ui.bg2.y, ui.bg2.width, ui.bg2.height); + break; + default: + return ifast_rect(0, 0, ui.backBuffer.width, ui.backBuffer.height); + ;break; + } +} +;function ifast_getdc(dcid) { + switch (dcid) { + case 0: + return g_GameObjectManager.d2dbj; + break; + case 1: + return g_GameObjectManager.d2dbj1; + break; + case 2: + return g_GameObjectManager.d2dbj2; + break; + default: + return gameabc_face.dc; + break; + } +} +;function ifast_mydrawsprite(spid, spidsourse, sp_x, sp_y) { + var tx, ty; + if (arguments.length == 2) { + tx = spidsourse.x; + ty = spidsourse.y; + spidsourse.x = spid.x + spidsourse.x; + spidsourse.y = spid.y + spidsourse.y; + spidsourse.draw(0, gameabc_face.dc, 0, 0); + spidsourse.x = tx; + spidsourse.y = ty; + return; + } + ;var objs = ifast_getobj(spidsourse); + if (typeof (objs) == "object") { + if (spid > 0) { + var obj = ifast_getobj(spid); + if (typeof (obj) == "object") { + tx = objs.x; + ty = objs.y; + objs.x = obj.x + sp_x; + objs.y = obj.y + sp_y; + objs.draw(0, gameabc_face.dc, 0, 0); + objs.x = tx; + objs.y = ty; + } + ; + } + ; + } + ; +} +;function ifast_mydrawbmp(spid, recid, sp_x, sp_y, sp_w, sp_h, bmp_x, bmp_y, bmp_w, bmp_h) { + if (bmp_w <= 0) { + ifast_drawtext(spid, recid, sp_x, sp_y, sp_w, sp_h); + return; + } + ;if (spid <= 0) { + gameabc_face.dc.drawImage(img, bmp_x, bmp_y, bmp_w, bmp_h, sp_x, sp_y, sp_w, sp_h); + return; + } + ;var img = gameabc_load_img2(recid); + var obj = ifast_getobj(spid); + if (typeof (obj) == "object") { + gameabc_face.dc.drawImage(img, bmp_x, bmp_y, bmp_w, bmp_h, obj.x + sp_x, obj.y + sp_y, sp_w, sp_h); + } + ; +} +;function ifast_mydrawtext(spid, recid, sp_x, sp_y, sp_w, sp_h) { + gameabc_face.dc.textBaseline = "top"; + gameabc_face.dc.fillStyle = gameabc_GameTxt.GameTxtList[recid].Color; + gameabc_face.dc.font = sp_h + 'px' + ' bold san-serif'; + var caption = gameabc_GameTxt.GameTxtList[recid].Text; + if (spid <= 0) { + gameabc_face.dc.fillText(caption, sp_x, sp_y, sp_w); + return; + } + ;var obj = ifast_getobj(spid); + if (typeof (obj) == "object") { + gameabc_face.dc.fillText(caption, obj.x + sp_x, obj.y + sp_y, sp_w); + } + ; +} +;function ifast_lenth(key) { + if (typeof (key) != "string") { + var g = key + ""; + return g.length; + } else { + return key.length; + } +} +;function ifast_stringat(key, pos) { + return key.charAt(pos); +} +;function ifast_setpause(is) { + if (!gameabgc_face.pause) { + gameabc_face.pause = 0; + } + ;return gameabc_face.pause = is; +} +;function ifasthttpobj(httppath, httpdata) { + this.httppath = httppath; + this.httpdata = httpdata; + this.httppath = readfile_t(httppath); + this.httpdata = readfile_t(httpdata); + ;this.render = function() { + return this.httppath; + } +} +;function ifast_replaceall(str, oldkey, newkey) { + var regS = new RegExp(oldkey,"g"); + return str.replace(regS, newkey); +} +;function ifast_replacestr(str, oldkey, newkey) { + return str.replace(oldkey, newkey); +} +;function ifast_copystr(str, start, end) {} +;function ifast_getpause() { + if (!gameabgc_face.pause) { + gameabc_face.pause = 0; + } + ;return gameabc_face.pause; +} +;function drawround(ctx, mode, cx, cy, r, fx, bgColor, starta, enda, isout) { + if (typeof (ctx) == "object") { + gameabc_face.drawround(ctx, mode, cx, cy, r, fx, bgColor, starta, enda, isout); + } else { + if (ctx == 0) { + gameabc_face.drawround(gameabc_face.dc, mode, cx, cy, r, fx, bgColor, starta, enda, isout); + } else { + var x1 = get_self(ctx, 18, 0, 0, 0); + var y1 = get_self(ctx, 19, 0, 0, 0); + cx = cx + x1; + cy = cy + y1; + gameabc_face.drawround(gameabc_face.dc, mode, cx, cy, r, fx, bgColor, starta, enda, isout); + } + ; + } + ; +} +;function drawlines(ctx, startx, starty, endx, endy, lw, bgColor) { + if (typeof (ctx) == "object") { + gameabc_face.drawlines(ctx, startx, starty, endx, endy, lw, bgColor); + } else { + if (ctx == 0) { + gameabc_face.drawlines(gameabc_face.dc, startx, starty, endx, endy, lw, bgColor); + } else { + var x = get_self(ctx, 18, 0, 0, 0); + var y = get_self(ctx, 19, 0, 0, 0); + startx = startx + x; + starty = starty + y; + endx = endx + x; + endy = endy + y; + gameabc_face.drawlines(gameabc_face.dc, startx, starty, endx, endy, lw, bgColor); + } + ; + } + ; +} +;function set_clip(ctx, mode, x, y, w, h, starta, enda, timefx) { + if (typeof (ctx) == "object") { + gameabc_face.set_clip(ctx, mode, x, y, w, h, starta, enda, timefx); + } else { + if (ctx == 0) { + gameabc_face.set_clip(gameabc_face.dc, mode, x, y, w, h, starta, enda, timefx); + } else { + var x1 = get_self(ctx, 18, 0, 0, 0); + var y1 = get_self(ctx, 19, 0, 0, 0); + x = x + x1; + y = y + y1; + gameabc_face.set_clip(gameabc_face.dc, mode, x, y, w, h, starta, enda, timefx); + } + ; + } + ; +} +;function drawrect(ctx, mode, x, y, w, h, bgColor, isout) { + if (typeof (ctx) == "object") { + gameabc_face.drawrect(ctx, mode, x, y, w, h, bgColor, isout); + } else { + if (ctx == 0) { + gameabc_face.drawrect(gameabc_face.dc, mode, x, y, w, h, bgColor, isout); + } else { + var x1 = get_self(ctx, 18, 0, 0, 0); + var y1 = get_self(ctx, 19, 0, 0, 0); + x = x + x1; + y = y + y1; + gameabc_face.drawrect(gameabc_face.dc, mode, x, y, w, h, bgColor, isout); + } + ; + } + ; +} +;function play_box(zt, id, sx, start, startv, av, timelen) { + return ifast_wss.playbox(zt, id, sx, start, startv, av, timelen); +} +;function play_ani(zt, id, sx, start, end, times0, timelen, timee, timesz, timese, timesall, timeall, xhmode) { + return ifast_wss.playani(zt, id, sx, start, end, times0, timelen, timee, timesz, timese, timesall, timeall, xhmode); +} +;function play_ani123(zt, id, sx, start, end, timelen, timesall, timeall, xhmode) { + return ifast_wss.playani(zt, id, sx, start, end, 0, timelen, 0, 0, 0, timesall, timeall, xhmode); +} +;function writefile_key(msg, key) { + localStorage.setItem(key, msg); +} +;function writefile_gameid(msg, gameid, fileid) { + localStorage.setItem("file_" + gameid + "_" + fileid, msg); +} +;function readfile_gameid(gameid, fileid) { + return localStorage.getItem("file_" + gameid + "_" + fileid); +} +;function chartoint(str) { + return str.charCodeAt(); +} +;function inttochar(code) { + return String.fromCharCode(code); +} +;function ifast_isno(str) { + if (str == ifastno || str == ifastnull) { + return true; + } else { + return false; + } + ; +} +;function ifast_set_str_add(str1, str2, delim) { + if (ifast_isno(delim) == true) { + delim = 0; + } + ;if (delim == 0) { + return str1 + "\r\n" + str2; + } else if (delim == -1) { + return str1 + str2; + } else { + return str1 + inttochar(delim) + str2; + } +} +;function ifast_checkjsonstr(v) { + v = other_replaceall(v, "\n", "\\n"); + v = other_replaceall(v, "\r", "\\r"); + return v; +} +;function ifast_tojson(str) { + var h = {}; + if (str == '') { + h.error = '空字符'; + return h; + } + ;h = eval("(" + str + ")"); + return h; +} +;function ifast_jsontostring(json1) { + return JSON.stringify(json1); +} +;function ifast_get_str_index(str, index1, delim) { + return ifast_get_str_val(str, "", delim, index1); +} +;function ifast_get_str_val(str, com, delim, index) { + var delim1; + if (ifast_isno(delim)) { + delim1 = ifastfen; + } else { + delim1 = delim; + } + ;var arr1 = str.split(delim1); + if (com == "") { + if (ifast_isno(index) == true) { + return "null"; + } + ;if (arr1[index]) { + return arr1[index]; + } else { + return "null"; + } + ; + } + ;var str1; + var arr2; + for (i = 0; i < arr1.length - 1; i++) { + str1 = arr1[i]; + arr2 = str1.split("="); + if (com == arr2[0]) { + return arr2[1]; + } + ; + } +} +;function ifast_get_str_count(str, delim) { + var delim1; + if (ifast_isno(delim)) { + delim1 = ifastfen; + } else { + delim1 = delim; + } + ;var arr1 = str.split(delim1); + return arr1.length; +} +;function showmessage(str, mode) { + if (arguments.length == 1) { + var sUserAgent = navigator.userAgent.toLowerCase(); + var bIsIpad = sUserAgent.match(/ipad/i) == "ipad"; + var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os"; + var bIsMidp = sUserAgent.match(/midp/i) == "midp"; + var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4"; + var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb"; + var bIsAndroid = sUserAgent.match(/android/i) == "android"; + var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce"; + var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile"; + if ((typeof (settings) != "undefined") && (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM)) { + settings.showmessage(str); + } else { + alert(str); + } + } else { + var mybody = document.getElementsByTagName("body")[0]; + var mytablebody = document.createElement("textarea"); + mytablebody.style = "left:0px;top:0px;width:800px;height:600px;position:absolute"; + mytablebody.value = str; + mybody.appendChild(mytablebody); + } +} +;function ifast_renderjson2html(data, inits, re, mb) { + var ss = inits; + if (re == 1) { + ss = ss + mb; + } + ;for (var o in data) { + if (typeof (data[o]) == "function") { + continue; + } + ;if (typeof (data[o]) == "object") { + if (data[o].constructor.name == 'Array') { + ss = ifast_renderjson2html(data[o], ss, 0, mb); + } else { + if (data[o].hasOwnProperty('mydata')) { + ss = ifast_renderjson2html(data[o], ss, 1, data[o].mydata); + } else { + if (data[o].hasOwnProperty('myfunc')) { + ss = ifast_renderjson2html(data[o], ss, 2, data[o].myfunc); + } else { + ss = ifast_renderjson2html(data[o], ss, 0, mb); + } + ; + } + } + } else { + switch (re) { + case 2: + if (o != "myfunc") { + ss = mb + "&" + o + "=" + data[o]; + ss = readfile_t(ss); + ss = inits + ss; + } + ;break; + case 1: + if (o != "mydata") { + ss = ifast_replacestr(ss, "{%=" + o + "%}", data[o]); + } + ;break; + default: + ss = ss + data[o]; + break; + } + ; + } + ; + } + ;return ss; +} +;function logmessage(str, mode) { + if (gameabc_face.openlog != 1 && mode == 0) { + return; + } + ;if (!mode) { + mode = 0; + } + ;switch (mode) { + case 2: + document.title = str; + break; + case 0: + ;break; + case 1: + gameabc_face.drawcharge = 1; + gameabc_face.loglist.push(str); + break; + case -1: + gameabc_face.drawcharge = 1; + gameabc_face.loglist = []; + break; + default: + break; + } +} +;function readfile_a2(myid, url, postcp, fun) { + var XMLHttpRequestObject = false; + try { + if (window.XMLHttpRequest) { + XMLHttpRequestObject = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); + } + ;if (XMLHttpRequestObject) { + if (!postcp || postcp == 'GET') { + XMLHttpRequestObject.open("GET", url, true); + } else { + XMLHttpRequestObject.open("POST", url, true); + } + ;XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + XMLHttpRequestObject.onreadystatechange = function() { + if (XMLHttpRequestObject.readyState == 4) { + if (XMLHttpRequestObject.status == 200) { + if (fun) { + fun(myid, url, XMLHttpRequestObject.responseText); + } + } else { + if (fun) { + fun(myid, "error", XMLHttpRequestObject.responseText); + } + } + } + } + ; + if (!postcp || postcp == 'GET') { + XMLHttpRequestObject.send(null); + } else { + XMLHttpRequestObject.send(postcp); + } + } + } catch (e) { + if (fun) { + fun(myid, "error", "error"); + } + ; + } + ; +} +;function readfile_a(url, postcp, fun) { + var XMLHttpRequestObject = false; + try { + if (window.XMLHttpRequest) { + XMLHttpRequestObject = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); + } + ;if (XMLHttpRequestObject) { + if (!postcp || postcp == 'GET') { + XMLHttpRequestObject.open("GET", url, true); + } else { + XMLHttpRequestObject.open("POST", url, true); + } + ;XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + XMLHttpRequestObject.onreadystatechange = function() { + if (XMLHttpRequestObject.readyState == 4) { + if (XMLHttpRequestObject.status == 200) { + fun(XMLHttpRequestObject.responseText); + } else { + fun("null"); + } + } + } + ; + if (!postcp || postcp == 'GET') { + XMLHttpRequestObject.send(null); + } else { + XMLHttpRequestObject.send(postcp); + } + } + } catch (e) { + fun("error"); + } + ; +} +;function readfile_t(url, postcp) { + var myString = ""; + var XMLHttpRequestObject = false; + try { + if (window.XMLHttpRequest) { + XMLHttpRequestObject = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); + } + ;if (XMLHttpRequestObject) { + if (!postcp || postcp == 'GET') { + XMLHttpRequestObject.open("GET", url, false); + XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + XMLHttpRequestObject.send(null); + } else { + XMLHttpRequestObject.open("POST", url, false); + XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + XMLHttpRequestObject.send(postcp); + } + ;myString = XMLHttpRequestObject.responseText; + return myString; + } else { + return myString; + } + } catch (e) { + return "error"; + } + ; +} +;function ifast_mod(i, b) { + return i % b; +} +;function ifast_div(i, b) { + if (!b) { + return parseInt(i); + } + ;return parseInt(i / b); +} +;function ifast_getobj(spid) { + return gameabc_getobj(spid); +} +;function set_rec(stringid, stringv) { + gameabc_GameTxt.GameTxtList[stringid].Text = stringv; +} +;function get_rec(stringid) { + return gameabc_GameTxt.GameTxtList[stringid].Text; +} +;function ifast_tel(tel) { + if (ifast_ispc() == 0) { + window.location.href = "tel://" + tel; + } else { + showmessage("模拟打电è¯:" + tel); + } +} +;function set_level_up(levelid, vsb) { + if (!gameabc_Layer.LayerList[levelid]) { + return; + } + ;gameabc_Layer.LayerList[levelid].vsb = vsb; + var t = gameabc_Layer.showorder; + t.removeval(levelid); + if (vsb == 1) { + t.push(levelid); + set_level(gameabc_Layer.showorder); + } +} +;function set_level(levelid, vsb, val) { + if (arguments.length == 1) { + var le = gameabc_Layer.LayerList; + gameabc_Layer.showorder = levelid; + for (yy = 0; yy < le.length; yy++) { + le[yy].vsb = 0; + } + ;for (yy = 0; yy < levelid.length; yy++) { + if (!le[levelid[yy]].Property) { + continue; + } + ;le[levelid[yy]].vsb = 1; + } + ;return; + } + ;if (!gameabc_Layer.LayerList[levelid]) { + return; + } + ;if (arguments.length == 2) { + gameabc_Layer.LayerList[levelid].vsb = vsb; + return; + } + ;if (vsb == 41) { + gameabc_Layer.LayerList[levelid].canclick = val; + } +} +;function set_group(groupid, cpid, val, mode, val2) { + var groups = gameabc_GroupList.GroupList; + var group; + var id; + for (var x = 0; x < groups.length; x++) { + if (groups[x].GroupID == groupid) { + group = groups[x].ObjectList; + for (var y = 0; y < group.length; y++) { + id = group[y]; + set_self(id, cpid, val, mode, val2); + } + } + } +} +;function get_self(id, cpid, val, mode, val2) { + var obj = gameabc_func.getobj(id); + if (ifast_isno(obj)) { + return 0; + } + ;var re = 0; + if (mode == 0) { + mode = -1; + } + ;switch (cpid) { + case 6: + re = obj.image; + break; + case 16: + re = obj.f; + break; + case 7: + if (obj.uipointer == 0) { + if (!val || val == 0) { + re = obj.caption; + } else { + if (typeof (val) == 'string') { + re = ifast_measureText(id, val); + } else { + re = ifast_measureText(id); + } + ; + } + } else { + re = gameabc_face.getdiv_text(obj.uipointer); + } + ;break; + case 1: + re = gamabc_getval(obj.recid, val, mode); + break; + case 33: + re = gamabc_getval(obj.scale, val, mode); + break; + case 34: + re = gamabc_getval(obj.arge, val, mode); + break; + case 35: + re = gamabc_getval(obj.ap, val, mode); + break; + case 36: + re = gamabc_getval(obj.hu, val, mode); + break; + case 45: + re = gamabc_getval(obj.cx, val, mode); + break; + case 46: + re = gamabc_getval(obj.cy, val, mode); + break; + case 51: + re = gamabc_getval(obj.jx, val, mode); + break; + case 18: + re = gamabc_getval(obj.x, val, mode); + break; + case 19: + re = gamabc_getval(obj.y, val, mode); + break; + case 20: + re = gamabc_getval(obj.w, val, mode); + break; + case 21: + re = gamabc_getval(obj.h, val, mode); + break; + case 43: + re = gamabc_getval(obj.frame, val, mode); + break; + case 37: + if (obj.uipointer == 0) { + re = gamabc_getval(obj.visbale, val, mode); + } else { + re = gameabc_face.getdiv_v(obj.uipointer); + } + ;break; + case 41: + re = gamabc_getval(obj.canclick, val, mode); + break; + case 44: + re = gamabc_getval(obj.groupid, val, mode); + break; + case 57: + re = gamabc_getval(obj.ontime, val, mode); + break; + case 58: + re = obj.color; + break; + case 28: + var t = {}; + t.x = obj.x; + t.y = obj.y; + t.w = obj.w; + t.h = obj.h; + re = t; + break; + default: + if (!obj["other" + cpid]) { + obj["other" + cpid] = 0; + } + ;re = gamabc_getval(obj["other" + cpid], val, mode); + break; + } + ;return re; +} +;function set_self(id, cpid, val, mode, val2) { + var obj = gameabc_func.getobj(id); + if (ifast_isno(obj)) { + return 0; + } + ;if (arguments.length == 3) { + mode = 0; + } + ;if (typeof (cpid) == "string") { + if (obj.uipointer != 0) { + obj.uipointer.setAttribute(cpid, val); + } + ;return; + } + ;switch (cpid) { + case 6: + obj.image = val; + break; + case 28: + if (typeof (val) == "object") { + obj.x = val.x; + obj.y = val.y; + obj.w = val.w; + obj.h = val.h; + } + ;break; + case 16: + if (val <= 0) { + obj.f = 0; + } else { + obj.f = ifast_getobj(val); + } + ;break; + case 58: + obj.color = val; + break; + case 7: + if (typeof (val) != "string") { + try { + val = val.toString(); + } catch (e) { + val = "null"; + } + } + ;if (obj.uipointer != 0) { + gameabc_face.setdiv_text(obj.uipointer, val); + } + ;obj.caption = val; + break; + case 1: + obj.recid = gamabc_getval(obj.recid, val, mode); + if (obj.recid <= 0) { + obj.image = null; + } else { + if (obj.recid < 10000) { + obj.image = gameabc_load_img2(obj.recid); + } else { + obj.image = gameabc_Image.addimgs["add" + obj.recid].img; + } + } + ;break; + case 33: + obj.scale = gamabc_getval(obj.scale, val, mode); + break; + case 34: + obj.arge = gamabc_getval(obj.arge, val, mode); + break; + case 35: + obj.ap = gamabc_getval(obj.ap, val, mode); + break; + case 36: + obj.hu = gamabc_getval(obj.hu, val, mode); + break; + case 45: + obj.cx = gamabc_getval(obj.cx, val, mode); + break; + case 46: + obj.cy = gamabc_getval(obj.cy, val, mode); + break; + case 51: + obj.jx = gamabc_getval(obj.jx, val, mode); + break; + case 18: + obj.x = gamabc_getval(obj.x, val, mode); + break; + case 19: + obj.y = gamabc_getval(obj.y, val, mode); + break; + case 20: + obj.w = gamabc_getval(obj.w, val, mode); + break; + case 21: + obj.h = gamabc_getval(obj.h, val, mode); + break; + case 43: + obj.frame = gamabc_getval(obj.frame, val, mode); + break; + case 37: + if (obj.uipointer != 0) { + gameabc_face.setdiv_v(obj.uipointer, val); + } + ;obj.visbale = gamabc_getval(obj.visbale, val, mode); + break; + case 41: + obj.canclick = gamabc_getval(obj.canclick, val, mode); + break; + case 44: + obj.groupid = gamabc_getval(obj.groupid, val, mode); + break; + case 57: + obj.ontime = gamabc_getval(obj.ontime, val, mode); + if (obj.ontime == 0) { + obj.click_time = 0; + } + ;break; + default: + if (!obj["other" + cpid]) { + obj["other" + cpid] = 0; + } + ;obj["other" + cpid] = gamabc_getval(obj["other" + cpid], val, mode); + break; + } + ;if (obj.ObjectType == 5) { + obj.charge(obj.x, obj.y, obj.w, obj.h); + } +} +;function ifast_getrectdec(allrect, syrect, Align, SizeStyle, size, dec) { + return getmyrectdec(allrect, syrect, Align, SizeStyle, size, dec); +} +;function ifast_getrect(spid, Align, SizeStyle, size) { + var rect1; + if (spid <= 0) { + return ifast_rect(0, 0, window.innerWidth, window.innerHeight); + } + ;rect1 = get_self(spid, 28); + if (!Align) { + return rect1; + } + ;return getmyrectdec(rect1, rect1, Align, SizeStyle, size, 0); +} +;function ifast_checksprite(spido, spidd) { + var o = get_self(spido, 28); + var d = get_self(spidd, 28); + return ifast_checkrect(o, d); +} +;function ifast_checkpoint(x, y, d) { + if (x >= d.x && x <= d.x + d.w && y >= d.y && y <= d.y + d.h) { + return 1; + } else { + return 0; + } +} +;function ifast_checkrect(o, d) { + if (d.x >= o.w || d.y >= o.h) { + return 0; + } else { + return 1; + } + ;if (d.x + d.w <= o.x || d.y + d.h < o.y) { + return 0; + } else { + return 1; + } + ;var px; + var py; + px = o.x <= d.x ? d.x : o.x; + py = o.y <= d.y ? d.y : o.y; + if (px >= o.x && px <= o.x + o.w && py >= o.y && py <= o.y + o.h && px >= d.x && px <= d.x + d.w && py >= d.y && py <= d.y + d.h) { + return 1; + } else { + return 0; + } +} +;function ifast_rectalign(rects, mode, pointx, y) { + var point; + if (arguments.length == 3) { + point = pointx; + } else { + point = ifast_rect(pointx, y, 0, 0); + } + ;var rect1 = ifast_rect(rects); + switch (mode) { + case 1: + rect1 = ifast_rectoffxy(rect1, point.x, point.y); + break; + case 2: + rect1.x = point.x + rect1.x - rect1.w; + rect1.y = point.y + rect1.y; + break; + case 3: + rect1.x = point.x + rect1.x - rect1.w; + rect1.y = point.y + rect1.y - rect1.h; + break; + case 4: + rect1.x = point.x + rect1.x; + rect1.y = point.y + rect1.y - rect1.h; + break; + case 5: + rect1.x = point.x + rect1.x - parseInt(rect1.w * 0.5); + rect1.y = point.y + rect1.y - parseInt(rect1.h * 0.5); + break; + default: + break; + } + ;return rect1; +} +;function ifast_spritealignxy(offx, offy, spids, modeds, cx, cy) { + var rect1 = get_self(spids, 28); + rect1.x = offx; + rect1.y = offy; + var rect2; + rect2 = ifast_rectalign(rect1, modeds, cx, cy); + set_self(spids, 28, rect2); +} +;function ifast_spritealign(offx, offy, spids, modeds, spidd, moded) { + var rect1 = get_self(spids, 28); + rect1.x = offx; + rect1.y = offy; + var rect2 = get_self(spidd, 28); + rect2 = ifast_point(rect2, moded); + rect2 = ifast_rectalign(rect1, modeds, rect2); + set_self(spids, 28, rect2); +} +;function ifast_point(r, mode) { + var rect1; + rect1 = ifast_rect(r.x, r.y, r.w, r.h); + switch (mode) { + case 1: + break; + case 2: + rect1.x += rect1.w; + break; + case 3: + rect1.x += rect1.w; + rect1.y += rect1.h; + break; + case 4: + rect1.y += rect1.h; + break; + case 5: + rect1.x += parseInt(rect1.w * 0.5); + rect1.y += parseInt(rect1.h * 0.5); + break; + } + ;return rect1; +} +;function ifast_rectscwh(r, sw, sh) { + var rect1; + rect1 = ifast_rect(r.x, r.y, r.w, r.h); + rect1.w = parseInt(r.w * sw); + rect1.h = parseInt(r.h * sh); + return rect1; +} +;function ifast_rectoffxy(r, x, y) { + var rect1 = {}; + rect1.x = x + r.x; + rect1.y = y + r.y; + rect1.w = r.w; + rect1.h = r.h; + return rect1; +} +;function ifast_rect(ox, oy, ow, oh) { + var rect1 = {}; + if (arguments.length < 4) { + rect1.x = ox.x; + rect1.y = ox.y; + rect1.w = ox.w; + rect1.h = ox.h; + } else { + rect1.x = ox; + rect1.y = oy; + rect1.w = ow; + rect1.h = oh; + } + ;return rect1; +} +;function ifast_setkey(id, key, val) { + if (ifast_hashmaps['my' + id] == undefined) { + ifast_hashmaps['my' + id] = {}; + } + ;ifast_hashmaps['my' + id]['my' + key] = val; +} +;function ifast_getkey(id, key) { + if (ifast_hashmaps['my' + id] == undefined) { + ifast_hashmaps['my' + id] = {}; + return null; + } + ;return ifast_hashmaps['my' + id]['my' + key]; +} +;function ifast_delkey(id, key) { + if (ifast_hashmaps['my' + id] == undefined) { + ifast_hashmaps['my' + id] = {}; + } + ;delete ifast_hashmaps['my' + id]['my' + key]; +} +;function ifast_addtospritefromspritecopy(fspid, copyspid, x, y, tag) { + if (fspid <= 0) { + return; + } + ;var fobj = ifast_getobj(fspid); + var obj2 = new GameObject().addtospritefromspritecopy(fspid, copyspid, x, y, tag); + return fspid + 'add' + tag; +} +;function ifast_dllpritefromspritecopy(fspid, tag) { + if (fspid <= 0) { + return; + } + ;var fobj = ifast_getobj(fspid); + fobj.dllpritefromspritecopy(tag); +} +;function ifast_check_add(spid, x1, y1) { + return gameabc_check_add(spid, x1, y1) +} +;function ifast_ispc() { + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; + var flag = 1; + for (var v = 0; v < Agents.length; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = 0; + break; + } + } + ;return flag; +} +;function ifast_checkimg(image_id, upwh) { + gameabc_face.drawcharge = 1; + var obj; + if (image_id < 10000) { + obj = gameabc_Image.ImageFileList[image_id]; + if (!obj) { + return 0; + } + ;if (obj.img.error != 0) { + return -obj.img.error; + } + ;if (upwh == 1) { + obj.w1 = parseInt(obj.w1 * (obj.img.width / obj.img.allw)); + obj.h1 = parseInt(obj.h1 * (obj.img.height / obj.img.allh)); + obj.img.allw = obj.img.width; + obj.img.allh = obj.img.height; + } + ;return obj.img.ok; + } else { + if (!gameabc_Image.addimgs) { + gameabc_Image.addimgs = {}; + } + ;obj = gameabc_Image.addimgs["add" + image_id]; + if (!obj) { + return 0; + } + ;if (obj.img.error != 0) { + return -obj.img.error; + } + ;if (upwh == 1) { + obj.w1 = parseInt(obj.w1 * (obj.img.width / obj.img.allw)); + obj.h1 = parseInt(obj.h1 * (obj.img.height / obj.img.allh)); + obj.img.allw = obj.img.width; + obj.img.allh = obj.img.height; + } + ;return obj.img.ok; + } +} +;function ifast_addimgfromimgcopy(fimgid, copyimgid, url) { + if (fimgid > 10000) { + alert('ifast_addimgfromimgcopy:fimgid:å¿…é¡»å°äºŽ10000'); + return -1; + } + ;if (copyimgid < 10000) { + alert('ifast_addimgfromimgcopy:copyimgid:必须大于等于10000'); + return -2; + } + ;if (!gameabc_Image.addimgs) { + gameabc_Image.addimgs = {}; + } + ;var obj = gameabc_Image.addimgs["add" + copyimgid]; + if (obj) { + return; + } + ;gameabc_Image.addimgs["add" + copyimgid] = {}; + obj = gameabc_Image.addimgs["add" + copyimgid]; + var objimg = gameabc_Image.ImageFileList[fimgid]; + if (!objimg.id) { + alert('ifast_addimgfromimgcopy:fimgid:没有属性'); + return -3; + } + ;obj.img = new Image(); + obj.img.id = copyimgid; + obj.img.ok = 0; + obj.img.allw = objimg.w_all; + obj.img.allh = objimg.h_all; + obj.img.error = 0; + obj.id = copyimgid; + obj.w_all = objimg.w_all; + obj.h_all = objimg.h_all; + obj.h = objimg.h; + obj.w = objimg.w; + obj.frame_all = objimg.frame_all; + obj.w1 = objimg.w1; + obj.h1 = objimg.h1; + obj.img.src = url; + obj.img.pathx = url; + obj.img.onload = function() { + this.ok = 1; + obj.w_all = this.width; + obj.h_all = this.height; + obj.w1 = parseInt(this.width / obj.w); + obj.h1 = parseInt(this.height / obj.h); + } + ; + obj.img.onerror = function() { + this.error = this.error + 1; + if (this.error < 3) { + obj.img.src = ''; + obj.img.src = obj.img.pathx; + } + } +} +;function ifast_delimgfromimgcopy(recid) { + if (!gameabc_Image.addimgs) { + gameabc_Image.addimgs = {}; + } + ;var obj = gameabc_Image.addimgs["add" + copyimgid]; + if (obj) { + delete obj.img; + delete gameabc_Image.addimgs["add" + copyimgid]; + } + ; +} +;function ifast_loadhtml(htmltxt) { + document.open(); + document.write(htmltxt); + document.close(); +} +;function ifast_split(str1, str2) { + return str1.split(str2); +} +;function draw_bg(recid) { + var img = gameabc_load_img2(recid); + if (g_GameObjectManager.d2dbj) { + g_GameObjectManager.d2dbj.drawImage(img, 0, 0, g_GameObjectManager.canvas.width, g_GameObjectManager.canvas.height); + g_GameObjectManager.userbj = 1; + } + ; +} +;function other_replaceall(sstr, key1, ostr) { + if (arguments.length == 2) { + var news = sstr; + var key; + if (typeof (key1) == 'string') { + key = eval("(" + key1 + ")"); + } else { + key = key1; + } + ;for (var kayname in key) { + news = other_replaceall(news, '{{' + kayname + '}}', key[kayname]); + } + ;return news; + } + ;var regS = new RegExp(key1,"g"); + return sstr.replace(regS, ostr); +} +;function other_upimgsrc(id, str) { + var obj = window.document.getElementById(id); + obj.src = str; +} +;function other_upinnerHTML(id, str, isadd) { + var obj = window.document.getElementById(id); + if (isadd) { + obj.innerHTML = obj.innerHTML + str; + } else { + obj.innerHTML = str; + } +} +;function other_upkey(id, key, ostr) { + var obj = window.document.getElementById(id); + obj.setAttribute(key, ostr); +} +;function other_setdom(id, key, val) { + var obj; + if (typeof (id) == 'string') { + obj = gameabc_face.getdiv(id); + } else { + obj = id; + } + ;obj.setAttribute(key, val); +} +;function other_deldom(id) { + var obj; + if (typeof (id) == 'string') { + obj = gameabc_face.getdiv(id); + } else { + obj = id; + } + ;obj.parentNode.removeChild(obj); +} +;function other_creatdom(mode) { + var inText = document.createElement(mode); + return inText; +} +;function other_offdomxywh(sdom, ddom, offx, offy, ww, hh) { + var obj; + if (typeof (sdom) == 'string') { + obj = gameabc_face.getdiv(sdom); + } else { + obj = sdom; + } + ;var obj2; + if (typeof (ddom) == 'string') { + obj2 = gameabc_face.getdiv(ddom); + } else { + obj2 = ddom; + } + ;if (obj2 == null) { + return; + } + ;obj2.style.position = 'absolute'; + if (!offx) { + offx = 0; + } else { + offx = parseInt(offx / gameabc_face.mouse_sx); + } + ;if (!offy) { + offy = 0; + } else { + offy = parseInt(offy / gameabc_face.mouse_sy); + } + ;if (!ww) { + ww = obj.width; + } else { + ww = parseInt((ww) / gameabc_face.mouse_sx); + } + ;if (!hh) { + hh = obj.height; + } else { + hh = parseInt((hh) / gameabc_face.mouse_sy); + } + ;obj2.style.left = parseInt(obj.style.left) + offx + 'px'; + obj2.style.top = parseInt(obj.style.top) + offy + 'px'; + obj2.width = ww; + obj2.height = hh; +} +;function other_appdom(pdom, dom) { + var obj; + if (typeof (pdom) == 'string') { + obj = gameabc_face.getdiv(pdom); + } else { + obj = pdom; + } + ;obj.appendChild(dom); +} +;function other_setdom_v(pdom, v) { + var obj; + if (typeof (pdom) == 'string') { + obj = gameabc_face.getdiv(pdom); + } else { + obj = pdom; + } + ;if (v == 0) { + obj.style.display = "none"; + } else { + obj.style.display = "block"; + } +} +;function ifast_urlstr(sstr) { + return encodeURIComponent(sstr); +} +;function ifast_unurlstr(sstr) { + return decodeURIComponent(sstr); +} +;function ifast_checkjsonstr(v) { + v = other_replaceall(v, "\n", "\\n"); + v = other_replaceall(v, "\r", "\\r"); + return v; +} +;ifastunit = 7; +var gameabc_func = gameabc_func || {}; +function set_self2(name, cpid, val, mode, val2) {} +;function get_self2(name, cpid, val, mode, val2) {} +;gameabc_func.resizespanle2 = function(uidata, obj, allwh, mode) { + var wh = {}; + switch (mode) { + case 0: + wh = allwh; + break; + case 1: + break; + case 2: + break; + } + ;return wh; +} +; +gameabc_func.resizespanle = function(levelid, w, h) { + var objs = gameabc_Layer.LayerList[levelid].ObjectList; + var i; + var objid; + var obj; + var l = objs.length; + var allwh = {}; + allwh.x = 0; + allwh.y = 0; + allwh.w = w; + allwh.w = h; + var sywh = {}; + sywh.x = 0; + sywh.y = 0; + sywh.w = w; + sywh.w = h; + for (i = 0; i < l; i++) { + objid = objs[i]; + obj = gameabc_func.getobj(objid); + if (ifast_isno(obj)) { + continue; + } + ;if (obj.uidata.ObjectType == 6) { + if (obj.uidata.SizeStyle <= 1) { + sywh = gameabc_func.resizespanle2(obj.uidata, obj, allwh, obj.uidata.SizeStyle); + } else { + sywh = gameabc_func.resizespanle2(obj.uidata, obj, sywh, obj.uidata.SizeStyle); + } + ; + } + ; + } +} +; +gameabc_func.getobj = function(id) { + if (id < 1) { + return gameabc_face.obj; + } + ;return gameabc_Object["sp" + id]; +} +; +function gamabc_getval(val, val2, mode) { + switch (mode) { + case -1: + return val; + break; + case 0: + return val2; + break; + case 1: + return val + val2; + break; + case 2: + return val - val2; + break; + case 3: + return parseInt(val * val2); + break; + case 4: + return parseInt(val / val2); + break; + default: + return val; + break; + } +} +;gameabc_func.setioplay = function() { + setioplay(); +} +; +gameabc_func.getval = function(val, val2, mode) { + gamabc_getval(val, val2, mode); +} +; +gameabc_func.get_self = function(id, cpid, val, mode, val2) { + return get_self(id, cpid, val, mode, val2); +} +; +gameabc_func.set_self = function(id, cpid, val, mode, val2) { + set_self(id, cpid, val, mode, val2); +} +; +gameabc_func.set_group = function(groupid, cpid, val, mode, val2) { + set_group(groupid, cpid, val, mode, val2); +} +; +gameabc_func.set_level = function(levelid, vsb) { + set_level(levelid, vsb); +} +; +function gameabc_insert_sp() {} +;function gameabc_del_sp() {} +;function gameabc_getrect1() {} +;function gameabc_getrect2(recid, frame) { + var obj; + if (recid < 10000) { + obj = gameabc_Image.ImageFileList[recid]; + } else { + obj = gameabc_Image.addimgs['add' + recid]; + if (!obj) { + alert('add' + recid + 'ä¸å­˜åœ¨ï¼'); + } + ; + } + ;var w = obj.w1; + var h = obj.h1; + var x = obj.w; + var y = obj.h; + var frame_all = obj.frame_all; + frame = frame - 1; + if (frame < 0) + frame = 0; + frame = frame % frame_all; + var py = parseInt(frame / x); + var px = frame % x; + var r = {}; + r.x = px * w; + r.y = py * h; + r.w = w; + r.h = h; + return r; +} +;function gameabc_loadui1(canvas1, w, h) {} +;function gameabc_loaduiall() { + gameabc_loadui2(); +} +;function gameabc_getobj(id) { + if (id < 1) { + return gameabc_face.obj; + } + ;return gameabc_Object["sp" + id]; +} +;function gameabc_check_add(spid, x1, y1) { + var id = -99999999; + var i; + var obj = ifast_getobj(spid); + var obj2; + var x; + var y; + var w; + var h; + if (obj.addlist) { + var l = obj.addlist.length; + if (l > 0) { + for (i = l - 1; i >= 0; i--) { + obj2 = obj[obj.addlist[i]]; + if (!obj2) {//---xwb------- + continue; + } + if (!obj2.visbale) {//---xwb------- + continue; + } + if (obj2.visbale == false) { + continue; + } + ;if (obj2.canclick == false) { + continue; + } + ;if (obj2.ObjectType == 6) { + continue; + } + ;x = obj2.x + obj.x; + y = obj2.y + obj.y; + w = obj2.w; + h = obj2.h; + if (x1 >= x && x1 < x + w && y1 > y && y1 < y + h) { + return obj2.add_fatag; + } + } + } + } + ;return id; +} +;function gameabc_check_click2(x1, y1) { + var le = gameabc_Layer.LayerList; + var order = gameabc_Layer.showorder; + var orderlen = order.length; + var xx; + var yy; + var yy1; + var ok = 0; + var list; + for (yy1 = orderlen - 1; yy1 >= 0; yy1--) { + yy = order[yy1]; + if (!le[yy].Property) { + continue; + } + ;if (le[yy].vsb == 0) { + continue; + } + ;if (le[yy].canclick == 0) { + continue; + } + ;list = le[yy].ObjectList; + for (xx = list.length - 1; xx >= 0; xx--) { + obj = gameabc_Object["sp" + list[xx]]; + if (obj) { + ok = gameabc_check_click1(obj, x1, y1); + if (ok != 0) { + return ok; + } + } else { + if (!gameabc_face.tsbb) { + showmessage('版本å¯èƒ½æœªæ³¨å†Œï¼'); + gameabc_face.tsbb = 1; + } + } + } + ;if (ok != 0) { + return ok; + } + } + ;return 0; +} +;function gameabc_check_click1(obj, x1, y1) { + if (obj.visbale == false) { + return 0; + } + ;if (obj.canclick == false) { + return 0; + } + ;if (obj.ObjectType == 6) { + return 0; + } + ;if (gameabc_Layer.LayerList[obj.z].vsb == false) { + return 0; + } + ;if (obj.f) { + x = obj.x + obj.f.x; + y = obj.y + obj.f.y; + } else { + x = obj.x; + y = obj.y; + } + ;w = obj.w; + h = obj.h; + if (x1 >= x && x1 < x + w && y1 > y && y1 < y + h) { + return obj.objid; + } + ;return 0; +} +;function gameabc_check_click(x1, y1) { + return gameabc_check_click2(x1, y1); + var obs = g_GameObjectManager.gameObjects; + var i; + var x; + var y; + var w; + var h; + var ob; + for (i = obs.length - 1; i >= 0; i--) { + if (obs[i].visbale == false) { + continue; + } + ;if (obs[i].canclick == false) { + continue; + } + ;if (obs[i].ObjectType == 6) { + continue; + } + ;if (gameabc_Layer.LayerList[obs[i].z].vsb == false) { + continue; + } + ;if (obs[i].f) { + x = obs[i].x + obs[i].f.x; + y = obs[i].y + obs[i].f.y; + } else { + x = obs[i].x; + y = obs[i].y; + } + ;w = obs[i].w; + h = obs[i].h; + if (x1 >= x && x1 < x + w && y1 > y && y1 < y + h) { + return obs[i].objid; + } + } + ;return 0; +} +;function gameabc_loadui2(ObjectID) { + if (arguments.length == 0) { + gameabc_face.ifast_app = 0; + gameabc_face.logmessage("gameabc_loadui2"); + if (!gameabc_Layer.showorder) { + gameabc_Layer.showorder = []; + gameabc_Layer.showtimelist = []; + } + ;var i; + for (i = 1; i < gameabc_Object.ObjectList.length; i++) { + gameabc_loadui2(i); + } + ;var d = 1; + var okle; + for (d = 1; d < gameabc_Layer.LayerList.length; d++) { + okle = gameabc_Layer.LayerList[d]; + okle.vsb = 1; + okle.canclick = 1; + okle.ontimelist = []; + gameabc_Layer.showorder[d - 1] = d; + if (!okle.allrect) { + okle.allrect = {}; + okle.syrect = {}; + okle.myrect = {}; + } + } + ;for (i = 1; i < gameabc_Object.ObjectList.length; i++) { + var objx = gameabc_Object.ObjectList[i].Property; + if (!objx) { + continue; + } + ;if (!objx.obj2) { + continue; + } + ;var fun = gameabc_face["ontimer_" + objx.ObjectID]; + if (fun) { + okle = gameabc_Layer.LayerList[objx.BelongLayerID]; + okle.ontimelist.push(objx.ObjectID); + } + ;if (objx.obj2.f > 0) { + objx.obj2.f = ifast_getobj(objx.obj2.f); + } + ; + } + ;for (d = 1; d < gameabc_Layer.LayerList.length; d++) { + okle = gameabc_Layer.LayerList[d]; + if (okle.ontimelist.length > 0) { + gameabc_Layer.showtimelist.push(d); + } + } + ;gameabc_face.loadui2 = 1; + return; + } + ;var objs = gameabc_Object.ObjectList; + var obj = gameabc_Object.ObjectList[ObjectID].Property; + if (!obj) { + return; + } + ;if (obj.obj2) { + if (obj.obj2 != null) { + return; + } + } + ;var obj2 = null; + var op = obj.ObjectType; + var x = obj.Left; + var y = obj.Top; + var z = obj.BelongLayerID; + var zorder = z * 10000 + obj.IndexOfLayer; + var w = obj.Width; + var h = obj.Height; + var f = obj.FrameIndex; + var recid = obj.ImageFileID; + var Parent = obj.Parent; + switch (op) { + case 6: + obj2 = new gameabc_panle().gameabc_open(ObjectID, x, y, zorder, w, h); + obj2.Align = obj.Align; + obj2.SizeStyle = obj.SizeStyle; + obj2.Size = obj.Size; + gameabc_face.ifast_app = 1; + break; + case 5: + obj2 = new gameabc_list().gameabc_open(ObjectID, x, y, zorder, w, h); + obj2.charge(obj.Left, obj.Top, obj.Width, obj.Height, 0, 0); + break; + case 2: + var imgid = obj.ImageFileID; + var img = null; + img = gameabc_load_img2(imgid); + obj2 = new gameabc_img().gameabc_open(img, x, y, zorder); + obj2.objid = ObjectID; + obj2.w = w; + obj2.h = h; + obj2.frame = f; + obj2.recid = recid; + obj2.classid = op; + obj2.caption = obj.TextFrames; + break; + case 3: + f = obj.GameTxtID; + obj2 = new gameabc_imgtxt().gameabc_open("", x, y, zorder); + obj2.objid = ObjectID; + obj2.classid = op; + obj2.w = w; + obj2.h = h; + obj2.frame = f; + if (obj.GameTxtStyle > 0) { + var t = 0; + if (obj.GameTxtStyle < 3) { + if (obj.Data) { + t = parseInt(obj.Data); + } + } + ;obj2.uipointer = gameabc_face.addinputdiv("div" + ObjectID, obj.GameTxtStyle - 1 + t, x, y, w, h); + if (obj2.uipointer) { + obj2.uipointer.mode = obj.GameTxtStyle - 1; + gameabc_face.setdiv_text(obj2.uipointer, gameabc_GameTxt.GameTxtList[f].Text); + } + ; + } + ;break; + case 4: + var txt = objs[ObjectID].Property.Text; + obj2 = new gameabc_txt().gameabc_open(txt, x, y, zorder); + obj2.objid = ObjectID; + obj2.classid = op; + obj2.w = w; + obj2.h = h; + if (obj.GameTxtStyle > 0) { + if (obj.Data) { + obj.GameTxtStyle = parseInt(obj.Data); + } + ;obj2.uipointer = gameabc_face.addinputdiv("div" + ObjectID, obj.GameTxtStyle - 1, x, y, w, h); + if (obj2.uipointer) { + obj2.uipointer.mode = obj.GameTxtStyle - 1; + gameabc_face.setdiv_text(obj2.uipointer, txt); + } + ; + } + ;break; + } + ;if (obj2) { + gameabc_Object["sp" + ObjectID] = obj2; + obj2.classid = op; + obj.obj2 = obj2; + obj2.z = z; + if (Parent) { + obj2.f = Parent; + } + ;obj2.uidata = obj; + if (obj.canclick) { + obj2.canclick = obj.canclick; + } + ;if (objs[ObjectID].visbale) { + obj2.visbale = obj.visbale; + } + ;obj2.ontime = obj.TimerInterval; + obj2.groupid = obj.GroupID; + obj2.levelobj = gameabc_Layer.LayerList[z]; + } + ; +} +;function gameabc_getnewxywh2(myw, myh, w, h, cj) { + var sh, sw, ss, neww, newh, neww2, newh2; + sh = h / myh; + sw = w / myw; + var offx = 0 + , offy = 0; + switch (cj) { + case 2: + ss = Math.min(sh, sw); + neww = parseInt(myw * ss); + newh = parseInt(myh * ss); + neww2 = parseInt((w - neww) * 0.5); + newh2 = parseInt((h - newh) * 0.5); + if (Math.abs(neww2) > Math.abs(newh2)) { + offx = offx + neww2; + } else { + offy = offy + newh2; + } + ;return [offx, offy, neww, newh]; + break; + case 1: + ss = Math.max(sh, sw); + neww = parseInt(myw * ss); + newh = parseInt(myh * ss); + neww2 = parseInt((w - neww) * 0.5); + newh2 = parseInt((h - newh) * 0.5); + if (Math.abs(neww2) > Math.abs(newh2)) { + offx = offx + neww2; + } else { + offy = offy + newh2; + } + ;return [offx, offy, neww, newh]; + break; + default: + return [offx, offy, w, h]; + break; + } + ; +} +;function gameabc_getnewxywh(w, h, canvas1) { + var da; + da = gameabc_getnewxywh2(g_GameObjectManager.backBuffer.width, g_GameObjectManager.backBuffer.height, w, h, gameabc_face.jm_sj_cj); + gameabc_face.sy_x = da[0]; + gameabc_face.sy_y = da[1]; + gameabc_face.sy_w = da[2]; + gameabc_face.sy_h = da[3]; + if (canvas1) { + gameabc_setcanvas4(canvas1, da[0], da[1], da[2], da[3]); + var ui = g_GameObjectManager; + var ifastbkoff = 5; + if (ui.bg1) { + if (da[0] > 0) { + ui.bg1.height = h; + ui.bg1.width = da[0] + ifastbkoff; + ui.bg1.style.height = h + "px"; + ui.bg1.style.width = da[0] + ifastbkoff + "px"; + ui.bg1.style.left = 0 + "px"; + ui.bg1.style.top = 0 + "px"; + ui.d2dbj1.fillStyle = "red"; + ui.d2dbj1.clearRect(0, 0, ui.bg1.width, ui.bg1.height); + ui.bg1.x = 0; + ui.bg1.y = 0; + ui.bg1.w = da[0] + ifastbkoff; + ui.bg1.h = h; + ui.bg2.height = h; + ui.bg2.width = da[0] + ifastbkoff; + ui.bg2.style.height = h + "px"; + ui.bg2.style.width = da[0] + ifastbkoff + "px"; + ui.bg2.style.left = da[0] + da[2] - ifastbkoff + "px"; + ui.bg2.style.top = 0 + "px"; + ui.d2dbj2.fillStyle = "yellow"; + ui.d2dbj2.clearRect(0, 0, ui.bg2.width, ui.bg2.height); + ui.bg2.x = da[0] + da[2] - ifastbkoff; + ui.bg2.y = 0; + ui.bg2.w = da[0] + ifastbkoff; + ui.bg2.h = h; + } else { + ui.bg1.height = da[1] + ifastbkoff; + ui.bg1.width = w; + ui.bg1.style.height = da[1] + ifastbkoff + "px"; + ui.bg1.style.width = w + "px"; + ui.bg1.style.left = 0 + "px"; + ui.bg1.style.top = 0 + "px"; + ui.d2dbj1.fillStyle = "red"; + ui.d2dbj1.clearRect(0, 0, ui.bg1.width, ui.bg1.height); + ui.bg1.x = 0; + ui.bg1.y = 0; + ui.bg1.w = 0; + ui.bg1.h = da[1] + ifastbkoff; + ui.bg2.height = da[1] + ifastbkoff; + ui.bg2.width = w; + ui.bg2.style.height = da[1] + ifastbkoff + "px"; + ui.bg2.style.width = w + "px"; + ui.bg2.style.left = 0 + "px"; + ui.bg2.style.top = da[1] + da[3] - ifastbkoff + "px"; + ui.d2dbj2.fillStyle = "yellow"; + ui.d2dbj2.clearRect(0, 0, ui.bg2.width, ui.bg2.height); + ui.bg2.x = 0; + ui.bg2.y = da[1] + da[3] - ifastbkoff; + ui.bg2.w = w; + ui.bg2.h = da[1] + ifastbkoff; + } + } + } + ; +} +;function gameabc_setcanvas4(canvas1, x, y, w, h) { + if (!gameabc_face.dfwgao) { + canvas1.height = h; + canvas1.width = w; + } else { + canvas1.height = h * iui.ratio; + canvas1.width = w * iui.ratio; + canvas1.style.height = h + "px"; + canvas1.style.width = w + "px"; + } + ;canvas1.style.left = x + "px"; + canvas1.style.top = y + "px"; + canvas1.left = x; + canvas1.top = y; + gameabc_face.sy_x = x; + gameabc_face.sy_y = y; + gameabc_face.sy_w = w; + gameabc_face.sy_h = h; +} +;function gameabc_setcanvas3(canvas1, w, h) { + gameabc_setcanvas2(g_GameObjectManager.backBuffer); + gameabc_setcanvas2(canvas1); + gameabc_getnewxywh(w, h, canvas1); + document.body.style.backgroundColor = "black"; + gameabc_face.showmode = 0; + gameabc_face.mouse_sx = g_GameObjectManager.backBuffer.width / gameabc_face.sy_w; + gameabc_face.mouse_sy = g_GameObjectManager.backBuffer.height / gameabc_face.sy_h; + if (gameabc_face.jm_sj_xz == 1) { + var x1 = g_GameObjectManager.backBuffer.width / g_GameObjectManager.backBuffer.height; + var y1 = w / h; + if (x1 > 1 && y1 > 1) { + gameabc_face.jm_sj_tong = 1; + } + ;if (x1 < 1 && y1 < 1) { + gameabc_face.jm_sj_tong = 1; + } + ;if (x1 > 1 && y1 < 1) { + gameabc_face.jm_sj_tong = 0; + } + ;if (x1 < 1 && y1 > 1) { + gameabc_face.jm_sj_tong = 0; + } + ; + } + ; +} +;function gameabc_setcanvas1(canvas1, w, h) { + canvas1.height = h; + canvas1.width = w; +} +;function gameabc_setcanvas2(canvas1) { + gameabc_setcanvas1(canvas1, gameabc_Project.Property.ScreenWidth, gameabc_Project.Property.ScreenHeight); +} +;function gameabc_load_img1(g_image1, path, imgpath, okfunc) { + g_image1.error = 0; + g_image1.ok = 0; + var count = 0; + g_image1.onload = function() { + this.ok = 1; + gameabc_face.img_list_downing.removeObject(this); + if (this.backBuffer) { + delete this.backBuffer; + delete this.mydc; + } + ;this.backBuffer = undefined; + gameabc_check_img_ok(); + if (gameabc_face.onloadurl) { + gameabc_face.drawcharge = 1; + gameabc_face.onloadurl(0, 1, this.pathx, 0, gameabc_face.loadcount); + } else { + gameabc_face.drawcharge = 1; + if (gameabc_face.loadcount == 100) { + game_close_zsmsg(""); + } else { + game_open_zsmsg(gameabc_face.loadcount + "%" + " 加载..."); + } + ; + } + ; + } + ; + g_image1.onerror = function() { + this.error = this.error + 1; + if ( this.error>10 ) {return}; + gameabc_face.drawcharge = 1; + if (this.error == 3) { + var canvas = document.createElement("canvas"); + canvas.width = this.allw; + canvas.height = this.allh; + var c2d = canvas.getContext("2d"); + c2d.drawImage(gameabc_face.banall_img, 0, 0, 1, 1, 0, 0, this.allw, this.allh); + this.src = canvas.toDataURL("image/png"); + this.ok = 1; + gameabc_face.img_list_downing.removeObject(this); + if (this.backBuffer) { + delete this.backBuffer; + delete this.mydc; + } + ;this.backBuffer = undefined; + canvas = null; + } else { + this.src = this.pathx + "?kk=" + ifast_random(gameabc_face.randombase) + 10; + return; + } + ;gameabc_check_img_ok(); + if (gameabc_face.onloadurl) { + gameabc_face.drawcharge = 1; + gameabc_face.onloadurl(0, 1, this.pathx, 1, gameabc_face.loadcount); + } else { + gameabc_face.drawcharge = 1; + if (gameabc_face.loadcount == 100) { + game_close_zsmsg(""); + } else { + game_open_zsmsg(gameabc_face.loadcount + "%" + " 加载..."); + } + ; + } + } + + ; + g_image1.src_pre = path + "/" + imgpath + "?kk=" + ifast_random(gameabc_face.randombase) + 10; + gameabc_face.img_list_pre.push(g_image1); + g_image1.pathx = path + "/" + imgpath; +} +;function gameabc_check_img_ok(image_id) { + if (image_id > 0) { + if (!gameabc_Image.ImageFileList[image_id].img) { + return 0; + } + ;return gameabc_Image.ImageFileList[image_id].img.ok; + } else { + var i; + var y = 0; + var t = 0; + for (i = 1; i < gameabc_Image.ImageFileList.length; i++) { + if (!gameabc_Image.ImageFileList[i].img) { + continue; + } + ;t++; + if (gameabc_Image.ImageFileList[i].img.ok == 1) { + y++; + } + } + ;if (y >= t) { + gameabc_face.loadcount = 100; + return 100; + } else { + gameabc_face.loadcount = parseInt((y / t) * 100); + return gameabc_face.loadcount; + } + } +} +;function gameabc_load_img_ok(image_id) { + gameabc_Image.ImageFileList[image_id].img.ok = 1; +} +;function gameabc_load_img3(image_id, okfunc) { + var objimg = gameabc_Image.ImageFileList[image_id]; + game_abc_imgpath = gameabc_face.path; + if (objimg.img == undefined) { + objimg.img = new Image(); + objimg.img.id = image_id; + objimg.img.ok = 0; + objimg.img.allw = objimg.w_all; + objimg.img.allh = objimg.h_all; + gameabc_load_img1(objimg.img, game_abc_imgpath, objimg.bmp, okfunc) + } + ;return objimg.img; +} +;function gameabc_load_img_add(image_id, url, okfunc) { + game_abc_imgpath = gameabc_face.path; + var objimg = gameabc_Image.ImageFileList[image_id]; + if (objimg.img == undefined) { + objimg.img = new Image(); + objimg.img.id = image_id; + objimg.img.ok = 0; + objimg.img.allw = objimg.w_all; + objimg.img.allh = objimg.h_all; + gameabc_load_img1(objimg.img, game_abc_imgpath, objimg.bmp, okfunc) + } + ;return objimg.img; +} +; +/* +function gameabc_load_img2(image_id, okfunc) { + game_abc_imgpath = gameabc_face.path; + var objimg = gameabc_Image.ImageFileList[image_id]; + if (objimg.img == undefined) { + objimg.img = new Image(); + objimg.img.id = image_id; + objimg.img.ok = 0; + objimg.img.allw = objimg.w_all; + objimg.img.allh = objimg.h_all; + gameabc_load_img1(objimg.img, game_abc_imgpath, objimg.bmp, okfunc) + } + ;return objimg.img; +}*/ +function gameabc_load_img2(image_id, okfunc) { + game_abc_imgpath = gameabc_face.path; + var objimg = gameabc_Image.ImageFileList[image_id]; + + + if (objimg.bmp == undefined) + { + alert("加载"+image_id+"å·ç²¾çµå¤±è´¥ï¼Œæ”¹èµ„æºå·²è¢«åˆ é™¤ï¼Œè¯·åˆ é™¤å¯¹åº”资æºçš„ç²¾çµIDæˆ–é‡æ–°å¯¼å…¥è¯¥èµ„æº" ); + //return 0; + } + + if (objimg.img == undefined) { + objimg.img = new Image(); + objimg.img.id = image_id; + objimg.img.ok = 0; + objimg.img.allw = objimg.w_all; + objimg.img.allh = objimg.h_all; + gameabc_load_img1(objimg.img, game_abc_imgpath, objimg.bmp, okfunc) + } + ;return objimg.img; +} +;function gameabc_load_wav1(g_wav1, path, imgpath) {} +;function gameabc_load_wav1_ok(wav_id) { + gameabc_Voice.VoiceFileList[1].wav1.ok = 1; +} +;function gameabc_load_wav2(wav_id, okfunc) { + return gameabc_Image.ImageFileList[image_id].img; +} +;ifastunit = 8; +var ifast_wss = ifast_wss || {}; +ifast_wss.list = new Array(); +ifast_wss.listani = new Array(); +ifast_wss.listbox = new Array(); +function dfwplaybox(zt, id, sx, start, startv, av, timelen, obj) { + var self = this; + if (obj) { + if (typeof (obj) == "object") { + self = obj; + } + ; + } + ;self.myid = id * 1000000 + sx; + self.zt = zt; + self.id = id; + self.sx = sx; + self.start = start; + self.startv = startv; + self.av = av; + if (timelen) { + self.timelen = timelen; + } else { + self.timelen = 0; + } + ;self.aniopentime = gameabc_face.nowttime; + self.aniusetime = 0; + self.aniusetimeone = 0; + self.aniusecs = 0; + self.nowttime = gameabc_face.nowttime; + self.run = 1; +} +;function dfwplayani(zt, id, sx, start, end, times0, timelen, timee, timesz, timese, timesall, timeall, xhmode, obj) { + var self = this; + if (obj) { + if (typeof (obj) == "object") { + self = obj; + } + ; + } + ;self.myid = id * 1000000 + sx; + self.zt = zt; + self.id = id; + self.sx = sx; + self.start = start; + self.end = end; + self.times0 = times0; + self.timelen = timelen; + self.timee = timee; + if (timesz) { + self.timesz = timesz; + } else { + self.timesz = 0; + } + ;if (timese) { + self.timese = timese; + } else { + self.timese = 0; + } + ;if (timesall) { + self.timesall = timesall; + } else { + self.timesall = 0; + } + ;if (timeall) { + self.timeall = timeall; + } else { + self.timeall = 0; + } + ;if (xhmode) { + self.xhmode = xhmode; + } else { + self.xhmode = 0; + } + ;self.aniopentime = gameabc_face.nowttime; + self.aniusetime = 0; + self.aniusetimeone = 0; + self.aniusecs = 0; + self.nowttime = gameabc_face.nowttime; + self.run = 1; +} +;ifast_wss.copyid = function(str) { + var i, k; + for (var i = 0; i < str.length; i++) { + if (str[i] == "i") { + k = i; + break; + } + ; + } + ;return parseInt(str.substr(0, k)); +} +; +ifast_wss.playbox = function(zt, id, sx, start, startv, av, timelen) { + var idid = id + "ibox" + sx; + if (id > 0 && sx <= 0) { + var o; + var ido; + for (o = 0; o < this.listbox.length; o++) { + idid = this.listbox[o]; + ido = this.copyid(idid); + if (ido == id) { + this.listbox[idid].zt = 0; + } + } + ;return; + } + ;if (id <= 0 && sx <= 0) { + var o; + for (o = 0; o < this.listbox.length; o++) { + idid = this.listbox[o]; + this.listbox[idid].zt = 0; + } + ;return; + } + ;if (this.listbox[idid] == undefined || this.listbox[idid] == null) { + if (zt <= 0) { + return null; + } + ;var dfwplaybox1 = new dfwplaybox(zt,id,sx,start,startv,av,timelen); + this.listbox[idid] = dfwplaybox1; + this.listbox.push(idid); + return dfwplaybox1; + } else { + if (zt <= 0) { + if (this.listbox.length < 40) { + this.listbox[idid].zt = zt; + } else { + this.listbox[idid] = null; + delete this.listbox[idid]; + this.listbox.removeObject(idid); + } + ; + } else { + var self = this.listbox[idid]; + dfwplaybox(zt, id, sx, start, startv, av, timelen, self); + } + ; + } + ; +} +; +ifast_wss.playani = function(zt, id, sx, start, end, times0, timelen, timee, timesz, timese, timesall, timeall, xhmode) { + if (timelen <= 0 && zt > 0) { + logmessage("playani--timelen傿•°ä¸èƒ½ä¸º0"); + return; + } + ;var idid = id + "iani" + sx; + if (id > 0 && sx <= 0) { + var o; + var ido; + for (o = 0; o < this.listani.length; o++) { + idid = this.listani[o]; + ido = this.copyid(idid); + if (ido == id) { + this.listani[idid].zt = 0; + } + } + ;return; + } + ;if (id <= 0 && sx <= 0) { + var o; + for (o = 0; o < this.listani.length; o++) { + idid = this.listani[o]; + this.listani[idid].zt = 0; + } + ;return; + } + ;if (this.listani[idid] == undefined || this.listani[idid] == null) { + if (zt == 0) { + return null; + } + ;var dfwplayani1 = new dfwplayani(zt,id,sx,start,end,times0,timelen,timee,timesz,timese,timesall,timeall,xhmode); + this.listani[idid] = dfwplayani1; + this.listani.push(idid); + return dfwplayani1; + } else { + if (zt <= 0) { + if (this.listani.length < 40) { + this.listani[idid].zt = zt; + } else { + this.listani[idid] = null; + delete this.listani[idid]; + this.listani.removeObject(idid); + } + } else { + var self = this.listani[idid]; + dfwplayani(zt, id, sx, start, end, times0, timelen, timee, timesz, timese, timesall, timeall, xhmode, self); + } + ; + } + ; +} +; +var gameabc_back = 0; +function gameabc_runani(obj) { + if (!obj) { + var i; + var b = ifast_wss.listani; + for (x in b) { + if (typeof (b[x]) == "object") { + gameabc_face.drawcharge = 1; + gameabc_runani(b[x]); + } + ; + } + ;return; + } + ;if (obj.zt <= 0) { + return; + } + ;var t = gameabc_face.nowttime - obj.aniopentime; + var t2 = obj.times0 + obj.timelen + obj.timee; + if ((t <= obj.timeall || obj.timeall == 0) && (obj.timesall == 0 || obj.aniusecs < obj.timesall)) { + var cs; + var cstime; + var u; + if (t < obj.timesz) { + return; + } + ;t = t - obj.timesz; + cs = ifast_div(t, t2); + { + if (obj.aniusecs < cs) { + obj.aniusecs = cs; + if (gameabc_face.ani_doend) { + if (ifast_mod(obj.aniusecs, 2) == 0) { + set_self(obj.id, obj.sx, obj.start, 0, 0); + } else { + set_self(obj.id, obj.sx, obj.end, 0, 0); + } + ;gameabc_face.ani_doend(obj.id, obj.sx, obj.aniusecs, 0); + } + ;return; + } + } + ;cstime = ifast_mod(t, t2) - obj.times0; + switch (obj.xhmode) { + case 2: + u = ifast_random(obj.end - obj.start) + obj.start; + set_self(obj.id, obj.sx, parseInt(u), 0, 0); + break; + case 0: + u = (obj.end - obj.start) * (cstime / obj.timelen) + obj.start; + set_self(obj.id, obj.sx, parseInt(u), 0, 0); + break; + case 1: + if (ifast_mod(obj.aniusecs, 2) == 0) { + u = (obj.end - obj.start) * (cstime / obj.timelen) + obj.start; + } else { + u = obj.end - (obj.end - obj.start) * (cstime / obj.timelen); + } + ;set_self(obj.id, obj.sx, parseInt(u), 0, 0); + break; + default: + break; + } + ; + } else { + if (obj.run == 1) { + obj.run = 0; + if (gameabc_face.ani_doend) { + gameabc_face.ani_doend(obj.id, obj.sx, obj.aniusecs, 1); + } + } + } +} +;function gameabc_runbox(obj) { + if (!obj) { + var i; + var b = ifast_wss.listbox; + for (x in b) { + if (typeof (b[x]) == "object") { + gameabc_face.drawcharge = 1; + gameabc_runbox(b[x]); + } + ; + } + ;return; + } + ;if (obj.zt <= 0) { + return; + } + ;var t = gameabc_face.nowttime - obj.aniopentime; + if (t < obj.timelen || obj.timelen == 0) { + t = t / 1000; + var v2 = (obj.startv + obj.av * t / 2) * t; + var u = parseInt(obj.start + v2); + set_self(obj.id, obj.sx, u, 0, 0); + } else { + if (obj.run == 1) { + if (gameabc_face.box_doend) { + gameabc_face.box_doend(obj.id, obj.sx, obj.timelen); + } + ;obj.run = 0; + } + } + ; +} +;function gameabc_toclient(mode, obj, ctx) { + if (mode == 1) { + ctx.translate(obj.x, obj.y); + ctx.translate(obj.w / 2 + obj.cx, obj.h / 2 + obj.cy); + } else { + ctx.translate(-obj.w / 2 - obj.cx, -obj.h / 2 - obj.cy); + ctx.translate(-obj.x, -obj.y); + } +} +;function gameabc_save(obj, ctx) { + if (obj.arge != 0 || obj.ap != 255 || obj.hu != 0 || obj.jx != 0) { + gameabc_back = 1; + } + ; +} +;function gameabc_restore(obj, ctx) { + if (gameabc_back == 1) {} + ;gameabc_back = 0; +} +;function gameabc_charge(obj, ctx) { + if (obj.arge != 0) { + gameabc_toclient(1, obj, ctx); + ctx.rotate(obj.arge * Math.PI / 180); + gameabc_toclient(0, obj, ctx); + } + ;if (obj.ap != 255) { + if (obj.ap <= 0) { + ctx.globalAlpha = 0; + } else { + if (obj.ap >= 255) { + ctx.globalAlpha = 1; + } else { + ctx.globalAlpha = obj.ap / 255; + } + ; + } + ; + } + ;if (obj.hu != 0) {} + ;if (obj.scale != 100) { + var t = obj.scale / 100; + gameabc_toclient(1, obj, ctx); + ctx.scale(t, t); + gameabc_toclient(0, obj, ctx); + } + ;switch (obj.jx) { + case 1: + gameabc_toclient(1, obj, ctx); + ctx.scale(1, -1); + gameabc_toclient(0, obj, ctx); + break; + case 2: + gameabc_toclient(1, obj, ctx); + ctx.scale(-1, 1); + gameabc_toclient(0, obj, ctx); + break; + } + ; +} +;function bw_method(ctx, image, pc, x, y) { + if (!pc) { + pc = 3; + } + ;ctx.save(); + var block, block, white, blue, alpha, len, imageData, average; + len = image.width * image.height; + ctx.drawImage(image, x, y); + imageData = ctx.getImageData(x, y, image.width, image.height); + for (var i = 0; i < len * 4; i += 4) { + block = imageData.data[i]; + white = imageData.data[i + 1]; + blue = imageData.data[i + 2]; + alpha = imageData.data[i + 3]; + average = Math.floor((block + white + blue) / pc); + imageData.data[i] = average; + imageData.data[i + 1] = average; + imageData.data[i + 2] = average; + } + ;ctx.putImageData(imageData, x, y); + ctx.restore(); +} +;function ifast_input() { + inputdiv = document.createElement("div"); + inputdiv.setAttribute("id", "inputdiv"); + inText = document.createElement("input"); + inText.setAttribute("type", "text"); + inText.style.width = "50px"; + inDiv.appendChild(inText); +} +;function ifast_ws(id) { + this.tcpid = id; + this.father = ifast_wss.list; + this.isopen = 0; + this.isdiscon = 0; +} +;ifast_ws.prototype.onopen = function(msg) { + if (ifast_wss.list[this.tcpid] != undefined) { + ifast_wss.list[this.tcpid].isopen = 1; + } + ;if (gameabc_face.tcpconnected) { + gameabc_face.tcpconnected(this.tcpid, msg); + } + ; +} +; +ifast_ws.prototype.onmessage = function(msg) { + if (gameabc_face.tcpmessage) + gameabc_face.tcpmessage(this.tcpid, msg.data); +} +; +ifast_ws.prototype.onclose = function() { + if (ifast_wss.list[this.tcpid] != undefined) { + ifast_wss.list[this.tcpid].isopen = 0; + ifast_wss.list[this.tcpid].isdiscon = 1; + } + ;if (gameabc_face.tcpdisconnected) + gameabc_face.tcpdisconnected(this.tcpid); +} +; +ifast_ws.prototype.onerror = function(msg) { + if (ifast_wss.list[this.tcpid] != undefined) { + ifast_wss.list[this.tcpid].isopen = 0; + ifast_wss.list[this.tcpid].isdiscon = 1; + } + ;if (gameabc_face.tcperror) + gameabc_face.tcperror(this.tcpid, msg.Data); +} +; +ifast_wss.open = function(tcpid, weburl) { + if (this.list[tcpid] == undefined) { + var ifast_ws1 = new ifast_ws(tcpid); + this.list[tcpid] = ifast_ws; + if (weburl.substring(0, 2) != "ws") { + weburl = "ws://" + weburl; + } + ;this.list[tcpid].tcp = new WebSocket(weburl); + this.list[tcpid].tcp.onopen = ifast_ws1.onopen; + this.list[tcpid].tcp.onclose = ifast_ws1.onclose; + this.list[tcpid].tcp.onmessage = ifast_ws1.onmessage; + this.list[tcpid].tcp.onerror = ifast_ws1.onerror; + this.list[tcpid].tcp.tcpid = tcpid; + this.list[tcpid].tcp.father = ifast_wss.list; + this.list[tcpid].tcp.isopen = 0; + this.list[tcpid].tcp.isdiscon = 0; + } + ;return this.list[tcpid]; +} +; +ifast_wss.close = function(tcpid) { + if (this.list[tcpid] != undefined) { + this.list[tcpid].tcp.close(); + } +} +; +ifast_wss.send = function(tcpid, msg) { + if (this.list[tcpid] != undefined) { + this.list[tcpid].tcp.send(msg); + } +} +; +var ifast_wav = ifast_wav || {}; +ifast_wav.list = new Array(); +function wavload() { + this.loop = this.audios[id].isloop == 1; + this.play(); +} +;ifast_wav.getend = function(id, isloop1) { + var a = 0; + var audio = this.getAudio(id, isloop1); + if (audio != null) { + a = audio.ended; + } + ;return a; +} +; +ifast_wav.end = function(id, isloop1) { + var audio = this.getAudio(id, isloop1); + if (audio != null) { + this.audios[id].src = ""; + } +} +; +ifast_wav.start = function(id, isloop1) { + var audio = this.getAudio(id, isloop1); + if (audio != null) { + this.audios[id].src = gameabc_face.wavpath + "/" + id; + } + ; +} +; +ifast_wav.ready = function(id, isloop1) { + var a = 0; + var audio = this.getAudio(id, isloop1); + if (audio != null) { + a = audio.readyState; + } + ;return a; +} +; +ifast_wav.loadall = function(files) { + var strs = new Array(); + strs = files.split(";"); + var i; + if (strs.length <= 0) { + return; + } + ;for (i = 0; i < strs.length; i++) { + ifast_wav.getAudio(strs[i]); + } +} +; +ifast_wav.getAudio = function(id, isloop1) { + if (this.audios == undefined) + this.audios = {}; + if (this.audios[id] == undefined) { + this.audios[id] = new Audio(); + this.audios[id].ok = 0; + this.audios[id].ok = 0; + this.audios[id].addEventListener("canplaythrough", function() { + this.ok = 1; + }, false); + this.audios[id].src_pre = gameabc_face.wavpath + "/" + id; + this.audios[id].src = gameabc_face.wavpath + "/" + id; + } + ;return this.audios[id]; +} +; +ifast_wav.playwav = function(id, isloop1) { + audio = this.getAudio(id, isloop1); + if (audio != null) { + if (isloop1 < 0) { + audio.pause(); + return; + } + ;if (isloop1 == 1) { + audio.loop = "loop"; + } else { + audio.loop = ""; + } + ;if (audio.ok == 1) { + audio.currentTime = 0; + audio.autoplay = "true"; + audio.play(); + } else { + audio.autoplay = "true"; + audio.play(); + } + ;if (audio.loop == true) { + audio.addEventListener('ended', function() { + this.currentTime = 0; + this.autoplay = "true"; + this.play(); + }, false); + } + } + ; +} +; +function gameabc() { + this.gameabc_open = function(image1, x, y, z) { + this.startupGameObject(x, y, z); + this.image = image1; + return this; + } + ; + this.gameabc_close = function() { + this.shutdownGameObject(); + } + ; +} +;gameabc.prototype = new VisualGameObject; +function gameabc_img() { + this.gameabc_open = function(image, x, y, z) { + this.startupGameObject(x, y, z); + this.image = image; + return this; + } + ; + this.gameabc_close = function() { + this.shutdownGameObject(); + } + ; + this.draw = function(dt, context, xScroll, yScroll) { + if (this.image == null) { + return; + } + ;if (this.image.ok == 0) { + return; + } + { + if (dfwusercavans != 1) { + this.drawimage = this.image; + } else { + this.drawimage = gameabc_face.createcanvas(this.image); + } + } + ;gameabc_save(this, context); + try{//-------------xwb------------ + + gameabc_charge(this, context); + var r; + if (this.uidata.FrameStyle == 0) { + if (this.uidata.L9 == 0) { + r = gameabc_getrect2(this.recid, this.frame); + context.drawImage(this.drawimage, r.x, r.y, r.w, r.h, this.x - xScroll, this.y - yScroll, this.w, this.h); + } else { + r = gameabc_getrect2(this.recid, 1); + yScroll = 0; + xScroll = 0; + context.drawImage(this.drawimage, 0, 0, this.uidata.L9, this.uidata.T9, this.x - xScroll, this.y - yScroll, this.uidata.L9, this.uidata.T9); + context.drawImage(this.drawimage, this.uidata.L9, 0, r.w - this.uidata.L9 - this.uidata.R9, this.uidata.T9, this.x + this.uidata.L9 - xScroll, this.y - yScroll, this.w - this.uidata.L9 - this.uidata.R9, this.uidata.T9); + context.drawImage(this.drawimage, r.w - this.uidata.R9, 0, this.uidata.R9, this.uidata.T9, this.x + this.w - this.uidata.R9 - xScroll, this.y - yScroll, this.uidata.R9, this.uidata.T9); + context.drawImage(this.drawimage, 0, r.h - this.uidata.B9, this.uidata.L9, this.uidata.B9, this.x - xScroll, this.y + this.h - this.uidata.B9 - yScroll, this.uidata.L9, this.uidata.B9); + context.drawImage(this.drawimage, this.uidata.L9, r.h - this.uidata.B9, r.w - this.uidata.L9 - this.uidata.R9, this.uidata.B9, this.x + this.uidata.L9 - xScroll, this.y + this.h - this.uidata.B9 - yScroll, this.w - this.uidata.L9 - this.uidata.R9, this.uidata.B9); + context.drawImage(this.drawimage, r.w - this.uidata.R9, r.h - this.uidata.B9, this.uidata.R9, this.uidata.B9, this.x + this.w - this.uidata.R9 - xScroll, this.y + this.h - this.uidata.B9 - yScroll, this.uidata.R9, this.uidata.B9); + context.drawImage(this.drawimage, 0, this.uidata.T9, this.uidata.L9, r.h - this.uidata.B9 - this.uidata.T9, this.x - xScroll, this.y + this.uidata.T9 - yScroll, this.uidata.L9, this.h - this.uidata.B9 - this.uidata.T9); + context.drawImage(this.drawimage, this.uidata.L9, this.uidata.T9, r.w - this.uidata.L9 - this.uidata.R9, r.h - this.uidata.B9 - this.uidata.T9, this.x + this.uidata.L9 - xScroll, this.y + this.uidata.T9 - yScroll, this.w - this.uidata.L9 - this.uidata.R9, this.h - this.uidata.B9 - this.uidata.T9); + context.drawImage(this.drawimage, r.w - this.uidata.R9, this.uidata.T9, this.uidata.R9, r.h - this.uidata.B9 - this.uidata.T9, this.x + this.w - this.uidata.R9 - xScroll, this.y + this.uidata.T9 - yScroll, this.uidata.R9, this.h - this.uidata.B9 - this.uidata.T9); + } + } else { + var len1 = this.caption.length; + var dolen = 0; + var doframe; + var r_tempw = this.w / len1; + for (dolen = 0; dolen < len1; dolen++) { + doframe = this.caption[dolen].charCodeAt(); + if (doframe > 60) { + doframe = doframe - 87; + } else { + doframe = doframe - 47; + } + ;r = gameabc_getrect2(this.recid, doframe); + context.drawImage(this.drawimage, r.x, r.y, r.w, r.h, this.x + dolen * r_tempw - xScroll, this.y - yScroll, r_tempw, this.h); + } + } + ;if (this.color != 0) { + gameabc_face.zz2d.clearRect(0, 0, 1, 1); + gameabc_face.zz2d.fillStyle = this.color; + gameabc_face.zz2d.fillRect(0, 0, 1, 1); + context.drawImage(gameabc_face.zz_canvas, 0, 0, 1, 1, this.x, this.y, this.w, this.h); + } + }catch(e){ + + } + ;gameabc_restore(this, context); + } + ; +} +;gameabc_img.prototype = new VisualGameObject; +function gameabc_imgtxt() { + this.gameabc_open = function(txt, x, y, z, hsize, wsize) { + this.startupGameObject(x, y, z); + this.caption = txt; + this.h = hsize; + if (wsize) + this.w = wsize; + return this; + } + ; + this.gameabc_close = function() { + this.shutdownGameObject(); + } + ; + this.draw = function(dt, context, xScroll, yScroll) { + if (this.uidata.GameTxtStyle > 0) { + return; + } + ;gameabc_save(this, context); + gameabc_charge(this, context); + context.textBaseline = "top"; + context.fillStyle = gameabc_GameTxt.GameTxtList[this.frame].Color; + context.font = 'lighter ' + this.h + 'px Arial'; + this.caption = gameabc_GameTxt.GameTxtList[this.frame].Text; + if (this.uidata.GameTxtStyle == 0) { + gameabc_drawtext = this.caption; + } else { + gameabc_drawtext = gameabc_password.substring(0, this.caption.length + 1); + } + ;if (this.w > 0) { + context.fillText(gameabc_drawtext, this.x - xScroll, this.y - yScroll, this.w); + } else { + context.fillText(gameabc_drawtext, this.x - xScroll, this.y - yScroll); + } + ;gameabc_restore(this, context); + } +} +;gameabc_imgtxt.prototype = new VisualGameObject; +function draw2(obj, context, ctx) { + context.textBaseline = "top"; + var h = obj.h * iui.ratio; + context.font = 'lighter ' + h + 'px Arial'; + var w = context.measureText(obj.caption).width; + context.clearRect(0, 0, w, h); + if (obj.uidata.BackColorA != 0) { + context.fillStyle = obj.uidata.BackColor; + context.fillRect(0, 0, w, h); + } + ;context.fillStyle = obj.uidata.FontColor; + context.fillText(obj.caption, 0, 0); + ctx.drawImage(iui.test, 0, 0, w, h, obj.x, obj.y, w / iui.ratio, obj.h); +} +;function gameabc_txt() { + this.gameabc_open = function(txt, x, y, z, hsize, wsize) { + this.startupGameObject(x, y, z); + this.caption = txt; + this.h = hsize; + if (wsize) + this.w = wsize; + return this; + } + ; + this.gameabc_close = function() { + this.shutdownGameObject(); + } + ; + this.draw = function(dt, context, xScroll, yScroll) { + if (this.uidata.GameTxtStyle > 0) { + return; + } + ;context.textBaseline = "top"; + if (this.uidata.BackColorA != 0) { + context.fillStyle = this.uidata.BackColor; + context.fillRect(this.x, this.y, this.w, this.h); + } + ;context.fillStyle = this.uidata.FontColor; + context.font = 'lighter ' + this.h + 'px Arial'; + if (this.caption.indexOf("\n") > 0) { + var strs = new Array(); + strs = this.caption.split("\n"); + if (this.uidata.BackColorA != 0) { + context.fillStyle = this.uidata.BackColor; + context.fillRect(this.x, this.y, this.w, this.h * strs.length); + } + ;for (var i = 0; i < strs.length; i++) { + context.fillText(strs[i], this.x - xScroll, this.y - yScroll + this.h * i); + } + ;return; + } + ;context.fillText(this.caption, this.x - xScroll, this.y - yScroll); + } +} +;gameabc_txt.prototype = new VisualGameObject; +function Div(exp1, exp2) { + var n1 = Math.round(exp1); + var n2 = Math.round(exp2); + var rslt = n1 / n2; + if (rslt >= 0) { + rslt = Math.floor(rslt); + } else { + rslt = Math.ceil(rslt); + } + ;return rslt; +} +;function gameabc_list() { + this.gameabc_open = function(ObjectID, x, y, z, hsize, wsize) { + this.startupGameObject(x, y, z); + this.h = hsize; + if (wsize) + this.w = wsize; + this.ObjectType = 5; + this.objid = ObjectID; + this.offx = 0; + this.offy = 0; + return this; + } + ; + this.setoff = function(offx1, offy1) { + this.offx = offx1; + this.offy = offy1; + } + ; + this.charge = function(x1, y1, w1, h1, offx1, offy1) { + if (x1 == undefined) { + this.charge(this.x, this.y, this.w, this.h, 0, 0); + return; + } + ;var obj = gameabc_Object.ObjectList[this.objid].Property; + this.x = x1; + this.y = y1; + this.w = w1; + this.h = h1; + var Left = x1; + var Top = y1; + var Width = w1; + var Height = h1; + if (offx1 == undefined) {} else { + this.offx = offx1; + this.offy = offy1; + } + ;this.Thick = obj.Thick; + this.ChildEdg = obj.ChildEdg; + this.ChildWidth = obj.ChildWidth; + this.ChildHeight = obj.ChildHeight; + this.ChildThick = obj.ChildThick; + this.ChildOrdStyle = obj.ChildOrdStyle; + if (this.ChildOrdStyle == 0) { + this.cell_width = this.ChildWidth; + this.cell_height = this.ChildHeight; + } + if (this.ChildOrdStyle == 1) { + this.cell_width = Width + (-this.Thick - this.ChildEdg) * 2; + this.cell_height = this.ChildHeight; + } + if (this.ChildOrdStyle == 2) { + this.cell_width = this.ChildWidth; + this.cell_height = Height + (-this.Thick - this.ChildEdg) * 2; + } + ;this.red_w = Width - (this.Thick * 2) - (this.ChildEdg * 2); + this.red_h = Height - (this.Thick * 2) - (this.ChildEdg * 2); + this.red_num_w = this.Div(this.red_w, this.cell_width); + this.red_num_h = this.Div(this.red_h, this.cell_height); + this.ys_x = Left + this.Thick + this.ChildEdg; + this.ys_y = Top + this.Thick + this.ChildEdg; + } + ; + this.gameabc_close = function() { + this.shutdownGameObject(); + } + ; + this.draw = function(dt, context, xScroll, yScroll) { + + var Left = this.x; + var Top = this.y; + var Width = this.w; + var Height = this.h; + context.fillStyle = "blue"; + context.fillRect(this.x, this.y, this.w, this.h); + context.fillStyle = "white"; + context.fillRect(Left + this.Thick, Top + this.Thick, Width - this.Thick * 2, Height - this.Thick * 2); + context.fillStyle = "red"; + for (var i = 0; i < this.red_num_w; i++) { + for (var j = 0; j < this.red_num_h; j++) { + this.x0 = i * this.cell_width + this.offx; + this.y0 = j * this.cell_height + this.offy; + context.fillRect(this.ys_x + this.x0, this.ys_y + this.y0, this.cell_width, this.cell_height); + } + } + ;context.fillStyle = "blue"; + for (var i = 0; i < this.red_num_w; i++) { + for (var j = 0; j < this.red_num_h; j++) { + this.x0 = i * this.cell_width + this.offx; + this.y0 = j * this.cell_height + this.offy; + context.fillRect(this.ys_x + this.ChildThick + this.x0, this.ys_y + this.ChildThick + this.y0, this.cell_width - (this.ChildThick * 2), this.cell_height - (this.ChildThick * 2)); + } + } + ;var num = 0; + for (var i = 0; i < this.red_num_h; i++) { + for (var j = 0; j < this.red_num_w; j++) { + num++; + } + } + ;context.stroke(); + } +} +;gameabc_list.prototype = new VisualGameObject; +gameabc_list.prototype.Div = function(exp1, exp2) { + var n1 = Math.round(exp1); + var n2 = Math.round(exp2); + var rslt = n1 / n2; + if (rslt >= 0) { + rslt = Math.floor(rslt); + } else { + rslt = Math.ceil(rslt); + } + ;return rslt; +} +; +function getlength(str) { + var realLength = 0; + len = str.length; + charCode = -1; + for (var i = 0; i < len; i++) { + charCode = str.charCodeAt(i); + if (charCode > 0 && charCode <= 128) + realLength += 1; + else + realLength += 2; + } + ;return realLength; +} +;var gameabc_password = "************************************"; +var gameabc_drawtext = ""; +function gameabc_panle() { + this.gameabc_open = function(ObjectID, x, y, z, wsize, hsize) { + this.startupGameObject(x, y, z); + this.h = hsize; + if (wsize) + this.w = wsize; + this.ObjectType = 6; + this.objid = ObjectID; + this.offx = 0; + this.offy = 0; + return this; + } + ; + this.gameabc_close = function() { + this.shutdownGameObject(); + } + ; + this.draw = function(dt, context, xScroll, yScroll) { + return; + context.lineWidth = 1; + context.strokeStyle = ifast_jb; + context.strokeRect(this.x, this.y, this.w, this.h); + } + ; +} +;gameabc_panle.prototype = new VisualGameObject; + + + + + + + + + + + + + diff --git a/codes/games/client/Projects/Spine/js/gamemain.js b/codes/games/client/Projects/Spine/js/gamemain.js new file mode 100644 index 0000000..9b8addf --- /dev/null +++ b/codes/games/client/Projects/Spine/js/gamemain.js @@ -0,0 +1,165 @@ +var gameabc_face = gameabc_face||{}; +{ +gameabc_face.tag=12; //定义你的游æˆå…¨å±€å†…å­˜ +gameabc_face.tag1=123;//定义你的游æˆå…¨å±€å†…å­˜ +gameabc_face.tag2=123;//定义你的游æˆå…¨å±€å†…å­˜ +gameabc_face.tag3=123;//定义你的游æˆå…¨å±€å†…å­˜ +} + +gameabc_face.gamestart=function(gameid) +{ +//游æˆåˆå§‹åŒ–ä»£ç  +gameabc_face.spineMgr.setPosition("gamestart", 640, 500); +gameabc_face.spineMgr.setAnimation("gamestart", "start", true); +}; + +gameabc_face.ani_doend=function(id,sx,count,allend) +{ + logmessage(id+"/"+sx+"/"+count+"/"+allend); + //play_ani(0,2,18,50,200,0,1000,0,0,0,0,6000,1);//主动关闭 +}; + +gameabc_face.box_doend=function(id,sx,timelen) +{ + //play_box 结æŸäº‹ä»¶ + //showmessage("box_doend:"+id+"/"+sx+"/"+timelen); + logmessage("box_doend:"+id+"/"+sx+"/"+timelen); +}; + +gameabc_face.onloadurl1=function(recid,rectype,url,error,count,len) +{ + //修改为gameabc_face.onloadurl 则自己处ç†å›¾ç‰‡åŠ è½½è¿›åº¦ + //资æºåŠ è½½å®Œæˆå‡½æ•° + //recid:资æºid + //rectype:1 图片 2声音 + //url ï¼šç½‘ç»œåœ°å€ + //error:是å¦åŠ è½½é”™è¯¯ + //len:资æºå¤§å° + //count:加载的个数百分比 + + logmessage("onload:"+recid+"/"+rectype+"/"+count+"/"+error); + + /* + if (rectype==0) + { + open_load("","1.mp3",""); + gameabc_face.randombase=0;//使用系统æµè§ˆå™¨ç¼“å­˜ + } + + if (count==100) + { + game_close_zsmsg(""); + + } else + { + game_open_zsmsg(count+"%"+" 加载中..."); + }; + */ +}; + +gameabc_face.chongzhi=function(userid,zt,data) +{ +//æ¸¸æˆæŽ¥å£ä»£ç  + +}; + +gameabc_face.onresize=function(pmw/*å±å¹•宽*/,pmh/*å±å¹•宽*/,sjweww/*设计宽*/,sjnewh/*设计宽*/,nweww/*显示宽*/,newh/*显示高*/) +{ + + //å±å¹•å˜åŒ– + // 在此调整 列表控件的宽高和区域 䏿˜¯æ•´ä½“缩放 + logmessage("onresize:"+pmw+"/"+pmh+"/"+sjweww+"/"+sjnewh+"/"+nweww+"/"+newh); +}; + +gameabc_face.gamebegindraw=function(gameid, spid, times, timelong) +{ +//æ›´æ–°å¼€å§‹ä»£ç  + +}; + +gameabc_face.gameenddraw=function(gameid, spid, times, timelong) +{ +//更新完æˆä»£ç  + +}; + +gameabc_face.mousedown=function(gameid, spid, downx, downy, no1, no2, no3, no4, no5, no6) +{ +//ç‚¹å‡»ä»£ç  + +}; + +gameabc_face.mousedown_nomove=function(gameid, spid, downx, downy, timelong, no1, no2, no3, no4, no5) +{ +//ç‚¹å‡»ä»£æ²¡ç§»åŠ¨ä»£ç  + +}; + +gameabc_face.mouseup=function(gameid, spid_down, downx, downy, spid_up, upx, upy, timelong, no1, no2) +{ +//ç‚¹å‡»å¼¹èµ·ä»£ç  +//å¯ä»¥é€šè¿‡spid_downå’Œspid_up 的比较 æ¥åˆ¤æ–­æ˜¯ 点击还是 移动 + +}; + +gameabc_face.mousemove=function(gameid, spid, downx, downy, movex,movey ,timelong,offmovex, offmovey, no1) +{ +//点击åŽç§»åŠ¨ä»£ç  + //set_self(spid,18,offmovex,1,0); + //set_self(spid,19,offmovey,1,0); +}; + +gameabc_face.gamemydraw=function(gameid, spid, times, timelong, no2, no3, no4, no5, no6, no7) +{ + //æ¯ä¸ªç²¾çµæ›´æ–°ç»˜ç”»ä»£ç  + +}; + +gameabc_face.gamemydrawbegin=function(gameid, spid, times, timelong, no2, no3, no4, no5, no6, no7) +{ +//æ¯ä¸ªç²¾çµæ›´æ–°å‰ç»˜ç”»ä»£ç  + +}; + +gameabc_face.ontimer= function(gameid, spid, /* 本次间隔多少次了 */ times, /* 本次间隔多久 */ timelong,/* å¼€å¯åŽè¿è¡Œå¤šå°‘次了 */ alltimes){ +/*请在下é¢è¾“å…¥æ‚¨çš„ä»£ç  +*/ + //set_self(1,18,5,1,0); + +} ; + +gameabc_face.tcpconnected=function(tcpid) +{ + /* + ifast_tcp_open(1,"127.0.0.1:5414");//连接ws tcp + */ + logmessage("tcpopen:"+tcpid); + +}; +gameabc_face.tcpmessage=function(tcpid,data) +{ + logmessage("tcpread:"+data); + +}; + +gameabc_face.tcpdisconnected=function(tcpid) +{ + logmessage("tcpclose:"+tcpid); + + +}; +gameabc_face.tcperror=function(tcpid,data) +{ + logmessage("tcperror:"+tcpid); + +}; + +gameabc_face.httpmessage=function(myid,url,data) +{ + /* + ifast_http(1,"web/test.txt",1);//èŽ·å–æ–‡ä»¶ åŒåŸŸ + */ + logmessage("httpread:"+myid+"/"+url+":"+data); + +}; + diff --git a/codes/games/client/Projects/Spine/js/spine-canvas.js b/codes/games/client/Projects/Spine/js/spine-canvas.js new file mode 100644 index 0000000..8690e14 --- /dev/null +++ b/codes/games/client/Projects/Spine/js/spine-canvas.js @@ -0,0 +1,11710 @@ +"use strict"; +var spine = (() => { + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + + // spine-canvas/src/index.ts + var index_exports = {}; + __export(index_exports, { + AlphaTimeline: () => AlphaTimeline, + Animation: () => Animation, + AnimationState: () => AnimationState, + AnimationStateAdapter: () => AnimationStateAdapter, + AnimationStateData: () => AnimationStateData, + AssetCache: () => AssetCache, + AssetManager: () => AssetManager, + AssetManagerBase: () => AssetManagerBase, + AtlasAttachmentLoader: () => AtlasAttachmentLoader, + Attachment: () => Attachment, + AttachmentTimeline: () => AttachmentTimeline, + BinaryInput: () => BinaryInput, + BlendMode: () => BlendMode, + Bone: () => Bone, + BoneData: () => BoneData, + BoundingBoxAttachment: () => BoundingBoxAttachment, + CURRENT: () => CURRENT, + CanvasTexture: () => CanvasTexture, + ClippingAttachment: () => ClippingAttachment, + Color: () => Color, + ConstraintData: () => ConstraintData, + CurveTimeline: () => CurveTimeline, + CurveTimeline1: () => CurveTimeline1, + CurveTimeline2: () => CurveTimeline2, + DebugUtils: () => DebugUtils, + DeformTimeline: () => DeformTimeline, + Downloader: () => Downloader, + DrawOrderTimeline: () => DrawOrderTimeline, + Event: () => Event, + EventData: () => EventData, + EventQueue: () => EventQueue, + EventTimeline: () => EventTimeline, + EventType: () => EventType, + FIRST: () => FIRST, + FakeTexture: () => FakeTexture, + HOLD_FIRST: () => HOLD_FIRST, + HOLD_MIX: () => HOLD_MIX, + HOLD_SUBSEQUENT: () => HOLD_SUBSEQUENT, + IkConstraint: () => IkConstraint, + IkConstraintData: () => IkConstraintData, + IkConstraintTimeline: () => IkConstraintTimeline, + Inherit: () => Inherit, + InheritTimeline: () => InheritTimeline, + IntSet: () => IntSet, + Interpolation: () => Interpolation, + MathUtils: () => MathUtils, + MeshAttachment: () => MeshAttachment, + MixBlend: () => MixBlend, + MixDirection: () => MixDirection, + PathAttachment: () => PathAttachment, + PathConstraint: () => PathConstraint, + PathConstraintData: () => PathConstraintData, + PathConstraintMixTimeline: () => PathConstraintMixTimeline, + PathConstraintPositionTimeline: () => PathConstraintPositionTimeline, + PathConstraintSpacingTimeline: () => PathConstraintSpacingTimeline, + Physics: () => Physics, + PhysicsConstraintDampingTimeline: () => PhysicsConstraintDampingTimeline, + PhysicsConstraintGravityTimeline: () => PhysicsConstraintGravityTimeline, + PhysicsConstraintInertiaTimeline: () => PhysicsConstraintInertiaTimeline, + PhysicsConstraintMassTimeline: () => PhysicsConstraintMassTimeline, + PhysicsConstraintMixTimeline: () => PhysicsConstraintMixTimeline, + PhysicsConstraintResetTimeline: () => PhysicsConstraintResetTimeline, + PhysicsConstraintStrengthTimeline: () => PhysicsConstraintStrengthTimeline, + PhysicsConstraintTimeline: () => PhysicsConstraintTimeline, + PhysicsConstraintWindTimeline: () => PhysicsConstraintWindTimeline, + PointAttachment: () => PointAttachment, + Pool: () => Pool, + PositionMode: () => PositionMode, + Pow: () => Pow, + PowOut: () => PowOut, + RGB2Timeline: () => RGB2Timeline, + RGBA2Timeline: () => RGBA2Timeline, + RGBATimeline: () => RGBATimeline, + RGBTimeline: () => RGBTimeline, + RegionAttachment: () => RegionAttachment, + RotateMode: () => RotateMode, + RotateTimeline: () => RotateTimeline, + SETUP: () => SETUP, + SUBSEQUENT: () => SUBSEQUENT, + ScaleTimeline: () => ScaleTimeline, + ScaleXTimeline: () => ScaleXTimeline, + ScaleYTimeline: () => ScaleYTimeline, + SequenceTimeline: () => SequenceTimeline, + ShearTimeline: () => ShearTimeline, + ShearXTimeline: () => ShearXTimeline, + ShearYTimeline: () => ShearYTimeline, + Skeleton: () => Skeleton, + SkeletonBinary: () => SkeletonBinary, + SkeletonBounds: () => SkeletonBounds, + SkeletonClipping: () => SkeletonClipping, + SkeletonData: () => SkeletonData, + SkeletonJson: () => SkeletonJson, + SkeletonRenderer: () => SkeletonRenderer, + Skin: () => Skin, + SkinEntry: () => SkinEntry, + Slot: () => Slot, + SlotData: () => SlotData, + SpacingMode: () => SpacingMode, + StringSet: () => StringSet, + Texture: () => Texture, + TextureAtlas: () => TextureAtlas, + TextureAtlasPage: () => TextureAtlasPage, + TextureAtlasRegion: () => TextureAtlasRegion, + TextureFilter: () => TextureFilter, + TextureRegion: () => TextureRegion, + TextureWrap: () => TextureWrap, + TimeKeeper: () => TimeKeeper, + Timeline: () => Timeline, + TrackEntry: () => TrackEntry, + TransformConstraint: () => TransformConstraint, + TransformConstraintData: () => TransformConstraintData, + TransformConstraintTimeline: () => TransformConstraintTimeline, + TranslateTimeline: () => TranslateTimeline, + TranslateXTimeline: () => TranslateXTimeline, + TranslateYTimeline: () => TranslateYTimeline, + Triangulator: () => Triangulator, + Utils: () => Utils, + Vector2: () => Vector2, + VertexAttachment: () => VertexAttachment, + WindowedMean: () => WindowedMean + }); + + // spine-core/src/Utils.ts + var IntSet = class { + array = new Array(); + add(value) { + let contains = this.contains(value); + this.array[value | 0] = value | 0; + return !contains; + } + contains(value) { + return this.array[value | 0] != void 0; + } + remove(value) { + this.array[value | 0] = void 0; + } + clear() { + this.array.length = 0; + } + }; + var StringSet = class { + entries = {}; + size = 0; + add(value) { + let contains = this.entries[value]; + this.entries[value] = true; + if (!contains) { + this.size++; + return true; + } + return false; + } + addAll(values) { + let oldSize = this.size; + for (var i = 0, n = values.length; i < n; i++) + this.add(values[i]); + return oldSize != this.size; + } + contains(value) { + return this.entries[value]; + } + clear() { + this.entries = {}; + this.size = 0; + } + }; + var Color = class _Color { + constructor(r = 0, g = 0, b = 0, a = 0) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + static WHITE = new _Color(1, 1, 1, 1); + static RED = new _Color(1, 0, 0, 1); + static GREEN = new _Color(0, 1, 0, 1); + static BLUE = new _Color(0, 0, 1, 1); + static MAGENTA = new _Color(1, 0, 1, 1); + set(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + return this.clamp(); + } + setFromColor(c) { + this.r = c.r; + this.g = c.g; + this.b = c.b; + this.a = c.a; + return this; + } + setFromString(hex) { + hex = hex.charAt(0) == "#" ? hex.substr(1) : hex; + this.r = parseInt(hex.substr(0, 2), 16) / 255; + this.g = parseInt(hex.substr(2, 2), 16) / 255; + this.b = parseInt(hex.substr(4, 2), 16) / 255; + this.a = hex.length != 8 ? 1 : parseInt(hex.substr(6, 2), 16) / 255; + return this; + } + add(r, g, b, a) { + this.r += r; + this.g += g; + this.b += b; + this.a += a; + return this.clamp(); + } + clamp() { + if (this.r < 0) this.r = 0; + else if (this.r > 1) this.r = 1; + if (this.g < 0) this.g = 0; + else if (this.g > 1) this.g = 1; + if (this.b < 0) this.b = 0; + else if (this.b > 1) this.b = 1; + if (this.a < 0) this.a = 0; + else if (this.a > 1) this.a = 1; + return this; + } + static rgba8888ToColor(color, value) { + color.r = ((value & 4278190080) >>> 24) / 255; + color.g = ((value & 16711680) >>> 16) / 255; + color.b = ((value & 65280) >>> 8) / 255; + color.a = (value & 255) / 255; + } + static rgb888ToColor(color, value) { + color.r = ((value & 16711680) >>> 16) / 255; + color.g = ((value & 65280) >>> 8) / 255; + color.b = (value & 255) / 255; + } + toRgb888() { + const hex = (x) => ("0" + (x * 255).toString(16)).slice(-2); + return Number("0x" + hex(this.r) + hex(this.g) + hex(this.b)); + } + static fromString(hex, color = new _Color()) { + return color.setFromString(hex); + } + }; + var MathUtils = class _MathUtils { + static PI = 3.1415927; + static PI2 = _MathUtils.PI * 2; + static invPI2 = 1 / _MathUtils.PI2; + static radiansToDegrees = 180 / _MathUtils.PI; + static radDeg = _MathUtils.radiansToDegrees; + static degreesToRadians = _MathUtils.PI / 180; + static degRad = _MathUtils.degreesToRadians; + static clamp(value, min, max) { + if (value < min) return min; + if (value > max) return max; + return value; + } + static cosDeg(degrees) { + return Math.cos(degrees * _MathUtils.degRad); + } + static sinDeg(degrees) { + return Math.sin(degrees * _MathUtils.degRad); + } + static atan2Deg(y, x) { + return Math.atan2(y, x) * _MathUtils.degRad; + } + static signum(value) { + return value > 0 ? 1 : value < 0 ? -1 : 0; + } + static toInt(x) { + return x > 0 ? Math.floor(x) : Math.ceil(x); + } + static cbrt(x) { + let y = Math.pow(Math.abs(x), 1 / 3); + return x < 0 ? -y : y; + } + static randomTriangular(min, max) { + return _MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); + } + static randomTriangularWith(min, max, mode) { + let u = Math.random(); + let d = max - min; + if (u <= (mode - min) / d) return min + Math.sqrt(u * d * (mode - min)); + return max - Math.sqrt((1 - u) * d * (max - mode)); + } + static isPowerOfTwo(value) { + return value && (value & value - 1) === 0; + } + }; + var Interpolation = class { + apply(start, end, a) { + return start + (end - start) * this.applyInternal(a); + } + }; + var Pow = class extends Interpolation { + power = 2; + constructor(power) { + super(); + this.power = power; + } + applyInternal(a) { + if (a <= 0.5) return Math.pow(a * 2, this.power) / 2; + return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; + } + }; + var PowOut = class extends Pow { + constructor(power) { + super(power); + } + applyInternal(a) { + return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; + } + }; + var Utils = class _Utils { + static SUPPORTS_TYPED_ARRAYS = typeof Float32Array !== "undefined"; + static arrayCopy(source, sourceStart, dest, destStart, numElements) { + for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { + dest[j] = source[i]; + } + } + static arrayFill(array, fromIndex, toIndex, value) { + for (let i = fromIndex; i < toIndex; i++) + array[i] = value; + } + static setArraySize(array, size, value = 0) { + let oldSize = array.length; + if (oldSize == size) return array; + array.length = size; + if (oldSize < size) { + for (let i = oldSize; i < size; i++) array[i] = value; + } + return array; + } + static ensureArrayCapacity(array, size, value = 0) { + if (array.length >= size) return array; + return _Utils.setArraySize(array, size, value); + } + static newArray(size, defaultValue) { + let array = new Array(size); + for (let i = 0; i < size; i++) array[i] = defaultValue; + return array; + } + static newFloatArray(size) { + if (_Utils.SUPPORTS_TYPED_ARRAYS) + return new Float32Array(size); + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) array[i] = 0; + return array; + } + } + static newShortArray(size) { + if (_Utils.SUPPORTS_TYPED_ARRAYS) + return new Int16Array(size); + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) array[i] = 0; + return array; + } + } + static toFloatArray(array) { + return _Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; + } + static toSinglePrecision(value) { + return _Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value; + } + // This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 + static webkit602BugfixHelper(alpha, blend) { + } + static contains(array, element, identity = true) { + for (var i = 0; i < array.length; i++) + if (array[i] == element) return true; + return false; + } + static enumValue(type, name) { + return type[name[0].toUpperCase() + name.slice(1)]; + } + }; + var DebugUtils = class { + static logBones(skeleton) { + for (let i = 0; i < skeleton.bones.length; i++) { + let bone = skeleton.bones[i]; + console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY); + } + } + }; + var Pool = class { + items = new Array(); + instantiator; + constructor(instantiator) { + this.instantiator = instantiator; + } + obtain() { + return this.items.length > 0 ? this.items.pop() : this.instantiator(); + } + free(item) { + if (item.reset) item.reset(); + this.items.push(item); + } + freeAll(items) { + for (let i = 0; i < items.length; i++) + this.free(items[i]); + } + clear() { + this.items.length = 0; + } + }; + var Vector2 = class { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + set(x, y) { + this.x = x; + this.y = y; + return this; + } + length() { + let x = this.x; + let y = this.y; + return Math.sqrt(x * x + y * y); + } + normalize() { + let len = this.length(); + if (len != 0) { + this.x /= len; + this.y /= len; + } + return this; + } + }; + var TimeKeeper = class { + maxDelta = 0.064; + framesPerSecond = 0; + delta = 0; + totalTime = 0; + lastTime = Date.now() / 1e3; + frameCount = 0; + frameTime = 0; + update() { + let now = Date.now() / 1e3; + this.delta = now - this.lastTime; + this.frameTime += this.delta; + this.totalTime += this.delta; + if (this.delta > this.maxDelta) this.delta = this.maxDelta; + this.lastTime = now; + this.frameCount++; + if (this.frameTime > 1) { + this.framesPerSecond = this.frameCount / this.frameTime; + this.frameTime = 0; + this.frameCount = 0; + } + } + }; + var WindowedMean = class { + values; + addedValues = 0; + lastValue = 0; + mean = 0; + dirty = true; + constructor(windowSize = 32) { + this.values = new Array(windowSize); + } + hasEnoughData() { + return this.addedValues >= this.values.length; + } + addValue(value) { + if (this.addedValues < this.values.length) this.addedValues++; + this.values[this.lastValue++] = value; + if (this.lastValue > this.values.length - 1) this.lastValue = 0; + this.dirty = true; + } + getMean() { + if (this.hasEnoughData()) { + if (this.dirty) { + let mean = 0; + for (let i = 0; i < this.values.length; i++) + mean += this.values[i]; + this.mean = mean / this.values.length; + this.dirty = false; + } + return this.mean; + } + return 0; + } + }; + + // spine-core/src/attachments/Attachment.ts + var Attachment = class { + name; + constructor(name) { + if (!name) throw new Error("name cannot be null."); + this.name = name; + } + }; + var VertexAttachment = class _VertexAttachment extends Attachment { + static nextID = 0; + /** The unique ID for this attachment. */ + id = _VertexAttachment.nextID++; + /** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting + * the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#bones}. Will be null + * if this attachment has no weights. */ + bones = null; + /** The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are `x,y` + * entries for each vertex. For a weighted attachment, the values are `x,y,weight` entries for each bone affecting + * each vertex. */ + vertices = []; + /** The maximum number of world vertex values that can be output by + * {@link #computeWorldVertices()} using the `count` parameter. */ + worldVerticesLength = 0; + /** Timelines for the timeline attachment are also applied to this attachment. + * May be null if no attachment-specific timelines should be applied. */ + timelineAttachment = this; + constructor(name) { + super(name); + } + /** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} is + * not empty, it is used to deform the vertices. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. + * @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y. + * @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`. + * @param worldVertices The output world vertices. Must have a length >= `offset` + `count` * + * `stride` / 2. + * @param offset The `worldVertices` index to begin writing values. + * @param stride The number of `worldVertices` entries between the value pairs written. */ + computeWorldVertices(slot, start, count, worldVertices2, offset, stride) { + count = offset + (count >> 1) * stride; + let skeleton = slot.bone.skeleton; + let deformArray = slot.deform; + let vertices = this.vertices; + let bones = this.bones; + if (!bones) { + if (deformArray.length > 0) vertices = deformArray; + let bone = slot.bone; + let x = bone.worldX; + let y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + for (let v2 = start, w = offset; w < count; v2 += 2, w += stride) { + let vx = vertices[v2], vy = vertices[v2 + 1]; + worldVertices2[w] = vx * a + vy * b + x; + worldVertices2[w + 1] = vx * c + vy * d + y; + } + return; + } + let v = 0, skip = 0; + for (let i = 0; i < start; i += 2) { + let n = bones[v]; + v += n + 1; + skip += n; + } + let skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (let w = offset, b = skip * 3; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices2[w] = wx; + worldVertices2[w + 1] = wy; + } + } else { + let deform = deformArray; + for (let w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices2[w] = wx; + worldVertices2[w + 1] = wy; + } + } + } + /** Does not copy id (generated) or name (set on construction). **/ + copyTo(attachment) { + if (this.bones) { + attachment.bones = new Array(this.bones.length); + Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); + } else + attachment.bones = null; + if (this.vertices) { + attachment.vertices = Utils.newFloatArray(this.vertices.length); + Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); + } + attachment.worldVerticesLength = this.worldVerticesLength; + attachment.timelineAttachment = this.timelineAttachment; + } + }; + + // spine-core/src/attachments/Sequence.ts + var Sequence = class _Sequence { + static _nextID = 0; + id = _Sequence.nextID(); + regions; + start = 0; + digits = 0; + /** The index of the region to show for the setup pose. */ + setupIndex = 0; + constructor(count) { + this.regions = new Array(count); + } + copy() { + let copy = new _Sequence(this.regions.length); + Utils.arrayCopy(this.regions, 0, copy.regions, 0, this.regions.length); + copy.start = this.start; + copy.digits = this.digits; + copy.setupIndex = this.setupIndex; + return copy; + } + apply(slot, attachment) { + let index = slot.sequenceIndex; + if (index == -1) index = this.setupIndex; + if (index >= this.regions.length) index = this.regions.length - 1; + let region = this.regions[index]; + if (attachment.region != region) { + attachment.region = region; + attachment.updateRegion(); + } + } + getPath(basePath, index) { + let result = basePath; + let frame = (this.start + index).toString(); + for (let i = this.digits - frame.length; i > 0; i--) + result += "0"; + result += frame; + return result; + } + static nextID() { + return _Sequence._nextID++; + } + }; + var SequenceMode = /* @__PURE__ */ ((SequenceMode2) => { + SequenceMode2[SequenceMode2["hold"] = 0] = "hold"; + SequenceMode2[SequenceMode2["once"] = 1] = "once"; + SequenceMode2[SequenceMode2["loop"] = 2] = "loop"; + SequenceMode2[SequenceMode2["pingpong"] = 3] = "pingpong"; + SequenceMode2[SequenceMode2["onceReverse"] = 4] = "onceReverse"; + SequenceMode2[SequenceMode2["loopReverse"] = 5] = "loopReverse"; + SequenceMode2[SequenceMode2["pingpongReverse"] = 6] = "pingpongReverse"; + return SequenceMode2; + })(SequenceMode || {}); + var SequenceModeValues = [ + 0 /* hold */, + 1 /* once */, + 2 /* loop */, + 3 /* pingpong */, + 4 /* onceReverse */, + 5 /* loopReverse */, + 6 /* pingpongReverse */ + ]; + + // spine-core/src/Animation.ts + var Animation = class { + /** The animation's name, which is unique across all animations in the skeleton. */ + name; + timelines = []; + timelineIds = new StringSet(); + /** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */ + duration; + constructor(name, timelines, duration) { + if (!name) throw new Error("name cannot be null."); + this.name = name; + this.setTimelines(timelines); + this.duration = duration; + } + setTimelines(timelines) { + if (!timelines) throw new Error("timelines cannot be null."); + this.timelines = timelines; + this.timelineIds.clear(); + for (var i = 0; i < timelines.length; i++) + this.timelineIds.addAll(timelines[i].getPropertyIds()); + } + hasTimeline(ids) { + for (let i = 0; i < ids.length; i++) + if (this.timelineIds.contains(ids[i])) return true; + return false; + } + /** Applies all the animation's timelines to the specified skeleton. + * + * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. + * @param loop If true, the animation repeats after {@link #getDuration()}. + * @param events May be null to ignore fired events. */ + apply(skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (!skeleton) throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) lastTime %= this.duration; + } + let timelines = this.timelines; + for (let i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + } + }; + var MixBlend = /* @__PURE__ */ ((MixBlend2) => { + MixBlend2[MixBlend2["setup"] = 0] = "setup"; + MixBlend2[MixBlend2["first"] = 1] = "first"; + MixBlend2[MixBlend2["replace"] = 2] = "replace"; + MixBlend2[MixBlend2["add"] = 3] = "add"; + return MixBlend2; + })(MixBlend || {}); + var MixDirection = /* @__PURE__ */ ((MixDirection2) => { + MixDirection2[MixDirection2["mixIn"] = 0] = "mixIn"; + MixDirection2[MixDirection2["mixOut"] = 1] = "mixOut"; + return MixDirection2; + })(MixDirection || {}); + var Property = { + rotate: 0, + x: 1, + y: 2, + scaleX: 3, + scaleY: 4, + shearX: 5, + shearY: 6, + inherit: 7, + rgb: 8, + alpha: 9, + rgb2: 10, + attachment: 11, + deform: 12, + event: 13, + drawOrder: 14, + ikConstraint: 15, + transformConstraint: 16, + pathConstraintPosition: 17, + pathConstraintSpacing: 18, + pathConstraintMix: 19, + physicsConstraintInertia: 20, + physicsConstraintStrength: 21, + physicsConstraintDamping: 22, + physicsConstraintMass: 23, + physicsConstraintWind: 24, + physicsConstraintGravity: 25, + physicsConstraintMix: 26, + physicsConstraintReset: 27, + sequence: 28 + }; + var Timeline = class { + propertyIds; + frames; + constructor(frameCount, propertyIds) { + this.propertyIds = propertyIds; + this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries()); + } + getPropertyIds() { + return this.propertyIds; + } + getFrameEntries() { + return 1; + } + getFrameCount() { + return this.frames.length / this.getFrameEntries(); + } + getDuration() { + return this.frames[this.frames.length - this.getFrameEntries()]; + } + static search1(frames, time) { + let n = frames.length; + for (let i = 1; i < n; i++) + if (frames[i] > time) return i - 1; + return n - 1; + } + static search(frames, time, step) { + let n = frames.length; + for (let i = step; i < n; i += step) + if (frames[i] > time) return i - step; + return n - step; + } + }; + var CurveTimeline = class extends Timeline { + curves; + // type, x, y, ... + constructor(frameCount, bezierCount, propertyIds) { + super(frameCount, propertyIds); + this.curves = Utils.newFloatArray( + frameCount + bezierCount * 18 + /*BEZIER_SIZE*/ + ); + this.curves[frameCount - 1] = 1; + } + /** Sets the specified key frame to linear interpolation. */ + setLinear(frame) { + this.curves[frame] = 0; + } + /** Sets the specified key frame to stepped interpolation. */ + setStepped(frame) { + this.curves[frame] = 1; + } + /** Shrinks the storage for Bezier curves, for use when bezierCount (specified in the constructor) was larger + * than the actual number of Bezier curves. */ + shrink(bezierCount) { + let size = this.getFrameCount() + bezierCount * 18; + if (this.curves.length > size) { + let newCurves = Utils.newFloatArray(size); + Utils.arrayCopy(this.curves, 0, newCurves, 0, size); + this.curves = newCurves; + } + } + /** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than + * one curve per frame. + * @param bezier The ordinal of this Bezier curve for this timeline, between 0 and bezierCount - 1 (specified + * in the constructor), inclusive. + * @param frame Between 0 and frameCount - 1, inclusive. + * @param value The index of the value for this frame that this curve is used for. + * @param time1 The time for the first key. + * @param value1 The value for the first key. + * @param cx1 The time for the first Bezier handle. + * @param cy1 The value for the first Bezier handle. + * @param cx2 The time of the second Bezier handle. + * @param cy2 The value for the second Bezier handle. + * @param time2 The time for the second key. + * @param value2 The value for the second key. */ + setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { + let curves = this.curves; + let i = this.getFrameCount() + bezier * 18; + if (value == 0) curves[frame] = 2 + i; + let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = (value1 - cy1 * 2 + cy2) * 0.03; + let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 6e-3, dddy = ((cy1 - cy2) * 3 - value1 + value2) * 6e-3; + let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = (cy1 - value1) * 0.3 + tmpy + dddy * 0.16666667; + let x = time1 + dx, y = value1 + dy; + for (let n = i + 18; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dx += ddx; + dy += ddy; + ddx += dddx; + ddy += dddy; + x += dx; + y += dy; + } + } + /** Returns the Bezier interpolated value for the specified time. + * @param frameIndex The index into {@link #getFrames()} for the values of the frame before time. + * @param valueOffset The offset from frameIndex to the value this curve is used for. + * @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */ + getBezierValue(time, frameIndex, valueOffset, i) { + let curves = this.curves; + if (curves[i] > time) { + let x2 = this.frames[frameIndex], y2 = this.frames[frameIndex + valueOffset]; + return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2); + } + let n = i + 18; + for (i += 2; i < n; i += 2) { + if (curves[i] >= time) { + let x2 = curves[i - 2], y2 = curves[i - 1]; + return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2); + } + } + frameIndex += this.getFrameEntries(); + let x = curves[n - 2], y = curves[n - 1]; + return y + (time - x) / (this.frames[frameIndex] - x) * (this.frames[frameIndex + valueOffset] - y); + } + }; + var CurveTimeline1 = class extends CurveTimeline { + constructor(frameCount, bezierCount, propertyId) { + super(frameCount, bezierCount, [propertyId]); + } + getFrameEntries() { + return 2; + } + /** Sets the time and value for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + setFrame(frame, time, value) { + frame <<= 1; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*VALUE*/ + ] = value; + } + /** Returns the interpolated value for the specified time. */ + getCurveValue(time) { + let frames = this.frames; + let i = frames.length - 2; + for (let ii = 2; ii <= i; ii += 2) { + if (frames[ii] > time) { + i = ii - 2; + break; + } + } + let curveType = this.curves[i >> 1]; + switch (curveType) { + case 0: + let before = frames[i], value = frames[ + i + 1 + /*VALUE*/ + ]; + return value + (time - before) / (frames[ + i + 2 + /*ENTRIES*/ + ] - before) * (frames[ + i + 2 + 1 + /*VALUE*/ + ] - value); + case 1: + return frames[ + i + 1 + /*VALUE*/ + ]; + } + return this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + } + getRelativeValue(time, alpha, blend, current, setup) { + if (time < this.frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + let value = this.getCurveValue(time); + switch (blend) { + case 0 /* setup */: + return setup + value * alpha; + case 1 /* first */: + case 2 /* replace */: + value += setup - current; + } + return current + value * alpha; + } + getAbsoluteValue(time, alpha, blend, current, setup) { + if (time < this.frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + let value = this.getCurveValue(time); + if (blend == 0 /* setup */) return setup + (value - setup) * alpha; + return current + (value - current) * alpha; + } + getAbsoluteValue2(time, alpha, blend, current, setup, value) { + if (time < this.frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + if (blend == 0 /* setup */) return setup + (value - setup) * alpha; + return current + (value - current) * alpha; + } + getScaleValue(time, alpha, blend, direction, current, setup) { + const frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + return setup; + case 1 /* first */: + return current + (setup - current) * alpha; + } + return current; + } + let value = this.getCurveValue(time) * setup; + if (alpha == 1) { + if (blend == 3 /* add */) return current + value - setup; + return value; + } + if (direction == 1 /* mixOut */) { + switch (blend) { + case 0 /* setup */: + return setup + (Math.abs(value) * MathUtils.signum(setup) - setup) * alpha; + case 1 /* first */: + case 2 /* replace */: + return current + (Math.abs(value) * MathUtils.signum(current) - current) * alpha; + } + } else { + let s = 0; + switch (blend) { + case 0 /* setup */: + s = Math.abs(setup) * MathUtils.signum(value); + return s + (value - s) * alpha; + case 1 /* first */: + case 2 /* replace */: + s = Math.abs(current) * MathUtils.signum(value); + return s + (value - s) * alpha; + } + } + return current + (value - setup) * alpha; + } + }; + var CurveTimeline2 = class extends CurveTimeline { + /** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}. + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ + constructor(frameCount, bezierCount, propertyId1, propertyId2) { + super(frameCount, bezierCount, [propertyId1, propertyId2]); + } + getFrameEntries() { + return 3; + } + /** Sets the time and values for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + setFrame(frame, time, value1, value2) { + frame *= 3; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*VALUE1*/ + ] = value1; + this.frames[ + frame + 2 + /*VALUE2*/ + ] = value2; + } + }; + var RotateTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.rotate + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.rotation = this.getRelativeValue(time, alpha, blend, bone.rotation, bone.data.rotation); + } + }; + var TranslateTimeline = class extends CurveTimeline2 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super( + frameCount, + bezierCount, + Property.x + "|" + boneIndex, + Property.y + "|" + boneIndex + ); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case 1 /* first */: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + let x = 0, y = 0; + let i = Timeline.search( + frames, + time, + 3 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 3 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + let t = (time - before) / (frames[ + i + 3 + /*ENTRIES*/ + ] - before); + x += (frames[ + i + 3 + 1 + /*VALUE1*/ + ] - x) * t; + y += (frames[ + i + 3 + 2 + /*VALUE2*/ + ] - y) * t; + break; + case 1: + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + break; + default: + x = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + switch (blend) { + case 0 /* setup */: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case 3 /* add */: + bone.x += x * alpha; + bone.y += y * alpha; + } + } + }; + var TranslateXTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.x + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.x = this.getRelativeValue(time, alpha, blend, bone.x, bone.data.x); + } + }; + var TranslateYTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.y + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.y = this.getRelativeValue(time, alpha, blend, bone.y, bone.data.y); + } + }; + var ScaleTimeline = class extends CurveTimeline2 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super( + frameCount, + bezierCount, + Property.scaleX + "|" + boneIndex, + Property.scaleY + "|" + boneIndex + ); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case 1 /* first */: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + let x, y; + let i = Timeline.search( + frames, + time, + 3 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 3 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + let t = (time - before) / (frames[ + i + 3 + /*ENTRIES*/ + ] - before); + x += (frames[ + i + 3 + 1 + /*VALUE1*/ + ] - x) * t; + y += (frames[ + i + 3 + 2 + /*VALUE2*/ + ] - y) * t; + break; + case 1: + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + break; + default: + x = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + x *= bone.data.scaleX; + y *= bone.data.scaleY; + if (alpha == 1) { + if (blend == 3 /* add */) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } else { + bone.scaleX = x; + bone.scaleY = y; + } + } else { + let bx = 0, by = 0; + if (direction == 1 /* mixOut */) { + switch (blend) { + case 0 /* setup */: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha; + break; + case 3 /* add */: + bone.scaleX += (x - bone.data.scaleX) * alpha; + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } else { + switch (blend) { + case 0 /* setup */: + bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bx = Math.abs(bone.scaleX) * MathUtils.signum(x); + by = Math.abs(bone.scaleY) * MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case 3 /* add */: + bone.scaleX += (x - bone.data.scaleX) * alpha; + bone.scaleY += (y - bone.data.scaleY) * alpha; + } + } + } + } + }; + var ScaleXTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.scaleX + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.scaleX = this.getScaleValue(time, alpha, blend, direction, bone.scaleX, bone.data.scaleX); + } + }; + var ScaleYTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.scaleY + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.scaleY = this.getScaleValue(time, alpha, blend, direction, bone.scaleY, bone.data.scaleY); + } + }; + var ShearTimeline = class extends CurveTimeline2 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super( + frameCount, + bezierCount, + Property.shearX + "|" + boneIndex, + Property.shearY + "|" + boneIndex + ); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case 1 /* first */: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + let x = 0, y = 0; + let i = Timeline.search( + frames, + time, + 3 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 3 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + let t = (time - before) / (frames[ + i + 3 + /*ENTRIES*/ + ] - before); + x += (frames[ + i + 3 + 1 + /*VALUE1*/ + ] - x) * t; + y += (frames[ + i + 3 + 2 + /*VALUE2*/ + ] - y) * t; + break; + case 1: + x = frames[ + i + 1 + /*VALUE1*/ + ]; + y = frames[ + i + 2 + /*VALUE2*/ + ]; + break; + default: + x = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + switch (blend) { + case 0 /* setup */: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case 1 /* first */: + case 2 /* replace */: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case 3 /* add */: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + } + }; + var ShearXTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.shearX + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.shearX = this.getRelativeValue(time, alpha, blend, bone.shearX, bone.data.shearX); + } + }; + var ShearYTimeline = class extends CurveTimeline1 { + boneIndex = 0; + constructor(frameCount, bezierCount, boneIndex) { + super(frameCount, bezierCount, Property.shearY + "|" + boneIndex); + this.boneIndex = boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (bone.active) bone.shearY = this.getRelativeValue(time, alpha, blend, bone.shearY, bone.data.shearY); + } + }; + var InheritTimeline = class extends Timeline { + boneIndex = 0; + constructor(frameCount, boneIndex) { + super(frameCount, [Property.inherit + "|" + boneIndex]); + this.boneIndex = boneIndex; + } + getFrameEntries() { + return 2; + } + /** Sets the transform mode for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time The frame time in seconds. */ + setFrame(frame, time, inherit) { + frame *= 2; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*INHERIT*/ + ] = inherit; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) return; + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) bone.inherit = bone.data.inherit; + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) bone.inherit = bone.data.inherit; + return; + } + bone.inherit = this.frames[ + Timeline.search( + frames, + time, + 2 + /*ENTRIES*/ + ) + 1 + /*INHERIT*/ + ]; + } + }; + var RGBATimeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.alpha + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 5; + } + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + setFrame(frame, time, r, g, b, a) { + frame *= 5; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + this.frames[ + frame + 4 + /*A*/ + ] = a; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let color = slot.color; + if (time < frames[0]) { + let setup = slot.data.color; + switch (blend) { + case 0 /* setup */: + color.setFromColor(setup); + return; + case 1 /* first */: + color.add( + (setup.r - color.r) * alpha, + (setup.g - color.g) * alpha, + (setup.b - color.b) * alpha, + (setup.a - color.a) * alpha + ); + } + return; + } + let r = 0, g = 0, b = 0, a = 0; + let i = Timeline.search( + frames, + time, + 5 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 5 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + let t = (time - before) / (frames[ + i + 5 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 5 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 5 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 5 + 3 + /*B*/ + ] - b) * t; + a += (frames[ + i + 5 + 4 + /*A*/ + ] - a) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + a = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) + color.set(r, g, b, a); + else { + if (blend == 0 /* setup */) color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + } + }; + var RGBTimeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 4; + } + /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ + setFrame(frame, time, r, g, b) { + frame <<= 2; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let color = slot.color; + if (time < frames[0]) { + let setup = slot.data.color; + switch (blend) { + case 0 /* setup */: + color.r = setup.r; + color.g = setup.g; + color.b = setup.b; + return; + case 1 /* first */: + color.r += (setup.r - color.r) * alpha; + color.g += (setup.g - color.g) * alpha; + color.b += (setup.b - color.b) * alpha; + } + return; + } + let r = 0, g = 0, b = 0; + let i = Timeline.search( + frames, + time, + 4 + /*ENTRIES*/ + ); + let curveType = this.curves[i >> 2]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + let t = (time - before) / (frames[ + i + 4 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 4 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 4 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 4 + 3 + /*B*/ + ] - b) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) { + color.r = r; + color.g = g; + color.b = b; + } else { + if (blend == 0 /* setup */) { + let setup = slot.data.color; + color.r = setup.r; + color.g = setup.g; + color.b = setup.b; + } + color.r += (r - color.r) * alpha; + color.g += (g - color.g) * alpha; + color.b += (b - color.b) * alpha; + } + } + }; + var AlphaTimeline = class extends CurveTimeline1 { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, Property.alpha + "|" + slotIndex); + this.slotIndex = slotIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let color = slot.color; + if (time < this.frames[0]) { + let setup = slot.data.color; + switch (blend) { + case 0 /* setup */: + color.a = setup.a; + return; + case 1 /* first */: + color.a += (setup.a - color.a) * alpha; + } + return; + } + let a = this.getCurveValue(time); + if (alpha == 1) + color.a = a; + else { + if (blend == 0 /* setup */) color.a = slot.data.color.a; + color.a += (a - color.a) * alpha; + } + } + }; + var RGBA2Timeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.alpha + "|" + slotIndex, + Property.rgb2 + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 8; + } + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + setFrame(frame, time, r, g, b, a, r2, g2, b2) { + frame <<= 3; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + this.frames[ + frame + 4 + /*A*/ + ] = a; + this.frames[ + frame + 5 + /*R2*/ + ] = r2; + this.frames[ + frame + 6 + /*G2*/ + ] = g2; + this.frames[ + frame + 7 + /*B2*/ + ] = b2; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let light = slot.color, dark = slot.darkColor; + if (time < frames[0]) { + let setupLight = slot.data.color, setupDark = slot.data.darkColor; + switch (blend) { + case 0 /* setup */: + light.setFromColor(setupLight); + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + return; + case 1 /* first */: + light.add( + (setupLight.r - light.r) * alpha, + (setupLight.g - light.g) * alpha, + (setupLight.b - light.b) * alpha, + (setupLight.a - light.a) * alpha + ); + dark.r += (setupDark.r - dark.r) * alpha; + dark.g += (setupDark.g - dark.g) * alpha; + dark.b += (setupDark.b - dark.b) * alpha; + } + return; + } + let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + let i = Timeline.search( + frames, + time, + 8 + /*ENTRIES*/ + ); + let curveType = this.curves[i >> 3]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + r2 = frames[ + i + 5 + /*R2*/ + ]; + g2 = frames[ + i + 6 + /*G2*/ + ]; + b2 = frames[ + i + 7 + /*B2*/ + ]; + let t = (time - before) / (frames[ + i + 8 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 8 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 8 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 8 + 3 + /*B*/ + ] - b) * t; + a += (frames[ + i + 8 + 4 + /*A*/ + ] - a) * t; + r2 += (frames[ + i + 8 + 5 + /*R2*/ + ] - r2) * t; + g2 += (frames[ + i + 8 + 6 + /*G2*/ + ] - g2) * t; + b2 += (frames[ + i + 8 + 7 + /*B2*/ + ] - b2) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + a = frames[ + i + 4 + /*A*/ + ]; + r2 = frames[ + i + 5 + /*R2*/ + ]; + g2 = frames[ + i + 6 + /*G2*/ + ]; + b2 = frames[ + i + 7 + /*B2*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + a = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + r2 = this.getBezierValue( + time, + i, + 5, + curveType + 18 * 4 - 2 + /*BEZIER*/ + ); + g2 = this.getBezierValue( + time, + i, + 6, + curveType + 18 * 5 - 2 + /*BEZIER*/ + ); + b2 = this.getBezierValue( + time, + i, + 7, + curveType + 18 * 6 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) { + light.set(r, g, b, a); + dark.r = r2; + dark.g = g2; + dark.b = b2; + } else { + if (blend == 0 /* setup */) { + light.setFromColor(slot.data.color); + let setupDark = slot.data.darkColor; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.r += (r2 - dark.r) * alpha; + dark.g += (g2 - dark.g) * alpha; + dark.b += (b2 - dark.b) * alpha; + } + } + }; + var RGB2Timeline = class extends CurveTimeline { + slotIndex = 0; + constructor(frameCount, bezierCount, slotIndex) { + super(frameCount, bezierCount, [ + Property.rgb + "|" + slotIndex, + Property.rgb2 + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + } + getFrameEntries() { + return 7; + } + /** Sets the time in seconds, light, and dark colors for the specified key frame. */ + setFrame(frame, time, r, g, b, r2, g2, b2) { + frame *= 7; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*R*/ + ] = r; + this.frames[ + frame + 2 + /*G*/ + ] = g; + this.frames[ + frame + 3 + /*B*/ + ] = b; + this.frames[ + frame + 4 + /*R2*/ + ] = r2; + this.frames[ + frame + 5 + /*G2*/ + ] = g2; + this.frames[ + frame + 6 + /*B2*/ + ] = b2; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let frames = this.frames; + let light = slot.color, dark = slot.darkColor; + if (time < frames[0]) { + let setupLight = slot.data.color, setupDark = slot.data.darkColor; + switch (blend) { + case 0 /* setup */: + light.r = setupLight.r; + light.g = setupLight.g; + light.b = setupLight.b; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + return; + case 1 /* first */: + light.r += (setupLight.r - light.r) * alpha; + light.g += (setupLight.g - light.g) * alpha; + light.b += (setupLight.b - light.b) * alpha; + dark.r += (setupDark.r - dark.r) * alpha; + dark.g += (setupDark.g - dark.g) * alpha; + dark.b += (setupDark.b - dark.b) * alpha; + } + return; + } + let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + let i = Timeline.search( + frames, + time, + 7 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 7 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + r2 = frames[ + i + 4 + /*R2*/ + ]; + g2 = frames[ + i + 5 + /*G2*/ + ]; + b2 = frames[ + i + 6 + /*B2*/ + ]; + let t = (time - before) / (frames[ + i + 7 + /*ENTRIES*/ + ] - before); + r += (frames[ + i + 7 + 1 + /*R*/ + ] - r) * t; + g += (frames[ + i + 7 + 2 + /*G*/ + ] - g) * t; + b += (frames[ + i + 7 + 3 + /*B*/ + ] - b) * t; + r2 += (frames[ + i + 7 + 4 + /*R2*/ + ] - r2) * t; + g2 += (frames[ + i + 7 + 5 + /*G2*/ + ] - g2) * t; + b2 += (frames[ + i + 7 + 6 + /*B2*/ + ] - b2) * t; + break; + case 1: + r = frames[ + i + 1 + /*R*/ + ]; + g = frames[ + i + 2 + /*G*/ + ]; + b = frames[ + i + 3 + /*B*/ + ]; + r2 = frames[ + i + 4 + /*R2*/ + ]; + g2 = frames[ + i + 5 + /*G2*/ + ]; + b2 = frames[ + i + 6 + /*B2*/ + ]; + break; + default: + r = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + g = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + b = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + r2 = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + g2 = this.getBezierValue( + time, + i, + 5, + curveType + 18 * 4 - 2 + /*BEZIER*/ + ); + b2 = this.getBezierValue( + time, + i, + 6, + curveType + 18 * 5 - 2 + /*BEZIER*/ + ); + } + if (alpha == 1) { + light.r = r; + light.g = g; + light.b = b; + dark.r = r2; + dark.g = g2; + dark.b = b2; + } else { + if (blend == 0 /* setup */) { + let setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.r = setupLight.r; + light.g = setupLight.g; + light.b = setupLight.b; + dark.r = setupDark.r; + dark.g = setupDark.g; + dark.b = setupDark.b; + } + light.r += (r - light.r) * alpha; + light.g += (g - light.g) * alpha; + light.b += (b - light.b) * alpha; + dark.r += (r2 - dark.r) * alpha; + dark.g += (g2 - dark.g) * alpha; + dark.b += (b2 - dark.b) * alpha; + } + } + }; + var AttachmentTimeline = class extends Timeline { + slotIndex = 0; + /** The attachment name for each key frame. May contain null values to clear the attachment. */ + attachmentNames; + constructor(frameCount, slotIndex) { + super(frameCount, [ + Property.attachment + "|" + slotIndex + ]); + this.slotIndex = slotIndex; + this.attachmentNames = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the attachment name for the specified key frame. */ + setFrame(frame, time, attachmentName) { + this.frames[frame] = time; + this.attachmentNames[frame] = attachmentName; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + if (time < this.frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]); + } + setAttachment(skeleton, slot, attachmentName) { + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + } + }; + var DeformTimeline = class extends CurveTimeline { + slotIndex = 0; + /** The attachment that will be deformed. */ + attachment; + /** The vertices for each key frame. */ + vertices; + constructor(frameCount, bezierCount, slotIndex, attachment) { + super(frameCount, bezierCount, [ + Property.deform + "|" + slotIndex + "|" + attachment.id + ]); + this.slotIndex = slotIndex; + this.attachment = attachment; + this.vertices = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the vertices for the specified key frame. + * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ + setFrame(frame, time, vertices) { + this.frames[frame] = time; + this.vertices[frame] = vertices; + } + /** @param value1 Ignored (0 is used for a deform timeline). + * @param value2 Ignored (1 is used for a deform timeline). */ + setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2) { + let curves = this.curves; + let i = this.getFrameCount() + bezier * 18; + if (value == 0) curves[frame] = 2 + i; + let tmpx = (time1 - cx1 * 2 + cx2) * 0.03, tmpy = cy2 * 0.03 - cy1 * 0.06; + let dddx = ((cx1 - cx2) * 3 - time1 + time2) * 6e-3, dddy = (cy1 - cy2 + 0.33333333) * 0.018; + let ddx = tmpx * 2 + dddx, ddy = tmpy * 2 + dddy; + let dx = (cx1 - time1) * 0.3 + tmpx + dddx * 0.16666667, dy = cy1 * 0.3 + tmpy + dddy * 0.16666667; + let x = time1 + dx, y = dy; + for (let n = i + 18; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dx += ddx; + dy += ddy; + ddx += dddx; + ddy += dddy; + x += dx; + y += dy; + } + } + getCurvePercent(time, frame) { + let curves = this.curves; + let i = curves[frame]; + switch (i) { + case 0: + let x2 = this.frames[frame]; + return (time - x2) / (this.frames[frame + this.getFrameEntries()] - x2); + case 1: + return 0; + } + i -= 2; + if (curves[i] > time) { + let x2 = this.frames[frame]; + return curves[i + 1] * (time - x2) / (curves[i] - x2); + } + let n = i + 18; + for (i += 2; i < n; i += 2) { + if (curves[i] >= time) { + let x2 = curves[i - 2], y2 = curves[i - 1]; + return y2 + (time - x2) / (curves[i] - x2) * (curves[i + 1] - y2); + } + } + let x = curves[n - 2], y = curves[n - 1]; + return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x); + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let slotAttachment = slot.getAttachment(); + if (!slotAttachment) return; + if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != this.attachment) return; + let deform = slot.deform; + if (deform.length == 0) blend = 0 /* setup */; + let vertices = this.vertices; + let vertexCount = vertices[0].length; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + deform.length = 0; + return; + case 1 /* first */: + if (alpha == 1) { + deform.length = 0; + return; + } + deform.length = vertexCount; + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + deform[i] += (setupVertices[i] - deform[i]) * alpha; + } else { + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + deform[i] *= alpha; + } + } + return; + } + deform.length = vertexCount; + if (time >= frames[frames.length - 1]) { + let lastVertices = vertices[frames.length - 1]; + if (alpha == 1) { + if (blend == 3 /* add */) { + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += lastVertices[i2] - setupVertices[i2]; + } else { + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += lastVertices[i2]; + } + } else + Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); + } else { + switch (blend) { + case 0 /* setup */: { + let vertexAttachment2 = slotAttachment; + if (!vertexAttachment2.bones) { + let setupVertices = vertexAttachment2.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let setup = setupVertices[i2]; + deform[i2] = setup + (lastVertices[i2] - setup) * alpha; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] = lastVertices[i2] * alpha; + } + break; + } + case 1 /* first */: + case 2 /* replace */: + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += (lastVertices[i2] - deform[i2]) * alpha; + break; + case 3 /* add */: + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += (lastVertices[i2] - setupVertices[i2]) * alpha; + } else { + for (let i2 = 0; i2 < vertexCount; i2++) + deform[i2] += lastVertices[i2] * alpha; + } + } + } + return; + } + let frame = Timeline.search1(frames, time); + let percent = this.getCurvePercent(time, frame); + let prevVertices = vertices[frame]; + let nextVertices = vertices[frame + 1]; + if (alpha == 1) { + if (blend == 3 /* add */) { + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += prev + (nextVertices[i2] - prev) * percent - setupVertices[i2]; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += prev + (nextVertices[i2] - prev) * percent; + } + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] = prev + (nextVertices[i2] - prev) * percent; + } + } + } else { + switch (blend) { + case 0 /* setup */: { + let vertexAttachment2 = slotAttachment; + if (!vertexAttachment2.bones) { + let setupVertices = vertexAttachment2.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2], setup = setupVertices[i2]; + deform[i2] = setup + (prev + (nextVertices[i2] - prev) * percent - setup) * alpha; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] = (prev + (nextVertices[i2] - prev) * percent) * alpha; + } + } + break; + } + case 1 /* first */: + case 2 /* replace */: + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += (prev + (nextVertices[i2] - prev) * percent - deform[i2]) * alpha; + } + break; + case 3 /* add */: + let vertexAttachment = slotAttachment; + if (!vertexAttachment.bones) { + let setupVertices = vertexAttachment.vertices; + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += (prev + (nextVertices[i2] - prev) * percent - setupVertices[i2]) * alpha; + } + } else { + for (let i2 = 0; i2 < vertexCount; i2++) { + let prev = prevVertices[i2]; + deform[i2] += (prev + (nextVertices[i2] - prev) * percent) * alpha; + } + } + } + } + } + }; + var EventTimeline = class _EventTimeline extends Timeline { + static propertyIds = ["" + Property.event]; + /** The event for each key frame. */ + events; + constructor(frameCount) { + super(frameCount, _EventTimeline.propertyIds); + this.events = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the event for the specified key frame. */ + setFrame(frame, event) { + this.frames[frame] = event.time; + this.events[frame] = event; + } + /** Fires events for frames > `lastTime` and <= `time`. */ + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (!firedEvents) return; + let frames = this.frames; + let frameCount = this.frames.length; + if (lastTime > time) { + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } else if (lastTime >= frames[frameCount - 1]) + return; + if (time < frames[0]) return; + let i = 0; + if (lastTime < frames[0]) + i = 0; + else { + i = Timeline.search1(frames, lastTime) + 1; + let frameTime = frames[i]; + while (i > 0) { + if (frames[i - 1] != frameTime) break; + i--; + } + } + for (; i < frameCount && time >= frames[i]; i++) + firedEvents.push(this.events[i]); + } + }; + var DrawOrderTimeline = class _DrawOrderTimeline extends Timeline { + static propertyIds = ["" + Property.drawOrder]; + /** The draw order for each key frame. See {@link #setFrame(int, float, int[])}. */ + drawOrders; + constructor(frameCount) { + super(frameCount, _DrawOrderTimeline.propertyIds); + this.drawOrders = new Array(frameCount); + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time in seconds and the draw order for the specified key frame. + * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose + * draw order. */ + setFrame(frame, time, drawOrder) { + this.frames[frame] = time; + this.drawOrders[frame] = drawOrder; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + if (time < this.frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + let idx = Timeline.search1(this.frames, time); + let drawOrderToSetupIndex = this.drawOrders[idx]; + if (!drawOrderToSetupIndex) + Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + else { + let drawOrder = skeleton.drawOrder; + let slots = skeleton.slots; + for (let i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + } + }; + var IkConstraintTimeline = class extends CurveTimeline { + /** The index of the IK constraint in {@link Skeleton#getIkConstraints()} that will be changed when this timeline is applied */ + constraintIndex = 0; + constructor(frameCount, bezierCount, ikConstraintIndex) { + super(frameCount, bezierCount, [ + Property.ikConstraint + "|" + ikConstraintIndex + ]); + this.constraintIndex = ikConstraintIndex; + } + getFrameEntries() { + return 6; + } + /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ + setFrame(frame, time, mix, softness, bendDirection, compress, stretch) { + frame *= 6; + this.frames[frame] = time; + this.frames[ + frame + 1 + /*MIX*/ + ] = mix; + this.frames[ + frame + 2 + /*SOFTNESS*/ + ] = softness; + this.frames[ + frame + 3 + /*BEND_DIRECTION*/ + ] = bendDirection; + this.frames[ + frame + 4 + /*COMPRESS*/ + ] = compress ? 1 : 0; + this.frames[ + frame + 5 + /*STRETCH*/ + ] = stretch ? 1 : 0; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.ikConstraints[this.constraintIndex]; + if (!constraint.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case 1 /* first */: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.softness += (constraint.data.softness - constraint.softness) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + let mix = 0, softness = 0; + let i = Timeline.search( + frames, + time, + 6 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 6 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + mix = frames[ + i + 1 + /*MIX*/ + ]; + softness = frames[ + i + 2 + /*SOFTNESS*/ + ]; + let t = (time - before) / (frames[ + i + 6 + /*ENTRIES*/ + ] - before); + mix += (frames[ + i + 6 + 1 + /*MIX*/ + ] - mix) * t; + softness += (frames[ + i + 6 + 2 + /*SOFTNESS*/ + ] - softness) * t; + break; + case 1: + mix = frames[ + i + 1 + /*MIX*/ + ]; + softness = frames[ + i + 2 + /*SOFTNESS*/ + ]; + break; + default: + mix = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + softness = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + } + if (blend == 0 /* setup */) { + constraint.mix = constraint.data.mix + (mix - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + (softness - constraint.data.softness) * alpha; + if (direction == 1 /* mixOut */) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } else { + constraint.bendDirection = frames[ + i + 3 + /*BEND_DIRECTION*/ + ]; + constraint.compress = frames[ + i + 4 + /*COMPRESS*/ + ] != 0; + constraint.stretch = frames[ + i + 5 + /*STRETCH*/ + ] != 0; + } + } else { + constraint.mix += (mix - constraint.mix) * alpha; + constraint.softness += (softness - constraint.softness) * alpha; + if (direction == 0 /* mixIn */) { + constraint.bendDirection = frames[ + i + 3 + /*BEND_DIRECTION*/ + ]; + constraint.compress = frames[ + i + 4 + /*COMPRESS*/ + ] != 0; + constraint.stretch = frames[ + i + 5 + /*STRETCH*/ + ] != 0; + } + } + } + }; + var TransformConstraintTimeline = class extends CurveTimeline { + /** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, transformConstraintIndex) { + super(frameCount, bezierCount, [ + Property.transformConstraint + "|" + transformConstraintIndex + ]); + this.constraintIndex = transformConstraintIndex; + } + getFrameEntries() { + return 7; + } + /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ + setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY) { + let frames = this.frames; + frame *= 7; + frames[frame] = time; + frames[ + frame + 1 + /*ROTATE*/ + ] = mixRotate; + frames[ + frame + 2 + /*X*/ + ] = mixX; + frames[ + frame + 3 + /*Y*/ + ] = mixY; + frames[ + frame + 4 + /*SCALEX*/ + ] = mixScaleX; + frames[ + frame + 5 + /*SCALEY*/ + ] = mixScaleY; + frames[ + frame + 6 + /*SHEARY*/ + ] = mixShearY; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.transformConstraints[this.constraintIndex]; + if (!constraint.active) return; + let frames = this.frames; + if (time < frames[0]) { + let data = constraint.data; + switch (blend) { + case 0 /* setup */: + constraint.mixRotate = data.mixRotate; + constraint.mixX = data.mixX; + constraint.mixY = data.mixY; + constraint.mixScaleX = data.mixScaleX; + constraint.mixScaleY = data.mixScaleY; + constraint.mixShearY = data.mixShearY; + return; + case 1 /* first */: + constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (data.mixX - constraint.mixX) * alpha; + constraint.mixY += (data.mixY - constraint.mixY) * alpha; + constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha; + } + return; + } + let rotate, x, y, scaleX, scaleY, shearY; + let i = Timeline.search( + frames, + time, + 7 + /*ENTRIES*/ + ); + let curveType = this.curves[ + i / 7 + /*ENTRIES*/ + ]; + switch (curveType) { + case 0: + let before = frames[i]; + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + scaleX = frames[ + i + 4 + /*SCALEX*/ + ]; + scaleY = frames[ + i + 5 + /*SCALEY*/ + ]; + shearY = frames[ + i + 6 + /*SHEARY*/ + ]; + let t = (time - before) / (frames[ + i + 7 + /*ENTRIES*/ + ] - before); + rotate += (frames[ + i + 7 + 1 + /*ROTATE*/ + ] - rotate) * t; + x += (frames[ + i + 7 + 2 + /*X*/ + ] - x) * t; + y += (frames[ + i + 7 + 3 + /*Y*/ + ] - y) * t; + scaleX += (frames[ + i + 7 + 4 + /*SCALEX*/ + ] - scaleX) * t; + scaleY += (frames[ + i + 7 + 5 + /*SCALEY*/ + ] - scaleY) * t; + shearY += (frames[ + i + 7 + 6 + /*SHEARY*/ + ] - shearY) * t; + break; + case 1: + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + scaleX = frames[ + i + 4 + /*SCALEX*/ + ]; + scaleY = frames[ + i + 5 + /*SCALEY*/ + ]; + shearY = frames[ + i + 6 + /*SHEARY*/ + ]; + break; + default: + rotate = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + x = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + scaleX = this.getBezierValue( + time, + i, + 4, + curveType + 18 * 3 - 2 + /*BEZIER*/ + ); + scaleY = this.getBezierValue( + time, + i, + 5, + curveType + 18 * 4 - 2 + /*BEZIER*/ + ); + shearY = this.getBezierValue( + time, + i, + 6, + curveType + 18 * 5 - 2 + /*BEZIER*/ + ); + } + if (blend == 0 /* setup */) { + let data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha; + constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha; + constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha; + } else { + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (shearY - constraint.mixShearY) * alpha; + } + } + }; + var PathConstraintPositionTimeline = class extends CurveTimeline1 { + /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is + * applied. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, pathConstraintIndex) { + super(frameCount, bezierCount, Property.pathConstraintPosition + "|" + pathConstraintIndex); + this.constraintIndex = pathConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.pathConstraints[this.constraintIndex]; + if (constraint.active) + constraint.position = this.getAbsoluteValue(time, alpha, blend, constraint.position, constraint.data.position); + } + }; + var PathConstraintSpacingTimeline = class extends CurveTimeline1 { + /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is + * applied. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, pathConstraintIndex) { + super(frameCount, bezierCount, Property.pathConstraintSpacing + "|" + pathConstraintIndex); + this.constraintIndex = pathConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.pathConstraints[this.constraintIndex]; + if (constraint.active) + constraint.spacing = this.getAbsoluteValue(time, alpha, blend, constraint.spacing, constraint.data.spacing); + } + }; + var PathConstraintMixTimeline = class extends CurveTimeline { + /** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is + * applied. */ + constraintIndex = 0; + constructor(frameCount, bezierCount, pathConstraintIndex) { + super(frameCount, bezierCount, [ + Property.pathConstraintMix + "|" + pathConstraintIndex + ]); + this.constraintIndex = pathConstraintIndex; + } + getFrameEntries() { + return 4; + } + setFrame(frame, time, mixRotate, mixX, mixY) { + let frames = this.frames; + frame <<= 2; + frames[frame] = time; + frames[ + frame + 1 + /*ROTATE*/ + ] = mixRotate; + frames[ + frame + 2 + /*X*/ + ] = mixX; + frames[ + frame + 3 + /*Y*/ + ] = mixY; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint = skeleton.pathConstraints[this.constraintIndex]; + if (!constraint.active) return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + constraint.mixRotate = constraint.data.mixRotate; + constraint.mixX = constraint.data.mixX; + constraint.mixY = constraint.data.mixY; + return; + case 1 /* first */: + constraint.mixRotate += (constraint.data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (constraint.data.mixX - constraint.mixX) * alpha; + constraint.mixY += (constraint.data.mixY - constraint.mixY) * alpha; + } + return; + } + let rotate, x, y; + let i = Timeline.search( + frames, + time, + 4 + /*ENTRIES*/ + ); + let curveType = this.curves[i >> 2]; + switch (curveType) { + case 0: + let before = frames[i]; + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + let t = (time - before) / (frames[ + i + 4 + /*ENTRIES*/ + ] - before); + rotate += (frames[ + i + 4 + 1 + /*ROTATE*/ + ] - rotate) * t; + x += (frames[ + i + 4 + 2 + /*X*/ + ] - x) * t; + y += (frames[ + i + 4 + 3 + /*Y*/ + ] - y) * t; + break; + case 1: + rotate = frames[ + i + 1 + /*ROTATE*/ + ]; + x = frames[ + i + 2 + /*X*/ + ]; + y = frames[ + i + 3 + /*Y*/ + ]; + break; + default: + rotate = this.getBezierValue( + time, + i, + 1, + curveType - 2 + /*BEZIER*/ + ); + x = this.getBezierValue( + time, + i, + 2, + curveType + 18 - 2 + /*BEZIER*/ + ); + y = this.getBezierValue( + time, + i, + 3, + curveType + 18 * 2 - 2 + /*BEZIER*/ + ); + } + if (blend == 0 /* setup */) { + let data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + } else { + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + } + } + }; + var PhysicsConstraintTimeline = class extends CurveTimeline1 { + /** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be changed when this timeline + * is applied, or -1 if all physics constraints in the skeleton will be changed. */ + constraintIndex = 0; + /** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */ + constructor(frameCount, bezierCount, physicsConstraintIndex, property) { + super(frameCount, bezierCount, property + "|" + physicsConstraintIndex); + this.constraintIndex = physicsConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint; + if (this.constraintIndex == -1) { + const value = time >= this.frames[0] ? this.getCurveValue(time) : 0; + for (const constraint2 of skeleton.physicsConstraints) { + if (constraint2.active && this.global(constraint2.data)) + this.set(constraint2, this.getAbsoluteValue2(time, alpha, blend, this.get(constraint2), this.setup(constraint2), value)); + } + } else { + constraint = skeleton.physicsConstraints[this.constraintIndex]; + if (constraint.active) this.set(constraint, this.getAbsoluteValue(time, alpha, blend, this.get(constraint), this.setup(constraint))); + } + } + }; + var PhysicsConstraintInertiaTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia); + } + setup(constraint) { + return constraint.data.inertia; + } + get(constraint) { + return constraint.inertia; + } + set(constraint, value) { + constraint.inertia = value; + } + global(constraint) { + return constraint.inertiaGlobal; + } + }; + var PhysicsConstraintStrengthTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength); + } + setup(constraint) { + return constraint.data.strength; + } + get(constraint) { + return constraint.strength; + } + set(constraint, value) { + constraint.strength = value; + } + global(constraint) { + return constraint.strengthGlobal; + } + }; + var PhysicsConstraintDampingTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping); + } + setup(constraint) { + return constraint.data.damping; + } + get(constraint) { + return constraint.damping; + } + set(constraint, value) { + constraint.damping = value; + } + global(constraint) { + return constraint.dampingGlobal; + } + }; + var PhysicsConstraintMassTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass); + } + setup(constraint) { + return 1 / constraint.data.massInverse; + } + get(constraint) { + return 1 / constraint.massInverse; + } + set(constraint, value) { + constraint.massInverse = 1 / value; + } + global(constraint) { + return constraint.massGlobal; + } + }; + var PhysicsConstraintWindTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind); + } + setup(constraint) { + return constraint.data.wind; + } + get(constraint) { + return constraint.wind; + } + set(constraint, value) { + constraint.wind = value; + } + global(constraint) { + return constraint.windGlobal; + } + }; + var PhysicsConstraintGravityTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity); + } + setup(constraint) { + return constraint.data.gravity; + } + get(constraint) { + return constraint.gravity; + } + set(constraint, value) { + constraint.gravity = value; + } + global(constraint) { + return constraint.gravityGlobal; + } + }; + var PhysicsConstraintMixTimeline = class extends PhysicsConstraintTimeline { + constructor(frameCount, bezierCount, physicsConstraintIndex) { + super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix); + } + setup(constraint) { + return constraint.data.mix; + } + get(constraint) { + return constraint.mix; + } + set(constraint, value) { + constraint.mix = value; + } + global(constraint) { + return constraint.mixGlobal; + } + }; + var PhysicsConstraintResetTimeline = class _PhysicsConstraintResetTimeline extends Timeline { + static propertyIds = [Property.physicsConstraintReset.toString()]; + /** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset when this timeline is + * applied, or -1 if all physics constraints in the skeleton will be reset. */ + constraintIndex; + /** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */ + constructor(frameCount, physicsConstraintIndex) { + super(frameCount, _PhysicsConstraintResetTimeline.propertyIds); + this.constraintIndex = physicsConstraintIndex; + } + getFrameCount() { + return this.frames.length; + } + /** Sets the time for the specified frame. + * @param frame Between 0 and frameCount, inclusive. */ + setFrame(frame, time) { + this.frames[frame] = time; + } + /** Resets the physics constraint when frames > lastTime and <= time. */ + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let constraint; + if (this.constraintIndex != -1) { + constraint = skeleton.physicsConstraints[this.constraintIndex]; + if (!constraint.active) return; + } + const frames = this.frames; + if (lastTime > time) { + this.apply(skeleton, lastTime, Number.MAX_VALUE, [], alpha, blend, direction); + lastTime = -1; + } else if (lastTime >= frames[frames.length - 1]) + return; + if (time < frames[0]) return; + if (lastTime < frames[0] || time >= frames[Timeline.search1(frames, lastTime) + 1]) { + if (constraint != null) + constraint.reset(); + else { + for (const constraint2 of skeleton.physicsConstraints) { + if (constraint2.active) constraint2.reset(); + } + } + } + } + }; + var SequenceTimeline = class _SequenceTimeline extends Timeline { + static ENTRIES = 3; + static MODE = 1; + static DELAY = 2; + slotIndex; + attachment; + constructor(frameCount, slotIndex, attachment) { + super(frameCount, [ + Property.sequence + "|" + slotIndex + "|" + attachment.sequence.id + ]); + this.slotIndex = slotIndex; + this.attachment = attachment; + } + getFrameEntries() { + return _SequenceTimeline.ENTRIES; + } + getSlotIndex() { + return this.slotIndex; + } + getAttachment() { + return this.attachment; + } + /** Sets the time, mode, index, and frame time for the specified frame. + * @param frame Between 0 and frameCount, inclusive. + * @param time Seconds between frames. */ + setFrame(frame, time, mode, index, delay) { + let frames = this.frames; + frame *= _SequenceTimeline.ENTRIES; + frames[frame] = time; + frames[frame + _SequenceTimeline.MODE] = mode | index << 4; + frames[frame + _SequenceTimeline.DELAY] = delay; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) return; + let slotAttachment = slot.attachment; + let attachment = this.attachment; + if (slotAttachment != attachment) { + if (!(slotAttachment instanceof VertexAttachment) || slotAttachment.timelineAttachment != attachment) return; + } + if (direction == 1 /* mixOut */) { + if (blend == 0 /* setup */) slot.sequenceIndex = -1; + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) slot.sequenceIndex = -1; + return; + } + let i = Timeline.search(frames, time, _SequenceTimeline.ENTRIES); + let before = frames[i]; + let modeAndIndex = frames[i + _SequenceTimeline.MODE]; + let delay = frames[i + _SequenceTimeline.DELAY]; + if (!this.attachment.sequence) return; + let index = modeAndIndex >> 4, count = this.attachment.sequence.regions.length; + let mode = SequenceModeValues[modeAndIndex & 15]; + if (mode != 0 /* hold */) { + index += (time - before) / delay + 1e-5 | 0; + switch (mode) { + case 1 /* once */: + index = Math.min(count - 1, index); + break; + case 2 /* loop */: + index %= count; + break; + case 3 /* pingpong */: { + let n = (count << 1) - 2; + index = n == 0 ? 0 : index % n; + if (index >= count) index = n - index; + break; + } + case 4 /* onceReverse */: + index = Math.max(count - 1 - index, 0); + break; + case 5 /* loopReverse */: + index = count - 1 - index % count; + break; + case 6 /* pingpongReverse */: { + let n = (count << 1) - 2; + index = n == 0 ? 0 : (index + count - 1) % n; + if (index >= count) index = n - index; + } + } + } + slot.sequenceIndex = index; + } + }; + + // spine-core/src/AnimationState.ts + var AnimationState = class _AnimationState { + static _emptyAnimation = new Animation("", [], 0); + static emptyAnimation() { + return _AnimationState._emptyAnimation; + } + /** The AnimationStateData to look up mix durations. */ + data; + /** The list of tracks that currently have animations, which may contain null entries. */ + tracks = new Array(); + /** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower + * or faster. Defaults to 1. + * + * See TrackEntry {@link TrackEntry#timeScale} for affecting a single animation. */ + timeScale = 1; + unkeyedState = 0; + events = new Array(); + listeners = new Array(); + queue = new EventQueue(this); + propertyIDs = new StringSet(); + animationsChanged = false; + trackEntryPool = new Pool(() => new TrackEntry()); + constructor(data) { + this.data = data; + } + /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ + update(delta) { + delta *= this.timeScale; + let tracks = this.tracks; + for (let i = 0, n = tracks.length; i < n; i++) { + let current = tracks[i]; + if (!current) continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + let currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) continue; + currentDelta = -current.delay; + current.delay = 0; + } + let next = current.next; + if (next) { + let nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } else if (current.trackLast >= current.trackEnd && !current.mixingFrom) { + tracks[i] = null; + this.queue.end(current); + this.clearNext(current); + continue; + } + if (current.mixingFrom && this.updateMixingFrom(current, delta)) { + let from = current.mixingFrom; + current.mixingFrom = null; + if (from) from.mixingTo = null; + while (from) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + } + /** Returns true when all mixing from entries are complete. */ + updateMixingFrom(to, delta) { + let from = to.mixingFrom; + if (!from) return true; + let finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + if (to.nextTrackLast != -1 && to.mixTime >= to.mixDuration) { + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + } + /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the + * animation state can be applied to multiple skeletons to pose them identically. + * @returns True if any animations were applied. */ + apply(skeleton) { + if (!skeleton) throw new Error("skeleton cannot be null."); + if (this.animationsChanged) this._animationsChanged(); + let events = this.events; + let tracks = this.tracks; + let applied = false; + for (let i2 = 0, n2 = tracks.length; i2 < n2; i2++) { + let current = tracks[i2]; + if (!current || current.delay > 0) continue; + applied = true; + let blend = i2 == 0 ? 1 /* first */ : current.mixBlend; + let alpha = current.alpha; + if (current.mixingFrom) + alpha *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && !current.next) + alpha = 0; + let attachments = alpha >= current.alphaAttachmentThreshold; + let animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime; + let applyEvents = events; + if (current.reverse) { + applyTime = current.animation.duration - applyTime; + applyEvents = null; + } + let timelines = current.animation.timelines; + let timelineCount = timelines.length; + if (i2 == 0 && alpha == 1 || blend == 3 /* add */) { + if (i2 == 0) attachments = true; + for (let ii = 0; ii < timelineCount; ii++) { + Utils.webkit602BugfixHelper(alpha, blend); + var timeline = timelines[ii]; + if (timeline instanceof AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, attachments); + else + timeline.apply(skeleton, animationLast, applyTime, applyEvents, alpha, blend, 0 /* mixIn */); + } + } else { + let timelineMode = current.timelineMode; + let shortestRotation = current.shortestRotation; + let firstFrame = !shortestRotation && current.timelinesRotation.length != timelineCount << 1; + if (firstFrame) current.timelinesRotation.length = timelineCount << 1; + for (let ii = 0; ii < timelineCount; ii++) { + let timeline2 = timelines[ii]; + let timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : 0 /* setup */; + if (!shortestRotation && timeline2 instanceof RotateTimeline) { + this.applyRotateTimeline(timeline2, skeleton, applyTime, alpha, timelineBlend, current.timelinesRotation, ii << 1, firstFrame); + } else if (timeline2 instanceof AttachmentTimeline) { + this.applyAttachmentTimeline(timeline2, skeleton, applyTime, blend, attachments); + } else { + Utils.webkit602BugfixHelper(alpha, blend); + timeline2.apply(skeleton, animationLast, applyTime, applyEvents, alpha, timelineBlend, 0 /* mixIn */); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + var setupState = this.unkeyedState + SETUP; + var slots = skeleton.slots; + for (var i = 0, n = skeleton.slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.attachmentState == setupState) { + var attachmentName = slot.data.attachmentName; + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + } + } + this.unkeyedState += 2; + this.queue.drain(); + return applied; + } + applyMixingFrom(to, skeleton, blend) { + let from = to.mixingFrom; + if (from.mixingFrom) this.applyMixingFrom(from, skeleton, blend); + let mix = 0; + if (to.mixDuration == 0) { + mix = 1; + if (blend == 1 /* first */) blend = 0 /* setup */; + } else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) mix = 1; + if (blend != 1 /* first */) blend = from.mixBlend; + } + let attachments = mix < from.mixAttachmentThreshold, drawOrder = mix < from.mixDrawOrderThreshold; + let timelines = from.animation.timelines; + let timelineCount = timelines.length; + let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + let animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime; + let events = null; + if (from.reverse) + applyTime = from.animation.duration - applyTime; + else if (mix < from.eventThreshold) + events = this.events; + if (blend == 3 /* add */) { + for (let i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, 1 /* mixOut */); + } else { + let timelineMode = from.timelineMode; + let timelineHoldMix = from.timelineHoldMix; + let shortestRotation = from.shortestRotation; + let firstFrame = !shortestRotation && from.timelinesRotation.length != timelineCount << 1; + if (firstFrame) from.timelinesRotation.length = timelineCount << 1; + from.totalAlpha = 0; + for (let i = 0; i < timelineCount; i++) { + let timeline = timelines[i]; + let direction = 1 /* mixOut */; + let timelineBlend; + let alpha = 0; + switch (timelineMode[i]) { + case SUBSEQUENT: + if (!drawOrder && timeline instanceof DrawOrderTimeline) continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case FIRST: + timelineBlend = 0 /* setup */; + alpha = alphaMix; + break; + case HOLD_SUBSEQUENT: + timelineBlend = blend; + alpha = alphaHold; + break; + case HOLD_FIRST: + timelineBlend = 0 /* setup */; + alpha = alphaHold; + break; + default: + timelineBlend = 0 /* setup */; + let holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (!shortestRotation && timeline instanceof RotateTimeline) + this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, from.timelinesRotation, i << 1, firstFrame); + else if (timeline instanceof AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments && alpha >= from.alphaAttachmentThreshold); + else { + Utils.webkit602BugfixHelper(alpha, blend); + if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == 0 /* setup */) + direction = 0 /* mixIn */; + timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + } + applyAttachmentTimeline(timeline, skeleton, time, blend, attachments) { + var slot = skeleton.slots[timeline.slotIndex]; + if (!slot.bone.active) return; + if (time < timeline.frames[0]) { + if (blend == 0 /* setup */ || blend == 1 /* first */) + this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); + } else + this.setAttachment(skeleton, slot, timeline.attachmentNames[Timeline.search1(timeline.frames, time)], attachments); + if (slot.attachmentState <= this.unkeyedState) slot.attachmentState = this.unkeyedState + SETUP; + } + setAttachment(skeleton, slot, attachmentName, attachments) { + slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + if (attachments) slot.attachmentState = this.unkeyedState + CURRENT; + } + applyRotateTimeline(timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, 0 /* mixIn */); + return; + } + let bone = skeleton.bones[timeline.boneIndex]; + if (!bone.active) return; + let frames = timeline.frames; + let r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case 0 /* setup */: + bone.rotation = bone.data.rotation; + default: + return; + case 1 /* first */: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } else { + r1 = blend == 0 /* setup */ ? bone.data.rotation : bone.rotation; + r2 = bone.data.rotation + timeline.getCurveValue(time); + } + let total = 0, diff = r2 - r1; + diff -= Math.ceil(diff / 360 - 0.5) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } else { + let lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } else { + lastTotal = timelinesRotation[i]; + lastDiff = timelinesRotation[i + 1]; + } + let loops = lastTotal - lastTotal % 360; + total = diff + loops; + let current = diff >= 0, dir = lastTotal >= 0; + if (Math.abs(lastDiff) <= 90 && MathUtils.signum(lastDiff) != MathUtils.signum(diff)) { + if (Math.abs(lastTotal - loops) > 180) { + total += 360 * MathUtils.signum(lastTotal); + dir = current; + } else if (loops != 0) + total -= 360 * MathUtils.signum(lastTotal); + else + dir = current; + } + if (dir != current) total += 360 * MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + bone.rotation = r1 + total * alpha; + } + queueEvents(entry, animationTime) { + let animationStart = entry.animationStart, animationEnd = entry.animationEnd; + let duration = animationEnd - animationStart; + let trackLastWrapped = entry.trackLast % duration; + let events = this.events; + let i = 0, n = events.length; + for (; i < n; i++) { + let event = events[i]; + if (event.time < trackLastWrapped) break; + if (event.time > animationEnd) continue; + this.queue.event(entry, event); + } + let complete = false; + if (entry.loop) { + if (duration == 0) + complete = true; + else { + const cycles = Math.floor(entry.trackTime / duration); + complete = cycles > 0 && cycles > Math.floor(entry.trackLast / duration); + } + } else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) this.queue.complete(entry); + for (; i < n; i++) { + let event = events[i]; + if (event.time < animationStart) continue; + this.queue.event(entry, event); + } + } + /** Removes all animations from all tracks, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + clearTracks() { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + /** Removes all animations from the track, leaving skeletons in their current pose. + * + * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, + * rather than leaving them in their current pose. */ + clearTrack(trackIndex) { + if (trackIndex >= this.tracks.length) return; + let current = this.tracks[trackIndex]; + if (!current) return; + this.queue.end(current); + this.clearNext(current); + let entry = current; + while (true) { + let from = entry.mixingFrom; + if (!from) break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + } + setCurrent(index, current, interrupt) { + let from = this.expandToIndex(index); + this.tracks[index] = current; + current.previous = null; + if (from) { + if (interrupt) this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + if (from.mixingFrom && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; + } + this.queue.start(current); + } + /** Sets an animation by name. + * + * See {@link #setAnimationWith()}. */ + setAnimation(trackIndex, animationName, loop = false) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + } + /** Sets the current animation for a track, discarding any queued animations. If the formerly current track entry was never + * applied to a skeleton, it is replaced (not mixed from). + * @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + setAnimationWith(trackIndex, animation, loop = false) { + if (!animation) throw new Error("animation cannot be null."); + let interrupt = true; + let current = this.expandToIndex(trackIndex); + if (current) { + if (current.nextTrackLast == -1) { + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.clearNext(current); + current = current.mixingFrom; + interrupt = false; + } else + this.clearNext(current); + } + let entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + } + /** Queues an animation by name. + * + * See {@link #addAnimationWith()}. */ + addAnimation(trackIndex, animationName, loop = false, delay = 0) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + } + /** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is + * equivalent to calling {@link #setAnimationWith()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration (from the {@link AnimationStateData}) plus the specified `delay` (ie the mix + * ends at (`delay` = 0) or before (`delay` < 0) the previous track entry duration). If the + * previous entry is looping, its next loop completion is used instead of its duration. + * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + addAnimationWith(trackIndex, animation, loop = false, delay = 0) { + if (!animation) throw new Error("animation cannot be null."); + let last = this.expandToIndex(trackIndex); + if (last) { + while (last.next) + last = last.next; + } + let entry = this.trackEntry(trackIndex, animation, loop, last); + if (!last) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + if (delay < 0) delay = 0; + } else { + last.next = entry; + entry.previous = last; + if (delay <= 0) delay = Math.max(delay + last.getTrackComplete() - entry.mixDuration, 0); + } + entry.delay = delay; + return entry; + } + /** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's + * {@link TrackEntry#mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out. + * + * Mixing out is done by setting an empty animation with a mix duration using either {@link #setEmptyAnimation()}, + * {@link #setEmptyAnimations()}, or {@link #addEmptyAnimation()}. Mixing to an empty animation causes + * the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation + * transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of + * 0 still mixes out over one frame. + * + * Mixing in is done by first setting an empty animation, then adding an animation using + * {@link #addAnimation()} and on the returned track entry, set the + * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and + * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the + * setup pose value if no lower tracks key the property to the value keyed in the new animation. */ + setEmptyAnimation(trackIndex, mixDuration = 0) { + let entry = this.setAnimationWith(trackIndex, _AnimationState.emptyAnimation(), false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + /** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's + * {@link TrackEntry#mixDuration}. If the track is empty, it is equivalent to calling + * {@link #setEmptyAnimation()}. + * + * See {@link #setEmptyAnimation()}. + * @param delay If > 0, sets {@link TrackEntry#delay}. If <= 0, the delay set is the duration of the previous track entry + * minus any mix duration plus the specified `delay` (ie the mix ends at (`delay` = 0) or + * before (`delay` < 0) the previous track entry duration). If the previous entry is looping, its next + * loop completion is used instead of its duration. + * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept + * after the {@link AnimationStateListener#dispose()} event occurs. */ + addEmptyAnimation(trackIndex, mixDuration = 0, delay = 0) { + let entry = this.addAnimationWith(trackIndex, _AnimationState.emptyAnimation(), false, delay); + if (delay <= 0) entry.delay = Math.max(entry.delay + entry.mixDuration - mixDuration, 0); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix + * duration. */ + setEmptyAnimations(mixDuration = 0) { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) { + let current = this.tracks[i]; + if (current) this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + expandToIndex(index) { + if (index < this.tracks.length) return this.tracks[index]; + Utils.ensureArrayCapacity(this.tracks, index + 1, null); + this.tracks.length = index + 1; + return null; + } + /** @param last May be null. */ + trackEntry(trackIndex, animation, loop, last) { + let entry = this.trackEntryPool.obtain(); + entry.reset(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.reverse = false; + entry.shortestRotation = false; + entry.eventThreshold = 0; + entry.alphaAttachmentThreshold = 0; + entry.mixAttachmentThreshold = 0; + entry.mixDrawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.mixTime = 0; + entry.mixDuration = !last ? 0 : this.data.getMix(last.animation, animation); + entry.interruptAlpha = 1; + entry.totalAlpha = 0; + entry.mixBlend = 2 /* replace */; + return entry; + } + /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */ + clearNext(entry) { + let next = entry.next; + while (next) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + } + _animationsChanged() { + this.animationsChanged = false; + this.propertyIDs.clear(); + let tracks = this.tracks; + for (let i = 0, n = tracks.length; i < n; i++) { + let entry = tracks[i]; + if (!entry) continue; + while (entry.mixingFrom) + entry = entry.mixingFrom; + do { + if (!entry.mixingTo || entry.mixBlend != 3 /* add */) this.computeHold(entry); + entry = entry.mixingTo; + } while (entry); + } + } + computeHold(entry) { + let to = entry.mixingTo; + let timelines = entry.animation.timelines; + let timelinesCount = entry.animation.timelines.length; + let timelineMode = entry.timelineMode; + timelineMode.length = timelinesCount; + let timelineHoldMix = entry.timelineHoldMix; + timelineHoldMix.length = 0; + let propertyIDs = this.propertyIDs; + if (to && to.holdPrevious) { + for (let i = 0; i < timelinesCount; i++) + timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? HOLD_FIRST : HOLD_SUBSEQUENT; + return; + } + outer: + for (let i = 0; i < timelinesCount; i++) { + let timeline = timelines[i]; + let ids = timeline.getPropertyIds(); + if (!propertyIDs.addAll(ids)) + timelineMode[i] = SUBSEQUENT; + else if (!to || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) { + timelineMode[i] = FIRST; + } else { + for (let next = to.mixingTo; next; next = next.mixingTo) { + if (next.animation.hasTimeline(ids)) continue; + if (entry.mixDuration > 0) { + timelineMode[i] = HOLD_MIX; + timelineHoldMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = HOLD_FIRST; + } + } + } + /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ + getCurrent(trackIndex) { + if (trackIndex >= this.tracks.length) return null; + return this.tracks[trackIndex]; + } + /** Adds a listener to receive events for all track entries. */ + addListener(listener) { + if (!listener) throw new Error("listener cannot be null."); + this.listeners.push(listener); + } + /** Removes the listener added with {@link #addListener()}. */ + removeListener(listener) { + let index = this.listeners.indexOf(listener); + if (index >= 0) this.listeners.splice(index, 1); + } + /** Removes all listeners added with {@link #addListener()}. */ + clearListeners() { + this.listeners.length = 0; + } + /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an + * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery + * are not wanted because new animations are being set. */ + clearListenerNotifications() { + this.queue.clear(); + } + }; + var TrackEntry = class { + /** The animation to apply for this track entry. */ + animation = null; + previous = null; + /** The animation queued to start after this animation, or null. `next` makes up a linked list. */ + next = null; + /** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no + * mixing is currently occuring. When mixing from multiple animations, `mixingFrom` makes up a linked list. */ + mixingFrom = null; + /** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is + * currently occuring. When mixing to multiple animations, `mixingTo` makes up a linked list. */ + mixingTo = null; + /** The listener for events generated by this track entry, or null. + * + * A track entry returned from {@link AnimationState#setAnimation()} is already the current animation + * for the track, so the track entry listener {@link AnimationStateListener#start()} will not be called. */ + listener = null; + /** The index of the track where this track entry is either current or queued. + * + * See {@link AnimationState#getCurrent()}. */ + trackIndex = 0; + /** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + * duration. */ + loop = false; + /** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead + * of being mixed out. + * + * When mixing between animations that key the same property, if a lower track also keys that property then the value will + * briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0% + * while the second animation mixes from 0% to 100%. Setting `holdPrevious` to true applies the first animation + * at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which + * keys the property, only when a higher track also keys the property. + * + * Snapping will occur if `holdPrevious` is true and this animation does not key all the same properties as the + * previous animation. */ + holdPrevious = false; + reverse = false; + shortestRotation = false; + /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the + * `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event + * timelines are not applied while this animation is being mixed out. */ + eventThreshold = 0; + /** When the mix percentage ({@link #mixtime} / {@link #mixDuration}) is less than the + * `attachmentThreshold`, attachment timelines are applied while this animation is being mixed out. Defaults to + * 0, so attachment timelines are not applied while this animation is being mixed out. */ + mixAttachmentThreshold = 0; + /** When {@link #getAlpha()} is greater than alphaAttachmentThreshold, attachment timelines are applied. + * Defaults to 0, so attachment timelines are always applied. */ + alphaAttachmentThreshold = 0; + /** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the + * mixDrawOrderThreshold, draw order timelines are applied while this animation is being mixed out. Defaults to + * 0, so draw order timelines are not applied while this animation is being mixed out. */ + mixDrawOrderThreshold = 0; + /** Seconds when this animation starts, both initially and after looping. Defaults to 0. + * + * When changing the `animationStart` time, it often makes sense to set {@link #animationLast} to the same + * value to prevent timeline keys before the start time from triggering. */ + animationStart = 0; + /** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will + * loop back to {@link #animationStart} at this time. Defaults to the animation {@link Animation#duration}. */ + animationEnd = 0; + /** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this + * animation is applied, event timelines will fire all events between the `animationLast` time (exclusive) and + * `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation + * is applied. */ + animationLast = 0; + nextAnimationLast = 0; + /** Seconds to postpone playing the animation. When this track entry is the current track entry, `delay` + * postpones incrementing the {@link #trackTime}. When this track entry is queued, `delay` is the time from + * the start of the previous animation to when this track entry will become the current track entry (ie when the previous + * track entry {@link TrackEntry#trackTime} >= this track entry's `delay`). + * + * {@link #timeScale} affects the delay. */ + delay = 0; + /** Current time in seconds this track entry has been the current track entry. The track time determines + * {@link #animationTime}. The track time can be set to start the animation at a time other than 0, without affecting + * looping. */ + trackTime = 0; + trackLast = 0; + nextTrackLast = 0; + /** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float + * value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time + * is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the + * properties keyed by the animation are set to the setup pose and the track is cleared. + * + * It may be desired to use {@link AnimationState#addEmptyAnimation()} rather than have the animation + * abruptly cease being applied. */ + trackEnd = 0; + /** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or + * faster. Defaults to 1. + * + * {@link #mixTime} is not affected by track entry time scale, so {@link #mixDuration} may need to be adjusted to + * match the animation speed. + * + * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the + * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If + * the time scale is not 1, the delay may need to be adjusted. + * + * See AnimationState {@link AnimationState#timeScale} for affecting all animations. */ + timeScale = 0; + /** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults + * to 1, which overwrites the skeleton's current pose with this animation. + * + * Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to + * use alpha on track 0 if the skeleton pose is from the last frame render. */ + alpha = 0; + /** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be + * slightly more than `mixDuration` when the mix is complete. */ + mixTime = 0; + /** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData + * {@link AnimationStateData#getMix()} based on the animation before this animation (if any). + * + * A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the + * properties it was animating. + * + * The `mixDuration` can be set manually rather than use the value from + * {@link AnimationStateData#getMix()}. In that case, the `mixDuration` can be set for a new + * track entry only before {@link AnimationState#update(float)} is first called. + * + * When using {@link AnimationState#addAnimation()} with a `delay` <= 0, note the + * {@link #delay} is set using the mix duration from the {@link AnimationStateData}, not a mix duration set + * afterward. */ + _mixDuration = 0; + interruptAlpha = 0; + totalAlpha = 0; + get mixDuration() { + return this._mixDuration; + } + set mixDuration(mixDuration) { + this._mixDuration = mixDuration; + } + setMixDurationWithDelay(mixDuration, delay) { + this._mixDuration = mixDuration; + if (delay <= 0) { + if (this.previous != null) + delay = Math.max(delay + this.previous.getTrackComplete() - mixDuration, 0); + else + delay = 0; + } + this.delay = delay; + } + /** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}, which + * replaces the values from the lower tracks with the animation values. {@link MixBlend#add} adds the animation values to + * the values from the lower tracks. + * + * The `mixBlend` can be set for a new track entry only before {@link AnimationState#apply()} is first + * called. */ + mixBlend = 2 /* replace */; + timelineMode = new Array(); + timelineHoldMix = new Array(); + timelinesRotation = new Array(); + reset() { + this.next = null; + this.previous = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + } + /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} + * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the + * `animationStart` time. */ + getAnimationTime() { + if (this.loop) { + let duration = this.animationEnd - this.animationStart; + if (duration == 0) return this.animationStart; + return this.trackTime % duration + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + } + setAnimationLast(animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + } + /** Returns true if at least one loop has been completed. + * + * See {@link AnimationStateListener#complete()}. */ + isComplete() { + return this.trackTime >= this.animationEnd - this.animationStart; + } + /** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the + * long way around when using {@link #alpha} and starting animations on other tracks. + * + * Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions: + * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long + * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the + * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ + resetRotationDirections() { + this.timelinesRotation.length = 0; + } + getTrackComplete() { + let duration = this.animationEnd - this.animationStart; + if (duration != 0) { + if (this.loop) return duration * (1 + (this.trackTime / duration | 0)); + if (this.trackTime < duration) return duration; + } + return this.trackTime; + } + /** Returns true if this track entry has been applied at least once. + *

+ * See {@link AnimationState#apply(Skeleton)}. */ + wasApplied() { + return this.nextTrackLast != -1; + } + /** Returns true if there is a {@link #getNext()} track entry and it will become the current track entry during the next + * {@link AnimationState#update(float)}. */ + isNextReady() { + return this.next != null && this.nextTrackLast - this.next.delay >= 0; + } + }; + var EventQueue = class { + objects = []; + drainDisabled = false; + animState; + constructor(animState) { + this.animState = animState; + } + start(entry) { + this.objects.push(0 /* start */); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + interrupt(entry) { + this.objects.push(1 /* interrupt */); + this.objects.push(entry); + } + end(entry) { + this.objects.push(2 /* end */); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + dispose(entry) { + this.objects.push(3 /* dispose */); + this.objects.push(entry); + } + complete(entry) { + this.objects.push(4 /* complete */); + this.objects.push(entry); + } + event(entry, event) { + this.objects.push(5 /* event */); + this.objects.push(entry); + this.objects.push(event); + } + drain() { + if (this.drainDisabled) return; + this.drainDisabled = true; + let objects = this.objects; + let listeners = this.animState.listeners; + for (let i = 0; i < objects.length; i += 2) { + let type = objects[i]; + let entry = objects[i + 1]; + switch (type) { + case 0 /* start */: + if (entry.listener && entry.listener.start) entry.listener.start(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.start) listener.start(entry); + } + break; + case 1 /* interrupt */: + if (entry.listener && entry.listener.interrupt) entry.listener.interrupt(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.interrupt) listener.interrupt(entry); + } + break; + case 2 /* end */: + if (entry.listener && entry.listener.end) entry.listener.end(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.end) listener.end(entry); + } + // Fall through. + case 3 /* dispose */: + if (entry.listener && entry.listener.dispose) entry.listener.dispose(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.dispose) listener.dispose(entry); + } + this.animState.trackEntryPool.free(entry); + break; + case 4 /* complete */: + if (entry.listener && entry.listener.complete) entry.listener.complete(entry); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.complete) listener.complete(entry); + } + break; + case 5 /* event */: + let event = objects[i++ + 2]; + if (entry.listener && entry.listener.event) entry.listener.event(entry, event); + for (let ii = 0; ii < listeners.length; ii++) { + let listener = listeners[ii]; + if (listener.event) listener.event(entry, event); + } + break; + } + } + this.clear(); + this.drainDisabled = false; + } + clear() { + this.objects.length = 0; + } + }; + var EventType = /* @__PURE__ */ ((EventType2) => { + EventType2[EventType2["start"] = 0] = "start"; + EventType2[EventType2["interrupt"] = 1] = "interrupt"; + EventType2[EventType2["end"] = 2] = "end"; + EventType2[EventType2["dispose"] = 3] = "dispose"; + EventType2[EventType2["complete"] = 4] = "complete"; + EventType2[EventType2["event"] = 5] = "event"; + return EventType2; + })(EventType || {}); + var AnimationStateAdapter = class { + start(entry) { + } + interrupt(entry) { + } + end(entry) { + } + dispose(entry) { + } + complete(entry) { + } + event(entry, event) { + } + }; + var SUBSEQUENT = 0; + var FIRST = 1; + var HOLD_SUBSEQUENT = 2; + var HOLD_FIRST = 3; + var HOLD_MIX = 4; + var SETUP = 1; + var CURRENT = 2; + + // spine-core/src/AnimationStateData.ts + var AnimationStateData = class { + /** The SkeletonData to look up animations when they are specified by name. */ + skeletonData; + animationToMixTime = {}; + /** The mix duration to use when no mix duration has been defined between two animations. */ + defaultMix = 0; + constructor(skeletonData) { + if (!skeletonData) throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + /** Sets a mix duration by animation name. + * + * See {@link #setMixWith()}. */ + setMix(fromName, toName, duration) { + let from = this.skeletonData.findAnimation(fromName); + if (!from) throw new Error("Animation not found: " + fromName); + let to = this.skeletonData.findAnimation(toName); + if (!to) throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + } + /** Sets the mix duration when changing from the specified animation to the other. + * + * See {@link TrackEntry#mixDuration}. */ + setMixWith(from, to, duration) { + if (!from) throw new Error("from cannot be null."); + if (!to) throw new Error("to cannot be null."); + let key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + } + /** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if + * no mix duration has been set. */ + getMix(from, to) { + let key = from.name + "." + to.name; + let value = this.animationToMixTime[key]; + return value === void 0 ? this.defaultMix : value; + } + }; + + // spine-core/src/attachments/BoundingBoxAttachment.ts + var BoundingBoxAttachment = class _BoundingBoxAttachment extends VertexAttachment { + color = new Color(1, 1, 1, 1); + constructor(name) { + super(name); + } + copy() { + let copy = new _BoundingBoxAttachment(this.name); + this.copyTo(copy); + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/attachments/ClippingAttachment.ts + var ClippingAttachment = class _ClippingAttachment extends VertexAttachment { + /** Clipping is performed between the clipping polygon's slot and the end slot. Returns null if clipping is done until the end of + * the skeleton's rendering. */ + endSlot = null; + // Nonessential. + /** The color of the clipping polygon as it was in Spine. Available only when nonessential data was exported. Clipping polygons + * are not usually rendered at runtime. */ + color = new Color(0.2275, 0.2275, 0.8078, 1); + // ce3a3aff + constructor(name) { + super(name); + } + copy() { + let copy = new _ClippingAttachment(this.name); + this.copyTo(copy); + copy.endSlot = this.endSlot; + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/Texture.ts + var Texture = class { + _image; + constructor(image) { + this._image = image; + } + getImage() { + return this._image; + } + }; + var TextureFilter = /* @__PURE__ */ ((TextureFilter3) => { + TextureFilter3[TextureFilter3["Nearest"] = 9728] = "Nearest"; + TextureFilter3[TextureFilter3["Linear"] = 9729] = "Linear"; + TextureFilter3[TextureFilter3["MipMap"] = 9987] = "MipMap"; + TextureFilter3[TextureFilter3["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest"; + TextureFilter3[TextureFilter3["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; + TextureFilter3[TextureFilter3["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; + TextureFilter3[TextureFilter3["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; + return TextureFilter3; + })(TextureFilter || {}); + var TextureWrap = /* @__PURE__ */ ((TextureWrap3) => { + TextureWrap3[TextureWrap3["MirroredRepeat"] = 33648] = "MirroredRepeat"; + TextureWrap3[TextureWrap3["ClampToEdge"] = 33071] = "ClampToEdge"; + TextureWrap3[TextureWrap3["Repeat"] = 10497] = "Repeat"; + return TextureWrap3; + })(TextureWrap || {}); + var TextureRegion = class { + texture; + u = 0; + v = 0; + u2 = 0; + v2 = 0; + width = 0; + height = 0; + degrees = 0; + offsetX = 0; + offsetY = 0; + originalWidth = 0; + originalHeight = 0; + }; + var FakeTexture = class extends Texture { + setFilters(minFilter, magFilter) { + } + setWraps(uWrap, vWrap) { + } + dispose() { + } + }; + + // spine-core/src/TextureAtlas.ts + var TextureAtlas = class { + pages = new Array(); + regions = new Array(); + constructor(atlasText) { + let reader = new TextureAtlasReader(atlasText); + let entry = new Array(4); + let pageFields = {}; + pageFields["size"] = (page2) => { + page2.width = parseInt(entry[1]); + page2.height = parseInt(entry[2]); + }; + pageFields["format"] = () => { + }; + pageFields["filter"] = (page2) => { + page2.minFilter = Utils.enumValue(TextureFilter, entry[1]); + page2.magFilter = Utils.enumValue(TextureFilter, entry[2]); + }; + pageFields["repeat"] = (page2) => { + if (entry[1].indexOf("x") != -1) page2.uWrap = 10497 /* Repeat */; + if (entry[1].indexOf("y") != -1) page2.vWrap = 10497 /* Repeat */; + }; + pageFields["pma"] = (page2) => { + page2.pma = entry[1] == "true"; + }; + var regionFields = {}; + regionFields["xy"] = (region) => { + region.x = parseInt(entry[1]); + region.y = parseInt(entry[2]); + }; + regionFields["size"] = (region) => { + region.width = parseInt(entry[1]); + region.height = parseInt(entry[2]); + }; + regionFields["bounds"] = (region) => { + region.x = parseInt(entry[1]); + region.y = parseInt(entry[2]); + region.width = parseInt(entry[3]); + region.height = parseInt(entry[4]); + }; + regionFields["offset"] = (region) => { + region.offsetX = parseInt(entry[1]); + region.offsetY = parseInt(entry[2]); + }; + regionFields["orig"] = (region) => { + region.originalWidth = parseInt(entry[1]); + region.originalHeight = parseInt(entry[2]); + }; + regionFields["offsets"] = (region) => { + region.offsetX = parseInt(entry[1]); + region.offsetY = parseInt(entry[2]); + region.originalWidth = parseInt(entry[3]); + region.originalHeight = parseInt(entry[4]); + }; + regionFields["rotate"] = (region) => { + let value = entry[1]; + if (value == "true") + region.degrees = 90; + else if (value != "false") + region.degrees = parseInt(value); + }; + regionFields["index"] = (region) => { + region.index = parseInt(entry[1]); + }; + let line = reader.readLine(); + while (line && line.trim().length == 0) + line = reader.readLine(); + while (true) { + if (!line || line.trim().length == 0) break; + if (reader.readEntry(entry, line) == 0) break; + line = reader.readLine(); + } + let page = null; + let names = null; + let values = null; + while (true) { + if (line === null) break; + if (line.trim().length == 0) { + page = null; + line = reader.readLine(); + } else if (!page) { + page = new TextureAtlasPage(line.trim()); + while (true) { + if (reader.readEntry(entry, line = reader.readLine()) == 0) break; + let field = pageFields[entry[0]]; + if (field) field(page); + } + this.pages.push(page); + } else { + let region = new TextureAtlasRegion(page, line); + while (true) { + let count = reader.readEntry(entry, line = reader.readLine()); + if (count == 0) break; + let field = regionFields[entry[0]]; + if (field) + field(region); + else { + if (!names) names = []; + if (!values) values = []; + names.push(entry[0]); + let entryValues = []; + for (let i = 0; i < count; i++) + entryValues.push(parseInt(entry[i + 1])); + values.push(entryValues); + } + } + if (region.originalWidth == 0 && region.originalHeight == 0) { + region.originalWidth = region.width; + region.originalHeight = region.height; + } + if (names && names.length > 0 && values && values.length > 0) { + region.names = names; + region.values = values; + names = null; + values = null; + } + region.u = region.x / page.width; + region.v = region.y / page.height; + if (region.degrees == 90) { + region.u2 = (region.x + region.height) / page.width; + region.v2 = (region.y + region.width) / page.height; + } else { + region.u2 = (region.x + region.width) / page.width; + region.v2 = (region.y + region.height) / page.height; + } + this.regions.push(region); + } + } + } + findRegion(name) { + for (let i = 0; i < this.regions.length; i++) { + if (this.regions[i].name == name) { + return this.regions[i]; + } + } + return null; + } + setTextures(assetManager, pathPrefix = "") { + for (let page of this.pages) + page.setTexture(assetManager.get(pathPrefix + page.name)); + } + dispose() { + for (let i = 0; i < this.pages.length; i++) { + this.pages[i].texture?.dispose(); + } + } + }; + var TextureAtlasReader = class { + lines; + index = 0; + constructor(text) { + this.lines = text.split(/\r\n|\r|\n/); + } + readLine() { + if (this.index >= this.lines.length) + return null; + return this.lines[this.index++]; + } + readEntry(entry, line) { + if (!line) return 0; + line = line.trim(); + if (line.length == 0) return 0; + let colon = line.indexOf(":"); + if (colon == -1) return 0; + entry[0] = line.substr(0, colon).trim(); + for (let i = 1, lastMatch = colon + 1; ; i++) { + let comma = line.indexOf(",", lastMatch); + if (comma == -1) { + entry[i] = line.substr(lastMatch).trim(); + return i; + } + entry[i] = line.substr(lastMatch, comma - lastMatch).trim(); + lastMatch = comma + 1; + if (i == 4) return 4; + } + } + }; + var TextureAtlasPage = class { + name; + minFilter = 9728 /* Nearest */; + magFilter = 9728 /* Nearest */; + uWrap = 33071 /* ClampToEdge */; + vWrap = 33071 /* ClampToEdge */; + texture = null; + width = 0; + height = 0; + pma = false; + regions = new Array(); + constructor(name) { + this.name = name; + } + setTexture(texture) { + this.texture = texture; + texture.setFilters(this.minFilter, this.magFilter); + texture.setWraps(this.uWrap, this.vWrap); + for (let region of this.regions) + region.texture = texture; + } + }; + var TextureAtlasRegion = class extends TextureRegion { + page; + name; + x = 0; + y = 0; + offsetX = 0; + offsetY = 0; + originalWidth = 0; + originalHeight = 0; + index = 0; + degrees = 0; + names = null; + values = null; + constructor(page, name) { + super(); + this.page = page; + this.name = name; + page.regions.push(this); + } + }; + + // spine-core/src/attachments/MeshAttachment.ts + var MeshAttachment = class _MeshAttachment extends VertexAttachment { + region = null; + /** The name of the texture region for this attachment. */ + path; + /** The UV pair for each vertex, normalized within the texture region. */ + regionUVs = []; + /** The UV pair for each vertex, normalized within the entire texture. + * + * See {@link #updateUVs}. */ + uvs = []; + /** Triplets of vertex indices which describe the mesh's triangulation. */ + triangles = []; + /** The color to tint the mesh. */ + color = new Color(1, 1, 1, 1); + /** The width of the mesh's image. Available only when nonessential data was exported. */ + width = 0; + /** The height of the mesh's image. Available only when nonessential data was exported. */ + height = 0; + /** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */ + hullLength = 0; + /** Vertex index pairs describing edges for controling triangulation. Mesh triangles will never cross edges. Only available if + * nonessential data was exported. Triangulation is not performed at runtime. */ + edges = []; + parentMesh = null; + sequence = null; + tempColor = new Color(0, 0, 0, 0); + constructor(name, path) { + super(name); + this.path = path; + } + /** Calculates {@link #uvs} using the {@link #regionUVs} and region. Must be called if the region, the region's properties, or + * the {@link #regionUVs} are changed. */ + updateRegion() { + if (!this.region) throw new Error("Region not set."); + let regionUVs = this.regionUVs; + if (!this.uvs || this.uvs.length != regionUVs.length) this.uvs = Utils.newFloatArray(regionUVs.length); + let uvs = this.uvs; + let n = this.uvs.length; + let u = this.region.u, v = this.region.v, width = 0, height = 0; + if (this.region instanceof TextureAtlasRegion) { + let region = this.region, page = region.page; + let textureWidth = page.width, textureHeight = page.height; + switch (region.degrees) { + case 90: + u -= (region.originalHeight - region.offsetY - region.height) / textureWidth; + v -= (region.originalWidth - region.offsetX - region.width) / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + (1 - regionUVs[i]) * height; + } + return; + case 180: + u -= (region.originalWidth - region.offsetX - region.width) / textureWidth; + v -= region.offsetY / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i]) * width; + uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; + } + return; + case 270: + u -= region.offsetY / textureWidth; + v -= region.offsetX / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i + 1]) * width; + uvs[i + 1] = v + regionUVs[i] * height; + } + return; + } + u -= region.offsetX / textureWidth; + v -= (region.originalHeight - region.offsetY - region.height) / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + } else if (!this.region) { + u = v = 0; + width = height = 1; + } else { + width = this.region.u2 - u; + height = this.region.v2 - v; + } + for (let i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; + } + } + /** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices}, + * {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the + * parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */ + getParentMesh() { + return this.parentMesh; + } + /** @param parentMesh May be null. */ + setParentMesh(parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + } + copy() { + if (this.parentMesh) return this.newLinkedMesh(); + let copy = new _MeshAttachment(this.name, this.path); + copy.region = this.region; + copy.color.setFromColor(this.color); + this.copyTo(copy); + copy.regionUVs = new Array(this.regionUVs.length); + Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); + copy.uvs = this.uvs instanceof Float32Array ? Utils.newFloatArray(this.uvs.length) : new Array(this.uvs.length); + Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, this.uvs.length); + copy.triangles = new Array(this.triangles.length); + Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); + copy.hullLength = this.hullLength; + copy.sequence = this.sequence != null ? this.sequence.copy() : null; + if (this.edges) { + copy.edges = new Array(this.edges.length); + Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); + } + copy.width = this.width; + copy.height = this.height; + return copy; + } + computeWorldVertices(slot, start, count, worldVertices2, offset, stride) { + if (this.sequence != null) this.sequence.apply(slot, this); + super.computeWorldVertices(slot, start, count, worldVertices2, offset, stride); + } + /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/ + newLinkedMesh() { + let copy = new _MeshAttachment(this.name, this.path); + copy.region = this.region; + copy.color.setFromColor(this.color); + copy.timelineAttachment = this.timelineAttachment; + copy.setParentMesh(this.parentMesh ? this.parentMesh : this); + if (copy.region != null) copy.updateRegion(); + return copy; + } + }; + + // spine-core/src/attachments/PathAttachment.ts + var PathAttachment = class _PathAttachment extends VertexAttachment { + /** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */ + lengths = []; + /** If true, the start and end knots are connected. */ + closed = false; + /** If true, additional calculations are performed to make calculating positions along the path more accurate. If false, fewer + * calculations are performed but calculating positions along the path is less accurate. */ + constantSpeed = false; + /** The color of the path as it was in Spine. Available only when nonessential data was exported. Paths are not usually + * rendered at runtime. */ + color = new Color(1, 1, 1, 1); + constructor(name) { + super(name); + } + copy() { + let copy = new _PathAttachment(this.name); + this.copyTo(copy); + copy.lengths = new Array(this.lengths.length); + Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); + copy.closed = closed; + copy.constantSpeed = this.constantSpeed; + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/attachments/PointAttachment.ts + var PointAttachment = class _PointAttachment extends VertexAttachment { + x = 0; + y = 0; + rotation = 0; + /** The color of the point attachment as it was in Spine. Available only when nonessential data was exported. Point attachments + * are not usually rendered at runtime. */ + color = new Color(0.38, 0.94, 0, 1); + constructor(name) { + super(name); + } + computeWorldPosition(bone, point) { + point.x = this.x * bone.a + this.y * bone.b + bone.worldX; + point.y = this.x * bone.c + this.y * bone.d + bone.worldY; + return point; + } + computeWorldRotation(bone) { + const r = this.rotation * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r); + const x = cos * bone.a + sin * bone.b; + const y = cos * bone.c + sin * bone.d; + return MathUtils.atan2Deg(y, x); + } + copy() { + let copy = new _PointAttachment(this.name); + copy.x = this.x; + copy.y = this.y; + copy.rotation = this.rotation; + copy.color.setFromColor(this.color); + return copy; + } + }; + + // spine-core/src/attachments/RegionAttachment.ts + var RegionAttachment = class _RegionAttachment extends Attachment { + /** The local x translation. */ + x = 0; + /** The local y translation. */ + y = 0; + /** The local scaleX. */ + scaleX = 1; + /** The local scaleY. */ + scaleY = 1; + /** The local rotation. */ + rotation = 0; + /** The width of the region attachment in Spine. */ + width = 0; + /** The height of the region attachment in Spine. */ + height = 0; + /** The color to tint the region attachment. */ + color = new Color(1, 1, 1, 1); + /** The name of the texture region for this attachment. */ + path; + region = null; + sequence = null; + /** For each of the 4 vertices, a pair of x,y values that is the local position of the vertex. + * + * See {@link #updateOffset()}. */ + offset = Utils.newFloatArray(8); + uvs = Utils.newFloatArray(8); + tempColor = new Color(1, 1, 1, 1); + constructor(name, path) { + super(name); + this.path = path; + } + /** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */ + updateRegion() { + if (!this.region) throw new Error("Region not set."); + let region = this.region; + let uvs = this.uvs; + if (region == null) { + uvs[0] = 0; + uvs[1] = 0; + uvs[2] = 0; + uvs[3] = 1; + uvs[4] = 1; + uvs[5] = 1; + uvs[6] = 1; + uvs[7] = 0; + return; + } + let regionScaleX = this.width / this.region.originalWidth * this.scaleX; + let regionScaleY = this.height / this.region.originalHeight * this.scaleY; + let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + let localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + let localX2 = localX + this.region.width * regionScaleX; + let localY2 = localY + this.region.height * regionScaleY; + let radians = this.rotation * MathUtils.degRad; + let cos = Math.cos(radians); + let sin = Math.sin(radians); + let x = this.x, y = this.y; + let localXCos = localX * cos + x; + let localXSin = localX * sin; + let localYCos = localY * cos + y; + let localYSin = localY * sin; + let localX2Cos = localX2 * cos + x; + let localX2Sin = localX2 * sin; + let localY2Cos = localY2 * cos + y; + let localY2Sin = localY2 * sin; + let offset = this.offset; + offset[0] = localXCos - localYSin; + offset[1] = localYCos + localXSin; + offset[2] = localXCos - localY2Sin; + offset[3] = localY2Cos + localXSin; + offset[4] = localX2Cos - localY2Sin; + offset[5] = localY2Cos + localX2Sin; + offset[6] = localX2Cos - localYSin; + offset[7] = localYCos + localX2Sin; + if (region.degrees == 90) { + uvs[0] = region.u2; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + } else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + } + /** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the region may + * be changed. + *

+ * See World transforms in the Spine + * Runtimes Guide. + * @param worldVertices The output world vertices. Must have a length >= offset + 8. + * @param offset The worldVertices index to begin writing values. + * @param stride The number of worldVertices entries between the value pairs written. */ + computeWorldVertices(slot, worldVertices2, offset, stride) { + if (this.sequence != null) + this.sequence.apply(slot, this); + let bone = slot.bone; + let vertexOffset = this.offset; + let x = bone.worldX, y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let offsetX = 0, offsetY = 0; + offsetX = vertexOffset[0]; + offsetY = vertexOffset[1]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[2]; + offsetY = vertexOffset[3]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[4]; + offsetY = vertexOffset[5]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[6]; + offsetY = vertexOffset[7]; + worldVertices2[offset] = offsetX * a + offsetY * b + x; + worldVertices2[offset + 1] = offsetX * c + offsetY * d + y; + } + copy() { + let copy = new _RegionAttachment(this.name, this.path); + copy.region = this.region; + copy.x = this.x; + copy.y = this.y; + copy.scaleX = this.scaleX; + copy.scaleY = this.scaleY; + copy.rotation = this.rotation; + copy.width = this.width; + copy.height = this.height; + Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); + Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); + copy.color.setFromColor(this.color); + copy.sequence = this.sequence != null ? this.sequence.copy() : null; + return copy; + } + static X1 = 0; + static Y1 = 1; + static C1R = 2; + static C1G = 3; + static C1B = 4; + static C1A = 5; + static U1 = 6; + static V1 = 7; + static X2 = 8; + static Y2 = 9; + static C2R = 10; + static C2G = 11; + static C2B = 12; + static C2A = 13; + static U2 = 14; + static V2 = 15; + static X3 = 16; + static Y3 = 17; + static C3R = 18; + static C3G = 19; + static C3B = 20; + static C3A = 21; + static U3 = 22; + static V3 = 23; + static X4 = 24; + static Y4 = 25; + static C4R = 26; + static C4G = 27; + static C4B = 28; + static C4A = 29; + static U4 = 30; + static V4 = 31; + }; + + // spine-core/src/AtlasAttachmentLoader.ts + var AtlasAttachmentLoader = class { + atlas; + constructor(atlas) { + this.atlas = atlas; + } + loadSequence(name, basePath, sequence) { + let regions = sequence.regions; + for (let i = 0, n = regions.length; i < n; i++) { + let path = sequence.getPath(basePath, i); + let region = this.atlas.findRegion(path); + if (region == null) throw new Error("Region not found in atlas: " + path + " (sequence: " + name + ")"); + regions[i] = region; + } + } + newRegionAttachment(skin, name, path, sequence) { + let attachment = new RegionAttachment(name, path); + if (sequence != null) { + this.loadSequence(name, path, sequence); + } else { + let region = this.atlas.findRegion(path); + if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + attachment.region = region; + } + return attachment; + } + newMeshAttachment(skin, name, path, sequence) { + let attachment = new MeshAttachment(name, path); + if (sequence != null) { + this.loadSequence(name, path, sequence); + } else { + let region = this.atlas.findRegion(path); + if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + attachment.region = region; + } + return attachment; + } + newBoundingBoxAttachment(skin, name) { + return new BoundingBoxAttachment(name); + } + newPathAttachment(skin, name) { + return new PathAttachment(name); + } + newPointAttachment(skin, name) { + return new PointAttachment(name); + } + newClippingAttachment(skin, name) { + return new ClippingAttachment(name); + } + }; + + // spine-core/src/BoneData.ts + var BoneData = class { + /** The index of the bone in {@link Skeleton#getBones()}. */ + index = 0; + /** The name of the bone, which is unique across all bones in the skeleton. */ + name; + /** @returns May be null. */ + parent = null; + /** The bone's length. */ + length = 0; + /** The local x translation. */ + x = 0; + /** The local y translation. */ + y = 0; + /** The local rotation in degrees, counter clockwise. */ + rotation = 0; + /** The local scaleX. */ + scaleX = 1; + /** The local scaleY. */ + scaleY = 1; + /** The local shearX. */ + shearX = 0; + /** The local shearX. */ + shearY = 0; + /** The transform mode for how parent world transforms affect this bone. */ + inherit = 0 /* Normal */; + /** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#skin} contains this + * bone. + * @see Skin#bones */ + skinRequired = false; + /** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually + * rendered at runtime. */ + color = new Color(); + /** The bone icon as it was in Spine, or null if nonessential data was not exported. */ + icon; + /** False if the bone was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */ + visible = false; + constructor(index, name, parent) { + if (index < 0) throw new Error("index must be >= 0."); + if (!name) throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + }; + var Inherit = /* @__PURE__ */ ((Inherit2) => { + Inherit2[Inherit2["Normal"] = 0] = "Normal"; + Inherit2[Inherit2["OnlyTranslation"] = 1] = "OnlyTranslation"; + Inherit2[Inherit2["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; + Inherit2[Inherit2["NoScale"] = 3] = "NoScale"; + Inherit2[Inherit2["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; + return Inherit2; + })(Inherit || {}); + + // spine-core/src/Bone.ts + var Bone = class { + /** The bone's setup pose data. */ + data; + /** The skeleton this bone belongs to. */ + skeleton; + /** The parent bone, or null if this is the root bone. */ + parent = null; + /** The immediate children of this bone. */ + children = new Array(); + /** The local x translation. */ + x = 0; + /** The local y translation. */ + y = 0; + /** The local rotation in degrees, counter clockwise. */ + rotation = 0; + /** The local scaleX. */ + scaleX = 0; + /** The local scaleY. */ + scaleY = 0; + /** The local shearX. */ + shearX = 0; + /** The local shearY. */ + shearY = 0; + /** The applied local x translation. */ + ax = 0; + /** The applied local y translation. */ + ay = 0; + /** The applied local rotation in degrees, counter clockwise. */ + arotation = 0; + /** The applied local scaleX. */ + ascaleX = 0; + /** The applied local scaleY. */ + ascaleY = 0; + /** The applied local shearX. */ + ashearX = 0; + /** The applied local shearY. */ + ashearY = 0; + /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */ + a = 0; + /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */ + b = 0; + /** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */ + c = 0; + /** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */ + d = 0; + /** The world X position. If changed, {@link #updateAppliedTransform()} should be called. */ + worldY = 0; + /** The world Y position. If changed, {@link #updateAppliedTransform()} should be called. */ + worldX = 0; + inherit = 0 /* Normal */; + sorted = false; + active = false; + /** @param parent May be null. */ + constructor(data, skeleton, parent) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + /** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the + * {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */ + isActive() { + return this.active; + } + /** Computes the world transform using the parent bone and this bone's local applied transform. */ + update(physics) { + this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY); + } + /** Computes the world transform using the parent bone and this bone's local transform. + * + * See {@link #updateWorldTransformWith()}. */ + updateWorldTransform() { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + } + /** Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the + * specified local transform. Child bones are not updated. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. */ + updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + let parent = this.parent; + if (!parent) { + let skeleton = this.skeleton; + const sx = skeleton.scaleX, sy = skeleton.scaleY; + const rx = (rotation + shearX) * MathUtils.degRad; + const ry = (rotation + 90 + shearY) * MathUtils.degRad; + this.a = Math.cos(rx) * scaleX * sx; + this.b = Math.cos(ry) * scaleY * sx; + this.c = Math.sin(rx) * scaleX * sy; + this.d = Math.sin(ry) * scaleY * sy; + this.worldX = x * sx + skeleton.x; + this.worldY = y * sy + skeleton.y; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + this.worldX = pa * x + pb * y + parent.worldX; + this.worldY = pc * x + pd * y + parent.worldY; + switch (this.inherit) { + case 0 /* Normal */: { + const rx = (rotation + shearX) * MathUtils.degRad; + const ry = (rotation + 90 + shearY) * MathUtils.degRad; + const la = Math.cos(rx) * scaleX; + const lb = Math.cos(ry) * scaleY; + const lc = Math.sin(rx) * scaleX; + const ld = Math.sin(ry) * scaleY; + this.a = pa * la + pb * lc; + this.b = pa * lb + pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + return; + } + case 1 /* OnlyTranslation */: { + const rx = (rotation + shearX) * MathUtils.degRad; + const ry = (rotation + 90 + shearY) * MathUtils.degRad; + this.a = Math.cos(rx) * scaleX; + this.b = Math.cos(ry) * scaleY; + this.c = Math.sin(rx) * scaleX; + this.d = Math.sin(ry) * scaleY; + break; + } + case 2 /* NoRotationOrReflection */: { + let sx = 1 / this.skeleton.scaleX, sy = 1 / this.skeleton.scaleY; + pa *= sx; + pc *= sy; + let s = pa * pa + pc * pc; + let prx = 0; + if (s > 1e-4) { + s = Math.abs(pa * pd * sy - pb * sx * pc) / s; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * MathUtils.radDeg; + } else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg; + } + const rx = (rotation + shearX - prx) * MathUtils.degRad; + const ry = (rotation + shearY - prx + 90) * MathUtils.degRad; + const la = Math.cos(rx) * scaleX; + const lb = Math.cos(ry) * scaleY; + const lc = Math.sin(rx) * scaleX; + const ld = Math.sin(ry) * scaleY; + this.a = pa * la - pb * lc; + this.b = pa * lb - pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + break; + } + case 3 /* NoScale */: + case 4 /* NoScaleOrReflection */: { + rotation *= MathUtils.degRad; + const cos = Math.cos(rotation), sin = Math.sin(rotation); + let za = (pa * cos + pb * sin) / this.skeleton.scaleX; + let zc = (pc * cos + pd * sin) / this.skeleton.scaleY; + let s = Math.sqrt(za * za + zc * zc); + if (s > 1e-5) s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.inherit == 3 /* NoScale */ && pa * pd - pb * pc < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s; + rotation = Math.PI / 2 + Math.atan2(zc, za); + const zb = Math.cos(rotation) * s; + const zd = Math.sin(rotation) * s; + shearX *= MathUtils.degRad; + shearY = (90 + shearY) * MathUtils.degRad; + const la = Math.cos(shearX) * scaleX; + const lb = Math.cos(shearY) * scaleY; + const lc = Math.sin(shearX) * scaleX; + const ld = Math.sin(shearY) * scaleY; + this.a = za * la + zb * lc; + this.b = za * lb + zb * ld; + this.c = zc * la + zd * lc; + this.d = zc * lb + zd * ld; + break; + } + } + this.a *= this.skeleton.scaleX; + this.b *= this.skeleton.scaleX; + this.c *= this.skeleton.scaleY; + this.d *= this.skeleton.scaleY; + } + /** Sets this bone's local transform to the setup pose. */ + setToSetupPose() { + let data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + this.inherit = data.inherit; + } + /** Computes the applied transform values from the world transform. + * + * If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, etc) then this method should be called so + * the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply other + * constraints). + * + * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after + * calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */ + updateAppliedTransform() { + let parent = this.parent; + if (!parent) { + this.ax = this.worldX - this.skeleton.x; + this.ay = this.worldY - this.skeleton.y; + this.arotation = Math.atan2(this.c, this.a) * MathUtils.radDeg; + this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c); + this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d); + this.ashearX = 0; + this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * MathUtils.radDeg; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + let pid = 1 / (pa * pd - pb * pc); + let ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid; + let dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY; + this.ax = dx * ia - dy * ib; + this.ay = dy * id - dx * ic; + let ra, rb, rc, rd; + if (this.inherit == 1 /* OnlyTranslation */) { + ra = this.a; + rb = this.b; + rc = this.c; + rd = this.d; + } else { + switch (this.inherit) { + case 2 /* NoRotationOrReflection */: { + let s2 = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); + pb = -pc * this.skeleton.scaleX * s2 / this.skeleton.scaleY; + pd = pa * this.skeleton.scaleY * s2 / this.skeleton.scaleX; + pid = 1 / (pa * pd - pb * pc); + ia = pd * pid; + ib = pb * pid; + break; + } + case 3 /* NoScale */: + case 4 /* NoScaleOrReflection */: + let cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); + pa = (pa * cos + pb * sin) / this.skeleton.scaleX; + pc = (pc * cos + pd * sin) / this.skeleton.scaleY; + let s = Math.sqrt(pa * pa + pc * pc); + if (s > 1e-5) s = 1 / s; + pa *= s; + pc *= s; + s = Math.sqrt(pa * pa + pc * pc); + if (this.inherit == 3 /* NoScale */ && pid < 0 != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) s = -s; + let r = MathUtils.PI / 2 + Math.atan2(pc, pa); + pb = Math.cos(r) * s; + pd = Math.sin(r) * s; + pid = 1 / (pa * pd - pb * pc); + ia = pd * pid; + ib = pb * pid; + ic = pc * pid; + id = pa * pid; + } + ra = ia * this.a - ib * this.c; + rb = ia * this.b - ib * this.d; + rc = id * this.c - ic * this.a; + rd = id * this.d - ic * this.b; + } + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 1e-4) { + let det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = -Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * MathUtils.radDeg; + } else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg; + } + } + /** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */ + getWorldRotationX() { + return Math.atan2(this.c, this.a) * MathUtils.radDeg; + } + /** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */ + getWorldRotationY() { + return Math.atan2(this.d, this.b) * MathUtils.radDeg; + } + /** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */ + getWorldScaleX() { + return Math.sqrt(this.a * this.a + this.c * this.c); + } + /** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */ + getWorldScaleY() { + return Math.sqrt(this.b * this.b + this.d * this.d); + } + /** Transforms a point from world coordinates to the bone's local coordinates. */ + worldToLocal(world) { + let invDet = 1 / (this.a * this.d - this.b * this.c); + let x = world.x - this.worldX, y = world.y - this.worldY; + world.x = x * this.d * invDet - y * this.b * invDet; + world.y = y * this.a * invDet - x * this.c * invDet; + return world; + } + /** Transforms a point from the bone's local coordinates to world coordinates. */ + localToWorld(local) { + let x = local.x, y = local.y; + local.x = x * this.a + y * this.b + this.worldX; + local.y = x * this.c + y * this.d + this.worldY; + return local; + } + /** Transforms a point from world coordinates to the parent bone's local coordinates. */ + worldToParent(world) { + if (world == null) throw new Error("world cannot be null."); + return this.parent == null ? world : this.parent.worldToLocal(world); + } + /** Transforms a point from the parent bone's coordinates to world coordinates. */ + parentToWorld(world) { + if (world == null) throw new Error("world cannot be null."); + return this.parent == null ? world : this.parent.localToWorld(world); + } + /** Transforms a world rotation to a local rotation. */ + worldToLocalRotation(worldRotation) { + let sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); + return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * MathUtils.radDeg + this.rotation - this.shearX; + } + /** Transforms a local rotation to a world rotation. */ + localToWorldRotation(localRotation) { + localRotation -= this.rotation - this.shearX; + let sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); + return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg; + } + /** Rotates the world transform the specified amount. + *

+ * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and + * {@link #update(Physics)} will need to be called on any child bones, recursively. */ + rotateWorld(degrees) { + degrees *= MathUtils.degRad; + const sin = Math.sin(degrees), cos = Math.cos(degrees); + const ra = this.a, rb = this.b; + this.a = cos * ra - sin * this.c; + this.b = cos * rb - sin * this.d; + this.c = sin * ra + cos * this.c; + this.d = sin * rb + cos * this.d; + } + }; + + // spine-core/src/ConstraintData.ts + var ConstraintData = class { + constructor(name, order, skinRequired) { + this.name = name; + this.order = order; + this.skinRequired = skinRequired; + } + }; + + // spine-core/src/AssetManagerBase.ts + var AssetManagerBase = class { + pathPrefix = ""; + textureLoader; + downloader; + cache; + errors = {}; + toLoad = 0; + loaded = 0; + constructor(textureLoader, pathPrefix = "", downloader = new Downloader(), cache = new AssetCache()) { + this.textureLoader = textureLoader; + this.pathPrefix = pathPrefix; + this.downloader = downloader; + this.cache = cache; + } + start(path) { + this.toLoad++; + return this.pathPrefix + path; + } + success(callback, path, asset) { + this.toLoad--; + this.loaded++; + this.cache.assets[path] = asset; + this.cache.assetsRefCount[path] = (this.cache.assetsRefCount[path] || 0) + 1; + if (callback) callback(path, asset); + } + error(callback, path, message) { + this.toLoad--; + this.loaded++; + this.errors[path] = message; + if (callback) callback(path, message); + } + loadAll() { + let promise = new Promise((resolve, reject) => { + let check = () => { + if (this.isLoadingComplete()) { + if (this.hasErrors()) reject(this.errors); + else resolve(this); + return; + } + requestAnimationFrame(check); + }; + requestAnimationFrame(check); + }); + return promise; + } + setRawDataURI(path, data) { + this.downloader.rawDataUris[this.pathPrefix + path] = data; + } + loadBinary(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadBinary(path, (data) => { + this.success(success, path, data); + resolve(data); + }, (status, responseText) => { + const errorMsg = `Couldn't load binary ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + loadText(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + this.downloader.downloadText(path, (data) => { + this.success(success, path, data); + }, (status, responseText) => { + this.error(error, path, `Couldn't load text ${path}: status ${status}, ${responseText}`); + }); + } + loadJson(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadJson(path, (data) => { + this.success(success, path, data); + resolve(data); + }, (status, responseText) => { + const errorMsg = `Couldn't load JSON ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + reuseAssets(path, success = () => { + }, error = () => { + }) { + const loadedStatus = this.cache.assetsLoaded[path]; + const alreadyExistsOrLoading = loadedStatus !== void 0; + if (alreadyExistsOrLoading) { + this.cache.assetsLoaded[path] = loadedStatus.then((data) => { + data = data instanceof Image || data instanceof ImageBitmap ? this.textureLoader(data) : data; + this.success(success, path, data); + return data; + }).catch((errorMsg) => this.error(error, path, errorMsg)); + } + return alreadyExistsOrLoading; + } + loadTexture(path, success = () => { + }, error = () => { + }) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + let isBrowser = !!(typeof window !== "undefined" && typeof navigator !== "undefined" && window.document); + let isWebWorker = !isBrowser; + if (isWebWorker) { + fetch(path, { mode: "cors" }).then((response) => { + if (response.ok) return response.blob(); + const errorMsg = `Couldn't load image: ${path}`; + this.error(error, path, `Couldn't load image: ${path}`); + reject(errorMsg); + }).then((blob) => { + return blob ? createImageBitmap(blob, { premultiplyAlpha: "none", colorSpaceConversion: "none" }) : null; + }).then((bitmap) => { + if (bitmap) { + const texture = this.createTexture(path, bitmap); + this.success(success, path, texture); + resolve(texture); + } + ; + }); + } else { + let image = new Image(); + if (typeof location === "undefined" || location.protocol !== "file:") + image.crossOrigin = "anonymous"; + image.onload = () => { + const texture = this.createTexture(path, image); + this.success(success, path, texture); + resolve(texture); + }; + image.onerror = () => { + const errorMsg = `Couldn't load image: ${path}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }; + if (this.downloader.rawDataUris[path]) path = this.downloader.rawDataUris[path]; + image.src = path; + } + }); + } + loadTextureAtlas(path, success = () => { + }, error = () => { + }, fileAlias) { + let index = path.lastIndexOf("/"); + let parent = index >= 0 ? path.substring(0, index + 1) : ""; + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadText(path, (atlasText) => { + try { + const atlas = this.createTextureAtlas(path, atlasText); + let toLoad = atlas.pages.length, abort = false; + for (let page of atlas.pages) { + this.loadTexture( + !fileAlias ? parent + page.name : fileAlias[page.name], + (imagePath, texture) => { + if (!abort) { + page.setTexture(texture); + if (--toLoad == 0) { + this.success(success, path, atlas); + resolve(atlas); + } + } + }, + (imagePath, message) => { + if (!abort) { + const errorMsg = `Couldn't load texture ${path} page image: ${imagePath}`; + this.error(error, path, errorMsg); + reject(errorMsg); + } + abort = true; + } + ); + } + } catch (e) { + const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`; + this.error(error, path, errorMsg); + reject(errorMsg); + } + }, (status, responseText) => { + const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + loadTextureAtlasButNoTextures(path, success = () => { + }, error = () => { + }, fileAlias) { + path = this.start(path); + if (this.reuseAssets(path, success, error)) return; + this.cache.assetsLoaded[path] = new Promise((resolve, reject) => { + this.downloader.downloadText(path, (atlasText) => { + try { + const atlas = this.createTextureAtlas(path, atlasText); + this.success(success, path, atlas); + resolve(atlas); + } catch (e) { + const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`; + this.error(error, path, errorMsg); + reject(errorMsg); + } + }, (status, responseText) => { + const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; + this.error(error, path, errorMsg); + reject(errorMsg); + }); + }); + } + // Promisified versions of load function + async loadBinaryAsync(path) { + return new Promise((resolve, reject) => { + this.loadBinary( + path, + (_, binary) => resolve(binary), + (_, message) => reject(message) + ); + }); + } + async loadJsonAsync(path) { + return new Promise((resolve, reject) => { + this.loadJson( + path, + (_, object) => resolve(object), + (_, message) => reject(message) + ); + }); + } + async loadTextureAsync(path) { + return new Promise((resolve, reject) => { + this.loadTexture( + path, + (_, texture) => resolve(texture), + (_, message) => reject(message) + ); + }); + } + async loadTextureAtlasAsync(path) { + return new Promise((resolve, reject) => { + this.loadTextureAtlas( + path, + (_, atlas) => resolve(atlas), + (_, message) => reject(message) + ); + }); + } + async loadTextureAtlasButNoTexturesAsync(path) { + return new Promise((resolve, reject) => { + this.loadTextureAtlasButNoTextures( + path, + (_, atlas) => resolve(atlas), + (_, message) => reject(message) + ); + }); + } + setCache(cache) { + this.cache = cache; + } + get(path) { + return this.cache.assets[this.pathPrefix + path]; + } + require(path) { + path = this.pathPrefix + path; + let asset = this.cache.assets[path]; + if (asset) return asset; + let error = this.errors[path]; + throw Error("Asset not found: " + path + (error ? "\n" + error : "")); + } + remove(path) { + path = this.pathPrefix + path; + let asset = this.cache.assets[path]; + if (asset.dispose) asset.dispose(); + delete this.cache.assets[path]; + delete this.cache.assetsRefCount[path]; + delete this.cache.assetsLoaded[path]; + return asset; + } + removeAll() { + for (let path in this.cache.assets) { + let asset = this.cache.assets[path]; + if (asset.dispose) asset.dispose(); + } + this.cache.assets = {}; + this.cache.assetsLoaded = {}; + this.cache.assetsRefCount = {}; + } + isLoadingComplete() { + return this.toLoad == 0; + } + getToLoad() { + return this.toLoad; + } + getLoaded() { + return this.loaded; + } + dispose() { + this.removeAll(); + } + // dispose asset only if it's not used by others + disposeAsset(path) { + const asset = this.cache.assets[path]; + if (asset instanceof TextureAtlas) { + asset.dispose(); + return; + } + this.disposeAssetInternal(path); + } + hasErrors() { + return Object.keys(this.errors).length > 0; + } + getErrors() { + return this.errors; + } + disposeAssetInternal(path) { + if (this.cache.assetsRefCount[path] > 0 && --this.cache.assetsRefCount[path] === 0) { + return this.remove(path); + } + } + createTextureAtlas(path, atlasText) { + const atlas = new TextureAtlas(atlasText); + atlas.dispose = () => { + if (this.cache.assetsRefCount[path] <= 0) return; + this.disposeAssetInternal(path); + for (const page of atlas.pages) { + page.texture?.dispose(); + } + }; + return atlas; + } + createTexture(path, image) { + const texture = this.textureLoader(image); + const textureDispose = texture.dispose.bind(texture); + texture.dispose = () => { + if (this.disposeAssetInternal(path)) textureDispose(); + }; + return texture; + } + }; + var AssetCache = class _AssetCache { + assets = {}; + assetsRefCount = {}; + assetsLoaded = {}; + static AVAILABLE_CACHES = /* @__PURE__ */ new Map(); + static getCache(id) { + const cache = _AssetCache.AVAILABLE_CACHES.get(id); + if (cache) return cache; + const newCache = new _AssetCache(); + _AssetCache.AVAILABLE_CACHES.set(id, newCache); + return newCache; + } + async addAsset(path, asset) { + this.assetsLoaded[path] = Promise.resolve(asset); + this.assets[path] = await asset; + } + }; + var Downloader = class { + callbacks = {}; + rawDataUris = {}; + dataUriToString(dataUri) { + if (!dataUri.startsWith("data:")) { + throw new Error("Not a data URI."); + } + let base64Idx = dataUri.indexOf("base64,"); + if (base64Idx != -1) { + base64Idx += "base64,".length; + return atob(dataUri.substr(base64Idx)); + } else { + return dataUri.substr(dataUri.indexOf(",") + 1); + } + } + base64ToUint8Array(base64) { + var binary_string = window.atob(base64); + var len = binary_string.length; + var bytes = new Uint8Array(len); + for (var i = 0; i < len; i++) { + bytes[i] = binary_string.charCodeAt(i); + } + return bytes; + } + dataUriToUint8Array(dataUri) { + if (!dataUri.startsWith("data:")) { + throw new Error("Not a data URI."); + } + let base64Idx = dataUri.indexOf("base64,"); + if (base64Idx == -1) throw new Error("Not a binary data URI."); + base64Idx += "base64,".length; + return this.base64ToUint8Array(dataUri.substr(base64Idx)); + } + downloadText(url, success, error) { + if (this.start(url, success, error)) return; + const rawDataUri = this.rawDataUris[url]; + if (rawDataUri && rawDataUri.startsWith("data:")) { + try { + this.finish(url, 200, this.dataUriToString(rawDataUri)); + } catch (e) { + this.finish(url, 400, JSON.stringify(e)); + } + return; + } + let request = new XMLHttpRequest(); + request.overrideMimeType("text/html"); + request.open("GET", rawDataUri ? rawDataUri : url, true); + let done = () => { + this.finish(url, request.status, request.responseText); + }; + request.onload = done; + request.onerror = done; + request.send(); + } + downloadJson(url, success, error) { + this.downloadText(url, (data) => { + success(JSON.parse(data)); + }, error); + } + downloadBinary(url, success, error) { + if (this.start(url, success, error)) return; + const rawDataUri = this.rawDataUris[url]; + if (rawDataUri && !rawDataUri.includes(".")) { + try { + this.finish(url, 200, this.dataUriToUint8Array(rawDataUri)); + } catch (e) { + this.finish(url, 400, JSON.stringify(e)); + } + return; + } + let request = new XMLHttpRequest(); + request.open("GET", rawDataUri ? rawDataUri : url, true); + request.responseType = "arraybuffer"; + let onerror = () => { + this.finish(url, request.status, request.response); + }; + request.onload = () => { + if (request.status == 200 || request.status == 0) + this.finish(url, 200, new Uint8Array(request.response)); + else + onerror(); + }; + request.onerror = onerror; + request.send(); + } + start(url, success, error) { + let callbacks = this.callbacks[url]; + try { + if (callbacks) return true; + this.callbacks[url] = callbacks = []; + } finally { + callbacks.push(success, error); + } + } + finish(url, status, data) { + let callbacks = this.callbacks[url]; + delete this.callbacks[url]; + let args = status == 200 || status == 0 ? [data] : [status, data]; + for (let i = args.length - 1, n = callbacks.length; i < n; i += 2) + callbacks[i].apply(null, args); + } + }; + + // spine-core/src/Event.ts + var Event = class { + data; + intValue = 0; + floatValue = 0; + stringValue = null; + time = 0; + volume = 0; + balance = 0; + constructor(time, data) { + if (!data) throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + }; + + // spine-core/src/EventData.ts + var EventData = class { + name; + intValue = 0; + floatValue = 0; + stringValue = null; + audioPath = null; + volume = 0; + balance = 0; + constructor(name) { + this.name = name; + } + }; + + // spine-core/src/IkConstraint.ts + var IkConstraint = class { + /** The IK constraint's setup pose data. */ + data; + /** The bones that will be modified by this IK constraint. */ + bones; + /** The bone that is the IK target. */ + target; + /** Controls the bend direction of the IK bones, either 1 or -1. */ + bendDirection = 0; + /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ + compress = false; + /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + * and the parent bone has local nonuniform scale, stretch is not applied. */ + stretch = false; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ + mix = 1; + /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ + softness = 0; + active = false; + constructor(data, skeleton) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let bone = skeleton.findBone(data.bones[i].name); + if (!bone) throw new Error(`Couldn't find bone ${data.bones[i].name}`); + this.bones.push(bone); + } + let target = skeleton.findBone(data.target.name); + if (!target) throw new Error(`Couldn't find bone ${data.target.name}`); + this.target = target; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + } + isActive() { + return this.active; + } + setToSetupPose() { + const data = this.data; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + } + update(physics) { + if (this.mix == 0) return; + let target = this.target; + let bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.data.uniform, this.softness, this.mix); + break; + } + } + /** Applies 1 bone IK. The target is specified in the world coordinate system. */ + apply1(bone, targetX, targetY, compress, stretch, uniform, alpha) { + let p = bone.parent; + if (!p) throw new Error("IK bone must have parent."); + let pa = p.a, pb = p.b, pc = p.c, pd = p.d; + let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; + switch (bone.inherit) { + case 1 /* OnlyTranslation */: + tx = (targetX - bone.worldX) * MathUtils.signum(bone.skeleton.scaleX); + ty = (targetY - bone.worldY) * MathUtils.signum(bone.skeleton.scaleY); + break; + case 2 /* NoRotationOrReflection */: + let s = Math.abs(pa * pd - pb * pc) / Math.max(1e-4, pa * pa + pc * pc); + let sa = pa / bone.skeleton.scaleX; + let sc = pc / bone.skeleton.scaleY; + pb = -sc * s * bone.skeleton.scaleX; + pd = sa * s * bone.skeleton.scaleY; + rotationIK += Math.atan2(sc, sa) * MathUtils.radDeg; + // Fall through + default: + let x = targetX - p.worldX, y = targetY - p.worldY; + let d = pa * pd - pb * pc; + if (Math.abs(d) <= 1e-4) { + tx = 0; + ty = 0; + } else { + tx = (x * pd - y * pb) / d - bone.ax; + ty = (y * pa - x * pc) / d - bone.ay; + } + } + rotationIK += Math.atan2(ty, tx) * MathUtils.radDeg; + if (bone.ascaleX < 0) rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + let sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + switch (bone.inherit) { + case 3 /* NoScale */: + case 4 /* NoScaleOrReflection */: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + } + const b = bone.data.length * sx; + if (b > 1e-4) { + const dd = tx * tx + ty * ty; + if (compress && dd < b * b || stretch && dd > b * b) { + const s = (Math.sqrt(dd) / b - 1) * alpha + 1; + sx *= s; + if (uniform) sy *= s; + } + } + } + bone.updateWorldTransformWith( + bone.ax, + bone.ay, + bone.arotation + rotationIK * alpha, + sx, + sy, + bone.ashearX, + bone.ashearY + ); + } + /** Applies 2 bone IK. The target is specified in the world coordinate system. + * @param child A direct descendant of the parent bone. */ + apply2(parent, child, targetX, targetY, bendDir, stretch, uniform, softness, alpha) { + if (parent.inherit != 0 /* Normal */ || child.inherit != 0 /* Normal */) return; + let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX; + let os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } else + os2 = 0; + let cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d; + let u = Math.abs(psx - psy) <= 1e-4; + if (!u || stretch) { + cy = 0; + cwx = a * cx + parent.worldX; + cwy = c * cx + parent.worldY; + } else { + cy = child.ay; + cwx = a * cx + b * cy + parent.worldX; + cwy = c * cx + d * cy + parent.worldY; + } + let pp = parent.parent; + if (!pp) throw new Error("IK parent must itself have a parent."); + a = pp.a; + b = pp.b; + c = pp.c; + d = pp.d; + let id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY; + id = Math.abs(id) <= 1e-4 ? 0 : 1 / id; + let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; + if (l1 < 1e-4) { + this.apply1(parent, targetX, targetY, false, stretch, false, alpha); + child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + return; + } + x = targetX - pp.worldX; + y = targetY - pp.worldY; + let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; + let dd = tx * tx + ty * ty; + if (softness != 0) { + softness *= psx * (csx + 1) * 0.5; + let td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; + if (sd > 0) { + let p = Math.min(1, sd / (softness * 2)) - 1; + p = (sd - softness * (1 - p * p)) / td; + tx -= p * tx; + ty -= p * ty; + dd = tx * tx + ty * ty; + } + } + outer: + if (u) { + l2 *= psx; + let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) { + cos = -1; + a2 = Math.PI * bendDir; + } else if (cos > 1) { + cos = 1; + a2 = 0; + if (stretch) { + a = (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + sx *= a; + if (uniform) sy *= a; + } + } else + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } else { + a = psx * l2; + b = psy * l2; + let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + let c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + let q = Math.sqrt(d); + if (c1 < 0) q = -q; + q = -(c1 + q) * 0.5; + let r0 = q / c2, r1 = c / q; + let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + r0 = dd - r * r; + if (r0 >= 0) { + y = Math.sqrt(r0) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + let minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) * 0.5) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + let os = Math.atan2(cy, cx) * s2; + let rotation = parent.arotation; + a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, sy, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + } + }; + + // spine-core/src/IkConstraintData.ts + var IkConstraintData = class extends ConstraintData { + /** The bones that are constrained by this IK constraint. */ + bones = new Array(); + /** The bone that is the IK target. */ + _target = null; + set target(boneData) { + this._target = boneData; + } + get target() { + if (!this._target) throw new Error("BoneData not set."); + else return this._target; + } + /** Controls the bend direction of the IK bones, either 1 or -1. */ + bendDirection = 0; + /** When true and only a single bone is being constrained, if the target is too close, the bone is scaled to reach it. */ + compress = false; + /** When true, if the target is out of range, the parent bone is scaled to reach it. If more than one bone is being constrained + * and the parent bone has local nonuniform scale, stretch is not applied. */ + stretch = false; + /** When true, only a single bone is being constrained, and {@link #getCompress()} or {@link #getStretch()} is used, the bone + * is scaled on both the X and Y axes. */ + uniform = false; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */ + mix = 0; + /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ + softness = 0; + constructor(name) { + super(name, 0, false); + } + }; + + // spine-core/src/PathConstraintData.ts + var PathConstraintData = class extends ConstraintData { + /** The bones that will be modified by this path constraint. */ + bones = new Array(); + /** The slot whose path attachment will be used to constrained the bones. */ + _target = null; + set target(slotData) { + this._target = slotData; + } + get target() { + if (!this._target) throw new Error("SlotData not set."); + else return this._target; + } + /** The mode for positioning the first bone on the path. */ + positionMode = 0 /* Fixed */; + /** The mode for positioning the bones after the first bone on the path. */ + spacingMode = 1 /* Fixed */; + /** The mode for adjusting the rotation of the bones. */ + rotateMode = 1 /* Chain */; + /** An offset added to the constrained bone rotation. */ + offsetRotation = 0; + /** The position along the path. */ + position = 0; + /** The spacing between bones. */ + spacing = 0; + mixRotate = 0; + mixX = 0; + mixY = 0; + constructor(name) { + super(name, 0, false); + } + }; + var PositionMode = /* @__PURE__ */ ((PositionMode2) => { + PositionMode2[PositionMode2["Fixed"] = 0] = "Fixed"; + PositionMode2[PositionMode2["Percent"] = 1] = "Percent"; + return PositionMode2; + })(PositionMode || {}); + var SpacingMode = /* @__PURE__ */ ((SpacingMode2) => { + SpacingMode2[SpacingMode2["Length"] = 0] = "Length"; + SpacingMode2[SpacingMode2["Fixed"] = 1] = "Fixed"; + SpacingMode2[SpacingMode2["Percent"] = 2] = "Percent"; + SpacingMode2[SpacingMode2["Proportional"] = 3] = "Proportional"; + return SpacingMode2; + })(SpacingMode || {}); + var RotateMode = /* @__PURE__ */ ((RotateMode2) => { + RotateMode2[RotateMode2["Tangent"] = 0] = "Tangent"; + RotateMode2[RotateMode2["Chain"] = 1] = "Chain"; + RotateMode2[RotateMode2["ChainScale"] = 2] = "ChainScale"; + return RotateMode2; + })(RotateMode || {}); + + // spine-core/src/PathConstraint.ts + var PathConstraint = class _PathConstraint { + static NONE = -1; + static BEFORE = -2; + static AFTER = -3; + static epsilon = 1e-5; + /** The path constraint's setup pose data. */ + data; + /** The bones that will be modified by this path constraint. */ + bones; + /** The slot whose path attachment will be used to constrained the bones. */ + target; + /** The position along the path. */ + position = 0; + /** The spacing between bones. */ + spacing = 0; + mixRotate = 0; + mixX = 0; + mixY = 0; + spaces = new Array(); + positions = new Array(); + world = new Array(); + curves = new Array(); + lengths = new Array(); + segments = new Array(); + active = false; + constructor(data, skeleton) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0, n = data.bones.length; i < n; i++) { + let bone = skeleton.findBone(data.bones[i].name); + if (!bone) throw new Error(`Couldn't find bone ${data.bones[i].name}.`); + this.bones.push(bone); + } + let target = skeleton.findSlot(data.target.name); + if (!target) throw new Error(`Couldn't find target bone ${data.target.name}`); + this.target = target; + this.position = data.position; + this.spacing = data.spacing; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + } + isActive() { + return this.active; + } + setToSetupPose() { + const data = this.data; + this.position = data.position; + this.spacing = data.spacing; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + } + update(physics) { + let attachment = this.target.getAttachment(); + if (!(attachment instanceof PathAttachment)) return; + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; + if (mixRotate == 0 && mixX == 0 && mixY == 0) return; + let data = this.data; + let tangents = data.rotateMode == 0 /* Tangent */, scale = data.rotateMode == 2 /* ChainScale */; + let bones = this.bones; + let boneCount = bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + let spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = scale ? this.lengths = Utils.setArraySize(this.lengths, boneCount) : []; + let spacing = this.spacing; + switch (data.spacingMode) { + case 2 /* Percent */: + if (scale) { + for (let i = 0, n = spacesCount - 1; i < n; i++) { + let bone = bones[i]; + let setupLength = bone.data.length; + let x = setupLength * bone.a, y = setupLength * bone.c; + lengths[i] = Math.sqrt(x * x + y * y); + } + } + Utils.arrayFill(spaces, 1, spacesCount, spacing); + break; + case 3 /* Proportional */: + let sum = 0; + for (let i = 0, n = spacesCount - 1; i < n; ) { + let bone = bones[i]; + let setupLength = bone.data.length; + if (setupLength < _PathConstraint.epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = spacing; + } else { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + if (scale) lengths[i] = length; + spaces[++i] = length; + sum += length; + } + } + if (sum > 0) { + sum = spacesCount / sum * spacing; + for (let i = 1; i < spacesCount; i++) + spaces[i] *= sum; + } + break; + default: + let lengthSpacing = data.spacingMode == 0 /* Length */; + for (let i = 0, n = spacesCount - 1; i < n; ) { + let bone = bones[i]; + let setupLength = bone.data.length; + if (setupLength < _PathConstraint.epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = spacing; + } else { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + if (scale) lengths[i] = length; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + } + let positions = this.computeWorldPositions(attachment, spacesCount, tangents); + let boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + let tip = false; + if (offsetRotation == 0) + tip = data.rotateMode == 1 /* Chain */; + else { + tip = false; + let p = this.target.bone; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.degRad : -MathUtils.degRad; + } + for (let i = 0, p = 3; i < boneCount; i++, p += 3) { + let bone = bones[i]; + bone.worldX += (boneX - bone.worldX) * mixX; + bone.worldY += (boneY - bone.worldY) * mixY; + let x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + let length = lengths[i]; + if (length != 0) { + let s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1; + bone.a *= s; + bone.c *= s; + } + } + boneX = x; + boneY = y; + if (mixRotate > 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + let length = bone.data.length; + boneX += (length * (cos * a - sin * c) - dx) * mixRotate; + boneY += (length * (sin * a + cos * c) - dy) * mixRotate; + } else { + r += offsetRotation; + } + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= mixRotate; + cos = Math.cos(r); + sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + bone.updateAppliedTransform(); + } + } + computeWorldPositions(path, spacesCount, tangents) { + let target = this.target; + let position = this.position; + let spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = this.world; + let closed2 = path.closed; + let verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = _PathConstraint.NONE; + if (!path.constantSpeed) { + let lengths = path.lengths; + curveCount -= closed2 ? 1 : 2; + let pathLength2 = lengths[curveCount]; + if (this.data.positionMode == 1 /* Percent */) position *= pathLength2; + let multiplier2; + switch (this.data.spacingMode) { + case 2 /* Percent */: + multiplier2 = pathLength2; + break; + case 3 /* Proportional */: + multiplier2 = pathLength2 / spacesCount; + break; + default: + multiplier2 = 1; + } + world = Utils.setArraySize(this.world, 8); + for (let i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i] * multiplier2; + position += space; + let p = position; + if (closed2) { + p %= pathLength2; + if (p < 0) p += pathLength2; + curve = 0; + } else if (p < 0) { + if (prevCurve != _PathConstraint.BEFORE) { + prevCurve = _PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } else if (p > pathLength2) { + if (prevCurve != _PathConstraint.AFTER) { + prevCurve = _PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength2, world, 0, out, o); + continue; + } + for (; ; curve++) { + let length = lengths[curve]; + if (p > length) continue; + if (curve == 0) + p /= length; + else { + let prev = lengths[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed2 && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition( + p, + world[0], + world[1], + world[2], + world[3], + world[4], + world[5], + world[6], + world[7], + out, + o, + tangents || i > 0 && space == 0 + ); + } + return out; + } + if (closed2) { + verticesLength += 2; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } else { + curveCount--; + verticesLength -= 4; + world = Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + let curves = Utils.setArraySize(this.curves, curveCount); + let pathLength = 0; + let x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + let tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (let i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (this.data.positionMode == 1 /* Percent */) position *= pathLength; + let multiplier; + switch (this.data.spacingMode) { + case 2 /* Percent */: + multiplier = pathLength; + break; + case 3 /* Proportional */: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + } + let segments = this.segments; + let curveLength = 0; + for (let i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i] * multiplier; + position += space; + let p = position; + if (closed2) { + p %= pathLength; + if (p < 0) p += pathLength; + curve = 0; + } else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + for (; ; curve++) { + let length = curves[curve]; + if (p > length) continue; + if (curve == 0) + p /= length; + else { + let prev = curves[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + let ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 6e-3; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 6e-3; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + p *= curveLength; + for (; ; segment++) { + let length = segments[segment]; + if (p > length) continue; + if (segment == 0) + p /= length; + else { + let prev = segments[segment - 1]; + p = segment + (p - prev) / (length - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || i > 0 && space == 0); + } + return out; + } + addBeforePosition(p, temp, i, out, o) { + let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addAfterPosition(p, temp, i, out, o) { + let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) { + out[o] = x1; + out[o + 1] = y1; + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + return; + } + let tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + let ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + let x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) { + if (p < 1e-3) + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + else + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + } + }; + + // spine-core/src/PhysicsConstraint.ts + var PhysicsConstraint = class { + data; + _bone = null; + /** The bone constrained by this physics constraint. */ + set bone(bone) { + this._bone = bone; + } + get bone() { + if (!this._bone) throw new Error("Bone not set."); + else return this._bone; + } + inertia = 0; + strength = 0; + damping = 0; + massInverse = 0; + wind = 0; + gravity = 0; + mix = 0; + _reset = true; + ux = 0; + uy = 0; + cx = 0; + cy = 0; + tx = 0; + ty = 0; + xOffset = 0; + xVelocity = 0; + yOffset = 0; + yVelocity = 0; + rotateOffset = 0; + rotateVelocity = 0; + scaleOffset = 0; + scaleVelocity = 0; + active = false; + skeleton; + remaining = 0; + lastTime = 0; + constructor(data, skeleton) { + this.data = data; + this.skeleton = skeleton; + this.bone = skeleton.bones[data.bone.index]; + this.inertia = data.inertia; + this.strength = data.strength; + this.damping = data.damping; + this.massInverse = data.massInverse; + this.wind = data.wind; + this.gravity = data.gravity; + this.mix = data.mix; + } + reset() { + this.remaining = 0; + this.lastTime = this.skeleton.time; + this._reset = true; + this.xOffset = 0; + this.xVelocity = 0; + this.yOffset = 0; + this.yVelocity = 0; + this.rotateOffset = 0; + this.rotateVelocity = 0; + this.scaleOffset = 0; + this.scaleVelocity = 0; + } + setToSetupPose() { + const data = this.data; + this.inertia = data.inertia; + this.strength = data.strength; + this.damping = data.damping; + this.massInverse = data.massInverse; + this.wind = data.wind; + this.gravity = data.gravity; + this.mix = data.mix; + } + isActive() { + return this.active; + } + /** Applies the constraint to the constrained bones. */ + update(physics) { + const mix = this.mix; + if (mix == 0) return; + const x = this.data.x > 0, y = this.data.y > 0, rotateOrShearX = this.data.rotate > 0 || this.data.shearX > 0, scaleX = this.data.scaleX > 0; + const bone = this.bone; + const l = bone.data.length; + switch (physics) { + case 0 /* none */: + return; + case 1 /* reset */: + this.reset(); + // Fall through. + case 2 /* update */: + const skeleton = this.skeleton; + const delta = Math.max(this.skeleton.time - this.lastTime, 0); + this.remaining += delta; + this.lastTime = skeleton.time; + const bx = bone.worldX, by = bone.worldY; + if (this._reset) { + this._reset = false; + this.ux = bx; + this.uy = by; + } else { + let a = this.remaining, i = this.inertia, t = this.data.step, f = this.skeleton.data.referenceScale, d = -1; + let qx = this.data.limit * delta, qy = qx * Math.abs(skeleton.scaleY); + qx *= Math.abs(skeleton.scaleX); + if (x || y) { + if (x) { + const u = (this.ux - bx) * i; + this.xOffset += u > qx ? qx : u < -qx ? -qx : u; + this.ux = bx; + } + if (y) { + const u = (this.uy - by) * i; + this.yOffset += u > qy ? qy : u < -qy ? -qy : u; + this.uy = by; + } + if (a >= t) { + d = Math.pow(this.damping, 60 * t); + const m = this.massInverse * t, e = this.strength, w = this.wind * f * skeleton.scaleX, g = this.gravity * f * skeleton.scaleY; + do { + if (x) { + this.xVelocity += (w - this.xOffset * e) * m; + this.xOffset += this.xVelocity * t; + this.xVelocity *= d; + } + if (y) { + this.yVelocity -= (g + this.yOffset * e) * m; + this.yOffset += this.yVelocity * t; + this.yVelocity *= d; + } + a -= t; + } while (a >= t); + } + if (x) bone.worldX += this.xOffset * mix * this.data.x; + if (y) bone.worldY += this.yOffset * mix * this.data.y; + } + if (rotateOrShearX || scaleX) { + let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0; + let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY; + if (dx > qx) + dx = qx; + else if (dx < -qx) + dx = -qx; + if (dy > qy) + dy = qy; + else if (dy < -qy) + dy = -qy; + if (rotateOrShearX) { + mr = (this.data.rotate + this.data.shearX) * mix; + let r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr; + this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i; + r = this.rotateOffset * mr + ca; + c = Math.cos(r); + s = Math.sin(r); + if (scaleX) { + r = l * bone.getWorldScaleX(); + if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r; + } + } else { + c = Math.cos(ca); + s = Math.sin(ca); + const r = l * bone.getWorldScaleX(); + if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r; + } + a = this.remaining; + if (a >= t) { + if (d == -1) d = Math.pow(this.damping, 60 * t); + const m = this.massInverse * t, e = this.strength, w = this.wind, g = Skeleton.yDown ? -this.gravity : this.gravity, h = l / f; + while (true) { + a -= t; + if (scaleX) { + this.scaleVelocity += (w * c - g * s - this.scaleOffset * e) * m; + this.scaleOffset += this.scaleVelocity * t; + this.scaleVelocity *= d; + } + if (rotateOrShearX) { + this.rotateVelocity -= ((w * s + g * c) * h + this.rotateOffset * e) * m; + this.rotateOffset += this.rotateVelocity * t; + this.rotateVelocity *= d; + if (a < t) break; + const r = this.rotateOffset * mr + ca; + c = Math.cos(r); + s = Math.sin(r); + } else if (a < t) + break; + } + } + } + this.remaining = a; + } + this.cx = bone.worldX; + this.cy = bone.worldY; + break; + case 3 /* pose */: + if (x) bone.worldX += this.xOffset * mix * this.data.x; + if (y) bone.worldY += this.yOffset * mix * this.data.y; + } + if (rotateOrShearX) { + let o = this.rotateOffset * mix, s = 0, c = 0, a = 0; + if (this.data.shearX > 0) { + let r = 0; + if (this.data.rotate > 0) { + r = o * this.data.rotate; + s = Math.sin(r); + c = Math.cos(r); + a = bone.b; + bone.b = c * a - s * bone.d; + bone.d = s * a + c * bone.d; + } + r += o * this.data.shearX; + s = Math.sin(r); + c = Math.cos(r); + a = bone.a; + bone.a = c * a - s * bone.c; + bone.c = s * a + c * bone.c; + } else { + o *= this.data.rotate; + s = Math.sin(o); + c = Math.cos(o); + a = bone.a; + bone.a = c * a - s * bone.c; + bone.c = s * a + c * bone.c; + a = bone.b; + bone.b = c * a - s * bone.d; + bone.d = s * a + c * bone.d; + } + } + if (scaleX) { + const s = 1 + this.scaleOffset * mix * this.data.scaleX; + bone.a *= s; + bone.c *= s; + } + if (physics != 3 /* pose */) { + this.tx = l * bone.a; + this.ty = l * bone.c; + } + bone.updateAppliedTransform(); + } + /** Translates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone moved an additional + * amount in world space. */ + translate(x, y) { + this.ux -= x; + this.uy -= y; + this.cx -= x; + this.cy -= y; + } + /** Rotates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone rotated around the + * specified point in world space. */ + rotate(x, y, degrees) { + const r = degrees * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r); + const dx = this.cx - x, dy = this.cy - y; + this.translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy); + } + }; + + // spine-core/src/Slot.ts + var Slot = class { + /** The slot's setup pose data. */ + data; + /** The bone this slot belongs to. */ + bone; + /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two + * color tinting. */ + color; + /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark + * color's alpha is not used. */ + darkColor = null; + attachment = null; + attachmentState = 0; + /** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the + * {@link Sequence#getSetupIndex()}. */ + sequenceIndex = -1; + /** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a + * weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. + * + * See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */ + deform = new Array(); + constructor(data, bone) { + if (!data) throw new Error("data cannot be null."); + if (!bone) throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new Color(); + this.darkColor = !data.darkColor ? null : new Color(); + this.setToSetupPose(); + } + /** The skeleton this slot belongs to. */ + getSkeleton() { + return this.bone.skeleton; + } + /** The current attachment for the slot, or null if the slot has no attachment. */ + getAttachment() { + return this.attachment; + } + /** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}. + * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the + * specified attachment. */ + setAttachment(attachment) { + if (this.attachment == attachment) return; + if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment) || attachment.timelineAttachment != this.attachment.timelineAttachment) { + this.deform.length = 0; + } + this.attachment = attachment; + this.sequenceIndex = -1; + } + /** Sets this slot to the setup pose. */ + setToSetupPose() { + this.color.setFromColor(this.data.color); + if (this.darkColor) this.darkColor.setFromColor(this.data.darkColor); + if (!this.data.attachmentName) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + } + }; + + // spine-core/src/TransformConstraint.ts + var TransformConstraint = class { + /** The transform constraint's setup pose data. */ + data; + /** The bones that will be modified by this transform constraint. */ + bones; + /** The target bone whose world transform will be copied to the constrained bones. */ + target; + mixRotate = 0; + mixX = 0; + mixY = 0; + mixScaleX = 0; + mixScaleY = 0; + mixShearY = 0; + temp = new Vector2(); + active = false; + constructor(data, skeleton) { + if (!data) throw new Error("data cannot be null."); + if (!skeleton) throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let bone = skeleton.findBone(data.bones[i].name); + if (!bone) throw new Error(`Couldn't find bone ${data.bones[i].name}.`); + this.bones.push(bone); + } + let target = skeleton.findBone(data.target.name); + if (!target) throw new Error(`Couldn't find target bone ${data.target.name}.`); + this.target = target; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + this.mixScaleX = data.mixScaleX; + this.mixScaleY = data.mixScaleY; + this.mixShearY = data.mixShearY; + } + isActive() { + return this.active; + } + setToSetupPose() { + const data = this.data; + this.mixRotate = data.mixRotate; + this.mixX = data.mixX; + this.mixY = data.mixY; + this.mixScaleX = data.mixScaleX; + this.mixScaleY = data.mixScaleY; + this.mixShearY = data.mixShearY; + } + update(physics) { + if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleY == 0 && this.mixShearY == 0) return; + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + } + applyAbsoluteWorld() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let translate = mixX != 0 || mixY != 0; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect; + let offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (mixRotate != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= mixRotate; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + if (translate) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += (temp.x - bone.worldX) * mixX; + bone.worldY += (temp.y - bone.worldY) * mixY; + } + if (mixScaleX != 0) { + let s = Math.sqrt(bone.a * bone.a + bone.c * bone.c); + if (s != 0) s = (s + (Math.sqrt(ta * ta + tc * tc) - s + this.data.offsetScaleX) * mixScaleX) / s; + bone.a *= s; + bone.c *= s; + } + if (mixScaleY != 0) { + let s = Math.sqrt(bone.b * bone.b + bone.d * bone.d); + if (s != 0) s = (s + (Math.sqrt(tb * tb + td * td) - s + this.data.offsetScaleY) * mixScaleY) / s; + bone.b *= s; + bone.d *= s; + } + if (mixShearY > 0) { + let b = bone.b, d = bone.d; + let by = Math.atan2(d, b); + let r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a)); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r = by + (r + offsetShearY) * mixShearY; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + } + bone.updateAppliedTransform(); + } + } + applyRelativeWorld() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let translate = mixX != 0 || mixY != 0; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (mixRotate != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) + offsetRotation; + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + r *= mixRotate; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + if (translate) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += temp.x * mixX; + bone.worldY += temp.y * mixY; + } + if (mixScaleX != 0) { + let s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * mixScaleX + 1; + bone.a *= s; + bone.c *= s; + } + if (mixScaleY != 0) { + let s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * mixScaleY + 1; + bone.b *= s; + bone.d *= s; + } + if (mixShearY > 0) { + let r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > MathUtils.PI) + r -= MathUtils.PI2; + else if (r < -MathUtils.PI) + r += MathUtils.PI2; + let b = bone.b, d = bone.d; + r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * mixShearY; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + } + bone.updateAppliedTransform(); + } + } + applyAbsoluteLocal() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let target = this.target; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let rotation = bone.arotation; + if (mixRotate != 0) rotation += (target.arotation - rotation + this.data.offsetRotation) * mixRotate; + let x = bone.ax, y = bone.ay; + x += (target.ax - x + this.data.offsetX) * mixX; + y += (target.ay - y + this.data.offsetY) * mixY; + let scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (mixScaleX != 0 && scaleX != 0) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * mixScaleX) / scaleX; + if (mixScaleY != 0 && scaleY != 0) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * mixScaleY) / scaleY; + let shearY = bone.ashearY; + if (mixShearY != 0) shearY += (target.ashearY - shearY + this.data.offsetShearY) * mixShearY; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + applyRelativeLocal() { + let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + let target = this.target; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let rotation = bone.arotation + (target.arotation + this.data.offsetRotation) * mixRotate; + let x = bone.ax + (target.ax + this.data.offsetX) * mixX; + let y = bone.ay + (target.ay + this.data.offsetY) * mixY; + let scaleX = bone.ascaleX * ((target.ascaleX - 1 + this.data.offsetScaleX) * mixScaleX + 1); + let scaleY = bone.ascaleY * ((target.ascaleY - 1 + this.data.offsetScaleY) * mixScaleY + 1); + let shearY = bone.ashearY + (target.ashearY + this.data.offsetShearY) * mixShearY; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + }; + + // spine-core/src/Skeleton.ts + var Skeleton = class _Skeleton { + static quadTriangles = [0, 1, 2, 2, 3, 0]; + static yDown = false; + /** The skeleton's setup pose data. */ + data; + /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ + bones; + /** The skeleton's slots in the setup pose draw order. */ + slots; + /** The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. */ + drawOrder; + /** The skeleton's IK constraints. */ + ikConstraints; + /** The skeleton's transform constraints. */ + transformConstraints; + /** The skeleton's path constraints. */ + pathConstraints; + /** The skeleton's physics constraints. */ + physicsConstraints; + /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */ + _updateCache = new Array(); + /** The skeleton's current skin. May be null. */ + skin = null; + /** The color to tint all the skeleton's attachments. */ + color; + /** Scales the entire skeleton on the X axis. This affects all bones, even if the bone's transform mode disallows scale + * inheritance. */ + scaleX = 1; + /** Scales the entire skeleton on the Y axis. This affects all bones, even if the bone's transform mode disallows scale + * inheritance. */ + _scaleY = 1; + get scaleY() { + return _Skeleton.yDown ? -this._scaleY : this._scaleY; + } + set scaleY(scaleY) { + this._scaleY = scaleY; + } + /** Sets the skeleton X position, which is added to the root bone worldX position. */ + x = 0; + /** Sets the skeleton Y position, which is added to the root bone worldY position. */ + y = 0; + /** Returns the skeleton's time. This is used for time-based manipulations, such as {@link PhysicsConstraint}. + *

+ * See {@link #update(float)}. */ + time = 0; + constructor(data) { + if (!data) throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let boneData = data.bones[i]; + let bone; + if (!boneData.parent) + bone = new Bone(boneData, this, null); + else { + let parent = this.bones[boneData.parent.index]; + bone = new Bone(boneData, this, parent); + parent.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (let i = 0; i < data.slots.length; i++) { + let slotData = data.slots[i]; + let bone = this.bones[slotData.boneData.index]; + let slot = new Slot(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (let i = 0; i < data.ikConstraints.length; i++) { + let ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new IkConstraint(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (let i = 0; i < data.transformConstraints.length; i++) { + let transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new TransformConstraint(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (let i = 0; i < data.pathConstraints.length; i++) { + let pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new PathConstraint(pathConstraintData, this)); + } + this.physicsConstraints = new Array(); + for (let i = 0; i < data.physicsConstraints.length; i++) { + let physicsConstraintData = data.physicsConstraints[i]; + this.physicsConstraints.push(new PhysicsConstraint(physicsConstraintData, this)); + } + this.color = new Color(1, 1, 1, 1); + this.updateCache(); + } + /** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones, + * constraints, or weighted path attachments are added or removed. */ + updateCache() { + let updateCache = this._updateCache; + updateCache.length = 0; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (this.skin) { + let skinBones = this.skin.bones; + for (let i = 0, n = this.skin.bones.length; i < n; i++) { + let bone = this.bones[skinBones[i].index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone); + } + } + let ikConstraints = this.ikConstraints; + let transformConstraints = this.transformConstraints; + let pathConstraints = this.pathConstraints; + let physicsConstraints = this.physicsConstraints; + let ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length, physicsCount = this.physicsConstraints.length; + let constraintCount = ikCount + transformCount + pathCount + physicsCount; + outer: + for (let i = 0; i < constraintCount; i++) { + for (let ii = 0; ii < ikCount; ii++) { + let constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < transformCount; ii++) { + let constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < pathCount; ii++) { + let constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < physicsCount; ii++) { + const constraint = physicsConstraints[ii]; + if (constraint.data.order == i) { + this.sortPhysicsConstraint(constraint); + continue outer; + } + } + } + for (let i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + } + sortIkConstraint(constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || this.skin && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + let target = constraint.target; + this.sortBone(target); + let constrained = constraint.bones; + let parent = constrained[0]; + this.sortBone(parent); + if (constrained.length == 1) { + this._updateCache.push(constraint); + this.sortReset(parent.children); + } else { + let child = constrained[constrained.length - 1]; + this.sortBone(child); + this._updateCache.push(constraint); + this.sortReset(parent.children); + child.sorted = true; + } + } + sortPathConstraint(constraint) { + constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || this.skin && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + let slot = constraint.target; + let slotIndex = slot.data.index; + let slotBone = slot.bone; + if (this.skin) this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (let i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + let attachment = slot.getAttachment(); + if (attachment instanceof PathAttachment) this.sortPathConstraintAttachmentWith(attachment, slotBone); + let constrained = constraint.bones; + let boneCount = constrained.length; + for (let i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (let i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (let i = 0; i < boneCount; i++) + constrained[i].sorted = true; + } + sortTransformConstraint(constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || this.skin && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + this.sortBone(constraint.target); + let constrained = constraint.bones; + let boneCount = constrained.length; + if (constraint.data.local) { + for (let i = 0; i < boneCount; i++) { + let child = constrained[i]; + this.sortBone(child.parent); + this.sortBone(child); + } + } else { + for (let i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (let i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (let i = 0; i < boneCount; i++) + constrained[i].sorted = true; + } + sortPathConstraintAttachment(skin, slotIndex, slotBone) { + let attachments = skin.attachments[slotIndex]; + if (!attachments) return; + for (let key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + } + sortPathConstraintAttachmentWith(attachment, slotBone) { + if (!(attachment instanceof PathAttachment)) return; + let pathBones = attachment.bones; + if (!pathBones) + this.sortBone(slotBone); + else { + let bones = this.bones; + for (let i = 0, n = pathBones.length; i < n; ) { + let nn = pathBones[i++]; + nn += i; + while (i < nn) + this.sortBone(bones[pathBones[i++]]); + } + } + } + sortPhysicsConstraint(constraint) { + const bone = constraint.bone; + constraint.active = bone.active && (!constraint.data.skinRequired || this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)); + if (!constraint.active) return; + this.sortBone(bone); + this._updateCache.push(constraint); + this.sortReset(bone.children); + bone.sorted = true; + } + sortBone(bone) { + if (!bone) return; + if (bone.sorted) return; + let parent = bone.parent; + if (parent) this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + } + sortReset(bones) { + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.active) continue; + if (bone.sorted) this.sortReset(bone.children); + bone.sorted = false; + } + } + /** Updates the world transform for each bone and applies all constraints. + * + * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + * Runtimes Guide. */ + updateWorldTransform(physics) { + if (physics === void 0 || physics === null) throw new Error("physics is undefined"); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + } + let updateCache = this._updateCache; + for (let i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(physics); + } + updateWorldTransformWith(physics, parent) { + if (!parent) throw new Error("parent cannot be null."); + let bones = this.bones; + for (let i = 1, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + } + let rootBone = this.getRootBone(); + if (!rootBone) throw new Error("Root bone must not be null."); + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + rootBone.worldX = pa * this.x + pb * this.y + parent.worldX; + rootBone.worldY = pc * this.x + pd * this.y + parent.worldY; + const rx = (rootBone.rotation + rootBone.shearX) * MathUtils.degRad; + const ry = (rootBone.rotation + 90 + rootBone.shearY) * MathUtils.degRad; + const la = Math.cos(rx) * rootBone.scaleX; + const lb = Math.cos(ry) * rootBone.scaleY; + const lc = Math.sin(rx) * rootBone.scaleX; + const ld = Math.sin(ry) * rootBone.scaleY; + rootBone.a = (pa * la + pb * lc) * this.scaleX; + rootBone.b = (pa * lb + pb * ld) * this.scaleX; + rootBone.c = (pc * la + pd * lc) * this.scaleY; + rootBone.d = (pc * lb + pd * ld) * this.scaleY; + let updateCache = this._updateCache; + for (let i = 0, n = updateCache.length; i < n; i++) { + let updatable = updateCache[i]; + if (updatable != rootBone) updatable.update(physics); + } + } + /** Sets the bones, constraints, and slots to their setup pose values. */ + setToSetupPose() { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + } + /** Sets the bones and constraints to their setup pose values. */ + setBonesToSetupPose() { + for (const bone of this.bones) bone.setToSetupPose(); + for (const constraint of this.ikConstraints) constraint.setToSetupPose(); + for (const constraint of this.transformConstraints) constraint.setToSetupPose(); + for (const constraint of this.pathConstraints) constraint.setToSetupPose(); + for (const constraint of this.physicsConstraints) constraint.setToSetupPose(); + } + /** Sets the slots and draw order to their setup pose values. */ + setSlotsToSetupPose() { + let slots = this.slots; + Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (let i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + } + /** @returns May return null. */ + getRootBone() { + if (this.bones.length == 0) return null; + return this.bones[0]; + } + /** @returns May be null. */ + findBone(boneName) { + if (!boneName) throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.data.name == boneName) return bone; + } + return null; + } + /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it + * repeatedly. + * @returns May be null. */ + findSlot(slotName) { + if (!slotName) throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) return slot; + } + return null; + } + /** Sets a skin by name. + * + * See {@link #setSkin()}. */ + setSkinByName(skinName) { + let skin = this.data.findSkin(skinName); + if (!skin) throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + } + /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#defaultSkin default skin}. If the + * skin is changed, {@link #updateCache()} is called. + * + * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no + * old skin, each slot's setup mode attachment is attached from the new skin. + * + * After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling + * {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the + * skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. + * @param newSkin May be null. */ + setSkin(newSkin) { + if (newSkin == this.skin) return; + if (newSkin) { + if (this.skin) + newSkin.attachAll(this, this.skin); + else { + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + let name = slot.data.attachmentName; + if (name) { + let attachment = newSkin.getAttachment(i, name); + if (attachment) slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + this.updateCache(); + } + /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment + * name. + * + * See {@link #getAttachment()}. + * @returns May be null. */ + getAttachmentByName(slotName, attachmentName) { + let slot = this.data.findSlot(slotName); + if (!slot) throw new Error(`Can't find slot with name ${slotName}`); + return this.getAttachment(slot.index, attachmentName); + } + /** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and + * attachment name. First the skin is checked and if the attachment was not found, the default skin is checked. + * + * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. + * @returns May be null. */ + getAttachment(slotIndex, attachmentName) { + if (!attachmentName) throw new Error("attachmentName cannot be null."); + if (this.skin) { + let attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment) return attachment; + } + if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + } + /** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with + * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}. + * @param attachmentName May be null to clear the slot's attachment. */ + setAttachment(slotName, attachmentName) { + if (!slotName) throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) { + let attachment = null; + if (attachmentName) { + attachment = this.getAttachment(i, attachmentName); + if (!attachment) throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + } + /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method + * than to call it repeatedly. + * @return May be null. */ + findIkConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + return this.ikConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of + * this method than to call it repeatedly. + * @return May be null. */ + findTransformConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + return this.transformConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method + * than to call it repeatedly. + * @return May be null. */ + findPathConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + return this.pathConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this + * method than to call it repeatedly. */ + findPhysicsConstraint(constraintName) { + if (constraintName == null) throw new Error("constraintName cannot be null."); + return this.physicsConstraints.find((constraint) => constraint.data.name == constraintName) ?? null; + } + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose as `{ x: number, y: number, width: number, height: number }`. + * Note that this method will create temporary objects which can add to garbage collection pressure. Use `getBounds()` if garbage collection is a concern. */ + getBoundsRect(clipper) { + let offset = new Vector2(); + let size = new Vector2(); + this.getBounds(offset, size, void 0, clipper); + return { x: offset.x, y: offset.y, width: size.x, height: size.y }; + } + /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB. + * @param size An output value, the width and height of the AABB. + * @param temp Working memory to temporarily store attachments' computed world vertices. + * @param clipper {@link SkeletonClipping} to use. If null, no clipping is applied. */ + getBounds(offset, size, temp = new Array(2), clipper = null) { + if (!offset) throw new Error("offset cannot be null."); + if (!size) throw new Error("size cannot be null."); + let drawOrder = this.drawOrder; + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + if (!slot.bone.active) continue; + let verticesLength = 0; + let vertices = null; + let triangles = null; + let attachment = slot.getAttachment(); + if (attachment instanceof RegionAttachment) { + verticesLength = 8; + vertices = Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot, vertices, 0, 2); + triangles = _Skeleton.quadTriangles; + } else if (attachment instanceof MeshAttachment) { + let mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + triangles = mesh.triangles; + } else if (attachment instanceof ClippingAttachment && clipper != null) { + clipper.clipStart(slot, attachment); + continue; + } + if (vertices && triangles) { + if (clipper != null && clipper.isClipping()) { + clipper.clipTriangles(vertices, triangles, triangles.length); + vertices = clipper.clippedVertices; + verticesLength = clipper.clippedVertices.length; + } + for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) { + let x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + if (clipper != null) clipper.clipEndWithSlot(slot); + } + if (clipper != null) clipper.clipEnd(); + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + } + /** Increments the skeleton's {@link #time}. */ + update(delta) { + this.time += delta; + } + physicsTranslate(x, y) { + const physicsConstraints = this.physicsConstraints; + for (let i = 0, n = physicsConstraints.length; i < n; i++) + physicsConstraints[i].translate(x, y); + } + /** Calls {@link PhysicsConstraint#rotate(float, float, float)} for each physics constraint. */ + physicsRotate(x, y, degrees) { + const physicsConstraints = this.physicsConstraints; + for (let i = 0, n = physicsConstraints.length; i < n; i++) + physicsConstraints[i].rotate(x, y, degrees); + } + }; + var Physics = /* @__PURE__ */ ((Physics2) => { + Physics2[Physics2["none"] = 0] = "none"; + Physics2[Physics2["reset"] = 1] = "reset"; + Physics2[Physics2["update"] = 2] = "update"; + Physics2[Physics2["pose"] = 3] = "pose"; + return Physics2; + })(Physics || {}); + + // spine-core/src/PhysicsConstraintData.ts + var PhysicsConstraintData = class extends ConstraintData { + _bone = null; + /** The bone constrained by this physics constraint. */ + set bone(boneData) { + this._bone = boneData; + } + get bone() { + if (!this._bone) throw new Error("BoneData not set."); + else return this._bone; + } + x = 0; + y = 0; + rotate = 0; + scaleX = 0; + shearX = 0; + limit = 0; + step = 0; + inertia = 0; + strength = 0; + damping = 0; + massInverse = 0; + wind = 0; + gravity = 0; + /** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */ + mix = 0; + inertiaGlobal = false; + strengthGlobal = false; + dampingGlobal = false; + massGlobal = false; + windGlobal = false; + gravityGlobal = false; + mixGlobal = false; + constructor(name) { + super(name, 0, false); + } + }; + + // spine-core/src/SkeletonData.ts + var SkeletonData = class { + /** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */ + name = null; + /** The skeleton's bones, sorted parent first. The root bone is always the first bone. */ + bones = new Array(); + // Ordered parents first. + /** The skeleton's slots in the setup pose draw order. */ + slots = new Array(); + // Setup pose draw order. + skins = new Array(); + /** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine. + * + * See {@link Skeleton#getAttachmentByName()}. + * May be null. */ + defaultSkin = null; + /** The skeleton's events. */ + events = new Array(); + /** The skeleton's animations. */ + animations = new Array(); + /** The skeleton's IK constraints. */ + ikConstraints = new Array(); + /** The skeleton's transform constraints. */ + transformConstraints = new Array(); + /** The skeleton's path constraints. */ + pathConstraints = new Array(); + /** The skeleton's physics constraints. */ + physicsConstraints = new Array(); + /** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + x = 0; + /** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */ + y = 0; + /** The width of the skeleton's axis aligned bounding box in the setup pose. */ + width = 0; + /** The height of the skeleton's axis aligned bounding box in the setup pose. */ + height = 0; + /** Baseline scale factor for applying distance-dependent effects on non-scalable properties, such as angle or scale. Default + * is 100. */ + referenceScale = 100; + /** The Spine version used to export the skeleton data, or null. */ + version = null; + /** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */ + hash = null; + // Nonessential + /** The dopesheet FPS in Spine. Available only when nonessential data was exported. */ + fps = 0; + /** The path to the images directory as defined in Spine. Available only when nonessential data was exported. May be null. */ + imagesPath = null; + /** The path to the audio directory as defined in Spine. Available only when nonessential data was exported. May be null. */ + audioPath = null; + /** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findBone(boneName) { + if (!boneName) throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.name == boneName) return bone; + } + return null; + } + /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findSlot(slotName) { + if (!slotName) throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.name == slotName) return slot; + } + return null; + } + /** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findSkin(skinName) { + if (!skinName) throw new Error("skinName cannot be null."); + let skins = this.skins; + for (let i = 0, n = skins.length; i < n; i++) { + let skin = skins[i]; + if (skin.name == skinName) return skin; + } + return null; + } + /** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it + * multiple times. + * @returns May be null. */ + findEvent(eventDataName) { + if (!eventDataName) throw new Error("eventDataName cannot be null."); + let events = this.events; + for (let i = 0, n = events.length; i < n; i++) { + let event = events[i]; + if (event.name == eventDataName) return event; + } + return null; + } + /** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to + * call it multiple times. + * @returns May be null. */ + findAnimation(animationName) { + if (!animationName) throw new Error("animationName cannot be null."); + let animations = this.animations; + for (let i = 0, n = animations.length; i < n; i++) { + let animation = animations[i]; + if (animation.name == animationName) return animation; + } + return null; + } + /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method + * than to call it multiple times. + * @return May be null. */ + findIkConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + const constraint = ikConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of + * this method than to call it multiple times. + * @return May be null. */ + findTransformConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + const constraint = transformConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method + * than to call it multiple times. + * @return May be null. */ + findPathConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + const constraint = pathConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + /** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this method + * than to call it multiple times. + * @return May be null. */ + findPhysicsConstraint(constraintName) { + if (!constraintName) throw new Error("constraintName cannot be null."); + const physicsConstraints = this.physicsConstraints; + for (let i = 0, n = physicsConstraints.length; i < n; i++) { + const constraint = physicsConstraints[i]; + if (constraint.name == constraintName) return constraint; + } + return null; + } + }; + + // spine-core/src/Skin.ts + var SkinEntry = class { + constructor(slotIndex = 0, name, attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + } + }; + var Skin = class { + /** The skin's name, which is unique across all skins in the skeleton. */ + name; + attachments = new Array(); + bones = Array(); + constraints = new Array(); + /** The color of the skin as it was in Spine, or a default color if nonessential data was not exported. */ + color = new Color(0.99607843, 0.61960787, 0.30980393, 1); + // fe9e4fff + constructor(name) { + if (!name) throw new Error("name cannot be null."); + this.name = name; + } + /** Adds an attachment to the skin for the specified slot index and name. */ + setAttachment(slotIndex, name, attachment) { + if (!attachment) throw new Error("attachment cannot be null."); + let attachments = this.attachments; + if (slotIndex >= attachments.length) attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + } + /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ + addSkin(skin) { + for (let i = 0; i < skin.bones.length; i++) { + let bone = skin.bones[i]; + let contained = false; + for (let ii = 0; ii < this.bones.length; ii++) { + if (this.bones[ii] == bone) { + contained = true; + break; + } + } + if (!contained) this.bones.push(bone); + } + for (let i = 0; i < skin.constraints.length; i++) { + let constraint = skin.constraints[i]; + let contained = false; + for (let ii = 0; ii < this.constraints.length; ii++) { + if (this.constraints[ii] == constraint) { + contained = true; + break; + } + } + if (!contained) this.constraints.push(constraint); + } + let attachments = skin.getAttachments(); + for (let i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + /** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not + * copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */ + copySkin(skin) { + for (let i = 0; i < skin.bones.length; i++) { + let bone = skin.bones[i]; + let contained = false; + for (let ii = 0; ii < this.bones.length; ii++) { + if (this.bones[ii] == bone) { + contained = true; + break; + } + } + if (!contained) this.bones.push(bone); + } + for (let i = 0; i < skin.constraints.length; i++) { + let constraint = skin.constraints[i]; + let contained = false; + for (let ii = 0; ii < this.constraints.length; ii++) { + if (this.constraints[ii] == constraint) { + contained = true; + break; + } + } + if (!contained) this.constraints.push(constraint); + } + let attachments = skin.getAttachments(); + for (let i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + if (!attachment.attachment) continue; + if (attachment.attachment instanceof MeshAttachment) { + attachment.attachment = attachment.attachment.newLinkedMesh(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } else { + attachment.attachment = attachment.attachment.copy(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + } + /** Returns the attachment for the specified slot index and name, or null. */ + getAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + } + /** Removes the attachment in the skin for the specified slot index and name, if any. */ + removeAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + if (dictionary) delete dictionary[name]; + } + /** Returns all attachments in this skin. */ + getAttachments() { + let entries = new Array(); + for (var i = 0; i < this.attachments.length; i++) { + let slotAttachments = this.attachments[i]; + if (slotAttachments) { + for (let name in slotAttachments) { + let attachment = slotAttachments[name]; + if (attachment) entries.push(new SkinEntry(i, name, attachment)); + } + } + } + return entries; + } + /** Returns all attachments in this skin for the specified slot index. */ + getAttachmentsForSlot(slotIndex, attachments) { + let slotAttachments = this.attachments[slotIndex]; + if (slotAttachments) { + for (let name in slotAttachments) { + let attachment = slotAttachments[name]; + if (attachment) attachments.push(new SkinEntry(slotIndex, name, attachment)); + } + } + } + /** Clears all attachments, bones, and constraints. */ + clear() { + this.attachments.length = 0; + this.bones.length = 0; + this.constraints.length = 0; + } + /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ + attachAll(skeleton, oldSkin) { + let slotIndex = 0; + for (let i = 0; i < skeleton.slots.length; i++) { + let slot = skeleton.slots[i]; + let slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + let dictionary = oldSkin.attachments[slotIndex]; + for (let key in dictionary) { + let skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + let attachment = this.getAttachment(slotIndex, key); + if (attachment) slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + } + }; + + // spine-core/src/SlotData.ts + var SlotData = class { + /** The index of the slot in {@link Skeleton#getSlots()}. */ + index = 0; + /** The name of the slot, which is unique across all slots in the skeleton. */ + name; + /** The bone this slot belongs to. */ + boneData; + /** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two + * color tinting. */ + color = new Color(1, 1, 1, 1); + /** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark + * color's alpha is not used. */ + darkColor = null; + /** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */ + attachmentName = null; + /** The blend mode for drawing the slot's attachment. */ + blendMode = 0 /* Normal */; + /** False if the slot was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */ + visible = true; + constructor(index, name, boneData) { + if (index < 0) throw new Error("index must be >= 0."); + if (!name) throw new Error("name cannot be null."); + if (!boneData) throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + }; + var BlendMode = /* @__PURE__ */ ((BlendMode3) => { + BlendMode3[BlendMode3["Normal"] = 0] = "Normal"; + BlendMode3[BlendMode3["Additive"] = 1] = "Additive"; + BlendMode3[BlendMode3["Multiply"] = 2] = "Multiply"; + BlendMode3[BlendMode3["Screen"] = 3] = "Screen"; + return BlendMode3; + })(BlendMode || {}); + + // spine-core/src/TransformConstraintData.ts + var TransformConstraintData = class extends ConstraintData { + /** The bones that will be modified by this transform constraint. */ + bones = new Array(); + /** The target bone whose world transform will be copied to the constrained bones. */ + _target = null; + set target(boneData) { + this._target = boneData; + } + get target() { + if (!this._target) throw new Error("BoneData not set."); + else return this._target; + } + mixRotate = 0; + mixX = 0; + mixY = 0; + mixScaleX = 0; + mixScaleY = 0; + mixShearY = 0; + /** An offset added to the constrained bone rotation. */ + offsetRotation = 0; + /** An offset added to the constrained bone X translation. */ + offsetX = 0; + /** An offset added to the constrained bone Y translation. */ + offsetY = 0; + /** An offset added to the constrained bone scaleX. */ + offsetScaleX = 0; + /** An offset added to the constrained bone scaleY. */ + offsetScaleY = 0; + /** An offset added to the constrained bone shearY. */ + offsetShearY = 0; + relative = false; + local = false; + constructor(name) { + super(name, 0, false); + } + }; + + // spine-core/src/SkeletonBinary.ts + var SkeletonBinary = class { + /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at + * runtime than were used in Spine. + * + * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ + scale = 1; + attachmentLoader; + linkedMeshes = new Array(); + constructor(attachmentLoader) { + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(binary) { + let scale = this.scale; + let skeletonData = new SkeletonData(); + skeletonData.name = ""; + let input = new BinaryInput(binary); + let lowHash = input.readInt32(); + let highHash = input.readInt32(); + skeletonData.hash = highHash == 0 && lowHash == 0 ? null : highHash.toString(16) + lowHash.toString(16); + skeletonData.version = input.readString(); + skeletonData.x = input.readFloat(); + skeletonData.y = input.readFloat(); + skeletonData.width = input.readFloat(); + skeletonData.height = input.readFloat(); + skeletonData.referenceScale = input.readFloat() * scale; + let nonessential = input.readBoolean(); + if (nonessential) { + skeletonData.fps = input.readFloat(); + skeletonData.imagesPath = input.readString(); + skeletonData.audioPath = input.readString(); + } + let n = 0; + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let str = input.readString(); + if (!str) throw new Error("String in string table must not be null."); + input.strings.push(str); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("Bone name must not be null."); + let parent = i == 0 ? null : skeletonData.bones[input.readInt(true)]; + let data = new BoneData(i, name, parent); + data.rotation = input.readFloat(); + data.x = input.readFloat() * scale; + data.y = input.readFloat() * scale; + data.scaleX = input.readFloat(); + data.scaleY = input.readFloat(); + data.shearX = input.readFloat(); + data.shearY = input.readFloat(); + data.length = input.readFloat() * scale; + data.inherit = input.readByte(); + data.skinRequired = input.readBoolean(); + if (nonessential) { + Color.rgba8888ToColor(data.color, input.readInt32()); + data.icon = input.readString() ?? void 0; + data.visible = input.readBoolean(); + } + skeletonData.bones.push(data); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let slotName = input.readString(); + if (!slotName) throw new Error("Slot name must not be null."); + let boneData = skeletonData.bones[input.readInt(true)]; + let data = new SlotData(i, slotName, boneData); + Color.rgba8888ToColor(data.color, input.readInt32()); + let darkColor = input.readInt32(); + if (darkColor != -1) Color.rgb888ToColor(data.darkColor = new Color(), darkColor); + data.attachmentName = input.readStringRef(); + data.blendMode = input.readInt(true); + if (nonessential) data.visible = input.readBoolean(); + skeletonData.slots.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("IK constraint data name must not be null."); + let data = new IkConstraintData(name); + data.order = input.readInt(true); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + let flags = input.readByte(); + data.skinRequired = (flags & 1) != 0; + data.bendDirection = (flags & 2) != 0 ? 1 : -1; + data.compress = (flags & 4) != 0; + data.stretch = (flags & 8) != 0; + data.uniform = (flags & 16) != 0; + if ((flags & 32) != 0) data.mix = (flags & 64) != 0 ? input.readFloat() : 1; + if ((flags & 128) != 0) data.softness = input.readFloat() * scale; + skeletonData.ikConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("Transform constraint data name must not be null."); + let data = new TransformConstraintData(name); + data.order = input.readInt(true); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + let flags = input.readByte(); + data.skinRequired = (flags & 1) != 0; + data.local = (flags & 2) != 0; + data.relative = (flags & 4) != 0; + if ((flags & 8) != 0) data.offsetRotation = input.readFloat(); + if ((flags & 16) != 0) data.offsetX = input.readFloat() * scale; + if ((flags & 32) != 0) data.offsetY = input.readFloat() * scale; + if ((flags & 64) != 0) data.offsetScaleX = input.readFloat(); + if ((flags & 128) != 0) data.offsetScaleY = input.readFloat(); + flags = input.readByte(); + if ((flags & 1) != 0) data.offsetShearY = input.readFloat(); + if ((flags & 2) != 0) data.mixRotate = input.readFloat(); + if ((flags & 4) != 0) data.mixX = input.readFloat(); + if ((flags & 8) != 0) data.mixY = input.readFloat(); + if ((flags & 16) != 0) data.mixScaleX = input.readFloat(); + if ((flags & 32) != 0) data.mixScaleY = input.readFloat(); + if ((flags & 64) != 0) data.mixShearY = input.readFloat(); + skeletonData.transformConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let name = input.readString(); + if (!name) throw new Error("Path constraint data name must not be null."); + let data = new PathConstraintData(name); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.slots[input.readInt(true)]; + const flags = input.readByte(); + data.positionMode = flags & 1; + data.spacingMode = flags >> 1 & 3; + data.rotateMode = flags >> 3 & 3; + if ((flags & 128) != 0) data.offsetRotation = input.readFloat(); + data.position = input.readFloat(); + if (data.positionMode == 0 /* Fixed */) data.position *= scale; + data.spacing = input.readFloat(); + if (data.spacingMode == 0 /* Length */ || data.spacingMode == 1 /* Fixed */) data.spacing *= scale; + data.mixRotate = input.readFloat(); + data.mixX = input.readFloat(); + data.mixY = input.readFloat(); + skeletonData.pathConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + const name = input.readString(); + if (!name) throw new Error("Physics constraint data name must not be null."); + const data = new PhysicsConstraintData(name); + data.order = input.readInt(true); + data.bone = skeletonData.bones[input.readInt(true)]; + let flags = input.readByte(); + data.skinRequired = (flags & 1) != 0; + if ((flags & 2) != 0) data.x = input.readFloat(); + if ((flags & 4) != 0) data.y = input.readFloat(); + if ((flags & 8) != 0) data.rotate = input.readFloat(); + if ((flags & 16) != 0) data.scaleX = input.readFloat(); + if ((flags & 32) != 0) data.shearX = input.readFloat(); + data.limit = ((flags & 64) != 0 ? input.readFloat() : 5e3) * scale; + data.step = 1 / input.readUnsignedByte(); + data.inertia = input.readFloat(); + data.strength = input.readFloat(); + data.damping = input.readFloat(); + data.massInverse = (flags & 128) != 0 ? input.readFloat() : 1; + data.wind = input.readFloat(); + data.gravity = input.readFloat(); + flags = input.readByte(); + if ((flags & 1) != 0) data.inertiaGlobal = true; + if ((flags & 2) != 0) data.strengthGlobal = true; + if ((flags & 4) != 0) data.dampingGlobal = true; + if ((flags & 8) != 0) data.massGlobal = true; + if ((flags & 16) != 0) data.windGlobal = true; + if ((flags & 32) != 0) data.gravityGlobal = true; + if ((flags & 64) != 0) data.mixGlobal = true; + data.mix = (flags & 128) != 0 ? input.readFloat() : 1; + skeletonData.physicsConstraints.push(data); + } + let defaultSkin = this.readSkin(input, skeletonData, true, nonessential); + if (defaultSkin) { + skeletonData.defaultSkin = defaultSkin; + skeletonData.skins.push(defaultSkin); + } + { + let i = skeletonData.skins.length; + Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); + for (; i < n; i++) { + let skin = this.readSkin(input, skeletonData, false, nonessential); + if (!skin) throw new Error("readSkin() should not have returned null."); + skeletonData.skins[i] = skin; + } + } + n = this.linkedMeshes.length; + for (let i = 0; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + const skin = skeletonData.skins[linkedMesh.skinIndex]; + if (!linkedMesh.parent) throw new Error("Linked mesh parent must not be null"); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (!parent) throw new Error(`Parent mesh not found: ${linkedMesh.parent}`); + linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent); + if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); + } + this.linkedMeshes.length = 0; + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let eventName = input.readString(); + if (!eventName) throw new Error("Event data name must not be null"); + let data = new EventData(eventName); + data.intValue = input.readInt(false); + data.floatValue = input.readFloat(); + data.stringValue = input.readString(); + data.audioPath = input.readString(); + if (data.audioPath) { + data.volume = input.readFloat(); + data.balance = input.readFloat(); + } + skeletonData.events.push(data); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let animationName = input.readString(); + if (!animationName) throw new Error("Animatio name must not be null."); + skeletonData.animations.push(this.readAnimation(input, animationName, skeletonData)); + } + return skeletonData; + } + readSkin(input, skeletonData, defaultSkin, nonessential) { + let skin = null; + let slotCount = 0; + if (defaultSkin) { + slotCount = input.readInt(true); + if (slotCount == 0) return null; + skin = new Skin("default"); + } else { + let skinName = input.readString(); + if (!skinName) throw new Error("Skin name must not be null."); + skin = new Skin(skinName); + if (nonessential) Color.rgba8888ToColor(skin.color, input.readInt32()); + skin.bones.length = input.readInt(true); + for (let i = 0, n = skin.bones.length; i < n; i++) + skin.bones[i] = skeletonData.bones[input.readInt(true)]; + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.physicsConstraints[input.readInt(true)]); + slotCount = input.readInt(true); + } + for (let i = 0; i < slotCount; i++) { + let slotIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let name = input.readStringRef(); + if (!name) + throw new Error("Attachment name must not be null"); + let attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name, nonessential); + if (attachment) skin.setAttachment(slotIndex, name, attachment); + } + } + return skin; + } + readAttachment(input, skeletonData, skin, slotIndex, attachmentName, nonessential) { + let scale = this.scale; + let flags = input.readByte(); + const name = (flags & 8) != 0 ? input.readStringRef() : attachmentName; + if (!name) throw new Error("Attachment name must not be null"); + switch (flags & 7) { + // BUG? + case 0 /* Region */: { + let path = (flags & 16) != 0 ? input.readStringRef() : null; + const color = (flags & 32) != 0 ? input.readInt32() : 4294967295; + const sequence = (flags & 64) != 0 ? this.readSequence(input) : null; + let rotation = (flags & 128) != 0 ? input.readFloat() : 0; + let x = input.readFloat(); + let y = input.readFloat(); + let scaleX = input.readFloat(); + let scaleY = input.readFloat(); + let width = input.readFloat(); + let height = input.readFloat(); + if (!path) path = name; + let region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); + if (!region) return null; + region.path = path; + region.x = x * scale; + region.y = y * scale; + region.scaleX = scaleX; + region.scaleY = scaleY; + region.rotation = rotation; + region.width = width * scale; + region.height = height * scale; + Color.rgba8888ToColor(region.color, color); + region.sequence = sequence; + if (sequence == null) region.updateRegion(); + return region; + } + case 1 /* BoundingBox */: { + let vertices = this.readVertices(input, (flags & 16) != 0); + let color = nonessential ? input.readInt32() : 0; + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (!box) return null; + box.worldVerticesLength = vertices.length; + box.vertices = vertices.vertices; + box.bones = vertices.bones; + if (nonessential) Color.rgba8888ToColor(box.color, color); + return box; + } + case 2 /* Mesh */: { + let path = (flags & 16) != 0 ? input.readStringRef() : name; + const color = (flags & 32) != 0 ? input.readInt32() : 4294967295; + const sequence = (flags & 64) != 0 ? this.readSequence(input) : null; + const hullLength = input.readInt(true); + const vertices = this.readVertices(input, (flags & 128) != 0); + const uvs = this.readFloatArray(input, vertices.length, 1); + const triangles = this.readShortArray(input, (vertices.length - hullLength - 2) * 3); + let edges = []; + let width = 0, height = 0; + if (nonessential) { + edges = this.readShortArray(input, input.readInt(true)); + width = input.readFloat(); + height = input.readFloat(); + } + if (!path) path = name; + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.bones = vertices.bones; + mesh.vertices = vertices.vertices; + mesh.worldVerticesLength = vertices.length; + mesh.triangles = triangles; + mesh.regionUVs = uvs; + if (sequence == null) mesh.updateRegion(); + mesh.hullLength = hullLength << 1; + mesh.sequence = sequence; + if (nonessential) { + mesh.edges = edges; + mesh.width = width * scale; + mesh.height = height * scale; + } + return mesh; + } + case 3 /* LinkedMesh */: { + const path = (flags & 16) != 0 ? input.readStringRef() : name; + if (path == null) throw new Error("Path of linked mesh must not be null"); + const color = (flags & 32) != 0 ? input.readInt32() : 4294967295; + const sequence = (flags & 64) != 0 ? this.readSequence(input) : null; + const inheritTimelines = (flags & 128) != 0; + const skinIndex = input.readInt(true); + const parent = input.readStringRef(); + let width = 0, height = 0; + if (nonessential) { + width = input.readFloat(); + height = input.readFloat(); + } + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) return null; + mesh.path = path; + Color.rgba8888ToColor(mesh.color, color); + mesh.sequence = sequence; + if (nonessential) { + mesh.width = width * scale; + mesh.height = height * scale; + } + this.linkedMeshes.push(new LinkedMesh(mesh, skinIndex, slotIndex, parent, inheritTimelines)); + return mesh; + } + case 4 /* Path */: { + const closed2 = (flags & 16) != 0; + const constantSpeed = (flags & 32) != 0; + const vertices = this.readVertices(input, (flags & 64) != 0); + const lengths = Utils.newArray(vertices.length / 6, 0); + for (let i = 0, n = lengths.length; i < n; i++) + lengths[i] = input.readFloat() * scale; + const color = nonessential ? input.readInt32() : 0; + const path = this.attachmentLoader.newPathAttachment(skin, name); + if (!path) return null; + path.closed = closed2; + path.constantSpeed = constantSpeed; + path.worldVerticesLength = vertices.length; + path.vertices = vertices.vertices; + path.bones = vertices.bones; + path.lengths = lengths; + if (nonessential) Color.rgba8888ToColor(path.color, color); + return path; + } + case 5 /* Point */: { + const rotation = input.readFloat(); + const x = input.readFloat(); + const y = input.readFloat(); + const color = nonessential ? input.readInt32() : 0; + const point = this.attachmentLoader.newPointAttachment(skin, name); + if (!point) return null; + point.x = x * scale; + point.y = y * scale; + point.rotation = rotation; + if (nonessential) Color.rgba8888ToColor(point.color, color); + return point; + } + case 6 /* Clipping */: { + const endSlotIndex = input.readInt(true); + const vertices = this.readVertices(input, (flags & 16) != 0); + let color = nonessential ? input.readInt32() : 0; + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (!clip) return null; + clip.endSlot = skeletonData.slots[endSlotIndex]; + clip.worldVerticesLength = vertices.length; + clip.vertices = vertices.vertices; + clip.bones = vertices.bones; + if (nonessential) Color.rgba8888ToColor(clip.color, color); + return clip; + } + } + return null; + } + readSequence(input) { + let sequence = new Sequence(input.readInt(true)); + sequence.start = input.readInt(true); + sequence.digits = input.readInt(true); + sequence.setupIndex = input.readInt(true); + return sequence; + } + readVertices(input, weighted) { + const scale = this.scale; + const vertexCount = input.readInt(true); + const vertices = new Vertices(); + vertices.length = vertexCount << 1; + if (!weighted) { + vertices.vertices = this.readFloatArray(input, vertices.length, scale); + return vertices; + } + let weights = new Array(); + let bonesArray = new Array(); + for (let i = 0; i < vertexCount; i++) { + let boneCount = input.readInt(true); + bonesArray.push(boneCount); + for (let ii = 0; ii < boneCount; ii++) { + bonesArray.push(input.readInt(true)); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat()); + } + } + vertices.vertices = Utils.toFloatArray(weights); + vertices.bones = bonesArray; + return vertices; + } + readFloatArray(input, n, scale) { + let array = new Array(n); + if (scale == 1) { + for (let i = 0; i < n; i++) + array[i] = input.readFloat(); + } else { + for (let i = 0; i < n; i++) + array[i] = input.readFloat() * scale; + } + return array; + } + readShortArray(input, n) { + let array = new Array(n); + for (let i = 0; i < n; i++) + array[i] = input.readInt(true); + return array; + } + readAnimation(input, name, skeletonData) { + input.readInt(true); + let timelines = new Array(); + let scale = this.scale; + for (let i = 0, n = input.readInt(true); i < n; i++) { + let slotIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + let frameLast = frameCount - 1; + switch (timelineType) { + case SLOT_ATTACHMENT: { + let timeline = new AttachmentTimeline(frameCount, slotIndex); + for (let frame = 0; frame < frameCount; frame++) + timeline.setFrame(frame, input.readFloat(), input.readStringRef()); + timelines.push(timeline); + break; + } + case SLOT_RGBA: { + let bezierCount = input.readInt(true); + let timeline = new RGBATimeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + let a = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b, a); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + let a2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1); + } + time = time2; + r = r2; + g = g2; + b = b2; + a = a2; + } + timelines.push(timeline); + break; + } + case SLOT_RGB: { + let bezierCount = input.readInt(true); + let timeline = new RGBTimeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1); + } + time = time2; + r = r2; + g = g2; + b = b2; + } + timelines.push(timeline); + break; + } + case SLOT_RGBA2: { + let bezierCount = input.readInt(true); + let timeline = new RGBA2Timeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + let a = input.readUnsignedByte() / 255; + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let nr = input.readUnsignedByte() / 255; + let ng = input.readUnsignedByte() / 255; + let nb = input.readUnsignedByte() / 255; + let na = input.readUnsignedByte() / 255; + let nr2 = input.readUnsignedByte() / 255; + let ng2 = input.readUnsignedByte() / 255; + let nb2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1); + setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1); + } + time = time2; + r = nr; + g = ng; + b = nb; + a = na; + r2 = nr2; + g2 = ng2; + b2 = nb2; + } + timelines.push(timeline); + break; + } + case SLOT_RGB2: { + let bezierCount = input.readInt(true); + let timeline = new RGB2Timeline(frameCount, bezierCount, slotIndex); + let time = input.readFloat(); + let r = input.readUnsignedByte() / 255; + let g = input.readUnsignedByte() / 255; + let b = input.readUnsignedByte() / 255; + let r2 = input.readUnsignedByte() / 255; + let g2 = input.readUnsignedByte() / 255; + let b2 = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, r, g, b, r2, g2, b2); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let nr = input.readUnsignedByte() / 255; + let ng = input.readUnsignedByte() / 255; + let nb = input.readUnsignedByte() / 255; + let nr2 = input.readUnsignedByte() / 255; + let ng2 = input.readUnsignedByte() / 255; + let nb2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, r2, nr2, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, g2, ng2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, b2, nb2, 1); + } + time = time2; + r = nr; + g = ng; + b = nb; + r2 = nr2; + g2 = ng2; + b2 = nb2; + } + timelines.push(timeline); + break; + } + case SLOT_ALPHA: { + let timeline = new AlphaTimeline(frameCount, input.readInt(true), slotIndex); + let time = input.readFloat(), a = input.readUnsignedByte() / 255; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, a); + if (frame == frameLast) break; + let time2 = input.readFloat(); + let a2 = input.readUnsignedByte() / 255; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, a, a2, 1); + } + time = time2; + a = a2; + } + timelines.push(timeline); + } + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let boneIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let type = input.readByte(), frameCount = input.readInt(true); + if (type == BONE_INHERIT) { + let timeline = new InheritTimeline(frameCount, boneIndex); + for (let frame = 0; frame < frameCount; frame++) { + timeline.setFrame(frame, input.readFloat(), input.readByte()); + } + timelines.push(timeline); + continue; + } + let bezierCount = input.readInt(true); + switch (type) { + case BONE_ROTATE: + timelines.push(readTimeline1(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_TRANSLATE: + timelines.push(readTimeline2(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_TRANSLATEX: + timelines.push(readTimeline1(input, new TranslateXTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_TRANSLATEY: + timelines.push(readTimeline1(input, new TranslateYTimeline(frameCount, bezierCount, boneIndex), scale)); + break; + case BONE_SCALE: + timelines.push(readTimeline2(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SCALEX: + timelines.push(readTimeline1(input, new ScaleXTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SCALEY: + timelines.push(readTimeline1(input, new ScaleYTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEAR: + timelines.push(readTimeline2(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEARX: + timelines.push(readTimeline1(input, new ShearXTimeline(frameCount, bezierCount, boneIndex), 1)); + break; + case BONE_SHEARY: + timelines.push(readTimeline1(input, new ShearYTimeline(frameCount, bezierCount, boneIndex), 1)); + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; + let timeline = new IkConstraintTimeline(frameCount, input.readInt(true), index); + let flags = input.readByte(); + let time = input.readFloat(), mix = (flags & 1) != 0 ? (flags & 2) != 0 ? input.readFloat() : 1 : 0; + let softness = (flags & 4) != 0 ? input.readFloat() * scale : 0; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mix, softness, (flags & 8) != 0 ? 1 : -1, (flags & 16) != 0, (flags & 32) != 0); + if (frame == frameLast) break; + flags = input.readByte(); + const time2 = input.readFloat(), mix2 = (flags & 1) != 0 ? (flags & 2) != 0 ? input.readFloat() : 1 : 0; + const softness2 = (flags & 4) != 0 ? input.readFloat() * scale : 0; + if ((flags & 64) != 0) { + timeline.setStepped(frame); + } else if ((flags & 128) != 0) { + setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale); + } + time = time2; + mix = mix2; + softness = softness2; + } + timelines.push(timeline); + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true), frameCount = input.readInt(true), frameLast = frameCount - 1; + let timeline = new TransformConstraintTimeline(frameCount, input.readInt(true), index); + let time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(), mixScaleX = input.readFloat(), mixScaleY = input.readFloat(), mixShearY = input.readFloat(); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); + if (frame == frameLast) break; + let time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(), mixScaleX2 = input.readFloat(), mixScaleY2 = input.readFloat(), mixShearY2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + setBezier(input, timeline, bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + setBezier(input, timeline, bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + setBezier(input, timeline, bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixShearY = mixShearY2; + } + timelines.push(timeline); + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true); + let data = skeletonData.pathConstraints[index]; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + const type = input.readByte(), frameCount = input.readInt(true), bezierCount = input.readInt(true); + switch (type) { + case PATH_POSITION: + timelines.push(readTimeline1( + input, + new PathConstraintPositionTimeline(frameCount, bezierCount, index), + data.positionMode == 0 /* Fixed */ ? scale : 1 + )); + break; + case PATH_SPACING: + timelines.push(readTimeline1( + input, + new PathConstraintSpacingTimeline(frameCount, bezierCount, index), + data.spacingMode == 0 /* Length */ || data.spacingMode == 1 /* Fixed */ ? scale : 1 + )); + break; + case PATH_MIX: + let timeline = new PathConstraintMixTimeline(frameCount, bezierCount, index); + let time = input.readFloat(), mixRotate = input.readFloat(), mixX = input.readFloat(), mixY = input.readFloat(); + for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY); + if (frame == frameLast) break; + let time2 = input.readFloat(), mixRotate2 = input.readFloat(), mixX2 = input.readFloat(), mixY2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + setBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + setBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + } + timelines.push(timeline); + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + const index = input.readInt(true) - 1; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + const type = input.readByte(), frameCount = input.readInt(true); + if (type == PHYSICS_RESET) { + const timeline = new PhysicsConstraintResetTimeline(frameCount, index); + for (let frame = 0; frame < frameCount; frame++) + timeline.setFrame(frame, input.readFloat()); + timelines.push(timeline); + continue; + } + const bezierCount = input.readInt(true); + switch (type) { + case PHYSICS_INERTIA: + timelines.push(readTimeline1(input, new PhysicsConstraintInertiaTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_STRENGTH: + timelines.push(readTimeline1(input, new PhysicsConstraintStrengthTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_DAMPING: + timelines.push(readTimeline1(input, new PhysicsConstraintDampingTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_MASS: + timelines.push(readTimeline1(input, new PhysicsConstraintMassTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_WIND: + timelines.push(readTimeline1(input, new PhysicsConstraintWindTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_GRAVITY: + timelines.push(readTimeline1(input, new PhysicsConstraintGravityTimeline(frameCount, bezierCount, index), 1)); + break; + case PHYSICS_MIX: + timelines.push(readTimeline1(input, new PhysicsConstraintMixTimeline(frameCount, bezierCount, index), 1)); + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let skin = skeletonData.skins[input.readInt(true)]; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let slotIndex = input.readInt(true); + for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { + let attachmentName = input.readStringRef(); + if (!attachmentName) throw new Error("attachmentName must not be null."); + let attachment = skin.getAttachment(slotIndex, attachmentName); + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + let frameLast = frameCount - 1; + switch (timelineType) { + case ATTACHMENT_DEFORM: { + let vertexAttachment = attachment; + let weighted = vertexAttachment.bones; + let vertices = vertexAttachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let bezierCount = input.readInt(true); + let timeline = new DeformTimeline(frameCount, bezierCount, slotIndex, vertexAttachment); + let time = input.readFloat(); + for (let frame = 0, bezier = 0; ; frame++) { + let deform; + let end = input.readInt(true); + if (end == 0) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + let start = input.readInt(true); + end += start; + if (scale == 1) { + for (let v = start; v < end; v++) + deform[v] = input.readFloat(); + } else { + for (let v = start; v < end; v++) + deform[v] = input.readFloat() * scale; + } + if (!weighted) { + for (let v = 0, vn = deform.length; v < vn; v++) + deform[v] += vertices[v]; + } + } + timeline.setFrame(frame, time, deform); + if (frame == frameLast) break; + let time2 = input.readFloat(); + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1); + } + time = time2; + } + timelines.push(timeline); + break; + } + case ATTACHMENT_SEQUENCE: { + let timeline = new SequenceTimeline(frameCount, slotIndex, attachment); + for (let frame = 0; frame < frameCount; frame++) { + let time = input.readFloat(); + let modeAndIndex = input.readInt32(); + timeline.setFrame( + frame, + time, + SequenceModeValues[modeAndIndex & 15], + modeAndIndex >> 4, + input.readFloat() + ); + } + timelines.push(timeline); + break; + } + } + } + } + } + let drawOrderCount = input.readInt(true); + if (drawOrderCount > 0) { + let timeline = new DrawOrderTimeline(drawOrderCount); + let slotCount = skeletonData.slots.length; + for (let i = 0; i < drawOrderCount; i++) { + let time = input.readFloat(); + let offsetCount = input.readInt(true); + let drawOrder = Utils.newArray(slotCount, 0); + for (let ii = slotCount - 1; ii >= 0; ii--) + drawOrder[ii] = -1; + let unchanged = Utils.newArray(slotCount - offsetCount, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let ii = 0; ii < offsetCount; ii++) { + let slotIndex = input.readInt(true); + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + input.readInt(true)] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; + timeline.setFrame(i, time, drawOrder); + } + timelines.push(timeline); + } + let eventCount = input.readInt(true); + if (eventCount > 0) { + let timeline = new EventTimeline(eventCount); + for (let i = 0; i < eventCount; i++) { + let time = input.readFloat(); + let eventData = skeletonData.events[input.readInt(true)]; + let event = new Event(time, eventData); + event.intValue = input.readInt(false); + event.floatValue = input.readFloat(); + event.stringValue = input.readString(); + if (event.stringValue == null) event.stringValue = eventData.stringValue; + if (event.data.audioPath) { + event.volume = input.readFloat(); + event.balance = input.readFloat(); + } + timeline.setFrame(i, event); + } + timelines.push(timeline); + } + let duration = 0; + for (let i = 0, n = timelines.length; i < n; i++) + duration = Math.max(duration, timelines[i].getDuration()); + return new Animation(name, timelines, duration); + } + }; + var BinaryInput = class { + constructor(data, strings = new Array(), index = 0, buffer = new DataView(data instanceof ArrayBuffer ? data : data.buffer)) { + this.strings = strings; + this.index = index; + this.buffer = buffer; + } + readByte() { + return this.buffer.getInt8(this.index++); + } + readUnsignedByte() { + return this.buffer.getUint8(this.index++); + } + readShort() { + let value = this.buffer.getInt16(this.index); + this.index += 2; + return value; + } + readInt32() { + let value = this.buffer.getInt32(this.index); + this.index += 4; + return value; + } + readInt(optimizePositive) { + let b = this.readByte(); + let result = b & 127; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 7; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 14; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 21; + if ((b & 128) != 0) { + b = this.readByte(); + result |= (b & 127) << 28; + } + } + } + } + return optimizePositive ? result : result >>> 1 ^ -(result & 1); + } + readStringRef() { + let index = this.readInt(true); + return index == 0 ? null : this.strings[index - 1]; + } + readString() { + let byteCount = this.readInt(true); + switch (byteCount) { + case 0: + return null; + case 1: + return ""; + } + byteCount--; + let chars = ""; + let charCount = 0; + for (let i = 0; i < byteCount; ) { + let b = this.readUnsignedByte(); + switch (b >> 4) { + case 12: + case 13: + chars += String.fromCharCode((b & 31) << 6 | this.readByte() & 63); + i += 2; + break; + case 14: + chars += String.fromCharCode((b & 15) << 12 | (this.readByte() & 63) << 6 | this.readByte() & 63); + i += 3; + break; + default: + chars += String.fromCharCode(b); + i++; + } + } + return chars; + } + readFloat() { + let value = this.buffer.getFloat32(this.index); + this.index += 4; + return value; + } + readBoolean() { + return this.readByte() != 0; + } + }; + var LinkedMesh = class { + parent; + skinIndex; + slotIndex; + mesh; + inheritTimeline; + constructor(mesh, skinIndex, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skinIndex = skinIndex; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritTimeline = inheritDeform; + } + }; + var Vertices = class { + constructor(bones = null, vertices = null, length = 0) { + this.bones = bones; + this.vertices = vertices; + this.length = length; + } + }; + function readTimeline1(input, timeline, scale) { + let time = input.readFloat(), value = input.readFloat() * scale; + for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { + timeline.setFrame(frame, time, value); + if (frame == frameLast) break; + let time2 = input.readFloat(), value2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, scale); + } + time = time2; + value = value2; + } + return timeline; + } + function readTimeline2(input, timeline, scale) { + let time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale; + for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { + timeline.setFrame(frame, time, value1, value2); + if (frame == frameLast) break; + let time2 = input.readFloat(), nvalue1 = input.readFloat() * scale, nvalue2 = input.readFloat() * scale; + switch (input.readByte()) { + case CURVE_STEPPED: + timeline.setStepped(frame); + break; + case CURVE_BEZIER: + setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale); + setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale); + } + time = time2; + value1 = nvalue1; + value2 = nvalue2; + } + return timeline; + } + function setBezier(input, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { + timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2); + } + var BONE_ROTATE = 0; + var BONE_TRANSLATE = 1; + var BONE_TRANSLATEX = 2; + var BONE_TRANSLATEY = 3; + var BONE_SCALE = 4; + var BONE_SCALEX = 5; + var BONE_SCALEY = 6; + var BONE_SHEAR = 7; + var BONE_SHEARX = 8; + var BONE_SHEARY = 9; + var BONE_INHERIT = 10; + var SLOT_ATTACHMENT = 0; + var SLOT_RGBA = 1; + var SLOT_RGB = 2; + var SLOT_RGBA2 = 3; + var SLOT_RGB2 = 4; + var SLOT_ALPHA = 5; + var ATTACHMENT_DEFORM = 0; + var ATTACHMENT_SEQUENCE = 1; + var PATH_POSITION = 0; + var PATH_SPACING = 1; + var PATH_MIX = 2; + var PHYSICS_INERTIA = 0; + var PHYSICS_STRENGTH = 1; + var PHYSICS_DAMPING = 2; + var PHYSICS_MASS = 4; + var PHYSICS_WIND = 5; + var PHYSICS_GRAVITY = 6; + var PHYSICS_MIX = 7; + var PHYSICS_RESET = 8; + var CURVE_STEPPED = 1; + var CURVE_BEZIER = 2; + + // spine-core/src/SkeletonBounds.ts + var SkeletonBounds = class { + /** The left edge of the axis aligned bounding box. */ + minX = 0; + /** The bottom edge of the axis aligned bounding box. */ + minY = 0; + /** The right edge of the axis aligned bounding box. */ + maxX = 0; + /** The top edge of the axis aligned bounding box. */ + maxY = 0; + /** The visible bounding boxes. */ + boundingBoxes = new Array(); + /** The world vertices for the bounding box polygons. */ + polygons = new Array(); + polygonPool = new Pool(() => { + return Utils.newFloatArray(16); + }); + /** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding + * box's polygon. + * @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the + * SkeletonBounds AABB methods will always return true. */ + update(skeleton, updateAabb) { + if (!skeleton) throw new Error("skeleton cannot be null."); + let boundingBoxes = this.boundingBoxes; + let polygons = this.polygons; + let polygonPool = this.polygonPool; + let slots = skeleton.slots; + let slotCount = slots.length; + boundingBoxes.length = 0; + polygonPool.freeAll(polygons); + polygons.length = 0; + for (let i = 0; i < slotCount; i++) { + let slot = slots[i]; + if (!slot.bone.active) continue; + let attachment = slot.getAttachment(); + if (attachment instanceof BoundingBoxAttachment) { + let boundingBox = attachment; + boundingBoxes.push(boundingBox); + let polygon = polygonPool.obtain(); + if (polygon.length != boundingBox.worldVerticesLength) { + polygon = Utils.newFloatArray(boundingBox.worldVerticesLength); + } + polygons.push(polygon); + boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); + } + } + if (updateAabb) { + this.aabbCompute(); + } else { + this.minX = Number.POSITIVE_INFINITY; + this.minY = Number.POSITIVE_INFINITY; + this.maxX = Number.NEGATIVE_INFINITY; + this.maxY = Number.NEGATIVE_INFINITY; + } + } + aabbCompute() { + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) { + let polygon = polygons[i]; + let vertices = polygon; + for (let ii = 0, nn = polygon.length; ii < nn; ii += 2) { + let x = vertices[ii]; + let y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + /** Returns true if the axis aligned bounding box contains the point. */ + aabbContainsPoint(x, y) { + return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; + } + /** Returns true if the axis aligned bounding box intersects the line segment. */ + aabbIntersectsSegment(x1, y1, x2, y2) { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + if (x1 <= minX && x2 <= minX || y1 <= minY && y2 <= minY || x1 >= maxX && x2 >= maxX || y1 >= maxY && y2 >= maxY) + return false; + let m = (y2 - y1) / (x2 - x1); + let y = m * (minX - x1) + y1; + if (y > minY && y < maxY) return true; + y = m * (maxX - x1) + y1; + if (y > minY && y < maxY) return true; + let x = (minY - y1) / m + x1; + if (x > minX && x < maxX) return true; + x = (maxY - y1) / m + x1; + if (x > minX && x < maxX) return true; + return false; + } + /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ + aabbIntersectsSkeleton(bounds) { + return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; + } + /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more + * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */ + containsPoint(x, y) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.containsPointPolygon(polygons[i], x, y)) return this.boundingBoxes[i]; + return null; + } + /** Returns true if the polygon contains the point. */ + containsPointPolygon(polygon, x, y) { + let vertices = polygon; + let nn = polygon.length; + let prevIndex = nn - 2; + let inside = false; + for (let ii = 0; ii < nn; ii += 2) { + let vertexY = vertices[ii + 1]; + let prevY = vertices[prevIndex + 1]; + if (vertexY < y && prevY >= y || prevY < y && vertexY >= y) { + let vertexX = vertices[ii]; + if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) inside = !inside; + } + prevIndex = ii; + } + return inside; + } + /** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it + * is usually more efficient to only call this method if {@link #aabbIntersectsSegment()} returns + * true. */ + intersectsSegment(x1, y1, x2, y2) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) return this.boundingBoxes[i]; + return null; + } + /** Returns true if the polygon contains any part of the line segment. */ + intersectsSegmentPolygon(polygon, x1, y1, x2, y2) { + let vertices = polygon; + let nn = polygon.length; + let width12 = x1 - x2, height12 = y1 - y2; + let det1 = x1 * y2 - y1 * x2; + let x3 = vertices[nn - 2], y3 = vertices[nn - 1]; + for (let ii = 0; ii < nn; ii += 2) { + let x4 = vertices[ii], y4 = vertices[ii + 1]; + let det2 = x3 * y4 - y3 * x4; + let width34 = x3 - x4, height34 = y3 - y4; + let det3 = width12 * height34 - height12 * width34; + let x = (det1 * width34 - width12 * det2) / det3; + if ((x >= x3 && x <= x4 || x >= x4 && x <= x3) && (x >= x1 && x <= x2 || x >= x2 && x <= x1)) { + let y = (det1 * height34 - height12 * det2) / det3; + if ((y >= y3 && y <= y4 || y >= y4 && y <= y3) && (y >= y1 && y <= y2 || y >= y2 && y <= y1)) return true; + } + x3 = x4; + y3 = y4; + } + return false; + } + /** Returns the polygon for the specified bounding box, or null. */ + getPolygon(boundingBox) { + if (!boundingBox) throw new Error("boundingBox cannot be null."); + let index = this.boundingBoxes.indexOf(boundingBox); + return index == -1 ? null : this.polygons[index]; + } + /** The width of the axis aligned bounding box. */ + getWidth() { + return this.maxX - this.minX; + } + /** The height of the axis aligned bounding box. */ + getHeight() { + return this.maxY - this.minY; + } + }; + + // spine-core/src/Triangulator.ts + var Triangulator = class _Triangulator { + convexPolygons = new Array(); + convexPolygonsIndices = new Array(); + indicesArray = new Array(); + isConcaveArray = new Array(); + triangles = new Array(); + polygonPool = new Pool(() => { + return new Array(); + }); + polygonIndicesPool = new Pool(() => { + return new Array(); + }); + triangulate(verticesArray) { + let vertices = verticesArray; + let vertexCount = verticesArray.length >> 1; + let indices = this.indicesArray; + indices.length = 0; + for (let i = 0; i < vertexCount; i++) + indices[i] = i; + let isConcave = this.isConcaveArray; + isConcave.length = 0; + for (let i = 0, n = vertexCount; i < n; ++i) + isConcave[i] = _Triangulator.isConcave(i, vertexCount, vertices, indices); + let triangles = this.triangles; + triangles.length = 0; + while (vertexCount > 3) { + let previous = vertexCount - 1, i = 0, next = 1; + while (true) { + outer: + if (!isConcave[i]) { + let p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1; + let p1x = vertices[p1], p1y = vertices[p1 + 1]; + let p2x = vertices[p2], p2y = vertices[p2 + 1]; + let p3x = vertices[p3], p3y = vertices[p3 + 1]; + for (let ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) { + if (!isConcave[ii]) continue; + let v = indices[ii] << 1; + let vx = vertices[v], vy = vertices[v + 1]; + if (_Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) { + if (_Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) { + if (_Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy)) break outer; + } + } + } + break; + } + if (next == 0) { + do { + if (!isConcave[i]) break; + i--; + } while (i > 0); + break; + } + previous = i; + i = next; + next = (next + 1) % vertexCount; + } + triangles.push(indices[(vertexCount + i - 1) % vertexCount]); + triangles.push(indices[i]); + triangles.push(indices[(i + 1) % vertexCount]); + indices.splice(i, 1); + isConcave.splice(i, 1); + vertexCount--; + let previousIndex = (vertexCount + i - 1) % vertexCount; + let nextIndex = i == vertexCount ? 0 : i; + isConcave[previousIndex] = _Triangulator.isConcave(previousIndex, vertexCount, vertices, indices); + isConcave[nextIndex] = _Triangulator.isConcave(nextIndex, vertexCount, vertices, indices); + } + if (vertexCount == 3) { + triangles.push(indices[2]); + triangles.push(indices[0]); + triangles.push(indices[1]); + } + return triangles; + } + decompose(verticesArray, triangles) { + let vertices = verticesArray; + let convexPolygons = this.convexPolygons; + this.polygonPool.freeAll(convexPolygons); + convexPolygons.length = 0; + let convexPolygonsIndices = this.convexPolygonsIndices; + this.polygonIndicesPool.freeAll(convexPolygonsIndices); + convexPolygonsIndices.length = 0; + let polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + let polygon = this.polygonPool.obtain(); + polygon.length = 0; + let fanBaseIndex = -1, lastWinding = 0; + for (let i = 0, n = triangles.length; i < n; i += 3) { + let t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1; + let x1 = vertices[t1], y1 = vertices[t1 + 1]; + let x2 = vertices[t2], y2 = vertices[t2 + 1]; + let x3 = vertices[t3], y3 = vertices[t3 + 1]; + let merged = false; + if (fanBaseIndex == t1) { + let o = polygon.length - 4; + let winding1 = _Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3); + let winding2 = _Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]); + if (winding1 == lastWinding && winding2 == lastWinding) { + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(t3); + merged = true; + } + } + if (!merged) { + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } else { + this.polygonPool.free(polygon); + this.polygonIndicesPool.free(polygonIndices); + } + polygon = this.polygonPool.obtain(); + polygon.length = 0; + polygon.push(x1); + polygon.push(y1); + polygon.push(x2); + polygon.push(y2); + polygon.push(x3); + polygon.push(y3); + polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + polygonIndices.push(t1); + polygonIndices.push(t2); + polygonIndices.push(t3); + lastWinding = _Triangulator.winding(x1, y1, x2, y2, x3, y3); + fanBaseIndex = t1; + } + } + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + for (let i = 0, n = convexPolygons.length; i < n; i++) { + polygonIndices = convexPolygonsIndices[i]; + if (polygonIndices.length == 0) continue; + let firstIndex = polygonIndices[0]; + let lastIndex = polygonIndices[polygonIndices.length - 1]; + polygon = convexPolygons[i]; + let o = polygon.length - 4; + let prevPrevX = polygon[o], prevPrevY = polygon[o + 1]; + let prevX = polygon[o + 2], prevY = polygon[o + 3]; + let firstX = polygon[0], firstY = polygon[1]; + let secondX = polygon[2], secondY = polygon[3]; + let winding = _Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY); + for (let ii = 0; ii < n; ii++) { + if (ii == i) continue; + let otherIndices = convexPolygonsIndices[ii]; + if (otherIndices.length != 3) continue; + let otherFirstIndex = otherIndices[0]; + let otherSecondIndex = otherIndices[1]; + let otherLastIndex = otherIndices[2]; + let otherPoly = convexPolygons[ii]; + let x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1]; + if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) continue; + let winding1 = _Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3); + let winding2 = _Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY); + if (winding1 == winding && winding2 == winding) { + otherPoly.length = 0; + otherIndices.length = 0; + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(otherLastIndex); + prevPrevX = prevX; + prevPrevY = prevY; + prevX = x3; + prevY = y3; + ii = 0; + } + } + } + for (let i = convexPolygons.length - 1; i >= 0; i--) { + polygon = convexPolygons[i]; + if (polygon.length == 0) { + convexPolygons.splice(i, 1); + this.polygonPool.free(polygon); + polygonIndices = convexPolygonsIndices[i]; + convexPolygonsIndices.splice(i, 1); + this.polygonIndicesPool.free(polygonIndices); + } + } + return convexPolygons; + } + static isConcave(index, vertexCount, vertices, indices) { + let previous = indices[(vertexCount + index - 1) % vertexCount] << 1; + let current = indices[index] << 1; + let next = indices[(index + 1) % vertexCount] << 1; + return !this.positiveArea( + vertices[previous], + vertices[previous + 1], + vertices[current], + vertices[current + 1], + vertices[next], + vertices[next + 1] + ); + } + static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y) { + return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; + } + static winding(p1x, p1y, p2x, p2y, p3x, p3y) { + let px = p2x - p1x, py = p2y - p1y; + return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; + } + }; + + // spine-core/src/SkeletonClipping.ts + var SkeletonClipping = class _SkeletonClipping { + triangulator = new Triangulator(); + clippingPolygon = new Array(); + clipOutput = new Array(); + clippedVertices = new Array(); + clippedUVs = new Array(); + clippedTriangles = new Array(); + scratch = new Array(); + clipAttachment = null; + clippingPolygons = null; + clipStart(slot, clip) { + if (this.clipAttachment) return 0; + this.clipAttachment = clip; + let n = clip.worldVerticesLength; + let vertices = Utils.setArraySize(this.clippingPolygon, n); + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + let clippingPolygon = this.clippingPolygon; + _SkeletonClipping.makeClockwise(clippingPolygon); + let clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon)); + for (let i = 0, n2 = clippingPolygons.length; i < n2; i++) { + let polygon = clippingPolygons[i]; + _SkeletonClipping.makeClockwise(polygon); + polygon.push(polygon[0]); + polygon.push(polygon[1]); + } + return clippingPolygons.length; + } + clipEndWithSlot(slot) { + if (this.clipAttachment && this.clipAttachment.endSlot == slot.data) this.clipEnd(); + } + clipEnd() { + if (!this.clipAttachment) return; + this.clipAttachment = null; + this.clippingPolygons = null; + this.clippedVertices.length = 0; + this.clippedTriangles.length = 0; + this.clippingPolygon.length = 0; + } + isClipping() { + return this.clipAttachment != null; + } + clipTriangles(vertices, verticesLengthOrTriangles, trianglesOrTrianglesLength, trianglesLengthOrUvs, uvsOrLight, lightOrDark, darkOrTwoColor, twoColorParam) { + let triangles; + let trianglesLength; + let uvs; + let light; + let dark; + let twoColor; + if (typeof verticesLengthOrTriangles === "number") { + triangles = trianglesOrTrianglesLength; + trianglesLength = trianglesLengthOrUvs; + uvs = uvsOrLight; + light = lightOrDark; + dark = darkOrTwoColor; + twoColor = twoColorParam; + } else { + triangles = verticesLengthOrTriangles; + trianglesLength = trianglesOrTrianglesLength; + uvs = trianglesLengthOrUvs; + light = uvsOrLight; + dark = lightOrDark; + twoColor = darkOrTwoColor; + } + if (uvs && light && dark && typeof twoColor === "boolean") + this.clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor); + else + this.clipTrianglesNoRender(vertices, triangles, trianglesLength); + } + clipTrianglesNoRender(vertices, triangles, trianglesLength) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = polygons.length; + let index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) continue; + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * 2); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += 2) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++, s += 3) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + } + index += clipOutputCount + 1; + } else { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * 2); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = x2; + clippedVerticesItems[s + 3] = y2; + clippedVerticesItems[s + 4] = x3; + clippedVerticesItems[s + 5] = y3; + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; + } + } + } + } + clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = polygons.length; + let vertexSize = twoColor ? 12 : 8; + let index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) continue; + let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + let d = 1 / (d0 * d2 + d1 * (y1 - y3)); + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += vertexSize) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + let c0 = x - x3, c1 = y - y3; + let a = (d0 * c0 + d1 * c1) * d; + let b = (d4 * c0 + d2 * c1) * d; + let c = 1 - a - b; + clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c; + clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c; + if (twoColor) { + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + } + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++, s += 3) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + } + index += clipOutputCount + 1; + } else { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * vertexSize); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + if (!twoColor) { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = x2; + clippedVerticesItems[s + 9] = y2; + clippedVerticesItems[s + 10] = light.r; + clippedVerticesItems[s + 11] = light.g; + clippedVerticesItems[s + 12] = light.b; + clippedVerticesItems[s + 13] = light.a; + clippedVerticesItems[s + 14] = u2; + clippedVerticesItems[s + 15] = v2; + clippedVerticesItems[s + 16] = x3; + clippedVerticesItems[s + 17] = y3; + clippedVerticesItems[s + 18] = light.r; + clippedVerticesItems[s + 19] = light.g; + clippedVerticesItems[s + 20] = light.b; + clippedVerticesItems[s + 21] = light.a; + clippedVerticesItems[s + 22] = u3; + clippedVerticesItems[s + 23] = v3; + } else { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + clippedVerticesItems[s + 12] = x2; + clippedVerticesItems[s + 13] = y2; + clippedVerticesItems[s + 14] = light.r; + clippedVerticesItems[s + 15] = light.g; + clippedVerticesItems[s + 16] = light.b; + clippedVerticesItems[s + 17] = light.a; + clippedVerticesItems[s + 18] = u2; + clippedVerticesItems[s + 19] = v2; + clippedVerticesItems[s + 20] = dark.r; + clippedVerticesItems[s + 21] = dark.g; + clippedVerticesItems[s + 22] = dark.b; + clippedVerticesItems[s + 23] = dark.a; + clippedVerticesItems[s + 24] = x3; + clippedVerticesItems[s + 25] = y3; + clippedVerticesItems[s + 26] = light.r; + clippedVerticesItems[s + 27] = light.g; + clippedVerticesItems[s + 28] = light.b; + clippedVerticesItems[s + 29] = light.a; + clippedVerticesItems[s + 30] = u3; + clippedVerticesItems[s + 31] = v3; + clippedVerticesItems[s + 32] = dark.r; + clippedVerticesItems[s + 33] = dark.g; + clippedVerticesItems[s + 34] = dark.b; + clippedVerticesItems[s + 35] = dark.a; + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; + } + } + } + } + clipTrianglesUnpacked(vertices, triangles, trianglesLength, uvs) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices, clippedUVs = this.clippedUVs; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = polygons.length; + let index = 0; + clippedVertices.length = 0; + clippedUVs.length = 0; + clippedTriangles.length = 0; + for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) continue; + let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + let d = 1 / (d0 * d2 + d1 * (y1 - y3)); + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + clipOutputCount * 2); + let clippedUVsItems = Utils.setArraySize(clippedUVs, s + clipOutputCount * 2); + for (let ii = 0; ii < clipOutputLength; ii += 2, s += 2) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + let c0 = x - x3, c1 = y - y3; + let a = (d0 * c0 + d1 * c1) * d; + let b = (d4 * c0 + d2 * c1) * d; + let c = 1 - a - b; + clippedUVsItems[s] = u1 * a + u2 * b + u3 * c; + clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c; + } + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++, s += 3) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; + } + index += clipOutputCount + 1; + } else { + let clippedVerticesItems = Utils.setArraySize(clippedVertices, s + 3 * 2); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = x2; + clippedVerticesItems[s + 3] = y2; + clippedVerticesItems[s + 4] = x3; + clippedVerticesItems[s + 5] = y3; + let clippedUVSItems = Utils.setArraySize(clippedUVs, s + 3 * 2); + clippedUVSItems[s] = u1; + clippedUVSItems[s + 1] = v1; + clippedUVSItems[s + 2] = u2; + clippedUVSItems[s + 3] = v2; + clippedUVSItems[s + 4] = u3; + clippedUVSItems[s + 5] = v3; + s = clippedTriangles.length; + let clippedTrianglesItems = Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; + index += 3; + break; + } + } + } + } + /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping + * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */ + clip(x1, y1, x2, y2, x3, y3, clippingArea, output) { + let originalOutput = output; + let clipped = false; + let input; + if (clippingArea.length % 4 >= 2) { + input = output; + output = this.scratch; + } else + input = this.scratch; + input.length = 0; + input.push(x1); + input.push(y1); + input.push(x2); + input.push(y2); + input.push(x3); + input.push(y3); + input.push(x1); + input.push(y1); + output.length = 0; + let clippingVerticesLast = clippingArea.length - 4; + let clippingVertices = clippingArea; + for (let i = 0; ; i += 2) { + let edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; + let ex = edgeX - clippingVertices[i + 2], ey = edgeY - clippingVertices[i + 3]; + let outputStart = output.length; + let inputVertices = input; + for (let ii = 0, nn = input.length - 2; ii < nn; ) { + let inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; + ii += 2; + let inputX2 = inputVertices[ii], inputY2 = inputVertices[ii + 1]; + let s2 = ey * (edgeX - inputX2) > ex * (edgeY - inputY2); + let s1 = ey * (edgeX - inputX) - ex * (edgeY - inputY); + if (s1 > 0) { + if (s2) { + output.push(inputX2); + output.push(inputY2); + continue; + } + let ix = inputX2 - inputX, iy = inputY2 - inputY, t = s1 / (ix * ey - iy * ex); + if (t >= 0 && t <= 1) { + output.push(inputX + ix * t); + output.push(inputY + iy * t); + } else { + output.push(inputX2); + output.push(inputY2); + continue; + } + } else if (s2) { + let ix = inputX2 - inputX, iy = inputY2 - inputY, t = s1 / (ix * ey - iy * ex); + if (t >= 0 && t <= 1) { + output.push(inputX + ix * t); + output.push(inputY + iy * t); + output.push(inputX2); + output.push(inputY2); + } else { + output.push(inputX2); + output.push(inputY2); + continue; + } + } + clipped = true; + } + if (outputStart == output.length) { + originalOutput.length = 0; + return true; + } + output.push(output[0]); + output.push(output[1]); + if (i == clippingVerticesLast) break; + let temp = output; + output = input; + output.length = 0; + input = temp; + } + if (originalOutput != output) { + originalOutput.length = 0; + for (let i = 0, n = output.length - 2; i < n; i++) + originalOutput[i] = output[i]; + } else + originalOutput.length = originalOutput.length - 2; + return clipped; + } + static makeClockwise(polygon) { + let vertices = polygon; + let verticeslength = polygon.length; + let area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0; + for (let i = 0, n = verticeslength - 3; i < n; i += 2) { + p1x = vertices[i]; + p1y = vertices[i + 1]; + p2x = vertices[i + 2]; + p2y = vertices[i + 3]; + area += p1x * p2y - p2x * p1y; + } + if (area < 0) return; + for (let i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { + let x = vertices[i], y = vertices[i + 1]; + let other = lastX - i; + vertices[i] = vertices[other]; + vertices[i + 1] = vertices[other + 1]; + vertices[other] = x; + vertices[other + 1] = y; + } + } + }; + + // spine-core/src/SkeletonJson.ts + var SkeletonJson = class { + attachmentLoader; + /** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at + * runtime than were used in Spine. + * + * See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */ + scale = 1; + linkedMeshes = new Array(); + constructor(attachmentLoader) { + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(json) { + let scale = this.scale; + let skeletonData = new SkeletonData(); + let root = typeof json === "string" ? JSON.parse(json) : json; + let skeletonMap = root.skeleton; + if (skeletonMap) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + skeletonData.x = skeletonMap.x; + skeletonData.y = skeletonMap.y; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.referenceScale = getValue(skeletonMap, "referenceScale", 100) * scale; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images ?? null; + skeletonData.audioPath = skeletonMap.audio ?? null; + } + if (root.bones) { + for (let i = 0; i < root.bones.length; i++) { + let boneMap = root.bones[i]; + let parent = null; + let parentName = getValue(boneMap, "parent", null); + if (parentName) parent = skeletonData.findBone(parentName); + let data = new BoneData(skeletonData.bones.length, boneMap.name, parent); + data.length = getValue(boneMap, "length", 0) * scale; + data.x = getValue(boneMap, "x", 0) * scale; + data.y = getValue(boneMap, "y", 0) * scale; + data.rotation = getValue(boneMap, "rotation", 0); + data.scaleX = getValue(boneMap, "scaleX", 1); + data.scaleY = getValue(boneMap, "scaleY", 1); + data.shearX = getValue(boneMap, "shearX", 0); + data.shearY = getValue(boneMap, "shearY", 0); + data.inherit = Utils.enumValue(Inherit, getValue(boneMap, "inherit", "Normal")); + data.skinRequired = getValue(boneMap, "skin", false); + let color = getValue(boneMap, "color", null); + if (color) data.color.setFromString(color); + skeletonData.bones.push(data); + } + } + if (root.slots) { + for (let i = 0; i < root.slots.length; i++) { + let slotMap = root.slots[i]; + let slotName = slotMap.name; + let boneData = skeletonData.findBone(slotMap.bone); + if (!boneData) throw new Error(`Couldn't find bone ${slotMap.bone} for slot ${slotName}`); + let data = new SlotData(skeletonData.slots.length, slotName, boneData); + let color = getValue(slotMap, "color", null); + if (color) data.color.setFromString(color); + let dark = getValue(slotMap, "dark", null); + if (dark) data.darkColor = Color.fromString(dark); + data.attachmentName = getValue(slotMap, "attachment", null); + data.blendMode = Utils.enumValue(BlendMode, getValue(slotMap, "blend", "normal")); + data.visible = getValue(slotMap, "visible", true); + skeletonData.slots.push(data); + } + } + if (root.ik) { + for (let i = 0; i < root.ik.length; i++) { + let constraintMap = root.ik[i]; + let data = new IkConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (let ii = 0; ii < constraintMap.bones.length; ii++) { + let bone = skeletonData.findBone(constraintMap.bones[ii]); + if (!bone) throw new Error(`Couldn't find bone ${constraintMap.bones[ii]} for IK constraint ${constraintMap.name}.`); + data.bones.push(bone); + } + let target = skeletonData.findBone(constraintMap.target); + ; + if (!target) throw new Error(`Couldn't find target bone ${constraintMap.target} for IK constraint ${constraintMap.name}.`); + data.target = target; + data.mix = getValue(constraintMap, "mix", 1); + data.softness = getValue(constraintMap, "softness", 0) * scale; + data.bendDirection = getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = getValue(constraintMap, "compress", false); + data.stretch = getValue(constraintMap, "stretch", false); + data.uniform = getValue(constraintMap, "uniform", false); + skeletonData.ikConstraints.push(data); + } + } + if (root.transform) { + for (let i = 0; i < root.transform.length; i++) { + let constraintMap = root.transform[i]; + let data = new TransformConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (let ii = 0; ii < constraintMap.bones.length; ii++) { + let boneName = constraintMap.bones[ii]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error(`Couldn't find bone ${boneName} for transform constraint ${constraintMap.name}.`); + data.bones.push(bone); + } + let targetName = constraintMap.target; + let target = skeletonData.findBone(targetName); + if (!target) throw new Error(`Couldn't find target bone ${targetName} for transform constraint ${constraintMap.name}.`); + data.target = target; + data.local = getValue(constraintMap, "local", false); + data.relative = getValue(constraintMap, "relative", false); + data.offsetRotation = getValue(constraintMap, "rotation", 0); + data.offsetX = getValue(constraintMap, "x", 0) * scale; + data.offsetY = getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = getValue(constraintMap, "scaleY", 0); + data.offsetShearY = getValue(constraintMap, "shearY", 0); + data.mixRotate = getValue(constraintMap, "mixRotate", 1); + data.mixX = getValue(constraintMap, "mixX", 1); + data.mixY = getValue(constraintMap, "mixY", data.mixX); + data.mixScaleX = getValue(constraintMap, "mixScaleX", 1); + data.mixScaleY = getValue(constraintMap, "mixScaleY", data.mixScaleX); + data.mixShearY = getValue(constraintMap, "mixShearY", 1); + skeletonData.transformConstraints.push(data); + } + } + if (root.path) { + for (let i = 0; i < root.path.length; i++) { + let constraintMap = root.path[i]; + let data = new PathConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + for (let ii = 0; ii < constraintMap.bones.length; ii++) { + let boneName = constraintMap.bones[ii]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error(`Couldn't find bone ${boneName} for path constraint ${constraintMap.name}.`); + data.bones.push(bone); + } + let targetName = constraintMap.target; + let target = skeletonData.findSlot(targetName); + if (!target) throw new Error(`Couldn't find target slot ${targetName} for path constraint ${constraintMap.name}.`); + data.target = target; + data.positionMode = Utils.enumValue(PositionMode, getValue(constraintMap, "positionMode", "Percent")); + data.spacingMode = Utils.enumValue(SpacingMode, getValue(constraintMap, "spacingMode", "Length")); + data.rotateMode = Utils.enumValue(RotateMode, getValue(constraintMap, "rotateMode", "Tangent")); + data.offsetRotation = getValue(constraintMap, "rotation", 0); + data.position = getValue(constraintMap, "position", 0); + if (data.positionMode == 0 /* Fixed */) data.position *= scale; + data.spacing = getValue(constraintMap, "spacing", 0); + if (data.spacingMode == 0 /* Length */ || data.spacingMode == 1 /* Fixed */) data.spacing *= scale; + data.mixRotate = getValue(constraintMap, "mixRotate", 1); + data.mixX = getValue(constraintMap, "mixX", 1); + data.mixY = getValue(constraintMap, "mixY", data.mixX); + skeletonData.pathConstraints.push(data); + } + } + if (root.physics) { + for (let i = 0; i < root.physics.length; i++) { + const constraintMap = root.physics[i]; + const data = new PhysicsConstraintData(constraintMap.name); + data.order = getValue(constraintMap, "order", 0); + data.skinRequired = getValue(constraintMap, "skin", false); + const boneName = constraintMap.bone; + const bone = skeletonData.findBone(boneName); + if (bone == null) throw new Error("Physics bone not found: " + boneName); + data.bone = bone; + data.x = getValue(constraintMap, "x", 0); + data.y = getValue(constraintMap, "y", 0); + data.rotate = getValue(constraintMap, "rotate", 0); + data.scaleX = getValue(constraintMap, "scaleX", 0); + data.shearX = getValue(constraintMap, "shearX", 0); + data.limit = getValue(constraintMap, "limit", 5e3) * scale; + data.step = 1 / getValue(constraintMap, "fps", 60); + data.inertia = getValue(constraintMap, "inertia", 1); + data.strength = getValue(constraintMap, "strength", 100); + data.damping = getValue(constraintMap, "damping", 1); + data.massInverse = 1 / getValue(constraintMap, "mass", 1); + data.wind = getValue(constraintMap, "wind", 0); + data.gravity = getValue(constraintMap, "gravity", 0); + data.mix = getValue(constraintMap, "mix", 1); + data.inertiaGlobal = getValue(constraintMap, "inertiaGlobal", false); + data.strengthGlobal = getValue(constraintMap, "strengthGlobal", false); + data.dampingGlobal = getValue(constraintMap, "dampingGlobal", false); + data.massGlobal = getValue(constraintMap, "massGlobal", false); + data.windGlobal = getValue(constraintMap, "windGlobal", false); + data.gravityGlobal = getValue(constraintMap, "gravityGlobal", false); + data.mixGlobal = getValue(constraintMap, "mixGlobal", false); + skeletonData.physicsConstraints.push(data); + } + } + if (root.skins) { + for (let i = 0; i < root.skins.length; i++) { + let skinMap = root.skins[i]; + let skin = new Skin(skinMap.name); + if (skinMap.bones) { + for (let ii = 0; ii < skinMap.bones.length; ii++) { + let boneName = skinMap.bones[ii]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error(`Couldn't find bone ${boneName} for skin ${skinMap.name}.`); + skin.bones.push(bone); + } + } + if (skinMap.ik) { + for (let ii = 0; ii < skinMap.ik.length; ii++) { + let constraintName = skinMap.ik[ii]; + let constraint = skeletonData.findIkConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find IK constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + if (skinMap.transform) { + for (let ii = 0; ii < skinMap.transform.length; ii++) { + let constraintName = skinMap.transform[ii]; + let constraint = skeletonData.findTransformConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find transform constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + if (skinMap.path) { + for (let ii = 0; ii < skinMap.path.length; ii++) { + let constraintName = skinMap.path[ii]; + let constraint = skeletonData.findPathConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find path constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + if (skinMap.physics) { + for (let ii = 0; ii < skinMap.physics.length; ii++) { + let constraintName = skinMap.physics[ii]; + let constraint = skeletonData.findPhysicsConstraint(constraintName); + if (!constraint) throw new Error(`Couldn't find physics constraint ${constraintName} for skin ${skinMap.name}.`); + skin.constraints.push(constraint); + } + } + for (let slotName in skinMap.attachments) { + let slot = skeletonData.findSlot(slotName); + if (!slot) throw new Error(`Couldn't find slot ${slotName} for skin ${skinMap.name}.`); + let slotMap = skinMap.attachments[slotName]; + for (let entryName in slotMap) { + let attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); + if (attachment) skin.setAttachment(slot.index, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") skeletonData.defaultSkin = skin; + } + } + for (let i = 0, n = this.linkedMeshes.length; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + let skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (!skin) throw new Error(`Skin not found: ${linkedMesh.skin}`); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (!parent) throw new Error(`Parent mesh not found: ${linkedMesh.parent}`); + linkedMesh.mesh.timelineAttachment = linkedMesh.inheritTimeline ? parent : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent); + if (linkedMesh.mesh.region != null) linkedMesh.mesh.updateRegion(); + } + this.linkedMeshes.length = 0; + if (root.events) { + for (let eventName in root.events) { + let eventMap = root.events[eventName]; + let data = new EventData(eventName); + data.intValue = getValue(eventMap, "int", 0); + data.floatValue = getValue(eventMap, "float", 0); + data.stringValue = getValue(eventMap, "string", ""); + data.audioPath = getValue(eventMap, "audio", null); + if (data.audioPath) { + data.volume = getValue(eventMap, "volume", 1); + data.balance = getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + if (root.animations) { + for (let animationName in root.animations) { + let animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + } + readAttachment(map, skin, slotIndex, name, skeletonData) { + let scale = this.scale; + name = getValue(map, "name", name); + switch (getValue(map, "type", "region")) { + case "region": { + let path = getValue(map, "path", name); + let sequence = this.readSequence(getValue(map, "sequence", null)); + let region = this.attachmentLoader.newRegionAttachment(skin, name, path, sequence); + if (!region) return null; + region.path = path; + region.x = getValue(map, "x", 0) * scale; + region.y = getValue(map, "y", 0) * scale; + region.scaleX = getValue(map, "scaleX", 1); + region.scaleY = getValue(map, "scaleY", 1); + region.rotation = getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + region.sequence = sequence; + let color = getValue(map, "color", null); + if (color) region.color.setFromString(color); + if (region.region != null) region.updateRegion(); + return region; + } + case "boundingbox": { + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (!box) return null; + this.readVertices(map, box, map.vertexCount << 1); + let color = getValue(map, "color", null); + if (color) box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + let path = getValue(map, "path", name); + let sequence = this.readSequence(getValue(map, "sequence", null)); + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path, sequence); + if (!mesh) return null; + mesh.path = path; + let color = getValue(map, "color", null); + if (color) mesh.color.setFromString(color); + mesh.width = getValue(map, "width", 0) * scale; + mesh.height = getValue(map, "height", 0) * scale; + mesh.sequence = sequence; + let parent = getValue(map, "parent", null); + if (parent) { + this.linkedMeshes.push(new LinkedMesh2(mesh, getValue(map, "skin", null), slotIndex, parent, getValue(map, "timelines", true))); + return mesh; + } + let uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = uvs; + if (mesh.region != null) mesh.updateRegion(); + mesh.edges = getValue(map, "edges", null); + mesh.hullLength = getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + let path = this.attachmentLoader.newPathAttachment(skin, name); + if (!path) return null; + path.closed = getValue(map, "closed", false); + path.constantSpeed = getValue(map, "constantSpeed", true); + let vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + let lengths = Utils.newArray(vertexCount / 3, 0); + for (let i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + let color = getValue(map, "color", null); + if (color) path.color.setFromString(color); + return path; + } + case "point": { + let point = this.attachmentLoader.newPointAttachment(skin, name); + if (!point) return null; + point.x = getValue(map, "x", 0) * scale; + point.y = getValue(map, "y", 0) * scale; + point.rotation = getValue(map, "rotation", 0); + let color = getValue(map, "color", null); + if (color) point.color.setFromString(color); + return point; + } + case "clipping": { + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (!clip) return null; + let end = getValue(map, "end", null); + if (end) clip.endSlot = skeletonData.findSlot(end); + let vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + let color = getValue(map, "color", null); + if (color) clip.color.setFromString(color); + return clip; + } + } + return null; + } + readSequence(map) { + if (map == null) return null; + let sequence = new Sequence(getValue(map, "count", 0)); + sequence.start = getValue(map, "start", 1); + sequence.digits = getValue(map, "digits", 0); + sequence.setupIndex = getValue(map, "setup", 0); + return sequence; + } + readVertices(map, attachment, verticesLength) { + let scale = this.scale; + attachment.worldVerticesLength = verticesLength; + let vertices = map.vertices; + if (verticesLength == vertices.length) { + let scaledVertices = Utils.toFloatArray(vertices); + if (scale != 1) { + for (let i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + let weights = new Array(); + let bones = new Array(); + for (let i = 0, n = vertices.length; i < n; ) { + let boneCount = vertices[i++]; + bones.push(boneCount); + for (let nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = Utils.toFloatArray(weights); + } + readAnimation(map, name, skeletonData) { + let scale = this.scale; + let timelines = new Array(); + if (map.slots) { + for (let slotName in map.slots) { + let slotMap = map.slots[slotName]; + let slot = skeletonData.findSlot(slotName); + if (!slot) throw new Error("Slot not found: " + slotName); + let slotIndex = slot.index; + for (let timelineName in slotMap) { + let timelineMap = slotMap[timelineName]; + if (!timelineMap) continue; + let frames = timelineMap.length; + if (timelineName == "attachment") { + let timeline = new AttachmentTimeline(frames, slotIndex); + for (let frame = 0; frame < frames; frame++) { + let keyMap = timelineMap[frame]; + timeline.setFrame(frame, getValue(keyMap, "time", 0), getValue(keyMap, "name", null)); + } + timelines.push(timeline); + } else if (timelineName == "rgba") { + let timeline = new RGBATimeline(frames, frames << 2, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.color); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color.a); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.color); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); + } + time = time2; + color = newColor; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineName == "rgb") { + let timeline = new RGBTimeline(frames, frames * 3, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.color); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.color); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + } + time = time2; + color = newColor; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineName == "alpha") { + timelines.push(readTimeline12(timelineMap, new AlphaTimeline(frames, frames, slotIndex), 0, 1)); + } else if (timelineName == "rgba2") { + let timeline = new RGBA2Timeline(frames, frames * 7, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.light); + let color2 = Color.fromString(keyMap.dark); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.light); + let newColor2 = Color.fromString(nextMap.dark); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1); + } + time = time2; + color = newColor; + color2 = newColor2; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineName == "rgb2") { + let timeline = new RGB2Timeline(frames, frames * 6, slotIndex); + let keyMap = timelineMap[0]; + let time = getValue(keyMap, "time", 0); + let color = Color.fromString(keyMap.light); + let color2 = Color.fromString(keyMap.dark); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, color.r, color.g, color.b, color2.r, color2.g, color2.b); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let newColor = Color.fromString(nextMap.light); + let newColor2 = Color.fromString(nextMap.dark); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, color2.r, newColor2.r, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.g, newColor2.g, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.b, newColor2.b, 1); + } + time = time2; + color = newColor; + color2 = newColor2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + } + } + if (map.bones) { + for (let boneName in map.bones) { + let boneMap = map.bones[boneName]; + let bone = skeletonData.findBone(boneName); + if (!bone) throw new Error("Bone not found: " + boneName); + let boneIndex = bone.index; + for (let timelineName in boneMap) { + let timelineMap = boneMap[timelineName]; + let frames = timelineMap.length; + if (frames == 0) continue; + if (timelineName === "rotate") { + timelines.push(readTimeline12(timelineMap, new RotateTimeline(frames, frames, boneIndex), 0, 1)); + } else if (timelineName === "translate") { + let timeline = new TranslateTimeline(frames, frames << 1, boneIndex); + timelines.push(readTimeline22(timelineMap, timeline, "x", "y", 0, scale)); + } else if (timelineName === "translatex") { + let timeline = new TranslateXTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, scale)); + } else if (timelineName === "translatey") { + let timeline = new TranslateYTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, scale)); + } else if (timelineName === "scale") { + let timeline = new ScaleTimeline(frames, frames << 1, boneIndex); + timelines.push(readTimeline22(timelineMap, timeline, "x", "y", 1, 1)); + } else if (timelineName === "scalex") { + let timeline = new ScaleXTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 1, 1)); + } else if (timelineName === "scaley") { + let timeline = new ScaleYTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 1, 1)); + } else if (timelineName === "shear") { + let timeline = new ShearTimeline(frames, frames << 1, boneIndex); + timelines.push(readTimeline22(timelineMap, timeline, "x", "y", 0, 1)); + } else if (timelineName === "shearx") { + let timeline = new ShearXTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, 1)); + } else if (timelineName === "sheary") { + let timeline = new ShearYTimeline(frames, frames, boneIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, 1)); + } else if (timelineName === "inherit") { + let timeline = new InheritTimeline(frames, bone.index); + for (let frame = 0; frame < timelineMap.length; frame++) { + let aFrame = timelineMap[frame]; + timeline.setFrame(frame, getValue(aFrame, "time", 0), Utils.enumValue(Inherit, getValue(aFrame, "inherit", "Normal"))); + } + timelines.push(timeline); + } + } + } + } + if (map.ik) { + for (let constraintName in map.ik) { + let constraintMap = map.ik[constraintName]; + let keyMap = constraintMap[0]; + if (!keyMap) continue; + let constraint = skeletonData.findIkConstraint(constraintName); + if (!constraint) throw new Error("IK Constraint not found: " + constraintName); + let constraintIndex = skeletonData.ikConstraints.indexOf(constraint); + let timeline = new IkConstraintTimeline(constraintMap.length, constraintMap.length << 1, constraintIndex); + let time = getValue(keyMap, "time", 0); + let mix = getValue(keyMap, "mix", 1); + let softness = getValue(keyMap, "softness", 0) * scale; + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mix, softness, getValue(keyMap, "bendPositive", true) ? 1 : -1, getValue(keyMap, "compress", false), getValue(keyMap, "stretch", false)); + let nextMap = constraintMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let mix2 = getValue(nextMap, "mix", 1); + let softness2 = getValue(nextMap, "softness", 0) * scale; + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, scale); + } + time = time2; + mix = mix2; + softness = softness2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + if (map.transform) { + for (let constraintName in map.transform) { + let timelineMap = map.transform[constraintName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + let constraint = skeletonData.findTransformConstraint(constraintName); + if (!constraint) throw new Error("Transform constraint not found: " + constraintName); + let constraintIndex = skeletonData.transformConstraints.indexOf(constraint); + let timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, constraintIndex); + let time = getValue(keyMap, "time", 0); + let mixRotate = getValue(keyMap, "mixRotate", 1); + let mixX = getValue(keyMap, "mixX", 1); + let mixY = getValue(keyMap, "mixY", mixX); + let mixScaleX = getValue(keyMap, "mixScaleX", 1); + let mixScaleY = getValue(keyMap, "mixScaleY", mixScaleX); + let mixShearY = getValue(keyMap, "mixShearY", 1); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let mixRotate2 = getValue(nextMap, "mixRotate", 1); + let mixX2 = getValue(nextMap, "mixX", 1); + let mixY2 = getValue(nextMap, "mixY", mixX2); + let mixScaleX2 = getValue(nextMap, "mixScaleX", 1); + let mixScaleY2 = getValue(nextMap, "mixScaleY", mixScaleX2); + let mixShearY2 = getValue(nextMap, "mixShearY", 1); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixScaleX = mixScaleX2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + if (map.path) { + for (let constraintName in map.path) { + let constraintMap = map.path[constraintName]; + let constraint = skeletonData.findPathConstraint(constraintName); + if (!constraint) throw new Error("Path constraint not found: " + constraintName); + let constraintIndex = skeletonData.pathConstraints.indexOf(constraint); + for (let timelineName in constraintMap) { + let timelineMap = constraintMap[timelineName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + let frames = timelineMap.length; + if (timelineName === "position") { + let timeline = new PathConstraintPositionTimeline(frames, frames, constraintIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, constraint.positionMode == 0 /* Fixed */ ? scale : 1)); + } else if (timelineName === "spacing") { + let timeline = new PathConstraintSpacingTimeline(frames, frames, constraintIndex); + timelines.push(readTimeline12(timelineMap, timeline, 0, constraint.spacingMode == 0 /* Length */ || constraint.spacingMode == 1 /* Fixed */ ? scale : 1)); + } else if (timelineName === "mix") { + let timeline = new PathConstraintMixTimeline(frames, frames * 3, constraintIndex); + let time = getValue(keyMap, "time", 0); + let mixRotate = getValue(keyMap, "mixRotate", 1); + let mixX = getValue(keyMap, "mixX", 1); + let mixY = getValue(keyMap, "mixY", mixX); + for (let frame = 0, bezier = 0; ; frame++) { + timeline.setFrame(frame, time, mixRotate, mixX, mixY); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let mixRotate2 = getValue(nextMap, "mixRotate", 1); + let mixX2 = getValue(nextMap, "mixX", 1); + let mixY2 = getValue(nextMap, "mixY", mixX2); + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + keyMap = nextMap; + } + timelines.push(timeline); + } + } + } + } + if (map.physics) { + for (let constraintName in map.physics) { + let constraintMap = map.physics[constraintName]; + let constraintIndex = -1; + if (constraintName.length > 0) { + let constraint = skeletonData.findPhysicsConstraint(constraintName); + if (!constraint) throw new Error("Physics constraint not found: " + constraintName); + constraintIndex = skeletonData.physicsConstraints.indexOf(constraint); + } + for (let timelineName in constraintMap) { + let timelineMap = constraintMap[timelineName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + let frames = timelineMap.length; + if (timelineName == "reset") { + const timeline2 = new PhysicsConstraintResetTimeline(frames, constraintIndex); + for (let frame = 0; keyMap != null; keyMap = timelineMap[frame + 1], frame++) + timeline2.setFrame(frame, getValue(keyMap, "time", 0)); + timelines.push(timeline2); + continue; + } + let timeline; + if (timelineName == "inertia") + timeline = new PhysicsConstraintInertiaTimeline(frames, frames, constraintIndex); + else if (timelineName == "strength") + timeline = new PhysicsConstraintStrengthTimeline(frames, frames, constraintIndex); + else if (timelineName == "damping") + timeline = new PhysicsConstraintDampingTimeline(frames, frames, constraintIndex); + else if (timelineName == "mass") + timeline = new PhysicsConstraintMassTimeline(frames, frames, constraintIndex); + else if (timelineName == "wind") + timeline = new PhysicsConstraintWindTimeline(frames, frames, constraintIndex); + else if (timelineName == "gravity") + timeline = new PhysicsConstraintGravityTimeline(frames, frames, constraintIndex); + else if (timelineName == "mix") + timeline = new PhysicsConstraintMixTimeline(frames, frames, constraintIndex); + else + continue; + timelines.push(readTimeline12(timelineMap, timeline, 0, 1)); + } + } + } + if (map.attachments) { + for (let attachmentsName in map.attachments) { + let attachmentsMap = map.attachments[attachmentsName]; + let skin = skeletonData.findSkin(attachmentsName); + if (!skin) throw new Error("Skin not found: " + attachmentsName); + for (let slotMapName in attachmentsMap) { + let slotMap = attachmentsMap[slotMapName]; + let slot = skeletonData.findSlot(slotMapName); + if (!slot) throw new Error("Slot not found: " + slotMapName); + let slotIndex = slot.index; + for (let attachmentMapName in slotMap) { + let attachmentMap = slotMap[attachmentMapName]; + let attachment = skin.getAttachment(slotIndex, attachmentMapName); + for (let timelineMapName in attachmentMap) { + let timelineMap = attachmentMap[timelineMapName]; + let keyMap = timelineMap[0]; + if (!keyMap) continue; + if (timelineMapName == "deform") { + let weighted = attachment.bones; + let vertices = attachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment); + let time = getValue(keyMap, "time", 0); + for (let frame = 0, bezier = 0; ; frame++) { + let deform; + let verticesValue = getValue(keyMap, "vertices", null); + if (!verticesValue) + deform = weighted ? Utils.newFloatArray(deformLength) : vertices; + else { + deform = Utils.newFloatArray(deformLength); + let start = getValue(keyMap, "offset", 0); + Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (let i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (let i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frame, time, deform); + let nextMap = timelineMap[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + break; + } + let time2 = getValue(nextMap, "time", 0); + let curve = keyMap.curve; + if (curve) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1); + time = time2; + keyMap = nextMap; + } + timelines.push(timeline); + } else if (timelineMapName == "sequence") { + let timeline = new SequenceTimeline(timelineMap.length, slotIndex, attachment); + let lastDelay = 0; + for (let frame = 0; frame < timelineMap.length; frame++) { + let delay = getValue(keyMap, "delay", lastDelay); + let time = getValue(keyMap, "time", 0); + let mode = SequenceMode[getValue(keyMap, "mode", "hold")]; + let index = getValue(keyMap, "index", 0); + timeline.setFrame(frame, time, mode, index, delay); + lastDelay = delay; + keyMap = timelineMap[frame + 1]; + } + timelines.push(timeline); + } + } + } + } + } + } + if (map.drawOrder) { + let timeline = new DrawOrderTimeline(map.drawOrder.length); + let slotCount = skeletonData.slots.length; + let frame = 0; + for (let i = 0; i < map.drawOrder.length; i++, frame++) { + let drawOrderMap = map.drawOrder[i]; + let drawOrder = null; + let offsets = getValue(drawOrderMap, "offsets", null); + if (offsets) { + drawOrder = Utils.newArray(slotCount, -1); + let unchanged = Utils.newArray(slotCount - offsets.length, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let ii = 0; ii < offsets.length; ii++) { + let offsetMap = offsets[ii]; + let slot = skeletonData.findSlot(offsetMap.slot); + if (!slot) throw new Error("Slot not found: " + slot); + let slotIndex = slot.index; + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frame, getValue(drawOrderMap, "time", 0), drawOrder); + } + timelines.push(timeline); + } + if (map.events) { + let timeline = new EventTimeline(map.events.length); + let frame = 0; + for (let i = 0; i < map.events.length; i++, frame++) { + let eventMap = map.events[i]; + let eventData = skeletonData.findEvent(eventMap.name); + if (!eventData) throw new Error("Event not found: " + eventMap.name); + let event = new Event(Utils.toSinglePrecision(getValue(eventMap, "time", 0)), eventData); + event.intValue = getValue(eventMap, "int", eventData.intValue); + event.floatValue = getValue(eventMap, "float", eventData.floatValue); + event.stringValue = getValue(eventMap, "string", eventData.stringValue); + if (event.data.audioPath) { + event.volume = getValue(eventMap, "volume", 1); + event.balance = getValue(eventMap, "balance", 0); + } + timeline.setFrame(frame, event); + } + timelines.push(timeline); + } + let duration = 0; + for (let i = 0, n = timelines.length; i < n; i++) + duration = Math.max(duration, timelines[i].getDuration()); + skeletonData.animations.push(new Animation(name, timelines, duration)); + } + }; + var LinkedMesh2 = class { + parent; + skin; + slotIndex; + mesh; + inheritTimeline; + constructor(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritTimeline = inheritDeform; + } + }; + function readTimeline12(keys, timeline, defaultValue, scale) { + let keyMap = keys[0]; + let time = getValue(keyMap, "time", 0); + let value = getValue(keyMap, "value", defaultValue) * scale; + let bezier = 0; + for (let frame = 0; ; frame++) { + timeline.setFrame(frame, time, value); + let nextMap = keys[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + return timeline; + } + let time2 = getValue(nextMap, "time", 0); + let value2 = getValue(nextMap, "value", defaultValue) * scale; + if (keyMap.curve) bezier = readCurve(keyMap.curve, timeline, bezier, frame, 0, time, time2, value, value2, scale); + time = time2; + value = value2; + keyMap = nextMap; + } + } + function readTimeline22(keys, timeline, name1, name2, defaultValue, scale) { + let keyMap = keys[0]; + let time = getValue(keyMap, "time", 0); + let value1 = getValue(keyMap, name1, defaultValue) * scale; + let value2 = getValue(keyMap, name2, defaultValue) * scale; + let bezier = 0; + for (let frame = 0; ; frame++) { + timeline.setFrame(frame, time, value1, value2); + let nextMap = keys[frame + 1]; + if (!nextMap) { + timeline.shrink(bezier); + return timeline; + } + let time2 = getValue(nextMap, "time", 0); + let nvalue1 = getValue(nextMap, name1, defaultValue) * scale; + let nvalue2 = getValue(nextMap, name2, defaultValue) * scale; + let curve = keyMap.curve; + if (curve) { + bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale); + bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale); + } + time = time2; + value1 = nvalue1; + value2 = nvalue2; + keyMap = nextMap; + } + } + function readCurve(curve, timeline, bezier, frame, value, time1, time2, value1, value2, scale) { + if (curve == "stepped") { + timeline.setStepped(frame); + return bezier; + } + let i = value << 2; + let cx1 = curve[i]; + let cy1 = curve[i + 1] * scale; + let cx2 = curve[i + 2]; + let cy2 = curve[i + 3] * scale; + timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2); + return bezier + 1; + } + function getValue(map, property, defaultValue) { + return map[property] !== void 0 ? map[property] : defaultValue; + } + + // spine-core/src/polyfills.ts + (() => { + if (typeof Math.fround === "undefined") { + Math.fround = /* @__PURE__ */ function(array) { + return function(x) { + return array[0] = x, array[0]; + }; + }(new Float32Array(1)); + } + })(); + + // spine-canvas/src/CanvasTexture.ts + var CanvasTexture = class extends Texture { + constructor(image) { + super(image); + } + setFilters(minFilter, magFilter) { + } + setWraps(uWrap, vWrap) { + } + dispose() { + } + }; + + // spine-canvas/src/AssetManager.ts + var AssetManager = class extends AssetManagerBase { + constructor(pathPrefix = "", downloader = new Downloader()) { + super((image) => { + return new CanvasTexture(image); + }, pathPrefix, downloader); + } + }; + + // spine-canvas/src/SkeletonRenderer.ts + var worldVertices = Utils.newFloatArray(8); + var SkeletonRenderer = class _SkeletonRenderer { + static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; + static VERTEX_SIZE = 2 + 2 + 4; + ctx; + triangleRendering = false; + debugRendering = false; + vertices = Utils.newFloatArray(8 * 1024); + tempColor = new Color(); + constructor(context) { + this.ctx = context; + } + draw(skeleton) { + if (this.triangleRendering) this.drawTriangles(skeleton); + else this.drawImages(skeleton); + } + drawImages(skeleton) { + let ctx = this.ctx; + let color = this.tempColor; + let skeletonColor = skeleton.color; + let drawOrder = skeleton.drawOrder; + if (this.debugRendering) ctx.strokeStyle = "green"; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + let bone = slot.bone; + if (!bone.active) continue; + let attachment = slot.getAttachment(); + if (!(attachment instanceof RegionAttachment)) continue; + attachment.computeWorldVertices(slot, worldVertices, 0, 2); + let region = attachment.region; + let image = region.texture.getImage(); + let slotColor = slot.color; + let regionColor = attachment.color; + color.set( + skeletonColor.r * slotColor.r * regionColor.r, + skeletonColor.g * slotColor.g * regionColor.g, + skeletonColor.b * slotColor.b * regionColor.b, + skeletonColor.a * slotColor.a * regionColor.a + ); + ctx.save(); + ctx.transform(bone.a, bone.c, bone.b, bone.d, bone.worldX, bone.worldY); + ctx.translate(attachment.offset[0], attachment.offset[1]); + ctx.rotate(attachment.rotation * Math.PI / 180); + let atlasScale = attachment.width / region.originalWidth; + ctx.scale(atlasScale * attachment.scaleX, atlasScale * attachment.scaleY); + let w = region.width, h = region.height; + ctx.translate(w / 2, h / 2); + if (attachment.region.degrees == 90) { + let t = w; + w = h; + h = t; + ctx.rotate(-Math.PI / 2); + } + ctx.scale(1, -1); + ctx.translate(-w / 2, -h / 2); + ctx.globalAlpha = color.a; + ctx.drawImage(image, image.width * region.u, image.height * region.v, w, h, 0, 0, w, h); + if (this.debugRendering) ctx.strokeRect(0, 0, w, h); + ctx.restore(); + } + } + drawTriangles(skeleton) { + let ctx = this.ctx; + let color = this.tempColor; + let skeletonColor = skeleton.color; + let drawOrder = skeleton.drawOrder; + let blendMode = null; + let vertices = this.vertices; + let triangles = null; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + let attachment = slot.getAttachment(); + let texture; + let region; + if (attachment instanceof RegionAttachment) { + let regionAttachment = attachment; + vertices = this.computeRegionVertices(slot, regionAttachment, false); + triangles = _SkeletonRenderer.QUAD_TRIANGLES; + texture = regionAttachment.region.texture.getImage(); + } else if (attachment instanceof MeshAttachment) { + let mesh = attachment; + vertices = this.computeMeshVertices(slot, mesh, false); + triangles = mesh.triangles; + texture = mesh.region.texture.getImage(); + } else + continue; + if (texture) { + if (slot.data.blendMode != blendMode) blendMode = slot.data.blendMode; + let slotColor = slot.color; + let attachmentColor = attachment.color; + color.set( + skeletonColor.r * slotColor.r * attachmentColor.r, + skeletonColor.g * slotColor.g * attachmentColor.g, + skeletonColor.b * slotColor.b * attachmentColor.b, + skeletonColor.a * slotColor.a * attachmentColor.a + ); + ctx.globalAlpha = color.a; + for (var j = 0; j < triangles.length; j += 3) { + let t1 = triangles[j] * 8, t2 = triangles[j + 1] * 8, t3 = triangles[j + 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); + if (this.debugRendering) { + ctx.strokeStyle = "green"; + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.lineTo(x0, y0); + ctx.stroke(); + } + } + } + } + this.ctx.globalAlpha = 1; + } + // Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120 + // Apache 2 licensed + drawTriangle(img, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) { + let ctx = this.ctx; + const width = img.width - 1; + const height = img.height - 1; + u0 *= width; + v0 *= height; + u1 *= width; + v1 *= height; + u2 *= width; + v2 *= 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; + let det = u1 * v2 - u2 * v1; + if (det == 0) return; + det = 1 / det; + const a = (v2 * x1 - v1 * x2) * det; + const b = (v2 * y1 - v1 * y2) * det; + const c = (u1 * x2 - u2 * x1) * det; + const d = (u1 * y2 - u2 * y1) * det; + const e = x0 - a * u0 - c * v0; + const 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(); + } + computeRegionVertices(slot, region, pma) { + let skeletonColor = slot.bone.skeleton.color; + let slotColor = slot.color; + let regionColor = region.color; + let alpha = skeletonColor.a * slotColor.a * regionColor.a; + let multiplier = pma ? alpha : 1; + let color = this.tempColor; + color.set( + skeletonColor.r * slotColor.r * regionColor.r * multiplier, + skeletonColor.g * slotColor.g * regionColor.g * multiplier, + skeletonColor.b * slotColor.b * regionColor.b * multiplier, + alpha + ); + region.computeWorldVertices(slot, this.vertices, 0, _SkeletonRenderer.VERTEX_SIZE); + let vertices = this.vertices; + let uvs = region.uvs; + vertices[RegionAttachment.C1R] = color.r; + vertices[RegionAttachment.C1G] = color.g; + vertices[RegionAttachment.C1B] = color.b; + vertices[RegionAttachment.C1A] = color.a; + vertices[RegionAttachment.U1] = uvs[0]; + vertices[RegionAttachment.V1] = uvs[1]; + vertices[RegionAttachment.C2R] = color.r; + vertices[RegionAttachment.C2G] = color.g; + vertices[RegionAttachment.C2B] = color.b; + vertices[RegionAttachment.C2A] = color.a; + vertices[RegionAttachment.U2] = uvs[2]; + vertices[RegionAttachment.V2] = uvs[3]; + vertices[RegionAttachment.C3R] = color.r; + vertices[RegionAttachment.C3G] = color.g; + vertices[RegionAttachment.C3B] = color.b; + vertices[RegionAttachment.C3A] = color.a; + vertices[RegionAttachment.U3] = uvs[4]; + vertices[RegionAttachment.V3] = uvs[5]; + vertices[RegionAttachment.C4R] = color.r; + vertices[RegionAttachment.C4G] = color.g; + vertices[RegionAttachment.C4B] = color.b; + vertices[RegionAttachment.C4A] = color.a; + vertices[RegionAttachment.U4] = uvs[6]; + vertices[RegionAttachment.V4] = uvs[7]; + return vertices; + } + computeMeshVertices(slot, mesh, pma) { + let skeletonColor = slot.bone.skeleton.color; + let slotColor = slot.color; + let regionColor = mesh.color; + let alpha = skeletonColor.a * slotColor.a * regionColor.a; + let multiplier = pma ? alpha : 1; + let color = this.tempColor; + color.set( + skeletonColor.r * slotColor.r * regionColor.r * multiplier, + skeletonColor.g * slotColor.g * regionColor.g * multiplier, + skeletonColor.b * slotColor.b * regionColor.b * multiplier, + alpha + ); + let vertexCount = mesh.worldVerticesLength / 2; + let vertices = this.vertices; + if (vertices.length < mesh.worldVerticesLength) this.vertices = vertices = Utils.newFloatArray(mesh.worldVerticesLength); + mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, _SkeletonRenderer.VERTEX_SIZE); + let uvs = mesh.uvs; + for (let i = 0, u = 0, v = 2; i < vertexCount; i++) { + vertices[v++] = color.r; + vertices[v++] = color.g; + vertices[v++] = color.b; + vertices[v++] = color.a; + vertices[v++] = uvs[u++]; + vertices[v++] = uvs[u++]; + v += 2; + } + return vertices; + } + }; + return __toCommonJS(index_exports); +})(); +//# sourceMappingURL=spine-canvas.js.map diff --git a/codes/games/client/Projects/Spine/output/gameabc_GameTxt.json b/codes/games/client/Projects/Spine/output/gameabc_GameTxt.json new file mode 100644 index 0000000..2dd77eb --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_GameTxt.json @@ -0,0 +1,3 @@ +{ + "GameTxtList": [] +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_GroupList.json b/codes/games/client/Projects/Spine/output/gameabc_GroupList.json new file mode 100644 index 0000000..0c7cfe6 --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_GroupList.json @@ -0,0 +1,3 @@ +{ + "GroupList": [] +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_Image.json b/codes/games/client/Projects/Spine/output/gameabc_Image.json new file mode 100644 index 0000000..26837d4 --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_Image.json @@ -0,0 +1,24 @@ +{ + "ImageFileList": [ + {},{ + "id": 1, + "w_all": 1280, + "h_all": 720, + "w": 1, + "h": 1, + "frame_all": 1, + "bmp": "00001.png", + "w1": 1280, + "h1": 720 + },{ + "id": 2, + "w_all": 1920, + "h_all": 740, + "w": 1, + "h": 1, + "frame_all": 1, + "bmp": "00002.png", + "w1": 1920, + "h1": 740 + }] +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_Layer.json b/codes/games/client/Projects/Spine/output/gameabc_Layer.json new file mode 100644 index 0000000..9c57adf --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_Layer.json @@ -0,0 +1,11 @@ +{ + "LayerList": [ + {},{ + "Property": { + "LayerID": 1, + "LayerName": "Layer1" + }, + "ObjectList": [ + 1,2,3] + }] +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_Object.json b/codes/games/client/Projects/Spine/output/gameabc_Object.json new file mode 100644 index 0000000..30e5df8 --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_Object.json @@ -0,0 +1,153 @@ +{ + "ObjectList": [ + {},{ + "Property": { + "ObjectID": 1, + "ObjectType": 4, + "ObjectName": "Spirit1", + "Left": -668, + "Top": 19, + "Width": 79, + "Height": 35, + "BelongLayerID": 1, + "IndexOfLayer": 1, + "Text": "Spirit1", + "FontSize": 20, + "FontBold": 0, + "FontColorR": 0, + "FontColorG": 0, + "FontColorB": 0, + "FontColor": "#000000", + "BackColorR": 255, + "BackColorG": 255, + "BackColorB": 255, + "BackColorA": 0, + "BackColor": "#FFFFFF", + "GameTxtStyle": 0, + "LineSpace": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": -668, + "offY": 19 + }, + "Event": { + "mousedown": 1, + "mouseup": 1, + "mousemove": 1, + "ontimer": 1 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + },{ + "Property": { + "ObjectID": 2, + "ObjectType": 2, + "ObjectName": "Spirit2", + "Left": 0, + "Top": 0, + "Width": 1280, + "Height": 720, + "BelongLayerID": 1, + "IndexOfLayer": 2, + "ImageFileID": 1, + "FrameStyle": 0, + "FrameIndex": 0, + "TextFrames": "", + "L9": 0, + "T9": 0, + "R9": 0, + "B9": 0, + "VoiceFileID": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": 0, + "offY": 0 + }, + "Event": { + "mousedown": 2, + "mouseup": 2, + "mousemove": 2, + "ontimer": 2 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + },{ + "Property": { + "ObjectID": 3, + "ObjectType": 2, + "ObjectName": "Spirit3", + "Left": 393, + "Top": 412, + "Width": 560, + "Height": 148, + "BelongLayerID": 1, + "IndexOfLayer": 3, + "ImageFileID": 2, + "FrameStyle": 0, + "FrameIndex": 0, + "TextFrames": "", + "L9": 0, + "T9": 0, + "R9": 0, + "B9": 0, + "VoiceFileID": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": 393, + "offY": 412 + }, + "Event": { + "mousedown": 3, + "mouseup": 3, + "mousemove": 3, + "ontimer": 3 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + }] +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_Project.json b/codes/games/client/Projects/Spine/output/gameabc_Project.json new file mode 100644 index 0000000..c3e9d8f --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_Project.json @@ -0,0 +1,44 @@ +{ + "Property": { + "ProjectName": "Spine", + "ScreenWidth": 1280, + "ScreenHeight": 720, + "GameSceneWidth": 2337, + "GameSceneHeight": 1800, + "ScreenFitMode": 0, + "TcpIP": "", + "TcpPort": "", + "Http": "", + "title": "" + }, + "Event": { + "gamestart": 0, + "gamebegindraw": 0, + "gameenddraw": 0, + "mousedown": 0, + "mousedown_nomove": 0, + "mouseup": 0, + "mousemove": 0, + "gamemydraw": 0, + "gamemydrawbegin": 0, + "chongzhi": 0, + "tcpconnected": 0, + "tcpdisconnected": 0, + "tcpmessage": 0, + "tcperror": 0, + "httpmessage": 0, + "ani_doend": 0, + "box_doend": 0, + "onresize": 0, + "ontimer": 0, + "onloadurl": 0 + }, + "Option": { + "fps": 30, + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "showmodel": 0 + } +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_Voice.json b/codes/games/client/Projects/Spine/output/gameabc_Voice.json new file mode 100644 index 0000000..3586e1d --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_Voice.json @@ -0,0 +1,3 @@ +{ + "VoiceFileList": [] +} \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/output/gameabc_data.js b/codes/games/client/Projects/Spine/output/gameabc_data.js new file mode 100644 index 0000000..2322732 --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_data.js @@ -0,0 +1,255 @@ +var gameabc_Project = +{ + "Property": { + "ProjectName": "Spine", + "ScreenWidth": 1280, + "ScreenHeight": 720, + "GameSceneWidth": 2337, + "GameSceneHeight": 1800, + "ScreenFitMode": 0, + "TcpIP": "", + "TcpPort": "", + "Http": "", + "title": "" + }, + "Event": { + "gamestart": 0, + "gamebegindraw": 0, + "gameenddraw": 0, + "mousedown": 0, + "mousedown_nomove": 0, + "mouseup": 0, + "mousemove": 0, + "gamemydraw": 0, + "gamemydrawbegin": 0, + "chongzhi": 0, + "tcpconnected": 0, + "tcpdisconnected": 0, + "tcpmessage": 0, + "tcperror": 0, + "httpmessage": 0, + "ani_doend": 0, + "box_doend": 0, + "onresize": 0, + "ontimer": 0, + "onloadurl": 0 + }, + "Option": { + "fps": 30, + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "showmodel": 0 + } +} +; +var gameabc_Layer = +{ + "LayerList": [ + {},{ + "Property": { + "LayerID": 1, + "LayerName": "Layer1" + }, + "ObjectList": [ + 1,2,3] + }] +} +; +var gameabc_GroupList = +{ + "GroupList": [] +} +; +var gameabc_Object = +{ + "ObjectList": [ + {},{ + "Property": { + "ObjectID": 1, + "ObjectType": 4, + "ObjectName": "Spirit1", + "Left": -668, + "Top": 19, + "Width": 79, + "Height": 35, + "BelongLayerID": 1, + "IndexOfLayer": 1, + "Text": "Spirit1", + "FontSize": 20, + "FontBold": 0, + "FontColorR": 0, + "FontColorG": 0, + "FontColorB": 0, + "FontColor": "#000000", + "BackColorR": 255, + "BackColorG": 255, + "BackColorB": 255, + "BackColorA": 0, + "BackColor": "#FFFFFF", + "GameTxtStyle": 0, + "LineSpace": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": -668, + "offY": 19 + }, + "Event": { + "mousedown": 1, + "mouseup": 1, + "mousemove": 1, + "ontimer": 1 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + },{ + "Property": { + "ObjectID": 2, + "ObjectType": 2, + "ObjectName": "Spirit2", + "Left": 0, + "Top": 0, + "Width": 1280, + "Height": 720, + "BelongLayerID": 1, + "IndexOfLayer": 2, + "ImageFileID": 1, + "FrameStyle": 0, + "FrameIndex": 0, + "TextFrames": "", + "L9": 0, + "T9": 0, + "R9": 0, + "B9": 0, + "VoiceFileID": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": 0, + "offY": 0 + }, + "Event": { + "mousedown": 2, + "mouseup": 2, + "mousemove": 2, + "ontimer": 2 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + },{ + "Property": { + "ObjectID": 3, + "ObjectType": 2, + "ObjectName": "Spirit3", + "Left": 393, + "Top": 412, + "Width": 560, + "Height": 148, + "BelongLayerID": 1, + "IndexOfLayer": 3, + "ImageFileID": 2, + "FrameStyle": 0, + "FrameIndex": 0, + "TextFrames": "", + "L9": 0, + "T9": 0, + "R9": 0, + "B9": 0, + "VoiceFileID": 0, + "GroupID": 0, + "TimerInterval": 0, + "Data": "", + "Parent": 0, + "OriginID": 0, + "OriginPos": 1, + "SelfPos": 1, + "offX": 393, + "offY": 412 + }, + "Event": { + "mousedown": 3, + "mouseup": 3, + "mousemove": 3, + "ontimer": 3 + }, + "Option": { + "tag": 0, + "tag1": 0, + "tag2": 0, + "tag3": 0, + "vx": 0, + "vy": 0, + "vw": 0, + "vh": 0, + "canclick": 1, + "visbale": 1 + } + }] +} +; +var gameabc_Image = +{ + "ImageFileList": [ + {},{ + "id": 1, + "w_all": 1280, + "h_all": 720, + "w": 1, + "h": 1, + "frame_all": 1, + "bmp": "00001.png", + "w1": 1280, + "h1": 720 + },{ + "id": 2, + "w_all": 1920, + "h_all": 740, + "w": 1, + "h": 1, + "frame_all": 1, + "bmp": "00002.png", + "w1": 1920, + "h1": 740 + }] +} +; +var gameabc_GameTxt = +{ + "GameTxtList": [] +} +; +var gameabc_Voice = +{ + "VoiceFileList": [] +} +; diff --git a/codes/games/client/Projects/Spine/output/gameabc_data.min.js b/codes/games/client/Projects/Spine/output/gameabc_data.min.js new file mode 100644 index 0000000..b544c1c --- /dev/null +++ b/codes/games/client/Projects/Spine/output/gameabc_data.min.js @@ -0,0 +1 @@ +var gameabc_Project = { "Property": { "ProjectName": "Spine", "ScreenWidth": 1280, "ScreenHeight": 720, "GameSceneWidth": 2337, "GameSceneHeight": 1800, "ScreenFitMode": 0, "TcpIP": "", "TcpPort": "", "Http": "", "title": "" }, "Event": { "gamestart": 0, "gamebegindraw": 0, "gameenddraw": 0, "mousedown": 0, "mousedown_nomove": 0, "mouseup": 0, "mousemove": 0, "gamemydraw": 0, "gamemydrawbegin": 0, "chongzhi": 0, "tcpconnected": 0, "tcpdisconnected": 0, "tcpmessage": 0, "tcperror": 0, "httpmessage": 0, "ani_doend": 0, "box_doend": 0, "onresize": 0, "ontimer": 0, "onloadurl": 0 }, "Option": { "fps": 30, "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "showmodel": 0 }};var gameabc_Layer = { "LayerList": [ {},{ "Property": { "LayerID": 1, "LayerName": "Layer1" }, "ObjectList": [ 1,2,3] }]};var gameabc_GroupList = { "GroupList": []};var gameabc_Object = { "ObjectList": [ {},{ "Property": { "ObjectID": 1, "ObjectType": 4, "ObjectName": "Spirit1", "Left": -668, "Top": 19, "Width": 79, "Height": 35, "BelongLayerID": 1, "IndexOfLayer": 1, "Text": "Spirit1", "FontSize": 20, "FontBold": 0, "FontColorR": 0, "FontColorG": 0, "FontColorB": 0, "FontColor": "#000000", "BackColorR": 255, "BackColorG": 255, "BackColorB": 255, "BackColorA": 0, "BackColor": "#FFFFFF", "GameTxtStyle": 0, "LineSpace": 0, "GroupID": 0, "TimerInterval": 0, "Data": "", "Parent": 0, "OriginID": 0, "OriginPos": 1, "SelfPos": 1, "offX": -668, "offY": 19 }, "Event": { "mousedown": 1, "mouseup": 1, "mousemove": 1, "ontimer": 1 }, "Option": { "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "vx": 0, "vy": 0, "vw": 0, "vh": 0, "canclick": 1, "visbale": 1 } },{ "Property": { "ObjectID": 2, "ObjectType": 2, "ObjectName": "Spirit2", "Left": 0, "Top": 0, "Width": 1280, "Height": 720, "BelongLayerID": 1, "IndexOfLayer": 2, "ImageFileID": 1, "FrameStyle": 0, "FrameIndex": 0, "TextFrames": "", "L9": 0, "T9": 0, "R9": 0, "B9": 0, "VoiceFileID": 0, "GroupID": 0, "TimerInterval": 0, "Data": "", "Parent": 0, "OriginID": 0, "OriginPos": 1, "SelfPos": 1, "offX": 0, "offY": 0 }, "Event": { "mousedown": 2, "mouseup": 2, "mousemove": 2, "ontimer": 2 }, "Option": { "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "vx": 0, "vy": 0, "vw": 0, "vh": 0, "canclick": 1, "visbale": 1 } },{ "Property": { "ObjectID": 3, "ObjectType": 2, "ObjectName": "Spirit3", "Left": 393, "Top": 412, "Width": 560, "Height": 148, "BelongLayerID": 1, "IndexOfLayer": 3, "ImageFileID": 2, "FrameStyle": 0, "FrameIndex": 0, "TextFrames": "", "L9": 0, "T9": 0, "R9": 0, "B9": 0, "VoiceFileID": 0, "GroupID": 0, "TimerInterval": 0, "Data": "", "Parent": 0, "OriginID": 0, "OriginPos": 1, "SelfPos": 1, "offX": 393, "offY": 412 }, "Event": { "mousedown": 3, "mouseup": 3, "mousemove": 3, "ontimer": 3 }, "Option": { "tag": 0, "tag1": 0, "tag2": 0, "tag3": 0, "vx": 0, "vy": 0, "vw": 0, "vh": 0, "canclick": 1, "visbale": 1 } }]};var gameabc_Image = { "ImageFileList": [ {},{ "id": 1, "w_all": 1280, "h_all": 720, "w": 1, "h": 1, "frame_all": 1, "bmp": "00001.png", "w1": 1280, "h1": 720 },{ "id": 2, "w_all": 1920, "h_all": 740, "w": 1, "h": 1, "frame_all": 1, "bmp": "00002.png", "w1": 1920, "h1": 740 }]};var gameabc_GameTxt = { "GameTxtList": []};var gameabc_Voice = { "VoiceFileList": []}; diff --git a/codes/games/client/Projects/Spine/save/Layer00001.xml b/codes/games/client/Projects/Spine/save/Layer00001.xml new file mode 100644 index 0000000..8e6c63d --- /dev/null +++ b/codes/games/client/Projects/Spine/save/Layer00001.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codes/games/client/Projects/Spine/save/Project.xml b/codes/games/client/Projects/Spine/save/Project.xml new file mode 100644 index 0000000..7046fa6 --- /dev/null +++ b/codes/games/client/Projects/Spine/save/Project.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codes/games/client/Projects/Spine/save/ResImage.xml b/codes/games/client/Projects/Spine/save/ResImage.xml new file mode 100644 index 0000000..bed7f9c --- /dev/null +++ b/codes/games/client/Projects/Spine/save/ResImage.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/codes/games/client/Projects/Spine/scripts/build_spine_data.cmd b/codes/games/client/Projects/Spine/scripts/build_spine_data.cmd new file mode 100644 index 0000000..98bc802 --- /dev/null +++ b/codes/games/client/Projects/Spine/scripts/build_spine_data.cmd @@ -0,0 +1,17 @@ +@echo off +chcp 65001 >nul +REM ============================================================ +REM Spine èµ„æºæ•°æ®ç”Ÿæˆè„šæœ¬ +REM 扫æ assets/spine/ 目录,自动生æˆï¼š +REM generated/spine_assets.js — 资æºåæ¸…å• +REM generated/spine_data.js — .json/.atlas 文本内容嵌入 +REM +REM 用法:åŒå‡»è¿è¡Œï¼Œæˆ–在命令行执行: +REM cd codes\games\client\Projects\Spine\scripts +REM build_spine_data.cmd +REM ============================================================ + +pushd "%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0build_spine_data.ps1" +popd +pause diff --git a/codes/games/client/Projects/Spine/scripts/build_spine_data.ps1 b/codes/games/client/Projects/Spine/scripts/build_spine_data.ps1 new file mode 100644 index 0000000..8d73558 --- /dev/null +++ b/codes/games/client/Projects/Spine/scripts/build_spine_data.ps1 @@ -0,0 +1,99 @@ +# Spine resource data generation script +# Scans assets/spine/ directory and generates: +# generated/spine_assets.js - resource name list +# generated/spine_data.js - .json/.atlas text content embedded (file:// CORS fix) + +$ErrorActionPreference = "Stop" + +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$projectDir = Split-Path -Parent $scriptDir +$spineDir = Join-Path $projectDir "assets\spine" +$outDir = Join-Path $projectDir "generated" +$assetsOut = Join-Path $outDir "spine_assets.js" +$dataOut = Join-Path $outDir "spine_data.js" + +if (-not (Test-Path $outDir)) { + New-Item -ItemType Directory -Path $outDir | Out-Null +} + +if (-not (Test-Path $spineDir)) { + Write-Host "[WARN] Spine assets directory not found: $spineDir — generating empty files" -ForegroundColor Yellow + $jsonFiles = @() +} else { + $jsonFiles = Get-ChildItem $spineDir -Filter "*.json" | Sort-Object Name +} + +if ($jsonFiles.Count -eq 0) { + Write-Host "[INFO] No .json files found — generating empty placeholder files" -ForegroundColor Yellow + + $utf8NoBom = New-Object System.Text.UTF8Encoding($false) + [System.IO.File]::WriteAllText($assetsOut, "// Spine resource list (auto-generated, do not edit manually)`ngameabc_face.spineAssets = [];`n", $utf8NoBom) + [System.IO.File]::WriteAllText($dataOut, "// Spine text data (auto-generated, do not edit manually)`ngameabc_face.spineTextData = {};`n", $utf8NoBom) + + Write-Host "[OK] $assetsOut (empty)" -ForegroundColor Green + Write-Host "[OK] $dataOut (empty)" -ForegroundColor Green + exit 0 +} + +$names = @() +foreach ($f in $jsonFiles) { + $names += $f.BaseName +} + +Write-Host "Found $($names.Count) Spine resource(s): $($names -join ', ')" -ForegroundColor Cyan + +# ==================== spine_assets.js ==================== +$assetsSB = [System.Text.StringBuilder]::new() +[void]$assetsSB.AppendLine('// Spine resource list (auto-generated, do not edit manually)') +[void]$assetsSB.Append('gameabc_face.spineAssets = [') + +for ($i = 0; $i -lt $names.Count; $i++) { + if ($i -gt 0) { [void]$assetsSB.Append(',') } + [void]$assetsSB.AppendLine('') + [void]$assetsSB.Append("`t`"$($names[$i])`"") +} + +[void]$assetsSB.AppendLine('') +[void]$assetsSB.AppendLine('];') + +$utf8NoBom = New-Object System.Text.UTF8Encoding($false) +[System.IO.File]::WriteAllText($assetsOut, $assetsSB.ToString(), $utf8NoBom) +Write-Host "[OK] $assetsOut" -ForegroundColor Green + +# ==================== spine_data.js ==================== +$dataSB = [System.Text.StringBuilder]::new() +[void]$dataSB.AppendLine('// Spine text data (auto-generated, do not edit manually)') +[void]$dataSB.AppendLine('// Embeds .json/.atlas content into JS to bypass file:// XHR CORS') +[void]$dataSB.AppendLine('gameabc_face.spineTextData = {};') + +$totalOriginal = 0 + +foreach ($name in $names) { + foreach ($ext in '.json', '.atlas') { + $filePath = Join-Path $spineDir "$name$ext" + if (-not (Test-Path $filePath)) { + Write-Host "[WARN] Missing file: $name$ext" -ForegroundColor Yellow + continue + } + + $raw = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::UTF8) + $totalOriginal += (Get-Item $filePath).Length + + $escaped = $raw.Replace('\', '\\').Replace("'", "\'") + $escaped = $escaped.Replace("`r`n", '\n').Replace("`n", '\n').Replace("`r", '') + + [void]$dataSB.AppendLine("gameabc_face.spineTextData['$name$ext'] = '$escaped';") + } +} + +[System.IO.File]::WriteAllText($dataOut, $dataSB.ToString(), $utf8NoBom) + +$dataSize = (Get-Item $dataOut).Length +$overhead = $dataSize - $totalOriginal + +Write-Host "[OK] $dataOut" -ForegroundColor Green +Write-Host '' +Write-Host '=== Summary ===' -ForegroundColor Cyan +Write-Host " Resources: $($names.Count)" +Write-Host " Original size: $([math]::Round($totalOriginal/1024, 1)) KB" +Write-Host " Output size: $([math]::Round($dataSize/1024, 1)) KB (overhead: $overhead bytes)" \ No newline at end of file diff --git a/codes/games/client/Projects/Spine/server.html b/codes/games/client/Projects/Spine/server.html new file mode 100644 index 0000000..bb413e6 --- /dev/null +++ b/codes/games/client/Projects/Spine/server.html @@ -0,0 +1,141 @@ + + + + + + + + +gameabc + + + + + +

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/codes/games/server/games/erqiwang/class.arith.js b/codes/games/server/games/erqiwang/class.arith.js new file mode 100644 index 0000000..3a73979 --- /dev/null +++ b/codes/games/server/games/erqiwang/class.arith.js @@ -0,0 +1,1089 @@ +/////////////////////////////////////////////////// +////////// cls_youle_erqiwang_arith: 算法 ///////// +/////////////////////////////////////////////////// +var cls_youle_erqiwang_arith = cls_youle_erqiwang_arith || { + + //æ ¹æ®å«åˆ†è®¡ç®—倿•° + get_multiple_bycall: function(callgrade){ + if (callgrade > 60){ + return 1; + } + if (callgrade > 40){ + return 2; + } + if (callgrade > 0){ + return 4; + } + return 0; + }, + + //牌id转花色 + id_to_flower: function(cardid){ + if (cardid == 52 || cardid == 106){ + //å°çŽ‹ + return 5; + } + if (cardid == 53 || cardid == 107){ + //大王 + return 5; + } + return parseInt((cardid % 54) / 13) + 1; + }, + + //牌idè½¬ç‰Œé¢æ•°å€¼ + id_to_number: function(cardid){ + if (cardid == 52 || cardid == 106){ + //å°çŽ‹ + return 53; + } + if (cardid == 53 || cardid == 107){ + //大王 + return 54; + } + return (cardid % 54) % 13 + 1; + }, + + //牌idè½¬ç‰Œç¼–ç  + id_to_code: function(mainflower, cardid){ + if (cardid == 52 || cardid == 106){ + //å°çŽ‹ + return 9553; + } + if (cardid == 53 || cardid == 107){ + //大王 + return 9554; + } + var flower = cls_youle_erqiwang_arith.id_to_flower(cardid); + var number = cls_youle_erqiwang_arith.id_to_number(cardid); + var code = flower * 100 + number; + //ç‰¹æ®Šå¤„ç† + switch (number) + { + case 1: + code = code + 13; + break; + case 2: + code = code + 2000; + break; + case 7: + code = code + 7000; + break; + } + //ä¸»ç‰ŒèŠ±è‰²å¤„ç† + if (flower == mainflower){ + code = code + 1000; + } + return code; + }, + + //ä»Žå¤§åˆ°å°æŽ’åº(冒泡排åº) + order_cards: function(mainflower, aryCardIDs){ + if (aryCardIDs){ + for (var i = 0; i < aryCardIDs.length; i++) { + for (var j = i + 1; j < aryCardIDs.length; j++) { + var i_code = cls_youle_erqiwang_arith.id_to_code(mainflower, aryCardIDs[i]); + var j_code = cls_youle_erqiwang_arith.id_to_code(mainflower, aryCardIDs[j]); + if (i_code < j_code) { + var tmp = aryCardIDs[j]; + aryCardIDs[j] = aryCardIDs[i]; + aryCardIDs[i] = tmp; + } + } + } + } + return aryCardIDs; + }, + + //åˆ¤æ–­ä¸¤ä¸ªç‰Œæ˜¯å¦æ˜¯è¿žç»­çš„ + is_continuous: function(bigcode, smallcode){ + //是å°çŽ‹ + var is_xiaowang = function(_code){ + if (_code == 9553){ + return true; + } + return false; + } + //是正7 + var is_zheng7 = function(_code){ + if (_code > 8000 && _code < 9000){ + return true; + } + return false; + } + //是负7 + var is_fu7 = function(_code){ + if (_code > 7000 && _code < 8000){ + return true; + } + return false; + } + //是正2 + var is_zheng2 = function(_code){ + if (_code > 3000 && _code < 4000){ + return true; + } + return false; + } + //是负2 + var is_fu2 = function(_code){ + if (_code > 2000 && _code < 3000){ + return true; + } + return false; + } + //是主A + var is_zhuA = function(_code){ + if (_code > 1000 && _code < 2000 && _code % 100 == 14){ + return true; + } + return false; + } + //是8 + var is_8 = function(_code){ + if (_code % 100 == 8){ + return true; + } + return false; + } + //是6 + var is_6 = function(_code){ + if (_code % 100 == 6){ + return true; + } + return false; + } + + //普通的连牌 + if (bigcode - smallcode == 1){ + return true; + } + //å°çŽ‹ã€æ­£7 + if (is_xiaowang(bigcode) && is_zheng7(smallcode)){ + return true; + } + //æ­£7ã€è´Ÿ7 + if (is_zheng7(bigcode) && is_fu7(smallcode)){ + return true; + } + //è´Ÿ7ã€æ­£2 + if (is_fu7(bigcode) && is_zheng2(smallcode)){ + return true; + } + //æ­£2ã€è´Ÿ2 + if (is_zheng2(bigcode) && is_fu2(smallcode)){ + return true; + } + //è´Ÿ2ã€ä¸»A + if (is_fu2(bigcode) && is_zhuA(smallcode)){ + return true; + } + //8ã€6 + if (is_8(bigcode) && is_6(smallcode)){ + return true; + } + return false; + }, + + //获å–对å­åˆ—表,cards为åŒä¸€èŠ±è‰²çš„æŽ’è¿‡åºçš„牌列表 + get_pairlist: function(mainflower, flowercards){ + var pairlist = []; + var i = 0; + while (i < flowercards.length - 1){ + //牌编ç ï¼Œä¸¤å¼ ç‰Œä¸¤å¼ ç‰Œä¸€å– + var code_i = cls_youle_erqiwang_arith.id_to_code(mainflower, flowercards[i]); + var code_j = cls_youle_erqiwang_arith.id_to_code(mainflower, flowercards[i + 1]); + if (code_i == code_j){ + pairlist.push([flowercards[i], flowercards[i + 1]]); + i = i + 2; + } else { + i++; + } + } + return pairlist; + }, + + //èŽ·å–æ‹–拉机列表,pairlist为åŒä¸€èŠ±è‰²çš„æŽ’è¿‡åºçš„对å­åˆ—表,cardtype为拖拉机牌型 + get_tuolaji_list: function(mainflower, pairlist, cardtype){ + var tuolaji = []; + var count = cardtype - 300; //æ‹–æ‹‰æœºçš„å¯¹å­æ•°é‡ + var i = 0; + for (var i = 0; i < pairlist.length - count + 1; i++){ + //æ¯æ¬¡æŒ‰æ‹–æ‹‰æœºçš„å¯¹å­æ•°é‡å–N对 + var tmplist = pairlist.slice(i, i + count); + //åˆ¤æ–­æ˜¯å¦æ˜¯cardtype类型的拖拉机 + var is_tlj = true; + for (var j = 0; j < tmplist.length - 1; j++) { + var code_j1 = cls_youle_erqiwang_arith.id_to_code(mainflower, tmplist[j][0]); + var code_j2 = cls_youle_erqiwang_arith.id_to_code(mainflower, tmplist[j+1][0]); + if (!cls_youle_erqiwang_arith.is_continuous(code_j1, code_j2)){ + is_tlj = false; + break; + } + } + if (is_tlj){ + var tlj = []; + for (var k = 0; k < tmplist.length; k++){ + tlj = tlj.concat(tmplist[k]); + } + tuolaji.push(tlj); + } + } + return tuolaji; + }, + + //第一个ä½ç½®æ˜¯å¦å¯å‡ºç‰Œ + can_playcard: function(mainflower, cards, selfseat, seatlist){ + /* + 傿•°: + mainflower: 主牌花色 + cards : è¦å‡ºçš„牌id列表 + selfseat : 出牌者的ä½ç½® + seatlist : 座ä½åˆ—表,四维数组, + [ //第一层表示玩家,与ä½ç½®åºå·å¯¹åº” + [ //第二层表示花色,与花色-1对应 + [ + 0, //无该花色的牌标志 + 0 //该花色无对标志 + ], [0, 0], [0, 0], [0, 0] + ], + [[0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0]] + ] + 返回结果json: + result : trueå¯å‡ºï¼Œfalseä¸å¯å‡º + flower : 花色,result=falseæ—¶æ— æ­¤å±žæ€§ï¼Œä¸‹åŒ + cardtype : 牌型 + cardvalue: ç‰Œåž‹å€¼ï¼Œå–æ»¡è¶³ç‰Œåž‹çš„æœ€å°ç‰Œçš„ç‰Œç¼–ç  + */ + + //返回的结果 + var can = {}; + can.result = true; + can.flower = null; + can.cardtype = null; + can.cardvalue = null; + + //返回ä¸èƒ½å‡ºç‰Œçš„结果 + var do_returnfalse = function(){ + can.result = false; + delete can.flower; + delete can.cardtype; + delete can.cardvalue; + } + + //规则外的约定,一次最多åªèƒ½å‡º14张牌 + if (cards.length > 14){ + do_returnfalse; + return can; + } + + /////////// 计算牌型 /////////// + //å°†ç‰Œä»Žå¤§åˆ°å°æŽ’åº + cards = cls_youle_erqiwang_arith.order_cards(mainflower, cards); + var i = 0; + while (i < cards.length){ + //ç‰Œç¼–ç  + var code = cls_youle_erqiwang_arith.id_to_code(mainflower, cards[i]); + //牌的花色 + var flower = parseInt(code / 100); + if (code > 1000){ //大于1000是主牌 + flower = mainflower; + } + + //是第一张牌 + if (i == 0){ + can.flower = flower; + can.cardtype = 101; + can.cardvalue = code; + i++; + continue; + } + + //䏿˜¯ç¬¬ä¸€å¼ ç‰Œ + //花色必须一致 + if (flower != can.flower){ + do_returnfalse(); + return can; + } + + //之剿˜¯å•张牌型 + if (can.cardtype > 100 && can.cardtype < 200){ + if (can.cardtype == 101 && code == can.cardvalue){ + can.cardtype = 201; //是一对 + } else { + can.cardtype = can.cardtype + 1; //å•张甩牌 + can.cardvalue = code; + } + i++; + continue; + } + + //之剿˜¯å¯¹å­æˆ–æ‹–æ‹‰æœºç‰Œåž‹ï¼Œåˆ™ä¸¤å¼ ä¸¤å¼ ç‰Œä¸€å– + //如果是最åŽä¸€å¼ ç‰Œï¼Œå–ä¸åˆ°åŽé¢ä¸€å¼ ç‰Œäº† + if (i == cards.length - 1){ + can.cardtype = 100 + i + 1; //å•张甩牌 + can.cardvalue = code; + i++; + continue; + } + + //åŽé¢ä¸€å¼ ç‰Œçš„ç¼–ç  + var code_2 = cls_youle_erqiwang_arith.id_to_code(mainflower, cards[i + 1]); + //åŽé¢ä¸€å¼ ç‰Œçš„花色 + var flower_2 = parseInt(code_2 / 100); + if (code_2 > 1000){ //大于1000是主牌 + flower_2 = mainflower; + } + //åŽé¢ä¸€å¼ ç‰Œçš„花色必须一致 + if (flower_2 != flower){ + do_returnfalse(); + return can; + } + + //当å‰ä¸¤å¼ ç‰Œä¸æ˜¯å¯¹å­ + if (code_2 != code){ + can.cardtype = 100 + i + 2; //å•张甩牌 + can.cardvalue = code_2; + i = i + 2; + continue; + } + + //当å‰ä¸¤å¼ ç‰Œæ˜¯å¯¹å­ + //之剿˜¯å¯¹å­ç‰Œåž‹ + if (can.cardtype > 200 && can.cardtype < 300){ + if (can.cardtype == 201 && cls_youle_erqiwang_arith.is_continuous(can.cardvalue, code)){ + //之剿˜¯ä¸€å¯¹ï¼Œä¸”现在是连牌,则是拖拉机 + can.cardtype = 302; + can.cardvalue = code; + } else { + //是多对 + can.cardtype = can.cardtype + 1; //多对甩牌 + can.cardvalue = code; + } + i = i + 2; + continue; + } + + //之剿˜¯æ‹–拉机牌型 + if (can.cardtype > 300 && can.cardtype < 400){ + if (cls_youle_erqiwang_arith.is_continuous(can.cardvalue, code)){ + //现在是连牌,则还是拖拉机 + can.cardtype = can.cardtype + 1; + can.cardvalue = code; + } else { + //是多对 + can.cardtype = 200 + can.cardtype % 100 + 1; //多对甩牌 + can.cardvalue = code; + } + i = i + 2; + continue; + } + } + + /////////// ç”©ç‰Œå¤„ç† /////////// + //其他玩家没有主牌 + var other_noflower = function(_flower){ + for (var i = 0; i < seatlist.length; i++){ + if (i != selfseat){ + if (seatlist[i][_flower - 1][0] == 0){ + return false; + } + } + } + return true; + } + + //其他玩家没有主对 + var other_noflowerpair = function(_flower){ + for (var i = 0; i < seatlist.length; i++){ + if (i != selfseat){ + if (seatlist[i][_flower - 1][1] == 0){ + return false; + } + } + } + return true; + } + + //ä¸å¯ç”©ç‰Œåˆ¤æ–­ + if (can.cardtype > 101 && can.cardtype < 200){ //å•张甩牌 + //其他玩家有主牌则ä¸èƒ½ç”©ç‰Œ + if (!other_noflower(mainflower)){ + do_returnfalse(); + return can; + } + //å‰¯ç‰Œç”©ç‰Œéœ€è¦æ»¡è¶³å…¶ä»–玩家没有主牌且其他玩家都没有该花色的牌 + if (!other_noflower(can.flower)){ + do_returnfalse(); + return can; + } + } else if (can.cardtype > 201 && can.cardtype < 300){ //对å­ç”©ç‰Œ + if (can.flower == mainflower){ //甩主对 + //其他玩家有主牌对å­åˆ™ä¸èƒ½ç”©ç‰Œ + if (!other_noflowerpair(mainflower)){ + do_returnfalse(); + return can; + } + } else { //ç”©å‰¯ç‰Œå¯¹å­ + //其他玩家有主牌则ä¸èƒ½ç”©ç‰Œ + if (!other_noflower(mainflower)){ + do_returnfalse(); + return can; + } + //副牌甩牌需è¦å…¶ä»–çŽ©å®¶æ²¡æœ‰ä¸»ç‰Œä¸”å…¶ä»–çŽ©å®¶æ²¡æœ‰è¯¥èŠ±è‰²çš„å¯¹å­ + if (!other_noflowerpair(can.flower)){ + do_returnfalse(); + return can; + } + } + } + + return can; + }, + + //æ ¹æ®ç¬¬ä¸€ä¸ªçŽ©å®¶çš„å‡ºç‰ŒèŽ·å–åŽé¢çŽ©å®¶å¿…å‡ºçš„å’Œå¯å‡ºçš„牌 + get_followcard: function(mainflower, inhandcards, startcount, startflower, startcardtype){ + /* + 傿•°: + mainflower : 主牌花色 + inhandcards : 手上的牌id列表 + startcount : ç¬¬ä¸€ä¸ªçŽ©å®¶å‡ºç‰Œçš„æ•°é‡ + startflower : 第一个玩家出牌的牌花色 + startcardtype: 第一个玩家出牌的牌型 + 返回结果json: + mustcard: 必出的牌列表 + cancard : å¯å‡ºçš„牌列表 + cantype : å¯å‡ºçš„牌中需è¦çš„牌型 + */ + //返回的结果 + var re = {}; + re.mustcard = []; + re.cancard = []; + re.cantype = null; + + //æ‹·è´æ•°ç»„ + var _inhandcards = inhandcards.concat(); + //å°†ç‰Œä»Žå¤§åˆ°å°æŽ’åº + _inhandcards = cls_youle_erqiwang_arith.order_cards(mainflower, _inhandcards); + + //如果手上的牌数é‡ä¸Žè¦æ±‚的出牌数é‡ä¸€æ ·åˆ™å…¨æ˜¯å¿…出的牌 + if (_inhandcards.length == startcount){ + re.mustcard = _inhandcards; + re.cancard = []; + re.cantype = null; + return re; + } + + //获å–相åŒèŠ±è‰²çš„ç‰Œä¸Žå…¶ä»–èŠ±è‰²çš„ç‰Œ + var _startflowercards = []; //相åŒèŠ±è‰²çš„ç‰Œ + var _otherflowercards = []; //其他花色的牌 + for (var i = 0; i < _inhandcards.length; i++){ + //ç‰Œç¼–ç  + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, _inhandcards[i]); + //牌的花色 + var _flower = parseInt(_code / 100); + if (_code > 1000){ //大于1000是主牌 + _flower = mainflower; + } + if (_flower == startflower){ + _startflowercards.push(_inhandcards[i]); + } else { + _otherflowercards.push(_inhandcards[i]); + } + } + + //如果没有相åŒèŠ±è‰²çš„ç‰Œï¼Œåˆ™å…¨éƒ¨ä¸ºå¯å‡ºçš„牌 + if (_startflowercards.length == 0){ + re.mustcard = []; + re.cancard = _inhandcards; + re.cantype = 100 + startcount; + return re; + } + + //如果相åŒèŠ±è‰²çš„ç‰Œæ•°é‡ä¸å¤Ÿï¼Œåˆ™ç›¸åŒèŠ±è‰²çš„ç‰Œä¸ºå¿…å‡ºçš„ç‰Œï¼Œå…¶ä»–èŠ±è‰²ä¸ºå¯å‡ºçš„牌 + if (_startflowercards.length < startcount){ + re.mustcard = _startflowercards; + re.cancard = _otherflowercards; + re.cantype = 100 + startcount - re.mustcard.length; + return re; + } + + //如果相åŒèŠ±è‰²çš„ç‰Œæ•°é‡ä¸Žè¦æ±‚的出牌数é‡ä¸€æ ·åˆ™å…¨æ˜¯å¿…出的牌,没有å¯å‡ºçš„牌 + if (_startflowercards.length == startcount){ + re.mustcard = _startflowercards; + re.cancard = []; + re.cantype = null; + return re; + } + + //如果相åŒèŠ±è‰²çš„ç‰Œæ•°é‡å¤§äºŽè¦æ±‚çš„å‡ºç‰Œæ•°é‡ + if (startcardtype == 101){ + //一张å•å¼  + re.mustcard = []; + re.cancard = _startflowercards; + re.cantype = 100 + startcount; + return re; + } else if (startcardtype > 101 && startcardtype < 200){ + //多张å•å¼  + re.mustcard = []; + re.cancard = _startflowercards; + re.cantype = 100 + startcount; + return re; + } else if (startcardtype == 201){ + //一对 + //获å–对å­åˆ—表 + var pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, _startflowercards); + //æ²¡æœ‰å¯¹å­ + if (pairlist.length == 0){ + re.mustcard = []; + re.cancard = _startflowercards; + re.cantype = 100 + startcount; + return re; + } + //åªæœ‰ä¸€å¯¹ + if (pairlist.length == 1){ + re.mustcard = pairlist[0]; + re.cancard = []; + re.cantype = null; + return re; + } + //有多对 + re.mustcard = []; + for (var i = 0; i < pairlist.length; i++){ + re.cancard = re.cancard.concat(pairlist[i]); + } + re.cantype = 201; + return re; + } else if (startcardtype > 201 && startcardtype < 300){ + //多对 + re.mustcard = []; + re.cancard = _startflowercards; + re.cantype = 100 + startcount; + return re; + } else if (startcardtype > 300 && startcardtype < 400){ + //拖拉机 + //获å–对å­åˆ—表 + var pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, _startflowercards); + + //æ²¡æœ‰å¯¹å­ + if (pairlist.length == 0){ + re.mustcard = []; + re.cancard = _startflowercards; + re.cantype = 100 + startcount; + return re; + } + + //坹孿•°é‡ä¸å¤Ÿ + if (pairlist.length * 2 < startcount){ + for (var i = 0; i < pairlist.length; i++){ + re.mustcard = re.mustcard.concat(pairlist[i]); + } + re.cancard = min_ary_deduct(_startflowercards, re.mustcard); + re.cantype = 100 + startcount - re.mustcard.length; + return re; + } + + //坹孿•°é‡åˆšå¥½å¤Ÿ + if (pairlist.length * 2 == startcount){ + for (var i = 0; i < pairlist.length; i++){ + re.mustcard = re.mustcard.concat(pairlist[i]); + } + re.cancard = []; + re.cantype = null; + return re; + } + + //坹孿œ‰å¤š + //拖拉机列表 + var tuolaji_list = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, pairlist, startcardtype); + + //æœ‰å¤šä¸ªç¬¦åˆæ¡ä»¶çš„æ‹–拉机 + if (tuolaji_list.length > 1){ + re.mustcard = []; + re.cancard = []; + //这里è¦åŽ»é‡å¤é¡¹ + for (var i = 0; i < tuolaji_list.length; i++){ + for (var j = 0; j < tuolaji_list[i].length; j++) { + var found = false; + for (var k = 0; k < re.cancard.length; k++){ + if (re.cancard[k] == tuolaji_list[i][j]){ + found = true; + break; + } + } + if (!found){ + re.cancard.push(tuolaji_list[i][j]); + } + } + } + re.cantype = startcardtype; + return re; + } + + //åªæœ‰ä¸€ä¸ªç¬¦åˆæ¡ä»¶çš„æ‹–拉机 + if (tuolaji_list.length == 1){ + re.mustcard = tuolaji_list[0]; + re.cancard = []; + re.cantype = null; + return re; + } + + //æ²¡æœ‰ç¬¦åˆæ¡ä»¶çš„æ‹–拉机 + if (tuolaji_list.length == 0){ + re.mustcard = []; + for (var i = 0; i < pairlist.length; i++){ + re.cancard = re.cancard.concat(pairlist[i]); + } + re.cantype = startcardtype - 100; + //如果是连两对拖拉机 + if (startcardtype == 302){ + return re; + } + + //如果是3连对åŠä»¥ä¸Šçš„æ‹–拉机则é™ä½Žæ‹–拉机的规格å†ç»§ç»­æ‰¾ + var tlj_type = startcardtype; //需è¦çš„牌型 + var tlj_find = startcardtype - 1; //当剿Ÿ¥æ‰¾çš„牌型 + //å†ç»§ç»­æ‰¾ + while (tlj_type >= 302 && tlj_find >= 302){ + var tlj_list = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, pairlist, tlj_find); + if (tlj_list.length == 1){ + //找到一个 + re.mustcard = re.mustcard.concat(tlj_list[0]); + re.cantype = re.cantype - (tlj_find - 100) + 200; + if (re.cantype < 201){ + re.cancard = []; + re.cantype = null; + return re; + } + re.cancard = min_ary_deduct(re.cancard, tlj_list[0]); + //删除对å­åˆ—表 + i = 0; + while (i < pairlist.length){ + if (min_ary_include(tlj_list[0], pairlist[i])){ + pairlist.splice(i, 1); + } else { + i++; + } + } + tlj_type = (tlj_type - tlj_find) + 300; + continue; + } + + if (tlj_list.length > 1){ + //找到多个 + if ((tlj_find - 300) * tlj_list.length <= (tlj_type - 300)){ + re.mustcard = re.mustcard.concat(tlj_list[0]); + re.cantype = re.cantype - (tlj_find - 100) + 200; + if (re.cantype < 201){ + re.cancard = []; + re.cantype = null; + return re; + } + re.cancard = min_ary_deduct(re.cancard, tlj_list[0]); + //删除对å­åˆ—表 + i = 0; + while (i < pairlist.length){ + if (min_ary_include(tlj_list[0], pairlist[i])){ + pairlist.splice(i, 1); + } else { + i++; + } + } + tlj_type = (tlj_type - tlj_find) + 300; + continue; + } else { + return re; + } + } + tlj_find = tlj_find - 1; + } + return re; + } + } + }, + + //第二ã€ä¸‰ä¸ªä½ç½®æ˜¯å¦å¯è·Ÿç‰Œ + can_followcard: function(mainflower, inhandcards, followcards, startcount, startflower, startcardtype){ + /* + 傿•°: + mainflower : 主牌花色 + inhandcards : 手上的牌id列表 + followcards : è¦è·Ÿçš„牌id列表 + startcount : ç¬¬ä¸€ä¸ªçŽ©å®¶å‡ºç‰Œçš„æ•°é‡ + startflower : 第一个玩家出牌的牌花色 + startcardtype: 第一个玩家出牌的牌型 + 返回结果json: + result : trueå¯è·Ÿï¼Œfalseä¸å¯è·Ÿ + cardvalue: 满足第一个玩家出牌的牌型值 + noflower : å‡ºç‰ŒåŽæ²¡æœ‰äº†ç¬¬ä¸€ä¸ªçŽ©å®¶å‡ºç‰ŒèŠ±è‰²çš„ç‰Œæ ‡å¿— + nopair : å‡ºç‰ŒåŽæ²¡æœ‰äº†ç¬¬ä¸€ä¸ªçŽ©å®¶å‡ºç‰ŒèŠ±è‰²çš„å¯¹å­æ ‡å¿— + */ + + //返回的结果 + var can = {}; + can.result = true; + can.cardvalue = null; + can.noflower = false; + can.nopair = false; + + //返回ä¸èƒ½å‡ºç‰Œçš„结果 + var do_returnfalse = function(){ + can.result = false; + delete can.cardvalue; + delete can.noflower; + delete can.nopair; + } + + //牌的数é‡å¿…须相等 + if (followcards.length != startcount){ + do_returnfalse(); + return can; + } + + //æ‹·è´æ•°ç»„ + var _inhandcards = inhandcards.concat(); + var _followcards = followcards.concat(); + + //å°†ç‰Œä»Žå¤§åˆ°å°æŽ’åº + _inhandcards = cls_youle_erqiwang_arith.order_cards(mainflower, _inhandcards); + _followcards = cls_youle_erqiwang_arith.order_cards(mainflower, _followcards); + + //æ ¹æ®ç¬¬ä¸€ä¸ªçŽ©å®¶çš„å‡ºç‰ŒèŽ·å–åŽé¢çŽ©å®¶å¿…å‡ºçš„å’Œå¯å‡ºçš„牌 + var get = cls_youle_erqiwang_arith.get_followcard(mainflower, _inhandcards, startcount, startflower, startcardtype); + + ////////// 判断是å¦å¯è·Ÿç‰Œ /////////// + //如果有必出的牌则必须包å«å¿…出的牌 + if (get.mustcard.length > 0){ + if (!min_ary_include(_followcards, get.mustcard)){ + do_returnfalse(); + return can; + } + //除去必出的牌还è¦å‡ºçš„牌 + _followcards = min_ary_deduct(_followcards, get.mustcard); + } + + if (_followcards.length > 0){ + //必须在å¯å‡ºçš„ç‰Œé‡Œé¢ + if (!min_ary_include(get.cancard, _followcards)){ + do_returnfalse(); + return can; + } + + //必须满足需è¦çš„牌型 + if (get.cantype > 100 && get.cantype < 200){ + //å•张牌型 + //牌数é‡è¦æ­£ç¡® + if (_followcards.length != get.cantype - 100){ + do_returnfalse(); + return can; + } + } else if (get.cantype > 200 && get.cantype < 300){ + //对å­ç‰Œåž‹ + //牌数é‡è¦æ­£ç¡® + if (_followcards.length != (get.cantype - 200) * 2){ + do_returnfalse(); + return can; + } + //坹孿•°é‡è¦æ­£ç¡® + var pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, _followcards); + if (pairlist.length != get.cantype - 200){ + do_returnfalse(); + return can; + } + } else if (get.cantype > 300 && get.cantype < 400){ + //拖拉机牌型 + //牌数é‡è¦æ­£ç¡® + if (_followcards.length != (get.cantype - 300) * 2){ + do_returnfalse(); + return can; + } + //è¦æ˜¯æ­£ç¡®çš„æ‹–拉机牌型 + if (tuolaji_list.length == 0){ + do_returnfalse(); + return can; + } + } + } + + /////////// å¯ä»¥è·Ÿç‰Œ /////////// + //æ ¹æ®è·Ÿç‰Œæƒ…å†µèŽ·å–æ˜¯å¦æœ‰ç›¸åŒèŠ±è‰²çš„ç‰Œï¼Œæ˜¯å¦æœ‰å¯¹å­ + //如果第一张牌的花色与第一家的出牌花色ä¸ä¸€æ ·åˆ™è®¤ä¸ºæ²¡æœ‰äº†ç›¸åŒèŠ±è‰²çš„ç‰Œ + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, followcards[0]); + var _flower = parseInt(_code / 100); + if (_code > 1000){ + _flower = mainflower; + } + if (_flower != startflower){ + can.noflower = true; + can.nopair = true; + } + //如果最åŽä¸€å¼ ç‰Œçš„花色与第一家的出牌花色ä¸ä¸€æ ·åˆ™è®¤ä¸ºæ²¡æœ‰äº†ç›¸åŒèŠ±è‰²çš„ç‰Œ + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, followcards[followcards.length - 1]); + var _flower = parseInt(_code / 100); + if (_code > 1000){ + _flower = mainflower; + } + if (_flower != startflower){ + can.noflower = true; + can.nopair = true; + } + //å¦‚æžœç¬¬ä¸€å®¶å‡ºçš„æ˜¯å¯¹å­æˆ–拖拉机牌型,而跟牌没有出对å­åˆ™è®¤ä¸ºæ²¡æœ‰ç›¸åŒèŠ±è‰²çš„å¯¹å­ + if (startcardtype > 200){ + var pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, followcards); + if (pairlist.length != startcardtype % 100){ + can.nopair = true; + } + } + + //æ ¹æ®ç¬¬ä¸€å®¶çš„å‡ºç‰Œè®¡ç®—ç‰Œå€¼å¤§å° + //一张å•å¼  + if (startcardtype == 101){ + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, followcards[0]); + var _flower = parseInt(_code / 100); + if (_code > 1000){ //大于1000是主牌 + _flower = mainflower; + } + + if (_flower == startflower || _flower == mainflower){ + if (_code > 7000 && _code < 8000){ //副7 + can.cardvalue = 7000; + } else if (_code > 2000 && _code < 3000){ //副2 + can.cardvalue = 2000; + } else { + can.cardvalue = _code; + } + } else { + can.cardvalue = 0; + } + return can; + } + + //甩多张å•å¼  + if (startcardtype > 101 && startcardtype < 200){ + //第一个玩家是甩牌,则跟牌一定没有第一家玩家的牌大 + can.cardvalue = 0; + return can; + } + + //一对 + if (startcardtype == 201){ + var pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, followcards); + if (pairlist.length != 1){ + can.cardvalue = 0; + return can; + } + + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, followcards[0]); + var _flower = parseInt(_code / 100); + if (_code > 1000){ + _flower = mainflower; + } + if (_flower == startflower || _flower == mainflower){ + if (_code > 7000 && _code < 8000){ //副7 + can.cardvalue = 7000; + } else if (_code > 2000 && _code < 3000){ //副2 + can.cardvalue = 2000; + } else { + can.cardvalue = _code; + } + } else { + can.cardvalue = 0; + } + return can; + } + + //甩多对 + if (startcardtype > 201 && startcardtype < 300){ + //第一个玩家是甩牌,则跟牌一定没有第一家玩家的牌大 + can.cardvalue = 0; + return can; + } + + //拖拉机 + if (startcardtype > 300 && startcardtype < 400){ + var pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, followcards); + var tuolaji_list = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, pairlist, startcardtype); + if (tuolaji_list.length != 1){ + can.cardvalue = 0; + return can; + } + + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, followcards[0]); + var _flower = parseInt(_code / 100); + if (_code > 1000){ + _flower = mainflower; + } + if (_flower == startflower || _flower == mainflower){ + can.cardvalue = _code; + } else { + can.cardvalue = 0; + } + return can; + } + }, + + //é—²å®¶æŠ åº•å€æ•° + get_bottom_multiple: function(mainflower, cards){ + //æ‹·è´æ•°ç»„ + var _cards = cards.concat(); + //å°†ç‰Œä»Žå¤§åˆ°å°æŽ’åº + _cards = cls_youle_erqiwang_arith.order_cards(mainflower, _cards); + + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, _cards[0]); + if (_code < 1000){ + return 0; + } + var _code = cls_youle_erqiwang_arith.id_to_code(mainflower, _cards[_cards.length - 1]); + if (_code < 1000){ + return 0; + } + + var _pairlist = cls_youle_erqiwang_arith.get_pairlist(mainflower, _cards); + if (_pairlist.length == 0){ + return 2; + } + + var _tljlist = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, _pairlist, 302); + if (_tljlist.length == 0){ + return 4; + } + + var _tljlist = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, _pairlist, 303); + if (_tljlist.length == 0){ + return 8; + } + + var _tljlist = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, _pairlist, 304); + if (_tljlist.length == 0){ + return 16; + } + + var _tljlist = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, _pairlist, 305); + if (_tljlist.length == 0){ + return 32; + } + + var _tljlist = cls_youle_erqiwang_arith.get_tuolaji_list(mainflower, _pairlist, 306); + if (_tljlist.length == 0){ + return 64; + } + }, + + //冲关计算关数 + get_chongguan: function(mainflower, cards){ + var re = {}; + re.count = 0; //关数 + re.wang = 0; //çŽ‹ç‰Œæ•°é‡ + re.cards = []; //王牌和冲关的牌 + if (cards.length < 28){ + return re; + } + + //æ‹·è´æ•°ç»„ + var _cards = cards.concat(); + //å°†ç‰Œä»Žå¤§åˆ°å°æŽ’åº + _cards = cls_youle_erqiwang_arith.order_cards(mainflower, _cards); + + var _wlist = []; //王 + var _2list = []; //2 + var _7list = []; //7 + var _incards = []; //æ˜¯å¦æ·»åŠ å¾—åˆ°äº†re.cards标志 + for (var i = 0; i < _cards.length; i++) { + var _number = cls_youle_erqiwang_arith.id_to_number(_cards[i]); + if (_number >= 53){ + _wlist.push(i); + re.wang = re.wang + 1; + re.cards.push(_cards[i]); + } else if (_number == 2){ + _2list.push(i); + } else if (_number == 7){ + _7list.push(i); + } + _incards.push(0); + } + + //添加到re.cards + var do_addlisttocards = function(_list){ + for (var i = 0; i < _list.length; i++){ + if (!_incards[_list[i]]){ + re.cards.push(_cards[_list[i]]); + _incards[_list[i]] = 1; + } + } + } + + //三王四王冲关判断 + if (_wlist.length >= 3){ + re.count = 1; + var _code = 9553; //当å‰çš„ç‰Œç¼–ç  + var i = 3; //åŽé¢æŸ¥æ‰¾çš„èµ·å§‹ä½ç½® + if (_wlist.length == 4){ + re.count = 3; + i = 4; + } + //å¾€åŽæŸ¥æ‰¾ï¼Œçœ‹æ˜¯å¦è¿˜æœ‰å†²å…³ + while (i < _cards.length - 1){ + //牌编ç ï¼Œä¸¤å¼ ç‰Œä¸¤å¼ ç‰Œä¸€å– + var code_i = cls_youle_erqiwang_arith.id_to_code(mainflower, _cards[i]); + var code_j = cls_youle_erqiwang_arith.id_to_code(mainflower, _cards[i + 1]); + if (code_i == code_j){ + if (cls_youle_erqiwang_arith.is_continuous(_code, code_i)){ + re.count = re.count + 1; + re.cards.push(_cards[i]); + re.cards.push(_cards[i + 1]); + _incards[i] = 1; + _incards[i + 1] = 1; + _code = code_i; + } + i = i + 2; + } else { + i++; + } + } + } + + //å…­2å…­7判断 + if (_7list.length >= 6){ + re.count = re.count + _7list.length - 5; + do_addlisttocards(_7list); + } + if (_2list.length >= 6){ + re.count = re.count + _2list.length - 5; + do_addlisttocards(_2list); + } + + //10个è€ä¸»åˆ¤æ–­ + var _total = _wlist.length + _7list.length + _2list.length; + if (_total >= 10){ + re.count = re.count + _total - 9; + do_addlisttocards(_7list); + do_addlisttocards(_2list); + } + + re.cards = cls_youle_erqiwang_arith.order_cards(mainflower, re.cards); + return re; + }, + + //计算å‡çº§çº§æ•° + get_upgrade: function(call, grade){ + //å«åˆ†çš„ä¸€åŠ + var _halfcall; + if (call % 2 == 0){ + _halfcall = call / 2; + } else { + _halfcall = (call + 5) / 2; + } + + if (grade == 0){ + return 4; + } + if (grade < _halfcall){ + return 2; + } + if (grade < call){ + return 1; + } + return -1 * (parseInt((grade - call) / _halfcall) + 1); + } +} + diff --git a/codes/games/server/games/erqiwang/class.desk.js b/codes/games/server/games/erqiwang/class.desk.js new file mode 100644 index 0000000..e504a74 --- /dev/null +++ b/codes/games/server/games/erqiwang/class.desk.js @@ -0,0 +1,185 @@ +/////////////////////////////////////////////////// +////////// cls_youle_erqiwang_desk: 牌桌 ////////// +/////////////////////////////////////////////////// +var cls_youle_erqiwang_desk = cls_youle_erqiwang_desk || { + + countdown_jiaofen: 15, //å«åˆ†å€’计时 + countdown_xuanzhu: 20, //选主倒计时 + countdown_maipai: 25, //埋牌倒计时 + countdown_chupai: 30, //出牌倒计时 + + //创建牌桌对象 + new: function(o_room){ + + var desk = {}; + + desk.o_room = o_room; //桌所属的房间对象 + desk.seatlist = []; //玩家得分 + desk.seatlist.push([0, []]); //第一ä½ä¸ºç´¯ç§¯å¾—分,第二ä½ä¸ºæ¯å±€å¾—分 + desk.seatlist.push([0, []]); + desk.seatlist.push([0, []]); + desk.prepare = [0,0,0]; //çŽ©å®¶å‡†å¤‡çŠ¶æ€ + desk.paiju_list = []; //牌局列表 + + //方法 + desk.method = {}; + + //当å‰ç‰Œå±€ + desk.method.curr_paiju = function(){ + return desk.paiju_list[desk.paiju_list.length - 1]; + } + + //新牌局 + desk.method.do_new_paiju = function(firstseat){ + cls_youle_erqiwang_desk.do_new_paiju(desk, firstseat); + } + + //å«åˆ†å€’计时 + desk.method.get_countdown_jiaofen = function(){ + return cls_youle_erqiwang_desk.countdown_jiaofen; + } + + //å«ä¸»å€’计时 + desk.method.get_countdown_xuanzhu = function(){ + return cls_youle_erqiwang_desk.countdown_xuanzhu; + } + + //埋牌倒计时 + desk.method.get_countdown_maipai = function(){ + return cls_youle_erqiwang_desk.countdown_maipai; + } + + //出牌倒计时 + desk.method.get_countdown_chupai = function(){ + return cls_youle_erqiwang_desk.countdown_chupai; + } + + //准备 + desk.method.do_prepare = function(seat){ + return cls_youle_erqiwang_desk.do_prepare(desk, seat); + } + + //获å–大局结算包 + desk.method.get_desk_account = function(msg){ + return cls_youle_erqiwang_desk.get_desk_account(desk, msg); + } + + return desk; + }, + + //新开一局 + do_new_paiju: function(o_desk, firstseat){ + //æ¢å¤çŽ©å®¶å‡†å¤‡çŠ¶æ€ + o_desk.prepare = [0,0,0]; + + if (o_desk.paiju_list.length > 0){ + delete o_desk.paiju_list[o_desk.paiju_list.length - 1].tmp_jiesuan_aset; + } + + //新开一局 + cls_youle_erqiwang_paiju.new(o_desk, firstseat); + + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "fapai"; + msg.data = {}; + msg.data.asetidx = o_desk.paiju_list.length; + msg.data.asetcount = o_desk.o_room.asetcount; + msg.data.seat = o_desk.method.curr_paiju().method.get_callgrade_seat(); + msg.data.countdown = o_desk.method.get_countdown_jiaofen(); + for (var i = 0; i < o_desk.o_room.seatlist.length; i++) { + msg.conmode = o_desk.o_room.seatlist[i].conmode; + msg.fromid = o_desk.o_room.seatlist[i].fromid; + msg.data.cards = o_desk.method.curr_paiju().method.get_seat_cards(i); + youle_erqiwang.app.SendPack(msg); + } + }, + + //准备 + do_prepare: function(o_desk, seat){ + o_desk.prepare[seat] = 1; + if (o_desk.prepare[0] && o_desk.prepare[1] && o_desk.prepare[2]){ + //新开一局 + var paiju = o_desk.method.curr_paiju(); + var firstseat = paiju.banker; + if (paiju.result == 1 || paiju.result == 2){ + firstseat = (firstseat + 1) % 3; + } + cls_youle_erqiwang_desk.do_new_paiju(o_desk, firstseat); + } else { + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "zhunbei"; + msg.data = {}; + msg.data.seat = seat; + o_desk.o_room.method.sendpack_toother(msg, -1); + } + }, + + //大局结算包 + get_desk_account: function(o_desk, msg){ + //ä¿å­˜æˆ˜ç»© + var do_save_grade = function(){ + var o_gameinfo1 = {}; + o_gameinfo1.roomcode = o_desk.o_room.roomcode; + o_gameinfo1.asetcount = o_desk.paiju_list.length; + o_gameinfo1.createtime = o_desk.o_room.createtime; + o_gameinfo1.makewartime = o_desk.o_room.makewartime; + o_gameinfo1.players = []; + for (var i = 0; i < o_desk.o_room.seatlist.length; i++){ + var _player = {}; + _player.seat = i; + _player.playerid = o_desk.o_room.seatlist[i].playerid; + _player.name = o_desk.o_room.seatlist[i].nickname; + _player.avatar = o_desk.o_room.seatlist[i].avatar; + _player.score = o_desk.seatlist[i][0]; + o_gameinfo1.players.push(_player); + } + + var o_gameinfo2 = []; + for (var i = 0; i < o_desk.paiju_list.length; i++) { + var _paiju = {}; + _paiju.starttime = o_desk.paiju_list[i].starttime; + _paiju.endtime = o_desk.paiju_list[i].endtime; + _paiju.seatlist = [0, 0, 0]; + _paiju.seatlist[0] = o_desk.seatlist[0][1][i]; + _paiju.seatlist[1] = o_desk.seatlist[1][1][i]; + _paiju.seatlist[2] = o_desk.seatlist[2][1][i]; + _paiju.callproc = o_desk.paiju_list[i].callproc; + _paiju.banker = o_desk.paiju_list[i].banker; + _paiju.call = o_desk.paiju_list[i].call; + _paiju.flower = o_desk.paiju_list[i].flower; + _paiju.result = o_desk.paiju_list[i].result; + //æ•°æ®é‡å¤ªå¤šï¼Œjson转数组åŽè¿›è¡Œå­˜å‚¨ + _paiju.cards = []; + for (var j = 0; j < o_desk.paiju_list[i].cards.length; j++) { + var _pai = o_desk.paiju_list[i].cards[j]; + var _card = []; + _card.push(_pai.id); + _card.push(_pai.flower); + _card.push(_pai.number); + _card.push(_pai.score); + _card.push(_pai.dealowner); + _card.push(_pai.playround); + _card.push(_pai.playindex); + _card.push(_pai.playowner); + _paiju.cards.push(_card); + } + o_gameinfo2.push(_paiju); + } + + //累积游æˆå¾—分 + for (var i = 0; i < o_desk.o_room.seatlist.length; i++) { + o_desk.o_room.seatlist[i].gameinfo.grade = o_desk.seatlist[i][0]; + } + //ä¿å­˜æˆ˜ç»© + youle_erqiwang.import.save_grade(o_desk.o_room, o_gameinfo1, o_gameinfo2, 1); + } + min_ontimeout(do_save_grade, 1000); + + msg.data.account = o_desk.seatlist; + return msg; + } +} diff --git a/codes/games/server/games/erqiwang/class.export.js b/codes/games/server/games/erqiwang/class.export.js new file mode 100644 index 0000000..8520d90 --- /dev/null +++ b/codes/games/server/games/erqiwang/class.export.js @@ -0,0 +1,273 @@ +/////////////////////////////////////////////////// +/////// cls_youle_erqiwang_export: è¾“å‡ºæŽ¥å£ /////// +/////////////////////////////////////////////////// +var cls_youle_erqiwang_export = cls_youle_erqiwang_export || { + + new: function() { + + var exp = {}; + + //è§£æžroomtype获å–å¼€æˆ¿æ‰€éœ€æˆ¿å¡ + exp.get_needroomcard = function(roomtype){ + switch (roomtype[2]) + { + case 1: //æˆ¿ä¸»æ‰£å¡ + switch (roomtype[0]) + { + case 1: + return 1; + break; + case 2: + return 2; + break; + default: + return 1; + break; + } + break; + case 2: //æ¯äººæ‰£å¡ + switch (roomtype[0]) + { + case 1: + return 1; + break; + case 2: + return 2; + break; + default: + return 1; + break; + } + break; + } + } + + //è§£æžroomtypeèŽ·å–æ€»å±€æ•° + exp.get_asetcount = function(roomtype){ + switch (roomtype[0]) + { + case 1: + return 2; + break; + case 2: + return 4; + break; + default: + return 4; + break; + } + } + + //加入房间时根æ®roomtype获å–需è¦çš„æˆ¿å¡æ•°é‡ + exp.get_needroomcard_joinroom = function(roomtype){ + switch (roomtype[2]) + { + case 1: //æˆ¿ä¸»æ‰£å¡ + return 0; + break; + case 2: //æ¯äººæ‰£å¡ + switch (roomtype[0]) + { + case 1: + return 1; + break; + case 2: + return 2; + break; + default: + return 1; + break; + } + break; + } + } + + //开战 + exp.makewar = function(o_room){ + //牌桌对象 + o_room.o_desk = cls_youle_erqiwang_desk.new(o_room); + for (var i = 0; i < o_room.seatlist.length; i++) { + o_room.seatlist[i].gameinfo.isbet = 1; + } + + //开始第一局 + var do_newpaiju = function(){ + o_room.o_desk.method.do_new_paiju(0); + } + min_ontimeout(do_newpaiju, 1000); + } + + //èŽ·å–æŸä¸ªçŽ©å®¶çš„ç‰Œæ¡Œæ•´æ¡Œå½“å‰ä¿¡æ¯ + exp.get_deskinfo = function(o_room, seat){ + if (!o_room.o_desk){ + return null; + } + var paiju = o_room.o_desk.method.curr_paiju(); + var deskinfo = {}; + deskinfo.count = o_room.asetcount; //总局数 + deskinfo.idx = paiju.idx; //当å‰å±€æ•° + deskinfo.PlayerInfo = []; //玩家当å‰ç´¯ç§¯å¾—分 + for (var i = 0; i < o_room.o_desk.seatlist.length; i++) { + deskinfo.PlayerInfo.push(o_room.o_desk.seatlist[i][0]); + }; + deskinfo.step = paiju.step; //ç‰Œå±€çŠ¶æ€ + deskinfo.MyCards = paiju.method.get_seat_cards(seat); //我手上的牌 + switch (paiju.step){ + case 1: //å‘完牌å«åˆ† + deskinfo.CallRun = {}; + //当å‰å«åˆ†ä½ç½® + deskinfo.CallRun.seat = paiju.method.get_callgrade_seat(); + //å«åˆ†å€’计时 + deskinfo.CallRun.countdown = o_room.o_desk.method.get_countdown_jiaofen(); + //当å‰å«åˆ† + deskinfo.CallRun.nowcall = paiju.method.get_callgrade_value(); + //当å‰å«åˆ†å€æ•° + deskinfo.CallRun.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(deskinfo.CallRun.nowcall); + //所有玩家的å«åˆ†æƒ…况 + deskinfo.CallRun.call = [null, null, null]; + deskinfo.CallRun.call[0] = paiju.method.get_seat_callgrade(0); + deskinfo.CallRun.call[1] = paiju.method.get_seat_callgrade(1); + deskinfo.CallRun.call[2] = paiju.method.get_seat_callgrade(2); + break; + case 2: //选主 + deskinfo.ChooseMain = {}; + //庄家 + deskinfo.ChooseMain.banker = paiju.banker; + //庄家å«åˆ† + deskinfo.ChooseMain.call = paiju.call; + //庄家å«åˆ†å€æ•° + deskinfo.ChooseMain.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); + //选主倒计时 + deskinfo.ChooseMain.countdown = o_room.o_desk.method.get_countdown_xuanzhu(); + //底牌 + deskinfo.ChooseMain.bottomcards = paiju.method.get_bottomcards(); + //是å¦å¯æŠ•é™ + if (paiju.call < 65){ + deskinfo.ChooseMain.touxiang = 0; + } else { + deskinfo.ChooseMain.touxiang = 1; + } + break; + case 3: //埋牌 + deskinfo.BuryCards = {}; + //庄家 + deskinfo.BuryCards.banker = paiju.banker; + //庄家å«åˆ† + deskinfo.BuryCards.call = paiju.call; + //庄家å«åˆ†å€æ•° + deskinfo.BuryCards.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); + //埋牌倒计时 + deskinfo.BuryCards.countdown = o_room.o_desk.method.get_countdown_maipai(); + //底牌 + deskinfo.BuryCards.bottomcards = paiju.method.get_bottomcards(); + //主牌花色 + deskinfo.BuryCards.flower = paiju.flower; + //是å¦å¯æŠ•é™ + if (paiju.call < 65){ + deskinfo.BuryCards.touxiang = 0; + } else { + deskinfo.BuryCards.touxiang = 1; + } + break; + case 4: //æŠ•é™ + deskinfo.Surrender = {}; + //庄家 + deskinfo.Surrender.banker = paiju.banker; + //庄家å«åˆ† + deskinfo.Surrender.call = paiju.call; + //庄家å«åˆ†å€æ•° + deskinfo.Surrender.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); + //出牌倒计时 + deskinfo.Surrender.countdown = o_room.o_desk.method.get_countdown_chupai(); + //主牌花色 + deskinfo.Surrender.flower = paiju.flower; + if (seat == paiju.banker){ + //埋的牌 + deskinfo.Surrender.bottomcards = paiju.method.get_burycard(); + } + //是å¦å¯æŠ•é™ + if (paiju.call < 65){ + deskinfo.Surrender.touxiang = 0; + } else { + deskinfo.Surrender.touxiang = 1; + } + break; + case 5: //出牌 + deskinfo.PushCards = {}; + //庄家 + deskinfo.PushCards.banker = paiju.banker; + //庄家å«åˆ† + deskinfo.PushCards.call = paiju.call; + //庄家å«åˆ†å€æ•° + deskinfo.PushCards.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(paiju.call); + //出牌倒计时 + deskinfo.PushCards.countdown = o_room.o_desk.method.get_countdown_chupai(); + //主牌花色 + deskinfo.PushCards.flower = paiju.flower; + //æ¡åˆ† + var jian_grade = paiju.method.get_jian_grade(); + if (seat == paiju.banker){ + //埋的牌 + deskinfo.PushCards.bottomcards = paiju.method.get_burycard(); + } else { + //闲家当å‰çš„æ¡åˆ†åˆ†ç‰Œ + deskinfo.PushCards.gradecards = jian_grade.cards; + } + //闲家当å‰çš„æ¡åˆ†åˆ†æ•° + deskinfo.PushCards.grade = jian_grade.grade; + //当å‰çš„出牌情况 + deskinfo.PushCards.playproc = paiju.playproc; + //座ä½åˆ—表 + deskinfo.PushCards.seatlist = paiju.seatlist; + //å‡ºç‰ŒåŽ†å² + deskinfo.PushCards.pushlist = []; + for (var i = 0; i < paiju.cards.length; i++) { + var pai = paiju.cards[i]; + if (pai.playround > 0){ + if (deskinfo.PushCards.pushlist.length < pai.playround){ + deskinfo.PushCards.pushlist.length = pai.playround; + } + if (!deskinfo.PushCards.pushlist[pai.playround - 1]){ + deskinfo.PushCards.pushlist[pai.playround - 1] = [[], [], []]; + } + + var owner = pai.dealowner; + if (owner == 0){ + owner = paiju.banker + 1; + } + deskinfo.PushCards.pushlist[pai.playround - 1][owner - 1].push(i); + } + } + //æŒ‰å¤§å°æŽ’åº + for (var i = 0; i < deskinfo.PushCards.pushlist.length; i++) { + for (var j = 0; j < deskinfo.PushCards.pushlist.length; j++) { + deskinfo.PushCards.pushlist[i][j] = cls_youle_erqiwang_arith.order_cards(pai.flower, deskinfo.PushCards.pushlist[i][j]); + } + } + break; + case 6: //结算 + deskinfo.Balance = {}; + //çŽ©å®¶çš„å‡†å¤‡çŠ¶æ€ + deskinfo.Balance.readystate = o_room.o_desk.prepare; + if (o_room.o_desk.prepare[seat] == 0){ + //结算情况 + deskinfo.Balance.aset = paiju.tmp_jiesuan_aset; + } + break; + } + + return deskinfo; + } + + //解散房间 + exp.get_disbandRoom = function(o_room){ + var msg = {}; + return o_room.o_desk.method.curr_paiju().method.get_paiju_account(2, msg); + } + + return exp; + } +} + +//å¯¹å†…è¾“å‡ºæŽ¥å£ +youle_erqiwang.export = cls_youle_erqiwang_export.new(); \ No newline at end of file diff --git a/codes/games/server/games/erqiwang/class.import.js b/codes/games/server/games/erqiwang/class.import.js new file mode 100644 index 0000000..4c09150 --- /dev/null +++ b/codes/games/server/games/erqiwang/class.import.js @@ -0,0 +1,30 @@ +/////////////////////////////////////////////////// +/////// cls_youle_platform_import: è¾“å…¥æŽ¥å£ /////// +/////////////////////////////////////////////////// +var cls_youle_erqiwang_import = cls_youle_erqiwang_import || { + + new: function() { + + var imp = {}; + + //检查玩家 + imp.check_player = function(agentid, gameid, roomcode, seat, playerid, conmode, fromid){ + return youle_erqiwang.app.youle_room.export.check_player(agentid, gameid, roomcode, seat, playerid, conmode, fromid); + } + + //ç¬¬ä¸€å±€ç»“ç®—æ‰£é™¤æˆ¿å¡ + imp.deduct_roomcard = function(o_room){ + return youle_erqiwang.app.youle_room.export.deduct_roomcard(o_room); + } + + //ä¿å­˜æˆ˜ç»© + imp.save_grade = function(o_room, o_gameinfo1, o_gameinfo2, freeroomflag){ + youle_erqiwang.app.youle_room.export.save_grade(o_room, o_gameinfo1, o_gameinfo2, freeroomflag); + } + + return imp; + } +} + +// è¾“å…¥æŽ¥å£ +youle_erqiwang.import = cls_youle_erqiwang_import.new(); \ No newline at end of file diff --git a/codes/games/server/games/erqiwang/class.pai.js b/codes/games/server/games/erqiwang/class.pai.js new file mode 100644 index 0000000..a9e674e --- /dev/null +++ b/codes/games/server/games/erqiwang/class.pai.js @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////// +////////// cls_youle_erqiwang_pai: 牌 ////////// +/////////////////////////////////////////////////// +var cls_youle_erqiwang_pai = cls_youle_erqiwang_pai || { + + //创建å•张牌对象 + new: function(id, flower, number, score, dealowner){ + /* + 傿•°è¯´æ˜Žï¼š + id ç»å¯¹id + flower 牌é¢èŠ±è‰² + number ç‰Œé¢æ•°å€¼ + code ç‰Œç¼–ç  + + 扑克牌的统一编ç è§„则: + 1,牌é¢èŠ±è‰²çš„å®šä¹‰ 5:王 4:黑桃 3:红心 2:梅花 1:æ–¹å— + 2ï¼Œç‰Œé¢æ•°å€¼çš„定义 01:A 02:2 03:3 ... 09:9 10:10 11:J 12:Q 13:K 53:å°çŽ‹ 54:大王 + 3,牌编ç çš„定义 + 3.1 常主的牌编ç å®šä¹‰ï¼š + 未å«ä¸»ä¹‹å‰: + 2的牌编ç å®šä¹‰ 黑桃2:2402 红心2:2302 梅花2:2202 æ–¹å—2:2102 + 7的牌编ç å®šä¹‰ 黑桃7:7407 红心2:7307 梅花7:7207 æ–¹å—7:7107 + 王的牌编ç å®šä¹‰ å°çŽ‹:9553 大王:9554 + å«ä¸»ä¹‹åŽ: + 主2牌编ç å®šä¹‰ 原有牌编ç çš„基础上+1000,例如红心为主牌,则红心2的牌编ç å˜ä¸º3302 + 主7牌编ç å®šä¹‰ 原有牌编ç çš„基础上+1000,例如红心为主牌,则红心7的牌编ç å˜ä¸º8307 + 3.2 普通牌的牌编ç å®šä¹‰ + A的定义:14 + 未å«ä¸»ä¹‹å‰: + 3使•°å­— 第一ä½ä¸ºç‰Œé¢èŠ±è‰² 第二三ä½ä¸ºç‰Œé¢æ•°å€¼ + å«ä¸»ä¹‹åŽ: + 主牌花色 4使•°å­—,å³åœ¨åŽŸæœ‰ç‰Œç¼–ç çš„基础上+1000,表示是主牌 + éžä¸»ç‰ŒèŠ±è‰² 3使•°å­—,å³åŽŸæœ‰ç‰Œç¼–ç ä¸å˜ + 3.3 综上所述 + ç‰Œç¼–ç æ˜¯3ä½çš„,å³å°äºŽ1000的都是éžä¸»ç‰Œ + ç‰Œç¼–ç æ˜¯4ä½çš„,å³å¤§äºŽ1000的都是主牌 + 坿 ¹æ®ç‰Œç¼–ç è¿›è¡Œç‰Œå¤§å°çš„æ¯”è¾ƒå’ŒæŽ’åº + 4 牌型定义 + >100: å•张, 101一张å•张,102两张å•张,103三张å•å¼  ... + >200: 对å­ï¼Œ 201一对,202两对,203三对 ... + >300: 拖拉机,302两连对拖拉机,303三连对拖拉机 ... + + */ + var pai = {}; + pai.id = id; //ç»å¯¹idï¼Œå³æ•°ç»„下标,从0开始计数 + pai.flower = flower; //牌é¢èŠ±è‰² + pai.number = number; //ç‰Œé¢æ•°å€¼ + pai.score = score; //牌在游æˆä¸­çš„分值 + pai.dealowner = dealowner; //å‘ç‰ŒçŠ¶æ€ + //-1:规则去除的牌 + // 0:未å‘的牌,å³åº•牌 + //>0:å‘牌å‘åˆ°è°æ‰‹ä¸Šï¼Œä»Ž1开始计数,å³ä½ç½®ç¼–å·+1,ä½ç½®ç¼–å·æ˜¯ä»Ž0开始计数的 + pai.playround = -1; //å‡ºç‰ŒçŠ¶æ€ + //-1:未出的牌 + // 0:埋牌 + //>0:牌是第几轮出出去的,从1开始计数 + pai.playindex = -1; //本轮中的出牌顺åºï¼Œä»Ž1开始计数 + pai.playowner = -1; //出牌åŽè¢«è°å¾—到,与ä½ç½®ç¼–å·å¯¹åº” + return pai; + } +} diff --git a/codes/games/server/games/erqiwang/class.paiju.js b/codes/games/server/games/erqiwang/class.paiju.js new file mode 100644 index 0000000..62c0f3a --- /dev/null +++ b/codes/games/server/games/erqiwang/class.paiju.js @@ -0,0 +1,863 @@ +/////////////////////////////////////////////////// +////////// cls_youle_erqiwang_paiju: 牌局 ///////// +/////////////////////////////////////////////////// +var cls_youle_erqiwang_paiju = cls_youle_erqiwang_paiju || { + + new: function(o_desk, firstseat) { + var paiju = {}; + o_desk.paiju_list.push(paiju); + + // ================= å®žä¾‹çš„ç§æœ‰å±žæ€§ ================= // + //å‘牌过程中待å‘çš„ä½ç½®åˆ—表 + var tmpdeal = []; + //三家需è¦å„å‘28张牌 + for (var i = 0; i < 28; i++){ + tmpdeal.push(0); //0表示第一个玩家的ä½ç½® + tmpdeal.push(1); //1表示第二个玩家的ä½ç½® + tmpdeal.push(2); //2表示第三个玩家的ä½ç½® + } + //8张底牌 + for (var i = 0; i < 8; i++){ + tmpdeal.push(-1); //-1 表示是底牌 + } + + // ================= å®žä¾‹çš„ç§æœ‰æ–¹æ³• ================= // + + //åˆå§‹åŒ–座ä½åˆ—表 + var init_seatlist = function(){ + //第一层是玩家列表,与ä½ç½®åºå·å¯¹åº” + //第二层å‰4个数组是花色列表,与花色-1对应 + //ç¬¬ä¸‰å±‚çš„ç¬¬ä¸€ä½æ˜¯æ— è¯¥èŠ±è‰²çš„ç‰Œæ ‡å¿— + //ç¬¬ä¸‰å±‚çš„ç¬¬äºŒä½æ˜¯è¯¥èŠ±è‰²æ— å¯¹æ ‡å¿— + //第二层第5个数组是报副情况 + //ç¬¬ä¸‰å±‚çš„ç¬¬ä¸€ä½æ˜¯å‰©ä½™ä¸»ç‰Œæ•°é‡ + //ç¬¬ä¸‰å±‚çš„ç¬¬äºŒä½æ˜¯å‰©ä½™ä¸»ç‰Œå¯¹å­ + //0å·ä½ + paiju.seatlist.push([[0,0],[0,0],[0,0],[0,0],[-1,-1]]); + //1å·ä½ + paiju.seatlist.push([[0,0],[0,0],[0,0],[0,0],[-1,-1]]); + //2å·ä½ + paiju.seatlist.push([[0,0],[0,0],[0,0],[0,0],[-1,-1]]); + } + + //åˆå§‹åŒ–牌列表并å‘牌 + var init_cards = function(){ + //两副牌 + for (var i = 1; i <= 2; i++){ + //å››ç§èŠ±è‰² + for (var j = 1; j <= 4; j++){ + for (var k = 1; k <= 13; k++){ + //牌id + var id = (i - 1) * 54 + (j - 1) * 13 + k - 1; + //分值 + var score = 0; + //å‘ç‰ŒçŠ¶æ€ + var dealowner = 0; + //ç‰¹æ®Šå¤„ç† + switch (k) + { + case 5: + score = 5; + break; + case 10: + score = 10; + break; + case 13: + score = 10; + break; + case 3: + dealowner = -1; + break; + case 4: + dealowner = -1; + break; + } + var pai = cls_youle_erqiwang_pai.new(id, j, k, score, dealowner); + paiju.cards.push(pai); + //å‘牌 + if (k != 3 && k != 4){ + do_dealpai(pai); + } + } + } + + //å°çŽ‹ + var pai = cls_youle_erqiwang_pai.new((i - 1) * 54 + 53 - 1, 5, 53, 0, 0); + paiju.cards.push(pai); + do_dealpai(pai); + + //大王 + var pai = cls_youle_erqiwang_pai.new((i - 1) * 54 + 54 - 1, 5, 54, 0, 0); + paiju.cards.push(pai); + do_dealpai(pai); + } + } + + //å°†å•å¼ ç‰Œéšæœºå‘到玩家手中或æˆä¸ºåº•牌 + var do_dealpai = function(o_pai){ + var idx = min_random(0, tmpdeal.length - 1); + if (tmpdeal[idx] == -1) { //底牌 + o_pai.dealowner = 0; + } else { + o_pai.dealowner = tmpdeal[idx] + 1; + } + //将数组的最åŽä¸€ä½è‡³è¯¥ä½ç½® + if (idx < tmpdeal.length - 1) { + tmpdeal[idx] = tmpdeal[tmpdeal.length - 1]; + }; + //数组长度å‡ä¸€ + tmpdeal.length = tmpdeal.length - 1; + } + + //进入å«åˆ†é˜¶æ®µ + var start_call = function(){ + paiju.step = 1; + var o_call = {}; + o_call.seat = paiju.firstseat; + o_call.call = null; //null:未å«åˆ† 0:ä¸å«åˆ† >0:å«åˆ†åˆ†æ•° + paiju.callproc.push(o_call); + } + + // ================= 实例的公有属性 ================= // + paiju.o_desk = o_desk; + //ç‰Œå±€å· + paiju.idx = o_desk.paiju_list.length; + //第一个å«åˆ†è€…çš„ä½ç½® + paiju.firstseat = firstseat; + //开始时间 + paiju.starttime = min_now(); + //ç»“æŸæ—¶é—´ + paiju.endtime = null; + //座ä½åˆ—表 + paiju.seatlist = []; + //牌列表 + paiju.cards = []; + //当å‰é˜¶æ®µ + paiju.step = -1; //1å‘完牌å«åˆ† 2选主 3埋牌 4æŠ•é™ 5出牌 6结算 + //å«åˆ†è¿‡ç¨‹ + paiju.callproc = []; + //庄家ä½ç½® + paiju.banker = -1; + //庄家å«åˆ† + paiju.call = -1; + //主牌花色 + paiju.flower = -1; + //当å‰å‡ºç‰Œæƒ…况 + paiju.playproc = {}; + //输赢结果 0:庄赢 1:闲赢 2:åº„æŠ•é™ 3:中途解散 + paiju.result = null; + //结算包,供断线é‡è¿žæ—¶ä½¿ç”¨ï¼Œæ–°å¼€ä¸€å±€æ—¶æ¸…除 + paiju.tmp_jiesuan_aset = null; + + //åˆå§‹åŒ–座ä½åˆ—表 + init_seatlist(); + //åˆå§‹åŒ–牌列表并å‘牌 + init_cards(); + //进入å«åˆ†é˜¶æ®µ + start_call(); + + // ================= 实例的公有方法 ================= // + paiju.method = {}; + + //èŽ·å–æŸä¸ªä½ç½®çŽ©å®¶æ‰‹ä¸Šçš„ç‰Œ + paiju.method.get_seat_cards = function(seat){ + return cls_youle_erqiwang_paiju.get_seat_cards(paiju, seat); + } + + //获å–当å‰çš„å«åˆ†ä½ç½® + paiju.method.get_callgrade_seat = function(){ + return paiju.callproc[paiju.callproc.length - 1].seat; + } + + //获å–当å‰çš„å«åˆ†åˆ†æ•° + paiju.method.get_callgrade_value = function(){ + return cls_youle_erqiwang_paiju.get_callgrade_value(paiju); + } + + //èŽ·å–æŸä¸ªçŽ©å®¶çš„å½“å‰å«åˆ†æƒ…况 + paiju.method.get_seat_callgrade = function(seat){ + return cls_youle_erqiwang_paiju.get_seat_callgrade(paiju, seat); + } + + //å«åˆ†æˆ–ä¸å« + paiju.method.do_callgrade = function(call){ + cls_youle_erqiwang_paiju.do_callgrade(paiju, call); + } + + //获å–底牌 + paiju.method.get_bottomcards = function(){ + return cls_youle_erqiwang_paiju.get_bottomcards(paiju); + } + + //选主 + paiju.method.do_choiceflower = function(flower){ + cls_youle_erqiwang_paiju.do_choiceflower(paiju, flower); + } + + //判断牌是å¦åœ¨çŽ©å®¶æ‰‹ä¸Š + paiju.method.check_cards_inhand = function(cards, seat){ + return cls_youle_erqiwang_paiju.check_cards_inhand(paiju, cards, seat); + } + + //埋牌 + paiju.method.do_burycard = function(cards){ + cls_youle_erqiwang_paiju.do_burycard(paiju, cards); + } + + //检查选中的牌是å¦å¯å‡ºï¼Œå¹¶å‡ºç‰Œ + paiju.method.do_playcard = function(cards){ + return cls_youle_erqiwang_paiju.do_playcard(paiju, cards); + } + + //æ˜¯å¦æœ‰äººæŠ¥å‰¯ + paiju.method.have_baofu = function(){ + return (paiju.seatlist[0][4][0] == 0 || paiju.seatlist[1][4][0] == 0 || paiju.seatlist[2][4][0] == 0); + } + + //在牌列表中获å–分牌和分值 + paiju.method.get_grade_incard = function(cards){ + return cls_youle_erqiwang_paiju.get_grade_incard(paiju, cards); + } + + //获å–埋牌 + paiju.method.get_burycard= function(){ + return cls_youle_erqiwang_paiju.get_burycard(paiju); + } + + //èŽ·å–æŠ åº•åŒ… + paiju.method.get_bottom_account = function(msg){ + return cls_youle_erqiwang_paiju.get_bottom_account(paiju, msg); + } + + //å°å±€ç»“算,type 0正常结算 1投é™ç»“ç®— 2解散结算 + paiju.method.get_paiju_account = function(type, msg){ + return cls_youle_erqiwang_paiju.get_paiju_account(paiju, type, msg); + } + + //获å–闲家当å‰çš„æ¡åˆ†åˆ†æ•°å’Œåˆ†ç‰Œ + paiju.method.get_jian_grade = function(){ + return cls_youle_erqiwang_paiju.get_jian_grade(paiju); + } + + return paiju; + }, + + //下一个ä½ç½® + get_nextseat: function(seat){ + return (seat + 1) % 3; + }, + + //èŽ·å–æŸä¸ªä½ç½®çŽ©å®¶æ‰‹ä¸Šçš„ç‰Œ + get_seat_cards: function(o_paiju, seat){ + var aryCardIDs = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + var o_card = o_paiju.cards[i]; + if (o_card.playround == -1){ //未出的牌 + if ((o_card.dealowner == seat + 1) || //å‘到手上 + (o_card.dealowner == 0 && seat == o_paiju.banker)){ //庄家包括底牌 + aryCardIDs.push(o_paiju.cards[i].id); + } + } + } + return cls_youle_erqiwang_arith.order_cards(o_paiju.flower, aryCardIDs); + }, + + //èŽ·å–æŸä¸ªä½ç½®çީ家å‘到手上的牌 + get_seat_cards_deal: function(o_paiju, seat){ + var aryCardIDs = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + var o_card = o_paiju.cards[i]; + if (o_card.dealowner == seat + 1){ + aryCardIDs.push(o_paiju.cards[i].id); + } + } + return cls_youle_erqiwang_arith.order_cards(o_paiju.flower, aryCardIDs); + }, + + //èŽ·å–æŸä¸ªä½ç½®çީ家å‘到手上的牌(庄家包å«åº•牌) + get_seat_cards_owner: function(o_paiju, seat){ + var aryCardIDs = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + var o_card = o_paiju.cards[i]; + if ((o_card.dealowner == seat + 1) || //å‘到手上 + (o_card.dealowner == 0 && seat == o_paiju.banker)){ //庄家包括底牌 + aryCardIDs.push(o_paiju.cards[i].id); + } + } + return cls_youle_erqiwang_arith.order_cards(o_paiju.flower, aryCardIDs); + }, + + //èŽ·å–æŸä¸ªä½ç½®çŽ©å®¶æ‰‹ä¸Šçš„ä¸»ç‰Œ + get_seat_zhucards: function(o_paiju, seat){ + var aryCardIDs = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + var o_card = o_paiju.cards[i]; + if (o_card.playround == -1){ //未出的牌 + if ((o_card.dealowner == seat + 1) || //å‘到手上 + (o_card.dealowner == 0 && seat == o_paiju.banker)){ //庄家包括底牌 + if (o_card.flower == o_paiju.flower || o_card.flower == 5 || o_card.number == 2 || o_card.number == 7){ + aryCardIDs.push(o_paiju.cards[i].id); + } + } + } + } + return cls_youle_erqiwang_arith.order_cards(o_paiju.flower, aryCardIDs); + }, + + //获å–当å‰çš„å«åˆ†åˆ†æ•° + get_callgrade_value: function(o_paiju){ + var value = 0; + for (var i = o_paiju.callproc.length - 2; i >= 0; i--) { + if (o_paiju.callproc[i].call) { + value = o_paiju.callproc[i].call; + break; + } + } + return value; + }, + + //èŽ·å–æŸä¸ªä½ç½®çš„å«åˆ† 返回值:nullæœªå« 0ä¸å« >0当å‰å«åˆ† + get_seat_callgrade: function(o_paiju, seat){ + for (var i = o_paiju.callproc.length - 2; i >= 0; i--){ + if (o_paiju.callproc[i].seat == seat){ + return o_paiju.callproc[i].call; + } + } + return null; + }, + + //å«åˆ† + do_callgrade: function(o_paiju, call){ + var o_call = o_paiju.callproc[o_paiju.callproc.length - 1]; + o_call.call = call; + + //等待下一个å«åˆ†è€…å«åˆ† + var do_wait_nextseat_call = function(seat){ + var o_call = {}; + o_call.seat = seat; + o_call.call = null; + o_paiju.callproc.push(o_call); + } + + //上庄 + var do_up_banker = function(seat, call){ + //庄家ä½ç½® + o_paiju.banker = seat; + //庄家å«åˆ† + o_paiju.call = call; + //进入选主阶段 + o_paiju.step = 2; + } + + //å«äº†5分直接上庄 + if (call == 5){ + do_up_banker(o_call.seat, call); + return; + } + //å«äº†åˆ† + if (call > 0){ + //下一个ä½ç½® + var nextseat = cls_youle_erqiwang_paiju.get_nextseat(o_call.seat); + //下一个ä½ç½®çš„å«åˆ† + var nextcall = cls_youle_erqiwang_paiju.get_seat_callgrade(o_paiju, nextseat); + //下一个ä½ç½®ä¸å«åˆ† + if (nextcall == 0){ + //å†ä¸‹ä¸€ä¸ªä½ç½® + nextseat = cls_youle_erqiwang_paiju.get_nextseat(nextseat); + } + //等待下一个å«åˆ†è€…å«åˆ† + do_wait_nextseat_call(nextseat); + return; + } + + //ä¸å« + if (call == 0){ + //下一个ä½ç½® + var nextseat_1 = cls_youle_erqiwang_paiju.get_nextseat(o_call.seat); + //下一个ä½ç½®çš„å«åˆ† + var nextcall_1 = cls_youle_erqiwang_paiju.get_seat_callgrade(o_paiju, nextseat_1); + //å†ä¸‹ä¸€ä¸ªä½ç½® + var nextseat_2 = cls_youle_erqiwang_paiju.get_nextseat(nextseat_1); + //å†ä¸‹ä¸€ä¸ªä½ç½®çš„å«åˆ† + var nextcall_2 = cls_youle_erqiwang_paiju.get_seat_callgrade(o_paiju, nextseat_2); + + if (nextcall_1 != 0 && nextcall_2 != 0){ + //å¦å¤–两家都没有ä¸å«åˆ† + do_wait_nextseat_call(nextseat_1); + return; + } + if (nextcall_1 != 0 && nextcall_2 == 0){ + //nextseat_1上庄 + do_up_banker(nextseat_1, nextcall_1); + return; + } + if (nextcall_1 == 0 && nextcall_2 != 0){ + //nextseat_2上庄 + do_up_banker(nextseat_2, nextcall_2); + return; + } + } + }, + + //获å–底牌 + get_bottomcards: function(o_paiju){ + var aryCardIDs = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + if (o_paiju.cards[i].dealowner == 0){ + aryCardIDs.push(o_paiju.cards[i].id); + } + } + return cls_youle_erqiwang_arith.order_cards(o_paiju.flower, aryCardIDs); + }, + + //选主 + do_choiceflower: function(o_paiju, flower){ + o_paiju.flower = flower; + //ä¿®æ”¹ä¸»ç‰Œçš„ç‰Œç¼–ç  + for (var i = 1; i <= 2; i++){ //两副牌 + for (var j = 0; j < 13; j++){ + var o_card = o_paiju.cards[(i - 1) * 54 + (flower - 1) * 13 + j]; + } + } + //进入埋牌阶段 + o_paiju.step = 3; + }, + + //判断牌是å¦åœ¨çŽ©å®¶æ‰‹ä¸Š + check_cards_inhand: function(o_paiju, cards, seat){ + for (var i = 0; i < cards.length; i++) { + var o_card = o_paiju.cards[cards[i]]; + if (o_card.playround != -1){ + return; + } + if (seat == o_paiju.banker){ + //是庄家 + if (o_card.dealowner != seat + 1 && o_card.dealowner != 0){ + return false; + } + } else { + //是闲家 + if (o_card.dealowner != seat + 1){ + return false; + } + } + } + return true; + }, + + //埋牌 + do_burycard: function(o_paiju, cards){ + for (var i = 0; i < cards.length; i++) { + o_paiju.cards[cards[i]].playround = 0; + }; + //进入投é™é˜¶æ®µ + o_paiju.step = 4; + cls_youle_erqiwang_paiju.new_playround(o_paiju, 1, o_paiju.banker); + }, + + //新一轮出牌 + new_playround: function(o_paiju, round, startseat){ + o_paiju.playproc.round = round; //第几轮 + o_paiju.playproc.start = startseat; //本轮的起始出牌ä½ç½® + o_paiju.playproc.currseat = startseat; //本轮的当å‰çš„出牌ä½ç½® + o_paiju.playproc.startcount = -1; //本轮第一个出牌的张数 + o_paiju.playproc.startflower = -1; //本轮第一个出牌的花色 + o_paiju.playproc.starttype = -1; //本轮第一个出牌的牌型 + o_paiju.playproc.maxseat = -1; //è°çš„牌最大,ä½ç½® + o_paiju.playproc.maxcard = -1; //满足第一个玩家出牌的牌型最大牌 + o_paiju.playproc.cards = []; //本轮å„ä½ç½®å‡ºçš„牌,数组与ä½ç½®åºå·å¯¹åº” + o_paiju.playproc.cards.length= 3; + }, + + //在牌列表中获å–分牌和分值 + get_grade_incard: function(o_paiju, cards){ + var re = {}; + re.grade = 0; + re.cards = []; + for (var i = 0; i < cards.length; i++) { + if (o_paiju.cards[cards[i]].score > 0){ + re.grade = re.grade + o_paiju.cards[cards[i]].score; + re.cards.push(cards[i]); + } + } + return re; + }, + + //检查选中的牌是å¦å¯å‡ºï¼Œå¹¶å‡ºç‰Œ + do_playcard: function(o_paiju, cards){ + //出牌 + var doplay = function(playindex){ + for (var i = 0; i < cards.length; i++) { + o_paiju.cards[cards[i]].playround = o_paiju.playproc.round; + o_paiju.cards[cards[i]].playindex = playindex; + }; + o_paiju.playproc.cards[o_paiju.playproc.currseat] = cards; + + //进入出牌阶段 + o_paiju.step = 5; + + //æ˜¯å¦æŠ¥å‰¯å¤„ç† + if (o_paiju.seatlist[o_paiju.playproc.currseat][4][0] != 0){ + var _zhu = cls_youle_erqiwang_paiju.get_seat_zhucards(o_paiju, o_paiju.playproc.currseat); + if (_zhu.length == 0){ + o_paiju.seatlist[o_paiju.playproc.currseat][4][0] = 0; + o_paiju.seatlist[o_paiju.playproc.currseat][4][1] = 0; + } + if (o_paiju.method.have_baofu()){ + var _parilist = cls_youle_erqiwang_arith.get_pairlist(o_paiju.flower, _zhu); + o_paiju.seatlist[o_paiju.playproc.currseat][4][0] = _zhu.length; + o_paiju.seatlist[o_paiju.playproc.currseat][4][1] = _parilist.length; + + if (o_paiju.seatlist[o_paiju.playproc.currseat][4][0] == 0){ + o_paiju.seatlist[o_paiju.playproc.currseat][o_paiju.flower - 1][0] = 1; + o_paiju.seatlist[o_paiju.playproc.currseat][o_paiju.flower - 1][1] = 1; + } else if (o_paiju.seatlist[o_paiju.playproc.currseat][4][1] == 0){ + o_paiju.seatlist[o_paiju.playproc.currseat][o_paiju.flower - 1][1] = 1; + } + } + } + } + + //本轮中的第二个出牌ä½ç½® + var nextseat_1 = cls_youle_erqiwang_paiju.get_nextseat(o_paiju.playproc.start); + //本轮中的第三个出牌ä½ç½® + var nextseat_2 = cls_youle_erqiwang_paiju.get_nextseat(nextseat_1); + + if (o_paiju.playproc.currseat == o_paiju.playproc.start){ //是本轮的第一个出牌 + var can = cls_youle_erqiwang_arith.can_playcard(o_paiju.flower, cards, o_paiju.playproc.currseat, o_paiju.seatlist); + if (!can.result){ + var re = {}; + re.result = false; + return re; + } + //出牌 + doplay(1); + //记录下牌型ã€èŠ±è‰²ã€ç‰Œåž‹æœ€å¤§ç‰Œ + o_paiju.playproc.startcount = cards.length; + o_paiju.playproc.startflower = can.flower; + o_paiju.playproc.starttype = can.cardtype; + o_paiju.playproc.maxseat = o_paiju.playproc.currseat; + o_paiju.playproc.maxcard = can.cardvalue; + o_paiju.playproc.currseat = nextseat_1; + //返回结果 + var re1 = {}; + re1.result = true; + re1.idx = 1; + re1.count = cards.length; + re1.flower = can.flower; + re1.cardtype = can.cardtype; + return re1; + } + + //䏿˜¯æœ¬è½®ä¸­çš„第一个出牌,是跟牌 + var cardsinhand = cls_youle_erqiwang_paiju.get_seat_cards(o_paiju, o_paiju.playproc.currseat); + var can = cls_youle_erqiwang_arith.can_followcard(o_paiju.flower, cardsinhand, cards, o_paiju.playproc.startcount, o_paiju.playproc.startflower, o_paiju.playproc.starttype); + if (!can.result){ + var re = {}; + re.result = false; + return re; + } + + //与之å‰çš„å‡ºç‰Œæ¯”è¾ƒå¤§å° + if (can.cardvalue > o_paiju.playproc.maxcard){ + o_paiju.playproc.maxseat = o_paiju.playproc.currseat; + o_paiju.playproc.maxcard = can.cardvalue; + } + + //æ— èŠ±è‰²ã€æ— å¯¹å­å¤„ç† + if (can.nopair){ + o_paiju.seatlist[o_paiju.playproc.currseat][o_paiju.playproc.startflower - 1][1] = 1; + } + if (can.noflower){ + o_paiju.seatlist[o_paiju.playproc.currseat][o_paiju.playproc.startflower - 1][0] = 1; + o_paiju.seatlist[o_paiju.playproc.currseat][o_paiju.playproc.startflower - 1][1] = 1; + } + + //是本轮中的第二个出牌 + if (o_paiju.playproc.currseat == nextseat_1){ + //出牌 + doplay(2); + //下一个出牌者 + o_paiju.playproc.currseat = nextseat_2; + //返回结果 + var re2 = {}; + re2.idx = 2; + re2.result = true; + return re2; + } + + //是本轮中的第三个出牌 + //出牌 + doplay(3); + //æœ¬è½®å‡ºç‰Œç»“æŸ + for (var i = 0; i < o_paiju.playproc.cards.length; i++) { + for (var j = 0; j < o_paiju.playproc.cards[i].length; j++) { + o_paiju.cards[o_paiju.playproc.cards[i][j]].playowner = o_paiju.playproc.maxseat; + } + } + + //返回结果 + var re3 = {}; + re3.result = true; + re3.idx = 3; + re3.maxseat = o_paiju.playproc.maxseat; + if (o_paiju.playproc.maxseat != o_paiju.banker){ + re3.grade = 0; + // re3.gradecards = []; + for (var i = 0; i < o_paiju.playproc.cards.length; i++) { + var grade_incards = cls_youle_erqiwang_paiju.get_grade_incard(o_paiju, o_paiju.playproc.cards[i]); + re3.grade = re3.grade + grade_incards.grade; + // re3.gradecards = re3.gradecards.concat(grade_incards.cards); + } + } + + //判断是å¦è¿˜æœ‰ç‰Œåœ¨çŽ©å®¶æ‰‹ä¸Šæœªå‡º + var havecard_inhand = function(){ + for (var i = 0; i < o_paiju.cards.length; i++) { + if (o_paiju.cards[i].playround == -1 && o_paiju.cards[i].number != 3 && o_paiju.cards[i].number != 4){ + return true; + } + } + return false; + } + // if (!havecard_inhand() || o_paiju.playproc.round == 2){ //测试用 + if (!havecard_inhand()){ + //进入结算阶段 + o_paiju.step = 6; + } else { + //新一轮出牌 + cls_youle_erqiwang_paiju.new_playround(o_paiju, o_paiju.playproc.round + 1, o_paiju.playproc.maxseat); + } + return re3; + }, + + //获å–埋牌 + get_burycard: function(o_paiju){ + var aryCardIDs = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + if (o_paiju.cards[i].playround == 0){ + aryCardIDs.push(o_paiju.cards[i].id); + } + } + return cls_youle_erqiwang_arith.order_cards(o_paiju.flower, aryCardIDs); + }, + + //èŽ·å–æŠ åº•åŒ… + get_bottom_account: function(o_paiju, msg){ + msg.data.bottom = {}; + msg.data.bottom.cards = o_paiju.method.get_burycard(); + if (o_paiju.playproc.maxseat != o_paiju.banker){ //闲家抠底 + var multiple = cls_youle_erqiwang_arith.get_bottom_multiple(o_paiju.flower, o_paiju.playproc.cards[o_paiju.playproc.maxseat]); + if (multiple > 0){ + msg.data.bottom.multiple = multiple; + var get = o_paiju.method.get_grade_incard(msg.data.bottom.cards); + msg.data.bottom.grade1 = get.grade; + msg.data.bottom.grade2 = multiple * msg.data.bottom.grade1; + } + } + return msg; + }, + + //获å–闲家æ¡åˆ†ï¼ˆä¸åŒ…å«æŠ åº•ï¼‰ + get_jian_grade: function(o_paiju){ + var re = {}; + re.grade = 0; + re.cards = []; + for (var i = 0; i < o_paiju.cards.length; i++){ + if (o_paiju.cards[i].playowner > -1 && o_paiju.cards[i].playowner != o_paiju.banker){ + if (o_paiju.cards[i].score > 0){ + re.grade = re.grade + o_paiju.cards[i].score; + re.cards.push(i); + } + } + } + return re; + }, + + //获å–å°å±€ç»“算包,type 0正常结算 1投é™ç»“ç®— 2解散结算 + get_paiju_account: function(o_paiju, type, msg){ + o_paiju.endtime = min_now(); + //ç¬¬ä¸€å±€ç»“ç®—æ‰£é™¤æˆ¿å¡ + if (o_paiju.idx == 1 && type != 2){ + var do_deduct_roomcard = function(){ + youle_erqiwang.import.deduct_roomcard(o_paiju.o_desk.o_room); + } + min_ontimeout(do_deduct_roomcard, 1000); + } + + if (msg.rpc != "jiesuan"){ + msg.rpc = "jiesuan"; + } + if (!msg.data){ + msg.data = {}; + } + msg.data.aset = {}; + msg.data.aset.banker = o_paiju.banker; + msg.data.aset.call = o_paiju.call; + msg.data.aset.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(o_paiju.call); + msg.data.aset.flower = o_paiju.flower; + var jian_grade = cls_youle_erqiwang_paiju.get_jian_grade(o_paiju); + msg.data.aset.grade = jian_grade.grade; + if (msg.data.bottom && msg.data.bottom.grade2){ + msg.data.aset.grade = msg.data.aset.grade + msg.data.bottom.grade2; + } + switch (type){ + case 0: + msg.data.aset.upgrade = cls_youle_erqiwang_arith.get_upgrade(o_paiju.call, msg.data.aset.grade); + if (msg.data.aset.upgrade > 0){ + o_paiju.result = 0; + } else { + o_paiju.result = 1; + } + break; + case 1: + msg.data.aset.upgrade = -99; + o_paiju.result = 2; + break; + case 2: + msg.data.aset.upgrade = 0; + o_paiju.result = 3; + break; + } + + msg.data.aset.seatlist = []; + var _player0 = {}; + var _player1 = {}; + var _player2 = {}; + //获å–玩家的牌 + var _card0 = cls_youle_erqiwang_paiju.get_seat_cards_owner(o_paiju, 0); + var _card1 = cls_youle_erqiwang_paiju.get_seat_cards_owner(o_paiju, 1); + var _card2 = cls_youle_erqiwang_paiju.get_seat_cards_owner(o_paiju, 2); + //计算冲关或王牌 + var _flower = o_paiju.flower; + if (type != 2){ + _flower = -1; + } + var _chongguan0 = cls_youle_erqiwang_arith.get_chongguan(_flower, _card0); + var _chongguan1 = cls_youle_erqiwang_arith.get_chongguan(_flower, _card1); + var _chongguan2 = cls_youle_erqiwang_arith.get_chongguan(_flower, _card2); + //冲关的牌或王牌 + _player0.cards = _chongguan0.cards; + _player1.cards = _chongguan1.cards; + _player2.cards = _chongguan2.cards; + //关数 + _player0.chongguan = _chongguan0.count; + _player1.chongguan = _chongguan1.count; + _player2.chongguan = _chongguan2.count; + //是å¦ä½œåºŸ + _player0.obsolete = 0; + _player1.obsolete = 0; + _player2.obsolete = 0; + //æ ¹æ®å«åˆ†åˆ¤æ–­å†²å…³æ˜¯å¦ä½œåºŸ + var do_obsolete_with_call = function(player, seat){ + var _dealcards = cls_youle_erqiwang_paiju.get_seat_cards_deal(o_paiju, seat); + var _dealchongguan = cls_youle_erqiwang_arith.get_chongguan(-1, _dealcards); + if (_dealchongguan.count == 0){ + return; + } + var _call = null; + for (var i = 0; i < o_paiju.callproc.length; i++){ + if (o_paiju.callproc[i].seat == seat){ + _call = o_paiju.callproc[i].call; + break; + } + } + if (!_call){ //å†²å…³å¿…å« + player.obsolete = 1; + } else if (_dealchongguan.wang == 4 && _call > 60){ //四王必踢 + player.obsolete = 1; + } + } + + do_obsolete_with_call(_player0, 0); + do_obsolete_with_call(_player1, 1); + do_obsolete_with_call(_player2, 2); + //计算冲关得分 + var _cg0 = _player0.chongguan; + var _cg1 = _player1.chongguan; + var _cg2 = _player2.chongguan; + if (_player0.obsolete){ + _cg0 = 0; + } + if (_player1.obsolete){ + _cg1 = 0; + } + if (_player2.obsolete){ + _cg2 = 0; + } + _player0.grade_cg = _cg0 * 2 - _cg1 - _cg2; + _player1.grade_cg = _cg1 * 2 - _cg2 - _cg0; + _player2.grade_cg = _cg2 * 2 - _cg0 - _cg1; + //计算å‚王得分 + var _w0 = _chongguan0.wang; + var _w1 = _chongguan1.wang; + var _w2 = _chongguan2.wang; + if (_player0.obsolete){ + _w0 = 0; + } + if (_player1.obsolete){ + _w1 = 0; + } + if (_player2.obsolete){ + _w2 = 0; + } + _player0.grade_w = _w0 * 2 - _w1 - _w2; + _player1.grade_w = _w1 * 2 - _w2 - _w0; + _player2.grade_w = _w2 * 2 - _w0 - _w1; + //计算æ¡åˆ†å¾—分 + var _upgrade = msg.data.aset.upgrade; + if (_upgrade == -99){ + _upgrade = -2; + } + switch (o_paiju.banker){ + case -1: + _player0.grade_jf = 0; + _player1.grade_jf = 0; + _player2.grade_jf = 0; + break; + case 0: + _player0.grade_jf = _upgrade * msg.data.aset.multiple * 2; + _player1.grade_jf = _upgrade * msg.data.aset.multiple * -1; + _player2.grade_jf = _player1.grade_jf; + break; + case 1: + _player0.grade_jf = _upgrade * msg.data.aset.multiple * -1; + _player1.grade_jf = _upgrade * msg.data.aset.multiple * 2; + _player2.grade_jf = _player0.grade_jf; + break; + case 2: + _player0.grade_jf = _upgrade * msg.data.aset.multiple * -1; + _player1.grade_jf = _player0.grade_jf; + _player2.grade_jf = _upgrade * msg.data.aset.multiple * 2; + break; + } + //计算本局总得分 + _player0.grade = _player0.grade_cg + _player0.grade_w + _player0.grade_jf; + _player1.grade = _player1.grade_cg + _player1.grade_w + _player1.grade_jf; + _player2.grade = _player2.grade_cg + _player2.grade_w + _player2.grade_jf; + //大局累积得分 + o_paiju.o_desk.seatlist[0][0] = o_paiju.o_desk.seatlist[0][0] + _player0.grade; + o_paiju.o_desk.seatlist[1][0] = o_paiju.o_desk.seatlist[1][0] + _player1.grade; + o_paiju.o_desk.seatlist[2][0] = o_paiju.o_desk.seatlist[2][0] + _player2.grade; + _player0.score = o_paiju.o_desk.seatlist[0][0]; + _player1.score = o_paiju.o_desk.seatlist[1][0]; + _player2.score = o_paiju.o_desk.seatlist[2][0]; + //ä¿å­˜æ¯å±€å¾—分 + o_paiju.o_desk.seatlist[0][1].push(_player0.grade); + o_paiju.o_desk.seatlist[1][1].push(_player1.grade); + o_paiju.o_desk.seatlist[2][1].push(_player2.grade); + + msg.data.aset.seatlist.push(_player0); + msg.data.aset.seatlist.push(_player1); + msg.data.aset.seatlist.push(_player2); + + if (o_paiju.idx >= o_paiju.o_desk.o_room.asetcount || type == 2){ + msg = o_paiju.o_desk.method.get_desk_account(msg); + } + + //ä¿å­˜ç»“算包,供断线é‡è¿žæ—¶ä½¿ç”¨ + o_paiju.tmp_jiesuan_aset = msg.data.aset; + + return msg; + } +} diff --git a/codes/games/server/games/erqiwang/mod.js b/codes/games/server/games/erqiwang/mod.js new file mode 100644 index 0000000..ce27254 --- /dev/null +++ b/codes/games/server/games/erqiwang/mod.js @@ -0,0 +1,457 @@ +////////////////////////////////////////////////////////////////// +/////////////////////////////咻一咻///////////////////////////// +////////////////////////////////////////////////////////////////// + +var youle_erqiwang = youle_erqiwang || cls_mod.new("youle_erqiwang", "erqiwang", youle_app); + +//牌类 +min_loadJsFile("games2/erqiwang/class.pai.js", function(){ +//牌局类 +min_loadJsFile("games2/erqiwang/class.paiju.js", function(){ +//牌桌类 +min_loadJsFile("games2/erqiwang/class.desk.js", function(){ +//算法类 +min_loadJsFile("games2/erqiwang/class.arith.js", function(){ +//对内的输入接å£ç±» +min_loadJsFile("games2/erqiwang/class.import.js", function(){ +//对内的输出接å£ç±» +min_loadJsFile("games2/erqiwang/class.export.js", function(){ + +}); +}); +}); +}); +}); +}); + +//对内的输入接å£ç±»ï¼ˆéœ€è¦çš„外部接å£ï¼‰ +youle_erqiwang.import = null; +//对内的输出接å£ç±»ï¼ˆæä¾›ç»™å¤–部使用的接å£ï¼‰ +youle_erqiwang.export = null; + +//å«åˆ†æˆ–ä¸å« +youle_erqiwang.jiaofen = function(pack){ + var agentid = pack.data.agentid; + var playerid = parseInt(pack.data.playerid); + var gameid = pack.data.gameid; + var roomcode = parseInt(pack.data.roomcode); + var seat = parseInt(pack.data.seat); + var call = parseInt(pack.data.call); + //检查玩家的ä½ç½®æ˜¯å¦æ­£ç¡® + var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid); + if (!o_room){ + return; + } + //牌桌 + var o_desk = o_room.o_desk; + if (!o_desk){ + return; + } + //牌局 + var o_paiju = o_desk.method.curr_paiju(); + if (!o_paiju){ + return; + } + //检查当å‰çš„æ¸¸æˆé˜¶æ®µæ˜¯å¦æ˜¯å«åˆ†é˜¶æ®µ + if (o_paiju.step != 1){ + return; + } + //检查当å‰çš„å«åˆ†ä½ç½® + if (o_paiju.method.get_callgrade_seat() != seat){ + return; + } + //检查当å‰çš„å«åˆ†åˆ†å€¼å¿…须大于0,且是5çš„æ•´æ•°å€ + if (call < 0 || call % 5 != 0){ + return; + } + var curr_call = o_paiju.method.get_callgrade_value(); + //第一家ä¸èƒ½ä¸å«åˆ† + if (curr_call == 0 && call == 0){ + return; + } + //å«åˆ†å¿…é¡»å°äºŽä¹‹å‰çš„å«åˆ† + if (curr_call != 0 && call >= curr_call){ + return; + } + + //å«åˆ†æˆåŠŸ + o_paiju.method.do_callgrade(call); + + //返回å‰ç«¯ + if (o_paiju.step == 1){ + //等待下一家å«åˆ† + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "jiaofen"; + msg.data = {}; + msg.data.seat = seat; + msg.data.call = call; + msg.data.currcall = o_paiju.method.get_callgrade_value(); + msg.data.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(msg.data.currcall); + msg.data.nextseat = o_paiju.method.get_callgrade_seat(); + msg.data.countdown = o_desk.method.get_countdown_jiaofen(); + o_room.method.sendpack_toother(msg, -1); + return; + } + if (o_paiju.step == 2){ + //等待庄家å«ä¸» + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "shangzhuang"; + msg.data = {}; + msg.data.seat = seat; + msg.data.call = call; + msg.data.banker = o_paiju.banker; + msg.data.grade = o_paiju.call; + msg.data.multiple = cls_youle_erqiwang_arith.get_multiple_bycall(msg.data.grade); + msg.data.bottomcards = o_paiju.method.get_bottomcards(); + msg.data.countdown = o_desk.method.get_countdown_xuanzhu(); + if (o_paiju.call < 65){ + msg.data.touxiang = 0; + } else { + msg.data.touxiang = 1; + } + + for (var i = 0; i < o_room.seatlist.length; i++) { + msg.conmode = o_room.seatlist[i].conmode; + msg.fromid = o_room.seatlist[i].fromid; + if (i == o_paiju.banker){ + msg.data.cards = o_paiju.method.get_seat_cards(i); + } else { + delete msg.data.cards; + } + youle_erqiwang.app.SendPack(msg); + } + return; + } +} + +//选主 +youle_erqiwang.xuanzhu = function(pack){ + var agentid = pack.data.agentid; + var playerid = parseInt(pack.data.playerid); + var gameid = pack.data.gameid; + var roomcode = parseInt(pack.data.roomcode); + var seat = parseInt(pack.data.seat); + var flower = parseInt(pack.data.flower); + //检查玩家的ä½ç½®æ˜¯å¦æ­£ç¡® + var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid); + if (!o_room){ + return; + } + //牌桌 + var o_desk = o_room.o_desk; + if (!o_desk){ + return; + } + //牌局 + var o_paiju = o_desk.method.curr_paiju(); + if (!o_paiju){ + return; + } + //检查当å‰çš„æ¸¸æˆé˜¶æ®µæ˜¯å¦æ˜¯é€‰ä¸»é˜¶æ®µ + if (o_paiju.step != 2){ + return; + } + //检查庄家ä½ç½® + if (o_paiju.banker != seat){ + return; + } + //检查花色 + if (flower != 1 && flower != 2 && flower != 3 && flower != 4){ + return; + } + + //选主æˆåŠŸ + o_paiju.method.do_choiceflower(flower); + + //返回å‰ç«¯ + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "xuanzhu"; + msg.data = {}; + msg.data.banker = o_paiju.banker; + msg.data.flower = flower; + msg.data.countdown = o_desk.method.get_countdown_maipai(); + for (var i = 0; i < o_room.seatlist.length; i++) { + msg.conmode = o_room.seatlist[i].conmode; + msg.fromid = o_room.seatlist[i].fromid; + msg.data.cards = o_paiju.method.get_seat_cards(i); + youle_erqiwang.app.SendPack(msg); + } +} + +//埋牌 +youle_erqiwang.maipai = function(pack){ + var agentid = pack.data.agentid; + var playerid = parseInt(pack.data.playerid); + var gameid = pack.data.gameid; + var roomcode = parseInt(pack.data.roomcode); + var seat = parseInt(pack.data.seat); + var cards = pack.data.cards; + //检查玩家的ä½ç½®æ˜¯å¦æ­£ç¡® + var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid); + if (!o_room){ + return; + } + //牌桌 + var o_desk = o_room.o_desk; + if (!o_desk){ + return; + } + //牌局 + var o_paiju = o_desk.method.curr_paiju(); + if (!o_paiju){ + return; + } + //检查当å‰çš„æ¸¸æˆé˜¶æ®µæ˜¯å¦æ˜¯åŸ‹ç‰Œé˜¶æ®µ + if (o_paiju.step != 3){ + return; + } + //检查庄家ä½ç½® + if (o_paiju.banker != seat){ + return; + } + //æ£€æŸ¥åŸ‹ç‰Œæ˜¯å¦æ˜¯8å¼  + if (cards.length != 8){ + return; + } + //检查埋牌是å¦éƒ½åœ¨åº„家手上 + if (!o_paiju.method.check_cards_inhand(cards, seat)){ + return; + } + + //埋牌æˆåŠŸ + o_paiju.method.do_burycard(cards); + + //返回å‰ç«¯ + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "maipai"; + msg.data = {}; + msg.data.seat = o_paiju.playproc.currseat; + msg.data.countdown = o_desk.method.get_countdown_chupai(); + for (var i = 0; i < o_room.seatlist.length; i++) { + msg.conmode = o_room.seatlist[i].conmode; + msg.fromid = o_room.seatlist[i].fromid; + if (i == o_paiju.banker){ + msg.data.cards = o_paiju.method.get_seat_cards(i); + msg.data.bottomcards = cards; + } else { + delete msg.data.cards; + delete msg.data.bottomcards; + } + youle_erqiwang.app.SendPack(msg); + } +} + +//æŠ•é™ +youle_erqiwang.touxiang = function(pack){ + var agentid = pack.data.agentid; + var playerid = parseInt(pack.data.playerid); + var gameid = pack.data.gameid; + var roomcode = parseInt(pack.data.roomcode); + var seat = parseInt(pack.data.seat); + //检查玩家的ä½ç½®æ˜¯å¦æ­£ç¡® + var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid); + if (!o_room){ + return; + } + //牌桌 + var o_desk = o_room.o_desk; + if (!o_desk){ + return; + } + //牌局 + var o_paiju = o_desk.method.curr_paiju(); + if (!o_paiju){ + return; + } + //检查当å‰çš„æ¸¸æˆé˜¶æ®µæ˜¯å¦æ˜¯å«åˆ†ã€åŸ‹ç‰Œã€æŠ•é™é˜¶æ®µ + if (o_paiju.step != 2 && o_paiju.step != 3 && o_paiju.step != 4){ + return; + } + //检查庄家ä½ç½® + if (o_paiju.banker != seat){ + return; + } + //检查是å¦å…è®¸æŠ•é™ + if (o_paiju.call < 65){ + return; + } + + //投é™ç»“ç®— + o_paiju.step = 6; + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.rpc = "jiesuan"; + msg.data = {}; + msg = o_paiju.method.get_paiju_account(1, msg); + o_room.method.sendpack_toother(msg, -1); +} + +//出牌 +youle_erqiwang.chupai = function(pack){ + var agentid = pack.data.agentid; + var playerid = parseInt(pack.data.playerid); + var gameid = pack.data.gameid; + var roomcode = parseInt(pack.data.roomcode); + var seat = parseInt(pack.data.seat); + var cards = pack.data.cards; + //检查玩家的ä½ç½®æ˜¯å¦æ­£ç¡® + var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid); + if (!o_room){ + return; + } + //牌桌 + var o_desk = o_room.o_desk; + if (!o_desk){ + return; + } + //牌局 + var o_paiju = o_desk.method.curr_paiju(); + if (!o_paiju){ + return; + } + //检查当å‰çš„æ¸¸æˆé˜¶æ®µæ˜¯å¦æ˜¯å‡ºç‰Œé˜¶æ®µ + if (o_paiju.step != 4 && o_paiju.step != 5){ + return; + } + //检查出牌ä½ç½® + if (seat != o_paiju.playproc.currseat){ + return; + } + //检查出牌 + if (cards.length == 0){ + return; + } + //检查出牌是å¦éƒ½åœ¨çŽ©å®¶æ‰‹ä¸Š + if (!o_paiju.method.check_cards_inhand(cards, seat)){ + return; + } + + //检查选中的牌是å¦å¯å‡ºï¼Œå¹¶å‡ºç‰Œ + var re = o_paiju.method.do_playcard(cards); + if (!re.result){ + return; + } + + //返回å‰ç«¯ + var msg = {}; + msg.app = "youle"; + msg.route = "erqiwang"; + msg.data = {}; + msg.data.seat = seat; + msg.data.cards = cards; + msg.data.info = o_paiju.seatlist[seat]; + msg.data.nextseat = o_paiju.playproc.currseat; + msg.data.countdown = o_desk.method.get_countdown_chupai(); + if (o_paiju.method.have_baofu()){ + msg.data.baozhu = 1; + } else { + msg.data.baozhu = 0; + } + + switch (re.idx) + { + case 1: //第一个出牌 + msg.rpc = "chupai1"; + msg.data.count = re.count; + msg.data.flower = re.flower; + msg.data.cardtype = re.cardtype; + break; + case 2: //第二个出牌 + msg.rpc = "chupai2"; + break; + case 3: //第三个出牌 + msg.rpc = "chupai3"; + msg.data.maxseat = re.maxseat; + if (re.grade > 0){ + msg.data.grade = re.grade; + // msg.data.gradecards = re.gradecards; + } + break; + } + + if (o_paiju.step == 5){ + for (var i = 0; i < o_room.seatlist.length; i++){ + msg.conmode = o_room.seatlist[i].conmode; + msg.fromid = o_room.seatlist[i].fromid; + if (i == seat){ + msg.data.cardsinhand = o_paiju.method.get_seat_cards(i); + } else { + delete msg.data.cardsinhand; + } + youle_erqiwang.app.SendPack(msg); + } + } else if (o_paiju.step == 6){ + //å°å±€ç»“ç®— + //出牌包的调整 + msg.data.chupai = {}; + msg.data.chupai.seat = msg.data.seat; + msg.data.chupai.cards = msg.data.cards; + msg.data.chupai.maxseat = msg.data.maxseat; + if (msg.data.grade){ + msg.data.chupai.grade = msg.data.grade; + } + if (msg.data.gradecards){ + msg.data.chupai.gradecards = msg.data.gradecards; + } + delete msg.data.seat; + delete msg.data.cards; + delete msg.data.info; + delete msg.data.nextseat; + delete msg.data.countdown; + delete msg.data.baozhu; + delete msg.data.cardsinhand; + delete msg.data.maxseat; + delete msg.data.grade; + delete msg.data.gradecards; + + //èŽ·å–æŠ åº•åŒ… + msg = o_paiju.method.get_bottom_account(msg); + //获å–å°å±€ç»“算包 + msg = o_paiju.method.get_paiju_account(0, msg); + o_room.method.sendpack_toother(msg, -1); + } +} + +//准备 +youle_erqiwang.zhunbei = function(pack){ + var agentid = pack.data.agentid; + var playerid = parseInt(pack.data.playerid); + var gameid = pack.data.gameid; + var roomcode = parseInt(pack.data.roomcode); + var seat = parseInt(pack.data.seat); + //检查玩家的ä½ç½®æ˜¯å¦æ­£ç¡® + var o_room = youle_erqiwang.import.check_player(agentid, gameid, roomcode, seat, playerid, pack.conmode, pack.fromid); + if (!o_room){ + return; + } + //牌桌 + var o_desk = o_room.o_desk; + if (!o_desk){ + return; + } + //牌局 + var o_paiju = o_desk.method.curr_paiju(); + if (!o_paiju){ + return; + } + //检查当å‰çš„æ¸¸æˆé˜¶æ®µæ˜¯å¦æ˜¯ç»“算阶段 + if (o_paiju.step != 6){ + return; + } + //检查当å‰å±€æ•°å°äºŽæ€»å±€æ•° + if (o_desk.paiju_list.length >= o_room.asetcount){ + return; + } + + //准备æˆåŠŸ + o_desk.method.do_prepare(seat); +} \ No newline at end of file diff --git a/codes/games/server/games/erqiwang/二七王接å£.xlsx b/codes/games/server/games/erqiwang/二七王接å£.xlsx new file mode 100644 index 0000000..7e75428 Binary files /dev/null and b/codes/games/server/games/erqiwang/二七王接å£.xlsx differ diff --git a/tools/downloadWeb/index.html b/tools/downloadWeb/index.html index 27a715e..70d4e0c 100644 --- a/tools/downloadWeb/index.html +++ b/tools/downloadWeb/index.html @@ -189,15 +189,15 @@ $(".btn___37Kse").text(btnText); $(".down_load").attr("href", downloadLink); - // if (isAndroid && !isHarmony) { - // $(".down_load").after('
无法安装时备用包下载
'); - // } + if (isAndroid && !isHarmony) { + $(".down_load").after('
无法安装时备用包下载
'); + } } else { // PC Mode $(".shuoming").html('请选择对应系统下载'); var btns = ''; btns += '
Android版下载
'; - // btns += '
无法安装时备用包下载
'; + btns += '
无法安装时备用包下载
'; btns += '
HarmonyOS版下载
'; btns += '
iOS版下载
'; diff --git a/tools/downloadWeb2/css/download.css b/tools/downloadWeb2/css/download.css new file mode 100644 index 0000000..ba0be9d --- /dev/null +++ b/tools/downloadWeb2/css/download.css @@ -0,0 +1,1508 @@ +.am-toast { + position: fixed; + width: 100%; + z-index: 1999; + font-size: 14px; + text-align: center +} + +.am-toast>span { + max-width: 50% +} + +.am-toast.am-toast-mask { + height: 100%; + display: flex; + justify-content: center; + align-items: center; + left: 0; + top: 0; + transform: translateZ(1px) +} + +.am-toast.am-toast-nomask { + position: fixed; + max-width: 50%; + width: auto; + left: 50%; + top: 50%; + transform: translateZ(1px) +} + +.am-toast.am-toast-nomask .am-toast-notice { + transform: translateX(-50%) translateY(-50%) +} + +.am-toast-notice-content .am-toast-text { + min-width: 60px; + border-radius: 3px; + color: #fff; + background-color: rgba(58,58,58,.9); + line-height: 1.5; + padding: 9px 15px +} + +.am-toast-notice-content .am-toast-text.am-toast-text-icon { + border-radius: 5px; + padding: 15px +} + +.am-toast-notice-content .am-toast-text.am-toast-text-icon .am-toast-text-info { + margin-top: 6px +} + +.mobile___3touz { + background: #F5EEE6; + min-height: 100vh; + padding-bottom: 30px; + font-family: "PingFang SC","Microsoft YaHei",Arial,Helvetica,sans-serif +} + +.mobile___3touz .top-content___1-px4 { + display: flex; + flex-direction: column; + align-items: center; + + background-repeat: no-repeat; + background-position-x: 100%; + background-position-y: -120% +} + +.mobile___3touz .top-content___1-px4 .title___vZvj6 { + display: flex; + align-items: center; + padding-top: 96px; + font-weight: 700; + font-size: 24px; + text-align: center; + color: #B18B62; +} + +.mobile___3touz .top-content___1-px4 .desc___1bUF- { + margin-top: 10px; + font-size: 14px; + text-align: center; + color: #B18B62; +} + +.mobile___3touz .top-content___1-px4 .logo___2JBdG { + margin-top: 48px +} + +.mobile___3touz .top-content___1-px4 .logo___2JBdG img { + width: 128px +} + +.mobile___3touz .bottom-content___25WPV { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 40px; + + background-repeat: no-repeat; + background-position-x: 0; + background-position-y: 50px +} + +.mobile___3touz .bottom-content___25WPV .btn___37Kse { + height: 46px; + width: 182px; + line-height: 46px; + background: #CB593C; + border-radius: 8px; + font-weight: 500; + font-size: 16px; + text-align: center; + color: #fff; + cursor: pointer +} + +.mobile___3touz .bottom-content___25WPV .ios___3BJ-b { + margin-top: 20px +} + +.mobile___3touz .bottom-content___25WPV .update-info___1KZ0J { + margin: 48px 16px 0; + width: 90%; + background: #8FADB4; + border-radius: 12px; + padding: 16px +} + +.mobile___3touz .bottom-content___25WPV .update-info___1KZ0J .title___vZvj6 { + font-weight: 700; + font-size: 16px; + color: #fff +} + +.mobile___3touz .bottom-content___25WPV .update-info___1KZ0J .tabs___3HuvX { + display: flex; + height: 46px; + line-height: 46px +} + +.mobile___3touz .bottom-content___25WPV .update-info___1KZ0J .tabs___3HuvX .tab___2xr3g { + font-size: 16px; + color: rgba(255,255,255,.6); + margin-right: 20px +} + +.mobile___3touz .bottom-content___25WPV .update-info___1KZ0J .tabs___3HuvX .tab_active___1UnmD { + color: #fff; + border-bottom: 2px solid #AA9E65 +} + +.mobile___3touz .bottom-content___25WPV .update-info___1KZ0J .content___3LVDL { + margin-top: 20px; + font-size: 14px; + color: #fff +} + +.mobile___3touz .footer___31nRH { + padding-top: 10px; + bottom: 0; + font-size: 12px; + color: rgba(0,0,0,.3); + text-align: center +} + +.mobile___3touz .footer___31nRH a { + margin-left: 5px; + display: inline-block; + color: rgba(0,0,0,.3) +} + +.mobile___3touz .maskLayer___1tWhN { + width: 100%; + height: 100%; + background-color: #000; + opacity: .8; + position: absolute; + top: 0 +} + +.mobile___3touz .maskLayer___1tWhN img { + float: right; + margin-right: 5% +} + +.mobile___3touz .maskLayer___1tWhN .text___17fz4 { + font-weight: 700; + font-size: 17px; + color: #fff; + text-align: center; + margin-top: 120px +} + +.modal___23BIA .close___3nNbL img { + float: right +} + +.modal___23BIA .title___vZvj6 { + margin-top: 17px; + font-weight: 700; + font-size: 17px; + color: rgba(0,0,0,.85) +} + +.modal___23BIA .content___3LVDL { + margin-top: 16px; + font-size: 18px; + line-height: 25px; + text-align: left; + color: rgba(0,0,0,.85); + padding: 0 9px 17px +} + +.modal___23BIA .am-modal-content { + border-radius: 12px +} + +.ant-modal { + box-sizing: border-box; + color: rgba(0,0,0,.85); + font-size: 14px; + font-variant: tabular-nums; + line-height: 1.5715; + list-style: none; + font-feature-settings: "tnum","tnum"; + pointer-events: none; + position: relative; + top: 100px; + width: auto; + max-width: calc(100vw - 32px); + margin: 0 auto; + padding: 0 0 24px +} + +.ant-modal.ant-zoom-appear,.ant-modal.ant-zoom-enter { + transform: none; + opacity: 0; + animation-duration: .3s; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none +} + +.ant-modal-mask { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1000; + height: 100%; + background-color: rgba(0,0,0,.45) +} + +.ant-modal-mask-hidden { + display: none +} + +.ant-modal-wrap { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + overflow: auto; + outline: 0 +} + +.ant-modal-wrap { + z-index: 1000 +} + +.ant-modal-title { + margin: 0; + color: rgba(0,0,0,.85); + font-weight: 500; + font-size: 16px; + line-height: 22px; + word-wrap: break-word +} + +.ant-modal-content { + position: relative; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-radius: 2px; + box-shadow: 0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05); + pointer-events: auto +} + +.ant-modal-close { + position: absolute; + top: 0; + right: 0; + z-index: 10; + padding: 0; + color: rgba(0,0,0,.45); + font-weight: 700; + line-height: 1; + text-decoration: none; + background: transparent; + border: 0; + outline: 0; + cursor: pointer; + transition: color .3s +} + +.ant-modal-close-x { + display: block; + width: 54px; + height: 54px; + font-size: 16px; + font-style: normal; + line-height: 54px; + text-align: center; + text-transform: none; + text-rendering: auto +} + +.ant-modal-close:focus,.ant-modal-close:hover { + color: rgba(0,0,0,.75); + text-decoration: none +} + +.ant-modal-header { + padding: 16px 24px; + color: rgba(0,0,0,.85); + background: #fff; + border-bottom: 1px solid #f0f0f0; + border-radius: 2px 2px 0 0 +} + +.ant-modal-body { + padding: 24px; + font-size: 14px; + line-height: 1.5715; + word-wrap: break-word +} + +.ant-modal-footer { + padding: 10px 16px; + text-align: right; + background: transparent; + border-top: 1px solid #f0f0f0; + border-radius: 0 0 2px 2px +} + +.ant-modal-footer .ant-btn+.ant-btn:not(.ant-dropdown-trigger) { + margin-bottom: 0; + margin-left: 8px +} + +.ant-modal-open { + overflow: hidden +} + +.ant-modal-centered { + text-align: center +} + +.ant-modal-centered:before { + display: inline-block; + width: 0; + height: 100%; + vertical-align: middle; + content: "" +} + +.ant-modal-centered .ant-modal { + top: 0; + display: inline-block; + padding-bottom: 0; + text-align: left; + vertical-align: middle +} + +@media (max-width: 767px) { + .ant-modal { + max-width:calc(100vw - 16px); + margin: 8px auto + } + + .ant-modal-centered .ant-modal { + flex: 1 1 + } +} + +.ant-modal-confirm .ant-modal-header { + display: none +} + +.ant-modal-confirm .ant-modal-body { + padding: 32px 32px 24px +} + +.ant-modal-confirm-body-wrapper:before { + display: table; + content: "" +} + +.ant-modal-confirm-body-wrapper:after { + display: table; + clear: both; + content: "" +} + +.ant-modal-confirm-body .ant-modal-confirm-title { + display: block; + overflow: hidden; + color: rgba(0,0,0,.85); + font-weight: 500; + font-size: 16px; + line-height: 1.4 +} + +.ant-modal-confirm-body .ant-modal-confirm-content { + margin-top: 8px; + color: rgba(0,0,0,.85); + font-size: 14px +} + +.ant-modal-confirm-body>.anticon { + float: left; + margin-right: 16px; + font-size: 22px +} + +.ant-modal-confirm-body>.anticon+.ant-modal-confirm-title+.ant-modal-confirm-content { + margin-left: 38px +} + +.ant-modal-confirm .ant-modal-confirm-btns { + margin-top: 24px; + text-align: right +} + +.ant-modal-confirm .ant-modal-confirm-btns .ant-btn+.ant-btn { + margin-bottom: 0; + margin-left: 8px +} + +.ant-modal-confirm-error .ant-modal-confirm-body>.anticon { + color: #ff4d4f +} + +.ant-modal-confirm-confirm .ant-modal-confirm-body>.anticon,.ant-modal-confirm-warning .ant-modal-confirm-body>.anticon { + color: #faad14 +} + +.ant-modal-confirm-info .ant-modal-confirm-body>.anticon { + color: #1890ff +} + +.ant-modal-confirm-success .ant-modal-confirm-body>.anticon { + color: #52c41a +} + +.ant-modal-confirm .ant-zoom-leave .ant-modal-confirm-btns { + pointer-events: none +} + +.ant-modal-wrap-rtl { + direction: rtl +} + +.ant-modal-wrap-rtl .ant-modal-close { + right: auto; + left: 0 +} + +.ant-modal-wrap-rtl .ant-modal-footer { + text-align: left +} + +.ant-modal-wrap-rtl .ant-modal-footer .ant-btn+.ant-btn { + margin-right: 8px; + margin-left: 0 +} + +.ant-modal-wrap-rtl .ant-modal-confirm-body { + direction: rtl +} + +.ant-modal-wrap-rtl .ant-modal-confirm-body>.anticon { + float: right; + margin-right: 0; + margin-left: 16px +} + +.ant-modal-wrap-rtl .ant-modal-confirm-body>.anticon+.ant-modal-confirm-title+.ant-modal-confirm-content { + margin-right: 38px; + margin-left: 0 +} + +.ant-modal-wrap-rtl .ant-modal-confirm-btns { + text-align: left +} + +.ant-modal-wrap-rtl .ant-modal-confirm-btns .ant-btn+.ant-btn { + margin-right: 8px; + margin-left: 0 +} + +.ant-modal-wrap-rtl.ant-modal-centered .ant-modal { + text-align: right +} + +.ant-select-single .ant-select-selector { + display: flex +} + +.ant-select-single .ant-select-selector .ant-select-selection-search { + position: absolute; + top: 0; + right: 11px; + bottom: 0; + left: 11px +} + +.ant-select-single .ant-select-selector .ant-select-selection-search-input { + width: 100% +} + +.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-single .ant-select-selector .ant-select-selection-placeholder { + padding: 0; + line-height: 30px; + transition: all .3s +} + +.ant-select-single .ant-select-selector .ant-select-selection-item { + position: relative; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none +} + +.ant-select-single .ant-select-selector .ant-select-selection-placeholder { + transition: none; + pointer-events: none +} + +.ant-select-single .ant-select-selector .ant-select-selection-item:after,.ant-select-single .ant-select-selector .ant-select-selection-placeholder:after,.ant-select-single .ant-select-selector:after { + display: inline-block; + width: 0; + visibility: hidden; + content: "\a0" +} + +.ant-select-single.ant-select-show-arrow .ant-select-selection-search { + right: 25px +} + +.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder { + padding-right: 18px +} + +.ant-select-single.ant-select-open .ant-select-selection-item { + color: #bfbfbf +} + +.ant-select-single:not(.ant-select-customize-input) .ant-select-selector { + width: 100%; + height: 32px; + padding: 0 11px +} + +.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input { + height: 30px +} + +.ant-select-single:not(.ant-select-customize-input) .ant-select-selector:after { + line-height: 30px +} + +.ant-select-single.ant-select-customize-input .ant-select-selector:after { + display: none +} + +.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-search { + position: static; + width: 100% +} + +.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder { + position: absolute; + right: 0; + left: 0; + padding: 0 11px +} + +.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder:after { + display: none +} + +.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector { + height: 40px +} + +.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder,.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector:after { + line-height: 38px +} + +.ant-select-single.ant-select-lg:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input { + height: 38px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector { + height: 24px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder,.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector:after { + line-height: 22px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input { + height: 22px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selection-search { + right: 7px; + left: 7px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector { + padding: 0 7px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search { + right: 28px +} + +.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder { + padding-right: 21px +} + +.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector { + padding: 0 11px +} + +.ant-select-selection-overflow { + position: relative; + display: flex; + flex: auto; + flex-wrap: wrap; + max-width: 100% +} + +.ant-select-selection-overflow-item { + flex: none; + align-self: center; + max-width: 100% +} + +.ant-select-multiple .ant-select-selector { + display: flex; + flex-wrap: wrap; + align-items: center; + padding: 1px 4px +} + +.ant-select-show-search.ant-select-multiple .ant-select-selector { + cursor: text +} + +.ant-select-disabled.ant-select-multiple .ant-select-selector { + background: #f5f5f5; + cursor: not-allowed +} + +.ant-select-multiple .ant-select-selector:after { + display: inline-block; + width: 0; + margin: 2px 0; + line-height: 24px; + content: "\a0" +} + +.ant-select-multiple.ant-select-allow-clear .ant-select-selector,.ant-select-multiple.ant-select-show-arrow .ant-select-selector { + padding-right: 24px +} + +.ant-select-multiple .ant-select-selection-item { + position: relative; + display: flex; + flex: none; + box-sizing: border-box; + max-width: 100%; + height: 24px; + margin-top: 2px; + margin-bottom: 2px; + line-height: 22px; + background: #f5f5f5; + border: 1px solid #f0f0f0; + border-radius: 2px; + cursor: default; + transition: font-size .3s,line-height .3s,height .3s; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-margin-end: 4px; + margin-inline-end:4px;-webkit-padding-start: 8px; + padding-inline-start:8px;-webkit-padding-end: 4px; + padding-inline-end:4px} + +.ant-select-disabled.ant-select-multiple .ant-select-selection-item { + color: #bfbfbf; + border-color: #d9d9d9; + cursor: not-allowed +} + +.ant-select-multiple .ant-select-selection-item-content { + display: inline-block; + margin-right: 4px; + overflow: hidden; + white-space: pre; + text-overflow: ellipsis +} + +.ant-select-multiple .ant-select-selection-item-remove { + color: inherit; + font-style: normal; + line-height: 0; + text-align: center; + text-transform: none; + vertical-align: -.125em; + text-rendering: optimizelegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + color: rgba(0,0,0,.45); + font-weight: 700; + font-size: 10px; + line-height: inherit; + cursor: pointer +} + +.ant-select-multiple .ant-select-selection-item-remove>* { + line-height: 1 +} + +.ant-select-multiple .ant-select-selection-item-remove svg { + display: inline-block +} + +.ant-select-multiple .ant-select-selection-item-remove:before { + display: none +} + +.ant-select-multiple .ant-select-selection-item-remove .ant-select-multiple .ant-select-selection-item-remove-icon { + display: block +} + +.ant-select-multiple .ant-select-selection-item-remove>.anticon { + vertical-align: middle +} + +.ant-select-multiple .ant-select-selection-item-remove:hover { + color: rgba(0,0,0,.75) +} + +.ant-select-multiple .ant-select-selection-overflow-item+.ant-select-selection-overflow-item .ant-select-selection-search { + -webkit-margin-start: 0; + margin-inline-start:0} + +.ant-select-multiple .ant-select-selection-search { + position: relative; + max-width: 100%; + -webkit-margin-start: 7px; + margin-inline-start:7px} + +.ant-select-multiple .ant-select-selection-search-input,.ant-select-multiple .ant-select-selection-search-mirror { + height: 24px; + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; + line-height: 24px; + transition: all .3s +} + +.ant-select-multiple .ant-select-selection-search-input { + width: 100%; + min-width: 4.1px +} + +.ant-select-multiple .ant-select-selection-search-mirror { + position: absolute; + top: 0; + left: 0; + z-index: 999; + white-space: pre; + visibility: hidden +} + +.ant-select-multiple .ant-select-selection-placeholder { + position: absolute; + top: 50%; + right: 11px; + left: 11px; + transform: translateY(-50%); + transition: all .3s +} + +.ant-select-multiple.ant-select-lg .ant-select-selector:after { + line-height: 32px +} + +.ant-select-multiple.ant-select-lg .ant-select-selection-item { + line-height: 30px +} + +.ant-select-multiple.ant-select-lg .ant-select-selection-search { + height: 32px; + line-height: 32px +} + +.ant-select-multiple.ant-select-lg .ant-select-selection-search-input,.ant-select-multiple.ant-select-lg .ant-select-selection-search-mirror { + height: 32px; + line-height: 30px +} + +.ant-select-multiple.ant-select-sm .ant-select-selector:after { + line-height: 16px +} + +.ant-select-multiple.ant-select-sm .ant-select-selection-item { + height: 16px; + line-height: 14px +} + +.ant-select-multiple.ant-select-sm .ant-select-selection-search { + height: 16px; + line-height: 16px +} + +.ant-select-multiple.ant-select-sm .ant-select-selection-search-input,.ant-select-multiple.ant-select-sm .ant-select-selection-search-mirror { + height: 16px; + line-height: 14px +} + +.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder { + left: 7px +} + +.ant-select-multiple.ant-select-sm .ant-select-selection-search { + -webkit-margin-start: 3px; + margin-inline-start:3px} + +.ant-select-multiple.ant-select-lg .ant-select-selection-item { + height: 32px; + line-height: 32px +} + +.ant-select-disabled .ant-select-selection-item-remove { + display: none +} + +.ant-select-status-error.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer) .ant-select-selector { + background-color: #fff; + border-color: #ff4d4f!important +} + +.ant-select-status-error.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-focused .ant-select-selector,.ant-select-status-error.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-open .ant-select-selector { + border-color: #ff7875; + box-shadow: 0 0 0 2px rgba(255,77,79,.2); + border-right-width: 1px; + outline: 0 +} + +.ant-select-status-warning.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer) .ant-select-selector { + background-color: #fff; + border-color: #faad14!important +} + +.ant-select-status-warning.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-focused .ant-select-selector,.ant-select-status-warning.ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer).ant-select-open .ant-select-selector { + border-color: #ffc53d; + box-shadow: 0 0 0 2px rgba(250,173,20,.2); + border-right-width: 1px; + outline: 0 +} + +.ant-select-status-error.ant-select-has-feedback .ant-select-clear,.ant-select-status-success.ant-select-has-feedback .ant-select-clear,.ant-select-status-validating.ant-select-has-feedback .ant-select-clear,.ant-select-status-warning.ant-select-has-feedback .ant-select-clear { + right: 32px +} + +.ant-select-status-error.ant-select-has-feedback .ant-select-selection-selected-value,.ant-select-status-success.ant-select-has-feedback .ant-select-selection-selected-value,.ant-select-status-validating.ant-select-has-feedback .ant-select-selection-selected-value,.ant-select-status-warning.ant-select-has-feedback .ant-select-selection-selected-value { + padding-right: 42px +} + +.ant-select { + box-sizing: border-box; + margin: 0; + padding: 0; + color: rgba(0,0,0,.85); + font-size: 14px; + font-variant: tabular-nums; + line-height: 1.5715; + list-style: none; + font-feature-settings: "tnum","tnum"; + position: relative; + display: inline-block; + cursor: pointer +} + +.ant-select:not(.ant-select-customize-input) .ant-select-selector { + position: relative; + background-color: #fff; + border: 1px solid #d9d9d9; + border-radius: 2px; + transition: all .3s cubic-bezier(.645,.045,.355,1) +} + +.ant-select:not(.ant-select-customize-input) .ant-select-selector input { + cursor: pointer +} + +.ant-select-show-search.ant-select:not(.ant-select-customize-input) .ant-select-selector { + cursor: text +} + +.ant-select-show-search.ant-select:not(.ant-select-customize-input) .ant-select-selector input { + cursor: auto +} + +.ant-select-focused:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) .ant-select-selector { + border-color: #40a9ff; + box-shadow: 0 0 0 2px rgba(24,144,255,.2); + border-right-width: 1px; + outline: 0 +} + +.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector { + color: rgba(0,0,0,.25); + background: #f5f5f5; + cursor: not-allowed +} + +.ant-select-multiple.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector { + background: #f5f5f5 +} + +.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector input { + cursor: not-allowed +} + +.ant-select:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input { + margin: 0; + padding: 0; + background: transparent; + border: none; + outline: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +.ant-select:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input::-webkit-search-cancel-button { + display: none; + -webkit-appearance: none +} + +.ant-select:not(.ant-select-disabled):hover .ant-select-selector { + border-color: #40a9ff; + border-right-width: 1px +} + +.ant-select-selection-item { + flex: 1 1; + overflow: hidden; + font-weight: 400; + white-space: nowrap; + text-overflow: ellipsis +} + +@media (-ms-high-contrast:none) { + .ant-select-selection-item,.ant-select-selection-item ::-ms-backdrop { + flex: auto + } +} + +.ant-select-selection-placeholder { + flex: 1 1; + overflow: hidden; + color: #bfbfbf; + white-space: nowrap; + text-overflow: ellipsis; + pointer-events: none +} + +@media (-ms-high-contrast:none) { + .ant-select-selection-placeholder,.ant-select-selection-placeholder ::-ms-backdrop { + flex: auto + } +} + +.ant-select-arrow { + display: inline-block; + color: inherit; + font-style: normal; + line-height: 0; + text-transform: none; + vertical-align: -.125em; + text-rendering: optimizelegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + position: absolute; + top: 50%; + right: 11px; + display: flex; + align-items: center; + height: 12px; + margin-top: -6px; + color: rgba(0,0,0,.25); + font-size: 12px; + line-height: 1; + text-align: center; + pointer-events: none +} + +.ant-select-arrow>* { + line-height: 1 +} + +.ant-select-arrow svg { + display: inline-block +} + +.ant-select-arrow:before { + display: none +} + +.ant-select-arrow .ant-select-arrow-icon { + display: block +} + +.ant-select-arrow .anticon { + vertical-align: top; + transition: transform .3s +} + +.ant-select-arrow .anticon>svg { + vertical-align: top +} + +.ant-select-arrow .anticon:not(.ant-select-suffix) { + pointer-events: auto +} + +.ant-select-disabled .ant-select-arrow { + cursor: not-allowed +} + +.ant-select-arrow>:not(:last-child) { + -webkit-margin-end: 8px; + margin-inline-end:8px} + +.ant-select-clear { + position: absolute; + top: 50%; + right: 11px; + z-index: 1; + display: inline-block; + width: 12px; + height: 12px; + margin-top: -6px; + color: rgba(0,0,0,.25); + font-size: 12px; + font-style: normal; + line-height: 1; + text-align: center; + text-transform: none; + background: #fff; + cursor: pointer; + opacity: 0; + transition: color .3s ease,opacity .15s ease; + text-rendering: auto +} + +.ant-select-clear:before { + display: block +} + +.ant-select-clear:hover { + color: rgba(0,0,0,.45) +} + +.ant-select:hover .ant-select-clear { + opacity: 1 +} + +.ant-select-dropdown { + margin: 0; + color: rgba(0,0,0,.85); + font-variant: tabular-nums; + line-height: 1.5715; + list-style: none; + font-feature-settings: "tnum","tnum",; + position: absolute; + top: -9999px; + left: -9999px; + z-index: 1050; + box-sizing: border-box; + padding: 4px 0; + overflow: hidden; + font-size: 14px; + font-variant: normal; + background-color: #fff; + border-radius: 2px; + outline: none; + box-shadow: 0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05) +} + +.ant-select-dropdown.ant-slide-up-appear.ant-slide-up-appear-active.ant-select-dropdown-placement-bottomLeft,.ant-select-dropdown.ant-slide-up-enter.ant-slide-up-enter-active.ant-select-dropdown-placement-bottomLeft { + animation-name: antSlideUpIn +} + +.ant-select-dropdown.ant-slide-up-appear.ant-slide-up-appear-active.ant-select-dropdown-placement-topLeft,.ant-select-dropdown.ant-slide-up-enter.ant-slide-up-enter-active.ant-select-dropdown-placement-topLeft { + animation-name: antSlideDownIn +} + +.ant-select-dropdown.ant-slide-up-leave.ant-slide-up-leave-active.ant-select-dropdown-placement-bottomLeft { + animation-name: antSlideUpOut +} + +.ant-select-dropdown.ant-slide-up-leave.ant-slide-up-leave-active.ant-select-dropdown-placement-topLeft { + animation-name: antSlideDownOut +} + +.ant-select-dropdown-hidden { + display: none +} + +.ant-select-dropdown-empty { + color: rgba(0,0,0,.25) +} + +.ant-select-item-empty { + position: relative; + display: block; + min-height: 32px; + padding: 5px 12px; + color: rgba(0,0,0,.85); + font-weight: 400; + font-size: 14px; + line-height: 22px; + color: rgba(0,0,0,.25) +} + +.ant-select-item { + position: relative; + display: block; + min-height: 32px; + padding: 5px 12px; + color: rgba(0,0,0,.85); + font-weight: 400; + font-size: 14px; + line-height: 22px; + cursor: pointer; + transition: background .3s ease +} + +.ant-select-item-group { + color: rgba(0,0,0,.45); + font-size: 12px; + cursor: default +} + +.ant-select-item-option { + display: flex +} + +.ant-select-item-option-content { + flex: auto; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis +} + +.ant-select-item-option-state { + flex: none +} + +.ant-select-item-option-active:not(.ant-select-item-option-disabled) { + background-color: #f5f5f5 +} + +.ant-select-item-option-selected:not(.ant-select-item-option-disabled) { + color: rgba(0,0,0,.85); + font-weight: 600; + background-color: #e6f7ff +} + +.ant-select-item-option-selected:not(.ant-select-item-option-disabled) .ant-select-item-option-state { + color: #1890ff +} + +.ant-select-item-option-disabled { + color: rgba(0,0,0,.25); + cursor: not-allowed +} + +.ant-select-item-option-disabled.ant-select-item-option-selected { + background-color: #f5f5f5 +} + +.ant-select-item-option-grouped { + padding-left: 24px +} + +.ant-select-lg { + font-size: 16px +} + +.ant-select-borderless .ant-select-selector { + background-color: transparent!important; + border-color: transparent!important; + box-shadow: none!important +} + +.ant-select.ant-select-in-form-item { + width: 100% +} + +.ant-select-compact-item:not(.ant-select-compact-last-item) { + margin-right: -1px +} + +.ant-select-compact-item:not(.ant-select-compact-last-item).ant-select-compact-item-rtl { + margin-right: 0; + margin-left: -1px +} + +.ant-select-compact-item:active>*,.ant-select-compact-item:focus>*,.ant-select-compact-item:hover>* { + z-index: 2 +} + +.ant-select-compact-item.ant-select-focused>* { + z-index: 2 +} + +.ant-select-compact-item[disabled]>* { + z-index: 0 +} + +.ant-select-compact-item:not(.ant-select-compact-first-item):not(.ant-select-compact-last-item).ant-select>.ant-select-selector { + border-radius: 0 +} + +.ant-select-compact-item.ant-select-compact-first-item.ant-select:not(.ant-select-compact-last-item):not(.ant-select-compact-item-rtl)>.ant-select-selector { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.ant-select-compact-item.ant-select-compact-last-item.ant-select:not(.ant-select-compact-first-item):not(.ant-select-compact-item-rtl)>.ant-select-selector { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.ant-select-compact-item.ant-select.ant-select-compact-first-item.ant-select-compact-item-rtl:not(.ant-select-compact-last-item)>.ant-select-selector { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.ant-select-compact-item.ant-select.ant-select-compact-last-item.ant-select-compact-item-rtl:not(.ant-select-compact-first-item)>.ant-select-selector { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.ant-select-rtl { + direction: rtl +} + +.ant-select-rtl .ant-select-arrow { + right: auto; + left: 11px +} + +.ant-select-rtl .ant-select-clear { + right: auto; + left: 11px +} + +.ant-select-dropdown-rtl { + direction: rtl +} + +.ant-select-dropdown-rtl .ant-select-item-option-grouped { + padding-right: 24px; + padding-left: 12px +} + +.ant-select-rtl.ant-select-multiple.ant-select-allow-clear .ant-select-selector,.ant-select-rtl.ant-select-multiple.ant-select-show-arrow .ant-select-selector { + padding-right: 4px; + padding-left: 24px +} + +.ant-select-rtl.ant-select-multiple .ant-select-selection-item { + text-align: right +} + +.ant-select-rtl.ant-select-multiple .ant-select-selection-item-content { + margin-right: 0; + margin-left: 4px; + text-align: right +} + +.ant-select-rtl.ant-select-multiple .ant-select-selection-search-mirror { + right: 0; + left: auto +} + +.ant-select-rtl.ant-select-multiple .ant-select-selection-placeholder { + right: 11px; + left: auto +} + +.ant-select-rtl.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder { + right: 7px +} + +.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-placeholder { + right: 0; + left: 9px; + text-align: right +} + +.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-search { + right: 11px; + left: 25px +} + +.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder { + padding-right: 0; + padding-left: 18px +} + +.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search { + right: 6px +} + +.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder { + padding-right: 0; + padding-left: 21px +} + +.ant-empty { + margin: 0 8px; + font-size: 14px; + line-height: 1.5715; + text-align: center +} + +.ant-empty-image { + height: 100px; + margin-bottom: 8px +} + +.ant-empty-image img { + height: 100% +} + +.ant-empty-image svg { + height: 100%; + margin: auto +} + +.ant-empty-footer { + margin-top: 16px +} + +.ant-empty-normal { + margin: 32px 0; + color: rgba(0,0,0,.25) +} + +.ant-empty-normal .ant-empty-image { + height: 40px +} + +.ant-empty-small { + margin: 8px 0; + color: rgba(0,0,0,.25) +} + +.ant-empty-small .ant-empty-image { + height: 35px +} + +.ant-empty-img-default-ellipse { + fill: #f5f5f5; + fill-opacity: .8 +} + +.ant-empty-img-default-path-1 { + fill: #aeb8c2 +} + +.ant-empty-img-default-path-2 { + fill: url(#linearGradient-1) +} + +.ant-empty-img-default-path-3 { + fill: #f5f5f7 +} + +.ant-empty-img-default-path-4 { + fill: #dce0e6 +} + +.ant-empty-img-default-path-5 { + fill: #dce0e6 +} + +.ant-empty-img-default-g { + fill: #fff +} + +.ant-empty-img-simple-ellipse { + fill: #f5f5f5 +} + +.ant-empty-img-simple-g { + stroke: #d9d9d9 +} + +.ant-empty-img-simple-path { + fill: #fafafa +} + +.ant-empty-rtl { + direction: rtl +} + +.pc___1L_rd { + background-color: #f6f9ff; + min-height: 100vh; + font-family: "PingFang SC","Microsoft YaHei",Arial,Helvetica,sans-serif +} + +.pc___1L_rd .header___3KIw6 { + width: 100%; + position: fixed; + padding-left: 300px; + height: 64px; + line-height: 64px; + background-color: #fff +} + +.pc___1L_rd .content___oGU9u .bottom___3VIzY .update-info___1KE8A { + background: #fff; + border-radius: 12px; + width: 100% +} + +.pc___1L_rd .content___oGU9u .bottom___3VIzY .update-info___1KE8A .title___2kG_B { + padding-top: 32px; + font-weight: 500; + font-size: 24px; + color: rgba(0,0,0,.85) +} + +.pc___1L_rd .content___oGU9u .bottom___3VIzY .update-info___1KE8A .content___oGU9u { + margin-top: 32px; + padding-left: 200px; + padding-bottom: 32px; + text-align: left +} + +.pc___1L_rd .content___oGU9u .bottom___3VIzY .update-info___1KE8A .content___oGU9u .label___3GJis { + font-weight: 500; + font-size: 22px; + color: rgba(0,0,0,.85) +} + +.pc___1L_rd .content___oGU9u .bottom___3VIzY .update-info___1KE8A .content___oGU9u .text___36doz { + margin-top: 24px; + padding-right: 200px; + font-size: 18px; + color: rgba(0,0,0,.85) +} + +.pc___1L_rd .content___oGU9u .bottom___3VIzY .update-info___1KE8A .content___oGU9u .time___28se3 { + margin-top: 4px; + font-size: 14px; + color: rgba(0,0,0,.45) +} + +.pc___1L_rd .footer___2wO0v { + position: fixed; + bottom: 0; + width: 100%; + height: 54px; + line-height: 54px; + text-align: center; + color: #fff; + background: #252e44 +} + +.pc___1L_rd .footer___2wO0v a { + margin-left: 5px; + color: #fff; + text-decoration: underline; + display: inline-block +} diff --git a/tools/downloadWeb2/css/main.css b/tools/downloadWeb2/css/main.css new file mode 100644 index 0000000..d4ad957 --- /dev/null +++ b/tools/downloadWeb2/css/main.css @@ -0,0 +1,713 @@ +@charset "utf-8"; +@charset "utf-8"; +/*防止用户自定义背景颜色对网页的影å“,添加让用户å¯ä»¥è‡ªå®šä¹‰å­—体 */ +html{-webkit-text-size-adjust:100%; /*ç¦ç”¨Webkit内核æµè§ˆå™¨çš„æ–‡å­—大å°è°ƒæ•´åŠŸèƒ½ï¼Œé»˜è®¤æ˜¯auto;*/ + -ms-text-size-adjust:100%; /*ç¦ç”¨IE内核æµè§ˆå™¨çš„æ–‡å­—大å°è°ƒæ•´åŠŸèƒ½ï¼Œé»˜è®¤æ˜¯auto;*/ + font-family: sans-serif; + -webkit-font-smoothing: antialiased; + height: 100%; + touch-action: manipulation; /*å–æ¶ˆç§»åŠ¨ç«¯click300ms的延迟*/ +} +body{font-family: "Helvetica", "Tahoma", "Arial", "PingFang SC", "Microsoft Yahei", "SimSun", "SimHei", "sans-serif"; color: #848484; background: #f1f1f194; font-size: 14px;} + +/*针对英文å•è¯ï¼Œå¼ºåˆ¶è®©å•è¯æ¢è¡Œ,break-word䏿‹†åˆ†å•è¯, break-all拆分å•è¯*/ +*{word-wrap: break-word; /*word-break: break-all;*/} +.break-all{word-break: break-all;} + +a, abbr, acronym, address, applet, article, aside, audio, b, big, body, button, canvas, caption, center, cite, code, dd, del, details, dfn, div, dl, dt, em, embed, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, html, hr, i, iframe, input, img, ins, kbd, label, legend, li, mark, menu, nav, object, ol, output, p, pre, q, ruby, s, samp, section, select, small, span, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, time, tr, tt, textarea, u, ul, var, video,.h1, .h2, .h3{margin: 0; padding: 0;} + +dt,label{font-weight:normal; font-size:100%;}/*此处增加dt,label针对bootstrap的加粗定义*/ + +input,button,textarea,select,optgroup,option{font-size: 100%; font-weight: normal; outline: none;} +input,button,textarea{-webkit-appearance: none;}/*去除ios按钮内阴影ã€åœ†è§’,对å•选框ã€å¤é€‰æ¡†æœ‰å½±å“*/ +input[type=checkbox]{-webkit-appearance: checkbox;} +input[type=radio]{-webkit-appearance: radio;} +input::-webkit-input-safebox-button{display: none;}/*解决æœç‹—æµè§ˆå™¨å¯†ç æ¡†è‡ªå¸¦å®‰å…¨é”®ç›˜*/ + +input:focus,textarea:focus{outline: none;} + +th,td,button,input,select,textarea{-webkit-font-smoothing: antialiased; -moz-font-smoothing: antialiased;}/*页é¢çš„字体抗锯齿,字体会更清晰圆滑*/ +textarea{resize: none; border: 1px solid #e5e5e5; padding: 5px; width: 100%; border-radius: 0;} + +address,caption,cite,code,dfn,th,var,/*em,*/i{font-style: normal; font-weight: normal;} +sub,sup{vertical-align: baseline;} + +button{overflow: visible; vertical-align: middle; outline: none; height: auto;} + +/*去掉列表标签的默认样å¼*/ +ul,ol,li{list-style-type: none;} + +/*é‡ç½®tableæ ·å¼*/ +table{border-collapse:collapse; border-spacing:0; /*table-layout: fixed;*/}/*table-layout: fixed; 表格布局尺寸固定(默认等分表格),表格的宽度ä¸å†ç”±å•元格的内容多少而决定,å¯è‡ªå®šä¹‰å®½åº¦(ç»™th,tdä¸èµ·ä½œç”¨)*/ +/*border-collapse: separate(独立边框); border-spacing:20px 20px(边框å•元格间è·ç¦»ï¼‰;*/ +/*btn基础样å¼*/ +.ms-btn{display: inline-block; padding: 6px 12px; border-radius: 0; text-align: center; white-space: nowrap; vertical-align: middle; cursor: pointer; background: none; border: 1px solid transparent;} +/*a链接*/ +a{outline:none; text-decoration: none; color: #848484; cursor: pointer;} +a:focus{outline: none; text-decoration: none; color: inherit;} +a:hover{outline: none; color: #157df1; text-decoration: none;} + +@media (min-width: 1200px) { + .container{} + .table-responsive{overflow-x: visible;} +} +/*----------分å‘è½åœ°é¡µ----------*/ +.template-common .form-control{height: 40px;} +.passwords .template-common{padding: 0 320px;} +.template-common{padding: 0 235px;} +.template-common hr{border-top-color: #e5e5e5; margin-top: 25px; display: none;} +.template-common .t-icon{background-color: #fff; width: 180px; height: 180px; border-radius: 25px; box-shadow: 0 0 10px rgba(0,0,0,.2); display: flex; align-items: center; margin: 0 auto;} +.template-common .t-icon img{width: 120px; height: 120px; border-radius: 30px; border: 1px solid #e5e5e5; margin: 0 auto;} +.template-common .template-btn-wrap{text-align: center;} +.template-common .template-btn{color: #fff; background-color: #51a3fe; height: 50px; padding: 0 38px; line-height: 48px; font-size: 18px; margin: 35px auto 15px; display: inline-block;} +.template-common .decoding{color: #fff; background-color: #157df1; height: 50px; padding: 0; width: 180px; text-align: center; line-height: 48px; font-size: 18px; margin: 30px auto 20px; display: block;} +.template-common .template-btn span:last-of-type{line-height: 50px;} +.template-common .template-btn .iconfont{font-size: 36px; margin-left: -5px;} +.template-common .t-apply{color: #666; text-align: center;} +.template-common .t-code{color: #666; width: 200px; overflow: hidden; margin: 35px auto 0; text-align: center;} +.template-common .t-code img{border: 1px solid #e5e5e5; width: 150px; height: 150px; margin: 0 auto 5px;} + +.template-common .t-name{color: #333; text-align: center;} +.template-common .t-name .name-info span{margin-right: 10px; color: #666;} +.template-common .t-name .tit{font-size: 28px; margin-bottom: 10px; margin-top: 15px;} +.template-common .t-introduce{color: #333;} +.template-common .t-introduce .tit{font-size: 20px; margin-top: 25px;} +.template-common .t-introduce p{margin-top: 15px;} +.template-common .t-contact{color: #333; margin-top: 20px;} +.template-common .t-contact .tit{font-size: 20px; margin-bottom: 15px;} +.template-common .t-contact dl{margin-bottom: 5px;} +.template-common .t-contact dl dt{margin-right: 10px;} + +.template-pwd{border: 1px solid #e5e5e5; border-radius: 3px; padding: 45px 35px; margin-top: 45px; /*margin-bottom: 50px;*/ display: none;} +.template-pwd label{color: #3e4753; text-align: center; display: block;} +.template-pwd .form-control{margin-top: 15px;} + +.passwords+.template-footer{margin-top: 50px;} +.template-footer{margin-top: 30px;} +.template-footer .methods-tutorial-full{background-color: #ff6666;} +.template-footer .methods-tutorial-full a{color: #fff;} +.template-footer .methods-tutorial-full a.fl{height: 50px; line-height: 50px;} +.template-footer .methods-tutorial-full a.fl:hover{text-decoration: underline;} +.template-footer .methods-tutorial-full a.fr{width: 22px; height: 22px; line-height: 22px; border: 1px solid #fff; border-radius: 50%; text-align: center; margin-top: 14px;} +.template-footer .methods-tutorial-full a.fr .iconfont{color: #fff;} + +.template-footer .t-footer{text-align: center; margin-top: 30px; padding-bottom: 30px;} +.template-footer .t-footer a{color: #157df1;} +.template-footer .t-footer a:hover{text-decoration: underline;} + +/*应用截图*/ +.template-common .app-screen{margin-top: 20px;} +.template-common .app-screen .tit{font-size: 20px; margin-bottom: 15px; color: #333;} +.template-common .app-screen .s-responsive{overflow: hidden; height: 405px; width: 100%; overflow-x: auto;} +/*.template-common .app-screen ul{height: 405px;}*/ +.template-common .app-screen ul li{float: left; margin-right: 20px;} +.template-common .app-screen ul li img{width: auto; height: auto; max-width: 800px; max-height: 405px;} +.template-common .app-screen ul li:last-of-type{margin-right: 0;} + +/*模æ¿1*/ +.template-1 .t-bg-1{background: #157df1 url("../images/t-04.png") repeat-x center bottom; height: 175px;} +.template-1 .content{margin-top: -125px; padding: 0 80px;} +.template-1 .template-common{padding: 0;} +.template-1 .template-common .t-icon{box-shadow: none; width: auto; height: auto; background-color: transparent;} +.template-1.passwords .template-common .t-code{width: 125px; margin-top: 35px;} +.template-1 .template-common .t-code{width: 200px; margin-top: 15px;} +.template-1 .template-common .t-code img{width: 125px; height: 125px; margin: 0 auto;} +.template-1 .template-common .t-name{text-align: left;} +.template-1 .template-common .t-name .name-info span{color: #fff;} +.template-1+.template-footer{margin-top: 140px;} +.template-1 .template-common .template-btn{margin-top: 30px; margin-bottom: 15px; padding: 0 15px;} + +.template-1 .content .c-left{background: url("../images/t-05.png") no-repeat center; width: 308px; height: 608px; padding-top: 110px;} +.template-1.passwords .content .c-left{padding-top: 140px;} +.template-1.passwords .content .c-right{margin-left: 130px; width: auto;} +.template-1 .content .c-right{margin-left: 100px; width: 630px;} +.template-1 .content .c-right .t-name{color: #fff; margin-bottom: 100px;} +.template-1 .template-common .t-name .tit{margin-top: 5px;} +.template-1 .content .c-right .t-introduce{/*margin-top: 100px;*/ margin-bottom: 45px;} +.template-1 .content .c-right .t-contact{margin-top: 0; margin-bottom: 45px;} + +.template-1 .template-pwd{width: 500px; height: 230px; background-color: #fafafa; margin-top: 90px; padding: 60px 30px 0; position: relative; border-radius: 5px; display: none; border: none;} +.template-1 .template-pwd .form-group{text-align: center;} +.template-1 .template-pwd .form-group label{color: #3e4753;} + +.template-1 .template-pwd .form-group .form-control{border-color: #e5e5e5; margin-top: 5px;} +.template-1 .template-pwd .form-group .form-control:focus{border-color: #66afe9;} +.template-1 .template-pwd .top-pwd{position: absolute; left: 50%; top: -20px; margin-left: -30px; width: 60px; height: 60px; border: 1px solid #157df1; border-radius: 50%; display: flex; justify-content: center; align-items: center; background-color: #fafafa;} +.template-1 .template-pwd .top-pwd .iconfont{color: #157df1; font-size: 30px;} + +.template-1 .template-common .app-screen .s-responsive{width: 730px;} +/*/模æ¿1*/ + +/*模æ¿2*/ +.template-2 .t-bg-2{/* background: url("../images/t-06.jpg") center; */background-color: #51a3fe; height: 130px;} +.template-2 .content{margin-top: -90px;} +/*/模æ¿2*/ + +/*模æ¿3*/ +.template-3 .t-bg-3{background: url("../images/t-07.jpg") center; height: 160px;} +.template-3 .content{margin-top: 20px;} +.template-3 .template-common .t-icon{width: 160px; height: 160px; border-radius: 50%;} +.template-3 .template-common .t-icon img{width: 105px; height: 105px;} +/*/模æ¿3*/ + +/*模æ¿4*/ +.template-4 .t-bg-4{background: url("../images/t-09.png") no-repeat center; height: 485px;} +.template-4 .t-left{width: 255px; margin-left: 265px; margin-top: 150px;} +.template-4 .t-right{margin-left: 225px; margin-top: 45px;} +.template-4 .content4 .template-common{padding: 0;} +.template-4 .content4 .template-common .t-icon{width: auto; height: auto; background-color: transparent; box-shadow: none;} +.template-4 .content4 .template-common .t-icon img{border: none;} +.template-4 .content4 .template-common .t-name .tit{color: #fff; margin-top: 25px; margin-bottom: 20px;} +.template-4 .content4 .template-common .t-name .name-info span{display: block; text-align: center; margin-right: 0; color: #fff; line-height: 24px;} +.template-4 .template-common .template-btn{margin-bottom: 20px;} +.template-4 .content>.template-common{padding: 80px 100px 0;} +.template-4 .template-common .t-code{width: 200px;} +.template-4 .template-common .t-code img{width: 120px; height: 120px; margin-left: auto; margin-right: auto;} +.template-4 .template-common .decoding{width: 100%; margin-top: 30px;} + +.template-4 .template-pwd{border: none; padding: 0; width: 490px; margin: 0 auto;} + +.template-4+.template-footer{margin-top: 100px;} + +.template-4 .content>.template-common .app-screen{width: 730px;} +/*/模æ¿4*/ + +/*模æ¿5*/ +.template-5 .left-bg{position: absolute; left: 0; top: 0; background: url("../images/t11.png") no-repeat left top; width: 283px; height: 1012px;} +.template-5 .right-bg{position: absolute; right: 0; top: 0; background: url("../images/t12.png") no-repeat right top; width: 283px; height: 1012px;} + +.template-5 .content{padding-top: 100px;} +.template-5 .template-common{padding: 0 235px;} +.template-5 .template-common .t-icon{border-radius: 50%; position: relative; margin-left: 180px;} +.template-5 .template-common .t-icon .bg-shadow{position: absolute; left: -20px; top: 70px; border-radius: 90px; width: 360px; height: 180px; background-color: #eff2f2; z-index: -1; transform: rotate(45deg);} + +.template-5 .template-common .t-icon .code{position: absolute; top: 160px; right: -160px; transition: all 500ms;} +.template-5 .template-common .t-icon .code img{border-radius: 0; border: none; width: 110px; height: 110px; transition: all 500ms;} +.template-5 .template-common .t-icon .code:hover{width: 240px; height: 240px; right: -190px; top: 130px;} +.template-5 .template-common .t-icon .code:hover img{width: 160px; height: 160px;} +.template-5 .template-common .t-name-wrap{width: 350px; margin-left: auto; margin-right: auto;} +.template-5 .template-common .t-name-wrap .t-name{text-align: left;} +.template-5 .template-common .t-name-wrap .template-btn{margin: 45px 0 20px} +.template-5 .template-common .t-name{margin-top: 200px;} +.template-5 .template-common .t-name .tit{margin-bottom: 20px;} +.template-5 .template-common .t-name .name-info{text-align: left; line-height: 24px;} +.template-5 .template-common .t-apply{text-align: left; padding-left: 15px;} +.template-5 .template-common .template-btn{padding: 0 53px;} + +.template-5 .template-common hr{margin-top: 50px;} +.template-5 .template-common .t-introduce .tit{margin-top: 50px;} +.template-5 .template-common .t-contact{margin-top: 25px;} + +.template-5.passwords+.template-footer{margin-top: 99px;} +.template-5+.template-footer{margin-top: 40px;} + +.template-5 .template-pwd{width: 555px; height: 245px; margin: 80px auto 0; padding: 60px 30px 0; position: relative; border-radius: 5px;} + +.template-5 .template-pwd .top-pwd{position: absolute; left: 50%; top: -30px; margin-left: -30px; width: 60px; height: 60px; border: 1px solid #157df1; border-radius: 50%; display: flex; justify-content: center; align-items: center; background-color: #fafafa;} +.template-5 .template-pwd .top-pwd .iconfont{color: #157df1; font-size: 30px;} + +.template-5 .template-pwd .decoding{width: 100%; margin-top: 30px; margin-bottom: 30px;} +/*/模æ¿5*/ + +/*模æ¿6*/ +.template-6 .t-bg-6{background-color: #f4f4f4; height: 80px; line-height: 80px;} +.template-6 .t-top .tit{font-size: 30px; color: #333;} +.template-6 .t-top .name-info{font-size: 18px; color: #666;} +.template-6 .t-top .name-info span{margin-left: 10px;} + +.template-6 .content{margin-top: 55px;} +.template-6 .template-common .template-btn{margin-bottom: 15px;} +.template-6 .template-common .show-hr{display: block; margin-top: 40px;} +.template-6 .template-common .t-code{margin-top: 40px;} +/*/模æ¿6*/ + +/*å¯†ç æ˜¾ç¤ºæŽ§åˆ¶*/ +.passwords .template-pwd{display: block;} +.passwords .pc-pwd{display: none !important;} +.passwords .template-pwd{display: block;} +/*----------/分å‘è½åœ°é¡µ----------*/ + + /*----------/分å‘è½åœ°é¡µ----------*/ + .passwords .template-common{padding: 0;} + .template-common{padding: 0;} + .template-common .form-control{height: 34px;} + .template-common hr{display: block;} + .template-common .t-icon{width: 2.5rem; height: 2.5rem; background-color: #fff; box-shadow: 0 0 10px rgba(0,0,0,.1); border-radius: 25px; margin: 0 auto;} + /* + .template-common .t-icon{width: 1.8rem; height: 1.8rem; padding: .3rem; background-color: #a45dec21e0787f8b; box-shadow: 0 0 10px rgba(0,0,0,.1); border-radius: 20px; margin: 0 auto;} + */ + .template-common .t-icon img{border-radius: 15px; width: 110px; height: 110px;} + + .template-common .t-name .tit{text-align: center; font-size: .4rem; font-weight: 600; margin-top: .3rem; margin-bottom: 8px;} + .template-common .t-name .name-info{font-size: .28rem;} + .template-common .t-name .name-info span{color: #999;} + .template-common .t-name .name-info span:last-of-type{display: block;} + .template-common .t-apply{color: #999; font-size: .24rem;} + .template-common .t-code{color: #999; font-size: .24rem; margin-top: 25px; width: 200px;} + .template-common .t-code img{width: 130px; height: 130px;} + .template-common .t-introduce .tit{font-size: .3rem; font-weight: 600; margin-bottom: 5px;} + .template-common .t-introduce p{font-size: .24rem;} + .template-common .t-contact{margin-top: .4rem !important;} + .template-common .t-contact .tit{font-size: .3rem; font-weight: 600; margin-bottom: 5px;} + .template-common .t-contact p{font-size: .24rem;} + .template-common .t-contact dl{font-size: .24rem;} + + .template-common .template-btn{padding: 0 50px; height: 40px; line-height: 38px; border-radius: 20px; text-align: center; font-size: .32rem; margin-top: .4rem; margin-bottom: .2rem;} + .template-common .template-btn span:last-of-type{line-height: .8rem;} + .template-common .decoding{padding: 0; height: 40px; line-height: 40px; border-radius: 20px; text-align: center; font-size: .32rem; margin-top: .4rem; margin-bottom: .2rem; width: 3.6rem;} + .template-common .template-btn .iconfont{font-size: 32px;} + + .passwords+.template-footer{margin-top: 30px;} + .template-footer{margin-top: 15px;} + .template-footer .methods-tutorial-full{position: fixed; width: 100%; left: 0; bottom: 0;} + .template-footer .methods-tutorial-full a.fl{height: 30px; line-height: 30px; font-size: .24rem;} + .template-footer .methods-tutorial-full a.fr{margin-top: 4px;} + + .template-footer .t-footer{margin-top: 0; margin-bottom: 40px; padding-bottom: .2rem; font-size: .24rem;} + + .template-pwd{width: auto !important; margin: .4rem .7rem 0; background-color: #fff !important; box-shadow: 0 0 10px rgba(0,0,0,.2); padding: .4rem .3rem !important; height: auto !important;} + .template-pwd .form-group label{color: #666; font-size: .24rem;} + .template-pwd .form-control{margin-top: 10px;} + + /*应用截图*/ + .template-common .app-screen .tit{font-size: .3rem; font-weight: 600; margin-bottom: 5px;} + .template-common .app-screen .s-responsive{overflow: hidden; height: 350px; width: 100%; overflow-x: auto; /*-webkit-overflow-scrolling: touch;*/} + .template-common .app-screen ul li{float: left; margin-right: 10px;} + .template-common .app-screen ul li img{max-width: 600px; width: auto; height: auto; max-height: 350px;} + + + /*模æ¿1*/ + .template-1 .t-bg-1{background: #157df1 url("../images/t-04.png") repeat-x center bottom; height: 1.4rem;} + .template-1 .content{margin-top: 0; padding: 0;} + .template-1 .content .c-left{background-image: none; width: 100%; height: auto; float: none; padding-top: .4rem;} + .template-1.passwords .content .c-left{padding-top: 25px;} + .template-1 .template-common .t-name .tit{margin-bottom: 0; margin-top: 15px;} + /*.template-1 .template-common .t-icon{width: 3.2rem; height: 3.2rem; background-color: #fff; box-shadow: 0 0 10px rgba(0,0,0,.1); border-radius: 25px; margin: 0 auto;}*/ + /*设计稿 å•独定义APP图标大å°*/ + .template-1 .template-common .t-icon{width: 1.8rem; height: 1.8rem; background-color: #fff; box-shadow: 0 0 10px rgba(0,0,0,.1); border-radius: 20px; margin: 0 auto;} + .template-1 .template-common .t-icon img{width: 60px; height: 60px;} + /*设计稿 å•独定义APP图标大å°*/ + + .template-1 .content .c-right{float: none; width: 100%; margin-left: 0 !important; padding-top: .5rem; border-top: 1px solid transparent; margin-top: 0; padding-top: 0;} + .template-1 .content .c-right .template-common{padding: 0;} + + .template-1 .template-common .t-name .name-info{text-align: center; margin-top: 5px;} + .template-1 .template-common .t-name .name-info span{color: #999;} + .template-1 .template-common .template-btn{margin-top: 20px; padding: 0 36px; margin-bottom: 10px;} + .template-1 .content .c-right .t-introduce{margin-top: 0; margin-bottom: 20px;} + .template-1 .content .c-right .t-introduce p{margin-top: 0;} + .template-1 .content .c-right .t-contact{margin-bottom: 20px; margin-top: 0;} + .template-1 .template-common .t-code{margin-top: 25px;} + .template-1 .template-pwd{margin-top: .4rem;} + .template-1.passwords+.template-footer{margin-top: 40px;} + .template-1+.template-footer{margin-top: 40px;} + + .template-1 .template-common .app-screen .s-responsive{width: 100%;} + /*/模æ¿1*/ + + /*模æ¿2*/ + .template-2 .content{margin-top: -80px;} + /*/模æ¿2*/ + + /*模æ¿3*/ + .template-3 .t-bg-3{background: url("../images/f57fbed0feda5a33.jpg") center; height: .7rem; background-size: cover;} + .template-3 .content{margin-top: 20px;} + .template-3 .template-common .t-icon{width: 100px; height: 100px; border-radius: 50%;} + .template-3 .template-common .t-icon img{width: 65px; height: 65px;} + .template-3 .template-common .t-name .tit{margin-top: 10px;} + + .template-3.passwords+.template-footer{margin-top: 40px;} + /*/模æ¿3*/ + + /*模æ¿4*/ + .template-4 .t-bg-4{background: none; height: auto;} + .template-4 .t-bg-4>.container{padding: 0;} + .template-4 .t-left{float: none; margin: 0; width: 100%; padding-top: 55px; background: url("../images/d9ee8741f22ce1f3.png") no-repeat center; height: 3.7rem; background-size: cover;} + .template-4 .t-right{float: none; margin: 25px auto 0; width: 100%;} + /*.template-4 .t-right{float: none; margin: 40px auto 0; width: 100%;}*/ + .template-4 .content4 .template-common .t-icon{margin-left: -3px;} + .template-4 .content4 .template-common .t-icon img{width: 70px; height: 70px;} + .template-4 .content4 .template-common .t-name .tit{font-weight: normal; margin-top: 10px; font-size: .32rem;} + + .template-4 .t-right .template-common .t-name .name-info span{color: #999; display: inline-block; line-height: 20px;} + .template-4 .t-right .template-common .t-name .name-info span:last-of-type{display: block;} + + .template-4 .content>.template-common{padding: 0;} + .template-4 .template-common .template-btn{margin-bottom: 5px;} + .template-4 .template-common .decoding{width: 3.6rem; padding: 0; margin-top: .4rem;} + .template-4 .template-common .template-pwd{margin: 0 .7rem;} + + .template-4.passwords+.template-footer{margin-top: 55px;} + .template-4+.template-footer{margin-top: 15px;} + + .template-4 .content>.template-common .app-screen{width: 100%;} + /*/模æ¿4*/ + + /*模æ¿5*/ + .template-5 .left-bg{position: absolute; left: 0; top: 0; background: url("../images/t11.png") no-repeat left top; width: 1.1rem; height: 3.93rem; background-size: cover;} + .template-5 .right-bg{position: absolute; right: 0; top: 0; background: url("../images/t12.png") no-repeat right top; width: 1.1rem; height: 3.93rem; background-size: cover;} + + .template-5 .content{padding-top: 25px;} + .template-5.passwords .template-common{padding: 0 .7rem;} + .template-5 .template-common .t-icon{border-radius: 25px; margin-left: auto; margin-right: auto;} + .template-5 .template-common .t-name-wrap{width: auto; margin-left: 0;} + .template-5 .template-common .t-name{margin-top: 0;} + .template-5 .template-common .t-name .tit{margin-bottom: 10px;} + .template-5 .template-common .t-name .name-info{text-align: center; line-height: 20px;} + .template-5 .template-common .t-name-wrap .template-btn{padding: 0 38px; margin: 20px auto 10px;} + .template-5 .template-common .t-apply{padding-left: 0; text-align: center;} + .template-5 .template-common hr{margin-top: 25px;} + .template-5 .template-common .t-introduce .tit{margin-top: 25px;} + .template-5 .template-common .t-contact{margin-top: .4rem;} + .template-5.passwords+.template-footer{margin-top: 30px;} + .template-5+.template-footer{margin-top: 15px;} + + .template-5 .template-pwd{margin-top: 15px;} + .template-5 .template-pwd .decoding{width: 3.6rem; margin-top: 0; margin-bottom: 25px;} + + .template-5 .template-common{padding: 0;} + /*/模æ¿5*/ + + /*模æ¿6*/ + .template-6 .t-bg-6{background-color: #f4f4f4; height: auto; line-height: normal; padding: 10px 0;} + .template-6 .t-top .tit{font-size: .4rem; color: #333; float: none; text-align: center;} + .template-6 .t-top .name-info{font-size: .28rem; background-color:#a54adea061bafe6f;color: #999; float: none; text-align: center; margin-top: 3px;} + .template-6 .t-top .name-info span{margin-left: 10px;} + .template-6 .t-top .name-info span:last-of-type{display: block;} + + .template-6 .content{margin-top: 25px;} + .template-6 .template-common .template-btn{margin-bottom: 15px;} + .template-6 .template-common .show-hr{display: none;} + .template-6 .template-common .t-code{margin-top: 25px;} + /*/模æ¿6*/ + + /*å¯†ç æ˜¾ç¤ºæŽ§åˆ¶*/ + .passwords .pc-pwd{display: none !important;} + .passwords .phone-pwd{display: none;} + /*----------/分å‘è½åœ°é¡µ----------*/ + .xuanfutishi span { + float: left; + padding-left: 15px; + } + + .xuanfutishi img { + float: right; + height: 15px; + margin: 12px 15px 0 0; + width: 15px; + } + + .appicon { + border: 1px solid #ddd; + border-radius: 24px; + height: 120px; + width: 120px; + } + + .appicon2 { + border: 1px solid #fff; + border-radius: 24px; + height: 140px; + width: 140px; + } + + #codeico { + background-color: #efefef; + border: 2px solid #fff; + border-radius: 10px; + margin: 77px; + position: absolute; + z-index: 999; + } + + .one-key-report { + background-color: #32b2a7; + color: #fff; + margin-top: -5px; + padding: 5px 10px; + } + + .one-key-report-dialog { + background-color: #fff; + border-radius: 10px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); + left: 50%; + margin-left: -225px; + margin-top: -275px; + padding: 20px; + position: fixed; + top: 50%; + width: 450px; + z-index: 99999; + } + + .one-key-report-dialog .dialog-close { + position: absolute; + right: 10px; + top: 10px; + } + + .one-key-report-dialog .dialog-close i.icon-close { + cursor: pointer; + font-size: 18px; + font-weight: 700; + } + + .one-key-report-dialog .dialog-close i.icon-close:hover { + color: #333; + } + + .one-key-report-dialog .dialog-close .icon-return { + color: #32b2a7; + display: none; + } + + .one-key-report-dialog .custom-checkbox { + cursor: pointer; + display: inline-block; + line-height: 24px; + margin-right: 40px; + padding: 2px 2px 2px 25px; + position: relative; + text-align: left; + } + + .one-key-report-dialog .custom-checkbox:last-child { + margin-right: 0; + } + + .one-key-report-dialog .custom-checkbox::after, .one-key-report-dialog .custom-checkbox::before { + content: " "; + display: block; + position: absolute; + } + + .one-key-report-dialog .custom-checkbox::after { + background-color: #1989fa; + border-radius: 10px; + display: none; + height: 10px; + left: 1px; + top: 7px; + width: 10px; + } + + .one-key-report-dialog .custom-checkbox::before { + background-color: #fff; + border: 1px solid #1989fa; + border-radius: 12px; + height: 12px; + left: 0; + top: 6px; + width: 12px; + } + + .one-key-report-dialog .custom-checkbox.active::after { + display: block; + } + + .one-key-report-dialog .content-row { + display: table; + padding: 10px 10px 5px; + position: relative; + width: 100%; + } + + .one-key-report-dialog .content-row input, .one-key-report-dialog .content-row label { + display: inline-block; + float: left; + } + + .one-key-report-dialog .content-row label { + font-size: 18px; + line-height: 34px; + margin-right: 30px; + } + + .one-key-report-dialog .content-row input { + border: 1px solid #a9b1b3; + border-radius: 5px; + height: 34px; + outline: 0 none; + padding: 5px 10px; + width: 240px; + } + + .one-key-report-dialog .content-row .checkbox-list { + clear: both; + padding: 5px 0; + text-align: left; + width: 100%; + } + + .one-key-report-dialog .content-row textarea { + border: 1px solid #a9b1b3; + border-radius: 10px; + color: #a9b1b3; + font-size: 16px; + height: 200px; + outline: 0 none; + padding: 10px; + resize: none; + width: 100%; + } + + .one-key-report-dialog .content-row .btn-report { + background-color: #32b2a7; + border-radius: 15px; + color: #fff; + float: right; + margin-top: -5px; + padding: 5px 10px; + } + + .one-key-report-dialog .report-feedback, .one-key-report-dialog .report-form { + height: 100%; + position: relative; + width: 100%; + } + + .one-key-report-dialog .report-sending { + background-color: rgba(255, 255, 255, 0.5); + color: #000; + cursor: default; + display: none; + font-size: 20px; + height: 100%; + left: 0; + line-height: 450px; + position: absolute; + text-align: center; + top: 0; + width: 100%; + z-index: 100; + } + + .one-key-report-dialog .report-form { + display: block; + } + + .one-key-report-dialog .report-feedback { + cursor: default; + display: none; + } + + .one-key-report-dialog .report-feedback .feedback-thanks { + background-color: #efefef; + border-radius: 20px; + height: 160px; + margin: 50px auto 20px; + width: 160px; + } + + .one-key-report-dialog .report-feedback .feedback-thanks .brace-content { + color: #000; + margin: 0 auto; + padding-top: 30px; + text-align: center; + width: 110px; + } + + .one-key-report-dialog .report-feedback .feedback-thanks .thanks { + color: #000; + cursor: default; + font-family: "Roboto Slab", "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif; + font-size: 16px; + font-weight: 700; + letter-spacing: 0.8px; + margin: 15px 0 0; + min-height: 22px; + text-align: center; + } + + .one-key-report-dialog .report-feedback .feedback-thanks .face, .one-key-report-dialog .report-feedback .feedback-thanks .icon-brace-left, .one-key-report-dialog .report-feedback .feedback-thanks .icon-brace-right { + display: inline-block; + vertical-align: middle; + } + + .one-key-report-dialog .report-feedback .feedback-thanks .icon-brace-left, .one-key-report-dialog .report-feedback .feedback-thanks .icon-brace-right { + font-size: 80px; + } + + .one-key-report-dialog .report-feedback .feedback-thanks .face .icon-comma-eye { + font-size: 22px; + margin: 0 4px; + } + + .one-key-report-dialog .report-feedback .feedback-thanks .face .icon-comma-eye.right { + display: inline-block; + margin-left: 16px; + transform: scaleY(0.5); + } + + .one-key-report-dialog .report-feedback .feedback-thanks .face .icon-mouth { + display: block; + margin-top: 15px; + transform: rotateZ(-19deg) translateX(2px); + } + + .one-key-report-dialog .report-feedback .feedback-message { + color: #1989fa; + font-size: 30px; + text-align: center; + } + + .one-key-report-dialog .report-feedback .feedback-content { + color: #858585; + font-size: 18px; + margin-top: 40px; + } + + .one-key-report-dialog .report-error { + color: red; + cursor: default; + line-height: 34px; + padding: 0 10px; + } + + .one-key-report-dialog .report-error > div { + display: none; + } + + .ad_section { + position: fixed; + bottom: 0; + margin-bottom: 0; + left: 50%; + margin-left: -365px; + } + + @media (max-width: 767px) { + .ad_section { + position: fixed; + bottom: 0; + left: 0; + margin: auto; + } + } + + .floadAd { + position: absolute; + z-index: 999900; + display: none; + } + + .floadAd .item { + display: block; + } + + .floadAd .item img { + vertical-align: bottom; + } +/*safari打开æç¤º*/ +.click_opacity{ width:100%; height:100%; background:#000; opacity:0.6; position:fixed; z-index:10000; top:0px;} +.to_btn{ position:fixed; top:10px; right:10px; text-align:right; z-index:10001; font-family:"微软雅黑";} +.to_btn span{ display:block;} +.to_btn img{ width:20%; height:auto; display:inline-block;} +.to_btn .span1{ font-size:1.6rem; color:#fff; margin-top:5px;} +.to_btn{ color:#fff;} +.to_btn .span2{ display:inline-block; line-height:36px; width:80%; margin-bottom:12px; text-align:left; font-size:16px;} +.to_btn .span2 em{ display:inline-block; width:16px; height:16px; background:#009dd9; color:#fff; font-size:12px; text-align:center; line-height:16px; border:1px solid #fff; border-radius:50%; margin-right:3px;} +.to_btn .span2 img{ display:inline-block; width:30px; height:30px; margin:0px 5px;} +.to_btn span{ display:block; float:right;} +.to_btn .android_open img{ display:inline-block; width:150px; height:34px;} diff --git a/tools/downloadWeb2/css/umi.css b/tools/downloadWeb2/css/umi.css new file mode 100644 index 0000000..e24607d --- /dev/null +++ b/tools/downloadWeb2/css/umi.css @@ -0,0 +1,3 @@ +a,body,br,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,hr,img,input,li,ol,p,table,td,textarea,th,tr,ul{padding:0;margin:0;font-family:Arial,"Microsoft YaHei","宋体"}li,ol,ul{list-style:none}a{display:block}img{border:0;display:block}.clearfloat{zoom:1}.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}#root,body,html{height:100%}.border{border:1px solid #eaeaea;border-radius:0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border{position:relative;border:none}html:not([data-scale]) .border:before{content:"";position:absolute;left:0;top:0;width:200%;height:200%;border:1px solid #eaeaea;border-radius:0;transform-origin:0 0;transform:scale(.5);box-sizing:border-box;pointer-events:none}}.border-left{border-left:1px solid #eaeaea}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-left{border-left:none}html:not([data-scale]) .border-left:before{content:"";position:absolute;background-color:#eaeaea;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:1px;height:100%;transform-origin:100% 50%;transform:scaleX(.5)}}@media (-webkit-min-device-pixel-ratio:2) and (-webkit-min-device-pixel-ratio:3),(min-resolution:2dppx) and (min-resolution:3dppx){html:not([data-scale]) .border-left:before{transform:scaleX(.33)}}.border-right{border-right:1px solid #eaeaea}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-right{border-right:none}html:not([data-scale]) .border-right:after{content:"";position:absolute;background-color:#eaeaea;display:block;z-index:1;top:0;right:0;bottom:auto;left:auto;width:1px;height:100%;background:#eaeaea;transform-origin:100% 50%;transform:scaleX(.5)}}@media (-webkit-min-device-pixel-ratio:2) and (-webkit-min-device-pixel-ratio:3),(min-resolution:2dppx) and (min-resolution:3dppx){html:not([data-scale]) .border-right:after{transform:scaleX(.33)}}.border-top{border-top:1px solid #eaeaea}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-top{border-top:none}html:not([data-scale]) .border-top:before{content:"";position:absolute;background-color:#eaeaea;display:block;z-index:1;top:0;right:auto;bottom:auto;left:0;width:100%;height:1px;transform-origin:50% 50%;transform:scaleY(.5)}}@media (-webkit-min-device-pixel-ratio:2) and (-webkit-min-device-pixel-ratio:3),(min-resolution:2dppx) and (min-resolution:3dppx){html:not([data-scale]) .border-top:before{transform:scaleY(.33)}}.border-bottom{border-bottom:1px solid #eaeaea}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){html:not([data-scale]) .border-bottom{border-bottom:none}html:not([data-scale]) .border-bottom:after{content:"";position:absolute;background-color:#eaeaea;display:block;z-index:1;top:auto;right:auto;bottom:0;left:0;width:100%;height:1px;transform-origin:50% 100%;transform:scaleY(.5)}}@media (-webkit-min-device-pixel-ratio:2) and (-webkit-min-device-pixel-ratio:3),(min-resolution:2dppx) and (min-resolution:3dppx){html:not([data-scale]) .border-bottom:after{transform:scaleY(.33)}}.pa{position:absolute}.pr{position:relative}.pf{position:fixed}.fl{float:left}.fr{float:right}.tc{text-align:center}.tl{text-align:left}.tr{text-align:right}.df{display:flex}.di{display:inline}.db{display:block}.ib{display:inline-block}.vm{vertical-align:middle}.vb{vertical-align:bottom}.vt{vertical-align:top}.cb{clear:both}.cl{clear:left}.cr{clear:right}.fb{font-weight:700}.fw500{font-weight:500}.for-bold .fw500{font-weight:700}.text-overflow{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.space-between{justify-content:space-between}.space-around{justify-content:space-around}.flexbox{display:flex}.flex1{flex:1 1}.flex2{flex:2 1}.flex3{flex:2 1}.f0{font-size:0}.half-w{width:50%}.half-h{height:50%}.quarter-w{width:25%}.quarter-h{height:25%}.w{width:100%}.wp30{width:30%}.h{height:100%}.align-items{align-items:center}.board-crmi{padding-bottom:2rem}.one-third{width:33.3%}.p0{padding:0}.pl0{padding-left:0}.pr0{padding-right:0}.pt0{padding-top:0}.pb0{padding-bottom:0}.m0{margin:0}.mt0{margin-top:0}.ml0{margin-left:0}.mb0{margin-bottom:0}.mr0{margin-right:0}.p5{padding:5px}.pl5{padding-left:5px}.pr5{padding-right:5px}.pt5{padding-top:5px}.pb5{padding-bottom:5px}.m5{margin:5px}.mt5{margin-top:5px}.ml5{margin-left:5px}.mb5{margin-bottom:5px}.mr5{margin-right:5px}.p10{padding:10px}.pl10{padding-left:10px}.pr10{padding-right:10px}.pt10{padding-top:10px}.pb10{padding-bottom:10px}.m10{margin:10px}.mt10{margin-top:10px}.ml10{margin-left:10px}.mb10{margin-bottom:10px}.mr10{margin-right:10px}.p15{padding:15px}.pl15{padding-left:15px}.pr15{padding-right:15px}.pt15{padding-top:15px}.pb15{padding-bottom:15px}.m15{margin:15px}.mt15{margin-top:15px}.ml15{margin-left:15px}.mb15{margin-bottom:15px}.mr15{margin-right:15px}.p20{padding:20px}.pl20{padding-left:20px}.pr20{padding-right:20px}.pt20{padding-top:20px}.pb20{padding-bottom:20px}.m20{margin:20px}.mt20{margin-top:20px}.ml20{margin-left:20px}.mb20{margin-bottom:20px}.mr20{margin-right:20px}.p25{padding:25px}.pl25{padding-left:25px}.pr25{padding-right:25px}.pt25{padding-top:25px}.pb25{padding-bottom:25px}.m25{margin:25px}.mt25{margin-top:25px}.ml25{margin-left:25px}.mb25{margin-bottom:25px}.mr25{margin-right:25px}.p30{padding:30px}.pl30{padding-left:30px}.pr30{padding-right:30px}.pt30{padding-top:30px}.pb30{padding-bottom:30px}.m30{margin:30px}.mt30{margin-top:30px}.ml30{margin-left:30px}.mb30{margin-bottom:30px}.mr30{margin-right:30px}.p35{padding:35px}.pl35{padding-left:35px}.pr35{padding-right:35px}.pt35{padding-top:35px}.pb35{padding-bottom:35px}.m35{margin:35px}.mt35{margin-top:35px}.ml35{margin-left:35px}.mb35{margin-bottom:35px}.mr35{margin-right:35px}.p40{padding:40px}.pl40{padding-left:40px}.pr40{padding-right:40px}.pt40{padding-top:40px}.pb40{padding-bottom:40px}.m40{margin:40px}.mt40{margin-top:40px}.ml40{margin-left:40px}.mb40{margin-bottom:40px}.mr40{margin-right:40px}.f10{font-size:10px}.f11{font-size:11px}.f12{font-size:12px}.f13{font-size:13px}.f14{font-size:14px}.f15{font-size:15px}.f16{font-size:16px}.f17{font-size:17px}.f18{font-size:18px}.f19{font-size:19px}.f20{font-size:20px}.f21{font-size:21px}.f22{font-size:22px}.f23{font-size:23px}.f24{font-size:24px}.f25{font-size:25px}.f26{font-size:26px}.f27{font-size:27px}.f28{font-size:28px}.w50{width:50px}.h50{height:50px}.w100{width:100px}.h100{height:100px}.w150{width:150px}.h150{height:150px}.w200{width:200px}.h200{height:200px}.w250{width:250px}.h250{height:250px}.w300{width:300px}.h300{height:300px}.w350{width:350px}.h350{height:350px}.w400{width:400px}.h400{height:400px}[class*=ant-]::-ms-clear,[class*=ant-] input::-ms-clear,[class*=ant-] input::-ms-reveal,[class^=ant-]::-ms-clear,[class^=ant-] input::-ms-clear,[class^=ant-] input::-ms-reveal{display:none}body,html{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}body{color:rgba(0,0,0,.85);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-variant:tabular-nums;line-height:1.5715;background-color:#fff;font-feature-settings:"tnum","tnum"}[tabindex="-1"]:focus{outline:none!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;color:rgba(0,0,0,.85);font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=number],input[type=password],input[type=text],textarea{-webkit-appearance:none}dl,ol,ul{margin-top:0;margin-bottom:1em}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}a{color:#1890ff;cursor:pointer;transition:color .3s}a:hover{color:#40a9ff}a:active{color:#096dd9}a:active,a:hover{text-decoration:none;outline:0}a:focus{text-decoration:none;outline:0}a[disabled]{color:rgba(0,0,0,.25);cursor:not-allowed}code,kbd,pre,samp{font-size:1em;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle}[role=button],a,area,button,input:not([type=range]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;color:rgba(0,0,0,.45);text-align:left;caption-side:bottom}button,input,optgroup,select,textarea{color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;margin-bottom:.5em;font-size:1.5em;line-height:inherit}[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}::selection{color:#fff;background:#1890ff}.clearfix:before{display:table;content:""}.clearfix:after{display:table;clear:both;content:""}.anticon{display:inline-block;color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizelegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.anticon>*{line-height:1}.anticon svg{display:inline-block}.anticon:before{display:none}.anticon .anticon-icon{display:block}.anticon>.anticon{line-height:0;vertical-align:0}.anticon[tabindex]{cursor:pointer}.anticon-spin,.anticon-spin:before{display:inline-block;animation:loadingCircle 1s linear infinite}.ant-fade-appear,.ant-fade-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-fade-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-fade-appear.ant-fade-appear-active,.ant-fade-enter.ant-fade-enter-active{animation-name:antFadeIn;animation-play-state:running}.ant-fade-leave.ant-fade-leave-active{animation-name:antFadeOut;animation-play-state:running;pointer-events:none}.ant-fade-appear,.ant-fade-enter{opacity:0;animation-timing-function:linear}.ant-fade-leave{animation-timing-function:linear}@keyframes antFadeIn{0%{opacity:0}to{opacity:1}}@keyframes antFadeOut{0%{opacity:1}to{opacity:0}}.ant-move-up-appear,.ant-move-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-up-appear.ant-move-up-appear-active,.ant-move-up-enter.ant-move-up-enter-active{animation-name:antMoveUpIn;animation-play-state:running}.ant-move-up-leave.ant-move-up-leave-active{animation-name:antMoveUpOut;animation-play-state:running;pointer-events:none}.ant-move-up-appear,.ant-move-up-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-up-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-down-appear,.ant-move-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-down-appear.ant-move-down-appear-active,.ant-move-down-enter.ant-move-down-enter-active{animation-name:antMoveDownIn;animation-play-state:running}.ant-move-down-leave.ant-move-down-leave-active{animation-name:antMoveDownOut;animation-play-state:running;pointer-events:none}.ant-move-down-appear,.ant-move-down-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-down-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-left-appear,.ant-move-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-left-appear.ant-move-left-appear-active,.ant-move-left-enter.ant-move-left-enter-active{animation-name:antMoveLeftIn;animation-play-state:running}.ant-move-left-leave.ant-move-left-leave-active{animation-name:antMoveLeftOut;animation-play-state:running;pointer-events:none}.ant-move-left-appear,.ant-move-left-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-left-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-right-appear,.ant-move-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-right-appear.ant-move-right-appear-active,.ant-move-right-enter.ant-move-right-enter-active{animation-name:antMoveRightIn;animation-play-state:running}.ant-move-right-leave.ant-move-right-leave-active{animation-name:antMoveRightOut;animation-play-state:running;pointer-events:none}.ant-move-right-appear,.ant-move-right-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-right-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}@keyframes antMoveDownIn{0%{transform:translateY(100%);transform-origin:0 0;opacity:0}to{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes antMoveDownOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}to{transform:translateY(100%);transform-origin:0 0;opacity:0}}@keyframes antMoveLeftIn{0%{transform:translateX(-100%);transform-origin:0 0;opacity:0}to{transform:translateX(0);transform-origin:0 0;opacity:1}}@keyframes antMoveLeftOut{0%{transform:translateX(0);transform-origin:0 0;opacity:1}to{transform:translateX(-100%);transform-origin:0 0;opacity:0}}@keyframes antMoveRightIn{0%{transform:translateX(100%);transform-origin:0 0;opacity:0}to{transform:translateX(0);transform-origin:0 0;opacity:1}}@keyframes antMoveRightOut{0%{transform:translateX(0);transform-origin:0 0;opacity:1}to{transform:translateX(100%);transform-origin:0 0;opacity:0}}@keyframes antMoveUpIn{0%{transform:translateY(-100%);transform-origin:0 0;opacity:0}to{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes antMoveUpOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}to{transform:translateY(-100%);transform-origin:0 0;opacity:0}}@keyframes loadingCircle{to{transform:rotate(1turn)}}[ant-click-animating-without-extra-node=true],[ant-click-animating=true]{position:relative}html{--antd-wave-shadow-color:#1890ff;--scroll-bar:0}.ant-click-animating-node,[ant-click-animating-without-extra-node=true]:after{position:absolute;top:0;right:0;bottom:0;left:0;display:block;border-radius:inherit;box-shadow:0 0 0 0 #1890ff;box-shadow:0 0 0 0 var(--antd-wave-shadow-color);opacity:.2;animation:fadeEffect 2s cubic-bezier(.08,.82,.17,1),waveEffect .4s cubic-bezier(.08,.82,.17,1);animation-fill-mode:forwards;content:"";pointer-events:none}@keyframes waveEffect{to{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@keyframes fadeEffect{to{opacity:0}}.ant-slide-up-appear,.ant-slide-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-up-appear.ant-slide-up-appear-active,.ant-slide-up-enter.ant-slide-up-enter-active{animation-name:antSlideUpIn;animation-play-state:running}.ant-slide-up-leave.ant-slide-up-leave-active{animation-name:antSlideUpOut;animation-play-state:running;pointer-events:none}.ant-slide-up-appear,.ant-slide-up-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-up-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-down-appear,.ant-slide-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-down-appear.ant-slide-down-appear-active,.ant-slide-down-enter.ant-slide-down-enter-active{animation-name:antSlideDownIn;animation-play-state:running}.ant-slide-down-leave.ant-slide-down-leave-active{animation-name:antSlideDownOut;animation-play-state:running;pointer-events:none}.ant-slide-down-appear,.ant-slide-down-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-left-appear,.ant-slide-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-left-appear.ant-slide-left-appear-active,.ant-slide-left-enter.ant-slide-left-enter-active{animation-name:antSlideLeftIn;animation-play-state:running}.ant-slide-left-leave.ant-slide-left-leave-active{animation-name:antSlideLeftOut;animation-play-state:running;pointer-events:none}.ant-slide-left-appear,.ant-slide-left-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-left-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-right-appear,.ant-slide-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-right-appear.ant-slide-right-appear-active,.ant-slide-right-enter.ant-slide-right-enter-active{animation-name:antSlideRightIn;animation-play-state:running}.ant-slide-right-leave.ant-slide-right-leave-active{animation-name:antSlideRightOut;animation-play-state:running;pointer-events:none}.ant-slide-right-appear,.ant-slide-right-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-right-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes antSlideUpIn{0%{transform:scaleY(.8);transform-origin:0 0;opacity:0}to{transform:scaleY(1);transform-origin:0 0;opacity:1}}@keyframes antSlideUpOut{0%{transform:scaleY(1);transform-origin:0 0;opacity:1}to{transform:scaleY(.8);transform-origin:0 0;opacity:0}}@keyframes antSlideDownIn{0%{transform:scaleY(.8);transform-origin:100% 100%;opacity:0}to{transform:scaleY(1);transform-origin:100% 100%;opacity:1}}@keyframes antSlideDownOut{0%{transform:scaleY(1);transform-origin:100% 100%;opacity:1}to{transform:scaleY(.8);transform-origin:100% 100%;opacity:0}}@keyframes antSlideLeftIn{0%{transform:scaleX(.8);transform-origin:0 0;opacity:0}to{transform:scaleX(1);transform-origin:0 0;opacity:1}}@keyframes antSlideLeftOut{0%{transform:scaleX(1);transform-origin:0 0;opacity:1}to{transform:scaleX(.8);transform-origin:0 0;opacity:0}}@keyframes antSlideRightIn{0%{transform:scaleX(.8);transform-origin:100% 0;opacity:0}to{transform:scaleX(1);transform-origin:100% 0;opacity:1}}@keyframes antSlideRightOut{0%{transform:scaleX(1);transform-origin:100% 0;opacity:1}to{transform:scaleX(.8);transform-origin:100% 0;opacity:0}}.ant-zoom-appear,.ant-zoom-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-appear.ant-zoom-appear-active,.ant-zoom-enter.ant-zoom-enter-active{animation-name:antZoomIn;animation-play-state:running}.ant-zoom-leave.ant-zoom-leave-active{animation-name:antZoomOut;animation-play-state:running;pointer-events:none}.ant-zoom-appear,.ant-zoom-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-appear-prepare,.ant-zoom-enter-prepare{transform:none}.ant-zoom-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-big-appear,.ant-zoom-big-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-appear.ant-zoom-big-appear-active,.ant-zoom-big-enter.ant-zoom-big-enter-active{animation-name:antZoomBigIn;animation-play-state:running}.ant-zoom-big-leave.ant-zoom-big-leave-active{animation-name:antZoomBigOut;animation-play-state:running;pointer-events:none}.ant-zoom-big-appear,.ant-zoom-big-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-big-appear-prepare,.ant-zoom-big-enter-prepare{transform:none}.ant-zoom-big-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-big-fast-appear,.ant-zoom-big-fast-enter{animation-duration:.1s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-fast-leave{animation-duration:.1s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-fast-appear.ant-zoom-big-fast-appear-active,.ant-zoom-big-fast-enter.ant-zoom-big-fast-enter-active{animation-name:antZoomBigIn;animation-play-state:running}.ant-zoom-big-fast-leave.ant-zoom-big-fast-leave-active{animation-name:antZoomBigOut;animation-play-state:running;pointer-events:none}.ant-zoom-big-fast-appear,.ant-zoom-big-fast-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-big-fast-appear-prepare,.ant-zoom-big-fast-enter-prepare{transform:none}.ant-zoom-big-fast-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-up-appear,.ant-zoom-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-up-appear.ant-zoom-up-appear-active,.ant-zoom-up-enter.ant-zoom-up-enter-active{animation-name:antZoomUpIn;animation-play-state:running}.ant-zoom-up-leave.ant-zoom-up-leave-active{animation-name:antZoomUpOut;animation-play-state:running;pointer-events:none}.ant-zoom-up-appear,.ant-zoom-up-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-up-appear-prepare,.ant-zoom-up-enter-prepare{transform:none}.ant-zoom-up-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-down-appear,.ant-zoom-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-down-appear.ant-zoom-down-appear-active,.ant-zoom-down-enter.ant-zoom-down-enter-active{animation-name:antZoomDownIn;animation-play-state:running}.ant-zoom-down-leave.ant-zoom-down-leave-active{animation-name:antZoomDownOut;animation-play-state:running;pointer-events:none}.ant-zoom-down-appear,.ant-zoom-down-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-down-appear-prepare,.ant-zoom-down-enter-prepare{transform:none}.ant-zoom-down-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-left-appear,.ant-zoom-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-left-appear.ant-zoom-left-appear-active,.ant-zoom-left-enter.ant-zoom-left-enter-active{animation-name:antZoomLeftIn;animation-play-state:running}.ant-zoom-left-leave.ant-zoom-left-leave-active{animation-name:antZoomLeftOut;animation-play-state:running;pointer-events:none}.ant-zoom-left-appear,.ant-zoom-left-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-left-appear-prepare,.ant-zoom-left-enter-prepare{transform:none}.ant-zoom-left-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-right-appear,.ant-zoom-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-right-appear.ant-zoom-right-appear-active,.ant-zoom-right-enter.ant-zoom-right-enter-active{animation-name:antZoomRightIn;animation-play-state:running}.ant-zoom-right-leave.ant-zoom-right-leave-active{animation-name:antZoomRightOut;animation-play-state:running;pointer-events:none}.ant-zoom-right-appear,.ant-zoom-right-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-right-appear-prepare,.ant-zoom-right-enter-prepare{transform:none}.ant-zoom-right-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}@keyframes antZoomIn{0%{transform:scale(.2);opacity:0}to{transform:scale(1);opacity:1}}@keyframes antZoomOut{0%{transform:scale(1)}to{transform:scale(.2);opacity:0}}@keyframes antZoomBigIn{0%{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@keyframes antZoomBigOut{0%{transform:scale(1)}to{transform:scale(.8);opacity:0}}@keyframes antZoomUpIn{0%{transform:scale(.8);transform-origin:50% 0;opacity:0}to{transform:scale(1);transform-origin:50% 0}}@keyframes antZoomUpOut{0%{transform:scale(1);transform-origin:50% 0}to{transform:scale(.8);transform-origin:50% 0;opacity:0}}@keyframes antZoomLeftIn{0%{transform:scale(.8);transform-origin:0 50%;opacity:0}to{transform:scale(1);transform-origin:0 50%}}@keyframes antZoomLeftOut{0%{transform:scale(1);transform-origin:0 50%}to{transform:scale(.8);transform-origin:0 50%;opacity:0}}@keyframes antZoomRightIn{0%{transform:scale(.8);transform-origin:100% 50%;opacity:0}to{transform:scale(1);transform-origin:100% 50%}}@keyframes antZoomRightOut{0%{transform:scale(1);transform-origin:100% 50%}to{transform:scale(.8);transform-origin:100% 50%;opacity:0}}@keyframes antZoomDownIn{0%{transform:scale(.8);transform-origin:50% 100%;opacity:0}to{transform:scale(1);transform-origin:50% 100%}}@keyframes antZoomDownOut{0%{transform:scale(1);transform-origin:50% 100%}to{transform:scale(.8);transform-origin:50% 100%;opacity:0}}.ant-motion-collapse-legacy{overflow:hidden}.ant-motion-collapse-legacy-active{transition:height .2s cubic-bezier(.645,.045,.355,1),opacity .2s cubic-bezier(.645,.045,.355,1)!important}.ant-motion-collapse{overflow:hidden;transition:height .2s cubic-bezier(.645,.045,.355,1),opacity .2s cubic-bezier(.645,.045,.355,1)!important}.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{animation-name:MessageMoveOut;animation-duration:.3s}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl{direction:rtl}.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}.ant-notification{box-sizing:border-box;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";position:fixed;z-index:1010;margin:0 24px 0 0}.ant-notification-close-icon{font-size:14px;cursor:pointer}.ant-notification-hook-holder{position:relative}.ant-notification-notice{position:relative;width:384px;max-width:calc(100vw - 48px);margin-bottom:16px;margin-left:auto;padding:16px 24px;overflow:hidden;line-height:1.5715;word-wrap:break-word;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05)}.ant-notification-bottom .ant-notification-notice,.ant-notification-top .ant-notification-notice{margin-right:auto;margin-left:auto}.ant-notification-bottomLeft .ant-notification-notice,.ant-notification-topLeft .ant-notification-notice{margin-right:auto;margin-left:0}.ant-notification-notice-message{margin-bottom:8px;color:rgba(0,0,0,.85);font-size:16px;line-height:24px}.ant-notification-notice-message-single-line-auto-margin{display:block;width:calc(264px - 100%);max-width:4px;background-color:transparent;pointer-events:none}.ant-notification-notice-message-single-line-auto-margin:before{display:block;content:""}.ant-notification-notice-description{font-size:14px}.ant-notification-notice-closable .ant-notification-notice-message{padding-right:24px}.ant-notification-notice-with-icon .ant-notification-notice-message{margin-bottom:4px;margin-left:48px;font-size:16px}.ant-notification-notice-with-icon .ant-notification-notice-description{margin-left:48px;font-size:14px}.ant-notification-notice-icon{position:absolute;margin-left:4px;font-size:24px;line-height:24px}.anticon.ant-notification-notice-icon-success{color:#52c41a}.anticon.ant-notification-notice-icon-info{color:#1890ff}.anticon.ant-notification-notice-icon-warning{color:#faad14}.anticon.ant-notification-notice-icon-error{color:#ff4d4f}.ant-notification-notice-close{position:absolute;top:16px;right:22px;color:rgba(0,0,0,.45);outline:none}.ant-notification-notice-close:hover{color:rgba(0,0,0,.67)}.ant-notification-notice-btn{float:right;margin-top:16px}.ant-notification .notification-fade-effect{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both}.ant-notification-fade-appear,.ant-notification-fade-enter{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both;opacity:0;animation-play-state:paused}.ant-notification-fade-leave{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both;animation-duration:.2s;animation-play-state:paused}.ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationFadeIn;animation-play-state:running}.ant-notification-fade-leave.ant-notification-fade-leave-active{animation-name:NotificationFadeOut;animation-play-state:running}@keyframes NotificationFadeIn{0%{left:384px;opacity:0}to{left:0;opacity:1}}@keyframes NotificationFadeOut{0%{max-height:150px;margin-bottom:16px;opacity:1}to{max-height:0;margin-bottom:0;padding-top:0;padding-bottom:0;opacity:0}}.ant-notification-rtl{direction:rtl}.ant-notification-rtl .ant-notification-notice-closable .ant-notification-notice-message{padding-right:0;padding-left:24px}.ant-notification-rtl .ant-notification-notice-with-icon .ant-notification-notice-message{margin-right:48px;margin-left:0}.ant-notification-rtl .ant-notification-notice-with-icon .ant-notification-notice-description{margin-right:48px;margin-left:0}.ant-notification-rtl .ant-notification-notice-icon{margin-right:4px;margin-left:0}.ant-notification-rtl .ant-notification-notice-close{right:auto;left:22px}.ant-notification-rtl .ant-notification-notice-btn{float:left}.ant-notification-bottom,.ant-notification-top{margin-right:0;margin-left:0}.ant-notification-top .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-top .ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationTopFadeIn}.ant-notification-bottom .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-bottom .ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationBottomFadeIn}.ant-notification-bottomLeft,.ant-notification-topLeft{margin-right:0;margin-left:24px}.ant-notification-bottomLeft .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-bottomLeft .ant-notification-fade-enter.ant-notification-fade-enter-active,.ant-notification-topLeft .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-topLeft .ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationLeftFadeIn}@keyframes NotificationTopFadeIn{0%{margin-top:-100%;opacity:0}to{margin-top:0;opacity:1}}@keyframes NotificationBottomFadeIn{0%{margin-bottom:-100%;opacity:0}to{margin-bottom:0;opacity:1}}@keyframes NotificationLeftFadeIn{0%{right:384px;opacity:0}to{right:0;opacity:1}} + +/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}.am-fade-appear,.am-fade-enter{opacity:0;animation-duration:.2s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.55,0,.55,.2);animation-play-state:paused}.am-fade-leave{animation-duration:.2s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.55,0,.55,.2);animation-play-state:paused}.am-fade-appear.am-fade-appear-active,.am-fade-enter.am-fade-enter-active{animation-name:amFadeIn;animation-play-state:running}.am-fade-leave.am-fade-leave-active{animation-name:amFadeOut;animation-play-state:running}@keyframes amFadeIn{0%{opacity:0}to{opacity:1}}@keyframes amFadeOut{0%{opacity:1}to{opacity:0}}.am-slide-up-appear,.am-slide-up-enter{transform:translateY(100%)}.am-slide-up-appear,.am-slide-up-enter,.am-slide-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.55,0,.55,.2);animation-play-state:paused}.am-slide-up-appear.am-slide-up-appear-active,.am-slide-up-enter.am-slide-up-enter-active{animation-name:amSlideUpIn;animation-play-state:running}.am-slide-up-leave.am-slide-up-leave-active{animation-name:amSlideUpOut;animation-play-state:running}@keyframes amSlideUpIn{0%{transform:translateY(100%)}to{transform:translate(0)}}@keyframes amSlideUpOut{0%{transform:translate(0)}to{transform:translateY(100%)}}.am.am-zoom-enter,.am.am-zoom-leave{display:block}.am-zoom-appear,.am-zoom-enter{opacity:0;animation-duration:.2s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.55,0,.55,.2);animation-timing-function:cubic-bezier(.18,.89,.32,1.28);animation-play-state:paused}.am-zoom-leave{animation-duration:.2s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.55,0,.55,.2);animation-timing-function:cubic-bezier(.6,-.3,.74,.05);animation-play-state:paused}.am-zoom-appear.am-zoom-appear-active,.am-zoom-enter.am-zoom-enter-active{animation-name:amZoomIn;animation-play-state:running}.am-zoom-leave.am-zoom-leave-active{animation-name:amZoomOut;animation-play-state:running}@keyframes amZoomIn{0%{opacity:0;transform-origin:50% 50%;transform:scale(0)}to{opacity:1;transform-origin:50% 50%;transform:scale(1)}}@keyframes amZoomOut{0%{opacity:1;transform-origin:50% 50%;transform:scale(1)}to{opacity:0;transform-origin:50% 50%;transform:scale(0)}}.am-slide-down-appear,.am-slide-down-enter{transform:translateY(-100%)}.am-slide-down-appear,.am-slide-down-enter,.am-slide-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.55,0,.55,.2);animation-play-state:paused}.am-slide-down-appear.am-slide-down-appear-active,.am-slide-down-enter.am-slide-down-enter-active{animation-name:amSlideDownIn;animation-play-state:running}.am-slide-down-leave.am-slide-down-leave-active{animation-name:amSlideDownOut;animation-play-state:running}@keyframes amSlideDownIn{0%{transform:translateY(-100%)}to{transform:translate(0)}}@keyframes amSlideDownOut{0%{transform:translate(0)}to{transform:translateY(-100%)}}*,:after,:before{-webkit-tap-highlight-color:rgba(0,0,0,0)}body{background-color:#f5f5f9;font-size:14px}[contenteditable]{-webkit-user-select:auto!important}:focus{outline:none}a{background:transparent;text-decoration:none;outline:none}.am-activity-indicator{display:flex;align-items:center;z-index:99}.am-activity-indicator-spinner{display:inline-block;width:20px;height:20px;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-2.125 -1.875 64 64'%3E%3Cpath fill='%23CCC' d='M29.875-1.875c-17.673 0-32 14.327-32 32s14.327 32 32 32 32-14.327 32-32-14.327-32-32-32zm0 60.7c-15.85 0-28.7-12.85-28.7-28.7s12.85-28.7 28.7-28.7 28.7 12.85 28.7 28.7-12.85 28.7-28.7 28.7z'/%3E%3Cpath fill='%23ccc' d='M61.858 30.34c.003-.102.008-.203.008-.305 0-11.43-5.996-21.452-15.01-27.113l-.013.026a1.629 1.629 0 00-.81-.22 1.646 1.646 0 00-.713 3.132c7.963 5.1 13.247 14.017 13.247 24.176 0 .147-.01.293-.01.44h.022c0 .01-.004.02-.004.03 0 .91.74 1.65 1.65 1.65s1.65-.74 1.65-1.65c0-.06-.012-.112-.018-.167z'/%3E%3C/svg%3E");background-position:50%;background-size:100%;background-repeat:no-repeat;animation:spinner-anime 1s linear infinite}.am-activity-indicator-tip{font-size:14px;margin-left:8px;color:#000;opacity:.4}.am-activity-indicator.am-activity-indicator-toast{position:fixed;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;text-align:center;z-index:1999}.am-activity-indicator.am-activity-indicator-toast .am-activity-indicator-spinner{margin:0}.am-activity-indicator.am-activity-indicator-toast .am-activity-indicator-toast{display:inline-block;position:relative;top:4px}.am-activity-indicator-content{display:flex;flex-direction:column;justify-content:center;align-items:center;padding:15px;border-radius:7px;background-clip:padding-box;color:#fff;background-color:rgba(58,58,58,.9);font-size:15px;line-height:20px}.am-activity-indicator-spinner-lg{width:32px;height:32px}@keyframes spinner-anime{to{transform:rotate(1turn)}} \ No newline at end of file diff --git a/tools/downloadWeb2/img/logo.png b/tools/downloadWeb2/img/logo.png new file mode 100644 index 0000000..5148e20 Binary files /dev/null and b/tools/downloadWeb2/img/logo.png differ diff --git a/tools/downloadWeb2/index.html b/tools/downloadWeb2/index.html new file mode 100644 index 0000000..c4fbeae --- /dev/null +++ b/tools/downloadWeb2/index.html @@ -0,0 +1,211 @@ + + + + + + + + + + + + 下载 + + + +
+
+
+
+ 下载客户端 +
+
+ 适应系统:HarmonyOS 2.0+ ,Android 5.0+ ,iOS 9.0+ +
+
+ +
+
+
+ +
+ ç«‹å³ä¸‹è½½ +
+
+
+
+ 游æˆå£°æ˜Ž +
+
+
+ - 游æˆä»…ä¾›å¨±ä¹ +
+ +
+
+
+
+
+
+
+ +
+
+ + + + + + \ No newline at end of file diff --git a/tools/downloadWeb2/js/jquery-1.9.1.min.js b/tools/downloadWeb2/js/jquery-1.9.1.min.js new file mode 100644 index 0000000..9760d9b --- /dev/null +++ b/tools/downloadWeb2/js/jquery-1.9.1.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Incaab3d7e0a465eadf. | jquery.org/license +//@ sourceMappingURL=jquery.min.map +*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="
t
",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; +return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="
",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) +}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("