@almadar/std 16.173.0 → 16.174.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 (203) hide show
  1. package/behaviors/lolo/infra/atoms/std-cross-reference.lolo +2 -4
  2. package/behaviors/lolo/ui/core/atoms/std-board.lolo +5 -9
  3. package/behaviors/lolo/ui/core/atoms/std-browse.lolo +8 -1
  4. package/behaviors/lolo/ui/core/atoms/std-esign-flow.lolo +2 -2
  5. package/behaviors/lolo/ui/core/atoms/std-event-log.lolo +3 -7
  6. package/behaviors/lolo/ui/core/atoms/std-form-advanced.lolo +1 -1
  7. package/behaviors/lolo/ui/core/atoms/std-image-upload-multi.lolo +1 -1
  8. package/behaviors/lolo/ui/core/atoms/std-list.lolo +3 -3
  9. package/behaviors/lolo/ui/core/atoms/std-modal.lolo +2 -2
  10. package/behaviors/lolo/ui/core/atoms/std-multi-party-flow.lolo +2 -4
  11. package/behaviors/lolo/ui/core/atoms/std-rating-review.lolo +5 -13
  12. package/behaviors/lolo/ui/core/atoms/std-recurrence.lolo +3 -7
  13. package/behaviors/lolo/ui/core/atoms/std-saved-search.lolo +1 -1
  14. package/behaviors/lolo/ui/core/atoms/std-signature-capture.lolo +2 -2
  15. package/behaviors/lolo/ui/core/atoms/std-step-flow.lolo +2 -4
  16. package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +1 -1
  17. package/behaviors/lolo/ui/core/atoms/std-thread.lolo +2 -2
  18. package/behaviors/lolo/ui/core/atoms/std-vote.lolo +2 -2
  19. package/behaviors/lolo/ui/core/atoms/std-wizard.lolo +3 -7
  20. package/behaviors/lolo/ui/core/atoms/ui-atlas-image.lolo +1 -1
  21. package/behaviors/lolo/ui/core/atoms/ui-atlas-panel.lolo +1 -1
  22. package/behaviors/lolo/ui/core/atoms/ui-center.lolo +1 -1
  23. package/behaviors/lolo/ui/core/atoms/ui-hstack.lolo +1 -1
  24. package/behaviors/lolo/ui/core/atoms/ui-icon.lolo +1 -1
  25. package/behaviors/lolo/ui/core/atoms/ui-stack.lolo +1 -1
  26. package/behaviors/lolo/ui/core/atoms/ui-typography.lolo +1 -1
  27. package/behaviors/lolo/ui/core/atoms/ui-vstack.lolo +1 -1
  28. package/behaviors/lolo/ui/core/molecules/ui-content-renderer.lolo +1 -1
  29. package/behaviors/lolo/ui/core/molecules/ui-form-layout.lolo +1 -1
  30. package/behaviors/lolo/ui/core/molecules/ui-grid.lolo +1 -1
  31. package/behaviors/lolo/ui/core/organisms/ui-chat-bar.lolo +1 -1
  32. package/behaviors/lolo/ui/core/organisms/ui-dashboard-grid.lolo +1 -1
  33. package/behaviors/lolo/ui/core/organisms/ui-detail-panel.lolo +1 -1
  34. package/behaviors/lolo/ui/core/organisms/ui-entity-cards.lolo +1 -1
  35. package/behaviors/lolo/ui/core/organisms/ui-entity-list.lolo +1 -1
  36. package/behaviors/lolo/ui/core/organisms/ui-entity-table.lolo +1 -1
  37. package/behaviors/lolo/ui/core/organisms/ui-form-section.lolo +9 -3
  38. package/behaviors/lolo/ui/core/organisms/ui-form.lolo +9 -3
  39. package/behaviors/lolo/ui/core/organisms/ui-master-detail.lolo +1 -1
  40. package/behaviors/lolo/ui/core/organisms/ui-media-gallery.lolo +1 -1
  41. package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +7 -1
  42. package/behaviors/lolo/ui/core/organisms/ui-stat-card.lolo +1 -1
  43. package/behaviors/lolo/ui/core/organisms/ui-subagent-trace-panel.lolo +1 -1
  44. package/behaviors/lolo/ui/game/atoms/ui-action-tile.lolo +1 -1
  45. package/behaviors/lolo/ui/game/atoms/ui-draw-shape-layer.lolo +41 -9
  46. package/behaviors/lolo/ui/game/atoms/ui-draw-shape.lolo +40 -8
  47. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite-layer.lolo +13 -3
  48. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite.lolo +12 -2
  49. package/behaviors/lolo/ui/game/atoms/ui-draw-text-layer.lolo +3 -3
  50. package/behaviors/lolo/ui/game/atoms/ui-draw-text.lolo +2 -2
  51. package/behaviors/lolo/ui/game/organisms/std-tactics-board-3d.lolo +32 -2
  52. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +1 -1
  53. package/behaviors/lolo/ui/learning/atoms/std-learn-compare.lolo +397 -0
  54. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +537 -0
  55. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +419 -0
  56. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +591 -0
  57. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +425 -0
  58. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +398 -0
  59. package/behaviors/lolo/ui/learning/atoms/std-learn-measure.lolo +325 -0
  60. package/behaviors/lolo/ui/learning/atoms/std-learn-perturb.lolo +494 -0
  61. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +408 -0
  62. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +307 -0
  63. package/behaviors/lolo/ui/learning/atoms/std-learn-sim-3d.lolo +318 -0
  64. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +336 -0
  65. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +380 -0
  66. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +43 -4
  67. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +41 -4
  68. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +43 -4
  69. package/behaviors/lolo/ui/marketing/organisms/ui-book-viewer.lolo +1 -1
  70. package/behaviors/lolo/ui/marketing/organisms/ui-case-study-organism.lolo +1 -1
  71. package/behaviors/lolo/ui/marketing/organisms/ui-feature-grid-organism.lolo +1 -1
  72. package/behaviors/lolo/ui/marketing/organisms/ui-hero-organism.lolo +1 -1
  73. package/behaviors/lolo/ui/marketing/organisms/ui-pricing-organism.lolo +1 -1
  74. package/behaviors/lolo/ui/marketing/organisms/ui-showcase-organism.lolo +1 -1
  75. package/behaviors/lolo/ui/marketing/organisms/ui-stats-organism.lolo +1 -1
  76. package/behaviors/lolo/ui/marketing/organisms/ui-step-flow-organism.lolo +1 -1
  77. package/behaviors/lolo/ui/marketing/organisms/ui-team-organism.lolo +1 -1
  78. package/behaviors/registry/agent/atoms/std-agent-session.orb +22 -1
  79. package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +38 -2
  80. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +38 -2
  81. package/behaviors/registry/agent/organisms/std-agent-rabit.orb +23 -1
  82. package/behaviors/registry/infra/atoms/std-approval-gate.orb +8 -16
  83. package/behaviors/registry/infra/atoms/std-cache-aside.orb +31 -62
  84. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +16 -32
  85. package/behaviors/registry/infra/atoms/std-cross-reference.orb +32 -4
  86. package/behaviors/registry/infra/atoms/std-data-erasure.orb +8 -16
  87. package/behaviors/registry/infra/atoms/std-mod-queue.orb +8 -16
  88. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +14 -28
  89. package/behaviors/registry/infra/atoms/std-row-access-control.orb +30 -2
  90. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -2
  91. package/behaviors/registry/ui/core/atoms/std-board.orb +19 -5
  92. package/behaviors/registry/ui/core/atoms/std-browse.orb +29 -7
  93. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -2
  94. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +3 -5
  95. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +3 -6
  96. package/behaviors/registry/ui/core/atoms/std-event-log.orb +17 -3
  97. package/behaviors/registry/ui/core/atoms/std-export.orb +2 -4
  98. package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
  99. package/behaviors/registry/ui/core/atoms/std-gallery.orb +9 -18
  100. package/behaviors/registry/ui/core/atoms/std-graphs.orb +15 -1
  101. package/behaviors/registry/ui/core/atoms/std-import.orb +2 -4
  102. package/behaviors/registry/ui/core/atoms/std-list.orb +4 -6
  103. package/behaviors/registry/ui/core/atoms/std-modal.orb +2 -2
  104. package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +16 -2
  105. package/behaviors/registry/ui/core/atoms/std-pagination.orb +15 -1
  106. package/behaviors/registry/ui/core/atoms/std-rating-review.orb +19 -5
  107. package/behaviors/registry/ui/core/atoms/std-recurrence.orb +17 -3
  108. package/behaviors/registry/ui/core/atoms/std-rich-editor.orb +15 -1
  109. package/behaviors/registry/ui/core/atoms/std-scatter.orb +15 -1
  110. package/behaviors/registry/ui/core/atoms/std-signature-capture.orb +2 -2
  111. package/behaviors/registry/ui/core/atoms/std-stats.orb +15 -1
  112. package/behaviors/registry/ui/core/atoms/std-step-flow.orb +16 -2
  113. package/behaviors/registry/ui/core/atoms/std-thread.orb +2 -2
  114. package/behaviors/registry/ui/core/atoms/std-vote.orb +2 -2
  115. package/behaviors/registry/ui/core/atoms/std-wizard.orb +17 -3
  116. package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +4 -1
  117. package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +4 -1
  118. package/behaviors/registry/ui/core/atoms/ui-center.orb +4 -1
  119. package/behaviors/registry/ui/core/atoms/ui-hstack.orb +4 -1
  120. package/behaviors/registry/ui/core/atoms/ui-icon.orb +4 -1
  121. package/behaviors/registry/ui/core/atoms/ui-stack.orb +4 -1
  122. package/behaviors/registry/ui/core/atoms/ui-typography.orb +4 -1
  123. package/behaviors/registry/ui/core/atoms/ui-vstack.orb +4 -1
  124. package/behaviors/registry/ui/core/molecules/ui-accordion.orb +3 -3
  125. package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +4 -1
  126. package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +4 -1
  127. package/behaviors/registry/ui/core/molecules/ui-grid.orb +4 -1
  128. package/behaviors/registry/ui/core/molecules/ui-tabs.orb +2 -2
  129. package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
  130. package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +4 -1
  131. package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +5 -2
  132. package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +5 -2
  133. package/behaviors/registry/ui/core/organisms/ui-entity-cards.orb +4 -1
  134. package/behaviors/registry/ui/core/organisms/ui-entity-list.orb +4 -1
  135. package/behaviors/registry/ui/core/organisms/ui-entity-table.orb +4 -1
  136. package/behaviors/registry/ui/core/organisms/ui-form-section.orb +34 -2
  137. package/behaviors/registry/ui/core/organisms/ui-form.orb +34 -2
  138. package/behaviors/registry/ui/core/organisms/ui-master-detail.orb +4 -1
  139. package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +4 -1
  140. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +24 -2
  141. package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +4 -1
  142. package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +4 -1
  143. package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
  144. package/behaviors/registry/ui/core/organisms/ui-ui-slot-renderer.orb +1 -1
  145. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +35 -1
  146. package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +4 -1
  147. package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +183 -13
  148. package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +104 -9
  149. package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +56 -2
  150. package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +36 -4
  151. package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +21 -2
  152. package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +19 -4
  153. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +173 -2
  154. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1 -1
  155. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +2814 -0
  156. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +3183 -0
  157. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +2394 -0
  158. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +3951 -0
  159. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +3458 -0
  160. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +2646 -0
  161. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1979 -0
  162. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +2994 -0
  163. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +2682 -0
  164. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1842 -0
  165. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1648 -0
  166. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +2307 -0
  167. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +2947 -0
  168. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +173 -4
  169. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +267 -7
  170. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +263 -8
  171. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +116 -1
  172. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +200 -4
  173. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +264 -7
  174. package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +1 -2
  175. package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +1 -2
  176. package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +1 -2
  177. package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +1 -2
  178. package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +1 -2
  179. package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +1 -2
  180. package/behaviors/registry/ui/marketing/organisms/ui-book-viewer.orb +4 -1
  181. package/behaviors/registry/ui/marketing/organisms/ui-case-study-organism.orb +4 -1
  182. package/behaviors/registry/ui/marketing/organisms/ui-feature-grid-organism.orb +4 -1
  183. package/behaviors/registry/ui/marketing/organisms/ui-hero-organism.orb +4 -1
  184. package/behaviors/registry/ui/marketing/organisms/ui-pricing-organism.orb +4 -1
  185. package/behaviors/registry/ui/marketing/organisms/ui-showcase-organism.orb +4 -1
  186. package/behaviors/registry/ui/marketing/organisms/ui-stats-organism.orb +4 -1
  187. package/behaviors/registry/ui/marketing/organisms/ui-step-flow-organism.orb +4 -1
  188. package/behaviors/registry/ui/marketing/organisms/ui-team-organism.orb +4 -1
  189. package/dist/behaviors/exports-reader.js +3440 -2189
  190. package/dist/behaviors/functions/index.d.ts +1751 -154
  191. package/dist/behaviors/functions/index.js +3402 -2190
  192. package/dist/behaviors/index.d.ts +1 -1
  193. package/dist/behaviors/index.js +3441 -2190
  194. package/dist/behaviors/query.js +3440 -2189
  195. package/dist/behaviors-embeddings.hash.json +3 -3
  196. package/dist/behaviors-embeddings.json +230 -178
  197. package/dist/behaviors-registry.json +4397 -171
  198. package/dist/index.d.ts +1 -1
  199. package/dist/index.js +3441 -2190
  200. package/dist/knob-embeddings.hash.json +3 -3
  201. package/dist/knob-embeddings.json +1 -1
  202. package/dist/registry/factory-signatures.json +1 -1
  203. package/package.json +2 -2
