tilemap-parser 0.1.0

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 (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/dist/core/errors.d.ts +13 -0
  4. package/dist/core/errors.d.ts.map +1 -0
  5. package/dist/core/errors.js +13 -0
  6. package/dist/core/errors.js.map +1 -0
  7. package/dist/core/index.d.ts +7 -0
  8. package/dist/core/index.d.ts.map +1 -0
  9. package/dist/core/index.js +7 -0
  10. package/dist/core/index.js.map +1 -0
  11. package/dist/core/loaders.d.ts +19 -0
  12. package/dist/core/loaders.d.ts.map +1 -0
  13. package/dist/core/loaders.js +50 -0
  14. package/dist/core/loaders.js.map +1 -0
  15. package/dist/core/parser/animation.d.ts +35 -0
  16. package/dist/core/parser/animation.d.ts.map +1 -0
  17. package/dist/core/parser/animation.js +178 -0
  18. package/dist/core/parser/animation.js.map +1 -0
  19. package/dist/core/parser/coerce.d.ts +13 -0
  20. package/dist/core/parser/coerce.d.ts.map +1 -0
  21. package/dist/core/parser/coerce.js +109 -0
  22. package/dist/core/parser/coerce.js.map +1 -0
  23. package/dist/core/parser/collision.d.ts +98 -0
  24. package/dist/core/parser/collision.d.ts.map +1 -0
  25. package/dist/core/parser/collision.js +486 -0
  26. package/dist/core/parser/collision.js.map +1 -0
  27. package/dist/core/parser/index.d.ts +7 -0
  28. package/dist/core/parser/index.d.ts.map +1 -0
  29. package/dist/core/parser/index.js +7 -0
  30. package/dist/core/parser/index.js.map +1 -0
  31. package/dist/core/parser/map.d.ts +132 -0
  32. package/dist/core/parser/map.d.ts.map +1 -0
  33. package/dist/core/parser/map.js +416 -0
  34. package/dist/core/parser/map.js.map +1 -0
  35. package/dist/core/parser/node.d.ts +14 -0
  36. package/dist/core/parser/node.d.ts.map +1 -0
  37. package/dist/core/parser/node.js +40 -0
  38. package/dist/core/parser/node.js.map +1 -0
  39. package/dist/core/parser/particle.d.ts +68 -0
  40. package/dist/core/parser/particle.d.ts.map +1 -0
  41. package/dist/core/parser/particle.js +341 -0
  42. package/dist/core/parser/particle.js.map +1 -0
  43. package/dist/core/parser/tileanim.d.ts +31 -0
  44. package/dist/core/parser/tileanim.d.ts.map +1 -0
  45. package/dist/core/parser/tileanim.js +182 -0
  46. package/dist/core/parser/tileanim.js.map +1 -0
  47. package/dist/core/runtime/body.d.ts +27 -0
  48. package/dist/core/runtime/body.d.ts.map +1 -0
  49. package/dist/core/runtime/body.js +105 -0
  50. package/dist/core/runtime/body.js.map +1 -0
  51. package/dist/core/runtime/collision/hit.d.ts +19 -0
  52. package/dist/core/runtime/collision/hit.d.ts.map +1 -0
  53. package/dist/core/runtime/collision/hit.js +87 -0
  54. package/dist/core/runtime/collision/hit.js.map +1 -0
  55. package/dist/core/runtime/collision/index.d.ts +4 -0
  56. package/dist/core/runtime/collision/index.d.ts.map +1 -0
  57. package/dist/core/runtime/collision/index.js +4 -0
  58. package/dist/core/runtime/collision/index.js.map +1 -0
  59. package/dist/core/runtime/collision/manager.d.ts +20 -0
  60. package/dist/core/runtime/collision/manager.d.ts.map +1 -0
  61. package/dist/core/runtime/collision/manager.js +142 -0
  62. package/dist/core/runtime/collision/manager.js.map +1 -0
  63. package/dist/core/runtime/collision/shapes.d.ts +10 -0
  64. package/dist/core/runtime/collision/shapes.d.ts.map +1 -0
  65. package/dist/core/runtime/collision/shapes.js +193 -0
  66. package/dist/core/runtime/collision/shapes.js.map +1 -0
  67. package/dist/core/runtime/collision_cache.d.ts +17 -0
  68. package/dist/core/runtime/collision_cache.d.ts.map +1 -0
  69. package/dist/core/runtime/collision_cache.js +78 -0
  70. package/dist/core/runtime/collision_cache.js.map +1 -0
  71. package/dist/core/runtime/index.d.ts +9 -0
  72. package/dist/core/runtime/index.d.ts.map +1 -0
  73. package/dist/core/runtime/index.js +9 -0
  74. package/dist/core/runtime/index.js.map +1 -0
  75. package/dist/core/runtime/movement/grounded.d.ts +12 -0
  76. package/dist/core/runtime/movement/grounded.d.ts.map +1 -0
  77. package/dist/core/runtime/movement/grounded.js +97 -0
  78. package/dist/core/runtime/movement/grounded.js.map +1 -0
  79. package/dist/core/runtime/movement/index.d.ts +8 -0
  80. package/dist/core/runtime/movement/index.d.ts.map +1 -0
  81. package/dist/core/runtime/movement/index.js +8 -0
  82. package/dist/core/runtime/movement/index.js.map +1 -0
  83. package/dist/core/runtime/movement/platformer.d.ts +15 -0
  84. package/dist/core/runtime/movement/platformer.d.ts.map +1 -0
  85. package/dist/core/runtime/movement/platformer.js +419 -0
  86. package/dist/core/runtime/movement/platformer.js.map +1 -0
  87. package/dist/core/runtime/movement/queries.d.ts +21 -0
  88. package/dist/core/runtime/movement/queries.d.ts.map +1 -0
  89. package/dist/core/runtime/movement/queries.js +326 -0
  90. package/dist/core/runtime/movement/queries.js.map +1 -0
  91. package/dist/core/runtime/movement/rpg.d.ts +10 -0
  92. package/dist/core/runtime/movement/rpg.d.ts.map +1 -0
  93. package/dist/core/runtime/movement/rpg.js +47 -0
  94. package/dist/core/runtime/movement/rpg.js.map +1 -0
  95. package/dist/core/runtime/movement/runner.d.ts +52 -0
  96. package/dist/core/runtime/movement/runner.d.ts.map +1 -0
  97. package/dist/core/runtime/movement/runner.js +220 -0
  98. package/dist/core/runtime/movement/runner.js.map +1 -0
  99. package/dist/core/runtime/movement/slide.d.ts +12 -0
  100. package/dist/core/runtime/movement/slide.d.ts.map +1 -0
  101. package/dist/core/runtime/movement/slide.js +145 -0
  102. package/dist/core/runtime/movement/slide.js.map +1 -0
  103. package/dist/core/runtime/movement/types.d.ts +22 -0
  104. package/dist/core/runtime/movement/types.d.ts.map +1 -0
  105. package/dist/core/runtime/movement/types.js +21 -0
  106. package/dist/core/runtime/movement/types.js.map +1 -0
  107. package/dist/core/runtime/navigation/index.d.ts +4 -0
  108. package/dist/core/runtime/navigation/index.d.ts.map +1 -0
  109. package/dist/core/runtime/navigation/index.js +4 -0
  110. package/dist/core/runtime/navigation/index.js.map +1 -0
  111. package/dist/core/runtime/navigation/nav_grid.d.ts +36 -0
  112. package/dist/core/runtime/navigation/nav_grid.d.ts.map +1 -0
  113. package/dist/core/runtime/navigation/nav_grid.js +245 -0
  114. package/dist/core/runtime/navigation/nav_grid.js.map +1 -0
  115. package/dist/core/runtime/navigation/path_follower.d.ts +19 -0
  116. package/dist/core/runtime/navigation/path_follower.d.ts.map +1 -0
  117. package/dist/core/runtime/navigation/path_follower.js +59 -0
  118. package/dist/core/runtime/navigation/path_follower.js.map +1 -0
  119. package/dist/core/runtime/navigation/pathfinder.d.ts +8 -0
  120. package/dist/core/runtime/navigation/pathfinder.d.ts.map +1 -0
  121. package/dist/core/runtime/navigation/pathfinder.js +114 -0
  122. package/dist/core/runtime/navigation/pathfinder.js.map +1 -0
  123. package/dist/core/runtime/polygon_query.d.ts +13 -0
  124. package/dist/core/runtime/polygon_query.d.ts.map +1 -0
  125. package/dist/core/runtime/polygon_query.js +462 -0
  126. package/dist/core/runtime/polygon_query.js.map +1 -0
  127. package/dist/core/runtime/protocols.d.ts +15 -0
  128. package/dist/core/runtime/protocols.d.ts.map +1 -0
  129. package/dist/core/runtime/protocols.js +2 -0
  130. package/dist/core/runtime/protocols.js.map +1 -0
  131. package/dist/core/runtime/world.d.ts +47 -0
  132. package/dist/core/runtime/world.d.ts.map +1 -0
  133. package/dist/core/runtime/world.js +272 -0
  134. package/dist/core/runtime/world.js.map +1 -0
  135. package/dist/core/utils/geometry.d.ts +25 -0
  136. package/dist/core/utils/geometry.d.ts.map +1 -0
  137. package/dist/core/utils/geometry.js +485 -0
  138. package/dist/core/utils/geometry.js.map +1 -0
  139. package/dist/core/utils/index.d.ts +2 -0
  140. package/dist/core/utils/index.d.ts.map +1 -0
  141. package/dist/core/utils/index.js +2 -0
  142. package/dist/core/utils/index.js.map +1 -0
  143. package/dist/core/vec.d.ts +13 -0
  144. package/dist/core/vec.d.ts.map +1 -0
  145. package/dist/core/vec.js +20 -0
  146. package/dist/core/vec.js.map +1 -0
  147. package/dist/phaser/anim.d.ts +8 -0
  148. package/dist/phaser/anim.d.ts.map +1 -0
  149. package/dist/phaser/anim.js +24 -0
  150. package/dist/phaser/anim.js.map +1 -0
  151. package/dist/phaser/camera.d.ts +29 -0
  152. package/dist/phaser/camera.d.ts.map +1 -0
  153. package/dist/phaser/camera.js +19 -0
  154. package/dist/phaser/camera.js.map +1 -0
  155. package/dist/phaser/images.d.ts +13 -0
  156. package/dist/phaser/images.d.ts.map +1 -0
  157. package/dist/phaser/images.js +40 -0
  158. package/dist/phaser/images.js.map +1 -0
  159. package/dist/phaser/index.d.ts +12 -0
  160. package/dist/phaser/index.d.ts.map +1 -0
  161. package/dist/phaser/index.js +12 -0
  162. package/dist/phaser/index.js.map +1 -0
  163. package/dist/phaser/keys.d.ts +11 -0
  164. package/dist/phaser/keys.d.ts.map +1 -0
  165. package/dist/phaser/keys.js +29 -0
  166. package/dist/phaser/keys.js.map +1 -0
  167. package/dist/phaser/loader.d.ts +9 -0
  168. package/dist/phaser/loader.d.ts.map +1 -0
  169. package/dist/phaser/loader.js +23 -0
  170. package/dist/phaser/loader.js.map +1 -0
  171. package/dist/phaser/objects.d.ts +20 -0
  172. package/dist/phaser/objects.d.ts.map +1 -0
  173. package/dist/phaser/objects.js +56 -0
  174. package/dist/phaser/objects.js.map +1 -0
  175. package/dist/phaser/particles.d.ts +34 -0
  176. package/dist/phaser/particles.d.ts.map +1 -0
  177. package/dist/phaser/particles.js +24 -0
  178. package/dist/phaser/particles.js.map +1 -0
  179. package/dist/phaser/spawns.d.ts +8 -0
  180. package/dist/phaser/spawns.d.ts.map +1 -0
  181. package/dist/phaser/spawns.js +29 -0
  182. package/dist/phaser/spawns.js.map +1 -0
  183. package/dist/phaser/sprites.d.ts +23 -0
  184. package/dist/phaser/sprites.d.ts.map +1 -0
  185. package/dist/phaser/sprites.js +34 -0
  186. package/dist/phaser/sprites.js.map +1 -0
  187. package/dist/phaser/tiles.d.ts +16 -0
  188. package/dist/phaser/tiles.d.ts.map +1 -0
  189. package/dist/phaser/tiles.js +76 -0
  190. package/dist/phaser/tiles.js.map +1 -0
  191. package/package.json +79 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FluffyBrudy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # tilemap-parser
2
+
3
+ TypeScript port of the `tilemap-parser` core, targeted at the web via
4
+ [Phaser](https://phaser.io/). Engine-agnostic parsing + runtime under
5
+ `tilemap-parser/core`, thin Phaser bindings under `tilemap-parser/phaser`.
6
+
7
+ > Fresh derivation from the unreleased `tilemap-parser` 6.0.0 line — not a
8
+ > port of legacy releases. Most of the Python API is mirrored where it makes
9
+ > sense on web/Phaser; engine-specific parts (pygame rendering) are replaced
10
+ > by Phaser helpers.
11
+
12
+ ## Install
13
+
14
+ ```sh
15
+ npm install tilemap-parser
16
+ ```
17
+
18
+ Phaser is an optional peer (`>=3.60.0`). Install it only if you use the
19
+ `/phaser` entry:
20
+
21
+ ```sh
22
+ npm install phaser
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```ts
28
+ import { parseMapDict } from "tilemap-parser/core";
29
+ import { buildTileLayers, queueMapAssets } from "tilemap-parser/phaser";
30
+
31
+ const map = parseMapDict(json);
32
+ queueMapAssets(scene, map, { mapUrl: "data/entry.json" });
33
+ buildTileLayers(scene, map);
34
+ ```
35
+
36
+ - `tilemap-parser` / `tilemap-parser/core` — map, animation, collision,
37
+ particle parsing plus the physics/navigation runtime (no engine deps).
38
+ - `tilemap-parser/phaser` — asset refs, tile/image/object layers, spawns,
39
+ camera, animations, particles for Phaser scenes.
40
+
41
+ ## Demo
42
+
43
+ `examples/swamp/` is a full playable Phaser demo (excluded from the npm
44
+ tarball). Run it from its own folder; see `examples/swamp/package.json`.
45
+
46
+ ## Docs
47
+
48
+ `webdocs/` is reserved for a future standalone docs site (Vercel). It ships
49
+ no code and is excluded from the npm package.
50
+
51
+ ## License
52
+
53
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,13 @@
1
+ export declare class TilemapParserError extends Error {
2
+ name: string;
3
+ }
4
+ export declare class MapParseError extends TilemapParserError {
5
+ name: string;
6
+ }
7
+ export declare class CollisionParseError extends TilemapParserError {
8
+ name: string;
9
+ }
10
+ export declare class AnimationParseError extends TilemapParserError {
11
+ name: string;
12
+ }
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;IAClC,IAAI,SAAwB;CACtC;AAED,qBAAa,aAAc,SAAQ,kBAAkB;IAC1C,IAAI,SAAmB;CACjC;AAED,qBAAa,mBAAoB,SAAQ,kBAAkB;IAChD,IAAI,SAAyB;CACvC;AAED,qBAAa,mBAAoB,SAAQ,kBAAkB;IAChD,IAAI,SAAyB;CACvC"}
@@ -0,0 +1,13 @@
1
+ export class TilemapParserError extends Error {
2
+ name = "TilemapParserError";
3
+ }
4
+ export class MapParseError extends TilemapParserError {
5
+ name = "MapParseError";
6
+ }
7
+ export class CollisionParseError extends TilemapParserError {
8
+ name = "CollisionParseError";
9
+ }
10
+ export class AnimationParseError extends TilemapParserError {
11
+ name = "AnimationParseError";
12
+ }
13
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,GAAG,oBAAoB,CAAC;CACtC;AAED,MAAM,OAAO,aAAc,SAAQ,kBAAkB;IAC1C,IAAI,GAAG,eAAe,CAAC;CACjC;AAED,MAAM,OAAO,mBAAoB,SAAQ,kBAAkB;IAChD,IAAI,GAAG,qBAAqB,CAAC;CACvC;AAED,MAAM,OAAO,mBAAoB,SAAQ,kBAAkB;IAChD,IAAI,GAAG,qBAAqB,CAAC;CACvC"}
@@ -0,0 +1,7 @@
1
+ export * from "./errors.js";
2
+ export * from "./vec.js";
3
+ export * from "./loaders.js";
4
+ export * from "./parser/index.js";
5
+ export * from "./runtime/index.js";
6
+ export * from "./utils/index.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from "./errors.js";
2
+ export * from "./vec.js";
3
+ export * from "./loaders.js";
4
+ export * from "./parser/index.js";
5
+ export * from "./runtime/index.js";
6
+ export * from "./utils/index.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface TextLoader {
2
+ read(pathOrUrl: string): Promise<string>;
3
+ }
4
+ export interface ImageLoader {
5
+ load(url: string): Promise<CanvasImageSource>;
6
+ }
7
+ export interface Clock {
8
+ nowMs(): number;
9
+ }
10
+ export type Rng = () => number;
11
+ export declare const mathRandom: Rng;
12
+ export declare const systemClock: Clock;
13
+ export declare const performanceClock: Clock;
14
+ export interface ResolveResourceOptions {
15
+ readonly mapUrl?: string;
16
+ readonly extraBaseUrls?: readonly string[] | undefined;
17
+ }
18
+ export declare function resolveResourceUrl(ref: string, options?: ResolveResourceOptions): string;
19
+ //# sourceMappingURL=loaders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../../src/core/loaders.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,IAAI,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC;AAE/B,eAAO,MAAM,UAAU,EAAE,GAAyB,CAAC;AAEnD,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAG9B,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACxD;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAwBR"}
@@ -0,0 +1,50 @@
1
+ export const mathRandom = () => Math.random();
2
+ export const systemClock = {
3
+ nowMs: () => Date.now(),
4
+ };
5
+ export const performanceClock = {
6
+ nowMs: () => typeof performance === "undefined" ? Date.now() : performance.now(),
7
+ };
8
+ export function resolveResourceUrl(ref, options = {}) {
9
+ const trimmed = ref.trim();
10
+ if (trimmed === "")
11
+ return trimmed;
12
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed) || trimmed.startsWith("/")) {
13
+ return trimmed;
14
+ }
15
+ const bases = [];
16
+ if (options.mapUrl !== undefined && options.mapUrl !== "") {
17
+ bases.push(options.mapUrl);
18
+ }
19
+ for (const extra of options.extraBaseUrls ?? []) {
20
+ if (extra !== "")
21
+ bases.push(extra);
22
+ }
23
+ for (const base of bases) {
24
+ try {
25
+ return new URL(trimmed, base).toString();
26
+ }
27
+ catch {
28
+ const dir = base.includes("/")
29
+ ? base.slice(0, base.lastIndexOf("/") + 1)
30
+ : "";
31
+ return normalizePath(`${dir}${trimmed}`);
32
+ }
33
+ }
34
+ return trimmed;
35
+ }
36
+ function normalizePath(path) {
37
+ const absolute = path.startsWith("/");
38
+ const out = [];
39
+ for (const seg of path.split("/")) {
40
+ if (seg === "" || seg === ".")
41
+ continue;
42
+ if (seg === "..") {
43
+ out.pop();
44
+ continue;
45
+ }
46
+ out.push(seg);
47
+ }
48
+ return (absolute ? "/" : "") + out.join("/");
49
+ }
50
+ //# sourceMappingURL=loaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loaders.js","sourceRoot":"","sources":["../../src/core/loaders.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,UAAU,GAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAU;IAChC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;CACxB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAU;IACrC,KAAK,EAAE,GAAG,EAAE,CACV,OAAO,WAAW,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE;CACtE,CAAC;AAOF,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,UAAkC,EAAE;IAEpC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,OAAO,CAAC;IACnC,IAAI,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzE,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;QAChD,IAAI,KAAK,KAAK,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAC5B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC1C,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,aAAa,CAAC,GAAG,GAAG,GAAG,OAAO,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,GAAG;YAAE,SAAS;QACxC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { Vec2 } from "../vec.js";
2
+ type JsonDict = Record<string, unknown>;
3
+ export interface AnimationMarker {
4
+ name: string;
5
+ frameIndex: number;
6
+ }
7
+ export interface AnimationFrame {
8
+ variantId: number;
9
+ durationMs: number;
10
+ }
11
+ export declare class AnimationClip {
12
+ name: string;
13
+ frames: AnimationFrame[];
14
+ loop: boolean;
15
+ fps: number;
16
+ metadata: JsonDict;
17
+ markers: AnimationMarker[];
18
+ constructor(name: string, frames?: AnimationFrame[], loop?: boolean, fps?: number, metadata?: JsonDict, markers?: AnimationMarker[]);
19
+ frameCount(): number;
20
+ totalDurationMs(): number;
21
+ clampMarkers(): void;
22
+ }
23
+ export declare class AnimationLibrary {
24
+ animations: Map<string, AnimationClip>;
25
+ spritesheetPath: string | null;
26
+ tileSize: Vec2;
27
+ gridOffset: Vec2;
28
+ trimTransparent: boolean;
29
+ constructor(animations?: Map<string, AnimationClip>, spritesheetPath?: string | null, tileSize?: Vec2, gridOffset?: Vec2, trimTransparent?: boolean);
30
+ get(name: string): AnimationClip | null;
31
+ }
32
+ export declare function parseAnimationDict(data: unknown): AnimationLibrary;
33
+ export declare function parseAnimationJson(text: string): AnimationLibrary;
34
+ export {};
35
+ //# sourceMappingURL=animation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../../../src/core/parser/animation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAoDxC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAa;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;gBAGzB,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,cAAc,EAAO,EAC7B,IAAI,UAAO,EACX,GAAG,SAAO,EACV,QAAQ,GAAE,QAAa,EACvB,OAAO,GAAE,eAAe,EAAO;IAUjC,UAAU,IAAI,MAAM;IAIpB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,IAAI;CAUrB;AAED,qBAAa,gBAAgB;IAC3B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACvC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;gBAGvB,UAAU,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,EAClD,eAAe,GAAE,MAAM,GAAG,IAAW,EACrC,QAAQ,GAAE,IAAe,EACzB,UAAU,GAAE,IAAa,EACzB,eAAe,UAAQ;IASzB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;CAGxC;AAqED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAiDlE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAUjE"}
@@ -0,0 +1,178 @@
1
+ import { AnimationParseError } from "../errors.js";
2
+ function reqDict(v, context) {
3
+ if (typeof v !== "object" || v === null || Array.isArray(v)) {
4
+ throw new AnimationParseError(`${context}: expected object`);
5
+ }
6
+ return v;
7
+ }
8
+ function reqList(v, context) {
9
+ if (!Array.isArray(v)) {
10
+ throw new AnimationParseError(`${context}: expected array`);
11
+ }
12
+ return v;
13
+ }
14
+ function reqStr(v, context) {
15
+ if (typeof v !== "string") {
16
+ throw new AnimationParseError(`${context}: expected string`);
17
+ }
18
+ return v;
19
+ }
20
+ function coerceInt(v, context) {
21
+ if (typeof v === "boolean") {
22
+ throw new AnimationParseError(`${context}: expected int`);
23
+ }
24
+ if (typeof v === "number") {
25
+ if (!Number.isInteger(v)) {
26
+ throw new AnimationParseError(`${context}: expected int`);
27
+ }
28
+ return v;
29
+ }
30
+ if (typeof v === "string" && /^[+-]?\d+$/.test(v.trim())) {
31
+ const n = Number(v.trim());
32
+ if (Number.isSafeInteger(n))
33
+ return n;
34
+ }
35
+ throw new AnimationParseError(`${context}: expected int`);
36
+ }
37
+ function coerceFloat(v, context) {
38
+ if (typeof v === "boolean") {
39
+ throw new AnimationParseError(`${context}: expected number`);
40
+ }
41
+ if (typeof v === "number")
42
+ return v;
43
+ if (typeof v === "string") {
44
+ const n = Number(v.trim());
45
+ if (v.trim() !== "" && Number.isFinite(n))
46
+ return n;
47
+ }
48
+ throw new AnimationParseError(`${context}: expected number`);
49
+ }
50
+ export class AnimationClip {
51
+ name;
52
+ frames;
53
+ loop;
54
+ fps;
55
+ metadata;
56
+ markers;
57
+ constructor(name, frames = [], loop = true, fps = 60.0, metadata = {}, markers = []) {
58
+ this.name = name;
59
+ this.frames = frames;
60
+ this.loop = loop;
61
+ this.fps = fps;
62
+ this.metadata = metadata;
63
+ this.markers = markers;
64
+ }
65
+ frameCount() {
66
+ return this.frames.length;
67
+ }
68
+ totalDurationMs() {
69
+ return this.frames.reduce((acc, f) => acc + f.durationMs, 0);
70
+ }
71
+ clampMarkers() {
72
+ const count = this.frames.length;
73
+ if (count === 0) {
74
+ this.markers.length = 0;
75
+ return;
76
+ }
77
+ for (const marker of this.markers) {
78
+ marker.frameIndex = Math.max(0, Math.min(marker.frameIndex, count - 1));
79
+ }
80
+ }
81
+ }
82
+ export class AnimationLibrary {
83
+ animations;
84
+ spritesheetPath;
85
+ tileSize;
86
+ gridOffset;
87
+ trimTransparent;
88
+ constructor(animations = new Map(), spritesheetPath = null, tileSize = [32, 32], gridOffset = [0, 0], trimTransparent = false) {
89
+ this.animations = animations;
90
+ this.spritesheetPath = spritesheetPath;
91
+ this.tileSize = tileSize;
92
+ this.gridOffset = gridOffset;
93
+ this.trimTransparent = trimTransparent;
94
+ }
95
+ get(name) {
96
+ return this.animations.get(name) ?? null;
97
+ }
98
+ }
99
+ function parseMarker(d, context) {
100
+ return {
101
+ name: reqStr(d["name"], `${context}.name`),
102
+ frameIndex: coerceInt(d["frame_index"], `${context}.frame_index`),
103
+ };
104
+ }
105
+ function parseFrame(d, context) {
106
+ return {
107
+ variantId: coerceInt(d["variant_id"], `${context}.variant_id`),
108
+ durationMs: coerceFloat(d["duration_ms"] ?? 100.0, `${context}.duration_ms`),
109
+ };
110
+ }
111
+ function parseAnimation(name, d, context) {
112
+ const framesRaw = reqList(d["frames"] ?? [], `${context}.frames`);
113
+ const frames = framesRaw.map((f, i) => parseFrame(reqDict(f, `${context}.frames[${i}]`), `${context}.frames[${i}]`));
114
+ const metadataRaw = d["metadata"];
115
+ let metadata;
116
+ if (metadataRaw === null || metadataRaw === undefined) {
117
+ metadata = {};
118
+ }
119
+ else if (typeof metadataRaw === "object" && !Array.isArray(metadataRaw)) {
120
+ metadata = { ...metadataRaw };
121
+ }
122
+ else {
123
+ throw new AnimationParseError(`${context}.metadata: expected object or null`);
124
+ }
125
+ const markers = [];
126
+ const markersRaw = d["markers"];
127
+ if (markersRaw !== null && markersRaw !== undefined) {
128
+ reqList(markersRaw, `${context}.markers`).forEach((marker, i) => {
129
+ markers.push(parseMarker(reqDict(marker, `${context}.markers[${i}]`), `${context}.markers[${i}]`));
130
+ });
131
+ }
132
+ const clip = new AnimationClip(reqStr(d["name"] ?? name, `${context}.name`), frames, Boolean(d["loop"] ?? true), coerceFloat(d["fps"] ?? 60.0, `${context}.fps`), metadata, markers);
133
+ clip.clampMarkers();
134
+ return clip;
135
+ }
136
+ export function parseAnimationDict(data) {
137
+ const root = reqDict(data, "root");
138
+ const spritesheet = root["spritesheet_path"];
139
+ const spritesheetPath = spritesheet === null || spritesheet === undefined
140
+ ? null
141
+ : reqStr(spritesheet, "spritesheet_path");
142
+ const tileSizeRaw = reqList(root["tile_size"] ?? [32, 32], "tile_size");
143
+ if (tileSizeRaw.length !== 2) {
144
+ throw new AnimationParseError("tile_size: expected [w, h]");
145
+ }
146
+ const tw = coerceInt(tileSizeRaw[0], "tile_size[0]");
147
+ const th = coerceInt(tileSizeRaw[1], "tile_size[1]");
148
+ if (tw < 1 || th < 1) {
149
+ throw new AnimationParseError("tile_size: width and height must be >= 1");
150
+ }
151
+ const gridOffsetRaw = root["grid_offset"] ?? [0, 0];
152
+ if (!Array.isArray(gridOffsetRaw) || gridOffsetRaw.length !== 2) {
153
+ throw new AnimationParseError("grid_offset: expected [x, y]");
154
+ }
155
+ const gox = coerceInt(gridOffsetRaw[0], "grid_offset[0]");
156
+ const goy = coerceInt(gridOffsetRaw[1], "grid_offset[1]");
157
+ if (gox < 0 || goy < 0) {
158
+ throw new AnimationParseError("grid_offset: values must be >= 0");
159
+ }
160
+ const animationsRaw = reqDict(root["animations"] ?? {}, "animations");
161
+ const animations = new Map();
162
+ for (const [key, value] of Object.entries(animationsRaw)) {
163
+ const k = String(key);
164
+ animations.set(k, parseAnimation(k, reqDict(value, `animations[${JSON.stringify(k)}]`), `animations[${JSON.stringify(k)}]`));
165
+ }
166
+ return new AnimationLibrary(animations, spritesheetPath, [tw, th], [gox, goy], Boolean(root["trim_transparent"] ?? false));
167
+ }
168
+ export function parseAnimationJson(text) {
169
+ let payload;
170
+ try {
171
+ payload = JSON.parse(text);
172
+ }
173
+ catch (err) {
174
+ throw new AnimationParseError(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
175
+ }
176
+ return parseAnimationDict(payload);
177
+ }
178
+ //# sourceMappingURL=animation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.js","sourceRoot":"","sources":["../../../src/core/parser/animation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Vec2 } from "../vec.js";
2
+ export type JsonDict = Record<string, unknown>;
3
+ export declare function _ctx(path: string, detail: string): string;
4
+ export declare function _requireDict(value: unknown, path: string): JsonDict;
5
+ export declare function _requireList(value: unknown, path: string): unknown[];
6
+ export declare function _requireStr(value: unknown, path: string): string;
7
+ export declare function _coerceInt(value: unknown, path: string): number;
8
+ export declare function _coerceFloat(value: unknown, path: string): number;
9
+ export declare function _coerceBool(value: unknown, path: string): boolean;
10
+ export declare function _optionalDict(value: unknown, path: string): JsonDict | null;
11
+ export declare function _parsePoint(text: string, path: string): Vec2;
12
+ export declare function _parsePointField(raw: unknown, path: string, fallback?: string): Vec2;
13
+ //# sourceMappingURL=coerce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../../src/core/parser/coerce.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAKnE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAKpE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAmB/D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CA0BjE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMjE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAG3E;AAOD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAe5D;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAQN"}
@@ -0,0 +1,109 @@
1
+ import { MapParseError } from "../errors.js";
2
+ export function _ctx(path, detail) {
3
+ return `${path}: ${detail}`;
4
+ }
5
+ export function _requireDict(value, path) {
6
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
7
+ throw new MapParseError(_ctx(path, "expected object"));
8
+ }
9
+ return value;
10
+ }
11
+ export function _requireList(value, path) {
12
+ if (!Array.isArray(value)) {
13
+ throw new MapParseError(_ctx(path, "expected array"));
14
+ }
15
+ return value;
16
+ }
17
+ export function _requireStr(value, path) {
18
+ if (typeof value !== "string") {
19
+ throw new MapParseError(_ctx(path, "expected string"));
20
+ }
21
+ return value;
22
+ }
23
+ export function _coerceInt(value, path) {
24
+ if (typeof value === "boolean") {
25
+ throw new MapParseError(_ctx(path, "expected int (got bool)"));
26
+ }
27
+ if (typeof value === "number") {
28
+ if (!Number.isInteger(value)) {
29
+ throw new MapParseError(_ctx(path, "expected int"));
30
+ }
31
+ return value;
32
+ }
33
+ if (typeof value === "string") {
34
+ const t = value.trim();
35
+ if (/^[+-]?\d+$/.test(t)) {
36
+ const n = Number(t);
37
+ if (Number.isSafeInteger(n))
38
+ return n;
39
+ }
40
+ throw new MapParseError(_ctx(path, "expected int"));
41
+ }
42
+ throw new MapParseError(_ctx(path, "expected int"));
43
+ }
44
+ export function _coerceFloat(value, path) {
45
+ if (typeof value === "boolean") {
46
+ throw new MapParseError(_ctx(path, "expected number (got bool)"));
47
+ }
48
+ if (typeof value === "number") {
49
+ return value;
50
+ }
51
+ if (typeof value === "string") {
52
+ const t = value.trim();
53
+ const lower = t.toLowerCase();
54
+ if (lower === "nan" || lower === "+nan" || lower === "-nan")
55
+ return NaN;
56
+ if (lower === "inf" ||
57
+ lower === "+inf" ||
58
+ lower === "infinity" ||
59
+ lower === "+infinity") {
60
+ return Infinity;
61
+ }
62
+ if (lower === "-inf" || lower === "-infinity")
63
+ return -Infinity;
64
+ if (/^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/.test(t)) {
65
+ return Number(t);
66
+ }
67
+ throw new MapParseError(_ctx(path, "expected number"));
68
+ }
69
+ throw new MapParseError(_ctx(path, "expected number"));
70
+ }
71
+ export function _coerceBool(value, path) {
72
+ if (typeof value === "boolean")
73
+ return value;
74
+ if (typeof value === "number" && (value === 0 || value === 1)) {
75
+ return value === 1;
76
+ }
77
+ throw new MapParseError(_ctx(path, "expected bool"));
78
+ }
79
+ export function _optionalDict(value, path) {
80
+ if (value === null || value === undefined)
81
+ return null;
82
+ return _requireDict(value, path);
83
+ }
84
+ // Anchored at both ends so leading garbage is rejected. Fractional parts are
85
+ // accepted because production maps store float points (e.g. meta.scroll
86
+ // "1499.35;610.03"); integer inputs still parse as before.
87
+ const POINT_RE = /^(-?\d+(?:\.\d+)?)([!-/:-@[-`{-~])(-?\d+(?:\.\d+)?)$/;
88
+ export function _parsePoint(text, path) {
89
+ if (typeof text !== "string") {
90
+ throw new MapParseError(_ctx(path, "expected point string"));
91
+ }
92
+ const matched = POINT_RE.exec(text.trim());
93
+ if (matched === null ||
94
+ matched[1] === undefined ||
95
+ matched[3] === undefined) {
96
+ throw new MapParseError(_ctx(path, `invalid point ${JSON.stringify(text)}`));
97
+ }
98
+ return [Number(matched[1]), Number(matched[3])];
99
+ }
100
+ export function _parsePointField(raw, path, fallback) {
101
+ if ((raw === null || raw === undefined) && fallback !== undefined) {
102
+ return _parsePoint(fallback, path);
103
+ }
104
+ if (typeof raw !== "string") {
105
+ throw new MapParseError(_ctx(path, "expected serialized point string"));
106
+ }
107
+ return _parsePoint(raw, path);
108
+ }
109
+ //# sourceMappingURL=coerce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.js","sourceRoot":"","sources":["../../../src/core/parser/coerce.ts"],"names":[],"mappings":"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"}