@pie-players/pie-assessment-toolkit 1.0.0-beta.7 → 1.0.0-beta.8
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.
- package/custom-elements.json +7 -0
- package/dist/components/ItemScope.custom-element.js +1 -1
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +7 -7
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-bsww9e8f.js +4 -0
- package/dist/components/chunks/{ItemToolBar-pxan157g.js → ItemToolBar-gsb96731.js} +2 -2
- package/dist/components/chunks/ItemToolBar-na4e5vwt.js +2 -0
- package/dist/components/chunks/{ItemToolBar-xwjrpdmz.js → ItemToolBar-wcw4yxjy.js} +1 -1
- package/dist/components/chunks/ItemToolBar-x998kkvy.js +2 -0
- package/dist/components/chunks/ItemToolBar-zvy0hskj.js +40 -0
- package/dist/components/chunks/sre-engine-wazxma67.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/runtime/SectionControllerBinding.d.ts +11 -0
- package/dist/runtime/SectionControllerBinding.js +8 -0
- package/dist/runtime/registration-events.d.ts +28 -1
- package/dist/runtime/registration-events.js +19 -0
- package/dist/runtime/shell-event-bridge.d.ts +7 -1
- package/dist/runtime/shell-event-bridge.js +44 -1
- package/dist/runtime/shell-scope.d.ts +2 -2
- package/dist/runtime/shell-scope.js +14 -5
- package/dist/services/SSMLExtractor.js +8 -23
- package/dist/services/ToolRegistry.d.ts +11 -3
- package/dist/services/ToolRegistry.js +8 -4
- package/dist/services/ToolkitCoordinator.d.ts +12 -47
- package/dist/services/ToolkitCoordinator.js +45 -284
- package/dist/services/section-controller-types.d.ts +40 -0
- package/dist/services/tool-config-validation.d.ts +1 -1
- package/dist/services/tool-context.js +94 -11
- package/dist/services/tool-icons.js +2 -0
- package/dist/services/tool-provider-defaults.d.ts +13 -0
- package/dist/services/tool-provider-defaults.js +20 -0
- package/dist/services/tts/browser-provider.js +3 -1
- package/dist/services/tts/tts-lifecycle.d.ts +142 -0
- package/dist/services/tts/tts-lifecycle.js +341 -0
- package/dist/tools/content-surfaces.d.ts +35 -0
- package/dist/tools/content-surfaces.js +35 -0
- package/dist/tools/registration.d.ts +2 -0
- package/dist/tools/registration.js +5 -0
- package/package.json +8 -8
- package/dist/components/chunks/ItemToolBar-4vq9nbxz.js +0 -2
- package/dist/components/chunks/ItemToolBar-f971t0cw.js +0 -4
- package/dist/components/chunks/ItemToolBar-n05xjkp8.js +0 -2
- package/dist/components/chunks/ItemToolBar-rgmvw9sm.js +0 -40
- package/dist/components/chunks/sre-engine-dq0w45fv.js +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as F8,c as Y5,d as Z4,e as Q4,i as J4,j as Y4,k as X4,l as G4,m as j4,n as N8,o as P8}from"./chunks/ItemToolBar-x998kkvy.js";import{t as A1,u as C7,v as _0,w as e1,x as s0}from"./chunks/ItemToolBar-na4e5vwt.js";import{A as u1,B as p1,C as d,D as k,E as n,F as m,G as g1,H as c1,I as T7,J as X5,K as G5,L as y,M as d1,N as F,O as I,R as k7,S as i1,T as j5,U as B5,V as l1,Z as s1,_ as n1,ea as r1,fa as f,ga as a1,ha as o1,ia as W5,la as x7,oa as t1,qa as S1,ra as p0,z as m1}from"./chunks/ItemToolBar-bsww9e8f.js";import{sa as D9,ta as _9}from"./chunks/ItemToolBar-gsb96731.js";import{va as b3}from"./chunks/ItemToolBar-wcw4yxjy.js";import{coerceBooleanAttributes as JQ}from"@pie-players/pie-players-shared/ui/attribute-coercion";import{ContextProvider as y7,interfaceLocaleContext as YQ,requestContext as v1}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as XQ,resolveInstrumentationProvider as GQ,TOOLKIT_INSTRUMENTATION_EVENT_MAP as jQ}from"@pie-players/pie-players-shared/pie";import{commitPendingSessions as h1,createPieLogger as BQ,isGlobalDebugEnabled as WQ,isInstrumentationProvider as VQ}from"@pie-players/pie-players-shared";import{createPieI18n as KQ,DEFAULT_LOCALE as qQ,defaultContentLanguage as UQ,stampInterfaceLocale as $Q}from"@pie-players/pie-players-shared/i18n";import{settleAll as MZ}from"@pie-players/pie-players-shared/promise";var Z6="error";function P5(Z){if(Z==="off"||Z==="warn"||Z==="error")return Z;return Z6}function o(Z){return Z}function Q6(Z){if(!Z)return new Map;return new Map(Z.getAllTools().slice().sort((Q,J)=>Q.toolId.localeCompare(J.toolId)).map((Q)=>[Q.toolId,Q]))}function J6(Z,Q,J,Y){if(!Q||!J?.sanitizeConfig)return Q;try{let X=J.sanitizeConfig(Q);if(!X||typeof X!=="object"||Array.isArray(X))return Y.push(o({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Z}`,message:`Config sanitizer of tool "${Z}" must return an object.`,toolId:Z})),Q;return X}catch(X){return Y.push(o({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Z}`,message:`Config sanitizer of tool "${Z}" failed: ${X instanceof Error?X.message:String(X)}`,toolId:Z})),Q}}function Y6(Z,Q,J,Y){if(!Q||!J?.validateConfig)return;try{let X=J.validateConfig(Q);if(!Array.isArray(X)){Y.push(o({code:"tools.invalidProviderValidation",severity:"error",path:`providers.${Z}`,message:`Config validator of tool "${Z}" must return an array.`,toolId:Z}));return}for(let G of X)Y.push({...G,path:G.path||`providers.${Z}`,toolId:G.toolId||Z})}catch(X){Y.push(o({code:"tools.providerValidateFailed",severity:"error",path:`providers.${Z}`,message:`Config validator of tool "${Z}" failed: ${X instanceof Error?X.message:String(X)}`,toolId:Z}))}}function X6(Z,Q,J){if(Q.size===0)return;let Y=["section","item","passage"];for(let X of Y)for(let G of Z.placement[X]){let j=Q.get(G);if(!j){J.push(o({code:"tools.unknownToolId",severity:"error",path:`placement.${X}`,message:`Unknown tool id "${G}" in placement.${X}.`,toolId:G}));continue}if(j.activation==="region"){J.push(o({code:"tools.unplaceableActivation",severity:"error",path:`placement.${X}`,message:`Tool "${G}" 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:G}));continue}let B=j.supportedLevels.includes(X),V=X==="item"&&j.supportedLevels.includes("section");if(!B&&!V)J.push(o({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${G}" does not support level "${X}".`,toolId:G}))}}var U8=new Set(F8);function G6(Z,Q,J){if(Q.size===0)return;for(let Y of Z.policy.allowed||[]){if(Q.has(Y)||U8.has(Y))continue;J.push(o({code:"tools.unknownToolId",severity:"error",path:"policy.allowed",message:`Unknown tool id "${Y}" in policy.allowed.`,toolId:Y}))}for(let Y of Z.policy.blocked||[]){if(Q.has(Y)||U8.has(Y))continue;J.push(o({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${Y}" in policy.blocked.`,toolId:Y}))}}function j6(Z,Q,J){for(let Y of Object.keys(Z.providers).sort()){if(Q.size===0||Q.has(Y))continue;J.push(o({code:"tools.unknownProviderKey",severity:"error",path:`providers.${Y}`,message:`Unknown provider key "${Y}".`,toolId:Y}))}}function $8(Z,Q){if(Z.length===0)return;for(let J of Z){let Y=`[tool-config-validation:${Q}]`;console.warn(`${Y} ${J.path} - ${J.message}`)}}function B6(Z,Q){let J=Z.map((Y)=>`- ${Y.path}: ${Y.message}`).join(`
|
|
2
2
|
`);throw Error(`[tool-config-validation:${Q}] Invalid tools config:
|
|
3
|
-
${J}`)}function $8(Z,Q={}){let J=N5(Z,Q.toolRegistry);return w5(J.diagnostics,Q),J}function N5(Z,Q){let J=a4(Q),Y=l0(Z),X=[],G=Object.values(Y.placement).some((V)=>V.length>0)||Object.keys(Y.providers).length>0||(Y.policy.allowed?.length??0)>0||(Y.policy.blocked?.length??0)>0;if(J.size===0&&G)X.push(a({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 j={...Y.providers||{}};for(let V of Object.keys(j).sort()){let K=J.get(V);j[V]=o4(V,j[V],K,X),t4(V,j[V],K,X)}let B={...Y,providers:j};return e4(B,J,X),Z6(B,J,X),Q6(B,J,X),{config:B,diagnostics:X}}function w5(Z,Q={}){let J=P5(Q.strictness),Y=Q.source??"tools";if(J==="warn")q8(Z,Y);let X=Z.filter((G)=>G.severity==="error");if(J==="error"&&X.length>0)J6(X,Y);if(J==="error"&&X.length===0)q8(Z,Y)}import{languageTagScriptLookupSequence as B6,languageTagScriptsMatch as W6,normalizeLanguageTag as S5}from"@pie-players/pie-players-shared/i18n/language-tags";var b5=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),F8=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),z8=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),D8=new Set(["break","mark","lexicon"]);function Y6(Z){let Q=Z;for(let J of D8){let Y=new RegExp(`<${J}\\b([^>/]*?)\\s*/>`,"gi");Q=Q.replace(Y,(X,G)=>{let j=G?G.replace(/\s+$/,""):"";return`<${J}${j}></${J}>`})}return Q}var X6=[/^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 G6(Z){if(typeof Z!=="string"||Z.length===0)return!1;let Q;try{Q=new URL(Z)}catch{return!1}if(Q.protocol!=="http:"&&Q.protocol!=="https:")return!1;let J=Q.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!X6.some((Y)=>Y.test(J))}function R5(Z){let Q=Array.from(Z.children);for(let Y of Q){let X=Y.tagName.toLowerCase();if(F8.has(X)){Y.remove();continue}if(R5(Y),!b5.has(X)){let G=Z.ownerDocument.createTextNode(Y.textContent??"");Y.replaceWith(G)}}let J=Array.from(Z.attributes).map((Y)=>Y.name);for(let Y of J)if(!z8.has(Y.toLowerCase()))Z.removeAttribute(Y);if(Z.tagName.toLowerCase()==="audio"){let Y=Z.getAttribute("src");if(Y!==null&&!G6(Y))Z.removeAttribute("src")}}function C5(Z){let Q=Z.tagName.toLowerCase(),J=Array.from(Z.attributes).filter((X)=>z8.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${j6(X.value)}"`).join("");if(D8.has(Q))return`<${Q}${J}/>`;let Y=[];for(let X of Array.from(Z.childNodes))if(X.nodeType===3)Y.push(xZ(X.nodeValue??""));else if(X.nodeType===1){let G=X,j=G.tagName.toLowerCase();if(F8.has(j))continue;if(b5.has(j))Y.push(C5(G));else Y.push(xZ(G.textContent??""))}return`<${Q}${J}>${Y.join("")}</${Q}>`}function E5(Z){let Q=String(Z||"").trim();if(!Q||!Q.includes("<"))return Z;if(typeof DOMParser>"u")return Z;let Y=new DOMParser().parseFromString(Y6(Q),"text/html"),X=Y.querySelector("speak");if(X)return R5(X),C5(X);let G=Y.createElement("speak");for(let j of Array.from(Y.body.childNodes))G.appendChild(j);return R5(G),Array.from(G.childNodes).map((j)=>{if(j.nodeType===3)return xZ(j.nodeValue??"");if(j.nodeType===1){let B=j;if(b5.has(B.tagName.toLowerCase()))return C5(B);return xZ(B.textContent??"")}return""}).join("")}function xZ(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function j6(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var P8=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),T5="ext:";function H8(Z){if(P8.has(Z))return!0;return Z.startsWith(T5)&&Z.length>T5.length}var A8=new Set;function y5(Z,Q=new Set){if(Z===null||typeof Z==="string"||typeof Z==="number"||typeof Z==="boolean"||typeof Z>"u")return Z;if(typeof Z!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Q.has(Z))throw TypeError("catalog cards must not contain cycles");Q.add(Z);try{if(Array.isArray(Z))return Object.freeze(Z.map((X)=>y5(X,Q)));let J=Object.getPrototypeOf(Z);if(J!==Object.prototype&&J!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let Y={};for(let[X,G]of Object.entries(Z))Y[X]=y5(G,Q);return Object.freeze(Y)}finally{Q.delete(Z)}}function _8(Z,Q,J){let Y=`${Q}|${Z}`;if(A8.has(Y))return;A8.add(Y);let X=`${Array.from(P8).join(", ")}, or an "${T5}" prefixed vendor extension`;if(Q==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${J}" has a card of unknown type "${Z}"; 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 "${Z}" on "${J}" cannot match any card. Expected one of: ${X}.`)}var O8=(Z)=>Z.payload!==void 0?"payload":"content";class x5{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(Z,Q="en-US"){this.defaultLanguage=Q,this.indexCatalogs(Z??[],"assessment")}setDefaultLanguage(Z){this.defaultLanguage=Z}onCatalogsChange(Z){return this.catalogChangeListeners.add(Z),()=>{this.catalogChangeListeners.delete(Z)}}emitCatalogsChange(Z){for(let Q of Array.from(this.catalogChangeListeners))try{Q(Z)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(Z,Q){let J=Q==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let Y of this.sanitizeCatalogs(Z)){if(J.has(Y.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Q} catalog "${Y.identifier}" ignored`);continue}J.set(Y.identifier,Y)}}insertScopedCatalogs(Z,Q){if(!Q||Q.length===0)return null;let J=this.getOwnerKey(Z),Y=this.scopedCatalogs.get(J),X=Y?.catalogs??new Map,G=[];for(let j of this.sanitizeCatalogs(Q)){if(X.has(j.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${j.identifier}" ignored for ${J}`);continue}X.set(j.identifier,j),G.push(j.identifier)}if(!Y&&G.length>0)this.scopedCatalogs.set(J,{context:{...Z},catalogs:X});return{key:J,context:{...Z},catalogs:X,insertedIds:G}}removeScopedInsertion(Z){let Q=this.scopedCatalogs.get(Z.key);if(Q?.catalogs!==Z.catalogs)return!1;let J=!1;for(let Y of Z.insertedIds)J=Q.catalogs.delete(Y)||J;if(Q.catalogs.size===0)this.scopedCatalogs.delete(Z.key);return J}registerCatalogs(Z,Q){let J=this.insertScopedCatalogs(Z,Q);if(J&&J.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:Z});let Y=!0;return()=>{if(!Y)return;if(Y=!1,J&&this.removeScopedInsertion(J))this.emitCatalogsChange({reason:"scoped-removed",context:Z})}}registerOwner(Z){let{owner:Q,entity:J}=Z,Y=M8(Q),X=[],G=[];try{G=L8(J,Q)}catch(V){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",V)}for(let V of G)try{let K=this.insertScopedCatalogs(V.context,V.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((V)=>V.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:Y});let B=!0;return()=>{if(!B)return;B=!1;let V=!1;for(let K of X)V=this.removeScopedInsertion(K)||V;if(V)this.emitCatalogsChange({reason:"scoped-removed",context:Y})}}forOwner(Z){let Q={...Z};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Q),onChange:(J)=>this.onCatalogsChange((Y)=>{if(this.catalogChangeAffectsOwner(Y,Q))J()})})}addItemCatalogs(Z){if(!Z||Z.length===0)return;this.indexCatalogs(Z,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(Z){return this.itemCatalogs.has(Z)||this.assessmentCatalogs.has(Z)||Array.from(this.scopedCatalogs.values()).some((Q)=>Q.catalogs.has(Z))}getAlternative(Z,Q){if(!H8(Q.type))_8(Q.type,"lookup",Z);let J=Q.context?this.scopedCatalogs.get(this.getOwnerKey(Q.context))?.catalogs.get(Z):null;if(J){let G=this.findMatchingCard(J,Q);if(G)return this.resolveCard(Z,G,"item")}if(Q.context){let G=this.findScopedCandidates(Z,Q.context);if(G.length===1){let j=this.findMatchingCard(G[0],Q);if(j)return this.resolveCard(Z,j,"item")}else if(G.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${Z}" for owner context`,Q.context),null}let Y=this.itemCatalogs.get(Z);if(Y){let G=this.findMatchingCard(Y,Q);if(G)return this.resolveCard(Z,G,"item")}let X=this.assessmentCatalogs.get(Z);if(X){let G=this.findMatchingCard(X,Q);if(G)return this.resolveCard(Z,G,"assessment")}return null}resolveCard(Z,Q,J){return{catalogId:Z,type:Q.catalog,language:Q.language,content:Q.catalog==="spoken"&&Q.content!==void 0?this.ensureSpokenSanitized(Q.content):Q.content,payload:Q.payload,source:J}}ensureSpokenSanitized(Z){let Q=this.sanitizedSpokenCache.get(Z);if(Q!==void 0)return Q;let J=E5(Z);return this.sanitizedSpokenCache.set(Z,J),J}getOwnerKey(Z){return[Z.ownerKind,Z.assessmentId||"",Z.sectionId||"",Z.canonicalItemId||"",Z.itemId||"",Z.passageId||"",Z.modelId||""].join("|")}scopedCatalogEntries(){let Z=[];for(let Q of this.scopedCatalogs.values())for(let J of Q.catalogs.entries())Z.push(J);return Z}findScopedCandidates(Z,Q){return Array.from(this.scopedCatalogs.values()).filter((J)=>this.isCompatibleOwnerContext(J.context,Q)).map((J)=>J.catalogs.get(Z)).filter((J)=>Boolean(J))}isCompatibleOwnerContext(Z,Q){if(Z.ownerKind!==Q.ownerKind)return!1;if(Q.assessmentId&&Z.assessmentId!==Q.assessmentId)return!1;if(Q.sectionId&&Z.sectionId!==Q.sectionId)return!1;if(Q.canonicalItemId&&Z.canonicalItemId!==Q.canonicalItemId)return!1;if(Q.itemId&&Z.itemId!==Q.itemId)return!1;if(Q.passageId&&Z.passageId!==Q.passageId)return!1;if(Q.modelId&&Z.modelId!==Q.modelId)return!1;return!0}ownerScopedCatalogEntries(Z){let Q=[],J=this.scopedCatalogs.get(this.getOwnerKey(Z));if(J)Q.push(...J.catalogs.entries());for(let Y of this.scopedCatalogs.values()){if(Y===J)continue;if(!this.isCompatibleOwnerContext(Y.context,Z))continue;Q.push(...Y.catalogs.entries())}return Q}createOwnerSnapshot(Z){let Q=[],J=this.ownerScopedCatalogEntries(Z);if(Z.ownerKind==="global")J.push(...this.assessmentCatalogs.entries());for(let[Y,X]of J)for(let G of X.cards)try{Q.push(Object.freeze({catalogId:Y,card:y5(G)}))}catch(j){let B=`${this.getOwnerKey(Z)}\x00${Y}`;if(!this.reportedSnapshotProblems.has(B))this.reportedSnapshotProblems.add(B),console.warn(`[AccessibilityCatalogResolver] Catalog "${Y}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,j)}return Object.freeze({cards:Object.freeze(Q)})}catalogChangeAffectsOwner(Z,Q){if(!Z.context)return!1;if(this.isCompatibleOwnerContext(Z.context,Q))return!0;if(Q.ownerKind==="itemModel"&&Q.modelId&&Z.context.ownerKind==="itemModel"&&!Z.context.modelId)return this.isCompatibleOwnerContext({...Z.context,modelId:Q.modelId},Q);return!1}sanitizeCatalogs(Z){return Z.map((Q)=>({...Q,cards:Q.cards.map((J)=>{if(!H8(J.catalog))_8(J.catalog,"card",Q.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?E5(J.content):J.content}})}))}findMatchingCard(Z,Q){let{type:J,language:Y,useFallback:X=!0,form:G}=Q,j=[],B=(V)=>{let K=S5(V);for(let U of B6(V))j.push(($)=>S5($.language)===U&&(U===K||W6(V,$.language)))};if(Y)B(Y);if(X)B(this.defaultLanguage),j.push(()=>!0);for(let V of j){let K=Z.cards.filter((U)=>U.catalog===J&&V(U));if(K.length===0)continue;if(G){let U=K.find(($)=>O8($)===G);if(U)return U}return K[0]}return null}getAllAlternatives(Z){let Q=[],J=new Set,Y=(j,B)=>{let V=`${j.catalog}|${S5(j.language)}|${O8(j)}`;if(J.has(V))return;J.add(V),Q.push(this.resolveCard(Z,j,B))},X=this.itemCatalogs.get(Z);if(X)for(let j of X.cards)Y(j,"item");let G=this.assessmentCatalogs.get(Z);if(G)for(let j of G.cards)Y(j,"assessment");for(let[j,B]of this.scopedCatalogEntries()){if(j!==Z)continue;for(let V of B.cards)Y(V,"item")}return Q}getAllCatalogIds(){let Z=this.scopedCatalogEntries().map(([Q])=>Q);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...Z]))}getStatistics(){let Z=new Set,Q=new Set;for(let J of this.assessmentCatalogs.values())for(let Y of J.cards)if(Z.add(Y.catalog),Y.language)Q.add(Y.language);for(let J of this.itemCatalogs.values())for(let Y of J.cards)if(Z.add(Y.catalog),Y.language)Q.add(Y.language);for(let J of this.scopedCatalogs.values())for(let Y of J.catalogs.values())for(let X of Y.cards)if(Z.add(X.catalog),X.language)Q.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,Y)=>J+Y.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,Y)=>J+Y.catalogs.size,0),availableTypes:Z,availableLanguages:Q}}hasAlternativeType(Z,Q){return this.getAllAlternatives(Z).some((Y)=>Y.type===Q)}getCatalogsByType(Z){let Q=new Set;for(let[J,Y]of this.assessmentCatalogs.entries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);for(let[J,Y]of this.itemCatalogs.entries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);for(let[J,Y]of this.scopedCatalogEntries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);return Array.from(Q)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}var N8=["assessmentId","sectionId","attemptId","itemId","elementId"];function k5(Z){return Z.replace(/%/g,"%25").replace(/:/g,"%3A")}function V6(Z){return Z.replace(/%(25|3A)/g,(Q,J)=>J==="25"?"%":":")}class f5{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Z){return N8.map((Q)=>k5(Z[Q])).join(":")}parseGlobalElementId(Z){let Q=Z.split(":");if(Q.length!==N8.length)return null;let[J,Y,X,G,j]=Q.map(V6);return{assessmentId:J,sectionId:Y,attemptId:X,itemId:G,elementId:j}}setState(Z,Q,J){let Y=this.elementStates.get(Z);if(!Y)Y=new Map,this.elementStates.set(Z,Y);Y.set(Q,J),this._notifyListeners(),this._notifyStateChange()}getState(Z,Q){return this.elementStates.get(Z)?.get(Q)}getElementState(Z){let Q=this.elementStates.get(Z);if(!Q)return{};return Object.fromEntries(Q.entries())}getAllState(){let Z={};for(let[Q,J]of this.elementStates.entries())Z[Q]=Object.fromEntries(J.entries());return Z}subscribe(Z){return this.listeners.add(Z),()=>this.listeners.delete(Z)}_notifyListeners(){if(this.listeners.size===0)return;let Z=new Map([...this.elementStates].map(([Q,J])=>[Q,new Map(J)]));for(let Q of this.listeners)try{Q(Z)}catch(J){console.warn("[ElementToolStateStore] listener failed:",J)}}setOnStateChange(Z){this.onStateChange=Z}_notifyStateChange(){if(!this.onStateChange)return;try{this.onStateChange(this.getAllState())}catch(Z){console.warn("[ElementToolStateStore] state-change callback failed:",Z)}}loadState(Z){this.elementStates.clear();for(let[Q,J]of Object.entries(Z)){let Y=new Map(Object.entries(J));this.elementStates.set(Q,Y)}this._notifyListeners()}clearElement(Z){this.elementStates.delete(Z),this._notifyListeners(),this._notifyStateChange()}clearTool(Z){for(let Q of this.elementStates.values())Q.delete(Z);this._notifyListeners(),this._notifyStateChange()}clearSection(Z,Q){let J=`${k5(Z)}:${k5(Q)}:`,Y=[];for(let X of this.elementStates.keys())if(X.startsWith(J))Y.push(X);for(let X of Y)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}function kZ(Z){return{kind:Z.kind,severity:Z.severity??"error",source:Z.source,message:Z.message,details:[...Z.details||[]],recoverable:Z.recoverable===!0,scope:Z.scope??"runtime",...Z.cohort?{cohort:{...Z.cohort}}:{},cause:Z.cause}}function I5(Z){let Q=Z.error instanceof Error&&Z.error.message.trim().length>0?Z.error.message:String(Z.error||"Unknown framework error");return kZ({kind:Z.kind,source:Z.source,message:Q,recoverable:Z.recoverable,scope:Z.scope,cohort:Z.cohort,cause:Z.error})}var K6={"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","tool-module-load":"tool-module-load","tool-request-open":"tool-request","tool-request-host-check":"tool-request","tool-visibility":"tool-registration","tool-applicability":"tool-registration","tool-state-load":"tool-state-load","tool-state-save":"tool-state-save","tool-playback":"tool-playback"};function w8(Z){let Q=K6[Z.context.phase],J=Z.context.toolId?`pie-toolkit-coordinator/${Z.context.toolId}`:`pie-toolkit-coordinator:${Z.context.phase}`;return I5({kind:Q,source:J,error:Z.error,recoverable:Z.recoverable,scope:Z.scope,cohort:Z.cohort})}function R8(Z){let Q=`[pie-framework:${Z.kind}:${Z.source}]`;if(Z.details.length===0)return`${Q} ${Z.message}`;return`${Q} ${Z.message}
|
|
3
|
+
${J}`)}function z8(Z,Q={}){let J=w5(Z,Q.toolRegistry);return R5(J.diagnostics,Q),J}function w5(Z,Q){let J=Q6(Q),Y=s0(Z),X=[],G=Object.values(Y.placement).some((V)=>V.length>0)||Object.keys(Y.providers).length>0||(Y.policy.allowed?.length??0)>0||(Y.policy.blocked?.length??0)>0;if(J.size===0&&G)X.push(o({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 j={...Y.providers||{}};for(let V of Object.keys(j).sort()){let K=J.get(V);j[V]=J6(V,j[V],K,X),Y6(V,j[V],K,X)}let B={...Y,providers:j};return X6(B,J,X),G6(B,J,X),j6(B,J,X),{config:B,diagnostics:X}}function R5(Z,Q={}){let J=P5(Q.strictness),Y=Q.source??"tools";if(J==="warn")$8(Z,Y);let X=Z.filter((G)=>G.severity==="error");if(J==="error"&&X.length>0)B6(X,Y);if(J==="error"&&X.length===0)$8(Z,Y)}import{languageTagScriptLookupSequence as $6,languageTagScriptsMatch as F6,normalizeLanguageTag as y5}from"@pie-players/pie-players-shared/i18n/language-tags";import{isCloudMetadataHostname as W6,isPrivateHostname as V6}from"@pie-players/pie-players-shared/security/private-hosts";var E5=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),H8=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),A8=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),D8=new Set(["break","mark","lexicon"]);function K6(Z){let Q=Z;for(let J of D8){let Y=new RegExp(`<${J}\\b([^>/]*?)\\s*/>`,"gi");Q=Q.replace(Y,(X,G)=>{let j=G?G.replace(/\s+$/,""):"";return`<${J}${j}></${J}>`})}return Q}function q6(Z){if(typeof Z!=="string"||Z.length===0)return!1;let Q;try{Q=new URL(Z)}catch{return!1}if(Q.protocol!=="http:"&&Q.protocol!=="https:")return!1;return!W6(Q.hostname)&&!V6(Q.hostname)}function C5(Z){let Q=Array.from(Z.children);for(let Y of Q){let X=Y.tagName.toLowerCase();if(H8.has(X)){Y.remove();continue}if(C5(Y),!E5.has(X)){let G=Z.ownerDocument.createTextNode(Y.textContent??"");Y.replaceWith(G)}}let J=Array.from(Z.attributes).map((Y)=>Y.name);for(let Y of J)if(!A8.has(Y.toLowerCase()))Z.removeAttribute(Y);if(Z.tagName.toLowerCase()==="audio"){let Y=Z.getAttribute("src");if(Y!==null&&!q6(Y))Z.removeAttribute("src")}}function b5(Z){let Q=Z.tagName.toLowerCase(),J=Array.from(Z.attributes).filter((X)=>A8.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${U6(X.value)}"`).join("");if(D8.has(Q))return`<${Q}${J}/>`;let Y=[];for(let X of Array.from(Z.childNodes))if(X.nodeType===3)Y.push(kZ(X.nodeValue??""));else if(X.nodeType===1){let G=X,j=G.tagName.toLowerCase();if(H8.has(j))continue;if(E5.has(j))Y.push(b5(G));else Y.push(kZ(G.textContent??""))}return`<${Q}${J}>${Y.join("")}</${Q}>`}function S5(Z){let Q=String(Z||"").trim();if(!Q||!Q.includes("<"))return Z;if(typeof DOMParser>"u")return Z;let Y=new DOMParser().parseFromString(K6(Q),"text/html"),X=Y.querySelector("speak");if(X)return C5(X),b5(X);let G=Y.createElement("speak");for(let j of Array.from(Y.body.childNodes))G.appendChild(j);return C5(G),Array.from(G.childNodes).map((j)=>{if(j.nodeType===3)return kZ(j.nodeValue??"");if(j.nodeType===1){let B=j;if(E5.has(B.tagName.toLowerCase()))return b5(B);return kZ(B.textContent??"")}return""}).join("")}function kZ(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function U6(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var w8=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),T5="ext:";function _8(Z){if(w8.has(Z))return!0;return Z.startsWith(T5)&&Z.length>T5.length}var M8=new Set;function x5(Z,Q=new Set){if(Z===null||typeof Z==="string"||typeof Z==="number"||typeof Z==="boolean"||typeof Z>"u")return Z;if(typeof Z!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Q.has(Z))throw TypeError("catalog cards must not contain cycles");Q.add(Z);try{if(Array.isArray(Z))return Object.freeze(Z.map((X)=>x5(X,Q)));let J=Object.getPrototypeOf(Z);if(J!==Object.prototype&&J!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let Y={};for(let[X,G]of Object.entries(Z))Y[X]=x5(G,Q);return Object.freeze(Y)}finally{Q.delete(Z)}}function O8(Z,Q,J){let Y=`${Q}|${Z}`;if(M8.has(Y))return;M8.add(Y);let X=`${Array.from(w8).join(", ")}, or an "${T5}" prefixed vendor extension`;if(Q==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${J}" has a card of unknown type "${Z}"; 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 "${Z}" on "${J}" cannot match any card. Expected one of: ${X}.`)}var L8=(Z)=>Z.payload!==void 0?"payload":"content";class k5{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(Z,Q="en-US"){this.defaultLanguage=Q,this.indexCatalogs(Z??[],"assessment")}setDefaultLanguage(Z){this.defaultLanguage=Z}onCatalogsChange(Z){return this.catalogChangeListeners.add(Z),()=>{this.catalogChangeListeners.delete(Z)}}emitCatalogsChange(Z){for(let Q of Array.from(this.catalogChangeListeners))try{Q(Z)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(Z,Q){let J=Q==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let Y of this.sanitizeCatalogs(Z)){if(J.has(Y.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Q} catalog "${Y.identifier}" ignored`);continue}J.set(Y.identifier,Y)}}insertScopedCatalogs(Z,Q){if(!Q||Q.length===0)return null;let J=this.getOwnerKey(Z),Y=this.scopedCatalogs.get(J),X=Y?.catalogs??new Map,G=[];for(let j of this.sanitizeCatalogs(Q)){if(X.has(j.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${j.identifier}" ignored for ${J}`);continue}X.set(j.identifier,j),G.push(j.identifier)}if(!Y&&G.length>0)this.scopedCatalogs.set(J,{context:{...Z},catalogs:X});return{key:J,context:{...Z},catalogs:X,insertedIds:G}}removeScopedInsertion(Z){let Q=this.scopedCatalogs.get(Z.key);if(Q?.catalogs!==Z.catalogs)return!1;let J=!1;for(let Y of Z.insertedIds)J=Q.catalogs.delete(Y)||J;if(Q.catalogs.size===0)this.scopedCatalogs.delete(Z.key);return J}registerCatalogs(Z,Q){let J=this.insertScopedCatalogs(Z,Q);if(J&&J.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:Z});let Y=!0;return()=>{if(!Y)return;if(Y=!1,J&&this.removeScopedInsertion(J))this.emitCatalogsChange({reason:"scoped-removed",context:Z})}}registerOwner(Z){let{owner:Q,entity:J}=Z,Y=N8(Q),X=[],G=[];try{G=P8(J,Q)}catch(V){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",V)}for(let V of G)try{let K=this.insertScopedCatalogs(V.context,V.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((V)=>V.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:Y});let B=!0;return()=>{if(!B)return;B=!1;let V=!1;for(let K of X)V=this.removeScopedInsertion(K)||V;if(V)this.emitCatalogsChange({reason:"scoped-removed",context:Y})}}forOwner(Z){let Q={...Z};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Q),onChange:(J)=>this.onCatalogsChange((Y)=>{if(this.catalogChangeAffectsOwner(Y,Q))J()})})}addItemCatalogs(Z){if(!Z||Z.length===0)return;this.indexCatalogs(Z,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(Z){return this.itemCatalogs.has(Z)||this.assessmentCatalogs.has(Z)||Array.from(this.scopedCatalogs.values()).some((Q)=>Q.catalogs.has(Z))}getAlternative(Z,Q){if(!_8(Q.type))O8(Q.type,"lookup",Z);let J=Q.context?this.scopedCatalogs.get(this.getOwnerKey(Q.context))?.catalogs.get(Z):null;if(J){let G=this.findMatchingCard(J,Q);if(G)return this.resolveCard(Z,G,"item")}if(Q.context){let G=this.findScopedCandidates(Z,Q.context);if(G.length===1){let j=this.findMatchingCard(G[0],Q);if(j)return this.resolveCard(Z,j,"item")}else if(G.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${Z}" for owner context`,Q.context),null}let Y=this.itemCatalogs.get(Z);if(Y){let G=this.findMatchingCard(Y,Q);if(G)return this.resolveCard(Z,G,"item")}let X=this.assessmentCatalogs.get(Z);if(X){let G=this.findMatchingCard(X,Q);if(G)return this.resolveCard(Z,G,"assessment")}return null}resolveCard(Z,Q,J){return{catalogId:Z,type:Q.catalog,language:Q.language,content:Q.catalog==="spoken"&&Q.content!==void 0?this.ensureSpokenSanitized(Q.content):Q.content,payload:Q.payload,source:J}}ensureSpokenSanitized(Z){let Q=this.sanitizedSpokenCache.get(Z);if(Q!==void 0)return Q;let J=S5(Z);return this.sanitizedSpokenCache.set(Z,J),J}getOwnerKey(Z){return[Z.ownerKind,Z.assessmentId||"",Z.sectionId||"",Z.canonicalItemId||"",Z.itemId||"",Z.passageId||"",Z.modelId||""].join("|")}scopedCatalogEntries(){let Z=[];for(let Q of this.scopedCatalogs.values())for(let J of Q.catalogs.entries())Z.push(J);return Z}findScopedCandidates(Z,Q){return Array.from(this.scopedCatalogs.values()).filter((J)=>this.isCompatibleOwnerContext(J.context,Q)).map((J)=>J.catalogs.get(Z)).filter((J)=>Boolean(J))}isCompatibleOwnerContext(Z,Q){if(Z.ownerKind!==Q.ownerKind)return!1;if(Q.assessmentId&&Z.assessmentId!==Q.assessmentId)return!1;if(Q.sectionId&&Z.sectionId!==Q.sectionId)return!1;if(Q.canonicalItemId&&Z.canonicalItemId!==Q.canonicalItemId)return!1;if(Q.itemId&&Z.itemId!==Q.itemId)return!1;if(Q.passageId&&Z.passageId!==Q.passageId)return!1;if(Q.modelId&&Z.modelId!==Q.modelId)return!1;return!0}ownerScopedCatalogEntries(Z){let Q=[],J=this.scopedCatalogs.get(this.getOwnerKey(Z));if(J)Q.push(...J.catalogs.entries());for(let Y of this.scopedCatalogs.values()){if(Y===J)continue;if(!this.isCompatibleOwnerContext(Y.context,Z))continue;Q.push(...Y.catalogs.entries())}return Q}createOwnerSnapshot(Z){let Q=[],J=this.ownerScopedCatalogEntries(Z);if(Z.ownerKind==="global")J.push(...this.assessmentCatalogs.entries());for(let[Y,X]of J)for(let G of X.cards)try{Q.push(Object.freeze({catalogId:Y,card:x5(G)}))}catch(j){let B=`${this.getOwnerKey(Z)}\x00${Y}`;if(!this.reportedSnapshotProblems.has(B))this.reportedSnapshotProblems.add(B),console.warn(`[AccessibilityCatalogResolver] Catalog "${Y}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,j)}return Object.freeze({cards:Object.freeze(Q)})}catalogChangeAffectsOwner(Z,Q){if(!Z.context)return!1;if(this.isCompatibleOwnerContext(Z.context,Q))return!0;if(Q.ownerKind==="itemModel"&&Q.modelId&&Z.context.ownerKind==="itemModel"&&!Z.context.modelId)return this.isCompatibleOwnerContext({...Z.context,modelId:Q.modelId},Q);return!1}sanitizeCatalogs(Z){return Z.map((Q)=>({...Q,cards:Q.cards.map((J)=>{if(!_8(J.catalog))O8(J.catalog,"card",Q.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?S5(J.content):J.content}})}))}findMatchingCard(Z,Q){let{type:J,language:Y,useFallback:X=!0,form:G}=Q,j=[],B=(V)=>{let K=y5(V);for(let U of $6(V))j.push(($)=>y5($.language)===U&&(U===K||F6(V,$.language)))};if(Y)B(Y);if(X)B(this.defaultLanguage),j.push(()=>!0);for(let V of j){let K=Z.cards.filter((U)=>U.catalog===J&&V(U));if(K.length===0)continue;if(G){let U=K.find(($)=>L8($)===G);if(U)return U}return K[0]}return null}getAllAlternatives(Z){let Q=[],J=new Set,Y=(j,B)=>{let V=`${j.catalog}|${y5(j.language)}|${L8(j)}`;if(J.has(V))return;J.add(V),Q.push(this.resolveCard(Z,j,B))},X=this.itemCatalogs.get(Z);if(X)for(let j of X.cards)Y(j,"item");let G=this.assessmentCatalogs.get(Z);if(G)for(let j of G.cards)Y(j,"assessment");for(let[j,B]of this.scopedCatalogEntries()){if(j!==Z)continue;for(let V of B.cards)Y(V,"item")}return Q}getAllCatalogIds(){let Z=this.scopedCatalogEntries().map(([Q])=>Q);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...Z]))}getStatistics(){let Z=new Set,Q=new Set;for(let J of this.assessmentCatalogs.values())for(let Y of J.cards)if(Z.add(Y.catalog),Y.language)Q.add(Y.language);for(let J of this.itemCatalogs.values())for(let Y of J.cards)if(Z.add(Y.catalog),Y.language)Q.add(Y.language);for(let J of this.scopedCatalogs.values())for(let Y of J.catalogs.values())for(let X of Y.cards)if(Z.add(X.catalog),X.language)Q.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,Y)=>J+Y.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,Y)=>J+Y.catalogs.size,0),availableTypes:Z,availableLanguages:Q}}hasAlternativeType(Z,Q){return this.getAllAlternatives(Z).some((Y)=>Y.type===Q)}getCatalogsByType(Z){let Q=new Set;for(let[J,Y]of this.assessmentCatalogs.entries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);for(let[J,Y]of this.itemCatalogs.entries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);for(let[J,Y]of this.scopedCatalogEntries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);return Array.from(Q)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}var R8=["assessmentId","sectionId","attemptId","itemId","elementId"];function f5(Z){return Z.replace(/%/g,"%25").replace(/:/g,"%3A")}function z6(Z){return Z.replace(/%(25|3A)/g,(Q,J)=>J==="25"?"%":":")}class I5{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Z){return R8.map((Q)=>f5(Z[Q])).join(":")}parseGlobalElementId(Z){let Q=Z.split(":");if(Q.length!==R8.length)return null;let[J,Y,X,G,j]=Q.map(z6);return{assessmentId:J,sectionId:Y,attemptId:X,itemId:G,elementId:j}}setState(Z,Q,J){let Y=this.elementStates.get(Z);if(!Y)Y=new Map,this.elementStates.set(Z,Y);Y.set(Q,J),this._notifyListeners(),this._notifyStateChange()}getState(Z,Q){return this.elementStates.get(Z)?.get(Q)}getElementState(Z){let Q=this.elementStates.get(Z);if(!Q)return{};return Object.fromEntries(Q.entries())}getAllState(){let Z={};for(let[Q,J]of this.elementStates.entries())Z[Q]=Object.fromEntries(J.entries());return Z}subscribe(Z){return this.listeners.add(Z),()=>this.listeners.delete(Z)}_notifyListeners(){if(this.listeners.size===0)return;let Z=new Map([...this.elementStates].map(([Q,J])=>[Q,new Map(J)]));for(let Q of this.listeners)try{Q(Z)}catch(J){console.warn("[ElementToolStateStore] listener failed:",J)}}setOnStateChange(Z){this.onStateChange=Z}_notifyStateChange(){if(!this.onStateChange)return;try{this.onStateChange(this.getAllState())}catch(Z){console.warn("[ElementToolStateStore] state-change callback failed:",Z)}}loadState(Z){this.elementStates.clear();for(let[Q,J]of Object.entries(Z)){let Y=new Map(Object.entries(J));this.elementStates.set(Q,Y)}this._notifyListeners()}clearElement(Z){this.elementStates.delete(Z),this._notifyListeners(),this._notifyStateChange()}clearTool(Z){for(let Q of this.elementStates.values())Q.delete(Z);this._notifyListeners(),this._notifyStateChange()}clearSection(Z,Q){let J=`${f5(Z)}:${f5(Q)}:`,Y=[];for(let X of this.elementStates.keys())if(X.startsWith(J))Y.push(X);for(let X of Y)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}function fZ(Z){return{kind:Z.kind,severity:Z.severity??"error",source:Z.source,message:Z.message,details:[...Z.details||[]],recoverable:Z.recoverable===!0,scope:Z.scope??"runtime",...Z.cohort?{cohort:{...Z.cohort}}:{},cause:Z.cause}}function v5(Z){let Q=Z.error instanceof Error&&Z.error.message.trim().length>0?Z.error.message:String(Z.error||"Unknown framework error");return fZ({kind:Z.kind,source:Z.source,message:Q,recoverable:Z.recoverable,scope:Z.scope,cohort:Z.cohort,cause:Z.error})}var H6={"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","tool-module-load":"tool-module-load","tool-request-open":"tool-request","tool-request-host-check":"tool-request","tool-visibility":"tool-registration","tool-applicability":"tool-registration","tool-state-load":"tool-state-load","tool-state-save":"tool-state-save","tool-playback":"tool-playback"};function C8(Z){let Q=H6[Z.context.phase],J=Z.context.toolId?`pie-toolkit-coordinator/${Z.context.toolId}`:`pie-toolkit-coordinator:${Z.context.phase}`;return v5({kind:Q,source:J,error:Z.error,recoverable:Z.recoverable,scope:Z.scope,cohort:Z.cohort})}function b8(Z){let Q=`[pie-framework:${Z.kind}:${Z.source}]`;if(Z.details.length===0)return`${Q} ${Z.message}`;return`${Q} ${Z.message}
|
|
4
4
|
- ${Z.details.join(`
|
|
5
|
-
- `)}`}class
|
|
5
|
+
- `)}`}class UZ{listeners=new Set;subscribeFrameworkErrors(Z){this.listeners.add(Z);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(Z)}}reportFrameworkError(Z){let Q=Array.from(this.listeners);for(let J of Q)try{J(Z)}catch(Y){console.warn("[FrameworkErrorBus] listener failed:",Y)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}var A6=new Set(["pie-item-toolbar","pie-section-toolbar","pie-item-player-session-debugger"]),D6=["pie-tool-","pie-section-player-tools-"],_6=new Set(["style","script","noscript","template"]),u=(Z)=>!!Z&&Z.nodeType===11&&Z.host?.nodeType===1,M6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(A6.has(Q))return!0;return D6.some((J)=>Q.startsWith(J))},O6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(_6.has(Q))return!0;if(M6(Z))return!0;return u(Z.parentNode)&&Z.getAttribute("aria-hidden")==="true"},L6=(Z)=>{if(!u(Z.getRootNode?.()))return null;let Q=Z.assignedNodes;if(typeof Q!=="function")return null;try{return Q.call(Z,{flatten:!0})}catch{return null}},F0=(Z)=>{let Q=Z.childNodes;if(Z.nodeType===1){let Y=Z,X=Y.shadowRoot;if(X)Q=X.childNodes;else if(Y.localName?.toLowerCase()==="slot")Q=L6(Y)??Y.childNodes}let J=[];for(let Y of Array.from(Q||[])){if(Y.nodeType===1&&O6(Y))continue;J.push(Y)}return J},$Z=(Z,Q)=>{let J=(Y)=>{for(let X of F0(Y)){let G=Q(X);if(G==="stop")return!1;if(G==="skip")continue;if(!J(X))return!1}return!0};J(Z)},b0=(Z)=>{let Q=[];return $Z(Z,(J)=>{if(J.nodeType===3)Q.push(J);return}),Q},S8=(Z)=>b0(Z).map((Q)=>Q.data).join(""),y8=(Z,Q)=>{let J=[];return $Z(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))J.push(Y);return}),J},E0=(Z,Q)=>{let J=null;return $Z(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))return J=Y,"stop";return}),J},E8=(Z)=>{let Q=Z.assignedSlot;if(Q)return Q;let J=Z.parentNode;if(u(J))return J.host;return J},c=(Z)=>{let Q=E8(Z);while(Q&&Q.nodeType!==1)Q=E8(Q);return Q},h5=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(J.matches(Q))return J;J=c(J)}return null},i=(Z)=>{if(Z.parentElement)return Z.parentElement;let Q=Z.parentNode;return u(Q)?Q.host:null},IZ=(Z,Q,J)=>{let Y=Z.nodeType===1?Z:i(Z);while(Y){if(Y.matches(Q))return Y;if(J&&Y===J)return null;Y=i(Y)}return null},J0=(Z,Q)=>{if(!Z||!Q)return!1;let J=Q;while(J){if(J===Z||Z.contains(J))return!0;let Y=J.getRootNode?.();J=u(Y)?Y.host:null}return!1},T8=(Z,Q)=>{let J=Z;while(J){let Y=J.getRootNode?.();if(Y===Q)return J;J=u(Y)?Y.host:null}return null},FZ=(Z,Q,J)=>{try{let Y=Z.startContainer.getRootNode?.();if(!Y||Q.getRootNode?.()===Y)return Z.comparePoint(Q,J)===0&&Z.comparePoint(Q,Math.min(J+1,Q.length))===0;return x8(Z,T8(Q,Y))}catch{return!1}},G0=(Z,Q)=>{try{let J=Z.startContainer.getRootNode?.();if(!J||Q.getRootNode?.()===J)return Z.intersectsNode(Q);return x8(Z,T8(Q,J))}catch{return!1}},x8=(Z,Q)=>{let J=Q?.parentNode;if(!Q||!J)return!1;let Y=Array.prototype.indexOf.call(J.childNodes,Q);if(Y<0)return!1;return Z.comparePoint(J,Y)===0&&Z.comparePoint(J,Y+1)===0};var m5=" >>> ";class u5{serialize(Z,Q){return{startContainer:this.getNodePath(Z.startContainer,Q),startOffset:Z.startOffset,endContainer:this.getNodePath(Z.endContainer,Q),endOffset:Z.endOffset,text:Z.toString()}}deserialize(Z,Q){let J=this.findNodeByPath(Z.startContainer,Q),Y=this.findNodeByPath(Z.endContainer,Q);if(!J||!Y)return null;try{let X=new Range;if(X.setStart(J,Z.startOffset),X.setEnd(Y,Z.endOffset),X.toString()===Z.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(Z,Q){if(Z===Q)return"";if(Z.nodeType===Node.TEXT_NODE){let J=Z.parentNode;if(!J)throw Error("Text node has no parent");let X=Array.from(J.childNodes).filter((j)=>j.nodeType===Node.TEXT_NODE).indexOf(Z);return`${u(J)?this.getShadowRootPath(J,Q):this.getElementPath(J,Q)}::text[${X}]`}if(Z.nodeType===Node.ELEMENT_NODE)return this.getElementPath(Z,Q);if(u(Z))return this.getShadowRootPath(Z,Q);throw Error(`Unsupported node type: ${Z.nodeType}`)}getElementPath(Z,Q){if(Z===Q)return"";let J=Q.getRootNode?.(),Y=[],X=[],G=Z,j=(B)=>{Y.unshift(X.join(" > ")),X=[],G=B.host};while(G&&G!==Q){if(G.id){X.unshift(`#${G.id}`);let O=G.getRootNode?.();if(u(O)&&O!==J){j(O);continue}break}let{parentElement:B,parentNode:V}=G,K=B??(u(V)?V:null);if(!K)break;let U=G.tagName,$=Array.from(K.children).filter((O)=>O.tagName===U),z=$.indexOf(G),H=$.length>1?`${U.toLowerCase()}:nth-of-type(${z+1})`:U.toLowerCase();if(X.unshift(H),B)G=B;else j(K)}return Y.unshift(X.join(" > ")),Y.join(m5)}getShadowRootPath(Z,Q){return`${this.getElementPath(Z.host,Q)}${m5}`}resolveElementPath(Z,Q){let J=Q,Y=Z.split(m5);for(let X=0;X<Y.length;X++){if(X>0){let B=u(J)?null:J.shadowRoot;if(!B)return null;J=B}let G=Y[X].trim();if(!G)continue;let j=J.querySelector(G);if(!j)return null;J=j}return J}findNodeByPath(Z,Q){if(Z==="")return Q;if(Z.includes("::text[")){let J=Z.lastIndexOf("::text["),Y=Z.slice(0,J),X=Z.slice(J+7),G=Number.parseInt(X.replace("]",""),10),j;try{j=this.resolveElementPath(Y,Q)}catch(V){return console.warn("Invalid selector path:",Z,V),null}if(!j)return null;return Array.from(j.childNodes).filter((V)=>V.nodeType===Node.TEXT_NODE)[G]||null}try{return this.resolveElementPath(Z,Q)}catch(J){return console.warn("Invalid selector path:",Z,J),null}}}var c5;(function(Z){Z.TTS_WORD="tts-word",Z.TTS_SENTENCE="tts-sentence",Z.ANNOTATION="annotation"})(c5||(c5={}));var vZ;(function(Z){Z.YELLOW="yellow",Z.GREEN="green",Z.BLUE="blue",Z.PINK="pink",Z.ORANGE="orange",Z.UNDERLINE="underline"})(vZ||(vZ={}));var h8=`
|
|
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,7 +212,7 @@ ${J}`)}function $8(Z,Q={}){let J=N5(Z,Q.toolRegistry);return w5(J.diagnostics,Q)
|
|
|
212
212
|
text-shadow: none;
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
`,y8=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet"),x8=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet-adopted"),k8=(Z)=>!!Z&&typeof Z.replaceSync==="function",H6=()=>{let Z=globalThis,Q=Z[y8];if(k8(Q))return Q;let J=globalThis.CSSStyleSheet;if(typeof J!=="function")return null;try{let Y=new J;if(!k8(Y))return null;return Y.replaceSync(I8),Z[y8]=Y,Y}catch{return null}},FZ=(Z)=>{let Q=Z?.getRootNode?.();if(!m(Q))return;let J=Q,Y=J.adoptedStyleSheets;if(!Y||typeof Y!=="object")return;let X=Array.from(Y),G=J[x8];if(G&&X.includes(G))return;let j=H6();if(!j)return;try{J.adoptedStyleSheets=[...X,j],J[x8]=j}catch{}},u5="tts-word",p5="tts-sentence",s0=(Z)=>`annotation-${Z}`,E0=(Z)=>{let Q=CSS.highlights.get(Z);if(Q)return Q;let J=new Highlight;return CSS.highlights.set(Z,J),J},zZ=(Z,Q)=>{let J=CSS.highlights.get(Z);if(!J)return;for(let Y of Q)J.delete(Y)},f8=(Z)=>{let Q=Z[0]?.startContainer;if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:d(Q)},G0={source:null,override:null};class DZ{ttsWordRanges=new Set;ttsSentenceRanges=new Set;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;ttsStyleSource=null;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;constructor(){if(this.rangeSerializer=new m5,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 Z=document.getElementsByTagName("pie-theme"),Q=new WeakSet,J=()=>{let X=!1;for(let G of Z){if(Q.has(G))continue;Q.add(G),Y.observe(G,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]}),X=!0}return X},Y=new MutationObserver((X)=>{if(J()||X.some((j)=>j.type==="attributes"))this.applyAdaptiveTTSStyle()});this.themeObserver=Y,Y.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]}),Y.observe(document,{childList:!0,subtree:!0}),J()}parseColor(Z){if(!Z)return null;let Q=Z.trim();if(!Q)return null;let J=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Q);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 Y=/^rgba?\((.+)\)$/i.exec(Q);if(Y){let G=Y[1].replace(/\//g,",").split(/[,\s]+/).map((K)=>K.trim()).filter(Boolean),j=Number(G[0]),B=Number(G[1]),V=Number(G[2]);if(Number.isFinite(j)&&Number.isFinite(B)&&Number.isFinite(V))return[j,B,V]}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 G=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let j=G.trim();if(j&&j!==Q)return this.parseColor(G)}}return null}relativeLuminance([Z,Q,J]){let Y=(B)=>{let V=B/255;return V<=0.03928?V/12.92:((V+0.055)/1.055)**2.4},X=Y(Z),G=Y(Q),j=Y(J);return 0.2126*X+0.7152*G+0.0722*j}contrastRatio(Z,Q){let J=this.relativeLuminance(Z),Y=this.relativeLuminance(Q),X=Math.max(J,Y),G=Math.min(J,Y);return(X+0.05)/(G+0.05)}blend(Z,Q,J){return[Math.round(Z[0]*J+Q[0]*(1-J)),Math.round(Z[1]*J+Q[1]*(1-J)),Math.round(Z[2]*J+Q[2]*(1-J))]}resolveAdaptiveTTSStyle(Z){let Q=[255,235,59],J=[17,24,39],Y=[255,255,255],X=Z||(typeof document<"u"?document.documentElement:null),G=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,j=this.parseColor(G?.getPropertyValue("--pie-background")||G?.backgroundColor)||Y,B=this.parseColor(G?.getPropertyValue("--pie-text"))||J,V=G0.override,K=V?this.parseColor(V.color)||Q:this.parseColor(G?.getPropertyValue("--pie-missing"))||Q,U=V?[Math.max(0.3,Math.min(0.95,V.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],$=U[U.length-1],z=-1/0;for(let n of U){let K0=this.blend(K,j,n),e=this.contrastRatio(K0,j),A0=this.contrastRatio(K0,B),_0=e*1.2+A0*0.8;if(e>=1.25&&A0>=2.4){$=n;break}if(_0>z)z=_0,$=n}let D=Math.max(0.24,Math.min(0.85,$*0.55)),M=Math.max(0.55,Math.min(0.95,$+0.2)),P=Math.max(0.22,Math.min(0.6,$*0.45)),H=B,N=this.blend(H,j,M),O=this.contrastRatio(N,j),C=this.relativeLuminance(j)>0.45?[0,0,0]:[255,255,255],E=O>=1.35?H:C,v=`rgba(${K[0]}, ${K[1]}, ${K[2]}, ${$})`,S=`rgba(${K[0]}, ${K[1]}, ${K[2]}, ${D})`,u=`rgba(${E[0]}, ${E[1]}, ${E[2]}, ${M})`,t=`rgba(${E[0]}, ${E[1]}, ${E[2]}, ${P})`;return{wordHighlight:v,sentenceHighlight:S,wordUnderline:u,wordShadow:t}}applyAdaptiveTTSStyle(Z){if(typeof document>"u")return;if(Z)this.ttsStyleSource=Z,G0.source=Z;let Q=Z??(G0.source?.isConnected?G0.source:null),J=this.resolveAdaptiveTTSStyle(Q),Y=document.documentElement.style,X=[["--pie-tts-word-highlight",J.wordHighlight],["--pie-tts-sentence-highlight",J.sentenceHighlight],["--pie-tts-line-highlight",J.sentenceHighlight],["--pie-tts-word-underline",J.wordUnderline],["--pie-tts-word-shadow",J.wordShadow]];for(let[G,j]of X){if(Y.getPropertyValue?.(G)===j)continue;Y.setProperty(G,j)}}initializeHighlights(){if(!this.supported)return;E0(u5),E0(p5);for(let Z of Object.values(IZ))E0(s0(Z))}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let Z=document.createElement("style");Z.id="pie-highlight-styles",Z.textContent=I8,document.head.appendChild(Z)}highlightTTSWord(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(f8(Z)),this.clearTTSWord();let Q=E0(u5);for(let J of Z)FZ(J.startContainer),Q.add(J),this.ttsWordRanges.add(J);this.highlightTTSWordElementFallbacks(Z.filter((J)=>J.startContainer!==J.endContainer||J.startContainer.nodeType!==Node.TEXT_NODE))}highlightTTSWordElement(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(Z),FZ(Z),this.clearTTSWord(),Z.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(Z)}highlightTTSSentence(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(f8(Z)),this.clearTTSSentence();let Q=E0(p5);for(let J of Z)FZ(J.startContainer),Q.add(J),this.ttsSentenceRanges.add(J);this.highlightTTSElementFallbacks(Z)}highlightTTSSentenceElements(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(Z[0]||null),this.clearTTSSentence();for(let Q of Z)FZ(Q),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(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,DZ.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-word-element",this.ttsWordElementHighlights,DZ.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Z,Q,J,Y){let X=(G)=>G.nodeType===Node.ELEMENT_NODE?G:d(G);for(let G of Z){let j=G.commonAncestorContainer,B=m(j)?j:X(j);if(!B)continue;let V=[],K=X(G.startContainer),U=X(G.endContainer);for(let $ of[K,U]){let z=$;while(z){if(z.matches?.(Y))V.push(z);z=d(z)}}if(!m(B)&&B.matches?.(Y))V.push(B);V.push(...Array.from(B.querySelectorAll(Y)));for(let $ of new Set(V)){try{if(!G.intersectsNode($)&&!Q0($,K)&&!Q0($,U))continue}catch{continue}$.setAttribute(Q,"true"),J.add($)}}}clearTTSWord(){if(!this.supported)return;zZ(u5,this.ttsWordRanges),this.ttsWordRanges.clear();for(let Z of this.ttsWordElementHighlights)Z.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.supported)return;zZ(p5,this.ttsSentenceRanges),this.ttsSentenceRanges.clear();for(let Z of this.ttsSentenceElementHighlights)Z.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){if(this.clearTTSWord(),this.clearTTSSentence(),G0.source===this.ttsStyleSource)G0.source=null;this.ttsStyleSource=null}addAnnotation(Z,Q=IZ.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,Y=Z.cloneRange();FZ(Y.startContainer);let X={id:J,range:Y,type:g5.ANNOTATION,color:Q,timestamp:Date.now()};if(this.annotations.set(J,X),this.supported)E0(s0(Q)).add(Y);return J}removeAnnotation(Z){let Q=this.annotations.get(Z);if(!Q){console.warn(`[HighlightCoordinator] Annotation ${Z} not found`);return}if(this.supported)zZ(s0(Q.color),[Q.range]);this.annotations.delete(Z)}clearAnnotations(){if(this.supported)for(let Z of this.annotations.values())zZ(s0(Z.color),[Z.range]);this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(Z){return this.annotations.get(Z)??null}changeAnnotationColor(Z,Q){let J=this.annotations.get(Z);if(!J)return;let Y=J.color;if(Y===Q)return;if(J.color=Q,this.supported)zZ(s0(Y),[J.range]),E0(s0(Q)).add(J.range)}exportAnnotations(Z=document.body){return this.getAnnotations().map((Q)=>({...this.rangeSerializer.serialize(Q.range,Z),id:Q.id,color:Q.color,timestamp:Q.timestamp}))}importAnnotations(Z,Q=document.body){let J=0;for(let Y of Z){let X=this.rangeSerializer.deserialize(Y,Q);if(X)this.addAnnotation(X,Y.color),J++}return J}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}updateTTSHighlightStyle(Z,Q){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((G)=>{let j=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(G);return j?{r:parseInt(j[1],16),g:parseInt(j[2],16),b:parseInt(j[3],16)}:null})(Z);if(!X)return;G0.override={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Q)),owner:this},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;if(this.clearTTS(),this.clearAnnotations(),G0.override?.owner===this)G0.override=null;this.themeObserver?.disconnect(),this.themeObserver=null}}import{applyMediaFragment as Q2,enforceMediaFragment as J2}from"@pie-players/pie-players-shared/media";import{createPieLogger as Y2,isTtsDebugEnabled as n9}from"@pie-players/pie-players-shared/pie";import{isUnsupportedMediaAssetVersion as A6,normalizeMediaFragment as _6,normalizeMediaSources as O6,trimmedOrUndefined as M6}from"@pie-players/pie-players-shared/media";function v8(Z){if(!Z)return null;let Q=Z.payload;if(!Q||typeof Q!=="object")return null;let J=Q.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(A6(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 Y=O6(J.sources);if(Y.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:Y,fragment:_6(Q.fragment),label:M6(J.label)}}var L6="[data-pie-shell-root]";var h8=(Z)=>Z?fZ(Z,L6):null;var vZ="en-US",c5=(Z,Q)=>{let J=!Z?null:Z.nodeType===1?Z:d(Z);while(J){let Y=J.getAttribute("lang");if(Y!==null)return Y.trim()||void 0;if(Q&&J===Q)return;J=d(J)}return},m8=(Z)=>{let Q;for(let J of Z.querySelectorAll("[lang]")){let Y=J.parentElement?.closest("[lang]");if(Y&&Y!==Z&&Z.contains(Y))continue;let X=J.getAttribute("lang")?.trim();if(!X)return;if(Q===void 0)Q=X;else if(Q.toLowerCase()!==X.toLowerCase())return}return Q},d5=(Z,Q={})=>{let J=Q.boundary!==void 0?Q.boundary:h8(Z);return(J?c5(Z,J):void 0)||Q.contentLanguage?.trim()||void 0},u8=(Z,Q={})=>d5(Z,Q)??vZ;var y=(Z)=>Z.trim().replace(/\s+/g," "),d8=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,hZ=(Z)=>{if(Z.hidden)return!0;if(Z.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(Z.getAttribute("aria-hidden")==="true")return!0;if(Z.hasAttribute("inert"))return!0;let Q=Z.classList;if(Q?.contains("sr-only")||Q?.contains("pie-sr-only")||Q?.contains("visually-hidden"))return!0;if(typeof window<"u"){let J=window.getComputedStyle(Z);if(J.display==="none"||J.visibility==="hidden")return!0;let Y=Number.parseFloat(J.width||"0"),X=Number.parseFloat(J.height||"0"),G=Number.isFinite(Y)&&Number.isFinite(X)&&Y<=1&&X<=1,j=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")&&G&&(J.overflow==="hidden"||j))return!0;if(J.opacity==="0"&&G)return!0}return!1},n0=(Z,Q)=>{let J=Z.nodeType===1?Z:g(Z);while(J){if(hZ(J))return!0;if(Q&&J===Q)break;J=g(J)}return!1},p8="data-tts-suppress",i8=new Set(["computer-read-aloud","all"]),g8=new Set([...i8,"screen-reader"]),c8=new Set,P6=(Z)=>{let Q=Z.getAttribute?.(p8);if(Q===null||Q===void 0)return!1;let J=Q.trim().toLowerCase();if(i8.has(J))return!0;if(g8.has(J))return!1;if(!c8.has(J))c8.add(J),console.warn(`[tts] ${p8}="${Q}" is not one of ${Array.from(g8).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},mZ=(Z,Q)=>{let J=Z.nodeType===1?Z:g(Z);while(J){if(P6(J))return!0;if(Q&&J===Q)break;J=g(J)}return!1},$0=(Z,Q)=>n0(Z,Q)||mZ(Z),i5=(Z,Q)=>{if(typeof Z.intersectsNode!=="function")return{text:Z.toString(),filtered:!1};let J=[],Y=!1;for(let X of C0(Q))if(X0(Z,X))if($0(X,Q))Y=!0;else J.push(l5(X,Z));return{text:J.join(""),filtered:Y}},l5=(Z,Q)=>{let J=Z.textContent||"",Y=Z===Q.startContainer?Q.startOffset:0,X=Z===Q.endContainer?Q.endOffset:J.length;return J.slice(Y,X)},HZ=(Z,Q,J)=>{let Y=null,X=null;for(let G of C0(Q)){if($0(G,J))continue;let j=G.textContent||"",B=j.search(/\S/);if(B===-1)continue;Y??={node:G,offset:B},X={node:G,offset:j.trimEnd().length-1}}if(!Y||!X)return X0(Z,Q);return $Z(Z,Y.node,Y.offset)&&$Z(Z,X.node,X.offset)},s5=(Z,Q,J)=>{if(!Z||!Q)return!1;if(/\s/.test(Z)||/\s/.test(Q))return!1;let Y=J?.boundarySpacingMode??"segmenterPreferred";if(Y==="none")return!1;if(Y==="segmenterPreferred")try{let j=globalThis.Intl?.Segmenter;if(typeof j==="function"){let B=new j(J?.locale,{granularity:"word"});if(Array.from(B.segment(`${Z}${Q}`)).filter((U)=>U.isWordLike!==!1&&U.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(Z),G=/[A-Za-z0-9]/.test(Q);return X&&G},S0=(Z,Q)=>{let J=new Map;if(typeof document>"u")return{text:"",map:J};let Y=[],X=0,G=!0,j=!1,B=null,V=null;for(let U of C0(Z))if(g(U)&&!$0(U,Z)){let z=U.textContent||"",D=z.match(/\S/),M=D?D[0]:null;if(!G&&!j&&s5(V,M,Q)){if(Y.push(" "),B)J.set(X,B);X++,j=!0}for(let P=0;P<z.length;P++){let H=z[P],N=/\s/.test(H);if(G){if(!N)G=!1,Y.push(H),J.set(X,{node:U,offset:P}),B={node:U,offset:P},X++,j=!1,V=H}else if(N){if(!j)Y.push(" "),J.set(X,{node:U,offset:P}),B={node:U,offset:P},X++;j=!0}else Y.push(H),J.set(X,{node:U,offset:P}),B={node:U,offset:P},X++,j=!1,V=H}}let K=Y.join("").trimEnd();while(J.has(K.length))J.delete(K.length);return{text:K,map:J}};var N6=/^\s*<speak[\s/>]/i,pZ=(Z)=>N6.test(Z),w6=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),l8=new Set(["audio","phoneme"]),n8=(Z)=>Z.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),uZ=(Z,Q,J)=>{for(let Y=0;Y<Q.length;Y++)Z.push({char:Q[Y],rawOffset:J===null?null:J+Y})},R6=(Z,Q,J)=>{let Y=Q.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!Y)return 0;return uZ(Z,n8(Y[0]),J),Y[0].length},s8=(Z)=>{Z.push({char:" ",rawOffset:null})},C6=(Z)=>{let Q=new Map,J=[],Y=!0;for(let X of Z){if(/\s/.test(X.char)){if(!Y&&J.length>0){if(J.push(" "),X.rawOffset!==null)Q.set(X.rawOffset,J.length-1)}Y=!0;continue}if(J.push(X.char),X.rawOffset!==null)Q.set(X.rawOffset,J.length-1);Y=!1}while(J.length>0&&J[J.length-1]===" ")J.pop();for(let[X,G]of Q)if(G>=J.length)Q.delete(X);return{text:J.join(""),rawToSpokenOffsetMap:Q}},b6=(Z)=>{return Z.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},E6=(Z,Q)=>{let J=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),Y=Z.match(J);return n8(Y?.[2]??Y?.[3]??"")||null},gZ=(Z)=>{let Q=[],J=!1,Y=!1,X=0;while(X<Z.length){let j=Z[X];if(j!=="<"){if(j==="&"){let z=R6(Q,Z,X);if(z>0){X+=z;continue}}uZ(Q,j,X),X++;continue}let B=Z.indexOf(">",X+1);if(B<0){uZ(Q,j,X),X++;continue}Y=!0;let V=Z.slice(X,B+1),K=b6(V),U=/^<\s*\//.test(V),$=/\/\s*>$/.test(V);if(!U&&K==="sub"){let z=E6(V,"alias");if(!z){J=!0,X=B+1;continue}uZ(Q,z,null);let D=Z.toLowerCase().indexOf("</sub>",B+1);X=D>=0?D+6:B+1;continue}if(!U&&K==="break"){s8(Q),X=B+1;continue}if(!U&&l8.has(K)){if(J=!0,$){X=B+1;continue}}if(K&&!w6.has(K)&&!l8.has(K)&&K!=="break"&&K!=="sub")J=!0;if(!U&&(K==="p"||K==="s"))s8(Q);X=B+1}let G=C6(Q);return{spokenText:y(G.text),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:Y}};var S6=d8(),T6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),y6=(Z)=>{let Q=Z.toLowerCase();return T6.get(Q)||Q},a5=(Z)=>{let Q=[];for(let J of Z.matchAll(S6)){let Y=J[0],X=J.index??0;Q.push({text:Y,normalized:y6(Y),start:X,end:X+Y.length})}return Q},x6=(Z)=>a5(Z).map((Q,J)=>({...Q,id:`speech-token-${J}`,sourceStart:Q.start,sourceEnd:Q.end,coordinateSystem:"normalized-speech"})),T0=(Z)=>{let Q=gZ(Z.speechText);return{speechText:Z.speechText,spokenText:Q.spokenText,tokens:x6(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},o5=(Z)=>Boolean(Z&&/^<[^>]+>$/.test(Z.trim())),r0=(Z)=>{if(!Z||o5(Z))return null;return T0({speechText:Z}).tokens[0]?.normalized??null},k6=(Z,Q)=>Z.find((J)=>J.start<=Q&&Q<J.end)||null,f6=(Z,Q)=>{let J=Z.rawToSpokenOffsetMap.get(Q);if(J!==void 0)return J;for(let Y=Q;Y<Z.speechText.length;Y++){let X=Z.rawToSpokenOffsetMap.get(Y);if(X!==void 0)return X;if(Z.speechText[Y]===">")break}return null},n5=(Z,Q,J)=>{if(Q===null)return null;let Y=k6(Z.tokens,Q);if(!Y)return null;return{token:Y,start:Q,length:Math.max(1,Math.min(J,Y.end-Q)),confidence:0.75}},r5=(Z,Q)=>Boolean(Z&&Q&&Z.token.normalized===Q),t5=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||o5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=r0(Z.boundaryWord),Y=n5(Z.tokenization,f6(Z.tokenization,Z.position),Q),X=n5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(r5(Y,J))return{...Y,confidence:1};if(r5(X,J))return{...X,confidence:1};if(J)return null;return Z.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||X:X||Y},r8=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||o5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=r0(Z.boundaryWord),Y=n5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(r5(Y,J))return{...Y,confidence:1};if(J)return null;return Y};var e5=10,I6=0.12,v6=[{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}],h6=(Z,Q)=>{let J=[];for(let Y=0;Y<Z.length;Y++){for(let X=0;X<Q.length;X++)if(Z[Y].normalized===Q[X].normalized)J.push({spokenStartToken:Y,spokenEndToken:Y+1,visibleToken:X,score:e5});for(let X of v6){let G=Z.slice(Y,Y+X.phrase.length);if(G.length!==X.phrase.length)continue;if(!G.every((j,B)=>j.normalized===X.phrase[B]))continue;for(let j=0;j<Q.length;j++){if(Q[j].text!==X.visible)continue;J.push({spokenStartToken:Y,spokenEndToken:Y+X.phrase.length,visibleToken:j,score:X.score})}}}return J},m6=(Z,Q)=>{let J=h6(Z,Q).sort((V,K)=>Z[V.spokenStartToken].start-Z[K.spokenStartToken].start||Q[V.visibleToken].start-Q[K.visibleToken].start),Y=Array(J.length).fill(0),X=Array(J.length).fill(-1);for(let V=0;V<J.length;V++){let K=J[V];Y[V]=K.score;for(let U=0;U<V;U++){let $=J[U];if($.spokenEndToken<=K.spokenStartToken&&$.visibleToken<K.visibleToken){let z=K.spokenStartToken-$.spokenEndToken,D=K.visibleToken-$.visibleToken-1,M=Math.max(0,Math.abs(z-D)-2),P=Y[U]+K.score-M;if(P>Y[V])Y[V]=P,X[V]=U}}}let G=-1;for(let V=0;V<Y.length;V++)if(G<0||Y[V]>Y[G])G=V;if(G<0)return[];let j=[],B=G;while(B>=0)j.unshift(J[B]),B=X[B];return j.map((V)=>{let K=Z[V.spokenStartToken],U=Z[V.spokenEndToken-1],$=Q[V.visibleToken];return{spokenStart:K.start,spokenEnd:U.end,visibleStart:$.start,visibleEnd:$.end,score:V.score}})},u6=(Z,Q,J)=>{if(Z.length===0)return 0;let Y=Z.length/Math.max(1,Math.min(Q.length,J.length)),X=Z.reduce((G,j)=>G+j.score,0)/Z.length/e5;return Math.min(1,Y*X)},cZ=(Z)=>{let Q=T0({speechText:Z.speechText}),J=y(Z.visibleText),Y=Q.tokens,X=a5(J),G=Q.unsupportedSemantic?[]:m6(Y,X),j=u6(G,Y,X),B=Q.spokenText===J&&Q.spokenText.length>0,V=G.length===1&&G[0].score===e5&&Y.length<=2&&X.length<=2,K=(G.length>=2||V)&&j>=I6,U=Q.unsupportedSemantic?"region-fallback":B?"exact-word":K?"anchor-span":"region-fallback";return{speech:Q,visibleText:J,playbackMode:U,anchors:G,confidence:j}},a8=(Z,Q)=>{if(Z.playbackMode==="region-fallback")return null;let J=Z.anchors.find((G)=>G.spokenStart<=Q&&Q<G.spokenEnd);if(J)return{start:J.visibleStart,end:J.visibleEnd};let Y=null,X=null;for(let G of Z.anchors){if(G.spokenEnd<=Q){Y=G;continue}if(G.spokenStart>Q){X=G;break}}if(Y&&X)return{start:Math.min(Y.visibleStart,X.visibleStart),end:Math.max(Y.visibleEnd,X.visibleEnd)};return null};var p6=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"]]]),g6=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),o8=new Map([["2",["squared"]],["3",["cubed"]]]),c6=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),d6=(Z)=>Z.replace(/\s+/g," ").trim(),y0=(Z)=>(Z.localName||Z.tagName||"").toLowerCase(),i6=(Z)=>Z.nodeType===Node.ELEMENT_NODE,a0=(Z)=>Array.from(Z.childNodes).filter(i6),Z7=(Z)=>d6(Z.textContent||""),j0=(Z,Q)=>({type:"element-range",quality:Q,element:Z}),l6=(Z)=>{switch(Z){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"}},s6=(Z,Q)=>{if(Q==="operator"){if(Z==="−")return"-";return Z}return Z.toLowerCase()},n6=(Z,Q,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return o8.get(Z)??[];if(Z==="|")return["absolute value"];if(Q==="operator")return p6.get(Z)||[];return[]},x0=(Z)=>{let Q=Z.normalized??s6(Z.text,Z.kind||"unknown");return{id:`math-token-${Z.state.nextId++}`,kind:Z.kind,role:Z.role,text:Z.text,normalized:Q,spokenAliases:n6(Z.text,Z.kind,Z.role),sourceElement:Z.sourceElement,path:Z.path,target:Z.target||j0(Z.sourceElement,"element-range"),optional:Z.optional}},k0=(Z,Q,J="tokens")=>{Z[J].push(Q)},t8=(Z,Q,J)=>{a0(Z).forEach((Y,X)=>B0(Y,Q,`${J}/${y0(Y)}[${X}]`))},r6=(Z,Q,J)=>{let Y=a0(Z);if(Y[0])B0(Y[0],Q,`${J}/numerator`);if(k0(Q,x0({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:Z,path:J,target:j0(Z,"element-range")})),Y[1])B0(Y[1],Q,`${J}/denominator`)},a6=(Z,Q,J)=>{let Y=Z.getAttribute("open")||"(",X=Z.getAttribute("close")||")";k0(Q,x0({state:Q,kind:"operator",role:Y==="|"?"absolute-value-fence":"open-fence",text:Y,sourceElement:Z,path:`${J}/open`,target:j0(Z,"element-range")})),t8(Z,Q,J),k0(Q,x0({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Z,path:`${J}/close`,target:j0(Z,"element-range")}))},o6=(Z,Q,J)=>{let Y=a0(Z);if(Y[0])B0(Y[0],Q,`${J}/base`);let X=Y[1];if(!X)return;let G=Z7(X);if(o8.has(G)){k0(Q,x0({state:Q,kind:"structure",role:"superscript",text:G,normalized:G,sourceElement:X,path:`${J}/exponent`,target:j0(Z,"element-range")}));return}B0(X,Q,`${J}/exponent`)},t6=(Z,Q,J,Y)=>{k0(Q,x0({state:Q,kind:"structure",role:Y,text:Z7(Z)||Y,normalized:`\x00${Y}`,sourceElement:Z,path:J,target:j0(Z,"element-range")}))},e6=(Z,Q,J)=>{let Y=0;for(let X of a0(Z)){if(y0(X)==="mtr"||y0(X)==="mlabeledtr")Y++,k0(Q,x0({state:Q,kind:"layout",role:"table-row",text:`row-${Y}`,normalized:`row-${Y}`,sourceElement:X,path:`${J}/row[${Y}]`,target:j0(X,"region-fallback")}),"layoutTargets");B0(X,Q,`${J}/${y0(X)}[${Y}]`)}},Z3=(Z,Q,J)=>{let Y=Z7(Z);if(!Y)return;let X=l6(y0(Z)),G=X==="operator"?g6.get(Y):void 0,j=G??(X==="operator"&&(Y==="("||Y===")")?"grouping-fence":X);k0(Q,x0({state:Q,kind:X,role:j,text:Y,sourceElement:Z,path:J,target:G&&Z.parentElement?j0(Z.parentElement,"region-fallback"):void 0,optional:Boolean(G)||j==="grouping-fence"}))},B0=(Z,Q,J)=>{let Y=y0(Z);switch(Y){case"annotation":case"annotation-xml":return;case"semantics":{let X=a0(Z).find((G)=>{let j=y0(G);return j!=="annotation"&&j!=="annotation-xml"});if(X)B0(X,Q,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":Z3(Z,Q,J);return;case"mfrac":r6(Z,Q,J);return;case"msup":o6(Z,Q,J);return;case"mfenced":a6(Z,Q,J);return;case"mtable":e6(Z,Q,J);return;case"mphantom":return;case"maction":{let X=a0(Z)[0];if(X)B0(X,Q,`${J}/action`);return}default:{let X=c6.get(Y);if(X){t6(Z,Q,J,X);return}t8(Z,Q,J)}}},e8=(Z)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return B0(Z,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:j0(Z,"region-fallback")}};var Z9=(Z)=>{if(!Z.boundary)return null;return Z.alignment.segments.find((J)=>J.speechTokenIds.includes(Z.boundary.token.id))?.target||null};var Q3=(Z)=>{let Q=[],J=new Set,Y=(X)=>{let G=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(G.length===0)return;let j=G.join(" ");if(J.has(j))return;J.add(j),Q.push(G)};Y(Z.normalized);for(let X of Z.spokenAliases)Y(X);return Q},Q9=(Z,Q,J)=>{let Y=0;for(let X of J){if(X.length<=Y)continue;let G=!0;for(let j=0;j<X.length;j++){let B=Z[Q+j];if(!B||B.normalized.toLowerCase()!==X[j]){G=!1;break}}if(G)Y=X.length}return Y},J3=(Z,Q)=>{let J=[],Y=0;for(let X of Q){let G=Q3(X);if(X.optional){let j=Q9(Z,Y,G);if(j>0)J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;continue}while(Y<Z.length){let j=Q9(Z,Y,G);if(j>0){J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;break}Y++}}return J},Y3=(Z,Q,J)=>{let Y=J.filter((j)=>!j.optional).length,X=Z.filter((j)=>!j.math.optional).length,G=Z.reduce((j,B)=>j+B.speechTokens.length,0);return Y>0&&X===Y&&G===Q.length},X3=(Z)=>Z.map(({speechTokens:Q,math:J})=>({speechTokenIds:Q.map((Y)=>Y.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),J9=(Z)=>{let Q=Z.minExactWordConfidence??0.95,J=J3(Z.speech.tokens,Z.math.tokens),Y=Y3(J,Z.speech.tokens,Z.math.tokens)?1:0;return{segments:Y>=Q?X3(J):[],confidence:Y,fallbackTarget:Z.math.expressionTarget}};var o0=(Z)=>{let Q=T0({speechText:Z.speechText}),J=e8(Z.mathElement);return{speech:Q,math:J,result:J9({speech:Q,math:J})}};var Y9=(Z,Q)=>{let J=r8({tokenization:Z.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return Z9({alignment:Z.result,boundary:J})},X9=(Z,Q)=>{let J=r0(Q.boundaryWord);if(!J)return null;let Y=Z.math.tokens.filter((X)=>X.normalized.toLowerCase()===J||X.spokenAliases.some((G)=>G.toLowerCase()===J));return Y.length===1?Y[0].target:null};var G3=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"]),j3=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"]),G9=(Z)=>Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),B3=(Z)=>G9(Z).replace(/"/g,"""),W3=(Z,Q)=>{let J=Z.toLowerCase(),Y=Q.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!j3.has(J))return!0;if(Y.includes("javascript:"))return!0;if(Y.includes("data:text/html"))return!0;return!1},V3=(Z)=>{let Q=Z.localName.toLowerCase();if(!G3.has(Q))return!1;let J=Z.namespaceURI;return!J||J==="http://www.w3.org/1998/Math/MathML"||J==="http://www.w3.org/1999/xhtml"},j9=(Z)=>{if(Z.nodeType===Node.TEXT_NODE)return G9(Z.textContent||"");if(Z.nodeType===Node.COMMENT_NODE)return"";if(Z.nodeType!==Node.ELEMENT_NODE)return null;let Q=Z;if(!V3(Q))return null;let J=Q.localName.toLowerCase(),Y=[];for(let j of Array.from(Q.attributes)){let B=j.name.toLowerCase();if(W3(B,j.value))continue;if(B==="xmlns"&&j.value!=="http://www.w3.org/1998/Math/MathML")return null;Y.push(`${B}="${B3(j.value)}"`)}if(J==="math"&&!Y.some((j)=>j.startsWith("xmlns=")))Y.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let j of Array.from(Q.childNodes)){let B=j9(j);if(B===null)return null;X.push(B)}let G=Y.length>0?` ${Y.join(" ")}`:"";return`<${J}${G}>${X.join("")}</${J}>`},K3=(Z)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Z,"application/xml");return null},t0=(Z)=>{let Q=String(Z||"").trim();if(!Q)return null;let J=K3(Q);if(!J)return null;if(J.getElementsByTagName("parsererror").length>0)return null;let Y=J.documentElement;if(!Y||Y.localName.toLowerCase()!=="math")return null;return j9(Y)};var W9=(Z)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Z}),Q7=(Z)=>Z.classList?.contains("MathJax")||Z.tagName?.toLowerCase()==="mjx-container",V9=(Z)=>Z.tagName?.toLowerCase()==="mjx-assistive-mml",J7=(Z)=>{let Q=Z.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},q3=(Z)=>{let Q=Z.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},U3=(Z)=>{return b0(Z,"mjx-assistive-mml math")?.outerHTML||null},$3=(Z)=>{if(Z.tagName.toLowerCase()==="math")return t0(Z.outerHTML);let Q=q3(Z);if(Q){let J=t0(Q);if(J)return J}if(Q7(Z)){let J=U3(Z);if(J){let Y=t0(J);if(Y)return Y}}return null},F3=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),z3=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),D3=(Z,Q)=>{let J=g(Z);while(J&&J!==Q){let Y=(J.getAttribute("role")||"").toLowerCase(),X=J.tagName.toUpperCase();if(F3.has(X)||z3.has(Y))return J;J=g(J)}return Q},H3=(Z)=>Boolean(typeof Z.querySelector==="function"&&b0(Z,"math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Z.tagName?.toLowerCase()==="math"||Z.hasAttribute?.("data-mathml")||Q7(Z),f0=(Z,Q,J)=>{if(/[.,;:!?]/.test(Q)&&Z.chars.length>0&&Z.chars[Z.chars.length-1]===" ")Z.chars.pop(),Z.position--,Z.map.delete(Z.position);if(Z.chars.push(Q),J)Z.map.set(Z.position,J),Z.lastMapped=J;else if(Z.lastMapped)Z.map.set(Z.position,Z.lastMapped);Z.position++},K9=(Z,Q)=>{if(Z.inLeadingWhitespace||Z.lastCharWasWhitespace||Z.chars.length===0)return!1;let J=Z.chars[Z.chars.length-1];return s5(J,Q,Z.options)},q9=(Z,Q,J=0,Y=(Q.textContent||"").length)=>{let X=Q.textContent||"",G=!1;for(let j=J;j<Y;j++){let B=X[j],V=/\s/.test(B);if(Z.inLeadingWhitespace){if(!V)Z.inLeadingWhitespace=!1,f0(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1;continue}if(V){if(!Z.lastCharWasWhitespace)f0(Z," ",{node:Q,offset:j});Z.lastCharWasWhitespace=!0;continue}if(!G&&K9(Z,B))f0(Z," ",{node:Q,offset:j});f0(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1}},A3=(Z,Q)=>{for(let J=0;J<Q.text.length;J++){let Y=Q.text[J],X=/\s/.test(Y),G=Q.map.get(J),j=G?{node:G.node,offset:G.offset}:Z.lastMapped?{node:Z.lastMapped.node,offset:Z.lastMapped.offset}:null;if(Z.inLeadingWhitespace){if(X)continue;Z.inLeadingWhitespace=!1}if(X){if(!Z.lastCharWasWhitespace)f0(Z," ",j);Z.lastCharWasWhitespace=!0;continue}if(J===0&&K9(Z,Y))f0(Z," ",j);f0(Z,Y,j),Z.lastCharWasWhitespace=!1}},_3=(Z)=>{if(typeof DOMParser>"u")return"";let Q=new DOMParser().parseFromString(Z,"application/xml");if(Q.getElementsByTagName("parsererror").length>0)return"";let J=[],Y=(X)=>{if(X.nodeType===3){let j=X.textContent||"";if(j.trim())J.push(j);return}if(X.nodeType!==1)return;let G=X;if(J7(G))return;for(let j of Array.from(G.childNodes))Y(j)};return Y(Q.documentElement),y(J.join(" "))},O3=(Z,Q)=>{let J=new Map,Y=Q7(Z)?b0(Z,"mjx-assistive-mml math"):null;if(!Y)return J;let X=[],G=(B)=>{if(B.nodeType===3){let V=B.textContent||"";for(let K=0;K<V.length;K++)if(!/\s/.test(V[K]))X.push({node:B,offset:K});return}if(B.nodeType!==1||J7(B))return;for(let V of U0(B))G(V)};G(Y);let j=0;for(let B=0;B<Q.length;B++){if(/\s/.test(Q[B]))continue;let V=X[j];if(V?.node.textContent?.[V.offset]!==Q[B])return new Map;J.set(B,V),j++}return j===X.length?J:new Map},M3=(Z,Q,J)=>{let Y=W9(J),X=(B)=>{if($0(B,Z))return;if(B.nodeType===3){q9(Y,B);return}if(B.nodeType!==1)return;let V=B;if(V9(V)||J7(V))return;for(let K of U0(V))X(K)};X(Z),U9(Y);let G=y(Y.chars.join(""));if(G)return{text:G,map:Y.map};let j=_3(Q);if(!j)return S0(Z,J);return{text:j,map:O3(Z,j)}},U9=(Z)=>{while(Z.chars.length>0&&/\s/.test(Z.chars[Z.chars.length-1]))Z.chars.pop(),Z.position--,Z.map.delete(Z.position)},B9=(Z,Q,J)=>{let Y=W9(Q),X=[],G=0,j,B=!1,V=()=>{let $=y(Y.chars.slice(G,Y.chars.length).join(""));if($)X.push({type:"text",text:$,sourceElement:j});G=Y.chars.length,j=void 0},K=($)=>{if($0($,Z))return;if(J&&!X0(J,$))return;if($.nodeType===3){let M=D3($,Z);if(j&&M!==j)V();j=M;let P=$;q9(Y,P,J?.startContainer===P?J.startOffset:void 0,J?.endContainer===P?J.endOffset:void 0);return}if($.nodeType!==1)return;let z=$;if(V9(z))return;let D=$3(z);if(D&&(!J||HZ(J,z,Z))){V();let M=M3(z,D,Q);A3(Y,M);let P=y(M.text);X.push({type:"math",mathml:D,fallbackText:P,sourceElement:z}),G=Y.chars.length,B=!0;return}for(let M of U0(z))K(M)};for(let $ of U0(Z))K($);return U9(Y),V(),{visibleText:Y.chars.join(""),map:Y.map,chunks:X,containsMathMarkup:B}},F0=(Z,Q,J)=>{if(J)return B9(Z,Q,J);if(!H3(Z)){let{text:Y,map:X}=S0(Z,Q);return{visibleText:Y,map:X,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return B9(Z,Q)};import{createPieLogger as P3,isTtsDebugEnabled as N3}from"@pie-players/pie-players-shared/pie";var dZ=P3("tts-math-speech",N3),$9=Promise.resolve(),w3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",R3=(Z)=>{let Q=null,J=!1;return(Y)=>{if(!Q){H9(Y);let X=Z();Q=X,X.catch((G)=>{if(Q===X)Q=null;if(J){dZ.debug("speech-rule-engine failed to load again",G);return}J=!0,dZ.warn("speech-rule-engine failed to load; math reads as its visible text until a later read loads it.",G)})}return Q}},C3=R3(()=>import("./chunks/sre-engine-dq0w45fv.js").then(({default:Z})=>{if(!Z||typeof Z.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Z})),Y7=(Z)=>{let Q=null;return()=>{return Q??=C3(W0(Z)?.engineOptions),Q}},b3=(Z)=>Z==="en"?"clearspeak":"mathspeak",F9=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),z9=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,W0=(Z)=>{if(!F9(Z))return;let Q=z9(Z.domain),J=z9(Z.style),Y=F9(Z.engineOptions)?Z.engineOptions:void 0;if(!Q&&!J&&!Y)return;return{...Q?{domain:Q}:{},...J?{style:J}:{},...Y?{engineOptions:Y}:{}}},E3=async(Z,Q,J,Y)=>{let X=w3(Q),G=W0(Y),j=G?.engineOptions||{};await Z.setupEngine?.({...D9(j),...j,locale:X,domain:G?.domain||b3(X),style:G?.style||"default",modality:"speech",markup:J}),await Z.engineReady?.()},S3=async(Z)=>{let Q=$9.then(Z,Z);return $9=Q.then(()=>{return},()=>{return}),Q},A9=async(Z,Q,J,Y,X)=>S3(async()=>{return await E3(Z,J,Y,X),Z.toSpeech(Q)}),T3=(Z)=>Z.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),y3=async(Z,Q,J,Y)=>{try{let X=T3(await A9(Z,Q,J,"ssml",Y));return X.includes("<speak")?X:null}catch(X){return dZ.debug("math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},e0=async(Z,Q={})=>{if(!Z.some((K)=>K.type==="math"))return{speechText:y(Z.map((K)=>K.type==="text"?K.text:K.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let J=null,Y=!1,X=!1,G=Q.loadSre||Y7(Q.mathSpeech),j=[];for(let K of Z){if(K.type==="text"){j.push(K.text);continue}try{if(!J)J=await G();let U=y(await A9(J,K.mathml,Q.language,"none",Q.mathSpeech));if(U){j.push(U),Y=!0;continue}X=!0,j.push(K.fallbackText)}catch(U){X=!0,dZ.debug("math speech generation failed; using visible fallback",{message:U instanceof Error?U.message:String(U)}),j.push(K.fallbackText)}}let B=y(j.join(" ")),V;if(Q.produceSsml&&J&&Y&&Z.length===1&&Z[0].type==="math")V=await y3(J,Z[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:Y,usedFallback:X,ssml:V}};var x3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",k3="sre-v1",f3=256,X7=(Z)=>{if(Array.isArray(Z))return`array:[${Z.map(X7).join(",")}]`;if(Z&&typeof Z==="object")return`object:{${Object.entries(Z).sort(([Q],[J])=>Q.localeCompare(J)).map(([Q,J])=>`${JSON.stringify(Q)}:${X7(J)}`).join(",")}}`;if(Z===null)return"null:null";if(typeof Z>"u")return"undefined:";if(typeof Z==="function")return`function:${Z.name||"anonymous"}`;if(typeof Z==="symbol")return`symbol:${String(Z)}`;if(typeof Z==="bigint")return`bigint:${Z.toString()}`;if(typeof Z==="number")return Number.isFinite(Z)?`number:${Z}`:`number:${String(Z)}`;return`${typeof Z}:${JSON.stringify(Z)}`},_9=(Z,Q,J,Y)=>`${k3}\x00${x3(Z)}\x00${Q?"ssml":"plain"}\x00${X7(J??null)}\x00${Y}`,G7=(Z={})=>{let Q=Math.max(1,Z.maxEntries??f3),J=Z.resolve??((G,j)=>e0([G],j)),Y=new Map,X=(G,j)=>{Y.delete(G),Y.set(G,j);while(Y.size>Q){let B=Y.keys().next().value;if(B!==void 0)Y.delete(B)}};return async(G,j)=>{let B=W0(j.mathSpeech),V=j.produceSsml===!0,K=_9(j.language,V,B,G.mathml),U=Y.get(K);if(U)return Y.delete(K),Y.set(K,U),U;let $=await J(G,{...j,mathSpeech:B});if($.usedFallback)return $;if(V&&$.ssml&&Q>1)X(_9(j.language,!1,B,G.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(K,$),$}};var O9=(Z,Q)=>{let J=r0(Q.word);if(Z.id!==Q.chunkId)return{chunkId:Q.chunkId,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Q.providerOffsetSpace==="unknown"||Z.offsetSpace==="unsupported")return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let Y=t5({tokenization:Z.catalogAlignment?.speech??T0({speechText:Z.speechText}),position:Q.position,length:Q.length,boundaryWord:Q.word});if(!Y)return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:Y.start,chunkSpokenEnd:Y.start+Y.length,confidence:Y.confidence,reason:Z.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var I0=(Z)=>{if(Z.semanticTarget)return{activeTarget:Z.semanticTarget,regionTarget:Z.regionTarget,quality:Z.semanticTarget.quality==="exact-word"?"exact-word":Z.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:Z.confidence,reason:Z.reason};if(Z.expressionTarget)return{activeTarget:Z.expressionTarget,regionTarget:Z.regionTarget,quality:"expression",confidence:Z.confidence,reason:Z.reason};return{activeTarget:null,regionTarget:Z.regionTarget,quality:"region",confidence:Z.confidence,reason:Z.reason}};var L9=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),j7="mi,mn,mo,mtext",P9="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",N9=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),w9=(Z)=>{if(Z.type==="text-range")return Z.node.parentElement;return Z.element},iZ=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},M9=(Z)=>{if(!Z)return!1;if(iZ(Z))return!1;return!n0(Z)},R9=(Z)=>{let Q=Z.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},B7=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},C9=(Z,Q)=>{if(Z.length===0)return!1;if(Z.length!==Q.length)return!1;for(let J=0;J<Z.length;J+=1){let Y=L9.get(Z[J].localName.toLowerCase());if(!Y)return!1;if(Q[J].localName.toLowerCase()!==Y)return!1}return!0},I3=(Z,Q)=>{if(!Z)return null;if(!L9.has(Z.localName.toLowerCase()))return null;if(Q.querySelector(N9))return null;let J=B7(Z),Y=Q.querySelector("mjx-math");if(!J||!Y)return null;let X=Array.from(J.querySelectorAll(j7)),G=X.indexOf(Z);if(G<0)return null;let j=Array.from(Y.querySelectorAll(P9));if(!C9(X,j))return null;let B=j[G];if(!B||!R9(B))return null;return B},b9=(Z)=>{let Q=iZ(Z);if(Q){if(Q.querySelector(N9))return"expression";let X=B7(Z)??Z,G=Q.querySelector("mjx-math");if(!G)return"expression";let j=Array.from(X.querySelectorAll(j7)),B=Array.from(G.querySelectorAll(P9));if(!C9(j,B))return"expression";return B.some((V)=>R9(V))?"token":"expression"}let J=B7(Z)??Z;return Array.from(J.querySelectorAll(j7)).some((X)=>!n0(X))?"token":"expression"},W7=(Z)=>{let Q=w9(Z),J=iZ(Q);if(J){let Y=I3(Q,J);if(Y)return{type:"element",quality:"semantic-token",element:Y};return{type:"element",quality:"expression",element:J}}if(Z.type==="text-range"){if(!M9(Z.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Z.node,startOffset:Z.startOffset,endOffset:Z.endOffset}}if(!M9(Z.element))return null;return{type:"element",quality:Z.quality==="region-fallback"?"expression":"semantic-token",element:Z.element}},E9=W7,S9=()=>{let Z=new WeakMap;return(Q)=>{let J=w9(Q),Y=iZ(J);if(!J||!Y)return W7(Q);if(Z.has(J))return Z.get(J)??null;let X=W7(Q);return Z.set(J,X),X}};var T9=(Z,Q,J,Y=Z.mathAlignments,X=E9)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let G=null;for(let j of Y){let B=Y9(j.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:J.word})||X9(j.alignment,{boundaryWord:J.word});if(!B)continue;let V=X(B);if(!V)continue;if(V.quality==="semantic-token")return V;G??=V}return G};var z0=(Z)=>Z.node.getRootNode?.()??Z.node,y9=(Z,Q)=>{try{let J=document.createRange();return J.setStart(Z.node,Z.offset),J.setEnd(Q.node,Q.offset+1),J}catch{return null}},V7=(Z,Q,J)=>{if(!Z||typeof document>"u")return null;if(J<=Q)return null;let Y=Z.get(Q),X=Z.get(Math.max(Q,J-1));if(!Y)return null;if(!X)X=Y;if(z0(X)!==z0(Y)){let G=z0(Y);X=Y;for(let j=Q+1;j<J;j++){let B=Z.get(j);if(B&&z0(B)===G)X=B}}return y9(Y,X)},D0=(Z,Q,J)=>{if(!Z||typeof document>"u"||J<=Q)return[];let Y=Z.get(Q);if(!Y)return[];let X=z0(Y),G=!1;for(let U=Q+1;U<J&&!G;U++){let $=Z.get(U);if($&&z0($)!==X)G=!0}if(!G){let U=V7(Z,Q,J);return U?[U]:[]}let j=[],B=null,V=null,K=()=>{if(B&&V){let U=y9(B,V);if(U)j.push(U)}B=null,V=null};for(let U=Q;U<J;U++){let $=Z.get(U);if(!$)continue;if(B&&z0(B)!==z0($))K();if(!B)B=$;V=$}return K(),j};var x9=(Z,Q)=>{if(!Z.catalogAlignment||Q.chunkSpokenStart===null)return null;let J=a8(Z.catalogAlignment,Q.chunkSpokenStart);if(!J)return null;let Y=D0(Z.visibleMap,J.start,J.end);if(Y.length===0)return null;return{type:"range",quality:Z.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:Y[0],ranges:Y.length>1?Y:void 0}};var v3=(Z)=>{let Q=D0(Z.visibleMap,0,Z.visibleText.length);return Q.length>1?Q:void 0},h3=(Z)=>Z.regionRange?{type:"range",quality:"region",range:Z.regionRange,ranges:v3(Z)}:Z.regionElement?{type:"element",quality:"region",element:Z.regionElement}:null,k9=(Z,Q=Z.chunk.mathAlignments)=>{if(Q.length!==1)return null;let J=Q[0]?.alignment.result.fallbackTarget;return J?Z.renderedMathTargetResolver(J):null},m3=(Z,Q)=>{if(!Z)return Q.mathAlignments;return Q.mathAlignments.filter(({element:J})=>{try{if(Z.type==="range")return(Z.ranges??[Z.range]).some((Y)=>X0(Y,J));if(Z.type==="element")return Q0(Z.element,J);return Q0(d(Z.node),J)}catch{return!1}})},f9=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),K7=(Z)=>Z.length===1?Z[0].element:null,u3=(Z,Q)=>Q.length>0&&Q.every(({element:J})=>Z.mathCapabilityByElement.get(J)==="token"),I9=3,p3=(Z,Q,J)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:Y,endContainer:X}=Q.range;if(Y===X&&Y.nodeType===I9)return!1;return J.some(({element:j})=>Z.mathCapabilityByElement.get(j)==="token"&&j.contains(Y)&&j.contains(X))},v9=(Z)=>Z?.type==="range"&&n0(Z.range.startContainer),g3=(Z,Q)=>{if(!v9(Q))return null;let{startContainer:J,endContainer:Y,startOffset:X,endOffset:G}=Q.range;if(J!==Y||J.nodeType!==I9)return null;return Z.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:G})},c3=(Z,Q)=>({chunk:Z,regionTarget:h3(Z),renderedMathTargetResolver:S9(),mathCapabilityByElement:new Map(Z.mathAlignments.map(({element:J})=>[J,Q?b9(J):"expression"])),heldTokenByElement:new Map}),h9=(Z)=>{let Q=Z.mathTokenHighlighting!==!1,J=new Map(Z.chunks.map((Y)=>[Y.id,c3(Y,Q)]));return{chunks:Z.chunks,resolveInitial(Y){let X=J.get(Y);if(!X)return f9();let G=K7(X.chunk.mathAlignments),j=G?X.mathCapabilityByElement.get(G):null;if(j==="expression")return I0({semanticTarget:null,expressionTarget:k9(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return I0({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:j==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(Y){let X=J.get(Y.chunkId);if(!X)return f9();let{chunk:G}=X,j=O9(G,Y),B=x9(G,j),V=m3(B,G),K=!B||V.length>0?T9(G,j,Y,V,X.renderedMathTargetResolver):null,U=K?.quality==="semantic-token"?K:g3(X,B)??K,$=Q&&U&&U.quality!=="expression"?U:null,z=U&&U.quality==="expression"?U:null;if($){let D=K7(V);if(D)X.heldTokenByElement.set(D,$);return I0({semanticTarget:$,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}if(B&&!v9(B)&&(Q?!p3(X,B,V):V.length===0))return I0({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason});if(u3(X,V)){let D=K7(V),M=D?X.heldTokenByElement.get(D)??null:null;return I0({semanticTarget:M,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:M?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return I0({semanticTarget:null,expressionTarget:z??k9(X,V),regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}}};var d3=(Z)=>{return Z.alignment?.speech.boundaryOffsetSpace??Z.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},i3=(Z)=>{if(Z.mathAlignments?.length)return Z.mathAlignments;if(Z.mathAlignment&&Z.sourceElement)return[{element:Z.sourceElement,alignment:Z.mathAlignment}];return[]},m9=(Z)=>{return(Z.chunks&&Z.chunks.length?Z.chunks:[{speechText:Z.speechText||"",visibleText:Z.visibleText||Z.speechText||"",sourceElement:Z.sourceElement||Z.contentRoot,regionElement:Z.regionElement||Z.sourceElement||Z.contentRoot,regionRange:Z.regionRange,visibleMap:Z.visibleMap}]).map((J,Y)=>({id:`tts-chunk-${Y}`,speechText:J.speechText,visibleText:J.visibleText,sourceElement:J.sourceElement,contentRoot:Z.contentRoot,regionElement:J.regionElement??J.sourceElement,regionRange:J.regionRange,visibleMap:J.visibleMap,catalogAlignment:J.alignment,mathAlignments:i3(J),offsetSpace:d3(J)}))};var l3=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),lZ=(Z,Q)=>{let J=fZ(Z,l3);if(J&&Q0(Q,J))return J;return Z};var v0=(Z,Q)=>{let J=Q?.useSentenceSegmenter===!1?void 0:globalThis.Intl?.Segmenter;if(typeof J==="function")try{let B=new J(Q?.locale,{granularity:"sentence"}),V=Array.from(B.segment(Z)).map((K)=>({text:K.segment,offset:K.index})).filter((K)=>K.text.trim().length>0);if(V.length>0)return V}catch{}let Y=/[^.!?]+(?:[.!?]+|$)/g,X=Z.match(Y)||[Z],G=[],j=0;for(let B of X){let V=Z.indexOf(B,j);if(V===-1)continue;G.push({text:B,offset:V}),j=V+B.length}return G.length>0?G:[{text:Z,offset:0}]},q7=(Z,Q,J)=>{let Y=Math.max(1,Math.floor(Q)),X=[],G=-1,j=-1,B=()=>{if(G>=0)X.push({text:Z.slice(G,j),offset:G});G=-1},V=(K,U)=>{if(G>=0&&U-G<=Y){j=U;return}B();let $=K;while(U-$>Y){let D=Z.slice($,$+Y+1).search(/\s\S*$/),M=D>0?$+D:$+Y;X.push({text:Z.slice($,M).trimEnd(),offset:$}),$=M;while($<U&&/\s/.test(Z[$]))$++}if($<U)G=$,j=U};for(let K of v0(Z,J)){let U=K.text.search(/\S/);if(U===-1)continue;let $=K.offset+U;V($,K.offset+K.text.trimEnd().length)}return B(),X};var s3=(Z,Q)=>e0([Z],Q),n3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",r3=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),a3=new Set(["heading","listitem","option","radio"]),o3=(Z)=>{if(Z.type!=="text"||!Z.sourceElement)return!1;let Q=Z.sourceElement.tagName.toUpperCase(),J=(Z.sourceElement.getAttribute("role")||"").toLowerCase();return r3.has(Q)||a3.has(J)},u9=async(Z)=>{let Q=Z.resolveMathSpeech??s3,J=Y7(Z.mathSpeech),{visibleText:Y}=Z,X=[],G=0,j=(V)=>{let K=y(V),U=Y.indexOf(K,G),$=U>=0?U:G,z=$+K.length;return G=z,{start:$,end:z}},B=[];for(let V=0;V<Z.chunks.length;V++){let K=Z.chunks[V];if(K.type==="text"){let M=o3(K)?[{text:K.text,offset:0}]:v0(K.text,{locale:Z.language});for(let P of M){let H=y(P.text);if(!H)continue;let N=j(H);X.push({sourceChunkIndex:V,segment:{kind:"prose",spokenText:H,visibleText:H,visibleSpan:N}}),B.push(H)}continue}let U=j(K.fallbackText),$=await Q(K,{language:Z.language,produceSsml:Z.produceSsml,mathSpeech:Z.mathSpeech,loadSre:J}),z=!$.speechText,D=$.speechText||K.fallbackText;X.push({sourceChunkIndex:V,segment:{kind:"math",spokenText:D,mathml:K.mathml,fallbackText:K.fallbackText,visibleSpan:U,usedFallback:z,ssml:$.ssml}}),B.push(D)}return{segments:X,locale:n3(Z.language),visibleText:Y,plainSpeechText:y(B.join(" "))}};var t3=(Z,Q,J)=>{let Y=new Map;for(let X=Q;X<J;X++){let G=Z.get(X);if(G)Y.set(X-Q,G)}return Y},U7=async(Z)=>{let Q=F0(Z.contentRoot,Z.textProcessingOptions,Z.range),J=await u9({chunks:Q.chunks,visibleText:Q.visibleText,language:Z.language,mathSpeech:Z.mathSpeech,produceSsml:Z.produceSsml,resolveMathSpeech:Z.resolveMathSpeech});return{plan:{items:J.segments.map(({segment:X,sourceChunkIndex:G})=>{let j=Q.chunks[G];if(X.kind==="prose"){let V=j?.type==="text"?j.sourceElement??Z.contentRoot:Z.contentRoot;return{segment:X,anchor:{sourceElement:V,regionElement:lZ(V,Z.contentRoot),visibleMap:t3(Q.map,X.visibleSpan.start,X.visibleSpan.end)}}}let B=j?.type==="math"?j.sourceElement??null:null;return{segment:X,anchor:{sourceElement:B,regionElement:B}}}),locale:J.locale,visibleText:J.visibleText,plainSpeechText:J.plainSpeechText},containsMathMarkup:Q.containsMathMarkup,visibleText:Q.visibleText}};var e3=(Z,Q)=>{let J=cZ({speechText:Z.spokenText,visibleText:Z.spokenText});return{speechText:Z.spokenText,visibleText:Z.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:V7(Q.visibleMap,0,Z.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Q.visibleMap}},p9=(Z,Q)=>{let J=Q.sourceElement;return{speechText:Z.spokenText,visibleText:Z.fallbackText,sourceElement:J,regionElement:Q.regionElement,speechMatchesVisibleText:Z.spokenText===Z.fallbackText,mathAlignment:J?o0({mathElement:J,speechText:Z.spokenText}):void 0}},Z2=(Z,Q,J)=>{let Y=Q.sourceElement;return{speechText:J,visibleText:Z.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:Y?o0({mathElement:Y,speechText:J}):void 0,plainFallback:p9(Z,Q)}},$7=(Z,Q={})=>Z.items.map(({segment:J,anchor:Y})=>{if(J.kind==="prose")return e3(J,Y);if(Q.format==="ssml"&&J.ssml)return Z2(J,Y,J.ssml);return p9(J,Y)});function sZ(Z){let Q=Z instanceof Error?Z:Error(String(Z));return Q.code="tts-start-failed",Q}var o=Y2("tts-service",n9),R;(function(Z){Z.IDLE="idle",Z.LOADING="loading",Z.PLAYING="playing",Z.PAUSED="paused",Z.ERROR="error"})(R||(R={}));var X2={baseMs:280,units:{minor:0.65,section:1,major:1.35},minMs:120,maxMs:900},g9=0.25,c9=4,h0=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,d9=(Z,Q={})=>{if(!Z)return Q;return{locale:"locale"in Z?h0(Z.locale):Q.locale,textNormalization:Z.textNormalization&&"locale"in Z.textNormalization?h0(Z.textNormalization.locale):Q.textNormalization,segmenter:Z.segmenter&&"locale"in Z.segmenter?h0(Z.segmenter.locale):Q.segmenter}},i9=(Z)=>("commonAncestorContainer"in Z),r9=(Z,Q)=>Z===Q||Z.startContainer===Q.startContainer&&Z.startOffset===Q.startOffset&&Z.endContainer===Q.endContainer&&Z.endOffset===Q.endOffset,G2=(Z,Q)=>{if(Z===Q)return!0;if(!Z||!Q||Z.type!==Q.type||Z.quality!==Q.quality)return!1;if(Z.type==="range"&&Q.type==="range")return r9(Z.range,Q.range);if(Z.type==="element"&&Q.type==="element")return Z.element===Q.element;if(Z.type==="text-range"&&Q.type==="text-range")return Z.node===Q.node&&Z.startOffset===Q.startOffset&&Z.endOffset===Q.endOffset;return!1},j2=(Z,Q)=>{for(let J=0;J<Math.min(Z.length,Q.length);J++)if(Z[J]!==Q[J])return{index:J,spokenChar:Z[J],normalizedChar:Q[J],spokenContext:Z.substring(Math.max(0,J-20),J+20),normalizedContext:Q.substring(Math.max(0,J-20),J+20)};return null},l9=(Z)=>{let Q=Number(Z.getAttribute("data-tts-break-ms"));return Number.isFinite(Q)&&Q>0?Q:null},B2=(Z)=>{if(typeof window>"u")return!1;let Q=window.getComputedStyle(Z).display;return Q==="block"||Q==="list-item"||Q.startsWith("table")||Q==="flex"||Q==="grid"},s9=(Z,Q,J)=>{let Y=Z.substring(Q,J);return{start:Q+(Y.match(/^\s*/)?.[0].length||0),end:J-(Y.match(/\s*$/)?.[0].length||0)}};class F7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.IDLE;resumeState=R.PLAYING;ttsConfig={};hostLocales={};readLocale=vZ;disposed=!1;readinessGate=null;mathSpeechSource=null;currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Set;lastError=null;speakRunId=0;restartRunId=null;runOwner=null;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;pauseHold=null;structuralPause=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";wordlessPartHighlight=null;lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=G7();clearPlaybackStartBarrier(Z=this.playbackStartBarrierCleanup){if(Z?.(),this.playbackStartBarrierCleanup===Z)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Z,Q){if(this.playbackStartDeferredRunId!==Z||Z!==this.speakRunId)return;if(this.state===R.PAUSED)this.activeRecordedAudio?.element.pause(),this.provider?.pause();this.markPlaying();let J=this.pendingPlaybackStartHighlights.splice(0);for(let Y of J)Y();if(Q?.wordBoundaries===!1)this.highlightWordlessPlayback()}highlightWordlessPlayback(){let Z=this.wordlessPartHighlight;if(!Z||this.activeHighlightMode!=="word")return;this.highlightCoordinator?.clearTTSWord(),Z()}installPlaybackStartBarrier(Z,Q=!1){this.clearPlaybackStartBarrier();let J=this.provider,Y=J&&"onPlaybackStart"in J?J:null;if(!Y&&!Q)return null;let X=Y?.onPlaybackStart,G=(B)=>{try{this.notifyPlaybackStarted(Z,B)}finally{X?.(B)}};if(Y)Y.onPlaybackStart=G;this.playbackStartDeferredRunId=Z;let j=()=>{if(Y?.onPlaybackStart===G)Y.onPlaybackStart=X;if(this.playbackStartDeferredRunId===Z)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=j,j}runWhenPlaybackStarts(Z,Q){if(this.playbackStartDeferredRunId===Z){this.pendingPlaybackStartHighlights.push(Q);return}Q()}async waitWhilePaused(Z){while(this.state===R.PAUSED&&Z===this.speakRunId){if(!this.pauseHold){let Q=()=>{},J=new Promise((Y)=>{Q=Y});this.pauseHold={promise:J,release:Q}}await this.pauseHold.promise}}releasePauseHold(){let Z=this.pauseHold;this.pauseHold=null,Z?.release()}waitStructuralPause(Z){return this.cancelStructuralPause(),new Promise((Q)=>{let J=()=>{if(this.structuralPause?.finish===J)clearTimeout(this.structuralPause.timer),this.structuralPause=null;Q()};this.structuralPause={timer:setTimeout(J,Z),finish:J}})}cancelStructuralPause(){this.structuralPause?.finish()}abandonRun(){this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.cancelStructuralPause(),this.releasePauseHold()}beginRun(Z){let Q=this.state===R.LOADING||this.state===R.PLAYING||this.state===R.PAUSED,J=++this.speakRunId;if(this.runOwner=Z,this.abandonRun(),Q)this.provider?.stop();return this.setState(R.LOADING,!0),J}markPlaying(){if(this.state===R.PAUSED){this.resumeState=R.PLAYING;return}this.setState(R.PLAYING)}assertNotDisposed(){if(this.disposed)throw sZ(Error("TTS service disposed"))}async emitTelemetry(Z,Q){try{await this.telemetryReporter?.(Z,Q)}catch(J){console.warn("[TTSService] telemetry callback failed:",J)}}async initialize(Z,Q={}){if(this.disposed)throw Error("TTS service disposed");this.currentProvider=Z,this.ttsConfig={...Q},this.hostLocales=d9(Q.providerOptions);let J=this.providerOptions().__pieTelemetry;this.telemetryReporter=typeof J==="function"?J:null,this.provider=await Z.initialize(Q)}async updateSettings(Z){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q={...Z,...Z.providerOptions?{providerOptions:{...this.providerOptions(),...Z.providerOptions}}:{}};await this.provider.updateSettings(Q),this.ttsConfig={...this.ttsConfig,...Q},this.hostLocales=d9(Z.providerOptions,this.hostLocales)}setHighlightCoordinator(Z){this.highlightCoordinator=Z}setReadinessGate(Z){this.readinessGate=Z}setMathSpeechSource(Z){this.mathSpeechSource=Z}pendingReadiness(){if(this.provider||!this.readinessGate)return null;return this.readinessGate().catch((Z)=>{throw sZ(Z)})}setHighlightTargetResolverProvider(Z){return this.highlightTargetResolverProvider=Z,()=>{if(this.highlightTargetResolverProvider===Z)this.highlightTargetResolverProvider=null}}setCatalogResolver(Z){this.catalogResolver=Z}getHighlightResolverRuntime(){let Z=null;try{Z=this.highlightTargetResolverProvider?.()??null}catch{Z=null}let Q=Z?.context??{},J=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Q,scopeElement:Q.scopeElement??J},resolver:Z?.resolver??null}}getNodeElement(Z){if(!Z)return null;return Z.nodeType===Node.ELEMENT_NODE?Z:d(Z)}isElementWithinScope(Z,Q){if(!Q)return!0;return Q0(Q,Z)}isRangeWithinScope(Z,Q){let J=this.getNodeElement(Z.startContainer),Y=this.getNodeElement(Z.endContainer);if(!J||!Y)return!1;return this.isElementWithinScope(J,Q)&&this.isElementWithinScope(Y,Q)}resolveWordHighlightRange(Z){let{context:Q,resolver:J}=this.getHighlightResolverRuntime(),Y=Q.scopeElement??this.currentContentElement;try{let X=J?.resolveWordRange?.(Z,Q);if(X&&this.isRangeWithinScope(X,Y))return{range:X,remapped:!r9(Z,X)}}catch{}return{range:Z,remapped:!1}}resolveSentenceHighlightTargets(Z){let{context:Q,resolver:J}=this.getHighlightResolverRuntime(),Y=Q.scopeElement??this.currentContentElement;try{let X=J?.resolveSentenceRanges?.(Z,Q);if(!X)return{ranges:Z,elements:[]};let G=[],j=[];for(let B of X){if(typeof Range<"u"&&B instanceof Range){if(!this.isRangeWithinScope(B,Y))return{ranges:Z,elements:[]};G.push(B);continue}if(typeof Element<"u"&&B instanceof Element){if(!this.isElementWithinScope(B,Y))return{ranges:Z,elements:[]};j.push(B);continue}return{ranges:Z,elements:[]}}return{ranges:G,elements:j}}catch{return{ranges:Z,elements:[]}}}createTextRange(Z,Q,J){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let Y=document.createRange();if(Y.setStart(Z,Q),Y.setEnd(Z,J),Y.startContainer!==Z||Y.endContainer!==Z)return null;return Y}catch{return null}}paintTTSWord(Z){if(!this.highlightCoordinator||Z.length===0)return;this.highlightCoordinator.highlightTTSWord(Z.map((Q)=>this.resolveWordHighlightRange(Q).range))}paintTTSSentenceRanges(Z){if(!this.highlightCoordinator)return;let{ranges:Q,elements:J}=this.resolveSentenceHighlightTargets(Z);if(J.length>0&&Q.length===0){this.highlightCoordinator.highlightTTSSentenceElements(J);return}let Y=[...Q];for(let X of J){let G=document.createRange();G.selectNodeContents(X),Y.push(G)}this.highlightCoordinator.highlightTTSSentence(Y)}providerOptions(){let Z=this.ttsConfig.providerOptions;return Z&&typeof Z==="object"?Z:{}}maxTextLength(){let Z=this.currentProvider?.getCapabilities?.().maxTextLength;return typeof Z==="number"&&Z>0?Z:void 0}async speakWithinLimit(Z,Q){let J=this.provider;if(!J)return;let Y=this.maxTextLength();if(!Y||Z.length<=Y){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;await J.speak(Z);return}if(pZ(Z))throw Error(`[tts] SSML of ${Z.length} characters exceeds the provider's limit of ${Y}`);let X=J.onWordBoundary;try{for(let G of q7(Z,Y,{locale:this.readLocale})){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;J.onWordBoundary=X?(j,B,V)=>X(j,B+G.offset,V):void 0,await J.speak(G.text)}}finally{if(this.provider===J&&Q===this.speakRunId)J.onWordBoundary=X}}segmentsWithinLimit(Z){let Q=this.maxTextLength();if(!Q)return Z;return Z.flatMap((J)=>{if(J.text.length<=Q)return[J];let Y=q7(J.text,Q,{locale:this.readLocale});return Y.map((X,G)=>({text:X.text,startOffset:J.startOffset+X.offset,pauseMsAfter:G===Y.length-1?J.pauseMsAfter:void 0}))})}getTextProcessingOptions(Z){let Q=this.providerOptions().textNormalization?.boundarySpacingMode;return{locale:Z,boundarySpacingMode:Q==="none"||Q==="alnum"||Q==="segmenterPreferred"?Q:void 0}}resolveReadLanguage(Z,Q){let J=d5(Z)??(Z.nodeType===1?m8(Z):void 0)??(Q?.trim()||void 0)??h0(this.providerOptions().lang_id);return{contentLanguage:J,locale:J??this.hostLocales.locale??this.hostLocales.textNormalization??vZ}}getMathSpeechOptions(){if(this.mathSpeechSource)return W0(this.mathSpeechSource());return W0(this.providerOptions().mathSpeech)}buildPositionMap(Z,Q,J){this.normalizedToDOM.clear();let{text:Y,map:X}=S0(Z,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!n9())return;o.debug("Text comparison:",{spokenLength:Q.length,normalizedDomLength:Y.length,match:Q===Y,spokenPreview:Q.substring(0,150),normalizedPreview:Y.substring(0,150),differAtIndex:Q===Y?null:j2(Q,Y)}),o.debug("Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Q.length,normalizedDomLength:Y.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Q.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([G,{node:j,offset:B}])=>({pos:G,offset:B,char:j.textContent?.[B],expected:Q[G]}))})}getStructuralPauseProfile(){let Z=this.providerOptions().structuralPauses||{},Q=Z.units||{},J=(X,G)=>{if(typeof X==="number"&&Number.isFinite(X))return X;if(typeof X==="string"&&X.trim()){let j=Number(X);return Number.isFinite(j)?j:G}return G},Y=X2;return{baseMs:J(Z.baseMs,Y.baseMs),units:{minor:J(Q.minor,Y.units.minor),section:J(Q.section,Y.units.section),major:J(Q.major,Y.units.major)},minMs:J(Z.minMs,Y.minMs),maxMs:J(Z.maxMs,Y.maxMs)}}resolvePauseMsFromUnits(Z){let Q=this.getStructuralPauseProfile(),J=Math.max(g9,Math.min(c9,Number(this.ttsConfig.rate||1))),Y=Q.baseMs*Math.max(0,Z)/J;return Math.max(Q.minMs,Math.min(Q.maxMs,Math.round(Y)))}resolveHighlightMode(){let Z=this.providerOptions().highlightMode;if(Z==="word"||Z==="sentence")return Z;let Q=this.currentProvider?.getCapabilities();if(Q?.defaultHighlightMode)return Q.defaultHighlightMode;return Q?.supportsWordBoundary?"word":"sentence"}hasExplicitBreakSemantics(Z){if(!Z.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(Z)}getBoundaryStrength(Z){if(l9(Z)!==null)return"major";let Q=Z.tagName.toUpperCase();if(Q.match(/^H[1-6]$/))return"major";let J=(Z.getAttribute("role")||"").toLowerCase();if(J==="heading")return"major";if(J==="listitem"||J==="row"||J==="option"||J==="radio"||Q==="LI")return"section";return"minor"}getBoundaryAnchor(Z,Q){let J=g(Z),Y=null;while(J&&J!==Q){if(hZ(J))return null;let G=l9(J);if(G!==null)return{anchor:J,units:G/this.getStructuralPauseProfile().baseMs};let j=(J.getAttribute("role")||"").toLowerCase(),B=J.tagName.toUpperCase();if(B.match(/^H[1-6]$/)||j==="heading"||j==="listitem"||B==="LI"){Y=J;break}if(!Y&&B2(J))Y=J;J=g(J)}if(!Y)return null;let X=this.getBoundaryStrength(Y);return{anchor:Y,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Z,Q,J,Y){let X=this.collectSpeechPlanBoundaries(Z,Y);if(J===0)return this.createSpeechPlanSegments(Q,X);let G=new Map;for(let[j,B]of X)G.set(j-J,B);return this.createSpeechPlanSegments(Q,G)}collectSpeechPlanBoundaries(Z,Q){let J=new Map,{map:Y}=S0(Z,this.getTextProcessingOptions(Q)),X=this.createNodeStartOffsets(Y),G=null;for(let j of C0(Z)){let B=g(j);if(B&&!hZ(B)&&!mZ(j)){let V=this.getBoundaryAnchor(j,Z),K=X.get(j);if(V&&K!==void 0&&V.anchor!==G&&K>0)J.set(K,Math.max(J.get(K)||0,V.units)),G=V.anchor}}return J}createNodeStartOffsets(Z){let Q=new Map;for(let[J,Y]of Z.entries())if(!Q.has(Y.node))Q.set(Y.node,J);return Q}createSpeechPlanSegments(Z,Q){let J=Array.from(Q.keys()).filter((V)=>V>0&&V<Z.length).sort((V,K)=>V-K),Y=[],X=0;for(let V of J){let{start:K,end:U}=s9(Z,X,V);if(U>K){let $=Z.substring(K,U);Y.push({text:$,startOffset:K,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(V)||0)})}X=V}let j=Z.substring(X).match(/^\s*/)?.[0].length||0,B=X+j;if(B<Z.length)Y.push({text:Z.substring(B).trimEnd(),startOffset:B,pauseMsAfter:0});return Y.filter((V)=>V.text.trim().length>0)}segmentSentences(Z){return v0(Z,{locale:this.readLocale})}createSeekSegmentsFromText(Z){return this.segmentSentences(Z).map((Q)=>{let J=Q.text.match(/^\s*/)?.[0].length||0;return{text:Q.text.trim(),startOffset:Q.offset+J,pauseMsAfter:0}}).filter((Q)=>Q.text.length>0)}splitSegmentsAtBoundaries(Z,Q,J){if(Z.length===0||Q.length===0)return Z;let Y=Array.from(new Set(Q)).filter((G)=>Number.isFinite(G)&&G>0).sort((G,j)=>G-j);if(Y.length===0)return Z;let X=[];for(let G of Z){let j=G.startOffset,B=G.startOffset+G.text.length,V=Y.filter((U)=>U>j&&U<B);if(V.length===0){X.push(G);continue}let K=j;for(let U of[...V,B]){let{start:$,end:z}=s9(J,K,U);if(z>$)X.push({text:J.substring($,z),startOffset:$,pauseMsAfter:0});K=U}}return X}createSentenceHighlightSegments(Z){let Q=this.createSeekSegmentsFromText(Z.contentToSpeak);if(!Z.shouldUsePlan||Z.playbackSegments.length===0)return Q;let J=Z.playbackSegments.map((Y)=>Y.startOffset).filter((Y)=>Y>0);return this.splitSegmentsAtBoundaries(Q,J,Z.contentToSpeak)}createSeekSegmentsFromSpeechChunks(Z){let Q=0;return Z.map((J)=>{let Y=J.plainFallback?.speechText||(this.hasExplicitBreakSemantics(J.speechText)?J.visibleText:J.speechText)||J.visibleText,X=y(Y)||J.visibleText||"",G={text:X,startOffset:Q,pauseMsAfter:0};return Q+=X.length+1,G})}getCurrentSeekSegmentIndex(){return Math.max(0,this.getSegmentIndexForOffset(this.seekSegments,this.currentBoundaryOffset))}async speakWithPlan(Z,Q,J){if(!this.provider||Z.length===0)return;let Y=J?.highlightMode==="sentence",X=this.provider;if(!Y&&typeof X.speakSegments==="function"){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==X)return;this.currentBoundaryOffset=0;let G=this.provider.onWordBoundary;this.provider.onWordBoundary=(j,B,V)=>{if(G?.(j,B,V),Number.isFinite(B))this.currentBoundaryOffset=B};try{await X.speakSegments(this.segmentsWithinLimit(Z))}finally{if(Q===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=G}return}this.configureWordBoundaryHighlighting({highlightMode:J?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let G of Z){if(await this.waitWhilePaused(Q),Q!==this.speakRunId)return;this.currentBoundaryOffset=G.startOffset;let j=()=>{this.highlightSentenceSegment(G.startOffset,G.text)};if(Y)this.runWhenPlaybackStarts(Q,j);this.wordlessPartHighlight=j;try{await this.speakWithinLimit(G.text,Q)}finally{if(this.wordlessPartHighlight===j)this.wordlessPartHighlight=null}let B=G.pauseMsAfter??0;if(B>0&&Q===this.speakRunId)await this.waitStructuralPause(B)}}highlightSentenceSegment(Z,Q){if(!this.highlightCoordinator||typeof document>"u")return;let J=Q.trimEnd().length;if(J<=0)return;let Y=Z+this.activeWordBoundaryOffset,X=this.normalizedToDOM.get(Y),G=this.normalizedToDOM.get(Y+J-1);if(!X||!G)return;let j=D0(this.normalizedToDOM,Y,Y+J);if(j.length===0)return;this.paintTTSSentenceRanges(j),this.activeSentenceStartOffset=Z}getSegmentIndexForOffset(Z,Q){if(Z.length===0)return-1;let J=-1;for(let Y=0;Y<Z.length;Y++)if(Z[Y].startOffset<=Q)J=Y;else break;return J}highlightSentenceForOffset(Z){let Q=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Q.length===0)return;let J=this.getSegmentIndexForOffset(Q,Z);if(J<0)return;let Y=Q[J];if(!Y)return;if(this.activeSentenceStartOffset===Y.startOffset)return;this.highlightSentenceSegment(Y.startOffset,Y.text)}async speak(Z,Q={}){this.assertNotDisposed();let J=this.pendingReadiness(),Y=Q.ownerId??null,X=J?this.beginRun(Y):null;if(J){try{await J}catch(V){if(X===this.speakRunId)this.setState(R.IDLE);throw V}if(this.assertNotDisposed(),X!==this.speakRunId)return}if(!this.provider){if(X!==null)this.setState(R.IDLE);throw sZ(Error("TTS service not initialized"))}let G=this.resolveReadLanguage(i9(Z)?Z.startContainer:Z,Q.language),j=i9(Z)?this.resolveRangeTarget(Z,Q,G):this.resolveElementTarget(Z,Q,G);if(!j){if(X!==null)this.setState(R.IDLE);return}let B=X??this.beginRun(Y);if(Q.rate!==void 0||Q.pitch!==void 0||Q.volume!==void 0){if(await this.applyRunSettings(Q),B!==this.speakRunId)return}await this.speakContent(j.text,j.options,B)}async applyRunSettings(Z){await this.playbackRateWriteQueue;let Q={};if(Z.rate!==void 0){let J=this.normalizePlaybackRate(Z.rate),Y=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(J!==Y)Q.rate=J}if(Z.pitch!==void 0&&Z.pitch!==this.ttsConfig.pitch)Q.pitch=Z.pitch;if(Z.volume!==void 0&&Z.volume!==this.ttsConfig.volume)Q.volume=Z.volume;if(Object.keys(Q).length>0)await this.updateSettings(Q)}isSuppressedTarget(Z){if(!mZ(Z))return!1;return console.warn("[tts] the content to read lies inside content marked not-to-be-spoken; nothing was spoken."),!0}resolveElementTarget(Z,Q,J){if(this.isSuppressedTarget(Z))return null;let Y={catalogId:Q.catalogId,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:Z},X=F0(Z,this.getTextProcessingOptions(J.locale)).visibleText.trim();if(!X&&!this.holdsSpokenCard(Z,Y))return console.warn("[tts] the content to read holds no speakable text; nothing was spoken."),null;return{text:X,options:Y}}holdsSpokenCard(Z,Q){if(!this.catalogResolver)return!1;if(Q.catalogId){if(this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language,useFallback:!0,context:Q.catalogContext,form:"content"})?.content!==void 0)return!0}return this.collectCatalogSpeechChunks(Z,Q).some((J)=>J.sourceElement)}resolveRangeTarget(Z,Q,J){if(this.isSuppressedTarget(Z.commonAncestorContainer))return null;let Y=Z.commonAncestorContainer,X=Q.contentRoot||(Y.nodeType===Node.ELEMENT_NODE?Y:d(Y));if(!X)return null;let G=i5(Z,X),j=G.text.trim();if(!j){if(G.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return null}let B=this.selectMappedRangeText(Z,X,J.locale),V=j,K=B?.offset??0;if(B)V=B.text;else{let U=document.createRange();U.selectNodeContents(X),U.setEnd(Z.startContainer,Z.startOffset);let $=i5(U,X).text,z=y($);K=z.length+(/\s$/.test($)&&z?1:0)}return o.debug("selection offset calculation:",{selectedText:V,mapped:!!B,offset:K,rootTag:X.tagName}),{text:V,options:{catalogId:Q.catalogId&&HZ(Z,X,X)?Q.catalogId:void 0,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:X,contentRange:Z,wordBoundaryOffset:K}}}async speakContent(Z,Q,J){let Y=null;try{if(await this.applyLanguageSettings(Q),J!==this.speakRunId)return;let X=await this.resolveSpeechContent(Z,Q);if(J!==this.speakRunId)return;let{contentToSpeak:G,speechText:j,highlightText:B,normalizedText:V,usedCatalogSpoken:K,speechSource:U,speechMatchesVisibleText:$,speechChunks:z}=X;this.logResolvedSpeechContent({contentToSpeak:G,speechSource:U,catalogId:Q.catalogId}),this.initializeSpeakTracking(B,Q);let D=$?this.resolveHighlightMode():"sentence";this.activeHighlightMode=D;let M=Q.wordBoundaryOffset||0;this.activeWordBoundaryOffset=M;let P=this.hasExplicitBreakSemantics(G),H=!!this.currentContentElement&&!K&&!P&&$;if(this.playbackChunks=z?.length?z:[],this.playbackChunks.length)this.seekSegments=this.createSeekSegmentsFromSpeechChunks(this.playbackChunks);else if(P||!$)this.seekSegments=[];else if(H&&this.currentContentElement)this.seekSegments=this.createSpeechPlan(this.currentContentElement,V,M,Q.language);else this.seekSegments=this.createSeekSegmentsFromText(B);if(this.sentenceHighlightSegments=P?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:H,playbackSegments:this.seekSegments}),Y=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Q,highlightMode:D,shouldUsePlan:H,runId:J}),$)this.configureWordBoundaryHighlighting({highlightMode:D,wordBoundaryOffset:M});else this.clearWordBoundaryHighlighting();if(!Y)this.markPlaying();if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:H,runId:J,highlightMode:D,contentToSpeak:j,speechChunks:z}),J!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(X){if(J!==this.speakRunId)return;throw console.error("TTS error:",X),this.lastError=X instanceof Error?X.message:String(X),this.setState(R.ERROR),this.clearHighlightsAndTracking(),X}finally{this.clearPlaybackStartBarrier(Y)}}async applyLanguageSettings(Z){if(!this.provider)return;this.readLocale=Z.language;let Q=Z.contentLanguage,J=this.providerOptions(),Y={locale:Q??this.hostLocales.locale,textNormalization:Q??this.hostLocales.textNormalization,segmenter:Q??this.hostLocales.segmenter};if(J.contentLanguage===Q&&h0(J.locale)===Y.locale&&h0(J.textNormalization?.locale)===Y.textNormalization&&h0(J.segmenter?.locale)===Y.segmenter)return;let X={...J,locale:Y.locale,textNormalization:{...J.textNormalization,locale:Y.textNormalization},segmenter:{...J.segmenter,locale:Y.segmenter},contentLanguage:Q};this.ttsConfig={...this.ttsConfig,providerOptions:X},await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(Z,Q){let J=y(Z);if(Q.catalogId&&this.catalogResolver){let G=this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language,useFallback:!0,context:Q.catalogContext,form:"content"}),j=G?.content;if(G&&j!==void 0){let B=F0(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||J,V=y(j);return o.debug(`Using catalog content for "${Q.catalogId}" (${G.language})`),{contentToSpeak:j,speechText:j,visibleText:B,highlightText:B,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:V===B}}o.debug(`No catalog found for "${Q.catalogId}", falling back to generated TTS`)}let Y=this.resolveCatalogComposedSpeechContent(Q.contentElement,J,Q);if(Y)return Y;return{...await this.resolveGeneratedSpeechContent(Q.contentElement,J,Q.language,Q.contentRange),usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(Z,Q,J){if(!this.catalogResolver)return null;let Y=this.collectCatalogSpeechChunks(Z,J);if(!Y.some((j)=>j.sourceElement))return null;let X=y(Y.map((j)=>j.speechText).join(" ")),G=J.contentRange?Q:F0(Z,this.getTextProcessingOptions(J.language)).visibleText||Q;return{contentToSpeak:X,speechText:X,visibleText:G,highlightText:G,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:G,containsMathMarkup:!1,speechMatchesVisibleText:Y.every((j)=>j.speechMatchesVisibleText),speechChunks:Y}}collectCatalogSpeechChunks(Z,Q){let J=this.catalogResolver;if(!J)return[];let Y=[],X="",G=()=>{let $=y(X);if(X="",!$)return;Y.push({speechText:$,visibleText:$,sourceElement:null,speechMatchesVisibleText:!0})},j=Q.contentRange,B=($)=>{let z=$.getAttribute("data-catalog-idref");if(!z)return null;if(j&&!HZ(j,$,Z))return null;let D={type:"spoken",language:c5($,Z)||Q.language,useFallback:!0,context:Q.catalogContext},M=J.getAlternative(z,{...D,form:"payload"}),P=M?.payload?v8({payload:M.payload})??void 0:void 0,N=J.getAlternative(z,{...D,form:"content"})?.content;if(P===void 0&&N===void 0)return null;return{script:N,audio:P}},V=($,z)=>{let D=K($);if(D.length!==1)return null;let M=D[0],P=F0(M,this.getTextProcessingOptions(Q.language)).visibleText||y(M.textContent||""),H=(N)=>y(N).replace(/\s+/g,"");return H(P)===H(z)?M:null},K=($)=>{let z=E8($,"math");if($.localName?.toLowerCase()==="math")return[$,...z];return z},U=($)=>{if($0($,Z))return;if($.nodeType===Node.TEXT_NODE){if(!j)X+=` ${$.textContent||""}`;else if(X0(j,$))X+=` ${l5($,j)}`;return}if($.nodeType!==Node.ELEMENT_NODE)return;let z=$,D=B(z);if(D){G();let M=F0(z,this.getTextProcessingOptions(Q.language)),P=M.visibleText||y(b8(z)),H=lZ(z,Z),N=null;if(D.script!==void 0){let O=D.script,C=cZ({speechText:O,visibleText:P}),E=V(z,P),v=E?o0({mathElement:E,speechText:O}):void 0,S=v?void 0:K(z).map((u)=>({element:u,alignment:o0({mathElement:u,speechText:O})}));N={speechText:O,visibleText:P,sourceElement:z,regionElement:H,speechMatchesVisibleText:y(O)===P,playbackMode:C.playbackMode,alignment:C,mathAlignment:v,mathAlignments:S,visibleMap:M.map}}if(D.audio){Y.push(N?{...N,audio:D.audio,plainFallback:N}:{speechText:P,visibleText:P,sourceElement:z,regionElement:H,speechMatchesVisibleText:!1,visibleMap:M.map,audio:D.audio});return}if(N)Y.push(N);return}for(let M of U0(z))U(M)};return U(Z),G(),Y}resolveGeneratedPlaybackFormat(){let Z=this.currentProvider;if(!Z)return"plain";return Z.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(Z,Q,J,Y){let X=this.resolveGeneratedPlaybackFormat(),{plan:G,containsMathMarkup:j,visibleText:B}=await U7({contentRoot:Z,range:Y,language:J,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(J),produceSsml:X==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver});if(!j){let $=Y?Q:B||Q;return{contentToSpeak:$,speechText:$,visibleText:$,highlightText:$,normalizedText:$,containsMathMarkup:!1,speechMatchesVisibleText:!0}}let V=B||Q,K=$7(G,{format:X}),U=G.plainSpeechText;return{contentToSpeak:U,speechText:U,visibleText:V,highlightText:V,normalizedText:V,containsMathMarkup:!0,speechMatchesVisibleText:U===V,speechChunks:K}}logResolvedSpeechContent(Z){let Q=Z.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);o.debug("Speak resolved content",{source:Z.speechSource,catalogId:Z.catalogId||null,length:Z.contentToSpeak.length,preview:Q})}initializeSpeakTracking(Z,Q){this.currentText=Z,this.currentContentElement=Q.contentElement,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(Z){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,Z.contentToSpeak,Z.options.language),Z.highlightMode==="sentence"&&Z.shouldUsePlan)return;let Q=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(Z.runId,()=>{if(Q)this.highlightSentenceSegment(Q.startOffset,Q.text),o.debug("Applied initial sentence highlighting");else try{let J=document.createRange();J.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([J])}catch{}})}configureWordBoundaryHighlighting(Z){if(!this.provider)return;if(Z.highlightMode==="sentence"){this.provider.onWordBoundary=void 0;return}if(!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Q,J,Y)=>{let X=Y||Q.length,G=J+this.currentBoundaryOffset,j=G+Z.wordBoundaryOffset;this.highlightSentenceForOffset(G);let B=D0(this.normalizedToDOM,j,j+X);if(B.length===0){o.debug(`no text at position ${j}, length ${X}, to highlight`);return}o.debug(`Highlighting "${B.join("")}" (word: "${Q}") at position ${j}`),this.paintTTSWord(B)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(Z){let Q=Z.regionElement||Z.sourceElement;if(!Q&&!Z.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,Z.regionRange){let Y=D0(Z.visibleMap,0,Z.visibleText.length);this.highlightCoordinator.clearTTSWord(),this.paintTTSSentenceRanges(Y.length>1?Y:[Z.regionRange]);return}if(!Q)return;let J=document.createRange();J.selectNodeContents(Q),this.highlightCoordinator.clearTTSWord(),this.paintTTSSentenceRanges([J])}catch{}}highlightRenderableRegionTarget(Z){if(!this.highlightCoordinator||!Z||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&G2(this.lastRenderedRegionTarget,Z))return;try{let Q=document.createRange();if(Z.type==="element")Q.selectNodeContents(Z.element);else if(Z.type==="range"){this.paintTTSSentenceRanges(Z.ranges??[Z.range]),this.lastRenderedRegionTarget=Z;return}else Q.setStart(Z.node,Z.startOffset),Q.setEnd(Z.node,Z.endOffset);this.paintTTSSentenceRanges([Q]),this.lastRenderedRegionTarget=Z}catch{}}highlightRenderableActiveTarget(Z){if(!this.highlightCoordinator||typeof document>"u")return;if(!Z){this.highlightCoordinator.clearTTSWord();return}if(Z.type==="text-range"){let X=this.createTextRange(Z.node,Z.startOffset,Z.endOffset);if(X)this.paintTTSWord([X]);return}if(Z.type==="range"){this.paintTTSWord(Z.ranges??[Z.range]);return}let Q=document.createRange();Q.selectNodeContents(Z.element);let J=this.resolveWordHighlightRange(Q);if(J.remapped){this.highlightCoordinator.highlightTTSWord([J.range]);return}let Y=Z.element.childNodes.length===1?Z.element.firstChild:null;if(Z.quality==="semantic-token"&&Y?.nodeType===Node.TEXT_NODE){let X=document.createRange();X.selectNodeContents(Y),this.highlightCoordinator.highlightTTSWord([X]);return}this.highlightCoordinator.highlightTTSWordElement(Z.element)}renderHighlightDecision(Z){this.highlightRenderableRegionTarget(Z.regionTarget),this.highlightRenderableActiveTarget(Z.activeTarget)}async speakCatalogChunk(Z,Q){try{await this.speakCatalogChunkOnce(Z,Q)}catch(J){if(Z.plainFallback&&Q===this.speakRunId){if(o.debug("SSML chunk speak failed; retrying plain text",{message:J instanceof Error?J.message:String(J)}),this.playbackStartDeferredRunId===Q&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.markPlaying();await this.speakCatalogChunkOnce(Z.plainFallback,Q);return}throw J}}async playRecordedAudio(Z,Q){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let J=Z.sources[0],Y=document.createElement("audio");Y.preload="auto",Y.src=Q2(J.src,Z.fragment),Y.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,G)=>{let j,B=!1,V=!1,K=()=>{if(V||B)return;B=!0,Q?.()},U=()=>{if(Y.removeEventListener("ended",$),Y.removeEventListener("error",z),Y.removeEventListener("playing",K),j?.(),this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null},$=()=>{if(V)return;V=!0,U(),X()},z=()=>{if(V)return;V=!0,U(),G(Error(`[tts] recorded audio failed to play: ${J.src}`))},D=()=>{Promise.resolve(Y.play()).then(K).catch((M)=>{if(M?.name==="AbortError"&&this.state===R.PAUSED)return;z()})};this.activeRecordedAudio={element:Y,cancel:()=>{if(V)return;V=!0,U(),Y.pause(),X()},play:D},Y.addEventListener("ended",$),Y.addEventListener("error",z),Y.addEventListener("playing",K),j=J2(Y,Z.fragment,$),D()}).finally(()=>{if(this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null;Y.pause(),Y.removeAttribute("src")})}cancelRecordedAudio(){let Z=this.activeRecordedAudio;if(!Z)return;this.activeRecordedAudio=null,Z.cancel()}async speakCatalogChunkOnce(Z,Q){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,Z.audio){this.runWhenPlaybackStarts(Q,()=>{this.highlightCatalogRegion(Z)}),await this.playRecordedAudio(Z.audio,()=>{this.notifyPlaybackStarted(Q)});return}let J=Z.regionElement||Z.sourceElement||this.currentContentElement,Y=J?m9({contentRoot:J,chunks:[Z]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,G=Y?h9({chunks:[Y],mathTokenHighlighting:X}):null,j=!Y||Y.offsetSpace==="unsupported"?"unknown":Y.offsetSpace;if(this.runWhenPlaybackStarts(Q,()=>{if(G&&Y&&Z.mathAlignment)this.renderHighlightDecision(G.resolveInitial(Y.id));else this.highlightCatalogRegion(Z)}),!(this.resolveHighlightMode()==="word"&&Z.sourceElement&&(Z.mathAlignment&&Z.mathAlignment.speech.tokens.length>0||Z.mathAlignments&&Z.mathAlignments.length>0||Z.alignment&&Z.visibleMap&&(Z.playbackMode==="exact-word"||Z.playbackMode==="anchor-span")))){let $=this.provider,z=$.onWordBoundary;$.onWordBoundary=void 0;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===$&&Q===this.speakRunId&&$.onWordBoundary===void 0)$.onWordBoundary=z}return}let V=this.provider,K=V.onWordBoundary,U=($,z,D)=>{if(Q!==this.speakRunId||!G||!Y)return;this.renderHighlightDecision(G.resolveBoundary({chunkId:Y.id,word:$,position:z,length:D,providerOffsetSpace:j}))};V.onWordBoundary=U;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===V&&Q===this.speakRunId&&V.onWordBoundary===U)V.onWordBoundary=K}}async executeSpeakPlayback(Z){if(Z.speechChunks?.length&&this.provider){for(let Q=0;Q<Z.speechChunks.length;Q++){if(await this.waitWhilePaused(Z.runId),Z.runId!==this.speakRunId)return;let J=this.seekSegments[Q];if(J)this.currentBoundaryOffset=J.startOffset;let Y=Z.speechChunks[Q];await this.speakCatalogChunk(Y,Z.runId)}return}if(Z.shouldUsePlan&&this.currentContentElement&&this.seekSegments.length>0){await this.speakWithPlan(this.seekSegments,Z.runId,{highlightMode:Z.highlightMode});return}await this.speakWithinLimit(Z.contentToSpeak,Z.runId)}clearHighlightsAndTracking(){if(this.clearWordBoundaryHighlighting(),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,this.wordlessPartHighlight=null}selectMappedRangeText(Z,Q,J){if(typeof Z.comparePoint!=="function")return null;let{text:Y,map:X}=S0(Q,this.getTextProcessingOptions(J)),G=-1,j=-1;for(let[U,{node:$,offset:z}]of X){if(U>=Y.length)continue;if(!$Z(Z,$,z))continue;if(G===-1||U<G)G=U;if(U>j)j=U}if(G===-1)return null;let B=Y.slice(G,j+1),V=B.length-B.trimStart().length,K=B.trim();return K?{text:K,offset:G+V}:null}pause(){if(this.state!==R.PLAYING&&this.state!==R.LOADING)return;this.resumeState=this.state,this.activeRecordedAudio?.element.pause(),this.provider?.pause(),this.setState(R.PAUSED)}resume(){if(this.state!==R.PAUSED)return;this.setState(this.resumeState),this.activeRecordedAudio?.play(),this.provider?.resume(),this.releasePauseHold()}normalizePlaybackRate(Z){if(!Number.isFinite(Z))return 1;return Math.max(g9,Math.min(c9,Z))}async restartFromSeekIndex(Z){if(!this.provider||this.seekSegments.length===0)return;let Q=Math.max(0,Math.min(this.seekSegments.length-1,Z)),J=this.playbackChunks.length?this.playbackChunks.slice(Q):null,Y=this.state===R.PAUSED;this.speakRunId+=1,this.abandonRun(),this.provider.onWordBoundary=void 0,this.provider.stop();let X=++this.speakRunId;this.restartRunId=X;let G=this.seekSegments.slice(Q);if(this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.currentBoundaryOffset=this.seekSegments[Q].startOffset,!Y)this.setState(R.LOADING);let j=this.installPlaybackStartBarrier(X,!!J?.[0]?.audio);if(Y)this.resumeState=j?R.LOADING:R.PLAYING;else 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}),J)for(let B=0;B<J.length;B++){if(await this.waitWhilePaused(X),X!==this.speakRunId)return;let V=Q+B,K=this.seekSegments[V];if(K)this.currentBoundaryOffset=K.startOffset;await this.speakCatalogChunk(J[B],X)}else await this.speakWithPlan(G,X,{highlightMode:this.activeHighlightMode});if(X!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(B){if(X!==this.speakRunId){o.debug("Superseded seek restart failed:",B);return}throw this.lastError=B instanceof Error?B.message:String(B),this.setState(R.ERROR),this.clearHighlightsAndTracking(),B}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(Z){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.normalizePlaybackRate(Z),J=this.pendingPlaybackRateRequest;if(J?.rate===Q){await J.promise;return}let Y=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let B=this.speakRunId;if(Y!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:B};let V=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===V)return{didUpdate:!1,playbackRunId:B};return await this.updateSettings({rate:Q}),{didUpdate:!0,playbackRunId:B}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let G=X.then(async(B)=>{if(Y!==this.playbackRateRequestId||B.playbackRunId!==this.speakRunId)return;let V=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!B.didUpdate&&!V)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())}),j;j=G.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===j)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Q,promise:j},await j}async seekBy(Z){if(!this.provider||!this.currentText)return;let Q=this.state===R.LOADING&&this.restartRunId===this.speakRunId;if(this.state!==R.PLAYING&&this.state!==R.PAUSED&&!Q)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let J=Number.isFinite(Z)?Math.trunc(Z):0;if(J===0)return;let Y=this.getCurrentSeekSegmentIndex(),X=Math.max(0,Math.min(this.seekSegments.length-1,Y+J));if(X===Y)return;await this.restartFromSeekIndex(X)}async seekForward(Z=1){let Q=Number.isFinite(Z)?Math.max(1,Math.trunc(Z)):1;await this.seekBy(Q)}async seekBackward(Z=1){let Q=Number.isFinite(Z)?Math.max(1,Math.trunc(Z)):1;await this.seekBy(-Q)}stop(){this.speakRunId+=1,this.abandonRun(),this.provider?.stop(),this.clearHighlightsAndTracking(),this.currentText=null;let Z=this.runOwner!==null;this.runOwner=null,this.setState(R.IDLE,Z)}releaseProvider(){this.stop(),this.provider=null,this.currentProvider=null}dispose(){if(this.disposed)return;this.releaseProvider(),this.disposed=!0,this.speakRunId+=1,this.abandonRun(),this.playbackRateRequestId+=1,this.pendingPlaybackRateRequest=null,this.listeners.clear(),this.readinessGate=null,this.mathSpeechSource=null,this.highlightTargetResolverProvider=null,this.highlightCoordinator=null,this.catalogResolver=null,this.telemetryReporter=null}getState(){return this.state}getRunOwner(){return this.runOwner}onStateChange(Z){let Q=(J)=>Z(J);return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}setState(Z,Q=!1){let J=this.state;if(J===Z&&!Q)return;this.state=Z;for(let Y of[...this.listeners])Y(Z);if(J===Z)return;if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",previousState:J,state:Z}),Z===R.PLAYING){let Y=J===R.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(Y,{toolId:"textToSpeech",previousState:J,state:Z});return}if(Z===R.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",previousState:J,state:Z});return}if(Z===R.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",previousState:J,state:Z,message:this.lastError||void 0});return}if(Z===R.IDLE&&(J===R.PLAYING||J===R.PAUSED||J===R.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",previousState:J,state:Z})}}import{createPieLogger as W2,isTtsDebugEnabled as V2}from"@pie-players/pie-players-shared/pie";var a9=W2("browser-tts-provider",V2),o9=5000,Z1=2000,t9=260,K2=80,q2=["__pieTelemetry","contentLanguage","highlightMode","locale","mathSpeech","segmenter","structuralPauses","textNormalization"],Q1=(Z)=>{let Q={};if(Z.rate!==void 0)Q.rate=Z.rate;if(Z.pitch!==void 0)Q.pitch=Z.pitch;if(Z.volume!==void 0)Q.volume=Z.volume;if(Z.mathTokenHighlighting!==void 0)Q.mathTokenHighlighting=Z.mathTokenHighlighting;let J=Z.providerOptions;if(J&&typeof J==="object"){let Y={};for(let X of q2)if(J[X]!==void 0)Y[X]=J[X];if(Object.keys(Y).length>0)Q.providerOptions=Y}return Q},e9=(Z)=>{if(!pZ(Z))return{text:Z,sourceOffset:(X)=>X};let{spokenText:Q,rawToSpokenOffsetMap:J}=gZ(Z),Y=[];for(let[X,G]of J){let j=Y[G];if(j===void 0||X<j)Y[G]=X}return{text:Q,sourceOffset:(X)=>{for(let G=X;G>=0;G--){let j=Y[G];if(j!==void 0)return j}return 0}}},z7=(Z)=>String(Z||"").trim().toLowerCase(),U2=()=>{let Z=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return z7(Z||"en-US")},$2=(Z,Q)=>{let J=z7(Q)||U2(),Y=J.split("-")[0]||"en",X=z7(Z.lang);return X===J||X.startsWith(`${Y}-`)},F2=(Z,Q,J)=>{if(Q)return Z.find((G)=>G.voiceURI===Q)||Z.find((G)=>G.name===Q)||null;let Y=(G)=>$2(G,J),X=[(G)=>G.localService&&Y(G),(G)=>G.default&&Y(G),(G)=>Y(G),(G)=>G.localService,(G)=>G.default];for(let G of X){let j=Z.find(G);if(j)return j}return Z[0]||null},z2=(Z,Q,J=()=>!0)=>{if(Z.getVoices().length>0)return Promise.resolve(!0);let Y=typeof Z.addEventListener==="function"&&typeof Z.removeEventListener==="function";if(!Y&&!("onvoiceschanged"in Z))return Promise.resolve(!1);return new Promise((X)=>{let G=Y?null:Z.onvoiceschanged,j=!1,B=(z)=>{if(j)return;if(j=!0,clearTimeout($),Y)Z.removeEventListener("voiceschanged",K);else if(Z.onvoiceschanged===U)Z.onvoiceschanged=G;X(z)},V=()=>{if(!J())B(!1);else if(Z.getVoices().length>0)B(!0)},K=()=>V(),U=(z)=>{try{G?.call(Z,z)}finally{V()}},$=setTimeout(()=>B(!1),Q);if(Y)Z.addEventListener("voiceschanged",K);else Z.onvoiceschanged=U;V()})},D2=(Z)=>!Z.default;class D7{providerId="browser";async initialize(Z){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");if(typeof Z.voice==="string"&&Z.voice.trim())await z2(window.speechSynthesis,Z1);return new J1(Z)}getCapabilities(){return{supportsWordBoundary:!0,defaultHighlightMode:"sentence",supportsSSML:!1}}destroy(){}}class J1{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;activeRunId=null;releasePauseHold=null;settlePendingChunk=null;settlePendingGap=null;onPlaybackStart=void 0;constructor(Z){this.config=Z}async waitWhilePaused(Z){while(this._isPaused&&Z===this.speakRunId)await new Promise((Q)=>{this.releasePauseHold=Q});return Z===this.speakRunId}releaseHold(){let Z=this.releasePauseHold;this.releasePauseHold=null,Z?.()}resolveBrowserVoice(){let Z=typeof this.config?.voice==="string"?this.config.voice.trim():"",Q=speechSynthesis.getVoices();if(Z&&Q.length===0)throw Error(`Configured browser voice "${Z}" could not be resolved because the browser did not publish its voice inventory within ${Z1/1000} seconds.`);let J=F2(Q,Z||void 0,this.getContentLocale());if(Z&&!J)throw Error(`Configured browser voice "${Z}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return J}async speak(Z){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId;this.activeRunId=Q;try{let J=this.resolveBrowserVoice(),Y=e9(Z),X=this.splitIntoChunks(Y.text);for(let G of X){if(this._isPaused&&!await this.waitWhilePaused(Q))break;if(!await this.speakChunk(G.text,G.offset,Q,J,Y.sourceOffset))break}}finally{if(this.activeRunId===Q)this.activeRunId=null}}async speakSegments(Z){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId;this.activeRunId=Q;try{let J=this.resolveBrowserVoice();for(let Y of Z){if(Q!==this.speakRunId)break;let X=e9(Y.text),G=this.splitIntoChunks(X.text);for(let B of G){if(this._isPaused&&!await this.waitWhilePaused(Q))break;if(!await this.speakChunk(B.text,B.offset,Q,J,(K)=>Y.startOffset+X.sourceOffset(K)))break}let j=Math.max(0,Number(Y.pauseMsAfter||0));if(j>0&&Q===this.speakRunId){if(!await this.waitForPause(j,Q))break}}}finally{if(this.activeRunId===Q)this.activeRunId=null}}async waitForPause(Z,Q){return await new Promise((J)=>{let Y=()=>{if(clearTimeout(X),this.settlePendingGap===Y)this.settlePendingGap=null;J()},X=setTimeout(Y,Z);this.settlePendingGap=Y}),Q===this.speakRunId}splitIntoChunks(Z){if(Z.length<=t9)return[{text:Z,offset:0}];let Q=this.segmentSentences(Z),J=[],Y="",X=0;for(let G of Q){let j=G.text.trim();if(!j)continue;let B=G.text.search(/\S/),V=G.offset+(B===-1?0:B);if(!Y){Y=j,X=V;continue}let K=`${Y} ${j}`;if(K.length<=t9)Y=K;else J.push({text:Y,offset:X}),Y=j,X=V}if(Y)J.push({text:Y,offset:X});return J.length?J:[{text:Z,offset:0}]}getContentLocale(){let Z=this.config?.providerOptions?.contentLanguage;return typeof Z==="string"&&Z.trim()?Z.trim():void 0}getSegmentationPolicy(){let Z=this.config?.providerOptions||{},Q=Z.segmenter||{},Y=Q.mode!=="regexOnly",X=typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:typeof Z.locale==="string"&&Z.locale.trim().length>0?Z.locale:void 0;return{useSentenceSegmenter:Y,locale:X}}segmentSentences(Z){let Q=this.getSegmentationPolicy();return v0(Z,{locale:Q.locale,useSentenceSegmenter:Q.useSentenceSegmenter})}inferWordLength(Z,Q){let J=Math.max(0,Math.min(Q,Math.max(0,Z.length-1)));return Z.slice(J).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(Z,Q,J,Y,X){return new Promise((G,j)=>{if(J!==this.speakRunId){G(!1);return}let B=new SpeechSynthesisUtterance(Z);this.utterance=B;let V=this.getContentLocale();if(V)B.lang=V;if(Y&&D2(Y))B.voice=Y;if(this.config?.rate)B.rate=this.config.rate;if(this.config?.pitch!==void 0)B.pitch=this.config.pitch;if(this.config?.volume!==void 0)B.volume=this.config.volume;let K=!1,U=!1,$=null,z=null,D=()=>{if(this.utterance===B)this.utterance=null},M=()=>{if($!==null)clearTimeout($),$=null},P=()=>{B.onstart=null,B.onend=null,B.onerror=null,B.onpause=null,B.onresume=null,B.onboundary=null},H=(O,C)=>{if(U)return;if(U=!0,M(),P(),D(),z&&this.settlePendingChunk===z)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1;if(C)j(C);else G(O)},N=(O)=>Error(O==="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 ${o9/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);z=()=>H(!1),this.settlePendingChunk=z,B.onstart=()=>{if(J!==this.speakRunId){H(!1);return}if(K=!0,M(),this._isPlaying=!0,this._isPaused)speechSynthesis.pause();try{this.onPlaybackStart?.()}catch(O){console.error("Browser TTS playback-start callback failed",O)}},B.onend=()=>{if(J!==this.speakRunId){H(!1);return}if(!K){H(!1,N("ended"));return}H(!0)},B.onerror=(O)=>{if(J!==this.speakRunId){H(!1);return}if(O.error==="interrupted"||O.error==="canceled"){H(!1);return}H(!1,Error(`Speech synthesis error: ${O.error}`))},B.onpause=()=>{if(J!==this.speakRunId)return;this._isPaused=!0},B.onresume=()=>{if(J!==this.speakRunId)return;this._isPaused=!1},B.onboundary=(O)=>{if(J!==this.speakRunId)return;if(a9.debug(`boundary event: ${O.name}, charIndex ${O.charIndex}, charLength ${O.charLength}`),O.name!=="word"||!this.onWordBoundary)return;let C=Math.max(0,Math.min(O.charIndex,Math.max(0,Z.length-1))),E=Number(O.charLength||0),v=this.inferWordLength(Z,C),S=Number.isFinite(E)&&E>0&&E<=K2&&C+E<=Z.length?E:v,u=Z.substring(C,Math.min(Z.length,C+S)).trim(),t=Q+C,n=X(t),K0=X(t+S-1)+1-n;a9.debug(`word boundary "${u}" at ${n}`),this.onWordBoundary(u,n,K0)},$=setTimeout(()=>{if(U||K||J!==this.speakRunId)return;H(!1,N("timedOut")),speechSynthesis.cancel()},o9);try{speechSynthesis.speak(B)}catch(O){H(!1,O instanceof Error?O:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPaused)return;if(this._isPlaying)speechSynthesis.pause(),this._isPaused=!0;else if(this.activeRunId===this.speakRunId)this._isPaused=!0}resume(){if(!this._isPaused)return;if(this._isPaused=!1,this._isPlaying)speechSynthesis.resume();this.releaseHold()}stop(){let Z=this.utterance,Q=this._isPlaying||Z!==null;if(this.speakRunId+=1,this.activeRunId=null,this.settlePendingChunk?.(),this.settlePendingGap?.(),Q)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1,this.releaseHold()}updateSettings(Z){if(!this.config)this.config={};if(Z.rate!==void 0)this.config.rate=Z.rate;if(Z.pitch!==void 0)this.config.pitch=Z.pitch;if(Z.volume!==void 0)this.config.volume=Z.volume;if(Z.voice!==void 0)this.config.voice=Z.voice;if(Z.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...Z.providerOptions||{}}}onWordBoundary}var H2=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),Y1=(Z)=>Z&&typeof Z==="object"?Z:{},V0=(Z,Q)=>Z===void 0?Q:Z,X1=(Z)=>nZ(Z)==="server"&&Z.serverProvider==="custom"?"custom":"pie",A2=(Z)=>typeof Z==="string"&&H2.has(Z)?Z:"left-aligned",NY=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 wY=Object.freeze([0.8,1,1.25]);var _2=(Z)=>{let Q={...Z,layoutMode:A2(Z.layoutMode)};if(Z.backend!=="server")return Q;let J={...Q,apiEndpoint:V0(Q.apiEndpoint,"/api/tts"),transportMode:V0(Q.transportMode,X1(Z)),endpointValidationMode:V0(Q.endpointValidationMode,"voices"),includeAuthOnAssetFetch:V0(Q.includeAuthOnAssetFetch,!1),rate:V0(Q.rate,1),language:V0(Q.language,"en-US")};if(Z.serverProvider==="polly")return{...J,engine:V0(J.engine,"neural"),format:V0(J.format,"mp3"),speechMarksMode:V0(J.speechMarksMode,"word+sentence")};return J},H7=(Z)=>{let{enabled:Q,provider:J,...Y}=Y1(Z);return _2(Y)},nZ=(Z)=>Z.backend||"browser",A7=(Z)=>{let Q=nZ(Z)==="server"?Z.serverProvider:void 0,J=Q==="polly",Y=Z.transportMode||X1(Z),X=W0(Z.mathSpeech);return{voice:Z.defaultVoice,rate:Z.rate,pitch:Z.pitch,providerOptions:{...Y1(Z.providerOptions),...Z.language?{locale:Z.language}:{},...J&&Z.engine?{engine:Z.engine}:{},...J&&typeof Z.sampleRate==="number"?{sampleRate:Z.sampleRate}:{},...J&&Z.format?{format:Z.format}:{},...J?{speechMarkTypes:Z.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...Y==="custom"&&typeof Z.cache==="boolean"?{cache:Z.cache}:{},...Y==="custom"&&Z.speedRate?{speedRate:Z.speedRate}:{},...Y==="custom"&&Z.lang_id?{lang_id:Z.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:Z.apiEndpoint,provider:Q,language:Z.language,transportMode:Y,endpointMode:Z.endpointMode,endpointValidationMode:Z.endpointValidationMode,includeAuthOnAssetFetch:Z.includeAuthOnAssetFetch,assetOrigins:Z.assetOrigins,credentials:Z.credentials,headers:Z.headers,...typeof Z.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Z.mathTokenHighlighting}:{}}};import{createPieLogger as O2,isGlobalDebugEnabled as M2}from"@pie-players/pie-players-shared/pie";var ZZ=O2("ToolProviderRegistry",M2);function QZ(Z){let Q=Z&&typeof Z==="object"?Z.backend:void 0;return typeof Q==="string"&&Q?Q:"unknown"}class rZ{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(Z,Q,J){try{await Z.onTelemetry?.(Q,J)}catch(Y){console.warn("[ToolProviderRegistry] Telemetry callback failed:",Y)}}register(Z,Q){let J=this.providers.get(Z),Y=this.initializationPromises.get(Z);if(this.providers.set(Z,Q.provider),this.configs.set(Z,Q),this.initialized.set(Z,!1),this.initializationPromises.delete(Z),J)if(Y)Y.catch(()=>{}).then(()=>this.destroyProvider(Z,J));else this.destroyProvider(Z,J);if(ZZ.debug(`${J?"Replaced":"Registered"} provider "${Z}" (${Q.provider.providerName})`),Q.lazy===!1)this.initialize(Z).catch((X)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${Z}":`,X)})}async initialize(Z){if(this.initialized.get(Z))return;let Q=this.initializationPromises.get(Z);if(Q)return Q;let J=this.providers.get(Z),Y=this._doInitialize(Z);this.initializationPromises.set(Z,Y);try{await Y}catch(X){if(!this.isReplaced(Z,J))throw X}finally{if(this.initializationPromises.get(Z)===Y)this.initializationPromises.delete(Z)}if(this.isReplaced(Z,J))return this.initialize(Z)}isReplaced(Z,Q){let J=this.providers.get(Z);return J!==void 0&&J!==Q}destroyProvider(Z,Q){try{Q.destroy()}catch(J){console.warn(`[ToolProviderRegistry] Failed to destroy provider "${Z}":`,J)}}async _doInitialize(Z){let Q=this.providers.get(Z),J=this.configs.get(Z);if(!Q||!J)throw Error(`[ToolProviderRegistry] Provider "${Z}" not registered`);let Y={...J.config},X=Date.now();if(await this.emitTelemetry(J,"pie-tool-init-start",{toolId:Z,backend:QZ(Y),operation:"provider-initialize"}),Q.requiresAuth&&J.authFetcher){let G=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Z,backend:QZ(Y),operation:"auth-fetch"}),ZZ.debug(`Fetching auth for "${Z}"...`);try{let j=await J.authFetcher();Y={...Y,...j},await this.emitTelemetry(J,"pie-tool-backend-call-success",{toolId:Z,backend:QZ(Y),operation:"auth-fetch",duration:Date.now()-G})}catch(j){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Z,backend:QZ(Y),operation:"auth-fetch",duration:Date.now()-G,errorType:"ProviderAuthFetchError",message:j instanceof Error?j.message:String(j)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Z}":`,j),Error(`Failed to fetch auth credentials for provider "${Z}"`)}}try{if(await Q.initialize(Y),this.providers.get(Z)===Q)this.initialized.set(Z,!0);await this.emitTelemetry(J,"pie-tool-init-success",{toolId:Z,backend:QZ(Y),operation:"provider-initialize",duration:Date.now()-X}),ZZ.debug(`Provider "${Z}" initialized`)}catch(G){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Z,backend:QZ(Y),operation:"provider-initialize",duration:Date.now()-X,errorType:"ProviderInitializationError",message:G instanceof Error?G.message:String(G)}),console.error(`[ToolProviderRegistry] Initialization failed for "${Z}":`,G),G}}async getProvider(Z,Q=!0){let J=this.providers.get(Z);if(!J)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:Z,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${Z}" not registered`);if(Q&&!this.initialized.get(Z))ZZ.debug("Auto-initializing provider:",Z),await this.initialize(Z);return J}getProvidersByCategory(Z){return Array.from(this.providers.entries()).filter(([Q,J])=>J.category===Z).map(([Q])=>Q)}getProviderIds(){return Array.from(this.providers.keys())}has(Z){return this.providers.has(Z)}isInitialized(Z){return this.initialized.get(Z)===!0}isInitializing(Z){return this.initializationPromises.has(Z)}async unregister(Z){let Q=this.providers.get(Z);if(Q){let J=this.initializationPromises.get(Z);if(J){try{await J}catch{}if(this.providers.get(Z)!==Q)return}this.destroyProvider(Z,Q),this.providers.delete(Z),this.configs.delete(Z),this.initialized.delete(Z),this.initializationPromises.delete(Z),ZZ.debug(`Unregistered provider "${Z}"`)}}async destroy(){let Z=Array.from(this.providers.keys());await Promise.all(Z.map((Q)=>this.unregister(Q))),ZZ.debug("Registry destroyed")}}class _7{onTargetFailure;targets=new Set;changeListeners=new Set;constructor(Z=(Q,J,Y)=>console.error(`[ToolRequestRegistry] "${Q}" ${J} failed:`,Y)){this.onTargetFailure=Z}registerTarget(Z){return this.targets.add(Z),this.notifyTargetsChange(),()=>{if(!this.targets.delete(Z))return;this.notifyTargetsChange()}}canRequest(Z,Q,J){return this.findTarget(Z,Q,J)!==null}request(Z){let Q=this.findTarget(Z.toolId,Z.level,Z.scopeId);if(!Q)return!1;try{Q.open(Z.toolId,Z.params)}catch(J){return this.onTargetFailure(Z.toolId,"tool-request-open",J),!1}return!0}onTargetsChange(Z){return this.changeListeners.add(Z),()=>{this.changeListeners.delete(Z)}}findTarget(Z,Q,J){let Y=this.findTargetAtLevel(Z,Q??"section",J);if(Y||Q!==void 0)return Y;for(let X of this.targets){if(X.level==="section")continue;if(J!==void 0&&X.scopeId!==J)continue;if(this.hostsTool(X,Z))return X}return null}findTargetAtLevel(Z,Q,J){for(let Y of this.targets){if(Y.level!==Q)continue;if(J!==void 0&&Y.scopeId!==J)continue;if(this.hostsTool(Y,Z))return Y}return null}hostsTool(Z,Q){try{return Z.hostsTool(Q)===!0}catch(J){return this.onTargetFailure(Q,"tool-request-host-check",J),!1}}notifyTargetsChange(){for(let Z of this.changeListeners)try{Z()}catch(Q){console.warn("[ToolRequestRegistry] Target change listener threw:",Q)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}function L2(Z){return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:void 0}function aZ(Z,Q,J){let Y=Q?.settings,X=[Q?.personalNeedsProfile?.toolParameters?.[Z],Y?.toolParameters?.[Z],J?.settings.toolParameters?.[Z]].map(L2).filter((G)=>G!==void 0);return X.length>0?Object.assign({},...X):void 0}class O7{provenance;stepCounter=0;constructor(Z){this.provenance={contextId:Z,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(Z,Q){let J={id:Q.id,name:Q.name??Q.id};switch(Z){case"organization":this.provenance.sources.organization={...J,pnpDefaults:Q.config};break;case"assessment":this.provenance.sources.assessment={...J,settings:Q.config};break;case"section":this.provenance.sources.section={...J,settings:Q.config};break;case"item":this.provenance.sources.item={...J,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(Z){let Q={step:++this.stepCounter,precedence:Z.precedence,rule:Z.rule,featureId:Z.featureId,action:Z.action,source:{type:Z.sourceType,id:Z.sourceId,name:Z.sourceName},reason:Z.reason,value:Z.value,timestamp:new Date};this.provenance.decisionLog.push(Q);let J=this.provenance.features.get(Z.featureId);if(!J)J={featureId:Z.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(Z.featureId,J);if(J.allDecisions.push(Q),Z.action==="advisory"){if(J.finalState==="not-configured")J.finalState="advisory-only"}else if(Z.action!=="skip"){if(!J.winningDecision||Q.precedence<J.winningDecision.precedence)J.winningDecision=Q,J.finalState=Q.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[Z.sourceType]=(this.provenance.summary.bySource[Z.sourceType]||0)+1,this.provenance.summary.byRule[Z.rule]=(this.provenance.summary.byRule[Z.rule]||0)+1,this}reconcileFinalStates(Z){for(let Q of Z){let J=this.provenance.features.get(Q);if(!J){J={featureId:Q,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Q,J);continue}J.finalState="enabled"}for(let Q of this.provenance.features.values()){if(Z.has(Q.featureId))continue;let J=Q.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),Y=Q.allDecisions.some((X)=>X.action==="advisory");if(J)Q.finalState="blocked";else if(Y)Q.finalState="advisory-only";else Q.finalState="not-configured"}return this}build(){for(let Z of this.provenance.features.values())Z.explanation=P2(Z);for(let Z of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,Z.finalState==="enabled")this.provenance.summary.enabled++;else if(Z.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function P2(Z){if(!Z.winningDecision){if(Z.finalState==="advisory-only"){let G=Z.allDecisions.find((j)=>j.action==="advisory");return G?`Feature "${Z.featureId}" was kept in its host-decided state; ${G.reason}`:`Feature "${Z.featureId}" carries an advisory note.`}return`Feature "${Z.featureId}" was not configured at any level.`}let Q=Z.winningDecision,J=Q.source.name||Q.source.type,Y=`Feature "${Z.featureId}" is ${Z.finalState}.
|
|
215
|
+
`,k8=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet"),f8=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet-adopted"),I8=(Z)=>!!Z&&typeof Z.replaceSync==="function",N6=()=>{let Z=globalThis,Q=Z[k8];if(I8(Q))return Q;let J=globalThis.CSSStyleSheet;if(typeof J!=="function")return null;try{let Y=new J;if(!I8(Y))return null;return Y.replaceSync(h8),Z[k8]=Y,Y}catch{return null}},zZ=(Z)=>{let Q=Z?.getRootNode?.();if(!u(Q))return;let J=Q,Y=J.adoptedStyleSheets;if(!Y||typeof Y!=="object")return;let X=Array.from(Y),G=J[f8];if(G&&X.includes(G))return;let j=N6();if(!j)return;try{J.adoptedStyleSheets=[...X,j],J[f8]=j}catch{}},p5="tts-word",g5="tts-sentence",n0=(Z)=>`annotation-${Z}`,S0=(Z)=>{let Q=CSS.highlights.get(Z);if(Q)return Q;let J=new Highlight;return CSS.highlights.set(Z,J),J},HZ=(Z,Q)=>{let J=CSS.highlights.get(Z);if(!J)return;for(let Y of Q)J.delete(Y)},v8=(Z)=>{let Q=Z[0]?.startContainer;if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:i(Q)},j0={source:null,override:null};class AZ{ttsWordRanges=new Set;ttsSentenceRanges=new Set;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;ttsStyleSource=null;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;constructor(){if(this.rangeSerializer=new u5,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 Z=document.getElementsByTagName("pie-theme"),Q=new WeakSet,J=()=>{let X=!1;for(let G of Z){if(Q.has(G))continue;Q.add(G),Y.observe(G,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]}),X=!0}return X},Y=new MutationObserver((X)=>{if(J()||X.some((j)=>j.type==="attributes"))this.applyAdaptiveTTSStyle()});this.themeObserver=Y,Y.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]}),Y.observe(document,{childList:!0,subtree:!0}),J()}parseColor(Z){if(!Z)return null;let Q=Z.trim();if(!Q)return null;let J=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Q);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 Y=/^rgba?\((.+)\)$/i.exec(Q);if(Y){let G=Y[1].replace(/\//g,",").split(/[,\s]+/).map((K)=>K.trim()).filter(Boolean),j=Number(G[0]),B=Number(G[1]),V=Number(G[2]);if(Number.isFinite(j)&&Number.isFinite(B)&&Number.isFinite(V))return[j,B,V]}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 G=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let j=G.trim();if(j&&j!==Q)return this.parseColor(G)}}return null}relativeLuminance([Z,Q,J]){let Y=(B)=>{let V=B/255;return V<=0.03928?V/12.92:((V+0.055)/1.055)**2.4},X=Y(Z),G=Y(Q),j=Y(J);return 0.2126*X+0.7152*G+0.0722*j}contrastRatio(Z,Q){let J=this.relativeLuminance(Z),Y=this.relativeLuminance(Q),X=Math.max(J,Y),G=Math.min(J,Y);return(X+0.05)/(G+0.05)}blend(Z,Q,J){return[Math.round(Z[0]*J+Q[0]*(1-J)),Math.round(Z[1]*J+Q[1]*(1-J)),Math.round(Z[2]*J+Q[2]*(1-J))]}resolveAdaptiveTTSStyle(Z){let Q=[255,235,59],J=[17,24,39],Y=[255,255,255],X=Z||(typeof document<"u"?document.documentElement:null),G=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,j=this.parseColor(G?.getPropertyValue("--pie-background")||G?.backgroundColor)||Y,B=this.parseColor(G?.getPropertyValue("--pie-text"))||J,V=j0.override,K=V?this.parseColor(V.color)||Q:this.parseColor(G?.getPropertyValue("--pie-missing"))||Q,U=V?[Math.max(0.3,Math.min(0.95,V.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],$=U[U.length-1],z=-1/0;for(let r of U){let q0=this.blend(K,j,r),Z0=this.contrastRatio(q0,j),M0=this.contrastRatio(q0,B),O0=Z0*1.2+M0*0.8;if(Z0>=1.25&&M0>=2.4){$=r;break}if(O0>z)z=O0,$=r}let H=Math.max(0.24,Math.min(0.85,$*0.55)),O=Math.max(0.55,Math.min(0.95,$+0.2)),N=Math.max(0.22,Math.min(0.6,$*0.45)),D=B,P=this.blend(D,j,O),M=this.contrastRatio(P,j),C=this.relativeLuminance(j)>0.45?[0,0,0]:[255,255,255],E=M>=1.35?D:C,v=`rgba(${K[0]}, ${K[1]}, ${K[2]}, ${$})`,S=`rgba(${K[0]}, ${K[1]}, ${K[2]}, ${H})`,p=`rgba(${E[0]}, ${E[1]}, ${E[2]}, ${O})`,e=`rgba(${E[0]}, ${E[1]}, ${E[2]}, ${N})`;return{wordHighlight:v,sentenceHighlight:S,wordUnderline:p,wordShadow:e}}applyAdaptiveTTSStyle(Z){if(typeof document>"u")return;if(Z)this.ttsStyleSource=Z,j0.source=Z;let Q=Z??(j0.source?.isConnected?j0.source:null),J=this.resolveAdaptiveTTSStyle(Q),Y=document.documentElement.style,X=[["--pie-tts-word-highlight",J.wordHighlight],["--pie-tts-sentence-highlight",J.sentenceHighlight],["--pie-tts-line-highlight",J.sentenceHighlight],["--pie-tts-word-underline",J.wordUnderline],["--pie-tts-word-shadow",J.wordShadow]];for(let[G,j]of X){if(Y.getPropertyValue?.(G)===j)continue;Y.setProperty(G,j)}}initializeHighlights(){if(!this.supported)return;S0(p5),S0(g5);for(let Z of Object.values(vZ))S0(n0(Z))}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let Z=document.createElement("style");Z.id="pie-highlight-styles",Z.textContent=h8,document.head.appendChild(Z)}highlightTTSWord(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(v8(Z)),this.clearTTSWord();let Q=S0(p5);for(let J of Z)zZ(J.startContainer),Q.add(J),this.ttsWordRanges.add(J);this.highlightTTSWordElementFallbacks(Z.filter((J)=>J.startContainer!==J.endContainer||J.startContainer.nodeType!==Node.TEXT_NODE))}highlightTTSWordElement(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(Z),zZ(Z),this.clearTTSWord(),Z.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(Z)}highlightTTSSentence(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(v8(Z)),this.clearTTSSentence();let Q=S0(g5);for(let J of Z)zZ(J.startContainer),Q.add(J),this.ttsSentenceRanges.add(J);this.highlightTTSElementFallbacks(Z)}highlightTTSSentenceElements(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(Z[0]||null),this.clearTTSSentence();for(let Q of Z)zZ(Q),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(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,AZ.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-word-element",this.ttsWordElementHighlights,AZ.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Z,Q,J,Y){let X=(G)=>G.nodeType===Node.ELEMENT_NODE?G:i(G);for(let G of Z){let j=G.commonAncestorContainer,B=u(j)?j:X(j);if(!B)continue;let V=[],K=X(G.startContainer),U=X(G.endContainer);for(let $ of[K,U]){let z=$;while(z){if(z.matches?.(Y))V.push(z);z=i(z)}}if(!u(B)&&B.matches?.(Y))V.push(B);V.push(...Array.from(B.querySelectorAll(Y)));for(let $ of new Set(V)){try{if(!G.intersectsNode($)&&!J0($,K)&&!J0($,U))continue}catch{continue}$.setAttribute(Q,"true"),J.add($)}}}clearTTSWord(){if(!this.supported)return;HZ(p5,this.ttsWordRanges),this.ttsWordRanges.clear();for(let Z of this.ttsWordElementHighlights)Z.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.supported)return;HZ(g5,this.ttsSentenceRanges),this.ttsSentenceRanges.clear();for(let Z of this.ttsSentenceElementHighlights)Z.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){if(this.clearTTSWord(),this.clearTTSSentence(),j0.source===this.ttsStyleSource)j0.source=null;this.ttsStyleSource=null}addAnnotation(Z,Q=vZ.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,Y=Z.cloneRange();zZ(Y.startContainer);let X={id:J,range:Y,type:c5.ANNOTATION,color:Q,timestamp:Date.now()};if(this.annotations.set(J,X),this.supported)S0(n0(Q)).add(Y);return J}removeAnnotation(Z){let Q=this.annotations.get(Z);if(!Q){console.warn(`[HighlightCoordinator] Annotation ${Z} not found`);return}if(this.supported)HZ(n0(Q.color),[Q.range]);this.annotations.delete(Z)}clearAnnotations(){if(this.supported)for(let Z of this.annotations.values())HZ(n0(Z.color),[Z.range]);this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(Z){return this.annotations.get(Z)??null}changeAnnotationColor(Z,Q){let J=this.annotations.get(Z);if(!J)return;let Y=J.color;if(Y===Q)return;if(J.color=Q,this.supported)HZ(n0(Y),[J.range]),S0(n0(Q)).add(J.range)}exportAnnotations(Z=document.body){return this.getAnnotations().map((Q)=>({...this.rangeSerializer.serialize(Q.range,Z),id:Q.id,color:Q.color,timestamp:Q.timestamp}))}importAnnotations(Z,Q=document.body){let J=0;for(let Y of Z){let X=this.rangeSerializer.deserialize(Y,Q);if(X)this.addAnnotation(X,Y.color),J++}return J}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}updateTTSHighlightStyle(Z,Q){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((G)=>{let j=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(G);return j?{r:parseInt(j[1],16),g:parseInt(j[2],16),b:parseInt(j[3],16)}:null})(Z);if(!X)return;j0.override={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Q)),owner:this},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;if(this.clearTTS(),this.clearAnnotations(),j0.override?.owner===this)j0.override=null;this.themeObserver?.disconnect(),this.themeObserver=null}}import{applyMediaFragment as B2,enforceMediaFragment as W2}from"@pie-players/pie-players-shared/media";import{createPieLogger as V2,isTtsDebugEnabled as a9}from"@pie-players/pie-players-shared/pie";import{isUnsupportedMediaAssetVersion as P6,normalizeMediaFragment as w6,normalizeMediaSources as R6,trimmedOrUndefined as C6}from"@pie-players/pie-players-shared/media";function m8(Z){if(!Z)return null;let Q=Z.payload;if(!Q||typeof Q!=="object")return null;let J=Q.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(P6(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 Y=R6(J.sources);if(Y.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:Y,fragment:w6(Q.fragment),label:C6(J.label)}}var b6="[data-pie-shell-root]";var u8=(Z)=>Z?IZ(Z,b6):null;var hZ="en-US",d5=(Z,Q)=>{let J=!Z?null:Z.nodeType===1?Z:i(Z);while(J){let Y=J.getAttribute("lang");if(Y!==null)return Y.trim()||void 0;if(Q&&J===Q)return;J=i(J)}return},p8=(Z)=>{let Q;for(let J of Z.querySelectorAll("[lang]")){let Y=J.parentElement?.closest("[lang]");if(Y&&Y!==Z&&Z.contains(Y))continue;let X=J.getAttribute("lang")?.trim();if(!X)return;if(Q===void 0)Q=X;else if(Q.toLowerCase()!==X.toLowerCase())return}return Q},i5=(Z,Q={})=>{let J=Q.boundary!==void 0?Q.boundary:u8(Z);return(J?d5(Z,J):void 0)||Q.contentLanguage?.trim()||void 0},g8=(Z,Q={})=>i5(Z,Q)??hZ;var T=(Z)=>Z.trim().replace(/\s+/g," "),l8=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,mZ=(Z)=>{if(Z.hidden)return!0;if(Z.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(Z.getAttribute("aria-hidden")==="true")return!0;if(Z.hasAttribute("inert"))return!0;let Q=Z.classList;if(Q?.contains("sr-only")||Q?.contains("pie-sr-only")||Q?.contains("visually-hidden"))return!0;if(typeof window<"u"){let J=window.getComputedStyle(Z);if(J.display==="none"||J.visibility==="hidden")return!0;let Y=Number.parseFloat(J.width||"0"),X=Number.parseFloat(J.height||"0"),G=Number.isFinite(Y)&&Number.isFinite(X)&&Y<=1&&X<=1,j=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")&&G&&(J.overflow==="hidden"||j))return!0;if(J.opacity==="0"&&G)return!0}return!1},r0=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(mZ(J))return!0;if(Q&&J===Q)break;J=c(J)}return!1},c8="data-tts-suppress",s8=new Set(["computer-read-aloud","all"]),d8=new Set([...s8,"screen-reader"]),i8=new Set,E6=(Z)=>{let Q=Z.getAttribute?.(c8);if(Q===null||Q===void 0)return!1;let J=Q.trim().toLowerCase();if(s8.has(J))return!0;if(d8.has(J))return!1;if(!i8.has(J))i8.add(J),console.warn(`[tts] ${c8}="${Q}" is not one of ${Array.from(d8).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},uZ=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(E6(J))return!0;if(Q&&J===Q)break;J=c(J)}return!1},z0=(Z,Q)=>r0(Z,Q)||uZ(Z),l5=(Z,Q)=>{if(typeof Z.intersectsNode!=="function")return{text:Z.toString(),filtered:!1};let J=[],Y=!1;for(let X of b0(Q))if(G0(Z,X))if(z0(X,Q))Y=!0;else J.push(s5(X,Z));return{text:J.join(""),filtered:Y}},s5=(Z,Q)=>{let J=Z.textContent||"",Y=Z===Q.startContainer?Q.startOffset:0,X=Z===Q.endContainer?Q.endOffset:J.length;return J.slice(Y,X)},DZ=(Z,Q,J)=>{let Y=null,X=null;for(let G of b0(Q)){if(z0(G,J))continue;let j=G.textContent||"",B=j.search(/\S/);if(B===-1)continue;Y??={node:G,offset:B},X={node:G,offset:j.trimEnd().length-1}}if(!Y||!X)return G0(Z,Q);return FZ(Z,Y.node,Y.offset)&&FZ(Z,X.node,X.offset)},n5=(Z,Q,J)=>{if(!Z||!Q)return!1;if(/\s/.test(Z)||/\s/.test(Q))return!1;let Y=J?.boundarySpacingMode??"segmenterPreferred";if(Y==="none")return!1;if(Y==="segmenterPreferred")try{let j=globalThis.Intl?.Segmenter;if(typeof j==="function"){let B=new j(J?.locale,{granularity:"word"});if(Array.from(B.segment(`${Z}${Q}`)).filter((U)=>U.isWordLike!==!1&&U.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(Z),G=/[A-Za-z0-9]/.test(Q);return X&&G},y0=(Z,Q)=>{let J=new Map;if(typeof document>"u")return{text:"",map:J};let Y=[],X=0,G=!0,j=!1,B=null,V=null;for(let U of b0(Z))if(c(U)&&!z0(U,Z)){let z=U.textContent||"",H=z.match(/\S/),O=H?H[0]:null;if(!G&&!j&&n5(V,O,Q)){if(Y.push(" "),B)J.set(X,B);X++,j=!0}for(let N=0;N<z.length;N++){let D=z[N],P=/\s/.test(D);if(G){if(!P)G=!1,Y.push(D),J.set(X,{node:U,offset:N}),B={node:U,offset:N},X++,j=!1,V=D}else if(P){if(!j)Y.push(" "),J.set(X,{node:U,offset:N}),B={node:U,offset:N},X++;j=!0}else Y.push(D),J.set(X,{node:U,offset:N}),B={node:U,offset:N},X++,j=!1,V=D}}let K=Y.join("").trimEnd();while(J.has(K.length))J.delete(K.length);return{text:K,map:J}};var S6=/^\s*<speak[\s/>]/i,gZ=(Z)=>S6.test(Z),y6=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),n8=new Set(["audio","phoneme"]),a8=(Z)=>Z.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),pZ=(Z,Q,J)=>{for(let Y=0;Y<Q.length;Y++)Z.push({char:Q[Y],rawOffset:J===null?null:J+Y})},T6=(Z,Q,J)=>{let Y=Q.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!Y)return 0;return pZ(Z,a8(Y[0]),J),Y[0].length},r8=(Z)=>{Z.push({char:" ",rawOffset:null})},x6=(Z)=>{let Q=new Map,J=[],Y=!0;for(let X of Z){if(/\s/.test(X.char)){if(!Y&&J.length>0){if(J.push(" "),X.rawOffset!==null)Q.set(X.rawOffset,J.length-1)}Y=!0;continue}if(J.push(X.char),X.rawOffset!==null)Q.set(X.rawOffset,J.length-1);Y=!1}while(J.length>0&&J[J.length-1]===" ")J.pop();for(let[X,G]of Q)if(G>=J.length)Q.delete(X);return{text:J.join(""),rawToSpokenOffsetMap:Q}},k6=(Z)=>{return Z.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},f6=(Z,Q)=>{let J=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),Y=Z.match(J);return a8(Y?.[2]??Y?.[3]??"")||null},cZ=(Z)=>{let Q=[],J=!1,Y=!1,X=0;while(X<Z.length){let j=Z[X];if(j!=="<"){if(j==="&"){let z=T6(Q,Z,X);if(z>0){X+=z;continue}}pZ(Q,j,X),X++;continue}let B=Z.indexOf(">",X+1);if(B<0){pZ(Q,j,X),X++;continue}Y=!0;let V=Z.slice(X,B+1),K=k6(V),U=/^<\s*\//.test(V),$=/\/\s*>$/.test(V);if(!U&&K==="sub"){let z=f6(V,"alias");if(!z){J=!0,X=B+1;continue}pZ(Q,z,null);let H=Z.toLowerCase().indexOf("</sub>",B+1);X=H>=0?H+6:B+1;continue}if(!U&&K==="break"){r8(Q),X=B+1;continue}if(!U&&n8.has(K)){if(J=!0,$){X=B+1;continue}}if(K&&!y6.has(K)&&!n8.has(K)&&K!=="break"&&K!=="sub")J=!0;if(!U&&(K==="p"||K==="s"))r8(Q);X=B+1}let G=x6(Q);return{spokenText:T(G.text),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:Y}};var I6=l8(),v6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),h6=(Z)=>{let Q=Z.toLowerCase();return v6.get(Q)||Q},o5=(Z)=>{let Q=[];for(let J of Z.matchAll(I6)){let Y=J[0],X=J.index??0;Q.push({text:Y,normalized:h6(Y),start:X,end:X+Y.length})}return Q},m6=(Z)=>o5(Z).map((Q,J)=>({...Q,id:`speech-token-${J}`,sourceStart:Q.start,sourceEnd:Q.end,coordinateSystem:"normalized-speech"})),T0=(Z)=>{let Q=cZ(Z.speechText);return{speechText:Z.speechText,spokenText:Q.spokenText,tokens:m6(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},t5=(Z)=>Boolean(Z&&/^<[^>]+>$/.test(Z.trim())),a0=(Z)=>{if(!Z||t5(Z))return null;return T0({speechText:Z}).tokens[0]?.normalized??null},u6=(Z,Q)=>Z.find((J)=>J.start<=Q&&Q<J.end)||null,p6=(Z,Q)=>{let J=Z.rawToSpokenOffsetMap.get(Q);if(J!==void 0)return J;for(let Y=Q;Y<Z.speechText.length;Y++){let X=Z.rawToSpokenOffsetMap.get(Y);if(X!==void 0)return X;if(Z.speechText[Y]===">")break}return null},r5=(Z,Q,J)=>{if(Q===null)return null;let Y=u6(Z.tokens,Q);if(!Y)return null;return{token:Y,start:Q,length:Math.max(1,Math.min(J,Y.end-Q)),confidence:0.75}},a5=(Z,Q)=>Boolean(Z&&Q&&Z.token.normalized===Q),e5=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||t5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=a0(Z.boundaryWord),Y=r5(Z.tokenization,p6(Z.tokenization,Z.position),Q),X=r5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(a5(Y,J))return{...Y,confidence:1};if(a5(X,J))return{...X,confidence:1};if(J)return null;return Z.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||X:X||Y},o8=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||t5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=a0(Z.boundaryWord),Y=r5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(a5(Y,J))return{...Y,confidence:1};if(J)return null;return Y};var Z7=10,g6=0.12,c6=[{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}],d6=(Z,Q)=>{let J=[];for(let Y=0;Y<Z.length;Y++){for(let X=0;X<Q.length;X++)if(Z[Y].normalized===Q[X].normalized)J.push({spokenStartToken:Y,spokenEndToken:Y+1,visibleToken:X,score:Z7});for(let X of c6){let G=Z.slice(Y,Y+X.phrase.length);if(G.length!==X.phrase.length)continue;if(!G.every((j,B)=>j.normalized===X.phrase[B]))continue;for(let j=0;j<Q.length;j++){if(Q[j].text!==X.visible)continue;J.push({spokenStartToken:Y,spokenEndToken:Y+X.phrase.length,visibleToken:j,score:X.score})}}}return J},i6=(Z,Q)=>{let J=d6(Z,Q).sort((V,K)=>Z[V.spokenStartToken].start-Z[K.spokenStartToken].start||Q[V.visibleToken].start-Q[K.visibleToken].start),Y=Array(J.length).fill(0),X=Array(J.length).fill(-1);for(let V=0;V<J.length;V++){let K=J[V];Y[V]=K.score;for(let U=0;U<V;U++){let $=J[U];if($.spokenEndToken<=K.spokenStartToken&&$.visibleToken<K.visibleToken){let z=K.spokenStartToken-$.spokenEndToken,H=K.visibleToken-$.visibleToken-1,O=Math.max(0,Math.abs(z-H)-2),N=Y[U]+K.score-O;if(N>Y[V])Y[V]=N,X[V]=U}}}let G=-1;for(let V=0;V<Y.length;V++)if(G<0||Y[V]>Y[G])G=V;if(G<0)return[];let j=[],B=G;while(B>=0)j.unshift(J[B]),B=X[B];return j.map((V)=>{let K=Z[V.spokenStartToken],U=Z[V.spokenEndToken-1],$=Q[V.visibleToken];return{spokenStart:K.start,spokenEnd:U.end,visibleStart:$.start,visibleEnd:$.end,score:V.score}})},l6=(Z,Q,J)=>{if(Z.length===0)return 0;let Y=Z.length/Math.max(1,Math.min(Q.length,J.length)),X=Z.reduce((G,j)=>G+j.score,0)/Z.length/Z7;return Math.min(1,Y*X)},dZ=(Z)=>{let Q=T0({speechText:Z.speechText}),J=T(Z.visibleText),Y=Q.tokens,X=o5(J),G=Q.unsupportedSemantic?[]:i6(Y,X),j=l6(G,Y,X),B=Q.spokenText===J&&Q.spokenText.length>0,V=G.length===1&&G[0].score===Z7&&Y.length<=2&&X.length<=2,K=(G.length>=2||V)&&j>=g6,U=Q.unsupportedSemantic?"region-fallback":B?"exact-word":K?"anchor-span":"region-fallback";return{speech:Q,visibleText:J,playbackMode:U,anchors:G,confidence:j}},t8=(Z,Q)=>{if(Z.playbackMode==="region-fallback")return null;let J=Z.anchors.find((G)=>G.spokenStart<=Q&&Q<G.spokenEnd);if(J)return{start:J.visibleStart,end:J.visibleEnd};let Y=null,X=null;for(let G of Z.anchors){if(G.spokenEnd<=Q){Y=G;continue}if(G.spokenStart>Q){X=G;break}}if(Y&&X)return{start:Math.min(Y.visibleStart,X.visibleStart),end:Math.max(Y.visibleEnd,X.visibleEnd)};return null};var s6=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"]]]),n6=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),e8=new Map([["2",["squared"]],["3",["cubed"]]]),r6=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),a6=(Z)=>Z.replace(/\s+/g," ").trim(),x0=(Z)=>(Z.localName||Z.tagName||"").toLowerCase(),o6=(Z)=>Z.nodeType===Node.ELEMENT_NODE,o0=(Z)=>Array.from(Z.childNodes).filter(o6),Q7=(Z)=>a6(Z.textContent||""),B0=(Z,Q)=>({type:"element-range",quality:Q,element:Z}),t6=(Z)=>{switch(Z){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"}},e6=(Z,Q)=>{if(Q==="operator"){if(Z==="−")return"-";return Z}return Z.toLowerCase()},Z3=(Z,Q,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return e8.get(Z)??[];if(Z==="|")return["absolute value"];if(Q==="operator")return s6.get(Z)||[];return[]},k0=(Z)=>{let Q=Z.normalized??e6(Z.text,Z.kind||"unknown");return{id:`math-token-${Z.state.nextId++}`,kind:Z.kind,role:Z.role,text:Z.text,normalized:Q,spokenAliases:Z3(Z.text,Z.kind,Z.role),sourceElement:Z.sourceElement,path:Z.path,target:Z.target||B0(Z.sourceElement,"element-range"),optional:Z.optional}},f0=(Z,Q,J="tokens")=>{Z[J].push(Q)},Z9=(Z,Q,J)=>{o0(Z).forEach((Y,X)=>W0(Y,Q,`${J}/${x0(Y)}[${X}]`))},Q3=(Z,Q,J)=>{let Y=o0(Z);if(Y[0])W0(Y[0],Q,`${J}/numerator`);if(f0(Q,k0({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:Z,path:J,target:B0(Z,"element-range")})),Y[1])W0(Y[1],Q,`${J}/denominator`)},J3=(Z,Q,J)=>{let Y=Z.getAttribute("open")||"(",X=Z.getAttribute("close")||")";f0(Q,k0({state:Q,kind:"operator",role:Y==="|"?"absolute-value-fence":"open-fence",text:Y,sourceElement:Z,path:`${J}/open`,target:B0(Z,"element-range")})),Z9(Z,Q,J),f0(Q,k0({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Z,path:`${J}/close`,target:B0(Z,"element-range")}))},Y3=(Z,Q,J)=>{let Y=o0(Z);if(Y[0])W0(Y[0],Q,`${J}/base`);let X=Y[1];if(!X)return;let G=Q7(X);if(e8.has(G)){f0(Q,k0({state:Q,kind:"structure",role:"superscript",text:G,normalized:G,sourceElement:X,path:`${J}/exponent`,target:B0(Z,"element-range")}));return}W0(X,Q,`${J}/exponent`)},X3=(Z,Q,J,Y)=>{f0(Q,k0({state:Q,kind:"structure",role:Y,text:Q7(Z)||Y,normalized:`\x00${Y}`,sourceElement:Z,path:J,target:B0(Z,"element-range")}))},G3=(Z,Q,J)=>{let Y=0;for(let X of o0(Z)){if(x0(X)==="mtr"||x0(X)==="mlabeledtr")Y++,f0(Q,k0({state:Q,kind:"layout",role:"table-row",text:`row-${Y}`,normalized:`row-${Y}`,sourceElement:X,path:`${J}/row[${Y}]`,target:B0(X,"region-fallback")}),"layoutTargets");W0(X,Q,`${J}/${x0(X)}[${Y}]`)}},j3=(Z,Q,J)=>{let Y=Q7(Z);if(!Y)return;let X=t6(x0(Z)),G=X==="operator"?n6.get(Y):void 0,j=G??(X==="operator"&&(Y==="("||Y===")")?"grouping-fence":X);f0(Q,k0({state:Q,kind:X,role:j,text:Y,sourceElement:Z,path:J,target:G&&Z.parentElement?B0(Z.parentElement,"region-fallback"):void 0,optional:Boolean(G)||j==="grouping-fence"}))},W0=(Z,Q,J)=>{let Y=x0(Z);switch(Y){case"annotation":case"annotation-xml":return;case"semantics":{let X=o0(Z).find((G)=>{let j=x0(G);return j!=="annotation"&&j!=="annotation-xml"});if(X)W0(X,Q,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":j3(Z,Q,J);return;case"mfrac":Q3(Z,Q,J);return;case"msup":Y3(Z,Q,J);return;case"mfenced":J3(Z,Q,J);return;case"mtable":G3(Z,Q,J);return;case"mphantom":return;case"maction":{let X=o0(Z)[0];if(X)W0(X,Q,`${J}/action`);return}default:{let X=r6.get(Y);if(X){X3(Z,Q,J,X);return}Z9(Z,Q,J)}}},Q9=(Z)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return W0(Z,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:B0(Z,"region-fallback")}};var J9=(Z)=>{if(!Z.boundary)return null;return Z.alignment.segments.find((J)=>J.speechTokenIds.includes(Z.boundary.token.id))?.target||null};var B3=(Z)=>{let Q=[],J=new Set,Y=(X)=>{let G=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(G.length===0)return;let j=G.join(" ");if(J.has(j))return;J.add(j),Q.push(G)};Y(Z.normalized);for(let X of Z.spokenAliases)Y(X);return Q},Y9=(Z,Q,J)=>{let Y=0;for(let X of J){if(X.length<=Y)continue;let G=!0;for(let j=0;j<X.length;j++){let B=Z[Q+j];if(!B||B.normalized.toLowerCase()!==X[j]){G=!1;break}}if(G)Y=X.length}return Y},W3=(Z,Q)=>{let J=[],Y=0;for(let X of Q){let G=B3(X);if(X.optional){let j=Y9(Z,Y,G);if(j>0)J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;continue}while(Y<Z.length){let j=Y9(Z,Y,G);if(j>0){J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;break}Y++}}return J},V3=(Z,Q,J)=>{let Y=J.filter((j)=>!j.optional).length,X=Z.filter((j)=>!j.math.optional).length,G=Z.reduce((j,B)=>j+B.speechTokens.length,0);return Y>0&&X===Y&&G===Q.length},K3=(Z)=>Z.map(({speechTokens:Q,math:J})=>({speechTokenIds:Q.map((Y)=>Y.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),X9=(Z)=>{let Q=Z.minExactWordConfidence??0.95,J=W3(Z.speech.tokens,Z.math.tokens),Y=V3(J,Z.speech.tokens,Z.math.tokens)?1:0;return{segments:Y>=Q?K3(J):[],confidence:Y,fallbackTarget:Z.math.expressionTarget}};var t0=(Z)=>{let Q=T0({speechText:Z.speechText}),J=Q9(Z.mathElement);return{speech:Q,math:J,result:X9({speech:Q,math:J})}};var G9=(Z,Q)=>{let J=o8({tokenization:Z.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return J9({alignment:Z.result,boundary:J})},j9=(Z,Q)=>{let J=a0(Q.boundaryWord);if(!J)return null;let Y=Z.math.tokens.filter((X)=>X.normalized.toLowerCase()===J||X.spokenAliases.some((G)=>G.toLowerCase()===J));return Y.length===1?Y[0].target:null};var q3=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"]),U3=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"]),B9=(Z)=>Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),$3=(Z)=>B9(Z).replace(/"/g,"""),F3=(Z,Q)=>{let J=Z.toLowerCase(),Y=Q.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!U3.has(J))return!0;if(Y.includes("javascript:"))return!0;if(Y.includes("data:text/html"))return!0;return!1},z3=(Z)=>{let Q=Z.localName.toLowerCase();if(!q3.has(Q))return!1;let J=Z.namespaceURI;return!J||J==="http://www.w3.org/1998/Math/MathML"||J==="http://www.w3.org/1999/xhtml"},W9=(Z)=>{if(Z.nodeType===Node.TEXT_NODE)return B9(Z.textContent||"");if(Z.nodeType===Node.COMMENT_NODE)return"";if(Z.nodeType!==Node.ELEMENT_NODE)return null;let Q=Z;if(!z3(Q))return null;let J=Q.localName.toLowerCase(),Y=[];for(let j of Array.from(Q.attributes)){let B=j.name.toLowerCase();if(F3(B,j.value))continue;if(B==="xmlns"&&j.value!=="http://www.w3.org/1998/Math/MathML")return null;Y.push(`${B}="${$3(j.value)}"`)}if(J==="math"&&!Y.some((j)=>j.startsWith("xmlns=")))Y.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let j of Array.from(Q.childNodes)){let B=W9(j);if(B===null)return null;X.push(B)}let G=Y.length>0?` ${Y.join(" ")}`:"";return`<${J}${G}>${X.join("")}</${J}>`},H3=(Z)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Z,"application/xml");return null},e0=(Z)=>{let Q=String(Z||"").trim();if(!Q)return null;let J=H3(Q);if(!J)return null;if(J.getElementsByTagName("parsererror").length>0)return null;let Y=J.documentElement;if(!Y||Y.localName.toLowerCase()!=="math")return null;return W9(Y)};var K9=(Z)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Z}),J7=(Z)=>Z.classList?.contains("MathJax")||Z.tagName?.toLowerCase()==="mjx-container",q9=(Z)=>Z.tagName?.toLowerCase()==="mjx-assistive-mml",Y7=(Z)=>{let Q=Z.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},A3=(Z)=>{let Q=Z.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},D3=(Z)=>{return E0(Z,"mjx-assistive-mml math")?.outerHTML||null},_3=(Z)=>{if(Z.tagName.toLowerCase()==="math")return e0(Z.outerHTML);let Q=A3(Z);if(Q){let J=e0(Q);if(J)return J}if(J7(Z)){let J=D3(Z);if(J){let Y=e0(J);if(Y)return Y}}return null},M3=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),O3=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),L3=(Z,Q)=>{let J=c(Z);while(J&&J!==Q){let Y=(J.getAttribute("role")||"").toLowerCase(),X=J.tagName.toUpperCase();if(M3.has(X)||O3.has(Y))return J;J=c(J)}return Q},N3=(Z)=>Boolean(typeof Z.querySelector==="function"&&E0(Z,"math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Z.tagName?.toLowerCase()==="math"||Z.hasAttribute?.("data-mathml")||J7(Z),I0=(Z,Q,J)=>{if(/[.,;:!?]/.test(Q)&&Z.chars.length>0&&Z.chars[Z.chars.length-1]===" ")Z.chars.pop(),Z.position--,Z.map.delete(Z.position);if(Z.chars.push(Q),J)Z.map.set(Z.position,J),Z.lastMapped=J;else if(Z.lastMapped)Z.map.set(Z.position,Z.lastMapped);Z.position++},U9=(Z,Q)=>{if(Z.inLeadingWhitespace||Z.lastCharWasWhitespace||Z.chars.length===0)return!1;let J=Z.chars[Z.chars.length-1];return n5(J,Q,Z.options)},$9=(Z,Q,J=0,Y=(Q.textContent||"").length)=>{let X=Q.textContent||"",G=!1;for(let j=J;j<Y;j++){let B=X[j],V=/\s/.test(B);if(Z.inLeadingWhitespace){if(!V)Z.inLeadingWhitespace=!1,I0(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1;continue}if(V){if(!Z.lastCharWasWhitespace)I0(Z," ",{node:Q,offset:j});Z.lastCharWasWhitespace=!0;continue}if(!G&&U9(Z,B))I0(Z," ",{node:Q,offset:j});I0(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1}},P3=(Z,Q)=>{for(let J=0;J<Q.text.length;J++){let Y=Q.text[J],X=/\s/.test(Y),G=Q.map.get(J),j=G?{node:G.node,offset:G.offset}:Z.lastMapped?{node:Z.lastMapped.node,offset:Z.lastMapped.offset}:null;if(Z.inLeadingWhitespace){if(X)continue;Z.inLeadingWhitespace=!1}if(X){if(!Z.lastCharWasWhitespace)I0(Z," ",j);Z.lastCharWasWhitespace=!0;continue}if(J===0&&U9(Z,Y))I0(Z," ",j);I0(Z,Y,j),Z.lastCharWasWhitespace=!1}},w3=(Z)=>{if(typeof DOMParser>"u")return"";let Q=new DOMParser().parseFromString(Z,"application/xml");if(Q.getElementsByTagName("parsererror").length>0)return"";let J=[],Y=(X)=>{if(X.nodeType===3){let j=X.textContent||"";if(j.trim())J.push(j);return}if(X.nodeType!==1)return;let G=X;if(Y7(G))return;for(let j of Array.from(G.childNodes))Y(j)};return Y(Q.documentElement),T(J.join(" "))},R3=(Z,Q)=>{let J=new Map,Y=J7(Z)?E0(Z,"mjx-assistive-mml math"):null;if(!Y)return J;let X=[],G=(B)=>{if(B.nodeType===3){let V=B.textContent||"";for(let K=0;K<V.length;K++)if(!/\s/.test(V[K]))X.push({node:B,offset:K});return}if(B.nodeType!==1||Y7(B))return;for(let V of F0(B))G(V)};G(Y);let j=0;for(let B=0;B<Q.length;B++){if(/\s/.test(Q[B]))continue;let V=X[j];if(V?.node.textContent?.[V.offset]!==Q[B])return new Map;J.set(B,V),j++}return j===X.length?J:new Map},C3=(Z,Q,J)=>{let Y=K9(J),X=(B)=>{if(z0(B,Z))return;if(B.nodeType===3){$9(Y,B);return}if(B.nodeType!==1)return;let V=B;if(q9(V)||Y7(V))return;for(let K of F0(V))X(K)};X(Z),F9(Y);let G=T(Y.chars.join(""));if(G)return{text:G,map:Y.map};let j=w3(Q);if(!j)return y0(Z,J);return{text:j,map:R3(Z,j)}},F9=(Z)=>{while(Z.chars.length>0&&/\s/.test(Z.chars[Z.chars.length-1]))Z.chars.pop(),Z.position--,Z.map.delete(Z.position)},V9=(Z,Q,J)=>{let Y=K9(Q),X=[],G=0,j,B=!1,V=()=>{let $=T(Y.chars.slice(G,Y.chars.length).join(""));if($)X.push({type:"text",text:$,sourceElement:j});G=Y.chars.length,j=void 0},K=($)=>{if(z0($,Z))return;if(J&&!G0(J,$))return;if($.nodeType===3){let O=L3($,Z);if(j&&O!==j)V();j=O;let N=$;$9(Y,N,J?.startContainer===N?J.startOffset:void 0,J?.endContainer===N?J.endOffset:void 0);return}if($.nodeType!==1)return;let z=$;if(q9(z))return;let H=_3(z);if(H&&(!J||DZ(J,z,Z))){V();let O=C3(z,H,Q);P3(Y,O);let N=T(O.text);X.push({type:"math",mathml:H,fallbackText:N,sourceElement:z}),G=Y.chars.length,B=!0;return}for(let O of F0(z))K(O)};for(let $ of F0(Z))K($);return F9(Y),V(),{visibleText:Y.chars.join(""),map:Y.map,chunks:X,containsMathMarkup:B}},H0=(Z,Q,J)=>{if(J)return V9(Z,Q,J);if(!N3(Z)){let{text:Y,map:X}=y0(Z,Q);return{visibleText:Y,map:X,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return V9(Z,Q)};import{createPieLogger as E3,isTtsDebugEnabled as S3}from"@pie-players/pie-players-shared/pie";var iZ=E3("tts-math-speech",S3),z9=Promise.resolve(),y3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",T3=(Z)=>{let Q=null,J=!1;return(Y)=>{if(!Q){_9(Y);let X=Z();Q=X,X.catch((G)=>{if(Q===X)Q=null;if(J){iZ.debug("speech-rule-engine failed to load again",G);return}J=!0,iZ.warn("speech-rule-engine failed to load; math reads as its visible text until a later read loads it.",G)})}return Q}},x3=T3(()=>import("./chunks/sre-engine-wazxma67.js").then(({default:Z})=>{if(!Z||typeof Z.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Z})),X7=(Z)=>{let Q=null;return()=>{return Q??=x3(V0(Z)?.engineOptions),Q}},k3=(Z)=>Z==="en"?"clearspeak":"mathspeak",H9=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),A9=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,V0=(Z)=>{if(!H9(Z))return;let Q=A9(Z.domain),J=A9(Z.style),Y=H9(Z.engineOptions)?Z.engineOptions:void 0;if(!Q&&!J&&!Y)return;return{...Q?{domain:Q}:{},...J?{style:J}:{},...Y?{engineOptions:Y}:{}}},f3=async(Z,Q,J,Y)=>{let X=y3(Q),G=V0(Y),j=G?.engineOptions||{};await Z.setupEngine?.({...D9(j),...j,locale:X,domain:G?.domain||k3(X),style:G?.style||"default",modality:"speech",markup:J}),await Z.engineReady?.()},I3=async(Z)=>{let Q=z9.then(Z,Z);return z9=Q.then(()=>{return},()=>{return}),Q},M9=async(Z,Q,J,Y,X)=>I3(async()=>{return await f3(Z,J,Y,X),Z.toSpeech(Q)}),v3=(Z)=>Z.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),h3=async(Z,Q,J,Y)=>{try{let X=v3(await M9(Z,Q,J,"ssml",Y));return X.includes("<speak")?X:null}catch(X){return iZ.debug("math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},ZZ=async(Z,Q={})=>{if(!Z.some((K)=>K.type==="math"))return{speechText:T(Z.map((K)=>K.type==="text"?K.text:K.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let J=null,Y=!1,X=!1,G=Q.loadSre||X7(Q.mathSpeech),j=[];for(let K of Z){if(K.type==="text"){j.push(K.text);continue}try{if(!J)J=await G();let U=T(await M9(J,K.mathml,Q.language,"none",Q.mathSpeech));if(U){j.push(U),Y=!0;continue}X=!0,j.push(K.fallbackText)}catch(U){X=!0,iZ.debug("math speech generation failed; using visible fallback",{message:U instanceof Error?U.message:String(U)}),j.push(K.fallbackText)}}let B=T(j.join(" ")),V;if(Q.produceSsml&&J&&Y&&Z.length===1&&Z[0].type==="math")V=await h3(J,Z[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:Y,usedFallback:X,ssml:V}};var m3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",u3="sre-v1",p3=256,G7=(Z)=>{if(Array.isArray(Z))return`array:[${Z.map(G7).join(",")}]`;if(Z&&typeof Z==="object")return`object:{${Object.entries(Z).sort(([Q],[J])=>Q.localeCompare(J)).map(([Q,J])=>`${JSON.stringify(Q)}:${G7(J)}`).join(",")}}`;if(Z===null)return"null:null";if(typeof Z>"u")return"undefined:";if(typeof Z==="function")return`function:${Z.name||"anonymous"}`;if(typeof Z==="symbol")return`symbol:${String(Z)}`;if(typeof Z==="bigint")return`bigint:${Z.toString()}`;if(typeof Z==="number")return Number.isFinite(Z)?`number:${Z}`:`number:${String(Z)}`;return`${typeof Z}:${JSON.stringify(Z)}`},O9=(Z,Q,J,Y)=>`${u3}\x00${m3(Z)}\x00${Q?"ssml":"plain"}\x00${G7(J??null)}\x00${Y}`,j7=(Z={})=>{let Q=Math.max(1,Z.maxEntries??p3),J=Z.resolve??((G,j)=>ZZ([G],j)),Y=new Map,X=(G,j)=>{Y.delete(G),Y.set(G,j);while(Y.size>Q){let B=Y.keys().next().value;if(B!==void 0)Y.delete(B)}};return async(G,j)=>{let B=V0(j.mathSpeech),V=j.produceSsml===!0,K=O9(j.language,V,B,G.mathml),U=Y.get(K);if(U)return Y.delete(K),Y.set(K,U),U;let $=await J(G,{...j,mathSpeech:B});if($.usedFallback)return $;if(V&&$.ssml&&Q>1)X(O9(j.language,!1,B,G.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(K,$),$}};var L9=(Z,Q)=>{let J=a0(Q.word);if(Z.id!==Q.chunkId)return{chunkId:Q.chunkId,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Q.providerOffsetSpace==="unknown"||Z.offsetSpace==="unsupported")return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let Y=e5({tokenization:Z.catalogAlignment?.speech??T0({speechText:Z.speechText}),position:Q.position,length:Q.length,boundaryWord:Q.word});if(!Y)return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:Y.start,chunkSpokenEnd:Y.start+Y.length,confidence:Y.confidence,reason:Z.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var v0=(Z)=>{if(Z.semanticTarget)return{activeTarget:Z.semanticTarget,regionTarget:Z.regionTarget,quality:Z.semanticTarget.quality==="exact-word"?"exact-word":Z.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:Z.confidence,reason:Z.reason};if(Z.expressionTarget)return{activeTarget:Z.expressionTarget,regionTarget:Z.regionTarget,quality:"expression",confidence:Z.confidence,reason:Z.reason};return{activeTarget:null,regionTarget:Z.regionTarget,quality:"region",confidence:Z.confidence,reason:Z.reason}};var P9=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),B7="mi,mn,mo,mtext",w9="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",R9=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),C9=(Z)=>{if(Z.type==="text-range")return Z.node.parentElement;return Z.element},lZ=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},N9=(Z)=>{if(!Z)return!1;if(lZ(Z))return!1;return!r0(Z)},b9=(Z)=>{let Q=Z.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},W7=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},E9=(Z,Q)=>{if(Z.length===0)return!1;if(Z.length!==Q.length)return!1;for(let J=0;J<Z.length;J+=1){let Y=P9.get(Z[J].localName.toLowerCase());if(!Y)return!1;if(Q[J].localName.toLowerCase()!==Y)return!1}return!0},g3=(Z,Q)=>{if(!Z)return null;if(!P9.has(Z.localName.toLowerCase()))return null;if(Q.querySelector(R9))return null;let J=W7(Z),Y=Q.querySelector("mjx-math");if(!J||!Y)return null;let X=Array.from(J.querySelectorAll(B7)),G=X.indexOf(Z);if(G<0)return null;let j=Array.from(Y.querySelectorAll(w9));if(!E9(X,j))return null;let B=j[G];if(!B||!b9(B))return null;return B},S9=(Z)=>{let Q=lZ(Z);if(Q){if(Q.querySelector(R9))return"expression";let X=W7(Z)??Z,G=Q.querySelector("mjx-math");if(!G)return"expression";let j=Array.from(X.querySelectorAll(B7)),B=Array.from(G.querySelectorAll(w9));if(!E9(j,B))return"expression";return B.some((V)=>b9(V))?"token":"expression"}let J=W7(Z)??Z;return Array.from(J.querySelectorAll(B7)).some((X)=>!r0(X))?"token":"expression"},V7=(Z)=>{let Q=C9(Z),J=lZ(Q);if(J){let Y=g3(Q,J);if(Y)return{type:"element",quality:"semantic-token",element:Y};return{type:"element",quality:"expression",element:J}}if(Z.type==="text-range"){if(!N9(Z.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Z.node,startOffset:Z.startOffset,endOffset:Z.endOffset}}if(!N9(Z.element))return null;return{type:"element",quality:Z.quality==="region-fallback"?"expression":"semantic-token",element:Z.element}},y9=V7,T9=()=>{let Z=new WeakMap;return(Q)=>{let J=C9(Q),Y=lZ(J);if(!J||!Y)return V7(Q);if(Z.has(J))return Z.get(J)??null;let X=V7(Q);return Z.set(J,X),X}};var x9=(Z,Q,J,Y=Z.mathAlignments,X=y9)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let G=null;for(let j of Y){let B=G9(j.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:J.word})||j9(j.alignment,{boundaryWord:J.word});if(!B)continue;let V=X(B);if(!V)continue;if(V.quality==="semantic-token")return V;G??=V}return G};var A0=(Z)=>Z.node.getRootNode?.()??Z.node,k9=(Z,Q)=>{try{let J=document.createRange();return J.setStart(Z.node,Z.offset),J.setEnd(Q.node,Q.offset+1),J}catch{return null}},K7=(Z,Q,J)=>{if(!Z||typeof document>"u")return null;if(J<=Q)return null;let Y=Z.get(Q),X=Z.get(Math.max(Q,J-1));if(!Y)return null;if(!X)X=Y;if(A0(X)!==A0(Y)){let G=A0(Y);X=Y;for(let j=Q+1;j<J;j++){let B=Z.get(j);if(B&&A0(B)===G)X=B}}return k9(Y,X)},D0=(Z,Q,J)=>{if(!Z||typeof document>"u"||J<=Q)return[];let Y=Z.get(Q);if(!Y)return[];let X=A0(Y),G=!1;for(let U=Q+1;U<J&&!G;U++){let $=Z.get(U);if($&&A0($)!==X)G=!0}if(!G){let U=K7(Z,Q,J);return U?[U]:[]}let j=[],B=null,V=null,K=()=>{if(B&&V){let U=k9(B,V);if(U)j.push(U)}B=null,V=null};for(let U=Q;U<J;U++){let $=Z.get(U);if(!$)continue;if(B&&A0(B)!==A0($))K();if(!B)B=$;V=$}return K(),j};var f9=(Z,Q)=>{if(!Z.catalogAlignment||Q.chunkSpokenStart===null)return null;let J=t8(Z.catalogAlignment,Q.chunkSpokenStart);if(!J)return null;let Y=D0(Z.visibleMap,J.start,J.end);if(Y.length===0)return null;return{type:"range",quality:Z.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:Y[0],ranges:Y.length>1?Y:void 0}};var c3=(Z)=>{let Q=D0(Z.visibleMap,0,Z.visibleText.length);return Q.length>1?Q:void 0},d3=(Z)=>Z.regionRange?{type:"range",quality:"region",range:Z.regionRange,ranges:c3(Z)}:Z.regionElement?{type:"element",quality:"region",element:Z.regionElement}:null,I9=(Z,Q=Z.chunk.mathAlignments)=>{if(Q.length!==1)return null;let J=Q[0]?.alignment.result.fallbackTarget;return J?Z.renderedMathTargetResolver(J):null},i3=(Z,Q)=>{if(!Z)return Q.mathAlignments;return Q.mathAlignments.filter(({element:J})=>{try{if(Z.type==="range")return(Z.ranges??[Z.range]).some((Y)=>G0(Y,J));if(Z.type==="element")return J0(Z.element,J);return J0(i(Z.node),J)}catch{return!1}})},v9=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),q7=(Z)=>Z.length===1?Z[0].element:null,l3=(Z,Q)=>Q.length>0&&Q.every(({element:J})=>Z.mathCapabilityByElement.get(J)==="token"),h9=3,s3=(Z,Q,J)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:Y,endContainer:X}=Q.range;if(Y===X&&Y.nodeType===h9)return!1;return J.some(({element:j})=>Z.mathCapabilityByElement.get(j)==="token"&&j.contains(Y)&&j.contains(X))},m9=(Z)=>Z?.type==="range"&&r0(Z.range.startContainer),n3=(Z,Q)=>{if(!m9(Q))return null;let{startContainer:J,endContainer:Y,startOffset:X,endOffset:G}=Q.range;if(J!==Y||J.nodeType!==h9)return null;return Z.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:G})},r3=(Z,Q)=>({chunk:Z,regionTarget:d3(Z),renderedMathTargetResolver:T9(),mathCapabilityByElement:new Map(Z.mathAlignments.map(({element:J})=>[J,Q?S9(J):"expression"])),heldTokenByElement:new Map}),u9=(Z)=>{let Q=Z.mathTokenHighlighting!==!1,J=new Map(Z.chunks.map((Y)=>[Y.id,r3(Y,Q)]));return{chunks:Z.chunks,resolveInitial(Y){let X=J.get(Y);if(!X)return v9();let G=q7(X.chunk.mathAlignments),j=G?X.mathCapabilityByElement.get(G):null;if(j==="expression")return v0({semanticTarget:null,expressionTarget:I9(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return v0({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:j==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(Y){let X=J.get(Y.chunkId);if(!X)return v9();let{chunk:G}=X,j=L9(G,Y),B=f9(G,j),V=i3(B,G),K=!B||V.length>0?x9(G,j,Y,V,X.renderedMathTargetResolver):null,U=K?.quality==="semantic-token"?K:n3(X,B)??K,$=Q&&U&&U.quality!=="expression"?U:null,z=U&&U.quality==="expression"?U:null;if($){let H=q7(V);if(H)X.heldTokenByElement.set(H,$);return v0({semanticTarget:$,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}if(B&&!m9(B)&&(Q?!s3(X,B,V):V.length===0))return v0({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason});if(l3(X,V)){let H=q7(V),O=H?X.heldTokenByElement.get(H)??null:null;return v0({semanticTarget:O,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:O?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return v0({semanticTarget:null,expressionTarget:z??I9(X,V),regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}}};var a3=(Z)=>{return Z.alignment?.speech.boundaryOffsetSpace??Z.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},o3=(Z)=>{if(Z.mathAlignments?.length)return Z.mathAlignments;if(Z.mathAlignment&&Z.sourceElement)return[{element:Z.sourceElement,alignment:Z.mathAlignment}];return[]},p9=(Z)=>{return(Z.chunks&&Z.chunks.length?Z.chunks:[{speechText:Z.speechText||"",visibleText:Z.visibleText||Z.speechText||"",sourceElement:Z.sourceElement||Z.contentRoot,regionElement:Z.regionElement||Z.sourceElement||Z.contentRoot,regionRange:Z.regionRange,visibleMap:Z.visibleMap}]).map((J,Y)=>({id:`tts-chunk-${Y}`,speechText:J.speechText,visibleText:J.visibleText,sourceElement:J.sourceElement,contentRoot:Z.contentRoot,regionElement:J.regionElement??J.sourceElement,regionRange:J.regionRange,visibleMap:J.visibleMap,catalogAlignment:J.alignment,mathAlignments:o3(J),offsetSpace:a3(J)}))};var t3=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),sZ=(Z,Q)=>{let J=IZ(Z,t3);if(J&&J0(Q,J))return J;return Z};var h0=(Z,Q)=>{let J=Q?.useSentenceSegmenter===!1?void 0:globalThis.Intl?.Segmenter;if(typeof J==="function")try{let B=new J(Q?.locale,{granularity:"sentence"}),V=Array.from(B.segment(Z)).map((K)=>({text:K.segment,offset:K.index})).filter((K)=>K.text.trim().length>0);if(V.length>0)return V}catch{}let Y=/[^.!?]+(?:[.!?]+|$)/g,X=Z.match(Y)||[Z],G=[],j=0;for(let B of X){let V=Z.indexOf(B,j);if(V===-1)continue;G.push({text:B,offset:V}),j=V+B.length}return G.length>0?G:[{text:Z,offset:0}]},U7=(Z,Q,J)=>{let Y=Math.max(1,Math.floor(Q)),X=[],G=-1,j=-1,B=()=>{if(G>=0)X.push({text:Z.slice(G,j),offset:G});G=-1},V=(K,U)=>{if(G>=0&&U-G<=Y){j=U;return}B();let $=K;while(U-$>Y){let H=Z.slice($,$+Y+1).search(/\s\S*$/),O=H>0?$+H:$+Y;X.push({text:Z.slice($,O).trimEnd(),offset:$}),$=O;while($<U&&/\s/.test(Z[$]))$++}if($<U)G=$,j=U};for(let K of h0(Z,J)){let U=K.text.search(/\S/);if(U===-1)continue;let $=K.offset+U;V($,K.offset+K.text.trimEnd().length)}return B(),X};var e3=(Z,Q)=>ZZ([Z],Q),Z2=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",Q2=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),J2=new Set(["heading","listitem","option","radio"]),Y2=(Z)=>{if(Z.type!=="text"||!Z.sourceElement)return!1;let Q=Z.sourceElement.tagName.toUpperCase(),J=(Z.sourceElement.getAttribute("role")||"").toLowerCase();return Q2.has(Q)||J2.has(J)},g9=async(Z)=>{let Q=Z.resolveMathSpeech??e3,J=X7(Z.mathSpeech),{visibleText:Y}=Z,X=[],G=0,j=(V)=>{let K=T(V),U=Y.indexOf(K,G),$=U>=0?U:G,z=$+K.length;return G=z,{start:$,end:z}},B=[];for(let V=0;V<Z.chunks.length;V++){let K=Z.chunks[V];if(K.type==="text"){let O=Y2(K)?[{text:K.text,offset:0}]:h0(K.text,{locale:Z.language});for(let N of O){let D=T(N.text);if(!D)continue;let P=j(D);X.push({sourceChunkIndex:V,segment:{kind:"prose",spokenText:D,visibleText:D,visibleSpan:P}}),B.push(D)}continue}let U=j(K.fallbackText),$=await Q(K,{language:Z.language,produceSsml:Z.produceSsml,mathSpeech:Z.mathSpeech,loadSre:J}),z=!$.speechText,H=$.speechText||K.fallbackText;X.push({sourceChunkIndex:V,segment:{kind:"math",spokenText:H,mathml:K.mathml,fallbackText:K.fallbackText,visibleSpan:U,usedFallback:z,ssml:$.ssml}}),B.push(H)}return{segments:X,locale:Z2(Z.language),visibleText:Y,plainSpeechText:T(B.join(" "))}};var X2=(Z,Q,J)=>{let Y=new Map;for(let X=Q;X<J;X++){let G=Z.get(X);if(G)Y.set(X-Q,G)}return Y},$7=async(Z)=>{let Q=H0(Z.contentRoot,Z.textProcessingOptions,Z.range),J=await g9({chunks:Q.chunks,visibleText:Q.visibleText,language:Z.language,mathSpeech:Z.mathSpeech,produceSsml:Z.produceSsml,resolveMathSpeech:Z.resolveMathSpeech});return{plan:{items:J.segments.map(({segment:X,sourceChunkIndex:G})=>{let j=Q.chunks[G];if(X.kind==="prose"){let V=j?.type==="text"?j.sourceElement??Z.contentRoot:Z.contentRoot;return{segment:X,anchor:{sourceElement:V,regionElement:sZ(V,Z.contentRoot),visibleMap:X2(Q.map,X.visibleSpan.start,X.visibleSpan.end)}}}let B=j?.type==="math"?j.sourceElement??null:null;return{segment:X,anchor:{sourceElement:B,regionElement:B}}}),locale:J.locale,visibleText:J.visibleText,plainSpeechText:J.plainSpeechText},containsMathMarkup:Q.containsMathMarkup,visibleText:Q.visibleText}};var G2=(Z,Q)=>{let J=dZ({speechText:Z.spokenText,visibleText:Z.spokenText});return{speechText:Z.spokenText,visibleText:Z.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:K7(Q.visibleMap,0,Z.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Q.visibleMap}},c9=(Z,Q)=>{let J=Q.sourceElement;return{speechText:Z.spokenText,visibleText:Z.fallbackText,sourceElement:J,regionElement:Q.regionElement,speechMatchesVisibleText:Z.spokenText===Z.fallbackText,mathAlignment:J?t0({mathElement:J,speechText:Z.spokenText}):void 0}},j2=(Z,Q,J)=>{let Y=Q.sourceElement;return{speechText:J,visibleText:Z.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:Y?t0({mathElement:Y,speechText:J}):void 0,plainFallback:c9(Z,Q)}},F7=(Z,Q={})=>Z.items.map(({segment:J,anchor:Y})=>{if(J.kind==="prose")return G2(J,Y);if(Q.format==="ssml"&&J.ssml)return j2(J,Y,J.ssml);return c9(J,Y)});function nZ(Z){let Q=Z instanceof Error?Z:Error(String(Z));return Q.code="tts-start-failed",Q}var t=V2("tts-service",a9),R;(function(Z){Z.IDLE="idle",Z.LOADING="loading",Z.PLAYING="playing",Z.PAUSED="paused",Z.ERROR="error"})(R||(R={}));var K2={baseMs:280,units:{minor:0.65,section:1,major:1.35},minMs:120,maxMs:900},d9=0.25,i9=4,m0=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,l9=(Z,Q={})=>{if(!Z)return Q;return{locale:"locale"in Z?m0(Z.locale):Q.locale,textNormalization:Z.textNormalization&&"locale"in Z.textNormalization?m0(Z.textNormalization.locale):Q.textNormalization,segmenter:Z.segmenter&&"locale"in Z.segmenter?m0(Z.segmenter.locale):Q.segmenter}},s9=(Z)=>("commonAncestorContainer"in Z),o9=(Z,Q)=>Z===Q||Z.startContainer===Q.startContainer&&Z.startOffset===Q.startOffset&&Z.endContainer===Q.endContainer&&Z.endOffset===Q.endOffset,q2=(Z,Q)=>{if(Z===Q)return!0;if(!Z||!Q||Z.type!==Q.type||Z.quality!==Q.quality)return!1;if(Z.type==="range"&&Q.type==="range")return o9(Z.range,Q.range);if(Z.type==="element"&&Q.type==="element")return Z.element===Q.element;if(Z.type==="text-range"&&Q.type==="text-range")return Z.node===Q.node&&Z.startOffset===Q.startOffset&&Z.endOffset===Q.endOffset;return!1},U2=(Z,Q)=>{for(let J=0;J<Math.min(Z.length,Q.length);J++)if(Z[J]!==Q[J])return{index:J,spokenChar:Z[J],normalizedChar:Q[J],spokenContext:Z.substring(Math.max(0,J-20),J+20),normalizedContext:Q.substring(Math.max(0,J-20),J+20)};return null},n9=(Z)=>{let Q=Number(Z.getAttribute("data-tts-break-ms"));return Number.isFinite(Q)&&Q>0?Q:null},$2=(Z)=>{if(typeof window>"u")return!1;let Q=window.getComputedStyle(Z).display;return Q==="block"||Q==="list-item"||Q.startsWith("table")||Q==="flex"||Q==="grid"},r9=(Z,Q,J)=>{let Y=Z.substring(Q,J);return{start:Q+(Y.match(/^\s*/)?.[0].length||0),end:J-(Y.match(/\s*$/)?.[0].length||0)}};class z7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.IDLE;resumeState=R.PLAYING;ttsConfig={};hostLocales={};readLocale=hZ;disposed=!1;readinessGate=null;mathSpeechSource=null;currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Set;lastError=null;speakRunId=0;restartRunId=null;runOwner=null;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;pauseHold=null;structuralPause=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";wordlessPartHighlight=null;lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=j7();clearPlaybackStartBarrier(Z=this.playbackStartBarrierCleanup){if(Z?.(),this.playbackStartBarrierCleanup===Z)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Z,Q){if(this.playbackStartDeferredRunId!==Z||Z!==this.speakRunId)return;if(this.state===R.PAUSED)this.activeRecordedAudio?.element.pause(),this.provider?.pause();this.markPlaying();let J=this.pendingPlaybackStartHighlights.splice(0);for(let Y of J)Y();if(Q?.wordBoundaries===!1)this.highlightWordlessPlayback()}highlightWordlessPlayback(){let Z=this.wordlessPartHighlight;if(!Z||this.activeHighlightMode!=="word")return;this.highlightCoordinator?.clearTTSWord(),Z()}installPlaybackStartBarrier(Z,Q=!1){this.clearPlaybackStartBarrier();let J=this.provider,Y=J&&"onPlaybackStart"in J?J:null;if(!Y&&!Q)return null;let X=Y?.onPlaybackStart,G=(B)=>{try{this.notifyPlaybackStarted(Z,B)}finally{X?.(B)}};if(Y)Y.onPlaybackStart=G;this.playbackStartDeferredRunId=Z;let j=()=>{if(Y?.onPlaybackStart===G)Y.onPlaybackStart=X;if(this.playbackStartDeferredRunId===Z)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=j,j}runWhenPlaybackStarts(Z,Q){if(this.playbackStartDeferredRunId===Z){this.pendingPlaybackStartHighlights.push(Q);return}Q()}async waitWhilePaused(Z){while(this.state===R.PAUSED&&Z===this.speakRunId){if(!this.pauseHold){let Q=()=>{},J=new Promise((Y)=>{Q=Y});this.pauseHold={promise:J,release:Q}}await this.pauseHold.promise}}releasePauseHold(){let Z=this.pauseHold;this.pauseHold=null,Z?.release()}waitStructuralPause(Z){return this.cancelStructuralPause(),new Promise((Q)=>{let J=()=>{if(this.structuralPause?.finish===J)clearTimeout(this.structuralPause.timer),this.structuralPause=null;Q()};this.structuralPause={timer:setTimeout(J,Z),finish:J}})}cancelStructuralPause(){this.structuralPause?.finish()}abandonRun(){this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.cancelStructuralPause(),this.releasePauseHold()}beginRun(Z){let Q=this.state===R.LOADING||this.state===R.PLAYING||this.state===R.PAUSED,J=++this.speakRunId;if(this.runOwner=Z,this.abandonRun(),Q)this.provider?.stop();return this.setState(R.LOADING,!0),J}markPlaying(){if(this.state===R.PAUSED){this.resumeState=R.PLAYING;return}this.setState(R.PLAYING)}assertNotDisposed(){if(this.disposed)throw nZ(Error("TTS service disposed"))}async emitTelemetry(Z,Q){try{await this.telemetryReporter?.(Z,Q)}catch(J){console.warn("[TTSService] telemetry callback failed:",J)}}async initialize(Z,Q={}){if(this.disposed)throw Error("TTS service disposed");this.currentProvider=Z,this.ttsConfig={...Q},this.hostLocales=l9(Q.providerOptions);let J=this.providerOptions().__pieTelemetry;this.telemetryReporter=typeof J==="function"?J:null,this.provider=await Z.initialize(Q)}async updateSettings(Z){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q={...Z,...Z.providerOptions?{providerOptions:{...this.providerOptions(),...Z.providerOptions}}:{}};await this.provider.updateSettings(Q),this.ttsConfig={...this.ttsConfig,...Q},this.hostLocales=l9(Z.providerOptions,this.hostLocales)}setHighlightCoordinator(Z){this.highlightCoordinator=Z}setReadinessGate(Z){this.readinessGate=Z}setMathSpeechSource(Z){this.mathSpeechSource=Z}pendingReadiness(){if(this.provider||!this.readinessGate)return null;return this.readinessGate().catch((Z)=>{throw nZ(Z)})}setHighlightTargetResolverProvider(Z){return this.highlightTargetResolverProvider=Z,()=>{if(this.highlightTargetResolverProvider===Z)this.highlightTargetResolverProvider=null}}setCatalogResolver(Z){this.catalogResolver=Z}getHighlightResolverRuntime(){let Z=null;try{Z=this.highlightTargetResolverProvider?.()??null}catch{Z=null}let Q=Z?.context??{},J=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Q,scopeElement:Q.scopeElement??J},resolver:Z?.resolver??null}}getNodeElement(Z){if(!Z)return null;return Z.nodeType===Node.ELEMENT_NODE?Z:i(Z)}isElementWithinScope(Z,Q){if(!Q)return!0;return J0(Q,Z)}isRangeWithinScope(Z,Q){let J=this.getNodeElement(Z.startContainer),Y=this.getNodeElement(Z.endContainer);if(!J||!Y)return!1;return this.isElementWithinScope(J,Q)&&this.isElementWithinScope(Y,Q)}resolveWordHighlightRange(Z){let{context:Q,resolver:J}=this.getHighlightResolverRuntime(),Y=Q.scopeElement??this.currentContentElement;try{let X=J?.resolveWordRange?.(Z,Q);if(X&&this.isRangeWithinScope(X,Y))return{range:X,remapped:!o9(Z,X)}}catch{}return{range:Z,remapped:!1}}resolveSentenceHighlightTargets(Z){let{context:Q,resolver:J}=this.getHighlightResolverRuntime(),Y=Q.scopeElement??this.currentContentElement;try{let X=J?.resolveSentenceRanges?.(Z,Q);if(!X)return{ranges:Z,elements:[]};let G=[],j=[];for(let B of X){if(typeof Range<"u"&&B instanceof Range){if(!this.isRangeWithinScope(B,Y))return{ranges:Z,elements:[]};G.push(B);continue}if(typeof Element<"u"&&B instanceof Element){if(!this.isElementWithinScope(B,Y))return{ranges:Z,elements:[]};j.push(B);continue}return{ranges:Z,elements:[]}}return{ranges:G,elements:j}}catch{return{ranges:Z,elements:[]}}}createTextRange(Z,Q,J){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let Y=document.createRange();if(Y.setStart(Z,Q),Y.setEnd(Z,J),Y.startContainer!==Z||Y.endContainer!==Z)return null;return Y}catch{return null}}paintTTSWord(Z){if(!this.highlightCoordinator||Z.length===0)return;this.highlightCoordinator.highlightTTSWord(Z.map((Q)=>this.resolveWordHighlightRange(Q).range))}paintTTSSentenceRanges(Z){if(!this.highlightCoordinator)return;let{ranges:Q,elements:J}=this.resolveSentenceHighlightTargets(Z);if(J.length>0&&Q.length===0){this.highlightCoordinator.highlightTTSSentenceElements(J);return}let Y=[...Q];for(let X of J){let G=document.createRange();G.selectNodeContents(X),Y.push(G)}this.highlightCoordinator.highlightTTSSentence(Y)}providerOptions(){let Z=this.ttsConfig.providerOptions;return Z&&typeof Z==="object"?Z:{}}maxTextLength(){let Z=this.currentProvider?.getCapabilities?.().maxTextLength;return typeof Z==="number"&&Z>0?Z:void 0}async speakWithinLimit(Z,Q){let J=this.provider;if(!J)return;let Y=this.maxTextLength();if(!Y||Z.length<=Y){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;await J.speak(Z);return}if(gZ(Z))throw Error(`[tts] SSML of ${Z.length} characters exceeds the provider's limit of ${Y}`);let X=J.onWordBoundary;try{for(let G of U7(Z,Y,{locale:this.readLocale})){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;J.onWordBoundary=X?(j,B,V)=>X(j,B+G.offset,V):void 0,await J.speak(G.text)}}finally{if(this.provider===J&&Q===this.speakRunId)J.onWordBoundary=X}}segmentsWithinLimit(Z){let Q=this.maxTextLength();if(!Q)return Z;return Z.flatMap((J)=>{if(J.text.length<=Q)return[J];let Y=U7(J.text,Q,{locale:this.readLocale});return Y.map((X,G)=>({text:X.text,startOffset:J.startOffset+X.offset,pauseMsAfter:G===Y.length-1?J.pauseMsAfter:void 0}))})}getTextProcessingOptions(Z){let Q=this.providerOptions().textNormalization?.boundarySpacingMode;return{locale:Z,boundarySpacingMode:Q==="none"||Q==="alnum"||Q==="segmenterPreferred"?Q:void 0}}resolveReadLanguage(Z,Q){let J=i5(Z)??(Z.nodeType===1?p8(Z):void 0)??(Q?.trim()||void 0)??m0(this.providerOptions().lang_id);return{contentLanguage:J,locale:J??this.hostLocales.locale??this.hostLocales.textNormalization??hZ}}getMathSpeechOptions(){if(this.mathSpeechSource)return V0(this.mathSpeechSource());return V0(this.providerOptions().mathSpeech)}buildPositionMap(Z,Q,J){this.normalizedToDOM.clear();let{text:Y,map:X}=y0(Z,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!a9())return;t.debug("Text comparison:",{spokenLength:Q.length,normalizedDomLength:Y.length,match:Q===Y,spokenPreview:Q.substring(0,150),normalizedPreview:Y.substring(0,150),differAtIndex:Q===Y?null:U2(Q,Y)}),t.debug("Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Q.length,normalizedDomLength:Y.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Q.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([G,{node:j,offset:B}])=>({pos:G,offset:B,char:j.textContent?.[B],expected:Q[G]}))})}getStructuralPauseProfile(){let Z=this.providerOptions().structuralPauses||{},Q=Z.units||{},J=(X,G)=>{if(typeof X==="number"&&Number.isFinite(X))return X;if(typeof X==="string"&&X.trim()){let j=Number(X);return Number.isFinite(j)?j:G}return G},Y=K2;return{baseMs:J(Z.baseMs,Y.baseMs),units:{minor:J(Q.minor,Y.units.minor),section:J(Q.section,Y.units.section),major:J(Q.major,Y.units.major)},minMs:J(Z.minMs,Y.minMs),maxMs:J(Z.maxMs,Y.maxMs)}}resolvePauseMsFromUnits(Z){let Q=this.getStructuralPauseProfile(),J=Math.max(d9,Math.min(i9,Number(this.ttsConfig.rate||1))),Y=Q.baseMs*Math.max(0,Z)/J;return Math.max(Q.minMs,Math.min(Q.maxMs,Math.round(Y)))}resolveHighlightMode(){let Z=this.providerOptions().highlightMode;if(Z==="word"||Z==="sentence")return Z;let Q=this.currentProvider?.getCapabilities();if(Q?.defaultHighlightMode)return Q.defaultHighlightMode;return Q?.supportsWordBoundary?"word":"sentence"}hasExplicitBreakSemantics(Z){if(!Z.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(Z)}getBoundaryStrength(Z){if(n9(Z)!==null)return"major";let Q=Z.tagName.toUpperCase();if(Q.match(/^H[1-6]$/))return"major";let J=(Z.getAttribute("role")||"").toLowerCase();if(J==="heading")return"major";if(J==="listitem"||J==="row"||J==="option"||J==="radio"||Q==="LI")return"section";return"minor"}getBoundaryAnchor(Z,Q){let J=c(Z),Y=null;while(J&&J!==Q){if(mZ(J))return null;let G=n9(J);if(G!==null)return{anchor:J,units:G/this.getStructuralPauseProfile().baseMs};let j=(J.getAttribute("role")||"").toLowerCase(),B=J.tagName.toUpperCase();if(B.match(/^H[1-6]$/)||j==="heading"||j==="listitem"||B==="LI"){Y=J;break}if(!Y&&$2(J))Y=J;J=c(J)}if(!Y)return null;let X=this.getBoundaryStrength(Y);return{anchor:Y,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Z,Q,J,Y){let X=this.collectSpeechPlanBoundaries(Z,Y);if(J===0)return this.createSpeechPlanSegments(Q,X);let G=new Map;for(let[j,B]of X)G.set(j-J,B);return this.createSpeechPlanSegments(Q,G)}collectSpeechPlanBoundaries(Z,Q){let J=new Map,{map:Y}=y0(Z,this.getTextProcessingOptions(Q)),X=this.createNodeStartOffsets(Y),G=null;for(let j of b0(Z)){let B=c(j);if(B&&!mZ(B)&&!uZ(j)){let V=this.getBoundaryAnchor(j,Z),K=X.get(j);if(V&&K!==void 0&&V.anchor!==G&&K>0)J.set(K,Math.max(J.get(K)||0,V.units)),G=V.anchor}}return J}createNodeStartOffsets(Z){let Q=new Map;for(let[J,Y]of Z.entries())if(!Q.has(Y.node))Q.set(Y.node,J);return Q}createSpeechPlanSegments(Z,Q){let J=Array.from(Q.keys()).filter((V)=>V>0&&V<Z.length).sort((V,K)=>V-K),Y=[],X=0;for(let V of J){let{start:K,end:U}=r9(Z,X,V);if(U>K){let $=Z.substring(K,U);Y.push({text:$,startOffset:K,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(V)||0)})}X=V}let j=Z.substring(X).match(/^\s*/)?.[0].length||0,B=X+j;if(B<Z.length)Y.push({text:Z.substring(B).trimEnd(),startOffset:B,pauseMsAfter:0});return Y.filter((V)=>V.text.trim().length>0)}segmentSentences(Z){return h0(Z,{locale:this.readLocale})}createSeekSegmentsFromText(Z){return this.segmentSentences(Z).map((Q)=>{let J=Q.text.match(/^\s*/)?.[0].length||0;return{text:Q.text.trim(),startOffset:Q.offset+J,pauseMsAfter:0}}).filter((Q)=>Q.text.length>0)}splitSegmentsAtBoundaries(Z,Q,J){if(Z.length===0||Q.length===0)return Z;let Y=Array.from(new Set(Q)).filter((G)=>Number.isFinite(G)&&G>0).sort((G,j)=>G-j);if(Y.length===0)return Z;let X=[];for(let G of Z){let j=G.startOffset,B=G.startOffset+G.text.length,V=Y.filter((U)=>U>j&&U<B);if(V.length===0){X.push(G);continue}let K=j;for(let U of[...V,B]){let{start:$,end:z}=r9(J,K,U);if(z>$)X.push({text:J.substring($,z),startOffset:$,pauseMsAfter:0});K=U}}return X}createSentenceHighlightSegments(Z){let Q=this.createSeekSegmentsFromText(Z.contentToSpeak);if(!Z.shouldUsePlan||Z.playbackSegments.length===0)return Q;let J=Z.playbackSegments.map((Y)=>Y.startOffset).filter((Y)=>Y>0);return this.splitSegmentsAtBoundaries(Q,J,Z.contentToSpeak)}createSeekSegmentsFromSpeechChunks(Z){let Q=0;return Z.map((J)=>{let Y=J.plainFallback?.speechText||(this.hasExplicitBreakSemantics(J.speechText)?J.visibleText:J.speechText)||J.visibleText,X=T(Y)||J.visibleText||"",G={text:X,startOffset:Q,pauseMsAfter:0};return Q+=X.length+1,G})}getCurrentSeekSegmentIndex(){return Math.max(0,this.getSegmentIndexForOffset(this.seekSegments,this.currentBoundaryOffset))}async speakWithPlan(Z,Q,J){if(!this.provider||Z.length===0)return;let Y=J?.highlightMode==="sentence",X=this.provider;if(!Y&&typeof X.speakSegments==="function"){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==X)return;this.currentBoundaryOffset=0;let G=this.provider.onWordBoundary;this.provider.onWordBoundary=(j,B,V)=>{if(G?.(j,B,V),Number.isFinite(B))this.currentBoundaryOffset=B};try{await X.speakSegments(this.segmentsWithinLimit(Z))}finally{if(Q===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=G}return}this.configureWordBoundaryHighlighting({highlightMode:J?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let G of Z){if(await this.waitWhilePaused(Q),Q!==this.speakRunId)return;this.currentBoundaryOffset=G.startOffset;let j=()=>{this.highlightSentenceSegment(G.startOffset,G.text)};if(Y)this.runWhenPlaybackStarts(Q,j);this.wordlessPartHighlight=j;try{await this.speakWithinLimit(G.text,Q)}finally{if(this.wordlessPartHighlight===j)this.wordlessPartHighlight=null}let B=G.pauseMsAfter??0;if(B>0&&Q===this.speakRunId)await this.waitStructuralPause(B)}}highlightSentenceSegment(Z,Q){if(!this.highlightCoordinator||typeof document>"u")return;let J=Q.trimEnd().length;if(J<=0)return;let Y=Z+this.activeWordBoundaryOffset,X=this.normalizedToDOM.get(Y),G=this.normalizedToDOM.get(Y+J-1);if(!X||!G)return;let j=D0(this.normalizedToDOM,Y,Y+J);if(j.length===0)return;this.paintTTSSentenceRanges(j),this.activeSentenceStartOffset=Z}getSegmentIndexForOffset(Z,Q){if(Z.length===0)return-1;let J=-1;for(let Y=0;Y<Z.length;Y++)if(Z[Y].startOffset<=Q)J=Y;else break;return J}highlightSentenceForOffset(Z){let Q=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Q.length===0)return;let J=this.getSegmentIndexForOffset(Q,Z);if(J<0)return;let Y=Q[J];if(!Y)return;if(this.activeSentenceStartOffset===Y.startOffset)return;this.highlightSentenceSegment(Y.startOffset,Y.text)}async speak(Z,Q={}){this.assertNotDisposed();let J=this.pendingReadiness(),Y=Q.ownerId??null,X=J?this.beginRun(Y):null;if(J){try{await J}catch(V){if(X===this.speakRunId)this.setState(R.IDLE);throw V}if(this.assertNotDisposed(),X!==this.speakRunId)return}if(!this.provider){if(X!==null)this.setState(R.IDLE);throw nZ(Error("TTS service not initialized"))}let G=this.resolveReadLanguage(s9(Z)?Z.startContainer:Z,Q.language),j=s9(Z)?this.resolveRangeTarget(Z,Q,G):this.resolveElementTarget(Z,Q,G);if(!j){if(X!==null)this.setState(R.IDLE);return}let B=X??this.beginRun(Y);if(Q.rate!==void 0||Q.pitch!==void 0||Q.volume!==void 0){if(await this.applyRunSettings(Q),B!==this.speakRunId)return}await this.speakContent(j.text,j.options,B)}async applyRunSettings(Z){await this.playbackRateWriteQueue;let Q={};if(Z.rate!==void 0){let J=this.normalizePlaybackRate(Z.rate),Y=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(J!==Y)Q.rate=J}if(Z.pitch!==void 0&&Z.pitch!==this.ttsConfig.pitch)Q.pitch=Z.pitch;if(Z.volume!==void 0&&Z.volume!==this.ttsConfig.volume)Q.volume=Z.volume;if(Object.keys(Q).length>0)await this.updateSettings(Q)}isSuppressedTarget(Z){if(!uZ(Z))return!1;return console.warn("[tts] the content to read lies inside content marked not-to-be-spoken; nothing was spoken."),!0}resolveElementTarget(Z,Q,J){if(this.isSuppressedTarget(Z))return null;let Y={catalogId:Q.catalogId,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:Z},X=H0(Z,this.getTextProcessingOptions(J.locale)).visibleText.trim();if(!X&&!this.holdsSpokenCard(Z,Y))return console.warn("[tts] the content to read holds no speakable text; nothing was spoken."),null;return{text:X,options:Y}}holdsSpokenCard(Z,Q){if(!this.catalogResolver)return!1;if(Q.catalogId){if(this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language,useFallback:!0,context:Q.catalogContext,form:"content"})?.content!==void 0)return!0}return this.collectCatalogSpeechChunks(Z,Q).some((J)=>J.sourceElement)}resolveRangeTarget(Z,Q,J){if(this.isSuppressedTarget(Z.commonAncestorContainer))return null;let Y=Z.commonAncestorContainer,X=Q.contentRoot||(Y.nodeType===Node.ELEMENT_NODE?Y:i(Y));if(!X)return null;let G=l5(Z,X),j=G.text.trim();if(!j){if(G.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return null}let B=this.selectMappedRangeText(Z,X,J.locale),V=j,K=B?.offset??0;if(B)V=B.text;else{let U=document.createRange();U.selectNodeContents(X),U.setEnd(Z.startContainer,Z.startOffset);let $=l5(U,X).text,z=T($);K=z.length+(/\s$/.test($)&&z?1:0)}return t.debug("selection offset calculation:",{selectedText:V,mapped:!!B,offset:K,rootTag:X.tagName}),{text:V,options:{catalogId:Q.catalogId&&DZ(Z,X,X)?Q.catalogId:void 0,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:X,contentRange:Z,wordBoundaryOffset:K}}}async speakContent(Z,Q,J){let Y=null;try{if(await this.applyLanguageSettings(Q),J!==this.speakRunId)return;let X=await this.resolveSpeechContent(Z,Q);if(J!==this.speakRunId)return;let{contentToSpeak:G,speechText:j,highlightText:B,normalizedText:V,usedCatalogSpoken:K,speechSource:U,speechMatchesVisibleText:$,speechChunks:z}=X;this.logResolvedSpeechContent({contentToSpeak:G,speechSource:U,catalogId:Q.catalogId}),this.initializeSpeakTracking(B,Q);let H=$?this.resolveHighlightMode():"sentence";this.activeHighlightMode=H;let O=Q.wordBoundaryOffset||0;this.activeWordBoundaryOffset=O;let N=this.hasExplicitBreakSemantics(G),D=!!this.currentContentElement&&!K&&!N&&$;if(this.playbackChunks=z?.length?z:[],this.playbackChunks.length)this.seekSegments=this.createSeekSegmentsFromSpeechChunks(this.playbackChunks);else if(N||!$)this.seekSegments=[];else if(D&&this.currentContentElement)this.seekSegments=this.createSpeechPlan(this.currentContentElement,V,O,Q.language);else this.seekSegments=this.createSeekSegmentsFromText(B);if(this.sentenceHighlightSegments=N?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:D,playbackSegments:this.seekSegments}),Y=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Q,highlightMode:H,shouldUsePlan:D,runId:J}),$)this.configureWordBoundaryHighlighting({highlightMode:H,wordBoundaryOffset:O});else this.clearWordBoundaryHighlighting();if(!Y)this.markPlaying();if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:D,runId:J,highlightMode:H,contentToSpeak:j,speechChunks:z}),J!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(X){if(J!==this.speakRunId)return;throw console.error("TTS error:",X),this.lastError=X instanceof Error?X.message:String(X),this.setState(R.ERROR),this.clearHighlightsAndTracking(),X}finally{this.clearPlaybackStartBarrier(Y)}}async applyLanguageSettings(Z){if(!this.provider)return;this.readLocale=Z.language;let Q=Z.contentLanguage,J=this.providerOptions(),Y={locale:Q??this.hostLocales.locale,textNormalization:Q??this.hostLocales.textNormalization,segmenter:Q??this.hostLocales.segmenter};if(J.contentLanguage===Q&&m0(J.locale)===Y.locale&&m0(J.textNormalization?.locale)===Y.textNormalization&&m0(J.segmenter?.locale)===Y.segmenter)return;let X={...J,locale:Y.locale,textNormalization:{...J.textNormalization,locale:Y.textNormalization},segmenter:{...J.segmenter,locale:Y.segmenter},contentLanguage:Q};this.ttsConfig={...this.ttsConfig,providerOptions:X},await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(Z,Q){let J=T(Z);if(Q.catalogId&&this.catalogResolver){let G=this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language,useFallback:!0,context:Q.catalogContext,form:"content"}),j=G?.content;if(G&&j!==void 0){let B=H0(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||J,V=T(j);return t.debug(`Using catalog content for "${Q.catalogId}" (${G.language})`),{contentToSpeak:j,speechText:j,visibleText:B,highlightText:B,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:V===B}}t.debug(`No catalog found for "${Q.catalogId}", falling back to generated TTS`)}let Y=this.resolveCatalogComposedSpeechContent(Q.contentElement,J,Q);if(Y)return Y;return{...await this.resolveGeneratedSpeechContent(Q.contentElement,J,Q.language,Q.contentRange),usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(Z,Q,J){if(!this.catalogResolver)return null;let Y=this.collectCatalogSpeechChunks(Z,J);if(!Y.some((j)=>j.sourceElement))return null;let X=T(Y.map((j)=>j.speechText).join(" ")),G=J.contentRange?Q:H0(Z,this.getTextProcessingOptions(J.language)).visibleText||Q;return{contentToSpeak:X,speechText:X,visibleText:G,highlightText:G,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:G,containsMathMarkup:!1,speechMatchesVisibleText:Y.every((j)=>j.speechMatchesVisibleText),speechChunks:Y}}collectCatalogSpeechChunks(Z,Q){let J=this.catalogResolver;if(!J)return[];let Y=[],X="",G=()=>{let $=T(X);if(X="",!$)return;Y.push({speechText:$,visibleText:$,sourceElement:null,speechMatchesVisibleText:!0})},j=Q.contentRange,B=($)=>{let z=$.getAttribute("data-catalog-idref");if(!z)return null;if(j&&!DZ(j,$,Z))return null;let H={type:"spoken",language:d5($,Z)||Q.language,useFallback:!0,context:Q.catalogContext},O=J.getAlternative(z,{...H,form:"payload"}),N=O?.payload?m8({payload:O.payload})??void 0:void 0,P=J.getAlternative(z,{...H,form:"content"})?.content;if(N===void 0&&P===void 0)return null;return{script:P,audio:N}},V=($,z)=>{let H=K($);if(H.length!==1)return null;let O=H[0],N=H0(O,this.getTextProcessingOptions(Q.language)).visibleText||T(O.textContent||""),D=(P)=>T(P).replace(/\s+/g,"");return D(N)===D(z)?O:null},K=($)=>{let z=y8($,"math");if($.localName?.toLowerCase()==="math")return[$,...z];return z},U=($)=>{if(z0($,Z))return;if($.nodeType===Node.TEXT_NODE){if(!j)X+=` ${$.textContent||""}`;else if(G0(j,$))X+=` ${s5($,j)}`;return}if($.nodeType!==Node.ELEMENT_NODE)return;let z=$,H=B(z);if(H){G();let O=H0(z,this.getTextProcessingOptions(Q.language)),N=O.visibleText||T(S8(z)),D=sZ(z,Z),P=null;if(H.script!==void 0){let M=H.script,C=dZ({speechText:M,visibleText:N}),E=V(z,N),v=E?t0({mathElement:E,speechText:M}):void 0,S=v?void 0:K(z).map((p)=>({element:p,alignment:t0({mathElement:p,speechText:M})}));P={speechText:M,visibleText:N,sourceElement:z,regionElement:D,speechMatchesVisibleText:T(M)===N,playbackMode:C.playbackMode,alignment:C,mathAlignment:v,mathAlignments:S,visibleMap:O.map}}if(H.audio){Y.push(P?{...P,audio:H.audio,plainFallback:P}:{speechText:N,visibleText:N,sourceElement:z,regionElement:D,speechMatchesVisibleText:!1,visibleMap:O.map,audio:H.audio});return}if(P)Y.push(P);return}for(let O of F0(z))U(O)};return U(Z),G(),Y}resolveGeneratedPlaybackFormat(){let Z=this.currentProvider;if(!Z)return"plain";return Z.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(Z,Q,J,Y){let X=this.resolveGeneratedPlaybackFormat(),{plan:G,containsMathMarkup:j,visibleText:B}=await $7({contentRoot:Z,range:Y,language:J,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(J),produceSsml:X==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver});if(!j){let $=Y?Q:B||Q;return{contentToSpeak:$,speechText:$,visibleText:$,highlightText:$,normalizedText:$,containsMathMarkup:!1,speechMatchesVisibleText:!0}}let V=B||Q,K=F7(G,{format:X}),U=G.plainSpeechText;return{contentToSpeak:U,speechText:U,visibleText:V,highlightText:V,normalizedText:V,containsMathMarkup:!0,speechMatchesVisibleText:U===V,speechChunks:K}}logResolvedSpeechContent(Z){let Q=Z.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);t.debug("Speak resolved content",{source:Z.speechSource,catalogId:Z.catalogId||null,length:Z.contentToSpeak.length,preview:Q})}initializeSpeakTracking(Z,Q){this.currentText=Z,this.currentContentElement=Q.contentElement,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(Z){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,Z.contentToSpeak,Z.options.language),Z.highlightMode==="sentence"&&Z.shouldUsePlan)return;let Q=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(Z.runId,()=>{if(Q)this.highlightSentenceSegment(Q.startOffset,Q.text),t.debug("Applied initial sentence highlighting");else try{let J=document.createRange();J.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([J])}catch{}})}configureWordBoundaryHighlighting(Z){if(!this.provider)return;if(Z.highlightMode==="sentence"){this.provider.onWordBoundary=void 0;return}if(!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Q,J,Y)=>{let X=Y||Q.length,G=J+this.currentBoundaryOffset,j=G+Z.wordBoundaryOffset;this.highlightSentenceForOffset(G);let B=D0(this.normalizedToDOM,j,j+X);if(B.length===0){t.debug(`no text at position ${j}, length ${X}, to highlight`);return}t.debug(`Highlighting "${B.join("")}" (word: "${Q}") at position ${j}`),this.paintTTSWord(B)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(Z){let Q=Z.regionElement||Z.sourceElement;if(!Q&&!Z.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,Z.regionRange){let Y=D0(Z.visibleMap,0,Z.visibleText.length);this.highlightCoordinator.clearTTSWord(),this.paintTTSSentenceRanges(Y.length>1?Y:[Z.regionRange]);return}if(!Q)return;let J=document.createRange();J.selectNodeContents(Q),this.highlightCoordinator.clearTTSWord(),this.paintTTSSentenceRanges([J])}catch{}}highlightRenderableRegionTarget(Z){if(!this.highlightCoordinator||!Z||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&q2(this.lastRenderedRegionTarget,Z))return;try{let Q=document.createRange();if(Z.type==="element")Q.selectNodeContents(Z.element);else if(Z.type==="range"){this.paintTTSSentenceRanges(Z.ranges??[Z.range]),this.lastRenderedRegionTarget=Z;return}else Q.setStart(Z.node,Z.startOffset),Q.setEnd(Z.node,Z.endOffset);this.paintTTSSentenceRanges([Q]),this.lastRenderedRegionTarget=Z}catch{}}highlightRenderableActiveTarget(Z){if(!this.highlightCoordinator||typeof document>"u")return;if(!Z){this.highlightCoordinator.clearTTSWord();return}if(Z.type==="text-range"){let X=this.createTextRange(Z.node,Z.startOffset,Z.endOffset);if(X)this.paintTTSWord([X]);return}if(Z.type==="range"){this.paintTTSWord(Z.ranges??[Z.range]);return}let Q=document.createRange();Q.selectNodeContents(Z.element);let J=this.resolveWordHighlightRange(Q);if(J.remapped){this.highlightCoordinator.highlightTTSWord([J.range]);return}let Y=Z.element.childNodes.length===1?Z.element.firstChild:null;if(Z.quality==="semantic-token"&&Y?.nodeType===Node.TEXT_NODE){let X=document.createRange();X.selectNodeContents(Y),this.highlightCoordinator.highlightTTSWord([X]);return}this.highlightCoordinator.highlightTTSWordElement(Z.element)}renderHighlightDecision(Z){this.highlightRenderableRegionTarget(Z.regionTarget),this.highlightRenderableActiveTarget(Z.activeTarget)}async speakCatalogChunk(Z,Q){try{await this.speakCatalogChunkOnce(Z,Q)}catch(J){if(Z.plainFallback&&Q===this.speakRunId){if(t.debug("SSML chunk speak failed; retrying plain text",{message:J instanceof Error?J.message:String(J)}),this.playbackStartDeferredRunId===Q&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.markPlaying();await this.speakCatalogChunkOnce(Z.plainFallback,Q);return}throw J}}async playRecordedAudio(Z,Q){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let J=Z.sources[0],Y=document.createElement("audio");Y.preload="auto",Y.src=B2(J.src,Z.fragment),Y.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,G)=>{let j,B=!1,V=!1,K=()=>{if(V||B)return;B=!0,Q?.()},U=()=>{if(Y.removeEventListener("ended",$),Y.removeEventListener("error",z),Y.removeEventListener("playing",K),j?.(),this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null},$=()=>{if(V)return;V=!0,U(),X()},z=()=>{if(V)return;V=!0,U(),G(Error(`[tts] recorded audio failed to play: ${J.src}`))},H=()=>{Promise.resolve(Y.play()).then(K).catch((O)=>{if(O?.name==="AbortError"&&this.state===R.PAUSED)return;z()})};this.activeRecordedAudio={element:Y,cancel:()=>{if(V)return;V=!0,U(),Y.pause(),X()},play:H},Y.addEventListener("ended",$),Y.addEventListener("error",z),Y.addEventListener("playing",K),j=W2(Y,Z.fragment,$),H()}).finally(()=>{if(this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null;Y.pause(),Y.removeAttribute("src")})}cancelRecordedAudio(){let Z=this.activeRecordedAudio;if(!Z)return;this.activeRecordedAudio=null,Z.cancel()}async speakCatalogChunkOnce(Z,Q){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,Z.audio){this.runWhenPlaybackStarts(Q,()=>{this.highlightCatalogRegion(Z)}),await this.playRecordedAudio(Z.audio,()=>{this.notifyPlaybackStarted(Q)});return}let J=Z.regionElement||Z.sourceElement||this.currentContentElement,Y=J?p9({contentRoot:J,chunks:[Z]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,G=Y?u9({chunks:[Y],mathTokenHighlighting:X}):null,j=!Y||Y.offsetSpace==="unsupported"?"unknown":Y.offsetSpace;if(this.runWhenPlaybackStarts(Q,()=>{if(G&&Y&&Z.mathAlignment)this.renderHighlightDecision(G.resolveInitial(Y.id));else this.highlightCatalogRegion(Z)}),!(this.resolveHighlightMode()==="word"&&Z.sourceElement&&(Z.mathAlignment&&Z.mathAlignment.speech.tokens.length>0||Z.mathAlignments&&Z.mathAlignments.length>0||Z.alignment&&Z.visibleMap&&(Z.playbackMode==="exact-word"||Z.playbackMode==="anchor-span")))){let $=this.provider,z=$.onWordBoundary;$.onWordBoundary=void 0;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===$&&Q===this.speakRunId&&$.onWordBoundary===void 0)$.onWordBoundary=z}return}let V=this.provider,K=V.onWordBoundary,U=($,z,H)=>{if(Q!==this.speakRunId||!G||!Y)return;this.renderHighlightDecision(G.resolveBoundary({chunkId:Y.id,word:$,position:z,length:H,providerOffsetSpace:j}))};V.onWordBoundary=U;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===V&&Q===this.speakRunId&&V.onWordBoundary===U)V.onWordBoundary=K}}async executeSpeakPlayback(Z){if(Z.speechChunks?.length&&this.provider){for(let Q=0;Q<Z.speechChunks.length;Q++){if(await this.waitWhilePaused(Z.runId),Z.runId!==this.speakRunId)return;let J=this.seekSegments[Q];if(J)this.currentBoundaryOffset=J.startOffset;let Y=Z.speechChunks[Q];await this.speakCatalogChunk(Y,Z.runId)}return}if(Z.shouldUsePlan&&this.currentContentElement&&this.seekSegments.length>0){await this.speakWithPlan(this.seekSegments,Z.runId,{highlightMode:Z.highlightMode});return}await this.speakWithinLimit(Z.contentToSpeak,Z.runId)}clearHighlightsAndTracking(){if(this.clearWordBoundaryHighlighting(),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,this.wordlessPartHighlight=null}selectMappedRangeText(Z,Q,J){if(typeof Z.comparePoint!=="function")return null;let{text:Y,map:X}=y0(Q,this.getTextProcessingOptions(J)),G=-1,j=-1;for(let[U,{node:$,offset:z}]of X){if(U>=Y.length)continue;if(!FZ(Z,$,z))continue;if(G===-1||U<G)G=U;if(U>j)j=U}if(G===-1)return null;let B=Y.slice(G,j+1),V=B.length-B.trimStart().length,K=B.trim();return K?{text:K,offset:G+V}:null}pause(){if(this.state!==R.PLAYING&&this.state!==R.LOADING)return;this.resumeState=this.state,this.activeRecordedAudio?.element.pause(),this.provider?.pause(),this.setState(R.PAUSED)}resume(){if(this.state!==R.PAUSED)return;this.setState(this.resumeState),this.activeRecordedAudio?.play(),this.provider?.resume(),this.releasePauseHold()}normalizePlaybackRate(Z){if(!Number.isFinite(Z))return 1;return Math.max(d9,Math.min(i9,Z))}async restartFromSeekIndex(Z){if(!this.provider||this.seekSegments.length===0)return;let Q=Math.max(0,Math.min(this.seekSegments.length-1,Z)),J=this.playbackChunks.length?this.playbackChunks.slice(Q):null,Y=this.state===R.PAUSED;this.speakRunId+=1,this.abandonRun(),this.provider.onWordBoundary=void 0,this.provider.stop();let X=++this.speakRunId;this.restartRunId=X;let G=this.seekSegments.slice(Q);if(this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.currentBoundaryOffset=this.seekSegments[Q].startOffset,!Y)this.setState(R.LOADING);let j=this.installPlaybackStartBarrier(X,!!J?.[0]?.audio);if(Y)this.resumeState=j?R.LOADING:R.PLAYING;else 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}),J)for(let B=0;B<J.length;B++){if(await this.waitWhilePaused(X),X!==this.speakRunId)return;let V=Q+B,K=this.seekSegments[V];if(K)this.currentBoundaryOffset=K.startOffset;await this.speakCatalogChunk(J[B],X)}else await this.speakWithPlan(G,X,{highlightMode:this.activeHighlightMode});if(X!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(B){if(X!==this.speakRunId){t.debug("Superseded seek restart failed:",B);return}throw this.lastError=B instanceof Error?B.message:String(B),this.setState(R.ERROR),this.clearHighlightsAndTracking(),B}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(Z){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.normalizePlaybackRate(Z),J=this.pendingPlaybackRateRequest;if(J?.rate===Q){await J.promise;return}let Y=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let B=this.speakRunId;if(Y!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:B};let V=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===V)return{didUpdate:!1,playbackRunId:B};return await this.updateSettings({rate:Q}),{didUpdate:!0,playbackRunId:B}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let G=X.then(async(B)=>{if(Y!==this.playbackRateRequestId||B.playbackRunId!==this.speakRunId)return;let V=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!B.didUpdate&&!V)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())}),j;j=G.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===j)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Q,promise:j},await j}async seekBy(Z){if(!this.provider||!this.currentText)return;let Q=this.state===R.LOADING&&this.restartRunId===this.speakRunId;if(this.state!==R.PLAYING&&this.state!==R.PAUSED&&!Q)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let J=Number.isFinite(Z)?Math.trunc(Z):0;if(J===0)return;let Y=this.getCurrentSeekSegmentIndex(),X=Math.max(0,Math.min(this.seekSegments.length-1,Y+J));if(X===Y)return;await this.restartFromSeekIndex(X)}async seekForward(Z=1){let Q=Number.isFinite(Z)?Math.max(1,Math.trunc(Z)):1;await this.seekBy(Q)}async seekBackward(Z=1){let Q=Number.isFinite(Z)?Math.max(1,Math.trunc(Z)):1;await this.seekBy(-Q)}stop(){this.speakRunId+=1,this.abandonRun(),this.provider?.stop(),this.clearHighlightsAndTracking(),this.currentText=null;let Z=this.runOwner!==null;this.runOwner=null,this.setState(R.IDLE,Z)}releaseProvider(){this.stop(),this.provider=null,this.currentProvider=null}dispose(){if(this.disposed)return;this.releaseProvider(),this.disposed=!0,this.speakRunId+=1,this.abandonRun(),this.playbackRateRequestId+=1,this.pendingPlaybackRateRequest=null,this.listeners.clear(),this.readinessGate=null,this.mathSpeechSource=null,this.highlightTargetResolverProvider=null,this.highlightCoordinator=null,this.catalogResolver=null,this.telemetryReporter=null}getState(){return this.state}getRunOwner(){return this.runOwner}onStateChange(Z){let Q=(J)=>Z(J);return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}setState(Z,Q=!1){let J=this.state;if(J===Z&&!Q)return;this.state=Z;for(let Y of[...this.listeners])Y(Z);if(J===Z)return;if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",previousState:J,state:Z}),Z===R.PLAYING){let Y=J===R.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(Y,{toolId:"textToSpeech",previousState:J,state:Z});return}if(Z===R.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",previousState:J,state:Z});return}if(Z===R.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",previousState:J,state:Z,message:this.lastError||void 0});return}if(Z===R.IDLE&&(J===R.PLAYING||J===R.PAUSED||J===R.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",previousState:J,state:Z})}}import{createPieLogger as F2,isGlobalDebugEnabled as z2}from"@pie-players/pie-players-shared/pie";var QZ=F2("ToolProviderRegistry",z2);function JZ(Z){let Q=Z&&typeof Z==="object"?Z.backend:void 0;return typeof Q==="string"&&Q?Q:"unknown"}class rZ{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(Z,Q,J){try{await Z.onTelemetry?.(Q,J)}catch(Y){console.warn("[ToolProviderRegistry] Telemetry callback failed:",Y)}}register(Z,Q){let J=this.providers.get(Z),Y=this.initializationPromises.get(Z);if(this.providers.set(Z,Q.provider),this.configs.set(Z,Q),this.initialized.set(Z,!1),this.initializationPromises.delete(Z),J)if(Y)Y.catch(()=>{}).then(()=>this.destroyProvider(Z,J));else this.destroyProvider(Z,J);if(QZ.debug(`${J?"Replaced":"Registered"} provider "${Z}" (${Q.provider.providerName})`),Q.lazy===!1)this.initialize(Z).catch((X)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${Z}":`,X)})}async initialize(Z){if(this.initialized.get(Z))return;let Q=this.initializationPromises.get(Z);if(Q)return Q;let J=this.providers.get(Z),Y=this._doInitialize(Z);this.initializationPromises.set(Z,Y);try{await Y}catch(X){if(!this.isReplaced(Z,J))throw X}finally{if(this.initializationPromises.get(Z)===Y)this.initializationPromises.delete(Z)}if(this.isReplaced(Z,J))return this.initialize(Z)}isReplaced(Z,Q){let J=this.providers.get(Z);return J!==void 0&&J!==Q}destroyProvider(Z,Q){try{Q.destroy()}catch(J){console.warn(`[ToolProviderRegistry] Failed to destroy provider "${Z}":`,J)}}async _doInitialize(Z){let Q=this.providers.get(Z),J=this.configs.get(Z);if(!Q||!J)throw Error(`[ToolProviderRegistry] Provider "${Z}" not registered`);let Y={...J.config},X=Date.now();if(await this.emitTelemetry(J,"pie-tool-init-start",{toolId:Z,backend:JZ(Y),operation:"provider-initialize"}),Q.requiresAuth&&J.authFetcher){let G=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Z,backend:JZ(Y),operation:"auth-fetch"}),QZ.debug(`Fetching auth for "${Z}"...`);try{let j=await J.authFetcher();Y={...Y,...j},await this.emitTelemetry(J,"pie-tool-backend-call-success",{toolId:Z,backend:JZ(Y),operation:"auth-fetch",duration:Date.now()-G})}catch(j){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Z,backend:JZ(Y),operation:"auth-fetch",duration:Date.now()-G,errorType:"ProviderAuthFetchError",message:j instanceof Error?j.message:String(j)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Z}":`,j),Error(`Failed to fetch auth credentials for provider "${Z}"`)}}try{if(await Q.initialize(Y),this.providers.get(Z)===Q)this.initialized.set(Z,!0);await this.emitTelemetry(J,"pie-tool-init-success",{toolId:Z,backend:JZ(Y),operation:"provider-initialize",duration:Date.now()-X}),QZ.debug(`Provider "${Z}" initialized`)}catch(G){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Z,backend:JZ(Y),operation:"provider-initialize",duration:Date.now()-X,errorType:"ProviderInitializationError",message:G instanceof Error?G.message:String(G)}),console.error(`[ToolProviderRegistry] Initialization failed for "${Z}":`,G),G}}async getProvider(Z,Q=!0){let J=this.providers.get(Z);if(!J)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:Z,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${Z}" not registered`);if(Q&&!this.initialized.get(Z))QZ.debug("Auto-initializing provider:",Z),await this.initialize(Z);return J}getProvidersByCategory(Z){return Array.from(this.providers.entries()).filter(([Q,J])=>J.category===Z).map(([Q])=>Q)}getProviderIds(){return Array.from(this.providers.keys())}has(Z){return this.providers.has(Z)}isInitialized(Z){return this.initialized.get(Z)===!0}isInitializing(Z){return this.initializationPromises.has(Z)}async unregister(Z){let Q=this.providers.get(Z);if(Q){let J=this.initializationPromises.get(Z);if(J){try{await J}catch{}if(this.providers.get(Z)!==Q)return}this.destroyProvider(Z,Q),this.providers.delete(Z),this.configs.delete(Z),this.initialized.delete(Z),this.initializationPromises.delete(Z),QZ.debug(`Unregistered provider "${Z}"`)}}async destroy(){let Z=Array.from(this.providers.keys());await Promise.all(Z.map((Q)=>this.unregister(Q))),QZ.debug("Registry destroyed")}}import{languageTagWithoutVariants as H2}from"@pie-players/pie-players-shared/i18n/language-tags";import{createPieLogger as A2,isTtsDebugEnabled as D2}from"@pie-players/pie-players-shared/pie";var t9=A2("browser-tts-provider",D2),e9=5000,J1=2000,Z1=260,_2=80,M2=["__pieTelemetry","contentLanguage","highlightMode","locale","mathSpeech","segmenter","structuralPauses","textNormalization"],Y1=(Z)=>{let Q={};if(Z.rate!==void 0)Q.rate=Z.rate;if(Z.pitch!==void 0)Q.pitch=Z.pitch;if(Z.volume!==void 0)Q.volume=Z.volume;if(Z.mathTokenHighlighting!==void 0)Q.mathTokenHighlighting=Z.mathTokenHighlighting;let J=Z.providerOptions;if(J&&typeof J==="object"){let Y={};for(let X of M2)if(J[X]!==void 0)Y[X]=J[X];if(Object.keys(Y).length>0)Q.providerOptions=Y}return Q},Q1=(Z)=>{if(!gZ(Z))return{text:Z,sourceOffset:(X)=>X};let{spokenText:Q,rawToSpokenOffsetMap:J}=cZ(Z),Y=[];for(let[X,G]of J){let j=Y[G];if(j===void 0||X<j)Y[G]=X}return{text:Q,sourceOffset:(X)=>{for(let G=X;G>=0;G--){let j=Y[G];if(j!==void 0)return j}return 0}}},H7=(Z)=>String(Z||"").trim().toLowerCase(),O2=()=>{let Z=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return H7(Z||"en-US")},L2=(Z,Q)=>{let J=H7(Q)||O2(),Y=J.split("-")[0]||"en",X=H7(Z.lang);return X===J||X.startsWith(`${Y}-`)},N2=(Z,Q,J)=>{if(Q)return Z.find((G)=>G.voiceURI===Q)||Z.find((G)=>G.name===Q)||null;let Y=(G)=>L2(G,J),X=[(G)=>G.localService&&Y(G),(G)=>G.default&&Y(G),(G)=>Y(G),(G)=>G.localService,(G)=>G.default];for(let G of X){let j=Z.find(G);if(j)return j}return Z[0]||null},P2=(Z,Q,J=()=>!0)=>{if(Z.getVoices().length>0)return Promise.resolve(!0);let Y=typeof Z.addEventListener==="function"&&typeof Z.removeEventListener==="function";if(!Y&&!("onvoiceschanged"in Z))return Promise.resolve(!1);return new Promise((X)=>{let G=Y?null:Z.onvoiceschanged,j=!1,B=(z)=>{if(j)return;if(j=!0,clearTimeout($),Y)Z.removeEventListener("voiceschanged",K);else if(Z.onvoiceschanged===U)Z.onvoiceschanged=G;X(z)},V=()=>{if(!J())B(!1);else if(Z.getVoices().length>0)B(!0)},K=()=>V(),U=(z)=>{try{G?.call(Z,z)}finally{V()}},$=setTimeout(()=>B(!1),Q);if(Y)Z.addEventListener("voiceschanged",K);else Z.onvoiceschanged=U;V()})},w2=(Z)=>!Z.default;class A7{providerId="browser";async initialize(Z){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");if(typeof Z.voice==="string"&&Z.voice.trim())await P2(window.speechSynthesis,J1);return new X1(Z)}getCapabilities(){return{supportsWordBoundary:!0,defaultHighlightMode:"sentence",supportsSSML:!1}}destroy(){}}class X1{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;activeRunId=null;releasePauseHold=null;settlePendingChunk=null;settlePendingGap=null;onPlaybackStart=void 0;constructor(Z){this.config=Z}async waitWhilePaused(Z){while(this._isPaused&&Z===this.speakRunId)await new Promise((Q)=>{this.releasePauseHold=Q});return Z===this.speakRunId}releaseHold(){let Z=this.releasePauseHold;this.releasePauseHold=null,Z?.()}resolveBrowserVoice(){let Z=typeof this.config?.voice==="string"?this.config.voice.trim():"",Q=speechSynthesis.getVoices();if(Z&&Q.length===0)throw Error(`Configured browser voice "${Z}" could not be resolved because the browser did not publish its voice inventory within ${J1/1000} seconds.`);let J=N2(Q,Z||void 0,this.getContentLocale());if(Z&&!J)throw Error(`Configured browser voice "${Z}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return J}async speak(Z){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId;this.activeRunId=Q;try{let J=this.resolveBrowserVoice(),Y=Q1(Z),X=this.splitIntoChunks(Y.text);for(let G of X){if(this._isPaused&&!await this.waitWhilePaused(Q))break;if(!await this.speakChunk(G.text,G.offset,Q,J,Y.sourceOffset))break}}finally{if(this.activeRunId===Q)this.activeRunId=null}}async speakSegments(Z){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId;this.activeRunId=Q;try{let J=this.resolveBrowserVoice();for(let Y of Z){if(Q!==this.speakRunId)break;let X=Q1(Y.text),G=this.splitIntoChunks(X.text);for(let B of G){if(this._isPaused&&!await this.waitWhilePaused(Q))break;if(!await this.speakChunk(B.text,B.offset,Q,J,(K)=>Y.startOffset+X.sourceOffset(K)))break}let j=Math.max(0,Number(Y.pauseMsAfter||0));if(j>0&&Q===this.speakRunId){if(!await this.waitForPause(j,Q))break}}}finally{if(this.activeRunId===Q)this.activeRunId=null}}async waitForPause(Z,Q){return await new Promise((J)=>{let Y=()=>{if(clearTimeout(X),this.settlePendingGap===Y)this.settlePendingGap=null;J()},X=setTimeout(Y,Z);this.settlePendingGap=Y}),Q===this.speakRunId}splitIntoChunks(Z){if(Z.length<=Z1)return[{text:Z,offset:0}];let Q=this.segmentSentences(Z),J=[],Y="",X=0;for(let G of Q){let j=G.text.trim();if(!j)continue;let B=G.text.search(/\S/),V=G.offset+(B===-1?0:B);if(!Y){Y=j,X=V;continue}let K=`${Y} ${j}`;if(K.length<=Z1)Y=K;else J.push({text:Y,offset:X}),Y=j,X=V}if(Y)J.push({text:Y,offset:X});return J.length?J:[{text:Z,offset:0}]}getContentLocale(){let Z=this.config?.providerOptions?.contentLanguage;return typeof Z==="string"&&Z.trim()?H2(Z):void 0}getSegmentationPolicy(){let Z=this.config?.providerOptions||{},Q=Z.segmenter||{},Y=Q.mode!=="regexOnly",X=typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:typeof Z.locale==="string"&&Z.locale.trim().length>0?Z.locale:void 0;return{useSentenceSegmenter:Y,locale:X}}segmentSentences(Z){let Q=this.getSegmentationPolicy();return h0(Z,{locale:Q.locale,useSentenceSegmenter:Q.useSentenceSegmenter})}inferWordLength(Z,Q){let J=Math.max(0,Math.min(Q,Math.max(0,Z.length-1)));return Z.slice(J).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(Z,Q,J,Y,X){return new Promise((G,j)=>{if(J!==this.speakRunId){G(!1);return}let B=new SpeechSynthesisUtterance(Z);this.utterance=B;let V=this.getContentLocale();if(V)B.lang=V;if(Y&&w2(Y))B.voice=Y;if(this.config?.rate)B.rate=this.config.rate;if(this.config?.pitch!==void 0)B.pitch=this.config.pitch;if(this.config?.volume!==void 0)B.volume=this.config.volume;let K=!1,U=!1,$=null,z=null,H=()=>{if(this.utterance===B)this.utterance=null},O=()=>{if($!==null)clearTimeout($),$=null},N=()=>{B.onstart=null,B.onend=null,B.onerror=null,B.onpause=null,B.onresume=null,B.onboundary=null},D=(M,C)=>{if(U)return;if(U=!0,O(),N(),H(),z&&this.settlePendingChunk===z)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1;if(C)j(C);else G(M)},P=(M)=>Error(M==="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 ${e9/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);z=()=>D(!1),this.settlePendingChunk=z,B.onstart=()=>{if(J!==this.speakRunId){D(!1);return}if(K=!0,O(),this._isPlaying=!0,this._isPaused)speechSynthesis.pause();try{this.onPlaybackStart?.()}catch(M){console.error("Browser TTS playback-start callback failed",M)}},B.onend=()=>{if(J!==this.speakRunId){D(!1);return}if(!K){D(!1,P("ended"));return}D(!0)},B.onerror=(M)=>{if(J!==this.speakRunId){D(!1);return}if(M.error==="interrupted"||M.error==="canceled"){D(!1);return}D(!1,Error(`Speech synthesis error: ${M.error}`))},B.onpause=()=>{if(J!==this.speakRunId)return;this._isPaused=!0},B.onresume=()=>{if(J!==this.speakRunId)return;this._isPaused=!1},B.onboundary=(M)=>{if(J!==this.speakRunId)return;if(t9.debug(`boundary event: ${M.name}, charIndex ${M.charIndex}, charLength ${M.charLength}`),M.name!=="word"||!this.onWordBoundary)return;let C=Math.max(0,Math.min(M.charIndex,Math.max(0,Z.length-1))),E=Number(M.charLength||0),v=this.inferWordLength(Z,C),S=Number.isFinite(E)&&E>0&&E<=_2&&C+E<=Z.length?E:v,p=Z.substring(C,Math.min(Z.length,C+S)).trim(),e=Q+C,r=X(e),q0=X(e+S-1)+1-r;t9.debug(`word boundary "${p}" at ${r}`),this.onWordBoundary(p,r,q0)},$=setTimeout(()=>{if(U||K||J!==this.speakRunId)return;D(!1,P("timedOut")),speechSynthesis.cancel()},e9);try{speechSynthesis.speak(B)}catch(M){D(!1,M instanceof Error?M:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPaused)return;if(this._isPlaying)speechSynthesis.pause(),this._isPaused=!0;else if(this.activeRunId===this.speakRunId)this._isPaused=!0}resume(){if(!this._isPaused)return;if(this._isPaused=!1,this._isPlaying)speechSynthesis.resume();this.releaseHold()}stop(){let Z=this.utterance,Q=this._isPlaying||Z!==null;if(this.speakRunId+=1,this.activeRunId=null,this.settlePendingChunk?.(),this.settlePendingGap?.(),Q)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1,this.releaseHold()}updateSettings(Z){if(!this.config)this.config={};if(Z.rate!==void 0)this.config.rate=Z.rate;if(Z.pitch!==void 0)this.config.pitch=Z.pitch;if(Z.volume!==void 0)this.config.volume=Z.volume;if(Z.voice!==void 0)this.config.voice=Z.voice;if(Z.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...Z.providerOptions||{}}}onWordBoundary}var R2=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),G1=(Z)=>Z&&typeof Z==="object"?Z:{},K0=(Z,Q)=>Z===void 0?Q:Z,j1=(Z)=>aZ(Z)==="server"&&Z.serverProvider==="custom"?"custom":"pie",C2=(Z)=>typeof Z==="string"&&R2.has(Z)?Z:"left-aligned",mY=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 uY=Object.freeze([0.8,1,1.25]);var b2=(Z)=>{let Q={...Z,layoutMode:C2(Z.layoutMode)};if(Z.backend!=="server")return Q;let J={...Q,apiEndpoint:K0(Q.apiEndpoint,"/api/tts"),transportMode:K0(Q.transportMode,j1(Z)),endpointValidationMode:K0(Q.endpointValidationMode,"voices"),includeAuthOnAssetFetch:K0(Q.includeAuthOnAssetFetch,!1),rate:K0(Q.rate,1),language:K0(Q.language,"en-US")};if(Z.serverProvider==="polly")return{...J,engine:K0(J.engine,"neural"),format:K0(J.format,"mp3"),speechMarksMode:K0(J.speechMarksMode,"word+sentence")};return J},D7=(Z)=>{let{enabled:Q,provider:J,...Y}=G1(Z);return b2(Y)},aZ=(Z)=>Z.backend||"browser",_7=(Z)=>{let Q=aZ(Z)==="server"?Z.serverProvider:void 0,J=Q==="polly",Y=Z.transportMode||j1(Z),X=V0(Z.mathSpeech);return{voice:Z.defaultVoice,rate:Z.rate,pitch:Z.pitch,providerOptions:{...G1(Z.providerOptions),...Z.language?{locale:Z.language}:{},...J&&Z.engine?{engine:Z.engine}:{},...J&&typeof Z.sampleRate==="number"?{sampleRate:Z.sampleRate}:{},...J&&Z.format?{format:Z.format}:{},...J?{speechMarkTypes:Z.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...Y==="custom"&&typeof Z.cache==="boolean"?{cache:Z.cache}:{},...Y==="custom"&&Z.speedRate?{speedRate:Z.speedRate}:{},...Y==="custom"&&Z.lang_id?{lang_id:Z.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:Z.apiEndpoint,provider:Q,language:Z.language,transportMode:Y,endpointMode:Z.endpointMode,endpointValidationMode:Z.endpointValidationMode,includeAuthOnAssetFetch:Z.includeAuthOnAssetFetch,assetOrigins:Z.assetOrigins,credentials:Z.credentials,headers:Z.headers,...typeof Z.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Z.mathTokenHighlighting}:{}}};var h="textToSpeech";function W1(Z,Q,J){if(Z!==h||!B1(Q.mathSpeech)||!B1(J.mathSpeech))return;return{...Q.mathSpeech,...J.mathSpeech}}function B1(Z){return typeof Z==="object"&&Z!==null&&!Array.isArray(Z)}class M7{host;initialized=!1;degraded=!1;initPromise;reconfigurePromise;reportedMissingProvider=!1;heldMissingProviderBackend=null;constructor(Z){this.host=Z}get started(){return this.initialized}get failedUngranted(){return this.degraded}ownsTool(Z){return Z===h}isStarted(){return this.initialized||this.initPromise!==void 0||this.reconfigurePromise!==void 0}flushInitPromises(Z){if(this.initPromise)Z.add(this.initPromise);if(this.reconfigurePromise)Z.add(this.reconfigurePromise)}mathSpeechRuntimeOptions(){return _7(D7(this.resolveToolConfig())).providerOptions?.mathSpeech}async ensureReady(){if(this.host.assertNotDisposed(),await this.waitForPendingReconfigure(),this.host.assertNotDisposed(),this.initialized)return;if(this.initPromise)return this.initPromise;return this.initPromise=this.initializeIfNeeded().then(()=>this.host.assertNotDisposed()).finally(()=>{this.initPromise=void 0,this.host.notifyReadyChange()}),this.initPromise}waitForPendingReconfigure(){let Z=this.reconfigurePromise;return(async()=>{while(Z)await Z,Z=this.reconfigurePromise})()}async initializeIfNeeded(){if(this.initialized)return;let Z=this.resolveToolConfig(),Q=D7(Z),J=aZ(Q),Y=_7(Q);if(await this.host.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:J}}),this.host.assertNotDisposed(),await this.host.emitTelemetry("pie-toolkit-tts-init-start",{backend:J}),await this.host.emitTelemetry("pie-tool-init-start",{toolId:h,operation:"tts-init",backend:J}),this.host.toolProviderRegistry.has(h))try{let j=await(await this.host.initializeProvider(h,!0)).createInstance();await this.initializeService(j,Y),await this.host.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.host.emitTelemetry("pie-tool-init-success",{toolId:h,operation:"tts-init",backend:J,provider:"registry"});return}catch(G){if(this.host.isDisposalError(G))throw G;let j=G instanceof Error?G:Error(String(G));await this.host.emitTelemetry("pie-tool-init-fallback",{toolId:h,operation:"tts-init",backend:J,fromProvider:"registry",toProvider:"browser",reason:j.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",j)}else if(J!=="browser")this.reportMissingProvider(J);let X=new A7;try{await this.initializeService(X,J==="browser"?Y:Y1(Y)),await this.host.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.host.emitTelemetry("pie-tool-init-success",{toolId:h,operation:"tts-init",backend:J,provider:"browser-fallback"})}catch(G){if(this.host.isDisposalError(G))throw G;let j=G instanceof Error?G:Error(String(G));throw this.host.reportStartFailure(j,{phase:"tts-init"},[h]),await this.host.emitTelemetry("pie-toolkit-tts-init-error",{message:j.message}),await this.host.emitTelemetry("pie-tool-init-error",{toolId:h,operation:"tts-init",backend:J,errorType:"TTSInitError",message:j.message}),j}}resolveToolConfig(){return this.host.providersConfig()?.[h]||{}}async initializeService(Z,Q){let J={...Q.providerOptions,__pieTelemetry:async(X,G)=>{await this.host.emitTelemetry(X,{toolId:h,...G||{}})}},Y={...Q,providerOptions:J};await this.host.ttsService.initialize(Z,Y),this.host.assertNotDisposed(),this.host.ttsService.setCatalogResolver(this.host.catalogResolver),this.initialized=!0,this.degraded=!1,this.host.clearDegradedTool(h),await this.host.hooks.onTTSReady?.(),this.host.assertNotDisposed()}reportMissingProvider(Z){if(this.host.isToolRegistryPending()){this.heldMissingProviderBackend=Z;return}if(this.reportedMissingProvider)return;this.reportedMissingProvider=!0,console.warn(`[ToolkitCoordinator] Text-to-speech is configured for the "${Z}" backend but falls back to browser speech: no "${h}" 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.`)}reportHeldMissingProvider(){let Z=this.heldMissingProviderBackend;if(this.heldMissingProviderBackend=null,Z)this.reportMissingProvider(Z)}discardHeldMissingProvider(){this.heldMissingProviderBackend=null}requiredForReadiness(){if(this.resolveToolConfig()?.enabled===!1)return!1;return!this.host.lazyInit||this.host.isToolGranted(h)}async startForReadiness(){try{await this.ensureReady()}catch(Z){if(this.host.isDisposalError(Z))throw Z;if(this.host.isToolGranted(h))throw Z;this.degraded=!0,this.host.notifyReadyChange()}}scheduleReconfigure(){let Z=this.initPromise,Q=Z?Z.catch(()=>{}).then(()=>this.reconfigure()):this.reconfigure();this.reconfigurePromise=Q,Q.finally(()=>{if(this.reconfigurePromise===Q)this.reconfigurePromise=void 0}),Q.then(async()=>{if(this.host.isDisposalStarted())return;if(this.requiredForReadiness())await this.startForReadiness()}).catch(()=>{})}async reconfigure(){this.initialized=!1,this.degraded=!1,this.host.clearDegradedTool(h),this.initPromise=void 0,this.host.notifyReadyChange();try{this.host.ttsService.releaseProvider()}catch{}if(this.host.toolProviderRegistry.has(h))await this.host.toolProviderRegistry.unregister(h);if(this.host.isDisposalStarted())return;let Z=this.host.getProviderDescriptorTools().find((Q)=>this.ownsTool(Q.toolId));if(!Z)return;await this.host.registerProviderFromTool(Z)}}var V1={textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}};class O7{onTargetFailure;targets=new Set;changeListeners=new Set;constructor(Z=(Q,J,Y)=>console.error(`[ToolRequestRegistry] "${Q}" ${J} failed:`,Y)){this.onTargetFailure=Z}registerTarget(Z){return this.targets.add(Z),this.notifyTargetsChange(),()=>{if(!this.targets.delete(Z))return;this.notifyTargetsChange()}}canRequest(Z,Q,J){return this.findTarget(Z,Q,J)!==null}request(Z){let Q=this.findTarget(Z.toolId,Z.level,Z.scopeId);if(!Q)return!1;try{Q.open(Z.toolId,Z.params)}catch(J){return this.onTargetFailure(Z.toolId,"tool-request-open",J),!1}return!0}onTargetsChange(Z){return this.changeListeners.add(Z),()=>{this.changeListeners.delete(Z)}}findTarget(Z,Q,J){let Y=this.findTargetAtLevel(Z,Q??"section",J);if(Y||Q!==void 0)return Y;for(let X of this.targets){if(X.level==="section")continue;if(J!==void 0&&X.scopeId!==J)continue;if(this.hostsTool(X,Z))return X}return null}findTargetAtLevel(Z,Q,J){for(let Y of this.targets){if(Y.level!==Q)continue;if(J!==void 0&&Y.scopeId!==J)continue;if(this.hostsTool(Y,Z))return Y}return null}hostsTool(Z,Q){try{return Z.hostsTool(Q)===!0}catch(J){return this.onTargetFailure(Q,"tool-request-host-check",J),!1}}notifyTargetsChange(){for(let Z of this.changeListeners)try{Z()}catch(Q){console.warn("[ToolRequestRegistry] Target change listener threw:",Q)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}function E2(Z){return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:void 0}function oZ(Z,Q,J){let Y=Q?.settings,X=[Q?.personalNeedsProfile?.toolParameters?.[Z],Y?.toolParameters?.[Z],J?.settings.toolParameters?.[Z]].map(E2).filter((G)=>G!==void 0);return X.length>0?Object.assign({},...X):void 0}class L7{provenance;stepCounter=0;constructor(Z){this.provenance={contextId:Z,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(Z,Q){let J={id:Q.id,name:Q.name??Q.id};switch(Z){case"organization":this.provenance.sources.organization={...J,pnpDefaults:Q.config};break;case"assessment":this.provenance.sources.assessment={...J,settings:Q.config};break;case"section":this.provenance.sources.section={...J,settings:Q.config};break;case"item":this.provenance.sources.item={...J,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(Z){let Q={step:++this.stepCounter,precedence:Z.precedence,rule:Z.rule,featureId:Z.featureId,action:Z.action,source:{type:Z.sourceType,id:Z.sourceId,name:Z.sourceName},reason:Z.reason,value:Z.value,timestamp:new Date};this.provenance.decisionLog.push(Q);let J=this.provenance.features.get(Z.featureId);if(!J)J={featureId:Z.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(Z.featureId,J);if(J.allDecisions.push(Q),Z.action==="advisory"){if(J.finalState==="not-configured")J.finalState="advisory-only"}else if(Z.action!=="skip"){if(!J.winningDecision||Q.precedence<J.winningDecision.precedence)J.winningDecision=Q,J.finalState=Q.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[Z.sourceType]=(this.provenance.summary.bySource[Z.sourceType]||0)+1,this.provenance.summary.byRule[Z.rule]=(this.provenance.summary.byRule[Z.rule]||0)+1,this}reconcileFinalStates(Z){for(let Q of Z){let J=this.provenance.features.get(Q);if(!J){J={featureId:Q,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Q,J);continue}J.finalState="enabled"}for(let Q of this.provenance.features.values()){if(Z.has(Q.featureId))continue;let J=Q.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),Y=Q.allDecisions.some((X)=>X.action==="advisory");if(J)Q.finalState="blocked";else if(Y)Q.finalState="advisory-only";else Q.finalState="not-configured"}return this}build(){for(let Z of this.provenance.features.values())Z.explanation=S2(Z);for(let Z of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,Z.finalState==="enabled")this.provenance.summary.enabled++;else if(Z.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function S2(Z){if(!Z.winningDecision){if(Z.finalState==="advisory-only"){let G=Z.allDecisions.find((j)=>j.action==="advisory");return G?`Feature "${Z.featureId}" was kept in its host-decided state; ${G.reason}`:`Feature "${Z.featureId}" carries an advisory note.`}return`Feature "${Z.featureId}" was not configured at any level.`}let Q=Z.winningDecision,J=Q.source.name||Q.source.type,Y=`Feature "${Z.featureId}" is ${Z.finalState}.
|
|
216
216
|
|
|
217
217
|
`;Y+=`**Primary Reason** (${Q.rule}):
|
|
218
218
|
`,Y+=`${Q.reason}
|
|
@@ -220,6 +220,6 @@ ${J}`)}function $8(Z,Q={}){let J=N5(Z,Q.toolRegistry);return w5(J.diagnostics,Q)
|
|
|
220
220
|
`;let X=Z.allDecisions.filter((G)=>G.step!==Q.step&&G.action!=="skip"&&G.action!=="advisory"&&G.precedence>Q.precedence);if(X.length>0){Y+=`
|
|
221
221
|
**Overridden Rules**:
|
|
222
222
|
`;for(let G of X)Y+=`- ${G.rule}: ${G.reason}
|
|
223
|
-
`}return Y}function G1(Z){let{request:Q,tools:J,pnpPolicy:Y,customSources:X,contextId:G}=Z,j=new O7(G);j.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=H0(J.placement[Q.level]),V=H0(J.policy.allowed),K=new Set(H0(J.policy.blocked)),U=[];for(let H of B)U.push(H),j.addDecision({precedence:0,rule:"placement-membership",featureId:H,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(U=U.filter((H)=>{if(J.providers?.[H]?.enabled===!1)return j.addDecision({precedence:0,rule:"provider-disabled",featureId:H,action:"block",sourceType:"host",reason:`tools.providers.${H}.enabled === false`,value:!1}),!1;return!0}),V.length>0){let H=new Set(V);U=U.filter((N)=>{if(!H.has(N))return j.addDecision({precedence:0,rule:"host-allowlist",featureId:N,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:V}),!1;return!0})}U=U.filter((H)=>{if(K.has(H))return j.addDecision({precedence:0,rule:"host-blocked",featureId:H,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:J.policy.blocked}),!1;return!0});let $=[],z=new Set(U),D=null;if(Y.enforcement==="on"&&Y.source&&(Y.assessment||Y.item)){if(D=Y.source.apply({assessment:Y.assessment,item:Y.item}),D.sources.assessment)j.addSource("assessment",D.sources.assessment);if(D.sources.student)j.addSource("student",D.sources.student);if(D.sources.item)j.addSource("item",D.sources.item);for(let O of D.decisions)j.addDecision({precedence:O.precedence,rule:O.rule,featureId:O.featureId,action:O.action,sourceType:O.sourceType,reason:O.reason,value:O.value});for(let[O,C]of D.blockedOverrides)$.push(L7(O,C,Q.level));for(let[O,C]of D.supportConflicts){if(!z.has(O))continue;$.push(AZ(O,C.support,C.grant??"placement",Q.level))}let{blockedToolIds:H}=D;U=U.filter((O)=>!H.has(O));let N=new Set(Object.values(J.placement).flatMap(H0));for(let[O,C]of D.mandates){if(z.has(O))continue;if(!B.includes(O)&&N.has(O))continue;let E=N2(O,{placedAtAnyLevel:N,allTools:J.placement,allowed:V,blocked:K,providers:J.providers}),v={rule:C,hostRule:E.hostRule,hostValue:E.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:O,message:E.hostRule==="placement-missing"?`Profile policy mandates "${O}" (${C}), but no level of tools.placement lists it.`:`Profile policy mandates "${O}" (${C}), but host policy removes it via ${E.hostRule}.`,details:v}),j.addDecision({precedence:0,rule:"required-tool-blocked",featureId:O,action:"advisory",sourceType:"host",reason:`Host removed required tool "${O}" via ${E.hostRule}`,value:v})}}for(let H=0;H<X.length;H++){let N=X[H],O=U.slice(),C=N.refine({request:Q,candidates:O}),E=new Set(C.refinedCandidates);for(let S of C.refinedCandidates)if(!O.includes(S))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:S,message:`Custom source "${N.id}" tried to add tool "${S}" that was not in candidates; ignored.`,details:{customSourceId:N.id}}),E.delete(S);U=O.filter((S)=>E.has(S));let v=new Set;if(C.decisions){for(let S of C.decisions)if(j.addDecision({precedence:S.precedence??100+H,rule:S.rule,featureId:S.featureId,action:S.action,sourceType:S.sourceType,reason:S.reason,value:S.value}),S.action==="block")v.add(S.featureId)}for(let S of O){if(E.has(S))continue;if(v.has(S))continue;j.addDecision({precedence:100+H,rule:"custom-source",featureId:S,action:"block",sourceType:"custom",reason:`Custom policy source "${N.id}" removed tool "${S}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:N.id}})}}for(let H of U)for(let N of Z.unappliedItems??[]){let O=["restrictedTools","requiredTools"].filter((E)=>N.settings[E]?.includes(H)===!0);if(O.length===0)continue;let C={itemId:N.id,settings:O,toolbarLevel:Q.scope.level};$.push({code:"tool-policy.itemSettingNotApplied",level:Q.level,toolId:H,message:`Item "${N.id}" names "${H}" in ${O.join(" and ")}, but "${H}" is on the ${Q.scope.level}-level toolbar, which item settings do not reach. Place "${H}" at item level to enforce the setting per item.`,details:C})}let M=new Set(U),P=U.map((H)=>{let N=D?.perToolFlags.get(H);return{toolId:H,required:N?.required??!1,alwaysAvailable:N?.alwaysAvailable??!1,activateAtInit:N?.activateAtInit??!1,parameters:aZ(H,Y.assessment,Y.item)}});return j.reconcileFinalStates(M),{visibleTools:P,diagnostics:$,provenance:j.build()}}function N2(Z,Q){if(!Q.placedAtAnyLevel.has(Z))return{hostRule:"placement-missing",hostValue:Q.allTools};if(Q.providers?.[Z]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Q.allowed.length>0&&!Q.allowed.includes(Z))return{hostRule:"host-allowlist",hostValue:Q.allowed};if(Q.blocked.has(Z))return{hostRule:"host-blocked",hostValue:Array.from(Q.blocked)};return{hostRule:"placement-missing",hostValue:Q.allTools}}var M7={"district-block":"settings.districtPolicy.blockedTools","test-admin-override":"settings.testAdministration.toolOverrides","item-restriction":"item settings.restrictedTools","pnp-prohibited":"personalNeedsProfile.prohibitedSupports","support-conflict":"a withholding support in personalNeedsProfile.supports","item-requirement":"item settings.requiredTools","district-requirement":"settings.districtPolicy.requiredTools","pnp-support":"personalNeedsProfile.supports","pnp-activate-at-init":"personalNeedsProfile.activateAtInit"};function L7(Z,Q,J){return{code:"tool-policy.overrideBlocked",...J?{level:J}:{},toolId:Z,message:`settings.testAdministration.toolOverrides grants "${Z}", but ${M7[Q]} withdraws it and outranks a granting override.`,details:{rule:Q}}}function AZ(Z,Q,J,Y){let X=J==="placement"?"tools.placement":J==="attribute"?"The item player's attribute":J==="authored"?"The item's authored content":M7[J];return{code:"tool-policy.supportConflict",...Y?{level:Y}:{},toolId:Z,message:`${X} serves "${Z}", but the student's "${Q}" support withholds it.`,details:{support:Q,servedBy:J}}}function j1(Z,Q){let J=Q.map((Y)=>M7[Y]).join(", ");return{code:"tool-policy.unknownSupportId",toolId:Z,message:`No tool is registered under "${Z}", named in ${J}, so it matches nothing. These lists name tools by tool id.`,details:{origins:[...Q]}}}var w2=(Z)=>`No assessment is bound, so no policy source could grant "${Z}"`;function P7(Z,Q,J,Y){return{featureId:Z,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 (${J.join(", ")})`,required:!1,assessmentBound:Y.assessmentBound,diagnostics:[]}}function B1(Z,Q,J,Y){let X=Q.decisions[0],G=Array.from(Q.perToolFlags.values())[0],j=X?.action==="enable",B=X?.reason??`Feature "${Z}" not configured`,V=X!==void 0&&X.action!=="skip",K=Q.supportConflicts.get(Z);return{featureId:Z,granted:j,action:X?.action??"skip",rule:V?X.rule:"none",precedence:V?X.precedence:null,sourceType:X?.sourceType??"system",reason:J.assessmentBound||j?B:w2(Z),required:Boolean(G?.required),parameters:Y,...V&&X.rule==="support-conflict"&&K?{withheldBy:K.support}:{},assessmentBound:J.assessmentBound,diagnostics:[...Array.from(Q.blockedOverrides,([U,$])=>L7(U,$)),...Array.from(Q.supportConflicts).flatMap(([U,{support:$,grant:z}])=>z?[AZ(U,$,z)]:[])]}}var m0=(Z)=>Array.isArray(Z)&&Z.length>0;function R2(Z){if(!Z)return!1;let Q=Z.personalNeedsProfile;if(Q&&(m0(Q.supports)||m0(Q.prohibitedSupports)||m0(Q.activateAtInit)))return!0;let J=Z.settings;if(J){let Y=J.districtPolicy;if(Y&&(m0(Y.blockedTools)||m0(Y.requiredTools)))return!0;let X=J.testAdministration?.toolOverrides;if(X&&typeof X==="object"&&Object.keys(X).length>0)return!0}return!1}function C2(Z){if(!Z)return!1;return m0(Z.requiredTools)||m0(Z.restrictedTools)}function W1(Z){if(R2(Z.assessment))return"on";if(C2(Z.itemSettings))return"on";return"off"}class oZ{id="pnp";toolRegistry;supportConflicts;withheldBy=new Map;registrylessIds=new Set;constructor(Z,Q=[]){this.toolRegistry=Z,this.supportConflicts=Q;for(let{support:J,withholds:Y}of Q){this.registrylessIds.add(J);for(let X of Y){this.registrylessIds.add(X);let G=this.withheldBy.get(X)??[];G.push(J),this.withheldBy.set(X,G)}}}apply(Z){let{ctx:Q,result:J}=this.prepare(Z),{pnp:Y,districtPolicy:X,testAdmin:G,itemSettings:j}=Q,B=new Set;Y?.supports?.forEach((V)=>B.add(V)),Y?.prohibitedSupports?.forEach((V)=>B.add(V)),Y?.activateAtInit?.forEach((V)=>B.add(V)),X?.blockedTools?.forEach((V)=>B.add(V)),X?.requiredTools?.forEach((V)=>B.add(V));for(let V of Object.keys(G?.toolOverrides??{}))B.add(V);j?.requiredTools?.forEach((V)=>B.add(V)),j?.restrictedTools?.forEach((V)=>B.add(V));for(let{support:V,withholds:K}of this.supportConflicts)if(this.supportInEffect(V,Q))K.forEach((U)=>B.add(U));for(let V of B)this.resolveSupport(V,Q,J);return J}resolveFeature(Z,Q){let{ctx:J,result:Y}=this.prepare(Q);return this.resolveSupport(Z,J,Y),Y}prepare(Z){let{assessment:Q,item:J}=Z,Y=Q?.personalNeedsProfile,X=Q?.settings,G=J?.settings,j=N7();if(X?.districtPolicy||X?.testAdministration)j.sources.assessment={id:Q?.id||"unknown",name:Q?.name||Q?.id||"Assessment",config:X};if(Y)j.sources.student={id:"student",name:"Student PNP Profile",config:Y};if(J)j.sources.item={id:J.id,name:J.id,config:J.settings};return{ctx:{pnp:Y,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:G},result:j}}supportInEffect(Z,Q){let J=N7();return this.resolveSupport(Z,Q,J,!1),J.decisions[0]?.action==="enable"}resolveSupport(Z,Q,J,Y=!0){if(Q.districtPolicy?.blockedTools?.includes(Z)){J.blockedToolIds.add(Z),J.decisions.push({precedence:1,rule:"district-block",featureId:Z,action:"block",sourceType:"assessment",reason:`District policy blocks "${Z}" for all assessments`,value:Q.districtPolicy.blockedTools});return}let X=Q.testAdmin?.toolOverrides?.[Z];if(X===!1){J.blockedToolIds.add(Z),J.decisions.push({precedence:2,rule:"test-admin-override",featureId:Z,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${Z}" for this session`,value:Q.testAdmin?.toolOverrides});return}if(Q.itemSettings?.restrictedTools?.includes(Z)){if(J.blockedToolIds.add(Z),X===!0)J.blockedOverrides.set(Z,"item-restriction");J.decisions.push({precedence:3,rule:"item-restriction",featureId:Z,action:"block",sourceType:"item",reason:`Item restricts "${Z}" (e.g., mental math question blocks calculator)`,value:Q.itemSettings.restrictedTools});return}if(Q.pnp?.prohibitedSupports?.includes(Z)){if(J.blockedToolIds.add(Z),X===!0)J.blockedOverrides.set(Z,"pnp-prohibited");J.decisions.push({precedence:4,rule:"pnp-prohibited",featureId:Z,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${Z}"`,value:Q.pnp.prohibitedSupports});return}let G=Y?this.withheldBy.get(Z)?.find((V)=>this.supportInEffect(V,Q)):void 0;if(G){let V=N7();this.resolveSupport(Z,Q,V,!1);let K=V.decisions[0];J.blockedToolIds.add(Z),J.supportConflicts.set(Z,{support:G,...K?.action==="enable"?{grant:K.rule}:{}}),J.decisions.push({precedence:4,rule:"support-conflict",featureId:Z,action:"block",sourceType:"student",reason:`"${Z}" is withheld while the student's "${G}" support is in effect`,value:{support:G}});return}let j=Q.pnp?.activateAtInit?.includes(Z)===!0,B=Q.itemSettings?.requiredTools?.includes(Z)?"item-requirement":Q.districtPolicy?.requiredTools?.includes(Z)?"district-requirement":void 0;if(X===!0){if(B)J.mandates.set(Z,B);J.perToolFlags.set(Z,{required:B!==void 0,alwaysAvailable:!0,activateAtInit:j,rule:"test-admin-override"}),J.decisions.push({precedence:5,rule:"test-admin-override",featureId:Z,action:"enable",sourceType:"assessment",reason:`Test administrator enabled "${Z}" for this session`,value:Q.testAdmin?.toolOverrides});return}if(B==="item-requirement"){J.mandates.set(Z,B),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,activateAtInit:j,rule:"item-requirement"}),J.decisions.push({precedence:6,rule:"item-requirement",featureId:Z,action:"enable",sourceType:"item",reason:`Item requires "${Z}" for this question`,value:Q.itemSettings?.requiredTools});return}if(B==="district-requirement"){J.mandates.set(Z,B),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,activateAtInit:j,rule:"district-requirement"}),J.decisions.push({precedence:7,rule:"district-requirement",featureId:Z,action:"enable",sourceType:"assessment",reason:`District policy requires "${Z}" for all assessments`,value:Q.districtPolicy?.requiredTools});return}if(j){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,activateAtInit:j,rule:"pnp-activate-at-init"}),J.decisions.push({precedence:8,rule:"pnp-activate-at-init",featureId:Z,action:"enable",sourceType:"student",reason:`Student PNP profile turns on "${Z}" at start`,value:Q.pnp?.activateAtInit});return}if(Q.pnp?.supports?.includes(Z)){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,activateAtInit:!1,rule:"pnp-support"}),J.decisions.push({precedence:8,rule:"pnp-support",featureId:Z,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${Z}"`,value:Q.pnp.supports});return}J.decisions.push({precedence:8,rule:"pnp-support",featureId:Z,action:"skip",sourceType:"system",reason:`Feature "${Z}" not configured at any level`,value:{supportId:Z}})}unknownSupportIds(Z,Q){let J=new Map;if(this.toolRegistry.getAllTools().length===0)return J;let Y=Z?.personalNeedsProfile,X=Z?.settings,G=[["district-block",X?.districtPolicy?.blockedTools],["test-admin-override",Object.keys(X?.testAdministration?.toolOverrides??{})],["item-restriction",Q.flatMap((j)=>j.restrictedTools??[])],["pnp-prohibited",Y?.prohibitedSupports],["item-requirement",Q.flatMap((j)=>j.requiredTools??[])],["district-requirement",X?.districtPolicy?.requiredTools],["pnp-activate-at-init",Y?.activateAtInit],["pnp-support",Y?.supports]];for(let[j,B]of G)for(let V of B??[]){if(this.toolRegistry.has(V)||this.registrylessIds.has(V))continue;let K=J.get(V)??[];if(!K.includes(j))K.push(j);J.set(V,K)}return J}}function N7(){return{blockedToolIds:new Set,mandates:new Map,perToolFlags:new Map,decisions:[],blockedOverrides:new Map,supportConflicts:new Map,sources:{}}}var V1=l0({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class tZ{toolRegistry;unsubscribeRegistry;contextId;assessmentOptional;pnpPolicySource;supportConflicts;customSources;listeners=new Set;tools;assessment;pnpEnforcementOverride;itemSettings=new Map;inputDiagnostics=Object.freeze([]);disposed=!1;constructor(Z){this.toolRegistry=Z.toolRegistry,this.contextId=Z.contextId??"tool-policy",this.assessmentOptional=Z.assessmentOptional===!0,this.supportConflicts=Z.supportConflicts??[],this.pnpPolicySource=new oZ(this.toolRegistry,this.supportConflicts),this.customSources=Z.customSources?[...Z.customSources]:[];let Q=Z.inputs??{};this.tools=Q.tools??V1,this.assessment=Q.assessment??null,this.pnpEnforcementOverride=Q.pnpEnforcement??null,this.refreshInputDiagnostics(),this.unsubscribeRegistry=this.watchRegistry()}decide(Z){this.assertNotDisposed();let Q=Z.scope.scopeId?`${this.contextId}:${Z.level}:${Z.scope.scopeId}`:`${this.contextId}:${Z.level}`,J=Z.level==="item"?this.itemForScope(Z.scope):void 0,Y=Z.level!=="item"||Z.scope.level==="section"||Z.scope.level==="assessment";return G1({request:Z,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,item:J,enforcement:this.enforcementFor(J)},unappliedItems:Y?this.enforcedItems():void 0,customSources:this.customSources,contextId:Q})}grantsFeatureAnywhere(Z,Q={}){let J=(Y)=>!Q.enforced||this.enforcementFor(Y)==="on";if(J()&&this.decideFeature(Z).granted)return!0;for(let Y of this.itemSettings.keys()){let X=this.itemSettingsFor(Y);if(!J(X?{id:Y,settings:X}:void 0))continue;if(this.decideFeature(Z,{level:"item",scopeId:Y}).granted)return!0}return!1}registerItemSettings(Z,Q){this.assertNotDisposed();let J={settings:Q},Y=this.itemSettingsFor(Z),X=this.itemSettings.get(Z)??[];return X.push(J),this.itemSettings.set(Z,X),this.emitIfItemSettingsChanged(Z,Y),()=>{if(this.disposed)return;let G=this.itemSettings.get(Z),j=G?.indexOf(J)??-1;if(!G||j<0)return;let B=this.itemSettingsFor(Z);if(G.splice(j,1),G.length===0)this.itemSettings.delete(Z);this.emitIfItemSettingsChanged(Z,B)}}decideFeature(Z,Q){this.assertNotDisposed();let J=this.hostFeatureGate(Z);if(J)return J;let Y=this.itemForScope(Q);return B1(Z,this.pnpPolicySource.resolveFeature(Z,{assessment:this.assessment??void 0,item:Y}),{assessmentBound:this.assessment!==null},aZ(Z,this.assessment,Y))}hostFeatureGate(Z){let Q={assessmentBound:this.assessment!==null},J=H0(this.tools.policy.blocked);if(J.includes(Z))return P7(Z,"host-blocked",J,Q);let Y=H0(this.tools.policy.allowed);if(Y.length>0&&!Y.includes(Z))return P7(Z,"host-allowlist",Y,Q);return null}getVisibleToolIds(Z,Q){return this.decide({level:Z,scope:{level:Z,scopeId:Q}}).visibleTools.map((J)=>J.toolId)}updateInputs(Z){this.assertNotDisposed();let Q=!1,J=!1;if("tools"in Z){let Y=Z.tools??V1;if(!Object.is(this.tools,Y))this.tools=Y,Q=!0}if("assessment"in Z){let Y=Z.assessment??null,X=!u0(this.assessment,Y);if(this.assessment=Y,X)Q=!0,this.refreshInputDiagnostics()}if("pnpEnforcement"in Z){let Y=Z.pnpEnforcement??null;if(this.pnpEnforcementOverride!==Y)this.pnpEnforcementOverride=Y,J=!0}if(Q||J)this.emit({reason:J&&!Q?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}replaceToolRegistry(Z,Q){this.assertNotDisposed(),this.unsubscribeRegistry(),this.toolRegistry=Z,this.pnpPolicySource=new oZ(Z,this.supportConflicts),this.unsubscribeRegistry=this.watchRegistry(),this.tools=Q,this.refreshInputDiagnostics(),this.emit({reason:"inputs",inputs:this.snapshotInputs()})}registerPolicySource(Z){return this.assertNotDisposed(),this.customSources.push(Z),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Q=this.customSources.indexOf(Z);if(Q===-1)return;if(this.customSources.splice(Q,1),this.disposed)return;this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}onPolicyChange(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.unsubscribeRegistry(),this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.itemSettings.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,pnpEnforcement:this.enforcementFor(),pnpEnforcementOverride:this.pnpEnforcementOverride,assessmentExpected:!this.assessmentOptional||this.pnpEnforcementOverride==="on",diagnostics:this.inputDiagnostics})}enforcementFor(Z){return this.pnpEnforcementOverride??W1({assessment:this.assessment,itemSettings:Z?.settings})}itemSettingsFor(Z){return this.itemSettings.get(Z)?.at(-1)?.settings}emitIfItemSettingsChanged(Z,Q){if(u0(Q,this.itemSettingsFor(Z)))return;this.refreshInputDiagnostics(),this.emit({reason:"item-settings",inputs:this.snapshotInputs()})}refreshInputDiagnostics(){let Z=[];for(let J of this.itemSettings.keys()){let Y=this.itemSettingsFor(J);if(Y)Z.push(Y)}let Q=Array.from(this.pnpPolicySource.unknownSupportIds(this.assessment,Z),([J,Y])=>j1(J,Y));if(u0(this.inputDiagnostics,Q))return!1;return this.inputDiagnostics=Object.freeze(Q),!0}watchRegistry(){return this.toolRegistry.onRegistryChange(()=>{if(this.disposed)return;if(this.refreshInputDiagnostics())this.emit({reason:"inputs",inputs:this.snapshotInputs()})})}itemForScope(Z){if(Z?.level!=="item")return;let Q=Z.canonicalItemId||Z.itemId||Z.scopeId,J=Q?this.itemSettingsFor(Q):void 0;return J?{id:Q,settings:J}:void 0}enforcedItems(){let Z=[];for(let Q of this.itemSettings.keys()){let J=this.itemSettingsFor(Q);if(!J)continue;let Y={id:Q,settings:J};if(this.enforcementFor(Y)==="on")Z.push(Y)}return Z}emit(Z){for(let Q of Array.from(this.listeners))try{Q(Z)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}import{hasResponseField as b2,hasResponseValue as K1}from"@pie-players/pie-players-shared/pie";import{isPlainRecord as JZ}from"@pie-players/pie-players-shared/object";function eZ(Z){return JZ(Z)&&JZ(Z.session)?Z.session:Z}function E2(Z,Q){let J=JZ(Z)?Z:{},Y=JZ(Q)?Q:{},X=new Set([...Object.keys(J),...Object.keys(Y)]);for(let G of X)if(!u0(eZ(J[G]),eZ(Y[G])))return!1;return!0}function S2(Z,Q){for(let[J,Y]of Object.entries(Z)){if(Y===void 0)continue;if(J==="itemSessions"){if(!E2(Y,Q.itemSessions))return!1;continue}if(!u0(Y,Q[J]))return!1}return!0}function Z5(Z,Q){if(!Z)return Q;let J=JZ(Q.itemSessions)?{...Q.itemSessions}:{},Y=JZ(Z.itemSessions)?Z.itemSessions:{};for(let[G,j]of Object.entries(Y)){if(!K1(eZ(j)))continue;let B=eZ(J[G]);if(K1(B)||b2(B))continue;J[G]=j}let X={...Q,itemSessions:J};return S2(X,Z)?null:X}var q1=[{support:"screenReader",withholds:["textToSpeech","autoplayAudio"]}];class i extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class Q5 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var U1=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),T2=(Z,Q,J)=>{let Y={...Q,...J};if(Z==="textToSpeech"&&U1(Q.mathSpeech)&&U1(J.mathSpeech))Y.mathSpeech={...Q.mathSpeech,...J.mathSpeech};return Y},y2={"tool-module-load":"failed to load","tool-request-open":"failed to open on request","tool-request-host-check":"failed its toolbar's host check","tool-visibility":"failed its relevance check","tool-applicability":"failed its applicability check","tool-state-load":"failed to restore its state","tool-state-save":"failed to save its state","tool-playback":"failed during playback"},x2=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],k2=["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 R7{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsDegraded=!1;ttsInitPromise;ttsReconfigurePromise;stateLoadSettled=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;degradedTools=new Map;reportedToolFailures=new Set;readyChangeListeners=new Set;eagerInit;toolRegistry;toolRegistrySupplied;toolRegistrySettled;toolRegistryAbsent=!1;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new _7((Z,Q,J)=>this.reportToolFailure(Z,Q,J));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;ownedToolCoordinator;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;reportedPolicyDiagnostics=new Map;policyDiagnosticListeners=new Set;reportedUnboundFeaturePolicy=!1;reportedMissingTTSProvider=!1;heldMissingTTSProviderBackend=null;reportedRegistryUnavailable=!1;resolveConfig(Z){let Q=P5(Z.toolConfigStrictness),J=Z.toolRegistry??new w7,Y=Z.deferToolConfigValidation===!0?l0(Z.tools):this.validateToolsConfig(Z.tools,{strictness:Q,source:"ToolkitCoordinator.init",toolRegistry:J});return{...Z,toolConfigStrictness:Q,toolRegistry:J,tools:{...Y,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...Y.providers}},accessibility:{language:"en-US",...Z.accessibility??{},catalogs:Z.accessibility?.catalogs??[]}}}validateToolsConfig(Z,Q){let{config:J,diagnostics:Y}=N5(Z,Q.toolRegistry),X=this.reportedRegistryUnavailable||this.toolRegistryPending()?Y.filter((G)=>G.code!=="tools.registryUnavailable"):Y;if(w5(X,Q),Q.strictness!=="off"&&X.some((G)=>G.code==="tools.registryUnavailable"))this.reportedRegistryUnavailable=!0;return J}constructor(Z){if(!Z.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");this.toolRegistrySupplied=Z.toolRegistry!=null,this.toolRegistrySettled=this.toolRegistrySupplied;let Q=this.resolveConfig(Z);if(this.assessmentId=Q.assessmentId,this.config=Q,this.toolRegistry=Q.toolRegistry??new w7,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks={...Q.hooks},this.lazyInit=Z.lazyInit===!0,this.eagerInit=Z.eagerInit??!this.lazyInit,this.frameworkErrorBus=Z.frameworkErrorBus??new qZ,this.ownsFrameworkErrorBus=!Z.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.ownedToolCoordinator=new $1,this.toolCoordinator=this.ownedToolCoordinator,this.highlightCoordinator=new DZ,this.elementToolStateStore=new f5,this.catalogResolver=new x5(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new rZ,this._registerToolProviders(),this.ttsService=new F7,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.ttsService.setReadinessGate(()=>this.ensureTTSReady()),this.ttsService.setMathSpeechSource(()=>A7(H7(this.resolveTTSToolConfig())).providerOptions?.mathSpeech),this.setupStatePersistenceHooks(),this.policyEngine=new tZ({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,assessmentOptional:this.config.assessmentOptional===!0,supportConflicts:q1,inputs:{tools:this.config.tools,assessment:null,pnpEnforcement:this.resolveConfiguredPnpEnforcement()}}),this.policyEngine.onPolicyChange((J)=>{if(J.reason==="disposed")return;if(J.reason==="inputs"||J.reason==="pnp-enforcement")this.reportedPolicyDiagnostics.clear();this.warnPolicyDiagnostics(J.inputs.diagnostics),this.reportNewlyGrantedFailures()}),this.eagerInit)this.waitUntilReady().catch((J)=>{if(J instanceof i)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready",recoverable:!1})})}assertNotDisposed(){if(this.disposePromise!==null)throw new i}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((Z)=>{let Q=this.hooks.onFrameworkError;if(!Q)return;try{Q(Z)}catch(J){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",J)}})}async emitTelemetry(Z,Q){try{await this.hooks.onTelemetry?.(Z,Q)}catch(Y){console.warn("[ToolkitCoordinator] telemetry hook failed:",Y)}let J=Q?{...Q}:void 0;for(let Y of this.telemetryListeners)try{Y({eventName:Z,payload:J?{...J}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(Z){for(let Q of this.sectionControllerLifecycleListeners)try{Q(Z)}catch(J){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",J)}}handleError(Z,Q,J){let Y=w8({error:Z,context:Q,recoverable:Q.recoverable,scope:J?"cohort":"runtime",cohort:J});this.frameworkErrorBus.reportFrameworkError(Y)}isToolGranted(Z){try{return this.policyEngine.grantsFeatureAnywhere(Z,{enforced:this.toolRegistry.getToolActivation(Z)!=="region"})}catch{return!1}}reportStartFailure(Z,Q,J,Y=!1){let X=Array.from(J),G=Y||!X.some((j)=>this.isToolGranted(j));if(G&&!Y)for(let j of X)this.degradedTools.set(j,{error:Z,context:Q});this.handleError(Z,{...Q,recoverable:G})}reportToolFailure(Z,Q,J){if(Q==="tool-module-load")this.toolRequests.notifyTargetsChange();let Y=`${Q}\x00${Z}`;if(this.reportedToolFailures.has(Y))return;this.reportedToolFailures.add(Y);let X=J instanceof Error&&J.message.trim().length>0?J.message:String(J),G=()=>this.reportStartFailure(Error(`Tool "${Z}" ${y2[Q]}: ${X}`,{cause:J}),{phase:Q,details:{toolId:Z}},[Z],Q!=="tool-module-load");if(Q==="tool-module-load")G();else queueMicrotask(G)}reportNewlyGrantedFailures(){for(let[Z,Q]of this.degradedTools){if(!this.isToolGranted(Z))continue;this.degradedTools.delete(Z),this.handleError(Q.error,{...Q.context,recoverable:!1})}}onReadyChange(Z){return this.readyChangeListeners.add(Z),()=>{this.readyChangeListeners.delete(Z)}}notifyReadyChange(){for(let Z of this.readyChangeListeners)try{Z()}catch(Q){console.warn("[ToolkitCoordinator] ready-change listener failed:",Q)}}subscribeFrameworkErrors(Z){return this.frameworkErrorBus.subscribeFrameworkErrors(Z)}reportFrameworkError(Z){this.frameworkErrorBus.reportFrameworkError(Z)}sectionControllerKey(Z){return{assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId}}getSectionControllerMapKey(Z){return`${Z.assessmentId}::${Z.sectionId}::${Z.attemptId||""}`}createDefaultSectionPersistence(){let Z=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Q=(J)=>{let{assessmentId:Y,sectionId:X,attemptId:G}=J.key;if(!G)return null;return`pie:section-controller:v1:${Y}:${X}:${G}`};return{async loadSession(J){let Y=Q(J);if(!Z||!Y)return null;let X=Z.getItem(Y);if(!X)return null;try{return JSON.parse(X)}catch{return null}},async saveSession(J,Y){let X=Q(J);if(!Z||!X)return;Z.setItem(X,JSON.stringify(Y))},async clearSession(J){let Y=Q(J);if(!Z||!Y)return;Z.removeItem(Y)}}}async resolveSectionPersistence(Z){let Q=this.getSectionControllerMapKey(Z.key),J=this.sectionPersistenceStrategies.get(Q);if(J)return J;let Y={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(Z,Y)??await Y.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Q,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((Z)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(Z)).catch((Q)=>{this.handleError(Q,{phase:"state-save",recoverable:!0})})})}async ensureStateLoaded(){if(this.stateLoadSettled)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let Z=this.hooks.loadToolState;if(!Z)return;try{let Q=await Z();if(this.assertNotDisposed(),Q&&typeof Q==="object")this.elementToolStateStore.loadState(Q);this.stateLoadSettled=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Q)})}catch(Q){if(Q instanceof i)throw Q;this.stateLoadSettled=!0,this.handleError(Q,{phase:"state-load",recoverable:!0})}})().finally(()=>{this.stateLoadPromise=void 0,this.notifyReadyChange()}),this.stateLoadPromise}toolRegistryPending(){return!this.toolRegistrySettled&&!this.toolRegistryAbsent}reportMissingTTSProvider(Z){if(this.toolRegistryPending()){this.heldMissingTTSProviderBackend=Z;return}if(this.reportedMissingTTSProvider)return;this.reportedMissingTTSProvider=!0,console.warn(`[ToolkitCoordinator] Text-to-speech is configured for the "${Z}" backend but falls back to browser speech: no "textToSpeech" 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(Z){if(this.disposePromise!==null||this.toolRegistrySettled)return!1;if(!Z&&this.toolRegistryAbsent)return!1;let Q=this.heldMissingTTSProviderBackend;this.heldMissingTTSProviderBackend=null;let J=this.config.toolConfigStrictness??"error",Y="ToolkitCoordinator.adoptToolRegistry";if(!Z){if(this.toolRegistryAbsent=!0,this.validateToolsConfig(this.config.tools,{strictness:J,source:Y,toolRegistry:this.toolRegistry}),Q)this.reportMissingTTSProvider(Q);return!1}this.toolRegistrySettled=!0,this.toolRegistry=Z,this.config.toolRegistry=Z;try{this.config.tools=this.validateToolsConfig(this.config.tools,{strictness:J==="off"?"off":"warn",source:Y,toolRegistry:Z})}catch(G){console.warn("[ToolkitCoordinator] Tool config does not validate against the adopted tool registry:",G)}this.policyEngine.replaceToolRegistry(Z,this.config.tools);let X=this.ttsInitialized||this.ttsInitPromise!==void 0||this.ttsReconfigurePromise!==void 0;for(let G of this.getProviderDescriptorTools()){if(X&&G.toolId==="textToSpeech")continue;this.registerProviderFromTool(G)}if(X)this.scheduleTTSReconfigure();return!0}_registerToolProviders(){let Z=this.getProviderDescriptorTools();for(let Q of Z)this.registerProviderFromTool(Q)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((Z)=>!!Z.provider)}async registerProviderFromTool(Z,Q=!1){let J=Z.provider;if(!J)return;let{toolId:Y}=Z,X;try{let G=this.getToolConfig(Y)||void 0;if(G?.enabled===!1){if(Q)this.toolProviderRegistry.unregister(Y);return}if(!Q&&this.toolProviderRegistry.has(Y))return;let j=J.createProvider(G),B=J.getInitConfig?.(G)??G?.provider?.init??{},V=this.addToolTelemetryReporter(Y,B),K=this.createToolTelemetryForwarder(Y),U=J.getAuthFetcher?.(G)??G?.provider?.runtime?.authFetcher;X={provider:j,config:V,lazy:J.lazy??!0,authFetcher:U,onTelemetry:K}}catch(G){this.reportProviderRegisterFailure(G,Y);return}await this.registerProvider(Y,X)}createToolTelemetryForwarder(Z){return async(Q,J)=>{await this.emitTelemetry(Q,{...J||{},toolId:Z})}}addToolTelemetryReporter(Z,Q){let J=Q&&typeof Q==="object"?{...Q}:{},Y=typeof J.onTelemetry==="function"?J.onTelemetry:null,X=this.createToolTelemetryForwarder(Z);return J.onTelemetry=async(G,j)=>{if(Y)await Y(G,j);await X(G,j)},J}async registerProvider(Z,Q){try{this.toolProviderRegistry.register(Z,Q);let J={providerName:Q.provider.providerName};await this.hooks.onProviderRegistered?.(Z,J),await this.emitTelemetry("pie-toolkit-provider-registered",{toolId:Z,providerName:Q.provider.providerName})}catch(J){this.reportProviderRegisterFailure(J,Z)}}reportProviderRegisterFailure(Z,Q){console.warn(`[ToolkitCoordinator] Failed to register the provider of tool "${Q}":`,Z),this.reportStartFailure(Z,{phase:"provider-register",toolId:Q},[Q])}async ensureProviderReady(Z){return this.initializeProvider(Z,!1)}async initializeProvider(Z,Q){this.assertNotDisposed();let J=this.providerInitPromises.get(Z);if(J)return J;let Y=(async()=>{try{let X=await this.toolProviderRegistry.getProvider(Z,!1);if(this.assertNotDisposed(),this.toolProviderRegistry.isInitialized(Z))return X;let G={providerName:X.providerName};return await this.hooks.onProviderInitStart?.(Z,G),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(Z),this.assertNotDisposed(),X=await this.toolProviderRegistry.getProvider(Z,!1),await this.hooks.onProviderReady?.(Z,G),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{toolId:Z}),this.assertNotDisposed(),X}catch(X){if(X instanceof i)throw X;let G=X instanceof Error?X:Error(String(X));throw this.reportStartFailure(G,{phase:"provider-init",toolId:Z},this.toolRegistry.get(Z)?.provider?[Z]:[],Q),G}})().finally(()=>{this.providerInitPromises.delete(Z)});return this.providerInitPromises.set(Z,Y),Y}setHooks(Z){if(Object.assign(this.hooks,Z),this.setupStatePersistenceHooks(),this.disposePromise===null&&Z.onCoordinatorReady&&this.isReady())Promise.resolve(Z.onCoordinatorReady(this)).catch((Q)=>{this.handleError(Q,{phase:"coordinator-ready",recoverable:!1})})}subscribeTelemetry(Z){return this.telemetryListeners.add(Z),()=>{this.telemetryListeners.delete(Z)}}getSectionController(Z){let Q=this.sectionControllerKey(Z);return this.sectionControllers.get(this.getSectionControllerMapKey(Q))}subscribeSectionEvents(Z){if(this.activeCohortMapKey===null&&this.latestRequestedActiveCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Q=this.activeSubscriptions.get(Z.listener);if(Q)Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let J={listener:Z.listener,eventTypes:Z.eventTypes,itemIds:Z.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(Z.listener,J);let Y=this.activeCohortMapKey===null?void 0:this.sectionControllers.get(this.activeCohortMapKey);if(Y)this.bindSubscriptionToController(J,Y);let X=!1;return()=>{if(X)return;if(X=!0,J.unsubscribeCurrent?.(),J.unsubscribeCurrent=null,this.activeSubscriptions.get(Z.listener)===J)this.activeSubscriptions.delete(Z.listener)}}bindSubscriptionToController(Z,Q){Z.unsubscribeCurrent?.(),Z.unsubscribeCurrent=null;let J=Q.subscribe;if(typeof J!=="function")return;let Y=this.buildSectionEventPredicate(Z);Z.unsubscribeCurrent=J.call(Q,(j)=>{if(!Y(j))return;this.deliverSectionEventSafely(Z.listener,j)});let X=this.buildContentLoadedReplayEvents(Q);for(let j of X)if(Y(j))this.deliverSectionEventSafely(Z.listener,j);let G=this.buildLoadingCompleteReplayEvent(Q);if(G&&Y(G))this.deliverSectionEventSafely(Z.listener,G)}deliverSectionEventSafely(Z,Q){try{Z(Q)}catch(J){console.warn("[ToolkitCoordinator] section-event listener failed:",J)}}setActiveCohort(Z){if(this.activeCohortMapKey===Z)return;this.activeCohortMapKey=Z;let Q=this.sectionControllers.get(Z);if(!Q)return;for(let J of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(J,Q)}setActiveCohortIfLatestRequest(Z){if(this.latestRequestedActiveCohortMapKey!==Z)return;this.setActiveCohort(Z)}suspendActiveCohortIfSuperseded(Z){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===Z)return;this.activeCohortMapKey=null,this.detachActiveSubscriptions()}clearActiveCohortIfMatches(Z){if(this.activeCohortMapKey!==Z)return;this.activeCohortMapKey=null,this.detachActiveSubscriptions()}detachActiveSubscriptions(){for(let Z of Array.from(this.activeSubscriptions.values()))Z.unsubscribeCurrent?.(),Z.unsubscribeCurrent=null}buildSectionEventPredicate(Z){let Q=Z.eventTypes?new Set(Z.eventTypes):null,J=Z.itemIds?new Set(Z.itemIds):null;return(Y)=>{if(Q){let X=Y?.type;if(!X||!Q.has(X))return!1}if(!J)return!0;return Array.from(this.collectEventItemIds(Y)).some((X)=>J.has(X))}}collectEventItemIds(Z){let Q=new Set;if("itemId"in Z&&typeof Z.itemId==="string")Q.add(Z.itemId);if("canonicalItemId"in Z&&typeof Z.canonicalItemId==="string")Q.add(Z.canonicalItemId);if("currentItemId"in Z&&typeof Z.currentItemId==="string")Q.add(Z.currentItemId);if("previousItemId"in Z&&typeof Z.previousItemId==="string")Q.add(Z.previousItemId);return Q}buildContentLoadedReplayEvents(Z){let Q=Z.getRuntimeState?.(),J=Q?.loadedRenderables;if(!Array.isArray(J)||J.length===0)return[];let Y=typeof Q?.currentItemIndex==="number"&&Number.isFinite(Q.currentItemIndex)?Q.currentItemIndex:0,X=Date.now(),G=[];for(let j of J){if(!j)continue;let B=j.itemId,V=typeof j.canonicalItemId==="string"&&j.canonicalItemId?j.canonicalItemId:B;if(typeof B!=="string"||!B)continue;G.push({type:"content-loaded",contentKind:j.contentKind??"unknown",itemId:B,canonicalItemId:V,currentItemIndex:Y,timestamp:X})}return G}buildLoadingCompleteReplayEvent(Z){let Q=Z.getRuntimeState?.();if(Q?.loadingComplete!==!0)return null;let J=typeof Q.totalRegistered==="number"&&Number.isFinite(Q.totalRegistered)?Math.max(0,Q.totalRegistered):0,Y=typeof Q.totalLoaded==="number"&&Number.isFinite(Q.totalLoaded)?Math.max(0,Q.totalLoaded):J;return{type:"section-loading-complete",totalRegistered:J,totalLoaded:Y,currentItemIndex:Q.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||x2,itemIds:Z.itemIds,listener:Z.listener})}subscribeSectionLifecycleEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||k2,listener:Z.listener})}onSectionControllerLifecycle(Z){return this.sectionControllerLifecycleListeners.add(Z),()=>{this.sectionControllerLifecycleListeners.delete(Z)}}async getOrCreateSectionController(Z){if(this.disposePromise!==null)throw new i;let Q=this.sectionControllerKey(Z),J=this.getSectionControllerMapKey(Q);this.latestRequestedActiveCohortMapKey=J,this.suspendActiveCohortIfSuperseded(J);let Y;try{if(Y=await this.resolveExistingSectionController({mapKey:J,key:Q,input:Z.input,updateExisting:Z.updateExisting}),Y){if(this.disposePromise!==null)throw new i;if(Z.initialSession)await this.assignSessionToPublishedController(Y,Z.initialSession)}}catch(V){throw this.deliverSectionStartError(J,V),V}if(Y)return Y;let X=this.sectionControllerDisposePromises.get(J);if(X)await _Z([X]);if(this.disposePromise!==null)throw new i;let G=this.sectionControllerInitEntries.get(J);if(G){if(!Z.initialSession)return G.promise;let V=await G.promise;return await this.assignSessionToPublishedController(V,Z.initialSession),V}let j={retired:!1,candidateClaimed:!1},B=this.initializeNewSectionController({args:Z,key:Q,mapKey:J,token:j}).catch((V)=>{throw this.handleSectionControllerInitError(V,Z),this.deliverSectionStartError(J,V),V}).finally(()=>{if(this.sectionControllerInitEntries.get(J)?.token===j)this.sectionControllerInitEntries.delete(J)});return this.sectionControllerInitEntries.set(J,{key:Q,token:j,promise:B}),B}async resolveExistingSectionController(Z){let Q=this.sectionControllers.get(Z.mapKey);if(!Q)return;if(this.sectionControllerKeys.set(Z.mapKey,Z.key),Z.updateExisting!==!1)await Q.updateInput?.(Z.input);if(this.sectionControllers.get(Z.mapKey)!==Q)return;return this.setActiveCohortIfLatestRequest(Z.mapKey),Q}createSectionControllerContext(Z){return{key:Z.key,coordinator:this,input:Z.input}}async initializeNewSectionController(Z){let Q=this.createSectionControllerContext({key:Z.key,input:Z.args.input}),J=await this.resolveSectionPersistence(Q);if(this.disposePromise!==null||Z.token.retired){if(this.sectionPersistenceStrategies.get(Z.mapKey)===J)this.sectionPersistenceStrategies.delete(Z.mapKey);throw this.createSectionControllerRetirementError()}let Y={createDefaultController:Z.args.createDefaultController},X=await this.hooks.createSectionController?.(Q,Y)??await Y.createDefaultController(),G={mapKey:Z.mapKey,key:Z.key,controller:X,persistence:J,token:Z.token};try{await this.retireUnpublishedSectionControllerIfNeeded(G),await X.configureSessionPersistence?.({strategy:J,context:Q}),await this.retireUnpublishedSectionControllerIfNeeded(G),await X.initialize?.(Z.args.input),await this.retireUnpublishedSectionControllerIfNeeded(G);let j=Z.args.initialSession;if(j){if(!X.applySession)throw Error("Section controller cannot apply the session it was created with: it has no applySession.");await X.applySession(j,{mode:"replace"})}else await X.hydrate?.();return await this.finalizeSectionControllerReady({...G,context:Q}),X}catch(j){throw await this.cleanupUnpublishedSectionController(G),j}}async assignSessionToPublishedController(Z,Q){if(!Q)return;if(!Z.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");let J=Z5(Z.getSession?.()??null,Q);if(!J)return;await Z.applySession(J,{mode:"replace"})}createSectionControllerRetirementError(){return this.disposePromise!==null?new i:new Q5}async retireUnpublishedSectionControllerIfNeeded(Z){if(this.disposePromise===null&&!Z.token.retired)return;throw await this.cleanupUnpublishedSectionController(Z),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(Z){if(Z.token.candidateClaimed)return;Z.token.candidateClaimed=!0;try{await Z.controller.dispose?.()}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:Z.key.sectionId,attemptId:Z.key.attemptId},recoverable:!0})}finally{if(this.sectionPersistenceStrategies.get(Z.mapKey)===Z.persistence)this.sectionPersistenceStrategies.delete(Z.mapKey)}}retirePublishedSectionControllerIfNeeded(Z){if(this.disposePromise!==null&&!Z.token.retired)this.disposeSectionController({sectionId:Z.key.sectionId,attemptId:Z.key.attemptId});if(Z.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(Z){await this.retireUnpublishedSectionControllerIfNeeded(Z),this.sectionControllers.set(Z.mapKey,Z.controller),this.sectionControllerKeys.set(Z.mapKey,Z.key),Z.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(Z.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:Z.key,controller:Z.controller}),await this.hooks.onSectionControllerReady?.(Z.context,Z.controller),this.retirePublishedSectionControllerIfNeeded(Z),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:Z.key.assessmentId,sectionId:Z.key.sectionId,attemptId:Z.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(Z)}handleSectionControllerInitError(Z,Q){if(Z instanceof i||Z instanceof Q5)return;this.handleError(Z,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId},recoverable:!1},{sectionId:Q.sectionId,attemptId:Q.attemptId})}deliverSectionStartError(Z,Q){if(Q instanceof i||Q instanceof Q5||this.latestRequestedActiveCohortMapKey!==Z)return;let J={type:"section-error",source:"section-runtime",error:Q,currentItemIndex:0,timestamp:Date.now()};for(let Y of Array.from(this.activeSubscriptions.values()))if(this.buildSectionEventPredicate(Y)(J))this.deliverSectionEventSafely(Y.listener,J)}disposeSectionController(Z){let Q=this.sectionControllerKey(Z),J=this.getSectionControllerMapKey(Q),Y=this.sectionControllerInitEntries.get(J);if(Y)Y.token.retired=!0;let X=this.sectionControllers.get(J);if(!X){let K=this.sectionControllerDisposePromises.get(J);if(K)return K;if(!Y)return Promise.resolve();let U=_Z([Y.promise]).then(()=>{return});return this.trackSectionControllerDisposal(J,U)}let G=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:Q});let j=this.createSectionControllerContext({key:Q,input:void 0}),B=this.disposeSectionControllerEntry({args:Z,key:Q,context:j,controller:X,persistenceStrategy:G}),V=Y?_Z([Y.promise]).then(()=>B):B;return this.trackSectionControllerDisposal(J,V)}trackSectionControllerDisposal(Z,Q){this.sectionControllerDisposePromises.set(Z,Q);let J=()=>{if(this.sectionControllerDisposePromises.get(Z)===Q)this.sectionControllerDisposePromises.delete(Z)};return Q.then(J,J),Q}async disposeSectionControllerEntry(Z){try{await this.runSectionControllerDisposePipeline({key:Z.key,context:Z.context,controller:Z.controller,persistBeforeDispose:Z.args.persistBeforeDispose})}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:Z.args.sectionId,attemptId:Z.args.attemptId},recoverable:!0})}finally{await this.finalizeSectionControllerDispose({context:Z.context,persistenceStrategy:Z.persistenceStrategy,clearPersistence:Z.args.clearPersistence})}}async runSectionControllerDisposePipeline(Z){let Q=[];if(Z.persistBeforeDispose!==!1)try{await Z.controller.persist?.()}catch(J){Q.push(J)}try{await Z.controller.dispose?.()}catch(J){Q.push(J)}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?.(Z.context,Z.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:Z.key.assessmentId,sectionId:Z.key.sectionId,attemptId:Z.key.attemptId})}async finalizeSectionControllerDispose(Z){if(Z.clearPersistence)await Z.persistenceStrategy?.clearSession?.(Z.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let Z=[],Q=async(Y)=>{try{await Y()}catch(X){Z.push(X)}};await this.waitForAdmittedInitialization();let J=new Map;for(let[Y,X]of this.sectionControllerInitEntries)J.set(Y,X.key);for(let[Y,X]of this.sectionControllerKeys)J.set(Y,X);for(let Y of J.values())this.disposeSectionController({sectionId:Y.sectionId,attemptId:Y.attemptId});await _Z(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let Y of this.activeSubscriptions.values())await Q(()=>Y.unsubscribeCurrent?.()),Y.unsubscribeCurrent=null;if(this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Q(()=>this.ttsService.dispose()),await Q(()=>this.toolProviderRegistry.destroy()),await Q(()=>this.highlightCoordinator.destroy()),await Q(()=>this.ownedToolCoordinator.destroy()),await Q(()=>this.catalogResolver.destroy()),await Q(()=>this.toolRequests.dispose()),await Q(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.policyDiagnosticListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(Z.length===1)throw Z[0];if(Z.length>1)throw AggregateError(Z,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let Z=new Set;if(this.coordinatorReadyPromise)Z.add(this.coordinatorReadyPromise);if(this.ttsInitPromise)Z.add(this.ttsInitPromise);if(this.ttsReconfigurePromise)Z.add(this.ttsReconfigurePromise);for(let Q of this.providerInitPromises.values())Z.add(Q);await _Z(Z)}async ensureTTSReady(){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS().then(()=>this.assertNotDisposed()).finally(()=>{this.ttsInitPromise=void 0,this.notifyReadyChange()}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let Z=this.ttsReconfigurePromise;while(Z)await Z,Z=this.ttsReconfigurePromise}async _initializeTTS(){if(this.ttsInitialized)return;let Z=this.resolveTTSToolConfig(),Q=H7(Z),J=nZ(Q),Y=A7(Q);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("textToSpeech"))try{let j=await(await this.initializeProvider("textToSpeech",!0)).createInstance();await this.initializeTTSService(j,Y),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"});return}catch(G){if(G instanceof i)throw G;let j=G instanceof Error?G:Error(String(G));await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",operation:"tts-init",backend:J,fromProvider:"registry",toProvider:"browser",reason:j.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",j)}else if(J!=="browser")this.reportMissingTTSProvider(J);let X=new D7;try{await this.initializeTTSService(X,J==="browser"?Y:Q1(Y)),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(G){if(G instanceof i)throw G;let j=G instanceof Error?G:Error(String(G));throw this.reportStartFailure(j,{phase:"tts-init"},["textToSpeech"]),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:j.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:J,errorType:"TTSInitError",message:j.message}),j}}resolveTTSToolConfig(){return this.getTTSConfigFromProviders()||{}}async initializeTTSService(Z,Q){let J={...Q.providerOptions,__pieTelemetry:async(X,G)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...G||{}})}},Y={...Q,providerOptions:J};await this.ttsService.initialize(Z,Y),this.assertNotDisposed(),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,this.ttsDegraded=!1,this.degradedTools.delete("textToSpeech"),await this.hooks.onTTSReady?.(),this.assertNotDisposed()}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{if(await this.ensureStateLoaded(),this.assertNotDisposed(),this.ttsRequiredForReadiness())await this.startTTSForReadiness();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.stateLoadSettled||!this.hooks.loadToolState)&&(this.ttsInitialized||this.ttsDegraded||!this.ttsRequiredForReadiness())}ttsRequiredForReadiness(){if(this.getTTSConfigFromProviders()?.enabled===!1)return!1;return!this.lazyInit||this.isToolGranted("textToSpeech")}async startTTSForReadiness(){try{await this.ensureTTSReady()}catch(Z){if(Z instanceof i)throw Z;if(this.isToolGranted("textToSpeech"))throw Z;this.ttsDegraded=!0,this.notifyReadyChange()}}getTTSConfigFromProviders(){return this.config.tools?.providers?.textToSpeech}assertCanonicalToolId(Z){if(typeof Z!=="string"||Z.trim().length===0)throw Error("Tool id must be a non-empty string.");if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(Z))throw Error(`Unknown tool id "${Z}".`)}installToolContextResolvers(Z){if(!Z)return;for(let[Q,J]of Object.entries(Z)){if(J==null)continue;if(this.assertCanonicalToolId(Q),typeof J!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);this.toolContextResolvers.set(Q,J)}}setToolContextResolvers(Z){this.toolContextResolvers.clear(),this.installToolContextResolvers(Z??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let Z of this.toolContextResolverChangeListeners)try{Z()}catch(Q){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Q)}}getToolConfig(Z){return this.assertCanonicalToolId(Z),this.config.tools?.providers?.[Z]||null}updateToolConfig(Z,Q){this.assertCanonicalToolId(Z);let J=this.getToolConfig(Z)||{};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 Y={...this.config.tools.providers,[Z]:T2(Z,J,Q)},X=this.validateToolsConfig({...this.config.tools,providers:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});this.config.tools=X,this.policyEngine.updateInputs({tools:X}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:Z}),this._applyToolConfigChange(Z)}updateToolsPlacement(Z){if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});let Q=this.config.tools?.placement??{section:[],item:[],passage:[]},J={section:[...Z.section??Q.section??[]],item:[...Z.item??Q.item??[]],passage:[...Z.passage??Q.passage??[]]},Y=this.validateToolsConfig({...this.config.tools,placement:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});Y.placement=J,this.config.tools=Y,this.policyEngine.updateInputs({tools:Y})}decideToolPolicy(Z){let Q=this.policyEngine.decide(Z);return this.warnPolicyDiagnostics(Q.diagnostics),Q}warnPolicyDiagnostics(Z){for(let Q of Z){let J=Q.code==="tool-policy.itemSettingNotApplied"?Q.details.itemId:"",Y=`${Q.code}\x00${Q.toolId}\x00${J}`;if(this.reportedPolicyDiagnostics.has(Y))continue;this.reportedPolicyDiagnostics.set(Y,Q),console.warn(`[ToolkitCoordinator] ${Q.message}`);for(let X of Array.from(this.policyDiagnosticListeners))this.notifyPolicyDiagnosticListener(X,Q)}}notifyPolicyDiagnosticListener(Z,Q){try{Z(Q)}catch(J){console.error("[ToolkitCoordinator] Policy diagnostic listener failed:",J)}}registerItemSettings(Z,Q){return this.policyEngine.registerItemSettings(Z,Q)}decideFeaturePolicy(Z,Q){let J=this.policyEngine.decideFeature(Z,Q);if(this.warnPolicyDiagnostics(J.diagnostics),!J.assessmentBound&&this.policyEngine.getInputs().assessmentExpected&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${Z}" with no assessment bound, so profile, district and test-administration policy have nothing to read and only an item's requiredTools can grant. Pass the assessment to the toolkit's assessment property, or call updateAssessment(...), before relying on any accommodation. Reported once per coordinator.`);return J}reportFeatureDecisionApplied(Z,Q){if(Z.granted||Z.rule!=="support-conflict"||Z.overrode!=="attribute"&&Z.overrode!=="authored")return;let J=this.policyEngine.decideFeature(Z.featureId,Q);if(J.rule!=="support-conflict"||!J.withheldBy)return;this.warnPolicyDiagnostics([AZ(Z.featureId,J.withheldBy,Z.overrode)])}onPolicyChange(Z){return this.policyEngine.onPolicyChange(Z)}onPolicyDiagnostic(Z){this.policyDiagnosticListeners.add(Z);for(let Q of Array.from(this.reportedPolicyDiagnostics.values()))this.notifyPolicyDiagnosticListener(Z,Q);return()=>{this.policyDiagnosticListeners.delete(Z)}}onCatalogsChange(Z){return this.catalogResolver.onCatalogsChange(Z)}updateAssessment(Z){this.policyEngine.updateInputs({assessment:Z})}setPnpEnforcement(Z){this.policyEngine.updateInputs({pnpEnforcement:Z})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(Z){return this.policyEngine.registerPolicySource(Z)}hasToolContextResolver(Z){return this.assertCanonicalToolId(Z),this.toolContextResolvers.has(Z)}resolveToolContext(Z){this.assertCanonicalToolId(Z.toolId);let Q=this.toolContextResolvers.get(Z.toolId);if(!Q)return null;let J;try{J=Q(Z)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${Z.toolId}" threw:`,X),{toolId:Z.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!J)return{toolId:Z.toolId,visible:!0,params:{}};let Y=J.params&&typeof J.params==="object"&&!Array.isArray(J.params)?J.params:{};return{toolId:Z.toolId,visible:J.visible!==!1,params:Y,reason:typeof J.reason==="string"?J.reason:void 0}}onToolContextResolverChange(Z){return this.toolContextResolverChangeListeners.add(Z),()=>{this.toolContextResolverChangeListeners.delete(Z)}}getToolRegistry(){return this.toolRegistry}registerToolRequestTarget(Z){return this.toolRequests.registerTarget(Z)}requestTool(Z){return this.assertCanonicalToolId(Z.toolId),this.toolRequests.request(Z)}canRequestTool(Z,Q,J){try{this.assertCanonicalToolId(Z)}catch{return!1}return this.toolRequests.canRequest(Z,Q,J)}onToolRequestTargetsChange(Z){return this.toolRequests.onTargetsChange(Z)}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(Z){if(this.disposePromise!==null)return;if(Z==="textToSpeech"){this.scheduleTTSReconfigure();return}this._registerChangedToolProvider(Z)}_registerChangedToolProvider(Z){let Q=this.getProviderDescriptorTools().find((J)=>J.toolId===Z);if(!Q)return;this.degradedTools.delete(Z),this.registerProviderFromTool(Q,!0)}scheduleTTSReconfigure(){let Z=this.ttsInitPromise,Q=Z?Z.catch(()=>{}).then(()=>this._reconfigureTTSProvider()):this._reconfigureTTSProvider();this.ttsReconfigurePromise=Q,Q.finally(()=>{if(this.ttsReconfigurePromise===Q)this.ttsReconfigurePromise=void 0}),Q.then(async()=>{if(this.disposePromise!==null)return;if(this.ttsRequiredForReadiness())await this.startTTSForReadiness()}).catch(()=>{})}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsDegraded=!1,this.degradedTools.delete("textToSpeech"),this.ttsInitPromise=void 0,this.notifyReadyChange();try{this.ttsService.releaseProvider()}catch{}if(this.toolProviderRegistry.has("textToSpeech"))await this.toolProviderRegistry.unregister("textToSpeech");if(this.disposePromise!==null)return;let Z=this.getProviderDescriptorTools().find((Q)=>Q.toolId==="textToSpeech");if(!Z)return;await this.registerProviderFromTool(Z)}}var f2=()=>{};function F1(Z){return Z===R.PLAYING||Z===R.LOADING}function z1(Z){let{ttsService:Q,silence:J}=Z;if(typeof Q?.onStateChange!=="function")return f2;let Y=Q.onStateChange((X)=>{if(F1(X))J()});return()=>{try{Y()}catch{}}}function D1(Z){try{if(F1(Z?.getState?.()))Z?.pause?.()}catch{}}import{timedMediaProjectionSignature as BQ}from"@pie-players/pie-players-shared/timed-media";function H1(Z,Q,J){let Y=Z.detail?.runtimeId;if(typeof Y==="string"&&Y!=="")return Y===Q;return J(Z.target)}function A1(Z,Q,J){let Y=[Z.catalogResolver.registerOwner({owner:{kind:Q.kind,itemId:Q.itemId,canonicalItemId:Q.canonicalItemId,assessmentId:J.assessmentId,sectionId:J.sectionId},entity:Q.item})];if(Q.kind==="item"&&Q.settings)Y.push(Z.registerItemSettings(Q.canonicalItemId||Q.itemId,Q.settings));return Y}var I2=["a[href]","button","label","summary",...["button","checkbox","combobox","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","switch","tab","treeitem"].map((Z)=>`[role="${Z}"]`)].join(", "),_1=new Set(["mi","mn","mtext"]),v2=(Z)=>_1.has(Z.localName)||Z.localName==="mrow"&&Z.children.length===1&&_1.has(Z.children[0].localName),h2=(Z)=>Array.from(Z.getElementsByTagName("mfrac")).every((Q)=>Array.from(Q.children).every(v2))?"Fraction_Over":"Fraction_General",m2=(Z)=>!Z||Z.toLowerCase().split("-")[0]==="en",u2=(Z)=>{if(Z.localName!=="label")return Z;let Q=Z;if(Q.control)return Q.control;let J=Q.getAttribute("for"),Y=Q.getRootNode();return(J?Y.getElementById?.(J):null)??Q.querySelector("input, select, textarea, button")},O1=(Z,Q)=>{let J=u2(Z),Y=J?.getAttribute("aria-labelledby")?.split(/\s+/).filter(Boolean);if(!J||!Y?.length)return!1;let X=J.getRootNode(),G=Y.map((j)=>X.getElementById?.(j)??null).filter((j)=>j!==null);return G.length>0&&!G.some((j)=>j.contains(Q))};function M1(Z,Q={}){if(typeof MutationObserver>"u")return()=>{};let J=new Map,Y=!1,X=async(U,$,z)=>{let D=await e0([{type:"math",mathml:U,fallbackText:""}],{language:z,loadSre:Q.loadSre,mathSpeech:{...m2(z)?{style:h2($)}:{},engineOptions:Q.getMathSpeech?.()?.engineOptions}});return D.usedMathSpeech?D.speechText:null},G=(U)=>{let $=v5(U,I2);if(!$||O1($,U))return;let z=b0(U,"math"),D=z&&t0(z.outerHTML);if(!z||!D)return;let M=u8(U,{contentLanguage:Q.getContentLanguage?.()}),P=`${M??""}\x00${D}`,H=J.get(P);if(!H)H=X(D,z,M),J.set(P,H);H.then((N)=>{if(Y||!N||!U.isConnected)return;if(O1($,U))return;if(U.getAttribute("aria-label")!==N)U.setAttribute("aria-label",N)})},j=new WeakSet,B=(U)=>{if(j.has(U))return;j.add(U),K.observe(U,{childList:!0,subtree:!0})},V=(U)=>{if(U.nodeType!==1)return;let $=U,z=v5($,"mjx-container");if(z){G(z);return}if($.shadowRoot)B($.shadowRoot);UZ($,(D)=>{if(D.nodeType!==1)return"skip";let M=D;if(M.localName==="mjx-container")return G(M),"skip";if(M.shadowRoot)B(M.shadowRoot);return})},K=new MutationObserver((U)=>{for(let $ of U)for(let z of $.addedNodes)V(z)});return B(Z),V(Z),()=>{Y=!0,K.disconnect()}}import{createPieLogger as g2,isGlobalDebugEnabled as c2}from"@pie-players/pie-players-shared";function p2(Z,Q){if(Z===Q)return 0;let J=Z.compareDocumentPosition(Q);if(J&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(J&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class C7{shellsByElement=new Map;register(Z){let Q=this.shellsByElement.get(Z.element),J={...Z,sortKey:Date.now()};if(Q&&Q.kind===J.kind&&Q.itemId===J.itemId&&Q.canonicalItemId===J.canonicalItemId)return!1;return this.shellsByElement.set(Z.element,J),!0}unregister(Z){return this.shellsByElement.delete(Z)}getOrderedShells(Z){let Q=Array.from(this.shellsByElement.values()).filter((J)=>!Z||J.kind===Z);return Q.sort((J,Y)=>p2(J.element,Y.element)),Q}getCanonicalIdMap(){let Z={};for(let Q of this.getOrderedShells("item")){if(!Q.itemId)continue;Z[Q.itemId]=Q.canonicalItemId||Q.itemId}return Z}clear(){this.shellsByElement.clear()}}var L1=g2("section-controller-binding",()=>c2());function d2(Z){let Q=Z?.renderables;if(!Array.isArray(Q))return null;let J=new Set;for(let Y of Q){let X=Y?.entity?.id;if(typeof X==="string"&&X)J.add(X)}return J}function P1(Z,Q){return Z.has(Q.itemId)||!!Q.canonicalItemId&&Z.has(Q.canonicalItemId)}class b7{registry=new C7;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;sectionRenderableIds=null;boundSections=new Map;loadedRenderableKeys=new Set;async initialize(Z){this.activeInitToken+=1;let Q=this.activeInitToken;this.coordinator=Z.coordinator,this.sectionId=Z.sectionId,this.attemptId=Z.attemptId,this.forgetUnregisteredLoads(Z.coordinator.getSectionController({sectionId:Z.sectionId,attemptId:Z.attemptId}));let J;try{J=await Z.coordinator.getOrCreateSectionController({sectionId:Z.sectionId,attemptId:Z.attemptId,input:{section:Z.section,sectionId:Z.sectionId,assessmentId:Z.assessmentId,view:Z.view},updateExisting:!0,initialSession:Z.initialSession,createDefaultController:Z.createDefaultController})}catch(X){if(Q===this.activeInitToken)this.unsubscribeController?.(),this.unsubscribeController=null,this.controller=null;throw X}if(Q!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=J,this.sectionRenderableIds=d2(J.getCompositionModel?.());let Y=this.getSectionKey(Z.sectionId,Z.attemptId);this.boundSections.delete(Y),this.boundSections.set(Y,{sectionId:Z.sectionId,attemptId:Z.attemptId,renderableIds:this.sectionRenderableIds}),this.replayRegisteredShellsIntoController(J),Z.onCompositionChanged?.(J.getCompositionModel?.()),this.unsubscribeController=J.subscribe?.((X)=>{try{Z.onControllerEvent?.(X)}catch(G){L1.warn("onControllerEvent handler threw",G)}Z.onCompositionChanged?.(J.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(Z){if(!Z.handleContentRegistered)return;let Q=this.registry.getOrderedShells().filter((Y)=>this.isSectionRenderable(Y));if(Q.length===0)return;for(let Y of Q){let X=Y.canonicalItemId||Y.itemId;Z.handleContentRegistered({itemId:Y.itemId,canonicalItemId:X,contentKind:Y.contentKind||Y.kind})}let J=Date.now();for(let Y of Q){let X=Y.canonicalItemId||Y.itemId,G=this.getLoadedKey(X,Y.contentKind);if(this.loadedRenderableKeys.has(G))Z.handleContentLoaded?.({itemId:Y.itemId,canonicalItemId:X,contentKind:Y.contentKind||Y.kind,timestamp:J})}}getLoadedKey(Z,Q){return`${Q??""}:${Z}`}isSectionRenderable(Z){let Q=this.sectionRenderableIds;return!Q||P1(Q,Z)}getSectionKey(Z,Q){return`${Z}\x00${Q??""}`}controllerFor(Z){if(this.isSectionRenderable(Z))return this.controller;let Q=this.getSectionKey(this.sectionId,this.attemptId),J=[...this.boundSections.entries()].reverse();for(let[Y,X]of J){if(Y===Q||!X.renderableIds)continue;if(!P1(X.renderableIds,Z))continue;let G=this.coordinator?.getSectionController({sectionId:X.sectionId,attemptId:X.attemptId});if(G)return G}return null}requireControllerFor(Z,Q){let J=this.controllerFor(Z);if(!J)L1.warn(`Dropped ${Q} for "${Z.itemId}": no section this toolkit bound renders it.`);return J}forgetUnregisteredLoads(Z){if(!Z||Z===this.controller)return;let Q=Z.getRuntimeState?.()?.loadedRenderables??[];if(Q.length===0)return;let J=new Set;for(let Y of this.registry.getOrderedShells())if(J.add(Y.itemId),Y.canonicalItemId)J.add(Y.canonicalItemId);for(let Y of Q){if(J.has(Y.canonicalItemId)||J.has(Y.itemId))continue;Z.handleContentUnregistered?.({itemId:Y.itemId,canonicalItemId:Y.canonicalItemId,contentKind:Y.contentKind})}}register(Z){return this.registry.register(Z)}unregister(Z){return this.registry.unregister(Z)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(Z){return this.registry.getCanonicalIdMap()[Z]||this.controller?.getCanonicalItemId?.(Z)||Z}handleContentRegistered(Z){if(!this.isSectionRenderable(Z))return;this.controller?.handleContentRegistered?.({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId||Z.itemId,contentKind:Z.contentKind||Z.kind})}handleContentUnregistered(Z){let Q=Z.canonicalItemId||Z.itemId,J=this.getLoadedKey(Q,Z.contentKind);if(this.registry.getOrderedShells().some((X)=>this.getLoadedKey(X.canonicalItemId||X.itemId,X.contentKind)===J))return;this.loadedRenderableKeys.delete(J),this.controllerFor(Z)?.handleContentUnregistered?.({itemId:Z.itemId,canonicalItemId:Q,contentKind:Z.contentKind||Z.kind})}handleContentLoaded(Z){let Q=Z.canonicalItemId||Z.itemId;if(this.loadedRenderableKeys.add(this.getLoadedKey(Q,Z.contentKind)),!this.isSectionRenderable(Z))return;this.controller?.handleContentLoaded?.(Z)}handleItemPlayerError(Z){this.requireControllerFor(Z,"an item player error")?.handleItemPlayerError?.(Z)}reportSectionError(Z){(Z.itemId?this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId},"a section error"):this.controller)?.reportSectionError?.(Z)}updateItemSession(Z,Q){let J=this.getCanonicalItemId(Z);return this.requireControllerFor({itemId:Z,canonicalItemId:J},"a session update")?.updateItemSession?.(J,Q)??null}navigateToItem(Z){return this.controller?.navigateToItem?.(Z)??null}handleFormativeAction(Z){if(!Z?.itemId)return;let Q=Z.canonicalItemId||this.getCanonicalItemId(Z.itemId),J=this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Q},"a formative action");if(Z.action==="retry"){J?.retryFormativeItem?.({itemId:Q});return}J?.recordFormativeTry?.({itemId:Q,outcomes:Z.outcomes})}handleMediaTimeSource(Z){if(!Z?.renderableId)return;let Q=this.requireControllerFor({itemId:Z.renderableId,canonicalItemId:this.getCanonicalItemId(Z.renderableId)},"a media time source");if(Z.action==="detach"){Q?.detachMediaTimeSource?.({origin:Z.origin??"host"});return}if(!Z.source)return;Q?.attachMediaTimeSource?.(Z.source,{origin:Z.origin??"host",renderableId:Z.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}async dispose(){this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null;let Z=this.coordinator;if(Z)for(let Q of this.boundSections.values())await Z.disposeSectionController({sectionId:Q.sectionId,attemptId:Q.attemptId});this.registry.clear(),this.loadedRenderableKeys.clear(),this.boundSections.clear(),this.controller=null,this.sectionRenderableIds=null,this.coordinator=null}}function N1(Z){let Q=Z.section?.identifier;return Z.sectionId||(typeof Q==="string"?Q:"")||`section-${Z.assessmentId||"default"}`}function w1(Z,Q){return["pnpEnforcement","assessment"].filter((Y)=>Z?!Object.is(Z[Y],Q[Y]):Q[Y]!==null)}function C1(Z){if(!Z)return;let Q=Symbol.for("pie.assessmentToolkit.unclaimedRegistrationWatch"),J=Z;if(J[Q])return;J[Q]=!0,Z.addEventListener(J5,(Y)=>{let X=Y.detail,G=typeof X?.itemId==="string"?X.itemId:"";R1(Z,"unclaimedRegistration",`[pie-assessment-toolkit] Item "${G}" registered, but no toolkit claimed the registration, so its accessibility catalogs are not filed and it does not count toward its section's loading. Render its shell or scope inside the <pie-assessment-toolkit> that answered it. Reported once per page.`)})}function OZ(Z,Q){if(typeof Z==="function")return Z;if(Z===null)return null;return typeof Q==="function"?Q:null}function b1(Z={}){let Q=Z.frameDeadlineMs??100,J=!1,Y=null,X=null,G=null,j=null,B=null;function V(){if(J=!1,X!==null)j?.(X),X=null;if(G!==null)B?.(G),G=null;j=null,B=null}function K(z){if(!J)return;if(z==="frame")X=null;if(z==="timer")G=null;let D=Y;Y=null,V(),D?.()}function U(z){if(Y=z,J)return;J=!0;let D=globalThis,M=OZ(Z.requestFrame,D.requestAnimationFrame);j=OZ(Z.cancelFrame,D.cancelAnimationFrame);let P=OZ(Z.setTimer,D.setTimeout);if(B=OZ(Z.clearTimer,D.clearTimeout),M){let N=M(()=>K("frame"));if(!J)return;if(X=N,P){let O=P(()=>K("timer"),Q);if(J)G=O}return}let H=OZ(Z.queueMicrotaskFn,D.queueMicrotask);if(H){H(()=>K("microtask"));return}if(P){let N=P(()=>K("timer"),0);if(J)G=N;return}K("microtask")}function $(){if(!J)return;Y=null,V()}return{schedule:U,cancel:$,isPending:()=>J}}function E1(Z="runtime"){return`${Z}-${Math.random().toString(16).slice(2)}-${Date.now()}`}function S1(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function T1(Z){Z.lastSessionEventSignatureByItemId.clear(),Z.lastMetadataSignatureByItemId.clear()}function y1(Z){let{state:Q,itemId:J,payload:Y}=Z;if(l2(Y)){let j=s2(Y);if(Q.lastMetadataSignatureByItemId.get(J)===j)return!1;Q.lastMetadataSignatureByItemId.set(J,j)}let X=i2(Y);if(Q.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(J,X),!0}function i2(Z){let Q={...Z};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function l2(Z){return Z.intent==="metadata-only"}function s2(Z){try{return JSON.stringify({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId,intent:Z.intent,complete:Z.complete??null,component:Z.component??null})}catch{return String(Z.itemId||"")}}var n2=(Z,Q)=>{if(customElements.get(Z))return;try{customElements.define(Z,Q)}catch(J){if(!(J instanceof DOMException&&J.name==="NotSupportedError"||J&&typeof J==="object"&&J.name==="NotSupportedError")||!customElements.get(Z))throw J}},WQ=y7('<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>'),VQ=y7('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),KQ={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 J4(Z,Q){I1(Q,!0),d1(Z,KQ);let J=ZQ("pie-assessment-toolkit",()=>QQ()),Y=E1("toolkit"),X=new b7,G=new qZ,j={mode:"gather",role:"student"},B={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},V="Unable to initialize assessment toolkit.",K=f(Q,"assessmentId",7,""),U=f(Q,"section",7,null),$=f(Q,"sectionId",7,""),z=f(Q,"attemptId",7,""),D=f(Q,"env",23,()=>({})),M=f(Q,"ndsIcons",7,!1),P=f(Q,"locale",7,""),H=f(Q,"i18n",7,null),N=f(Q,"contentLanguage",7,""),O=f(Q,"lazyInit",7,!1),C=f(Q,"toolConfigStrictness",7,"error"),E=f(Q,"tools",23,()=>({})),v=f(Q,"toolContextResolvers",7,null),S=f(Q,"enabledTools",7,""),u=f(Q,"toolRegistry",7,null),t=f(Q,"accessibility",23,()=>({})),n=f(Q,"player",7,null),K0=f(Q,"playerType",7,""),e=f(Q,"coordinator",7,null),A0=f(Q,"createSectionController",7,null),_0=f(Q,"onFrameworkError",7,null),MZ=f(Q,"errorRenderer",7,null),LZ=f(Q,"assessment",7,null),q0=f(Q,"isolation",7,"inherit"),O0=f(Q,"session",7,null),YZ=s(null),p=s(null),J0=s(null),x7=null,k7=null,XZ=!1,p0=null,g0=null,c0=null,d0=null,PZ=s(0),W5=s(null),Y0=s(null),V5=s(V),K5=s(h1([])),f7="",q5="",GZ=null,jZ=null,NZ=null,I7=null,U5=null,v7=null,wZ=null,h7=!1,m7=null,u7=!1,p7=s(""),$5=null,RZ=b1(),M0=[],CZ=new Map,F5=new WeakMap,bZ=new Map,g7=S1(),BZ=s(!1);function Y4(){if(!F(YZ))return null;let W=F(YZ).getRootNode();if(W&&"host"in W)return W.host;return F(YZ).parentElement}let x=c(()=>Y4());function L0(W,q){if(!F(x)){M0=[...M0,{name:W,detail:q}];return}T7(F(x),W,q)}T(()=>{if(!F(x))return;if(M0.length===0)return;let W=M0;M0=[],queueMicrotask(()=>{let q=F(x);if(!q){M0=[...W,...M0];return}for(let A of W)T7(q,A.name,A.detail)})});function c7(W){return W.details.length>0?W.details:[W.message]}function X4(W){if(!MZ())return{title:V,details:c7(W)};try{let q=MZ()(W)||{};return{title:typeof q.title==="string"&&q.title.trim().length>0?q.title:V,details:Array.isArray(q.details)&&q.details.length>0?q.details.map((A)=>String(A)):c7(W)}}catch(q){let A=q instanceof Error&&q.message.trim().length>0?q.message:String(q||"Unknown renderer error");return{title:V,details:[...W.details,`Error renderer failed: ${A}`]}}}function P0(W){let q=I5({kind:W.kind,source:W.source,error:W.error,recoverable:W.recoverable,scope:W.cohort?"cohort":"runtime",cohort:W.cohort});return G.reportFrameworkError(q),q}function d7(W){return(W||[]).map((q)=>q?.message).filter((q)=>typeof q==="string")}function G4(W,q){if(W?.type==="timed-media-policy-degraded"){G.reportFrameworkError(kZ({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:d7(W.degradations),recoverable:!0,scope:"cohort",cohort:q}));return}if(W?.type!=="timed-media-invalid")return;G.reportFrameworkError(kZ({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:d7(W.errors),recoverable:!1,scope:"cohort",cohort:q}))}function j4(W){if(W?.type!=="timed-media-audio-started")return;if(!F(b))return;D1(F(b).ttsService)}function B4(W){return W==="coordinator-init"||W==="runtime-init"||W==="tool-config"}function WZ(W){return`${W.kind}|${W.source}|${W.message}`}function i7(W){if(!_0())return;try{_0()(W),f7=WZ(W)}catch(q){console.error(`[pie-framework:${W.kind}:${W.source}] framework error hook failed`,q)}}let l7=new WeakSet,s7=new WeakMap;function W4(W){if(typeof W!=="object"||W===null)return null;return s7.get(W)??null}function n7(W){let q=X4(W);h(Y0,W,!0),h(V5,q.title,!0),h(K5,q.details,!0)}function r7(){h(Y0,null),h(V5,V),h(K5,[],!0)}T(()=>{let W=G.subscribeFrameworkErrors((q)=>{if(console.error(R8(q),q.cause),typeof q.cause==="object"&&q.cause!==null)s7.set(q.cause,q);if(B4(q.kind)&&!l7.has(q))n7(q);L0("framework-error",q),i7(q)});return()=>{W()}}),T(()=>{let W=e();if(!W||F(b)!==W)return;if(typeof W.subscribeFrameworkErrors!=="function")return;return I(()=>W.subscribeFrameworkErrors((q)=>{l7.add(q),G.reportFrameworkError(q)}))}),T(()=>{let W=F(b),q=u();if(!W||F(TZ))return;if(typeof W.adoptToolRegistry!=="function")return;I(()=>{let A=W===F(p);if(A&&!q)return;if(W.adoptToolRegistry(q)&&A&&GZ)GZ={...GZ,toolRegistry:q}})}),T(()=>{if(!F(Y0))return;if(f7===WZ(F(Y0)))return;i7(F(Y0))});function V4(W){let q=5381;for(let A=0;A<W.length;A+=1)q=(q<<5)+q^W.charCodeAt(A);return(q>>>0).toString(36)}function r(W){return W&&typeof W==="object"?W:{}}function K4(W){let q=r(W.section),A=typeof q.identifier==="string"?q.identifier:"",w=typeof W.sectionId==="string"?W.sectionId:"";return A||w}function q4(W){return typeof W.currentItemIndex==="number"?W.currentItemIndex:-1}function U4(W){return(Array.isArray(W.renderables)?W.renderables:[]).map((A,w)=>{let L=r(A),_=r(L.entity),l=typeof _.id==="string"&&_.id||`renderable-${w}`,yZ=r(_.config),L5=typeof _.version==="string"&&_.version||(typeof _.version==="number"?String(_.version):"")||(typeof yZ.version==="string"?yZ.version:"");return{id:l,version:L5}})}function $4(W){let q=r(W.itemSessionsByItemId);return Object.keys(q).sort((A,w)=>A.localeCompare(w)).map((A)=>{let w=r(q[A]),L=typeof w.id==="string"?w.id:"",_=Array.isArray(w.data)?w.data:[],l="";try{l=V4(JSON.stringify(_))}catch{l=String(_.length)}return{itemId:A,sessionId:L,payloadSignature:l}})}function F4(W){let q=r(r(W.formative).states);return Object.entries(q).map(([A,w])=>{let L=r(w),_=r(L.lastOutcome).correctness??"";return`${A}:${L.tryCount??0}:${L.revealed===!0?1:0}:${String(_)}:${String(L.revealOverride??"")}`}).sort().join("|")}function z4(W){let q=W.timedMedia;return BQ(q)}function D4(W){let q=r(W),A=U4(q).map((L)=>`${L.id}:${L.version}`).join("|"),w=$4(q).map((L)=>`${L.itemId}:${L.sessionId}:${L.payloadSignature}`).join("|");return{sectionId:K4(q),currentItemIndex:q4(q),renderableSignature:A,itemSessionSignature:w,formativeSignature:F4(q),timedMediaSignature:z4(q)}}function H4(W){let q=D4(W);return`${q.sectionId}|${q.currentItemIndex}|${q.renderableSignature}|${q.itemSessionSignature}|${q.formativeSignature}|${q.timedMediaSignature}`}function a7(W){return W==="iife"||W==="esm"||W==="preloaded"||W==="custom"}function A4(W,q){let A=W?.type,w=a7(A)?A:a7(q)?q:W?.tagName?"custom":"iife",L=W?.tagName?.trim();if(w==="custom"&&!L)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:w,tagName:L||B[w],version:W?.version,source:W?.source,loaderConfig:W?.loaderConfig,loaderOptions:W?.loaderOptions,isDefault:!W&&!q}}function o7(W){let q=W||{},A=typeof q.mode==="string"&&q.mode.trim()?q.mode.trim():j.mode,w=typeof q.role==="string"&&q.role.trim()?q.role.trim():j.role;return{mode:A,role:w}}function _4(W){let q=o7(W);if(q.mode==="author")return"author";if(q.role==="instructor")return"scorer";return"candidate"}function t7(W,q){return W.sectionId===q.sectionId&&W.attemptId===q.attemptId}function e7(){if(!O0()||O0()===I7)return;I7=O0(),NZ={value:O0(),cohort:{sectionId:F(Z0),attemptId:z()||void 0}}}function Z8(W,q){e7();let A=NZ;if(!A)return null;if(!t7(A.cohort,W)){if(q)NZ=null;return null}return NZ=null,A.value}function Q8(){let W=U5,q=F(b);if(!W||!q)return;let A=Z8(W,!1);if(!A)return;let w=q.getSectionController(W);if(!w)return;let L=Z5(w.getSession?.()??null,A);if(!L)return;Promise.resolve().then(()=>{if(!w.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");return w.applySession(L,{mode:"replace"})}).catch((_)=>{P0({kind:"unknown",source:"pie-assessment-toolkit",error:_,recoverable:!0})})}async function O4(){if(A0())return A0()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function z5(){let W=E()||{},q=r1(S());if(q.length===0)return W;let A=W.placement||{},w=Array.isArray(A.section)?A.section:null;if(w&&w.length>0)return W;return{...W,placement:{...A,section:q}}}function M4(){return $8(z5(),{strictness:C(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:u()}).config}function L4(){let W="",q="";try{W=JSON.stringify(z5())}catch{W="[unserializable-tools]"}try{q=JSON.stringify(Object.entries(v()??{}).map(([A,w])=>[A,typeof w]))}catch{q="[unserializable-resolvers]"}return[K()||"",String(C()||"error"),W,q].join("|")}function P4(W){let q=W?.pnpEnforcement;return q==="on"||q==="off"?q:null}function N4(W){let q=K()||U()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new R7({assessmentId:q,lazyInit:O(),eagerInit:!1,toolConfigStrictness:C(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:W,toolRegistry:u(),toolContextResolvers:v(),accessibility:t(),frameworkErrorBus:G})}function J8(W){try{return JSON.stringify(W??null)}catch{return"[unserializable]"}}function Y8(){return{signatures:{assessmentId:K()||"",toolConfigStrictness:String(C()||"error"),lazyInit:String(O()),tools:J8({...z5(),pnpEnforcement:void 0}),accessibility:J8(t())},toolRegistry:u()}}function w4(){let W=GZ;if(!W)return[];let q=Y8(),A=Object.keys(q.signatures).filter((w)=>q.signatures[w]!==W.signatures[w]);if(W.toolRegistry&&q.toolRegistry!==W.toolRegistry)A.push("toolRegistry");return A}function R4(W,q){if(h7)return;h7=!0,console.warn(`[pie-assessment-toolkit] ${W.join(", ")} changed after ${q} with the coordinator this toolkit built, and that coordinator keeps the values it was built with. Set these inputs no later than the section or the first item scope, pass a coordinator of your own, or update this one from runtime-ready with updateToolConfig(...) or updateToolsPlacement(...). Reported once per toolkit.`)}function C4(W){if(u7)return;u7=!0,console.warn(`[pie-assessment-toolkit] The toolkit above this one (runtime "${W}") had no coordinator when this one connected, so this one built its own and keeps it: the two share no tool state, policy or read-aloud. Give the outer toolkit its coordinator before the inner one connects, or set isolation="force" on the inner one to keep them apart on purpose. Reported once per toolkit.`)}function EZ(){let W=F(p);if(!W)return Promise.resolve();return h(p,null),W.dispose()}function SZ(W){P0({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}let TZ=c(()=>!e()&&q0()!=="force"&&F(J0)?.coordinator!=null),b=c(()=>{if(F(TZ))return F(J0)?.coordinator;return e()||F(p)}),D5=c(()=>U()!=null);T(()=>{F(x),e(),q0(),F(J0),v(),F(D5),F(BZ),E(),S(),K(),C(),O(),t(),u(),I(()=>{if(!F(x))return;if(e()){if(F(p))EZ().catch(SZ);p0=null;return}if(q0()!=="force"&&F(J0)?.coordinator){if(F(p))EZ().catch(SZ);p0=null;return}if(F(p)){let W=w4();if(W.length>0&&jZ)R4(W,jZ);else if(W.length>0&&(U()||F(BZ)))EZ().catch(SZ)}if(F(p)&&p0!==v()){try{F(p).setToolContextResolvers(v()),p0=v()}catch(W){P0({kind:"coordinator-init",source:"pie-assessment-toolkit",error:W})}return}if(!F(p)){if(q0()!=="force"&&!XZ){let q=x1(F(x),B5);if(q?.coordinator&&q.runtimeId!==Y){h(J0,q,!0),p0=null;return}}let W=L4();if(q5===W)return;try{let q=M4();h(p,N4(q),!0),XZ=q0()!=="force",GZ=Y8(),jZ=null,p0=v(),q5="",r7()}catch(q){h(p,null),q5=W,P0({kind:"coordinator-init",source:"pie-assessment-toolkit",error:q})}}})}),T(()=>{if(!F(BZ)||!F(b))return;let W=F(b);I(()=>{if(W===F(p))jZ??="an item registered"})});let X8=YQ(),N0=c(()=>H()??X8),VZ=s(0);T(()=>{return F(N0).subscribe?.(()=>{h(VZ,F(VZ)+1)})}),T(()=>{let W=typeof P()==="string"?P().trim():"",q=F(N0);if(!W&&q!==X8)return;I(()=>{Promise.resolve(q.setLocale(W||XQ)).catch((A)=>{P0({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:A instanceof Error?A:Error(String(A)),recoverable:!0})})})});let b4=c(()=>{return F(VZ),{locale:F(N0).getLocale(),direction:F(N0).getDirection?.()??"ltr"}});T(()=>{F(VZ);let W=F(x);if(!W)return;jQ(W,F(N0))});let w0=c(()=>K()||F(b)?.assessmentId||""),Z0=c(()=>N1({sectionId:$(),section:U(),assessmentId:K()})),H5=c(()=>o7(D())),E4=c(()=>_4(F(H5))),i0=c(()=>A4(n(),K0())),KZ=c(()=>t2({player:F(i0),component:"pie-assessment-toolkit"})),S4=c(()=>{if(!F(b))return null;return{toolkitCoordinator:F(b),toolCoordinator:F(b).toolCoordinator,ttsService:F(b).ttsService,highlightCoordinator:F(b).highlightCoordinator,catalogResolver:F(b).catalogResolver,elementToolStateStore:F(b).elementToolStateStore,assessmentId:F(w0),sectionId:F(Z0),attemptId:z()||void 0,itemPlayer:F(i0),ndsIcons:M()===!0,locale:(F(VZ),F(N0).getLocale()),i18n:F(N0),contentLanguage:N()?.trim()||void 0,contentLanguageDefault:GQ({contentLanguage:N(),interfaceLocale:P()}),reportSectionError:(W)=>{X.reportSectionError({source:"section-runtime",error:W,timestamp:Date.now()})}}}),T4=c(()=>{if(!F(b)||!F(x))return null;return{runtimeId:Y,coordinator:F(b),sectionBound:F(D5),eventTarget:F(x)}});function G8(W){if(W==null)return;let q=H4(W);if(q===F(p7))return;h(p7,q,!0),h(PZ,F(PZ)+1),h(W5,W,!0),L0("composition-changed",{composition:F(W5),version:F(PZ)})}function A5(W){$5=W??X.getCompositionModel(),RZ.schedule(()=>{G8($5)})}function y4(){if(!RZ.isPending())return;RZ.cancel(),G8($5)}function _5(W){if(!W)return;let q=F5.get(W);if(!q)return;for(let A of q)A();F5.delete(W)}function j8(){for(let W of CZ.values())_5(W.element)}function B8(W){if(_5(W.element),!F(b))return;F5.set(W.element,A1(F(b),W,{assessmentId:F(w0),sectionId:F(Z0)}))}function x4(){j8();for(let W of CZ.values())B8(W)}function O5(W){if(!W)return;bZ.get(W)?.(),bZ.delete(W)}function k4(W){O5(W),bZ.set(W,M1(W,{getMathSpeech:()=>F(b)?.ttsService.getMathSpeechOptions(),getContentLanguage:()=>N()}))}function f4(W){let A={...W.result?.eventDetail||W.fallbackSession,itemId:W.itemId,canonicalItemId:W.canonicalItemId||W.itemId,sourceRuntimeId:Y};if(!y1({state:g7,itemId:W.itemId,payload:A}))return;L0("session-changed",A)}function I4(W){if(!(W instanceof HTMLElement))return!1;return x1(W,B5)?.runtimeId===Y}function R0(W){return W.detail??null}function v4(W,q){for(let A of q)W.addEventListener(A.name,A.handler);return()=>{for(let A of q)W.removeEventListener(A.name,A.handler)}}T(()=>{let W=F(x),q=q0();return I(()=>{if(!W)return;if(q==="force")return h(J0,null),()=>{XZ=!1};let A=n1(W,(w)=>{if(w.runtimeId===Y)return;if(XZ){C4(w.runtimeId);return}h(J0,w,!0)});return()=>{A(),h(J0,null),XZ=!1}})}),T(()=>{let W=F(b);if(!W)return;return I(()=>z1({ttsService:W.ttsService,silence:()=>X.requestMediaPauseForCompetingAudio()}))}),T(()=>{let W=F(TZ)?F(J0)?.runtimeId??null:null,q=W?"inherited":"owned";if(q!==x7)x7=q,L0(q==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:W})}),T(()=>{let W=F(x);if(!W)return;I(()=>C1(W.ownerDocument))}),T(()=>{let W=F(b);if(!W)return;let q=F(TZ)?"inherited":"owned";I(()=>{if(W===k7)return;k7=W,L0("runtime-ready",{runtimeId:Y,coordinator:W,ownership:q})})}),T(()=>{let W=F(Z0),q=z()||"";T1(g7)}),T(()=>{if(!F(x))return;F(x).setAttribute("data-item-player-type",F(i0).type),F(x).setAttribute("data-item-player-tag",F(i0).tagName),F(x).setAttribute("data-env-mode",F(H5).mode),F(x).setAttribute("data-env-role",F(H5).role)}),T(()=>{return F(b),F(w0),F(Z0),x4(),()=>{j8()}}),T(()=>{if(!F(x))return;return o2({host:F(x),instrumentationProvider:F(KZ),component:"pie-assessment-toolkit",eventMap:e2,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:F(w0),sectionId:F(Z0),attemptId:z()||void 0}})});let M5=null;T(()=>{LZ(),E();let W=F(b);if(!W)return;if(W!==F(p))return;I(()=>{let q={pnpEnforcement:P4(E()),assessment:LZ()??null},A=M5?.coordinator===W?M5.inputs:null;M5={coordinator:W,inputs:q};for(let w of w1(A,q))if(w==="pnpEnforcement")W.setPnpEnforcement(q.pnpEnforcement);else W.updateAssessment(q.assessment)})}),T(()=>{if(!F(b))return;return F(b).subscribeTelemetry(({eventName:W,payload:q})=>{if(!JQ(F(KZ)))return;if(!F(KZ).isReady())return;let A=new Date().toISOString(),w={...q||{},instrumentationLayer:"toolkit",assessmentId:F(w0),sectionId:F(Z0),attemptId:z()||void 0,component:"pie-assessment-toolkit",sourceEventName:W,timestamp:A};F(KZ).trackEvent(W,w);let L=q&&typeof q.errorType==="string"?q.errorType:void 0;if(!W.endsWith("-error")&&!L)return;let _=q&&typeof q.message==="string"?q.message:`Toolkit telemetry error: ${W}`;F(KZ).trackError(Error(_),{component:"pie-assessment-toolkit",errorType:L||"ToolkitTelemetryError",...w})})}),T(()=>{if(!U()||!F(b))return;let W=!1;if(F(b)===I(()=>F(p)))jZ??="a section initialized";let q={sectionId:F(Z0),attemptId:z()||void 0},A=v7;if(v7=q,A&&!t7(A,q))I(()=>k1(F(x),{reason:"teardown",logger:J}));U5=null;let w=I(()=>Z8(q,!0));return X.initialize({coordinator:F(b),section:U(),sectionId:F(Z0),assessmentId:F(w0),attemptId:z()||void 0,view:F(E4),initialSession:w,createDefaultController:O4,onCompositionChanged:(L)=>{if(W)return;A5(L)},onControllerEvent:(L)=>{if(W)return;j4(L),G4(L,q)}}).then(()=>{if(W)return;U5=q;let L=I(()=>F(Y0));if(L&&WZ(L)===wZ)r7();wZ=null,I(()=>Q8()),I(()=>y4()),queueMicrotask(()=>{if(W)return;L0("toolkit-ready",{runtimeId:Y,assessmentId:F(w0),sectionId:F(Z0),itemPlayer:F(i0),coordinator:F(b)}),L0("section-ready",{sectionId:q.sectionId,attemptId:q.attemptId,controller:F(b).getSectionController(q)??null})})}).catch((L)=>{if(W)return;let _=I(()=>W4(L));if(_)I(()=>n7(_)),wZ=WZ(_);else wZ=WZ(P0({kind:"runtime-init",source:"pie-assessment-toolkit",error:L,cohort:q}))}),()=>{W=!0}}),T(()=>{O0(),I(()=>{e7(),Q8()})}),T(()=>{if(!F(x))return;let W=F(x),q=(L)=>{if(!H1(L,Y,I4))return!1;return L.stopPropagation(),!0},w=v4(W,[{name:J5,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.element||!_?.itemId)return;let l=X.register(_);if(CZ.set(_.element,_),h(BZ,!0),B8(_),k4(_.element),X.handleContentRegistered(_),l)A5()}},{name:a1,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;let l=_?.element?X.unregister(_.element):!1;if(_5(_.element),O5(_.element),_.element)CZ.delete(_.element);if(X.handleContentUnregistered(_),l)A5()}},{name:o1,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;let l=X.updateItemSession(_.itemId,_.session);f4({itemId:_.itemId,canonicalItemId:X.getCanonicalItemId(_.itemId),result:l,fallbackSession:_.session})}},{name:t1,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;X.handleContentLoaded({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,detail:_.detail,timestamp:Date.now()})}},{name:e1,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;X.handleItemPlayerError({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,error:_.error,timestamp:Date.now()})}},{name:Z4,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;if(_.action!=="check"&&_.action!=="retry")return;X.handleFormativeAction({itemId:_.itemId,canonicalItemId:_.canonicalItemId,action:_.action,outcomes:_.outcomes})}},{name:Q4,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.renderableId)return;if(_.action!=="attach"&&_.action!=="detach")return;X.handleMediaTimeSource({renderableId:_.renderableId,action:_.action,source:_.source,origin:_.origin})}}]);return()=>{I(()=>k1(W,{reason:"teardown",logger:J})),w();for(let L of[...bZ.keys()])O5(L)}}),T(()=>{if(!F(x))return;return()=>{c0?.disconnect(),c0=null,g0?.disconnect(),g0=null,d0?.disconnect(),d0=null}}),T(()=>{let W=F(x),q=F(T4);if(!W||!q)return;I(()=>{if(c0){c0.setValue(q);return}c0=new E7(W,{context:B5,initialValue:q}),c0.connect()})}),T(()=>{let W=F(x),q=F(S4);if(!W||!q)return;I(()=>{if(g0){g0.setValue(q);return}g0=new E7(W,{context:s1,initialValue:q}),g0.connect()})}),T(()=>{let W=F(x),q=F(b4);if(!W)return;I(()=>{if(d0){d0.setValue(q);return}d0=new E7(W,{context:a2,initialValue:q}),d0.connect()})});async function h4(){if(!F(b))throw Error("Coordinator not initialized");await F(b).waitUntilReady()}function m4(W){if(!F(b))throw Error("Coordinator not initialized");F(b).setHooks(W)}function u4(W){return X.navigateToItem(W)}function p4(){return X.getCompositionModel()}function g4(){return F(i0)}async function c4(){await X.persist()}async function d4(){await X.hydrate()}T(()=>{let W=F(b);if(!W)return;let q=F(PZ)>0||F(W5)!==null,A=!F(D5)&&F(BZ);if(!q&&!A)return;I(()=>{if(W===m7)return;m7=W,W.waitUntilReady().catch(()=>{})})}),T(()=>{return()=>{RZ.cancel(),X.dispose().catch((W)=>{P0({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}).then(()=>EZ()).catch(SZ).finally(()=>{G.dispose()})}});var i4={waitUntilReady:h4,setHooks:m4,navigateToItem:u4,getCompositionModel:p4,getItemPlayerConfig:g4,persist:c4,hydrate:d4,get assessmentId(){return K()},set assessmentId(W){K(W),k()},get section(){return U()},set section(W){U(W),k()},get sectionId(){return $()},set sectionId(W){$(W),k()},get attemptId(){return z()},set attemptId(W){z(W),k()},get env(){return D()},set env(W){D(W),k()},get ndsIcons(){return M()},set ndsIcons(W){M(W),k()},get locale(){return P()},set locale(W){P(W),k()},get i18n(){return H()},set i18n(W){H(W),k()},get contentLanguage(){return N()},set contentLanguage(W){N(W),k()},get lazyInit(){return O()},set lazyInit(W){O(W),k()},get toolConfigStrictness(){return C()},set toolConfigStrictness(W){C(W),k()},get tools(){return E()},set tools(W){E(W),k()},get toolContextResolvers(){return v()},set toolContextResolvers(W){v(W),k()},get enabledTools(){return S()},set enabledTools(W){S(W),k()},get toolRegistry(){return u()},set toolRegistry(W){u(W),k()},get accessibility(){return t()},set accessibility(W){t(W),k()},get player(){return n()},set player(W){n(W),k()},get playerType(){return K0()},set playerType(W){K0(W),k()},get coordinator(){return e()},set coordinator(W){e(W),k()},get createSectionController(){return A0()},set createSectionController(W){A0(W),k()},get onFrameworkError(){return _0()},set onFrameworkError(W){_0(W),k()},get errorRenderer(){return MZ()},set errorRenderer(W){MZ(W),k()},get assessment(){return LZ()},set assessment(W){LZ(W),k()},get isolation(){return q0()},set isolation(W){q0(W),k()},get session(){return O0()},set session(W){O0(W),k()}},W8=VQ(),V8=S7(W8);i1(V8,(W)=>h(YZ,W),()=>F(YZ));var l4=X5(V8,2);{var s4=(W)=>{var q=WQ(),A=m1(q),w=Y5(A,!0),L=X5(A,2),_=Y5(L,!0),l=X5(L,2),yZ=Y5(l,!0);f1(q),u1((L5)=>{j5(w,F(V5)),j5(_,F(Y0).message),j5(yZ,L5)},[()=>F(K5).join(`
|
|
225
|
-
`)]),
|
|
223
|
+
`}return Y}function K1(Z){let{request:Q,tools:J,pnpPolicy:Y,customSources:X,contextId:G}=Z,j=new L7(G);j.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=_0(J.placement[Q.level]),V=_0(J.policy.allowed),K=new Set(_0(J.policy.blocked)),U=[];for(let D of B)U.push(D),j.addDecision({precedence:0,rule:"placement-membership",featureId:D,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(U=U.filter((D)=>{if(J.providers?.[D]?.enabled===!1)return j.addDecision({precedence:0,rule:"provider-disabled",featureId:D,action:"block",sourceType:"host",reason:`tools.providers.${D}.enabled === false`,value:!1}),!1;return!0}),V.length>0){let D=new Set(V);U=U.filter((P)=>{if(!D.has(P))return j.addDecision({precedence:0,rule:"host-allowlist",featureId:P,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:V}),!1;return!0})}U=U.filter((D)=>{if(K.has(D))return j.addDecision({precedence:0,rule:"host-blocked",featureId:D,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:J.policy.blocked}),!1;return!0});let $=[],z=new Set(U),H=null;if(Y.enforcement==="on"&&Y.source&&(Y.assessment||Y.item)){if(H=Y.source.apply({assessment:Y.assessment,item:Y.item}),H.sources.assessment)j.addSource("assessment",H.sources.assessment);if(H.sources.student)j.addSource("student",H.sources.student);if(H.sources.item)j.addSource("item",H.sources.item);for(let M of H.decisions)j.addDecision({precedence:M.precedence,rule:M.rule,featureId:M.featureId,action:M.action,sourceType:M.sourceType,reason:M.reason,value:M.value});for(let[M,C]of H.blockedOverrides)$.push(P7(M,C,Q.level));for(let[M,C]of H.supportConflicts){if(!z.has(M))continue;$.push(_Z(M,C.support,C.grant??"placement",Q.level))}let{blockedToolIds:D}=H;U=U.filter((M)=>!D.has(M));let P=new Set(Object.values(J.placement).flatMap(_0));for(let[M,C]of H.mandates){if(z.has(M))continue;if(!B.includes(M)&&P.has(M))continue;let E=y2(M,{placedAtAnyLevel:P,allTools:J.placement,allowed:V,blocked:K,providers:J.providers}),v={rule:C,hostRule:E.hostRule,hostValue:E.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:M,message:E.hostRule==="placement-missing"?`Profile policy mandates "${M}" (${C}), but no level of tools.placement lists it.`:`Profile policy mandates "${M}" (${C}), but host policy removes it via ${E.hostRule}.`,details:v}),j.addDecision({precedence:0,rule:"required-tool-blocked",featureId:M,action:"advisory",sourceType:"host",reason:`Host removed required tool "${M}" via ${E.hostRule}`,value:v})}}for(let D=0;D<X.length;D++){let P=X[D],M=U.slice(),C=P.refine({request:Q,candidates:M}),E=new Set(C.refinedCandidates);for(let S of C.refinedCandidates)if(!M.includes(S))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:S,message:`Custom source "${P.id}" tried to add tool "${S}" that was not in candidates; ignored.`,details:{customSourceId:P.id}}),E.delete(S);U=M.filter((S)=>E.has(S));let v=new Set;if(C.decisions){for(let S of C.decisions)if(j.addDecision({precedence:S.precedence??100+D,rule:S.rule,featureId:S.featureId,action:S.action,sourceType:S.sourceType,reason:S.reason,value:S.value}),S.action==="block")v.add(S.featureId)}for(let S of M){if(E.has(S))continue;if(v.has(S))continue;j.addDecision({precedence:100+D,rule:"custom-source",featureId:S,action:"block",sourceType:"custom",reason:`Custom policy source "${P.id}" removed tool "${S}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:P.id}})}}for(let D of U)for(let P of Z.unappliedItems??[]){let M=["restrictedTools","requiredTools"].filter((E)=>P.settings[E]?.includes(D)===!0);if(M.length===0)continue;let C={itemId:P.id,settings:M,toolbarLevel:Q.scope.level};$.push({code:"tool-policy.itemSettingNotApplied",level:Q.level,toolId:D,message:`Item "${P.id}" names "${D}" in ${M.join(" and ")}, but "${D}" is on the ${Q.scope.level}-level toolbar, which item settings do not reach. Place "${D}" at item level to enforce the setting per item.`,details:C})}let O=new Set(U),N=U.map((D)=>{let P=H?.perToolFlags.get(D);return{toolId:D,required:P?.required??!1,alwaysAvailable:P?.alwaysAvailable??!1,activateAtInit:P?.activateAtInit??!1,parameters:oZ(D,Y.assessment,Y.item)}});return j.reconcileFinalStates(O),{visibleTools:N,diagnostics:$,provenance:j.build()}}function y2(Z,Q){if(!Q.placedAtAnyLevel.has(Z))return{hostRule:"placement-missing",hostValue:Q.allTools};if(Q.providers?.[Z]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Q.allowed.length>0&&!Q.allowed.includes(Z))return{hostRule:"host-allowlist",hostValue:Q.allowed};if(Q.blocked.has(Z))return{hostRule:"host-blocked",hostValue:Array.from(Q.blocked)};return{hostRule:"placement-missing",hostValue:Q.allTools}}var N7={"district-block":"settings.districtPolicy.blockedTools","test-admin-override":"settings.testAdministration.toolOverrides","item-restriction":"item settings.restrictedTools","pnp-prohibited":"personalNeedsProfile.prohibitedSupports","support-conflict":"a withholding support in personalNeedsProfile.supports","item-requirement":"item settings.requiredTools","district-requirement":"settings.districtPolicy.requiredTools","pnp-support":"personalNeedsProfile.supports","pnp-activate-at-init":"personalNeedsProfile.activateAtInit"};function P7(Z,Q,J){return{code:"tool-policy.overrideBlocked",...J?{level:J}:{},toolId:Z,message:`settings.testAdministration.toolOverrides grants "${Z}", but ${N7[Q]} withdraws it and outranks a granting override.`,details:{rule:Q}}}function _Z(Z,Q,J,Y){let X=J==="placement"?"tools.placement":J==="attribute"?"The item player's attribute":J==="authored"?"The item's authored content":N7[J];return{code:"tool-policy.supportConflict",...Y?{level:Y}:{},toolId:Z,message:`${X} serves "${Z}", but the student's "${Q}" support withholds it.`,details:{support:Q,servedBy:J}}}function q1(Z,Q){let J=Q.map((Y)=>N7[Y]).join(", ");return{code:"tool-policy.unknownSupportId",toolId:Z,message:`No tool is registered under "${Z}", named in ${J}, so it matches nothing. These lists name tools by tool id.`,details:{origins:[...Q]}}}var T2=(Z)=>`No assessment is bound, so no policy source could grant "${Z}"`;function w7(Z,Q,J,Y){return{featureId:Z,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 (${J.join(", ")})`,required:!1,assessmentBound:Y.assessmentBound,diagnostics:[]}}function U1(Z,Q,J,Y){let X=Q.decisions[0],G=Array.from(Q.perToolFlags.values())[0],j=X?.action==="enable",B=X?.reason??`Feature "${Z}" not configured`,V=X!==void 0&&X.action!=="skip",K=Q.supportConflicts.get(Z);return{featureId:Z,granted:j,action:X?.action??"skip",rule:V?X.rule:"none",precedence:V?X.precedence:null,sourceType:X?.sourceType??"system",reason:J.assessmentBound||j?B:T2(Z),required:Boolean(G?.required),parameters:Y,...V&&X.rule==="support-conflict"&&K?{withheldBy:K.support}:{},assessmentBound:J.assessmentBound,diagnostics:[...Array.from(Q.blockedOverrides,([U,$])=>P7(U,$)),...Array.from(Q.supportConflicts).flatMap(([U,{support:$,grant:z}])=>z?[_Z(U,$,z)]:[])]}}var u0=(Z)=>Array.isArray(Z)&&Z.length>0;function x2(Z){if(!Z)return!1;let Q=Z.personalNeedsProfile;if(Q&&(u0(Q.supports)||u0(Q.prohibitedSupports)||u0(Q.activateAtInit)))return!0;let J=Z.settings;if(J){let Y=J.districtPolicy;if(Y&&(u0(Y.blockedTools)||u0(Y.requiredTools)))return!0;let X=J.testAdministration?.toolOverrides;if(X&&typeof X==="object"&&Object.keys(X).length>0)return!0}return!1}function k2(Z){if(!Z)return!1;return u0(Z.requiredTools)||u0(Z.restrictedTools)}function $1(Z){if(x2(Z.assessment))return"on";if(k2(Z.itemSettings))return"on";return"off"}class tZ{id="pnp";toolRegistry;supportConflicts;withheldBy=new Map;registrylessIds=new Set;constructor(Z,Q=[]){this.toolRegistry=Z,this.supportConflicts=Q;for(let{support:J,withholds:Y}of Q){this.registrylessIds.add(J);for(let X of Y){this.registrylessIds.add(X);let G=this.withheldBy.get(X)??[];G.push(J),this.withheldBy.set(X,G)}}}apply(Z){let{ctx:Q,result:J}=this.prepare(Z),{pnp:Y,districtPolicy:X,testAdmin:G,itemSettings:j}=Q,B=new Set;Y?.supports?.forEach((V)=>B.add(V)),Y?.prohibitedSupports?.forEach((V)=>B.add(V)),Y?.activateAtInit?.forEach((V)=>B.add(V)),X?.blockedTools?.forEach((V)=>B.add(V)),X?.requiredTools?.forEach((V)=>B.add(V));for(let V of Object.keys(G?.toolOverrides??{}))B.add(V);j?.requiredTools?.forEach((V)=>B.add(V)),j?.restrictedTools?.forEach((V)=>B.add(V));for(let{support:V,withholds:K}of this.supportConflicts)if(this.supportInEffect(V,Q))K.forEach((U)=>B.add(U));for(let V of B)this.resolveSupport(V,Q,J);return J}resolveFeature(Z,Q){let{ctx:J,result:Y}=this.prepare(Q);return this.resolveSupport(Z,J,Y),Y}prepare(Z){let{assessment:Q,item:J}=Z,Y=Q?.personalNeedsProfile,X=Q?.settings,G=J?.settings,j=R7();if(X?.districtPolicy||X?.testAdministration)j.sources.assessment={id:Q?.id||"unknown",name:Q?.name||Q?.id||"Assessment",config:X};if(Y)j.sources.student={id:"student",name:"Student PNP Profile",config:Y};if(J)j.sources.item={id:J.id,name:J.id,config:J.settings};return{ctx:{pnp:Y,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:G},result:j}}supportInEffect(Z,Q){let J=R7();return this.resolveSupport(Z,Q,J,!1),J.decisions[0]?.action==="enable"}resolveSupport(Z,Q,J,Y=!0){if(Q.districtPolicy?.blockedTools?.includes(Z)){J.blockedToolIds.add(Z),J.decisions.push({precedence:1,rule:"district-block",featureId:Z,action:"block",sourceType:"assessment",reason:`District policy blocks "${Z}" for all assessments`,value:Q.districtPolicy.blockedTools});return}let X=Q.testAdmin?.toolOverrides?.[Z];if(X===!1){J.blockedToolIds.add(Z),J.decisions.push({precedence:2,rule:"test-admin-override",featureId:Z,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${Z}" for this session`,value:Q.testAdmin?.toolOverrides});return}if(Q.itemSettings?.restrictedTools?.includes(Z)){if(J.blockedToolIds.add(Z),X===!0)J.blockedOverrides.set(Z,"item-restriction");J.decisions.push({precedence:3,rule:"item-restriction",featureId:Z,action:"block",sourceType:"item",reason:`Item restricts "${Z}" (e.g., mental math question blocks calculator)`,value:Q.itemSettings.restrictedTools});return}if(Q.pnp?.prohibitedSupports?.includes(Z)){if(J.blockedToolIds.add(Z),X===!0)J.blockedOverrides.set(Z,"pnp-prohibited");J.decisions.push({precedence:4,rule:"pnp-prohibited",featureId:Z,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${Z}"`,value:Q.pnp.prohibitedSupports});return}let G=Y?this.withheldBy.get(Z)?.find((V)=>this.supportInEffect(V,Q)):void 0;if(G){let V=R7();this.resolveSupport(Z,Q,V,!1);let K=V.decisions[0];J.blockedToolIds.add(Z),J.supportConflicts.set(Z,{support:G,...K?.action==="enable"?{grant:K.rule}:{}}),J.decisions.push({precedence:4,rule:"support-conflict",featureId:Z,action:"block",sourceType:"student",reason:`"${Z}" is withheld while the student's "${G}" support is in effect`,value:{support:G}});return}let j=Q.pnp?.activateAtInit?.includes(Z)===!0,B=Q.itemSettings?.requiredTools?.includes(Z)?"item-requirement":Q.districtPolicy?.requiredTools?.includes(Z)?"district-requirement":void 0;if(X===!0){if(B)J.mandates.set(Z,B);J.perToolFlags.set(Z,{required:B!==void 0,alwaysAvailable:!0,activateAtInit:j,rule:"test-admin-override"}),J.decisions.push({precedence:5,rule:"test-admin-override",featureId:Z,action:"enable",sourceType:"assessment",reason:`Test administrator enabled "${Z}" for this session`,value:Q.testAdmin?.toolOverrides});return}if(B==="item-requirement"){J.mandates.set(Z,B),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,activateAtInit:j,rule:"item-requirement"}),J.decisions.push({precedence:6,rule:"item-requirement",featureId:Z,action:"enable",sourceType:"item",reason:`Item requires "${Z}" for this question`,value:Q.itemSettings?.requiredTools});return}if(B==="district-requirement"){J.mandates.set(Z,B),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,activateAtInit:j,rule:"district-requirement"}),J.decisions.push({precedence:7,rule:"district-requirement",featureId:Z,action:"enable",sourceType:"assessment",reason:`District policy requires "${Z}" for all assessments`,value:Q.districtPolicy?.requiredTools});return}if(j){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,activateAtInit:j,rule:"pnp-activate-at-init"}),J.decisions.push({precedence:8,rule:"pnp-activate-at-init",featureId:Z,action:"enable",sourceType:"student",reason:`Student PNP profile turns on "${Z}" at start`,value:Q.pnp?.activateAtInit});return}if(Q.pnp?.supports?.includes(Z)){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,activateAtInit:!1,rule:"pnp-support"}),J.decisions.push({precedence:8,rule:"pnp-support",featureId:Z,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${Z}"`,value:Q.pnp.supports});return}J.decisions.push({precedence:8,rule:"pnp-support",featureId:Z,action:"skip",sourceType:"system",reason:`Feature "${Z}" not configured at any level`,value:{supportId:Z}})}unknownSupportIds(Z,Q){let J=new Map;if(this.toolRegistry.getAllTools().length===0)return J;let Y=Z?.personalNeedsProfile,X=Z?.settings,G=[["district-block",X?.districtPolicy?.blockedTools],["test-admin-override",Object.keys(X?.testAdministration?.toolOverrides??{})],["item-restriction",Q.flatMap((j)=>j.restrictedTools??[])],["pnp-prohibited",Y?.prohibitedSupports],["item-requirement",Q.flatMap((j)=>j.requiredTools??[])],["district-requirement",X?.districtPolicy?.requiredTools],["pnp-activate-at-init",Y?.activateAtInit],["pnp-support",Y?.supports]];for(let[j,B]of G)for(let V of B??[]){if(this.toolRegistry.has(V)||this.registrylessIds.has(V))continue;let K=J.get(V)??[];if(!K.includes(j))K.push(j);J.set(V,K)}return J}}function R7(){return{blockedToolIds:new Set,mandates:new Map,perToolFlags:new Map,decisions:[],blockedOverrides:new Map,supportConflicts:new Map,sources:{}}}var F1=s0({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class eZ{toolRegistry;unsubscribeRegistry;contextId;assessmentOptional;pnpPolicySource;supportConflicts;customSources;listeners=new Set;tools;assessment;pnpEnforcementOverride;itemSettings=new Map;inputDiagnostics=Object.freeze([]);disposed=!1;constructor(Z){this.toolRegistry=Z.toolRegistry,this.contextId=Z.contextId??"tool-policy",this.assessmentOptional=Z.assessmentOptional===!0,this.supportConflicts=Z.supportConflicts??[],this.pnpPolicySource=new tZ(this.toolRegistry,this.supportConflicts),this.customSources=Z.customSources?[...Z.customSources]:[];let Q=Z.inputs??{};this.tools=Q.tools??F1,this.assessment=Q.assessment??null,this.pnpEnforcementOverride=Q.pnpEnforcement??null,this.refreshInputDiagnostics(),this.unsubscribeRegistry=this.watchRegistry()}decide(Z){this.assertNotDisposed();let Q=Z.scope.scopeId?`${this.contextId}:${Z.level}:${Z.scope.scopeId}`:`${this.contextId}:${Z.level}`,J=Z.level==="item"?this.itemForScope(Z.scope):void 0,Y=Z.level!=="item"||Z.scope.level==="section"||Z.scope.level==="assessment";return K1({request:Z,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,item:J,enforcement:this.enforcementFor(J)},unappliedItems:Y?this.enforcedItems():void 0,customSources:this.customSources,contextId:Q})}grantsFeatureAnywhere(Z,Q={}){let J=(Y)=>!Q.enforced||this.enforcementFor(Y)==="on";if(J()&&this.decideFeature(Z).granted)return!0;for(let Y of this.itemSettings.keys()){let X=this.itemSettingsFor(Y);if(!J(X?{id:Y,settings:X}:void 0))continue;if(this.decideFeature(Z,{level:"item",scopeId:Y}).granted)return!0}return!1}registerItemSettings(Z,Q){this.assertNotDisposed();let J={settings:Q},Y=this.itemSettingsFor(Z),X=this.itemSettings.get(Z)??[];return X.push(J),this.itemSettings.set(Z,X),this.emitIfItemSettingsChanged(Z,Y),()=>{if(this.disposed)return;let G=this.itemSettings.get(Z),j=G?.indexOf(J)??-1;if(!G||j<0)return;let B=this.itemSettingsFor(Z);if(G.splice(j,1),G.length===0)this.itemSettings.delete(Z);this.emitIfItemSettingsChanged(Z,B)}}decideFeature(Z,Q){this.assertNotDisposed();let J=this.hostFeatureGate(Z);if(J)return J;let Y=this.itemForScope(Q);return U1(Z,this.pnpPolicySource.resolveFeature(Z,{assessment:this.assessment??void 0,item:Y}),{assessmentBound:this.assessment!==null},oZ(Z,this.assessment,Y))}hostFeatureGate(Z){let Q={assessmentBound:this.assessment!==null},J=_0(this.tools.policy.blocked);if(J.includes(Z))return w7(Z,"host-blocked",J,Q);let Y=_0(this.tools.policy.allowed);if(Y.length>0&&!Y.includes(Z))return w7(Z,"host-allowlist",Y,Q);return null}getVisibleToolIds(Z,Q){return this.decide({level:Z,scope:{level:Z,scopeId:Q}}).visibleTools.map((J)=>J.toolId)}updateInputs(Z){this.assertNotDisposed();let Q=!1,J=!1;if("tools"in Z){let Y=Z.tools??F1;if(!Object.is(this.tools,Y))this.tools=Y,Q=!0}if("assessment"in Z){let Y=Z.assessment??null,X=!p0(this.assessment,Y);if(this.assessment=Y,X)Q=!0,this.refreshInputDiagnostics()}if("pnpEnforcement"in Z){let Y=Z.pnpEnforcement??null;if(this.pnpEnforcementOverride!==Y)this.pnpEnforcementOverride=Y,J=!0}if(Q||J)this.emit({reason:J&&!Q?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}replaceToolRegistry(Z,Q){this.assertNotDisposed(),this.unsubscribeRegistry(),this.toolRegistry=Z,this.pnpPolicySource=new tZ(Z,this.supportConflicts),this.unsubscribeRegistry=this.watchRegistry(),this.tools=Q,this.refreshInputDiagnostics(),this.emit({reason:"inputs",inputs:this.snapshotInputs()})}registerPolicySource(Z){return this.assertNotDisposed(),this.customSources.push(Z),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Q=this.customSources.indexOf(Z);if(Q===-1)return;if(this.customSources.splice(Q,1),this.disposed)return;this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}onPolicyChange(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.unsubscribeRegistry(),this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.itemSettings.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,pnpEnforcement:this.enforcementFor(),pnpEnforcementOverride:this.pnpEnforcementOverride,assessmentExpected:!this.assessmentOptional||this.pnpEnforcementOverride==="on",diagnostics:this.inputDiagnostics})}enforcementFor(Z){return this.pnpEnforcementOverride??$1({assessment:this.assessment,itemSettings:Z?.settings})}itemSettingsFor(Z){return this.itemSettings.get(Z)?.at(-1)?.settings}emitIfItemSettingsChanged(Z,Q){if(p0(Q,this.itemSettingsFor(Z)))return;this.refreshInputDiagnostics(),this.emit({reason:"item-settings",inputs:this.snapshotInputs()})}refreshInputDiagnostics(){let Z=[];for(let J of this.itemSettings.keys()){let Y=this.itemSettingsFor(J);if(Y)Z.push(Y)}let Q=Array.from(this.pnpPolicySource.unknownSupportIds(this.assessment,Z),([J,Y])=>q1(J,Y));if(p0(this.inputDiagnostics,Q))return!1;return this.inputDiagnostics=Object.freeze(Q),!0}watchRegistry(){return this.toolRegistry.onRegistryChange(()=>{if(this.disposed)return;if(this.refreshInputDiagnostics())this.emit({reason:"inputs",inputs:this.snapshotInputs()})})}itemForScope(Z){if(Z?.level!=="item")return;let Q=Z.canonicalItemId||Z.itemId||Z.scopeId,J=Q?this.itemSettingsFor(Q):void 0;return J?{id:Q,settings:J}:void 0}enforcedItems(){let Z=[];for(let Q of this.itemSettings.keys()){let J=this.itemSettingsFor(Q);if(!J)continue;let Y={id:Q,settings:J};if(this.enforcementFor(Y)==="on")Z.push(Y)}return Z}emit(Z){for(let Q of Array.from(this.listeners))try{Q(Z)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}import{hasResponseField as f2,hasResponseValue as z1}from"@pie-players/pie-players-shared/pie";import{isPlainRecord as YZ}from"@pie-players/pie-players-shared/object";function Z5(Z){return YZ(Z)&&YZ(Z.session)?Z.session:Z}function I2(Z,Q){let J=YZ(Z)?Z:{},Y=YZ(Q)?Q:{},X=new Set([...Object.keys(J),...Object.keys(Y)]);for(let G of X)if(!p0(Z5(J[G]),Z5(Y[G])))return!1;return!0}function v2(Z,Q){for(let[J,Y]of Object.entries(Z)){if(Y===void 0)continue;if(J==="itemSessions"){if(!I2(Y,Q.itemSessions))return!1;continue}if(!p0(Y,Q[J]))return!1}return!0}function Q5(Z,Q){if(!Z)return Q;let J=YZ(Q.itemSessions)?{...Q.itemSessions}:{},Y=YZ(Z.itemSessions)?Z.itemSessions:{};for(let[G,j]of Object.entries(Y)){if(!z1(Z5(j)))continue;let B=Z5(J[G]);if(z1(B)||f2(B))continue;J[G]=j}let X={...Q,itemSessions:J};return v2(X,Z)?null:X}var H1=[{support:"screenReader",withholds:["textToSpeech","autoplayAudio"]}];class s extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class J5 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var h2=(Z,Q,J)=>{let Y={...Q,...J},X=W1(Z,Q,J);if(X)Y.mathSpeech=X;return Y},m2={"tool-module-load":"failed to load","tool-request-open":"failed to open on request","tool-request-host-check":"failed its toolbar's host check","tool-visibility":"failed its relevance check","tool-applicability":"failed its applicability check","tool-state-load":"failed to restore its state","tool-state-save":"failed to save its state","tool-playback":"failed during playback"},u2=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],p2=["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 b7{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;tts;stateLoadSettled=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;degradedTools=new Map;reportedToolFailures=new Set;readyChangeListeners=new Set;eagerInit;toolRegistry;toolRegistrySupplied;toolRegistrySettled;toolRegistryAbsent=!1;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new O7((Z,Q,J)=>this.reportToolFailure(Z,Q,J));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;ownedToolCoordinator;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;reportedPolicyDiagnostics=new Map;policyDiagnosticListeners=new Set;reportedUnboundFeaturePolicy=!1;reportedRegistryUnavailable=!1;resolveConfig(Z){let Q=P5(Z.toolConfigStrictness),J=Z.toolRegistry??new C7,Y=Z.deferToolConfigValidation===!0?s0(Z.tools):this.validateToolsConfig(Z.tools,{strictness:Q,source:"ToolkitCoordinator.init",toolRegistry:J}),X={...V1};return{...Z,toolConfigStrictness:Q,toolRegistry:J,tools:{...Y,providers:{...X,...Y.providers}},accessibility:{language:"en-US",...Z.accessibility??{},catalogs:Z.accessibility?.catalogs??[]}}}validateToolsConfig(Z,Q){let{config:J,diagnostics:Y}=w5(Z,Q.toolRegistry),X=this.reportedRegistryUnavailable||this.toolRegistryPending()?Y.filter((G)=>G.code!=="tools.registryUnavailable"):Y;if(R5(X,Q),Q.strictness!=="off"&&X.some((G)=>G.code==="tools.registryUnavailable"))this.reportedRegistryUnavailable=!0;return J}constructor(Z){if(!Z.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");this.toolRegistrySupplied=Z.toolRegistry!=null,this.toolRegistrySettled=this.toolRegistrySupplied;let Q=this.resolveConfig(Z);if(this.assessmentId=Q.assessmentId,this.config=Q,this.toolRegistry=Q.toolRegistry??new C7,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks={...Q.hooks},this.lazyInit=Z.lazyInit===!0,this.eagerInit=Z.eagerInit??!this.lazyInit,this.frameworkErrorBus=Z.frameworkErrorBus??new UZ,this.ownsFrameworkErrorBus=!Z.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.ownedToolCoordinator=new A1,this.toolCoordinator=this.ownedToolCoordinator,this.highlightCoordinator=new AZ,this.elementToolStateStore=new I5,this.catalogResolver=new k5(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new rZ,this._registerToolProviders(),this.ttsService=new z7,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.ttsService.setReadinessGate(()=>this.ensureTTSReady()),this.tts=new M7({assertNotDisposed:()=>this.assertNotDisposed(),isDisposalStarted:()=>this.disposePromise!==null,isDisposalError:(J)=>J instanceof s,emitTelemetry:(J,Y)=>this.emitTelemetry(J,Y),hooks:this.hooks,toolProviderRegistry:this.toolProviderRegistry,initializeProvider:(J,Y)=>this.initializeProvider(J,Y),ttsService:this.ttsService,catalogResolver:this.catalogResolver,clearDegradedTool:(J)=>void this.degradedTools.delete(J),reportStartFailure:(J,Y,X)=>this.reportStartFailure(J,Y,X),isToolGranted:(J)=>this.isToolGranted(J),lazyInit:this.lazyInit,isToolRegistryPending:()=>this.toolRegistryPending(),providersConfig:()=>this.config.tools?.providers,getProviderDescriptorTools:()=>this.getProviderDescriptorTools(),registerProviderFromTool:(J,Y)=>this.registerProviderFromTool(J,Y),notifyReadyChange:()=>this.notifyReadyChange()}),this.ttsService.setMathSpeechSource(()=>this.tts.mathSpeechRuntimeOptions()),this.setupStatePersistenceHooks(),this.policyEngine=new eZ({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,assessmentOptional:this.config.assessmentOptional===!0,supportConflicts:H1,inputs:{tools:this.config.tools,assessment:null,pnpEnforcement:this.resolveConfiguredPnpEnforcement()}}),this.policyEngine.onPolicyChange((J)=>{if(J.reason==="disposed")return;if(J.reason==="inputs"||J.reason==="pnp-enforcement")this.reportedPolicyDiagnostics.clear();this.warnPolicyDiagnostics(J.inputs.diagnostics),this.reportNewlyGrantedFailures()}),this.eagerInit)this.waitUntilReady().catch((J)=>{if(J instanceof s)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready",recoverable:!1})})}assertNotDisposed(){if(this.disposePromise!==null)throw new s}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((Z)=>{let Q=this.hooks.onFrameworkError;if(!Q)return;try{Q(Z)}catch(J){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",J)}})}async emitTelemetry(Z,Q){try{await this.hooks.onTelemetry?.(Z,Q)}catch(Y){console.warn("[ToolkitCoordinator] telemetry hook failed:",Y)}let J=Q?{...Q}:void 0;for(let Y of this.telemetryListeners)try{Y({eventName:Z,payload:J?{...J}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(Z){for(let Q of this.sectionControllerLifecycleListeners)try{Q(Z)}catch(J){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",J)}}handleError(Z,Q,J){let Y=C8({error:Z,context:Q,recoverable:Q.recoverable,scope:J?"cohort":"runtime",cohort:J});this.frameworkErrorBus.reportFrameworkError(Y)}isToolGranted(Z){try{return this.policyEngine.grantsFeatureAnywhere(Z,{enforced:this.toolRegistry.getToolActivation(Z)!=="region"})}catch{return!1}}reportStartFailure(Z,Q,J,Y=!1){let X=Array.from(J),G=Y||!X.some((j)=>this.isToolGranted(j));if(G&&!Y)for(let j of X)this.degradedTools.set(j,{error:Z,context:Q});this.handleError(Z,{...Q,recoverable:G})}reportToolFailure(Z,Q,J){if(Q==="tool-module-load")this.toolRequests.notifyTargetsChange();let Y=`${Q}\x00${Z}`;if(this.reportedToolFailures.has(Y))return;this.reportedToolFailures.add(Y);let X=J instanceof Error&&J.message.trim().length>0?J.message:String(J),G=()=>this.reportStartFailure(Error(`Tool "${Z}" ${m2[Q]}: ${X}`,{cause:J}),{phase:Q,details:{toolId:Z}},[Z],Q!=="tool-module-load");if(Q==="tool-module-load")G();else queueMicrotask(G)}reportNewlyGrantedFailures(){for(let[Z,Q]of this.degradedTools){if(!this.isToolGranted(Z))continue;this.degradedTools.delete(Z),this.handleError(Q.error,{...Q.context,recoverable:!1})}}onReadyChange(Z){return this.readyChangeListeners.add(Z),()=>{this.readyChangeListeners.delete(Z)}}notifyReadyChange(){for(let Z of this.readyChangeListeners)try{Z()}catch(Q){console.warn("[ToolkitCoordinator] ready-change listener failed:",Q)}}subscribeFrameworkErrors(Z){return this.frameworkErrorBus.subscribeFrameworkErrors(Z)}reportFrameworkError(Z){this.frameworkErrorBus.reportFrameworkError(Z)}sectionControllerKey(Z){return{assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId}}getSectionControllerMapKey(Z){return`${Z.assessmentId}::${Z.sectionId}::${Z.attemptId||""}`}createDefaultSectionPersistence(){let Z=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Q=(J)=>{let{assessmentId:Y,sectionId:X,attemptId:G}=J.key;if(!G)return null;return`pie:section-controller:v1:${Y}:${X}:${G}`};return{async loadSession(J){let Y=Q(J);if(!Z||!Y)return null;let X=Z.getItem(Y);if(!X)return null;try{return JSON.parse(X)}catch{return null}},async saveSession(J,Y){let X=Q(J);if(!Z||!X)return;Z.setItem(X,JSON.stringify(Y))},async clearSession(J){let Y=Q(J);if(!Z||!Y)return;Z.removeItem(Y)}}}async resolveSectionPersistence(Z){let Q=this.getSectionControllerMapKey(Z.key),J=this.sectionPersistenceStrategies.get(Q);if(J)return J;let Y={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(Z,Y)??await Y.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Q,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((Z)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(Z)).catch((Q)=>{this.handleError(Q,{phase:"state-save",recoverable:!0})})})}async ensureStateLoaded(){if(this.stateLoadSettled)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let Z=this.hooks.loadToolState;if(!Z)return;try{let Q=await Z();if(this.assertNotDisposed(),Q&&typeof Q==="object")this.elementToolStateStore.loadState(Q);this.stateLoadSettled=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Q)})}catch(Q){if(Q instanceof s)throw Q;this.stateLoadSettled=!0,this.handleError(Q,{phase:"state-load",recoverable:!0})}})().finally(()=>{this.stateLoadPromise=void 0,this.notifyReadyChange()}),this.stateLoadPromise}toolRegistryPending(){return!this.toolRegistrySettled&&!this.toolRegistryAbsent}adoptToolRegistry(Z){if(this.disposePromise!==null||this.toolRegistrySettled)return!1;if(!Z&&this.toolRegistryAbsent)return!1;let Q=this.config.toolConfigStrictness??"error",J="ToolkitCoordinator.adoptToolRegistry";if(!Z)return this.toolRegistryAbsent=!0,this.validateToolsConfig(this.config.tools,{strictness:Q,source:J,toolRegistry:this.toolRegistry}),this.tts.reportHeldMissingProvider(),!1;this.toolRegistrySettled=!0,this.toolRegistry=Z,this.config.toolRegistry=Z,this.tts.discardHeldMissingProvider();try{this.config.tools=this.validateToolsConfig(this.config.tools,{strictness:Q==="off"?"off":"warn",source:J,toolRegistry:Z})}catch(X){console.warn("[ToolkitCoordinator] Tool config does not validate against the adopted tool registry:",X)}this.policyEngine.replaceToolRegistry(Z,this.config.tools);let Y=this.tts.isStarted();for(let X of this.getProviderDescriptorTools()){if(Y&&this.tts.ownsTool(X.toolId))continue;this.registerProviderFromTool(X)}if(Y)this.tts.scheduleReconfigure();return!0}_registerToolProviders(){let Z=this.getProviderDescriptorTools();for(let Q of Z)this.registerProviderFromTool(Q)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((Z)=>!!Z.provider)}async registerProviderFromTool(Z,Q=!1){let J=Z.provider;if(!J)return;let{toolId:Y}=Z,X;try{let G=this.getToolConfig(Y)||void 0;if(G?.enabled===!1){if(Q)this.toolProviderRegistry.unregister(Y);return}if(!Q&&this.toolProviderRegistry.has(Y))return;let j=J.createProvider(G),B=J.getInitConfig?.(G)??G?.provider?.init??{},V=this.addToolTelemetryReporter(Y,B),K=this.createToolTelemetryForwarder(Y),U=J.getAuthFetcher?.(G)??G?.provider?.runtime?.authFetcher;X={provider:j,config:V,lazy:J.lazy??!0,authFetcher:U,onTelemetry:K}}catch(G){this.reportProviderRegisterFailure(G,Y);return}await this.registerProvider(Y,X)}createToolTelemetryForwarder(Z){return async(Q,J)=>{await this.emitTelemetry(Q,{...J||{},toolId:Z})}}addToolTelemetryReporter(Z,Q){let J=Q&&typeof Q==="object"?{...Q}:{},Y=typeof J.onTelemetry==="function"?J.onTelemetry:null,X=this.createToolTelemetryForwarder(Z);return J.onTelemetry=async(G,j)=>{if(Y)await Y(G,j);await X(G,j)},J}async registerProvider(Z,Q){try{this.toolProviderRegistry.register(Z,Q);let J={providerName:Q.provider.providerName};await this.hooks.onProviderRegistered?.(Z,J),await this.emitTelemetry("pie-toolkit-provider-registered",{toolId:Z,providerName:Q.provider.providerName})}catch(J){this.reportProviderRegisterFailure(J,Z)}}reportProviderRegisterFailure(Z,Q){console.warn(`[ToolkitCoordinator] Failed to register the provider of tool "${Q}":`,Z),this.reportStartFailure(Z,{phase:"provider-register",toolId:Q},[Q])}async ensureProviderReady(Z){return this.initializeProvider(Z,!1)}async initializeProvider(Z,Q){this.assertNotDisposed();let J=this.providerInitPromises.get(Z);if(J)return J;let Y=(async()=>{try{let X=await this.toolProviderRegistry.getProvider(Z,!1);if(this.assertNotDisposed(),this.toolProviderRegistry.isInitialized(Z))return X;let G={providerName:X.providerName};return await this.hooks.onProviderInitStart?.(Z,G),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(Z),this.assertNotDisposed(),X=await this.toolProviderRegistry.getProvider(Z,!1),await this.hooks.onProviderReady?.(Z,G),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{toolId:Z}),this.assertNotDisposed(),X}catch(X){if(X instanceof s)throw X;let G=X instanceof Error?X:Error(String(X));throw this.reportStartFailure(G,{phase:"provider-init",toolId:Z},this.toolRegistry.get(Z)?.provider?[Z]:[],Q),G}})().finally(()=>{this.providerInitPromises.delete(Z)});return this.providerInitPromises.set(Z,Y),Y}setHooks(Z){if(Object.assign(this.hooks,Z),this.setupStatePersistenceHooks(),this.disposePromise===null&&Z.onCoordinatorReady&&this.isReady())Promise.resolve(Z.onCoordinatorReady(this)).catch((Q)=>{this.handleError(Q,{phase:"coordinator-ready",recoverable:!1})})}subscribeTelemetry(Z){return this.telemetryListeners.add(Z),()=>{this.telemetryListeners.delete(Z)}}getSectionController(Z){let Q=this.sectionControllerKey(Z);return this.sectionControllers.get(this.getSectionControllerMapKey(Q))}subscribeSectionEvents(Z){if(this.activeCohortMapKey===null&&this.latestRequestedActiveCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Q=this.activeSubscriptions.get(Z.listener);if(Q)Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let J={listener:Z.listener,eventTypes:Z.eventTypes,itemIds:Z.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(Z.listener,J);let Y=this.activeCohortMapKey===null?void 0:this.sectionControllers.get(this.activeCohortMapKey);if(Y)this.bindSubscriptionToController(J,Y);let X=!1;return()=>{if(X)return;if(X=!0,J.unsubscribeCurrent?.(),J.unsubscribeCurrent=null,this.activeSubscriptions.get(Z.listener)===J)this.activeSubscriptions.delete(Z.listener)}}bindSubscriptionToController(Z,Q){Z.unsubscribeCurrent?.(),Z.unsubscribeCurrent=null;let J=Q.subscribe;if(typeof J!=="function")return;let Y=this.buildSectionEventPredicate(Z);Z.unsubscribeCurrent=J.call(Q,(j)=>{if(!Y(j))return;this.deliverSectionEventSafely(Z.listener,j)});let X=this.buildContentLoadedReplayEvents(Q);for(let j of X)if(Y(j))this.deliverSectionEventSafely(Z.listener,j);let G=this.buildLoadingCompleteReplayEvent(Q);if(G&&Y(G))this.deliverSectionEventSafely(Z.listener,G)}deliverSectionEventSafely(Z,Q){try{Z(Q)}catch(J){console.warn("[ToolkitCoordinator] section-event listener failed:",J)}}setActiveCohort(Z){if(this.activeCohortMapKey===Z)return;this.activeCohortMapKey=Z;let Q=this.sectionControllers.get(Z);if(!Q)return;for(let J of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(J,Q)}setActiveCohortIfLatestRequest(Z){if(this.latestRequestedActiveCohortMapKey!==Z)return;this.setActiveCohort(Z)}suspendActiveCohortIfSuperseded(Z){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===Z)return;this.activeCohortMapKey=null,this.detachActiveSubscriptions()}clearActiveCohortIfMatches(Z){if(this.activeCohortMapKey!==Z)return;this.activeCohortMapKey=null,this.detachActiveSubscriptions()}detachActiveSubscriptions(){for(let Z of Array.from(this.activeSubscriptions.values()))Z.unsubscribeCurrent?.(),Z.unsubscribeCurrent=null}buildSectionEventPredicate(Z){let Q=Z.eventTypes?new Set(Z.eventTypes):null,J=Z.itemIds?new Set(Z.itemIds):null;return(Y)=>{if(Q){let X=Y?.type;if(!X||!Q.has(X))return!1}if(!J)return!0;return Array.from(this.collectEventItemIds(Y)).some((X)=>J.has(X))}}collectEventItemIds(Z){let Q=new Set;if("itemId"in Z&&typeof Z.itemId==="string")Q.add(Z.itemId);if("canonicalItemId"in Z&&typeof Z.canonicalItemId==="string")Q.add(Z.canonicalItemId);if("currentItemId"in Z&&typeof Z.currentItemId==="string")Q.add(Z.currentItemId);if("previousItemId"in Z&&typeof Z.previousItemId==="string")Q.add(Z.previousItemId);return Q}buildContentLoadedReplayEvents(Z){let Q=Z.getRuntimeState?.(),J=Q?.loadedRenderables;if(!Array.isArray(J)||J.length===0)return[];let Y=typeof Q?.currentItemIndex==="number"&&Number.isFinite(Q.currentItemIndex)?Q.currentItemIndex:0,X=Date.now(),G=[];for(let j of J){if(!j)continue;let B=j.itemId,V=typeof j.canonicalItemId==="string"&&j.canonicalItemId?j.canonicalItemId:B;if(typeof B!=="string"||!B)continue;G.push({type:"content-loaded",contentKind:j.contentKind??"unknown",itemId:B,canonicalItemId:V,currentItemIndex:Y,timestamp:X})}return G}buildLoadingCompleteReplayEvent(Z){let Q=Z.getRuntimeState?.();if(Q?.loadingComplete!==!0)return null;let J=typeof Q.totalRegistered==="number"&&Number.isFinite(Q.totalRegistered)?Math.max(0,Q.totalRegistered):0,Y=typeof Q.totalLoaded==="number"&&Number.isFinite(Q.totalLoaded)?Math.max(0,Q.totalLoaded):J;return{type:"section-loading-complete",totalRegistered:J,totalLoaded:Y,currentItemIndex:Q.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||u2,itemIds:Z.itemIds,listener:Z.listener})}subscribeSectionLifecycleEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||p2,listener:Z.listener})}onSectionControllerLifecycle(Z){return this.sectionControllerLifecycleListeners.add(Z),()=>{this.sectionControllerLifecycleListeners.delete(Z)}}async getOrCreateSectionController(Z){if(this.disposePromise!==null)throw new s;let Q=this.sectionControllerKey(Z),J=this.getSectionControllerMapKey(Q);this.latestRequestedActiveCohortMapKey=J,this.suspendActiveCohortIfSuperseded(J);let Y;try{if(Y=await this.resolveExistingSectionController({mapKey:J,key:Q,input:Z.input,updateExisting:Z.updateExisting}),Y){if(this.disposePromise!==null)throw new s;if(Z.initialSession)await this.assignSessionToPublishedController(Y,Z.initialSession)}}catch(V){throw this.deliverSectionStartError(J,V),V}if(Y)return Y;let X=this.sectionControllerDisposePromises.get(J);if(X)await MZ([X]);if(this.disposePromise!==null)throw new s;let G=this.sectionControllerInitEntries.get(J);if(G){if(!Z.initialSession)return G.promise;let V=await G.promise;return await this.assignSessionToPublishedController(V,Z.initialSession),V}let j={retired:!1,candidateClaimed:!1},B=this.initializeNewSectionController({args:Z,key:Q,mapKey:J,token:j}).catch((V)=>{throw this.handleSectionControllerInitError(V,Z),this.deliverSectionStartError(J,V),V}).finally(()=>{if(this.sectionControllerInitEntries.get(J)?.token===j)this.sectionControllerInitEntries.delete(J)});return this.sectionControllerInitEntries.set(J,{key:Q,token:j,promise:B}),B}async resolveExistingSectionController(Z){let Q=this.sectionControllers.get(Z.mapKey);if(!Q)return;if(this.sectionControllerKeys.set(Z.mapKey,Z.key),Z.updateExisting!==!1)await Q.updateInput?.(Z.input);if(this.sectionControllers.get(Z.mapKey)!==Q)return;return this.setActiveCohortIfLatestRequest(Z.mapKey),Q}createSectionControllerContext(Z){return{key:Z.key,coordinator:this,input:Z.input}}async initializeNewSectionController(Z){let Q=this.createSectionControllerContext({key:Z.key,input:Z.args.input}),J=await this.resolveSectionPersistence(Q);if(this.disposePromise!==null||Z.token.retired){if(this.sectionPersistenceStrategies.get(Z.mapKey)===J)this.sectionPersistenceStrategies.delete(Z.mapKey);throw this.createSectionControllerRetirementError()}let Y={createDefaultController:Z.args.createDefaultController},X=await this.hooks.createSectionController?.(Q,Y)??await Y.createDefaultController(),G={mapKey:Z.mapKey,key:Z.key,controller:X,persistence:J,token:Z.token};try{await this.retireUnpublishedSectionControllerIfNeeded(G),await X.configureSessionPersistence?.({strategy:J,context:Q}),await this.retireUnpublishedSectionControllerIfNeeded(G),await X.initialize?.(Z.args.input),await this.retireUnpublishedSectionControllerIfNeeded(G);let j=Z.args.initialSession;if(j){if(!X.applySession)throw Error("Section controller cannot apply the session it was created with: it has no applySession.");await X.applySession(j,{mode:"replace"})}else await X.hydrate?.();return await this.finalizeSectionControllerReady({...G,context:Q}),X}catch(j){throw await this.cleanupUnpublishedSectionController(G),j}}async assignSessionToPublishedController(Z,Q){if(!Q)return;if(!Z.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");let J=Q5(Z.getSession?.()??null,Q);if(!J)return;await Z.applySession(J,{mode:"replace"})}createSectionControllerRetirementError(){return this.disposePromise!==null?new s:new J5}async retireUnpublishedSectionControllerIfNeeded(Z){if(this.disposePromise===null&&!Z.token.retired)return;throw await this.cleanupUnpublishedSectionController(Z),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(Z){if(Z.token.candidateClaimed)return;Z.token.candidateClaimed=!0;try{await Z.controller.dispose?.()}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:Z.key.sectionId,attemptId:Z.key.attemptId},recoverable:!0})}finally{if(this.sectionPersistenceStrategies.get(Z.mapKey)===Z.persistence)this.sectionPersistenceStrategies.delete(Z.mapKey)}}retirePublishedSectionControllerIfNeeded(Z){if(this.disposePromise!==null&&!Z.token.retired)this.disposeSectionController({sectionId:Z.key.sectionId,attemptId:Z.key.attemptId});if(Z.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(Z){await this.retireUnpublishedSectionControllerIfNeeded(Z),this.sectionControllers.set(Z.mapKey,Z.controller),this.sectionControllerKeys.set(Z.mapKey,Z.key),Z.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(Z.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:Z.key,controller:Z.controller}),await this.hooks.onSectionControllerReady?.(Z.context,Z.controller),this.retirePublishedSectionControllerIfNeeded(Z),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:Z.key.assessmentId,sectionId:Z.key.sectionId,attemptId:Z.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(Z)}handleSectionControllerInitError(Z,Q){if(Z instanceof s||Z instanceof J5)return;this.handleError(Z,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId},recoverable:!1},{sectionId:Q.sectionId,attemptId:Q.attemptId})}deliverSectionStartError(Z,Q){if(Q instanceof s||Q instanceof J5||this.latestRequestedActiveCohortMapKey!==Z)return;let J={type:"section-error",source:"section-runtime",error:Q,currentItemIndex:0,timestamp:Date.now()};for(let Y of Array.from(this.activeSubscriptions.values()))if(this.buildSectionEventPredicate(Y)(J))this.deliverSectionEventSafely(Y.listener,J)}disposeSectionController(Z){let Q=this.sectionControllerKey(Z),J=this.getSectionControllerMapKey(Q),Y=this.sectionControllerInitEntries.get(J);if(Y)Y.token.retired=!0;let X=this.sectionControllers.get(J);if(!X){let K=this.sectionControllerDisposePromises.get(J);if(K)return K;if(!Y)return Promise.resolve();let U=MZ([Y.promise]).then(()=>{return});return this.trackSectionControllerDisposal(J,U)}let G=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:Q});let j=this.createSectionControllerContext({key:Q,input:void 0}),B=this.disposeSectionControllerEntry({args:Z,key:Q,context:j,controller:X,persistenceStrategy:G}),V=Y?MZ([Y.promise]).then(()=>B):B;return this.trackSectionControllerDisposal(J,V)}trackSectionControllerDisposal(Z,Q){this.sectionControllerDisposePromises.set(Z,Q);let J=()=>{if(this.sectionControllerDisposePromises.get(Z)===Q)this.sectionControllerDisposePromises.delete(Z)};return Q.then(J,J),Q}async disposeSectionControllerEntry(Z){try{await this.runSectionControllerDisposePipeline({key:Z.key,context:Z.context,controller:Z.controller,persistBeforeDispose:Z.args.persistBeforeDispose})}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:Z.args.sectionId,attemptId:Z.args.attemptId},recoverable:!0})}finally{await this.finalizeSectionControllerDispose({context:Z.context,persistenceStrategy:Z.persistenceStrategy,clearPersistence:Z.args.clearPersistence})}}async runSectionControllerDisposePipeline(Z){let Q=[];if(Z.persistBeforeDispose!==!1)try{await Z.controller.persist?.()}catch(J){Q.push(J)}try{await Z.controller.dispose?.()}catch(J){Q.push(J)}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?.(Z.context,Z.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:Z.key.assessmentId,sectionId:Z.key.sectionId,attemptId:Z.key.attemptId})}async finalizeSectionControllerDispose(Z){if(Z.clearPersistence)await Z.persistenceStrategy?.clearSession?.(Z.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let Z=[],Q=async(Y)=>{try{await Y()}catch(X){Z.push(X)}};await this.waitForAdmittedInitialization();let J=new Map;for(let[Y,X]of this.sectionControllerInitEntries)J.set(Y,X.key);for(let[Y,X]of this.sectionControllerKeys)J.set(Y,X);for(let Y of J.values())this.disposeSectionController({sectionId:Y.sectionId,attemptId:Y.attemptId});await MZ(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let Y of this.activeSubscriptions.values())await Q(()=>Y.unsubscribeCurrent?.()),Y.unsubscribeCurrent=null;if(this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Q(()=>this.ttsService.dispose()),await Q(()=>this.toolProviderRegistry.destroy()),await Q(()=>this.highlightCoordinator.destroy()),await Q(()=>this.ownedToolCoordinator.destroy()),await Q(()=>this.catalogResolver.destroy()),await Q(()=>this.toolRequests.dispose()),await Q(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.policyDiagnosticListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(Z.length===1)throw Z[0];if(Z.length>1)throw AggregateError(Z,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let Z=new Set;if(this.coordinatorReadyPromise)Z.add(this.coordinatorReadyPromise);this.tts.flushInitPromises(Z);for(let Q of this.providerInitPromises.values())Z.add(Q);await MZ(Z)}async ensureTTSReady(){return this.tts.ensureReady()}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{if(await this.ensureStateLoaded(),this.assertNotDisposed(),this.tts.requiredForReadiness())await this.tts.startForReadiness();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.stateLoadSettled||!this.hooks.loadToolState)&&(this.tts.started||this.tts.failedUngranted||!this.tts.requiredForReadiness())}assertCanonicalToolId(Z){if(typeof Z!=="string"||Z.trim().length===0)throw Error("Tool id must be a non-empty string.");if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(Z))throw Error(`Unknown tool id "${Z}".`)}installToolContextResolvers(Z){if(!Z)return;for(let[Q,J]of Object.entries(Z)){if(J==null)continue;if(this.assertCanonicalToolId(Q),typeof J!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);this.toolContextResolvers.set(Q,J)}}setToolContextResolvers(Z){this.toolContextResolvers.clear(),this.installToolContextResolvers(Z??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let Z of this.toolContextResolverChangeListeners)try{Z()}catch(Q){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Q)}}getToolConfig(Z){return this.assertCanonicalToolId(Z),this.config.tools?.providers?.[Z]||null}updateToolConfig(Z,Q){this.assertCanonicalToolId(Z);let J=this.getToolConfig(Z)||{};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 Y={...this.config.tools.providers,[Z]:h2(Z,J,Q)},X=this.validateToolsConfig({...this.config.tools,providers:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});this.config.tools=X,this.policyEngine.updateInputs({tools:X}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:Z}),this._applyToolConfigChange(Z)}updateToolsPlacement(Z){if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});let Q=this.config.tools?.placement??{section:[],item:[],passage:[]},J={section:[...Z.section??Q.section??[]],item:[...Z.item??Q.item??[]],passage:[...Z.passage??Q.passage??[]]},Y=this.validateToolsConfig({...this.config.tools,placement:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});Y.placement=J,this.config.tools=Y,this.policyEngine.updateInputs({tools:Y})}decideToolPolicy(Z){let Q=this.policyEngine.decide(Z);return this.warnPolicyDiagnostics(Q.diagnostics),Q}warnPolicyDiagnostics(Z){for(let Q of Z){let J=Q.code==="tool-policy.itemSettingNotApplied"?Q.details.itemId:"",Y=`${Q.code}\x00${Q.toolId}\x00${J}`;if(this.reportedPolicyDiagnostics.has(Y))continue;this.reportedPolicyDiagnostics.set(Y,Q),console.warn(`[ToolkitCoordinator] ${Q.message}`);for(let X of Array.from(this.policyDiagnosticListeners))this.notifyPolicyDiagnosticListener(X,Q)}}notifyPolicyDiagnosticListener(Z,Q){try{Z(Q)}catch(J){console.error("[ToolkitCoordinator] Policy diagnostic listener failed:",J)}}registerItemSettings(Z,Q){return this.policyEngine.registerItemSettings(Z,Q)}decideFeaturePolicy(Z,Q){let J=this.policyEngine.decideFeature(Z,Q);if(this.warnPolicyDiagnostics(J.diagnostics),!J.assessmentBound&&this.policyEngine.getInputs().assessmentExpected&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${Z}" with no assessment bound, so profile, district and test-administration policy have nothing to read and only an item's requiredTools can grant. Pass the assessment to the toolkit's assessment property, or call updateAssessment(...), before relying on any accommodation. Reported once per coordinator.`);return J}reportFeatureDecisionApplied(Z,Q){if(Z.granted||Z.rule!=="support-conflict"||Z.overrode!=="attribute"&&Z.overrode!=="authored")return;let J=this.policyEngine.decideFeature(Z.featureId,Q);if(J.rule!=="support-conflict"||!J.withheldBy)return;this.warnPolicyDiagnostics([_Z(Z.featureId,J.withheldBy,Z.overrode)])}onPolicyChange(Z){return this.policyEngine.onPolicyChange(Z)}onPolicyDiagnostic(Z){this.policyDiagnosticListeners.add(Z);for(let Q of Array.from(this.reportedPolicyDiagnostics.values()))this.notifyPolicyDiagnosticListener(Z,Q);return()=>{this.policyDiagnosticListeners.delete(Z)}}onCatalogsChange(Z){return this.catalogResolver.onCatalogsChange(Z)}updateAssessment(Z){this.policyEngine.updateInputs({assessment:Z})}setPnpEnforcement(Z){this.policyEngine.updateInputs({pnpEnforcement:Z})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(Z){return this.policyEngine.registerPolicySource(Z)}hasToolContextResolver(Z){return this.assertCanonicalToolId(Z),this.toolContextResolvers.has(Z)}resolveToolContext(Z){this.assertCanonicalToolId(Z.toolId);let Q=this.toolContextResolvers.get(Z.toolId);if(!Q)return null;let J;try{J=Q(Z)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${Z.toolId}" threw:`,X),{toolId:Z.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!J)return{toolId:Z.toolId,visible:!0,params:{}};let Y=J.params&&typeof J.params==="object"&&!Array.isArray(J.params)?J.params:{};return{toolId:Z.toolId,visible:J.visible!==!1,params:Y,reason:typeof J.reason==="string"?J.reason:void 0}}onToolContextResolverChange(Z){return this.toolContextResolverChangeListeners.add(Z),()=>{this.toolContextResolverChangeListeners.delete(Z)}}getToolRegistry(){return this.toolRegistry}registerToolRequestTarget(Z){return this.toolRequests.registerTarget(Z)}requestTool(Z){return this.assertCanonicalToolId(Z.toolId),this.toolRequests.request(Z)}canRequestTool(Z,Q,J){try{this.assertCanonicalToolId(Z)}catch{return!1}return this.toolRequests.canRequest(Z,Q,J)}onToolRequestTargetsChange(Z){return this.toolRequests.onTargetsChange(Z)}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(Z){if(this.disposePromise!==null)return;if(this.tts.ownsTool(Z)){this.tts.scheduleReconfigure();return}this._registerChangedToolProvider(Z)}_registerChangedToolProvider(Z){let Q=this.getProviderDescriptorTools().find((J)=>J.toolId===Z);if(!Q)return;this.degradedTools.delete(Z),this.registerProviderFromTool(Q,!0)}}var g2=()=>{};function D1(Z){return Z===R.PLAYING||Z===R.LOADING}function _1(Z){let{ttsService:Q,silence:J}=Z;if(typeof Q?.onStateChange!=="function")return g2;let Y=Q.onStateChange((X)=>{if(D1(X))J()});return()=>{try{Y()}catch{}}}function M1(Z){try{if(D1(Z?.getState?.()))Z?.pause?.()}catch{}}import{timedMediaProjectionSignature as FQ}from"@pie-players/pie-players-shared/timed-media";function O1(Z,Q,J){let Y=Z.detail?.runtimeId;if(typeof Y==="string"&&Y!=="")return Y===Q;return J(Z.target)}function L1(Z,Q,J){let Y=[Z.catalogResolver.registerOwner({owner:{kind:Q.kind,itemId:Q.itemId,canonicalItemId:Q.canonicalItemId,assessmentId:J.assessmentId,sectionId:J.sectionId},entity:Q.item})];if(Q.kind==="item"&&Q.settings)Y.push(Z.registerItemSettings(Q.canonicalItemId||Q.itemId,Q.settings));return Y}var c2=["a[href]","button","label","summary",...["button","checkbox","combobox","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","switch","tab","treeitem"].map((Z)=>`[role="${Z}"]`)].join(", "),N1=new Set(["mi","mn","mtext"]),d2=(Z)=>N1.has(Z.localName)||Z.localName==="mrow"&&Z.children.length===1&&N1.has(Z.children[0].localName),i2=(Z)=>Array.from(Z.getElementsByTagName("mfrac")).every((Q)=>Array.from(Q.children).every(d2))?"Fraction_Over":"Fraction_General",l2=(Z)=>!Z||Z.toLowerCase().split("-")[0]==="en",s2=(Z)=>{if(Z.localName!=="label")return Z;let Q=Z;if(Q.control)return Q.control;let J=Q.getAttribute("for"),Y=Q.getRootNode();return(J?Y.getElementById?.(J):null)??Q.querySelector("input, select, textarea, button")},P1=(Z,Q)=>{let J=s2(Z),Y=J?.getAttribute("aria-labelledby")?.split(/\s+/).filter(Boolean);if(!J||!Y?.length)return!1;let X=J.getRootNode(),G=Y.map((j)=>X.getElementById?.(j)??null).filter((j)=>j!==null);return G.length>0&&!G.some((j)=>j.contains(Q))};function w1(Z,Q={}){if(typeof MutationObserver>"u")return()=>{};let J=new Map,Y=!1,X=async(U,$,z)=>{let H=await ZZ([{type:"math",mathml:U,fallbackText:""}],{language:z,loadSre:Q.loadSre,mathSpeech:{...l2(z)?{style:i2($)}:{},engineOptions:Q.getMathSpeech?.()?.engineOptions}});return H.usedMathSpeech?H.speechText:null},G=(U)=>{let $=h5(U,c2);if(!$||P1($,U))return;let z=E0(U,"math"),H=z&&e0(z.outerHTML);if(!z||!H)return;let O=g8(U,{contentLanguage:Q.getContentLanguage?.()}),N=`${O??""}\x00${H}`,D=J.get(N);if(!D)D=X(H,z,O),J.set(N,D);D.then((P)=>{if(Y||!P||!U.isConnected)return;if(P1($,U))return;if(U.getAttribute("aria-label")!==P)U.setAttribute("aria-label",P)})},j=new WeakSet,B=(U)=>{if(j.has(U))return;j.add(U),K.observe(U,{childList:!0,subtree:!0})},V=(U)=>{if(U.nodeType!==1)return;let $=U,z=h5($,"mjx-container");if(z){G(z);return}if($.shadowRoot)B($.shadowRoot);$Z($,(H)=>{if(H.nodeType!==1)return"skip";let O=H;if(O.localName==="mjx-container")return G(O),"skip";if(O.shadowRoot)B(O.shadowRoot);return})},K=new MutationObserver((U)=>{for(let $ of U)for(let z of $.addedNodes)V(z)});return B(Z),V(Z),()=>{Y=!0,K.disconnect()}}import{createPieLogger as r2,isGlobalDebugEnabled as a2}from"@pie-players/pie-players-shared";function n2(Z,Q){if(Z===Q)return 0;let J=Z.compareDocumentPosition(Q);if(J&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(J&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class E7{shellsByElement=new Map;register(Z){let Q=this.shellsByElement.get(Z.element),J={...Z,sortKey:Date.now()};if(Q&&Q.kind===J.kind&&Q.itemId===J.itemId&&Q.canonicalItemId===J.canonicalItemId)return!1;return this.shellsByElement.set(Z.element,J),!0}unregister(Z){return this.shellsByElement.delete(Z)}getOrderedShells(Z){let Q=Array.from(this.shellsByElement.values()).filter((J)=>!Z||J.kind===Z);return Q.sort((J,Y)=>n2(J.element,Y.element)),Q}getCanonicalIdMap(){let Z={};for(let Q of this.getOrderedShells("item")){if(!Q.itemId)continue;Z[Q.itemId]=Q.canonicalItemId||Q.itemId}return Z}clear(){this.shellsByElement.clear()}}var R1=r2("section-controller-binding",()=>a2());function o2(Z){let Q=Z?.renderables;if(!Array.isArray(Q))return null;let J=new Set;for(let Y of Q){let X=Y?.entity?.id;if(typeof X==="string"&&X)J.add(X)}return J}function C1(Z,Q){return Z.has(Q.itemId)||!!Q.canonicalItemId&&Z.has(Q.canonicalItemId)}class S7{registry=new E7;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;sectionRenderableIds=null;boundSections=new Map;loadedRenderableKeys=new Set;async initialize(Z){this.activeInitToken+=1;let Q=this.activeInitToken;this.coordinator=Z.coordinator,this.sectionId=Z.sectionId,this.attemptId=Z.attemptId,this.forgetUnregisteredLoads(Z.coordinator.getSectionController({sectionId:Z.sectionId,attemptId:Z.attemptId}));let J;try{J=await Z.coordinator.getOrCreateSectionController({sectionId:Z.sectionId,attemptId:Z.attemptId,input:{section:Z.section,sectionId:Z.sectionId,assessmentId:Z.assessmentId,view:Z.view},updateExisting:!0,initialSession:Z.initialSession,createDefaultController:Z.createDefaultController})}catch(X){if(Q===this.activeInitToken)this.unsubscribeController?.(),this.unsubscribeController=null,this.controller=null;throw X}if(Q!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=J,this.sectionRenderableIds=o2(J.getCompositionModel?.());let Y=this.getSectionKey(Z.sectionId,Z.attemptId);this.boundSections.delete(Y),this.boundSections.set(Y,{sectionId:Z.sectionId,attemptId:Z.attemptId,renderableIds:this.sectionRenderableIds}),this.replayRegisteredShellsIntoController(J),Z.onCompositionChanged?.(J.getCompositionModel?.()),this.unsubscribeController=J.subscribe?.((X)=>{try{Z.onControllerEvent?.(X)}catch(G){R1.warn("onControllerEvent handler threw",G)}Z.onCompositionChanged?.(J.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(Z){if(!Z.handleContentRegistered)return;let Q=this.registry.getOrderedShells().filter((Y)=>this.isSectionRenderable(Y));if(Q.length===0)return;for(let Y of Q){let X=Y.canonicalItemId||Y.itemId;Z.handleContentRegistered({itemId:Y.itemId,canonicalItemId:X,contentKind:Y.contentKind||Y.kind})}let J=Date.now();for(let Y of Q){let X=Y.canonicalItemId||Y.itemId,G=this.getLoadedKey(X,Y.contentKind);if(this.loadedRenderableKeys.has(G))Z.handleContentLoaded?.({itemId:Y.itemId,canonicalItemId:X,contentKind:Y.contentKind||Y.kind,timestamp:J})}}getLoadedKey(Z,Q){return`${Q??""}:${Z}`}isSectionRenderable(Z){let Q=this.sectionRenderableIds;return!Q||C1(Q,Z)}getSectionKey(Z,Q){return`${Z}\x00${Q??""}`}controllerFor(Z){if(this.isSectionRenderable(Z))return this.controller;let Q=this.getSectionKey(this.sectionId,this.attemptId),J=[...this.boundSections.entries()].reverse();for(let[Y,X]of J){if(Y===Q||!X.renderableIds)continue;if(!C1(X.renderableIds,Z))continue;let G=this.coordinator?.getSectionController({sectionId:X.sectionId,attemptId:X.attemptId});if(G)return G}return null}requireControllerFor(Z,Q){let J=this.controllerFor(Z);if(!J)R1.warn(`Dropped ${Q} for "${Z.itemId}": no section this toolkit bound renders it.`);return J}forgetUnregisteredLoads(Z){if(!Z||Z===this.controller)return;let Q=Z.getRuntimeState?.()?.loadedRenderables??[];if(Q.length===0)return;let J=new Set;for(let Y of this.registry.getOrderedShells())if(J.add(Y.itemId),Y.canonicalItemId)J.add(Y.canonicalItemId);for(let Y of Q){if(J.has(Y.canonicalItemId)||J.has(Y.itemId))continue;Z.handleContentUnregistered?.({itemId:Y.itemId,canonicalItemId:Y.canonicalItemId,contentKind:Y.contentKind})}}register(Z){return this.registry.register(Z)}unregister(Z){return this.registry.unregister(Z)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(Z){return this.registry.getCanonicalIdMap()[Z]||this.controller?.getCanonicalItemId?.(Z)||Z}handleContentRegistered(Z){if(!this.isSectionRenderable(Z))return;this.controller?.handleContentRegistered?.({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId||Z.itemId,contentKind:Z.contentKind||Z.kind})}handleContentUnregistered(Z){let Q=Z.canonicalItemId||Z.itemId,J=this.getLoadedKey(Q,Z.contentKind);if(this.registry.getOrderedShells().some((X)=>this.getLoadedKey(X.canonicalItemId||X.itemId,X.contentKind)===J))return;this.loadedRenderableKeys.delete(J),this.controllerFor(Z)?.handleContentUnregistered?.({itemId:Z.itemId,canonicalItemId:Q,contentKind:Z.contentKind||Z.kind})}handleContentLoaded(Z){let Q=Z.canonicalItemId||Z.itemId;if(this.loadedRenderableKeys.add(this.getLoadedKey(Q,Z.contentKind)),!this.isSectionRenderable(Z))return;this.controller?.handleContentLoaded?.(Z)}handleItemPlayerError(Z){this.requireControllerFor(Z,"an item player error")?.handleItemPlayerError?.(Z)}reportSectionError(Z){(Z.itemId?this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId},"a section error"):this.controller)?.reportSectionError?.(Z)}updateItemSession(Z,Q){let J=this.getCanonicalItemId(Z);return this.requireControllerFor({itemId:Z,canonicalItemId:J},"a session update")?.updateItemSession?.(J,Q)??null}recordServedContentIdentity(Z){let Q=Z.canonicalItemId||this.getCanonicalItemId(Z.itemId);this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Q},"a served content identity")?.recordServedContentIdentity?.({itemId:Q,identity:Z.identity})}navigateToItem(Z){return this.controller?.navigateToItem?.(Z)??null}handleFormativeAction(Z){if(!Z?.itemId)return;let Q=Z.canonicalItemId||this.getCanonicalItemId(Z.itemId),J=this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Q},"a formative action");if(Z.action==="retry"){J?.retryFormativeItem?.({itemId:Q});return}J?.recordFormativeTry?.({itemId:Q,outcomes:Z.outcomes})}handleMediaTimeSource(Z){if(!Z?.renderableId)return;let Q=this.requireControllerFor({itemId:Z.renderableId,canonicalItemId:this.getCanonicalItemId(Z.renderableId)},"a media time source");if(Z.action==="detach"){Q?.detachMediaTimeSource?.({origin:Z.origin??"host"});return}if(!Z.source)return;Q?.attachMediaTimeSource?.(Z.source,{origin:Z.origin??"host",renderableId:Z.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}async dispose(){this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null;let Z=this.coordinator;if(Z)for(let Q of this.boundSections.values())await Z.disposeSectionController({sectionId:Q.sectionId,attemptId:Q.attemptId});this.registry.clear(),this.loadedRenderableKeys.clear(),this.boundSections.clear(),this.controller=null,this.sectionRenderableIds=null,this.coordinator=null}}function b1(Z){let Q=Z.section?.identifier;return Z.sectionId||(typeof Q==="string"?Q:"")||`section-${Z.assessmentId||"default"}`}function E1(Z,Q){return["pnpEnforcement","assessment"].filter((Y)=>Z?!Object.is(Z[Y],Q[Y]):Q[Y]!==null)}function y1(Z){if(!Z)return;let Q=Symbol.for("pie.assessmentToolkit.unclaimedRegistrationWatch"),J=Z;if(J[Q])return;J[Q]=!0,Z.addEventListener(Y5,(Y)=>{let X=Y.detail,G=typeof X?.itemId==="string"?X.itemId:"";S1(Z,"unclaimedRegistration",`[pie-assessment-toolkit] Item "${G}" registered, but no toolkit claimed the registration, so its accessibility catalogs are not filed and it does not count toward its section's loading. Render its shell or scope inside the <pie-assessment-toolkit> that answered it. Reported once per page.`)})}function OZ(Z,Q){if(typeof Z==="function")return Z;if(Z===null)return null;return typeof Q==="function"?Q:null}function T1(Z={}){let Q=Z.frameDeadlineMs??100,J=!1,Y=null,X=null,G=null,j=null,B=null;function V(){if(J=!1,X!==null)j?.(X),X=null;if(G!==null)B?.(G),G=null;j=null,B=null}function K(z){if(!J)return;if(z==="frame")X=null;if(z==="timer")G=null;let H=Y;Y=null,V(),H?.()}function U(z){if(Y=z,J)return;J=!0;let H=globalThis,O=OZ(Z.requestFrame,H.requestAnimationFrame);j=OZ(Z.cancelFrame,H.cancelAnimationFrame);let N=OZ(Z.setTimer,H.setTimeout);if(B=OZ(Z.clearTimer,H.clearTimeout),O){let P=O(()=>K("frame"));if(!J)return;if(X=P,N){let M=N(()=>K("timer"),Q);if(J)G=M}return}let D=OZ(Z.queueMicrotaskFn,H.queueMicrotask);if(D){D(()=>K("microtask"));return}if(N){let P=N(()=>K("timer"),0);if(J)G=P;return}K("microtask")}function $(){if(!J)return;Y=null,V()}return{schedule:U,cancel:$,isPending:()=>J}}function x1(Z="runtime"){return`${Z}-${Math.random().toString(16).slice(2)}-${Date.now()}`}function k1(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function f1(Z){Z.lastSessionEventSignatureByItemId.clear(),Z.lastMetadataSignatureByItemId.clear()}function I1(Z){let{state:Q,itemId:J,payload:Y}=Z;if(e2(Y)){let j=ZQ(Y);if(Q.lastMetadataSignatureByItemId.get(J)===j)return!1;Q.lastMetadataSignatureByItemId.set(J,j)}let X=t2(Y);if(Q.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(J,X),!0}function t2(Z){let Q={...Z};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function e2(Z){return Z.intent==="metadata-only"}function ZQ(Z){try{return JSON.stringify({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId,intent:Z.intent,complete:Z.complete??null,component:Z.component??null})}catch{return String(Z.itemId||"")}}var QQ=(Z,Q)=>{if(customElements.get(Z))return;try{customElements.define(Z,Q)}catch(J){if(!(J instanceof DOMException&&J.name==="NotSupportedError"||J&&typeof J==="object"&&J.name==="NotSupportedError")||!customElements.get(Z))throw J}},zQ=k7('<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>'),HQ=k7('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),AQ={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 B4(Z,Q){u1(Q,!0),n1(Z,AQ);let J=BQ("pie-assessment-toolkit",()=>WQ()),Y=x1("toolkit"),X=new S7,G=new UZ,j={mode:"gather",role:"student"},B={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},V="Unable to initialize assessment toolkit.",K=f(Q,"assessmentId",7,""),U=f(Q,"section",7,null),$=f(Q,"sectionId",7,""),z=f(Q,"attemptId",7,""),H=f(Q,"env",23,()=>({})),O=f(Q,"ndsIcons",7,!1),N=f(Q,"locale",7,""),D=f(Q,"i18n",7,null),P=f(Q,"contentLanguage",7,""),M=f(Q,"lazyInit",7,!1),C=f(Q,"toolConfigStrictness",7,"error"),E=f(Q,"tools",23,()=>({})),v=f(Q,"toolContextResolvers",7,null),S=f(Q,"enabledTools",7,""),p=f(Q,"toolRegistry",7,null),e=f(Q,"accessibility",23,()=>({})),r=f(Q,"player",7,null),q0=f(Q,"playerType",7,""),Z0=f(Q,"coordinator",7,null),M0=f(Q,"createSectionController",7,null),O0=f(Q,"onFrameworkError",7,null),LZ=f(Q,"errorRenderer",7,null),NZ=f(Q,"assessment",7,null),U0=f(Q,"isolation",7,"inherit"),L0=f(Q,"session",7,null),XZ=n(null),g=n(null),Y0=n(null),f7=null,I7=null,GZ=!1,g0=null,c0=null,d0=null,i0=null,PZ=n(0),V5=n(null),X0=n(null),K5=n(V),q5=n(g1([])),v7="",U5="",jZ=null,BZ=null,wZ=null,h7=null,$5=null,m7=null,RZ=null,u7=!1,p7=null,g7=!1,c7=n(""),F5=null,CZ=T1(),N0=[],bZ=new Map,z5=new WeakMap,EZ=new Map,d7=k1(),WZ=n(!1);function W4(){if(!F(XZ))return null;let W=F(XZ).getRootNode();if(W&&"host"in W)return W.host;return F(XZ).parentElement}let x=d(()=>W4());function P0(W,q){if(!F(x)){N0=[...N0,{name:W,detail:q}];return}x7(F(x),W,q)}y(()=>{if(!F(x))return;if(N0.length===0)return;let W=N0;N0=[],queueMicrotask(()=>{let q=F(x);if(!q){N0=[...W,...N0];return}for(let _ of W)x7(q,_.name,_.detail)})});function i7(W){return W.details.length>0?W.details:[W.message]}function V4(W){if(!LZ())return{title:V,details:i7(W)};try{let q=LZ()(W)||{};return{title:typeof q.title==="string"&&q.title.trim().length>0?q.title:V,details:Array.isArray(q.details)&&q.details.length>0?q.details.map((_)=>String(_)):i7(W)}}catch(q){let _=q instanceof Error&&q.message.trim().length>0?q.message:String(q||"Unknown renderer error");return{title:V,details:[...W.details,`Error renderer failed: ${_}`]}}}function w0(W){let q=v5({kind:W.kind,source:W.source,error:W.error,recoverable:W.recoverable,scope:W.cohort?"cohort":"runtime",cohort:W.cohort});return G.reportFrameworkError(q),q}function l7(W){return(W||[]).map((q)=>q?.message).filter((q)=>typeof q==="string")}function K4(W,q){if(W?.type==="timed-media-policy-degraded"){G.reportFrameworkError(fZ({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:l7(W.degradations),recoverable:!0,scope:"cohort",cohort:q}));return}if(W?.type!=="timed-media-invalid")return;G.reportFrameworkError(fZ({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:l7(W.errors),recoverable:!1,scope:"cohort",cohort:q}))}function q4(W){if(W?.type!=="timed-media-audio-started")return;if(!F(b))return;M1(F(b).ttsService)}function U4(W){return W==="coordinator-init"||W==="runtime-init"||W==="tool-config"}function VZ(W){return`${W.kind}|${W.source}|${W.message}`}function s7(W){if(!O0())return;try{O0()(W),v7=VZ(W)}catch(q){console.error(`[pie-framework:${W.kind}:${W.source}] framework error hook failed`,q)}}let n7=new WeakSet,r7=new WeakMap;function $4(W){if(typeof W!=="object"||W===null)return null;return r7.get(W)??null}function a7(W){let q=V4(W);m(X0,W,!0),m(K5,q.title,!0),m(q5,q.details,!0)}function o7(){m(X0,null),m(K5,V),m(q5,[],!0)}y(()=>{let W=G.subscribeFrameworkErrors((q)=>{if(console.error(b8(q),q.cause),typeof q.cause==="object"&&q.cause!==null)r7.set(q.cause,q);if(U4(q.kind)&&!n7.has(q))a7(q);P0("framework-error",q),s7(q)});return()=>{W()}}),y(()=>{let W=Z0();if(!W||F(b)!==W)return;if(typeof W.subscribeFrameworkErrors!=="function")return;return I(()=>W.subscribeFrameworkErrors((q)=>{n7.add(q),G.reportFrameworkError(q)}))}),y(()=>{let W=F(b),q=p();if(!W||F(TZ))return;if(typeof W.adoptToolRegistry!=="function")return;I(()=>{let _=W===F(g);if(_&&!q)return;if(W.adoptToolRegistry(q)&&_&&jZ)jZ={...jZ,toolRegistry:q}})}),y(()=>{if(!F(X0))return;if(v7===VZ(F(X0)))return;s7(F(X0))});function F4(W){let q=5381;for(let _=0;_<W.length;_+=1)q=(q<<5)+q^W.charCodeAt(_);return(q>>>0).toString(36)}function a(W){return W&&typeof W==="object"?W:{}}function z4(W){let q=a(W.section),_=typeof q.identifier==="string"?q.identifier:"",w=typeof W.sectionId==="string"?W.sectionId:"";return _||w}function H4(W){return typeof W.currentItemIndex==="number"?W.currentItemIndex:-1}function A4(W){return(Array.isArray(W.renderables)?W.renderables:[]).map((_,w)=>{let L=a(_),A=a(L.entity),l=typeof A.id==="string"&&A.id||`renderable-${w}`,xZ=a(A.config),N5=typeof A.version==="string"&&A.version||(typeof A.version==="number"?String(A.version):"")||(typeof xZ.version==="string"?xZ.version:"");return{id:l,version:N5}})}function D4(W){let q=a(W.itemSessionsByItemId);return Object.keys(q).sort((_,w)=>_.localeCompare(w)).map((_)=>{let w=a(q[_]),L=typeof w.id==="string"?w.id:"",A=Array.isArray(w.data)?w.data:[],l="";try{l=F4(JSON.stringify(A))}catch{l=String(A.length)}return{itemId:_,sessionId:L,payloadSignature:l}})}function _4(W){let q=a(a(W.formative).states);return Object.entries(q).map(([_,w])=>{let L=a(w),A=a(L.lastOutcome).correctness??"";return`${_}:${L.tryCount??0}:${L.revealed===!0?1:0}:${String(A)}:${String(L.revealOverride??"")}`}).sort().join("|")}function M4(W){let q=W.timedMedia;return FQ(q)}function O4(W){let q=a(W),_=A4(q).map((L)=>`${L.id}:${L.version}`).join("|"),w=D4(q).map((L)=>`${L.itemId}:${L.sessionId}:${L.payloadSignature}`).join("|");return{sectionId:z4(q),currentItemIndex:H4(q),renderableSignature:_,itemSessionSignature:w,formativeSignature:_4(q),timedMediaSignature:M4(q)}}function L4(W){let q=O4(W);return`${q.sectionId}|${q.currentItemIndex}|${q.renderableSignature}|${q.itemSessionSignature}|${q.formativeSignature}|${q.timedMediaSignature}`}function t7(W){return W==="iife"||W==="esm"||W==="preloaded"||W==="custom"}function N4(W,q){let _=W?.type,w=t7(_)?_:t7(q)?q:W?.tagName?"custom":"iife",L=W?.tagName?.trim();if(w==="custom"&&!L)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:w,tagName:L||B[w],version:W?.version,source:W?.source,loaderConfig:W?.loaderConfig,loaderOptions:W?.loaderOptions,isDefault:!W&&!q}}function e7(W){let q=W||{},_=typeof q.mode==="string"&&q.mode.trim()?q.mode.trim():j.mode,w=typeof q.role==="string"&&q.role.trim()?q.role.trim():j.role;return{mode:_,role:w}}function P4(W){let q=e7(W);if(q.mode==="author")return"author";if(q.role==="instructor")return"scorer";return"candidate"}function Z8(W,q){return W.sectionId===q.sectionId&&W.attemptId===q.attemptId}function Q8(){if(!L0()||L0()===h7)return;h7=L0(),wZ={value:L0(),cohort:{sectionId:F(Q0),attemptId:z()||void 0}}}function J8(W,q){Q8();let _=wZ;if(!_)return null;if(!Z8(_.cohort,W)){if(q)wZ=null;return null}return wZ=null,_.value}function Y8(){let W=$5,q=F(b);if(!W||!q)return;let _=J8(W,!1);if(!_)return;let w=q.getSectionController(W);if(!w)return;let L=Q5(w.getSession?.()??null,_);if(!L)return;Promise.resolve().then(()=>{if(!w.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");return w.applySession(L,{mode:"replace"})}).catch((A)=>{w0({kind:"unknown",source:"pie-assessment-toolkit",error:A,recoverable:!0})})}async function w4(){if(M0())return M0()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function H5(){let W=E()||{},q=e1(S());if(q.length===0)return W;let _=W.placement||{},w=Array.isArray(_.section)?_.section:null;if(w&&w.length>0)return W;return{...W,placement:{..._,section:q}}}function R4(){return z8(H5(),{strictness:C(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:p()}).config}function C4(){let W="",q="";try{W=JSON.stringify(H5())}catch{W="[unserializable-tools]"}try{q=JSON.stringify(Object.entries(v()??{}).map(([_,w])=>[_,typeof w]))}catch{q="[unserializable-resolvers]"}return[K()||"",String(C()||"error"),W,q].join("|")}function b4(W){let q=W?.pnpEnforcement;return q==="on"||q==="off"?q:null}function E4(W){let q=K()||U()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new b7({assessmentId:q,lazyInit:M(),eagerInit:!1,toolConfigStrictness:C(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:W,toolRegistry:p(),toolContextResolvers:v(),accessibility:e(),frameworkErrorBus:G})}function X8(W){try{return JSON.stringify(W??null)}catch{return"[unserializable]"}}function G8(){return{signatures:{assessmentId:K()||"",toolConfigStrictness:String(C()||"error"),lazyInit:String(M()),tools:X8({...H5(),pnpEnforcement:void 0}),accessibility:X8(e())},toolRegistry:p()}}function S4(){let W=jZ;if(!W)return[];let q=G8(),_=Object.keys(q.signatures).filter((w)=>q.signatures[w]!==W.signatures[w]);if(W.toolRegistry&&q.toolRegistry!==W.toolRegistry)_.push("toolRegistry");return _}function y4(W,q){if(u7)return;u7=!0,console.warn(`[pie-assessment-toolkit] ${W.join(", ")} changed after ${q} with the coordinator this toolkit built, and that coordinator keeps the values it was built with. Set these inputs no later than the section or the first item scope, pass a coordinator of your own, or update this one from runtime-ready with updateToolConfig(...) or updateToolsPlacement(...). Reported once per toolkit.`)}function T4(W){if(g7)return;g7=!0,console.warn(`[pie-assessment-toolkit] The toolkit above this one (runtime "${W}") had no coordinator when this one connected, so this one built its own and keeps it: the two share no tool state, policy or read-aloud. Give the outer toolkit its coordinator before the inner one connects, or set isolation="force" on the inner one to keep them apart on purpose. Reported once per toolkit.`)}function SZ(){let W=F(g);if(!W)return Promise.resolve();return m(g,null),W.dispose()}function yZ(W){w0({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}let TZ=d(()=>!Z0()&&U0()!=="force"&&F(Y0)?.coordinator!=null),b=d(()=>{if(F(TZ))return F(Y0)?.coordinator;return Z0()||F(g)}),A5=d(()=>U()!=null);y(()=>{F(x),Z0(),U0(),F(Y0),v(),F(A5),F(WZ),E(),S(),K(),C(),M(),e(),p(),I(()=>{if(!F(x))return;if(Z0()){if(F(g))SZ().catch(yZ);g0=null;return}if(U0()!=="force"&&F(Y0)?.coordinator){if(F(g))SZ().catch(yZ);g0=null;return}if(F(g)){let W=S4();if(W.length>0&&BZ)y4(W,BZ);else if(W.length>0&&(U()||F(WZ)))SZ().catch(yZ)}if(F(g)&&g0!==v()){try{F(g).setToolContextResolvers(v()),g0=v()}catch(W){w0({kind:"coordinator-init",source:"pie-assessment-toolkit",error:W})}return}if(!F(g)){if(U0()!=="force"&&!GZ){let q=v1(F(x),W5);if(q?.coordinator&&q.runtimeId!==Y){m(Y0,q,!0),g0=null;return}}let W=C4();if(U5===W)return;try{let q=R4();m(g,E4(q),!0),GZ=U0()!=="force",jZ=G8(),BZ=null,g0=v(),U5="",o7()}catch(q){m(g,null),U5=W,w0({kind:"coordinator-init",source:"pie-assessment-toolkit",error:q})}}})}),y(()=>{if(!F(WZ)||!F(b))return;let W=F(b);I(()=>{if(W===F(g))BZ??="an item registered"})});let j8=KQ(),R0=d(()=>D()??j8),KZ=n(0);y(()=>{return F(R0).subscribe?.(()=>{m(KZ,F(KZ)+1)})}),y(()=>{let W=typeof N()==="string"?N().trim():"",q=F(R0);if(!W&&q!==j8)return;I(()=>{Promise.resolve(q.setLocale(W||qQ)).catch((_)=>{w0({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:_ instanceof Error?_:Error(String(_)),recoverable:!0})})})});let x4=d(()=>{return F(KZ),{locale:F(R0).getLocale(),direction:F(R0).getDirection?.()??"ltr"}});y(()=>{F(KZ);let W=F(x);if(!W)return;$Q(W,F(R0))});let C0=d(()=>K()||F(b)?.assessmentId||""),Q0=d(()=>b1({sectionId:$(),section:U(),assessmentId:K()})),D5=d(()=>e7(H())),k4=d(()=>P4(F(D5))),l0=d(()=>N4(r(),q0())),qZ=d(()=>GQ({player:F(l0),component:"pie-assessment-toolkit"})),f4=d(()=>{if(!F(b))return null;return{toolkitCoordinator:F(b),toolCoordinator:F(b).toolCoordinator,ttsService:F(b).ttsService,highlightCoordinator:F(b).highlightCoordinator,catalogResolver:F(b).catalogResolver,elementToolStateStore:F(b).elementToolStateStore,assessmentId:F(C0),sectionId:F(Q0),attemptId:z()||void 0,itemPlayer:F(l0),ndsIcons:O()===!0,locale:(F(KZ),F(R0).getLocale()),i18n:F(R0),contentLanguage:P()?.trim()||void 0,contentLanguageDefault:UQ({contentLanguage:P(),interfaceLocale:N()}),reportSectionError:(W)=>{X.reportSectionError({source:"section-runtime",error:W,timestamp:Date.now()})}}}),I4=d(()=>{if(!F(b)||!F(x))return null;return{runtimeId:Y,coordinator:F(b),sectionBound:F(A5),eventTarget:F(x)}});function B8(W){if(W==null)return;let q=L4(W);if(q===F(c7))return;m(c7,q,!0),m(PZ,F(PZ)+1),m(V5,W,!0),P0("composition-changed",{composition:F(V5),version:F(PZ)})}function _5(W){F5=W??X.getCompositionModel(),CZ.schedule(()=>{B8(F5)})}function v4(){if(!CZ.isPending())return;CZ.cancel(),B8(F5)}function M5(W){if(!W)return;let q=z5.get(W);if(!q)return;for(let _ of q)_();z5.delete(W)}function W8(){for(let W of bZ.values())M5(W.element)}function V8(W){if(M5(W.element),!F(b))return;z5.set(W.element,L1(F(b),W,{assessmentId:F(C0),sectionId:F(Q0)}))}function h4(){W8();for(let W of bZ.values())V8(W)}function O5(W){if(!W)return;EZ.get(W)?.(),EZ.delete(W)}function m4(W){O5(W),EZ.set(W,w1(W,{getMathSpeech:()=>F(b)?.ttsService.getMathSpeechOptions(),getContentLanguage:()=>P()}))}function u4(W){let _={...W.result?.eventDetail||W.fallbackSession,itemId:W.itemId,canonicalItemId:W.canonicalItemId||W.itemId,sourceRuntimeId:Y};if(!I1({state:d7,itemId:W.itemId,payload:_}))return;P0("session-changed",_)}function p4(W){if(!(W instanceof HTMLElement))return!1;return v1(W,W5)?.runtimeId===Y}function $0(W){return W.detail??null}function g4(W,q){for(let _ of q)W.addEventListener(_.name,_.handler);return()=>{for(let _ of q)W.removeEventListener(_.name,_.handler)}}y(()=>{let W=F(x),q=U0();return I(()=>{if(!W)return;if(q==="force")return m(Y0,null),()=>{GZ=!1};let _=t1(W,(w)=>{if(w.runtimeId===Y)return;if(GZ){T4(w.runtimeId);return}m(Y0,w,!0)});return()=>{_(),m(Y0,null),GZ=!1}})}),y(()=>{let W=F(b);if(!W)return;return I(()=>_1({ttsService:W.ttsService,silence:()=>X.requestMediaPauseForCompetingAudio()}))}),y(()=>{let W=F(TZ)?F(Y0)?.runtimeId??null:null,q=W?"inherited":"owned";if(q!==f7)f7=q,P0(q==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:W})}),y(()=>{let W=F(x);if(!W)return;I(()=>y1(W.ownerDocument))}),y(()=>{let W=F(b);if(!W)return;let q=F(TZ)?"inherited":"owned";I(()=>{if(W===I7)return;I7=W,P0("runtime-ready",{runtimeId:Y,coordinator:W,ownership:q})})}),y(()=>{let W=F(Q0),q=z()||"";f1(d7)}),y(()=>{if(!F(x))return;F(x).setAttribute("data-item-player-type",F(l0).type),F(x).setAttribute("data-item-player-tag",F(l0).tagName),F(x).setAttribute("data-env-mode",F(D5).mode),F(x).setAttribute("data-env-role",F(D5).role)}),y(()=>{return F(b),F(C0),F(Q0),h4(),()=>{W8()}}),y(()=>{if(!F(x))return;return XQ({host:F(x),instrumentationProvider:F(qZ),component:"pie-assessment-toolkit",eventMap:jQ,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:F(C0),sectionId:F(Q0),attemptId:z()||void 0}})});let L5=null;y(()=>{NZ(),E();let W=F(b);if(!W)return;if(W!==F(g))return;I(()=>{let q={pnpEnforcement:b4(E()),assessment:NZ()??null},_=L5?.coordinator===W?L5.inputs:null;L5={coordinator:W,inputs:q};for(let w of E1(_,q))if(w==="pnpEnforcement")W.setPnpEnforcement(q.pnpEnforcement);else W.updateAssessment(q.assessment)})}),y(()=>{if(!F(b))return;return F(b).subscribeTelemetry(({eventName:W,payload:q})=>{if(!VQ(F(qZ)))return;if(!F(qZ).isReady())return;let _=new Date().toISOString(),w={...q||{},instrumentationLayer:"toolkit",assessmentId:F(C0),sectionId:F(Q0),attemptId:z()||void 0,component:"pie-assessment-toolkit",sourceEventName:W,timestamp:_};F(qZ).trackEvent(W,w);let L=q&&typeof q.errorType==="string"?q.errorType:void 0;if(!W.endsWith("-error")&&!L)return;let A=q&&typeof q.message==="string"?q.message:`Toolkit telemetry error: ${W}`;F(qZ).trackError(Error(A),{component:"pie-assessment-toolkit",errorType:L||"ToolkitTelemetryError",...w})})}),y(()=>{if(!U()||!F(b))return;let W=!1;if(F(b)===I(()=>F(g)))BZ??="a section initialized";let q={sectionId:F(Q0),attemptId:z()||void 0},_=m7;if(m7=q,_&&!Z8(_,q))I(()=>h1(F(x),{reason:"teardown",logger:J}));$5=null;let w=I(()=>J8(q,!0));return X.initialize({coordinator:F(b),section:U(),sectionId:F(Q0),assessmentId:F(C0),attemptId:z()||void 0,view:F(k4),initialSession:w,createDefaultController:w4,onCompositionChanged:(L)=>{if(W)return;_5(L)},onControllerEvent:(L)=>{if(W)return;q4(L),K4(L,q)}}).then(()=>{if(W)return;$5=q;let L=I(()=>F(X0));if(L&&VZ(L)===RZ)o7();RZ=null,I(()=>Y8()),I(()=>v4()),queueMicrotask(()=>{if(W)return;P0("toolkit-ready",{runtimeId:Y,assessmentId:F(C0),sectionId:F(Q0),itemPlayer:F(l0),coordinator:F(b)}),P0("section-ready",{sectionId:q.sectionId,attemptId:q.attemptId,controller:F(b).getSectionController(q)??null})})}).catch((L)=>{if(W)return;let A=I(()=>$4(L));if(A)I(()=>a7(A)),RZ=VZ(A);else RZ=VZ(w0({kind:"runtime-init",source:"pie-assessment-toolkit",error:L,cohort:q}))}),()=>{W=!0}}),y(()=>{L0(),I(()=>{Q8(),Y8()})}),y(()=>{if(!F(x))return;let W=F(x),q=(L)=>{if(!O1(L,Y,p4))return!1;return L.stopPropagation(),!0},w=g4(W,[{name:Y5,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.element||!A?.itemId)return;let l=X.register(A);if(bZ.set(A.element,A),m(WZ,!0),V8(A),m4(A.element),X.handleContentRegistered(A),l)_5()}},{name:Z4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.itemId)return;let l=A?.element?X.unregister(A.element):!1;if(M5(A.element),O5(A.element),A.element)bZ.delete(A.element);if(X.handleContentUnregistered(A),l)_5()}},{name:Q4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.itemId)return;let l=X.updateItemSession(A.itemId,A.session);u4({itemId:A.itemId,canonicalItemId:X.getCanonicalItemId(A.itemId),result:l,fallbackSession:A.session})}},{name:Y4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.itemId)return;X.recordServedContentIdentity({itemId:A.itemId,canonicalItemId:A.canonicalItemId,identity:A.identity})}},{name:J4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.itemId)return;X.handleContentLoaded({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,detail:A.detail,timestamp:Date.now()})}},{name:X4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.itemId)return;X.handleItemPlayerError({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,error:A.error,timestamp:Date.now()})}},{name:G4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.itemId)return;if(A.action!=="check"&&A.action!=="retry")return;X.handleFormativeAction({itemId:A.itemId,canonicalItemId:A.canonicalItemId,action:A.action,outcomes:A.outcomes})}},{name:j4,handler:(L)=>{if(!q(L))return;let A=$0(L);if(!A?.renderableId)return;if(A.action!=="attach"&&A.action!=="detach")return;X.handleMediaTimeSource({renderableId:A.renderableId,action:A.action,source:A.source,origin:A.origin})}}]);return()=>{I(()=>h1(W,{reason:"teardown",logger:J})),w();for(let L of[...EZ.keys()])O5(L)}}),y(()=>{if(!F(x))return;return()=>{d0?.disconnect(),d0=null,c0?.disconnect(),c0=null,i0?.disconnect(),i0=null}}),y(()=>{let W=F(x),q=F(I4);if(!W||!q)return;I(()=>{if(d0){d0.setValue(q);return}d0=new y7(W,{context:W5,initialValue:q}),d0.connect()})}),y(()=>{let W=F(x),q=F(f4);if(!W||!q)return;I(()=>{if(c0){c0.setValue(q);return}c0=new y7(W,{context:o1,initialValue:q}),c0.connect()})}),y(()=>{let W=F(x),q=F(x4);if(!W)return;I(()=>{if(i0){i0.setValue(q);return}i0=new y7(W,{context:YQ,initialValue:q}),i0.connect()})});async function c4(){if(!F(b))throw Error("Coordinator not initialized");await F(b).waitUntilReady()}function d4(W){if(!F(b))throw Error("Coordinator not initialized");F(b).setHooks(W)}function i4(W){return X.navigateToItem(W)}function l4(){return X.getCompositionModel()}function s4(){return F(l0)}async function n4(){await X.persist()}async function r4(){await X.hydrate()}y(()=>{let W=F(b);if(!W)return;let q=F(PZ)>0||F(V5)!==null,_=!F(A5)&&F(WZ);if(!q&&!_)return;I(()=>{if(W===p7)return;p7=W,W.waitUntilReady().catch(()=>{})})}),y(()=>{return()=>{CZ.cancel(),X.dispose().catch((W)=>{w0({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}).then(()=>SZ()).catch(yZ).finally(()=>{G.dispose()})}});var a4={waitUntilReady:c4,setHooks:d4,navigateToItem:i4,getCompositionModel:l4,getItemPlayerConfig:s4,persist:n4,hydrate:r4,get assessmentId(){return K()},set assessmentId(W){K(W),k()},get section(){return U()},set section(W){U(W),k()},get sectionId(){return $()},set sectionId(W){$(W),k()},get attemptId(){return z()},set attemptId(W){z(W),k()},get env(){return H()},set env(W){H(W),k()},get ndsIcons(){return O()},set ndsIcons(W){O(W),k()},get locale(){return N()},set locale(W){N(W),k()},get i18n(){return D()},set i18n(W){D(W),k()},get contentLanguage(){return P()},set contentLanguage(W){P(W),k()},get lazyInit(){return M()},set lazyInit(W){M(W),k()},get toolConfigStrictness(){return C()},set toolConfigStrictness(W){C(W),k()},get tools(){return E()},set tools(W){E(W),k()},get toolContextResolvers(){return v()},set toolContextResolvers(W){v(W),k()},get enabledTools(){return S()},set enabledTools(W){S(W),k()},get toolRegistry(){return p()},set toolRegistry(W){p(W),k()},get accessibility(){return e()},set accessibility(W){e(W),k()},get player(){return r()},set player(W){r(W),k()},get playerType(){return q0()},set playerType(W){q0(W),k()},get coordinator(){return Z0()},set coordinator(W){Z0(W),k()},get createSectionController(){return M0()},set createSectionController(W){M0(W),k()},get onFrameworkError(){return O0()},set onFrameworkError(W){O0(W),k()},get errorRenderer(){return LZ()},set errorRenderer(W){LZ(W),k()},get assessment(){return NZ()},set assessment(W){NZ(W),k()},get isolation(){return U0()},set isolation(W){U0(W),k()},get session(){return L0()},set session(W){L0(W),k()}},K8=HQ(),q8=T7(K8);r1(q8,(W)=>m(XZ,W),()=>F(XZ));var o4=G5(q8,2);{var t4=(W)=>{var q=zQ(),_=c1(q),w=X5(_,!0),L=G5(_,2),A=X5(L,!0),l=G5(L,2),xZ=X5(l,!0);m1(q),d1((N5)=>{B5(w,F(K5)),B5(A,F(X0).message),B5(xZ,N5)},[()=>F(q5).join(`
|
|
225
|
+
`)]),j5(W,q)},e4=(W)=>{var q=i1(),_=T7(q);s1(_,Q,"default",{},null),j5(W,q)};l1(o4,(W)=>{if(F(X0)&&!F(X0).recoverable)W(t4);else W(e4,-1)})}return j5(Z,K8),p1(a4)}QQ("pie-assessment-toolkit",a1(B4,{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"},i18n:{type:"Object"},contentLanguage:{attribute:"content-language",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"},assessment:{type:"Object"},isolation:{attribute:"isolation",type:"String"},session:{type:"Object"}},["default"],["waitUntilReady","setHooks","navigateToItem","getCompositionModel","getItemPlayerConfig","persist","hydrate"],{mode:"open"},JQ));export{B4 as default};
|