@lernapps/app-templates 0.0.1 → 0.1.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/LICENSE +22 -0
- package/README.md +195 -2
- package/dist/appname-Bh23cUuz.mjs +12 -0
- package/dist/assessment-By2GGTJC.mjs +1696 -0
- package/dist/block-BK_ohsH1.mjs +82 -0
- package/dist/blocks-BmRrD7UY.mjs +149 -0
- package/dist/blocks.mjs +4 -0
- package/dist/check-BkEl-m-F.mjs +254 -0
- package/dist/content-cYBPYg_J.mjs +140 -0
- package/dist/contract-PONpxJtd.mjs +52 -0
- package/dist/e2e-BiMI-pCL.mjs +89 -0
- package/dist/engine-BqF2Vffn.mjs +136 -0
- package/dist/explainer-e2e.mjs +1297 -0
- package/dist/explainer-islands.mjs +197 -0
- package/dist/explainer-plugin.mjs +2131 -0
- package/dist/explainer.mjs +1246 -0
- package/dist/html-mffkHGHh.mjs +89 -0
- package/dist/image-CspJVfyQ.mjs +21 -0
- package/dist/interactive-e2e.mjs +140 -0
- package/dist/interactive-plugin.mjs +242 -0
- package/dist/interactive.mjs +75 -0
- package/dist/load-C-0hUaSC.mjs +16947 -0
- package/dist/needs-BzEahJ6X.mjs +97 -0
- package/dist/pages-9RaaomoO.mjs +81 -0
- package/dist/questions-e2e.mjs +1 -0
- package/dist/questions-engine.mjs +3 -0
- package/dist/questions.mjs +6 -0
- package/dist/quiz-BKc8JYtC.mjs +70 -0
- package/dist/quiz-e2e.mjs +174 -0
- package/dist/quiz-plugin.mjs +266 -0
- package/dist/quiz.mjs +246 -0
- package/dist/render-BJey0bwl.mjs +540 -0
- package/dist/render-BL6fV_NI.mjs +507 -0
- package/dist/render-DpRO_RKm.mjs +146 -0
- package/dist/result-_eQcamoz.mjs +180 -0
- package/dist/tasks-DADUYy52.mjs +74 -0
- package/dist/validate-COaZso7u.mjs +1072 -0
- package/dist/validate-CxtdeQ5S.mjs +146 -0
- package/dist/vue-DO1m6q1R.mjs +40 -0
- package/dist/vue-code-BkJjW_I_.mjs +320 -0
- package/docs/arc42/01-introduction-and-goals.arc42.md +82 -0
- package/docs/arc42/02-constraints.arc42.md +228 -0
- package/docs/arc42/03-system-context.arc42.md +118 -0
- package/docs/arc42/04-solution-strategy.arc42.md +47 -0
- package/docs/arc42/05-building-blocks.arc42.md +307 -0
- package/docs/arc42/06-runtime-view.arc42.md +98 -0
- package/docs/arc42/07-deployment-view.arc42.md +160 -0
- package/docs/arc42/08-concepts.arc42.md +123 -0
- package/docs/arc42/09-decisions.arc42.md +246 -0
- package/docs/arc42/10-quality-requirements.arc42.md +155 -0
- package/docs/arc42/11-risks.arc42.md +113 -0
- package/docs/arc42/12-glossary.arc42.md +162 -0
- package/docs/arc42/architecture-evidence.md +395 -0
- package/explainer/.arc42ignore +3 -0
- package/explainer/README.md +54 -0
- package/explainer/_gitignore +5 -0
- package/explainer/docs/arc42/03-explainer-system-context.arc42.md +35 -0
- package/explainer/docs/arc42/05-explainer-building-blocks.arc42.md +659 -0
- package/explainer/docs/arc42/06-explainer-runtime-view.arc42.md +105 -0
- package/explainer/docs/arc42/07-explainer-deployment-view.arc42.md +34 -0
- package/explainer/docs/arc42/08-explainer-concepts.arc42.md +17 -0
- package/explainer/docs/arc42/09-explainer-decisions.arc42.md +443 -0
- package/explainer/docs/arc42/10-explainer-quality-requirements.arc42.md +54 -0
- package/explainer/docs/arc42/11-explainer-risks.arc42.md +17 -0
- package/explainer/docs/arc42/12-explainer-glossary.arc42.md +185 -0
- package/explainer/e2e/explainer.e2e.ts +3 -0
- package/explainer/index.html +11 -0
- package/explainer/package.json +18 -0
- package/explainer/playwright.config.ts +1 -0
- package/explainer/src/app.yaml +20 -0
- package/explainer/src/components/ProzentFeld.test.ts +30 -0
- package/explainer/src/components/ProzentFeld.ts +121 -0
- package/explainer/src/components/ProzentFeld.vue +84 -0
- package/explainer/src/images/hunderterfeld-klammern.svg +105 -0
- package/explainer/src/main.ts +4 -0
- package/explainer/src/prozent/chapter.yaml +18 -0
- package/explainer/src/prozent/grundwert.yaml +115 -0
- package/explainer/src/prozent/prozentsatz.yaml +99 -0
- package/explainer/src/prozent/prozentwert.yaml +119 -0
- package/explainer/tsconfig.json +1 -0
- package/explainer/vite.config.ts +4 -0
- package/interactive/.arc42ignore +5 -0
- package/interactive/README.md +28 -0
- package/interactive/_gitignore +4 -0
- package/interactive/docs/arc42/05-interactive-building-blocks.arc42.md +518 -0
- package/interactive/docs/arc42/06-interactive-runtime-view.arc42.md +58 -0
- package/interactive/docs/arc42/07-interactive-deployment-view.arc42.md +35 -0
- package/interactive/docs/arc42/08-interactive-concepts.arc42.md +52 -0
- package/interactive/docs/arc42/09-interactive-decisions.arc42.md +130 -0
- package/interactive/docs/arc42/10-interactive-quality-requirements.arc42.md +45 -0
- package/interactive/docs/arc42/11-interactive-risks.arc42.md +20 -0
- package/interactive/docs/arc42/12-interactive-glossary.arc42.md +80 -0
- package/interactive/e2e/interactive.e2e.ts +3 -0
- package/interactive/index.html +11 -0
- package/interactive/package.json +18 -0
- package/interactive/playwright.config.ts +1 -0
- package/interactive/src/app.yaml +28 -0
- package/interactive/src/core/index.ts +101 -0
- package/interactive/src/data/lessons.json +4 -0
- package/interactive/src/env.d.ts +6 -0
- package/interactive/src/main.ts +6 -0
- package/interactive/src/messages/de.json +12 -0
- package/interactive/src/playthroughs/grundreihe.yaml +33 -0
- package/interactive/src/playthroughs/obere-reihe.yaml +14 -0
- package/interactive/src/ui/App.vue +85 -0
- package/interactive/tsconfig.json +1 -0
- package/interactive/vite.config.ts +4 -0
- package/package.json +142 -4
- package/quiz/README.md +31 -0
- package/quiz/_gitignore +5 -0
- package/quiz/docs/arc42/05-quiz-building-blocks.arc42.md +283 -0
- package/quiz/docs/arc42/06-quiz-runtime-view.arc42.md +21 -0
- package/quiz/docs/arc42/07-quiz-deployment-view.arc42.md +33 -0
- package/quiz/docs/arc42/09-quiz-decisions.arc42.md +36 -0
- package/quiz/docs/arc42/10-quiz-quality-requirements.arc42.md +53 -0
- package/quiz/docs/arc42/11-quiz-risks.arc42.md +19 -0
- package/quiz/docs/arc42/12-quiz-glossary.arc42.md +27 -0
- package/quiz/e2e/quiz.e2e.ts +3 -0
- package/quiz/index.html +11 -0
- package/quiz/package.json +18 -0
- package/quiz/playwright.config.ts +1 -0
- package/quiz/src/images/berge-ordnen.jpg +0 -0
- package/quiz/src/images/everest-hoehe.jpg +0 -0
- package/quiz/src/images/galapagos.jpg +0 -0
- package/quiz/src/images/grand-canyon.jpg +0 -0
- package/quiz/src/images/totes-meer.jpg +0 -0
- package/quiz/src/images/uluru.jpg +0 -0
- package/quiz/src/images/wasserfaelle-laender.jpg +0 -0
- package/quiz/src/main.ts +4 -0
- package/quiz/src/quiz.json +312 -0
- package/quiz/tsconfig.json +1 -0
- package/quiz/vite.config.ts +4 -0
- package/runtime/explainer/assessment-client.ts +478 -0
- package/runtime/explainer/assessment-page.ts +446 -0
- package/runtime/explainer/assessment.ts +393 -0
- package/runtime/explainer/check-page.ts +520 -0
- package/runtime/explainer/components/exercise.ts +409 -0
- package/runtime/explainer/components/props.ts +230 -0
- package/runtime/explainer/components/read.ts +428 -0
- package/runtime/explainer/content.ts +277 -0
- package/runtime/explainer/e2e.ts +1474 -0
- package/runtime/explainer/exercises.ts +324 -0
- package/runtime/explainer/explainer.css +1283 -0
- package/runtime/explainer/explainer.ts +838 -0
- package/runtime/explainer/explainer.v1.schema.json +1165 -0
- package/runtime/explainer/expression.ts +407 -0
- package/runtime/explainer/fraction.ts +107 -0
- package/runtime/explainer/generated/comparator.ts +31 -0
- package/runtime/explainer/generated/question.ts +165 -0
- package/runtime/explainer/generated/soundness.ts +280 -0
- package/runtime/explainer/generated/texts.ts +257 -0
- package/runtime/explainer/generated/types.ts +103 -0
- package/runtime/explainer/generated/values.ts +136 -0
- package/runtime/explainer/islands.ts +281 -0
- package/runtime/explainer/load.ts +457 -0
- package/runtime/explainer/messages/de.json +200 -0
- package/runtime/explainer/messages/en.json +200 -0
- package/runtime/explainer/messages.ts +13 -0
- package/runtime/explainer/needs.ts +122 -0
- package/runtime/explainer/open-task.ts +235 -0
- package/runtime/explainer/outline.ts +299 -0
- package/runtime/explainer/plugin.ts +488 -0
- package/runtime/explainer/position.ts +62 -0
- package/runtime/explainer/prompt.ts +75 -0
- package/runtime/explainer/render.ts +686 -0
- package/runtime/explainer/result.ts +238 -0
- package/runtime/explainer/routes.ts +119 -0
- package/runtime/explainer/schema.ts +140 -0
- package/runtime/explainer/scope.ts +87 -0
- package/runtime/explainer/stuck.ts +57 -0
- package/runtime/explainer/tasks.ts +109 -0
- package/runtime/explainer/tutor.ts +469 -0
- package/runtime/explainer/tutorpage.ts +669 -0
- package/runtime/explainer/video.ts +123 -0
- package/runtime/interactive/contract.ts +121 -0
- package/runtime/interactive/e2e.ts +190 -0
- package/runtime/interactive/interactive.css +82 -0
- package/runtime/interactive/interactive.ts +115 -0
- package/runtime/interactive/interactive.v1.schema.json +146 -0
- package/runtime/interactive/load.ts +188 -0
- package/runtime/interactive/messages/de.json +14 -0
- package/runtime/interactive/messages/en.json +14 -0
- package/runtime/interactive/messages.ts +11 -0
- package/runtime/interactive/playthrough.v1.schema.json +143 -0
- package/runtime/interactive/plugin.ts +266 -0
- package/runtime/interactive/render.ts +126 -0
- package/runtime/quiz/e2e.ts +233 -0
- package/runtime/quiz/engine.ts +242 -0
- package/runtime/quiz/messages/de.json +23 -0
- package/runtime/quiz/messages/en.json +23 -0
- package/runtime/quiz/plugin.ts +150 -0
- package/runtime/quiz/quiz.css +154 -0
- package/runtime/quiz/quiz.ts +56 -0
- package/runtime/quiz/quiz.v1.schema.json +72 -0
- package/runtime/quiz/render.ts +173 -0
- package/runtime/quiz/validate.ts +108 -0
- package/runtime/shared/appname.ts +16 -0
- package/runtime/shared/blocks/block.ts +162 -0
- package/runtime/shared/blocks/blocks.css +190 -0
- package/runtime/shared/blocks/blocks.v1.schema.json +432 -0
- package/runtime/shared/blocks/code.ts +26 -0
- package/runtime/shared/blocks/figures.ts +49 -0
- package/runtime/shared/blocks/image.ts +25 -0
- package/runtime/shared/blocks/index.ts +13 -0
- package/runtime/shared/blocks/messages/de.json +4 -0
- package/runtime/shared/blocks/messages/en.json +4 -0
- package/runtime/shared/blocks/render.ts +134 -0
- package/runtime/shared/blocks/validate.ts +165 -0
- package/runtime/shared/content.ts +197 -0
- package/runtime/shared/examples.ts +20 -0
- package/runtime/shared/html.ts +10 -0
- package/runtime/shared/languages.ts +94 -0
- package/runtime/shared/page.css +101 -0
- package/runtime/shared/pages.ts +114 -0
- package/runtime/shared/questions/e2e.ts +115 -0
- package/runtime/shared/questions/engine.ts +209 -0
- package/runtime/shared/questions/index.ts +39 -0
- package/runtime/shared/questions/messages/de.json +26 -0
- package/runtime/shared/questions/messages/en.json +26 -0
- package/runtime/shared/questions/question.ts +430 -0
- package/runtime/shared/questions/question.v1.schema.json +342 -0
- package/runtime/shared/questions/questions.css +192 -0
- package/runtime/shared/questions/render.ts +247 -0
- package/runtime/shared/questions/validate.ts +518 -0
- package/runtime/shared/schema.ts +44 -0
- package/runtime/shared/text/check.ts +68 -0
- package/runtime/shared/text/formula.ts +69 -0
- package/runtime/shared/text/markdown.ts +185 -0
- package/runtime/shared/text/text.v1.schema.json +34 -0
- package/runtime/shared/vue-code.ts +395 -0
- package/runtime/shared/vue.ts +38 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
# Building Blocks
|
|
2
|
+
|
|
3
|
+
The explainer's extension of the generic architecture (`docs/arc42/` at the root of `lernapps/app-templates`): an
|
|
4
|
+
explainer of chapters of pages with an exercise on every page, whose build step, rendering, validation, client module,
|
|
5
|
+
islands, generated exercises, tutor handoff, task numbers and tests the runtime `runtime/explainer/` ships, and whose
|
|
6
|
+
creator writes the content as YAML, data files and, only where no block fits, Vue components under the component
|
|
7
|
+
contract (`explainer-only-content`, `prefer-built-in-block`); `src/main.ts` stays as generated. It reuses the quiz's
|
|
8
|
+
question types for its quiz-type exercises. Every page is complete without JavaScript
|
|
9
|
+
(`qg-explainer-readable-without-js`). The creator's assistant follows the skill `lernapps-explainer` (`if-skills`). An
|
|
10
|
+
explainer app writes no architecture of its own: the content schema fixes its structure.
|
|
11
|
+
|
|
12
|
+
## Level 1 (explainer)
|
|
13
|
+
|
|
14
|
+
```arc42
|
|
15
|
+
:::diagram
|
|
16
|
+
id: building-blocks-explainer-level-1
|
|
17
|
+
view: building-block
|
|
18
|
+
notation: mermaid
|
|
19
|
+
:::
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
flowchart TB
|
|
24
|
+
bb-tooling["Tooling helpers"]
|
|
25
|
+
bb-archetype-runtime["Explainer runtime"]
|
|
26
|
+
subgraph bb-runtime["Shared runtime"]
|
|
27
|
+
bb-blocks["Content blocks"]
|
|
28
|
+
bb-questions["Questions"]
|
|
29
|
+
end
|
|
30
|
+
bb-explainer-content["Content"]
|
|
31
|
+
bb-explainer-data["Data files (optional)"]
|
|
32
|
+
bb-explainer-components["Vue components (optional)"]
|
|
33
|
+
bb-archetype-runtime -->|"if-shared-runtime"| bb-runtime
|
|
34
|
+
bb-archetype-runtime -->|"if-questions"| bb-questions
|
|
35
|
+
bb-archetype-runtime -->|"if-blocks"| bb-blocks
|
|
36
|
+
bb-archetype-runtime -->|"if-component-rules"| bb-component-rules
|
|
37
|
+
bb-archetype-runtime -->|"if-preset"| bb-tooling
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Level 2: the explainer runtime
|
|
41
|
+
|
|
42
|
+
```arc42
|
|
43
|
+
:::diagram
|
|
44
|
+
id: building-blocks-explainer-runtime
|
|
45
|
+
view: building-block
|
|
46
|
+
notation: mermaid
|
|
47
|
+
:::
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```mermaid
|
|
51
|
+
flowchart TB
|
|
52
|
+
subgraph bb-archetype-runtime["Explainer runtime"]
|
|
53
|
+
bb-build["Build step"]
|
|
54
|
+
bb-validation["Content validation"]
|
|
55
|
+
bb-render["Page rendering"]
|
|
56
|
+
bb-shell["Client module"]
|
|
57
|
+
bb-islands["Component islands"]
|
|
58
|
+
bb-generated-exercises["Generated exercises"]
|
|
59
|
+
bb-open-tasks["Open tasks"]
|
|
60
|
+
bb-scope["Scope"]
|
|
61
|
+
bb-tutor-handoff["Tutor handoff"]
|
|
62
|
+
bb-task-numbers["Task numbers"]
|
|
63
|
+
bb-video["Video block"]
|
|
64
|
+
bb-self-assessment["Self-assessment"]
|
|
65
|
+
bb-e2e["End-to-end tests"]
|
|
66
|
+
bb-runtime-texts["Runtime texts"]
|
|
67
|
+
end
|
|
68
|
+
bb-explainer-content["Content"]
|
|
69
|
+
bb-explainer-data["Data files"]
|
|
70
|
+
bb-explainer-components["Vue components"]
|
|
71
|
+
bb-tooling["Tooling helpers"]
|
|
72
|
+
bb-build -->|"if-archetype-content"| bb-explainer-content
|
|
73
|
+
bb-build -->|"if-exercise-logic"| bb-explainer-components
|
|
74
|
+
bb-build -->|"if-tutor-files"| bb-tutor-handoff
|
|
75
|
+
bb-validation -->|"if-archetype-content"| bb-explainer-content
|
|
76
|
+
bb-validation -->|"if-data-files"| bb-explainer-data
|
|
77
|
+
bb-render -->|"if-archetype-content"| bb-explainer-content
|
|
78
|
+
bb-render -->|"if-vue-component"| bb-explainer-components
|
|
79
|
+
bb-render -->|"if-runtime-texts"| bb-runtime-texts
|
|
80
|
+
bb-shell -->|"if-task-numbers"| bb-task-numbers
|
|
81
|
+
bb-shell -->|"if-tutor-files"| bb-tutor-handoff
|
|
82
|
+
bb-shell -->|"if-runtime-texts"| bb-runtime-texts
|
|
83
|
+
bb-shell -->|"if-device-storage"| bb-tooling
|
|
84
|
+
bb-shell -->|"if-a11y"| bb-tooling
|
|
85
|
+
bb-islands -->|"if-vue-component"| bb-explainer-components
|
|
86
|
+
bb-islands -->|"if-task-numbers"| bb-task-numbers
|
|
87
|
+
bb-generated-exercises -->|"if-archetype-content"| bb-explainer-content
|
|
88
|
+
bb-open-tasks -->|"if-archetype-content"| bb-explainer-content
|
|
89
|
+
bb-scope -->|"if-archetype-content"| bb-explainer-content
|
|
90
|
+
bb-generated-exercises -->|"if-data-files"| bb-explainer-data
|
|
91
|
+
bb-tutor-handoff -->|"if-archetype-content"| bb-explainer-content
|
|
92
|
+
bb-tutor-handoff -->|"if-exercise-logic"| bb-explainer-components
|
|
93
|
+
bb-tutor-handoff -->|"if-task-numbers"| bb-task-numbers
|
|
94
|
+
bb-video -->|"if-runtime-texts"| bb-runtime-texts
|
|
95
|
+
bb-video -->|"if-device-storage"| bb-tooling
|
|
96
|
+
bb-build -->|"if-self-assessment"| bb-self-assessment
|
|
97
|
+
bb-shell -->|"if-self-assessment"| bb-self-assessment
|
|
98
|
+
bb-self-assessment -->|"if-archetype-content"| bb-explainer-content
|
|
99
|
+
bb-self-assessment -->|"if-tutor-files"| bb-tutor-handoff
|
|
100
|
+
bb-self-assessment -->|"if-task-numbers"| bb-task-numbers
|
|
101
|
+
bb-self-assessment -->|"if-runtime-texts"| bb-runtime-texts
|
|
102
|
+
bb-self-assessment -->|"if-device-storage"| bb-tooling
|
|
103
|
+
bb-e2e -->|"if-archetype-content"| bb-explainer-content
|
|
104
|
+
bb-e2e -->|"if-runtime-texts"| bb-runtime-texts
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Explainer runtime
|
|
108
|
+
|
|
109
|
+
Built. The runtime of every explainer, which the app does not change: it validates and renders the content into
|
|
110
|
+
static pages, writes the tutor pages, makes the exercises live in the browser and brings the end-to-end tests.
|
|
111
|
+
|
|
112
|
+
```arc42
|
|
113
|
+
:::building-block
|
|
114
|
+
id: bb-archetype-runtime
|
|
115
|
+
title: Explainer runtime
|
|
116
|
+
path: runtime/explainer
|
|
117
|
+
technology: TypeScript, Vite plugin, Vue
|
|
118
|
+
requires: if-shared-runtime, if-preset, if-questions, if-blocks, if-component-rules
|
|
119
|
+
implements: concept-archetype-extension
|
|
120
|
+
:::
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Build step
|
|
124
|
+
|
|
125
|
+
Built. The plugin `explainer()` reads and validates the content, runs the component rules and the property test of
|
|
126
|
+
each generated exercise and exercise component over fixed seeds, and only then writes every page in each language,
|
|
127
|
+
the tutor pages where the tutor is on, and the 404 page; `vp dev` serves the same pages.
|
|
128
|
+
|
|
129
|
+
```arc42
|
|
130
|
+
:::building-block
|
|
131
|
+
id: bb-build
|
|
132
|
+
title: Build step
|
|
133
|
+
parent: bb-archetype-runtime
|
|
134
|
+
path: runtime/explainer/plugin.ts
|
|
135
|
+
technology: Vite plugin
|
|
136
|
+
requires: if-archetype-content, if-component-rules, if-exercise-logic, if-tutor-files, if-self-assessment
|
|
137
|
+
:::
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Build plugin interface
|
|
141
|
+
|
|
142
|
+
The app's vite.config.ts adds `explainer()` to the tooling preset.
|
|
143
|
+
|
|
144
|
+
```arc42
|
|
145
|
+
:::interface
|
|
146
|
+
id: if-build-plugin
|
|
147
|
+
title: explainer() Vite plugin
|
|
148
|
+
provider: bb-build
|
|
149
|
+
protocol: TypeScript import, @lernapps/app-templates/explainer/plugin
|
|
150
|
+
path: runtime/explainer/plugin.ts
|
|
151
|
+
:::
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Content validation
|
|
155
|
+
|
|
156
|
+
Built. Validates every content file against its part of the schema, then what a schema cannot say (complete order
|
|
157
|
+
lists, depth, unique ids, complete languages, restricted Markdown, formulas in the command list, sources and
|
|
158
|
+
licences, links to pages and sections, an exercise on every page, components and their props), one line per problem
|
|
159
|
+
with file and line.
|
|
160
|
+
|
|
161
|
+
```arc42
|
|
162
|
+
:::building-block
|
|
163
|
+
id: bb-validation
|
|
164
|
+
title: Content validation
|
|
165
|
+
parent: bb-archetype-runtime
|
|
166
|
+
path: runtime/explainer/load.ts
|
|
167
|
+
technology: Ajv, JSON Schema, YAML
|
|
168
|
+
requires: if-archetype-content, if-data-files, if-component-rules, if-questions
|
|
169
|
+
:::
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Page rendering
|
|
173
|
+
|
|
174
|
+
Built. Renders every YAML page to static HTML in each language: text in restricted Markdown, formulas as MathML,
|
|
175
|
+
figures as SVG, tables, timelines, code, videos as links (`bb-video`), the exercises with their solution folded (a generated one with three worked
|
|
176
|
+
tasks), the navigation and the glossary, and each Vue component's island as the server renderer drew it, with its
|
|
177
|
+
`nojs` text. Without JavaScript every page is complete.
|
|
178
|
+
|
|
179
|
+
```arc42
|
|
180
|
+
:::building-block
|
|
181
|
+
id: bb-render
|
|
182
|
+
title: Page rendering
|
|
183
|
+
parent: bb-archetype-runtime
|
|
184
|
+
path: runtime/explainer/render.ts
|
|
185
|
+
technology: TypeScript, Temml, highlight.js, Vue server renderer
|
|
186
|
+
requires: if-archetype-content, if-vue-component, if-runtime-texts, if-questions
|
|
187
|
+
implements: concept-readable-without-js, concept-accessibility
|
|
188
|
+
:::
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### Pages interface
|
|
192
|
+
|
|
193
|
+
Learners, teachers and parents read the explainer at `lernapps.net/<repo>/` (and `/<language>/`): the start page, a
|
|
194
|
+
page per chapter, the content pages at `<chapter>/<page>/` and the glossary, with `?<id>=<n>` for the task number of
|
|
195
|
+
an exercise; the catalog entry and its topics link there.
|
|
196
|
+
|
|
197
|
+
```arc42
|
|
198
|
+
:::interface
|
|
199
|
+
id: if-pages
|
|
200
|
+
title: Explainer pages at lernapps.net/<repo>/
|
|
201
|
+
provider: bb-render
|
|
202
|
+
protocol: HTML pages over HTTPS
|
|
203
|
+
path: runtime/explainer/routes.ts
|
|
204
|
+
:::
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Client module
|
|
208
|
+
|
|
209
|
+
Built. Makes a page's exercises live: answered before the solution shows, the reason of a wrong answer, "Neue
|
|
210
|
+
Aufgabe", the task numbers in the address; the tutor button; and starts the videos (`bb-video`). It keeps only the
|
|
211
|
+
learner's chosen way to the tutor and their choice to load videos directly on the device, and the needs the learner chose for the tutor (`dec-tutor-needs`), for every explainer or
|
|
212
|
+
for this app only; the last result of a self-assessment is kept by `bb-self-assessment`, which it starts.
|
|
213
|
+
|
|
214
|
+
```arc42
|
|
215
|
+
:::building-block
|
|
216
|
+
id: bb-shell
|
|
217
|
+
title: Client module
|
|
218
|
+
parent: bb-archetype-runtime
|
|
219
|
+
path: runtime/explainer/explainer.ts
|
|
220
|
+
technology: TypeScript, DOM
|
|
221
|
+
requires: if-questions, if-task-numbers, if-tutor-files, if-runtime-texts, if-device-storage, if-a11y, if-self-assessment
|
|
222
|
+
implements: concept-accessibility, concept-determinism
|
|
223
|
+
:::
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Start interface
|
|
227
|
+
|
|
228
|
+
The app's `src/main.ts` imports the explainer's style and calls `startExplainer()`.
|
|
229
|
+
|
|
230
|
+
```arc42
|
|
231
|
+
:::interface
|
|
232
|
+
id: if-start
|
|
233
|
+
title: startExplainer()
|
|
234
|
+
provider: bb-shell
|
|
235
|
+
protocol: TypeScript import, @lernapps/app-templates/explainer
|
|
236
|
+
path: runtime/explainer/explainer.ts
|
|
237
|
+
:::
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Component islands
|
|
241
|
+
|
|
242
|
+
Built. Only on a page with a component: loads Vue, hydrates each component's island with the props of the page's
|
|
243
|
+
language, gives an exercise component the seed of its task number, takes the answer it emits, checks it on "Prüfen"
|
|
244
|
+
with its logic module, and shows the feedback (`dec-explainer-checks`). On a self-assessment's page it hydrates the
|
|
245
|
+
components once the self-assessment put them into the page, shows the task the run draws, and judges each answer
|
|
246
|
+
silently, without "Prüfen", for "Auswerten" (`dec-self-assessment`).
|
|
247
|
+
|
|
248
|
+
```arc42
|
|
249
|
+
:::building-block
|
|
250
|
+
id: bb-islands
|
|
251
|
+
title: Component islands
|
|
252
|
+
parent: bb-archetype-runtime
|
|
253
|
+
path: runtime/explainer/islands.ts
|
|
254
|
+
technology: Vue hydration
|
|
255
|
+
requires: if-vue-component, if-task-numbers
|
|
256
|
+
:::
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Generated exercises
|
|
260
|
+
|
|
261
|
+
Built. Exercises drawn from a seed (`generated`), the explainer's own notation: the same code gives three worked tasks
|
|
262
|
+
at build, runs the property test over fixed seeds and draws a live task in the browser, so both agree; their answers
|
|
263
|
+
are checked through the question types' checker.
|
|
264
|
+
The texts of a quiz-type exercise are plain text in which `$…$` is a formula, rendered as MathML at build and checked
|
|
265
|
+
like every formula.
|
|
266
|
+
|
|
267
|
+
```arc42
|
|
268
|
+
:::building-block
|
|
269
|
+
id: bb-generated-exercises
|
|
270
|
+
title: Generated exercises
|
|
271
|
+
parent: bb-archetype-runtime
|
|
272
|
+
path: runtime/explainer/generated
|
|
273
|
+
technology: TypeScript, exact fractions
|
|
274
|
+
requires: if-archetype-content, if-data-files, if-questions
|
|
275
|
+
implements: concept-determinism
|
|
276
|
+
:::
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Open tasks
|
|
280
|
+
|
|
281
|
+
Built. An open task (`open-task`) is answered in the learner's own words, typed or written on paper and photographed,
|
|
282
|
+
then compared with the points of a good answer, which the learner ticks: all right, some partly right (`teilweise`),
|
|
283
|
+
none wrong, the missed points named P1, P2 …; the model answer opens after the learner's own answer
|
|
284
|
+
(`dec-open-task`). Each content point names its source, a section of the app, which the build checks as it checks every
|
|
285
|
+
link. The same client part runs on a content page and in a self-assessment, where the ticks are the answer.
|
|
286
|
+
|
|
287
|
+
```arc42
|
|
288
|
+
:::building-block
|
|
289
|
+
id: bb-open-tasks
|
|
290
|
+
title: Open tasks
|
|
291
|
+
parent: bb-archetype-runtime
|
|
292
|
+
path: runtime/explainer/open-task.ts
|
|
293
|
+
technology: TypeScript, DOM
|
|
294
|
+
requires: if-archetype-content
|
|
295
|
+
:::
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Scope
|
|
299
|
+
|
|
300
|
+
Built, optional per app, required by lernapps/practice. The scope is the whole learning path for a tutor, written by
|
|
301
|
+
the creator's assistant in its own words from the material: `scope` in each page's YAML says what the page teaches,
|
|
302
|
+
optionally `scope` in a chapter's what it is about, and `scope` in `src/app.yaml` what the app is about and what
|
|
303
|
+
does not belong to the scope (`dec-scope`). With the app's, the build requires a page's on every page, and
|
|
304
|
+
writes a scope per content page (`<chapter>/<page>/scope/`: its text and what does not belong to the scope), per chapter
|
|
305
|
+
(`<chapter>/scope/`: all its pages) and for the whole app (`scope/`), in each language, each linking one level up, as
|
|
306
|
+
Markdown and a page for no menu and no search engine; every tutor page links its page's scope.
|
|
307
|
+
|
|
308
|
+
```arc42
|
|
309
|
+
:::building-block
|
|
310
|
+
id: bb-scope
|
|
311
|
+
title: Scope
|
|
312
|
+
parent: bb-archetype-runtime
|
|
313
|
+
path: runtime/explainer/scope.ts
|
|
314
|
+
technology: TypeScript, Markdown
|
|
315
|
+
requires: if-archetype-content
|
|
316
|
+
:::
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Tutor handoff
|
|
320
|
+
|
|
321
|
+
Built, optional per app. No model runs in the browser: after the learner's click the app hands over to the learner's
|
|
322
|
+
own assistant on one of two ways (`dec-tutor-page`), once the learner has switched an assistant on, on the start page
|
|
323
|
+
or beside the title of a content page, kept on the device (`dec-tutor-assistant`). Both ways name one address, the
|
|
324
|
+
page's tutor page `<chapter>/<page>/tutor/`, with where the learner is in its query: the page's task numbers as its
|
|
325
|
+
own address has them (`?<id>=<n>`); way B adds the exercise (`uebung`) and its section (`abschnitt`). Way A, a bar
|
|
326
|
+
beside the title of each content page, "Mit <name> lernen", opens the assistant with one sentence that asks for help
|
|
327
|
+
with the page, and the tutor page tells the tutor to lead through the page first. Way B, "Hilfe" ("Warum?" after a wrong answer) in the row of "Prüfen" and "Lösung" of every exercise, adds the
|
|
328
|
+
task, the input with its tries and the app's message word for word; without a chat it opens the assistant with them
|
|
329
|
+
(B1), on a page a tutor opened it copies them for the running chat (B2). "Zurück zum Tutor", at the top and the end of a
|
|
330
|
+
page a tutor opened, leads back with the page's tutor page and the result of each task of the session on the
|
|
331
|
+
clipboard. A chat assistant fetches only addresses its user wrote into the conversation, so the one
|
|
332
|
+
address the tutor needs comes in the prompt or in a line the learner pastes. The tutor page is the one source of what
|
|
333
|
+
the tutor gets: a short visible guide, then the page's content and its exercises with every task number, a
|
|
334
|
+
`generated` one once as its template with a table of each number's inputs and outputs (the values, the solution, what
|
|
335
|
+
each typical mistake gives), an exercise component with its `about` and the same table from its exercise logic
|
|
336
|
+
(`dec-component-table`), or without one each number's task and solution from its `describe` as far as they fit into
|
|
337
|
+
64 kB; its Markdown lies beside it for copying. Under "Besondere Anforderungen" it ends with a short section for each
|
|
338
|
+
need a learner can choose, which holds when the query names it in `bedarf=` (`dec-tutor-needs`). No
|
|
339
|
+
prompt and no line carries a rule for the tutor, and the app writes no `llms.txt`.
|
|
340
|
+
|
|
341
|
+
```arc42
|
|
342
|
+
:::building-block
|
|
343
|
+
id: bb-tutor-handoff
|
|
344
|
+
title: Tutor handoff
|
|
345
|
+
parent: bb-archetype-runtime
|
|
346
|
+
path: runtime/explainer/tutor.ts
|
|
347
|
+
technology: TypeScript, static Markdown
|
|
348
|
+
requires: if-archetype-content, if-exercise-logic, if-task-numbers
|
|
349
|
+
implements: concept-tutor
|
|
350
|
+
:::
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
#### Tutor pages and the learner's lines
|
|
354
|
+
|
|
355
|
+
The start prompt of way A, the lines of "Hilfe" (way B) and the result line of "Zurück zum Tutor" name the page's
|
|
356
|
+
tutor page with the page's task numbers, those of way B also with `uebung` and `abschnitt`, those that start a chat
|
|
357
|
+
(way A, B1) also with the learner's needs in `bedarf`, absolute; the start prompt adds "Meine Muttersprache ist …"
|
|
358
|
+
when `andere-muttersprache` is chosen; the lines of way B and the result line
|
|
359
|
+
add the task, the input, the app's message word for word and how far the learner got. A chat assistant reads the
|
|
360
|
+
tutor page without running JavaScript; its Markdown (`index.md`) is the text "Ein anderer: Text kopieren" copies. The
|
|
361
|
+
page ids, exercise ids, the query parameters, the ids of the needs, the tutor page's structure, the result line and the lines of way B are
|
|
362
|
+
a contract with every tutor.
|
|
363
|
+
|
|
364
|
+
```arc42
|
|
365
|
+
:::interface
|
|
366
|
+
id: if-tutor-files
|
|
367
|
+
title: Tutor pages, start prompt and the learner's lines
|
|
368
|
+
provider: bb-tutor-handoff
|
|
369
|
+
protocol: Prompt text (provider link or clipboard), result line and the lines of way B (clipboard), static HTML and Markdown over HTTPS
|
|
370
|
+
path: runtime/explainer/tutorpage.ts
|
|
371
|
+
:::
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Task numbers
|
|
375
|
+
|
|
376
|
+
Built: the distinct tasks of a seeded exercise numbered 1 to N, the one identifier learner, tutor and address
|
|
377
|
+
(`?<id>=<n>`) share.
|
|
378
|
+
|
|
379
|
+
```arc42
|
|
380
|
+
:::building-block
|
|
381
|
+
id: bb-task-numbers
|
|
382
|
+
title: Task numbers
|
|
383
|
+
parent: bb-archetype-runtime
|
|
384
|
+
path: runtime/explainer/tasks.ts
|
|
385
|
+
technology: TypeScript
|
|
386
|
+
implements: concept-determinism
|
|
387
|
+
:::
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Task numbers interface
|
|
391
|
+
|
|
392
|
+
The client module, the islands and the tutor handoff turn a task number into its seed and back.
|
|
393
|
+
|
|
394
|
+
```arc42
|
|
395
|
+
:::interface
|
|
396
|
+
id: if-task-numbers
|
|
397
|
+
title: Task numbers and their seeds
|
|
398
|
+
provider: bb-task-numbers
|
|
399
|
+
protocol: TypeScript import
|
|
400
|
+
path: runtime/explainer/tasks.ts
|
|
401
|
+
:::
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Video block
|
|
405
|
+
|
|
406
|
+
Built. A YouTube video behind two clicks (`dec-explainer-video-two-click`): the page rendering writes the video as a
|
|
407
|
+
figure with its title as a link to youtube.com, its channel and a note that playing it sends data, among them the IP
|
|
408
|
+
address, to YouTube/Google; nothing loads from another host. The client module shows "Video abspielen", which puts
|
|
409
|
+
the player of youtube-nocookie.com into the figure, and "Videos immer direkt laden", a standing choice kept on the
|
|
410
|
+
device until the learner clears it. The tutor page names the video in its section as a link with its title and
|
|
411
|
+
channel, as it names a figure by its alt text.
|
|
412
|
+
|
|
413
|
+
```arc42
|
|
414
|
+
:::building-block
|
|
415
|
+
id: bb-video
|
|
416
|
+
title: Video block
|
|
417
|
+
parent: bb-archetype-runtime
|
|
418
|
+
path: runtime/explainer/video.ts
|
|
419
|
+
technology: TypeScript, DOM, iframe
|
|
420
|
+
requires: if-runtime-texts, if-device-storage
|
|
421
|
+
implements: concept-readable-without-js
|
|
422
|
+
:::
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
#### Video player request
|
|
426
|
+
|
|
427
|
+
The one request to another host an explainer makes on its own: the address of a video's player,
|
|
428
|
+
`https://www.youtube-nocookie.com/embed/<id>`, in an iframe named by the video's title, with the app's origin as its
|
|
429
|
+
only referrer; sent after the learner's click, or on opening the page once they chose to load videos directly.
|
|
430
|
+
|
|
431
|
+
```arc42
|
|
432
|
+
:::interface
|
|
433
|
+
id: if-video-player
|
|
434
|
+
title: Video player request to youtube-nocookie.com
|
|
435
|
+
provider: bb-video
|
|
436
|
+
protocol: HTML iframe over HTTPS, after a click
|
|
437
|
+
path: runtime/explainer/video.ts
|
|
438
|
+
:::
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Self-assessment
|
|
442
|
+
|
|
443
|
+
Built. An optional self-assessment (`dec-self-assessment`), declared per chapter: `selfAssessment` in its
|
|
444
|
+
`chapter.yaml`, its pages with the exercises it asks, each by `/<chapter>/<page>/#<exercise>` of the chapter (a
|
|
445
|
+
generated one, a question type or an exercise component). The app's is every chapter's in the order of the
|
|
446
|
+
chapters (`einschaetzung/`), a chapter's its own (`<chapter>/einschaetzung/`; in an app with one chapter, the app's is
|
|
447
|
+
the chapter's). The validation checks each reference, that it is of the chapter and that an exercise is listed once;
|
|
448
|
+
the build notes a page of it with fewer than two or more than five exercises. The page rendering writes its page and
|
|
449
|
+
the offer on the start page or the chapter's page, every part of them in a `<template>` until the client module puts it
|
|
450
|
+
into the page, and its tutor page `<assessment>/tutor/`, which makes the tutor a guide (`dec-self-assessment-tutor`).
|
|
451
|
+
In the browser a run draws a new task of each generated exercise and exercise component (the islands show a
|
|
452
|
+
component's task and judge its answer silently, `bb-islands`), shows the pages one by one without "Prüfen", checks
|
|
453
|
+
all exercises together at "Auswerten" and shows for each content page in its scope whether the learner probably knows
|
|
454
|
+
it, should look at it again or should read it; a page with no exercise in it is not asked. The last result stays on the
|
|
455
|
+
device, one per self-assessment (`dec-self-assessment-result`); a run a tutor opened keeps nothing and ends in "Zurück
|
|
456
|
+
zum Tutor".
|
|
457
|
+
|
|
458
|
+
```arc42
|
|
459
|
+
:::building-block
|
|
460
|
+
id: bb-self-assessment
|
|
461
|
+
title: Self-assessment
|
|
462
|
+
parent: bb-archetype-runtime
|
|
463
|
+
path: runtime/explainer/assessment.ts
|
|
464
|
+
technology: TypeScript, DOM, static HTML and Markdown
|
|
465
|
+
requires: if-archetype-content, if-tutor-files, if-task-numbers, if-questions, if-runtime-texts, if-device-storage
|
|
466
|
+
implements: concept-tutor
|
|
467
|
+
:::
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
#### Self-assessment interface
|
|
471
|
+
|
|
472
|
+
The build step writes the page, the offer and the tutor page of each self-assessment (`assessment-page.ts`); the client
|
|
473
|
+
module starts it (`assessment-client.ts`). Its addresses, the query of its tutor page (`?a1=17-falsch-F1&a2=richtig&a3=teilweise-P2`:
|
|
474
|
+
each exercise by its key in order, its task number, `richtig`, `teilweise`, `falsch` or `offen`, the typical mistake,
|
|
475
|
+
the points a partly right answer missed), the lines of
|
|
476
|
+
its prompt and of "Zurück zum Tutor", and the result kept under `self-assessment` or `self-assessment:<chapter>` are a
|
|
477
|
+
contract with every tutor and with the result kept on a device.
|
|
478
|
+
|
|
479
|
+
```arc42
|
|
480
|
+
:::interface
|
|
481
|
+
id: if-self-assessment
|
|
482
|
+
title: Self-assessment page, its tutor page and the result kept on the device
|
|
483
|
+
provider: bb-self-assessment
|
|
484
|
+
protocol: Static HTML and Markdown over HTTPS, prompt text (provider link or clipboard), JSON in localStorage
|
|
485
|
+
path: runtime/explainer/assessment.ts
|
|
486
|
+
:::
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### End-to-end tests
|
|
490
|
+
|
|
491
|
+
Built. `explainerTests()` derives from the content what every page must show, checks it without JavaScript in every
|
|
492
|
+
language, and with JavaScript one exercise per type and page and every component.
|
|
493
|
+
|
|
494
|
+
```arc42
|
|
495
|
+
:::building-block
|
|
496
|
+
id: bb-e2e
|
|
497
|
+
title: End-to-end tests
|
|
498
|
+
parent: bb-archetype-runtime
|
|
499
|
+
path: runtime/explainer/e2e.ts
|
|
500
|
+
technology: Playwright
|
|
501
|
+
requires: if-archetype-content, if-runtime-texts, if-questions
|
|
502
|
+
:::
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
#### Tests interface
|
|
506
|
+
|
|
507
|
+
The app's `e2e/explainer.e2e.ts` only calls `explainerTests()`.
|
|
508
|
+
|
|
509
|
+
```arc42
|
|
510
|
+
:::interface
|
|
511
|
+
id: if-e2e-tests
|
|
512
|
+
title: explainerTests()
|
|
513
|
+
provider: bb-e2e
|
|
514
|
+
protocol: TypeScript import, @lernapps/app-templates/explainer/e2e
|
|
515
|
+
path: runtime/explainer/e2e.ts
|
|
516
|
+
:::
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Runtime texts
|
|
520
|
+
|
|
521
|
+
Built. The explainer's own learner texts in German and English; an app may declare only these languages.
|
|
522
|
+
|
|
523
|
+
```arc42
|
|
524
|
+
:::building-block
|
|
525
|
+
id: bb-runtime-texts
|
|
526
|
+
title: Runtime texts
|
|
527
|
+
parent: bb-archetype-runtime
|
|
528
|
+
path: runtime/explainer/messages.ts
|
|
529
|
+
technology: JSON per language
|
|
530
|
+
implements: concept-languages
|
|
531
|
+
:::
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
#### Runtime texts interface
|
|
535
|
+
|
|
536
|
+
The rendering, the client module and the tests take the explainer's texts by key and language.
|
|
537
|
+
|
|
538
|
+
```arc42
|
|
539
|
+
:::interface
|
|
540
|
+
id: if-runtime-texts
|
|
541
|
+
title: Explainer texts by language
|
|
542
|
+
provider: bb-runtime-texts
|
|
543
|
+
protocol: TypeScript import, JSON
|
|
544
|
+
path: runtime/explainer/messages
|
|
545
|
+
:::
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
## Content
|
|
549
|
+
|
|
550
|
+
Built in the template, written by the creator: `src/app.yaml` and a folder per chapter with `chapter.yaml` and its
|
|
551
|
+
pages of blocks, each page with an exercise; optionally the scope for the tutor in them (`bb-scope`).
|
|
552
|
+
|
|
553
|
+
```arc42
|
|
554
|
+
:::building-block
|
|
555
|
+
id: bb-explainer-content
|
|
556
|
+
title: Content
|
|
557
|
+
technology: YAML, restricted Markdown, LaTeX subset
|
|
558
|
+
implements: concept-languages
|
|
559
|
+
path: explainer/src/app.yaml
|
|
560
|
+
:::
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Content interface
|
|
564
|
+
|
|
565
|
+
The explainer's content: build, validation, rendering, generated exercises, tutor pages and tests read it only through
|
|
566
|
+
its schema.
|
|
567
|
+
|
|
568
|
+
```arc42
|
|
569
|
+
:::interface
|
|
570
|
+
id: if-archetype-content
|
|
571
|
+
title: Content YAML (explainer.v1 schema)
|
|
572
|
+
provider: bb-explainer-content
|
|
573
|
+
protocol: YAML, JSON Schema
|
|
574
|
+
path: runtime/explainer/explainer.v1.schema.json
|
|
575
|
+
:::
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
## Data files
|
|
579
|
+
|
|
580
|
+
Optional, not in the template: `src/data/<name>.yaml`, lists of records a timeline or a generated exercise draws
|
|
581
|
+
from, so each fact is written once.
|
|
582
|
+
|
|
583
|
+
```arc42
|
|
584
|
+
:::ignore H014 optional and not in the template; an app that adds it sets its path in its own architecture
|
|
585
|
+
:::
|
|
586
|
+
:::building-block
|
|
587
|
+
id: bb-explainer-data
|
|
588
|
+
title: Data files
|
|
589
|
+
technology: YAML
|
|
590
|
+
:::
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Data files interface
|
|
594
|
+
|
|
595
|
+
A block names a data file by its name (`data: ereignisse`, `from: { data: elemente }`).
|
|
596
|
+
|
|
597
|
+
```arc42
|
|
598
|
+
:::ignore H014 optional and not in the template; an app that adds it sets its path in its own architecture
|
|
599
|
+
:::
|
|
600
|
+
:::interface
|
|
601
|
+
id: if-data-files
|
|
602
|
+
title: Data files src/data/<name>.yaml
|
|
603
|
+
provider: bb-explainer-data
|
|
604
|
+
protocol: YAML records
|
|
605
|
+
:::
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
## Vue components
|
|
609
|
+
|
|
610
|
+
Optional: `src/components/<Name>.vue` with its test, for what no block can express, under the component rules and
|
|
611
|
+
within a fixed size each (`dec-explainer-component-size`); an exercise component adds its logic module. The template
|
|
612
|
+
has one as an example, `ProzentFeld` on the page `prozent/prozentwert`: a field of G squares of which the learner
|
|
613
|
+
colours p %, with the exercise declared for the tutor (`dec-component-table`), so that a hand test shows how a tutor
|
|
614
|
+
deals with its typical mistakes.
|
|
615
|
+
|
|
616
|
+
```arc42
|
|
617
|
+
:::building-block
|
|
618
|
+
id: bb-explainer-components
|
|
619
|
+
title: Vue components
|
|
620
|
+
path: explainer/src/components
|
|
621
|
+
technology: Vue single-file components, TypeScript
|
|
622
|
+
implements: concept-component-rules
|
|
623
|
+
:::
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Component contract
|
|
627
|
+
|
|
628
|
+
A `vue-component` block names the component with its typed props and a `nojs` text; an exercise component is the
|
|
629
|
+
input of its task: it takes the prop `seed`, emits `answer` with the learner's answer each time it changes, may take
|
|
630
|
+
the prop `checked`, and draws no "Prüfen" of its own, which the explainer draws under it (`dec-explainer-checks`).
|
|
631
|
+
|
|
632
|
+
```arc42
|
|
633
|
+
:::interface
|
|
634
|
+
id: if-vue-component
|
|
635
|
+
title: Component contract (props, nojs, answer)
|
|
636
|
+
provider: bb-explainer-components
|
|
637
|
+
path: explainer/src/components/ProzentFeld.vue
|
|
638
|
+
protocol: Vue props and events, YAML block
|
|
639
|
+
:::
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### Exercise logic module
|
|
643
|
+
|
|
644
|
+
An exercise component's `<Name>.ts` exports `generate`, `check`, `solution`, `wrong`, `reason`, `describe` and
|
|
645
|
+
`about`: the exercise contract, which the build tests over fixed seeds, the islands call on "Prüfen" and the tutor
|
|
646
|
+
pages read (the task and its solution as text
|
|
647
|
+
in each language, and what the exercise is for a tutor). For its table of tasks it adds `template`, `params`,
|
|
648
|
+
`mistakes` and `show`, all four or none (`dec-component-table`); the build checks them against `check` for every task
|
|
649
|
+
number and gives a hint for a component without them.
|
|
650
|
+
|
|
651
|
+
```arc42
|
|
652
|
+
:::interface
|
|
653
|
+
id: if-exercise-logic
|
|
654
|
+
title: Exercise logic module (exercise contract)
|
|
655
|
+
provider: bb-explainer-components
|
|
656
|
+
path: explainer/src/components/ProzentFeld.ts
|
|
657
|
+
protocol: TypeScript module exports
|
|
658
|
+
:::
|
|
659
|
+
```
|