@pie-players/pie-assessment-toolkit 0.3.43 → 0.3.45

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 (441) hide show
  1. package/README.md +54 -69
  2. package/dist/attempt/AssessmentSession.d.ts +0 -1
  3. package/dist/attempt/AssessmentSession.js.map +1 -1
  4. package/dist/attempt/TestSession.d.ts +0 -1
  5. package/dist/attempt/TestSession.js.map +1 -1
  6. package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -1
  7. package/dist/attempt/adapters/activity-to-test-attempt-session.js.map +1 -1
  8. package/dist/components/ItemToolBar.custom-element.js +1607 -428
  9. package/dist/components/PieAssessmentToolkit.custom-element.js +19498 -3590
  10. package/dist/components/SectionToolBar.custom-element.js +1887 -611
  11. package/dist/components/item-toolbar-element.d.ts +0 -1
  12. package/dist/components/item-toolbar-element.js.map +1 -1
  13. package/dist/components/pie-assessment-toolkit-element.d.ts +0 -1
  14. package/dist/components/pie-assessment-toolkit-element.js.map +1 -1
  15. package/dist/components/section-toolbar-element.d.ts +0 -1
  16. package/dist/components/section-toolbar-element.js.map +1 -1
  17. package/dist/components/vendor/nds/README.md +110 -0
  18. package/dist/components/vendor/nds/nds-icon-button.js +826 -0
  19. package/dist/context/assessment-toolkit-context.d.ts +0 -1
  20. package/dist/context/assessment-toolkit-context.js.map +1 -1
  21. package/dist/context/runtime-context-consumer.d.ts +0 -1
  22. package/dist/context/runtime-context-consumer.js.map +1 -1
  23. package/dist/index.d.ts +3 -7
  24. package/dist/index.js +1 -3
  25. package/dist/index.js.map +1 -1
  26. package/dist/item-loader.d.ts +0 -1
  27. package/dist/item-loader.js.map +1 -1
  28. package/dist/policy/core/PolicySource.d.ts +0 -1
  29. package/dist/policy/core/PolicySource.js.map +1 -1
  30. package/dist/policy/core/ToolPolicyEngine.d.ts +1 -3
  31. package/dist/policy/core/ToolPolicyEngine.js +1 -2
  32. package/dist/policy/core/ToolPolicyEngine.js.map +1 -1
  33. package/dist/policy/core/compose-decision.d.ts +0 -1
  34. package/dist/policy/core/compose-decision.js.map +1 -1
  35. package/dist/policy/core/decision-types.d.ts +0 -1
  36. package/dist/policy/core/decision-types.js.map +1 -1
  37. package/dist/policy/core/engine-context.d.ts +0 -1
  38. package/dist/policy/core/engine-context.js.map +1 -1
  39. package/dist/policy/core/pnp-policy-inputs.d.ts +2 -4
  40. package/dist/policy/core/pnp-policy-inputs.js +2 -3
  41. package/dist/policy/core/pnp-policy-inputs.js.map +1 -1
  42. package/dist/policy/core/policy-source-tag.d.ts +0 -1
  43. package/dist/policy/core/policy-source-tag.js.map +1 -1
  44. package/dist/policy/core/provenance.d.ts +7 -35
  45. package/dist/policy/core/provenance.js +4 -21
  46. package/dist/policy/core/provenance.js.map +1 -1
  47. package/dist/policy/engine.d.ts +0 -1
  48. package/dist/policy/engine.js.map +1 -1
  49. package/dist/policy/internal.d.ts +0 -1
  50. package/dist/policy/internal.js.map +1 -1
  51. package/dist/policy/sources/PnpPolicySource.d.ts +6 -20
  52. package/dist/policy/sources/PnpPolicySource.js +6 -19
  53. package/dist/policy/sources/PnpPolicySource.js.map +1 -1
  54. package/dist/runtime/RuntimeRegistry.d.ts +0 -1
  55. package/dist/runtime/RuntimeRegistry.js.map +1 -1
  56. package/dist/runtime/SectionRuntimeEngine.d.ts +13 -29
  57. package/dist/runtime/SectionRuntimeEngine.js +13 -27
  58. package/dist/runtime/SectionRuntimeEngine.js.map +1 -1
  59. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +2 -3
  60. package/dist/runtime/adapter/SectionEngineAdapter.js +2 -2
  61. package/dist/runtime/adapter/SectionEngineAdapter.js.map +1 -1
  62. package/dist/runtime/adapter/coordinator-bridge.d.ts +1 -2
  63. package/dist/runtime/adapter/coordinator-bridge.js +1 -1
  64. package/dist/runtime/adapter/coordinator-bridge.js.map +1 -1
  65. package/dist/runtime/adapter/dom-event-bridge.d.ts +1 -2
  66. package/dist/runtime/adapter/dom-event-bridge.js +1 -1
  67. package/dist/runtime/adapter/dom-event-bridge.js.map +1 -1
  68. package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -1
  69. package/dist/runtime/adapter/framework-error-bridge.js.map +1 -1
  70. package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -1
  71. package/dist/runtime/adapter/instrumentation-bridge.js.map +1 -1
  72. package/dist/runtime/adapter/subscriber-fanout.d.ts +0 -1
  73. package/dist/runtime/adapter/subscriber-fanout.js.map +1 -1
  74. package/dist/runtime/catalog-registration.d.ts +12 -0
  75. package/dist/runtime/catalog-registration.js +54 -0
  76. package/dist/runtime/catalog-registration.js.map +1 -0
  77. package/dist/runtime/core/SectionEngineCore.d.ts +0 -1
  78. package/dist/runtime/core/SectionEngineCore.js.map +1 -1
  79. package/dist/runtime/core/cohort.d.ts +0 -1
  80. package/dist/runtime/core/cohort.js.map +1 -1
  81. package/dist/runtime/core/engine-input.d.ts +0 -1
  82. package/dist/runtime/core/engine-input.js.map +1 -1
  83. package/dist/runtime/core/engine-output.d.ts +2 -3
  84. package/dist/runtime/core/engine-output.js +2 -2
  85. package/dist/runtime/core/engine-output.js.map +1 -1
  86. package/dist/runtime/core/engine-readiness.d.ts +2 -3
  87. package/dist/runtime/core/engine-readiness.js.map +1 -1
  88. package/dist/runtime/core/engine-resolver.d.ts +13 -42
  89. package/dist/runtime/core/engine-resolver.js +19 -76
  90. package/dist/runtime/core/engine-resolver.js.map +1 -1
  91. package/dist/runtime/core/engine-stage-derivation.d.ts +0 -1
  92. package/dist/runtime/core/engine-stage-derivation.js.map +1 -1
  93. package/dist/runtime/core/engine-state.d.ts +0 -1
  94. package/dist/runtime/core/engine-state.js.map +1 -1
  95. package/dist/runtime/core/engine-transition.d.ts +1 -2
  96. package/dist/runtime/core/engine-transition.js +1 -1
  97. package/dist/runtime/core/engine-transition.js.map +1 -1
  98. package/dist/runtime/engine-context.d.ts +0 -1
  99. package/dist/runtime/engine-context.js.map +1 -1
  100. package/dist/runtime/engine.d.ts +1 -2
  101. package/dist/runtime/engine.js.map +1 -1
  102. package/dist/runtime/internal.d.ts +0 -1
  103. package/dist/runtime/internal.js.map +1 -1
  104. package/dist/runtime/registration-events.d.ts +0 -1
  105. package/dist/runtime/registration-events.js.map +1 -1
  106. package/dist/runtime/runtime-id.d.ts +0 -1
  107. package/dist/runtime/runtime-id.js.map +1 -1
  108. package/dist/runtime/section-runtime-engine-host-context.d.ts +22 -16
  109. package/dist/runtime/section-runtime-engine-host-context.js +10 -10
  110. package/dist/runtime/section-runtime-engine-host-context.js.map +1 -1
  111. package/dist/runtime/session-event-emitter-policy.d.ts +0 -1
  112. package/dist/runtime/session-event-emitter-policy.js.map +1 -1
  113. package/dist/runtime/stage-emit-gate.d.ts +4 -5
  114. package/dist/runtime/stage-emit-gate.js +3 -3
  115. package/dist/runtime/stage-emit-gate.js.map +1 -1
  116. package/dist/runtime/tool-host-contract.d.ts +0 -1
  117. package/dist/runtime/tool-host-contract.js.map +1 -1
  118. package/dist/services/AccessibilityCatalogResolver.d.ts +23 -1
  119. package/dist/services/AccessibilityCatalogResolver.js +200 -28
  120. package/dist/services/AccessibilityCatalogResolver.js.map +1 -1
  121. package/dist/services/ContextVariableStore.d.ts +0 -1
  122. package/dist/services/ContextVariableStore.js.map +1 -1
  123. package/dist/services/ElementToolStateStore.d.ts +0 -1
  124. package/dist/services/ElementToolStateStore.js.map +1 -1
  125. package/dist/services/HighlightCoordinator.d.ts +25 -1
  126. package/dist/services/HighlightCoordinator.js +125 -0
  127. package/dist/services/HighlightCoordinator.js.map +1 -1
  128. package/dist/services/I18nService.d.ts +0 -1
  129. package/dist/services/I18nService.js.map +1 -1
  130. package/dist/services/RangeSerializer.d.ts +0 -1
  131. package/dist/services/RangeSerializer.js.map +1 -1
  132. package/dist/services/SSMLExtractor.d.ts +16 -2
  133. package/dist/services/SSMLExtractor.js +86 -7
  134. package/dist/services/SSMLExtractor.js.map +1 -1
  135. package/dist/services/TTSService.d.ts +30 -5
  136. package/dist/services/TTSService.js +652 -159
  137. package/dist/services/TTSService.js.map +1 -1
  138. package/dist/services/ThemeProvider.d.ts +0 -1
  139. package/dist/services/ThemeProvider.js.map +1 -1
  140. package/dist/services/ToolConfigResolver.d.ts +0 -1
  141. package/dist/services/ToolConfigResolver.js.map +1 -1
  142. package/dist/services/ToolCoordinator.d.ts +0 -1
  143. package/dist/services/ToolCoordinator.js.map +1 -1
  144. package/dist/services/ToolRegistry.d.ts +2 -3
  145. package/dist/services/ToolRegistry.js +1 -1
  146. package/dist/services/ToolRegistry.js.map +1 -1
  147. package/dist/services/ToolkitCoordinator.d.ts +16 -74
  148. package/dist/services/ToolkitCoordinator.js +34 -113
  149. package/dist/services/ToolkitCoordinator.js.map +1 -1
  150. package/dist/services/create-tools-config.d.ts +0 -1
  151. package/dist/services/create-tools-config.js.map +1 -1
  152. package/dist/services/createDefaultToolRegistry.d.ts +0 -1
  153. package/dist/services/createDefaultToolRegistry.js.map +1 -1
  154. package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -1
  155. package/dist/services/defaultPersonalNeedsProfile.js.map +1 -1
  156. package/dist/services/framework-error-bus.d.ts +0 -1
  157. package/dist/services/framework-error-bus.js.map +1 -1
  158. package/dist/services/framework-error.d.ts +0 -1
  159. package/dist/services/framework-error.js.map +1 -1
  160. package/dist/services/interfaces.d.ts +20 -3
  161. package/dist/services/interfaces.js.map +1 -1
  162. package/dist/services/pnp-standard-features.d.ts +0 -1
  163. package/dist/services/pnp-standard-features.js.map +1 -1
  164. package/dist/services/section-controller-types.d.ts +0 -1
  165. package/dist/services/section-controller-types.js.map +1 -1
  166. package/dist/services/tool-config-defaults.d.ts +0 -1
  167. package/dist/services/tool-config-defaults.js.map +1 -1
  168. package/dist/services/tool-config-validation.d.ts +1 -2
  169. package/dist/services/tool-config-validation.js +7 -7
  170. package/dist/services/tool-config-validation.js.map +1 -1
  171. package/dist/services/tool-context.d.ts +0 -1
  172. package/dist/services/tool-context.js.map +1 -1
  173. package/dist/services/tool-instance-id.d.ts +0 -1
  174. package/dist/services/tool-instance-id.js +1 -1
  175. package/dist/services/tool-instance-id.js.map +1 -1
  176. package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -1
  177. package/dist/services/tool-providers/DesmosToolProvider.js.map +1 -1
  178. package/dist/services/tool-providers/TTSToolProvider.d.ts +0 -1
  179. package/dist/services/tool-providers/TTSToolProvider.js +3 -3
  180. package/dist/services/tool-providers/TTSToolProvider.js.map +1 -1
  181. package/dist/services/tool-providers/ToolProviderApi.d.ts +0 -1
  182. package/dist/services/tool-providers/ToolProviderApi.js.map +1 -1
  183. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +0 -1
  184. package/dist/services/tool-providers/ToolProviderRegistry.js.map +1 -1
  185. package/dist/services/tool-providers/index.d.ts +0 -1
  186. package/dist/services/tool-providers/index.js.map +1 -1
  187. package/dist/services/toolbar-items.d.ts +0 -1
  188. package/dist/services/toolbar-items.js.map +1 -1
  189. package/dist/services/tools-config-normalizer.d.ts +13 -3
  190. package/dist/services/tools-config-normalizer.js +3 -8
  191. package/dist/services/tools-config-normalizer.js.map +1 -1
  192. package/dist/services/tts/browser-provider.d.ts +0 -1
  193. package/dist/services/tts/browser-provider.js +2 -0
  194. package/dist/services/tts/browser-provider.js.map +1 -1
  195. package/dist/services/tts/catalog-span-alignment.d.ts +39 -0
  196. package/dist/services/tts/catalog-span-alignment.js +300 -0
  197. package/dist/services/tts/catalog-span-alignment.js.map +1 -0
  198. package/dist/services/tts/generated-speech/assemble-plan.d.ts +33 -0
  199. package/dist/services/tts/generated-speech/assemble-plan.js +111 -0
  200. package/dist/services/tts/generated-speech/assemble-plan.js.map +1 -0
  201. package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +25 -0
  202. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +66 -0
  203. package/dist/services/tts/generated-speech/dom/build-dom-plan.js.map +1 -0
  204. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.d.ts +19 -0
  205. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.js +71 -0
  206. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.js.map +1 -0
  207. package/dist/services/tts/generated-speech/dom/types.d.ts +37 -0
  208. package/dist/services/tts/generated-speech/dom/types.js +2 -0
  209. package/dist/services/tts/generated-speech/dom/types.js.map +1 -0
  210. package/dist/services/tts/generated-speech/index.d.ts +17 -0
  211. package/dist/services/tts/generated-speech/index.js +17 -0
  212. package/dist/services/tts/generated-speech/index.js.map +1 -0
  213. package/dist/services/tts/generated-speech/math-speech-cache.d.ts +15 -0
  214. package/dist/services/tts/generated-speech/math-speech-cache.js +78 -0
  215. package/dist/services/tts/generated-speech/math-speech-cache.js.map +1 -0
  216. package/dist/services/tts/generated-speech/types.d.ts +104 -0
  217. package/dist/services/tts/generated-speech/types.js +18 -0
  218. package/dist/services/tts/generated-speech/types.js.map +1 -0
  219. package/dist/services/tts/highlight-pipeline/boundary-normalizer.d.ts +2 -0
  220. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +106 -0
  221. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js.map +1 -0
  222. package/dist/services/tts/highlight-pipeline/create-highlight-plan.d.ts +6 -0
  223. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +217 -0
  224. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js.map +1 -0
  225. package/dist/services/tts/highlight-pipeline/highlight-policy.d.ts +2 -0
  226. package/dist/services/tts/highlight-pipeline/highlight-policy.js +32 -0
  227. package/dist/services/tts/highlight-pipeline/highlight-policy.js.map +1 -0
  228. package/dist/services/tts/highlight-pipeline/index.d.ts +9 -0
  229. package/dist/services/tts/highlight-pipeline/index.js +9 -0
  230. package/dist/services/tts/highlight-pipeline/index.js.map +1 -0
  231. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.d.ts +3 -0
  232. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.js +32 -0
  233. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.js.map +1 -0
  234. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.d.ts +29 -0
  235. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +44 -0
  236. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js.map +1 -0
  237. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.d.ts +2 -0
  238. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +20 -0
  239. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js.map +1 -0
  240. package/dist/services/tts/highlight-pipeline/readable-region.d.ts +1 -0
  241. package/dist/services/tts/highlight-pipeline/readable-region.js +19 -0
  242. package/dist/services/tts/highlight-pipeline/readable-region.js.map +1 -0
  243. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.d.ts +6 -0
  244. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.js +198 -0
  245. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.js.map +1 -0
  246. package/dist/services/tts/highlight-pipeline/types.d.ts +72 -0
  247. package/dist/services/tts/highlight-pipeline/types.js +2 -0
  248. package/dist/services/tts/highlight-pipeline/types.js.map +1 -0
  249. package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +2 -0
  250. package/dist/services/tts/highlight-pipeline/visible-map-range.js +22 -0
  251. package/dist/services/tts/highlight-pipeline/visible-map-range.js.map +1 -0
  252. package/dist/services/tts/math-alignment/index.d.ts +30 -0
  253. package/dist/services/tts/math-alignment/index.js +66 -0
  254. package/dist/services/tts/math-alignment/index.js.map +1 -0
  255. package/dist/services/tts/math-alignment/mathml-tokenizer.d.ts +2 -0
  256. package/dist/services/tts/math-alignment/mathml-tokenizer.js +317 -0
  257. package/dist/services/tts/math-alignment/mathml-tokenizer.js.map +1 -0
  258. package/dist/services/tts/math-alignment/range-resolver.d.ts +10 -0
  259. package/dist/services/tts/math-alignment/range-resolver.js +13 -0
  260. package/dist/services/tts/math-alignment/range-resolver.js.map +1 -0
  261. package/dist/services/tts/math-alignment/sequence-aligner.d.ts +7 -0
  262. package/dist/services/tts/math-alignment/sequence-aligner.js +119 -0
  263. package/dist/services/tts/math-alignment/sequence-aligner.js.map +1 -0
  264. package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +31 -0
  265. package/dist/services/tts/math-alignment/speech-tokenizer.js +143 -0
  266. package/dist/services/tts/math-alignment/speech-tokenizer.js.map +1 -0
  267. package/dist/services/tts/math-alignment/types.d.ts +58 -0
  268. package/dist/services/tts/math-alignment/types.js +2 -0
  269. package/dist/services/tts/math-alignment/types.js.map +1 -0
  270. package/dist/services/tts/math-aware-text-processing.d.ts +18 -0
  271. package/dist/services/tts/math-aware-text-processing.js +348 -0
  272. package/dist/services/tts/math-aware-text-processing.js.map +1 -0
  273. package/dist/services/tts/math-speech.d.ts +44 -0
  274. package/dist/services/tts/math-speech.js +147 -0
  275. package/dist/services/tts/math-speech.js.map +1 -0
  276. package/dist/services/tts/mathml-sanitization.d.ts +1 -0
  277. package/dist/services/tts/mathml-sanitization.js +170 -0
  278. package/dist/services/tts/mathml-sanitization.js.map +1 -0
  279. package/dist/services/tts/ssml/spoken-text.d.ts +33 -0
  280. package/dist/services/tts/ssml/spoken-text.js +159 -0
  281. package/dist/services/tts/ssml/spoken-text.js.map +1 -0
  282. package/dist/services/tts/text-processing.d.ts +3 -1
  283. package/dist/services/tts/text-processing.js +30 -4
  284. package/dist/services/tts/text-processing.js.map +1 -1
  285. package/dist/services/tts/text-segmentation.d.ts +0 -1
  286. package/dist/services/tts/text-segmentation.js.map +1 -1
  287. package/dist/services/tts/visual-line-ranges.d.ts +0 -1
  288. package/dist/services/tts/visual-line-ranges.js.map +1 -1
  289. package/dist/services/tts-control-events.d.ts +0 -1
  290. package/dist/services/tts-control-events.js.map +1 -1
  291. package/dist/services/tts-runtime-config.d.ts +17 -2
  292. package/dist/services/tts-runtime-config.js +11 -1
  293. package/dist/services/tts-runtime-config.js.map +1 -1
  294. package/dist/tools/calculators/desmos-provider.d.ts +0 -1
  295. package/dist/tools/calculators/desmos-provider.js.map +1 -1
  296. package/dist/tools/client.d.ts +0 -1
  297. package/dist/tools/client.js.map +1 -1
  298. package/dist/tools/default-tool-module-loaders.d.ts +0 -1
  299. package/dist/tools/default-tool-module-loaders.js.map +1 -1
  300. package/dist/tools/index.d.ts +0 -1
  301. package/dist/tools/index.js.map +1 -1
  302. package/dist/tools/library-loader.d.ts +0 -1
  303. package/dist/tools/library-loader.js.map +1 -1
  304. package/dist/tools/registrations/accessibility-tools.d.ts +0 -1
  305. package/dist/tools/registrations/accessibility-tools.js +0 -1
  306. package/dist/tools/registrations/accessibility-tools.js.map +1 -1
  307. package/dist/tools/registrations/calculator.d.ts +0 -1
  308. package/dist/tools/registrations/calculator.js +41 -2
  309. package/dist/tools/registrations/calculator.js.map +1 -1
  310. package/dist/tools/registrations/interaction-tools.d.ts +0 -1
  311. package/dist/tools/registrations/interaction-tools.js.map +1 -1
  312. package/dist/tools/registrations/measurement-tools.d.ts +0 -1
  313. package/dist/tools/registrations/measurement-tools.js.map +1 -1
  314. package/dist/tools/registrations/subject-specific-tools.d.ts +0 -1
  315. package/dist/tools/registrations/subject-specific-tools.js.map +1 -1
  316. package/dist/tools/registrations/toolbar-registration-helpers.d.ts +0 -1
  317. package/dist/tools/registrations/toolbar-registration-helpers.js.map +1 -1
  318. package/dist/tools/registrations/tts.d.ts +0 -1
  319. package/dist/tools/registrations/tts.js.map +1 -1
  320. package/dist/tools/response-discovery.d.ts +0 -1
  321. package/dist/tools/response-discovery.js.map +1 -1
  322. package/dist/tools/tool-tag-map.d.ts +0 -1
  323. package/dist/tools/tool-tag-map.js +0 -1
  324. package/dist/tools/tool-tag-map.js.map +1 -1
  325. package/dist/tools/types.d.ts +0 -1
  326. package/dist/tools/types.js.map +1 -1
  327. package/dist/tools/variant-resolver.d.ts +0 -1
  328. package/dist/tools/variant-resolver.js.map +1 -1
  329. package/dist/utils/logger.d.ts +0 -1
  330. package/dist/utils/logger.js.map +1 -1
  331. package/package.json +8 -11
  332. package/dist/attempt/AssessmentSession.d.ts.map +0 -1
  333. package/dist/attempt/TestSession.d.ts.map +0 -1
  334. package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts.map +0 -1
  335. package/dist/components/item-toolbar-element.d.ts.map +0 -1
  336. package/dist/components/pie-assessment-toolkit-element.d.ts.map +0 -1
  337. package/dist/components/section-toolbar-element.d.ts.map +0 -1
  338. package/dist/context/assessment-toolkit-context.d.ts.map +0 -1
  339. package/dist/context/runtime-context-consumer.d.ts.map +0 -1
  340. package/dist/index.d.ts.map +0 -1
  341. package/dist/item-loader.d.ts.map +0 -1
  342. package/dist/policy/core/PolicySource.d.ts.map +0 -1
  343. package/dist/policy/core/ToolPolicyEngine.d.ts.map +0 -1
  344. package/dist/policy/core/compose-decision.d.ts.map +0 -1
  345. package/dist/policy/core/decision-types.d.ts.map +0 -1
  346. package/dist/policy/core/engine-context.d.ts.map +0 -1
  347. package/dist/policy/core/pnp-policy-inputs.d.ts.map +0 -1
  348. package/dist/policy/core/policy-source-tag.d.ts.map +0 -1
  349. package/dist/policy/core/provenance.d.ts.map +0 -1
  350. package/dist/policy/engine.d.ts.map +0 -1
  351. package/dist/policy/internal.d.ts.map +0 -1
  352. package/dist/policy/sources/PnpPolicySource.d.ts.map +0 -1
  353. package/dist/runtime/RuntimeRegistry.d.ts.map +0 -1
  354. package/dist/runtime/SectionRuntimeEngine.d.ts.map +0 -1
  355. package/dist/runtime/adapter/SectionEngineAdapter.d.ts.map +0 -1
  356. package/dist/runtime/adapter/coordinator-bridge.d.ts.map +0 -1
  357. package/dist/runtime/adapter/dom-event-bridge.d.ts.map +0 -1
  358. package/dist/runtime/adapter/framework-error-bridge.d.ts.map +0 -1
  359. package/dist/runtime/adapter/instrumentation-bridge.d.ts.map +0 -1
  360. package/dist/runtime/adapter/subscriber-fanout.d.ts.map +0 -1
  361. package/dist/runtime/core/SectionEngineCore.d.ts.map +0 -1
  362. package/dist/runtime/core/cohort.d.ts.map +0 -1
  363. package/dist/runtime/core/engine-input.d.ts.map +0 -1
  364. package/dist/runtime/core/engine-output.d.ts.map +0 -1
  365. package/dist/runtime/core/engine-readiness.d.ts.map +0 -1
  366. package/dist/runtime/core/engine-resolver.d.ts.map +0 -1
  367. package/dist/runtime/core/engine-stage-derivation.d.ts.map +0 -1
  368. package/dist/runtime/core/engine-state.d.ts.map +0 -1
  369. package/dist/runtime/core/engine-transition.d.ts.map +0 -1
  370. package/dist/runtime/engine-context.d.ts.map +0 -1
  371. package/dist/runtime/engine.d.ts.map +0 -1
  372. package/dist/runtime/internal.d.ts.map +0 -1
  373. package/dist/runtime/registration-events.d.ts.map +0 -1
  374. package/dist/runtime/runtime-id.d.ts.map +0 -1
  375. package/dist/runtime/section-runtime-engine-host-context.d.ts.map +0 -1
  376. package/dist/runtime/session-event-emitter-policy.d.ts.map +0 -1
  377. package/dist/runtime/stage-emit-gate.d.ts.map +0 -1
  378. package/dist/runtime/tool-host-contract.d.ts.map +0 -1
  379. package/dist/services/AccessibilityCatalogResolver.d.ts.map +0 -1
  380. package/dist/services/ContextVariableStore.d.ts.map +0 -1
  381. package/dist/services/ElementToolStateStore.d.ts.map +0 -1
  382. package/dist/services/HighlightCoordinator.d.ts.map +0 -1
  383. package/dist/services/I18nService.d.ts.map +0 -1
  384. package/dist/services/PNPToolResolver.d.ts +0 -281
  385. package/dist/services/PNPToolResolver.d.ts.map +0 -1
  386. package/dist/services/PNPToolResolver.js +0 -514
  387. package/dist/services/PNPToolResolver.js.map +0 -1
  388. package/dist/services/RangeSerializer.d.ts.map +0 -1
  389. package/dist/services/SSMLExtractor.d.ts.map +0 -1
  390. package/dist/services/TTSService.d.ts.map +0 -1
  391. package/dist/services/ThemeProvider.d.ts.map +0 -1
  392. package/dist/services/ToolConfigResolver.d.ts.map +0 -1
  393. package/dist/services/ToolCoordinator.d.ts.map +0 -1
  394. package/dist/services/ToolRegistry.d.ts.map +0 -1
  395. package/dist/services/ToolkitCoordinator.d.ts.map +0 -1
  396. package/dist/services/create-tools-config.d.ts.map +0 -1
  397. package/dist/services/createDefaultToolRegistry.d.ts.map +0 -1
  398. package/dist/services/defaultPersonalNeedsProfile.d.ts.map +0 -1
  399. package/dist/services/framework-error-bus.d.ts.map +0 -1
  400. package/dist/services/framework-error.d.ts.map +0 -1
  401. package/dist/services/interfaces.d.ts.map +0 -1
  402. package/dist/services/pnp-provenance.d.ts +0 -167
  403. package/dist/services/pnp-provenance.d.ts.map +0 -1
  404. package/dist/services/pnp-provenance.js +0 -231
  405. package/dist/services/pnp-provenance.js.map +0 -1
  406. package/dist/services/pnp-standard-features.d.ts.map +0 -1
  407. package/dist/services/section-controller-types.d.ts.map +0 -1
  408. package/dist/services/tool-config-defaults.d.ts.map +0 -1
  409. package/dist/services/tool-config-validation.d.ts.map +0 -1
  410. package/dist/services/tool-context.d.ts.map +0 -1
  411. package/dist/services/tool-instance-id.d.ts.map +0 -1
  412. package/dist/services/tool-providers/DesmosToolProvider.d.ts.map +0 -1
  413. package/dist/services/tool-providers/TTSToolProvider.d.ts.map +0 -1
  414. package/dist/services/tool-providers/ToolProviderApi.d.ts.map +0 -1
  415. package/dist/services/tool-providers/ToolProviderRegistry.d.ts.map +0 -1
  416. package/dist/services/tool-providers/index.d.ts.map +0 -1
  417. package/dist/services/toolbar-items.d.ts.map +0 -1
  418. package/dist/services/tools-config-normalizer.d.ts.map +0 -1
  419. package/dist/services/tts/browser-provider.d.ts.map +0 -1
  420. package/dist/services/tts/text-processing.d.ts.map +0 -1
  421. package/dist/services/tts/text-segmentation.d.ts.map +0 -1
  422. package/dist/services/tts/visual-line-ranges.d.ts.map +0 -1
  423. package/dist/services/tts-control-events.d.ts.map +0 -1
  424. package/dist/services/tts-runtime-config.d.ts.map +0 -1
  425. package/dist/tools/calculators/desmos-provider.d.ts.map +0 -1
  426. package/dist/tools/client.d.ts.map +0 -1
  427. package/dist/tools/default-tool-module-loaders.d.ts.map +0 -1
  428. package/dist/tools/index.d.ts.map +0 -1
  429. package/dist/tools/library-loader.d.ts.map +0 -1
  430. package/dist/tools/registrations/accessibility-tools.d.ts.map +0 -1
  431. package/dist/tools/registrations/calculator.d.ts.map +0 -1
  432. package/dist/tools/registrations/interaction-tools.d.ts.map +0 -1
  433. package/dist/tools/registrations/measurement-tools.d.ts.map +0 -1
  434. package/dist/tools/registrations/subject-specific-tools.d.ts.map +0 -1
  435. package/dist/tools/registrations/toolbar-registration-helpers.d.ts.map +0 -1
  436. package/dist/tools/registrations/tts.d.ts.map +0 -1
  437. package/dist/tools/response-discovery.d.ts.map +0 -1
  438. package/dist/tools/tool-tag-map.d.ts.map +0 -1
  439. package/dist/tools/types.d.ts.map +0 -1
  440. package/dist/tools/variant-resolver.d.ts.map +0 -1
  441. package/dist/utils/logger.d.ts.map +0 -1
