@almadar/std 16.173.0 → 16.175.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 (220) 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/molecules/ui-table-view.lolo +4 -9
  32. package/behaviors/lolo/ui/core/organisms/ui-chat-bar.lolo +1 -1
  33. package/behaviors/lolo/ui/core/organisms/ui-dashboard-grid.lolo +1 -1
  34. package/behaviors/lolo/ui/core/organisms/ui-detail-panel.lolo +1 -1
  35. package/behaviors/lolo/ui/core/organisms/ui-entity-cards.lolo +1 -1
  36. package/behaviors/lolo/ui/core/organisms/ui-entity-list.lolo +1 -1
  37. package/behaviors/lolo/ui/core/organisms/ui-entity-table.lolo +1 -1
  38. package/behaviors/lolo/ui/core/organisms/ui-form-section.lolo +9 -3
  39. package/behaviors/lolo/ui/core/organisms/ui-form.lolo +9 -3
  40. package/behaviors/lolo/ui/core/organisms/ui-master-detail.lolo +1 -1
  41. package/behaviors/lolo/ui/core/organisms/ui-media-gallery.lolo +1 -1
  42. package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +7 -1
  43. package/behaviors/lolo/ui/core/organisms/ui-stat-card.lolo +1 -1
  44. package/behaviors/lolo/ui/core/organisms/ui-subagent-trace-panel.lolo +1 -1
  45. package/behaviors/lolo/ui/game/atoms/ui-action-tile.lolo +1 -1
  46. package/behaviors/lolo/ui/game/atoms/ui-draw-shape-layer.lolo +41 -9
  47. package/behaviors/lolo/ui/game/atoms/ui-draw-shape.lolo +40 -8
  48. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite-layer.lolo +13 -3
  49. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite.lolo +12 -2
  50. package/behaviors/lolo/ui/game/atoms/ui-draw-text-layer.lolo +3 -3
  51. package/behaviors/lolo/ui/game/atoms/ui-draw-text.lolo +2 -2
  52. package/behaviors/lolo/ui/game/organisms/std-tactics-board-3d.lolo +32 -2
  53. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +133 -23
  54. package/behaviors/lolo/ui/learning/atoms/std-learn-compare.lolo +397 -0
  55. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +537 -0
  56. package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +428 -0
  57. package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +520 -0
  58. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +419 -0
  59. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +591 -0
  60. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +425 -0
  61. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +398 -0
  62. package/behaviors/lolo/ui/learning/atoms/std-learn-measure.lolo +325 -0
  63. package/behaviors/lolo/ui/learning/atoms/std-learn-perturb.lolo +494 -0
  64. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +408 -0
  65. package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +805 -0
  66. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +307 -0
  67. package/behaviors/lolo/ui/learning/atoms/std-learn-sim-3d.lolo +318 -0
  68. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +336 -0
  69. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +409 -0
  70. package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +186 -0
  71. package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +522 -0
  72. package/behaviors/lolo/ui/learning/atoms/ui-algo-graph-canvas.lolo +192 -0
  73. package/behaviors/lolo/ui/learning/atoms/ui-algorithm-canvas.lolo +111 -2
  74. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +193 -5
  75. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +173 -5
  76. package/behaviors/lolo/ui/learning/atoms/ui-learning-canvas.lolo +48 -1
  77. package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +141 -1
  78. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +242 -5
  79. package/behaviors/lolo/ui/marketing/organisms/ui-book-viewer.lolo +1 -1
  80. package/behaviors/lolo/ui/marketing/organisms/ui-case-study-organism.lolo +1 -1
  81. package/behaviors/lolo/ui/marketing/organisms/ui-feature-grid-organism.lolo +1 -1
  82. package/behaviors/lolo/ui/marketing/organisms/ui-hero-organism.lolo +1 -1
  83. package/behaviors/lolo/ui/marketing/organisms/ui-pricing-organism.lolo +1 -1
  84. package/behaviors/lolo/ui/marketing/organisms/ui-showcase-organism.lolo +1 -1
  85. package/behaviors/lolo/ui/marketing/organisms/ui-stats-organism.lolo +1 -1
  86. package/behaviors/lolo/ui/marketing/organisms/ui-step-flow-organism.lolo +1 -1
  87. package/behaviors/lolo/ui/marketing/organisms/ui-team-organism.lolo +1 -1
  88. package/behaviors/registry/agent/atoms/std-agent-session.orb +22 -1
  89. package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +38 -2
  90. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +38 -2
  91. package/behaviors/registry/agent/organisms/std-agent-rabit.orb +23 -1
  92. package/behaviors/registry/infra/atoms/std-approval-gate.orb +8 -16
  93. package/behaviors/registry/infra/atoms/std-cache-aside.orb +31 -62
  94. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +16 -32
  95. package/behaviors/registry/infra/atoms/std-cross-reference.orb +32 -4
  96. package/behaviors/registry/infra/atoms/std-data-erasure.orb +8 -16
  97. package/behaviors/registry/infra/atoms/std-mod-queue.orb +8 -16
  98. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +14 -28
  99. package/behaviors/registry/infra/atoms/std-row-access-control.orb +30 -2
  100. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -2
  101. package/behaviors/registry/ui/core/atoms/std-board.orb +19 -5
  102. package/behaviors/registry/ui/core/atoms/std-browse.orb +29 -7
  103. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -2
  104. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +3 -5
  105. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +3 -6
  106. package/behaviors/registry/ui/core/atoms/std-event-log.orb +17 -3
  107. package/behaviors/registry/ui/core/atoms/std-export.orb +2 -4
  108. package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
  109. package/behaviors/registry/ui/core/atoms/std-gallery.orb +9 -18
  110. package/behaviors/registry/ui/core/atoms/std-graphs.orb +15 -1
  111. package/behaviors/registry/ui/core/atoms/std-import.orb +2 -4
  112. package/behaviors/registry/ui/core/atoms/std-list.orb +4 -6
  113. package/behaviors/registry/ui/core/atoms/std-modal.orb +2 -2
  114. package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +16 -2
  115. package/behaviors/registry/ui/core/atoms/std-pagination.orb +15 -1
  116. package/behaviors/registry/ui/core/atoms/std-rating-review.orb +19 -5
  117. package/behaviors/registry/ui/core/atoms/std-recurrence.orb +17 -3
  118. package/behaviors/registry/ui/core/atoms/std-rich-editor.orb +15 -1
  119. package/behaviors/registry/ui/core/atoms/std-scatter.orb +15 -1
  120. package/behaviors/registry/ui/core/atoms/std-signature-capture.orb +2 -2
  121. package/behaviors/registry/ui/core/atoms/std-stats.orb +15 -1
  122. package/behaviors/registry/ui/core/atoms/std-step-flow.orb +16 -2
  123. package/behaviors/registry/ui/core/atoms/std-thread.orb +2 -2
  124. package/behaviors/registry/ui/core/atoms/std-vote.orb +2 -2
  125. package/behaviors/registry/ui/core/atoms/std-wizard.orb +17 -3
  126. package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +4 -1
  127. package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +4 -1
  128. package/behaviors/registry/ui/core/atoms/ui-center.orb +4 -1
  129. package/behaviors/registry/ui/core/atoms/ui-hstack.orb +4 -1
  130. package/behaviors/registry/ui/core/atoms/ui-icon.orb +4 -1
  131. package/behaviors/registry/ui/core/atoms/ui-stack.orb +4 -1
  132. package/behaviors/registry/ui/core/atoms/ui-typography.orb +4 -1
  133. package/behaviors/registry/ui/core/atoms/ui-vstack.orb +4 -1
  134. package/behaviors/registry/ui/core/molecules/ui-accordion.orb +3 -3
  135. package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +4 -1
  136. package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +4 -1
  137. package/behaviors/registry/ui/core/molecules/ui-grid.orb +4 -1
  138. package/behaviors/registry/ui/core/molecules/ui-table-view.orb +4 -39
  139. package/behaviors/registry/ui/core/molecules/ui-tabs.orb +2 -2
  140. package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
  141. package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +4 -1
  142. package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +5 -2
  143. package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +5 -2
  144. package/behaviors/registry/ui/core/organisms/ui-entity-cards.orb +4 -1
  145. package/behaviors/registry/ui/core/organisms/ui-entity-list.orb +4 -1
  146. package/behaviors/registry/ui/core/organisms/ui-entity-table.orb +4 -1
  147. package/behaviors/registry/ui/core/organisms/ui-form-section.orb +34 -2
  148. package/behaviors/registry/ui/core/organisms/ui-form.orb +34 -2
  149. package/behaviors/registry/ui/core/organisms/ui-master-detail.orb +4 -1
  150. package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +4 -1
  151. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +24 -2
  152. package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +4 -1
  153. package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +4 -1
  154. package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
  155. package/behaviors/registry/ui/core/organisms/ui-ui-slot-renderer.orb +1 -1
  156. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +35 -1
  157. package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +4 -1
  158. package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +183 -13
  159. package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +104 -9
  160. package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +56 -2
  161. package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +36 -4
  162. package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +21 -2
  163. package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +19 -4
  164. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +173 -2
  165. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1288 -197
  166. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +2814 -0
  167. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +3183 -0
  168. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +2512 -0
  169. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +3678 -0
  170. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +2394 -0
  171. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +3951 -0
  172. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +3458 -0
  173. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +2646 -0
  174. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1979 -0
  175. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +2994 -0
  176. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +2682 -0
  177. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +6539 -0
  178. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1842 -0
  179. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1648 -0
  180. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +2307 -0
  181. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +3118 -0
  182. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +986 -0
  183. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +3333 -0
  184. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +716 -0
  185. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +679 -5
  186. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +962 -18
  187. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +919 -30
  188. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +372 -1
  189. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +936 -16
  190. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +1328 -43
  191. package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +1 -2
  192. package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +1 -2
  193. package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +1 -2
  194. package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +1 -2
  195. package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +1 -2
  196. package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +1 -2
  197. package/behaviors/registry/ui/marketing/organisms/ui-book-viewer.orb +4 -1
  198. package/behaviors/registry/ui/marketing/organisms/ui-case-study-organism.orb +4 -1
  199. package/behaviors/registry/ui/marketing/organisms/ui-feature-grid-organism.orb +4 -1
  200. package/behaviors/registry/ui/marketing/organisms/ui-hero-organism.orb +4 -1
  201. package/behaviors/registry/ui/marketing/organisms/ui-pricing-organism.orb +4 -1
  202. package/behaviors/registry/ui/marketing/organisms/ui-showcase-organism.orb +4 -1
  203. package/behaviors/registry/ui/marketing/organisms/ui-stats-organism.orb +4 -1
  204. package/behaviors/registry/ui/marketing/organisms/ui-step-flow-organism.orb +4 -1
  205. package/behaviors/registry/ui/marketing/organisms/ui-team-organism.orb +4 -1
  206. package/dist/behaviors/exports-reader.js +3704 -2189
  207. package/dist/behaviors/functions/index.d.ts +2638 -254
  208. package/dist/behaviors/functions/index.js +3648 -2190
  209. package/dist/behaviors/index.d.ts +1 -1
  210. package/dist/behaviors/index.js +3705 -2190
  211. package/dist/behaviors/query.js +3704 -2189
  212. package/dist/behaviors-embeddings.hash.json +3 -3
  213. package/dist/behaviors-embeddings.json +289 -213
  214. package/dist/behaviors-registry.json +7900 -587
  215. package/dist/index.d.ts +1 -1
  216. package/dist/index.js +3705 -2190
  217. package/dist/knob-embeddings.hash.json +3 -3
  218. package/dist/knob-embeddings.json +1 -1
  219. package/dist/registry/factory-signatures.json +1 -1
  220. package/package.json +2 -2
