@teachinglab/omd 0.6.1 → 0.6.3
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/README.md +257 -251
- package/README.old.md +137 -137
- package/canvas/core/canvasConfig.js +202 -202
- package/canvas/drawing/segment.js +167 -167
- package/canvas/drawing/stroke.js +385 -385
- package/canvas/events/eventManager.js +444 -444
- package/canvas/events/pointerEventHandler.js +262 -262
- package/canvas/index.js +48 -48
- package/canvas/tools/PointerTool.js +71 -71
- package/canvas/tools/tool.js +222 -222
- package/canvas/utils/boundingBox.js +377 -377
- package/canvas/utils/mathUtils.js +258 -258
- package/docs/api/configuration-options.md +198 -198
- package/docs/api/eventManager.md +82 -82
- package/docs/api/focusFrameManager.md +144 -144
- package/docs/api/index.md +105 -105
- package/docs/api/main.md +62 -62
- package/docs/api/omdBinaryExpressionNode.md +86 -86
- package/docs/api/omdCanvas.md +83 -83
- package/docs/api/omdConfigManager.md +112 -112
- package/docs/api/omdConstantNode.md +52 -52
- package/docs/api/omdDisplay.md +87 -87
- package/docs/api/omdEquationNode.md +174 -174
- package/docs/api/omdEquationSequenceNode.md +258 -258
- package/docs/api/omdEquationStack.md +192 -192
- package/docs/api/omdFunctionNode.md +82 -82
- package/docs/api/omdGroupNode.md +78 -78
- package/docs/api/omdHelpers.md +87 -87
- package/docs/api/omdLeafNode.md +85 -85
- package/docs/api/omdNode.md +201 -201
- package/docs/api/omdOperationDisplayNode.md +117 -117
- package/docs/api/omdOperatorNode.md +91 -91
- package/docs/api/omdParenthesisNode.md +133 -133
- package/docs/api/omdPopup.md +191 -191
- package/docs/api/omdPowerNode.md +131 -131
- package/docs/api/omdRationalNode.md +144 -144
- package/docs/api/omdSequenceNode.md +128 -128
- package/docs/api/omdSimplification.md +78 -78
- package/docs/api/omdSqrtNode.md +144 -144
- package/docs/api/omdStepVisualizer.md +146 -146
- package/docs/api/omdStepVisualizerHighlighting.md +65 -65
- package/docs/api/omdStepVisualizerInteractiveSteps.md +108 -108
- package/docs/api/omdStepVisualizerLayout.md +70 -70
- package/docs/api/omdStepVisualizerNodeUtils.md +140 -140
- package/docs/api/omdStepVisualizerTextBoxes.md +76 -76
- package/docs/api/omdToolbar.md +130 -130
- package/docs/api/omdTranscriptionService.md +95 -95
- package/docs/api/omdTreeDiff.md +169 -169
- package/docs/api/omdUnaryExpressionNode.md +137 -137
- package/docs/api/omdUtilities.md +82 -82
- package/docs/api/omdVariableNode.md +123 -123
- package/docs/api/selectTool.md +74 -74
- package/docs/api/simplificationEngine.md +97 -97
- package/docs/api/simplificationRules.md +76 -76
- package/docs/api/simplificationUtils.md +64 -64
- package/docs/api/transcribe.md +43 -43
- package/docs/api-reference.md +85 -85
- package/docs/index.html +453 -453
- package/docs/index.md +38 -38
- package/docs/omd-objects.md +258 -258
- package/index.js +79 -79
- package/jsvg/index.js +3 -0
- package/jsvg/jsvg.js +898 -898
- package/jsvg/jsvgComponents.js +357 -358
- package/npm-docs/DOCUMENTATION_SUMMARY.md +220 -220
- package/npm-docs/README.md +251 -251
- package/npm-docs/api/api-reference.md +85 -85
- package/npm-docs/api/configuration-options.md +198 -198
- package/npm-docs/api/eventManager.md +82 -82
- package/npm-docs/api/expression-nodes.md +561 -561
- package/npm-docs/api/focusFrameManager.md +144 -144
- package/npm-docs/api/index.md +105 -105
- package/npm-docs/api/main.md +62 -62
- package/npm-docs/api/omdBinaryExpressionNode.md +86 -86
- package/npm-docs/api/omdCanvas.md +83 -83
- package/npm-docs/api/omdConfigManager.md +112 -112
- package/npm-docs/api/omdConstantNode.md +52 -52
- package/npm-docs/api/omdDisplay.md +87 -87
- package/npm-docs/api/omdEquationNode.md +174 -174
- package/npm-docs/api/omdEquationSequenceNode.md +258 -258
- package/npm-docs/api/omdEquationStack.md +192 -192
- package/npm-docs/api/omdFunctionNode.md +82 -82
- package/npm-docs/api/omdGroupNode.md +78 -78
- package/npm-docs/api/omdHelpers.md +87 -87
- package/npm-docs/api/omdLeafNode.md +85 -85
- package/npm-docs/api/omdNode.md +201 -201
- package/npm-docs/api/omdOperationDisplayNode.md +117 -117
- package/npm-docs/api/omdOperatorNode.md +91 -91
- package/npm-docs/api/omdParenthesisNode.md +133 -133
- package/npm-docs/api/omdPopup.md +191 -191
- package/npm-docs/api/omdPowerNode.md +131 -131
- package/npm-docs/api/omdRationalNode.md +144 -144
- package/npm-docs/api/omdSequenceNode.md +128 -128
- package/npm-docs/api/omdSimplification.md +78 -78
- package/npm-docs/api/omdSqrtNode.md +144 -144
- package/npm-docs/api/omdStepVisualizer.md +146 -146
- package/npm-docs/api/omdStepVisualizerHighlighting.md +65 -65
- package/npm-docs/api/omdStepVisualizerInteractiveSteps.md +108 -108
- package/npm-docs/api/omdStepVisualizerLayout.md +70 -70
- package/npm-docs/api/omdStepVisualizerNodeUtils.md +140 -140
- package/npm-docs/api/omdStepVisualizerTextBoxes.md +76 -76
- package/npm-docs/api/omdToolbar.md +130 -130
- package/npm-docs/api/omdTranscriptionService.md +95 -95
- package/npm-docs/api/omdTreeDiff.md +169 -169
- package/npm-docs/api/omdUnaryExpressionNode.md +137 -137
- package/npm-docs/api/omdUtilities.md +82 -82
- package/npm-docs/api/omdVariableNode.md +123 -123
- package/npm-docs/api/selectTool.md +74 -74
- package/npm-docs/api/simplificationEngine.md +97 -97
- package/npm-docs/api/simplificationRules.md +76 -76
- package/npm-docs/api/simplificationUtils.md +64 -64
- package/npm-docs/api/transcribe.md +43 -43
- package/npm-docs/guides/equations.md +854 -854
- package/npm-docs/guides/factory-functions.md +354 -354
- package/npm-docs/guides/getting-started.md +318 -318
- package/npm-docs/guides/quick-examples.md +525 -525
- package/npm-docs/guides/visualizations.md +682 -682
- package/npm-docs/index.html +12 -0
- package/npm-docs/json-schemas.md +826 -826
- package/omd/config/omdConfigManager.js +279 -267
- package/omd/core/index.js +158 -158
- package/omd/core/omdEquationStack.js +606 -547
- package/omd/core/omdUtilities.js +113 -113
- package/omd/display/omdDisplay.js +1045 -963
- package/omd/display/omdToolbar.js +501 -501
- package/omd/nodes/omdBinaryExpressionNode.js +459 -459
- package/omd/nodes/omdConstantNode.js +141 -141
- package/omd/nodes/omdEquationNode.js +1327 -1327
- package/omd/nodes/omdFunctionNode.js +351 -351
- package/omd/nodes/omdGroupNode.js +67 -67
- package/omd/nodes/omdLeafNode.js +76 -76
- package/omd/nodes/omdNode.js +556 -556
- package/omd/nodes/omdOperationDisplayNode.js +321 -321
- package/omd/nodes/omdOperatorNode.js +108 -108
- package/omd/nodes/omdParenthesisNode.js +292 -292
- package/omd/nodes/omdPowerNode.js +235 -235
- package/omd/nodes/omdRationalNode.js +295 -295
- package/omd/nodes/omdSqrtNode.js +307 -307
- package/omd/nodes/omdUnaryExpressionNode.js +227 -227
- package/omd/nodes/omdVariableNode.js +122 -122
- package/omd/simplification/omdSimplification.js +140 -140
- package/omd/simplification/omdSimplificationEngine.js +887 -887
- package/omd/simplification/package.json +5 -5
- package/omd/simplification/rules/binaryRules.js +1037 -1037
- package/omd/simplification/rules/functionRules.js +111 -111
- package/omd/simplification/rules/index.js +48 -48
- package/omd/simplification/rules/parenthesisRules.js +19 -19
- package/omd/simplification/rules/powerRules.js +143 -143
- package/omd/simplification/rules/rationalRules.js +725 -725
- package/omd/simplification/rules/sqrtRules.js +48 -48
- package/omd/simplification/rules/unaryRules.js +37 -37
- package/omd/simplification/simplificationRules.js +31 -31
- package/omd/simplification/simplificationUtils.js +1055 -1055
- package/omd/step-visualizer/omdStepVisualizer.js +947 -947
- package/omd/step-visualizer/omdStepVisualizerHighlighting.js +246 -246
- package/omd/step-visualizer/omdStepVisualizerLayout.js +892 -892
- package/omd/step-visualizer/omdStepVisualizerTextBoxes.js +200 -200
- package/omd/utils/aiNextEquationStep.js +106 -106
- package/omd/utils/omdNodeOverlay.js +638 -638
- package/omd/utils/omdPopup.js +1203 -1203
- package/omd/utils/omdStepVisualizerInteractiveSteps.js +684 -684
- package/omd/utils/omdStepVisualizerNodeUtils.js +267 -267
- package/omd/utils/omdTranscriptionService.js +123 -123
- package/omd/utils/omdTreeDiff.js +733 -733
- package/package.json +59 -57
- package/readme.html +184 -120
- package/src/index.js +74 -74
- package/src/json-schemas.md +576 -576
- package/src/omd-json-samples.js +147 -147
- package/src/omdApp.js +391 -391
- package/src/omdAppCanvas.js +335 -335
- package/src/omdBalanceHanger.js +199 -199
- package/src/omdColor.js +13 -13
- package/src/omdCoordinatePlane.js +541 -541
- package/src/omdExpression.js +115 -115
- package/src/omdFactory.js +150 -150
- package/src/omdFunction.js +114 -114
- package/src/omdMetaExpression.js +290 -290
- package/src/omdNaturalExpression.js +563 -563
- package/src/omdNode.js +383 -383
- package/src/omdNumber.js +52 -52
- package/src/omdNumberLine.js +114 -112
- package/src/omdNumberTile.js +118 -118
- package/src/omdOperator.js +72 -72
- package/src/omdPowerExpression.js +91 -91
- package/src/omdProblem.js +259 -259
- package/src/omdRatioChart.js +251 -251
- package/src/omdRationalExpression.js +114 -114
- package/src/omdSampleData.js +215 -215
- package/src/omdShapes.js +512 -512
- package/src/omdSpinner.js +151 -151
- package/src/omdString.js +49 -49
- package/src/omdTable.js +498 -498
- package/src/omdTapeDiagram.js +244 -244
- package/src/omdTerm.js +91 -91
- package/src/omdTileEquation.js +349 -349
- package/src/omdUtils.js +84 -84
- package/src/omdVariable.js +51 -51
|
@@ -1,267 +1,279 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OMD Configuration Manager
|
|
3
|
-
* Dynamically loads and manages configuration from JSON file
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Configuration data - will be loaded from JSON or provided by user
|
|
7
|
-
let configData = null;
|
|
8
|
-
let configLoadPromise = null;
|
|
9
|
-
|
|
10
|
-
// Default configuration (fallback when no config file is available)
|
|
11
|
-
const defaultConfig = {
|
|
12
|
-
multiplication: {
|
|
13
|
-
symbol: "·",
|
|
14
|
-
forceImplicit: false,
|
|
15
|
-
implicitCombinations: {
|
|
16
|
-
constantVariable: true,
|
|
17
|
-
variableConstant: false,
|
|
18
|
-
parenthesisAfterVariable: true,
|
|
19
|
-
parenthesisAfterConstant: true,
|
|
20
|
-
variableParenthesis: true,
|
|
21
|
-
parenthesisParenthesis: true,
|
|
22
|
-
parenthesisVariable: true,
|
|
23
|
-
parenthesisConstant: true,
|
|
24
|
-
variableVariable: true
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
stepVisualizer: {
|
|
28
|
-
dotSizes: {
|
|
29
|
-
level0: 8,
|
|
30
|
-
level1: 8,
|
|
31
|
-
level2: 8
|
|
32
|
-
},
|
|
33
|
-
fontWeights: {
|
|
34
|
-
level0: 400,
|
|
35
|
-
level1: 400,
|
|
36
|
-
level2: 400
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Loads configuration from JSON file or uses default
|
|
43
|
-
* @param {string|Object} configSource - Optional path to config file or config object
|
|
44
|
-
* @returns {Promise<Object>} Promise that resolves to the configuration object
|
|
45
|
-
*/
|
|
46
|
-
async function loadConfig(configSource = null) {
|
|
47
|
-
if (configLoadPromise && !configSource) {
|
|
48
|
-
return configLoadPromise;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// If a config object is provided directly, use it
|
|
52
|
-
if (configSource && typeof configSource === 'object') {
|
|
53
|
-
configData = { ...defaultConfig, ...configSource };
|
|
54
|
-
return configData;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
configLoadPromise = (async () => {
|
|
58
|
-
try {
|
|
59
|
-
// Detect environment and use appropriate loading method
|
|
60
|
-
if (typeof window !== 'undefined') {
|
|
61
|
-
// Browser environment - use fetch
|
|
62
|
-
const configPath = configSource || './omd/config/omdConfig.json';
|
|
63
|
-
const response = await fetch(configPath);
|
|
64
|
-
if (!response.ok) {
|
|
65
|
-
console.warn(`Config file not found at ${configPath}, using default configuration`);
|
|
66
|
-
configData = defaultConfig;
|
|
67
|
-
return configData;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const configText = await response.text();
|
|
71
|
-
const loadedConfig = JSON.parse(configText);
|
|
72
|
-
configData = { ...defaultConfig, ...loadedConfig };
|
|
73
|
-
return configData;
|
|
74
|
-
|
|
75
|
-
} else {
|
|
76
|
-
// Node.js environment - use
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
*
|
|
118
|
-
* @returns {Object}
|
|
119
|
-
*/
|
|
120
|
-
function
|
|
121
|
-
if (!configData) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
*
|
|
130
|
-
* @
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*
|
|
167
|
-
* @
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
*
|
|
179
|
-
* @returns {
|
|
180
|
-
*/
|
|
181
|
-
export function
|
|
182
|
-
const config = getConfigSync();
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
*
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
*
|
|
201
|
-
* @param {string}
|
|
202
|
-
* @
|
|
203
|
-
*/
|
|
204
|
-
export function
|
|
205
|
-
const config = getConfigSync();
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
*
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
*
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
*
|
|
261
|
-
* @
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
1
|
+
/**
|
|
2
|
+
* OMD Configuration Manager
|
|
3
|
+
* Dynamically loads and manages configuration from JSON file
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Configuration data - will be loaded from JSON or provided by user
|
|
7
|
+
let configData = null;
|
|
8
|
+
let configLoadPromise = null;
|
|
9
|
+
|
|
10
|
+
// Default configuration (fallback when no config file is available)
|
|
11
|
+
const defaultConfig = {
|
|
12
|
+
multiplication: {
|
|
13
|
+
symbol: "·",
|
|
14
|
+
forceImplicit: false,
|
|
15
|
+
implicitCombinations: {
|
|
16
|
+
constantVariable: true,
|
|
17
|
+
variableConstant: false,
|
|
18
|
+
parenthesisAfterVariable: true,
|
|
19
|
+
parenthesisAfterConstant: true,
|
|
20
|
+
variableParenthesis: true,
|
|
21
|
+
parenthesisParenthesis: true,
|
|
22
|
+
parenthesisVariable: true,
|
|
23
|
+
parenthesisConstant: true,
|
|
24
|
+
variableVariable: true
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
stepVisualizer: {
|
|
28
|
+
dotSizes: {
|
|
29
|
+
level0: 8,
|
|
30
|
+
level1: 8,
|
|
31
|
+
level2: 8
|
|
32
|
+
},
|
|
33
|
+
fontWeights: {
|
|
34
|
+
level0: 400,
|
|
35
|
+
level1: 400,
|
|
36
|
+
level2: 400
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Loads configuration from JSON file or uses default
|
|
43
|
+
* @param {string|Object} configSource - Optional path to config file or config object
|
|
44
|
+
* @returns {Promise<Object>} Promise that resolves to the configuration object
|
|
45
|
+
*/
|
|
46
|
+
async function loadConfig(configSource = null) {
|
|
47
|
+
if (configLoadPromise && !configSource) {
|
|
48
|
+
return configLoadPromise;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// If a config object is provided directly, use it
|
|
52
|
+
if (configSource && typeof configSource === 'object') {
|
|
53
|
+
configData = { ...defaultConfig, ...configSource };
|
|
54
|
+
return configData;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
configLoadPromise = (async () => {
|
|
58
|
+
try {
|
|
59
|
+
// Detect environment and use appropriate loading method
|
|
60
|
+
if (typeof window !== 'undefined') {
|
|
61
|
+
// Browser environment - use fetch
|
|
62
|
+
const configPath = configSource || './omd/config/omdConfig.json';
|
|
63
|
+
const response = await fetch(configPath);
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
console.warn(`Config file not found at ${configPath}, using default configuration`);
|
|
66
|
+
configData = defaultConfig;
|
|
67
|
+
return configData;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const configText = await response.text();
|
|
71
|
+
const loadedConfig = JSON.parse(configText);
|
|
72
|
+
configData = { ...defaultConfig, ...loadedConfig };
|
|
73
|
+
return configData;
|
|
74
|
+
|
|
75
|
+
} else {
|
|
76
|
+
// Server/Node.js environment - use filesystem access when available
|
|
77
|
+
const isNodeEnvironment = typeof process !== 'undefined' && !!(process.versions && process.versions.node);
|
|
78
|
+
if (!isNodeEnvironment) {
|
|
79
|
+
console.warn('Config loading skipped: filesystem APIs unavailable in this environment. Using default configuration.');
|
|
80
|
+
configData = defaultConfig;
|
|
81
|
+
return configData;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const fs = await import('node:fs/promises');
|
|
86
|
+
const path = await import('node:path');
|
|
87
|
+
const { fileURLToPath } = await import('node:url');
|
|
88
|
+
|
|
89
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
90
|
+
const configPath = configSource || path.join(__dirname, 'omdConfig.json');
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const fileContent = await fs.readFile(configPath, 'utf-8');
|
|
94
|
+
const loadedConfig = JSON.parse(fileContent);
|
|
95
|
+
configData = { ...defaultConfig, ...loadedConfig };
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.warn(`Config file not found at ${configPath}, using default configuration`);
|
|
98
|
+
configData = defaultConfig;
|
|
99
|
+
}
|
|
100
|
+
} catch (nodeImportError) {
|
|
101
|
+
console.warn('Config loading skipped: unable to access Node filesystem APIs. Using default configuration.', nodeImportError);
|
|
102
|
+
configData = defaultConfig;
|
|
103
|
+
}
|
|
104
|
+
return configData;
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.warn('Error loading config, using default configuration:', error);
|
|
108
|
+
configData = defaultConfig;
|
|
109
|
+
return configData;
|
|
110
|
+
}
|
|
111
|
+
})();
|
|
112
|
+
|
|
113
|
+
return configLoadPromise;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Gets the configuration object, loading it if necessary
|
|
118
|
+
* @returns {Promise<Object>} Promise that resolves to the configuration object
|
|
119
|
+
*/
|
|
120
|
+
async function getConfig() {
|
|
121
|
+
if (!configData) {
|
|
122
|
+
await loadConfig();
|
|
123
|
+
}
|
|
124
|
+
return configData;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Gets the configuration object synchronously (for backwards compatibility)
|
|
129
|
+
* If config hasn't been loaded yet, returns default config
|
|
130
|
+
* @returns {Object} The configuration object
|
|
131
|
+
*/
|
|
132
|
+
function getConfigSync() {
|
|
133
|
+
if (!configData) {
|
|
134
|
+
// Auto-initialize with defaults if not loaded
|
|
135
|
+
configData = defaultConfig;
|
|
136
|
+
}
|
|
137
|
+
return configData;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Initialize configuration loading (call this early in app lifecycle)
|
|
142
|
+
* @param {string|Object} configSource - Optional path to config file or config object
|
|
143
|
+
* @returns {Promise<void>}
|
|
144
|
+
*/
|
|
145
|
+
export async function initializeConfig(configSource = null) {
|
|
146
|
+
await loadConfig(configSource);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Set configuration directly without loading from file
|
|
151
|
+
* @param {Object} config - Configuration object
|
|
152
|
+
*/
|
|
153
|
+
export function setConfig(config) {
|
|
154
|
+
configData = { ...defaultConfig, ...config };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the default configuration
|
|
159
|
+
* @returns {Object} The default configuration object
|
|
160
|
+
*/
|
|
161
|
+
export function getDefaultConfig() {
|
|
162
|
+
return { ...defaultConfig };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Utility function to check if a specific feature is enabled
|
|
167
|
+
* @param {string} category - The configuration category (e.g., 'multiplication', 'simplification')
|
|
168
|
+
* @param {string} setting - The specific setting to check
|
|
169
|
+
* @returns {boolean} Whether the setting is enabled
|
|
170
|
+
*/
|
|
171
|
+
export function isEnabled(category, setting) {
|
|
172
|
+
const config = getConfigSync();
|
|
173
|
+
return config[category]?.[setting] ?? false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Check if implicit multiplication should be used for a specific combination
|
|
178
|
+
* @param {string} combination - The type of combination (e.g., 'constantVariable')
|
|
179
|
+
* @returns {boolean} Whether implicit multiplication should be used
|
|
180
|
+
*/
|
|
181
|
+
export function useImplicitMultiplication(combination = null) {
|
|
182
|
+
const config = getConfigSync();
|
|
183
|
+
if (combination) {
|
|
184
|
+
return config.multiplication.implicitCombinations[combination] ?? false;
|
|
185
|
+
}
|
|
186
|
+
return config.multiplication.forceImplicit;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get the configured multiplication symbol
|
|
191
|
+
* @returns {string} The multiplication symbol to use for display
|
|
192
|
+
*/
|
|
193
|
+
export function getMultiplicationSymbol() {
|
|
194
|
+
const config = getConfigSync();
|
|
195
|
+
return config.multiplication.symbol;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Update configuration settings at runtime
|
|
200
|
+
* @param {string} category - The configuration category
|
|
201
|
+
* @param {string} setting - The setting to update
|
|
202
|
+
* @param {any} value - The new value
|
|
203
|
+
*/
|
|
204
|
+
export function updateConfig(category, setting, value) {
|
|
205
|
+
const config = getConfigSync();
|
|
206
|
+
if (config[category] && config[category].hasOwnProperty(setting)) {
|
|
207
|
+
config[category][setting] = value;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get a configuration value by path
|
|
213
|
+
* @param {string} path - Dot-separated path to the config value (e.g., 'multiplication.symbol')
|
|
214
|
+
* @returns {any} The configuration value
|
|
215
|
+
*/
|
|
216
|
+
export function getConfigValue(path) {
|
|
217
|
+
const config = getConfigSync();
|
|
218
|
+
return path.split('.').reduce((obj, key) => obj?.[key], config);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Set a configuration value by path
|
|
223
|
+
* @param {string} path - Dot-separated path to the config value
|
|
224
|
+
* @param {any} value - The new value
|
|
225
|
+
*/
|
|
226
|
+
export function setConfigValue(path, value) {
|
|
227
|
+
const config = getConfigSync();
|
|
228
|
+
const keys = path.split('.');
|
|
229
|
+
const lastKey = keys.pop();
|
|
230
|
+
const target = keys.reduce((obj, key) => obj[key] = obj[key] || {}, config);
|
|
231
|
+
target[lastKey] = value;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Reset configuration to defaults
|
|
236
|
+
*/
|
|
237
|
+
export function resetConfig() {
|
|
238
|
+
throw new Error('resetConfig not available - edit omdConfig.json file directly');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Reload configuration from JSON file
|
|
243
|
+
* @returns {Promise<Object>} Promise that resolves to the reloaded configuration
|
|
244
|
+
*/
|
|
245
|
+
export async function reloadConfig() {
|
|
246
|
+
configData = null;
|
|
247
|
+
configLoadPromise = null;
|
|
248
|
+
return await loadConfig();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get the raw configuration object (async)
|
|
253
|
+
* @returns {Promise<Object>} Promise that resolves to the configuration object
|
|
254
|
+
*/
|
|
255
|
+
export async function getConfigAsync() {
|
|
256
|
+
return await getConfig();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get dot radius for a given step level (0,1,2)
|
|
261
|
+
* @param {number} level
|
|
262
|
+
* @returns {number}
|
|
263
|
+
*/
|
|
264
|
+
export function getDotRadius(level=0){
|
|
265
|
+
const cfg=getConfigSync();
|
|
266
|
+
const key=`level${level}`;
|
|
267
|
+
return cfg.stepVisualizer?.dotSizes?.[key]??6;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get font weight for a given step level (0,1,2)
|
|
272
|
+
* @param {number} level
|
|
273
|
+
* @returns {number}
|
|
274
|
+
*/
|
|
275
|
+
export function getFontWeight(level=0){
|
|
276
|
+
const cfg=getConfigSync();
|
|
277
|
+
const key=`level${level}`;
|
|
278
|
+
return cfg.stepVisualizer?.fontWeights?.[key]??400;
|
|
279
|
+
}
|