@woosh/meep-engine 3.16.0 → 3.17.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 (410) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  4. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  7. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  10. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  11. package/editor/view/node-graph/NodeGraphView.js +84 -8
  12. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  15. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  16. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  17. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  20. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  22. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  25. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  27. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  28. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  29. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  30. package/editor/view/particles/effect/particle-editor.css +123 -35
  31. package/package.json +1 -1
  32. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  34. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  35. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  37. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  38. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  39. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  40. package/src/core/graph/csr/CSRGraph.js +14 -6
  41. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  44. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  47. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  50. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  53. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  55. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  56. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  57. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  59. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  62. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  65. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  68. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  71. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  74. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  77. package/src/engine/animation/AnimationUtils.js +246 -246
  78. package/src/engine/animation/Animations.js +74 -74
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  80. package/src/engine/ecs/EventType.d.ts +0 -1
  81. package/src/engine/ecs/EventType.js +1 -26
  82. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  85. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  86. package/src/engine/ecs/parent/EntityNode.js +4 -9
  87. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  89. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  93. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  95. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  96. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  97. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  98. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  99. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  100. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  101. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  102. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  103. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  104. package/src/engine/graphics3/LightSystem.js +4 -8
  105. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/MeshSystem.js +9 -19
  107. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  109. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  111. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  112. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  113. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  114. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  115. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  116. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  117. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  118. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  119. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  120. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  121. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  122. package/src/shade/playground/particle_editor/README.md +43 -2
  123. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  124. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  125. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  126. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  127. package/src/shade/renderer/Renderer.js +13 -1
  128. package/src/shade/renderer/particles/DESIGN.md +104 -19
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  130. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  132. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  133. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  134. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  135. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  136. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  137. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  138. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  139. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  140. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  141. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  142. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  143. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  144. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  145. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  146. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  148. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  149. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  151. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  153. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  155. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  157. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  159. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  161. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  162. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  163. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  164. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  165. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  166. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  168. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  169. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  170. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  171. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  172. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  174. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  175. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  177. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  178. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  179. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  180. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  181. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  182. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  183. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  185. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  186. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/graph_particles.js +105 -262
  188. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  189. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  190. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  191. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  192. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  193. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  194. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  196. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  197. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  198. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  199. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  200. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  202. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  203. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  205. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  206. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  207. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  208. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  209. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  210. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  211. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  212. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  213. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  214. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  215. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  216. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  217. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  218. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  219. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  220. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  221. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  222. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  223. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  224. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  225. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  226. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  227. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  228. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  229. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  230. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  235. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  236. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  238. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  239. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  240. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  241. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  242. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  244. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  245. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  246. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  247. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  248. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  250. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  251. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  252. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  253. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  254. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  255. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  256. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  257. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  258. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  259. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  261. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  262. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  263. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  264. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  265. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  266. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  267. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  268. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  270. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  271. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  272. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  273. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  274. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  275. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  276. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  277. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  279. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  280. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  281. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  282. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  283. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  285. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  286. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  287. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  288. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  289. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  291. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
  292. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  293. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  294. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  295. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  296. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  297. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  298. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  299. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  300. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  302. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  303. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  305. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  306. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  307. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  308. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  309. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  310. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  311. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  312. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  314. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  315. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  317. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  318. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  320. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  321. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  323. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  324. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  325. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  326. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  327. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  328. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  329. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  330. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  331. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  332. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  333. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  334. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  335. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  336. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  337. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  338. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  339. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  340. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  341. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  342. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  343. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  344. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  345. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  346. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  347. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  348. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  349. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  350. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  351. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  352. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  353. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  354. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  355. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  356. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  357. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  374. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  375. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  376. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  377. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  378. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  379. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  380. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  381. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  382. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  383. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  384. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  385. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  386. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  387. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  388. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  389. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  390. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  391. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  392. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  393. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  394. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  395. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  396. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  397. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  398. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  399. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  400. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  401. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  402. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  403. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  404. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  405. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  406. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  407. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  408. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  409. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  410. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -6,40 +6,6 @@
6
6
  * @returns {ParticleOpSemantics}
7
7
  */
8
8
  export function vm_semantics_of(op: number): ParticleOpSemantics;
