@almadar/std 16.174.0 → 16.176.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/ui/core/molecules/ui-table-view.lolo +4 -9
- package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +132 -22
- package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +428 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +520 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +805 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +31 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +186 -0
- package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +522 -0
- package/behaviors/lolo/ui/learning/atoms/ui-algo-graph-canvas.lolo +192 -0
- package/behaviors/lolo/ui/learning/atoms/ui-algorithm-canvas.lolo +111 -2
- package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +150 -1
- package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +132 -1
- package/behaviors/lolo/ui/learning/atoms/ui-learning-canvas.lolo +48 -1
- package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +141 -1
- package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +199 -1
- package/behaviors/registry/ui/core/molecules/ui-table-view.orb +4 -39
- package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1288 -197
- package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +2512 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +3678 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +6539 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +173 -2
- package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +986 -0
- package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +3333 -0
- package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +716 -0
- package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +506 -1
- package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +684 -0
- package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +634 -0
- package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +256 -0
- package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +736 -12
- package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +1061 -33
- package/dist/behaviors/exports-reader.js +2448 -2184
- package/dist/behaviors/functions/index.d.ts +800 -13
- package/dist/behaviors/functions/index.js +2431 -2185
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +2449 -2185
- package/dist/behaviors/query.js +2448 -2184
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +318 -294
- package/dist/behaviors-registry.json +4391 -1298
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2449 -2185
- 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
|
@@ -116,11 +116,6 @@ orbital TableViewOrbital {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
emits {
|
|
119
|
-
@config.itemClickEvent -> external {
|
|
120
|
-
id : string
|
|
121
|
-
}
|
|
122
|
-
@description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract."
|
|
123
|
-
@tier "essential"
|
|
124
119
|
@config.selectEvent -> external {
|
|
125
120
|
id : string
|
|
126
121
|
}
|
|
@@ -185,15 +180,15 @@ orbital TableViewOrbital {
|
|
|
185
180
|
@tier "presentation"
|
|
186
181
|
itemActions : [TableViewItemActionsItem] = []
|
|
187
182
|
@label "Item Actions"
|
|
188
|
-
@description "Per-row
|
|
183
|
+
@description "Per-row actions, collected under a trailing kebab overflow menu."
|
|
189
184
|
@tier "presentation"
|
|
190
185
|
maxInlineActions : number
|
|
191
186
|
@label "Max Inline Actions"
|
|
192
|
-
@description "
|
|
187
|
+
@description "maxInlineActions prop"
|
|
193
188
|
@tier "presentation"
|
|
194
|
-
itemClickEvent : string = "
|
|
189
|
+
itemClickEvent : string = ""
|
|
195
190
|
@label "Item Click Event"
|
|
196
|
-
@description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract."
|
|
191
|
+
@description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract. When OMITTED and `itemActions` exist, the row click defaults to the first non-danger item action (the view/open action by authoring convention) — a danger action never becomes the row default (destructive actions require intentional reach)."
|
|
197
192
|
@tier "presentation"
|
|
198
193
|
selectable : boolean = false
|
|
199
194
|
@label "Selectable"
|
|
@@ -32,11 +32,16 @@ orbital LearnClassifyOrbital {
|
|
|
32
32
|
lineWidth : number
|
|
33
33
|
opacity : number
|
|
34
34
|
}
|
|
35
|
+
type LearnClassifyItemOption = {
|
|
36
|
+
category : string!
|
|
37
|
+
label : string!
|
|
38
|
+
}
|
|
35
39
|
type LearnClassifyItem = {
|
|
36
40
|
text : string!
|
|
37
41
|
category : string!
|
|
38
42
|
hint : string
|
|
39
43
|
explanation : string
|
|
44
|
+
options : [LearnClassifyItemOption]
|
|
40
45
|
}
|
|
41
46
|
type LearnClassifyOption = {
|
|
42
47
|
value : string!
|
|
@@ -66,6 +71,9 @@ orbital LearnClassifyOrbital {
|
|
|
66
71
|
attemptedCount : number
|
|
67
72
|
totalItems : number
|
|
68
73
|
roundComplete : boolean = false
|
|
74
|
+
running : boolean = false
|
|
75
|
+
elapsedMs : number = 0
|
|
76
|
+
score : number = 0
|
|
69
77
|
categoryStats : [LearnClassifyCategoryStat]
|
|
70
78
|
backdropShapes : [LearnClassifyShape]
|
|
71
79
|
roundView : [node]
|
|
@@ -85,6 +93,9 @@ orbital LearnClassifyOrbital {
|
|
|
85
93
|
(set @entity.feedback "")
|
|
86
94
|
(set @entity.verdict "")
|
|
87
95
|
(set @entity.roundComplete false)
|
|
96
|
+
(set @entity.running @config.autoRun)
|
|
97
|
+
(set @entity.elapsedMs 0)
|
|
98
|
+
(set @entity.score 0)
|
|
88
99
|
(set @entity.totalItems (array/len @config.items))
|
|
89
100
|
(set @entity.categoryStats (array/map @config.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
|
|
90
101
|
(let (
|
|
@@ -141,14 +152,19 @@ orbital LearnClassifyOrbital {
|
|
|
141
152
|
(itemView [
|
|
142
153
|
{ type: card, variant: bordered, padding: md, children: (array/concat [
|
|
143
154
|
{ type: typography, variant: body, content: @entity.itemText }
|
|
144
|
-
] (if (!= @entity.itemHint "") [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
155
|
+
] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
145
156
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate },
|
|
146
|
-
{ type: stack, direction: horizontal, gap: xs, children: (
|
|
157
|
+
{ type: stack, direction: horizontal, gap: xs, children: (let (
|
|
158
|
+
(itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
|
|
159
|
+
) (if (> (array/len @itemOptions) 0)
|
|
160
|
+
(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 }))
|
|
161
|
+
(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 })))) },
|
|
147
162
|
{ 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 } ]) },
|
|
148
163
|
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
149
|
-
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) }
|
|
164
|
+
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
|
|
165
|
+
{ type: button, action: TOGGLE_RUN, label: (if @entity.running "Pause" "Auto"), variant: ghost }
|
|
150
166
|
] },
|
|
151
|
-
{ type: stat-display, label: "Score", value: @entity.correctCount, max: @entity.attemptedCount }
|
|
167
|
+
{ type: stat-display, label: (if (> @config.passScore 0) (str/concat "Score — pass at " @config.passScore) "Score"), value: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) @entity.score @entity.correctCount), max: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) (if (> @config.scoreCap 0) @config.scoreCap (* @entity.totalItems @config.pointsPerCorrect)) @entity.attemptedCount) }
|
|
152
168
|
])
|
|
153
169
|
)
|
|
154
170
|
(do
|
|
@@ -178,6 +194,9 @@ orbital LearnClassifyOrbital {
|
|
|
178
194
|
(set @entity.feedback "")
|
|
179
195
|
(set @entity.verdict "")
|
|
180
196
|
(set @entity.roundComplete false)
|
|
197
|
+
(set @entity.running @config.autoRun)
|
|
198
|
+
(set @entity.elapsedMs 0)
|
|
199
|
+
(set @entity.score 0)
|
|
181
200
|
(set @entity.totalItems (array/len @config.items))
|
|
182
201
|
(set @entity.categoryStats (array/map @config.categories (fn c { category: (object/get @c value), label: (object/get @c label), attempted: 0, correct: 0 })))
|
|
183
202
|
(let (
|
|
@@ -234,14 +253,19 @@ orbital LearnClassifyOrbital {
|
|
|
234
253
|
(itemView [
|
|
235
254
|
{ type: card, variant: bordered, padding: md, children: (array/concat [
|
|
236
255
|
{ type: typography, variant: body, content: @entity.itemText }
|
|
237
|
-
] (if (!= @entity.itemHint "") [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
256
|
+
] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
238
257
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate },
|
|
239
|
-
{ type: stack, direction: horizontal, gap: xs, children: (
|
|
258
|
+
{ type: stack, direction: horizontal, gap: xs, children: (let (
|
|
259
|
+
(itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
|
|
260
|
+
) (if (> (array/len @itemOptions) 0)
|
|
261
|
+
(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 }))
|
|
262
|
+
(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 })))) },
|
|
240
263
|
{ 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 } ]) },
|
|
241
264
|
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
242
|
-
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) }
|
|
265
|
+
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
|
|
266
|
+
{ type: button, action: TOGGLE_RUN, label: (if @entity.running "Pause" "Auto"), variant: ghost }
|
|
243
267
|
] },
|
|
244
|
-
{ type: stat-display, label: "Score", value: @entity.correctCount, max: @entity.attemptedCount }
|
|
268
|
+
{ type: stat-display, label: (if (> @config.passScore 0) (str/concat "Score — pass at " @config.passScore) "Score"), value: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) @entity.score @entity.correctCount), max: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) (if (> @config.scoreCap 0) @config.scoreCap (* @entity.totalItems @config.pointsPerCorrect)) @entity.attemptedCount) }
|
|
245
269
|
])
|
|
246
270
|
)
|
|
247
271
|
(do
|
|
@@ -272,6 +296,9 @@ orbital LearnClassifyOrbital {
|
|
|
272
296
|
(do
|
|
273
297
|
(set @entity.attemptedCount (+ @entity.attemptedCount 1))
|
|
274
298
|
(set @entity.correctCount (if @isCorrect (+ @entity.correctCount 1) @entity.correctCount))
|
|
299
|
+
(set @entity.score (let (
|
|
300
|
+
(raw (if @isCorrect (+ @entity.score @config.pointsPerCorrect) (- @entity.score @config.penaltyPerMiss)))
|
|
301
|
+
) (math/max 0 (if (> @config.scoreCap 0) (math/min @raw @config.scoreCap) @raw))))
|
|
275
302
|
(set @entity.verdict (if @isCorrect "correct" "incorrect"))
|
|
276
303
|
(set @entity.feedback @fullMessage)
|
|
277
304
|
)
|
|
@@ -321,14 +348,19 @@ orbital LearnClassifyOrbital {
|
|
|
321
348
|
(itemView [
|
|
322
349
|
{ type: card, variant: bordered, padding: md, children: (array/concat [
|
|
323
350
|
{ type: typography, variant: body, content: @entity.itemText }
|
|
324
|
-
] (if (!= @entity.itemHint "") [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
351
|
+
] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
325
352
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate },
|
|
326
|
-
{ type: stack, direction: horizontal, gap: xs, children: (
|
|
353
|
+
{ type: stack, direction: horizontal, gap: xs, children: (let (
|
|
354
|
+
(itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
|
|
355
|
+
) (if (> (array/len @itemOptions) 0)
|
|
356
|
+
(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 }))
|
|
357
|
+
(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 })))) },
|
|
327
358
|
{ 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 } ]) },
|
|
328
359
|
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
329
|
-
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) }
|
|
360
|
+
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
|
|
361
|
+
{ type: button, action: TOGGLE_RUN, label: (if @entity.running "Pause" "Auto"), variant: ghost }
|
|
330
362
|
] },
|
|
331
|
-
{ type: stat-display, label: "Score", value: @entity.correctCount, max: @entity.attemptedCount }
|
|
363
|
+
{ type: stat-display, label: (if (> @config.passScore 0) (str/concat "Score — pass at " @config.passScore) "Score"), value: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) @entity.score @entity.correctCount), max: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) (if (> @config.scoreCap 0) @config.scoreCap (* @entity.totalItems @config.pointsPerCorrect)) @entity.attemptedCount) }
|
|
332
364
|
])
|
|
333
365
|
)
|
|
334
366
|
(do
|
|
@@ -351,7 +383,7 @@ orbital LearnClassifyOrbital {
|
|
|
351
383
|
|
|
352
384
|
ADVANCE -> idle when (and (== @entity.active true) (== @entity.roundComplete false))
|
|
353
385
|
(let (
|
|
354
|
-
(isLast (>= @entity.itemIndex
|
|
386
|
+
(isLast (and (not @config.loopRound) (>= (+ @entity.itemIndex @config.orderStride) @entity.totalItems)))
|
|
355
387
|
)
|
|
356
388
|
(if @isLast
|
|
357
389
|
(do
|
|
@@ -361,7 +393,7 @@ orbital LearnClassifyOrbital {
|
|
|
361
393
|
(set @entity.verdict "")
|
|
362
394
|
)
|
|
363
395
|
(let (
|
|
364
|
-
(nextIndex (+ @entity.itemIndex
|
|
396
|
+
(nextIndex (if @config.loopRound (math/mod (+ @entity.itemIndex @config.orderStride) @entity.totalItems) (+ @entity.itemIndex @config.orderStride)))
|
|
365
397
|
(item (array/nth @config.items @nextIndex))
|
|
366
398
|
)
|
|
367
399
|
(do
|
|
@@ -421,14 +453,19 @@ orbital LearnClassifyOrbital {
|
|
|
421
453
|
(itemView [
|
|
422
454
|
{ type: card, variant: bordered, padding: md, children: (array/concat [
|
|
423
455
|
{ type: typography, variant: body, content: @entity.itemText }
|
|
424
|
-
] (if (!= @entity.itemHint "") [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
456
|
+
] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
425
457
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate },
|
|
426
|
-
{ type: stack, direction: horizontal, gap: xs, children: (
|
|
458
|
+
{ type: stack, direction: horizontal, gap: xs, children: (let (
|
|
459
|
+
(itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
|
|
460
|
+
) (if (> (array/len @itemOptions) 0)
|
|
461
|
+
(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 }))
|
|
462
|
+
(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 })))) },
|
|
427
463
|
{ 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 } ]) },
|
|
428
464
|
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
429
|
-
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) }
|
|
465
|
+
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
|
|
466
|
+
{ type: button, action: TOGGLE_RUN, label: (if @entity.running "Pause" "Auto"), variant: ghost }
|
|
430
467
|
] },
|
|
431
|
-
{ type: stat-display, label: "Score", value: @entity.correctCount, max: @entity.attemptedCount }
|
|
468
|
+
{ type: stat-display, label: (if (> @config.passScore 0) (str/concat "Score — pass at " @config.passScore) "Score"), value: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) @entity.score @entity.correctCount), max: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) (if (> @config.scoreCap 0) @config.scoreCap (* @entity.totalItems @config.pointsPerCorrect)) @entity.attemptedCount) }
|
|
432
469
|
])
|
|
433
470
|
)
|
|
434
471
|
(do
|
|
@@ -451,6 +488,9 @@ orbital LearnClassifyOrbital {
|
|
|
451
488
|
|
|
452
489
|
RETRY -> idle when (== @entity.roundComplete true)
|
|
453
490
|
(set @entity.active true)
|
|
491
|
+
(set @entity.running @config.autoRun)
|
|
492
|
+
(set @entity.elapsedMs 0)
|
|
493
|
+
(set @entity.score 0)
|
|
454
494
|
(set @entity.itemIndex 0)
|
|
455
495
|
(set @entity.correctCount 0)
|
|
456
496
|
(set @entity.attemptedCount 0)
|
|
@@ -513,14 +553,19 @@ orbital LearnClassifyOrbital {
|
|
|
513
553
|
(itemView [
|
|
514
554
|
{ type: card, variant: bordered, padding: md, children: (array/concat [
|
|
515
555
|
{ type: typography, variant: body, content: @entity.itemText }
|
|
516
|
-
] (if (!= @entity.itemHint "") [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
556
|
+
] (if (and @config.showHint (!= @entity.itemHint "")) [ { type: typography, variant: caption, color: muted, content: @entity.itemHint } ] [])) },
|
|
517
557
|
{ type: biology-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, nodes: [], edges: [], shapes: @backdropShapes, interactive: @config.interactive, animate: @config.animate },
|
|
518
|
-
{ type: stack, direction: horizontal, gap: xs, children: (
|
|
558
|
+
{ type: stack, direction: horizontal, gap: xs, children: (let (
|
|
559
|
+
(itemOptions (object/get (array/nth @config.items @entity.itemIndex) options []))
|
|
560
|
+
) (if (> (array/len @itemOptions) 0)
|
|
561
|
+
(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 }))
|
|
562
|
+
(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 })))) },
|
|
519
563
|
{ 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 } ]) },
|
|
520
564
|
{ type: stack, direction: horizontal, gap: sm, children: [
|
|
521
|
-
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) }
|
|
565
|
+
{ type: button, action: ADVANCE, label: @config.advanceLabel, variant: primary, disabled: (if (== @entity.selectedCategory "") true false) },
|
|
566
|
+
{ type: button, action: TOGGLE_RUN, label: (if @entity.running "Pause" "Auto"), variant: ghost }
|
|
522
567
|
] },
|
|
523
|
-
{ type: stat-display, label: "Score", value: @entity.correctCount, max: @entity.attemptedCount }
|
|
568
|
+
{ type: stat-display, label: (if (> @config.passScore 0) (str/concat "Score — pass at " @config.passScore) "Score"), value: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) @entity.score @entity.correctCount), max: (if (or (!= @config.pointsPerCorrect 1) (> @config.penaltyPerMiss 0)) (if (> @config.scoreCap 0) @config.scoreCap (* @entity.totalItems @config.pointsPerCorrect)) @entity.attemptedCount) }
|
|
524
569
|
])
|
|
525
570
|
)
|
|
526
571
|
(do
|
|
@@ -541,6 +586,31 @@ orbital LearnClassifyOrbital {
|
|
|
541
586
|
})
|
|
542
587
|
(emit CLASSIFY_UPDATED { itemIndex: @entity.itemIndex, correctCount: @entity.correctCount, attemptedCount: @entity.attemptedCount, selectedCategory: @entity.selectedCategory, verdict: @entity.verdict, roundComplete: @entity.roundComplete })
|
|
543
588
|
|
|
589
|
+
TOGGLE_RUN -> idle when (and (== @entity.active true) (== @entity.roundComplete false))
|
|
590
|
+
(set @entity.running (not @entity.running))
|
|
591
|
+
(set @entity.elapsedMs 0)
|
|
592
|
+
(render-ui main {
|
|
593
|
+
type: box
|
|
594
|
+
padding: md
|
|
595
|
+
children: [
|
|
596
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
597
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
598
|
+
{ 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)) },
|
|
599
|
+
{ type: stack, direction: vertical, gap: md, children: @entity.roundView }
|
|
600
|
+
] }
|
|
601
|
+
]
|
|
602
|
+
})
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
ticks {
|
|
606
|
+
advanceTick every 32ms
|
|
607
|
+
when (and (== @entity.active true) (and (== @entity.running true) (== @entity.roundComplete false)))
|
|
608
|
+
(set @entity.elapsedMs (+ @entity.elapsedMs 32))
|
|
609
|
+
(when (>= @entity.elapsedMs @config.advanceMs)
|
|
610
|
+
(do
|
|
611
|
+
(set @entity.elapsedMs 0)
|
|
612
|
+
(emit ADVANCE { })
|
|
613
|
+
))
|
|
544
614
|
}
|
|
545
615
|
|
|
546
616
|
listens {
|
|
@@ -562,6 +632,10 @@ orbital LearnClassifyOrbital {
|
|
|
562
632
|
}
|
|
563
633
|
@description "Learner restarted the round from the summary screen — score, per-category breakdown, and item cursor reset to the beginning."
|
|
564
634
|
@tier "domain"
|
|
635
|
+
TOGGLE_RUN {
|
|
636
|
+
}
|
|
637
|
+
@description "Learner toggled auto-advance: while running, the advance clock steps to the next item every advanceMs milliseconds."
|
|
638
|
+
@tier "domain"
|
|
565
639
|
}
|
|
566
640
|
|
|
567
641
|
emits {
|
|
@@ -634,6 +708,42 @@ orbital LearnClassifyOrbital {
|
|
|
634
708
|
@label "Advance Button Label"
|
|
635
709
|
@description "Label text for the button that advances to the next item."
|
|
636
710
|
@tier "presentation"
|
|
711
|
+
showHint : boolean = true
|
|
712
|
+
@label "Show Hint"
|
|
713
|
+
@description "Show each item's hint line beneath the prompt before the learner picks; hide for a harder drill."
|
|
714
|
+
@tier "domain"
|
|
715
|
+
passScore : number = 0
|
|
716
|
+
@label "Pass Score"
|
|
717
|
+
@description "Target score shown next to the running score as \"pass at N\"; 0 hides the target."
|
|
718
|
+
@tier "domain"
|
|
719
|
+
autoRun : boolean = false
|
|
720
|
+
@label "Auto Run"
|
|
721
|
+
@description "When true the advance clock starts on load and the drill flips to the next item every advanceMs milliseconds; toggle live with the Auto/Pause button."
|
|
722
|
+
@tier "domain"
|
|
723
|
+
advanceMs : number = 900
|
|
724
|
+
@label "Auto-Advance Interval (ms)"
|
|
725
|
+
@description "Milliseconds between automatic advances while running — the 32ms base tick accumulates elapsed time and fires ADVANCE each time this interval elapses."
|
|
726
|
+
@tier "domain"
|
|
727
|
+
orderStride : number = 1
|
|
728
|
+
@label "Order Stride"
|
|
729
|
+
@description "Items advance by this stride through the roster — 1 is sequential; a stride coprime with the roster length (e.g. 3) interleaves the corpus so adjacent items differ."
|
|
730
|
+
@tier "domain"
|
|
731
|
+
loopRound : boolean = false
|
|
732
|
+
@label "Loop Round"
|
|
733
|
+
@description "When true the item cursor wraps past the last item forever (a looping drill) instead of ending the round at the summary screen."
|
|
734
|
+
@tier "domain"
|
|
735
|
+
pointsPerCorrect : number = 1
|
|
736
|
+
@label "Points Per Correct"
|
|
737
|
+
@description "Rubric points added to the score for each correct pick; at the default 1 with no penalty, the plain correct/attempted counts render instead of the rubric score."
|
|
738
|
+
@tier "domain"
|
|
739
|
+
penaltyPerMiss : number = 0
|
|
740
|
+
@label "Penalty Per Miss"
|
|
741
|
+
@description "Rubric points subtracted for each incorrect pick (score never drops below 0)."
|
|
742
|
+
@tier "domain"
|
|
743
|
+
scoreCap : number = 0
|
|
744
|
+
@label "Score Cap"
|
|
745
|
+
@description "Upper bound on the rubric score; 0 means uncapped."
|
|
746
|
+
@tier "domain"
|
|
637
747
|
retryLabel : string = "Retry Round"
|
|
638
748
|
@label "Retry Button Label"
|
|
639
749
|
@description "Label text for the button that restarts the round from the end-of-round summary."
|