@pie-players/pie-assessment-toolkit 1.0.0-beta.3 → 1.0.0-beta.4
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/README.md +15 -7
- package/custom-elements.json +19 -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-4vq9nbxz.js +2 -0
- package/dist/components/chunks/{ItemToolBar-jpac75fa.js → ItemToolBar-f971t0cw.js} +1 -1
- package/dist/components/chunks/{ItemToolBar-341vf20n.js → ItemToolBar-n05xjkp8.js} +2 -2
- package/dist/components/chunks/{ItemToolBar-66hcwmfw.js → ItemToolBar-pxan157g.js} +2 -2
- package/dist/components/chunks/ItemToolBar-rgmvw9sm.js +40 -0
- package/dist/components/chunks/{ItemToolBar-kkj69ptr.js → ItemToolBar-xwjrpdmz.js} +1 -1
- package/dist/components/chunks/sre-engine-dq0w45fv.js +1 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts +8 -0
- package/dist/policy/core/ToolPolicyEngine.js +4 -2
- package/dist/policy/core/compose-decision.d.ts +7 -1
- package/dist/policy/core/compose-decision.js +29 -0
- package/dist/policy/core/decision-types.d.ts +20 -0
- package/dist/policy/core/feature-decision.d.ts +8 -1
- package/dist/policy/core/feature-decision.js +9 -2
- package/dist/policy/core/provenance.d.ts +1 -1
- package/dist/policy/engine.d.ts +2 -1
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -2
- package/dist/policy/sources/PnpPolicySource.js +80 -11
- package/dist/runtime/core/engine-resolver.d.ts +17 -0
- package/dist/runtime/item-feature-decisions.d.ts +44 -0
- package/dist/runtime/item-feature-decisions.js +115 -0
- package/dist/services/ToolkitCoordinator.d.ts +9 -0
- package/dist/services/ToolkitCoordinator.js +23 -0
- package/dist/services/interfaces.d.ts +10 -0
- package/dist/services/support-conflicts.d.ts +10 -0
- package/dist/services/support-conflicts.js +11 -0
- package/dist/services/tool-config-validation.js +8 -2
- package/dist/services/tool-icons.js +1 -0
- package/package.json +6 -6
- package/dist/components/chunks/ItemToolBar-qvtpthc9.js +0 -40
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +0 -2
- package/dist/components/chunks/sre-engine-bj997w4b.js +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as q8,c as J5,d as n1,e as r1,g as a1,h as o1,i as t1,j as e1,k as M8,l as L8}from"./chunks/ItemToolBar-4vq9nbxz.js";import{q as U1,r as P7,s as H0,t as s1,u as i0}from"./chunks/ItemToolBar-n05xjkp8.js";import{A as k,B as s,C as h,D as I1,E as v1,F as E7,G as Y5,H as X5,I as T,J as h1,K as F,L as I,O as T7,P as m1,Q as G5,R as j5,S as u1,W as p1,X as g1,ba as c1,ca as f,da as d1,ea as l1,fa as B5,ia as S7,la as i1,na as P1,oa as u0,w as x1,x as k1,y as f1,z as c}from"./chunks/ItemToolBar-f971t0cw.js";import{pa as z9,qa as D9}from"./chunks/ItemToolBar-pxan157g.js";import{sa as _3}from"./chunks/ItemToolBar-xwjrpdmz.js";import{coerceBooleanAttributes as l2}from"@pie-players/pie-players-shared/ui/attribute-coercion";import{ContextProvider as b7,interfaceLocaleContext as i2,requestContext as T1}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as s2,resolveInstrumentationProvider as n2,TOOLKIT_INSTRUMENTATION_EVENT_MAP as r2}from"@pie-players/pie-players-shared/pie";import{commitPendingSessions as y1,createPieLogger as a2,isGlobalDebugEnabled as o2,isInstrumentationProvider as t2}from"@pie-players/pie-players-shared";import{createPieI18n as e2,DEFAULT_LOCALE as ZQ,stampInterfaceLocale as QQ}from"@pie-players/pie-players-shared/i18n";import{settleAll as _Z}from"@pie-players/pie-players-shared/promise";var s4="error";function N5(Z){if(Z==="off"||Z==="warn"||Z==="error")return Z;return s4}function a(Z){return Z}function n4(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 r4(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(a({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(a({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 a4(Z,Q,J,Y){if(!Q||!J?.validateConfig)return;try{let X=J.validateConfig(Q);if(!Array.isArray(X)){Y.push(a({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(a({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 o4(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(a({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(a({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(a({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${G}" does not support level "${X}".`,toolId:G}))}}var V8=new Set(q8);function t4(Z,Q,J){if(Q.size===0)return;for(let Y of Z.policy.allowed||[]){if(Q.has(Y)||V8.has(Y))continue;J.push(a({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)||V8.has(Y))continue;J.push(a({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${Y}" in policy.blocked.`,toolId:Y}))}}function e4(Z,Q,J){for(let Y of Object.keys(Z.providers).sort()){if(Q.size===0||Q.has(Y))continue;J.push(a({code:"tools.unknownProviderKey",severity:"error",path:`providers.${Y}`,message:`Unknown provider key "${Y}".`,toolId:Y}))}}function K8(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 Z6(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 Y8(Z,Q={}){let J=L5(Z,Q.toolRegistry);return M5(J.diagnostics,Q),J}function L5(Z,Q){let J=m6(Q),Y=dZ(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]=u6(V,j[V],K,X),p6(V,j[V],K,X)}let B={...Y,providers:j};return g6(B,J,X),c6(B,J,X),d6(B,J,X),{config:B,diagnostics:X}}function M5(Z,Q={}){let J=O5(Q.strictness),Y=Q.source??"tools";if(J==="warn")J8(Z,Y);let X=Z.filter((G)=>G.severity==="error");if(J==="error"&&X.length>0)l6(X,Y);if(J==="error"&&X.length===0)J8(Z,Y)}import{languageTagLookupSequence as a6,normalizeLanguageTag as B8}from"@pie-players/pie-players-shared/i18n/language-tags";var w5=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),X8=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),G8=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),j8=new Set(["break","mark","lexicon"]);function i6(Z){let Q=Z;for(let J of j8){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 s6=[/^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 n6(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!s6.some((Y)=>Y.test(J))}function P5(Z){let Q=Array.from(Z.children);for(let Y of Q){let X=Y.tagName.toLowerCase();if(X8.has(X)){Y.remove();continue}if(P5(Y),!w5.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(!G8.has(Y.toLowerCase()))Z.removeAttribute(Y);if(Z.tagName.toLowerCase()==="audio"){let Y=Z.getAttribute("src");if(Y!==null&&!n6(Y))Z.removeAttribute("src")}}function N5(Z){let Q=Z.tagName.toLowerCase(),J=Array.from(Z.attributes).filter((X)=>G8.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${r6(X.value)}"`).join("");if(j8.has(Q))return`<${Q}${J}/>`;let Y=[];for(let X of Array.from(Z.childNodes))if(X.nodeType===3)Y.push(b0(X.nodeValue??""));else if(X.nodeType===1){let G=X,j=G.tagName.toLowerCase();if(X8.has(j))continue;if(w5.has(j))Y.push(N5(G));else Y.push(b0(G.textContent??""))}return`<${Q}${J}>${Y.join("")}</${Q}>`}function R5(Z){let Q=String(Z||"").trim();if(!Q||!Q.includes("<"))return Z;if(typeof DOMParser>"u")return Z;let Y=new DOMParser().parseFromString(i6(Q),"text/html"),X=Y.querySelector("speak");if(X)return P5(X),N5(X);let G=Y.createElement("speak");for(let j of Array.from(Y.body.childNodes))G.appendChild(j);return P5(G),Array.from(G.childNodes).map((j)=>{if(j.nodeType===3)return b0(j.nodeValue??"");if(j.nodeType===1){let B=j;if(w5.has(B.tagName.toLowerCase()))return N5(B);return b0(B.textContent??"")}return""}).join("")}function b0(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function r6(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var F8=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),C5="ext:";function W8(Z){if(F8.has(Z))return!0;return Z.startsWith(C5)&&Z.length>C5.length}var V8=new Set;function E5(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)=>E5(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]=E5(G,Q);return Object.freeze(Y)}finally{Q.delete(Z)}}function q8(Z,Q,J){let Y=`${Q}|${Z}`;if(V8.has(Y))return;V8.add(Y);let X=`${Array.from(F8).join(", ")}, or an "${C5}" 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 K8=(Z)=>Z.payload!==void 0?"payload":"content";class b5{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=U8(Q),X=[],G=[];try{G=$8(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(!W8(Q.type))q8(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=R5(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:E5(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(!W8(J.catalog))q8(J.catalog,"card",Q.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?R5(J.content):J.content}})}))}findMatchingCard(Z,Q){let{type:J,language:Y,useFallback:X=!0,form:G}=Q,j=[],B=(V)=>{for(let K of a6(V))j.push((U)=>B8(U.language)===K)};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(($)=>K8($)===G);if(U)return U}return K[0]}return null}getAllAlternatives(Z){let Q=[],J=new Set,Y=(j,B)=>{let V=`${j.catalog}|${B8(j.language)}|${K8(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 z8=["assessmentId","sectionId","attemptId","itemId","elementId"];function S5(Z){return Z.replace(/%/g,"%25").replace(/:/g,"%3A")}function o6(Z){return Z.replace(/%(25|3A)/g,(Q,J)=>J==="25"?"%":":")}class T5{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Z){return z8.map((Q)=>S5(Z[Q])).join(":")}parseGlobalElementId(Z){let Q=Z.split(":");if(Q.length!==z8.length)return null;let[J,Y,X,G,j]=Q.map(o6);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=`${S5(Z)}:${S5(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 S0(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 y5(Z){let Q=Z.error instanceof Error&&Z.error.message.trim().length>0?Z.error.message:String(Z.error||"Unknown framework error");return S0({kind:Z.kind,source:Z.source,message:Q,recoverable:Z.recoverable,scope:Z.scope,cohort:Z.cohort,cause:Z.error})}var t6={"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 D8(Z){let Q=t6[Z.context.phase],J=Z.context.toolId?`pie-toolkit-coordinator/${Z.context.toolId}`:`pie-toolkit-coordinator:${Z.context.phase}`;return y5({kind:Q,source:J,error:Z.error,recoverable:Z.recoverable,scope:Z.scope,cohort:Z.cohort})}function H8(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 U8(Z,Q={}){let J=P5(Z,Q.toolRegistry);return w5(J.diagnostics,Q),J}function P5(Z,Q){let J=n4(Q),Y=i0(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]=r4(V,j[V],K,X),a4(V,j[V],K,X)}let B={...Y,providers:j};return o4(B,J,X),t4(B,J,X),e4(B,J,X),{config:B,diagnostics:X}}function w5(Z,Q={}){let J=N5(Q.strictness),Y=Q.source??"tools";if(J==="warn")K8(Z,Y);let X=Z.filter((G)=>G.severity==="error");if(J==="error"&&X.length>0)Z6(X,Y);if(J==="error"&&X.length===0)K8(Z,Y)}import{languageTagLookupSequence as G6,normalizeLanguageTag as D8}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"]),$8=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),F8=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),z8=new Set(["break","mark","lexicon"]);function Q6(Z){let Q=Z;for(let J of z8){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 J6=[/^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 Y6(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!J6.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($8.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(!F8.has(Y.toLowerCase()))Z.removeAttribute(Y);if(Z.tagName.toLowerCase()==="audio"){let Y=Z.getAttribute("src");if(Y!==null&&!Y6(Y))Z.removeAttribute("src")}}function C5(Z){let Q=Z.tagName.toLowerCase(),J=Array.from(Z.attributes).filter((X)=>F8.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${X6(X.value)}"`).join("");if(z8.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($8.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(Q6(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 X6(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var N8=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),S5="ext:";function H8(Z){if(N8.has(Z))return!0;return Z.startsWith(S5)&&Z.length>S5.length}var A8=new Set;function T5(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)=>T5(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]=T5(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(N8).join(", ")}, or an "${S5}" 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 y5{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:T5(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)=>{for(let K of G6(V))j.push((U)=>D8(U.language)===K)};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}|${D8(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 P8=["assessmentId","sectionId","attemptId","itemId","elementId"];function x5(Z){return Z.replace(/%/g,"%25").replace(/:/g,"%3A")}function j6(Z){return Z.replace(/%(25|3A)/g,(Q,J)=>J==="25"?"%":":")}class k5{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Z){return P8.map((Q)=>x5(Z[Q])).join(":")}parseGlobalElementId(Z){let Q=Z.split(":");if(Q.length!==P8.length)return null;let[J,Y,X,G,j]=Q.map(j6);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=`${x5(Z)}:${x5(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 f5(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 B6={"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=B6[Z.context.phase],J=Z.context.toolId?`pie-toolkit-coordinator/${Z.context.toolId}`:`pie-toolkit-coordinator:${Z.context.phase}`;return f5({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}
|
|
4
4
|
- ${Z.details.join(`
|
|
5
|
-
- `)}`}class
|
|
5
|
+
- `)}`}class qZ{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 W6=new Set(["pie-item-toolbar","pie-section-toolbar","pie-item-player-session-debugger"]),V6=["pie-tool-","pie-section-player-tools-"],K6=new Set(["style","script","noscript","template"]),m=(Z)=>!!Z&&Z.nodeType===11&&Z.host?.nodeType===1,q6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(W6.has(Q))return!0;return V6.some((J)=>Q.startsWith(J))},U6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(K6.has(Q))return!0;if(q6(Z))return!0;return m(Z.parentNode)&&Z.getAttribute("aria-hidden")==="true"},$6=(Z)=>{if(!m(Z.getRootNode?.()))return null;let Q=Z.assignedNodes;if(typeof Q!=="function")return null;try{return Q.call(Z,{flatten:!0})}catch{return null}},U0=(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=$6(Y)??Y.childNodes}let J=[];for(let Y of Array.from(Q||[])){if(Y.nodeType===1&&U6(Y))continue;J.push(Y)}return J},UZ=(Z,Q)=>{let J=(Y)=>{for(let X of U0(Y)){let G=Q(X);if(G==="stop")return!1;if(G==="skip")continue;if(!J(X))return!1}return!0};J(Z)},C0=(Z)=>{let Q=[];return UZ(Z,(J)=>{if(J.nodeType===3)Q.push(J);return}),Q},b8=(Z)=>C0(Z).map((Q)=>Q.data).join(""),E8=(Z,Q)=>{let J=[];return UZ(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))J.push(Y);return}),J},b0=(Z,Q)=>{let J=null;return UZ(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))return J=Y,"stop";return}),J},C8=(Z)=>{let Q=Z.assignedSlot;if(Q)return Q;let J=Z.parentNode;if(m(J))return J.host;return J},g=(Z)=>{let Q=C8(Z);while(Q&&Q.nodeType!==1)Q=C8(Q);return Q},I5=(Z,Q)=>{let J=Z.nodeType===1?Z:g(Z);while(J){if(J.matches(Q))return J;J=g(J)}return null},d=(Z)=>{if(Z.parentElement)return Z.parentElement;let Q=Z.parentNode;return m(Q)?Q.host:null},fZ=(Z,Q,J)=>{let Y=Z.nodeType===1?Z:d(Z);while(Y){if(Y.matches(Q))return Y;if(J&&Y===J)return null;Y=d(Y)}return null},Q0=(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=m(Y)?Y.host:null}return!1},S8=(Z,Q)=>{let J=Z;while(J){let Y=J.getRootNode?.();if(Y===Q)return J;J=m(Y)?Y.host:null}return null},$Z=(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 T8(Z,S8(Q,Y))}catch{return!1}},X0=(Z,Q)=>{try{let J=Z.startContainer.getRootNode?.();if(!J||Q.getRootNode?.()===J)return Z.intersectsNode(Q);return T8(Z,S8(Q,J))}catch{return!1}},T8=(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 v5=" >>> ";class h5{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`${m(J)?this.getShadowRootPath(J,Q):this.getElementPath(J,Q)}::text[${X}]`}if(Z.nodeType===Node.ELEMENT_NODE)return this.getElementPath(Z,Q);if(m(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 M=G.getRootNode?.();if(m(M)&&M!==J){j(M);continue}break}let{parentElement:B,parentNode:V}=G,K=B??(m(V)?V:null);if(!K)break;let U=G.tagName,$=Array.from(K.children).filter((M)=>M.tagName===U),z=$.indexOf(G),D=$.length>1?`${U.toLowerCase()}:nth-of-type(${z+1})`:U.toLowerCase();if(X.unshift(D),B)G=B;else j(K)}return Y.unshift(X.join(" > ")),Y.join(v5)}getShadowRootPath(Z,Q){return`${this.getElementPath(Z.host,Q)}${v5}`}resolveElementPath(Z,Q){let J=Q,Y=Z.split(v5);for(let X=0;X<Y.length;X++){if(X>0){let B=m(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 p5;(function(Z){Z.TTS_WORD="tts-word",Z.TTS_SENTENCE="tts-sentence",Z.ANNOTATION="annotation"})(p5||(p5={}));var IZ;(function(Z){Z.YELLOW="yellow",Z.GREEN="green",Z.BLUE="blue",Z.PINK="pink",Z.ORANGE="orange",Z.UNDERLINE="underline"})(IZ||(IZ={}));var I8=`
|
|
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 Y8(Z,Q={}){let J=L5(Z,Q.toolRegistry);return M5(J.diagnostics,Q)
|
|
|
212
212
|
text-shadow: none;
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
`,P8=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet"),N8=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet-adopted"),w8=(Z)=>!!Z&&typeof Z.replaceSync==="function",G4=()=>{let Z=globalThis,Q=Z[P8];if(w8(Q))return Q;let J=globalThis.CSSStyleSheet;if(typeof J!=="function")return null;try{let Y=new J;if(!w8(Y))return null;return Y.replaceSync(C8),Z[P8]=Y,Y}catch{return null}},K0=(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[N8];if(G&&X.includes(G))return;let j=G4();if(!j)return;try{J.adoptedStyleSheets=[...X,j],J[N8]=j}catch{}},I5="tts-word",v5="tts-sentence",lZ=(Z)=>`annotation-${Z}`,EZ=(Z)=>{let Q=CSS.highlights.get(Z);if(Q)return Q;let J=new Highlight;return CSS.highlights.set(Z,J),J},U0=(Z,Q)=>{let J=CSS.highlights.get(Z);if(!J)return;for(let Y of Q)J.delete(Y)},R8=(Z)=>{let Q=Z[0]?.startContainer;if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:g(Q)},XZ={source:null,override:null};class $0{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 f5,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=XZ.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 s=this.blend(K,j,r),HZ=this.contrastRatio(s,j),AZ=this.contrastRatio(s,B),_Z=HZ*1.2+AZ*0.8;if(HZ>=1.25&&AZ>=2.4){$=r;break}if(_Z>z)z=_Z,$=r}let D=Math.max(0.24,Math.min(0.85,$*0.55)),L=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,L),O=this.contrastRatio(N,j),S=this.relativeLuminance(j)>0.45?[0,0,0]:[255,255,255],C=O>=1.35?H:S,h=`rgba(${K[0]}, ${K[1]}, ${K[2]}, ${$})`,E=`rgba(${K[0]}, ${K[1]}, ${K[2]}, ${D})`,d=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${L})`,VZ=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${P})`;return{wordHighlight:h,sentenceHighlight:E,wordUnderline:d,wordShadow:VZ}}applyAdaptiveTTSStyle(Z){if(typeof document>"u")return;if(Z)this.ttsStyleSource=Z,XZ.source=Z;let Q=Z??(XZ.source?.isConnected?XZ.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;EZ(I5),EZ(v5);for(let Z of Object.values(y0))EZ(lZ(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=C8,document.head.appendChild(Z)}highlightTTSWord(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(R8(Z)),this.clearTTSWord();let Q=EZ(I5);for(let J of Z)K0(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),K0(Z),this.clearTTSWord(),Z.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(Z)}highlightTTSSentence(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(R8(Z)),this.clearTTSSentence();let Q=EZ(v5);for(let J of Z)K0(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)K0(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,$0.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-word-element",this.ttsWordElementHighlights,$0.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Z,Q,J,Y){let X=(G)=>G.nodeType===Node.ELEMENT_NODE?G:g(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=g(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($)&&!ZZ($,K)&&!ZZ($,U))continue}catch{continue}$.setAttribute(Q,"true"),J.add($)}}}clearTTSWord(){if(!this.supported)return;U0(I5,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;U0(v5,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(),XZ.source===this.ttsStyleSource)XZ.source=null;this.ttsStyleSource=null}addAnnotation(Z,Q=y0.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,Y=Z.cloneRange();K0(Y.startContainer);let X={id:J,range:Y,type:h5.ANNOTATION,color:Q,timestamp:Date.now()};if(this.annotations.set(J,X),this.supported)EZ(lZ(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)U0(lZ(Q.color),[Q.range]);this.annotations.delete(Z)}clearAnnotations(){if(this.supported)for(let Z of this.annotations.values())U0(lZ(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)U0(lZ(Y),[J.range]),EZ(lZ(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;XZ.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(),XZ.override?.owner===this)XZ.override=null;this.themeObserver?.disconnect(),this.themeObserver=null}}import{applyMediaFragment as c3,enforceMediaFragment as d3}from"@pie-players/pie-players-shared/media";import{createPieLogger as l3,isTtsDebugEnabled as h9}from"@pie-players/pie-players-shared/pie";import{isUnsupportedMediaAssetVersion as j4,normalizeMediaFragment as B4,normalizeMediaSources as W4,trimmedOrUndefined as V4}from"@pie-players/pie-players-shared/media";function E8(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(j4(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=W4(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:B4(Q.fragment),label:V4(J.label)}}var q4="[data-pie-shell-root]";var b8=(Z)=>Z?T0(Z,q4):null;var x0="en-US",m5=(Z,Q)=>{let J=!Z?null:Z.nodeType===1?Z:g(Z);while(J){let Y=J.getAttribute("lang")?.trim();if(Y)return Y;if(Q&&J===Q)return;J=g(J)}return},u5=(Z,Q={})=>{let J=Q.boundary!==void 0?Q.boundary:b8(Z);return(J?m5(Z,J):void 0)||Q.contentLanguage?.trim()||void 0},S8=(Z,Q={})=>u5(Z,Q)??x0;var y=(Z)=>Z.trim().replace(/\s+/g," "),k8=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,k0=(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},iZ=(Z,Q)=>{let J=Z.nodeType===1?Z:p(Z);while(J){if(k0(J))return!0;if(Q&&J===Q)break;J=p(J)}return!1},T8="data-tts-suppress",f8=new Set(["computer-read-aloud","all"]),y8=new Set([...f8,"screen-reader"]),x8=new Set,K4=(Z)=>{let Q=Z.getAttribute?.(T8);if(Q===null||Q===void 0)return!1;let J=Q.trim().toLowerCase();if(f8.has(J))return!0;if(y8.has(J))return!1;if(!x8.has(J))x8.add(J),console.warn(`[tts] ${T8}="${Q}" is not one of ${Array.from(y8).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},f0=(Z,Q)=>{let J=Z.nodeType===1?Z:p(Z);while(J){if(K4(J))return!0;if(Q&&J===Q)break;J=p(J)}return!1},UZ=(Z,Q)=>iZ(Z,Q)||f0(Z),p5=(Z,Q)=>{if(typeof Z.intersectsNode!=="function")return{text:Z.toString(),filtered:!1};let J=[],Y=!1;for(let X of RZ(Q))if(YZ(Z,X))if(UZ(X,Q))Y=!0;else J.push(g5(X,Z));return{text:J.join(""),filtered:Y}},g5=(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)},F0=(Z,Q,J)=>{let Y=null,X=null;for(let G of RZ(Q)){if(UZ(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 YZ(Z,Q);return q0(Z,Y.node,Y.offset)&&q0(Z,X.node,X.offset)},c5=(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},bZ=(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 RZ(Z))if(p(U)&&!UZ(U,Z)){let z=U.textContent||"",D=z.match(/\S/),L=D?D[0]:null;if(!G&&!j&&c5(V,L,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 U4=/^\s*<speak[\s/>]/i,v0=(Z)=>U4.test(Z),$4=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),I8=new Set(["audio","phoneme"]),h8=(Z)=>Z.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),I0=(Z,Q,J)=>{for(let Y=0;Y<Q.length;Y++)Z.push({char:Q[Y],rawOffset:J===null?null:J+Y})},F4=(Z,Q,J)=>{let Y=Q.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!Y)return 0;return I0(Z,h8(Y[0]),J),Y[0].length},v8=(Z)=>{Z.push({char:" ",rawOffset:null})},z4=(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}},D4=(Z)=>{return Z.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},H4=(Z,Q)=>{let J=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),Y=Z.match(J);return h8(Y?.[2]??Y?.[3]??"")||null},h0=(Z)=>{let Q=[],J=!1,Y=!1,X=0;while(X<Z.length){let j=Z[X];if(j!=="<"){if(j==="&"){let z=F4(Q,Z,X);if(z>0){X+=z;continue}}I0(Q,j,X),X++;continue}let B=Z.indexOf(">",X+1);if(B<0){I0(Q,j,X),X++;continue}Y=!0;let V=Z.slice(X,B+1),K=D4(V),U=/^<\s*\//.test(V),$=/\/\s*>$/.test(V);if(!U&&K==="sub"){let z=H4(V,"alias");if(!z){J=!0,X=B+1;continue}I0(Q,z,null);let D=Z.toLowerCase().indexOf("</sub>",B+1);X=D>=0?D+6:B+1;continue}if(!U&&K==="break"){v8(Q),X=B+1;continue}if(!U&&I8.has(K)){if(J=!0,$){X=B+1;continue}}if(K&&!$4.has(K)&&!I8.has(K)&&K!=="break"&&K!=="sub")J=!0;if(!U&&(K==="p"||K==="s"))v8(Q);X=B+1}let G=z4(Q);return{spokenText:y(G.text),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:Y}};var A4=k8(),_4=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),O4=(Z)=>{let Q=Z.toLowerCase();return _4.get(Q)||Q},i5=(Z)=>{let Q=[];for(let J of Z.matchAll(A4)){let Y=J[0],X=J.index??0;Q.push({text:Y,normalized:O4(Y),start:X,end:X+Y.length})}return Q},L4=(Z)=>i5(Z).map((Q,J)=>({...Q,id:`speech-token-${J}`,sourceStart:Q.start,sourceEnd:Q.end,coordinateSystem:"normalized-speech"})),SZ=(Z)=>{let Q=h0(Z.speechText);return{speechText:Z.speechText,spokenText:Q.spokenText,tokens:L4(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},s5=(Z)=>Boolean(Z&&/^<[^>]+>$/.test(Z.trim())),sZ=(Z)=>{if(!Z||s5(Z))return null;return SZ({speechText:Z}).tokens[0]?.normalized??null},M4=(Z,Q)=>Z.find((J)=>J.start<=Q&&Q<J.end)||null,P4=(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},d5=(Z,Q,J)=>{if(Q===null)return null;let Y=M4(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}},l5=(Z,Q)=>Boolean(Z&&Q&&Z.token.normalized===Q),n5=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||s5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=sZ(Z.boundaryWord),Y=d5(Z.tokenization,P4(Z.tokenization,Z.position),Q),X=d5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(l5(Y,J))return{...Y,confidence:1};if(l5(X,J))return{...X,confidence:1};if(J)return null;return Z.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||X:X||Y},m8=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||s5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=sZ(Z.boundaryWord),Y=d5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(l5(Y,J))return{...Y,confidence:1};if(J)return null;return Y};var r5=10,N4=0.12,w4=[{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}],R4=(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:r5});for(let X of w4){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},C4=(Z,Q)=>{let J=R4(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,L=Math.max(0,Math.abs(z-D)-2),P=Y[U]+K.score-L;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}})},E4=(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/r5;return Math.min(1,Y*X)},m0=(Z)=>{let Q=SZ({speechText:Z.speechText}),J=y(Z.visibleText),Y=Q.tokens,X=i5(J),G=Q.unsupportedSemantic?[]:C4(Y,X),j=E4(G,Y,X),B=Q.spokenText===J&&Q.spokenText.length>0,V=G.length===1&&G[0].score===r5&&Y.length<=2&&X.length<=2,K=(G.length>=2||V)&&j>=N4,U=Q.unsupportedSemantic?"region-fallback":B?"exact-word":K?"anchor-span":"region-fallback";return{speech:Q,visibleText:J,playbackMode:U,anchors:G,confidence:j}},u8=(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 b4=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"]]]),S4=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),p8=new Map([["2",["squared"]],["3",["cubed"]]]),T4=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),y4=(Z)=>Z.replace(/\s+/g," ").trim(),TZ=(Z)=>(Z.localName||Z.tagName||"").toLowerCase(),x4=(Z)=>Z.nodeType===Node.ELEMENT_NODE,nZ=(Z)=>Array.from(Z.childNodes).filter(x4),a5=(Z)=>y4(Z.textContent||""),GZ=(Z,Q)=>({type:"element-range",quality:Q,element:Z}),k4=(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"}},f4=(Z,Q)=>{if(Q==="operator"){if(Z==="−")return"-";return Z}return Z.toLowerCase()},I4=(Z,Q,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return p8.get(Z)??[];if(Z==="|")return["absolute value"];if(Q==="operator")return b4.get(Z)||[];return[]},yZ=(Z)=>{let Q=Z.normalized??f4(Z.text,Z.kind||"unknown");return{id:`math-token-${Z.state.nextId++}`,kind:Z.kind,role:Z.role,text:Z.text,normalized:Q,spokenAliases:I4(Z.text,Z.kind,Z.role),sourceElement:Z.sourceElement,path:Z.path,target:Z.target||GZ(Z.sourceElement,"element-range"),optional:Z.optional}},xZ=(Z,Q,J="tokens")=>{Z[J].push(Q)},g8=(Z,Q,J)=>{nZ(Z).forEach((Y,X)=>jZ(Y,Q,`${J}/${TZ(Y)}[${X}]`))},v4=(Z,Q,J)=>{let Y=nZ(Z);if(Y[0])jZ(Y[0],Q,`${J}/numerator`);if(xZ(Q,yZ({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:Z,path:J,target:GZ(Z,"element-range")})),Y[1])jZ(Y[1],Q,`${J}/denominator`)},h4=(Z,Q,J)=>{let Y=Z.getAttribute("open")||"(",X=Z.getAttribute("close")||")";xZ(Q,yZ({state:Q,kind:"operator",role:Y==="|"?"absolute-value-fence":"open-fence",text:Y,sourceElement:Z,path:`${J}/open`,target:GZ(Z,"element-range")})),g8(Z,Q,J),xZ(Q,yZ({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Z,path:`${J}/close`,target:GZ(Z,"element-range")}))},m4=(Z,Q,J)=>{let Y=nZ(Z);if(Y[0])jZ(Y[0],Q,`${J}/base`);let X=Y[1];if(!X)return;let G=a5(X);if(p8.has(G)){xZ(Q,yZ({state:Q,kind:"structure",role:"superscript",text:G,normalized:G,sourceElement:X,path:`${J}/exponent`,target:GZ(Z,"element-range")}));return}jZ(X,Q,`${J}/exponent`)},u4=(Z,Q,J,Y)=>{xZ(Q,yZ({state:Q,kind:"structure",role:Y,text:a5(Z)||Y,normalized:`\x00${Y}`,sourceElement:Z,path:J,target:GZ(Z,"element-range")}))},p4=(Z,Q,J)=>{let Y=0;for(let X of nZ(Z)){if(TZ(X)==="mtr"||TZ(X)==="mlabeledtr")Y++,xZ(Q,yZ({state:Q,kind:"layout",role:"table-row",text:`row-${Y}`,normalized:`row-${Y}`,sourceElement:X,path:`${J}/row[${Y}]`,target:GZ(X,"region-fallback")}),"layoutTargets");jZ(X,Q,`${J}/${TZ(X)}[${Y}]`)}},g4=(Z,Q,J)=>{let Y=a5(Z);if(!Y)return;let X=k4(TZ(Z)),G=X==="operator"?S4.get(Y):void 0,j=G??(X==="operator"&&(Y==="("||Y===")")?"grouping-fence":X);xZ(Q,yZ({state:Q,kind:X,role:j,text:Y,sourceElement:Z,path:J,target:G&&Z.parentElement?GZ(Z.parentElement,"region-fallback"):void 0,optional:Boolean(G)||j==="grouping-fence"}))},jZ=(Z,Q,J)=>{let Y=TZ(Z);switch(Y){case"annotation":case"annotation-xml":return;case"semantics":{let X=nZ(Z).find((G)=>{let j=TZ(G);return j!=="annotation"&&j!=="annotation-xml"});if(X)jZ(X,Q,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":g4(Z,Q,J);return;case"mfrac":v4(Z,Q,J);return;case"msup":m4(Z,Q,J);return;case"mfenced":h4(Z,Q,J);return;case"mtable":p4(Z,Q,J);return;case"mphantom":return;case"maction":{let X=nZ(Z)[0];if(X)jZ(X,Q,`${J}/action`);return}default:{let X=T4.get(Y);if(X){u4(Z,Q,J,X);return}g8(Z,Q,J)}}},c8=(Z)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return jZ(Z,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:GZ(Z,"region-fallback")}};var d8=(Z)=>{if(!Z.boundary)return null;return Z.alignment.segments.find((J)=>J.speechTokenIds.includes(Z.boundary.token.id))?.target||null};var c4=(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},l8=(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},d4=(Z,Q)=>{let J=[],Y=0;for(let X of Q){let G=c4(X);if(X.optional){let j=l8(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=l8(Z,Y,G);if(j>0){J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;break}Y++}}return J},l4=(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},i4=(Z)=>Z.map(({speechTokens:Q,math:J})=>({speechTokenIds:Q.map((Y)=>Y.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),i8=(Z)=>{let Q=Z.minExactWordConfidence??0.95,J=d4(Z.speech.tokens,Z.math.tokens),Y=l4(J,Z.speech.tokens,Z.math.tokens)?1:0;return{segments:Y>=Q?i4(J):[],confidence:Y,fallbackTarget:Z.math.expressionTarget}};var rZ=(Z)=>{let Q=SZ({speechText:Z.speechText}),J=c8(Z.mathElement);return{speech:Q,math:J,result:i8({speech:Q,math:J})}};var s8=(Z,Q)=>{let J=m8({tokenization:Z.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return d8({alignment:Z.result,boundary:J})},n8=(Z,Q)=>{let J=sZ(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 s4=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"]),n4=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"]),r8=(Z)=>Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),r4=(Z)=>r8(Z).replace(/"/g,"""),a4=(Z,Q)=>{let J=Z.toLowerCase(),Y=Q.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!n4.has(J))return!0;if(Y.includes("javascript:"))return!0;if(Y.includes("data:text/html"))return!0;return!1},o4=(Z)=>{let Q=Z.localName.toLowerCase();if(!s4.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"},a8=(Z)=>{if(Z.nodeType===Node.TEXT_NODE)return r8(Z.textContent||"");if(Z.nodeType===Node.COMMENT_NODE)return"";if(Z.nodeType!==Node.ELEMENT_NODE)return null;let Q=Z;if(!o4(Q))return null;let J=Q.localName.toLowerCase(),Y=[];for(let j of Array.from(Q.attributes)){let B=j.name.toLowerCase();if(a4(B,j.value))continue;if(B==="xmlns"&&j.value!=="http://www.w3.org/1998/Math/MathML")return null;Y.push(`${B}="${r4(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=a8(j);if(B===null)return null;X.push(B)}let G=Y.length>0?` ${Y.join(" ")}`:"";return`<${J}${G}>${X.join("")}</${J}>`},t4=(Z)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Z,"application/xml");return null},aZ=(Z)=>{let Q=String(Z||"").trim();if(!Q)return null;let J=t4(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 a8(Y)};var t8=(Z)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Z}),o5=(Z)=>Z.classList?.contains("MathJax")||Z.tagName?.toLowerCase()==="mjx-container",e8=(Z)=>Z.tagName?.toLowerCase()==="mjx-assistive-mml",t5=(Z)=>{let Q=Z.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},e4=(Z)=>{let Q=Z.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},Z3=(Z)=>{return CZ(Z,"mjx-assistive-mml math")?.outerHTML||null},Q3=(Z)=>{if(Z.tagName.toLowerCase()==="math")return aZ(Z.outerHTML);let Q=e4(Z);if(Q){let J=aZ(Q);if(J)return J}if(o5(Z)){let J=Z3(Z);if(J){let Y=aZ(J);if(Y)return Y}}return null},J3=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),Y3=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),X3=(Z,Q)=>{let J=p(Z);while(J&&J!==Q){let Y=(J.getAttribute("role")||"").toLowerCase(),X=J.tagName.toUpperCase();if(J3.has(X)||Y3.has(Y))return J;J=p(J)}return Q},G3=(Z)=>Boolean(typeof Z.querySelector==="function"&&CZ(Z,"math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Z.tagName?.toLowerCase()==="math"||Z.hasAttribute?.("data-mathml")||o5(Z),kZ=(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++},Z9=(Z,Q)=>{if(Z.inLeadingWhitespace||Z.lastCharWasWhitespace||Z.chars.length===0)return!1;let J=Z.chars[Z.chars.length-1];return c5(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,kZ(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1;continue}if(V){if(!Z.lastCharWasWhitespace)kZ(Z," ",{node:Q,offset:j});Z.lastCharWasWhitespace=!0;continue}if(!G&&Z9(Z,B))kZ(Z," ",{node:Q,offset:j});kZ(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1}},j3=(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)kZ(Z," ",j);Z.lastCharWasWhitespace=!0;continue}if(J===0&&Z9(Z,Y))kZ(Z," ",j);kZ(Z,Y,j),Z.lastCharWasWhitespace=!1}},B3=(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(t5(G))return;for(let j of Array.from(G.childNodes))Y(j)};return Y(Q.documentElement),y(J.join(" "))},W3=(Z,Q)=>{let J=new Map,Y=o5(Z)?CZ(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||t5(B))return;for(let V of KZ(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},V3=(Z,Q,J)=>{let Y=t8(J),X=(B)=>{if(UZ(B,Z))return;if(B.nodeType===3){Q9(Y,B);return}if(B.nodeType!==1)return;let V=B;if(e8(V)||t5(V))return;for(let K of KZ(V))X(K)};X(Z),J9(Y);let G=y(Y.chars.join(""));if(G)return{text:G,map:Y.map};let j=B3(Q);if(!j)return bZ(Z,J);return{text:j,map:W3(Z,j)}},J9=(Z)=>{while(Z.chars.length>0&&/\s/.test(Z.chars[Z.chars.length-1]))Z.chars.pop(),Z.position--,Z.map.delete(Z.position)},o8=(Z,Q,J)=>{let Y=t8(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(UZ($,Z))return;if(J&&!YZ(J,$))return;if($.nodeType===3){let L=X3($,Z);if(j&&L!==j)V();j=L;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(e8(z))return;let D=Q3(z);if(D&&(!J||F0(J,z,Z))){V();let L=V3(z,D,Q);j3(Y,L);let P=y(L.text);X.push({type:"math",mathml:D,fallbackText:P,sourceElement:z}),G=Y.chars.length,B=!0;return}for(let L of KZ(z))K(L)};for(let $ of KZ(Z))K($);return J9(Y),V(),{visibleText:Y.chars.join(""),map:Y.map,chunks:X,containsMathMarkup:B}},$Z=(Z,Q,J)=>{if(J)return o8(Z,Q,J);if(!G3(Z)){let{text:Y,map:X}=bZ(Z,Q);return{visibleText:Y,map:X,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return o8(Z,Q)};import{createPieLogger as K3,isTtsDebugEnabled as U3}from"@pie-players/pie-players-shared/pie";var u0=K3("tts-math-speech",U3),Y9=Promise.resolve(),$3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",F3=(Z)=>{let Q=null,J=!1;return(Y)=>{if(!Q){B9(Y);let X=Z();Q=X,X.catch((G)=>{if(Q===X)Q=null;if(J){u0.debug("speech-rule-engine failed to load again",G);return}J=!0,u0.warn("speech-rule-engine failed to load; math reads as its visible text until a later read loads it.",G)})}return Q}},z3=F3(()=>import("./chunks/sre-engine-bj997w4b.js").then(({default:Z})=>{if(!Z||typeof Z.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Z})),e5=(Z)=>{let Q=null;return()=>{return Q??=z3(BZ(Z)?.engineOptions),Q}},D3=(Z)=>Z==="en"?"clearspeak":"mathspeak",X9=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),G9=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,BZ=(Z)=>{if(!X9(Z))return;let Q=G9(Z.domain),J=G9(Z.style),Y=X9(Z.engineOptions)?Z.engineOptions:void 0;if(!Q&&!J&&!Y)return;return{...Q?{domain:Q}:{},...J?{style:J}:{},...Y?{engineOptions:Y}:{}}},H3=async(Z,Q,J,Y)=>{let X=$3(Q),G=BZ(Y),j=G?.engineOptions||{};await Z.setupEngine?.({...j9(j),...j,locale:X,domain:G?.domain||D3(X),style:G?.style||"default",modality:"speech",markup:J}),await Z.engineReady?.()},A3=async(Z)=>{let Q=Y9.then(Z,Z);return Y9=Q.then(()=>{return},()=>{return}),Q},W9=async(Z,Q,J,Y,X)=>A3(async()=>{return await H3(Z,J,Y,X),Z.toSpeech(Q)}),_3=(Z)=>Z.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),O3=async(Z,Q,J,Y)=>{try{let X=_3(await W9(Z,Q,J,"ssml",Y));return X.includes("<speak")?X:null}catch(X){return u0.debug("math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},oZ=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||e5(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 W9(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,u0.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 O3(J,Z[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:Y,usedFallback:X,ssml:V}};var L3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",M3="sre-v1",P3=256,Z7=(Z)=>{if(Array.isArray(Z))return`array:[${Z.map(Z7).join(",")}]`;if(Z&&typeof Z==="object")return`object:{${Object.entries(Z).sort(([Q],[J])=>Q.localeCompare(J)).map(([Q,J])=>`${JSON.stringify(Q)}:${Z7(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)}`},V9=(Z,Q,J,Y)=>`${M3}\x00${L3(Z)}\x00${Q?"ssml":"plain"}\x00${Z7(J??null)}\x00${Y}`,Q7=(Z={})=>{let Q=Math.max(1,Z.maxEntries??P3),J=Z.resolve??((G,j)=>oZ([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=BZ(j.mathSpeech),V=j.produceSsml===!0,K=V9(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(V9(j.language,!1,B,G.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(K,$),$}};var q9=(Z,Q)=>{let J=sZ(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=n5({tokenization:Z.catalogAlignment?.speech??SZ({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 fZ=(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 U9=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),J7="mi,mn,mo,mtext",$9="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",F9=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),z9=(Z)=>{if(Z.type==="text-range")return Z.node.parentElement;return Z.element},p0=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},K9=(Z)=>{if(!Z)return!1;if(p0(Z))return!1;return!iZ(Z)},D9=(Z)=>{let Q=Z.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},Y7=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},H9=(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=U9.get(Z[J].localName.toLowerCase());if(!Y)return!1;if(Q[J].localName.toLowerCase()!==Y)return!1}return!0},N3=(Z,Q)=>{if(!Z)return null;if(!U9.has(Z.localName.toLowerCase()))return null;if(Q.querySelector(F9))return null;let J=Y7(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($9));if(!H9(X,j))return null;let B=j[G];if(!B||!D9(B))return null;return B},A9=(Z)=>{let Q=p0(Z);if(Q){if(Q.querySelector(F9))return"expression";let X=Y7(Z)??Z,G=Q.querySelector("mjx-math");if(!G)return"expression";let j=Array.from(X.querySelectorAll(J7)),B=Array.from(G.querySelectorAll($9));if(!H9(j,B))return"expression";return B.some((V)=>D9(V))?"token":"expression"}let J=Y7(Z)??Z;return Array.from(J.querySelectorAll(J7)).some((X)=>!iZ(X))?"token":"expression"},X7=(Z)=>{let Q=z9(Z),J=p0(Q);if(J){let Y=N3(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(!K9(Z.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Z.node,startOffset:Z.startOffset,endOffset:Z.endOffset}}if(!K9(Z.element))return null;return{type:"element",quality:Z.quality==="region-fallback"?"expression":"semantic-token",element:Z.element}},_9=X7,O9=()=>{let Z=new WeakMap;return(Q)=>{let J=z9(Q),Y=p0(J);if(!J||!Y)return X7(Q);if(Z.has(J))return Z.get(J)??null;let X=X7(Q);return Z.set(J,X),X}};var L9=(Z,Q,J,Y=Z.mathAlignments,X=_9)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let G=null;for(let j of Y){let B=s8(j.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:J.word})||n8(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 FZ=(Z)=>Z.node.getRootNode?.()??Z.node,M9=(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}},G7=(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(FZ(X)!==FZ(Y)){let G=FZ(Y);X=Y;for(let j=Q+1;j<J;j++){let B=Z.get(j);if(B&&FZ(B)===G)X=B}}return M9(Y,X)},zZ=(Z,Q,J)=>{if(!Z||typeof document>"u"||J<=Q)return[];let Y=Z.get(Q);if(!Y)return[];let X=FZ(Y),G=!1;for(let U=Q+1;U<J&&!G;U++){let $=Z.get(U);if($&&FZ($)!==X)G=!0}if(!G){let U=G7(Z,Q,J);return U?[U]:[]}let j=[],B=null,V=null,K=()=>{if(B&&V){let U=M9(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&&FZ(B)!==FZ($))K();if(!B)B=$;V=$}return K(),j};var P9=(Z,Q)=>{if(!Z.catalogAlignment||Q.chunkSpokenStart===null)return null;let J=u8(Z.catalogAlignment,Q.chunkSpokenStart);if(!J)return null;let Y=zZ(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 w3=(Z)=>{let Q=zZ(Z.visibleMap,0,Z.visibleText.length);return Q.length>1?Q:void 0},R3=(Z)=>Z.regionRange?{type:"range",quality:"region",range:Z.regionRange,ranges:w3(Z)}:Z.regionElement?{type:"element",quality:"region",element:Z.regionElement}:null,N9=(Z,Q=Z.chunk.mathAlignments)=>{if(Q.length!==1)return null;let J=Q[0]?.alignment.result.fallbackTarget;return J?Z.renderedMathTargetResolver(J):null},C3=(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)=>YZ(Y,J));if(Z.type==="element")return ZZ(Z.element,J);return ZZ(g(Z.node),J)}catch{return!1}})},w9=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),j7=(Z)=>Z.length===1?Z[0].element:null,E3=(Z,Q)=>Q.length>0&&Q.every(({element:J})=>Z.mathCapabilityByElement.get(J)==="token"),R9=3,b3=(Z,Q,J)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:Y,endContainer:X}=Q.range;if(Y===X&&Y.nodeType===R9)return!1;return J.some(({element:j})=>Z.mathCapabilityByElement.get(j)==="token"&&j.contains(Y)&&j.contains(X))},C9=(Z)=>Z?.type==="range"&&iZ(Z.range.startContainer),S3=(Z,Q)=>{if(!C9(Q))return null;let{startContainer:J,endContainer:Y,startOffset:X,endOffset:G}=Q.range;if(J!==Y||J.nodeType!==R9)return null;return Z.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:G})},T3=(Z,Q)=>({chunk:Z,regionTarget:R3(Z),renderedMathTargetResolver:O9(),mathCapabilityByElement:new Map(Z.mathAlignments.map(({element:J})=>[J,Q?A9(J):"expression"])),heldTokenByElement:new Map}),E9=(Z)=>{let Q=Z.mathTokenHighlighting!==!1,J=new Map(Z.chunks.map((Y)=>[Y.id,T3(Y,Q)]));return{chunks:Z.chunks,resolveInitial(Y){let X=J.get(Y);if(!X)return w9();let G=j7(X.chunk.mathAlignments),j=G?X.mathCapabilityByElement.get(G):null;if(j==="expression")return fZ({semanticTarget:null,expressionTarget:N9(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return fZ({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 w9();let{chunk:G}=X,j=q9(G,Y),B=P9(G,j),V=C3(B,G),K=!B||V.length>0?L9(G,j,Y,V,X.renderedMathTargetResolver):null,U=K?.quality==="semantic-token"?K:S3(X,B)??K,$=Q&&U&&U.quality!=="expression"?U:null,z=U&&U.quality==="expression"?U:null;if($){let D=j7(V);if(D)X.heldTokenByElement.set(D,$);return fZ({semanticTarget:$,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}if(B&&!C9(B)&&(Q?!b3(X,B,V):V.length===0))return fZ({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason});if(E3(X,V)){let D=j7(V),L=D?X.heldTokenByElement.get(D)??null:null;return fZ({semanticTarget:L,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:L?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return fZ({semanticTarget:null,expressionTarget:z??N9(X,V),regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}}};var y3=(Z)=>{return Z.alignment?.speech.boundaryOffsetSpace??Z.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},x3=(Z)=>{if(Z.mathAlignments?.length)return Z.mathAlignments;if(Z.mathAlignment&&Z.sourceElement)return[{element:Z.sourceElement,alignment:Z.mathAlignment}];return[]},b9=(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:x3(J),offsetSpace:y3(J)}))};var k3=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),g0=(Z,Q)=>{let J=T0(Z,k3);if(J&&ZZ(Q,J))return J;return Z};var IZ=(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}]},B7=(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*$/),L=D>0?$+D:$+Y;X.push({text:Z.slice($,L).trimEnd(),offset:$}),$=L;while($<U&&/\s/.test(Z[$]))$++}if($<U)G=$,j=U};for(let K of IZ(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 f3=(Z,Q)=>oZ([Z],Q),I3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",v3=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),h3=new Set(["heading","listitem","option","radio"]),m3=(Z)=>{if(Z.type!=="text"||!Z.sourceElement)return!1;let Q=Z.sourceElement.tagName.toUpperCase(),J=(Z.sourceElement.getAttribute("role")||"").toLowerCase();return v3.has(Q)||h3.has(J)},S9=async(Z)=>{let Q=Z.resolveMathSpeech??f3,J=e5(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 L=m3(K)?[{text:K.text,offset:0}]:IZ(K.text,{locale:Z.language});for(let P of L){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:I3(Z.language),visibleText:Y,plainSpeechText:y(B.join(" "))}};var u3=(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},W7=async(Z)=>{let Q=$Z(Z.contentRoot,Z.textProcessingOptions,Z.range),J=await S9({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:g0(V,Z.contentRoot),visibleMap:u3(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 p3=(Z,Q)=>{let J=m0({speechText:Z.spokenText,visibleText:Z.spokenText});return{speechText:Z.spokenText,visibleText:Z.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:G7(Q.visibleMap,0,Z.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Q.visibleMap}},T9=(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?rZ({mathElement:J,speechText:Z.spokenText}):void 0}},g3=(Z,Q,J)=>{let Y=Q.sourceElement;return{speechText:J,visibleText:Z.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:Y?rZ({mathElement:Y,speechText:J}):void 0,plainFallback:T9(Z,Q)}},V7=(Z,Q={})=>Z.items.map(({segment:J,anchor:Y})=>{if(J.kind==="prose")return p3(J,Y);if(Q.format==="ssml"&&J.ssml)return g3(J,Y,J.ssml);return T9(J,Y)});function c0(Z){let Q=Z instanceof Error?Z:Error(String(Z));return Q.code="tts-start-failed",Q}var t=l3("tts-service",h9),R;(function(Z){Z.IDLE="idle",Z.LOADING="loading",Z.PLAYING="playing",Z.PAUSED="paused",Z.ERROR="error"})(R||(R={}));var i3={baseMs:280,units:{minor:0.65,section:1,major:1.35},minMs:120,maxMs:900},y9=0.25,x9=4,vZ=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,k9=(Z,Q={})=>{if(!Z)return Q;return{locale:"locale"in Z?vZ(Z.locale):Q.locale,textNormalization:Z.textNormalization&&"locale"in Z.textNormalization?vZ(Z.textNormalization.locale):Q.textNormalization,segmenter:Z.segmenter&&"locale"in Z.segmenter?vZ(Z.segmenter.locale):Q.segmenter}},f9=(Z)=>("commonAncestorContainer"in Z),m9=(Z,Q)=>Z===Q||Z.startContainer===Q.startContainer&&Z.startOffset===Q.startOffset&&Z.endContainer===Q.endContainer&&Z.endOffset===Q.endOffset,s3=(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 m9(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},n3=(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},I9=(Z)=>{let Q=Number(Z.getAttribute("data-tts-break-ms"));return Number.isFinite(Q)&&Q>0?Q:null},r3=(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"},v9=(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 q7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.IDLE;resumeState=R.PLAYING;ttsConfig={};hostLocales={};readLocale=x0;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=Q7();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 c0(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=k9(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=k9(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 c0(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:g(Z)}isElementWithinScope(Z,Q){if(!Q)return!0;return ZZ(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:!m9(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(v0(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 B7(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=B7(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=u5(Z,{contentLanguage:Q})??vZ(this.providerOptions().lang_id);return{contentLanguage:J,locale:J??this.hostLocales.locale??this.hostLocales.textNormalization??x0}}getMathSpeechOptions(){if(this.mathSpeechSource)return BZ(this.mathSpeechSource());return BZ(this.providerOptions().mathSpeech)}buildPositionMap(Z,Q,J){this.normalizedToDOM.clear();let{text:Y,map:X}=bZ(Z,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!h9())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:n3(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=i3;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(y9,Math.min(x9,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(I9(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=p(Z),Y=null;while(J&&J!==Q){if(k0(J))return null;let G=I9(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&&r3(J))Y=J;J=p(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}=bZ(Z,this.getTextProcessingOptions(Q)),X=this.createNodeStartOffsets(Y),G=null;for(let j of RZ(Z)){let B=p(j);if(B&&!k0(B)&&!f0(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}=v9(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 IZ(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}=v9(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=zZ(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 c0(Error("TTS service not initialized"))}let G=this.resolveReadLanguage(f9(Z)?Z.startContainer:Z,Q.language),j=f9(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(!f0(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=$Z(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:g(Y));if(!X)return null;let G=p5(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 $=p5(U,X).text,z=y($);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&&F0(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 L=Q.wordBoundaryOffset||0;this.activeWordBoundaryOffset=L;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,L,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:L});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&&vZ(J.locale)===Y.locale&&vZ(J.textNormalization?.locale)===Y.textNormalization&&vZ(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=$Z(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||J,V=y(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=y(Y.map((j)=>j.speechText).join(" ")),G=J.contentRange?Q:$Z(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&&!F0(j,$,Z))return null;let D={type:"spoken",language:m5($,Z)||Q.language,useFallback:!0,context:Q.catalogContext},L=J.getAlternative(z,{...D,form:"payload"}),P=L?.payload?E8({payload:L.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 L=D[0],P=$Z(L,this.getTextProcessingOptions(Q.language)).visibleText||y(L.textContent||""),H=(N)=>y(N).replace(/\s+/g,"");return H(P)===H(z)?L:null},K=($)=>{let z=O8($,"math");if($.localName?.toLowerCase()==="math")return[$,...z];return z},U=($)=>{if(UZ($,Z))return;if($.nodeType===Node.TEXT_NODE){if(!j)X+=` ${$.textContent||""}`;else if(YZ(j,$))X+=` ${g5($,j)}`;return}if($.nodeType!==Node.ELEMENT_NODE)return;let z=$,D=B(z);if(D){G();let L=$Z(z,this.getTextProcessingOptions(Q.language)),P=L.visibleText||y(_8(z)),H=g0(z,Z),N=null;if(D.script!==void 0){let O=D.script,S=m0({speechText:O,visibleText:P}),C=V(z,P),h=C?rZ({mathElement:C,speechText:O}):void 0,E=h?void 0:K(z).map((d)=>({element:d,alignment:rZ({mathElement:d,speechText:O})}));N={speechText:O,visibleText:P,sourceElement:z,regionElement:H,speechMatchesVisibleText:y(O)===P,playbackMode:S.playbackMode,alignment:S,mathAlignment:h,mathAlignments:E,visibleMap:L.map}}if(D.audio){Y.push(N?{...N,audio:D.audio,plainFallback:N}:{speechText:P,visibleText:P,sourceElement:z,regionElement:H,speechMatchesVisibleText:!1,visibleMap:L.map,audio:D.audio});return}if(N)Y.push(N);return}for(let L of KZ(z))U(L)};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 W7({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=V7(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=zZ(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=zZ(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&&s3(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=c3(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((L)=>{if(L?.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=d3(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?b9({contentRoot:J,chunks:[Z]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,G=Y?E9({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}=bZ(Q,this.getTextProcessingOptions(J)),G=-1,j=-1;for(let[U,{node:$,offset:z}]of X){if(U>=Y.length)continue;if(!q0(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(y9,Math.min(x9,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 a3,isTtsDebugEnabled as o3}from"@pie-players/pie-players-shared/pie";var u9=a3("browser-tts-provider",o3),p9=5000,d9=2000,g9=260,t3=80,e3=["__pieTelemetry","contentLanguage","highlightMode","locale","mathSpeech","segmenter","structuralPauses","textNormalization"],l9=(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 e3)if(J[X]!==void 0)Y[X]=J[X];if(Object.keys(Y).length>0)Q.providerOptions=Y}return Q},c9=(Z)=>{if(!v0(Z))return{text:Z,sourceOffset:(X)=>X};let{spokenText:Q,rawToSpokenOffsetMap:J}=h0(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}}},K7=(Z)=>String(Z||"").trim().toLowerCase(),Z2=()=>{let Z=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return K7(Z||"en-US")},Q2=(Z,Q)=>{let J=K7(Q)||Z2(),Y=J.split("-")[0]||"en",X=K7(Z.lang);return X===J||X.startsWith(`${Y}-`)},J2=(Z,Q,J)=>{if(Q)return Z.find((G)=>G.voiceURI===Q)||Z.find((G)=>G.name===Q)||null;let Y=(G)=>Q2(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},Y2=(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()})},X2=(Z)=>!Z.default;class U7{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 Y2(window.speechSynthesis,d9);return new i9(Z)}getCapabilities(){return{supportsWordBoundary:!0,defaultHighlightMode:"sentence",supportsSSML:!1}}destroy(){}}class i9{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 ${d9/1000} seconds.`);let J=J2(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=c9(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=c9(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<=g9)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<=g9)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 IZ(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&&X2(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},L=()=>{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,S)=>{if(U)return;if(U=!0,L(),P(),D(),z&&this.settlePendingChunk===z)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1;if(S)j(S);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 ${p9/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,L(),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(u9.debug(`boundary event: ${O.name}, charIndex ${O.charIndex}, charLength ${O.charLength}`),O.name!=="word"||!this.onWordBoundary)return;let S=Math.max(0,Math.min(O.charIndex,Math.max(0,Z.length-1))),C=Number(O.charLength||0),h=this.inferWordLength(Z,S),E=Number.isFinite(C)&&C>0&&C<=t3&&S+C<=Z.length?C:h,d=Z.substring(S,Math.min(Z.length,S+E)).trim(),VZ=Q+S,r=X(VZ),s=X(VZ+E-1)+1-r;u9.debug(`word boundary "${d}" at ${r}`),this.onWordBoundary(d,r,s)},$=setTimeout(()=>{if(U||K||J!==this.speakRunId)return;H(!1,N("timedOut")),speechSynthesis.cancel()},p9);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 G2=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),s9=(Z)=>Z&&typeof Z==="object"?Z:{},WZ=(Z,Q)=>Z===void 0?Q:Z,n9=(Z)=>d0(Z)==="server"&&Z.serverProvider==="custom"?"custom":"pie",j2=(Z)=>typeof Z==="string"&&G2.has(Z)?Z:"left-aligned",BY=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 B2=(Z)=>{let Q={...Z,layoutMode:j2(Z.layoutMode)};if(Z.backend!=="server")return Q;let J={...Q,apiEndpoint:WZ(Q.apiEndpoint,"/api/tts"),transportMode:WZ(Q.transportMode,n9(Z)),endpointValidationMode:WZ(Q.endpointValidationMode,"voices"),includeAuthOnAssetFetch:WZ(Q.includeAuthOnAssetFetch,!1),rate:WZ(Q.rate,1),language:WZ(Q.language,"en-US")};if(Z.serverProvider==="polly")return{...J,engine:WZ(J.engine,"neural"),format:WZ(J.format,"mp3"),speechMarksMode:WZ(J.speechMarksMode,"word+sentence")};return J},$7=(Z)=>{let{enabled:Q,provider:J,...Y}=s9(Z);return B2(Y)},d0=(Z)=>Z.backend||"browser",F7=(Z)=>{let Q=d0(Z)==="server"?Z.serverProvider:void 0,J=Q==="polly",Y=Z.transportMode||n9(Z),X=BZ(Z.mathSpeech);return{voice:Z.defaultVoice,rate:Z.rate,pitch:Z.pitch,providerOptions:{...s9(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 W2,isGlobalDebugEnabled as V2}from"@pie-players/pie-players-shared/pie";var tZ=W2("ToolProviderRegistry",V2);function eZ(Z){let Q=Z&&typeof Z==="object"?Z.backend:void 0;return typeof Q==="string"&&Q?Q:"unknown"}class l0{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(tZ.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:eZ(Y),operation:"provider-initialize"}),Q.requiresAuth&&J.authFetcher){let G=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Z,backend:eZ(Y),operation:"auth-fetch"}),tZ.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:eZ(Y),operation:"auth-fetch",duration:Date.now()-G})}catch(j){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Z,backend:eZ(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:eZ(Y),operation:"provider-initialize",duration:Date.now()-X}),tZ.debug(`Provider "${Z}" initialized`)}catch(G){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Z,backend:eZ(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))tZ.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),tZ.debug(`Unregistered provider "${Z}"`)}}async destroy(){let Z=Array.from(this.providers.keys());await Promise.all(Z.map((Q)=>this.unregister(Q))),tZ.debug("Registry destroyed")}}class z7{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 q2(Z){return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:void 0}function i0(Z,Q,J){let Y=Q?.settings,X=[Q?.personalNeedsProfile?.toolParameters?.[Z],Y?.toolParameters?.[Z],J?.settings.toolParameters?.[Z]].map(q2).filter((G)=>G!==void 0);return X.length>0?Object.assign({},...X):void 0}class D7{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=K2(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 K2(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
|
+
`,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",F6=()=>{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=F6();if(!j)return;try{J.adoptedStyleSheets=[...X,j],J[x8]=j}catch{}},m5="tts-word",u5="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 h5,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)),N=Math.max(0.22,Math.min(0.6,$*0.45)),A=B,P=this.blend(A,j,M),O=this.contrastRatio(P,j),C=this.relativeLuminance(j)>0.45?[0,0,0]:[255,255,255],E=O>=1.35?A: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]}, ${N})`;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(m5),E0(u5);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(m5);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(u5);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(m5,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(u5,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:p5.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 t3,enforceMediaFragment as e3}from"@pie-players/pie-players-shared/media";import{createPieLogger as Z2,isTtsDebugEnabled as s9}from"@pie-players/pie-players-shared/pie";import{isUnsupportedMediaAssetVersion as z6,normalizeMediaFragment as D6,normalizeMediaSources as H6,trimmedOrUndefined as A6}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(z6(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=H6(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:D6(Q.fragment),label:A6(J.label)}}var _6="[data-pie-shell-root]";var h8=(Z)=>Z?fZ(Z,_6):null;var vZ="en-US",g5=(Z,Q)=>{let J=!Z?null:Z.nodeType===1?Z:d(Z);while(J){let Y=J.getAttribute("lang")?.trim();if(Y)return Y;if(Q&&J===Q)return;J=d(J)}return},c5=(Z,Q={})=>{let J=Q.boundary!==void 0?Q.boundary:h8(Z);return(J?g5(Z,J):void 0)||Q.contentLanguage?.trim()||void 0},m8=(Z,Q={})=>c5(Z,Q)??vZ;var y=(Z)=>Z.trim().replace(/\s+/g," "),c8=()=>/[\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},u8="data-tts-suppress",d8=new Set(["computer-read-aloud","all"]),p8=new Set([...d8,"screen-reader"]),g8=new Set,O6=(Z)=>{let Q=Z.getAttribute?.(u8);if(Q===null||Q===void 0)return!1;let J=Q.trim().toLowerCase();if(d8.has(J))return!0;if(p8.has(J))return!1;if(!g8.has(J))g8.add(J),console.warn(`[tts] ${u8}="${Q}" is not one of ${Array.from(p8).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(O6(J))return!0;if(Q&&J===Q)break;J=g(J)}return!1},$0=(Z,Q)=>n0(Z,Q)||mZ(Z),d5=(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)},i5=(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&&i5(V,M,Q)){if(Y.push(" "),B)J.set(X,B);X++,j=!0}for(let N=0;N<z.length;N++){let A=z[N],P=/\s/.test(A);if(G){if(!P)G=!1,Y.push(A),J.set(X,{node:U,offset:N}),B={node:U,offset:N},X++,j=!1,V=A}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(A),J.set(X,{node:U,offset:N}),B={node:U,offset:N},X++,j=!1,V=A}}let K=Y.join("").trimEnd();while(J.has(K.length))J.delete(K.length);return{text:K,map:J}};var M6=/^\s*<speak[\s/>]/i,pZ=(Z)=>M6.test(Z),L6=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),l8=new Set(["audio","phoneme"]),s8=(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})},N6=(Z,Q,J)=>{let Y=Q.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!Y)return 0;return uZ(Z,s8(Y[0]),J),Y[0].length},i8=(Z)=>{Z.push({char:" ",rawOffset:null})},P6=(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}},w6=(Z)=>{return Z.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},R6=(Z,Q)=>{let J=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),Y=Z.match(J);return s8(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=N6(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=w6(V),U=/^<\s*\//.test(V),$=/\/\s*>$/.test(V);if(!U&&K==="sub"){let z=R6(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"){i8(Q),X=B+1;continue}if(!U&&l8.has(K)){if(J=!0,$){X=B+1;continue}}if(K&&!L6.has(K)&&!l8.has(K)&&K!=="break"&&K!=="sub")J=!0;if(!U&&(K==="p"||K==="s"))i8(Q);X=B+1}let G=P6(Q);return{spokenText:y(G.text),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:Y}};var C6=c8(),b6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),E6=(Z)=>{let Q=Z.toLowerCase();return b6.get(Q)||Q},r5=(Z)=>{let Q=[];for(let J of Z.matchAll(C6)){let Y=J[0],X=J.index??0;Q.push({text:Y,normalized:E6(Y),start:X,end:X+Y.length})}return Q},S6=(Z)=>r5(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:S6(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},a5=(Z)=>Boolean(Z&&/^<[^>]+>$/.test(Z.trim())),r0=(Z)=>{if(!Z||a5(Z))return null;return T0({speechText:Z}).tokens[0]?.normalized??null},T6=(Z,Q)=>Z.find((J)=>J.start<=Q&&Q<J.end)||null,y6=(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},s5=(Z,Q,J)=>{if(Q===null)return null;let Y=T6(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}},n5=(Z,Q)=>Boolean(Z&&Q&&Z.token.normalized===Q),o5=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||a5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=r0(Z.boundaryWord),Y=s5(Z.tokenization,y6(Z.tokenization,Z.position),Q),X=s5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(n5(Y,J))return{...Y,confidence:1};if(n5(X,J))return{...X,confidence:1};if(J)return null;return Z.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||X:X||Y},n8=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||a5(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=r0(Z.boundaryWord),Y=s5(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(n5(Y,J))return{...Y,confidence:1};if(J)return null;return Y};var t5=10,x6=0.12,k6=[{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}],f6=(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:t5});for(let X of k6){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=f6(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),N=Y[U]+K.score-M;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}})},v6=(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/t5;return Math.min(1,Y*X)},cZ=(Z)=>{let Q=T0({speechText:Z.speechText}),J=y(Z.visibleText),Y=Q.tokens,X=r5(J),G=Q.unsupportedSemantic?[]:I6(Y,X),j=v6(G,Y,X),B=Q.spokenText===J&&Q.spokenText.length>0,V=G.length===1&&G[0].score===t5&&Y.length<=2&&X.length<=2,K=(G.length>=2||V)&&j>=x6,U=Q.unsupportedSemantic?"region-fallback":B?"exact-word":K?"anchor-span":"region-fallback";return{speech:Q,visibleText:J,playbackMode:U,anchors:G,confidence:j}},r8=(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 h6=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"]]]),m6=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),a8=new Map([["2",["squared"]],["3",["cubed"]]]),u6=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),p6=(Z)=>Z.replace(/\s+/g," ").trim(),y0=(Z)=>(Z.localName||Z.tagName||"").toLowerCase(),g6=(Z)=>Z.nodeType===Node.ELEMENT_NODE,a0=(Z)=>Array.from(Z.childNodes).filter(g6),e5=(Z)=>p6(Z.textContent||""),j0=(Z,Q)=>({type:"element-range",quality:Q,element:Z}),c6=(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"}},d6=(Z,Q)=>{if(Q==="operator"){if(Z==="−")return"-";return Z}return Z.toLowerCase()},l6=(Z,Q,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return a8.get(Z)??[];if(Z==="|")return["absolute value"];if(Q==="operator")return h6.get(Z)||[];return[]},x0=(Z)=>{let Q=Z.normalized??d6(Z.text,Z.kind||"unknown");return{id:`math-token-${Z.state.nextId++}`,kind:Z.kind,role:Z.role,text:Z.text,normalized:Q,spokenAliases:l6(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)},o8=(Z,Q,J)=>{a0(Z).forEach((Y,X)=>B0(Y,Q,`${J}/${y0(Y)}[${X}]`))},i6=(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`)},s6=(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")})),o8(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")}))},n6=(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=e5(X);if(a8.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`)},r6=(Z,Q,J,Y)=>{k0(Q,x0({state:Q,kind:"structure",role:Y,text:e5(Z)||Y,normalized:`\x00${Y}`,sourceElement:Z,path:J,target:j0(Z,"element-range")}))},a6=(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}]`)}},o6=(Z,Q,J)=>{let Y=e5(Z);if(!Y)return;let X=c6(y0(Z)),G=X==="operator"?m6.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":o6(Z,Q,J);return;case"mfrac":i6(Z,Q,J);return;case"msup":n6(Z,Q,J);return;case"mfenced":s6(Z,Q,J);return;case"mtable":a6(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=u6.get(Y);if(X){r6(Z,Q,J,X);return}o8(Z,Q,J)}}},t8=(Z)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return B0(Z,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:j0(Z,"region-fallback")}};var e8=(Z)=>{if(!Z.boundary)return null;return Z.alignment.segments.find((J)=>J.speechTokenIds.includes(Z.boundary.token.id))?.target||null};var t6=(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},Z9=(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},e6=(Z,Q)=>{let J=[],Y=0;for(let X of Q){let G=t6(X);if(X.optional){let j=Z9(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=Z9(Z,Y,G);if(j>0){J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;break}Y++}}return J},Z3=(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},Q3=(Z)=>Z.map(({speechTokens:Q,math:J})=>({speechTokenIds:Q.map((Y)=>Y.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),Q9=(Z)=>{let Q=Z.minExactWordConfidence??0.95,J=e6(Z.speech.tokens,Z.math.tokens),Y=Z3(J,Z.speech.tokens,Z.math.tokens)?1:0;return{segments:Y>=Q?Q3(J):[],confidence:Y,fallbackTarget:Z.math.expressionTarget}};var o0=(Z)=>{let Q=T0({speechText:Z.speechText}),J=t8(Z.mathElement);return{speech:Q,math:J,result:Q9({speech:Q,math:J})}};var J9=(Z,Q)=>{let J=n8({tokenization:Z.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return e8({alignment:Z.result,boundary:J})},Y9=(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 J3=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"]),Y3=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"]),X9=(Z)=>Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),X3=(Z)=>X9(Z).replace(/"/g,"""),G3=(Z,Q)=>{let J=Z.toLowerCase(),Y=Q.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!Y3.has(J))return!0;if(Y.includes("javascript:"))return!0;if(Y.includes("data:text/html"))return!0;return!1},j3=(Z)=>{let Q=Z.localName.toLowerCase();if(!J3.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"},G9=(Z)=>{if(Z.nodeType===Node.TEXT_NODE)return X9(Z.textContent||"");if(Z.nodeType===Node.COMMENT_NODE)return"";if(Z.nodeType!==Node.ELEMENT_NODE)return null;let Q=Z;if(!j3(Q))return null;let J=Q.localName.toLowerCase(),Y=[];for(let j of Array.from(Q.attributes)){let B=j.name.toLowerCase();if(G3(B,j.value))continue;if(B==="xmlns"&&j.value!=="http://www.w3.org/1998/Math/MathML")return null;Y.push(`${B}="${X3(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=G9(j);if(B===null)return null;X.push(B)}let G=Y.length>0?` ${Y.join(" ")}`:"";return`<${J}${G}>${X.join("")}</${J}>`},B3=(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=B3(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 G9(Y)};var B9=(Z)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Z}),Z7=(Z)=>Z.classList?.contains("MathJax")||Z.tagName?.toLowerCase()==="mjx-container",W9=(Z)=>Z.tagName?.toLowerCase()==="mjx-assistive-mml",Q7=(Z)=>{let Q=Z.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},W3=(Z)=>{let Q=Z.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},V3=(Z)=>{return b0(Z,"mjx-assistive-mml math")?.outerHTML||null},K3=(Z)=>{if(Z.tagName.toLowerCase()==="math")return t0(Z.outerHTML);let Q=W3(Z);if(Q){let J=t0(Q);if(J)return J}if(Z7(Z)){let J=V3(Z);if(J){let Y=t0(J);if(Y)return Y}}return null},q3=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),U3=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),$3=(Z,Q)=>{let J=g(Z);while(J&&J!==Q){let Y=(J.getAttribute("role")||"").toLowerCase(),X=J.tagName.toUpperCase();if(q3.has(X)||U3.has(Y))return J;J=g(J)}return Q},F3=(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")||Z7(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++},V9=(Z,Q)=>{if(Z.inLeadingWhitespace||Z.lastCharWasWhitespace||Z.chars.length===0)return!1;let J=Z.chars[Z.chars.length-1];return i5(J,Q,Z.options)},K9=(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&&V9(Z,B))f0(Z," ",{node:Q,offset:j});f0(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1}},z3=(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&&V9(Z,Y))f0(Z," ",j);f0(Z,Y,j),Z.lastCharWasWhitespace=!1}},D3=(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(Q7(G))return;for(let j of Array.from(G.childNodes))Y(j)};return Y(Q.documentElement),y(J.join(" "))},H3=(Z,Q)=>{let J=new Map,Y=Z7(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||Q7(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},A3=(Z,Q,J)=>{let Y=B9(J),X=(B)=>{if($0(B,Z))return;if(B.nodeType===3){K9(Y,B);return}if(B.nodeType!==1)return;let V=B;if(W9(V)||Q7(V))return;for(let K of U0(V))X(K)};X(Z),q9(Y);let G=y(Y.chars.join(""));if(G)return{text:G,map:Y.map};let j=D3(Q);if(!j)return S0(Z,J);return{text:j,map:H3(Z,j)}},q9=(Z)=>{while(Z.chars.length>0&&/\s/.test(Z.chars[Z.chars.length-1]))Z.chars.pop(),Z.position--,Z.map.delete(Z.position)},j9=(Z,Q,J)=>{let Y=B9(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=$3($,Z);if(j&&M!==j)V();j=M;let N=$;K9(Y,N,J?.startContainer===N?J.startOffset:void 0,J?.endContainer===N?J.endOffset:void 0);return}if($.nodeType!==1)return;let z=$;if(W9(z))return;let D=K3(z);if(D&&(!J||HZ(J,z,Z))){V();let M=A3(z,D,Q);z3(Y,M);let N=y(M.text);X.push({type:"math",mathml:D,fallbackText:N,sourceElement:z}),G=Y.chars.length,B=!0;return}for(let M of U0(z))K(M)};for(let $ of U0(Z))K($);return q9(Y),V(),{visibleText:Y.chars.join(""),map:Y.map,chunks:X,containsMathMarkup:B}},F0=(Z,Q,J)=>{if(J)return j9(Z,Q,J);if(!F3(Z)){let{text:Y,map:X}=S0(Z,Q);return{visibleText:Y,map:X,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return j9(Z,Q)};import{createPieLogger as O3,isTtsDebugEnabled as M3}from"@pie-players/pie-players-shared/pie";var dZ=O3("tts-math-speech",M3),U9=Promise.resolve(),L3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",N3=(Z)=>{let Q=null,J=!1;return(Y)=>{if(!Q){D9(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}},P3=N3(()=>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})),J7=(Z)=>{let Q=null;return()=>{return Q??=P3(W0(Z)?.engineOptions),Q}},w3=(Z)=>Z==="en"?"clearspeak":"mathspeak",$9=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),F9=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,W0=(Z)=>{if(!$9(Z))return;let Q=F9(Z.domain),J=F9(Z.style),Y=$9(Z.engineOptions)?Z.engineOptions:void 0;if(!Q&&!J&&!Y)return;return{...Q?{domain:Q}:{},...J?{style:J}:{},...Y?{engineOptions:Y}:{}}},R3=async(Z,Q,J,Y)=>{let X=L3(Q),G=W0(Y),j=G?.engineOptions||{};await Z.setupEngine?.({...z9(j),...j,locale:X,domain:G?.domain||w3(X),style:G?.style||"default",modality:"speech",markup:J}),await Z.engineReady?.()},C3=async(Z)=>{let Q=U9.then(Z,Z);return U9=Q.then(()=>{return},()=>{return}),Q},H9=async(Z,Q,J,Y,X)=>C3(async()=>{return await R3(Z,J,Y,X),Z.toSpeech(Q)}),b3=(Z)=>Z.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),E3=async(Z,Q,J,Y)=>{try{let X=b3(await H9(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||J7(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 H9(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 E3(J,Z[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:Y,usedFallback:X,ssml:V}};var S3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",T3="sre-v1",y3=256,Y7=(Z)=>{if(Array.isArray(Z))return`array:[${Z.map(Y7).join(",")}]`;if(Z&&typeof Z==="object")return`object:{${Object.entries(Z).sort(([Q],[J])=>Q.localeCompare(J)).map(([Q,J])=>`${JSON.stringify(Q)}:${Y7(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)}`},A9=(Z,Q,J,Y)=>`${T3}\x00${S3(Z)}\x00${Q?"ssml":"plain"}\x00${Y7(J??null)}\x00${Y}`,X7=(Z={})=>{let Q=Math.max(1,Z.maxEntries??y3),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=A9(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(A9(j.language,!1,B,G.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(K,$),$}};var _9=(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=o5({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 M9=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),G7="mi,mn,mo,mtext",L9="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",N9=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),P9=(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},O9=(Z)=>{if(!Z)return!1;if(lZ(Z))return!1;return!n0(Z)},w9=(Z)=>{let Q=Z.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},j7=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},R9=(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=M9.get(Z[J].localName.toLowerCase());if(!Y)return!1;if(Q[J].localName.toLowerCase()!==Y)return!1}return!0},x3=(Z,Q)=>{if(!Z)return null;if(!M9.has(Z.localName.toLowerCase()))return null;if(Q.querySelector(N9))return null;let J=j7(Z),Y=Q.querySelector("mjx-math");if(!J||!Y)return null;let X=Array.from(J.querySelectorAll(G7)),G=X.indexOf(Z);if(G<0)return null;let j=Array.from(Y.querySelectorAll(L9));if(!R9(X,j))return null;let B=j[G];if(!B||!w9(B))return null;return B},C9=(Z)=>{let Q=lZ(Z);if(Q){if(Q.querySelector(N9))return"expression";let X=j7(Z)??Z,G=Q.querySelector("mjx-math");if(!G)return"expression";let j=Array.from(X.querySelectorAll(G7)),B=Array.from(G.querySelectorAll(L9));if(!R9(j,B))return"expression";return B.some((V)=>w9(V))?"token":"expression"}let J=j7(Z)??Z;return Array.from(J.querySelectorAll(G7)).some((X)=>!n0(X))?"token":"expression"},B7=(Z)=>{let Q=P9(Z),J=lZ(Q);if(J){let Y=x3(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(!O9(Z.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Z.node,startOffset:Z.startOffset,endOffset:Z.endOffset}}if(!O9(Z.element))return null;return{type:"element",quality:Z.quality==="region-fallback"?"expression":"semantic-token",element:Z.element}},b9=B7,E9=()=>{let Z=new WeakMap;return(Q)=>{let J=P9(Q),Y=lZ(J);if(!J||!Y)return B7(Q);if(Z.has(J))return Z.get(J)??null;let X=B7(Q);return Z.set(J,X),X}};var S9=(Z,Q,J,Y=Z.mathAlignments,X=b9)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let G=null;for(let j of Y){let B=J9(j.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:J.word})||Y9(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,T9=(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}},W7=(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 T9(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=W7(Z,Q,J);return U?[U]:[]}let j=[],B=null,V=null,K=()=>{if(B&&V){let U=T9(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 y9=(Z,Q)=>{if(!Z.catalogAlignment||Q.chunkSpokenStart===null)return null;let J=r8(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 k3=(Z)=>{let Q=D0(Z.visibleMap,0,Z.visibleText.length);return Q.length>1?Q:void 0},f3=(Z)=>Z.regionRange?{type:"range",quality:"region",range:Z.regionRange,ranges:k3(Z)}:Z.regionElement?{type:"element",quality:"region",element:Z.regionElement}:null,x9=(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)=>X0(Y,J));if(Z.type==="element")return Q0(Z.element,J);return Q0(d(Z.node),J)}catch{return!1}})},k9=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),V7=(Z)=>Z.length===1?Z[0].element:null,v3=(Z,Q)=>Q.length>0&&Q.every(({element:J})=>Z.mathCapabilityByElement.get(J)==="token"),f9=3,h3=(Z,Q,J)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:Y,endContainer:X}=Q.range;if(Y===X&&Y.nodeType===f9)return!1;return J.some(({element:j})=>Z.mathCapabilityByElement.get(j)==="token"&&j.contains(Y)&&j.contains(X))},I9=(Z)=>Z?.type==="range"&&n0(Z.range.startContainer),m3=(Z,Q)=>{if(!I9(Q))return null;let{startContainer:J,endContainer:Y,startOffset:X,endOffset:G}=Q.range;if(J!==Y||J.nodeType!==f9)return null;return Z.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:G})},u3=(Z,Q)=>({chunk:Z,regionTarget:f3(Z),renderedMathTargetResolver:E9(),mathCapabilityByElement:new Map(Z.mathAlignments.map(({element:J})=>[J,Q?C9(J):"expression"])),heldTokenByElement:new Map}),v9=(Z)=>{let Q=Z.mathTokenHighlighting!==!1,J=new Map(Z.chunks.map((Y)=>[Y.id,u3(Y,Q)]));return{chunks:Z.chunks,resolveInitial(Y){let X=J.get(Y);if(!X)return k9();let G=V7(X.chunk.mathAlignments),j=G?X.mathCapabilityByElement.get(G):null;if(j==="expression")return I0({semanticTarget:null,expressionTarget:x9(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 k9();let{chunk:G}=X,j=_9(G,Y),B=y9(G,j),V=I3(B,G),K=!B||V.length>0?S9(G,j,Y,V,X.renderedMathTargetResolver):null,U=K?.quality==="semantic-token"?K:m3(X,B)??K,$=Q&&U&&U.quality!=="expression"?U:null,z=U&&U.quality==="expression"?U:null;if($){let D=V7(V);if(D)X.heldTokenByElement.set(D,$);return I0({semanticTarget:$,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}if(B&&!I9(B)&&(Q?!h3(X,B,V):V.length===0))return I0({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason});if(v3(X,V)){let D=V7(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??x9(X,V),regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}}};var p3=(Z)=>{return Z.alignment?.speech.boundaryOffsetSpace??Z.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},g3=(Z)=>{if(Z.mathAlignments?.length)return Z.mathAlignments;if(Z.mathAlignment&&Z.sourceElement)return[{element:Z.sourceElement,alignment:Z.mathAlignment}];return[]},h9=(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:g3(J),offsetSpace:p3(J)}))};var c3=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),iZ=(Z,Q)=>{let J=fZ(Z,c3);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}]},K7=(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 d3=(Z,Q)=>e0([Z],Q),l3=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",i3=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),s3=new Set(["heading","listitem","option","radio"]),n3=(Z)=>{if(Z.type!=="text"||!Z.sourceElement)return!1;let Q=Z.sourceElement.tagName.toUpperCase(),J=(Z.sourceElement.getAttribute("role")||"").toLowerCase();return i3.has(Q)||s3.has(J)},m9=async(Z)=>{let Q=Z.resolveMathSpeech??d3,J=J7(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=n3(K)?[{text:K.text,offset:0}]:v0(K.text,{locale:Z.language});for(let N of M){let A=y(N.text);if(!A)continue;let P=j(A);X.push({sourceChunkIndex:V,segment:{kind:"prose",spokenText:A,visibleText:A,visibleSpan:P}}),B.push(A)}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:l3(Z.language),visibleText:Y,plainSpeechText:y(B.join(" "))}};var r3=(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},q7=async(Z)=>{let Q=F0(Z.contentRoot,Z.textProcessingOptions,Z.range),J=await m9({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:iZ(V,Z.contentRoot),visibleMap:r3(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 a3=(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:W7(Q.visibleMap,0,Z.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Q.visibleMap}},u9=(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}},o3=(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:u9(Z,Q)}},U7=(Z,Q={})=>Z.items.map(({segment:J,anchor:Y})=>{if(J.kind==="prose")return a3(J,Y);if(Q.format==="ssml"&&J.ssml)return o3(J,Y,J.ssml);return u9(J,Y)});function sZ(Z){let Q=Z instanceof Error?Z:Error(String(Z));return Q.code="tts-start-failed",Q}var o=Z2("tts-service",s9),R;(function(Z){Z.IDLE="idle",Z.LOADING="loading",Z.PLAYING="playing",Z.PAUSED="paused",Z.ERROR="error"})(R||(R={}));var Q2={baseMs:280,units:{minor:0.65,section:1,major:1.35},minMs:120,maxMs:900},p9=0.25,g9=4,h0=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,c9=(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}},d9=(Z)=>("commonAncestorContainer"in Z),n9=(Z,Q)=>Z===Q||Z.startContainer===Q.startContainer&&Z.startOffset===Q.startOffset&&Z.endContainer===Q.endContainer&&Z.endOffset===Q.endOffset,J2=(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 n9(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},Y2=(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},X2=(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"},i9=(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 $7{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=X7();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=c9(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=c9(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:!n9(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 K7(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=K7(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=c5(Z,{contentLanguage:Q})??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,!s9())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:Y2(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=Q2;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(p9,Math.min(g9,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&&X2(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}=i9(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}=i9(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(d9(Z)?Z.startContainer:Z,Q.language),j=d9(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=d5(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 $=d5(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 N=this.hasExplicitBreakSemantics(G),A=!!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(A&&this.currentContentElement)this.seekSegments=this.createSpeechPlan(this.currentContentElement,V,M,Q.language);else this.seekSegments=this.createSeekSegmentsFromText(B);if(this.sentenceHighlightSegments=N?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:A,playbackSegments:this.seekSegments}),Y=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Q,highlightMode:D,shouldUsePlan:A,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:A,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:g5($,Z)||Q.language,useFallback:!0,context:Q.catalogContext},M=J.getAlternative(z,{...D,form:"payload"}),N=M?.payload?v8({payload:M.payload})??void 0:void 0,P=J.getAlternative(z,{...D,form:"content"})?.content;if(N===void 0&&P===void 0)return null;return{script:P,audio:N}},V=($,z)=>{let D=K($);if(D.length!==1)return null;let M=D[0],N=F0(M,this.getTextProcessingOptions(Q.language)).visibleText||y(M.textContent||""),A=(P)=>y(P).replace(/\s+/g,"");return A(N)===A(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)),N=M.visibleText||y(b8(z)),A=iZ(z,Z),P=null;if(D.script!==void 0){let O=D.script,C=cZ({speechText:O,visibleText:N}),E=V(z,N),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})}));P={speechText:O,visibleText:N,sourceElement:z,regionElement:A,speechMatchesVisibleText:y(O)===N,playbackMode:C.playbackMode,alignment:C,mathAlignment:v,mathAlignments:S,visibleMap:M.map}}if(D.audio){Y.push(P?{...P,audio:D.audio,plainFallback:P}:{speechText:N,visibleText:N,sourceElement:z,regionElement:A,speechMatchesVisibleText:!1,visibleMap:M.map,audio:D.audio});return}if(P)Y.push(P);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 q7({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=U7(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&&J2(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=t3(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=e3(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?h9({contentRoot:J,chunks:[Z]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,G=Y?v9({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(p9,Math.min(g9,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 G2,isTtsDebugEnabled as j2}from"@pie-players/pie-players-shared/pie";var r9=G2("browser-tts-provider",j2),a9=5000,e9=2000,o9=260,B2=80,W2=["__pieTelemetry","contentLanguage","highlightMode","locale","mathSpeech","segmenter","structuralPauses","textNormalization"],Z1=(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 W2)if(J[X]!==void 0)Y[X]=J[X];if(Object.keys(Y).length>0)Q.providerOptions=Y}return Q},t9=(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}}},F7=(Z)=>String(Z||"").trim().toLowerCase(),V2=()=>{let Z=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return F7(Z||"en-US")},K2=(Z,Q)=>{let J=F7(Q)||V2(),Y=J.split("-")[0]||"en",X=F7(Z.lang);return X===J||X.startsWith(`${Y}-`)},q2=(Z,Q,J)=>{if(Q)return Z.find((G)=>G.voiceURI===Q)||Z.find((G)=>G.name===Q)||null;let Y=(G)=>K2(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},U2=(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()})},$2=(Z)=>!Z.default;class z7{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 U2(window.speechSynthesis,e9);return new Q1(Z)}getCapabilities(){return{supportsWordBoundary:!0,defaultHighlightMode:"sentence",supportsSSML:!1}}destroy(){}}class Q1{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 ${e9/1000} seconds.`);let J=q2(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=t9(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=t9(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<=o9)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<=o9)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&&$2(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},N=()=>{B.onstart=null,B.onend=null,B.onerror=null,B.onpause=null,B.onresume=null,B.onboundary=null},A=(O,C)=>{if(U)return;if(U=!0,M(),N(),D(),z&&this.settlePendingChunk===z)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1;if(C)j(C);else G(O)},P=(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 ${a9/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);z=()=>A(!1),this.settlePendingChunk=z,B.onstart=()=>{if(J!==this.speakRunId){A(!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){A(!1);return}if(!K){A(!1,P("ended"));return}A(!0)},B.onerror=(O)=>{if(J!==this.speakRunId){A(!1);return}if(O.error==="interrupted"||O.error==="canceled"){A(!1);return}A(!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(r9.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<=B2&&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;r9.debug(`word boundary "${u}" at ${n}`),this.onWordBoundary(u,n,K0)},$=setTimeout(()=>{if(U||K||J!==this.speakRunId)return;A(!1,P("timedOut")),speechSynthesis.cancel()},a9);try{speechSynthesis.speak(B)}catch(O){A(!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 F2=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),J1=(Z)=>Z&&typeof Z==="object"?Z:{},V0=(Z,Q)=>Z===void 0?Q:Z,Y1=(Z)=>nZ(Z)==="server"&&Z.serverProvider==="custom"?"custom":"pie",z2=(Z)=>typeof Z==="string"&&F2.has(Z)?Z:"left-aligned",_Y=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 OY=Object.freeze([0.8,1,1.25]);var D2=(Z)=>{let Q={...Z,layoutMode:z2(Z.layoutMode)};if(Z.backend!=="server")return Q;let J={...Q,apiEndpoint:V0(Q.apiEndpoint,"/api/tts"),transportMode:V0(Q.transportMode,Y1(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},D7=(Z)=>{let{enabled:Q,provider:J,...Y}=J1(Z);return D2(Y)},nZ=(Z)=>Z.backend||"browser",H7=(Z)=>{let Q=nZ(Z)==="server"?Z.serverProvider:void 0,J=Q==="polly",Y=Z.transportMode||Y1(Z),X=W0(Z.mathSpeech);return{voice:Z.defaultVoice,rate:Z.rate,pitch:Z.pitch,providerOptions:{...J1(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 H2,isGlobalDebugEnabled as A2}from"@pie-players/pie-players-shared/pie";var ZZ=H2("ToolProviderRegistry",A2);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 A7{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 _2(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(_2).filter((G)=>G!==void 0);return X.length>0?Object.assign({},...X):void 0}class _7{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=O2(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 O2(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 Y8(Z,Q={}){let J=L5(Z,Q.toolRegistry);return M5(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 r9(Z){let{request:Q,tools:J,pnpPolicy:Y,customSources:X,contextId:G}=Z,j=new D7(G);j.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=DZ(J.placement[Q.level]),V=DZ(J.policy.allowed),K=new Set(DZ(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,S]of D.blockedOverrides)$.push(H7(O,S,Q.level));let{blockedToolIds:H}=D;U=U.filter((O)=>!H.has(O));let N=new Set(Object.values(J.placement).flatMap(DZ));for(let[O,S]of D.mandates){if(z.has(O))continue;if(!B.includes(O)&&N.has(O))continue;let C=U2(O,{placedAtAnyLevel:N,allTools:J.placement,allowed:V,blocked:K,providers:J.providers}),h={rule:S,hostRule:C.hostRule,hostValue:C.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:O,message:C.hostRule==="placement-missing"?`Profile policy mandates "${O}" (${S}), but no level of tools.placement lists it.`:`Profile policy mandates "${O}" (${S}), but host policy removes it via ${C.hostRule}.`,details:h}),j.addDecision({precedence:0,rule:"required-tool-blocked",featureId:O,action:"advisory",sourceType:"host",reason:`Host removed required tool "${O}" via ${C.hostRule}`,value:h})}}for(let H=0;H<X.length;H++){let N=X[H],O=U.slice(),S=N.refine({request:Q,candidates:O}),C=new Set(S.refinedCandidates);for(let E of S.refinedCandidates)if(!O.includes(E))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:E,message:`Custom source "${N.id}" tried to add tool "${E}" that was not in candidates; ignored.`,details:{customSourceId:N.id}}),C.delete(E);U=O.filter((E)=>C.has(E));let h=new Set;if(S.decisions){for(let E of S.decisions)if(j.addDecision({precedence:E.precedence??100+H,rule:E.rule,featureId:E.featureId,action:E.action,sourceType:E.sourceType,reason:E.reason,value:E.value}),E.action==="block")h.add(E.featureId)}for(let E of O){if(C.has(E))continue;if(h.has(E))continue;j.addDecision({precedence:100+H,rule:"custom-source",featureId:E,action:"block",sourceType:"custom",reason:`Custom policy source "${N.id}" removed tool "${E}" 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((C)=>N.settings[C]?.includes(H)===!0);if(O.length===0)continue;let S={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:S})}let L=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:i0(H,Y.assessment,Y.item)}});return j.reconcileFinalStates(L),{visibleTools:P,diagnostics:$,provenance:j.build()}}function U2(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 a9={"district-block":"settings.districtPolicy.blockedTools","test-admin-override":"settings.testAdministration.toolOverrides","item-restriction":"item settings.restrictedTools","pnp-prohibited":"personalNeedsProfile.prohibitedSupports","item-requirement":"item settings.requiredTools","district-requirement":"settings.districtPolicy.requiredTools","pnp-support":"personalNeedsProfile.supports","pnp-activate-at-init":"personalNeedsProfile.activateAtInit"};function H7(Z,Q,J){return{code:"tool-policy.overrideBlocked",...J?{level:J}:{},toolId:Z,message:`settings.testAdministration.toolOverrides grants "${Z}", but ${a9[Q]} withdraws it and outranks a granting override.`,details:{rule:Q}}}function o9(Z,Q){let J=Q.map((Y)=>a9[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 $2=(Z)=>`No assessment is bound, so no policy source could grant "${Z}"`;function A7(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 t9(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";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:$2(Z),required:Boolean(G?.required),parameters:Y,assessmentBound:J.assessmentBound,diagnostics:Array.from(Q.blockedOverrides,([K,U])=>H7(K,U))}}var hZ=(Z)=>Array.isArray(Z)&&Z.length>0;function F2(Z){if(!Z)return!1;let Q=Z.personalNeedsProfile;if(Q&&(hZ(Q.supports)||hZ(Q.prohibitedSupports)||hZ(Q.activateAtInit)))return!0;let J=Z.settings;if(J){let Y=J.districtPolicy;if(Y&&(hZ(Y.blockedTools)||hZ(Y.requiredTools)))return!0;let X=J.testAdministration?.toolOverrides;if(X&&typeof X==="object"&&Object.keys(X).length>0)return!0}return!1}function z2(Z){if(!Z)return!1;return hZ(Z.requiredTools)||hZ(Z.restrictedTools)}function e9(Z){if(F2(Z.assessment))return"on";if(z2(Z.itemSettings))return"on";return"off"}class s0{id="pnp";toolRegistry;constructor(Z){this.toolRegistry=Z}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 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={blockedToolIds:new Set,mandates:new Map,perToolFlags:new Map,decisions:[],blockedOverrides:new Map,sources:{}};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}}resolveSupport(Z,Q,J){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 Y=Q.testAdmin?.toolOverrides?.[Z];if(Y===!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),Y===!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),Y===!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 X=Q.pnp?.activateAtInit?.includes(Z)===!0,G=Q.itemSettings?.requiredTools?.includes(Z)?"item-requirement":Q.districtPolicy?.requiredTools?.includes(Z)?"district-requirement":void 0;if(Y===!0){if(G)J.mandates.set(Z,G);J.perToolFlags.set(Z,{required:G!==void 0,alwaysAvailable:!0,activateAtInit:X,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(G==="item-requirement"){J.mandates.set(Z,G),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,activateAtInit:X,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(G==="district-requirement"){J.mandates.set(Z,G),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,activateAtInit:X,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(X){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,activateAtInit:X,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))continue;let K=J.get(V)??[];if(!K.includes(j))K.push(j);J.set(V,K)}return J}}var Z1=dZ({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class n0{toolRegistry;unsubscribeRegistry;contextId;assessmentOptional;pnpPolicySource;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.pnpPolicySource=new s0(this.toolRegistry),this.customSources=Z.customSources?[...Z.customSources]:[];let Q=Z.inputs??{};this.tools=Q.tools??Z1,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 r9({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 t9(Z,this.pnpPolicySource.resolveFeature(Z,{assessment:this.assessment??void 0,item:Y}),{assessmentBound:this.assessment!==null},i0(Z,this.assessment,Y))}hostFeatureGate(Z){let Q={assessmentBound:this.assessment!==null},J=DZ(this.tools.policy.blocked);if(J.includes(Z))return A7(Z,"host-blocked",J,Q);let Y=DZ(this.tools.policy.allowed);if(Y.length>0&&!Y.includes(Z))return A7(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??Z1;if(!Object.is(this.tools,Y))this.tools=Y,Q=!0}if("assessment"in Z){let Y=Z.assessment??null,X=!mZ(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 s0(Z),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??e9({assessment:this.assessment,itemSettings:Z?.settings})}itemSettingsFor(Z){return this.itemSettings.get(Z)?.at(-1)?.settings}emitIfItemSettingsChanged(Z,Q){if(mZ(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])=>o9(J,Y));if(mZ(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 D2,hasResponseValue as Q1}from"@pie-players/pie-players-shared/pie";import{isPlainRecord as Z0}from"@pie-players/pie-players-shared/object";function r0(Z){return Z0(Z)&&Z0(Z.session)?Z.session:Z}function H2(Z,Q){let J=Z0(Z)?Z:{},Y=Z0(Q)?Q:{},X=new Set([...Object.keys(J),...Object.keys(Y)]);for(let G of X)if(!mZ(r0(J[G]),r0(Y[G])))return!1;return!0}function A2(Z,Q){for(let[J,Y]of Object.entries(Z)){if(Y===void 0)continue;if(J==="itemSessions"){if(!H2(Y,Q.itemSessions))return!1;continue}if(!mZ(Y,Q[J]))return!1}return!0}function a0(Z,Q){if(!Z)return Q;let J=Z0(Q.itemSessions)?{...Q.itemSessions}:{},Y=Z0(Z.itemSessions)?Z.itemSessions:{};for(let[G,j]of Object.entries(Y)){if(!Q1(r0(j)))continue;let B=r0(J[G]);if(Q1(B)||D2(B))continue;J[G]=j}let X={...Q,itemSessions:J};return A2(X,Z)?null:X}class c extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class o0 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var J1=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),_2=(Z,Q,J)=>{let Y={...Q,...J};if(Z==="textToSpeech"&&J1(Q.mathSpeech)&&J1(J.mathSpeech))Y.mathSpeech={...Q.mathSpeech,...J.mathSpeech};return Y},O2={"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"},L2=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],M2=["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 O7{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 z7((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=O5(Z.toolConfigStrictness),J=Z.toolRegistry??new _7,Y=Z.deferToolConfigValidation===!0?dZ(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}=L5(Z,Q.toolRegistry),X=this.reportedRegistryUnavailable||this.toolRegistryPending()?Y.filter((G)=>G.code!=="tools.registryUnavailable"):Y;if(M5(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 _7,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks={...Q.hooks},this.lazyInit=Z.lazyInit===!0,this.eagerInit=Z.eagerInit??!this.lazyInit,this.frameworkErrorBus=Z.frameworkErrorBus??new W0,this.ownsFrameworkErrorBus=!Z.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.ownedToolCoordinator=new Y1,this.toolCoordinator=this.ownedToolCoordinator,this.highlightCoordinator=new $0,this.elementToolStateStore=new T5,this.catalogResolver=new b5(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new l0,this._registerToolProviders(),this.ttsService=new q7,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.ttsService.setReadinessGate(()=>this.ensureTTSReady()),this.ttsService.setMathSpeechSource(()=>F7($7(this.resolveTTSToolConfig())).providerOptions?.mathSpeech),this.setupStatePersistenceHooks(),this.policyEngine=new n0({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,assessmentOptional:this.config.assessmentOptional===!0,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 c)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready",recoverable:!1})})}assertNotDisposed(){if(this.disposePromise!==null)throw new c}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=D8({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}" ${O2[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 c)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 c)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||L2,itemIds:Z.itemIds,listener:Z.listener})}subscribeSectionLifecycleEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||M2,listener:Z.listener})}onSectionControllerLifecycle(Z){return this.sectionControllerLifecycleListeners.add(Z),()=>{this.sectionControllerLifecycleListeners.delete(Z)}}async getOrCreateSectionController(Z){if(this.disposePromise!==null)throw new c;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 c;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 z0([X]);if(this.disposePromise!==null)throw new c;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=a0(Z.getSession?.()??null,Q);if(!J)return;await Z.applySession(J,{mode:"replace"})}createSectionControllerRetirementError(){return this.disposePromise!==null?new c:new o0}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 c||Z instanceof o0)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 c||Q instanceof o0||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=z0([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?z0([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 z0(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 z0(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=$7(Z),J=d0(Q),Y=F7(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 c)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 U7;try{await this.initializeTTSService(X,J==="browser"?Y:l9(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 c)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 c)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]:_2(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}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 P2=()=>{};function X1(Z){return Z===R.PLAYING||Z===R.LOADING}function G1(Z){let{ttsService:Q,silence:J}=Z;if(typeof Q?.onStateChange!=="function")return P2;let Y=Q.onStateChange((X)=>{if(X1(X))J()});return()=>{try{Y()}catch{}}}function j1(Z){try{if(X1(Z?.getState?.()))Z?.pause?.()}catch{}}import{timedMediaProjectionSignature as l2}from"@pie-players/pie-players-shared/timed-media";function B1(Z,Q,J){let Y=Z.detail?.runtimeId;if(typeof Y==="string"&&Y!=="")return Y===Q;return J(Z.target)}function W1(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 N2=["a[href]","button","label","summary",...["button","checkbox","combobox","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","switch","tab","treeitem"].map((Z)=>`[role="${Z}"]`)].join(", "),V1=new Set(["mi","mn","mtext"]),w2=(Z)=>V1.has(Z.localName)||Z.localName==="mrow"&&Z.children.length===1&&V1.has(Z.children[0].localName),R2=(Z)=>Array.from(Z.getElementsByTagName("mfrac")).every((Q)=>Array.from(Q.children).every(w2))?"Fraction_Over":"Fraction_General",C2=(Z)=>!Z||Z.toLowerCase().split("-")[0]==="en";function q1(Z,Q={}){if(typeof MutationObserver>"u")return()=>{};let J=new Map,Y=!1,X=async(U,$,z)=>{let D=await oZ([{type:"math",mathml:U,fallbackText:""}],{language:z,loadSre:Q.loadSre,mathSpeech:{...C2(z)?{style:R2($)}:{},engineOptions:Q.getMathSpeech?.()?.engineOptions}});return D.usedMathSpeech?D.speechText:null},G=(U)=>{if(!x5(U,N2))return;let $=CZ(U,"math"),z=$&&aZ($.outerHTML);if(!$||!z)return;let D=S8(U,{contentLanguage:Q.getContentLanguage?.()}),L=`${D??""}\x00${z}`,P=J.get(L);if(!P)P=X(z,$,D),J.set(L,P);P.then((H)=>{if(Y||!H||!U.isConnected)return;if(U.getAttribute("aria-label")!==H)U.setAttribute("aria-label",H)})},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=x5($,"mjx-container");if(z){G(z);return}if($.shadowRoot)B($.shadowRoot);V0($,(D)=>{if(D.nodeType!==1)return"skip";let L=D;if(L.localName==="mjx-container")return G(L),"skip";if(L.shadowRoot)B(L.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 b2,isGlobalDebugEnabled as S2}from"@pie-players/pie-players-shared";function E2(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 L7{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)=>E2(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 K1=b2("section-controller-binding",()=>S2());function T2(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 U1(Z,Q){return Z.has(Q.itemId)||!!Q.canonicalItemId&&Z.has(Q.canonicalItemId)}class M7{registry=new L7;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=T2(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){K1.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||U1(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(!U1(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)K1.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 $1(Z){let Q=Z.section?.identifier;return Z.sectionId||(typeof Q==="string"?Q:"")||`section-${Z.assessmentId||"default"}`}function F1(Z,Q){return["pnpEnforcement","assessment"].filter((Y)=>Z?!Object.is(Z[Y],Q[Y]):Q[Y]!==null)}function D1(Z){if(!Z)return;let Q=Symbol.for("pie.assessmentToolkit.unclaimedRegistrationWatch"),J=Z;if(J[Q])return;J[Q]=!0,Z.addEventListener(t0,(Y)=>{let X=Y.detail,G=typeof X?.itemId==="string"?X.itemId:"";z1(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 D0(Z,Q){if(typeof Z==="function")return Z;if(Z===null)return null;return typeof Q==="function"?Q:null}function H1(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,L=D0(Z.requestFrame,D.requestAnimationFrame);j=D0(Z.cancelFrame,D.cancelAnimationFrame);let P=D0(Z.setTimer,D.setTimeout);if(B=D0(Z.clearTimer,D.clearTimeout),L){let N=L(()=>K("frame"));if(!J)return;if(X=N,P){let O=P(()=>K("timer"),Q);if(J)G=O}return}let H=D0(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 A1(Z="runtime"){return`${Z}-${Math.random().toString(16).slice(2)}-${Date.now()}`}function _1(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function O1(Z){Z.lastSessionEventSignatureByItemId.clear(),Z.lastMetadataSignatureByItemId.clear()}function L1(Z){let{state:Q,itemId:J,payload:Y}=Z;if(x2(Y)){let j=k2(Y);if(Q.lastMetadataSignatureByItemId.get(J)===j)return!1;Q.lastMetadataSignatureByItemId.set(J,j)}let X=y2(Y);if(Q.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(J,X),!0}function y2(Z){let Q={...Z};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function x2(Z){return Z.intent==="metadata-only"}function k2(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 f2=(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}},i2=w7('<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>'),s2=w7('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),n2={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 i1(Z,Q){R1(Q,!0),k1(Z,n2);let J=u2("pie-assessment-toolkit",()=>p2()),Y=A1("toolkit"),X=new M7,G=new W0,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=k(Q,"assessmentId",7,""),U=k(Q,"section",7,null),$=k(Q,"sectionId",7,""),z=k(Q,"attemptId",7,""),D=k(Q,"env",23,()=>({})),L=k(Q,"ndsIcons",7,!1),P=k(Q,"locale",7,""),H=k(Q,"contentLanguage",7,""),N=k(Q,"lazyInit",7,!1),O=k(Q,"toolConfigStrictness",7,"error"),S=k(Q,"tools",23,()=>({})),C=k(Q,"toolContextResolvers",7,null),h=k(Q,"enabledTools",7,""),E=k(Q,"toolRegistry",7,null),d=k(Q,"accessibility",23,()=>({})),VZ=k(Q,"player",7,null),r=k(Q,"playerType",7,""),s=k(Q,"coordinator",7,null),HZ=k(Q,"createSectionController",7,null),AZ=k(Q,"onFrameworkError",7,null),_Z=k(Q,"errorRenderer",7,null),H0=k(Q,"assessment",7,null),qZ=k(Q,"isolation",7,"inherit"),OZ=k(Q,"session",7,null),Q0=n(null),u=n(null),QZ=n(null),R7=null,C7=null,J0=!1,uZ=null,pZ=null,gZ=null,A0=n(0),X5=n(null),JZ=n(null),G5=n(V),j5=n(E1([])),E7="",B5="",Y0=null,X0=null,_0=null,b7=null,W5=null,S7=null,O0=null,T7=!1,y7=null,x7=!1,k7=n(""),V5=null,L0=H1(),LZ=[],M0=new Map,q5=new WeakMap,P0=new Map,f7=_1(),G0=n(!1);function s1(){if(!F(Q0))return null;let W=F(Q0).getRootNode();if(W&&"host"in W)return W.host;return F(Q0).parentElement}let f=i(()=>s1());function MZ(W,q){if(!F(f)){LZ=[...LZ,{name:W,detail:q}];return}N7(F(f),W,q)}T(()=>{if(!F(f))return;if(LZ.length===0)return;let W=LZ;LZ=[],queueMicrotask(()=>{let q=F(f);if(!q){LZ=[...W,...LZ];return}for(let A of W)N7(q,A.name,A.detail)})});function I7(W){return W.details.length>0?W.details:[W.message]}function n1(W){if(!_Z())return{title:V,details:I7(W)};try{let q=_Z()(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)):I7(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 PZ(W){let q=y5({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 v7(W){return(W||[]).map((q)=>q?.message).filter((q)=>typeof q==="string")}function r1(W,q){if(W?.type==="timed-media-policy-degraded"){G.reportFrameworkError(S0({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:v7(W.degradations),recoverable:!0,scope:"cohort",cohort:q}));return}if(W?.type!=="timed-media-invalid")return;G.reportFrameworkError(S0({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:v7(W.errors),recoverable:!1,scope:"cohort",cohort:q}))}function a1(W){if(W?.type!=="timed-media-audio-started")return;if(!F(b))return;j1(F(b).ttsService)}function o1(W){return W==="coordinator-init"||W==="runtime-init"||W==="tool-config"}function j0(W){return`${W.kind}|${W.source}|${W.message}`}function h7(W){if(!AZ())return;try{AZ()(W),E7=j0(W)}catch(q){console.error(`[pie-framework:${W.kind}:${W.source}] framework error hook failed`,q)}}let m7=new WeakSet,u7=new WeakMap;function t1(W){if(typeof W!=="object"||W===null)return null;return u7.get(W)??null}function p7(W){let q=n1(W);v(JZ,W,!0),v(G5,q.title,!0),v(j5,q.details,!0)}function g7(){v(JZ,null),v(G5,V),v(j5,[],!0)}T(()=>{let W=G.subscribeFrameworkErrors((q)=>{if(console.error(H8(q),q.cause),typeof q.cause==="object"&&q.cause!==null)u7.set(q.cause,q);if(o1(q.kind)&&!m7.has(q))p7(q);MZ("framework-error",q),h7(q)});return()=>{W()}}),T(()=>{let W=s();if(!W||F(b)!==W)return;if(typeof W.subscribeFrameworkErrors!=="function")return;return I(()=>W.subscribeFrameworkErrors((q)=>{m7.add(q),G.reportFrameworkError(q)}))}),T(()=>{let W=F(b),q=E();if(!W||F(R0))return;if(typeof W.adoptToolRegistry!=="function")return;I(()=>{let A=W===F(u);if(A&&!q)return;if(W.adoptToolRegistry(q)&&A&&Y0)Y0={...Y0,toolRegistry:q}})}),T(()=>{if(!F(JZ))return;if(E7===j0(F(JZ)))return;h7(F(JZ))});function e1(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 a(W){return W&&typeof W==="object"?W:{}}function Z6(W){let q=a(W.section),A=typeof q.identifier==="string"?q.identifier:"",w=typeof W.sectionId==="string"?W.sectionId:"";return A||w}function Q6(W){return typeof W.currentItemIndex==="number"?W.currentItemIndex:-1}function J6(W){return(Array.isArray(W.renderables)?W.renderables:[]).map((A,w)=>{let M=a(A),_=a(M.entity),l=typeof _.id==="string"&&_.id||`renderable-${w}`,E0=a(_.config),_5=typeof _.version==="string"&&_.version||(typeof _.version==="number"?String(_.version):"")||(typeof E0.version==="string"?E0.version:"");return{id:l,version:_5}})}function Y6(W){let q=a(W.itemSessionsByItemId);return Object.keys(q).sort((A,w)=>A.localeCompare(w)).map((A)=>{let w=a(q[A]),M=typeof w.id==="string"?w.id:"",_=Array.isArray(w.data)?w.data:[],l="";try{l=e1(JSON.stringify(_))}catch{l=String(_.length)}return{itemId:A,sessionId:M,payloadSignature:l}})}function X6(W){let q=a(a(W.formative).states);return Object.entries(q).map(([A,w])=>{let M=a(w),_=a(M.lastOutcome).correctness??"";return`${A}:${M.tryCount??0}:${M.revealed===!0?1:0}:${String(_)}:${String(M.revealOverride??"")}`}).sort().join("|")}function G6(W){let q=W.timedMedia;return l2(q)}function j6(W){let q=a(W),A=J6(q).map((M)=>`${M.id}:${M.version}`).join("|"),w=Y6(q).map((M)=>`${M.itemId}:${M.sessionId}:${M.payloadSignature}`).join("|");return{sectionId:Z6(q),currentItemIndex:Q6(q),renderableSignature:A,itemSessionSignature:w,formativeSignature:X6(q),timedMediaSignature:G6(q)}}function B6(W){let q=j6(W);return`${q.sectionId}|${q.currentItemIndex}|${q.renderableSignature}|${q.itemSessionSignature}|${q.formativeSignature}|${q.timedMediaSignature}`}function c7(W){return W==="iife"||W==="esm"||W==="preloaded"||W==="custom"}function W6(W,q){let A=W?.type,w=c7(A)?A:c7(q)?q:W?.tagName?"custom":"iife",M=W?.tagName?.trim();if(w==="custom"&&!M)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:w,tagName:M||B[w],version:W?.version,source:W?.source,loaderConfig:W?.loaderConfig,loaderOptions:W?.loaderOptions,isDefault:!W&&!q}}function d7(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 V6(W){let q=d7(W);if(q.mode==="author")return"author";if(q.role==="instructor")return"scorer";return"candidate"}function l7(W,q){return W.sectionId===q.sectionId&&W.attemptId===q.attemptId}function i7(){if(!OZ()||OZ()===b7)return;b7=OZ(),_0={value:OZ(),cohort:{sectionId:F(e),attemptId:z()||void 0}}}function s7(W,q){i7();let A=_0;if(!A)return null;if(!l7(A.cohort,W)){if(q)_0=null;return null}return _0=null,A.value}function n7(){let W=W5,q=F(b);if(!W||!q)return;let A=s7(W,!1);if(!A)return;let w=q.getSectionController(W);if(!w)return;let M=a0(w.getSession?.()??null,A);if(!M)return;Promise.resolve().then(()=>{if(!w.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");return w.applySession(M,{mode:"replace"})}).catch((_)=>{PZ({kind:"unknown",source:"pie-assessment-toolkit",error:_,recoverable:!0})})}async function q6(){if(HZ())return HZ()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function K5(){let W=S()||{},q=m1(h());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 K6(){return Y8(K5(),{strictness:O(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:E()}).config}function U6(){let W="",q="";try{W=JSON.stringify(K5())}catch{W="[unserializable-tools]"}try{q=JSON.stringify(Object.entries(C()??{}).map(([A,w])=>[A,typeof w]))}catch{q="[unserializable-resolvers]"}return[K()||"",String(O()||"error"),W,q].join("|")}function $6(W){let q=W?.pnpEnforcement;return q==="on"||q==="off"?q:null}function F6(W){let q=K()||U()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new O7({assessmentId:q,lazyInit:N(),eagerInit:!1,toolConfigStrictness:O(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:W,toolRegistry:E(),toolContextResolvers:C(),accessibility:d(),frameworkErrorBus:G})}function r7(W){try{return JSON.stringify(W??null)}catch{return"[unserializable]"}}function a7(){return{signatures:{assessmentId:K()||"",toolConfigStrictness:String(O()||"error"),lazyInit:String(N()),tools:r7({...K5(),pnpEnforcement:void 0}),accessibility:r7(d())},toolRegistry:E()}}function z6(){let W=Y0;if(!W)return[];let q=a7(),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 D6(W,q){if(T7)return;T7=!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 H6(W){if(x7)return;x7=!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 N0(){let W=F(u);if(!W)return Promise.resolve();return v(u,null),W.dispose()}function w0(W){PZ({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}let R0=i(()=>!s()&&qZ()!=="force"&&F(QZ)?.coordinator!=null),b=i(()=>{if(F(R0))return F(QZ)?.coordinator;return s()||F(u)}),U5=i(()=>U()!=null);T(()=>{F(f),s(),qZ(),F(QZ),C(),F(U5),F(G0),S(),h(),K(),O(),N(),d(),E(),I(()=>{if(!F(f))return;if(s()){if(F(u))N0().catch(w0);uZ=null;return}if(qZ()!=="force"&&F(QZ)?.coordinator){if(F(u))N0().catch(w0);uZ=null;return}if(F(u)){let W=z6();if(W.length>0&&X0)D6(W,X0);else if(W.length>0&&(U()||F(G0)))N0().catch(w0)}if(F(u)&&uZ!==C()){try{F(u).setToolContextResolvers(C()),uZ=C()}catch(W){PZ({kind:"coordinator-init",source:"pie-assessment-toolkit",error:W})}return}if(!F(u)){if(qZ()!=="force"&&!J0){let q=P1(F(f),Y5);if(q?.coordinator&&q.runtimeId!==Y){v(QZ,q,!0),uZ=null;return}}let W=U6();if(B5===W)return;try{let q=K6();v(u,F6(q),!0),J0=qZ()!=="force",Y0=a7(),X0=null,uZ=C(),B5="",g7()}catch(q){v(u,null),B5=W,PZ({kind:"coordinator-init",source:"pie-assessment-toolkit",error:q})}}})}),T(()=>{if(!F(G0)||!F(b))return;let W=F(b);I(()=>{if(W===F(u))X0??="an item registered"})});let C0=c2(),$5=n(0);T(()=>C0.subscribe(()=>{v($5,F($5)+1)})),T(()=>{let W=typeof P()==="string"?P().trim():"";I(()=>{Promise.resolve(C0.setLocale(W||d2)).catch((q)=>{PZ({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:q instanceof Error?q:Error(String(q)),recoverable:!0})})})});let NZ=i(()=>K()||F(b)?.assessmentId||""),e=i(()=>$1({sectionId:$(),section:U(),assessmentId:K()})),F5=i(()=>d7(D())),A6=i(()=>V6(F(F5))),cZ=i(()=>W6(VZ(),r())),B0=i(()=>h2({player:F(cZ),component:"pie-assessment-toolkit"})),_6=i(()=>{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(NZ),sectionId:F(e),attemptId:z()||void 0,itemPlayer:F(cZ),ndsIcons:L()===!0,locale:(F($5),C0.getLocale()),i18n:C0,contentLanguage:H()?.trim()||void 0,reportSectionError:(W)=>{X.reportSectionError({source:"section-runtime",error:W,timestamp:Date.now()})}}}),O6=i(()=>{if(!F(b)||!F(f))return null;return{runtimeId:Y,coordinator:F(b),sectionBound:F(U5),eventTarget:F(f)}});function o7(W){if(W==null)return;let q=B6(W);if(q===F(k7))return;v(k7,q,!0),v(A0,F(A0)+1),v(X5,W,!0),MZ("composition-changed",{composition:F(X5),version:F(A0)})}function z5(W){V5=W??X.getCompositionModel(),L0.schedule(()=>{o7(V5)})}function L6(){if(!L0.isPending())return;L0.cancel(),o7(V5)}function D5(W){if(!W)return;let q=q5.get(W);if(!q)return;for(let A of q)A();q5.delete(W)}function t7(){for(let W of M0.values())D5(W.element)}function e7(W){if(D5(W.element),!F(b))return;q5.set(W.element,W1(F(b),W,{assessmentId:F(NZ),sectionId:F(e)}))}function M6(){t7();for(let W of M0.values())e7(W)}function H5(W){if(!W)return;P0.get(W)?.(),P0.delete(W)}function P6(W){H5(W),P0.set(W,q1(W,{getMathSpeech:()=>F(b)?.ttsService.getMathSpeechOptions(),getContentLanguage:()=>H()}))}function N6(W){let A={...W.result?.eventDetail||W.fallbackSession,itemId:W.itemId,canonicalItemId:W.canonicalItemId||W.itemId,sourceRuntimeId:Y};if(!L1({state:f7,itemId:W.itemId,payload:A}))return;MZ("session-changed",A)}function w6(W){if(!(W instanceof HTMLElement))return!1;return P1(W,Y5)?.runtimeId===Y}function wZ(W){return W.detail??null}function R6(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(f),q=qZ();return I(()=>{if(!W)return;if(q==="force")return v(QZ,null),()=>{J0=!1};let A=h1(W,(w)=>{if(w.runtimeId===Y)return;if(J0){H6(w.runtimeId);return}v(QZ,w,!0)});return()=>{A(),v(QZ,null),J0=!1}})}),T(()=>{let W=F(b);if(!W)return;return I(()=>G1({ttsService:W.ttsService,silence:()=>X.requestMediaPauseForCompetingAudio()}))}),T(()=>{let W=F(R0)?F(QZ)?.runtimeId??null:null,q=W?"inherited":"owned";if(q!==R7)R7=q,MZ(q==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:W})}),T(()=>{let W=F(f);if(!W)return;I(()=>D1(W.ownerDocument))}),T(()=>{let W=F(b);if(!W)return;let q=F(R0)?"inherited":"owned";I(()=>{if(W===C7)return;C7=W,MZ("runtime-ready",{runtimeId:Y,coordinator:W,ownership:q})})}),T(()=>{let W=F(e),q=z()||"";O1(f7)}),T(()=>{if(!F(f))return;F(f).setAttribute("data-item-player-type",F(cZ).type),F(f).setAttribute("data-item-player-tag",F(cZ).tagName),F(f).setAttribute("data-env-mode",F(F5).mode),F(f).setAttribute("data-env-role",F(F5).role)}),T(()=>{return F(b),F(NZ),F(e),M6(),()=>{t7()}}),T(()=>{if(!F(f))return;return v2({host:F(f),instrumentationProvider:F(B0),component:"pie-assessment-toolkit",eventMap:m2,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:F(NZ),sectionId:F(e),attemptId:z()||void 0}})});let A5=null;T(()=>{H0(),S();let W=F(b);if(!W)return;if(W!==F(u))return;I(()=>{let q={pnpEnforcement:$6(S()),assessment:H0()??null},A=A5?.coordinator===W?A5.inputs:null;A5={coordinator:W,inputs:q};for(let w of F1(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(!g2(F(B0)))return;if(!F(B0).isReady())return;let A=new Date().toISOString(),w={...q||{},instrumentationLayer:"toolkit",assessmentId:F(NZ),sectionId:F(e),attemptId:z()||void 0,component:"pie-assessment-toolkit",sourceEventName:W,timestamp:A};F(B0).trackEvent(W,w);let M=q&&typeof q.errorType==="string"?q.errorType:void 0;if(!W.endsWith("-error")&&!M)return;let _=q&&typeof q.message==="string"?q.message:`Toolkit telemetry error: ${W}`;F(B0).trackError(Error(_),{component:"pie-assessment-toolkit",errorType:M||"ToolkitTelemetryError",...w})})}),T(()=>{if(!U()||!F(b))return;let W=!1;if(F(b)===I(()=>F(u)))X0??="a section initialized";let q={sectionId:F(e),attemptId:z()||void 0},A=S7;if(S7=q,A&&!l7(A,q))I(()=>N1(F(f),{reason:"teardown",logger:J}));W5=null;let w=I(()=>s7(q,!0));return X.initialize({coordinator:F(b),section:U(),sectionId:F(e),assessmentId:F(NZ),attemptId:z()||void 0,view:F(A6),initialSession:w,createDefaultController:q6,onCompositionChanged:(M)=>{if(W)return;z5(M)},onControllerEvent:(M)=>{if(W)return;a1(M),r1(M,q)}}).then(()=>{if(W)return;W5=q;let M=I(()=>F(JZ));if(M&&j0(M)===O0)g7();O0=null,I(()=>n7()),I(()=>L6()),queueMicrotask(()=>{if(W)return;MZ("toolkit-ready",{runtimeId:Y,assessmentId:F(NZ),sectionId:F(e),itemPlayer:F(cZ),coordinator:F(b)}),MZ("section-ready",{sectionId:q.sectionId,attemptId:q.attemptId,controller:F(b).getSectionController(q)??null})})}).catch((M)=>{if(W)return;let _=I(()=>t1(M));if(_)I(()=>p7(_)),O0=j0(_);else O0=j0(PZ({kind:"runtime-init",source:"pie-assessment-toolkit",error:M,cohort:q}))}),()=>{W=!0}}),T(()=>{OZ(),I(()=>{i7(),n7()})}),T(()=>{if(!F(f))return;let W=F(f),q=(M)=>{if(!B1(M,Y,w6))return!1;return M.stopPropagation(),!0},w=R6(W,[{name:t0,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.element||!_?.itemId)return;let l=X.register(_);if(M0.set(_.element,_),v(G0,!0),e7(_),P6(_.element),X.handleContentRegistered(_),l)z5()}},{name:u1,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.itemId)return;let l=_?.element?X.unregister(_.element):!1;if(D5(_.element),H5(_.element),_.element)M0.delete(_.element);if(X.handleContentUnregistered(_),l)z5()}},{name:p1,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.itemId)return;let l=X.updateItemSession(_.itemId,_.session);N6({itemId:_.itemId,canonicalItemId:X.getCanonicalItemId(_.itemId),result:l,fallbackSession:_.session})}},{name:g1,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.itemId)return;X.handleContentLoaded({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,detail:_.detail,timestamp:Date.now()})}},{name:c1,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.itemId)return;X.handleItemPlayerError({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,error:_.error,timestamp:Date.now()})}},{name:d1,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.itemId)return;if(_.action!=="check"&&_.action!=="retry")return;X.handleFormativeAction({itemId:_.itemId,canonicalItemId:_.canonicalItemId,action:_.action,outcomes:_.outcomes})}},{name:l1,handler:(M)=>{if(!q(M))return;let _=wZ(M);if(!_?.renderableId)return;if(_.action!=="attach"&&_.action!=="detach")return;X.handleMediaTimeSource({renderableId:_.renderableId,action:_.action,source:_.source,origin:_.origin})}}]);return()=>{I(()=>N1(W,{reason:"teardown",logger:J})),w();for(let M of[...P0.keys()])H5(M)}}),T(()=>{if(!F(f))return;return()=>{gZ?.disconnect(),gZ=null,pZ?.disconnect(),pZ=null}}),T(()=>{let W=F(f),q=F(O6);if(!W||!q)return;I(()=>{if(gZ){gZ.setValue(q);return}gZ=new M1(W,{context:Y5,initialValue:q}),gZ.connect()})}),T(()=>{let W=F(f),q=F(_6);if(!W||!q)return;I(()=>{if(pZ){pZ.setValue(q);return}pZ=new M1(W,{context:v1,initialValue:q}),pZ.connect()})});async function C6(){if(!F(b))throw Error("Coordinator not initialized");await F(b).waitUntilReady()}function E6(W){if(!F(b))throw Error("Coordinator not initialized");F(b).setHooks(W)}function b6(W){return X.navigateToItem(W)}function S6(){return X.getCompositionModel()}function T6(){return F(cZ)}async function y6(){await X.persist()}async function x6(){await X.hydrate()}T(()=>{let W=F(b);if(!W)return;let q=F(A0)>0||F(X5)!==null,A=!F(U5)&&F(G0);if(!q&&!A)return;I(()=>{if(W===y7)return;y7=W,W.waitUntilReady().catch(()=>{})})}),T(()=>{return()=>{L0.cancel(),X.dispose().catch((W)=>{PZ({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}).then(()=>N0()).catch(w0).finally(()=>{G.dispose()})}});var k6={waitUntilReady:C6,setHooks:E6,navigateToItem:b6,getCompositionModel:S6,getItemPlayerConfig:T6,persist:y6,hydrate:x6,get assessmentId(){return K()},set assessmentId(W){K(W),x()},get section(){return U()},set section(W){U(W),x()},get sectionId(){return $()},set sectionId(W){$(W),x()},get attemptId(){return z()},set attemptId(W){z(W),x()},get env(){return D()},set env(W){D(W),x()},get ndsIcons(){return L()},set ndsIcons(W){L(W),x()},get locale(){return P()},set locale(W){P(W),x()},get contentLanguage(){return H()},set contentLanguage(W){H(W),x()},get lazyInit(){return N()},set lazyInit(W){N(W),x()},get toolConfigStrictness(){return O()},set toolConfigStrictness(W){O(W),x()},get tools(){return S()},set tools(W){S(W),x()},get toolContextResolvers(){return C()},set toolContextResolvers(W){C(W),x()},get enabledTools(){return h()},set enabledTools(W){h(W),x()},get toolRegistry(){return E()},set toolRegistry(W){E(W),x()},get accessibility(){return d()},set accessibility(W){d(W),x()},get player(){return VZ()},set player(W){VZ(W),x()},get playerType(){return r()},set playerType(W){r(W),x()},get coordinator(){return s()},set coordinator(W){s(W),x()},get createSectionController(){return HZ()},set createSectionController(W){HZ(W),x()},get onFrameworkError(){return AZ()},set onFrameworkError(W){AZ(W),x()},get errorRenderer(){return _Z()},set errorRenderer(W){_Z(W),x()},get assessment(){return H0()},set assessment(W){H0(W),x()},get isolation(){return qZ()},set isolation(W){qZ(W),x()},get session(){return OZ()},set session(W){OZ(W),x()}},Z8=s2(),Q8=P7(Z8);f1(Q8,(W)=>v(Q0,W),()=>F(Q0));var f6=Z5(Q8,2);{var I6=(W)=>{var q=i2(),A=b1(q),w=e0(A,!0),M=Z5(A,2),_=e0(M,!0),l=Z5(M,2),E0=e0(l,!0);w1(q),S1((_5)=>{J5(w,F(G5)),J5(_,F(JZ).message),J5(E0,_5)},[()=>F(j5).join(`
|
|
225
|
-
`)]),
|
|
223
|
+
`}return Y}function X1(Z){let{request:Q,tools:J,pnpPolicy:Y,customSources:X,contextId:G}=Z,j=new _7(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 A of B)U.push(A),j.addDecision({precedence:0,rule:"placement-membership",featureId:A,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(U=U.filter((A)=>{if(J.providers?.[A]?.enabled===!1)return j.addDecision({precedence:0,rule:"provider-disabled",featureId:A,action:"block",sourceType:"host",reason:`tools.providers.${A}.enabled === false`,value:!1}),!1;return!0}),V.length>0){let A=new Set(V);U=U.filter((P)=>{if(!A.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((A)=>{if(K.has(A))return j.addDecision({precedence:0,rule:"host-blocked",featureId:A,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(M7(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:A}=D;U=U.filter((O)=>!A.has(O));let P=new Set(Object.values(J.placement).flatMap(H0));for(let[O,C]of D.mandates){if(z.has(O))continue;if(!B.includes(O)&&P.has(O))continue;let E=M2(O,{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: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 A=0;A<X.length;A++){let P=X[A],O=U.slice(),C=P.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 "${P.id}" tried to add tool "${S}" that was not in candidates; ignored.`,details:{customSourceId:P.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+A,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+A,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 A of U)for(let P of Z.unappliedItems??[]){let O=["restrictedTools","requiredTools"].filter((E)=>P.settings[E]?.includes(A)===!0);if(O.length===0)continue;let C={itemId:P.id,settings:O,toolbarLevel:Q.scope.level};$.push({code:"tool-policy.itemSettingNotApplied",level:Q.level,toolId:A,message:`Item "${P.id}" names "${A}" in ${O.join(" and ")}, but "${A}" is on the ${Q.scope.level}-level toolbar, which item settings do not reach. Place "${A}" at item level to enforce the setting per item.`,details:C})}let M=new Set(U),N=U.map((A)=>{let P=D?.perToolFlags.get(A);return{toolId:A,required:P?.required??!1,alwaysAvailable:P?.alwaysAvailable??!1,activateAtInit:P?.activateAtInit??!1,parameters:aZ(A,Y.assessment,Y.item)}});return j.reconcileFinalStates(M),{visibleTools:N,diagnostics:$,provenance:j.build()}}function M2(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 O7={"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 M7(Z,Q,J){return{code:"tool-policy.overrideBlocked",...J?{level:J}:{},toolId:Z,message:`settings.testAdministration.toolOverrides grants "${Z}", but ${O7[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":O7[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 G1(Z,Q){let J=Q.map((Y)=>O7[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 L2=(Z)=>`No assessment is bound, so no policy source could grant "${Z}"`;function L7(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 j1(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:L2(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,$])=>M7(U,$)),...Array.from(Q.supportConflicts).flatMap(([U,{support:$,grant:z}])=>z?[AZ(U,$,z)]:[])]}}var m0=(Z)=>Array.isArray(Z)&&Z.length>0;function N2(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 P2(Z){if(!Z)return!1;return m0(Z.requiredTools)||m0(Z.restrictedTools)}function B1(Z){if(N2(Z.assessment))return"on";if(P2(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 W1=i0({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??W1,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 X1({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 j1(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 L7(Z,"host-blocked",J,Q);let Y=H0(this.tools.policy.allowed);if(Y.length>0&&!Y.includes(Z))return L7(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??W1;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??B1({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])=>G1(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 w2,hasResponseValue as V1}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 R2(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 C2(Z,Q){for(let[J,Y]of Object.entries(Z)){if(Y===void 0)continue;if(J==="itemSessions"){if(!R2(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(!V1(eZ(j)))continue;let B=eZ(J[G]);if(V1(B)||w2(B))continue;J[G]=j}let X={...Q,itemSessions:J};return C2(X,Z)?null:X}var K1=[{support:"screenReader",withholds:["textToSpeech","autoplayAudio"]}];class l 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 q1=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),b2=(Z,Q,J)=>{let Y={...Q,...J};if(Z==="textToSpeech"&&q1(Q.mathSpeech)&&q1(J.mathSpeech))Y.mathSpeech={...Q.mathSpeech,...J.mathSpeech};return Y},E2={"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"},S2=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],T2=["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 w7{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 A7((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=N5(Z.toolConfigStrictness),J=Z.toolRegistry??new P7,Y=Z.deferToolConfigValidation===!0?i0(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}=P5(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 P7,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 U1,this.toolCoordinator=this.ownedToolCoordinator,this.highlightCoordinator=new DZ,this.elementToolStateStore=new k5,this.catalogResolver=new y5(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new rZ,this._registerToolProviders(),this.ttsService=new $7,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.ttsService.setReadinessGate(()=>this.ensureTTSReady()),this.ttsService.setMathSpeechSource(()=>H7(D7(this.resolveTTSToolConfig())).providerOptions?.mathSpeech),this.setupStatePersistenceHooks(),this.policyEngine=new tZ({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,assessmentOptional:this.config.assessmentOptional===!0,supportConflicts:K1,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 l)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready",recoverable:!1})})}assertNotDisposed(){if(this.disposePromise!==null)throw new l}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}" ${E2[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 l)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 l)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||S2,itemIds:Z.itemIds,listener:Z.listener})}subscribeSectionLifecycleEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||T2,listener:Z.listener})}onSectionControllerLifecycle(Z){return this.sectionControllerLifecycleListeners.add(Z),()=>{this.sectionControllerLifecycleListeners.delete(Z)}}async getOrCreateSectionController(Z){if(this.disposePromise!==null)throw new l;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 l;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 l;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 l: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 l||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 l||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=D7(Z),J=nZ(Q),Y=H7(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 l)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 z7;try{await this.initializeTTSService(X,J==="browser"?Y:Z1(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 l)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 l)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]:b2(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 y2=()=>{};function $1(Z){return Z===R.PLAYING||Z===R.LOADING}function F1(Z){let{ttsService:Q,silence:J}=Z;if(typeof Q?.onStateChange!=="function")return y2;let Y=Q.onStateChange((X)=>{if($1(X))J()});return()=>{try{Y()}catch{}}}function z1(Z){try{if($1(Z?.getState?.()))Z?.pause?.()}catch{}}import{timedMediaProjectionSignature as JQ}from"@pie-players/pie-players-shared/timed-media";function D1(Z,Q,J){let Y=Z.detail?.runtimeId;if(typeof Y==="string"&&Y!=="")return Y===Q;return J(Z.target)}function H1(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 x2=["a[href]","button","label","summary",...["button","checkbox","combobox","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","switch","tab","treeitem"].map((Z)=>`[role="${Z}"]`)].join(", "),A1=new Set(["mi","mn","mtext"]),k2=(Z)=>A1.has(Z.localName)||Z.localName==="mrow"&&Z.children.length===1&&A1.has(Z.children[0].localName),f2=(Z)=>Array.from(Z.getElementsByTagName("mfrac")).every((Q)=>Array.from(Q.children).every(k2))?"Fraction_Over":"Fraction_General",I2=(Z)=>!Z||Z.toLowerCase().split("-")[0]==="en";function _1(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:{...I2(z)?{style:f2($)}:{},engineOptions:Q.getMathSpeech?.()?.engineOptions}});return D.usedMathSpeech?D.speechText:null},G=(U)=>{if(!I5(U,x2))return;let $=b0(U,"math"),z=$&&t0($.outerHTML);if(!$||!z)return;let D=m8(U,{contentLanguage:Q.getContentLanguage?.()}),M=`${D??""}\x00${z}`,N=J.get(M);if(!N)N=X(z,$,D),J.set(M,N);N.then((A)=>{if(Y||!A||!U.isConnected)return;if(U.getAttribute("aria-label")!==A)U.setAttribute("aria-label",A)})},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=I5($,"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 h2,isGlobalDebugEnabled as m2}from"@pie-players/pie-players-shared";function v2(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 R7{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)=>v2(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 O1=h2("section-controller-binding",()=>m2());function u2(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 M1(Z,Q){return Z.has(Q.itemId)||!!Q.canonicalItemId&&Z.has(Q.canonicalItemId)}class C7{registry=new R7;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=u2(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){O1.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||M1(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(!M1(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)O1.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 L1(Z){let Q=Z.section?.identifier;return Z.sectionId||(typeof Q==="string"?Q:"")||`section-${Z.assessmentId||"default"}`}function N1(Z,Q){return["pnpEnforcement","assessment"].filter((Y)=>Z?!Object.is(Z[Y],Q[Y]):Q[Y]!==null)}function w1(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:"";P1(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 R1(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 N=OZ(Z.setTimer,D.setTimeout);if(B=OZ(Z.clearTimer,D.clearTimeout),M){let P=M(()=>K("frame"));if(!J)return;if(X=P,N){let O=N(()=>K("timer"),Q);if(J)G=O}return}let A=OZ(Z.queueMicrotaskFn,D.queueMicrotask);if(A){A(()=>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 C1(Z="runtime"){return`${Z}-${Math.random().toString(16).slice(2)}-${Date.now()}`}function b1(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function E1(Z){Z.lastSessionEventSignatureByItemId.clear(),Z.lastMetadataSignatureByItemId.clear()}function S1(Z){let{state:Q,itemId:J,payload:Y}=Z;if(g2(Y)){let j=c2(Y);if(Q.lastMetadataSignatureByItemId.get(J)===j)return!1;Q.lastMetadataSignatureByItemId.set(J,j)}let X=p2(Y);if(Q.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(J,X),!0}function p2(Z){let Q={...Z};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function g2(Z){return Z.intent==="metadata-only"}function c2(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 d2=(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}},YQ=T7('<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>'),XQ=T7('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),GQ={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 Z4(Z,Q){k1(Q,!0),g1(Z,GQ);let J=a2("pie-assessment-toolkit",()=>o2()),Y=C1("toolkit"),X=new C7,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),N=f(Q,"locale",7,""),A=f(Q,"i18n",7,null),P=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),y7=null,x7=null,XZ=!1,p0=null,g0=null,c0=null,d0=null,NZ=s(0),W5=s(null),Y0=s(null),V5=s(V),K5=s(I1([])),k7="",q5="",GZ=null,jZ=null,PZ=null,f7=null,U5=null,I7=null,wZ=null,v7=!1,h7=null,m7=!1,u7=s(""),$5=null,RZ=R1(),M0=[],CZ=new Map,F5=new WeakMap,bZ=new Map,p7=b1(),BZ=s(!1);function Q4(){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(()=>Q4());function L0(W,q){if(!F(x)){M0=[...M0,{name:W,detail:q}];return}S7(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 H of W)S7(q,H.name,H.detail)})});function g7(W){return W.details.length>0?W.details:[W.message]}function J4(W){if(!MZ())return{title:V,details:g7(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((H)=>String(H)):g7(W)}}catch(q){let H=q instanceof Error&&q.message.trim().length>0?q.message:String(q||"Unknown renderer error");return{title:V,details:[...W.details,`Error renderer failed: ${H}`]}}}function N0(W){let q=f5({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 c7(W){return(W||[]).map((q)=>q?.message).filter((q)=>typeof q==="string")}function Y4(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:c7(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:c7(W.errors),recoverable:!1,scope:"cohort",cohort:q}))}function X4(W){if(W?.type!=="timed-media-audio-started")return;if(!F(b))return;z1(F(b).ttsService)}function G4(W){return W==="coordinator-init"||W==="runtime-init"||W==="tool-config"}function WZ(W){return`${W.kind}|${W.source}|${W.message}`}function d7(W){if(!_0())return;try{_0()(W),k7=WZ(W)}catch(q){console.error(`[pie-framework:${W.kind}:${W.source}] framework error hook failed`,q)}}let l7=new WeakSet,i7=new WeakMap;function j4(W){if(typeof W!=="object"||W===null)return null;return i7.get(W)??null}function s7(W){let q=J4(W);h(Y0,W,!0),h(V5,q.title,!0),h(K5,q.details,!0)}function n7(){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)i7.set(q.cause,q);if(G4(q.kind)&&!l7.has(q))s7(q);L0("framework-error",q),d7(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 H=W===F(p);if(H&&!q)return;if(W.adoptToolRegistry(q)&&H&&GZ)GZ={...GZ,toolRegistry:q}})}),T(()=>{if(!F(Y0))return;if(k7===WZ(F(Y0)))return;d7(F(Y0))});function B4(W){let q=5381;for(let H=0;H<W.length;H+=1)q=(q<<5)+q^W.charCodeAt(H);return(q>>>0).toString(36)}function r(W){return W&&typeof W==="object"?W:{}}function W4(W){let q=r(W.section),H=typeof q.identifier==="string"?q.identifier:"",w=typeof W.sectionId==="string"?W.sectionId:"";return H||w}function V4(W){return typeof W.currentItemIndex==="number"?W.currentItemIndex:-1}function K4(W){return(Array.isArray(W.renderables)?W.renderables:[]).map((H,w)=>{let L=r(H),_=r(L.entity),i=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:i,version:L5}})}function q4(W){let q=r(W.itemSessionsByItemId);return Object.keys(q).sort((H,w)=>H.localeCompare(w)).map((H)=>{let w=r(q[H]),L=typeof w.id==="string"?w.id:"",_=Array.isArray(w.data)?w.data:[],i="";try{i=B4(JSON.stringify(_))}catch{i=String(_.length)}return{itemId:H,sessionId:L,payloadSignature:i}})}function U4(W){let q=r(r(W.formative).states);return Object.entries(q).map(([H,w])=>{let L=r(w),_=r(L.lastOutcome).correctness??"";return`${H}:${L.tryCount??0}:${L.revealed===!0?1:0}:${String(_)}:${String(L.revealOverride??"")}`}).sort().join("|")}function $4(W){let q=W.timedMedia;return JQ(q)}function F4(W){let q=r(W),H=K4(q).map((L)=>`${L.id}:${L.version}`).join("|"),w=q4(q).map((L)=>`${L.itemId}:${L.sessionId}:${L.payloadSignature}`).join("|");return{sectionId:W4(q),currentItemIndex:V4(q),renderableSignature:H,itemSessionSignature:w,formativeSignature:U4(q),timedMediaSignature:$4(q)}}function z4(W){let q=F4(W);return`${q.sectionId}|${q.currentItemIndex}|${q.renderableSignature}|${q.itemSessionSignature}|${q.formativeSignature}|${q.timedMediaSignature}`}function r7(W){return W==="iife"||W==="esm"||W==="preloaded"||W==="custom"}function D4(W,q){let H=W?.type,w=r7(H)?H:r7(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 a7(W){let q=W||{},H=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:H,role:w}}function H4(W){let q=a7(W);if(q.mode==="author")return"author";if(q.role==="instructor")return"scorer";return"candidate"}function o7(W,q){return W.sectionId===q.sectionId&&W.attemptId===q.attemptId}function t7(){if(!O0()||O0()===f7)return;f7=O0(),PZ={value:O0(),cohort:{sectionId:F(Z0),attemptId:z()||void 0}}}function e7(W,q){t7();let H=PZ;if(!H)return null;if(!o7(H.cohort,W)){if(q)PZ=null;return null}return PZ=null,H.value}function Z8(){let W=U5,q=F(b);if(!W||!q)return;let H=e7(W,!1);if(!H)return;let w=q.getSectionController(W);if(!w)return;let L=Z5(w.getSession?.()??null,H);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((_)=>{N0({kind:"unknown",source:"pie-assessment-toolkit",error:_,recoverable:!0})})}async function A4(){if(A0())return A0()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function z5(){let W=E()||{},q=s1(S());if(q.length===0)return W;let H=W.placement||{},w=Array.isArray(H.section)?H.section:null;if(w&&w.length>0)return W;return{...W,placement:{...H,section:q}}}function _4(){return U8(z5(),{strictness:C(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:u()}).config}function O4(){let W="",q="";try{W=JSON.stringify(z5())}catch{W="[unserializable-tools]"}try{q=JSON.stringify(Object.entries(v()??{}).map(([H,w])=>[H,typeof w]))}catch{q="[unserializable-resolvers]"}return[K()||"",String(C()||"error"),W,q].join("|")}function M4(W){let q=W?.pnpEnforcement;return q==="on"||q==="off"?q:null}function L4(W){let q=K()||U()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new w7({assessmentId:q,lazyInit:O(),eagerInit:!1,toolConfigStrictness:C(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:W,toolRegistry:u(),toolContextResolvers:v(),accessibility:t(),frameworkErrorBus:G})}function Q8(W){try{return JSON.stringify(W??null)}catch{return"[unserializable]"}}function J8(){return{signatures:{assessmentId:K()||"",toolConfigStrictness:String(C()||"error"),lazyInit:String(O()),tools:Q8({...z5(),pnpEnforcement:void 0}),accessibility:Q8(t())},toolRegistry:u()}}function N4(){let W=GZ;if(!W)return[];let q=J8(),H=Object.keys(q.signatures).filter((w)=>q.signatures[w]!==W.signatures[w]);if(W.toolRegistry&&q.toolRegistry!==W.toolRegistry)H.push("toolRegistry");return H}function P4(W,q){if(v7)return;v7=!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 w4(W){if(m7)return;m7=!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){N0({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=N4();if(W.length>0&&jZ)P4(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){N0({kind:"coordinator-init",source:"pie-assessment-toolkit",error:W})}return}if(!F(p)){if(q0()!=="force"&&!XZ){let q=T1(F(x),B5);if(q?.coordinator&&q.runtimeId!==Y){h(J0,q,!0),p0=null;return}}let W=O4();if(q5===W)return;try{let q=_4();h(p,L4(q),!0),XZ=q0()!=="force",GZ=J8(),jZ=null,p0=v(),q5="",n7()}catch(q){h(p,null),q5=W,N0({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 Y8=e2(),P0=c(()=>A()??Y8),VZ=s(0);T(()=>{return F(P0).subscribe?.(()=>{h(VZ,F(VZ)+1)})}),T(()=>{let W=typeof N()==="string"?N().trim():"",q=F(P0);if(!W&&q!==Y8)return;I(()=>{Promise.resolve(q.setLocale(W||ZQ)).catch((H)=>{N0({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:H instanceof Error?H:Error(String(H)),recoverable:!0})})})});let R4=c(()=>{return F(VZ),{locale:F(P0).getLocale(),direction:F(P0).getDirection?.()??"ltr"}});T(()=>{F(VZ);let W=F(x);if(!W)return;QQ(W,F(P0))});let w0=c(()=>K()||F(b)?.assessmentId||""),Z0=c(()=>L1({sectionId:$(),section:U(),assessmentId:K()})),H5=c(()=>a7(D())),C4=c(()=>H4(F(H5))),l0=c(()=>D4(n(),K0())),KZ=c(()=>n2({player:F(l0),component:"pie-assessment-toolkit"})),b4=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(l0),ndsIcons:M()===!0,locale:(F(VZ),F(P0).getLocale()),i18n:F(P0),contentLanguage:P()?.trim()||void 0,reportSectionError:(W)=>{X.reportSectionError({source:"section-runtime",error:W,timestamp:Date.now()})}}}),E4=c(()=>{if(!F(b)||!F(x))return null;return{runtimeId:Y,coordinator:F(b),sectionBound:F(D5),eventTarget:F(x)}});function X8(W){if(W==null)return;let q=z4(W);if(q===F(u7))return;h(u7,q,!0),h(NZ,F(NZ)+1),h(W5,W,!0),L0("composition-changed",{composition:F(W5),version:F(NZ)})}function A5(W){$5=W??X.getCompositionModel(),RZ.schedule(()=>{X8($5)})}function S4(){if(!RZ.isPending())return;RZ.cancel(),X8($5)}function _5(W){if(!W)return;let q=F5.get(W);if(!q)return;for(let H of q)H();F5.delete(W)}function G8(){for(let W of CZ.values())_5(W.element)}function j8(W){if(_5(W.element),!F(b))return;F5.set(W.element,H1(F(b),W,{assessmentId:F(w0),sectionId:F(Z0)}))}function T4(){G8();for(let W of CZ.values())j8(W)}function O5(W){if(!W)return;bZ.get(W)?.(),bZ.delete(W)}function y4(W){O5(W),bZ.set(W,_1(W,{getMathSpeech:()=>F(b)?.ttsService.getMathSpeechOptions(),getContentLanguage:()=>P()}))}function x4(W){let H={...W.result?.eventDetail||W.fallbackSession,itemId:W.itemId,canonicalItemId:W.canonicalItemId||W.itemId,sourceRuntimeId:Y};if(!S1({state:p7,itemId:W.itemId,payload:H}))return;L0("session-changed",H)}function k4(W){if(!(W instanceof HTMLElement))return!1;return T1(W,B5)?.runtimeId===Y}function R0(W){return W.detail??null}function f4(W,q){for(let H of q)W.addEventListener(H.name,H.handler);return()=>{for(let H of q)W.removeEventListener(H.name,H.handler)}}T(()=>{let W=F(x),q=q0();return I(()=>{if(!W)return;if(q==="force")return h(J0,null),()=>{XZ=!1};let H=i1(W,(w)=>{if(w.runtimeId===Y)return;if(XZ){w4(w.runtimeId);return}h(J0,w,!0)});return()=>{H(),h(J0,null),XZ=!1}})}),T(()=>{let W=F(b);if(!W)return;return I(()=>F1({ttsService:W.ttsService,silence:()=>X.requestMediaPauseForCompetingAudio()}))}),T(()=>{let W=F(TZ)?F(J0)?.runtimeId??null:null,q=W?"inherited":"owned";if(q!==y7)y7=q,L0(q==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:W})}),T(()=>{let W=F(x);if(!W)return;I(()=>w1(W.ownerDocument))}),T(()=>{let W=F(b);if(!W)return;let q=F(TZ)?"inherited":"owned";I(()=>{if(W===x7)return;x7=W,L0("runtime-ready",{runtimeId:Y,coordinator:W,ownership:q})})}),T(()=>{let W=F(Z0),q=z()||"";E1(p7)}),T(()=>{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(H5).mode),F(x).setAttribute("data-env-role",F(H5).role)}),T(()=>{return F(b),F(w0),F(Z0),T4(),()=>{G8()}}),T(()=>{if(!F(x))return;return s2({host:F(x),instrumentationProvider:F(KZ),component:"pie-assessment-toolkit",eventMap:r2,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:M4(E()),assessment:LZ()??null},H=M5?.coordinator===W?M5.inputs:null;M5={coordinator:W,inputs:q};for(let w of N1(H,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(!t2(F(KZ)))return;if(!F(KZ).isReady())return;let H=new Date().toISOString(),w={...q||{},instrumentationLayer:"toolkit",assessmentId:F(w0),sectionId:F(Z0),attemptId:z()||void 0,component:"pie-assessment-toolkit",sourceEventName:W,timestamp:H};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},H=I7;if(I7=q,H&&!o7(H,q))I(()=>y1(F(x),{reason:"teardown",logger:J}));U5=null;let w=I(()=>e7(q,!0));return X.initialize({coordinator:F(b),section:U(),sectionId:F(Z0),assessmentId:F(w0),attemptId:z()||void 0,view:F(C4),initialSession:w,createDefaultController:A4,onCompositionChanged:(L)=>{if(W)return;A5(L)},onControllerEvent:(L)=>{if(W)return;X4(L),Y4(L,q)}}).then(()=>{if(W)return;U5=q;let L=I(()=>F(Y0));if(L&&WZ(L)===wZ)n7();wZ=null,I(()=>Z8()),I(()=>S4()),queueMicrotask(()=>{if(W)return;L0("toolkit-ready",{runtimeId:Y,assessmentId:F(w0),sectionId:F(Z0),itemPlayer:F(l0),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(()=>j4(L));if(_)I(()=>s7(_)),wZ=WZ(_);else wZ=WZ(N0({kind:"runtime-init",source:"pie-assessment-toolkit",error:L,cohort:q}))}),()=>{W=!0}}),T(()=>{O0(),I(()=>{t7(),Z8()})}),T(()=>{if(!F(x))return;let W=F(x),q=(L)=>{if(!D1(L,Y,k4))return!1;return L.stopPropagation(),!0},w=f4(W,[{name:J5,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.element||!_?.itemId)return;let i=X.register(_);if(CZ.set(_.element,_),h(BZ,!0),j8(_),y4(_.element),X.handleContentRegistered(_),i)A5()}},{name:n1,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;let i=_?.element?X.unregister(_.element):!1;if(_5(_.element),O5(_.element),_.element)CZ.delete(_.element);if(X.handleContentUnregistered(_),i)A5()}},{name:r1,handler:(L)=>{if(!q(L))return;let _=R0(L);if(!_?.itemId)return;let i=X.updateItemSession(_.itemId,_.session);x4({itemId:_.itemId,canonicalItemId:X.getCanonicalItemId(_.itemId),result:i,fallbackSession:_.session})}},{name:a1,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:o1,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:t1,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:e1,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(()=>y1(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(E4);if(!W||!q)return;I(()=>{if(c0){c0.setValue(q);return}c0=new b7(W,{context:B5,initialValue:q}),c0.connect()})}),T(()=>{let W=F(x),q=F(b4);if(!W||!q)return;I(()=>{if(g0){g0.setValue(q);return}g0=new b7(W,{context:l1,initialValue:q}),g0.connect()})}),T(()=>{let W=F(x),q=F(R4);if(!W)return;I(()=>{if(d0){d0.setValue(q);return}d0=new b7(W,{context:i2,initialValue:q}),d0.connect()})});async function I4(){if(!F(b))throw Error("Coordinator not initialized");await F(b).waitUntilReady()}function v4(W){if(!F(b))throw Error("Coordinator not initialized");F(b).setHooks(W)}function h4(W){return X.navigateToItem(W)}function m4(){return X.getCompositionModel()}function u4(){return F(l0)}async function p4(){await X.persist()}async function g4(){await X.hydrate()}T(()=>{let W=F(b);if(!W)return;let q=F(NZ)>0||F(W5)!==null,H=!F(D5)&&F(BZ);if(!q&&!H)return;I(()=>{if(W===h7)return;h7=W,W.waitUntilReady().catch(()=>{})})}),T(()=>{return()=>{RZ.cancel(),X.dispose().catch((W)=>{N0({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}).then(()=>EZ()).catch(SZ).finally(()=>{G.dispose()})}});var c4={waitUntilReady:I4,setHooks:v4,navigateToItem:h4,getCompositionModel:m4,getItemPlayerConfig:u4,persist:p4,hydrate:g4,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 N()},set locale(W){N(W),k()},get i18n(){return A()},set i18n(W){A(W),k()},get contentLanguage(){return P()},set contentLanguage(W){P(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()}},B8=XQ(),W8=E7(B8);c1(W8,(W)=>h(YZ,W),()=>F(YZ));var d4=X5(W8,2);{var l4=(W)=>{var q=YQ(),H=v1(q),w=Y5(H,!0),L=X5(H,2),_=Y5(L,!0),i=X5(L,2),yZ=Y5(i,!0);x1(q),h1((L5)=>{j5(w,F(V5)),j5(_,F(Y0).message),j5(yZ,L5)},[()=>F(K5).join(`
|
|
225
|
+
`)]),G5(W,q)},i4=(W)=>{var q=m1(),H=E7(q);p1(H,Q,"default",{},null),G5(W,q)};u1(d4,(W)=>{if(F(Y0)&&!F(Y0).recoverable)W(l4);else W(i4,-1)})}return G5(Z,B8),f1(c4)}d2("pie-assessment-toolkit",d1(Z4,{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"},l2));export{Z4 as default};
|