9
- /**
10
- * Which lane of a source operand feeds a given output lane.
11
- *
12
- * A scalar operand feeds every output lane from lane 0, a `SWIZZLE` reads the lane its pattern
13
- * names, and everything lanewise reads straight across.
14
- *
15
- * @param {number} op
16
- * @param {number} lane output lane
17
- * @param {boolean} is_scalar whether the ISA marks this source slot scalar
18
- * @param {number} pattern packed swizzle pattern, read only for `SWIZZLE`
19
- * @returns {number} lane of the source operand read into `lane`
20
- */
21
- export function vm_source_lane(op: number, lane: number, is_scalar: boolean, pattern: number): number;
22
- /**
23
- * Rewrite a swizzle pattern so its lanes past `width` name nothing new.
24
- *
25
- * A pattern's four selectors are read whatever the instruction's width, so a narrowed broadcast
26
- * still reaches as far as its widest selector — {@link swizzle_span} counts all four. Pointing the
27
- * unused ones at lane 0's selector shrinks the source run to what the live lanes actually read,
28
- * which is what frees the slots above it.
29
- *
30
- * @param {number} pattern
31
- * @param {number} width lanes the instruction still writes
32
- * @returns {number} a pattern equivalent at that width
33
- */
34
- export function vm_trim_swizzle(pattern: number, width: number): number;
35
- /**
36
- * How far into its source a swizzle reaches once trimmed to `width`.
37
- *
38
- * @param {number} pattern
39
- * @param {number} width
40
- * @returns {number}
41
- */
42
- export function vm_trimmed_swizzle_span(pattern: number, width: number): number;
43
9
  /**
44
10
  * What the optimizer is allowed to assume about each opcode.
45
11
  *
@@ -52,6 +18,11 @@ export function vm_trimmed_swizzle_span(pattern: number, width: number): number;
52
18
  * Every opcode has to appear in {@link VM_SEMANTICS} — the spec asserts it — because the safe
53
19
  * default for a new one is "assume nothing", and a table that silently omitted it would instead have
54
20
  * the optimizer assume everything.
21
+ *
22
+ * Which lane of a source feeds which lane of the result is not a property of the opcode any more:
23
+ * every register operand carries a swizzle, and `vm_operand_slot` in the ISA answers it per operand.
24
+ * What is left here is per-opcode: whether lane `i` of the result depends on lane `i` of the
25
+ * sources alone (`lanewise`), and whether every lane of the result is the same value (`broadcasts`).
55
26
  */
56
27
  /**
57
28
  * @typedef {object} ParticleOpSemantics
@@ -59,8 +30,7 @@ export function vm_trimmed_swizzle_span(pattern: number, width: number): number;
59
30
  * the RNG stream, the record, the kill flag, or where the section stops. Never removable, never
60
31
  * duplicated, never widened or narrowed.
61
32
  * @property {boolean} lanewise output lane `i` is a function of lane `i` of every non-scalar source
62
- * (and of the whole of a scalar one). The reductions and `CROSS` are not; `SWIZZLE` is lane-mapped
63
- * rather than lanewise and is handled by {@link vm_source_lane}.
33
+ * (and of the whole of a scalar one). The reductions and `CROSS` are not.
64
34
  * @property {boolean} narrowable dropping trailing output lanes leaves the remaining ones unchanged.
65
35
  * Weaker than `lanewise` — `CROSS` writes a fourth lane nothing else depends on — and not implied
66
36
  * by it for `RANDOM`, whose lanes are independent but whose count is the draw count.
@@ -75,6 +45,13 @@ export function vm_trimmed_swizzle_span(pattern: number, width: number): number;
75
45
  * on either. Correctly-rounded IEEE arithmetic qualifies; a transcendental does not — JS
76
46
  * `Math.sin` and a GPU's `sin` agree to about a part in 10^7, which is what the parity spec's
77
47
  * tolerance is for, and folding would quietly pick the CPU's answer for the GPU.
48
+ * @property {boolean} foldable_inexact the operation has a value at compile time and it is the right
49
+ * one, but only to within the rounding the two executors are allowed to differ by. Folding it is
50
+ * the fast-math trade every shading compiler offers: a constant instead of a transcendental, at
51
+ * the price of the GPU's own last bits. Never true alongside `foldable` — an operation is exact
52
+ * or it is not — and read only by `pass_fold_constants.fold_inexact`, which is off by default.
53
+ * Only lanewise operations may carry it: the fold evaluates lane `i` from lane `i` of the sources
54
+ * and has no model for a reduction.
78
55
  */
79
56
  /** @type {Map<number, ParticleOpSemantics>} */
80
57
  export const VM_SEMANTICS: Map<number, ParticleOpSemantics>;