@@ -0,0 +1,397 @@
1
+ app std-learn-compare "1.0.0"
2
+ "Generic dual-view comparator — two instances of the same config-declared curve family (power y = A·xᴮ, linear y = A + B·x, or sine y = A·sin(B·x)) render overlaid on one canvas, each side driven by its own parameter pair of sliders, with a live delta readout of the two values at the midpoint x. Changing either side recomputes immediately, so the learner sees exactly how the two settings diverge. All labels and defaults are config-declared, so the same mechanism serves any side-by-side contrast: two interest rates compounding, two spring constants, two demand elasticities, two wave frequencies. Standalone by default; behind a lab router set matchMode and it renders only when MODE_SELECTED matches."
3
+ orbital CompareOrbital {
4
+ type CompareCurve = {
5
+ label : string
6
+ color : string
7
+ samples : [CompareCurveSample]!
8
+ }
9
+ type CompareCurveSample = {
10
+ x : number!
11
+ y : number!
12
+ }
13
+
14
+ entity CompareScene [runtime] {
15
+ id : string!
16
+ active : boolean = false
17
+ title : string
18
+ curveKind : string
19
+ leftA : number = 0
20
+ leftB : number = 0
21
+ rightA : number = 0
22
+ rightB : number = 0
23
+ curves : [CompareCurve]
24
+ xMid : number = 0
25
+ leftMid : number = 0
26
+ rightMid : number = 0
27
+ delta : number = 0
28
+ yMin : number
29
+ yMax : number
30
+ }
31
+
32
+ trait CompareSim -> @rebindable CompareScene [interaction, instance] {
33
+ initial: idle
34
+
35
+ state idle {
36
+ INIT -> idle when (== @config.matchMode "")
37
+ (let (
38
+ (kind @config.curveKind)
39
+ (span (- @config.xMax @config.xMin))
40
+ (lA @config.leftADefault)
41
+ (lB @config.leftBDefault)
42
+ (rA @config.rightADefault)
43
+ (rB @config.rightBDefault)
44
+ (leftSamples (array/map (array/range 0 81) (fn (i)
45
+ (let (
46
+ (x (+ @config.xMin (* @i (/ @span 80))))
47
+ (yVal (if (== @kind "power")
48
+ (* @lA (math/pow @x @lB))
49
+ (if (== @kind "linear")
50
+ (+ @lA (* @lB @x))
51
+ (* @lA (math/sin (* @lB @x))))))
52
+ )
53
+ { x: @x, y: @yVal }))))
54
+ (rightSamples (array/map (array/range 0 81) (fn (i)
55
+ (let (
56
+ (x (+ @config.xMin (* @i (/ @span 80))))
57
+ (yVal (if (== @kind "power")
58
+ (* @rA (math/pow @x @rB))
59
+ (if (== @kind "linear")
60
+ (+ @rA (* @rB @x))
61
+ (* @rA (math/sin (* @rB @x))))))
62
+ )
63
+ { x: @x, y: @yVal }))))
64
+ (allSamples (array/concat @leftSamples @rightSamples))
65
+ (yMinRaw (array/reduce @allSamples (object/get (array/nth @allSamples 0) y) (fn (acc s) (math/min @acc (object/get @s y)))))
66
+ (yMaxRaw (array/reduce @allSamples (object/get (array/nth @allSamples 0) y) (fn (acc s) (math/max @acc (object/get @s y)))))
67
+ (yPad (* 0.1 (math/max 0.001 (- @yMaxRaw @yMinRaw))))
68
+ (xMidV (/ (+ @config.xMin @config.xMax) 2))
69
+ (lMid (if (== @kind "power") (* @lA (math/pow @xMidV @lB)) (if (== @kind "linear") (+ @lA (* @lB @xMidV)) (* @lA (math/sin (* @lB @xMidV))))))
70
+ (rMid (if (== @kind "power") (* @rA (math/pow @xMidV @rB)) (if (== @kind "linear") (+ @rA (* @rB @xMidV)) (* @rA (math/sin (* @rB @xMidV))))))
71
+ )
72
+ (do
73
+ (set @entity.active true)
74
+ (set @entity.title @config.title)
75
+ (set @entity.curveKind @kind)
76
+ (set @entity.leftA @lA)
77
+ (set @entity.leftB @lB)
78
+ (set @entity.rightA @rA)
79
+ (set @entity.rightB @rB)
80
+ (set @entity.xMid @xMidV)
81
+ (set @entity.leftMid @lMid)
82
+ (set @entity.rightMid @rMid)
83
+ (set @entity.delta (- @rMid @lMid))
84
+ (set @entity.yMin (- @yMinRaw @yPad))
85
+ (set @entity.yMax (+ @yMaxRaw @yPad))
86
+ (set @entity.curves [
87
+ { label: @config.leftLabel, color: @config.leftColor, samples: @leftSamples },
88
+ { label: @config.rightLabel, color: @config.rightColor, samples: @rightSamples }
89
+ ])))
90
+ (render-ui main {
91
+ type: box
92
+ padding: md
93
+ children: [
94
+ { type: stack, direction: vertical, gap: md, children: [
95
+ { type: typography, variant: h4, content: @entity.title },
96
+ { type: typography, variant: body, content: @config.compareText },
97
+ { type: stack, direction: horizontal, gap: lg, children: [
98
+ { type: stack, direction: vertical, gap: xs, children: [
99
+ { type: typography, variant: caption, content: (str/concat @config.leftLabel " — " @config.paramALabel ": " (math/round @entity.leftA 2)) },
100
+ { type: range-slider, min: @config.paramAMin, max: @config.paramAMax, step: @config.paramAStep, value: @entity.leftA, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "left", which: "A" } },
101
+ { type: typography, variant: caption, content: (str/concat @config.leftLabel " — " @config.paramBLabel ": " (math/round @entity.leftB 2)) },
102
+ { type: range-slider, min: @config.paramBMin, max: @config.paramBMax, step: @config.paramBStep, value: @entity.leftB, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "left", which: "B" } }
103
+ ] },
104
+ { type: stack, direction: vertical, gap: xs, children: [
105
+ { type: typography, variant: caption, content: (str/concat @config.rightLabel " — " @config.paramALabel ": " (math/round @entity.rightA 2)) },
106
+ { type: range-slider, min: @config.paramAMin, max: @config.paramAMax, step: @config.paramAStep, value: @entity.rightA, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "right", which: "A" } },
107
+ { type: typography, variant: caption, content: (str/concat @config.rightLabel " — " @config.paramBLabel ": " (math/round @entity.rightB 2)) },
108
+ { type: range-slider, min: @config.paramBMin, max: @config.paramBMax, step: @config.paramBStep, value: @entity.rightB, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "right", which: "B" } }
109
+ ] }
110
+ ] },
111
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: @config.xMin, xMax: @config.xMax, yMin: @entity.yMin, yMax: @entity.yMax, showAxes: @config.showAxes, showGrid: @config.showGrid, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
112
+ { type: typography, variant: body, content: (str/concat "At x=" (math/round @entity.xMid 2) ": " @config.leftLabel " = " (math/round @entity.leftMid 3) ", " @config.rightLabel " = " (math/round @entity.rightMid 3) ", Δ = " (math/round @entity.delta 3)) }
113
+ ] }
114
+ ]
115
+ })
116
+
117
+ MODE_SELECTED -> idle when (== ?mode @config.matchMode)
118
+ (let (
119
+ (kind @config.curveKind)
120
+ (span (- @config.xMax @config.xMin))
121
+ (lA @config.leftADefault)
122
+ (lB @config.leftBDefault)
123
+ (rA @config.rightADefault)
124
+ (rB @config.rightBDefault)
125
+ (leftSamples (array/map (array/range 0 81) (fn (i)
126
+ (let (
127
+ (x (+ @config.xMin (* @i (/ @span 80))))
128
+ (yVal (if (== @kind "power")
129
+ (* @lA (math/pow @x @lB))
130
+ (if (== @kind "linear")
131
+ (+ @lA (* @lB @x))
132
+ (* @lA (math/sin (* @lB @x))))))
133
+ )
134
+ { x: @x, y: @yVal }))))
135
+ (rightSamples (array/map (array/range 0 81) (fn (i)
136
+ (let (
137
+ (x (+ @config.xMin (* @i (/ @span 80))))
138
+ (yVal (if (== @kind "power")
139
+ (* @rA (math/pow @x @rB))
140
+ (if (== @kind "linear")
141
+ (+ @rA (* @rB @x))
142
+ (* @rA (math/sin (* @rB @x))))))
143
+ )
144
+ { x: @x, y: @yVal }))))
145
+ (allSamples (array/concat @leftSamples @rightSamples))
146
+ (yMinRaw (array/reduce @allSamples (object/get (array/nth @allSamples 0) y) (fn (acc s) (math/min @acc (object/get @s y)))))
147
+ (yMaxRaw (array/reduce @allSamples (object/get (array/nth @allSamples 0) y) (fn (acc s) (math/max @acc (object/get @s y)))))
148
+ (yPad (* 0.1 (math/max 0.001 (- @yMaxRaw @yMinRaw))))
149
+ (xMidV (/ (+ @config.xMin @config.xMax) 2))
150
+ (lMid (if (== @kind "power") (* @lA (math/pow @xMidV @lB)) (if (== @kind "linear") (+ @lA (* @lB @xMidV)) (* @lA (math/sin (* @lB @xMidV))))))
151
+ (rMid (if (== @kind "power") (* @rA (math/pow @xMidV @rB)) (if (== @kind "linear") (+ @rA (* @rB @xMidV)) (* @rA (math/sin (* @rB @xMidV))))))
152
+ )
153
+ (do
154
+ (set @entity.active true)
155
+ (set @entity.title @config.title)
156
+ (set @entity.curveKind @kind)
157
+ (set @entity.leftA @lA)
158
+ (set @entity.leftB @lB)
159
+ (set @entity.rightA @rA)
160
+ (set @entity.rightB @rB)
161
+ (set @entity.xMid @xMidV)
162
+ (set @entity.leftMid @lMid)
163
+ (set @entity.rightMid @rMid)
164
+ (set @entity.delta (- @rMid @lMid))
165
+ (set @entity.yMin (- @yMinRaw @yPad))
166
+ (set @entity.yMax (+ @yMaxRaw @yPad))
167
+ (set @entity.curves [
168
+ { label: @config.leftLabel, color: @config.leftColor, samples: @leftSamples },
169
+ { label: @config.rightLabel, color: @config.rightColor, samples: @rightSamples }
170
+ ])))
171
+ (render-ui main {
172
+ type: box
173
+ padding: md
174
+ children: [
175
+ { type: stack, direction: vertical, gap: md, children: [
176
+ { type: typography, variant: h4, content: @entity.title },
177
+ { type: typography, variant: body, content: @config.compareText },
178
+ { type: stack, direction: horizontal, gap: lg, children: [
179
+ { type: stack, direction: vertical, gap: xs, children: [
180
+ { type: typography, variant: caption, content: (str/concat @config.leftLabel " — " @config.paramALabel ": " (math/round @entity.leftA 2)) },
181
+ { type: range-slider, min: @config.paramAMin, max: @config.paramAMax, step: @config.paramAStep, value: @entity.leftA, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "left", which: "A" } },
182
+ { type: typography, variant: caption, content: (str/concat @config.leftLabel " — " @config.paramBLabel ": " (math/round @entity.leftB 2)) },
183
+ { type: range-slider, min: @config.paramBMin, max: @config.paramBMax, step: @config.paramBStep, value: @entity.leftB, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "left", which: "B" } }
184
+ ] },
185
+ { type: stack, direction: vertical, gap: xs, children: [
186
+ { type: typography, variant: caption, content: (str/concat @config.rightLabel " — " @config.paramALabel ": " (math/round @entity.rightA 2)) },
187
+ { type: range-slider, min: @config.paramAMin, max: @config.paramAMax, step: @config.paramAStep, value: @entity.rightA, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "right", which: "A" } },
188
+ { type: typography, variant: caption, content: (str/concat @config.rightLabel " — " @config.paramBLabel ": " (math/round @entity.rightB 2)) },
189
+ { type: range-slider, min: @config.paramBMin, max: @config.paramBMax, step: @config.paramBStep, value: @entity.rightB, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "right", which: "B" } }
190
+ ] }
191
+ ] },
192
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: @config.xMin, xMax: @config.xMax, yMin: @entity.yMin, yMax: @entity.yMax, showAxes: @config.showAxes, showGrid: @config.showGrid, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
193
+ { type: typography, variant: body, content: (str/concat "At x=" (math/round @entity.xMid 2) ": " @config.leftLabel " = " (math/round @entity.leftMid 3) ", " @config.rightLabel " = " (math/round @entity.rightMid 3) ", Δ = " (math/round @entity.delta 3)) }
194
+ ] }
195
+ ]
196
+ })
197
+
198
+ SET_PARAM -> idle when (== @entity.active true)
199
+ (let (
200
+ (kind @entity.curveKind)
201
+ (span (- @config.xMax @config.xMin))
202
+ (lA (if (and (== ?side "left") (== ?which "A")) (math/clamp ?value @config.paramAMin @config.paramAMax) @entity.leftA))
203
+ (lB (if (and (== ?side "left") (== ?which "B")) (math/clamp ?value @config.paramBMin @config.paramBMax) @entity.leftB))
204
+ (rA (if (and (== ?side "right") (== ?which "A")) (math/clamp ?value @config.paramAMin @config.paramAMax) @entity.rightA))
205
+ (rB (if (and (== ?side "right") (== ?which "B")) (math/clamp ?value @config.paramBMin @config.paramBMax) @entity.rightB))
206
+ (leftSamples (array/map (array/range 0 81) (fn (i)
207
+ (let (
208
+ (x (+ @config.xMin (* @i (/ @span 80))))
209
+ (yVal (if (== @kind "power")
210
+ (* @lA (math/pow @x @lB))
211
+ (if (== @kind "linear")
212
+ (+ @lA (* @lB @x))
213
+ (* @lA (math/sin (* @lB @x))))))
214
+ )
215
+ { x: @x, y: @yVal }))))
216
+ (rightSamples (array/map (array/range 0 81) (fn (i)
217
+ (let (
218
+ (x (+ @config.xMin (* @i (/ @span 80))))
219
+ (yVal (if (== @kind "power")
220
+ (* @rA (math/pow @x @rB))
221
+ (if (== @kind "linear")
222
+ (+ @rA (* @rB @x))
223
+ (* @rA (math/sin (* @rB @x))))))
224
+ )
225
+ { x: @x, y: @yVal }))))
226
+ (allSamples (array/concat @leftSamples @rightSamples))
227
+ (yMinRaw (array/reduce @allSamples (object/get (array/nth @allSamples 0) y) (fn (acc s) (math/min @acc (object/get @s y)))))
228
+ (yMaxRaw (array/reduce @allSamples (object/get (array/nth @allSamples 0) y) (fn (acc s) (math/max @acc (object/get @s y)))))
229
+ (yPad (* 0.1 (math/max 0.001 (- @yMaxRaw @yMinRaw))))
230
+ (lMid (if (== @kind "power") (* @lA (math/pow @entity.xMid @lB)) (if (== @kind "linear") (+ @lA (* @lB @entity.xMid)) (* @lA (math/sin (* @lB @entity.xMid))))))
231
+ (rMid (if (== @kind "power") (* @rA (math/pow @entity.xMid @rB)) (if (== @kind "linear") (+ @rA (* @rB @entity.xMid)) (* @rA (math/sin (* @rB @entity.xMid))))))
232
+ )
233
+ (do
234
+ (set @entity.leftA @lA)
235
+ (set @entity.leftB @lB)
236
+ (set @entity.rightA @rA)
237
+ (set @entity.rightB @rB)
238
+ (set @entity.leftMid @lMid)
239
+ (set @entity.rightMid @rMid)
240
+ (set @entity.delta (- @rMid @lMid))
241
+ (set @entity.yMin (- @yMinRaw @yPad))
242
+ (set @entity.yMax (+ @yMaxRaw @yPad))
243
+ (set @entity.curves [
244
+ { label: @config.leftLabel, color: @config.leftColor, samples: @leftSamples },
245
+ { label: @config.rightLabel, color: @config.rightColor, samples: @rightSamples }
246
+ ])))
247
+ (render-ui main {
248
+ type: box
249
+ padding: md
250
+ children: [
251
+ { type: stack, direction: vertical, gap: md, children: [
252
+ { type: typography, variant: h4, content: @entity.title },
253
+ { type: typography, variant: body, content: @config.compareText },
254
+ { type: stack, direction: horizontal, gap: lg, children: [
255
+ { type: stack, direction: vertical, gap: xs, children: [
256
+ { type: typography, variant: caption, content: (str/concat @config.leftLabel " — " @config.paramALabel ": " (math/round @entity.leftA 2)) },
257
+ { type: range-slider, min: @config.paramAMin, max: @config.paramAMax, step: @config.paramAStep, value: @entity.leftA, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "left", which: "A" } },
258
+ { type: typography, variant: caption, content: (str/concat @config.leftLabel " — " @config.paramBLabel ": " (math/round @entity.leftB 2)) },
259
+ { type: range-slider, min: @config.paramBMin, max: @config.paramBMax, step: @config.paramBStep, value: @entity.leftB, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "left", which: "B" } }
260
+ ] },
261
+ { type: stack, direction: vertical, gap: xs, children: [
262
+ { type: typography, variant: caption, content: (str/concat @config.rightLabel " — " @config.paramALabel ": " (math/round @entity.rightA 2)) },
263
+ { type: range-slider, min: @config.paramAMin, max: @config.paramAMax, step: @config.paramAStep, value: @entity.rightA, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "right", which: "A" } },
264
+ { type: typography, variant: caption, content: (str/concat @config.rightLabel " — " @config.paramBLabel ": " (math/round @entity.rightB 2)) },
265
+ { type: range-slider, min: @config.paramBMin, max: @config.paramBMax, step: @config.paramBStep, value: @entity.rightB, showTooltip: true, action: "SET_PARAM", actionPayload: { side: "right", which: "B" } }
266
+ ] }
267
+ ] },
268
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: @config.xMin, xMax: @config.xMax, yMin: @entity.yMin, yMax: @entity.yMax, showAxes: @config.showAxes, showGrid: @config.showGrid, gridStep: @config.gridStep, curves: @entity.curves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
269
+ { type: typography, variant: body, content: (str/concat "At x=" (math/round @entity.xMid 2) ": " @config.leftLabel " = " (math/round @entity.leftMid 3) ", " @config.rightLabel " = " (math/round @entity.rightMid 3) ", Δ = " (math/round @entity.delta 3)) }
270
+ ] }
271
+ ]
272
+ })
273
+ (emit COMPARISON_CHANGED { leftA: @entity.leftA, leftB: @entity.leftB, rightA: @entity.rightA, rightB: @entity.rightB, delta: @entity.delta })
274
+ }
275
+
276
+ listens {
277
+ MODE_SELECTED {
278
+ mode : string
279
+ }
280
+ @description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
281
+ @tier "domain"
282
+ SET_PARAM {
283
+ side : string
284
+ which : string
285
+ value : number
286
+ }
287
+ @description "Learner dragged one of the four sliders — side names the compared instance (left or right), which names the parameter (A or B), value is the new setting; both curves and the delta recompute immediately."
288
+ @tier "domain"
289
+ }
290
+
291
+ emits {
292
+ COMPARISON_CHANGED -> external {
293
+ leftA : number
294
+ leftB : number
295
+ rightA : number
296
+ rightB : number
297
+ delta : number
298
+ }
299
+ @description "Both parameter pairs and the midpoint delta after a slider change — a composed listener (readout, grader) can subscribe; a harmless no-op when the atom runs standalone."
300
+ @synonyms "dual view, side by side, comparator, contrast two settings, A/B comparison"
301
+ @tier "domain"
302
+ }
303
+
304
+ config {
305
+ matchMode : string = ""
306
+ @label "Match Mode"
307
+ @description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
308
+ @tier "presentation"
309
+ title : string = "Compare Two Settings"
310
+ @label "Title"
311
+ @description "Title shown above the canvas."
312
+ @tier "presentation"
313
+ compareText : string = "Tune each side's parameters and watch how the two curves diverge."
314
+ @label "Compare Text"
315
+ @description "One-sentence statement of what is being contrasted."
316
+ @tier "domain"
317
+ curveKind : string = "power"
318
+ @label "Curve Kind"
319
+ @description "Curve family both sides are drawn from: power (y = A·xᴮ), linear (y = A + B·x), or sine (y = A·sin(B·x))."
320
+ @synonyms "curve family, power law, linear function, sine wave, function type"
321
+ @tier "domain"
322
+ leftLabel : string = "Left"
323
+ @label "Left Label"
324
+ @description "Display name of the first compared instance."
325
+ @tier "domain"
326
+ rightLabel : string = "Right"
327
+ @label "Right Label"
328
+ @description "Display name of the second compared instance."
329
+ @tier "domain"
330
+ paramALabel : string = "A"
331
+ @label "Parameter A Label"
332
+ @tier "presentation"
333
+ paramBLabel : string = "B"
334
+ @label "Parameter B Label"
335
+ @tier "presentation"
336
+ paramAMin : number = -5
337
+ @label "Parameter A Min"
338
+ @tier "domain"
339
+ paramAMax : number = 5
340
+ @label "Parameter A Max"
341
+ @tier "domain"
342
+ paramAStep : number = 0.1
343
+ @label "Parameter A Step"
344
+ @tier "presentation"
345
+ paramBMin : number = -5
346
+ @label "Parameter B Min"
347
+ @tier "domain"
348
+ paramBMax : number = 5
349
+ @label "Parameter B Max"
350
+ @tier "domain"
351
+ paramBStep : number = 0.1
352
+ @label "Parameter B Step"
353
+ @tier "presentation"
354
+ leftADefault : number = 1
355
+ @label "Left A Default"
356
+ @tier "domain"
357
+ leftBDefault : number = 2
358
+ @label "Left B Default"
359
+ @tier "domain"
360
+ rightADefault : number = 2
361
+ @label "Right A Default"
362
+ @tier "domain"
363
+ rightBDefault : number = 1.5
364
+ @label "Right B Default"
365
+ @tier "domain"
366
+ leftColor : string = "#3b82f6"
367
+ @label "Left Color"
368
+ @tier "presentation"
369
+ rightColor : string = "#f59e0b"
370
+ @label "Right Color"
371
+ @tier "presentation"
372
+ xMin : number = 0
373
+ @label "X Min"
374
+ @tier "presentation"
375
+ xMax : number = 10
376
+ @label "X Max"
377
+ @tier "presentation"
378
+ width : number = 600
379
+ @label "Width"
380
+ @tier "presentation"
381
+ height : number = 400
382
+ @label "Height"
383
+ @tier "presentation"
384
+ showAxes : boolean = true
385
+ @label "Show Axes"
386
+ @tier "presentation"
387
+ showGrid : boolean = true
388
+ @label "Show Grid"
389
+ @tier "presentation"
390
+ gridStep : number = 1
391
+ @label "Grid Step"
392
+ @tier "presentation"
393
+ }
394
+ }
395
+
396
+ page "/learn-compare" as ComparePage -> CompareSim
397
+ }