@almadar/std 16.173.0 → 16.174.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/behaviors/lolo/infra/atoms/std-cross-reference.lolo +2 -4
- package/behaviors/lolo/ui/core/atoms/std-board.lolo +5 -9
- package/behaviors/lolo/ui/core/atoms/std-browse.lolo +8 -1
- package/behaviors/lolo/ui/core/atoms/std-esign-flow.lolo +2 -2
- package/behaviors/lolo/ui/core/atoms/std-event-log.lolo +3 -7
- package/behaviors/lolo/ui/core/atoms/std-form-advanced.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/std-image-upload-multi.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/std-list.lolo +3 -3
- package/behaviors/lolo/ui/core/atoms/std-modal.lolo +2 -2
- package/behaviors/lolo/ui/core/atoms/std-multi-party-flow.lolo +2 -4
- package/behaviors/lolo/ui/core/atoms/std-rating-review.lolo +5 -13
- package/behaviors/lolo/ui/core/atoms/std-recurrence.lolo +3 -7
- package/behaviors/lolo/ui/core/atoms/std-saved-search.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/std-signature-capture.lolo +2 -2
- package/behaviors/lolo/ui/core/atoms/std-step-flow.lolo +2 -4
- package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/std-thread.lolo +2 -2
- package/behaviors/lolo/ui/core/atoms/std-vote.lolo +2 -2
- package/behaviors/lolo/ui/core/atoms/std-wizard.lolo +3 -7
- package/behaviors/lolo/ui/core/atoms/ui-atlas-image.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-atlas-panel.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-center.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-hstack.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-icon.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-stack.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-typography.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/ui-vstack.lolo +1 -1
- package/behaviors/lolo/ui/core/molecules/ui-content-renderer.lolo +1 -1
- package/behaviors/lolo/ui/core/molecules/ui-form-layout.lolo +1 -1
- package/behaviors/lolo/ui/core/molecules/ui-grid.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-chat-bar.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-dashboard-grid.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-detail-panel.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-entity-cards.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-entity-list.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-entity-table.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-form-section.lolo +9 -3
- package/behaviors/lolo/ui/core/organisms/ui-form.lolo +9 -3
- package/behaviors/lolo/ui/core/organisms/ui-master-detail.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-media-gallery.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +7 -1
- package/behaviors/lolo/ui/core/organisms/ui-stat-card.lolo +1 -1
- package/behaviors/lolo/ui/core/organisms/ui-subagent-trace-panel.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/ui-action-tile.lolo +1 -1
- package/behaviors/lolo/ui/game/atoms/ui-draw-shape-layer.lolo +41 -9
- package/behaviors/lolo/ui/game/atoms/ui-draw-shape.lolo +40 -8
- package/behaviors/lolo/ui/game/atoms/ui-draw-sprite-layer.lolo +13 -3
- package/behaviors/lolo/ui/game/atoms/ui-draw-sprite.lolo +12 -2
- package/behaviors/lolo/ui/game/atoms/ui-draw-text-layer.lolo +3 -3
- package/behaviors/lolo/ui/game/atoms/ui-draw-text.lolo +2 -2
- package/behaviors/lolo/ui/game/organisms/std-tactics-board-3d.lolo +32 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +1 -1
- package/behaviors/lolo/ui/learning/atoms/std-learn-compare.lolo +397 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +537 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +419 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +591 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +425 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +398 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-measure.lolo +325 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-perturb.lolo +494 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +408 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +307 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-sim-3d.lolo +318 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +336 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +380 -0
- package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +43 -4
- package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +41 -4
- package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +43 -4
- package/behaviors/lolo/ui/marketing/organisms/ui-book-viewer.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-case-study-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-feature-grid-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-hero-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-pricing-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-showcase-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-stats-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-step-flow-organism.lolo +1 -1
- package/behaviors/lolo/ui/marketing/organisms/ui-team-organism.lolo +1 -1
- package/behaviors/registry/agent/atoms/std-agent-session.orb +22 -1
- package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +38 -2
- package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +38 -2
- package/behaviors/registry/agent/organisms/std-agent-rabit.orb +23 -1
- package/behaviors/registry/infra/atoms/std-approval-gate.orb +8 -16
- package/behaviors/registry/infra/atoms/std-cache-aside.orb +31 -62
- package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +16 -32
- package/behaviors/registry/infra/atoms/std-cross-reference.orb +32 -4
- package/behaviors/registry/infra/atoms/std-data-erasure.orb +8 -16
- package/behaviors/registry/infra/atoms/std-mod-queue.orb +8 -16
- package/behaviors/registry/infra/atoms/std-rate-limiter.orb +14 -28
- package/behaviors/registry/infra/atoms/std-row-access-control.orb +30 -2
- package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -2
- package/behaviors/registry/ui/core/atoms/std-board.orb +19 -5
- package/behaviors/registry/ui/core/atoms/std-browse.orb +29 -7
- package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -2
- package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +3 -5
- package/behaviors/registry/ui/core/atoms/std-esign-request.orb +3 -6
- package/behaviors/registry/ui/core/atoms/std-event-log.orb +17 -3
- package/behaviors/registry/ui/core/atoms/std-export.orb +2 -4
- package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
- package/behaviors/registry/ui/core/atoms/std-gallery.orb +9 -18
- package/behaviors/registry/ui/core/atoms/std-graphs.orb +15 -1
- package/behaviors/registry/ui/core/atoms/std-import.orb +2 -4
- package/behaviors/registry/ui/core/atoms/std-list.orb +4 -6
- package/behaviors/registry/ui/core/atoms/std-modal.orb +2 -2
- package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +16 -2
- package/behaviors/registry/ui/core/atoms/std-pagination.orb +15 -1
- package/behaviors/registry/ui/core/atoms/std-rating-review.orb +19 -5
- package/behaviors/registry/ui/core/atoms/std-recurrence.orb +17 -3
- package/behaviors/registry/ui/core/atoms/std-rich-editor.orb +15 -1
- package/behaviors/registry/ui/core/atoms/std-scatter.orb +15 -1
- package/behaviors/registry/ui/core/atoms/std-signature-capture.orb +2 -2
- package/behaviors/registry/ui/core/atoms/std-stats.orb +15 -1
- package/behaviors/registry/ui/core/atoms/std-step-flow.orb +16 -2
- package/behaviors/registry/ui/core/atoms/std-thread.orb +2 -2
- package/behaviors/registry/ui/core/atoms/std-vote.orb +2 -2
- package/behaviors/registry/ui/core/atoms/std-wizard.orb +17 -3
- package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-center.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-hstack.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-icon.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-stack.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-typography.orb +4 -1
- package/behaviors/registry/ui/core/atoms/ui-vstack.orb +4 -1
- package/behaviors/registry/ui/core/molecules/ui-accordion.orb +3 -3
- package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +4 -1
- package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +4 -1
- package/behaviors/registry/ui/core/molecules/ui-grid.orb +4 -1
- package/behaviors/registry/ui/core/molecules/ui-tabs.orb +2 -2
- package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +5 -2
- package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +5 -2
- package/behaviors/registry/ui/core/organisms/ui-entity-cards.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-entity-list.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-entity-table.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-form-section.orb +34 -2
- package/behaviors/registry/ui/core/organisms/ui-form.orb +34 -2
- package/behaviors/registry/ui/core/organisms/ui-master-detail.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +24 -2
- package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +4 -1
- package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
- package/behaviors/registry/ui/core/organisms/ui-ui-slot-renderer.orb +1 -1
- package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +35 -1
- package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +4 -1
- package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +183 -13
- package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +104 -9
- package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +56 -2
- package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +36 -4
- package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +21 -2
- package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +19 -4
- package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +173 -2
- package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1 -1
- package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +2814 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +3183 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +2394 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +3951 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +3458 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +2646 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1979 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +2994 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +2682 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1842 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1648 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +2307 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +2947 -0
- package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +173 -4
- package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +267 -7
- package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +263 -8
- package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +116 -1
- package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +200 -4
- package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +264 -7
- package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +1 -2
- package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +1 -2
- package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +1 -2
- package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +1 -2
- package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +1 -2
- package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +1 -2
- package/behaviors/registry/ui/marketing/organisms/ui-book-viewer.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-case-study-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-feature-grid-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-hero-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-pricing-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-showcase-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-stats-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-step-flow-organism.orb +4 -1
- package/behaviors/registry/ui/marketing/organisms/ui-team-organism.orb +4 -1
- package/dist/behaviors/exports-reader.js +3440 -2189
- package/dist/behaviors/functions/index.d.ts +1751 -154
- package/dist/behaviors/functions/index.js +3402 -2190
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +3441 -2190
- package/dist/behaviors/query.js +3440 -2189
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +230 -178
- package/dist/behaviors-registry.json +4397 -171
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3441 -2190
- package/dist/knob-embeddings.hash.json +3 -3
- package/dist/knob-embeddings.json +1 -1
- package/dist/registry/factory-signatures.json +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
app std-learn-measure "1.0.0"
|
|
2
|
+
"Generic measurement lab — a config-declared signal (sine A·sin(B·t), growth A·(1+B)ᵗ, or half-life decay A·(1/2)^(t/B)) evolves live while Run is engaged, drawing its trace across the chart, and the learner presses Probe to record the instantaneous value as a data point: recorded points accumulate on the chart with a running sample count and mean, teaching the discipline of sampling a changing quantity rather than reading a printed table. Pause freezes time mid-run and Reset clears the experiment. All vocabulary and dynamics are config-declared, so the same mechanism serves any measure-the-system exercise: temperature during a reaction, voltage on a discharging capacitor, population through a season, a pendulum's displacement. Standalone by default; behind a lab router set matchMode and it renders only when MODE_SELECTED matches."
|
|
3
|
+
orbital MeasureOrbital {
|
|
4
|
+
type MeasureSample = {
|
|
5
|
+
x : number!
|
|
6
|
+
y : number!
|
|
7
|
+
}
|
|
8
|
+
type MeasureCurve = {
|
|
9
|
+
label : string
|
|
10
|
+
color : string
|
|
11
|
+
samples : [MeasureSample]!
|
|
12
|
+
}
|
|
13
|
+
type MeasurePoint = {
|
|
14
|
+
x : number!
|
|
15
|
+
y : number!
|
|
16
|
+
color : string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
entity MeasureScene [runtime] {
|
|
20
|
+
id : string!
|
|
21
|
+
active : boolean = false
|
|
22
|
+
title : string
|
|
23
|
+
t : number = 0
|
|
24
|
+
value : number = 0
|
|
25
|
+
running : boolean = false
|
|
26
|
+
traceSamples : [MeasureSample]
|
|
27
|
+
traceCurves : [MeasureCurve]
|
|
28
|
+
points : [MeasurePoint]
|
|
29
|
+
sampleCount : number = 0
|
|
30
|
+
meanValue : number = 0
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
trait MeasureSim -> @rebindable MeasureScene [interaction, instance] {
|
|
34
|
+
initial: idle
|
|
35
|
+
|
|
36
|
+
state idle {
|
|
37
|
+
INIT -> idle when (== @config.matchMode "")
|
|
38
|
+
(set @entity.active true)
|
|
39
|
+
(set @entity.title @config.title)
|
|
40
|
+
(set @entity.t 0)
|
|
41
|
+
(set @entity.value (if (== @config.signalKind "sine") 0 @config.amplitude))
|
|
42
|
+
(set @entity.running false)
|
|
43
|
+
(set @entity.traceSamples [])
|
|
44
|
+
(set @entity.traceCurves [])
|
|
45
|
+
(set @entity.points [])
|
|
46
|
+
(set @entity.sampleCount 0)
|
|
47
|
+
(set @entity.meanValue 0)
|
|
48
|
+
(render-ui main {
|
|
49
|
+
type: box
|
|
50
|
+
padding: md
|
|
51
|
+
children: [
|
|
52
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
53
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
54
|
+
{ type: typography, variant: body, content: @config.taskText },
|
|
55
|
+
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
56
|
+
{ type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
|
|
57
|
+
{ type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
|
|
58
|
+
{ type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
|
|
59
|
+
{ type: button, action: RESET, label: "Reset", variant: ghost }
|
|
60
|
+
] },
|
|
61
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
|
|
62
|
+
{ type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
|
|
63
|
+
{ type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
|
|
64
|
+
] }
|
|
65
|
+
]
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
MODE_SELECTED -> idle when (== ?mode @config.matchMode)
|
|
69
|
+
(set @entity.active true)
|
|
70
|
+
(set @entity.title @config.title)
|
|
71
|
+
(set @entity.t 0)
|
|
72
|
+
(set @entity.value (if (== @config.signalKind "sine") 0 @config.amplitude))
|
|
73
|
+
(set @entity.running false)
|
|
74
|
+
(set @entity.traceSamples [])
|
|
75
|
+
(set @entity.traceCurves [])
|
|
76
|
+
(set @entity.points [])
|
|
77
|
+
(set @entity.sampleCount 0)
|
|
78
|
+
(set @entity.meanValue 0)
|
|
79
|
+
(render-ui main {
|
|
80
|
+
type: box
|
|
81
|
+
padding: md
|
|
82
|
+
children: [
|
|
83
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
84
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
85
|
+
{ type: typography, variant: body, content: @config.taskText },
|
|
86
|
+
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
87
|
+
{ type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
|
|
88
|
+
{ type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
|
|
89
|
+
{ type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
|
|
90
|
+
{ type: button, action: RESET, label: "Reset", variant: ghost }
|
|
91
|
+
] },
|
|
92
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
|
|
93
|
+
{ type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
|
|
94
|
+
{ type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
|
|
95
|
+
] }
|
|
96
|
+
]
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
RUN -> idle when (and (== @entity.active true) (and (== @entity.running false) (< @entity.t @config.duration)))
|
|
100
|
+
(set @entity.running true)
|
|
101
|
+
(render-ui main {
|
|
102
|
+
type: box
|
|
103
|
+
padding: md
|
|
104
|
+
children: [
|
|
105
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
106
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
107
|
+
{ type: typography, variant: body, content: @config.taskText },
|
|
108
|
+
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
109
|
+
{ type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
|
|
110
|
+
{ type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
|
|
111
|
+
{ type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
|
|
112
|
+
{ type: button, action: RESET, label: "Reset", variant: ghost }
|
|
113
|
+
] },
|
|
114
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
|
|
115
|
+
{ type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
|
|
116
|
+
{ type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
|
|
117
|
+
] }
|
|
118
|
+
]
|
|
119
|
+
})
|
|
120
|
+
(emit RUN_TOGGLED { running: @entity.running })
|
|
121
|
+
|
|
122
|
+
PAUSE -> idle when (and (== @entity.active true) (== @entity.running true))
|
|
123
|
+
(set @entity.running false)
|
|
124
|
+
(render-ui main {
|
|
125
|
+
type: box
|
|
126
|
+
padding: md
|
|
127
|
+
children: [
|
|
128
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
129
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
130
|
+
{ type: typography, variant: body, content: @config.taskText },
|
|
131
|
+
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
132
|
+
{ type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
|
|
133
|
+
{ type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
|
|
134
|
+
{ type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
|
|
135
|
+
{ type: button, action: RESET, label: "Reset", variant: ghost }
|
|
136
|
+
] },
|
|
137
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
|
|
138
|
+
{ type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
|
|
139
|
+
{ type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
|
|
140
|
+
] }
|
|
141
|
+
]
|
|
142
|
+
})
|
|
143
|
+
(emit RUN_TOGGLED { running: @entity.running })
|
|
144
|
+
|
|
145
|
+
PROBE -> idle when (and (== @entity.active true) (> @entity.t 0))
|
|
146
|
+
(set @entity.points (array/append @entity.points { x: @entity.t, y: @entity.value, color: @config.probeColor }))
|
|
147
|
+
(set @entity.sampleCount (array/len @entity.points))
|
|
148
|
+
(set @entity.meanValue (array/avg (array/map @entity.points (fn p (object/get @p y)))))
|
|
149
|
+
(render-ui main {
|
|
150
|
+
type: box
|
|
151
|
+
padding: md
|
|
152
|
+
children: [
|
|
153
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
154
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
155
|
+
{ type: typography, variant: body, content: @config.taskText },
|
|
156
|
+
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
157
|
+
{ type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
|
|
158
|
+
{ type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
|
|
159
|
+
{ type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
|
|
160
|
+
{ type: button, action: RESET, label: "Reset", variant: ghost }
|
|
161
|
+
] },
|
|
162
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
|
|
163
|
+
{ type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
|
|
164
|
+
{ type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
|
|
165
|
+
] }
|
|
166
|
+
]
|
|
167
|
+
})
|
|
168
|
+
(emit PROBE_RECORDED { t: @entity.t, value: @entity.value, count: @entity.sampleCount, mean: @entity.meanValue })
|
|
169
|
+
|
|
170
|
+
RESET -> idle when (== @entity.active true)
|
|
171
|
+
(set @entity.t 0)
|
|
172
|
+
(set @entity.value (if (== @config.signalKind "sine") 0 @config.amplitude))
|
|
173
|
+
(set @entity.running false)
|
|
174
|
+
(set @entity.traceSamples [])
|
|
175
|
+
(set @entity.traceCurves [])
|
|
176
|
+
(set @entity.points [])
|
|
177
|
+
(set @entity.sampleCount 0)
|
|
178
|
+
(set @entity.meanValue 0)
|
|
179
|
+
(render-ui main {
|
|
180
|
+
type: box
|
|
181
|
+
padding: md
|
|
182
|
+
children: [
|
|
183
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
184
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
185
|
+
{ type: typography, variant: body, content: @config.taskText },
|
|
186
|
+
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
187
|
+
{ type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
|
|
188
|
+
{ type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
|
|
189
|
+
{ type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
|
|
190
|
+
{ type: button, action: RESET, label: "Reset", variant: ghost }
|
|
191
|
+
] },
|
|
192
|
+
{ type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
|
|
193
|
+
{ type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
|
|
194
|
+
{ type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
|
|
195
|
+
] }
|
|
196
|
+
]
|
|
197
|
+
})
|
|
198
|
+
(emit MEASURE_RESET { duration: @config.duration })
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
ticks {
|
|
202
|
+
measureTick every 100ms
|
|
203
|
+
when (and (== @entity.active true) (== @entity.running true))
|
|
204
|
+
(set @entity.t (math/min @config.duration (+ @entity.t 0.1)))
|
|
205
|
+
(set @entity.value (if (== @config.signalKind "sine")
|
|
206
|
+
(* @config.amplitude (math/sin (* @config.rate @entity.t)))
|
|
207
|
+
(if (== @config.signalKind "growth")
|
|
208
|
+
(* @config.amplitude (math/pow (+ 1 @config.rate) @entity.t))
|
|
209
|
+
(* @config.amplitude (math/pow 0.5 (/ @entity.t @config.rate))))))
|
|
210
|
+
(set @entity.traceSamples (array/append @entity.traceSamples { x: @entity.t, y: @entity.value }))
|
|
211
|
+
(set @entity.traceCurves [ { label: @config.valueLabel, color: @config.signalColor, samples: @entity.traceSamples } ])
|
|
212
|
+
(set @entity.running (if (>= @entity.t @config.duration) false true))
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
listens {
|
|
216
|
+
MODE_SELECTED {
|
|
217
|
+
mode : string
|
|
218
|
+
}
|
|
219
|
+
@description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
|
|
220
|
+
@tier "domain"
|
|
221
|
+
RUN {
|
|
222
|
+
}
|
|
223
|
+
@description "Learner started (or resumed) the signal's evolution; the trace draws live until Pause or the configured duration."
|
|
224
|
+
@tier "domain"
|
|
225
|
+
PAUSE {
|
|
226
|
+
}
|
|
227
|
+
@description "Learner froze the signal mid-run; Probe still works on the frozen value."
|
|
228
|
+
@tier "domain"
|
|
229
|
+
PROBE {
|
|
230
|
+
}
|
|
231
|
+
@description "Learner recorded the signal's instantaneous value as a data point; the sample count and running mean update."
|
|
232
|
+
@tier "domain"
|
|
233
|
+
RESET {
|
|
234
|
+
}
|
|
235
|
+
@description "Learner cleared the experiment — time, trace, and all recorded samples return to zero."
|
|
236
|
+
@tier "domain"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
emits {
|
|
240
|
+
RUN_TOGGLED -> external {
|
|
241
|
+
running : boolean
|
|
242
|
+
}
|
|
243
|
+
@description "The experiment was started or paused — a composed listener (readout, grader) can subscribe; a harmless no-op when the atom runs standalone."
|
|
244
|
+
@tier "domain"
|
|
245
|
+
PROBE_RECORDED -> external {
|
|
246
|
+
t : number
|
|
247
|
+
value : number
|
|
248
|
+
count : number
|
|
249
|
+
mean : number
|
|
250
|
+
}
|
|
251
|
+
@description "A measurement was taken: the probed time and value plus the running sample count and mean."
|
|
252
|
+
@synonyms "measurement lab, probe, sample the signal, record data points, running mean"
|
|
253
|
+
@tier "domain"
|
|
254
|
+
MEASURE_RESET -> external {
|
|
255
|
+
duration : number
|
|
256
|
+
}
|
|
257
|
+
@description "The learner reset the experiment to a clean slate."
|
|
258
|
+
@tier "domain"
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
config {
|
|
262
|
+
matchMode : string = ""
|
|
263
|
+
@label "Match Mode"
|
|
264
|
+
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
|
|
265
|
+
@tier "presentation"
|
|
266
|
+
title : string = "Measurement Lab"
|
|
267
|
+
@label "Title"
|
|
268
|
+
@description "Title shown above the experiment."
|
|
269
|
+
@tier "presentation"
|
|
270
|
+
taskText : string = "Run the signal, then press Probe to record measurements. Watch the running mean settle."
|
|
271
|
+
@label "Task Text"
|
|
272
|
+
@description "One-sentence statement of the measuring task."
|
|
273
|
+
@tier "domain"
|
|
274
|
+
signalKind : string = "sine"
|
|
275
|
+
@label "Signal Kind"
|
|
276
|
+
@description "How the measured quantity evolves: sine (A·sin(B·t)), growth (A·(1+B)ᵗ), or decay (half-life A·(1/2)^(t/B))."
|
|
277
|
+
@synonyms "signal family, oscillation, exponential growth, half-life decay"
|
|
278
|
+
@tier "domain"
|
|
279
|
+
amplitude : number = 5
|
|
280
|
+
@label "Amplitude"
|
|
281
|
+
@description "The A parameter: the signal's scale."
|
|
282
|
+
@tier "domain"
|
|
283
|
+
rate : number = 1.2
|
|
284
|
+
@label "Rate"
|
|
285
|
+
@description "The B parameter: angular rate for sine, growth rate for growth, half-life in seconds for decay."
|
|
286
|
+
@tier "domain"
|
|
287
|
+
duration : number = 12
|
|
288
|
+
@label "Duration"
|
|
289
|
+
@description "Seconds the signal runs before stopping automatically."
|
|
290
|
+
@tier "domain"
|
|
291
|
+
valueLabel : string = "value"
|
|
292
|
+
@label "Value Label"
|
|
293
|
+
@description "Display name of the measured quantity."
|
|
294
|
+
@tier "presentation"
|
|
295
|
+
valueMin : number = -6
|
|
296
|
+
@label "Value Min"
|
|
297
|
+
@description "Lower bound of the chart's y axis."
|
|
298
|
+
@tier "presentation"
|
|
299
|
+
valueMax : number = 6
|
|
300
|
+
@label "Value Max"
|
|
301
|
+
@description "Upper bound of the chart's y axis."
|
|
302
|
+
@tier "presentation"
|
|
303
|
+
gridStep : number = 1
|
|
304
|
+
@label "Grid Step"
|
|
305
|
+
@tier "presentation"
|
|
306
|
+
probeLabel : string = "Probe"
|
|
307
|
+
@label "Probe Label"
|
|
308
|
+
@tier "presentation"
|
|
309
|
+
signalColor : string = "#94a3b8"
|
|
310
|
+
@label "Signal Color"
|
|
311
|
+
@tier "presentation"
|
|
312
|
+
probeColor : string = "#dc2626"
|
|
313
|
+
@label "Probe Color"
|
|
314
|
+
@tier "presentation"
|
|
315
|
+
width : number = 600
|
|
316
|
+
@label "Width"
|
|
317
|
+
@tier "presentation"
|
|
318
|
+
height : number = 360
|
|
319
|
+
@label "Height"
|
|
320
|
+
@tier "presentation"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
page "/learn-measure" as MeasurePage -> MeasureSim
|
|
325
|
+
}
|