@almadar/std 16.242.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.
- package/behaviors/behaviors-registry.json +4470 -513
- package/behaviors/lolo/agent/atoms/std-agent-context.lolo +24 -4
- package/behaviors/lolo/agent/atoms/std-agent-memory.lolo +20 -5
- package/behaviors/lolo/agent/atoms/std-agent-proposal.lolo +550 -0
- package/behaviors/lolo/agent/atoms/std-agent-session.lolo +284 -25
- package/behaviors/lolo/agent/atoms/std-agent-suggestions.lolo +841 -0
- package/behaviors/lolo/agent/atoms/std-agent-tool-loop.lolo +58 -8
- package/behaviors/lolo/agent/organisms/std-agent-assistant.lolo +1 -0
- package/behaviors/lolo/infra/atoms/std-page-search.lolo +3 -1
- package/behaviors/lolo/infra/atoms/std-page-treat.lolo +28 -1
- package/behaviors/lolo/infra/atoms/std-page-watch.lolo +3 -1
- package/behaviors/lolo/ui/avl/atoms/ui-avl-state-machine.lolo +22 -0
- package/behaviors/lolo/ui/avl/atoms/ui-avl-transition-explainer.lolo +175 -0
- package/behaviors/lolo/ui/avl/atoms/ui-module-card.lolo +22 -0
- package/behaviors/lolo/ui/core/atoms/std-app-layout.lolo +23 -4
- package/behaviors/lolo/ui/core/atoms/std-hero.lolo +72 -33
- package/behaviors/lolo/ui/core/molecules/ui-agent-chat-feed.lolo +1 -1
- package/behaviors/lolo/ui/core/molecules/ui-markdown-content.lolo +54 -0
- package/behaviors/lolo/ui/core/molecules/ui-upload-drop-zone.lolo +5 -0
- package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +127 -3
- package/behaviors/lolo/ui/core/organisms/ui-state-machine-view.lolo +22 -0
- package/behaviors/lolo/ui/core/templates/ui-dashboard-layout.lolo +2 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-arrangement.lolo +87 -17
- package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +172 -37
- package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +183 -70
- package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +78 -13
- package/behaviors/lolo/ui/learning/atoms/std-learn-diagram.lolo +58 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +107 -12
- package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +83 -10
- package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +130 -9
- package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +143 -59
- package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +96 -22
- package/behaviors/lolo/ui/learning/atoms/std-learn-live-sim.lolo +66 -5
- package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +84 -6
- package/behaviors/lolo/ui/learning/atoms/std-learn-sandbox.lolo +80 -14
- package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +99 -5
- package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +81 -7
- package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +83 -7
- package/behaviors/lolo/ui/learning/atoms/std-learn-stepper.lolo +224 -99
- package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +63 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-trace-player.lolo +99 -38
- package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +7 -7
- package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +69 -4
- package/behaviors/lolo-behavior-contracts.json +1 -1
- package/behaviors/registry/agent/atoms/std-agent-context.orb +205 -6
- package/behaviors/registry/agent/atoms/std-agent-memory.orb +146 -4
- package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1972 -0
- package/behaviors/registry/agent/atoms/std-agent-session.orb +2021 -597
- package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +5079 -0
- package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +287 -5
- package/behaviors/registry/agent/organisms/std-agent-assistant.orb +7 -0
- package/behaviors/registry/factory-signatures.json +1 -1
- package/behaviors/registry/infra/atoms/std-page-search.orb +19 -1
- package/behaviors/registry/infra/atoms/std-page-treat.orb +327 -2
- package/behaviors/registry/infra/atoms/std-page-watch.orb +19 -1
- package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +134 -0
- package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +678 -0
- package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +122 -0
- package/behaviors/registry/ui/core/atoms/std-app-layout.orb +73 -4
- package/behaviors/registry/ui/core/atoms/std-hero.orb +174 -97
- package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +204 -1
- package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +12 -0
- package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +683 -30
- package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +748 -21
- package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1429 -41
- package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1031 -185
- package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +807 -132
- package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +553 -6
- package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +987 -21
- package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +582 -16
- package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +954 -13
- package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +828 -88
- package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +730 -28
- package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +479 -9
- package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +797 -46
- package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +757 -58
- package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1176 -164
- package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +599 -12
- package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +832 -150
- package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1561 -127
- package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +655 -6
- package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +634 -43
- package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +85 -31
- package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +425 -9
- package/canonical-operators.json +45 -2
- package/dist/behaviors/exports-reader.js +16667 -7868
- package/dist/behaviors/functions/index.d.ts +711 -32
- package/dist/behaviors/functions/index.js +16651 -7869
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +16668 -7869
- package/dist/behaviors/query.js +16667 -7868
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +77 -53
- package/dist/behaviors-registry.json +4470 -513
- package/dist/index.d.ts +3 -3
- package/dist/index.js +16101 -7275
- package/dist/knob-embeddings.hash.json +3 -3
- package/dist/knob-embeddings.json +1309 -685
- package/dist/modules/anim.d.ts +1 -1
- package/dist/modules/array.d.ts +1 -1
- package/dist/modules/async.d.ts +1 -1
- package/dist/modules/behavior.d.ts +1 -1
- package/dist/modules/browser.d.ts +1 -1
- package/dist/modules/composition.d.ts +1 -1
- package/dist/modules/contract.d.ts +1 -1
- package/dist/modules/core.d.ts +1 -1
- package/dist/modules/core.js +29 -2
- package/dist/modules/data.d.ts +1 -1
- package/dist/modules/ease.d.ts +1 -1
- package/dist/modules/format.d.ts +1 -1
- package/dist/modules/geo.d.ts +1 -1
- package/dist/modules/graph.d.ts +1 -1
- package/dist/modules/grid.d.ts +1 -1
- package/dist/modules/i18n.d.ts +1 -1
- package/dist/modules/index.d.ts +1 -1
- package/dist/modules/index.js +29 -2
- package/dist/modules/integration.d.ts +1 -1
- package/dist/modules/json.d.ts +1 -1
- package/dist/modules/llm.d.ts +1 -1
- package/dist/modules/math.d.ts +1 -1
- package/dist/modules/memory.d.ts +1 -1
- package/dist/modules/nn.d.ts +1 -1
- package/dist/modules/noise.d.ts +1 -1
- package/dist/modules/object.d.ts +1 -1
- package/dist/modules/os.d.ts +1 -1
- package/dist/modules/path.d.ts +1 -1
- package/dist/modules/prob.d.ts +1 -1
- package/dist/modules/session.d.ts +1 -1
- package/dist/modules/str.d.ts +1 -1
- package/dist/modules/tensor.d.ts +1 -1
- package/dist/modules/time.d.ts +1 -1
- package/dist/modules/trace.d.ts +1 -1
- package/dist/modules/train.d.ts +1 -1
- package/dist/modules/validate.d.ts +1 -1
- package/dist/modules/vector.d.ts +1 -1
- package/dist/modules/workspace.d.ts +1 -1
- package/dist/registry/factory-signatures.json +1 -1
- package/dist/registry.d.ts +2 -2
- package/dist/registry.js +29 -2
- package/dist/{types-Cdb321uM.d.ts → types-Y-yYWEOX.d.ts} +1 -1
- package/i18n/ar.json +3 -1
- package/i18n/en.json +2 -0
- package/i18n/sl.json +3 -1
- package/package.json +3 -3
|
@@ -16,6 +16,7 @@ orbital LearnLiveSimOrbital {
|
|
|
16
16
|
active : boolean = false
|
|
17
17
|
title : string
|
|
18
18
|
bodies : [LiveSimBody]
|
|
19
|
+
loadedBodies : [LiveSimBody]
|
|
19
20
|
running : boolean = false
|
|
20
21
|
gravity : number = 0
|
|
21
22
|
damping : number = 1
|
|
@@ -27,9 +28,10 @@ orbital LearnLiveSimOrbital {
|
|
|
27
28
|
initial: idle
|
|
28
29
|
|
|
29
30
|
state idle {
|
|
30
|
-
INIT -> idle when (== @config.matchMode "")
|
|
31
|
+
INIT -> idle when (and (== @config.matchMode "") (== @config.rosterSource "config"))
|
|
31
32
|
(set @entity.active true)
|
|
32
33
|
(set @entity.title @config.title)
|
|
34
|
+
(set @entity.loadedBodies @config.bodies)
|
|
33
35
|
(set @entity.bodies @config.bodies)
|
|
34
36
|
(set @entity.running @config.running)
|
|
35
37
|
(set @entity.gravity @config.gravity)
|
|
@@ -74,9 +76,10 @@ orbital LearnLiveSimOrbital {
|
|
|
74
76
|
(set @entity.running false)
|
|
75
77
|
(render-ui main null)
|
|
76
78
|
|
|
77
|
-
MODE_SELECTED -> idle when (== ?mode @config.matchMode)
|
|
79
|
+
MODE_SELECTED -> idle when (and (== ?mode @config.matchMode) (== @config.rosterSource "config"))
|
|
78
80
|
(set @entity.active true)
|
|
79
81
|
(set @entity.title @config.title)
|
|
82
|
+
(set @entity.loadedBodies @config.bodies)
|
|
80
83
|
(set @entity.bodies @config.bodies)
|
|
81
84
|
(set @entity.running @config.running)
|
|
82
85
|
(set @entity.gravity @config.gravity)
|
|
@@ -116,6 +119,54 @@ orbital LearnLiveSimOrbital {
|
|
|
116
119
|
]
|
|
117
120
|
})
|
|
118
121
|
|
|
122
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (and (== ?mode @config.matchMode) (> (array/len ?bodies) 0)))
|
|
123
|
+
(set @entity.active true)
|
|
124
|
+
(set @entity.title @config.title)
|
|
125
|
+
(set @entity.loadedBodies ?bodies)
|
|
126
|
+
(set @entity.bodies ?bodies)
|
|
127
|
+
(set @entity.running @config.running)
|
|
128
|
+
(set @entity.gravity @config.gravity)
|
|
129
|
+
(set @entity.damping @config.damping)
|
|
130
|
+
(set @entity.tickCount 0)
|
|
131
|
+
(set @entity.sampleSpeed 0)
|
|
132
|
+
(render-ui main {
|
|
133
|
+
type: box
|
|
134
|
+
padding: md
|
|
135
|
+
children: [
|
|
136
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
137
|
+
{ type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
|
|
138
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
139
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
140
|
+
(if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
|
|
141
|
+
] },
|
|
142
|
+
{ type: badge, label: (if @entity.running "Running" "Paused"), variant: (if @entity.running "primary" "neutral") }
|
|
143
|
+
] },
|
|
144
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
145
|
+
(if @entity.running { type: button, action: TOGGLE_RUN, label: "Pause", icon: "pause", variant: primary, aria-pressed: "true" } { type: button, action: TOGGLE_RUN, label: "Play", icon: "play", variant: primary, aria-pressed: "false" }),
|
|
146
|
+
{ type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
|
|
147
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "Tick " @entity.tickCount) }
|
|
148
|
+
] },
|
|
149
|
+
{ type: physics-canvas, keyMap: { Space: TOGGLE_RUN, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, bodies: @entity.bodies, showVelocity: @config.showVelocity, showForces: false, velocityScale: @config.velocityScale },
|
|
150
|
+
{ type: stack, direction: vertical, gap: sm, children: [
|
|
151
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
152
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "Gravity: " (math/round @entity.gravity 2)) },
|
|
153
|
+
{ type: range-slider, min: -1, max: 1.5, step: 0.05, value: @entity.gravity, showTooltip: true, action: "SET_GRAVITY" }
|
|
154
|
+
] },
|
|
155
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
156
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "Damping: " (math/round @entity.damping 3)) },
|
|
157
|
+
{ type: range-slider, min: 0.9, max: 1, step: 0.005, value: @entity.damping, showTooltip: true, action: "SET_DAMPING" }
|
|
158
|
+
] }
|
|
159
|
+
] },
|
|
160
|
+
{ type: typography, variant: body, content: (str/concat "Sample body speed " (math/round @entity.sampleSpeed 2)) }
|
|
161
|
+
] }
|
|
162
|
+
]
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (not (== ?mode @config.matchMode)))
|
|
166
|
+
(set @entity.active false)
|
|
167
|
+
(set @entity.running false)
|
|
168
|
+
(render-ui main null)
|
|
169
|
+
|
|
119
170
|
TOGGLE_RUN -> idle when (== @entity.active true)
|
|
120
171
|
(set @entity.running (not @entity.running))
|
|
121
172
|
(render-ui main {
|
|
@@ -225,7 +276,7 @@ orbital LearnLiveSimOrbital {
|
|
|
225
276
|
(emit RUN_TOGGLED { running: @entity.running })
|
|
226
277
|
|
|
227
278
|
RESET -> idle when (== @entity.active true)
|
|
228
|
-
(set @entity.bodies @
|
|
279
|
+
(set @entity.bodies @entity.loadedBodies)
|
|
229
280
|
(set @entity.running false)
|
|
230
281
|
(set @entity.gravity @config.gravity)
|
|
231
282
|
(set @entity.damping @config.damping)
|
|
@@ -404,6 +455,12 @@ orbital LearnLiveSimOrbital {
|
|
|
404
455
|
}
|
|
405
456
|
@description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
|
|
406
457
|
@tier "domain"
|
|
458
|
+
ROSTER_LOADED {
|
|
459
|
+
mode : string!
|
|
460
|
+
bodies : [LiveSimBody]!
|
|
461
|
+
}
|
|
462
|
+
@description "Runtime content feed, honoured only when rosterSource is event — mode names the instrument it is for (the matchMode it carries, blank when standalone) and bodies is the initial body list; a matching instrument re-initialises from it exactly as INIT does from config, any other instrument hides."
|
|
463
|
+
@tier "domain"
|
|
407
464
|
TOGGLE_RUN {
|
|
408
465
|
}
|
|
409
466
|
@description "Learner pressed the Play/Pause toggle — flips the running flag."
|
|
@@ -450,8 +507,12 @@ orbital LearnLiveSimOrbital {
|
|
|
450
507
|
config {
|
|
451
508
|
matchMode : string = ""
|
|
452
509
|
@label "Match Mode"
|
|
453
|
-
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
|
|
510
|
+
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT (or on ROSTER_LOADED when rosterSource is event)."
|
|
454
511
|
@tier "presentation"
|
|
512
|
+
rosterSource : "config" | "event" = "config"
|
|
513
|
+
@label "Roster Source"
|
|
514
|
+
@description "Where the body roster comes from: config reads the bodies knob at INIT; event waits for ROSTER_LOADED and takes the bodies from its payload."
|
|
515
|
+
@tier "domain"
|
|
455
516
|
title : string = "Live Sim"
|
|
456
517
|
@label "Title"
|
|
457
518
|
@description "The instrument's name, the header's one hero."
|
|
@@ -502,7 +563,7 @@ orbital LearnLiveSimOrbital {
|
|
|
502
563
|
{ id: "ball-c", x: 420, y: 40, radius: 11, color: "series-3", vx: 2, vy: -1 }
|
|
503
564
|
]
|
|
504
565
|
@label "Bodies"
|
|
505
|
-
@description "Initial bodies; each carries position (x,y), radius, color, and velocity (vx,vy). Restored on Reset."
|
|
566
|
+
@description "Initial bodies; each carries position (x,y), radius, color, and velocity (vx,vy). Restored on Reset. Used when rosterSource is config."
|
|
506
567
|
@tier "presentation"
|
|
507
568
|
}
|
|
508
569
|
}
|
|
@@ -27,6 +27,7 @@ orbital PredictOrbital {
|
|
|
27
27
|
id : string!
|
|
28
28
|
active : boolean = false
|
|
29
29
|
title : string
|
|
30
|
+
scenarios : [PredictScenario]
|
|
30
31
|
scenarioIndex : number = 0
|
|
31
32
|
totalScenarios : number = 0
|
|
32
33
|
phase : string
|
|
@@ -52,7 +53,7 @@ orbital PredictOrbital {
|
|
|
52
53
|
initial: idle
|
|
53
54
|
|
|
54
55
|
state idle {
|
|
55
|
-
INIT -> idle when (== @config.matchMode "")
|
|
56
|
+
INIT -> idle when (and (== @config.matchMode "") (== @config.rosterSource "config"))
|
|
56
57
|
(let (
|
|
57
58
|
(first (array/nth @config.scenarios 0))
|
|
58
59
|
)
|
|
@@ -60,6 +61,7 @@ orbital PredictOrbital {
|
|
|
60
61
|
(set @entity.active true)
|
|
61
62
|
(set @entity.title @config.title)
|
|
62
63
|
(set @entity.scenarioIndex 0)
|
|
64
|
+
(set @entity.scenarios @config.scenarios)
|
|
63
65
|
(set @entity.totalScenarios (array/len @config.scenarios))
|
|
64
66
|
(set @entity.phase "commit")
|
|
65
67
|
(set @entity.chosenIndex 0)
|
|
@@ -115,7 +117,7 @@ orbital PredictOrbital {
|
|
|
115
117
|
(set @entity.active false)
|
|
116
118
|
(render-ui main null)
|
|
117
119
|
|
|
118
|
-
MODE_SELECTED -> idle when (== ?mode @config.matchMode)
|
|
120
|
+
MODE_SELECTED -> idle when (and (== ?mode @config.matchMode) (== @config.rosterSource "config"))
|
|
119
121
|
(let (
|
|
120
122
|
(first (array/nth @config.scenarios 0))
|
|
121
123
|
)
|
|
@@ -123,6 +125,7 @@ orbital PredictOrbital {
|
|
|
123
125
|
(set @entity.active true)
|
|
124
126
|
(set @entity.title @config.title)
|
|
125
127
|
(set @entity.scenarioIndex 0)
|
|
128
|
+
(set @entity.scenarios @config.scenarios)
|
|
126
129
|
(set @entity.totalScenarios (array/len @config.scenarios))
|
|
127
130
|
(set @entity.phase "commit")
|
|
128
131
|
(set @entity.chosenIndex 0)
|
|
@@ -174,6 +177,71 @@ orbital PredictOrbital {
|
|
|
174
177
|
]
|
|
175
178
|
})
|
|
176
179
|
|
|
180
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (and (== ?mode @config.matchMode) (> (array/len ?scenarios) 0)))
|
|
181
|
+
(let (
|
|
182
|
+
(first (array/nth ?scenarios 0))
|
|
183
|
+
)
|
|
184
|
+
(do
|
|
185
|
+
(set @entity.active true)
|
|
186
|
+
(set @entity.title @config.title)
|
|
187
|
+
(set @entity.scenarioIndex 0)
|
|
188
|
+
(set @entity.scenarios ?scenarios)
|
|
189
|
+
(set @entity.totalScenarios (array/len ?scenarios))
|
|
190
|
+
(set @entity.phase "commit")
|
|
191
|
+
(set @entity.chosenIndex 0)
|
|
192
|
+
(set @entity.frames (object/get @first frames))
|
|
193
|
+
(set @entity.frameIndex 0)
|
|
194
|
+
(set @entity.frameCaption "")
|
|
195
|
+
(set @entity.frameValue 0)
|
|
196
|
+
(set @entity.revealSamples [])
|
|
197
|
+
(set @entity.revealCurves [])
|
|
198
|
+
(set @entity.score 0)
|
|
199
|
+
(set @entity.done false)
|
|
200
|
+
(set @entity.setupText (object/get @first setup))
|
|
201
|
+
(set @entity.question (object/get @first question))
|
|
202
|
+
(set @entity.options (object/get @first options))
|
|
203
|
+
(set @entity.correctIndex (object/get @first correctIndex))
|
|
204
|
+
(set @entity.explanation (object/get @first explanation ""))
|
|
205
|
+
(set @entity.feedback "")
|
|
206
|
+
(set @entity.view [
|
|
207
|
+
{ type: card, variant: bordered, padding: md, children: [
|
|
208
|
+
{ type: typography, variant: body, content: @entity.setupText },
|
|
209
|
+
{ type: typography, variant: h4, content: @entity.question }
|
|
210
|
+
] }
|
|
211
|
+
])))
|
|
212
|
+
(render-ui main {
|
|
213
|
+
type: box
|
|
214
|
+
padding: md
|
|
215
|
+
children: [
|
|
216
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
217
|
+
{ type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
|
|
218
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
219
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
220
|
+
(if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
|
|
221
|
+
] },
|
|
222
|
+
{ type: badge, label: (if @entity.done (str/concat @entity.score " / " @entity.totalScenarios " correct") (if (== @entity.phase "commit") "Predict" (if (== @entity.phase "reveal") "Revealing" (if (== @entity.chosenIndex @entity.correctIndex) "Correct" "Incorrect")))), variant: (if @entity.done "primary" (if (== @entity.phase "judged") (if (== @entity.chosenIndex @entity.correctIndex) "success" "error") "neutral")) }
|
|
223
|
+
] },
|
|
224
|
+
{ type: progress-bar, value: (+ @entity.scenarioIndex 1), max: @entity.totalScenarios, showPercentage: false, label: (str/concat "Scenario " (str/concat "" (+ @entity.scenarioIndex 1)) " of " (str/concat "" @entity.totalScenarios)) },
|
|
225
|
+
{ type: stack, direction: vertical, gap: md, children: @entity.view },
|
|
226
|
+
{ type: stack, direction: vertical, gap: sm, children: (array/map (array/range 0 (array/len @entity.options)) (fn (i)
|
|
227
|
+
{ type: button, action: PREDICT, actionPayload: { index: @i }, label: (array/nth @entity.options @i), size: lg, disabled: (!= @entity.phase "commit"), variant: (if (== @entity.phase "commit") "secondary" (if (== @entity.phase "reveal") (if (== @entity.chosenIndex @i) "primary" "ghost") (if (== @i @entity.correctIndex) "success" (if (== @entity.chosenIndex @i) "danger" "ghost")))) })) },
|
|
228
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: (math/max 1 (- (array/len @entity.frames) 1)), yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.revealCurves, points: [], vectors: [], shapes: [], interactive: false, animate: false, keyMap: { ArrowRight: NEXT, KeyR: RETRY } },
|
|
229
|
+
{ type: typography, variant: body, content: @entity.frameCaption },
|
|
230
|
+
{ type: typography, variant: body, content: @entity.feedback },
|
|
231
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
232
|
+
{ type: button, action: NEXT, label: @config.nextLabel, icon: "chevron-right", variant: primary, disabled: (if (and (== @entity.phase "judged") (== @entity.done false)) false true) },
|
|
233
|
+
{ type: button, action: RETRY, label: @config.retryLabel, icon: "rotate-ccw", variant: ghost, disabled: (if @entity.done false true) },
|
|
234
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "Correct " @entity.score " of " @entity.totalScenarios) }
|
|
235
|
+
] }
|
|
236
|
+
] }
|
|
237
|
+
]
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (not (== ?mode @config.matchMode)))
|
|
242
|
+
(set @entity.active false)
|
|
243
|
+
(render-ui main null)
|
|
244
|
+
|
|
177
245
|
PREDICT -> idle when (and (== @entity.active true) (and (== @entity.phase "commit") (== @entity.done false)))
|
|
178
246
|
(let (
|
|
179
247
|
(frame0 (array/nth @entity.frames 0))
|
|
@@ -190,11 +258,11 @@ orbital PredictOrbital {
|
|
|
190
258
|
(emit PREDICTION_COMMITTED { scenarioIndex: @entity.scenarioIndex, chosenIndex: @entity.chosenIndex })
|
|
191
259
|
|
|
192
260
|
NEXT -> idle when (and (== @entity.active true) (and (== @entity.phase "judged") (== @entity.done false)))
|
|
193
|
-
(if (>= (+ @entity.scenarioIndex 1) (array/len @
|
|
261
|
+
(if (>= (+ @entity.scenarioIndex 1) (array/len @entity.scenarios)) (emit LEARN_ROUND_COMPLETE { score: @entity.score, total: (array/len @entity.scenarios) }) null)
|
|
194
262
|
(let (
|
|
195
263
|
(nextIndex (+ @entity.scenarioIndex 1))
|
|
196
|
-
(finished (>= @nextIndex (array/len @
|
|
197
|
-
(next (array/nth @
|
|
264
|
+
(finished (>= @nextIndex (array/len @entity.scenarios)))
|
|
265
|
+
(next (array/nth @entity.scenarios (math/min @nextIndex (- (array/len @entity.scenarios) 1))))
|
|
198
266
|
)
|
|
199
267
|
(do
|
|
200
268
|
(set @entity.scenarioIndex (if @finished @entity.scenarioIndex @nextIndex))
|
|
@@ -256,7 +324,7 @@ orbital PredictOrbital {
|
|
|
256
324
|
|
|
257
325
|
RETRY -> idle when (and (== @entity.active true) (== @entity.done true))
|
|
258
326
|
(let (
|
|
259
|
-
(first (array/nth @
|
|
327
|
+
(first (array/nth @entity.scenarios 0))
|
|
260
328
|
)
|
|
261
329
|
(do
|
|
262
330
|
(set @entity.scenarioIndex 0)
|
|
@@ -335,6 +403,12 @@ orbital PredictOrbital {
|
|
|
335
403
|
}
|
|
336
404
|
@description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
|
|
337
405
|
@tier "domain"
|
|
406
|
+
ROSTER_LOADED {
|
|
407
|
+
mode : string!
|
|
408
|
+
scenarios : [PredictScenario]!
|
|
409
|
+
}
|
|
410
|
+
@description "Runtime content feed, honoured only when rosterSource is event — mode names the instrument it is for (the matchMode it carries, blank when standalone) and scenarios is the scenario list; a matching instrument re-initialises from it exactly as INIT does from config, any other instrument hides."
|
|
411
|
+
@tier "domain"
|
|
338
412
|
PREDICT {
|
|
339
413
|
index : number
|
|
340
414
|
}
|
|
@@ -384,6 +458,10 @@ orbital PredictOrbital {
|
|
|
384
458
|
@label "Match Mode"
|
|
385
459
|
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
|
|
386
460
|
@tier "presentation"
|
|
461
|
+
rosterSource : "config" | "event" = "config"
|
|
462
|
+
@label "Roster Source"
|
|
463
|
+
@description "Where the scenario roster comes from: config reads the scenarios knob at INIT; event waits for ROSTER_LOADED and takes the roster from its payload."
|
|
464
|
+
@tier "domain"
|
|
387
465
|
title : string = "Predict, Then Watch"
|
|
388
466
|
@label "Title"
|
|
389
467
|
@description "Title shown above the instrument."
|
|
@@ -31,6 +31,8 @@ orbital LearnSandboxOrbital {
|
|
|
31
31
|
id : string!
|
|
32
32
|
active : boolean = false
|
|
33
33
|
title : string
|
|
34
|
+
elements : [LearnSandboxElement]
|
|
35
|
+
links : [LearnSandboxLink]
|
|
34
36
|
enabledIds : [string]
|
|
35
37
|
total : number = 0
|
|
36
38
|
holds : boolean = false
|
|
@@ -43,7 +45,9 @@ orbital LearnSandboxOrbital {
|
|
|
43
45
|
initial: idle
|
|
44
46
|
|
|
45
47
|
state idle {
|
|
46
|
-
INIT -> idle when (== @config.matchMode "")
|
|
48
|
+
INIT -> idle when (and (== @config.matchMode "") (== @config.rosterSource "config"))
|
|
49
|
+
(set @entity.elements @config.elements)
|
|
50
|
+
(set @entity.links @config.links)
|
|
47
51
|
(set @entity.active true)
|
|
48
52
|
(set @entity.title @config.title)
|
|
49
53
|
(set @entity.enabledIds (array/map (array/filter @config.elements (fn e (== (object/get @e enabled true) true))) (fn e (object/get @e id))))
|
|
@@ -76,7 +80,7 @@ orbital LearnSandboxOrbital {
|
|
|
76
80
|
{ type: badge, variant: (if @entity.holds "primary" "warning"), label: (if @entity.holds "Holds" "Does not hold") }
|
|
77
81
|
] },
|
|
78
82
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: @entity.nodes, edges: @entity.edges, shapes: [], interactive: @config.interactive, animate: @config.animate, keyMap: { KeyR: RESET } },
|
|
79
|
-
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @
|
|
83
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @entity.elements (fn e { type: button, action: TOGGLE, actionPayload: { elementId: (object/get @e id) }, label: (if (array/includes @entity.enabledIds (object/get @e id)) (object/get @e label) (str/concat (object/get @e label) " — off")), variant: (if (array/includes @entity.enabledIds (object/get @e id)) "secondary" "ghost"), aria-pressed: (if (array/includes @entity.enabledIds (object/get @e id)) "true" "false") })) },
|
|
80
84
|
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
81
85
|
{ type: button, action: RESET, label: @config.resetLabel, icon: "rotate-ccw", variant: ghost },
|
|
82
86
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Total " @entity.total " of " @config.threshold) }
|
|
@@ -90,7 +94,9 @@ orbital LearnSandboxOrbital {
|
|
|
90
94
|
(set @entity.active false)
|
|
91
95
|
(render-ui main null)
|
|
92
96
|
|
|
93
|
-
MODE_SELECTED -> idle when (== ?mode @config.matchMode)
|
|
97
|
+
MODE_SELECTED -> idle when (and (== ?mode @config.matchMode) (== @config.rosterSource "config"))
|
|
98
|
+
(set @entity.elements @config.elements)
|
|
99
|
+
(set @entity.links @config.links)
|
|
94
100
|
(set @entity.active true)
|
|
95
101
|
(set @entity.title @config.title)
|
|
96
102
|
(set @entity.enabledIds (array/map (array/filter @config.elements (fn e (== (object/get @e enabled true) true))) (fn e (object/get @e id))))
|
|
@@ -123,7 +129,7 @@ orbital LearnSandboxOrbital {
|
|
|
123
129
|
{ type: badge, variant: (if @entity.holds "primary" "warning"), label: (if @entity.holds "Holds" "Does not hold") }
|
|
124
130
|
] },
|
|
125
131
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: @entity.nodes, edges: @entity.edges, shapes: [], interactive: @config.interactive, animate: @config.animate, keyMap: { KeyR: RESET } },
|
|
126
|
-
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @
|
|
132
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @entity.elements (fn e { type: button, action: TOGGLE, actionPayload: { elementId: (object/get @e id) }, label: (if (array/includes @entity.enabledIds (object/get @e id)) (object/get @e label) (str/concat (object/get @e label) " — off")), variant: (if (array/includes @entity.enabledIds (object/get @e id)) "secondary" "ghost"), aria-pressed: (if (array/includes @entity.enabledIds (object/get @e id)) "true" "false") })) },
|
|
127
133
|
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
128
134
|
{ type: button, action: RESET, label: @config.resetLabel, icon: "rotate-ccw", variant: ghost },
|
|
129
135
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Total " @entity.total " of " @config.threshold) }
|
|
@@ -133,15 +139,64 @@ orbital LearnSandboxOrbital {
|
|
|
133
139
|
]
|
|
134
140
|
})
|
|
135
141
|
|
|
142
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (and (== ?mode @config.matchMode) (> (array/len ?elements) 0)))
|
|
143
|
+
(set @entity.elements ?elements)
|
|
144
|
+
(set @entity.links ?links)
|
|
145
|
+
(set @entity.active true)
|
|
146
|
+
(set @entity.title @config.title)
|
|
147
|
+
(set @entity.enabledIds (array/map (array/filter ?elements (fn e (== (object/get @e enabled true) true))) (fn e (object/get @e id))))
|
|
148
|
+
(let (
|
|
149
|
+
(activeElements (array/filter ?elements (fn e (array/includes @entity.enabledIds (object/get @e id)))))
|
|
150
|
+
(total (array/sum (array/map @activeElements (fn e (object/get @e weight)))))
|
|
151
|
+
(holds (>= @total @config.threshold))
|
|
152
|
+
(readout (str/concat @config.outcomeLabel ": total " @total " of " @config.threshold " needed. " (if @holds "Holds." "Does not hold.")))
|
|
153
|
+
(nodes (array/map ?elements (fn e { id: (object/get @e id), x: (object/get @e x), y: (object/get @e y), radius: @config.nodeRadius, color: (if (array/includes @entity.enabledIds (object/get @e id)) @config.enabledColor @config.disabledColor), label: (object/get @e label) })))
|
|
154
|
+
(edges (array/map ?links (fn l { from: (object/get @l from), to: (object/get @l to), color: (if (and (array/includes @entity.enabledIds (object/get @l from)) (array/includes @entity.enabledIds (object/get @l to))) @config.enabledEdgeColor @config.disabledEdgeColor) })))
|
|
155
|
+
)
|
|
156
|
+
(do
|
|
157
|
+
(set @entity.total @total)
|
|
158
|
+
(set @entity.holds @holds)
|
|
159
|
+
(set @entity.readout @readout)
|
|
160
|
+
(set @entity.nodes @nodes)
|
|
161
|
+
(set @entity.edges @edges)
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
(render-ui main {
|
|
165
|
+
type: box
|
|
166
|
+
padding: md
|
|
167
|
+
children: [
|
|
168
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
169
|
+
{ type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
|
|
170
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
171
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
172
|
+
(if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
|
|
173
|
+
] },
|
|
174
|
+
{ type: badge, variant: (if @entity.holds "primary" "warning"), label: (if @entity.holds "Holds" "Does not hold") }
|
|
175
|
+
] },
|
|
176
|
+
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: @entity.nodes, edges: @entity.edges, shapes: [], interactive: @config.interactive, animate: @config.animate, keyMap: { KeyR: RESET } },
|
|
177
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @entity.elements (fn e { type: button, action: TOGGLE, actionPayload: { elementId: (object/get @e id) }, label: (if (array/includes @entity.enabledIds (object/get @e id)) (object/get @e label) (str/concat (object/get @e label) " — off")), variant: (if (array/includes @entity.enabledIds (object/get @e id)) "secondary" "ghost"), aria-pressed: (if (array/includes @entity.enabledIds (object/get @e id)) "true" "false") })) },
|
|
178
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
179
|
+
{ type: button, action: RESET, label: @config.resetLabel, icon: "rotate-ccw", variant: ghost },
|
|
180
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "Total " @entity.total " of " @config.threshold) }
|
|
181
|
+
] },
|
|
182
|
+
{ type: typography, variant: body, content: @entity.readout }
|
|
183
|
+
] }
|
|
184
|
+
]
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (not (== ?mode @config.matchMode)))
|
|
188
|
+
(set @entity.active false)
|
|
189
|
+
(render-ui main null)
|
|
190
|
+
|
|
136
191
|
TOGGLE -> idle when (== @entity.active true)
|
|
137
192
|
(set @entity.enabledIds (if (array/includes @entity.enabledIds ?elementId) (array/filter @entity.enabledIds (fn eid (!= @eid ?elementId))) (array/concat @entity.enabledIds [?elementId])))
|
|
138
193
|
(let (
|
|
139
|
-
(activeElements (array/filter @
|
|
194
|
+
(activeElements (array/filter @entity.elements (fn e (array/includes @entity.enabledIds (object/get @e id)))))
|
|
140
195
|
(total (array/sum (array/map @activeElements (fn e (object/get @e weight)))))
|
|
141
196
|
(holds (>= @total @config.threshold))
|
|
142
197
|
(readout (str/concat @config.outcomeLabel ": total " @total " of " @config.threshold " needed. " (if @holds "Holds." "Does not hold.")))
|
|
143
|
-
(nodes (array/map @
|
|
144
|
-
(edges (array/map @
|
|
198
|
+
(nodes (array/map @entity.elements (fn e { id: (object/get @e id), x: (object/get @e x), y: (object/get @e y), radius: @config.nodeRadius, color: (if (array/includes @entity.enabledIds (object/get @e id)) @config.enabledColor @config.disabledColor), label: (object/get @e label) })))
|
|
199
|
+
(edges (array/map @entity.links (fn l { from: (object/get @l from), to: (object/get @l to), color: (if (and (array/includes @entity.enabledIds (object/get @l from)) (array/includes @entity.enabledIds (object/get @l to))) @config.enabledEdgeColor @config.disabledEdgeColor) })))
|
|
145
200
|
)
|
|
146
201
|
(do
|
|
147
202
|
(set @entity.total @total)
|
|
@@ -164,7 +219,7 @@ orbital LearnSandboxOrbital {
|
|
|
164
219
|
{ type: badge, variant: (if @entity.holds "primary" "warning"), label: (if @entity.holds "Holds" "Does not hold") }
|
|
165
220
|
] },
|
|
166
221
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: @entity.nodes, edges: @entity.edges, shapes: [], interactive: @config.interactive, animate: @config.animate, keyMap: { KeyR: RESET } },
|
|
167
|
-
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @
|
|
222
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @entity.elements (fn e { type: button, action: TOGGLE, actionPayload: { elementId: (object/get @e id) }, label: (if (array/includes @entity.enabledIds (object/get @e id)) (object/get @e label) (str/concat (object/get @e label) " — off")), variant: (if (array/includes @entity.enabledIds (object/get @e id)) "secondary" "ghost"), aria-pressed: (if (array/includes @entity.enabledIds (object/get @e id)) "true" "false") })) },
|
|
168
223
|
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
169
224
|
{ type: button, action: RESET, label: @config.resetLabel, icon: "rotate-ccw", variant: ghost },
|
|
170
225
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Total " @entity.total " of " @config.threshold) }
|
|
@@ -176,14 +231,14 @@ orbital LearnSandboxOrbital {
|
|
|
176
231
|
(emit SYSTEM_CHANGED { total: @entity.total, holds: @entity.holds })
|
|
177
232
|
|
|
178
233
|
RESET -> idle when (== @entity.active true)
|
|
179
|
-
(set @entity.enabledIds (array/map (array/filter @
|
|
234
|
+
(set @entity.enabledIds (array/map (array/filter @entity.elements (fn e (== (object/get @e enabled true) true))) (fn e (object/get @e id))))
|
|
180
235
|
(let (
|
|
181
|
-
(activeElements (array/filter @
|
|
236
|
+
(activeElements (array/filter @entity.elements (fn e (array/includes @entity.enabledIds (object/get @e id)))))
|
|
182
237
|
(total (array/sum (array/map @activeElements (fn e (object/get @e weight)))))
|
|
183
238
|
(holds (>= @total @config.threshold))
|
|
184
239
|
(readout (str/concat @config.outcomeLabel ": total " @total " of " @config.threshold " needed. " (if @holds "Holds." "Does not hold.")))
|
|
185
|
-
(nodes (array/map @
|
|
186
|
-
(edges (array/map @
|
|
240
|
+
(nodes (array/map @entity.elements (fn e { id: (object/get @e id), x: (object/get @e x), y: (object/get @e y), radius: @config.nodeRadius, color: (if (array/includes @entity.enabledIds (object/get @e id)) @config.enabledColor @config.disabledColor), label: (object/get @e label) })))
|
|
241
|
+
(edges (array/map @entity.links (fn l { from: (object/get @l from), to: (object/get @l to), color: (if (and (array/includes @entity.enabledIds (object/get @l from)) (array/includes @entity.enabledIds (object/get @l to))) @config.enabledEdgeColor @config.disabledEdgeColor) })))
|
|
187
242
|
)
|
|
188
243
|
(do
|
|
189
244
|
(set @entity.total @total)
|
|
@@ -206,7 +261,7 @@ orbital LearnSandboxOrbital {
|
|
|
206
261
|
{ type: badge, variant: (if @entity.holds "primary" "warning"), label: (if @entity.holds "Holds" "Does not hold") }
|
|
207
262
|
] },
|
|
208
263
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: @entity.nodes, edges: @entity.edges, shapes: [], interactive: @config.interactive, animate: @config.animate, keyMap: { KeyR: RESET } },
|
|
209
|
-
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @
|
|
264
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: (array/map @entity.elements (fn e { type: button, action: TOGGLE, actionPayload: { elementId: (object/get @e id) }, label: (if (array/includes @entity.enabledIds (object/get @e id)) (object/get @e label) (str/concat (object/get @e label) " — off")), variant: (if (array/includes @entity.enabledIds (object/get @e id)) "secondary" "ghost"), aria-pressed: (if (array/includes @entity.enabledIds (object/get @e id)) "true" "false") })) },
|
|
210
265
|
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
211
266
|
{ type: button, action: RESET, label: @config.resetLabel, icon: "rotate-ccw", variant: ghost },
|
|
212
267
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Total " @entity.total " of " @config.threshold) }
|
|
@@ -224,6 +279,13 @@ orbital LearnSandboxOrbital {
|
|
|
224
279
|
}
|
|
225
280
|
@description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
|
|
226
281
|
@tier "domain"
|
|
282
|
+
ROSTER_LOADED {
|
|
283
|
+
mode : string!
|
|
284
|
+
elements : [LearnSandboxElement]!
|
|
285
|
+
links : [LearnSandboxLink]!
|
|
286
|
+
}
|
|
287
|
+
@description "Runtime content feed, honoured only when rosterSource is event — mode names the instrument it is for (the matchMode it carries, blank when standalone) and elements and links are the element roster and its relationships; a matching instrument re-initialises from it exactly as INIT does from config, any other instrument hides."
|
|
288
|
+
@tier "domain"
|
|
227
289
|
TOGGLE {
|
|
228
290
|
elementId : string
|
|
229
291
|
}
|
|
@@ -253,7 +315,7 @@ orbital LearnSandboxOrbital {
|
|
|
253
315
|
config {
|
|
254
316
|
matchMode : string = ""
|
|
255
317
|
@label "Match Mode"
|
|
256
|
-
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
|
|
318
|
+
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT, or on ROSTER_LOADED when rosterSource is event."
|
|
257
319
|
@tier "presentation"
|
|
258
320
|
title : string = "System Sandbox"
|
|
259
321
|
@label "Title"
|
|
@@ -282,6 +344,10 @@ orbital LearnSandboxOrbital {
|
|
|
282
344
|
@label "Animate"
|
|
283
345
|
@description "Enable continuous redraw loop."
|
|
284
346
|
@tier "presentation"
|
|
347
|
+
rosterSource : "config" | "event" = "config"
|
|
348
|
+
@label "Roster Source"
|
|
349
|
+
@description "Where the roster comes from: config reads elements and links knobs at INIT; event waits for ROSTER_LOADED and takes the roster from its payload."
|
|
350
|
+
@tier "domain"
|
|
285
351
|
elements : [LearnSandboxElement] = [
|
|
286
352
|
{ id: "a", label: "Module A", weight: 15, enabled: true, x: 100, y: 80 },
|
|
287
353
|
{ id: "b", label: "Module B", weight: 20, enabled: true, x: 300, y: 60 },
|