@pie-players/pie-assessment-toolkit 0.3.73 → 0.3.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +171 -56
  2. package/dist/attempt/AssessmentSession.d.ts +1 -5
  3. package/dist/attempt/AssessmentSession.js +0 -29
  4. package/dist/components/ItemToolBar.custom-element.d.ts +1 -0
  5. package/dist/components/ItemToolBar.custom-element.js +1 -1
  6. package/dist/components/PieAssessmentToolkit.custom-element.d.ts +1 -0
  7. package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
  8. package/dist/components/SectionToolBar.custom-element.d.ts +1 -0
  9. package/dist/components/SectionToolBar.custom-element.js +1 -1
  10. package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +40 -0
  11. package/dist/components/chunks/ItemToolBar-gmrryv2v.js +2 -0
  12. package/dist/components/chunks/ItemToolBar-h4xap0t0.js +4 -0
  13. package/dist/components/chunks/ItemToolBar-wr2myaah.js +2 -0
  14. package/dist/components/chunks/sre-engine-wf9s43gg.js +1 -0
  15. package/dist/context/assessment-toolkit-context.d.ts +5 -0
  16. package/dist/context/runtime-context-consumer.js +5 -38
  17. package/dist/index.d.ts +6 -6
  18. package/dist/index.js +8 -9
  19. package/dist/policy/core/ToolPolicyEngine.d.ts +8 -2
  20. package/dist/policy/core/ToolPolicyEngine.js +12 -0
  21. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +3 -3
  22. package/dist/runtime/adapter/SectionEngineAdapter.js +3 -3
  23. package/dist/runtime/registration-events.d.ts +3 -0
  24. package/dist/runtime/section-runtime-engine-host-context.d.ts +3 -9
  25. package/dist/runtime/section-runtime-engine-host-context.js +5 -43
  26. package/dist/runtime/tool-host-contract.d.ts +20 -0
  27. package/dist/runtime/tool-host-contract.js +21 -0
  28. package/dist/services/HighlightCoordinator.d.ts +1 -7
  29. package/dist/services/HighlightCoordinator.js +1 -3
  30. package/dist/services/TTSService.d.ts +15 -1
  31. package/dist/services/TTSService.js +88 -35
  32. package/dist/services/ToolCoordinator.d.ts +1 -7
  33. package/dist/services/ToolCoordinator.js +1 -3
  34. package/dist/services/ToolRegistry.d.ts +13 -6
  35. package/dist/services/ToolRegistry.js +19 -7
  36. package/dist/services/ToolkitCoordinator.d.ts +110 -18
  37. package/dist/services/ToolkitCoordinator.js +273 -85
  38. package/dist/services/catalog-owner.d.ts +11 -0
  39. package/dist/services/catalog-owner.js +25 -0
  40. package/dist/services/create-tools-config.d.ts +2 -2
  41. package/dist/services/framework-error.d.ts +8 -1
  42. package/dist/services/interfaces.d.ts +9 -9
  43. package/dist/services/pnp-standard-features.d.ts +1 -1
  44. package/dist/services/section-controller-types.d.ts +15 -0
  45. package/dist/services/spoken-audio-cards.js +1 -1
  46. package/dist/services/tool-config-validation.d.ts +13 -2
  47. package/dist/services/tool-config-validation.js +33 -16
  48. package/dist/services/tool-context.js +29 -13
  49. package/dist/services/tool-providers/TTSToolProvider.d.ts +27 -65
  50. package/dist/services/tool-providers/TTSToolProvider.js +47 -9
  51. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +4 -4
  52. package/dist/services/tool-providers/ToolProviderRegistry.js +4 -16
  53. package/dist/services/tool-providers/index.d.ts +0 -9
  54. package/dist/services/tool-providers/index.js +2 -4
  55. package/dist/services/tools-config-normalizer.d.ts +20 -1
  56. package/dist/services/tts/catalog-span-alignment.d.ts +2 -17
  57. package/dist/services/tts/catalog-span-alignment.js +17 -142
  58. package/dist/services/tts/generated-speech/types.d.ts +0 -12
  59. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +12 -62
  60. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +26 -1
  61. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +3 -6
  62. package/dist/services/tts/math-alignment/index.d.ts +0 -5
  63. package/dist/services/tts/math-alignment/index.js +5 -25
  64. package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +9 -1
  65. package/dist/services/tts/math-alignment/speech-tokenizer.js +38 -36
  66. package/dist/services/tts/math-alignment/types.d.ts +4 -2
  67. package/dist/services/tts/math-aware-text-processing.js +44 -2
  68. package/dist/services/tts/math-speech.d.ts +5 -1
  69. package/dist/services/tts/math-speech.js +9 -6
  70. package/dist/services/tts/sre-engine.d.ts +7 -0
  71. package/dist/services/tts/sre-engine.js +11 -0
  72. package/dist/services/tts/sre-locales.d.ts +14 -0
  73. package/dist/services/tts/sre-locales.js +57 -0
  74. package/dist/services/tts/text-processing.d.ts +0 -1
  75. package/dist/services/tts/text-processing.js +0 -1
  76. package/dist/services/tts-runtime-config.d.ts +21 -3
  77. package/dist/services/tts-runtime-config.js +11 -3
  78. package/dist/tools/client.d.ts +1 -3
  79. package/dist/tools/client.js +1 -5
  80. package/dist/tools/internal.d.ts +6 -5
  81. package/dist/tools/internal.js +6 -8
  82. package/package.json +17 -36
  83. package/dist/components/chunks/ItemToolBar-byq80z42.js +0 -40
  84. package/dist/components/chunks/ItemToolBar-d36g3aw4.js +0 -49
  85. package/dist/services/ToolConfigResolver.d.ts +0 -161
  86. package/dist/services/ToolConfigResolver.js +0 -229
  87. package/dist/services/catalog-media.d.ts +0 -56
  88. package/dist/services/catalog-media.js +0 -190
  89. package/dist/services/createDefaultToolRegistry.d.ts +0 -53
  90. package/dist/services/createDefaultToolRegistry.js +0 -45
  91. package/dist/services/tool-providers/CortexToolProvider.d.ts +0 -13
  92. package/dist/services/tool-providers/CortexToolProvider.js +0 -32
  93. package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -14
  94. package/dist/services/tool-providers/DesmosToolProvider.js +0 -32
  95. package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +0 -16
  96. package/dist/services/tool-providers/GeoGebraToolProvider.js +0 -32
  97. package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +0 -35
  98. package/dist/services/tool-providers/LazyCalculatorToolProvider.js +0 -95
  99. package/dist/services/tts/visual-line-ranges.d.ts +0 -18
  100. package/dist/services/tts/visual-line-ranges.js +0 -226
  101. package/dist/tools/index.d.ts +0 -8
  102. package/dist/tools/index.js +0 -10
  103. package/dist/tools/response-discovery.d.ts +0 -61
  104. package/dist/tools/response-discovery.js +0 -113
  105. package/dist/tools/types.d.ts +0 -337
  106. package/dist/tools/types.js +0 -12
  107. package/dist/tools/variant-resolver.d.ts +0 -41
  108. package/dist/tools/variant-resolver.js +0 -207
@@ -1,8 +1,8 @@
1
- import{C as L3,D as w3,I as R3,J as x,K as E3,L as b3,M as m8,O as S3,Q as L7,R as T3,S as b7,T as S8,b as xG,c as A3,d as N3,e as F3,f as r,g as y,h,i as w,j as v8,k as M3,l as h8,m as b1,n as S1,o as b,p as z3,q as V,r as m,u as u8,v as O3,w as T1,x as C1,y as P3}from"./chunks/ItemToolBar-d36g3aw4.js";import{ContextProvider as H3,ContextRoot as D3,requestContext as iQ}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as sQ,createStageTracker as nQ,resolveInstrumentationProvider as rQ,TOOLKIT_INSTRUMENTATION_EVENT_MAP as oQ}from"@pie-players/pie-players-shared/pie";import{isInstrumentationProvider as aQ}from"@pie-players/pie-players-shared";import{createPieI18n as tQ,DEFAULT_LOCALE as eQ}from"@pie-players/pie-players-shared/i18n";function Z1(G){return{kind:G.kind,severity:G.severity??"error",source:G.source,message:G.message,details:[...G.details||[]],recoverable:G.recoverable===!0,cause:G.cause}}function j1(G){let Q=G.error instanceof Error&&G.error.message.trim().length>0?G.error.message:String(G.error||"Unknown framework error");return Z1({kind:G.kind,source:G.source,message:Q,recoverable:G.recoverable,cause:G.error})}var D5={"coordinator-ready":"coordinator-init","state-load":"tool-state-load","state-save":"tool-state-save","provider-register":"provider-register","provider-init":"provider-init","tts-init":"tts-init","section-controller-init":"section-controller-init","section-controller-dispose":"section-controller-dispose"};function X6(G){let Q=D5[G.context.phase],Y=G.context.providerId?`pie-toolkit-coordinator/${G.context.providerId}`:`pie-toolkit-coordinator:${G.context.phase}`;return j1({kind:Q,source:Y,error:G.error,recoverable:G.recoverable})}function Z6(G){let Q=`[pie-framework:${G.kind}:${G.source}]`;if(G.details.length===0)return`${Q} ${G.message}`;return`${Q} ${G.message}
2
- - ${G.details.join(`
3
- - `)}`}var A5="error";function i1(G){if(G==="off"||G==="warn"||G==="error")return G;return A5}function c(G){return G}function N5(G){if(!G)return new Map;return new Map(G.getAllTools().slice().sort((Q,Y)=>Q.toolId.localeCompare(Y.toolId)).map((Q)=>[Q.toolId,Q]))}function F5(G,Q,Y,J){if(!Q||!Y?.provider?.sanitizeConfig)return Q;try{let X=Y.provider.sanitizeConfig(Q);if(!X||typeof X!=="object"||Array.isArray(X))return J.push(c({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${G}`,message:`Provider sanitizer for "${G}" must return an object.`,providerId:G,toolId:G})),Q;return X}catch(X){return J.push(c({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${G}`,message:`Provider sanitizer failed for "${G}": ${X instanceof Error?X.message:String(X)}`,providerId:G,toolId:G})),Q}}function M5(G,Q,Y,J){if(!Q||!Y?.provider?.validateConfig)return;try{let X=Y.provider.validateConfig(Q);if(!Array.isArray(X)){J.push(c({code:"tools.invalidProviderValidation",severity:"error",path:`providers.${G}`,message:`Provider validator for "${G}" must return an array.`,providerId:G,toolId:G}));return}for(let j of X)J.push({...j,path:j.path||`providers.${G}`,providerId:j.providerId||G,toolId:j.toolId||G})}catch(X){J.push(c({code:"tools.providerValidateFailed",severity:"error",path:`providers.${G}`,message:`Provider validator failed for "${G}": ${X instanceof Error?X.message:String(X)}`,providerId:G,toolId:G}))}}function z5(G,Q,Y){if(Q.size===0)return;let J=["section","item","passage"];for(let X of J)for(let j of G.placement[X]){let Z=Q.get(j);if(!Z){Y.push(c({code:"tools.unknownToolId",severity:"error",path:`placement.${X}`,message:`Unknown tool id "${j}" in placement.${X}.`,toolId:j}));continue}if(Z.activation==="region"){Y.push(c({code:"tools.unplaceableActivation",severity:"error",path:`placement.${X}`,message:`Tool "${j}" renders into a host surface (activation "region") and cannot be placed on the ${X} toolbar. Remove it from placement.${X}; its availability comes from policy plus its content dependency.`,toolId:j}));continue}let q=Z.supportedLevels.includes(X),B=X==="item"&&Z.supportedLevels.includes("section");if(!q&&!B)Y.push(c({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${j}" does not support level "${X}".`,toolId:j}))}}function O5(G,Q,Y){if(Q.size===0)return;for(let J of G.policy.allowed||[]){if(Q.has(J))continue;Y.push(c({code:"tools.unknownToolId",severity:"error",path:"policy.allowed",message:`Unknown tool id "${J}" in policy.allowed.`,toolId:J}))}for(let J of G.policy.blocked||[]){if(Q.has(J))continue;Y.push(c({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${J}" in policy.blocked.`,toolId:J}))}}function P5(G,Q,Y,J){if(Y)J.push(c({code:"tools.removedProviderKey",severity:"error",path:"providers.tts",message:'Provider key "tts" is no longer supported. Use "providers.textToSpeech".',providerId:"tts",toolId:"textToSpeech"}));for(let X of Object.keys(G.providers).sort()){if(Q.size===0||Q.has(X))continue;J.push(c({code:"tools.unknownProviderKey",severity:"error",path:`providers.${X}`,message:`Unknown provider key "${X}".`,providerId:X,toolId:X}))}}function j6(G,Q){if(G.length===0)return;for(let Y of G){let J=`[tool-config-validation:${Q}]`;console.warn(`${J} ${Y.path} - ${Y.message}`)}}function q6(G,Q){let Y=G.map((J)=>`- ${J.path}: ${J.message}`).join(`
4
- `);throw Error(`[tool-config-validation:${Q}] Invalid tools config:
5
- ${Y}`)}function Z7(G,Q={}){let Y=i1(Q.strictness),J=Q.source??"tools",X=N5(Q.toolRegistry),j=b7(G),Z=[],q=Object.values(j.placement).some((H)=>H.length>0)||Object.keys(j.providers).length>0||(j.policy.allowed?.length??0)>0||(j.policy.blocked?.length??0)>0;if(X.size===0&&q)Z.push(c({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated. Pass `toolRegistry` — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let B=Object.hasOwn(j.providers,"tts"),K={...j.providers||{}};for(let H of Object.keys(K).sort()){if(H==="tts"){delete K.tts;continue}let N=X.get(H);K[H]=F5(H,K[H],N,Z),M5(H,K[H],N,Z)}let W={...j,providers:K};if(z5(W,X,Z),O5(W,X,Z),P5(W,X,B,Z),B)q6(Z.filter((H)=>H.code==="tools.removedProviderKey"),J);if(Y==="warn")j6(Z,J);let $=Z.filter((H)=>H.severity==="error");if(Y==="error"&&$.length>0)q6($,J);if(Y==="error"&&$.length===0)j6(Z,J);return{config:W,diagnostics:Z}}import{languageTagLookupSequence as b5,normalizeLanguageTag as _6}from"@pie-players/pie-players-shared/i18n/language-tags";var s1=(G)=>Array.isArray(G)&&G.length>0;function n1(G){if(G.kind==="passage")return{ownerKind:"passage",assessmentId:G.assessmentId,sectionId:G.sectionId,passageId:G.canonicalItemId||G.itemId};return{ownerKind:"itemModel",assessmentId:G.assessmentId,sectionId:G.sectionId,itemId:G.itemId,canonicalItemId:G.canonicalItemId||G.itemId}}function U6(G,Q){if(!G)return[];let Y=n1(Q),J=[];if(s1(G.accessibilityCatalogs))J.push({context:Y,catalogs:G.accessibilityCatalogs});if(s1(G.config?.extractedCatalogs))J.push({context:Y,catalogs:G.config.extractedCatalogs});if(Q.kind==="passage")return J;if(Y.ownerKind!=="itemModel")return J;for(let X of G.config?.models??[]){if(!s1(X.accessibilityCatalogs))continue;J.push({context:{...Y,modelId:X.id},catalogs:X.accessibilityCatalogs})}return J}var a1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),B6=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),W6=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),K6=new Set(["break","mark","lexicon"]);function L5(G){let Q=G;for(let Y of K6){let J=new RegExp(`<${Y}\\b([^>/]*?)\\s*/>`,"gi");Q=Q.replace(J,(X,j)=>{let Z=j?j.replace(/\s+$/,""):"";return`<${Y}${Z}></${Y}>`})}return Q}var w5=[/^localhost$/i,/^127(?:\.\d{1,3}){3}$/,/^0(?:\.\d{1,3}){3}$/,/^10(?:\.\d{1,3}){3}$/,/^192\.168(?:\.\d{1,3}){2}$/,/^172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}$/,/^169\.254(?:\.\d{1,3}){2}$/,/^::1$/,/^fe80:/i,/^fc00:/i,/^fd[0-9a-f]{2}:/i,/^metadata\.google\.internal$/i,/^metadata\.azure\.internal$/i,/^metadata\.packet\.net$/i];function R5(G){if(typeof G!=="string"||G.length===0)return!1;let Q;try{Q=new URL(G)}catch{return!1}if(Q.protocol!=="http:"&&Q.protocol!=="https:")return!1;let Y=Q.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!w5.some((J)=>J.test(Y))}function r1(G){let Q=Array.from(G.children);for(let J of Q){let X=J.tagName.toLowerCase();if(B6.has(X)){J.remove();continue}if(r1(J),!a1.has(X)){let j=G.ownerDocument.createTextNode(J.textContent??"");J.replaceWith(j)}}let Y=Array.from(G.attributes).map((J)=>J.name);for(let J of Y)if(!W6.has(J.toLowerCase()))G.removeAttribute(J);if(G.tagName.toLowerCase()==="audio"){let J=G.getAttribute("src");if(J!==null&&!R5(J))G.removeAttribute("src")}}function o1(G){let Q=G.tagName.toLowerCase(),Y=Array.from(G.attributes).filter((X)=>W6.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${E5(X.value)}"`).join("");if(K6.has(Q))return`<${Q}${Y}/>`;let J=[];for(let X of Array.from(G.childNodes))if(X.nodeType===3)J.push(q1(X.nodeValue??""));else if(X.nodeType===1){let j=X,Z=j.tagName.toLowerCase();if(B6.has(Z))continue;if(a1.has(Z))J.push(o1(j));else J.push(q1(j.textContent??""))}return`<${Q}${Y}>${J.join("")}</${Q}>`}function t1(G){let Q=String(G||"").trim();if(!Q||!Q.includes("<"))return G;if(typeof DOMParser>"u")return G;let J=new DOMParser().parseFromString(L5(Q),"text/html"),X=J.querySelector("speak");if(X)return r1(X),o1(X);let j=J.createElement("speak");for(let Z of Array.from(J.body.childNodes))j.appendChild(Z);return r1(j),Array.from(j.childNodes).map((Z)=>{if(Z.nodeType===3)return q1(Z.nodeValue??"");if(Z.nodeType===1){let q=Z;if(a1.has(q.tagName.toLowerCase()))return o1(q);return q1(q.textContent??"")}return""}).join("")}function q1(G){return G.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function E5(G){return G.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var A6=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),e1="ext:";function V6(G){if(A6.has(G))return!0;return G.startsWith(e1)&&G.length>e1.length}var $6=new Set;function G8(G,Q=new Set){if(G===null||typeof G==="string"||typeof G==="number"||typeof G==="boolean"||typeof G>"u")return G;if(typeof G!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Q.has(G))throw TypeError("catalog cards must not contain cycles");Q.add(G);try{if(Array.isArray(G))return Object.freeze(G.map((X)=>G8(X,Q)));let Y=Object.getPrototypeOf(G);if(Y!==Object.prototype&&Y!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let J={};for(let[X,j]of Object.entries(G))J[X]=G8(j,Q);return Object.freeze(J)}finally{Q.delete(G)}}function H6(G,Q,Y){let J=`${Q}|${G}`;if($6.has(J))return;$6.add(J);let X=`${Array.from(A6).join(", ")}, or an "${e1}" prefixed vendor extension`;if(Q==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${Y}" has a card of unknown type "${G}"; it is stored but no reader asks for that type, so the alternate will never be shown. Expected one of: ${X}.`);return}console.warn(`[AccessibilityCatalogResolver] lookup for unknown catalog type "${G}" on "${Y}" cannot match any card. Expected one of: ${X}.`)}var D6=(G)=>G.payload!==void 0?"payload":"content";class Q8{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(G,Q="en-US"){this.defaultLanguage=Q,this.indexCatalogs(G??[],"assessment")}setDefaultLanguage(G){this.defaultLanguage=G}onCatalogsChange(G){return this.catalogChangeListeners.add(G),()=>{this.catalogChangeListeners.delete(G)}}emitCatalogsChange(G){for(let Q of Array.from(this.catalogChangeListeners))try{Q(G)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(G,Q){let Y=Q==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let J of this.sanitizeCatalogs(G)){if(Y.has(J.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Q} catalog "${J.identifier}" ignored`);continue}Y.set(J.identifier,J)}}insertScopedCatalogs(G,Q){if(!Q||Q.length===0)return null;let Y=this.getOwnerKey(G),J=this.scopedCatalogs.get(Y),X=J?.catalogs??new Map,j=[];for(let Z of this.sanitizeCatalogs(Q)){if(X.has(Z.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${Z.identifier}" ignored for ${Y}`);continue}X.set(Z.identifier,Z),j.push(Z.identifier)}if(!J&&j.length>0)this.scopedCatalogs.set(Y,{context:{...G},catalogs:X});return{key:Y,context:{...G},catalogs:X,insertedIds:j}}removeScopedInsertion(G){let Q=this.scopedCatalogs.get(G.key);if(Q?.catalogs!==G.catalogs)return!1;let Y=!1;for(let J of G.insertedIds)Y=Q.catalogs.delete(J)||Y;if(Q.catalogs.size===0)this.scopedCatalogs.delete(G.key);return Y}registerCatalogs(G,Q){let Y=this.insertScopedCatalogs(G,Q);if(Y&&Y.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:G});let J=!0;return()=>{if(!J)return;if(J=!1,Y&&this.removeScopedInsertion(Y))this.emitCatalogsChange({reason:"scoped-removed",context:G})}}registerOwner(G){let{owner:Q,entity:Y}=G,J=n1(Q),X=[],j=[];try{j=U6(Y,Q)}catch(B){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",B)}for(let B of j)try{let K=this.insertScopedCatalogs(B.context,B.catalogs);if(K)X.push(K)}catch(K){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",K)}if(X.some((B)=>B.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:J});let q=!0;return()=>{if(!q)return;q=!1;let B=!1;for(let K of X)B=this.removeScopedInsertion(K)||B;if(B)this.emitCatalogsChange({reason:"scoped-removed",context:J})}}forOwner(G){let Q={...G};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Q),onChange:(Y)=>this.onCatalogsChange((J)=>{if(this.catalogChangeAffectsOwner(J,Q))Y()})})}addItemCatalogs(G){if(!G||G.length===0)return;this.indexCatalogs(G,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(G){return this.itemCatalogs.has(G)||this.assessmentCatalogs.has(G)||Array.from(this.scopedCatalogs.values()).some((Q)=>Q.catalogs.has(G))}getAlternative(G,Q){if(!V6(Q.type))H6(Q.type,"lookup",G);let Y=Q.context?this.scopedCatalogs.get(this.getOwnerKey(Q.context))?.catalogs.get(G):null;if(Y){let j=this.findMatchingCard(Y,Q);if(j)return this.resolveCard(G,j,"item")}if(Q.context){let j=this.findScopedCandidates(G,Q.context);if(j.length===1){let Z=this.findMatchingCard(j[0],Q);if(Z)return this.resolveCard(G,Z,"item")}else if(j.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${G}" for owner context`,Q.context),null}let J=this.itemCatalogs.get(G);if(J){let j=this.findMatchingCard(J,Q);if(j)return this.resolveCard(G,j,"item")}let X=this.assessmentCatalogs.get(G);if(X){let j=this.findMatchingCard(X,Q);if(j)return this.resolveCard(G,j,"assessment")}return null}resolveCard(G,Q,Y){return{catalogId:G,type:Q.catalog,language:Q.language,content:Q.catalog==="spoken"&&Q.content!==void 0?this.ensureSpokenSanitized(Q.content):Q.content,payload:Q.payload,source:Y}}ensureSpokenSanitized(G){let Q=this.sanitizedSpokenCache.get(G);if(Q!==void 0)return Q;let Y=t1(G);return this.sanitizedSpokenCache.set(G,Y),Y}getOwnerKey(G){return[G.ownerKind,G.assessmentId||"",G.sectionId||"",G.canonicalItemId||"",G.itemId||"",G.passageId||"",G.modelId||""].join("|")}scopedCatalogEntries(){let G=[];for(let Q of this.scopedCatalogs.values())for(let Y of Q.catalogs.entries())G.push(Y);return G}findScopedCandidates(G,Q){return Array.from(this.scopedCatalogs.values()).filter((Y)=>this.isCompatibleOwnerContext(Y.context,Q)).map((Y)=>Y.catalogs.get(G)).filter((Y)=>Boolean(Y))}isCompatibleOwnerContext(G,Q){if(G.ownerKind!==Q.ownerKind)return!1;if(Q.assessmentId&&G.assessmentId!==Q.assessmentId)return!1;if(Q.sectionId&&G.sectionId!==Q.sectionId)return!1;if(Q.canonicalItemId&&G.canonicalItemId!==Q.canonicalItemId)return!1;if(Q.itemId&&G.itemId!==Q.itemId)return!1;if(Q.passageId&&G.passageId!==Q.passageId)return!1;if(Q.modelId&&G.modelId!==Q.modelId)return!1;return!0}ownerScopedCatalogEntries(G){let Q=[],Y=this.scopedCatalogs.get(this.getOwnerKey(G));if(Y)Q.push(...Y.catalogs.entries());for(let J of this.scopedCatalogs.values()){if(J===Y)continue;if(!this.isCompatibleOwnerContext(J.context,G))continue;Q.push(...J.catalogs.entries())}return Q}createOwnerSnapshot(G){let Q=[],Y=this.ownerScopedCatalogEntries(G);if(G.ownerKind==="global")Y.push(...this.assessmentCatalogs.entries());for(let[J,X]of Y)for(let j of X.cards)try{Q.push(Object.freeze({catalogId:J,card:G8(j)}))}catch(Z){let q=`${this.getOwnerKey(G)}\x00${J}`;if(!this.reportedSnapshotProblems.has(q))this.reportedSnapshotProblems.add(q),console.warn(`[AccessibilityCatalogResolver] Catalog "${J}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,Z)}return Object.freeze({cards:Object.freeze(Q)})}catalogChangeAffectsOwner(G,Q){if(!G.context)return!1;if(this.isCompatibleOwnerContext(G.context,Q))return!0;if(Q.ownerKind==="itemModel"&&Q.modelId&&G.context.ownerKind==="itemModel"&&!G.context.modelId)return this.isCompatibleOwnerContext({...G.context,modelId:Q.modelId},Q);return!1}sanitizeCatalogs(G){return G.map((Q)=>({...Q,cards:Q.cards.map((Y)=>{if(!V6(Y.catalog))H6(Y.catalog,"card",Q.identifier);return{...Y,content:Y.catalog==="spoken"&&Y.content!==void 0?t1(Y.content):Y.content}})}))}findMatchingCard(G,Q){let{type:Y,language:J,useFallback:X=!0,form:j}=Q,Z=[],q=(B)=>{for(let K of b5(B))Z.push((W)=>_6(W.language)===K)};if(J)q(J);if(X)q(this.defaultLanguage),Z.push(()=>!0);for(let B of Z){let K=G.cards.filter((W)=>W.catalog===Y&&B(W));if(K.length===0)continue;if(j){let W=K.find(($)=>D6($)===j);if(W)return W}return K[0]}return null}getAllAlternatives(G){let Q=[],Y=new Set,J=(Z,q)=>{let B=`${Z.catalog}|${_6(Z.language)}|${D6(Z)}`;if(Y.has(B))return;Y.add(B),Q.push(this.resolveCard(G,Z,q))},X=this.itemCatalogs.get(G);if(X)for(let Z of X.cards)J(Z,"item");let j=this.assessmentCatalogs.get(G);if(j)for(let Z of j.cards)J(Z,"assessment");for(let[Z,q]of this.scopedCatalogEntries()){if(Z!==G)continue;for(let B of q.cards)J(B,"item")}return Q}getAllCatalogIds(){let G=this.scopedCatalogEntries().map(([Q])=>Q);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...G]))}getStatistics(){let G=new Set,Q=new Set;for(let Y of this.assessmentCatalogs.values())for(let J of Y.cards)if(G.add(J.catalog),J.language)Q.add(J.language);for(let Y of this.itemCatalogs.values())for(let J of Y.cards)if(G.add(J.catalog),J.language)Q.add(J.language);for(let Y of this.scopedCatalogs.values())for(let J of Y.catalogs.values())for(let X of J.cards)if(G.add(X.catalog),X.language)Q.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),availableTypes:G,availableLanguages:Q}}hasAlternativeType(G,Q){return this.getAllAlternatives(G).some((J)=>J.type===Q)}getCatalogsByType(G){let Q=new Set;for(let[Y,J]of this.assessmentCatalogs.entries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);for(let[Y,J]of this.itemCatalogs.entries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);for(let[Y,J]of this.scopedCatalogEntries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);return Array.from(Q)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}class Y8{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(G,Q,Y,J){return`${G}:${Q}:${Y}:${J}`}parseGlobalElementId(G){let Q=G.split(":");if(Q.length!==4)return null;return{assessmentId:Q[0],sectionId:Q[1],itemId:Q[2],elementId:Q[3]}}setState(G,Q,Y){let J=this.elementStates.get(G);if(!J)J=new Map,this.elementStates.set(G,J);J.set(Q,Y),this._notifyListeners(),this._notifyStateChange()}getState(G,Q){return this.elementStates.get(G)?.get(Q)}getElementState(G){let Q=this.elementStates.get(G);if(!Q)return{};return Object.fromEntries(Q.entries())}getAllState(){let G={};for(let[Q,Y]of this.elementStates.entries())G[Q]=Object.fromEntries(Y.entries());return G}subscribe(G){return this.listeners.add(G),()=>this.listeners.delete(G)}_notifyListeners(){for(let G of this.listeners)G(this.elementStates)}setOnStateChange(G){this.onStateChange=G}_notifyStateChange(){if(this.onStateChange)this.onStateChange(this.getAllState())}loadState(G){this.elementStates.clear();for(let[Q,Y]of Object.entries(G)){let J=new Map(Object.entries(Y));this.elementStates.set(Q,J)}this._notifyListeners()}clearElement(G){this.elementStates.delete(G),this._notifyListeners(),this._notifyStateChange()}clearTool(G){for(let Q of this.elementStates.values())Q.delete(G);this._notifyListeners(),this._notifyStateChange()}clearSection(G,Q){let Y=`${G}:${Q}:`,J=[];for(let X of this.elementStates.keys())if(X.startsWith(Y))J.push(X);for(let X of J)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class p7{listeners=new Set;subscribeFrameworkErrors(G){this.listeners.add(G);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(G)}}reportFrameworkError(G){let Q=Array.from(this.listeners);for(let Y of Q)try{Y(G)}catch(J){console.warn("[FrameworkErrorBus] listener failed:",J)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}class J8{serialize(G,Q){return{startContainer:this.getNodePath(G.startContainer,Q),startOffset:G.startOffset,endContainer:this.getNodePath(G.endContainer,Q),endOffset:G.endOffset,text:G.toString()}}deserialize(G,Q){let Y=this.findNodeByPath(G.startContainer,Q),J=this.findNodeByPath(G.endContainer,Q);if(!Y||!J)return null;try{let X=new Range;if(X.setStart(Y,G.startOffset),X.setEnd(J,G.endOffset),X.toString()===G.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(G,Q){if(G===Q)return"";if(G.nodeType===Node.TEXT_NODE){let Y=G.parentElement;if(!Y)throw Error("Text node has no parent");let X=Array.from(Y.childNodes).filter((Z)=>Z.nodeType===Node.TEXT_NODE).indexOf(G);return`${this.getElementPath(Y,Q)}::text[${X}]`}if(G.nodeType===Node.ELEMENT_NODE)return this.getElementPath(G,Q);throw Error(`Unsupported node type: ${G.nodeType}`)}getElementPath(G,Q){if(G===Q)return"";let Y=[],J=G;while(J&&J!==Q){if(J.id){Y.unshift(`#${J.id}`);break}let X=J.parentElement;if(!X)break;let j=Array.from(X.children).filter((B)=>B.tagName===J.tagName),Z=j.indexOf(J),q=j.length>1?`${J.tagName.toLowerCase()}:nth-of-type(${Z+1})`:J.tagName.toLowerCase();Y.unshift(q),J=X}return Y.join(" > ")}findNodeByPath(G,Q){if(G==="")return Q;if(G.includes("::text[")){let[Y,J]=G.split("::text["),X=Number.parseInt(J.replace("]",""),10),j=Y?Q.querySelector(Y):Q;if(!j)return null;return Array.from(j.childNodes).filter((q)=>q.nodeType===Node.TEXT_NODE)[X]||null}try{return Q.querySelector(G)}catch(Y){return console.warn("Invalid selector path:",G,Y),null}}serializeMany(G,Q){return G.map((Y)=>this.serialize(Y,Q))}deserializeMany(G,Q){return G.map((Y)=>this.deserialize(Y,Q))}}var u;(function(G){G.TTS_WORD="tts-word",G.TTS_SENTENCE="tts-sentence",G.ANNOTATION="annotation"})(u||(u={}));var $7;(function(G){G.YELLOW="yellow",G.GREEN="green",G.BLUE="blue",G.PINK="pink",G.ORANGE="orange",G.UNDERLINE="underline"})($7||($7={}));class g7{config;ttsWordHighlight=null;ttsSentenceHighlight=null;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;colorHighlights=new Map;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;explicitTTSColorOverride=null;constructor(G={}){if(this.config=G,this.rangeSerializer=new J8,typeof CSS>"u"||!("highlights"in CSS)){console.warn("CSS Custom Highlight API not supported (SSR or unsupported browser)");return}this.supported=!0,this.initializeHighlights(),this.registerStyles(),this.applyAdaptiveTTSStyle(),this.setupThemeObservation()}setupThemeObservation(){if(typeof document>"u")return;if(typeof MutationObserver>"u")return;let G=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(G),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]});for(let Q of document.querySelectorAll("pie-theme"))this.themeObserver.observe(Q,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(G){if(!G)return null;let Q=G.trim();if(!Q)return null;let Y=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Q);if(Y){let X=Y[1];if(X.length===3)return[parseInt(X[0]+X[0],16),parseInt(X[1]+X[1],16),parseInt(X[2]+X[2],16)];return[parseInt(X.slice(0,2),16),parseInt(X.slice(2,4),16),parseInt(X.slice(4,6),16)]}let J=/^rgba?\((.+)\)$/i.exec(Q);if(J){let j=J[1].replace(/\//g,",").split(/[,\s]+/).map((K)=>K.trim()).filter(Boolean),Z=Number(j[0]),q=Number(j[1]),B=Number(j[2]);if(Number.isFinite(Z)&&Number.isFinite(q)&&Number.isFinite(B))return[Z,q,B]}if(typeof document<"u"){let X=document.createElement("span");if(X.style.color=Q,typeof X.style.color==="string"&&X.style.color){document.body?.appendChild(X);let j=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let Z=j.trim();if(Z&&Z!==Q)return this.parseColor(j)}}return null}relativeLuminance([G,Q,Y]){let J=(q)=>{let B=q/255;return B<=0.03928?B/12.92:((B+0.055)/1.055)**2.4},X=J(G),j=J(Q),Z=J(Y);return 0.2126*X+0.7152*j+0.0722*Z}contrastRatio(G,Q){let Y=this.relativeLuminance(G),J=this.relativeLuminance(Q),X=Math.max(Y,J),j=Math.min(Y,J);return(X+0.05)/(j+0.05)}blend(G,Q,Y){return[Math.round(G[0]*Y+Q[0]*(1-Y)),Math.round(G[1]*Y+Q[1]*(1-Y)),Math.round(G[2]*Y+Q[2]*(1-Y))]}resolveAdaptiveTTSStyle(G){let Q=[255,235,59],Y=[17,24,39],J=[255,255,255],X=G||(typeof document<"u"?document.documentElement:null),j=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,Z=this.parseColor(j?.getPropertyValue("--pie-background")||j?.backgroundColor)||J,q=this.parseColor(j?.getPropertyValue("--pie-text"))||Y,B=this.explicitTTSColorOverride?this.parseColor(this.explicitTTSColorOverride.color)||Q:this.parseColor(j?.getPropertyValue("--pie-missing"))||Q,K=this.explicitTTSColorOverride?[Math.max(0.3,Math.min(0.95,this.explicitTTSColorOverride.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],W=K[K.length-1],$=-1/0;for(let g of K){let q7=this.blend(B,Z,g),U7=this.contrastRatio(q7,Z),B7=this.contrastRatio(q7,q),w7=U7*1.2+B7*0.8;if(U7>=1.25&&B7>=2.4){W=g;break}if(w7>$)$=w7,W=g}let H=Math.max(0.24,Math.min(0.85,W*0.55)),N=Math.max(0.55,Math.min(0.95,W+0.2)),F=Math.max(0.22,Math.min(0.6,W*0.45)),O=q,L=this.blend(O,Z,N),D=this.contrastRatio(L,Z),P=this.relativeLuminance(Z)>0.45?[0,0,0]:[255,255,255],S=D>=1.35?O:P,v=`rgba(${B[0]}, ${B[1]}, ${B[2]}, ${W})`,I=`rgba(${B[0]}, ${B[1]}, ${B[2]}, ${H})`,p=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${N})`,E=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${F})`;return{wordHighlight:v,sentenceHighlight:I,wordUnderline:p,wordShadow:E}}applyAdaptiveTTSStyle(G){if(typeof document>"u")return;let Q=this.resolveAdaptiveTTSStyle(G);document.documentElement.style.setProperty("--pie-tts-word-highlight",Q.wordHighlight),document.documentElement.style.setProperty("--pie-tts-sentence-highlight",Q.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-line-highlight",Q.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-word-underline",Q.wordUnderline),document.documentElement.style.setProperty("--pie-tts-word-shadow",Q.wordShadow)}initializeHighlights(){if(!this.supported)return;this.ttsWordHighlight=new Highlight,this.ttsSentenceHighlight=new Highlight,CSS.highlights.set("tts-word",this.ttsWordHighlight),CSS.highlights.set("tts-sentence",this.ttsSentenceHighlight);for(let G of Object.values($7)){let Q=new Highlight;this.colorHighlights.set(G,Q),CSS.highlights.set(`annotation-${G}`,Q)}}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let G=document.createElement("style");G.id="pie-highlight-styles",G.textContent=`
1
+ import{B as D6,C as N6,H as M6,I as f,J as z6,K as O6,L as u9,N as P6,P as L7,Q as L6,R as b7,S as b9,T as S9,b as U6,c as V6,d as A6,e as c,f as y,g as m,h as E,i as h9,j as _6,k as m9,l as L1,m as w1,n as b,o as $6,p as A,q as h,t as p9,u as F6,v as R1,w as E1,x as H6}from"./chunks/ItemToolBar-h4xap0t0.js";import{U as X8,V as Z8}from"./chunks/ItemToolBar-wr2myaah.js";import{X as f5}from"./chunks/ItemToolBar-gmrryv2v.js";import{coerceBooleanAttributes as l2}from"@pie-players/pie-players-shared/ui/attribute-coercion";import{ContextProvider as W6,ContextRoot as K6,requestContext as i2}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as s2,createStageTracker as n2,resolveInstrumentationProvider as r2,TOOLKIT_INSTRUMENTATION_EVENT_MAP as o2}from"@pie-players/pie-players-shared/pie";import{isInstrumentationProvider as a2}from"@pie-players/pie-players-shared";import{createPieI18n as t2,DEFAULT_LOCALE as e2}from"@pie-players/pie-players-shared/i18n";function B1(Q){return{kind:Q.kind,severity:Q.severity??"error",source:Q.source,message:Q.message,details:[...Q.details||[]],recoverable:Q.recoverable===!0,cause:Q.cause}}function g1(Q){let Y=Q.error instanceof Error&&Q.error.message.trim().length>0?Q.error.message:String(Q.error||"Unknown framework error");return B1({kind:Q.kind,source:Q.source,message:Y,recoverable:Q.recoverable,cause:Q.error})}var $3={"coordinator-ready":"coordinator-init","state-load":"tool-state-load","state-save":"tool-state-save","provider-register":"provider-register","provider-init":"provider-init","tts-init":"tts-init","section-controller-init":"section-controller-init","section-controller-dispose":"section-controller-dispose"};function W0(Q){let Y=$3[Q.context.phase],J=Q.context.providerId?`pie-toolkit-coordinator/${Q.context.providerId}`:`pie-toolkit-coordinator:${Q.context.phase}`;return g1({kind:Y,source:J,error:Q.error,recoverable:Q.recoverable})}function K0(Q){let Y=`[pie-framework:${Q.kind}:${Q.source}]`;if(Q.details.length===0)return`${Y} ${Q.message}`;return`${Y} ${Q.message}
2
+ - ${Q.details.join(`
3
+ - `)}`}var F3="error";function c1(Q){if(Q==="off"||Q==="warn"||Q==="error")return Q;return F3}function l(Q){return Q}function H3(Q){if(!Q)return new Map;return new Map(Q.getAllTools().slice().sort((Y,J)=>Y.toolId.localeCompare(J.toolId)).map((Y)=>[Y.toolId,Y]))}function D3(Q,Y,J,G){if(!Y||!J?.provider?.sanitizeConfig)return Y;try{let X=J.provider.sanitizeConfig(Y);if(!X||typeof X!=="object"||Array.isArray(X))return G.push(l({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Q}`,message:`Provider sanitizer for "${Q}" must return an object.`,providerId:Q,toolId:Q})),Y;return X}catch(X){return G.push(l({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Q}`,message:`Provider sanitizer failed for "${Q}": ${X instanceof Error?X.message:String(X)}`,providerId:Q,toolId:Q})),Y}}function N3(Q,Y,J,G){if(!Y||!J?.provider?.validateConfig)return;try{let X=J.provider.validateConfig(Y);if(!Array.isArray(X)){G.push(l({code:"tools.invalidProviderValidation",severity:"error",path:`providers.${Q}`,message:`Provider validator for "${Q}" must return an array.`,providerId:Q,toolId:Q}));return}for(let j of X)G.push({...j,path:j.path||`providers.${Q}`,providerId:j.providerId||Q,toolId:j.toolId||Q})}catch(X){G.push(l({code:"tools.providerValidateFailed",severity:"error",path:`providers.${Q}`,message:`Provider validator failed for "${Q}": ${X instanceof Error?X.message:String(X)}`,providerId:Q,toolId:Q}))}}function M3(Q,Y,J){if(Y.size===0)return;let G=["section","item","passage"];for(let X of G)for(let j of Q.placement[X]){let Z=Y.get(j);if(!Z){J.push(l({code:"tools.unknownToolId",severity:"error",path:`placement.${X}`,message:`Unknown tool id "${j}" in placement.${X}.`,toolId:j}));continue}if(Z.activation==="region"){J.push(l({code:"tools.unplaceableActivation",severity:"error",path:`placement.${X}`,message:`Tool "${j}" renders into a host surface (activation "region") and cannot be placed on the ${X} toolbar. Remove it from placement.${X}; its availability comes from policy plus its content dependency.`,toolId:j}));continue}let B=Z.supportedLevels.includes(X),W=X==="item"&&Z.supportedLevels.includes("section");if(!B&&!W)J.push(l({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${j}" does not support level "${X}".`,toolId:j}))}}function z3(Q,Y,J){if(Y.size===0)return;for(let G of Q.policy.allowed||[]){if(Y.has(G))continue;J.push(l({code:"tools.unknownToolId",severity:"error",path:"policy.allowed",message:`Unknown tool id "${G}" in policy.allowed.`,toolId:G}))}for(let G of Q.policy.blocked||[]){if(Y.has(G))continue;J.push(l({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${G}" in policy.blocked.`,toolId:G}))}}function O3(Q,Y,J,G){if(J)G.push(l({code:"tools.removedProviderKey",severity:"error",path:"providers.tts",message:'Provider key "tts" is no longer supported. Use "providers.textToSpeech".',providerId:"tts",toolId:"textToSpeech"}));for(let X of Object.keys(Q.providers).sort()){if(Y.size===0||Y.has(X))continue;G.push(l({code:"tools.unknownProviderKey",severity:"error",path:`providers.${X}`,message:`Unknown provider key "${X}".`,providerId:X,toolId:X}))}}function U0(Q,Y){if(Q.length===0)return;for(let J of Q){let G=`[tool-config-validation:${Y}]`;console.warn(`${G} ${J.path} - ${J.message}`)}}function V0(Q,Y){let J=Q.map((G)=>`- ${G.path}: ${G.message}`).join(`
4
+ `);throw Error(`[tool-config-validation:${Y}] Invalid tools config:
5
+ ${J}`)}function A0(Q,Y={}){let J=d1(Q,Y.toolRegistry);return l1(J.diagnostics,Y),J}function d1(Q,Y){let J=H3(Y),G=b7(Q),X=[],j=Object.values(G.placement).some((K)=>K.length>0)||Object.keys(G.providers).length>0||(G.policy.allowed?.length??0)>0||(G.policy.blocked?.length??0)>0;if(J.size===0&&j)X.push(l({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated, and a coordinator without one registers no tool providers. Pass `toolRegistry` to the coordinator or the toolkit it is bound to — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let Z=Object.hasOwn(G.providers,"tts"),B={...G.providers||{}};for(let K of Object.keys(B).sort()){if(K==="tts"){delete B.tts;continue}let U=J.get(K);B[K]=D3(K,B[K],U,X),N3(K,B[K],U,X)}let W={...G,providers:B};return M3(W,J,X),z3(W,J,X),O3(W,J,Z,X),{config:W,diagnostics:X}}function l1(Q,Y={}){let J=c1(Y.strictness),G=Y.source??"tools",X=Q.filter((Z)=>Z.code==="tools.removedProviderKey");if(X.length>0)V0(X,G);if(J==="warn")U0(Q,G);let j=Q.filter((Z)=>Z.severity==="error");if(J==="error"&&j.length>0)V0(j,G);if(J==="error"&&j.length===0)U0(Q,G)}import{languageTagLookupSequence as E3,normalizeLanguageTag as D0}from"@pie-players/pie-players-shared/i18n/language-tags";var i1=(Q)=>Array.isArray(Q)&&Q.length>0;function s1(Q){if(Q.kind==="passage")return{ownerKind:"passage",assessmentId:Q.assessmentId,sectionId:Q.sectionId,passageId:Q.canonicalItemId||Q.itemId};return{ownerKind:"itemModel",assessmentId:Q.assessmentId,sectionId:Q.sectionId,itemId:Q.itemId,canonicalItemId:Q.canonicalItemId||Q.itemId}}function _0(Q,Y){if(!Q)return[];let J=s1(Y),G=[];if(i1(Q.accessibilityCatalogs))G.push({context:J,catalogs:Q.accessibilityCatalogs});if(i1(Q.config?.extractedCatalogs))G.push({context:J,catalogs:Q.config.extractedCatalogs});if(Y.kind==="passage")return G;if(J.ownerKind!=="itemModel")return G;for(let X of Q.config?.models??[]){if(!i1(X.accessibilityCatalogs))continue;G.push({context:{...J,modelId:X.id},catalogs:X.accessibilityCatalogs})}return G}var o1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),$0=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),F0=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),H0=new Set(["break","mark","lexicon"]);function P3(Q){let Y=Q;for(let J of H0){let G=new RegExp(`<${J}\\b([^>/]*?)\\s*/>`,"gi");Y=Y.replace(G,(X,j)=>{let Z=j?j.replace(/\s+$/,""):"";return`<${J}${Z}></${J}>`})}return Y}var L3=[/^localhost$/i,/^127(?:\.\d{1,3}){3}$/,/^0(?:\.\d{1,3}){3}$/,/^10(?:\.\d{1,3}){3}$/,/^192\.168(?:\.\d{1,3}){2}$/,/^172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}$/,/^169\.254(?:\.\d{1,3}){2}$/,/^::1$/,/^fe80:/i,/^fc00:/i,/^fd[0-9a-f]{2}:/i,/^metadata\.google\.internal$/i,/^metadata\.azure\.internal$/i,/^metadata\.packet\.net$/i];function w3(Q){if(typeof Q!=="string"||Q.length===0)return!1;let Y;try{Y=new URL(Q)}catch{return!1}if(Y.protocol!=="http:"&&Y.protocol!=="https:")return!1;let J=Y.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!L3.some((G)=>G.test(J))}function n1(Q){let Y=Array.from(Q.children);for(let G of Y){let X=G.tagName.toLowerCase();if($0.has(X)){G.remove();continue}if(n1(G),!o1.has(X)){let j=Q.ownerDocument.createTextNode(G.textContent??"");G.replaceWith(j)}}let J=Array.from(Q.attributes).map((G)=>G.name);for(let G of J)if(!F0.has(G.toLowerCase()))Q.removeAttribute(G);if(Q.tagName.toLowerCase()==="audio"){let G=Q.getAttribute("src");if(G!==null&&!w3(G))Q.removeAttribute("src")}}function r1(Q){let Y=Q.tagName.toLowerCase(),J=Array.from(Q.attributes).filter((X)=>F0.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${R3(X.value)}"`).join("");if(H0.has(Y))return`<${Y}${J}/>`;let G=[];for(let X of Array.from(Q.childNodes))if(X.nodeType===3)G.push(q1(X.nodeValue??""));else if(X.nodeType===1){let j=X,Z=j.tagName.toLowerCase();if($0.has(Z))continue;if(o1.has(Z))G.push(r1(j));else G.push(q1(j.textContent??""))}return`<${Y}${J}>${G.join("")}</${Y}>`}function a1(Q){let Y=String(Q||"").trim();if(!Y||!Y.includes("<"))return Q;if(typeof DOMParser>"u")return Q;let G=new DOMParser().parseFromString(P3(Y),"text/html"),X=G.querySelector("speak");if(X)return n1(X),r1(X);let j=G.createElement("speak");for(let Z of Array.from(G.body.childNodes))j.appendChild(Z);return n1(j),Array.from(j.childNodes).map((Z)=>{if(Z.nodeType===3)return q1(Z.nodeValue??"");if(Z.nodeType===1){let B=Z;if(o1.has(B.tagName.toLowerCase()))return r1(B);return q1(B.textContent??"")}return""}).join("")}function q1(Q){return Q.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function R3(Q){return Q.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var P0=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),t1="ext:";function N0(Q){if(P0.has(Q))return!0;return Q.startsWith(t1)&&Q.length>t1.length}var M0=new Set;function e1(Q,Y=new Set){if(Q===null||typeof Q==="string"||typeof Q==="number"||typeof Q==="boolean"||typeof Q>"u")return Q;if(typeof Q!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Y.has(Q))throw TypeError("catalog cards must not contain cycles");Y.add(Q);try{if(Array.isArray(Q))return Object.freeze(Q.map((X)=>e1(X,Y)));let J=Object.getPrototypeOf(Q);if(J!==Object.prototype&&J!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let G={};for(let[X,j]of Object.entries(Q))G[X]=e1(j,Y);return Object.freeze(G)}finally{Y.delete(Q)}}function z0(Q,Y,J){let G=`${Y}|${Q}`;if(M0.has(G))return;M0.add(G);let X=`${Array.from(P0).join(", ")}, or an "${t1}" prefixed vendor extension`;if(Y==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${J}" has a card of unknown type "${Q}"; it is stored but no reader asks for that type, so the alternate will never be shown. Expected one of: ${X}.`);return}console.warn(`[AccessibilityCatalogResolver] lookup for unknown catalog type "${Q}" on "${J}" cannot match any card. Expected one of: ${X}.`)}var O0=(Q)=>Q.payload!==void 0?"payload":"content";class Q9{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(Q,Y="en-US"){this.defaultLanguage=Y,this.indexCatalogs(Q??[],"assessment")}setDefaultLanguage(Q){this.defaultLanguage=Q}onCatalogsChange(Q){return this.catalogChangeListeners.add(Q),()=>{this.catalogChangeListeners.delete(Q)}}emitCatalogsChange(Q){for(let Y of Array.from(this.catalogChangeListeners))try{Y(Q)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(Q,Y){let J=Y==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let G of this.sanitizeCatalogs(Q)){if(J.has(G.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Y} catalog "${G.identifier}" ignored`);continue}J.set(G.identifier,G)}}insertScopedCatalogs(Q,Y){if(!Y||Y.length===0)return null;let J=this.getOwnerKey(Q),G=this.scopedCatalogs.get(J),X=G?.catalogs??new Map,j=[];for(let Z of this.sanitizeCatalogs(Y)){if(X.has(Z.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${Z.identifier}" ignored for ${J}`);continue}X.set(Z.identifier,Z),j.push(Z.identifier)}if(!G&&j.length>0)this.scopedCatalogs.set(J,{context:{...Q},catalogs:X});return{key:J,context:{...Q},catalogs:X,insertedIds:j}}removeScopedInsertion(Q){let Y=this.scopedCatalogs.get(Q.key);if(Y?.catalogs!==Q.catalogs)return!1;let J=!1;for(let G of Q.insertedIds)J=Y.catalogs.delete(G)||J;if(Y.catalogs.size===0)this.scopedCatalogs.delete(Q.key);return J}registerCatalogs(Q,Y){let J=this.insertScopedCatalogs(Q,Y);if(J&&J.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:Q});let G=!0;return()=>{if(!G)return;if(G=!1,J&&this.removeScopedInsertion(J))this.emitCatalogsChange({reason:"scoped-removed",context:Q})}}registerOwner(Q){let{owner:Y,entity:J}=Q,G=s1(Y),X=[],j=[];try{j=_0(J,Y)}catch(W){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",W)}for(let W of j)try{let K=this.insertScopedCatalogs(W.context,W.catalogs);if(K)X.push(K)}catch(K){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",K)}if(X.some((W)=>W.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:G});let B=!0;return()=>{if(!B)return;B=!1;let W=!1;for(let K of X)W=this.removeScopedInsertion(K)||W;if(W)this.emitCatalogsChange({reason:"scoped-removed",context:G})}}forOwner(Q){let Y={...Q};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Y),onChange:(J)=>this.onCatalogsChange((G)=>{if(this.catalogChangeAffectsOwner(G,Y))J()})})}addItemCatalogs(Q){if(!Q||Q.length===0)return;this.indexCatalogs(Q,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(Q){return this.itemCatalogs.has(Q)||this.assessmentCatalogs.has(Q)||Array.from(this.scopedCatalogs.values()).some((Y)=>Y.catalogs.has(Q))}getAlternative(Q,Y){if(!N0(Y.type))z0(Y.type,"lookup",Q);let J=Y.context?this.scopedCatalogs.get(this.getOwnerKey(Y.context))?.catalogs.get(Q):null;if(J){let j=this.findMatchingCard(J,Y);if(j)return this.resolveCard(Q,j,"item")}if(Y.context){let j=this.findScopedCandidates(Q,Y.context);if(j.length===1){let Z=this.findMatchingCard(j[0],Y);if(Z)return this.resolveCard(Q,Z,"item")}else if(j.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${Q}" for owner context`,Y.context),null}let G=this.itemCatalogs.get(Q);if(G){let j=this.findMatchingCard(G,Y);if(j)return this.resolveCard(Q,j,"item")}let X=this.assessmentCatalogs.get(Q);if(X){let j=this.findMatchingCard(X,Y);if(j)return this.resolveCard(Q,j,"assessment")}return null}resolveCard(Q,Y,J){return{catalogId:Q,type:Y.catalog,language:Y.language,content:Y.catalog==="spoken"&&Y.content!==void 0?this.ensureSpokenSanitized(Y.content):Y.content,payload:Y.payload,source:J}}ensureSpokenSanitized(Q){let Y=this.sanitizedSpokenCache.get(Q);if(Y!==void 0)return Y;let J=a1(Q);return this.sanitizedSpokenCache.set(Q,J),J}getOwnerKey(Q){return[Q.ownerKind,Q.assessmentId||"",Q.sectionId||"",Q.canonicalItemId||"",Q.itemId||"",Q.passageId||"",Q.modelId||""].join("|")}scopedCatalogEntries(){let Q=[];for(let Y of this.scopedCatalogs.values())for(let J of Y.catalogs.entries())Q.push(J);return Q}findScopedCandidates(Q,Y){return Array.from(this.scopedCatalogs.values()).filter((J)=>this.isCompatibleOwnerContext(J.context,Y)).map((J)=>J.catalogs.get(Q)).filter((J)=>Boolean(J))}isCompatibleOwnerContext(Q,Y){if(Q.ownerKind!==Y.ownerKind)return!1;if(Y.assessmentId&&Q.assessmentId!==Y.assessmentId)return!1;if(Y.sectionId&&Q.sectionId!==Y.sectionId)return!1;if(Y.canonicalItemId&&Q.canonicalItemId!==Y.canonicalItemId)return!1;if(Y.itemId&&Q.itemId!==Y.itemId)return!1;if(Y.passageId&&Q.passageId!==Y.passageId)return!1;if(Y.modelId&&Q.modelId!==Y.modelId)return!1;return!0}ownerScopedCatalogEntries(Q){let Y=[],J=this.scopedCatalogs.get(this.getOwnerKey(Q));if(J)Y.push(...J.catalogs.entries());for(let G of this.scopedCatalogs.values()){if(G===J)continue;if(!this.isCompatibleOwnerContext(G.context,Q))continue;Y.push(...G.catalogs.entries())}return Y}createOwnerSnapshot(Q){let Y=[],J=this.ownerScopedCatalogEntries(Q);if(Q.ownerKind==="global")J.push(...this.assessmentCatalogs.entries());for(let[G,X]of J)for(let j of X.cards)try{Y.push(Object.freeze({catalogId:G,card:e1(j)}))}catch(Z){let B=`${this.getOwnerKey(Q)}\x00${G}`;if(!this.reportedSnapshotProblems.has(B))this.reportedSnapshotProblems.add(B),console.warn(`[AccessibilityCatalogResolver] Catalog "${G}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,Z)}return Object.freeze({cards:Object.freeze(Y)})}catalogChangeAffectsOwner(Q,Y){if(!Q.context)return!1;if(this.isCompatibleOwnerContext(Q.context,Y))return!0;if(Y.ownerKind==="itemModel"&&Y.modelId&&Q.context.ownerKind==="itemModel"&&!Q.context.modelId)return this.isCompatibleOwnerContext({...Q.context,modelId:Y.modelId},Y);return!1}sanitizeCatalogs(Q){return Q.map((Y)=>({...Y,cards:Y.cards.map((J)=>{if(!N0(J.catalog))z0(J.catalog,"card",Y.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?a1(J.content):J.content}})}))}findMatchingCard(Q,Y){let{type:J,language:G,useFallback:X=!0,form:j}=Y,Z=[],B=(W)=>{for(let K of E3(W))Z.push((U)=>D0(U.language)===K)};if(G)B(G);if(X)B(this.defaultLanguage),Z.push(()=>!0);for(let W of Z){let K=Q.cards.filter((U)=>U.catalog===J&&W(U));if(K.length===0)continue;if(j){let U=K.find((_)=>O0(_)===j);if(U)return U}return K[0]}return null}getAllAlternatives(Q){let Y=[],J=new Set,G=(Z,B)=>{let W=`${Z.catalog}|${D0(Z.language)}|${O0(Z)}`;if(J.has(W))return;J.add(W),Y.push(this.resolveCard(Q,Z,B))},X=this.itemCatalogs.get(Q);if(X)for(let Z of X.cards)G(Z,"item");let j=this.assessmentCatalogs.get(Q);if(j)for(let Z of j.cards)G(Z,"assessment");for(let[Z,B]of this.scopedCatalogEntries()){if(Z!==Q)continue;for(let W of B.cards)G(W,"item")}return Y}getAllCatalogIds(){let Q=this.scopedCatalogEntries().map(([Y])=>Y);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...Q]))}getStatistics(){let Q=new Set,Y=new Set;for(let J of this.assessmentCatalogs.values())for(let G of J.cards)if(Q.add(G.catalog),G.language)Y.add(G.language);for(let J of this.itemCatalogs.values())for(let G of J.cards)if(Q.add(G.catalog),G.language)Y.add(G.language);for(let J of this.scopedCatalogs.values())for(let G of J.catalogs.values())for(let X of G.cards)if(Q.add(X.catalog),X.language)Y.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,G)=>J+G.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,G)=>J+G.catalogs.size,0),availableTypes:Q,availableLanguages:Y}}hasAlternativeType(Q,Y){return this.getAllAlternatives(Q).some((G)=>G.type===Y)}getCatalogsByType(Q){let Y=new Set;for(let[J,G]of this.assessmentCatalogs.entries())if(G.cards.some((X)=>X.catalog===Q))Y.add(J);for(let[J,G]of this.itemCatalogs.entries())if(G.cards.some((X)=>X.catalog===Q))Y.add(J);for(let[J,G]of this.scopedCatalogEntries())if(G.cards.some((X)=>X.catalog===Q))Y.add(J);return Array.from(Y)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}class Y9{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Q,Y,J,G){return`${Q}:${Y}:${J}:${G}`}parseGlobalElementId(Q){let Y=Q.split(":");if(Y.length!==4)return null;return{assessmentId:Y[0],sectionId:Y[1],itemId:Y[2],elementId:Y[3]}}setState(Q,Y,J){let G=this.elementStates.get(Q);if(!G)G=new Map,this.elementStates.set(Q,G);G.set(Y,J),this._notifyListeners(),this._notifyStateChange()}getState(Q,Y){return this.elementStates.get(Q)?.get(Y)}getElementState(Q){let Y=this.elementStates.get(Q);if(!Y)return{};return Object.fromEntries(Y.entries())}getAllState(){let Q={};for(let[Y,J]of this.elementStates.entries())Q[Y]=Object.fromEntries(J.entries());return Q}subscribe(Q){return this.listeners.add(Q),()=>this.listeners.delete(Q)}_notifyListeners(){for(let Q of this.listeners)Q(this.elementStates)}setOnStateChange(Q){this.onStateChange=Q}_notifyStateChange(){if(this.onStateChange)this.onStateChange(this.getAllState())}loadState(Q){this.elementStates.clear();for(let[Y,J]of Object.entries(Q)){let G=new Map(Object.entries(J));this.elementStates.set(Y,G)}this._notifyListeners()}clearElement(Q){this.elementStates.delete(Q),this._notifyListeners(),this._notifyStateChange()}clearTool(Q){for(let Y of this.elementStates.values())Y.delete(Q);this._notifyListeners(),this._notifyStateChange()}clearSection(Q,Y){let J=`${Q}:${Y}:`,G=[];for(let X of this.elementStates.keys())if(X.startsWith(J))G.push(X);for(let X of G)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class u7{listeners=new Set;subscribeFrameworkErrors(Q){this.listeners.add(Q);let Y=!0;return()=>{if(!Y)return;Y=!1,this.listeners.delete(Q)}}reportFrameworkError(Q){let Y=Array.from(this.listeners);for(let J of Y)try{J(Q)}catch(G){console.warn("[FrameworkErrorBus] listener failed:",G)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}class J9{serialize(Q,Y){return{startContainer:this.getNodePath(Q.startContainer,Y),startOffset:Q.startOffset,endContainer:this.getNodePath(Q.endContainer,Y),endOffset:Q.endOffset,text:Q.toString()}}deserialize(Q,Y){let J=this.findNodeByPath(Q.startContainer,Y),G=this.findNodeByPath(Q.endContainer,Y);if(!J||!G)return null;try{let X=new Range;if(X.setStart(J,Q.startOffset),X.setEnd(G,Q.endOffset),X.toString()===Q.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(Q,Y){if(Q===Y)return"";if(Q.nodeType===Node.TEXT_NODE){let J=Q.parentElement;if(!J)throw Error("Text node has no parent");let X=Array.from(J.childNodes).filter((Z)=>Z.nodeType===Node.TEXT_NODE).indexOf(Q);return`${this.getElementPath(J,Y)}::text[${X}]`}if(Q.nodeType===Node.ELEMENT_NODE)return this.getElementPath(Q,Y);throw Error(`Unsupported node type: ${Q.nodeType}`)}getElementPath(Q,Y){if(Q===Y)return"";let J=[],G=Q;while(G&&G!==Y){if(G.id){J.unshift(`#${G.id}`);break}let X=G.parentElement;if(!X)break;let j=Array.from(X.children).filter((W)=>W.tagName===G.tagName),Z=j.indexOf(G),B=j.length>1?`${G.tagName.toLowerCase()}:nth-of-type(${Z+1})`:G.tagName.toLowerCase();J.unshift(B),G=X}return J.join(" > ")}findNodeByPath(Q,Y){if(Q==="")return Y;if(Q.includes("::text[")){let[J,G]=Q.split("::text["),X=Number.parseInt(G.replace("]",""),10),j=J?Y.querySelector(J):Y;if(!j)return null;return Array.from(j.childNodes).filter((B)=>B.nodeType===Node.TEXT_NODE)[X]||null}try{return Y.querySelector(Q)}catch(J){return console.warn("Invalid selector path:",Q,J),null}}serializeMany(Q,Y){return Q.map((J)=>this.serialize(J,Y))}deserializeMany(Q,Y){return Q.map((J)=>this.deserialize(J,Y))}}var u;(function(Q){Q.TTS_WORD="tts-word",Q.TTS_SENTENCE="tts-sentence",Q.ANNOTATION="annotation"})(u||(u={}));var _7;(function(Q){Q.YELLOW="yellow",Q.GREEN="green",Q.BLUE="blue",Q.PINK="pink",Q.ORANGE="orange",Q.UNDERLINE="underline"})(_7||(_7={}));class p7{ttsWordHighlight=null;ttsSentenceHighlight=null;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;colorHighlights=new Map;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;explicitTTSColorOverride=null;constructor(){if(this.rangeSerializer=new J9,typeof CSS>"u"||!("highlights"in CSS)){console.warn("CSS Custom Highlight API not supported (SSR or unsupported browser)");return}this.supported=!0,this.initializeHighlights(),this.registerStyles(),this.applyAdaptiveTTSStyle(),this.setupThemeObservation()}setupThemeObservation(){if(typeof document>"u")return;if(typeof MutationObserver>"u")return;let Q=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(Q),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]});for(let Y of document.querySelectorAll("pie-theme"))this.themeObserver.observe(Y,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(Q){if(!Q)return null;let Y=Q.trim();if(!Y)return null;let J=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Y);if(J){let X=J[1];if(X.length===3)return[parseInt(X[0]+X[0],16),parseInt(X[1]+X[1],16),parseInt(X[2]+X[2],16)];return[parseInt(X.slice(0,2),16),parseInt(X.slice(2,4),16),parseInt(X.slice(4,6),16)]}let G=/^rgba?\((.+)\)$/i.exec(Y);if(G){let j=G[1].replace(/\//g,",").split(/[,\s]+/).map((K)=>K.trim()).filter(Boolean),Z=Number(j[0]),B=Number(j[1]),W=Number(j[2]);if(Number.isFinite(Z)&&Number.isFinite(B)&&Number.isFinite(W))return[Z,B,W]}if(typeof document<"u"){let X=document.createElement("span");if(X.style.color=Y,typeof X.style.color==="string"&&X.style.color){document.body?.appendChild(X);let j=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let Z=j.trim();if(Z&&Z!==Y)return this.parseColor(j)}}return null}relativeLuminance([Q,Y,J]){let G=(B)=>{let W=B/255;return W<=0.03928?W/12.92:((W+0.055)/1.055)**2.4},X=G(Q),j=G(Y),Z=G(J);return 0.2126*X+0.7152*j+0.0722*Z}contrastRatio(Q,Y){let J=this.relativeLuminance(Q),G=this.relativeLuminance(Y),X=Math.max(J,G),j=Math.min(J,G);return(X+0.05)/(j+0.05)}blend(Q,Y,J){return[Math.round(Q[0]*J+Y[0]*(1-J)),Math.round(Q[1]*J+Y[1]*(1-J)),Math.round(Q[2]*J+Y[2]*(1-J))]}resolveAdaptiveTTSStyle(Q){let Y=[255,235,59],J=[17,24,39],G=[255,255,255],X=Q||(typeof document<"u"?document.documentElement:null),j=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,Z=this.parseColor(j?.getPropertyValue("--pie-background")||j?.backgroundColor)||G,B=this.parseColor(j?.getPropertyValue("--pie-text"))||J,W=this.explicitTTSColorOverride?this.parseColor(this.explicitTTSColorOverride.color)||Y:this.parseColor(j?.getPropertyValue("--pie-missing"))||Y,K=this.explicitTTSColorOverride?[Math.max(0.3,Math.min(0.95,this.explicitTTSColorOverride.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],U=K[K.length-1],_=-1/0;for(let g of K){let B7=this.blend(W,Z,g),q7=this.contrastRatio(B7,Z),W7=this.contrastRatio(B7,B),w7=q7*1.2+W7*0.8;if(q7>=1.25&&W7>=2.4){U=g;break}if(w7>_)_=w7,U=g}let $=Math.max(0.24,Math.min(0.85,U*0.55)),N=Math.max(0.55,Math.min(0.95,U+0.2)),D=Math.max(0.22,Math.min(0.6,U*0.45)),O=B,P=this.blend(O,Z,N),F=this.contrastRatio(P,Z),L=this.relativeLuminance(Z)>0.45?[0,0,0]:[255,255,255],C=F>=1.35?O:L,v=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${U})`,k=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${$})`,p=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${N})`,R=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${D})`;return{wordHighlight:v,sentenceHighlight:k,wordUnderline:p,wordShadow:R}}applyAdaptiveTTSStyle(Q){if(typeof document>"u")return;let Y=this.resolveAdaptiveTTSStyle(Q);document.documentElement.style.setProperty("--pie-tts-word-highlight",Y.wordHighlight),document.documentElement.style.setProperty("--pie-tts-sentence-highlight",Y.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-line-highlight",Y.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-word-underline",Y.wordUnderline),document.documentElement.style.setProperty("--pie-tts-word-shadow",Y.wordShadow)}initializeHighlights(){if(!this.supported)return;this.ttsWordHighlight=new Highlight,this.ttsSentenceHighlight=new Highlight,CSS.highlights.set("tts-word",this.ttsWordHighlight),CSS.highlights.set("tts-sentence",this.ttsSentenceHighlight);for(let Q of Object.values(_7)){let Y=new Highlight;this.colorHighlights.set(Q,Y),CSS.highlights.set(`annotation-${Q}`,Y)}}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let Q=document.createElement("style");Q.id="pie-highlight-styles",Q.textContent=`
6
6
  /* TTS highlights - temporary */
7
7
  ::highlight(tts-word) {
8
8
  background-color: var(--pie-tts-word-highlight, color-mix(in srgb, var(--pie-missing, #ffeb3b) 68%, transparent));
@@ -212,14 +212,14 @@ ${Y}`)}function Z7(G,Q={}){let Y=i1(Q.strictness),J=Q.source??"tools",X=N5(Q.too
212
212
  text-shadow: none;
213
213
  }
214
214
  }
215
- `,document.head.appendChild(G)}highlightTTSWord(G,Q,Y){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(G.parentElement),this.clearTTSWord();let J=document.createRange();J.setStart(G,Q),J.setEnd(G,Y),this.ttsWordHighlight.add(J)}highlightTTSWordElement(G){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(G),this.clearTTSWord(),G.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(G)}highlightTTSSentence(G){if(!this.ttsSentenceHighlight)return;let Q=G[0]?.startContainer,Y=Q?.nodeType===Node.ELEMENT_NODE?Q:Q?.parentElement;this.applyAdaptiveTTSStyle(Y),this.clearTTSSentence();for(let J of G)this.ttsSentenceHighlight.add(J);this.highlightTTSElementFallbacks(G)}highlightTTSSentenceElements(G){if(!this.ttsSentenceHighlight)return;this.applyAdaptiveTTSStyle(G[0]||null),this.clearTTSSentence();for(let Q of G)Q.setAttribute("data-pie-tts-sentence-element","true"),this.ttsSentenceElementHighlights.add(Q)}static SENTENCE_FALLBACK_SELECTOR="math, mjx-container, svg, img, canvas, [role='img']";static WORD_FALLBACK_SELECTOR="svg, img, canvas, [role='img']";highlightTTSElementFallbacks(G){if(typeof Element>"u")return;this.highlightElementFallbacks(G,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,g7.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(G){if(typeof Element>"u")return;this.highlightElementFallbacks(G,"data-pie-tts-word-element",this.ttsWordElementHighlights,g7.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(G,Q,Y,J){for(let X of G){let j=X.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?X.commonAncestorContainer:X.commonAncestorContainer.parentElement;if(!j)continue;let Z=[],q=X.startContainer.nodeType===Node.ELEMENT_NODE?X.startContainer:X.startContainer.parentElement,B=X.endContainer.nodeType===Node.ELEMENT_NODE?X.endContainer:X.endContainer.parentElement;for(let K of[q,B]){let W=K;while(W){if(W.matches?.(J))Z.push(W);W=W.parentElement}}if(j.matches?.(J))Z.push(j);Z.push(...Array.from(j.querySelectorAll(J)));for(let K of new Set(Z)){try{if(!X.intersectsNode(K)&&!K.contains(q)&&!K.contains(B))continue}catch{continue}K.setAttribute(Q,"true"),Y.add(K)}}}clearTTSWord(){if(!this.ttsWordHighlight)return;this.ttsWordHighlight.clear();for(let G of this.ttsWordElementHighlights)G.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.ttsSentenceHighlight)return;this.ttsSentenceHighlight.clear();for(let G of this.ttsSentenceElementHighlights)G.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){this.clearTTSWord(),this.clearTTSSentence()}addAnnotation(G,Q=$7.YELLOW){let Y=`annotation-${this.nextAnnotationId++}`,J=G.cloneRange(),X={id:Y,range:J,type:u.ANNOTATION,color:Q,timestamp:Date.now()};this.annotations.set(Y,X);let j=this.colorHighlights.get(Q);if(j)j.add(J);return Y}removeAnnotation(G){let Q=this.annotations.get(G);if(!Q){console.warn(`[HighlightCoordinator] Annotation ${G} not found`);return}console.log(`[HighlightCoordinator] Removing annotation ${G} (color: ${Q.color})`);let Y=this.colorHighlights.get(Q.color);if(Y){let J=Y.delete(Q.range);console.log("[HighlightCoordinator] Highlight.delete() returned:",J)}this.annotations.delete(G),console.log(`[HighlightCoordinator] Annotation ${G} removed from map. Remaining:`,this.annotations.size)}clearAnnotations(){for(let G of this.colorHighlights.values())G.clear();this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(G){return this.annotations.get(G)??null}changeAnnotationColor(G,Q){let Y=this.annotations.get(G);if(!Y)return;let J=Y.color;if(J===Q)return;let X=this.colorHighlights.get(J);if(X)X.delete(Y.range);Y.color=Q;let j=this.colorHighlights.get(Q);if(j)j.add(Y.range)}exportAnnotations(G=document.body){return this.getAnnotations().map((Q)=>({...this.rangeSerializer.serialize(Q.range,G),id:Q.id,color:Q.color,timestamp:Q.timestamp}))}importAnnotations(G,Q=document.body){let Y=0;for(let J of G){let X=this.rangeSerializer.deserialize(J,Q);if(X)this.addAnnotation(X,J.color),Y++}return Y}highlightRange(G,Q,Y=$7.YELLOW){if(!this.supported)return;switch(Q){case u.TTS_WORD:case u.TTS_SENTENCE:{let J=Q===u.TTS_WORD?this.ttsWordHighlight:this.ttsSentenceHighlight;if(J){if(J.clear(),J.add(G),Q===u.TTS_WORD){for(let X of this.ttsWordElementHighlights)X.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear(),this.highlightTTSWordElementFallbacks([G])}}break}case u.ANNOTATION:this.addAnnotation(G,Y);break}}clearHighlights(G){if(!this.supported)return;switch(G){case u.TTS_WORD:this.clearTTSWord();break;case u.TTS_SENTENCE:this.clearTTSSentence();break;case u.ANNOTATION:this.clearAnnotations();break}}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}isSupported(){return this.supported}updateTTSHighlightStyle(G,Q){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((j)=>{let Z=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(j);return Z?{r:parseInt(Z[1],16),g:parseInt(Z[2],16),b:parseInt(Z[3],16)}:null})(G);if(!X)return;this.explicitTTSColorOverride={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Q))},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations(),this.themeObserver?.disconnect(),this.themeObserver=null}}function N6(G){return(...Q)=>{console.debug(`[${G}]`,...Q)}}var a=N6("ToolCoordinator"),j7;(function(G){G[G.BASE=0]="BASE",G[G.TOOL=1000]="TOOL",G[G.MODAL=2000]="MODAL",G[G.CONTROL=3000]="CONTROL",G[G.HIGHLIGHT=4000]="HIGHLIGHT"})(j7||(j7={}));class X8{config;tools=new Map;layerCounters=new Map;listeners=new Set;visibilityState=new Map;constructor(G={}){this.config=G,this.layerCounters.set(j7.BASE,0),this.layerCounters.set(j7.TOOL,0),this.layerCounters.set(j7.MODAL,0),this.layerCounters.set(j7.CONTROL,0),this.layerCounters.set(j7.HIGHLIGHT,0)}subscribe(G){return this.listeners.add(G),()=>{this.listeners.delete(G)}}notifyListeners(){this.listeners.forEach((G)=>G())}registerTool(G,Q,Y,J=j7.MODAL){if(a("registerTool called:",{id:G,name:Q,hasElement:!!Y,layer:J}),this.tools.has(G)){a(`Tool ${G} is already registered`);return}let X=this.visibilityState.get(G)??!1;if(!Y){this.tools.set(G,{id:G,name:Q,element:null,layer:J,isVisible:X,baseZIndex:J}),a("Tool registered without element:",G);return}let j=J+this.getNextLayerOffset(J);Y.style.zIndex=String(j),Y.style.display=X?"":"none";let Z=()=>this.bringToFront(Y);if(Y.addEventListener("mousedown",Z),this.tools.set(G,{id:G,name:Q,element:Y,layer:J,isVisible:X,baseZIndex:j,mouseDownHandler:Z}),X)this.bringToFront(Y);a("Tool registered with element:",G)}unregisterTool(G){let Q=this.tools.get(G);if(!Q)return;if(Q.element&&Q.mouseDownHandler)Q.element.removeEventListener("mousedown",Q.mouseDownHandler);this.tools.delete(G)}releaseTool(G){this.unregisterTool(G),this.visibilityState.delete(G)}showTool(G){let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found`);return}if(Q.element)Q.element.style.display="",this.bringToFront(Q.element);Q.isVisible=!0,this.visibilityState.set(G,!0),this.notifyListeners()}hideTool(G){let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found`);return}if(Q.element)Q.element.style.display="none";Q.isVisible=!1,this.visibilityState.set(G,!1),this.notifyListeners()}toggleTool(G){a("toggleTool called for:",G);let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found. Registered tools:`,Array.from(this.tools.keys()));return}if(a("Tool found, current visibility:",Q.isVisible),Q.isVisible)this.hideTool(G);else this.showTool(G)}isToolVisible(G){let Q=this.tools.get(G);if(Q)return Q.isVisible;return this.visibilityState.get(G)??!1}bringToFront(G){let Q=Array.from(this.tools.values()).find((X)=>X.element===G);if(!Q)return;let Y=this.getMaxZIndexInLayer(Q.layer),J=Math.max(Y+1,Q.layer+1);G.style.zIndex=String(J),Q.baseZIndex=J}getRegisteredTools(){return Array.from(this.tools.keys())}getToolElement(G){return this.tools.get(G)?.element??null}getNextLayerOffset(G){let Q=this.layerCounters.get(G)??0;return this.layerCounters.set(G,Q+1),Q}getMaxZIndexInLayer(G){let Q=G;for(let Y of this.tools.values())if(Y.layer===G)Q=Math.max(Q,Y.baseZIndex);return Q}resetZIndices(){for(let G of this.tools.values())if(G.element)G.element.style.zIndex=String(G.baseZIndex)}updateToolElement(G,Q){let Y=this.tools.get(G);if(!Y){a(`Tool ${G} not found`);return}if(Y.element&&Y.mouseDownHandler)Y.element.removeEventListener("mousedown",Y.mouseDownHandler);let J=()=>this.bringToFront(Q);if(Q.addEventListener("mousedown",J),Y.element=Q,Y.mouseDownHandler=J,Q.style.zIndex=String(Y.baseZIndex),Y.isVisible)Q.style.display="";else Q.style.display="none"}hideAllTools(){for(let G of this.tools.keys())this.hideTool(G);this.notifyListeners()}getToolState(G){let Q=this.tools.get(G);if(!Q)return;return{id:Q.id,name:Q.name,isVisible:Q.isVisible,element:Q.element??null,layer:Q.layer}}getVisibleTools(){return Array.from(this.tools.values()).filter((G)=>G.isVisible).map((G)=>({id:G.id,name:G.name,isVisible:G.isVisible,element:G.element??null,layer:G.layer}))}}var S5=/^[a-z][a-z0-9+.-]*:/i,T5=new Set(["http:","https:","data:","blob:"]);function F6(G){return G!==void 0&&G!==1}function C5(G){if(typeof G!=="string")return!1;let Q=G.trim();if(!Q)return!1;if(Q.startsWith("//")||!S5.test(Q))return!0;let Y=Q.slice(0,Q.indexOf(":")+1).toLowerCase();return T5.has(Y)}function M6(G){if(!Array.isArray(G))return[];let Q=[];for(let Y of G){if(!Y||typeof Y!=="object")continue;let J=Y;if(!C5(J.src))continue;let X={src:J.src.trim()};if(typeof J.type==="string"&&J.type.trim())X.type=J.type.trim();if(Number.isFinite(J.width))X.width=J.width;if(Number.isFinite(J.height))X.height=J.height;if(Q.some((j)=>j.src===X.src))continue;Q.push(X)}return Q}function z6(G){if(!G||typeof G!=="object")return;let Q=G,Y=Number(Q.startSeconds);if(!Number.isFinite(Y)||Y<0)return;let J=Number(Q.endSeconds);if(!Number.isFinite(J)||J<=Y)return{startSeconds:Y};return{startSeconds:Y,endSeconds:J}}function O6(G){if(typeof G!=="string")return;return G.trim()||void 0}var y5=100,x5=1;function P6(G,Q,Y){if(!Q)return()=>{};let{startSeconds:J,endSeconds:X}=Q,j;if(J>0)if(j=()=>{if(G.currentTime<J)G.currentTime=J},G.readyState>=x5)j();else G.addEventListener("loadedmetadata",j);let Z,q;if(X!==void 0)Z=()=>{if(G.currentTime>=X)Y()},G.addEventListener("timeupdate",Z),q=setInterval(()=>{if(!G.paused)Z?.()},y5);return()=>{if(j)G.removeEventListener("loadedmetadata",j);if(Z)G.removeEventListener("timeupdate",Z);if(q!==void 0)clearInterval(q)}}function L6(G,Q){if(!Q)return G;if(G.includes("#"))return G;let Y=Q.endSeconds!==void 0?`,${Q.endSeconds}`:"";return`${G}#t=${Q.startSeconds}${Y}`}function w6(G){if(!G)return null;let Q=G.payload;if(!Q||typeof Q!=="object")return null;let Y=Q.media;if(!Y||typeof Y!=="object")return console.warn("[spoken-audio] card carries a `payload` with no `media`; recorded speech needs `media.sources`, so this card is ignored and read-aloud falls back to the script or generated speech"),null;if(F6(Y.version))return console.warn(`[spoken-audio] card's media declares version ${String(Y.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(Y.kind!==void 0&&Y.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${Y.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let J=M6(Y.sources);if(J.length===0)return console.warn("[spoken-audio] card's `media.sources` yielded no usable URL; read-aloud falls back to the script or generated speech"),null;return{sources:J,fragment:z6(Q.fragment),label:O6(Y.label)}}var S7=(G,Q)=>{let Y=Q?.useSentenceSegmenter!==!1;try{if(!Y)throw Error("Segmenter disabled by policy");let q=globalThis.Intl?.Segmenter;if(typeof q==="function"){let B=new q(Q?.locale,{granularity:"sentence"}),K=Array.from(B.segment(G)).map((W)=>({text:W.segment,offset:W.index})).filter((W)=>W.text.trim().length>0);if(K.length>0)return K}}catch{}let J=/[^.!?]+(?:[.!?]+|$)/g,X=G.match(J)||[G],j=[],Z=0;for(let q of X){let B=G.indexOf(q,Z);if(B===-1)continue;j.push({text:q,offset:B}),Z=B+q.length}return j.length>0?j:[{text:G,offset:0}]};var R6=5000,E6=2000,b6=(G)=>String(G||"").trim().toLowerCase(),f5=()=>{let G=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return b6(G||"en-US")},k5=(G,Q)=>{if(Q)return G.find((Z)=>Z.voiceURI===Q)||G.find((Z)=>Z.name===Q)||null;let Y=f5(),J=Y.split("-")[0]||"en",X=(Z)=>{let q=b6(Z.lang);return q===Y||q.startsWith(`${J}-`)},j=[(Z)=>Z.localService&&X(Z),(Z)=>Z.default&&X(Z),(Z)=>X(Z),(Z)=>Z.localService,(Z)=>Z.default];for(let Z of j){let q=G.find(Z);if(q)return q}return G[0]||null},I5=(G)=>!G.default;class T7{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";async initialize(G){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");return new S6(G)}supportsFeature(G){return!0}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class S6{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;settlePendingVoiceWait=null;settlePendingChunk=null;onPlaybackStart=void 0;constructor(G){this.config=G}waitForBrowserVoices(G,Q){return new Promise((Y,J)=>{let X=speechSynthesis,j=typeof X.addEventListener==="function"&&typeof X.removeEventListener==="function",Z=j?null:X.onvoiceschanged,q=!1,B=null,K=null,W=()=>{if(B!==null)clearTimeout(B),B=null;if(j)X.removeEventListener("voiceschanged",N);else if(X.onvoiceschanged===F)X.onvoiceschanged=Z;if(K&&this.settlePendingVoiceWait===K)this.settlePendingVoiceWait=null},$=(O,L)=>{if(q)return;if(q=!0,W(),L)J(L);else Y(O)},H=()=>{if(G!==this.speakRunId){$(!1);return}if(X.getVoices().length>0)$(!0)},N=()=>H(),F=(O)=>{try{Z?.call(X,O)}finally{H()}};if(K=()=>$(!1),this.settlePendingVoiceWait=K,B=setTimeout(()=>$(!1,Error(`Configured browser voice "${Q}" could not be resolved because the browser did not publish its voice inventory within ${E6/1000} seconds.`)),E6),j)X.addEventListener("voiceschanged",N);else X.onvoiceschanged=F;H()})}async resolveBrowserVoice(G){let Q=typeof this.config?.voice==="string"?this.config.voice.trim():"",Y=speechSynthesis.getVoices();if(Q&&Y.length===0){if(!await this.waitForBrowserVoices(G,Q)||G!==this.speakRunId)return{shouldContinue:!1,voice:null};Y=speechSynthesis.getVoices()}if(G!==this.speakRunId)return{shouldContinue:!1,voice:null};let J=k5(Y,Q||void 0);if(Q&&!J)throw Error(`Configured browser voice "${Q}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return{shouldContinue:!0,voice:J}}async speak(G){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId,Y=await this.resolveBrowserVoice(Q);if(!Y.shouldContinue)return;let J=this.splitIntoChunks(G);for(let X of J){if(Q!==this.speakRunId)break;if(!await this.speakChunk(X.text,X.offset,Q,Y.voice))break}}async speakSegments(G){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId,Y=await this.resolveBrowserVoice(Q);if(!Y.shouldContinue)return;for(let J of G){if(Q!==this.speakRunId)break;let X=this.splitIntoChunks(J.text);for(let Z of X){if(Q!==this.speakRunId)break;if(!await this.speakChunk(Z.text,J.startOffset+Z.offset,Q,Y.voice))break}let j=Math.max(0,Number(J.pauseMsAfter||0));if(j>0&&Q===this.speakRunId){if(!await this.waitForPause(j,Q))break}}}async waitForPause(G,Q){return await new Promise((Y)=>setTimeout(Y,G)),Q===this.speakRunId}splitIntoChunks(G){if(G.length<=260)return[{text:G,offset:0}];let Y=this.segmentSentences(G),J=[],X="",j=0;for(let Z of Y){let q=Z.text.trim();if(!q)continue;let B=Z.text.search(/\S/),K=Z.offset+(B===-1?0:B);if(!X){X=q,j=K;continue}let W=`${X} ${q}`;if(W.length<=260)X=W;else J.push({text:X,offset:j}),X=q,j=K}if(X)J.push({text:X,offset:j});return J.length?J:[{text:G,offset:0}]}getHighlightMode(){return(this.config?.providerOptions||{}).highlightMode==="word"?"word":"sentence"}getSegmentationPolicy(){let G=this.config?.providerOptions||{},Q=G.segmenter||{},J=Q.mode!=="regexOnly",X=typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:typeof G.locale==="string"&&G.locale.trim().length>0?G.locale:void 0;return{useSentenceSegmenter:J,useWordSegmenter:J,locale:X}}segmentSentences(G){let Q=this.getSegmentationPolicy();return S7(G,{locale:Q.locale,useSentenceSegmenter:Q.useSentenceSegmenter})}inferWordLength(G,Q){let Y=Math.max(0,Math.min(Q,Math.max(0,G.length-1)));return G.slice(Y).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(G,Q,Y,J){return new Promise((X,j)=>{if(Y!==this.speakRunId){X(!1);return}let Z=new SpeechSynthesisUtterance(G);if(this.utterance=Z,J&&I5(J))Z.voice=J;if(this.config?.rate)Z.rate=this.config.rate;if(this.config?.pitch)Z.pitch=this.config.pitch;let q=!1,B=!1,K=null,W=null,$=()=>{if(this.utterance===Z)this.utterance=null},H=()=>{if(K!==null)clearTimeout(K),K=null},N=()=>{Z.onstart=null,Z.onend=null,Z.onerror=null,Z.onpause=null,Z.onresume=null,Z.onboundary=null},F=(L,D)=>{if(B)return;if(B=!0,H(),N(),$(),W&&this.settlePendingChunk===W)this.settlePendingChunk=null;if(Y===this.speakRunId)this._isPlaying=!1,this._isPaused=!1;if(D)j(D);else X(L)},O=(L)=>Error(L==="ended"?"Browser speech synthesis ended before audio started. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.":`Browser speech synthesis did not start within ${R6/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);W=()=>F(!1),this.settlePendingChunk=W,Z.onstart=()=>{if(Y!==this.speakRunId){F(!1);return}q=!0,H(),this._isPlaying=!0,this._isPaused=!1;try{this.onPlaybackStart?.()}catch(L){console.error("Browser TTS playback-start callback failed",L)}},Z.onend=()=>{if(Y!==this.speakRunId){F(!1);return}if(!q){F(!1,O("ended"));return}F(!0)},Z.onerror=(L)=>{if(Y!==this.speakRunId){F(!1);return}if(L.error==="interrupted"||L.error==="canceled"){F(!1);return}F(!1,Error(`Speech synthesis error: ${L.error}`))},Z.onpause=()=>{if(Y!==this.speakRunId)return;this._isPaused=!0},Z.onresume=()=>{if(Y!==this.speakRunId)return;this._isPaused=!1},Z.onboundary=(L)=>{if(Y!==this.speakRunId)return;if(console.log("[BrowserProvider] Boundary event:",L.name,"charIndex:",L.charIndex,"charLength:",L.charLength),L.name!=="word"||!this.onWordBoundary)return;if(this.getHighlightMode()==="sentence")return;let D=Math.max(0,Math.min(L.charIndex,Math.max(0,G.length-1))),P=Number(L.charLength||0),S=this.inferWordLength(G,D),v=Number.isFinite(P)&&P>0&&P<=80&&D+P<=G.length?P:S,I=G.substring(D,Math.min(G.length,D+v)).trim(),p=Q+D;console.log("[BrowserProvider] Calling onWordBoundary with word:",I,"at position:",p),this.onWordBoundary(I,p,v)},K=setTimeout(()=>{if(B||q||Y!==this.speakRunId)return;F(!1,O("timedOut")),speechSynthesis.cancel()},R6);try{speechSynthesis.speak(Z)}catch(L){F(!1,L instanceof Error?L:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPlaying&&!this._isPaused)speechSynthesis.pause()}resume(){if(this._isPlaying&&this._isPaused)speechSynthesis.resume()}stop(){let G=this.utterance,Q=this._isPlaying||G!==null;if(this.speakRunId+=1,this.settlePendingVoiceWait?.(),this.settlePendingChunk?.(),Q)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}updateSettings(G){if(!this.config)this.config={};if(G.rate!==void 0)this.config.rate=G.rate;if(G.pitch!==void 0)this.config.pitch=G.pitch;if(G.voice!==void 0)this.config.voice=G.voice;if(G.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...G.providerOptions||{}}}onWordBoundary}var T=(G)=>G.trim().replace(/\s+/g," "),U1=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,Z8=(G)=>{if(G.hidden)return!0;if(G.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(G.getAttribute("aria-hidden")==="true")return!0;if(G.hasAttribute("inert"))return!0;let Q=G.classList;if(Q?.contains("sr-only")||Q?.contains("pie-sr-only")||Q?.contains("visually-hidden"))return!0;if(typeof window<"u"){let Y=window.getComputedStyle(G);if(Y.display==="none"||Y.visibility==="hidden")return!0;let J=Number.parseFloat(Y.width||"0"),X=Number.parseFloat(Y.height||"0"),j=Number.isFinite(J)&&Number.isFinite(X)&&J<=1&&X<=1,Z=Y.clipPath.includes("inset(50%")||Y.clipPath.includes("inset(100%")||Y.clip.includes("rect(0px, 0px, 0px, 0px)")||Y.clip.includes("rect(0 0 0 0)");if((Y.position==="absolute"||Y.position==="fixed")&&j&&(Y.overflow==="hidden"||Z))return!0;if(Y.opacity==="0"&&j)return!0}return!1},B1=(G,Q)=>{let Y=G.nodeType===1?G:G.parentElement;while(Y){if(Z8(Y))return!0;if(Q&&Y===Q)break;Y=Y.parentElement}return!1};var y6=new Set(["computer-read-aloud","all"]),T6=new Set([...y6,"screen-reader"]),C6=new Set,v5=(G)=>{let Q=G.getAttribute?.("data-tts-suppress");if(Q===null||Q===void 0)return!1;let Y=Q.trim().toLowerCase();if(y6.has(Y))return!0;if(T6.has(Y))return!1;if(!C6.has(Y))C6.add(Y),console.warn(`[tts] data-tts-suppress="${Q}" is not one of ${Array.from(T6).join(", ")}; suppressing read-aloud for this content anyway, because a suppression attribute that fails open would leak the answer to items where reading is the construct. Correct the value to silence this.`);return!0},W1=(G,Q)=>{let Y=G.nodeType===1?G:G.parentElement;while(Y){if(v5(Y))return!0;if(Q&&Y===Q)break;Y=Y.parentElement}return!1},H7=(G,Q)=>B1(G,Q)||W1(G),j8=(G,Q)=>{if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u"||typeof G.intersectsNode!=="function")return{text:G.toString(),filtered:!1};let Y=[],J=!1,X=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),j=X.nextNode();while(j){let Z=j;if(G.intersectsNode(Z))if(H7(Z,Q))J=!0;else{let q=Z.textContent||"",B=Z===G.startContainer?G.startOffset:0,K=Z===G.endContainer?G.endOffset:q.length;Y.push(q.slice(B,K))}j=X.nextNode()}return{text:Y.join(""),filtered:J}},q8=(G,Q,Y)=>{if(!G||!Q)return!1;if(/\s/.test(G)||/\s/.test(Q))return!1;let J=Y?.boundarySpacingMode??"segmenterPreferred";if(J==="none")return!1;if(J==="segmenterPreferred")try{let Z=globalThis.Intl?.Segmenter;if(typeof Z==="function"){let q=new Z(Y?.locale,{granularity:"word"});if(Array.from(q.segment(`${G}${Q}`)).filter((W)=>W.isWordLike!==!1&&W.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(G),j=/[A-Za-z0-9]/.test(Q);return X&&j},C7=(G,Q)=>{let Y=new Map;if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u")return{text:"",map:Y};let J=[],X=0,j=!0,Z=!1,q=null,B=null,K=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),W=K.nextNode();while(W){let H=W;if(H.parentElement&&!H7(H,G)){let F=H.textContent||"",O=F.match(/\S/),L=O?O[0]:null;if(!j&&!Z&&q8(B,L,Q)){if(J.push(" "),q)Y.set(X,q);X++,Z=!0}for(let D=0;D<F.length;D++){let P=F[D],S=/\s/.test(P);if(j){if(!S)j=!1,J.push(P),Y.set(X,{node:H,offset:D}),q={node:H,offset:D},X++,Z=!1,B=P}else if(S){if(!Z)J.push(" "),Y.set(X,{node:H,offset:D}),q={node:H,offset:D},X++;Z=!0}else J.push(P),Y.set(X,{node:H,offset:D}),q={node:H,offset:D},X++,Z=!1,B=P}}W=K.nextNode()}let $=J.join("").trimEnd();while(Y.has($.length))Y.delete($.length);return{text:$,map:Y}};var h5=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),x6=new Set(["audio","phoneme"]),k6=(G)=>G.replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&nbsp;/g," ").replace(/&#160;/g," ").replace(/&amp;/g,"&"),K1=(G,Q,Y)=>{for(let J=0;J<Q.length;J++)G.push({char:Q[J],rawOffset:Y===null?null:Y+J})},m5=(G,Q,Y)=>{let J=Q.slice(Y).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!J)return 0;return K1(G,k6(J[0]),Y),J[0].length},f6=(G)=>{G.push({char:" ",rawOffset:null})},u5=(G)=>{let Q=new Map,Y=[],J=!0;for(let X of G){if(/\s/.test(X.char)){if(!J&&Y.length>0){if(Y.push(" "),X.rawOffset!==null)Q.set(X.rawOffset,Y.length-1)}J=!0;continue}if(Y.push(X.char),X.rawOffset!==null)Q.set(X.rawOffset,Y.length-1);J=!1}while(Y.length>0&&Y[Y.length-1]===" ")Y.pop();for(let[X,j]of Q)if(j>=Y.length)Q.delete(X);return{text:Y.join(""),rawToSpokenOffsetMap:Q}},p5=(G)=>{return G.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},g5=(G,Q)=>{let Y=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),J=G.match(Y);return k6(J?.[2]??J?.[3]??"")||null},_1=(G)=>{let Q=[],Y=!1,J=!1,X=0;while(X<G.length){let Z=G[X];if(Z!=="<"){if(Z==="&"){let H=m5(Q,G,X);if(H>0){X+=H;continue}}K1(Q,Z,X),X++;continue}let q=G.indexOf(">",X+1);if(q<0){K1(Q,Z,X),X++;continue}J=!0;let B=G.slice(X,q+1),K=p5(B),W=/^<\s*\//.test(B),$=/\/\s*>$/.test(B);if(!W&&K==="sub"){let H=g5(B,"alias");if(!H){Y=!0,X=q+1;continue}K1(Q,H,null);let N=G.toLowerCase().indexOf("</sub>",q+1);X=N>=0?N+6:q+1;continue}if(!W&&K==="break"){f6(Q),X=q+1;continue}if(!W&&x6.has(K)){if(Y=!0,$){X=q+1;continue}}if(K&&!h5.has(K)&&!x6.has(K)&&K!=="break"&&K!=="sub")Y=!0;if(!W&&(K==="p"||K==="s"))f6(Q);X=q+1}let j=u5(Q);return{spokenText:T(j.text),rawToSpokenOffsetMap:j.rawToSpokenOffsetMap,unsupportedSemantic:Y,hasMarkup:J}};var c5=U1(),u6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),l5=[{phrase:["plus","or","minus"],visible:"±",score:8},{phrase:["square","root"],visible:"√",score:8},{phrase:["divided","by"],visible:"/",score:7},{phrase:["all","over"],visible:"/",score:7},{phrase:["equals"],visible:"=",score:7},{phrase:["equal"],visible:"=",score:7},{phrase:["times"],visible:"⁢",score:7},{phrase:["multiplied","by"],visible:"⁢",score:7},{phrase:["over"],visible:"/",score:6},{phrase:["squared"],visible:"²",score:6},{phrase:["squared"],visible:"2",score:4},{phrase:["negative"],visible:"-",score:5},{phrase:["minus"],visible:"-",score:5},{phrase:["plus"],visible:"+",score:5}],U8=(G)=>{let Q=[];for(let Y of G.matchAll(c5)){let J=Y[0],X=Y.index??0;Q.push({text:J,normalized:J.toLowerCase(),start:X,end:X+J.length})}return Q},B8=(G)=>u6.get(G.normalized)||G.normalized,d5=(G,Q)=>{let Y=[];for(let J=0;J<G.length;J++){for(let X=0;X<Q.length;X++){let j=B8(G[J]),Z=B8(Q[X]);if(j===Z)Y.push({spokenStartToken:J,spokenEndToken:J+1,visibleToken:X,score:10})}for(let X of l5){let j=G.slice(J,J+X.phrase.length);if(j.length!==X.phrase.length)continue;if(!j.every((Z,q)=>Z.normalized===X.phrase[q]))continue;for(let Z=0;Z<Q.length;Z++){if(Q[Z].normalized!==X.visible)continue;Y.push({spokenStartToken:J,spokenEndToken:J+X.phrase.length,visibleToken:Z,score:X.score})}}}return Y},i5=(G,Q)=>{let Y=d5(G,Q).sort((B,K)=>G[B.spokenStartToken].start-G[K.spokenStartToken].start||Q[B.visibleToken].start-Q[K.visibleToken].start),J=Array(Y.length).fill(0),X=Array(Y.length).fill(-1);for(let B=0;B<Y.length;B++){let K=Y[B];J[B]=K.score;for(let W=0;W<B;W++){let $=Y[W];if($.spokenEndToken<=K.spokenStartToken&&$.visibleToken<K.visibleToken){let H=K.spokenStartToken-$.spokenEndToken,N=K.visibleToken-$.visibleToken-1,F=Math.max(0,Math.abs(H-N)-2),O=J[W]+K.score-F;if(O>J[B])J[B]=O,X[B]=W}}}let j=-1;for(let B=0;B<J.length;B++)if(j<0||J[B]>J[j])j=B;if(j<0)return[];let Z=[],q=j;while(q>=0)Z.unshift(Y[q]),q=X[q];return Z.map((B)=>{let K=G[B.spokenStartToken],W=G[B.spokenEndToken-1],$=Q[B.visibleToken];return{spokenStart:K.start,spokenEnd:W.end,visibleStart:$.start,visibleEnd:$.end,score:B.score}})},s5=(G,Q,Y)=>{if(G.length===0)return 0;let J=G.length/Math.max(1,Math.min(Q.length,Y.length)),X=G.reduce((j,Z)=>j+Z.score,0)/G.length/10;return Math.min(1,J*X)},V1=(G)=>{let Q=_1(G.speechText),Y=T(G.visibleText),J=Q.spokenText,X=U8(J),j=U8(Y),Z=Q.unsupportedSemantic?[]:i5(X,j),q=s5(Z,X,j),B=J===Y&&J.length>0,K=Z.length===1&&Z[0].score===10&&X.length<=2&&j.length<=2,W=Q.unsupportedSemantic?"region-fallback":B?"exact-word":Z.length>=2||K?q>=0.12?"anchor-span":"region-fallback":"region-fallback",$=Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text";return{speechText:G.speechText,spokenText:J,visibleText:Y,playbackMode:W,boundaryOffsetMode:$,anchors:Z,confidence:q,spokenTokens:X,visibleTokens:j,rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap}},W8=(G,Q)=>G.find((Y)=>Y.start<=Q&&Q<Y.end)||null,p6=(G)=>{if(!G)return null;if(/^<[^>]+>$/.test(G.trim()))return null;let Q=U8(G)[0];if(!Q)return null;return u6.get(Q.normalized)||Q.normalized},I6=(G,Q,Y)=>{let J=p6(Y);if(!Q||!J)return!1;let X=W8(G.spokenTokens,Q.start);if(!X)return!1;return B8(X)===J},v6=(G,Q)=>{let Y=G.rawToSpokenOffsetMap.get(Q);if(Y!==void 0)return Y;for(let J=Q;J<G.speechText.length;J++){let X=G.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(G.speechText[J]===">")break}return null},h6=(G,Q,Y)=>{let J=v6(G,Q);if(J===null)return null;let X=v6(G,Math.max(Q,Q+Y-1)),j=W8(G.spokenTokens,J),Z=X!==null&&X>=J?X-J+1:j?j.end-J:Y;return{start:J,length:Math.max(1,Z)}},m6=(G,Q,Y)=>{if(Q<0||Q>=G.spokenText.length)return null;let J=W8(G.spokenTokens,Q);if(!J)return null;return{start:Q,length:Math.min(Y,J.end-Q)}},g6=(G,Q,Y=1,J)=>{if(G.boundaryOffsetMode==="unsupported"||!Number.isFinite(Q))return null;let X=Math.max(1,Number.isFinite(Y)?Y:1);if(J&&/^<[^>]+>$/.test(J.trim()))return null;if(G.boundaryOffsetMode==="raw-ssml"){let j=h6(G,Q,X),Z=m6(G,Q,X);if(J){if(I6(G,j,J))return j;if(I6(G,Z,J))return Z;if(p6(J))return null}return j||Z}return m6(G,Q,X)||h6(G,Q,X)},c6=(G,Q)=>{if(G.playbackMode==="region-fallback")return null;let Y=G.anchors.find((j)=>j.spokenStart<=Q&&Q<j.spokenEnd);if(Y)return{start:Y.visibleStart,end:Y.visibleEnd};let J=null,X=null;for(let j of G.anchors){if(j.spokenEnd<=Q){J=j;continue}if(j.spokenStart>Q){X=j;break}}if(J&&X)return{start:Math.min(J.visibleStart,X.visibleStart),end:Math.max(J.visibleEnd,X.visibleEnd)};return null};var n5=new Map([["+",["plus"]],["-",["minus","negative"]],["−",["minus","negative"]],["×",["times","multiplied by"]],["÷",["divided by"]],["=",["equals","equal to"]],["≠",["is not equal to","not equal to"]],["≈",["approximately equals"]],["≤",["less than or equal to"]],["≥",["greater than or equal to"]],["<",["less than"]],[">",["greater than"]],["∠",["angle"]],["△",["triangle"]],["□",["box"]],["○",["circle"]],["°",["degrees","degree"]],["%",["percent"]],["'",["prime"]],["′",["prime"]],["•",["times"]],["·",["times"]],["⁢",["times","multiplied by"]]]),r5=new Map([["⁡","function-application"],["⁢","implicit-multiply"],["⁣","invisible-separator"],["⁤","invisible-plus"]]),l6=new Map([["2",["squared"]],["3",["cubed"]]]),o5=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),a5=(G)=>G.replace(/\s+/g," ").trim(),D7=(G)=>(G.localName||G.tagName||"").toLowerCase(),t5=(G)=>G.nodeType===Node.ELEMENT_NODE,y7=(G)=>Array.from(G.childNodes).filter(t5),K8=(G)=>a5(G.textContent||""),Q7=(G,Q)=>({type:"element-range",quality:Q,element:G}),e5=(G)=>{switch(G){case"mi":return"identifier";case"mn":return"number";case"mo":return"operator";case"mtext":case"ms":return"text";case"mspace":return"space";default:return"unknown"}},GG=(G,Q)=>{if(Q==="operator"){if(G==="−")return"-";return G}return G.toLowerCase()},QG=(G,Q,Y)=>{if(Y==="fraction")return["over","divided by"];if(Y==="superscript")return l6.get(G)??[];if(G==="|")return["absolute value"];if(Q==="operator")return n5.get(G)||[];return[]},A7=(G)=>{let Q=G.normalized??GG(G.text,G.kind||"unknown");return{id:`math-token-${G.state.nextId++}`,kind:G.kind,role:G.role,text:G.text,normalized:Q,spokenAliases:QG(G.text,G.kind,G.role),sourceElement:G.sourceElement,path:G.path,target:G.target||Q7(G.sourceElement,"element-range"),optional:G.optional}},N7=(G,Q,Y="tokens")=>{G[Y].push(Q)},d6=(G,Q,Y)=>{y7(G).forEach((J,X)=>Y7(J,Q,`${Y}/${D7(J)}[${X}]`))},YG=(G,Q,Y)=>{let J=y7(G);if(J[0])Y7(J[0],Q,`${Y}/numerator`);if(N7(Q,A7({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:G,path:Y,target:Q7(G,"element-range")})),J[1])Y7(J[1],Q,`${Y}/denominator`)},JG=(G,Q,Y)=>{let J=G.getAttribute("open")||"(",X=G.getAttribute("close")||")";N7(Q,A7({state:Q,kind:"operator",role:J==="|"?"absolute-value-fence":"open-fence",text:J,sourceElement:G,path:`${Y}/open`,target:Q7(G,"element-range")})),d6(G,Q,Y),N7(Q,A7({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:G,path:`${Y}/close`,target:Q7(G,"element-range")}))},XG=(G,Q,Y)=>{let J=y7(G);if(J[0])Y7(J[0],Q,`${Y}/base`);let X=J[1];if(!X)return;let j=K8(X);if(l6.has(j)){N7(Q,A7({state:Q,kind:"structure",role:"superscript",text:j,normalized:j,sourceElement:X,path:`${Y}/exponent`,target:Q7(G,"element-range")}));return}Y7(X,Q,`${Y}/exponent`)},ZG=(G,Q,Y,J)=>{N7(Q,A7({state:Q,kind:"structure",role:J,text:K8(G)||J,normalized:`\x00${J}`,sourceElement:G,path:Y,target:Q7(G,"element-range")}))},jG=(G,Q,Y)=>{let J=0;for(let X of y7(G)){if(D7(X)==="mtr"||D7(X)==="mlabeledtr")J++,N7(Q,A7({state:Q,kind:"layout",role:"table-row",text:`row-${J}`,normalized:`row-${J}`,sourceElement:X,path:`${Y}/row[${J}]`,target:Q7(X,"region-fallback")}),"layoutTargets");Y7(X,Q,`${Y}/${D7(X)}[${J}]`)}},qG=(G,Q,Y)=>{let J=K8(G);if(!J)return;let X=e5(D7(G)),j=X==="operator"?r5.get(J):void 0,Z=j??(X==="operator"&&(J==="("||J===")")?"grouping-fence":X);N7(Q,A7({state:Q,kind:X,role:Z,text:J,sourceElement:G,path:Y,target:j&&G.parentElement?Q7(G.parentElement,"region-fallback"):void 0,optional:Boolean(j)||Z==="grouping-fence"}))},Y7=(G,Q,Y)=>{let J=D7(G);switch(J){case"annotation":case"annotation-xml":return;case"semantics":{let X=y7(G).find((j)=>{let Z=D7(j);return Z!=="annotation"&&Z!=="annotation-xml"});if(X)Y7(X,Q,`${Y}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":qG(G,Q,Y);return;case"mfrac":YG(G,Q,Y);return;case"msup":XG(G,Q,Y);return;case"mfenced":JG(G,Q,Y);return;case"mtable":jG(G,Q,Y);return;case"mphantom":return;case"maction":{let X=y7(G)[0];if(X)Y7(X,Q,`${Y}/action`);return}default:{let X=o5.get(J);if(X){ZG(G,Q,Y,X);return}d6(G,Q,Y)}}},i6=(G)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return Y7(G,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:Q7(G,"region-fallback")}};var s6=(G)=>{if(!G.boundary)return null;return G.alignment.segments.find((Y)=>Y.speechTokenIds.includes(G.boundary.token.id))?.target||null};var UG=(G)=>{let Q=[],Y=new Set,J=(X)=>{let j=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(j.length===0)return;let Z=j.join(" ");if(Y.has(Z))return;Y.add(Z),Q.push(j)};J(G.normalized);for(let X of G.spokenAliases)J(X);return Q},n6=(G,Q,Y)=>{let J=0;for(let X of Y){if(X.length<=J)continue;let j=!0;for(let Z=0;Z<X.length;Z++){let q=G[Q+Z];if(!q||q.normalized.toLowerCase()!==X[Z]){j=!1;break}}if(j)J=X.length}return J},BG=(G,Q)=>{let Y=[],J=0;for(let X of Q){let j=UG(X);if(X.optional){let Z=n6(G,J,j);if(Z>0)Y.push({speechTokens:G.slice(J,J+Z),math:X}),J+=Z;continue}while(J<G.length){let Z=n6(G,J,j);if(Z>0){Y.push({speechTokens:G.slice(J,J+Z),math:X}),J+=Z;break}J++}}return Y},WG=(G,Q,Y)=>{let J=Y.filter((Z)=>!Z.optional).length,X=G.filter((Z)=>!Z.math.optional).length,j=G.reduce((Z,q)=>Z+q.speechTokens.length,0);return J>0&&X===J&&j===Q.length},KG=(G)=>G.map(({speechTokens:Q,math:Y})=>({speechTokenIds:Q.map((J)=>J.id),mathTokenIds:[Y.id],score:1,confidence:1,target:Y.target})),r6=(G)=>{let Q=G.minExactWordConfidence??0.95,Y=BG(G.speech.tokens,G.math.tokens),J=WG(Y,G.speech.tokens,G.math.tokens)?1:0;return{segments:J>=Q?KG(Y):[],confidence:J,fallbackTarget:G.math.expressionTarget}};var o6=U1(),_G=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),a6=(G)=>{let Q=G.toLowerCase();return _G.get(Q)||Q},VG=(G)=>{let Q=[];for(let Y of G.matchAll(o6)){let J=Y[0],X=Y.index??0;Q.push({id:`speech-token-${Q.length}`,text:J,normalized:a6(J),start:X,end:X+J.length,sourceStart:X,sourceEnd:X+J.length,coordinateSystem:"normalized-speech"})}return Q},F7=(G)=>{let Q=_1(G.speechText);return{speechText:G.speechText,spokenText:Q.spokenText,tokens:VG(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},$8=(G)=>{if(!G)return null;if(/^<[^>]+>$/.test(G.trim()))return null;let Q=G.match(o6);if(!Q?.[0])return null;return a6(Q[0])},$G=(G,Q)=>G.find((Y)=>Y.start<=Q&&Q<Y.end)||null,HG=(G,Q)=>{let Y=G.rawToSpokenOffsetMap.get(Q);if(Y!==void 0)return Y;for(let J=Q;J<G.speechText.length;J++){let X=G.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(G.speechText[J]===">")break}return null},_8=(G,Q,Y)=>{if(Q===null)return null;let J=$G(G.tokens,Q);if(!J)return null;return{token:J,start:Q,length:Math.max(1,Math.min(Y,J.end-Q)),confidence:0.75}},V8=(G,Q)=>{let Y=$8(Q);return Boolean(G&&Y&&G.token.normalized===Y)},H8=(G)=>{if(G.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(G.position)||G.boundaryWord&&/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Q=Math.max(1,Number.isFinite(G.length)?G.length:1),Y=_8(G.tokenization,HG(G.tokenization,G.position),Q),J=_8(G.tokenization,G.position>=0&&G.position<G.tokenization.spokenText.length?G.position:null,Q);if(V8(Y,G.boundaryWord))return{...Y,confidence:1};if(V8(J,G.boundaryWord))return{...J,confidence:1};if(G.boundaryWord&&$8(G.boundaryWord))return null;return G.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||J:J||Y},t6=(G)=>{if(G.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(G.position)||G.boundaryWord&&/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Q=Math.max(1,Number.isFinite(G.length)?G.length:1),Y=_8(G.tokenization,G.position>=0&&G.position<G.tokenization.spokenText.length?G.position:null,Q);if(V8(Y,G.boundaryWord))return{...Y,confidence:1};if(G.boundaryWord&&$8(G.boundaryWord))return null;return Y};var x7=(G)=>{let Q=F7({speechText:G.speechText}),Y=i6(G.mathElement);return{speech:Q,math:Y,result:r6({speech:Q,math:Y})}};var e6=(G,Q)=>{let Y=t6({tokenization:G.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return s6({alignment:G.result,boundary:Y})},G0=(G,Q)=>{if(!Q.boundaryWord||/^<[^>]+>$/.test(Q.boundaryWord.trim()))return null;let Y=F7({speechText:Q.boundaryWord}).tokens[0];if(!Y)return null;let J=G.math.tokens.filter((X)=>{let j=Y.normalized.toLowerCase();return X.normalized.toLowerCase()===j||X.spokenAliases.some((Z)=>Z.toLowerCase()===j)});return J.length===1?J[0].target:null};var DG=new Set(["math","maction","menclose","merror","mfenced","mfrac","mi","mmultiscripts","mn","mo","mover","mpadded","mphantom","mprescripts","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msubsup","msup","mtable","mtd","mtext","mtr","munder","munderover","none","semantics","annotation","annotation-xml"]),AG=new Set(["accent","accentunder","align","bevelled","class","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","encoding","fence","height","href","id","largeop","length","linethickness","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","width","xmlns","xml:lang"]),Q0=(G)=>G.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),NG=(G)=>Q0(G).replace(/"/g,"&quot;"),FG=(G,Q)=>{let Y=G.toLowerCase(),J=Q.trim().toLowerCase();if(Y.startsWith("on"))return!0;if(!AG.has(Y))return!0;if(J.includes("javascript:"))return!0;if(J.includes("data:text/html"))return!0;return!1},MG=(G)=>{let Q=G.localName.toLowerCase();if(!DG.has(Q))return!1;let Y=G.namespaceURI;return!Y||Y==="http://www.w3.org/1998/Math/MathML"||Y==="http://www.w3.org/1999/xhtml"},Y0=(G)=>{if(G.nodeType===Node.TEXT_NODE)return Q0(G.textContent||"");if(G.nodeType===Node.COMMENT_NODE)return"";if(G.nodeType!==Node.ELEMENT_NODE)return null;let Q=G;if(!MG(Q))return null;let Y=Q.localName.toLowerCase(),J=[];for(let Z of Array.from(Q.attributes)){let q=Z.name.toLowerCase();if(FG(q,Z.value))continue;if(q==="xmlns"&&Z.value!=="http://www.w3.org/1998/Math/MathML")return null;J.push(`${q}="${NG(Z.value)}"`)}if(Y==="math"&&!J.some((Z)=>Z.startsWith("xmlns=")))J.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let Z of Array.from(Q.childNodes)){let q=Y0(Z);if(q===null)return null;X.push(q)}let j=J.length>0?` ${J.join(" ")}`:"";return`<${Y}${j}>${X.join("")}</${Y}>`},zG=(G)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(G,"application/xml");return null},$1=(G)=>{let Q=String(G||"").trim();if(!Q)return null;let Y=zG(Q);if(!Y)return null;if(Y.getElementsByTagName("parsererror").length>0)return null;let J=Y.documentElement;if(!J||J.localName.toLowerCase()!=="math")return null;return Y0(J)};var J0=(G)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:G}),X0=(G)=>G.classList?.contains("MathJax")||G.tagName?.toLowerCase()==="mjx-container",Z0=(G)=>G.tagName?.toLowerCase()==="mjx-assistive-mml",j0=(G)=>{let Q=G.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},OG=(G)=>{let Q=G.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},PG=(G)=>{return G.querySelector("mjx-assistive-mml math")?.outerHTML||null},LG=(G)=>{if(G.tagName.toLowerCase()==="math")return $1(G.outerHTML);let Q=OG(G);if(Q){let Y=$1(Q);if(Y)return Y}if(X0(G)){let Y=PG(G);if(Y){let J=$1(Y);if(J)return J}}return null};var wG=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),RG=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),EG=(G,Q)=>{let Y=G.parentElement,J=null;while(Y&&Y!==Q){let X=(Y.getAttribute("role")||"").toLowerCase(),j=Y.tagName.toUpperCase();if(wG.has(j)||RG.has(X)){J=Y;break}Y=Y.parentElement}return J||Q},bG=(G)=>Boolean(typeof G.querySelector==="function"&&G.querySelector("math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||G.tagName?.toLowerCase()==="math"||G.hasAttribute?.("data-mathml")||X0(G),M7=(G,Q,Y)=>{if(/[.,;:!?]/.test(Q)&&G.chars.length>0&&G.chars[G.chars.length-1]===" ")G.chars.pop(),G.position--,G.map.delete(G.position);if(G.chars.push(Q),Y)G.map.set(G.position,Y),G.lastMapped=Y;else if(G.lastMapped)G.map.set(G.position,G.lastMapped);G.position++},q0=(G,Q)=>{if(G.inLeadingWhitespace||G.lastCharWasWhitespace||G.chars.length===0)return!1;let Y=G.chars[G.chars.length-1];return q8(Y,Q,G.options)},U0=(G,Q)=>{let Y=Q.textContent||"",J=!1;for(let X=0;X<Y.length;X++){let j=Y[X],Z=/\s/.test(j);if(G.inLeadingWhitespace){if(!Z)G.inLeadingWhitespace=!1,M7(G,j,{node:Q,offset:X}),J=!0,G.lastCharWasWhitespace=!1;continue}if(Z){if(!G.lastCharWasWhitespace)M7(G," ",{node:Q,offset:X});G.lastCharWasWhitespace=!0;continue}if(!J&&q0(G,j))M7(G," ",{node:Q,offset:X});M7(G,j,{node:Q,offset:X}),J=!0,G.lastCharWasWhitespace=!1}},SG=(G,Q)=>{for(let Y=0;Y<Q.text.length;Y++){let J=Q.text[Y],X=/\s/.test(J),j=Q.map.get(Y)||null,Z=j?.node||G.lastMapped?.node||null,q=j?.offset??G.lastMapped?.offset??0,B=j?{node:j.node,offset:j.offset}:Z?{node:Z,offset:q}:null;if(G.inLeadingWhitespace){if(X)continue;G.inLeadingWhitespace=!1}if(X){if(!G.lastCharWasWhitespace)M7(G," ",B);G.lastCharWasWhitespace=!0;continue}if(Y===0&&q0(G,J))M7(G," ",B);if(M7(G,J,B),G.lastCharWasWhitespace=!1,j)G.map.set(G.position-1,{node:j.node,offset:j.offset}),G.lastMapped={node:j.node,offset:j.offset};else if(Z)G.map.set(G.position-1,{node:Z,offset:q})}},TG=(G)=>{if(typeof DOMParser>"u")return"";let Q=new DOMParser().parseFromString(G,"application/xml");if(Q.getElementsByTagName("parsererror").length>0)return"";let Y=[],J=(X)=>{if(X.nodeType===3){let Z=X.textContent||"";if(Z.trim())Y.push(Z);return}if(X.nodeType!==1)return;let j=X;if(j0(j))return;for(let Z of Array.from(j.childNodes))J(Z)};return J(Q.documentElement),T(Y.join(" "))},CG=(G,Q,Y)=>{let J=J0(Y),X=(q)=>{if(H7(q,G))return;if(q.nodeType===3){U0(J,q);return}if(q.nodeType!==1)return;let B=q;if(Z0(B)||j0(B))return;for(let K of Array.from(B.childNodes))X(K)};X(G),B0(J);let j=T(J.chars.join(""));if(j)return{text:j,map:J.map};let Z=TG(Q);if(!Z)return C7(G,Y);return{text:Z,map:new Map}},B0=(G)=>{while(G.chars.length>0&&/\s/.test(G.chars[G.chars.length-1]))G.chars.pop(),G.position--,G.map.delete(G.position)},yG=(G,Q)=>{let Y=J0(Q),J=[],X=0,j,Z=!1,q=()=>{let W=T(Y.chars.slice(X,Y.chars.length).join(""));if(W)J.push({type:"text",text:W,sourceElement:j});X=Y.chars.length,j=void 0},B=(W)=>{if(H7(W,G))return;if(W.nodeType===Node.TEXT_NODE){let N=EG(W,G);if(j&&N!==j)q();j=N,U0(Y,W);return}if(W.nodeType!==Node.ELEMENT_NODE)return;let $=W;if(Z0($))return;let H=LG($);if(H){q();let N=CG($,H,Q);SG(Y,N);let F=T(N.text);J.push({type:"math",mathml:H,fallbackText:F,sourceElement:$}),X=Y.chars.length,Z=!0;return}for(let N of Array.from($.childNodes))B(N)};for(let W of Array.from(G.childNodes))B(W);B0(Y),q();let K=Y.chars.join("");while(Y.map.has(K.length))Y.map.delete(K.length);return{visibleText:K,map:Y.map,chunks:J,containsMathMarkup:Z}},z7=(G,Q)=>{if(!bG(G)){let{text:Y,map:J}=C7(G,Q);return{visibleText:Y,map:J,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return yG(G,Q)};var D8=null,W0=Promise.resolve(),fG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",kG=async()=>{if(!D8)D8=import("speech-rule-engine").then((G)=>{let Q=G.default||G;if(!Q||typeof Q.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Q});return D8},IG=(G)=>G==="en"?"clearspeak":"mathspeak",K0=(G)=>!!G&&typeof G==="object"&&!Array.isArray(G),_0=(G)=>typeof G==="string"&&G.trim()?G.trim():void 0,O7=(G)=>{if(!K0(G))return;let Q=_0(G.domain),Y=_0(G.style),J=K0(G.engineOptions)?G.engineOptions:void 0;if(!Q&&!Y&&!J)return;return{...Q?{domain:Q}:{},...Y?{style:Y}:{},...J?{engineOptions:J}:{}}},vG=async(G,Q,Y,J)=>{let X=fG(Q),j=O7(J);await G.setupEngine?.({...j?.engineOptions||{},locale:X,domain:j?.domain||IG(X),...j?.style?{style:j.style}:{},modality:"speech",markup:Y}),await G.engineReady?.()},hG=async(G)=>{let Q=W0.then(G,G);return W0=Q.then(()=>{return},()=>{return}),Q},V0=async(G,Q,Y,J,X)=>hG(async()=>{return await vG(G,Y,J,X),G.toSpeech(Q)}),mG=(G)=>G.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),uG=async(G,Q,Y,J)=>{try{let X=mG(await V0(G,Q,Y,"ssml",J));return X.includes("<speak")?X:null}catch(X){return console.debug("[TTSService] Math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},H1=async(G,Q={})=>{if(!G.some((K)=>K.type==="math"))return{speechText:T(G.map((K)=>K.type==="text"?K.text:K.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let Y=null,J=!1,X=!1,j=Q.loadSre||kG,Z=[];for(let K of G){if(K.type==="text"){Z.push(K.text);continue}try{if(!Y)Y=await j();let W=T(await V0(Y,K.mathml,Q.language,"none",Q.mathSpeech));if(W){Z.push(W),J=!0;continue}X=!0,Z.push(K.fallbackText)}catch(W){X=!0,console.debug("[TTSService] Math speech generation failed; using visible fallback",{message:W instanceof Error?W.message:String(W)}),Z.push(K.fallbackText)}}let q=T(Z.join(" ")),B;if(Q.produceSsml&&Y&&J&&G.length===1&&G[0].type==="math")B=await uG(Y,G[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:q,usedMathSpeech:J,usedFallback:X,ssml:B}};var pG=(G,Q)=>H1([G],Q),gG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",cG=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),lG=new Set(["heading","listitem","option","radio"]),dG=(G)=>{if(G.type!=="text"||!G.sourceElement)return!1;let Q=G.sourceElement.tagName.toUpperCase(),Y=(G.sourceElement.getAttribute("role")||"").toLowerCase();return cG.has(Q)||lG.has(Y)},A8=async(G)=>{let Q=G.resolveMathSpeech??pG,{visibleText:Y}=G,J=[],X=0,j=(q)=>{let B=T(q),K=Y.indexOf(B,X),W=K>=0?K:X,$=W+B.length;return X=$,{start:W,end:$}},Z=[];for(let q=0;q<G.chunks.length;q++){let B=G.chunks[q];if(B.type==="text"){let N=dG(B)?[{text:B.text,offset:0}]:S7(B.text,{locale:G.language});for(let F of N){let O=T(F.text);if(!O)continue;let L=j(O);J.push({sourceChunkIndex:q,segment:{kind:"prose",spokenText:O,visibleText:O,visibleSpan:L}}),Z.push(O)}continue}let K=j(B.fallbackText),W=await Q(B,{language:G.language,produceSsml:G.produceSsml,mathSpeech:G.mathSpeech}),$=!W.speechText,H=W.speechText||B.fallbackText;J.push({sourceChunkIndex:q,segment:{kind:"math",spokenText:H,mathml:B.mathml,fallbackText:B.fallbackText,visibleSpan:K,usedFallback:$,ssml:W.ssml}}),Z.push(H)}return{segments:J,locale:gG(G.language),visibleText:Y,plainSpeechText:T(Z.join(" "))}};var iG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",sG="sre-v1",nG=256,N8=(G)=>{if(Array.isArray(G))return`array:[${G.map(N8).join(",")}]`;if(G&&typeof G==="object")return`object:{${Object.entries(G).sort(([Q],[Y])=>Q.localeCompare(Y)).map(([Q,Y])=>`${JSON.stringify(Q)}:${N8(Y)}`).join(",")}}`;if(G===null)return"null:null";if(typeof G>"u")return"undefined:";if(typeof G==="function")return`function:${G.name||"anonymous"}`;if(typeof G==="symbol")return`symbol:${String(G)}`;if(typeof G==="bigint")return`bigint:${G.toString()}`;if(typeof G==="number")return Number.isFinite(G)?`number:${G}`:`number:${String(G)}`;return`${typeof G}:${JSON.stringify(G)}`},$0=(G,Q,Y,J)=>`${sG}\x00${iG(G)}\x00${Q?"ssml":"plain"}\x00${N8(Y??null)}\x00${J}`,F8=(G={})=>{let Q=Math.max(1,G.maxEntries??nG),Y=G.resolve??((j,Z)=>H1([j],Z)),J=new Map,X=(j,Z)=>{J.delete(j),J.set(j,Z);while(J.size>Q){let q=J.keys().next().value;if(q!==void 0)J.delete(q)}};return async(j,Z)=>{let q=O7(Z.mathSpeech),B=Z.produceSsml===!0,K=$0(Z.language,B,q,j.mathml),W=J.get(K);if(W)return J.delete(K),J.set(K,W),W;let $=await Y(j,{...Z,mathSpeech:q});if(B&&$.ssml&&Q>1)X($0(Z.language,!1,q,j.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(K,$),$}};var rG=(G)=>{if(!G||/^<[^>]+>$/.test(G.trim()))return null;return F7({speechText:G}).tokens[0]?.normalized||null},oG=(G,Q)=>{let Y=F7({speechText:G.speechText});if(!Number.isFinite(Q.position))return{boundary:null,spokenText:Y.spokenText};let J=H8({tokenization:Y,position:Q.position,length:Q.length,boundaryWord:Q.word});return{boundary:J?{start:J.start,length:J.length}:null,spokenText:Y.spokenText}},aG=(G,Q,Y)=>{if(!Y)return!0;return F7({speechText:G}).tokens.find((X)=>X.start<=Q&&Q<X.end)?.normalized===Y},H0=(G,Q)=>{let Y=rG(Q.word);if(G.id!==Q.chunkId)return{chunkId:Q.chunkId,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Q.providerOffsetSpace==="unknown"||G.offsetSpace==="unsupported")return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let J,X;if(G.catalogAlignment)J=g6(G.catalogAlignment,Q.position,Q.length,Q.word),X=G.catalogAlignment.spokenText;else{let j=oG(G,Q);J=j.boundary,X=j.spokenText}if(!J)return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};if(!aG(X,J.start,Y))return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to matching word"};return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:J.start,chunkSpokenEnd:J.start+J.length,confidence:Y?1:0.75,reason:G.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var P7=(G)=>{if(G.semanticTarget)return{activeTarget:G.semanticTarget,regionTarget:G.regionTarget,quality:G.semanticTarget.quality==="exact-word"?"exact-word":G.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:G.confidence,reason:G.reason};if(G.expressionTarget)return{activeTarget:G.expressionTarget,regionTarget:G.regionTarget,quality:"expression",confidence:G.confidence,reason:G.reason};return{activeTarget:null,regionTarget:G.regionTarget,quality:"region",confidence:G.confidence,reason:G.reason}};var A0=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),M8="mi,mn,mo,mtext",N0="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",F0=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),M0=(G)=>{if(G.type==="text-range")return G.node.parentElement;return G.element},D1=(G)=>{let Q=G;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},D0=(G)=>{if(!G)return!1;if(D1(G))return!1;return!B1(G)},z0=(G)=>{let Q=G.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},z8=(G)=>{let Q=G;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},O0=(G,Q)=>{if(G.length===0)return!1;if(G.length!==Q.length)return!1;for(let Y=0;Y<G.length;Y+=1){let J=A0.get(G[Y].localName.toLowerCase());if(!J)return!1;if(Q[Y].localName.toLowerCase()!==J)return!1}return!0},tG=(G,Q)=>{if(!G)return null;if(!A0.has(G.localName.toLowerCase()))return null;if(Q.querySelector(F0))return null;let Y=z8(G),J=Q.querySelector("mjx-math");if(!Y||!J)return null;let X=Array.from(Y.querySelectorAll(M8)),j=X.indexOf(G);if(j<0)return null;let Z=Array.from(J.querySelectorAll(N0));if(!O0(X,Z))return null;let q=Z[j];if(!q||!z0(q))return null;return q},P0=(G)=>{let Q=D1(G);if(Q){if(Q.querySelector(F0))return"expression";let X=z8(G)??G,j=Q.querySelector("mjx-math");if(!j)return"expression";let Z=Array.from(X.querySelectorAll(M8)),q=Array.from(j.querySelectorAll(N0));if(!O0(Z,q))return"expression";return q.some((B)=>z0(B))?"token":"expression"}let Y=z8(G)??G;return Array.from(Y.querySelectorAll(M8)).some((X)=>!B1(X))?"token":"expression"},O8=(G)=>{let Q=M0(G),Y=D1(Q);if(Y){let J=tG(Q,Y);if(J)return{type:"element",quality:"semantic-token",element:J};return{type:"element",quality:"expression",element:Y}}if(G.type==="text-range"){if(!D0(G.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:G.node,startOffset:G.startOffset,endOffset:G.endOffset}}if(!D0(G.element))return null;return{type:"element",quality:G.quality==="region-fallback"?"expression":"semantic-token",element:G.element}},L0=O8,w0=()=>{let G=new WeakMap;return(Q)=>{let Y=M0(Q),J=D1(Y);if(!Y||!J)return O8(Q);if(G.has(Y))return G.get(Y)??null;let X=O8(Q);return G.set(Y,X),X}};var R0=(G,Q,Y,J=G.mathAlignments,X=L0)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let j=null;for(let Z of J){let q=e6(Z.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:Y.word})||G0(Z.alignment,{boundaryWord:Y.word});if(!q)continue;let B=X(q);if(!B)continue;if(B.quality==="semantic-token")return B;j??=B}return j};var A1=(G,Q,Y)=>{if(!G||typeof document>"u")return null;if(Y<=Q)return null;let J=G.get(Q),X=G.get(Math.max(Q,Y-1));if(!J)return null;if(!X)X=J;try{let j=document.createRange();return j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),j}catch{return null}};var E0=(G,Q)=>{if(!G.catalogAlignment||Q.chunkSpokenStart===null)return null;let Y=c6(G.catalogAlignment,Q.chunkSpokenStart);if(!Y)return null;let J=A1(G.visibleMap,Y.start,Y.end);if(!J)return null;return{type:"range",quality:G.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:J}};var eG=(G)=>G.regionRange?{type:"range",quality:"region",range:G.regionRange}:G.regionElement?{type:"element",quality:"region",element:G.regionElement}:null,b0=(G,Q=G.chunk.mathAlignments)=>{if(Q.length!==1)return null;let Y=Q[0]?.alignment.result.fallbackTarget;return Y?G.renderedMathTargetResolver(Y):null},GQ=(G,Q)=>{if(!G)return Q.mathAlignments;return Q.mathAlignments.filter(({element:Y})=>{try{if(G.type==="range")return G.range.intersectsNode(Y);if(G.type==="element")return G.element===Y||G.element.contains(Y);return G.node.parentElement?.contains(Y)||!1}catch{return!1}})},S0=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),T0=(G)=>G.length===1?G[0].element:null,QQ=(G,Q)=>Q.length>0&&Q.every(({element:Y})=>G.mathCapabilityByElement.get(Y)==="token"),YQ=3,JQ=(G,Q,Y)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:J,endContainer:X}=Q.range;if(J===X&&J.nodeType===YQ)return!1;return Y.some(({element:Z})=>G.mathCapabilityByElement.get(Z)==="token"&&Z.contains(J)&&Z.contains(X))},XQ=(G,Q)=>({chunk:G,regionTarget:eG(G),renderedMathTargetResolver:w0(),mathCapabilityByElement:new Map(G.mathAlignments.map(({element:Y})=>[Y,Q?P0(Y):"expression"])),heldTokenByElement:new Map}),C0=(G)=>{let Q=G.mathTokenHighlighting!==!1,Y=new Map(G.chunks.map((J)=>[J.id,XQ(J,Q)]));return{chunks:G.chunks,resolveInitial(J){let X=Y.get(J);if(!X)return S0();let j=X.chunk.mathAlignments,Z=j.length===1?j[0].element:null,q=Z?X.mathCapabilityByElement.get(Z):null;if(q==="expression")return P7({semanticTarget:null,expressionTarget:b0(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return P7({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:q==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(J){let X=Y.get(J.chunkId);if(!X)return S0();let{chunk:j}=X,Z=H0(j,J),q=E0(j,Z),B=GQ(q,j),K=(!q||B.length>0?R0(j,Z,J,B,X.renderedMathTargetResolver):null)||null,W=Q&&K&&K.quality!=="expression"?K:null,$=K&&K.quality==="expression"?K:null;if(W){let H=T0(B);if(H)X.heldTokenByElement.set(H,W);return P7({semanticTarget:W,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}if(q&&(Q?!JQ(X,q,B):B.length===0))return P7({semanticTarget:q,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason});if(QQ(X,B)){let H=T0(B),N=H?X.heldTokenByElement.get(H)??null:null;return P7({semanticTarget:N,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:N?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return P7({semanticTarget:null,expressionTarget:$??b0(X,B),regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}}};var ZQ=(G)=>{if(G.alignment?.boundaryOffsetMode)return G.alignment.boundaryOffsetMode;let Q=G.mathAlignment?.speech.boundaryOffsetSpace;if(Q)return Q;return"plain-spoken-text"},jQ=(G)=>{if(G.mathAlignments?.length)return G.mathAlignments;if(G.mathAlignment&&G.sourceElement)return[{element:G.sourceElement,alignment:G.mathAlignment}];return[]},y0=(G)=>{return(G.chunks&&G.chunks.length?G.chunks:[{speechText:G.speechText||"",visibleText:G.visibleText||G.speechText||"",sourceElement:G.sourceElement||G.contentRoot,regionElement:G.regionElement||G.sourceElement||G.contentRoot,regionRange:G.regionRange,visibleMap:G.visibleMap}]).map((Y,J)=>({id:`tts-chunk-${J}`,speechText:Y.speechText,visibleText:Y.visibleText,sourceElement:Y.sourceElement,contentRoot:G.contentRoot,regionElement:Y.regionElement??Y.sourceElement,regionRange:Y.regionRange,visibleMap:Y.visibleMap,catalogAlignment:Y.alignment,mathAlignments:jQ(Y),offsetSpace:ZQ(Y)}))};var qQ=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),N1=(G,Q)=>{let Y=G.closest(qQ);if(Y&&Q.contains(Y))return Y;return G};var UQ=(G,Q,Y)=>{let J=new Map;for(let X=Q;X<Y;X++){let j=G.get(X);if(j)J.set(X-Q,j)}return J},P8=async(G)=>{let Q=z7(G.contentRoot,G.textProcessingOptions),Y=await A8({chunks:Q.chunks,visibleText:Q.visibleText,language:G.language,mathSpeech:G.mathSpeech,produceSsml:G.produceSsml,resolveMathSpeech:G.resolveMathSpeech});return{plan:{items:Y.segments.map(({segment:X,sourceChunkIndex:j})=>{let Z=Q.chunks[j];if(X.kind==="prose"){let B=Z?.type==="text"?Z.sourceElement??G.contentRoot:G.contentRoot;return{segment:X,anchor:{sourceElement:B,regionElement:N1(B,G.contentRoot),visibleMap:UQ(Q.map,X.visibleSpan.start,X.visibleSpan.end)}}}let q=Z?.type==="math"?Z.sourceElement??null:null;return{segment:X,anchor:{sourceElement:q,regionElement:q}}}),locale:Y.locale,visibleText:Y.visibleText,plainSpeechText:Y.plainSpeechText},containsMathMarkup:Q.containsMathMarkup,visibleText:Q.visibleText}};var BQ=(G,Q)=>{let Y=V1({speechText:G.spokenText,visibleText:G.spokenText});return{speechText:G.spokenText,visibleText:G.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:A1(Q.visibleMap,0,G.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:Y.playbackMode,alignment:Y,visibleMap:Q.visibleMap}},x0=(G,Q)=>{let Y=Q.sourceElement;return{speechText:G.spokenText,visibleText:G.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:G.spokenText===G.fallbackText,mathAlignment:Y?x7({mathElement:Y,speechText:G.spokenText}):void 0}},WQ=(G,Q,Y)=>{let J=Q.sourceElement;return{speechText:Y,visibleText:G.fallbackText,sourceElement:J,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:J?x7({mathElement:J,speechText:Y}):void 0,plainFallback:x0(G,Q)}},L8=(G,Q={})=>G.items.map(({segment:Y,anchor:J})=>{if(Y.kind==="prose")return BQ(Y,J);if(Q.format==="ssml"&&Y.ssml)return WQ(Y,J,Y.ssml);return x0(Y,J)});var f0="pie-tts-control-handoff";var R;(function(G){G.IDLE="idle",G.LOADING="loading",G.PLAYING="playing",G.PAUSED="paused",G.ERROR="error"})(R||(R={}));var k0=(G,Q)=>G===Q||G.startContainer===Q.startContainer&&G.startOffset===Q.startOffset&&G.endContainer===Q.endContainer&&G.endOffset===Q.endOffset,KQ=(G,Q)=>{if(G===Q)return!0;if(!G||!Q||G.type!==Q.type||G.quality!==Q.quality)return!1;if(G.type==="range"&&Q.type==="range")return k0(G.range,Q.range);if(G.type==="element"&&Q.type==="element")return G.element===Q.element;if(G.type==="text-range"&&Q.type==="text-range")return G.node===Q.node&&G.startOffset===Q.startOffset&&G.endOffset===Q.endOffset;return!1};class c7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.IDLE;ttsConfig={};currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Map;lastError=null;speakRunId=0;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];currentSeekSegmentIndex=0;activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=F8();static debugEnabled=(()=>{try{if(typeof process<"u"&&process.env?.PIE_TTS_DEBUG==="1")return!0}catch{}return globalThis.__PIE_TTS_DEBUG__===!0})();constructor(){}debugLog(G,Q){if(!c7.debugEnabled)return;if(Q===void 0)console.debug(G);else console.debug(G,Q)}clearPlaybackStartBarrier(G=this.playbackStartBarrierCleanup){if(G?.(),this.playbackStartBarrierCleanup===G)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(G){if(this.playbackStartDeferredRunId!==G||G!==this.speakRunId)return;this.setState(R.PLAYING);let Q=this.pendingPlaybackStartHighlights.splice(0);for(let Y of Q)Y()}installPlaybackStartBarrier(G,Q=!1){this.clearPlaybackStartBarrier();let Y=this.provider,J=Y&&"onPlaybackStart"in Y?Y:null;if(!J&&!Q)return null;let X=J?.onPlaybackStart,j=()=>{try{this.notifyPlaybackStarted(G)}finally{X?.()}};if(J)J.onPlaybackStart=j;this.playbackStartDeferredRunId=G;let Z=()=>{if(J?.onPlaybackStart===j)J.onPlaybackStart=X;if(this.playbackStartDeferredRunId===G)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=Z,Z}runWhenPlaybackStarts(G,Q){if(this.playbackStartDeferredRunId===G){this.pendingPlaybackStartHighlights.push(Q);return}Q()}async emitTelemetry(G,Q){try{await this.telemetryReporter?.(G,Q)}catch(Y){console.warn("[TTSService] telemetry callback failed:",Y)}}async initialize(G,Q={}){this.currentProvider=G,this.ttsConfig={...Q};let Y=Q.providerOptions&&typeof Q.providerOptions==="object"?Q.providerOptions:{};this.telemetryReporter=typeof Y.__pieTelemetry==="function"?Y.__pieTelemetry:null;try{this.provider=await G.initialize(Q)}catch(J){if(G.providerId.toLowerCase()==="browser")throw J;if(!this.isBrowserSpeechFallbackAvailable())throw J;if(!await this.switchProviderToBrowser(J,{operation:"tts-initialize"}))throw J}}async updateSettings(G){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.provider;if(typeof Q.updateSettings==="function"){let Y={...G,...G.providerOptions?{providerOptions:{...this.ttsConfig.providerOptions||{},...G.providerOptions}}:{}};await Q.updateSettings(Y),this.ttsConfig={...this.ttsConfig,...Y}}else console.warn("[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.")}setHighlightCoordinator(G){this.highlightCoordinator=G}setHighlightTargetResolverProvider(G){return this.highlightTargetResolverProvider=G,()=>{if(this.highlightTargetResolverProvider===G)this.highlightTargetResolverProvider=null}}setCatalogResolver(G){this.catalogResolver=G}hasSpokenAlternate(G,Q="en-US"){if(!G||!this.catalogResolver)return!1;return this.catalogResolver.getAlternative(G,{type:"spoken",language:Q,useFallback:!0,form:"content"})?.content!==void 0}getHighlightResolverRuntime(){let G=null;try{G=this.highlightTargetResolverProvider?.()??null}catch{G=null}let Q=G?.context??{},Y=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Q,scopeElement:Q.scopeElement??Y},resolver:G?.resolver??null}}getNodeElement(G){if(!G)return null;return G.nodeType===Node.ELEMENT_NODE?G:G.parentElement}isElementWithinScope(G,Q){if(!Q)return!0;return G===Q||Q.contains(G)}isRangeWithinScope(G,Q){let Y=this.getNodeElement(G.startContainer),J=this.getNodeElement(G.endContainer);if(!Y||!J)return!1;return this.isElementWithinScope(Y,Q)&&this.isElementWithinScope(J,Q)}resolveWordHighlightRange(G){let{context:Q,resolver:Y}=this.getHighlightResolverRuntime(),J=Q.scopeElement??this.currentContentElement;try{let X=Y?.resolveWordRange?.(G,Q);if(X&&this.isRangeWithinScope(X,J))return{range:X,remapped:!k0(G,X)}}catch{}return{range:G,remapped:!1}}resolveSentenceHighlightTargets(G){let{context:Q,resolver:Y}=this.getHighlightResolverRuntime(),J=Q.scopeElement??this.currentContentElement;try{let X=Y?.resolveSentenceRanges?.(G,Q);if(!X)return{ranges:G,elements:[]};let j=[],Z=[];for(let q of X){if(typeof Range<"u"&&q instanceof Range){if(!this.isRangeWithinScope(q,J))return{ranges:G,elements:[]};j.push(q);continue}if(typeof Element<"u"&&q instanceof Element){if(!this.isElementWithinScope(q,J))return{ranges:G,elements:[]};Z.push(q);continue}return{ranges:G,elements:[]}}return{ranges:j,elements:Z}}catch{return{ranges:G,elements:[]}}}createTextRange(G,Q,Y){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let J=document.createRange();if(J.setStart(G,Q),J.setEnd(G,Y),J.startContainer!==G||J.endContainer!==G)return null;return J}catch{return null}}paintTTSWordRange(G){if(!this.highlightCoordinator)return;try{if(G.startContainer===G.endContainer&&G.startContainer.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(G.startContainer,G.startOffset,G.endOffset);return}}catch{}this.highlightCoordinator.highlightRange(G,u.TTS_WORD,$7.YELLOW)}paintTTSSentenceRanges(G){if(!this.highlightCoordinator)return;let{ranges:Q,elements:Y}=this.resolveSentenceHighlightTargets(G);if(Y.length>0&&Q.length===0&&this.highlightCoordinator.highlightTTSSentenceElements){this.highlightCoordinator.highlightTTSSentenceElements(Y);return}let J=[...Q];for(let X of Y){let j=document.createRange();j.selectNodeContents(X),J.push(j)}this.highlightCoordinator.highlightTTSSentence(J)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}getTextProcessingOptions(G){let Y=(this.ttsConfig.providerOptions||{}).textNormalization||{},J=Y.boundarySpacingMode,X=J==="none"||J==="alnum"||J==="segmenterPreferred"?J:void 0;return{locale:G||(typeof Y.locale==="string"?Y.locale:void 0),boundarySpacingMode:X}}getMathSpeechOptions(){let Q=(this.ttsConfig.providerOptions||{}).mathSpeech;return O7(Q)}buildPositionMap(G,Q,Y){this.normalizedToDOM.clear();let{text:J,map:X}=C7(G,this.getTextProcessingOptions(Y));if(this.normalizedToDOM=X,!c7.debugEnabled)return;this.debugLog("[TTSService] Text comparison:",{spokenLength:Q.length,normalizedDomLength:J.length,match:Q===J,spokenPreview:Q.substring(0,150),normalizedPreview:J.substring(0,150),differAtIndex:Q===J?null:(()=>{for(let j=0;j<Math.min(Q.length,J.length);j++)if(Q[j]!==J[j])return{index:j,spokenChar:Q[j],normalizedChar:J[j],spokenContext:Q.substring(Math.max(0,j-20),j+20),normalizedContext:J.substring(Math.max(0,j-20),j+20)};return null})()}),this.debugLog("[TTSService] Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Q.length,normalizedDomLength:J.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Q.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([j,{node:Z,offset:q}])=>({pos:j,offset:q,char:Z.textContent?.[q],expected:Q[j]}))})}getStructuralPauseProfile(){let Q=(this.ttsConfig.providerOptions||{}).structuralPauses||{},Y=Q.units||{},J=(X,j)=>{if(typeof X==="number"&&Number.isFinite(X))return X;if(typeof X==="string"&&X.trim()){let Z=Number(X);return Number.isFinite(Z)?Z:j}return j};return{baseMs:J(Q.baseMs,280),units:{minor:J(Y.minor,0.65),section:J(Y.section,1),major:J(Y.major,1.35)},minMs:J(Q.minMs,120),maxMs:J(Q.maxMs,900)}}resolvePauseMsFromUnits(G){let Q=this.getStructuralPauseProfile(),Y=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),J=Q.baseMs*Math.max(0,G)/Y;return Math.max(Q.minMs,Math.min(Q.maxMs,Math.round(J)))}resolveHighlightMode(){let Q=(this.ttsConfig.providerOptions||{}).highlightMode;if(Q==="word"||Q==="sentence")return Q;if((this.currentProvider?.providerId||"").toLowerCase()==="browser")return"sentence";return this.currentProvider?.getCapabilities().supportsWordBoundary??!1?"word":"sentence"}hasExplicitBreakSemantics(G){if(!G.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(G)}isElementHidden(G){return Z8(G)}getBoundaryStrength(G){let Q=Number(G.getAttribute("data-tts-break-ms"));if(Number.isFinite(Q)&&Q>0)return"major";let Y=G.tagName.toUpperCase();if(Y.match(/^H[1-6]$/))return"major";let J=(G.getAttribute("role")||"").toLowerCase();if(J==="heading")return"major";if(J==="listitem"||J==="row"||J==="option"||J==="radio"||Y==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(G).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(G,Q){let Y=G.parentElement,J=null;while(Y&&Y!==Q){if(this.isElementHidden(Y))return null;let j=Number(Y.getAttribute("data-tts-break-ms"));if(Number.isFinite(j)&&j>0)return{anchor:Y,units:j/this.getStructuralPauseProfile().baseMs};let Z=(Y.getAttribute("role")||"").toLowerCase(),q=Y.tagName.toUpperCase();if(q.match(/^H[1-6]$/)||Z==="heading"||Z==="listitem"||q==="LI"){J=Y;break}if(!J){if(typeof window<"u"){let B=window.getComputedStyle(Y).display;if(B==="block"||B==="list-item"||B.startsWith("table")||B==="flex"||B==="grid")J=Y}}Y=Y.parentElement}if(!J)return null;let X=this.getBoundaryStrength(J);return{anchor:J,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(G,Q){let Y=this.collectSpeechPlanBoundaries(G,Q);return this.createSpeechPlanSegments(Q,Y)}collectSpeechPlanBoundaries(G,Q){let Y=new Map,{map:J}=C7(G,this.getTextProcessingOptions()),X=this.createNodeStartOffsets(J),j=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),Z=j.nextNode(),q=null;while(Z){let B=Z,K=B.parentElement;if(K&&!this.isElementHidden(K)&&!W1(B)){let W=this.getBoundaryAnchor(B,G),$=X.get(B);if(W&&$!==void 0&&W.anchor!==q&&$>0)Y.set($,Math.max(Y.get($)||0,W.units)),q=W.anchor}Z=j.nextNode()}return Y}createNodeStartOffsets(G){let Q=new Map;for(let[Y,J]of G.entries())if(!Q.has(J.node))Q.set(J.node,Y);return Q}createSpeechPlanSegments(G,Q){let Y=Array.from(Q.keys()).filter((B)=>B>0&&B<G.length).sort((B,K)=>B-K),J=[],X=0;for(let B of Y){let K=G.substring(X,B),W=K.match(/^\s*/)?.[0].length||0,$=K.match(/\s*$/)?.[0].length||0,H=X+W,N=B-$;if(N>H){let F=G.substring(H,N);J.push({text:F,startOffset:H,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(B)||0)})}X=B}let Z=G.substring(X).match(/^\s*/)?.[0].length||0,q=X+Z;if(q<G.length)J.push({text:G.substring(q).trimEnd(),startOffset:q,pauseMsAfter:0});return J.filter((B)=>B.text.trim().length>0)}segmentSentences(G){let Q=this.ttsConfig.providerOptions?.locale||void 0;return S7(G,{locale:Q})}createSeekSegmentsFromText(G){return this.segmentSentences(G).map((Q)=>{let Y=Q.text.match(/^\s*/)?.[0].length||0;return{text:Q.text.trim(),startOffset:Q.offset+Y,pauseMsAfter:0}}).filter((Q)=>Q.text.length>0)}splitSegmentsAtBoundaries(G,Q,Y){if(G.length===0||Q.length===0)return G;let J=Array.from(new Set(Q)).filter((j)=>Number.isFinite(j)&&j>0).sort((j,Z)=>j-Z);if(J.length===0)return G;let X=[];for(let j of G){let Z=j.startOffset,q=j.startOffset+j.text.length,B=J.filter((W)=>W>Z&&W<q);if(B.length===0){X.push(j);continue}let K=Z;for(let W of[...B,q]){let $=Y.substring(K,W),H=$.match(/^\s*/)?.[0].length||0,N=$.match(/\s*$/)?.[0].length||0,F=K+H,O=W-N;if(O>F)X.push({text:Y.substring(F,O),startOffset:F,pauseMsAfter:0});K=W}}return X}createSentenceHighlightSegments(G){let Q=this.createSeekSegmentsFromText(G.contentToSpeak);if(!G.shouldUsePlan||G.playbackSegments.length===0)return Q;let Y=G.playbackSegments.map((J)=>J.startOffset).filter((J)=>J>0);return this.splitSegmentsAtBoundaries(Q,Y,G.contentToSpeak)}createSeekSegmentsFromSpeechChunks(G){let Q=0;return G.map((Y)=>{let J=Y.plainFallback?.speechText||(this.hasExplicitBreakSemantics(Y.speechText)?Y.visibleText:Y.speechText)||Y.visibleText,X=T(J)||Y.visibleText||"",j={text:X,startOffset:Q,pauseMsAfter:0};return Q+=Math.max(1,X.length+1),j})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let G=0;for(let Q=0;Q<this.seekSegments.length;Q++)if(this.seekSegments[Q].startOffset<=this.currentBoundaryOffset)G=Q;else break;return G}async speakWithPlan(G,Q,Y){if(!this.provider||G.length===0)return;let J=Y?.highlightMode==="sentence",X=this.provider;if(!J&&typeof X.speakSegments==="function"){this.currentBoundaryOffset=0;let j=this.provider.onWordBoundary;this.provider.onWordBoundary=(Z,q,B)=>{if(j?.(Z,q,B),Number.isFinite(q))this.currentBoundaryOffset=q,this.currentSeekSegmentIndex=this.getCurrentSeekSegmentIndex()};try{await X.speakSegments(G)}finally{if(Q===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=j}return}this.configureWordBoundaryHighlighting({highlightMode:Y?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let j of G){if(Q!==this.speakRunId)return;let Z=this.seekSegments.findIndex((B)=>B.startOffset===j.startOffset);if(Z>=0)this.currentSeekSegmentIndex=Z;if(this.currentBoundaryOffset=j.startOffset,J)this.runWhenPlaybackStarts(Q,()=>{this.highlightSentenceSegment(j.startOffset,j.text)});await this.provider.speak(j.text);let q=j.pauseMsAfter??0;if(q>0)await new Promise((B)=>setTimeout(B,q))}}highlightSentenceSegment(G,Q){if(!this.highlightCoordinator||typeof document>"u")return;let Y=Q.trimEnd().length;if(Y<=0)return;let J=this.normalizedToDOM.get(G),X=this.normalizedToDOM.get(G+Y-1);if(!J||!X)return;let j=document.createRange();j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),this.paintTTSSentenceRanges([j]),this.activeSentenceStartOffset=G}getSegmentIndexForOffset(G,Q){if(G.length===0)return-1;let Y=-1;for(let J=0;J<G.length;J++)if(G[J].startOffset<=Q)Y=J;else break;return Y}highlightSentenceForOffset(G){let Q=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Q.length===0)return;let Y=this.getSegmentIndexForOffset(Q,G);if(Y<0)return;let J=Q[Y];if(!J)return;if(this.activeSentenceStartOffset===J.startOffset)return;this.highlightSentenceSegment(J.startOffset,J.text)}findHighlightRange(G,Q){let Y=this.normalizedToDOM.get(G);if(!Y)return console.warn(`[TTSService] No mapping found for start position ${G}`,{totalMappings:this.normalizedToDOM.size,nearbyMappings:Array.from(this.normalizedToDOM.entries()).filter(([j])=>Math.abs(j-G)<5).map(([j,{offset:Z,node:q}])=>({pos:j,offset:Z,char:q.textContent?.[Z]}))}),null;let J=G+Q-1,X=this.normalizedToDOM.get(J);if(!X)return console.warn(`[TTSService] No mapping found for end position ${J}`,{startChar:G,length:Q,totalMappings:this.normalizedToDOM.size}),null;if(Y.node!==X.node)return console.warn("[TTSService] Word spans multiple nodes, highlighting in first node only"),{node:Y.node,start:Y.offset,end:(Y.node.textContent||"").length};return{node:Y.node,start:Y.offset,end:X.offset+1}}async speak(G,Q){if(!this.provider)throw Error("TTS service not initialized");let Y=++this.speakRunId;this.clearPlaybackStartBarrier();let J=null;try{if(await this.applyLanguageSettings(Q),Y!==this.speakRunId)return;let X=await this.resolveSpeechContent(G,Q);if(Y!==this.speakRunId)return;let{contentToSpeak:j,speechText:Z,highlightText:q,normalizedText:B,usedCatalogSpoken:K,speechSource:W,speechMatchesVisibleText:$,speechChunks:H}=X;this.logResolvedSpeechContent({contentToSpeak:j,speechSource:W,catalogId:Q?.catalogId}),this.initializeSpeakTracking(q,Q);let N=Q?.highlightModeOverride||($?this.resolveHighlightMode():"sentence");this.activeHighlightMode=N,this.activeWordBoundaryOffset=Q?.wordBoundaryOffset||0;let F=this.hasExplicitBreakSemantics(j),O=!!this.currentContentElement&&!K&&!F&&$;if(this.playbackChunks=H?.length?H:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):F||!$?[]:O&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,B):this.createSeekSegmentsFromText(q),this.sentenceHighlightSegments=F?[]:this.createSentenceHighlightSegments({contentToSpeak:q,shouldUsePlan:O,playbackSegments:this.seekSegments}),this.setState(R.LOADING),J=this.installPlaybackStartBarrier(Y,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:q,options:Q,highlightMode:N,shouldUsePlan:O,runId:Y}),$)this.configureWordBoundaryHighlighting({highlightMode:N,wordBoundaryOffset:Q?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!J)this.setState(R.PLAYING);if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:O,runId:Y,highlightMode:N,contentToSpeak:Z,speechChunks:H}),Y!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(X){let j=X;if(console.error("TTS error:",j),this.lastError=j instanceof Error?j.message:String(j),Y!==this.speakRunId)return;throw this.setState(R.ERROR),this.clearHighlightsAndTracking(),j}finally{this.clearPlaybackStartBarrier(J)}}async switchProviderToBrowser(G,Q){if(!this.currentProvider)return!1;let Y=new T7,J=this.currentProvider.providerId,X={};if(this.ttsConfig.rate!==void 0)X.rate=this.ttsConfig.rate;if(this.ttsConfig.pitch!==void 0)X.pitch=this.ttsConfig.pitch;if(this.ttsConfig.mathTokenHighlighting!==void 0)X.mathTokenHighlighting=this.ttsConfig.mathTokenHighlighting;let j=Q?.operation||"tts-initialize",Z=Q?.contentToSpeak??"",q=Z.replace(/\s+/g," ").trim().slice(0,120),B=Z.length>0?{textLength:Z.length,textPreview:q.length<Z.length?`${q}…`:q}:{};try{return this.provider?.stop(),this.currentProvider.destroy(),this.currentProvider=Y,this.provider=await Y.initialize(X),this.ttsConfig=X,await this.emitTelemetry("pie-tool-runtime-fallback",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:Y.providerId,reason:G instanceof Error?G.message:String(G),...B}),console.warn("[TTSService] TTS provider initialization failed; switched to browser fallback",{fromProvider:J,reason:G,...B}),!0}catch(K){return await this.emitTelemetry("pie-tool-runtime-fallback-error",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:"browser",errorType:"TTSRuntimeFallbackError",message:K instanceof Error?K.message:String(K)}),console.error("[TTSService] Failed to switch to browser fallback provider",K),!1}}isBrowserSpeechFallbackAvailable(){if(typeof window>"u")return!1;if(!("speechSynthesis"in window))return!1;return typeof globalThis.SpeechSynthesisUtterance==="function"}async applyLanguageSettings(G){if(!G?.language||!this.provider)return;let Q=this.ttsConfig.providerOptions||{},Y=Q.textNormalization||{},J=Q.segmenter||{},X={...Q,locale:G.language,textNormalization:{...Y,locale:G.language},segmenter:{...J,locale:G.language}};if(this.ttsConfig={...this.ttsConfig,providerOptions:X},"updateSettings"in this.provider&&typeof this.provider.updateSettings==="function")await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(G,Q){let Y=T(G);if(Q?.ignoreCatalogs)return{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,usedCatalogSpoken:!1,speechSource:"dom-or-input",normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0};if(Q?.catalogId&&this.catalogResolver){let j=this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language||"en-US",useFallback:!0,context:Q.catalogContext,form:"content"}),Z=j?.content;if(j&&Z!==void 0){let q=Q?.contentElement?z7(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||Y:Y,B=T(Z);return this.debugLog(`[TTSService] Using catalog content for "${Q.catalogId}" (${j.language})`),{contentToSpeak:Z,speechText:Z,visibleText:q,highlightText:q,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:q,containsMathMarkup:!1,speechMatchesVisibleText:B===q}}this.debugLog(`[TTSService] No catalog found for "${Q.catalogId}", falling back to generated TTS`)}let J=Q?.contentElement?this.resolveCatalogComposedSpeechContent(Q.contentElement,Y,Q):null;if(J)return J;return{...Q?.contentElement?await this.resolveGeneratedSpeechContent(Q.contentElement,Y,Q.language):{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0},usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(G,Q,Y){if(!this.catalogResolver)return null;let J=this.collectCatalogSpeechChunks(G,Y);if(!J.some((Z)=>Z.sourceElement))return null;let X=T(J.map((Z)=>Z.speechText).join(" ")),j=z7(G,this.getTextProcessingOptions(Y.language)).visibleText||Q;return{contentToSpeak:X,speechText:X,visibleText:j,highlightText:j,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:j,containsMathMarkup:!1,speechMatchesVisibleText:J.every((Z)=>Z.speechMatchesVisibleText),speechChunks:J}}collectCatalogSpeechChunks(G,Q){let Y=[],J="",X=()=>{let K=T(J);if(J="",!K)return;Y.push({speechText:K,visibleText:K,sourceElement:null,speechMatchesVisibleText:!0})},j=(K)=>{let W=K.getAttribute("data-catalog-idref");if(!W)return null;let $={type:"spoken",language:Q.language||"en-US",useFallback:!0,context:Q.catalogContext},H=this.catalogResolver.getAlternative(W,{...$,form:"payload"}),N=H?.payload?w6({payload:H.payload})??void 0:void 0,O=this.catalogResolver.getAlternative(W,{...$,form:"content"})?.content;if(N===void 0&&O===void 0)return null;return{script:O,audio:N}},Z=(K,W)=>{let $=q(K);if($.length!==1)return null;let H=$[0],N=z7(H,this.getTextProcessingOptions(Q.language)).visibleText||T(H.textContent||""),F=(O)=>T(O).replace(/\s+/g,"");return F(N)===F(W)?H:null},q=(K)=>{let W=Array.from(K.querySelectorAll("math"));if(K.localName?.toLowerCase()==="math")return[K,...W];return W},B=(K)=>{if(H7(K,G))return;if(K.nodeType===Node.TEXT_NODE){J+=` ${K.textContent||""}`;return}if(K.nodeType!==Node.ELEMENT_NODE)return;let W=K,$=j(W);if($){X();let H=z7(W,this.getTextProcessingOptions(Q.language)),N=H.visibleText||T(W.textContent||""),F=N1(W,G),O=$.script!==void 0?(()=>{let L=$.script,D=V1({speechText:L,visibleText:N}),P=Z(W,N),S=P?x7({mathElement:P,speechText:L}):void 0,v=S?void 0:q(W).map((I)=>({element:I,alignment:x7({mathElement:I,speechText:L})}));return{speechText:L,visibleText:N,sourceElement:W,regionElement:F,speechMatchesVisibleText:T(L)===N,playbackMode:D.playbackMode,alignment:D,mathAlignment:S,mathAlignments:v,visibleMap:H.map}})():null;if($.audio){Y.push(O?{...O,audio:$.audio,plainFallback:O}:{speechText:N,visibleText:N,sourceElement:W,regionElement:F,speechMatchesVisibleText:!1,visibleMap:H.map,audio:$.audio});return}if(O)Y.push(O);return}for(let H of Array.from(W.childNodes))B(H)};return B(G),X(),Y}resolveGeneratedPlaybackFormat(){let G=this.currentProvider;if(!G)return"plain";if(G.providerId?.toLowerCase()==="browser")return"plain";return G.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(G,Q,Y){let J=this.resolveGeneratedPlaybackFormat(),{plan:X,containsMathMarkup:j,visibleText:Z}=await P8({contentRoot:G,language:Y,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(Y),produceSsml:J==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver}),q=Z||Q;if(!j)return{contentToSpeak:q,speechText:q,visibleText:q,highlightText:q,normalizedText:q,containsMathMarkup:!1,speechMatchesVisibleText:!0};let B=L8(X,{format:J}),K=X.plainSpeechText;return{contentToSpeak:K,speechText:K,visibleText:q,highlightText:q,normalizedText:q,containsMathMarkup:!0,speechMatchesVisibleText:K===q,speechChunks:B}}logResolvedSpeechContent(G){let Q=G.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);this.debugLog("[TTSService] Speak resolved content",{source:G.speechSource,catalogId:G.catalogId||null,length:G.contentToSpeak.length,preview:Q})}initializeSpeakTracking(G,Q){this.currentText=G,this.currentContentElement=Q?.contentElement||null,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(G){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,G.contentToSpeak,G.options?.language),G.highlightMode==="sentence"&&G.shouldUsePlan)return;let Q=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(G.runId,()=>{if(Q)this.highlightSentenceSegment(Q.startOffset,Q.text),this.debugLog("[TTSService] Applied initial sentence highlighting");else try{let Y=document.createRange();Y.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([Y])}catch{}})}configureWordBoundaryHighlighting(G){if(!this.provider||G.highlightMode!=="word"||!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Q,Y,J)=>{let X=J||Q.length,j=Y+this.currentBoundaryOffset+G.wordBoundaryOffset;this.highlightSentenceForOffset(j);let Z=this.findHighlightRange(j,X);if(Z&&this.highlightCoordinator){let q=Z.node.textContent?.substring(Z.start,Z.end)||"";this.debugLog(`[TTSService] Highlighting "${q}" (word: "${Q}") at position ${j}`);let B=this.createTextRange(Z.node,Z.start,Z.end);if(B)this.paintTTSWordRange(this.resolveWordHighlightRange(B).range);else this.highlightCoordinator.highlightTTSWord(Z.node,Z.start,Z.end)}else console.warn(`[TTSService] Could not find highlight range for position ${j}, length ${X}`)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(G){let Q=G.regionElement||G.sourceElement;if(!Q&&!G.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,G.regionRange){this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([G.regionRange]);return}if(!Q)return;let Y=document.createRange();Y.selectNodeContents(Q),this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Y])}catch{}}highlightCatalogActiveRange(G){if(!this.highlightCoordinator)return;this.paintTTSWordRange(this.resolveWordHighlightRange(G).range)}highlightRenderableRegionTarget(G){if(!this.highlightCoordinator||!G||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&KQ(this.lastRenderedRegionTarget,G))return;try{let Q=document.createRange();if(G.type==="element")Q.selectNodeContents(G.element);else if(G.type==="range"){this.paintTTSSentenceRanges([G.range]),this.lastRenderedRegionTarget=G;return}else Q.setStart(G.node,G.startOffset),Q.setEnd(G.node,G.endOffset);this.paintTTSSentenceRanges([Q]),this.lastRenderedRegionTarget=G}catch{}}highlightRenderableActiveTarget(G){if(!this.highlightCoordinator||typeof document>"u")return;if(!G){this.highlightCoordinator.clearHighlights(u.TTS_WORD);return}if(G.type==="text-range"){let X=this.createTextRange(G.node,G.startOffset,G.endOffset);if(X)this.paintTTSWordRange(this.resolveWordHighlightRange(X).range);else this.highlightCoordinator.highlightTTSWord(G.node,G.startOffset,G.endOffset);return}if(G.type==="range"){this.highlightCatalogActiveRange(G.range);return}let Q=document.createRange();Q.selectNodeContents(G.element);let Y=this.resolveWordHighlightRange(Q);if(Y.remapped){this.paintTTSWordRange(Y.range);return}let J=G.element.childNodes.length===1?G.element.firstChild:null;if(G.quality==="semantic-token"&&J?.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(J,0,J.textContent?.length||0);return}this.highlightCoordinator.highlightTTSWordElement?.(G.element)}renderHighlightDecision(G){this.highlightRenderableRegionTarget(G.regionTarget),this.highlightRenderableActiveTarget(G.activeTarget)}async speakCatalogChunk(G,Q){try{await this.speakCatalogChunkOnce(G,Q)}catch(Y){if(G.plainFallback&&Q===this.speakRunId){if(this.debugLog("[TTSService] SSML chunk speak failed; retrying plain text",{message:Y instanceof Error?Y.message:String(Y)}),this.playbackStartDeferredRunId===Q&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.setState(R.PLAYING);await this.speakCatalogChunkOnce(G.plainFallback,Q);return}throw Y}}async playRecordedAudio(G,Q){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let Y=G.sources[0],J=document.createElement("audio");J.preload="auto",J.src=L6(Y.src,G.fragment),J.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,j)=>{let Z,q=!1,B=!1,K=()=>{if(B||q)return;q=!0,Q?.()},W=()=>{if(J.removeEventListener("ended",$),J.removeEventListener("error",H),J.removeEventListener("playing",K),Z?.(),this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null},$=()=>{if(B)return;B=!0,W(),X()},H=()=>{if(B)return;B=!0,W(),j(Error(`[tts] recorded audio failed to play: ${Y.src}`))};this.activeRecordedAudio={element:J,cancel:()=>{if(B)return;B=!0,W(),J.pause(),X()}},J.addEventListener("ended",$),J.addEventListener("error",H),J.addEventListener("playing",K),Z=P6(J,G.fragment,$),Promise.resolve(J.play()).then(K).catch(H)}).finally(()=>{if(this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null;J.pause(),J.removeAttribute("src")})}cancelRecordedAudio(){let G=this.activeRecordedAudio;if(!G)return;this.activeRecordedAudio=null,G.cancel()}async speakCatalogChunkOnce(G,Q){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,G.audio){this.runWhenPlaybackStarts(Q,()=>{this.highlightCatalogRegion(G)}),await this.playRecordedAudio(G.audio,()=>{this.notifyPlaybackStarted(Q)});return}let Y=G.regionElement||G.sourceElement||this.currentContentElement,J=Y?y0({contentRoot:Y,chunks:[G]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,j=J?C0({chunks:[J],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(Q,()=>{if(j&&J&&G.mathAlignment)this.renderHighlightDecision(j.resolveInitial(J.id));else this.highlightCatalogRegion(G)}),!(G.sourceElement&&(G.mathAlignment&&G.mathAlignment.speech.tokens.length>0||G.mathAlignments&&G.mathAlignments.length>0||G.alignment&&G.visibleMap&&(G.playbackMode==="exact-word"||G.playbackMode==="anchor-span")))){let W=this.provider,$=W.onWordBoundary;W.onWordBoundary=void 0;try{await W.speak(G.speechText)}finally{if(this.provider===W&&Q===this.speakRunId&&W.onWordBoundary===void 0)W.onWordBoundary=$}return}let q=this.provider,B=q.onWordBoundary,K=(W,$,H)=>{if(Q!==this.speakRunId)return;if(j&&J){let N=J.offsetSpace==="unsupported"?"unknown":J.offsetSpace;this.renderHighlightDecision(j.resolveBoundary({chunkId:J.id,word:W,position:$,length:H,providerOffsetSpace:N}));return}};q.onWordBoundary=K;try{await q.speak(G.speechText)}finally{if(this.provider===q&&Q===this.speakRunId&&q.onWordBoundary===K)q.onWordBoundary=B}}async executeSpeakPlayback(G){if(G.speechChunks?.length&&this.provider){for(let Q=0;Q<G.speechChunks.length;Q++){if(G.runId!==this.speakRunId)return;this.currentSeekSegmentIndex=Q;let Y=this.seekSegments[Q];if(Y)this.currentBoundaryOffset=Y.startOffset;let J=G.speechChunks[Q];await this.speakCatalogChunk(J,G.runId)}return}if(G.shouldUsePlan&&this.currentContentElement){let Q=this.seekSegments;if(Q.length>0)await this.speakWithPlan(Q,G.runId,{highlightMode:G.highlightMode});else if(this.provider)await this.provider.speak(G.contentToSpeak);return}if(this.provider)await this.provider.speak(G.contentToSpeak)}clearHighlightsAndTracking(){if(this.pendingPlaybackStartHighlights=[],this.activePlaybackRate=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}async speakRange(G,Q){if(!this.provider)throw Error("TTS service not initialized");if(W1(G.commonAncestorContainer)){console.warn("[tts] selection lies inside content marked not-to-be-spoken; nothing was spoken. Selecting a node and pressing read-aloud must not become a way around suppression.");return}let J=Q?.contentRoot||null;if(!J){let W=G.commonAncestorContainer;J=W.nodeType===Node.ELEMENT_NODE?W:W.parentElement}if(!J)return;let X=j8(G,J),j=X.text.trim();if(!j){if(X.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return}let Z=document.createRange();Z.selectNodeContents(J),Z.setEnd(G.startContainer,G.startOffset);let q=j8(Z,J).text,B=T(q),K=B.length+(/\s$/.test(q)&&B?1:0);this.debugLog("[TTSService] speakRange offset calculation:",{selectedText:j,textBeforeRange:q.substring(0,100),offset:K,rootTag:J.tagName}),await this.speak(j,{contentElement:J,ignoreCatalogs:!0,wordBoundaryOffset:K})}pause(){if(!this.provider)return;if(this.state===R.PLAYING)this.activeRecordedAudio?.element.pause(),this.provider.pause(),this.setState(R.PAUSED)}resume(){if(!this.provider)return;if(this.state===R.PAUSED){let G=this.activeRecordedAudio?.element;if(G)Promise.resolve(G.play()).catch(()=>{});this.provider.resume(),this.setState(R.PLAYING)}}normalizePlaybackRate(G){if(!Number.isFinite(G))return 1;return Math.max(0.25,Math.min(4,G))}async restartFromSeekIndex(G){if(!this.provider||this.seekSegments.length===0)return;let Q=Math.max(0,Math.min(this.seekSegments.length-1,G)),Y=this.playbackChunks.length?this.playbackChunks.slice(Q):null;this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.currentSeekSegmentIndex=Q;let J=++this.speakRunId,X=this.seekSegments.slice(Q);this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.setState(R.LOADING);let j=this.installPlaybackStartBarrier(J,!!Y?.[0]?.audio);if(!j)this.setState(R.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),Y)for(let Z=0;Z<Y.length;Z++){if(J!==this.speakRunId)return;let q=Q+Z;this.currentSeekSegmentIndex=q;let B=this.seekSegments[q];if(B)this.currentBoundaryOffset=B.startOffset;await this.speakCatalogChunk(Y[Z],J)}else await this.speakWithPlan(X,J,{highlightMode:this.activeHighlightMode});if(J!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(Z){if(J!==this.speakRunId)return;throw this.lastError=Z instanceof Error?Z.message:String(Z),this.setState(R.ERROR),this.clearHighlightsAndTracking(),Z}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(G){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.normalizePlaybackRate(G),Y=this.pendingPlaybackRateRequest;if(Y?.rate===Q){await Y.promise;return}let J=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let q=this.speakRunId;if(J!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:q};let B=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===B)return{didUpdate:!1,playbackRunId:q};return await this.updateSettings({rate:Q}),{didUpdate:!0,playbackRunId:q}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let j=X.then(async(q)=>{if(J!==this.playbackRateRequestId||q.playbackRunId!==this.speakRunId)return;let B=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!q.didUpdate&&!B)return;if(this.state!==R.PLAYING&&this.state!==R.LOADING||!this.currentText||this.seekSegments.length===0||this.hasExplicitBreakSemantics(this.currentText))return;await this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex())}),Z;Z=j.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===Z)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Q,promise:Z},await Z}async seekBy(G){if(!this.provider||!this.currentText)return;if(this.state!==R.PLAYING&&this.state!==R.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Q=Number.isFinite(G)?Math.trunc(G):0;if(Q===0)return;let Y=this.getCurrentSeekSegmentIndex(),J=Math.max(0,Math.min(this.seekSegments.length-1,Y+Q));if(J===Y)return;await this.restartFromSeekIndex(J)}async seekForward(G=1){let Q=Number.isFinite(G)?Math.max(1,Math.trunc(G)):1;await this.seekBy(Q)}async seekBackward(G=1){let Q=Number.isFinite(G)?Math.max(1,Math.trunc(G)):1;await this.seekBy(-Q)}stop(){if(!this.provider)return;if(this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.setState(R.IDLE),this.currentText=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null,this.activePlaybackRate=null}requestControlHandoff(){if(typeof window>"u")return;let G={source:"host"};window.dispatchEvent(new CustomEvent(f0,{detail:G}))}isPlaying(){return this.state===R.PLAYING}isPaused(){return this.state===R.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(G,Q){if(!this.listeners.has(G))this.listeners.set(G,new Set);this.listeners.get(G).add(Q)}offStateChange(G,Q){let Y=this.listeners.get(G);if(Y){if(Y.delete(Q),Y.size===0)this.listeners.delete(G)}}setState(G){if(this.state===G)return;let Q=this.state;this.state=G;for(let Y of this.listeners.values())for(let J of Y)J(G);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G}),G===R.PLAYING){let Y=Q===R.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(Y,{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G});return}if(G===R.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G});return}if(G===R.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G,message:this.lastError||void 0});return}if(G===R.IDLE&&(Q===R.PLAYING||Q===R.PAUSED||Q===R.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G})}}var _Q=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),I0=(G)=>G&&typeof G==="object"?G:{},VQ=(G)=>G==="polly"||G==="google"||G==="server",l=(G,Q)=>G===void 0?Q:G,$Q=(G,Q="left-aligned")=>typeof G==="string"&&_Q.has(G)?G:Q,K4=Object.freeze([0.8,1.25]),_4=Object.freeze([{rate:0.8,label:"Slow",ariaLabel:"Slow speed"},{rate:1,label:"Normal",ariaLabel:"Normal speed",default:!0},{rate:1.25,label:"Fast",ariaLabel:"Fast speed"}]);var V4=Object.freeze([0.8,1,1.25]);var HQ=(G)=>{let Q={...G,layoutMode:$Q(G.layoutMode)},Y=G.backend||"browser";if(!VQ(Y))return Q;let J={...Q,apiEndpoint:l(Q.apiEndpoint,"/api/tts"),transportMode:l(Q.transportMode,"pie"),endpointValidationMode:l(Q.endpointValidationMode,"voices"),validateEndpoint:l(Q.validateEndpoint,!0),includeAuthOnAssetFetch:l(Q.includeAuthOnAssetFetch,!1),rate:l(Q.rate,1),language:l(Q.language,"en-US")};if(Y==="polly")return{...J,defaultVoice:l(J.defaultVoice,"Joanna"),engine:l(J.engine,"neural"),format:l(J.format,"mp3"),speechMarksMode:l(J.speechMarksMode,"word+sentence")};if(Y==="google")return{...J,defaultVoice:l(J.defaultVoice,"en-US-Wavenet-A")};return J},v0=(G)=>{let Q=I0(G),Y=I0(Q.settings);return HQ({...Q,...Y})},w8=(G)=>G.backend||"browser",DQ=(G,Q)=>{if(Q==="polly"||Q==="google")return Q;if(Q==="server")return G.serverProvider||G.provider;return G.serverProvider||G.provider},AQ=(G,Q)=>G.transportMode||(Q==="custom"?"custom":"pie"),h0=(G)=>{let Q=w8(G),Y=DQ(G,Q),J=AQ(G,Y),X=O7(G.mathSpeech);return{voice:G.defaultVoice,rate:G.rate,pitch:G.pitch,providerOptions:{...G.language?{locale:G.language}:{},...Q==="polly"&&G.engine?{engine:G.engine}:{},...Q==="polly"&&typeof G.sampleRate==="number"?{sampleRate:G.sampleRate}:{},...Q==="polly"&&G.format?{format:G.format}:{},...Q==="polly"?{speechMarkTypes:G.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...J==="custom"&&typeof G.cache==="boolean"?{cache:G.cache}:{},...J==="custom"&&G.speedRate?{speedRate:G.speedRate}:{},...J==="custom"&&G.lang_id?{lang_id:G.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:G.apiEndpoint,provider:Y,language:G.language,transportMode:J,endpointMode:G.endpointMode,endpointValidationMode:G.endpointValidationMode,includeAuthOnAssetFetch:G.includeAuthOnAssetFetch,validateEndpoint:G.validateEndpoint,...typeof G.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:G.mathTokenHighlighting}:{}}};class F1{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(G,Q,Y){try{await G.onTelemetry?.(Q,Y)}catch(J){console.warn("[ToolProviderRegistry] Telemetry callback failed:",J)}}register(G,Q){if(this.providers.has(G)){console.warn(`[ToolProviderRegistry] Provider "${G}" already registered, skipping`);return}if(this.providers.set(G,Q.provider),this.configs.set(G,Q),this.initialized.set(G,!1),console.log(`[ToolProviderRegistry] Registered provider "${G}" (${Q.provider.providerName})`),Q.lazy===!1)this.initialize(G).catch((Y)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${G}":`,Y)})}async initialize(G){if(this.initialized.get(G))return;let Q=this.initializationPromises.get(G);if(Q)return Q;let Y=this._doInitialize(G);this.initializationPromises.set(G,Y);try{await Y}finally{this.initializationPromises.delete(G)}}async _doInitialize(G){let Q=this.providers.get(G),Y=this.configs.get(G);if(!Q||!Y)throw Error(`[ToolProviderRegistry] Provider "${G}" not registered`);let J={...Y.config},X=(Z)=>{if(!Z||typeof Z!=="object")return"unknown";let q=Z;return(typeof q.backend==="string"?q.backend:typeof q.provider==="string"?q.provider:typeof q.serverProvider==="string"?q.serverProvider:typeof q.providerId==="string"?q.providerId:"")||"unknown"},j=Date.now();if(await this.emitTelemetry(Y,"pie-tool-init-start",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize"}),Q.requiresAuth&&Y.authFetcher){let Z=Date.now();await this.emitTelemetry(Y,"pie-tool-backend-call-start",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch"}),console.log(`[ToolProviderRegistry] Fetching auth for "${G}"...`);try{let q=await Y.authFetcher();J={...J,...q},await this.emitTelemetry(Y,"pie-tool-backend-call-success",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z})}catch(q){throw await this.emitTelemetry(Y,"pie-tool-backend-call-error",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z,errorType:"ProviderAuthFetchError",message:q instanceof Error?q.message:String(q)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${G}":`,q),Error(`Failed to fetch auth credentials for provider "${G}"`)}}try{await Q.initialize(J),this.initialized.set(G,!0),await this.emitTelemetry(Y,"pie-tool-init-success",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize",duration:Date.now()-j}),console.log(`[ToolProviderRegistry] Provider "${G}" initialized`)}catch(Z){throw await this.emitTelemetry(Y,"pie-tool-init-error",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize",duration:Date.now()-j,errorType:"ProviderInitializationError",message:Z instanceof Error?Z.message:String(Z)}),console.error(`[ToolProviderRegistry] Initialization failed for "${G}":`,Z),Z}}async getProvider(G,Q=!0){console.log("[ToolProviderRegistry] getProvider called",{providerId:G,autoInitialize:Q,isRegistered:this.providers.has(G),isInitialized:this.initialized.get(G),allProviderIds:Array.from(this.providers.keys())});let Y=this.providers.get(G);if(!Y)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:G,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${G}" not registered`);if(Q&&!this.initialized.get(G))console.log("[ToolProviderRegistry] Auto-initializing provider:",G),await this.initialize(G);return console.log("[ToolProviderRegistry] Returning provider:",{providerId:G,providerName:Y.providerName,isReady:Y.isReady()}),Y}getProvidersByCategory(G){return Array.from(this.providers.entries()).filter(([Q,Y])=>Y.category===G).map(([Q])=>Q)}getProviderIds(){return Array.from(this.providers.keys())}has(G){return this.providers.has(G)}isInitialized(G){return this.initialized.get(G)===!0}isInitializing(G){return this.initializationPromises.has(G)}async unregister(G){let Q=this.providers.get(G);if(Q){let Y=this.initializationPromises.get(G);if(Y)try{await Y}catch{}Q.destroy(),this.providers.delete(G),this.configs.delete(G),this.initialized.delete(G),this.initializationPromises.delete(G),console.log(`[ToolProviderRegistry] Unregistered provider "${G}"`)}}async destroy(){let G=Array.from(this.providers.keys());await Promise.all(G.map((Q)=>this.unregister(Q))),console.log("[ToolProviderRegistry] Registry destroyed")}}class R8{targets=new Set;changeListeners=new Set;registerTarget(G){return this.targets.add(G),this.notifyChange(),()=>{if(!this.targets.delete(G))return;this.notifyChange()}}canRequest(G,Q){return this.findTarget(G,Q)!==null}request(G){let Q=this.findTarget(G.toolId,G.level);if(!Q)return!1;try{Q.open(G.toolId,G.params)}catch(Y){return console.error(`[ToolRequestRegistry] Target failed to open "${G.toolId}":`,Y),!1}return!0}onTargetsChange(G){return this.changeListeners.add(G),()=>{this.changeListeners.delete(G)}}findTarget(G,Q){let Y=this.findTargetAtLevel(G,Q??"section");if(Y||Q!==void 0)return Y;for(let J of this.targets){if(J.level==="section")continue;if(this.hostsTool(J,G))return J}return null}findTargetAtLevel(G,Q){for(let Y of this.targets){if(Y.level!==Q)continue;if(this.hostsTool(Y,G))return Y}return null}hostsTool(G,Q){try{return G.hostsTool(Q)===!0}catch(Y){return console.warn(`[ToolRequestRegistry] Target at level "${G.level}" failed the host check for "${Q}":`,Y),!1}}notifyChange(){for(let G of this.changeListeners)try{G()}catch(Q){console.warn("[ToolRequestRegistry] Target change listener threw:",Q)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}var NQ=(G)=>`No assessment is bound, so no policy source could grant "${G}"`;function E8(G,Q,Y,J){return{featureId:G,granted:!1,action:"block",rule:Q,precedence:0,sourceType:"host",reason:Q==="host-blocked"?"Listed in tools.policy.blocked":`Not listed in tools.policy.allowed (${Y.join(", ")})`,required:!1,assessmentBound:J.assessmentBound}}function u0(G,Q,Y){let J=Q.decisions[0],X=Array.from(Q.perToolFlags.values())[0],j=J?.action==="enable",Z=J?.reason??`Feature "${G}" not configured`;return{featureId:G,granted:j,action:J?.action??"skip",rule:J?.rule??"pnp-support",precedence:J?.precedence??6,sourceType:J?.sourceType??"system",reason:Y.assessmentBound||j?Z:NQ(G),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:Y.assessmentBound}}class M1{provenance;stepCounter=0;constructor(G){this.provenance={contextId:G,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(G,Q){let Y={id:Q.id,name:Q.name??Q.id};switch(G){case"organization":this.provenance.sources.organization={...Y,pnpDefaults:Q.config};break;case"assessment":this.provenance.sources.assessment={...Y,settings:Q.config};break;case"section":this.provenance.sources.section={...Y,settings:Q.config};break;case"item":this.provenance.sources.item={...Y,settings:Q.config};break;case"student":this.provenance.sources.student={id:Q.id,pnpProfile:Q.config};break;case"host":this.provenance.sources.host={id:Q.id,config:Q.config};break}return this}addDecision(G){let Q={step:++this.stepCounter,precedence:G.precedence,rule:G.rule,featureId:G.featureId,action:G.action,source:{type:G.sourceType,id:G.sourceId,name:G.sourceName},reason:G.reason,value:G.value,timestamp:new Date};this.provenance.decisionLog.push(Q);let Y=this.provenance.features.get(G.featureId);if(!Y)Y={featureId:G.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(G.featureId,Y);if(Y.allDecisions.push(Q),G.action==="advisory"){if(Y.finalState==="not-configured")Y.finalState="advisory-only"}else if(G.action!=="skip"){if(!Y.winningDecision||Q.precedence<Y.winningDecision.precedence)Y.winningDecision=Q,Y.finalState=Q.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[G.sourceType]=(this.provenance.summary.bySource[G.sourceType]||0)+1,this.provenance.summary.byRule[G.rule]=(this.provenance.summary.byRule[G.rule]||0)+1,this}reconcileFinalStates(G){for(let Q of G){let Y=this.provenance.features.get(Q);if(!Y){Y={featureId:Q,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Q,Y);continue}Y.finalState="enabled"}for(let Q of this.provenance.features.values()){if(G.has(Q.featureId))continue;let Y=Q.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),J=Q.allDecisions.some((X)=>X.action==="advisory");if(Y)Q.finalState="blocked";else if(J)Q.finalState="advisory-only";else Q.finalState="not-configured"}return this}build(){for(let G of this.provenance.features.values())G.explanation=FQ(G);for(let G of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,G.finalState==="enabled")this.provenance.summary.enabled++;else if(G.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function FQ(G){if(!G.winningDecision){if(G.finalState==="advisory-only"){let j=G.allDecisions.find((Z)=>Z.action==="advisory");return j?`Feature "${G.featureId}" was kept in its host-decided state; ${j.reason}`:`Feature "${G.featureId}" carries an advisory note.`}return`Feature "${G.featureId}" was not configured at any level.`}let Q=G.winningDecision,Y=Q.source.name||Q.source.type,J=`Feature "${G.featureId}" is ${G.finalState}.
215
+ `,document.head.appendChild(Q)}highlightTTSWord(Q,Y,J){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(Q.parentElement),this.clearTTSWord();let G=document.createRange();G.setStart(Q,Y),G.setEnd(Q,J),this.ttsWordHighlight.add(G)}highlightTTSWordElement(Q){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(Q),this.clearTTSWord(),Q.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(Q)}highlightTTSSentence(Q){if(!this.ttsSentenceHighlight)return;let Y=Q[0]?.startContainer,J=Y?.nodeType===Node.ELEMENT_NODE?Y:Y?.parentElement;this.applyAdaptiveTTSStyle(J),this.clearTTSSentence();for(let G of Q)this.ttsSentenceHighlight.add(G);this.highlightTTSElementFallbacks(Q)}highlightTTSSentenceElements(Q){if(!this.ttsSentenceHighlight)return;this.applyAdaptiveTTSStyle(Q[0]||null),this.clearTTSSentence();for(let Y of Q)Y.setAttribute("data-pie-tts-sentence-element","true"),this.ttsSentenceElementHighlights.add(Y)}static SENTENCE_FALLBACK_SELECTOR="math, mjx-container, svg, img, canvas, [role='img']";static WORD_FALLBACK_SELECTOR="svg, img, canvas, [role='img']";highlightTTSElementFallbacks(Q){if(typeof Element>"u")return;this.highlightElementFallbacks(Q,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,p7.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Q){if(typeof Element>"u")return;this.highlightElementFallbacks(Q,"data-pie-tts-word-element",this.ttsWordElementHighlights,p7.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Q,Y,J,G){for(let X of Q){let j=X.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?X.commonAncestorContainer:X.commonAncestorContainer.parentElement;if(!j)continue;let Z=[],B=X.startContainer.nodeType===Node.ELEMENT_NODE?X.startContainer:X.startContainer.parentElement,W=X.endContainer.nodeType===Node.ELEMENT_NODE?X.endContainer:X.endContainer.parentElement;for(let K of[B,W]){let U=K;while(U){if(U.matches?.(G))Z.push(U);U=U.parentElement}}if(j.matches?.(G))Z.push(j);Z.push(...Array.from(j.querySelectorAll(G)));for(let K of new Set(Z)){try{if(!X.intersectsNode(K)&&!K.contains(B)&&!K.contains(W))continue}catch{continue}K.setAttribute(Y,"true"),J.add(K)}}}clearTTSWord(){if(!this.ttsWordHighlight)return;this.ttsWordHighlight.clear();for(let Q of this.ttsWordElementHighlights)Q.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.ttsSentenceHighlight)return;this.ttsSentenceHighlight.clear();for(let Q of this.ttsSentenceElementHighlights)Q.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){this.clearTTSWord(),this.clearTTSSentence()}addAnnotation(Q,Y=_7.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,G=Q.cloneRange(),X={id:J,range:G,type:u.ANNOTATION,color:Y,timestamp:Date.now()};this.annotations.set(J,X);let j=this.colorHighlights.get(Y);if(j)j.add(G);return J}removeAnnotation(Q){let Y=this.annotations.get(Q);if(!Y){console.warn(`[HighlightCoordinator] Annotation ${Q} not found`);return}console.log(`[HighlightCoordinator] Removing annotation ${Q} (color: ${Y.color})`);let J=this.colorHighlights.get(Y.color);if(J){let G=J.delete(Y.range);console.log("[HighlightCoordinator] Highlight.delete() returned:",G)}this.annotations.delete(Q),console.log(`[HighlightCoordinator] Annotation ${Q} removed from map. Remaining:`,this.annotations.size)}clearAnnotations(){for(let Q of this.colorHighlights.values())Q.clear();this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(Q){return this.annotations.get(Q)??null}changeAnnotationColor(Q,Y){let J=this.annotations.get(Q);if(!J)return;let G=J.color;if(G===Y)return;let X=this.colorHighlights.get(G);if(X)X.delete(J.range);J.color=Y;let j=this.colorHighlights.get(Y);if(j)j.add(J.range)}exportAnnotations(Q=document.body){return this.getAnnotations().map((Y)=>({...this.rangeSerializer.serialize(Y.range,Q),id:Y.id,color:Y.color,timestamp:Y.timestamp}))}importAnnotations(Q,Y=document.body){let J=0;for(let G of Q){let X=this.rangeSerializer.deserialize(G,Y);if(X)this.addAnnotation(X,G.color),J++}return J}highlightRange(Q,Y,J=_7.YELLOW){if(!this.supported)return;switch(Y){case u.TTS_WORD:case u.TTS_SENTENCE:{let G=Y===u.TTS_WORD?this.ttsWordHighlight:this.ttsSentenceHighlight;if(G){if(G.clear(),G.add(Q),Y===u.TTS_WORD){for(let X of this.ttsWordElementHighlights)X.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear(),this.highlightTTSWordElementFallbacks([Q])}}break}case u.ANNOTATION:this.addAnnotation(Q,J);break}}clearHighlights(Q){if(!this.supported)return;switch(Q){case u.TTS_WORD:this.clearTTSWord();break;case u.TTS_SENTENCE:this.clearTTSSentence();break;case u.ANNOTATION:this.clearAnnotations();break}}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}isSupported(){return this.supported}updateTTSHighlightStyle(Q,Y){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((j)=>{let Z=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(j);return Z?{r:parseInt(Z[1],16),g:parseInt(Z[2],16),b:parseInt(Z[3],16)}:null})(Q);if(!X)return;this.explicitTTSColorOverride={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Y))},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations(),this.themeObserver?.disconnect(),this.themeObserver=null}}function L0(Q){return(...Y)=>{console.debug(`[${Q}]`,...Y)}}var a=L0("ToolCoordinator"),Z7;(function(Q){Q[Q.BASE=0]="BASE",Q[Q.TOOL=1000]="TOOL",Q[Q.MODAL=2000]="MODAL",Q[Q.CONTROL=3000]="CONTROL",Q[Q.HIGHLIGHT=4000]="HIGHLIGHT"})(Z7||(Z7={}));class G9{tools=new Map;layerCounters=new Map;listeners=new Set;visibilityState=new Map;constructor(){this.layerCounters.set(Z7.BASE,0),this.layerCounters.set(Z7.TOOL,0),this.layerCounters.set(Z7.MODAL,0),this.layerCounters.set(Z7.CONTROL,0),this.layerCounters.set(Z7.HIGHLIGHT,0)}subscribe(Q){return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}notifyListeners(){this.listeners.forEach((Q)=>Q())}registerTool(Q,Y,J,G=Z7.MODAL){if(a("registerTool called:",{id:Q,name:Y,hasElement:!!J,layer:G}),this.tools.has(Q)){a(`Tool ${Q} is already registered`);return}let X=this.visibilityState.get(Q)??!1;if(!J){this.tools.set(Q,{id:Q,name:Y,element:null,layer:G,isVisible:X,baseZIndex:G}),a("Tool registered without element:",Q);return}let j=G+this.getNextLayerOffset(G);J.style.zIndex=String(j),J.style.display=X?"":"none";let Z=()=>this.bringToFront(J);if(J.addEventListener("mousedown",Z),this.tools.set(Q,{id:Q,name:Y,element:J,layer:G,isVisible:X,baseZIndex:j,mouseDownHandler:Z}),X)this.bringToFront(J);a("Tool registered with element:",Q)}unregisterTool(Q){let Y=this.tools.get(Q);if(!Y)return;if(Y.element&&Y.mouseDownHandler)Y.element.removeEventListener("mousedown",Y.mouseDownHandler);this.tools.delete(Q)}releaseTool(Q){this.unregisterTool(Q),this.visibilityState.delete(Q)}showTool(Q){let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found`);return}if(Y.element)Y.element.style.display="",this.bringToFront(Y.element);Y.isVisible=!0,this.visibilityState.set(Q,!0),this.notifyListeners()}hideTool(Q){let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found`);return}if(Y.element)Y.element.style.display="none";Y.isVisible=!1,this.visibilityState.set(Q,!1),this.notifyListeners()}toggleTool(Q){a("toggleTool called for:",Q);let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found. Registered tools:`,Array.from(this.tools.keys()));return}if(a("Tool found, current visibility:",Y.isVisible),Y.isVisible)this.hideTool(Q);else this.showTool(Q)}isToolVisible(Q){let Y=this.tools.get(Q);if(Y)return Y.isVisible;return this.visibilityState.get(Q)??!1}bringToFront(Q){let Y=Array.from(this.tools.values()).find((X)=>X.element===Q);if(!Y)return;let J=this.getMaxZIndexInLayer(Y.layer),G=Math.max(J+1,Y.layer+1);Q.style.zIndex=String(G),Y.baseZIndex=G}getRegisteredTools(){return Array.from(this.tools.keys())}getToolElement(Q){return this.tools.get(Q)?.element??null}getNextLayerOffset(Q){let Y=this.layerCounters.get(Q)??0;return this.layerCounters.set(Q,Y+1),Y}getMaxZIndexInLayer(Q){let Y=Q;for(let J of this.tools.values())if(J.layer===Q)Y=Math.max(Y,J.baseZIndex);return Y}resetZIndices(){for(let Q of this.tools.values())if(Q.element)Q.element.style.zIndex=String(Q.baseZIndex)}updateToolElement(Q,Y){let J=this.tools.get(Q);if(!J){a(`Tool ${Q} not found`);return}if(J.element&&J.mouseDownHandler)J.element.removeEventListener("mousedown",J.mouseDownHandler);let G=()=>this.bringToFront(Y);if(Y.addEventListener("mousedown",G),J.element=Y,J.mouseDownHandler=G,Y.style.zIndex=String(J.baseZIndex),J.isVisible)Y.style.display="";else Y.style.display="none"}hideAllTools(){for(let Q of this.tools.keys())this.hideTool(Q);this.notifyListeners()}getToolState(Q){let Y=this.tools.get(Q);if(!Y)return;return{id:Y.id,name:Y.name,isVisible:Y.isVisible,element:Y.element??null,layer:Y.layer}}getVisibleTools(){return Array.from(this.tools.values()).filter((Q)=>Q.isVisible).map((Q)=>({id:Q.id,name:Q.name,isVisible:Q.isVisible,element:Q.element??null,layer:Q.layer}))}}import{applyMediaFragment as q2,enforceMediaFragment as W2}from"@pie-players/pie-players-shared/media";import{isUnsupportedMediaAssetVersion as b3,normalizeMediaFragment as S3,normalizeMediaSources as C3,trimmedOrUndefined as T3}from"@pie-players/pie-players-shared/media";function w0(Q){if(!Q)return null;let Y=Q.payload;if(!Y||typeof Y!=="object")return null;let J=Y.media;if(!J||typeof J!=="object")return console.warn("[spoken-audio] card carries a `payload` with no `media`; recorded speech needs `media.sources`, so this card is ignored and read-aloud falls back to the script or generated speech"),null;if(b3(J.version))return console.warn(`[spoken-audio] card's media declares version ${String(J.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(J.kind!==void 0&&J.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${J.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let G=C3(J.sources);if(G.length===0)return console.warn("[spoken-audio] card's `media.sources` yielded no usable URL; read-aloud falls back to the script or generated speech"),null;return{sources:G,fragment:S3(Y.fragment),label:T3(J.label)}}var S7=(Q,Y)=>{let J=Y?.useSentenceSegmenter!==!1;try{if(!J)throw Error("Segmenter disabled by policy");let B=globalThis.Intl?.Segmenter;if(typeof B==="function"){let W=new B(Y?.locale,{granularity:"sentence"}),K=Array.from(W.segment(Q)).map((U)=>({text:U.segment,offset:U.index})).filter((U)=>U.text.trim().length>0);if(K.length>0)return K}}catch{}let G=/[^.!?]+(?:[.!?]+|$)/g,X=Q.match(G)||[Q],j=[],Z=0;for(let B of X){let W=Q.indexOf(B,Z);if(W===-1)continue;j.push({text:B,offset:W}),Z=W+B.length}return j.length>0?j:[{text:Q,offset:0}]};var R0=5000,E0=2000,b0=(Q)=>String(Q||"").trim().toLowerCase(),y3=()=>{let Q=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return b0(Q||"en-US")},f3=(Q,Y)=>{if(Y)return Q.find((Z)=>Z.voiceURI===Y)||Q.find((Z)=>Z.name===Y)||null;let J=y3(),G=J.split("-")[0]||"en",X=(Z)=>{let B=b0(Z.lang);return B===J||B.startsWith(`${G}-`)},j=[(Z)=>Z.localService&&X(Z),(Z)=>Z.default&&X(Z),(Z)=>X(Z),(Z)=>Z.localService,(Z)=>Z.default];for(let Z of j){let B=Q.find(Z);if(B)return B}return Q[0]||null},x3=(Q)=>!Q.default;class g7{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";async initialize(Q){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");return new S0(Q)}supportsFeature(Q){return!0}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class S0{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;settlePendingVoiceWait=null;settlePendingChunk=null;onPlaybackStart=void 0;constructor(Q){this.config=Q}waitForBrowserVoices(Q,Y){return new Promise((J,G)=>{let X=speechSynthesis,j=typeof X.addEventListener==="function"&&typeof X.removeEventListener==="function",Z=j?null:X.onvoiceschanged,B=!1,W=null,K=null,U=()=>{if(W!==null)clearTimeout(W),W=null;if(j)X.removeEventListener("voiceschanged",N);else if(X.onvoiceschanged===D)X.onvoiceschanged=Z;if(K&&this.settlePendingVoiceWait===K)this.settlePendingVoiceWait=null},_=(O,P)=>{if(B)return;if(B=!0,U(),P)G(P);else J(O)},$=()=>{if(Q!==this.speakRunId){_(!1);return}if(X.getVoices().length>0)_(!0)},N=()=>$(),D=(O)=>{try{Z?.call(X,O)}finally{$()}};if(K=()=>_(!1),this.settlePendingVoiceWait=K,W=setTimeout(()=>_(!1,Error(`Configured browser voice "${Y}" could not be resolved because the browser did not publish its voice inventory within ${E0/1000} seconds.`)),E0),j)X.addEventListener("voiceschanged",N);else X.onvoiceschanged=D;$()})}async resolveBrowserVoice(Q){let Y=typeof this.config?.voice==="string"?this.config.voice.trim():"",J=speechSynthesis.getVoices();if(Y&&J.length===0){if(!await this.waitForBrowserVoices(Q,Y)||Q!==this.speakRunId)return{shouldContinue:!1,voice:null};J=speechSynthesis.getVoices()}if(Q!==this.speakRunId)return{shouldContinue:!1,voice:null};let G=f3(J,Y||void 0);if(Y&&!G)throw Error(`Configured browser voice "${Y}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return{shouldContinue:!0,voice:G}}async speak(Q){if(!this.config)throw Error("TTS not initialized");this.stop();let Y=this.speakRunId,J=await this.resolveBrowserVoice(Y);if(!J.shouldContinue)return;let G=this.splitIntoChunks(Q);for(let X of G){if(Y!==this.speakRunId)break;if(!await this.speakChunk(X.text,X.offset,Y,J.voice))break}}async speakSegments(Q){if(!this.config)throw Error("TTS not initialized");this.stop();let Y=this.speakRunId,J=await this.resolveBrowserVoice(Y);if(!J.shouldContinue)return;for(let G of Q){if(Y!==this.speakRunId)break;let X=this.splitIntoChunks(G.text);for(let Z of X){if(Y!==this.speakRunId)break;if(!await this.speakChunk(Z.text,G.startOffset+Z.offset,Y,J.voice))break}let j=Math.max(0,Number(G.pauseMsAfter||0));if(j>0&&Y===this.speakRunId){if(!await this.waitForPause(j,Y))break}}}async waitForPause(Q,Y){return await new Promise((J)=>setTimeout(J,Q)),Y===this.speakRunId}splitIntoChunks(Q){if(Q.length<=260)return[{text:Q,offset:0}];let J=this.segmentSentences(Q),G=[],X="",j=0;for(let Z of J){let B=Z.text.trim();if(!B)continue;let W=Z.text.search(/\S/),K=Z.offset+(W===-1?0:W);if(!X){X=B,j=K;continue}let U=`${X} ${B}`;if(U.length<=260)X=U;else G.push({text:X,offset:j}),X=B,j=K}if(X)G.push({text:X,offset:j});return G.length?G:[{text:Q,offset:0}]}getHighlightMode(){return(this.config?.providerOptions||{}).highlightMode==="word"?"word":"sentence"}getSegmentationPolicy(){let Q=this.config?.providerOptions||{},Y=Q.segmenter||{},G=Y.mode!=="regexOnly",X=typeof Y.locale==="string"&&Y.locale.trim().length>0?Y.locale:typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:void 0;return{useSentenceSegmenter:G,useWordSegmenter:G,locale:X}}segmentSentences(Q){let Y=this.getSegmentationPolicy();return S7(Q,{locale:Y.locale,useSentenceSegmenter:Y.useSentenceSegmenter})}inferWordLength(Q,Y){let J=Math.max(0,Math.min(Y,Math.max(0,Q.length-1)));return Q.slice(J).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(Q,Y,J,G){return new Promise((X,j)=>{if(J!==this.speakRunId){X(!1);return}let Z=new SpeechSynthesisUtterance(Q);if(this.utterance=Z,G&&x3(G))Z.voice=G;if(this.config?.rate)Z.rate=this.config.rate;if(this.config?.pitch)Z.pitch=this.config.pitch;let B=!1,W=!1,K=null,U=null,_=()=>{if(this.utterance===Z)this.utterance=null},$=()=>{if(K!==null)clearTimeout(K),K=null},N=()=>{Z.onstart=null,Z.onend=null,Z.onerror=null,Z.onpause=null,Z.onresume=null,Z.onboundary=null},D=(P,F)=>{if(W)return;if(W=!0,$(),N(),_(),U&&this.settlePendingChunk===U)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1,this._isPaused=!1;if(F)j(F);else X(P)},O=(P)=>Error(P==="ended"?"Browser speech synthesis ended before audio started. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.":`Browser speech synthesis did not start within ${R0/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);U=()=>D(!1),this.settlePendingChunk=U,Z.onstart=()=>{if(J!==this.speakRunId){D(!1);return}B=!0,$(),this._isPlaying=!0,this._isPaused=!1;try{this.onPlaybackStart?.()}catch(P){console.error("Browser TTS playback-start callback failed",P)}},Z.onend=()=>{if(J!==this.speakRunId){D(!1);return}if(!B){D(!1,O("ended"));return}D(!0)},Z.onerror=(P)=>{if(J!==this.speakRunId){D(!1);return}if(P.error==="interrupted"||P.error==="canceled"){D(!1);return}D(!1,Error(`Speech synthesis error: ${P.error}`))},Z.onpause=()=>{if(J!==this.speakRunId)return;this._isPaused=!0},Z.onresume=()=>{if(J!==this.speakRunId)return;this._isPaused=!1},Z.onboundary=(P)=>{if(J!==this.speakRunId)return;if(console.log("[BrowserProvider] Boundary event:",P.name,"charIndex:",P.charIndex,"charLength:",P.charLength),P.name!=="word"||!this.onWordBoundary)return;if(this.getHighlightMode()==="sentence")return;let F=Math.max(0,Math.min(P.charIndex,Math.max(0,Q.length-1))),L=Number(P.charLength||0),C=this.inferWordLength(Q,F),v=Number.isFinite(L)&&L>0&&L<=80&&F+L<=Q.length?L:C,k=Q.substring(F,Math.min(Q.length,F+v)).trim(),p=Y+F;console.log("[BrowserProvider] Calling onWordBoundary with word:",k,"at position:",p),this.onWordBoundary(k,p,v)},K=setTimeout(()=>{if(W||B||J!==this.speakRunId)return;D(!1,O("timedOut")),speechSynthesis.cancel()},R0);try{speechSynthesis.speak(Z)}catch(P){D(!1,P instanceof Error?P:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPlaying&&!this._isPaused)speechSynthesis.pause()}resume(){if(this._isPlaying&&this._isPaused)speechSynthesis.resume()}stop(){let Q=this.utterance,Y=this._isPlaying||Q!==null;if(this.speakRunId+=1,this.settlePendingVoiceWait?.(),this.settlePendingChunk?.(),Y)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}updateSettings(Q){if(!this.config)this.config={};if(Q.rate!==void 0)this.config.rate=Q.rate;if(Q.pitch!==void 0)this.config.pitch=Q.pitch;if(Q.voice!==void 0)this.config.voice=Q.voice;if(Q.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...Q.providerOptions||{}}}onWordBoundary}var T=(Q)=>Q.trim().replace(/\s+/g," "),y0=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,X9=(Q)=>{if(Q.hidden)return!0;if(Q.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(Q.getAttribute("aria-hidden")==="true")return!0;if(Q.hasAttribute("inert"))return!0;let Y=Q.classList;if(Y?.contains("sr-only")||Y?.contains("pie-sr-only")||Y?.contains("visually-hidden"))return!0;if(typeof window<"u"){let J=window.getComputedStyle(Q);if(J.display==="none"||J.visibility==="hidden")return!0;let G=Number.parseFloat(J.width||"0"),X=Number.parseFloat(J.height||"0"),j=Number.isFinite(G)&&Number.isFinite(X)&&G<=1&&X<=1,Z=J.clipPath.includes("inset(50%")||J.clipPath.includes("inset(100%")||J.clip.includes("rect(0px, 0px, 0px, 0px)")||J.clip.includes("rect(0 0 0 0)");if((J.position==="absolute"||J.position==="fixed")&&j&&(J.overflow==="hidden"||Z))return!0;if(J.opacity==="0"&&j)return!0}return!1},C7=(Q,Y)=>{let J=Q.nodeType===1?Q:Q.parentElement;while(J){if(X9(J))return!0;if(Y&&J===Y)break;J=J.parentElement}return!1};var f0=new Set(["computer-read-aloud","all"]),C0=new Set([...f0,"screen-reader"]),T0=new Set,k3=(Q)=>{let Y=Q.getAttribute?.("data-tts-suppress");if(Y===null||Y===void 0)return!1;let J=Y.trim().toLowerCase();if(f0.has(J))return!0;if(C0.has(J))return!1;if(!T0.has(J))T0.add(J),console.warn(`[tts] data-tts-suppress="${Y}" is not one of ${Array.from(C0).join(", ")}; suppressing read-aloud for this content anyway, because a suppression attribute that fails open would leak the answer to items where reading is the construct. Correct the value to silence this.`);return!0},W1=(Q,Y)=>{let J=Q.nodeType===1?Q:Q.parentElement;while(J){if(k3(J))return!0;if(Y&&J===Y)break;J=J.parentElement}return!1},$7=(Q,Y)=>C7(Q,Y)||W1(Q),Z9=(Q,Y)=>{if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u"||typeof Q.intersectsNode!=="function")return{text:Q.toString(),filtered:!1};let J=[],G=!1,X=document.createTreeWalker(Y,NodeFilter.SHOW_TEXT),j=X.nextNode();while(j){let Z=j;if(Q.intersectsNode(Z))if($7(Z,Y))G=!0;else{let B=Z.textContent||"",W=Z===Q.startContainer?Q.startOffset:0,K=Z===Q.endContainer?Q.endOffset:B.length;J.push(B.slice(W,K))}j=X.nextNode()}return{text:J.join(""),filtered:G}},j9=(Q,Y,J)=>{if(!Q||!Y)return!1;if(/\s/.test(Q)||/\s/.test(Y))return!1;let G=J?.boundarySpacingMode??"segmenterPreferred";if(G==="none")return!1;if(G==="segmenterPreferred")try{let Z=globalThis.Intl?.Segmenter;if(typeof Z==="function"){let B=new Z(J?.locale,{granularity:"word"});if(Array.from(B.segment(`${Q}${Y}`)).filter((U)=>U.isWordLike!==!1&&U.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(Q),j=/[A-Za-z0-9]/.test(Y);return X&&j},F7=(Q,Y)=>{let J=new Map;if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u")return{text:"",map:J};let G=[],X=0,j=!0,Z=!1,B=null,W=null,K=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),U=K.nextNode();while(U){let $=U;if($.parentElement&&!$7($,Q)){let D=$.textContent||"",O=D.match(/\S/),P=O?O[0]:null;if(!j&&!Z&&j9(W,P,Y)){if(G.push(" "),B)J.set(X,B);X++,Z=!0}for(let F=0;F<D.length;F++){let L=D[F],C=/\s/.test(L);if(j){if(!C)j=!1,G.push(L),J.set(X,{node:$,offset:F}),B={node:$,offset:F},X++,Z=!1,W=L}else if(C){if(!Z)G.push(" "),J.set(X,{node:$,offset:F}),B={node:$,offset:F},X++;Z=!0}else G.push(L),J.set(X,{node:$,offset:F}),B={node:$,offset:F},X++,Z=!1,W=L}}U=K.nextNode()}let _=G.join("").trimEnd();while(J.has(_.length))J.delete(_.length);return{text:_,map:J}};var I3=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),x0=new Set(["audio","phoneme"]),I0=(Q)=>Q.replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&nbsp;/g," ").replace(/&#160;/g," ").replace(/&amp;/g,"&"),K1=(Q,Y,J)=>{for(let G=0;G<Y.length;G++)Q.push({char:Y[G],rawOffset:J===null?null:J+G})},v3=(Q,Y,J)=>{let G=Y.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!G)return 0;return K1(Q,I0(G[0]),J),G[0].length},k0=(Q)=>{Q.push({char:" ",rawOffset:null})},h3=(Q)=>{let Y=new Map,J=[],G=!0;for(let X of Q){if(/\s/.test(X.char)){if(!G&&J.length>0){if(J.push(" "),X.rawOffset!==null)Y.set(X.rawOffset,J.length-1)}G=!0;continue}if(J.push(X.char),X.rawOffset!==null)Y.set(X.rawOffset,J.length-1);G=!1}while(J.length>0&&J[J.length-1]===" ")J.pop();for(let[X,j]of Y)if(j>=J.length)Y.delete(X);return{text:J.join(""),rawToSpokenOffsetMap:Y}},m3=(Q)=>{return Q.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},u3=(Q,Y)=>{let J=new RegExp(`${Y}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),G=Q.match(J);return I0(G?.[2]??G?.[3]??"")||null},v0=(Q)=>{let Y=[],J=!1,G=!1,X=0;while(X<Q.length){let Z=Q[X];if(Z!=="<"){if(Z==="&"){let $=v3(Y,Q,X);if($>0){X+=$;continue}}K1(Y,Z,X),X++;continue}let B=Q.indexOf(">",X+1);if(B<0){K1(Y,Z,X),X++;continue}G=!0;let W=Q.slice(X,B+1),K=m3(W),U=/^<\s*\//.test(W),_=/\/\s*>$/.test(W);if(!U&&K==="sub"){let $=u3(W,"alias");if(!$){J=!0,X=B+1;continue}K1(Y,$,null);let N=Q.toLowerCase().indexOf("</sub>",B+1);X=N>=0?N+6:B+1;continue}if(!U&&K==="break"){k0(Y),X=B+1;continue}if(!U&&x0.has(K)){if(J=!0,_){X=B+1;continue}}if(K&&!I3.has(K)&&!x0.has(K)&&K!=="break"&&K!=="sub")J=!0;if(!U&&(K==="p"||K==="s"))k0(Y);X=B+1}let j=h3(Y);return{spokenText:T(j.text),rawToSpokenOffsetMap:j.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:G}};var p3=y0(),g3=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),c3=(Q)=>{let Y=Q.toLowerCase();return g3.get(Y)||Y},W9=(Q)=>{let Y=[];for(let J of Q.matchAll(p3)){let G=J[0],X=J.index??0;Y.push({text:G,normalized:c3(G),start:X,end:X+G.length})}return Y},d3=(Q)=>W9(Q).map((Y,J)=>({...Y,id:`speech-token-${J}`,sourceStart:Y.start,sourceEnd:Y.end,coordinateSystem:"normalized-speech"})),H7=(Q)=>{let Y=v0(Q.speechText);return{speechText:Q.speechText,spokenText:Y.spokenText,tokens:d3(Y.spokenText),rawToSpokenOffsetMap:Y.rawToSpokenOffsetMap,boundaryOffsetSpace:Y.unsupportedSemantic?"unsupported":Y.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Y.unsupportedSemantic,hasMarkup:Y.hasMarkup}},K9=(Q)=>Boolean(Q&&/^<[^>]+>$/.test(Q.trim())),T7=(Q)=>{if(!Q||K9(Q))return null;return H7({speechText:Q}).tokens[0]?.normalized??null},l3=(Q,Y)=>Q.find((J)=>J.start<=Y&&Y<J.end)||null,i3=(Q,Y)=>{let J=Q.rawToSpokenOffsetMap.get(Y);if(J!==void 0)return J;for(let G=Y;G<Q.speechText.length;G++){let X=Q.rawToSpokenOffsetMap.get(G);if(X!==void 0)return X;if(Q.speechText[G]===">")break}return null},B9=(Q,Y,J)=>{if(Y===null)return null;let G=l3(Q.tokens,Y);if(!G)return null;return{token:G,start:Y,length:Math.max(1,Math.min(J,G.end-Y)),confidence:0.75}},q9=(Q,Y)=>Boolean(Q&&Y&&Q.token.normalized===Y),U9=(Q)=>{if(Q.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Q.position)||K9(Q.boundaryWord))return null;let Y=Math.max(1,Number.isFinite(Q.length)?Q.length:1),J=T7(Q.boundaryWord),G=B9(Q.tokenization,i3(Q.tokenization,Q.position),Y),X=B9(Q.tokenization,Q.position>=0&&Q.position<Q.tokenization.spokenText.length?Q.position:null,Y);if(q9(G,J))return{...G,confidence:1};if(q9(X,J))return{...X,confidence:1};if(J)return null;return Q.tokenization.boundaryOffsetSpace==="raw-ssml"?G||X:X||G},h0=(Q)=>{if(Q.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Q.position)||K9(Q.boundaryWord))return null;let Y=Math.max(1,Number.isFinite(Q.length)?Q.length:1),J=T7(Q.boundaryWord),G=B9(Q.tokenization,Q.position>=0&&Q.position<Q.tokenization.spokenText.length?Q.position:null,Y);if(q9(G,J))return{...G,confidence:1};if(J)return null;return G};var s3=[{phrase:["plus","or","minus"],visible:"±",score:8},{phrase:["square","root"],visible:"√",score:8},{phrase:["divided","by"],visible:"/",score:7},{phrase:["all","over"],visible:"/",score:7},{phrase:["equals"],visible:"=",score:7},{phrase:["equal"],visible:"=",score:7},{phrase:["times"],visible:"⁢",score:7},{phrase:["multiplied","by"],visible:"⁢",score:7},{phrase:["over"],visible:"/",score:6},{phrase:["squared"],visible:"²",score:6},{phrase:["squared"],visible:"2",score:4},{phrase:["negative"],visible:"-",score:5},{phrase:["minus"],visible:"-",score:5},{phrase:["plus"],visible:"+",score:5}],n3=(Q,Y)=>{let J=[];for(let G=0;G<Q.length;G++){for(let X=0;X<Y.length;X++)if(Q[G].normalized===Y[X].normalized)J.push({spokenStartToken:G,spokenEndToken:G+1,visibleToken:X,score:10});for(let X of s3){let j=Q.slice(G,G+X.phrase.length);if(j.length!==X.phrase.length)continue;if(!j.every((Z,B)=>Z.normalized===X.phrase[B]))continue;for(let Z=0;Z<Y.length;Z++){if(Y[Z].text!==X.visible)continue;J.push({spokenStartToken:G,spokenEndToken:G+X.phrase.length,visibleToken:Z,score:X.score})}}}return J},r3=(Q,Y)=>{let J=n3(Q,Y).sort((W,K)=>Q[W.spokenStartToken].start-Q[K.spokenStartToken].start||Y[W.visibleToken].start-Y[K.visibleToken].start),G=Array(J.length).fill(0),X=Array(J.length).fill(-1);for(let W=0;W<J.length;W++){let K=J[W];G[W]=K.score;for(let U=0;U<W;U++){let _=J[U];if(_.spokenEndToken<=K.spokenStartToken&&_.visibleToken<K.visibleToken){let $=K.spokenStartToken-_.spokenEndToken,N=K.visibleToken-_.visibleToken-1,D=Math.max(0,Math.abs($-N)-2),O=G[U]+K.score-D;if(O>G[W])G[W]=O,X[W]=U}}}let j=-1;for(let W=0;W<G.length;W++)if(j<0||G[W]>G[j])j=W;if(j<0)return[];let Z=[],B=j;while(B>=0)Z.unshift(J[B]),B=X[B];return Z.map((W)=>{let K=Q[W.spokenStartToken],U=Q[W.spokenEndToken-1],_=Y[W.visibleToken];return{spokenStart:K.start,spokenEnd:U.end,visibleStart:_.start,visibleEnd:_.end,score:W.score}})},o3=(Q,Y,J)=>{if(Q.length===0)return 0;let G=Q.length/Math.max(1,Math.min(Y.length,J.length)),X=Q.reduce((j,Z)=>j+Z.score,0)/Q.length/10;return Math.min(1,G*X)},U1=(Q)=>{let Y=H7({speechText:Q.speechText}),J=T(Q.visibleText),G=Y.tokens,X=W9(J),j=Y.unsupportedSemantic?[]:r3(G,X),Z=o3(j,G,X),B=Y.spokenText===J&&Y.spokenText.length>0,W=j.length===1&&j[0].score===10&&G.length<=2&&X.length<=2,K=Y.unsupportedSemantic?"region-fallback":B?"exact-word":j.length>=2||W?Z>=0.12?"anchor-span":"region-fallback":"region-fallback";return{speech:Y,visibleText:J,playbackMode:K,anchors:j,confidence:Z}},m0=(Q,Y)=>{if(Q.playbackMode==="region-fallback")return null;let J=Q.anchors.find((j)=>j.spokenStart<=Y&&Y<j.spokenEnd);if(J)return{start:J.visibleStart,end:J.visibleEnd};let G=null,X=null;for(let j of Q.anchors){if(j.spokenEnd<=Y){G=j;continue}if(j.spokenStart>Y){X=j;break}}if(G&&X)return{start:Math.min(G.visibleStart,X.visibleStart),end:Math.max(G.visibleEnd,X.visibleEnd)};return null};var a3=new Map([["+",["plus"]],["-",["minus","negative"]],["−",["minus","negative"]],["×",["times","multiplied by"]],["÷",["divided by"]],["=",["equals","equal to"]],["≠",["is not equal to","not equal to"]],["≈",["approximately equals"]],["≤",["less than or equal to"]],["≥",["greater than or equal to"]],["<",["less than"]],[">",["greater than"]],["∠",["angle"]],["△",["triangle"]],["□",["box"]],["○",["circle"]],["°",["degrees","degree"]],["%",["percent"]],["'",["prime"]],["′",["prime"]],["•",["times"]],["·",["times"]],["⁢",["times","multiplied by"]]]),t3=new Map([["⁡","function-application"],["⁢","implicit-multiply"],["⁣","invisible-separator"],["⁤","invisible-plus"]]),u0=new Map([["2",["squared"]],["3",["cubed"]]]),e3=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),Q5=(Q)=>Q.replace(/\s+/g," ").trim(),D7=(Q)=>(Q.localName||Q.tagName||"").toLowerCase(),Y5=(Q)=>Q.nodeType===Node.ELEMENT_NODE,y7=(Q)=>Array.from(Q.childNodes).filter(Y5),V9=(Q)=>Q5(Q.textContent||""),Y7=(Q,Y)=>({type:"element-range",quality:Y,element:Q}),J5=(Q)=>{switch(Q){case"mi":return"identifier";case"mn":return"number";case"mo":return"operator";case"mtext":case"ms":return"text";case"mspace":return"space";default:return"unknown"}},G5=(Q,Y)=>{if(Y==="operator"){if(Q==="−")return"-";return Q}return Q.toLowerCase()},X5=(Q,Y,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return u0.get(Q)??[];if(Q==="|")return["absolute value"];if(Y==="operator")return a3.get(Q)||[];return[]},N7=(Q)=>{let Y=Q.normalized??G5(Q.text,Q.kind||"unknown");return{id:`math-token-${Q.state.nextId++}`,kind:Q.kind,role:Q.role,text:Q.text,normalized:Y,spokenAliases:X5(Q.text,Q.kind,Q.role),sourceElement:Q.sourceElement,path:Q.path,target:Q.target||Y7(Q.sourceElement,"element-range"),optional:Q.optional}},M7=(Q,Y,J="tokens")=>{Q[J].push(Y)},p0=(Q,Y,J)=>{y7(Q).forEach((G,X)=>J7(G,Y,`${J}/${D7(G)}[${X}]`))},Z5=(Q,Y,J)=>{let G=y7(Q);if(G[0])J7(G[0],Y,`${J}/numerator`);if(M7(Y,N7({state:Y,kind:"structure",role:"fraction",text:"/",sourceElement:Q,path:J,target:Y7(Q,"element-range")})),G[1])J7(G[1],Y,`${J}/denominator`)},j5=(Q,Y,J)=>{let G=Q.getAttribute("open")||"(",X=Q.getAttribute("close")||")";M7(Y,N7({state:Y,kind:"operator",role:G==="|"?"absolute-value-fence":"open-fence",text:G,sourceElement:Q,path:`${J}/open`,target:Y7(Q,"element-range")})),p0(Q,Y,J),M7(Y,N7({state:Y,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Q,path:`${J}/close`,target:Y7(Q,"element-range")}))},B5=(Q,Y,J)=>{let G=y7(Q);if(G[0])J7(G[0],Y,`${J}/base`);let X=G[1];if(!X)return;let j=V9(X);if(u0.has(j)){M7(Y,N7({state:Y,kind:"structure",role:"superscript",text:j,normalized:j,sourceElement:X,path:`${J}/exponent`,target:Y7(Q,"element-range")}));return}J7(X,Y,`${J}/exponent`)},q5=(Q,Y,J,G)=>{M7(Y,N7({state:Y,kind:"structure",role:G,text:V9(Q)||G,normalized:`\x00${G}`,sourceElement:Q,path:J,target:Y7(Q,"element-range")}))},W5=(Q,Y,J)=>{let G=0;for(let X of y7(Q)){if(D7(X)==="mtr"||D7(X)==="mlabeledtr")G++,M7(Y,N7({state:Y,kind:"layout",role:"table-row",text:`row-${G}`,normalized:`row-${G}`,sourceElement:X,path:`${J}/row[${G}]`,target:Y7(X,"region-fallback")}),"layoutTargets");J7(X,Y,`${J}/${D7(X)}[${G}]`)}},K5=(Q,Y,J)=>{let G=V9(Q);if(!G)return;let X=J5(D7(Q)),j=X==="operator"?t3.get(G):void 0,Z=j??(X==="operator"&&(G==="("||G===")")?"grouping-fence":X);M7(Y,N7({state:Y,kind:X,role:Z,text:G,sourceElement:Q,path:J,target:j&&Q.parentElement?Y7(Q.parentElement,"region-fallback"):void 0,optional:Boolean(j)||Z==="grouping-fence"}))},J7=(Q,Y,J)=>{let G=D7(Q);switch(G){case"annotation":case"annotation-xml":return;case"semantics":{let X=y7(Q).find((j)=>{let Z=D7(j);return Z!=="annotation"&&Z!=="annotation-xml"});if(X)J7(X,Y,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":K5(Q,Y,J);return;case"mfrac":Z5(Q,Y,J);return;case"msup":B5(Q,Y,J);return;case"mfenced":j5(Q,Y,J);return;case"mtable":W5(Q,Y,J);return;case"mphantom":return;case"maction":{let X=y7(Q)[0];if(X)J7(X,Y,`${J}/action`);return}default:{let X=e3.get(G);if(X){q5(Q,Y,J,X);return}p0(Q,Y,J)}}},g0=(Q)=>{let Y={tokens:[],layoutTargets:[],nextId:0};return J7(Q,Y,"/math"),{tokens:Y.tokens,layoutTargets:Y.layoutTargets,expressionTarget:Y7(Q,"region-fallback")}};var c0=(Q)=>{if(!Q.boundary)return null;return Q.alignment.segments.find((J)=>J.speechTokenIds.includes(Q.boundary.token.id))?.target||null};var U5=(Q)=>{let Y=[],J=new Set,G=(X)=>{let j=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(j.length===0)return;let Z=j.join(" ");if(J.has(Z))return;J.add(Z),Y.push(j)};G(Q.normalized);for(let X of Q.spokenAliases)G(X);return Y},d0=(Q,Y,J)=>{let G=0;for(let X of J){if(X.length<=G)continue;let j=!0;for(let Z=0;Z<X.length;Z++){let B=Q[Y+Z];if(!B||B.normalized.toLowerCase()!==X[Z]){j=!1;break}}if(j)G=X.length}return G},V5=(Q,Y)=>{let J=[],G=0;for(let X of Y){let j=U5(X);if(X.optional){let Z=d0(Q,G,j);if(Z>0)J.push({speechTokens:Q.slice(G,G+Z),math:X}),G+=Z;continue}while(G<Q.length){let Z=d0(Q,G,j);if(Z>0){J.push({speechTokens:Q.slice(G,G+Z),math:X}),G+=Z;break}G++}}return J},A5=(Q,Y,J)=>{let G=J.filter((Z)=>!Z.optional).length,X=Q.filter((Z)=>!Z.math.optional).length,j=Q.reduce((Z,B)=>Z+B.speechTokens.length,0);return G>0&&X===G&&j===Y.length},_5=(Q)=>Q.map(({speechTokens:Y,math:J})=>({speechTokenIds:Y.map((G)=>G.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),l0=(Q)=>{let Y=Q.minExactWordConfidence??0.95,J=V5(Q.speech.tokens,Q.math.tokens),G=A5(J,Q.speech.tokens,Q.math.tokens)?1:0;return{segments:G>=Y?_5(J):[],confidence:G,fallbackTarget:Q.math.expressionTarget}};var f7=(Q)=>{let Y=H7({speechText:Q.speechText}),J=g0(Q.mathElement);return{speech:Y,math:J,result:l0({speech:Y,math:J})}};var i0=(Q,Y)=>{let J=h0({tokenization:Q.speech,position:Y.position,length:Y.length,boundaryWord:Y.boundaryWord});return c0({alignment:Q.result,boundary:J})},s0=(Q,Y)=>{let J=T7(Y.boundaryWord);if(!J)return null;let G=Q.math.tokens.filter((X)=>X.normalized.toLowerCase()===J||X.spokenAliases.some((j)=>j.toLowerCase()===J));return G.length===1?G[0].target:null};var $5=new Set(["math","maction","menclose","merror","mfenced","mfrac","mi","mmultiscripts","mn","mo","mover","mpadded","mphantom","mprescripts","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msubsup","msup","mtable","mtd","mtext","mtr","munder","munderover","none","semantics","annotation","annotation-xml"]),F5=new Set(["accent","accentunder","align","bevelled","class","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","encoding","fence","height","href","id","largeop","length","linethickness","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","width","xmlns","xml:lang"]),n0=(Q)=>Q.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),H5=(Q)=>n0(Q).replace(/"/g,"&quot;"),D5=(Q,Y)=>{let J=Q.toLowerCase(),G=Y.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!F5.has(J))return!0;if(G.includes("javascript:"))return!0;if(G.includes("data:text/html"))return!0;return!1},N5=(Q)=>{let Y=Q.localName.toLowerCase();if(!$5.has(Y))return!1;let J=Q.namespaceURI;return!J||J==="http://www.w3.org/1998/Math/MathML"||J==="http://www.w3.org/1999/xhtml"},r0=(Q)=>{if(Q.nodeType===Node.TEXT_NODE)return n0(Q.textContent||"");if(Q.nodeType===Node.COMMENT_NODE)return"";if(Q.nodeType!==Node.ELEMENT_NODE)return null;let Y=Q;if(!N5(Y))return null;let J=Y.localName.toLowerCase(),G=[];for(let Z of Array.from(Y.attributes)){let B=Z.name.toLowerCase();if(D5(B,Z.value))continue;if(B==="xmlns"&&Z.value!=="http://www.w3.org/1998/Math/MathML")return null;G.push(`${B}="${H5(Z.value)}"`)}if(J==="math"&&!G.some((Z)=>Z.startsWith("xmlns=")))G.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let Z of Array.from(Y.childNodes)){let B=r0(Z);if(B===null)return null;X.push(B)}let j=G.length>0?` ${G.join(" ")}`:"";return`<${J}${j}>${X.join("")}</${J}>`},M5=(Q)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Q,"application/xml");return null},V1=(Q)=>{let Y=String(Q||"").trim();if(!Y)return null;let J=M5(Y);if(!J)return null;if(J.getElementsByTagName("parsererror").length>0)return null;let G=J.documentElement;if(!G||G.localName.toLowerCase()!=="math")return null;return r0(G)};var o0=(Q)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Q}),A9=(Q)=>Q.classList?.contains("MathJax")||Q.tagName?.toLowerCase()==="mjx-container",a0=(Q)=>Q.tagName?.toLowerCase()==="mjx-assistive-mml",_9=(Q)=>{let Y=Q.tagName?.toLowerCase();return Y==="annotation"||Y==="annotation-xml"},z5=(Q)=>{let Y=Q.getAttribute("data-mathml");return Y&&Y.trim()?Y:null},O5=(Q)=>{return Q.querySelector("mjx-assistive-mml math")?.outerHTML||null},P5=(Q)=>{if(Q.tagName.toLowerCase()==="math")return V1(Q.outerHTML);let Y=z5(Q);if(Y){let J=V1(Y);if(J)return J}if(A9(Q)){let J=O5(Q);if(J){let G=V1(J);if(G)return G}}return null},L5=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),w5=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),R5=(Q,Y)=>{let J=Q.parentElement,G=null;while(J&&J!==Y){let X=(J.getAttribute("role")||"").toLowerCase(),j=J.tagName.toUpperCase();if(L5.has(j)||w5.has(X)){G=J;break}J=J.parentElement}return G||Y},E5=(Q)=>Boolean(typeof Q.querySelector==="function"&&Q.querySelector("math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Q.tagName?.toLowerCase()==="math"||Q.hasAttribute?.("data-mathml")||A9(Q),z7=(Q,Y,J)=>{if(/[.,;:!?]/.test(Y)&&Q.chars.length>0&&Q.chars[Q.chars.length-1]===" ")Q.chars.pop(),Q.position--,Q.map.delete(Q.position);if(Q.chars.push(Y),J)Q.map.set(Q.position,J),Q.lastMapped=J;else if(Q.lastMapped)Q.map.set(Q.position,Q.lastMapped);Q.position++},t0=(Q,Y)=>{if(Q.inLeadingWhitespace||Q.lastCharWasWhitespace||Q.chars.length===0)return!1;let J=Q.chars[Q.chars.length-1];return j9(J,Y,Q.options)},e0=(Q,Y)=>{let J=Y.textContent||"",G=!1;for(let X=0;X<J.length;X++){let j=J[X],Z=/\s/.test(j);if(Q.inLeadingWhitespace){if(!Z)Q.inLeadingWhitespace=!1,z7(Q,j,{node:Y,offset:X}),G=!0,Q.lastCharWasWhitespace=!1;continue}if(Z){if(!Q.lastCharWasWhitespace)z7(Q," ",{node:Y,offset:X});Q.lastCharWasWhitespace=!0;continue}if(!G&&t0(Q,j))z7(Q," ",{node:Y,offset:X});z7(Q,j,{node:Y,offset:X}),G=!0,Q.lastCharWasWhitespace=!1}},b5=(Q,Y)=>{for(let J=0;J<Y.text.length;J++){let G=Y.text[J],X=/\s/.test(G),j=Y.map.get(J)||null,Z=j?.node||Q.lastMapped?.node||null,B=j?.offset??Q.lastMapped?.offset??0,W=j?{node:j.node,offset:j.offset}:Z?{node:Z,offset:B}:null;if(Q.inLeadingWhitespace){if(X)continue;Q.inLeadingWhitespace=!1}if(X){if(!Q.lastCharWasWhitespace)z7(Q," ",W);Q.lastCharWasWhitespace=!0;continue}if(J===0&&t0(Q,G))z7(Q," ",W);if(z7(Q,G,W),Q.lastCharWasWhitespace=!1,j)Q.map.set(Q.position-1,{node:j.node,offset:j.offset}),Q.lastMapped={node:j.node,offset:j.offset};else if(Z)Q.map.set(Q.position-1,{node:Z,offset:B})}},S5=(Q)=>{if(typeof DOMParser>"u")return"";let Y=new DOMParser().parseFromString(Q,"application/xml");if(Y.getElementsByTagName("parsererror").length>0)return"";let J=[],G=(X)=>{if(X.nodeType===3){let Z=X.textContent||"";if(Z.trim())J.push(Z);return}if(X.nodeType!==1)return;let j=X;if(_9(j))return;for(let Z of Array.from(j.childNodes))G(Z)};return G(Y.documentElement),T(J.join(" "))},C5=(Q,Y)=>{let J=new Map,G=A9(Q)?Q.querySelector("mjx-assistive-mml math"):null;if(!G)return J;let X=[],j=(B)=>{if(B.nodeType===3){let W=B.textContent||"";for(let K=0;K<W.length;K++)if(!/\s/.test(W[K]))X.push({node:B,offset:K});return}if(B.nodeType!==1||_9(B))return;for(let W of Array.from(B.childNodes))j(W)};j(G);let Z=0;for(let B=0;B<Y.length;B++){if(/\s/.test(Y[B]))continue;let W=X[Z];if(W?.node.textContent?.[W.offset]!==Y[B])return new Map;J.set(B,W),Z++}return Z===X.length?J:new Map},T5=(Q,Y,J)=>{let G=o0(J),X=(B)=>{if($7(B,Q))return;if(B.nodeType===3){e0(G,B);return}if(B.nodeType!==1)return;let W=B;if(a0(W)||_9(W))return;for(let K of Array.from(W.childNodes))X(K)};X(Q),Q8(G);let j=T(G.chars.join(""));if(j)return{text:j,map:G.map};let Z=S5(Y);if(!Z)return F7(Q,J);return{text:Z,map:C5(Q,Z)}},Q8=(Q)=>{while(Q.chars.length>0&&/\s/.test(Q.chars[Q.chars.length-1]))Q.chars.pop(),Q.position--,Q.map.delete(Q.position)},y5=(Q,Y)=>{let J=o0(Y),G=[],X=0,j,Z=!1,B=()=>{let U=T(J.chars.slice(X,J.chars.length).join(""));if(U)G.push({type:"text",text:U,sourceElement:j});X=J.chars.length,j=void 0},W=(U)=>{if($7(U,Q))return;if(U.nodeType===Node.TEXT_NODE){let N=R5(U,Q);if(j&&N!==j)B();j=N,e0(J,U);return}if(U.nodeType!==Node.ELEMENT_NODE)return;let _=U;if(a0(_))return;let $=P5(_);if($){B();let N=T5(_,$,Y);b5(J,N);let D=T(N.text);G.push({type:"math",mathml:$,fallbackText:D,sourceElement:_}),X=J.chars.length,Z=!0;return}for(let N of Array.from(_.childNodes))W(N)};for(let U of Array.from(Q.childNodes))W(U);Q8(J),B();let K=J.chars.join("");while(J.map.has(K.length))J.map.delete(K.length);return{visibleText:K,map:J.map,chunks:G,containsMathMarkup:Z}},O7=(Q,Y)=>{if(!E5(Q)){let{text:J,map:G}=F7(Q,Y);return{visibleText:J,map:G,chunks:J?[{type:"text",text:J}]:[],containsMathMarkup:!1}}return y5(Q,Y)};var $9=null,Y8=Promise.resolve(),x5=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",k5=async(Q)=>{if(!$9)Z8(Q),$9=import("./chunks/sre-engine-wf9s43gg.js").then(({default:Y})=>{if(!Y||typeof Y.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Y});return $9},I5=(Q)=>Q==="en"?"clearspeak":"mathspeak",J8=(Q)=>!!Q&&typeof Q==="object"&&!Array.isArray(Q),G8=(Q)=>typeof Q==="string"&&Q.trim()?Q.trim():void 0,j7=(Q)=>{if(!J8(Q))return;let Y=G8(Q.domain),J=G8(Q.style),G=J8(Q.engineOptions)?Q.engineOptions:void 0;if(!Y&&!J&&!G)return;return{...Y?{domain:Y}:{},...J?{style:J}:{},...G?{engineOptions:G}:{}}},v5=async(Q,Y,J,G)=>{let X=x5(Y),j=j7(G),Z=j?.engineOptions||{};await Q.setupEngine?.({...X8(Z),...Z,locale:X,domain:j?.domain||I5(X),...j?.style?{style:j.style}:{},modality:"speech",markup:J}),await Q.engineReady?.()},h5=async(Q)=>{let Y=Y8.then(Q,Q);return Y8=Y.then(()=>{return},()=>{return}),Y},j8=async(Q,Y,J,G,X)=>h5(async()=>{return await v5(Q,J,G,X),Q.toSpeech(Y)}),m5=(Q)=>Q.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),u5=async(Q,Y,J,G)=>{try{let X=m5(await j8(Q,Y,J,"ssml",G));return X.includes("<speak")?X:null}catch(X){return console.debug("[TTSService] Math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},A1=async(Q,Y={})=>{if(!Q.some((K)=>K.type==="math"))return{speechText:T(Q.map((K)=>K.type==="text"?K.text:K.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let J=null,G=!1,X=!1,j=Y.loadSre||(()=>k5(j7(Y.mathSpeech)?.engineOptions)),Z=[];for(let K of Q){if(K.type==="text"){Z.push(K.text);continue}try{if(!J)J=await j();let U=T(await j8(J,K.mathml,Y.language,"none",Y.mathSpeech));if(U){Z.push(U),G=!0;continue}X=!0,Z.push(K.fallbackText)}catch(U){X=!0,console.debug("[TTSService] Math speech generation failed; using visible fallback",{message:U instanceof Error?U.message:String(U)}),Z.push(K.fallbackText)}}let B=T(Z.join(" ")),W;if(Y.produceSsml&&J&&G&&Q.length===1&&Q[0].type==="math")W=await u5(J,Q[0].mathml,Y.language,Y.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:G,usedFallback:X,ssml:W}};var p5=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",g5="sre-v1",c5=256,F9=(Q)=>{if(Array.isArray(Q))return`array:[${Q.map(F9).join(",")}]`;if(Q&&typeof Q==="object")return`object:{${Object.entries(Q).sort(([Y],[J])=>Y.localeCompare(J)).map(([Y,J])=>`${JSON.stringify(Y)}:${F9(J)}`).join(",")}}`;if(Q===null)return"null:null";if(typeof Q>"u")return"undefined:";if(typeof Q==="function")return`function:${Q.name||"anonymous"}`;if(typeof Q==="symbol")return`symbol:${String(Q)}`;if(typeof Q==="bigint")return`bigint:${Q.toString()}`;if(typeof Q==="number")return Number.isFinite(Q)?`number:${Q}`:`number:${String(Q)}`;return`${typeof Q}:${JSON.stringify(Q)}`},B8=(Q,Y,J,G)=>`${g5}\x00${p5(Q)}\x00${Y?"ssml":"plain"}\x00${F9(J??null)}\x00${G}`,H9=(Q={})=>{let Y=Math.max(1,Q.maxEntries??c5),J=Q.resolve??((j,Z)=>A1([j],Z)),G=new Map,X=(j,Z)=>{G.delete(j),G.set(j,Z);while(G.size>Y){let B=G.keys().next().value;if(B!==void 0)G.delete(B)}};return async(j,Z)=>{let B=j7(Z.mathSpeech),W=Z.produceSsml===!0,K=B8(Z.language,W,B,j.mathml),U=G.get(K);if(U)return G.delete(K),G.set(K,U),U;let _=await J(j,{...Z,mathSpeech:B});if(W&&_.ssml&&Y>1)X(B8(Z.language,!1,B,j.mathml),{speechText:_.speechText,usedMathSpeech:_.usedMathSpeech,usedFallback:_.usedFallback});return X(K,_),_}};var q8=(Q,Y)=>{let J=T7(Y.word);if(Q.id!==Y.chunkId)return{chunkId:Y.chunkId,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Y.providerOffsetSpace==="unknown"||Q.offsetSpace==="unsupported")return{chunkId:Q.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let G=U9({tokenization:Q.catalogAlignment?.speech??H7({speechText:Q.speechText}),position:Y.position,length:Y.length,boundaryWord:Y.word});if(!G)return{chunkId:Q.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};return{chunkId:Q.id,normalizedWord:J,chunkSpokenStart:G.start,chunkSpokenEnd:G.start+G.length,confidence:G.confidence,reason:Q.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var P7=(Q)=>{if(Q.semanticTarget)return{activeTarget:Q.semanticTarget,regionTarget:Q.regionTarget,quality:Q.semanticTarget.quality==="exact-word"?"exact-word":Q.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:Q.confidence,reason:Q.reason};if(Q.expressionTarget)return{activeTarget:Q.expressionTarget,regionTarget:Q.regionTarget,quality:"expression",confidence:Q.confidence,reason:Q.reason};return{activeTarget:null,regionTarget:Q.regionTarget,quality:"region",confidence:Q.confidence,reason:Q.reason}};var K8=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),D9="mi,mn,mo,mtext",U8="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",V8=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),A8=(Q)=>{if(Q.type==="text-range")return Q.node.parentElement;return Q.element},_1=(Q)=>{let Y=Q;while(Y){if(Y.localName?.toLowerCase()==="mjx-container")return Y;Y=Y.parentElement}return null},W8=(Q)=>{if(!Q)return!1;if(_1(Q))return!1;return!C7(Q)},_8=(Q)=>{let Y=Q.getBoundingClientRect?.();return Boolean(Y&&Y.width>0&&Y.height>0)},N9=(Q)=>{let Y=Q;while(Y){if(Y.localName?.toLowerCase()==="math")return Y;Y=Y.parentElement}return null},$8=(Q,Y)=>{if(Q.length===0)return!1;if(Q.length!==Y.length)return!1;for(let J=0;J<Q.length;J+=1){let G=K8.get(Q[J].localName.toLowerCase());if(!G)return!1;if(Y[J].localName.toLowerCase()!==G)return!1}return!0},d5=(Q,Y)=>{if(!Q)return null;if(!K8.has(Q.localName.toLowerCase()))return null;if(Y.querySelector(V8))return null;let J=N9(Q),G=Y.querySelector("mjx-math");if(!J||!G)return null;let X=Array.from(J.querySelectorAll(D9)),j=X.indexOf(Q);if(j<0)return null;let Z=Array.from(G.querySelectorAll(U8));if(!$8(X,Z))return null;let B=Z[j];if(!B||!_8(B))return null;return B},F8=(Q)=>{let Y=_1(Q);if(Y){if(Y.querySelector(V8))return"expression";let X=N9(Q)??Q,j=Y.querySelector("mjx-math");if(!j)return"expression";let Z=Array.from(X.querySelectorAll(D9)),B=Array.from(j.querySelectorAll(U8));if(!$8(Z,B))return"expression";return B.some((W)=>_8(W))?"token":"expression"}let J=N9(Q)??Q;return Array.from(J.querySelectorAll(D9)).some((X)=>!C7(X))?"token":"expression"},M9=(Q)=>{let Y=A8(Q),J=_1(Y);if(J){let G=d5(Y,J);if(G)return{type:"element",quality:"semantic-token",element:G};return{type:"element",quality:"expression",element:J}}if(Q.type==="text-range"){if(!W8(Q.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Q.node,startOffset:Q.startOffset,endOffset:Q.endOffset}}if(!W8(Q.element))return null;return{type:"element",quality:Q.quality==="region-fallback"?"expression":"semantic-token",element:Q.element}},H8=M9,D8=()=>{let Q=new WeakMap;return(Y)=>{let J=A8(Y),G=_1(J);if(!J||!G)return M9(Y);if(Q.has(J))return Q.get(J)??null;let X=M9(Y);return Q.set(J,X),X}};var N8=(Q,Y,J,G=Q.mathAlignments,X=H8)=>{if(Y.chunkSpokenStart===null||Y.chunkSpokenEnd===null)return null;let j=null;for(let Z of G){let B=i0(Z.alignment,{position:Y.chunkSpokenStart,length:Math.max(1,Y.chunkSpokenEnd-Y.chunkSpokenStart),boundaryWord:J.word})||s0(Z.alignment,{boundaryWord:J.word});if(!B)continue;let W=X(B);if(!W)continue;if(W.quality==="semantic-token")return W;j??=W}return j};var $1=(Q,Y,J)=>{if(!Q||typeof document>"u")return null;if(J<=Y)return null;let G=Q.get(Y),X=Q.get(Math.max(Y,J-1));if(!G)return null;if(!X)X=G;try{let j=document.createRange();return j.setStart(G.node,G.offset),j.setEnd(X.node,X.offset+1),j}catch{return null}};var M8=(Q,Y)=>{if(!Q.catalogAlignment||Y.chunkSpokenStart===null)return null;let J=m0(Q.catalogAlignment,Y.chunkSpokenStart);if(!J)return null;let G=$1(Q.visibleMap,J.start,J.end);if(!G)return null;return{type:"range",quality:Q.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:G}};var l5=(Q)=>Q.regionRange?{type:"range",quality:"region",range:Q.regionRange}:Q.regionElement?{type:"element",quality:"region",element:Q.regionElement}:null,z8=(Q,Y=Q.chunk.mathAlignments)=>{if(Y.length!==1)return null;let J=Y[0]?.alignment.result.fallbackTarget;return J?Q.renderedMathTargetResolver(J):null},i5=(Q,Y)=>{if(!Q)return Y.mathAlignments;return Y.mathAlignments.filter(({element:J})=>{try{if(Q.type==="range")return Q.range.intersectsNode(J);if(Q.type==="element")return Q.element===J||Q.element.contains(J);return Q.node.parentElement?.contains(J)||!1}catch{return!1}})},O8=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),P8=(Q)=>Q.length===1?Q[0].element:null,s5=(Q,Y)=>Y.length>0&&Y.every(({element:J})=>Q.mathCapabilityByElement.get(J)==="token"),L8=3,n5=(Q,Y,J)=>{if(!Y||Y.type!=="range")return!1;let{startContainer:G,endContainer:X}=Y.range;if(G===X&&G.nodeType===L8)return!1;return J.some(({element:Z})=>Q.mathCapabilityByElement.get(Z)==="token"&&Z.contains(G)&&Z.contains(X))},w8=(Q)=>Q?.type==="range"&&C7(Q.range.startContainer),r5=(Q,Y)=>{if(!w8(Y))return null;let{startContainer:J,endContainer:G,startOffset:X,endOffset:j}=Y.range;if(J!==G||J.nodeType!==L8)return null;return Q.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:j})},o5=(Q,Y)=>({chunk:Q,regionTarget:l5(Q),renderedMathTargetResolver:D8(),mathCapabilityByElement:new Map(Q.mathAlignments.map(({element:J})=>[J,Y?F8(J):"expression"])),heldTokenByElement:new Map}),R8=(Q)=>{let Y=Q.mathTokenHighlighting!==!1,J=new Map(Q.chunks.map((G)=>[G.id,o5(G,Y)]));return{chunks:Q.chunks,resolveInitial(G){let X=J.get(G);if(!X)return O8();let j=X.chunk.mathAlignments,Z=j.length===1?j[0].element:null,B=Z?X.mathCapabilityByElement.get(Z):null;if(B==="expression")return P7({semanticTarget:null,expressionTarget:z8(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return P7({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:B==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(G){let X=J.get(G.chunkId);if(!X)return O8();let{chunk:j}=X,Z=q8(j,G),B=M8(j,Z),W=i5(B,j),K=(!B||W.length>0?N8(j,Z,G,W,X.renderedMathTargetResolver):null)||null,U=K?.quality==="semantic-token"?K:r5(X,B)??K,_=Y&&U&&U.quality!=="expression"?U:null,$=U&&U.quality==="expression"?U:null;if(_){let N=P8(W);if(N)X.heldTokenByElement.set(N,_);return P7({semanticTarget:_,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}if(B&&!w8(B)&&(Y?!n5(X,B,W):W.length===0))return P7({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason});if(s5(X,W)){let N=P8(W),D=N?X.heldTokenByElement.get(N)??null:null;return P7({semanticTarget:D,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:D?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return P7({semanticTarget:null,expressionTarget:$??z8(X,W),regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}}};var a5=(Q)=>{return Q.alignment?.speech.boundaryOffsetSpace??Q.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},t5=(Q)=>{if(Q.mathAlignments?.length)return Q.mathAlignments;if(Q.mathAlignment&&Q.sourceElement)return[{element:Q.sourceElement,alignment:Q.mathAlignment}];return[]},E8=(Q)=>{return(Q.chunks&&Q.chunks.length?Q.chunks:[{speechText:Q.speechText||"",visibleText:Q.visibleText||Q.speechText||"",sourceElement:Q.sourceElement||Q.contentRoot,regionElement:Q.regionElement||Q.sourceElement||Q.contentRoot,regionRange:Q.regionRange,visibleMap:Q.visibleMap}]).map((J,G)=>({id:`tts-chunk-${G}`,speechText:J.speechText,visibleText:J.visibleText,sourceElement:J.sourceElement,contentRoot:Q.contentRoot,regionElement:J.regionElement??J.sourceElement,regionRange:J.regionRange,visibleMap:J.visibleMap,catalogAlignment:J.alignment,mathAlignments:t5(J),offsetSpace:a5(J)}))};var e5=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),F1=(Q,Y)=>{let J=Q.closest(e5);if(J&&Y.contains(J))return J;return Q};var Q2=(Q,Y)=>A1([Q],Y),Y2=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",J2=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),G2=new Set(["heading","listitem","option","radio"]),X2=(Q)=>{if(Q.type!=="text"||!Q.sourceElement)return!1;let Y=Q.sourceElement.tagName.toUpperCase(),J=(Q.sourceElement.getAttribute("role")||"").toLowerCase();return J2.has(Y)||G2.has(J)},b8=async(Q)=>{let Y=Q.resolveMathSpeech??Q2,{visibleText:J}=Q,G=[],X=0,j=(B)=>{let W=T(B),K=J.indexOf(W,X),U=K>=0?K:X,_=U+W.length;return X=_,{start:U,end:_}},Z=[];for(let B=0;B<Q.chunks.length;B++){let W=Q.chunks[B];if(W.type==="text"){let N=X2(W)?[{text:W.text,offset:0}]:S7(W.text,{locale:Q.language});for(let D of N){let O=T(D.text);if(!O)continue;let P=j(O);G.push({sourceChunkIndex:B,segment:{kind:"prose",spokenText:O,visibleText:O,visibleSpan:P}}),Z.push(O)}continue}let K=j(W.fallbackText),U=await Y(W,{language:Q.language,produceSsml:Q.produceSsml,mathSpeech:Q.mathSpeech}),_=!U.speechText,$=U.speechText||W.fallbackText;G.push({sourceChunkIndex:B,segment:{kind:"math",spokenText:$,mathml:W.mathml,fallbackText:W.fallbackText,visibleSpan:K,usedFallback:_,ssml:U.ssml}}),Z.push($)}return{segments:G,locale:Y2(Q.language),visibleText:J,plainSpeechText:T(Z.join(" "))}};var Z2=(Q,Y,J)=>{let G=new Map;for(let X=Y;X<J;X++){let j=Q.get(X);if(j)G.set(X-Y,j)}return G},z9=async(Q)=>{let Y=O7(Q.contentRoot,Q.textProcessingOptions),J=await b8({chunks:Y.chunks,visibleText:Y.visibleText,language:Q.language,mathSpeech:Q.mathSpeech,produceSsml:Q.produceSsml,resolveMathSpeech:Q.resolveMathSpeech});return{plan:{items:J.segments.map(({segment:X,sourceChunkIndex:j})=>{let Z=Y.chunks[j];if(X.kind==="prose"){let W=Z?.type==="text"?Z.sourceElement??Q.contentRoot:Q.contentRoot;return{segment:X,anchor:{sourceElement:W,regionElement:F1(W,Q.contentRoot),visibleMap:Z2(Y.map,X.visibleSpan.start,X.visibleSpan.end)}}}let B=Z?.type==="math"?Z.sourceElement??null:null;return{segment:X,anchor:{sourceElement:B,regionElement:B}}}),locale:J.locale,visibleText:J.visibleText,plainSpeechText:J.plainSpeechText},containsMathMarkup:Y.containsMathMarkup,visibleText:Y.visibleText}};var j2=(Q,Y)=>{let J=U1({speechText:Q.spokenText,visibleText:Q.spokenText});return{speechText:Q.spokenText,visibleText:Q.visibleText,sourceElement:Y.sourceElement,regionElement:Y.regionElement,regionRange:$1(Y.visibleMap,0,Q.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Y.visibleMap}},S8=(Q,Y)=>{let J=Y.sourceElement;return{speechText:Q.spokenText,visibleText:Q.fallbackText,sourceElement:J,regionElement:Y.regionElement,speechMatchesVisibleText:Q.spokenText===Q.fallbackText,mathAlignment:J?f7({mathElement:J,speechText:Q.spokenText}):void 0}},B2=(Q,Y,J)=>{let G=Y.sourceElement;return{speechText:J,visibleText:Q.fallbackText,sourceElement:G,regionElement:Y.regionElement,speechMatchesVisibleText:!1,mathAlignment:G?f7({mathElement:G,speechText:J}):void 0,plainFallback:S8(Q,Y)}},O9=(Q,Y={})=>Q.items.map(({segment:J,anchor:G})=>{if(J.kind==="prose")return j2(J,G);if(Y.format==="ssml"&&J.ssml)return B2(J,G,J.ssml);return S8(J,G)});var C8="pie-tts-control-handoff";var w;(function(Q){Q.IDLE="idle",Q.LOADING="loading",Q.PLAYING="playing",Q.PAUSED="paused",Q.ERROR="error"})(w||(w={}));var T8=(Q,Y)=>Q===Y||Q.startContainer===Y.startContainer&&Q.startOffset===Y.startOffset&&Q.endContainer===Y.endContainer&&Q.endOffset===Y.endOffset,K2=(Q,Y)=>{if(Q===Y)return!0;if(!Q||!Y||Q.type!==Y.type||Q.quality!==Y.quality)return!1;if(Q.type==="range"&&Y.type==="range")return T8(Q.range,Y.range);if(Q.type==="element"&&Y.type==="element")return Q.element===Y.element;if(Q.type==="text-range"&&Y.type==="text-range")return Q.node===Y.node&&Q.startOffset===Y.startOffset&&Q.endOffset===Y.endOffset;return!1};class c7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=w.IDLE;ttsConfig={};currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Map;lastError=null;speakRunId=0;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=H9();static debugEnabled=(()=>{try{if(typeof process<"u"&&process.env?.PIE_TTS_DEBUG==="1")return!0}catch{}return globalThis.__PIE_TTS_DEBUG__===!0})();constructor(){}debugLog(Q,Y){if(!c7.debugEnabled)return;if(Y===void 0)console.debug(Q);else console.debug(Q,Y)}clearPlaybackStartBarrier(Q=this.playbackStartBarrierCleanup){if(Q?.(),this.playbackStartBarrierCleanup===Q)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Q){if(this.playbackStartDeferredRunId!==Q||Q!==this.speakRunId)return;this.setState(w.PLAYING);let Y=this.pendingPlaybackStartHighlights.splice(0);for(let J of Y)J()}installPlaybackStartBarrier(Q,Y=!1){this.clearPlaybackStartBarrier();let J=this.provider,G=J&&"onPlaybackStart"in J?J:null;if(!G&&!Y)return null;let X=G?.onPlaybackStart,j=()=>{try{this.notifyPlaybackStarted(Q)}finally{X?.()}};if(G)G.onPlaybackStart=j;this.playbackStartDeferredRunId=Q;let Z=()=>{if(G?.onPlaybackStart===j)G.onPlaybackStart=X;if(this.playbackStartDeferredRunId===Q)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=Z,Z}runWhenPlaybackStarts(Q,Y){if(this.playbackStartDeferredRunId===Q){this.pendingPlaybackStartHighlights.push(Y);return}Y()}async emitTelemetry(Q,Y){try{await this.telemetryReporter?.(Q,Y)}catch(J){console.warn("[TTSService] telemetry callback failed:",J)}}async initialize(Q,Y={}){this.currentProvider=Q,this.ttsConfig={...Y};let J=Y.providerOptions&&typeof Y.providerOptions==="object"?Y.providerOptions:{};this.telemetryReporter=typeof J.__pieTelemetry==="function"?J.__pieTelemetry:null;try{this.provider=await Q.initialize(Y)}catch(G){if(Q.providerId.toLowerCase()==="browser")throw G;if(!this.isBrowserSpeechFallbackAvailable())throw G;if(!await this.switchProviderToBrowser(G,{operation:"tts-initialize"}))throw G}}async updateSettings(Q){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Y=this.provider;if(typeof Y.updateSettings==="function"){let J={...Q,...Q.providerOptions?{providerOptions:{...this.ttsConfig.providerOptions||{},...Q.providerOptions}}:{}};await Y.updateSettings(J),this.ttsConfig={...this.ttsConfig,...J}}else console.warn("[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.")}setHighlightCoordinator(Q){this.highlightCoordinator=Q}setHighlightTargetResolverProvider(Q){return this.highlightTargetResolverProvider=Q,()=>{if(this.highlightTargetResolverProvider===Q)this.highlightTargetResolverProvider=null}}setCatalogResolver(Q){this.catalogResolver=Q}hasSpokenAlternate(Q,Y="en-US"){if(!Q||!this.catalogResolver)return!1;return this.catalogResolver.getAlternative(Q,{type:"spoken",language:Y,useFallback:!0,form:"content"})?.content!==void 0}getHighlightResolverRuntime(){let Q=null;try{Q=this.highlightTargetResolverProvider?.()??null}catch{Q=null}let Y=Q?.context??{},J=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Y,scopeElement:Y.scopeElement??J},resolver:Q?.resolver??null}}getNodeElement(Q){if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:Q.parentElement}isElementWithinScope(Q,Y){if(!Y)return!0;return Q===Y||Y.contains(Q)}isRangeWithinScope(Q,Y){let J=this.getNodeElement(Q.startContainer),G=this.getNodeElement(Q.endContainer);if(!J||!G)return!1;return this.isElementWithinScope(J,Y)&&this.isElementWithinScope(G,Y)}resolveWordHighlightRange(Q){let{context:Y,resolver:J}=this.getHighlightResolverRuntime(),G=Y.scopeElement??this.currentContentElement;try{let X=J?.resolveWordRange?.(Q,Y);if(X&&this.isRangeWithinScope(X,G))return{range:X,remapped:!T8(Q,X)}}catch{}return{range:Q,remapped:!1}}resolveSentenceHighlightTargets(Q){let{context:Y,resolver:J}=this.getHighlightResolverRuntime(),G=Y.scopeElement??this.currentContentElement;try{let X=J?.resolveSentenceRanges?.(Q,Y);if(!X)return{ranges:Q,elements:[]};let j=[],Z=[];for(let B of X){if(typeof Range<"u"&&B instanceof Range){if(!this.isRangeWithinScope(B,G))return{ranges:Q,elements:[]};j.push(B);continue}if(typeof Element<"u"&&B instanceof Element){if(!this.isElementWithinScope(B,G))return{ranges:Q,elements:[]};Z.push(B);continue}return{ranges:Q,elements:[]}}return{ranges:j,elements:Z}}catch{return{ranges:Q,elements:[]}}}createTextRange(Q,Y,J){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let G=document.createRange();if(G.setStart(Q,Y),G.setEnd(Q,J),G.startContainer!==Q||G.endContainer!==Q)return null;return G}catch{return null}}paintTTSWordRange(Q){if(!this.highlightCoordinator)return;try{if(Q.startContainer===Q.endContainer&&Q.startContainer.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(Q.startContainer,Q.startOffset,Q.endOffset);return}}catch{}this.highlightCoordinator.highlightRange(Q,u.TTS_WORD,_7.YELLOW)}paintTTSSentenceRanges(Q){if(!this.highlightCoordinator)return;let{ranges:Y,elements:J}=this.resolveSentenceHighlightTargets(Q);if(J.length>0&&Y.length===0&&this.highlightCoordinator.highlightTTSSentenceElements){this.highlightCoordinator.highlightTTSSentenceElements(J);return}let G=[...Y];for(let X of J){let j=document.createRange();j.selectNodeContents(X),G.push(j)}this.highlightCoordinator.highlightTTSSentence(G)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}getTextProcessingOptions(Q){let J=(this.ttsConfig.providerOptions||{}).textNormalization||{},G=J.boundarySpacingMode,X=G==="none"||G==="alnum"||G==="segmenterPreferred"?G:void 0;return{locale:Q||(typeof J.locale==="string"?J.locale:void 0),boundarySpacingMode:X}}getMathSpeechOptions(){let Y=(this.ttsConfig.providerOptions||{}).mathSpeech;return j7(Y)}buildPositionMap(Q,Y,J){this.normalizedToDOM.clear();let{text:G,map:X}=F7(Q,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!c7.debugEnabled)return;this.debugLog("[TTSService] Text comparison:",{spokenLength:Y.length,normalizedDomLength:G.length,match:Y===G,spokenPreview:Y.substring(0,150),normalizedPreview:G.substring(0,150),differAtIndex:Y===G?null:(()=>{for(let j=0;j<Math.min(Y.length,G.length);j++)if(Y[j]!==G[j])return{index:j,spokenChar:Y[j],normalizedChar:G[j],spokenContext:Y.substring(Math.max(0,j-20),j+20),normalizedContext:G.substring(Math.max(0,j-20),j+20)};return null})()}),this.debugLog("[TTSService] Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Y.length,normalizedDomLength:G.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Y.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([j,{node:Z,offset:B}])=>({pos:j,offset:B,char:Z.textContent?.[B],expected:Y[j]}))})}getStructuralPauseProfile(){let Y=(this.ttsConfig.providerOptions||{}).structuralPauses||{},J=Y.units||{},G=(X,j)=>{if(typeof X==="number"&&Number.isFinite(X))return X;if(typeof X==="string"&&X.trim()){let Z=Number(X);return Number.isFinite(Z)?Z:j}return j};return{baseMs:G(Y.baseMs,280),units:{minor:G(J.minor,0.65),section:G(J.section,1),major:G(J.major,1.35)},minMs:G(Y.minMs,120),maxMs:G(Y.maxMs,900)}}resolvePauseMsFromUnits(Q){let Y=this.getStructuralPauseProfile(),J=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),G=Y.baseMs*Math.max(0,Q)/J;return Math.max(Y.minMs,Math.min(Y.maxMs,Math.round(G)))}resolveHighlightMode(){let Y=(this.ttsConfig.providerOptions||{}).highlightMode;if(Y==="word"||Y==="sentence")return Y;if((this.currentProvider?.providerId||"").toLowerCase()==="browser")return"sentence";return this.currentProvider?.getCapabilities().supportsWordBoundary??!1?"word":"sentence"}hasExplicitBreakSemantics(Q){if(!Q.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(Q)}isElementHidden(Q){return X9(Q)}getBoundaryStrength(Q){let Y=Number(Q.getAttribute("data-tts-break-ms"));if(Number.isFinite(Y)&&Y>0)return"major";let J=Q.tagName.toUpperCase();if(J.match(/^H[1-6]$/))return"major";let G=(Q.getAttribute("role")||"").toLowerCase();if(G==="heading")return"major";if(G==="listitem"||G==="row"||G==="option"||G==="radio"||J==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(Q).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(Q,Y){let J=Q.parentElement,G=null;while(J&&J!==Y){if(this.isElementHidden(J))return null;let j=Number(J.getAttribute("data-tts-break-ms"));if(Number.isFinite(j)&&j>0)return{anchor:J,units:j/this.getStructuralPauseProfile().baseMs};let Z=(J.getAttribute("role")||"").toLowerCase(),B=J.tagName.toUpperCase();if(B.match(/^H[1-6]$/)||Z==="heading"||Z==="listitem"||B==="LI"){G=J;break}if(!G){if(typeof window<"u"){let W=window.getComputedStyle(J).display;if(W==="block"||W==="list-item"||W.startsWith("table")||W==="flex"||W==="grid")G=J}}J=J.parentElement}if(!G)return null;let X=this.getBoundaryStrength(G);return{anchor:G,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Q,Y,J=0){let G=this.collectSpeechPlanBoundaries(Q,Y);if(J===0)return this.createSpeechPlanSegments(Y,G);let X=new Map;for(let[j,Z]of G)X.set(j-J,Z);return this.createSpeechPlanSegments(Y,X)}collectSpeechPlanBoundaries(Q,Y){let J=new Map,{map:G}=F7(Q,this.getTextProcessingOptions()),X=this.createNodeStartOffsets(G),j=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),Z=j.nextNode(),B=null;while(Z){let W=Z,K=W.parentElement;if(K&&!this.isElementHidden(K)&&!W1(W)){let U=this.getBoundaryAnchor(W,Q),_=X.get(W);if(U&&_!==void 0&&U.anchor!==B&&_>0)J.set(_,Math.max(J.get(_)||0,U.units)),B=U.anchor}Z=j.nextNode()}return J}createNodeStartOffsets(Q){let Y=new Map;for(let[J,G]of Q.entries())if(!Y.has(G.node))Y.set(G.node,J);return Y}createSpeechPlanSegments(Q,Y){let J=Array.from(Y.keys()).filter((W)=>W>0&&W<Q.length).sort((W,K)=>W-K),G=[],X=0;for(let W of J){let K=Q.substring(X,W),U=K.match(/^\s*/)?.[0].length||0,_=K.match(/\s*$/)?.[0].length||0,$=X+U,N=W-_;if(N>$){let D=Q.substring($,N);G.push({text:D,startOffset:$,pauseMsAfter:this.resolvePauseMsFromUnits(Y.get(W)||0)})}X=W}let Z=Q.substring(X).match(/^\s*/)?.[0].length||0,B=X+Z;if(B<Q.length)G.push({text:Q.substring(B).trimEnd(),startOffset:B,pauseMsAfter:0});return G.filter((W)=>W.text.trim().length>0)}segmentSentences(Q){let Y=this.ttsConfig.providerOptions?.locale||void 0;return S7(Q,{locale:Y})}createSeekSegmentsFromText(Q){return this.segmentSentences(Q).map((Y)=>{let J=Y.text.match(/^\s*/)?.[0].length||0;return{text:Y.text.trim(),startOffset:Y.offset+J,pauseMsAfter:0}}).filter((Y)=>Y.text.length>0)}splitSegmentsAtBoundaries(Q,Y,J){if(Q.length===0||Y.length===0)return Q;let G=Array.from(new Set(Y)).filter((j)=>Number.isFinite(j)&&j>0).sort((j,Z)=>j-Z);if(G.length===0)return Q;let X=[];for(let j of Q){let Z=j.startOffset,B=j.startOffset+j.text.length,W=G.filter((U)=>U>Z&&U<B);if(W.length===0){X.push(j);continue}let K=Z;for(let U of[...W,B]){let _=J.substring(K,U),$=_.match(/^\s*/)?.[0].length||0,N=_.match(/\s*$/)?.[0].length||0,D=K+$,O=U-N;if(O>D)X.push({text:J.substring(D,O),startOffset:D,pauseMsAfter:0});K=U}}return X}createSentenceHighlightSegments(Q){let Y=this.createSeekSegmentsFromText(Q.contentToSpeak);if(!Q.shouldUsePlan||Q.playbackSegments.length===0)return Y;let J=Q.playbackSegments.map((G)=>G.startOffset).filter((G)=>G>0);return this.splitSegmentsAtBoundaries(Y,J,Q.contentToSpeak)}createSeekSegmentsFromSpeechChunks(Q){let Y=0;return Q.map((J)=>{let G=J.plainFallback?.speechText||(this.hasExplicitBreakSemantics(J.speechText)?J.visibleText:J.speechText)||J.visibleText,X=T(G)||J.visibleText||"",j={text:X,startOffset:Y,pauseMsAfter:0};return Y+=Math.max(1,X.length+1),j})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let Q=0;for(let Y=0;Y<this.seekSegments.length;Y++)if(this.seekSegments[Y].startOffset<=this.currentBoundaryOffset)Q=Y;else break;return Q}async speakWithPlan(Q,Y,J){if(!this.provider||Q.length===0)return;let G=J?.highlightMode==="sentence",X=this.provider;if(!G&&typeof X.speakSegments==="function"){this.currentBoundaryOffset=0;let j=this.provider.onWordBoundary;this.provider.onWordBoundary=(Z,B,W)=>{if(j?.(Z,B,W),Number.isFinite(B))this.currentBoundaryOffset=B};try{await X.speakSegments(Q)}finally{if(Y===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=j}return}this.configureWordBoundaryHighlighting({highlightMode:J?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let j of Q){if(Y!==this.speakRunId)return;if(this.currentBoundaryOffset=j.startOffset,G)this.runWhenPlaybackStarts(Y,()=>{this.highlightSentenceSegment(j.startOffset,j.text)});await this.provider.speak(j.text);let Z=j.pauseMsAfter??0;if(Z>0)await new Promise((B)=>setTimeout(B,Z))}}highlightSentenceSegment(Q,Y){if(!this.highlightCoordinator||typeof document>"u")return;let J=Y.trimEnd().length;if(J<=0)return;let G=Q+this.activeWordBoundaryOffset,X=this.normalizedToDOM.get(G),j=this.normalizedToDOM.get(G+J-1);if(!X||!j)return;let Z=document.createRange();Z.setStart(X.node,X.offset),Z.setEnd(j.node,j.offset+1),this.paintTTSSentenceRanges([Z]),this.activeSentenceStartOffset=Q}getSegmentIndexForOffset(Q,Y){if(Q.length===0)return-1;let J=-1;for(let G=0;G<Q.length;G++)if(Q[G].startOffset<=Y)J=G;else break;return J}highlightSentenceForOffset(Q){let Y=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Y.length===0)return;let J=this.getSegmentIndexForOffset(Y,Q);if(J<0)return;let G=Y[J];if(!G)return;if(this.activeSentenceStartOffset===G.startOffset)return;this.highlightSentenceSegment(G.startOffset,G.text)}findHighlightRange(Q,Y){let J=this.normalizedToDOM.get(Q);if(!J)return console.warn(`[TTSService] No mapping found for start position ${Q}`,{totalMappings:this.normalizedToDOM.size,nearbyMappings:Array.from(this.normalizedToDOM.entries()).filter(([j])=>Math.abs(j-Q)<5).map(([j,{offset:Z,node:B}])=>({pos:j,offset:Z,char:B.textContent?.[Z]}))}),null;let G=Q+Y-1,X=this.normalizedToDOM.get(G);if(!X)return console.warn(`[TTSService] No mapping found for end position ${G}`,{startChar:Q,length:Y,totalMappings:this.normalizedToDOM.size}),null;if(J.node!==X.node)return console.warn("[TTSService] Word spans multiple nodes, highlighting in first node only"),{node:J.node,start:J.offset,end:(J.node.textContent||"").length};return{node:J.node,start:J.offset,end:X.offset+1}}async speak(Q,Y){if(!this.provider)throw Error("TTS service not initialized");let J=++this.speakRunId;this.clearPlaybackStartBarrier();let G=null;try{if(await this.applyLanguageSettings(Y),J!==this.speakRunId)return;let X=await this.resolveSpeechContent(Q,Y);if(J!==this.speakRunId)return;let{contentToSpeak:j,speechText:Z,highlightText:B,normalizedText:W,usedCatalogSpoken:K,speechSource:U,speechMatchesVisibleText:_,speechChunks:$}=X;this.logResolvedSpeechContent({contentToSpeak:j,speechSource:U,catalogId:Y?.catalogId}),this.initializeSpeakTracking(B,Y);let N=Y?.highlightModeOverride||(_?this.resolveHighlightMode():"sentence");this.activeHighlightMode=N,this.activeWordBoundaryOffset=Y?.wordBoundaryOffset||0;let D=this.hasExplicitBreakSemantics(j),O=!!this.currentContentElement&&!K&&!D&&_;if(this.playbackChunks=$?.length?$:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):D||!_?[]:O&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,W,Y?.wordBoundaryOffset||0):this.createSeekSegmentsFromText(B),this.sentenceHighlightSegments=D?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:O,playbackSegments:this.seekSegments}),this.setState(w.LOADING),G=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Y,highlightMode:N,shouldUsePlan:O,runId:J}),_)this.configureWordBoundaryHighlighting({highlightMode:N,wordBoundaryOffset:Y?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!G)this.setState(w.PLAYING);if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:O,runId:J,highlightMode:N,contentToSpeak:Z,speechChunks:$}),J!==this.speakRunId)return;this.setState(w.IDLE),this.clearHighlightsAndTracking()}catch(X){let j=X;if(console.error("TTS error:",j),this.lastError=j instanceof Error?j.message:String(j),J!==this.speakRunId)return;throw this.setState(w.ERROR),this.clearHighlightsAndTracking(),j}finally{this.clearPlaybackStartBarrier(G)}}async switchProviderToBrowser(Q,Y){if(!this.currentProvider)return!1;let J=new g7,G=this.currentProvider.providerId,X={};if(this.ttsConfig.rate!==void 0)X.rate=this.ttsConfig.rate;if(this.ttsConfig.pitch!==void 0)X.pitch=this.ttsConfig.pitch;if(this.ttsConfig.mathTokenHighlighting!==void 0)X.mathTokenHighlighting=this.ttsConfig.mathTokenHighlighting;let j=Y?.operation||"tts-initialize",Z=Y?.contentToSpeak??"",B=Z.replace(/\s+/g," ").trim().slice(0,120),W=Z.length>0?{textLength:Z.length,textPreview:B.length<Z.length?`${B}…`:B}:{};try{return this.provider?.stop(),this.currentProvider.destroy(),this.currentProvider=J,this.provider=await J.initialize(X),this.ttsConfig=X,await this.emitTelemetry("pie-tool-runtime-fallback",{toolId:"textToSpeech",operation:j,fromProvider:G,toProvider:J.providerId,reason:Q instanceof Error?Q.message:String(Q),...W}),console.warn("[TTSService] TTS provider initialization failed; switched to browser fallback",{fromProvider:G,reason:Q,...W}),!0}catch(K){return await this.emitTelemetry("pie-tool-runtime-fallback-error",{toolId:"textToSpeech",operation:j,fromProvider:G,toProvider:"browser",errorType:"TTSRuntimeFallbackError",message:K instanceof Error?K.message:String(K)}),console.error("[TTSService] Failed to switch to browser fallback provider",K),!1}}isBrowserSpeechFallbackAvailable(){if(typeof window>"u")return!1;if(!("speechSynthesis"in window))return!1;return typeof globalThis.SpeechSynthesisUtterance==="function"}async applyLanguageSettings(Q){if(!Q?.language||!this.provider)return;let Y=this.ttsConfig.providerOptions||{},J=Y.textNormalization||{},G=Y.segmenter||{},X={...Y,locale:Q.language,textNormalization:{...J,locale:Q.language},segmenter:{...G,locale:Q.language}};if(this.ttsConfig={...this.ttsConfig,providerOptions:X},"updateSettings"in this.provider&&typeof this.provider.updateSettings==="function")await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(Q,Y){let J=T(Q);if(Y?.ignoreCatalogs)return{contentToSpeak:J,speechText:J,visibleText:J,highlightText:J,usedCatalogSpoken:!1,speechSource:"dom-or-input",normalizedText:J,containsMathMarkup:!1,speechMatchesVisibleText:!0};if(Y?.catalogId&&this.catalogResolver){let j=this.catalogResolver.getAlternative(Y.catalogId,{type:"spoken",language:Y.language||"en-US",useFallback:!0,context:Y.catalogContext,form:"content"}),Z=j?.content;if(j&&Z!==void 0){let B=Y?.contentElement?O7(Y.contentElement,this.getTextProcessingOptions(Y.language)).visibleText||J:J,W=T(Z);return this.debugLog(`[TTSService] Using catalog content for "${Y.catalogId}" (${j.language})`),{contentToSpeak:Z,speechText:Z,visibleText:B,highlightText:B,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:W===B}}this.debugLog(`[TTSService] No catalog found for "${Y.catalogId}", falling back to generated TTS`)}let G=Y?.contentElement?this.resolveCatalogComposedSpeechContent(Y.contentElement,J,Y):null;if(G)return G;return{...Y?.contentElement?await this.resolveGeneratedSpeechContent(Y.contentElement,J,Y.language):{contentToSpeak:J,speechText:J,visibleText:J,highlightText:J,normalizedText:J,containsMathMarkup:!1,speechMatchesVisibleText:!0},usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(Q,Y,J){if(!this.catalogResolver)return null;let G=this.collectCatalogSpeechChunks(Q,J);if(!G.some((Z)=>Z.sourceElement))return null;let X=T(G.map((Z)=>Z.speechText).join(" ")),j=O7(Q,this.getTextProcessingOptions(J.language)).visibleText||Y;return{contentToSpeak:X,speechText:X,visibleText:j,highlightText:j,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:j,containsMathMarkup:!1,speechMatchesVisibleText:G.every((Z)=>Z.speechMatchesVisibleText),speechChunks:G}}collectCatalogSpeechChunks(Q,Y){let J=[],G="",X=()=>{let K=T(G);if(G="",!K)return;J.push({speechText:K,visibleText:K,sourceElement:null,speechMatchesVisibleText:!0})},j=(K)=>{let U=K.getAttribute("data-catalog-idref");if(!U)return null;let _={type:"spoken",language:Y.language||"en-US",useFallback:!0,context:Y.catalogContext},$=this.catalogResolver.getAlternative(U,{..._,form:"payload"}),N=$?.payload?w0({payload:$.payload})??void 0:void 0,O=this.catalogResolver.getAlternative(U,{..._,form:"content"})?.content;if(N===void 0&&O===void 0)return null;return{script:O,audio:N}},Z=(K,U)=>{let _=B(K);if(_.length!==1)return null;let $=_[0],N=O7($,this.getTextProcessingOptions(Y.language)).visibleText||T($.textContent||""),D=(O)=>T(O).replace(/\s+/g,"");return D(N)===D(U)?$:null},B=(K)=>{let U=Array.from(K.querySelectorAll("math"));if(K.localName?.toLowerCase()==="math")return[K,...U];return U},W=(K)=>{if($7(K,Q))return;if(K.nodeType===Node.TEXT_NODE){G+=` ${K.textContent||""}`;return}if(K.nodeType!==Node.ELEMENT_NODE)return;let U=K,_=j(U);if(_){X();let $=O7(U,this.getTextProcessingOptions(Y.language)),N=$.visibleText||T(U.textContent||""),D=F1(U,Q),O=_.script!==void 0?(()=>{let P=_.script,F=U1({speechText:P,visibleText:N}),L=Z(U,N),C=L?f7({mathElement:L,speechText:P}):void 0,v=C?void 0:B(U).map((k)=>({element:k,alignment:f7({mathElement:k,speechText:P})}));return{speechText:P,visibleText:N,sourceElement:U,regionElement:D,speechMatchesVisibleText:T(P)===N,playbackMode:F.playbackMode,alignment:F,mathAlignment:C,mathAlignments:v,visibleMap:$.map}})():null;if(_.audio){J.push(O?{...O,audio:_.audio,plainFallback:O}:{speechText:N,visibleText:N,sourceElement:U,regionElement:D,speechMatchesVisibleText:!1,visibleMap:$.map,audio:_.audio});return}if(O)J.push(O);return}for(let $ of Array.from(U.childNodes))W($)};return W(Q),X(),J}resolveGeneratedPlaybackFormat(){let Q=this.currentProvider;if(!Q)return"plain";if(Q.providerId?.toLowerCase()==="browser")return"plain";return Q.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(Q,Y,J){let G=this.resolveGeneratedPlaybackFormat(),{plan:X,containsMathMarkup:j,visibleText:Z}=await z9({contentRoot:Q,language:J,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(J),produceSsml:G==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver}),B=Z||Y;if(!j)return{contentToSpeak:B,speechText:B,visibleText:B,highlightText:B,normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:!0};let W=O9(X,{format:G}),K=X.plainSpeechText;return{contentToSpeak:K,speechText:K,visibleText:B,highlightText:B,normalizedText:B,containsMathMarkup:!0,speechMatchesVisibleText:K===B,speechChunks:W}}logResolvedSpeechContent(Q){let Y=Q.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);this.debugLog("[TTSService] Speak resolved content",{source:Q.speechSource,catalogId:Q.catalogId||null,length:Q.contentToSpeak.length,preview:Y})}initializeSpeakTracking(Q,Y){this.currentText=Q,this.currentContentElement=Y?.contentElement||null,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(Q){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,Q.contentToSpeak,Q.options?.language),Q.highlightMode==="sentence"&&Q.shouldUsePlan)return;let Y=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(Q.runId,()=>{if(Y)this.highlightSentenceSegment(Y.startOffset,Y.text),this.debugLog("[TTSService] Applied initial sentence highlighting");else try{let J=document.createRange();J.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([J])}catch{}})}configureWordBoundaryHighlighting(Q){if(!this.provider||Q.highlightMode!=="word"||!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Y,J,G)=>{let X=G||Y.length,j=J+this.currentBoundaryOffset,Z=j+Q.wordBoundaryOffset;this.highlightSentenceForOffset(j);let B=this.findHighlightRange(Z,X);if(B&&this.highlightCoordinator){let W=B.node.textContent?.substring(B.start,B.end)||"";this.debugLog(`[TTSService] Highlighting "${W}" (word: "${Y}") at position ${Z}`);let K=this.createTextRange(B.node,B.start,B.end);if(K)this.paintTTSWordRange(this.resolveWordHighlightRange(K).range);else this.highlightCoordinator.highlightTTSWord(B.node,B.start,B.end)}else console.warn(`[TTSService] Could not find highlight range for position ${Z}, length ${X}`)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(Q){let Y=Q.regionElement||Q.sourceElement;if(!Y&&!Q.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,Q.regionRange){this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Q.regionRange]);return}if(!Y)return;let J=document.createRange();J.selectNodeContents(Y),this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([J])}catch{}}highlightCatalogActiveRange(Q){if(!this.highlightCoordinator)return;this.paintTTSWordRange(this.resolveWordHighlightRange(Q).range)}highlightRenderableRegionTarget(Q){if(!this.highlightCoordinator||!Q||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&K2(this.lastRenderedRegionTarget,Q))return;try{let Y=document.createRange();if(Q.type==="element")Y.selectNodeContents(Q.element);else if(Q.type==="range"){this.paintTTSSentenceRanges([Q.range]),this.lastRenderedRegionTarget=Q;return}else Y.setStart(Q.node,Q.startOffset),Y.setEnd(Q.node,Q.endOffset);this.paintTTSSentenceRanges([Y]),this.lastRenderedRegionTarget=Q}catch{}}highlightRenderableActiveTarget(Q){if(!this.highlightCoordinator||typeof document>"u")return;if(!Q){this.highlightCoordinator.clearHighlights(u.TTS_WORD);return}if(Q.type==="text-range"){let X=this.createTextRange(Q.node,Q.startOffset,Q.endOffset);if(X)this.paintTTSWordRange(this.resolveWordHighlightRange(X).range);else this.highlightCoordinator.highlightTTSWord(Q.node,Q.startOffset,Q.endOffset);return}if(Q.type==="range"){this.highlightCatalogActiveRange(Q.range);return}let Y=document.createRange();Y.selectNodeContents(Q.element);let J=this.resolveWordHighlightRange(Y);if(J.remapped){this.paintTTSWordRange(J.range);return}let G=Q.element.childNodes.length===1?Q.element.firstChild:null;if(Q.quality==="semantic-token"&&G?.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(G,0,G.textContent?.length||0);return}this.highlightCoordinator.highlightTTSWordElement?.(Q.element)}renderHighlightDecision(Q){this.highlightRenderableRegionTarget(Q.regionTarget),this.highlightRenderableActiveTarget(Q.activeTarget)}async speakCatalogChunk(Q,Y){try{await this.speakCatalogChunkOnce(Q,Y)}catch(J){if(Q.plainFallback&&Y===this.speakRunId){if(this.debugLog("[TTSService] SSML chunk speak failed; retrying plain text",{message:J instanceof Error?J.message:String(J)}),this.playbackStartDeferredRunId===Y&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.setState(w.PLAYING);await this.speakCatalogChunkOnce(Q.plainFallback,Y);return}throw J}}async playRecordedAudio(Q,Y){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let J=Q.sources[0],G=document.createElement("audio");G.preload="auto",G.src=q2(J.src,Q.fragment),G.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,j)=>{let Z,B=!1,W=!1,K=()=>{if(W||B)return;B=!0,Y?.()},U=()=>{if(G.removeEventListener("ended",_),G.removeEventListener("error",$),G.removeEventListener("playing",K),Z?.(),this.activeRecordedAudio?.element===G)this.activeRecordedAudio=null},_=()=>{if(W)return;W=!0,U(),X()},$=()=>{if(W)return;W=!0,U(),j(Error(`[tts] recorded audio failed to play: ${J.src}`))};this.activeRecordedAudio={element:G,cancel:()=>{if(W)return;W=!0,U(),G.pause(),X()}},G.addEventListener("ended",_),G.addEventListener("error",$),G.addEventListener("playing",K),Z=W2(G,Q.fragment,_),Promise.resolve(G.play()).then(K).catch($)}).finally(()=>{if(this.activeRecordedAudio?.element===G)this.activeRecordedAudio=null;G.pause(),G.removeAttribute("src")})}cancelRecordedAudio(){let Q=this.activeRecordedAudio;if(!Q)return;this.activeRecordedAudio=null,Q.cancel()}async speakCatalogChunkOnce(Q,Y){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,Q.audio){this.runWhenPlaybackStarts(Y,()=>{this.highlightCatalogRegion(Q)}),await this.playRecordedAudio(Q.audio,()=>{this.notifyPlaybackStarted(Y)});return}let J=Q.regionElement||Q.sourceElement||this.currentContentElement,G=J?E8({contentRoot:J,chunks:[Q]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,j=G?R8({chunks:[G],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(Y,()=>{if(j&&G&&Q.mathAlignment)this.renderHighlightDecision(j.resolveInitial(G.id));else this.highlightCatalogRegion(Q)}),!(Q.sourceElement&&(Q.mathAlignment&&Q.mathAlignment.speech.tokens.length>0||Q.mathAlignments&&Q.mathAlignments.length>0||Q.alignment&&Q.visibleMap&&(Q.playbackMode==="exact-word"||Q.playbackMode==="anchor-span")))){let U=this.provider,_=U.onWordBoundary;U.onWordBoundary=void 0;try{await U.speak(Q.speechText)}finally{if(this.provider===U&&Y===this.speakRunId&&U.onWordBoundary===void 0)U.onWordBoundary=_}return}let B=this.provider,W=B.onWordBoundary,K=(U,_,$)=>{if(Y!==this.speakRunId)return;if(j&&G){let N=G.offsetSpace==="unsupported"?"unknown":G.offsetSpace;this.renderHighlightDecision(j.resolveBoundary({chunkId:G.id,word:U,position:_,length:$,providerOffsetSpace:N}));return}};B.onWordBoundary=K;try{await B.speak(Q.speechText)}finally{if(this.provider===B&&Y===this.speakRunId&&B.onWordBoundary===K)B.onWordBoundary=W}}async executeSpeakPlayback(Q){if(Q.speechChunks?.length&&this.provider){for(let Y=0;Y<Q.speechChunks.length;Y++){if(Q.runId!==this.speakRunId)return;let J=this.seekSegments[Y];if(J)this.currentBoundaryOffset=J.startOffset;let G=Q.speechChunks[Y];await this.speakCatalogChunk(G,Q.runId)}return}if(Q.shouldUsePlan&&this.currentContentElement){let Y=this.seekSegments;if(Y.length>0)await this.speakWithPlan(Y,Q.runId,{highlightMode:Q.highlightMode});else if(this.provider)await this.provider.speak(Q.contentToSpeak);return}if(this.provider)await this.provider.speak(Q.contentToSpeak)}clearHighlightsAndTracking(){if(this.pendingPlaybackStartHighlights=[],this.activePlaybackRate=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null}selectMappedRangeText(Q,Y){if(typeof Q.comparePoint!=="function")return null;let{text:J,map:G}=F7(Y,this.getTextProcessingOptions()),X=-1,j=-1;for(let[K,{node:U,offset:_}]of G){if(K>=J.length)continue;let $=!1;try{$=Q.comparePoint(U,_)===0&&Q.comparePoint(U,Math.min(_+1,U.length))===0}catch{$=!1}if(!$)continue;if(X===-1||K<X)X=K;if(K>j)j=K}if(X===-1)return null;let Z=J.slice(X,j+1),B=Z.length-Z.trimStart().length,W=Z.trim();return W?{text:W,offset:X+B}:null}async speakRange(Q,Y){if(!this.provider)throw Error("TTS service not initialized");if(W1(Q.commonAncestorContainer)){console.warn("[tts] selection lies inside content marked not-to-be-spoken; nothing was spoken. Selecting a node and pressing read-aloud must not become a way around suppression.");return}let G=Y?.contentRoot||null;if(!G){let K=Q.commonAncestorContainer;G=K.nodeType===Node.ELEMENT_NODE?K:K.parentElement}if(!G)return;let X=Z9(Q,G),j=X.text.trim();if(!j){if(X.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return}let Z=this.selectMappedRangeText(Q,G),B=j,W=Z?.offset??0;if(Z)B=Z.text;else{let K=document.createRange();K.selectNodeContents(G),K.setEnd(Q.startContainer,Q.startOffset);let U=Z9(K,G).text,_=T(U);W=_.length+(/\s$/.test(U)&&_?1:0)}this.debugLog("[TTSService] speakRange offset calculation:",{selectedText:B,mapped:!!Z,offset:W,rootTag:G.tagName}),await this.speak(B,{contentElement:G,ignoreCatalogs:!0,wordBoundaryOffset:W})}pause(){if(!this.provider)return;if(this.state===w.PLAYING)this.activeRecordedAudio?.element.pause(),this.provider.pause(),this.setState(w.PAUSED)}resume(){if(!this.provider)return;if(this.state===w.PAUSED){let Q=this.activeRecordedAudio?.element;if(Q)Promise.resolve(Q.play()).catch(()=>{});this.provider.resume(),this.setState(w.PLAYING)}}normalizePlaybackRate(Q){if(!Number.isFinite(Q))return 1;return Math.max(0.25,Math.min(4,Q))}async restartFromSeekIndex(Q){if(!this.provider||this.seekSegments.length===0)return;let Y=Math.max(0,Math.min(this.seekSegments.length-1,Q)),J=this.playbackChunks.length?this.playbackChunks.slice(Y):null;this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop();let G=++this.speakRunId,X=this.seekSegments.slice(Y);this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.setState(w.LOADING);let j=this.installPlaybackStartBarrier(G,!!J?.[0]?.audio);if(!j)this.setState(w.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),J)for(let Z=0;Z<J.length;Z++){if(G!==this.speakRunId)return;let B=Y+Z,W=this.seekSegments[B];if(W)this.currentBoundaryOffset=W.startOffset;await this.speakCatalogChunk(J[Z],G)}else await this.speakWithPlan(X,G,{highlightMode:this.activeHighlightMode});if(G!==this.speakRunId)return;this.setState(w.IDLE),this.clearHighlightsAndTracking()}catch(Z){if(G!==this.speakRunId)return;throw this.lastError=Z instanceof Error?Z.message:String(Z),this.setState(w.ERROR),this.clearHighlightsAndTracking(),Z}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(Q){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Y=this.normalizePlaybackRate(Q),J=this.pendingPlaybackRateRequest;if(J?.rate===Y){await J.promise;return}let G=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let B=this.speakRunId;if(G!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:B};let W=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Y===W)return{didUpdate:!1,playbackRunId:B};return await this.updateSettings({rate:Y}),{didUpdate:!0,playbackRunId:B}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let j=X.then(async(B)=>{if(G!==this.playbackRateRequestId||B.playbackRunId!==this.speakRunId)return;let W=this.activePlaybackRate!==null&&this.activePlaybackRate!==Y;if(!B.didUpdate&&!W)return;if(this.state!==w.PLAYING&&this.state!==w.LOADING||!this.currentText||this.seekSegments.length===0||this.hasExplicitBreakSemantics(this.currentText))return;await this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex())}),Z;Z=j.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===Z)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Y,promise:Z},await Z}async seekBy(Q){if(!this.provider||!this.currentText)return;if(this.state!==w.PLAYING&&this.state!==w.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Y=Number.isFinite(Q)?Math.trunc(Q):0;if(Y===0)return;let J=this.getCurrentSeekSegmentIndex(),G=Math.max(0,Math.min(this.seekSegments.length-1,J+Y));if(G===J)return;await this.restartFromSeekIndex(G)}async seekForward(Q=1){let Y=Number.isFinite(Q)?Math.max(1,Math.trunc(Q)):1;await this.seekBy(Y)}async seekBackward(Q=1){let Y=Number.isFinite(Q)?Math.max(1,Math.trunc(Q)):1;await this.seekBy(-Y)}stop(){if(!this.provider)return;if(this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.setState(w.IDLE),this.currentText=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null,this.activePlaybackRate=null}requestControlHandoff(){if(typeof window>"u")return;let Q={source:"host"};window.dispatchEvent(new CustomEvent(C8,{detail:Q}))}isPlaying(){return this.state===w.PLAYING}isPaused(){return this.state===w.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(Q,Y){if(!this.listeners.has(Q))this.listeners.set(Q,new Set);this.listeners.get(Q).add(Y)}offStateChange(Q,Y){let J=this.listeners.get(Q);if(J){if(J.delete(Y),J.size===0)this.listeners.delete(Q)}}setState(Q){if(this.state===Q)return;let Y=this.state;this.state=Q;for(let J of this.listeners.values())for(let G of J)G(Q);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q}),Q===w.PLAYING){let J=Y===w.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(J,{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q});return}if(Q===w.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q});return}if(Q===w.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q,message:this.lastError||void 0});return}if(Q===w.IDLE&&(Y===w.PLAYING||Y===w.PAUSED||Y===w.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q})}}var U2=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),P9=(Q)=>Q&&typeof Q==="object"?Q:{},V2=(Q)=>Q==="polly"||Q==="google"||Q==="server",i=(Q,Y)=>Q===void 0?Y:Q,A2=(Q,Y="left-aligned")=>typeof Q==="string"&&U2.has(Q)?Q:Y,YY=Object.freeze([0.8,1.25]),JY=Object.freeze([{rate:0.8,label:"Slow",ariaLabel:"Slow speed"},{rate:1,label:"Normal",ariaLabel:"Normal speed",default:!0},{rate:1.25,label:"Fast",ariaLabel:"Fast speed"}]);var GY=Object.freeze([0.8,1,1.25]);var _2=(Q)=>{let Y={...Q,layoutMode:A2(Q.layoutMode)},J=Q.backend||"browser";if(!V2(J))return Y;let G={...Y,apiEndpoint:i(Y.apiEndpoint,"/api/tts"),transportMode:i(Y.transportMode,"pie"),endpointValidationMode:i(Y.endpointValidationMode,"voices"),validateEndpoint:i(Y.validateEndpoint,!0),includeAuthOnAssetFetch:i(Y.includeAuthOnAssetFetch,!1),rate:i(Y.rate,1),language:i(Y.language,"en-US")};if(J==="polly")return{...G,defaultVoice:i(G.defaultVoice,"Joanna"),engine:i(G.engine,"neural"),format:i(G.format,"mp3"),speechMarksMode:i(G.speechMarksMode,"word+sentence")};if(J==="google")return{...G,defaultVoice:i(G.defaultVoice,"en-US-Wavenet-A")};return G},y8=(Q)=>{let Y=P9(Q),J=P9(Y.settings),{provider:G,...X}={...Y,...J};return _2({...X,...typeof G==="string"?{provider:G}:{}})},L9=(Q)=>Q.backend||"browser",$2=(Q,Y)=>{if(Y==="polly"||Y==="google")return Y;if(Y==="server")return Q.serverProvider||Q.provider;return Q.serverProvider||Q.provider},F2=(Q,Y)=>Q.transportMode||(Y==="custom"?"custom":"pie"),f8=(Q)=>{let Y=L9(Q),J=$2(Q,Y),G=F2(Q,J),X=j7(Q.mathSpeech);return{voice:Q.defaultVoice,rate:Q.rate,pitch:Q.pitch,providerOptions:{...P9(Q.providerOptions),...Q.language?{locale:Q.language}:{},...Y==="polly"&&Q.engine?{engine:Q.engine}:{},...Y==="polly"&&typeof Q.sampleRate==="number"?{sampleRate:Q.sampleRate}:{},...Y==="polly"&&Q.format?{format:Q.format}:{},...Y==="polly"?{speechMarkTypes:Q.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...G==="custom"&&typeof Q.cache==="boolean"?{cache:Q.cache}:{},...G==="custom"&&Q.speedRate?{speedRate:Q.speedRate}:{},...G==="custom"&&Q.lang_id?{lang_id:Q.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:Q.apiEndpoint,provider:J,language:Q.language,transportMode:G,endpointMode:Q.endpointMode,endpointValidationMode:Q.endpointValidationMode,includeAuthOnAssetFetch:Q.includeAuthOnAssetFetch,assetOrigins:Q.assetOrigins,credentials:Q.credentials,headers:Q.headers,validateEndpoint:Q.validateEndpoint,...typeof Q.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Q.mathTokenHighlighting}:{}}};class H1{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(Q,Y,J){try{await Q.onTelemetry?.(Y,J)}catch(G){console.warn("[ToolProviderRegistry] Telemetry callback failed:",G)}}register(Q,Y){if(this.providers.has(Q)){console.warn(`[ToolProviderRegistry] Provider "${Q}" already registered, skipping`);return}if(this.providers.set(Q,Y.provider),this.configs.set(Q,Y),this.initialized.set(Q,!1),console.log(`[ToolProviderRegistry] Registered provider "${Q}" (${Y.provider.providerName})`),Y.lazy===!1)this.initialize(Q).catch((J)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${Q}":`,J)})}async initialize(Q){if(this.initialized.get(Q))return;let Y=this.initializationPromises.get(Q);if(Y)return Y;let J=this._doInitialize(Q);this.initializationPromises.set(Q,J);try{await J}finally{this.initializationPromises.delete(Q)}}async _doInitialize(Q){let Y=this.providers.get(Q),J=this.configs.get(Q);if(!Y||!J)throw Error(`[ToolProviderRegistry] Provider "${Q}" not registered`);let G={...J.config},X=(Z)=>{if(!Z||typeof Z!=="object")return"unknown";let B=Z;return(typeof B.backend==="string"?B.backend:typeof B.provider==="string"?B.provider:typeof B.serverProvider==="string"?B.serverProvider:typeof B.providerId==="string"?B.providerId:"")||"unknown"},j=Date.now();if(await this.emitTelemetry(J,"pie-tool-init-start",{toolId:Q,providerId:Q,backend:X(G),operation:"provider-initialize"}),Y.requiresAuth&&J.authFetcher){let Z=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Q,providerId:Q,backend:X(G),operation:"auth-fetch"}),console.log(`[ToolProviderRegistry] Fetching auth for "${Q}"...`);try{let B=await J.authFetcher();G={...G,...B},await this.emitTelemetry(J,"pie-tool-backend-call-success",{toolId:Q,providerId:Q,backend:X(G),operation:"auth-fetch",duration:Date.now()-Z})}catch(B){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Q,providerId:Q,backend:X(G),operation:"auth-fetch",duration:Date.now()-Z,errorType:"ProviderAuthFetchError",message:B instanceof Error?B.message:String(B)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Q}":`,B),Error(`Failed to fetch auth credentials for provider "${Q}"`)}}try{await Y.initialize(G),this.initialized.set(Q,!0),await this.emitTelemetry(J,"pie-tool-init-success",{toolId:Q,providerId:Q,backend:X(G),operation:"provider-initialize",duration:Date.now()-j}),console.log(`[ToolProviderRegistry] Provider "${Q}" initialized`)}catch(Z){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Q,providerId:Q,backend:X(G),operation:"provider-initialize",duration:Date.now()-j,errorType:"ProviderInitializationError",message:Z instanceof Error?Z.message:String(Z)}),console.error(`[ToolProviderRegistry] Initialization failed for "${Q}":`,Z),Z}}async getProvider(Q,Y=!0){let J=this.providers.get(Q);if(!J)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:Q,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${Q}" not registered`);if(Y&&!this.initialized.get(Q))console.log("[ToolProviderRegistry] Auto-initializing provider:",Q),await this.initialize(Q);return J}getProvidersByCategory(Q){return Array.from(this.providers.entries()).filter(([Y,J])=>J.category===Q).map(([Y])=>Y)}getProviderIds(){return Array.from(this.providers.keys())}has(Q){return this.providers.has(Q)}isInitialized(Q){return this.initialized.get(Q)===!0}isInitializing(Q){return this.initializationPromises.has(Q)}async unregister(Q){let Y=this.providers.get(Q);if(Y){let J=this.initializationPromises.get(Q);if(J)try{await J}catch{}Y.destroy(),this.providers.delete(Q),this.configs.delete(Q),this.initialized.delete(Q),this.initializationPromises.delete(Q),console.log(`[ToolProviderRegistry] Unregistered provider "${Q}"`)}}async destroy(){let Q=Array.from(this.providers.keys());await Promise.all(Q.map((Y)=>this.unregister(Y))),console.log("[ToolProviderRegistry] Registry destroyed")}}class w9{targets=new Set;changeListeners=new Set;registerTarget(Q){return this.targets.add(Q),this.notifyChange(),()=>{if(!this.targets.delete(Q))return;this.notifyChange()}}canRequest(Q,Y){return this.findTarget(Q,Y)!==null}request(Q){let Y=this.findTarget(Q.toolId,Q.level);if(!Y)return!1;try{Y.open(Q.toolId,Q.params)}catch(J){return console.error(`[ToolRequestRegistry] Target failed to open "${Q.toolId}":`,J),!1}return!0}onTargetsChange(Q){return this.changeListeners.add(Q),()=>{this.changeListeners.delete(Q)}}findTarget(Q,Y){let J=this.findTargetAtLevel(Q,Y??"section");if(J||Y!==void 0)return J;for(let G of this.targets){if(G.level==="section")continue;if(this.hostsTool(G,Q))return G}return null}findTargetAtLevel(Q,Y){for(let J of this.targets){if(J.level!==Y)continue;if(this.hostsTool(J,Q))return J}return null}hostsTool(Q,Y){try{return Q.hostsTool(Y)===!0}catch(J){return console.warn(`[ToolRequestRegistry] Target at level "${Q.level}" failed the host check for "${Y}":`,J),!1}}notifyChange(){for(let Q of this.changeListeners)try{Q()}catch(Y){console.warn("[ToolRequestRegistry] Target change listener threw:",Y)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}var H2=(Q)=>`No assessment is bound, so no policy source could grant "${Q}"`;function R9(Q,Y,J,G){return{featureId:Q,granted:!1,action:"block",rule:Y,precedence:0,sourceType:"host",reason:Y==="host-blocked"?"Listed in tools.policy.blocked":`Not listed in tools.policy.allowed (${J.join(", ")})`,required:!1,assessmentBound:G.assessmentBound}}function x8(Q,Y,J){let G=Y.decisions[0],X=Array.from(Y.perToolFlags.values())[0],j=G?.action==="enable",Z=G?.reason??`Feature "${Q}" not configured`;return{featureId:Q,granted:j,action:G?.action??"skip",rule:G?.rule??"pnp-support",precedence:G?.precedence??6,sourceType:G?.sourceType??"system",reason:J.assessmentBound||j?Z:H2(Q),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:J.assessmentBound}}class E9{provenance;stepCounter=0;constructor(Q){this.provenance={contextId:Q,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(Q,Y){let J={id:Y.id,name:Y.name??Y.id};switch(Q){case"organization":this.provenance.sources.organization={...J,pnpDefaults:Y.config};break;case"assessment":this.provenance.sources.assessment={...J,settings:Y.config};break;case"section":this.provenance.sources.section={...J,settings:Y.config};break;case"item":this.provenance.sources.item={...J,settings:Y.config};break;case"student":this.provenance.sources.student={id:Y.id,pnpProfile:Y.config};break;case"host":this.provenance.sources.host={id:Y.id,config:Y.config};break}return this}addDecision(Q){let Y={step:++this.stepCounter,precedence:Q.precedence,rule:Q.rule,featureId:Q.featureId,action:Q.action,source:{type:Q.sourceType,id:Q.sourceId,name:Q.sourceName},reason:Q.reason,value:Q.value,timestamp:new Date};this.provenance.decisionLog.push(Y);let J=this.provenance.features.get(Q.featureId);if(!J)J={featureId:Q.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(Q.featureId,J);if(J.allDecisions.push(Y),Q.action==="advisory"){if(J.finalState==="not-configured")J.finalState="advisory-only"}else if(Q.action!=="skip"){if(!J.winningDecision||Y.precedence<J.winningDecision.precedence)J.winningDecision=Y,J.finalState=Y.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[Q.sourceType]=(this.provenance.summary.bySource[Q.sourceType]||0)+1,this.provenance.summary.byRule[Q.rule]=(this.provenance.summary.byRule[Q.rule]||0)+1,this}reconcileFinalStates(Q){for(let Y of Q){let J=this.provenance.features.get(Y);if(!J){J={featureId:Y,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Y,J);continue}J.finalState="enabled"}for(let Y of this.provenance.features.values()){if(Q.has(Y.featureId))continue;let J=Y.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),G=Y.allDecisions.some((X)=>X.action==="advisory");if(J)Y.finalState="blocked";else if(G)Y.finalState="advisory-only";else Y.finalState="not-configured"}return this}build(){for(let Q of this.provenance.features.values())Q.explanation=D2(Q);for(let Q of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,Q.finalState==="enabled")this.provenance.summary.enabled++;else if(Q.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function D2(Q){if(!Q.winningDecision){if(Q.finalState==="advisory-only"){let j=Q.allDecisions.find((Z)=>Z.action==="advisory");return j?`Feature "${Q.featureId}" was kept in its host-decided state; ${j.reason}`:`Feature "${Q.featureId}" carries an advisory note.`}return`Feature "${Q.featureId}" was not configured at any level.`}let Y=Q.winningDecision,J=Y.source.name||Y.source.type,G=`Feature "${Q.featureId}" is ${Q.finalState}.
216
216
 
217
- `;J+=`**Primary Reason** (${Q.rule}):
218
- `,J+=`${Q.reason}
219
- `,J+=`Source: ${Y} (${Q.source.type})
220
- `;let X=G.allDecisions.filter((j)=>j.step!==Q.step&&j.action!=="skip"&&j.action!=="advisory"&&j.precedence>Q.precedence);if(X.length>0){J+=`
217
+ `;G+=`**Primary Reason** (${Y.rule}):
218
+ `,G+=`${Y.reason}
219
+ `,G+=`Source: ${J} (${Y.source.type})
220
+ `;let X=Q.allDecisions.filter((j)=>j.step!==Y.step&&j.action!=="skip"&&j.action!=="advisory"&&j.precedence>Y.precedence);if(X.length>0){G+=`
221
221
  **Overridden Rules**:
222
- `;for(let j of X)J+=`- ${j.rule}: ${j.reason}
223
- `}return J}function b8(G){let{request:Q,tools:Y,pnpPolicy:J,customSources:X,contextId:j}=G,Z=new M1(j);Z.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:Y.placement,policy:Y.policy}});let q=L7(Y.placement[Q.level]),B=L7(Y.policy.allowed),K=new Set(L7(Y.policy.blocked)),W=[];for(let D of q)W.push(D),Z.addDecision({precedence:0,rule:"placement-membership",featureId:D,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(W=W.filter((D)=>{if(Y.providers?.[D]?.enabled===!1)return Z.addDecision({precedence:0,rule:"provider-disabled",featureId:D,action:"block",sourceType:"host",reason:`tools.providers.${D}.enabled === false`,value:!1}),!1;return!0}),B.length>0){let D=new Set(B);W=W.filter((P)=>{if(!D.has(P))return Z.addDecision({precedence:0,rule:"host-allowlist",featureId:P,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:B}),!1;return!0})}W=W.filter((D)=>{if(K.has(D))return Z.addDecision({precedence:0,rule:"host-blocked",featureId:D,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:Y.policy.blocked}),!1;return!0});let $=[],H=new Map;for(let D of W)H.set(D,["placement"]);let N=new Set(W),F=null;if(J.enforcement==="on"&&J.source&&(J.assessment||J.currentItemRef)){if(F=J.source.apply({assessment:J.assessment,currentItemRef:J.currentItemRef}),F.sources.assessment)Z.addSource("assessment",F.sources.assessment);if(F.sources.student)Z.addSource("student",F.sources.student);if(F.sources.item)Z.addSource("item",F.sources.item);for(let D of F.decisions)Z.addDecision({precedence:D.precedence,rule:D.rule,featureId:D.featureId,action:D.action,sourceType:D.sourceType,reason:D.reason,value:D.value});for(let D of F.unmappedSupportIds)$.push({code:"tool-policy.unknownSupportId",level:Q.level,toolId:D,message:`No registered tool claims PNP support id "${D}"; it was carried through as a feature id and matched nothing. Expected an AfA 3.0 / QTI 3.0 access feature id.`,source:"pnp.pnp-support"});W=W.filter((D)=>{return!F.blockedToolIds.has(D)});for(let D of Array.from(H.keys()))if(F.blockedToolIds.has(D))H.delete(D);for(let D of F.mandatedToolIds){if(!!N.has(D))continue;let v=F.perToolFlags.get(D)?.rule??"required-tool",I=MQ(D,{placement:q,allowed:B,blocked:K,providers:Y.providers}),p={rule:v,hostRule:I.hostRule,hostValue:I.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:D,message:`Profile policy mandates "${D}" (${v}) but host policy removed it from level "${Q.level}" via ${I.hostRule}.`,details:p}),Z.addDecision({precedence:0,rule:"required-tool-blocked",featureId:D,action:"advisory",sourceType:"host",reason:`Host removed required tool "${D}" via ${I.hostRule}`,value:p})}for(let D of W){let P=F.perToolFlags.get(D);if(P){let S=H.get(D)??[];S.push(`pnp.${P.rule}`),H.set(D,S)}}}for(let D=0;D<X.length;D++){let P=X[D],S=W.slice(),v=P.refine({request:Q,candidates:S}),I=new Set(v.refinedCandidates);for(let E of v.refinedCandidates)if(!S.includes(E))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:E,message:`Custom source "${P.id}" tried to add tool "${E}" that was not in candidates; ignored.`,source:`custom.${P.id}`}),I.delete(E);W=S.filter((E)=>I.has(E));let p=new Set;if(v.decisions){for(let E of v.decisions)if(Z.addDecision({precedence:E.precedence??100+D,rule:E.rule,featureId:E.featureId,action:E.action,sourceType:E.sourceType,reason:E.reason,value:E.value}),E.action==="block")p.add(E.featureId)}for(let E of S){if(I.has(E))continue;if(p.has(E))continue;Z.addDecision({precedence:100+D,rule:"custom-source",featureId:E,action:"block",sourceType:"custom",reason:`Custom policy source "${P.id}" removed tool "${E}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:P.id}})}for(let E of W){let g=H.get(E)??["placement"];g.push(`custom.${P.id}`),H.set(E,g)}for(let E of S)if(!I.has(E))H.delete(E)}let O=new Set(W),L=W.map((D)=>{let P=F?.perToolFlags.get(D);return{toolId:D,required:P?.required??!1,alwaysAvailable:P?.alwaysAvailable??!1,settings:P?.settings,sources:H.get(D)??["placement"]}});return Z.reconcileFinalStates(O),{visibleTools:L,diagnostics:$,provenance:Z.build()}}function MQ(G,Q){if(!Q.placement.includes(G))return{hostRule:"placement-missing",hostValue:Q.placement};if(Q.providers?.[G]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Q.allowed.length>0&&!Q.allowed.includes(G))return{hostRule:"host-allowlist",hostValue:Q.allowed};if(Q.blocked.has(G))return{hostRule:"host-blocked",hostValue:Array.from(Q.blocked)};return{hostRule:"placement-missing",hostValue:Q.placement}}function p0(G){if(!G)return!1;let Q=G.personalNeedsProfile;if(Q){if(Array.isArray(Q.supports)&&Q.supports.length>0)return!0;if(Array.isArray(Q.prohibitedSupports)&&Q.prohibitedSupports.length>0)return!0;if(Array.isArray(Q.activateAtInit)&&Q.activateAtInit.length>0)return!0}let Y=G.settings;if(Y){let J=Y.districtPolicy;if(J){if(Array.isArray(J.blockedTools)&&J.blockedTools.length>0)return!0;if(Array.isArray(J.requiredTools)&&J.requiredTools.length>0)return!0;if(J.policies&&typeof J.policies==="object"&&Object.keys(J.policies).length>0)return!0}let X=Y.testAdministration;if(X&&typeof X==="object")for(let j of Object.keys(X)){let Z=X[j];if(Z===void 0||Z===null)continue;if(Array.isArray(Z)&&Z.length===0)continue;if(typeof Z==="object"&&!Array.isArray(Z)&&Object.keys(Z).length===0)continue;return!0}}return!1}function g0(G){let Q=G?.settings;if(!Q)return!1;if(Array.isArray(Q.requiredTools)&&Q.requiredTools.length>0)return!0;if(Array.isArray(Q.restrictedTools)&&Q.restrictedTools.length>0)return!0;if(Q.toolParameters&&typeof Q.toolParameters==="object"&&Object.keys(Q.toolParameters).length>0)return!0;return!1}function l7(G){if(p0(G.assessment))return"on";if(g0(G.currentItemRef))return"on";return"off"}class z1{id="pnp";toolRegistry;constructor(G){this.toolRegistry=G}apply(G){let{ctx:Q,result:Y}=this.prepare(G),{pnp:J,districtPolicy:X,itemSettings:j}=Q,Z=new Set;J?.supports?.forEach((q)=>Z.add(q)),J?.prohibitedSupports?.forEach((q)=>Z.add(q)),X?.blockedTools?.forEach((q)=>Z.add(q)),X?.requiredTools?.forEach((q)=>Z.add(q)),j?.requiredTools?.forEach((q)=>Z.add(q)),j?.restrictedTools?.forEach((q)=>Z.add(q));for(let q of Z)this.resolveSupport(q,Q,Y);return Y}resolveFeature(G,Q){let{ctx:Y,result:J}=this.prepare(Q);return this.resolveSupport(G,Y,J),J}prepare(G){let{assessment:Q,currentItemRef:Y}=G,J=Q?.personalNeedsProfile,X=Q?.settings,j=Y?.settings,Z={blockedToolIds:new Set,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],unmappedSupportIds:new Set,sources:{}};if(X?.districtPolicy||X?.testAdministration)Z.sources.assessment={id:Q?.id||"unknown",name:Q?.name||Q?.id||"Assessment",config:X};if(J)Z.sources.student={id:"student",name:"Student PNP Profile",config:J};if(Y&&j)Z.sources.item={id:Y.identifier,name:Y.identifier,config:j};return{ctx:{pnp:J,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:j,toolConfigs:X?.toolConfigs},result:Z}}resolveSupport(G,Q,Y){if(Q.districtPolicy?.blockedTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:1,rule:"district-block",featureId:X,action:"block",sourceType:"assessment",reason:`District policy blocks "${G}" for all assessments`,value:Q.districtPolicy.blockedTools});return}if(Q.testAdmin?.toolOverrides?.[G]===!1){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:2,rule:"test-admin-override",featureId:X,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${G}" for this session`,value:Q.testAdmin.toolOverrides});return}if(Q.itemSettings?.restrictedTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:3,rule:"item-restriction",featureId:X,action:"block",sourceType:"item",reason:`Item restricts "${G}" (e.g., mental math question blocks calculator)`,value:Q.itemSettings.restrictedTools});return}if(Q.itemSettings?.requiredTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(G,Q),rule:"item-requirement",sourceType:"item"}),Y.decisions.push({precedence:4,rule:"item-requirement",featureId:X,action:"enable",sourceType:"item",reason:`Item requires "${G}" for this question`,value:Q.itemSettings.requiredTools});return}if(Q.districtPolicy?.requiredTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(G,Q),rule:"district-requirement",sourceType:"assessment"}),Y.decisions.push({precedence:5,rule:"district-requirement",featureId:X,action:"enable",sourceType:"assessment",reason:`District policy requires "${G}" for all assessments`,value:Q.districtPolicy.requiredTools});return}if(Q.pnp?.prohibitedSupports?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:6,rule:"pnp-prohibited",featureId:X,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${G}"`,value:Q.pnp.prohibitedSupports});return}if(Q.pnp?.supports?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.perToolFlags.set(X,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(G,Q),rule:"pnp-support",sourceType:"student"}),Y.decisions.push({precedence:6,rule:"pnp-support",featureId:X,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${G}"`,value:Q.pnp.supports});return}let J=this.mapSupportToToolId(G,Y);Y.decisions.push({precedence:6,rule:"pnp-support",featureId:J,action:"skip",sourceType:"system",reason:`Feature "${G}" not configured at any level`,value:{supportId:G}})}mapSupportToToolId(G,Q){let Y=this.toolRegistry.getToolsByPNPSupport(G);if(Y.size===0){if(this.toolRegistry.getAllTools().length>0)Q.unmappedSupportIds.add(G);return G}return Array.from(Y)[0]}resolveToolSettings(G,Q){return Q.itemSettings?.toolParameters?.[G]??Q.toolConfigs?.[G]}}var c0=b7({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class O1{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;currentItemRef;pnpEnforcement;disposed=!1;constructor(G){this.toolRegistry=G.toolRegistry,this.contextId=G.contextId??"tool-policy",this.pnpPolicySource=new z1(this.toolRegistry),this.customSources=G.customSources?[...G.customSources]:[];let Q=G.inputs??{};this.tools=Q.tools??c0,this.assessment=Q.assessment??null,this.currentItemRef=Q.currentItemRef??null,this.pnpEnforcement=Q.pnpEnforcement??l7({assessment:this.assessment,currentItemRef:this.currentItemRef})}decide(G){this.assertNotDisposed();let Q=G.scope.scopeId?`${this.contextId}:${G.level}:${G.scope.scopeId}`:`${this.contextId}:${G.level}`;return b8({request:G,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0,enforcement:this.pnpEnforcement},customSources:this.customSources,contextId:Q})}decideFeature(G){this.assertNotDisposed();let Q=this.hostFeatureGate(G);if(Q)return Q;return u0(G,this.pnpPolicySource.resolveFeature(G,{assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0}),{assessmentBound:this.assessment!==null})}hostFeatureGate(G){let Q={assessmentBound:this.assessment!==null},Y=L7(this.tools.policy.blocked);if(Y.includes(G))return E8(G,"host-blocked",Y,Q);let J=L7(this.tools.policy.allowed);if(J.length>0&&!J.includes(G))return E8(G,"host-allowlist",J,Q);return null}getVisibleToolIds(G,Q){return this.decide({level:G,scope:{level:G,scopeId:Q}}).visibleTools.map((Y)=>Y.toolId)}updateInputs(G){this.assertNotDisposed();let Q=!1,Y=!1;if("tools"in G){let J=G.tools??c0;if(!Object.is(this.tools,J))this.tools=J,Q=!0}if("assessment"in G){let J=G.assessment??null;if(!Object.is(this.assessment,J))this.assessment=J,Q=!0}if("currentItemRef"in G){let J=G.currentItemRef??null;if(!Object.is(this.currentItemRef,J))this.currentItemRef=J,Q=!0}if("pnpEnforcement"in G&&G.pnpEnforcement){if(this.pnpEnforcement!==G.pnpEnforcement)this.pnpEnforcement=G.pnpEnforcement,Y=!0}if(Q||Y)this.emit({reason:Y&&!Q?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}registerPolicySource(G){return this.assertNotDisposed(),this.customSources.push(G),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Q=this.customSources.indexOf(G);if(Q!==-1){if(this.customSources.splice(Q,1),!this.disposed)this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}}onPolicyChange(G){return this.listeners.add(G),()=>{this.listeners.delete(G)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,currentItemRef:this.currentItemRef,pnpEnforcement:this.pnpEnforcement})}emit(G){for(let Q of Array.from(this.listeners))try{Q(G)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}var zQ=Symbol("@pie-players/tool-policy-engine");class d extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class T8 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var P1=(G)=>!!G&&typeof G==="object"&&!Array.isArray(G),OQ=(G,Q,Y)=>{let J={...Q,...Y};if(G==="textToSpeech"&&P1(Q.settings)&&P1(Y.settings)){if(J.settings={...Q.settings,...Y.settings},P1(Q.settings.mathSpeech)&&P1(Y.settings.mathSpeech))J.settings.mathSpeech={...Q.settings.mathSpeech,...Y.settings.mathSpeech}}return J},PQ=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],LQ=["section-navigation-change","section-session-applied","section-loading-complete","section-items-complete-changed","section-error","timed-media-cue-changed","timed-media-policy-degraded","timed-media-invalid"];class L1{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;toolRegistry;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new R8;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitEntries=new Map;sectionControllerDisposePromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;pnpEnforcementOverride=null;boundAssessment=null;boundCurrentItemRef=null;reportedUnboundFeaturePolicy=!1;static resolveConfig(G){let Q=i1(G.toolConfigStrictness),Y=G.toolRegistry??new S8,J=G.deferToolConfigValidation===!0?b7(G.tools):Z7(G.tools,{strictness:Q,source:"ToolkitCoordinator.init",toolRegistry:Y}).config;return{...G,toolConfigStrictness:Q,toolRegistry:Y,tools:{...J,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...J.providers}},accessibility:{language:"en-US",...G.accessibility??{},catalogs:G.accessibility?.catalogs??[]}}}constructor(G){if(!G.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");let Q=L1.resolveConfig(G);if(this.assessmentId=Q.assessmentId,this.config=Q,this.toolRegistry=Q.toolRegistry??new S8,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks=Q.hooks??{},this.lazyInit=G.lazyInit===!0,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=G.frameworkErrorBus??new p7,this.ownsFrameworkErrorBus=!G.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new X8,this.highlightCoordinator=new g7,this.elementToolStateStore=new Y8,this.catalogResolver=new Q8(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new F1,this._registerToolProviders(),this.ttsService=new c7,this.setupStatePersistenceHooks(),this.policyEngine=new O1({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,inputs:{tools:this.config.tools,assessment:null,currentItemRef:null,pnpEnforcement:this.resolveEffectivePnpEnforcement()}}),!this.lazyInit)this.waitUntilReady().catch((Y)=>{if(Y instanceof d)return;console.error("[ToolkitCoordinator] Failed eager initialization:",Y),this.handleError(Y,{phase:"coordinator-ready"})})}assertNotDisposed(){if(this.disposePromise!==null)throw new d}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((G)=>{let Q=this.hooks.onFrameworkError;if(!Q)return;try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",Y)}})}async emitTelemetry(G,Q){try{await this.hooks.onTelemetry?.(G,Q)}catch(J){console.warn("[ToolkitCoordinator] telemetry hook failed:",J)}let Y=Q?{...Q}:void 0;for(let J of this.telemetryListeners)try{J({eventName:G,payload:Y?{...Y}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(G){for(let Q of this.sectionControllerLifecycleListeners)try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",Y)}}handleError(G,Q){let Y=X6({error:G,context:Q});this.frameworkErrorBus.reportFrameworkError(Y)}subscribeFrameworkErrors(G){return this.frameworkErrorBus.subscribeFrameworkErrors(G)}reportFrameworkError(G){this.frameworkErrorBus.reportFrameworkError(G)}getSectionControllerMapKey(G){return`${G.assessmentId}::${G.sectionId}::${G.attemptId||""}`}createDefaultSectionPersistence(){let G=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Q=(Y)=>{let{assessmentId:J,sectionId:X,attemptId:j}=Y.key;return`pie:section-controller:v1:${J}:${X}:${j||"default"}`};return{async loadSession(Y){if(!G)return null;let J=G.getItem(Q(Y));if(!J)return null;try{return JSON.parse(J)}catch{return null}},async saveSession(Y,J){if(!G)return;G.setItem(Q(Y),JSON.stringify(J))},async clearSession(Y){if(!G)return;G.removeItem(Q(Y))}}}async resolveSectionPersistence(G){let Q=this.getSectionControllerMapKey(G.key),Y=this.sectionPersistenceStrategies.get(Q);if(Y)return Y;let J={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(G,J)??await J.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Q,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((G)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(G)).catch((Q)=>{this.handleError(Q,{phase:"state-save"})})})}async ensureStateLoaded(){if(this.stateLoaded)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let G=this.hooks.loadToolState;if(!G)return;try{let Q=await G();if(this.assertNotDisposed(),Q&&typeof Q==="object")this.elementToolStateStore.loadState(Q);this.stateLoaded=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Q)})}catch(Q){if(Q instanceof d)throw Q;this.handleError(Q,{phase:"state-load"})}})().finally(()=>{this.stateLoadPromise=void 0}),this.stateLoadPromise}_registerToolProviders(){let G=this.getProviderDescriptorTools();for(let Q of G)this.registerProviderFromTool(Q)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((G)=>!!G.provider)}async registerProviderFromTool(G){let Q=G.provider;if(!Q)return;let Y=this.getToolConfig(G.toolId)||void 0;if(Y?.enabled===!1)return;let J=Q.getProviderId?.(Y)??Y?.provider?.id??G.toolId;if(this.toolProviderRegistry.has(J))return;let X=Q.createProvider(Y),j=Q.getInitConfig?.(Y)??Y?.provider?.init??{},Z=this.addToolTelemetryReporter({toolId:G.toolId,providerId:J,initConfig:j}),q=this.createToolTelemetryForwarder({toolId:G.toolId,providerId:J}),B=Q.getAuthFetcher?.(Y)??Y?.provider?.runtime?.authFetcher;await this.registerProvider(J,{provider:X,config:Z,lazy:Q.lazy??!0,authFetcher:B,onTelemetry:q})}createToolTelemetryForwarder(G){return async(Q,Y)=>{await this.emitTelemetry(Q,{...Y||{},toolId:G.toolId,providerId:G.providerId})}}addToolTelemetryReporter(G){let Q=G.initConfig&&typeof G.initConfig==="object"?{...G.initConfig}:{},Y=typeof Q.onTelemetry==="function"?Q.onTelemetry:null,J=this.createToolTelemetryForwarder({toolId:G.toolId,providerId:G.providerId});return Q.onTelemetry=async(X,j)=>{if(Y)await Y(X,j);await J(X,j)},Q}async registerProvider(G,Q){try{this.toolProviderRegistry.register(G,Q);let Y={providerId:G,providerName:Q.provider.providerName};await this.hooks.onProviderRegistered?.(G,Y),await this.emitTelemetry("pie-toolkit-provider-registered",{providerId:G,providerName:Q.provider.providerName})}catch(Y){console.warn(`[ToolkitCoordinator] Failed to register provider "${G}":`,Y),this.handleError(Y,{phase:"provider-register",providerId:G})}}async ensureProviderReady(G){this.assertNotDisposed();let Q=this.providerInitPromises.get(G);if(Q)return Q;let Y=(async()=>{let J=await this.toolProviderRegistry.getProvider(G,!1);this.assertNotDisposed();let X={providerId:G,providerName:J.providerName};try{return await this.hooks.onProviderInitStart?.(G,X),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(G),this.assertNotDisposed(),await this.hooks.onProviderReady?.(G,X),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{providerId:G}),this.assertNotDisposed(),J}catch(j){if(j instanceof d)throw j;let Z=j instanceof Error?j:Error(String(j));throw this.handleError(Z,{phase:"provider-init",providerId:G}),Z}})().finally(()=>{this.providerInitPromises.delete(G)});return this.providerInitPromises.set(G,Y),Y}setHooks(G){if(Object.assign(this.hooks,G),this.setupStatePersistenceHooks(),this.disposePromise===null&&G.onCoordinatorReady&&this.isReady())Promise.resolve(G.onCoordinatorReady(this)).catch((Q)=>{this.handleError(Q,{phase:"coordinator-ready"})})}subscribeTelemetry(G){return this.telemetryListeners.add(G),()=>{this.telemetryListeners.delete(G)}}getSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(Q))}subscribeSectionEvents(G){if(this.activeCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Q=this.activeSubscriptions.get(G.listener);if(Q)Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let Y={listener:G.listener,eventTypes:G.eventTypes,itemIds:G.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(G.listener,Y);let J=this.sectionControllers.get(this.activeCohortMapKey);if(J)this.bindSubscriptionToController(Y,J);let X=!1;return()=>{if(X)return;if(X=!0,Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null,this.activeSubscriptions.get(G.listener)===Y)this.activeSubscriptions.delete(G.listener)}}bindSubscriptionToController(G,Q){G.unsubscribeCurrent?.(),G.unsubscribeCurrent=null;let Y=Q.subscribe;if(typeof Y!=="function")return;let J=this.buildSectionEventPredicate(G);G.unsubscribeCurrent=Y.call(Q,(Z)=>{if(!J(Z))return;this.deliverSectionEventSafely(G.listener,Z)});let X=this.buildContentLoadedReplayEvents(Q);for(let Z of X)if(J(Z))this.deliverSectionEventSafely(G.listener,Z);let j=this.buildLoadingCompleteReplayEvent(Q);if(j&&J(j))this.deliverSectionEventSafely(G.listener,j)}deliverSectionEventSafely(G,Q){try{G(Q)}catch(Y){console.warn("[ToolkitCoordinator] section-event listener failed:",Y)}}setActiveCohort(G){if(this.activeCohortMapKey===G)return;this.activeCohortMapKey=G;let Q=this.sectionControllers.get(G);if(!Q)return;for(let Y of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(Y,Q)}setActiveCohortIfLatestRequest(G){if(this.latestRequestedActiveCohortMapKey!==G)return;this.setActiveCohort(G)}suspendActiveCohortIfSuperseded(G){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===G)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}clearActiveCohortIfMatches(G){if(this.activeCohortMapKey!==G)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}buildSectionEventPredicate(G){let Q=G.eventTypes?new Set(G.eventTypes):null,Y=G.itemIds?new Set(G.itemIds):null;return(J)=>{if(Q||Y){let X=J?.type||null;if(Q&&(!X||!Q.has(X)))return!1;if(Y){if(!Array.from(this.collectEventItemIds(J)).some((Z)=>Y.has(Z)))return!1}}return!0}}collectEventItemIds(G){let Q=new Set;if("itemId"in G&&typeof G.itemId==="string")Q.add(G.itemId);if("canonicalItemId"in G&&typeof G.canonicalItemId==="string")Q.add(G.canonicalItemId);if("currentItemId"in G&&typeof G.currentItemId==="string")Q.add(G.currentItemId);if("previousItemId"in G&&typeof G.previousItemId==="string")Q.add(G.previousItemId);return Q}buildContentLoadedReplayEvents(G){let Q=G.getRuntimeState?.(),Y=Q?.loadedRenderables;if(!Array.isArray(Y)||Y.length===0)return[];let J=typeof Q?.currentItemIndex==="number"&&Number.isFinite(Q.currentItemIndex)?Q.currentItemIndex:0,X=Date.now(),j=[];for(let Z of Y){if(!Z)continue;let q=Z.itemId,B=typeof Z.canonicalItemId==="string"&&Z.canonicalItemId?Z.canonicalItemId:q;if(typeof q!=="string"||!q)continue;j.push({type:"content-loaded",contentKind:Z.contentKind??"unknown",itemId:q,canonicalItemId:B,currentItemIndex:J,timestamp:X})}return j}buildLoadingCompleteReplayEvent(G){let Q=G.getRuntimeState?.();if(Q?.loadingComplete!==!0)return null;let Y=typeof Q.totalRegistered==="number"&&Number.isFinite(Q.totalRegistered)?Math.max(0,Q.totalRegistered):0,J=typeof Q.totalLoaded==="number"&&Number.isFinite(Q.totalLoaded)?Math.max(0,Q.totalLoaded):Y;return{type:"section-loading-complete",totalRegistered:Y,totalLoaded:J,currentItemIndex:Q.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(G){return this.subscribeSectionEvents({eventTypes:G.eventTypes||PQ,itemIds:G.itemIds,listener:G.listener})}subscribeSectionLifecycleEvents(G){return this.subscribeSectionEvents({eventTypes:G.eventTypes||LQ,listener:G.listener})}onSectionControllerLifecycle(G){return this.sectionControllerLifecycleListeners.add(G),()=>{this.sectionControllerLifecycleListeners.delete(G)}}async getOrCreateSectionController(G){if(this.disposePromise!==null)throw new d;let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId},Y=this.getSectionControllerMapKey(Q);this.latestRequestedActiveCohortMapKey=Y,this.suspendActiveCohortIfSuperseded(Y);let J=await this.resolveExistingSectionController({mapKey:Y,key:Q,input:G.input,updateExisting:G.updateExisting});if(J){if(this.disposePromise!==null)throw new d;return J}let X=this.sectionControllerDisposePromises.get(Y);if(X)await Promise.allSettled([X]);if(this.disposePromise!==null)throw new d;let j=this.sectionControllerInitEntries.get(Y);if(j)return j.promise;let Z={retired:!1,candidateClaimed:!1},q=this.initializeNewSectionController({args:G,key:Q,mapKey:Y,token:Z}).catch((B)=>{throw this.handleSectionControllerInitError(B,G),B}).finally(()=>{if(this.sectionControllerInitEntries.get(Y)?.token===Z)this.sectionControllerInitEntries.delete(Y)});return this.sectionControllerInitEntries.set(Y,{key:Q,token:Z,promise:q}),q}async resolveExistingSectionController(G){let Q=this.sectionControllers.get(G.mapKey);if(!Q)return;if(this.sectionControllerKeys.set(G.mapKey,G.key),G.updateExisting!==!1)await Q.updateInput?.(G.input);if(this.sectionControllers.get(G.mapKey)!==Q)return;return this.setActiveCohortIfLatestRequest(G.mapKey),Q}createSectionControllerContext(G){return{key:G.key,coordinator:this,input:G.input}}async initializeNewSectionController(G){let Q=this.createSectionControllerContext({key:G.key,input:G.args.input}),Y=await this.resolveSectionPersistence(Q);if(this.disposePromise!==null||G.token.retired){if(this.sectionPersistenceStrategies.get(G.mapKey)===Y)this.sectionPersistenceStrategies.delete(G.mapKey);throw this.createSectionControllerRetirementError()}let J={createDefaultController:G.args.createDefaultController},X=await this.hooks.createSectionController?.(Q,J)??await J.createDefaultController(),j={mapKey:G.mapKey,key:G.key,controller:X,persistence:Y,token:G.token};try{return await this.retireUnpublishedSectionControllerIfNeeded(j),await X.configureSessionPersistence?.({strategy:Y,context:Q}),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.initialize?.(G.args.input),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.hydrate?.(),await this.finalizeSectionControllerReady({...j,context:Q}),X}catch(Z){throw await this.cleanupUnpublishedSectionController(j),Z}}createSectionControllerRetirementError(){return this.disposePromise!==null?new d:new T8}async retireUnpublishedSectionControllerIfNeeded(G){if(this.disposePromise===null&&!G.token.retired)return;throw await this.cleanupUnpublishedSectionController(G),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(G){if(G.token.candidateClaimed)return;G.token.candidateClaimed=!0;try{await G.controller.dispose?.()}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:G.key.sectionId,attemptId:G.key.attemptId}})}finally{if(this.sectionPersistenceStrategies.get(G.mapKey)===G.persistence)this.sectionPersistenceStrategies.delete(G.mapKey)}}retirePublishedSectionControllerIfNeeded(G){if(this.disposePromise!==null&&!G.token.retired)this.disposeSectionController({sectionId:G.key.sectionId,attemptId:G.key.attemptId});if(G.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(G){await this.retireUnpublishedSectionControllerIfNeeded(G),this.sectionControllers.set(G.mapKey,G.controller),this.sectionControllerKeys.set(G.mapKey,G.key),G.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(G.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:G.key,controller:G.controller}),await this.hooks.onSectionControllerReady?.(G.context,G.controller),this.retirePublishedSectionControllerIfNeeded(G),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:G.key.assessmentId,sectionId:G.key.sectionId,attemptId:G.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(G)}handleSectionControllerInitError(G,Q){if(G instanceof d||G instanceof T8)return;this.handleError(G,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId}})}disposeSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId},Y=this.getSectionControllerMapKey(Q),J=this.sectionControllerInitEntries.get(Y);if(J)J.token.retired=!0;let X=this.sectionControllers.get(Y);if(!X){let K=this.sectionControllerDisposePromises.get(Y);if(K)return K;if(!J)return Promise.resolve();let W=Promise.allSettled([J.promise]).then(()=>{return});return this.trackSectionControllerDisposal(Y,W)}let j=this.sectionPersistenceStrategies.get(Y);if(this.clearActiveCohortIfMatches(Y),this.sectionControllers.get(Y)===X)this.sectionControllers.delete(Y),this.sectionControllerKeys.delete(Y),this.sectionPersistenceStrategies.delete(Y),this.emitSectionControllerLifecycle({type:"disposed",key:Q});let Z=this.createSectionControllerContext({key:Q,input:void 0}),q=this.disposeSectionControllerEntry({args:G,key:Q,context:Z,controller:X,persistenceStrategy:j}),B=J?Promise.allSettled([J.promise]).then(()=>q):q;return this.trackSectionControllerDisposal(Y,B)}trackSectionControllerDisposal(G,Q){this.sectionControllerDisposePromises.set(G,Q);let Y=()=>{if(this.sectionControllerDisposePromises.get(G)===Q)this.sectionControllerDisposePromises.delete(G)};return Q.then(Y,Y),Q}async disposeSectionControllerEntry(G){try{await this.runSectionControllerDisposePipeline({key:G.key,context:G.context,controller:G.controller,persistBeforeDispose:G.args.persistBeforeDispose})}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:G.args.sectionId,attemptId:G.args.attemptId}})}finally{await this.finalizeSectionControllerDispose({context:G.context,persistenceStrategy:G.persistenceStrategy,clearPersistence:G.args.clearPersistence})}}async runSectionControllerDisposePipeline(G){let Q=[];if(G.persistBeforeDispose!==!1)try{await G.controller.persist?.()}catch(Y){Q.push(Y)}try{await G.controller.dispose?.()}catch(Y){Q.push(Y)}if(Q.length===1)throw Q[0];if(Q.length>1)throw AggregateError(Q,"Section controller persistence and disposal both failed.");await this.hooks.onSectionControllerDispose?.(G.context,G.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:G.key.assessmentId,sectionId:G.key.sectionId,attemptId:G.key.attemptId})}async finalizeSectionControllerDispose(G){if(G.clearPersistence)await G.persistenceStrategy?.clearSession?.(G.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let G=[],Q=async(J)=>{try{await J()}catch(X){G.push(X)}};await this.waitForAdmittedInitialization();let Y=new Map;for(let[J,X]of this.sectionControllerInitEntries)Y.set(J,X.key);for(let[J,X]of this.sectionControllerKeys)Y.set(J,X);for(let J of Y.values())this.disposeSectionController({sectionId:J.sectionId,attemptId:J.attemptId});await Promise.allSettled(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let J of this.activeSubscriptions.values())await Q(()=>J.unsubscribeCurrent?.()),J.unsubscribeCurrent=null;this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Q(()=>this.ttsService.stop()),await Q(()=>this.toolProviderRegistry.destroy()),await Q(()=>this.highlightCoordinator.destroy());for(let J of this.toolCoordinator.getRegisteredTools())await Q(()=>this.toolCoordinator.releaseTool(J));if(await Q(()=>this.catalogResolver.destroy()),await Q(()=>this.toolRequests.dispose()),await Q(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(G.length===1)throw G[0];if(G.length>1)throw AggregateError(G,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let G=new Set;if(this.coordinatorReadyPromise)G.add(this.coordinatorReadyPromise);if(this.ttsInitPromise)G.add(this.ttsInitPromise);if(this.ttsReconfigurePromise)G.add(this.ttsReconfigurePromise);for(let Q of this.providerInitPromises.values())G.add(Q);await Promise.allSettled(G)}async ensureTTSReady(G){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(G).then(()=>this.assertNotDisposed()).finally(()=>{this.ttsInitPromise=void 0}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let G=this.ttsReconfigurePromise;while(G)await G,G=this.ttsReconfigurePromise}async _initializeTTS(G){if(this.ttsInitialized)return;let Q=this.resolveTTSToolConfig(G),Y=v0(Q),J=w8(Y),X=h0(Y);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:J}}),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:J}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:J}),this.toolProviderRegistry.has("tts"))try{let q=await(await this.ensureProviderReady("tts")).createInstance();await this.initializeTTSService(q,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:J,provider:"registry"}),console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");return}catch(Z){if(Z instanceof d)throw Z;let q=Z instanceof Error?Z:Error(String(Z));await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,errorType:"TTSRegistryInitError",message:q.message,recovered:!0}),await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,fromProvider:"registry",toProvider:"browser",reason:q.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",q)}let j=new T7;try{await this.initializeTTSService(j,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:J,provider:"browser-fallback"})}catch(Z){if(Z instanceof d)throw Z;let q=Z instanceof Error?Z:Error(String(Z));throw this.handleError(q,{phase:"tts-init"}),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:q.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:J,errorType:"TTSInitError",message:q.message}),q}}resolveTTSToolConfig(G){return G||this.getTTSConfigFromProviders()||{}}async initializeTTSService(G,Q){let Y={...Q.providerOptions||{},__pieTelemetry:async(X,j)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...j||{}})}},J={...Q,providerOptions:Y};await this.ttsService.initialize(G,J),await this.ensureBrowserVoicesReady(G),this.assertNotDisposed(),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,await this.hooks.onTTSReady?.(),this.assertNotDisposed()}async ensureBrowserVoicesReady(G,Q=1200){if(G.providerId!=="browser")return;if(typeof window>"u")return;if(!("speechSynthesis"in window))return;let Y=window.speechSynthesis;if(Y.getVoices().length>0)return;await new Promise((j)=>{let Z=!1,q=typeof Y.addEventListener==="function"&&typeof Y.removeEventListener==="function",B=!q&&"onvoiceschanged"in Y,K=B?Y.onvoiceschanged:null,W=!1,$=()=>{if(Z)return;if(Z=!0,window.clearTimeout(N),q)Y.removeEventListener("voiceschanged",H);else if(W&&Y.onvoiceschanged===H)Y.onvoiceschanged=K;j()},H=(F)=>{if(!q&&typeof K==="function"&&F)K.call(Y,F);$()},N=window.setTimeout($,Q);if(q)Y.addEventListener("voiceschanged",H,{once:!0});else if(B)Y.onvoiceschanged=H,W=!0});let X=Y.getVoices();await this.emitTelemetry("pie-toolkit-tts-browser-voices-ready",{voiceCount:X.length,timedOut:X.length===0})}getServiceBundle(){return{ttsService:this.ttsService,toolCoordinator:this.toolCoordinator,highlightCoordinator:this.highlightCoordinator,elementToolStateStore:this.elementToolStateStore,catalogResolver:this.catalogResolver,toolProviderRegistry:this.toolProviderRegistry}}async getToolProvider(G){return this.ensureProviderReady(G)}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{await this.ensureStateLoaded(),this.assertNotDisposed();let G=this.getTTSConfigFromProviders();if(G?.enabled!==!1)await this.ensureTTSReady(G);if(this.assertNotDisposed(),!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-coordinator-ready",{assessmentId:this.assessmentId})})().finally(()=>{this.coordinatorReadyPromise=void 0}),this.coordinatorReadyPromise}isReady(){return this.getInitStatus().coordinator}getInitStatus(){let G={};for(let Y of this.toolProviderRegistry.getProviderIds())G[Y]=this.toolProviderRegistry.isInitialized(Y);let Q=this.getTTSConfigFromProviders();return{tts:this.ttsInitialized,stateLoaded:this.stateLoaded||!this.hooks.loadToolState,coordinator:(this.stateLoaded||!this.hooks.loadToolState)&&(this.ttsInitialized||Q?.enabled===!1),providers:G}}getTTSConfigFromProviders(){return(this.config.tools?.providers||{}).textToSpeech}assertCanonicalToolId(G){if(typeof G!=="string"||G.trim().length===0)throw Error("Tool id must be a non-empty string.");if(G==="tts")throw Error('Tool id "tts" is no longer supported. Use "textToSpeech".');if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(G))throw Error(`Unknown tool id "${G}".`)}installToolContextResolvers(G){if(!G)return;for(let[Q,Y]of Object.entries(G)){if(Y==null)continue;if(this.assertCanonicalToolId(Q),typeof Y!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);this.toolContextResolvers.set(Q,Y)}}setToolContextResolvers(G){this.toolContextResolvers.clear(),this.installToolContextResolvers(G??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let G of this.toolContextResolverChangeListeners)try{G()}catch(Q){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Q)}}isToolEnabled(G){return this.assertCanonicalToolId(G),this.config.tools?.providers?.[G]?.enabled!==!1}getToolConfig(G){return this.assertCanonicalToolId(G),this.config.tools?.providers?.[G]||null}updateToolConfig(G,Q){this.assertCanonicalToolId(G);let Y=this.getToolConfig(G)||{};if(!this.config.tools)this.config.tools=Z7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}).config;if(!this.config.tools.providers)this.config.tools.providers={};let J={...this.config.tools.providers||{},[G]:OQ(G,Y,Q)},X=Z7({...this.config.tools,providers:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});this.config.tools=X.config,this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:G}),this._applyToolConfigChange(G,Q)}updateToolPlacement(G,Q){this.updateToolsPlacement({[G]:[...Q]})}updateToolsPlacement(G){if(!this.config.tools)this.config.tools=Z7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry}).config;let Q=this.config.tools?.placement??{section:[],item:[],passage:[]},Y={section:[...G.section??Q.section??[]],item:[...G.item??Q.item??[]],passage:[...G.passage??Q.passage??[]]},J=Z7({...this.config.tools,placement:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});J.config.placement=Y,this.config.tools=J.config,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(G){return this.policyEngine.decide(G)}decideFeaturePolicy(G){let Q=this.policyEngine.decideFeature(G);if(!Q.assessmentBound&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${G}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);return Q}onPolicyChange(G){return this.policyEngine.onPolicyChange(G)}onCatalogsChange(G){return this.catalogResolver.onCatalogsChange(G)}updateAssessment(G){this.boundAssessment=G,this.policyEngine.updateInputs({assessment:G,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}updateCurrentItemRef(G){this.boundCurrentItemRef=G,this.policyEngine.updateInputs({currentItemRef:G,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}setPnpEnforcement(G){this.pnpEnforcementOverride=G,this.policyEngine.updateInputs({pnpEnforcement:this.resolveEffectivePnpEnforcement()})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(G){return this.policyEngine.registerPolicySource(G)}registerToolContextResolver(G,Q){if(this.assertCanonicalToolId(G),typeof Q!=="function")throw Error(`Invalid tool context resolver for "${G}": expected a function.`);return this.toolContextResolvers.set(G,Q),this.notifyToolContextResolverChange(),()=>{if(this.toolContextResolvers.get(G)!==Q)return;this.toolContextResolvers.delete(G),this.notifyToolContextResolverChange()}}hasToolContextResolver(G){return this.assertCanonicalToolId(G),this.toolContextResolvers.has(G)}resolveToolContext(G){this.assertCanonicalToolId(G.toolId);let Q=this.toolContextResolvers.get(G.toolId);if(!Q)return null;let Y;try{Y=Q(G)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${G.toolId}" threw:`,X),{toolId:G.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!Y)return{toolId:G.toolId,visible:!0,params:{}};let J=Y.params&&typeof Y.params==="object"&&!Array.isArray(Y.params)?Y.params:{};return{toolId:G.toolId,visible:Y.visible!==!1,params:J,reason:typeof Y.reason==="string"?Y.reason:void 0}}onToolContextResolverChange(G){return this.toolContextResolverChangeListeners.add(G),()=>{this.toolContextResolverChangeListeners.delete(G)}}registerToolRequestTarget(G){return this.toolRequests.registerTarget(G)}requestTool(G){return this.assertCanonicalToolId(G.toolId),this.toolRequests.request(G)}canRequestTool(G,Q){try{this.assertCanonicalToolId(G)}catch{return!1}return this.toolRequests.canRequest(G,Q)}onToolRequestTargetsChange(G){return this.toolRequests.onTargetsChange(G)}resolveEffectivePnpEnforcement(){if(this.pnpEnforcementOverride!==null)return this.pnpEnforcementOverride;return l7({assessment:this.boundAssessment,currentItemRef:this.boundCurrentItemRef})}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(G,Q){if(this.disposePromise!==null)return;switch(G){case"textToSpeech":{let Y=this._reconfigureTTSProvider();this.ttsReconfigurePromise=Y,Y.finally(()=>{if(this.ttsReconfigurePromise===Y)this.ttsReconfigurePromise=void 0}),Y.then(async()=>{if(this.disposePromise!==null)return;let J=this.getTTSConfigFromProviders();if(!this.lazyInit&&J?.enabled!==!1)await this.ensureTTSReady(J)});break}case"answerEliminator":break}}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsInitPromise=void 0;try{this.ttsService.stop()}catch{}if(this.toolProviderRegistry.has("tts"))await this.toolProviderRegistry.unregister("tts");if(this.disposePromise!==null)return;let G=this.getProviderDescriptorTools().find((Q)=>Q.toolId==="textToSpeech");if(!G)return;await this.registerProviderFromTool(G)}}var wQ=()=>{};function l0(G){let{ttsService:Q,listenerId:Y,silence:J}=G;if(typeof Q?.onStateChange!=="function")return wQ;let X=(j)=>{if(j!==R.PLAYING&&j!==R.LOADING)return;J()};return Q.onStateChange(Y,X),()=>{try{Q.offStateChange?.(Y,X)}catch{}}}function d0(G){try{if(G?.isPlaying?.())G.pause?.()}catch{}}import{timedMediaProjectionSignature as G9}from"@pie-players/pie-players-shared/timed-media";var i0="pie-register",s0="pie-unregister",n0="pie-item-session-changed";var r0="pie-content-loaded",o0="pie-item-player-error",a0="pie-formative-action",t0="pie-media-time-source";var RQ={bubbles:!0,composed:!0,cancelable:!1};function EQ(G,Q,Y={}){return new CustomEvent(G,{detail:Q,...RQ,...Y})}function C8(G,Q,Y,J={}){return G.dispatchEvent(EQ(Q,Y,J))}function f7(){return{phase:"idle",cohort:null,controllerResolved:!1,readinessSignals:{sectionReady:!1,interactionReady:!1,allLoadingComplete:!1,runtimeError:!1},effectiveRuntime:null,effectiveToolsConfig:null,loadingCompleteEmitted:!1,lastFrameworkError:null,itemCount:0,loadedCount:0}}function y8(G,Q){if(G===Q)return!0;if(!G||!Q)return!1;return G.sectionId===Q.sectionId&&G.attemptId===Q.attemptId}function bQ(G){if(G.runtimeError)return"error";if(G.allLoadingComplete)return"ready";if(G.interactionReady)return"interaction-ready";if(G.sectionReady)return"loading";return"bootstrapping"}function e0(G){let Q=G.signals.sectionReady&&G.signals.allLoadingComplete,Y=G.mode==="strict"?Q:G.signals.interactionReady;return{phase:bQ({...G.signals,allLoadingComplete:Q,interactionReady:Y}),interactionReady:Y,allLoadingComplete:Q,reason:G.reason}}function G3(G){switch(G){case"idle":return null;case"booting-section":return"composed";case"engine-ready":return"engine-ready";case"interactive":return"interactive";case"disposed":return"disposed"}}function w1(G,Q,Y,J="entered"){let X=G3(Q);if(!X)return;G.push({kind:"stage-change",stage:X,status:J,cohort:Y})}function Q3(G){let Q={...f7(),phase:"booting-section",cohort:G.cohort,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig,itemCount:G.itemCount},Y=[];return w1(Y,"booting-section",G.cohort),{state:Q,outputs:Y}}function SQ(G,Q){if(G.phase==="idle"||G.phase==="disposed")return{state:G,outputs:[]};let Y=e0({mode:Q.mode,signals:Q.signals}),J=[],X=G.phase,j=G.loadingCompleteEmitted;if(X==="engine-ready"&&Y.interactionReady)X="interactive",w1(J,X,G.cohort);if(Y.allLoadingComplete&&G.cohort&&!j)j=!0,J.push({kind:"loading-complete",cohort:G.cohort,itemCount:Q.itemCount,loadedCount:Q.loadedCount});return{state:{...G,phase:X,readinessSignals:Q.signals,loadedCount:Q.loadedCount,itemCount:Q.itemCount,loadingCompleteEmitted:j},outputs:J}}function d7(G,Q){switch(Q.kind){case"initialize":{if(G.phase==="disposed")return{state:G,outputs:[]};if(G.phase!=="idle"){if(y8(G.cohort,Q.cohort))return d7(G,{kind:"update-runtime",effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig});return d7(G,{kind:"cohort-change",cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount})}return Q3({state:G,cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount})}case"update-runtime":{if(G.phase==="idle"||G.phase==="disposed")return{state:G,outputs:[]};return{state:{...G,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig},outputs:[]}}case"cohort-change":{if(G.phase==="disposed")return{state:G,outputs:[]};if(y8(G.cohort,Q.cohort))return d7(G,{kind:"update-runtime",effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig});let Y=[];if(G.phase!=="idle")Y.push({kind:"stage-change",stage:"disposed",status:"entered",cohort:G.cohort});let J=Q3({state:G,cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount});return{state:J.state,outputs:[...Y,...J.outputs]}}case"section-controller-resolved":{if(G.phase!=="booting-section")return{state:{...G,controllerResolved:!0},outputs:[]};let Y=[];return w1(Y,"engine-ready",G.cohort),{state:{...G,phase:"engine-ready",controllerResolved:!0},outputs:Y}}case"update-readiness-signals":return SQ(G,{signals:Q.signals,mode:Q.mode,loadedCount:Q.loadedCount,itemCount:Q.itemCount});case"framework-error":return{state:{...G,lastFrameworkError:Q.error,readinessSignals:{...G.readinessSignals,runtimeError:Q.error.recoverable===!0?G.readinessSignals.runtimeError:!0}},outputs:[{kind:"framework-error",error:Q.error}]};case"dispose":{if(G.phase==="disposed")return{state:G,outputs:[]};let Y=[];if(G.phase!=="idle")w1(Y,"disposed",G.cohort);return{state:{...G,phase:"disposed"},outputs:Y}}default:{let Y=Q;return{state:G,outputs:[]}}}}class x8{state=f7();listeners=new Set;getState(){return this.state}dispatch(G){let Q=d7(this.state,G);if(this.state=Q.state,Q.outputs.length>0)this.fanOut(Q.outputs);return Q.outputs}subscribe(G){this.listeners.add(G);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(G)}}disposeListeners(){this.listeners.clear()}fanOut(G){let Q=Array.from(this.listeners),Y=Object.freeze(G.slice());for(let J of Q)try{J(Y)}catch(X){console.warn("[SectionEngineCore] listener failed:",X)}}}function Y3(G){let{coordinator:Q,dispatchCoreInput:Y}=G,J=0,X=null,j=null,Z=!1,q=Q.subscribeFrameworkErrors(($)=>{try{Y({kind:"framework-error",error:$})}catch(H){console.warn("[CoordinatorBridge] framework-error dispatch failed:",H)}});function B(){if(!j)return;try{j()}catch($){console.warn("[CoordinatorBridge] controller unsubscribe failed:",$)}j=null}async function K($){if(Z)return;J+=1;let H=J;X=$.cohort;let N=await Q.getOrCreateSectionController({sectionId:$.cohort.sectionId,attemptId:$.cohort.attemptId||void 0,input:{section:$.section,sectionId:$.cohort.sectionId,assessmentId:$.assessmentId,view:$.view},updateExisting:!0,createDefaultController:$.createDefaultController});if(H!==J||Z)return;B(),$.onControllerResolved?.(N);let F=N.getCompositionModel;if($.onCompositionChanged?.(F?.()),typeof N.subscribe==="function")j=N.subscribe((O)=>{if(H!==J||Z)return;$.onCompositionChanged?.(F?.())});Y({kind:"section-controller-resolved"})}async function W(){if(Z)return;Z=!0,J+=1,B();try{q()}catch(H){console.warn("[CoordinatorBridge] framework-error unsubscribe failed:",H)}let $=X;if(X=null,$)try{await Q.disposeSectionController({sectionId:$.sectionId,attemptId:$.attemptId||void 0})}catch(H){console.warn("[CoordinatorBridge] section-controller dispose failed:",H)}}return{resolveSectionController:K,dispose:W}}function J3(G){let{runtimeId:Q,sourceCe:Y}=G,J=G.host,X=G.now??(()=>new Date().toISOString());function j(W){let $={stage:W.stage,status:W.status,runtimeId:Q,sectionId:W.cohort?.sectionId,attemptId:W.cohort?.attemptId?W.cohort.attemptId:void 0,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-stage-change",{detail:$}))}function Z(W){let $={runtimeId:Q,sectionId:W.cohort.sectionId,attemptId:W.cohort.attemptId?W.cohort.attemptId:void 0,itemCount:W.itemCount,loadedCount:W.loadedCount,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-loading-complete",{detail:$}))}function q(W){J.dispatchEvent(new CustomEvent("framework-error",{detail:W.error}))}function B(W){switch(W.kind){case"stage-change":j(W);return;case"loading-complete":Z(W);return;case"framework-error":q(W);return;default:{let $=W;return}}}function K(W){J=W}return{dispatch:B,setHost:K}}function X3(G){let{bus:Q}=G;function Y(J){switch(J.kind){case"framework-error":Q.reportFrameworkError(J.error);return;case"stage-change":case"loading-complete":return;default:{let X=J;return}}}return{dispatch:Y}}function Z3(G={}){let Q=G.hook;function Y(X){if(!Q)return;try{Q(X)}catch(j){console.warn("[InstrumentationBridge] hook failed:",j)}}function J(X){Q=X}return{dispatch:Y,setHook:J}}function j3(){let G=new Set;function Q(j){if(j.length===0)return;let Z=Array.from(G),q=Object.freeze(j.slice());for(let B of Z)try{B(q)}catch(K){console.warn("[SubscriberFanout] listener failed:",K)}}function Y(j){G.add(j);let Z=!0;return()=>{if(!Z)return;Z=!1,G.delete(j)}}function J(){G.clear()}function X(){return G.size}return{emit:Q,subscribe:Y,dispose:J,getListenerCount:X}}class f8{core;domEventBridge;frameworkErrorBridge;instrumentationBridge;subscriberFanout;coordinatorBridge;unsubscribeCore;disposed=!1;constructor(G){this.core=G.core??new x8,this.domEventBridge=J3({host:G.host,runtimeId:G.runtimeId,sourceCe:G.sourceCe,now:G.now}),this.frameworkErrorBridge=X3({bus:G.frameworkErrorBus}),this.instrumentationBridge=Z3({hook:G.instrumentationHook}),this.subscriberFanout=j3(),this.coordinatorBridge=G.coordinator?Y3({coordinator:G.coordinator,dispatchCoreInput:(Q)=>this.dispatchInput(Q)}):null,this.unsubscribeCore=this.core.subscribe((Q)=>{this.routeOutputs(Q)})}getState(){return this.core.getState()}dispatchInput(G){if(this.disposed)return[];return this.core.dispatch(G)}subscribe(G){return this.subscriberFanout.subscribe(G)}setHost(G){this.domEventBridge.setHost(G)}setInstrumentationHook(G){this.instrumentationBridge.setHook(G)}resolveSectionController(G){if(!this.coordinatorBridge)throw Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");return this.coordinatorBridge.resolveSectionController(G)}async dispose(){if(this.disposed)return;if(this.disposed=!0,this.core.dispatch({kind:"dispose"}),this.unsubscribeCore(),this.subscriberFanout.dispose(),this.coordinatorBridge)await this.coordinatorBridge.dispose()}routeOutputs(G){for(let Q of G)this.routeOne(Q);this.subscriberFanout.emit(G)}routeOne(G){switch(G.kind){case"stage-change":case"loading-complete":this.domEventBridge.dispatch(G);break;case"framework-error":this.domEventBridge.dispatch(G),this.frameworkErrorBridge.dispatch(G);break;default:{let Q=G;return}}this.instrumentationBridge.dispatch(G)}}var TQ={mode:"gather",role:"student"};function R1(G,Q){return G!==void 0?G:Q}function CQ(G){let Q=G.runtime??{};if(Q.onFrameworkError!==void 0)return Q.onFrameworkError;return G.onFrameworkError}function yQ(G){let Q=G.runtime?.tools||{},Y=Q.placement||{};return{...Q,placement:{...Y}}}function xQ(G){let Q=G.runtime||{},Y=Q.player?{...Q.player}:null;return{...Q,assessmentId:R1(Q.assessmentId,G.assessmentId),playerType:Q.playerType??"iife",player:Y,lazyInit:Q.lazyInit??!0,accessibility:Q.accessibility??null,coordinator:Q.coordinator??null,createSectionController:Q.createSectionController,isolation:Q.isolation??"inherit",env:Q.env??TQ,toolConfigStrictness:R1(Q.toolConfigStrictness,G.toolConfigStrictness)??"error",onFrameworkError:CQ({runtime:G.runtime,onFrameworkError:G.onFrameworkError}),onStageChange:R1(Q.onStageChange,G.onStageChange),onLoadingComplete:R1(Q.onLoadingComplete,G.onLoadingComplete),tools:G.effectiveToolsConfig}}function q3(G,Q){let Y=G.assessmentId??"section-demo-direct",J=yQ({runtime:G.runtime}),X=xQ({assessmentId:Y,runtime:G.runtime,effectiveToolsConfig:J,toolConfigStrictness:G.toolConfigStrictness,onFrameworkError:G.onFrameworkError,onStageChange:G.onStageChange,onLoadingComplete:G.onLoadingComplete}),j=Q.resolvePlayerRuntime({effectiveRuntime:X,playerType:String(X.playerType??"iife"),env:X.env??null});return{effectiveToolsConfig:J,effectiveRuntime:X,playerRuntime:j}}import{createPieLogger as kQ,isGlobalDebugEnabled as IQ}from"@pie-players/pie-players-shared";function fQ(G,Q){if(G===Q)return 0;let Y=G.compareDocumentPosition(Q);if(Y&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(Y&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class k8{shellsByElement=new Map;register(G){let Q=this.shellsByElement.get(G.element),Y={...G,sortKey:Date.now()};if(Q&&Q.kind===Y.kind&&Q.itemId===Y.itemId&&Q.canonicalItemId===Y.canonicalItemId)return!1;return this.shellsByElement.set(G.element,Y),!0}unregister(G){return this.shellsByElement.delete(G)}getOrderedShells(G){let Q=Array.from(this.shellsByElement.values()).filter((Y)=>!G||Y.kind===G);return Q.sort((Y,J)=>fQ(Y.element,J.element)),Q}getCanonicalIdMap(){let G={};for(let Q of this.getOrderedShells("item")){if(!Q.itemId)continue;G[Q.itemId]=Q.canonicalItemId||Q.itemId}return G}clear(){this.shellsByElement.clear()}}function E1(G="runtime"){return`${G}-${Math.random().toString(16).slice(2)}-${Date.now()}`}var vQ=kQ("section-runtime-engine",()=>IQ());class I8{registry=new k8;runtimeId=E1("section-engine");adapter=null;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;loadedRenderableKeys=new Set;attachHost(G){if(this.adapter){if(this.adapter.setHost(G.host),G.instrumentationHook!==void 0)this.adapter.setInstrumentationHook(G.instrumentationHook);return}this.adapter=new f8({host:G.host,runtimeId:this.runtimeId,sourceCe:G.sourceCe,frameworkErrorBus:G.frameworkErrorBus,coordinator:G.coordinator,instrumentationHook:G.instrumentationHook,now:G.now})}dispatchInput(G){return this.adapter?.dispatchInput(G)??[]}subscribe(G){return this.adapter?.subscribe(G)??hQ}getState(){return this.adapter?.getState()??f7()}getEffectiveRuntime(G,Q){return q3(G,Q).effectiveRuntime}setInstrumentationHook(G){this.adapter?.setInstrumentationHook(G)}getRuntimeId(){return this.runtimeId}async initialize(G){this.activeInitToken+=1;let Q=this.activeInitToken;this.coordinator=G.coordinator,this.sectionId=G.sectionId,this.attemptId=G.attemptId;let Y=await G.coordinator.getOrCreateSectionController({sectionId:G.sectionId,attemptId:G.attemptId,input:{section:G.section,sectionId:G.sectionId,assessmentId:G.assessmentId,view:G.view},updateExisting:!0,createDefaultController:G.createDefaultController});if(Q!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=Y,this.replayRegisteredShellsIntoController(Y),G.onCompositionChanged?.(Y.getCompositionModel?.()),this.unsubscribeController=Y.subscribe?.((J)=>{try{G.onControllerEvent?.(J)}catch(X){vQ.warn("onControllerEvent handler threw",X)}G.onCompositionChanged?.(Y.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(G){if(!G.handleContentRegistered)return;let Q=this.registry.getOrderedShells();if(Q.length===0)return;for(let J of Q){let X=J.canonicalItemId||J.itemId;G.handleContentRegistered({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind})}let Y=Date.now();for(let J of Q){let X=J.canonicalItemId||J.itemId,j=this.getLoadedKey(X,J.contentKind);if(this.loadedRenderableKeys.has(j))G.handleContentLoaded?.({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind,timestamp:Y})}}getLoadedKey(G,Q){return`${Q??""}:${G}`}register(G){return this.registry.register(G)}unregister(G){return this.registry.unregister(G)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(G){return this.registry.getCanonicalIdMap()[G]||this.controller?.getCanonicalItemId?.(G)||G}handleContentRegistered(G){this.controller?.handleContentRegistered?.({itemId:G.itemId,canonicalItemId:G.canonicalItemId||G.itemId,contentKind:G.contentKind||G.kind})}handleContentUnregistered(G){let Q=G.canonicalItemId||G.itemId;this.loadedRenderableKeys.delete(this.getLoadedKey(Q,G.contentKind)),this.controller?.handleContentUnregistered?.({itemId:G.itemId,canonicalItemId:Q,contentKind:G.contentKind||G.kind})}handleContentLoaded(G){let Q=G.canonicalItemId||G.itemId;this.loadedRenderableKeys.add(this.getLoadedKey(Q,G.contentKind)),this.controller?.handleContentLoaded?.(G)}handleItemPlayerError(G){this.controller?.handleItemPlayerError?.(G)}reportSectionError(G){this.controller?.reportSectionError?.(G)}updateItemSession(G,Q){let Y=this.getCanonicalItemId(G);return this.controller?.updateItemSession?.(Y,Q)??null}navigateToItem(G){return this.controller?.navigateToItem?.(G)??null}handleFormativeAction(G){if(!G?.itemId)return;let Q=this.getCanonicalItemId(G.itemId);if(G.action==="retry"){this.controller?.retryFormativeItem?.({itemId:Q});return}this.controller?.recordFormativeTry?.({itemId:Q,outcomes:G.outcomes})}handleMediaTimeSource(G){if(G?.action==="detach"){this.controller?.detachMediaTimeSource?.({origin:G.origin??"host"});return}if(!G?.source)return;this.controller?.attachMediaTimeSource?.(G.source,{origin:G.origin??"host",renderableId:G.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}getRegistry(){return this.registry}async dispose(){if(this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null,this.coordinator&&this.sectionId)await this.coordinator.disposeSectionController({sectionId:this.sectionId,attemptId:this.attemptId});if(this.registry.clear(),this.loadedRenderableKeys.clear(),this.controller=null,this.coordinator=null,this.adapter){let G=this.adapter;this.adapter=null,await G.dispose()}}}var hQ=()=>{};import{ContextConsumer as mQ,createContext as uQ}from"@pie-players/pie-context";var U3=uQ(Symbol.for("pie.sectionRuntimeEngineHostContext"));function B3(G,Q){let Y=!1,J=new mQ(G,{context:U3,subscribe:!0,onValue:(B)=>{Y=!0,Q(B)}});J.connect();let X=(B)=>{if(B.context!==U3)return;J.requestValue()};G.addEventListener("context-provider",X);let j=0,Z=200,q=globalThis.setInterval(()=>{if(Y||j>=Z){globalThis.clearInterval(q);return}j+=1,J.requestValue()},50);return()=>{globalThis.clearInterval(q),G.removeEventListener("context-provider",X),J.disconnect()}}var pQ=(G)=>{console.error("[pie-assessment-toolkit] onStageChange handler threw",G)};function W3(G,Q){if(G.isSuppressed())return!1;G.dispatchDomEvent(Q);let Y=G.getOnStageChange();if(Y)try{Y(Q)}catch(J){(G.logHandlerError??pQ)(J)}return!0}function i7(G,Q){if(typeof G==="function")return G;if(G===null)return null;return typeof Q==="function"?Q:null}function K3(G={}){let Q=G.frameDeadlineMs??100,Y=!1,J=null,X=null,j=null,Z=null,q=null;function B(){if(Y=!1,X!==null)Z?.(X),X=null;if(j!==null)q?.(j),j=null;Z=null,q=null}function K(H){if(!Y)return;if(H==="frame")X=null;if(H==="timer")j=null;let N=J;J=null,B(),N?.()}function W(H){if(J=H,Y)return;Y=!0;let N=globalThis,F=i7(G.requestFrame,N.requestAnimationFrame);Z=i7(G.cancelFrame,N.cancelAnimationFrame);let O=i7(G.setTimer,N.setTimeout);if(q=i7(G.clearTimer,N.clearTimeout),F){let D=F(()=>K("frame"));if(!Y)return;if(X=D,O){let P=O(()=>K("timer"),Q);if(Y)j=P}return}let L=i7(G.queueMicrotaskFn,N.queueMicrotask);if(L){L(()=>K("microtask"));return}if(O){let D=O(()=>K("timer"),0);if(Y)j=D;return}K("microtask")}function $(){if(!Y)return;J=null,B()}return{schedule:W,cancel:$,isPending:()=>Y}}function _3(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function V3(G){G.lastSessionEventSignatureByItemId.clear(),G.lastMetadataSignatureByItemId.clear()}function $3(G){let{state:Q,itemId:Y,payload:J}=G;if(cQ(J)){let Z=lQ(J);if(Q.lastMetadataSignatureByItemId.get(Y)===Z)return!1;Q.lastMetadataSignatureByItemId.set(Y,Z)}let X=gQ(J);if(Q.lastSessionEventSignatureByItemId.get(Y)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(Y,X),!0}function gQ(G){let Q={...G};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function cQ(G){return G.intent==="metadata-only"}function lQ(G){try{return JSON.stringify({itemId:G.itemId,canonicalItemId:G.canonicalItemId,intent:G.intent,complete:G.complete??null,component:G.component??null})}catch{return String(G.itemId||"")}}var dQ=(G,Q)=>{if(customElements.get(G))return;try{customElements.define(G,Q)}catch(Y){if(!(Y instanceof DOMException&&Y.name==="NotSupportedError"||Y&&typeof Y==="object"&&Y.name==="NotSupportedError")||!customElements.get(G))throw Y}},Q9=u8('<div class="pie-assessment-toolkit-error svelte-vpe4u2" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-vpe4u2"> </div> <div class="pie-assessment-toolkit-error-message svelte-vpe4u2"> </div> <pre class="pie-assessment-toolkit-error-details svelte-vpe4u2"> </pre></div>'),Y9=u8('<div class="pie-assessment-toolkit-anchor svelte-vpe4u2" aria-hidden="true"></div> <!>',1),J9={hash:"svelte-vpe4u2",code:`.pie-assessment-toolkit-anchor.svelte-vpe4u2 {display:none;}.pie-assessment-toolkit-error.svelte-vpe4u2 {margin:0.75rem;padding:0.75rem 1rem;border-radius:0.5rem;border:1px solid
224
- color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 40%, transparent);background:color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 12%, transparent);color:var(--pie-incorrect, #7f1d1d);font-size:0.9rem;}.pie-assessment-toolkit-error-title.svelte-vpe4u2 {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-vpe4u2 {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-vpe4u2 {margin:0;white-space:pre-wrap;word-break:break-word;}`};function C3(G,Q){N3(Q,!0),w3(G,J9);let Y=E1("toolkit"),J=new I8,X=h(null),j=new p7,Z={mode:"gather",role:"student"},q={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},B=x(Q,"assessmentId",7,""),K=x(Q,"section",7,null),W=x(Q,"sectionId",7,""),$=x(Q,"attemptId",7,""),H=x(Q,"env",23,()=>({})),N=x(Q,"ndsIcons",7,!1),F=x(Q,"locale",7,""),O=x(Q,"lazyInit",7,!0),L=x(Q,"toolConfigStrictness",7,"error"),D=x(Q,"tools",23,()=>({})),P=x(Q,"toolContextResolvers",7,null),S=x(Q,"enabledTools",7,""),v=x(Q,"toolRegistry",7,null),I=x(Q,"accessibility",23,()=>({})),p=x(Q,"player",7,null),E=x(Q,"playerType",7,""),g=x(Q,"coordinator",7,null),q7=x(Q,"createSectionController",7,null),U7=x(Q,"onFrameworkError",7,null),B7=x(Q,"errorRenderer",7,null),w7=x(Q,"onStageChange",7,null),s7=x(Q,"assessment",7,null),n7=x(Q,"currentItemRef",7,null),r7=x(Q,"pnpEnforcement",7,null),W7=x(Q,"isolation",7,"inherit"),k7=h(null),i=h(null),J7=h(null),p8=null,I7=null,v7=null,o7=null,h7=null,a7=null,t7=h(0),y1=h(null),m7=h(null),o=h(null),x1=h("Unable to initialize assessment toolkit."),f1=h(v8([])),g8="",k1="",c8=h(""),l8=null,d8=K3(),K7=[],e7=new Map,I1=new WeakMap,i8=_3(),s=nQ({sourceCe:"pie-assessment-toolkit",sourceCeShape:"toolkit",runtimeId:Y,sectionId:m(()=>W()||void 0),attemptId:m(()=>$()||void 0),emit:(U)=>{W3({isSuppressed:()=>V(X)!==null,dispatchDomEvent:(_)=>_7("pie-stage-change",_),getOnStageChange:()=>w7()},U)}}),s8=h(v8(m(()=>`${W()}|${$()}`))),G1=h(!1),t=h(!1),v1=h(!1),h1=h(!1);function y3(){if(!V(k7))return null;let U=V(k7).getRootNode();if(U&&"host"in U)return U.host;return V(k7).parentElement}let f=r(()=>y3());function _7(U,_){if(!V(f)){K7=[...K7,{name:U,detail:_}];return}C8(V(f),U,_)}b(()=>{if(!V(f))return;if(K7.length===0)return;let U=K7;K7=[],queueMicrotask(()=>{let _=V(f);if(!_){K7=[...U,...K7];return}for(let M of U)C8(_,M.name,M.detail)})});function x3(U){if(!B7())return{title:"Unable to initialize assessment toolkit.",details:U.details.length>0?U.details:[U.message]};try{let _=B7()(U)||{};return{title:typeof _.title==="string"&&_.title.trim().length>0?_.title:"Unable to initialize assessment toolkit.",details:Array.isArray(_.details)&&_.details.length>0?_.details.map((M)=>String(M)):U.details.length>0?U.details:[U.message]}}catch(_){let M=_ instanceof Error&&_.message.trim().length>0?_.message:String(_||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...U.details,`Error renderer failed: ${M}`]}}}function R7(U){let _=j1({kind:U.kind,source:U.source,error:U.error,recoverable:U.recoverable});return j.reportFrameworkError(_),_}function f3(U){if(U?.type==="timed-media-policy-degraded"){let M=U.degradations||[];j.reportFrameworkError(Z1({kind:"timed-media",severity:"warning",source:"pie-assessment-toolkit",message:"A timed-media playback policy degraded to advisory: the media time source does not report the capability it needs.",details:M.map((z)=>z?.message).filter((z)=>typeof z==="string"),recoverable:!0}));return}if(U?.type!=="timed-media-invalid")return;let _=U.errors||[];j.reportFrameworkError(Z1({kind:"timed-media",severity:"error",source:"pie-assessment-toolkit",message:'This section declares sectionType: "timed-media" but its timedMedia data is not deliverable; the section renders without cue behavior.',details:_.map((M)=>M?.message).filter((M)=>typeof M==="string"),recoverable:!1}))}function k3(U){if(U?.type!=="timed-media-audio-started")return;if(!V(C))return;d0(V(C).getServiceBundle().ttsService)}function I3(U){return U==="coordinator-init"||U==="runtime-init"||U==="tool-config"}function n8(U){if(!U7())return;try{U7()(U),g8=`${U.kind}|${U.source}|${U.message}`}catch(_){console.error(`[pie-framework:${U.kind}:${U.source}] framework error hook failed`,_)}}b(()=>{let U=j.subscribeFrameworkErrors((_)=>{if(console.error(Z6(_),_.cause),I3(_.kind)){let M=x3(_);w(o,_,!0),w(x1,M.title,!0),w(f1,M.details,!0)}_7("framework-error",_),n8(_)});return()=>{U()}}),b(()=>{if(!V(o))return;let U=`${V(o).kind}|${V(o).source}|${V(o).message}`;if(g8===U)return;n8(V(o))});function v3(U){let _=5381;for(let M=0;M<U.length;M+=1)_=(_<<5)+_^U.charCodeAt(M);return(_>>>0).toString(36)}function n(U){return U&&typeof U==="object"?U:{}}function h3(U){let _=n(U.section),M=typeof _.identifier==="string"?_.identifier:"",z=typeof U.sectionId==="string"?U.sectionId:"";return M||z}function m3(U){return typeof U.currentItemIndex==="number"?U.currentItemIndex:-1}function u3(U){return(Array.isArray(U.renderables)?U.renderables:[]).map((M,z)=>{let A=n(M),k=n(A.entity),G7=typeof k.id==="string"&&k.id||`renderable-${z}`,X1=n(k.config),d1=typeof k.version==="string"&&k.version||(typeof k.version==="number"?String(k.version):"")||(typeof X1.version==="string"?X1.version:"");return{id:G7,version:d1}})}function p3(U){let _=n(U.itemSessionsByItemId);return Object.keys(_).sort((M,z)=>M.localeCompare(z)).map((M)=>{let z=n(_[M]),A=typeof z.id==="string"?z.id:"",k=Array.isArray(z.data)?z.data:[],G7="";try{G7=v3(JSON.stringify(k))}catch{G7=String(k.length)}return{itemId:M,sessionId:A,payloadSignature:G7}})}function g3(U){let _=n(n(U.formative).states);return Object.entries(_).map(([M,z])=>{let A=n(z),k=n(A.lastOutcome).correctness??"";return`${M}:${A.tryCount??0}:${A.revealed===!0?1:0}:${String(k)}:${String(A.revealOverride??"")}`}).sort().join("|")}function c3(U){let _=U.timedMedia;return G9(_)}function l3(U){let _=n(U),M=u3(_).map((A)=>`${A.id}:${A.version}`).join("|"),z=p3(_).map((A)=>`${A.itemId}:${A.sessionId}:${A.payloadSignature}`).join("|");return{sectionId:h3(_),currentItemIndex:m3(_),renderableSignature:M,itemSessionSignature:z,formativeSignature:g3(_),timedMediaSignature:c3(_)}}function d3(U){let _=l3(U);return`${_.sectionId}|${_.currentItemIndex}|${_.renderableSignature}|${_.itemSessionSignature}|${_.formativeSignature}|${_.timedMediaSignature}`}function r8(U){return U==="iife"||U==="esm"||U==="preloaded"||U==="custom"}function i3(U,_){let M=U?.type,z=r8(M)?M:r8(_)?_:U?.tagName?"custom":"iife",A=U?.tagName?.trim();if(z==="custom"&&!A)return{type:"iife",tagName:q.iife,version:void 0,source:void 0,isDefault:!0};return{type:z,tagName:A||q[z],version:U?.version,source:U?.source,loaderConfig:U?.loaderConfig,loaderOptions:U?.loaderOptions,isDefault:!U&&!_}}function o8(U){let _=U||{},M=typeof _.mode==="string"&&_.mode.trim()?_.mode.trim():Z.mode,z=typeof _.role==="string"&&_.role.trim()?_.role.trim():Z.role;return{mode:M,role:z}}function s3(U){let _=o8(U);if(_.mode==="author")return"author";if(_.role==="instructor")return"scorer";return"candidate"}async function n3(){if(q7())return q7()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function a8(){let U=D()||{},_=T3(S());if(_.length===0)return U;let M=U.placement||{},z=Array.isArray(M.section)?M.section:null;if(z&&z.length>0)return U;return{...U,placement:{...M,section:_}}}function r3(){return Z7(a8(),{strictness:L(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:v()}).config}function o3(){let U="",_="";try{U=JSON.stringify(a8())}catch{U="[unserializable-tools]"}try{_=JSON.stringify(Object.entries(P()??{}).map(([M,z])=>[M,typeof z]))}catch{_="[unserializable-resolvers]"}return[B()||"",String(L()||"error"),U,_].join("|")}function t8(U){return U==="on"||U==="off"?U:null}function a3(U,_){let M=t8(U);if(M)return M;if(_&&typeof _==="object"){let A=_.pnpEnforcement;return t8(typeof A==="string"?A:null)}return null}function t3(U){let _=B()||K()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new L1({assessmentId:_,lazyInit:O(),toolConfigStrictness:L(),deferToolConfigValidation:!0,tools:U,toolRegistry:v(),toolContextResolvers:P(),accessibility:I(),frameworkErrorBus:j})}function m1(){let U=V(i);if(!U)return Promise.resolve();return w(i,null),U.dispose()}function u1(U){w(m7,U,!0),R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:U,recoverable:!0,details:{owner:"toolkit-coordinator"}})}let C=r(()=>{if(W7()!=="force"&&V(J7)?.coordinator)return V(J7).coordinator;return g()||V(i)});b(()=>{V(f),g(),W7(),V(J7),P(),m(()=>{if(!V(f))return;if(g()){if(V(i))m1().catch(u1);I7=null;return}if(W7()!=="force"&&V(J7)?.coordinator){if(V(i))m1().catch(u1);I7=null;return}if(V(i)&&I7!==P()){try{V(i).setToolContextResolvers(P()),I7=P()}catch(U){w(m7,U,!0),R7({kind:"coordinator-init",phase:"coordinator-ready",error:U})}return}if(!V(i)){let U=o3();if(k1===U)return;try{let _=r3();w(i,t3(_),!0),I7=P(),k1="",w(o,null),w(x1,"Unable to initialize assessment toolkit."),w(f1,[],!0)}catch(_){w(m7,_,!0),w(i,null),k1=U,R7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:_})}}})});let Q1=tQ(),p1=h(0);b(()=>Q1.subscribe(()=>{w(p1,V(p1)+1)})),b(()=>{let U=typeof F()==="string"?F().trim():"";m(()=>{Promise.resolve(Q1.setLocale(U||eQ)).catch((_)=>{R7({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:_ instanceof Error?_:Error(String(_))})})})});let X7=r(()=>B()||V(C)?.assessmentId||""),e=r(()=>W()||K()?.identifier||`section-${V(X7)||"default"}`),g1=r(()=>o8(H())),e3=r(()=>s3(V(g1))),E7=r(()=>i3(p(),E())),u7=r(()=>rQ({player:V(E7),component:"pie-assessment-toolkit"})),Y1=r(()=>{if(!V(C))return null;let U=V(C).getServiceBundle();return{toolkitCoordinator:V(C),toolCoordinator:V(C).toolCoordinator,ttsService:U.ttsService,highlightCoordinator:U.highlightCoordinator,catalogResolver:U.catalogResolver,elementToolStateStore:U.elementToolStateStore,assessmentId:V(X7),sectionId:V(e),itemPlayer:V(E7),ndsIcons:N()===!0,locale:(V(p1),Q1.getLocale()),i18n:Q1,reportSessionChanged:(_,M)=>{let z=J.updateItemSession(_,M);Q6({itemId:_,result:z,fallbackSession:M})}}}),J1=r(()=>{if(!V(C))return null;return{runtimeId:Y,coordinator:V(C)}});function G5(U){let _=d3(U);if(_===V(c8))return;w(c8,_,!0),w(t7,V(t7)+1),w(y1,U,!0),_7("composition-changed",{composition:V(y1),version:V(t7)})}function c1(U){l8=U??J.getCompositionModel(),d8.schedule(()=>{G5(l8)})}function l1(U){if(!U)return;let _=I1.get(U);if(!_)return;for(let M of _)M();I1.delete(U)}function e8(){for(let U of e7.values())l1(U.element)}function G6(U){if(l1(U.element),!V(C))return;let _=V(C).getServiceBundle().catalogResolver;I1.set(U.element,[_.registerOwner({owner:{kind:U.kind,itemId:U.itemId,canonicalItemId:U.canonicalItemId,assessmentId:V(X7),sectionId:V(e)},entity:U.item})])}function Q5(){e8();for(let U of e7.values())G6(U)}function Q6(U){let M={...U.result?.eventDetail||U.fallbackSession,itemId:U.itemId,canonicalItemId:U.canonicalItemId||U.itemId,sourceRuntimeId:Y};if(!$3({state:i8,itemId:U.itemId,payload:M}))return;_7("session-changed",M)}function Y5(U){if(!(U instanceof HTMLElement))return!1;return iQ(U,m8)?.runtimeId===Y}function V7(U){return U.detail??null}function J5(U,_){for(let M of _)U.addEventListener(M.name,M.handler);return()=>{for(let M of _)U.removeEventListener(M.name,M.handler)}}b(()=>{if(!V(f))return;if(W7()==="force"){w(J7,null);return}return S3(V(f),(U)=>{if(U.runtimeId===Y)return;w(J7,U,!0)})}),b(()=>{let U=V(f);return m(()=>{if(!U){w(X,null);return}let _=B3(U,(M)=>{if(M.engine===V(X))return;w(X,M.engine,!0)});return()=>{_(),w(X,null)}})}),b(()=>{let U=V(C);if(!U)return;return m(()=>l0({ttsService:U.getServiceBundle().ttsService,listenerId:`timed-media-audio-handoff:${Y}`,silence:()=>J.requestMediaPauseForCompetingAudio()}))}),b(()=>{let U=W7()!=="force"&&V(J7)?V(J7).runtimeId:null,_=U?"inherited":"owned";if(_!==p8)p8=_,_7(_==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:U})}),b(()=>{let U=V(e),_=$()||"";V3(i8)}),b(()=>{if(!V(f)||!V(J1))return;return h7=new H3(V(f),{context:m8,initialValue:V(J1)}),h7.connect(),a7=new D3(V(f)),a7.attach(),()=>{a7?.detach(),a7=null,h7?.disconnect(),h7=null}}),b(()=>{if(!V(J1))return;h7?.setValue(V(J1))}),b(()=>{if(!V(f))return;V(f).setAttribute("data-item-player-type",V(E7).type),V(f).setAttribute("data-item-player-tag",V(E7).tagName),V(f).setAttribute("data-env-mode",String(V(g1)?.mode||"")),V(f).setAttribute("data-env-role",String(V(g1)?.role||""))}),b(()=>{if(!V(f)||!V(Y1))return;return v7=new H3(V(f),{context:b3,initialValue:V(Y1)}),v7.connect(),o7=new D3(V(f)),o7.attach(),()=>{o7?.detach(),o7=null,v7?.disconnect(),v7=null}}),b(()=>{if(V(Y1))v7?.setValue(V(Y1))}),b(()=>{return V(C),V(X7),V(e),Q5(),()=>{e8()}}),b(()=>{if(!V(f))return;return sQ({host:V(f),instrumentationProvider:V(u7),component:"pie-assessment-toolkit",eventMap:oQ,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:V(X7),sectionId:V(e),attemptId:$()||void 0}})}),b(()=>{s7(),n7(),r7(),D();let U=V(C);if(!U)return;if(U!==V(i))return;m(()=>{U.setPnpEnforcement(a3(r7(),D())),U.updateAssessment(s7()),U.updateCurrentItemRef(n7())})}),b(()=>{if(!V(C))return;return V(C).subscribeTelemetry(({eventName:U,payload:_})=>{if(!aQ(V(u7)))return;if(!V(u7).isReady())return;let M=U,z=new Date().toISOString(),A={..._||{},instrumentationLayer:"toolkit",assessmentId:V(X7),sectionId:V(e),attemptId:$()||void 0,component:"pie-assessment-toolkit",sourceEventName:U,timestamp:z};V(u7).trackEvent(M,A);let k=_&&typeof _.errorType==="string"?_.errorType:void 0;if(!U.endsWith("-error")&&!k)return;let G7=_&&typeof _.message==="string"?_.message:`Toolkit telemetry error: ${U}`;V(u7).trackError(Error(G7),{component:"pie-assessment-toolkit",errorType:k||"ToolkitTelemetryError",...A})})}),b(()=>{if(!K()||!V(C))return;let U=!1;return J.initialize({coordinator:V(C),section:K(),sectionId:V(e),assessmentId:V(X7),attemptId:$()||void 0,view:V(e3),createDefaultController:n3,onCompositionChanged:(_)=>{if(U)return;c1(_)},onControllerEvent:(_)=>{if(U)return;k3(_),f3(_)}}).then(()=>{if(U)return;_7("toolkit-ready",{runtimeId:Y,assessmentId:V(X7),sectionId:V(e),itemPlayer:V(E7),coordinator:V(C)}),_7("section-ready",{sectionId:V(e)}),m(()=>{w(h1,!0)})}).catch((_)=>{if(U)return;m(()=>{if(!V(t))w(t,!0),s.enter("engine-ready","skipped");s.enter("interactive","failed")}),w(m7,_,!0),J.reportSectionError({source:"section-runtime",error:_,timestamp:Date.now()}),R7({kind:"runtime-init",source:"pie-assessment-toolkit",error:_})}),()=>{U=!0}}),b(()=>{if(!V(f))return;let U=V(f),_=(z)=>Y5(z.target);return J5(U,[{name:i0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.element||!A?.itemId)return;let k=J.register(A);if(e7.set(A.element,A),G6(A),J.handleContentRegistered(A),k)c1()}},{name:s0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;let k=A?.element?J.unregister(A.element):!1;if(l1(A.element),A.element)e7.delete(A.element);if(J.handleContentUnregistered(A),k)c1()}},{name:n0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;let k=J.updateItemSession(A.itemId,A.session);Q6({itemId:A.itemId,canonicalItemId:J.getCanonicalItemId(A.itemId),result:k,fallbackSession:A.session})}},{name:r0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;J.handleContentLoaded({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,detail:A.detail,timestamp:Date.now()})}},{name:o0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;J.handleItemPlayerError({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,error:A.error,timestamp:Date.now()})}},{name:a0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;if(A.action!=="check"&&A.action!=="retry")return;J.handleFormativeAction({itemId:A.canonicalItemId||A.itemId,action:A.action,outcomes:A.outcomes})}},{name:t0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.renderableId)return;if(A.action!=="attach"&&A.action!=="detach")return;J.handleMediaTimeSource({renderableId:A.renderableId,action:A.action,source:A.source,origin:A.origin})}}])});async function X5(){if(!V(C))throw Error("Coordinator not initialized");await V(C).waitUntilReady()}function Z5(){if(!V(C))throw Error("Coordinator not initialized");return V(C).getServiceBundle()}function j5(U){if(!V(C))throw Error("Coordinator not initialized");V(C).setHooks(U)}function q5(U){return J.navigateToItem(U)}function U5(){return J.getCompositionModel()}function B5(){return V(E7)}async function W5(){await J.persist()}async function K5(){await J.hydrate()}b(()=>{return()=>{m(()=>{if(s.getCurrent()!==null)s.enter("disposed")})}}),b(()=>{let U=`${W()}|${$()}`;m(()=>{if(U===V(s8))return;if(s.getCurrent()!==null)s.enter("disposed");s.reset({sectionId:W()||void 0,attemptId:$()||void 0}),w(s8,U),w(G1,!1),w(t,!1),w(v1,!1),w(h1,!1)})}),b(()=>{let U=V(t)&&V(h1);m(()=>{if(!U)return;if(V(v1))return;w(v1,!0),s.enter("interactive")})}),b(()=>{let U=V(t7)>0||V(y1)!==null;m(()=>{if(!V(G1)&&U)w(G1,!0),s.enter("composed")})}),b(()=>{if(!V(C))return;if(!V(G1))return;if(V(t))return;let U=V(C),_=!1;return U.waitUntilReady().then(()=>{if(_)return;m(()=>{if(V(t))return;w(t,!0),s.enter("engine-ready")})}).catch(()=>{if(_)return;m(()=>{if(V(t))return;w(t,!0),s.enter("engine-ready","failed")})}),()=>{_=!0}}),b(()=>{return()=>{d8.cancel(),J.dispose().catch((U)=>{w(m7,U,!0),R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:U,recoverable:!0})}).then(()=>m1()).catch(u1).finally(()=>{j.dispose()})}});var _5={waitUntilReady:X5,getServiceBundle:Z5,setHooks:j5,navigateToItem:q5,getCompositionModel:U5,getItemPlayerConfig:B5,persist:W5,hydrate:K5,get assessmentId(){return B()},set assessmentId(U){B(U),y()},get section(){return K()},set section(U){K(U),y()},get sectionId(){return W()},set sectionId(U){W(U),y()},get attemptId(){return $()},set attemptId(U){$(U),y()},get env(){return H()},set env(U){H(U),y()},get ndsIcons(){return N()},set ndsIcons(U){N(U),y()},get locale(){return F()},set locale(U){F(U),y()},get lazyInit(){return O()},set lazyInit(U){O(U),y()},get toolConfigStrictness(){return L()},set toolConfigStrictness(U){L(U),y()},get tools(){return D()},set tools(U){D(U),y()},get toolContextResolvers(){return P()},set toolContextResolvers(U){P(U),y()},get enabledTools(){return S()},set enabledTools(U){S(U),y()},get toolRegistry(){return v()},set toolRegistry(U){v(U),y()},get accessibility(){return I()},set accessibility(U){I(U),y()},get player(){return p()},set player(U){p(U),y()},get playerType(){return E()},set playerType(U){E(U),y()},get coordinator(){return g()},set coordinator(U){g(U),y()},get createSectionController(){return q7()},set createSectionController(U){q7(U),y()},get onFrameworkError(){return U7()},set onFrameworkError(U){U7(U),y()},get errorRenderer(){return B7()},set errorRenderer(U){B7(U),y()},get onStageChange(){return w7()},set onStageChange(U){w7(U),y()},get assessment(){return s7()},set assessment(U){s7(U),y()},get currentItemRef(){return n7()},set currentItemRef(U){n7(U),y()},get pnpEnforcement(){return r7()},set pnpEnforcement(U){r7(U),y()},get isolation(){return W7()},set isolation(U){W7(U),y()}},Y6=Y9(),J6=h8(Y6);R3(J6,(U)=>w(k7,U),()=>V(k7));var V5=S1(J6,2);{var $5=(U)=>{var _=Q9(),M=M3(_),z=b1(M,!0),A=S1(M,2),k=b1(A,!0),G7=S1(A,2),X1=b1(G7,!0);A3(_),z3((d1)=>{C1(z,V(x1)),C1(k,V(o).message),C1(X1,d1)},[()=>V(f1).join(`
225
- `)]),T1(U,_)},H5=(U)=>{var _=O3(),M=h8(_);L3(M,Q,"default",{},null),T1(U,_)};P3(V5,(U)=>{if(V(o)&&!V(o).recoverable)U($5);else U(H5,-1)})}return T1(G,Y6),F3(_5)}dQ("pie-assessment-toolkit",E3(C3,{assessmentId:{attribute:"assessment-id",type:"String"},section:{attribute:"section",type:"Object"},sectionId:{attribute:"section-id",type:"String"},attemptId:{attribute:"attempt-id",type:"String"},env:{attribute:"env",type:"Object"},ndsIcons:{attribute:"nds-icons",type:"Boolean"},locale:{attribute:"locale",type:"String"},lazyInit:{attribute:"lazy-init",type:"Boolean"},toolConfigStrictness:{attribute:"tool-config-strictness",type:"String"},tools:{attribute:"tools",type:"Object"},toolContextResolvers:{type:"Object"},enabledTools:{attribute:"enabled-tools",type:"String"},toolRegistry:{type:"Object"},accessibility:{type:"Object"},player:{attribute:"player",type:"Object"},playerType:{attribute:"player-type",type:"String"},coordinator:{type:"Object"},createSectionController:{type:"Object"},onFrameworkError:{type:"Object"},errorRenderer:{type:"Object"},onStageChange:{type:"Object"},assessment:{type:"Object"},currentItemRef:{type:"Object"},pnpEnforcement:{attribute:"pnp-enforcement",type:"String"},isolation:{type:"Object"}},["default"],["waitUntilReady","getServiceBundle","setHooks","navigateToItem","getCompositionModel","getItemPlayerConfig","persist","hydrate"],{mode:"open"}));export{C3 as default};
222
+ `;for(let j of X)G+=`- ${j.rule}: ${j.reason}
223
+ `}return G}function k8(Q){let{request:Y,tools:J,pnpPolicy:G,customSources:X,contextId:j}=Q,Z=new E9(j);Z.addSource("host",{id:Y.scope.scopeId,name:`${Y.level}:${Y.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=L7(J.placement[Y.level]),W=L7(J.policy.allowed),K=new Set(L7(J.policy.blocked)),U=[];for(let F of B)U.push(F),Z.addDecision({precedence:0,rule:"placement-membership",featureId:F,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Y.level}`});if(U=U.filter((F)=>{if(J.providers?.[F]?.enabled===!1)return Z.addDecision({precedence:0,rule:"provider-disabled",featureId:F,action:"block",sourceType:"host",reason:`tools.providers.${F}.enabled === false`,value:!1}),!1;return!0}),W.length>0){let F=new Set(W);U=U.filter((L)=>{if(!F.has(L))return Z.addDecision({precedence:0,rule:"host-allowlist",featureId:L,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:W}),!1;return!0})}U=U.filter((F)=>{if(K.has(F))return Z.addDecision({precedence:0,rule:"host-blocked",featureId:F,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:J.policy.blocked}),!1;return!0});let _=[],$=new Map;for(let F of U)$.set(F,["placement"]);let N=new Set(U),D=null;if(G.enforcement==="on"&&G.source&&(G.assessment||G.currentItemRef)){if(D=G.source.apply({assessment:G.assessment,currentItemRef:G.currentItemRef}),D.sources.assessment)Z.addSource("assessment",D.sources.assessment);if(D.sources.student)Z.addSource("student",D.sources.student);if(D.sources.item)Z.addSource("item",D.sources.item);for(let F of D.decisions)Z.addDecision({precedence:F.precedence,rule:F.rule,featureId:F.featureId,action:F.action,sourceType:F.sourceType,reason:F.reason,value:F.value});for(let F of D.unmappedSupportIds)_.push({code:"tool-policy.unknownSupportId",level:Y.level,toolId:F,message:`No registered tool claims PNP support id "${F}"; it was carried through as a feature id and matched nothing. Expected an AfA 3.0 / QTI 3.0 access feature id.`,source:"pnp.pnp-support"});U=U.filter((F)=>{return!D.blockedToolIds.has(F)});for(let F of Array.from($.keys()))if(D.blockedToolIds.has(F))$.delete(F);for(let F of D.mandatedToolIds){if(!!N.has(F))continue;let v=D.perToolFlags.get(F)?.rule??"required-tool",k=N2(F,{placement:B,allowed:W,blocked:K,providers:J.providers}),p={rule:v,hostRule:k.hostRule,hostValue:k.hostValue};_.push({code:"tool-policy.requiredToolBlocked",level:Y.level,toolId:F,message:`Profile policy mandates "${F}" (${v}) but host policy removed it from level "${Y.level}" via ${k.hostRule}.`,details:p}),Z.addDecision({precedence:0,rule:"required-tool-blocked",featureId:F,action:"advisory",sourceType:"host",reason:`Host removed required tool "${F}" via ${k.hostRule}`,value:p})}for(let F of U){let L=D.perToolFlags.get(F);if(L){let C=$.get(F)??[];C.push(`pnp.${L.rule}`),$.set(F,C)}}}for(let F=0;F<X.length;F++){let L=X[F],C=U.slice(),v=L.refine({request:Y,candidates:C}),k=new Set(v.refinedCandidates);for(let R of v.refinedCandidates)if(!C.includes(R))_.push({code:"tool-policy.placementMissing",level:Y.level,toolId:R,message:`Custom source "${L.id}" tried to add tool "${R}" that was not in candidates; ignored.`,source:`custom.${L.id}`}),k.delete(R);U=C.filter((R)=>k.has(R));let p=new Set;if(v.decisions){for(let R of v.decisions)if(Z.addDecision({precedence:R.precedence??100+F,rule:R.rule,featureId:R.featureId,action:R.action,sourceType:R.sourceType,reason:R.reason,value:R.value}),R.action==="block")p.add(R.featureId)}for(let R of C){if(k.has(R))continue;if(p.has(R))continue;Z.addDecision({precedence:100+F,rule:"custom-source",featureId:R,action:"block",sourceType:"custom",reason:`Custom policy source "${L.id}" removed tool "${R}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:L.id}})}for(let R of U){let g=$.get(R)??["placement"];g.push(`custom.${L.id}`),$.set(R,g)}for(let R of C)if(!k.has(R))$.delete(R)}let O=new Set(U),P=U.map((F)=>{let L=D?.perToolFlags.get(F);return{toolId:F,required:L?.required??!1,alwaysAvailable:L?.alwaysAvailable??!1,settings:L?.settings,sources:$.get(F)??["placement"]}});return Z.reconcileFinalStates(O),{visibleTools:P,diagnostics:_,provenance:Z.build()}}function N2(Q,Y){if(!Y.placement.includes(Q))return{hostRule:"placement-missing",hostValue:Y.placement};if(Y.providers?.[Q]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Y.allowed.length>0&&!Y.allowed.includes(Q))return{hostRule:"host-allowlist",hostValue:Y.allowed};if(Y.blocked.has(Q))return{hostRule:"host-blocked",hostValue:Array.from(Y.blocked)};return{hostRule:"placement-missing",hostValue:Y.placement}}function I8(Q){if(!Q)return!1;let Y=Q.personalNeedsProfile;if(Y){if(Array.isArray(Y.supports)&&Y.supports.length>0)return!0;if(Array.isArray(Y.prohibitedSupports)&&Y.prohibitedSupports.length>0)return!0;if(Array.isArray(Y.activateAtInit)&&Y.activateAtInit.length>0)return!0}let J=Q.settings;if(J){let G=J.districtPolicy;if(G){if(Array.isArray(G.blockedTools)&&G.blockedTools.length>0)return!0;if(Array.isArray(G.requiredTools)&&G.requiredTools.length>0)return!0;if(G.policies&&typeof G.policies==="object"&&Object.keys(G.policies).length>0)return!0}let X=J.testAdministration;if(X&&typeof X==="object")for(let j of Object.keys(X)){let Z=X[j];if(Z===void 0||Z===null)continue;if(Array.isArray(Z)&&Z.length===0)continue;if(typeof Z==="object"&&!Array.isArray(Z)&&Object.keys(Z).length===0)continue;return!0}}return!1}function v8(Q){let Y=Q?.settings;if(!Y)return!1;if(Array.isArray(Y.requiredTools)&&Y.requiredTools.length>0)return!0;if(Array.isArray(Y.restrictedTools)&&Y.restrictedTools.length>0)return!0;if(Y.toolParameters&&typeof Y.toolParameters==="object"&&Object.keys(Y.toolParameters).length>0)return!0;return!1}function d7(Q){if(I8(Q.assessment))return"on";if(v8(Q.currentItemRef))return"on";return"off"}class D1{id="pnp";toolRegistry;constructor(Q){this.toolRegistry=Q}apply(Q){let{ctx:Y,result:J}=this.prepare(Q),{pnp:G,districtPolicy:X,itemSettings:j}=Y,Z=new Set;G?.supports?.forEach((B)=>Z.add(B)),G?.prohibitedSupports?.forEach((B)=>Z.add(B)),X?.blockedTools?.forEach((B)=>Z.add(B)),X?.requiredTools?.forEach((B)=>Z.add(B)),j?.requiredTools?.forEach((B)=>Z.add(B)),j?.restrictedTools?.forEach((B)=>Z.add(B));for(let B of Z)this.resolveSupport(B,Y,J);return J}resolveFeature(Q,Y){let{ctx:J,result:G}=this.prepare(Y);return this.resolveSupport(Q,J,G),G}prepare(Q){let{assessment:Y,currentItemRef:J}=Q,G=Y?.personalNeedsProfile,X=Y?.settings,j=J?.settings,Z={blockedToolIds:new Set,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],unmappedSupportIds:new Set,sources:{}};if(X?.districtPolicy||X?.testAdministration)Z.sources.assessment={id:Y?.id||"unknown",name:Y?.name||Y?.id||"Assessment",config:X};if(G)Z.sources.student={id:"student",name:"Student PNP Profile",config:G};if(J&&j)Z.sources.item={id:J.identifier,name:J.identifier,config:j};return{ctx:{pnp:G,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:j,toolConfigs:X?.toolConfigs},result:Z}}resolveSupport(Q,Y,J){if(Y.districtPolicy?.blockedTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:1,rule:"district-block",featureId:X,action:"block",sourceType:"assessment",reason:`District policy blocks "${Q}" for all assessments`,value:Y.districtPolicy.blockedTools});return}if(Y.testAdmin?.toolOverrides?.[Q]===!1){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:2,rule:"test-admin-override",featureId:X,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${Q}" for this session`,value:Y.testAdmin.toolOverrides});return}if(Y.itemSettings?.restrictedTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:3,rule:"item-restriction",featureId:X,action:"block",sourceType:"item",reason:`Item restricts "${Q}" (e.g., mental math question blocks calculator)`,value:Y.itemSettings.restrictedTools});return}if(Y.itemSettings?.requiredTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.mandatedToolIds.add(X),J.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Q,Y),rule:"item-requirement",sourceType:"item"}),J.decisions.push({precedence:4,rule:"item-requirement",featureId:X,action:"enable",sourceType:"item",reason:`Item requires "${Q}" for this question`,value:Y.itemSettings.requiredTools});return}if(Y.districtPolicy?.requiredTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.mandatedToolIds.add(X),J.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Q,Y),rule:"district-requirement",sourceType:"assessment"}),J.decisions.push({precedence:5,rule:"district-requirement",featureId:X,action:"enable",sourceType:"assessment",reason:`District policy requires "${Q}" for all assessments`,value:Y.districtPolicy.requiredTools});return}if(Y.pnp?.prohibitedSupports?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:6,rule:"pnp-prohibited",featureId:X,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${Q}"`,value:Y.pnp.prohibitedSupports});return}if(Y.pnp?.supports?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.perToolFlags.set(X,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Q,Y),rule:"pnp-support",sourceType:"student"}),J.decisions.push({precedence:6,rule:"pnp-support",featureId:X,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${Q}"`,value:Y.pnp.supports});return}let G=this.mapSupportToToolId(Q,J);J.decisions.push({precedence:6,rule:"pnp-support",featureId:G,action:"skip",sourceType:"system",reason:`Feature "${Q}" not configured at any level`,value:{supportId:Q}})}mapSupportToToolId(Q,Y){let J=this.toolRegistry.getToolsByPNPSupport(Q);if(J.size===0){if(this.toolRegistry.getAllTools().length>0)Y.unmappedSupportIds.add(Q);return Q}return Array.from(J)[0]}resolveToolSettings(Q,Y){return Y.itemSettings?.toolParameters?.[Q]??Y.toolConfigs?.[Q]}}var h8=b7({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class N1{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;currentItemRef;pnpEnforcement;disposed=!1;constructor(Q){this.toolRegistry=Q.toolRegistry,this.contextId=Q.contextId??"tool-policy",this.pnpPolicySource=new D1(this.toolRegistry),this.customSources=Q.customSources?[...Q.customSources]:[];let Y=Q.inputs??{};this.tools=Y.tools??h8,this.assessment=Y.assessment??null,this.currentItemRef=Y.currentItemRef??null,this.pnpEnforcement=Y.pnpEnforcement??d7({assessment:this.assessment,currentItemRef:this.currentItemRef})}decide(Q){this.assertNotDisposed();let Y=Q.scope.scopeId?`${this.contextId}:${Q.level}:${Q.scope.scopeId}`:`${this.contextId}:${Q.level}`;return k8({request:Q,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0,enforcement:this.pnpEnforcement},customSources:this.customSources,contextId:Y})}decideFeature(Q){this.assertNotDisposed();let Y=this.hostFeatureGate(Q);if(Y)return Y;return x8(Q,this.pnpPolicySource.resolveFeature(Q,{assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0}),{assessmentBound:this.assessment!==null})}hostFeatureGate(Q){let Y={assessmentBound:this.assessment!==null},J=L7(this.tools.policy.blocked);if(J.includes(Q))return R9(Q,"host-blocked",J,Y);let G=L7(this.tools.policy.allowed);if(G.length>0&&!G.includes(Q))return R9(Q,"host-allowlist",G,Y);return null}getVisibleToolIds(Q,Y){return this.decide({level:Q,scope:{level:Q,scopeId:Y}}).visibleTools.map((J)=>J.toolId)}updateInputs(Q){this.assertNotDisposed();let Y=!1,J=!1;if("tools"in Q){let G=Q.tools??h8;if(!Object.is(this.tools,G))this.tools=G,Y=!0}if("assessment"in Q){let G=Q.assessment??null;if(!Object.is(this.assessment,G))this.assessment=G,Y=!0}if("currentItemRef"in Q){let G=Q.currentItemRef??null;if(!Object.is(this.currentItemRef,G))this.currentItemRef=G,Y=!0}if("pnpEnforcement"in Q&&Q.pnpEnforcement){if(this.pnpEnforcement!==Q.pnpEnforcement)this.pnpEnforcement=Q.pnpEnforcement,J=!0}if(Y||J)this.emit({reason:J&&!Y?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}replaceToolRegistry(Q,Y){this.assertNotDisposed(),this.toolRegistry=Q,this.pnpPolicySource=new D1(Q),this.tools=Y,this.emit({reason:"inputs",inputs:this.snapshotInputs()})}registerPolicySource(Q){return this.assertNotDisposed(),this.customSources.push(Q),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Y=this.customSources.indexOf(Q);if(Y!==-1){if(this.customSources.splice(Y,1),!this.disposed)this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}}onPolicyChange(Q){return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,currentItemRef:this.currentItemRef,pnpEnforcement:this.pnpEnforcement})}emit(Q){for(let Y of Array.from(this.listeners))try{Y(Q)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}class s extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class C9 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var M1=(Q)=>!!Q&&typeof Q==="object"&&!Array.isArray(Q),M2=(Q,Y,J)=>{let G={...Y,...J};if(Q==="textToSpeech"&&M1(Y.settings)&&M1(J.settings)){if(G.settings={...Y.settings,...J.settings},M1(Y.settings.mathSpeech)&&M1(J.settings.mathSpeech))G.settings.mathSpeech={...Y.settings.mathSpeech,...J.settings.mathSpeech}}return G},z2=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],O2=["section-navigation-change","section-session-applied","section-loading-complete","section-items-complete-changed","section-error","timed-media-cue-changed","timed-media-policy-degraded","timed-media-invalid"];class T9{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;toolRegistry;toolRegistrySupplied;toolRegistrySettled;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new w9;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitEntries=new Map;sectionControllerDisposePromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;pnpEnforcementOverride=null;boundAssessment=null;boundCurrentItemRef=null;reportedUnboundFeaturePolicy=!1;reportedMissingTTSProvider=!1;heldMissingTTSProviderBackend=null;reportedRegistryUnavailable=!1;resolveConfig(Q){let Y=c1(Q.toolConfigStrictness),J=Q.toolRegistry??new S9,G=Q.deferToolConfigValidation===!0?b7(Q.tools):this.validateToolsConfig(Q.tools,{strictness:Y,source:"ToolkitCoordinator.init",toolRegistry:J});return{...Q,toolConfigStrictness:Y,toolRegistry:J,tools:{...G,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...G.providers}},accessibility:{language:"en-US",...Q.accessibility??{},catalogs:Q.accessibility?.catalogs??[]}}}validateToolsConfig(Q,Y){let{config:J,diagnostics:G}=d1(Q,Y.toolRegistry),X=this.reportedRegistryUnavailable||!this.toolRegistrySettled?G.filter((j)=>j.code!=="tools.registryUnavailable"):G;if(l1(X,Y),Y.strictness!=="off"&&X.some((j)=>j.code==="tools.registryUnavailable"))this.reportedRegistryUnavailable=!0;return J}constructor(Q){if(!Q.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");this.toolRegistrySupplied=Q.toolRegistry!=null,this.toolRegistrySettled=this.toolRegistrySupplied;let Y=this.resolveConfig(Q);if(this.assessmentId=Y.assessmentId,this.config=Y,this.toolRegistry=Y.toolRegistry??new S9,this.installToolContextResolvers(Y.toolContextResolvers),this.hooks=Y.hooks??{},this.lazyInit=Q.lazyInit===!0,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=Q.frameworkErrorBus??new u7,this.ownsFrameworkErrorBus=!Q.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new G9,this.highlightCoordinator=new p7,this.elementToolStateStore=new Y9,this.catalogResolver=new Q9(Y.accessibility?.catalogs||[],Y.accessibility?.language||"en-US"),this.toolProviderRegistry=new H1,this._registerToolProviders(),this.ttsService=new c7,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.setupStatePersistenceHooks(),this.policyEngine=new N1({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,inputs:{tools:this.config.tools,assessment:null,currentItemRef:null,pnpEnforcement:this.resolveEffectivePnpEnforcement()}}),!this.lazyInit)this.waitUntilReady().catch((J)=>{if(J instanceof s)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready"})})}assertNotDisposed(){if(this.disposePromise!==null)throw new s}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((Q)=>{let Y=this.hooks.onFrameworkError;if(!Y)return;try{Y(Q)}catch(J){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",J)}})}async emitTelemetry(Q,Y){try{await this.hooks.onTelemetry?.(Q,Y)}catch(G){console.warn("[ToolkitCoordinator] telemetry hook failed:",G)}let J=Y?{...Y}:void 0;for(let G of this.telemetryListeners)try{G({eventName:Q,payload:J?{...J}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(Q){for(let Y of this.sectionControllerLifecycleListeners)try{Y(Q)}catch(J){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",J)}}handleError(Q,Y){let J=W0({error:Q,context:Y});this.frameworkErrorBus.reportFrameworkError(J)}subscribeFrameworkErrors(Q){return this.frameworkErrorBus.subscribeFrameworkErrors(Q)}reportFrameworkError(Q){this.frameworkErrorBus.reportFrameworkError(Q)}getSectionControllerMapKey(Q){return`${Q.assessmentId}::${Q.sectionId}::${Q.attemptId||""}`}createDefaultSectionPersistence(){let Q=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Y=(J)=>{let{assessmentId:G,sectionId:X,attemptId:j}=J.key;return`pie:section-controller:v1:${G}:${X}:${j||"default"}`};return{async loadSession(J){if(!Q)return null;let G=Q.getItem(Y(J));if(!G)return null;try{return JSON.parse(G)}catch{return null}},async saveSession(J,G){if(!Q)return;Q.setItem(Y(J),JSON.stringify(G))},async clearSession(J){if(!Q)return;Q.removeItem(Y(J))}}}async resolveSectionPersistence(Q){let Y=this.getSectionControllerMapKey(Q.key),J=this.sectionPersistenceStrategies.get(Y);if(J)return J;let G={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(Q,G)??await G.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Y,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((Q)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(Q)).catch((Y)=>{this.handleError(Y,{phase:"state-save"})})})}async ensureStateLoaded(){if(this.stateLoaded)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let Q=this.hooks.loadToolState;if(!Q)return;try{let Y=await Q();if(this.assertNotDisposed(),Y&&typeof Y==="object")this.elementToolStateStore.loadState(Y);this.stateLoaded=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Y)})}catch(Y){if(Y instanceof s)throw Y;this.handleError(Y,{phase:"state-load"})}})().finally(()=>{this.stateLoadPromise=void 0}),this.stateLoadPromise}reportMissingTTSProvider(Q){if(!this.toolRegistrySettled){this.heldMissingTTSProviderBackend=Q;return}if(this.reportedMissingTTSProvider)return;this.reportedMissingTTSProvider=!0,console.warn(`[ToolkitCoordinator] Text-to-speech is configured for the "${Q}" backend but falls back to browser speech: no "tts" tool provider is registered. A coordinator registers tool providers only from its \`toolRegistry\`, or from its toolkit's when constructed without one, so supply one that carries the text-to-speech registration — for the packaged capability set, \`createPackagedToolRegistry()\` from "@pie-players/pie-default-tool-loaders". Reported once per coordinator.`)}adoptToolRegistry(Q){if(this.disposePromise!==null||this.toolRegistrySettled)return!1;this.toolRegistrySettled=!0;let Y=this.heldMissingTTSProviderBackend;this.heldMissingTTSProviderBackend=null;let J=this.config.toolConfigStrictness??"error",G="ToolkitCoordinator.adoptToolRegistry";if(!Q){if(this.validateToolsConfig(this.config.tools,{strictness:J,source:G,toolRegistry:this.toolRegistry}),Y)this.reportMissingTTSProvider(Y);return!1}this.toolRegistry=Q,this.config.toolRegistry=Q;try{this.config.tools=this.validateToolsConfig(this.config.tools,{strictness:J==="off"?"off":"warn",source:G,toolRegistry:Q})}catch(j){console.warn("[ToolkitCoordinator] Tool config does not validate against the adopted tool registry:",j)}this.policyEngine.replaceToolRegistry(Q,this.config.tools);let X=this.ttsInitialized||this.ttsInitPromise!==void 0||this.ttsReconfigurePromise!==void 0;for(let j of this.getProviderDescriptorTools()){if(X&&j.toolId==="textToSpeech")continue;this.registerProviderFromTool(j)}if(X)this.scheduleTTSReconfigure();return!0}_registerToolProviders(){let Q=this.getProviderDescriptorTools();for(let Y of Q)this.registerProviderFromTool(Y)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((Q)=>!!Q.provider)}async registerProviderFromTool(Q){let Y=Q.provider;if(!Y)return;let J=null,G;try{let X=this.getToolConfig(Q.toolId)||void 0;if(X?.enabled===!1)return;if(J=b9(Q,X),!J||this.toolProviderRegistry.has(J))return;let j=Y.createProvider(X),Z=Y.getInitConfig?.(X)??X?.provider?.init??{},B=this.addToolTelemetryReporter({toolId:Q.toolId,providerId:J,initConfig:Z}),W=this.createToolTelemetryForwarder({toolId:Q.toolId,providerId:J}),K=Y.getAuthFetcher?.(X)??X?.provider?.runtime?.authFetcher;G={provider:j,config:B,lazy:Y.lazy??!0,authFetcher:K,onTelemetry:W}}catch(X){this.reportProviderRegisterFailure(X,J,Q.toolId);return}await this.registerProvider(J,G)}createToolTelemetryForwarder(Q){return async(Y,J)=>{await this.emitTelemetry(Y,{...J||{},toolId:Q.toolId,providerId:Q.providerId})}}addToolTelemetryReporter(Q){let Y=Q.initConfig&&typeof Q.initConfig==="object"?{...Q.initConfig}:{},J=typeof Y.onTelemetry==="function"?Y.onTelemetry:null,G=this.createToolTelemetryForwarder({toolId:Q.toolId,providerId:Q.providerId});return Y.onTelemetry=async(X,j)=>{if(J)await J(X,j);await G(X,j)},Y}async registerProvider(Q,Y){try{this.toolProviderRegistry.register(Q,Y);let J={providerId:Q,providerName:Y.provider.providerName};await this.hooks.onProviderRegistered?.(Q,J),await this.emitTelemetry("pie-toolkit-provider-registered",{providerId:Q,providerName:Y.provider.providerName})}catch(J){this.reportProviderRegisterFailure(J,Q)}}reportProviderRegisterFailure(Q,Y,J){console.warn(Y?`[ToolkitCoordinator] Failed to register provider "${Y}":`:`[ToolkitCoordinator] Failed to register the provider of tool "${J}":`,Q),this.handleError(Q,{phase:"provider-register",providerId:Y??void 0})}async ensureProviderReady(Q){this.assertNotDisposed();let Y=this.providerInitPromises.get(Q);if(Y)return Y;let J=(async()=>{let G=await this.toolProviderRegistry.getProvider(Q,!1);this.assertNotDisposed();let X={providerId:Q,providerName:G.providerName};try{return await this.hooks.onProviderInitStart?.(Q,X),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(Q),this.assertNotDisposed(),await this.hooks.onProviderReady?.(Q,X),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{providerId:Q}),this.assertNotDisposed(),G}catch(j){if(j instanceof s)throw j;let Z=j instanceof Error?j:Error(String(j));throw this.handleError(Z,{phase:"provider-init",providerId:Q}),Z}})().finally(()=>{this.providerInitPromises.delete(Q)});return this.providerInitPromises.set(Q,J),J}setHooks(Q){if(Object.assign(this.hooks,Q),this.setupStatePersistenceHooks(),this.disposePromise===null&&Q.onCoordinatorReady&&this.isReady())Promise.resolve(Q.onCoordinatorReady(this)).catch((Y)=>{this.handleError(Y,{phase:"coordinator-ready"})})}subscribeTelemetry(Q){return this.telemetryListeners.add(Q),()=>{this.telemetryListeners.delete(Q)}}getSectionController(Q){let Y={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(Y))}subscribeSectionEvents(Q){if(this.activeCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Y=this.activeSubscriptions.get(Q.listener);if(Y)Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null;let J={listener:Q.listener,eventTypes:Q.eventTypes,itemIds:Q.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(Q.listener,J);let G=this.sectionControllers.get(this.activeCohortMapKey);if(G)this.bindSubscriptionToController(J,G);let X=!1;return()=>{if(X)return;if(X=!0,J.unsubscribeCurrent?.(),J.unsubscribeCurrent=null,this.activeSubscriptions.get(Q.listener)===J)this.activeSubscriptions.delete(Q.listener)}}bindSubscriptionToController(Q,Y){Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let J=Y.subscribe;if(typeof J!=="function")return;let G=this.buildSectionEventPredicate(Q);Q.unsubscribeCurrent=J.call(Y,(Z)=>{if(!G(Z))return;this.deliverSectionEventSafely(Q.listener,Z)});let X=this.buildContentLoadedReplayEvents(Y);for(let Z of X)if(G(Z))this.deliverSectionEventSafely(Q.listener,Z);let j=this.buildLoadingCompleteReplayEvent(Y);if(j&&G(j))this.deliverSectionEventSafely(Q.listener,j)}deliverSectionEventSafely(Q,Y){try{Q(Y)}catch(J){console.warn("[ToolkitCoordinator] section-event listener failed:",J)}}setActiveCohort(Q){if(this.activeCohortMapKey===Q)return;this.activeCohortMapKey=Q;let Y=this.sectionControllers.get(Q);if(!Y)return;for(let J of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(J,Y)}setActiveCohortIfLatestRequest(Q){if(this.latestRequestedActiveCohortMapKey!==Q)return;this.setActiveCohort(Q)}suspendActiveCohortIfSuperseded(Q){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===Q)return;this.activeCohortMapKey=null;for(let Y of Array.from(this.activeSubscriptions.values()))Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null}clearActiveCohortIfMatches(Q){if(this.activeCohortMapKey!==Q)return;this.activeCohortMapKey=null;for(let Y of Array.from(this.activeSubscriptions.values()))Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null}buildSectionEventPredicate(Q){let Y=Q.eventTypes?new Set(Q.eventTypes):null,J=Q.itemIds?new Set(Q.itemIds):null;return(G)=>{if(Y||J){let X=G?.type||null;if(Y&&(!X||!Y.has(X)))return!1;if(J){if(!Array.from(this.collectEventItemIds(G)).some((Z)=>J.has(Z)))return!1}}return!0}}collectEventItemIds(Q){let Y=new Set;if("itemId"in Q&&typeof Q.itemId==="string")Y.add(Q.itemId);if("canonicalItemId"in Q&&typeof Q.canonicalItemId==="string")Y.add(Q.canonicalItemId);if("currentItemId"in Q&&typeof Q.currentItemId==="string")Y.add(Q.currentItemId);if("previousItemId"in Q&&typeof Q.previousItemId==="string")Y.add(Q.previousItemId);return Y}buildContentLoadedReplayEvents(Q){let Y=Q.getRuntimeState?.(),J=Y?.loadedRenderables;if(!Array.isArray(J)||J.length===0)return[];let G=typeof Y?.currentItemIndex==="number"&&Number.isFinite(Y.currentItemIndex)?Y.currentItemIndex:0,X=Date.now(),j=[];for(let Z of J){if(!Z)continue;let B=Z.itemId,W=typeof Z.canonicalItemId==="string"&&Z.canonicalItemId?Z.canonicalItemId:B;if(typeof B!=="string"||!B)continue;j.push({type:"content-loaded",contentKind:Z.contentKind??"unknown",itemId:B,canonicalItemId:W,currentItemIndex:G,timestamp:X})}return j}buildLoadingCompleteReplayEvent(Q){let Y=Q.getRuntimeState?.();if(Y?.loadingComplete!==!0)return null;let J=typeof Y.totalRegistered==="number"&&Number.isFinite(Y.totalRegistered)?Math.max(0,Y.totalRegistered):0,G=typeof Y.totalLoaded==="number"&&Number.isFinite(Y.totalLoaded)?Math.max(0,Y.totalLoaded):J;return{type:"section-loading-complete",totalRegistered:J,totalLoaded:G,currentItemIndex:Y.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(Q){return this.subscribeSectionEvents({eventTypes:Q.eventTypes||z2,itemIds:Q.itemIds,listener:Q.listener})}subscribeSectionLifecycleEvents(Q){return this.subscribeSectionEvents({eventTypes:Q.eventTypes||O2,listener:Q.listener})}onSectionControllerLifecycle(Q){return this.sectionControllerLifecycleListeners.add(Q),()=>{this.sectionControllerLifecycleListeners.delete(Q)}}async getOrCreateSectionController(Q){if(this.disposePromise!==null)throw new s;let Y={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId},J=this.getSectionControllerMapKey(Y);this.latestRequestedActiveCohortMapKey=J,this.suspendActiveCohortIfSuperseded(J);let G=await this.resolveExistingSectionController({mapKey:J,key:Y,input:Q.input,updateExisting:Q.updateExisting});if(G){if(this.disposePromise!==null)throw new s;return G}let X=this.sectionControllerDisposePromises.get(J);if(X)await Promise.allSettled([X]);if(this.disposePromise!==null)throw new s;let j=this.sectionControllerInitEntries.get(J);if(j)return j.promise;let Z={retired:!1,candidateClaimed:!1},B=this.initializeNewSectionController({args:Q,key:Y,mapKey:J,token:Z}).catch((W)=>{throw this.handleSectionControllerInitError(W,Q),W}).finally(()=>{if(this.sectionControllerInitEntries.get(J)?.token===Z)this.sectionControllerInitEntries.delete(J)});return this.sectionControllerInitEntries.set(J,{key:Y,token:Z,promise:B}),B}async resolveExistingSectionController(Q){let Y=this.sectionControllers.get(Q.mapKey);if(!Y)return;if(this.sectionControllerKeys.set(Q.mapKey,Q.key),Q.updateExisting!==!1)await Y.updateInput?.(Q.input);if(this.sectionControllers.get(Q.mapKey)!==Y)return;return this.setActiveCohortIfLatestRequest(Q.mapKey),Y}createSectionControllerContext(Q){return{key:Q.key,coordinator:this,input:Q.input}}async initializeNewSectionController(Q){let Y=this.createSectionControllerContext({key:Q.key,input:Q.args.input}),J=await this.resolveSectionPersistence(Y);if(this.disposePromise!==null||Q.token.retired){if(this.sectionPersistenceStrategies.get(Q.mapKey)===J)this.sectionPersistenceStrategies.delete(Q.mapKey);throw this.createSectionControllerRetirementError()}let G={createDefaultController:Q.args.createDefaultController},X=await this.hooks.createSectionController?.(Y,G)??await G.createDefaultController(),j={mapKey:Q.mapKey,key:Q.key,controller:X,persistence:J,token:Q.token};try{return await this.retireUnpublishedSectionControllerIfNeeded(j),await X.configureSessionPersistence?.({strategy:J,context:Y}),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.initialize?.(Q.args.input),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.hydrate?.(),await this.finalizeSectionControllerReady({...j,context:Y}),X}catch(Z){throw await this.cleanupUnpublishedSectionController(j),Z}}createSectionControllerRetirementError(){return this.disposePromise!==null?new s:new C9}async retireUnpublishedSectionControllerIfNeeded(Q){if(this.disposePromise===null&&!Q.token.retired)return;throw await this.cleanupUnpublishedSectionController(Q),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(Q){if(Q.token.candidateClaimed)return;Q.token.candidateClaimed=!0;try{await Q.controller.dispose?.()}catch(Y){this.handleError(Y,{phase:"section-controller-dispose",details:{sectionId:Q.key.sectionId,attemptId:Q.key.attemptId}})}finally{if(this.sectionPersistenceStrategies.get(Q.mapKey)===Q.persistence)this.sectionPersistenceStrategies.delete(Q.mapKey)}}retirePublishedSectionControllerIfNeeded(Q){if(this.disposePromise!==null&&!Q.token.retired)this.disposeSectionController({sectionId:Q.key.sectionId,attemptId:Q.key.attemptId});if(Q.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(Q){await this.retireUnpublishedSectionControllerIfNeeded(Q),this.sectionControllers.set(Q.mapKey,Q.controller),this.sectionControllerKeys.set(Q.mapKey,Q.key),Q.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(Q.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:Q.key,controller:Q.controller}),await this.hooks.onSectionControllerReady?.(Q.context,Q.controller),this.retirePublishedSectionControllerIfNeeded(Q),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:Q.key.assessmentId,sectionId:Q.key.sectionId,attemptId:Q.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(Q)}handleSectionControllerInitError(Q,Y){if(Q instanceof s||Q instanceof C9)return;this.handleError(Q,{phase:"section-controller-init",details:{sectionId:Y.sectionId,attemptId:Y.attemptId}})}disposeSectionController(Q){let Y={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId},J=this.getSectionControllerMapKey(Y),G=this.sectionControllerInitEntries.get(J);if(G)G.token.retired=!0;let X=this.sectionControllers.get(J);if(!X){let K=this.sectionControllerDisposePromises.get(J);if(K)return K;if(!G)return Promise.resolve();let U=Promise.allSettled([G.promise]).then(()=>{return});return this.trackSectionControllerDisposal(J,U)}let j=this.sectionPersistenceStrategies.get(J);if(this.clearActiveCohortIfMatches(J),this.sectionControllers.get(J)===X)this.sectionControllers.delete(J),this.sectionControllerKeys.delete(J),this.sectionPersistenceStrategies.delete(J),this.emitSectionControllerLifecycle({type:"disposed",key:Y});let Z=this.createSectionControllerContext({key:Y,input:void 0}),B=this.disposeSectionControllerEntry({args:Q,key:Y,context:Z,controller:X,persistenceStrategy:j}),W=G?Promise.allSettled([G.promise]).then(()=>B):B;return this.trackSectionControllerDisposal(J,W)}trackSectionControllerDisposal(Q,Y){this.sectionControllerDisposePromises.set(Q,Y);let J=()=>{if(this.sectionControllerDisposePromises.get(Q)===Y)this.sectionControllerDisposePromises.delete(Q)};return Y.then(J,J),Y}async disposeSectionControllerEntry(Q){try{await this.runSectionControllerDisposePipeline({key:Q.key,context:Q.context,controller:Q.controller,persistBeforeDispose:Q.args.persistBeforeDispose})}catch(Y){this.handleError(Y,{phase:"section-controller-dispose",details:{sectionId:Q.args.sectionId,attemptId:Q.args.attemptId}})}finally{await this.finalizeSectionControllerDispose({context:Q.context,persistenceStrategy:Q.persistenceStrategy,clearPersistence:Q.args.clearPersistence})}}async runSectionControllerDisposePipeline(Q){let Y=[];if(Q.persistBeforeDispose!==!1)try{await Q.controller.persist?.()}catch(J){Y.push(J)}try{await Q.controller.dispose?.()}catch(J){Y.push(J)}if(Y.length===1)throw Y[0];if(Y.length>1)throw AggregateError(Y,"Section controller persistence and disposal both failed.");await this.hooks.onSectionControllerDispose?.(Q.context,Q.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:Q.key.assessmentId,sectionId:Q.key.sectionId,attemptId:Q.key.attemptId})}async finalizeSectionControllerDispose(Q){if(Q.clearPersistence)await Q.persistenceStrategy?.clearSession?.(Q.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let Q=[],Y=async(G)=>{try{await G()}catch(X){Q.push(X)}};await this.waitForAdmittedInitialization();let J=new Map;for(let[G,X]of this.sectionControllerInitEntries)J.set(G,X.key);for(let[G,X]of this.sectionControllerKeys)J.set(G,X);for(let G of J.values())this.disposeSectionController({sectionId:G.sectionId,attemptId:G.attemptId});await Promise.allSettled(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let G of this.activeSubscriptions.values())await Y(()=>G.unsubscribeCurrent?.()),G.unsubscribeCurrent=null;this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Y(()=>this.ttsService.stop()),await Y(()=>this.toolProviderRegistry.destroy()),await Y(()=>this.highlightCoordinator.destroy());for(let G of this.toolCoordinator.getRegisteredTools())await Y(()=>this.toolCoordinator.releaseTool(G));if(await Y(()=>this.catalogResolver.destroy()),await Y(()=>this.toolRequests.dispose()),await Y(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(Q.length===1)throw Q[0];if(Q.length>1)throw AggregateError(Q,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let Q=new Set;if(this.coordinatorReadyPromise)Q.add(this.coordinatorReadyPromise);if(this.ttsInitPromise)Q.add(this.ttsInitPromise);if(this.ttsReconfigurePromise)Q.add(this.ttsReconfigurePromise);for(let Y of this.providerInitPromises.values())Q.add(Y);await Promise.allSettled(Q)}async ensureTTSReady(Q){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(Q).then(()=>this.assertNotDisposed()).finally(()=>{this.ttsInitPromise=void 0}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let Q=this.ttsReconfigurePromise;while(Q)await Q,Q=this.ttsReconfigurePromise}async _initializeTTS(Q){if(this.ttsInitialized)return;let Y=this.resolveTTSToolConfig(Q),J=y8(Y),G=L9(J),X=f8(J);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:G}}),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:G}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:G}),this.toolProviderRegistry.has("tts"))try{let B=await(await this.ensureProviderReady("tts")).createInstance();await this.initializeTTSService(B,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:G,provider:"registry"}),console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");return}catch(Z){if(Z instanceof s)throw Z;let B=Z instanceof Error?Z:Error(String(Z));await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:G,errorType:"TTSRegistryInitError",message:B.message,recovered:!0}),await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:G,fromProvider:"registry",toProvider:"browser",reason:B.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",B)}else if(G!=="browser")this.reportMissingTTSProvider(G);let j=new g7;try{await this.initializeTTSService(j,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:G,provider:"browser-fallback"})}catch(Z){if(Z instanceof s)throw Z;let B=Z instanceof Error?Z:Error(String(Z));throw this.handleError(B,{phase:"tts-init"}),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:B.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:G,errorType:"TTSInitError",message:B.message}),B}}resolveTTSToolConfig(Q){return Q||this.getTTSConfigFromProviders()||{}}async initializeTTSService(Q,Y){let J={...Y.providerOptions||{},__pieTelemetry:async(X,j)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...j||{}})}},G={...Y,providerOptions:J};await this.ttsService.initialize(Q,G),await this.ensureBrowserVoicesReady(Q),this.assertNotDisposed(),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,await this.hooks.onTTSReady?.(),this.assertNotDisposed()}async ensureBrowserVoicesReady(Q,Y=1200){if(Q.providerId!=="browser")return;if(typeof window>"u")return;if(!("speechSynthesis"in window))return;let J=window.speechSynthesis;if(J.getVoices().length>0)return;await new Promise((j)=>{let Z=!1,B=typeof J.addEventListener==="function"&&typeof J.removeEventListener==="function",W=!B&&"onvoiceschanged"in J,K=W?J.onvoiceschanged:null,U=!1,_=()=>{if(Z)return;if(Z=!0,window.clearTimeout(N),B)J.removeEventListener("voiceschanged",$);else if(U&&J.onvoiceschanged===$)J.onvoiceschanged=K;j()},$=(D)=>{if(!B&&typeof K==="function"&&D)K.call(J,D);_()},N=window.setTimeout(_,Y);if(B)J.addEventListener("voiceschanged",$,{once:!0});else if(W)J.onvoiceschanged=$,U=!0});let X=J.getVoices();await this.emitTelemetry("pie-toolkit-tts-browser-voices-ready",{voiceCount:X.length,timedOut:X.length===0})}getServiceBundle(){return{ttsService:this.ttsService,toolCoordinator:this.toolCoordinator,highlightCoordinator:this.highlightCoordinator,elementToolStateStore:this.elementToolStateStore,catalogResolver:this.catalogResolver,toolProviderRegistry:this.toolProviderRegistry}}async getToolProvider(Q){return this.ensureProviderReady(Q)}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{await this.ensureStateLoaded(),this.assertNotDisposed();let Q=this.getTTSConfigFromProviders();if(Q?.enabled!==!1)await this.ensureTTSReady(Q);if(this.assertNotDisposed(),!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-coordinator-ready",{assessmentId:this.assessmentId})})().finally(()=>{this.coordinatorReadyPromise=void 0}),this.coordinatorReadyPromise}isReady(){return this.getInitStatus().coordinator}getInitStatus(){let Q={};for(let J of this.toolProviderRegistry.getProviderIds())Q[J]=this.toolProviderRegistry.isInitialized(J);let Y=this.getTTSConfigFromProviders();return{tts:this.ttsInitialized,stateLoaded:this.stateLoaded||!this.hooks.loadToolState,coordinator:(this.stateLoaded||!this.hooks.loadToolState)&&(this.ttsInitialized||Y?.enabled===!1),providers:Q}}getTTSConfigFromProviders(){return this.config.tools?.providers?.textToSpeech}assertCanonicalToolId(Q){if(typeof Q!=="string"||Q.trim().length===0)throw Error("Tool id must be a non-empty string.");if(Q==="tts")throw Error('Tool id "tts" is no longer supported. Use "textToSpeech".');if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(Q))throw Error(`Unknown tool id "${Q}".`)}installToolContextResolvers(Q){if(!Q)return;for(let[Y,J]of Object.entries(Q)){if(J==null)continue;if(this.assertCanonicalToolId(Y),typeof J!=="function")throw Error(`Invalid tool context resolver for "${Y}": expected a function.`);this.toolContextResolvers.set(Y,J)}}setToolContextResolvers(Q){this.toolContextResolvers.clear(),this.installToolContextResolvers(Q??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let Q of this.toolContextResolverChangeListeners)try{Q()}catch(Y){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Y)}}isToolEnabled(Q){return this.assertCanonicalToolId(Q),this.config.tools?.providers?.[Q]?.enabled!==!1}getToolConfig(Q){return this.assertCanonicalToolId(Q),this.config.tools?.providers?.[Q]||null}updateToolConfig(Q,Y){this.assertCanonicalToolId(Q);let J=this.getToolConfig(Q)||{};if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});if(!this.config.tools.providers)this.config.tools.providers={};let G={...this.config.tools.providers||{},[Q]:M2(Q,J,Y)};this.config.tools=this.validateToolsConfig({...this.config.tools,providers:G},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}),this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:Q}),this._applyToolConfigChange(Q,J)}updateToolPlacement(Q,Y){this.updateToolsPlacement({[Q]:[...Y]})}updateToolsPlacement(Q){if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});let Y=this.config.tools?.placement??{section:[],item:[],passage:[]},J={section:[...Q.section??Y.section??[]],item:[...Q.item??Y.item??[]],passage:[...Q.passage??Y.passage??[]]},G=this.validateToolsConfig({...this.config.tools,placement:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});G.placement=J,this.config.tools=G,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(Q){return this.policyEngine.decide(Q)}decideFeaturePolicy(Q){let Y=this.policyEngine.decideFeature(Q),J=this.config.assessmentOptional!==!0||this.pnpEnforcementOverride==="on";if(!Y.assessmentBound&&J&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${Q}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);return Y}onPolicyChange(Q){return this.policyEngine.onPolicyChange(Q)}onCatalogsChange(Q){return this.catalogResolver.onCatalogsChange(Q)}updateAssessment(Q){this.boundAssessment=Q,this.policyEngine.updateInputs({assessment:Q,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}updateCurrentItemRef(Q){this.boundCurrentItemRef=Q,this.policyEngine.updateInputs({currentItemRef:Q,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}setPnpEnforcement(Q){this.pnpEnforcementOverride=Q,this.policyEngine.updateInputs({pnpEnforcement:this.resolveEffectivePnpEnforcement()})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(Q){return this.policyEngine.registerPolicySource(Q)}registerToolContextResolver(Q,Y){if(this.assertCanonicalToolId(Q),typeof Y!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);return this.toolContextResolvers.set(Q,Y),this.notifyToolContextResolverChange(),()=>{if(this.toolContextResolvers.get(Q)!==Y)return;this.toolContextResolvers.delete(Q),this.notifyToolContextResolverChange()}}hasToolContextResolver(Q){return this.assertCanonicalToolId(Q),this.toolContextResolvers.has(Q)}resolveToolContext(Q){this.assertCanonicalToolId(Q.toolId);let Y=this.toolContextResolvers.get(Q.toolId);if(!Y)return null;let J;try{J=Y(Q)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${Q.toolId}" threw:`,X),{toolId:Q.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!J)return{toolId:Q.toolId,visible:!0,params:{}};let G=J.params&&typeof J.params==="object"&&!Array.isArray(J.params)?J.params:{};return{toolId:Q.toolId,visible:J.visible!==!1,params:G,reason:typeof J.reason==="string"?J.reason:void 0}}onToolContextResolverChange(Q){return this.toolContextResolverChangeListeners.add(Q),()=>{this.toolContextResolverChangeListeners.delete(Q)}}registerToolRequestTarget(Q){return this.toolRequests.registerTarget(Q)}requestTool(Q){return this.assertCanonicalToolId(Q.toolId),this.toolRequests.request(Q)}canRequestTool(Q,Y){try{this.assertCanonicalToolId(Q)}catch{return!1}return this.toolRequests.canRequest(Q,Y)}onToolRequestTargetsChange(Q){return this.toolRequests.onTargetsChange(Q)}resolveEffectivePnpEnforcement(){if(this.pnpEnforcementOverride!==null)return this.pnpEnforcementOverride;return d7({assessment:this.boundAssessment,currentItemRef:this.boundCurrentItemRef})}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(Q,Y){if(this.disposePromise!==null)return;switch(Q){case"textToSpeech":this.scheduleTTSReconfigure();break;case"answerEliminator":break;default:this._registerChangedToolProvider(Q,Y)}}_registerChangedToolProvider(Q,Y){let J=this.getProviderDescriptorTools().find((Z)=>Z.toolId===Q);if(!J)return;this.registerProviderFromTool(J);let G=(Z)=>{try{return b9(J,Z)}catch{return null}},X=G(Y),j=G(this.getToolConfig(Q)||void 0);if(!X||X===j||!this.toolProviderRegistry.has(X))return;this.toolProviderRegistry.unregister(X).catch((Z)=>{console.warn(`[ToolkitCoordinator] Failed to unregister provider "${X}":`,Z)})}scheduleTTSReconfigure(){let Q=this.ttsInitPromise,Y=Q?Q.catch(()=>{}).then(()=>this._reconfigureTTSProvider()):this._reconfigureTTSProvider();this.ttsReconfigurePromise=Y,Y.finally(()=>{if(this.ttsReconfigurePromise===Y)this.ttsReconfigurePromise=void 0}),Y.then(async()=>{if(this.disposePromise!==null)return;let J=this.getTTSConfigFromProviders();if(!this.lazyInit&&J?.enabled!==!1)await this.ensureTTSReady(J)})}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsInitPromise=void 0;try{this.ttsService.stop()}catch{}if(this.toolProviderRegistry.has("tts"))await this.toolProviderRegistry.unregister("tts");if(this.disposePromise!==null)return;let Q=this.getProviderDescriptorTools().find((Y)=>Y.toolId==="textToSpeech");if(!Q)return;await this.registerProviderFromTool(Q)}}var P2=()=>{};function m8(Q){let{ttsService:Y,listenerId:J,silence:G}=Q;if(typeof Y?.onStateChange!=="function")return P2;let X=(j)=>{if(j!==w.PLAYING&&j!==w.LOADING)return;G()};return Y.onStateChange(J,X),()=>{try{Y.offStateChange?.(J,X)}catch{}}}function u8(Q){try{if(Q?.isPlaying?.())Q.pause?.()}catch{}}import{timedMediaProjectionSignature as Q4}from"@pie-players/pie-players-shared/timed-media";var p8="pie-register",g8="pie-unregister",c8="pie-item-session-changed";var d8="pie-content-loaded",l8="pie-item-player-error",i8="pie-formative-action",s8="pie-media-time-source";var L2={bubbles:!0,composed:!0,cancelable:!1};function w2(Q,Y,J={}){return new CustomEvent(Q,{detail:Y,...L2,...J})}function y9(Q,Y,J,G={}){return Q.dispatchEvent(w2(Y,J,G))}function x7(){return{phase:"idle",cohort:null,controllerResolved:!1,readinessSignals:{sectionReady:!1,interactionReady:!1,allLoadingComplete:!1,runtimeError:!1},effectiveRuntime:null,effectiveToolsConfig:null,loadingCompleteEmitted:!1,lastFrameworkError:null,itemCount:0,loadedCount:0}}function f9(Q,Y){if(Q===Y)return!0;if(!Q||!Y)return!1;return Q.sectionId===Y.sectionId&&Q.attemptId===Y.attemptId}function R2(Q){if(Q.runtimeError)return"error";if(Q.allLoadingComplete)return"ready";if(Q.interactionReady)return"interaction-ready";if(Q.sectionReady)return"loading";return"bootstrapping"}function n8(Q){let Y=Q.signals.sectionReady&&Q.signals.allLoadingComplete,J=Q.mode==="strict"?Y:Q.signals.interactionReady;return{phase:R2({...Q.signals,allLoadingComplete:Y,interactionReady:J}),interactionReady:J,allLoadingComplete:Y,reason:Q.reason}}function r8(Q){switch(Q){case"idle":return null;case"booting-section":return"composed";case"engine-ready":return"engine-ready";case"interactive":return"interactive";case"disposed":return"disposed"}}function z1(Q,Y,J,G="entered"){let X=r8(Y);if(!X)return;Q.push({kind:"stage-change",stage:X,status:G,cohort:J})}function o8(Q){let Y={...x7(),phase:"booting-section",cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount},J=[];return z1(J,"booting-section",Q.cohort),{state:Y,outputs:J}}function E2(Q,Y){if(Q.phase==="idle"||Q.phase==="disposed")return{state:Q,outputs:[]};let J=n8({mode:Y.mode,signals:Y.signals}),G=[],X=Q.phase,j=Q.loadingCompleteEmitted;if(X==="engine-ready"&&J.interactionReady)X="interactive",z1(G,X,Q.cohort);if(J.allLoadingComplete&&Q.cohort&&!j)j=!0,G.push({kind:"loading-complete",cohort:Q.cohort,itemCount:Y.itemCount,loadedCount:Y.loadedCount});return{state:{...Q,phase:X,readinessSignals:Y.signals,loadedCount:Y.loadedCount,itemCount:Y.itemCount,loadingCompleteEmitted:j},outputs:G}}function l7(Q,Y){switch(Y.kind){case"initialize":{if(Q.phase==="disposed")return{state:Q,outputs:[]};if(Q.phase!=="idle"){if(f9(Q.cohort,Y.cohort))return l7(Q,{kind:"update-runtime",effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig});return l7(Q,{kind:"cohort-change",cohort:Y.cohort,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig,itemCount:Y.itemCount})}return o8({state:Q,cohort:Y.cohort,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig,itemCount:Y.itemCount})}case"update-runtime":{if(Q.phase==="idle"||Q.phase==="disposed")return{state:Q,outputs:[]};return{state:{...Q,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig},outputs:[]}}case"cohort-change":{if(Q.phase==="disposed")return{state:Q,outputs:[]};if(f9(Q.cohort,Y.cohort))return l7(Q,{kind:"update-runtime",effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig});let J=[];if(Q.phase!=="idle")J.push({kind:"stage-change",stage:"disposed",status:"entered",cohort:Q.cohort});let G=o8({state:Q,cohort:Y.cohort,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig,itemCount:Y.itemCount});return{state:G.state,outputs:[...J,...G.outputs]}}case"section-controller-resolved":{if(Q.phase!=="booting-section")return{state:{...Q,controllerResolved:!0},outputs:[]};let J=[];return z1(J,"engine-ready",Q.cohort),{state:{...Q,phase:"engine-ready",controllerResolved:!0},outputs:J}}case"update-readiness-signals":return E2(Q,{signals:Y.signals,mode:Y.mode,loadedCount:Y.loadedCount,itemCount:Y.itemCount});case"framework-error":return{state:{...Q,lastFrameworkError:Y.error,readinessSignals:{...Q.readinessSignals,runtimeError:Y.error.recoverable===!0?Q.readinessSignals.runtimeError:!0}},outputs:[{kind:"framework-error",error:Y.error}]};case"dispose":{if(Q.phase==="disposed")return{state:Q,outputs:[]};let J=[];if(Q.phase!=="idle")z1(J,"disposed",Q.cohort);return{state:{...Q,phase:"disposed"},outputs:J}}default:{let J=Y;return{state:Q,outputs:[]}}}}class x9{state=x7();listeners=new Set;getState(){return this.state}dispatch(Q){let Y=l7(this.state,Q);if(this.state=Y.state,Y.outputs.length>0)this.fanOut(Y.outputs);return Y.outputs}subscribe(Q){this.listeners.add(Q);let Y=!0;return()=>{if(!Y)return;Y=!1,this.listeners.delete(Q)}}disposeListeners(){this.listeners.clear()}fanOut(Q){let Y=Array.from(this.listeners),J=Object.freeze(Q.slice());for(let G of Y)try{G(J)}catch(X){console.warn("[SectionEngineCore] listener failed:",X)}}}function a8(Q){let{coordinator:Y,dispatchCoreInput:J}=Q,G=0,X=null,j=null,Z=!1,B=Y.subscribeFrameworkErrors((_)=>{try{J({kind:"framework-error",error:_})}catch($){console.warn("[CoordinatorBridge] framework-error dispatch failed:",$)}});function W(){if(!j)return;try{j()}catch(_){console.warn("[CoordinatorBridge] controller unsubscribe failed:",_)}j=null}async function K(_){if(Z)return;G+=1;let $=G;X=_.cohort;let N=await Y.getOrCreateSectionController({sectionId:_.cohort.sectionId,attemptId:_.cohort.attemptId||void 0,input:{section:_.section,sectionId:_.cohort.sectionId,assessmentId:_.assessmentId,view:_.view},updateExisting:!0,createDefaultController:_.createDefaultController});if($!==G||Z)return;W(),_.onControllerResolved?.(N);let D=N.getCompositionModel;if(_.onCompositionChanged?.(D?.()),typeof N.subscribe==="function")j=N.subscribe((O)=>{if($!==G||Z)return;_.onCompositionChanged?.(D?.())});J({kind:"section-controller-resolved"})}async function U(){if(Z)return;Z=!0,G+=1,W();try{B()}catch($){console.warn("[CoordinatorBridge] framework-error unsubscribe failed:",$)}let _=X;if(X=null,_)try{await Y.disposeSectionController({sectionId:_.sectionId,attemptId:_.attemptId||void 0})}catch($){console.warn("[CoordinatorBridge] section-controller dispose failed:",$)}}return{resolveSectionController:K,dispose:U}}function t8(Q){let{runtimeId:Y,sourceCe:J}=Q,G=Q.host,X=Q.now??(()=>new Date().toISOString());function j(U){let _={stage:U.stage,status:U.status,runtimeId:Y,sectionId:U.cohort?.sectionId,attemptId:U.cohort?.attemptId?U.cohort.attemptId:void 0,timestamp:X(),sourceCe:J};G.dispatchEvent(new CustomEvent("pie-stage-change",{detail:_}))}function Z(U){let _={runtimeId:Y,sectionId:U.cohort.sectionId,attemptId:U.cohort.attemptId?U.cohort.attemptId:void 0,itemCount:U.itemCount,loadedCount:U.loadedCount,timestamp:X(),sourceCe:J};G.dispatchEvent(new CustomEvent("pie-loading-complete",{detail:_}))}function B(U){G.dispatchEvent(new CustomEvent("framework-error",{detail:U.error}))}function W(U){switch(U.kind){case"stage-change":j(U);return;case"loading-complete":Z(U);return;case"framework-error":B(U);return;default:{let _=U;return}}}function K(U){G=U}return{dispatch:W,setHost:K}}function e8(Q){let{bus:Y}=Q;function J(G){switch(G.kind){case"framework-error":Y.reportFrameworkError(G.error);return;case"stage-change":case"loading-complete":return;default:{let X=G;return}}}return{dispatch:J}}function Q6(Q={}){let Y=Q.hook;function J(X){if(!Y)return;try{Y(X)}catch(j){console.warn("[InstrumentationBridge] hook failed:",j)}}function G(X){Y=X}return{dispatch:J,setHook:G}}function Y6(){let Q=new Set;function Y(j){if(j.length===0)return;let Z=Array.from(Q),B=Object.freeze(j.slice());for(let W of Z)try{W(B)}catch(K){console.warn("[SubscriberFanout] listener failed:",K)}}function J(j){Q.add(j);let Z=!0;return()=>{if(!Z)return;Z=!1,Q.delete(j)}}function G(){Q.clear()}function X(){return Q.size}return{emit:Y,subscribe:J,dispose:G,getListenerCount:X}}class k9{core;domEventBridge;frameworkErrorBridge;instrumentationBridge;subscriberFanout;coordinatorBridge;unsubscribeCore;disposed=!1;constructor(Q){this.core=Q.core??new x9,this.domEventBridge=t8({host:Q.host,runtimeId:Q.runtimeId,sourceCe:Q.sourceCe,now:Q.now}),this.frameworkErrorBridge=e8({bus:Q.frameworkErrorBus}),this.instrumentationBridge=Q6({hook:Q.instrumentationHook}),this.subscriberFanout=Y6(),this.coordinatorBridge=Q.coordinator?a8({coordinator:Q.coordinator,dispatchCoreInput:(Y)=>this.dispatchInput(Y)}):null,this.unsubscribeCore=this.core.subscribe((Y)=>{this.routeOutputs(Y)})}getState(){return this.core.getState()}dispatchInput(Q){if(this.disposed)return[];return this.core.dispatch(Q)}subscribe(Q){return this.subscriberFanout.subscribe(Q)}setHost(Q){this.domEventBridge.setHost(Q)}setInstrumentationHook(Q){this.instrumentationBridge.setHook(Q)}resolveSectionController(Q){if(!this.coordinatorBridge)throw Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");return this.coordinatorBridge.resolveSectionController(Q)}async dispose(){if(this.disposed)return;if(this.disposed=!0,this.core.dispatch({kind:"dispose"}),this.unsubscribeCore(),this.subscriberFanout.dispose(),this.coordinatorBridge)await this.coordinatorBridge.dispose()}routeOutputs(Q){for(let Y of Q)this.routeOne(Y);this.subscriberFanout.emit(Q)}routeOne(Q){switch(Q.kind){case"stage-change":case"loading-complete":this.domEventBridge.dispatch(Q);break;case"framework-error":this.domEventBridge.dispatch(Q),this.frameworkErrorBridge.dispatch(Q);break;default:{let Y=Q;return}}this.instrumentationBridge.dispatch(Q)}}var b2={mode:"gather",role:"student"};function O1(Q,Y){return Q!==void 0?Q:Y}function S2(Q){let Y=Q.runtime??{};if(Y.onFrameworkError!==void 0)return Y.onFrameworkError;return Q.onFrameworkError}function C2(Q){let Y=Q.runtime?.tools||{},J=Y.placement||{};return{...Y,placement:{...J}}}function T2(Q){let Y=Q.runtime||{},J=Y.player?{...Y.player}:null;return{...Y,assessmentId:O1(Y.assessmentId,Q.assessmentId),playerType:Y.playerType??"iife",player:J,lazyInit:Y.lazyInit??!0,accessibility:Y.accessibility??null,coordinator:Y.coordinator??null,createSectionController:Y.createSectionController,isolation:Y.isolation??"inherit",env:Y.env??b2,toolConfigStrictness:O1(Y.toolConfigStrictness,Q.toolConfigStrictness)??"error",onFrameworkError:S2({runtime:Q.runtime,onFrameworkError:Q.onFrameworkError}),onStageChange:O1(Y.onStageChange,Q.onStageChange),onLoadingComplete:O1(Y.onLoadingComplete,Q.onLoadingComplete),tools:Q.effectiveToolsConfig}}function J6(Q,Y){let J=Q.assessmentId??"section-demo-direct",G=C2({runtime:Q.runtime}),X=T2({assessmentId:J,runtime:Q.runtime,effectiveToolsConfig:G,toolConfigStrictness:Q.toolConfigStrictness,onFrameworkError:Q.onFrameworkError,onStageChange:Q.onStageChange,onLoadingComplete:Q.onLoadingComplete}),j=Y.resolvePlayerRuntime({effectiveRuntime:X,playerType:String(X.playerType??"iife"),env:X.env??null});return{effectiveToolsConfig:G,effectiveRuntime:X,playerRuntime:j}}import{createPieLogger as f2,isGlobalDebugEnabled as x2}from"@pie-players/pie-players-shared";function y2(Q,Y){if(Q===Y)return 0;let J=Q.compareDocumentPosition(Y);if(J&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(J&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class I9{shellsByElement=new Map;register(Q){let Y=this.shellsByElement.get(Q.element),J={...Q,sortKey:Date.now()};if(Y&&Y.kind===J.kind&&Y.itemId===J.itemId&&Y.canonicalItemId===J.canonicalItemId)return!1;return this.shellsByElement.set(Q.element,J),!0}unregister(Q){return this.shellsByElement.delete(Q)}getOrderedShells(Q){let Y=Array.from(this.shellsByElement.values()).filter((J)=>!Q||J.kind===Q);return Y.sort((J,G)=>y2(J.element,G.element)),Y}getCanonicalIdMap(){let Q={};for(let Y of this.getOrderedShells("item")){if(!Y.itemId)continue;Q[Y.itemId]=Y.canonicalItemId||Y.itemId}return Q}clear(){this.shellsByElement.clear()}}function P1(Q="runtime"){return`${Q}-${Math.random().toString(16).slice(2)}-${Date.now()}`}var k2=f2("section-runtime-engine",()=>x2());class v9{registry=new I9;runtimeId=P1("section-engine");adapter=null;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;loadedRenderableKeys=new Set;attachHost(Q){if(this.adapter){if(this.adapter.setHost(Q.host),Q.instrumentationHook!==void 0)this.adapter.setInstrumentationHook(Q.instrumentationHook);return}this.adapter=new k9({host:Q.host,runtimeId:this.runtimeId,sourceCe:Q.sourceCe,frameworkErrorBus:Q.frameworkErrorBus,coordinator:Q.coordinator,instrumentationHook:Q.instrumentationHook,now:Q.now})}dispatchInput(Q){return this.adapter?.dispatchInput(Q)??[]}subscribe(Q){return this.adapter?.subscribe(Q)??I2}getState(){return this.adapter?.getState()??x7()}getEffectiveRuntime(Q,Y){return J6(Q,Y).effectiveRuntime}setInstrumentationHook(Q){this.adapter?.setInstrumentationHook(Q)}getRuntimeId(){return this.runtimeId}async initialize(Q){this.activeInitToken+=1;let Y=this.activeInitToken;this.coordinator=Q.coordinator,this.sectionId=Q.sectionId,this.attemptId=Q.attemptId;let J=await Q.coordinator.getOrCreateSectionController({sectionId:Q.sectionId,attemptId:Q.attemptId,input:{section:Q.section,sectionId:Q.sectionId,assessmentId:Q.assessmentId,view:Q.view},updateExisting:!0,createDefaultController:Q.createDefaultController});if(Y!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=J,this.replayRegisteredShellsIntoController(J),Q.onCompositionChanged?.(J.getCompositionModel?.()),this.unsubscribeController=J.subscribe?.((G)=>{try{Q.onControllerEvent?.(G)}catch(X){k2.warn("onControllerEvent handler threw",X)}Q.onCompositionChanged?.(J.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(Q){if(!Q.handleContentRegistered)return;let Y=this.registry.getOrderedShells();if(Y.length===0)return;for(let G of Y){let X=G.canonicalItemId||G.itemId;Q.handleContentRegistered({itemId:G.itemId,canonicalItemId:X,contentKind:G.contentKind||G.kind})}let J=Date.now();for(let G of Y){let X=G.canonicalItemId||G.itemId,j=this.getLoadedKey(X,G.contentKind);if(this.loadedRenderableKeys.has(j))Q.handleContentLoaded?.({itemId:G.itemId,canonicalItemId:X,contentKind:G.contentKind||G.kind,timestamp:J})}}getLoadedKey(Q,Y){return`${Y??""}:${Q}`}register(Q){return this.registry.register(Q)}unregister(Q){return this.registry.unregister(Q)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(Q){return this.registry.getCanonicalIdMap()[Q]||this.controller?.getCanonicalItemId?.(Q)||Q}handleContentRegistered(Q){this.controller?.handleContentRegistered?.({itemId:Q.itemId,canonicalItemId:Q.canonicalItemId||Q.itemId,contentKind:Q.contentKind||Q.kind})}handleContentUnregistered(Q){let Y=Q.canonicalItemId||Q.itemId;this.loadedRenderableKeys.delete(this.getLoadedKey(Y,Q.contentKind)),this.controller?.handleContentUnregistered?.({itemId:Q.itemId,canonicalItemId:Y,contentKind:Q.contentKind||Q.kind})}handleContentLoaded(Q){let Y=Q.canonicalItemId||Q.itemId;this.loadedRenderableKeys.add(this.getLoadedKey(Y,Q.contentKind)),this.controller?.handleContentLoaded?.(Q)}handleItemPlayerError(Q){this.controller?.handleItemPlayerError?.(Q)}reportSectionError(Q){this.controller?.reportSectionError?.(Q)}updateItemSession(Q,Y){let J=this.getCanonicalItemId(Q);return this.controller?.updateItemSession?.(J,Y)??null}navigateToItem(Q){return this.controller?.navigateToItem?.(Q)??null}handleFormativeAction(Q){if(!Q?.itemId)return;let Y=this.getCanonicalItemId(Q.itemId);if(Q.action==="retry"){this.controller?.retryFormativeItem?.({itemId:Y});return}this.controller?.recordFormativeTry?.({itemId:Y,outcomes:Q.outcomes})}handleMediaTimeSource(Q){if(Q?.action==="detach"){this.controller?.detachMediaTimeSource?.({origin:Q.origin??"host"});return}if(!Q?.source)return;this.controller?.attachMediaTimeSource?.(Q.source,{origin:Q.origin??"host",renderableId:Q.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}getRegistry(){return this.registry}async dispose(){if(this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null,this.coordinator&&this.sectionId)await this.coordinator.disposeSectionController({sectionId:this.sectionId,attemptId:this.attemptId});if(this.registry.clear(),this.loadedRenderableKeys.clear(),this.controller=null,this.coordinator=null,this.adapter){let Q=this.adapter;this.adapter=null,await Q.dispose()}}}var I2=()=>{};import{connectContextWithRetry as v2,createContext as h2}from"@pie-players/pie-context";var m2=h2(Symbol.for("pie.sectionRuntimeEngineHostContext"));function G6(Q,Y){return v2(Q,m2,Y)}var u2=(Q)=>{console.error("[pie-assessment-toolkit] onStageChange handler threw",Q)};function X6(Q,Y){if(Q.isSuppressed())return!1;Q.dispatchDomEvent(Y);let J=Q.getOnStageChange();if(J)try{J(Y)}catch(G){(Q.logHandlerError??u2)(G)}return!0}function i7(Q,Y){if(typeof Q==="function")return Q;if(Q===null)return null;return typeof Y==="function"?Y:null}function Z6(Q={}){let Y=Q.frameDeadlineMs??100,J=!1,G=null,X=null,j=null,Z=null,B=null;function W(){if(J=!1,X!==null)Z?.(X),X=null;if(j!==null)B?.(j),j=null;Z=null,B=null}function K($){if(!J)return;if($==="frame")X=null;if($==="timer")j=null;let N=G;G=null,W(),N?.()}function U($){if(G=$,J)return;J=!0;let N=globalThis,D=i7(Q.requestFrame,N.requestAnimationFrame);Z=i7(Q.cancelFrame,N.cancelAnimationFrame);let O=i7(Q.setTimer,N.setTimeout);if(B=i7(Q.clearTimer,N.clearTimeout),D){let F=D(()=>K("frame"));if(!J)return;if(X=F,O){let L=O(()=>K("timer"),Y);if(J)j=L}return}let P=i7(Q.queueMicrotaskFn,N.queueMicrotask);if(P){P(()=>K("microtask"));return}if(O){let F=O(()=>K("timer"),0);if(J)j=F;return}K("microtask")}function _(){if(!J)return;G=null,W()}return{schedule:U,cancel:_,isPending:()=>J}}function j6(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function B6(Q){Q.lastSessionEventSignatureByItemId.clear(),Q.lastMetadataSignatureByItemId.clear()}function q6(Q){let{state:Y,itemId:J,payload:G}=Q;if(g2(G)){let Z=c2(G);if(Y.lastMetadataSignatureByItemId.get(J)===Z)return!1;Y.lastMetadataSignatureByItemId.set(J,Z)}let X=p2(G);if(Y.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Y.lastSessionEventSignatureByItemId.set(J,X),!0}function p2(Q){let Y={...Q};delete Y.timestamp,delete Y.sourceRuntimeId;try{return JSON.stringify(Y)}catch{return String(Y.itemId||"")}}function g2(Q){return Q.intent==="metadata-only"}function c2(Q){try{return JSON.stringify({itemId:Q.itemId,canonicalItemId:Q.canonicalItemId,intent:Q.intent,complete:Q.complete??null,component:Q.component??null})}catch{return String(Q.itemId||"")}}var d2=(Q,Y)=>{if(customElements.get(Q))return;try{customElements.define(Q,Y)}catch(J){if(!(J instanceof DOMException&&J.name==="NotSupportedError"||J&&typeof J==="object"&&J.name==="NotSupportedError")||!customElements.get(Q))throw J}},Y4=p9('<div class="pie-assessment-toolkit-error svelte-15pthty" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-15pthty"> </div> <div class="pie-assessment-toolkit-error-message svelte-15pthty"> </div> <pre class="pie-assessment-toolkit-error-details svelte-15pthty"> </pre></div>'),J4=p9('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),G4={hash:"svelte-15pthty",code:`.pie-assessment-toolkit-anchor.svelte-15pthty {display:none;}.pie-assessment-toolkit-error.svelte-15pthty {margin:0.75rem;padding:0.75rem 1rem;border-radius:0.5rem;border:1px solid
224
+ color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 40%, transparent);background:color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 12%, transparent);color:var(--pie-incorrect, #7f1d1d);font-size:0.9rem;}.pie-assessment-toolkit-error-title.svelte-15pthty {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-15pthty {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-15pthty {margin:0;white-space:pre-wrap;word-break:break-word;}`};function w6(Q,Y){V6(Y,!0),N6(Q,G4);let J=P1("toolkit"),G=new v9,X=m(null),j=new u7,Z={mode:"gather",role:"student"},B={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},W=f(Y,"assessmentId",7,""),K=f(Y,"section",7,null),U=f(Y,"sectionId",7,""),_=f(Y,"attemptId",7,""),$=f(Y,"env",23,()=>({})),N=f(Y,"ndsIcons",7,!1),D=f(Y,"locale",7,""),O=f(Y,"lazyInit",7,!0),P=f(Y,"toolConfigStrictness",7,"error"),F=f(Y,"tools",23,()=>({})),L=f(Y,"toolContextResolvers",7,null),C=f(Y,"enabledTools",7,""),v=f(Y,"toolRegistry",7,null),k=f(Y,"accessibility",23,()=>({})),p=f(Y,"player",7,null),R=f(Y,"playerType",7,""),g=f(Y,"coordinator",7,null),B7=f(Y,"createSectionController",7,null),q7=f(Y,"onFrameworkError",7,null),W7=f(Y,"errorRenderer",7,null),w7=f(Y,"onStageChange",7,null),s7=f(Y,"assessment",7,null),n7=f(Y,"currentItemRef",7,null),r7=f(Y,"pnpEnforcement",7,null),K7=f(Y,"isolation",7,"inherit"),k7=m(null),d=m(null),G7=m(null),g9=null,I7=null,v7=null,o7=null,h7=null,a7=null,t7=m(0),b1=m(null),o=m(null),S1=m("Unable to initialize assessment toolkit."),C1=m(h9([])),c9="",T1="",d9=null,y1=!1,l9=!1,i9=m(""),s9=null,n9=Z6(),U7=[],e7=new Map,f1=new WeakMap,r9=j6(),n=n2({sourceCe:"pie-assessment-toolkit",sourceCeShape:"toolkit",runtimeId:J,sectionId:h(()=>U()||void 0),attemptId:h(()=>_()||void 0),emit:(q)=>{X6({isSuppressed:()=>A(X)!==null,dispatchDomEvent:(V)=>V7("pie-stage-change",V),getOnStageChange:()=>w7()},q)}}),o9=m(h9(h(()=>`${U()}|${_()}`))),Q1=m(!1),t=m(!1),x1=m(!1),k1=m(!1);function R6(){if(!A(k7))return null;let q=A(k7).getRootNode();if(q&&"host"in q)return q.host;return A(k7).parentElement}let x=c(()=>R6());function V7(q,V){if(!A(x)){U7=[...U7,{name:q,detail:V}];return}y9(A(x),q,V)}b(()=>{if(!A(x))return;if(U7.length===0)return;let q=U7;U7=[],queueMicrotask(()=>{let V=A(x);if(!V){U7=[...q,...U7];return}for(let M of q)y9(V,M.name,M.detail)})});function E6(q){if(!W7())return{title:"Unable to initialize assessment toolkit.",details:q.details.length>0?q.details:[q.message]};try{let V=W7()(q)||{};return{title:typeof V.title==="string"&&V.title.trim().length>0?V.title:"Unable to initialize assessment toolkit.",details:Array.isArray(V.details)&&V.details.length>0?V.details.map((M)=>String(M)):q.details.length>0?q.details:[q.message]}}catch(V){let M=V instanceof Error&&V.message.trim().length>0?V.message:String(V||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...q.details,`Error renderer failed: ${M}`]}}}function R7(q){let V=g1({kind:q.kind,source:q.source,error:q.error,recoverable:q.recoverable});return j.reportFrameworkError(V),V}function b6(q){if(q?.type==="timed-media-policy-degraded"){let M=q.degradations||[];j.reportFrameworkError(B1({kind:"timed-media",severity:"warning",source:"pie-assessment-toolkit",message:"A timed-media playback policy degraded to advisory: the media time source does not report the capability it needs.",details:M.map((z)=>z?.message).filter((z)=>typeof z==="string"),recoverable:!0}));return}if(q?.type!=="timed-media-invalid")return;let V=q.errors||[];j.reportFrameworkError(B1({kind:"timed-media",severity:"error",source:"pie-assessment-toolkit",message:'This section declares sectionType: "timed-media" but its timedMedia data is not deliverable; the section renders without cue behavior.',details:V.map((M)=>M?.message).filter((M)=>typeof M==="string"),recoverable:!1}))}function S6(q){if(q?.type!=="timed-media-audio-started")return;if(!A(S))return;u8(A(S).getServiceBundle().ttsService)}function C6(q){return q==="coordinator-init"||q==="runtime-init"||q==="tool-config"}function a9(q){if(!q7())return;try{q7()(q),c9=`${q.kind}|${q.source}|${q.message}`}catch(V){console.error(`[pie-framework:${q.kind}:${q.source}] framework error hook failed`,V)}}let t9=new WeakSet;b(()=>{let q=j.subscribeFrameworkErrors((V)=>{if(console.error(K0(V),V.cause),C6(V.kind)&&!t9.has(V)){let M=E6(V);E(o,V,!0),E(S1,M.title,!0),E(C1,M.details,!0)}V7("framework-error",V),a9(V)});return()=>{q()}}),b(()=>{let q=g();if(!q||A(S)!==q)return;if(typeof q.subscribeFrameworkErrors!=="function")return;return h(()=>q.subscribeFrameworkErrors((V)=>{t9.add(V),j.reportFrameworkError(V)}))}),b(()=>{let q=g(),V=v();if(!q||A(S)!==q)return;if(typeof q.adoptToolRegistry!=="function")return;h(()=>q.adoptToolRegistry(V))}),b(()=>{if(!A(o))return;let q=`${A(o).kind}|${A(o).source}|${A(o).message}`;if(c9===q)return;a9(A(o))});function T6(q){let V=5381;for(let M=0;M<q.length;M+=1)V=(V<<5)+V^q.charCodeAt(M);return(V>>>0).toString(36)}function r(q){return q&&typeof q==="object"?q:{}}function y6(q){let V=r(q.section),M=typeof V.identifier==="string"?V.identifier:"",z=typeof q.sectionId==="string"?q.sectionId:"";return M||z}function f6(q){return typeof q.currentItemIndex==="number"?q.currentItemIndex:-1}function x6(q){return(Array.isArray(q.renderables)?q.renderables:[]).map((M,z)=>{let H=r(M),I=r(H.entity),Q7=typeof I.id==="string"&&I.id||`renderable-${z}`,j1=r(I.config),p1=typeof I.version==="string"&&I.version||(typeof I.version==="number"?String(I.version):"")||(typeof j1.version==="string"?j1.version:"");return{id:Q7,version:p1}})}function k6(q){let V=r(q.itemSessionsByItemId);return Object.keys(V).sort((M,z)=>M.localeCompare(z)).map((M)=>{let z=r(V[M]),H=typeof z.id==="string"?z.id:"",I=Array.isArray(z.data)?z.data:[],Q7="";try{Q7=T6(JSON.stringify(I))}catch{Q7=String(I.length)}return{itemId:M,sessionId:H,payloadSignature:Q7}})}function I6(q){let V=r(r(q.formative).states);return Object.entries(V).map(([M,z])=>{let H=r(z),I=r(H.lastOutcome).correctness??"";return`${M}:${H.tryCount??0}:${H.revealed===!0?1:0}:${String(I)}:${String(H.revealOverride??"")}`}).sort().join("|")}function v6(q){let V=q.timedMedia;return Q4(V)}function h6(q){let V=r(q),M=x6(V).map((H)=>`${H.id}:${H.version}`).join("|"),z=k6(V).map((H)=>`${H.itemId}:${H.sessionId}:${H.payloadSignature}`).join("|");return{sectionId:y6(V),currentItemIndex:f6(V),renderableSignature:M,itemSessionSignature:z,formativeSignature:I6(V),timedMediaSignature:v6(V)}}function m6(q){let V=h6(q);return`${V.sectionId}|${V.currentItemIndex}|${V.renderableSignature}|${V.itemSessionSignature}|${V.formativeSignature}|${V.timedMediaSignature}`}function e9(q){return q==="iife"||q==="esm"||q==="preloaded"||q==="custom"}function u6(q,V){let M=q?.type,z=e9(M)?M:e9(V)?V:q?.tagName?"custom":"iife",H=q?.tagName?.trim();if(z==="custom"&&!H)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:z,tagName:H||B[z],version:q?.version,source:q?.source,loaderConfig:q?.loaderConfig,loaderOptions:q?.loaderOptions,isDefault:!q&&!V}}function Q0(q){let V=q||{},M=typeof V.mode==="string"&&V.mode.trim()?V.mode.trim():Z.mode,z=typeof V.role==="string"&&V.role.trim()?V.role.trim():Z.role;return{mode:M,role:z}}function p6(q){let V=Q0(q);if(V.mode==="author")return"author";if(V.role==="instructor")return"scorer";return"candidate"}async function g6(){if(B7())return B7()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function I1(){let q=F()||{},V=L6(C());if(V.length===0)return q;let M=q.placement||{},z=Array.isArray(M.section)?M.section:null;if(z&&z.length>0)return q;return{...q,placement:{...M,section:V}}}function c6(){return A0(I1(),{strictness:P(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:v()}).config}function d6(){let q="",V="";try{q=JSON.stringify(I1())}catch{q="[unserializable-tools]"}try{V=JSON.stringify(Object.entries(L()??{}).map(([M,z])=>[M,typeof z]))}catch{V="[unserializable-resolvers]"}return[W()||"",String(P()||"error"),q,V].join("|")}function Y0(q){return q==="on"||q==="off"?q:null}function l6(q,V){let M=Y0(q);if(M)return M;if(V&&typeof V==="object"){let H=V.pnpEnforcement;return Y0(typeof H==="string"?H:null)}return null}function i6(q){let V=W()||K()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new T9({assessmentId:V,lazyInit:O(),toolConfigStrictness:P(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:q,toolRegistry:v(),toolContextResolvers:L(),accessibility:k(),frameworkErrorBus:j})}function J0(q){try{return JSON.stringify(q??null)}catch{return"[unserializable]"}}function G0(){return{signatures:{assessmentId:W()||"",toolConfigStrictness:String(P()||"error"),lazyInit:String(O()),tools:J0({...I1(),pnpEnforcement:void 0}),accessibility:J0(k())},toolRegistry:v()}}function s6(){let q=d9;if(!q)return[];let V=G0(),M=Object.keys(V.signatures).filter((z)=>V.signatures[z]!==q.signatures[z]);if(V.toolRegistry!==q.toolRegistry)M.push("toolRegistry");return M}function n6(q){if(l9)return;l9=!0,console.warn(`[pie-assessment-toolkit] ${q.join(", ")} changed after a section initialized with the coordinator this toolkit built, and that coordinator keeps the values it was built with. Set these inputs no later than the section, pass a coordinator of your own, or update this one from toolkit-ready with updateToolConfig(...) or updateToolsPlacement(...). Reported once per toolkit.`)}function Y1(){let q=A(d);if(!q)return Promise.resolve();return E(d,null),q.dispose()}function J1(q){R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:q,recoverable:!0})}let S=c(()=>{if(K7()!=="force"&&A(G7)?.coordinator)return A(G7).coordinator;return g()||A(d)}),r6=c(()=>K()!=null);b(()=>{A(x),g(),K7(),A(G7),L(),A(r6),F(),C(),W(),P(),O(),k(),v(),h(()=>{if(!A(x))return;if(g()){if(A(d))Y1().catch(J1);I7=null;return}if(K7()!=="force"&&A(G7)?.coordinator){if(A(d))Y1().catch(J1);I7=null;return}if(A(d)){let q=s6();if(q.length>0&&y1)n6(q);else if(q.length>0&&K())Y1().catch(J1)}if(A(d)&&I7!==L()){try{A(d).setToolContextResolvers(L()),I7=L()}catch(q){R7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:q})}return}if(!A(d)){let q=d6();if(T1===q)return;try{let V=c6();E(d,i6(V),!0),d9=G0(),y1=!1,I7=L(),T1="",E(o,null),E(S1,"Unable to initialize assessment toolkit."),E(C1,[],!0)}catch(V){E(d,null),T1=q,R7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:V})}}})});let G1=t2(),v1=m(0);b(()=>G1.subscribe(()=>{E(v1,A(v1)+1)})),b(()=>{let q=typeof D()==="string"?D().trim():"";h(()=>{Promise.resolve(G1.setLocale(q||e2)).catch((V)=>{R7({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:V instanceof Error?V:Error(String(V))})})})});let X7=c(()=>W()||A(S)?.assessmentId||""),e=c(()=>U()||K()?.identifier||`section-${A(X7)||"default"}`),h1=c(()=>Q0($())),o6=c(()=>p6(A(h1))),E7=c(()=>u6(p(),R())),m7=c(()=>r2({player:A(E7),component:"pie-assessment-toolkit"})),X1=c(()=>{if(!A(S))return null;let q=A(S).getServiceBundle();return{toolkitCoordinator:A(S),toolCoordinator:A(S).toolCoordinator,ttsService:q.ttsService,highlightCoordinator:q.highlightCoordinator,catalogResolver:q.catalogResolver,elementToolStateStore:q.elementToolStateStore,assessmentId:A(X7),sectionId:A(e),itemPlayer:A(E7),ndsIcons:N()===!0,locale:(A(v1),G1.getLocale()),i18n:G1,reportSessionChanged:(V,M)=>{let z=G.updateItemSession(V,M);j0({itemId:V,result:z,fallbackSession:M})},reportSectionError:(V)=>{G.reportSectionError({source:"section-runtime",error:V,timestamp:Date.now()})}}}),Z1=c(()=>{if(!A(S))return null;return{runtimeId:J,coordinator:A(S)}});function a6(q){let V=m6(q);if(V===A(i9))return;E(i9,V,!0),E(t7,A(t7)+1),E(b1,q,!0),V7("composition-changed",{composition:A(b1),version:A(t7)})}function m1(q){s9=q??G.getCompositionModel(),n9.schedule(()=>{a6(s9)})}function u1(q){if(!q)return;let V=f1.get(q);if(!V)return;for(let M of V)M();f1.delete(q)}function X0(){for(let q of e7.values())u1(q.element)}function Z0(q){if(u1(q.element),!A(S))return;let V=A(S).getServiceBundle().catalogResolver;f1.set(q.element,[V.registerOwner({owner:{kind:q.kind,itemId:q.itemId,canonicalItemId:q.canonicalItemId,assessmentId:A(X7),sectionId:A(e)},entity:q.item})])}function t6(){X0();for(let q of e7.values())Z0(q)}function j0(q){let M={...q.result?.eventDetail||q.fallbackSession,itemId:q.itemId,canonicalItemId:q.canonicalItemId||q.itemId,sourceRuntimeId:J};if(!q6({state:r9,itemId:q.itemId,payload:M}))return;V7("session-changed",M)}function e6(q){if(!(q instanceof HTMLElement))return!1;return i2(q,u9)?.runtimeId===J}function A7(q){return q.detail??null}function Q3(q,V){for(let M of V)q.addEventListener(M.name,M.handler);return()=>{for(let M of V)q.removeEventListener(M.name,M.handler)}}b(()=>{if(!A(x))return;if(K7()==="force"){E(G7,null);return}return P6(A(x),(q)=>{if(q.runtimeId===J)return;E(G7,q,!0)})}),b(()=>{let q=A(x);return h(()=>{if(!q){E(X,null);return}let V=G6(q,(M)=>{if(M.engine===A(X))return;E(X,M.engine,!0)});return()=>{V(),E(X,null)}})}),b(()=>{let q=A(S);if(!q)return;return h(()=>m8({ttsService:q.getServiceBundle().ttsService,listenerId:`timed-media-audio-handoff:${J}`,silence:()=>G.requestMediaPauseForCompetingAudio()}))}),b(()=>{let q=K7()!=="force"&&A(G7)?A(G7).runtimeId:null,V=q?"inherited":"owned";if(V!==g9)g9=V,V7(V==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:J,parentRuntimeId:q})}),b(()=>{let q=A(e),V=_()||"";B6(r9)});let Y3=c(()=>A(Z1)!==null),J3=c(()=>A(X1)!==null);b(()=>{if(!A(x)||!A(Y3))return;let q=h(()=>A(Z1));if(!q)return;return h7=new W6(A(x),{context:u9,initialValue:q}),h7.connect(),a7=new K6(A(x)),a7.attach(),()=>{a7?.detach(),a7=null,h7?.disconnect(),h7=null}}),b(()=>{if(!A(Z1))return;h7?.setValue(A(Z1))}),b(()=>{if(!A(x))return;A(x).setAttribute("data-item-player-type",A(E7).type),A(x).setAttribute("data-item-player-tag",A(E7).tagName),A(x).setAttribute("data-env-mode",String(A(h1)?.mode||"")),A(x).setAttribute("data-env-role",String(A(h1)?.role||""))}),b(()=>{if(!A(x)||!A(J3))return;let q=h(()=>A(X1));if(!q)return;return v7=new W6(A(x),{context:O6,initialValue:q}),v7.connect(),o7=new K6(A(x)),o7.attach(),()=>{o7?.detach(),o7=null,v7?.disconnect(),v7=null}}),b(()=>{if(A(X1))v7?.setValue(A(X1))}),b(()=>{return A(S),A(X7),A(e),t6(),()=>{X0()}}),b(()=>{if(!A(x))return;return s2({host:A(x),instrumentationProvider:A(m7),component:"pie-assessment-toolkit",eventMap:o2,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:A(X7),sectionId:A(e),attemptId:_()||void 0}})}),b(()=>{s7(),n7(),r7(),F();let q=A(S);if(!q)return;if(q!==A(d))return;h(()=>{q.setPnpEnforcement(l6(r7(),F())),q.updateAssessment(s7()),q.updateCurrentItemRef(n7())})}),b(()=>{if(!A(S))return;return A(S).subscribeTelemetry(({eventName:q,payload:V})=>{if(!a2(A(m7)))return;if(!A(m7).isReady())return;let M=q,z=new Date().toISOString(),H={...V||{},instrumentationLayer:"toolkit",assessmentId:A(X7),sectionId:A(e),attemptId:_()||void 0,component:"pie-assessment-toolkit",sourceEventName:q,timestamp:z};A(m7).trackEvent(M,H);let I=V&&typeof V.errorType==="string"?V.errorType:void 0;if(!q.endsWith("-error")&&!I)return;let Q7=V&&typeof V.message==="string"?V.message:`Toolkit telemetry error: ${q}`;A(m7).trackError(Error(Q7),{component:"pie-assessment-toolkit",errorType:I||"ToolkitTelemetryError",...H})})}),b(()=>{if(!K()||!A(S))return;let q=!1;if(A(S)===h(()=>A(d)))y1=!0;return G.initialize({coordinator:A(S),section:K(),sectionId:A(e),assessmentId:A(X7),attemptId:_()||void 0,view:A(o6),createDefaultController:g6,onCompositionChanged:(V)=>{if(q)return;m1(V)},onControllerEvent:(V)=>{if(q)return;S6(V),b6(V)}}).then(()=>{if(q)return;V7("toolkit-ready",{runtimeId:J,assessmentId:A(X7),sectionId:A(e),itemPlayer:A(E7),coordinator:A(S)}),V7("section-ready",{sectionId:A(e)}),h(()=>{E(k1,!0)})}).catch((V)=>{if(q)return;h(()=>{if(!A(t))E(t,!0),n.enter("engine-ready","skipped");n.enter("interactive","failed")}),G.reportSectionError({source:"section-runtime",error:V,timestamp:Date.now()}),R7({kind:"runtime-init",source:"pie-assessment-toolkit",error:V})}),()=>{q=!0}}),b(()=>{if(!A(x))return;let q=A(x),V=(z)=>{if(!e6(z.target))return!1;return z.stopPropagation(),!0};return Q3(q,[{name:p8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.element||!H?.itemId)return;let I=G.register(H);if(e7.set(H.element,H),Z0(H),G.handleContentRegistered(H),I)m1()}},{name:g8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;let I=H?.element?G.unregister(H.element):!1;if(u1(H.element),H.element)e7.delete(H.element);if(G.handleContentUnregistered(H),I)m1()}},{name:c8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;let I=G.updateItemSession(H.itemId,H.session);j0({itemId:H.itemId,canonicalItemId:G.getCanonicalItemId(H.itemId),result:I,fallbackSession:H.session})}},{name:d8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;G.handleContentLoaded({itemId:H.itemId,canonicalItemId:H.canonicalItemId,contentKind:H.contentKind,detail:H.detail,timestamp:Date.now()})}},{name:l8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;G.handleItemPlayerError({itemId:H.itemId,canonicalItemId:H.canonicalItemId,contentKind:H.contentKind,error:H.error,timestamp:Date.now()})}},{name:i8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;if(H.action!=="check"&&H.action!=="retry")return;G.handleFormativeAction({itemId:H.canonicalItemId||H.itemId,action:H.action,outcomes:H.outcomes})}},{name:s8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.renderableId)return;if(H.action!=="attach"&&H.action!=="detach")return;G.handleMediaTimeSource({renderableId:H.renderableId,action:H.action,source:H.source,origin:H.origin})}}])});async function G3(){if(!A(S))throw Error("Coordinator not initialized");await A(S).waitUntilReady()}function X3(){if(!A(S))throw Error("Coordinator not initialized");return A(S).getServiceBundle()}function Z3(q){if(!A(S))throw Error("Coordinator not initialized");A(S).setHooks(q)}function j3(q){return G.navigateToItem(q)}function B3(){return G.getCompositionModel()}function q3(){return A(E7)}async function W3(){await G.persist()}async function K3(){await G.hydrate()}b(()=>{return()=>{h(()=>{if(n.getCurrent()!==null)n.enter("disposed")})}}),b(()=>{let q=`${U()}|${_()}`;h(()=>{if(q===A(o9))return;if(n.getCurrent()!==null)n.enter("disposed");n.reset({sectionId:U()||void 0,attemptId:_()||void 0}),E(o9,q),E(Q1,!1),E(t,!1),E(x1,!1),E(k1,!1)})}),b(()=>{let q=A(t)&&A(k1);h(()=>{if(!q)return;if(A(x1))return;E(x1,!0),n.enter("interactive")})}),b(()=>{let q=A(t7)>0||A(b1)!==null;h(()=>{if(!A(Q1)&&q)E(Q1,!0),n.enter("composed")})}),b(()=>{if(!A(S))return;if(!A(Q1))return;if(A(t))return;let q=A(S),V=!1;return q.waitUntilReady().then(()=>{if(V)return;h(()=>{if(A(t))return;E(t,!0),n.enter("engine-ready")})}).catch(()=>{if(V)return;h(()=>{if(A(t))return;E(t,!0),n.enter("engine-ready","failed")})}),()=>{V=!0}}),b(()=>{return()=>{n9.cancel(),G.dispose().catch((q)=>{R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:q,recoverable:!0})}).then(()=>Y1()).catch(J1).finally(()=>{j.dispose()})}});var U3={waitUntilReady:G3,getServiceBundle:X3,setHooks:Z3,navigateToItem:j3,getCompositionModel:B3,getItemPlayerConfig:q3,persist:W3,hydrate:K3,get assessmentId(){return W()},set assessmentId(q){W(q),y()},get section(){return K()},set section(q){K(q),y()},get sectionId(){return U()},set sectionId(q){U(q),y()},get attemptId(){return _()},set attemptId(q){_(q),y()},get env(){return $()},set env(q){$(q),y()},get ndsIcons(){return N()},set ndsIcons(q){N(q),y()},get locale(){return D()},set locale(q){D(q),y()},get lazyInit(){return O()},set lazyInit(q){O(q),y()},get toolConfigStrictness(){return P()},set toolConfigStrictness(q){P(q),y()},get tools(){return F()},set tools(q){F(q),y()},get toolContextResolvers(){return L()},set toolContextResolvers(q){L(q),y()},get enabledTools(){return C()},set enabledTools(q){C(q),y()},get toolRegistry(){return v()},set toolRegistry(q){v(q),y()},get accessibility(){return k()},set accessibility(q){k(q),y()},get player(){return p()},set player(q){p(q),y()},get playerType(){return R()},set playerType(q){R(q),y()},get coordinator(){return g()},set coordinator(q){g(q),y()},get createSectionController(){return B7()},set createSectionController(q){B7(q),y()},get onFrameworkError(){return q7()},set onFrameworkError(q){q7(q),y()},get errorRenderer(){return W7()},set errorRenderer(q){W7(q),y()},get onStageChange(){return w7()},set onStageChange(q){w7(q),y()},get assessment(){return s7()},set assessment(q){s7(q),y()},get currentItemRef(){return n7()},set currentItemRef(q){n7(q),y()},get pnpEnforcement(){return r7()},set pnpEnforcement(q){r7(q),y()},get isolation(){return K7()},set isolation(q){K7(q),y()}},B0=J4(),q0=m9(B0);M6(q0,(q)=>E(k7,q),()=>A(k7));var V3=w1(q0,2);{var A3=(q)=>{var V=Y4(),M=_6(V),z=L1(M,!0),H=w1(M,2),I=L1(H,!0),Q7=w1(H,2),j1=L1(Q7,!0);U6(V),$6((p1)=>{E1(z,A(S1)),E1(I,A(o).message),E1(j1,p1)},[()=>A(C1).join(`
225
+ `)]),R1(q,V)},_3=(q)=>{var V=F6(),M=m9(V);D6(M,Y,"default",{},null),R1(q,V)};H6(V3,(q)=>{if(A(o)&&!A(o).recoverable)q(A3);else q(_3,-1)})}return R1(Q,B0),A6(U3)}d2("pie-assessment-toolkit",z6(w6,{assessmentId:{attribute:"assessment-id",type:"String"},section:{attribute:"section",type:"Object"},sectionId:{attribute:"section-id",type:"String"},attemptId:{attribute:"attempt-id",type:"String"},env:{attribute:"env",type:"Object"},ndsIcons:{attribute:"nds-icons",type:"Boolean"},locale:{attribute:"locale",type:"String"},lazyInit:{attribute:"lazy-init",type:"Boolean"},toolConfigStrictness:{attribute:"tool-config-strictness",type:"String"},tools:{attribute:"tools",type:"Object"},toolContextResolvers:{type:"Object"},enabledTools:{attribute:"enabled-tools",type:"String"},toolRegistry:{type:"Object"},accessibility:{type:"Object"},player:{attribute:"player",type:"Object"},playerType:{attribute:"player-type",type:"String"},coordinator:{type:"Object"},createSectionController:{type:"Object"},onFrameworkError:{type:"Object"},errorRenderer:{type:"Object"},onStageChange:{type:"Object"},assessment:{type:"Object"},currentItemRef:{type:"Object"},pnpEnforcement:{attribute:"pnp-enforcement",type:"String"},isolation:{type:"Object"}},["default"],["waitUntilReady","getServiceBundle","setHooks","navigateToItem","getCompositionModel","getItemPlayerConfig","persist","hydrate"],{mode:"open"},l2));export{w6 as default};