@almadar/std 16.243.0 → 16.244.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 (140) hide show
  1. package/behaviors/behaviors-registry.json +4470 -513
  2. package/behaviors/lolo/agent/atoms/std-agent-context.lolo +24 -4
  3. package/behaviors/lolo/agent/atoms/std-agent-memory.lolo +20 -5
  4. package/behaviors/lolo/agent/atoms/std-agent-proposal.lolo +550 -0
  5. package/behaviors/lolo/agent/atoms/std-agent-session.lolo +284 -25
  6. package/behaviors/lolo/agent/atoms/std-agent-suggestions.lolo +841 -0
  7. package/behaviors/lolo/agent/atoms/std-agent-tool-loop.lolo +58 -8
  8. package/behaviors/lolo/agent/organisms/std-agent-assistant.lolo +1 -0
  9. package/behaviors/lolo/infra/atoms/std-page-treat.lolo +28 -1
  10. package/behaviors/lolo/ui/avl/atoms/ui-avl-state-machine.lolo +22 -0
  11. package/behaviors/lolo/ui/avl/atoms/ui-avl-transition-explainer.lolo +175 -0
  12. package/behaviors/lolo/ui/avl/atoms/ui-module-card.lolo +22 -0
  13. package/behaviors/lolo/ui/core/atoms/std-app-layout.lolo +23 -4
  14. package/behaviors/lolo/ui/core/atoms/std-hero.lolo +72 -33
  15. package/behaviors/lolo/ui/core/molecules/ui-agent-chat-feed.lolo +1 -1
  16. package/behaviors/lolo/ui/core/molecules/ui-markdown-content.lolo +54 -0
  17. package/behaviors/lolo/ui/core/molecules/ui-upload-drop-zone.lolo +5 -0
  18. package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +127 -3
  19. package/behaviors/lolo/ui/core/organisms/ui-state-machine-view.lolo +22 -0
  20. package/behaviors/lolo/ui/core/templates/ui-dashboard-layout.lolo +2 -2
  21. package/behaviors/lolo/ui/learning/atoms/std-learn-arrangement.lolo +87 -17
  22. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +172 -37
  23. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +183 -70
  24. package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +78 -13
  25. package/behaviors/lolo/ui/learning/atoms/std-learn-diagram.lolo +58 -2
  26. package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +107 -12
  27. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +83 -10
  28. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +130 -9
  29. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +143 -59
  30. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +96 -22
  31. package/behaviors/lolo/ui/learning/atoms/std-learn-live-sim.lolo +66 -5
  32. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +84 -6
  33. package/behaviors/lolo/ui/learning/atoms/std-learn-sandbox.lolo +80 -14
  34. package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +99 -5
  35. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +81 -7
  36. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +83 -7
  37. package/behaviors/lolo/ui/learning/atoms/std-learn-stepper.lolo +224 -99
  38. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +63 -2
  39. package/behaviors/lolo/ui/learning/atoms/std-learn-trace-player.lolo +99 -38
  40. package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +7 -7
  41. package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +69 -4
  42. package/behaviors/lolo-behavior-contracts.json +1 -1
  43. package/behaviors/registry/agent/atoms/std-agent-context.orb +205 -6
  44. package/behaviors/registry/agent/atoms/std-agent-memory.orb +146 -4
  45. package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1972 -0
  46. package/behaviors/registry/agent/atoms/std-agent-session.orb +2021 -597
  47. package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +5079 -0
  48. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +287 -5
  49. package/behaviors/registry/agent/organisms/std-agent-assistant.orb +7 -0
  50. package/behaviors/registry/factory-signatures.json +1 -1
  51. package/behaviors/registry/infra/atoms/std-page-treat.orb +327 -2
  52. package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +134 -0
  53. package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +678 -0
  54. package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +122 -0
  55. package/behaviors/registry/ui/core/atoms/std-app-layout.orb +73 -4
  56. package/behaviors/registry/ui/core/atoms/std-hero.orb +174 -97
  57. package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +204 -1
  58. package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +12 -0
  59. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +683 -30
  60. package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +748 -21
  61. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1429 -41
  62. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1031 -185
  63. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +807 -132
  64. package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +553 -6
  65. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +987 -21
  66. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +582 -16
  67. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +954 -13
  68. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +828 -88
  69. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +730 -28
  70. package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +479 -9
  71. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +797 -46
  72. package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +757 -58
  73. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1176 -164
  74. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +599 -12
  75. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +832 -150
  76. package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1561 -127
  77. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +655 -6
  78. package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +634 -43
  79. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +85 -31
  80. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +425 -9
  81. package/canonical-operators.json +45 -2
  82. package/dist/behaviors/exports-reader.js +16667 -7868
  83. package/dist/behaviors/functions/index.d.ts +711 -32
  84. package/dist/behaviors/functions/index.js +16651 -7869
  85. package/dist/behaviors/index.d.ts +1 -1
  86. package/dist/behaviors/index.js +16668 -7869
  87. package/dist/behaviors/query.js +16667 -7868
  88. package/dist/behaviors-embeddings.hash.json +3 -3
  89. package/dist/behaviors-embeddings.json +77 -53
  90. package/dist/behaviors-registry.json +4470 -513
  91. package/dist/index.d.ts +3 -3
  92. package/dist/index.js +16101 -7275
  93. package/dist/knob-embeddings.hash.json +3 -3
  94. package/dist/knob-embeddings.json +1309 -685
  95. package/dist/modules/anim.d.ts +1 -1
  96. package/dist/modules/array.d.ts +1 -1
  97. package/dist/modules/async.d.ts +1 -1
  98. package/dist/modules/behavior.d.ts +1 -1
  99. package/dist/modules/browser.d.ts +1 -1
  100. package/dist/modules/composition.d.ts +1 -1
  101. package/dist/modules/contract.d.ts +1 -1
  102. package/dist/modules/core.d.ts +1 -1
  103. package/dist/modules/core.js +29 -2
  104. package/dist/modules/data.d.ts +1 -1
  105. package/dist/modules/ease.d.ts +1 -1
  106. package/dist/modules/format.d.ts +1 -1
  107. package/dist/modules/geo.d.ts +1 -1
  108. package/dist/modules/graph.d.ts +1 -1
  109. package/dist/modules/grid.d.ts +1 -1
  110. package/dist/modules/i18n.d.ts +1 -1
  111. package/dist/modules/index.d.ts +1 -1
  112. package/dist/modules/index.js +29 -2
  113. package/dist/modules/integration.d.ts +1 -1
  114. package/dist/modules/json.d.ts +1 -1
  115. package/dist/modules/llm.d.ts +1 -1
  116. package/dist/modules/math.d.ts +1 -1
  117. package/dist/modules/memory.d.ts +1 -1
  118. package/dist/modules/nn.d.ts +1 -1
  119. package/dist/modules/noise.d.ts +1 -1
  120. package/dist/modules/object.d.ts +1 -1
  121. package/dist/modules/os.d.ts +1 -1
  122. package/dist/modules/path.d.ts +1 -1
  123. package/dist/modules/prob.d.ts +1 -1
  124. package/dist/modules/session.d.ts +1 -1
  125. package/dist/modules/str.d.ts +1 -1
  126. package/dist/modules/tensor.d.ts +1 -1
  127. package/dist/modules/time.d.ts +1 -1
  128. package/dist/modules/trace.d.ts +1 -1
  129. package/dist/modules/train.d.ts +1 -1
  130. package/dist/modules/validate.d.ts +1 -1
  131. package/dist/modules/vector.d.ts +1 -1
  132. package/dist/modules/workspace.d.ts +1 -1
  133. package/dist/registry/factory-signatures.json +1 -1
  134. package/dist/registry.d.ts +2 -2
  135. package/dist/registry.js +29 -2
  136. package/dist/{types-Cdb321uM.d.ts → types-Y-yYWEOX.d.ts} +1 -1
  137. package/i18n/ar.json +3 -1
  138. package/i18n/en.json +2 -0
  139. package/i18n/sl.json +3 -1
  140. package/package.json +3 -3
