@aura3d/engine 1.0.3 → 1.0.6

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 (210) hide show
  1. package/README.md +338 -14
  2. package/dist/animation/AnimationClipEvents.d.ts +57 -0
  3. package/dist/animation/AnimationClipEvents.d.ts.map +1 -0
  4. package/dist/animation/AnimationClipEvents.js +171 -0
  5. package/dist/animation/AnimationClipEvents.js.map +1 -0
  6. package/dist/animation/AnimationClipRegistry.d.ts +76 -0
  7. package/dist/animation/AnimationClipRegistry.d.ts.map +1 -0
  8. package/dist/animation/AnimationClipRegistry.js +130 -0
  9. package/dist/animation/AnimationClipRegistry.js.map +1 -0
  10. package/dist/animation/AnimationController.d.ts +168 -0
  11. package/dist/animation/AnimationController.d.ts.map +1 -0
  12. package/dist/animation/AnimationController.js +619 -0
  13. package/dist/animation/AnimationController.js.map +1 -0
  14. package/dist/animation/AnimationStateGraph.d.ts +2 -0
  15. package/dist/animation/AnimationStateGraph.d.ts.map +1 -0
  16. package/dist/animation/AnimationStateGraph.js +2 -0
  17. package/dist/animation/AnimationStateGraph.js.map +1 -0
  18. package/dist/animation/AnimationStateMachine.d.ts +16 -0
  19. package/dist/animation/AnimationStateMachine.d.ts.map +1 -1
  20. package/dist/animation/AnimationStateMachine.js +69 -7
  21. package/dist/animation/AnimationStateMachine.js.map +1 -1
  22. package/dist/animation/HumanoidRetargeting.d.ts +76 -0
  23. package/dist/animation/HumanoidRetargeting.d.ts.map +1 -0
  24. package/dist/animation/HumanoidRetargeting.js +331 -0
  25. package/dist/animation/HumanoidRetargeting.js.map +1 -0
  26. package/dist/animation/browser-index.d.ts +18 -0
  27. package/dist/animation/browser-index.d.ts.map +1 -1
  28. package/dist/animation/browser-index.js +13 -0
  29. package/dist/animation/browser-index.js.map +1 -1
  30. package/dist/animation/index.d.ts +17 -1
  31. package/dist/animation/index.d.ts.map +1 -1
  32. package/dist/animation/index.js +12 -1
  33. package/dist/animation/index.js.map +1 -1
  34. package/dist/animation/threejs-compatibility/AnimationDiagnostics.d.ts.map +1 -1
  35. package/dist/animation/threejs-compatibility/AnimationDiagnostics.js +3 -5
  36. package/dist/animation/threejs-compatibility/AnimationDiagnostics.js.map +1 -1
  37. package/dist/assets/GLTFAnimationRuntime.js +1 -1
  38. package/dist/assets/GLTFLoader.js +1 -1
  39. package/dist/aura3d-cli/cli.js +225 -8
  40. package/dist/aura3d-cli/cli.js.map +1 -1
  41. package/dist/aura3d-cli/index.d.ts +283 -3
  42. package/dist/aura3d-cli/index.d.ts.map +1 -1
  43. package/dist/aura3d-cli/index.js +1028 -4
  44. package/dist/aura3d-cli/index.js.map +1 -1
  45. package/dist/aura3d-cli/pull-bridge.d.ts +108 -0
  46. package/dist/aura3d-cli/pull-bridge.d.ts.map +1 -0
  47. package/dist/aura3d-cli/pull-bridge.js +333 -0
  48. package/dist/aura3d-cli/pull-bridge.js.map +1 -0
  49. package/dist/create-aura3d/index.d.ts +1 -1
  50. package/dist/create-aura3d/index.d.ts.map +1 -1
  51. package/dist/create-aura3d/index.js +9 -2
  52. package/dist/create-aura3d/index.js.map +1 -1
  53. package/dist/editor-runtime/ProjectSerializer.d.ts +74 -1
  54. package/dist/editor-runtime/ProjectSerializer.d.ts.map +1 -1
  55. package/dist/editor-runtime/ProjectSerializer.js +123 -6
  56. package/dist/editor-runtime/ProjectSerializer.js.map +1 -1
  57. package/dist/editor-runtime/TimelineModel.d.ts +18 -0
  58. package/dist/editor-runtime/TimelineModel.d.ts.map +1 -1
  59. package/dist/editor-runtime/TimelineModel.js +67 -3
  60. package/dist/editor-runtime/TimelineModel.js.map +1 -1
  61. package/dist/editor-runtime/TimelineRuntimeBridge.d.ts +98 -0
  62. package/dist/editor-runtime/TimelineRuntimeBridge.d.ts.map +1 -0
  63. package/dist/editor-runtime/TimelineRuntimeBridge.js +186 -0
  64. package/dist/editor-runtime/TimelineRuntimeBridge.js.map +1 -0
  65. package/dist/editor-runtime/index.d.ts +3 -1
  66. package/dist/editor-runtime/index.d.ts.map +1 -1
  67. package/dist/editor-runtime/index.js +1 -0
  68. package/dist/editor-runtime/index.js.map +1 -1
  69. package/dist/engine/agent-api/AnimationController.d.ts +607 -0
  70. package/dist/engine/agent-api/AnimationController.d.ts.map +1 -0
  71. package/dist/engine/agent-api/AnimationController.js +2192 -0
  72. package/dist/engine/agent-api/AnimationController.js.map +1 -0
  73. package/dist/engine/agent-api/AssetEvidence.d.ts +88 -0
  74. package/dist/engine/agent-api/AssetEvidence.d.ts.map +1 -0
  75. package/dist/engine/agent-api/AssetEvidence.js +157 -0
  76. package/dist/engine/agent-api/AssetEvidence.js.map +1 -0
  77. package/dist/engine/agent-api/AuraAppHandle.d.ts +55 -0
  78. package/dist/engine/agent-api/AuraAppHandle.d.ts.map +1 -0
  79. package/dist/engine/agent-api/AuraAppHandle.js +15 -0
  80. package/dist/engine/agent-api/AuraAppHandle.js.map +1 -0
  81. package/dist/engine/agent-api/AuraVoiceBridge.d.ts +96 -0
  82. package/dist/engine/agent-api/AuraVoiceBridge.d.ts.map +1 -0
  83. package/dist/engine/agent-api/AuraVoiceBridge.js +370 -0
  84. package/dist/engine/agent-api/AuraVoiceBridge.js.map +1 -0
  85. package/dist/engine/agent-api/CartoonDirector.d.ts +95 -0
  86. package/dist/engine/agent-api/CartoonDirector.d.ts.map +1 -0
  87. package/dist/engine/agent-api/CartoonDirector.js +342 -0
  88. package/dist/engine/agent-api/CartoonDirector.js.map +1 -0
  89. package/dist/engine/agent-api/CartoonPerformance.d.ts +149 -0
  90. package/dist/engine/agent-api/CartoonPerformance.d.ts.map +1 -0
  91. package/dist/engine/agent-api/CartoonPerformance.js +317 -0
  92. package/dist/engine/agent-api/CartoonPerformance.js.map +1 -0
  93. package/dist/engine/agent-api/CartoonRenderQueue.d.ts +132 -0
  94. package/dist/engine/agent-api/CartoonRenderQueue.d.ts.map +1 -0
  95. package/dist/engine/agent-api/CartoonRenderQueue.js +385 -0
  96. package/dist/engine/agent-api/CartoonRenderQueue.js.map +1 -0
  97. package/dist/engine/agent-api/CharacterAssembly.d.ts +126 -0
  98. package/dist/engine/agent-api/CharacterAssembly.d.ts.map +1 -0
  99. package/dist/engine/agent-api/CharacterAssembly.js +280 -0
  100. package/dist/engine/agent-api/CharacterAssembly.js.map +1 -0
  101. package/dist/engine/agent-api/DialoguePerformance.d.ts +150 -0
  102. package/dist/engine/agent-api/DialoguePerformance.d.ts.map +1 -0
  103. package/dist/engine/agent-api/DialoguePerformance.js +335 -0
  104. package/dist/engine/agent-api/DialoguePerformance.js.map +1 -0
  105. package/dist/engine/agent-api/FrameLoop.d.ts +70 -0
  106. package/dist/engine/agent-api/FrameLoop.d.ts.map +1 -0
  107. package/dist/engine/agent-api/FrameLoop.js +165 -0
  108. package/dist/engine/agent-api/FrameLoop.js.map +1 -0
  109. package/dist/engine/agent-api/GameAppRuntime.d.ts +62 -0
  110. package/dist/engine/agent-api/GameAppRuntime.d.ts.map +1 -0
  111. package/dist/engine/agent-api/GameAppRuntime.js +189 -0
  112. package/dist/engine/agent-api/GameAppRuntime.js.map +1 -0
  113. package/dist/engine/agent-api/GameAssetValidation.d.ts +279 -0
  114. package/dist/engine/agent-api/GameAssetValidation.d.ts.map +1 -0
  115. package/dist/engine/agent-api/GameAssetValidation.js +719 -0
  116. package/dist/engine/agent-api/GameAssetValidation.js.map +1 -0
  117. package/dist/engine/agent-api/GameEvidence.d.ts +148 -0
  118. package/dist/engine/agent-api/GameEvidence.d.ts.map +1 -0
  119. package/dist/engine/agent-api/GameEvidence.js +269 -0
  120. package/dist/engine/agent-api/GameEvidence.js.map +1 -0
  121. package/dist/engine/agent-api/GameRuntime.d.ts +931 -0
  122. package/dist/engine/agent-api/GameRuntime.d.ts.map +1 -0
  123. package/dist/engine/agent-api/GameRuntime.js +2229 -0
  124. package/dist/engine/agent-api/GameRuntime.js.map +1 -0
  125. package/dist/engine/agent-api/GameSceneBridge.d.ts +54 -0
  126. package/dist/engine/agent-api/GameSceneBridge.d.ts.map +1 -0
  127. package/dist/engine/agent-api/GameSceneBridge.js +110 -0
  128. package/dist/engine/agent-api/GameSceneBridge.js.map +1 -0
  129. package/dist/engine/agent-api/PromptAnimationContract.d.ts +278 -0
  130. package/dist/engine/agent-api/PromptAnimationContract.d.ts.map +1 -0
  131. package/dist/engine/agent-api/PromptAnimationContract.js +238 -0
  132. package/dist/engine/agent-api/PromptAnimationContract.js.map +1 -0
  133. package/dist/engine/agent-api/PromptAnimationEvidence.d.ts +183 -0
  134. package/dist/engine/agent-api/PromptAnimationEvidence.d.ts.map +1 -0
  135. package/dist/engine/agent-api/PromptAnimationEvidence.js +454 -0
  136. package/dist/engine/agent-api/PromptAnimationEvidence.js.map +1 -0
  137. package/dist/engine/agent-api/RuntimeNodeHandle.d.ts +100 -0
  138. package/dist/engine/agent-api/RuntimeNodeHandle.d.ts.map +1 -0
  139. package/dist/engine/agent-api/RuntimeNodeHandle.js +36 -0
  140. package/dist/engine/agent-api/RuntimeNodeHandle.js.map +1 -0
  141. package/dist/engine/agent-api/ShotTimeline.d.ts +179 -0
  142. package/dist/engine/agent-api/ShotTimeline.d.ts.map +1 -0
  143. package/dist/engine/agent-api/ShotTimeline.js +264 -0
  144. package/dist/engine/agent-api/ShotTimeline.js.map +1 -0
  145. package/dist/engine/agent-api/VisemeController.d.ts +89 -0
  146. package/dist/engine/agent-api/VisemeController.d.ts.map +1 -0
  147. package/dist/engine/agent-api/VisemeController.js +207 -0
  148. package/dist/engine/agent-api/VisemeController.js.map +1 -0
  149. package/dist/engine/agent-api/game-kits/fighting.d.ts +123 -0
  150. package/dist/engine/agent-api/game-kits/fighting.d.ts.map +1 -0
  151. package/dist/engine/agent-api/game-kits/fighting.js +483 -0
  152. package/dist/engine/agent-api/game-kits/fighting.js.map +1 -0
  153. package/dist/engine/agent-api/game-kits/index.d.ts +15 -0
  154. package/dist/engine/agent-api/game-kits/index.d.ts.map +1 -0
  155. package/dist/engine/agent-api/game-kits/index.js +6 -0
  156. package/dist/engine/agent-api/game-kits/index.js.map +1 -0
  157. package/dist/engine/agent-api/humanoid-walk-runtime.d.ts +1 -0
  158. package/dist/engine/agent-api/humanoid-walk-runtime.d.ts.map +1 -1
  159. package/dist/engine/agent-api/index.d.ts +495 -1
  160. package/dist/engine/agent-api/index.d.ts.map +1 -1
  161. package/dist/engine/agent-api/index.js +752 -6
  162. package/dist/engine/agent-api/index.js.map +1 -1
  163. package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
  164. package/dist/index.d.ts +1 -0
  165. package/dist/index.js +1 -0
  166. package/dist/physics/CollisionVolumes.d.ts +57 -0
  167. package/dist/physics/CollisionVolumes.d.ts.map +1 -0
  168. package/dist/physics/CollisionVolumes.js +159 -0
  169. package/dist/physics/CollisionVolumes.js.map +1 -0
  170. package/dist/physics/HitboxWorld.d.ts +250 -0
  171. package/dist/physics/HitboxWorld.d.ts.map +1 -0
  172. package/dist/physics/HitboxWorld.js +771 -0
  173. package/dist/physics/HitboxWorld.js.map +1 -0
  174. package/dist/physics/KinematicBody.d.ts +157 -0
  175. package/dist/physics/KinematicBody.d.ts.map +1 -0
  176. package/dist/physics/KinematicBody.js +405 -0
  177. package/dist/physics/KinematicBody.js.map +1 -0
  178. package/dist/physics/KinematicWorld.d.ts +58 -0
  179. package/dist/physics/KinematicWorld.d.ts.map +1 -0
  180. package/dist/physics/KinematicWorld.js +246 -0
  181. package/dist/physics/KinematicWorld.js.map +1 -0
  182. package/dist/physics/index.d.ts +4 -0
  183. package/dist/physics/index.d.ts.map +1 -1
  184. package/dist/physics/index.js +4 -0
  185. package/dist/physics/index.js.map +1 -1
  186. package/dist/rendering/ForwardPass.js +2 -2
  187. package/dist/rendering/ShaderLibrary.js +2 -2
  188. package/dist/rendering/SkinnedLitMaterial.js +3 -3
  189. package/dist/rendering/SkinnedUnlitMaterial.js +3 -3
  190. package/dist/scene/Renderable.js +2 -2
  191. package/dist/scripting/VisualGraph.d.ts +2 -1
  192. package/dist/scripting/VisualGraph.d.ts.map +1 -1
  193. package/dist/scripting/VisualGraph.js +118 -1
  194. package/dist/scripting/VisualGraph.js.map +1 -1
  195. package/dist/scripting/VisualGraphContext.d.ts +123 -0
  196. package/dist/scripting/VisualGraphContext.d.ts.map +1 -0
  197. package/dist/scripting/VisualGraphContext.js +2 -0
  198. package/dist/scripting/VisualGraphContext.js.map +1 -0
  199. package/dist/scripting/VisualGraphExecutor.d.ts +6 -1
  200. package/dist/scripting/VisualGraphExecutor.d.ts.map +1 -1
  201. package/dist/scripting/VisualGraphExecutor.js +364 -7
  202. package/dist/scripting/VisualGraphExecutor.js.map +1 -1
  203. package/dist/scripting/VisualNodeCatalog.d.ts +1 -1
  204. package/dist/scripting/VisualNodeCatalog.d.ts.map +1 -1
  205. package/dist/scripting/VisualNodeCatalog.js +61 -1
  206. package/dist/scripting/VisualNodeCatalog.js.map +1 -1
  207. package/dist/scripting/index.d.ts +1 -0
  208. package/dist/scripting/index.d.ts.map +1 -1
  209. package/dist/scripting/index.js.map +1 -1
  210. package/package.json +203 -118
