@pie-players/pie-assessment-toolkit 0.3.2 → 0.3.4

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.
Files changed (90) hide show
  1. package/README.md +5 -8
  2. package/dist/components/ItemToolBar.custom-element.js +539 -94
  3. package/dist/index.d.ts +1 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/services/PNPToolResolver.d.ts.map +1 -1
  8. package/dist/services/PNPToolResolver.js +4 -1
  9. package/dist/services/PNPToolResolver.js.map +1 -1
  10. package/dist/services/ToolRegistry.d.ts +51 -0
  11. package/dist/services/ToolRegistry.d.ts.map +1 -1
  12. package/dist/services/ToolRegistry.js +60 -0
  13. package/dist/services/ToolRegistry.js.map +1 -1
  14. package/dist/services/ToolkitCoordinator.d.ts +12 -24
  15. package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
  16. package/dist/services/ToolkitCoordinator.js +60 -99
  17. package/dist/services/ToolkitCoordinator.js.map +1 -1
  18. package/dist/services/defaultPersonalNeedsProfile.js +2 -2
  19. package/dist/services/defaultPersonalNeedsProfile.js.map +1 -1
  20. package/dist/services/interfaces.d.ts +8 -3
  21. package/dist/services/interfaces.d.ts.map +1 -1
  22. package/dist/services/interfaces.js.map +1 -1
  23. package/dist/services/pnp-standard-features.d.ts +1 -1
  24. package/dist/services/tool-providers/index.d.ts +0 -4
  25. package/dist/services/tool-providers/index.d.ts.map +1 -1
  26. package/dist/services/tool-providers/index.js +0 -2
  27. package/dist/services/tool-providers/index.js.map +1 -1
  28. package/dist/services/tools-config-normalizer.d.ts +40 -3
  29. package/dist/services/tools-config-normalizer.d.ts.map +1 -1
  30. package/dist/services/tools-config-normalizer.js +86 -11
  31. package/dist/services/tools-config-normalizer.js.map +1 -1
  32. package/dist/tools/client.d.ts +0 -2
  33. package/dist/tools/client.d.ts.map +1 -1
  34. package/dist/tools/client.js +0 -4
  35. package/dist/tools/client.js.map +1 -1
  36. package/dist/tools/default-tool-module-loaders.js +1 -1
  37. package/dist/tools/default-tool-module-loaders.js.map +1 -1
  38. package/dist/tools/library-loader.d.ts.map +1 -1
  39. package/dist/tools/library-loader.js +0 -35
  40. package/dist/tools/library-loader.js.map +1 -1
  41. package/dist/tools/registrations/accessibility-tools.d.ts.map +1 -1
  42. package/dist/tools/registrations/accessibility-tools.js +44 -41
  43. package/dist/tools/registrations/accessibility-tools.js.map +1 -1
  44. package/dist/tools/registrations/calculator.d.ts.map +1 -1
  45. package/dist/tools/registrations/calculator.js +50 -2
  46. package/dist/tools/registrations/calculator.js.map +1 -1
  47. package/dist/tools/registrations/interaction-tools.d.ts.map +1 -1
  48. package/dist/tools/registrations/interaction-tools.js +22 -28
  49. package/dist/tools/registrations/interaction-tools.js.map +1 -1
  50. package/dist/tools/registrations/measurement-tools.d.ts.map +1 -1
  51. package/dist/tools/registrations/measurement-tools.js +19 -27
  52. package/dist/tools/registrations/measurement-tools.js.map +1 -1
  53. package/dist/tools/registrations/subject-specific-tools.d.ts.map +1 -1
  54. package/dist/tools/registrations/subject-specific-tools.js +53 -37
  55. package/dist/tools/registrations/subject-specific-tools.js.map +1 -1
  56. package/dist/tools/registrations/toolbar-registration-helpers.d.ts +15 -0
  57. package/dist/tools/registrations/toolbar-registration-helpers.d.ts.map +1 -0
  58. package/dist/tools/registrations/toolbar-registration-helpers.js +22 -0
  59. package/dist/tools/registrations/toolbar-registration-helpers.js.map +1 -0
  60. package/dist/tools/registrations/tts.d.ts.map +1 -1
  61. package/dist/tools/registrations/tts.js +49 -0
  62. package/dist/tools/registrations/tts.js.map +1 -1
  63. package/dist/tools/types.d.ts +1 -1
  64. package/dist/tools/types.d.ts.map +1 -1
  65. package/dist/tools/types.js.map +1 -1
  66. package/package.json +8 -10
  67. package/dist/services/tool-providers/MathJsToolProvider.d.ts +0 -25
  68. package/dist/services/tool-providers/MathJsToolProvider.d.ts.map +0 -1
  69. package/dist/services/tool-providers/MathJsToolProvider.js +0 -53
  70. package/dist/services/tool-providers/MathJsToolProvider.js.map +0 -1
  71. package/dist/services/tool-providers/TIToolProvider.d.ts +0 -107
  72. package/dist/services/tool-providers/TIToolProvider.d.ts.map +0 -1
  73. package/dist/services/tool-providers/TIToolProvider.js +0 -123
  74. package/dist/services/tool-providers/TIToolProvider.js.map +0 -1
  75. package/dist/tools/calculators/mathjs-provider.d.ts +0 -50
  76. package/dist/tools/calculators/mathjs-provider.d.ts.map +0 -1
  77. package/dist/tools/calculators/mathjs-provider.js +0 -660
  78. package/dist/tools/calculators/mathjs-provider.js.map +0 -1
  79. package/dist/tools/calculators/ti-provider.d.ts +0 -122
  80. package/dist/tools/calculators/ti-provider.d.ts.map +0 -1
  81. package/dist/tools/calculators/ti-provider.js +0 -710
  82. package/dist/tools/calculators/ti-provider.js.map +0 -1
  83. package/src/README.md +0 -626
  84. package/src/components/ItemToolBar.svelte +0 -717
  85. package/src/components/PieAssessmentToolkit.svelte +0 -681
  86. package/src/components/SectionToolBar.svelte +0 -58
  87. package/src/components/ToolButton.svelte +0 -146
  88. package/src/components/ToolButtonGroup.svelte +0 -125
  89. package/src/tools/README.md +0 -617
  90. package/src/tools/calculators/README.md +0 -395