@@ -0,0 +1,217 @@
1
+ import { normalizeBoundaryEvent } from "./boundary-normalizer.js";
2
+ import { createHighlightDecision } from "./highlight-policy.js";
3
+ import { resolveMathBoundaryTarget } from "./math-semantic-resolver.js";
4
+ import { resolveProseBoundaryTarget } from "./prose-boundary-resolver.js";
5
+ import { classifyMathHighlightCapability, createRenderedMathTargetResolver, } from "./rendered-math-target-resolver.js";
6
+ const regionTargetFor = (chunk) => chunk.regionRange
7
+ ? {
8
+ type: "range",
9
+ quality: "region",
10
+ range: chunk.regionRange,
11
+ }
12
+ : chunk.regionElement
13
+ ? {
14
+ type: "element",
15
+ quality: "region",
16
+ element: chunk.regionElement,
17
+ }
18
+ : null;
19
+ const expressionTargetFor = (planned, candidates = planned.chunk
20
+ .mathAlignments) => {
21
+ if (candidates.length !== 1)
22
+ return null;
23
+ const fallback = candidates[0]?.alignment.result.fallbackTarget;
24
+ return fallback ? planned.renderedMathTargetResolver(fallback) : null;
25
+ };
26
+ const mathCandidatesForTarget = (target, chunk) => {
27
+ if (!target)
28
+ return chunk.mathAlignments;
29
+ return chunk.mathAlignments.filter(({ element }) => {
30
+ try {
31
+ if (target.type === "range")
32
+ return target.range.intersectsNode(element);
33
+ if (target.type === "element") {
34
+ return target.element === element || target.element.contains(element);
35
+ }
36
+ return target.node.parentElement?.contains(element) || false;
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ });
42
+ };
43
+ const missingChunkDecision = () => ({
44
+ activeTarget: null,
45
+ regionTarget: null,
46
+ quality: "region",
47
+ confidence: 0,
48
+ reason: "boundary chunk id was not found",
49
+ });
50
+ const soleEquationElement = (candidates) => (candidates.length === 1 ? candidates[0].element : null);
51
+ const everyCandidateIsTokenMode = (planned, candidates) => candidates.length > 0 &&
52
+ candidates.every(({ element }) => planned.mathCapabilityByElement.get(element) === "token");
53
+ const TEXT_NODE = 3;
54
+ // Safety policy for token-mode equations. A prose "range" target comes from the
55
+ // catalog span aligner, whose spoken→visible mapping inside an equation is
56
+ // heuristic and not trustworthy at glyph granularity. A multi-node range fully
57
+ // inside a token-mode equation is therefore rejected here in favor of holding
58
+ // the last token — painting it would be a likely false positive, and "false
59
+ // positives are worse than coarse highlighting." A single-text-node prose range
60
+ // is kept: it underlines one token cleanly and usefully fills in any token the
61
+ // math resolver missed. (The highlight coordinator no longer escalates word
62
+ // ranges to the whole <math> / <mjx-container>, so this is now a precision
63
+ // policy rather than flash-suppression — see HighlightCoordinator
64
+ // WORD_FALLBACK_SELECTOR.)
65
+ const wouldEscalateInsideTokenMath = (planned, target, candidates) => {
66
+ if (!target || target.type !== "range")
67
+ return false;
68
+ const { startContainer, endContainer } = target.range;
69
+ const singleTextNode = startContainer === endContainer && startContainer.nodeType === TEXT_NODE;
70
+ if (singleTextNode)
71
+ return false;
72
+ return candidates.some(({ element }) => planned.mathCapabilityByElement.get(element) === "token" &&
73
+ element.contains(startContainer) &&
74
+ element.contains(endContainer));
75
+ };
76
+ const createPlannedChunk = (chunk, mathTokenHighlighting) => ({
77
+ chunk,
78
+ regionTarget: regionTargetFor(chunk),
79
+ renderedMathTargetResolver: createRenderedMathTargetResolver(),
80
+ mathCapabilityByElement: new Map(chunk.mathAlignments.map(({ element }) => [
81
+ element,
82
+ // Forcing "expression" when per-token math highlighting is disabled
83
+ // routes every equation through the sticky whole-block path, so the
84
+ // formula is highlighted as one unit instead of glyph by glyph.
85
+ mathTokenHighlighting
86
+ ? classifyMathHighlightCapability(element)
87
+ : "expression",
88
+ ])),
89
+ heldTokenByElement: new Map(),
90
+ });
91
+ export const createTTSHighlightPlan = (args) => {
92
+ const mathTokenHighlighting = args.mathTokenHighlighting !== false;
93
+ const plannedChunksById = new Map(args.chunks.map((chunk) => [
94
+ chunk.id,
95
+ createPlannedChunk(chunk, mathTokenHighlighting),
96
+ ]));
97
+ return {
98
+ chunks: args.chunks,
99
+ resolveInitial(chunkId) {
100
+ const planned = plannedChunksById.get(chunkId);
101
+ if (!planned)
102
+ return missingChunkDecision();
103
+ const alignments = planned.chunk.mathAlignments;
104
+ const soleElement = alignments.length === 1 ? alignments[0].element : null;
105
+ const capability = soleElement
106
+ ? planned.mathCapabilityByElement.get(soleElement)
107
+ : null;
108
+ // Sticky mode. Only an equation we already know cannot be tracked per
109
+ // token gets the whole-expression paint up front. A token-mode equation
110
+ // stays on the region layer until its first token resolves, so the full
111
+ // equation never flashes before (or between) tokens.
112
+ if (capability === "expression") {
113
+ return createHighlightDecision({
114
+ semanticTarget: null,
115
+ expressionTarget: expressionTargetFor(planned),
116
+ regionTarget: planned.regionTarget,
117
+ confidence: 0.5,
118
+ reason: "initial expression (sticky expression mode)",
119
+ });
120
+ }
121
+ return createHighlightDecision({
122
+ semanticTarget: null,
123
+ expressionTarget: null,
124
+ regionTarget: planned.regionTarget,
125
+ confidence: 0,
126
+ reason: capability === "token"
127
+ ? "initial region (sticky token mode, awaiting first token)"
128
+ : "initial region fallback",
129
+ });
130
+ },
131
+ resolveBoundary(event) {
132
+ const planned = plannedChunksById.get(event.chunkId);
133
+ if (!planned)
134
+ return missingChunkDecision();
135
+ const { chunk } = planned;
136
+ const normalized = normalizeBoundaryEvent(chunk, event);
137
+ const proseTarget = resolveProseBoundaryTarget(chunk, normalized);
138
+ const mathCandidates = mathCandidatesForTarget(proseTarget, chunk);
139
+ const mathTarget = (!proseTarget || mathCandidates.length > 0
140
+ ? resolveMathBoundaryTarget(chunk, normalized, event, mathCandidates, planned.renderedMathTargetResolver)
141
+ : null) || null;
142
+ const mathTokenTarget = mathTokenHighlighting &&
143
+ mathTarget &&
144
+ mathTarget.quality !== "expression"
145
+ ? mathTarget
146
+ : null;
147
+ const mathExpressionFallback = mathTarget && mathTarget.quality === "expression" ? mathTarget : null;
148
+ // (1) A precise token always wins, and becomes the held target for its
149
+ // equation so a later gap can keep it lit instead of flashing the whole
150
+ // expression.
151
+ if (mathTokenTarget) {
152
+ const equationElement = soleEquationElement(mathCandidates);
153
+ if (equationElement) {
154
+ planned.heldTokenByElement.set(equationElement, mathTokenTarget);
155
+ }
156
+ return createHighlightDecision({
157
+ semanticTarget: mathTokenTarget,
158
+ expressionTarget: null,
159
+ regionTarget: planned.regionTarget,
160
+ confidence: normalized.confidence,
161
+ reason: normalized.reason,
162
+ });
163
+ }
164
+ // (2) A spoken word that maps to visible prose. The prose anchor is
165
+ // precise; a coarse math expression fallback must never override it.
166
+ // Exception: a multi-node prose range inside a token-mode equation
167
+ // would escalate to the whole expression, so it is rejected here and
168
+ // falls through to the token hold below. When per-token math
169
+ // highlighting is disabled, any prose range that lands inside a
170
+ // formula is likewise rejected so the formula stays a single block.
171
+ if (proseTarget &&
172
+ (mathTokenHighlighting
173
+ ? !wouldEscalateInsideTokenMath(planned, proseTarget, mathCandidates)
174
+ : mathCandidates.length === 0)) {
175
+ return createHighlightDecision({
176
+ semanticTarget: proseTarget,
177
+ expressionTarget: null,
178
+ regionTarget: planned.regionTarget,
179
+ confidence: normalized.confidence,
180
+ reason: normalized.reason,
181
+ });
182
+ }
183
+ // (3) A boundary inside a token-mode equation that did not map to a
184
+ // token — an SSML break, a pause, or a gap between spoken tokens. Hold
185
+ // the last token instead of flashing the whole expression; before the
186
+ // first token there is nothing to hold, so fall to the region layer.
187
+ // The whole expression is deliberately never painted in token mode.
188
+ if (everyCandidateIsTokenMode(planned, mathCandidates)) {
189
+ const equationElement = soleEquationElement(mathCandidates);
190
+ const heldToken = equationElement
191
+ ? (planned.heldTokenByElement.get(equationElement) ?? null)
192
+ : null;
193
+ return createHighlightDecision({
194
+ semanticTarget: heldToken,
195
+ expressionTarget: null,
196
+ regionTarget: planned.regionTarget,
197
+ confidence: normalized.confidence,
198
+ reason: heldToken
199
+ ? "hold last token (sticky token mode)"
200
+ : "region (sticky token mode, awaiting first token)",
201
+ });
202
+ }
203
+ // (4) An expression-mode (or mixed/ambiguous) math region: paint the
204
+ // whole equation. Stable for the equation's full duration because
205
+ // tokens never resolve here, so there is no flicker.
206
+ return createHighlightDecision({
207
+ semanticTarget: null,
208
+ expressionTarget: mathExpressionFallback ??
209
+ expressionTargetFor(planned, mathCandidates),
210
+ regionTarget: planned.regionTarget,
211
+ confidence: normalized.confidence,
212
+ reason: normalized.reason,
213
+ });
214
+ },
215
+ };
216
+ };
217
+ //# sourceMappingURL=create-highlight-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-highlight-plan.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/create-highlight-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EACN,+BAA+B,EAC/B,gCAAgC,GAGhC,MAAM,oCAAoC,CAAC;AAgC5C,MAAM,eAAe,GAAG,CACvB,KAAwB,EACW,EAAE,CACrC,KAAK,CAAC,WAAW;IAChB,CAAC,CAAC;QACA,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,KAAK,CAAC,WAAW;KACxB;IACF,CAAC,CAAC,KAAK,CAAC,aAAa;QACpB,CAAC,CAAC;YACA,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,KAAK,CAAC,aAAa;SAC5B;QACF,CAAC,CAAC,IAAI,CAAC;AAEV,MAAM,mBAAmB,GAAG,CAC3B,OAAqB,EACrB,aAAkD,OAAO,CAAC,KAAK;KAC7D,cAAc,EACmB,EAAE;IACrC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC;IAChE,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAC/B,MAAwC,EACxC,KAAwB,EACc,EAAE;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,cAAc,CAAC;IACzC,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;QAClD,IAAI,CAAC;YACJ,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACzE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,MAAM,CAAC,OAAO,KAAK,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACvE,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,GAAsB,EAAE,CAAC,CAAC;IACtD,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,QAAQ;IACjB,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,iCAAiC;CACzC,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAC3B,UAA+C,EAC9B,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAE9E,MAAM,yBAAyB,GAAG,CACjC,OAAqB,EACrB,UAA+C,EACrC,EAAE,CACZ,UAAU,CAAC,MAAM,GAAG,CAAC;IACrB,UAAU,CAAC,KAAK,CACf,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,OAAO,CACzE,CAAC;AAEH,MAAM,SAAS,GAAG,CAAC,CAAC;AAEpB,gFAAgF;AAChF,2EAA2E;AAC3E,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,kEAAkE;AAClE,2BAA2B;AAC3B,MAAM,4BAA4B,GAAG,CACpC,OAAqB,EACrB,MAAwC,EACxC,UAA+C,EACrC,EAAE;IACZ,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACrD,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IACtD,MAAM,cAAc,GACnB,cAAc,KAAK,YAAY,IAAI,cAAc,CAAC,QAAQ,KAAK,SAAS,CAAC;IAC1E,IAAI,cAAc;QAAE,OAAO,KAAK,CAAC;IACjC,OAAO,UAAU,CAAC,IAAI,CACrB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CACf,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,OAAO;QACxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;QAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAC/B,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAC1B,KAAwB,EACxB,qBAA8B,EACf,EAAE,CAAC,CAAC;IACnB,KAAK;IACL,YAAY,EAAE,eAAe,CAAC,KAAK,CAAC;IACpC,0BAA0B,EAAE,gCAAgC,EAAE;IAC9D,uBAAuB,EAAE,IAAI,GAAG,CAC/B,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACzC,OAAO;QACP,oEAAoE;QACpE,oEAAoE;QACpE,gEAAgE;QAChE,qBAAqB;YACpB,CAAC,CAAC,+BAA+B,CAAC,OAAO,CAAC;YAC1C,CAAC,CAAC,YAAY;KACf,CAAC,CACF;IACD,kBAAkB,EAAE,IAAI,GAAG,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACrC,IAAgC,EACb,EAAE;IACrB,MAAM,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,KAAK,KAAK,CAAC;IACnE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QAC1B,KAAK,CAAC,EAAE;QACR,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,CAAC;KAChD,CAAC,CACF,CAAC;IACF,OAAO;QACN,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,cAAc,CAAC,OAAe;YAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC/C,IAAI,CAAC,OAAO;gBAAE,OAAO,oBAAoB,EAAE,CAAC;YAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC;YAChD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3E,MAAM,UAAU,GAAG,WAAW;gBAC7B,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC;gBAClD,CAAC,CAAC,IAAI,CAAC;YACR,sEAAsE;YACtE,wEAAwE;YACxE,wEAAwE;YACxE,qDAAqD;YACrD,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;gBACjC,OAAO,uBAAuB,CAAC;oBAC9B,cAAc,EAAE,IAAI;oBACpB,gBAAgB,EAAE,mBAAmB,CAAC,OAAO,CAAC;oBAC9C,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,UAAU,EAAE,GAAG;oBACf,MAAM,EAAE,6CAA6C;iBACrD,CAAC,CAAC;YACJ,CAAC;YACD,OAAO,uBAAuB,CAAC;gBAC9B,cAAc,EAAE,IAAI;gBACpB,gBAAgB,EAAE,IAAI;gBACtB,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,UAAU,EAAE,CAAC;gBACb,MAAM,EACL,UAAU,KAAK,OAAO;oBACrB,CAAC,CAAC,0DAA0D;oBAC5D,CAAC,CAAC,yBAAyB;aAC7B,CAAC,CAAC;QACJ,CAAC;QACD,eAAe,CAAC,KAAuB;YACtC,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO;gBAAE,OAAO,oBAAoB,EAAE,CAAC;YAC5C,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;YAC1B,MAAM,UAAU,GAAG,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACxD,MAAM,WAAW,GAAG,0BAA0B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAClE,MAAM,cAAc,GAAG,uBAAuB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACnE,MAAM,UAAU,GACf,CAAC,CAAC,WAAW,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;gBACzC,CAAC,CAAC,yBAAyB,CACzB,KAAK,EACL,UAAU,EACV,KAAK,EACL,cAAc,EACd,OAAO,CAAC,0BAA0B,CAClC;gBACF,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;YAClB,MAAM,eAAe,GACpB,qBAAqB;gBACrB,UAAU;gBACV,UAAU,CAAC,OAAO,KAAK,YAAY;gBAClC,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,sBAAsB,GAC3B,UAAU,IAAI,UAAU,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;YAEvE,uEAAuE;YACvE,wEAAwE;YACxE,cAAc;YACd,IAAI,eAAe,EAAE,CAAC;gBACrB,MAAM,eAAe,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;gBAC5D,IAAI,eAAe,EAAE,CAAC;oBACrB,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;gBAClE,CAAC;gBACD,OAAO,uBAAuB,CAAC;oBAC9B,cAAc,EAAE,eAAe;oBAC/B,gBAAgB,EAAE,IAAI;oBACtB,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,UAAU,EAAE,UAAU,CAAC,UAAU;oBACjC,MAAM,EAAE,UAAU,CAAC,MAAM;iBACzB,CAAC,CAAC;YACJ,CAAC;YAED,oEAAoE;YACpE,qEAAqE;YACrE,mEAAmE;YACnE,qEAAqE;YACrE,6DAA6D;YAC7D,gEAAgE;YAChE,oEAAoE;YACpE,IACC,WAAW;gBACX,CAAC,qBAAqB;oBACrB,CAAC,CAAC,CAAC,4BAA4B,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC;oBACrE,CAAC,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,EAC9B,CAAC;gBACF,OAAO,uBAAuB,CAAC;oBAC9B,cAAc,EAAE,WAAW;oBAC3B,gBAAgB,EAAE,IAAI;oBACtB,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,UAAU,EAAE,UAAU,CAAC,UAAU;oBACjC,MAAM,EAAE,UAAU,CAAC,MAAM;iBACzB,CAAC,CAAC;YACJ,CAAC;YAED,oEAAoE;YACpE,uEAAuE;YACvE,sEAAsE;YACtE,qEAAqE;YACrE,oEAAoE;YACpE,IAAI,yBAAyB,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC;gBACxD,MAAM,eAAe,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;gBAC5D,MAAM,SAAS,GAAG,eAAe;oBAChC,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC;oBAC3D,CAAC,CAAC,IAAI,CAAC;gBACR,OAAO,uBAAuB,CAAC;oBAC9B,cAAc,EAAE,SAAS;oBACzB,gBAAgB,EAAE,IAAI;oBACtB,YAAY,EAAE,OAAO,CAAC,YAAY;oBAClC,UAAU,EAAE,UAAU,CAAC,UAAU;oBACjC,MAAM,EAAE,SAAS;wBAChB,CAAC,CAAC,qCAAqC;wBACvC,CAAC,CAAC,kDAAkD;iBACrD,CAAC,CAAC;YACJ,CAAC;YAED,qEAAqE;YACrE,kEAAkE;YAClE,qDAAqD;YACrD,OAAO,uBAAuB,CAAC;gBAC9B,cAAc,EAAE,IAAI;gBACpB,gBAAgB,EACf,sBAAsB;oBACtB,mBAAmB,CAAC,OAAO,EAAE,cAAc,CAAC;gBAC7C,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,MAAM,EAAE,UAAU,CAAC,MAAM;aACzB,CAAC,CAAC;QACJ,CAAC;KACD,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { normalizeBoundaryEvent } from \"./boundary-normalizer.js\";\nimport { createHighlightDecision } from \"./highlight-policy.js\";\nimport { resolveMathBoundaryTarget } from \"./math-semantic-resolver.js\";\nimport { resolveProseBoundaryTarget } from \"./prose-boundary-resolver.js\";\nimport {\n\tclassifyMathHighlightCapability,\n\tcreateRenderedMathTargetResolver,\n\ttype MathHighlightCapability,\n\ttype RenderedMathTargetResolver,\n} from \"./rendered-math-target-resolver.js\";\nimport type {\n\tHighlightDecision,\n\tRenderableHighlightTarget,\n\tTTSBoundaryEvent,\n\tTTSHighlightChunk,\n\tTTSHighlightPlan,\n} from \"./types.js\";\n\nexport interface CreateTTSHighlightPlanArgs {\n\tchunks: TTSHighlightChunk[];\n\t// When false, math is never broken into per-token highlights: every equation\n\t// is painted as a single block — the same expression/region fallback used\n\t// whenever token alignment is not confident. Prose word tracking is\n\t// unaffected. Defaults to true.\n\tmathTokenHighlighting?: boolean;\n}\n\ninterface PlannedChunk {\n\tchunk: TTSHighlightChunk;\n\tregionTarget: RenderableHighlightTarget | null;\n\trenderedMathTargetResolver: RenderedMathTargetResolver;\n\t// Capability decided once per equation (keyed by its source math element).\n\t// Sticky for the whole chunk so the same equation never switches between\n\t// token tracking and whole-expression highlighting mid-read.\n\tmathCapabilityByElement: Map<Element, MathHighlightCapability>;\n\t// The last precise token painted for each token-mode equation. Lets a gap\n\t// (SSML break / pause / unmappable boundary) hold the last token instead of\n\t// flashing the whole expression.\n\theldTokenByElement: Map<Element, RenderableHighlightTarget>;\n}\n\nconst regionTargetFor = (\n\tchunk: TTSHighlightChunk,\n): RenderableHighlightTarget | null =>\n\tchunk.regionRange\n\t\t? {\n\t\t\t\ttype: \"range\",\n\t\t\t\tquality: \"region\",\n\t\t\t\trange: chunk.regionRange,\n\t\t\t}\n\t\t: chunk.regionElement\n\t\t\t? {\n\t\t\t\t\ttype: \"element\",\n\t\t\t\t\tquality: \"region\",\n\t\t\t\t\telement: chunk.regionElement,\n\t\t\t\t}\n\t\t\t: null;\n\nconst expressionTargetFor = (\n\tplanned: PlannedChunk,\n\tcandidates: TTSHighlightChunk[\"mathAlignments\"] = planned.chunk\n\t\t.mathAlignments,\n): RenderableHighlightTarget | null => {\n\tif (candidates.length !== 1) return null;\n\tconst fallback = candidates[0]?.alignment.result.fallbackTarget;\n\treturn fallback ? planned.renderedMathTargetResolver(fallback) : null;\n};\n\nconst mathCandidatesForTarget = (\n\ttarget: RenderableHighlightTarget | null,\n\tchunk: TTSHighlightChunk,\n): TTSHighlightChunk[\"mathAlignments\"] => {\n\tif (!target) return chunk.mathAlignments;\n\treturn chunk.mathAlignments.filter(({ element }) => {\n\t\ttry {\n\t\t\tif (target.type === \"range\") return target.range.intersectsNode(element);\n\t\t\tif (target.type === \"element\") {\n\t\t\t\treturn target.element === element || target.element.contains(element);\n\t\t\t}\n\t\t\treturn target.node.parentElement?.contains(element) || false;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t});\n};\n\nconst missingChunkDecision = (): HighlightDecision => ({\n\tactiveTarget: null,\n\tregionTarget: null,\n\tquality: \"region\",\n\tconfidence: 0,\n\treason: \"boundary chunk id was not found\",\n});\n\nconst soleEquationElement = (\n\tcandidates: TTSHighlightChunk[\"mathAlignments\"],\n): Element | null => (candidates.length === 1 ? candidates[0].element : null);\n\nconst everyCandidateIsTokenMode = (\n\tplanned: PlannedChunk,\n\tcandidates: TTSHighlightChunk[\"mathAlignments\"],\n): boolean =>\n\tcandidates.length > 0 &&\n\tcandidates.every(\n\t\t({ element }) => planned.mathCapabilityByElement.get(element) === \"token\",\n\t);\n\nconst TEXT_NODE = 3;\n\n// Safety policy for token-mode equations. A prose \"range\" target comes from the\n// catalog span aligner, whose spoken→visible mapping inside an equation is\n// heuristic and not trustworthy at glyph granularity. A multi-node range fully\n// inside a token-mode equation is therefore rejected here in favor of holding\n// the last token — painting it would be a likely false positive, and \"false\n// positives are worse than coarse highlighting.\" A single-text-node prose range\n// is kept: it underlines one token cleanly and usefully fills in any token the\n// math resolver missed. (The highlight coordinator no longer escalates word\n// ranges to the whole <math> / <mjx-container>, so this is now a precision\n// policy rather than flash-suppression — see HighlightCoordinator\n// WORD_FALLBACK_SELECTOR.)\nconst wouldEscalateInsideTokenMath = (\n\tplanned: PlannedChunk,\n\ttarget: RenderableHighlightTarget | null,\n\tcandidates: TTSHighlightChunk[\"mathAlignments\"],\n): boolean => {\n\tif (!target || target.type !== \"range\") return false;\n\tconst { startContainer, endContainer } = target.range;\n\tconst singleTextNode =\n\t\tstartContainer === endContainer && startContainer.nodeType === TEXT_NODE;\n\tif (singleTextNode) return false;\n\treturn candidates.some(\n\t\t({ element }) =>\n\t\t\tplanned.mathCapabilityByElement.get(element) === \"token\" &&\n\t\t\telement.contains(startContainer) &&\n\t\t\telement.contains(endContainer),\n\t);\n};\n\nconst createPlannedChunk = (\n\tchunk: TTSHighlightChunk,\n\tmathTokenHighlighting: boolean,\n): PlannedChunk => ({\n\tchunk,\n\tregionTarget: regionTargetFor(chunk),\n\trenderedMathTargetResolver: createRenderedMathTargetResolver(),\n\tmathCapabilityByElement: new Map(\n\t\tchunk.mathAlignments.map(({ element }) => [\n\t\t\telement,\n\t\t\t// Forcing \"expression\" when per-token math highlighting is disabled\n\t\t\t// routes every equation through the sticky whole-block path, so the\n\t\t\t// formula is highlighted as one unit instead of glyph by glyph.\n\t\t\tmathTokenHighlighting\n\t\t\t\t? classifyMathHighlightCapability(element)\n\t\t\t\t: \"expression\",\n\t\t]),\n\t),\n\theldTokenByElement: new Map(),\n});\n\nexport const createTTSHighlightPlan = (\n\targs: CreateTTSHighlightPlanArgs,\n): TTSHighlightPlan => {\n\tconst mathTokenHighlighting = args.mathTokenHighlighting !== false;\n\tconst plannedChunksById = new Map(\n\t\targs.chunks.map((chunk) => [\n\t\t\tchunk.id,\n\t\t\tcreatePlannedChunk(chunk, mathTokenHighlighting),\n\t\t]),\n\t);\n\treturn {\n\t\tchunks: args.chunks,\n\t\tresolveInitial(chunkId: string): HighlightDecision {\n\t\t\tconst planned = plannedChunksById.get(chunkId);\n\t\t\tif (!planned) return missingChunkDecision();\n\t\t\tconst alignments = planned.chunk.mathAlignments;\n\t\t\tconst soleElement = alignments.length === 1 ? alignments[0].element : null;\n\t\t\tconst capability = soleElement\n\t\t\t\t? planned.mathCapabilityByElement.get(soleElement)\n\t\t\t\t: null;\n\t\t\t// Sticky mode. Only an equation we already know cannot be tracked per\n\t\t\t// token gets the whole-expression paint up front. A token-mode equation\n\t\t\t// stays on the region layer until its first token resolves, so the full\n\t\t\t// equation never flashes before (or between) tokens.\n\t\t\tif (capability === \"expression\") {\n\t\t\t\treturn createHighlightDecision({\n\t\t\t\t\tsemanticTarget: null,\n\t\t\t\t\texpressionTarget: expressionTargetFor(planned),\n\t\t\t\t\tregionTarget: planned.regionTarget,\n\t\t\t\t\tconfidence: 0.5,\n\t\t\t\t\treason: \"initial expression (sticky expression mode)\",\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn createHighlightDecision({\n\t\t\t\tsemanticTarget: null,\n\t\t\t\texpressionTarget: null,\n\t\t\t\tregionTarget: planned.regionTarget,\n\t\t\t\tconfidence: 0,\n\t\t\t\treason:\n\t\t\t\t\tcapability === \"token\"\n\t\t\t\t\t\t? \"initial region (sticky token mode, awaiting first token)\"\n\t\t\t\t\t\t: \"initial region fallback\",\n\t\t\t});\n\t\t},\n\t\tresolveBoundary(event: TTSBoundaryEvent): HighlightDecision {\n\t\t\tconst planned = plannedChunksById.get(event.chunkId);\n\t\t\tif (!planned) return missingChunkDecision();\n\t\t\tconst { chunk } = planned;\n\t\t\tconst normalized = normalizeBoundaryEvent(chunk, event);\n\t\t\tconst proseTarget = resolveProseBoundaryTarget(chunk, normalized);\n\t\t\tconst mathCandidates = mathCandidatesForTarget(proseTarget, chunk);\n\t\t\tconst mathTarget =\n\t\t\t\t(!proseTarget || mathCandidates.length > 0\n\t\t\t\t\t? resolveMathBoundaryTarget(\n\t\t\t\t\t\t\tchunk,\n\t\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\tevent,\n\t\t\t\t\t\t\tmathCandidates,\n\t\t\t\t\t\t\tplanned.renderedMathTargetResolver,\n\t\t\t\t\t\t)\n\t\t\t\t\t: null) || null;\n\t\t\tconst mathTokenTarget =\n\t\t\t\tmathTokenHighlighting &&\n\t\t\t\tmathTarget &&\n\t\t\t\tmathTarget.quality !== \"expression\"\n\t\t\t\t\t? mathTarget\n\t\t\t\t\t: null;\n\t\t\tconst mathExpressionFallback =\n\t\t\t\tmathTarget && mathTarget.quality === \"expression\" ? mathTarget : null;\n\n\t\t\t// (1) A precise token always wins, and becomes the held target for its\n\t\t\t// equation so a later gap can keep it lit instead of flashing the whole\n\t\t\t// expression.\n\t\t\tif (mathTokenTarget) {\n\t\t\t\tconst equationElement = soleEquationElement(mathCandidates);\n\t\t\t\tif (equationElement) {\n\t\t\t\t\tplanned.heldTokenByElement.set(equationElement, mathTokenTarget);\n\t\t\t\t}\n\t\t\t\treturn createHighlightDecision({\n\t\t\t\t\tsemanticTarget: mathTokenTarget,\n\t\t\t\t\texpressionTarget: null,\n\t\t\t\t\tregionTarget: planned.regionTarget,\n\t\t\t\t\tconfidence: normalized.confidence,\n\t\t\t\t\treason: normalized.reason,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// (2) A spoken word that maps to visible prose. The prose anchor is\n\t\t\t// precise; a coarse math expression fallback must never override it.\n\t\t\t// Exception: a multi-node prose range inside a token-mode equation\n\t\t\t// would escalate to the whole expression, so it is rejected here and\n\t\t\t// falls through to the token hold below. When per-token math\n\t\t\t// highlighting is disabled, any prose range that lands inside a\n\t\t\t// formula is likewise rejected so the formula stays a single block.\n\t\t\tif (\n\t\t\t\tproseTarget &&\n\t\t\t\t(mathTokenHighlighting\n\t\t\t\t\t? !wouldEscalateInsideTokenMath(planned, proseTarget, mathCandidates)\n\t\t\t\t\t: mathCandidates.length === 0)\n\t\t\t) {\n\t\t\t\treturn createHighlightDecision({\n\t\t\t\t\tsemanticTarget: proseTarget,\n\t\t\t\t\texpressionTarget: null,\n\t\t\t\t\tregionTarget: planned.regionTarget,\n\t\t\t\t\tconfidence: normalized.confidence,\n\t\t\t\t\treason: normalized.reason,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// (3) A boundary inside a token-mode equation that did not map to a\n\t\t\t// token — an SSML break, a pause, or a gap between spoken tokens. Hold\n\t\t\t// the last token instead of flashing the whole expression; before the\n\t\t\t// first token there is nothing to hold, so fall to the region layer.\n\t\t\t// The whole expression is deliberately never painted in token mode.\n\t\t\tif (everyCandidateIsTokenMode(planned, mathCandidates)) {\n\t\t\t\tconst equationElement = soleEquationElement(mathCandidates);\n\t\t\t\tconst heldToken = equationElement\n\t\t\t\t\t? (planned.heldTokenByElement.get(equationElement) ?? null)\n\t\t\t\t\t: null;\n\t\t\t\treturn createHighlightDecision({\n\t\t\t\t\tsemanticTarget: heldToken,\n\t\t\t\t\texpressionTarget: null,\n\t\t\t\t\tregionTarget: planned.regionTarget,\n\t\t\t\t\tconfidence: normalized.confidence,\n\t\t\t\t\treason: heldToken\n\t\t\t\t\t\t? \"hold last token (sticky token mode)\"\n\t\t\t\t\t\t: \"region (sticky token mode, awaiting first token)\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// (4) An expression-mode (or mixed/ambiguous) math region: paint the\n\t\t\t// whole equation. Stable for the equation's full duration because\n\t\t\t// tokens never resolve here, so there is no flicker.\n\t\t\treturn createHighlightDecision({\n\t\t\t\tsemanticTarget: null,\n\t\t\t\texpressionTarget:\n\t\t\t\t\tmathExpressionFallback ??\n\t\t\t\t\texpressionTargetFor(planned, mathCandidates),\n\t\t\t\tregionTarget: planned.regionTarget,\n\t\t\t\tconfidence: normalized.confidence,\n\t\t\t\treason: normalized.reason,\n\t\t\t});\n\t\t},\n\t};\n};\n"]}
@@ -0,0 +1,2 @@
1
+ import type { HighlightDecision, HighlightDecisionInput } from "./types.js";
2
+ export declare const createHighlightDecision: (input: HighlightDecisionInput) => HighlightDecision;
@@ -0,0 +1,32 @@
1
+ export const createHighlightDecision = (input) => {
2
+ if (input.semanticTarget) {
3
+ return {
4
+ activeTarget: input.semanticTarget,
5
+ regionTarget: input.regionTarget,
6
+ quality: input.semanticTarget.quality === "exact-word"
7
+ ? "exact-word"
8
+ : input.semanticTarget.quality === "expression"
9
+ ? "expression"
10
+ : "semantic-token",
11
+ confidence: input.confidence,
12
+ reason: input.reason,
13
+ };
14
+ }
15
+ if (input.expressionTarget) {
16
+ return {
17
+ activeTarget: input.expressionTarget,
18
+ regionTarget: input.regionTarget,
19
+ quality: "expression",
20
+ confidence: input.confidence,
21
+ reason: input.reason,
22
+ };
23
+ }
24
+ return {
25
+ activeTarget: null,
26
+ regionTarget: input.regionTarget,
27
+ quality: "region",
28
+ confidence: input.confidence,
29
+ reason: input.reason,
30
+ };
31
+ };
32
+ //# sourceMappingURL=highlight-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight-policy.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/highlight-policy.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACtC,KAA6B,EACT,EAAE;IACtB,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QAC1B,OAAO;YACN,YAAY,EAAE,KAAK,CAAC,cAAc;YAClC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,OAAO,EACN,KAAK,CAAC,cAAc,CAAC,OAAO,KAAK,YAAY;gBAC5C,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,KAAK,YAAY;oBAC9C,CAAC,CAAC,YAAY;oBACd,CAAC,CAAC,gBAAgB;YACrB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;SACpB,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAC5B,OAAO;YACN,YAAY,EAAE,KAAK,CAAC,gBAAgB;YACpC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,OAAO,EAAE,YAAY;YACrB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;SACpB,CAAC;IACH,CAAC;IACD,OAAO;QACN,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC;AACH,CAAC,CAAC","sourcesContent":["import type { HighlightDecision, HighlightDecisionInput } from \"./types.js\";\n\nexport const createHighlightDecision = (\n\tinput: HighlightDecisionInput,\n): HighlightDecision => {\n\tif (input.semanticTarget) {\n\t\treturn {\n\t\t\tactiveTarget: input.semanticTarget,\n\t\t\tregionTarget: input.regionTarget,\n\t\t\tquality:\n\t\t\t\tinput.semanticTarget.quality === \"exact-word\"\n\t\t\t\t\t? \"exact-word\"\n\t\t\t\t\t: input.semanticTarget.quality === \"expression\"\n\t\t\t\t\t\t? \"expression\"\n\t\t\t\t\t\t: \"semantic-token\",\n\t\t\tconfidence: input.confidence,\n\t\t\treason: input.reason,\n\t\t};\n\t}\n\tif (input.expressionTarget) {\n\t\treturn {\n\t\t\tactiveTarget: input.expressionTarget,\n\t\t\tregionTarget: input.regionTarget,\n\t\t\tquality: \"expression\",\n\t\t\tconfidence: input.confidence,\n\t\t\treason: input.reason,\n\t\t};\n\t}\n\treturn {\n\t\tactiveTarget: null,\n\t\tregionTarget: input.regionTarget,\n\t\tquality: \"region\",\n\t\tconfidence: input.confidence,\n\t\treason: input.reason,\n\t};\n};\n"]}
@@ -0,0 +1,9 @@
1
+ export * from "./boundary-normalizer.js";
2
+ export * from "./create-highlight-plan.js";
3
+ export * from "./highlight-policy.js";
4
+ export * from "./math-semantic-resolver.js";
5
+ export * from "./normalize-speech-chunks.js";
6
+ export * from "./prose-boundary-resolver.js";
7
+ export * from "./readable-region.js";
8
+ export * from "./rendered-math-target-resolver.js";
9
+ export type * from "./types.js";
@@ -0,0 +1,9 @@
1
+ export * from "./boundary-normalizer.js";
2
+ export * from "./create-highlight-plan.js";
3
+ export * from "./highlight-policy.js";
4
+ export * from "./math-semantic-resolver.js";
5
+ export * from "./normalize-speech-chunks.js";
6
+ export * from "./prose-boundary-resolver.js";
7
+ export * from "./readable-region.js";
8
+ export * from "./rendered-math-target-resolver.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,oCAAoC,CAAC","sourcesContent":["export * from \"./boundary-normalizer.js\";\nexport * from \"./create-highlight-plan.js\";\nexport * from \"./highlight-policy.js\";\nexport * from \"./math-semantic-resolver.js\";\nexport * from \"./normalize-speech-chunks.js\";\nexport * from \"./prose-boundary-resolver.js\";\nexport * from \"./readable-region.js\";\nexport * from \"./rendered-math-target-resolver.js\";\nexport type * from \"./types.js\";\n"]}
@@ -0,0 +1,3 @@
1
+ import { type RenderedMathTargetResolver } from "./rendered-math-target-resolver.js";
2
+ import type { NormalizedBoundaryEvent, RenderableHighlightTarget, TTSBoundaryEvent, TTSHighlightChunk } from "./types.js";
3
+ export declare const resolveMathBoundaryTarget: (chunk: TTSHighlightChunk, boundary: NormalizedBoundaryEvent, event: TTSBoundaryEvent, candidates?: TTSHighlightChunk["mathAlignments"], renderedResolver?: RenderedMathTargetResolver) => RenderableHighlightTarget | null;
@@ -0,0 +1,32 @@
1
+ import { resolveMatchedHighlightTargetForSpokenBoundary, resolveUniqueMathTargetForBoundaryWord, } from "../math-alignment/index.js";
2
+ import { resolveRenderedMathTarget, } from "./rendered-math-target-resolver.js";
3
+ export const resolveMathBoundaryTarget = (chunk, boundary, event, candidates = chunk.mathAlignments, renderedResolver = resolveRenderedMathTarget) => {
4
+ if (boundary.chunkSpokenStart === null || boundary.chunkSpokenEnd === null) {
5
+ return null;
6
+ }
7
+ // Prefer a precise per-token target across all candidate equations before
8
+ // settling for a coarse expression fallback: scan every candidate for a
9
+ // semantic-token first, remembering the first expression-quality hit only as
10
+ // a last resort.
11
+ let expressionFallback = null;
12
+ for (const mathAlignment of candidates) {
13
+ const target = resolveMatchedHighlightTargetForSpokenBoundary(mathAlignment.alignment, {
14
+ position: boundary.chunkSpokenStart,
15
+ length: Math.max(1, boundary.chunkSpokenEnd - boundary.chunkSpokenStart),
16
+ boundaryWord: event.word,
17
+ }) ||
18
+ resolveUniqueMathTargetForBoundaryWord(mathAlignment.alignment, {
19
+ boundaryWord: event.word,
20
+ });
21
+ if (!target)
22
+ continue;
23
+ const rendered = renderedResolver(target);
24
+ if (!rendered)
25
+ continue;
26
+ if (rendered.quality === "semantic-token")
27
+ return rendered;
28
+ expressionFallback ??= rendered;
29
+ }
30
+ return expressionFallback;
31
+ };
32
+ //# sourceMappingURL=math-semantic-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math-semantic-resolver.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/math-semantic-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8CAA8C,EAC9C,sCAAsC,GACtC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACN,yBAAyB,GAEzB,MAAM,oCAAoC,CAAC;AAQ5C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACxC,KAAwB,EACxB,QAAiC,EACjC,KAAuB,EACvB,aAAkD,KAAK,CAAC,cAAc,EACtE,mBAA+C,yBAAyB,EACrC,EAAE;IACrC,IAAI,QAAQ,CAAC,gBAAgB,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IACb,CAAC;IACD,0EAA0E;IAC1E,wEAAwE;IACxE,6EAA6E;IAC7E,iBAAiB;IACjB,IAAI,kBAAkB,GAAqC,IAAI,CAAC;IAChE,KAAK,MAAM,aAAa,IAAI,UAAU,EAAE,CAAC;QACxC,MAAM,MAAM,GACX,8CAA8C,CAAC,aAAa,CAAC,SAAS,EAAE;YACvE,QAAQ,EAAE,QAAQ,CAAC,gBAAgB;YACnC,MAAM,EAAE,IAAI,CAAC,GAAG,CACf,CAAC,EACD,QAAQ,CAAC,cAAc,GAAG,QAAQ,CAAC,gBAAgB,CACnD;YACD,YAAY,EAAE,KAAK,CAAC,IAAI;SACxB,CAAC;YACF,sCAAsC,CAAC,aAAa,CAAC,SAAS,EAAE;gBAC/D,YAAY,EAAE,KAAK,CAAC,IAAI;aACxB,CAAC,CAAC;QACJ,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,IAAI,QAAQ,CAAC,OAAO,KAAK,gBAAgB;YAAE,OAAO,QAAQ,CAAC;QAC3D,kBAAkB,KAAK,QAAQ,CAAC;IACjC,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC3B,CAAC,CAAC","sourcesContent":["import {\n\tresolveMatchedHighlightTargetForSpokenBoundary,\n\tresolveUniqueMathTargetForBoundaryWord,\n} from \"../math-alignment/index.js\";\nimport {\n\tresolveRenderedMathTarget,\n\ttype RenderedMathTargetResolver,\n} from \"./rendered-math-target-resolver.js\";\nimport type {\n\tNormalizedBoundaryEvent,\n\tRenderableHighlightTarget,\n\tTTSBoundaryEvent,\n\tTTSHighlightChunk,\n} from \"./types.js\";\n\nexport const resolveMathBoundaryTarget = (\n\tchunk: TTSHighlightChunk,\n\tboundary: NormalizedBoundaryEvent,\n\tevent: TTSBoundaryEvent,\n\tcandidates: TTSHighlightChunk[\"mathAlignments\"] = chunk.mathAlignments,\n\trenderedResolver: RenderedMathTargetResolver = resolveRenderedMathTarget,\n): RenderableHighlightTarget | null => {\n\tif (boundary.chunkSpokenStart === null || boundary.chunkSpokenEnd === null) {\n\t\treturn null;\n\t}\n\t// Prefer a precise per-token target across all candidate equations before\n\t// settling for a coarse expression fallback: scan every candidate for a\n\t// semantic-token first, remembering the first expression-quality hit only as\n\t// a last resort.\n\tlet expressionFallback: RenderableHighlightTarget | null = null;\n\tfor (const mathAlignment of candidates) {\n\t\tconst target =\n\t\t\tresolveMatchedHighlightTargetForSpokenBoundary(mathAlignment.alignment, {\n\t\t\t\tposition: boundary.chunkSpokenStart,\n\t\t\t\tlength: Math.max(\n\t\t\t\t\t1,\n\t\t\t\t\tboundary.chunkSpokenEnd - boundary.chunkSpokenStart,\n\t\t\t\t),\n\t\t\t\tboundaryWord: event.word,\n\t\t\t}) ||\n\t\t\tresolveUniqueMathTargetForBoundaryWord(mathAlignment.alignment, {\n\t\t\t\tboundaryWord: event.word,\n\t\t\t});\n\t\tif (!target) continue;\n\t\tconst rendered = renderedResolver(target);\n\t\tif (!rendered) continue;\n\t\tif (rendered.quality === \"semantic-token\") return rendered;\n\t\texpressionFallback ??= rendered;\n\t}\n\treturn expressionFallback;\n};\n"]}
@@ -0,0 +1,29 @@
1
+ import type { CatalogSpanAlignment } from "../catalog-span-alignment.js";
2
+ import type { MathAwareAlignment } from "../math-alignment/index.js";
3
+ import type { NormalizedTextMap } from "../text-processing.js";
4
+ import type { TTSHighlightChunk } from "./types.js";
5
+ export interface SpeechCompositionChunkInput {
6
+ speechText: string;
7
+ visibleText: string;
8
+ sourceElement: Element | null;
9
+ regionElement?: Element | null;
10
+ regionRange?: Range;
11
+ alignment?: CatalogSpanAlignment;
12
+ mathAlignment?: MathAwareAlignment;
13
+ mathAlignments?: Array<{
14
+ element: Element;
15
+ alignment: MathAwareAlignment;
16
+ }>;
17
+ visibleMap?: NormalizedTextMap;
18
+ }
19
+ export interface NormalizeSpeechChunksArgs {
20
+ contentRoot: Element;
21
+ chunks?: SpeechCompositionChunkInput[];
22
+ speechText?: string;
23
+ visibleText?: string;
24
+ sourceElement?: Element | null;
25
+ regionElement?: Element | null;
26
+ regionRange?: Range;
27
+ visibleMap?: NormalizedTextMap;
28
+ }
29
+ export declare const normalizeSpeechChunks: (args: NormalizeSpeechChunksArgs) => TTSHighlightChunk[];
@@ -0,0 +1,44 @@
1
+ const chunkOffsetSpaceFor = (chunk) => {
2
+ if (chunk.alignment?.boundaryOffsetMode)
3
+ return chunk.alignment.boundaryOffsetMode;
4
+ const mathOffsetSpace = chunk.mathAlignment?.speech.boundaryOffsetSpace;
5
+ if (mathOffsetSpace)
6
+ return mathOffsetSpace;
7
+ return "plain-spoken-text";
8
+ };
9
+ const mathAlignmentsFor = (chunk) => {
10
+ if (chunk.mathAlignments?.length)
11
+ return chunk.mathAlignments;
12
+ if (chunk.mathAlignment && chunk.sourceElement) {
13
+ return [{ element: chunk.sourceElement, alignment: chunk.mathAlignment }];
14
+ }
15
+ return [];
16
+ };
17
+ export const normalizeSpeechChunks = (args) => {
18
+ const sourceChunks = args.chunks && args.chunks.length
19
+ ? args.chunks
20
+ : [
21
+ {
22
+ speechText: args.speechText || "",
23
+ visibleText: args.visibleText || args.speechText || "",
24
+ sourceElement: args.sourceElement || args.contentRoot,
25
+ regionElement: args.regionElement || args.sourceElement || args.contentRoot,
26
+ regionRange: args.regionRange,
27
+ visibleMap: args.visibleMap,
28
+ },
29
+ ];
30
+ return sourceChunks.map((chunk, index) => ({
31
+ id: `tts-chunk-${index}`,
32
+ speechText: chunk.speechText,
33
+ visibleText: chunk.visibleText,
34
+ sourceElement: chunk.sourceElement,
35
+ contentRoot: args.contentRoot,
36
+ regionElement: chunk.regionElement ?? chunk.sourceElement,
37
+ regionRange: chunk.regionRange,
38
+ visibleMap: chunk.visibleMap,
39
+ catalogAlignment: chunk.alignment,
40
+ mathAlignments: mathAlignmentsFor(chunk),
41
+ offsetSpace: chunkOffsetSpaceFor(chunk),
42
+ }));
43
+ };
44
+ //# sourceMappingURL=normalize-speech-chunks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-speech-chunks.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/normalize-speech-chunks.ts"],"names":[],"mappings":"AA4BA,MAAM,mBAAmB,GAAG,CAC3B,KAAkC,EACf,EAAE;IACrB,IAAI,KAAK,CAAC,SAAS,EAAE,kBAAkB;QACtC,OAAO,KAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC;IAC3C,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,mBAAmB,CAAC;IACxE,IAAI,eAAe;QAAE,OAAO,eAAe,CAAC;IAC5C,OAAO,mBAAmB,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CACzB,KAAkC,EAC2B,EAAE;IAC/D,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM;QAAE,OAAO,KAAK,CAAC,cAAc,CAAC;IAC9D,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QAChD,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,aAAa,EAAE,SAAS,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,IAA+B,EACT,EAAE;IACxB,MAAM,YAAY,GACjB,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM;QAChC,CAAC,CAAC,IAAI,CAAC,MAAM;QACb,CAAC,CAAC;YACA;gBACC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;gBACjC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE;gBACtD,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,WAAW;gBACrD,aAAa,EACZ,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,WAAW;gBAC7D,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;aAC3B;SACD,CAAC;IACL,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,EAAE,EAAE,aAAa,KAAK,EAAE;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa;QACzD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,gBAAgB,EAAE,KAAK,CAAC,SAAS;QACjC,cAAc,EAAE,iBAAiB,CAAC,KAAK,CAAC;QACxC,WAAW,EAAE,mBAAmB,CAAC,KAAK,CAAC;KACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import type { CatalogSpanAlignment } from \"../catalog-span-alignment.js\";\nimport type { MathAwareAlignment } from \"../math-alignment/index.js\";\nimport type { NormalizedTextMap } from \"../text-processing.js\";\nimport type { ChunkOffsetSpace, TTSHighlightChunk } from \"./types.js\";\n\nexport interface SpeechCompositionChunkInput {\n\tspeechText: string;\n\tvisibleText: string;\n\tsourceElement: Element | null;\n\tregionElement?: Element | null;\n\tregionRange?: Range;\n\talignment?: CatalogSpanAlignment;\n\tmathAlignment?: MathAwareAlignment;\n\tmathAlignments?: Array<{ element: Element; alignment: MathAwareAlignment }>;\n\tvisibleMap?: NormalizedTextMap;\n}\n\nexport interface NormalizeSpeechChunksArgs {\n\tcontentRoot: Element;\n\tchunks?: SpeechCompositionChunkInput[];\n\tspeechText?: string;\n\tvisibleText?: string;\n\tsourceElement?: Element | null;\n\tregionElement?: Element | null;\n\tregionRange?: Range;\n\tvisibleMap?: NormalizedTextMap;\n}\n\nconst chunkOffsetSpaceFor = (\n\tchunk: SpeechCompositionChunkInput,\n): ChunkOffsetSpace => {\n\tif (chunk.alignment?.boundaryOffsetMode)\n\t\treturn chunk.alignment.boundaryOffsetMode;\n\tconst mathOffsetSpace = chunk.mathAlignment?.speech.boundaryOffsetSpace;\n\tif (mathOffsetSpace) return mathOffsetSpace;\n\treturn \"plain-spoken-text\";\n};\n\nconst mathAlignmentsFor = (\n\tchunk: SpeechCompositionChunkInput,\n): Array<{ element: Element; alignment: MathAwareAlignment }> => {\n\tif (chunk.mathAlignments?.length) return chunk.mathAlignments;\n\tif (chunk.mathAlignment && chunk.sourceElement) {\n\t\treturn [{ element: chunk.sourceElement, alignment: chunk.mathAlignment }];\n\t}\n\treturn [];\n};\n\nexport const normalizeSpeechChunks = (\n\targs: NormalizeSpeechChunksArgs,\n): TTSHighlightChunk[] => {\n\tconst sourceChunks =\n\t\targs.chunks && args.chunks.length\n\t\t\t? args.chunks\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\tspeechText: args.speechText || \"\",\n\t\t\t\t\t\tvisibleText: args.visibleText || args.speechText || \"\",\n\t\t\t\t\t\tsourceElement: args.sourceElement || args.contentRoot,\n\t\t\t\t\t\tregionElement:\n\t\t\t\t\t\t\targs.regionElement || args.sourceElement || args.contentRoot,\n\t\t\t\t\t\tregionRange: args.regionRange,\n\t\t\t\t\t\tvisibleMap: args.visibleMap,\n\t\t\t\t\t},\n\t\t\t\t];\n\treturn sourceChunks.map((chunk, index) => ({\n\t\tid: `tts-chunk-${index}`,\n\t\tspeechText: chunk.speechText,\n\t\tvisibleText: chunk.visibleText,\n\t\tsourceElement: chunk.sourceElement,\n\t\tcontentRoot: args.contentRoot,\n\t\tregionElement: chunk.regionElement ?? chunk.sourceElement,\n\t\tregionRange: chunk.regionRange,\n\t\tvisibleMap: chunk.visibleMap,\n\t\tcatalogAlignment: chunk.alignment,\n\t\tmathAlignments: mathAlignmentsFor(chunk),\n\t\toffsetSpace: chunkOffsetSpaceFor(chunk),\n\t}));\n};\n"]}
@@ -0,0 +1,2 @@
1
+ import type { NormalizedBoundaryEvent, RenderableHighlightTarget, TTSHighlightChunk } from "./types.js";
2
+ export declare const resolveProseBoundaryTarget: (chunk: TTSHighlightChunk, boundary: NormalizedBoundaryEvent) => RenderableHighlightTarget | null;
@@ -0,0 +1,20 @@
1
+ import { resolveVisibleSpanForBoundary } from "../catalog-span-alignment.js";
2
+ import { createRangeFromVisibleMap } from "./visible-map-range.js";
3
+ export const resolveProseBoundaryTarget = (chunk, boundary) => {
4
+ if (!chunk.catalogAlignment || boundary.chunkSpokenStart === null)
5
+ return null;
6
+ const visibleSpan = resolveVisibleSpanForBoundary(chunk.catalogAlignment, boundary.chunkSpokenStart);
7
+ if (!visibleSpan)
8
+ return null;
9
+ const range = createRangeFromVisibleMap(chunk.visibleMap, visibleSpan.start, visibleSpan.end);
10
+ if (!range)
11
+ return null;
12
+ return {
13
+ type: "range",
14
+ quality: chunk.catalogAlignment.playbackMode === "exact-word"
15
+ ? "exact-word"
16
+ : "semantic-token",
17
+ range,
18
+ };
19
+ };
20
+ //# sourceMappingURL=prose-boundary-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prose-boundary-resolver.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/prose-boundary-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACzC,KAAwB,EACxB,QAAiC,EACE,EAAE;IACrC,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,QAAQ,CAAC,gBAAgB,KAAK,IAAI;QAChE,OAAO,IAAI,CAAC;IACb,MAAM,WAAW,GAAG,6BAA6B,CAChD,KAAK,CAAC,gBAAgB,EACtB,QAAQ,CAAC,gBAAgB,CACzB,CAAC;IACF,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,KAAK,GAAG,yBAAyB,CACtC,KAAK,CAAC,UAAU,EAChB,WAAW,CAAC,KAAK,EACjB,WAAW,CAAC,GAAG,CACf,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO;QACN,IAAI,EAAE,OAAO;QACb,OAAO,EACN,KAAK,CAAC,gBAAgB,CAAC,YAAY,KAAK,YAAY;YACnD,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,gBAAgB;QACpB,KAAK;KACL,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { resolveVisibleSpanForBoundary } from \"../catalog-span-alignment.js\";\nimport { createRangeFromVisibleMap } from \"./visible-map-range.js\";\nimport type {\n\tNormalizedBoundaryEvent,\n\tRenderableHighlightTarget,\n\tTTSHighlightChunk,\n} from \"./types.js\";\n\nexport const resolveProseBoundaryTarget = (\n\tchunk: TTSHighlightChunk,\n\tboundary: NormalizedBoundaryEvent,\n): RenderableHighlightTarget | null => {\n\tif (!chunk.catalogAlignment || boundary.chunkSpokenStart === null)\n\t\treturn null;\n\tconst visibleSpan = resolveVisibleSpanForBoundary(\n\t\tchunk.catalogAlignment,\n\t\tboundary.chunkSpokenStart,\n\t);\n\tif (!visibleSpan) return null;\n\tconst range = createRangeFromVisibleMap(\n\t\tchunk.visibleMap,\n\t\tvisibleSpan.start,\n\t\tvisibleSpan.end,\n\t);\n\tif (!range) return null;\n\treturn {\n\t\ttype: \"range\",\n\t\tquality:\n\t\t\tchunk.catalogAlignment.playbackMode === \"exact-word\"\n\t\t\t\t? \"exact-word\"\n\t\t\t\t: \"semantic-token\",\n\t\trange,\n\t};\n};\n"]}
@@ -0,0 +1 @@
1
+ export declare const resolveReadableRegion: (sourceElement: Element, contentRoot: Element) => Element;
@@ -0,0 +1,19 @@
1
+ const READABLE_REGION_SELECTOR = [
2
+ "[data-pie-tts-region]",
3
+ "[data-catalog-region]",
4
+ "li",
5
+ "p",
6
+ "label",
7
+ "section",
8
+ "[role='group']",
9
+ "[role='region']",
10
+ "div",
11
+ ].join(",");
12
+ export const resolveReadableRegion = (sourceElement, contentRoot) => {
13
+ const region = sourceElement.closest(READABLE_REGION_SELECTOR);
14
+ if (region && contentRoot.contains(region)) {
15
+ return region;
16
+ }
17
+ return sourceElement;
18
+ };
19
+ //# sourceMappingURL=readable-region.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readable-region.js","sourceRoot":"","sources":["../../../../src/services/tts/highlight-pipeline/readable-region.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG;IAChC,uBAAuB;IACvB,uBAAuB;IACvB,IAAI;IACJ,GAAG;IACH,OAAO;IACP,SAAS;IACT,gBAAgB;IAChB,iBAAiB;IACjB,KAAK;CACL,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,aAAsB,EACtB,WAAoB,EACV,EAAE;IACZ,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC/D,IAAI,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC,CAAC","sourcesContent":["const READABLE_REGION_SELECTOR = [\n\t\"[data-pie-tts-region]\",\n\t\"[data-catalog-region]\",\n\t\"li\",\n\t\"p\",\n\t\"label\",\n\t\"section\",\n\t\"[role='group']\",\n\t\"[role='region']\",\n\t\"div\",\n].join(\",\");\n\nexport const resolveReadableRegion = (\n\tsourceElement: Element,\n\tcontentRoot: Element,\n): Element => {\n\tconst region = sourceElement.closest(READABLE_REGION_SELECTOR);\n\tif (region && contentRoot.contains(region)) {\n\t\treturn region;\n\t}\n\treturn sourceElement;\n};\n"]}
@@ -0,0 +1,6 @@
1
+ import type { SemanticHighlightTarget, RenderableHighlightTarget } from "./types.js";
2
+ export type MathHighlightCapability = "token" | "expression";
3
+ export declare const classifyMathHighlightCapability: (mathElement: Element) => MathHighlightCapability;
4
+ export type RenderedMathTargetResolver = (target: SemanticHighlightTarget) => RenderableHighlightTarget | null;
5
+ export declare const resolveRenderedMathTarget: RenderedMathTargetResolver;
6
+ export declare const createRenderedMathTargetResolver: () => RenderedMathTargetResolver;