@pie-players/pie-assessment-toolkit 0.3.61 → 0.3.63

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 (270) hide show
  1. package/dist/attempt/AssessmentSession.js +0 -1
  2. package/dist/attempt/TestSession.js +0 -1
  3. package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -1
  4. package/dist/components/ItemToolBar.custom-element.js +1 -10106
  5. package/dist/components/PieAssessmentToolkit.custom-element.js +48 -29930
  6. package/dist/components/SectionToolBar.custom-element.js +1 -14372
  7. package/dist/components/chunks/ItemToolBar-843902tp.js +51 -0
  8. package/dist/components/chunks/ItemToolBar-84nv78dy.js +22 -0
  9. package/dist/components/item-toolbar-element.js +0 -1
  10. package/dist/components/pie-assessment-toolkit-element.js +0 -1
  11. package/dist/components/section-toolbar-element.js +0 -1
  12. package/dist/context/assessment-toolkit-context.js +0 -1
  13. package/dist/context/runtime-context-consumer.js +0 -1
  14. package/dist/index.js +0 -1
  15. package/dist/item-loader.js +0 -1
  16. package/dist/policy/core/PolicySource.js +0 -1
  17. package/dist/policy/core/ToolPolicyEngine.js +0 -1
  18. package/dist/policy/core/compose-decision.js +0 -1
  19. package/dist/policy/core/decision-types.js +0 -1
  20. package/dist/policy/core/engine-context.js +0 -1
  21. package/dist/policy/core/pnp-policy-inputs.js +0 -1
  22. package/dist/policy/core/policy-source-tag.js +0 -1
  23. package/dist/policy/core/provenance.js +0 -1
  24. package/dist/policy/engine.js +0 -1
  25. package/dist/policy/internal.js +0 -1
  26. package/dist/policy/sources/PnpPolicySource.js +0 -1
  27. package/dist/runtime/RuntimeRegistry.js +0 -1
  28. package/dist/runtime/SectionRuntimeEngine.js +0 -1
  29. package/dist/runtime/adapter/SectionEngineAdapter.js +0 -1
  30. package/dist/runtime/adapter/coordinator-bridge.js +0 -1
  31. package/dist/runtime/adapter/dom-event-bridge.js +0 -1
  32. package/dist/runtime/adapter/framework-error-bridge.js +0 -1
  33. package/dist/runtime/adapter/instrumentation-bridge.js +0 -1
  34. package/dist/runtime/adapter/subscriber-fanout.js +0 -1
  35. package/dist/runtime/catalog-registration.js +0 -1
  36. package/dist/runtime/core/SectionEngineCore.js +0 -1
  37. package/dist/runtime/core/cohort.js +0 -1
  38. package/dist/runtime/core/engine-input.js +0 -1
  39. package/dist/runtime/core/engine-output.js +0 -1
  40. package/dist/runtime/core/engine-readiness.js +0 -1
  41. package/dist/runtime/core/engine-resolver.js +0 -1
  42. package/dist/runtime/core/engine-stage-derivation.js +0 -1
  43. package/dist/runtime/core/engine-state.js +0 -1
  44. package/dist/runtime/core/engine-transition.js +0 -1
  45. package/dist/runtime/engine-context.js +0 -1
  46. package/dist/runtime/engine.js +0 -1
  47. package/dist/runtime/internal.js +0 -1
  48. package/dist/runtime/registration-events.js +0 -1
  49. package/dist/runtime/runtime-id.js +0 -1
  50. package/dist/runtime/section-runtime-engine-host-context.js +0 -1
  51. package/dist/runtime/session-event-emitter-policy.js +0 -1
  52. package/dist/runtime/stage-emit-gate.js +0 -1
  53. package/dist/runtime/tool-host-contract.js +0 -1
  54. package/dist/services/AccessibilityCatalogResolver.js +0 -1
  55. package/dist/services/ContextVariableStore.js +0 -1
  56. package/dist/services/ElementToolStateStore.js +0 -1
  57. package/dist/services/HighlightCoordinator.js +35 -3
  58. package/dist/services/I18nService.js +0 -1
  59. package/dist/services/RangeSerializer.js +0 -1
  60. package/dist/services/SSMLExtractor.js +0 -1
  61. package/dist/services/TTSService.js +0 -1
  62. package/dist/services/ThemeProvider.js +0 -1
  63. package/dist/services/ToolConfigResolver.js +0 -1
  64. package/dist/services/ToolCoordinator.js +0 -1
  65. package/dist/services/ToolRegistry.js +0 -1
  66. package/dist/services/ToolkitCoordinator.js +0 -1
  67. package/dist/services/create-tools-config.js +0 -1
  68. package/dist/services/createDefaultToolRegistry.js +0 -1
  69. package/dist/services/defaultPersonalNeedsProfile.js +0 -1
  70. package/dist/services/framework-error-bus.js +0 -1
  71. package/dist/services/framework-error.js +0 -1
  72. package/dist/services/interfaces.js +0 -1
  73. package/dist/services/pnp-standard-features.js +0 -1
  74. package/dist/services/section-controller-types.js +0 -1
  75. package/dist/services/tool-config-defaults.js +0 -1
  76. package/dist/services/tool-config-validation.js +0 -1
  77. package/dist/services/tool-context.js +0 -1
  78. package/dist/services/tool-instance-id.js +0 -1
  79. package/dist/services/tool-providers/DesmosToolProvider.js +0 -1
  80. package/dist/services/tool-providers/TTSToolProvider.js +0 -1
  81. package/dist/services/tool-providers/ToolProviderApi.js +0 -1
  82. package/dist/services/tool-providers/ToolProviderRegistry.js +0 -1
  83. package/dist/services/tool-providers/index.js +0 -1
  84. package/dist/services/toolbar-items.js +0 -1
  85. package/dist/services/tools-config-normalizer.js +0 -1
  86. package/dist/services/tts/browser-provider.js +0 -1
  87. package/dist/services/tts/catalog-span-alignment.js +0 -1
  88. package/dist/services/tts/generated-speech/assemble-plan.js +0 -1
  89. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +0 -1
  90. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.js +0 -1
  91. package/dist/services/tts/generated-speech/dom/types.js +0 -1
  92. package/dist/services/tts/generated-speech/index.js +0 -1
  93. package/dist/services/tts/generated-speech/math-speech-cache.js +0 -1
  94. package/dist/services/tts/generated-speech/types.js +0 -1
  95. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +0 -1
  96. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +0 -1
  97. package/dist/services/tts/highlight-pipeline/highlight-policy.js +0 -1
  98. package/dist/services/tts/highlight-pipeline/index.js +0 -1
  99. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.js +0 -1
  100. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +0 -1
  101. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +0 -1
  102. package/dist/services/tts/highlight-pipeline/readable-region.js +0 -1
  103. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.js +0 -1
  104. package/dist/services/tts/highlight-pipeline/types.js +0 -1
  105. package/dist/services/tts/highlight-pipeline/visible-map-range.js +0 -1
  106. package/dist/services/tts/highlight-target-resolver.js +0 -1
  107. package/dist/services/tts/math-alignment/index.js +0 -1
  108. package/dist/services/tts/math-alignment/mathml-tokenizer.js +0 -1
  109. package/dist/services/tts/math-alignment/range-resolver.js +0 -1
  110. package/dist/services/tts/math-alignment/sequence-aligner.js +0 -1
  111. package/dist/services/tts/math-alignment/speech-tokenizer.js +0 -1
  112. package/dist/services/tts/math-alignment/types.js +0 -1
  113. package/dist/services/tts/math-aware-text-processing.js +0 -1
  114. package/dist/services/tts/math-speech.js +0 -1
  115. package/dist/services/tts/mathml-sanitization.js +0 -1
  116. package/dist/services/tts/ssml/spoken-text.js +0 -1
  117. package/dist/services/tts/text-processing.js +0 -1
  118. package/dist/services/tts/text-segmentation.js +0 -1
  119. package/dist/services/tts/visual-line-ranges.js +0 -1
  120. package/dist/services/tts-control-events.js +0 -1
  121. package/dist/services/tts-runtime-config.js +0 -1
  122. package/dist/tools/calculators/desmos-provider.js +0 -1
  123. package/dist/tools/client.js +0 -1
  124. package/dist/tools/index.js +0 -1
  125. package/dist/tools/library-loader.js +0 -1
  126. package/dist/tools/registrations/accessibility-tools.js +0 -1
  127. package/dist/tools/registrations/calculator.js +0 -1
  128. package/dist/tools/registrations/interaction-tools.js +0 -1
  129. package/dist/tools/registrations/measurement-tools.js +0 -1
  130. package/dist/tools/registrations/subject-specific-tools.js +0 -1
  131. package/dist/tools/registrations/toolbar-registration-helpers.js +0 -1
  132. package/dist/tools/registrations/tts.js +0 -1
  133. package/dist/tools/response-discovery.js +0 -1
  134. package/dist/tools/tool-tag-map.js +0 -1
  135. package/dist/tools/types.js +0 -1
  136. package/dist/tools/variant-resolver.js +0 -1
  137. package/dist/utils/logger.js +0 -1
  138. package/package.json +13 -11
  139. package/dist/attempt/AssessmentSession.js.map +0 -1
  140. package/dist/attempt/TestSession.js.map +0 -1
  141. package/dist/attempt/adapters/activity-to-test-attempt-session.js.map +0 -1
  142. package/dist/components/item-toolbar-element.js.map +0 -1
  143. package/dist/components/pie-assessment-toolkit-element.js.map +0 -1
  144. package/dist/components/section-toolbar-element.js.map +0 -1
  145. package/dist/context/assessment-toolkit-context.js.map +0 -1
  146. package/dist/context/runtime-context-consumer.js.map +0 -1
  147. package/dist/index.js.map +0 -1
  148. package/dist/item-loader.js.map +0 -1
  149. package/dist/policy/core/PolicySource.js.map +0 -1
  150. package/dist/policy/core/ToolPolicyEngine.js.map +0 -1
  151. package/dist/policy/core/compose-decision.js.map +0 -1
  152. package/dist/policy/core/decision-types.js.map +0 -1
  153. package/dist/policy/core/engine-context.js.map +0 -1
  154. package/dist/policy/core/pnp-policy-inputs.js.map +0 -1
  155. package/dist/policy/core/policy-source-tag.js.map +0 -1
  156. package/dist/policy/core/provenance.js.map +0 -1
  157. package/dist/policy/engine.js.map +0 -1
  158. package/dist/policy/internal.js.map +0 -1
  159. package/dist/policy/sources/PnpPolicySource.js.map +0 -1
  160. package/dist/runtime/RuntimeRegistry.js.map +0 -1
  161. package/dist/runtime/SectionRuntimeEngine.js.map +0 -1
  162. package/dist/runtime/adapter/SectionEngineAdapter.js.map +0 -1
  163. package/dist/runtime/adapter/coordinator-bridge.js.map +0 -1
  164. package/dist/runtime/adapter/dom-event-bridge.js.map +0 -1
  165. package/dist/runtime/adapter/framework-error-bridge.js.map +0 -1
  166. package/dist/runtime/adapter/instrumentation-bridge.js.map +0 -1
  167. package/dist/runtime/adapter/subscriber-fanout.js.map +0 -1
  168. package/dist/runtime/catalog-registration.js.map +0 -1
  169. package/dist/runtime/core/SectionEngineCore.js.map +0 -1
  170. package/dist/runtime/core/cohort.js.map +0 -1
  171. package/dist/runtime/core/engine-input.js.map +0 -1
  172. package/dist/runtime/core/engine-output.js.map +0 -1
  173. package/dist/runtime/core/engine-readiness.js.map +0 -1
  174. package/dist/runtime/core/engine-resolver.js.map +0 -1
  175. package/dist/runtime/core/engine-stage-derivation.js.map +0 -1
  176. package/dist/runtime/core/engine-state.js.map +0 -1
  177. package/dist/runtime/core/engine-transition.js.map +0 -1
  178. package/dist/runtime/engine-context.js.map +0 -1
  179. package/dist/runtime/engine.js.map +0 -1
  180. package/dist/runtime/internal.js.map +0 -1
  181. package/dist/runtime/registration-events.js.map +0 -1
  182. package/dist/runtime/runtime-id.js.map +0 -1
  183. package/dist/runtime/section-runtime-engine-host-context.js.map +0 -1
  184. package/dist/runtime/session-event-emitter-policy.js.map +0 -1
  185. package/dist/runtime/stage-emit-gate.js.map +0 -1
  186. package/dist/runtime/tool-host-contract.js.map +0 -1
  187. package/dist/services/AccessibilityCatalogResolver.js.map +0 -1
  188. package/dist/services/ContextVariableStore.js.map +0 -1
  189. package/dist/services/ElementToolStateStore.js.map +0 -1
  190. package/dist/services/HighlightCoordinator.js.map +0 -1
  191. package/dist/services/I18nService.js.map +0 -1
  192. package/dist/services/RangeSerializer.js.map +0 -1
  193. package/dist/services/SSMLExtractor.js.map +0 -1
  194. package/dist/services/TTSService.js.map +0 -1
  195. package/dist/services/ThemeProvider.js.map +0 -1
  196. package/dist/services/ToolConfigResolver.js.map +0 -1
  197. package/dist/services/ToolCoordinator.js.map +0 -1
  198. package/dist/services/ToolRegistry.js.map +0 -1
  199. package/dist/services/ToolkitCoordinator.js.map +0 -1
  200. package/dist/services/create-tools-config.js.map +0 -1
  201. package/dist/services/createDefaultToolRegistry.js.map +0 -1
  202. package/dist/services/defaultPersonalNeedsProfile.js.map +0 -1
  203. package/dist/services/framework-error-bus.js.map +0 -1
  204. package/dist/services/framework-error.js.map +0 -1
  205. package/dist/services/interfaces.js.map +0 -1
  206. package/dist/services/pnp-standard-features.js.map +0 -1
  207. package/dist/services/section-controller-types.js.map +0 -1
  208. package/dist/services/tool-config-defaults.js.map +0 -1
  209. package/dist/services/tool-config-validation.js.map +0 -1
  210. package/dist/services/tool-context.js.map +0 -1
  211. package/dist/services/tool-instance-id.js.map +0 -1
  212. package/dist/services/tool-providers/DesmosToolProvider.js.map +0 -1
  213. package/dist/services/tool-providers/TTSToolProvider.js.map +0 -1
  214. package/dist/services/tool-providers/ToolProviderApi.js.map +0 -1
  215. package/dist/services/tool-providers/ToolProviderRegistry.js.map +0 -1
  216. package/dist/services/tool-providers/index.js.map +0 -1
  217. package/dist/services/toolbar-items.js.map +0 -1
  218. package/dist/services/tools-config-normalizer.js.map +0 -1
  219. package/dist/services/tts/browser-provider.js.map +0 -1
  220. package/dist/services/tts/catalog-span-alignment.js.map +0 -1
  221. package/dist/services/tts/generated-speech/assemble-plan.js.map +0 -1
  222. package/dist/services/tts/generated-speech/dom/build-dom-plan.js.map +0 -1
  223. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.js.map +0 -1
  224. package/dist/services/tts/generated-speech/dom/types.js.map +0 -1
  225. package/dist/services/tts/generated-speech/index.js.map +0 -1
  226. package/dist/services/tts/generated-speech/math-speech-cache.js.map +0 -1
  227. package/dist/services/tts/generated-speech/types.js.map +0 -1
  228. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js.map +0 -1
  229. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js.map +0 -1
  230. package/dist/services/tts/highlight-pipeline/highlight-policy.js.map +0 -1
  231. package/dist/services/tts/highlight-pipeline/index.js.map +0 -1
  232. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.js.map +0 -1
  233. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js.map +0 -1
  234. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js.map +0 -1
  235. package/dist/services/tts/highlight-pipeline/readable-region.js.map +0 -1
  236. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.js.map +0 -1
  237. package/dist/services/tts/highlight-pipeline/types.js.map +0 -1
  238. package/dist/services/tts/highlight-pipeline/visible-map-range.js.map +0 -1
  239. package/dist/services/tts/highlight-target-resolver.js.map +0 -1
  240. package/dist/services/tts/math-alignment/index.js.map +0 -1
  241. package/dist/services/tts/math-alignment/mathml-tokenizer.js.map +0 -1
  242. package/dist/services/tts/math-alignment/range-resolver.js.map +0 -1
  243. package/dist/services/tts/math-alignment/sequence-aligner.js.map +0 -1
  244. package/dist/services/tts/math-alignment/speech-tokenizer.js.map +0 -1
  245. package/dist/services/tts/math-alignment/types.js.map +0 -1
  246. package/dist/services/tts/math-aware-text-processing.js.map +0 -1
  247. package/dist/services/tts/math-speech.js.map +0 -1
  248. package/dist/services/tts/mathml-sanitization.js.map +0 -1
  249. package/dist/services/tts/ssml/spoken-text.js.map +0 -1
  250. package/dist/services/tts/text-processing.js.map +0 -1
  251. package/dist/services/tts/text-segmentation.js.map +0 -1
  252. package/dist/services/tts/visual-line-ranges.js.map +0 -1
  253. package/dist/services/tts-control-events.js.map +0 -1
  254. package/dist/services/tts-runtime-config.js.map +0 -1
  255. package/dist/tools/calculators/desmos-provider.js.map +0 -1
  256. package/dist/tools/client.js.map +0 -1
  257. package/dist/tools/index.js.map +0 -1
  258. package/dist/tools/library-loader.js.map +0 -1
  259. package/dist/tools/registrations/accessibility-tools.js.map +0 -1
  260. package/dist/tools/registrations/calculator.js.map +0 -1
  261. package/dist/tools/registrations/interaction-tools.js.map +0 -1
  262. package/dist/tools/registrations/measurement-tools.js.map +0 -1
  263. package/dist/tools/registrations/subject-specific-tools.js.map +0 -1
  264. package/dist/tools/registrations/toolbar-registration-helpers.js.map +0 -1
  265. package/dist/tools/registrations/tts.js.map +0 -1
  266. package/dist/tools/response-discovery.js.map +0 -1
  267. package/dist/tools/tool-tag-map.js.map +0 -1
  268. package/dist/tools/types.js.map +0 -1
  269. package/dist/tools/variant-resolver.js.map +0 -1
  270. package/dist/utils/logger.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"TTSService.js","sourceRoot":"","sources":["../../src/services/TTSService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TTSService\n *\n * Text-to-speech service with pluggable provider architecture.\n * Manages playback state, coordinates multiple TTS entry points,\n * and integrates with HighlightCoordinator for word highlighting.\n *\n * Features:\n * - Pluggable TTS providers (browser, AWS Polly, etc.)\n * - QTI 3.0 accessibility catalogs (pre-authored spoken content)\n * - Unified playback state management\n * - Prevents conflicts from simultaneous speech\n * - Word highlighting integration\n * - Playback controls: play, pause, resume, stop\n *\n * Part of PIE Assessment Toolkit.\n */\n\nimport type {\n\tITTSProvider,\n\tITTSProviderImplementation,\n\tTTSConfig,\n\tTTSProviderCapabilities,\n} from \"@pie-players/pie-tts\";\nimport type {\n\tAccessibilityCatalogResolver,\n\tCatalogLookupContext,\n\tResolvedCatalog,\n} from \"./AccessibilityCatalogResolver.js\";\nimport { HighlightColor, HighlightType } from \"./HighlightCoordinator.js\";\nimport type { HighlightCoordinatorApi } from \"./interfaces.js\";\nimport { BrowserTTSProvider } from \"./tts/browser-provider.js\";\nimport type {\n\tTTSHighlightContext,\n\tTTSHighlightTargetResolver,\n\tTTSHighlightTargetResolverProvider,\n\tTTSHighlightTargetResolverRuntime,\n} from \"./tts/highlight-target-resolver.js\";\nimport {\n\ttype BoundarySpacingMode,\n\tcollectVisibleTextAndMap,\n\tisElementHiddenForTTS,\n\tisNodeHiddenForTTS,\n\ttype NormalizedTextMap,\n\tnormalizeTextForSpeech,\n} from \"./tts/text-processing.js\";\nimport {\n\tcreateCatalogSpanAlignment,\n\ttype CatalogChunkPlaybackMode,\n\ttype CatalogSpanAlignment,\n} from \"./tts/catalog-span-alignment.js\";\nimport {\n\tcreateMathAwareAlignment,\n\ttype MathAwareAlignment,\n} from \"./tts/math-alignment/index.js\";\nimport { collectMathAwareTextAndMap } from \"./tts/math-aware-text-processing.js\";\nimport {\n\tbuildGeneratedSpeechFromRoot,\n\tcreateMemoizedMathSpeechResolver,\n\tplanToCompositionChunkInputs,\n\ttype MathSpeechResolver,\n} from \"./tts/generated-speech/index.js\";\nimport {\n\tnormalizeSREMathSpeechOptions,\n\ttype SREMathSpeechOptions,\n} from \"./tts/math-speech.js\";\nimport {\n\tsegmentSentences as segmentTextToSentences,\n\ttype SentenceSegment as SharedSentenceSegment,\n} from \"./tts/text-segmentation.js\";\nimport {\n\tcreateTTSHighlightPlan,\n\tnormalizeSpeechChunks,\n\tresolveReadableRegion,\n\ttype ChunkOffsetSpace,\n\ttype HighlightDecision,\n\ttype RenderableHighlightTarget,\n} from \"./tts/highlight-pipeline/index.js\";\nimport {\n\tPIE_TTS_CONTROL_HANDOFF_EVENT,\n\ttype TTSControlHandoffDetail,\n} from \"./tts-control-events.js\";\n\ninterface TTSSpeechSegment {\n\ttext: string;\n\tstartOffset: number;\n\tpauseMsAfter?: number;\n}\n\n// Re-export core TTS types for convenience\nexport type {\n\tITTSProvider,\n\tITTSProviderImplementation,\n\tTTSConfig,\n\tTTSFeature,\n\tTTSProviderCapabilities,\n} from \"@pie-players/pie-tts\";\n\n/**\n * Playback state\n */\nexport enum PlaybackState {\n\tIDLE = \"idle\",\n\tLOADING = \"loading\",\n\tPLAYING = \"playing\",\n\tPAUSED = \"paused\",\n\tERROR = \"error\",\n}\n\ntype StructuralPauseStrength = \"minor\" | \"section\" | \"major\";\n\ninterface StructuralPauseProfile {\n\tbaseMs: number;\n\tunits: Record<StructuralPauseStrength, number>;\n\tminMs: number;\n\tmaxMs: number;\n}\n\ntype HighlightMode = \"word\" | \"sentence\";\n\ninterface SpeakOptions {\n\tcatalogId?: string;\n\tcatalogContext?: CatalogLookupContext;\n\tignoreCatalogs?: boolean;\n\tlanguage?: string;\n\tcontentElement?: Element;\n\twordBoundaryOffset?: number;\n\thighlightModeOverride?: HighlightMode;\n}\n\ninterface SpeechCompositionChunk {\n\tspeechText: string;\n\tvisibleText: string;\n\tsourceElement: Element | null;\n\tregionElement?: Element | null;\n\tregionRange?: Range;\n\tspeechMatchesVisibleText: boolean;\n\tplaybackMode?: CatalogChunkPlaybackMode;\n\talignment?: CatalogSpanAlignment;\n\tmathAlignment?: MathAwareAlignment;\n\tmathAlignments?: Array<{ element: Element; alignment: MathAwareAlignment }>;\n\tvisibleMap?: NormalizedTextMap;\n\t// Plain-text variant for speak-time fallback (generated SSML math chunks).\n\t// If the provider rejects the SSML `speechText`, playback retries this.\n\tplainFallback?: SpeechCompositionChunk;\n}\n\ninterface ResolvedSpeechContent {\n\tcontentToSpeak: string;\n\tspeechText: string;\n\tvisibleText: string;\n\thighlightText: string;\n\tusedCatalogSpoken: boolean;\n\tspeechSource: \"catalog-spoken\" | \"dom-or-input\";\n\tnormalizedText: string;\n\tcontainsMathMarkup: boolean;\n\tspeechMatchesVisibleText: boolean;\n\tspeechChunks?: SpeechCompositionChunk[];\n}\n\nconst sameRange = (left: Range, right: Range): boolean =>\n\tleft === right ||\n\t(left.startContainer === right.startContainer &&\n\t\tleft.startOffset === right.startOffset &&\n\t\tleft.endContainer === right.endContainer &&\n\t\tleft.endOffset === right.endOffset);\n\nconst sameRenderableHighlightTarget = (\n\tleft: RenderableHighlightTarget | null,\n\tright: RenderableHighlightTarget | null,\n): boolean => {\n\tif (left === right) return true;\n\tif (\n\t\t!left ||\n\t\t!right ||\n\t\tleft.type !== right.type ||\n\t\tleft.quality !== right.quality\n\t) {\n\t\treturn false;\n\t}\n\tif (left.type === \"range\" && right.type === \"range\") {\n\t\treturn sameRange(left.range, right.range);\n\t}\n\tif (left.type === \"element\" && right.type === \"element\") {\n\t\treturn left.element === right.element;\n\t}\n\tif (left.type === \"text-range\" && right.type === \"text-range\") {\n\t\treturn (\n\t\t\tleft.node === right.node &&\n\t\t\tleft.startOffset === right.startOffset &&\n\t\t\tleft.endOffset === right.endOffset\n\t\t);\n\t}\n\treturn false;\n};\n\n/**\n * TTSService\n *\n * Instantiable service for text-to-speech functionality.\n * Each instance manages its own playback state.\n */\nexport class TTSService {\n\tprivate currentProvider: ITTSProvider | null = null;\n\tprivate provider: ITTSProviderImplementation | null = null;\n\tprivate highlightCoordinator: HighlightCoordinatorApi | null = null;\n\tprivate highlightTargetResolverProvider: TTSHighlightTargetResolverProvider | null =\n\t\tnull;\n\tprivate catalogResolver: AccessibilityCatalogResolver | null = null;\n\tprivate state: PlaybackState = PlaybackState.IDLE;\n\tprivate ttsConfig: Partial<TTSConfig> = {};\n\tprivate currentText: string | null = null;\n\tprivate currentContentElement: Element | null = null;\n\tprivate normalizedToDOM: Map<number, { node: Text; offset: number }> =\n\t\tnew Map();\n\tprivate listeners = new Map<string, Set<(state: PlaybackState) => void>>();\n\tprivate lastError: string | null = null;\n\tprivate speakRunId = 0;\n\tprivate currentBoundaryOffset = 0;\n\tprivate activeWordBoundaryOffset = 0;\n\tprivate seekSegments: TTSSpeechSegment[] = [];\n\tprivate playbackChunks: SpeechCompositionChunk[] = [];\n\tprivate sentenceHighlightSegments: TTSSpeechSegment[] = [];\n\tprivate currentSeekSegmentIndex = 0;\n\tprivate activeSentenceStartOffset: number | null = null;\n\tprivate activeHighlightMode: HighlightMode = \"word\";\n\tprivate lastRenderedRegionTarget: RenderableHighlightTarget | null = null;\n\tprivate telemetryReporter:\n\t\t| ((\n\t\t\t\teventName: string,\n\t\t\t\tpayload?: Record<string, unknown>,\n\t\t ) => void | Promise<void>)\n\t\t| null = null;\n\n\t// Memoized SRE resolver for the runtime generated-speech path (PIE-623).\n\t// Caches DOM-free spoken text keyed by SRE settings and MathML source across\n\t// utterances within this service instance.\n\tprivate readonly generatedMathSpeechResolver: MathSpeechResolver =\n\t\tcreateMemoizedMathSpeechResolver();\n\n\t// Verbose alignment/highlight tracing is opt-in: it is expensive (large\n\t// objects, a full text diff per utterance) and noisy in production. Enable\n\t// with `PIE_TTS_DEBUG=1` or `globalThis.__PIE_TTS_DEBUG__ = true`.\n\tprivate static readonly debugEnabled = ((): boolean => {\n\t\ttry {\n\t\t\tif (\n\t\t\t\ttypeof process !== \"undefined\" &&\n\t\t\t\tprocess.env?.PIE_TTS_DEBUG === \"1\"\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch {\n\t\t\t// `process` is not defined in the browser; fall through to the global.\n\t\t}\n\t\treturn (\n\t\t\t(globalThis as { __PIE_TTS_DEBUG__?: unknown }).__PIE_TTS_DEBUG__ === true\n\t\t);\n\t})();\n\n\tconstructor() {}\n\n\tprivate debugLog(message: string, detail?: unknown): void {\n\t\tif (!TTSService.debugEnabled) return;\n\t\tif (detail === undefined) {\n\t\t\tconsole.debug(message);\n\t\t} else {\n\t\t\tconsole.debug(message, detail);\n\t\t}\n\t}\n\n\tprivate async emitTelemetry(\n\t\teventName: string,\n\t\tpayload?: Record<string, unknown>,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.telemetryReporter?.(eventName, payload);\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"[TTSService] telemetry callback failed:\", error);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize TTS service with a provider\n\t *\n\t * @param provider TTS provider instance\n\t * @param config Provider configuration\n\t */\n\tasync initialize(\n\t\tprovider: ITTSProvider,\n\t\tconfig: Partial<TTSConfig> = {},\n\t): Promise<void> {\n\t\tthis.currentProvider = provider;\n\t\tthis.ttsConfig = { ...config };\n\t\tconst providerOptions =\n\t\t\tconfig.providerOptions && typeof config.providerOptions === \"object\"\n\t\t\t\t? (config.providerOptions as Record<string, unknown>)\n\t\t\t\t: {};\n\t\tthis.telemetryReporter =\n\t\t\ttypeof providerOptions.__pieTelemetry === \"function\"\n\t\t\t\t? (providerOptions.__pieTelemetry as (\n\t\t\t\t\t\teventName: string,\n\t\t\t\t\t\tpayload?: Record<string, unknown>,\n\t\t\t\t\t) => void | Promise<void>)\n\t\t\t\t: null;\n\n\t\t// Initialize provider and get implementation. Browser fallback is only\n\t\t// allowed here, before the configured provider has successfully become\n\t\t// the active runtime. Per-call playback/synthesis errors must surface\n\t\t// instead of silently replacing a user-selected provider and voice.\n\t\ttry {\n\t\t\tthis.provider = await provider.initialize(config as TTSConfig);\n\t\t} catch (error) {\n\t\t\tif (provider.providerId.toLowerCase() === \"browser\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (!this.isBrowserSpeechFallbackAvailable()) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst switched = await this.switchProviderToBrowser(error, {\n\t\t\t\toperation: \"tts-initialize\",\n\t\t\t});\n\t\t\tif (!switched) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update TTS settings dynamically without full reinitialization\n\t *\n\t * This allows changing rate, pitch, and voice on the fly.\n\t * Note: Some providers may require reinitialization for voice changes.\n\t *\n\t * @param settings Partial settings to update (rate, pitch, voice)\n\t */\n\tasync updateSettings(settings: Partial<TTSConfig>): Promise<void> {\n\t\tif (!this.provider) {\n\t\t\tthrow new Error(\"TTSService not initialized. Call initialize() first.\");\n\t\t}\n\n\t\t// If the provider implementation has an updateSettings method, use it\n\t\tconst provider = this.provider as {\n\t\t\tupdateSettings?: (settings: Partial<TTSConfig>) => Promise<void> | void;\n\t\t};\n\t\tif (typeof provider.updateSettings === \"function\") {\n\t\t\tconst mergedSettings: Partial<TTSConfig> = {\n\t\t\t\t...settings,\n\t\t\t\t...(settings.providerOptions\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tproviderOptions: {\n\t\t\t\t\t\t\t\t...((this.ttsConfig.providerOptions || {}) as Record<\n\t\t\t\t\t\t\t\t\tstring,\n\t\t\t\t\t\t\t\t\tunknown\n\t\t\t\t\t\t\t\t>),\n\t\t\t\t\t\t\t\t...(settings.providerOptions as Record<string, unknown>),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t};\n\t\t\tawait provider.updateSettings(mergedSettings);\n\t\t\tthis.ttsConfig = { ...this.ttsConfig, ...mergedSettings };\n\t\t} else {\n\t\t\t// Fallback: Reinitialize with merged config\n\t\t\t// This requires storing the original config, which we don't have\n\t\t\t// So for now, just log a warning\n\t\t\tconsole.warn(\n\t\t\t\t\"[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Set highlight coordinator for word highlighting\n\t */\n\tsetHighlightCoordinator(coordinator: HighlightCoordinatorApi): void {\n\t\tthis.highlightCoordinator = coordinator;\n\t}\n\n\t/**\n\t * Set a late-bound provider for optional host TTS highlight target remapping.\n\t */\n\tsetHighlightTargetResolverProvider(\n\t\tprovider: TTSHighlightTargetResolverProvider | null,\n\t): () => void {\n\t\tthis.highlightTargetResolverProvider = provider;\n\t\treturn () => {\n\t\t\tif (this.highlightTargetResolverProvider === provider) {\n\t\t\t\tthis.highlightTargetResolverProvider = null;\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Set accessibility catalog resolver for spoken content\n\t *\n\t * When set, the speak() method will check for pre-authored spoken\n\t * content in catalogs before falling back to generated TTS.\n\t *\n\t * @param resolver AccessibilityCatalogResolver instance\n\t */\n\tsetCatalogResolver(resolver: AccessibilityCatalogResolver): void {\n\t\tthis.catalogResolver = resolver;\n\t}\n\n\tprivate getHighlightResolverRuntime(): {\n\t\tcontext: TTSHighlightContext;\n\t\tresolver: TTSHighlightTargetResolver | null;\n\t} {\n\t\tlet provided: TTSHighlightTargetResolverRuntime | null | undefined = null;\n\t\ttry {\n\t\t\tprovided = this.highlightTargetResolverProvider?.() ?? null;\n\t\t} catch {\n\t\t\tprovided = null;\n\t\t}\n\t\tconst providedContext = provided?.context ?? {};\n\t\tconst fallbackScope =\n\t\t\ttypeof HTMLElement !== \"undefined\" &&\n\t\t\tthis.currentContentElement instanceof HTMLElement\n\t\t\t\t? this.currentContentElement\n\t\t\t\t: null;\n\t\treturn {\n\t\t\tcontext: {\n\t\t\t\t...providedContext,\n\t\t\t\tscopeElement: providedContext.scopeElement ?? fallbackScope,\n\t\t\t},\n\t\t\tresolver: provided?.resolver ?? null,\n\t\t};\n\t}\n\n\tprivate getNodeElement(node: Node | null): Element | null {\n\t\tif (!node) return null;\n\t\treturn node.nodeType === Node.ELEMENT_NODE\n\t\t\t? (node as Element)\n\t\t\t: node.parentElement;\n\t}\n\n\tprivate isElementWithinScope(\n\t\telement: Element,\n\t\tscope: Element | null | undefined,\n\t): boolean {\n\t\tif (!scope) return true;\n\t\treturn element === scope || scope.contains(element);\n\t}\n\n\tprivate isRangeWithinScope(\n\t\trange: Range,\n\t\tscope: Element | null | undefined,\n\t): boolean {\n\t\tconst startElement = this.getNodeElement(range.startContainer);\n\t\tconst endElement = this.getNodeElement(range.endContainer);\n\t\tif (!startElement || !endElement) return false;\n\t\treturn (\n\t\t\tthis.isElementWithinScope(startElement, scope) &&\n\t\t\tthis.isElementWithinScope(endElement, scope)\n\t\t);\n\t}\n\n\tprivate resolveWordHighlightRange(nativeRange: Range): {\n\t\trange: Range;\n\t\tremapped: boolean;\n\t} {\n\t\tconst { context, resolver } = this.getHighlightResolverRuntime();\n\t\tconst scope = context.scopeElement ?? this.currentContentElement;\n\t\ttry {\n\t\t\tconst resolved = resolver?.resolveWordRange?.(nativeRange, context);\n\t\t\tif (resolved && this.isRangeWithinScope(resolved, scope)) {\n\t\t\t\treturn { range: resolved, remapped: !sameRange(nativeRange, resolved) };\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fail open: custom resolver failures must not interrupt TTS playback.\n\t\t}\n\t\treturn { range: nativeRange, remapped: false };\n\t}\n\n\tprivate resolveSentenceHighlightTargets(nativeRanges: Range[]): {\n\t\tranges: Range[];\n\t\telements: Element[];\n\t} {\n\t\tconst { context, resolver } = this.getHighlightResolverRuntime();\n\t\tconst scope = context.scopeElement ?? this.currentContentElement;\n\t\ttry {\n\t\t\tconst resolved = resolver?.resolveSentenceRanges?.(nativeRanges, context);\n\t\t\tif (!resolved) return { ranges: nativeRanges, elements: [] };\n\t\t\tconst ranges: Range[] = [];\n\t\t\tconst elements: Element[] = [];\n\t\t\tfor (const target of resolved) {\n\t\t\t\tif (typeof Range !== \"undefined\" && target instanceof Range) {\n\t\t\t\t\tif (!this.isRangeWithinScope(target, scope)) {\n\t\t\t\t\t\treturn { ranges: nativeRanges, elements: [] };\n\t\t\t\t\t}\n\t\t\t\t\tranges.push(target);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (typeof Element !== \"undefined\" && target instanceof Element) {\n\t\t\t\t\tif (!this.isElementWithinScope(target, scope)) {\n\t\t\t\t\t\treturn { ranges: nativeRanges, elements: [] };\n\t\t\t\t\t}\n\t\t\t\t\telements.push(target);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturn { ranges: nativeRanges, elements: [] };\n\t\t\t}\n\t\t\treturn { ranges, elements };\n\t\t} catch {\n\t\t\t// Fail open: custom resolver failures must not interrupt TTS playback.\n\t\t\treturn { ranges: nativeRanges, elements: [] };\n\t\t}\n\t}\n\n\tprivate createTextRange(\n\t\tnode: Text,\n\t\tstartOffset: number,\n\t\tendOffset: number,\n\t): Range | null {\n\t\tif (typeof document === \"undefined\") return null;\n\t\tif (typeof document.createRange !== \"function\") return null;\n\t\ttry {\n\t\t\tconst range = document.createRange();\n\t\t\trange.setStart(node, startOffset);\n\t\t\trange.setEnd(node, endOffset);\n\t\t\tif (range.startContainer !== node || range.endContainer !== node) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn range;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate paintTTSWordRange(range: Range): void {\n\t\tif (!this.highlightCoordinator) return;\n\t\ttry {\n\t\t\tif (\n\t\t\t\trange.startContainer === range.endContainer &&\n\t\t\t\trange.startContainer.nodeType === Node.TEXT_NODE\n\t\t\t) {\n\t\t\t\tthis.highlightCoordinator.highlightTTSWord(\n\t\t\t\t\trange.startContainer as Text,\n\t\t\t\t\trange.startOffset,\n\t\t\t\t\trange.endOffset,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to generic range painting for lightweight test doubles.\n\t\t}\n\t\tthis.highlightCoordinator.highlightRange(\n\t\t\trange,\n\t\t\tHighlightType.TTS_WORD,\n\t\t\tHighlightColor.YELLOW,\n\t\t);\n\t}\n\n\tprivate paintTTSSentenceRanges(nativeRanges: Range[]): void {\n\t\tif (!this.highlightCoordinator) return;\n\t\tconst { ranges, elements } =\n\t\t\tthis.resolveSentenceHighlightTargets(nativeRanges);\n\t\tif (\n\t\t\telements.length > 0 &&\n\t\t\tranges.length === 0 &&\n\t\t\tthis.highlightCoordinator.highlightTTSSentenceElements\n\t\t) {\n\t\t\tthis.highlightCoordinator.highlightTTSSentenceElements(elements);\n\t\t\treturn;\n\t\t}\n\t\tconst paintedRanges = [...ranges];\n\t\tfor (const element of elements) {\n\t\t\tconst elementRange = document.createRange();\n\t\t\telementRange.selectNodeContents(element);\n\t\t\tpaintedRanges.push(elementRange);\n\t\t}\n\t\tthis.highlightCoordinator.highlightTTSSentence(paintedRanges);\n\t}\n\n\t/**\n\t * Get provider capabilities\n\t */\n\tgetCapabilities(): TTSProviderCapabilities | null {\n\t\treturn this.currentProvider?.getCapabilities() || null;\n\t}\n\n\t/**\n\t * Build a character-by-character map from normalized text positions to DOM positions\n\t * This handles the complexity of whitespace normalization\n\t */\n\tprivate getTextProcessingOptions(language?: string): {\n\t\tlocale?: string;\n\t\tboundarySpacingMode?: BoundarySpacingMode;\n\t} {\n\t\tconst providerOptions = (this.ttsConfig.providerOptions || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst textNormalization = (providerOptions.textNormalization ||\n\t\t\t{}) as Record<string, unknown>;\n\t\tconst mode = textNormalization.boundarySpacingMode;\n\t\tconst boundarySpacingMode: BoundarySpacingMode | undefined =\n\t\t\tmode === \"none\" || mode === \"alnum\" || mode === \"segmenterPreferred\"\n\t\t\t\t? mode\n\t\t\t\t: undefined;\n\t\tconst locale =\n\t\t\tlanguage ||\n\t\t\t(typeof textNormalization.locale === \"string\"\n\t\t\t\t? textNormalization.locale\n\t\t\t\t: undefined);\n\t\treturn { locale, boundarySpacingMode };\n\t}\n\n\tprivate getMathSpeechOptions(): SREMathSpeechOptions | undefined {\n\t\tconst providerOptions = (this.ttsConfig.providerOptions || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst mathSpeech = providerOptions.mathSpeech;\n\t\treturn normalizeSREMathSpeechOptions(mathSpeech);\n\t}\n\n\tprivate buildPositionMap(\n\t\telement: Element,\n\t\tspokenText: string,\n\t\tlanguage?: string,\n\t): void {\n\t\tthis.normalizedToDOM.clear();\n\t\tconst { text: normalizedDomText, map } = collectVisibleTextAndMap(\n\t\t\telement,\n\t\t\tthis.getTextProcessingOptions(language),\n\t\t);\n\t\tthis.normalizedToDOM = map;\n\n\t\tif (!TTSService.debugEnabled) return;\n\n\t\tthis.debugLog(\"[TTSService] Text comparison:\", {\n\t\t\tspokenLength: spokenText.length,\n\t\t\tnormalizedDomLength: normalizedDomText.length,\n\t\t\tmatch: spokenText === normalizedDomText,\n\t\t\tspokenPreview: spokenText.substring(0, 150),\n\t\t\tnormalizedPreview: normalizedDomText.substring(0, 150),\n\t\t\tdifferAtIndex:\n\t\t\t\tspokenText === normalizedDomText\n\t\t\t\t\t? null\n\t\t\t\t\t: (() => {\n\t\t\t\t\t\t\tfor (\n\t\t\t\t\t\t\t\tlet i = 0;\n\t\t\t\t\t\t\t\ti < Math.min(spokenText.length, normalizedDomText.length);\n\t\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tif (spokenText[i] !== normalizedDomText[i]) {\n\t\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t\tindex: i,\n\t\t\t\t\t\t\t\t\t\tspokenChar: spokenText[i],\n\t\t\t\t\t\t\t\t\t\tnormalizedChar: normalizedDomText[i],\n\t\t\t\t\t\t\t\t\t\tspokenContext: spokenText.substring(\n\t\t\t\t\t\t\t\t\t\t\tMath.max(0, i - 20),\n\t\t\t\t\t\t\t\t\t\t\ti + 20,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tnormalizedContext: normalizedDomText.substring(\n\t\t\t\t\t\t\t\t\t\t\tMath.max(0, i - 20),\n\t\t\t\t\t\t\t\t\t\t\ti + 20,\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t})(),\n\t\t});\n\n\t\tthis.debugLog(\"[TTSService] Position map built:\", {\n\t\t\tentries: this.normalizedToDOM.size,\n\t\t\tspokenTextLength: spokenText.length,\n\t\t\tnormalizedDomLength: normalizedDomText.length,\n\t\t\tmapLengthMatchesSpoken: this.normalizedToDOM.size === spokenText.length,\n\t\t\tfirstFewMappings: Array.from(this.normalizedToDOM.entries())\n\t\t\t\t.slice(0, 10)\n\t\t\t\t.map(([pos, { node, offset }]) => ({\n\t\t\t\t\tpos,\n\t\t\t\t\toffset,\n\t\t\t\t\tchar: node.textContent?.[offset],\n\t\t\t\t\texpected: spokenText[pos],\n\t\t\t\t})),\n\t\t});\n\t}\n\n\tprivate getStructuralPauseProfile(): StructuralPauseProfile {\n\t\tconst providerOptions = (this.ttsConfig.providerOptions || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst custom = (providerOptions.structuralPauses || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst customUnits = (custom.units || {}) as Record<string, unknown>;\n\t\tconst toNumber = (value: unknown, fallback: number): number => {\n\t\t\tif (typeof value === \"number\" && Number.isFinite(value)) return value;\n\t\t\tif (typeof value === \"string\" && value.trim()) {\n\t\t\t\tconst parsed = Number(value);\n\t\t\t\treturn Number.isFinite(parsed) ? parsed : fallback;\n\t\t\t}\n\t\t\treturn fallback;\n\t\t};\n\t\treturn {\n\t\t\tbaseMs: toNumber(custom.baseMs, 280),\n\t\t\tunits: {\n\t\t\t\tminor: toNumber(customUnits.minor, 0.65),\n\t\t\t\tsection: toNumber(customUnits.section, 1.0),\n\t\t\t\tmajor: toNumber(customUnits.major, 1.35),\n\t\t\t},\n\t\t\tminMs: toNumber(custom.minMs, 120),\n\t\t\tmaxMs: toNumber(custom.maxMs, 900),\n\t\t};\n\t}\n\n\tprivate resolvePauseMsFromUnits(units: number): number {\n\t\tconst profile = this.getStructuralPauseProfile();\n\t\tconst rate = Math.max(0.25, Math.min(4, Number(this.ttsConfig.rate || 1)));\n\t\tconst raw = (profile.baseMs * Math.max(0, units)) / rate;\n\t\treturn Math.max(profile.minMs, Math.min(profile.maxMs, Math.round(raw)));\n\t}\n\n\tprivate resolveHighlightMode(): HighlightMode {\n\t\tconst providerOptions = (this.ttsConfig.providerOptions || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst configuredMode = providerOptions.highlightMode;\n\t\tif (configuredMode === \"word\" || configuredMode === \"sentence\") {\n\t\t\treturn configuredMode;\n\t\t}\n\t\tconst providerId = (this.currentProvider?.providerId || \"\").toLowerCase();\n\t\tif (providerId === \"browser\") {\n\t\t\treturn \"sentence\";\n\t\t}\n\t\tconst supportsWordBoundary =\n\t\t\tthis.currentProvider?.getCapabilities().supportsWordBoundary ?? false;\n\t\treturn supportsWordBoundary ? \"word\" : \"sentence\";\n\t}\n\n\tprivate hasExplicitBreakSemantics(text: string): boolean {\n\t\tif (!text.includes(\"<\")) return false;\n\t\treturn /<\\s*break\\b|<\\s*speak\\b|<\\s*prosody\\b|<\\s*p\\b|<\\s*s\\b/i.test(text);\n\t}\n\n\tprivate isElementHidden(element: Element): boolean {\n\t\treturn isElementHiddenForTTS(element);\n\t}\n\n\tprivate getBoundaryStrength(element: Element): StructuralPauseStrength {\n\t\tconst explicitBreakMs = Number(element.getAttribute(\"data-tts-break-ms\"));\n\t\tif (Number.isFinite(explicitBreakMs) && explicitBreakMs > 0) return \"major\";\n\t\tconst tagName = element.tagName.toUpperCase();\n\t\tif (tagName.match(/^H[1-6]$/)) return \"major\";\n\t\tconst role = (element.getAttribute(\"role\") || \"\").toLowerCase();\n\t\tif (role === \"heading\") return \"major\";\n\t\tif (\n\t\t\trole === \"listitem\" ||\n\t\t\trole === \"row\" ||\n\t\t\trole === \"option\" ||\n\t\t\trole === \"radio\" ||\n\t\t\ttagName === \"LI\"\n\t\t) {\n\t\t\treturn \"section\";\n\t\t}\n\t\tif (typeof window !== \"undefined\") {\n\t\t\tconst display = window.getComputedStyle(element).display;\n\t\t\tif (\n\t\t\t\tdisplay === \"block\" ||\n\t\t\t\tdisplay === \"list-item\" ||\n\t\t\t\tdisplay.startsWith(\"table\") ||\n\t\t\t\tdisplay === \"flex\" ||\n\t\t\t\tdisplay === \"grid\"\n\t\t\t) {\n\t\t\t\treturn \"minor\";\n\t\t\t}\n\t\t}\n\t\treturn \"minor\";\n\t}\n\n\tprivate getBoundaryAnchor(\n\t\ttextNode: Text,\n\t\troot: Element,\n\t): { anchor: Element; units: number } | null {\n\t\tlet current = textNode.parentElement;\n\t\tlet best: Element | null = null;\n\t\twhile (current && current !== root) {\n\t\t\tif (this.isElementHidden(current)) return null;\n\t\t\tconst explicitBreakMs = Number(current.getAttribute(\"data-tts-break-ms\"));\n\t\t\tif (Number.isFinite(explicitBreakMs) && explicitBreakMs > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tanchor: current,\n\t\t\t\t\tunits: explicitBreakMs / this.getStructuralPauseProfile().baseMs,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst role = (current.getAttribute(\"role\") || \"\").toLowerCase();\n\t\t\tconst tagName = current.tagName.toUpperCase();\n\t\t\tif (\n\t\t\t\ttagName.match(/^H[1-6]$/) ||\n\t\t\t\trole === \"heading\" ||\n\t\t\t\trole === \"listitem\" ||\n\t\t\t\ttagName === \"LI\"\n\t\t\t) {\n\t\t\t\tbest = current;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!best) {\n\t\t\t\tif (typeof window !== \"undefined\") {\n\t\t\t\t\tconst display = window.getComputedStyle(current).display;\n\t\t\t\t\tif (\n\t\t\t\t\t\tdisplay === \"block\" ||\n\t\t\t\t\t\tdisplay === \"list-item\" ||\n\t\t\t\t\t\tdisplay.startsWith(\"table\") ||\n\t\t\t\t\t\tdisplay === \"flex\" ||\n\t\t\t\t\t\tdisplay === \"grid\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tbest = current;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrent = current.parentElement;\n\t\t}\n\t\tif (!best) return null;\n\t\tconst strength = this.getBoundaryStrength(best);\n\t\treturn {\n\t\t\tanchor: best,\n\t\t\tunits: this.getStructuralPauseProfile().units[strength],\n\t\t};\n\t}\n\n\tprivate createSpeechPlan(\n\t\tcontentElement: Element,\n\t\tnormalizedText: string,\n\t): TTSSpeechSegment[] {\n\t\tconst boundaries = this.collectSpeechPlanBoundaries(\n\t\t\tcontentElement,\n\t\t\tnormalizedText,\n\t\t);\n\t\treturn this.createSpeechPlanSegments(normalizedText, boundaries);\n\t}\n\n\tprivate collectSpeechPlanBoundaries(\n\t\tcontentElement: Element,\n\t\tnormalizedText: string,\n\t): Map<number, number> {\n\t\tconst boundaries = new Map<number, number>();\n\t\tconst { map } = collectVisibleTextAndMap(\n\t\t\tcontentElement,\n\t\t\tthis.getTextProcessingOptions(),\n\t\t);\n\t\tconst nodeStartOffsets = this.createNodeStartOffsets(map);\n\n\t\tconst walker = document.createTreeWalker(\n\t\t\tcontentElement,\n\t\t\tNodeFilter.SHOW_TEXT,\n\t\t);\n\t\tlet currentNode = walker.nextNode();\n\t\tlet previousBoundaryAnchor: Element | null = null;\n\t\twhile (currentNode) {\n\t\t\tconst textNode = currentNode as Text;\n\t\t\tconst parent = textNode.parentElement;\n\t\t\tif (parent && !this.isElementHidden(parent)) {\n\t\t\t\tconst boundary = this.getBoundaryAnchor(textNode, contentElement);\n\t\t\t\tconst boundaryPoint = nodeStartOffsets.get(textNode);\n\t\t\t\tif (\n\t\t\t\t\tboundary &&\n\t\t\t\t\tboundaryPoint !== undefined &&\n\t\t\t\t\tboundary.anchor !== previousBoundaryAnchor &&\n\t\t\t\t\tboundaryPoint > 0\n\t\t\t\t) {\n\t\t\t\t\tboundaries.set(\n\t\t\t\t\t\tboundaryPoint,\n\t\t\t\t\t\tMath.max(boundaries.get(boundaryPoint) || 0, boundary.units),\n\t\t\t\t\t);\n\t\t\t\t\tpreviousBoundaryAnchor = boundary.anchor;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrentNode = walker.nextNode();\n\t\t}\n\t\treturn boundaries;\n\t}\n\n\tprivate createNodeStartOffsets(\n\t\tmap: Map<number, { node: Text; offset: number }>,\n\t): Map<Text, number> {\n\t\tconst nodeStartOffsets = new Map<Text, number>();\n\t\tfor (const [normalizedIndex, mapping] of map.entries()) {\n\t\t\tif (!nodeStartOffsets.has(mapping.node)) {\n\t\t\t\tnodeStartOffsets.set(mapping.node, normalizedIndex);\n\t\t\t}\n\t\t}\n\t\treturn nodeStartOffsets;\n\t}\n\n\tprivate createSpeechPlanSegments(\n\t\tnormalizedText: string,\n\t\tboundaries: Map<number, number>,\n\t): TTSSpeechSegment[] {\n\t\tconst points = Array.from(boundaries.keys())\n\t\t\t.filter((point) => point > 0 && point < normalizedText.length)\n\t\t\t.sort((a, b) => a - b);\n\t\tconst segments: TTSSpeechSegment[] = [];\n\t\tlet start = 0;\n\t\tfor (const point of points) {\n\t\t\tconst raw = normalizedText.substring(start, point);\n\t\t\tconst leading = raw.match(/^\\s*/)?.[0].length || 0;\n\t\t\tconst trailing = raw.match(/\\s*$/)?.[0].length || 0;\n\t\t\tconst segmentStart = start + leading;\n\t\t\tconst segmentEnd = point - trailing;\n\t\t\tif (segmentEnd > segmentStart) {\n\t\t\t\tconst text = normalizedText.substring(segmentStart, segmentEnd);\n\t\t\t\tsegments.push({\n\t\t\t\t\ttext,\n\t\t\t\t\tstartOffset: segmentStart,\n\t\t\t\t\tpauseMsAfter: this.resolvePauseMsFromUnits(\n\t\t\t\t\t\tboundaries.get(point) || 0,\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t\tstart = point;\n\t\t}\n\t\tconst tail = normalizedText.substring(start);\n\t\tconst tailLeading = tail.match(/^\\s*/)?.[0].length || 0;\n\t\tconst tailStart = start + tailLeading;\n\t\tif (tailStart < normalizedText.length) {\n\t\t\tsegments.push({\n\t\t\t\ttext: normalizedText.substring(tailStart).trimEnd(),\n\t\t\t\tstartOffset: tailStart,\n\t\t\t\tpauseMsAfter: 0,\n\t\t\t});\n\t\t}\n\t\treturn segments.filter((segment) => segment.text.trim().length > 0);\n\t}\n\n\tprivate segmentSentences(text: string): SharedSentenceSegment[] {\n\t\tconst locale =\n\t\t\t((this.ttsConfig.providerOptions as Record<string, unknown> | undefined)\n\t\t\t\t?.locale as string | undefined) || undefined;\n\t\treturn segmentTextToSentences(text, { locale });\n\t}\n\n\tprivate createSeekSegmentsFromText(text: string): TTSSpeechSegment[] {\n\t\treturn this.segmentSentences(text)\n\t\t\t.map((segment) => {\n\t\t\t\tconst leadingWhitespace = segment.text.match(/^\\s*/)?.[0].length || 0;\n\t\t\t\tconst trimmed = segment.text.trim();\n\t\t\t\treturn {\n\t\t\t\t\ttext: trimmed,\n\t\t\t\t\tstartOffset: segment.offset + leadingWhitespace,\n\t\t\t\t\tpauseMsAfter: 0,\n\t\t\t\t};\n\t\t\t})\n\t\t\t.filter((segment) => segment.text.length > 0);\n\t}\n\n\tprivate splitSegmentsAtBoundaries(\n\t\tsegments: TTSSpeechSegment[],\n\t\tboundaryOffsets: number[],\n\t\tsourceText: string,\n\t): TTSSpeechSegment[] {\n\t\tif (segments.length === 0 || boundaryOffsets.length === 0) return segments;\n\t\tconst normalizedBoundaries = Array.from(new Set(boundaryOffsets))\n\t\t\t.filter((offset) => Number.isFinite(offset) && offset > 0)\n\t\t\t.sort((left, right) => left - right);\n\t\tif (normalizedBoundaries.length === 0) return segments;\n\t\tconst result: TTSSpeechSegment[] = [];\n\t\tfor (const segment of segments) {\n\t\t\tconst segmentStart = segment.startOffset;\n\t\t\tconst segmentEnd = segment.startOffset + segment.text.length;\n\t\t\tconst splitPoints = normalizedBoundaries.filter(\n\t\t\t\t(offset) => offset > segmentStart && offset < segmentEnd,\n\t\t\t);\n\t\t\tif (splitPoints.length === 0) {\n\t\t\t\tresult.push(segment);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet cursor = segmentStart;\n\t\t\tfor (const point of [...splitPoints, segmentEnd]) {\n\t\t\t\tconst raw = sourceText.substring(cursor, point);\n\t\t\t\tconst leadingWhitespace = raw.match(/^\\s*/)?.[0].length || 0;\n\t\t\t\tconst trailingWhitespace = raw.match(/\\s*$/)?.[0].length || 0;\n\t\t\t\tconst startOffset = cursor + leadingWhitespace;\n\t\t\t\tconst endOffset = point - trailingWhitespace;\n\t\t\t\tif (endOffset > startOffset) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\ttext: sourceText.substring(startOffset, endOffset),\n\t\t\t\t\t\tstartOffset,\n\t\t\t\t\t\tpauseMsAfter: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcursor = point;\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate createSentenceHighlightSegments(args: {\n\t\tcontentToSpeak: string;\n\t\tshouldUsePlan: boolean;\n\t\tplaybackSegments: TTSSpeechSegment[];\n\t}): TTSSpeechSegment[] {\n\t\tconst grammaticalSegments = this.createSeekSegmentsFromText(\n\t\t\targs.contentToSpeak,\n\t\t);\n\t\tif (!args.shouldUsePlan || args.playbackSegments.length === 0) {\n\t\t\treturn grammaticalSegments;\n\t\t}\n\t\tconst structuralBoundaries = args.playbackSegments\n\t\t\t.map((segment) => segment.startOffset)\n\t\t\t.filter((offset) => offset > 0);\n\t\treturn this.splitSegmentsAtBoundaries(\n\t\t\tgrammaticalSegments,\n\t\t\tstructuralBoundaries,\n\t\t\targs.contentToSpeak,\n\t\t);\n\t}\n\n\tprivate createSeekSegmentsFromSpeechChunks(\n\t\tchunks: SpeechCompositionChunk[],\n\t): TTSSpeechSegment[] {\n\t\tlet offset = 0;\n\t\treturn chunks.map((chunk) => {\n\t\t\tconst speechText =\n\t\t\t\tchunk.plainFallback?.speechText ||\n\t\t\t\t(this.hasExplicitBreakSemantics(chunk.speechText)\n\t\t\t\t\t? chunk.visibleText\n\t\t\t\t\t: chunk.speechText) ||\n\t\t\t\tchunk.visibleText;\n\t\t\tconst text =\n\t\t\t\tnormalizeTextForSpeech(speechText) || chunk.visibleText || \"\";\n\t\t\tconst segment = {\n\t\t\t\ttext,\n\t\t\t\tstartOffset: offset,\n\t\t\t\tpauseMsAfter: 0,\n\t\t\t};\n\t\t\toffset += Math.max(1, text.length + 1);\n\t\t\treturn segment;\n\t\t});\n\t}\n\n\tprivate getCurrentSeekSegmentIndex(): number {\n\t\tif (this.seekSegments.length === 0) return 0;\n\t\tlet index = 0;\n\t\tfor (let i = 0; i < this.seekSegments.length; i++) {\n\t\t\tif (this.seekSegments[i].startOffset <= this.currentBoundaryOffset) {\n\t\t\t\tindex = i;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn index;\n\t}\n\n\tprivate async speakWithPlan(\n\t\tsegments: TTSSpeechSegment[],\n\t\trunId: number,\n\t\toptions?: { highlightMode?: HighlightMode },\n\t): Promise<void> {\n\t\tif (!this.provider || segments.length === 0) return;\n\t\tconst shouldTrackSentenceProgress = options?.highlightMode === \"sentence\";\n\t\tconst providerWithPlan = this.provider as ITTSProviderImplementation & {\n\t\t\tspeakSegments?: (segments: TTSSpeechSegment[]) => Promise<void>;\n\t\t};\n\t\tif (\n\t\t\t!shouldTrackSentenceProgress &&\n\t\t\ttypeof providerWithPlan.speakSegments === \"function\"\n\t\t) {\n\t\t\tthis.currentBoundaryOffset = 0;\n\t\t\tconst originalOnWordBoundary = this.provider.onWordBoundary;\n\t\t\tthis.provider.onWordBoundary = (\n\t\t\t\tword: string,\n\t\t\t\tposition: number,\n\t\t\t\tlength?: number,\n\t\t\t) => {\n\t\t\t\toriginalOnWordBoundary?.(word, position, length);\n\t\t\t\tif (Number.isFinite(position)) {\n\t\t\t\t\tthis.currentBoundaryOffset = position;\n\t\t\t\t\tthis.currentSeekSegmentIndex = this.getCurrentSeekSegmentIndex();\n\t\t\t\t}\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tawait providerWithPlan.speakSegments(segments);\n\t\t\t} finally {\n\t\t\t\tif (runId === this.speakRunId && this.provider === providerWithPlan) {\n\t\t\t\t\tthis.provider.onWordBoundary = originalOnWordBoundary;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis.configureWordBoundaryHighlighting({\n\t\t\thighlightMode: options?.highlightMode || \"word\",\n\t\t\twordBoundaryOffset: this.activeWordBoundaryOffset,\n\t\t});\n\t\tfor (const segment of segments) {\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tconst seekIndex = this.seekSegments.findIndex(\n\t\t\t\t(candidate) => candidate.startOffset === segment.startOffset,\n\t\t\t);\n\t\t\tif (seekIndex >= 0) {\n\t\t\t\tthis.currentSeekSegmentIndex = seekIndex;\n\t\t\t}\n\t\t\tthis.currentBoundaryOffset = segment.startOffset;\n\t\t\tif (shouldTrackSentenceProgress) {\n\t\t\t\tthis.highlightSentenceSegment(segment.startOffset, segment.text);\n\t\t\t}\n\t\t\tawait this.provider.speak(segment.text);\n\t\t\tconst pauseMs = segment.pauseMsAfter ?? 0;\n\t\t\tif (pauseMs > 0) {\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, pauseMs));\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate highlightSentenceSegment(startOffset: number, text: string): void {\n\t\tif (!this.highlightCoordinator || typeof document === \"undefined\") return;\n\t\tconst length = text.trimEnd().length;\n\t\tif (length <= 0) return;\n\t\tconst start = this.normalizedToDOM.get(startOffset);\n\t\tconst end = this.normalizedToDOM.get(startOffset + length - 1);\n\t\tif (!start || !end) return;\n\t\tconst range = document.createRange();\n\t\trange.setStart(start.node, start.offset);\n\t\trange.setEnd(end.node, end.offset + 1);\n\t\tthis.paintTTSSentenceRanges([range]);\n\t\tthis.activeSentenceStartOffset = startOffset;\n\t}\n\n\tprivate getSegmentIndexForOffset(\n\t\tsegments: TTSSpeechSegment[],\n\t\toffset: number,\n\t): number {\n\t\tif (segments.length === 0) return -1;\n\t\tlet index = -1;\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tif (segments[i].startOffset <= offset) {\n\t\t\t\tindex = i;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn index;\n\t}\n\n\tprivate highlightSentenceForOffset(offset: number): void {\n\t\tconst segments = this.sentenceHighlightSegments;\n\t\tif (!this.highlightCoordinator || segments.length === 0) return;\n\t\tconst segmentIndex = this.getSegmentIndexForOffset(segments, offset);\n\t\tif (segmentIndex < 0) return;\n\t\tconst segment = segments[segmentIndex];\n\t\tif (!segment) return;\n\t\tif (this.activeSentenceStartOffset === segment.startOffset) return;\n\t\tthis.highlightSentenceSegment(segment.startOffset, segment.text);\n\t}\n\n\t/**\n\t * Find text node and offsets for highlighting a word\n\t *\n\t * @param charIndex Character position in normalized/spoken text\n\t * @param length Length of the word\n\t * @returns Text node and local offsets, or null if not found\n\t */\n\tprivate findHighlightRange(\n\t\tcharIndex: number,\n\t\tlength: number,\n\t): { node: Text; start: number; end: number } | null {\n\t\tconst startPos = this.normalizedToDOM.get(charIndex);\n\t\tif (!startPos) {\n\t\t\tconsole.warn(\n\t\t\t\t`[TTSService] No mapping found for start position ${charIndex}`,\n\t\t\t\t{\n\t\t\t\t\ttotalMappings: this.normalizedToDOM.size,\n\t\t\t\t\tnearbyMappings: Array.from(this.normalizedToDOM.entries())\n\t\t\t\t\t\t.filter(([pos]) => Math.abs(pos - charIndex) < 5)\n\t\t\t\t\t\t.map(([pos, { offset, node }]) => ({\n\t\t\t\t\t\t\tpos,\n\t\t\t\t\t\t\toffset,\n\t\t\t\t\t\t\tchar: node.textContent?.[offset],\n\t\t\t\t\t\t})),\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\t// Find the end position (last character of the word)\n\t\tconst endIndex = charIndex + length - 1;\n\t\tconst endPos = this.normalizedToDOM.get(endIndex);\n\t\tif (!endPos) {\n\t\t\tconsole.warn(\n\t\t\t\t`[TTSService] No mapping found for end position ${endIndex}`,\n\t\t\t\t{\n\t\t\t\t\tstartChar: charIndex,\n\t\t\t\t\tlength,\n\t\t\t\t\ttotalMappings: this.normalizedToDOM.size,\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\t// For simplicity, if the word spans multiple nodes, just highlight in the first node\n\t\t// (This is a rare edge case and would require creating multiple ranges)\n\t\tif (startPos.node !== endPos.node) {\n\t\t\tconsole.warn(\n\t\t\t\t`[TTSService] Word spans multiple nodes, highlighting in first node only`,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tnode: startPos.node,\n\t\t\t\tstart: startPos.offset,\n\t\t\t\tend: (startPos.node.textContent || \"\").length,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tnode: startPos.node,\n\t\t\tstart: startPos.offset,\n\t\t\tend: endPos.offset + 1, // +1 because we want to include the character at endPos\n\t\t};\n\t}\n\n\t/**\n\t * Speak text with optional catalog support\n\t *\n\t * @param text Text to speak (will be normalized: trimmed and whitespace collapsed)\n\t * @param options Optional catalog ID, language, and content element for highlighting\n\t */\n\tasync speak(text: string, options?: SpeakOptions): Promise<void> {\n\t\tif (!this.provider) {\n\t\t\tthrow new Error(\"TTS service not initialized\");\n\t\t}\n\t\tconst runId = ++this.speakRunId;\n\t\ttry {\n\t\t\tawait this.applyLanguageSettings(options);\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tconst resolvedContent = await this.resolveSpeechContent(text, options);\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tconst {\n\t\t\t\tcontentToSpeak,\n\t\t\t\tspeechText,\n\t\t\t\thighlightText,\n\t\t\t\tnormalizedText,\n\t\t\t\tusedCatalogSpoken,\n\t\t\t\tspeechSource,\n\t\t\t\tspeechMatchesVisibleText,\n\t\t\t\tspeechChunks,\n\t\t\t} = resolvedContent;\n\t\t\tthis.logResolvedSpeechContent({\n\t\t\t\tcontentToSpeak,\n\t\t\t\tspeechSource,\n\t\t\t\tcatalogId: options?.catalogId,\n\t\t\t});\n\t\t\tthis.initializeSpeakTracking(highlightText, options);\n\t\t\tconst highlightMode =\n\t\t\t\toptions?.highlightModeOverride ||\n\t\t\t\t(speechMatchesVisibleText ? this.resolveHighlightMode() : \"sentence\");\n\t\t\tthis.activeHighlightMode = highlightMode;\n\t\t\tthis.activeWordBoundaryOffset = options?.wordBoundaryOffset || 0;\n\t\t\tconst hasExplicitBreaks = this.hasExplicitBreakSemantics(contentToSpeak);\n\t\t\tconst shouldUsePlan =\n\t\t\t\t!!this.currentContentElement &&\n\t\t\t\t!usedCatalogSpoken &&\n\t\t\t\t!hasExplicitBreaks &&\n\t\t\t\tspeechMatchesVisibleText;\n\t\t\tthis.playbackChunks = speechChunks?.length ? speechChunks : [];\n\t\t\tthis.seekSegments = this.playbackChunks.length\n\t\t\t\t? this.createSeekSegmentsFromSpeechChunks(this.playbackChunks)\n\t\t\t\t: hasExplicitBreaks || !speechMatchesVisibleText\n\t\t\t\t\t? []\n\t\t\t\t\t: shouldUsePlan && this.currentContentElement\n\t\t\t\t\t\t? this.createSpeechPlan(this.currentContentElement, normalizedText)\n\t\t\t\t\t\t: this.createSeekSegmentsFromText(highlightText);\n\t\t\tthis.sentenceHighlightSegments = hasExplicitBreaks\n\t\t\t\t? []\n\t\t\t\t: this.createSentenceHighlightSegments({\n\t\t\t\t\t\tcontentToSpeak: highlightText,\n\t\t\t\t\t\tshouldUsePlan,\n\t\t\t\t\t\tplaybackSegments: this.seekSegments,\n\t\t\t\t\t});\n\t\t\tthis.setState(PlaybackState.LOADING);\n\t\t\tthis.prepareHighlightsForSpeak({\n\t\t\t\tcontentToSpeak: highlightText,\n\t\t\t\toptions,\n\t\t\t\thighlightMode,\n\t\t\t\tshouldUsePlan,\n\t\t\t});\n\n\t\t\tif (speechMatchesVisibleText) {\n\t\t\t\tthis.configureWordBoundaryHighlighting({\n\t\t\t\t\thighlightMode,\n\t\t\t\t\twordBoundaryOffset: options?.wordBoundaryOffset || 0,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.clearWordBoundaryHighlighting();\n\t\t\t}\n\t\t\tthis.setState(PlaybackState.PLAYING);\n\t\t\tawait this.executeSpeakPlayback({\n\t\t\t\tshouldUsePlan,\n\t\t\t\trunId,\n\t\t\t\thighlightMode,\n\t\t\t\tcontentToSpeak: speechText,\n\t\t\t\tspeechChunks,\n\t\t\t});\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tthis.setState(PlaybackState.IDLE);\n\t\t\tthis.clearHighlightsAndTracking();\n\t\t} catch (error) {\n\t\t\tlet finalError = error;\n\t\t\tconsole.error(\"TTS error:\", finalError);\n\t\t\tthis.lastError =\n\t\t\t\tfinalError instanceof Error ? finalError.message : String(finalError);\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tthis.setState(PlaybackState.ERROR);\n\t\t\tthis.clearHighlightsAndTracking();\n\t\t\tthrow finalError;\n\t\t}\n\t}\n\n\tprivate async switchProviderToBrowser(\n\t\treason: unknown,\n\t\tcontext?: { operation?: string; contentToSpeak?: string },\n\t): Promise<boolean> {\n\t\tif (!this.currentProvider) return false;\n\t\tconst fallbackProvider = new BrowserTTSProvider();\n\t\tconst previousProviderId = this.currentProvider.providerId;\n\t\tconst browserConfig: Partial<TTSConfig> = { ...this.ttsConfig };\n\t\tconst operation = context?.operation || \"tts-initialize\";\n\t\tconst offendingText = context?.contentToSpeak ?? \"\";\n\t\tconst offendingPreview = offendingText\n\t\t\t.replace(/\\s+/g, \" \")\n\t\t\t.trim()\n\t\t\t.slice(0, 120);\n\t\tconst offendingDiagnostic =\n\t\t\toffendingText.length > 0\n\t\t\t\t? {\n\t\t\t\t\t\ttextLength: offendingText.length,\n\t\t\t\t\t\ttextPreview:\n\t\t\t\t\t\t\toffendingPreview.length < offendingText.length\n\t\t\t\t\t\t\t\t? `${offendingPreview}…`\n\t\t\t\t\t\t\t\t: offendingPreview,\n\t\t\t\t\t}\n\t\t\t\t: {};\n\t\ttry {\n\t\t\tthis.provider?.stop();\n\t\t\tthis.currentProvider.destroy();\n\t\t\tthis.currentProvider = fallbackProvider;\n\t\t\tthis.provider = await fallbackProvider.initialize(\n\t\t\t\tbrowserConfig as TTSConfig,\n\t\t\t);\n\t\t\tthis.ttsConfig = browserConfig;\n\t\t\tawait this.emitTelemetry(\"pie-tool-runtime-fallback\", {\n\t\t\t\ttoolId: \"textToSpeech\",\n\t\t\t\toperation,\n\t\t\t\tfromProvider: previousProviderId,\n\t\t\t\ttoProvider: fallbackProvider.providerId,\n\t\t\t\treason: reason instanceof Error ? reason.message : String(reason),\n\t\t\t\t...offendingDiagnostic,\n\t\t\t});\n\t\t\tconsole.warn(\n\t\t\t\t\"[TTSService] TTS provider initialization failed; switched to browser fallback\",\n\t\t\t\t{\n\t\t\t\t\tfromProvider: previousProviderId,\n\t\t\t\t\treason,\n\t\t\t\t\t...offendingDiagnostic,\n\t\t\t\t},\n\t\t\t);\n\t\t\treturn true;\n\t\t} catch (fallbackError) {\n\t\t\tawait this.emitTelemetry(\"pie-tool-runtime-fallback-error\", {\n\t\t\t\ttoolId: \"textToSpeech\",\n\t\t\t\toperation,\n\t\t\t\tfromProvider: previousProviderId,\n\t\t\t\ttoProvider: \"browser\",\n\t\t\t\terrorType: \"TTSRuntimeFallbackError\",\n\t\t\t\tmessage:\n\t\t\t\t\tfallbackError instanceof Error\n\t\t\t\t\t\t? fallbackError.message\n\t\t\t\t\t\t: String(fallbackError),\n\t\t\t});\n\t\t\tconsole.error(\n\t\t\t\t\"[TTSService] Failed to switch to browser fallback provider\",\n\t\t\t\tfallbackError,\n\t\t\t);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate isBrowserSpeechFallbackAvailable(): boolean {\n\t\tif (typeof window === \"undefined\") return false;\n\t\tif (!(\"speechSynthesis\" in window)) return false;\n\t\treturn (\n\t\t\ttypeof (globalThis as Record<string, unknown>)\n\t\t\t\t.SpeechSynthesisUtterance === \"function\"\n\t\t);\n\t}\n\n\tprivate async applyLanguageSettings(options?: SpeakOptions): Promise<void> {\n\t\tif (!options?.language || !this.provider) return;\n\t\tconst providerOptions = (this.ttsConfig.providerOptions || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst textNormalization = (providerOptions.textNormalization ||\n\t\t\t{}) as Record<string, unknown>;\n\t\tconst segmenter = (providerOptions.segmenter || {}) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t\tconst mergedProviderOptions = {\n\t\t\t...providerOptions,\n\t\t\tlocale: options.language,\n\t\t\ttextNormalization: {\n\t\t\t\t...textNormalization,\n\t\t\t\tlocale: options.language,\n\t\t\t},\n\t\t\tsegmenter: {\n\t\t\t\t...segmenter,\n\t\t\t\tlocale: options.language,\n\t\t\t},\n\t\t};\n\t\tthis.ttsConfig = {\n\t\t\t...this.ttsConfig,\n\t\t\tproviderOptions: mergedProviderOptions,\n\t\t};\n\t\tif (\n\t\t\t\"updateSettings\" in this.provider &&\n\t\t\ttypeof (this.provider as { updateSettings?: unknown }).updateSettings ===\n\t\t\t\t\"function\"\n\t\t) {\n\t\t\tawait (\n\t\t\t\tthis.provider as {\n\t\t\t\t\tupdateSettings: (\n\t\t\t\t\t\tsettings: Partial<TTSConfig>,\n\t\t\t\t\t) => Promise<void> | void;\n\t\t\t\t}\n\t\t\t).updateSettings({ providerOptions: mergedProviderOptions });\n\t\t}\n\t}\n\n\tprivate async resolveSpeechContent(\n\t\ttext: string,\n\t\toptions?: SpeakOptions,\n\t): Promise<ResolvedSpeechContent> {\n\t\tconst normalizedInputText = normalizeTextForSpeech(text);\n\t\tif (options?.ignoreCatalogs) {\n\t\t\treturn {\n\t\t\t\tcontentToSpeak: normalizedInputText,\n\t\t\t\tspeechText: normalizedInputText,\n\t\t\t\tvisibleText: normalizedInputText,\n\t\t\t\thighlightText: normalizedInputText,\n\t\t\t\tusedCatalogSpoken: false,\n\t\t\t\tspeechSource: \"dom-or-input\",\n\t\t\t\tnormalizedText: normalizedInputText,\n\t\t\t\tcontainsMathMarkup: false,\n\t\t\t\tspeechMatchesVisibleText: true,\n\t\t\t};\n\t\t}\n\t\tif (options?.catalogId && this.catalogResolver) {\n\t\t\tconst catalogContent = this.catalogResolver.getAlternative(\n\t\t\t\toptions.catalogId,\n\t\t\t\t{\n\t\t\t\t\ttype: \"spoken\",\n\t\t\t\t\tlanguage: options.language || \"en-US\",\n\t\t\t\t\tuseFallback: true,\n\t\t\t\t\tcontext: options.catalogContext,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (catalogContent) {\n\t\t\t\tconst visibleText = options?.contentElement\n\t\t\t\t\t? collectMathAwareTextAndMap(\n\t\t\t\t\t\t\toptions.contentElement,\n\t\t\t\t\t\t\tthis.getTextProcessingOptions(options.language),\n\t\t\t\t\t\t).visibleText || normalizedInputText\n\t\t\t\t\t: normalizedInputText;\n\t\t\t\tconst normalizedCatalogText = normalizeTextForSpeech(\n\t\t\t\t\tcatalogContent.content,\n\t\t\t\t);\n\t\t\t\tthis.debugLog(\n\t\t\t\t\t`[TTSService] Using catalog content for \"${options.catalogId}\" (${catalogContent.language})`,\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tcontentToSpeak: catalogContent.content,\n\t\t\t\t\tspeechText: catalogContent.content,\n\t\t\t\t\tvisibleText,\n\t\t\t\t\thighlightText: visibleText,\n\t\t\t\t\tusedCatalogSpoken: true,\n\t\t\t\t\tspeechSource: \"catalog-spoken\",\n\t\t\t\t\tnormalizedText: visibleText,\n\t\t\t\t\tcontainsMathMarkup: false,\n\t\t\t\t\tspeechMatchesVisibleText: normalizedCatalogText === visibleText,\n\t\t\t\t};\n\t\t\t}\n\t\t\tthis.debugLog(\n\t\t\t\t`[TTSService] No catalog found for \"${options.catalogId}\", falling back to generated TTS`,\n\t\t\t);\n\t\t}\n\n\t\tconst composed = options?.contentElement\n\t\t\t? this.resolveCatalogComposedSpeechContent(\n\t\t\t\t\toptions.contentElement,\n\t\t\t\t\tnormalizedInputText,\n\t\t\t\t\toptions,\n\t\t\t\t)\n\t\t\t: null;\n\t\tif (composed) return composed;\n\n\t\tconst generated = options?.contentElement\n\t\t\t? await this.resolveGeneratedSpeechContent(\n\t\t\t\t\toptions.contentElement,\n\t\t\t\t\tnormalizedInputText,\n\t\t\t\t\toptions.language,\n\t\t\t\t)\n\t\t\t: {\n\t\t\t\t\tcontentToSpeak: normalizedInputText,\n\t\t\t\t\tspeechText: normalizedInputText,\n\t\t\t\t\tvisibleText: normalizedInputText,\n\t\t\t\t\thighlightText: normalizedInputText,\n\t\t\t\t\tnormalizedText: normalizedInputText,\n\t\t\t\t\tcontainsMathMarkup: false,\n\t\t\t\t\tspeechMatchesVisibleText: true,\n\t\t\t\t};\n\t\treturn {\n\t\t\t...generated,\n\t\t\tusedCatalogSpoken: false,\n\t\t\tspeechSource: \"dom-or-input\",\n\t\t};\n\t}\n\n\tprivate resolveCatalogComposedSpeechContent(\n\t\tcontentElement: Element,\n\t\tnormalizedInputText: string,\n\t\toptions: SpeakOptions,\n\t): ResolvedSpeechContent | null {\n\t\tif (!this.catalogResolver) return null;\n\t\tconst chunks = this.collectCatalogSpeechChunks(contentElement, options);\n\t\tif (!chunks.some((chunk) => chunk.sourceElement)) return null;\n\t\tconst speechText = normalizeTextForSpeech(\n\t\t\tchunks.map((chunk) => chunk.speechText).join(\" \"),\n\t\t);\n\t\tconst visibleText =\n\t\t\tcollectMathAwareTextAndMap(\n\t\t\t\tcontentElement,\n\t\t\t\tthis.getTextProcessingOptions(options.language),\n\t\t\t).visibleText || normalizedInputText;\n\t\treturn {\n\t\t\tcontentToSpeak: speechText,\n\t\t\tspeechText,\n\t\t\tvisibleText,\n\t\t\thighlightText: visibleText,\n\t\t\tusedCatalogSpoken: true,\n\t\t\tspeechSource: \"catalog-spoken\",\n\t\t\tnormalizedText: visibleText,\n\t\t\tcontainsMathMarkup: false,\n\t\t\tspeechMatchesVisibleText: chunks.every(\n\t\t\t\t(chunk) => chunk.speechMatchesVisibleText,\n\t\t\t),\n\t\t\tspeechChunks: chunks,\n\t\t};\n\t}\n\n\tprivate collectCatalogSpeechChunks(\n\t\troot: Element,\n\t\toptions: SpeakOptions,\n\t): SpeechCompositionChunk[] {\n\t\tconst chunks: SpeechCompositionChunk[] = [];\n\t\tlet textBuffer = \"\";\n\t\tconst flushTextBuffer = () => {\n\t\t\tconst visibleText = normalizeTextForSpeech(textBuffer);\n\t\t\ttextBuffer = \"\";\n\t\t\tif (!visibleText) return;\n\t\t\tchunks.push({\n\t\t\t\tspeechText: visibleText,\n\t\t\t\tvisibleText,\n\t\t\t\tsourceElement: null,\n\t\t\t\tspeechMatchesVisibleText: true,\n\t\t\t});\n\t\t};\n\t\tconst resolveCatalog = (element: Element): ResolvedCatalog | null => {\n\t\t\tconst catalogIdRef = element.getAttribute(\"data-catalog-idref\");\n\t\t\tif (!catalogIdRef) return null;\n\t\t\treturn this.catalogResolver!.getAlternative(catalogIdRef, {\n\t\t\t\ttype: \"spoken\",\n\t\t\t\tlanguage: options.language || \"en-US\",\n\t\t\t\tuseFallback: true,\n\t\t\t\tcontext: options.catalogContext,\n\t\t\t});\n\t\t};\n\t\tconst getSingleMathElementForAlignment = (\n\t\t\telement: Element,\n\t\t\tvisibleText: string,\n\t\t): Element | null => {\n\t\t\tconst mathElements = getMathElementsForAlignment(element);\n\t\t\tif (mathElements.length !== 1) return null;\n\t\t\tconst mathElement = mathElements[0];\n\t\t\tconst mathVisibleText =\n\t\t\t\tcollectMathAwareTextAndMap(\n\t\t\t\t\tmathElement,\n\t\t\t\t\tthis.getTextProcessingOptions(options.language),\n\t\t\t\t).visibleText || normalizeTextForSpeech(mathElement.textContent || \"\");\n\t\t\tconst compact = (value: string) =>\n\t\t\t\tnormalizeTextForSpeech(value).replace(/\\s+/g, \"\");\n\t\t\treturn compact(mathVisibleText) === compact(visibleText)\n\t\t\t\t? mathElement\n\t\t\t\t: null;\n\t\t};\n\t\tconst getMathElementsForAlignment = (element: Element): Element[] => {\n\t\t\tconst mathElements = Array.from(element.querySelectorAll(\"math\"));\n\t\t\tif (element.localName?.toLowerCase() === \"math\") {\n\t\t\t\treturn [element, ...mathElements];\n\t\t\t}\n\t\t\treturn mathElements;\n\t\t};\n\t\tconst visit = (node: Node) => {\n\t\t\tif (isNodeHiddenForTTS(node, root)) return;\n\t\t\tif (node.nodeType === Node.TEXT_NODE) {\n\t\t\t\ttextBuffer += ` ${node.textContent || \"\"}`;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (node.nodeType !== Node.ELEMENT_NODE) return;\n\t\t\tconst element = node as Element;\n\t\t\tconst catalog = resolveCatalog(element);\n\t\t\tif (catalog) {\n\t\t\t\tflushTextBuffer();\n\t\t\t\tconst collectedVisible = collectMathAwareTextAndMap(\n\t\t\t\t\telement,\n\t\t\t\t\tthis.getTextProcessingOptions(options.language),\n\t\t\t\t);\n\t\t\t\tconst visibleText =\n\t\t\t\t\tcollectedVisible.visibleText ||\n\t\t\t\t\tnormalizeTextForSpeech(element.textContent || \"\");\n\t\t\t\tconst alignment = createCatalogSpanAlignment({\n\t\t\t\t\tspeechText: catalog.content,\n\t\t\t\t\tvisibleText,\n\t\t\t\t});\n\t\t\t\tconst mathElement = getSingleMathElementForAlignment(\n\t\t\t\t\telement,\n\t\t\t\t\tvisibleText,\n\t\t\t\t);\n\t\t\t\tconst mathAlignment = mathElement\n\t\t\t\t\t? createMathAwareAlignment({\n\t\t\t\t\t\t\tmathElement,\n\t\t\t\t\t\t\tspeechText: catalog.content,\n\t\t\t\t\t\t})\n\t\t\t\t\t: undefined;\n\t\t\t\tconst mathAlignments = mathAlignment\n\t\t\t\t\t? undefined\n\t\t\t\t\t: getMathElementsForAlignment(element).map((candidate) => ({\n\t\t\t\t\t\t\telement: candidate,\n\t\t\t\t\t\t\talignment: createMathAwareAlignment({\n\t\t\t\t\t\t\t\tmathElement: candidate,\n\t\t\t\t\t\t\t\tspeechText: catalog.content,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}));\n\t\t\t\tconst speechText = normalizeTextForSpeech(catalog.content);\n\t\t\t\tchunks.push({\n\t\t\t\t\tspeechText: catalog.content,\n\t\t\t\t\tvisibleText,\n\t\t\t\t\tsourceElement: element,\n\t\t\t\t\tregionElement: resolveReadableRegion(element, root),\n\t\t\t\t\tspeechMatchesVisibleText: speechText === visibleText,\n\t\t\t\t\tplaybackMode: alignment.playbackMode,\n\t\t\t\t\talignment,\n\t\t\t\t\tmathAlignment,\n\t\t\t\t\tmathAlignments,\n\t\t\t\t\tvisibleMap: collectedVisible.map,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const child of Array.from(element.childNodes)) {\n\t\t\t\tvisit(child);\n\t\t\t}\n\t\t};\n\t\tvisit(root);\n\t\tflushTextBuffer();\n\t\treturn chunks;\n\t}\n\n\t/**\n\t * Decide the playback format for the generated (no authored catalog) math\n\t * path. SSML is only emitted to providers that report `supportsSSML`: the\n\t * browser Web Speech API speaks tags literally (capability `false`), and the\n\t * server bridge reports `true` only for SSML-reliable backends (Polly,\n\t * Google) — the `custom`/SchoolCity transport stays plain.\n\t *\n\t * A speak-time plain fallback (`SpeechCompositionChunk.plainFallback`) is the\n\t * defensive net if a capable provider still rejects a given SSML payload.\n\t */\n\tprivate resolveGeneratedPlaybackFormat(): \"plain\" | \"ssml\" {\n\t\tconst provider = this.currentProvider;\n\t\tif (!provider) return \"plain\";\n\t\t// Belt-and-suspenders: the browser provider can never voice SSML.\n\t\tif (provider.providerId?.toLowerCase() === \"browser\") return \"plain\";\n\t\treturn provider.getCapabilities?.().supportsSSML ? \"ssml\" : \"plain\";\n\t}\n\n\tprivate async resolveGeneratedSpeechContent(\n\t\tcontentElement: Element,\n\t\tnormalizedInputText: string,\n\t\tlanguage?: string,\n\t): Promise<\n\t\tPick<\n\t\t\tResolvedSpeechContent,\n\t\t\t| \"contentToSpeak\"\n\t\t\t| \"speechText\"\n\t\t\t| \"visibleText\"\n\t\t\t| \"highlightText\"\n\t\t\t| \"normalizedText\"\n\t\t\t| \"containsMathMarkup\"\n\t\t\t| \"speechMatchesVisibleText\"\n\t\t\t| \"speechChunks\"\n\t\t>\n\t> {\n\t\t// Delegate to the generated-speech module: a pure plan assembly + SRE\n\t\t// memoization core, plus a DOM adapter that binds live-DOM anchors and\n\t\t// emits playback chunks. The aggregate `contentToSpeak` stays plain text\n\t\t// (`plan.plainSpeechText`) so seek/structural-pause planning is unaffected.\n\t\tconst playbackFormat = this.resolveGeneratedPlaybackFormat();\n\t\tconst {\n\t\t\tplan,\n\t\t\tcontainsMathMarkup,\n\t\t\tvisibleText: collectedVisibleText,\n\t\t} = await buildGeneratedSpeechFromRoot({\n\t\t\tcontentRoot: contentElement,\n\t\t\tlanguage,\n\t\t\tmathSpeech: this.getMathSpeechOptions(),\n\t\t\ttextProcessingOptions: this.getTextProcessingOptions(language),\n\t\t\tproduceSsml: playbackFormat === \"ssml\",\n\t\t\tresolveMathSpeech: this.generatedMathSpeechResolver,\n\t\t});\n\t\tconst visibleText = collectedVisibleText || normalizedInputText;\n\t\tif (!containsMathMarkup) {\n\t\t\treturn {\n\t\t\t\tcontentToSpeak: visibleText,\n\t\t\t\tspeechText: visibleText,\n\t\t\t\tvisibleText,\n\t\t\t\thighlightText: visibleText,\n\t\t\t\tnormalizedText: visibleText,\n\t\t\t\tcontainsMathMarkup: false,\n\t\t\t\tspeechMatchesVisibleText: true,\n\t\t\t};\n\t\t}\n\t\tconst speechChunks = planToCompositionChunkInputs(plan, {\n\t\t\tformat: playbackFormat,\n\t\t});\n\t\tconst speechText = plan.plainSpeechText;\n\t\treturn {\n\t\t\tcontentToSpeak: speechText,\n\t\t\tspeechText,\n\t\t\tvisibleText,\n\t\t\thighlightText: visibleText,\n\t\t\tnormalizedText: visibleText,\n\t\t\tcontainsMathMarkup: true,\n\t\t\tspeechMatchesVisibleText: speechText === visibleText,\n\t\t\tspeechChunks,\n\t\t};\n\t}\n\n\tprivate logResolvedSpeechContent(args: {\n\t\tcontentToSpeak: string;\n\t\tspeechSource: \"catalog-spoken\" | \"dom-or-input\";\n\t\tcatalogId?: string;\n\t}): void {\n\t\tconst preview = args.contentToSpeak\n\t\t\t.replace(/\\s+/g, \" \")\n\t\t\t.trim()\n\t\t\t.slice(0, 200);\n\t\tthis.debugLog(\"[TTSService] Speak resolved content\", {\n\t\t\tsource: args.speechSource,\n\t\t\tcatalogId: args.catalogId || null,\n\t\t\tlength: args.contentToSpeak.length,\n\t\t\tpreview,\n\t\t});\n\t}\n\n\tprivate initializeSpeakTracking(\n\t\tcontentToSpeak: string,\n\t\toptions?: SpeakOptions,\n\t): void {\n\t\tthis.currentText = contentToSpeak;\n\t\tthis.currentContentElement = options?.contentElement || null;\n\t\tthis.lastError = null;\n\t\tthis.currentBoundaryOffset = 0;\n\t\tthis.playbackChunks = [];\n\t\tthis.currentSeekSegmentIndex = 0;\n\t\tthis.activeSentenceStartOffset = null;\n\t}\n\n\tprivate prepareHighlightsForSpeak(args: {\n\t\tcontentToSpeak: string;\n\t\toptions?: SpeakOptions;\n\t\thighlightMode: HighlightMode;\n\t\tshouldUsePlan: boolean;\n\t}): void {\n\t\tif (!this.currentContentElement || !this.highlightCoordinator) return;\n\t\tthis.buildPositionMap(\n\t\t\tthis.currentContentElement,\n\t\t\targs.contentToSpeak,\n\t\t\targs.options?.language,\n\t\t);\n\t\tif (args.highlightMode === \"sentence\" && args.shouldUsePlan) {\n\t\t\treturn;\n\t\t}\n\t\tconst initialSegment =\n\t\t\tthis.sentenceHighlightSegments[0] || this.seekSegments[0];\n\t\tif (initialSegment) {\n\t\t\tthis.highlightSentenceSegment(\n\t\t\t\tinitialSegment.startOffset,\n\t\t\t\tinitialSegment.text,\n\t\t\t);\n\t\t\tthis.debugLog(\"[TTSService] Applied initial sentence highlighting\");\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst range = document.createRange();\n\t\t\t\trange.selectNodeContents(this.currentContentElement);\n\t\t\t\tthis.paintTTSSentenceRanges([range]);\n\t\t\t} catch {\n\t\t\t\t// No-op fallback when DOM range creation fails.\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate configureWordBoundaryHighlighting(args: {\n\t\thighlightMode: HighlightMode;\n\t\twordBoundaryOffset: number;\n\t}): void {\n\t\tif (\n\t\t\t!this.provider ||\n\t\t\targs.highlightMode !== \"word\" ||\n\t\t\t!this.highlightCoordinator ||\n\t\t\t!this.currentContentElement\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\t// Word index uses the same globalIndex as highlightTTSWord (browser boundaries\n\t\t// or ServerTTSProvider time-scaled onWordBoundary).\n\t\tthis.provider.onWordBoundary = (\n\t\t\tword: string,\n\t\t\tcharIndex: number,\n\t\t\tlength?: number,\n\t\t) => {\n\t\t\tconst wordLength = length || word.length;\n\t\t\tconst globalIndex =\n\t\t\t\tcharIndex + this.currentBoundaryOffset + args.wordBoundaryOffset;\n\t\t\tthis.highlightSentenceForOffset(globalIndex);\n\t\t\tconst highlightRange = this.findHighlightRange(globalIndex, wordLength);\n\t\t\tif (highlightRange && this.highlightCoordinator) {\n\t\t\t\tconst highlightText =\n\t\t\t\t\thighlightRange.node.textContent?.substring(\n\t\t\t\t\t\thighlightRange.start,\n\t\t\t\t\t\thighlightRange.end,\n\t\t\t\t\t) || \"\";\n\t\t\t\tthis.debugLog(\n\t\t\t\t\t`[TTSService] Highlighting \"${highlightText}\" (word: \"${word}\") at position ${globalIndex}`,\n\t\t\t\t);\n\t\t\t\tconst nativeRange = this.createTextRange(\n\t\t\t\t\thighlightRange.node,\n\t\t\t\t\thighlightRange.start,\n\t\t\t\t\thighlightRange.end,\n\t\t\t\t);\n\t\t\t\tif (nativeRange) {\n\t\t\t\t\tthis.paintTTSWordRange(\n\t\t\t\t\t\tthis.resolveWordHighlightRange(nativeRange).range,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.highlightCoordinator.highlightTTSWord(\n\t\t\t\t\t\thighlightRange.node,\n\t\t\t\t\t\thighlightRange.start,\n\t\t\t\t\t\thighlightRange.end,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[TTSService] Could not find highlight range for position ${globalIndex}, length ${wordLength}`,\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\t}\n\n\tprivate clearWordBoundaryHighlighting(): void {\n\t\tif (this.provider) {\n\t\t\tthis.provider.onWordBoundary = undefined;\n\t\t}\n\t}\n\n\tprivate highlightCatalogRegion(chunk: SpeechCompositionChunk): void {\n\t\tconst element = chunk.regionElement || chunk.sourceElement;\n\t\tif ((!element && !chunk.regionRange) || !this.highlightCoordinator) return;\n\t\ttry {\n\t\t\tthis.lastRenderedRegionTarget = null;\n\t\t\tif (chunk.regionRange) {\n\t\t\t\tthis.highlightCoordinator.clearHighlights?.(HighlightType.TTS_WORD);\n\t\t\t\tthis.paintTTSSentenceRanges([chunk.regionRange]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!element) return;\n\t\t\tconst range = document.createRange();\n\t\t\trange.selectNodeContents(element);\n\t\t\tthis.highlightCoordinator.clearHighlights?.(HighlightType.TTS_WORD);\n\t\t\tthis.paintTTSSentenceRanges([range]);\n\t\t} catch {\n\t\t\t// Continue playback even when a detached node cannot be highlighted.\n\t\t}\n\t}\n\n\tprivate highlightCatalogActiveRange(range: Range): void {\n\t\tif (!this.highlightCoordinator) return;\n\t\tthis.paintTTSWordRange(this.resolveWordHighlightRange(range).range);\n\t}\n\n\tprivate highlightRenderableRegionTarget(\n\t\ttarget: RenderableHighlightTarget | null,\n\t): void {\n\t\tif (\n\t\t\t!this.highlightCoordinator ||\n\t\t\t!target ||\n\t\t\ttypeof document === \"undefined\"\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\t!this.highlightTargetResolverProvider &&\n\t\t\tsameRenderableHighlightTarget(this.lastRenderedRegionTarget, target)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst range = document.createRange();\n\t\t\tif (target.type === \"element\") {\n\t\t\t\trange.selectNodeContents(target.element);\n\t\t\t} else if (target.type === \"range\") {\n\t\t\t\tthis.paintTTSSentenceRanges([target.range]);\n\t\t\t\tthis.lastRenderedRegionTarget = target;\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\trange.setStart(target.node, target.startOffset);\n\t\t\t\trange.setEnd(target.node, target.endOffset);\n\t\t\t}\n\t\t\tthis.paintTTSSentenceRanges([range]);\n\t\t\tthis.lastRenderedRegionTarget = target;\n\t\t} catch {\n\t\t\t// Continue playback even when a detached node cannot be highlighted.\n\t\t}\n\t}\n\n\tprivate highlightRenderableActiveTarget(\n\t\ttarget: RenderableHighlightTarget | null,\n\t): void {\n\t\tif (!this.highlightCoordinator || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\t\tif (!target) {\n\t\t\t// No active word for this boundary — an unresolved prose word, an SSML\n\t\t\t// break/pause, or a token-mode equation still awaiting its first token.\n\t\t\t// Clear the word layer so the previously spoken word does not stay\n\t\t\t// highlighted. (The \"hold last token\" behavior returns a non-null\n\t\t\t// target, so it does not reach here.)\n\t\t\tthis.highlightCoordinator.clearHighlights(HighlightType.TTS_WORD);\n\t\t\treturn;\n\t\t}\n\t\tif (target.type === \"text-range\") {\n\t\t\tconst nativeRange = this.createTextRange(\n\t\t\t\ttarget.node,\n\t\t\t\ttarget.startOffset,\n\t\t\t\ttarget.endOffset,\n\t\t\t);\n\t\t\tif (nativeRange) {\n\t\t\t\tthis.paintTTSWordRange(\n\t\t\t\t\tthis.resolveWordHighlightRange(nativeRange).range,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.highlightCoordinator.highlightTTSWord(\n\t\t\t\t\ttarget.node,\n\t\t\t\t\ttarget.startOffset,\n\t\t\t\t\ttarget.endOffset,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (target.type === \"range\") {\n\t\t\tthis.highlightCatalogActiveRange(target.range);\n\t\t\treturn;\n\t\t}\n\t\tconst elementNativeRange = document.createRange();\n\t\telementNativeRange.selectNodeContents(target.element);\n\t\tconst resolvedElementRange =\n\t\t\tthis.resolveWordHighlightRange(elementNativeRange);\n\t\tif (resolvedElementRange.remapped) {\n\t\t\tthis.paintTTSWordRange(resolvedElementRange.range);\n\t\t\treturn;\n\t\t}\n\t\t// Element targets are atomic: a resolved math token, a whole-expression\n\t\t// fallback, or a replaced element (image/svg). Paint exactly the resolved\n\t\t// element. Native MathML / HTML tokens that expose a single text node keep\n\t\t// the CSS-range underline (it reads more precisely than an element box);\n\t\t// everything else — notably MathJax CHTML tokens (`<mjx-mi><mjx-c/>`),\n\t\t// which have no text node, and expression fallbacks — is marked on the\n\t\t// element itself. Crucially we no longer escalate to the enclosing\n\t\t// `<math>` / `<mjx-container>`: that escalation is why MathJax math only\n\t\t// ever highlighted as a full block while native MathML tracked per-token.\n\t\tconst onlyChild =\n\t\t\ttarget.element.childNodes.length === 1 ? target.element.firstChild : null;\n\t\tif (\n\t\t\ttarget.quality === \"semantic-token\" &&\n\t\t\tonlyChild?.nodeType === Node.TEXT_NODE\n\t\t) {\n\t\t\tthis.highlightCoordinator.highlightTTSWord(\n\t\t\t\tonlyChild as Text,\n\t\t\t\t0,\n\t\t\t\tonlyChild.textContent?.length || 0,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tthis.highlightCoordinator.highlightTTSWordElement?.(target.element);\n\t}\n\n\tprivate renderHighlightDecision(decision: HighlightDecision): void {\n\t\tthis.highlightRenderableRegionTarget(decision.regionTarget);\n\t\tthis.highlightRenderableActiveTarget(decision.activeTarget);\n\t}\n\n\tprivate async speakCatalogChunk(\n\t\tchunk: SpeechCompositionChunk,\n\t\trunId: number,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.speakCatalogChunkOnce(chunk, runId);\n\t\t} catch (error) {\n\t\t\t// Speak-time fallback: if an SSML math chunk is rejected by the\n\t\t\t// provider, retry once with its precomputed plain-text variant (same\n\t\t\t// anchors, plain alignment). The fallback chunk carries no further\n\t\t\t// fallback, so this cannot recurse.\n\t\t\tif (chunk.plainFallback && runId === this.speakRunId) {\n\t\t\t\tthis.debugLog(\n\t\t\t\t\t\"[TTSService] SSML chunk speak failed; retrying plain text\",\n\t\t\t\t\t{ message: error instanceof Error ? error.message : String(error) },\n\t\t\t\t);\n\t\t\t\tawait this.speakCatalogChunkOnce(chunk.plainFallback, runId);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async speakCatalogChunkOnce(\n\t\tchunk: SpeechCompositionChunk,\n\t\trunId: number,\n\t): Promise<void> {\n\t\tif (!this.provider) return;\n\t\tthis.lastRenderedRegionTarget = null;\n\t\tconst contentRoot =\n\t\t\tchunk.regionElement || chunk.sourceElement || this.currentContentElement;\n\t\tconst pipelineChunk = contentRoot\n\t\t\t? normalizeSpeechChunks({\n\t\t\t\t\tcontentRoot,\n\t\t\t\t\tchunks: [chunk],\n\t\t\t\t})[0]\n\t\t\t: null;\n\t\t// Carried through the config channel (see buildRuntimeTTSConfig); defaults\n\t\t// to per-token math highlighting unless a host explicitly disables it.\n\t\tconst mathTokenHighlighting =\n\t\t\tthis.ttsConfig.mathTokenHighlighting !== false;\n\t\tconst highlightPlan = pipelineChunk\n\t\t\t? createTTSHighlightPlan({\n\t\t\t\t\tchunks: [pipelineChunk],\n\t\t\t\t\tmathTokenHighlighting,\n\t\t\t\t})\n\t\t\t: null;\n\t\tif (highlightPlan && pipelineChunk && chunk.mathAlignment) {\n\t\t\tthis.renderHighlightDecision(\n\t\t\t\thighlightPlan.resolveInitial(pipelineChunk.id),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.highlightCatalogRegion(chunk);\n\t\t}\n\t\tconst canUseChunkBoundaries =\n\t\t\tchunk.sourceElement &&\n\t\t\t((chunk.mathAlignment && chunk.mathAlignment.speech.tokens.length > 0) ||\n\t\t\t\t(chunk.mathAlignments && chunk.mathAlignments.length > 0) ||\n\t\t\t\t(chunk.alignment &&\n\t\t\t\t\tchunk.visibleMap &&\n\t\t\t\t\t(chunk.playbackMode === \"exact-word\" ||\n\t\t\t\t\t\tchunk.playbackMode === \"anchor-span\")));\n\t\tif (!canUseChunkBoundaries) {\n\t\t\tconst provider = this.provider;\n\t\t\tconst previousOnWordBoundary = provider.onWordBoundary;\n\t\t\tprovider.onWordBoundary = undefined;\n\t\t\ttry {\n\t\t\t\tawait provider.speak(chunk.speechText);\n\t\t\t} finally {\n\t\t\t\tif (\n\t\t\t\t\tthis.provider === provider &&\n\t\t\t\t\trunId === this.speakRunId &&\n\t\t\t\t\tprovider.onWordBoundary === undefined\n\t\t\t\t) {\n\t\t\t\t\tprovider.onWordBoundary = previousOnWordBoundary;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst provider = this.provider;\n\t\tconst previousOnWordBoundary = provider.onWordBoundary;\n\t\tconst installedHandler: NonNullable<\n\t\t\tITTSProviderImplementation[\"onWordBoundary\"]\n\t\t> = (word, position, length) => {\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tif (highlightPlan && pipelineChunk) {\n\t\t\t\tconst providerOffsetSpace =\n\t\t\t\t\tpipelineChunk.offsetSpace === \"unsupported\"\n\t\t\t\t\t\t? \"unknown\"\n\t\t\t\t\t\t: (pipelineChunk.offsetSpace as Exclude<\n\t\t\t\t\t\t\t\tChunkOffsetSpace,\n\t\t\t\t\t\t\t\t\"unsupported\"\n\t\t\t\t\t\t\t>);\n\t\t\t\tthis.renderHighlightDecision(\n\t\t\t\t\thighlightPlan.resolveBoundary({\n\t\t\t\t\t\tchunkId: pipelineChunk.id,\n\t\t\t\t\t\tword,\n\t\t\t\t\t\tposition,\n\t\t\t\t\t\tlength,\n\t\t\t\t\t\tproviderOffsetSpace,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t};\n\t\tprovider.onWordBoundary = installedHandler;\n\t\ttry {\n\t\t\tawait provider.speak(chunk.speechText);\n\t\t} finally {\n\t\t\tif (\n\t\t\t\tthis.provider === provider &&\n\t\t\t\trunId === this.speakRunId &&\n\t\t\t\tprovider.onWordBoundary === installedHandler\n\t\t\t) {\n\t\t\t\tprovider.onWordBoundary = previousOnWordBoundary;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async executeSpeakPlayback(args: {\n\t\tshouldUsePlan: boolean;\n\t\trunId: number;\n\t\thighlightMode: HighlightMode;\n\t\tcontentToSpeak: string;\n\t\tspeechChunks?: SpeechCompositionChunk[];\n\t}): Promise<void> {\n\t\tif (args.speechChunks?.length && this.provider) {\n\t\t\tfor (let index = 0; index < args.speechChunks.length; index++) {\n\t\t\t\tif (args.runId !== this.speakRunId) return;\n\t\t\t\tthis.currentSeekSegmentIndex = index;\n\t\t\t\tconst segment = this.seekSegments[index];\n\t\t\t\tif (segment) {\n\t\t\t\t\tthis.currentBoundaryOffset = segment.startOffset;\n\t\t\t\t}\n\t\t\t\tconst chunk = args.speechChunks[index];\n\t\t\t\tawait this.speakCatalogChunk(chunk, args.runId);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (args.shouldUsePlan && this.currentContentElement) {\n\t\t\tconst segments = this.seekSegments;\n\t\t\tif (segments.length > 0) {\n\t\t\t\tawait this.speakWithPlan(segments, args.runId, {\n\t\t\t\t\thighlightMode: args.highlightMode,\n\t\t\t\t});\n\t\t\t} else if (this.provider) {\n\t\t\t\tawait this.provider.speak(args.contentToSpeak);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (this.provider) {\n\t\t\tawait this.provider.speak(args.contentToSpeak);\n\t\t}\n\t}\n\n\tprivate clearHighlightsAndTracking(): void {\n\t\tif (this.highlightCoordinator) {\n\t\t\tthis.highlightCoordinator.clearTTS();\n\t\t}\n\t\tthis.lastRenderedRegionTarget = null;\n\t\tthis.currentContentElement = null;\n\t\tthis.normalizedToDOM.clear();\n\t\tthis.currentBoundaryOffset = 0;\n\t\tthis.activeWordBoundaryOffset = 0;\n\t\tthis.seekSegments = [];\n\t\tthis.playbackChunks = [];\n\t\tthis.sentenceHighlightSegments = [];\n\t\tthis.currentSeekSegmentIndex = 0;\n\t\tthis.activeSentenceStartOffset = null;\n\t}\n\n\t/**\n\t * Speak a text range with accurate word highlighting\n\t *\n\t * This calculates the offset of the range within its parent element\n\t * to ensure word highlighting aligns correctly with the selected text.\n\t *\n\t * @param range DOM Range to speak\n\t */\n\tasync speakRange(\n\t\trange: Range,\n\t\toptions?: { contentRoot?: Element | null },\n\t): Promise<void> {\n\t\tif (!this.provider) {\n\t\t\tthrow new Error(\"TTS service not initialized\");\n\t\t}\n\n\t\tconst text = range.toString().trim();\n\t\tif (!text) return;\n\n\t\t// Use explicit content root when provided; otherwise keep highlighting scoped\n\t\t// to the selected range's nearest element ancestor.\n\t\tconst fromOptions = options?.contentRoot || null;\n\t\tlet root: Element | null = fromOptions;\n\t\tif (!root) {\n\t\t\tconst ancestor = range.commonAncestorContainer;\n\t\t\troot =\n\t\t\t\tancestor.nodeType === Node.ELEMENT_NODE\n\t\t\t\t\t? (ancestor as Element)\n\t\t\t\t\t: ancestor.parentElement;\n\t\t}\n\t\tif (!root) return;\n\n\t\t// Calculate the offset of the range start within the root element\n\t\tconst beforeRange = document.createRange();\n\t\tbeforeRange.selectNodeContents(root);\n\t\tbeforeRange.setEnd(range.startContainer, range.startOffset);\n\t\tconst textBeforeRange = beforeRange.toString();\n\t\tconst normalizedTextBeforeRange = normalizeTextForSpeech(textBeforeRange);\n\t\tconst offset =\n\t\t\tnormalizedTextBeforeRange.length +\n\t\t\t(/\\s$/.test(textBeforeRange) && normalizedTextBeforeRange ? 1 : 0);\n\n\t\tthis.debugLog(\"[TTSService] speakRange offset calculation:\", {\n\t\t\tselectedText: text,\n\t\t\ttextBeforeRange: textBeforeRange.substring(0, 100),\n\t\t\toffset,\n\t\t\trootTag: root.tagName,\n\t\t});\n\n\t\t// Speak the text with the root element as context\n\t\tawait this.speak(text, {\n\t\t\tcontentElement: root,\n\t\t\tignoreCatalogs: true,\n\t\t\twordBoundaryOffset: offset,\n\t\t});\n\t}\n\n\t/**\n\t * Pause playback\n\t */\n\tpause(): void {\n\t\tif (!this.provider) return;\n\n\t\tif (this.state === PlaybackState.PLAYING) {\n\t\t\tthis.provider.pause();\n\t\t\tthis.setState(PlaybackState.PAUSED);\n\t\t}\n\t}\n\n\t/**\n\t * Resume playback\n\t */\n\tresume(): void {\n\t\tif (!this.provider) return;\n\n\t\tif (this.state === PlaybackState.PAUSED) {\n\t\t\tthis.provider.resume();\n\t\t\tthis.setState(PlaybackState.PLAYING);\n\t\t}\n\t}\n\n\tprivate normalizePlaybackRate(rate: number): number {\n\t\tif (!Number.isFinite(rate)) return 1;\n\t\treturn Math.max(0.25, Math.min(4, rate));\n\t}\n\n\tprivate async restartFromSeekIndex(targetIndex: number): Promise<void> {\n\t\tif (!this.provider || this.seekSegments.length === 0) return;\n\t\tconst safeTargetIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.seekSegments.length - 1, targetIndex),\n\t\t);\n\t\tconst restartChunks = this.playbackChunks.length\n\t\t\t? this.playbackChunks.slice(safeTargetIndex)\n\t\t\t: null;\n\n\t\tthis.speakRunId += 1;\n\t\tthis.provider.onWordBoundary = undefined;\n\t\tthis.provider.stop();\n\t\tthis.currentSeekSegmentIndex = safeTargetIndex;\n\t\tconst runId = ++this.speakRunId;\n\t\tconst restartSegments = this.seekSegments.slice(safeTargetIndex);\n\n\t\tthis.setState(PlaybackState.PLAYING);\n\t\ttry {\n\t\t\tthis.configureWordBoundaryHighlighting({\n\t\t\t\thighlightMode: this.activeHighlightMode,\n\t\t\t\twordBoundaryOffset: this.activeWordBoundaryOffset,\n\t\t\t});\n\t\t\tif (restartChunks) {\n\t\t\t\tfor (let index = 0; index < restartChunks.length; index++) {\n\t\t\t\t\tif (runId !== this.speakRunId) return;\n\t\t\t\t\tconst absoluteIndex = safeTargetIndex + index;\n\t\t\t\t\tthis.currentSeekSegmentIndex = absoluteIndex;\n\t\t\t\t\tconst segment = this.seekSegments[absoluteIndex];\n\t\t\t\t\tif (segment) {\n\t\t\t\t\t\tthis.currentBoundaryOffset = segment.startOffset;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.speakCatalogChunk(restartChunks[index], runId);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait this.speakWithPlan(restartSegments, runId, {\n\t\t\t\t\thighlightMode: this.activeHighlightMode,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tthis.setState(PlaybackState.IDLE);\n\t\t\tthis.clearHighlightsAndTracking();\n\t\t\tthis.highlightTargetResolverProvider = null;\n\t\t} catch (error) {\n\t\t\tif (runId !== this.speakRunId) return;\n\t\t\tthis.lastError = error instanceof Error ? error.message : String(error);\n\t\t\tthis.setState(PlaybackState.ERROR);\n\t\t\tthis.clearHighlightsAndTracking();\n\t\t\tthis.highlightTargetResolverProvider = null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync setPlaybackRate(rate: number): Promise<void> {\n\t\tconst nextRate = this.normalizePlaybackRate(rate);\n\t\tawait this.updateSettings({ rate: nextRate });\n\t\tif (\n\t\t\tthis.state !== PlaybackState.PLAYING ||\n\t\t\t!this.currentText ||\n\t\t\tthis.seekSegments.length === 0 ||\n\t\t\tthis.hasExplicitBreakSemantics(this.currentText)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex());\n\t}\n\n\tprivate async seekBy(units: number): Promise<void> {\n\t\tif (!this.provider || !this.currentText) return;\n\t\tif (\n\t\t\tthis.state !== PlaybackState.PLAYING &&\n\t\t\tthis.state !== PlaybackState.PAUSED\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.hasExplicitBreakSemantics(this.currentText)) return;\n\t\tif (this.seekSegments.length === 0) return;\n\n\t\tconst delta = Number.isFinite(units) ? Math.trunc(units) : 0;\n\t\tif (delta === 0) return;\n\n\t\tconst currentIndex = this.getCurrentSeekSegmentIndex();\n\t\tconst targetIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.seekSegments.length - 1, currentIndex + delta),\n\t\t);\n\t\tif (targetIndex === currentIndex) return;\n\n\t\tawait this.restartFromSeekIndex(targetIndex);\n\t}\n\n\tasync seekForward(units = 1): Promise<void> {\n\t\tconst step = Number.isFinite(units) ? Math.max(1, Math.trunc(units)) : 1;\n\t\tawait this.seekBy(step);\n\t}\n\n\tasync seekBackward(units = 1): Promise<void> {\n\t\tconst step = Number.isFinite(units) ? Math.max(1, Math.trunc(units)) : 1;\n\t\tawait this.seekBy(-step);\n\t}\n\n\t/**\n\t * Stop playback\n\t */\n\tstop(): void {\n\t\tif (!this.provider) return;\n\t\tthis.speakRunId += 1;\n\t\tthis.provider.onWordBoundary = undefined;\n\t\tthis.provider.stop();\n\t\tthis.highlightTargetResolverProvider = null;\n\t\tthis.setState(PlaybackState.IDLE);\n\t\tthis.currentText = null;\n\n\t\t// Clear highlights\n\t\tif (this.highlightCoordinator) {\n\t\t\tthis.highlightCoordinator.clearTTS();\n\t\t}\n\n\t\t// Clear tracking\n\t\tthis.lastRenderedRegionTarget = null;\n\t\tthis.currentContentElement = null;\n\t\tthis.normalizedToDOM.clear();\n\t\tthis.currentBoundaryOffset = 0;\n\t\tthis.activeWordBoundaryOffset = 0;\n\t\tthis.seekSegments = [];\n\t\tthis.playbackChunks = [];\n\t\tthis.sentenceHighlightSegments = [];\n\t\tthis.currentSeekSegmentIndex = 0;\n\t\tthis.activeSentenceStartOffset = null;\n\t}\n\n\t/**\n\t * Request UI-level TTS controls to hand off/deactivate.\n\t *\n\t * This is intentionally separate from playback controls so hosts can orchestrate\n\t * control handoff explicitly (for example: stop playback, then dismiss controls).\n\t */\n\trequestControlHandoff(): void {\n\t\tif (typeof window === \"undefined\") return;\n\t\tconst detail: TTSControlHandoffDetail = { source: \"host\" };\n\t\twindow.dispatchEvent(\n\t\t\tnew CustomEvent(PIE_TTS_CONTROL_HANDOFF_EVENT, {\n\t\t\t\tdetail,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Check if currently playing\n\t */\n\tisPlaying(): boolean {\n\t\treturn this.state === PlaybackState.PLAYING;\n\t}\n\n\t/**\n\t * Check if paused\n\t */\n\tisPaused(): boolean {\n\t\treturn this.state === PlaybackState.PAUSED;\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState(): PlaybackState {\n\t\treturn this.state;\n\t}\n\n\t/**\n\t * Get current text being spoken\n\t */\n\tgetCurrentText(): string | null {\n\t\treturn this.currentText;\n\t}\n\n\t/**\n\t * Get the last error message\n\t * Returns null if no error has occurred\n\t */\n\tgetLastError(): string | null {\n\t\treturn this.lastError;\n\t}\n\n\t/**\n\t * Subscribe to state changes\n\t *\n\t * @param id Unique listener ID\n\t * @param callback Function to call on state change\n\t */\n\tonStateChange(id: string, callback: (state: PlaybackState) => void): void {\n\t\tif (!this.listeners.has(id)) {\n\t\t\tthis.listeners.set(id, new Set());\n\t\t}\n\t\tthis.listeners.get(id)!.add(callback);\n\t}\n\n\t/**\n\t * Unsubscribe from state changes\n\t */\n\toffStateChange(id: string, callback: (state: PlaybackState) => void): void {\n\t\tconst callbacks = this.listeners.get(id);\n\t\tif (callbacks) {\n\t\t\tcallbacks.delete(callback);\n\t\t\tif (callbacks.size === 0) {\n\t\t\t\tthis.listeners.delete(id);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set state and notify listeners\n\t */\n\tprivate setState(newState: PlaybackState): void {\n\t\tif (this.state === newState) return;\n\n\t\tconst previousState = this.state;\n\t\tthis.state = newState;\n\n\t\t// Notify all listeners\n\t\tfor (const callbacks of this.listeners.values()) {\n\t\t\tfor (const callback of callbacks) {\n\t\t\t\tcallback(newState);\n\t\t\t}\n\t\t}\n\n\t\tvoid this.emitTelemetry(\"pie-tool-playback-state-changed\", {\n\t\t\ttoolId: \"textToSpeech\",\n\t\t\tproviderId: \"tts\",\n\t\t\tpreviousState,\n\t\t\tstate: newState,\n\t\t});\n\n\t\tif (newState === PlaybackState.PLAYING) {\n\t\t\tconst eventName =\n\t\t\t\tpreviousState === PlaybackState.PAUSED\n\t\t\t\t\t? \"pie-tool-playback-resume\"\n\t\t\t\t\t: \"pie-tool-playback-start\";\n\t\t\tvoid this.emitTelemetry(eventName, {\n\t\t\t\ttoolId: \"textToSpeech\",\n\t\t\t\tproviderId: \"tts\",\n\t\t\t\tpreviousState,\n\t\t\t\tstate: newState,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (newState === PlaybackState.PAUSED) {\n\t\t\tvoid this.emitTelemetry(\"pie-tool-playback-pause\", {\n\t\t\t\ttoolId: \"textToSpeech\",\n\t\t\t\tproviderId: \"tts\",\n\t\t\t\tpreviousState,\n\t\t\t\tstate: newState,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (newState === PlaybackState.ERROR) {\n\t\t\tvoid this.emitTelemetry(\"pie-tool-playback-error\", {\n\t\t\t\ttoolId: \"textToSpeech\",\n\t\t\t\tproviderId: \"tts\",\n\t\t\t\tpreviousState,\n\t\t\t\tstate: newState,\n\t\t\t\tmessage: this.lastError || undefined,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tnewState === PlaybackState.IDLE &&\n\t\t\t(previousState === PlaybackState.PLAYING ||\n\t\t\t\tpreviousState === PlaybackState.PAUSED ||\n\t\t\t\tpreviousState === PlaybackState.LOADING)\n\t\t) {\n\t\t\tvoid this.emitTelemetry(\"pie-tool-playback-stop\", {\n\t\t\t\ttoolId: \"textToSpeech\",\n\t\t\t\tproviderId: \"tts\",\n\t\t\t\tpreviousState,\n\t\t\t\tstate: newState,\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ThemeProvider.js","sourceRoot":"","sources":["../../src/services/ThemeProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ThemeProvider\n *\n * Applies consistent accessibility theming across items and tools.\n * Uses CSS custom properties and classes for framework-agnostic theming.\n *\n * Features:\n * - High contrast mode\n * - Font size scaling (small, normal, large, xlarge)\n * - Color customization (background, foreground, accent)\n * - Consistent theming across shadow DOM boundaries\n * - No framework dependencies\n *\n * Part of PIE Assessment Toolkit.\n */\n\nimport type { ThemeProviderApi } from \"./interfaces.js\";\n\n/**\n * Font size options\n */\nexport type FontSize = \"small\" | \"normal\" | \"large\" | \"xlarge\";\n\n/**\n * Theme configuration\n */\nexport interface ThemeConfig {\n\thighContrast?: boolean;\n\tfontSize?: FontSize;\n\tbackgroundColor?: string;\n\tforegroundColor?: string;\n\taccentColor?: string;\n\tlinkColor?: string;\n\terrorColor?: string;\n\tsuccessColor?: string;\n\twarningColor?: string;\n}\n\n/**\n * Font size scale (in rem units)\n */\nconst FONT_SIZE_SCALE: Record<FontSize, number> = {\n\tsmall: 0.875, // 14px at 16px base\n\tnormal: 1.0, // 16px at 16px base\n\tlarge: 1.25, // 20px at 16px base\n\txlarge: 1.5, // 24px at 16px base\n};\n\n/**\n * Default theme values\n */\nconst DEFAULT_THEME: Required<ThemeConfig> = {\n\thighContrast: false,\n\tfontSize: \"normal\",\n\tbackgroundColor: \"#ffffff\",\n\tforegroundColor: \"#000000\",\n\taccentColor: \"#3f51b5\",\n\tlinkColor: \"#146eb3\",\n\terrorColor: \"#ff9800\",\n\tsuccessColor: \"#4caf50\",\n\twarningColor: \"#d32f2f\",\n};\n\n/**\n * High contrast theme overrides\n */\nconst HIGH_CONTRAST_THEME: Partial<ThemeConfig> = {\n\tbackgroundColor: \"#000000\",\n\tforegroundColor: \"#ffffff\",\n\taccentColor: \"#ffff00\",\n\tlinkColor: \"#00ffff\",\n\terrorColor: \"#ff0000\",\n\tsuccessColor: \"#00ff00\",\n\twarningColor: \"#ffff00\",\n};\n\nexport class ThemeProvider implements ThemeProviderApi {\n\tprivate currentTheme: Required<ThemeConfig> = { ...DEFAULT_THEME };\n\tprivate styleElement: HTMLStyleElement | null = null;\n\tprivate rootElement: HTMLElement | null;\n\tprivate styleContainer: ShadowRoot | HTMLHeadElement | null = null;\n\n\tconstructor(\n\t\trootElement: HTMLElement | null = typeof document !== \"undefined\"\n\t\t\t? document.documentElement\n\t\t\t: null,\n\t) {\n\t\tthis.rootElement = rootElement;\n\n\t\t// SSR guard\n\t\tif (typeof document === \"undefined\") {\n\t\t\tconsole.warn(\"ThemeProvider: document not available (SSR context)\");\n\t\t\treturn;\n\t\t}\n\n\t\tthis.initializeStyles();\n\t}\n\n\t/**\n\t * Initialize theme styles\n\t */\n\tprivate initializeStyles(): void {\n\t\tif (!this.rootElement) return;\n\n\t\tconst rootNode = this.rootElement.getRootNode();\n\t\tif (rootNode instanceof ShadowRoot) {\n\t\t\tthis.styleContainer = rootNode;\n\t\t\tthis.styleElement = rootNode.querySelector(\n\t\t\t\t'style[data-pie-theme-styles=\"true\"]',\n\t\t\t) as HTMLStyleElement | null;\n\t\t} else {\n\t\t\tthis.styleContainer = document.head;\n\t\t\tthis.styleElement = document.getElementById(\n\t\t\t\t\"pie-theme-styles\",\n\t\t\t) as HTMLStyleElement | null;\n\t\t}\n\n\t\tif (!this.styleElement) {\n\t\t\tthis.styleElement = document.createElement(\"style\");\n\t\t\tif (this.styleContainer instanceof ShadowRoot) {\n\t\t\t\tthis.styleElement.setAttribute(\"data-pie-theme-styles\", \"true\");\n\t\t\t\tthis.styleContainer.appendChild(this.styleElement);\n\t\t\t} else {\n\t\t\t\tthis.styleElement.id = \"pie-theme-styles\";\n\t\t\t\tdocument.head.appendChild(this.styleElement);\n\t\t\t}\n\t\t}\n\n\t\t// Apply default theme\n\t\tthis.applyTheme({});\n\t}\n\n\t/**\n\t * Apply theme configuration\n\t *\n\t * @param config Partial theme configuration (merged with current theme)\n\t */\n\tapplyTheme(config: ThemeConfig): void {\n\t\tif (!this.rootElement) return;\n\n\t\t// Merge with current theme\n\t\tconst newTheme = {\n\t\t\t...this.currentTheme,\n\t\t\t...config,\n\t\t};\n\n\t\t// Apply high contrast overrides if enabled\n\t\tif (newTheme.highContrast) {\n\t\t\tObject.assign(newTheme, HIGH_CONTRAST_THEME);\n\t\t}\n\n\t\tthis.currentTheme = newTheme;\n\n\t\t// Apply CSS custom properties\n\t\tthis.applyCSSVariables();\n\n\t\t// Apply CSS classes\n\t\tthis.applyCSSClasses();\n\n\t\t// Update global styles\n\t\tthis.updateGlobalStyles();\n\t}\n\n\t/**\n\t * Apply CSS custom properties to root element\n\t */\n\tprivate applyCSSVariables(): void {\n\t\tif (!this.rootElement) return;\n\n\t\tconst {\n\t\t\tfontSize,\n\t\t\tbackgroundColor,\n\t\t\tforegroundColor,\n\t\t\taccentColor,\n\t\t\tlinkColor,\n\t\t\terrorColor,\n\t\t\tsuccessColor,\n\t\t\twarningColor,\n\t\t} = this.currentTheme;\n\n\t\t// Font sizing\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-font-scale\",\n\t\t\tString(FONT_SIZE_SCALE[fontSize]),\n\t\t);\n\n\t\t// Canonical PIE variables\n\t\tthis.rootElement.style.setProperty(\"--pie-background\", backgroundColor);\n\t\tthis.rootElement.style.setProperty(\"--pie-text\", foregroundColor);\n\t\tthis.rootElement.style.setProperty(\"--pie-primary\", accentColor);\n\t\tthis.rootElement.style.setProperty(\"--pie-tertiary\", linkColor);\n\t\tthis.rootElement.style.setProperty(\"--pie-incorrect\", errorColor);\n\t\tthis.rootElement.style.setProperty(\"--pie-correct\", successColor);\n\t\tthis.rootElement.style.setProperty(\"--pie-missing\", warningColor);\n\n\t\t// Derived surface tokens\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-background-dark\",\n\t\t\tthis.adjustOpacity(backgroundColor, 0.95),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-secondary-background\",\n\t\t\tthis.adjustOpacity(backgroundColor, 0.92),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-border\",\n\t\t\tthis.adjustOpacity(foregroundColor, 0.25),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-border-light\",\n\t\t\tthis.adjustOpacity(foregroundColor, 0.16),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-border-dark\",\n\t\t\tthis.adjustOpacity(foregroundColor, 0.4),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-focus-checked\",\n\t\t\tthis.adjustOpacity(accentColor, 0.18),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-focus-checked-border\",\n\t\t\taccentColor,\n\t\t);\n\n\t\t// Button tokens used by toolkit controls\n\t\tthis.rootElement.style.setProperty(\"--pie-button-bg\", backgroundColor);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-button-border\",\n\t\t\tthis.adjustOpacity(foregroundColor, 0.2),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\"--pie-button-color\", foregroundColor);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-button-hover-bg\",\n\t\t\tthis.adjustOpacity(accentColor, 0.1),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-button-hover-border\",\n\t\t\tthis.adjustOpacity(accentColor, 0.5),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-button-hover-color\",\n\t\t\tforegroundColor,\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-button-active-bg\",\n\t\t\tthis.adjustOpacity(accentColor, 0.16),\n\t\t);\n\t\tthis.rootElement.style.setProperty(\n\t\t\t\"--pie-button-focus-outline\",\n\t\t\taccentColor,\n\t\t);\n\t}\n\n\t/**\n\t * Apply CSS classes to root element\n\t */\n\tprivate applyCSSClasses(): void {\n\t\tif (!this.rootElement) return;\n\n\t\tconst { highContrast, fontSize } = this.currentTheme;\n\n\t\t// High contrast class\n\t\tthis.rootElement.classList.toggle(\"pie-high-contrast\", highContrast);\n\n\t\t// Font size classes\n\t\tthis.rootElement.classList.remove(\n\t\t\t\"pie-font-small\",\n\t\t\t\"pie-font-normal\",\n\t\t\t\"pie-font-large\",\n\t\t\t\"pie-font-xlarge\",\n\t\t);\n\t\tthis.rootElement.classList.add(`pie-font-${fontSize}`);\n\t}\n\n\t/**\n\t * Update global theme styles\n\t */\n\tprivate updateGlobalStyles(): void {\n\t\tif (!this.styleElement) return;\n\n\t\tthis.styleElement.textContent = `\n /* PIE Assessment Toolkit - Theme Styles */\n\n /* Font scaling */\n .pie-themed,\n .pie-themed * {\n font-size: calc(1rem * var(--pie-font-scale, 1));\n }\n\n /* Color theming */\n .pie-themed {\n background-color: var(--pie-background);\n color: var(--pie-text);\n }\n\n .pie-themed a {\n color: var(--pie-tertiary);\n }\n\n .pie-themed a:hover {\n opacity: 0.8;\n }\n\n /* High contrast mode */\n .pie-high-contrast .pie-themed {\n border: 2px solid var(--pie-text);\n }\n\n .pie-high-contrast .pie-themed a {\n text-decoration: underline;\n font-weight: bold;\n }\n\n .pie-high-contrast .pie-themed button {\n border: 2px solid var(--pie-text);\n background-color: var(--pie-background);\n color: var(--pie-text);\n }\n\n .pie-high-contrast .pie-themed button:hover {\n background-color: var(--pie-text);\n color: var(--pie-background);\n }\n\n /* Error/Success/Warning states */\n .pie-themed .pie-error {\n color: var(--pie-incorrect);\n }\n\n .pie-themed .pie-success {\n color: var(--pie-correct);\n }\n\n .pie-themed .pie-warning {\n color: var(--pie-missing);\n }\n\n /* Focus indicators (accessibility) */\n .pie-themed *:focus-visible {\n outline: 3px solid var(--pie-focus-checked-border);\n outline-offset: 2px;\n }\n\n .pie-high-contrast *:focus-visible {\n outline-width: 4px;\n }\n\n /* Responsive font scaling */\n @media (max-width: 768px) {\n .pie-themed,\n .pie-themed * {\n font-size: calc(1rem * var(--pie-font-scale, 1) * 0.9);\n }\n }\n `;\n\t}\n\n\t/**\n\t * Set high contrast mode\n\t */\n\tsetHighContrast(enabled: boolean): void {\n\t\tthis.applyTheme({ highContrast: enabled });\n\t}\n\n\t/**\n\t * Set font size\n\t */\n\tsetFontSize(size: FontSize): void {\n\t\tthis.applyTheme({ fontSize: size });\n\t}\n\n\t/**\n\t * Set color scheme\n\t */\n\tsetColors(colors: {\n\t\tbackgroundColor?: string;\n\t\tforegroundColor?: string;\n\t\taccentColor?: string;\n\t}): void {\n\t\tthis.applyTheme(colors);\n\t}\n\n\t/**\n\t * Get current theme configuration\n\t */\n\tgetCurrentTheme(): Required<ThemeConfig> {\n\t\treturn { ...this.currentTheme };\n\t}\n\n\t/**\n\t * Reset to default theme\n\t */\n\treset(): void {\n\t\tthis.currentTheme = { ...DEFAULT_THEME };\n\t\tthis.applyTheme({});\n\t}\n\n\t/**\n\t * Adjust color opacity (helper)\n\t */\n\tprivate adjustOpacity(color: string, opacity: number): string {\n\t\t// Simple hex to rgba conversion\n\t\tif (color.startsWith(\"#\")) {\n\t\t\tconst r = parseInt(color.slice(1, 3), 16);\n\t\t\tconst g = parseInt(color.slice(3, 5), 16);\n\t\t\tconst b = parseInt(color.slice(5, 7), 16);\n\t\t\treturn `rgba(${r}, ${g}, ${b}, ${opacity})`;\n\t\t}\n\n\t\t// If already rgba/rgb, just return as-is (simplified)\n\t\treturn color;\n\t}\n\n\t/**\n\t * Cleanup - remove theme styles\n\t */\n\tdestroy(): void {\n\t\tif (this.styleElement) {\n\t\t\tthis.styleElement.remove();\n\t\t\tthis.styleElement = null;\n\t\t}\n\t\tthis.styleContainer = null;\n\n\t\tif (!this.rootElement) return;\n\n\t\t// Remove CSS classes\n\t\tthis.rootElement.classList.remove(\n\t\t\t\"pie-high-contrast\",\n\t\t\t\"pie-font-small\",\n\t\t\t\"pie-font-normal\",\n\t\t\t\"pie-font-large\",\n\t\t\t\"pie-font-xlarge\",\n\t\t);\n\n\t\t// Remove CSS custom properties\n\t\tthis.rootElement.style.removeProperty(\"--pie-font-scale\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-background\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-text\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-primary\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-tertiary\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-incorrect\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-correct\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-missing\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-background-dark\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-secondary-background\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-border\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-border-light\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-border-dark\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-focus-checked\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-focus-checked-border\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-bg\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-border\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-color\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-hover-bg\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-hover-border\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-hover-color\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-active-bg\");\n\t\tthis.rootElement.style.removeProperty(\"--pie-button-focus-outline\");\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ToolConfigResolver.js","sourceRoot":"","sources":["../../src/services/ToolConfigResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAoDH,MAAM,OAAO,kBAAkB;IAC9B;;;;;;;;;;;;;OAaG;IACH,WAAW,CACV,MAAc,EACd,UAA2B,EAC3B,YAA+B,EAC/B,cAAsC;QAEtC,sCAAsC;QACtC,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,QAAQ,EAAE,CAAC;YACd,uCAAuC;YACvC,OAAO;gBACN,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,KAAK;gBACpC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,MAAM,EAAE,MAAM;aACd,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,MAAM,eAAe,GAAG,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,eAAe,KAAK,GAAG,EAAE,CAAC;YAC7B,qCAAqC;YACrC,OAAO,IAAI,CAAC;QACb,CAAC;QAED,IAAI,eAAe,KAAK,GAAG,EAAE,CAAC;YAC7B,0BAA0B;YAC1B,OAAO;gBACN,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,QAAQ;aAChB,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,MAAM,gBAAgB,GACrB,cAAc,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;QAC1D,IAAI,gBAAgB,EAAE,CAAC;YACtB,0CAA0C;YAC1C,OAAO;gBACN,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,SAAS;aACjB,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAsB;QAChC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;QAEvD,uCAAuC;QACvC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QAErC,mBAAmB;QACnB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,qBAAqB;QACrB,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC;QAED,8BAA8B;QAC9B,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YAC1B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,oBAAoB;QACpB,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAC9B,MAAM,EACN,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;YAEF,IAAI,MAAM,EAAE,CAAC;gBACZ,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9B,CAAC;QACF,CAAC;QAED,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,MAAc,EAAE,KAAsB;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAC9B,MAAM,EACN,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;QACF,OAAO,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,MAAc,EAAE,KAAsB;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAC9B,MAAM,EACN,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;QACF,OAAO,MAAM,EAAE,QAAQ,IAAI,KAAK,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,MAAc,EAAE,KAAsB;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAC9B,MAAM,EACN,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;QACF,OAAO,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,eAAe,CAAC,MAAc,EAAE,KAAsB;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAC9B,MAAM,EACN,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;QACF,OAAO,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,KAAsB;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;aACnC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC;aACvC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,KAAsB;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;aACnC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;aACxC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CACP,cAA2B,EAC3B,KAAsB;QAEtB,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CACxC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CACvC,CAAC;QAEF,OAAO;YACN,KAAK,EAAE,YAAY,CAAC,MAAM,KAAK,CAAC;YAChC,YAAY;SACZ,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,kBAAkB,CAAC,GAAG,OAA2B;QAChD,MAAM,MAAM,GAAqB,EAAE,CAAC;QAEpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,KAAK,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1D,8CAA8C;gBAC9C,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;oBACvB,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;gBACtB,CAAC;qBAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5B,yCAAyC;oBACzC,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;gBAC5B,CAAC;YACF,CAAC;QACF,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,oBAAoB,CACnB,GAAG,QAAiC;QAEpC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE5C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,CAAC;QAED,OAAO;YACN,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC;SAC7C,CAAC;IACH,CAAC;CACD","sourcesContent":["/**\n * ToolConfigResolver\n *\n * Implements 3-tier hierarchy for tool configuration:\n * Item requirements > Roster allowances > Student accommodations\n *\n * Ensures IEP/504 compliance by properly handling accommodation requirements\n * while respecting item-level and test-level restrictions.\n *\n * Features:\n * - 3-tier configuration hierarchy\n * - IEP/504 accommodation support\n * - Item-specific tool requirements\n * - Test-level tool restrictions\n * - Type-safe configuration\n *\n * Part of PIE Assessment Toolkit.\n */\n\n/**\n * Tool allowance: \"0\" = blocked, \"1\" = allowed\n */\nexport type ToolAllowance = \"0\" | \"1\";\n\n/**\n * Item-level tool configuration (most specific)\n */\nexport interface ItemToolConfig {\n\t[toolId: string]: {\n\t\ttype?: string; // e.g., 'scientific' for calculator\n\t\trequired?: boolean; // true = must be available\n\t\tsettings?: any; // tool-specific settings\n\t};\n}\n\n/**\n * Roster/Test-level tool allowances (assessment-wide rules)\n */\nexport interface RosterToolConfig {\n\t[toolId: string]: ToolAllowance;\n}\n\n/**\n * Student accommodation profile (least specific)\n */\nexport interface StudentAccommodations {\n\taccommodations: string[]; // e.g., ['tts', 'calculator', 'extended-time']\n}\n\n/**\n * Resolved tool configuration\n */\nexport interface ResolvedToolConfig {\n\tenabled: boolean;\n\ttype?: string;\n\trequired?: boolean;\n\tsettings?: any;\n\tsource: \"item\" | \"roster\" | \"student\" | \"default\";\n}\n\n/**\n * Full configuration input\n */\nexport interface ToolConfigInput {\n\titemConfig?: ItemToolConfig;\n\trosterConfig?: RosterToolConfig;\n\tstudentProfile?: StudentAccommodations;\n}\n\nexport class ToolConfigResolver {\n\t/**\n\t * Resolve configuration for a specific tool\n\t *\n\t * Hierarchy (highest to lowest priority):\n\t * 1. Item level: Item requires scientific calculator → must provide\n\t * 2. Roster level: Test blocks a tool → blocked regardless of accommodation\n\t * 3. Student level: IEP requires TTS → enabled unless blocked above\n\t *\n\t * @param toolId Tool identifier\n\t * @param itemConfig Item-level tool configuration\n\t * @param rosterConfig Roster-level tool allowances\n\t * @param studentProfile Student accommodation profile\n\t * @returns Resolved configuration or null if tool not available\n\t */\n\tresolveTool(\n\t\ttoolId: string,\n\t\titemConfig?: ItemToolConfig,\n\t\trosterConfig?: RosterToolConfig,\n\t\tstudentProfile?: StudentAccommodations,\n\t): ResolvedToolConfig | null {\n\t\t// Check item level (highest priority)\n\t\tconst itemTool = itemConfig?.[toolId];\n\t\tif (itemTool) {\n\t\t\t// Item explicitly configures this tool\n\t\t\treturn {\n\t\t\t\tenabled: true,\n\t\t\t\ttype: itemTool.type,\n\t\t\t\trequired: itemTool.required ?? false,\n\t\t\t\tsettings: itemTool.settings,\n\t\t\t\tsource: \"item\",\n\t\t\t};\n\t\t}\n\n\t\t// Check roster level (blocks take precedence)\n\t\tconst rosterAllowance = rosterConfig?.[toolId];\n\t\tif (rosterAllowance === \"0\") {\n\t\t\t// Roster explicitly blocks this tool\n\t\t\treturn null;\n\t\t}\n\n\t\tif (rosterAllowance === \"1\") {\n\t\t\t// Roster allows this tool\n\t\t\treturn {\n\t\t\t\tenabled: true,\n\t\t\t\trequired: false,\n\t\t\t\tsource: \"roster\",\n\t\t\t};\n\t\t}\n\n\t\t// Check student level (lowest priority)\n\t\tconst hasAccommodation =\n\t\t\tstudentProfile?.accommodations.includes(toolId) ?? false;\n\t\tif (hasAccommodation) {\n\t\t\t// Student has accommodation for this tool\n\t\t\treturn {\n\t\t\t\tenabled: true,\n\t\t\t\trequired: false,\n\t\t\t\tsource: \"student\",\n\t\t\t};\n\t\t}\n\n\t\t// Tool not configured at any level\n\t\treturn null;\n\t}\n\n\t/**\n\t * Resolve all tools from configuration\n\t *\n\t * @param input Configuration input\n\t * @returns Map of tool ID to resolved configuration\n\t */\n\tresolveAll(input: ToolConfigInput): Map<string, ResolvedToolConfig> {\n\t\tconst resolved = new Map<string, ResolvedToolConfig>();\n\n\t\t// Collect all tool IDs from all levels\n\t\tconst allToolIds = new Set<string>();\n\n\t\t// From item config\n\t\tif (input.itemConfig) {\n\t\t\tObject.keys(input.itemConfig).forEach((id) => allToolIds.add(id));\n\t\t}\n\n\t\t// From roster config\n\t\tif (input.rosterConfig) {\n\t\t\tObject.keys(input.rosterConfig).forEach((id) => allToolIds.add(id));\n\t\t}\n\n\t\t// From student accommodations\n\t\tif (input.studentProfile) {\n\t\t\tinput.studentProfile.accommodations.forEach((id) => allToolIds.add(id));\n\t\t}\n\n\t\t// Resolve each tool\n\t\tfor (const toolId of allToolIds) {\n\t\t\tconst config = this.resolveTool(\n\t\t\t\ttoolId,\n\t\t\t\tinput.itemConfig,\n\t\t\t\tinput.rosterConfig,\n\t\t\t\tinput.studentProfile,\n\t\t\t);\n\n\t\t\tif (config) {\n\t\t\t\tresolved.set(toolId, config);\n\t\t\t}\n\t\t}\n\n\t\treturn resolved;\n\t}\n\n\t/**\n\t * Check if a tool is enabled\n\t *\n\t * @param toolId Tool identifier\n\t * @param input Configuration input\n\t * @returns true if tool is enabled\n\t */\n\tisToolEnabled(toolId: string, input: ToolConfigInput): boolean {\n\t\tconst config = this.resolveTool(\n\t\t\ttoolId,\n\t\t\tinput.itemConfig,\n\t\t\tinput.rosterConfig,\n\t\t\tinput.studentProfile,\n\t\t);\n\t\treturn config?.enabled ?? false;\n\t}\n\n\t/**\n\t * Check if a tool is required\n\t *\n\t * @param toolId Tool identifier\n\t * @param input Configuration input\n\t * @returns true if tool is required\n\t */\n\tisToolRequired(toolId: string, input: ToolConfigInput): boolean {\n\t\tconst config = this.resolveTool(\n\t\t\ttoolId,\n\t\t\tinput.itemConfig,\n\t\t\tinput.rosterConfig,\n\t\t\tinput.studentProfile,\n\t\t);\n\t\treturn config?.required ?? false;\n\t}\n\n\t/**\n\t * Get tool type (e.g., 'scientific' for calculator)\n\t *\n\t * @param toolId Tool identifier\n\t * @param input Configuration input\n\t * @returns Tool type or null\n\t */\n\tgetToolType(toolId: string, input: ToolConfigInput): string | null {\n\t\tconst config = this.resolveTool(\n\t\t\ttoolId,\n\t\t\tinput.itemConfig,\n\t\t\tinput.rosterConfig,\n\t\t\tinput.studentProfile,\n\t\t);\n\t\treturn config?.type ?? null;\n\t}\n\n\t/**\n\t * Get tool settings\n\t *\n\t * @param toolId Tool identifier\n\t * @param input Configuration input\n\t * @returns Tool settings or null\n\t */\n\tgetToolSettings(toolId: string, input: ToolConfigInput): any | null {\n\t\tconst config = this.resolveTool(\n\t\t\ttoolId,\n\t\t\tinput.itemConfig,\n\t\t\tinput.rosterConfig,\n\t\t\tinput.studentProfile,\n\t\t);\n\t\treturn config?.settings ?? null;\n\t}\n\n\t/**\n\t * Get list of all enabled tools\n\t *\n\t * @param input Configuration input\n\t * @returns Array of enabled tool IDs\n\t */\n\tgetEnabledTools(input: ToolConfigInput): string[] {\n\t\tconst resolved = this.resolveAll(input);\n\t\treturn Array.from(resolved.entries())\n\t\t\t.filter(([_, config]) => config.enabled)\n\t\t\t.map(([toolId]) => toolId);\n\t}\n\n\t/**\n\t * Get list of required tools\n\t *\n\t * @param input Configuration input\n\t * @returns Array of required tool IDs\n\t */\n\tgetRequiredTools(input: ToolConfigInput): string[] {\n\t\tconst resolved = this.resolveAll(input);\n\t\treturn Array.from(resolved.entries())\n\t\t\t.filter(([_, config]) => config.required)\n\t\t\t.map(([toolId]) => toolId);\n\t}\n\n\t/**\n\t * Validate that all required tools are available\n\t *\n\t * @param availableTools Set of available tool IDs\n\t * @param input Configuration input\n\t * @returns Object with validation result\n\t */\n\tvalidate(\n\t\tavailableTools: Set<string>,\n\t\tinput: ToolConfigInput,\n\t): { valid: boolean; missingTools: string[] } {\n\t\tconst requiredTools = this.getRequiredTools(input);\n\t\tconst missingTools = requiredTools.filter(\n\t\t\t(toolId) => !availableTools.has(toolId),\n\t\t);\n\n\t\treturn {\n\t\t\tvalid: missingTools.length === 0,\n\t\t\tmissingTools,\n\t\t};\n\t}\n\n\t/**\n\t * Merge multiple roster configurations (for complex assessments)\n\t *\n\t * More restrictive settings win (blocked > allowed).\n\t *\n\t * @param configs Array of roster configurations\n\t * @returns Merged configuration\n\t */\n\tmergeRosterConfigs(...configs: RosterToolConfig[]): RosterToolConfig {\n\t\tconst merged: RosterToolConfig = {};\n\n\t\tfor (const config of configs) {\n\t\t\tfor (const [toolId, allowance] of Object.entries(config)) {\n\t\t\t\t// If any config blocks the tool, it's blocked\n\t\t\t\tif (allowance === \"0\") {\n\t\t\t\t\tmerged[toolId] = \"0\";\n\t\t\t\t} else if (!merged[toolId]) {\n\t\t\t\t\t// If not already set, use this allowance\n\t\t\t\t\tmerged[toolId] = allowance;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn merged;\n\t}\n\n\t/**\n\t * Merge multiple student accommodation profiles\n\t *\n\t * Union of all accommodations.\n\t *\n\t * @param profiles Array of student profiles\n\t * @returns Merged profile\n\t */\n\tmergeStudentProfiles(\n\t\t...profiles: StudentAccommodations[]\n\t): StudentAccommodations {\n\t\tconst allAccommodations = new Set<string>();\n\n\t\tfor (const profile of profiles) {\n\t\t\tprofile.accommodations.forEach((acc) => allAccommodations.add(acc));\n\t\t}\n\n\t\treturn {\n\t\t\taccommodations: Array.from(allAccommodations),\n\t\t};\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ToolCoordinator.js","sourceRoot":"","sources":["../../src/services/ToolCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ToolCoordinator\n *\n * Manages z-index layering and visibility for floating tools.\n * Prevents conflicts between calculator, ruler, protractor, etc.\n *\n * Features:\n * - Centralized z-index management with defined layers\n * - Tool visibility state tracking\n * - Bring-to-front on interaction\n * - Framework-agnostic (works with any DOM element)\n *\n * Part of PIE Assessment Toolkit.\n */\n\nimport { createLogger } from \"../utils/logger.js\";\nimport type { ToolCoordinatorApi, ToolState } from \"./interfaces.js\";\n\nconst log = createLogger(\"ToolCoordinator\");\n\n/**\n * Z-index layers for assessment components\n */\nexport enum ZIndexLayer {\n\tBASE = 0, // PIE content, player chrome (0-999)\n\tTOOL = 1000, // Non-modal tools (ruler, protractor) (1000-1999)\n\tMODAL = 2000, // Modal tools (calculator) (2000-2999)\n\tCONTROL = 3000, // Drag handles, resize controls (3000-3999)\n\tHIGHLIGHT = 4000, // TTS and annotation highlights (4000-4999)\n}\n\n/**\n * Tool registration info\n */\ninterface ToolRegistration {\n\tid: string;\n\tname: string;\n\telement: HTMLElement | null;\n\tlayer: ZIndexLayer;\n\tisVisible: boolean;\n\tbaseZIndex: number;\n\tmouseDownHandler?: (e: MouseEvent) => void;\n}\n\n/**\n * Configuration for ToolCoordinator\n * Currently empty but allows future extension without breaking changes\n */\nexport type ToolCoordinatorConfig = Record<string, never>;\n\nexport class ToolCoordinator implements ToolCoordinatorApi {\n\tprivate config: ToolCoordinatorConfig;\n\tprivate tools = new Map<string, ToolRegistration>();\n\tprivate layerCounters = new Map<ZIndexLayer, number>();\n\tprivate listeners = new Set<() => void>();\n\t/**\n\t * Activation (on/off) state keyed by tool id, kept independent of the\n\t * element registration lifecycle. A tool's DOM element can be unregistered\n\t * and re-registered as the item re-renders (e.g. a model change re-mounts\n\t * the toolbar overlay); when that happens the on/off state must survive so\n\t * that only an explicit toggle — the toolbar button — turns a tool off.\n\t * Cleared on genuine teardown via {@link releaseTool}.\n\t */\n\tprivate visibilityState = new Map<string, boolean>();\n\n\tconstructor(config: ToolCoordinatorConfig = {}) {\n\t\tthis.config = config;\n\t\t// Initialize layer counters\n\t\tthis.layerCounters.set(ZIndexLayer.BASE, 0);\n\t\tthis.layerCounters.set(ZIndexLayer.TOOL, 0);\n\t\tthis.layerCounters.set(ZIndexLayer.MODAL, 0);\n\t\tthis.layerCounters.set(ZIndexLayer.CONTROL, 0);\n\t\tthis.layerCounters.set(ZIndexLayer.HIGHLIGHT, 0);\n\t}\n\n\t/**\n\t * Subscribe to tool state changes\n\t * Returns unsubscribe function\n\t */\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\t/**\n\t * Notify all listeners of state change\n\t */\n\tprivate notifyListeners(): void {\n\t\tthis.listeners.forEach((listener) => listener());\n\t}\n\n\t/**\n\t * Register a tool with the coordinator\n\t *\n\t * @param id Unique tool identifier\n\t * @param name Display name\n\t * @param element DOM element for the tool (optional)\n\t * @param layer Z-index layer (defaults to MODAL)\n\t */\n\tregisterTool(\n\t\tid: string,\n\t\tname: string,\n\t\telement?: HTMLElement,\n\t\tlayer: ZIndexLayer = ZIndexLayer.MODAL,\n\t): void {\n\t\tlog(\"registerTool called:\", { id, name, hasElement: !!element, layer });\n\n\t\tif (this.tools.has(id)) {\n\t\t\tlog(`Tool ${id} is already registered`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Restore prior on/off state. A re-registration (e.g. after an item\n\t\t// re-render unmounts and re-mounts the tool element) must preserve the\n\t\t// tool's activation state so only an explicit toggle can turn it off.\n\t\tconst isVisible = this.visibilityState.get(id) ?? false;\n\n\t\t// If no element provided, create a placeholder registration\n\t\tif (!element) {\n\t\t\tthis.tools.set(id, {\n\t\t\t\tid,\n\t\t\t\tname,\n\t\t\t\telement: null,\n\t\t\t\tlayer,\n\t\t\t\tisVisible,\n\t\t\t\tbaseZIndex: layer,\n\t\t\t});\n\t\t\tlog(\"Tool registered without element:\", id);\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate base z-index for this layer\n\t\tconst baseZIndex = layer + this.getNextLayerOffset(layer);\n\n\t\t// Apply z-index\n\t\telement.style.zIndex = String(baseZIndex);\n\n\t\t// Reflect restored visibility onto the freshly registered element.\n\t\telement.style.display = isVisible ? \"\" : \"none\";\n\n\t\t// Create and store event handler to enable proper cleanup\n\t\tconst mouseDownHandler = () => this.bringToFront(element);\n\t\telement.addEventListener(\"mousedown\", mouseDownHandler);\n\n\t\t// Register tool with handler reference\n\t\tthis.tools.set(id, {\n\t\t\tid,\n\t\t\tname,\n\t\t\telement,\n\t\t\tlayer,\n\t\t\tisVisible,\n\t\t\tbaseZIndex,\n\t\t\tmouseDownHandler,\n\t\t});\n\n\t\tif (isVisible) {\n\t\t\tthis.bringToFront(element);\n\t\t}\n\n\t\tlog(\"Tool registered with element:\", id);\n\t}\n\n\t/**\n\t * Unregister a tool\n\t *\n\t * Detaches the element binding (listeners, registration) but intentionally\n\t * preserves the tool's activation state in {@link visibilityState}, so a\n\t * subsequent re-registration of the same id (e.g. after an item re-render)\n\t * restores whether the tool was on or off. Use {@link releaseTool} to also\n\t * discard the activation state on genuine teardown.\n\t *\n\t * @param id Tool identifier\n\t */\n\tunregisterTool(id: string): void {\n\t\tconst tool = this.tools.get(id);\n\t\tif (!tool) return;\n\n\t\t// Remove event listeners using stored handler reference\n\t\tif (tool.element && tool.mouseDownHandler) {\n\t\t\ttool.element.removeEventListener(\"mousedown\", tool.mouseDownHandler);\n\t\t}\n\n\t\tthis.tools.delete(id);\n\t}\n\n\t/**\n\t * Fully release a tool: unregister its element binding AND discard its\n\t * preserved activation state. Call this on genuine teardown (e.g. leaving\n\t * the item/section that owns the tool) rather than {@link unregisterTool},\n\t * which keeps the on/off state alive across element re-registration.\n\t *\n\t * @param id Tool identifier\n\t */\n\treleaseTool(id: string): void {\n\t\tthis.unregisterTool(id);\n\t\tthis.visibilityState.delete(id);\n\t}\n\n\t/**\n\t * Show a tool\n\t *\n\t * @param id Tool identifier\n\t */\n\tshowTool(id: string): void {\n\t\tconst tool = this.tools.get(id);\n\t\tif (!tool) {\n\t\t\tlog(`Tool ${id} not found`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (tool.element) {\n\t\t\ttool.element.style.display = \"\";\n\t\t\tthis.bringToFront(tool.element);\n\t\t}\n\t\ttool.isVisible = true;\n\t\tthis.visibilityState.set(id, true);\n\t\tthis.notifyListeners();\n\t}\n\n\t/**\n\t * Hide a tool\n\t *\n\t * @param id Tool identifier\n\t */\n\thideTool(id: string): void {\n\t\tconst tool = this.tools.get(id);\n\t\tif (!tool) {\n\t\t\tlog(`Tool ${id} not found`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (tool.element) {\n\t\t\ttool.element.style.display = \"none\";\n\t\t}\n\t\ttool.isVisible = false;\n\t\tthis.visibilityState.set(id, false);\n\t\tthis.notifyListeners();\n\t}\n\n\t/**\n\t * Toggle tool visibility\n\t *\n\t * @param id Tool identifier\n\t */\n\ttoggleTool(id: string): void {\n\t\tlog(\"toggleTool called for:\", id);\n\t\tconst tool = this.tools.get(id);\n\t\tif (!tool) {\n\t\t\tlog(\n\t\t\t\t`Tool ${id} not found. Registered tools:`,\n\t\t\t\tArray.from(this.tools.keys()),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tlog(\"Tool found, current visibility:\", tool.isVisible);\n\t\tif (tool.isVisible) {\n\t\t\tthis.hideTool(id);\n\t\t} else {\n\t\t\tthis.showTool(id);\n\t\t}\n\t}\n\n\t/**\n\t * Check if tool is visible\n\t *\n\t * @param id Tool identifier\n\t * @returns true if tool is visible\n\t */\n\tisToolVisible(id: string): boolean {\n\t\tconst tool = this.tools.get(id);\n\t\tif (tool) return tool.isVisible;\n\t\t// No live element registration (e.g. mid re-render, between unmount and\n\t\t// re-mount): fall back to the preserved activation state so the tool\n\t\t// doesn't read as \"off\" during the gap.\n\t\treturn this.visibilityState.get(id) ?? false;\n\t}\n\n\t/**\n\t * Bring element to front of its layer\n\t *\n\t * @param element DOM element to bring forward\n\t */\n\tbringToFront(element: HTMLElement): void {\n\t\t// Find tool registration\n\t\tconst tool = Array.from(this.tools.values()).find(\n\t\t\t(t) => t.element === element,\n\t\t);\n\t\tif (!tool) return;\n\n\t\t// Calculate new z-index (highest in layer + 1)\n\t\tconst maxZIndexInLayer = this.getMaxZIndexInLayer(tool.layer);\n\t\tconst newZIndex = Math.max(maxZIndexInLayer + 1, tool.layer + 1);\n\n\t\t// Update z-index\n\t\telement.style.zIndex = String(newZIndex);\n\t\ttool.baseZIndex = newZIndex;\n\t}\n\n\t/**\n\t * Get all registered tool IDs\n\t */\n\tgetRegisteredTools(): string[] {\n\t\treturn Array.from(this.tools.keys());\n\t}\n\n\t/**\n\t * Get tool element by ID\n\t */\n\tgetToolElement(id: string): HTMLElement | null {\n\t\treturn this.tools.get(id)?.element ?? null;\n\t}\n\n\t/**\n\t * Get next offset within a layer\n\t */\n\tprivate getNextLayerOffset(layer: ZIndexLayer): number {\n\t\tconst current = this.layerCounters.get(layer) ?? 0;\n\t\tthis.layerCounters.set(layer, current + 1);\n\t\treturn current;\n\t}\n\n\t/**\n\t * Get maximum z-index currently in use in a layer\n\t */\n\tprivate getMaxZIndexInLayer(layer: ZIndexLayer): number {\n\t\tlet max = layer;\n\n\t\tfor (const tool of this.tools.values()) {\n\t\t\tif (tool.layer === layer) {\n\t\t\t\tmax = Math.max(max, tool.baseZIndex);\n\t\t\t}\n\t\t}\n\n\t\treturn max;\n\t}\n\n\t/**\n\t * Reset all tools to their base z-indices\n\t */\n\tresetZIndices(): void {\n\t\tfor (const tool of this.tools.values()) {\n\t\t\tif (tool.element) {\n\t\t\t\ttool.element.style.zIndex = String(tool.baseZIndex);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update tool element reference\n\t *\n\t * @param id Tool identifier\n\t * @param element New DOM element\n\t */\n\tupdateToolElement(id: string, element: HTMLElement): void {\n\t\tconst tool = this.tools.get(id);\n\t\tif (!tool) {\n\t\t\tlog(`Tool ${id} not found`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove old event listener using stored handler reference\n\t\tif (tool.element && tool.mouseDownHandler) {\n\t\t\ttool.element.removeEventListener(\"mousedown\", tool.mouseDownHandler);\n\t\t}\n\n\t\t// Create new handler and add listener\n\t\tconst mouseDownHandler = () => this.bringToFront(element);\n\t\telement.addEventListener(\"mousedown\", mouseDownHandler);\n\n\t\t// Update element and handler reference\n\t\ttool.element = element;\n\t\ttool.mouseDownHandler = mouseDownHandler;\n\n\t\t// Apply z-index to new element\n\t\telement.style.zIndex = String(tool.baseZIndex);\n\t\tif (tool.isVisible) {\n\t\t\telement.style.display = \"\";\n\t\t} else {\n\t\t\telement.style.display = \"none\";\n\t\t}\n\t}\n\n\t/**\n\t * Hide all tools\n\t */\n\thideAllTools(): void {\n\t\tfor (const id of this.tools.keys()) {\n\t\t\tthis.hideTool(id);\n\t\t}\n\t\tthis.notifyListeners();\n\t}\n\n\t/**\n\t * Get tool state (interface method)\n\t *\n\t * @param id Tool identifier\n\t * @returns Tool state or undefined\n\t */\n\tgetToolState(id: string): ToolState | undefined {\n\t\tconst tool = this.tools.get(id);\n\t\tif (!tool) return undefined;\n\n\t\treturn {\n\t\t\tid: tool.id,\n\t\t\tname: tool.name,\n\t\t\tisVisible: tool.isVisible,\n\t\t\telement: tool.element ?? null,\n\t\t\tlayer: tool.layer,\n\t\t};\n\t}\n\n\t/**\n\t * Get all visible tools (interface method)\n\t *\n\t * @returns Array of visible tool states\n\t */\n\tgetVisibleTools(): ToolState[] {\n\t\treturn Array.from(this.tools.values())\n\t\t\t.filter((tool) => tool.isVisible)\n\t\t\t.map((tool) => ({\n\t\t\t\tid: tool.id,\n\t\t\t\tname: tool.name,\n\t\t\t\tisVisible: tool.isVisible,\n\t\t\t\telement: tool.element ?? null,\n\t\t\t\tlayer: tool.layer,\n\t\t\t}));\n\t}\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ToolRegistry.js","sourceRoot":"","sources":["../../src/services/ToolRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool Registry\n *\n * Central registry for all assessment tools. Manages tool metadata, visibility logic,\n * and button/instance creation. Supports dynamic registration and override by integrators.\n */\n\nimport type { ToolContext, ToolLevel } from \"./tool-context.js\";\nimport type { ToolComponentOverrides } from \"../tools/tool-tag-map.js\";\nimport type {\n\tElementToolStateStoreApi,\n\tToolCoordinatorApi,\n\tToolkitCoordinatorApi,\n\tTtsServiceApi,\n} from \"./interfaces.js\";\nimport type { ToolProviderApi } from \"./tool-providers/ToolProviderApi.js\";\nimport type { ToolProviderConfig as ToolRuntimeConfig } from \"./tools-config-normalizer.js\";\nimport type { ToolConfigDiagnostic } from \"./tool-config-validation.js\";\nimport { normalizeToolAlias } from \"./tools-config-normalizer.js\";\n\nexport type ToolModuleLoader = () => Promise<unknown>;\n\nexport interface ToolToolbarButtonDefinition {\n\ttoolId: string;\n\tlabel: string;\n\ticon: string;\n\tariaLabel: string;\n\ttooltip?: string;\n\tonClick: () => void;\n\tclassName?: string;\n\tdisabled?: boolean;\n\tactive?: boolean;\n}\n\nexport interface ToolbarContext {\n\tscope: {\n\t\tlevel: ToolLevel;\n\t\tscopeId: string;\n\t\tassessmentId?: string;\n\t\tsectionId?: string;\n\t\titemId?: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t};\n\titemId: string;\n\tcatalogId: string;\n\tlanguage: string;\n\tui?: {\n\t\tsize?: string;\n\t};\n\tgetScopeElement?: () => HTMLElement | null;\n\tgetGlobalElementId?: () => string | null;\n\ttoolCoordinator: ToolCoordinatorApi | null;\n\ttoolkitCoordinator: ToolkitCoordinatorApi | null;\n\tttsService: TtsServiceApi | null;\n\telementToolStateStore: ElementToolStateStoreApi | null;\n\ttoggleTool: (toolId: string) => void;\n\tisToolVisible: (toolId: string) => boolean;\n\tsubscribeVisibility: ((listener: () => void) => () => void) | null;\n\tcomponentOverrides?: ToolComponentOverrides;\n\tgetResolvedToolContext?: (toolId: string) => ResolvedToolContext | null;\n\tgetToolRenderParams?: (toolId: string) => Record<string, unknown> | null;\n}\n\nexport interface ToolContextResolverContext {\n\ttoolId: string;\n\tcontext: ToolContext;\n\ttoolbarContext: ToolbarContext;\n}\n\nexport interface ToolContextResolverResult {\n\tvisible?: boolean;\n\tparams?: Record<string, unknown>;\n\treason?: string;\n}\n\nexport type ToolContextResolver = (\n\tcontext: ToolContextResolverContext,\n) => ToolContextResolverResult | null | undefined;\n\nexport type ToolContextResolverMap = Record<\n\tstring,\n\tToolContextResolver | null | undefined\n>;\n\nexport interface ResolvedToolContext {\n\ttoolId: string;\n\tvisible: boolean;\n\tparams: Record<string, unknown>;\n\treason?: string;\n}\n\nexport interface ToolRenderElement {\n\telement: HTMLElement | null;\n\tmount: \"before-buttons\" | \"after-buttons\" | \"controls-row\";\n\tlayoutHints?: {\n\t\tcontrolsRow?: {\n\t\t\treserveSpace?: boolean;\n\t\t\tshowWhenToolActive?: boolean;\n\t\t};\n\t\theaderOverlay?: {\n\t\t\tshowWhenToolActive?: boolean;\n\t\t};\n\t};\n\tshell?: ToolWindowShellConfig;\n}\n\nexport interface ToolWindowShellAction {\n\tid: string;\n\tlabel: string;\n\tariaLabel?: string;\n\ticonSvg?: string;\n\tonClick: () => void;\n}\n\n/**\n * Alignment corner for the initial shell position.\n * The shell is offset by `initialMargin` (default 16 px) from the chosen corner.\n */\nexport type ToolWindowShellAlign =\n\t| \"center\"\n\t| \"top-left\"\n\t| \"top-right\"\n\t| \"bottom-left\"\n\t| \"bottom-right\";\n\nexport interface ToolWindowShellContentConfig {\n\t/** Vertical overflow behavior for the hosted content pane. Defaults to \"hidden\". */\n\toverflowY?: \"hidden\" | \"auto\";\n\t/**\n\t * Preserve the content area's configured minimum height when the shell shrinks\n\t * below `minHeight`, letting the content pane scroll instead of compressing\n\t * the hosted element.\n\t */\n\tpreserveMinHeight?: boolean;\n}\n\nexport interface ToolWindowShellConfig {\n\ttitle?: string;\n\tdraggable?: boolean;\n\tresizable?: boolean;\n\tcloseable?: boolean;\n\tinitialWidth?: number;\n\tinitialHeight?: number;\n\tminWidth?: number;\n\tminHeight?: number;\n\tmaxWidth?: number;\n\tmaxHeight?: number;\n\t/** Initial placement of the shell. Defaults to `'center'`. */\n\tinitialAlign?: ToolWindowShellAlign;\n\t/** Distance (px) from the viewport edge when using a corner align. Defaults to 16. */\n\tinitialMargin?: number;\n\tcontent?: ToolWindowShellContentConfig;\n\tactions?: ToolWindowShellAction[];\n}\n\nexport interface HostedToolContext {\n\ttoolId: string;\n\ttoolbarContext: ToolbarContext;\n\tshellConfig: ToolWindowShellConfig;\n}\n\nexport interface HostedToolSize {\n\twidth: number;\n\theight: number;\n}\n\nexport interface ToolProviderDescriptor {\n\tgetProviderId?: (config: ToolRuntimeConfig | undefined) => string;\n\tcreateProvider: (config: ToolRuntimeConfig | undefined) => ToolProviderApi;\n\tgetInitConfig?: (\n\t\tconfig: ToolRuntimeConfig | undefined,\n\t) => Record<string, unknown>;\n\tsanitizeConfig?: (config: ToolRuntimeConfig) => ToolRuntimeConfig;\n\tvalidateConfig?: (config: ToolRuntimeConfig) => ToolConfigDiagnostic[];\n\tgetAuthFetcher?: (\n\t\tconfig: ToolRuntimeConfig | undefined,\n\t) => (() => Promise<Record<string, unknown>>) | undefined;\n\tlazy?: boolean;\n}\n\nexport interface ToolToolbarRenderResult {\n\ttoolId: string;\n\telements?: ToolRenderElement[];\n\tbutton?: ToolToolbarButtonDefinition | null;\n\tsync?: () => void;\n\tsubscribeActive?: (callback: (active: boolean) => void) => () => void;\n}\n\nexport type ToolActivation = \"toolbar-toggle\" | \"selection-gateway\";\nexport type ToolSingletonScope = \"section\";\n\n/**\n * Tool registration interface\n */\nexport interface ToolRegistration {\n\t/** Unique tool identifier (e.g., 'calculator', 'textToSpeech') */\n\ttoolId: string;\n\n\t/** Human-readable name */\n\tname: string;\n\n\t/** Description of what the tool does */\n\tdescription: string;\n\n\t/** Icon identifier or SVG string */\n\ticon: string | ((context: ToolContext) => string);\n\n\t/** Which levels this tool supports */\n\tsupportedLevels: ToolLevel[];\n\n\t/**\n\t * Activation model for this tool.\n\t * - toolbar-toggle: rendered as a toolbar button (default)\n\t * - selection-gateway: rendered as a singleton selection-driven gateway\n\t */\n\tactivation?: ToolActivation;\n\n\t/**\n\t * Optional singleton scope for activation models that mount exactly one instance.\n\t */\n\tsingletonScope?: ToolSingletonScope;\n\n\t/**\n\t * PNP support IDs that enable this tool (optional)\n\t * Used by the tool policy engine to determine if a PNP support enables this tool.\n\t * Example: ['calculator', 'basic-calculator', 'scientific-calculator']\n\t */\n\tpnpSupportIds?: string[];\n\t/**\n\t * Optional provider registration metadata.\n\t * When present, ToolkitCoordinator can register provider(s) generically\n\t * without hardcoded tool-specific branches.\n\t */\n\tprovider?: ToolProviderDescriptor;\n\t/**\n\t * Optional shell-host lifecycle hooks for hosted (floating) tools.\n\t */\n\tonHostedMount?: (\n\t\telement: HTMLElement,\n\t\tcontext: HostedToolContext,\n\t) => void | Promise<void>;\n\tonHostedResize?: (\n\t\tsize: HostedToolSize,\n\t\telement: HTMLElement,\n\t\tcontext: HostedToolContext,\n\t) => void | Promise<void>;\n\tonHostedUnmount?: (\n\t\telement: HTMLElement,\n\t\tcontext: HostedToolContext,\n\t) => void | Promise<void>;\n\n\t/**\n\t * Pass 2: Tool decides if it's relevant in this context\n\t * Called ONLY if orchestrator has already allowed the tool (Pass 1)\n\t *\n\t * @param context - Rich context about where tool is being evaluated\n\t * @returns true if tool should be visible, false to hide\n\t */\n\tisVisibleInContext(context: ToolContext): boolean;\n\n\t/** Required toolbar-first render contract. */\n\trenderToolbar(\n\t\tcontext: ToolContext,\n\t\ttoolbarContext: ToolbarContext,\n\t): ToolToolbarRenderResult | null;\n}\n\nconst VALID_TOOL_LEVELS: ToolLevel[] = [\n\t\"assessment\",\n\t\"section\",\n\t\"item\",\n\t\"passage\",\n\t\"rubric\",\n\t\"element\",\n];\n\nfunction assertNonEmptyString(\n\tvalue: unknown,\n\tfieldName: string,\n): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration: \"${fieldName}\" must be a non-empty string.`,\n\t\t);\n\t}\n}\n\n// Defence-in-depth: reject obvious XSS payloads in tool-registered icon\n// markup at registration time. Runtime rendering still runs each icon\n// through DOMPurify (see `ToolIcon.svelte`), but surfacing the problem\n// early produces a clearer error for tool authors than \"the icon silently\n// disappeared after sanitization\".\nconst SCRIPTABLE_ICON_PATTERNS: Array<{ pattern: RegExp; reason: string }> = [\n\t{ pattern: /<script\\b/i, reason: \"contains a <script> tag\" },\n\t{\n\t\tpattern: /\\son[a-z]+\\s*=/i,\n\t\treason: \"contains an inline event handler (on*=) attribute\",\n\t},\n\t{ pattern: /javascript:/i, reason: \"contains a javascript: URL\" },\n\t{\n\t\tpattern: /<foreignObject\\b/i,\n\t\treason: \"contains a <foreignObject> element\",\n\t},\n];\n\nfunction assertIconStringIsSafe(\n\ttoolId: string,\n\ticon: string,\n\tfieldName: string,\n): void {\n\tconst trimmed = icon.trimStart();\n\tconst looksLikeSvg = trimmed.toLowerCase().startsWith(\"<svg\");\n\tconst looksLikeUrl = /^https?:/i.test(trimmed);\n\tconst looksLikeDataUrl = /^data:/i.test(trimmed);\n\tif (looksLikeDataUrl) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${toolId}\": \"${fieldName}\" may not be a data: URL.`,\n\t\t);\n\t}\n\tif (!looksLikeSvg && !looksLikeUrl) return;\n\tfor (const { pattern, reason } of SCRIPTABLE_ICON_PATTERNS) {\n\t\tif (pattern.test(icon)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid tool registration \"${toolId}\": \"${fieldName}\" ${reason}. Inline SVG icons must not include scriptable content.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction assertToolRegistrationShape(registration: ToolRegistration): void {\n\tassertNonEmptyString(registration.toolId, \"toolId\");\n\tassertNonEmptyString(registration.name, \"name\");\n\tassertNonEmptyString(registration.description, \"description\");\n\n\tif (\n\t\ttypeof registration.icon !== \"string\" &&\n\t\ttypeof registration.icon !== \"function\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": \"icon\" must be a string or function.`,\n\t\t);\n\t}\n\tif (typeof registration.icon === \"string\") {\n\t\tassertIconStringIsSafe(registration.toolId, registration.icon, \"icon\");\n\t}\n\tif (\n\t\t!Array.isArray(registration.supportedLevels) ||\n\t\tregistration.supportedLevels.length === 0\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": \"supportedLevels\" must be a non-empty array.`,\n\t\t);\n\t}\n\tconst invalidLevel = registration.supportedLevels.find(\n\t\t(level) => !VALID_TOOL_LEVELS.includes(level),\n\t);\n\tif (invalidLevel) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": unsupported level \"${invalidLevel}\".`,\n\t\t);\n\t}\n\tif (\n\t\tregistration.activation !== undefined &&\n\t\tregistration.activation !== \"toolbar-toggle\" &&\n\t\tregistration.activation !== \"selection-gateway\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": unsupported activation \"${String(registration.activation)}\".`,\n\t\t);\n\t}\n\tif (\n\t\tregistration.singletonScope !== undefined &&\n\t\tregistration.singletonScope !== \"section\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": unsupported singletonScope \"${String(registration.singletonScope)}\".`,\n\t\t);\n\t}\n\tif (\n\t\tregistration.activation === \"selection-gateway\" &&\n\t\tregistration.singletonScope !== \"section\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": selection-gateway tools must declare singletonScope \"section\".`,\n\t\t);\n\t}\n\tif (\n\t\tregistration.pnpSupportIds !== undefined &&\n\t\t(!Array.isArray(registration.pnpSupportIds) ||\n\t\t\tregistration.pnpSupportIds.some(\n\t\t\t\t(pnpId) => typeof pnpId !== \"string\" || pnpId.trim().length === 0,\n\t\t\t))\n\t) {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": \"pnpSupportIds\" must be an array of non-empty strings.`,\n\t\t);\n\t}\n\tif (typeof registration.isVisibleInContext !== \"function\") {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": \"isVisibleInContext\" must be a function.`,\n\t\t);\n\t}\n\tif (typeof registration.renderToolbar !== \"function\") {\n\t\tthrow new Error(\n\t\t\t`Invalid tool registration \"${registration.toolId}\": \"renderToolbar\" must be a function.`,\n\t\t);\n\t}\n}\n\n/**\n * Tool Registry\n *\n * Manages tool registrations and provides query/lookup functionality\n */\nexport class ToolRegistry {\n\tprivate tools = new Map<string, ToolRegistration>();\n\tprivate pnpIndex = new Map<string, Set<string>>(); // pnpSupportId → Set<toolId>\n\tprivate componentOverrides: ToolComponentOverrides = {};\n\tprivate moduleLoaders = new Map<string, ToolModuleLoader>();\n\tprivate loadedToolModules = new Set<string>();\n\tprivate moduleLoadPromises = new Map<string, Promise<void>>();\n\n\t/**\n\t * Normalize a single tool alias to canonical toolId.\n\t */\n\tnormalizeToolId(toolId: string): string {\n\t\treturn normalizeToolAlias(toolId);\n\t}\n\n\t/**\n\t * Normalize a list of tool aliases to canonical toolIds.\n\t */\n\tnormalizeToolIds(toolIds: string[]): string[] {\n\t\treturn toolIds.map((toolId) => this.normalizeToolId(toolId));\n\t}\n\n\t/**\n\t * Register a tool\n\t *\n\t * @param registration - Tool registration\n\t * @throws Error if toolId is already registered\n\t */\n\tregister(registration: ToolRegistration): void {\n\t\tassertToolRegistrationShape(registration);\n\t\tif (this.tools.has(registration.toolId)) {\n\t\t\tthrow new Error(`Tool '${registration.toolId}' is already registered`);\n\t\t}\n\n\t\tthis.tools.set(registration.toolId, registration);\n\n\t\t// Index PNP support IDs\n\t\tif (registration.pnpSupportIds) {\n\t\t\tfor (const pnpId of registration.pnpSupportIds) {\n\t\t\t\tif (!this.pnpIndex.has(pnpId)) {\n\t\t\t\t\tthis.pnpIndex.set(pnpId, new Set());\n\t\t\t\t}\n\t\t\t\tthis.pnpIndex.get(pnpId)!.add(registration.toolId);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Override an existing tool registration\n\t *\n\t * @param registration - New tool registration (must have existing toolId)\n\t */\n\toverride(registration: ToolRegistration): void {\n\t\tassertToolRegistrationShape(registration);\n\t\tif (!this.tools.has(registration.toolId)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot override non-existent tool '${registration.toolId}'`,\n\t\t\t);\n\t\t}\n\n\t\t// Remove old PNP index entries\n\t\tconst oldReg = this.tools.get(registration.toolId)!;\n\t\tif (oldReg.pnpSupportIds) {\n\t\t\tfor (const pnpId of oldReg.pnpSupportIds) {\n\t\t\t\tthis.pnpIndex.get(pnpId)?.delete(registration.toolId);\n\t\t\t}\n\t\t}\n\n\t\t// Add new registration\n\t\tthis.tools.set(registration.toolId, registration);\n\n\t\t// Re-index PNP support IDs\n\t\tif (registration.pnpSupportIds) {\n\t\t\tfor (const pnpId of registration.pnpSupportIds) {\n\t\t\t\tif (!this.pnpIndex.has(pnpId)) {\n\t\t\t\t\tthis.pnpIndex.set(pnpId, new Set());\n\t\t\t\t}\n\t\t\t\tthis.pnpIndex.get(pnpId)!.add(registration.toolId);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Unregister a tool\n\t *\n\t * @param toolId - Tool ID to remove\n\t */\n\tunregister(toolId: string): void {\n\t\tconst reg = this.tools.get(toolId);\n\t\tif (!reg) return;\n\n\t\t// Remove PNP index entries\n\t\tif (reg.pnpSupportIds) {\n\t\t\tfor (const pnpId of reg.pnpSupportIds) {\n\t\t\t\tthis.pnpIndex.get(pnpId)?.delete(toolId);\n\t\t\t}\n\t\t}\n\n\t\tthis.tools.delete(toolId);\n\t}\n\n\t/**\n\t * Get a tool registration by ID\n\t *\n\t * @param toolId - Tool ID\n\t * @returns Tool registration or undefined\n\t */\n\tget(toolId: string): ToolRegistration | undefined {\n\t\treturn this.tools.get(toolId);\n\t}\n\n\t/**\n\t * Check if a tool is registered\n\t *\n\t * @param toolId - Tool ID\n\t * @returns true if registered\n\t */\n\thas(toolId: string): boolean {\n\t\treturn this.tools.has(toolId);\n\t}\n\n\t/**\n\t * Get all registered tool IDs\n\t *\n\t * @returns Array of tool IDs\n\t */\n\tgetAllToolIds(): string[] {\n\t\treturn Array.from(this.tools.keys());\n\t}\n\n\t/**\n\t * Get all tool registrations\n\t *\n\t * @returns Array of tool registrations\n\t */\n\tgetAllTools(): ToolRegistration[] {\n\t\treturn Array.from(this.tools.values());\n\t}\n\n\t/**\n\t * Find tool IDs that support a given PNP support ID\n\t *\n\t * @param pnpSupportId - PNP support ID (e.g., 'calculator')\n\t * @returns Set of tool IDs that support this PNP ID\n\t */\n\tgetToolsByPNPSupport(pnpSupportId: string): Set<string> {\n\t\treturn this.pnpIndex.get(pnpSupportId) || new Set();\n\t}\n\n\t/**\n\t * Get tools that support a specific level\n\t *\n\t * @param level - Tool level (assessment, section, item, passage, element)\n\t * @returns Array of tool registrations that support this level\n\t */\n\tgetToolsByLevel(level: ToolLevel): ToolRegistration[] {\n\t\treturn this.getAllTools().filter((tool) =>\n\t\t\ttool.supportedLevels.includes(level),\n\t\t);\n\t}\n\n\t/**\n\t * Resolve tool activation, defaulting to toolbar-toggle.\n\t */\n\tgetToolActivation(toolId: string): ToolActivation {\n\t\treturn this.get(toolId)?.activation || \"toolbar-toggle\";\n\t}\n\n\t/**\n\t * Resolve singleton scope for a tool when present.\n\t */\n\tgetToolSingletonScope(toolId: string): ToolSingletonScope | null {\n\t\treturn this.get(toolId)?.singletonScope || null;\n\t}\n\n\t/**\n\t * Filter tool IDs by activation type.\n\t */\n\tfilterToolIdsByActivation(\n\t\ttoolIds: string[],\n\t\tactivation: ToolActivation,\n\t): string[] {\n\t\treturn toolIds.filter(\n\t\t\t(toolId) => this.getToolActivation(toolId) === activation,\n\t\t);\n\t}\n\n\t/**\n\t * Filter tools by visibility in a given context\n\t *\n\t * Pass 2 of the two-pass model: Given a list of allowed tool IDs (from Pass 1),\n\t * ask each tool if it's relevant in this context.\n\t *\n\t * @param allowedToolIds - Tool IDs that passed Pass 1 (orchestrator approval)\n\t * @param context - Context to evaluate\n\t * @returns Array of visible tool registrations\n\t */\n\tfilterVisibleInContext(\n\t\tallowedToolIds: string[],\n\t\tcontext: ToolContext,\n\t): ToolRegistration[] {\n\t\tconst visible: ToolRegistration[] = [];\n\n\t\tfor (const toolId of allowedToolIds) {\n\t\t\tconst tool = this.get(toolId);\n\t\t\tif (!tool) {\n\t\t\t\tconsole.warn(`Tool '${toolId}' is allowed but not registered`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if tool supports this level\n\t\t\tif (!tool.supportedLevels.includes(context.level)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Pass 2: Ask tool if it's relevant\n\t\t\ttry {\n\t\t\t\tif (tool.isVisibleInContext(context)) {\n\t\t\t\t\tvisible.push(tool);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Error evaluating visibility for tool '${toolId}':`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn visible;\n\t}\n\n\t/**\n\t * Get tool metadata for building UIs\n\t * Useful for building PNP configuration interfaces\n\t *\n\t * @returns Array of tool metadata (id, name, description, pnpSupportIds)\n\t */\n\tgetToolMetadata(): Array<{\n\t\ttoolId: string;\n\t\tname: string;\n\t\tdescription: string;\n\t\tpnpSupportIds: string[];\n\t\tsupportedLevels: ToolLevel[];\n\t\tactivation: ToolActivation;\n\t\tsingletonScope: ToolSingletonScope | null;\n\t}> {\n\t\treturn this.getAllTools().map((tool) => ({\n\t\t\ttoolId: tool.toolId,\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tpnpSupportIds: tool.pnpSupportIds || [],\n\t\t\tsupportedLevels: tool.supportedLevels,\n\t\t\tactivation: tool.activation || \"toolbar-toggle\",\n\t\t\tsingletonScope: tool.singletonScope || null,\n\t\t}));\n\t}\n\n\t/**\n\t * Generate PNP support IDs from enabled tools\n\t * Useful for creating PNP profiles\n\t *\n\t * @param enabledToolIds - Tool IDs to enable\n\t * @returns Array of unique PNP support IDs\n\t */\n\tgeneratePNPSupportsFromTools(enabledToolIds: string[]): string[] {\n\t\tconst pnpSupports = new Set<string>();\n\n\t\tfor (const toolId of enabledToolIds) {\n\t\t\tconst tool = this.get(toolId);\n\t\t\tif (tool?.pnpSupportIds) {\n\t\t\t\tfor (const pnpId of tool.pnpSupportIds) {\n\t\t\t\t\tpnpSupports.add(pnpId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Array.from(pnpSupports);\n\t}\n\n\t/**\n\t * Clear all registrations (useful for testing)\n\t */\n\tclear(): void {\n\t\tthis.tools.clear();\n\t\tthis.pnpIndex.clear();\n\t}\n\n\t/**\n\t * Configure global component overrides used by tool instance creation.\n\t */\n\tsetComponentOverrides(overrides: ToolComponentOverrides): void {\n\t\tthis.componentOverrides = overrides;\n\t}\n\n\t/**\n\t * Register lazy module loaders by toolId.\n\t * Toolbars call ensureToolModuleLoaded(toolId) before instance creation.\n\t */\n\tsetToolModuleLoaders(\n\t\tloaders: Partial<Record<string, ToolModuleLoader>>,\n\t): void {\n\t\tfor (const [toolId, loader] of Object.entries(loaders)) {\n\t\t\tif (!loader) continue;\n\t\t\tassertNonEmptyString(toolId, \"tool module loader id\");\n\t\t\tif (typeof loader !== \"function\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid tool module loader for \"${toolId}\": expected a function.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.moduleLoaders.set(toolId, loader);\n\t\t}\n\t}\n\n\t/**\n\t * Ensure tool module side-effects are loaded exactly once.\n\t * Safe to call repeatedly; concurrent callers share the same promise.\n\t */\n\tasync ensureToolModuleLoaded(toolId: string): Promise<void> {\n\t\tif (this.loadedToolModules.has(toolId)) return;\n\n\t\tconst existingPromise = this.moduleLoadPromises.get(toolId);\n\t\tif (existingPromise) {\n\t\t\tawait existingPromise;\n\t\t\treturn;\n\t\t}\n\n\t\tconst loader = this.moduleLoaders.get(toolId);\n\t\tif (!loader) return;\n\n\t\tconst loadPromise = (async () => {\n\t\t\tawait loader();\n\t\t\tthis.loadedToolModules.add(toolId);\n\t\t})();\n\n\t\tthis.moduleLoadPromises.set(toolId, loadPromise);\n\t\ttry {\n\t\t\tawait loadPromise;\n\t\t} finally {\n\t\t\tthis.moduleLoadPromises.delete(toolId);\n\t\t}\n\t}\n\n\t/**\n\t * Ensure a set of tool modules are loaded.\n\t */\n\tasync ensureToolModulesLoaded(toolIds: string[]): Promise<void> {\n\t\tawait Promise.all(\n\t\t\ttoolIds.map((toolId) => this.ensureToolModuleLoaded(toolId)),\n\t\t);\n\t}\n\n\t/**\n\t * Whether a tool module has already been loaded.\n\t */\n\tisToolModuleLoaded(toolId: string): boolean {\n\t\treturn this.loadedToolModules.has(toolId);\n\t}\n\n\t/**\n\t * Render a tool for toolbar use with component overrides attached.\n\t */\n\trenderForToolbar(\n\t\ttoolId: string,\n\t\tcontext: ToolContext,\n\t\ttoolbarContext: ToolbarContext,\n\t): ToolToolbarRenderResult | null {\n\t\tconst tool = this.get(toolId);\n\t\tif (!tool) {\n\t\t\tthrow new Error(`Tool '${toolId}' is not registered`);\n\t\t}\n\n\t\tconst mergedContext: ToolbarContext = {\n\t\t\t...toolbarContext,\n\t\t\tcomponentOverrides: {\n\t\t\t\t...(this.componentOverrides || {}),\n\t\t\t\t...(toolbarContext.componentOverrides || {}),\n\t\t\t},\n\t\t};\n\n\t\treturn tool.renderToolbar(context, mergedContext);\n\t}\n}\n"]}