@@ -0,0 +1,537 @@
1
+ app std-learn-coupled-sim "1.0.0"
2
+ "Generic coupled-dynamics simulation — two named quantities evolve each tick under a config-selected interaction family (predator-prey: dP = aP − bPQ, dQ = cbPQ − dQ; epidemic: dS = −aSI, dI = aSI − bI; kinetics: dP = −aP, dQ = aP − bQ), drawn live as two time-series curves while Run is engaged. The two governing rates are exposed as sliders the learner can retune mid-run, and shock buttons inject or remove a burst of the first quantity so the learner feels how the coupled system absorbs disturbance. All names, coefficients, and scales are config-declared, so one mechanism serves rabbits and foxes, infection and recovery, reactant and product, adopters and churn. Standalone by default; behind a lab router set matchMode and it renders only when MODE_SELECTED matches."
3
+ orbital CoupledSimOrbital {
4
+ type CoupledSample = {
5
+ x : number!
6
+ y : number!
7
+ }
8
+ type CoupledCurve = {
9
+ label : string
10
+ color : string
11
+ samples : [CoupledSample]!
12
+ }
13
+
14
+ entity CoupledSimScene [runtime] {
15
+ id : string!
16
+ active : boolean = false
17
+ title : string
18
+ t : number = 0
19
+ p : number = 0
20
+ q : number = 0
21
+ coefA : number = 0
22
+ coefB : number = 0
23
+ running : boolean = false
24
+ pSamples : [CoupledSample]
25
+ qSamples : [CoupledSample]
26
+ curves : [CoupledCurve]
27
+ }
28
+
29
+ trait CoupledSimSim -> @rebindable CoupledSimScene [interaction, instance] {
30
+ initial: idle
31
+
32
+ state idle {
33
+ INIT -> idle when (== @config.matchMode "")
34
+ (set @entity.active true)
35
+ (set @entity.title @config.title)
36
+ (set @entity.t 0)
37
+ (set @entity.p @config.pStart)
38
+ (set @entity.q @config.qStart)
39
+ (set @entity.coefA @config.coefADefault)
40
+ (set @entity.coefB @config.coefBDefault)
41
+ (set @entity.running @config.autoRun)
42
+ (set @entity.pSamples [ { x: 0, y: @config.pStart } ])
43
+ (set @entity.qSamples [ { x: 0, y: @config.qStart } ])
44
+ (set @entity.curves [
45
+ { label: @config.pLabel, color: @config.pColor, samples: @entity.pSamples },
46
+ { label: @config.qLabel, color: @config.qColor, samples: @entity.qSamples }
47
+ ])
48
+ (render-ui main {
49
+ type: box
50
+ padding: md
51
+ children: [
52
+ { type: stack, direction: vertical, gap: md, children: [
53
+ { type: typography, variant: h4, content: @entity.title },
54
+ { type: typography, variant: body, content: @config.taskText },
55
+ { type: stack, direction: horizontal, gap: sm, children: [
56
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
57
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
58
+ { type: button, action: RESET, label: "Reset", variant: ghost },
59
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
60
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
61
+ ] },
62
+ { type: stack, direction: vertical, gap: xs, children: [
63
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
64
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
65
+ ] },
66
+ { type: stack, direction: vertical, gap: xs, children: [
67
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
68
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
69
+ ] },
70
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
71
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
72
+ ] }
73
+ ]
74
+ })
75
+
76
+ MODE_SELECTED -> idle when (== ?mode @config.matchMode)
77
+ (set @entity.active true)
78
+ (set @entity.title @config.title)
79
+ (set @entity.t 0)
80
+ (set @entity.p @config.pStart)
81
+ (set @entity.q @config.qStart)
82
+ (set @entity.coefA @config.coefADefault)
83
+ (set @entity.coefB @config.coefBDefault)
84
+ (set @entity.running @config.autoRun)
85
+ (set @entity.pSamples [ { x: 0, y: @config.pStart } ])
86
+ (set @entity.qSamples [ { x: 0, y: @config.qStart } ])
87
+ (set @entity.curves [
88
+ { label: @config.pLabel, color: @config.pColor, samples: @entity.pSamples },
89
+ { label: @config.qLabel, color: @config.qColor, samples: @entity.qSamples }
90
+ ])
91
+ (render-ui main {
92
+ type: box
93
+ padding: md
94
+ children: [
95
+ { type: stack, direction: vertical, gap: md, children: [
96
+ { type: typography, variant: h4, content: @entity.title },
97
+ { type: typography, variant: body, content: @config.taskText },
98
+ { type: stack, direction: horizontal, gap: sm, children: [
99
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
100
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
101
+ { type: button, action: RESET, label: "Reset", variant: ghost },
102
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
103
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
104
+ ] },
105
+ { type: stack, direction: vertical, gap: xs, children: [
106
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
107
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
108
+ ] },
109
+ { type: stack, direction: vertical, gap: xs, children: [
110
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
111
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
112
+ ] },
113
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
114
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
115
+ ] }
116
+ ]
117
+ })
118
+
119
+ RUN -> idle when (and (== @entity.active true) (and (== @entity.running false) (< @entity.t @config.duration)))
120
+ (set @entity.running true)
121
+ (render-ui main {
122
+ type: box
123
+ padding: md
124
+ children: [
125
+ { type: stack, direction: vertical, gap: md, children: [
126
+ { type: typography, variant: h4, content: @entity.title },
127
+ { type: typography, variant: body, content: @config.taskText },
128
+ { type: stack, direction: horizontal, gap: sm, children: [
129
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
130
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
131
+ { type: button, action: RESET, label: "Reset", variant: ghost },
132
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
133
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
134
+ ] },
135
+ { type: stack, direction: vertical, gap: xs, children: [
136
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
137
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
138
+ ] },
139
+ { type: stack, direction: vertical, gap: xs, children: [
140
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
141
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
142
+ ] },
143
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
144
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
145
+ ] }
146
+ ]
147
+ })
148
+ (emit RUN_TOGGLED { running: @entity.running })
149
+
150
+ PAUSE -> idle when (and (== @entity.active true) (== @entity.running true))
151
+ (set @entity.running false)
152
+ (render-ui main {
153
+ type: box
154
+ padding: md
155
+ children: [
156
+ { type: stack, direction: vertical, gap: md, children: [
157
+ { type: typography, variant: h4, content: @entity.title },
158
+ { type: typography, variant: body, content: @config.taskText },
159
+ { type: stack, direction: horizontal, gap: sm, children: [
160
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
161
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
162
+ { type: button, action: RESET, label: "Reset", variant: ghost },
163
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
164
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
165
+ ] },
166
+ { type: stack, direction: vertical, gap: xs, children: [
167
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
168
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
169
+ ] },
170
+ { type: stack, direction: vertical, gap: xs, children: [
171
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
172
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
173
+ ] },
174
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
175
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
176
+ ] }
177
+ ]
178
+ })
179
+ (emit RUN_TOGGLED { running: @entity.running })
180
+
181
+ RESET -> idle when (== @entity.active true)
182
+ (set @entity.t 0)
183
+ (set @entity.p @config.pStart)
184
+ (set @entity.q @config.qStart)
185
+ (set @entity.coefA @config.coefADefault)
186
+ (set @entity.coefB @config.coefBDefault)
187
+ (set @entity.running false)
188
+ (set @entity.pSamples [ { x: 0, y: @config.pStart } ])
189
+ (set @entity.qSamples [ { x: 0, y: @config.qStart } ])
190
+ (set @entity.curves [
191
+ { label: @config.pLabel, color: @config.pColor, samples: @entity.pSamples },
192
+ { label: @config.qLabel, color: @config.qColor, samples: @entity.qSamples }
193
+ ])
194
+ (render-ui main {
195
+ type: box
196
+ padding: md
197
+ children: [
198
+ { type: stack, direction: vertical, gap: md, children: [
199
+ { type: typography, variant: h4, content: @entity.title },
200
+ { type: typography, variant: body, content: @config.taskText },
201
+ { type: stack, direction: horizontal, gap: sm, children: [
202
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
203
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
204
+ { type: button, action: RESET, label: "Reset", variant: ghost },
205
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
206
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
207
+ ] },
208
+ { type: stack, direction: vertical, gap: xs, children: [
209
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
210
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
211
+ ] },
212
+ { type: stack, direction: vertical, gap: xs, children: [
213
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
214
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
215
+ ] },
216
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
217
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
218
+ ] }
219
+ ]
220
+ })
221
+ (emit SIM_RESET { pStart: @config.pStart, qStart: @config.qStart })
222
+
223
+ SET_A -> idle when (== @entity.active true)
224
+ (set @entity.coefA (math/clamp ?value @config.coefAMin @config.coefAMax))
225
+ (render-ui main {
226
+ type: box
227
+ padding: md
228
+ children: [
229
+ { type: stack, direction: vertical, gap: md, children: [
230
+ { type: typography, variant: h4, content: @entity.title },
231
+ { type: typography, variant: body, content: @config.taskText },
232
+ { type: stack, direction: horizontal, gap: sm, children: [
233
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
234
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
235
+ { type: button, action: RESET, label: "Reset", variant: ghost },
236
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
237
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
238
+ ] },
239
+ { type: stack, direction: vertical, gap: xs, children: [
240
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
241
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
242
+ ] },
243
+ { type: stack, direction: vertical, gap: xs, children: [
244
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
245
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
246
+ ] },
247
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
248
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
249
+ ] }
250
+ ]
251
+ })
252
+ (emit COEFS_CHANGED { coefA: @entity.coefA, coefB: @entity.coefB })
253
+
254
+ SET_B -> idle when (== @entity.active true)
255
+ (set @entity.coefB (math/clamp ?value @config.coefBMin @config.coefBMax))
256
+ (render-ui main {
257
+ type: box
258
+ padding: md
259
+ children: [
260
+ { type: stack, direction: vertical, gap: md, children: [
261
+ { type: typography, variant: h4, content: @entity.title },
262
+ { type: typography, variant: body, content: @config.taskText },
263
+ { type: stack, direction: horizontal, gap: sm, children: [
264
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
265
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
266
+ { type: button, action: RESET, label: "Reset", variant: ghost },
267
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
268
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
269
+ ] },
270
+ { type: stack, direction: vertical, gap: xs, children: [
271
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
272
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
273
+ ] },
274
+ { type: stack, direction: vertical, gap: xs, children: [
275
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
276
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
277
+ ] },
278
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
279
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
280
+ ] }
281
+ ]
282
+ })
283
+ (emit COEFS_CHANGED { coefA: @entity.coefA, coefB: @entity.coefB })
284
+
285
+ SHOCK -> idle when (== @entity.active true)
286
+ (set @entity.p (math/max 0 (+ @entity.p ?delta)))
287
+ (set @entity.pSamples (array/append @entity.pSamples { x: @entity.t, y: @entity.p }))
288
+ (set @entity.curves [
289
+ { label: @config.pLabel, color: @config.pColor, samples: @entity.pSamples },
290
+ { label: @config.qLabel, color: @config.qColor, samples: @entity.qSamples }
291
+ ])
292
+ (render-ui main {
293
+ type: box
294
+ padding: md
295
+ children: [
296
+ { type: stack, direction: vertical, gap: md, children: [
297
+ { type: typography, variant: h4, content: @entity.title },
298
+ { type: typography, variant: body, content: @config.taskText },
299
+ { type: stack, direction: horizontal, gap: sm, children: [
300
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
301
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
302
+ { type: button, action: RESET, label: "Reset", variant: ghost },
303
+ { type: button, action: SHOCK, actionPayload: { delta: @config.shockSize }, label: @config.shockUpLabel, variant: secondary, size: sm },
304
+ { type: button, action: SHOCK, actionPayload: { delta: (- 0 @config.shockSize) }, label: @config.shockDownLabel, variant: secondary, size: sm }
305
+ ] },
306
+ { type: stack, direction: vertical, gap: xs, children: [
307
+ { type: typography, variant: caption, content: (str/concat @config.coefALabel ": " (math/round @entity.coefA 3)) },
308
+ { type: range-slider, min: @config.coefAMin, max: @config.coefAMax, step: @config.coefAStep, value: @entity.coefA, showTooltip: true, action: "SET_A" }
309
+ ] },
310
+ { type: stack, direction: vertical, gap: xs, children: [
311
+ { type: typography, variant: caption, content: (str/concat @config.coefBLabel ": " (math/round @entity.coefB 3)) },
312
+ { type: range-slider, min: @config.coefBMin, max: @config.coefBMax, step: @config.coefBStep, value: @entity.coefB, showTooltip: true, action: "SET_B" }
313
+ ] },
314
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: 0, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
315
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) " · " @config.pLabel " = " (math/round @entity.p 1) " · " @config.qLabel " = " (math/round @entity.q 1)) }
316
+ ] }
317
+ ]
318
+ })
319
+ (emit SHOCK_APPLIED { delta: ?delta, p: @entity.p, q: @entity.q })
320
+ }
321
+
322
+ ticks {
323
+ coupledTick every 100ms
324
+ when (and (== @entity.active true) (and (== @entity.running true) (< @entity.t @config.duration)))
325
+ (let (
326
+ (dt (* 0.1 @config.timeScale))
327
+ (a @entity.coefA)
328
+ (b @entity.coefB)
329
+ (P @entity.p)
330
+ (Q @entity.q)
331
+ (dP (if (== @config.kind "predator-prey")
332
+ (- (* @a @P) (* @b @P @Q 0.01))
333
+ (if (== @config.kind "epidemic")
334
+ (- 0 (* @a @P @Q 0.01))
335
+ (- 0 (* @a @P)))))
336
+ (dQ (if (== @config.kind "predator-prey")
337
+ (- (* @config.coefC @b @P @Q 0.01) (* @config.coefD @Q))
338
+ (if (== @config.kind "epidemic")
339
+ (- (* @a @P @Q 0.01) (* @b @Q))
340
+ (- (* @a @P) (* @b @Q)))))
341
+ (newP (math/max 0 (+ @P (* @dP @dt))))
342
+ (newQ (math/max 0 (+ @Q (* @dQ @dt))))
343
+ )
344
+ (do
345
+ (set @entity.t (math/min @config.duration (+ @entity.t 0.1)))
346
+ (set @entity.p @newP)
347
+ (set @entity.q @newQ)
348
+ (set @entity.pSamples (array/append @entity.pSamples { x: @entity.t, y: @newP }))
349
+ (set @entity.qSamples (array/append @entity.qSamples { x: @entity.t, y: @newQ }))
350
+ (set @entity.curves [
351
+ { label: @config.pLabel, color: @config.pColor, samples: @entity.pSamples },
352
+ { label: @config.qLabel, color: @config.qColor, samples: @entity.qSamples }
353
+ ])
354
+ (set @entity.running (if (>= @entity.t @config.duration) false true))))
355
+ }
356
+
357
+ listens {
358
+ MODE_SELECTED {
359
+ mode : string
360
+ }
361
+ @description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
362
+ @tier "domain"
363
+ RUN {
364
+ }
365
+ @description "Learner started (or resumed) the coupled evolution; the two curves draw live until Pause or the configured duration."
366
+ @tier "domain"
367
+ PAUSE {
368
+ }
369
+ @description "Learner froze the simulation mid-run; sliders and shocks still apply to the frozen state."
370
+ @tier "domain"
371
+ RESET {
372
+ }
373
+ @description "Learner restored both quantities, both rates, and the clock to their configured starting values."
374
+ @tier "domain"
375
+ SET_A {
376
+ value : number
377
+ }
378
+ @description "Learner retuned the first governing rate mid-run — value is the new coefficient; the dynamics change from the next tick."
379
+ @tier "domain"
380
+ SET_B {
381
+ value : number
382
+ }
383
+ @description "Learner retuned the second governing rate mid-run — value is the new coefficient; the dynamics change from the next tick."
384
+ @tier "domain"
385
+ SHOCK {
386
+ delta : number
387
+ }
388
+ @description "Learner injected (positive) or removed (negative) a burst of the first quantity to disturb the system and watch it respond."
389
+ @tier "domain"
390
+ }
391
+
392
+ emits {
393
+ RUN_TOGGLED -> external {
394
+ running : boolean
395
+ }
396
+ @description "The simulation was started or paused — a composed listener (readout, grader) can subscribe; a harmless no-op when the atom runs standalone."
397
+ @tier "domain"
398
+ SIM_RESET -> external {
399
+ pStart : number
400
+ qStart : number
401
+ }
402
+ @description "The learner reset the system to its configured starting state."
403
+ @tier "domain"
404
+ COEFS_CHANGED -> external {
405
+ coefA : number
406
+ coefB : number
407
+ }
408
+ @description "The governing rates after a slider change."
409
+ @tier "domain"
410
+ SHOCK_APPLIED -> external {
411
+ delta : number
412
+ p : number
413
+ q : number
414
+ }
415
+ @description "A disturbance was injected: the burst size and both quantities right after it."
416
+ @synonyms "coupled dynamics, predator prey, epidemic, reaction kinetics, feedback loop, disturbance"
417
+ @tier "domain"
418
+ }
419
+
420
+ config {
421
+ matchMode : string = ""
422
+ @label "Match Mode"
423
+ @description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
424
+ @tier "presentation"
425
+ title : string = "Coupled System"
426
+ @label "Title"
427
+ @description "Title shown above the simulation."
428
+ @tier "presentation"
429
+ taskText : string = "Run the system, retune the rates, and shock it — watch how the two quantities push and pull each other."
430
+ @label "Task Text"
431
+ @description "One-sentence statement of what to explore."
432
+ @tier "domain"
433
+ kind : string = "predator-prey"
434
+ @label "Interaction Family"
435
+ @description "Which coupled dynamics govern the two quantities: predator-prey (oscillating cycles), epidemic (S and I with transmission and recovery), or kinetics (A decaying into B)."
436
+ @synonyms "predator prey, Lotka-Volterra, SIR, epidemic, reaction kinetics, coupled ODE"
437
+ @tier "domain"
438
+ pLabel : string = "Prey"
439
+ @label "P Label"
440
+ @description "Display name of the first quantity."
441
+ @tier "domain"
442
+ qLabel : string = "Predators"
443
+ @label "Q Label"
444
+ @description "Display name of the second quantity."
445
+ @tier "domain"
446
+ pStart : number = 120
447
+ @label "P Start"
448
+ @tier "domain"
449
+ qStart : number = 40
450
+ @label "Q Start"
451
+ @tier "domain"
452
+ coefALabel : string = "Prey growth rate"
453
+ @label "Coefficient A Label"
454
+ @description "Display label of the first governing rate slider."
455
+ @tier "domain"
456
+ coefBLabel : string = "Predation rate"
457
+ @label "Coefficient B Label"
458
+ @description "Display label of the second governing rate slider."
459
+ @tier "domain"
460
+ coefADefault : number = 0.6
461
+ @label "Coefficient A Default"
462
+ @tier "domain"
463
+ coefBDefault : number = 0.9
464
+ @label "Coefficient B Default"
465
+ @tier "domain"
466
+ coefAMin : number = 0
467
+ @label "Coefficient A Min"
468
+ @tier "domain"
469
+ coefAMax : number = 2
470
+ @label "Coefficient A Max"
471
+ @tier "domain"
472
+ coefAStep : number = 0.01
473
+ @label "Coefficient A Step"
474
+ @tier "presentation"
475
+ coefBMin : number = 0
476
+ @label "Coefficient B Min"
477
+ @tier "domain"
478
+ coefBMax : number = 2
479
+ @label "Coefficient B Max"
480
+ @tier "domain"
481
+ coefBStep : number = 0.01
482
+ @label "Coefficient B Step"
483
+ @tier "presentation"
484
+ coefC : number = 0.5
485
+ @label "Coefficient C"
486
+ @description "Predator-prey only: conversion efficiency of predation into predator growth."
487
+ @tier "domain"
488
+ coefD : number = 0.4
489
+ @label "Coefficient D"
490
+ @description "Predator-prey only: predator death rate."
491
+ @tier "domain"
492
+ timeScale : number = 1
493
+ @label "Time Scale"
494
+ @description "Multiplier on the integration step; raise it to fast-forward the dynamics."
495
+ @tier "domain"
496
+ duration : number = 30
497
+ @label "Duration"
498
+ @description "Simulated seconds before the run stops automatically."
499
+ @tier "domain"
500
+ shockSize : number = 40
501
+ @label "Shock Size"
502
+ @description "How much of the first quantity a shock button injects or removes."
503
+ @tier "domain"
504
+ shockUpLabel : string = "+ Prey burst"
505
+ @label "Shock Up Label"
506
+ @tier "presentation"
507
+ shockDownLabel : string = "− Prey cull"
508
+ @label "Shock Down Label"
509
+ @tier "presentation"
510
+ valueMax : number = 300
511
+ @label "Value Max"
512
+ @description "Upper bound of the chart's y axis."
513
+ @tier "presentation"
514
+ gridStep : number = 50
515
+ @label "Grid Step"
516
+ @tier "presentation"
517
+ pColor : string = "#16a34a"
518
+ @label "P Color"
519
+ @tier "presentation"
520
+ qColor : string = "#dc2626"
521
+ @label "Q Color"
522
+ @tier "presentation"
523
+ autoRun : boolean = true
524
+ @label "Auto Run"
525
+ @description "Whether the simulation starts running immediately on load."
526
+ @tier "domain"
527
+ width : number = 600
528
+ @label "Width"
529
+ @tier "presentation"
530
+ height : number = 360
531
+ @label "Height"
532
+ @tier "presentation"
533
+ }
534
+ }
535
+
536
+ page "/learn-coupled-sim" as CoupledSimPage -> CoupledSimSim
537
+ }