@pie-players/pie-assessment-toolkit 0.3.67 → 0.3.69
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 +81 -9
- package/dist/attempt/AssessmentSession.d.ts +7 -27
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-pe5szfyx.js +46 -0
- package/dist/components/chunks/ItemToolBar-rd7te9r0.js +51 -0
- package/dist/components/item-toolbar-element.js +1 -0
- package/dist/components/pie-assessment-toolkit-element.js +1 -0
- package/dist/components/section-toolbar-element.js +1 -0
- package/dist/context/assessment-toolkit-context.d.ts +28 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.js +4 -2
- package/dist/policy/core/compose-decision.js +14 -0
- package/dist/policy/core/decision-types.d.ts +1 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +8 -0
- package/dist/policy/sources/PnpPolicySource.js +19 -10
- package/dist/runtime/SectionRuntimeEngine.d.ts +56 -0
- package/dist/runtime/SectionRuntimeEngine.js +66 -1
- package/dist/runtime/core/engine-resolver.d.ts +25 -1
- package/dist/runtime/registration-events.d.ts +52 -0
- package/dist/runtime/registration-events.js +2 -0
- package/dist/services/AccessibilityCatalogResolver.js +21 -5
- package/dist/services/I18nService.d.ts +28 -100
- package/dist/services/I18nService.js +43 -233
- package/dist/services/TTSService.d.ts +12 -0
- package/dist/services/TTSService.js +18 -17
- package/dist/services/ToolRegistry.d.ts +120 -2
- package/dist/services/ToolRegistry.js +64 -0
- package/dist/services/ToolkitCoordinator.d.ts +39 -37
- package/dist/services/ToolkitCoordinator.js +40 -0
- package/dist/services/audio-handoff.d.ts +39 -0
- package/dist/services/audio-handoff.js +58 -0
- package/dist/services/catalog-media.d.ts +35 -4
- package/dist/services/catalog-media.js +92 -3
- package/dist/services/framework-error.d.ts +15 -1
- package/dist/services/interfaces.d.ts +28 -0
- package/dist/services/pnp-standard-features.d.ts +1 -1
- package/dist/services/section-controller-types.d.ts +218 -7
- package/dist/services/selection-action.d.ts +49 -0
- package/dist/services/selection-action.js +10 -0
- package/dist/services/spoken-audio-cards.js +5 -1
- package/dist/services/tool-context.d.ts +6 -5
- package/dist/services/tool-context.js +205 -155
- package/dist/services/tool-icons.d.ts +18 -0
- package/dist/services/tool-icons.js +31 -0
- package/dist/services/tool-providers/CortexToolProvider.d.ts +18 -0
- package/dist/services/tool-providers/CortexToolProvider.js +32 -0
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +13 -101
- package/dist/services/tool-providers/DesmosToolProvider.js +14 -145
- package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +21 -0
- package/dist/services/tool-providers/GeoGebraToolProvider.js +32 -0
- package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +35 -0
- package/dist/services/tool-providers/LazyCalculatorToolProvider.js +95 -0
- package/dist/services/tool-providers/index.d.ts +4 -0
- package/dist/services/tool-providers/index.js +2 -0
- package/dist/services/tool-request.d.ts +106 -0
- package/dist/services/tool-request.js +127 -0
- package/dist/services/toolbar-items.d.ts +6 -0
- package/dist/tools/client.d.ts +0 -2
- package/dist/tools/client.js +0 -4
- package/dist/tools/internal.d.ts +7 -1
- package/dist/tools/internal.js +8 -1
- package/dist/tools/tool-surface-host.d.ts +57 -0
- package/dist/tools/tool-surface-host.js +610 -0
- package/dist/tools/types.d.ts +1 -66
- package/package.json +22 -12
- package/dist/components/chunks/ItemToolBar-8jgdz50p.js +0 -51
- package/dist/components/chunks/ItemToolBar-cvs646j3.js +0 -36
- package/dist/tools/calculators/desmos-provider.d.ts +0 -46
- package/dist/tools/calculators/desmos-provider.js +0 -393
- package/dist/tools/library-loader.d.ts +0 -62
- package/dist/tools/library-loader.js +0 -261
|
@@ -40,185 +40,226 @@ export function isRubricContext(context) {
|
|
|
40
40
|
export function isElementContext(context) {
|
|
41
41
|
return context.level === "element";
|
|
42
42
|
}
|
|
43
|
+
const stripHtml = (value) => value.replace(/<[^>]*>/g, " ").trim();
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
+
* A config's `models` as a list, whether it was authored as an array or as a
|
|
46
|
+
* record keyed by element id. Both forms are in the wild.
|
|
45
47
|
*/
|
|
46
|
-
|
|
48
|
+
function normalizeModels(modelsRaw) {
|
|
49
|
+
if (Array.isArray(modelsRaw))
|
|
50
|
+
return modelsRaw;
|
|
51
|
+
if (modelsRaw && typeof modelsRaw === "object") {
|
|
52
|
+
return Object.values(modelsRaw);
|
|
53
|
+
}
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Push every string a model carries, one level into its arrays of objects.
|
|
58
|
+
*
|
|
59
|
+
* The depth is deliberate rather than a full walk: math and prose live in a
|
|
60
|
+
* model's own fields (`prompt`, `label`) and in its choice/row arrays, which is
|
|
61
|
+
* one level down. Recursing further would pull in ids, keys and config flags.
|
|
62
|
+
*/
|
|
63
|
+
function collectModelText(model, push) {
|
|
64
|
+
if (!model || typeof model !== "object")
|
|
65
|
+
return;
|
|
66
|
+
for (const value of Object.values(model)) {
|
|
67
|
+
if (typeof value === "string")
|
|
68
|
+
push(value);
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
for (const entry of value) {
|
|
71
|
+
if (entry && typeof entry === "object") {
|
|
72
|
+
for (const nested of Object.values(entry)) {
|
|
73
|
+
if (typeof nested === "string")
|
|
74
|
+
push(nested);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Push the markup of every element snippet in a config's `elements` map. */
|
|
82
|
+
function collectElementsText(elements, push) {
|
|
83
|
+
if (!elements || typeof elements !== "object")
|
|
84
|
+
return;
|
|
85
|
+
for (const elementMarkup of Object.values(elements)) {
|
|
86
|
+
if (typeof elementMarkup === "string")
|
|
87
|
+
push(elementMarkup);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The authored content a context carries, for the content heuristics below.
|
|
92
|
+
*
|
|
93
|
+
* Each level differs only in which fields it reads: an element reads its own
|
|
94
|
+
* markup snippet and the one model bearing its id, an item and a passage read
|
|
95
|
+
* their whole config and every model. The traversal itself is shared, so a new
|
|
96
|
+
* place content can hide is added once.
|
|
97
|
+
*
|
|
98
|
+
* `transform` decides what the caller gets. {@link extractTextContent} strips
|
|
99
|
+
* tags, which is right for prose keyword matching and wrong for structural
|
|
100
|
+
* matching: a MathML item's only math signal *is* the `<math>` tag, and stripping
|
|
101
|
+
* first left `hasMathContent`'s MathML pattern unreachable.
|
|
102
|
+
*/
|
|
103
|
+
function extractContent(context, transform) {
|
|
104
|
+
const textChunks = [];
|
|
105
|
+
const push = (text) => {
|
|
106
|
+
textChunks.push(transform(text));
|
|
107
|
+
};
|
|
108
|
+
const joined = () => textChunks.filter(Boolean).join(" ").trim();
|
|
47
109
|
if (isElementContext(context)) {
|
|
48
110
|
const config = context.item.config;
|
|
49
111
|
if (!config)
|
|
50
112
|
return "";
|
|
51
|
-
const textChunks = [];
|
|
52
|
-
const stripHtml = (value) => value.replace(/<[^>]*>/g, " ").trim();
|
|
53
|
-
// Try to find element markup by element id.
|
|
54
113
|
const elementMarkup = config.elements?.[context.elementId];
|
|
55
|
-
if (elementMarkup)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
? modelsRaw
|
|
65
|
-
: modelsRaw && typeof modelsRaw === "object"
|
|
66
|
-
? Object.values(modelsRaw)
|
|
67
|
-
: [];
|
|
68
|
-
const model = models.find((m) => m && typeof m === "object" && m.id === context.elementId);
|
|
69
|
-
if (model) {
|
|
70
|
-
for (const value of Object.values(model)) {
|
|
71
|
-
if (typeof value === "string") {
|
|
72
|
-
textChunks.push(stripHtml(value));
|
|
73
|
-
}
|
|
74
|
-
if (Array.isArray(value)) {
|
|
75
|
-
for (const entry of value) {
|
|
76
|
-
if (entry && typeof entry === "object") {
|
|
77
|
-
for (const nested of Object.values(entry)) {
|
|
78
|
-
if (typeof nested === "string") {
|
|
79
|
-
textChunks.push(stripHtml(nested));
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return textChunks.filter(Boolean).join(" ").trim();
|
|
114
|
+
if (typeof elementMarkup === "string")
|
|
115
|
+
push(elementMarkup);
|
|
116
|
+
// Model data keyed by this element id: in many items the math is in
|
|
117
|
+
// `model.prompt`/labels rather than in `elements[elementId]`.
|
|
118
|
+
const model = normalizeModels(config.models).find((candidate) => !!candidate &&
|
|
119
|
+
typeof candidate === "object" &&
|
|
120
|
+
candidate.id === context.elementId);
|
|
121
|
+
collectModelText(model, push);
|
|
122
|
+
return joined();
|
|
88
123
|
}
|
|
89
124
|
if (isItemContext(context)) {
|
|
90
|
-
const
|
|
91
|
-
if (!
|
|
125
|
+
const config = context.item?.config;
|
|
126
|
+
if (!config)
|
|
92
127
|
return "";
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
textChunks.push(stripHtml(config.markup));
|
|
128
|
+
if (typeof config.markup === "string")
|
|
129
|
+
push(config.markup);
|
|
130
|
+
collectElementsText(config.elements, push);
|
|
131
|
+
for (const model of normalizeModels(config.models)) {
|
|
132
|
+
collectModelText(model, push);
|
|
99
133
|
}
|
|
100
|
-
|
|
101
|
-
const elements = config.elements;
|
|
102
|
-
if (elements && typeof elements === "object") {
|
|
103
|
-
for (const elementMarkup of Object.values(elements)) {
|
|
104
|
-
if (typeof elementMarkup === "string") {
|
|
105
|
-
textChunks.push(stripHtml(elementMarkup));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
// Model-level text (prompts, labels, etc.)
|
|
110
|
-
const modelsRaw = config.models;
|
|
111
|
-
const models = Array.isArray(modelsRaw)
|
|
112
|
-
? modelsRaw
|
|
113
|
-
: modelsRaw && typeof modelsRaw === "object"
|
|
114
|
-
? Object.values(modelsRaw)
|
|
115
|
-
: [];
|
|
116
|
-
for (const model of models) {
|
|
117
|
-
if (!model || typeof model !== "object")
|
|
118
|
-
continue;
|
|
119
|
-
for (const value of Object.values(model)) {
|
|
120
|
-
if (typeof value === "string") {
|
|
121
|
-
textChunks.push(stripHtml(value));
|
|
122
|
-
}
|
|
123
|
-
if (Array.isArray(value)) {
|
|
124
|
-
for (const entry of value) {
|
|
125
|
-
if (entry && typeof entry === "object") {
|
|
126
|
-
for (const nested of Object.values(entry)) {
|
|
127
|
-
if (typeof nested === "string") {
|
|
128
|
-
textChunks.push(stripHtml(nested));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return textChunks.filter(Boolean).join(" ").trim();
|
|
134
|
+
return joined();
|
|
137
135
|
}
|
|
138
136
|
if (isPassageContext(context)) {
|
|
139
|
-
const
|
|
140
|
-
if (!
|
|
137
|
+
const config = context.passage?.config;
|
|
138
|
+
if (!config)
|
|
141
139
|
return "";
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (typeof config.markup === "string") {
|
|
147
|
-
textChunks.push(stripHtml(config.markup));
|
|
148
|
-
}
|
|
149
|
-
if (typeof config.content === "string") {
|
|
150
|
-
textChunks.push(stripHtml(config.content));
|
|
151
|
-
}
|
|
152
|
-
if (typeof config.prompt === "string") {
|
|
153
|
-
textChunks.push(stripHtml(config.prompt));
|
|
154
|
-
}
|
|
155
|
-
// Element markup snippets
|
|
156
|
-
const elements = config.elements;
|
|
157
|
-
if (elements && typeof elements === "object") {
|
|
158
|
-
for (const elementMarkup of Object.values(elements)) {
|
|
159
|
-
if (typeof elementMarkup === "string") {
|
|
160
|
-
textChunks.push(stripHtml(elementMarkup));
|
|
161
|
-
}
|
|
162
|
-
}
|
|
140
|
+
for (const field of ["markup", "content", "prompt"]) {
|
|
141
|
+
const value = config[field];
|
|
142
|
+
if (typeof value === "string")
|
|
143
|
+
push(value);
|
|
163
144
|
}
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
? modelsRaw
|
|
168
|
-
: modelsRaw && typeof modelsRaw === "object"
|
|
169
|
-
? Object.values(modelsRaw)
|
|
170
|
-
: [];
|
|
171
|
-
for (const model of models) {
|
|
172
|
-
if (!model || typeof model !== "object")
|
|
173
|
-
continue;
|
|
174
|
-
for (const value of Object.values(model)) {
|
|
175
|
-
if (typeof value === "string") {
|
|
176
|
-
textChunks.push(stripHtml(value));
|
|
177
|
-
}
|
|
178
|
-
if (Array.isArray(value)) {
|
|
179
|
-
for (const entry of value) {
|
|
180
|
-
if (entry && typeof entry === "object") {
|
|
181
|
-
for (const nested of Object.values(entry)) {
|
|
182
|
-
if (typeof nested === "string") {
|
|
183
|
-
textChunks.push(stripHtml(nested));
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
145
|
+
collectElementsText(config.elements, push);
|
|
146
|
+
for (const model of normalizeModels(config.models)) {
|
|
147
|
+
collectModelText(model, push);
|
|
190
148
|
}
|
|
191
|
-
return
|
|
149
|
+
return joined();
|
|
192
150
|
}
|
|
193
151
|
if (isRubricContext(context)) {
|
|
152
|
+
// No model walk: a rubric block is authored prose, so its text is one
|
|
153
|
+
// string — the embedded passage's markup when it has one, else its content.
|
|
194
154
|
const rubric = context.rubricBlock;
|
|
195
|
-
// If rubric has embedded passage, extract from passage config
|
|
196
155
|
if (rubric.passage?.config) {
|
|
197
|
-
|
|
198
|
-
return markup.replace(/<[^>]*>/g, " ").trim();
|
|
156
|
+
return transform(rubric.passage.config.markup || "");
|
|
199
157
|
}
|
|
200
|
-
|
|
201
|
-
const content = rubric.content || "";
|
|
202
|
-
return content.replace(/<[^>]*>/g, " ").trim();
|
|
158
|
+
return transform(rubric.content || "");
|
|
203
159
|
}
|
|
204
160
|
return "";
|
|
205
161
|
}
|
|
162
|
+
/** The plain text a context carries, tags removed. */
|
|
163
|
+
export function extractTextContent(context) {
|
|
164
|
+
return extractContent(context, stripHtml);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The authored markup a context carries, tags intact.
|
|
168
|
+
*
|
|
169
|
+
* For indicators that live in the markup rather than in the prose — `<math>`
|
|
170
|
+
* above all, whose whole signal is the element name.
|
|
171
|
+
*/
|
|
172
|
+
export function extractMarkupContent(context) {
|
|
173
|
+
return extractContent(context, (value) => value);
|
|
174
|
+
}
|
|
206
175
|
/**
|
|
207
176
|
* Helper to check if context contains mathematical content
|
|
208
177
|
* (Basic heuristic - can be overridden by tools)
|
|
209
178
|
*/
|
|
179
|
+
/**
|
|
180
|
+
* Chemical element symbols.
|
|
181
|
+
*
|
|
182
|
+
* A real set rather than `[A-Z][a-z]?`: that shape matches "It", "In", "He" and
|
|
183
|
+
* "A", which is why the science gate used to answer `true` for any prose that
|
|
184
|
+
* began a sentence.
|
|
185
|
+
*/
|
|
186
|
+
const ELEMENT_SYMBOLS = new Set([
|
|
187
|
+
"H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si",
|
|
188
|
+
"P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co",
|
|
189
|
+
"Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr",
|
|
190
|
+
"Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I",
|
|
191
|
+
"Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy",
|
|
192
|
+
"Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au",
|
|
193
|
+
"Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U",
|
|
194
|
+
"Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
|
|
195
|
+
]);
|
|
196
|
+
/** A word that could be a formula: capitalised groups with optional counts. */
|
|
197
|
+
const FORMULA_CANDIDATE = /\b[A-Z][A-Za-z]*\d*(?:[A-Z][A-Za-z]*\d*)*\b/g;
|
|
198
|
+
const FORMULA_GROUP = /([A-Z][a-z]?)(\d*)/g;
|
|
199
|
+
/**
|
|
200
|
+
* Whether the text contains something only a chemical formula looks like.
|
|
201
|
+
*
|
|
202
|
+
* A token qualifies when every one of its groups is a real element symbol *and*
|
|
203
|
+
* it either names two or more of them or carries a count — `NaCl`, `CO2`, `H2O`,
|
|
204
|
+
* `C6H12O6`. A lone symbol never qualifies: "In", "He", "As" and "At" are
|
|
205
|
+
* ordinary English words, and a single-letter "I" or "A" more so.
|
|
206
|
+
*/
|
|
207
|
+
function hasChemicalFormula(text) {
|
|
208
|
+
for (const candidate of text.match(FORMULA_CANDIDATE) ?? []) {
|
|
209
|
+
FORMULA_GROUP.lastIndex = 0;
|
|
210
|
+
let groups = 0;
|
|
211
|
+
let hasCount = false;
|
|
212
|
+
let consumed = 0;
|
|
213
|
+
let valid = true;
|
|
214
|
+
let match = FORMULA_GROUP.exec(candidate);
|
|
215
|
+
while (match !== null) {
|
|
216
|
+
if (match[0] === "")
|
|
217
|
+
break;
|
|
218
|
+
if (!ELEMENT_SYMBOLS.has(match[1])) {
|
|
219
|
+
valid = false;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
groups += 1;
|
|
223
|
+
if (match[2])
|
|
224
|
+
hasCount = true;
|
|
225
|
+
consumed += match[0].length;
|
|
226
|
+
match = FORMULA_GROUP.exec(candidate);
|
|
227
|
+
}
|
|
228
|
+
// Every character has to belong to a group, or the token was only
|
|
229
|
+
// formula-shaped at its start ("Hello" -> "He" + "llo").
|
|
230
|
+
if (valid && consumed === candidate.length && (groups > 1 || hasCount)) {
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
210
236
|
export function hasMathContent(context) {
|
|
211
|
-
|
|
212
|
-
//
|
|
213
|
-
const
|
|
237
|
+
// Structural signals live in the markup: stripping tags first is what left the
|
|
238
|
+
// MathML pattern unable to match anything at all.
|
|
239
|
+
const markup = extractMarkupContent(context);
|
|
240
|
+
const structuralIndicators = [
|
|
214
241
|
/<math[>\s]/i, // MathML
|
|
215
242
|
/\\\[([^\]]+)\\\]/, // LaTeX display math
|
|
216
243
|
/\$\$[^$]+\$\$/, // LaTeX display math ($$...$$)
|
|
217
244
|
/\\\(/, // LaTeX inline math
|
|
218
|
-
/[+\-*/=<>≤≥∑∫√π]/, // Math symbols
|
|
219
|
-
/\d+\s*[+\-*/=]\s*\d+/, // Simple arithmetic
|
|
220
245
|
];
|
|
221
|
-
|
|
246
|
+
if (structuralIndicators.some((pattern) => pattern.test(markup)))
|
|
247
|
+
return true;
|
|
248
|
+
const text = extractTextContent(context);
|
|
249
|
+
// No bare-operator pattern. `/[+\-*/=<>≤≥∑∫√π]/` matched any hyphen or slash,
|
|
250
|
+
// so "well-known" and "and/or" made every item mathematical and this predicate
|
|
251
|
+
// answered `true` for essentially all content — a gate that does not gate. An
|
|
252
|
+
// operator counts only with operands around it, or when the character has no
|
|
253
|
+
// prose reading at all.
|
|
254
|
+
const textIndicators = [
|
|
255
|
+
/[≤≥≠±×÷∑∫√∞π]/, // Symbols with no prose reading
|
|
256
|
+
/\d+\s*[+\-*/×÷=]\s*\d+/, // Simple arithmetic
|
|
257
|
+
/\d\s*[<>]\s*\d/, // Numeric comparison
|
|
258
|
+
/\b\d+\s*\/\s*\d+\b/, // Fractions
|
|
259
|
+
/\b\d+(?:\.\d+)?\s*%/, // Percentages
|
|
260
|
+
/\^\s*\d/, // Exponents
|
|
261
|
+
];
|
|
262
|
+
return textIndicators.some((pattern) => pattern.test(text));
|
|
222
263
|
}
|
|
223
264
|
/**
|
|
224
265
|
* Helper to check if context contains choice-based interactions
|
|
@@ -259,9 +300,14 @@ export function hasChoiceInteraction(context) {
|
|
|
259
300
|
if (!m || typeof m !== "object")
|
|
260
301
|
return false;
|
|
261
302
|
const type = m.element || "";
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
//
|
|
303
|
+
// A model that names its element has answered the question, whichever way
|
|
304
|
+
// the answer falls. `choices` is carried by interactions that are not
|
|
305
|
+
// choice interactions at all — `placement-ordering`, `categorize` and
|
|
306
|
+
// `drag-in-the-blank` each hold their draggables there — so reading it on
|
|
307
|
+
// a named model showed the answer eliminator on items where the tool does
|
|
308
|
+
// nothing. The heuristic remains for configs that name no element.
|
|
309
|
+
if (type)
|
|
310
|
+
return interactionTypes.includes(type);
|
|
265
311
|
return Array.isArray(m.choices) && m.choices.length > 0;
|
|
266
312
|
});
|
|
267
313
|
}
|
|
@@ -281,14 +327,18 @@ export function hasReadableText(context) {
|
|
|
281
327
|
*/
|
|
282
328
|
export function hasScienceContent(context) {
|
|
283
329
|
const text = extractTextContent(context);
|
|
284
|
-
//
|
|
330
|
+
// The element-symbol pattern used to be `/\b[A-Z][a-z]?\d*\b/`, which matches
|
|
331
|
+
// any one- or two-letter capitalised word: "It", "In", "A", "No". Every item
|
|
332
|
+
// beginning a sentence with one read as science.
|
|
333
|
+
if (hasChemicalFormula(text))
|
|
334
|
+
return true;
|
|
335
|
+
if (/[A-Z][a-z]?[\u2080-\u2089]/.test(text))
|
|
336
|
+
return true; // Subscripted: H₂O, CO₂
|
|
285
337
|
const scienceIndicators = [
|
|
286
|
-
/chemistry|chemical|
|
|
287
|
-
|
|
288
|
-
/
|
|
289
|
-
|
|
290
|
-
/biology|organism|cell|DNA|RNA|protein/i,
|
|
291
|
-
/physics|force|energy|velocity|acceleration/i,
|
|
338
|
+
/chemistry|chemical|molecule|compound|periodic\s+table/i,
|
|
339
|
+
/\bchemical\s+element\b|\belement\s+symbol\b/i,
|
|
340
|
+
/biology|organism|\bDNA\b|\bRNA\b|protein|photosynthesis|ecosystem/i,
|
|
341
|
+
/physics|\bforce\b|\benergy\b|velocity|acceleration|momentum/i,
|
|
292
342
|
];
|
|
293
343
|
return scienceIndicators.some((pattern) => pattern.test(text));
|
|
294
344
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in icon markup for toolbar buttons, keyed by the names registrations use.
|
|
3
|
+
*
|
|
4
|
+
* A registration names an icon rather than shipping markup, so a host swapping the
|
|
5
|
+
* button chrome gets one consistent set. A name with no entry here renders no icon
|
|
6
|
+
* at all, and an icon-only button with no icon is a blank square — so a registration
|
|
7
|
+
* naming an icon and this map are one change, not two.
|
|
8
|
+
*
|
|
9
|
+
* Names are generic shapes ("book-open", "beaker"), never capability names. Core
|
|
10
|
+
* naming a capability is what the composition layer exists to prevent.
|
|
11
|
+
*
|
|
12
|
+
* Exported through `tools/internal` as well: a registration composing a selection
|
|
13
|
+
* gateway renders its own buttons and has to draw the same icon the toolbar button
|
|
14
|
+
* draws, or the learner sees two unrelated affordances for one tool.
|
|
15
|
+
*/
|
|
16
|
+
export declare const TOOL_FALLBACK_ICONS: Readonly<Record<string, string>>;
|
|
17
|
+
/** Icon markup for `name`, or `null` when nothing built in matches. */
|
|
18
|
+
export declare function resolveFallbackToolIcon(name: string): string | null;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in icon markup for toolbar buttons, keyed by the names registrations use.
|
|
3
|
+
*
|
|
4
|
+
* A registration names an icon rather than shipping markup, so a host swapping the
|
|
5
|
+
* button chrome gets one consistent set. A name with no entry here renders no icon
|
|
6
|
+
* at all, and an icon-only button with no icon is a blank square — so a registration
|
|
7
|
+
* naming an icon and this map are one change, not two.
|
|
8
|
+
*
|
|
9
|
+
* Names are generic shapes ("book-open", "beaker"), never capability names. Core
|
|
10
|
+
* naming a capability is what the composition layer exists to prevent.
|
|
11
|
+
*
|
|
12
|
+
* Exported through `tools/internal` as well: a registration composing a selection
|
|
13
|
+
* gateway renders its own buttons and has to draw the same icon the toolbar button
|
|
14
|
+
* draws, or the learner sees two unrelated affordances for one tool.
|
|
15
|
+
*/
|
|
16
|
+
export const TOOL_FALLBACK_ICONS = {
|
|
17
|
+
calculator: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 2h10a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm0 2v4h10V4H7Zm0 6v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Zm-8 4v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Zm-8 4v2h2v-2H7Zm4 0v2h2v-2h-2Zm4 0v2h2v-2h-2Z" fill="currentColor"/></svg>',
|
|
18
|
+
"volume-up": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 3.23v2.06A7.002 7.002 0 0 1 19 12a7 7 0 0 1-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77Zm-2 17.75V3L7 8H3v8h4l5 5Zm4.5-9a4.5 4.5 0 0 0-2.5-4.03v8.05A4.5 4.5 0 0 0 16.5 12Z" fill="currentColor"/></svg>',
|
|
19
|
+
swatch: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 3a9 9 0 1 0 9 9c0-.55-.45-1-1-1h-2.5a1.5 1.5 0 0 1 0-3H20a1 1 0 0 0 1-1 8.99 8.99 0 0 0-9-4Zm-5.5 9A1.5 1.5 0 1 1 8 13.5 1.5 1.5 0 0 1 6.5 12Zm3-4A1.5 1.5 0 1 1 11 9.5 1.5 1.5 0 0 1 9.5 8Zm5 0A1.5 1.5 0 1 1 16 9.5 1.5 1.5 0 0 1 14.5 8Z" fill="currentColor"/></svg>',
|
|
20
|
+
"chart-bar": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4.75 5a.76.76 0 0 1 .75.75v11c0 .438.313.75.75.75h13a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-13C5 19 4 18 4 16.75v-11A.74.74 0 0 1 4.75 5ZM8 8.25a.74.74 0 0 1 .75-.75h6.5a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-6.5A.722.722 0 0 1 8 8.25Zm.75 2.25h4.5a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-4.5a.723.723 0 0 1-.75-.75.74.74 0 0 1 .75-.75Zm0 3h8.5a.76.76 0 0 1 .696 1.039.74.74 0 0 1-.696.461h-8.5a.723.723 0 0 1-.75-.75.74.74 0 0 1 .75-.75Z" fill="currentColor"/></svg>',
|
|
21
|
+
beaker: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 21c-.85 0-1.454-.38-1.813-1.137-.358-.759-.27-1.463.263-2.113L9 11V5H8a.968.968 0 0 1-.713-.287A.968.968 0 0 1 7 4c0-.283.096-.52.287-.712A.968.968 0 0 1 8 3h8c.283 0 .52.096.712.288.192.191.288.429.288.712s-.096.52-.288.713A.968.968 0 0 1 16 5h-1v6l5.55 6.75c.533.65.62 1.354.262 2.113C20.454 20.62 19.85 21 19 21H5Zm2-3h10l-3.4-4h-3.2L7 18Zm-2 1h14l-6-7.3V5h-2v6.7L5 19Z" fill="currentColor"/></svg>',
|
|
22
|
+
protractor: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m6.75 21-.25-2.2 2.85-7.85a3.95 3.95 0 0 0 1.75.95l-2.75 7.55L6.75 21Zm10.5 0-1.6-1.55-2.75-7.55a3.948 3.948 0 0 0 1.75-.95l2.85 7.85-.25 2.2ZM12 11a2.893 2.893 0 0 1-2.125-.875A2.893 2.893 0 0 1 9 8c0-.65.188-1.23.563-1.737A2.935 2.935 0 0 1 11 5.2V3h2v2.2c.583.2 1.063.554 1.438 1.063C14.812 6.77 15 7.35 15 8c0 .833-.292 1.542-.875 2.125A2.893 2.893 0 0 1 12 11Zm0-2c.283 0 .52-.096.713-.287A.967.967 0 0 0 13 8a.967.967 0 0 0-.287-.713A.968.968 0 0 0 12 7a.968.968 0 0 0-.713.287A.967.967 0 0 0 11 8c0 .283.096.52.287.713.192.191.43.287.713.287Z" fill="currentColor"/></svg>',
|
|
23
|
+
"bars-3": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.85 15c.517 0 .98-.15 1.388-.45.408-.3.695-.692.862-1.175l.375-1.15c.267-.8.2-1.537-.2-2.213C8.875 9.337 8.3 9 7.55 9H4.025l.475 3.925c.083.583.346 1.075.787 1.475.442.4.963.6 1.563.6Zm10.3 0c.6 0 1.12-.2 1.563-.6.441-.4.704-.892.787-1.475L19.975 9h-3.5c-.75 0-1.325.342-1.725 1.025-.4.683-.467 1.425-.2 2.225l.35 1.125c.167.483.454.875.862 1.175.409.3.871.45 1.388.45Zm-10.3 2c-1.1 0-2.063-.363-2.887-1.088a4.198 4.198 0 0 1-1.438-2.737L2 9H1V7h6.55c.733 0 1.404.18 2.013.537A3.906 3.906 0 0 1 11 9h2.025c.35-.617.83-1.104 1.438-1.463A3.892 3.892 0 0 1 16.474 7H23v2h-1l-.525 4.175a4.198 4.198 0 0 1-1.438 2.737A4.238 4.238 0 0 1 17.15 17c-.95 0-1.804-.27-2.562-.813A4.234 4.234 0 0 1 13 14.026l-.375-1.125a21.35 21.35 0 0 1-.1-.363 4.926 4.926 0 0 1-.1-.537h-.85c-.033.2-.067.363-.1.488a21.35 21.35 0 0 1-.1.362L11 14a4.3 4.3 0 0 1-1.588 2.175A4.258 4.258 0 0 1 6.85 17Z" fill="currentColor"/></svg>',
|
|
24
|
+
ruler: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m8.8 10.95 2.15-2.175-1.4-1.425-1.1 1.1-1.4-1.4 1.075-1.1L7 4.825 4.825 7 8.8 10.95Zm8.2 8.225L19.175 17l-1.125-1.125-1.1 1.075-1.4-1.4 1.075-1.1-1.425-1.4-2.15 2.15L17 19.175ZM7.25 21H3v-4.25l4.375-4.375L2 7l5-5 5.4 5.4 3.775-3.8c.2-.2.425-.35.675-.45a2.068 2.068 0 0 1 1.55 0c.25.1.475.25.675.45L20.4 4.95c.2.2.35.425.45.675.1.25.15.508.15.775a1.975 1.975 0 0 1-.6 1.425l-3.775 3.8L22 17l-5 5-5.375-5.375L7.25 21ZM5 19h1.4l9.8-9.775L14.775 7.8 5 17.6V19Z" fill="currentColor"/></svg>',
|
|
25
|
+
"book-open": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 6.25a6.6 6.6 0 0 0-2.3-1.32A8.6 8.6 0 0 0 7 4.5c-.63 0-1.25.06-1.85.18-.6.12-1.19.3-1.76.54a1.5 1.5 0 0 0-.93 1.4v10.1c0 .52.26.98.68 1.24.42.26.92.28 1.35.06.36-.18.75-.31 1.18-.4.42-.09.86-.13 1.33-.13.78 0 1.53.14 2.24.42.7.28 1.35.7 1.93 1.24l.83-.75.83.75c.58-.54 1.22-.96 1.93-1.24a6.1 6.1 0 0 1 2.24-.42c.47 0 .91.04 1.33.13.43.09.82.22 1.18.4.43.22.93.2 1.35-.06.42-.26.68-.72.68-1.24V6.62c0-.6-.36-1.15-.93-1.4a9.3 9.3 0 0 0-1.76-.54A9.8 9.8 0 0 0 17 4.5a8.6 8.6 0 0 0-2.7.43A6.6 6.6 0 0 0 12 6.25Zm1 10.06V8.02c.55-.5 1.16-.88 1.84-1.13A6 6 0 0 1 17 6.5c.45 0 .89.04 1.32.11.43.08.85.19 1.26.34v9.24a8.2 8.2 0 0 0-1.28-.24A10 10 0 0 0 17 15.85c-.72 0-1.42.09-2.09.26a7.7 7.7 0 0 0-1.91.8Zm-2 0a7.7 7.7 0 0 0-1.91-.8 8.4 8.4 0 0 0-2.09-.26c-.44 0-.87.02-1.3.07-.43.05-.86.13-1.28.24V6.95c.41-.15.83-.26 1.26-.34A7.7 7.7 0 0 1 7 6.5c.76 0 1.48.13 2.16.39.68.25 1.29.63 1.84 1.13Z" fill="currentColor"/></svg>',
|
|
26
|
+
photo: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 21c-.55 0-1.02-.2-1.41-.59A1.93 1.93 0 0 1 2 19V5c0-.55.2-1.02.59-1.41A1.93 1.93 0 0 1 4 3h16c.55 0 1.02.2 1.41.59.39.39.59.86.59 1.41v14c0 .55-.2 1.02-.59 1.41-.39.39-.86.59-1.41.59H4Zm0-2h16V5H4v14Zm1.5-2.5h13l-4.1-5.47-3.4 4.47-2.5-3.25L5.5 16.5ZM8.5 10a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" fill="currentColor"/></svg>',
|
|
27
|
+
};
|
|
28
|
+
/** Icon markup for `name`, or `null` when nothing built in matches. */
|
|
29
|
+
export function resolveFallbackToolIcon(name) {
|
|
30
|
+
return TOOL_FALLBACK_ICONS[name] || null;
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Fully bundled open-source calculator adapter for the tool-provider registry. */
|
|
2
|
+
import type { CalculatorToolProviderInitConfig } from "./LazyCalculatorToolProvider.js";
|
|
3
|
+
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
4
|
+
import type { ToolProviderCapabilities } from "./ToolProviderApi.js";
|
|
5
|
+
export type CortexToolProviderConfig = CalculatorToolProviderInitConfig;
|
|
6
|
+
export declare class CortexToolProvider extends LazyCalculatorToolProvider<CortexToolProviderConfig> {
|
|
7
|
+
readonly providerId = "cortex-calculator";
|
|
8
|
+
readonly providerName = "PIE Open-Source Calculator";
|
|
9
|
+
readonly version = "1";
|
|
10
|
+
readonly requiresAuth = false;
|
|
11
|
+
protected getDefinition(): {
|
|
12
|
+
backend: string;
|
|
13
|
+
moduleImportOperation: string;
|
|
14
|
+
loadProvider: () => Promise<typeof import("@pie-players/pie-calculator-cortex").CortexCalculatorProvider>;
|
|
15
|
+
initializationErrorMessage: string;
|
|
16
|
+
};
|
|
17
|
+
getCapabilities(): ToolProviderCapabilities;
|
|
18
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Fully bundled open-source calculator adapter for the tool-provider registry. */
|
|
2
|
+
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
3
|
+
export class CortexToolProvider extends LazyCalculatorToolProvider {
|
|
4
|
+
providerId = "cortex-calculator";
|
|
5
|
+
providerName = "PIE Open-Source Calculator";
|
|
6
|
+
version = "1";
|
|
7
|
+
requiresAuth = false;
|
|
8
|
+
getDefinition() {
|
|
9
|
+
return {
|
|
10
|
+
backend: "cortex",
|
|
11
|
+
moduleImportOperation: "cortex-provider-module-import",
|
|
12
|
+
loadProvider: async () => {
|
|
13
|
+
const module = await import("@pie-players/pie-calculator-cortex");
|
|
14
|
+
return module.CortexCalculatorProvider;
|
|
15
|
+
},
|
|
16
|
+
initializationErrorMessage: "Failed to initialize the PIE open-source calculator provider. Confirm that this browser supports module workers and that the bundled worker assets are available.",
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
getCapabilities() {
|
|
20
|
+
return {
|
|
21
|
+
supportsOffline: true,
|
|
22
|
+
requiresAuth: false,
|
|
23
|
+
maxInstances: null,
|
|
24
|
+
features: {
|
|
25
|
+
basic: true,
|
|
26
|
+
scientific: true,
|
|
27
|
+
graphing: true,
|
|
28
|
+
fourFunction: true,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -1,107 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* - Development: Pass apiKey directly for local testing
|
|
9
|
-
* - Production: Use proxyEndpoint or authFetcher to keep API key server-side
|
|
10
|
-
*
|
|
11
|
-
* Part of PIE Assessment Toolkit.
|
|
12
|
-
*/
|
|
13
|
-
import type { CalculatorProvider, DesmosCalculatorConfig } from "@pie-players/pie-calculator";
|
|
14
|
-
import type { ToolProviderApi, ToolProviderCapabilities } from "./ToolProviderApi.js";
|
|
15
|
-
/**
|
|
16
|
-
* Desmos tool provider configuration
|
|
17
|
-
*/
|
|
18
|
-
export interface DesmosToolProviderConfig {
|
|
19
|
-
/**
|
|
20
|
-
* Desmos API key (DEVELOPMENT ONLY)
|
|
21
|
-
* Never expose in production client code!
|
|
22
|
-
*
|
|
23
|
-
* Obtain from: https://www.desmos.com/api
|
|
24
|
-
*/
|
|
25
|
-
apiKey?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Server proxy endpoint (PRODUCTION RECOMMENDED)
|
|
28
|
-
* Backend handles API key securely
|
|
29
|
-
*
|
|
30
|
-
* @example '/api/desmos/token'
|
|
31
|
-
* @example 'https://api.myapp.com/tools/desmos/auth'
|
|
32
|
-
*/
|
|
33
|
-
proxyEndpoint?: string;
|
|
34
|
-
/**
|
|
35
|
-
* Default calculator configuration applied to all instances
|
|
36
|
-
*/
|
|
37
|
-
defaultConfig?: DesmosCalculatorConfig;
|
|
38
|
-
/**
|
|
39
|
-
* Optional telemetry callback for tool/backend instrumentation.
|
|
40
|
-
*/
|
|
41
|
-
onTelemetry?: (eventName: string, payload?: Record<string, unknown>) => void | Promise<void>;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Desmos Calculator Tool Provider
|
|
45
|
-
*
|
|
46
|
-
* Wraps DesmosCalculatorProvider with the ToolProviderApi interface
|
|
47
|
-
* for use in the ToolProviderRegistry.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```typescript
|
|
51
|
-
* const provider = new DesmosToolProvider();
|
|
52
|
-
*
|
|
53
|
-
* await provider.initialize({
|
|
54
|
-
* apiKey: 'your-api-key', // Development only
|
|
55
|
-
* proxyEndpoint: '/api/desmos/token', // Production
|
|
56
|
-
* });
|
|
57
|
-
*
|
|
58
|
-
* const calculatorProvider = await provider.createInstance();
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
export declare class DesmosToolProvider implements ToolProviderApi<DesmosToolProviderConfig, CalculatorProvider> {
|
|
1
|
+
/** Desmos calculator adapter for the generic tool-provider registry. */
|
|
2
|
+
import type { CalculatorProviderInit } from "@pie-players/pie-calculator";
|
|
3
|
+
import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
|
|
4
|
+
import type { ToolProviderCapabilities } from "./ToolProviderApi.js";
|
|
5
|
+
/** Provider initialization is the provider-neutral calculator contract. */
|
|
6
|
+
export type DesmosToolProviderConfig = CalculatorProviderInit;
|
|
7
|
+
export declare class DesmosToolProvider extends LazyCalculatorToolProvider<DesmosToolProviderConfig> {
|
|
62
8
|
readonly providerId = "desmos-calculator";
|
|
63
9
|
readonly providerName = "Desmos Calculator";
|
|
64
|
-
readonly category: "calculator";
|
|
65
10
|
readonly version = "1.12";
|
|
66
11
|
readonly requiresAuth = true;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
* Loads the Desmos API library and authenticates with provided credentials.
|
|
74
|
-
*
|
|
75
|
-
* @param config Configuration with API key or proxy endpoint
|
|
76
|
-
* @throws Error if initialization fails
|
|
77
|
-
*/
|
|
78
|
-
initialize(config: DesmosToolProviderConfig): Promise<void>;
|
|
79
|
-
/**
|
|
80
|
-
* Create a calculator provider instance
|
|
81
|
-
*
|
|
82
|
-
* Returns the initialized Desmos calculator provider.
|
|
83
|
-
*
|
|
84
|
-
* @param config Optional instance-specific configuration (currently unused)
|
|
85
|
-
* @returns Desmos calculator provider
|
|
86
|
-
* @throws Error if provider not initialized
|
|
87
|
-
*/
|
|
88
|
-
createInstance(config?: Partial<DesmosToolProviderConfig>): Promise<CalculatorProvider>;
|
|
89
|
-
/**
|
|
90
|
-
* Get provider capabilities
|
|
91
|
-
*
|
|
92
|
-
* @returns Desmos calculator capabilities
|
|
93
|
-
*/
|
|
12
|
+
protected getDefinition(): {
|
|
13
|
+
backend: string;
|
|
14
|
+
moduleImportOperation: string;
|
|
15
|
+
loadProvider: () => Promise<typeof import("@pie-players/pie-calculator-desmos").DesmosCalculatorProvider>;
|
|
16
|
+
initializationErrorMessage: string;
|
|
17
|
+
};
|
|
94
18
|
getCapabilities(): ToolProviderCapabilities;
|
|
95
|
-
/**
|
|
96
|
-
* Check if provider is ready
|
|
97
|
-
*
|
|
98
|
-
* @returns true if provider is initialized
|
|
99
|
-
*/
|
|
100
|
-
isReady(): boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Clean up provider resources
|
|
103
|
-
*
|
|
104
|
-
* Destroys the Desmos calculator provider and releases resources.
|
|
105
|
-
*/
|
|
106
|
-
destroy(): void;
|
|
107
19
|
}
|