coursmith 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,1901 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "$schema": {
6
+ "type": "string"
7
+ },
8
+ "schemaVersion": {
9
+ "type": "string",
10
+ "const": "1.0"
11
+ },
12
+ "courseId": {
13
+ "description": "Set by the CLI after the first submission; do not invent it.",
14
+ "type": "string",
15
+ "format": "uuid",
16
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
17
+ },
18
+ "meta": {
19
+ "type": "object",
20
+ "properties": {
21
+ "title": {
22
+ "type": "string",
23
+ "minLength": 1,
24
+ "maxLength": 120
25
+ },
26
+ "subtitle": {
27
+ "type": "string",
28
+ "minLength": 1,
29
+ "maxLength": 200
30
+ },
31
+ "description": {
32
+ "type": "string",
33
+ "minLength": 1,
34
+ "maxLength": 2000
35
+ },
36
+ "language": {
37
+ "type": "string",
38
+ "pattern": "^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$",
39
+ "description": "Language of the course content (BCP-47)."
40
+ },
41
+ "difficulty": {
42
+ "type": "string",
43
+ "enum": [
44
+ "beginner",
45
+ "intermediate",
46
+ "advanced"
47
+ ]
48
+ },
49
+ "category": {
50
+ "type": "string",
51
+ "enum": [
52
+ "technology",
53
+ "programming",
54
+ "data-ai",
55
+ "science",
56
+ "mathematics",
57
+ "engineering",
58
+ "business",
59
+ "finance",
60
+ "marketing",
61
+ "design",
62
+ "arts-music",
63
+ "languages",
64
+ "history",
65
+ "humanities",
66
+ "health-wellness",
67
+ "environment",
68
+ "law-policy",
69
+ "personal-development",
70
+ "education",
71
+ "other"
72
+ ]
73
+ },
74
+ "tags": {
75
+ "default": [],
76
+ "maxItems": 10,
77
+ "type": "array",
78
+ "items": {
79
+ "type": "string",
80
+ "pattern": "^[\\p{L}\\p{N}][\\p{L}\\p{N} -]{0,39}$"
81
+ }
82
+ },
83
+ "estimatedMinutes": {
84
+ "type": "integer",
85
+ "minimum": 5,
86
+ "maximum": 600
87
+ },
88
+ "learningObjectives": {
89
+ "minItems": 2,
90
+ "maxItems": 10,
91
+ "type": "array",
92
+ "items": {
93
+ "type": "string",
94
+ "minLength": 1,
95
+ "maxLength": 240
96
+ }
97
+ },
98
+ "prerequisites": {
99
+ "default": [],
100
+ "maxItems": 10,
101
+ "type": "array",
102
+ "items": {
103
+ "type": "string",
104
+ "minLength": 1,
105
+ "maxLength": 240
106
+ }
107
+ },
108
+ "coverImage": {
109
+ "type": "string",
110
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
111
+ "description": "The `id` of an entry in `assets`."
112
+ },
113
+ "accentColor": {
114
+ "description": "Hex color used to tint the course pages.",
115
+ "type": "string",
116
+ "pattern": "^#[0-9a-fA-F]{6}$"
117
+ }
118
+ },
119
+ "required": [
120
+ "title",
121
+ "description",
122
+ "language",
123
+ "difficulty",
124
+ "category",
125
+ "estimatedMinutes",
126
+ "learningObjectives",
127
+ "coverImage"
128
+ ],
129
+ "additionalProperties": false
130
+ },
131
+ "assets": {
132
+ "minItems": 1,
133
+ "maxItems": 60,
134
+ "type": "array",
135
+ "items": {
136
+ "type": "object",
137
+ "properties": {
138
+ "id": {
139
+ "type": "string",
140
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
141
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
142
+ },
143
+ "kind": {
144
+ "type": "string",
145
+ "enum": [
146
+ "image",
147
+ "svg"
148
+ ]
149
+ },
150
+ "file": {
151
+ "type": "string",
152
+ "pattern": "^assets\\/[A-Za-z0-9._-]+\\.(png|jpe?g|webp|svg)$",
153
+ "description": "Path relative to the course folder, e.g. assets/cover.webp."
154
+ },
155
+ "alt": {
156
+ "type": "string",
157
+ "minLength": 1,
158
+ "maxLength": 300,
159
+ "description": "Text alternative for screen readers."
160
+ },
161
+ "caption": {
162
+ "type": "string",
163
+ "minLength": 1,
164
+ "maxLength": 300
165
+ },
166
+ "credit": {
167
+ "type": "string",
168
+ "minLength": 1,
169
+ "maxLength": 200
170
+ },
171
+ "generatedBy": {
172
+ "description": "Tool or model that produced the asset, if AI-generated.",
173
+ "type": "string",
174
+ "minLength": 1,
175
+ "maxLength": 100
176
+ }
177
+ },
178
+ "required": [
179
+ "id",
180
+ "kind",
181
+ "file",
182
+ "alt"
183
+ ],
184
+ "additionalProperties": false
185
+ }
186
+ },
187
+ "sections": {
188
+ "minItems": 1,
189
+ "maxItems": 12,
190
+ "type": "array",
191
+ "items": {
192
+ "type": "object",
193
+ "properties": {
194
+ "id": {
195
+ "type": "string",
196
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
197
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
198
+ },
199
+ "title": {
200
+ "type": "string",
201
+ "minLength": 1,
202
+ "maxLength": 160
203
+ },
204
+ "summary": {
205
+ "type": "string",
206
+ "minLength": 1,
207
+ "maxLength": 600
208
+ },
209
+ "steps": {
210
+ "minItems": 1,
211
+ "maxItems": 15,
212
+ "type": "array",
213
+ "items": {
214
+ "type": "object",
215
+ "properties": {
216
+ "id": {
217
+ "type": "string",
218
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
219
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
220
+ },
221
+ "title": {
222
+ "type": "string",
223
+ "minLength": 1,
224
+ "maxLength": 160
225
+ },
226
+ "visual": {
227
+ "oneOf": [
228
+ {
229
+ "type": "object",
230
+ "properties": {
231
+ "type": {
232
+ "type": "string",
233
+ "const": "chart"
234
+ },
235
+ "title": {
236
+ "type": "string",
237
+ "minLength": 1,
238
+ "maxLength": 200
239
+ },
240
+ "caption": {
241
+ "type": "string",
242
+ "minLength": 1,
243
+ "maxLength": 300
244
+ },
245
+ "spec": {
246
+ "type": "object",
247
+ "propertyNames": {
248
+ "type": "string"
249
+ },
250
+ "additionalProperties": {},
251
+ "description": "Vega-Lite v6 specification. Data must be inline (`data.values`); `url` data sources are rejected."
252
+ }
253
+ },
254
+ "required": [
255
+ "type",
256
+ "spec"
257
+ ],
258
+ "additionalProperties": false
259
+ },
260
+ {
261
+ "type": "object",
262
+ "properties": {
263
+ "type": {
264
+ "type": "string",
265
+ "const": "diagram"
266
+ },
267
+ "syntax": {
268
+ "type": "string",
269
+ "const": "mermaid"
270
+ },
271
+ "code": {
272
+ "type": "string",
273
+ "minLength": 1,
274
+ "maxLength": 8000,
275
+ "description": "Mermaid source. No `click` handlers and no `%%{init}%%` directives."
276
+ },
277
+ "caption": {
278
+ "type": "string",
279
+ "minLength": 1,
280
+ "maxLength": 300
281
+ }
282
+ },
283
+ "required": [
284
+ "type",
285
+ "syntax",
286
+ "code"
287
+ ],
288
+ "additionalProperties": false
289
+ },
290
+ {
291
+ "type": "object",
292
+ "properties": {
293
+ "type": {
294
+ "type": "string",
295
+ "const": "animation"
296
+ },
297
+ "caption": {
298
+ "type": "string",
299
+ "minLength": 1,
300
+ "maxLength": 300
301
+ },
302
+ "animation": {
303
+ "oneOf": [
304
+ {
305
+ "type": "object",
306
+ "properties": {
307
+ "preset": {
308
+ "type": "string",
309
+ "const": "sequence"
310
+ },
311
+ "layout": {
312
+ "default": "row",
313
+ "type": "string",
314
+ "enum": [
315
+ "row",
316
+ "column",
317
+ "grid"
318
+ ]
319
+ },
320
+ "items": {
321
+ "minItems": 2,
322
+ "maxItems": 12,
323
+ "type": "array",
324
+ "items": {
325
+ "type": "object",
326
+ "properties": {
327
+ "label": {
328
+ "type": "string",
329
+ "minLength": 1,
330
+ "maxLength": 80
331
+ },
332
+ "description": {
333
+ "type": "string",
334
+ "minLength": 1,
335
+ "maxLength": 240
336
+ },
337
+ "icon": {
338
+ "description": "A single emoji.",
339
+ "type": "string",
340
+ "maxLength": 8
341
+ }
342
+ },
343
+ "required": [
344
+ "label"
345
+ ],
346
+ "additionalProperties": false
347
+ }
348
+ }
349
+ },
350
+ "required": [
351
+ "preset",
352
+ "items"
353
+ ],
354
+ "additionalProperties": false
355
+ },
356
+ {
357
+ "type": "object",
358
+ "properties": {
359
+ "preset": {
360
+ "type": "string",
361
+ "const": "flow"
362
+ },
363
+ "direction": {
364
+ "default": "LR",
365
+ "type": "string",
366
+ "enum": [
367
+ "LR",
368
+ "TB"
369
+ ]
370
+ },
371
+ "nodes": {
372
+ "minItems": 2,
373
+ "maxItems": 12,
374
+ "type": "array",
375
+ "items": {
376
+ "type": "object",
377
+ "properties": {
378
+ "id": {
379
+ "type": "string",
380
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
381
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
382
+ },
383
+ "label": {
384
+ "type": "string",
385
+ "minLength": 1,
386
+ "maxLength": 60
387
+ }
388
+ },
389
+ "required": [
390
+ "id",
391
+ "label"
392
+ ],
393
+ "additionalProperties": false
394
+ }
395
+ },
396
+ "edges": {
397
+ "minItems": 1,
398
+ "maxItems": 24,
399
+ "type": "array",
400
+ "items": {
401
+ "type": "object",
402
+ "properties": {
403
+ "from": {
404
+ "type": "string",
405
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
406
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
407
+ },
408
+ "to": {
409
+ "type": "string",
410
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
411
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
412
+ },
413
+ "label": {
414
+ "type": "string",
415
+ "minLength": 1,
416
+ "maxLength": 40
417
+ }
418
+ },
419
+ "required": [
420
+ "from",
421
+ "to"
422
+ ],
423
+ "additionalProperties": false
424
+ }
425
+ }
426
+ },
427
+ "required": [
428
+ "preset",
429
+ "nodes",
430
+ "edges"
431
+ ],
432
+ "additionalProperties": false
433
+ },
434
+ {
435
+ "type": "object",
436
+ "properties": {
437
+ "preset": {
438
+ "type": "string",
439
+ "const": "timeline"
440
+ },
441
+ "events": {
442
+ "minItems": 2,
443
+ "maxItems": 16,
444
+ "type": "array",
445
+ "items": {
446
+ "type": "object",
447
+ "properties": {
448
+ "date": {
449
+ "type": "string",
450
+ "minLength": 1,
451
+ "maxLength": 40
452
+ },
453
+ "title": {
454
+ "type": "string",
455
+ "minLength": 1,
456
+ "maxLength": 80
457
+ },
458
+ "description": {
459
+ "type": "string",
460
+ "minLength": 1,
461
+ "maxLength": 240
462
+ }
463
+ },
464
+ "required": [
465
+ "date",
466
+ "title"
467
+ ],
468
+ "additionalProperties": false
469
+ }
470
+ }
471
+ },
472
+ "required": [
473
+ "preset",
474
+ "events"
475
+ ],
476
+ "additionalProperties": false
477
+ },
478
+ {
479
+ "type": "object",
480
+ "properties": {
481
+ "preset": {
482
+ "type": "string",
483
+ "const": "process"
484
+ },
485
+ "steps": {
486
+ "minItems": 2,
487
+ "maxItems": 10,
488
+ "type": "array",
489
+ "items": {
490
+ "type": "object",
491
+ "properties": {
492
+ "title": {
493
+ "type": "string",
494
+ "minLength": 1,
495
+ "maxLength": 80
496
+ },
497
+ "description": {
498
+ "type": "string",
499
+ "minLength": 1,
500
+ "maxLength": 240
501
+ }
502
+ },
503
+ "required": [
504
+ "title"
505
+ ],
506
+ "additionalProperties": false
507
+ }
508
+ }
509
+ },
510
+ "required": [
511
+ "preset",
512
+ "steps"
513
+ ],
514
+ "additionalProperties": false
515
+ },
516
+ {
517
+ "type": "object",
518
+ "properties": {
519
+ "preset": {
520
+ "type": "string",
521
+ "const": "compare"
522
+ },
523
+ "before": {
524
+ "type": "object",
525
+ "properties": {
526
+ "label": {
527
+ "type": "string",
528
+ "minLength": 1,
529
+ "maxLength": 60
530
+ },
531
+ "text": {
532
+ "type": "string",
533
+ "minLength": 1,
534
+ "maxLength": 400
535
+ },
536
+ "asset": {
537
+ "type": "string",
538
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
539
+ "description": "The `id` of an entry in `assets`."
540
+ }
541
+ },
542
+ "required": [
543
+ "label"
544
+ ],
545
+ "additionalProperties": false
546
+ },
547
+ "after": {
548
+ "type": "object",
549
+ "properties": {
550
+ "label": {
551
+ "type": "string",
552
+ "minLength": 1,
553
+ "maxLength": 60
554
+ },
555
+ "text": {
556
+ "type": "string",
557
+ "minLength": 1,
558
+ "maxLength": 400
559
+ },
560
+ "asset": {
561
+ "type": "string",
562
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
563
+ "description": "The `id` of an entry in `assets`."
564
+ }
565
+ },
566
+ "required": [
567
+ "label"
568
+ ],
569
+ "additionalProperties": false
570
+ }
571
+ },
572
+ "required": [
573
+ "preset",
574
+ "before",
575
+ "after"
576
+ ],
577
+ "additionalProperties": false
578
+ },
579
+ {
580
+ "type": "object",
581
+ "properties": {
582
+ "preset": {
583
+ "type": "string",
584
+ "const": "counter"
585
+ },
586
+ "items": {
587
+ "minItems": 1,
588
+ "maxItems": 6,
589
+ "type": "array",
590
+ "items": {
591
+ "type": "object",
592
+ "properties": {
593
+ "label": {
594
+ "type": "string",
595
+ "minLength": 1,
596
+ "maxLength": 80
597
+ },
598
+ "from": {
599
+ "default": 0,
600
+ "type": "number"
601
+ },
602
+ "to": {
603
+ "type": "number"
604
+ },
605
+ "unit": {
606
+ "type": "string",
607
+ "maxLength": 12
608
+ },
609
+ "decimals": {
610
+ "default": 0,
611
+ "type": "integer",
612
+ "minimum": 0,
613
+ "maximum": 4
614
+ }
615
+ },
616
+ "required": [
617
+ "label",
618
+ "to"
619
+ ],
620
+ "additionalProperties": false
621
+ }
622
+ }
623
+ },
624
+ "required": [
625
+ "preset",
626
+ "items"
627
+ ],
628
+ "additionalProperties": false
629
+ },
630
+ {
631
+ "type": "object",
632
+ "properties": {
633
+ "preset": {
634
+ "type": "string",
635
+ "const": "highlight-svg"
636
+ },
637
+ "asset": {
638
+ "type": "string",
639
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
640
+ "description": "An asset of kind `svg`."
641
+ },
642
+ "highlights": {
643
+ "minItems": 1,
644
+ "maxItems": 12,
645
+ "type": "array",
646
+ "items": {
647
+ "type": "object",
648
+ "properties": {
649
+ "elementId": {
650
+ "type": "string",
651
+ "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$",
652
+ "description": "`id` attribute of an element in the SVG."
653
+ },
654
+ "label": {
655
+ "type": "string",
656
+ "minLength": 1,
657
+ "maxLength": 80
658
+ },
659
+ "description": {
660
+ "type": "string",
661
+ "minLength": 1,
662
+ "maxLength": 240
663
+ }
664
+ },
665
+ "required": [
666
+ "elementId",
667
+ "label"
668
+ ],
669
+ "additionalProperties": false
670
+ }
671
+ }
672
+ },
673
+ "required": [
674
+ "preset",
675
+ "asset",
676
+ "highlights"
677
+ ],
678
+ "additionalProperties": false
679
+ }
680
+ ]
681
+ }
682
+ },
683
+ "required": [
684
+ "type",
685
+ "animation"
686
+ ],
687
+ "additionalProperties": false
688
+ },
689
+ {
690
+ "type": "object",
691
+ "properties": {
692
+ "type": {
693
+ "type": "string",
694
+ "const": "image"
695
+ },
696
+ "asset": {
697
+ "type": "string",
698
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
699
+ "description": "The `id` of an entry in `assets`."
700
+ },
701
+ "caption": {
702
+ "type": "string",
703
+ "minLength": 1,
704
+ "maxLength": 300
705
+ }
706
+ },
707
+ "required": [
708
+ "type",
709
+ "asset"
710
+ ],
711
+ "additionalProperties": false
712
+ }
713
+ ],
714
+ "description": "The step's main visual. Pinned beside the text in scrollytelling, split-screen in stepper and slides."
715
+ },
716
+ "blocks": {
717
+ "minItems": 1,
718
+ "maxItems": 20,
719
+ "type": "array",
720
+ "items": {
721
+ "oneOf": [
722
+ {
723
+ "type": "object",
724
+ "properties": {
725
+ "type": {
726
+ "type": "string",
727
+ "const": "markdown"
728
+ },
729
+ "text": {
730
+ "type": "string",
731
+ "minLength": 1,
732
+ "maxLength": 20000,
733
+ "description": "Markdown (CommonMark subset, no raw HTML, no images). Mark glossary terms as [[term]] or [[term|shown text]]."
734
+ }
735
+ },
736
+ "required": [
737
+ "type",
738
+ "text"
739
+ ],
740
+ "additionalProperties": false,
741
+ "description": "Paragraphs, lists, emphasis, links (https only), inline code."
742
+ },
743
+ {
744
+ "type": "object",
745
+ "properties": {
746
+ "type": {
747
+ "type": "string",
748
+ "const": "callout"
749
+ },
750
+ "variant": {
751
+ "type": "string",
752
+ "enum": [
753
+ "info",
754
+ "tip",
755
+ "warning",
756
+ "example"
757
+ ]
758
+ },
759
+ "title": {
760
+ "type": "string",
761
+ "minLength": 1,
762
+ "maxLength": 120
763
+ },
764
+ "text": {
765
+ "type": "string",
766
+ "minLength": 1,
767
+ "maxLength": 20000,
768
+ "description": "Markdown (CommonMark subset, no raw HTML, no images). Mark glossary terms as [[term]] or [[term|shown text]]."
769
+ }
770
+ },
771
+ "required": [
772
+ "type",
773
+ "variant",
774
+ "text"
775
+ ],
776
+ "additionalProperties": false
777
+ },
778
+ {
779
+ "type": "object",
780
+ "properties": {
781
+ "type": {
782
+ "type": "string",
783
+ "const": "image"
784
+ },
785
+ "asset": {
786
+ "type": "string",
787
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
788
+ "description": "The `id` of an entry in `assets`."
789
+ },
790
+ "caption": {
791
+ "type": "string",
792
+ "minLength": 1,
793
+ "maxLength": 300
794
+ }
795
+ },
796
+ "required": [
797
+ "type",
798
+ "asset"
799
+ ],
800
+ "additionalProperties": false
801
+ },
802
+ {
803
+ "type": "object",
804
+ "properties": {
805
+ "type": {
806
+ "type": "string",
807
+ "const": "code"
808
+ },
809
+ "language": {
810
+ "type": "string",
811
+ "pattern": "^[a-z0-9+#.-]{1,30}$",
812
+ "description": "Language for syntax highlighting, e.g. python, ts, bash."
813
+ },
814
+ "code": {
815
+ "type": "string",
816
+ "minLength": 1,
817
+ "maxLength": 10000
818
+ },
819
+ "caption": {
820
+ "type": "string",
821
+ "minLength": 1,
822
+ "maxLength": 300
823
+ }
824
+ },
825
+ "required": [
826
+ "type",
827
+ "language",
828
+ "code"
829
+ ],
830
+ "additionalProperties": false
831
+ },
832
+ {
833
+ "type": "object",
834
+ "properties": {
835
+ "type": {
836
+ "type": "string",
837
+ "const": "math"
838
+ },
839
+ "tex": {
840
+ "type": "string",
841
+ "minLength": 1,
842
+ "maxLength": 4000,
843
+ "description": "LaTeX rendered with KaTeX."
844
+ },
845
+ "caption": {
846
+ "type": "string",
847
+ "minLength": 1,
848
+ "maxLength": 300
849
+ }
850
+ },
851
+ "required": [
852
+ "type",
853
+ "tex"
854
+ ],
855
+ "additionalProperties": false
856
+ },
857
+ {
858
+ "type": "object",
859
+ "properties": {
860
+ "type": {
861
+ "type": "string",
862
+ "const": "table"
863
+ },
864
+ "headers": {
865
+ "minItems": 1,
866
+ "maxItems": 10,
867
+ "type": "array",
868
+ "items": {
869
+ "type": "string",
870
+ "minLength": 1,
871
+ "maxLength": 200
872
+ }
873
+ },
874
+ "rows": {
875
+ "minItems": 1,
876
+ "maxItems": 50,
877
+ "type": "array",
878
+ "items": {
879
+ "minItems": 1,
880
+ "maxItems": 10,
881
+ "type": "array",
882
+ "items": {
883
+ "type": "string",
884
+ "maxLength": 500
885
+ }
886
+ }
887
+ },
888
+ "caption": {
889
+ "type": "string",
890
+ "minLength": 1,
891
+ "maxLength": 300
892
+ }
893
+ },
894
+ "required": [
895
+ "type",
896
+ "headers",
897
+ "rows"
898
+ ],
899
+ "additionalProperties": false
900
+ },
901
+ {
902
+ "type": "object",
903
+ "properties": {
904
+ "type": {
905
+ "type": "string",
906
+ "const": "quote"
907
+ },
908
+ "text": {
909
+ "type": "string",
910
+ "minLength": 1,
911
+ "maxLength": 20000,
912
+ "description": "Markdown (CommonMark subset, no raw HTML, no images). Mark glossary terms as [[term]] or [[term|shown text]]."
913
+ },
914
+ "cite": {
915
+ "type": "string",
916
+ "minLength": 1,
917
+ "maxLength": 200
918
+ }
919
+ },
920
+ "required": [
921
+ "type",
922
+ "text"
923
+ ],
924
+ "additionalProperties": false
925
+ },
926
+ {
927
+ "type": "object",
928
+ "properties": {
929
+ "type": {
930
+ "type": "string",
931
+ "const": "chart"
932
+ },
933
+ "title": {
934
+ "type": "string",
935
+ "minLength": 1,
936
+ "maxLength": 200
937
+ },
938
+ "caption": {
939
+ "type": "string",
940
+ "minLength": 1,
941
+ "maxLength": 300
942
+ },
943
+ "spec": {
944
+ "type": "object",
945
+ "propertyNames": {
946
+ "type": "string"
947
+ },
948
+ "additionalProperties": {},
949
+ "description": "Vega-Lite v6 specification. Data must be inline (`data.values`); `url` data sources are rejected."
950
+ }
951
+ },
952
+ "required": [
953
+ "type",
954
+ "spec"
955
+ ],
956
+ "additionalProperties": false
957
+ },
958
+ {
959
+ "type": "object",
960
+ "properties": {
961
+ "type": {
962
+ "type": "string",
963
+ "const": "diagram"
964
+ },
965
+ "syntax": {
966
+ "type": "string",
967
+ "const": "mermaid"
968
+ },
969
+ "code": {
970
+ "type": "string",
971
+ "minLength": 1,
972
+ "maxLength": 8000,
973
+ "description": "Mermaid source. No `click` handlers and no `%%{init}%%` directives."
974
+ },
975
+ "caption": {
976
+ "type": "string",
977
+ "minLength": 1,
978
+ "maxLength": 300
979
+ }
980
+ },
981
+ "required": [
982
+ "type",
983
+ "syntax",
984
+ "code"
985
+ ],
986
+ "additionalProperties": false
987
+ },
988
+ {
989
+ "type": "object",
990
+ "properties": {
991
+ "type": {
992
+ "type": "string",
993
+ "const": "animation"
994
+ },
995
+ "caption": {
996
+ "type": "string",
997
+ "minLength": 1,
998
+ "maxLength": 300
999
+ },
1000
+ "animation": {
1001
+ "oneOf": [
1002
+ {
1003
+ "type": "object",
1004
+ "properties": {
1005
+ "preset": {
1006
+ "type": "string",
1007
+ "const": "sequence"
1008
+ },
1009
+ "layout": {
1010
+ "default": "row",
1011
+ "type": "string",
1012
+ "enum": [
1013
+ "row",
1014
+ "column",
1015
+ "grid"
1016
+ ]
1017
+ },
1018
+ "items": {
1019
+ "minItems": 2,
1020
+ "maxItems": 12,
1021
+ "type": "array",
1022
+ "items": {
1023
+ "type": "object",
1024
+ "properties": {
1025
+ "label": {
1026
+ "type": "string",
1027
+ "minLength": 1,
1028
+ "maxLength": 80
1029
+ },
1030
+ "description": {
1031
+ "type": "string",
1032
+ "minLength": 1,
1033
+ "maxLength": 240
1034
+ },
1035
+ "icon": {
1036
+ "description": "A single emoji.",
1037
+ "type": "string",
1038
+ "maxLength": 8
1039
+ }
1040
+ },
1041
+ "required": [
1042
+ "label"
1043
+ ],
1044
+ "additionalProperties": false
1045
+ }
1046
+ }
1047
+ },
1048
+ "required": [
1049
+ "preset",
1050
+ "items"
1051
+ ],
1052
+ "additionalProperties": false
1053
+ },
1054
+ {
1055
+ "type": "object",
1056
+ "properties": {
1057
+ "preset": {
1058
+ "type": "string",
1059
+ "const": "flow"
1060
+ },
1061
+ "direction": {
1062
+ "default": "LR",
1063
+ "type": "string",
1064
+ "enum": [
1065
+ "LR",
1066
+ "TB"
1067
+ ]
1068
+ },
1069
+ "nodes": {
1070
+ "minItems": 2,
1071
+ "maxItems": 12,
1072
+ "type": "array",
1073
+ "items": {
1074
+ "type": "object",
1075
+ "properties": {
1076
+ "id": {
1077
+ "type": "string",
1078
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1079
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1080
+ },
1081
+ "label": {
1082
+ "type": "string",
1083
+ "minLength": 1,
1084
+ "maxLength": 60
1085
+ }
1086
+ },
1087
+ "required": [
1088
+ "id",
1089
+ "label"
1090
+ ],
1091
+ "additionalProperties": false
1092
+ }
1093
+ },
1094
+ "edges": {
1095
+ "minItems": 1,
1096
+ "maxItems": 24,
1097
+ "type": "array",
1098
+ "items": {
1099
+ "type": "object",
1100
+ "properties": {
1101
+ "from": {
1102
+ "type": "string",
1103
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1104
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1105
+ },
1106
+ "to": {
1107
+ "type": "string",
1108
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1109
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1110
+ },
1111
+ "label": {
1112
+ "type": "string",
1113
+ "minLength": 1,
1114
+ "maxLength": 40
1115
+ }
1116
+ },
1117
+ "required": [
1118
+ "from",
1119
+ "to"
1120
+ ],
1121
+ "additionalProperties": false
1122
+ }
1123
+ }
1124
+ },
1125
+ "required": [
1126
+ "preset",
1127
+ "nodes",
1128
+ "edges"
1129
+ ],
1130
+ "additionalProperties": false
1131
+ },
1132
+ {
1133
+ "type": "object",
1134
+ "properties": {
1135
+ "preset": {
1136
+ "type": "string",
1137
+ "const": "timeline"
1138
+ },
1139
+ "events": {
1140
+ "minItems": 2,
1141
+ "maxItems": 16,
1142
+ "type": "array",
1143
+ "items": {
1144
+ "type": "object",
1145
+ "properties": {
1146
+ "date": {
1147
+ "type": "string",
1148
+ "minLength": 1,
1149
+ "maxLength": 40
1150
+ },
1151
+ "title": {
1152
+ "type": "string",
1153
+ "minLength": 1,
1154
+ "maxLength": 80
1155
+ },
1156
+ "description": {
1157
+ "type": "string",
1158
+ "minLength": 1,
1159
+ "maxLength": 240
1160
+ }
1161
+ },
1162
+ "required": [
1163
+ "date",
1164
+ "title"
1165
+ ],
1166
+ "additionalProperties": false
1167
+ }
1168
+ }
1169
+ },
1170
+ "required": [
1171
+ "preset",
1172
+ "events"
1173
+ ],
1174
+ "additionalProperties": false
1175
+ },
1176
+ {
1177
+ "type": "object",
1178
+ "properties": {
1179
+ "preset": {
1180
+ "type": "string",
1181
+ "const": "process"
1182
+ },
1183
+ "steps": {
1184
+ "minItems": 2,
1185
+ "maxItems": 10,
1186
+ "type": "array",
1187
+ "items": {
1188
+ "type": "object",
1189
+ "properties": {
1190
+ "title": {
1191
+ "type": "string",
1192
+ "minLength": 1,
1193
+ "maxLength": 80
1194
+ },
1195
+ "description": {
1196
+ "type": "string",
1197
+ "minLength": 1,
1198
+ "maxLength": 240
1199
+ }
1200
+ },
1201
+ "required": [
1202
+ "title"
1203
+ ],
1204
+ "additionalProperties": false
1205
+ }
1206
+ }
1207
+ },
1208
+ "required": [
1209
+ "preset",
1210
+ "steps"
1211
+ ],
1212
+ "additionalProperties": false
1213
+ },
1214
+ {
1215
+ "type": "object",
1216
+ "properties": {
1217
+ "preset": {
1218
+ "type": "string",
1219
+ "const": "compare"
1220
+ },
1221
+ "before": {
1222
+ "type": "object",
1223
+ "properties": {
1224
+ "label": {
1225
+ "type": "string",
1226
+ "minLength": 1,
1227
+ "maxLength": 60
1228
+ },
1229
+ "text": {
1230
+ "type": "string",
1231
+ "minLength": 1,
1232
+ "maxLength": 400
1233
+ },
1234
+ "asset": {
1235
+ "type": "string",
1236
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1237
+ "description": "The `id` of an entry in `assets`."
1238
+ }
1239
+ },
1240
+ "required": [
1241
+ "label"
1242
+ ],
1243
+ "additionalProperties": false
1244
+ },
1245
+ "after": {
1246
+ "type": "object",
1247
+ "properties": {
1248
+ "label": {
1249
+ "type": "string",
1250
+ "minLength": 1,
1251
+ "maxLength": 60
1252
+ },
1253
+ "text": {
1254
+ "type": "string",
1255
+ "minLength": 1,
1256
+ "maxLength": 400
1257
+ },
1258
+ "asset": {
1259
+ "type": "string",
1260
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1261
+ "description": "The `id` of an entry in `assets`."
1262
+ }
1263
+ },
1264
+ "required": [
1265
+ "label"
1266
+ ],
1267
+ "additionalProperties": false
1268
+ }
1269
+ },
1270
+ "required": [
1271
+ "preset",
1272
+ "before",
1273
+ "after"
1274
+ ],
1275
+ "additionalProperties": false
1276
+ },
1277
+ {
1278
+ "type": "object",
1279
+ "properties": {
1280
+ "preset": {
1281
+ "type": "string",
1282
+ "const": "counter"
1283
+ },
1284
+ "items": {
1285
+ "minItems": 1,
1286
+ "maxItems": 6,
1287
+ "type": "array",
1288
+ "items": {
1289
+ "type": "object",
1290
+ "properties": {
1291
+ "label": {
1292
+ "type": "string",
1293
+ "minLength": 1,
1294
+ "maxLength": 80
1295
+ },
1296
+ "from": {
1297
+ "default": 0,
1298
+ "type": "number"
1299
+ },
1300
+ "to": {
1301
+ "type": "number"
1302
+ },
1303
+ "unit": {
1304
+ "type": "string",
1305
+ "maxLength": 12
1306
+ },
1307
+ "decimals": {
1308
+ "default": 0,
1309
+ "type": "integer",
1310
+ "minimum": 0,
1311
+ "maximum": 4
1312
+ }
1313
+ },
1314
+ "required": [
1315
+ "label",
1316
+ "to"
1317
+ ],
1318
+ "additionalProperties": false
1319
+ }
1320
+ }
1321
+ },
1322
+ "required": [
1323
+ "preset",
1324
+ "items"
1325
+ ],
1326
+ "additionalProperties": false
1327
+ },
1328
+ {
1329
+ "type": "object",
1330
+ "properties": {
1331
+ "preset": {
1332
+ "type": "string",
1333
+ "const": "highlight-svg"
1334
+ },
1335
+ "asset": {
1336
+ "type": "string",
1337
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1338
+ "description": "An asset of kind `svg`."
1339
+ },
1340
+ "highlights": {
1341
+ "minItems": 1,
1342
+ "maxItems": 12,
1343
+ "type": "array",
1344
+ "items": {
1345
+ "type": "object",
1346
+ "properties": {
1347
+ "elementId": {
1348
+ "type": "string",
1349
+ "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$",
1350
+ "description": "`id` attribute of an element in the SVG."
1351
+ },
1352
+ "label": {
1353
+ "type": "string",
1354
+ "minLength": 1,
1355
+ "maxLength": 80
1356
+ },
1357
+ "description": {
1358
+ "type": "string",
1359
+ "minLength": 1,
1360
+ "maxLength": 240
1361
+ }
1362
+ },
1363
+ "required": [
1364
+ "elementId",
1365
+ "label"
1366
+ ],
1367
+ "additionalProperties": false
1368
+ }
1369
+ }
1370
+ },
1371
+ "required": [
1372
+ "preset",
1373
+ "asset",
1374
+ "highlights"
1375
+ ],
1376
+ "additionalProperties": false
1377
+ }
1378
+ ]
1379
+ }
1380
+ },
1381
+ "required": [
1382
+ "type",
1383
+ "animation"
1384
+ ],
1385
+ "additionalProperties": false
1386
+ }
1387
+ ]
1388
+ }
1389
+ },
1390
+ "check": {
1391
+ "oneOf": [
1392
+ {
1393
+ "type": "object",
1394
+ "properties": {
1395
+ "id": {
1396
+ "type": "string",
1397
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1398
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1399
+ },
1400
+ "prompt": {
1401
+ "type": "string",
1402
+ "minLength": 1,
1403
+ "maxLength": 600
1404
+ },
1405
+ "explanation": {
1406
+ "type": "string",
1407
+ "minLength": 1,
1408
+ "maxLength": 1200,
1409
+ "description": "Why the correct answer is correct; shown after answering."
1410
+ },
1411
+ "type": {
1412
+ "type": "string",
1413
+ "const": "single"
1414
+ },
1415
+ "options": {
1416
+ "minItems": 2,
1417
+ "maxItems": 6,
1418
+ "type": "array",
1419
+ "items": {
1420
+ "type": "object",
1421
+ "properties": {
1422
+ "id": {
1423
+ "type": "string",
1424
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1425
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1426
+ },
1427
+ "text": {
1428
+ "type": "string",
1429
+ "minLength": 1,
1430
+ "maxLength": 300
1431
+ }
1432
+ },
1433
+ "required": [
1434
+ "id",
1435
+ "text"
1436
+ ],
1437
+ "additionalProperties": false
1438
+ }
1439
+ },
1440
+ "correct": {
1441
+ "type": "string",
1442
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1443
+ "description": "The `id` of the correct option."
1444
+ }
1445
+ },
1446
+ "required": [
1447
+ "id",
1448
+ "prompt",
1449
+ "explanation",
1450
+ "type",
1451
+ "options",
1452
+ "correct"
1453
+ ],
1454
+ "additionalProperties": false
1455
+ },
1456
+ {
1457
+ "type": "object",
1458
+ "properties": {
1459
+ "id": {
1460
+ "type": "string",
1461
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1462
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1463
+ },
1464
+ "prompt": {
1465
+ "type": "string",
1466
+ "minLength": 1,
1467
+ "maxLength": 600
1468
+ },
1469
+ "explanation": {
1470
+ "type": "string",
1471
+ "minLength": 1,
1472
+ "maxLength": 1200,
1473
+ "description": "Why the correct answer is correct; shown after answering."
1474
+ },
1475
+ "type": {
1476
+ "type": "string",
1477
+ "const": "multiple"
1478
+ },
1479
+ "options": {
1480
+ "minItems": 3,
1481
+ "maxItems": 8,
1482
+ "type": "array",
1483
+ "items": {
1484
+ "type": "object",
1485
+ "properties": {
1486
+ "id": {
1487
+ "type": "string",
1488
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1489
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1490
+ },
1491
+ "text": {
1492
+ "type": "string",
1493
+ "minLength": 1,
1494
+ "maxLength": 300
1495
+ }
1496
+ },
1497
+ "required": [
1498
+ "id",
1499
+ "text"
1500
+ ],
1501
+ "additionalProperties": false
1502
+ }
1503
+ },
1504
+ "correct": {
1505
+ "minItems": 1,
1506
+ "type": "array",
1507
+ "items": {
1508
+ "type": "string",
1509
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1510
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1511
+ },
1512
+ "description": "The `id`s of all correct options."
1513
+ }
1514
+ },
1515
+ "required": [
1516
+ "id",
1517
+ "prompt",
1518
+ "explanation",
1519
+ "type",
1520
+ "options",
1521
+ "correct"
1522
+ ],
1523
+ "additionalProperties": false
1524
+ },
1525
+ {
1526
+ "type": "object",
1527
+ "properties": {
1528
+ "id": {
1529
+ "type": "string",
1530
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1531
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1532
+ },
1533
+ "prompt": {
1534
+ "type": "string",
1535
+ "minLength": 1,
1536
+ "maxLength": 600
1537
+ },
1538
+ "explanation": {
1539
+ "type": "string",
1540
+ "minLength": 1,
1541
+ "maxLength": 1200,
1542
+ "description": "Why the correct answer is correct; shown after answering."
1543
+ },
1544
+ "type": {
1545
+ "type": "string",
1546
+ "const": "true_false"
1547
+ },
1548
+ "correct": {
1549
+ "type": "boolean"
1550
+ }
1551
+ },
1552
+ "required": [
1553
+ "id",
1554
+ "prompt",
1555
+ "explanation",
1556
+ "type",
1557
+ "correct"
1558
+ ],
1559
+ "additionalProperties": false
1560
+ }
1561
+ ],
1562
+ "description": "Optional quick check at the end of a step (not scored)."
1563
+ }
1564
+ },
1565
+ "required": [
1566
+ "id",
1567
+ "title",
1568
+ "blocks"
1569
+ ],
1570
+ "additionalProperties": false
1571
+ }
1572
+ },
1573
+ "glossary": {
1574
+ "minItems": 1,
1575
+ "maxItems": 40,
1576
+ "type": "array",
1577
+ "items": {
1578
+ "type": "object",
1579
+ "properties": {
1580
+ "term": {
1581
+ "type": "string",
1582
+ "minLength": 1,
1583
+ "maxLength": 80
1584
+ },
1585
+ "definition": {
1586
+ "type": "string",
1587
+ "minLength": 1,
1588
+ "maxLength": 800
1589
+ },
1590
+ "aliases": {
1591
+ "description": "Other spellings or inflections that refer to the term.",
1592
+ "maxItems": 8,
1593
+ "type": "array",
1594
+ "items": {
1595
+ "type": "string",
1596
+ "minLength": 1,
1597
+ "maxLength": 80
1598
+ }
1599
+ }
1600
+ },
1601
+ "required": [
1602
+ "term",
1603
+ "definition"
1604
+ ],
1605
+ "additionalProperties": false
1606
+ },
1607
+ "description": "Every concept introduced and every technical term used in this section."
1608
+ }
1609
+ },
1610
+ "required": [
1611
+ "id",
1612
+ "title",
1613
+ "summary",
1614
+ "steps",
1615
+ "glossary"
1616
+ ],
1617
+ "additionalProperties": false
1618
+ }
1619
+ },
1620
+ "finalQuiz": {
1621
+ "type": "object",
1622
+ "properties": {
1623
+ "questions": {
1624
+ "minItems": 10,
1625
+ "maxItems": 40,
1626
+ "type": "array",
1627
+ "items": {
1628
+ "oneOf": [
1629
+ {
1630
+ "type": "object",
1631
+ "properties": {
1632
+ "id": {
1633
+ "type": "string",
1634
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1635
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1636
+ },
1637
+ "prompt": {
1638
+ "type": "string",
1639
+ "minLength": 1,
1640
+ "maxLength": 600
1641
+ },
1642
+ "explanation": {
1643
+ "type": "string",
1644
+ "minLength": 1,
1645
+ "maxLength": 1200,
1646
+ "description": "Why the correct answer is correct; shown after answering."
1647
+ },
1648
+ "type": {
1649
+ "type": "string",
1650
+ "const": "single"
1651
+ },
1652
+ "options": {
1653
+ "minItems": 2,
1654
+ "maxItems": 6,
1655
+ "type": "array",
1656
+ "items": {
1657
+ "type": "object",
1658
+ "properties": {
1659
+ "id": {
1660
+ "type": "string",
1661
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1662
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1663
+ },
1664
+ "text": {
1665
+ "type": "string",
1666
+ "minLength": 1,
1667
+ "maxLength": 300
1668
+ }
1669
+ },
1670
+ "required": [
1671
+ "id",
1672
+ "text"
1673
+ ],
1674
+ "additionalProperties": false
1675
+ }
1676
+ },
1677
+ "correct": {
1678
+ "type": "string",
1679
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1680
+ "description": "The `id` of the correct option."
1681
+ },
1682
+ "sectionRef": {
1683
+ "type": "string",
1684
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1685
+ "description": "Section this question tests."
1686
+ }
1687
+ },
1688
+ "required": [
1689
+ "id",
1690
+ "prompt",
1691
+ "explanation",
1692
+ "type",
1693
+ "options",
1694
+ "correct",
1695
+ "sectionRef"
1696
+ ],
1697
+ "additionalProperties": false
1698
+ },
1699
+ {
1700
+ "type": "object",
1701
+ "properties": {
1702
+ "id": {
1703
+ "type": "string",
1704
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1705
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1706
+ },
1707
+ "prompt": {
1708
+ "type": "string",
1709
+ "minLength": 1,
1710
+ "maxLength": 600
1711
+ },
1712
+ "explanation": {
1713
+ "type": "string",
1714
+ "minLength": 1,
1715
+ "maxLength": 1200,
1716
+ "description": "Why the correct answer is correct; shown after answering."
1717
+ },
1718
+ "type": {
1719
+ "type": "string",
1720
+ "const": "multiple"
1721
+ },
1722
+ "options": {
1723
+ "minItems": 3,
1724
+ "maxItems": 8,
1725
+ "type": "array",
1726
+ "items": {
1727
+ "type": "object",
1728
+ "properties": {
1729
+ "id": {
1730
+ "type": "string",
1731
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1732
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1733
+ },
1734
+ "text": {
1735
+ "type": "string",
1736
+ "minLength": 1,
1737
+ "maxLength": 300
1738
+ }
1739
+ },
1740
+ "required": [
1741
+ "id",
1742
+ "text"
1743
+ ],
1744
+ "additionalProperties": false
1745
+ }
1746
+ },
1747
+ "correct": {
1748
+ "minItems": 1,
1749
+ "type": "array",
1750
+ "items": {
1751
+ "type": "string",
1752
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1753
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1754
+ },
1755
+ "description": "The `id`s of all correct options."
1756
+ },
1757
+ "sectionRef": {
1758
+ "type": "string",
1759
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1760
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1761
+ }
1762
+ },
1763
+ "required": [
1764
+ "id",
1765
+ "prompt",
1766
+ "explanation",
1767
+ "type",
1768
+ "options",
1769
+ "correct",
1770
+ "sectionRef"
1771
+ ],
1772
+ "additionalProperties": false
1773
+ },
1774
+ {
1775
+ "type": "object",
1776
+ "properties": {
1777
+ "id": {
1778
+ "type": "string",
1779
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1780
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1781
+ },
1782
+ "prompt": {
1783
+ "type": "string",
1784
+ "minLength": 1,
1785
+ "maxLength": 600
1786
+ },
1787
+ "explanation": {
1788
+ "type": "string",
1789
+ "minLength": 1,
1790
+ "maxLength": 1200,
1791
+ "description": "Why the correct answer is correct; shown after answering."
1792
+ },
1793
+ "type": {
1794
+ "type": "string",
1795
+ "const": "true_false"
1796
+ },
1797
+ "correct": {
1798
+ "type": "boolean"
1799
+ },
1800
+ "sectionRef": {
1801
+ "type": "string",
1802
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1803
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1804
+ }
1805
+ },
1806
+ "required": [
1807
+ "id",
1808
+ "prompt",
1809
+ "explanation",
1810
+ "type",
1811
+ "correct",
1812
+ "sectionRef"
1813
+ ],
1814
+ "additionalProperties": false
1815
+ },
1816
+ {
1817
+ "type": "object",
1818
+ "properties": {
1819
+ "id": {
1820
+ "type": "string",
1821
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1822
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1823
+ },
1824
+ "prompt": {
1825
+ "type": "string",
1826
+ "minLength": 1,
1827
+ "maxLength": 600
1828
+ },
1829
+ "explanation": {
1830
+ "type": "string",
1831
+ "minLength": 1,
1832
+ "maxLength": 1200,
1833
+ "description": "Why the correct answer is correct; shown after answering."
1834
+ },
1835
+ "type": {
1836
+ "type": "string",
1837
+ "const": "ordering"
1838
+ },
1839
+ "items": {
1840
+ "minItems": 3,
1841
+ "maxItems": 8,
1842
+ "type": "array",
1843
+ "items": {
1844
+ "type": "object",
1845
+ "properties": {
1846
+ "id": {
1847
+ "type": "string",
1848
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1849
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1850
+ },
1851
+ "text": {
1852
+ "type": "string",
1853
+ "minLength": 1,
1854
+ "maxLength": 300
1855
+ }
1856
+ },
1857
+ "required": [
1858
+ "id",
1859
+ "text"
1860
+ ],
1861
+ "additionalProperties": false
1862
+ },
1863
+ "description": "Listed in the CORRECT order; the portal shuffles them."
1864
+ },
1865
+ "sectionRef": {
1866
+ "type": "string",
1867
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$",
1868
+ "description": "Stable identifier: lowercase letters, digits and dashes. Keep it unchanged across versions."
1869
+ }
1870
+ },
1871
+ "required": [
1872
+ "id",
1873
+ "prompt",
1874
+ "explanation",
1875
+ "type",
1876
+ "items",
1877
+ "sectionRef"
1878
+ ],
1879
+ "additionalProperties": false
1880
+ }
1881
+ ]
1882
+ }
1883
+ }
1884
+ },
1885
+ "required": [
1886
+ "questions"
1887
+ ],
1888
+ "additionalProperties": false
1889
+ }
1890
+ },
1891
+ "required": [
1892
+ "schemaVersion",
1893
+ "meta",
1894
+ "assets",
1895
+ "sections",
1896
+ "finalQuiz"
1897
+ ],
1898
+ "additionalProperties": false,
1899
+ "$id": "https://coursmith.dev/schema/course-1.0.json",
1900
+ "title": "Coursmith course"
1901
+ }