package/README.md CHANGED
@@ -5,17 +5,52 @@
5
5
  [![license: MIT](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-browser%203D-3178c6.svg)](https://www.typescriptlang.org/)
7
7
 
8
- Aura3D is an AI-native TypeScript 3D SDK for browser 3D apps, prompt-to-code scenes, GLB/glTF product viewers, browser-native games, Vite templates, typed asset workflows, diagnostics, screenshots, and static deployment checks.
8
+ Aura3D is an AI-native TypeScript 3D SDK for browser 3D apps, prompt-to-code scenes, GLB/glTF product viewers, browser-native game routes, Vite templates, typed asset workflows, diagnostics, screenshots, and static deployment checks.
9
9
 
10
10
  Describe the scene. Keep the TypeScript. Ship the browser app.
11
11
 
12
12
  Aura3D is built for developers and AI coding agents that need real 3D software, not a blank canvas and renderer glue. It gives agents maintained scene kits, typed GLB/glTF assets, product-viewer workflows, browser-game workflows, route-health diagnostics, screenshot evidence, and deployment checks through a public TypeScript API.
13
13
 
14
- Use Aura3D when you are building browser 3D apps, prompt-authored scenes, product configurators, GLB viewers, browser-native game showcases, static-deployed interactive websites, or AI-generated 3D scene tooling.
14
+ Use Aura3D when you are building agent-written browser 3D apps, prompt-authored scenes, product configurators, GLB viewers, browser-native game-route proofs, static-deployed interactive websites, or AI-generated 3D scene tooling.
15
15
 
16
16
  ## Current release
17
17
 
18
- `@aura3d/engine@1.0.3` removes Three.js from the root engine runtime and npm dependency graph. The default Aura3D install now uses Aura-owned browser runtime code; Three.js migration support lives in the separately installed `@aura3d/three-compat` package.
18
+ `@aura3d/engine@1.0.5` is the current public release for browser-native game routes, visible GLB animation runtime evidence, prompt-cartoon playback, AuraVoice timing packages, typed assets, diagnostics, screenshots, and readiness evidence. The root engine runtime remains free of Three.js imports; Three.js migration support lives in the separately installed `@aura3d/three-compat` package.
19
+
20
+ Aura3D 1.0.5 is a runtime foundation release, not a mature commercial game engine release. The 1.0.6 game-engine/showcase target remains release-blocked until the gates in `docs/project/aura3d-106-release-gates.md` pass.
21
+
22
+ Registry status: npm `latest` points at `@aura3d/engine@1.0.5`, `@aura3d/asset-index@1.0.5`, `@aura3d/cli@1.0.5`, and `create-aura3d@1.0.5`, so the `npx ...@latest` commands below work for external users.
23
+
24
+ ## Aura3D 1.0.5 asset catalog
25
+
26
+ Aura3D 1.0.5 includes the catalog-first asset workflow for AI coding agents. When a prompt names a real object, agents should search the hosted Aura3D catalog before writing scene code:
27
+
28
+ ```bash
29
+ npx @aura3d/cli@latest assets search "battle-worn knight helmet"
30
+ npx @aura3d/cli@latest assets resolve "battle-worn knight helmet" --name helmet
31
+ ```
32
+
33
+ The resolver pulls only verified auto-pullable candidates into the existing typed asset pipeline, then scene code uses `model(assets.helmet)`. Unverified or marketplace candidates stay as deep-links until the user approves and supplies the asset.
34
+
35
+ For game characters, use the catalog profile so the CLI filters toward animated redistributable GLB candidates and preserves catalog provenance when it registers the typed asset:
36
+
37
+ ```bash
38
+ npx @aura3d/cli@latest assets search "animated humanoid fighting character" --profile fighting-character --json
39
+ npx @aura3d/cli@latest assets resolve "animated humanoid fighting character" --name fighter --profile fighting-character
40
+ npx @aura3d/cli@latest assets validate-game --profile fighting-character --asset fighter --no-placeholders --require-license
41
+ ```
42
+
43
+ `--profile fighting-character` requires animated GLB candidates from verified CC0/CC-BY sources, applies a browser-sized triangle budget, and writes source URL, license, author/attribution, and source family into `aura.assets.json` during `assets resolve`.
44
+ ## Aura3D 1.0.5 runtime launch track
45
+
46
+ Aura3D 1.0.5 is the active runtime and animation evidence foundation for the next public showcase wave:
47
+
48
+ - `game runtime`: mutable runtime nodes, app-owned frame loops, input, kinematic bodies, hitboxes, combat events, camera direction, effects, and evidence for browser-native game routes.
49
+ - `fighting-game template`: `npx create-aura3d@latest my-fighter --template fighting-game` scaffolds a public-API playable starter using typed assets, `app.input(...)`, `app.onFrame(...)`, `game.kinematicBody(...)`, `game.combatWorld(...)`, and `app.evidence(...)`.
50
+ - `prompt animation`: `npx create-aura3d@latest my-episode --template prompt-cartoon-channel` scaffolds structured episode plans, storyboards, shot timelines, captions, visemes, render queues, and evidence for prompt-authored cartoon/video workflows. The shorter `cartoon-channel` template name remains supported.
51
+ - `AuraVoice bridge`: AuraVoice owns script/audio/caption/viseme timing; Aura3D owns typed scene generation, character performance, camera choreography, rendering, screenshots, and visual evidence.
52
+
53
+ Aura Clash requires Aura3D 1.0.5 runtime and animation evidence before it should be marketed as a polished public game showcase. Until the runtime, screenshot, route, GLB, package-smoke, and visual approval gates pass, Aura Clash remains a development showcase proving the direction of the public API.
19
54
 
20
55
  ## Install
21
56
 
@@ -56,22 +91,22 @@ import { createAuraApp, sceneKits } from "@aura3d/engine";
56
91
  - Vite 3D starter apps with route health, screenshot tests, and deploy checks.
57
92
  - Static-deployed 3D websites where proof, screenshots, and reliability matter.
58
93
 
59
- ## Flagship game showcase
94
+ ## Aura Clash development showcase
95
+
96
+ Aura Clash Arena is the active Aura3D game-runtime proof target: a 1v1 browser arena-fighter development showcase built with `@aura3d/engine` public APIs.
60
97
 
61
- World War X is Aura3D's production game proof: an original satirical 1v1 browser arena fighter built with `@aura3d/engine`.
98
+ The current showcase proves selected runtime mechanics, but it is not yet a flagship-quality game and must not be used as proof that Aura3D is comparable to Unity, Unreal, Babylon.js, or a mature commercial game engine.
62
99
 
63
- The showcase includes:
100
+ The showcase currently targets:
64
101
 
65
- - a 10-fighter G7+India+Russia+China roster;
66
- - generated fighter GLB assets;
102
+ - typed or validated stylized fighter assets;
67
103
  - typed asset members from `src/aura-assets.ts`;
68
104
  - `model(assets.x)` runtime usage;
69
- - arena primitives, lighting, effects, camera composition, and material polish;
70
- - arcade movement, hitboxes, projectiles, guard state, meter, AI pressure, and results;
71
- - Summit Remix prompt presets;
105
+ - arena composition, lighting, effects, camera framing, and material polish;
106
+ - arcade movement, hitboxes, guard state, meter, AI pressure, and results;
72
107
  - evidence routes, accessibility settings, poster capture, Playwright contracts, sitemap and robots integration, and marketing homepage placement.
73
108
 
74
- Open the route at `apps/world-war-x-showcase/`.
109
+ Open the source route at `apps/aura-clash-showcase/`. Treat the current route as a development showcase until the 1.0.6 gameplay, visual, asset, audio, performance, deployment, and docs-claim gates pass.
75
110
 
76
111
  ## 30-second product viewer
77
112
 
@@ -89,6 +124,269 @@ createAuraApp("#app", {
89
124
 
90
125
  The safe API uses generated refs such as `assets.robot`. Do not write `model("robot")`, hand-written GLB URLs, or invented asset ids.
91
126
 
127
+ ## Aura3D 1.0.5 game runtime example
128
+
129
+ Add typed assets before writing model code:
130
+
131
+ ```bash
132
+ npx @aura3d/cli@latest assets add ./assets/fighter.glb --name fighter
133
+ npx @aura3d/cli@latest assets add ./assets/opponent.glb --name opponent
134
+ ```
135
+
136
+ Then use the public game facade and stage builders:
137
+
138
+ ```ts
139
+ import {
140
+ AnimationController,
141
+ createAuraApp,
142
+ game,
143
+ games,
144
+ lights,
145
+ model,
146
+ scene
147
+ } from "@aura3d/engine";
148
+ import { assets } from "./aura-assets";
149
+
150
+ const stage = games.fighting.stagePreset("neon-dojo");
151
+ const stageIssues = games.fighting.validateStage(stage);
152
+
153
+ const fighting = game.fighting({
154
+ playerId: "player",
155
+ opponentId: "opponent",
156
+ stage: { width: stage.combatBounds.maxX - stage.combatBounds.minX },
157
+ autoListen: true
158
+ });
159
+
160
+ const app = createAuraApp("#app", {
161
+ scene: stage.nodes
162
+ .reduce((builder, node) => builder.add(node), scene())
163
+ .add(model(assets.fighter).runtime(game.runtimeNode("player", { tags: ["fighter", "local"] })))
164
+ .add(model(assets.opponent).runtime(game.runtimeNode("opponent", { tags: ["fighter", "ai"] })))
165
+ .add(lights.studio())
166
+ });
167
+
168
+ const player = app.nodes.require("player");
169
+ const opponent = app.nodes.require("opponent");
170
+ const animation = new AnimationController({
171
+ clipRegistry: assets.fighter,
172
+ requiredClips: ["Idle", "Walk", "LightPunch"],
173
+ suppressRootMotion: true
174
+ });
175
+
176
+ const touchLayout = game.touchControls({
177
+ width: window.innerWidth,
178
+ height: window.innerHeight,
179
+ buttons: [
180
+ { action: "jump", label: "Jump", binding: "TouchJump" },
181
+ { action: "light", label: "Light", binding: "TouchLight" }
182
+ ]
183
+ });
184
+
185
+ const jumpAssist = game.jumpAssist({ coyoteMs: 100, bufferMs: 120 });
186
+ const hud = game.hud.bindings([
187
+ game.hud.health({ actorId: "player", label: "Player health" }),
188
+ game.hud.health({ actorId: "opponent", label: "Opponent health" }),
189
+ game.hud.timer({ valuePath: "round.timeRemaining" }),
190
+ game.hud.debugToggle({ action: "debug", statePath: "debug.visible" })
191
+ ]);
192
+ const accessibility = [
193
+ game.accessibility.label({ targetId: "player-health", label: "Player health", live: true }),
194
+ game.accessibility.pauseControls({ actions: ["pause", "Escape"], resumeActions: ["pause", "Enter"], menuId: "pause-menu" })
195
+ ];
196
+
197
+ app.onFrame(({ dt }) => {
198
+ const snapshot = fighting.update(dt);
199
+ animation.update(dt);
200
+
201
+ jumpAssist.update(dt, {
202
+ grounded: fighting.bodies.player.grounded,
203
+ jumpPressed: fighting.input.pressed("jump")
204
+ });
205
+ if (jumpAssist.consume()) fighting.bodies.player.jump();
206
+
207
+ if (fighting.input.pressed("light")) {
208
+ animation.crossFade("LightPunch", 0.08, { restart: true });
209
+ }
210
+
211
+ player.setPosition(snapshot.player.position[0], snapshot.player.position[1], snapshot.player.position[2]);
212
+ opponent.setPosition(snapshot.opponent.position[0], snapshot.opponent.position[1], snapshot.opponent.position[2]);
213
+ });
214
+
215
+ const replayPlan = game.inputReplay(fighting.input.recorded(), { fps: 60, label: "round-1" });
216
+ const replayInput = game.input({
217
+ actions: fighting.controls.actions,
218
+ axes: fighting.controls.axes,
219
+ autoListen: false
220
+ });
221
+ const replayDriver = game.inputReplayDriver(replayInput, replayPlan);
222
+
223
+ const colliders = [
224
+ game.collider.capsule({ id: "player-body", center: fighting.bodies.player.position, radius: 0.34, height: 1.7 }),
225
+ game.collider.capsule({ id: "opponent-body", center: fighting.bodies.opponent.position, radius: 0.34, height: 1.7 })
226
+ ];
227
+ const overlay = game.debug.overlay({
228
+ runtime: app.runtime,
229
+ input: fighting.input,
230
+ bodies: [fighting.bodies.player, fighting.bodies.opponent],
231
+ combat: fighting.combat,
232
+ effects: fighting.effects,
233
+ camera: fighting.camera,
234
+ colliders,
235
+ warnings: stageIssues.map((issue) => issue.message)
236
+ });
237
+
238
+ const evidence = app.evidence({
239
+ input: fighting.input,
240
+ bodies: [fighting.bodies.player, fighting.bodies.opponent],
241
+ combat: fighting.combat,
242
+ effects: fighting.effects,
243
+ camera: fighting.camera,
244
+ hud,
245
+ accessibility,
246
+ stage: { id: stage.id, safeZones: true, bounds: stage.combatBounds, warnings: stageIssues.map((issue) => issue.message) }
247
+ });
248
+
249
+ console.log(touchLayout.controls.length, replayDriver.snapshot(), overlay.sections, evidence.systems);
250
+ ```
251
+
252
+ ## Aura3D 1.0.5 prompt-cartoon and AuraVoice example
253
+
254
+ Prompt-cartoon routes use typed assets, contract artifacts, shot playback, captions, visemes, and AuraVoice timing packages.
255
+
256
+ ```ts
257
+ import {
258
+ collectPromptAnimationEvidence,
259
+ compilePromptEpisodePlan,
260
+ createAudioStemManifest,
261
+ createAuraApp,
262
+ createAuraVoiceBridgePackage,
263
+ createAuraVoiceVisemeTrack,
264
+ createCartoonRenderOutputPackageMetadata,
265
+ createGlbBlendshapeVisemeCue,
266
+ createPrimitiveMouthVisemeCues,
267
+ createShotPlaybackPlan,
268
+ evaluatePromptAnimationPublishReadiness,
269
+ game,
270
+ installShotPlayback,
271
+ lights,
272
+ model,
273
+ scene,
274
+ sampleAuraVoiceBridgeAtTime,
275
+ validateAuraVoiceBridgePackage
276
+ } from "@aura3d/engine";
277
+ import { assets } from "./aura-assets";
278
+
279
+ const plan = compilePromptEpisodePlan({
280
+ episodeId: "moon-garden",
281
+ title: "Moon Garden Helpers",
282
+ prompt: "Two robots clean a glowing moon garden.",
283
+ language: "en",
284
+ runtime: { duration: 30, frameRate: 30, resolution: { width: 1280, height: 720 }, maxTimingDriftFrames: 1 },
285
+ characters: [
286
+ { id: "miko", name: "Miko", role: "hero", asset: assets.miko },
287
+ { id: "luma", name: "Luma", role: "sidekick", asset: assets.luma }
288
+ ],
289
+ locations: [{ id: "moon-garden", name: "Moon Garden", mood: "soft neon bedtime" }],
290
+ beats: [
291
+ {
292
+ id: "beat-001",
293
+ locationId: "moon-garden",
294
+ summary: "Miko and Luma clean the glowing weeds.",
295
+ visualIntent: "Two readable typed characters, safe captions, and gentle light.",
296
+ duration: 8,
297
+ characters: ["miko", "luma"],
298
+ dialogue: [{ speakerId: "miko", text: "The moon garden is glowing again.", emotion: "curious" }]
299
+ }
300
+ ],
301
+ route: "/episodes/moon-garden"
302
+ });
303
+
304
+ const visemes = createAuraVoiceVisemeTrack({
305
+ episodeId: plan.episodePlan.episodeId,
306
+ language: plan.episodePlan.language,
307
+ frameRate: plan.shotTimeline.frameRate,
308
+ cues: plan.dialogueTrack.lines.flatMap((line) =>
309
+ createPrimitiveMouthVisemeCues({
310
+ characterId: line.speakerId,
311
+ speakerId: line.speakerId,
312
+ lineId: line.lineId,
313
+ startTime: line.startTime,
314
+ endTime: line.endTime
315
+ }).map((cue) => createGlbBlendshapeVisemeCue(cue))
316
+ )
317
+ });
318
+
319
+ const audioStems = createAudioStemManifest({
320
+ episodeId: plan.episodePlan.episodeId,
321
+ duration: plan.dialogueTrack.duration,
322
+ stems: plan.dialogueTrack.lines.map((line) => ({
323
+ id: `audio:${line.lineId}`,
324
+ role: "dialogue",
325
+ path: line.audioFile ?? `assets/audio/${line.language}/${line.lineId}.wav`,
326
+ startTime: line.startTime,
327
+ duration: line.endTime - line.startTime,
328
+ language: line.language
329
+ }))
330
+ });
331
+
332
+ const renderOutputPackage = createCartoonRenderOutputPackageMetadata({
333
+ episodePlan: plan.episodePlan,
334
+ shotTimeline: plan.shotTimeline,
335
+ renderQueue: plan.renderQueue
336
+ });
337
+
338
+ const bridge = createAuraVoiceBridgePackage({
339
+ episodePlan: plan.episodePlan,
340
+ storyboard: plan.storyboard,
341
+ shotTimeline: plan.shotTimeline,
342
+ dialogueTrack: plan.dialogueTrack,
343
+ captionTrack: plan.captionTrack,
344
+ visemes,
345
+ audioStems,
346
+ renderQueue: plan.renderQueue,
347
+ renderOutputPackage
348
+ });
349
+ const bridgeIssues = validateAuraVoiceBridgePackage(bridge);
350
+
351
+ const playback = createShotPlaybackPlan({
352
+ timeline: plan.shotTimeline,
353
+ performance: plan.performance,
354
+ captions: plan.captionTrack,
355
+ visemes,
356
+ runtimeNodeByCharacterId: { miko: "miko", luma: "luma" },
357
+ loop: true
358
+ });
359
+
360
+ const app = createAuraApp("#app", {
361
+ scene: scene()
362
+ .add(model(assets.miko).runtime(game.runtimeNode("miko", { tags: ["character"] })))
363
+ .add(model(assets.luma).runtime(game.runtimeNode("luma", { tags: ["character"] })))
364
+ .add(lights.studio())
365
+ });
366
+ installShotPlayback(app, playback);
367
+
368
+ const sample = sampleAuraVoiceBridgeAtTime(bridge, 3);
369
+ const evidence = collectPromptAnimationEvidence({
370
+ bridgePackage: bridge,
371
+ screenshots: [
372
+ {
373
+ id: "shot-001",
374
+ time: sample.time,
375
+ path: "artifacts/screenshots/shot-001.png",
376
+ hash: "sha256:replace-with-rendered-screenshot-hash",
377
+ width: 1280,
378
+ height: 720
379
+ }
380
+ ],
381
+ routeHealth: { status: "pass" }
382
+ });
383
+ const readiness = evaluatePromptAnimationPublishReadiness(evidence);
384
+
385
+ console.log(bridgeIssues, evidence.publishReady, readiness.ready);
386
+ ```
387
+
388
+ Do not publish placeholder screenshot hashes. Deterministic render output must replace the placeholder before a prompt-cartoon or AuraVoice route is called publish-ready.
389
+
92
390
  ## Prompt-to-3D scene kits
93
391
 
94
392
  Use scene kits when an AI prompt asks for generated 3D systems rather than a supplied model.
@@ -114,7 +412,7 @@ Maintained scene-kit families include physics playgrounds, particle fountains, s
114
412
 
115
413
  ## Packages
116
414
 
117
- - `@aura3d/engine`: public TypeScript browser 3D SDK for AI-generated scenes and typed GLB/glTF assets.
415
+ - `@aura3d/engine`: public TypeScript browser 3D SDK for AI-generated scenes, runtime helpers, and typed GLB/glTF assets.
118
416
  - `@aura3d/cli`: typed GLB/glTF asset workflow, diagnostics, and deploy checks.
119
417
  - `@aura3d/react`: optional thin React adapter.
120
418
  - `create-aura3d`: Vite templates for product viewers, cinematic scenes, and mini-games.
@@ -124,7 +422,7 @@ Maintained scene-kit families include physics playgrounds, particle fountains, s
124
422
 
125
423
  Aura3D is built for the AI-assisted browser 3D era. It gives teams a source-code-first TypeScript workflow where agents generate maintainable scenes, game routes, product viewers, and deployable interactive websites.
126
424
 
127
- Aura3D combines scene kits, GLB/glTF asset typing, product viewers, browser-game systems, physics scenes, particles, material labs, data worlds, route diagnostics, screenshot workflows, and static deployment into one agent-ready SDK.
425
+ Aura3D combines scene kits, GLB/glTF asset typing, product viewers, browser-game runtime helpers, physics scenes, particles, material labs, data worlds, route diagnostics, screenshot workflows, and static deployment into one agent-ready SDK. It does not currently claim Unity, Unreal, Babylon.js, or full commercial game-engine parity.
128
426
 
129
427
  ## Documentation
130
428
 
@@ -143,6 +441,32 @@ pnpm run check:release
143
441
 
144
442
  Use release checks to confirm package integrity, generated assets, examples, and static deployment output before shipping.
145
443
 
444
+ Aura3D 1.0.5 route-specific readiness commands:
445
+
446
+ ```bash
447
+ npx @aura3d/cli@latest assets validate-game
448
+ npx @aura3d/cli@latest assets validate-cartoon
449
+ npx @aura3d/cli@latest check-deploy --dist dist
450
+ pnpm game-runtime:docs
451
+ pnpm game-runtime:template
452
+ pnpm game-runtime:package
453
+ pnpm game-runtime:release
454
+ pnpm prompt-animation:docs
455
+ pnpm prompt-animation:template
456
+ pnpm prompt-animation:package
457
+ pnpm prompt-animation:release
458
+ ```
459
+
460
+ Do not mark a game, prompt-cartoon, or AuraVoice route launch-ready from source evidence alone. Asset readiness, package smoke, browser route health, deterministic screenshots, visual review, accessibility proof, and deployment checks must also pass.
461
+
462
+ Aura3D 1.0.6 game-engine/showcase readiness is stricter:
463
+
464
+ ```bash
465
+ pnpm aura3d106:readiness
466
+ ```
467
+
468
+ Expected current state: release-blocked until the P0 gates in `docs/project/aura3d-106-release-gates.md` pass.
469
+
146
470
  ## Contributing
147
471
 
148
472
  Star the repo if you want AI-native browser 3D tooling for TypeScript, WebGL, WebGPU, GLB/glTF assets, product viewers, prompt-to-3D scenes, and deployable 3D websites. Open issues with the prompt, package version, asset source or license, commands run, route-health output, screenshots, and deploy context.
@@ -0,0 +1,57 @@
1
+ export type AnimationPlaybackDirection = 1 | -1;
2
+ export type AnimationClipEventType = "marker" | "hitbox" | "hurtbox" | "footstep" | "sfx" | "vfx" | "camera" | "state" | "custom" | (string & {});
3
+ export interface AnimationClipEvent<TName extends string = string, TPayload = unknown> {
4
+ readonly id?: string;
5
+ readonly name: TName;
6
+ readonly type?: AnimationClipEventType;
7
+ readonly time: number;
8
+ readonly duration?: number;
9
+ readonly payload?: TPayload;
10
+ readonly once?: boolean;
11
+ readonly tags?: readonly string[];
12
+ }
13
+ export interface AnimationClipEventSource<TEvent extends AnimationClipEvent = AnimationClipEvent> {
14
+ readonly id: string;
15
+ readonly duration: number;
16
+ readonly events?: readonly TEvent[];
17
+ }
18
+ export interface AnimationClipEventSamplingOptions {
19
+ readonly from: number;
20
+ readonly to: number;
21
+ readonly duration?: number;
22
+ readonly loop?: boolean;
23
+ readonly direction?: AnimationPlaybackDirection;
24
+ readonly includeStart?: boolean;
25
+ readonly includeEnd?: boolean;
26
+ readonly loopCount?: number;
27
+ readonly playbackTime?: number;
28
+ }
29
+ export interface AnimationClipEventInvocation<TEvent extends AnimationClipEvent = AnimationClipEvent, TClipId extends string = string> {
30
+ readonly clipId: TClipId;
31
+ readonly event: TEvent;
32
+ readonly time: number;
33
+ readonly previousTime: number;
34
+ readonly localTime: number;
35
+ readonly normalizedTime: number;
36
+ readonly loopCount: number;
37
+ readonly direction: AnimationPlaybackDirection;
38
+ readonly playbackTime?: number;
39
+ }
40
+ export type AnimationClipEventListener<TPayload> = (payload: TPayload) => void;
41
+ export type AnimationClipEventUnsubscribe = () => void;
42
+ export declare class AnimationEventDispatcher<TEventMap = Record<string, unknown>> {
43
+ private readonly listeners;
44
+ on<K extends Extract<keyof TEventMap, string>>(type: K, listener: AnimationClipEventListener<TEventMap[K]>): AnimationClipEventUnsubscribe;
45
+ once<K extends Extract<keyof TEventMap, string>>(type: K, listener: AnimationClipEventListener<TEventMap[K]>): AnimationClipEventUnsubscribe;
46
+ off<K extends Extract<keyof TEventMap, string>>(type: K, listener: AnimationClipEventListener<TEventMap[K]>): void;
47
+ emit<K extends Extract<keyof TEventMap, string>>(type: K, payload: TEventMap[K]): void;
48
+ clear(type?: Extract<keyof TEventMap, string>): void;
49
+ listenerCount(type?: Extract<keyof TEventMap, string>): number;
50
+ }
51
+ export declare function createAnimationClipEvent<TName extends string, TPayload = unknown>(name: TName, time: number, options?: Omit<AnimationClipEvent<TName, TPayload>, "name" | "time">): AnimationClipEvent<TName, TPayload>;
52
+ export declare function normalizeClipEvents<TEvent extends AnimationClipEvent>(events?: readonly TEvent[]): readonly TEvent[];
53
+ export declare function animationClipEventKey(clipId: string, event: AnimationClipEvent): string;
54
+ export declare function sampleClipEvents<TEvent extends AnimationClipEvent, TClipId extends string = string>(source: AnimationClipEventSource<TEvent> & {
55
+ readonly id: TClipId;
56
+ }, options: AnimationClipEventSamplingOptions): AnimationClipEventInvocation<TEvent, TClipId>[];
57
+ //# sourceMappingURL=AnimationClipEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimationClipEvents.d.ts","sourceRoot":"","sources":["../../../../packages/animation/src/AnimationClipEvents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,171 @@
1
+ export class AnimationEventDispatcher {
2
+ listeners = new Map();
3
+ on(type, listener) {
4
+ const listeners = this.listeners.get(type) ?? new Set();
5
+ listeners.add(listener);
6
+ this.listeners.set(type, listeners);
7
+ return () => {
8
+ this.off(type, listener);
9
+ };
10
+ }
11
+ once(type, listener) {
12
+ const unsubscribe = this.on(type, (payload) => {
13
+ unsubscribe();
14
+ listener(payload);
15
+ });
16
+ return unsubscribe;
17
+ }
18
+ off(type, listener) {
19
+ const listeners = this.listeners.get(type);
20
+ if (!listeners)
21
+ return;
22
+ listeners.delete(listener);
23
+ if (listeners.size === 0) {
24
+ this.listeners.delete(type);
25
+ }
26
+ }
27
+ emit(type, payload) {
28
+ const listeners = this.listeners.get(type);
29
+ if (!listeners)
30
+ return;
31
+ for (const listener of [...listeners]) {
32
+ listener(payload);
33
+ }
34
+ }
35
+ clear(type) {
36
+ if (type) {
37
+ this.listeners.delete(type);
38
+ return;
39
+ }
40
+ this.listeners.clear();
41
+ }
42
+ listenerCount(type) {
43
+ if (type) {
44
+ return this.listeners.get(type)?.size ?? 0;
45
+ }
46
+ let count = 0;
47
+ for (const listeners of this.listeners.values()) {
48
+ count += listeners.size;
49
+ }
50
+ return count;
51
+ }
52
+ }
53
+ export function createAnimationClipEvent(name, time, options = {}) {
54
+ return {
55
+ ...options,
56
+ name,
57
+ time
58
+ };
59
+ }
60
+ export function normalizeClipEvents(events = []) {
61
+ return [...events].sort((a, b) => {
62
+ if (a.time !== b.time)
63
+ return a.time - b.time;
64
+ return a.name.localeCompare(b.name);
65
+ });
66
+ }
67
+ export function animationClipEventKey(clipId, event) {
68
+ return `${clipId}:${event.id ?? event.name}:${event.type ?? "marker"}:${event.time}`;
69
+ }
70
+ export function sampleClipEvents(source, options) {
71
+ const events = normalizeClipEvents(source.events);
72
+ if (events.length === 0)
73
+ return [];
74
+ const duration = sanitizeDuration(options.duration ?? source.duration);
75
+ const direction = options.direction ?? (options.to >= options.from ? 1 : -1);
76
+ const includeStart = options.includeStart ?? false;
77
+ const includeEnd = options.includeEnd ?? true;
78
+ const loopCount = options.loopCount ?? 0;
79
+ const playbackTime = options.playbackTime;
80
+ if (duration === 0) {
81
+ return events
82
+ .filter((event) => event.time === 0 && includesBoundary(includeStart, includeEnd))
83
+ .map((event) => createInvocation(source.id, event, options.from, 0, duration, loopCount, direction, playbackTime));
84
+ }
85
+ const from = normalizeLocalTime(options.from, duration, options.loop ?? false);
86
+ const to = normalizeLocalTime(options.to, duration, options.loop ?? false);
87
+ const segments = createSamplingSegments(from, to, duration, options.loop ?? false, direction);
88
+ const invocations = [];
89
+ for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex += 1) {
90
+ const segment = segments[segmentIndex];
91
+ const segmentIncludeStart = segmentIndex === 0 ? includeStart : true;
92
+ const segmentIncludeEnd = segmentIndex === segments.length - 1 ? includeEnd : true;
93
+ const matching = events.filter((event) => eventInSegment(event.time, segment.start, segment.end, segmentIncludeStart, segmentIncludeEnd));
94
+ if (direction === -1) {
95
+ matching.reverse();
96
+ }
97
+ for (const event of matching) {
98
+ invocations.push(createInvocation(source.id, event, options.from, event.time, duration, loopCount + segment.loopOffset, direction, playbackTime));
99
+ }
100
+ }
101
+ return invocations;
102
+ }
103
+ function createSamplingSegments(from, to, duration, loop, direction) {
104
+ if (!loop) {
105
+ return [
106
+ {
107
+ start: Math.min(from, to),
108
+ end: Math.max(from, to),
109
+ loopOffset: 0
110
+ }
111
+ ];
112
+ }
113
+ if (direction === 1) {
114
+ if (to >= from) {
115
+ return [{ start: from, end: to, loopOffset: 0 }];
116
+ }
117
+ return [
118
+ { start: from, end: duration, loopOffset: 0 },
119
+ { start: 0, end: to, loopOffset: 1 }
120
+ ];
121
+ }
122
+ if (to <= from) {
123
+ return [{ start: to, end: from, loopOffset: 0 }];
124
+ }
125
+ return [
126
+ { start: 0, end: from, loopOffset: 0 },
127
+ { start: to, end: duration, loopOffset: 1 }
128
+ ];
129
+ }
130
+ function createInvocation(clipId, event, previousTime, localTime, duration, loopCount, direction, playbackTime) {
131
+ return {
132
+ clipId,
133
+ event,
134
+ time: event.time,
135
+ previousTime,
136
+ localTime,
137
+ normalizedTime: duration > 0 ? event.time / duration : 0,
138
+ loopCount,
139
+ direction,
140
+ playbackTime
141
+ };
142
+ }
143
+ function eventInSegment(time, start, end, includeStart, includeEnd) {
144
+ const startsAfter = includeStart ? time >= start : time > start;
145
+ const endsBefore = includeEnd ? time <= end : time < end;
146
+ return startsAfter && endsBefore;
147
+ }
148
+ function includesBoundary(includeStart, includeEnd) {
149
+ return includeStart || includeEnd;
150
+ }
151
+ function normalizeLocalTime(time, duration, loop) {
152
+ if (!Number.isFinite(time))
153
+ return 0;
154
+ if (!loop)
155
+ return clamp(time, 0, duration);
156
+ return positiveModulo(time, duration);
157
+ }
158
+ function sanitizeDuration(duration) {
159
+ if (!Number.isFinite(duration) || duration <= 0)
160
+ return 0;
161
+ return duration;
162
+ }
163
+ function positiveModulo(value, divisor) {
164
+ if (divisor <= 0)
165
+ return 0;
166
+ return ((value % divisor) + divisor) % divisor;
167
+ }
168
+ function clamp(value, min, max) {
169
+ return Math.min(max, Math.max(min, value));
170
+ }
171
+ //# sourceMappingURL=AnimationClipEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimationClipEvents.js","sourceRoot":"","sources":["../../../../packages/animation/src/AnimationClipEvents.ts"],"names":[],"mappings":"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"}