@nice2dev/game-engine 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/dist/cjs/ai/BehaviorTree.js +1215 -0
  2. package/dist/cjs/ai/BehaviorTree.js.map +1 -0
  3. package/dist/cjs/ai/StateMachine.js +783 -0
  4. package/dist/cjs/ai/StateMachine.js.map +1 -0
  5. package/dist/cjs/editor/ShaderGraph.js +1616 -0
  6. package/dist/cjs/editor/ShaderGraph.js.map +1 -0
  7. package/dist/cjs/editor/TimelineEditor.js +819 -0
  8. package/dist/cjs/editor/TimelineEditor.js.map +1 -0
  9. package/dist/cjs/export/GodotExporter.js +1102 -0
  10. package/dist/cjs/export/GodotExporter.js.map +1 -0
  11. package/dist/cjs/export/PlatformExporter.js +236 -0
  12. package/dist/cjs/export/PlatformExporter.js.map +1 -0
  13. package/dist/cjs/export/ThreeJSExporter.js +1116 -0
  14. package/dist/cjs/export/ThreeJSExporter.js.map +1 -0
  15. package/dist/cjs/export/UnityExporter.js +1193 -0
  16. package/dist/cjs/export/UnityExporter.js.map +1 -0
  17. package/dist/cjs/export/WebExporter.js +1036 -0
  18. package/dist/cjs/export/WebExporter.js.map +1 -0
  19. package/dist/cjs/export/index.js +58 -0
  20. package/dist/cjs/export/index.js.map +1 -0
  21. package/dist/cjs/import/AsepriteImporter.js +761 -0
  22. package/dist/cjs/import/AsepriteImporter.js.map +1 -0
  23. package/dist/cjs/import/DragonBonesImporter.js +499 -0
  24. package/dist/cjs/import/DragonBonesImporter.js.map +1 -0
  25. package/dist/cjs/import/GameMakerImporter.js +559 -0
  26. package/dist/cjs/import/GameMakerImporter.js.map +1 -0
  27. package/dist/cjs/import/GodotSceneImporter.js +824 -0
  28. package/dist/cjs/import/GodotSceneImporter.js.map +1 -0
  29. package/dist/cjs/import/LDtkImporter.js +481 -0
  30. package/dist/cjs/import/LDtkImporter.js.map +1 -0
  31. package/dist/cjs/import/Live2DImporter.js +553 -0
  32. package/dist/cjs/import/Live2DImporter.js.map +1 -0
  33. package/dist/cjs/import/NdgFormat.js +499 -0
  34. package/dist/cjs/import/NdgFormat.js.map +1 -0
  35. package/dist/cjs/import/OgmoImporter.js +529 -0
  36. package/dist/cjs/import/OgmoImporter.js.map +1 -0
  37. package/dist/cjs/import/RPGMakerImporter.js +520 -0
  38. package/dist/cjs/import/RPGMakerImporter.js.map +1 -0
  39. package/dist/cjs/import/SceneImporter.js +449 -0
  40. package/dist/cjs/import/SceneImporter.js.map +1 -0
  41. package/dist/cjs/import/SpineImporter.js +583 -0
  42. package/dist/cjs/import/SpineImporter.js.map +1 -0
  43. package/dist/cjs/import/SpriterImporter.js +652 -0
  44. package/dist/cjs/import/SpriterImporter.js.map +1 -0
  45. package/dist/cjs/import/TiledMapImporter.js +859 -0
  46. package/dist/cjs/import/TiledMapImporter.js.map +1 -0
  47. package/dist/cjs/import/UnitySceneImporter.js +732 -0
  48. package/dist/cjs/import/UnitySceneImporter.js.map +1 -0
  49. package/dist/cjs/import/index.js +305 -0
  50. package/dist/cjs/import/index.js.map +1 -0
  51. package/dist/cjs/index.js +201 -0
  52. package/dist/cjs/index.js.map +1 -1
  53. package/dist/cjs/scripting/GraphToAST.js +567 -0
  54. package/dist/cjs/scripting/GraphToAST.js.map +1 -0
  55. package/dist/cjs/scripting/LanguageExporter.js +321 -0
  56. package/dist/cjs/scripting/LanguageExporter.js.map +1 -0
  57. package/dist/cjs/scripting/ScriptAST.js +67 -0
  58. package/dist/cjs/scripting/ScriptAST.js.map +1 -0
  59. package/dist/cjs/scripting/VisualScripting2.js +1140 -0
  60. package/dist/cjs/scripting/VisualScripting2.js.map +1 -0
  61. package/dist/cjs/scripting/exporters/CSharpExporter.js +503 -0
  62. package/dist/cjs/scripting/exporters/CSharpExporter.js.map +1 -0
  63. package/dist/cjs/scripting/exporters/GDScriptExporter.js +452 -0
  64. package/dist/cjs/scripting/exporters/GDScriptExporter.js.map +1 -0
  65. package/dist/cjs/scripting/exporters/LuaExporter.js +457 -0
  66. package/dist/cjs/scripting/exporters/LuaExporter.js.map +1 -0
  67. package/dist/cjs/scripting/exporters/PythonExporter.js +565 -0
  68. package/dist/cjs/scripting/exporters/PythonExporter.js.map +1 -0
  69. package/dist/cjs/scripting/exporters/RustExporter.js +525 -0
  70. package/dist/cjs/scripting/exporters/RustExporter.js.map +1 -0
  71. package/dist/cjs/scripting/exporters/TypeScriptExporter.js +570 -0
  72. package/dist/cjs/scripting/exporters/TypeScriptExporter.js.map +1 -0
  73. package/dist/cjs/systems/ParticleSystem2.js +1478 -0
  74. package/dist/cjs/systems/ParticleSystem2.js.map +1 -0
  75. package/dist/esm/ai/BehaviorTree.js +1186 -0
  76. package/dist/esm/ai/BehaviorTree.js.map +1 -0
  77. package/dist/esm/ai/StateMachine.js +767 -0
  78. package/dist/esm/ai/StateMachine.js.map +1 -0
  79. package/dist/esm/editor/ShaderGraph.js +1606 -0
  80. package/dist/esm/editor/ShaderGraph.js.map +1 -0
  81. package/dist/esm/editor/TimelineEditor.js +800 -0
  82. package/dist/esm/editor/TimelineEditor.js.map +1 -0
  83. package/dist/esm/export/GodotExporter.js +1100 -0
  84. package/dist/esm/export/GodotExporter.js.map +1 -0
  85. package/dist/esm/export/PlatformExporter.js +230 -0
  86. package/dist/esm/export/PlatformExporter.js.map +1 -0
  87. package/dist/esm/export/ThreeJSExporter.js +1114 -0
  88. package/dist/esm/export/ThreeJSExporter.js.map +1 -0
  89. package/dist/esm/export/UnityExporter.js +1191 -0
  90. package/dist/esm/export/UnityExporter.js.map +1 -0
  91. package/dist/esm/export/WebExporter.js +1033 -0
  92. package/dist/esm/export/WebExporter.js.map +1 -0
  93. package/dist/esm/export/index.js +44 -0
  94. package/dist/esm/export/index.js.map +1 -0
  95. package/dist/esm/import/AsepriteImporter.js +759 -0
  96. package/dist/esm/import/AsepriteImporter.js.map +1 -0
  97. package/dist/esm/import/DragonBonesImporter.js +496 -0
  98. package/dist/esm/import/DragonBonesImporter.js.map +1 -0
  99. package/dist/esm/import/GameMakerImporter.js +556 -0
  100. package/dist/esm/import/GameMakerImporter.js.map +1 -0
  101. package/dist/esm/import/GodotSceneImporter.js +822 -0
  102. package/dist/esm/import/GodotSceneImporter.js.map +1 -0
  103. package/dist/esm/import/LDtkImporter.js +479 -0
  104. package/dist/esm/import/LDtkImporter.js.map +1 -0
  105. package/dist/esm/import/Live2DImporter.js +550 -0
  106. package/dist/esm/import/Live2DImporter.js.map +1 -0
  107. package/dist/esm/import/NdgFormat.js +490 -0
  108. package/dist/esm/import/NdgFormat.js.map +1 -0
  109. package/dist/esm/import/OgmoImporter.js +526 -0
  110. package/dist/esm/import/OgmoImporter.js.map +1 -0
  111. package/dist/esm/import/RPGMakerImporter.js +517 -0
  112. package/dist/esm/import/RPGMakerImporter.js.map +1 -0
  113. package/dist/esm/import/SceneImporter.js +441 -0
  114. package/dist/esm/import/SceneImporter.js.map +1 -0
  115. package/dist/esm/import/SpineImporter.js +580 -0
  116. package/dist/esm/import/SpineImporter.js.map +1 -0
  117. package/dist/esm/import/SpriterImporter.js +649 -0
  118. package/dist/esm/import/SpriterImporter.js.map +1 -0
  119. package/dist/esm/import/TiledMapImporter.js +857 -0
  120. package/dist/esm/import/TiledMapImporter.js.map +1 -0
  121. package/dist/esm/import/UnitySceneImporter.js +730 -0
  122. package/dist/esm/import/UnitySceneImporter.js.map +1 -0
  123. package/dist/esm/import/index.js +279 -0
  124. package/dist/esm/import/index.js.map +1 -0
  125. package/dist/esm/index.js +36 -0
  126. package/dist/esm/index.js.map +1 -1
  127. package/dist/esm/scripting/GraphToAST.js +564 -0
  128. package/dist/esm/scripting/GraphToAST.js.map +1 -0
  129. package/dist/esm/scripting/LanguageExporter.js +311 -0
  130. package/dist/esm/scripting/LanguageExporter.js.map +1 -0
  131. package/dist/esm/scripting/ScriptAST.js +52 -0
  132. package/dist/esm/scripting/ScriptAST.js.map +1 -0
  133. package/dist/esm/scripting/VisualScripting2.js +1130 -0
  134. package/dist/esm/scripting/VisualScripting2.js.map +1 -0
  135. package/dist/esm/scripting/exporters/CSharpExporter.js +501 -0
  136. package/dist/esm/scripting/exporters/CSharpExporter.js.map +1 -0
  137. package/dist/esm/scripting/exporters/GDScriptExporter.js +450 -0
  138. package/dist/esm/scripting/exporters/GDScriptExporter.js.map +1 -0
  139. package/dist/esm/scripting/exporters/LuaExporter.js +455 -0
  140. package/dist/esm/scripting/exporters/LuaExporter.js.map +1 -0
  141. package/dist/esm/scripting/exporters/PythonExporter.js +563 -0
  142. package/dist/esm/scripting/exporters/PythonExporter.js.map +1 -0
  143. package/dist/esm/scripting/exporters/RustExporter.js +523 -0
  144. package/dist/esm/scripting/exporters/RustExporter.js.map +1 -0
  145. package/dist/esm/scripting/exporters/TypeScriptExporter.js +568 -0
  146. package/dist/esm/scripting/exporters/TypeScriptExporter.js.map +1 -0
  147. package/dist/esm/systems/ParticleSystem2.js +1471 -0
  148. package/dist/esm/systems/ParticleSystem2.js.map +1 -0
  149. package/dist/types/ai/BehaviorTree.d.ts +375 -0
  150. package/dist/types/ai/StateMachine.d.ts +296 -0
  151. package/dist/types/editor/ShaderGraph.d.ts +207 -0
  152. package/dist/types/editor/TimelineEditor.d.ts +393 -0
  153. package/dist/types/export/GodotExporter.d.ts +56 -0
  154. package/dist/types/export/PlatformExporter.d.ts +201 -0
  155. package/dist/types/export/ThreeJSExporter.d.ts +40 -0
  156. package/dist/types/export/UnityExporter.d.ts +69 -0
  157. package/dist/types/export/WebExporter.d.ts +58 -0
  158. package/dist/types/export/index.d.ts +19 -0
  159. package/dist/types/import/AsepriteImporter.d.ts +46 -0
  160. package/dist/types/import/DragonBonesImporter.d.ts +331 -0
  161. package/dist/types/import/GameMakerImporter.d.ts +375 -0
  162. package/dist/types/import/GodotSceneImporter.d.ts +34 -0
  163. package/dist/types/import/LDtkImporter.d.ts +177 -0
  164. package/dist/types/import/Live2DImporter.d.ts +237 -0
  165. package/dist/types/import/NdgFormat.d.ts +387 -0
  166. package/dist/types/import/OgmoImporter.d.ts +237 -0
  167. package/dist/types/import/RPGMakerImporter.d.ts +186 -0
  168. package/dist/types/import/SceneImporter.d.ts +276 -0
  169. package/dist/types/import/SpineImporter.d.ts +372 -0
  170. package/dist/types/import/SpriterImporter.d.ts +230 -0
  171. package/dist/types/import/TiledMapImporter.d.ts +57 -0
  172. package/dist/types/import/UnitySceneImporter.d.ts +87 -0
  173. package/dist/types/import/index.d.ts +59 -0
  174. package/dist/types/index.d.ts +29 -17
  175. package/dist/types/scripting/GraphToAST.d.ts +55 -0
  176. package/dist/types/scripting/LanguageExporter.d.ts +136 -0
  177. package/dist/types/scripting/ScriptAST.d.ts +312 -0
  178. package/dist/types/scripting/VisualScripting2.d.ts +353 -0
  179. package/dist/types/scripting/exporters/CSharpExporter.d.ts +44 -0
  180. package/dist/types/scripting/exporters/GDScriptExporter.d.ts +46 -0
  181. package/dist/types/scripting/exporters/LuaExporter.d.ts +46 -0
  182. package/dist/types/scripting/exporters/PythonExporter.d.ts +49 -0
  183. package/dist/types/scripting/exporters/RustExporter.d.ts +46 -0
  184. package/dist/types/scripting/exporters/TypeScriptExporter.d.ts +48 -0
  185. package/dist/types/scripting/exporters/index.d.ts +8 -0
  186. package/dist/types/scripting/index.d.ts +11 -0
  187. package/dist/types/systems/ParticleSystem2.d.ts +646 -0
  188. package/package.json +2 -2