@@ -63,6 +63,8 @@ orbital LearnClassifyOrbital {
63
63
  entity LearnClassifyScene [runtime] {
64
64
  id : string!
65
65
  active : boolean = false
66
+ items : [LearnClassifyItem]
67
+ categories : [LearnClassifyOption]
66
68
  title : string
67
69
  itemIndex : number
68
70
  itemText : string
@@ -88,7 +90,9 @@ orbital LearnClassifyOrbital {
88
90
  initial: idle
89
91
 
90
92
  state idle {
91
- INIT -> idle when (== @config.matchMode "")
93
+ INIT -> idle when (and (== @config.matchMode "") (== @config.rosterSource "config"))
94
+ (set @entity.items @config.items)
95
+ (set @entity.categories @config.categories)
92
96
  (set @entity.active true)
93
97
  (set @entity.title @config.title)
94
98
  (set @entity.itemIndex 0)
@@ -101,10 +105,10 @@ orbital LearnClassifyOrbital {
101
105
  (set @entity.running @config.autoRun)
102
106
  (set @entity.elapsedMs 0)
103
107
  (set @entity.score 0)
104
- (set @entity.totalItems (array/len @config.items))
105
- (set @entity.categoryStats (array/map @config.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
108
+ (set @entity.totalItems (array/len @entity.items))
109
+ (set @entity.categoryStats (array/map @entity.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
106
110
  (let (
107
- (item (array/nth @config.items 0))
111
+ (item (array/nth @entity.items 0))
108
112
  )
109
113
  (do
110
114
  (set @entity.itemText (object/get @item text))
@@ -114,7 +118,7 @@ orbital LearnClassifyOrbital {
114
118
  )
115
119
  )
116
120
  (let (
117
- (categoryCount (array/len @config.categories))
121
+ (categoryCount (array/len @entity.categories))
118
122
  (marginX 30)
119
123
  (marginY 20)
120
124
  (plotWidth (- @config.width (* @marginX 2)))
@@ -127,7 +131,7 @@ orbital LearnClassifyOrbital {
127
131
  (centerX (/ @config.width 2))
128
132
  (revealed (!= @entity.selectedCategory ""))
129
133
  (rects (array/flatten (array/map (array/range @categoryCount) (fn i (let (
130
- (category (array/nth @config.categories @i))
134
+ (category (array/nth @entity.categories @i))
131
135
  (categoryValue (object/get @category value))
132
136
  (w (- @maxWidth (* @i @widthStep)))
133
137
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
@@ -143,7 +147,7 @@ orbital LearnClassifyOrbital {
143
147
  )
144
148
  )))))
145
149
  (labels (array/map (array/range @categoryCount) (fn i (let (
146
- (category (array/nth @config.categories @i))
150
+ (category (array/nth @entity.categories @i))
147
151
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
148
152
  )
149
153
  { type: text, id: (str/concat "category-label-" @i), x: @centerX, y: (+ @yTop (/ @tierHeight 2) 5), text: (object/get @category label), textSize: "sm", align: "center", tone: "label" }))))
@@ -160,11 +164,11 @@ orbital LearnClassifyOrbital {
160
164
  ] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
161
165
  { type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate, keyMap: { Space: TOGGLE_RUN, ArrowRight: ADVANCE, KeyR: RETRY } },
162
166
  { type: stack, direction: vertical, gap: sm, children: (let (
163
- (itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
167
+ (itemOptions (object/get (array/nth @entity.items @entity.itemIndex) options []))
164
168
  (locked (!= @entity.selectedCategory ""))
165
169
  ) (if (> (array/len @itemOptions) 0)
166
170
  (array/map @itemOptions (fn o { type: button, action: PICK, actionPayload: { category: (object/get @o category) }, label: (object/get @o label), size: lg, disabled: @locked, variant: (if (not @locked) "secondary" (if (== (object/get @o category) @entity.correctCategory) "success" (if (== (object/get @o category) @entity.selectedCategory) "danger" "ghost"))) }))
167
- (array/map (array/reverse @config.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), size: lg, disabled: @locked, variant: (if (not @locked) "secondary" (if (== (object/get @c value) @entity.correctCategory) "success" (if (== (object/get @c value) @entity.selectedCategory) "danger" "ghost"))) })))) },
171
+ (array/map (array/reverse @entity.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), size: lg, disabled: @locked, variant: (if (not @locked) "secondary" (if (== (object/get @c value) @entity.correctCategory) "success" (if (== (object/get @c value) @entity.selectedCategory) "danger" "ghost"))) })))) },
168
172
  (if (== @entity.verdict "") null { type: stack, direction: vertical, gap: xs, children: [
169
173
  { type: badge, variant: (if (== @entity.verdict "correct") "success" "error"), label: (if (== @entity.verdict "correct") "Correct" "Incorrect") },
170
174
  { type: typography, variant: body, content: @entity.feedback }
@@ -204,7 +208,9 @@ orbital LearnClassifyOrbital {
204
208
  (set @entity.running false)
205
209
  (render-ui main null)
206
210
 
207
- MODE_SELECTED -> idle when (== ?mode @config.matchMode)
211
+ MODE_SELECTED -> idle when (and (== ?mode @config.matchMode) (== @config.rosterSource "config"))
212
+ (set @entity.items @config.items)
213
+ (set @entity.categories @config.categories)
208
214
  (set @entity.active true)
209
215
  (set @entity.title @config.title)
210
216
  (set @entity.itemIndex 0)
@@ -217,10 +223,10 @@ orbital LearnClassifyOrbital {
217
223
  (set @entity.running @config.autoRun)
218
224
  (set @entity.elapsedMs 0)
219
225
  (set @entity.score 0)
220
- (set @entity.totalItems (array/len @config.items))
221
- (set @entity.categoryStats (array/map @config.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
226
+ (set @entity.totalItems (array/len @entity.items))
227
+ (set @entity.categoryStats (array/map @entity.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
222
228
  (let (
223
- (item (array/nth @config.items 0))
229
+ (item (array/nth @entity.items 0))
224
230
  )
225
231
  (do
226
232
  (set @entity.itemText (object/get @item text))
@@ -230,7 +236,7 @@ orbital LearnClassifyOrbital {
230
236
  )
231
237
  )
232
238
  (let (
233
- (categoryCount (array/len @config.categories))
239
+ (categoryCount (array/len @entity.categories))
234
240
  (marginX 30)
235
241
  (marginY 20)
236
242
  (plotWidth (- @config.width (* @marginX 2)))
@@ -243,7 +249,7 @@ orbital LearnClassifyOrbital {
243
249
  (centerX (/ @config.width 2))
244
250
  (revealed (!= @entity.selectedCategory ""))
245
251
  (rects (array/flatten (array/map (array/range @categoryCount) (fn i (let (
246
- (category (array/nth @config.categories @i))
252
+ (category (array/nth @entity.categories @i))
247
253
  (categoryValue (object/get @category value))
248
254
  (w (- @maxWidth (* @i @widthStep)))
249
255
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
@@ -259,7 +265,7 @@ orbital LearnClassifyOrbital {
259
265
  )
260
266
  )))))
261
267
  (labels (array/map (array/range @categoryCount) (fn i (let (
262
- (category (array/nth @config.categories @i))
268
+ (category (array/nth @entity.categories @i))
263
269
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
264
270
  )
265
271
  { type: text, id: (str/concat "category-label-" @i), x: @centerX, y: (+ @yTop (/ @tierHeight 2) 5), text: (object/get @category label), textSize: "sm", align: "center", tone: "label" }))))
@@ -276,10 +282,10 @@ orbital LearnClassifyOrbital {
276
282
  ] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
277
283
  { type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate, keyMap: { Space: TOGGLE_RUN, ArrowRight: ADVANCE, KeyR: RETRY } },
278
284
  { type: stack, direction: horizontal, gap: xs, children: (let (
279
- (itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
285
+ (itemOptions (object/get (array/nth @entity.items @entity.itemIndex) options []))
280
286
  ) (if (> (array/len @itemOptions) 0)
281
287
  (array/map @itemOptions (fn o { type: button, action: PICK, actionPayload: { category: (object/get @o category) }, label: (object/get @o label), variant: (if (== @entity.selectedCategory (object/get @o category)) "primary" "secondary"), size: sm }))
282
- (array/map (array/reverse @config.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
288
+ (array/map (array/reverse @entity.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
283
289
  { type: stack, direction: horizontal, gap: xs, children: (array/concat (if (!= @entity.verdict "") [ { type: badge, variant: (if (== @entity.verdict "correct") "success" "danger"), label: (if (== @entity.verdict "correct") "Correct" "Incorrect") } ] []) [ { type: typography, variant: caption, content: @entity.feedback } ]) },
284
290
  { type: stack, direction: horizontal, gap: sm, children: [
285
291
  { type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
@@ -311,11 +317,129 @@ orbital LearnClassifyOrbital {
311
317
  ]
312
318
  })
313
319
 
320
+ ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (and (== ?mode @config.matchMode) (and (> (array/len ?items) 0) (> (array/len ?categories) 0))))
321
+ (set @entity.items ?items)
322
+ (set @entity.categories ?categories)
323
+ (set @entity.active true)
324
+ (set @entity.title @config.title)
325
+ (set @entity.itemIndex 0)
326
+ (set @entity.correctCount 0)
327
+ (set @entity.attemptedCount 0)
328
+ (set @entity.selectedCategory "")
329
+ (set @entity.feedback "")
330
+ (set @entity.verdict "")
331
+ (set @entity.roundComplete false)
332
+ (set @entity.running @config.autoRun)
333
+ (set @entity.elapsedMs 0)
334
+ (set @entity.score 0)
335
+ (set @entity.totalItems (array/len @entity.items))
336
+ (set @entity.categoryStats (array/map @entity.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
337
+ (let (
338
+ (item (array/nth @entity.items 0))
339
+ )
340
+ (do
341
+ (set @entity.itemText (object/get @item text))
342
+ (set @entity.itemHint (object/get @item hint ""))
343
+ (set @entity.itemExplanation (object/get @item explanation ""))
344
+ (set @entity.correctCategory (object/get @item category))
345
+ )
346
+ )
347
+ (let (
348
+ (categoryCount (array/len @entity.categories))
349
+ (marginX 30)
350
+ (marginY 20)
351
+ (plotWidth (- @config.width (* @marginX 2)))
352
+ (plotHeight (- @config.height (* @marginY 2)))
353
+ (plotBottom (- @config.height @marginY))
354
+ (tierHeight (/ @plotHeight @categoryCount))
355
+ (maxWidth (* @plotWidth 0.95))
356
+ (minWidth (- @maxWidth (* @config.taper (- @maxWidth (* @plotWidth 0.3)))))
357
+ (widthStep (/ (- @maxWidth @minWidth) (math/max 1 (- @categoryCount 1))))
358
+ (centerX (/ @config.width 2))
359
+ (revealed (!= @entity.selectedCategory ""))
360
+ (rects (array/flatten (array/map (array/range @categoryCount) (fn i (let (
361
+ (category (array/nth @entity.categories @i))
362
+ (categoryValue (object/get @category value))
363
+ (w (- @maxWidth (* @i @widthStep)))
364
+ (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
365
+ (x (- @centerX (/ @w 2)))
366
+ (isCorrectCategory (== @categoryValue @entity.correctCategory))
367
+ (isSelectedCategory (== @categoryValue @entity.selectedCategory))
368
+ (fillColor (if (and @revealed @isCorrectCategory) @config.correctColor (if (and @revealed @isSelectedCategory) @config.incorrectColor (object/get @category color))))
369
+ (baseRect { type: rect, id: (str/concat "category-" @i), x: @x, y: @yTop, width: @w, height: @tierHeight, tone: @fillColor, fillTone: @fillColor, fillStyle: "tint" })
370
+ )
371
+ (if (and @revealed @isSelectedCategory)
372
+ [ @baseRect, { type: rect, id: (str/concat "category-pick-ring-" @i), x: @x, y: @yTop, width: @w, height: @tierHeight, tone: "ink", fillStyle: "outline", stroke: "bold", opacity: 1 } ]
373
+ [ @baseRect ]
374
+ )
375
+ )))))
376
+ (labels (array/map (array/range @categoryCount) (fn i (let (
377
+ (category (array/nth @entity.categories @i))
378
+ (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
379
+ )
380
+ { type: text, id: (str/concat "category-label-" @i), x: @centerX, y: (+ @yTop (/ @tierHeight 2) 5), text: (object/get @category label), textSize: "sm", align: "center", tone: "label" }))))
381
+ (backdropShapes (array/concat @rects @labels))
382
+ (summaryView [
383
+ { type: typography, variant: h4, content: "Round Complete" },
384
+ { type: stat-display, label: "Final Score", value: @entity.correctCount, max: @entity.attemptedCount },
385
+ { type: stack, direction: vertical, gap: xs, children: (array/map @entity.categoryStats (fn s { type: typography, variant: body, content: (str/concat (object/get @s label) ": " (str/concat "" (object/get @s correct)) "/" (str/concat "" (object/get @s attempted))) })) },
386
+ { type: button, action: RETRY, label: @config.retryLabel, icon: "rotate-ccw", variant: primary }
387
+ ])
388
+ (itemView [
389
+ { type: card, variant: bordered, padding: md, children: (array/concat [
390
+ { type: typography, variant: body, content: @entity.itemText }
391
+ ] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
392
+ { type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate, keyMap: { Space: TOGGLE_RUN, ArrowRight: ADVANCE, KeyR: RETRY } },
393
+ { type: stack, direction: vertical, gap: sm, children: (let (
394
+ (itemOptions (object/get (array/nth @entity.items @entity.itemIndex) options []))
395
+ (locked (!= @entity.selectedCategory ""))
396
+ ) (if (> (array/len @itemOptions) 0)
397
+ (array/map @itemOptions (fn o { type: button, action: PICK, actionPayload: { category: (object/get @o category) }, label: (object/get @o label), size: lg, disabled: @locked, variant: (if (not @locked) "secondary" (if (== (object/get @o category) @entity.correctCategory) "success" (if (== (object/get @o category) @entity.selectedCategory) "danger" "ghost"))) }))
398
+ (array/map (array/reverse @entity.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), size: lg, disabled: @locked, variant: (if (not @locked) "secondary" (if (== (object/get @c value) @entity.correctCategory) "success" (if (== (object/get @c value) @entity.selectedCategory) "danger" "ghost"))) })))) },
399
+ (if (== @entity.verdict "") null { type: stack, direction: vertical, gap: xs, children: [
400
+ { type: badge, variant: (if (== @entity.verdict "correct") "success" "error"), label: (if (== @entity.verdict "correct") "Correct" "Incorrect") },
401
+ { type: typography, variant: body, content: @entity.feedback }
402
+ ] }),
403
+ { type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
404
+ { type: button, action: ADVANCE, label: @config.advanceLabel, icon: "chevron-right", variant: primary, disabled: (== @entity.selectedCategory "") },
405
+ (if @entity.running { type: button, action: TOGGLE_RUN, label: "Pause", icon: "pause", variant: ghost, aria-pressed: "true" } { type: button, action: TOGGLE_RUN, label: "Auto", icon: "play", variant: ghost, aria-pressed: "false" }),
406
+ (if (> @config.passScore 0) { type: typography, variant: caption, color: muted, content: (str/concat "Pass at " @config.passScore) } null)
407
+ ] }
408
+ ])
409
+ )
410
+ (do
411
+ (set @entity.backdropShapes @backdropShapes)
412
+ (set @entity.roundView (if @entity.roundComplete @summaryView @itemView))
413
+ )
414
+ )
415
+ (render-ui main {
416
+ type: box
417
+ padding: md
418
+ children: [
419
+ { type: stack, direction: vertical, gap: md, children: [
420
+ { type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
421
+ { type: stack, direction: vertical, gap: xs, children: [
422
+ { type: typography, variant: h4, content: @entity.title },
423
+ (if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
424
+ ] },
425
+ { type: badge, label: (if @entity.roundComplete "Round complete" (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) (str/concat "Score " @entity.score) (str/concat @entity.correctCount " / " @entity.attemptedCount " correct"))), variant: (if @entity.roundComplete "primary" (if (== @entity.verdict "correct") "success" (if (== @entity.verdict "incorrect") "error" "neutral"))) }
426
+ ] },
427
+ { type: progress-bar, value: (+ @entity.itemIndex 1), max: @entity.totalItems, showPercentage: false, label: (str/concat "Item " (str/concat "" (+ @entity.itemIndex 1)) " of " (str/concat "" @entity.totalItems)) },
428
+ { type: stack, direction: vertical, gap: md, children: @entity.roundView }
429
+ ] }
430
+ ]
431
+ })
432
+
433
+ ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (not (== ?mode @config.matchMode)))
434
+ (set @entity.active false)
435
+ (set @entity.running false)
436
+ (render-ui main null)
437
+
314
438
  PICK -> idle when (and (== @entity.active true) (== @entity.roundComplete false))
315
439
  (set @entity.selectedCategory ?category)
316
440
  (let (
317
441
  (isCorrect (== @entity.selectedCategory @entity.correctCategory))
318
- (correctOption (array/first (array/filter @config.categories (fn c (== (object/get @c value) @entity.correctCategory)))))
442
+ (correctOption (array/first (array/filter @entity.categories (fn c (== (object/get @c value) @entity.correctCategory)))))
319
443
  (baseMessage (if @isCorrect "Correct!" (str/concat "Not quite — the correct answer is " (object/get @correctOption label) ".")))
320
444
  (fullMessage (if (!= @entity.itemExplanation "") (str/concat @baseMessage " " @entity.itemExplanation) @baseMessage))
321
445
  )
@@ -331,7 +455,7 @@ orbital LearnClassifyOrbital {
331
455
  )
332
456
  (set @entity.categoryStats (array/map @entity.categoryStats (fn s (if (== (object/get @s category) @entity.correctCategory) (object/merge @s { attempted: (+ (object/get @s attempted) 1), correct: (if (== @entity.selectedCategory @entity.correctCategory) (+ (object/get @s correct) 1) (object/get @s correct)) }) @s))))
333
457
  (let (
334
- (categoryCount (array/len @config.categories))
458
+ (categoryCount (array/len @entity.categories))
335
459
  (marginX 30)
336
460
  (marginY 20)
337
461
  (plotWidth (- @config.width (* @marginX 2)))
@@ -344,7 +468,7 @@ orbital LearnClassifyOrbital {
344
468
  (centerX (/ @config.width 2))
345
469
  (revealed (!= @entity.selectedCategory ""))
346
470
  (rects (array/flatten (array/map (array/range @categoryCount) (fn i (let (
347
- (category (array/nth @config.categories @i))
471
+ (category (array/nth @entity.categories @i))
348
472
  (categoryValue (object/get @category value))
349
473
  (w (- @maxWidth (* @i @widthStep)))
350
474
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
@@ -360,7 +484,7 @@ orbital LearnClassifyOrbital {
360
484
  )
361
485
  )))))
362
486
  (labels (array/map (array/range @categoryCount) (fn i (let (
363
- (category (array/nth @config.categories @i))
487
+ (category (array/nth @entity.categories @i))
364
488
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
365
489
  )
366
490
  { type: text, id: (str/concat "category-label-" @i), x: @centerX, y: (+ @yTop (/ @tierHeight 2) 5), text: (object/get @category label), textSize: "sm", align: "center", tone: "label" }))))
@@ -377,10 +501,10 @@ orbital LearnClassifyOrbital {
377
501
  ] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
378
502
  { type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate, keyMap: { Space: TOGGLE_RUN, ArrowRight: ADVANCE, KeyR: RETRY } },
379
503
  { type: stack, direction: horizontal, gap: xs, children: (let (
380
- (itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
504
+ (itemOptions (object/get (array/nth @entity.items @entity.itemIndex) options []))
381
505
  ) (if (> (array/len @itemOptions) 0)
382
506
  (array/map @itemOptions (fn o { type: button, action: PICK, actionPayload: { category: (object/get @o category) }, label: (object/get @o label), variant: (if (== @entity.selectedCategory (object/get @o category)) "primary" "secondary"), size: sm }))
383
- (array/map (array/reverse @config.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
507
+ (array/map (array/reverse @entity.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
384
508
  { type: stack, direction: horizontal, gap: xs, children: (array/concat (if (!= @entity.verdict "") [ { type: badge, variant: (if (== @entity.verdict "correct") "success" "danger"), label: (if (== @entity.verdict "correct") "Correct" "Incorrect") } ] []) [ { type: typography, variant: caption, content: @entity.feedback } ]) },
385
509
  { type: stack, direction: horizontal, gap: sm, children: [
386
510
  { type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
@@ -427,7 +551,7 @@ orbital LearnClassifyOrbital {
427
551
  )
428
552
  (let (
429
553
  (nextIndex (if @config.loopRound (math/mod (+ @entity.itemIndex @config.orderStride) @entity.totalItems) (+ @entity.itemIndex @config.orderStride)))
430
- (item (array/nth @config.items @nextIndex))
554
+ (item (array/nth @entity.items @nextIndex))
431
555
  )
432
556
  (do
433
557
  (set @entity.itemIndex @nextIndex)
@@ -443,7 +567,7 @@ orbital LearnClassifyOrbital {
443
567
  )
444
568
  )
445
569
  (let (
446
- (categoryCount (array/len @config.categories))
570
+ (categoryCount (array/len @entity.categories))
447
571
  (marginX 30)
448
572
  (marginY 20)
449
573
  (plotWidth (- @config.width (* @marginX 2)))
@@ -456,7 +580,7 @@ orbital LearnClassifyOrbital {
456
580
  (centerX (/ @config.width 2))
457
581
  (revealed (!= @entity.selectedCategory ""))
458
582
  (rects (array/flatten (array/map (array/range @categoryCount) (fn i (let (
459
- (category (array/nth @config.categories @i))
583
+ (category (array/nth @entity.categories @i))
460
584
  (categoryValue (object/get @category value))
461
585
  (w (- @maxWidth (* @i @widthStep)))
462
586
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
@@ -472,7 +596,7 @@ orbital LearnClassifyOrbital {
472
596
  )
473
597
  )))))
474
598
  (labels (array/map (array/range @categoryCount) (fn i (let (
475
- (category (array/nth @config.categories @i))
599
+ (category (array/nth @entity.categories @i))
476
600
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
477
601
  )
478
602
  { type: text, id: (str/concat "category-label-" @i), x: @centerX, y: (+ @yTop (/ @tierHeight 2) 5), text: (object/get @category label), textSize: "sm", align: "center", tone: "label" }))))
@@ -489,10 +613,10 @@ orbital LearnClassifyOrbital {
489
613
  ] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
490
614
  { type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate, keyMap: { Space: TOGGLE_RUN, ArrowRight: ADVANCE, KeyR: RETRY } },
491
615
  { type: stack, direction: horizontal, gap: xs, children: (let (
492
- (itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
616
+ (itemOptions (object/get (array/nth @entity.items @entity.itemIndex) options []))
493
617
  ) (if (> (array/len @itemOptions) 0)
494
618
  (array/map @itemOptions (fn o { type: button, action: PICK, actionPayload: { category: (object/get @o category) }, label: (object/get @o label), variant: (if (== @entity.selectedCategory (object/get @o category)) "primary" "secondary"), size: sm }))
495
- (array/map (array/reverse @config.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
619
+ (array/map (array/reverse @entity.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
496
620
  { type: stack, direction: horizontal, gap: xs, children: (array/concat (if (!= @entity.verdict "") [ { type: badge, variant: (if (== @entity.verdict "correct") "success" "danger"), label: (if (== @entity.verdict "correct") "Correct" "Incorrect") } ] []) [ { type: typography, variant: caption, content: @entity.feedback } ]) },
497
621
  { type: stack, direction: horizontal, gap: sm, children: [
498
622
  { type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
@@ -537,9 +661,9 @@ orbital LearnClassifyOrbital {
537
661
  (set @entity.feedback "")
538
662
  (set @entity.verdict "")
539
663
  (set @entity.roundComplete false)
540
- (set @entity.categoryStats (array/map @config.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
664
+ (set @entity.categoryStats (array/map @entity.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
541
665
  (let (
542
- (item (array/nth @config.items 0))
666
+ (item (array/nth @entity.items 0))
543
667
  )
544
668
  (do
545
669
  (set @entity.itemText (object/get @item text))
@@ -549,7 +673,7 @@ orbital LearnClassifyOrbital {
549
673
  )
550
674
  )
551
675
  (let (
552
- (categoryCount (array/len @config.categories))
676
+ (categoryCount (array/len @entity.categories))
553
677
  (marginX 30)
554
678
  (marginY 20)
555
679
  (plotWidth (- @config.width (* @marginX 2)))
@@ -562,7 +686,7 @@ orbital LearnClassifyOrbital {
562
686
  (centerX (/ @config.width 2))
563
687
  (revealed (!= @entity.selectedCategory ""))
564
688
  (rects (array/flatten (array/map (array/range @categoryCount) (fn i (let (
565
- (category (array/nth @config.categories @i))
689
+ (category (array/nth @entity.categories @i))
566
690
  (categoryValue (object/get @category value))
567
691
  (w (- @maxWidth (* @i @widthStep)))
568
692
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
@@ -578,7 +702,7 @@ orbital LearnClassifyOrbital {
578
702
  )
579
703
  )))))
580
704
  (labels (array/map (array/range @categoryCount) (fn i (let (
581
- (category (array/nth @config.categories @i))
705
+ (category (array/nth @entity.categories @i))
582
706
  (yTop (- @plotBottom (* (+ @i 1) @tierHeight)))
583
707
  )
584
708
  { type: text, id: (str/concat "category-label-" @i), x: @centerX, y: (+ @yTop (/ @tierHeight 2) 5), text: (object/get @category label), textSize: "sm", align: "center", tone: "label" }))))
@@ -595,10 +719,10 @@ orbital LearnClassifyOrbital {
595
719
  ] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
596
720
  { type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate, keyMap: { Space: TOGGLE_RUN, ArrowRight: ADVANCE, KeyR: RETRY } },
597
721
  { type: stack, direction: horizontal, gap: xs, children: (let (
598
- (itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
722
+ (itemOptions (object/get (array/nth @entity.items @entity.itemIndex) options []))
599
723
  ) (if (> (array/len @itemOptions) 0)
600
724
  (array/map @itemOptions (fn o { type: button, action: PICK, actionPayload: { category: (object/get @o category) }, label: (object/get @o label), variant: (if (== @entity.selectedCategory (object/get @o category)) "primary" "secondary"), size: sm }))
601
- (array/map (array/reverse @config.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
725
+ (array/map (array/reverse @entity.categories) (fn c { type: button, action: PICK, actionPayload: { category: (object/get @c value) }, label: (object/get @c label), variant: (if (== @entity.selectedCategory (object/get @c value)) "primary" "secondary"), size: sm })))) },
602
726
  { type: stack, direction: horizontal, gap: xs, children: (array/concat (if (!= @entity.verdict "") [ { type: badge, variant: (if (== @entity.verdict "correct") "success" "danger"), label: (if (== @entity.verdict "correct") "Correct" "Incorrect") } ] []) [ { type: typography, variant: caption, content: @entity.feedback } ]) },
603
727
  { type: stack, direction: horizontal, gap: sm, children: [
604
728
  { type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
@@ -670,6 +794,13 @@ orbital LearnClassifyOrbital {
670
794
  }
671
795
  @description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
672
796
  @tier "domain"
797
+ ROSTER_LOADED {
798
+ mode : string!
799
+ items : [LearnClassifyItem]!
800
+ categories : [LearnClassifyOption]!
801
+ }
802
+ @description "Runtime content feed, honoured only when rosterSource is event — mode names the instrument it is for (the matchMode it carries, blank when standalone), items is the roster to classify and categories the category buckets; a matching instrument re-initialises from them exactly as INIT does from config, any other instrument hides."
803
+ @tier "domain"
673
804
  PICK {
674
805
  category : string
675
806
  }
@@ -747,6 +878,10 @@ orbital LearnClassifyOrbital {
747
878
  @label "Animate"
748
879
  @description "Enable continuous redraw loop."
749
880
  @tier "presentation"
881
+ rosterSource : "config" | "event" = "config"
882
+ @label "Roster Source"
883
+ @description "Where the roster comes from: config reads the items/categories knob(s) at INIT; event waits for ROSTER_LOADED and takes the roster from its payload."
884
+ @tier "domain"
750
885
  items : [LearnClassifyItem] = [
751
886
  { text: "Example item one.", category: "a", hint: "Consider what makes this belong to category A.", explanation: "This example was written to satisfy category A's defining trait." },
752
887
  { text: "Example item two.", category: "b", hint: "Consider what makes this belong to category B.", explanation: "This example was written to satisfy category B's defining trait." }