@pie-players/pie-assessment-toolkit 0.2.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.
Files changed (194) hide show
  1. package/README.md +520 -0
  2. package/dist/attempt/TestSession.d.ts +90 -0
  3. package/dist/attempt/TestSession.d.ts.map +1 -0
  4. package/dist/attempt/TestSession.js +174 -0
  5. package/dist/attempt/TestSession.js.map +1 -0
  6. package/dist/core/TypedEventBus.d.ts +48 -0
  7. package/dist/core/TypedEventBus.d.ts.map +1 -0
  8. package/dist/core/TypedEventBus.js +63 -0
  9. package/dist/core/TypedEventBus.js.map +1 -0
  10. package/dist/index.d.ts +37 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +44 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/item-loader.d.ts +45 -0
  15. package/dist/item-loader.d.ts.map +1 -0
  16. package/dist/item-loader.js +62 -0
  17. package/dist/item-loader.js.map +1 -0
  18. package/dist/player/AssessmentPlayer.d.ts +388 -0
  19. package/dist/player/AssessmentPlayer.d.ts.map +1 -0
  20. package/dist/player/AssessmentPlayer.js +965 -0
  21. package/dist/player/AssessmentPlayer.js.map +1 -0
  22. package/dist/player/index.d.ts +17 -0
  23. package/dist/player/index.d.ts.map +1 -0
  24. package/dist/player/index.js +15 -0
  25. package/dist/player/index.js.map +1 -0
  26. package/dist/player/navigation-types.d.ts +63 -0
  27. package/dist/player/navigation-types.d.ts.map +1 -0
  28. package/dist/player/navigation-types.js +7 -0
  29. package/dist/player/navigation-types.js.map +1 -0
  30. package/dist/player/qti-navigation.d.ts +29 -0
  31. package/dist/player/qti-navigation.d.ts.map +1 -0
  32. package/dist/player/qti-navigation.js +160 -0
  33. package/dist/player/qti-navigation.js.map +1 -0
  34. package/dist/reference-layout/index.d.ts +19 -0
  35. package/dist/reference-layout/index.d.ts.map +1 -0
  36. package/dist/reference-layout/index.js +20 -0
  37. package/dist/reference-layout/index.js.map +1 -0
  38. package/dist/services/AccessibilityCatalogResolver.d.ts +141 -0
  39. package/dist/services/AccessibilityCatalogResolver.d.ts.map +1 -0
  40. package/dist/services/AccessibilityCatalogResolver.js +249 -0
  41. package/dist/services/AccessibilityCatalogResolver.js.map +1 -0
  42. package/dist/services/AssessmentAuthoringService.d.ts +60 -0
  43. package/dist/services/AssessmentAuthoringService.d.ts.map +1 -0
  44. package/dist/services/AssessmentAuthoringService.js +183 -0
  45. package/dist/services/AssessmentAuthoringService.js.map +1 -0
  46. package/dist/services/ContextVariableStore.d.ts +114 -0
  47. package/dist/services/ContextVariableStore.d.ts.map +1 -0
  48. package/dist/services/ContextVariableStore.js +207 -0
  49. package/dist/services/ContextVariableStore.js.map +1 -0
  50. package/dist/services/ElementToolStateStore.d.ts +125 -0
  51. package/dist/services/ElementToolStateStore.d.ts.map +1 -0
  52. package/dist/services/ElementToolStateStore.js +200 -0
  53. package/dist/services/ElementToolStateStore.js.map +1 -0
  54. package/dist/services/HighlightCoordinator.d.ts +179 -0
  55. package/dist/services/HighlightCoordinator.d.ts.map +1 -0
  56. package/dist/services/HighlightCoordinator.js +446 -0
  57. package/dist/services/HighlightCoordinator.js.map +1 -0
  58. package/dist/services/I18nService.d.ts +121 -0
  59. package/dist/services/I18nService.d.ts.map +1 -0
  60. package/dist/services/I18nService.js +276 -0
  61. package/dist/services/I18nService.js.map +1 -0
  62. package/dist/services/PNPMapper.d.ts +71 -0
  63. package/dist/services/PNPMapper.d.ts.map +1 -0
  64. package/dist/services/PNPMapper.js +98 -0
  65. package/dist/services/PNPMapper.js.map +1 -0
  66. package/dist/services/PNPToolResolver.d.ts +127 -0
  67. package/dist/services/PNPToolResolver.d.ts.map +1 -0
  68. package/dist/services/PNPToolResolver.js +222 -0
  69. package/dist/services/PNPToolResolver.js.map +1 -0
  70. package/dist/services/SSMLExtractor.d.ts +61 -0
  71. package/dist/services/SSMLExtractor.d.ts.map +1 -0
  72. package/dist/services/SSMLExtractor.js +181 -0
  73. package/dist/services/SSMLExtractor.js.map +1 -0
  74. package/dist/services/TTSService.d.ts +162 -0
  75. package/dist/services/TTSService.d.ts.map +1 -0
  76. package/dist/services/TTSService.js +465 -0
  77. package/dist/services/TTSService.js.map +1 -0
  78. package/dist/services/ThemeProvider.d.ts +95 -0
  79. package/dist/services/ThemeProvider.d.ts.map +1 -0
  80. package/dist/services/ThemeProvider.js +299 -0
  81. package/dist/services/ThemeProvider.js.map +1 -0
  82. package/dist/services/ToolConfigResolver.d.ts +162 -0
  83. package/dist/services/ToolConfigResolver.d.ts.map +1 -0
  84. package/dist/services/ToolConfigResolver.js +230 -0
  85. package/dist/services/ToolConfigResolver.js.map +1 -0
  86. package/dist/services/ToolCoordinator.d.ts +137 -0
  87. package/dist/services/ToolCoordinator.d.ts.map +1 -0
  88. package/dist/services/ToolCoordinator.js +318 -0
  89. package/dist/services/ToolCoordinator.js.map +1 -0
  90. package/dist/services/ToolkitCoordinator.d.ts +188 -0
  91. package/dist/services/ToolkitCoordinator.d.ts.map +1 -0
  92. package/dist/services/ToolkitCoordinator.js +252 -0
  93. package/dist/services/ToolkitCoordinator.js.map +1 -0
  94. package/dist/services/interfaces.d.ts +391 -0
  95. package/dist/services/interfaces.d.ts.map +1 -0
  96. package/dist/services/interfaces.js +12 -0
  97. package/dist/services/interfaces.js.map +1 -0
  98. package/dist/services/tool-providers/DesmosToolProvider.d.ts +103 -0
  99. package/dist/services/tool-providers/DesmosToolProvider.d.ts.map +1 -0
  100. package/dist/services/tool-providers/DesmosToolProvider.js +127 -0
  101. package/dist/services/tool-providers/DesmosToolProvider.js.map +1 -0
  102. package/dist/services/tool-providers/IToolProvider.d.ts +137 -0
  103. package/dist/services/tool-providers/IToolProvider.d.ts.map +1 -0
  104. package/dist/services/tool-providers/IToolProvider.js +13 -0
  105. package/dist/services/tool-providers/IToolProvider.js.map +1 -0
  106. package/dist/services/tool-providers/TIToolProvider.d.ts +107 -0
  107. package/dist/services/tool-providers/TIToolProvider.d.ts.map +1 -0
  108. package/dist/services/tool-providers/TIToolProvider.js +123 -0
  109. package/dist/services/tool-providers/TIToolProvider.js.map +1 -0
  110. package/dist/services/tool-providers/TTSToolProvider.d.ts +143 -0
  111. package/dist/services/tool-providers/TTSToolProvider.d.ts.map +1 -0
  112. package/dist/services/tool-providers/TTSToolProvider.js +168 -0
  113. package/dist/services/tool-providers/TTSToolProvider.js.map +1 -0
  114. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +165 -0
  115. package/dist/services/tool-providers/ToolProviderRegistry.d.ts.map +1 -0
  116. package/dist/services/tool-providers/ToolProviderRegistry.js +240 -0
  117. package/dist/services/tool-providers/ToolProviderRegistry.js.map +1 -0
  118. package/dist/services/tool-providers/index.d.ts +18 -0
  119. package/dist/services/tool-providers/index.d.ts.map +1 -0
  120. package/dist/services/tool-providers/index.js +15 -0
  121. package/dist/services/tool-providers/index.js.map +1 -0
  122. package/dist/services/tts/browser-provider.d.ts +24 -0
  123. package/dist/services/tts/browser-provider.d.ts.map +1 -0
  124. package/dist/services/tts/browser-provider.js +177 -0
  125. package/dist/services/tts/browser-provider.js.map +1 -0
  126. package/dist/services/tts/provider-interface.d.ts +131 -0
  127. package/dist/services/tts/provider-interface.d.ts.map +1 -0
  128. package/dist/services/tts/provider-interface.js +10 -0
  129. package/dist/services/tts/provider-interface.js.map +1 -0
  130. package/dist/tools/calculators/desmos-provider.d.ts +54 -0
  131. package/dist/tools/calculators/desmos-provider.d.ts.map +1 -0
  132. package/dist/tools/calculators/desmos-provider.js +384 -0
  133. package/dist/tools/calculators/desmos-provider.js.map +1 -0
  134. package/dist/tools/calculators/mathjs-provider.d.ts +50 -0
  135. package/dist/tools/calculators/mathjs-provider.d.ts.map +1 -0
  136. package/dist/tools/calculators/mathjs-provider.js +660 -0
  137. package/dist/tools/calculators/mathjs-provider.js.map +1 -0
  138. package/dist/tools/calculators/ti-provider.d.ts +122 -0
  139. package/dist/tools/calculators/ti-provider.d.ts.map +1 -0
  140. package/dist/tools/calculators/ti-provider.js +587 -0
  141. package/dist/tools/calculators/ti-provider.js.map +1 -0
  142. package/dist/tools/client.d.ts +17 -0
  143. package/dist/tools/client.d.ts.map +1 -0
  144. package/dist/tools/client.js +26 -0
  145. package/dist/tools/client.js.map +1 -0
  146. package/dist/tools/index.d.ts +8 -0
  147. package/dist/tools/index.d.ts.map +1 -0
  148. package/dist/tools/index.js +10 -0
  149. package/dist/tools/index.js.map +1 -0
  150. package/dist/tools/library-loader.d.ts +63 -0
  151. package/dist/tools/library-loader.d.ts.map +1 -0
  152. package/dist/tools/library-loader.js +292 -0
  153. package/dist/tools/library-loader.js.map +1 -0
  154. package/dist/tools/response-discovery.d.ts +72 -0
  155. package/dist/tools/response-discovery.d.ts.map +1 -0
  156. package/dist/tools/response-discovery.js +183 -0
  157. package/dist/tools/response-discovery.js.map +1 -0
  158. package/dist/tools/tool-coordinator.d.ts +76 -0
  159. package/dist/tools/tool-coordinator.d.ts.map +1 -0
  160. package/dist/tools/tool-coordinator.js +197 -0
  161. package/dist/tools/tool-coordinator.js.map +1 -0
  162. package/dist/tools/types.d.ts +427 -0
  163. package/dist/tools/types.d.ts.map +1 -0
  164. package/dist/tools/types.js +13 -0
  165. package/dist/tools/types.js.map +1 -0
  166. package/dist/tools/variant-resolver.d.ts +48 -0
  167. package/dist/tools/variant-resolver.d.ts.map +1 -0
  168. package/dist/tools/variant-resolver.js +214 -0
  169. package/dist/tools/variant-resolver.js.map +1 -0
  170. package/dist/types/events.d.ts +157 -0
  171. package/dist/types/events.d.ts.map +1 -0
  172. package/dist/types/events.js +11 -0
  173. package/dist/types/events.js.map +1 -0
  174. package/dist/utils/logger.d.ts +7 -0
  175. package/dist/utils/logger.d.ts.map +1 -0
  176. package/dist/utils/logger.js +11 -0
  177. package/dist/utils/logger.js.map +1 -0
  178. package/package.json +71 -0
  179. package/src/README.md +626 -0
  180. package/src/components/QuestionToolBar.svelte +406 -0
  181. package/src/player/AssessmentLayout.svelte +68 -0
  182. package/src/player/README.md +154 -0
  183. package/src/reference-layout/README.md +135 -0
  184. package/src/reference-layout/ReferenceLayout.svelte +209 -0
  185. package/src/reference-layout/components/AssessmentContent.svelte +259 -0
  186. package/src/reference-layout/components/AssessmentFooter.svelte +89 -0
  187. package/src/reference-layout/components/AssessmentHeader.svelte +250 -0
  188. package/src/reference-layout/components/AssessmentNavigation.svelte +134 -0
  189. package/src/reference-layout/components/AssessmentToolsBar.svelte +176 -0
  190. package/src/reference-layout/components/ItemPanel.svelte +200 -0
  191. package/src/reference-layout/components/NotesPanel.svelte +179 -0
  192. package/src/reference-layout/components/PassagePanel.svelte +76 -0
  193. package/src/tools/README.md +616 -0
  194. package/src/tools/calculators/README.md +395 -0
