@woosh/meep-engine 3.16.0 → 3.17.1

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 (431) hide show
  1. package/README.md +8 -72
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  3. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  4. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  7. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  10. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  11. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  12. package/editor/view/node-graph/NodeGraphView.js +84 -8
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  15. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  16. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  17. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  20. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  22. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  25. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  27. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  28. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  29. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  30. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  31. package/editor/view/particles/effect/particle-editor.css +123 -35
  32. package/package.json +1 -1
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  34. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  35. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  37. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  38. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  39. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  40. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  41. package/src/core/graph/csr/CSRGraph.js +14 -6
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  44. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  47. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  50. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  53. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  55. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  56. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  57. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  59. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  62. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  65. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  68. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  70. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  71. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  74. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  76. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  77. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  78. package/src/engine/animation/AnimationUtils.js +246 -246
  79. package/src/engine/animation/Animations.js +74 -74
  80. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  81. package/src/engine/ecs/EventType.d.ts +0 -1
  82. package/src/engine/ecs/EventType.js +1 -26
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  85. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  86. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  87. package/src/engine/ecs/parent/EntityNode.js +4 -9
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  89. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  93. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  95. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  96. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  97. package/src/engine/ecs/transform/t64_set_rotation_axis_angle.d.ts +25 -0
  98. package/src/engine/ecs/transform/t64_set_rotation_axis_angle.d.ts.map +1 -0
  99. package/src/engine/ecs/transform/t64_set_rotation_axis_angle.js +45 -0
  100. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  101. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  102. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  103. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  104. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  105. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  106. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  107. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/LightSystem.js +4 -8
  109. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/MeshSystem.js +9 -19
  111. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  112. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  113. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  114. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  115. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  116. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  117. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  118. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  119. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  120. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  121. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  122. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  123. package/src/engine/sound/simulation/AcousticSimulator.d.ts +11 -8
  124. package/src/engine/sound/simulation/AcousticSimulator.d.ts.map +1 -1
  125. package/src/engine/sound/simulation/AcousticSimulator.js +45 -36
  126. package/src/engine/sound/simulation/README.md +2 -2
  127. package/src/engine/sound/simulation/core/OcclusionSolver.d.ts.map +1 -1
  128. package/src/engine/sound/simulation/core/VolumeField.d.ts +9 -9
  129. package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
  130. package/src/engine/sound/simulation/core/VolumeField.js +29 -13
  131. package/src/engine/sound/simulation/core/acoustic_occlusion_solve.d.ts +31 -0
  132. package/src/engine/sound/simulation/core/acoustic_occlusion_solve.d.ts.map +1 -0
  133. package/src/engine/sound/simulation/core/acoustic_occlusion_solve.js +134 -0
  134. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  135. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  136. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  137. package/src/shade/playground/particle_editor/README.md +43 -2
  138. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  139. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  140. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  141. package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
  142. package/src/shade/playground/volumetrics_froxel/main.js +6 -1
  143. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  144. package/src/shade/renderer/Renderer.js +13 -1
  145. package/src/shade/renderer/particles/DESIGN.md +104 -19
  146. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  147. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  148. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  149. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  150. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  151. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  152. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  153. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  154. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  155. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  157. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  158. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  159. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  160. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  161. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  162. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  163. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  164. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  165. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  166. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  168. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  169. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  170. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  171. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  172. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  174. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  175. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  176. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  177. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  178. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  179. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  180. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  181. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  182. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  183. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  185. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  186. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  187. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  188. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  189. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  190. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  191. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  192. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  193. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  194. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  196. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  197. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  198. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  199. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  200. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  202. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  203. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/graph_particles.js +105 -262
  205. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  206. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  207. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  208. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  209. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  210. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  211. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  212. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  213. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  214. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  215. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  216. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  217. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  218. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  219. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  220. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  221. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  222. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  223. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  224. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  225. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  226. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  227. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  228. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  229. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  230. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  235. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  236. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  237. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  238. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  239. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  240. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  241. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  242. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  243. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  244. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  245. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  246. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  247. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  248. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  249. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  250. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  251. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  252. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  253. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  254. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  255. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  256. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  257. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  258. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  259. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  261. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  262. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  263. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  264. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  265. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  266. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  267. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  268. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  270. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  271. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  272. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  273. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  274. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  275. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  276. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  277. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  278. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  279. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  280. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  281. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  282. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  283. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  285. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  286. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  287. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  288. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  289. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  291. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  292. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  293. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  294. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  295. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  296. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  297. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  298. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  299. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  300. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  302. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  303. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  305. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  306. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  307. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  308. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  309. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  310. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  311. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  312. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  314. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  315. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  317. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  318. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  320. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  321. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  323. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  324. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  325. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  326. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  327. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  328. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  329. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  330. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  331. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  332. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  333. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  334. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  335. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  336. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  337. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  338. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  339. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  340. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  341. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  342. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  343. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  344. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  345. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  346. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  347. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  348. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  349. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  350. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  351. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  352. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  353. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  354. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  355. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  356. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  357. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  374. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  375. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  376. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  377. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  378. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  379. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  380. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  381. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  382. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  383. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  384. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  385. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  386. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  387. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  388. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  389. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +7 -0
  390. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
  391. package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +7 -0
  392. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  393. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  394. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  395. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  396. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  397. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  398. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  399. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  400. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  401. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  402. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  403. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  404. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  405. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  406. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  407. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  408. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  409. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  410. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  411. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  412. package/src/engine/sound/simulation/core/OcclusionSolver.js +0 -112
  413. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  414. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  415. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  416. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  417. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  418. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  419. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  420. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  421. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  422. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  423. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +0 -89
  424. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +0 -1
  425. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  426. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  427. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  428. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  429. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  430. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  431. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Nodes lifted out of a graph, waiting to be put back into one.
