@pie-players/pie-assessment-toolkit 0.3.52 → 0.3.53

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.
@@ -23911,6 +23911,7 @@ class TTSService {
23911
23911
  currentBoundaryOffset = 0;
23912
23912
  activeWordBoundaryOffset = 0;
23913
23913
  seekSegments = [];
23914
+ playbackChunks = [];
23914
23915
  sentenceHighlightSegments = [];
23915
23916
  currentSeekSegmentIndex = 0;
23916
23917
  activeSentenceStartOffset = null;
@@ -24409,6 +24410,20 @@ class TTSService {
24409
24410
  const structuralBoundaries = args.playbackSegments.map((segment) => segment.startOffset).filter((offset) => offset > 0);
24410
24411
  return this.splitSegmentsAtBoundaries(grammaticalSegments, structuralBoundaries, args.contentToSpeak);
24411
24412
  }
24413
+ createSeekSegmentsFromSpeechChunks(chunks) {
24414
+ let offset = 0;
24415
+ return chunks.map((chunk) => {
24416
+ const speechText = chunk.plainFallback?.speechText || (this.hasExplicitBreakSemantics(chunk.speechText) ? chunk.visibleText : chunk.speechText) || chunk.visibleText;
24417
+ const text2 = normalizeTextForSpeech(speechText) || chunk.visibleText || "";
24418
+ const segment = {
24419
+ text: text2,
24420
+ startOffset: offset,
24421
+ pauseMsAfter: 0
24422
+ };
24423
+ offset += Math.max(1, text2.length + 1);
24424
+ return segment;
24425
+ });
24426
+ }
24412
24427
  getCurrentSeekSegmentIndex() {
24413
24428
  if (this.seekSegments.length === 0)
24414
24429
  return 0;
@@ -24572,7 +24587,8 @@ class TTSService {
24572
24587
  this.activeWordBoundaryOffset = options?.wordBoundaryOffset || 0;
24573
24588
  const hasExplicitBreaks = this.hasExplicitBreakSemantics(contentToSpeak);
24574
24589
  const shouldUsePlan = !!this.currentContentElement && !usedCatalogSpoken && !hasExplicitBreaks && speechMatchesVisibleText;
24575
- this.seekSegments = hasExplicitBreaks || !speechMatchesVisibleText ? [] : shouldUsePlan && this.currentContentElement ? this.createSpeechPlan(this.currentContentElement, normalizedText) : this.createSeekSegmentsFromText(highlightText);
24590
+ this.playbackChunks = speechChunks?.length ? speechChunks : [];
24591
+ this.seekSegments = this.playbackChunks.length ? this.createSeekSegmentsFromSpeechChunks(this.playbackChunks) : hasExplicitBreaks || !speechMatchesVisibleText ? [] : shouldUsePlan && this.currentContentElement ? this.createSpeechPlan(this.currentContentElement, normalizedText) : this.createSeekSegmentsFromText(highlightText);
24576
24592
  this.sentenceHighlightSegments = hasExplicitBreaks ? [] : this.createSentenceHighlightSegments({
24577
24593
  contentToSpeak: highlightText,
24578
24594
  shouldUsePlan,
@@ -24929,6 +24945,7 @@ class TTSService {
24929
24945
  this.currentContentElement = options?.contentElement || null;
24930
24946
  this.lastError = null;
24931
24947
  this.currentBoundaryOffset = 0;
24948
+ this.playbackChunks = [];
24932
24949
  this.currentSeekSegmentIndex = 0;
24933
24950
  this.activeSentenceStartOffset = null;
24934
24951
  }
@@ -25138,9 +25155,15 @@ class TTSService {
25138
25155
  }
25139
25156
  async executeSpeakPlayback(args) {
25140
25157
  if (args.speechChunks?.length && this.provider) {
25141
- for (const chunk of args.speechChunks) {
25158
+ for (let index2 = 0;index2 < args.speechChunks.length; index2++) {
25142
25159
  if (args.runId !== this.speakRunId)
25143
25160
  return;
25161
+ this.currentSeekSegmentIndex = index2;
25162
+ const segment = this.seekSegments[index2];
25163
+ if (segment) {
25164
+ this.currentBoundaryOffset = segment.startOffset;
25165
+ }
25166
+ const chunk = args.speechChunks[index2];
25144
25167
  await this.speakCatalogChunk(chunk, args.runId);
25145
25168
  }
25146
25169
  return;
@@ -25170,6 +25193,7 @@ class TTSService {
25170
25193
  this.currentBoundaryOffset = 0;
25171
25194
  this.activeWordBoundaryOffset = 0;
25172
25195
  this.seekSegments = [];
25196
+ this.playbackChunks = [];
25173
25197
  this.sentenceHighlightSegments = [];
25174
25198
  this.currentSeekSegmentIndex = 0;
25175
25199
  this.activeSentenceStartOffset = null;
@@ -25232,6 +25256,7 @@ class TTSService {
25232
25256
  if (!this.provider || this.seekSegments.length === 0)
25233
25257
  return;
25234
25258
  const safeTargetIndex = Math.max(0, Math.min(this.seekSegments.length - 1, targetIndex));
25259
+ const restartChunks = this.playbackChunks.length ? this.playbackChunks.slice(safeTargetIndex) : null;
25235
25260
  this.speakRunId += 1;
25236
25261
  this.provider.onWordBoundary = undefined;
25237
25262
  this.provider.stop();
@@ -25244,9 +25269,23 @@ class TTSService {
25244
25269
  highlightMode: this.activeHighlightMode,
25245
25270
  wordBoundaryOffset: this.activeWordBoundaryOffset
25246
25271
  });
25247
- await this.speakWithPlan(restartSegments, runId, {
25248
- highlightMode: this.activeHighlightMode
25249
- });
25272
+ if (restartChunks) {
25273
+ for (let index2 = 0;index2 < restartChunks.length; index2++) {
25274
+ if (runId !== this.speakRunId)
25275
+ return;
25276
+ const absoluteIndex = safeTargetIndex + index2;
25277
+ this.currentSeekSegmentIndex = absoluteIndex;
25278
+ const segment = this.seekSegments[absoluteIndex];
25279
+ if (segment) {
25280
+ this.currentBoundaryOffset = segment.startOffset;
25281
+ }
25282
+ await this.speakCatalogChunk(restartChunks[index2], runId);
25283
+ }
25284
+ } else {
25285
+ await this.speakWithPlan(restartSegments, runId, {
25286
+ highlightMode: this.activeHighlightMode
25287
+ });
25288
+ }
25250
25289
  if (runId !== this.speakRunId)
25251
25290
  return;
25252
25291
  this.setState(PlaybackState.IDLE);
@@ -25315,6 +25354,7 @@ class TTSService {
25315
25354
  this.currentBoundaryOffset = 0;
25316
25355
  this.activeWordBoundaryOffset = 0;
25317
25356
  this.seekSegments = [];
25357
+ this.playbackChunks = [];
25318
25358
  this.sentenceHighlightSegments = [];
25319
25359
  this.currentSeekSegmentIndex = 0;
25320
25360
  this.activeSentenceStartOffset = null;
@@ -63,6 +63,7 @@ export declare class TTSService {
63
63
  private currentBoundaryOffset;
64
64
  private activeWordBoundaryOffset;
65
65
  private seekSegments;
66
+ private playbackChunks;
66
67
  private sentenceHighlightSegments;
67
68
  private currentSeekSegmentIndex;
68
69
  private activeSentenceStartOffset;
@@ -142,6 +143,7 @@ export declare class TTSService {
142
143
  private createSeekSegmentsFromText;
143
144
  private splitSegmentsAtBoundaries;
144
145
  private createSentenceHighlightSegments;
146
+ private createSeekSegmentsFromSpeechChunks;
145
147
  private getCurrentSeekSegmentIndex;
146
148
  private speakWithPlan;
147
149
  private highlightSentenceSegment;
@@ -87,6 +87,7 @@ export class TTSService {
87
87
  currentBoundaryOffset = 0;
88
88
  activeWordBoundaryOffset = 0;
89
89
  seekSegments = [];
90
+ playbackChunks = [];
90
91
  sentenceHighlightSegments = [];
91
92
  currentSeekSegmentIndex = 0;
92
93
  activeSentenceStartOffset = null;
@@ -705,6 +706,24 @@ export class TTSService {
705
706
  .filter((offset) => offset > 0);
706
707
  return this.splitSegmentsAtBoundaries(grammaticalSegments, structuralBoundaries, args.contentToSpeak);
707
708
  }
709
+ createSeekSegmentsFromSpeechChunks(chunks) {
710
+ let offset = 0;
711
+ return chunks.map((chunk) => {
712
+ const speechText = chunk.plainFallback?.speechText ||
713
+ (this.hasExplicitBreakSemantics(chunk.speechText)
714
+ ? chunk.visibleText
715
+ : chunk.speechText) ||
716
+ chunk.visibleText;
717
+ const text = normalizeTextForSpeech(speechText) || chunk.visibleText || "";
718
+ const segment = {
719
+ text,
720
+ startOffset: offset,
721
+ pauseMsAfter: 0,
722
+ };
723
+ offset += Math.max(1, text.length + 1);
724
+ return segment;
725
+ });
726
+ }
708
727
  getCurrentSeekSegmentIndex() {
709
728
  if (this.seekSegments.length === 0)
710
729
  return 0;
@@ -894,8 +913,10 @@ export class TTSService {
894
913
  !usedCatalogSpoken &&
895
914
  !hasExplicitBreaks &&
896
915
  speechMatchesVisibleText;
897
- this.seekSegments =
898
- hasExplicitBreaks || !speechMatchesVisibleText
916
+ this.playbackChunks = speechChunks?.length ? speechChunks : [];
917
+ this.seekSegments = this.playbackChunks.length
918
+ ? this.createSeekSegmentsFromSpeechChunks(this.playbackChunks)
919
+ : hasExplicitBreaks || !speechMatchesVisibleText
899
920
  ? []
900
921
  : shouldUsePlan && this.currentContentElement
901
922
  ? this.createSpeechPlan(this.currentContentElement, normalizedText)
@@ -1306,6 +1327,7 @@ export class TTSService {
1306
1327
  this.currentContentElement = options?.contentElement || null;
1307
1328
  this.lastError = null;
1308
1329
  this.currentBoundaryOffset = 0;
1330
+ this.playbackChunks = [];
1309
1331
  this.currentSeekSegmentIndex = 0;
1310
1332
  this.activeSentenceStartOffset = null;
1311
1333
  }
@@ -1579,9 +1601,15 @@ export class TTSService {
1579
1601
  }
1580
1602
  async executeSpeakPlayback(args) {
1581
1603
  if (args.speechChunks?.length && this.provider) {
1582
- for (const chunk of args.speechChunks) {
1604
+ for (let index = 0; index < args.speechChunks.length; index++) {
1583
1605
  if (args.runId !== this.speakRunId)
1584
1606
  return;
1607
+ this.currentSeekSegmentIndex = index;
1608
+ const segment = this.seekSegments[index];
1609
+ if (segment) {
1610
+ this.currentBoundaryOffset = segment.startOffset;
1611
+ }
1612
+ const chunk = args.speechChunks[index];
1585
1613
  await this.speakCatalogChunk(chunk, args.runId);
1586
1614
  }
1587
1615
  return;
@@ -1612,6 +1640,7 @@ export class TTSService {
1612
1640
  this.currentBoundaryOffset = 0;
1613
1641
  this.activeWordBoundaryOffset = 0;
1614
1642
  this.seekSegments = [];
1643
+ this.playbackChunks = [];
1615
1644
  this.sentenceHighlightSegments = [];
1616
1645
  this.currentSeekSegmentIndex = 0;
1617
1646
  this.activeSentenceStartOffset = null;
@@ -1696,6 +1725,9 @@ export class TTSService {
1696
1725
  if (!this.provider || this.seekSegments.length === 0)
1697
1726
  return;
1698
1727
  const safeTargetIndex = Math.max(0, Math.min(this.seekSegments.length - 1, targetIndex));
1728
+ const restartChunks = this.playbackChunks.length
1729
+ ? this.playbackChunks.slice(safeTargetIndex)
1730
+ : null;
1699
1731
  this.speakRunId += 1;
1700
1732
  this.provider.onWordBoundary = undefined;
1701
1733
  this.provider.stop();
@@ -1708,9 +1740,24 @@ export class TTSService {
1708
1740
  highlightMode: this.activeHighlightMode,
1709
1741
  wordBoundaryOffset: this.activeWordBoundaryOffset,
1710
1742
  });
1711
- await this.speakWithPlan(restartSegments, runId, {
1712
- highlightMode: this.activeHighlightMode,
1713
- });
1743
+ if (restartChunks) {
1744
+ for (let index = 0; index < restartChunks.length; index++) {
1745
+ if (runId !== this.speakRunId)
1746
+ return;
1747
+ const absoluteIndex = safeTargetIndex + index;
1748
+ this.currentSeekSegmentIndex = absoluteIndex;
1749
+ const segment = this.seekSegments[absoluteIndex];
1750
+ if (segment) {
1751
+ this.currentBoundaryOffset = segment.startOffset;
1752
+ }
1753
+ await this.speakCatalogChunk(restartChunks[index], runId);
1754
+ }
1755
+ }
1756
+ else {
1757
+ await this.speakWithPlan(restartSegments, runId, {
1758
+ highlightMode: this.activeHighlightMode,
1759
+ });
1760
+ }
1714
1761
  if (runId !== this.speakRunId)
1715
1762
  return;
1716
1763
  this.setState(PlaybackState.IDLE);
@@ -1789,6 +1836,7 @@ export class TTSService {
1789
1836
  this.currentBoundaryOffset = 0;
1790
1837
  this.activeWordBoundaryOffset = 0;
1791
1838
  this.seekSegments = [];
1839
+ this.playbackChunks = [];
1792
1840
  this.sentenceHighlightSegments = [];
1793
1841
  this.currentSeekSegmentIndex = 0;
1794
1842
  this.activeSentenceStartOffset = null;
@@ -1 +1 @@
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 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 } = this.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 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.seekSegments =\n\t\t\t\thasExplicitBreaks || !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.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 (const chunk of args.speechChunks) {\n\t\t\t\tif (args.runId !== this.speakRunId) return;\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.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\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\tawait this.speakWithPlan(restartSegments, runId, {\n\t\t\t\thighlightMode: this.activeHighlightMode,\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.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
+ {"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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-players/pie-assessment-toolkit",
3
- "version": "0.3.52",
3
+ "version": "0.3.53",
4
4
  "type": "module",
5
5
  "description": "PIE assessment toolkit: composable services + reference implementation for assessment players and tool coordination",
6
6
  "license": "MIT",
@@ -75,15 +75,15 @@
75
75
  "test": "bun test"
76
76
  },
77
77
  "dependencies": {
78
- "@pie-players/pie-calculator": "0.3.52",
79
- "@pie-players/pie-context": "0.3.52",
80
- "@pie-players/pie-players-shared": "0.3.52",
81
- "@pie-players/pie-tts": "0.3.52",
78
+ "@pie-players/pie-calculator": "0.3.53",
79
+ "@pie-players/pie-context": "0.3.53",
80
+ "@pie-players/pie-players-shared": "0.3.53",
81
+ "@pie-players/pie-tts": "0.3.53",
82
82
  "speech-rule-engine": "^5.0.0-rc.1"
83
83
  },
84
84
  "peerDependencies": {
85
- "@pie-players/pie-calculator-desmos": "0.3.52",
86
- "@pie-players/tts-client-server": "0.3.52"
85
+ "@pie-players/pie-calculator-desmos": "0.3.53",
86
+ "@pie-players/tts-client-server": "0.3.53"
87
87
  },
88
88
  "peerDependenciesMeta": {
89
89
  "@pie-players/pie-calculator-desmos": {