@@ -0,0 +1,230 @@
1
+ /**
2
+ * ToolConfigResolver
3
+ *
4
+ * Implements 3-tier hierarchy for tool configuration:
5
+ * Item requirements > Roster allowances > Student accommodations
6
+ *
7
+ * Ensures IEP/504 compliance by properly handling accommodation requirements
8
+ * while respecting item-level and test-level restrictions.
9
+ *
10
+ * Features:
11
+ * - 3-tier configuration hierarchy
12
+ * - IEP/504 accommodation support
13
+ * - Item-specific tool requirements
14
+ * - Test-level tool restrictions
15
+ * - Type-safe configuration
16
+ *
17
+ * Part of PIE Assessment Toolkit.
18
+ */
19
+ export class ToolConfigResolver {
20
+ /**
21
+ * Resolve configuration for a specific tool
22
+ *
23
+ * Hierarchy (highest to lowest priority):
24
+ * 1. Item level: Item requires scientific calculator → must provide
25
+ * 2. Roster level: Test blocks dictionary → blocked regardless of accommodation
26
+ * 3. Student level: IEP requires TTS → enabled unless blocked above
27
+ *
28
+ * @param toolId Tool identifier
29
+ * @param itemConfig Item-level tool configuration
30
+ * @param rosterConfig Roster-level tool allowances
31
+ * @param studentProfile Student accommodation profile
32
+ * @returns Resolved configuration or null if tool not available
33
+ */
34
+ resolveTool(toolId, itemConfig, rosterConfig, studentProfile) {
35
+ // Check item level (highest priority)
36
+ const itemTool = itemConfig?.[toolId];
37
+ if (itemTool) {
38
+ // Item explicitly configures this tool
39
+ return {
40
+ enabled: true,
41
+ type: itemTool.type,
42
+ required: itemTool.required ?? false,
43
+ settings: itemTool.settings,
44
+ source: "item",
45
+ };
46
+ }
47
+ // Check roster level (blocks take precedence)
48
+ const rosterAllowance = rosterConfig?.[toolId];
49
+ if (rosterAllowance === "0") {
50
+ // Roster explicitly blocks this tool
51
+ return null;
52
+ }
53
+ if (rosterAllowance === "1") {
54
+ // Roster allows this tool
55
+ return {
56
+ enabled: true,
57
+ required: false,
58
+ source: "roster",
59
+ };
60
+ }
61
+ // Check student level (lowest priority)
62
+ const hasAccommodation = studentProfile?.accommodations.includes(toolId) ?? false;
63
+ if (hasAccommodation) {
64
+ // Student has accommodation for this tool
65
+ return {
66
+ enabled: true,
67
+ required: false,
68
+ source: "student",
69
+ };
70
+ }
71
+ // Tool not configured at any level
72
+ return null;
73
+ }
74
+ /**
75
+ * Resolve all tools from configuration
76
+ *
77
+ * @param input Configuration input
78
+ * @returns Map of tool ID to resolved configuration
79
+ */
80
+ resolveAll(input) {
81
+ const resolved = new Map();
82
+ // Collect all tool IDs from all levels
83
+ const allToolIds = new Set();
84
+ // From item config
85
+ if (input.itemConfig) {
86
+ Object.keys(input.itemConfig).forEach((id) => allToolIds.add(id));
87
+ }
88
+ // From roster config
89
+ if (input.rosterConfig) {
90
+ Object.keys(input.rosterConfig).forEach((id) => allToolIds.add(id));
91
+ }
92
+ // From student accommodations
93
+ if (input.studentProfile) {
94
+ input.studentProfile.accommodations.forEach((id) => allToolIds.add(id));
95
+ }
96
+ // Resolve each tool
97
+ for (const toolId of allToolIds) {
98
+ const config = this.resolveTool(toolId, input.itemConfig, input.rosterConfig, input.studentProfile);
99
+ if (config) {
100
+ resolved.set(toolId, config);
101
+ }
102
+ }
103
+ return resolved;
104
+ }
105
+ /**
106
+ * Check if a tool is enabled
107
+ *
108
+ * @param toolId Tool identifier
109
+ * @param input Configuration input
110
+ * @returns true if tool is enabled
111
+ */
112
+ isToolEnabled(toolId, input) {
113
+ const config = this.resolveTool(toolId, input.itemConfig, input.rosterConfig, input.studentProfile);
114
+ return config?.enabled ?? false;
115
+ }
116
+ /**
117
+ * Check if a tool is required
118
+ *
119
+ * @param toolId Tool identifier
120
+ * @param input Configuration input
121
+ * @returns true if tool is required
122
+ */
123
+ isToolRequired(toolId, input) {
124
+ const config = this.resolveTool(toolId, input.itemConfig, input.rosterConfig, input.studentProfile);
125
+ return config?.required ?? false;
126
+ }
127
+ /**
128
+ * Get tool type (e.g., 'scientific' for calculator)
129
+ *
130
+ * @param toolId Tool identifier
131
+ * @param input Configuration input
132
+ * @returns Tool type or null
133
+ */
134
+ getToolType(toolId, input) {
135
+ const config = this.resolveTool(toolId, input.itemConfig, input.rosterConfig, input.studentProfile);
136
+ return config?.type ?? null;
137
+ }
138
+ /**
139
+ * Get tool settings
140
+ *
141
+ * @param toolId Tool identifier
142
+ * @param input Configuration input
143
+ * @returns Tool settings or null
144
+ */
145
+ getToolSettings(toolId, input) {
146
+ const config = this.resolveTool(toolId, input.itemConfig, input.rosterConfig, input.studentProfile);
147
+ return config?.settings ?? null;
148
+ }
149
+ /**
150
+ * Get list of all enabled tools
151
+ *
152
+ * @param input Configuration input
153
+ * @returns Array of enabled tool IDs
154
+ */
155
+ getEnabledTools(input) {
156
+ const resolved = this.resolveAll(input);
157
+ return Array.from(resolved.entries())
158
+ .filter(([_, config]) => config.enabled)
159
+ .map(([toolId]) => toolId);
160
+ }
161
+ /**
162
+ * Get list of required tools
163
+ *
164
+ * @param input Configuration input
165
+ * @returns Array of required tool IDs
166
+ */
167
+ getRequiredTools(input) {
168
+ const resolved = this.resolveAll(input);
169
+ return Array.from(resolved.entries())
170
+ .filter(([_, config]) => config.required)
171
+ .map(([toolId]) => toolId);
172
+ }
173
+ /**
174
+ * Validate that all required tools are available
175
+ *
176
+ * @param availableTools Set of available tool IDs
177
+ * @param input Configuration input
178
+ * @returns Object with validation result
179
+ */
180
+ validate(availableTools, input) {
181
+ const requiredTools = this.getRequiredTools(input);
182
+ const missingTools = requiredTools.filter((toolId) => !availableTools.has(toolId));
183
+ return {
184
+ valid: missingTools.length === 0,
185
+ missingTools,
186
+ };
187
+ }
188
+ /**
189
+ * Merge multiple roster configurations (for complex assessments)
190
+ *
191
+ * More restrictive settings win (blocked > allowed).
192
+ *
193
+ * @param configs Array of roster configurations
194
+ * @returns Merged configuration
195
+ */
196
+ mergeRosterConfigs(...configs) {
197
+ const merged = {};
198
+ for (const config of configs) {
199
+ for (const [toolId, allowance] of Object.entries(config)) {
200
+ // If any config blocks the tool, it's blocked
201
+ if (allowance === "0") {
202
+ merged[toolId] = "0";
203
+ }
204
+ else if (!merged[toolId]) {
205
+ // If not already set, use this allowance
206
+ merged[toolId] = allowance;
207
+ }
208
+ }
209
+ }
210
+ return merged;
211
+ }
212
+ /**
213
+ * Merge multiple student accommodation profiles
214
+ *
215
+ * Union of all accommodations.
216
+ *
217
+ * @param profiles Array of student profiles
218
+ * @returns Merged profile
219
+ */
220
+ mergeStudentProfiles(...profiles) {
221
+ const allAccommodations = new Set();
222
+ for (const profile of profiles) {
223
+ profile.accommodations.forEach((acc) => allAccommodations.add(acc));
224
+ }
225
+ return {
226
+ accommodations: Array.from(allAccommodations),
227
+ };
228
+ }
229
+ }
230
+ //# sourceMappingURL=ToolConfigResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolConfigResolver.js","sourceRoot":"","sources":["../../src/services/ToolConfigResolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * ToolCoordinator
3
+ *
4
+ * Manages z-index layering and visibility for floating tools.
5
+ * Prevents conflicts between calculator, ruler, protractor, etc.
6
+ *
7
+ * Features:
8
+ * - Centralized z-index management with defined layers
9
+ * - Tool visibility state tracking
10
+ * - Bring-to-front on interaction
11
+ * - Framework-agnostic (works with any DOM element)
12
+ *
13
+ * Part of PIE Assessment Toolkit.
14
+ */
15
+ import type { IToolCoordinator, ToolState } from "./interfaces";
16
+ /**
17
+ * Z-index layers for assessment components
18
+ */
19
+ export declare enum ZIndexLayer {
20
+ BASE = 0,// PIE content, player chrome (0-999)
21
+ TOOL = 1000,// Non-modal tools (ruler, protractor) (1000-1999)
22
+ MODAL = 2000,// Modal tools (calculator, dictionary) (2000-2999)
23
+ CONTROL = 3000,// Drag handles, resize controls (3000-3999)
24
+ HIGHLIGHT = 4000
25
+ }
26
+ /**
27
+ * Configuration for ToolCoordinator
28
+ * Currently empty but allows future extension without breaking changes
29
+ */
30
+ export type ToolCoordinatorConfig = Record<string, never>;
31
+ export declare class ToolCoordinator implements IToolCoordinator {
32
+ private config;
33
+ private tools;
34
+ private layerCounters;
35
+ private listeners;
36
+ constructor(config?: ToolCoordinatorConfig);
37
+ /**
38
+ * Subscribe to tool state changes
39
+ * Returns unsubscribe function
40
+ */
41
+ subscribe(listener: () => void): () => void;
42
+ /**
43
+ * Notify all listeners of state change
44
+ */
45
+ private notifyListeners;
46
+ /**
47
+ * Register a tool with the coordinator
48
+ *
49
+ * @param id Unique tool identifier
50
+ * @param name Display name
51
+ * @param element DOM element for the tool (optional for backward compatibility)
52
+ * @param layer Z-index layer (defaults to MODAL)
53
+ */
54
+ registerTool(id: string, name: string, element?: HTMLElement, layer?: ZIndexLayer): void;
55
+ /**
56
+ * Unregister a tool
57
+ *
58
+ * @param id Tool identifier
59
+ */
60
+ unregisterTool(id: string): void;
61
+ /**
62
+ * Show a tool
63
+ *
64
+ * @param id Tool identifier
65
+ */
66
+ showTool(id: string): void;
67
+ /**
68
+ * Hide a tool
69
+ *
70
+ * @param id Tool identifier
71
+ */
72
+ hideTool(id: string): void;
73
+ /**
74
+ * Toggle tool visibility
75
+ *
76
+ * @param id Tool identifier
77
+ */
78
+ toggleTool(id: string): void;
79
+ /**
80
+ * Check if tool is visible
81
+ *
82
+ * @param id Tool identifier
83
+ * @returns true if tool is visible
84
+ */
85
+ isToolVisible(id: string): boolean;
86
+ /**
87
+ * Bring element to front of its layer
88
+ *
89
+ * @param element DOM element to bring forward
90
+ */
91
+ bringToFront(element: HTMLElement): void;
92
+ /**
93
+ * Get all registered tool IDs
94
+ */
95
+ getRegisteredTools(): string[];
96
+ /**
97
+ * Get tool element by ID
98
+ */
99
+ getToolElement(id: string): HTMLElement | null;
100
+ /**
101
+ * Get next offset within a layer
102
+ */
103
+ private getNextLayerOffset;
104
+ /**
105
+ * Get maximum z-index currently in use in a layer
106
+ */
107
+ private getMaxZIndexInLayer;
108
+ /**
109
+ * Reset all tools to their base z-indices
110
+ */
111
+ resetZIndices(): void;
112
+ /**
113
+ * Update tool element reference (backward compatibility)
114
+ *
115
+ * @param id Tool identifier
116
+ * @param element New DOM element
117
+ */
118
+ updateToolElement(id: string, element: HTMLElement): void;
119
+ /**
120
+ * Hide all tools (backward compatibility)
121
+ */
122
+ hideAllTools(): void;
123
+ /**
124
+ * Get tool state (interface method)
125
+ *
126
+ * @param id Tool identifier
127
+ * @returns Tool state or undefined
128
+ */
129
+ getToolState(id: string): ToolState | undefined;
130
+ /**
131
+ * Get all visible tools (interface method)
132
+ *
133
+ * @returns Array of visible tool states
134
+ */
135
+ getVisibleTools(): ToolState[];
136
+ }
137
+ //# sourceMappingURL=ToolCoordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/ToolCoordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIhE;;GAEG;AACH,oBAAY,WAAW;IACtB,IAAI,IAAI,CAAE,qCAAqC;IAC/C,IAAI,OAAO,CAAE,kDAAkD;IAC/D,KAAK,OAAO,CAAE,mDAAmD;IACjE,OAAO,OAAO,CAAE,4CAA4C;IAC5D,SAAS,OAAO;CAChB;AAeD;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1D,qBAAa,eAAgB,YAAW,gBAAgB;IACvD,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,SAAS,CAAyB;gBAE9B,MAAM,GAAE,qBAA0B;IAU9C;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;;OAOG;IACH,YAAY,CACX,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,WAAW,EACrB,KAAK,GAAE,WAA+B,GACpC,IAAI;IA8CP;;;;OAIG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAYhC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAe1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAc1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAmB5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAKlC;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAgBxC;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI9C;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,aAAa,IAAI,IAAI;IAQrB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IA6BzD;;OAEG;IACH,YAAY,IAAI,IAAI;IAOpB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAa/C;;;;OAIG;IACH,eAAe,IAAI,SAAS,EAAE;CAW9B"}
@@ -0,0 +1,318 @@
1
+ /**
2
+ * ToolCoordinator
3
+ *
4
+ * Manages z-index layering and visibility for floating tools.
5
+ * Prevents conflicts between calculator, ruler, protractor, etc.
6
+ *
7
+ * Features:
8
+ * - Centralized z-index management with defined layers
9
+ * - Tool visibility state tracking
10
+ * - Bring-to-front on interaction
11
+ * - Framework-agnostic (works with any DOM element)
12
+ *
13
+ * Part of PIE Assessment Toolkit.
14
+ */
15
+ import { createLogger } from "../utils/logger";
16
+ const log = createLogger("ToolCoordinator");
17
+ /**
18
+ * Z-index layers for assessment components
19
+ */
20
+ export var ZIndexLayer;
21
+ (function (ZIndexLayer) {
22
+ ZIndexLayer[ZIndexLayer["BASE"] = 0] = "BASE";
23
+ ZIndexLayer[ZIndexLayer["TOOL"] = 1000] = "TOOL";
24
+ ZIndexLayer[ZIndexLayer["MODAL"] = 2000] = "MODAL";
25
+ ZIndexLayer[ZIndexLayer["CONTROL"] = 3000] = "CONTROL";
26
+ ZIndexLayer[ZIndexLayer["HIGHLIGHT"] = 4000] = "HIGHLIGHT";
27
+ })(ZIndexLayer || (ZIndexLayer = {}));
28
+ export class ToolCoordinator {
29
+ config;
30
+ tools = new Map();
31
+ layerCounters = new Map();
32
+ listeners = new Set();
33
+ constructor(config = {}) {
34
+ this.config = config;
35
+ // Initialize layer counters
36
+ this.layerCounters.set(ZIndexLayer.BASE, 0);
37
+ this.layerCounters.set(ZIndexLayer.TOOL, 0);
38
+ this.layerCounters.set(ZIndexLayer.MODAL, 0);
39
+ this.layerCounters.set(ZIndexLayer.CONTROL, 0);
40
+ this.layerCounters.set(ZIndexLayer.HIGHLIGHT, 0);
41
+ }
42
+ /**
43
+ * Subscribe to tool state changes
44
+ * Returns unsubscribe function
45
+ */
46
+ subscribe(listener) {
47
+ this.listeners.add(listener);
48
+ return () => {
49
+ this.listeners.delete(listener);
50
+ };
51
+ }
52
+ /**
53
+ * Notify all listeners of state change
54
+ */
55
+ notifyListeners() {
56
+ this.listeners.forEach((listener) => listener());
57
+ }
58
+ /**
59
+ * Register a tool with the coordinator
60
+ *
61
+ * @param id Unique tool identifier
62
+ * @param name Display name
63
+ * @param element DOM element for the tool (optional for backward compatibility)
64
+ * @param layer Z-index layer (defaults to MODAL)
65
+ */
66
+ registerTool(id, name, element, layer = ZIndexLayer.MODAL) {
67
+ log("registerTool called:", { id, name, hasElement: !!element, layer });
68
+ if (this.tools.has(id)) {
69
+ log(`Tool ${id} is already registered`);
70
+ return;
71
+ }
72
+ // If no element provided, create a placeholder registration
73
+ if (!element) {
74
+ this.tools.set(id, {
75
+ id,
76
+ name,
77
+ element: null,
78
+ layer,
79
+ isVisible: false,
80
+ baseZIndex: layer,
81
+ });
82
+ log("Tool registered without element:", id);
83
+ return;
84
+ }
85
+ // Calculate base z-index for this layer
86
+ const baseZIndex = layer + this.getNextLayerOffset(layer);
87
+ // Apply z-index
88
+ element.style.zIndex = String(baseZIndex);
89
+ // Create and store event handler to enable proper cleanup
90
+ const mouseDownHandler = () => this.bringToFront(element);
91
+ element.addEventListener("mousedown", mouseDownHandler);
92
+ // Register tool with handler reference
93
+ this.tools.set(id, {
94
+ id,
95
+ name,
96
+ element,
97
+ layer,
98
+ isVisible: false,
99
+ baseZIndex,
100
+ mouseDownHandler,
101
+ });
102
+ log("Tool registered with element:", id);
103
+ }
104
+ /**
105
+ * Unregister a tool
106
+ *
107
+ * @param id Tool identifier
108
+ */
109
+ unregisterTool(id) {
110
+ const tool = this.tools.get(id);
111
+ if (!tool)
112
+ return;
113
+ // Remove event listeners using stored handler reference
114
+ if (tool.element && tool.mouseDownHandler) {
115
+ tool.element.removeEventListener("mousedown", tool.mouseDownHandler);
116
+ }
117
+ this.tools.delete(id);
118
+ }
119
+ /**
120
+ * Show a tool
121
+ *
122
+ * @param id Tool identifier
123
+ */
124
+ showTool(id) {
125
+ const tool = this.tools.get(id);
126
+ if (!tool) {
127
+ log(`Tool ${id} not found`);
128
+ return;
129
+ }
130
+ if (tool.element) {
131
+ tool.element.style.display = "";
132
+ this.bringToFront(tool.element);
133
+ }
134
+ tool.isVisible = true;
135
+ this.notifyListeners();
136
+ }
137
+ /**
138
+ * Hide a tool
139
+ *
140
+ * @param id Tool identifier
141
+ */
142
+ hideTool(id) {
143
+ const tool = this.tools.get(id);
144
+ if (!tool) {
145
+ log(`Tool ${id} not found`);
146
+ return;
147
+ }
148
+ if (tool.element) {
149
+ tool.element.style.display = "none";
150
+ }
151
+ tool.isVisible = false;
152
+ this.notifyListeners();
153
+ }
154
+ /**
155
+ * Toggle tool visibility
156
+ *
157
+ * @param id Tool identifier
158
+ */
159
+ toggleTool(id) {
160
+ log("toggleTool called for:", id);
161
+ const tool = this.tools.get(id);
162
+ if (!tool) {
163
+ log(`Tool ${id} not found. Registered tools:`, Array.from(this.tools.keys()));
164
+ return;
165
+ }
166
+ log("Tool found, current visibility:", tool.isVisible);
167
+ if (tool.isVisible) {
168
+ this.hideTool(id);
169
+ }
170
+ else {
171
+ this.showTool(id);
172
+ }
173
+ }
174
+ /**
175
+ * Check if tool is visible
176
+ *
177
+ * @param id Tool identifier
178
+ * @returns true if tool is visible
179
+ */
180
+ isToolVisible(id) {
181
+ const tool = this.tools.get(id);
182
+ return tool?.isVisible ?? false;
183
+ }
184
+ /**
185
+ * Bring element to front of its layer
186
+ *
187
+ * @param element DOM element to bring forward
188
+ */
189
+ bringToFront(element) {
190
+ // Find tool registration
191
+ const tool = Array.from(this.tools.values()).find((t) => t.element === element);
192
+ if (!tool)
193
+ return;
194
+ // Calculate new z-index (highest in layer + 1)
195
+ const maxZIndexInLayer = this.getMaxZIndexInLayer(tool.layer);
196
+ const newZIndex = Math.max(maxZIndexInLayer + 1, tool.layer + 1);
197
+ // Update z-index
198
+ element.style.zIndex = String(newZIndex);
199
+ tool.baseZIndex = newZIndex;
200
+ }
201
+ /**
202
+ * Get all registered tool IDs
203
+ */
204
+ getRegisteredTools() {
205
+ return Array.from(this.tools.keys());
206
+ }
207
+ /**
208
+ * Get tool element by ID
209
+ */
210
+ getToolElement(id) {
211
+ return this.tools.get(id)?.element ?? null;
212
+ }
213
+ /**
214
+ * Get next offset within a layer
215
+ */
216
+ getNextLayerOffset(layer) {
217
+ const current = this.layerCounters.get(layer) ?? 0;
218
+ this.layerCounters.set(layer, current + 1);
219
+ return current;
220
+ }
221
+ /**
222
+ * Get maximum z-index currently in use in a layer
223
+ */
224
+ getMaxZIndexInLayer(layer) {
225
+ let max = layer;
226
+ for (const tool of this.tools.values()) {
227
+ if (tool.layer === layer) {
228
+ max = Math.max(max, tool.baseZIndex);
229
+ }
230
+ }
231
+ return max;
232
+ }
233
+ /**
234
+ * Reset all tools to their base z-indices
235
+ */
236
+ resetZIndices() {
237
+ for (const tool of this.tools.values()) {
238
+ if (tool.element) {
239
+ tool.element.style.zIndex = String(tool.baseZIndex);
240
+ }
241
+ }
242
+ }
243
+ /**
244
+ * Update tool element reference (backward compatibility)
245
+ *
246
+ * @param id Tool identifier
247
+ * @param element New DOM element
248
+ */
249
+ updateToolElement(id, element) {
250
+ const tool = this.tools.get(id);
251
+ if (!tool) {
252
+ log(`Tool ${id} not found`);
253
+ return;
254
+ }
255
+ // Remove old event listener using stored handler reference
256
+ if (tool.element && tool.mouseDownHandler) {
257
+ tool.element.removeEventListener("mousedown", tool.mouseDownHandler);
258
+ }
259
+ // Create new handler and add listener
260
+ const mouseDownHandler = () => this.bringToFront(element);
261
+ element.addEventListener("mousedown", mouseDownHandler);
262
+ // Update element and handler reference
263
+ tool.element = element;
264
+ tool.mouseDownHandler = mouseDownHandler;
265
+ // Apply z-index to new element
266
+ element.style.zIndex = String(tool.baseZIndex);
267
+ if (tool.isVisible) {
268
+ element.style.display = "";
269
+ }
270
+ else {
271
+ element.style.display = "none";
272
+ }
273
+ }
274
+ /**
275
+ * Hide all tools (backward compatibility)
276
+ */
277
+ hideAllTools() {
278
+ for (const id of this.tools.keys()) {
279
+ this.hideTool(id);
280
+ }
281
+ this.notifyListeners();
282
+ }
283
+ /**
284
+ * Get tool state (interface method)
285
+ *
286
+ * @param id Tool identifier
287
+ * @returns Tool state or undefined
288
+ */
289
+ getToolState(id) {
290
+ const tool = this.tools.get(id);
291
+ if (!tool)
292
+ return undefined;
293
+ return {
294
+ id: tool.id,
295
+ name: tool.name,
296
+ isVisible: tool.isVisible,
297
+ element: tool.element ?? null,
298
+ layer: tool.layer,
299
+ };
300
+ }
301
+ /**
302
+ * Get all visible tools (interface method)
303
+ *
304
+ * @returns Array of visible tool states
305
+ */
306
+ getVisibleTools() {
307
+ return Array.from(this.tools.values())
308
+ .filter((tool) => tool.isVisible)
309
+ .map((tool) => ({
310
+ id: tool.id,
311
+ name: tool.name,
312
+ isVisible: tool.isVisible,
313
+ element: tool.element ?? null,
314
+ layer: tool.layer,
315
+ }));
316
+ }
317
+ }
318
+ //# sourceMappingURL=ToolCoordinator.js.map