@@ -1,617 +0,0 @@
1
- # Assessment Tools System
2
-
3
- This directory contains the core infrastructure for the assessment tools system, including type definitions, store management, and coordination logic.
4
-
5
- ## Architecture
6
-
7
- ### Core Components
8
-
9
- 1. **`types.ts`** - Type definitions for tools, tool state, and configuration
10
- 2. **`toolCoordinator.ts`** - Central store for managing tool visibility, z-index, and coordination
11
- 3. **`index.ts`** - Public API exports
12
-
13
- ### Tool Lifecycle
14
-
15
- ```typescript
16
- // 1. Register tool (typically in onMount)
17
- toolCoordinator.registerTool('my-tool', 'My Tool', element);
18
-
19
- // 2. Show/hide tool
20
- toolCoordinator.showTool('my-tool');
21
- toolCoordinator.hideTool('my-tool');
22
- toolCoordinator.toggleTool('my-tool');
23
-
24
- // 3. Bring tool to front (when clicked)
25
- toolCoordinator.bringToFront('my-tool');
26
-
27
- // 4. Unregister (typically in onDestroy)
28
- toolCoordinator.unregisterTool('my-tool');
29
- ```
30
-
31
- ## Tool Coordinator Store
32
-
33
- The `toolCoordinator` manages:
34
-
35
- - **Tool Registration**: Track all active tools
36
- - **Visibility Management**: Show/hide tools
37
- - **Z-Index Coordination**: Automatically manage layering
38
- - **Active Tool Tracking**: Know which tool is currently in focus
39
-
40
- ### API Reference
41
-
42
- #### `registerTool(id, name, element?)`
43
- Register a new tool with the coordinator.
44
-
45
- **Parameters:**
46
- - `id: ToolId` - Unique identifier
47
- - `name: string` - Display name
48
- - `element?: HTMLElement` - DOM element reference (optional)
49
-
50
- #### `unregisterTool(id)`
51
- Remove a tool from the coordinator.
52
-
53
- #### `showTool(id)`
54
- Show a tool and bring it to the front.
55
-
56
- #### `hideTool(id)`
57
- Hide a tool.
58
-
59
- #### `toggleTool(id)`
60
- Toggle tool visibility.
61
-
62
- #### `bringToFront(id)`
63
- Bring a visible tool to the front (highest z-index).
64
-
65
- #### `updateToolElement(id, element)`
66
- Update the DOM element reference for a tool.
67
-
68
- #### `hideAllTools()`
69
- Hide all registered tools.
70
-
71
- #### `getToolState(id)`
72
- Get the current state of a tool.
73
-
74
- **Returns:** `ToolState | undefined`
75
-
76
- #### `isToolVisible(id)`
77
- Check if a tool is currently visible.
78
-
79
- **Returns:** `boolean`
80
-
81
- ### Derived Stores
82
-
83
- - **`visibleTools`** - Array of all currently visible tools
84
- - **`activeTool`** - The currently active (focused) tool
85
-
86
- ## Creating a New Tool
87
-
88
- Tools are packaged as Svelte components in `src/lib/tags/tool-{name}/`:
89
-
90
- ### Directory Structure
91
-
92
- ```
93
- src/lib/tags/tool-{name}/
94
- ├── package.json # NPM package configuration
95
- ├── tool-{name}.svelte # Main tool component
96
- ├── index.ts # Exports
97
- └── README.md # Tool-specific documentation (optional)
98
- ```
99
-
100
- ### Example Tool Implementation
101
-
102
- ```svelte
103
- <script lang="ts">
104
- import { onMount, onDestroy } from 'svelte';
105
- import { toolCoordinator } from '$lib/assessment-toolkit/tools';
106
- import type { Tool } from '$lib/assessment-toolkit/tools';
107
-
108
- export let visible: boolean = false;
109
- export let toolId: string = 'my-tool';
110
-
111
- let containerEl: HTMLDivElement;
112
-
113
- // Implement Tool interface
114
- const tool: Tool = {
115
- id: toolId,
116
- name: 'My Tool',
117
- show: () => { visible = true; },
118
- hide: () => { visible = false; },
119
- toggle: () => { visible = !visible; }
120
- };
121
-
122
- function handleClose() {
123
- toolCoordinator.hideTool(toolId);
124
- }
125
-
126
- onMount(() => {
127
- toolCoordinator.registerTool(toolId, 'My Tool', containerEl);
128
- });
129
-
130
- onDestroy(() => {
131
- toolCoordinator.unregisterTool(toolId);
132
- });
133
-
134
- $: if (containerEl) {
135
- toolCoordinator.updateToolElement(toolId, containerEl);
136
- }
137
- </script>
138
-
139
- {#if visible}
140
- <div
141
- bind:this={containerEl}
142
- class="pie-tool-my-tool"
143
- on:mousedown={() => toolCoordinator.bringToFront(toolId)}
144
- >
145
- <div class="pie-tool-my-tool__header">
146
- <span>My Tool</span>
147
- <button on:click={handleClose}>×</button>
148
- </div>
149
-
150
- <!-- Tool content here -->
151
- </div>
152
- {/if}
153
-
154
- <style>
155
- .pie-tool-my-tool {
156
- position: fixed;
157
- /* Tool-specific styles */
158
- }
159
- </style>
160
- ```
161
-
162
- ### Package.json Template
163
-
164
- ```json
165
- {
166
- "name": "@pie-framework/pie-tool-{name}",
167
- "version": "1.0.0",
168
- "type": "module",
169
- "description": "{Tool Name} for PIE assessment player",
170
- "keywords": [
171
- "pie",
172
- "assessment",
173
- "tool"
174
- ],
175
- "svelte": "./tool-{name}.svelte",
176
- "main": "./index.ts",
177
- "exports": {
178
- ".": {
179
- "svelte": "./tool-{name}.svelte",
180
- "import": "./index.ts"
181
- }
182
- },
183
- "files": [
184
- "tool-{name}.svelte",
185
- "index.ts",
186
- "README.md"
187
- ],
188
- "peerDependencies": {
189
- "svelte": "^4.0.0"
190
- },
191
- "license": "MIT"
192
- }
193
- ```
194
-
195
- ## Integration with Assessment Player
196
-
197
- In the assessment player component:
198
-
199
- ```svelte
200
- <script lang="ts">
201
- import { toolCoordinator } from '$lib/assessment-toolkit/tools';
202
- import { ToolProtractor } from '$lib/tags/tool-protractor';
203
- // Or using full package name: import ToolProtractor from '@pie-framework/pie-tool-protractor';
204
-
205
- let showProtractor = false;
206
-
207
- // Subscribe to tool state
208
- $: {
209
- const state = toolCoordinator.getToolState('protractor');
210
- showProtractor = state?.isVisible ?? false;
211
- }
212
- </script>
213
-
214
- <!-- Tool button -->
215
- <button
216
- on:click={() => toolCoordinator.toggleTool('protractor')}
217
- class:active={showProtractor}
218
- >
219
- Protractor
220
- </button>
221
-
222
- <!-- Tool component -->
223
- <ToolProtractor visible={showProtractor} toolId="protractor" />
224
- ```
225
-
226
- ## Tool Categories
227
-
228
- ### Standalone Tools
229
- Tools that don't interact with assessment content:
230
- - Protractor
231
- - Ruler
232
- - Calculator
233
- - Character Picker
234
- - Graph Tool
235
- - Periodic Table
236
-
237
- ### Content-Interactive Tools
238
- Tools that need to access/manipulate question content:
239
- - Annotation Toolbar (highlights, underlines)
240
- - Text Magnifier
241
- - Color Overlay
242
-
243
- ### Service-Dependent Tools
244
- Tools that require external API integration:
245
- - Dictionary
246
- - Translation
247
- - Text-to-Speech
248
- - Picture Dictionary
249
-
250
- ## Best Practices
251
-
252
- 1. **Always register/unregister** tools in `onMount`/`onDestroy`
253
- 2. **Use the coordinator** for all visibility changes (don't manipulate `visible` prop directly)
254
- 3. **Bring to front** on user interaction (mousedown)
255
- 4. **Update element reference** when container changes
256
- 5. **Handle cleanup** properly to prevent memory leaks
257
- 6. **Make tools draggable** for better UX
258
- 7. **Add close buttons** to all tools
259
- 8. **Use consistent styling** (header, body, controls)
260
- 9. **Use namespaced classes** (`pie-tool-{name}` and `pie-tool-{name}__*`)
261
-
262
- ## Architectural Enhancement Services
263
-
264
- The following services implement architectural enhancements based on analysis of production assessment platforms:
265
-
266
- ### 1. Library Loader Service
267
-
268
- Dynamically loads external JavaScript libraries with retry logic and fallback URLs.
269
-
270
- ```typescript
271
- import { libraryLoader, COMMON_LIBRARIES } from '$lib/assessment-toolkit/tools';
272
-
273
- // Load Desmos calculator library
274
- await libraryLoader.loadScript(COMMON_LIBRARIES.desmos);
275
-
276
- // Check if loaded
277
- if (libraryLoader.isLoaded('desmos')) {
278
- // Use Desmos API
279
- const calculator = Desmos.GraphingCalculator(element);
280
- }
281
-
282
- // Get loader statistics
283
- const stats = libraryLoader.getStats();
284
- console.log(`Loaded: ${stats.loaded.length}, Failed: ${stats.failed.length}`);
285
- ```
286
-
287
- **Features:**
288
- - Retry logic with exponential backoff
289
- - Multiple fallback URLs (CDN → backup CDN → local)
290
- - Timeout handling
291
- - SRI (Subresource Integrity) support
292
- - Statistics tracking
293
-
294
- **Common Libraries:**
295
- - `desmos` - Desmos calculator API
296
- - `mathjax` - Math rendering
297
- - `katex` - Fast math typesetting
298
- - `ti84`, `ti108`, `ti34mv` - TI calculator emulators (placeholders)
299
-
300
- ### 2. Accommodation Resolver Service
301
-
302
- Resolves final tool configuration by merging roster, student, and item configs.
303
-
304
- ```typescript
305
- import { accommodationResolver } from '$lib/assessment-toolkit/tools';
306
- import type { AccommodationProfile, RosterToolConfiguration, ItemToolConfig } from '$lib/assessment-toolkit/tools';
307
-
308
- // Define configurations
309
- const student: AccommodationProfile = {
310
- studentId: 'student-123',
311
- accommodations: {
312
- calculator: true,
313
- highlighter: true,
314
- },
315
- };
316
-
317
- const roster: RosterToolConfiguration = {
318
- rosterId: 'roster-456',
319
- toolAllowances: {
320
- calculator: '1', // allowed
321
- lineReader: '0', // blocked
322
- },
323
- };
324
-
325
- const item: ItemToolConfig = {
326
- itemId: 'item-789',
327
- requiredTools: ['protractor'], // required for this item
328
- restrictedTools: ['graphing-calculator'], // not allowed for this item
329
- };
330
-
331
- // Resolve final tools
332
- const resolved = accommodationResolver.resolveToolsForItem(student, roster, item);
333
- // Returns: [calculator, highlighter, protractor] (graphing-calculator blocked, lineReader blocked)
334
-
335
- // Check specific tool
336
- const result = accommodationResolver.isToolAllowed('calculator', student, roster, item);
337
- console.log(result); // { allowed: true, reason: '...', source: 'student-accommodation' }
338
-
339
- // Debug resolution
340
- const trace = accommodationResolver.getResolutionTrace('calculator', student, roster, item);
341
- ```
342
-
343
- **Precedence (highest to lowest):**
344
- 1. Roster block (`"0"` = blocked)
345
- 2. Item restriction
346
- 3. Item requirement
347
- 4. Student accommodation
348
- 5. Roster default (`"1"` = allowed)
349
- 6. System default (not allowed)
350
-
351
- ### 3. Variant Resolver Service
352
-
353
- Resolves item configuration considering variants for A/B testing and scaffolding.
354
-
355
- ```typescript
356
- import { variantResolver } from '$lib/assessment-toolkit/tools';
357
- import type { ItemToolConfig, VariantContext } from '$lib/assessment-toolkit/tools';
358
-
359
- const itemConfig: ItemToolConfig = {
360
- itemId: 'item-001',
361
- requiredTools: ['calculator'],
362
- variantConfig: {
363
- variantId: 'scaffolding-2',
364
- toolOverrides: {
365
- calculator: {
366
- parameters: {
367
- showHints: true,
368
- stepByStepMode: true,
369
- },
370
- },
371
- },
372
- adaptations: [
373
- {
374
- type: 'scaffolding',
375
- level: 2,
376
- affectedTools: ['calculator'],
377
- },
378
- ],
379
- },
380
- };
381
-
382
- const context: VariantContext = {
383
- studentId: 'student-123',
384
- sessionId: 'session-456',
385
- scaffoldingLevel: 2,
386
- };
387
-
388
- // Resolve variant
389
- const resolved = variantResolver.resolveVariant(itemConfig, context);
390
- console.log(resolved.appliedVariant); // 'scaffolding-2'
391
- console.log(resolved.toolParameters.calculator.finalConfig); // Merged config with hints enabled
392
- ```
393
-
394
- **Use Cases:**
395
- - A/B testing different tool configurations
396
- - Scaffolding for struggling students
397
- - Difficulty adaptations
398
- - Language-specific tool variants
399
-
400
- ### 4. Response Discovery Service
401
-
402
- Finds and manages PIE response components for tool-to-response integration.
403
-
404
- ```typescript
405
- import { responseDiscovery } from '$lib/assessment-toolkit/tools';
406
-
407
- // Setup (in player initialization)
408
- responseDiscovery.setupFocusTracking(); // Auto-track active response
409
- responseDiscovery.autoDiscoverResponses(); // Find all response elements
410
-
411
- // In calculator tool
412
- async function insertIntoResponse() {
413
- const activeResponse = responseDiscovery.getActiveResponse();
414
-
415
- if (!activeResponse) {
416
- console.warn('No active response');
417
- return;
418
- }
419
-
420
- const result = calculator.getValue();
421
- const capabilities = activeResponse.getCapabilities();
422
-
423
- if (capabilities.acceptsNumeric) {
424
- await activeResponse.insertContent(result, {
425
- mode: 'insert',
426
- format: 'numeric',
427
- focus: true,
428
- source: {
429
- toolId: 'calculator',
430
- toolType: 'scientific',
431
- timestamp: Date.now(),
432
- },
433
- });
434
- }
435
- }
436
-
437
- // Listen for active response changes
438
- responseDiscovery.onActiveResponseChanged((response) => {
439
- if (response) {
440
- console.log(`Active response: ${response.responseId}`);
441
- }
442
- });
443
- ```
444
-
445
- **Features:**
446
- - Automatic response discovery from DOM
447
- - Active response tracking (based on focus)
448
- - Capability-based content insertion
449
- - Format validation
450
- - Event notifications
451
-
452
- ### 5. Calculator Provider System
453
-
454
- Multi-provider calculator architecture supporting Desmos, Math.js, and TI emulators.
455
-
456
- ```typescript
457
- import { desmosProvider, mathjsProvider, tiProvider } from '$lib/assessment-toolkit/tools';
458
- import type { CalculatorType } from '$lib/assessment-toolkit/tools';
459
-
460
- // Option 1: Math.js (Open Source - Apache 2.0)
461
- // Perfect for testing without licensing requirements
462
- await mathjsProvider.initialize();
463
- const basicCalc = await mathjsProvider.createCalculator('basic', container);
464
- const scientificCalc = await mathjsProvider.createCalculator('scientific', container);
465
-
466
- // Option 2: Desmos (Requires License & API Key)
467
- // Professional graphing calculator
468
- // Obtain API key from https://www.desmos.com/api
469
- await desmosProvider.initialize({
470
- apiKey: 'your_desmos_api_key_here'
471
- });
472
- const graphingCalc = await desmosProvider.createCalculator('graphing', container, {
473
- theme: 'light',
474
- restrictedMode: false,
475
- });
476
-
477
- // Use calculator
478
- graphingCalc.setValue('y = x^2');
479
- const value = graphingCalc.getValue();
480
-
481
- // Export state for persistence
482
- const state = graphingCalc.exportState();
483
- localStorage.setItem('calculator-state', JSON.stringify(state));
484
-
485
- // Restore state
486
- const savedState = JSON.parse(localStorage.getItem('calculator-state'));
487
- graphingCalc.importState(savedState);
488
-
489
- // Switch providers
490
- const tiCalculator = await tiProvider.createCalculator('ti-84', container);
491
-
492
- // Cleanup
493
- graphingCalc.destroy();
494
- ```
495
-
496
- **Supported Calculator Types by Provider:**
497
-
498
- | Provider | Basic | Scientific | Graphing | License | Status |
499
- |----------|-------|------------|----------|---------|--------|
500
- | **Math.js** | ✅ | ✅ | ❌ | Apache 2.0 (Free) | ✅ Production Ready |
501
- | **Desmos** | ✅ | ✅ | ✅ | Proprietary | ✅ Production Ready |
502
- | **TI** | ❌ | ❌ | ✅ (TI-84) | Proprietary | ⚠️ Stub Only |
503
-
504
- **Math.js Provider Features:**
505
- - ✅ **No licensing fees** - Apache 2.0 open source
506
- - ✅ **Full calculator UI** - Button-based interface included
507
- - ✅ **Scientific functions** - Trigonometry, logarithms, constants (π, e)
508
- - ✅ **Angle modes** - Degrees and radians
509
- - ✅ **History** - Calculation history tracking
510
- - ✅ **Keyboard support** - Full keyboard navigation
511
- - ✅ **State persistence** - Export/import calculator state
512
- - ✅ **Perfect for testing** - Works out of the box without external dependencies
513
-
514
- **When to Use Each Provider:**
515
- - **Math.js**: Testing, basic/scientific calculators, cost-effective solution
516
- - **Desmos**: Professional graphing, when graphing is required (requires API key for production)
517
- - **TI**: Future - when TI emulator licensing is available
518
-
519
- **Desmos API Key Configuration:**
520
-
521
- Production usage of Desmos calculators requires an API key. There are three ways to provide it:
522
-
523
- ```typescript
524
- // Method 1: Initialize with API key (recommended)
525
- await desmosProvider.initialize({
526
- apiKey: 'your_desmos_api_key_here'
527
- });
528
-
529
- // Method 2: Per-calculator configuration
530
- const calculator = await desmosProvider.createCalculator('graphing', container, {
531
- desmos: {
532
- apiKey: 'your_desmos_api_key_here'
533
- }
534
- });
535
-
536
- // Method 3: Global configuration (set before initialization)
537
- window.PIE_DESMOS_API_KEY = 'your_desmos_api_key_here';
538
- await desmosProvider.initialize();
539
- ```
540
-
541
- To obtain a Desmos API key:
542
- - Visit: <https://www.desmos.com/api>
543
- - Contact: partnerships@desmos.com
544
-
545
- **Note:** Development and testing work without an API key, but production deployments require a valid Desmos license.
546
-
547
- **Provider Interface:**
548
- All providers implement the same interface, allowing seamless switching between providers without code changes.
549
-
550
- ## Service Integration Example
551
-
552
- Complete example showing all services working together:
553
-
554
- ```typescript
555
- import {
556
- libraryLoader,
557
- accommodationResolver,
558
- variantResolver,
559
- responseDiscovery,
560
- desmosProvider,
561
- type AccommodationProfile,
562
- type RosterToolConfiguration,
563
- type ItemToolConfig,
564
- } from '$lib/assessment-toolkit/tools';
565
-
566
- // 1. Load required library
567
- await libraryLoader.loadScript(COMMON_LIBRARIES.desmos);
568
-
569
- // 2. Resolve tool configuration
570
- const resolvedTools = accommodationResolver.resolveToolsForItem(
571
- studentProfile,
572
- rosterConfig,
573
- itemConfig
574
- );
575
-
576
- // 3. Resolve item variant
577
- const resolvedItem = variantResolver.resolveVariant(itemConfig, variantContext);
578
-
579
- // 4. Initialize calculator if allowed
580
- const calculatorAllowed = resolvedTools.some((t) => t.id === 'calculator');
581
- if (calculatorAllowed) {
582
- const calculator = await desmosProvider.createCalculator(
583
- 'scientific',
584
- calculatorContainer,
585
- resolvedItem.toolParameters.calculator?.finalConfig
586
- );
587
-
588
- // 5. Setup response integration
589
- responseDiscovery.setupFocusTracking();
590
-
591
- // Insert calculator result into active response
592
- calculator.insertIntoResponse = async () => {
593
- const response = responseDiscovery.getActiveResponse();
594
- if (response) {
595
- await response.insertContent(calculator.getValue(), {
596
- mode: 'insert',
597
- format: 'numeric',
598
- });
599
- }
600
- };
601
- }
602
- ```
603
-
604
- ## Future Enhancements
605
-
606
- - [ ] Tool configuration persistence (save position, settings)
607
- - [ ] Tool presets per assessment
608
- - [ ] Keyboard shortcuts for tool activation
609
- - [ ] Tool usage analytics
610
- - [ ] Multi-tool interactions
611
- - [x] Tool state serialization/restoration (via calculator providers)
612
- - [x] Library loading with fallbacks (via LibraryLoader)
613
- - [x] Multi-provider calculator support (Desmos + TI)
614
- - [x] Tool-to-response integration (via ResponseDiscovery)
615
- - [x] Configuration merge resolution (via AccommodationResolver)
616
- - [x] Item variant support (via VariantResolver)
617
-