@@ -0,0 +1,652 @@
1
+ 'use strict';
2
+
3
+ var SceneImporter = require('./SceneImporter.js');
4
+
5
+ /**
6
+ * @file SpriterImporter.ts
7
+ * @description Spriter Pro Animation Importer
8
+ * PRO-1.3: Scene Format Interoperability
9
+ *
10
+ * Spriter is a 2D animation tool for games.
11
+ * Supports SCML (XML) and SCON (JSON) formats.
12
+ *
13
+ * File Types:
14
+ * - *.scml - Spriter Character Map Lxml (XML format)
15
+ * - *.scon - Spriter Character Object Notation (JSON format)
16
+ */
17
+ // ============================================================
18
+ // Spriter Importer
19
+ // ============================================================
20
+ class SpriterImporter extends SceneImporter.SceneImporter {
21
+ constructor() {
22
+ super('spriter');
23
+ this.project = null;
24
+ this.fileMap = new Map();
25
+ this.folderMap = new Map();
26
+ }
27
+ canHandle(filePath) {
28
+ const ext = filePath.toLowerCase();
29
+ return ext.endsWith('.scml') || ext.endsWith('.scon');
30
+ }
31
+ async import(options) {
32
+ const startTime = Date.now();
33
+ this.options = options;
34
+ this.clearMessages();
35
+ const scenes = [];
36
+ const assets = [];
37
+ try {
38
+ const content = await this.readFile(options.sourcePath);
39
+ const isXml = options.sourcePath.toLowerCase().endsWith('.scml');
40
+ if (isXml) {
41
+ this.project = this.parseScml(content);
42
+ }
43
+ else {
44
+ const parsed = JSON.parse(content);
45
+ this.project = parsed.spriter_data;
46
+ }
47
+ if (!this.project) {
48
+ throw new Error('Failed to parse Spriter project');
49
+ }
50
+ // Build folder/file maps
51
+ this.buildMaps();
52
+ // Add file assets
53
+ for (const folder of this.project.folder) {
54
+ for (const file of folder.file) {
55
+ assets.push({
56
+ id: this.generateId(),
57
+ name: this.extractFileName(file.name),
58
+ type: file.name.match(/\.(wav|ogg|mp3)$/i) ? 'audio' : 'texture',
59
+ path: file.name,
60
+ data: {
61
+ folder: folder.name || `folder_${folder.id}`,
62
+ width: file.width,
63
+ height: file.height,
64
+ pivotX: file.pivot_x,
65
+ pivotY: file.pivot_y,
66
+ },
67
+ });
68
+ }
69
+ }
70
+ // Convert each entity to a scene
71
+ for (const entity of this.project.entity) {
72
+ const scene = this.convertEntityToScene(entity);
73
+ scenes.push(scene);
74
+ }
75
+ }
76
+ catch (error) {
77
+ this.addError('IMPORT_ERROR', `Failed to import: ${error}`, options.sourcePath, undefined, true);
78
+ }
79
+ return this.createResult(scenes, assets, startTime);
80
+ }
81
+ async parseFile(content, filePath) {
82
+ const stringContent = typeof content === 'string' ? content : new TextDecoder().decode(content);
83
+ try {
84
+ const isXml = filePath.toLowerCase().endsWith('.scml');
85
+ if (isXml) {
86
+ this.project = this.parseScml(stringContent);
87
+ }
88
+ else {
89
+ const parsed = JSON.parse(stringContent);
90
+ this.project = parsed.spriter_data;
91
+ }
92
+ if (this.project && this.project.entity.length > 0) {
93
+ this.buildMaps();
94
+ return this.convertEntityToParsed(this.project.entity[0]);
95
+ }
96
+ }
97
+ catch (_a) {
98
+ return null;
99
+ }
100
+ return null;
101
+ }
102
+ async validate(sourcePath) {
103
+ const errors = [];
104
+ if (!this.canHandle(sourcePath)) {
105
+ errors.push({
106
+ code: 'INVALID_FORMAT',
107
+ message: `File ${sourcePath} is not a valid Spriter file`,
108
+ file: sourcePath,
109
+ fatal: true,
110
+ });
111
+ }
112
+ return errors;
113
+ }
114
+ // ----------------------------------------
115
+ // SCML (XML) Parser
116
+ // ----------------------------------------
117
+ parseScml(xml) {
118
+ // Simple XML attribute parser
119
+ const getAttrs = (tag) => {
120
+ const attrs = {};
121
+ const attrRegex = /(\w+)="([^"]*)"/g;
122
+ let match;
123
+ while ((match = attrRegex.exec(tag)) !== null) {
124
+ attrs[match[1]] = match[2];
125
+ }
126
+ return attrs;
127
+ };
128
+ // Parse folders
129
+ const folders = [];
130
+ const folderRegex = /<folder\s+([^>]*)>([\s\S]*?)<\/folder>/g;
131
+ let folderMatch;
132
+ while ((folderMatch = folderRegex.exec(xml)) !== null) {
133
+ const folderAttrs = getAttrs(folderMatch[1]);
134
+ const files = [];
135
+ const fileRegex = /<file\s+([^/]*?)\/>/g;
136
+ let fileMatch;
137
+ const folderContent = folderMatch[2];
138
+ while ((fileMatch = fileRegex.exec(folderContent)) !== null) {
139
+ const fileAttrs = getAttrs(fileMatch[1]);
140
+ files.push({
141
+ id: parseInt(fileAttrs.id) || 0,
142
+ name: fileAttrs.name || '',
143
+ width: parseInt(fileAttrs.width) || 0,
144
+ height: parseInt(fileAttrs.height) || 0,
145
+ pivot_x: fileAttrs.pivot_x !== undefined ? parseFloat(fileAttrs.pivot_x) : undefined,
146
+ pivot_y: fileAttrs.pivot_y !== undefined ? parseFloat(fileAttrs.pivot_y) : undefined,
147
+ });
148
+ }
149
+ folders.push({
150
+ id: parseInt(folderAttrs.id) || 0,
151
+ name: folderAttrs.name,
152
+ file: files,
153
+ });
154
+ }
155
+ // Parse entities
156
+ const entities = [];
157
+ const entityRegex = /<entity\s+([^>]*)>([\s\S]*?)<\/entity>/g;
158
+ let entityMatch;
159
+ while ((entityMatch = entityRegex.exec(xml)) !== null) {
160
+ const entityAttrs = getAttrs(entityMatch[1]);
161
+ const entityContent = entityMatch[2];
162
+ // Parse animations
163
+ const animations = [];
164
+ const animRegex = /<animation\s+([^>]*)>([\s\S]*?)<\/animation>/g;
165
+ let animMatch;
166
+ while ((animMatch = animRegex.exec(entityContent)) !== null) {
167
+ const animAttrs = getAttrs(animMatch[1]);
168
+ const animContent = animMatch[2];
169
+ // Parse mainline
170
+ const mainlineMatch = /<mainline>([\s\S]*?)<\/mainline>/.exec(animContent);
171
+ const mainlineKeys = [];
172
+ if (mainlineMatch) {
173
+ const keyRegex = /<key\s+([^>]*)>([\s\S]*?)<\/key>/g;
174
+ let keyMatch;
175
+ while ((keyMatch = keyRegex.exec(mainlineMatch[1])) !== null) {
176
+ const keyAttrs = getAttrs(keyMatch[1]);
177
+ const keyContent = keyMatch[2];
178
+ // Parse bone_ref and object_ref
179
+ const boneRefs = [];
180
+ const objRefs = [];
181
+ const boneRefRegex = /<bone_ref\s+([^/]*?)\/>/g;
182
+ let boneRefMatch;
183
+ while ((boneRefMatch = boneRefRegex.exec(keyContent)) !== null) {
184
+ const refAttrs = getAttrs(boneRefMatch[1]);
185
+ boneRefs.push({
186
+ id: parseInt(refAttrs.id) || 0,
187
+ parent: refAttrs.parent !== undefined ? parseInt(refAttrs.parent) : undefined,
188
+ timeline: parseInt(refAttrs.timeline) || 0,
189
+ key: parseInt(refAttrs.key) || 0,
190
+ });
191
+ }
192
+ const objRefRegex = /<object_ref\s+([^/]*?)\/>/g;
193
+ let objRefMatch;
194
+ while ((objRefMatch = objRefRegex.exec(keyContent)) !== null) {
195
+ const refAttrs = getAttrs(objRefMatch[1]);
196
+ objRefs.push({
197
+ id: parseInt(refAttrs.id) || 0,
198
+ parent: refAttrs.parent !== undefined ? parseInt(refAttrs.parent) : undefined,
199
+ timeline: parseInt(refAttrs.timeline) || 0,
200
+ key: parseInt(refAttrs.key) || 0,
201
+ z_index: refAttrs.z_index !== undefined ? parseInt(refAttrs.z_index) : undefined,
202
+ });
203
+ }
204
+ mainlineKeys.push({
205
+ id: parseInt(keyAttrs.id) || 0,
206
+ time: keyAttrs.time !== undefined ? parseInt(keyAttrs.time) : undefined,
207
+ bone_ref: boneRefs.length > 0 ? boneRefs : undefined,
208
+ object_ref: objRefs.length > 0 ? objRefs : undefined,
209
+ });
210
+ }
211
+ }
212
+ // Parse timelines
213
+ const timelines = [];
214
+ const timelineRegex = /<timeline\s+([^>]*)>([\s\S]*?)<\/timeline>/g;
215
+ let timelineMatch;
216
+ while ((timelineMatch = timelineRegex.exec(animContent)) !== null) {
217
+ const tlAttrs = getAttrs(timelineMatch[1]);
218
+ const tlContent = timelineMatch[2];
219
+ const tlKeys = [];
220
+ const tlKeyRegex = /<key\s+([^>]*)>([\s\S]*?)<\/key>/g;
221
+ let tlKeyMatch;
222
+ while ((tlKeyMatch = tlKeyRegex.exec(tlContent)) !== null) {
223
+ const tlKeyAttrs = getAttrs(tlKeyMatch[1]);
224
+ const tlKeyContent = tlKeyMatch[2];
225
+ const key = {
226
+ id: parseInt(tlKeyAttrs.id) || 0,
227
+ time: tlKeyAttrs.time !== undefined ? parseInt(tlKeyAttrs.time) : undefined,
228
+ spin: tlKeyAttrs.spin !== undefined ? parseInt(tlKeyAttrs.spin) : undefined,
229
+ curve_type: tlKeyAttrs.curve_type,
230
+ };
231
+ // Parse bone
232
+ const boneMatch = /<bone\s+([^/]*?)\/?>/.exec(tlKeyContent);
233
+ if (boneMatch) {
234
+ const boneAttrs = getAttrs(boneMatch[1]);
235
+ key.bone = {
236
+ x: boneAttrs.x !== undefined ? parseFloat(boneAttrs.x) : undefined,
237
+ y: boneAttrs.y !== undefined ? parseFloat(boneAttrs.y) : undefined,
238
+ angle: boneAttrs.angle !== undefined ? parseFloat(boneAttrs.angle) : undefined,
239
+ scale_x: boneAttrs.scale_x !== undefined ? parseFloat(boneAttrs.scale_x) : undefined,
240
+ scale_y: boneAttrs.scale_y !== undefined ? parseFloat(boneAttrs.scale_y) : undefined,
241
+ a: boneAttrs.a !== undefined ? parseFloat(boneAttrs.a) : undefined,
242
+ };
243
+ }
244
+ // Parse object
245
+ const objectMatch = /<object\s+([^/]*?)\/?>/.exec(tlKeyContent);
246
+ if (objectMatch) {
247
+ const objAttrs = getAttrs(objectMatch[1]);
248
+ key.object = {
249
+ folder: objAttrs.folder !== undefined ? parseInt(objAttrs.folder) : undefined,
250
+ file: objAttrs.file !== undefined ? parseInt(objAttrs.file) : undefined,
251
+ x: objAttrs.x !== undefined ? parseFloat(objAttrs.x) : undefined,
252
+ y: objAttrs.y !== undefined ? parseFloat(objAttrs.y) : undefined,
253
+ angle: objAttrs.angle !== undefined ? parseFloat(objAttrs.angle) : undefined,
254
+ scale_x: objAttrs.scale_x !== undefined ? parseFloat(objAttrs.scale_x) : undefined,
255
+ scale_y: objAttrs.scale_y !== undefined ? parseFloat(objAttrs.scale_y) : undefined,
256
+ pivot_x: objAttrs.pivot_x !== undefined ? parseFloat(objAttrs.pivot_x) : undefined,
257
+ pivot_y: objAttrs.pivot_y !== undefined ? parseFloat(objAttrs.pivot_y) : undefined,
258
+ a: objAttrs.a !== undefined ? parseFloat(objAttrs.a) : undefined,
259
+ };
260
+ }
261
+ tlKeys.push(key);
262
+ }
263
+ timelines.push({
264
+ id: parseInt(tlAttrs.id) || 0,
265
+ name: tlAttrs.name || '',
266
+ object_type: tlAttrs.object_type,
267
+ obj: tlAttrs.obj !== undefined ? parseInt(tlAttrs.obj) : undefined,
268
+ key: tlKeys,
269
+ });
270
+ }
271
+ animations.push({
272
+ id: parseInt(animAttrs.id) || 0,
273
+ name: animAttrs.name || '',
274
+ length: parseInt(animAttrs.length) || 0,
275
+ interval: animAttrs.interval !== undefined ? parseInt(animAttrs.interval) : undefined,
276
+ looping: animAttrs.looping !== 'false',
277
+ mainline: { key: mainlineKeys },
278
+ timeline: timelines.length > 0 ? timelines : undefined,
279
+ });
280
+ }
281
+ // Parse character maps
282
+ const characterMaps = [];
283
+ const cmRegex = /<character_map\s+([^>]*)>([\s\S]*?)<\/character_map>/g;
284
+ let cmMatch;
285
+ while ((cmMatch = cmRegex.exec(entityContent)) !== null) {
286
+ const cmAttrs = getAttrs(cmMatch[1]);
287
+ const cmContent = cmMatch[2];
288
+ const maps = [];
289
+ const mapRegex = /<map\s+([^/]*?)\/>/g;
290
+ let mapMatch;
291
+ while ((mapMatch = mapRegex.exec(cmContent)) !== null) {
292
+ const mapAttrs = getAttrs(mapMatch[1]);
293
+ maps.push({
294
+ folder: parseInt(mapAttrs.folder),
295
+ file: parseInt(mapAttrs.file),
296
+ target_folder: mapAttrs.target_folder !== undefined ? parseInt(mapAttrs.target_folder) : undefined,
297
+ target_file: mapAttrs.target_file !== undefined ? parseInt(mapAttrs.target_file) : undefined,
298
+ });
299
+ }
300
+ characterMaps.push({
301
+ id: parseInt(cmAttrs.id) || 0,
302
+ name: cmAttrs.name || '',
303
+ map: maps.length > 0 ? maps : undefined,
304
+ });
305
+ }
306
+ entities.push({
307
+ id: parseInt(entityAttrs.id) || 0,
308
+ name: entityAttrs.name || '',
309
+ animation: animations,
310
+ character_map: characterMaps.length > 0 ? characterMaps : undefined,
311
+ });
312
+ }
313
+ // Get version info
314
+ const spriterDataMatch = /<spriter_data\s+([^>]*)>/;
315
+ const dataMatch = spriterDataMatch.exec(xml);
316
+ const dataAttrs = dataMatch ? getAttrs(dataMatch[1]) : {};
317
+ return {
318
+ scml_version: dataAttrs.scml_version,
319
+ generator: dataAttrs.generator,
320
+ generator_version: dataAttrs.generator_version,
321
+ folder: folders,
322
+ entity: entities,
323
+ };
324
+ }
325
+ // ----------------------------------------
326
+ // Build Maps
327
+ // ----------------------------------------
328
+ buildMaps() {
329
+ this.fileMap.clear();
330
+ this.folderMap.clear();
331
+ if (!this.project)
332
+ return;
333
+ for (const folder of this.project.folder) {
334
+ this.folderMap.set(folder.id, folder);
335
+ for (const file of folder.file) {
336
+ this.fileMap.set(`${folder.id}_${file.id}`, file);
337
+ }
338
+ }
339
+ }
340
+ // ----------------------------------------
341
+ // Entity Conversion
342
+ // ----------------------------------------
343
+ convertEntityToScene(entity) {
344
+ var _a, _b, _c;
345
+ const entities = [];
346
+ // Create root entity
347
+ const rootEntity = {
348
+ id: this.generateId(),
349
+ name: entity.name,
350
+ components: [
351
+ {
352
+ type: 'Transform',
353
+ data: {
354
+ position: { x: 0, y: 0 },
355
+ rotation: 0,
356
+ scale: { x: 1, y: 1 },
357
+ },
358
+ },
359
+ {
360
+ type: 'SpriterEntity',
361
+ data: {
362
+ animationCount: entity.animation.length,
363
+ characterMapCount: ((_a = entity.character_map) === null || _a === void 0 ? void 0 : _a.length) || 0,
364
+ hasVariables: !!entity.var_defs && entity.var_defs.length > 0,
365
+ },
366
+ },
367
+ ],
368
+ children: [],
369
+ tags: ['spriter', 'entity'],
370
+ active: true,
371
+ };
372
+ // Add object info components
373
+ if (entity.obj_info) {
374
+ for (const objInfo of entity.obj_info) {
375
+ rootEntity.components.push({
376
+ type: objInfo.type === 'bone' ? 'Bone' : 'SpriteObject',
377
+ data: {
378
+ name: objInfo.name,
379
+ type: objInfo.type,
380
+ width: objInfo.w,
381
+ height: objInfo.h,
382
+ pivotX: objInfo.pivot_x,
383
+ pivotY: objInfo.pivot_y,
384
+ },
385
+ });
386
+ }
387
+ }
388
+ // Add character maps
389
+ if (entity.character_map) {
390
+ for (const charMap of entity.character_map) {
391
+ rootEntity.components.push({
392
+ type: 'CharacterMap',
393
+ data: {
394
+ name: charMap.name,
395
+ mappingCount: ((_b = charMap.map) === null || _b === void 0 ? void 0 : _b.length) || 0,
396
+ mappings: (_c = charMap.map) === null || _c === void 0 ? void 0 : _c.map((m) => ({
397
+ sourceFolder: m.folder,
398
+ sourceFile: m.file,
399
+ targetFolder: m.target_folder,
400
+ targetFile: m.target_file,
401
+ })),
402
+ },
403
+ });
404
+ }
405
+ }
406
+ // Add variables
407
+ if (entity.var_defs) {
408
+ for (const varDef of entity.var_defs) {
409
+ rootEntity.components.push({
410
+ type: 'Variable',
411
+ data: {
412
+ name: varDef.name,
413
+ type: varDef.type,
414
+ defaultValue: varDef.default_value,
415
+ },
416
+ });
417
+ }
418
+ }
419
+ // Add animations
420
+ for (const anim of entity.animation) {
421
+ const animComponent = this.convertAnimation(anim);
422
+ rootEntity.components.push(animComponent);
423
+ }
424
+ entities.push(rootEntity);
425
+ return {
426
+ id: this.generateId(),
427
+ name: entity.name,
428
+ entities,
429
+ settings: {
430
+ width: 800,
431
+ height: 600,
432
+ backgroundColor: '#1a1a2e',
433
+ },
434
+ };
435
+ }
436
+ convertAnimation(anim) {
437
+ var _a, _b;
438
+ const bones = [];
439
+ const sprites = [];
440
+ // Extract bones and sprites from timelines
441
+ if (anim.timeline) {
442
+ for (const timeline of anim.timeline) {
443
+ if (timeline.object_type === 'bone' || ((_a = timeline.key[0]) === null || _a === void 0 ? void 0 : _a.bone)) {
444
+ bones.push({
445
+ name: timeline.name,
446
+ keyframeCount: timeline.key.length,
447
+ keys: timeline.key.map((k) => {
448
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
449
+ return ({
450
+ time: k.time || 0,
451
+ x: ((_a = k.bone) === null || _a === void 0 ? void 0 : _a.x) || 0,
452
+ y: ((_b = k.bone) === null || _b === void 0 ? void 0 : _b.y) || 0,
453
+ angle: ((_c = k.bone) === null || _c === void 0 ? void 0 : _c.angle) || 0,
454
+ scaleX: (_e = (_d = k.bone) === null || _d === void 0 ? void 0 : _d.scale_x) !== null && _e !== void 0 ? _e : 1,
455
+ scaleY: (_g = (_f = k.bone) === null || _f === void 0 ? void 0 : _f.scale_y) !== null && _g !== void 0 ? _g : 1,
456
+ alpha: (_j = (_h = k.bone) === null || _h === void 0 ? void 0 : _h.a) !== null && _j !== void 0 ? _j : 1,
457
+ spin: (_k = k.spin) !== null && _k !== void 0 ? _k : 1,
458
+ curveType: k.curve_type || 'linear',
459
+ });
460
+ }),
461
+ });
462
+ }
463
+ else if ((_b = timeline.key[0]) === null || _b === void 0 ? void 0 : _b.object) {
464
+ sprites.push({
465
+ name: timeline.name,
466
+ keyframeCount: timeline.key.length,
467
+ keys: timeline.key.map((k) => {
468
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
469
+ const file = ((_a = k.object) === null || _a === void 0 ? void 0 : _a.folder) !== undefined && ((_b = k.object) === null || _b === void 0 ? void 0 : _b.file) !== undefined
470
+ ? this.fileMap.get(`${k.object.folder}_${k.object.file}`)
471
+ : null;
472
+ return {
473
+ time: k.time || 0,
474
+ x: ((_c = k.object) === null || _c === void 0 ? void 0 : _c.x) || 0,
475
+ y: ((_d = k.object) === null || _d === void 0 ? void 0 : _d.y) || 0,
476
+ angle: ((_e = k.object) === null || _e === void 0 ? void 0 : _e.angle) || 0,
477
+ scaleX: (_g = (_f = k.object) === null || _f === void 0 ? void 0 : _f.scale_x) !== null && _g !== void 0 ? _g : 1,
478
+ scaleY: (_j = (_h = k.object) === null || _h === void 0 ? void 0 : _h.scale_y) !== null && _j !== void 0 ? _j : 1,
479
+ pivotX: (_m = (_l = (_k = k.object) === null || _k === void 0 ? void 0 : _k.pivot_x) !== null && _l !== void 0 ? _l : file === null || file === void 0 ? void 0 : file.pivot_x) !== null && _m !== void 0 ? _m : 0,
480
+ pivotY: (_q = (_p = (_o = k.object) === null || _o === void 0 ? void 0 : _o.pivot_y) !== null && _p !== void 0 ? _p : file === null || file === void 0 ? void 0 : file.pivot_y) !== null && _q !== void 0 ? _q : 1,
481
+ alpha: (_s = (_r = k.object) === null || _r === void 0 ? void 0 : _r.a) !== null && _s !== void 0 ? _s : 1,
482
+ spin: (_t = k.spin) !== null && _t !== void 0 ? _t : 1,
483
+ curveType: k.curve_type || 'linear',
484
+ file: file === null || file === void 0 ? void 0 : file.name,
485
+ };
486
+ }),
487
+ });
488
+ }
489
+ }
490
+ }
491
+ // Extract hierarchy from mainline
492
+ const hierarchy = [];
493
+ if (anim.mainline.key.length > 0) {
494
+ const firstKey = anim.mainline.key[0];
495
+ if (firstKey.bone_ref) {
496
+ for (const boneRef of firstKey.bone_ref) {
497
+ hierarchy.push({
498
+ type: 'bone',
499
+ id: boneRef.id,
500
+ parent: boneRef.parent,
501
+ timeline: boneRef.timeline,
502
+ });
503
+ }
504
+ }
505
+ if (firstKey.object_ref) {
506
+ for (const objRef of firstKey.object_ref) {
507
+ hierarchy.push({
508
+ type: 'sprite',
509
+ id: objRef.id,
510
+ parent: objRef.parent,
511
+ timeline: objRef.timeline,
512
+ zIndex: objRef.z_index,
513
+ });
514
+ }
515
+ }
516
+ }
517
+ // Events
518
+ const events = [];
519
+ if (anim.eventline) {
520
+ for (const eventline of anim.eventline) {
521
+ events.push({
522
+ name: eventline.name,
523
+ times: eventline.key.map((k) => k.time || 0),
524
+ });
525
+ }
526
+ }
527
+ // Sounds
528
+ const sounds = [];
529
+ if (anim.soundline) {
530
+ for (const soundline of anim.soundline) {
531
+ sounds.push({
532
+ name: soundline.name,
533
+ keys: soundline.key.map((k) => {
534
+ var _a, _b;
535
+ const file = this.fileMap.get(`${k.object.folder}_${k.object.file}`);
536
+ return {
537
+ time: k.time || 0,
538
+ file: file === null || file === void 0 ? void 0 : file.name,
539
+ volume: (_a = k.object.volume) !== null && _a !== void 0 ? _a : 1,
540
+ panning: (_b = k.object.panning) !== null && _b !== void 0 ? _b : 0,
541
+ };
542
+ }),
543
+ });
544
+ }
545
+ }
546
+ return {
547
+ type: 'Animation',
548
+ data: {
549
+ name: anim.name,
550
+ duration: anim.length,
551
+ interval: anim.interval,
552
+ looping: anim.looping !== false,
553
+ fps: 1000 / (anim.interval || 33), // Convert interval to FPS
554
+ boneCount: bones.length,
555
+ spriteCount: sprites.length,
556
+ bones,
557
+ sprites,
558
+ hierarchy,
559
+ events,
560
+ sounds,
561
+ mainlineKeyCount: anim.mainline.key.length,
562
+ },
563
+ };
564
+ }
565
+ convertEntityToParsed(entity) {
566
+ var _a, _b, _c, _d;
567
+ const entities = [];
568
+ // Create model entity
569
+ entities.push({
570
+ id: String(entity.id),
571
+ name: entity.name,
572
+ type: 'SpriterEntity',
573
+ x: 0,
574
+ y: 0,
575
+ width: 800,
576
+ height: 600,
577
+ rotation: 0,
578
+ scaleX: 1,
579
+ scaleY: 1,
580
+ visible: true,
581
+ components: [],
582
+ children: [],
583
+ properties: {
584
+ animationCount: entity.animation.length,
585
+ animations: entity.animation.map((a) => ({
586
+ name: a.name,
587
+ duration: a.length,
588
+ looping: a.looping !== false,
589
+ })),
590
+ characterMaps: (_a = entity.character_map) === null || _a === void 0 ? void 0 : _a.map((cm) => cm.name),
591
+ variables: (_b = entity.var_defs) === null || _b === void 0 ? void 0 : _b.map((v) => ({
592
+ name: v.name,
593
+ type: v.type,
594
+ defaultValue: v.default_value,
595
+ })),
596
+ },
597
+ });
598
+ return {
599
+ name: entity.name,
600
+ width: 800,
601
+ height: 600,
602
+ backgroundColor: '#1a1a2e',
603
+ layers: [
604
+ {
605
+ name: 'Animation',
606
+ type: 'object',
607
+ visible: true,
608
+ opacity: 1,
609
+ offsetX: 0,
610
+ offsetY: 0,
611
+ zIndex: 0,
612
+ properties: {},
613
+ },
614
+ ],
615
+ entities,
616
+ properties: {
617
+ generator: (_c = this.project) === null || _c === void 0 ? void 0 : _c.generator,
618
+ generatorVersion: (_d = this.project) === null || _d === void 0 ? void 0 : _d.generator_version,
619
+ },
620
+ };
621
+ }
622
+ // ----------------------------------------
623
+ // Utilities
624
+ // ----------------------------------------
625
+ async readFile(path) {
626
+ var _a;
627
+ if (typeof globalThis.process !== 'undefined' && ((_a = globalThis.process.versions) === null || _a === void 0 ? void 0 : _a.node)) {
628
+ const fs = await import('fs');
629
+ return fs.readFileSync(path, 'utf-8');
630
+ }
631
+ else if (typeof fetch !== 'undefined') {
632
+ const response = await fetch(path);
633
+ return response.text();
634
+ }
635
+ throw new Error('Unable to read file in current environment');
636
+ }
637
+ extractFileName(path) {
638
+ const name = path.substring(Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')) + 1);
639
+ const dotIndex = name.lastIndexOf('.');
640
+ return dotIndex > 0 ? name.substring(0, dotIndex) : name;
641
+ }
642
+ }
643
+ // ============================================================
644
+ // Factory Function
645
+ // ============================================================
646
+ function createSpriterImporter() {
647
+ return new SpriterImporter();
648
+ }
649
+
650
+ exports.SpriterImporter = SpriterImporter;
651
+ exports.createSpriterImporter = createSpriterImporter;
652
+ //# sourceMappingURL=SpriterImporter.js.map