@@ -87,8 +64,7 @@ export type ParticleOpSemantics = {
87
64
  side_effects: boolean;
88
65
  /**
89
66
  * output lane `i` is a function of lane `i` of every non-scalar source
90
- * (and of the whole of a scalar one). The reductions and `CROSS` are not; `SWIZZLE` is lane-mapped
91
- * rather than lanewise and is handled by {@link vm_source_lane }.
67
+ * (and of the whole of a scalar one). The reductions and `CROSS` are not.
92
68
  */
93
69
  lanewise: boolean;
94
70
  /**
@@ -117,5 +93,15 @@ export type ParticleOpSemantics = {
117
93
  * tolerance is for, and folding would quietly pick the CPU's answer for the GPU.
118
94
  */
119
95
  foldable: boolean;
96
+ /**
97
+ * the operation has a value at compile time and it is the right
98
+ * one, but only to within the rounding the two executors are allowed to differ by. Folding it is
99
+ * the fast-math trade every shading compiler offers: a constant instead of a transcendental, at
100
+ * the price of the GPU's own last bits. Never true alongside `foldable` — an operation is exact
101
+ * or it is not — and read only by `pass_fold_constants.fold_inexact`, which is off by default.
102
+ * Only lanewise operations may carry it: the fold evaluates lane `i` from lane `i` of the sources
103
+ * and has no model for a reduction.
104
+ */
105
+ foldable_inexact: boolean;
120
106
  };
121
107
  //# sourceMappingURL=particle_vm_semantics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"particle_vm_semantics.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_vm_semantics.js"],"names":[],"mappings":"AAgIA;;;;;;GAMG;AACH,oCAHW,MAAM,GACJ,mBAAmB,CAW/B;AAED;;;;;;;;;;;GAWG;AACH,mCANW,MAAM,QACN,MAAM,aACN,OAAO,WACP,MAAM,GACJ,MAAM,CAYlB;AAED;;;;;;;;;;;GAWG;AACH,yCAJW,MAAM,SACN,MAAM,GACJ,MAAM,CAclB;AAED;;;;;;GAMG;AACH,iDAJW,MAAM,SACN,MAAM,GACJ,MAAM,CAIlB;AA3MD;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,+CAA+C;AAC/C,2BADW,IAAI,MAAM,EAAE,mBAAmB,CAAC,CACL;;;;;;;kBAvBxB,OAAO;;;;;;cAGP,OAAO;;;;;;gBAGP,OAAO;;;;;;eAGP,OAAO;;;;;;gBAGP,OAAO;;;;;;;;cAGP,OAAO"}