3
+ *
4
+ * ## Why a fragment rather than a graph
5
+ *
6
+ * What is copied cannot be node ids: ids are pooled, so the ones a fragment was cut from are handed
7
+ * to unrelated nodes the moment the originals are deleted, and a paste that named them would wire
8
+ * itself to whatever happened to be holding them. A fragment therefore refers to its own nodes by
9
+ * **index**, and is a thing in its own right rather than a view onto the graph it came from.
10
+ *
11
+ * Nor can it be a live {@link NodeInstance}: the instance would keep pointing at the graph it is in,
12
+ * and its parameters would be shared with it — an author editing the original after copying it would
13
+ * be editing what they had copied. Parameters are cloned on the way in for the same reason a group
14
+ * clones its body on the way out.
15
+ *
16
+ * A {@link NodeDescription}, on the other hand, *is* carried by reference. A description is a type,
17
+ * shared by every instance of it, and there is nothing to copy; it is also the one part of a node
18
+ * that cannot be written down — a particle node's description carries the closure that is the whole
19
+ * of what the node does. Which is why this clipboard is an object in the page rather than text on
20
+ * the system one: what it holds is only meaningful to a canvas that shares its node library.
21
+ *
22
+ * ## Who holds one
23
+ *
24
+ * A host with several canvases over one document — the particle editor's two phases, and the body of
25
+ * every group opened inside them — builds one of these and gives it to all of them, so a copy in one
26
+ * pastes in the next. A canvas built without one gets its own, and copies to itself.
27
+ */
28
+
29
+ /**
30
+ * One node in a fragment.
31
+ *
32
+ * @typedef {object} NodeGraphFragmentNode
33
+ * @property {NodeDescription} description the type, by reference
34
+ * @property {object} parameters a deep copy, shared with nothing
35
+ * @property {number} x graph-space position it was copied from
36
+ * @property {number} y graph-space position it was copied from
37
+ */
38
+
39
+ /**
40
+ * One wire in a fragment, between two of its own nodes.
41
+ *
42
+ * @typedef {object} NodeGraphFragmentConnection
43
+ * @property {number} from index into the fragment's nodes
44
+ * @property {number} fromPort port id on that node's description
45
+ * @property {number} to index into the fragment's nodes
46
+ * @property {number} toPort port id on that node's description
47
+ */
48
+
49
+ /**
50
+ * @typedef {object} NodeGraphFragment
51
+ * @property {NodeGraphFragmentNode[]} nodes never empty — a fragment with no nodes is `null`
52
+ * @property {NodeGraphFragmentConnection[]} connections
53
+ */
54
+
55
+ /**
56
+ * How far each repeat paste of the same content steps, in graph-space units.
57
+ *
58
+ * Enough to see the copy is a second thing rather than a redraw of the first, and small enough that
59
+ * it lands next to what it came from rather than somewhere else entirely.
60
+ *
61
+ * @type {number}
62
+ */
63
+ export const NODE_GRAPH_PASTE_STEP = 32;
64
+
65
+ /**
66
+ * What was copied, and how many times it has been put down since.
67
+ */
68
+ export class NodeGraphClipboard {
69
+ /**
70
+ * @type {NodeGraphFragment|null}
71
+ */
72
+ #fragment = null;
73
+
74
+ /**
75
+ * @type {number}
76
+ */
77
+ #pastes = 0;
78
+
79
+ /**
80
+ * How many times what is held has been pasted already.
81
+ *
82
+ * A paste lands in the middle of what the author is looking at, so a second one would land
83
+ * exactly on top of the first and read as nothing having happened. The count is what steps it
84
+ * aside; see {@link NODE_GRAPH_PASTE_STEP}.
85
+ *
86
+ * @returns {number}
87
+ */
88
+ get pastes() {
89
+ return this.#pastes;
90
+ }
91
+
92
+ /**
93
+ * @returns {boolean}
94
+ */
95
+ isEmpty() {
96
+ return this.#fragment === null;
97
+ }
98
+
99
+ /**
100
+ * @returns {NodeGraphFragment|null}
101
+ */
102
+ read() {
103
+ return this.#fragment;
104
+ }
105
+
106
+ /**
107
+ * Replace what is held. New content starts its paste count over, because the first paste of
108
+ * something new belongs where the author is looking rather than however far the last thing had
109
+ * walked.
110
+ *
111
+ * @param {NodeGraphFragment} fragment
112
+ */
113
+ write(fragment) {
114
+ this.#fragment = fragment;
115
+ this.#pastes = 0;
116
+ }
117
+
118
+ /**
119
+ * Record that what is held has been put down. Called by whoever is pasting it, once the paste is
120
+ * going ahead — a paste a canvas refused must not move the next one aside.
121
+ */
122
+ notePaste() {
123
+ this.#pastes++;
124
+ }
125
+
126
+ clear() {
127
+ this.#fragment = null;
128
+ this.#pastes = 0;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Take a copy of some of a graph.
134
+ *
135
+ * The wires that come along are the ones the fragment holds whole — both ends among the copied
136
+ * nodes. A wire with one end outside cannot be brought back: the node it reached is not part of
137
+ * what was copied, and a paste elsewhere in the graph, or in another graph entirely, has nothing to
138
+ * attach it to.
139
+ *
140
+ * @param {object} params
141
+ * @param {NodeGraph} params.graph
142
+ * @param {NodeGraphVisualData} [params.visual] where the nodes are; without it, everything is at the
143
+ * origin and a paste arranges nothing
144
+ * @param {Iterable<number>} params.nodes ids to copy; ones that are not in the graph are skipped
145
+ * @param {function(NodeInstance):boolean} [params.copyable] whether a node may be had a second of.
146
+ * Everything, by default. A host with node types that exist once per graph — a group body's
147
+ * two boundary blocks — says so here, and they are left out rather than the whole copy being
148
+ * refused.
149
+ * @returns {NodeGraphFragment|null} `null` when nothing was copied, so that a copy of nothing can be
150
+ * told from a copy of something and left to leave the clipboard alone
151
+ */
152
+ export function node_graph_fragment_from_nodes({ graph, visual, nodes, copyable = () => true }) {
153
+ /** @type {Map<number, number>} node id -> its index in the fragment */
154
+ const index = new Map();
155
+
156
+ /** @type {NodeGraphFragmentNode[]} */
157
+ const records = [];
158
+
159
+ for (const id of nodes) {
160
+ if (index.has(id)) {
161
+ // a selection should not hold one node twice, and a fragment must not whatever it does
162
+ continue;
163
+ }
164
+
165
+ const node = graph.getNode(id);
166
+
167
+ if (node === undefined || !copyable(node)) {
168
+ continue;
169
+ }
170
+
171
+ const placed = visual === undefined ? undefined : visual.getNode(id);
172
+
173
+ index.set(id, records.length);
174
+
175
+ records.push({
176
+ description: node.description,
177
+ // deeply: a copy must not share so much as a gradient stop with what it was copied from
178
+ parameters: structuredClone(node.parameters),
179
+ x: placed?.dimensions.position.x ?? 0,
180
+ y: placed?.dimensions.position.y ?? 0,
181
+ });
182
+ }
183
+
184
+ if (records.length === 0) {
185
+ return null;
186
+ }
187
+
188
+ /** @type {NodeGraphFragmentConnection[]} */
189
+ const connections = [];
190
+
191
+ graph.traverseConnections(connection => {
192
+ const from = index.get(connection.source.instance.id);
193
+ const to = index.get(connection.target.instance.id);
194
+
195
+ if (from === undefined || to === undefined) {
196
+ return;
197
+ }
198
+
199
+ connections.push({
200
+ from,
201
+ fromPort: connection.source.port.id,
202
+ to,
203
+ toPort: connection.target.port.id,
204
+ });
205
+ });
206
+
207
+ return { nodes: records, connections };
208
+ }
209
+
210
+ /**
211
+ * The middle of a fragment, in the graph space it was copied from.
212
+ *
213
+ * What a paste puts where the author is looking, so that what lands is centred on the view rather
214
+ * than hanging off one corner of it.
215
+ *
216
+ * @param {NodeGraphFragment} fragment
217
+ * @returns {{x: number, y: number}}
218
+ */
219
+ export function node_graph_fragment_centre(fragment) {
220
+ let x = 0;
221
+ let y = 0;
222
+
223
+ for (const node of fragment.nodes) {
224
+ x += node.x;
225
+ y += node.y;
226
+ }
227
+
228
+ const count = fragment.nodes.length;
229
+
230
+ return count === 0 ? { x: 0, y: 0 } : { x: x / count, y: y / count };
231
+ }
@@ -28,8 +28,14 @@ export class NodeGraphEditorView extends View {
28
28
  * type the menu places, so a node arrives ready to compile rather than to repair
29
29
  * @param {boolean} [readOnly] show the graph without offering to change it; see
30
30
  * {@link NodeGraphView}. Turns off the add-node menu and the editing shortcuts too.
31
+ * @param {NodeGraphClipboard} [clipboard] what `Ctrl+C` writes and `Ctrl+V` reads. A host with
32
+ * several canvases over one document passes one to all of them, so a copy taken in one
33
+ * pastes in the next; on its own, a canvas gets one of its own and copies to itself.
34
+ * @param {function(NodeInstance):boolean} [copyable] whether a node may be had a second of, for
35
+ * a host with types that exist once per graph. See
36
+ * {@link node_graph_fragment_from_nodes}.
31
37
  */
32
- constructor({ graph, nodeRegistry, visual, camera, actions, actionProcessor, parameterViewFactory, portDataType, minimap, library, readOnly }: NodeGraph);
38
+ constructor({ graph, nodeRegistry, visual, camera, actions, actionProcessor, parameterViewFactory, portDataType, minimap, library, readOnly, clipboard, copyable }: NodeGraph);
33
39
  /**
34
40
  * @readonly
35
41
  */
@@ -43,6 +49,17 @@ export class NodeGraphEditorView extends View {
43
49
  * @type {ActionProcessor}
44
50
  */
45
51
  actionProcessor: ActionProcessor<any, any>;
52
+ /**
53
+ * What a copy is written to and a paste read from. Shared with the host's other canvases
54
+ * when it supplied one.
55
+ *
56
+ * @type {NodeGraphClipboard}
57
+ */
58
+ clipboard: NodeGraphClipboard;
59
+ /**
60
+ * @type {function(NodeInstance):boolean}
61
+ */
62
+ copyable: (arg0: NodeInstance) => boolean;
46
63
  /**
47
64
  *
48
65
  * @type {NodeGraphSelection}
@@ -181,11 +198,52 @@ export class NodeGraphEditorView extends View {
181
198
  * queues, so nothing has been removed on return
182
199
  */
183
200
  deleteSelection(): Promise<any>;
201
+ /**
202
+ * Take a copy of the selected nodes, and of every wire they hold whole.
203
+ *
204
+ * Reading, not editing, so a read-only canvas offers it: opening one of a library's own groups
205
+ * to take a copy of what is inside it is the point of being able to open them.
206
+ *
207
+ * @returns {boolean} whether anything was copied. A selection with nothing copyable in it leaves
208
+ * the clipboard alone rather than emptying it, which is the one outcome an author
209
+ * asking for a copy certainly did not want.
210
+ */
211
+ copySelection(): boolean;
212
+ /**
213
+ * Put what was copied into this graph, in the middle of what the author is looking at.
214
+ *
215
+ * Where a paste lands is the one decision here. It goes to the middle of the view rather than
216
+ * back where it was copied from, for the same reason a node added from the menu with no position
217
+ * does: what arrives has to be somewhere the author can see it, and the place it was copied from
218
+ * may be a long way off screen — a copy taken in one phase and pasted in the other has no
219
+ * meaningful "back where it was" at all. The arrangement inside the fragment is kept exactly; it
220
+ * is the whole of it that moves. A repeat paste of the same content steps aside by
221
+ * {@link NODE_GRAPH_PASTE_STEP} so that copies do not hide each other.
222
+ *
223
+ * @returns {Promise<NodeInstance[]>} the nodes that landed, once the timeline has applied them;
224
+ * empty when there was nothing on the clipboard
225
+ * @throws if this canvas is read-only
226
+ */
227
+ paste(): Promise<NodeInstance[]>;
228
+ /**
229
+ * A second of everything selected, beside the originals.
230
+ *
231
+ * Beside rather than in the middle of the view, which is where {@link #paste} puts things: a
232
+ * duplicate is a second of something the author is already looking at, and centring it would
233
+ * take it away from the thing it is a second of. The clipboard is not touched — `Ctrl+D` is not
234
+ * a copy, and it must not cost the author whatever they had copied earlier.
235
+ *
236
+ * @returns {Promise<NodeInstance[]>} the new nodes; empty when nothing selected could be had a
237
+ * second of
238
+ * @throws if this canvas is read-only
239
+ */
240
+ duplicateSelection(): Promise<NodeInstance[]>;
184
241
  cameraContainAll(): void;
185
242
  #private;
186
243
  }
187
244
  import View from "../../../src/view/View.js";
188
245
  import { ActionProcessor } from "../../../src/core/process/undo/ActionProcessor.js";
246
+ import { NodeGraphClipboard } from "./NodeGraphClipboard.js";
189
247
  import { NodeGraphSelection } from "./NodeGraphSelection.js";
190
248
  import { NodeGraphCamera } from "./NodeGraphView.js";
191
249
  import { NodeDescriptionVisualRegistry } from "../../../src/core/model/node-graph/visual/NodeDescriptionVisualRegistry.js";
@@ -1 +1 @@
1
- {"version":3,"file":"NodeGraphEditorView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphEditorView.js"],"names":[],"mappings":"AA4CA;IAyBI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,0JAiOC;IAvRD;;OAEG;IACH,iBAWE;IAuDE;;OAEG;IACH,UAFU,OAAO,CAEO;IAExB;;;OAGG;IACH,2CAAsC;IAEtC;;;OAGG;IACH,WAFU,kBAAkB,CAEa;IAEzC;;;OAGG;IACH,QAFU,eAAe,CAEL;IACpB;;;OAGG;IACH,4BAAoB;IAEpB;;;OAGG;IACH,iBAAkB;IAElB,mBAAuC;IAYvC;;;OAGG;IACH,gBAFU,6BAA6B,CAEH;IAepC;;OAEG;IACH,WAFU,aAAa,CAEG;IA2E1B;;;;;;;;OAQG;IACH,SAFU,oBAAoB,GAAC,IAAI,CAEhB;IA4BnB;;;;;OAKG;IACH,YAFU,uBAAuB,GAAC,IAAI,CAEhB;IAEtB;;;;;;;;;;OAUG;IACH,aAFU,qBAAqB,GAAC,IAAI,CAEb;IAgF3B;;;;;;;;;;;;;;;OAeG;IACH;QAP4B,CAAC,GAAlB,MAAM;QACW,CAAC,GAAlB,MAAM;QACW,UAAU,GAA3B,MAAM;QAC6B,QAAQ;QAC7B,IAAI;QAChB,qBAAqB,CAuBjC;IAED;;;;;;;;;;;;OAYG;IACH,eAWC;IAED;;;;;;;;;OASG;IACH,4BAFa,OAAO,CAInB;IAED;;;;;;;;;;;;;OAaG;IACH;QAN4B,CAAC,GAAlB,MAAM;QACW,CAAC,GAAlB,MAAM;QACW,UAAU,GAA3B,MAAM;QACJ,qBAAqB,CA6BjC;IAED;;;OAGG;IACH,0BAFa,OAAO,CAQnB;IAED;;;;;OAKG;IACH,gCA8BC;IAED,yBAuDC;;CACJ;iBAtmBgB,2BAA2B;gCAHZ,mDAAmD;mCAOhD,yBAAyB;gCAFb,oBAAoB;8CAS5D,4EAA4E;8BATpC,oBAAoB;qCAC9B,2BAA2B;wCAexB,8BAA8B;oBALlD,mCAAmC"}
1
+ {"version":3,"file":"NodeGraphEditorView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphEditorView.js"],"names":[],"mappings":"AAmDA;IAyBI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,+KAiSC;IA7VD;;OAEG;IACH,iBAWE;IA+DE;;OAEG;IACH,UAFU,OAAO,CAEO;IAExB;;;OAGG;IACH,2CAAsC;IAEtC;;;;;OAKG;IACH,WAFU,kBAAkB,CAEF;IAE1B;;OAEG;IACH,kCAFiC,OAAO,CAEA;IAExC;;;OAGG;IACH,WAFU,kBAAkB,CAEa;IAEzC;;;OAGG;IACH,QAFU,eAAe,CAEL;IACpB;;;OAGG;IACH,4BAAoB;IAEpB;;;OAGG;IACH,iBAAkB;IAElB,mBAAuC;IAYvC;;;OAGG;IACH,gBAFU,6BAA6B,CAEH;IAepC;;OAEG;IACH,WAFU,aAAa,CAEG;IA4H1B;;;;;;;;OAQG;IACH,SAFU,oBAAoB,GAAC,IAAI,CAEhB;IA4BnB;;;;;OAKG;IACH,YAFU,uBAAuB,GAAC,IAAI,CAEhB;IAEtB;;;;;;;;;;OAUG;IACH,aAFU,qBAAqB,GAAC,IAAI,CAEb;IAgF3B;;;;;;;;;;;;;;;OAeG;IACH;QAP4B,CAAC,GAAlB,MAAM;QACW,CAAC,GAAlB,MAAM;QACW,UAAU,GAA3B,MAAM;QAC6B,QAAQ;QAC7B,IAAI;QAChB,qBAAqB,CAwBjC;IAED;;;;;;;;;;;;OAYG;IACH,eAWC;IAED;;;;;;;;;OASG;IACH,4BAFa,OAAO,CAInB;IAED;;;;;;;;;;;;;OAaG;IACH;QAN4B,CAAC,GAAlB,MAAM;QACW,CAAC,GAAlB,MAAM;QACW,UAAU,GAA3B,MAAM;QACJ,qBAAqB,CA6BjC;IAED;;;OAGG;IACH,0BAFa,OAAO,CAQnB;IAED;;;;;OAKG;IACH,gCA8BC;IAED;;;;;;;;;OASG;IACH,iBAJa,OAAO,CAmBnB;IAED;;;;;;;;;;;;;;OAcG;IACH,SAJa,QAAQ,cAAc,CAAC,CAiCnC;IAED;;;;;;;;;;;OAWG;IACH,sBAJa,QAAQ,cAAc,CAAC,CAqBnC;IA+DD,yBAuDC;;CACJ;iBAz1BgB,2BAA2B;gCAHZ,mDAAmD;mCA4B5E,yBAAyB;mCArBG,yBAAyB;gCAFb,oBAAoB;8CAS5D,4EAA4E;8BATpC,oBAAoB;qCAC9B,2BAA2B;wCAexB,8BAA8B;oBALlD,mCAAmC"}
@@ -21,8 +21,15 @@ import Vector2 from "../../../src/core/geom/Vector2.js";
21
21
  import ButtonView from "../../../src/view/elements/button/ButtonView.js";
22
22
  import EmptyView from "../../../src/view/elements/EmptyView.js";
23
23
  import { PortDirection } from "../../../src/core/model/node-graph/node/PortDirection.js";
24
- import { ConnectionCreateAction } from "./actions/ConnectionCreateAction.js";
24
+ import { connection_bind_actions } from "./actions/connection_bind_actions.js";
25
25
  import { NodeGraphSearchMenuView } from "./NodeGraphSearchMenuView.js";
26
+ import { ConnectionCreateAction } from "./actions/ConnectionCreateAction.js";
27
+ import {
28
+ NODE_GRAPH_PASTE_STEP,
29
+ NodeGraphClipboard,
30
+ node_graph_fragment_centre,
31
+ node_graph_fragment_from_nodes,
32
+ } from "./NodeGraphClipboard.js";
26
33
 
27
34
  /**
28
35
  * Whether a port could take a value of this type, knowing nothing about the graph's domain: the same
@@ -96,6 +103,12 @@ export class NodeGraphEditorView extends View {
96
103
  * type the menu places, so a node arrives ready to compile rather than to repair
97
104
  * @param {boolean} [readOnly] show the graph without offering to change it; see
98
105
  * {@link NodeGraphView}. Turns off the add-node menu and the editing shortcuts too.
106
+ * @param {NodeGraphClipboard} [clipboard] what `Ctrl+C` writes and `Ctrl+V` reads. A host with
107
+ * several canvases over one document passes one to all of them, so a copy taken in one
108
+ * pastes in the next; on its own, a canvas gets one of its own and copies to itself.
109
+ * @param {function(NodeInstance):boolean} [copyable] whether a node may be had a second of, for
110
+ * a host with types that exist once per graph. See
111
+ * {@link node_graph_fragment_from_nodes}.
99
112
  */
100
113
  constructor({
101
114
  graph,
@@ -108,7 +121,9 @@ export class NodeGraphEditorView extends View {
108
121
  portDataType = undefined,
109
122
  minimap = true,
110
123
  library = undefined,
111
- readOnly = false
124
+ readOnly = false,
125
+ clipboard = new NodeGraphClipboard(),
126
+ copyable = undefined
112
127
  }) {
113
128
  super();
114
129
 
@@ -123,6 +138,19 @@ export class NodeGraphEditorView extends View {
123
138
  */
124
139
  this.actionProcessor = actionProcessor;
125
140
 
141
+ /**
142
+ * What a copy is written to and a paste read from. Shared with the host's other canvases
143
+ * when it supplied one.
144
+ *
145
+ * @type {NodeGraphClipboard}
146
+ */
147
+ this.clipboard = clipboard;
148
+
149
+ /**
150
+ * @type {function(NodeInstance):boolean}
151
+ */
152
+ this.copyable = copyable ?? (() => true);
153
+
126
154
  /**
127
155
  *
128
156
  * @type {NodeGraphSelection}
@@ -230,11 +258,60 @@ export class NodeGraphEditorView extends View {
230
258
  event.stopPropagation();
231
259
 
232
260
  actionProcessor.undo();
233
- } else if (event.keyCode === KeyCodes.y) {
261
+
262
+ return;
263
+ }
264
+
265
+ if (event.keyCode === KeyCodes.y) {
234
266
  event.preventDefault();
235
267
  event.stopPropagation();
236
268
 
237
269
  actionProcessor.redo();
270
+
271
+ return;
272
+ }
273
+
274
+ // The clipboard's three want Ctrl and nothing else. `AltGr` is `Ctrl+Alt` on a European
275
+ // keyboard, so a canvas that answered that combination would copy every time an author
276
+ // typed one of the characters behind it; and `Ctrl+Shift+C` belongs to the browser.
277
+ if (event.shiftKey || event.altKey) {
278
+ return;
279
+ }
280
+
281
+ // Copying reads the graph, so a locked group body offers it: taking a copy of something
282
+ // out of one of the library's own groups and putting it in a graph of your own is the
283
+ // point of being able to open them. Putting something *into* one is not.
284
+ if (event.keyCode === KeyCodes.c) {
285
+ event.preventDefault();
286
+ event.stopPropagation();
287
+
288
+ this.copySelection();
289
+
290
+ return;
291
+ }
292
+
293
+ if (readOnly) {
294
+ return;
295
+ }
296
+
297
+ // `Ctrl+D` is the browser's bookmark shortcut, so it is swallowed whether or not there
298
+ // is anything selected to duplicate — leaving it through on an empty selection would
299
+ // mean the canvas sometimes bookmarked the page instead.
300
+ if (event.keyCode === KeyCodes.d) {
301
+ event.preventDefault();
302
+ event.stopPropagation();
303
+
304
+ this.duplicateSelection()
305
+ .catch(e => console.error("could not duplicate the selection", e));
306
+
307
+ return;
308
+ }
309
+
310
+ if (event.keyCode === KeyCodes.v) {
311
+ event.preventDefault();
312
+ event.stopPropagation();
313
+
314
+ this.paste().catch(e => console.error("could not paste", e));
238
315
  }
239
316
  });
240
317
 
@@ -419,12 +496,13 @@ export class NodeGraphEditorView extends View {
419
496
  const outgoing = endpoint.port.direction === PortDirection.Out;
420
497
 
421
498
  // `addNode` marked the timeline and has not marked it again, so this joins the same step
422
- await this.actionProcessor.do(new ConnectionCreateAction(
499
+ await this.actionProcessor.doMany(connection_bind_actions(
423
500
  this.graph,
424
501
  outgoing ? endpoint.instance.id : node.id,
425
502
  outgoing ? endpoint.port.id : port.id,
426
503
  outgoing ? node.id : endpoint.instance.id,
427
- outgoing ? port.id : endpoint.port.id
504
+ outgoing ? port.id : endpoint.port.id,
505
+ this.visual
428
506
  ));
429
507
 
430
508
  return node;
@@ -562,6 +640,171 @@ export class NodeGraphEditorView extends View {
562
640
  await this.actionProcessor.doMany(actions);
563
641
  }
564
642
 
643
+ /**
644
+ * Take a copy of the selected nodes, and of every wire they hold whole.
645
+ *
646
+ * Reading, not editing, so a read-only canvas offers it: opening one of a library's own groups
647
+ * to take a copy of what is inside it is the point of being able to open them.
648
+ *
649
+ * @returns {boolean} whether anything was copied. A selection with nothing copyable in it leaves
650
+ * the clipboard alone rather than emptying it, which is the one outcome an author
651
+ * asking for a copy certainly did not want.
652
+ */
653
+ copySelection() {
654
+ const fragment = node_graph_fragment_from_nodes({
655
+ graph: this.graph,
656
+ visual: this.visual,
657
+ nodes: this.selection.nodes.asArray(),
658
+ copyable: this.copyable,
659
+ });
660
+
661
+ if (fragment === null) {
662
+ return false;
663
+ }
664
+
665
+ this.clipboard.write(fragment);
666
+
667
+ return true;
668
+ }
669
+
670
+ /**
671
+ * Put what was copied into this graph, in the middle of what the author is looking at.
672
+ *
673
+ * Where a paste lands is the one decision here. It goes to the middle of the view rather than
674
+ * back where it was copied from, for the same reason a node added from the menu with no position
675
+ * does: what arrives has to be somewhere the author can see it, and the place it was copied from
676
+ * may be a long way off screen — a copy taken in one phase and pasted in the other has no
677
+ * meaningful "back where it was" at all. The arrangement inside the fragment is kept exactly; it
678
+ * is the whole of it that moves. A repeat paste of the same content steps aside by
679
+ * {@link NODE_GRAPH_PASTE_STEP} so that copies do not hide each other.
680
+ *
681
+ * @returns {Promise<NodeInstance[]>} the nodes that landed, once the timeline has applied them;
682
+ * empty when there was nothing on the clipboard
683
+ * @throws if this canvas is read-only
684
+ */
685
+ async paste() {
686
+ if (this.readOnly) {
687
+ throw new Error("This graph is read-only, so nothing can be pasted into it.");
688
+ }
689
+
690
+ const clipboard = this.clipboard;
691
+
692
+ const fragment = clipboard.read();
693
+
694
+ if (fragment === null) {
695
+ return [];
696
+ }
697
+
698
+ const centre = node_graph_fragment_centre(fragment);
699
+ const target = this.viewCentreInGraphSpace();
700
+
701
+ const step = clipboard.pastes * NODE_GRAPH_PASTE_STEP;
702
+
703
+ // before the placing rather than after it: the timeline queues, so two pastes issued in one
704
+ // tick — which is what holding Ctrl+V down is — would otherwise both read the same count and
705
+ // land on top of each other
706
+ clipboard.notePaste();
707
+
708
+ return this.#placeFragment(
709
+ fragment,
710
+ target.x - centre.x + step,
711
+ target.y - centre.y + step,
712
+ 'paste'
713
+ );
714
+ }
715
+
716
+ /**
717
+ * A second of everything selected, beside the originals.
718
+ *
719
+ * Beside rather than in the middle of the view, which is where {@link #paste} puts things: a
720
+ * duplicate is a second of something the author is already looking at, and centring it would
721
+ * take it away from the thing it is a second of. The clipboard is not touched — `Ctrl+D` is not
722
+ * a copy, and it must not cost the author whatever they had copied earlier.
723
+ *
724
+ * @returns {Promise<NodeInstance[]>} the new nodes; empty when nothing selected could be had a
725
+ * second of
726
+ * @throws if this canvas is read-only
727
+ */
728
+ async duplicateSelection() {
729
+ if (this.readOnly) {
730
+ throw new Error("This graph is read-only, so nothing in it can be duplicated.");
731
+ }
732
+
733
+ const fragment = node_graph_fragment_from_nodes({
734
+ graph: this.graph,
735
+ visual: this.visual,
736
+ nodes: this.selection.nodes.asArray(),
737
+ copyable: this.copyable,
738
+ });
739
+
740
+ if (fragment === null) {
741
+ return [];
742
+ }
743
+
744
+ return this.#placeFragment(fragment, NODE_GRAPH_PASTE_STEP, NODE_GRAPH_PASTE_STEP, 'duplicate');
745
+ }
746
+
747
+ /**
748
+ * Build a fragment into this graph, offset, as one undoable step, and leave it selected.
749
+ *
750
+ * Two batches under one mark, because the wires need ids the creates have not handed out yet —
751
+ * the same shape an ungrouping has, and for the same reason. What is selected afterwards is what
752
+ * just arrived, so it can be dragged into place without being hunted for first.
753
+ *
754
+ * @param {import("./NodeGraphClipboard.js").NodeGraphFragment} fragment
755
+ * @param {number} offset_x graph-space
756
+ * @param {number} offset_y graph-space
757
+ * @param {string} label what the step is called on the timeline
758
+ * @returns {Promise<NodeInstance[]>}
759
+ */
760
+ async #placeFragment(fragment, offset_x, offset_y, label) {
761
+ const graph = this.graph;
762
+ const visual = this.visual;
763
+
764
+ // A canvas draws a node in a box generated from its type, and throws when it has none — so a
765
+ // fragment carrying a type this canvas has never drawn would fail from inside the timeline,
766
+ // half-way through a step. Which is reachable: the clipboard is shared between canvases, and
767
+ // a host's canvases need not have been built from the same set of types. Generating a box is
768
+ // arithmetic over port and parameter counts, keyed by the description, so telling a registry
769
+ // about a type it already knows costs nothing.
770
+ for (const record of fragment.nodes) {
771
+ this.visualRegistry.generate(record.description);
772
+ }
773
+
774
+ const creates = fragment.nodes.map(record => new NodeCreateAction(
775
+ graph,
776
+ visual,
777
+ this.visualRegistry,
778
+ record.description,
779
+ record.x + offset_x,
780
+ record.y + offset_y,
781
+ // cloned again on the way out: one fragment pasted twice must not hand both copies the
782
+ // same parameter objects, nor either of them the clipboard's
783
+ structuredClone(record.parameters)
784
+ ));
785
+
786
+ this.actionProcessor.mark(label);
787
+
788
+ await this.actionProcessor.doMany(creates);
789
+
790
+ const nodes = creates.map(create => create.node);
791
+
792
+ const wires = fragment.connections.map(wire => new ConnectionCreateAction(
793
+ graph,
794
+ nodes[wire.from].id,
795
+ wire.fromPort,
796
+ nodes[wire.to].id,
797
+ wire.toPort
798
+ ));
799
+
800
+ // `mark` has not been called again, so this joins the same step
801
+ wires.push(new SelectionSetAction(this.selection, nodes.map(node => node.id), []));
802
+
803
+ await this.actionProcessor.doMany(wires);
804
+
805
+ return nodes;
806
+ }
807
+
565
808
  cameraContainAll() {
566
809
  /**
567
810
  *
@@ -1 +1 @@
1
- {"version":3,"file":"NodeGraphView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphView.js"],"names":[],"mappings":";AAyGA;IA4GI;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gJA8cC;IA7kBD,mBAAmC;IAEnC;;;;;;;;;OASG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAQ,CAAC,CAET;IAmBtB;;;OAGG;IACH,qBAFmB,yBAAyB,cAE/B;IAEb;;OAEG;IACH,iBA0DE;IAEF;;;;OAIG;IACH,mBAFU,OAAO,CAEA;IAmCb;;;OAGG;IACH,2CAAsC;IAMtC;;;OAGG;IACH,QAFU,eAAe,CAEL;IAEpB;;;OAGG;IACH,iBAAkB;IAElB;;;OAGG;IACH,4BAAoB;IAEpB;;;OAGG;IACH,WAFU,kBAAkB,CAEF;IAma9B;;;;;;;;;OASG;IACH,oBAFa,IAAI,CAgBhB;IAED;;;;;;;;OAQG;IACH,gBAFa,IAAI,CAMhB;IAED;;;;;;;;OAQG;IACH,cAFa,OAAO,CAInB;IAgBD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gCAFa,IAAI,CA+NhB;IAED;;;;;;;;OAQG;IACH,0BAHW,KAAK,GACH,MAAM,EAAE,CAwBpB;IAED;;;;;;;;;;;OAWG;IACH,gCAHW,KAAK,GACH,MAAM,EAAE,CAsBpB;IAED;;;;;;;;;;OAUG;IACH,6BAJW,KAAK,SACL,UAAU,GAAC,YAAY,GACrB,IAAI,CAgDhB;IAED;;;;OAIG;IACH,wBAHW,OAAO,GACL,aAAW,IAAI,CAiC3B;IAED;;;;;;;OAOG;IACH,4BAJW,MAAM,GAAC,IAAI,gBACX,MAAM,GAAC,IAAI,SACX,UAAU,GAAC,YAAY,QA8CjC;IAGD;;;;;;;OAOG;IACH,wDAFa,OAAO,CAcnB;IAED;;;;;;;;;OASG;IACH,+CAFa,oBAAoB,CAYhC;IAED;;;;;;OAMG;IACH,oBALW,wBAAwB,QACxB,oBAAoB,iCAEpB,OAAO,QA+DjB;IAED;;;;OAIG;IACH,mCAHW,yBAAyB,UACzB,OAAO,QAiBjB;IAeD;;;;OAIG;IACH,kCAHW,OAAO,UACP,OAAO,QAIjB;IAED;;;;OAIG;IACH,kCAHW,OAAO,UACP,OAAO,QAIjB;;CACJ;iBAn3CgB,2BAA2B;yBAInB,eAAe;0CAIE,sEAAsE;gCAChF,mDAAmD;gCACnD,sBAAsB;mCACnB,yBAAyB;kBAQ1C,yCAAyC;oBAjBvC,mCAAmC;qCAgBlB,mEAAmE"}
1
+ {"version":3,"file":"NodeGraphView.d.ts","sourceRoot":"","sources":["../../../../editor/view/node-graph/NodeGraphView.js"],"names":[],"mappings":";AA0GA;IA4GI;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gJAyhBC;IAxpBD,mBAAmC;IAEnC;;;;;;;;;OASG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAQ,CAAC,CAET;IAmBtB;;;OAGG;IACH,qBAFmB,yBAAyB,cAE/B;IAEb;;OAEG;IACH,iBA0DE;IAEF;;;;OAIG;IACH,mBAFU,OAAO,CAEA;IAmCb;;;OAGG;IACH,2CAAsC;IAMtC;;;OAGG;IACH,QAFU,eAAe,CAEL;IAEpB;;;OAGG;IACH,iBAAkB;IAElB;;;OAGG;IACH,4BAAoB;IAEpB;;;OAGG;IACH,WAFU,kBAAkB,CAEF;IA8e9B;;;;;;;;;OASG;IACH,oBAFa,IAAI,CAgBhB;IAED;;;;;;;;OAQG;IACH,gBAFa,IAAI,CAMhB;IAED;;;;;;;;OAQG;IACH,cAFa,OAAO,CAInB;IAgBD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gCAFa,IAAI,CA+NhB;IAED;;;;;;;;OAQG;IACH,0BAHW,KAAK,GACH,MAAM,EAAE,CAwBpB;IAED;;;;;;;;;;;OAWG;IACH,gCAHW,KAAK,GACH,MAAM,EAAE,CAsBpB;IAED;;;;;;;;;;OAUG;IACH,6BAJW,KAAK,SACL,UAAU,GAAC,YAAY,GACrB,IAAI,CAgDhB;IAED;;;;OAIG;IACH,wBAHW,OAAO,GACL,aAAW,IAAI,CAiC3B;IAED;;;;;;;OAOG;IACH,4BAJW,MAAM,GAAC,IAAI,gBACX,MAAM,GAAC,IAAI,SACX,UAAU,GAAC,YAAY,QA8CjC;IAGD;;;;;;;OAOG;IACH,wDAFa,OAAO,CAcnB;IAED;;;;;;;;;OASG;IACH,+CAFa,oBAAoB,CAYhC;IAED;;;;;;OAMG;IACH,oBALW,wBAAwB,QACxB,oBAAoB,iCAEpB,OAAO,QA+DjB;IAED;;;;OAIG;IACH,mCAHW,yBAAyB,UACzB,OAAO,QAiBjB;IAeD;;;;OAIG;IACH,kCAHW,OAAO,UACP,OAAO,QAIjB;IAED;;;;OAIG;IACH,kCAHW,OAAO,UACP,OAAO,QAIjB;;CACJ;iBA/7CgB,2BAA2B;yBAInB,eAAe;0CAIE,sEAAsE;gCAChF,mDAAmD;gCACnD,sBAAsB;mCACnB,yBAAyB;kBAS1C,yCAAyC;oBAlBvC,mCAAmC;qCAiBlB,mEAAmE"}