1
+ {"version":3,"file":"particle_vm_semantics.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/particle_vm_semantics.js"],"names":[],"mappings":"AAoJA;;;;;;GAMG;AACH,oCAHW,MAAM,GACJ,mBAAmB,CAY/B;AAnKD;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,+CAA+C;AAC/C,2BADW,IAAI,MAAM,EAAE,mBAAmB,CAAC,CACL;;;;;;;kBA7BxB,OAAO;;;;;cAGP,OAAO;;;;;;gBAEP,OAAO;;;;;;eAGP,OAAO;;;;;;gBAGP,OAAO;;;;;;;;cAGP,OAAO;;;;;;;;;;sBAKP,OAAO"}
@@ -1,206 +1,166 @@
1
- import { VM_MAX_WIDTH, VM_OP, swizzle_span } from "../isa/ParticleVMISA.js";
2
-
3
- /**
4
- * What the optimizer is allowed to assume about each opcode.
5
- *
6
- * {@link ../isa/ParticleVMISA.js} says what an instruction *does*; this says what may be done *to*
7
- * it — whether it can be deleted when its result is unread, narrowed when its high lanes are dead,
8
- * evaluated at compile time, or recognised as a recomputation of something already in a register.
9
- * Those are four different questions and an opcode can answer them differently: `LOAD_ATTR` is
10
- * removable but not shareable across a store, `RANDOM` is neither, and `CURVE` is both.
11
- *
12
- * Every opcode has to appear in {@link VM_SEMANTICS} — the spec asserts it — because the safe
13
- * default for a new one is "assume nothing", and a table that silently omitted it would instead have
14
- * the optimizer assume everything.
15
- */
16
-
17
- /**
18
- * @typedef {object} ParticleOpSemantics
19
- * @property {boolean} side_effects execution changes something other than the destination register:
20
- * the RNG stream, the record, the kill flag, or where the section stops. Never removable, never
21
- * duplicated, never widened or narrowed.
22
- * @property {boolean} lanewise output lane `i` is a function of lane `i` of every non-scalar source
23
- * (and of the whole of a scalar one). The reductions and `CROSS` are not; `SWIZZLE` is lane-mapped
24
- * rather than lanewise and is handled by {@link vm_source_lane}.
25
- * @property {boolean} narrowable dropping trailing output lanes leaves the remaining ones unchanged.
26
- * Weaker than `lanewise` — `CROSS` writes a fourth lane nothing else depends on — and not implied
27
- * by it for `RANDOM`, whose lanes are independent but whose count is the draw count.
28
- * @property {boolean} shareable two executions with equal operand values produce equal results, so a
29
- * second one can read the first one's register instead. False for anything reading the record or
30
- * the RNG.
31
- * @property {boolean} broadcasts every lane of the destination holds the same value, by construction
32
- * rather than by what the operands happen to be. Lane `i` is then a copy of lane 0 and may be read
33
- * as one.
34
- * @property {boolean} foldable the JS reference and the WGSL interpreter are both obliged to produce
35
- * the *same bits* for this operation, so evaluating it here and baking a constant changes nothing
36
- * on either. Correctly-rounded IEEE arithmetic qualifies; a transcendental does not — JS
37
- * `Math.sin` and a GPU's `sin` agree to about a part in 10^7, which is what the parity spec's
38
- * tolerance is for, and folding would quietly pick the CPU's answer for the GPU.
39
- */
40
-
41
- /** @type {Map<number, ParticleOpSemantics>} */
42
- export const VM_SEMANTICS = new Map();
43
-
44
- /**
45
- * @param {number} op
46
- * @param {Partial<ParticleOpSemantics>} flags
47
- */
48
- function semantics(op, flags) {
49
- VM_SEMANTICS.set(op, {
50
- side_effects: false,
51
- lanewise: false,
52
- narrowable: false,
53
- shareable: false,
54
- broadcasts: false,
55
- foldable: false,
56
- ...flags,
57
- });
58
- }
59
-
60
- /** Pure element-wise arithmetic whose two executors are bit-for-bit obliged to agree. */
61
- const EXACT = { lanewise: true, narrowable: true, shareable: true, foldable: true };
62
-
63
- /** The same, minus the folding: correct to narrow and to share, but the executors may round apart. */
64
- const INEXACT = { lanewise: true, narrowable: true, shareable: true };
65
-
66
- semantics(VM_OP.HALT, { side_effects: true });
67
- semantics(VM_OP.NOP, {});
68
- semantics(VM_OP.MOV, EXACT);
69
- semantics(VM_OP.LOAD_CONST, EXACT);
70
- // Reads the record, so it is removable when dead but may not be shared across a store that could
71
- // touch the same words — which is why it is not `shareable` and the CSE pass never sees it.
72
- semantics(VM_OP.LOAD_ATTR, { lanewise: true, narrowable: true });
73
- semantics(VM_OP.STORE_ATTR, { side_effects: true });
74
- semantics(VM_OP.LOAD_BUILTIN, { lanewise: true, narrowable: true, shareable: true });
75
- semantics(VM_OP.KILL, { side_effects: true });
76
-
77
- semantics(VM_OP.ADD, EXACT);
78
- semantics(VM_OP.SUB, EXACT);
79
- semantics(VM_OP.MUL, EXACT);
80
- semantics(VM_OP.DIV, EXACT);
81
- // `a * b + c` is one rounding on hardware that contracts it into an FMA and two in the reference.
82
- semantics(VM_OP.MAD, INEXACT);
83
- semantics(VM_OP.MIN, EXACT);
84
- semantics(VM_OP.MAX, EXACT);
85
- // The reference spells it `a + (b - a) * t`; WGSL's `mix` is free to round it differently.
86
- semantics(VM_OP.MIX, INEXACT);
87
- semantics(VM_OP.CLAMP, EXACT);
88
- semantics(VM_OP.SCALE, EXACT);
89
-
90
- semantics(VM_OP.NEG, EXACT);
91
- semantics(VM_OP.ABS, EXACT);
92
- semantics(VM_OP.FLOOR, EXACT);
93
- semantics(VM_OP.FRACT, EXACT);
94
- semantics(VM_OP.SQRT, EXACT);
95
- semantics(VM_OP.SIN, INEXACT);
96
- semantics(VM_OP.COS, INEXACT);
97
- semantics(VM_OP.EXP, INEXACT);
98
- semantics(VM_OP.LOG, INEXACT);
99
- semantics(VM_OP.POW, INEXACT);
100
- semantics(VM_OP.STEP, EXACT);
101
- semantics(VM_OP.SMOOTHSTEP, INEXACT);
102
-
103
- // The reductions read every lane to write one, so there are no trailing lanes to drop.
104
- semantics(VM_OP.DOT, { shareable: true });
105
- // Three lanes of cross product plus, optionally, the zero `w`. Dropping that `w` is the one
106
- // narrowing available, and `min_width` already floors it at three.
107
- semantics(VM_OP.CROSS, { narrowable: true, shareable: true });
108
- semantics(VM_OP.LENGTH, { shareable: true });
109
- semantics(VM_OP.NORMALIZE, { shareable: true });
110
- semantics(VM_OP.DISTANCE, { shareable: true });
111
- // Lane-MAPPED rather than lanewise: output lane `i` is source lane `pattern[i]`.
112
- semantics(VM_OP.SWIZZLE, { narrowable: true, shareable: true, foldable: true });
113
-
114
- semantics(VM_OP.CMP_LT, EXACT);
115
- semantics(VM_OP.CMP_LE, EXACT);
116
- semantics(VM_OP.CMP_GT, EXACT);
117
- semantics(VM_OP.CMP_GE, EXACT);
118
- semantics(VM_OP.CMP_EQ, EXACT);
119
- semantics(VM_OP.SELECT, EXACT);
120
-
121
- // Ordered and side-effecting: it advances the shared RNG, and its width IS the number of draws it
122
- // takes. Removing, duplicating, reordering or narrowing one moves every value drawn after it.
123
- semantics(VM_OP.RANDOM, { side_effects: true });
124
- // An external WGSL symbol, but a pure function of (handle, t) — so a dead one goes and a repeated
125
- // one is shared. Every lane of the result is the same sample, which is what makes it narrowable —
126
- // and what makes it a broadcast, so a consumer reading it wide is a consumer that wants `SCALE`.
127
- semantics(VM_OP.CURVE, { lanewise: true, narrowable: true, shareable: true, broadcasts: true });
128
-
129
- /**
130
- * What may be assumed about an opcode. An unknown one is assumed to do everything, so a new opcode
131
- * is inert to the optimizer until somebody adds it to the table above.
132
- *
133
- * @param {number} op
134
- * @returns {ParticleOpSemantics}
135
- */
136
- export function vm_semantics_of(op) {
137
- return VM_SEMANTICS.get(op) ?? {
138
- side_effects: true,
139
- lanewise: false,
140
- narrowable: false,
141
- shareable: false,
142
- broadcasts: false,
143
- foldable: false,
144
- };
145
- }
146
-
147
- /**
148
- * Which lane of a source operand feeds a given output lane.
149
- *
150
- * A scalar operand feeds every output lane from lane 0, a `SWIZZLE` reads the lane its pattern
151
- * names, and everything lanewise reads straight across.
152
- *
153
- * @param {number} op
154
- * @param {number} lane output lane
155
- * @param {boolean} is_scalar whether the ISA marks this source slot scalar
156
- * @param {number} pattern packed swizzle pattern, read only for `SWIZZLE`
157
- * @returns {number} lane of the source operand read into `lane`
158
- */
159
- export function vm_source_lane(op, lane, is_scalar, pattern) {
160
- if (is_scalar) {
161
- return 0;
162
- }
163
-
164
- if (op === VM_OP.SWIZZLE) {
165
- return (pattern >> (2 * lane)) & 3;
166
- }
167
-
168
- return lane;
169
- }
170
-
171
- /**
172
- * Rewrite a swizzle pattern so its lanes past `width` name nothing new.
173
- *
174
- * A pattern's four selectors are read whatever the instruction's width, so a narrowed broadcast
175
- * still reaches as far as its widest selector — {@link swizzle_span} counts all four. Pointing the
176
- * unused ones at lane 0's selector shrinks the source run to what the live lanes actually read,
177
- * which is what frees the slots above it.
178
- *
179
- * @param {number} pattern
180
- * @param {number} width lanes the instruction still writes
181
- * @returns {number} a pattern equivalent at that width
182
- */
183
- export function vm_trim_swizzle(pattern, width) {
184
- const first = pattern & 3;
185
-
186
- let out = 0;
187
-
188
- for (let lane = 0; lane < VM_MAX_WIDTH; lane++) {
189
- const selector = lane < width ? (pattern >> (2 * lane)) & 3 : first;
190
-
191
- out |= selector << (2 * lane);
192
- }
193
-
194
- return out >>> 0;
195
- }
196
-
197
- /**
198
- * How far into its source a swizzle reaches once trimmed to `width`.
199
- *
200
- * @param {number} pattern
201
- * @param {number} width
202
- * @returns {number}
203
- */
204
- export function vm_trimmed_swizzle_span(pattern, width) {
205
- return swizzle_span(vm_trim_swizzle(pattern, width));
206
- }
1
+ import { VM_OP } from "../isa/ParticleVMISA.js";
2
+
3
+ /**
4
+ * What the optimizer is allowed to assume about each opcode.
5
+ *
6
+ * {@link ../isa/ParticleVMISA.js} says what an instruction *does*; this says what may be done *to*
7
+ * it — whether it can be deleted when its result is unread, narrowed when its high lanes are dead,
8
+ * evaluated at compile time, or recognised as a recomputation of something already in a register.
9
+ * Those are four different questions and an opcode can answer them differently: `LOAD_ATTR` is
10
+ * removable but not shareable across a store, `RANDOM` is neither, and `CURVE` is both.
11
+ *
12
+ * Every opcode has to appear in {@link VM_SEMANTICS} — the spec asserts it — because the safe
13
+ * default for a new one is "assume nothing", and a table that silently omitted it would instead have
14
+ * the optimizer assume everything.
15
+ *
16
+ * Which lane of a source feeds which lane of the result is not a property of the opcode any more:
17
+ * every register operand carries a swizzle, and `vm_operand_slot` in the ISA answers it per operand.
18
+ * What is left here is per-opcode: whether lane `i` of the result depends on lane `i` of the
19
+ * sources alone (`lanewise`), and whether every lane of the result is the same value (`broadcasts`).
20
+ */
21
+
22
+ /**
23
+ * @typedef {object} ParticleOpSemantics
24
+ * @property {boolean} side_effects execution changes something other than the destination register:
25
+ * the RNG stream, the record, the kill flag, or where the section stops. Never removable, never
26
+ * duplicated, never widened or narrowed.
27
+ * @property {boolean} lanewise output lane `i` is a function of lane `i` of every non-scalar source
28
+ * (and of the whole of a scalar one). The reductions and `CROSS` are not.
29
+ * @property {boolean} narrowable dropping trailing output lanes leaves the remaining ones unchanged.
30
+ * Weaker than `lanewise` — `CROSS` writes a fourth lane nothing else depends on — and not implied
31
+ * by it for `RANDOM`, whose lanes are independent but whose count is the draw count.
32
+ * @property {boolean} shareable two executions with equal operand values produce equal results, so a
33
+ * second one can read the first one's register instead. False for anything reading the record or
34
+ * the RNG.
35
+ * @property {boolean} broadcasts every lane of the destination holds the same value, by construction
36
+ * rather than by what the operands happen to be. Lane `i` is then a copy of lane 0 and may be read
37
+ * as one.
38
+ * @property {boolean} foldable the JS reference and the WGSL interpreter are both obliged to produce
39
+ * the *same bits* for this operation, so evaluating it here and baking a constant changes nothing
40
+ * on either. Correctly-rounded IEEE arithmetic qualifies; a transcendental does not — JS
41
+ * `Math.sin` and a GPU's `sin` agree to about a part in 10^7, which is what the parity spec's
42
+ * tolerance is for, and folding would quietly pick the CPU's answer for the GPU.
43
+ * @property {boolean} foldable_inexact the operation has a value at compile time and it is the right
44
+ * one, but only to within the rounding the two executors are allowed to differ by. Folding it is
45
+ * the fast-math trade every shading compiler offers: a constant instead of a transcendental, at
46
+ * the price of the GPU's own last bits. Never true alongside `foldable` — an operation is exact
47
+ * or it is not — and read only by `pass_fold_constants.fold_inexact`, which is off by default.
48
+ * Only lanewise operations may carry it: the fold evaluates lane `i` from lane `i` of the sources
49
+ * and has no model for a reduction.
50
+ */
51
+
52
+ /** @type {Map<number, ParticleOpSemantics>} */
53
+ export const VM_SEMANTICS = new Map();
54
+
55
+ /**
56
+ * @param {number} op
57
+ * @param {Partial<ParticleOpSemantics>} flags
58
+ */
59
+ function semantics(op, flags) {
60
+ VM_SEMANTICS.set(op, {
61
+ side_effects: false,
62
+ lanewise: false,
63
+ narrowable: false,
64
+ shareable: false,
65
+ broadcasts: false,
66
+ foldable: false,
67
+ foldable_inexact: false,
68
+ ...flags,
69
+ });
70
+ }
71
+
72
+ /** Pure element-wise arithmetic whose two executors are bit-for-bit obliged to agree. */
73
+ const EXACT = { lanewise: true, narrowable: true, shareable: true, foldable: true };
74
+
75
+ /**
76
+ * The same, except that the two executors may round apart: correct to narrow and to share, and
77
+ * foldable only under the named relaxation — see `foldable_inexact` above.
78
+ */
79
+ const INEXACT = { lanewise: true, narrowable: true, shareable: true, foldable_inexact: true };
80
+
81
+ semantics(VM_OP.HALT, { side_effects: true });
82
+ semantics(VM_OP.NOP, {});
83
+ semantics(VM_OP.MOV, EXACT);
84
+ semantics(VM_OP.LOAD_CONST, EXACT);
85
+ // Reads the record, so it is removable when dead but may not be shared across a store that could
86
+ // touch the same words — which is why it is not `shareable` and the CSE pass never sees it.
87
+ semantics(VM_OP.LOAD_ATTR, { lanewise: true, narrowable: true });
88
+ semantics(VM_OP.STORE_ATTR, { side_effects: true });
89
+ semantics(VM_OP.LOAD_BUILTIN, { lanewise: true, narrowable: true, shareable: true });
90
+ semantics(VM_OP.KILL, { side_effects: true });
91
+
92
+ semantics(VM_OP.ADD, EXACT);
93
+ semantics(VM_OP.SUB, EXACT);
94
+ semantics(VM_OP.MUL, EXACT);
95
+ semantics(VM_OP.DIV, EXACT);
96
+ // `a * b + c` is one rounding on hardware that contracts it into an FMA and two in the reference.
97
+ semantics(VM_OP.MAD, INEXACT);
98
+ semantics(VM_OP.MIN, EXACT);
99
+ semantics(VM_OP.MAX, EXACT);
100
+ // The reference spells it `a + (b - a) * t`; WGSL's `mix` is free to round it differently.
101
+ semantics(VM_OP.MIX, INEXACT);
102
+ semantics(VM_OP.CLAMP, EXACT);
103
+
104
+ semantics(VM_OP.NEG, EXACT);
105
+ semantics(VM_OP.ABS, EXACT);
106
+ semantics(VM_OP.FLOOR, EXACT);
107
+ semantics(VM_OP.FRACT, EXACT);
108
+ semantics(VM_OP.SQRT, EXACT);
109
+ semantics(VM_OP.SIN, INEXACT);
110
+ semantics(VM_OP.COS, INEXACT);
111
+ semantics(VM_OP.EXP, INEXACT);
112
+ semantics(VM_OP.LOG, INEXACT);
113
+ semantics(VM_OP.POW, INEXACT);
114
+ semantics(VM_OP.STEP, EXACT);
115
+ semantics(VM_OP.SMOOTHSTEP, INEXACT);
116
+ // `inverseSqrt` is a hardware estimate with ULPs of slack to it, and the reference divides one by
117
+ // a square root — a different computation rather than a different rounding of the same one. So it
118
+ // folds where a transcendental folds: under `fold_inexact`, and not before.
119
+ semantics(VM_OP.RSQRT, INEXACT);
120
+ semantics(VM_OP.TAN, INEXACT);
121
+ semantics(VM_OP.ASIN, INEXACT);
122
+ semantics(VM_OP.ACOS, INEXACT);
123
+ semantics(VM_OP.ATAN2, INEXACT);
124
+
125
+ // The reductions read every lane to write one, so there are no trailing lanes to drop.
126
+ semantics(VM_OP.DOT, { shareable: true });
127
+ // Three lanes of cross product plus, optionally, the zero `w`. Dropping that `w` is the one
128
+ // narrowing available, and `min_width` already floors it at three.
129
+ semantics(VM_OP.CROSS, { narrowable: true, shareable: true });
130
+ semantics(VM_OP.LENGTH, { shareable: true });
131
+ semantics(VM_OP.NORMALIZE, { shareable: true });
132
+ semantics(VM_OP.DISTANCE, { shareable: true });
133
+
134
+ semantics(VM_OP.CMP_LT, EXACT);
135
+ semantics(VM_OP.CMP_LE, EXACT);
136
+ semantics(VM_OP.CMP_GT, EXACT);
137
+ semantics(VM_OP.CMP_GE, EXACT);
138
+ semantics(VM_OP.CMP_EQ, EXACT);
139
+ semantics(VM_OP.SELECT, EXACT);
140
+
141
+ // Ordered and side-effecting: it advances the shared RNG, and its width IS the number of draws it
142
+ // takes. Removing, duplicating, reordering or narrowing one moves every value drawn after it.
143
+ semantics(VM_OP.RANDOM, { side_effects: true });
144
+ // An external WGSL symbol, but a pure function of (handle, t) — so a dead one goes and a repeated
145
+ // one is shared. Every lane of the result is the same sample, which is what makes it narrowable —
146
+ // and what makes it a broadcast, so a consumer reading it wide is a consumer that wants `.xxxx`.
147
+ semantics(VM_OP.CURVE, { lanewise: true, narrowable: true, shareable: true, broadcasts: true });
148
+
149
+ /**
150
+ * What may be assumed about an opcode. An unknown one is assumed to do everything, so a new opcode
151
+ * is inert to the optimizer until somebody adds it to the table above.
152
+ *
153
+ * @param {number} op
154
+ * @returns {ParticleOpSemantics}
155
+ */
156
+ export function vm_semantics_of(op) {
157
+ return VM_SEMANTICS.get(op) ?? {
158
+ side_effects: true,
159
+ lanewise: false,
160
+ narrowable: false,
161
+ shareable: false,
162
+ broadcasts: false,
163
+ foldable: false,
164
+ foldable_inexact: false,
165
+ };
166
+ }
@@ -0,0 +1,99 @@
1
+ export function pass_allocate_registers(instructions: number[][], context: import("./optimize_particle_program.js").ParticleOptimizerContext): number[][];
2
+ /**
3
+ * @typedef {object} ParticleRegisterSegment
4
+ * @property {number} slot the slot it occupies in the program as it stands
5
+ * @property {number} start the instruction that writes it, or `-1` for the reset
6
+ * @property {number} end the last instruction that reads it; `start` when nothing does
7
+ * @property {number} parent union-find link
8
+ * @property {number} placed the slot it is given, once the cluster is placed; `-1` until then
9
+ */
10
+ /**
11
+ * @typedef {object} ParticleRegisterShape
12
+ * @property {number[]} members segment indices
13
+ * @property {number} origin the lowest slot among the members, which the others keep their distance from
14
+ * @property {number} extent slots from the origin to one past the highest member
15
+ * @property {number} start the earliest write among the members
16
+ */
17
+ /**
18
+ * @typedef {object} ParticleRegisterSegments
19
+ * @property {ParticleRegisterSegment[]} segments
20
+ * @property {ParticleRegisterShape[]} shapes the clusters, in the order they are placed
21
+ * @property {Int32Array[]} read_segment per instruction, per source slot, the segment the operand's canonical base slot read
22
+ * @property {Uint32Array[]} read_word per instruction, per source slot, the operand in its canonical spelling
23
+ * @property {Int32Array} write_segment per instruction, the segment its destination base slot is written into
24
+ * @property {number} high_water one past the highest slot the program reaches
25
+ */
26
+ /**
27
+ * Every stretch of every slot, and which of them have to keep their distance.
28
+ *
29
+ * @param {import("./particle_program_analysis.js").ParticleDecodedInstruction[]} decoded
30
+ * @param {number} slots size of the register file
31
+ * @returns {ParticleRegisterSegments|null} `null` when an operand reaches outside the file
32
+ */
33
+ export function analyze_particle_register_segments(decoded: import("./particle_program_analysis.js").ParticleDecodedInstruction[], slots: number): ParticleRegisterSegments | null;
34
+ /** @type {string} */
35
+ export const PARTICLE_PASS_ALLOCATE_REGISTERS: string;
36
+ export type ParticleRegisterSegment = {
37
+ /**
38
+ * the slot it occupies in the program as it stands
39
+ */
40
+ slot: number;
41
+ /**
42
+ * the instruction that writes it, or `-1` for the reset
43
+ */
44
+ start: number;
45
+ /**
46
+ * the last instruction that reads it; `start` when nothing does
47
+ */
48
+ end: number;
49
+ /**
50
+ * union-find link
51
+ */
52
+ parent: number;
53
+ /**
54
+ * the slot it is given, once the cluster is placed; `-1` until then
55
+ */
56
+ placed: number;
57
+ };
58
+ export type ParticleRegisterShape = {
59
+ /**
60
+ * segment indices
61
+ */
62
+ members: number[];
63
+ /**
64
+ * the lowest slot among the members, which the others keep their distance from
65
+ */
66
+ origin: number;
67
+ /**
68
+ * slots from the origin to one past the highest member
69
+ */
70
+ extent: number;
71
+ /**
72
+ * the earliest write among the members
73
+ */
74
+ start: number;
75
+ };
76
+ export type ParticleRegisterSegments = {
77
+ segments: ParticleRegisterSegment[];
78
+ /**
79
+ * the clusters, in the order they are placed
80
+ */
81
+ shapes: ParticleRegisterShape[];
82
+ /**
83
+ * per instruction, per source slot, the segment the operand's canonical base slot read
84
+ */
85
+ read_segment: Int32Array[];
86
+ /**
87
+ * per instruction, per source slot, the operand in its canonical spelling
88
+ */
89
+ read_word: Uint32Array[];
90
+ /**
91
+ * per instruction, the segment its destination base slot is written into
92
+ */
93
+ write_segment: Int32Array;
94
+ /**
95
+ * one past the highest slot the program reaches
96
+ */
97
+ high_water: number;
98
+ };
99
+ //# sourceMappingURL=pass_allocate_registers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pass_allocate_registers.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/particles/optimizer/pass_allocate_registers.js"],"names":[],"mappings":"AA0FqC,0JAEqB;AAxB1D;;;;;;;GAOG;AAEH;;;;;;GAMG;AAEH;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,4DAJW,OAAO,gCAAgC,EAAE,0BAA0B,EAAE,SACrE,MAAM,GACJ,wBAAwB,GAAC,IAAI,CAsHzC;AAlND,qBAAqB;AACrB,+CADW,MAAM,CACoD;;;;;UA6DvD,MAAM;;;;WACN,MAAM;;;;SACN,MAAM;;;;YACN,MAAM;;;;YACN,MAAM;;;;;;aAKN,MAAM,EAAE;;;;YACR,MAAM;;;;YACN,MAAM;;;;WACN,MAAM;;;cAKN,uBAAuB,EAAE;;;;YACzB,qBAAqB,EAAE;;;;kBACvB,UAAU,EAAE;;;;eACZ,WAAW,EAAE;;;;mBACb,UAAU;;;;gBACV,MAAM"}