@pie-players/pie-assessment-toolkit 0.3.73 → 0.3.75
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 +469 -318
- package/dist/attempt/AssessmentSession.d.ts +1 -5
- package/dist/attempt/AssessmentSession.js +0 -29
- package/dist/attempt/TestSession.d.ts +1 -20
- package/dist/attempt/TestSession.js +8 -99
- package/dist/components/ItemScope.custom-element.d.ts +1 -0
- package/dist/components/ItemScope.custom-element.js +1 -0
- package/dist/components/ItemToolBar.custom-element.d.ts +1 -0
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.d.ts +1 -0
- package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
- package/dist/components/SectionToolBar.custom-element.d.ts +1 -0
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
- package/dist/components/chunks/ItemToolBar-97hx60z4.js +2 -0
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
- package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
- package/dist/components/item-scope-element.d.ts +2 -0
- package/dist/components/item-scope-element.js +2 -0
- package/dist/context/assessment-toolkit-context.d.ts +32 -6
- package/dist/index.d.ts +23 -48
- package/dist/index.js +12 -37
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +85 -34
- package/dist/policy/core/ToolPolicyEngine.js +148 -46
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +75 -54
- package/dist/policy/core/decision-types.d.ts +65 -34
- package/dist/policy/core/feature-decision.d.ts +16 -9
- package/dist/policy/core/feature-decision.js +14 -8
- package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
- package/dist/policy/core/pnp-policy-inputs.js +28 -56
- package/dist/policy/core/provenance.d.ts +9 -4
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
- package/dist/policy/sources/PnpPolicySource.js +117 -118
- package/dist/runtime/SectionControllerBinding.d.ts +279 -0
- package/dist/runtime/SectionControllerBinding.js +450 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
- package/dist/runtime/SectionRuntimeEngine.js +30 -372
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
- package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
- package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
- package/dist/runtime/adapter/dom-event-bridge.js +17 -44
- package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
- package/dist/runtime/adapter/subscriber-fanout.js +1 -2
- package/dist/runtime/catalog-context.d.ts +19 -0
- package/dist/runtime/catalog-context.js +28 -0
- package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
- package/dist/runtime/composition-emit-scheduler.js +9 -15
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +17 -0
- package/dist/runtime/content-region.js +29 -0
- package/dist/runtime/content-registration.d.ts +13 -0
- package/dist/runtime/content-registration.js +25 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
- package/dist/runtime/core/SectionEngineCore.js +2 -2
- package/dist/runtime/core/cohort.d.ts +1 -1
- package/dist/runtime/core/cohort.js +1 -1
- package/dist/runtime/core/engine-input.d.ts +18 -30
- package/dist/runtime/core/engine-input.js +11 -12
- package/dist/runtime/core/engine-output.d.ts +16 -40
- package/dist/runtime/core/engine-output.js +9 -21
- package/dist/runtime/core/engine-readiness.d.ts +5 -37
- package/dist/runtime/core/engine-readiness.js +8 -41
- package/dist/runtime/core/engine-resolver.d.ts +46 -74
- package/dist/runtime/core/engine-resolver.js +18 -43
- package/dist/runtime/core/engine-state.d.ts +28 -36
- package/dist/runtime/core/engine-state.js +18 -21
- package/dist/runtime/core/engine-transition.d.ts +14 -19
- package/dist/runtime/core/engine-transition.js +71 -51
- package/dist/runtime/engine.d.ts +16 -19
- package/dist/runtime/engine.js +12 -19
- package/dist/runtime/page-warnings.d.ts +13 -0
- package/dist/runtime/page-warnings.js +22 -0
- package/dist/runtime/policy-input-forwarding.d.ts +25 -0
- package/dist/runtime/policy-input-forwarding.js +25 -0
- package/dist/runtime/registration-events.d.ts +14 -0
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/shell-event-bridge.d.ts +45 -0
- package/dist/runtime/shell-event-bridge.js +127 -0
- package/dist/runtime/shell-registration.d.ts +73 -0
- package/dist/runtime/shell-registration.js +95 -0
- package/dist/runtime/shell-scope.d.ts +68 -0
- package/dist/runtime/shell-scope.js +188 -0
- package/dist/runtime/tool-host-contract.d.ts +28 -10
- package/dist/runtime/tool-host-contract.js +31 -10
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/ElementToolStateStore.d.ts +14 -10
- package/dist/services/ElementToolStateStore.js +37 -13
- package/dist/services/HighlightCoordinator.d.ts +22 -28
- package/dist/services/HighlightCoordinator.js +431 -327
- package/dist/services/RangeSerializer.d.ts +10 -1
- package/dist/services/RangeSerializer.js +87 -14
- package/dist/services/TTSService.d.ts +130 -69
- package/dist/services/TTSService.js +713 -570
- package/dist/services/ToolCoordinator.d.ts +43 -66
- package/dist/services/ToolCoordinator.js +164 -208
- package/dist/services/ToolRegistry.d.ts +78 -54
- package/dist/services/ToolRegistry.js +107 -105
- package/dist/services/ToolkitCoordinator.d.ts +261 -175
- package/dist/services/ToolkitCoordinator.js +667 -433
- package/dist/services/audio-handoff.d.ts +6 -7
- package/dist/services/audio-handoff.js +20 -14
- package/dist/services/catalog-owner.d.ts +11 -1
- package/dist/services/catalog-owner.js +25 -0
- package/dist/services/create-tools-config.d.ts +2 -2
- package/dist/services/framework-error-bus.d.ts +3 -6
- package/dist/services/framework-error-bus.js +3 -6
- package/dist/services/framework-error.d.ts +30 -8
- package/dist/services/framework-error.js +9 -7
- package/dist/services/interfaces.d.ts +158 -129
- package/dist/services/section-controller-types.d.ts +15 -0
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +82 -0
- package/dist/services/spoken-audio-cards.d.ts +0 -2
- package/dist/services/spoken-audio-cards.js +1 -3
- package/dist/services/tool-config-defaults.d.ts +3 -3
- package/dist/services/tool-config-defaults.js +3 -3
- package/dist/services/tool-config-validation.d.ts +14 -4
- package/dist/services/tool-config-validation.js +63 -71
- package/dist/services/tool-context.d.ts +0 -8
- package/dist/services/tool-context.js +29 -25
- package/dist/services/tool-icons.d.ts +4 -3
- package/dist/services/tool-icons.js +4 -3
- package/dist/services/tool-instance-id.d.ts +0 -1
- package/dist/services/tool-instance-id.js +0 -6
- package/dist/services/tool-providers/TTSToolProvider.d.ts +41 -80
- package/dist/services/tool-providers/TTSToolProvider.js +81 -40
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +32 -28
- package/dist/services/tool-providers/ToolProviderRegistry.js +121 -107
- package/dist/services/tool-providers/index.d.ts +0 -9
- package/dist/services/tool-providers/index.js +2 -4
- package/dist/services/tool-request.d.ts +27 -12
- package/dist/services/tool-request.js +24 -14
- package/dist/services/toolbar-decided-tools.d.ts +15 -0
- package/dist/services/toolbar-decided-tools.js +28 -0
- package/dist/services/tools-config-normalizer.d.ts +37 -23
- package/dist/services/tools-config-normalizer.js +2 -10
- package/dist/services/tts/browser-provider.d.ts +38 -2
- package/dist/services/tts/browser-provider.js +276 -140
- package/dist/services/tts/catalog-span-alignment.d.ts +2 -17
- package/dist/services/tts/catalog-span-alignment.js +17 -142
- package/dist/services/tts/flat-tree.d.ts +71 -0
- package/dist/services/tts/flat-tree.js +269 -0
- package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
- package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
- package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
- package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/generated-speech/types.d.ts +0 -12
- package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +12 -62
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +38 -5
- package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +3 -6
- package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
- package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
- package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
- package/dist/services/tts/math-alignment/index.d.ts +0 -5
- package/dist/services/tts/math-alignment/index.js +5 -25
- package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +9 -1
- package/dist/services/tts/math-alignment/speech-tokenizer.js +38 -36
- package/dist/services/tts/math-alignment/types.d.ts +4 -2
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +74 -18
- package/dist/services/tts/math-control-names.d.ts +21 -0
- package/dist/services/tts/math-control-names.js +142 -0
- package/dist/services/tts/math-speech.d.ts +16 -1
- package/dist/services/tts/math-speech.js +55 -19
- package/dist/services/tts/provider-options.d.ts +41 -0
- package/dist/services/tts/provider-options.js +1 -0
- package/dist/services/tts/sre-engine.d.ts +7 -0
- package/dist/services/tts/sre-engine.js +11 -0
- package/dist/services/tts/sre-locales.d.ts +14 -0
- package/dist/services/tts/sre-locales.js +57 -0
- package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
- package/dist/services/tts/ssml/spoken-text.js +29 -0
- package/dist/services/tts/start-failure.d.ts +11 -0
- package/dist/services/tts/start-failure.js +19 -0
- package/dist/services/tts/text-processing.d.ts +9 -1
- package/dist/services/tts/text-processing.js +46 -34
- package/dist/services/tts/text-segmentation.d.ts +7 -0
- package/dist/services/tts/text-segmentation.js +47 -0
- package/dist/services/tts-runtime-config.d.ts +44 -18
- package/dist/services/tts-runtime-config.js +22 -93
- package/dist/tools/content-capability-resolution.d.ts +7 -9
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +58 -0
- package/dist/tools/registration.js +54 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +44 -42
- package/dist/tools/tool-tag-map.d.ts +5 -15
- package/dist/tools/tool-tag-map.js +6 -20
- package/dist/utils/structural-equality.d.ts +11 -0
- package/dist/utils/structural-equality.js +47 -0
- package/package.json +24 -59
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
- package/dist/components/chunks/ItemToolBar-byq80z42.js +0 -40
- package/dist/components/chunks/ItemToolBar-d36g3aw4.js +0 -49
- package/dist/context/runtime-context-consumer.d.ts +0 -13
- package/dist/context/runtime-context-consumer.js +0 -51
- package/dist/item-loader.d.ts +0 -44
- package/dist/item-loader.js +0 -61
- package/dist/policy/core/engine-context.d.ts +0 -29
- package/dist/policy/core/engine-context.js +0 -27
- package/dist/policy/core/policy-source-tag.d.ts +0 -31
- package/dist/policy/core/policy-source-tag.js +0 -28
- package/dist/policy/internal.d.ts +0 -25
- package/dist/policy/internal.js +0 -25
- package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
- package/dist/runtime/adapter/coordinator-bridge.js +0 -126
- package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
- package/dist/runtime/adapter/framework-error-bridge.js +0 -46
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
- package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
- package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
- package/dist/runtime/core/engine-stage-derivation.js +0 -29
- package/dist/runtime/engine-context.d.ts +0 -39
- package/dist/runtime/engine-context.js +0 -31
- package/dist/runtime/internal.d.ts +0 -43
- package/dist/runtime/internal.js +0 -45
- package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -80
- package/dist/runtime/section-runtime-engine-host-context.js +0 -95
- package/dist/runtime/stage-emit-gate.d.ts +0 -92
- package/dist/runtime/stage-emit-gate.js +0 -82
- package/dist/services/I18nService.d.ts +0 -47
- package/dist/services/I18nService.js +0 -84
- package/dist/services/ThemeProvider.d.ts +0 -95
- package/dist/services/ThemeProvider.js +0 -334
- package/dist/services/ToolConfigResolver.d.ts +0 -161
- package/dist/services/ToolConfigResolver.js +0 -229
- package/dist/services/catalog-media.d.ts +0 -56
- package/dist/services/catalog-media.js +0 -190
- package/dist/services/createDefaultToolRegistry.d.ts +0 -53
- package/dist/services/createDefaultToolRegistry.js +0 -45
- package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
- package/dist/services/defaultPersonalNeedsProfile.js +0 -26
- package/dist/services/pnp-standard-features.d.ts +0 -238
- package/dist/services/pnp-standard-features.js +0 -338
- package/dist/services/tool-providers/CortexToolProvider.d.ts +0 -13
- package/dist/services/tool-providers/CortexToolProvider.js +0 -32
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -14
- package/dist/services/tool-providers/DesmosToolProvider.js +0 -32
- package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +0 -16
- package/dist/services/tool-providers/GeoGebraToolProvider.js +0 -32
- package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +0 -35
- package/dist/services/tool-providers/LazyCalculatorToolProvider.js +0 -95
- package/dist/services/tts/visual-line-ranges.d.ts +0 -18
- package/dist/services/tts/visual-line-ranges.js +0 -226
- package/dist/tools/client.d.ts +0 -12
- package/dist/tools/client.js +0 -14
- package/dist/tools/index.d.ts +0 -8
- package/dist/tools/index.js +0 -10
- package/dist/tools/internal.d.ts +0 -43
- package/dist/tools/internal.js +0 -41
- package/dist/tools/response-discovery.d.ts +0 -61
- package/dist/tools/response-discovery.js +0 -113
- package/dist/tools/types.d.ts +0 -337
- package/dist/tools/types.js +0 -12
- package/dist/tools/variant-resolver.d.ts +0 -41
- package/dist/tools/variant-resolver.js +0 -207
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{
|
|
2
|
-
- ${
|
|
3
|
-
- `)}`}var
|
|
1
|
+
import{a as i0,b as N5,c as w5,e as P5,f as R5,g as E5,h as C5,i as GZ,j as jZ}from"./chunks/ItemToolBar-vdkyn9f3.js";import{o as g3,p as $8,q as h9,r as O5,s as c9}from"./chunks/ItemToolBar-bxwyhr5p.js";import{$ as _5,A as V5,B as q5,C as z8,D as s0,E as n0,F as T,G as $5,H as A,I,L as _8,M as A5,N as r0,O as o0,P as D5,T as F5,U as z5,Z as H5,_ as k,aa as M5,ba as a0,ea as H8,ha as L5,ja as e3,ka as t9,t as W5,u as U5,v as K5,w as s,x,y as n,z as v}from"./chunks/ItemToolBar-7tt7v2xp.js";import{la as oZ,ma as aZ}from"./chunks/ItemToolBar-jx38w99s.js";import{oa as s7}from"./chunks/ItemToolBar-97hx60z4.js";import{coerceBooleanAttributes as $2}from"@pie-players/pie-players-shared/ui/attribute-coercion";import{ContextProvider as j5,requestContext as B5}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as A2,resolveInstrumentationProvider as D2,TOOLKIT_INSTRUMENTATION_EVENT_MAP as F2}from"@pie-players/pie-players-shared/pie";import{commitPendingSessions as z2,createPieLogger as H2,isGlobalDebugEnabled as _2,isInstrumentationProvider as M2}from"@pie-players/pie-players-shared";import{createPieI18n as L2,DEFAULT_LOCALE as O2}from"@pie-players/pie-players-shared/i18n";function E0(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",cause:Z.cause}}function A1(Z){let Q=Z.error instanceof Error&&Z.error.message.trim().length>0?Z.error.message:String(Z.error||"Unknown framework error");return E0({kind:Z.kind,source:Z.source,message:Q,recoverable:Z.recoverable,scope:Z.scope,cause:Z.error})}var O6={"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"};function s8(Z){let Q=O6[Z.context.phase],J=Z.context.toolId?`pie-toolkit-coordinator/${Z.context.toolId}`:`pie-toolkit-coordinator:${Z.context.phase}`;return A1({kind:Q,source:J,error:Z.error,recoverable:Z.recoverable,scope:Z.scope})}function n8(Z){let Q=`[pie-framework:${Z.kind}:${Z.source}]`;if(Z.details.length===0)return`${Q} ${Z.message}`;return`${Q} ${Z.message}
|
|
2
|
+
- ${Z.details.join(`
|
|
3
|
+
- `)}`}var N6="error";function D1(Z){if(Z==="off"||Z==="warn"||Z==="error")return Z;return N6}function o(Z){return Z}function w6(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 P6(Z,Q,J,Y){if(!Q||!J?.sanitizeConfig)return Q;try{let X=J.sanitizeConfig(Q);if(!X||typeof X!=="object"||Array.isArray(X))return Y.push(o({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Z}`,message:`Config sanitizer of tool "${Z}" must return an object.`,toolId:Z})),Q;return X}catch(X){return Y.push(o({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Z}`,message:`Config sanitizer of tool "${Z}" failed: ${X instanceof Error?X.message:String(X)}`,toolId:Z})),Q}}function R6(Z,Q,J,Y){if(!Q||!J?.validateConfig)return;try{let X=J.validateConfig(Q);if(!Array.isArray(X)){Y.push(o({code:"tools.invalidProviderValidation",severity:"error",path:`providers.${Z}`,message:`Config validator of tool "${Z}" must return an array.`,toolId:Z}));return}for(let G of X)Y.push({...G,path:G.path||`providers.${Z}`,toolId:G.toolId||Z})}catch(X){Y.push(o({code:"tools.providerValidateFailed",severity:"error",path:`providers.${Z}`,message:`Config validator of tool "${Z}" failed: ${X instanceof Error?X.message:String(X)}`,toolId:Z}))}}function E6(Z,Q,J){if(Q.size===0)return;let Y=["section","item","passage"];for(let X of Y)for(let G of Z.placement[X]){let j=Q.get(G);if(!j){J.push(o({code:"tools.unknownToolId",severity:"error",path:`placement.${X}`,message:`Unknown tool id "${G}" in placement.${X}.`,toolId:G}));continue}if(j.activation==="region"){J.push(o({code:"tools.unplaceableActivation",severity:"error",path:`placement.${X}`,message:`Tool "${G}" renders into a host surface (activation "region") and cannot be placed on the ${X} toolbar. Remove it from placement.${X}; its availability comes from policy plus its content dependency.`,toolId:G}));continue}let B=j.supportedLevels.includes(X),U=X==="item"&&j.supportedLevels.includes("section");if(!B&&!U)J.push(o({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${G}" does not support level "${X}".`,toolId:G}))}}function C6(Z,Q,J){if(Q.size===0)return;for(let Y of Z.policy.allowed||[]){if(Q.has(Y))continue;J.push(o({code:"tools.unknownToolId",severity:"error",path:"policy.allowed",message:`Unknown tool id "${Y}" in policy.allowed.`,toolId:Y}))}for(let Y of Z.policy.blocked||[]){if(Q.has(Y))continue;J.push(o({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${Y}" in policy.blocked.`,toolId:Y}))}}function b6(Z,Q,J){for(let Y of Object.keys(Z.providers).sort()){if(Q.size===0||Q.has(Y))continue;J.push(o({code:"tools.unknownProviderKey",severity:"error",path:`providers.${Y}`,message:`Unknown provider key "${Y}".`,toolId:Y}))}}function r8(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 S6(Z,Q){let J=Z.map((Y)=>`- ${Y.path}: ${Y.message}`).join(`
|
|
4
4
|
`);throw Error(`[tool-config-validation:${Q}] Invalid tools config:
|
|
5
|
-
${Y}`)}function Z7(G,Q={}){let Y=i1(Q.strictness),J=Q.source??"tools",X=N5(Q.toolRegistry),j=b7(G),Z=[],q=Object.values(j.placement).some((H)=>H.length>0)||Object.keys(j.providers).length>0||(j.policy.allowed?.length??0)>0||(j.policy.blocked?.length??0)>0;if(X.size===0&&q)Z.push(c({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated. Pass `toolRegistry` — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let B=Object.hasOwn(j.providers,"tts"),K={...j.providers||{}};for(let H of Object.keys(K).sort()){if(H==="tts"){delete K.tts;continue}let N=X.get(H);K[H]=F5(H,K[H],N,Z),M5(H,K[H],N,Z)}let W={...j,providers:K};if(z5(W,X,Z),O5(W,X,Z),P5(W,X,B,Z),B)q6(Z.filter((H)=>H.code==="tools.removedProviderKey"),J);if(Y==="warn")j6(Z,J);let $=Z.filter((H)=>H.severity==="error");if(Y==="error"&&$.length>0)q6($,J);if(Y==="error"&&$.length===0)j6(Z,J);return{config:W,diagnostics:Z}}import{languageTagLookupSequence as b5,normalizeLanguageTag as _6}from"@pie-players/pie-players-shared/i18n/language-tags";var s1=(G)=>Array.isArray(G)&&G.length>0;function n1(G){if(G.kind==="passage")return{ownerKind:"passage",assessmentId:G.assessmentId,sectionId:G.sectionId,passageId:G.canonicalItemId||G.itemId};return{ownerKind:"itemModel",assessmentId:G.assessmentId,sectionId:G.sectionId,itemId:G.itemId,canonicalItemId:G.canonicalItemId||G.itemId}}function U6(G,Q){if(!G)return[];let Y=n1(Q),J=[];if(s1(G.accessibilityCatalogs))J.push({context:Y,catalogs:G.accessibilityCatalogs});if(s1(G.config?.extractedCatalogs))J.push({context:Y,catalogs:G.config.extractedCatalogs});if(Q.kind==="passage")return J;if(Y.ownerKind!=="itemModel")return J;for(let X of G.config?.models??[]){if(!s1(X.accessibilityCatalogs))continue;J.push({context:{...Y,modelId:X.id},catalogs:X.accessibilityCatalogs})}return J}var a1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),B6=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),W6=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),K6=new Set(["break","mark","lexicon"]);function L5(G){let Q=G;for(let Y of K6){let J=new RegExp(`<${Y}\\b([^>/]*?)\\s*/>`,"gi");Q=Q.replace(J,(X,j)=>{let Z=j?j.replace(/\s+$/,""):"";return`<${Y}${Z}></${Y}>`})}return Q}var w5=[/^localhost$/i,/^127(?:\.\d{1,3}){3}$/,/^0(?:\.\d{1,3}){3}$/,/^10(?:\.\d{1,3}){3}$/,/^192\.168(?:\.\d{1,3}){2}$/,/^172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}$/,/^169\.254(?:\.\d{1,3}){2}$/,/^::1$/,/^fe80:/i,/^fc00:/i,/^fd[0-9a-f]{2}:/i,/^metadata\.google\.internal$/i,/^metadata\.azure\.internal$/i,/^metadata\.packet\.net$/i];function R5(G){if(typeof G!=="string"||G.length===0)return!1;let Q;try{Q=new URL(G)}catch{return!1}if(Q.protocol!=="http:"&&Q.protocol!=="https:")return!1;let Y=Q.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!w5.some((J)=>J.test(Y))}function r1(G){let Q=Array.from(G.children);for(let J of Q){let X=J.tagName.toLowerCase();if(B6.has(X)){J.remove();continue}if(r1(J),!a1.has(X)){let j=G.ownerDocument.createTextNode(J.textContent??"");J.replaceWith(j)}}let Y=Array.from(G.attributes).map((J)=>J.name);for(let J of Y)if(!W6.has(J.toLowerCase()))G.removeAttribute(J);if(G.tagName.toLowerCase()==="audio"){let J=G.getAttribute("src");if(J!==null&&!R5(J))G.removeAttribute("src")}}function o1(G){let Q=G.tagName.toLowerCase(),Y=Array.from(G.attributes).filter((X)=>W6.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${E5(X.value)}"`).join("");if(K6.has(Q))return`<${Q}${Y}/>`;let J=[];for(let X of Array.from(G.childNodes))if(X.nodeType===3)J.push(q1(X.nodeValue??""));else if(X.nodeType===1){let j=X,Z=j.tagName.toLowerCase();if(B6.has(Z))continue;if(a1.has(Z))J.push(o1(j));else J.push(q1(j.textContent??""))}return`<${Q}${Y}>${J.join("")}</${Q}>`}function t1(G){let Q=String(G||"").trim();if(!Q||!Q.includes("<"))return G;if(typeof DOMParser>"u")return G;let J=new DOMParser().parseFromString(L5(Q),"text/html"),X=J.querySelector("speak");if(X)return r1(X),o1(X);let j=J.createElement("speak");for(let Z of Array.from(J.body.childNodes))j.appendChild(Z);return r1(j),Array.from(j.childNodes).map((Z)=>{if(Z.nodeType===3)return q1(Z.nodeValue??"");if(Z.nodeType===1){let q=Z;if(a1.has(q.tagName.toLowerCase()))return o1(q);return q1(q.textContent??"")}return""}).join("")}function q1(G){return G.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function E5(G){return G.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var A6=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),e1="ext:";function V6(G){if(A6.has(G))return!0;return G.startsWith(e1)&&G.length>e1.length}var $6=new Set;function G8(G,Q=new Set){if(G===null||typeof G==="string"||typeof G==="number"||typeof G==="boolean"||typeof G>"u")return G;if(typeof G!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Q.has(G))throw TypeError("catalog cards must not contain cycles");Q.add(G);try{if(Array.isArray(G))return Object.freeze(G.map((X)=>G8(X,Q)));let Y=Object.getPrototypeOf(G);if(Y!==Object.prototype&&Y!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let J={};for(let[X,j]of Object.entries(G))J[X]=G8(j,Q);return Object.freeze(J)}finally{Q.delete(G)}}function H6(G,Q,Y){let J=`${Q}|${G}`;if($6.has(J))return;$6.add(J);let X=`${Array.from(A6).join(", ")}, or an "${e1}" prefixed vendor extension`;if(Q==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${Y}" has a card of unknown type "${G}"; it is stored but no reader asks for that type, so the alternate will never be shown. Expected one of: ${X}.`);return}console.warn(`[AccessibilityCatalogResolver] lookup for unknown catalog type "${G}" on "${Y}" cannot match any card. Expected one of: ${X}.`)}var D6=(G)=>G.payload!==void 0?"payload":"content";class Q8{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(G,Q="en-US"){this.defaultLanguage=Q,this.indexCatalogs(G??[],"assessment")}setDefaultLanguage(G){this.defaultLanguage=G}onCatalogsChange(G){return this.catalogChangeListeners.add(G),()=>{this.catalogChangeListeners.delete(G)}}emitCatalogsChange(G){for(let Q of Array.from(this.catalogChangeListeners))try{Q(G)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(G,Q){let Y=Q==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let J of this.sanitizeCatalogs(G)){if(Y.has(J.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Q} catalog "${J.identifier}" ignored`);continue}Y.set(J.identifier,J)}}insertScopedCatalogs(G,Q){if(!Q||Q.length===0)return null;let Y=this.getOwnerKey(G),J=this.scopedCatalogs.get(Y),X=J?.catalogs??new Map,j=[];for(let Z of this.sanitizeCatalogs(Q)){if(X.has(Z.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${Z.identifier}" ignored for ${Y}`);continue}X.set(Z.identifier,Z),j.push(Z.identifier)}if(!J&&j.length>0)this.scopedCatalogs.set(Y,{context:{...G},catalogs:X});return{key:Y,context:{...G},catalogs:X,insertedIds:j}}removeScopedInsertion(G){let Q=this.scopedCatalogs.get(G.key);if(Q?.catalogs!==G.catalogs)return!1;let Y=!1;for(let J of G.insertedIds)Y=Q.catalogs.delete(J)||Y;if(Q.catalogs.size===0)this.scopedCatalogs.delete(G.key);return Y}registerCatalogs(G,Q){let Y=this.insertScopedCatalogs(G,Q);if(Y&&Y.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:G});let J=!0;return()=>{if(!J)return;if(J=!1,Y&&this.removeScopedInsertion(Y))this.emitCatalogsChange({reason:"scoped-removed",context:G})}}registerOwner(G){let{owner:Q,entity:Y}=G,J=n1(Q),X=[],j=[];try{j=U6(Y,Q)}catch(B){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",B)}for(let B of j)try{let K=this.insertScopedCatalogs(B.context,B.catalogs);if(K)X.push(K)}catch(K){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",K)}if(X.some((B)=>B.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:J});let q=!0;return()=>{if(!q)return;q=!1;let B=!1;for(let K of X)B=this.removeScopedInsertion(K)||B;if(B)this.emitCatalogsChange({reason:"scoped-removed",context:J})}}forOwner(G){let Q={...G};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Q),onChange:(Y)=>this.onCatalogsChange((J)=>{if(this.catalogChangeAffectsOwner(J,Q))Y()})})}addItemCatalogs(G){if(!G||G.length===0)return;this.indexCatalogs(G,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(G){return this.itemCatalogs.has(G)||this.assessmentCatalogs.has(G)||Array.from(this.scopedCatalogs.values()).some((Q)=>Q.catalogs.has(G))}getAlternative(G,Q){if(!V6(Q.type))H6(Q.type,"lookup",G);let Y=Q.context?this.scopedCatalogs.get(this.getOwnerKey(Q.context))?.catalogs.get(G):null;if(Y){let j=this.findMatchingCard(Y,Q);if(j)return this.resolveCard(G,j,"item")}if(Q.context){let j=this.findScopedCandidates(G,Q.context);if(j.length===1){let Z=this.findMatchingCard(j[0],Q);if(Z)return this.resolveCard(G,Z,"item")}else if(j.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${G}" for owner context`,Q.context),null}let J=this.itemCatalogs.get(G);if(J){let j=this.findMatchingCard(J,Q);if(j)return this.resolveCard(G,j,"item")}let X=this.assessmentCatalogs.get(G);if(X){let j=this.findMatchingCard(X,Q);if(j)return this.resolveCard(G,j,"assessment")}return null}resolveCard(G,Q,Y){return{catalogId:G,type:Q.catalog,language:Q.language,content:Q.catalog==="spoken"&&Q.content!==void 0?this.ensureSpokenSanitized(Q.content):Q.content,payload:Q.payload,source:Y}}ensureSpokenSanitized(G){let Q=this.sanitizedSpokenCache.get(G);if(Q!==void 0)return Q;let Y=t1(G);return this.sanitizedSpokenCache.set(G,Y),Y}getOwnerKey(G){return[G.ownerKind,G.assessmentId||"",G.sectionId||"",G.canonicalItemId||"",G.itemId||"",G.passageId||"",G.modelId||""].join("|")}scopedCatalogEntries(){let G=[];for(let Q of this.scopedCatalogs.values())for(let Y of Q.catalogs.entries())G.push(Y);return G}findScopedCandidates(G,Q){return Array.from(this.scopedCatalogs.values()).filter((Y)=>this.isCompatibleOwnerContext(Y.context,Q)).map((Y)=>Y.catalogs.get(G)).filter((Y)=>Boolean(Y))}isCompatibleOwnerContext(G,Q){if(G.ownerKind!==Q.ownerKind)return!1;if(Q.assessmentId&&G.assessmentId!==Q.assessmentId)return!1;if(Q.sectionId&&G.sectionId!==Q.sectionId)return!1;if(Q.canonicalItemId&&G.canonicalItemId!==Q.canonicalItemId)return!1;if(Q.itemId&&G.itemId!==Q.itemId)return!1;if(Q.passageId&&G.passageId!==Q.passageId)return!1;if(Q.modelId&&G.modelId!==Q.modelId)return!1;return!0}ownerScopedCatalogEntries(G){let Q=[],Y=this.scopedCatalogs.get(this.getOwnerKey(G));if(Y)Q.push(...Y.catalogs.entries());for(let J of this.scopedCatalogs.values()){if(J===Y)continue;if(!this.isCompatibleOwnerContext(J.context,G))continue;Q.push(...J.catalogs.entries())}return Q}createOwnerSnapshot(G){let Q=[],Y=this.ownerScopedCatalogEntries(G);if(G.ownerKind==="global")Y.push(...this.assessmentCatalogs.entries());for(let[J,X]of Y)for(let j of X.cards)try{Q.push(Object.freeze({catalogId:J,card:G8(j)}))}catch(Z){let q=`${this.getOwnerKey(G)}\x00${J}`;if(!this.reportedSnapshotProblems.has(q))this.reportedSnapshotProblems.add(q),console.warn(`[AccessibilityCatalogResolver] Catalog "${J}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,Z)}return Object.freeze({cards:Object.freeze(Q)})}catalogChangeAffectsOwner(G,Q){if(!G.context)return!1;if(this.isCompatibleOwnerContext(G.context,Q))return!0;if(Q.ownerKind==="itemModel"&&Q.modelId&&G.context.ownerKind==="itemModel"&&!G.context.modelId)return this.isCompatibleOwnerContext({...G.context,modelId:Q.modelId},Q);return!1}sanitizeCatalogs(G){return G.map((Q)=>({...Q,cards:Q.cards.map((Y)=>{if(!V6(Y.catalog))H6(Y.catalog,"card",Q.identifier);return{...Y,content:Y.catalog==="spoken"&&Y.content!==void 0?t1(Y.content):Y.content}})}))}findMatchingCard(G,Q){let{type:Y,language:J,useFallback:X=!0,form:j}=Q,Z=[],q=(B)=>{for(let K of b5(B))Z.push((W)=>_6(W.language)===K)};if(J)q(J);if(X)q(this.defaultLanguage),Z.push(()=>!0);for(let B of Z){let K=G.cards.filter((W)=>W.catalog===Y&&B(W));if(K.length===0)continue;if(j){let W=K.find(($)=>D6($)===j);if(W)return W}return K[0]}return null}getAllAlternatives(G){let Q=[],Y=new Set,J=(Z,q)=>{let B=`${Z.catalog}|${_6(Z.language)}|${D6(Z)}`;if(Y.has(B))return;Y.add(B),Q.push(this.resolveCard(G,Z,q))},X=this.itemCatalogs.get(G);if(X)for(let Z of X.cards)J(Z,"item");let j=this.assessmentCatalogs.get(G);if(j)for(let Z of j.cards)J(Z,"assessment");for(let[Z,q]of this.scopedCatalogEntries()){if(Z!==G)continue;for(let B of q.cards)J(B,"item")}return Q}getAllCatalogIds(){let G=this.scopedCatalogEntries().map(([Q])=>Q);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...G]))}getStatistics(){let G=new Set,Q=new Set;for(let Y of this.assessmentCatalogs.values())for(let J of Y.cards)if(G.add(J.catalog),J.language)Q.add(J.language);for(let Y of this.itemCatalogs.values())for(let J of Y.cards)if(G.add(J.catalog),J.language)Q.add(J.language);for(let Y of this.scopedCatalogs.values())for(let J of Y.catalogs.values())for(let X of J.cards)if(G.add(X.catalog),X.language)Q.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((Y,J)=>Y+J.catalogs.size,0),availableTypes:G,availableLanguages:Q}}hasAlternativeType(G,Q){return this.getAllAlternatives(G).some((J)=>J.type===Q)}getCatalogsByType(G){let Q=new Set;for(let[Y,J]of this.assessmentCatalogs.entries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);for(let[Y,J]of this.itemCatalogs.entries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);for(let[Y,J]of this.scopedCatalogEntries())if(J.cards.some((X)=>X.catalog===G))Q.add(Y);return Array.from(Q)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}class Y8{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(G,Q,Y,J){return`${G}:${Q}:${Y}:${J}`}parseGlobalElementId(G){let Q=G.split(":");if(Q.length!==4)return null;return{assessmentId:Q[0],sectionId:Q[1],itemId:Q[2],elementId:Q[3]}}setState(G,Q,Y){let J=this.elementStates.get(G);if(!J)J=new Map,this.elementStates.set(G,J);J.set(Q,Y),this._notifyListeners(),this._notifyStateChange()}getState(G,Q){return this.elementStates.get(G)?.get(Q)}getElementState(G){let Q=this.elementStates.get(G);if(!Q)return{};return Object.fromEntries(Q.entries())}getAllState(){let G={};for(let[Q,Y]of this.elementStates.entries())G[Q]=Object.fromEntries(Y.entries());return G}subscribe(G){return this.listeners.add(G),()=>this.listeners.delete(G)}_notifyListeners(){for(let G of this.listeners)G(this.elementStates)}setOnStateChange(G){this.onStateChange=G}_notifyStateChange(){if(this.onStateChange)this.onStateChange(this.getAllState())}loadState(G){this.elementStates.clear();for(let[Q,Y]of Object.entries(G)){let J=new Map(Object.entries(Y));this.elementStates.set(Q,J)}this._notifyListeners()}clearElement(G){this.elementStates.delete(G),this._notifyListeners(),this._notifyStateChange()}clearTool(G){for(let Q of this.elementStates.values())Q.delete(G);this._notifyListeners(),this._notifyStateChange()}clearSection(G,Q){let Y=`${G}:${Q}:`,J=[];for(let X of this.elementStates.keys())if(X.startsWith(Y))J.push(X);for(let X of J)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class p7{listeners=new Set;subscribeFrameworkErrors(G){this.listeners.add(G);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(G)}}reportFrameworkError(G){let Q=Array.from(this.listeners);for(let Y of Q)try{Y(G)}catch(J){console.warn("[FrameworkErrorBus] listener failed:",J)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}class J8{serialize(G,Q){return{startContainer:this.getNodePath(G.startContainer,Q),startOffset:G.startOffset,endContainer:this.getNodePath(G.endContainer,Q),endOffset:G.endOffset,text:G.toString()}}deserialize(G,Q){let Y=this.findNodeByPath(G.startContainer,Q),J=this.findNodeByPath(G.endContainer,Q);if(!Y||!J)return null;try{let X=new Range;if(X.setStart(Y,G.startOffset),X.setEnd(J,G.endOffset),X.toString()===G.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(G,Q){if(G===Q)return"";if(G.nodeType===Node.TEXT_NODE){let Y=G.parentElement;if(!Y)throw Error("Text node has no parent");let X=Array.from(Y.childNodes).filter((Z)=>Z.nodeType===Node.TEXT_NODE).indexOf(G);return`${this.getElementPath(Y,Q)}::text[${X}]`}if(G.nodeType===Node.ELEMENT_NODE)return this.getElementPath(G,Q);throw Error(`Unsupported node type: ${G.nodeType}`)}getElementPath(G,Q){if(G===Q)return"";let Y=[],J=G;while(J&&J!==Q){if(J.id){Y.unshift(`#${J.id}`);break}let X=J.parentElement;if(!X)break;let j=Array.from(X.children).filter((B)=>B.tagName===J.tagName),Z=j.indexOf(J),q=j.length>1?`${J.tagName.toLowerCase()}:nth-of-type(${Z+1})`:J.tagName.toLowerCase();Y.unshift(q),J=X}return Y.join(" > ")}findNodeByPath(G,Q){if(G==="")return Q;if(G.includes("::text[")){let[Y,J]=G.split("::text["),X=Number.parseInt(J.replace("]",""),10),j=Y?Q.querySelector(Y):Q;if(!j)return null;return Array.from(j.childNodes).filter((q)=>q.nodeType===Node.TEXT_NODE)[X]||null}try{return Q.querySelector(G)}catch(Y){return console.warn("Invalid selector path:",G,Y),null}}serializeMany(G,Q){return G.map((Y)=>this.serialize(Y,Q))}deserializeMany(G,Q){return G.map((Y)=>this.deserialize(Y,Q))}}var u;(function(G){G.TTS_WORD="tts-word",G.TTS_SENTENCE="tts-sentence",G.ANNOTATION="annotation"})(u||(u={}));var $7;(function(G){G.YELLOW="yellow",G.GREEN="green",G.BLUE="blue",G.PINK="pink",G.ORANGE="orange",G.UNDERLINE="underline"})($7||($7={}));class g7{config;ttsWordHighlight=null;ttsSentenceHighlight=null;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;colorHighlights=new Map;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;explicitTTSColorOverride=null;constructor(G={}){if(this.config=G,this.rangeSerializer=new J8,typeof CSS>"u"||!("highlights"in CSS)){console.warn("CSS Custom Highlight API not supported (SSR or unsupported browser)");return}this.supported=!0,this.initializeHighlights(),this.registerStyles(),this.applyAdaptiveTTSStyle(),this.setupThemeObservation()}setupThemeObservation(){if(typeof document>"u")return;if(typeof MutationObserver>"u")return;let G=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(G),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]});for(let Q of document.querySelectorAll("pie-theme"))this.themeObserver.observe(Q,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(G){if(!G)return null;let Q=G.trim();if(!Q)return null;let Y=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Q);if(Y){let X=Y[1];if(X.length===3)return[parseInt(X[0]+X[0],16),parseInt(X[1]+X[1],16),parseInt(X[2]+X[2],16)];return[parseInt(X.slice(0,2),16),parseInt(X.slice(2,4),16),parseInt(X.slice(4,6),16)]}let J=/^rgba?\((.+)\)$/i.exec(Q);if(J){let j=J[1].replace(/\//g,",").split(/[,\s]+/).map((K)=>K.trim()).filter(Boolean),Z=Number(j[0]),q=Number(j[1]),B=Number(j[2]);if(Number.isFinite(Z)&&Number.isFinite(q)&&Number.isFinite(B))return[Z,q,B]}if(typeof document<"u"){let X=document.createElement("span");if(X.style.color=Q,typeof X.style.color==="string"&&X.style.color){document.body?.appendChild(X);let j=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let Z=j.trim();if(Z&&Z!==Q)return this.parseColor(j)}}return null}relativeLuminance([G,Q,Y]){let J=(q)=>{let B=q/255;return B<=0.03928?B/12.92:((B+0.055)/1.055)**2.4},X=J(G),j=J(Q),Z=J(Y);return 0.2126*X+0.7152*j+0.0722*Z}contrastRatio(G,Q){let Y=this.relativeLuminance(G),J=this.relativeLuminance(Q),X=Math.max(Y,J),j=Math.min(Y,J);return(X+0.05)/(j+0.05)}blend(G,Q,Y){return[Math.round(G[0]*Y+Q[0]*(1-Y)),Math.round(G[1]*Y+Q[1]*(1-Y)),Math.round(G[2]*Y+Q[2]*(1-Y))]}resolveAdaptiveTTSStyle(G){let Q=[255,235,59],Y=[17,24,39],J=[255,255,255],X=G||(typeof document<"u"?document.documentElement:null),j=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,Z=this.parseColor(j?.getPropertyValue("--pie-background")||j?.backgroundColor)||J,q=this.parseColor(j?.getPropertyValue("--pie-text"))||Y,B=this.explicitTTSColorOverride?this.parseColor(this.explicitTTSColorOverride.color)||Q:this.parseColor(j?.getPropertyValue("--pie-missing"))||Q,K=this.explicitTTSColorOverride?[Math.max(0.3,Math.min(0.95,this.explicitTTSColorOverride.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],W=K[K.length-1],$=-1/0;for(let g of K){let q7=this.blend(B,Z,g),U7=this.contrastRatio(q7,Z),B7=this.contrastRatio(q7,q),w7=U7*1.2+B7*0.8;if(U7>=1.25&&B7>=2.4){W=g;break}if(w7>$)$=w7,W=g}let H=Math.max(0.24,Math.min(0.85,W*0.55)),N=Math.max(0.55,Math.min(0.95,W+0.2)),F=Math.max(0.22,Math.min(0.6,W*0.45)),O=q,L=this.blend(O,Z,N),D=this.contrastRatio(L,Z),P=this.relativeLuminance(Z)>0.45?[0,0,0]:[255,255,255],S=D>=1.35?O:P,v=`rgba(${B[0]}, ${B[1]}, ${B[2]}, ${W})`,I=`rgba(${B[0]}, ${B[1]}, ${B[2]}, ${H})`,p=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${N})`,E=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${F})`;return{wordHighlight:v,sentenceHighlight:I,wordUnderline:p,wordShadow:E}}applyAdaptiveTTSStyle(G){if(typeof document>"u")return;let Q=this.resolveAdaptiveTTSStyle(G);document.documentElement.style.setProperty("--pie-tts-word-highlight",Q.wordHighlight),document.documentElement.style.setProperty("--pie-tts-sentence-highlight",Q.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-line-highlight",Q.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-word-underline",Q.wordUnderline),document.documentElement.style.setProperty("--pie-tts-word-shadow",Q.wordShadow)}initializeHighlights(){if(!this.supported)return;this.ttsWordHighlight=new Highlight,this.ttsSentenceHighlight=new Highlight,CSS.highlights.set("tts-word",this.ttsWordHighlight),CSS.highlights.set("tts-sentence",this.ttsSentenceHighlight);for(let G of Object.values($7)){let Q=new Highlight;this.colorHighlights.set(G,Q),CSS.highlights.set(`annotation-${G}`,Q)}}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let G=document.createElement("style");G.id="pie-highlight-styles",G.textContent=`
|
|
5
|
+
${J}`)}function o8(Z,Q={}){let J=F1(Z,Q.toolRegistry);return z1(J.diagnostics,Q),J}function F1(Z,Q){let J=w6(Q),Y=c9(Z),X=[],G=Object.values(Y.placement).some((U)=>U.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 U of Object.keys(j).sort()){let q=J.get(U);j[U]=P6(U,j[U],q,X),R6(U,j[U],q,X)}let B={...Y,providers:j};return E6(B,J,X),C6(B,J,X),b6(B,J,X),{config:B,diagnostics:X}}function z1(Z,Q={}){let J=D1(Q.strictness),Y=Q.source??"tools";if(J==="warn")r8(Z,Y);let X=Z.filter((G)=>G.severity==="error");if(J==="error"&&X.length>0)S6(X,Y);if(J==="error"&&X.length===0)r8(Z,Y)}import{languageTagLookupSequence as f6,normalizeLanguageTag as ZZ}from"@pie-players/pie-players-shared/i18n/language-tags";var M1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),a8=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),t8=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),e8=new Set(["break","mark","lexicon"]);function T6(Z){let Q=Z;for(let J of e8){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 y6=[/^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 x6(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!y6.some((Y)=>Y.test(J))}function H1(Z){let Q=Array.from(Z.children);for(let Y of Q){let X=Y.tagName.toLowerCase();if(a8.has(X)){Y.remove();continue}if(H1(Y),!M1.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(!t8.has(Y.toLowerCase()))Z.removeAttribute(Y);if(Z.tagName.toLowerCase()==="audio"){let Y=Z.getAttribute("src");if(Y!==null&&!x6(Y))Z.removeAttribute("src")}}function _1(Z){let Q=Z.tagName.toLowerCase(),J=Array.from(Z.attributes).filter((X)=>t8.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${k6(X.value)}"`).join("");if(e8.has(Q))return`<${Q}${J}/>`;let Y=[];for(let X of Array.from(Z.childNodes))if(X.nodeType===3)Y.push(C0(X.nodeValue??""));else if(X.nodeType===1){let G=X,j=G.tagName.toLowerCase();if(a8.has(j))continue;if(M1.has(j))Y.push(_1(G));else Y.push(C0(G.textContent??""))}return`<${Q}${J}>${Y.join("")}</${Q}>`}function L1(Z){let Q=String(Z||"").trim();if(!Q||!Q.includes("<"))return Z;if(typeof DOMParser>"u")return Z;let Y=new DOMParser().parseFromString(T6(Q),"text/html"),X=Y.querySelector("speak");if(X)return H1(X),_1(X);let G=Y.createElement("speak");for(let j of Array.from(Y.body.childNodes))G.appendChild(j);return H1(G),Array.from(G.childNodes).map((j)=>{if(j.nodeType===3)return C0(j.nodeValue??"");if(j.nodeType===1){let B=j;if(M1.has(B.tagName.toLowerCase()))return _1(B);return C0(B.textContent??"")}return""}).join("")}function C0(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function k6(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var BZ=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),O1="ext:";function QZ(Z){if(BZ.has(Z))return!0;return Z.startsWith(O1)&&Z.length>O1.length}var JZ=new Set;function N1(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)=>N1(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]=N1(G,Q);return Object.freeze(Y)}finally{Q.delete(Z)}}function YZ(Z,Q,J){let Y=`${Q}|${Z}`;if(JZ.has(Y))return;JZ.add(Y);let X=`${Array.from(BZ).join(", ")}, or an "${O1}" 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 XZ=(Z)=>Z.payload!==void 0?"payload":"content";class w1{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=GZ(Q),X=[],G=[];try{G=jZ(J,Q)}catch(U){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",U)}for(let U of G)try{let q=this.insertScopedCatalogs(U.context,U.catalogs);if(q)X.push(q)}catch(q){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",q)}if(X.some((U)=>U.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:Y});let B=!0;return()=>{if(!B)return;B=!1;let U=!1;for(let q of X)U=this.removeScopedInsertion(q)||U;if(U)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(!QZ(Q.type))YZ(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=L1(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:N1(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(!QZ(J.catalog))YZ(J.catalog,"card",Q.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?L1(J.content):J.content}})}))}findMatchingCard(Z,Q){let{type:J,language:Y,useFallback:X=!0,form:G}=Q,j=[],B=(U)=>{for(let q of f6(U))j.push((K)=>ZZ(K.language)===q)};if(Y)B(Y);if(X)B(this.defaultLanguage),j.push(()=>!0);for(let U of j){let q=Z.cards.filter((K)=>K.catalog===J&&U(K));if(q.length===0)continue;if(G){let K=q.find(($)=>XZ($)===G);if(K)return K}return q[0]}return null}getAllAlternatives(Z){let Q=[],J=new Set,Y=(j,B)=>{let U=`${j.catalog}|${ZZ(j.language)}|${XZ(j)}`;if(J.has(U))return;J.add(U),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 U of B.cards)Y(U,"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()}}function P1(Z){return Z.replace(/%/g,"%25").replace(/:/g,"%3A")}function I6(Z){return Z.replace(/%(25|3A)/g,(Q,J)=>J==="25"?"%":":")}class R1{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Z,Q,J,Y){return[Z,Q,J,Y].map(P1).join(":")}parseGlobalElementId(Z){let Q=Z.split(":");if(Q.length!==4)return null;let[J,Y,X,G]=Q.map(I6);return{assessmentId:J,sectionId:Y,itemId:X,elementId:G}}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=`${P1(Z)}:${P1(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()}}class B0{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 v6=new Set(["pie-item-toolbar","pie-section-toolbar","pie-item-player-session-debugger"]),h6=["pie-tool-","pie-section-player-tools-"],m6=new Set(["style","script","noscript","template"]),m=(Z)=>!!Z&&Z.nodeType===11&&Z.host?.nodeType===1,u6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(v6.has(Q))return!0;return h6.some((J)=>Q.startsWith(J))},p6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(m6.has(Q))return!0;if(u6(Z))return!0;return m(Z.parentNode)&&Z.getAttribute("aria-hidden")==="true"},g6=(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}},$9=(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=g6(Y)??Y.childNodes}let J=[];for(let Y of Array.from(Q||[])){if(Y.nodeType===1&&p6(Y))continue;J.push(Y)}return J},W0=(Z,Q)=>{let J=(Y)=>{for(let X of $9(Y)){let G=Q(X);if(G==="stop")return!1;if(G==="skip")continue;if(!J(X))return!1}return!0};J(Z)},R9=(Z)=>{let Q=[];return W0(Z,(J)=>{if(J.nodeType===3)Q.push(J);return}),Q},UZ=(Z)=>R9(Z).map((Q)=>Q.data).join(""),KZ=(Z,Q)=>{let J=[];return W0(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))J.push(Y);return}),J},E9=(Z,Q)=>{let J=null;return W0(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))return J=Y,"stop";return}),J},WZ=(Z)=>{let Q=Z.assignedSlot;if(Q)return Q;let J=Z.parentNode;if(m(J))return J.host;return J},c=(Z)=>{let Q=WZ(Z);while(Q&&Q.nodeType!==1)Q=WZ(Q);return Q},E1=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(J.matches(Q))return J;J=c(J)}return null},d=(Z)=>{if(Z.parentElement)return Z.parentElement;let Q=Z.parentNode;return m(Q)?Q.host:null},b0=(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},t=(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},VZ=(Z,Q)=>{let J=Z;while(J){let Y=J.getRootNode?.();if(Y===Q)return J;J=m(Y)?Y.host:null}return null},U0=(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 qZ(Z,VZ(Q,Y))}catch{return!1}},X9=(Z,Q)=>{try{let J=Z.startContainer.getRootNode?.();if(!J||Q.getRootNode?.()===J)return Z.intersectsNode(Q);return qZ(Z,VZ(Q,J))}catch{return!1}},qZ=(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 C1=" >>> ";class b1{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:U}=G,q=B??(m(U)?U:null);if(!q)break;let K=G.tagName,$=Array.from(q.children).filter((M)=>M.tagName===K),D=$.indexOf(G),z=$.length>1?`${K.toLowerCase()}:nth-of-type(${D+1})`:K.toLowerCase();if(X.unshift(z),B)G=B;else j(q)}return Y.unshift(X.join(" > ")),Y.join(C1)}getShadowRootPath(Z,Q){return`${this.getElementPath(Z.host,Q)}${C1}`}resolveElementPath(Z,Q){let J=Q,Y=Z.split(C1);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(U){return console.warn("Invalid selector path:",Z,U),null}if(!j)return null;return Array.from(j.childNodes).filter((U)=>U.nodeType===Node.TEXT_NODE)[G]||null}try{return this.resolveElementPath(Z,Q)}catch(J){return console.warn("Invalid selector path:",Z,J),null}}serializeMany(Z,Q){return Z.map((J)=>this.serialize(J,Q))}deserializeMany(Z,Q){return Z.map((J)=>this.deserialize(J,Q))}}var i;(function(Z){Z.TTS_WORD="tts-word",Z.TTS_SENTENCE="tts-sentence",Z.ANNOTATION="annotation"})(i||(i={}));var q0;(function(Z){Z.YELLOW="yellow",Z.GREEN="green",Z.BLUE="blue",Z.PINK="pink",Z.ORANGE="orange",Z.UNDERLINE="underline"})(q0||(q0={}));var zZ=`
|
|
6
6
|
/* TTS highlights - temporary */
|
|
7
7
|
::highlight(tts-word) {
|
|
8
8
|
background-color: var(--pie-tts-word-highlight, color-mix(in srgb, var(--pie-missing, #ffeb3b) 68%, transparent));
|
|
@@ -212,14 +212,14 @@ ${Y}`)}function Z7(G,Q={}){let Y=i1(Q.strictness),J=Q.source??"tools",X=N5(Q.too
|
|
|
212
212
|
text-shadow: none;
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
`,document.head.appendChild(G)}highlightTTSWord(G,Q,Y){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(G.parentElement),this.clearTTSWord();let J=document.createRange();J.setStart(G,Q),J.setEnd(G,Y),this.ttsWordHighlight.add(J)}highlightTTSWordElement(G){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(G),this.clearTTSWord(),G.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(G)}highlightTTSSentence(G){if(!this.ttsSentenceHighlight)return;let Q=G[0]?.startContainer,Y=Q?.nodeType===Node.ELEMENT_NODE?Q:Q?.parentElement;this.applyAdaptiveTTSStyle(Y),this.clearTTSSentence();for(let J of G)this.ttsSentenceHighlight.add(J);this.highlightTTSElementFallbacks(G)}highlightTTSSentenceElements(G){if(!this.ttsSentenceHighlight)return;this.applyAdaptiveTTSStyle(G[0]||null),this.clearTTSSentence();for(let Q of G)Q.setAttribute("data-pie-tts-sentence-element","true"),this.ttsSentenceElementHighlights.add(Q)}static SENTENCE_FALLBACK_SELECTOR="math, mjx-container, svg, img, canvas, [role='img']";static WORD_FALLBACK_SELECTOR="svg, img, canvas, [role='img']";highlightTTSElementFallbacks(G){if(typeof Element>"u")return;this.highlightElementFallbacks(G,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,g7.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(G){if(typeof Element>"u")return;this.highlightElementFallbacks(G,"data-pie-tts-word-element",this.ttsWordElementHighlights,g7.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(G,Q,Y,J){for(let X of G){let j=X.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?X.commonAncestorContainer:X.commonAncestorContainer.parentElement;if(!j)continue;let Z=[],q=X.startContainer.nodeType===Node.ELEMENT_NODE?X.startContainer:X.startContainer.parentElement,B=X.endContainer.nodeType===Node.ELEMENT_NODE?X.endContainer:X.endContainer.parentElement;for(let K of[q,B]){let W=K;while(W){if(W.matches?.(J))Z.push(W);W=W.parentElement}}if(j.matches?.(J))Z.push(j);Z.push(...Array.from(j.querySelectorAll(J)));for(let K of new Set(Z)){try{if(!X.intersectsNode(K)&&!K.contains(q)&&!K.contains(B))continue}catch{continue}K.setAttribute(Q,"true"),Y.add(K)}}}clearTTSWord(){if(!this.ttsWordHighlight)return;this.ttsWordHighlight.clear();for(let G of this.ttsWordElementHighlights)G.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.ttsSentenceHighlight)return;this.ttsSentenceHighlight.clear();for(let G of this.ttsSentenceElementHighlights)G.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){this.clearTTSWord(),this.clearTTSSentence()}addAnnotation(G,Q=$7.YELLOW){let Y=`annotation-${this.nextAnnotationId++}`,J=G.cloneRange(),X={id:Y,range:J,type:u.ANNOTATION,color:Q,timestamp:Date.now()};this.annotations.set(Y,X);let j=this.colorHighlights.get(Q);if(j)j.add(J);return Y}removeAnnotation(G){let Q=this.annotations.get(G);if(!Q){console.warn(`[HighlightCoordinator] Annotation ${G} not found`);return}console.log(`[HighlightCoordinator] Removing annotation ${G} (color: ${Q.color})`);let Y=this.colorHighlights.get(Q.color);if(Y){let J=Y.delete(Q.range);console.log("[HighlightCoordinator] Highlight.delete() returned:",J)}this.annotations.delete(G),console.log(`[HighlightCoordinator] Annotation ${G} removed from map. Remaining:`,this.annotations.size)}clearAnnotations(){for(let G of this.colorHighlights.values())G.clear();this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(G){return this.annotations.get(G)??null}changeAnnotationColor(G,Q){let Y=this.annotations.get(G);if(!Y)return;let J=Y.color;if(J===Q)return;let X=this.colorHighlights.get(J);if(X)X.delete(Y.range);Y.color=Q;let j=this.colorHighlights.get(Q);if(j)j.add(Y.range)}exportAnnotations(G=document.body){return this.getAnnotations().map((Q)=>({...this.rangeSerializer.serialize(Q.range,G),id:Q.id,color:Q.color,timestamp:Q.timestamp}))}importAnnotations(G,Q=document.body){let Y=0;for(let J of G){let X=this.rangeSerializer.deserialize(J,Q);if(X)this.addAnnotation(X,J.color),Y++}return Y}highlightRange(G,Q,Y=$7.YELLOW){if(!this.supported)return;switch(Q){case u.TTS_WORD:case u.TTS_SENTENCE:{let J=Q===u.TTS_WORD?this.ttsWordHighlight:this.ttsSentenceHighlight;if(J){if(J.clear(),J.add(G),Q===u.TTS_WORD){for(let X of this.ttsWordElementHighlights)X.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear(),this.highlightTTSWordElementFallbacks([G])}}break}case u.ANNOTATION:this.addAnnotation(G,Y);break}}clearHighlights(G){if(!this.supported)return;switch(G){case u.TTS_WORD:this.clearTTSWord();break;case u.TTS_SENTENCE:this.clearTTSSentence();break;case u.ANNOTATION:this.clearAnnotations();break}}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}isSupported(){return this.supported}updateTTSHighlightStyle(G,Q){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((j)=>{let Z=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(j);return Z?{r:parseInt(Z[1],16),g:parseInt(Z[2],16),b:parseInt(Z[3],16)}:null})(G);if(!X)return;this.explicitTTSColorOverride={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Q))},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations(),this.themeObserver?.disconnect(),this.themeObserver=null}}function N6(G){return(...Q)=>{console.debug(`[${G}]`,...Q)}}var a=N6("ToolCoordinator"),j7;(function(G){G[G.BASE=0]="BASE",G[G.TOOL=1000]="TOOL",G[G.MODAL=2000]="MODAL",G[G.CONTROL=3000]="CONTROL",G[G.HIGHLIGHT=4000]="HIGHLIGHT"})(j7||(j7={}));class X8{config;tools=new Map;layerCounters=new Map;listeners=new Set;visibilityState=new Map;constructor(G={}){this.config=G,this.layerCounters.set(j7.BASE,0),this.layerCounters.set(j7.TOOL,0),this.layerCounters.set(j7.MODAL,0),this.layerCounters.set(j7.CONTROL,0),this.layerCounters.set(j7.HIGHLIGHT,0)}subscribe(G){return this.listeners.add(G),()=>{this.listeners.delete(G)}}notifyListeners(){this.listeners.forEach((G)=>G())}registerTool(G,Q,Y,J=j7.MODAL){if(a("registerTool called:",{id:G,name:Q,hasElement:!!Y,layer:J}),this.tools.has(G)){a(`Tool ${G} is already registered`);return}let X=this.visibilityState.get(G)??!1;if(!Y){this.tools.set(G,{id:G,name:Q,element:null,layer:J,isVisible:X,baseZIndex:J}),a("Tool registered without element:",G);return}let j=J+this.getNextLayerOffset(J);Y.style.zIndex=String(j),Y.style.display=X?"":"none";let Z=()=>this.bringToFront(Y);if(Y.addEventListener("mousedown",Z),this.tools.set(G,{id:G,name:Q,element:Y,layer:J,isVisible:X,baseZIndex:j,mouseDownHandler:Z}),X)this.bringToFront(Y);a("Tool registered with element:",G)}unregisterTool(G){let Q=this.tools.get(G);if(!Q)return;if(Q.element&&Q.mouseDownHandler)Q.element.removeEventListener("mousedown",Q.mouseDownHandler);this.tools.delete(G)}releaseTool(G){this.unregisterTool(G),this.visibilityState.delete(G)}showTool(G){let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found`);return}if(Q.element)Q.element.style.display="",this.bringToFront(Q.element);Q.isVisible=!0,this.visibilityState.set(G,!0),this.notifyListeners()}hideTool(G){let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found`);return}if(Q.element)Q.element.style.display="none";Q.isVisible=!1,this.visibilityState.set(G,!1),this.notifyListeners()}toggleTool(G){a("toggleTool called for:",G);let Q=this.tools.get(G);if(!Q){a(`Tool ${G} not found. Registered tools:`,Array.from(this.tools.keys()));return}if(a("Tool found, current visibility:",Q.isVisible),Q.isVisible)this.hideTool(G);else this.showTool(G)}isToolVisible(G){let Q=this.tools.get(G);if(Q)return Q.isVisible;return this.visibilityState.get(G)??!1}bringToFront(G){let Q=Array.from(this.tools.values()).find((X)=>X.element===G);if(!Q)return;let Y=this.getMaxZIndexInLayer(Q.layer),J=Math.max(Y+1,Q.layer+1);G.style.zIndex=String(J),Q.baseZIndex=J}getRegisteredTools(){return Array.from(this.tools.keys())}getToolElement(G){return this.tools.get(G)?.element??null}getNextLayerOffset(G){let Q=this.layerCounters.get(G)??0;return this.layerCounters.set(G,Q+1),Q}getMaxZIndexInLayer(G){let Q=G;for(let Y of this.tools.values())if(Y.layer===G)Q=Math.max(Q,Y.baseZIndex);return Q}resetZIndices(){for(let G of this.tools.values())if(G.element)G.element.style.zIndex=String(G.baseZIndex)}updateToolElement(G,Q){let Y=this.tools.get(G);if(!Y){a(`Tool ${G} not found`);return}if(Y.element&&Y.mouseDownHandler)Y.element.removeEventListener("mousedown",Y.mouseDownHandler);let J=()=>this.bringToFront(Q);if(Q.addEventListener("mousedown",J),Y.element=Q,Y.mouseDownHandler=J,Q.style.zIndex=String(Y.baseZIndex),Y.isVisible)Q.style.display="";else Q.style.display="none"}hideAllTools(){for(let G of this.tools.keys())this.hideTool(G);this.notifyListeners()}getToolState(G){let Q=this.tools.get(G);if(!Q)return;return{id:Q.id,name:Q.name,isVisible:Q.isVisible,element:Q.element??null,layer:Q.layer}}getVisibleTools(){return Array.from(this.tools.values()).filter((G)=>G.isVisible).map((G)=>({id:G.id,name:G.name,isVisible:G.isVisible,element:G.element??null,layer:G.layer}))}}var S5=/^[a-z][a-z0-9+.-]*:/i,T5=new Set(["http:","https:","data:","blob:"]);function F6(G){return G!==void 0&&G!==1}function C5(G){if(typeof G!=="string")return!1;let Q=G.trim();if(!Q)return!1;if(Q.startsWith("//")||!S5.test(Q))return!0;let Y=Q.slice(0,Q.indexOf(":")+1).toLowerCase();return T5.has(Y)}function M6(G){if(!Array.isArray(G))return[];let Q=[];for(let Y of G){if(!Y||typeof Y!=="object")continue;let J=Y;if(!C5(J.src))continue;let X={src:J.src.trim()};if(typeof J.type==="string"&&J.type.trim())X.type=J.type.trim();if(Number.isFinite(J.width))X.width=J.width;if(Number.isFinite(J.height))X.height=J.height;if(Q.some((j)=>j.src===X.src))continue;Q.push(X)}return Q}function z6(G){if(!G||typeof G!=="object")return;let Q=G,Y=Number(Q.startSeconds);if(!Number.isFinite(Y)||Y<0)return;let J=Number(Q.endSeconds);if(!Number.isFinite(J)||J<=Y)return{startSeconds:Y};return{startSeconds:Y,endSeconds:J}}function O6(G){if(typeof G!=="string")return;return G.trim()||void 0}var y5=100,x5=1;function P6(G,Q,Y){if(!Q)return()=>{};let{startSeconds:J,endSeconds:X}=Q,j;if(J>0)if(j=()=>{if(G.currentTime<J)G.currentTime=J},G.readyState>=x5)j();else G.addEventListener("loadedmetadata",j);let Z,q;if(X!==void 0)Z=()=>{if(G.currentTime>=X)Y()},G.addEventListener("timeupdate",Z),q=setInterval(()=>{if(!G.paused)Z?.()},y5);return()=>{if(j)G.removeEventListener("loadedmetadata",j);if(Z)G.removeEventListener("timeupdate",Z);if(q!==void 0)clearInterval(q)}}function L6(G,Q){if(!Q)return G;if(G.includes("#"))return G;let Y=Q.endSeconds!==void 0?`,${Q.endSeconds}`:"";return`${G}#t=${Q.startSeconds}${Y}`}function w6(G){if(!G)return null;let Q=G.payload;if(!Q||typeof Q!=="object")return null;let Y=Q.media;if(!Y||typeof Y!=="object")return console.warn("[spoken-audio] card carries a `payload` with no `media`; recorded speech needs `media.sources`, so this card is ignored and read-aloud falls back to the script or generated speech"),null;if(F6(Y.version))return console.warn(`[spoken-audio] card's media declares version ${String(Y.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(Y.kind!==void 0&&Y.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${Y.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let J=M6(Y.sources);if(J.length===0)return console.warn("[spoken-audio] card's `media.sources` yielded no usable URL; read-aloud falls back to the script or generated speech"),null;return{sources:J,fragment:z6(Q.fragment),label:O6(Y.label)}}var S7=(G,Q)=>{let Y=Q?.useSentenceSegmenter!==!1;try{if(!Y)throw Error("Segmenter disabled by policy");let q=globalThis.Intl?.Segmenter;if(typeof q==="function"){let B=new q(Q?.locale,{granularity:"sentence"}),K=Array.from(B.segment(G)).map((W)=>({text:W.segment,offset:W.index})).filter((W)=>W.text.trim().length>0);if(K.length>0)return K}}catch{}let J=/[^.!?]+(?:[.!?]+|$)/g,X=G.match(J)||[G],j=[],Z=0;for(let q of X){let B=G.indexOf(q,Z);if(B===-1)continue;j.push({text:q,offset:B}),Z=B+q.length}return j.length>0?j:[{text:G,offset:0}]};var R6=5000,E6=2000,b6=(G)=>String(G||"").trim().toLowerCase(),f5=()=>{let G=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return b6(G||"en-US")},k5=(G,Q)=>{if(Q)return G.find((Z)=>Z.voiceURI===Q)||G.find((Z)=>Z.name===Q)||null;let Y=f5(),J=Y.split("-")[0]||"en",X=(Z)=>{let q=b6(Z.lang);return q===Y||q.startsWith(`${J}-`)},j=[(Z)=>Z.localService&&X(Z),(Z)=>Z.default&&X(Z),(Z)=>X(Z),(Z)=>Z.localService,(Z)=>Z.default];for(let Z of j){let q=G.find(Z);if(q)return q}return G[0]||null},I5=(G)=>!G.default;class T7{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";async initialize(G){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");return new S6(G)}supportsFeature(G){return!0}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class S6{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;settlePendingVoiceWait=null;settlePendingChunk=null;onPlaybackStart=void 0;constructor(G){this.config=G}waitForBrowserVoices(G,Q){return new Promise((Y,J)=>{let X=speechSynthesis,j=typeof X.addEventListener==="function"&&typeof X.removeEventListener==="function",Z=j?null:X.onvoiceschanged,q=!1,B=null,K=null,W=()=>{if(B!==null)clearTimeout(B),B=null;if(j)X.removeEventListener("voiceschanged",N);else if(X.onvoiceschanged===F)X.onvoiceschanged=Z;if(K&&this.settlePendingVoiceWait===K)this.settlePendingVoiceWait=null},$=(O,L)=>{if(q)return;if(q=!0,W(),L)J(L);else Y(O)},H=()=>{if(G!==this.speakRunId){$(!1);return}if(X.getVoices().length>0)$(!0)},N=()=>H(),F=(O)=>{try{Z?.call(X,O)}finally{H()}};if(K=()=>$(!1),this.settlePendingVoiceWait=K,B=setTimeout(()=>$(!1,Error(`Configured browser voice "${Q}" could not be resolved because the browser did not publish its voice inventory within ${E6/1000} seconds.`)),E6),j)X.addEventListener("voiceschanged",N);else X.onvoiceschanged=F;H()})}async resolveBrowserVoice(G){let Q=typeof this.config?.voice==="string"?this.config.voice.trim():"",Y=speechSynthesis.getVoices();if(Q&&Y.length===0){if(!await this.waitForBrowserVoices(G,Q)||G!==this.speakRunId)return{shouldContinue:!1,voice:null};Y=speechSynthesis.getVoices()}if(G!==this.speakRunId)return{shouldContinue:!1,voice:null};let J=k5(Y,Q||void 0);if(Q&&!J)throw Error(`Configured browser voice "${Q}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return{shouldContinue:!0,voice:J}}async speak(G){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId,Y=await this.resolveBrowserVoice(Q);if(!Y.shouldContinue)return;let J=this.splitIntoChunks(G);for(let X of J){if(Q!==this.speakRunId)break;if(!await this.speakChunk(X.text,X.offset,Q,Y.voice))break}}async speakSegments(G){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId,Y=await this.resolveBrowserVoice(Q);if(!Y.shouldContinue)return;for(let J of G){if(Q!==this.speakRunId)break;let X=this.splitIntoChunks(J.text);for(let Z of X){if(Q!==this.speakRunId)break;if(!await this.speakChunk(Z.text,J.startOffset+Z.offset,Q,Y.voice))break}let j=Math.max(0,Number(J.pauseMsAfter||0));if(j>0&&Q===this.speakRunId){if(!await this.waitForPause(j,Q))break}}}async waitForPause(G,Q){return await new Promise((Y)=>setTimeout(Y,G)),Q===this.speakRunId}splitIntoChunks(G){if(G.length<=260)return[{text:G,offset:0}];let Y=this.segmentSentences(G),J=[],X="",j=0;for(let Z of Y){let q=Z.text.trim();if(!q)continue;let B=Z.text.search(/\S/),K=Z.offset+(B===-1?0:B);if(!X){X=q,j=K;continue}let W=`${X} ${q}`;if(W.length<=260)X=W;else J.push({text:X,offset:j}),X=q,j=K}if(X)J.push({text:X,offset:j});return J.length?J:[{text:G,offset:0}]}getHighlightMode(){return(this.config?.providerOptions||{}).highlightMode==="word"?"word":"sentence"}getSegmentationPolicy(){let G=this.config?.providerOptions||{},Q=G.segmenter||{},J=Q.mode!=="regexOnly",X=typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:typeof G.locale==="string"&&G.locale.trim().length>0?G.locale:void 0;return{useSentenceSegmenter:J,useWordSegmenter:J,locale:X}}segmentSentences(G){let Q=this.getSegmentationPolicy();return S7(G,{locale:Q.locale,useSentenceSegmenter:Q.useSentenceSegmenter})}inferWordLength(G,Q){let Y=Math.max(0,Math.min(Q,Math.max(0,G.length-1)));return G.slice(Y).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(G,Q,Y,J){return new Promise((X,j)=>{if(Y!==this.speakRunId){X(!1);return}let Z=new SpeechSynthesisUtterance(G);if(this.utterance=Z,J&&I5(J))Z.voice=J;if(this.config?.rate)Z.rate=this.config.rate;if(this.config?.pitch)Z.pitch=this.config.pitch;let q=!1,B=!1,K=null,W=null,$=()=>{if(this.utterance===Z)this.utterance=null},H=()=>{if(K!==null)clearTimeout(K),K=null},N=()=>{Z.onstart=null,Z.onend=null,Z.onerror=null,Z.onpause=null,Z.onresume=null,Z.onboundary=null},F=(L,D)=>{if(B)return;if(B=!0,H(),N(),$(),W&&this.settlePendingChunk===W)this.settlePendingChunk=null;if(Y===this.speakRunId)this._isPlaying=!1,this._isPaused=!1;if(D)j(D);else X(L)},O=(L)=>Error(L==="ended"?"Browser speech synthesis ended before audio started. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.":`Browser speech synthesis did not start within ${R6/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);W=()=>F(!1),this.settlePendingChunk=W,Z.onstart=()=>{if(Y!==this.speakRunId){F(!1);return}q=!0,H(),this._isPlaying=!0,this._isPaused=!1;try{this.onPlaybackStart?.()}catch(L){console.error("Browser TTS playback-start callback failed",L)}},Z.onend=()=>{if(Y!==this.speakRunId){F(!1);return}if(!q){F(!1,O("ended"));return}F(!0)},Z.onerror=(L)=>{if(Y!==this.speakRunId){F(!1);return}if(L.error==="interrupted"||L.error==="canceled"){F(!1);return}F(!1,Error(`Speech synthesis error: ${L.error}`))},Z.onpause=()=>{if(Y!==this.speakRunId)return;this._isPaused=!0},Z.onresume=()=>{if(Y!==this.speakRunId)return;this._isPaused=!1},Z.onboundary=(L)=>{if(Y!==this.speakRunId)return;if(console.log("[BrowserProvider] Boundary event:",L.name,"charIndex:",L.charIndex,"charLength:",L.charLength),L.name!=="word"||!this.onWordBoundary)return;if(this.getHighlightMode()==="sentence")return;let D=Math.max(0,Math.min(L.charIndex,Math.max(0,G.length-1))),P=Number(L.charLength||0),S=this.inferWordLength(G,D),v=Number.isFinite(P)&&P>0&&P<=80&&D+P<=G.length?P:S,I=G.substring(D,Math.min(G.length,D+v)).trim(),p=Q+D;console.log("[BrowserProvider] Calling onWordBoundary with word:",I,"at position:",p),this.onWordBoundary(I,p,v)},K=setTimeout(()=>{if(B||q||Y!==this.speakRunId)return;F(!1,O("timedOut")),speechSynthesis.cancel()},R6);try{speechSynthesis.speak(Z)}catch(L){F(!1,L instanceof Error?L:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPlaying&&!this._isPaused)speechSynthesis.pause()}resume(){if(this._isPlaying&&this._isPaused)speechSynthesis.resume()}stop(){let G=this.utterance,Q=this._isPlaying||G!==null;if(this.speakRunId+=1,this.settlePendingVoiceWait?.(),this.settlePendingChunk?.(),Q)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}updateSettings(G){if(!this.config)this.config={};if(G.rate!==void 0)this.config.rate=G.rate;if(G.pitch!==void 0)this.config.pitch=G.pitch;if(G.voice!==void 0)this.config.voice=G.voice;if(G.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...G.providerOptions||{}}}onWordBoundary}var T=(G)=>G.trim().replace(/\s+/g," "),U1=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,Z8=(G)=>{if(G.hidden)return!0;if(G.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(G.getAttribute("aria-hidden")==="true")return!0;if(G.hasAttribute("inert"))return!0;let Q=G.classList;if(Q?.contains("sr-only")||Q?.contains("pie-sr-only")||Q?.contains("visually-hidden"))return!0;if(typeof window<"u"){let Y=window.getComputedStyle(G);if(Y.display==="none"||Y.visibility==="hidden")return!0;let J=Number.parseFloat(Y.width||"0"),X=Number.parseFloat(Y.height||"0"),j=Number.isFinite(J)&&Number.isFinite(X)&&J<=1&&X<=1,Z=Y.clipPath.includes("inset(50%")||Y.clipPath.includes("inset(100%")||Y.clip.includes("rect(0px, 0px, 0px, 0px)")||Y.clip.includes("rect(0 0 0 0)");if((Y.position==="absolute"||Y.position==="fixed")&&j&&(Y.overflow==="hidden"||Z))return!0;if(Y.opacity==="0"&&j)return!0}return!1},B1=(G,Q)=>{let Y=G.nodeType===1?G:G.parentElement;while(Y){if(Z8(Y))return!0;if(Q&&Y===Q)break;Y=Y.parentElement}return!1};var y6=new Set(["computer-read-aloud","all"]),T6=new Set([...y6,"screen-reader"]),C6=new Set,v5=(G)=>{let Q=G.getAttribute?.("data-tts-suppress");if(Q===null||Q===void 0)return!1;let Y=Q.trim().toLowerCase();if(y6.has(Y))return!0;if(T6.has(Y))return!1;if(!C6.has(Y))C6.add(Y),console.warn(`[tts] data-tts-suppress="${Q}" is not one of ${Array.from(T6).join(", ")}; suppressing read-aloud for this content anyway, because a suppression attribute that fails open would leak the answer to items where reading is the construct. Correct the value to silence this.`);return!0},W1=(G,Q)=>{let Y=G.nodeType===1?G:G.parentElement;while(Y){if(v5(Y))return!0;if(Q&&Y===Q)break;Y=Y.parentElement}return!1},H7=(G,Q)=>B1(G,Q)||W1(G),j8=(G,Q)=>{if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u"||typeof G.intersectsNode!=="function")return{text:G.toString(),filtered:!1};let Y=[],J=!1,X=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),j=X.nextNode();while(j){let Z=j;if(G.intersectsNode(Z))if(H7(Z,Q))J=!0;else{let q=Z.textContent||"",B=Z===G.startContainer?G.startOffset:0,K=Z===G.endContainer?G.endOffset:q.length;Y.push(q.slice(B,K))}j=X.nextNode()}return{text:Y.join(""),filtered:J}},q8=(G,Q,Y)=>{if(!G||!Q)return!1;if(/\s/.test(G)||/\s/.test(Q))return!1;let J=Y?.boundarySpacingMode??"segmenterPreferred";if(J==="none")return!1;if(J==="segmenterPreferred")try{let Z=globalThis.Intl?.Segmenter;if(typeof Z==="function"){let q=new Z(Y?.locale,{granularity:"word"});if(Array.from(q.segment(`${G}${Q}`)).filter((W)=>W.isWordLike!==!1&&W.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(G),j=/[A-Za-z0-9]/.test(Q);return X&&j},C7=(G,Q)=>{let Y=new Map;if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u")return{text:"",map:Y};let J=[],X=0,j=!0,Z=!1,q=null,B=null,K=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),W=K.nextNode();while(W){let H=W;if(H.parentElement&&!H7(H,G)){let F=H.textContent||"",O=F.match(/\S/),L=O?O[0]:null;if(!j&&!Z&&q8(B,L,Q)){if(J.push(" "),q)Y.set(X,q);X++,Z=!0}for(let D=0;D<F.length;D++){let P=F[D],S=/\s/.test(P);if(j){if(!S)j=!1,J.push(P),Y.set(X,{node:H,offset:D}),q={node:H,offset:D},X++,Z=!1,B=P}else if(S){if(!Z)J.push(" "),Y.set(X,{node:H,offset:D}),q={node:H,offset:D},X++;Z=!0}else J.push(P),Y.set(X,{node:H,offset:D}),q={node:H,offset:D},X++,Z=!1,B=P}}W=K.nextNode()}let $=J.join("").trimEnd();while(Y.has($.length))Y.delete($.length);return{text:$,map:Y}};var h5=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),x6=new Set(["audio","phoneme"]),k6=(G)=>G.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),K1=(G,Q,Y)=>{for(let J=0;J<Q.length;J++)G.push({char:Q[J],rawOffset:Y===null?null:Y+J})},m5=(G,Q,Y)=>{let J=Q.slice(Y).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!J)return 0;return K1(G,k6(J[0]),Y),J[0].length},f6=(G)=>{G.push({char:" ",rawOffset:null})},u5=(G)=>{let Q=new Map,Y=[],J=!0;for(let X of G){if(/\s/.test(X.char)){if(!J&&Y.length>0){if(Y.push(" "),X.rawOffset!==null)Q.set(X.rawOffset,Y.length-1)}J=!0;continue}if(Y.push(X.char),X.rawOffset!==null)Q.set(X.rawOffset,Y.length-1);J=!1}while(Y.length>0&&Y[Y.length-1]===" ")Y.pop();for(let[X,j]of Q)if(j>=Y.length)Q.delete(X);return{text:Y.join(""),rawToSpokenOffsetMap:Q}},p5=(G)=>{return G.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},g5=(G,Q)=>{let Y=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),J=G.match(Y);return k6(J?.[2]??J?.[3]??"")||null},_1=(G)=>{let Q=[],Y=!1,J=!1,X=0;while(X<G.length){let Z=G[X];if(Z!=="<"){if(Z==="&"){let H=m5(Q,G,X);if(H>0){X+=H;continue}}K1(Q,Z,X),X++;continue}let q=G.indexOf(">",X+1);if(q<0){K1(Q,Z,X),X++;continue}J=!0;let B=G.slice(X,q+1),K=p5(B),W=/^<\s*\//.test(B),$=/\/\s*>$/.test(B);if(!W&&K==="sub"){let H=g5(B,"alias");if(!H){Y=!0,X=q+1;continue}K1(Q,H,null);let N=G.toLowerCase().indexOf("</sub>",q+1);X=N>=0?N+6:q+1;continue}if(!W&&K==="break"){f6(Q),X=q+1;continue}if(!W&&x6.has(K)){if(Y=!0,$){X=q+1;continue}}if(K&&!h5.has(K)&&!x6.has(K)&&K!=="break"&&K!=="sub")Y=!0;if(!W&&(K==="p"||K==="s"))f6(Q);X=q+1}let j=u5(Q);return{spokenText:T(j.text),rawToSpokenOffsetMap:j.rawToSpokenOffsetMap,unsupportedSemantic:Y,hasMarkup:J}};var c5=U1(),u6=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),l5=[{phrase:["plus","or","minus"],visible:"±",score:8},{phrase:["square","root"],visible:"√",score:8},{phrase:["divided","by"],visible:"/",score:7},{phrase:["all","over"],visible:"/",score:7},{phrase:["equals"],visible:"=",score:7},{phrase:["equal"],visible:"=",score:7},{phrase:["times"],visible:"",score:7},{phrase:["multiplied","by"],visible:"",score:7},{phrase:["over"],visible:"/",score:6},{phrase:["squared"],visible:"²",score:6},{phrase:["squared"],visible:"2",score:4},{phrase:["negative"],visible:"-",score:5},{phrase:["minus"],visible:"-",score:5},{phrase:["plus"],visible:"+",score:5}],U8=(G)=>{let Q=[];for(let Y of G.matchAll(c5)){let J=Y[0],X=Y.index??0;Q.push({text:J,normalized:J.toLowerCase(),start:X,end:X+J.length})}return Q},B8=(G)=>u6.get(G.normalized)||G.normalized,d5=(G,Q)=>{let Y=[];for(let J=0;J<G.length;J++){for(let X=0;X<Q.length;X++){let j=B8(G[J]),Z=B8(Q[X]);if(j===Z)Y.push({spokenStartToken:J,spokenEndToken:J+1,visibleToken:X,score:10})}for(let X of l5){let j=G.slice(J,J+X.phrase.length);if(j.length!==X.phrase.length)continue;if(!j.every((Z,q)=>Z.normalized===X.phrase[q]))continue;for(let Z=0;Z<Q.length;Z++){if(Q[Z].normalized!==X.visible)continue;Y.push({spokenStartToken:J,spokenEndToken:J+X.phrase.length,visibleToken:Z,score:X.score})}}}return Y},i5=(G,Q)=>{let Y=d5(G,Q).sort((B,K)=>G[B.spokenStartToken].start-G[K.spokenStartToken].start||Q[B.visibleToken].start-Q[K.visibleToken].start),J=Array(Y.length).fill(0),X=Array(Y.length).fill(-1);for(let B=0;B<Y.length;B++){let K=Y[B];J[B]=K.score;for(let W=0;W<B;W++){let $=Y[W];if($.spokenEndToken<=K.spokenStartToken&&$.visibleToken<K.visibleToken){let H=K.spokenStartToken-$.spokenEndToken,N=K.visibleToken-$.visibleToken-1,F=Math.max(0,Math.abs(H-N)-2),O=J[W]+K.score-F;if(O>J[B])J[B]=O,X[B]=W}}}let j=-1;for(let B=0;B<J.length;B++)if(j<0||J[B]>J[j])j=B;if(j<0)return[];let Z=[],q=j;while(q>=0)Z.unshift(Y[q]),q=X[q];return Z.map((B)=>{let K=G[B.spokenStartToken],W=G[B.spokenEndToken-1],$=Q[B.visibleToken];return{spokenStart:K.start,spokenEnd:W.end,visibleStart:$.start,visibleEnd:$.end,score:B.score}})},s5=(G,Q,Y)=>{if(G.length===0)return 0;let J=G.length/Math.max(1,Math.min(Q.length,Y.length)),X=G.reduce((j,Z)=>j+Z.score,0)/G.length/10;return Math.min(1,J*X)},V1=(G)=>{let Q=_1(G.speechText),Y=T(G.visibleText),J=Q.spokenText,X=U8(J),j=U8(Y),Z=Q.unsupportedSemantic?[]:i5(X,j),q=s5(Z,X,j),B=J===Y&&J.length>0,K=Z.length===1&&Z[0].score===10&&X.length<=2&&j.length<=2,W=Q.unsupportedSemantic?"region-fallback":B?"exact-word":Z.length>=2||K?q>=0.12?"anchor-span":"region-fallback":"region-fallback",$=Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text";return{speechText:G.speechText,spokenText:J,visibleText:Y,playbackMode:W,boundaryOffsetMode:$,anchors:Z,confidence:q,spokenTokens:X,visibleTokens:j,rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap}},W8=(G,Q)=>G.find((Y)=>Y.start<=Q&&Q<Y.end)||null,p6=(G)=>{if(!G)return null;if(/^<[^>]+>$/.test(G.trim()))return null;let Q=U8(G)[0];if(!Q)return null;return u6.get(Q.normalized)||Q.normalized},I6=(G,Q,Y)=>{let J=p6(Y);if(!Q||!J)return!1;let X=W8(G.spokenTokens,Q.start);if(!X)return!1;return B8(X)===J},v6=(G,Q)=>{let Y=G.rawToSpokenOffsetMap.get(Q);if(Y!==void 0)return Y;for(let J=Q;J<G.speechText.length;J++){let X=G.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(G.speechText[J]===">")break}return null},h6=(G,Q,Y)=>{let J=v6(G,Q);if(J===null)return null;let X=v6(G,Math.max(Q,Q+Y-1)),j=W8(G.spokenTokens,J),Z=X!==null&&X>=J?X-J+1:j?j.end-J:Y;return{start:J,length:Math.max(1,Z)}},m6=(G,Q,Y)=>{if(Q<0||Q>=G.spokenText.length)return null;let J=W8(G.spokenTokens,Q);if(!J)return null;return{start:Q,length:Math.min(Y,J.end-Q)}},g6=(G,Q,Y=1,J)=>{if(G.boundaryOffsetMode==="unsupported"||!Number.isFinite(Q))return null;let X=Math.max(1,Number.isFinite(Y)?Y:1);if(J&&/^<[^>]+>$/.test(J.trim()))return null;if(G.boundaryOffsetMode==="raw-ssml"){let j=h6(G,Q,X),Z=m6(G,Q,X);if(J){if(I6(G,j,J))return j;if(I6(G,Z,J))return Z;if(p6(J))return null}return j||Z}return m6(G,Q,X)||h6(G,Q,X)},c6=(G,Q)=>{if(G.playbackMode==="region-fallback")return null;let Y=G.anchors.find((j)=>j.spokenStart<=Q&&Q<j.spokenEnd);if(Y)return{start:Y.visibleStart,end:Y.visibleEnd};let J=null,X=null;for(let j of G.anchors){if(j.spokenEnd<=Q){J=j;continue}if(j.spokenStart>Q){X=j;break}}if(J&&X)return{start:Math.min(J.visibleStart,X.visibleStart),end:Math.max(J.visibleEnd,X.visibleEnd)};return null};var n5=new Map([["+",["plus"]],["-",["minus","negative"]],["−",["minus","negative"]],["×",["times","multiplied by"]],["÷",["divided by"]],["=",["equals","equal to"]],["≠",["is not equal to","not equal to"]],["≈",["approximately equals"]],["≤",["less than or equal to"]],["≥",["greater than or equal to"]],["<",["less than"]],[">",["greater than"]],["∠",["angle"]],["△",["triangle"]],["□",["box"]],["○",["circle"]],["°",["degrees","degree"]],["%",["percent"]],["'",["prime"]],["′",["prime"]],["•",["times"]],["·",["times"]],["",["times","multiplied by"]]]),r5=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),l6=new Map([["2",["squared"]],["3",["cubed"]]]),o5=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),a5=(G)=>G.replace(/\s+/g," ").trim(),D7=(G)=>(G.localName||G.tagName||"").toLowerCase(),t5=(G)=>G.nodeType===Node.ELEMENT_NODE,y7=(G)=>Array.from(G.childNodes).filter(t5),K8=(G)=>a5(G.textContent||""),Q7=(G,Q)=>({type:"element-range",quality:Q,element:G}),e5=(G)=>{switch(G){case"mi":return"identifier";case"mn":return"number";case"mo":return"operator";case"mtext":case"ms":return"text";case"mspace":return"space";default:return"unknown"}},GG=(G,Q)=>{if(Q==="operator"){if(G==="−")return"-";return G}return G.toLowerCase()},QG=(G,Q,Y)=>{if(Y==="fraction")return["over","divided by"];if(Y==="superscript")return l6.get(G)??[];if(G==="|")return["absolute value"];if(Q==="operator")return n5.get(G)||[];return[]},A7=(G)=>{let Q=G.normalized??GG(G.text,G.kind||"unknown");return{id:`math-token-${G.state.nextId++}`,kind:G.kind,role:G.role,text:G.text,normalized:Q,spokenAliases:QG(G.text,G.kind,G.role),sourceElement:G.sourceElement,path:G.path,target:G.target||Q7(G.sourceElement,"element-range"),optional:G.optional}},N7=(G,Q,Y="tokens")=>{G[Y].push(Q)},d6=(G,Q,Y)=>{y7(G).forEach((J,X)=>Y7(J,Q,`${Y}/${D7(J)}[${X}]`))},YG=(G,Q,Y)=>{let J=y7(G);if(J[0])Y7(J[0],Q,`${Y}/numerator`);if(N7(Q,A7({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:G,path:Y,target:Q7(G,"element-range")})),J[1])Y7(J[1],Q,`${Y}/denominator`)},JG=(G,Q,Y)=>{let J=G.getAttribute("open")||"(",X=G.getAttribute("close")||")";N7(Q,A7({state:Q,kind:"operator",role:J==="|"?"absolute-value-fence":"open-fence",text:J,sourceElement:G,path:`${Y}/open`,target:Q7(G,"element-range")})),d6(G,Q,Y),N7(Q,A7({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:G,path:`${Y}/close`,target:Q7(G,"element-range")}))},XG=(G,Q,Y)=>{let J=y7(G);if(J[0])Y7(J[0],Q,`${Y}/base`);let X=J[1];if(!X)return;let j=K8(X);if(l6.has(j)){N7(Q,A7({state:Q,kind:"structure",role:"superscript",text:j,normalized:j,sourceElement:X,path:`${Y}/exponent`,target:Q7(G,"element-range")}));return}Y7(X,Q,`${Y}/exponent`)},ZG=(G,Q,Y,J)=>{N7(Q,A7({state:Q,kind:"structure",role:J,text:K8(G)||J,normalized:`\x00${J}`,sourceElement:G,path:Y,target:Q7(G,"element-range")}))},jG=(G,Q,Y)=>{let J=0;for(let X of y7(G)){if(D7(X)==="mtr"||D7(X)==="mlabeledtr")J++,N7(Q,A7({state:Q,kind:"layout",role:"table-row",text:`row-${J}`,normalized:`row-${J}`,sourceElement:X,path:`${Y}/row[${J}]`,target:Q7(X,"region-fallback")}),"layoutTargets");Y7(X,Q,`${Y}/${D7(X)}[${J}]`)}},qG=(G,Q,Y)=>{let J=K8(G);if(!J)return;let X=e5(D7(G)),j=X==="operator"?r5.get(J):void 0,Z=j??(X==="operator"&&(J==="("||J===")")?"grouping-fence":X);N7(Q,A7({state:Q,kind:X,role:Z,text:J,sourceElement:G,path:Y,target:j&&G.parentElement?Q7(G.parentElement,"region-fallback"):void 0,optional:Boolean(j)||Z==="grouping-fence"}))},Y7=(G,Q,Y)=>{let J=D7(G);switch(J){case"annotation":case"annotation-xml":return;case"semantics":{let X=y7(G).find((j)=>{let Z=D7(j);return Z!=="annotation"&&Z!=="annotation-xml"});if(X)Y7(X,Q,`${Y}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":qG(G,Q,Y);return;case"mfrac":YG(G,Q,Y);return;case"msup":XG(G,Q,Y);return;case"mfenced":JG(G,Q,Y);return;case"mtable":jG(G,Q,Y);return;case"mphantom":return;case"maction":{let X=y7(G)[0];if(X)Y7(X,Q,`${Y}/action`);return}default:{let X=o5.get(J);if(X){ZG(G,Q,Y,X);return}d6(G,Q,Y)}}},i6=(G)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return Y7(G,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:Q7(G,"region-fallback")}};var s6=(G)=>{if(!G.boundary)return null;return G.alignment.segments.find((Y)=>Y.speechTokenIds.includes(G.boundary.token.id))?.target||null};var UG=(G)=>{let Q=[],Y=new Set,J=(X)=>{let j=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(j.length===0)return;let Z=j.join(" ");if(Y.has(Z))return;Y.add(Z),Q.push(j)};J(G.normalized);for(let X of G.spokenAliases)J(X);return Q},n6=(G,Q,Y)=>{let J=0;for(let X of Y){if(X.length<=J)continue;let j=!0;for(let Z=0;Z<X.length;Z++){let q=G[Q+Z];if(!q||q.normalized.toLowerCase()!==X[Z]){j=!1;break}}if(j)J=X.length}return J},BG=(G,Q)=>{let Y=[],J=0;for(let X of Q){let j=UG(X);if(X.optional){let Z=n6(G,J,j);if(Z>0)Y.push({speechTokens:G.slice(J,J+Z),math:X}),J+=Z;continue}while(J<G.length){let Z=n6(G,J,j);if(Z>0){Y.push({speechTokens:G.slice(J,J+Z),math:X}),J+=Z;break}J++}}return Y},WG=(G,Q,Y)=>{let J=Y.filter((Z)=>!Z.optional).length,X=G.filter((Z)=>!Z.math.optional).length,j=G.reduce((Z,q)=>Z+q.speechTokens.length,0);return J>0&&X===J&&j===Q.length},KG=(G)=>G.map(({speechTokens:Q,math:Y})=>({speechTokenIds:Q.map((J)=>J.id),mathTokenIds:[Y.id],score:1,confidence:1,target:Y.target})),r6=(G)=>{let Q=G.minExactWordConfidence??0.95,Y=BG(G.speech.tokens,G.math.tokens),J=WG(Y,G.speech.tokens,G.math.tokens)?1:0;return{segments:J>=Q?KG(Y):[],confidence:J,fallbackTarget:G.math.expressionTarget}};var o6=U1(),_G=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),a6=(G)=>{let Q=G.toLowerCase();return _G.get(Q)||Q},VG=(G)=>{let Q=[];for(let Y of G.matchAll(o6)){let J=Y[0],X=Y.index??0;Q.push({id:`speech-token-${Q.length}`,text:J,normalized:a6(J),start:X,end:X+J.length,sourceStart:X,sourceEnd:X+J.length,coordinateSystem:"normalized-speech"})}return Q},F7=(G)=>{let Q=_1(G.speechText);return{speechText:G.speechText,spokenText:Q.spokenText,tokens:VG(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},$8=(G)=>{if(!G)return null;if(/^<[^>]+>$/.test(G.trim()))return null;let Q=G.match(o6);if(!Q?.[0])return null;return a6(Q[0])},$G=(G,Q)=>G.find((Y)=>Y.start<=Q&&Q<Y.end)||null,HG=(G,Q)=>{let Y=G.rawToSpokenOffsetMap.get(Q);if(Y!==void 0)return Y;for(let J=Q;J<G.speechText.length;J++){let X=G.rawToSpokenOffsetMap.get(J);if(X!==void 0)return X;if(G.speechText[J]===">")break}return null},_8=(G,Q,Y)=>{if(Q===null)return null;let J=$G(G.tokens,Q);if(!J)return null;return{token:J,start:Q,length:Math.max(1,Math.min(Y,J.end-Q)),confidence:0.75}},V8=(G,Q)=>{let Y=$8(Q);return Boolean(G&&Y&&G.token.normalized===Y)},H8=(G)=>{if(G.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(G.position)||G.boundaryWord&&/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Q=Math.max(1,Number.isFinite(G.length)?G.length:1),Y=_8(G.tokenization,HG(G.tokenization,G.position),Q),J=_8(G.tokenization,G.position>=0&&G.position<G.tokenization.spokenText.length?G.position:null,Q);if(V8(Y,G.boundaryWord))return{...Y,confidence:1};if(V8(J,G.boundaryWord))return{...J,confidence:1};if(G.boundaryWord&&$8(G.boundaryWord))return null;return G.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||J:J||Y},t6=(G)=>{if(G.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(G.position)||G.boundaryWord&&/^<[^>]+>$/.test(G.boundaryWord.trim()))return null;let Q=Math.max(1,Number.isFinite(G.length)?G.length:1),Y=_8(G.tokenization,G.position>=0&&G.position<G.tokenization.spokenText.length?G.position:null,Q);if(V8(Y,G.boundaryWord))return{...Y,confidence:1};if(G.boundaryWord&&$8(G.boundaryWord))return null;return Y};var x7=(G)=>{let Q=F7({speechText:G.speechText}),Y=i6(G.mathElement);return{speech:Q,math:Y,result:r6({speech:Q,math:Y})}};var e6=(G,Q)=>{let Y=t6({tokenization:G.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return s6({alignment:G.result,boundary:Y})},G0=(G,Q)=>{if(!Q.boundaryWord||/^<[^>]+>$/.test(Q.boundaryWord.trim()))return null;let Y=F7({speechText:Q.boundaryWord}).tokens[0];if(!Y)return null;let J=G.math.tokens.filter((X)=>{let j=Y.normalized.toLowerCase();return X.normalized.toLowerCase()===j||X.spokenAliases.some((Z)=>Z.toLowerCase()===j)});return J.length===1?J[0].target:null};var DG=new Set(["math","maction","menclose","merror","mfenced","mfrac","mi","mmultiscripts","mn","mo","mover","mpadded","mphantom","mprescripts","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msubsup","msup","mtable","mtd","mtext","mtr","munder","munderover","none","semantics","annotation","annotation-xml"]),AG=new Set(["accent","accentunder","align","bevelled","class","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","encoding","fence","height","href","id","largeop","length","linethickness","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","width","xmlns","xml:lang"]),Q0=(G)=>G.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),NG=(G)=>Q0(G).replace(/"/g,"""),FG=(G,Q)=>{let Y=G.toLowerCase(),J=Q.trim().toLowerCase();if(Y.startsWith("on"))return!0;if(!AG.has(Y))return!0;if(J.includes("javascript:"))return!0;if(J.includes("data:text/html"))return!0;return!1},MG=(G)=>{let Q=G.localName.toLowerCase();if(!DG.has(Q))return!1;let Y=G.namespaceURI;return!Y||Y==="http://www.w3.org/1998/Math/MathML"||Y==="http://www.w3.org/1999/xhtml"},Y0=(G)=>{if(G.nodeType===Node.TEXT_NODE)return Q0(G.textContent||"");if(G.nodeType===Node.COMMENT_NODE)return"";if(G.nodeType!==Node.ELEMENT_NODE)return null;let Q=G;if(!MG(Q))return null;let Y=Q.localName.toLowerCase(),J=[];for(let Z of Array.from(Q.attributes)){let q=Z.name.toLowerCase();if(FG(q,Z.value))continue;if(q==="xmlns"&&Z.value!=="http://www.w3.org/1998/Math/MathML")return null;J.push(`${q}="${NG(Z.value)}"`)}if(Y==="math"&&!J.some((Z)=>Z.startsWith("xmlns=")))J.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let Z of Array.from(Q.childNodes)){let q=Y0(Z);if(q===null)return null;X.push(q)}let j=J.length>0?` ${J.join(" ")}`:"";return`<${Y}${j}>${X.join("")}</${Y}>`},zG=(G)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(G,"application/xml");return null},$1=(G)=>{let Q=String(G||"").trim();if(!Q)return null;let Y=zG(Q);if(!Y)return null;if(Y.getElementsByTagName("parsererror").length>0)return null;let J=Y.documentElement;if(!J||J.localName.toLowerCase()!=="math")return null;return Y0(J)};var J0=(G)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:G}),X0=(G)=>G.classList?.contains("MathJax")||G.tagName?.toLowerCase()==="mjx-container",Z0=(G)=>G.tagName?.toLowerCase()==="mjx-assistive-mml",j0=(G)=>{let Q=G.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},OG=(G)=>{let Q=G.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},PG=(G)=>{return G.querySelector("mjx-assistive-mml math")?.outerHTML||null},LG=(G)=>{if(G.tagName.toLowerCase()==="math")return $1(G.outerHTML);let Q=OG(G);if(Q){let Y=$1(Q);if(Y)return Y}if(X0(G)){let Y=PG(G);if(Y){let J=$1(Y);if(J)return J}}return null};var wG=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),RG=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),EG=(G,Q)=>{let Y=G.parentElement,J=null;while(Y&&Y!==Q){let X=(Y.getAttribute("role")||"").toLowerCase(),j=Y.tagName.toUpperCase();if(wG.has(j)||RG.has(X)){J=Y;break}Y=Y.parentElement}return J||Q},bG=(G)=>Boolean(typeof G.querySelector==="function"&&G.querySelector("math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||G.tagName?.toLowerCase()==="math"||G.hasAttribute?.("data-mathml")||X0(G),M7=(G,Q,Y)=>{if(/[.,;:!?]/.test(Q)&&G.chars.length>0&&G.chars[G.chars.length-1]===" ")G.chars.pop(),G.position--,G.map.delete(G.position);if(G.chars.push(Q),Y)G.map.set(G.position,Y),G.lastMapped=Y;else if(G.lastMapped)G.map.set(G.position,G.lastMapped);G.position++},q0=(G,Q)=>{if(G.inLeadingWhitespace||G.lastCharWasWhitespace||G.chars.length===0)return!1;let Y=G.chars[G.chars.length-1];return q8(Y,Q,G.options)},U0=(G,Q)=>{let Y=Q.textContent||"",J=!1;for(let X=0;X<Y.length;X++){let j=Y[X],Z=/\s/.test(j);if(G.inLeadingWhitespace){if(!Z)G.inLeadingWhitespace=!1,M7(G,j,{node:Q,offset:X}),J=!0,G.lastCharWasWhitespace=!1;continue}if(Z){if(!G.lastCharWasWhitespace)M7(G," ",{node:Q,offset:X});G.lastCharWasWhitespace=!0;continue}if(!J&&q0(G,j))M7(G," ",{node:Q,offset:X});M7(G,j,{node:Q,offset:X}),J=!0,G.lastCharWasWhitespace=!1}},SG=(G,Q)=>{for(let Y=0;Y<Q.text.length;Y++){let J=Q.text[Y],X=/\s/.test(J),j=Q.map.get(Y)||null,Z=j?.node||G.lastMapped?.node||null,q=j?.offset??G.lastMapped?.offset??0,B=j?{node:j.node,offset:j.offset}:Z?{node:Z,offset:q}:null;if(G.inLeadingWhitespace){if(X)continue;G.inLeadingWhitespace=!1}if(X){if(!G.lastCharWasWhitespace)M7(G," ",B);G.lastCharWasWhitespace=!0;continue}if(Y===0&&q0(G,J))M7(G," ",B);if(M7(G,J,B),G.lastCharWasWhitespace=!1,j)G.map.set(G.position-1,{node:j.node,offset:j.offset}),G.lastMapped={node:j.node,offset:j.offset};else if(Z)G.map.set(G.position-1,{node:Z,offset:q})}},TG=(G)=>{if(typeof DOMParser>"u")return"";let Q=new DOMParser().parseFromString(G,"application/xml");if(Q.getElementsByTagName("parsererror").length>0)return"";let Y=[],J=(X)=>{if(X.nodeType===3){let Z=X.textContent||"";if(Z.trim())Y.push(Z);return}if(X.nodeType!==1)return;let j=X;if(j0(j))return;for(let Z of Array.from(j.childNodes))J(Z)};return J(Q.documentElement),T(Y.join(" "))},CG=(G,Q,Y)=>{let J=J0(Y),X=(q)=>{if(H7(q,G))return;if(q.nodeType===3){U0(J,q);return}if(q.nodeType!==1)return;let B=q;if(Z0(B)||j0(B))return;for(let K of Array.from(B.childNodes))X(K)};X(G),B0(J);let j=T(J.chars.join(""));if(j)return{text:j,map:J.map};let Z=TG(Q);if(!Z)return C7(G,Y);return{text:Z,map:new Map}},B0=(G)=>{while(G.chars.length>0&&/\s/.test(G.chars[G.chars.length-1]))G.chars.pop(),G.position--,G.map.delete(G.position)},yG=(G,Q)=>{let Y=J0(Q),J=[],X=0,j,Z=!1,q=()=>{let W=T(Y.chars.slice(X,Y.chars.length).join(""));if(W)J.push({type:"text",text:W,sourceElement:j});X=Y.chars.length,j=void 0},B=(W)=>{if(H7(W,G))return;if(W.nodeType===Node.TEXT_NODE){let N=EG(W,G);if(j&&N!==j)q();j=N,U0(Y,W);return}if(W.nodeType!==Node.ELEMENT_NODE)return;let $=W;if(Z0($))return;let H=LG($);if(H){q();let N=CG($,H,Q);SG(Y,N);let F=T(N.text);J.push({type:"math",mathml:H,fallbackText:F,sourceElement:$}),X=Y.chars.length,Z=!0;return}for(let N of Array.from($.childNodes))B(N)};for(let W of Array.from(G.childNodes))B(W);B0(Y),q();let K=Y.chars.join("");while(Y.map.has(K.length))Y.map.delete(K.length);return{visibleText:K,map:Y.map,chunks:J,containsMathMarkup:Z}},z7=(G,Q)=>{if(!bG(G)){let{text:Y,map:J}=C7(G,Q);return{visibleText:Y,map:J,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return yG(G,Q)};var D8=null,W0=Promise.resolve(),fG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",kG=async()=>{if(!D8)D8=import("speech-rule-engine").then((G)=>{let Q=G.default||G;if(!Q||typeof Q.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Q});return D8},IG=(G)=>G==="en"?"clearspeak":"mathspeak",K0=(G)=>!!G&&typeof G==="object"&&!Array.isArray(G),_0=(G)=>typeof G==="string"&&G.trim()?G.trim():void 0,O7=(G)=>{if(!K0(G))return;let Q=_0(G.domain),Y=_0(G.style),J=K0(G.engineOptions)?G.engineOptions:void 0;if(!Q&&!Y&&!J)return;return{...Q?{domain:Q}:{},...Y?{style:Y}:{},...J?{engineOptions:J}:{}}},vG=async(G,Q,Y,J)=>{let X=fG(Q),j=O7(J);await G.setupEngine?.({...j?.engineOptions||{},locale:X,domain:j?.domain||IG(X),...j?.style?{style:j.style}:{},modality:"speech",markup:Y}),await G.engineReady?.()},hG=async(G)=>{let Q=W0.then(G,G);return W0=Q.then(()=>{return},()=>{return}),Q},V0=async(G,Q,Y,J,X)=>hG(async()=>{return await vG(G,Y,J,X),G.toSpeech(Q)}),mG=(G)=>G.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),uG=async(G,Q,Y,J)=>{try{let X=mG(await V0(G,Q,Y,"ssml",J));return X.includes("<speak")?X:null}catch(X){return console.debug("[TTSService] Math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},H1=async(G,Q={})=>{if(!G.some((K)=>K.type==="math"))return{speechText:T(G.map((K)=>K.type==="text"?K.text:K.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let Y=null,J=!1,X=!1,j=Q.loadSre||kG,Z=[];for(let K of G){if(K.type==="text"){Z.push(K.text);continue}try{if(!Y)Y=await j();let W=T(await V0(Y,K.mathml,Q.language,"none",Q.mathSpeech));if(W){Z.push(W),J=!0;continue}X=!0,Z.push(K.fallbackText)}catch(W){X=!0,console.debug("[TTSService] Math speech generation failed; using visible fallback",{message:W instanceof Error?W.message:String(W)}),Z.push(K.fallbackText)}}let q=T(Z.join(" ")),B;if(Q.produceSsml&&Y&&J&&G.length===1&&G[0].type==="math")B=await uG(Y,G[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:q,usedMathSpeech:J,usedFallback:X,ssml:B}};var pG=(G,Q)=>H1([G],Q),gG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",cG=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),lG=new Set(["heading","listitem","option","radio"]),dG=(G)=>{if(G.type!=="text"||!G.sourceElement)return!1;let Q=G.sourceElement.tagName.toUpperCase(),Y=(G.sourceElement.getAttribute("role")||"").toLowerCase();return cG.has(Q)||lG.has(Y)},A8=async(G)=>{let Q=G.resolveMathSpeech??pG,{visibleText:Y}=G,J=[],X=0,j=(q)=>{let B=T(q),K=Y.indexOf(B,X),W=K>=0?K:X,$=W+B.length;return X=$,{start:W,end:$}},Z=[];for(let q=0;q<G.chunks.length;q++){let B=G.chunks[q];if(B.type==="text"){let N=dG(B)?[{text:B.text,offset:0}]:S7(B.text,{locale:G.language});for(let F of N){let O=T(F.text);if(!O)continue;let L=j(O);J.push({sourceChunkIndex:q,segment:{kind:"prose",spokenText:O,visibleText:O,visibleSpan:L}}),Z.push(O)}continue}let K=j(B.fallbackText),W=await Q(B,{language:G.language,produceSsml:G.produceSsml,mathSpeech:G.mathSpeech}),$=!W.speechText,H=W.speechText||B.fallbackText;J.push({sourceChunkIndex:q,segment:{kind:"math",spokenText:H,mathml:B.mathml,fallbackText:B.fallbackText,visibleSpan:K,usedFallback:$,ssml:W.ssml}}),Z.push(H)}return{segments:J,locale:gG(G.language),visibleText:Y,plainSpeechText:T(Z.join(" "))}};var iG=(G)=>(G||"en").split("-")[0].toLowerCase()||"en",sG="sre-v1",nG=256,N8=(G)=>{if(Array.isArray(G))return`array:[${G.map(N8).join(",")}]`;if(G&&typeof G==="object")return`object:{${Object.entries(G).sort(([Q],[Y])=>Q.localeCompare(Y)).map(([Q,Y])=>`${JSON.stringify(Q)}:${N8(Y)}`).join(",")}}`;if(G===null)return"null:null";if(typeof G>"u")return"undefined:";if(typeof G==="function")return`function:${G.name||"anonymous"}`;if(typeof G==="symbol")return`symbol:${String(G)}`;if(typeof G==="bigint")return`bigint:${G.toString()}`;if(typeof G==="number")return Number.isFinite(G)?`number:${G}`:`number:${String(G)}`;return`${typeof G}:${JSON.stringify(G)}`},$0=(G,Q,Y,J)=>`${sG}\x00${iG(G)}\x00${Q?"ssml":"plain"}\x00${N8(Y??null)}\x00${J}`,F8=(G={})=>{let Q=Math.max(1,G.maxEntries??nG),Y=G.resolve??((j,Z)=>H1([j],Z)),J=new Map,X=(j,Z)=>{J.delete(j),J.set(j,Z);while(J.size>Q){let q=J.keys().next().value;if(q!==void 0)J.delete(q)}};return async(j,Z)=>{let q=O7(Z.mathSpeech),B=Z.produceSsml===!0,K=$0(Z.language,B,q,j.mathml),W=J.get(K);if(W)return J.delete(K),J.set(K,W),W;let $=await Y(j,{...Z,mathSpeech:q});if(B&&$.ssml&&Q>1)X($0(Z.language,!1,q,j.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(K,$),$}};var rG=(G)=>{if(!G||/^<[^>]+>$/.test(G.trim()))return null;return F7({speechText:G}).tokens[0]?.normalized||null},oG=(G,Q)=>{let Y=F7({speechText:G.speechText});if(!Number.isFinite(Q.position))return{boundary:null,spokenText:Y.spokenText};let J=H8({tokenization:Y,position:Q.position,length:Q.length,boundaryWord:Q.word});return{boundary:J?{start:J.start,length:J.length}:null,spokenText:Y.spokenText}},aG=(G,Q,Y)=>{if(!Y)return!0;return F7({speechText:G}).tokens.find((X)=>X.start<=Q&&Q<X.end)?.normalized===Y},H0=(G,Q)=>{let Y=rG(Q.word);if(G.id!==Q.chunkId)return{chunkId:Q.chunkId,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Q.providerOffsetSpace==="unknown"||G.offsetSpace==="unsupported")return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let J,X;if(G.catalogAlignment)J=g6(G.catalogAlignment,Q.position,Q.length,Q.word),X=G.catalogAlignment.spokenText;else{let j=oG(G,Q);J=j.boundary,X=j.spokenText}if(!J)return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};if(!aG(X,J.start,Y))return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to matching word"};return{chunkId:G.id,normalizedWord:Y,chunkSpokenStart:J.start,chunkSpokenEnd:J.start+J.length,confidence:Y?1:0.75,reason:G.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var P7=(G)=>{if(G.semanticTarget)return{activeTarget:G.semanticTarget,regionTarget:G.regionTarget,quality:G.semanticTarget.quality==="exact-word"?"exact-word":G.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:G.confidence,reason:G.reason};if(G.expressionTarget)return{activeTarget:G.expressionTarget,regionTarget:G.regionTarget,quality:"expression",confidence:G.confidence,reason:G.reason};return{activeTarget:null,regionTarget:G.regionTarget,quality:"region",confidence:G.confidence,reason:G.reason}};var A0=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),M8="mi,mn,mo,mtext",N0="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",F0=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),M0=(G)=>{if(G.type==="text-range")return G.node.parentElement;return G.element},D1=(G)=>{let Q=G;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},D0=(G)=>{if(!G)return!1;if(D1(G))return!1;return!B1(G)},z0=(G)=>{let Q=G.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},z8=(G)=>{let Q=G;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},O0=(G,Q)=>{if(G.length===0)return!1;if(G.length!==Q.length)return!1;for(let Y=0;Y<G.length;Y+=1){let J=A0.get(G[Y].localName.toLowerCase());if(!J)return!1;if(Q[Y].localName.toLowerCase()!==J)return!1}return!0},tG=(G,Q)=>{if(!G)return null;if(!A0.has(G.localName.toLowerCase()))return null;if(Q.querySelector(F0))return null;let Y=z8(G),J=Q.querySelector("mjx-math");if(!Y||!J)return null;let X=Array.from(Y.querySelectorAll(M8)),j=X.indexOf(G);if(j<0)return null;let Z=Array.from(J.querySelectorAll(N0));if(!O0(X,Z))return null;let q=Z[j];if(!q||!z0(q))return null;return q},P0=(G)=>{let Q=D1(G);if(Q){if(Q.querySelector(F0))return"expression";let X=z8(G)??G,j=Q.querySelector("mjx-math");if(!j)return"expression";let Z=Array.from(X.querySelectorAll(M8)),q=Array.from(j.querySelectorAll(N0));if(!O0(Z,q))return"expression";return q.some((B)=>z0(B))?"token":"expression"}let Y=z8(G)??G;return Array.from(Y.querySelectorAll(M8)).some((X)=>!B1(X))?"token":"expression"},O8=(G)=>{let Q=M0(G),Y=D1(Q);if(Y){let J=tG(Q,Y);if(J)return{type:"element",quality:"semantic-token",element:J};return{type:"element",quality:"expression",element:Y}}if(G.type==="text-range"){if(!D0(G.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:G.node,startOffset:G.startOffset,endOffset:G.endOffset}}if(!D0(G.element))return null;return{type:"element",quality:G.quality==="region-fallback"?"expression":"semantic-token",element:G.element}},L0=O8,w0=()=>{let G=new WeakMap;return(Q)=>{let Y=M0(Q),J=D1(Y);if(!Y||!J)return O8(Q);if(G.has(Y))return G.get(Y)??null;let X=O8(Q);return G.set(Y,X),X}};var R0=(G,Q,Y,J=G.mathAlignments,X=L0)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let j=null;for(let Z of J){let q=e6(Z.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:Y.word})||G0(Z.alignment,{boundaryWord:Y.word});if(!q)continue;let B=X(q);if(!B)continue;if(B.quality==="semantic-token")return B;j??=B}return j};var A1=(G,Q,Y)=>{if(!G||typeof document>"u")return null;if(Y<=Q)return null;let J=G.get(Q),X=G.get(Math.max(Q,Y-1));if(!J)return null;if(!X)X=J;try{let j=document.createRange();return j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),j}catch{return null}};var E0=(G,Q)=>{if(!G.catalogAlignment||Q.chunkSpokenStart===null)return null;let Y=c6(G.catalogAlignment,Q.chunkSpokenStart);if(!Y)return null;let J=A1(G.visibleMap,Y.start,Y.end);if(!J)return null;return{type:"range",quality:G.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:J}};var eG=(G)=>G.regionRange?{type:"range",quality:"region",range:G.regionRange}:G.regionElement?{type:"element",quality:"region",element:G.regionElement}:null,b0=(G,Q=G.chunk.mathAlignments)=>{if(Q.length!==1)return null;let Y=Q[0]?.alignment.result.fallbackTarget;return Y?G.renderedMathTargetResolver(Y):null},GQ=(G,Q)=>{if(!G)return Q.mathAlignments;return Q.mathAlignments.filter(({element:Y})=>{try{if(G.type==="range")return G.range.intersectsNode(Y);if(G.type==="element")return G.element===Y||G.element.contains(Y);return G.node.parentElement?.contains(Y)||!1}catch{return!1}})},S0=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),T0=(G)=>G.length===1?G[0].element:null,QQ=(G,Q)=>Q.length>0&&Q.every(({element:Y})=>G.mathCapabilityByElement.get(Y)==="token"),YQ=3,JQ=(G,Q,Y)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:J,endContainer:X}=Q.range;if(J===X&&J.nodeType===YQ)return!1;return Y.some(({element:Z})=>G.mathCapabilityByElement.get(Z)==="token"&&Z.contains(J)&&Z.contains(X))},XQ=(G,Q)=>({chunk:G,regionTarget:eG(G),renderedMathTargetResolver:w0(),mathCapabilityByElement:new Map(G.mathAlignments.map(({element:Y})=>[Y,Q?P0(Y):"expression"])),heldTokenByElement:new Map}),C0=(G)=>{let Q=G.mathTokenHighlighting!==!1,Y=new Map(G.chunks.map((J)=>[J.id,XQ(J,Q)]));return{chunks:G.chunks,resolveInitial(J){let X=Y.get(J);if(!X)return S0();let j=X.chunk.mathAlignments,Z=j.length===1?j[0].element:null,q=Z?X.mathCapabilityByElement.get(Z):null;if(q==="expression")return P7({semanticTarget:null,expressionTarget:b0(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return P7({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:q==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(J){let X=Y.get(J.chunkId);if(!X)return S0();let{chunk:j}=X,Z=H0(j,J),q=E0(j,Z),B=GQ(q,j),K=(!q||B.length>0?R0(j,Z,J,B,X.renderedMathTargetResolver):null)||null,W=Q&&K&&K.quality!=="expression"?K:null,$=K&&K.quality==="expression"?K:null;if(W){let H=T0(B);if(H)X.heldTokenByElement.set(H,W);return P7({semanticTarget:W,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}if(q&&(Q?!JQ(X,q,B):B.length===0))return P7({semanticTarget:q,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason});if(QQ(X,B)){let H=T0(B),N=H?X.heldTokenByElement.get(H)??null:null;return P7({semanticTarget:N,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:N?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return P7({semanticTarget:null,expressionTarget:$??b0(X,B),regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}}};var ZQ=(G)=>{if(G.alignment?.boundaryOffsetMode)return G.alignment.boundaryOffsetMode;let Q=G.mathAlignment?.speech.boundaryOffsetSpace;if(Q)return Q;return"plain-spoken-text"},jQ=(G)=>{if(G.mathAlignments?.length)return G.mathAlignments;if(G.mathAlignment&&G.sourceElement)return[{element:G.sourceElement,alignment:G.mathAlignment}];return[]},y0=(G)=>{return(G.chunks&&G.chunks.length?G.chunks:[{speechText:G.speechText||"",visibleText:G.visibleText||G.speechText||"",sourceElement:G.sourceElement||G.contentRoot,regionElement:G.regionElement||G.sourceElement||G.contentRoot,regionRange:G.regionRange,visibleMap:G.visibleMap}]).map((Y,J)=>({id:`tts-chunk-${J}`,speechText:Y.speechText,visibleText:Y.visibleText,sourceElement:Y.sourceElement,contentRoot:G.contentRoot,regionElement:Y.regionElement??Y.sourceElement,regionRange:Y.regionRange,visibleMap:Y.visibleMap,catalogAlignment:Y.alignment,mathAlignments:jQ(Y),offsetSpace:ZQ(Y)}))};var qQ=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),N1=(G,Q)=>{let Y=G.closest(qQ);if(Y&&Q.contains(Y))return Y;return G};var UQ=(G,Q,Y)=>{let J=new Map;for(let X=Q;X<Y;X++){let j=G.get(X);if(j)J.set(X-Q,j)}return J},P8=async(G)=>{let Q=z7(G.contentRoot,G.textProcessingOptions),Y=await A8({chunks:Q.chunks,visibleText:Q.visibleText,language:G.language,mathSpeech:G.mathSpeech,produceSsml:G.produceSsml,resolveMathSpeech:G.resolveMathSpeech});return{plan:{items:Y.segments.map(({segment:X,sourceChunkIndex:j})=>{let Z=Q.chunks[j];if(X.kind==="prose"){let B=Z?.type==="text"?Z.sourceElement??G.contentRoot:G.contentRoot;return{segment:X,anchor:{sourceElement:B,regionElement:N1(B,G.contentRoot),visibleMap:UQ(Q.map,X.visibleSpan.start,X.visibleSpan.end)}}}let q=Z?.type==="math"?Z.sourceElement??null:null;return{segment:X,anchor:{sourceElement:q,regionElement:q}}}),locale:Y.locale,visibleText:Y.visibleText,plainSpeechText:Y.plainSpeechText},containsMathMarkup:Q.containsMathMarkup,visibleText:Q.visibleText}};var BQ=(G,Q)=>{let Y=V1({speechText:G.spokenText,visibleText:G.spokenText});return{speechText:G.spokenText,visibleText:G.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:A1(Q.visibleMap,0,G.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:Y.playbackMode,alignment:Y,visibleMap:Q.visibleMap}},x0=(G,Q)=>{let Y=Q.sourceElement;return{speechText:G.spokenText,visibleText:G.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:G.spokenText===G.fallbackText,mathAlignment:Y?x7({mathElement:Y,speechText:G.spokenText}):void 0}},WQ=(G,Q,Y)=>{let J=Q.sourceElement;return{speechText:Y,visibleText:G.fallbackText,sourceElement:J,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:J?x7({mathElement:J,speechText:Y}):void 0,plainFallback:x0(G,Q)}},L8=(G,Q={})=>G.items.map(({segment:Y,anchor:J})=>{if(Y.kind==="prose")return BQ(Y,J);if(Q.format==="ssml"&&Y.ssml)return WQ(Y,J,Y.ssml);return x0(Y,J)});var f0="pie-tts-control-handoff";var R;(function(G){G.IDLE="idle",G.LOADING="loading",G.PLAYING="playing",G.PAUSED="paused",G.ERROR="error"})(R||(R={}));var k0=(G,Q)=>G===Q||G.startContainer===Q.startContainer&&G.startOffset===Q.startOffset&&G.endContainer===Q.endContainer&&G.endOffset===Q.endOffset,KQ=(G,Q)=>{if(G===Q)return!0;if(!G||!Q||G.type!==Q.type||G.quality!==Q.quality)return!1;if(G.type==="range"&&Q.type==="range")return k0(G.range,Q.range);if(G.type==="element"&&Q.type==="element")return G.element===Q.element;if(G.type==="text-range"&&Q.type==="text-range")return G.node===Q.node&&G.startOffset===Q.startOffset&&G.endOffset===Q.endOffset;return!1};class c7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=R.IDLE;ttsConfig={};currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Map;lastError=null;speakRunId=0;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];currentSeekSegmentIndex=0;activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=F8();static debugEnabled=(()=>{try{if(typeof process<"u"&&process.env?.PIE_TTS_DEBUG==="1")return!0}catch{}return globalThis.__PIE_TTS_DEBUG__===!0})();constructor(){}debugLog(G,Q){if(!c7.debugEnabled)return;if(Q===void 0)console.debug(G);else console.debug(G,Q)}clearPlaybackStartBarrier(G=this.playbackStartBarrierCleanup){if(G?.(),this.playbackStartBarrierCleanup===G)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(G){if(this.playbackStartDeferredRunId!==G||G!==this.speakRunId)return;this.setState(R.PLAYING);let Q=this.pendingPlaybackStartHighlights.splice(0);for(let Y of Q)Y()}installPlaybackStartBarrier(G,Q=!1){this.clearPlaybackStartBarrier();let Y=this.provider,J=Y&&"onPlaybackStart"in Y?Y:null;if(!J&&!Q)return null;let X=J?.onPlaybackStart,j=()=>{try{this.notifyPlaybackStarted(G)}finally{X?.()}};if(J)J.onPlaybackStart=j;this.playbackStartDeferredRunId=G;let Z=()=>{if(J?.onPlaybackStart===j)J.onPlaybackStart=X;if(this.playbackStartDeferredRunId===G)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=Z,Z}runWhenPlaybackStarts(G,Q){if(this.playbackStartDeferredRunId===G){this.pendingPlaybackStartHighlights.push(Q);return}Q()}async emitTelemetry(G,Q){try{await this.telemetryReporter?.(G,Q)}catch(Y){console.warn("[TTSService] telemetry callback failed:",Y)}}async initialize(G,Q={}){this.currentProvider=G,this.ttsConfig={...Q};let Y=Q.providerOptions&&typeof Q.providerOptions==="object"?Q.providerOptions:{};this.telemetryReporter=typeof Y.__pieTelemetry==="function"?Y.__pieTelemetry:null;try{this.provider=await G.initialize(Q)}catch(J){if(G.providerId.toLowerCase()==="browser")throw J;if(!this.isBrowserSpeechFallbackAvailable())throw J;if(!await this.switchProviderToBrowser(J,{operation:"tts-initialize"}))throw J}}async updateSettings(G){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.provider;if(typeof Q.updateSettings==="function"){let Y={...G,...G.providerOptions?{providerOptions:{...this.ttsConfig.providerOptions||{},...G.providerOptions}}:{}};await Q.updateSettings(Y),this.ttsConfig={...this.ttsConfig,...Y}}else console.warn("[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.")}setHighlightCoordinator(G){this.highlightCoordinator=G}setHighlightTargetResolverProvider(G){return this.highlightTargetResolverProvider=G,()=>{if(this.highlightTargetResolverProvider===G)this.highlightTargetResolverProvider=null}}setCatalogResolver(G){this.catalogResolver=G}hasSpokenAlternate(G,Q="en-US"){if(!G||!this.catalogResolver)return!1;return this.catalogResolver.getAlternative(G,{type:"spoken",language:Q,useFallback:!0,form:"content"})?.content!==void 0}getHighlightResolverRuntime(){let G=null;try{G=this.highlightTargetResolverProvider?.()??null}catch{G=null}let Q=G?.context??{},Y=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Q,scopeElement:Q.scopeElement??Y},resolver:G?.resolver??null}}getNodeElement(G){if(!G)return null;return G.nodeType===Node.ELEMENT_NODE?G:G.parentElement}isElementWithinScope(G,Q){if(!Q)return!0;return G===Q||Q.contains(G)}isRangeWithinScope(G,Q){let Y=this.getNodeElement(G.startContainer),J=this.getNodeElement(G.endContainer);if(!Y||!J)return!1;return this.isElementWithinScope(Y,Q)&&this.isElementWithinScope(J,Q)}resolveWordHighlightRange(G){let{context:Q,resolver:Y}=this.getHighlightResolverRuntime(),J=Q.scopeElement??this.currentContentElement;try{let X=Y?.resolveWordRange?.(G,Q);if(X&&this.isRangeWithinScope(X,J))return{range:X,remapped:!k0(G,X)}}catch{}return{range:G,remapped:!1}}resolveSentenceHighlightTargets(G){let{context:Q,resolver:Y}=this.getHighlightResolverRuntime(),J=Q.scopeElement??this.currentContentElement;try{let X=Y?.resolveSentenceRanges?.(G,Q);if(!X)return{ranges:G,elements:[]};let j=[],Z=[];for(let q of X){if(typeof Range<"u"&&q instanceof Range){if(!this.isRangeWithinScope(q,J))return{ranges:G,elements:[]};j.push(q);continue}if(typeof Element<"u"&&q instanceof Element){if(!this.isElementWithinScope(q,J))return{ranges:G,elements:[]};Z.push(q);continue}return{ranges:G,elements:[]}}return{ranges:j,elements:Z}}catch{return{ranges:G,elements:[]}}}createTextRange(G,Q,Y){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let J=document.createRange();if(J.setStart(G,Q),J.setEnd(G,Y),J.startContainer!==G||J.endContainer!==G)return null;return J}catch{return null}}paintTTSWordRange(G){if(!this.highlightCoordinator)return;try{if(G.startContainer===G.endContainer&&G.startContainer.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(G.startContainer,G.startOffset,G.endOffset);return}}catch{}this.highlightCoordinator.highlightRange(G,u.TTS_WORD,$7.YELLOW)}paintTTSSentenceRanges(G){if(!this.highlightCoordinator)return;let{ranges:Q,elements:Y}=this.resolveSentenceHighlightTargets(G);if(Y.length>0&&Q.length===0&&this.highlightCoordinator.highlightTTSSentenceElements){this.highlightCoordinator.highlightTTSSentenceElements(Y);return}let J=[...Q];for(let X of Y){let j=document.createRange();j.selectNodeContents(X),J.push(j)}this.highlightCoordinator.highlightTTSSentence(J)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}getTextProcessingOptions(G){let Y=(this.ttsConfig.providerOptions||{}).textNormalization||{},J=Y.boundarySpacingMode,X=J==="none"||J==="alnum"||J==="segmenterPreferred"?J:void 0;return{locale:G||(typeof Y.locale==="string"?Y.locale:void 0),boundarySpacingMode:X}}getMathSpeechOptions(){let Q=(this.ttsConfig.providerOptions||{}).mathSpeech;return O7(Q)}buildPositionMap(G,Q,Y){this.normalizedToDOM.clear();let{text:J,map:X}=C7(G,this.getTextProcessingOptions(Y));if(this.normalizedToDOM=X,!c7.debugEnabled)return;this.debugLog("[TTSService] Text comparison:",{spokenLength:Q.length,normalizedDomLength:J.length,match:Q===J,spokenPreview:Q.substring(0,150),normalizedPreview:J.substring(0,150),differAtIndex:Q===J?null:(()=>{for(let j=0;j<Math.min(Q.length,J.length);j++)if(Q[j]!==J[j])return{index:j,spokenChar:Q[j],normalizedChar:J[j],spokenContext:Q.substring(Math.max(0,j-20),j+20),normalizedContext:J.substring(Math.max(0,j-20),j+20)};return null})()}),this.debugLog("[TTSService] Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Q.length,normalizedDomLength:J.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Q.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([j,{node:Z,offset:q}])=>({pos:j,offset:q,char:Z.textContent?.[q],expected:Q[j]}))})}getStructuralPauseProfile(){let Q=(this.ttsConfig.providerOptions||{}).structuralPauses||{},Y=Q.units||{},J=(X,j)=>{if(typeof X==="number"&&Number.isFinite(X))return X;if(typeof X==="string"&&X.trim()){let Z=Number(X);return Number.isFinite(Z)?Z:j}return j};return{baseMs:J(Q.baseMs,280),units:{minor:J(Y.minor,0.65),section:J(Y.section,1),major:J(Y.major,1.35)},minMs:J(Q.minMs,120),maxMs:J(Q.maxMs,900)}}resolvePauseMsFromUnits(G){let Q=this.getStructuralPauseProfile(),Y=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),J=Q.baseMs*Math.max(0,G)/Y;return Math.max(Q.minMs,Math.min(Q.maxMs,Math.round(J)))}resolveHighlightMode(){let Q=(this.ttsConfig.providerOptions||{}).highlightMode;if(Q==="word"||Q==="sentence")return Q;if((this.currentProvider?.providerId||"").toLowerCase()==="browser")return"sentence";return this.currentProvider?.getCapabilities().supportsWordBoundary??!1?"word":"sentence"}hasExplicitBreakSemantics(G){if(!G.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(G)}isElementHidden(G){return Z8(G)}getBoundaryStrength(G){let Q=Number(G.getAttribute("data-tts-break-ms"));if(Number.isFinite(Q)&&Q>0)return"major";let Y=G.tagName.toUpperCase();if(Y.match(/^H[1-6]$/))return"major";let J=(G.getAttribute("role")||"").toLowerCase();if(J==="heading")return"major";if(J==="listitem"||J==="row"||J==="option"||J==="radio"||Y==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(G).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(G,Q){let Y=G.parentElement,J=null;while(Y&&Y!==Q){if(this.isElementHidden(Y))return null;let j=Number(Y.getAttribute("data-tts-break-ms"));if(Number.isFinite(j)&&j>0)return{anchor:Y,units:j/this.getStructuralPauseProfile().baseMs};let Z=(Y.getAttribute("role")||"").toLowerCase(),q=Y.tagName.toUpperCase();if(q.match(/^H[1-6]$/)||Z==="heading"||Z==="listitem"||q==="LI"){J=Y;break}if(!J){if(typeof window<"u"){let B=window.getComputedStyle(Y).display;if(B==="block"||B==="list-item"||B.startsWith("table")||B==="flex"||B==="grid")J=Y}}Y=Y.parentElement}if(!J)return null;let X=this.getBoundaryStrength(J);return{anchor:J,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(G,Q){let Y=this.collectSpeechPlanBoundaries(G,Q);return this.createSpeechPlanSegments(Q,Y)}collectSpeechPlanBoundaries(G,Q){let Y=new Map,{map:J}=C7(G,this.getTextProcessingOptions()),X=this.createNodeStartOffsets(J),j=document.createTreeWalker(G,NodeFilter.SHOW_TEXT),Z=j.nextNode(),q=null;while(Z){let B=Z,K=B.parentElement;if(K&&!this.isElementHidden(K)&&!W1(B)){let W=this.getBoundaryAnchor(B,G),$=X.get(B);if(W&&$!==void 0&&W.anchor!==q&&$>0)Y.set($,Math.max(Y.get($)||0,W.units)),q=W.anchor}Z=j.nextNode()}return Y}createNodeStartOffsets(G){let Q=new Map;for(let[Y,J]of G.entries())if(!Q.has(J.node))Q.set(J.node,Y);return Q}createSpeechPlanSegments(G,Q){let Y=Array.from(Q.keys()).filter((B)=>B>0&&B<G.length).sort((B,K)=>B-K),J=[],X=0;for(let B of Y){let K=G.substring(X,B),W=K.match(/^\s*/)?.[0].length||0,$=K.match(/\s*$/)?.[0].length||0,H=X+W,N=B-$;if(N>H){let F=G.substring(H,N);J.push({text:F,startOffset:H,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(B)||0)})}X=B}let Z=G.substring(X).match(/^\s*/)?.[0].length||0,q=X+Z;if(q<G.length)J.push({text:G.substring(q).trimEnd(),startOffset:q,pauseMsAfter:0});return J.filter((B)=>B.text.trim().length>0)}segmentSentences(G){let Q=this.ttsConfig.providerOptions?.locale||void 0;return S7(G,{locale:Q})}createSeekSegmentsFromText(G){return this.segmentSentences(G).map((Q)=>{let Y=Q.text.match(/^\s*/)?.[0].length||0;return{text:Q.text.trim(),startOffset:Q.offset+Y,pauseMsAfter:0}}).filter((Q)=>Q.text.length>0)}splitSegmentsAtBoundaries(G,Q,Y){if(G.length===0||Q.length===0)return G;let J=Array.from(new Set(Q)).filter((j)=>Number.isFinite(j)&&j>0).sort((j,Z)=>j-Z);if(J.length===0)return G;let X=[];for(let j of G){let Z=j.startOffset,q=j.startOffset+j.text.length,B=J.filter((W)=>W>Z&&W<q);if(B.length===0){X.push(j);continue}let K=Z;for(let W of[...B,q]){let $=Y.substring(K,W),H=$.match(/^\s*/)?.[0].length||0,N=$.match(/\s*$/)?.[0].length||0,F=K+H,O=W-N;if(O>F)X.push({text:Y.substring(F,O),startOffset:F,pauseMsAfter:0});K=W}}return X}createSentenceHighlightSegments(G){let Q=this.createSeekSegmentsFromText(G.contentToSpeak);if(!G.shouldUsePlan||G.playbackSegments.length===0)return Q;let Y=G.playbackSegments.map((J)=>J.startOffset).filter((J)=>J>0);return this.splitSegmentsAtBoundaries(Q,Y,G.contentToSpeak)}createSeekSegmentsFromSpeechChunks(G){let Q=0;return G.map((Y)=>{let J=Y.plainFallback?.speechText||(this.hasExplicitBreakSemantics(Y.speechText)?Y.visibleText:Y.speechText)||Y.visibleText,X=T(J)||Y.visibleText||"",j={text:X,startOffset:Q,pauseMsAfter:0};return Q+=Math.max(1,X.length+1),j})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let G=0;for(let Q=0;Q<this.seekSegments.length;Q++)if(this.seekSegments[Q].startOffset<=this.currentBoundaryOffset)G=Q;else break;return G}async speakWithPlan(G,Q,Y){if(!this.provider||G.length===0)return;let J=Y?.highlightMode==="sentence",X=this.provider;if(!J&&typeof X.speakSegments==="function"){this.currentBoundaryOffset=0;let j=this.provider.onWordBoundary;this.provider.onWordBoundary=(Z,q,B)=>{if(j?.(Z,q,B),Number.isFinite(q))this.currentBoundaryOffset=q,this.currentSeekSegmentIndex=this.getCurrentSeekSegmentIndex()};try{await X.speakSegments(G)}finally{if(Q===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=j}return}this.configureWordBoundaryHighlighting({highlightMode:Y?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let j of G){if(Q!==this.speakRunId)return;let Z=this.seekSegments.findIndex((B)=>B.startOffset===j.startOffset);if(Z>=0)this.currentSeekSegmentIndex=Z;if(this.currentBoundaryOffset=j.startOffset,J)this.runWhenPlaybackStarts(Q,()=>{this.highlightSentenceSegment(j.startOffset,j.text)});await this.provider.speak(j.text);let q=j.pauseMsAfter??0;if(q>0)await new Promise((B)=>setTimeout(B,q))}}highlightSentenceSegment(G,Q){if(!this.highlightCoordinator||typeof document>"u")return;let Y=Q.trimEnd().length;if(Y<=0)return;let J=this.normalizedToDOM.get(G),X=this.normalizedToDOM.get(G+Y-1);if(!J||!X)return;let j=document.createRange();j.setStart(J.node,J.offset),j.setEnd(X.node,X.offset+1),this.paintTTSSentenceRanges([j]),this.activeSentenceStartOffset=G}getSegmentIndexForOffset(G,Q){if(G.length===0)return-1;let Y=-1;for(let J=0;J<G.length;J++)if(G[J].startOffset<=Q)Y=J;else break;return Y}highlightSentenceForOffset(G){let Q=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Q.length===0)return;let Y=this.getSegmentIndexForOffset(Q,G);if(Y<0)return;let J=Q[Y];if(!J)return;if(this.activeSentenceStartOffset===J.startOffset)return;this.highlightSentenceSegment(J.startOffset,J.text)}findHighlightRange(G,Q){let Y=this.normalizedToDOM.get(G);if(!Y)return console.warn(`[TTSService] No mapping found for start position ${G}`,{totalMappings:this.normalizedToDOM.size,nearbyMappings:Array.from(this.normalizedToDOM.entries()).filter(([j])=>Math.abs(j-G)<5).map(([j,{offset:Z,node:q}])=>({pos:j,offset:Z,char:q.textContent?.[Z]}))}),null;let J=G+Q-1,X=this.normalizedToDOM.get(J);if(!X)return console.warn(`[TTSService] No mapping found for end position ${J}`,{startChar:G,length:Q,totalMappings:this.normalizedToDOM.size}),null;if(Y.node!==X.node)return console.warn("[TTSService] Word spans multiple nodes, highlighting in first node only"),{node:Y.node,start:Y.offset,end:(Y.node.textContent||"").length};return{node:Y.node,start:Y.offset,end:X.offset+1}}async speak(G,Q){if(!this.provider)throw Error("TTS service not initialized");let Y=++this.speakRunId;this.clearPlaybackStartBarrier();let J=null;try{if(await this.applyLanguageSettings(Q),Y!==this.speakRunId)return;let X=await this.resolveSpeechContent(G,Q);if(Y!==this.speakRunId)return;let{contentToSpeak:j,speechText:Z,highlightText:q,normalizedText:B,usedCatalogSpoken:K,speechSource:W,speechMatchesVisibleText:$,speechChunks:H}=X;this.logResolvedSpeechContent({contentToSpeak:j,speechSource:W,catalogId:Q?.catalogId}),this.initializeSpeakTracking(q,Q);let N=Q?.highlightModeOverride||($?this.resolveHighlightMode():"sentence");this.activeHighlightMode=N,this.activeWordBoundaryOffset=Q?.wordBoundaryOffset||0;let F=this.hasExplicitBreakSemantics(j),O=!!this.currentContentElement&&!K&&!F&&$;if(this.playbackChunks=H?.length?H:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):F||!$?[]:O&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,B):this.createSeekSegmentsFromText(q),this.sentenceHighlightSegments=F?[]:this.createSentenceHighlightSegments({contentToSpeak:q,shouldUsePlan:O,playbackSegments:this.seekSegments}),this.setState(R.LOADING),J=this.installPlaybackStartBarrier(Y,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:q,options:Q,highlightMode:N,shouldUsePlan:O,runId:Y}),$)this.configureWordBoundaryHighlighting({highlightMode:N,wordBoundaryOffset:Q?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!J)this.setState(R.PLAYING);if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:O,runId:Y,highlightMode:N,contentToSpeak:Z,speechChunks:H}),Y!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(X){let j=X;if(console.error("TTS error:",j),this.lastError=j instanceof Error?j.message:String(j),Y!==this.speakRunId)return;throw this.setState(R.ERROR),this.clearHighlightsAndTracking(),j}finally{this.clearPlaybackStartBarrier(J)}}async switchProviderToBrowser(G,Q){if(!this.currentProvider)return!1;let Y=new T7,J=this.currentProvider.providerId,X={};if(this.ttsConfig.rate!==void 0)X.rate=this.ttsConfig.rate;if(this.ttsConfig.pitch!==void 0)X.pitch=this.ttsConfig.pitch;if(this.ttsConfig.mathTokenHighlighting!==void 0)X.mathTokenHighlighting=this.ttsConfig.mathTokenHighlighting;let j=Q?.operation||"tts-initialize",Z=Q?.contentToSpeak??"",q=Z.replace(/\s+/g," ").trim().slice(0,120),B=Z.length>0?{textLength:Z.length,textPreview:q.length<Z.length?`${q}…`:q}:{};try{return this.provider?.stop(),this.currentProvider.destroy(),this.currentProvider=Y,this.provider=await Y.initialize(X),this.ttsConfig=X,await this.emitTelemetry("pie-tool-runtime-fallback",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:Y.providerId,reason:G instanceof Error?G.message:String(G),...B}),console.warn("[TTSService] TTS provider initialization failed; switched to browser fallback",{fromProvider:J,reason:G,...B}),!0}catch(K){return await this.emitTelemetry("pie-tool-runtime-fallback-error",{toolId:"textToSpeech",operation:j,fromProvider:J,toProvider:"browser",errorType:"TTSRuntimeFallbackError",message:K instanceof Error?K.message:String(K)}),console.error("[TTSService] Failed to switch to browser fallback provider",K),!1}}isBrowserSpeechFallbackAvailable(){if(typeof window>"u")return!1;if(!("speechSynthesis"in window))return!1;return typeof globalThis.SpeechSynthesisUtterance==="function"}async applyLanguageSettings(G){if(!G?.language||!this.provider)return;let Q=this.ttsConfig.providerOptions||{},Y=Q.textNormalization||{},J=Q.segmenter||{},X={...Q,locale:G.language,textNormalization:{...Y,locale:G.language},segmenter:{...J,locale:G.language}};if(this.ttsConfig={...this.ttsConfig,providerOptions:X},"updateSettings"in this.provider&&typeof this.provider.updateSettings==="function")await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(G,Q){let Y=T(G);if(Q?.ignoreCatalogs)return{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,usedCatalogSpoken:!1,speechSource:"dom-or-input",normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0};if(Q?.catalogId&&this.catalogResolver){let j=this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language||"en-US",useFallback:!0,context:Q.catalogContext,form:"content"}),Z=j?.content;if(j&&Z!==void 0){let q=Q?.contentElement?z7(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||Y:Y,B=T(Z);return this.debugLog(`[TTSService] Using catalog content for "${Q.catalogId}" (${j.language})`),{contentToSpeak:Z,speechText:Z,visibleText:q,highlightText:q,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:q,containsMathMarkup:!1,speechMatchesVisibleText:B===q}}this.debugLog(`[TTSService] No catalog found for "${Q.catalogId}", falling back to generated TTS`)}let J=Q?.contentElement?this.resolveCatalogComposedSpeechContent(Q.contentElement,Y,Q):null;if(J)return J;return{...Q?.contentElement?await this.resolveGeneratedSpeechContent(Q.contentElement,Y,Q.language):{contentToSpeak:Y,speechText:Y,visibleText:Y,highlightText:Y,normalizedText:Y,containsMathMarkup:!1,speechMatchesVisibleText:!0},usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(G,Q,Y){if(!this.catalogResolver)return null;let J=this.collectCatalogSpeechChunks(G,Y);if(!J.some((Z)=>Z.sourceElement))return null;let X=T(J.map((Z)=>Z.speechText).join(" ")),j=z7(G,this.getTextProcessingOptions(Y.language)).visibleText||Q;return{contentToSpeak:X,speechText:X,visibleText:j,highlightText:j,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:j,containsMathMarkup:!1,speechMatchesVisibleText:J.every((Z)=>Z.speechMatchesVisibleText),speechChunks:J}}collectCatalogSpeechChunks(G,Q){let Y=[],J="",X=()=>{let K=T(J);if(J="",!K)return;Y.push({speechText:K,visibleText:K,sourceElement:null,speechMatchesVisibleText:!0})},j=(K)=>{let W=K.getAttribute("data-catalog-idref");if(!W)return null;let $={type:"spoken",language:Q.language||"en-US",useFallback:!0,context:Q.catalogContext},H=this.catalogResolver.getAlternative(W,{...$,form:"payload"}),N=H?.payload?w6({payload:H.payload})??void 0:void 0,O=this.catalogResolver.getAlternative(W,{...$,form:"content"})?.content;if(N===void 0&&O===void 0)return null;return{script:O,audio:N}},Z=(K,W)=>{let $=q(K);if($.length!==1)return null;let H=$[0],N=z7(H,this.getTextProcessingOptions(Q.language)).visibleText||T(H.textContent||""),F=(O)=>T(O).replace(/\s+/g,"");return F(N)===F(W)?H:null},q=(K)=>{let W=Array.from(K.querySelectorAll("math"));if(K.localName?.toLowerCase()==="math")return[K,...W];return W},B=(K)=>{if(H7(K,G))return;if(K.nodeType===Node.TEXT_NODE){J+=` ${K.textContent||""}`;return}if(K.nodeType!==Node.ELEMENT_NODE)return;let W=K,$=j(W);if($){X();let H=z7(W,this.getTextProcessingOptions(Q.language)),N=H.visibleText||T(W.textContent||""),F=N1(W,G),O=$.script!==void 0?(()=>{let L=$.script,D=V1({speechText:L,visibleText:N}),P=Z(W,N),S=P?x7({mathElement:P,speechText:L}):void 0,v=S?void 0:q(W).map((I)=>({element:I,alignment:x7({mathElement:I,speechText:L})}));return{speechText:L,visibleText:N,sourceElement:W,regionElement:F,speechMatchesVisibleText:T(L)===N,playbackMode:D.playbackMode,alignment:D,mathAlignment:S,mathAlignments:v,visibleMap:H.map}})():null;if($.audio){Y.push(O?{...O,audio:$.audio,plainFallback:O}:{speechText:N,visibleText:N,sourceElement:W,regionElement:F,speechMatchesVisibleText:!1,visibleMap:H.map,audio:$.audio});return}if(O)Y.push(O);return}for(let H of Array.from(W.childNodes))B(H)};return B(G),X(),Y}resolveGeneratedPlaybackFormat(){let G=this.currentProvider;if(!G)return"plain";if(G.providerId?.toLowerCase()==="browser")return"plain";return G.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(G,Q,Y){let J=this.resolveGeneratedPlaybackFormat(),{plan:X,containsMathMarkup:j,visibleText:Z}=await P8({contentRoot:G,language:Y,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(Y),produceSsml:J==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver}),q=Z||Q;if(!j)return{contentToSpeak:q,speechText:q,visibleText:q,highlightText:q,normalizedText:q,containsMathMarkup:!1,speechMatchesVisibleText:!0};let B=L8(X,{format:J}),K=X.plainSpeechText;return{contentToSpeak:K,speechText:K,visibleText:q,highlightText:q,normalizedText:q,containsMathMarkup:!0,speechMatchesVisibleText:K===q,speechChunks:B}}logResolvedSpeechContent(G){let Q=G.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);this.debugLog("[TTSService] Speak resolved content",{source:G.speechSource,catalogId:G.catalogId||null,length:G.contentToSpeak.length,preview:Q})}initializeSpeakTracking(G,Q){this.currentText=G,this.currentContentElement=Q?.contentElement||null,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(G){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,G.contentToSpeak,G.options?.language),G.highlightMode==="sentence"&&G.shouldUsePlan)return;let Q=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(G.runId,()=>{if(Q)this.highlightSentenceSegment(Q.startOffset,Q.text),this.debugLog("[TTSService] Applied initial sentence highlighting");else try{let Y=document.createRange();Y.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([Y])}catch{}})}configureWordBoundaryHighlighting(G){if(!this.provider||G.highlightMode!=="word"||!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Q,Y,J)=>{let X=J||Q.length,j=Y+this.currentBoundaryOffset+G.wordBoundaryOffset;this.highlightSentenceForOffset(j);let Z=this.findHighlightRange(j,X);if(Z&&this.highlightCoordinator){let q=Z.node.textContent?.substring(Z.start,Z.end)||"";this.debugLog(`[TTSService] Highlighting "${q}" (word: "${Q}") at position ${j}`);let B=this.createTextRange(Z.node,Z.start,Z.end);if(B)this.paintTTSWordRange(this.resolveWordHighlightRange(B).range);else this.highlightCoordinator.highlightTTSWord(Z.node,Z.start,Z.end)}else console.warn(`[TTSService] Could not find highlight range for position ${j}, length ${X}`)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(G){let Q=G.regionElement||G.sourceElement;if(!Q&&!G.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,G.regionRange){this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([G.regionRange]);return}if(!Q)return;let Y=document.createRange();Y.selectNodeContents(Q),this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Y])}catch{}}highlightCatalogActiveRange(G){if(!this.highlightCoordinator)return;this.paintTTSWordRange(this.resolveWordHighlightRange(G).range)}highlightRenderableRegionTarget(G){if(!this.highlightCoordinator||!G||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&KQ(this.lastRenderedRegionTarget,G))return;try{let Q=document.createRange();if(G.type==="element")Q.selectNodeContents(G.element);else if(G.type==="range"){this.paintTTSSentenceRanges([G.range]),this.lastRenderedRegionTarget=G;return}else Q.setStart(G.node,G.startOffset),Q.setEnd(G.node,G.endOffset);this.paintTTSSentenceRanges([Q]),this.lastRenderedRegionTarget=G}catch{}}highlightRenderableActiveTarget(G){if(!this.highlightCoordinator||typeof document>"u")return;if(!G){this.highlightCoordinator.clearHighlights(u.TTS_WORD);return}if(G.type==="text-range"){let X=this.createTextRange(G.node,G.startOffset,G.endOffset);if(X)this.paintTTSWordRange(this.resolveWordHighlightRange(X).range);else this.highlightCoordinator.highlightTTSWord(G.node,G.startOffset,G.endOffset);return}if(G.type==="range"){this.highlightCatalogActiveRange(G.range);return}let Q=document.createRange();Q.selectNodeContents(G.element);let Y=this.resolveWordHighlightRange(Q);if(Y.remapped){this.paintTTSWordRange(Y.range);return}let J=G.element.childNodes.length===1?G.element.firstChild:null;if(G.quality==="semantic-token"&&J?.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(J,0,J.textContent?.length||0);return}this.highlightCoordinator.highlightTTSWordElement?.(G.element)}renderHighlightDecision(G){this.highlightRenderableRegionTarget(G.regionTarget),this.highlightRenderableActiveTarget(G.activeTarget)}async speakCatalogChunk(G,Q){try{await this.speakCatalogChunkOnce(G,Q)}catch(Y){if(G.plainFallback&&Q===this.speakRunId){if(this.debugLog("[TTSService] SSML chunk speak failed; retrying plain text",{message:Y instanceof Error?Y.message:String(Y)}),this.playbackStartDeferredRunId===Q&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.setState(R.PLAYING);await this.speakCatalogChunkOnce(G.plainFallback,Q);return}throw Y}}async playRecordedAudio(G,Q){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let Y=G.sources[0],J=document.createElement("audio");J.preload="auto",J.src=L6(Y.src,G.fragment),J.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,j)=>{let Z,q=!1,B=!1,K=()=>{if(B||q)return;q=!0,Q?.()},W=()=>{if(J.removeEventListener("ended",$),J.removeEventListener("error",H),J.removeEventListener("playing",K),Z?.(),this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null},$=()=>{if(B)return;B=!0,W(),X()},H=()=>{if(B)return;B=!0,W(),j(Error(`[tts] recorded audio failed to play: ${Y.src}`))};this.activeRecordedAudio={element:J,cancel:()=>{if(B)return;B=!0,W(),J.pause(),X()}},J.addEventListener("ended",$),J.addEventListener("error",H),J.addEventListener("playing",K),Z=P6(J,G.fragment,$),Promise.resolve(J.play()).then(K).catch(H)}).finally(()=>{if(this.activeRecordedAudio?.element===J)this.activeRecordedAudio=null;J.pause(),J.removeAttribute("src")})}cancelRecordedAudio(){let G=this.activeRecordedAudio;if(!G)return;this.activeRecordedAudio=null,G.cancel()}async speakCatalogChunkOnce(G,Q){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,G.audio){this.runWhenPlaybackStarts(Q,()=>{this.highlightCatalogRegion(G)}),await this.playRecordedAudio(G.audio,()=>{this.notifyPlaybackStarted(Q)});return}let Y=G.regionElement||G.sourceElement||this.currentContentElement,J=Y?y0({contentRoot:Y,chunks:[G]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,j=J?C0({chunks:[J],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(Q,()=>{if(j&&J&&G.mathAlignment)this.renderHighlightDecision(j.resolveInitial(J.id));else this.highlightCatalogRegion(G)}),!(G.sourceElement&&(G.mathAlignment&&G.mathAlignment.speech.tokens.length>0||G.mathAlignments&&G.mathAlignments.length>0||G.alignment&&G.visibleMap&&(G.playbackMode==="exact-word"||G.playbackMode==="anchor-span")))){let W=this.provider,$=W.onWordBoundary;W.onWordBoundary=void 0;try{await W.speak(G.speechText)}finally{if(this.provider===W&&Q===this.speakRunId&&W.onWordBoundary===void 0)W.onWordBoundary=$}return}let q=this.provider,B=q.onWordBoundary,K=(W,$,H)=>{if(Q!==this.speakRunId)return;if(j&&J){let N=J.offsetSpace==="unsupported"?"unknown":J.offsetSpace;this.renderHighlightDecision(j.resolveBoundary({chunkId:J.id,word:W,position:$,length:H,providerOffsetSpace:N}));return}};q.onWordBoundary=K;try{await q.speak(G.speechText)}finally{if(this.provider===q&&Q===this.speakRunId&&q.onWordBoundary===K)q.onWordBoundary=B}}async executeSpeakPlayback(G){if(G.speechChunks?.length&&this.provider){for(let Q=0;Q<G.speechChunks.length;Q++){if(G.runId!==this.speakRunId)return;this.currentSeekSegmentIndex=Q;let Y=this.seekSegments[Q];if(Y)this.currentBoundaryOffset=Y.startOffset;let J=G.speechChunks[Q];await this.speakCatalogChunk(J,G.runId)}return}if(G.shouldUsePlan&&this.currentContentElement){let Q=this.seekSegments;if(Q.length>0)await this.speakWithPlan(Q,G.runId,{highlightMode:G.highlightMode});else if(this.provider)await this.provider.speak(G.contentToSpeak);return}if(this.provider)await this.provider.speak(G.contentToSpeak)}clearHighlightsAndTracking(){if(this.pendingPlaybackStartHighlights=[],this.activePlaybackRate=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null}async speakRange(G,Q){if(!this.provider)throw Error("TTS service not initialized");if(W1(G.commonAncestorContainer)){console.warn("[tts] selection lies inside content marked not-to-be-spoken; nothing was spoken. Selecting a node and pressing read-aloud must not become a way around suppression.");return}let J=Q?.contentRoot||null;if(!J){let W=G.commonAncestorContainer;J=W.nodeType===Node.ELEMENT_NODE?W:W.parentElement}if(!J)return;let X=j8(G,J),j=X.text.trim();if(!j){if(X.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return}let Z=document.createRange();Z.selectNodeContents(J),Z.setEnd(G.startContainer,G.startOffset);let q=j8(Z,J).text,B=T(q),K=B.length+(/\s$/.test(q)&&B?1:0);this.debugLog("[TTSService] speakRange offset calculation:",{selectedText:j,textBeforeRange:q.substring(0,100),offset:K,rootTag:J.tagName}),await this.speak(j,{contentElement:J,ignoreCatalogs:!0,wordBoundaryOffset:K})}pause(){if(!this.provider)return;if(this.state===R.PLAYING)this.activeRecordedAudio?.element.pause(),this.provider.pause(),this.setState(R.PAUSED)}resume(){if(!this.provider)return;if(this.state===R.PAUSED){let G=this.activeRecordedAudio?.element;if(G)Promise.resolve(G.play()).catch(()=>{});this.provider.resume(),this.setState(R.PLAYING)}}normalizePlaybackRate(G){if(!Number.isFinite(G))return 1;return Math.max(0.25,Math.min(4,G))}async restartFromSeekIndex(G){if(!this.provider||this.seekSegments.length===0)return;let Q=Math.max(0,Math.min(this.seekSegments.length-1,G)),Y=this.playbackChunks.length?this.playbackChunks.slice(Q):null;this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.currentSeekSegmentIndex=Q;let J=++this.speakRunId,X=this.seekSegments.slice(Q);this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.setState(R.LOADING);let j=this.installPlaybackStartBarrier(J,!!Y?.[0]?.audio);if(!j)this.setState(R.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),Y)for(let Z=0;Z<Y.length;Z++){if(J!==this.speakRunId)return;let q=Q+Z;this.currentSeekSegmentIndex=q;let B=this.seekSegments[q];if(B)this.currentBoundaryOffset=B.startOffset;await this.speakCatalogChunk(Y[Z],J)}else await this.speakWithPlan(X,J,{highlightMode:this.activeHighlightMode});if(J!==this.speakRunId)return;this.setState(R.IDLE),this.clearHighlightsAndTracking()}catch(Z){if(J!==this.speakRunId)return;throw this.lastError=Z instanceof Error?Z.message:String(Z),this.setState(R.ERROR),this.clearHighlightsAndTracking(),Z}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(G){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.normalizePlaybackRate(G),Y=this.pendingPlaybackRateRequest;if(Y?.rate===Q){await Y.promise;return}let J=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let q=this.speakRunId;if(J!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:q};let B=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===B)return{didUpdate:!1,playbackRunId:q};return await this.updateSettings({rate:Q}),{didUpdate:!0,playbackRunId:q}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let j=X.then(async(q)=>{if(J!==this.playbackRateRequestId||q.playbackRunId!==this.speakRunId)return;let B=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!q.didUpdate&&!B)return;if(this.state!==R.PLAYING&&this.state!==R.LOADING||!this.currentText||this.seekSegments.length===0||this.hasExplicitBreakSemantics(this.currentText))return;await this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex())}),Z;Z=j.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===Z)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Q,promise:Z},await Z}async seekBy(G){if(!this.provider||!this.currentText)return;if(this.state!==R.PLAYING&&this.state!==R.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Q=Number.isFinite(G)?Math.trunc(G):0;if(Q===0)return;let Y=this.getCurrentSeekSegmentIndex(),J=Math.max(0,Math.min(this.seekSegments.length-1,Y+Q));if(J===Y)return;await this.restartFromSeekIndex(J)}async seekForward(G=1){let Q=Number.isFinite(G)?Math.max(1,Math.trunc(G)):1;await this.seekBy(Q)}async seekBackward(G=1){let Q=Number.isFinite(G)?Math.max(1,Math.trunc(G)):1;await this.seekBy(-Q)}stop(){if(!this.provider)return;if(this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.setState(R.IDLE),this.currentText=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.currentSeekSegmentIndex=0,this.activeSentenceStartOffset=null,this.activePlaybackRate=null}requestControlHandoff(){if(typeof window>"u")return;let G={source:"host"};window.dispatchEvent(new CustomEvent(f0,{detail:G}))}isPlaying(){return this.state===R.PLAYING}isPaused(){return this.state===R.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(G,Q){if(!this.listeners.has(G))this.listeners.set(G,new Set);this.listeners.get(G).add(Q)}offStateChange(G,Q){let Y=this.listeners.get(G);if(Y){if(Y.delete(Q),Y.size===0)this.listeners.delete(G)}}setState(G){if(this.state===G)return;let Q=this.state;this.state=G;for(let Y of this.listeners.values())for(let J of Y)J(G);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G}),G===R.PLAYING){let Y=Q===R.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(Y,{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G});return}if(G===R.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G});return}if(G===R.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G,message:this.lastError||void 0});return}if(G===R.IDLE&&(Q===R.PLAYING||Q===R.PAUSED||Q===R.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",providerId:"tts",previousState:Q,state:G})}}var _Q=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),I0=(G)=>G&&typeof G==="object"?G:{},VQ=(G)=>G==="polly"||G==="google"||G==="server",l=(G,Q)=>G===void 0?Q:G,$Q=(G,Q="left-aligned")=>typeof G==="string"&&_Q.has(G)?G:Q,K4=Object.freeze([0.8,1.25]),_4=Object.freeze([{rate:0.8,label:"Slow",ariaLabel:"Slow speed"},{rate:1,label:"Normal",ariaLabel:"Normal speed",default:!0},{rate:1.25,label:"Fast",ariaLabel:"Fast speed"}]);var V4=Object.freeze([0.8,1,1.25]);var HQ=(G)=>{let Q={...G,layoutMode:$Q(G.layoutMode)},Y=G.backend||"browser";if(!VQ(Y))return Q;let J={...Q,apiEndpoint:l(Q.apiEndpoint,"/api/tts"),transportMode:l(Q.transportMode,"pie"),endpointValidationMode:l(Q.endpointValidationMode,"voices"),validateEndpoint:l(Q.validateEndpoint,!0),includeAuthOnAssetFetch:l(Q.includeAuthOnAssetFetch,!1),rate:l(Q.rate,1),language:l(Q.language,"en-US")};if(Y==="polly")return{...J,defaultVoice:l(J.defaultVoice,"Joanna"),engine:l(J.engine,"neural"),format:l(J.format,"mp3"),speechMarksMode:l(J.speechMarksMode,"word+sentence")};if(Y==="google")return{...J,defaultVoice:l(J.defaultVoice,"en-US-Wavenet-A")};return J},v0=(G)=>{let Q=I0(G),Y=I0(Q.settings);return HQ({...Q,...Y})},w8=(G)=>G.backend||"browser",DQ=(G,Q)=>{if(Q==="polly"||Q==="google")return Q;if(Q==="server")return G.serverProvider||G.provider;return G.serverProvider||G.provider},AQ=(G,Q)=>G.transportMode||(Q==="custom"?"custom":"pie"),h0=(G)=>{let Q=w8(G),Y=DQ(G,Q),J=AQ(G,Y),X=O7(G.mathSpeech);return{voice:G.defaultVoice,rate:G.rate,pitch:G.pitch,providerOptions:{...G.language?{locale:G.language}:{},...Q==="polly"&&G.engine?{engine:G.engine}:{},...Q==="polly"&&typeof G.sampleRate==="number"?{sampleRate:G.sampleRate}:{},...Q==="polly"&&G.format?{format:G.format}:{},...Q==="polly"?{speechMarkTypes:G.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...J==="custom"&&typeof G.cache==="boolean"?{cache:G.cache}:{},...J==="custom"&&G.speedRate?{speedRate:G.speedRate}:{},...J==="custom"&&G.lang_id?{lang_id:G.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:G.apiEndpoint,provider:Y,language:G.language,transportMode:J,endpointMode:G.endpointMode,endpointValidationMode:G.endpointValidationMode,includeAuthOnAssetFetch:G.includeAuthOnAssetFetch,validateEndpoint:G.validateEndpoint,...typeof G.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:G.mathTokenHighlighting}:{}}};class F1{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(G,Q,Y){try{await G.onTelemetry?.(Q,Y)}catch(J){console.warn("[ToolProviderRegistry] Telemetry callback failed:",J)}}register(G,Q){if(this.providers.has(G)){console.warn(`[ToolProviderRegistry] Provider "${G}" already registered, skipping`);return}if(this.providers.set(G,Q.provider),this.configs.set(G,Q),this.initialized.set(G,!1),console.log(`[ToolProviderRegistry] Registered provider "${G}" (${Q.provider.providerName})`),Q.lazy===!1)this.initialize(G).catch((Y)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${G}":`,Y)})}async initialize(G){if(this.initialized.get(G))return;let Q=this.initializationPromises.get(G);if(Q)return Q;let Y=this._doInitialize(G);this.initializationPromises.set(G,Y);try{await Y}finally{this.initializationPromises.delete(G)}}async _doInitialize(G){let Q=this.providers.get(G),Y=this.configs.get(G);if(!Q||!Y)throw Error(`[ToolProviderRegistry] Provider "${G}" not registered`);let J={...Y.config},X=(Z)=>{if(!Z||typeof Z!=="object")return"unknown";let q=Z;return(typeof q.backend==="string"?q.backend:typeof q.provider==="string"?q.provider:typeof q.serverProvider==="string"?q.serverProvider:typeof q.providerId==="string"?q.providerId:"")||"unknown"},j=Date.now();if(await this.emitTelemetry(Y,"pie-tool-init-start",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize"}),Q.requiresAuth&&Y.authFetcher){let Z=Date.now();await this.emitTelemetry(Y,"pie-tool-backend-call-start",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch"}),console.log(`[ToolProviderRegistry] Fetching auth for "${G}"...`);try{let q=await Y.authFetcher();J={...J,...q},await this.emitTelemetry(Y,"pie-tool-backend-call-success",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z})}catch(q){throw await this.emitTelemetry(Y,"pie-tool-backend-call-error",{toolId:G,providerId:G,backend:X(J),operation:"auth-fetch",duration:Date.now()-Z,errorType:"ProviderAuthFetchError",message:q instanceof Error?q.message:String(q)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${G}":`,q),Error(`Failed to fetch auth credentials for provider "${G}"`)}}try{await Q.initialize(J),this.initialized.set(G,!0),await this.emitTelemetry(Y,"pie-tool-init-success",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize",duration:Date.now()-j}),console.log(`[ToolProviderRegistry] Provider "${G}" initialized`)}catch(Z){throw await this.emitTelemetry(Y,"pie-tool-init-error",{toolId:G,providerId:G,backend:X(J),operation:"provider-initialize",duration:Date.now()-j,errorType:"ProviderInitializationError",message:Z instanceof Error?Z.message:String(Z)}),console.error(`[ToolProviderRegistry] Initialization failed for "${G}":`,Z),Z}}async getProvider(G,Q=!0){console.log("[ToolProviderRegistry] getProvider called",{providerId:G,autoInitialize:Q,isRegistered:this.providers.has(G),isInitialized:this.initialized.get(G),allProviderIds:Array.from(this.providers.keys())});let Y=this.providers.get(G);if(!Y)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:G,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${G}" not registered`);if(Q&&!this.initialized.get(G))console.log("[ToolProviderRegistry] Auto-initializing provider:",G),await this.initialize(G);return console.log("[ToolProviderRegistry] Returning provider:",{providerId:G,providerName:Y.providerName,isReady:Y.isReady()}),Y}getProvidersByCategory(G){return Array.from(this.providers.entries()).filter(([Q,Y])=>Y.category===G).map(([Q])=>Q)}getProviderIds(){return Array.from(this.providers.keys())}has(G){return this.providers.has(G)}isInitialized(G){return this.initialized.get(G)===!0}isInitializing(G){return this.initializationPromises.has(G)}async unregister(G){let Q=this.providers.get(G);if(Q){let Y=this.initializationPromises.get(G);if(Y)try{await Y}catch{}Q.destroy(),this.providers.delete(G),this.configs.delete(G),this.initialized.delete(G),this.initializationPromises.delete(G),console.log(`[ToolProviderRegistry] Unregistered provider "${G}"`)}}async destroy(){let G=Array.from(this.providers.keys());await Promise.all(G.map((Q)=>this.unregister(Q))),console.log("[ToolProviderRegistry] Registry destroyed")}}class R8{targets=new Set;changeListeners=new Set;registerTarget(G){return this.targets.add(G),this.notifyChange(),()=>{if(!this.targets.delete(G))return;this.notifyChange()}}canRequest(G,Q){return this.findTarget(G,Q)!==null}request(G){let Q=this.findTarget(G.toolId,G.level);if(!Q)return!1;try{Q.open(G.toolId,G.params)}catch(Y){return console.error(`[ToolRequestRegistry] Target failed to open "${G.toolId}":`,Y),!1}return!0}onTargetsChange(G){return this.changeListeners.add(G),()=>{this.changeListeners.delete(G)}}findTarget(G,Q){let Y=this.findTargetAtLevel(G,Q??"section");if(Y||Q!==void 0)return Y;for(let J of this.targets){if(J.level==="section")continue;if(this.hostsTool(J,G))return J}return null}findTargetAtLevel(G,Q){for(let Y of this.targets){if(Y.level!==Q)continue;if(this.hostsTool(Y,G))return Y}return null}hostsTool(G,Q){try{return G.hostsTool(Q)===!0}catch(Y){return console.warn(`[ToolRequestRegistry] Target at level "${G.level}" failed the host check for "${Q}":`,Y),!1}}notifyChange(){for(let G of this.changeListeners)try{G()}catch(Q){console.warn("[ToolRequestRegistry] Target change listener threw:",Q)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}var NQ=(G)=>`No assessment is bound, so no policy source could grant "${G}"`;function E8(G,Q,Y,J){return{featureId:G,granted:!1,action:"block",rule:Q,precedence:0,sourceType:"host",reason:Q==="host-blocked"?"Listed in tools.policy.blocked":`Not listed in tools.policy.allowed (${Y.join(", ")})`,required:!1,assessmentBound:J.assessmentBound}}function u0(G,Q,Y){let J=Q.decisions[0],X=Array.from(Q.perToolFlags.values())[0],j=J?.action==="enable",Z=J?.reason??`Feature "${G}" not configured`;return{featureId:G,granted:j,action:J?.action??"skip",rule:J?.rule??"pnp-support",precedence:J?.precedence??6,sourceType:J?.sourceType??"system",reason:Y.assessmentBound||j?Z:NQ(G),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:Y.assessmentBound}}class M1{provenance;stepCounter=0;constructor(G){this.provenance={contextId:G,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(G,Q){let Y={id:Q.id,name:Q.name??Q.id};switch(G){case"organization":this.provenance.sources.organization={...Y,pnpDefaults:Q.config};break;case"assessment":this.provenance.sources.assessment={...Y,settings:Q.config};break;case"section":this.provenance.sources.section={...Y,settings:Q.config};break;case"item":this.provenance.sources.item={...Y,settings:Q.config};break;case"student":this.provenance.sources.student={id:Q.id,pnpProfile:Q.config};break;case"host":this.provenance.sources.host={id:Q.id,config:Q.config};break}return this}addDecision(G){let Q={step:++this.stepCounter,precedence:G.precedence,rule:G.rule,featureId:G.featureId,action:G.action,source:{type:G.sourceType,id:G.sourceId,name:G.sourceName},reason:G.reason,value:G.value,timestamp:new Date};this.provenance.decisionLog.push(Q);let Y=this.provenance.features.get(G.featureId);if(!Y)Y={featureId:G.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(G.featureId,Y);if(Y.allDecisions.push(Q),G.action==="advisory"){if(Y.finalState==="not-configured")Y.finalState="advisory-only"}else if(G.action!=="skip"){if(!Y.winningDecision||Q.precedence<Y.winningDecision.precedence)Y.winningDecision=Q,Y.finalState=Q.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[G.sourceType]=(this.provenance.summary.bySource[G.sourceType]||0)+1,this.provenance.summary.byRule[G.rule]=(this.provenance.summary.byRule[G.rule]||0)+1,this}reconcileFinalStates(G){for(let Q of G){let Y=this.provenance.features.get(Q);if(!Y){Y={featureId:Q,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Q,Y);continue}Y.finalState="enabled"}for(let Q of this.provenance.features.values()){if(G.has(Q.featureId))continue;let Y=Q.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),J=Q.allDecisions.some((X)=>X.action==="advisory");if(Y)Q.finalState="blocked";else if(J)Q.finalState="advisory-only";else Q.finalState="not-configured"}return this}build(){for(let G of this.provenance.features.values())G.explanation=FQ(G);for(let G of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,G.finalState==="enabled")this.provenance.summary.enabled++;else if(G.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function FQ(G){if(!G.winningDecision){if(G.finalState==="advisory-only"){let j=G.allDecisions.find((Z)=>Z.action==="advisory");return j?`Feature "${G.featureId}" was kept in its host-decided state; ${j.reason}`:`Feature "${G.featureId}" carries an advisory note.`}return`Feature "${G.featureId}" was not configured at any level.`}let Q=G.winningDecision,Y=Q.source.name||Q.source.type,J=`Feature "${G.featureId}" is ${G.finalState}.
|
|
215
|
+
`,$Z=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet"),AZ=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet-adopted"),DZ=(Z)=>!!Z&&typeof Z.replaceSync==="function",c6=()=>{let Z=globalThis,Q=Z[$Z];if(DZ(Q))return Q;let J=globalThis.CSSStyleSheet;if(typeof J!=="function")return null;try{let Y=new J;if(!DZ(Y))return null;return Y.replaceSync(zZ),Z[$Z]=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[AZ];if(G&&X.includes(G))return;let j=c6();if(!j)return;try{J.adoptedStyleSheets=[...X,j],J[AZ]=j}catch{}},S1="tts-word",T1="tts-sentence",d9=(Z)=>`annotation-${Z}`,C9=(Z)=>{let Q=CSS.highlights.get(Z);if(Q)return Q;let J=new Highlight;return CSS.highlights.set(Z,J),J},V0=(Z,Q)=>{let J=CSS.highlights.get(Z);if(!J)return;for(let Y of Q)J.delete(Y)},FZ=(Z)=>{let Q=Z[0]?.startContainer;if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:d(Q)},G9={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 b1,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=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(Z),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]});for(let Q of document.querySelectorAll("pie-theme"))this.themeObserver.observe(Q,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(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((q)=>q.trim()).filter(Boolean),j=Number(G[0]),B=Number(G[1]),U=Number(G[2]);if(Number.isFinite(j)&&Number.isFinite(B)&&Number.isFinite(U))return[j,B,U]}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 U=B/255;return U<=0.03928?U/12.92:((U+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,U=G9.override,q=U?this.parseColor(U.color)||Q:this.parseColor(G?.getPropertyValue("--pie-missing"))||Q,K=U?[Math.max(0.3,Math.min(0.95,U.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],$=K[K.length-1],D=-1/0;for(let u of K){let Q9=this.blend(q,j,u),H9=this.contrastRatio(Q9,j),_9=this.contrastRatio(Q9,B),M9=H9*1.2+_9*0.8;if(H9>=1.25&&_9>=2.4){$=u;break}if(M9>D)D=M9,$=u}let z=Math.max(0.24,Math.min(0.85,$*0.55)),M=Math.max(0.55,Math.min(0.95,$+0.2)),O=Math.max(0.22,Math.min(0.6,$*0.45)),F=B,w=this.blend(F,j,M),R=this.contrastRatio(w,j),b=this.relativeLuminance(j)>0.45?[0,0,0]:[255,255,255],S=R>=1.35?F:b,h=`rgba(${q[0]}, ${q[1]}, ${q[2]}, ${$})`,C=`rgba(${q[0]}, ${q[1]}, ${q[2]}, ${z})`,U9=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${M})`,K9=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${O})`;return{wordHighlight:h,sentenceHighlight:C,wordUnderline:U9,wordShadow:K9}}applyAdaptiveTTSStyle(Z){if(typeof document>"u")return;if(Z)this.ttsStyleSource=Z,G9.source=Z;let Q=Z??(G9.source?.isConnected?G9.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;C9(S1),C9(T1);for(let Z of Object.values(q0))C9(d9(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=zZ,document.head.appendChild(Z)}highlightTTSWord(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(FZ(Z)),this.clearTTSWord();let Q=C9(S1);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(FZ(Z)),this.clearTTSSentence();let Q=C9(T1);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:d(G);for(let G of Z){let j=G.commonAncestorContainer,B=m(j)?j:X(j);if(!B)continue;let U=[],q=X(G.startContainer),K=X(G.endContainer);for(let $ of[q,K]){let D=$;while(D){if(D.matches?.(Y))U.push(D);D=d(D)}}if(!m(B)&&B.matches?.(Y))U.push(B);U.push(...Array.from(B.querySelectorAll(Y)));for(let $ of new Set(U)){try{if(!G.intersectsNode($)&&!t($,q)&&!t($,K))continue}catch{continue}$.setAttribute(Q,"true"),J.add($)}}}clearTTSWord(){if(!this.supported)return;V0(S1,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;V0(T1,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(),G9.source===this.ttsStyleSource)G9.source=null;this.ttsStyleSource=null}addAnnotation(Z,Q=q0.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,Y=Z.cloneRange();K0(Y.startContainer);let X={id:J,range:Y,type:i.ANNOTATION,color:Q,timestamp:Date.now()};if(this.annotations.set(J,X),this.supported)C9(d9(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)V0(d9(Q.color),[Q.range]);this.annotations.delete(Z)}clearAnnotations(){if(this.supported)for(let Z of this.annotations.values())V0(d9(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)V0(d9(Y),[J.range]),C9(d9(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}highlightRange(Z,Q,J=q0.YELLOW){if(!this.supported)return;switch(Q){case i.TTS_WORD:this.highlightTTSWord([Z]);break;case i.TTS_SENTENCE:this.highlightTTSSentence([Z]);break;case i.ANNOTATION:this.addAnnotation(Z,J);break}}clearHighlights(Z){if(!this.supported)return;switch(Z){case i.TTS_WORD:this.clearTTSWord();break;case i.TTS_SENTENCE:this.clearTTSSentence();break;case i.ANNOTATION:this.clearAnnotations();break}}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}isSupported(){return this.supported}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;G9.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(),G9.override?.owner===this)G9.override=null;this.themeObserver?.disconnect(),this.themeObserver=null}}import{applyMediaFragment as R4,enforceMediaFragment as E4}from"@pie-players/pie-players-shared/media";import{createPieLogger as C4,isTtsDebugEnabled as R3}from"@pie-players/pie-players-shared/pie";import{isUnsupportedMediaAssetVersion as d6,normalizeMediaFragment as l6,normalizeMediaSources as i6,trimmedOrUndefined as s6}from"@pie-players/pie-players-shared/media";function HZ(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(d6(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=i6(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:l6(Q.fragment),label:s6(J.label)}}var n6="[data-pie-shell-root]";var _Z=(Z)=>Z?b0(Z,n6):null;var S0="en-US",y1=(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},x1=(Z,Q={})=>{let J=Q.boundary!==void 0?Q.boundary:_Z(Z);return(J?y1(Z,J):void 0)||Q.contentLanguage?.trim()||void 0},MZ=(Z,Q={})=>x1(Z,Q)??S0;var y=(Z)=>Z.trim().replace(/\s+/g," "),wZ=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,k1=(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},l9=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(k1(J))return!0;if(Q&&J===Q)break;J=c(J)}return!1},LZ="data-tts-suppress",PZ=new Set(["computer-read-aloud","all"]),OZ=new Set([...PZ,"screen-reader"]),NZ=new Set,r6=(Z)=>{let Q=Z.getAttribute?.(LZ);if(Q===null||Q===void 0)return!1;let J=Q.trim().toLowerCase();if(PZ.has(J))return!0;if(OZ.has(J))return!1;if(!NZ.has(J))NZ.add(J),console.warn(`[tts] ${LZ}="${Q}" is not one of ${Array.from(OZ).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},T0=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(r6(J))return!0;if(Q&&J===Q)break;J=c(J)}return!1},A9=(Z,Q)=>l9(Z,Q)||T0(Z),f1=(Z,Q)=>{if(typeof Z.intersectsNode!=="function")return{text:Z.toString(),filtered:!1};let J=[],Y=!1;for(let X of R9(Q))if(X9(Z,X))if(A9(X,Q))Y=!0;else J.push(I1(X,Z));return{text:J.join(""),filtered:Y}},I1=(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)},A0=(Z,Q,J)=>{let Y=null,X=null;for(let G of R9(Q)){if(A9(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 X9(Z,Q);return U0(Z,Y.node,Y.offset)&&U0(Z,X.node,X.offset)},v1=(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((K)=>K.isWordLike!==!1&&K.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},b9=(Z,Q)=>{let J=new Map;if(typeof document>"u")return{text:"",map:J};let Y=[],X=0,G=!0,j=!1,B=null,U=null;for(let K of R9(Z))if(c(K)&&!A9(K,Z)){let D=K.textContent||"",z=D.match(/\S/),M=z?z[0]:null;if(!G&&!j&&v1(U,M,Q)){if(Y.push(" "),B)J.set(X,B);X++,j=!0}for(let O=0;O<D.length;O++){let F=D[O],w=/\s/.test(F);if(G){if(!w)G=!1,Y.push(F),J.set(X,{node:K,offset:O}),B={node:K,offset:O},X++,j=!1,U=F}else if(w){if(!j)Y.push(" "),J.set(X,{node:K,offset:O}),B={node:K,offset:O},X++;j=!0}else Y.push(F),J.set(X,{node:K,offset:O}),B={node:K,offset:O},X++,j=!1,U=F}}let q=Y.join("").trimEnd();while(J.has(q.length))J.delete(q.length);return{text:q,map:J}};var o6=/^\s*<speak[\s/>]/i,x0=(Z)=>o6.test(Z),a6=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),RZ=new Set(["audio","phoneme"]),CZ=(Z)=>Z.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),y0=(Z,Q,J)=>{for(let Y=0;Y<Q.length;Y++)Z.push({char:Q[Y],rawOffset:J===null?null:J+Y})},t6=(Z,Q,J)=>{let Y=Q.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!Y)return 0;return y0(Z,CZ(Y[0]),J),Y[0].length},EZ=(Z)=>{Z.push({char:" ",rawOffset:null})},e6=(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}},Z7=(Z)=>{return Z.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},Q7=(Z,Q)=>{let J=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),Y=Z.match(J);return CZ(Y?.[2]??Y?.[3]??"")||null},k0=(Z)=>{let Q=[],J=!1,Y=!1,X=0;while(X<Z.length){let j=Z[X];if(j!=="<"){if(j==="&"){let D=t6(Q,Z,X);if(D>0){X+=D;continue}}y0(Q,j,X),X++;continue}let B=Z.indexOf(">",X+1);if(B<0){y0(Q,j,X),X++;continue}Y=!0;let U=Z.slice(X,B+1),q=Z7(U),K=/^<\s*\//.test(U),$=/\/\s*>$/.test(U);if(!K&&q==="sub"){let D=Q7(U,"alias");if(!D){J=!0,X=B+1;continue}y0(Q,D,null);let z=Z.toLowerCase().indexOf("</sub>",B+1);X=z>=0?z+6:B+1;continue}if(!K&&q==="break"){EZ(Q),X=B+1;continue}if(!K&&RZ.has(q)){if(J=!0,$){X=B+1;continue}}if(q&&!a6.has(q)&&!RZ.has(q)&&q!=="break"&&q!=="sub")J=!0;if(!K&&(q==="p"||q==="s"))EZ(Q);X=B+1}let G=e6(Q);return{spokenText:y(G.text),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:Y}};var J7=wZ(),Y7=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),X7=(Z)=>{let Q=Z.toLowerCase();return Y7.get(Q)||Q},u1=(Z)=>{let Q=[];for(let J of Z.matchAll(J7)){let Y=J[0],X=J.index??0;Q.push({text:Y,normalized:X7(Y),start:X,end:X+Y.length})}return Q},G7=(Z)=>u1(Z).map((Q,J)=>({...Q,id:`speech-token-${J}`,sourceStart:Q.start,sourceEnd:Q.end,coordinateSystem:"normalized-speech"})),S9=(Z)=>{let Q=k0(Z.speechText);return{speechText:Z.speechText,spokenText:Q.spokenText,tokens:G7(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},p1=(Z)=>Boolean(Z&&/^<[^>]+>$/.test(Z.trim())),i9=(Z)=>{if(!Z||p1(Z))return null;return S9({speechText:Z}).tokens[0]?.normalized??null},j7=(Z,Q)=>Z.find((J)=>J.start<=Q&&Q<J.end)||null,B7=(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},h1=(Z,Q,J)=>{if(Q===null)return null;let Y=j7(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}},m1=(Z,Q)=>Boolean(Z&&Q&&Z.token.normalized===Q),g1=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||p1(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=i9(Z.boundaryWord),Y=h1(Z.tokenization,B7(Z.tokenization,Z.position),Q),X=h1(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(m1(Y,J))return{...Y,confidence:1};if(m1(X,J))return{...X,confidence:1};if(J)return null;return Z.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||X:X||Y},bZ=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||p1(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=i9(Z.boundaryWord),Y=h1(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(m1(Y,J))return{...Y,confidence:1};if(J)return null;return Y};var W7=[{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}],U7=(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:10});for(let X of W7){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},K7=(Z,Q)=>{let J=U7(Z,Q).sort((U,q)=>Z[U.spokenStartToken].start-Z[q.spokenStartToken].start||Q[U.visibleToken].start-Q[q.visibleToken].start),Y=Array(J.length).fill(0),X=Array(J.length).fill(-1);for(let U=0;U<J.length;U++){let q=J[U];Y[U]=q.score;for(let K=0;K<U;K++){let $=J[K];if($.spokenEndToken<=q.spokenStartToken&&$.visibleToken<q.visibleToken){let D=q.spokenStartToken-$.spokenEndToken,z=q.visibleToken-$.visibleToken-1,M=Math.max(0,Math.abs(D-z)-2),O=Y[K]+q.score-M;if(O>Y[U])Y[U]=O,X[U]=K}}}let G=-1;for(let U=0;U<Y.length;U++)if(G<0||Y[U]>Y[G])G=U;if(G<0)return[];let j=[],B=G;while(B>=0)j.unshift(J[B]),B=X[B];return j.map((U)=>{let q=Z[U.spokenStartToken],K=Z[U.spokenEndToken-1],$=Q[U.visibleToken];return{spokenStart:q.start,spokenEnd:K.end,visibleStart:$.start,visibleEnd:$.end,score:U.score}})},V7=(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/10;return Math.min(1,Y*X)},f0=(Z)=>{let Q=S9({speechText:Z.speechText}),J=y(Z.visibleText),Y=Q.tokens,X=u1(J),G=Q.unsupportedSemantic?[]:K7(Y,X),j=V7(G,Y,X),B=Q.spokenText===J&&Q.spokenText.length>0,U=G.length===1&&G[0].score===10&&Y.length<=2&&X.length<=2,q=Q.unsupportedSemantic?"region-fallback":B?"exact-word":G.length>=2||U?j>=0.12?"anchor-span":"region-fallback":"region-fallback";return{speech:Q,visibleText:J,playbackMode:q,anchors:G,confidence:j}},SZ=(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 q7=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"]]]),$7=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),TZ=new Map([["2",["squared"]],["3",["cubed"]]]),A7=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),D7=(Z)=>Z.replace(/\s+/g," ").trim(),T9=(Z)=>(Z.localName||Z.tagName||"").toLowerCase(),F7=(Z)=>Z.nodeType===Node.ELEMENT_NODE,s9=(Z)=>Array.from(Z.childNodes).filter(F7),c1=(Z)=>D7(Z.textContent||""),j9=(Z,Q)=>({type:"element-range",quality:Q,element:Z}),z7=(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"}},H7=(Z,Q)=>{if(Q==="operator"){if(Z==="−")return"-";return Z}return Z.toLowerCase()},_7=(Z,Q,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return TZ.get(Z)??[];if(Z==="|")return["absolute value"];if(Q==="operator")return q7.get(Z)||[];return[]},y9=(Z)=>{let Q=Z.normalized??H7(Z.text,Z.kind||"unknown");return{id:`math-token-${Z.state.nextId++}`,kind:Z.kind,role:Z.role,text:Z.text,normalized:Q,spokenAliases:_7(Z.text,Z.kind,Z.role),sourceElement:Z.sourceElement,path:Z.path,target:Z.target||j9(Z.sourceElement,"element-range"),optional:Z.optional}},x9=(Z,Q,J="tokens")=>{Z[J].push(Q)},yZ=(Z,Q,J)=>{s9(Z).forEach((Y,X)=>B9(Y,Q,`${J}/${T9(Y)}[${X}]`))},M7=(Z,Q,J)=>{let Y=s9(Z);if(Y[0])B9(Y[0],Q,`${J}/numerator`);if(x9(Q,y9({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:Z,path:J,target:j9(Z,"element-range")})),Y[1])B9(Y[1],Q,`${J}/denominator`)},L7=(Z,Q,J)=>{let Y=Z.getAttribute("open")||"(",X=Z.getAttribute("close")||")";x9(Q,y9({state:Q,kind:"operator",role:Y==="|"?"absolute-value-fence":"open-fence",text:Y,sourceElement:Z,path:`${J}/open`,target:j9(Z,"element-range")})),yZ(Z,Q,J),x9(Q,y9({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Z,path:`${J}/close`,target:j9(Z,"element-range")}))},O7=(Z,Q,J)=>{let Y=s9(Z);if(Y[0])B9(Y[0],Q,`${J}/base`);let X=Y[1];if(!X)return;let G=c1(X);if(TZ.has(G)){x9(Q,y9({state:Q,kind:"structure",role:"superscript",text:G,normalized:G,sourceElement:X,path:`${J}/exponent`,target:j9(Z,"element-range")}));return}B9(X,Q,`${J}/exponent`)},N7=(Z,Q,J,Y)=>{x9(Q,y9({state:Q,kind:"structure",role:Y,text:c1(Z)||Y,normalized:`\x00${Y}`,sourceElement:Z,path:J,target:j9(Z,"element-range")}))},w7=(Z,Q,J)=>{let Y=0;for(let X of s9(Z)){if(T9(X)==="mtr"||T9(X)==="mlabeledtr")Y++,x9(Q,y9({state:Q,kind:"layout",role:"table-row",text:`row-${Y}`,normalized:`row-${Y}`,sourceElement:X,path:`${J}/row[${Y}]`,target:j9(X,"region-fallback")}),"layoutTargets");B9(X,Q,`${J}/${T9(X)}[${Y}]`)}},P7=(Z,Q,J)=>{let Y=c1(Z);if(!Y)return;let X=z7(T9(Z)),G=X==="operator"?$7.get(Y):void 0,j=G??(X==="operator"&&(Y==="("||Y===")")?"grouping-fence":X);x9(Q,y9({state:Q,kind:X,role:j,text:Y,sourceElement:Z,path:J,target:G&&Z.parentElement?j9(Z.parentElement,"region-fallback"):void 0,optional:Boolean(G)||j==="grouping-fence"}))},B9=(Z,Q,J)=>{let Y=T9(Z);switch(Y){case"annotation":case"annotation-xml":return;case"semantics":{let X=s9(Z).find((G)=>{let j=T9(G);return j!=="annotation"&&j!=="annotation-xml"});if(X)B9(X,Q,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":P7(Z,Q,J);return;case"mfrac":M7(Z,Q,J);return;case"msup":O7(Z,Q,J);return;case"mfenced":L7(Z,Q,J);return;case"mtable":w7(Z,Q,J);return;case"mphantom":return;case"maction":{let X=s9(Z)[0];if(X)B9(X,Q,`${J}/action`);return}default:{let X=A7.get(Y);if(X){N7(Z,Q,J,X);return}yZ(Z,Q,J)}}},xZ=(Z)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return B9(Z,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:j9(Z,"region-fallback")}};var kZ=(Z)=>{if(!Z.boundary)return null;return Z.alignment.segments.find((J)=>J.speechTokenIds.includes(Z.boundary.token.id))?.target||null};var R7=(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},fZ=(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},E7=(Z,Q)=>{let J=[],Y=0;for(let X of Q){let G=R7(X);if(X.optional){let j=fZ(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=fZ(Z,Y,G);if(j>0){J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;break}Y++}}return J},C7=(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},b7=(Z)=>Z.map(({speechTokens:Q,math:J})=>({speechTokenIds:Q.map((Y)=>Y.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),IZ=(Z)=>{let Q=Z.minExactWordConfidence??0.95,J=E7(Z.speech.tokens,Z.math.tokens),Y=C7(J,Z.speech.tokens,Z.math.tokens)?1:0;return{segments:Y>=Q?b7(J):[],confidence:Y,fallbackTarget:Z.math.expressionTarget}};var n9=(Z)=>{let Q=S9({speechText:Z.speechText}),J=xZ(Z.mathElement);return{speech:Q,math:J,result:IZ({speech:Q,math:J})}};var vZ=(Z,Q)=>{let J=bZ({tokenization:Z.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return kZ({alignment:Z.result,boundary:J})},hZ=(Z,Q)=>{let J=i9(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 S7=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"]),T7=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"]),mZ=(Z)=>Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),y7=(Z)=>mZ(Z).replace(/"/g,"""),x7=(Z,Q)=>{let J=Z.toLowerCase(),Y=Q.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!T7.has(J))return!0;if(Y.includes("javascript:"))return!0;if(Y.includes("data:text/html"))return!0;return!1},k7=(Z)=>{let Q=Z.localName.toLowerCase();if(!S7.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"},uZ=(Z)=>{if(Z.nodeType===Node.TEXT_NODE)return mZ(Z.textContent||"");if(Z.nodeType===Node.COMMENT_NODE)return"";if(Z.nodeType!==Node.ELEMENT_NODE)return null;let Q=Z;if(!k7(Q))return null;let J=Q.localName.toLowerCase(),Y=[];for(let j of Array.from(Q.attributes)){let B=j.name.toLowerCase();if(x7(B,j.value))continue;if(B==="xmlns"&&j.value!=="http://www.w3.org/1998/Math/MathML")return null;Y.push(`${B}="${y7(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=uZ(j);if(B===null)return null;X.push(B)}let G=Y.length>0?` ${Y.join(" ")}`:"";return`<${J}${G}>${X.join("")}</${J}>`},f7=(Z)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Z,"application/xml");return null},r9=(Z)=>{let Q=String(Z||"").trim();if(!Q)return null;let J=f7(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 uZ(Y)};var gZ=(Z)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Z}),d1=(Z)=>Z.classList?.contains("MathJax")||Z.tagName?.toLowerCase()==="mjx-container",cZ=(Z)=>Z.tagName?.toLowerCase()==="mjx-assistive-mml",l1=(Z)=>{let Q=Z.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},I7=(Z)=>{let Q=Z.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},v7=(Z)=>{return E9(Z,"mjx-assistive-mml math")?.outerHTML||null},h7=(Z)=>{if(Z.tagName.toLowerCase()==="math")return r9(Z.outerHTML);let Q=I7(Z);if(Q){let J=r9(Q);if(J)return J}if(d1(Z)){let J=v7(Z);if(J){let Y=r9(J);if(Y)return Y}}return null},m7=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),u7=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),p7=(Z,Q)=>{let J=c(Z),Y=null;while(J&&J!==Q){let X=(J.getAttribute("role")||"").toLowerCase(),G=J.tagName.toUpperCase();if(m7.has(G)||u7.has(X)){Y=J;break}J=c(J)}return Y||Q},g7=(Z)=>Boolean(typeof Z.querySelector==="function"&&E9(Z,"math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Z.tagName?.toLowerCase()==="math"||Z.hasAttribute?.("data-mathml")||d1(Z),k9=(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++},dZ=(Z,Q)=>{if(Z.inLeadingWhitespace||Z.lastCharWasWhitespace||Z.chars.length===0)return!1;let J=Z.chars[Z.chars.length-1];return v1(J,Q,Z.options)},lZ=(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],U=/\s/.test(B);if(Z.inLeadingWhitespace){if(!U)Z.inLeadingWhitespace=!1,k9(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1;continue}if(U){if(!Z.lastCharWasWhitespace)k9(Z," ",{node:Q,offset:j});Z.lastCharWasWhitespace=!0;continue}if(!G&&dZ(Z,B))k9(Z," ",{node:Q,offset:j});k9(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1}},c7=(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)||null,j=G?.node||Z.lastMapped?.node||null,B=G?.offset??Z.lastMapped?.offset??0,U=G?{node:G.node,offset:G.offset}:j?{node:j,offset:B}:null;if(Z.inLeadingWhitespace){if(X)continue;Z.inLeadingWhitespace=!1}if(X){if(!Z.lastCharWasWhitespace)k9(Z," ",U);Z.lastCharWasWhitespace=!0;continue}if(J===0&&dZ(Z,Y))k9(Z," ",U);if(k9(Z,Y,U),Z.lastCharWasWhitespace=!1,G)Z.map.set(Z.position-1,{node:G.node,offset:G.offset}),Z.lastMapped={node:G.node,offset:G.offset};else if(j)Z.map.set(Z.position-1,{node:j,offset:B})}},d7=(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(l1(G))return;for(let j of Array.from(G.childNodes))Y(j)};return Y(Q.documentElement),y(J.join(" "))},l7=(Z,Q)=>{let J=new Map,Y=d1(Z)?E9(Z,"mjx-assistive-mml math"):null;if(!Y)return J;let X=[],G=(B)=>{if(B.nodeType===3){let U=B.textContent||"";for(let q=0;q<U.length;q++)if(!/\s/.test(U[q]))X.push({node:B,offset:q});return}if(B.nodeType!==1||l1(B))return;for(let U of $9(B))G(U)};G(Y);let j=0;for(let B=0;B<Q.length;B++){if(/\s/.test(Q[B]))continue;let U=X[j];if(U?.node.textContent?.[U.offset]!==Q[B])return new Map;J.set(B,U),j++}return j===X.length?J:new Map},i7=(Z,Q,J)=>{let Y=gZ(J),X=(B)=>{if(A9(B,Z))return;if(B.nodeType===3){lZ(Y,B);return}if(B.nodeType!==1)return;let U=B;if(cZ(U)||l1(U))return;for(let q of $9(U))X(q)};X(Z),iZ(Y);let G=y(Y.chars.join(""));if(G)return{text:G,map:Y.map};let j=d7(Q);if(!j)return b9(Z,J);return{text:j,map:l7(Z,j)}},iZ=(Z)=>{while(Z.chars.length>0&&/\s/.test(Z.chars[Z.chars.length-1]))Z.chars.pop(),Z.position--,Z.map.delete(Z.position)},pZ=(Z,Q,J)=>{let Y=gZ(Q),X=[],G=0,j,B=!1,U=()=>{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},q=($)=>{if(A9($,Z))return;if(J&&!X9(J,$))return;if($.nodeType===3){let M=p7($,Z);if(j&&M!==j)U();j=M;let O=$;lZ(Y,O,J?.startContainer===O?J.startOffset:void 0,J?.endContainer===O?J.endOffset:void 0);return}if($.nodeType!==1)return;let D=$;if(cZ(D))return;let z=h7(D);if(z&&(!J||A0(J,D,Z))){U();let M=i7(D,z,Q);c7(Y,M);let O=y(M.text);X.push({type:"math",mathml:z,fallbackText:O,sourceElement:D}),G=Y.chars.length,B=!0;return}for(let M of $9(D))q(M)};for(let $ of $9(Z))q($);iZ(Y),U();let K=Y.chars.join("");while(Y.map.has(K.length))Y.map.delete(K.length);return{visibleText:K,map:Y.map,chunks:X,containsMathMarkup:B}},D9=(Z,Q,J)=>{if(J)return pZ(Z,Q,J);if(!g7(Z)){let{text:Y,map:X}=b9(Z,Q);return{visibleText:Y,map:X,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return pZ(Z,Q)};import{createPieLogger as n7,isTtsDebugEnabled as r7}from"@pie-players/pie-players-shared/pie";var I0=n7("tts-math-speech",r7),sZ=Promise.resolve(),o7=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",a7=(Z)=>{let Q=null,J=!1;return(Y)=>{if(!Q){aZ(Y);let X=Z();Q=X,X.catch((G)=>{if(Q===X)Q=null;if(J){I0.debug("speech-rule-engine failed to load again",G);return}J=!0,I0.warn("speech-rule-engine failed to load; math reads as its visible text until a later read loads it.",G)})}return Q}},t7=a7(()=>import("./chunks/sre-engine-jd8cc08x.js").then(({default:Z})=>{if(!Z||typeof Z.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Z})),i1=(Z)=>{let Q=null;return()=>{return Q??=t7(W9(Z)?.engineOptions),Q}},e7=(Z)=>Z==="en"?"clearspeak":"mathspeak",nZ=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),rZ=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,W9=(Z)=>{if(!nZ(Z))return;let Q=rZ(Z.domain),J=rZ(Z.style),Y=nZ(Z.engineOptions)?Z.engineOptions:void 0;if(!Q&&!J&&!Y)return;return{...Q?{domain:Q}:{},...J?{style:J}:{},...Y?{engineOptions:Y}:{}}},Z4=async(Z,Q,J,Y)=>{let X=o7(Q),G=W9(Y),j=G?.engineOptions||{};await Z.setupEngine?.({...oZ(j),...j,locale:X,domain:G?.domain||e7(X),style:G?.style||"default",modality:"speech",markup:J}),await Z.engineReady?.()},Q4=async(Z)=>{let Q=sZ.then(Z,Z);return sZ=Q.then(()=>{return},()=>{return}),Q},tZ=async(Z,Q,J,Y,X)=>Q4(async()=>{return await Z4(Z,J,Y,X),Z.toSpeech(Q)}),J4=(Z)=>Z.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),Y4=async(Z,Q,J,Y)=>{try{let X=J4(await tZ(Z,Q,J,"ssml",Y));return X.includes("<speak")?X:null}catch(X){return I0.debug("math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},o9=async(Z,Q={})=>{if(!Z.some((q)=>q.type==="math"))return{speechText:y(Z.map((q)=>q.type==="text"?q.text:q.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let J=null,Y=!1,X=!1,G=Q.loadSre||i1(Q.mathSpeech),j=[];for(let q of Z){if(q.type==="text"){j.push(q.text);continue}try{if(!J)J=await G();let K=y(await tZ(J,q.mathml,Q.language,"none",Q.mathSpeech));if(K){j.push(K),Y=!0;continue}X=!0,j.push(q.fallbackText)}catch(K){X=!0,I0.debug("math speech generation failed; using visible fallback",{message:K instanceof Error?K.message:String(K)}),j.push(q.fallbackText)}}let B=y(j.join(" ")),U;if(Q.produceSsml&&J&&Y&&Z.length===1&&Z[0].type==="math")U=await Y4(J,Z[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:Y,usedFallback:X,ssml:U}};var X4=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",G4="sre-v1",j4=256,s1=(Z)=>{if(Array.isArray(Z))return`array:[${Z.map(s1).join(",")}]`;if(Z&&typeof Z==="object")return`object:{${Object.entries(Z).sort(([Q],[J])=>Q.localeCompare(J)).map(([Q,J])=>`${JSON.stringify(Q)}:${s1(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)}`},eZ=(Z,Q,J,Y)=>`${G4}\x00${X4(Z)}\x00${Q?"ssml":"plain"}\x00${s1(J??null)}\x00${Y}`,n1=(Z={})=>{let Q=Math.max(1,Z.maxEntries??j4),J=Z.resolve??((G,j)=>o9([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=W9(j.mathSpeech),U=j.produceSsml===!0,q=eZ(j.language,U,B,G.mathml),K=Y.get(q);if(K)return Y.delete(q),Y.set(q,K),K;let $=await J(G,{...j,mathSpeech:B});if($.usedFallback)return $;if(U&&$.ssml&&Q>1)X(eZ(j.language,!1,B,G.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(q,$),$}};var Z3=(Z,Q)=>{let J=i9(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=g1({tokenization:Z.catalogAlignment?.speech??S9({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 f9=(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 J3=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),r1="mi,mn,mo,mtext",Y3="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",X3=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),G3=(Z)=>{if(Z.type==="text-range")return Z.node.parentElement;return Z.element},v0=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},Q3=(Z)=>{if(!Z)return!1;if(v0(Z))return!1;return!l9(Z)},j3=(Z)=>{let Q=Z.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},o1=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},B3=(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=J3.get(Z[J].localName.toLowerCase());if(!Y)return!1;if(Q[J].localName.toLowerCase()!==Y)return!1}return!0},B4=(Z,Q)=>{if(!Z)return null;if(!J3.has(Z.localName.toLowerCase()))return null;if(Q.querySelector(X3))return null;let J=o1(Z),Y=Q.querySelector("mjx-math");if(!J||!Y)return null;let X=Array.from(J.querySelectorAll(r1)),G=X.indexOf(Z);if(G<0)return null;let j=Array.from(Y.querySelectorAll(Y3));if(!B3(X,j))return null;let B=j[G];if(!B||!j3(B))return null;return B},W3=(Z)=>{let Q=v0(Z);if(Q){if(Q.querySelector(X3))return"expression";let X=o1(Z)??Z,G=Q.querySelector("mjx-math");if(!G)return"expression";let j=Array.from(X.querySelectorAll(r1)),B=Array.from(G.querySelectorAll(Y3));if(!B3(j,B))return"expression";return B.some((U)=>j3(U))?"token":"expression"}let J=o1(Z)??Z;return Array.from(J.querySelectorAll(r1)).some((X)=>!l9(X))?"token":"expression"},a1=(Z)=>{let Q=G3(Z),J=v0(Q);if(J){let Y=B4(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(!Q3(Z.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Z.node,startOffset:Z.startOffset,endOffset:Z.endOffset}}if(!Q3(Z.element))return null;return{type:"element",quality:Z.quality==="region-fallback"?"expression":"semantic-token",element:Z.element}},U3=a1,K3=()=>{let Z=new WeakMap;return(Q)=>{let J=G3(Q),Y=v0(J);if(!J||!Y)return a1(Q);if(Z.has(J))return Z.get(J)??null;let X=a1(Q);return Z.set(J,X),X}};var V3=(Z,Q,J,Y=Z.mathAlignments,X=U3)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let G=null;for(let j of Y){let B=vZ(j.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:J.word})||hZ(j.alignment,{boundaryWord:J.word});if(!B)continue;let U=X(B);if(!U)continue;if(U.quality==="semantic-token")return U;G??=U}return G};var F9=(Z)=>Z.node.getRootNode?.()??Z.node,q3=(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}},t1=(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(F9(X)!==F9(Y)){let G=F9(Y);X=Y;for(let j=Q+1;j<J;j++){let B=Z.get(j);if(B&&F9(B)===G)X=B}}return q3(Y,X)},z9=(Z,Q,J)=>{if(!Z||typeof document>"u"||J<=Q)return[];let Y=Z.get(Q);if(!Y)return[];let X=F9(Y),G=!1;for(let K=Q+1;K<J&&!G;K++){let $=Z.get(K);if($&&F9($)!==X)G=!0}if(!G){let K=t1(Z,Q,J);return K?[K]:[]}let j=[],B=null,U=null,q=()=>{if(B&&U){let K=q3(B,U);if(K)j.push(K)}B=null,U=null};for(let K=Q;K<J;K++){let $=Z.get(K);if(!$)continue;if(B&&F9(B)!==F9($))q();if(!B)B=$;U=$}return q(),j};var $3=(Z,Q)=>{if(!Z.catalogAlignment||Q.chunkSpokenStart===null)return null;let J=SZ(Z.catalogAlignment,Q.chunkSpokenStart);if(!J)return null;let Y=z9(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 W4=(Z)=>{let Q=z9(Z.visibleMap,0,Z.visibleText.length);return Q.length>1?Q:void 0},U4=(Z)=>Z.regionRange?{type:"range",quality:"region",range:Z.regionRange,ranges:W4(Z)}:Z.regionElement?{type:"element",quality:"region",element:Z.regionElement}:null,A3=(Z,Q=Z.chunk.mathAlignments)=>{if(Q.length!==1)return null;let J=Q[0]?.alignment.result.fallbackTarget;return J?Z.renderedMathTargetResolver(J):null},K4=(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)=>X9(Y,J));if(Z.type==="element")return t(Z.element,J);return t(d(Z.node),J)}catch{return!1}})},D3=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),F3=(Z)=>Z.length===1?Z[0].element:null,V4=(Z,Q)=>Q.length>0&&Q.every(({element:J})=>Z.mathCapabilityByElement.get(J)==="token"),z3=3,q4=(Z,Q,J)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:Y,endContainer:X}=Q.range;if(Y===X&&Y.nodeType===z3)return!1;return J.some(({element:j})=>Z.mathCapabilityByElement.get(j)==="token"&&j.contains(Y)&&j.contains(X))},H3=(Z)=>Z?.type==="range"&&l9(Z.range.startContainer),$4=(Z,Q)=>{if(!H3(Q))return null;let{startContainer:J,endContainer:Y,startOffset:X,endOffset:G}=Q.range;if(J!==Y||J.nodeType!==z3)return null;return Z.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:G})},A4=(Z,Q)=>({chunk:Z,regionTarget:U4(Z),renderedMathTargetResolver:K3(),mathCapabilityByElement:new Map(Z.mathAlignments.map(({element:J})=>[J,Q?W3(J):"expression"])),heldTokenByElement:new Map}),_3=(Z)=>{let Q=Z.mathTokenHighlighting!==!1,J=new Map(Z.chunks.map((Y)=>[Y.id,A4(Y,Q)]));return{chunks:Z.chunks,resolveInitial(Y){let X=J.get(Y);if(!X)return D3();let G=X.chunk.mathAlignments,j=G.length===1?G[0].element:null,B=j?X.mathCapabilityByElement.get(j):null;if(B==="expression")return f9({semanticTarget:null,expressionTarget:A3(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return f9({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:B==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(Y){let X=J.get(Y.chunkId);if(!X)return D3();let{chunk:G}=X,j=Z3(G,Y),B=$3(G,j),U=K4(B,G),q=(!B||U.length>0?V3(G,j,Y,U,X.renderedMathTargetResolver):null)||null,K=q?.quality==="semantic-token"?q:$4(X,B)??q,$=Q&&K&&K.quality!=="expression"?K:null,D=K&&K.quality==="expression"?K:null;if($){let z=F3(U);if(z)X.heldTokenByElement.set(z,$);return f9({semanticTarget:$,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}if(B&&!H3(B)&&(Q?!q4(X,B,U):U.length===0))return f9({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason});if(V4(X,U)){let z=F3(U),M=z?X.heldTokenByElement.get(z)??null:null;return f9({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 f9({semanticTarget:null,expressionTarget:D??A3(X,U),regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}}};var D4=(Z)=>{return Z.alignment?.speech.boundaryOffsetSpace??Z.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},F4=(Z)=>{if(Z.mathAlignments?.length)return Z.mathAlignments;if(Z.mathAlignment&&Z.sourceElement)return[{element:Z.sourceElement,alignment:Z.mathAlignment}];return[]},M3=(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:F4(J),offsetSpace:D4(J)}))};var z4=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),h0=(Z,Q)=>{let J=b0(Z,z4);if(J&&t(Q,J))return J;return Z};var I9=(Z,Q)=>{let J=Q?.useSentenceSegmenter!==!1;try{if(!J)throw Error("Segmenter disabled by policy");let B=globalThis.Intl?.Segmenter;if(typeof B==="function"){let U=new B(Q?.locale,{granularity:"sentence"}),q=Array.from(U.segment(Z)).map((K)=>({text:K.segment,offset:K.index})).filter((K)=>K.text.trim().length>0);if(q.length>0)return q}}catch{}let Y=/[^.!?]+(?:[.!?]+|$)/g,X=Z.match(Y)||[Z],G=[],j=0;for(let B of X){let U=Z.indexOf(B,j);if(U===-1)continue;G.push({text:B,offset:U}),j=U+B.length}return G.length>0?G:[{text:Z,offset:0}]},e1=(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},U=(q,K)=>{if(G>=0&&K-G<=Y){j=K;return}B();let $=q;while(K-$>Y){let z=Z.slice($,$+Y+1).search(/\s\S*$/),M=z>0?$+z:$+Y;X.push({text:Z.slice($,M).trimEnd(),offset:$}),$=M;while($<K&&/\s/.test(Z[$]))$++}if($<K)G=$,j=K};for(let q of I9(Z,J)){let K=q.text.search(/\S/);if(K===-1)continue;let $=q.offset+K;U($,q.offset+q.text.trimEnd().length)}return B(),X};var H4=(Z,Q)=>o9([Z],Q),_4=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",M4=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),L4=new Set(["heading","listitem","option","radio"]),O4=(Z)=>{if(Z.type!=="text"||!Z.sourceElement)return!1;let Q=Z.sourceElement.tagName.toUpperCase(),J=(Z.sourceElement.getAttribute("role")||"").toLowerCase();return M4.has(Q)||L4.has(J)},L3=async(Z)=>{let Q=Z.resolveMathSpeech??H4,J=i1(Z.mathSpeech),{visibleText:Y}=Z,X=[],G=0,j=(U)=>{let q=y(U),K=Y.indexOf(q,G),$=K>=0?K:G,D=$+q.length;return G=D,{start:$,end:D}},B=[];for(let U=0;U<Z.chunks.length;U++){let q=Z.chunks[U];if(q.type==="text"){let M=O4(q)?[{text:q.text,offset:0}]:I9(q.text,{locale:Z.language});for(let O of M){let F=y(O.text);if(!F)continue;let w=j(F);X.push({sourceChunkIndex:U,segment:{kind:"prose",spokenText:F,visibleText:F,visibleSpan:w}}),B.push(F)}continue}let K=j(q.fallbackText),$=await Q(q,{language:Z.language,produceSsml:Z.produceSsml,mathSpeech:Z.mathSpeech,loadSre:J}),D=!$.speechText,z=$.speechText||q.fallbackText;X.push({sourceChunkIndex:U,segment:{kind:"math",spokenText:z,mathml:q.mathml,fallbackText:q.fallbackText,visibleSpan:K,usedFallback:D,ssml:$.ssml}}),B.push(z)}return{segments:X,locale:_4(Z.language),visibleText:Y,plainSpeechText:y(B.join(" "))}};var N4=(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},Z8=async(Z)=>{let Q=D9(Z.contentRoot,Z.textProcessingOptions,Z.range),J=await L3({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 U=j?.type==="text"?j.sourceElement??Z.contentRoot:Z.contentRoot;return{segment:X,anchor:{sourceElement:U,regionElement:h0(U,Z.contentRoot),visibleMap:N4(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 w4=(Z,Q)=>{let J=f0({speechText:Z.spokenText,visibleText:Z.spokenText});return{speechText:Z.spokenText,visibleText:Z.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:t1(Q.visibleMap,0,Z.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Q.visibleMap}},O3=(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?n9({mathElement:J,speechText:Z.spokenText}):void 0}},P4=(Z,Q,J)=>{let Y=Q.sourceElement;return{speechText:J,visibleText:Z.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:Y?n9({mathElement:Y,speechText:J}):void 0,plainFallback:O3(Z,Q)}},Q8=(Z,Q={})=>Z.items.map(({segment:J,anchor:Y})=>{if(J.kind==="prose")return w4(J,Y);if(Q.format==="ssml"&&J.ssml)return P4(J,Y,J.ssml);return O3(J,Y)});function m0(Z){let Q=Z instanceof Error?Z:Error(String(Z));return Q.code="tts-start-failed",Q}var N3="pie-tts-control-handoff";var e=C4("tts-service",R3),P;(function(Z){Z.IDLE="idle",Z.LOADING="loading",Z.PLAYING="playing",Z.PAUSED="paused",Z.ERROR="error"})(P||(P={}));var v9=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,w3=(Z,Q={})=>{if(!Z)return Q;return{locale:"locale"in Z?v9(Z.locale):Q.locale,textNormalization:Z.textNormalization&&"locale"in Z.textNormalization?v9(Z.textNormalization.locale):Q.textNormalization,segmenter:Z.segmenter&&"locale"in Z.segmenter?v9(Z.segmenter.locale):Q.segmenter}},P3=(Z)=>("commonAncestorContainer"in Z),E3=(Z,Q)=>Z===Q||Z.startContainer===Q.startContainer&&Z.startOffset===Q.startOffset&&Z.endContainer===Q.endContainer&&Z.endOffset===Q.endOffset,b4=(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 E3(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};class J8{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=P.IDLE;resumeState=P.PLAYING;ttsConfig={};hostLocales={};readLocale=S0;disposed=!1;readinessGate=null;mathSpeechSource=null;currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Set;lastError=null;speakRunId=0;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";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=n1();constructor(){}clearPlaybackStartBarrier(Z=this.playbackStartBarrierCleanup){if(Z?.(),this.playbackStartBarrierCleanup===Z)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Z){if(this.playbackStartDeferredRunId!==Z||Z!==this.speakRunId)return;if(this.state===P.PAUSED)this.activeRecordedAudio?.element.pause(),this.provider?.pause();this.markPlaying();let Q=this.pendingPlaybackStartHighlights.splice(0);for(let J of Q)J()}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=()=>{try{this.notifyPlaybackStarted(Z)}finally{X?.()}};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===P.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(){let Z=this.state===P.LOADING||this.state===P.PLAYING||this.state===P.PAUSED,Q=++this.speakRunId;if(this.abandonRun(),Z)this.provider?.stop();return this.setState(P.LOADING),Q}markPlaying(){if(this.state===P.PAUSED){this.resumeState=P.PLAYING;return}this.setState(P.PLAYING)}assertNotDisposed(){if(this.disposed)throw m0(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=w3(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=w3(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 m0(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 t(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:!E3(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)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}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(x0(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 e1(Z,Y,{locale:this.readLocale})){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;J.onWordBoundary=X?(j,B,U)=>X(j,B+G.offset,U):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=e1(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=x1(Z,{contentLanguage:Q})??v9(this.providerOptions().lang_id);return{contentLanguage:J,locale:J??this.hostLocales.locale??this.hostLocales.textNormalization??S0}}getMathSpeechOptions(){if(this.mathSpeechSource)return W9(this.mathSpeechSource());return W9(this.providerOptions().mathSpeech)}buildPositionMap(Z,Q,J){this.normalizedToDOM.clear();let{text:Y,map:X}=b9(Z,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!R3())return;e.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:(()=>{for(let G=0;G<Math.min(Q.length,Y.length);G++)if(Q[G]!==Y[G])return{index:G,spokenChar:Q[G],normalizedChar:Y[G],spokenContext:Q.substring(Math.max(0,G-20),G+20),normalizedContext:Y.substring(Math.max(0,G-20),G+20)};return null})()}),e.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=(Y,X)=>{if(typeof Y==="number"&&Number.isFinite(Y))return Y;if(typeof Y==="string"&&Y.trim()){let G=Number(Y);return Number.isFinite(G)?G:X}return X};return{baseMs:J(Z.baseMs,280),units:{minor:J(Q.minor,0.65),section:J(Q.section,1),major:J(Q.major,1.35)},minMs:J(Z.minMs,120),maxMs:J(Z.maxMs,900)}}resolvePauseMsFromUnits(Z){let Q=this.getStructuralPauseProfile(),J=Math.max(0.25,Math.min(4,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)}isElementHidden(Z){return k1(Z)}getBoundaryStrength(Z){let Q=Number(Z.getAttribute("data-tts-break-ms"));if(Number.isFinite(Q)&&Q>0)return"major";let J=Z.tagName.toUpperCase();if(J.match(/^H[1-6]$/))return"major";let Y=(Z.getAttribute("role")||"").toLowerCase();if(Y==="heading")return"major";if(Y==="listitem"||Y==="row"||Y==="option"||Y==="radio"||J==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(Z).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(Z,Q){let J=c(Z),Y=null;while(J&&J!==Q){if(this.isElementHidden(J))return null;let G=Number(J.getAttribute("data-tts-break-ms"));if(Number.isFinite(G)&&G>0)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){if(typeof window<"u"){let U=window.getComputedStyle(J).display;if(U==="block"||U==="list-item"||U.startsWith("table")||U==="flex"||U==="grid")Y=J}}J=c(J)}if(!Y)return null;let X=this.getBoundaryStrength(Y);return{anchor:Y,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Z,Q,J,Y){let X=this.collectSpeechPlanBoundaries(Z,Q,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,J){let Y=new Map,{map:X}=b9(Z,this.getTextProcessingOptions(J)),G=this.createNodeStartOffsets(X),j=null;for(let B of R9(Z)){let U=c(B);if(U&&!this.isElementHidden(U)&&!T0(B)){let q=this.getBoundaryAnchor(B,Z),K=G.get(B);if(q&&K!==void 0&&q.anchor!==j&&K>0)Y.set(K,Math.max(Y.get(K)||0,q.units)),j=q.anchor}}return Y}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((U)=>U>0&&U<Z.length).sort((U,q)=>U-q),Y=[],X=0;for(let U of J){let q=Z.substring(X,U),K=q.match(/^\s*/)?.[0].length||0,$=q.match(/\s*$/)?.[0].length||0,D=X+K,z=U-$;if(z>D){let M=Z.substring(D,z);Y.push({text:M,startOffset:D,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(U)||0)})}X=U}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((U)=>U.text.trim().length>0)}segmentSentences(Z){return I9(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,U=Y.filter((K)=>K>j&&K<B);if(U.length===0){X.push(G);continue}let q=j;for(let K of[...U,B]){let $=J.substring(q,K),D=$.match(/^\s*/)?.[0].length||0,z=$.match(/\s*$/)?.[0].length||0,M=q+D,O=K-z;if(O>M)X.push({text:J.substring(M,O),startOffset:M,pauseMsAfter:0});q=K}}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+=Math.max(1,X.length+1),G})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let Z=0;for(let Q=0;Q<this.seekSegments.length;Q++)if(this.seekSegments[Q].startOffset<=this.currentBoundaryOffset)Z=Q;else break;return Z}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,U)=>{if(G?.(j,B,U),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;if(this.currentBoundaryOffset=G.startOffset,Y)this.runWhenPlaybackStarts(Q,()=>{this.highlightSentenceSegment(G.startOffset,G.text)});await this.speakWithinLimit(G.text,Q);let j=G.pauseMsAfter??0;if(j>0&&Q===this.speakRunId)await this.waitStructuralPause(j)}}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=z9(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=J?this.beginRun():null;if(J){try{await J}catch(j){if(Y===this.speakRunId)this.setState(P.IDLE);throw j}if(this.assertNotDisposed(),Y!==this.speakRunId)return}if(!this.provider){if(Y!==null)this.setState(P.IDLE);throw m0(Error("TTS service not initialized"))}let X=this.resolveReadLanguage(P3(Z)?Z.startContainer:Z,Q.language),G=P3(Z)?this.resolveRangeTarget(Z,Q,X):this.resolveElementTarget(Z,Q,X);if(!G){if(Y!==null)this.setState(P.IDLE);return}await this.speakContent(G.text,G.options,Y??this.beginRun())}isSuppressedTarget(Z){if(!T0(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=D9(Z,this.getTextProcessingOptions(J.locale)).visibleText.trim();if(!Y)return console.warn("[tts] the content to read holds no speakable text; nothing was spoken."),null;return{text:Y,options:{catalogId:Q.catalogId,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:Z}}}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=f1(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),U=j,q=B?.offset??0;if(B)U=B.text;else{let K=document.createRange();K.selectNodeContents(X),K.setEnd(Z.startContainer,Z.startOffset);let $=f1(K,X).text,D=y($);q=D.length+(/\s$/.test($)&&D?1:0)}return e.debug("selection offset calculation:",{selectedText:U,mapped:!!B,offset:q,rootTag:X.tagName}),{text:U,options:{catalogId:Q.catalogId&&A0(Z,X,X)?Q.catalogId:void 0,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:X,contentRange:Z,wordBoundaryOffset:q}}}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:U,usedCatalogSpoken:q,speechSource:K,speechMatchesVisibleText:$,speechChunks:D}=X;this.logResolvedSpeechContent({contentToSpeak:G,speechSource:K,catalogId:Q?.catalogId}),this.initializeSpeakTracking(B,Q);let z=$?this.resolveHighlightMode():"sentence";this.activeHighlightMode=z,this.activeWordBoundaryOffset=Q?.wordBoundaryOffset||0;let M=this.hasExplicitBreakSemantics(G),O=!!this.currentContentElement&&!q&&!M&&$;if(this.playbackChunks=D?.length?D:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):M||!$?[]:O&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,U,Q?.wordBoundaryOffset||0,Q?.language):this.createSeekSegmentsFromText(B),this.sentenceHighlightSegments=M?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:O,playbackSegments:this.seekSegments}),Y=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Q,highlightMode:z,shouldUsePlan:O,runId:J}),$)this.configureWordBoundaryHighlighting({highlightMode:z,wordBoundaryOffset:Q?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!Y)this.markPlaying();if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:O,runId:J,highlightMode:z,contentToSpeak:j,speechChunks:D}),J!==this.speakRunId)return;this.setState(P.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(P.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&&v9(J.locale)===Y.locale&&v9(J.textNormalization?.locale)===Y.textNormalization&&v9(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=D9(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||J,U=y(j);return e.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:U===B}}e.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:D9(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=[],Y="",X=()=>{let K=y(Y);if(Y="",!K)return;J.push({speechText:K,visibleText:K,sourceElement:null,speechMatchesVisibleText:!0})},G=Q.contentRange,j=(K)=>{let $=K.getAttribute("data-catalog-idref");if(!$)return null;if(G&&!A0(G,K,Z))return null;let D={type:"spoken",language:y1(K,Z)||Q.language,useFallback:!0,context:Q.catalogContext},z=this.catalogResolver.getAlternative($,{...D,form:"payload"}),M=z?.payload?HZ({payload:z.payload})??void 0:void 0,F=this.catalogResolver.getAlternative($,{...D,form:"content"})?.content;if(M===void 0&&F===void 0)return null;return{script:F,audio:M}},B=(K,$)=>{let D=U(K);if(D.length!==1)return null;let z=D[0],M=D9(z,this.getTextProcessingOptions(Q.language)).visibleText||y(z.textContent||""),O=(F)=>y(F).replace(/\s+/g,"");return O(M)===O($)?z:null},U=(K)=>{let $=KZ(K,"math");if(K.localName?.toLowerCase()==="math")return[K,...$];return $},q=(K)=>{if(A9(K,Z))return;if(K.nodeType===Node.TEXT_NODE){if(!G)Y+=` ${K.textContent||""}`;else if(X9(G,K))Y+=` ${I1(K,G)}`;return}if(K.nodeType!==Node.ELEMENT_NODE)return;let $=K,D=j($);if(D){X();let z=D9($,this.getTextProcessingOptions(Q.language)),M=z.visibleText||y(UZ($)),O=h0($,Z),F=D.script!==void 0?(()=>{let w=D.script,R=f0({speechText:w,visibleText:M}),b=B($,M),S=b?n9({mathElement:b,speechText:w}):void 0,h=S?void 0:U($).map((C)=>({element:C,alignment:n9({mathElement:C,speechText:w})}));return{speechText:w,visibleText:M,sourceElement:$,regionElement:O,speechMatchesVisibleText:y(w)===M,playbackMode:R.playbackMode,alignment:R,mathAlignment:S,mathAlignments:h,visibleMap:z.map}})():null;if(D.audio){J.push(F?{...F,audio:D.audio,plainFallback:F}:{speechText:M,visibleText:M,sourceElement:$,regionElement:O,speechMatchesVisibleText:!1,visibleMap:z.map,audio:D.audio});return}if(F)J.push(F);return}for(let z of $9($))q(z)};return q(Z),X(),J}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 Z8({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 U=B||Q,q=Q8(G,{format:X}),K=G.plainSpeechText;return{contentToSpeak:K,speechText:K,visibleText:U,highlightText:U,normalizedText:U,containsMathMarkup:!0,speechMatchesVisibleText:K===U,speechChunks:q}}logResolvedSpeechContent(Z){let Q=Z.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);e.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),e.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=z9(this.normalizedToDOM,j,j+X);if(B.length===0){e.debug(`no text at position ${j}, length ${X}, to highlight`);return}e.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=z9(Z.visibleMap,0,Z.visibleText.length);this.highlightCoordinator.clearHighlights(i.TTS_WORD),this.paintTTSSentenceRanges(Y.length>1?Y:[Z.regionRange]);return}if(!Q)return;let J=document.createRange();J.selectNodeContents(Q),this.highlightCoordinator.clearHighlights(i.TTS_WORD),this.paintTTSSentenceRanges([J])}catch{}}highlightRenderableRegionTarget(Z){if(!this.highlightCoordinator||!Z||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&b4(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.clearHighlights(i.TTS_WORD);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(e.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=R4(J.src,Z.fragment),Y.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,G)=>{let j,B=!1,U=!1,q=()=>{if(U||B)return;B=!0,Q?.()},K=()=>{if(Y.removeEventListener("ended",$),Y.removeEventListener("error",D),Y.removeEventListener("playing",q),j?.(),this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null},$=()=>{if(U)return;U=!0,K(),X()},D=()=>{if(U)return;U=!0,K(),G(Error(`[tts] recorded audio failed to play: ${J.src}`))},z=()=>{Promise.resolve(Y.play()).then(q).catch((M)=>{if(M?.name==="AbortError"&&this.state===P.PAUSED)return;D()})};this.activeRecordedAudio={element:Y,cancel:()=>{if(U)return;U=!0,K(),Y.pause(),X()},play:z},Y.addEventListener("ended",$),Y.addEventListener("error",D),Y.addEventListener("playing",q),j=E4(Y,Z.fragment,$),z()}).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?M3({contentRoot:J,chunks:[Z]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,G=Y?_3({chunks:[Y],mathTokenHighlighting:X}):null;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 K=this.provider,$=K.onWordBoundary;K.onWordBoundary=void 0;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===K&&Q===this.speakRunId&&K.onWordBoundary===void 0)K.onWordBoundary=$}return}let B=this.provider,U=B.onWordBoundary,q=(K,$,D)=>{if(Q!==this.speakRunId)return;if(G&&Y){let z=Y.offsetSpace==="unsupported"?"unknown":Y.offsetSpace;this.renderHighlightDecision(G.resolveBoundary({chunkId:Y.id,word:K,position:$,length:D,providerOffsetSpace:z}));return}};B.onWordBoundary=q;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===B&&Q===this.speakRunId&&B.onWordBoundary===q)B.onWordBoundary=U}}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){let Q=this.seekSegments;if(Q.length>0)await this.speakWithPlan(Q,Z.runId,{highlightMode:Z.highlightMode});else await this.speakWithinLimit(Z.contentToSpeak,Z.runId);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}selectMappedRangeText(Z,Q,J){if(typeof Z.comparePoint!=="function")return null;let{text:Y,map:X}=b9(Q,this.getTextProcessingOptions(J)),G=-1,j=-1;for(let[K,{node:$,offset:D}]of X){if(K>=Y.length)continue;if(!U0(Z,$,D))continue;if(G===-1||K<G)G=K;if(K>j)j=K}if(G===-1)return null;let B=Y.slice(G,j+1),U=B.length-B.trimStart().length,q=B.trim();return q?{text:q,offset:G+U}:null}pause(){if(this.state!==P.PLAYING&&this.state!==P.LOADING)return;this.resumeState=this.state,this.activeRecordedAudio?.element.pause(),this.provider?.pause(),this.setState(P.PAUSED)}resume(){if(this.state!==P.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(0.25,Math.min(4,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===P.PAUSED;this.speakRunId+=1,this.abandonRun(),this.provider.onWordBoundary=void 0,this.provider.stop();let X=++this.speakRunId,G=this.seekSegments.slice(Q);if(this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.currentBoundaryOffset=this.seekSegments[Q].startOffset,!Y)this.setState(P.LOADING);let j=this.installPlaybackStartBarrier(X,!!J?.[0]?.audio);if(Y)this.resumeState=j?P.LOADING:P.PLAYING;else if(!j)this.setState(P.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 U=Q+B,q=this.seekSegments[U];if(q)this.currentBoundaryOffset=q.startOffset;await this.speakCatalogChunk(J[B],X)}else await this.speakWithPlan(G,X,{highlightMode:this.activeHighlightMode});if(X!==this.speakRunId)return;this.setState(P.IDLE),this.clearHighlightsAndTracking()}catch(B){if(X!==this.speakRunId)return;throw this.lastError=B instanceof Error?B.message:String(B),this.setState(P.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 U=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===U)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 U=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!B.didUpdate&&!U)return;if(this.state!==P.PLAYING&&this.state!==P.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;if(this.state!==P.PLAYING&&this.state!==P.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Q=Number.isFinite(Z)?Math.trunc(Z):0;if(Q===0)return;let J=this.getCurrentSeekSegmentIndex(),Y=Math.max(0,Math.min(this.seekSegments.length-1,J+Q));if(Y===J)return;await this.restartFromSeekIndex(Y)}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(){if(this.speakRunId+=1,this.abandonRun(),this.provider)this.provider.onWordBoundary=void 0,this.provider.stop();if(this.setState(P.IDLE),this.currentText=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null,this.activePlaybackRate=null}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}requestControlHandoff(){if(typeof window>"u")return;let Z={source:"host"};window.dispatchEvent(new CustomEvent(N3,{detail:Z}))}isPlaying(){return this.state===P.PLAYING}isPaused(){return this.state===P.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(Z){let Q=(J)=>Z(J);return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}setState(Z){if(this.state===Z)return;let Q=this.state;this.state=Z;for(let J of[...this.listeners])J(Z);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",previousState:Q,state:Z}),Z===P.PLAYING){let J=Q===P.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(J,{toolId:"textToSpeech",previousState:Q,state:Z});return}if(Z===P.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",previousState:Q,state:Z});return}if(Z===P.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",previousState:Q,state:Z,message:this.lastError||void 0});return}if(Z===P.IDLE&&(Q===P.PLAYING||Q===P.PAUSED||Q===P.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",previousState:Q,state:Z})}}import{createPieLogger as S4,isTtsDebugEnabled as T4}from"@pie-players/pie-players-shared/pie";var C3=S4("browser-tts-provider",T4),b3=5000,T3=2000,y4=["__pieTelemetry","contentLanguage","highlightMode","locale","mathSpeech","segmenter","structuralPauses","textNormalization"],y3=(Z)=>{let Q={};if(Z.rate!==void 0)Q.rate=Z.rate;if(Z.pitch!==void 0)Q.pitch=Z.pitch;if(Z.mathTokenHighlighting!==void 0)Q.mathTokenHighlighting=Z.mathTokenHighlighting;let J=Z.providerOptions;if(J&&typeof J==="object"){let Y={};for(let X of y4)if(J[X]!==void 0)Y[X]=J[X];if(Object.keys(Y).length>0)Q.providerOptions=Y}return Q},S3=(Z)=>{if(!x0(Z))return{text:Z,sourceOffset:(X)=>X};let{spokenText:Q,rawToSpokenOffsetMap:J}=k0(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}}},Y8=(Z)=>String(Z||"").trim().toLowerCase(),x4=()=>{let Z=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return Y8(Z||"en-US")},k4=(Z,Q)=>{let J=Y8(Q)||x4(),Y=J.split("-")[0]||"en",X=Y8(Z.lang);return X===J||X.startsWith(`${Y}-`)},f4=(Z,Q,J)=>{if(Q)return Z.find((G)=>G.voiceURI===Q)||Z.find((G)=>G.name===Q)||null;let Y=(G)=>k4(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},I4=(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=(D)=>{if(j)return;if(j=!0,clearTimeout($),Y)Z.removeEventListener("voiceschanged",q);else if(Z.onvoiceschanged===K)Z.onvoiceschanged=G;X(D)},U=()=>{if(!J())B(!1);else if(Z.getVoices().length>0)B(!0)},q=()=>U(),K=(D)=>{try{G?.call(Z,D)}finally{U()}},$=setTimeout(()=>B(!1),Q);if(Y)Z.addEventListener("voiceschanged",q);else Z.onvoiceschanged=K;U()})},v4=(Z)=>!Z.default;class X8{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";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 I4(window.speechSynthesis,T3);return new x3(Z)}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,defaultHighlightMode:"sentence",supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class x3{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 ${T3/1000} seconds.`);let J=f4(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=S3(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=S3(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,(q)=>Y.startOffset+X.sourceOffset(q)))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<=260)return[{text:Z,offset:0}];let J=this.segmentSentences(Z),Y=[],X="",G=0;for(let j of J){let B=j.text.trim();if(!B)continue;let U=j.text.search(/\S/),q=j.offset+(U===-1?0:U);if(!X){X=B,G=q;continue}let K=`${X} ${B}`;if(K.length<=260)X=K;else Y.push({text:X,offset:G}),X=B,G=q}if(X)Y.push({text:X,offset:G});return Y.length?Y:[{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,useWordSegmenter:Y,locale:X}}segmentSentences(Z){let Q=this.getSegmentationPolicy();return I9(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 U=this.getContentLocale();if(U)B.lang=U;if(Y&&v4(Y))B.voice=Y;if(this.config?.rate)B.rate=this.config.rate;if(this.config?.pitch)B.pitch=this.config.pitch;let q=!1,K=!1,$=null,D=null,z=()=>{if(this.utterance===B)this.utterance=null},M=()=>{if($!==null)clearTimeout($),$=null},O=()=>{B.onstart=null,B.onend=null,B.onerror=null,B.onpause=null,B.onresume=null,B.onboundary=null},F=(R,b)=>{if(K)return;if(K=!0,M(),O(),z(),D&&this.settlePendingChunk===D)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1;if(b)j(b);else G(R)},w=(R)=>Error(R==="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 ${b3/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);D=()=>F(!1),this.settlePendingChunk=D,B.onstart=()=>{if(J!==this.speakRunId){F(!1);return}if(q=!0,M(),this._isPlaying=!0,this._isPaused)speechSynthesis.pause();try{this.onPlaybackStart?.()}catch(R){console.error("Browser TTS playback-start callback failed",R)}},B.onend=()=>{if(J!==this.speakRunId){F(!1);return}if(!q){F(!1,w("ended"));return}F(!0)},B.onerror=(R)=>{if(J!==this.speakRunId){F(!1);return}if(R.error==="interrupted"||R.error==="canceled"){F(!1);return}F(!1,Error(`Speech synthesis error: ${R.error}`))},B.onpause=()=>{if(J!==this.speakRunId)return;this._isPaused=!0},B.onresume=()=>{if(J!==this.speakRunId)return;this._isPaused=!1},B.onboundary=(R)=>{if(J!==this.speakRunId)return;if(C3.debug(`boundary event: ${R.name}, charIndex ${R.charIndex}, charLength ${R.charLength}`),R.name!=="word"||!this.onWordBoundary)return;let b=Math.max(0,Math.min(R.charIndex,Math.max(0,Z.length-1))),S=Number(R.charLength||0),h=this.inferWordLength(Z,b),C=Number.isFinite(S)&&S>0&&S<=80&&b+S<=Z.length?S:h,U9=Z.substring(b,Math.min(Z.length,b+C)).trim(),K9=Q+b,u=X(K9),Q9=X(K9+C-1)+1-u;C3.debug(`word boundary "${U9}" at ${u}`),this.onWordBoundary(U9,u,Q9)},$=setTimeout(()=>{if(K||q||J!==this.speakRunId)return;F(!1,w("timedOut")),speechSynthesis.cancel()},b3);try{speechSynthesis.speak(B)}catch(R){F(!1,R instanceof Error?R: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()}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}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.voice!==void 0)this.config.voice=Z.voice;if(Z.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...Z.providerOptions||{}}}onWordBoundary}var h4=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),k3=(Z)=>Z&&typeof Z==="object"?Z:{},Z9=(Z,Q)=>Z===void 0?Q:Z,m4=(Z,Q="left-aligned")=>typeof Z==="string"&&h4.has(Z)?Z:Q,gJ=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 cJ=Object.freeze([0.8,1,1.25]);var u4=(Z)=>{let Q={...Z,layoutMode:m4(Z.layoutMode)};if(Z.backend!=="server")return Q;let J={...Q,apiEndpoint:Z9(Q.apiEndpoint,"/api/tts"),transportMode:Z9(Q.transportMode,"pie"),endpointValidationMode:Z9(Q.endpointValidationMode,"voices"),validateEndpoint:Z9(Q.validateEndpoint,!0),includeAuthOnAssetFetch:Z9(Q.includeAuthOnAssetFetch,!1),rate:Z9(Q.rate,1),language:Z9(Q.language,"en-US")};if(Z.serverProvider==="polly")return{...J,engine:Z9(J.engine,"neural"),format:Z9(J.format,"mp3"),speechMarksMode:Z9(J.speechMarksMode,"word+sentence")};return J},G8=(Z)=>{let{enabled:Q,provider:J,...Y}=k3(Z);return u4(Y)},j8=(Z)=>Z.backend||"browser",B8=(Z)=>{let Q=j8(Z)==="server"?Z.serverProvider:void 0,J=Q==="polly",Y=Z.transportMode||(Q==="custom"?"custom":"pie"),X=W9(Z.mathSpeech);return{voice:Z.defaultVoice,rate:Z.rate,pitch:Z.pitch,providerOptions:{...k3(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,validateEndpoint:Z.validateEndpoint,...typeof Z.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Z.mathTokenHighlighting}:{}}};import{createPieLogger as p4,isGlobalDebugEnabled as g4}from"@pie-players/pie-players-shared/pie";var a9=p4("ToolProviderRegistry",g4);class u0{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(a9.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=(j)=>{let B=j&&typeof j==="object"?j.backend:void 0;return typeof B==="string"&&B?B:"unknown"},G=Date.now();if(await this.emitTelemetry(J,"pie-tool-init-start",{toolId:Z,backend:X(Y),operation:"provider-initialize"}),Q.requiresAuth&&J.authFetcher){let j=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Z,backend:X(Y),operation:"auth-fetch"}),a9.debug(`Fetching auth for "${Z}"...`);try{let B=await J.authFetcher();Y={...Y,...B},await this.emitTelemetry(J,"pie-tool-backend-call-success",{toolId:Z,backend:X(Y),operation:"auth-fetch",duration:Date.now()-j})}catch(B){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Z,backend:X(Y),operation:"auth-fetch",duration:Date.now()-j,errorType:"ProviderAuthFetchError",message:B instanceof Error?B.message:String(B)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Z}":`,B),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:X(Y),operation:"provider-initialize",duration:Date.now()-G}),a9.debug(`Provider "${Z}" initialized`)}catch(j){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Z,backend:X(Y),operation:"provider-initialize",duration:Date.now()-G,errorType:"ProviderInitializationError",message:j instanceof Error?j.message:String(j)}),console.error(`[ToolProviderRegistry] Initialization failed for "${Z}":`,j),j}}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))a9.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),a9.debug(`Unregistered provider "${Z}"`)}}async destroy(){let Z=Array.from(this.providers.keys());await Promise.all(Z.map((Q)=>this.unregister(Q))),a9.debug("Registry destroyed")}}class W8{targets=new Set;changeListeners=new Set;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 console.error(`[ToolRequestRegistry] Target failed to open "${Z.toolId}":`,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 console.warn(`[ToolRequestRegistry] Target at level "${Z.level}" failed the host check for "${Q}":`,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()}}class U8{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=c4(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 c4(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
|
-
`;
|
|
218
|
-
`,
|
|
219
|
-
`,
|
|
220
|
-
`;let X=
|
|
217
|
+
`;Y+=`**Primary Reason** (${Q.rule}):
|
|
218
|
+
`,Y+=`${Q.reason}
|
|
219
|
+
`,Y+=`Source: ${J} (${Q.source.type})
|
|
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
|
-
`;for(let
|
|
223
|
-
`}return J}function b8(G){let{request:Q,tools:Y,pnpPolicy:J,customSources:X,contextId:j}=G,Z=new M1(j);Z.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:Y.placement,policy:Y.policy}});let q=L7(Y.placement[Q.level]),B=L7(Y.policy.allowed),K=new Set(L7(Y.policy.blocked)),W=[];for(let D of q)W.push(D),Z.addDecision({precedence:0,rule:"placement-membership",featureId:D,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(W=W.filter((D)=>{if(Y.providers?.[D]?.enabled===!1)return Z.addDecision({precedence:0,rule:"provider-disabled",featureId:D,action:"block",sourceType:"host",reason:`tools.providers.${D}.enabled === false`,value:!1}),!1;return!0}),B.length>0){let D=new Set(B);W=W.filter((P)=>{if(!D.has(P))return Z.addDecision({precedence:0,rule:"host-allowlist",featureId:P,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:B}),!1;return!0})}W=W.filter((D)=>{if(K.has(D))return Z.addDecision({precedence:0,rule:"host-blocked",featureId:D,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:Y.policy.blocked}),!1;return!0});let $=[],H=new Map;for(let D of W)H.set(D,["placement"]);let N=new Set(W),F=null;if(J.enforcement==="on"&&J.source&&(J.assessment||J.currentItemRef)){if(F=J.source.apply({assessment:J.assessment,currentItemRef:J.currentItemRef}),F.sources.assessment)Z.addSource("assessment",F.sources.assessment);if(F.sources.student)Z.addSource("student",F.sources.student);if(F.sources.item)Z.addSource("item",F.sources.item);for(let D of F.decisions)Z.addDecision({precedence:D.precedence,rule:D.rule,featureId:D.featureId,action:D.action,sourceType:D.sourceType,reason:D.reason,value:D.value});for(let D of F.unmappedSupportIds)$.push({code:"tool-policy.unknownSupportId",level:Q.level,toolId:D,message:`No registered tool claims PNP support id "${D}"; it was carried through as a feature id and matched nothing. Expected an AfA 3.0 / QTI 3.0 access feature id.`,source:"pnp.pnp-support"});W=W.filter((D)=>{return!F.blockedToolIds.has(D)});for(let D of Array.from(H.keys()))if(F.blockedToolIds.has(D))H.delete(D);for(let D of F.mandatedToolIds){if(!!N.has(D))continue;let v=F.perToolFlags.get(D)?.rule??"required-tool",I=MQ(D,{placement:q,allowed:B,blocked:K,providers:Y.providers}),p={rule:v,hostRule:I.hostRule,hostValue:I.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:D,message:`Profile policy mandates "${D}" (${v}) but host policy removed it from level "${Q.level}" via ${I.hostRule}.`,details:p}),Z.addDecision({precedence:0,rule:"required-tool-blocked",featureId:D,action:"advisory",sourceType:"host",reason:`Host removed required tool "${D}" via ${I.hostRule}`,value:p})}for(let D of W){let P=F.perToolFlags.get(D);if(P){let S=H.get(D)??[];S.push(`pnp.${P.rule}`),H.set(D,S)}}}for(let D=0;D<X.length;D++){let P=X[D],S=W.slice(),v=P.refine({request:Q,candidates:S}),I=new Set(v.refinedCandidates);for(let E of v.refinedCandidates)if(!S.includes(E))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:E,message:`Custom source "${P.id}" tried to add tool "${E}" that was not in candidates; ignored.`,source:`custom.${P.id}`}),I.delete(E);W=S.filter((E)=>I.has(E));let p=new Set;if(v.decisions){for(let E of v.decisions)if(Z.addDecision({precedence:E.precedence??100+D,rule:E.rule,featureId:E.featureId,action:E.action,sourceType:E.sourceType,reason:E.reason,value:E.value}),E.action==="block")p.add(E.featureId)}for(let E of S){if(I.has(E))continue;if(p.has(E))continue;Z.addDecision({precedence:100+D,rule:"custom-source",featureId:E,action:"block",sourceType:"custom",reason:`Custom policy source "${P.id}" removed tool "${E}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:P.id}})}for(let E of W){let g=H.get(E)??["placement"];g.push(`custom.${P.id}`),H.set(E,g)}for(let E of S)if(!I.has(E))H.delete(E)}let O=new Set(W),L=W.map((D)=>{let P=F?.perToolFlags.get(D);return{toolId:D,required:P?.required??!1,alwaysAvailable:P?.alwaysAvailable??!1,settings:P?.settings,sources:H.get(D)??["placement"]}});return Z.reconcileFinalStates(O),{visibleTools:L,diagnostics:$,provenance:Z.build()}}function MQ(G,Q){if(!Q.placement.includes(G))return{hostRule:"placement-missing",hostValue:Q.placement};if(Q.providers?.[G]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Q.allowed.length>0&&!Q.allowed.includes(G))return{hostRule:"host-allowlist",hostValue:Q.allowed};if(Q.blocked.has(G))return{hostRule:"host-blocked",hostValue:Array.from(Q.blocked)};return{hostRule:"placement-missing",hostValue:Q.placement}}function p0(G){if(!G)return!1;let Q=G.personalNeedsProfile;if(Q){if(Array.isArray(Q.supports)&&Q.supports.length>0)return!0;if(Array.isArray(Q.prohibitedSupports)&&Q.prohibitedSupports.length>0)return!0;if(Array.isArray(Q.activateAtInit)&&Q.activateAtInit.length>0)return!0}let Y=G.settings;if(Y){let J=Y.districtPolicy;if(J){if(Array.isArray(J.blockedTools)&&J.blockedTools.length>0)return!0;if(Array.isArray(J.requiredTools)&&J.requiredTools.length>0)return!0;if(J.policies&&typeof J.policies==="object"&&Object.keys(J.policies).length>0)return!0}let X=Y.testAdministration;if(X&&typeof X==="object")for(let j of Object.keys(X)){let Z=X[j];if(Z===void 0||Z===null)continue;if(Array.isArray(Z)&&Z.length===0)continue;if(typeof Z==="object"&&!Array.isArray(Z)&&Object.keys(Z).length===0)continue;return!0}}return!1}function g0(G){let Q=G?.settings;if(!Q)return!1;if(Array.isArray(Q.requiredTools)&&Q.requiredTools.length>0)return!0;if(Array.isArray(Q.restrictedTools)&&Q.restrictedTools.length>0)return!0;if(Q.toolParameters&&typeof Q.toolParameters==="object"&&Object.keys(Q.toolParameters).length>0)return!0;return!1}function l7(G){if(p0(G.assessment))return"on";if(g0(G.currentItemRef))return"on";return"off"}class z1{id="pnp";toolRegistry;constructor(G){this.toolRegistry=G}apply(G){let{ctx:Q,result:Y}=this.prepare(G),{pnp:J,districtPolicy:X,itemSettings:j}=Q,Z=new Set;J?.supports?.forEach((q)=>Z.add(q)),J?.prohibitedSupports?.forEach((q)=>Z.add(q)),X?.blockedTools?.forEach((q)=>Z.add(q)),X?.requiredTools?.forEach((q)=>Z.add(q)),j?.requiredTools?.forEach((q)=>Z.add(q)),j?.restrictedTools?.forEach((q)=>Z.add(q));for(let q of Z)this.resolveSupport(q,Q,Y);return Y}resolveFeature(G,Q){let{ctx:Y,result:J}=this.prepare(Q);return this.resolveSupport(G,Y,J),J}prepare(G){let{assessment:Q,currentItemRef:Y}=G,J=Q?.personalNeedsProfile,X=Q?.settings,j=Y?.settings,Z={blockedToolIds:new Set,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],unmappedSupportIds:new Set,sources:{}};if(X?.districtPolicy||X?.testAdministration)Z.sources.assessment={id:Q?.id||"unknown",name:Q?.name||Q?.id||"Assessment",config:X};if(J)Z.sources.student={id:"student",name:"Student PNP Profile",config:J};if(Y&&j)Z.sources.item={id:Y.identifier,name:Y.identifier,config:j};return{ctx:{pnp:J,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:j,toolConfigs:X?.toolConfigs},result:Z}}resolveSupport(G,Q,Y){if(Q.districtPolicy?.blockedTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:1,rule:"district-block",featureId:X,action:"block",sourceType:"assessment",reason:`District policy blocks "${G}" for all assessments`,value:Q.districtPolicy.blockedTools});return}if(Q.testAdmin?.toolOverrides?.[G]===!1){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:2,rule:"test-admin-override",featureId:X,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${G}" for this session`,value:Q.testAdmin.toolOverrides});return}if(Q.itemSettings?.restrictedTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:3,rule:"item-restriction",featureId:X,action:"block",sourceType:"item",reason:`Item restricts "${G}" (e.g., mental math question blocks calculator)`,value:Q.itemSettings.restrictedTools});return}if(Q.itemSettings?.requiredTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(G,Q),rule:"item-requirement",sourceType:"item"}),Y.decisions.push({precedence:4,rule:"item-requirement",featureId:X,action:"enable",sourceType:"item",reason:`Item requires "${G}" for this question`,value:Q.itemSettings.requiredTools});return}if(Q.districtPolicy?.requiredTools?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.mandatedToolIds.add(X),Y.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(G,Q),rule:"district-requirement",sourceType:"assessment"}),Y.decisions.push({precedence:5,rule:"district-requirement",featureId:X,action:"enable",sourceType:"assessment",reason:`District policy requires "${G}" for all assessments`,value:Q.districtPolicy.requiredTools});return}if(Q.pnp?.prohibitedSupports?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.blockedToolIds.add(X),Y.decisions.push({precedence:6,rule:"pnp-prohibited",featureId:X,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${G}"`,value:Q.pnp.prohibitedSupports});return}if(Q.pnp?.supports?.includes(G)){let X=this.mapSupportToToolId(G,Y);Y.perToolFlags.set(X,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(G,Q),rule:"pnp-support",sourceType:"student"}),Y.decisions.push({precedence:6,rule:"pnp-support",featureId:X,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${G}"`,value:Q.pnp.supports});return}let J=this.mapSupportToToolId(G,Y);Y.decisions.push({precedence:6,rule:"pnp-support",featureId:J,action:"skip",sourceType:"system",reason:`Feature "${G}" not configured at any level`,value:{supportId:G}})}mapSupportToToolId(G,Q){let Y=this.toolRegistry.getToolsByPNPSupport(G);if(Y.size===0){if(this.toolRegistry.getAllTools().length>0)Q.unmappedSupportIds.add(G);return G}return Array.from(Y)[0]}resolveToolSettings(G,Q){return Q.itemSettings?.toolParameters?.[G]??Q.toolConfigs?.[G]}}var c0=b7({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class O1{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;currentItemRef;pnpEnforcement;disposed=!1;constructor(G){this.toolRegistry=G.toolRegistry,this.contextId=G.contextId??"tool-policy",this.pnpPolicySource=new z1(this.toolRegistry),this.customSources=G.customSources?[...G.customSources]:[];let Q=G.inputs??{};this.tools=Q.tools??c0,this.assessment=Q.assessment??null,this.currentItemRef=Q.currentItemRef??null,this.pnpEnforcement=Q.pnpEnforcement??l7({assessment:this.assessment,currentItemRef:this.currentItemRef})}decide(G){this.assertNotDisposed();let Q=G.scope.scopeId?`${this.contextId}:${G.level}:${G.scope.scopeId}`:`${this.contextId}:${G.level}`;return b8({request:G,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0,enforcement:this.pnpEnforcement},customSources:this.customSources,contextId:Q})}decideFeature(G){this.assertNotDisposed();let Q=this.hostFeatureGate(G);if(Q)return Q;return u0(G,this.pnpPolicySource.resolveFeature(G,{assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0}),{assessmentBound:this.assessment!==null})}hostFeatureGate(G){let Q={assessmentBound:this.assessment!==null},Y=L7(this.tools.policy.blocked);if(Y.includes(G))return E8(G,"host-blocked",Y,Q);let J=L7(this.tools.policy.allowed);if(J.length>0&&!J.includes(G))return E8(G,"host-allowlist",J,Q);return null}getVisibleToolIds(G,Q){return this.decide({level:G,scope:{level:G,scopeId:Q}}).visibleTools.map((Y)=>Y.toolId)}updateInputs(G){this.assertNotDisposed();let Q=!1,Y=!1;if("tools"in G){let J=G.tools??c0;if(!Object.is(this.tools,J))this.tools=J,Q=!0}if("assessment"in G){let J=G.assessment??null;if(!Object.is(this.assessment,J))this.assessment=J,Q=!0}if("currentItemRef"in G){let J=G.currentItemRef??null;if(!Object.is(this.currentItemRef,J))this.currentItemRef=J,Q=!0}if("pnpEnforcement"in G&&G.pnpEnforcement){if(this.pnpEnforcement!==G.pnpEnforcement)this.pnpEnforcement=G.pnpEnforcement,Y=!0}if(Q||Y)this.emit({reason:Y&&!Q?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}registerPolicySource(G){return this.assertNotDisposed(),this.customSources.push(G),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Q=this.customSources.indexOf(G);if(Q!==-1){if(this.customSources.splice(Q,1),!this.disposed)this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}}onPolicyChange(G){return this.listeners.add(G),()=>{this.listeners.delete(G)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,currentItemRef:this.currentItemRef,pnpEnforcement:this.pnpEnforcement})}emit(G){for(let Q of Array.from(this.listeners))try{Q(G)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}var zQ=Symbol("@pie-players/tool-policy-engine");class d extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class T8 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var P1=(G)=>!!G&&typeof G==="object"&&!Array.isArray(G),OQ=(G,Q,Y)=>{let J={...Q,...Y};if(G==="textToSpeech"&&P1(Q.settings)&&P1(Y.settings)){if(J.settings={...Q.settings,...Y.settings},P1(Q.settings.mathSpeech)&&P1(Y.settings.mathSpeech))J.settings.mathSpeech={...Q.settings.mathSpeech,...Y.settings.mathSpeech}}return J},PQ=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],LQ=["section-navigation-change","section-session-applied","section-loading-complete","section-items-complete-changed","section-error","timed-media-cue-changed","timed-media-policy-degraded","timed-media-invalid"];class L1{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;toolRegistry;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new R8;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitEntries=new Map;sectionControllerDisposePromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;pnpEnforcementOverride=null;boundAssessment=null;boundCurrentItemRef=null;reportedUnboundFeaturePolicy=!1;static resolveConfig(G){let Q=i1(G.toolConfigStrictness),Y=G.toolRegistry??new S8,J=G.deferToolConfigValidation===!0?b7(G.tools):Z7(G.tools,{strictness:Q,source:"ToolkitCoordinator.init",toolRegistry:Y}).config;return{...G,toolConfigStrictness:Q,toolRegistry:Y,tools:{...J,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...J.providers}},accessibility:{language:"en-US",...G.accessibility??{},catalogs:G.accessibility?.catalogs??[]}}}constructor(G){if(!G.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");let Q=L1.resolveConfig(G);if(this.assessmentId=Q.assessmentId,this.config=Q,this.toolRegistry=Q.toolRegistry??new S8,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks=Q.hooks??{},this.lazyInit=G.lazyInit===!0,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=G.frameworkErrorBus??new p7,this.ownsFrameworkErrorBus=!G.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new X8,this.highlightCoordinator=new g7,this.elementToolStateStore=new Y8,this.catalogResolver=new Q8(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new F1,this._registerToolProviders(),this.ttsService=new c7,this.setupStatePersistenceHooks(),this.policyEngine=new O1({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,inputs:{tools:this.config.tools,assessment:null,currentItemRef:null,pnpEnforcement:this.resolveEffectivePnpEnforcement()}}),!this.lazyInit)this.waitUntilReady().catch((Y)=>{if(Y instanceof d)return;console.error("[ToolkitCoordinator] Failed eager initialization:",Y),this.handleError(Y,{phase:"coordinator-ready"})})}assertNotDisposed(){if(this.disposePromise!==null)throw new d}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((G)=>{let Q=this.hooks.onFrameworkError;if(!Q)return;try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",Y)}})}async emitTelemetry(G,Q){try{await this.hooks.onTelemetry?.(G,Q)}catch(J){console.warn("[ToolkitCoordinator] telemetry hook failed:",J)}let Y=Q?{...Q}:void 0;for(let J of this.telemetryListeners)try{J({eventName:G,payload:Y?{...Y}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(G){for(let Q of this.sectionControllerLifecycleListeners)try{Q(G)}catch(Y){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",Y)}}handleError(G,Q){let Y=X6({error:G,context:Q});this.frameworkErrorBus.reportFrameworkError(Y)}subscribeFrameworkErrors(G){return this.frameworkErrorBus.subscribeFrameworkErrors(G)}reportFrameworkError(G){this.frameworkErrorBus.reportFrameworkError(G)}getSectionControllerMapKey(G){return`${G.assessmentId}::${G.sectionId}::${G.attemptId||""}`}createDefaultSectionPersistence(){let G=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Q=(Y)=>{let{assessmentId:J,sectionId:X,attemptId:j}=Y.key;return`pie:section-controller:v1:${J}:${X}:${j||"default"}`};return{async loadSession(Y){if(!G)return null;let J=G.getItem(Q(Y));if(!J)return null;try{return JSON.parse(J)}catch{return null}},async saveSession(Y,J){if(!G)return;G.setItem(Q(Y),JSON.stringify(J))},async clearSession(Y){if(!G)return;G.removeItem(Q(Y))}}}async resolveSectionPersistence(G){let Q=this.getSectionControllerMapKey(G.key),Y=this.sectionPersistenceStrategies.get(Q);if(Y)return Y;let J={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(G,J)??await J.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Q,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((G)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(G)).catch((Q)=>{this.handleError(Q,{phase:"state-save"})})})}async ensureStateLoaded(){if(this.stateLoaded)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let G=this.hooks.loadToolState;if(!G)return;try{let Q=await G();if(this.assertNotDisposed(),Q&&typeof Q==="object")this.elementToolStateStore.loadState(Q);this.stateLoaded=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Q)})}catch(Q){if(Q instanceof d)throw Q;this.handleError(Q,{phase:"state-load"})}})().finally(()=>{this.stateLoadPromise=void 0}),this.stateLoadPromise}_registerToolProviders(){let G=this.getProviderDescriptorTools();for(let Q of G)this.registerProviderFromTool(Q)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((G)=>!!G.provider)}async registerProviderFromTool(G){let Q=G.provider;if(!Q)return;let Y=this.getToolConfig(G.toolId)||void 0;if(Y?.enabled===!1)return;let J=Q.getProviderId?.(Y)??Y?.provider?.id??G.toolId;if(this.toolProviderRegistry.has(J))return;let X=Q.createProvider(Y),j=Q.getInitConfig?.(Y)??Y?.provider?.init??{},Z=this.addToolTelemetryReporter({toolId:G.toolId,providerId:J,initConfig:j}),q=this.createToolTelemetryForwarder({toolId:G.toolId,providerId:J}),B=Q.getAuthFetcher?.(Y)??Y?.provider?.runtime?.authFetcher;await this.registerProvider(J,{provider:X,config:Z,lazy:Q.lazy??!0,authFetcher:B,onTelemetry:q})}createToolTelemetryForwarder(G){return async(Q,Y)=>{await this.emitTelemetry(Q,{...Y||{},toolId:G.toolId,providerId:G.providerId})}}addToolTelemetryReporter(G){let Q=G.initConfig&&typeof G.initConfig==="object"?{...G.initConfig}:{},Y=typeof Q.onTelemetry==="function"?Q.onTelemetry:null,J=this.createToolTelemetryForwarder({toolId:G.toolId,providerId:G.providerId});return Q.onTelemetry=async(X,j)=>{if(Y)await Y(X,j);await J(X,j)},Q}async registerProvider(G,Q){try{this.toolProviderRegistry.register(G,Q);let Y={providerId:G,providerName:Q.provider.providerName};await this.hooks.onProviderRegistered?.(G,Y),await this.emitTelemetry("pie-toolkit-provider-registered",{providerId:G,providerName:Q.provider.providerName})}catch(Y){console.warn(`[ToolkitCoordinator] Failed to register provider "${G}":`,Y),this.handleError(Y,{phase:"provider-register",providerId:G})}}async ensureProviderReady(G){this.assertNotDisposed();let Q=this.providerInitPromises.get(G);if(Q)return Q;let Y=(async()=>{let J=await this.toolProviderRegistry.getProvider(G,!1);this.assertNotDisposed();let X={providerId:G,providerName:J.providerName};try{return await this.hooks.onProviderInitStart?.(G,X),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(G),this.assertNotDisposed(),await this.hooks.onProviderReady?.(G,X),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{providerId:G}),this.assertNotDisposed(),J}catch(j){if(j instanceof d)throw j;let Z=j instanceof Error?j:Error(String(j));throw this.handleError(Z,{phase:"provider-init",providerId:G}),Z}})().finally(()=>{this.providerInitPromises.delete(G)});return this.providerInitPromises.set(G,Y),Y}setHooks(G){if(Object.assign(this.hooks,G),this.setupStatePersistenceHooks(),this.disposePromise===null&&G.onCoordinatorReady&&this.isReady())Promise.resolve(G.onCoordinatorReady(this)).catch((Q)=>{this.handleError(Q,{phase:"coordinator-ready"})})}subscribeTelemetry(G){return this.telemetryListeners.add(G),()=>{this.telemetryListeners.delete(G)}}getSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(Q))}subscribeSectionEvents(G){if(this.activeCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Q=this.activeSubscriptions.get(G.listener);if(Q)Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let Y={listener:G.listener,eventTypes:G.eventTypes,itemIds:G.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(G.listener,Y);let J=this.sectionControllers.get(this.activeCohortMapKey);if(J)this.bindSubscriptionToController(Y,J);let X=!1;return()=>{if(X)return;if(X=!0,Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null,this.activeSubscriptions.get(G.listener)===Y)this.activeSubscriptions.delete(G.listener)}}bindSubscriptionToController(G,Q){G.unsubscribeCurrent?.(),G.unsubscribeCurrent=null;let Y=Q.subscribe;if(typeof Y!=="function")return;let J=this.buildSectionEventPredicate(G);G.unsubscribeCurrent=Y.call(Q,(Z)=>{if(!J(Z))return;this.deliverSectionEventSafely(G.listener,Z)});let X=this.buildContentLoadedReplayEvents(Q);for(let Z of X)if(J(Z))this.deliverSectionEventSafely(G.listener,Z);let j=this.buildLoadingCompleteReplayEvent(Q);if(j&&J(j))this.deliverSectionEventSafely(G.listener,j)}deliverSectionEventSafely(G,Q){try{G(Q)}catch(Y){console.warn("[ToolkitCoordinator] section-event listener failed:",Y)}}setActiveCohort(G){if(this.activeCohortMapKey===G)return;this.activeCohortMapKey=G;let Q=this.sectionControllers.get(G);if(!Q)return;for(let Y of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(Y,Q)}setActiveCohortIfLatestRequest(G){if(this.latestRequestedActiveCohortMapKey!==G)return;this.setActiveCohort(G)}suspendActiveCohortIfSuperseded(G){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===G)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}clearActiveCohortIfMatches(G){if(this.activeCohortMapKey!==G)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}buildSectionEventPredicate(G){let Q=G.eventTypes?new Set(G.eventTypes):null,Y=G.itemIds?new Set(G.itemIds):null;return(J)=>{if(Q||Y){let X=J?.type||null;if(Q&&(!X||!Q.has(X)))return!1;if(Y){if(!Array.from(this.collectEventItemIds(J)).some((Z)=>Y.has(Z)))return!1}}return!0}}collectEventItemIds(G){let Q=new Set;if("itemId"in G&&typeof G.itemId==="string")Q.add(G.itemId);if("canonicalItemId"in G&&typeof G.canonicalItemId==="string")Q.add(G.canonicalItemId);if("currentItemId"in G&&typeof G.currentItemId==="string")Q.add(G.currentItemId);if("previousItemId"in G&&typeof G.previousItemId==="string")Q.add(G.previousItemId);return Q}buildContentLoadedReplayEvents(G){let Q=G.getRuntimeState?.(),Y=Q?.loadedRenderables;if(!Array.isArray(Y)||Y.length===0)return[];let J=typeof Q?.currentItemIndex==="number"&&Number.isFinite(Q.currentItemIndex)?Q.currentItemIndex:0,X=Date.now(),j=[];for(let Z of Y){if(!Z)continue;let q=Z.itemId,B=typeof Z.canonicalItemId==="string"&&Z.canonicalItemId?Z.canonicalItemId:q;if(typeof q!=="string"||!q)continue;j.push({type:"content-loaded",contentKind:Z.contentKind??"unknown",itemId:q,canonicalItemId:B,currentItemIndex:J,timestamp:X})}return j}buildLoadingCompleteReplayEvent(G){let Q=G.getRuntimeState?.();if(Q?.loadingComplete!==!0)return null;let Y=typeof Q.totalRegistered==="number"&&Number.isFinite(Q.totalRegistered)?Math.max(0,Q.totalRegistered):0,J=typeof Q.totalLoaded==="number"&&Number.isFinite(Q.totalLoaded)?Math.max(0,Q.totalLoaded):Y;return{type:"section-loading-complete",totalRegistered:Y,totalLoaded:J,currentItemIndex:Q.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(G){return this.subscribeSectionEvents({eventTypes:G.eventTypes||PQ,itemIds:G.itemIds,listener:G.listener})}subscribeSectionLifecycleEvents(G){return this.subscribeSectionEvents({eventTypes:G.eventTypes||LQ,listener:G.listener})}onSectionControllerLifecycle(G){return this.sectionControllerLifecycleListeners.add(G),()=>{this.sectionControllerLifecycleListeners.delete(G)}}async getOrCreateSectionController(G){if(this.disposePromise!==null)throw new d;let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId},Y=this.getSectionControllerMapKey(Q);this.latestRequestedActiveCohortMapKey=Y,this.suspendActiveCohortIfSuperseded(Y);let J=await this.resolveExistingSectionController({mapKey:Y,key:Q,input:G.input,updateExisting:G.updateExisting});if(J){if(this.disposePromise!==null)throw new d;return J}let X=this.sectionControllerDisposePromises.get(Y);if(X)await Promise.allSettled([X]);if(this.disposePromise!==null)throw new d;let j=this.sectionControllerInitEntries.get(Y);if(j)return j.promise;let Z={retired:!1,candidateClaimed:!1},q=this.initializeNewSectionController({args:G,key:Q,mapKey:Y,token:Z}).catch((B)=>{throw this.handleSectionControllerInitError(B,G),B}).finally(()=>{if(this.sectionControllerInitEntries.get(Y)?.token===Z)this.sectionControllerInitEntries.delete(Y)});return this.sectionControllerInitEntries.set(Y,{key:Q,token:Z,promise:q}),q}async resolveExistingSectionController(G){let Q=this.sectionControllers.get(G.mapKey);if(!Q)return;if(this.sectionControllerKeys.set(G.mapKey,G.key),G.updateExisting!==!1)await Q.updateInput?.(G.input);if(this.sectionControllers.get(G.mapKey)!==Q)return;return this.setActiveCohortIfLatestRequest(G.mapKey),Q}createSectionControllerContext(G){return{key:G.key,coordinator:this,input:G.input}}async initializeNewSectionController(G){let Q=this.createSectionControllerContext({key:G.key,input:G.args.input}),Y=await this.resolveSectionPersistence(Q);if(this.disposePromise!==null||G.token.retired){if(this.sectionPersistenceStrategies.get(G.mapKey)===Y)this.sectionPersistenceStrategies.delete(G.mapKey);throw this.createSectionControllerRetirementError()}let J={createDefaultController:G.args.createDefaultController},X=await this.hooks.createSectionController?.(Q,J)??await J.createDefaultController(),j={mapKey:G.mapKey,key:G.key,controller:X,persistence:Y,token:G.token};try{return await this.retireUnpublishedSectionControllerIfNeeded(j),await X.configureSessionPersistence?.({strategy:Y,context:Q}),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.initialize?.(G.args.input),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.hydrate?.(),await this.finalizeSectionControllerReady({...j,context:Q}),X}catch(Z){throw await this.cleanupUnpublishedSectionController(j),Z}}createSectionControllerRetirementError(){return this.disposePromise!==null?new d:new T8}async retireUnpublishedSectionControllerIfNeeded(G){if(this.disposePromise===null&&!G.token.retired)return;throw await this.cleanupUnpublishedSectionController(G),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(G){if(G.token.candidateClaimed)return;G.token.candidateClaimed=!0;try{await G.controller.dispose?.()}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:G.key.sectionId,attemptId:G.key.attemptId}})}finally{if(this.sectionPersistenceStrategies.get(G.mapKey)===G.persistence)this.sectionPersistenceStrategies.delete(G.mapKey)}}retirePublishedSectionControllerIfNeeded(G){if(this.disposePromise!==null&&!G.token.retired)this.disposeSectionController({sectionId:G.key.sectionId,attemptId:G.key.attemptId});if(G.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(G){await this.retireUnpublishedSectionControllerIfNeeded(G),this.sectionControllers.set(G.mapKey,G.controller),this.sectionControllerKeys.set(G.mapKey,G.key),G.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(G.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:G.key,controller:G.controller}),await this.hooks.onSectionControllerReady?.(G.context,G.controller),this.retirePublishedSectionControllerIfNeeded(G),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:G.key.assessmentId,sectionId:G.key.sectionId,attemptId:G.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(G)}handleSectionControllerInitError(G,Q){if(G instanceof d||G instanceof T8)return;this.handleError(G,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId}})}disposeSectionController(G){let Q={assessmentId:this.assessmentId,sectionId:G.sectionId,attemptId:G.attemptId},Y=this.getSectionControllerMapKey(Q),J=this.sectionControllerInitEntries.get(Y);if(J)J.token.retired=!0;let X=this.sectionControllers.get(Y);if(!X){let K=this.sectionControllerDisposePromises.get(Y);if(K)return K;if(!J)return Promise.resolve();let W=Promise.allSettled([J.promise]).then(()=>{return});return this.trackSectionControllerDisposal(Y,W)}let j=this.sectionPersistenceStrategies.get(Y);if(this.clearActiveCohortIfMatches(Y),this.sectionControllers.get(Y)===X)this.sectionControllers.delete(Y),this.sectionControllerKeys.delete(Y),this.sectionPersistenceStrategies.delete(Y),this.emitSectionControllerLifecycle({type:"disposed",key:Q});let Z=this.createSectionControllerContext({key:Q,input:void 0}),q=this.disposeSectionControllerEntry({args:G,key:Q,context:Z,controller:X,persistenceStrategy:j}),B=J?Promise.allSettled([J.promise]).then(()=>q):q;return this.trackSectionControllerDisposal(Y,B)}trackSectionControllerDisposal(G,Q){this.sectionControllerDisposePromises.set(G,Q);let Y=()=>{if(this.sectionControllerDisposePromises.get(G)===Q)this.sectionControllerDisposePromises.delete(G)};return Q.then(Y,Y),Q}async disposeSectionControllerEntry(G){try{await this.runSectionControllerDisposePipeline({key:G.key,context:G.context,controller:G.controller,persistBeforeDispose:G.args.persistBeforeDispose})}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:G.args.sectionId,attemptId:G.args.attemptId}})}finally{await this.finalizeSectionControllerDispose({context:G.context,persistenceStrategy:G.persistenceStrategy,clearPersistence:G.args.clearPersistence})}}async runSectionControllerDisposePipeline(G){let Q=[];if(G.persistBeforeDispose!==!1)try{await G.controller.persist?.()}catch(Y){Q.push(Y)}try{await G.controller.dispose?.()}catch(Y){Q.push(Y)}if(Q.length===1)throw Q[0];if(Q.length>1)throw AggregateError(Q,"Section controller persistence and disposal both failed.");await this.hooks.onSectionControllerDispose?.(G.context,G.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:G.key.assessmentId,sectionId:G.key.sectionId,attemptId:G.key.attemptId})}async finalizeSectionControllerDispose(G){if(G.clearPersistence)await G.persistenceStrategy?.clearSession?.(G.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let G=[],Q=async(J)=>{try{await J()}catch(X){G.push(X)}};await this.waitForAdmittedInitialization();let Y=new Map;for(let[J,X]of this.sectionControllerInitEntries)Y.set(J,X.key);for(let[J,X]of this.sectionControllerKeys)Y.set(J,X);for(let J of Y.values())this.disposeSectionController({sectionId:J.sectionId,attemptId:J.attemptId});await Promise.allSettled(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let J of this.activeSubscriptions.values())await Q(()=>J.unsubscribeCurrent?.()),J.unsubscribeCurrent=null;this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Q(()=>this.ttsService.stop()),await Q(()=>this.toolProviderRegistry.destroy()),await Q(()=>this.highlightCoordinator.destroy());for(let J of this.toolCoordinator.getRegisteredTools())await Q(()=>this.toolCoordinator.releaseTool(J));if(await Q(()=>this.catalogResolver.destroy()),await Q(()=>this.toolRequests.dispose()),await Q(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(G.length===1)throw G[0];if(G.length>1)throw AggregateError(G,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let G=new Set;if(this.coordinatorReadyPromise)G.add(this.coordinatorReadyPromise);if(this.ttsInitPromise)G.add(this.ttsInitPromise);if(this.ttsReconfigurePromise)G.add(this.ttsReconfigurePromise);for(let Q of this.providerInitPromises.values())G.add(Q);await Promise.allSettled(G)}async ensureTTSReady(G){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(G).then(()=>this.assertNotDisposed()).finally(()=>{this.ttsInitPromise=void 0}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let G=this.ttsReconfigurePromise;while(G)await G,G=this.ttsReconfigurePromise}async _initializeTTS(G){if(this.ttsInitialized)return;let Q=this.resolveTTSToolConfig(G),Y=v0(Q),J=w8(Y),X=h0(Y);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:J}}),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:J}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:J}),this.toolProviderRegistry.has("tts"))try{let q=await(await this.ensureProviderReady("tts")).createInstance();await this.initializeTTSService(q,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:J,provider:"registry"}),console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");return}catch(Z){if(Z instanceof d)throw Z;let q=Z instanceof Error?Z:Error(String(Z));await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,errorType:"TTSRegistryInitError",message:q.message,recovered:!0}),await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:J,fromProvider:"registry",toProvider:"browser",reason:q.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",q)}let j=new T7;try{await this.initializeTTSService(j,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:J,provider:"browser-fallback"})}catch(Z){if(Z instanceof d)throw Z;let q=Z instanceof Error?Z:Error(String(Z));throw this.handleError(q,{phase:"tts-init"}),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:q.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:J,errorType:"TTSInitError",message:q.message}),q}}resolveTTSToolConfig(G){return G||this.getTTSConfigFromProviders()||{}}async initializeTTSService(G,Q){let Y={...Q.providerOptions||{},__pieTelemetry:async(X,j)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...j||{}})}},J={...Q,providerOptions:Y};await this.ttsService.initialize(G,J),await this.ensureBrowserVoicesReady(G),this.assertNotDisposed(),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,await this.hooks.onTTSReady?.(),this.assertNotDisposed()}async ensureBrowserVoicesReady(G,Q=1200){if(G.providerId!=="browser")return;if(typeof window>"u")return;if(!("speechSynthesis"in window))return;let Y=window.speechSynthesis;if(Y.getVoices().length>0)return;await new Promise((j)=>{let Z=!1,q=typeof Y.addEventListener==="function"&&typeof Y.removeEventListener==="function",B=!q&&"onvoiceschanged"in Y,K=B?Y.onvoiceschanged:null,W=!1,$=()=>{if(Z)return;if(Z=!0,window.clearTimeout(N),q)Y.removeEventListener("voiceschanged",H);else if(W&&Y.onvoiceschanged===H)Y.onvoiceschanged=K;j()},H=(F)=>{if(!q&&typeof K==="function"&&F)K.call(Y,F);$()},N=window.setTimeout($,Q);if(q)Y.addEventListener("voiceschanged",H,{once:!0});else if(B)Y.onvoiceschanged=H,W=!0});let X=Y.getVoices();await this.emitTelemetry("pie-toolkit-tts-browser-voices-ready",{voiceCount:X.length,timedOut:X.length===0})}getServiceBundle(){return{ttsService:this.ttsService,toolCoordinator:this.toolCoordinator,highlightCoordinator:this.highlightCoordinator,elementToolStateStore:this.elementToolStateStore,catalogResolver:this.catalogResolver,toolProviderRegistry:this.toolProviderRegistry}}async getToolProvider(G){return this.ensureProviderReady(G)}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{await this.ensureStateLoaded(),this.assertNotDisposed();let G=this.getTTSConfigFromProviders();if(G?.enabled!==!1)await this.ensureTTSReady(G);if(this.assertNotDisposed(),!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-coordinator-ready",{assessmentId:this.assessmentId})})().finally(()=>{this.coordinatorReadyPromise=void 0}),this.coordinatorReadyPromise}isReady(){return this.getInitStatus().coordinator}getInitStatus(){let G={};for(let Y of this.toolProviderRegistry.getProviderIds())G[Y]=this.toolProviderRegistry.isInitialized(Y);let Q=this.getTTSConfigFromProviders();return{tts:this.ttsInitialized,stateLoaded:this.stateLoaded||!this.hooks.loadToolState,coordinator:(this.stateLoaded||!this.hooks.loadToolState)&&(this.ttsInitialized||Q?.enabled===!1),providers:G}}getTTSConfigFromProviders(){return(this.config.tools?.providers||{}).textToSpeech}assertCanonicalToolId(G){if(typeof G!=="string"||G.trim().length===0)throw Error("Tool id must be a non-empty string.");if(G==="tts")throw Error('Tool id "tts" is no longer supported. Use "textToSpeech".');if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(G))throw Error(`Unknown tool id "${G}".`)}installToolContextResolvers(G){if(!G)return;for(let[Q,Y]of Object.entries(G)){if(Y==null)continue;if(this.assertCanonicalToolId(Q),typeof Y!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);this.toolContextResolvers.set(Q,Y)}}setToolContextResolvers(G){this.toolContextResolvers.clear(),this.installToolContextResolvers(G??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let G of this.toolContextResolverChangeListeners)try{G()}catch(Q){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Q)}}isToolEnabled(G){return this.assertCanonicalToolId(G),this.config.tools?.providers?.[G]?.enabled!==!1}getToolConfig(G){return this.assertCanonicalToolId(G),this.config.tools?.providers?.[G]||null}updateToolConfig(G,Q){this.assertCanonicalToolId(G);let Y=this.getToolConfig(G)||{};if(!this.config.tools)this.config.tools=Z7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}).config;if(!this.config.tools.providers)this.config.tools.providers={};let J={...this.config.tools.providers||{},[G]:OQ(G,Y,Q)},X=Z7({...this.config.tools,providers:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});this.config.tools=X.config,this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:G}),this._applyToolConfigChange(G,Q)}updateToolPlacement(G,Q){this.updateToolsPlacement({[G]:[...Q]})}updateToolsPlacement(G){if(!this.config.tools)this.config.tools=Z7(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry}).config;let Q=this.config.tools?.placement??{section:[],item:[],passage:[]},Y={section:[...G.section??Q.section??[]],item:[...G.item??Q.item??[]],passage:[...G.passage??Q.passage??[]]},J=Z7({...this.config.tools,placement:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});J.config.placement=Y,this.config.tools=J.config,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(G){return this.policyEngine.decide(G)}decideFeaturePolicy(G){let Q=this.policyEngine.decideFeature(G);if(!Q.assessmentBound&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${G}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);return Q}onPolicyChange(G){return this.policyEngine.onPolicyChange(G)}onCatalogsChange(G){return this.catalogResolver.onCatalogsChange(G)}updateAssessment(G){this.boundAssessment=G,this.policyEngine.updateInputs({assessment:G,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}updateCurrentItemRef(G){this.boundCurrentItemRef=G,this.policyEngine.updateInputs({currentItemRef:G,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}setPnpEnforcement(G){this.pnpEnforcementOverride=G,this.policyEngine.updateInputs({pnpEnforcement:this.resolveEffectivePnpEnforcement()})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(G){return this.policyEngine.registerPolicySource(G)}registerToolContextResolver(G,Q){if(this.assertCanonicalToolId(G),typeof Q!=="function")throw Error(`Invalid tool context resolver for "${G}": expected a function.`);return this.toolContextResolvers.set(G,Q),this.notifyToolContextResolverChange(),()=>{if(this.toolContextResolvers.get(G)!==Q)return;this.toolContextResolvers.delete(G),this.notifyToolContextResolverChange()}}hasToolContextResolver(G){return this.assertCanonicalToolId(G),this.toolContextResolvers.has(G)}resolveToolContext(G){this.assertCanonicalToolId(G.toolId);let Q=this.toolContextResolvers.get(G.toolId);if(!Q)return null;let Y;try{Y=Q(G)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${G.toolId}" threw:`,X),{toolId:G.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!Y)return{toolId:G.toolId,visible:!0,params:{}};let J=Y.params&&typeof Y.params==="object"&&!Array.isArray(Y.params)?Y.params:{};return{toolId:G.toolId,visible:Y.visible!==!1,params:J,reason:typeof Y.reason==="string"?Y.reason:void 0}}onToolContextResolverChange(G){return this.toolContextResolverChangeListeners.add(G),()=>{this.toolContextResolverChangeListeners.delete(G)}}registerToolRequestTarget(G){return this.toolRequests.registerTarget(G)}requestTool(G){return this.assertCanonicalToolId(G.toolId),this.toolRequests.request(G)}canRequestTool(G,Q){try{this.assertCanonicalToolId(G)}catch{return!1}return this.toolRequests.canRequest(G,Q)}onToolRequestTargetsChange(G){return this.toolRequests.onTargetsChange(G)}resolveEffectivePnpEnforcement(){if(this.pnpEnforcementOverride!==null)return this.pnpEnforcementOverride;return l7({assessment:this.boundAssessment,currentItemRef:this.boundCurrentItemRef})}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(G,Q){if(this.disposePromise!==null)return;switch(G){case"textToSpeech":{let Y=this._reconfigureTTSProvider();this.ttsReconfigurePromise=Y,Y.finally(()=>{if(this.ttsReconfigurePromise===Y)this.ttsReconfigurePromise=void 0}),Y.then(async()=>{if(this.disposePromise!==null)return;let J=this.getTTSConfigFromProviders();if(!this.lazyInit&&J?.enabled!==!1)await this.ensureTTSReady(J)});break}case"answerEliminator":break}}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsInitPromise=void 0;try{this.ttsService.stop()}catch{}if(this.toolProviderRegistry.has("tts"))await this.toolProviderRegistry.unregister("tts");if(this.disposePromise!==null)return;let G=this.getProviderDescriptorTools().find((Q)=>Q.toolId==="textToSpeech");if(!G)return;await this.registerProviderFromTool(G)}}var wQ=()=>{};function l0(G){let{ttsService:Q,listenerId:Y,silence:J}=G;if(typeof Q?.onStateChange!=="function")return wQ;let X=(j)=>{if(j!==R.PLAYING&&j!==R.LOADING)return;J()};return Q.onStateChange(Y,X),()=>{try{Q.offStateChange?.(Y,X)}catch{}}}function d0(G){try{if(G?.isPlaying?.())G.pause?.()}catch{}}import{timedMediaProjectionSignature as G9}from"@pie-players/pie-players-shared/timed-media";var i0="pie-register",s0="pie-unregister",n0="pie-item-session-changed";var r0="pie-content-loaded",o0="pie-item-player-error",a0="pie-formative-action",t0="pie-media-time-source";var RQ={bubbles:!0,composed:!0,cancelable:!1};function EQ(G,Q,Y={}){return new CustomEvent(G,{detail:Q,...RQ,...Y})}function C8(G,Q,Y,J={}){return G.dispatchEvent(EQ(Q,Y,J))}function f7(){return{phase:"idle",cohort:null,controllerResolved:!1,readinessSignals:{sectionReady:!1,interactionReady:!1,allLoadingComplete:!1,runtimeError:!1},effectiveRuntime:null,effectiveToolsConfig:null,loadingCompleteEmitted:!1,lastFrameworkError:null,itemCount:0,loadedCount:0}}function y8(G,Q){if(G===Q)return!0;if(!G||!Q)return!1;return G.sectionId===Q.sectionId&&G.attemptId===Q.attemptId}function bQ(G){if(G.runtimeError)return"error";if(G.allLoadingComplete)return"ready";if(G.interactionReady)return"interaction-ready";if(G.sectionReady)return"loading";return"bootstrapping"}function e0(G){let Q=G.signals.sectionReady&&G.signals.allLoadingComplete,Y=G.mode==="strict"?Q:G.signals.interactionReady;return{phase:bQ({...G.signals,allLoadingComplete:Q,interactionReady:Y}),interactionReady:Y,allLoadingComplete:Q,reason:G.reason}}function G3(G){switch(G){case"idle":return null;case"booting-section":return"composed";case"engine-ready":return"engine-ready";case"interactive":return"interactive";case"disposed":return"disposed"}}function w1(G,Q,Y,J="entered"){let X=G3(Q);if(!X)return;G.push({kind:"stage-change",stage:X,status:J,cohort:Y})}function Q3(G){let Q={...f7(),phase:"booting-section",cohort:G.cohort,effectiveRuntime:G.effectiveRuntime,effectiveToolsConfig:G.effectiveToolsConfig,itemCount:G.itemCount},Y=[];return w1(Y,"booting-section",G.cohort),{state:Q,outputs:Y}}function SQ(G,Q){if(G.phase==="idle"||G.phase==="disposed")return{state:G,outputs:[]};let Y=e0({mode:Q.mode,signals:Q.signals}),J=[],X=G.phase,j=G.loadingCompleteEmitted;if(X==="engine-ready"&&Y.interactionReady)X="interactive",w1(J,X,G.cohort);if(Y.allLoadingComplete&&G.cohort&&!j)j=!0,J.push({kind:"loading-complete",cohort:G.cohort,itemCount:Q.itemCount,loadedCount:Q.loadedCount});return{state:{...G,phase:X,readinessSignals:Q.signals,loadedCount:Q.loadedCount,itemCount:Q.itemCount,loadingCompleteEmitted:j},outputs:J}}function d7(G,Q){switch(Q.kind){case"initialize":{if(G.phase==="disposed")return{state:G,outputs:[]};if(G.phase!=="idle"){if(y8(G.cohort,Q.cohort))return d7(G,{kind:"update-runtime",effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig});return d7(G,{kind:"cohort-change",cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount})}return Q3({state:G,cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount})}case"update-runtime":{if(G.phase==="idle"||G.phase==="disposed")return{state:G,outputs:[]};return{state:{...G,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig},outputs:[]}}case"cohort-change":{if(G.phase==="disposed")return{state:G,outputs:[]};if(y8(G.cohort,Q.cohort))return d7(G,{kind:"update-runtime",effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig});let Y=[];if(G.phase!=="idle")Y.push({kind:"stage-change",stage:"disposed",status:"entered",cohort:G.cohort});let J=Q3({state:G,cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount});return{state:J.state,outputs:[...Y,...J.outputs]}}case"section-controller-resolved":{if(G.phase!=="booting-section")return{state:{...G,controllerResolved:!0},outputs:[]};let Y=[];return w1(Y,"engine-ready",G.cohort),{state:{...G,phase:"engine-ready",controllerResolved:!0},outputs:Y}}case"update-readiness-signals":return SQ(G,{signals:Q.signals,mode:Q.mode,loadedCount:Q.loadedCount,itemCount:Q.itemCount});case"framework-error":return{state:{...G,lastFrameworkError:Q.error,readinessSignals:{...G.readinessSignals,runtimeError:Q.error.recoverable===!0?G.readinessSignals.runtimeError:!0}},outputs:[{kind:"framework-error",error:Q.error}]};case"dispose":{if(G.phase==="disposed")return{state:G,outputs:[]};let Y=[];if(G.phase!=="idle")w1(Y,"disposed",G.cohort);return{state:{...G,phase:"disposed"},outputs:Y}}default:{let Y=Q;return{state:G,outputs:[]}}}}class x8{state=f7();listeners=new Set;getState(){return this.state}dispatch(G){let Q=d7(this.state,G);if(this.state=Q.state,Q.outputs.length>0)this.fanOut(Q.outputs);return Q.outputs}subscribe(G){this.listeners.add(G);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(G)}}disposeListeners(){this.listeners.clear()}fanOut(G){let Q=Array.from(this.listeners),Y=Object.freeze(G.slice());for(let J of Q)try{J(Y)}catch(X){console.warn("[SectionEngineCore] listener failed:",X)}}}function Y3(G){let{coordinator:Q,dispatchCoreInput:Y}=G,J=0,X=null,j=null,Z=!1,q=Q.subscribeFrameworkErrors(($)=>{try{Y({kind:"framework-error",error:$})}catch(H){console.warn("[CoordinatorBridge] framework-error dispatch failed:",H)}});function B(){if(!j)return;try{j()}catch($){console.warn("[CoordinatorBridge] controller unsubscribe failed:",$)}j=null}async function K($){if(Z)return;J+=1;let H=J;X=$.cohort;let N=await Q.getOrCreateSectionController({sectionId:$.cohort.sectionId,attemptId:$.cohort.attemptId||void 0,input:{section:$.section,sectionId:$.cohort.sectionId,assessmentId:$.assessmentId,view:$.view},updateExisting:!0,createDefaultController:$.createDefaultController});if(H!==J||Z)return;B(),$.onControllerResolved?.(N);let F=N.getCompositionModel;if($.onCompositionChanged?.(F?.()),typeof N.subscribe==="function")j=N.subscribe((O)=>{if(H!==J||Z)return;$.onCompositionChanged?.(F?.())});Y({kind:"section-controller-resolved"})}async function W(){if(Z)return;Z=!0,J+=1,B();try{q()}catch(H){console.warn("[CoordinatorBridge] framework-error unsubscribe failed:",H)}let $=X;if(X=null,$)try{await Q.disposeSectionController({sectionId:$.sectionId,attemptId:$.attemptId||void 0})}catch(H){console.warn("[CoordinatorBridge] section-controller dispose failed:",H)}}return{resolveSectionController:K,dispose:W}}function J3(G){let{runtimeId:Q,sourceCe:Y}=G,J=G.host,X=G.now??(()=>new Date().toISOString());function j(W){let $={stage:W.stage,status:W.status,runtimeId:Q,sectionId:W.cohort?.sectionId,attemptId:W.cohort?.attemptId?W.cohort.attemptId:void 0,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-stage-change",{detail:$}))}function Z(W){let $={runtimeId:Q,sectionId:W.cohort.sectionId,attemptId:W.cohort.attemptId?W.cohort.attemptId:void 0,itemCount:W.itemCount,loadedCount:W.loadedCount,timestamp:X(),sourceCe:Y};J.dispatchEvent(new CustomEvent("pie-loading-complete",{detail:$}))}function q(W){J.dispatchEvent(new CustomEvent("framework-error",{detail:W.error}))}function B(W){switch(W.kind){case"stage-change":j(W);return;case"loading-complete":Z(W);return;case"framework-error":q(W);return;default:{let $=W;return}}}function K(W){J=W}return{dispatch:B,setHost:K}}function X3(G){let{bus:Q}=G;function Y(J){switch(J.kind){case"framework-error":Q.reportFrameworkError(J.error);return;case"stage-change":case"loading-complete":return;default:{let X=J;return}}}return{dispatch:Y}}function Z3(G={}){let Q=G.hook;function Y(X){if(!Q)return;try{Q(X)}catch(j){console.warn("[InstrumentationBridge] hook failed:",j)}}function J(X){Q=X}return{dispatch:Y,setHook:J}}function j3(){let G=new Set;function Q(j){if(j.length===0)return;let Z=Array.from(G),q=Object.freeze(j.slice());for(let B of Z)try{B(q)}catch(K){console.warn("[SubscriberFanout] listener failed:",K)}}function Y(j){G.add(j);let Z=!0;return()=>{if(!Z)return;Z=!1,G.delete(j)}}function J(){G.clear()}function X(){return G.size}return{emit:Q,subscribe:Y,dispose:J,getListenerCount:X}}class f8{core;domEventBridge;frameworkErrorBridge;instrumentationBridge;subscriberFanout;coordinatorBridge;unsubscribeCore;disposed=!1;constructor(G){this.core=G.core??new x8,this.domEventBridge=J3({host:G.host,runtimeId:G.runtimeId,sourceCe:G.sourceCe,now:G.now}),this.frameworkErrorBridge=X3({bus:G.frameworkErrorBus}),this.instrumentationBridge=Z3({hook:G.instrumentationHook}),this.subscriberFanout=j3(),this.coordinatorBridge=G.coordinator?Y3({coordinator:G.coordinator,dispatchCoreInput:(Q)=>this.dispatchInput(Q)}):null,this.unsubscribeCore=this.core.subscribe((Q)=>{this.routeOutputs(Q)})}getState(){return this.core.getState()}dispatchInput(G){if(this.disposed)return[];return this.core.dispatch(G)}subscribe(G){return this.subscriberFanout.subscribe(G)}setHost(G){this.domEventBridge.setHost(G)}setInstrumentationHook(G){this.instrumentationBridge.setHook(G)}resolveSectionController(G){if(!this.coordinatorBridge)throw Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");return this.coordinatorBridge.resolveSectionController(G)}async dispose(){if(this.disposed)return;if(this.disposed=!0,this.core.dispatch({kind:"dispose"}),this.unsubscribeCore(),this.subscriberFanout.dispose(),this.coordinatorBridge)await this.coordinatorBridge.dispose()}routeOutputs(G){for(let Q of G)this.routeOne(Q);this.subscriberFanout.emit(G)}routeOne(G){switch(G.kind){case"stage-change":case"loading-complete":this.domEventBridge.dispatch(G);break;case"framework-error":this.domEventBridge.dispatch(G),this.frameworkErrorBridge.dispatch(G);break;default:{let Q=G;return}}this.instrumentationBridge.dispatch(G)}}var TQ={mode:"gather",role:"student"};function R1(G,Q){return G!==void 0?G:Q}function CQ(G){let Q=G.runtime??{};if(Q.onFrameworkError!==void 0)return Q.onFrameworkError;return G.onFrameworkError}function yQ(G){let Q=G.runtime?.tools||{},Y=Q.placement||{};return{...Q,placement:{...Y}}}function xQ(G){let Q=G.runtime||{},Y=Q.player?{...Q.player}:null;return{...Q,assessmentId:R1(Q.assessmentId,G.assessmentId),playerType:Q.playerType??"iife",player:Y,lazyInit:Q.lazyInit??!0,accessibility:Q.accessibility??null,coordinator:Q.coordinator??null,createSectionController:Q.createSectionController,isolation:Q.isolation??"inherit",env:Q.env??TQ,toolConfigStrictness:R1(Q.toolConfigStrictness,G.toolConfigStrictness)??"error",onFrameworkError:CQ({runtime:G.runtime,onFrameworkError:G.onFrameworkError}),onStageChange:R1(Q.onStageChange,G.onStageChange),onLoadingComplete:R1(Q.onLoadingComplete,G.onLoadingComplete),tools:G.effectiveToolsConfig}}function q3(G,Q){let Y=G.assessmentId??"section-demo-direct",J=yQ({runtime:G.runtime}),X=xQ({assessmentId:Y,runtime:G.runtime,effectiveToolsConfig:J,toolConfigStrictness:G.toolConfigStrictness,onFrameworkError:G.onFrameworkError,onStageChange:G.onStageChange,onLoadingComplete:G.onLoadingComplete}),j=Q.resolvePlayerRuntime({effectiveRuntime:X,playerType:String(X.playerType??"iife"),env:X.env??null});return{effectiveToolsConfig:J,effectiveRuntime:X,playerRuntime:j}}import{createPieLogger as kQ,isGlobalDebugEnabled as IQ}from"@pie-players/pie-players-shared";function fQ(G,Q){if(G===Q)return 0;let Y=G.compareDocumentPosition(Q);if(Y&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(Y&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class k8{shellsByElement=new Map;register(G){let Q=this.shellsByElement.get(G.element),Y={...G,sortKey:Date.now()};if(Q&&Q.kind===Y.kind&&Q.itemId===Y.itemId&&Q.canonicalItemId===Y.canonicalItemId)return!1;return this.shellsByElement.set(G.element,Y),!0}unregister(G){return this.shellsByElement.delete(G)}getOrderedShells(G){let Q=Array.from(this.shellsByElement.values()).filter((Y)=>!G||Y.kind===G);return Q.sort((Y,J)=>fQ(Y.element,J.element)),Q}getCanonicalIdMap(){let G={};for(let Q of this.getOrderedShells("item")){if(!Q.itemId)continue;G[Q.itemId]=Q.canonicalItemId||Q.itemId}return G}clear(){this.shellsByElement.clear()}}function E1(G="runtime"){return`${G}-${Math.random().toString(16).slice(2)}-${Date.now()}`}var vQ=kQ("section-runtime-engine",()=>IQ());class I8{registry=new k8;runtimeId=E1("section-engine");adapter=null;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;loadedRenderableKeys=new Set;attachHost(G){if(this.adapter){if(this.adapter.setHost(G.host),G.instrumentationHook!==void 0)this.adapter.setInstrumentationHook(G.instrumentationHook);return}this.adapter=new f8({host:G.host,runtimeId:this.runtimeId,sourceCe:G.sourceCe,frameworkErrorBus:G.frameworkErrorBus,coordinator:G.coordinator,instrumentationHook:G.instrumentationHook,now:G.now})}dispatchInput(G){return this.adapter?.dispatchInput(G)??[]}subscribe(G){return this.adapter?.subscribe(G)??hQ}getState(){return this.adapter?.getState()??f7()}getEffectiveRuntime(G,Q){return q3(G,Q).effectiveRuntime}setInstrumentationHook(G){this.adapter?.setInstrumentationHook(G)}getRuntimeId(){return this.runtimeId}async initialize(G){this.activeInitToken+=1;let Q=this.activeInitToken;this.coordinator=G.coordinator,this.sectionId=G.sectionId,this.attemptId=G.attemptId;let Y=await G.coordinator.getOrCreateSectionController({sectionId:G.sectionId,attemptId:G.attemptId,input:{section:G.section,sectionId:G.sectionId,assessmentId:G.assessmentId,view:G.view},updateExisting:!0,createDefaultController:G.createDefaultController});if(Q!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=Y,this.replayRegisteredShellsIntoController(Y),G.onCompositionChanged?.(Y.getCompositionModel?.()),this.unsubscribeController=Y.subscribe?.((J)=>{try{G.onControllerEvent?.(J)}catch(X){vQ.warn("onControllerEvent handler threw",X)}G.onCompositionChanged?.(Y.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(G){if(!G.handleContentRegistered)return;let Q=this.registry.getOrderedShells();if(Q.length===0)return;for(let J of Q){let X=J.canonicalItemId||J.itemId;G.handleContentRegistered({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind})}let Y=Date.now();for(let J of Q){let X=J.canonicalItemId||J.itemId,j=this.getLoadedKey(X,J.contentKind);if(this.loadedRenderableKeys.has(j))G.handleContentLoaded?.({itemId:J.itemId,canonicalItemId:X,contentKind:J.contentKind||J.kind,timestamp:Y})}}getLoadedKey(G,Q){return`${Q??""}:${G}`}register(G){return this.registry.register(G)}unregister(G){return this.registry.unregister(G)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(G){return this.registry.getCanonicalIdMap()[G]||this.controller?.getCanonicalItemId?.(G)||G}handleContentRegistered(G){this.controller?.handleContentRegistered?.({itemId:G.itemId,canonicalItemId:G.canonicalItemId||G.itemId,contentKind:G.contentKind||G.kind})}handleContentUnregistered(G){let Q=G.canonicalItemId||G.itemId;this.loadedRenderableKeys.delete(this.getLoadedKey(Q,G.contentKind)),this.controller?.handleContentUnregistered?.({itemId:G.itemId,canonicalItemId:Q,contentKind:G.contentKind||G.kind})}handleContentLoaded(G){let Q=G.canonicalItemId||G.itemId;this.loadedRenderableKeys.add(this.getLoadedKey(Q,G.contentKind)),this.controller?.handleContentLoaded?.(G)}handleItemPlayerError(G){this.controller?.handleItemPlayerError?.(G)}reportSectionError(G){this.controller?.reportSectionError?.(G)}updateItemSession(G,Q){let Y=this.getCanonicalItemId(G);return this.controller?.updateItemSession?.(Y,Q)??null}navigateToItem(G){return this.controller?.navigateToItem?.(G)??null}handleFormativeAction(G){if(!G?.itemId)return;let Q=this.getCanonicalItemId(G.itemId);if(G.action==="retry"){this.controller?.retryFormativeItem?.({itemId:Q});return}this.controller?.recordFormativeTry?.({itemId:Q,outcomes:G.outcomes})}handleMediaTimeSource(G){if(G?.action==="detach"){this.controller?.detachMediaTimeSource?.({origin:G.origin??"host"});return}if(!G?.source)return;this.controller?.attachMediaTimeSource?.(G.source,{origin:G.origin??"host",renderableId:G.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}getRegistry(){return this.registry}async dispose(){if(this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null,this.coordinator&&this.sectionId)await this.coordinator.disposeSectionController({sectionId:this.sectionId,attemptId:this.attemptId});if(this.registry.clear(),this.loadedRenderableKeys.clear(),this.controller=null,this.coordinator=null,this.adapter){let G=this.adapter;this.adapter=null,await G.dispose()}}}var hQ=()=>{};import{ContextConsumer as mQ,createContext as uQ}from"@pie-players/pie-context";var U3=uQ(Symbol.for("pie.sectionRuntimeEngineHostContext"));function B3(G,Q){let Y=!1,J=new mQ(G,{context:U3,subscribe:!0,onValue:(B)=>{Y=!0,Q(B)}});J.connect();let X=(B)=>{if(B.context!==U3)return;J.requestValue()};G.addEventListener("context-provider",X);let j=0,Z=200,q=globalThis.setInterval(()=>{if(Y||j>=Z){globalThis.clearInterval(q);return}j+=1,J.requestValue()},50);return()=>{globalThis.clearInterval(q),G.removeEventListener("context-provider",X),J.disconnect()}}var pQ=(G)=>{console.error("[pie-assessment-toolkit] onStageChange handler threw",G)};function W3(G,Q){if(G.isSuppressed())return!1;G.dispatchDomEvent(Q);let Y=G.getOnStageChange();if(Y)try{Y(Q)}catch(J){(G.logHandlerError??pQ)(J)}return!0}function i7(G,Q){if(typeof G==="function")return G;if(G===null)return null;return typeof Q==="function"?Q:null}function K3(G={}){let Q=G.frameDeadlineMs??100,Y=!1,J=null,X=null,j=null,Z=null,q=null;function B(){if(Y=!1,X!==null)Z?.(X),X=null;if(j!==null)q?.(j),j=null;Z=null,q=null}function K(H){if(!Y)return;if(H==="frame")X=null;if(H==="timer")j=null;let N=J;J=null,B(),N?.()}function W(H){if(J=H,Y)return;Y=!0;let N=globalThis,F=i7(G.requestFrame,N.requestAnimationFrame);Z=i7(G.cancelFrame,N.cancelAnimationFrame);let O=i7(G.setTimer,N.setTimeout);if(q=i7(G.clearTimer,N.clearTimeout),F){let D=F(()=>K("frame"));if(!Y)return;if(X=D,O){let P=O(()=>K("timer"),Q);if(Y)j=P}return}let L=i7(G.queueMicrotaskFn,N.queueMicrotask);if(L){L(()=>K("microtask"));return}if(O){let D=O(()=>K("timer"),0);if(Y)j=D;return}K("microtask")}function $(){if(!Y)return;J=null,B()}return{schedule:W,cancel:$,isPending:()=>Y}}function _3(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function V3(G){G.lastSessionEventSignatureByItemId.clear(),G.lastMetadataSignatureByItemId.clear()}function $3(G){let{state:Q,itemId:Y,payload:J}=G;if(cQ(J)){let Z=lQ(J);if(Q.lastMetadataSignatureByItemId.get(Y)===Z)return!1;Q.lastMetadataSignatureByItemId.set(Y,Z)}let X=gQ(J);if(Q.lastSessionEventSignatureByItemId.get(Y)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(Y,X),!0}function gQ(G){let Q={...G};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function cQ(G){return G.intent==="metadata-only"}function lQ(G){try{return JSON.stringify({itemId:G.itemId,canonicalItemId:G.canonicalItemId,intent:G.intent,complete:G.complete??null,component:G.component??null})}catch{return String(G.itemId||"")}}var dQ=(G,Q)=>{if(customElements.get(G))return;try{customElements.define(G,Q)}catch(Y){if(!(Y instanceof DOMException&&Y.name==="NotSupportedError"||Y&&typeof Y==="object"&&Y.name==="NotSupportedError")||!customElements.get(G))throw Y}},Q9=u8('<div class="pie-assessment-toolkit-error svelte-vpe4u2" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-vpe4u2"> </div> <div class="pie-assessment-toolkit-error-message svelte-vpe4u2"> </div> <pre class="pie-assessment-toolkit-error-details svelte-vpe4u2"> </pre></div>'),Y9=u8('<div class="pie-assessment-toolkit-anchor svelte-vpe4u2" aria-hidden="true"></div> <!>',1),J9={hash:"svelte-vpe4u2",code:`.pie-assessment-toolkit-anchor.svelte-vpe4u2 {display:none;}.pie-assessment-toolkit-error.svelte-vpe4u2 {margin:0.75rem;padding:0.75rem 1rem;border-radius:0.5rem;border:1px solid
|
|
224
|
-
color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 40%, transparent);background:color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 12%, transparent);color:var(--pie-incorrect, #7f1d1d);font-size:0.9rem;}.pie-assessment-toolkit-error-title.svelte-vpe4u2 {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-vpe4u2 {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-vpe4u2 {margin:0;white-space:pre-wrap;word-break:break-word;}`};function C3(G,Q){N3(Q,!0),w3(G,J9);let Y=E1("toolkit"),J=new I8,X=h(null),j=new p7,Z={mode:"gather",role:"student"},q={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},B=x(Q,"assessmentId",7,""),K=x(Q,"section",7,null),W=x(Q,"sectionId",7,""),$=x(Q,"attemptId",7,""),H=x(Q,"env",23,()=>({})),N=x(Q,"ndsIcons",7,!1),F=x(Q,"locale",7,""),O=x(Q,"lazyInit",7,!0),L=x(Q,"toolConfigStrictness",7,"error"),D=x(Q,"tools",23,()=>({})),P=x(Q,"toolContextResolvers",7,null),S=x(Q,"enabledTools",7,""),v=x(Q,"toolRegistry",7,null),I=x(Q,"accessibility",23,()=>({})),p=x(Q,"player",7,null),E=x(Q,"playerType",7,""),g=x(Q,"coordinator",7,null),q7=x(Q,"createSectionController",7,null),U7=x(Q,"onFrameworkError",7,null),B7=x(Q,"errorRenderer",7,null),w7=x(Q,"onStageChange",7,null),s7=x(Q,"assessment",7,null),n7=x(Q,"currentItemRef",7,null),r7=x(Q,"pnpEnforcement",7,null),W7=x(Q,"isolation",7,"inherit"),k7=h(null),i=h(null),J7=h(null),p8=null,I7=null,v7=null,o7=null,h7=null,a7=null,t7=h(0),y1=h(null),m7=h(null),o=h(null),x1=h("Unable to initialize assessment toolkit."),f1=h(v8([])),g8="",k1="",c8=h(""),l8=null,d8=K3(),K7=[],e7=new Map,I1=new WeakMap,i8=_3(),s=nQ({sourceCe:"pie-assessment-toolkit",sourceCeShape:"toolkit",runtimeId:Y,sectionId:m(()=>W()||void 0),attemptId:m(()=>$()||void 0),emit:(U)=>{W3({isSuppressed:()=>V(X)!==null,dispatchDomEvent:(_)=>_7("pie-stage-change",_),getOnStageChange:()=>w7()},U)}}),s8=h(v8(m(()=>`${W()}|${$()}`))),G1=h(!1),t=h(!1),v1=h(!1),h1=h(!1);function y3(){if(!V(k7))return null;let U=V(k7).getRootNode();if(U&&"host"in U)return U.host;return V(k7).parentElement}let f=r(()=>y3());function _7(U,_){if(!V(f)){K7=[...K7,{name:U,detail:_}];return}C8(V(f),U,_)}b(()=>{if(!V(f))return;if(K7.length===0)return;let U=K7;K7=[],queueMicrotask(()=>{let _=V(f);if(!_){K7=[...U,...K7];return}for(let M of U)C8(_,M.name,M.detail)})});function x3(U){if(!B7())return{title:"Unable to initialize assessment toolkit.",details:U.details.length>0?U.details:[U.message]};try{let _=B7()(U)||{};return{title:typeof _.title==="string"&&_.title.trim().length>0?_.title:"Unable to initialize assessment toolkit.",details:Array.isArray(_.details)&&_.details.length>0?_.details.map((M)=>String(M)):U.details.length>0?U.details:[U.message]}}catch(_){let M=_ instanceof Error&&_.message.trim().length>0?_.message:String(_||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...U.details,`Error renderer failed: ${M}`]}}}function R7(U){let _=j1({kind:U.kind,source:U.source,error:U.error,recoverable:U.recoverable});return j.reportFrameworkError(_),_}function f3(U){if(U?.type==="timed-media-policy-degraded"){let M=U.degradations||[];j.reportFrameworkError(Z1({kind:"timed-media",severity:"warning",source:"pie-assessment-toolkit",message:"A timed-media playback policy degraded to advisory: the media time source does not report the capability it needs.",details:M.map((z)=>z?.message).filter((z)=>typeof z==="string"),recoverable:!0}));return}if(U?.type!=="timed-media-invalid")return;let _=U.errors||[];j.reportFrameworkError(Z1({kind:"timed-media",severity:"error",source:"pie-assessment-toolkit",message:'This section declares sectionType: "timed-media" but its timedMedia data is not deliverable; the section renders without cue behavior.',details:_.map((M)=>M?.message).filter((M)=>typeof M==="string"),recoverable:!1}))}function k3(U){if(U?.type!=="timed-media-audio-started")return;if(!V(C))return;d0(V(C).getServiceBundle().ttsService)}function I3(U){return U==="coordinator-init"||U==="runtime-init"||U==="tool-config"}function n8(U){if(!U7())return;try{U7()(U),g8=`${U.kind}|${U.source}|${U.message}`}catch(_){console.error(`[pie-framework:${U.kind}:${U.source}] framework error hook failed`,_)}}b(()=>{let U=j.subscribeFrameworkErrors((_)=>{if(console.error(Z6(_),_.cause),I3(_.kind)){let M=x3(_);w(o,_,!0),w(x1,M.title,!0),w(f1,M.details,!0)}_7("framework-error",_),n8(_)});return()=>{U()}}),b(()=>{if(!V(o))return;let U=`${V(o).kind}|${V(o).source}|${V(o).message}`;if(g8===U)return;n8(V(o))});function v3(U){let _=5381;for(let M=0;M<U.length;M+=1)_=(_<<5)+_^U.charCodeAt(M);return(_>>>0).toString(36)}function n(U){return U&&typeof U==="object"?U:{}}function h3(U){let _=n(U.section),M=typeof _.identifier==="string"?_.identifier:"",z=typeof U.sectionId==="string"?U.sectionId:"";return M||z}function m3(U){return typeof U.currentItemIndex==="number"?U.currentItemIndex:-1}function u3(U){return(Array.isArray(U.renderables)?U.renderables:[]).map((M,z)=>{let A=n(M),k=n(A.entity),G7=typeof k.id==="string"&&k.id||`renderable-${z}`,X1=n(k.config),d1=typeof k.version==="string"&&k.version||(typeof k.version==="number"?String(k.version):"")||(typeof X1.version==="string"?X1.version:"");return{id:G7,version:d1}})}function p3(U){let _=n(U.itemSessionsByItemId);return Object.keys(_).sort((M,z)=>M.localeCompare(z)).map((M)=>{let z=n(_[M]),A=typeof z.id==="string"?z.id:"",k=Array.isArray(z.data)?z.data:[],G7="";try{G7=v3(JSON.stringify(k))}catch{G7=String(k.length)}return{itemId:M,sessionId:A,payloadSignature:G7}})}function g3(U){let _=n(n(U.formative).states);return Object.entries(_).map(([M,z])=>{let A=n(z),k=n(A.lastOutcome).correctness??"";return`${M}:${A.tryCount??0}:${A.revealed===!0?1:0}:${String(k)}:${String(A.revealOverride??"")}`}).sort().join("|")}function c3(U){let _=U.timedMedia;return G9(_)}function l3(U){let _=n(U),M=u3(_).map((A)=>`${A.id}:${A.version}`).join("|"),z=p3(_).map((A)=>`${A.itemId}:${A.sessionId}:${A.payloadSignature}`).join("|");return{sectionId:h3(_),currentItemIndex:m3(_),renderableSignature:M,itemSessionSignature:z,formativeSignature:g3(_),timedMediaSignature:c3(_)}}function d3(U){let _=l3(U);return`${_.sectionId}|${_.currentItemIndex}|${_.renderableSignature}|${_.itemSessionSignature}|${_.formativeSignature}|${_.timedMediaSignature}`}function r8(U){return U==="iife"||U==="esm"||U==="preloaded"||U==="custom"}function i3(U,_){let M=U?.type,z=r8(M)?M:r8(_)?_:U?.tagName?"custom":"iife",A=U?.tagName?.trim();if(z==="custom"&&!A)return{type:"iife",tagName:q.iife,version:void 0,source:void 0,isDefault:!0};return{type:z,tagName:A||q[z],version:U?.version,source:U?.source,loaderConfig:U?.loaderConfig,loaderOptions:U?.loaderOptions,isDefault:!U&&!_}}function o8(U){let _=U||{},M=typeof _.mode==="string"&&_.mode.trim()?_.mode.trim():Z.mode,z=typeof _.role==="string"&&_.role.trim()?_.role.trim():Z.role;return{mode:M,role:z}}function s3(U){let _=o8(U);if(_.mode==="author")return"author";if(_.role==="instructor")return"scorer";return"candidate"}async function n3(){if(q7())return q7()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function a8(){let U=D()||{},_=T3(S());if(_.length===0)return U;let M=U.placement||{},z=Array.isArray(M.section)?M.section:null;if(z&&z.length>0)return U;return{...U,placement:{...M,section:_}}}function r3(){return Z7(a8(),{strictness:L(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:v()}).config}function o3(){let U="",_="";try{U=JSON.stringify(a8())}catch{U="[unserializable-tools]"}try{_=JSON.stringify(Object.entries(P()??{}).map(([M,z])=>[M,typeof z]))}catch{_="[unserializable-resolvers]"}return[B()||"",String(L()||"error"),U,_].join("|")}function t8(U){return U==="on"||U==="off"?U:null}function a3(U,_){let M=t8(U);if(M)return M;if(_&&typeof _==="object"){let A=_.pnpEnforcement;return t8(typeof A==="string"?A:null)}return null}function t3(U){let _=B()||K()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new L1({assessmentId:_,lazyInit:O(),toolConfigStrictness:L(),deferToolConfigValidation:!0,tools:U,toolRegistry:v(),toolContextResolvers:P(),accessibility:I(),frameworkErrorBus:j})}function m1(){let U=V(i);if(!U)return Promise.resolve();return w(i,null),U.dispose()}function u1(U){w(m7,U,!0),R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:U,recoverable:!0,details:{owner:"toolkit-coordinator"}})}let C=r(()=>{if(W7()!=="force"&&V(J7)?.coordinator)return V(J7).coordinator;return g()||V(i)});b(()=>{V(f),g(),W7(),V(J7),P(),m(()=>{if(!V(f))return;if(g()){if(V(i))m1().catch(u1);I7=null;return}if(W7()!=="force"&&V(J7)?.coordinator){if(V(i))m1().catch(u1);I7=null;return}if(V(i)&&I7!==P()){try{V(i).setToolContextResolvers(P()),I7=P()}catch(U){w(m7,U,!0),R7({kind:"coordinator-init",phase:"coordinator-ready",error:U})}return}if(!V(i)){let U=o3();if(k1===U)return;try{let _=r3();w(i,t3(_),!0),I7=P(),k1="",w(o,null),w(x1,"Unable to initialize assessment toolkit."),w(f1,[],!0)}catch(_){w(m7,_,!0),w(i,null),k1=U,R7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:_})}}})});let Q1=tQ(),p1=h(0);b(()=>Q1.subscribe(()=>{w(p1,V(p1)+1)})),b(()=>{let U=typeof F()==="string"?F().trim():"";m(()=>{Promise.resolve(Q1.setLocale(U||eQ)).catch((_)=>{R7({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:_ instanceof Error?_:Error(String(_))})})})});let X7=r(()=>B()||V(C)?.assessmentId||""),e=r(()=>W()||K()?.identifier||`section-${V(X7)||"default"}`),g1=r(()=>o8(H())),e3=r(()=>s3(V(g1))),E7=r(()=>i3(p(),E())),u7=r(()=>rQ({player:V(E7),component:"pie-assessment-toolkit"})),Y1=r(()=>{if(!V(C))return null;let U=V(C).getServiceBundle();return{toolkitCoordinator:V(C),toolCoordinator:V(C).toolCoordinator,ttsService:U.ttsService,highlightCoordinator:U.highlightCoordinator,catalogResolver:U.catalogResolver,elementToolStateStore:U.elementToolStateStore,assessmentId:V(X7),sectionId:V(e),itemPlayer:V(E7),ndsIcons:N()===!0,locale:(V(p1),Q1.getLocale()),i18n:Q1,reportSessionChanged:(_,M)=>{let z=J.updateItemSession(_,M);Q6({itemId:_,result:z,fallbackSession:M})}}}),J1=r(()=>{if(!V(C))return null;return{runtimeId:Y,coordinator:V(C)}});function G5(U){let _=d3(U);if(_===V(c8))return;w(c8,_,!0),w(t7,V(t7)+1),w(y1,U,!0),_7("composition-changed",{composition:V(y1),version:V(t7)})}function c1(U){l8=U??J.getCompositionModel(),d8.schedule(()=>{G5(l8)})}function l1(U){if(!U)return;let _=I1.get(U);if(!_)return;for(let M of _)M();I1.delete(U)}function e8(){for(let U of e7.values())l1(U.element)}function G6(U){if(l1(U.element),!V(C))return;let _=V(C).getServiceBundle().catalogResolver;I1.set(U.element,[_.registerOwner({owner:{kind:U.kind,itemId:U.itemId,canonicalItemId:U.canonicalItemId,assessmentId:V(X7),sectionId:V(e)},entity:U.item})])}function Q5(){e8();for(let U of e7.values())G6(U)}function Q6(U){let M={...U.result?.eventDetail||U.fallbackSession,itemId:U.itemId,canonicalItemId:U.canonicalItemId||U.itemId,sourceRuntimeId:Y};if(!$3({state:i8,itemId:U.itemId,payload:M}))return;_7("session-changed",M)}function Y5(U){if(!(U instanceof HTMLElement))return!1;return iQ(U,m8)?.runtimeId===Y}function V7(U){return U.detail??null}function J5(U,_){for(let M of _)U.addEventListener(M.name,M.handler);return()=>{for(let M of _)U.removeEventListener(M.name,M.handler)}}b(()=>{if(!V(f))return;if(W7()==="force"){w(J7,null);return}return S3(V(f),(U)=>{if(U.runtimeId===Y)return;w(J7,U,!0)})}),b(()=>{let U=V(f);return m(()=>{if(!U){w(X,null);return}let _=B3(U,(M)=>{if(M.engine===V(X))return;w(X,M.engine,!0)});return()=>{_(),w(X,null)}})}),b(()=>{let U=V(C);if(!U)return;return m(()=>l0({ttsService:U.getServiceBundle().ttsService,listenerId:`timed-media-audio-handoff:${Y}`,silence:()=>J.requestMediaPauseForCompetingAudio()}))}),b(()=>{let U=W7()!=="force"&&V(J7)?V(J7).runtimeId:null,_=U?"inherited":"owned";if(_!==p8)p8=_,_7(_==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:U})}),b(()=>{let U=V(e),_=$()||"";V3(i8)}),b(()=>{if(!V(f)||!V(J1))return;return h7=new H3(V(f),{context:m8,initialValue:V(J1)}),h7.connect(),a7=new D3(V(f)),a7.attach(),()=>{a7?.detach(),a7=null,h7?.disconnect(),h7=null}}),b(()=>{if(!V(J1))return;h7?.setValue(V(J1))}),b(()=>{if(!V(f))return;V(f).setAttribute("data-item-player-type",V(E7).type),V(f).setAttribute("data-item-player-tag",V(E7).tagName),V(f).setAttribute("data-env-mode",String(V(g1)?.mode||"")),V(f).setAttribute("data-env-role",String(V(g1)?.role||""))}),b(()=>{if(!V(f)||!V(Y1))return;return v7=new H3(V(f),{context:b3,initialValue:V(Y1)}),v7.connect(),o7=new D3(V(f)),o7.attach(),()=>{o7?.detach(),o7=null,v7?.disconnect(),v7=null}}),b(()=>{if(V(Y1))v7?.setValue(V(Y1))}),b(()=>{return V(C),V(X7),V(e),Q5(),()=>{e8()}}),b(()=>{if(!V(f))return;return sQ({host:V(f),instrumentationProvider:V(u7),component:"pie-assessment-toolkit",eventMap:oQ,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:V(X7),sectionId:V(e),attemptId:$()||void 0}})}),b(()=>{s7(),n7(),r7(),D();let U=V(C);if(!U)return;if(U!==V(i))return;m(()=>{U.setPnpEnforcement(a3(r7(),D())),U.updateAssessment(s7()),U.updateCurrentItemRef(n7())})}),b(()=>{if(!V(C))return;return V(C).subscribeTelemetry(({eventName:U,payload:_})=>{if(!aQ(V(u7)))return;if(!V(u7).isReady())return;let M=U,z=new Date().toISOString(),A={..._||{},instrumentationLayer:"toolkit",assessmentId:V(X7),sectionId:V(e),attemptId:$()||void 0,component:"pie-assessment-toolkit",sourceEventName:U,timestamp:z};V(u7).trackEvent(M,A);let k=_&&typeof _.errorType==="string"?_.errorType:void 0;if(!U.endsWith("-error")&&!k)return;let G7=_&&typeof _.message==="string"?_.message:`Toolkit telemetry error: ${U}`;V(u7).trackError(Error(G7),{component:"pie-assessment-toolkit",errorType:k||"ToolkitTelemetryError",...A})})}),b(()=>{if(!K()||!V(C))return;let U=!1;return J.initialize({coordinator:V(C),section:K(),sectionId:V(e),assessmentId:V(X7),attemptId:$()||void 0,view:V(e3),createDefaultController:n3,onCompositionChanged:(_)=>{if(U)return;c1(_)},onControllerEvent:(_)=>{if(U)return;k3(_),f3(_)}}).then(()=>{if(U)return;_7("toolkit-ready",{runtimeId:Y,assessmentId:V(X7),sectionId:V(e),itemPlayer:V(E7),coordinator:V(C)}),_7("section-ready",{sectionId:V(e)}),m(()=>{w(h1,!0)})}).catch((_)=>{if(U)return;m(()=>{if(!V(t))w(t,!0),s.enter("engine-ready","skipped");s.enter("interactive","failed")}),w(m7,_,!0),J.reportSectionError({source:"section-runtime",error:_,timestamp:Date.now()}),R7({kind:"runtime-init",source:"pie-assessment-toolkit",error:_})}),()=>{U=!0}}),b(()=>{if(!V(f))return;let U=V(f),_=(z)=>Y5(z.target);return J5(U,[{name:i0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.element||!A?.itemId)return;let k=J.register(A);if(e7.set(A.element,A),G6(A),J.handleContentRegistered(A),k)c1()}},{name:s0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;let k=A?.element?J.unregister(A.element):!1;if(l1(A.element),A.element)e7.delete(A.element);if(J.handleContentUnregistered(A),k)c1()}},{name:n0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;let k=J.updateItemSession(A.itemId,A.session);Q6({itemId:A.itemId,canonicalItemId:J.getCanonicalItemId(A.itemId),result:k,fallbackSession:A.session})}},{name:r0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;J.handleContentLoaded({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,detail:A.detail,timestamp:Date.now()})}},{name:o0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;J.handleItemPlayerError({itemId:A.itemId,canonicalItemId:A.canonicalItemId,contentKind:A.contentKind,error:A.error,timestamp:Date.now()})}},{name:a0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.itemId)return;if(A.action!=="check"&&A.action!=="retry")return;J.handleFormativeAction({itemId:A.canonicalItemId||A.itemId,action:A.action,outcomes:A.outcomes})}},{name:t0,handler:(z)=>{if(!_(z))return;let A=V7(z);if(!A?.renderableId)return;if(A.action!=="attach"&&A.action!=="detach")return;J.handleMediaTimeSource({renderableId:A.renderableId,action:A.action,source:A.source,origin:A.origin})}}])});async function X5(){if(!V(C))throw Error("Coordinator not initialized");await V(C).waitUntilReady()}function Z5(){if(!V(C))throw Error("Coordinator not initialized");return V(C).getServiceBundle()}function j5(U){if(!V(C))throw Error("Coordinator not initialized");V(C).setHooks(U)}function q5(U){return J.navigateToItem(U)}function U5(){return J.getCompositionModel()}function B5(){return V(E7)}async function W5(){await J.persist()}async function K5(){await J.hydrate()}b(()=>{return()=>{m(()=>{if(s.getCurrent()!==null)s.enter("disposed")})}}),b(()=>{let U=`${W()}|${$()}`;m(()=>{if(U===V(s8))return;if(s.getCurrent()!==null)s.enter("disposed");s.reset({sectionId:W()||void 0,attemptId:$()||void 0}),w(s8,U),w(G1,!1),w(t,!1),w(v1,!1),w(h1,!1)})}),b(()=>{let U=V(t)&&V(h1);m(()=>{if(!U)return;if(V(v1))return;w(v1,!0),s.enter("interactive")})}),b(()=>{let U=V(t7)>0||V(y1)!==null;m(()=>{if(!V(G1)&&U)w(G1,!0),s.enter("composed")})}),b(()=>{if(!V(C))return;if(!V(G1))return;if(V(t))return;let U=V(C),_=!1;return U.waitUntilReady().then(()=>{if(_)return;m(()=>{if(V(t))return;w(t,!0),s.enter("engine-ready")})}).catch(()=>{if(_)return;m(()=>{if(V(t))return;w(t,!0),s.enter("engine-ready","failed")})}),()=>{_=!0}}),b(()=>{return()=>{d8.cancel(),J.dispose().catch((U)=>{w(m7,U,!0),R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:U,recoverable:!0})}).then(()=>m1()).catch(u1).finally(()=>{j.dispose()})}});var _5={waitUntilReady:X5,getServiceBundle:Z5,setHooks:j5,navigateToItem:q5,getCompositionModel:U5,getItemPlayerConfig:B5,persist:W5,hydrate:K5,get assessmentId(){return B()},set assessmentId(U){B(U),y()},get section(){return K()},set section(U){K(U),y()},get sectionId(){return W()},set sectionId(U){W(U),y()},get attemptId(){return $()},set attemptId(U){$(U),y()},get env(){return H()},set env(U){H(U),y()},get ndsIcons(){return N()},set ndsIcons(U){N(U),y()},get locale(){return F()},set locale(U){F(U),y()},get lazyInit(){return O()},set lazyInit(U){O(U),y()},get toolConfigStrictness(){return L()},set toolConfigStrictness(U){L(U),y()},get tools(){return D()},set tools(U){D(U),y()},get toolContextResolvers(){return P()},set toolContextResolvers(U){P(U),y()},get enabledTools(){return S()},set enabledTools(U){S(U),y()},get toolRegistry(){return v()},set toolRegistry(U){v(U),y()},get accessibility(){return I()},set accessibility(U){I(U),y()},get player(){return p()},set player(U){p(U),y()},get playerType(){return E()},set playerType(U){E(U),y()},get coordinator(){return g()},set coordinator(U){g(U),y()},get createSectionController(){return q7()},set createSectionController(U){q7(U),y()},get onFrameworkError(){return U7()},set onFrameworkError(U){U7(U),y()},get errorRenderer(){return B7()},set errorRenderer(U){B7(U),y()},get onStageChange(){return w7()},set onStageChange(U){w7(U),y()},get assessment(){return s7()},set assessment(U){s7(U),y()},get currentItemRef(){return n7()},set currentItemRef(U){n7(U),y()},get pnpEnforcement(){return r7()},set pnpEnforcement(U){r7(U),y()},get isolation(){return W7()},set isolation(U){W7(U),y()}},Y6=Y9(),J6=h8(Y6);R3(J6,(U)=>w(k7,U),()=>V(k7));var V5=S1(J6,2);{var $5=(U)=>{var _=Q9(),M=M3(_),z=b1(M,!0),A=S1(M,2),k=b1(A,!0),G7=S1(A,2),X1=b1(G7,!0);A3(_),z3((d1)=>{C1(z,V(x1)),C1(k,V(o).message),C1(X1,d1)},[()=>V(f1).join(`
|
|
225
|
-
`)]),
|
|
222
|
+
`;for(let G of X)Y+=`- ${G.rule}: ${G.reason}
|
|
223
|
+
`}return Y}function f3(Z){let{request:Q,tools:J,pnpPolicy:Y,customSources:X,contextId:G}=Z,j=new U8(G);j.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=h9(J.placement[Q.level]),U=h9(J.policy.allowed),q=new Set(h9(J.policy.blocked)),K=[];for(let F of B)K.push(F),j.addDecision({precedence:0,rule:"placement-membership",featureId:F,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(K=K.filter((F)=>{if(J.providers?.[F]?.enabled===!1)return j.addDecision({precedence:0,rule:"provider-disabled",featureId:F,action:"block",sourceType:"host",reason:`tools.providers.${F}.enabled === false`,value:!1}),!1;return!0}),U.length>0){let F=new Set(U);K=K.filter((w)=>{if(!F.has(w))return j.addDecision({precedence:0,rule:"host-allowlist",featureId:w,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:U}),!1;return!0})}K=K.filter((F)=>{if(q.has(F))return j.addDecision({precedence:0,rule:"host-blocked",featureId:F,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:J.policy.blocked}),!1;return!0});let $=[],D=new Set(K),z=null;if(Y.enforcement==="on"&&Y.source&&(Y.assessment||Y.item)){if(z=Y.source.apply({assessment:Y.assessment,item:Y.item}),z.sources.assessment)j.addSource("assessment",z.sources.assessment);if(z.sources.student)j.addSource("student",z.sources.student);if(z.sources.item)j.addSource("item",z.sources.item);for(let F of z.decisions)j.addDecision({precedence:F.precedence,rule:F.rule,featureId:F.featureId,action:F.action,sourceType:F.sourceType,reason:F.reason,value:F.value});for(let[F,w]of z.unmappedSupportIds)$.push(V8(F,w,Q.level));for(let[F,w]of z.blockedOverrides)$.push(K8(F,w,Q.level));K=K.filter((F)=>{return!z.blockedToolIds.has(F)});for(let F of z.mandatedToolIds){if(!!D.has(F))continue;let b=z.perToolFlags.get(F)?.rule??"required-tool",S=d4(F,{placement:B,allowed:U,blocked:q,providers:J.providers}),h={rule:b,hostRule:S.hostRule,hostValue:S.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:F,message:`Profile policy mandates "${F}" (${b}) but host policy removed it from level "${Q.level}" via ${S.hostRule}.`,details:h}),j.addDecision({precedence:0,rule:"required-tool-blocked",featureId:F,action:"advisory",sourceType:"host",reason:`Host removed required tool "${F}" via ${S.hostRule}`,value:h})}}for(let F=0;F<X.length;F++){let w=X[F],R=K.slice(),b=w.refine({request:Q,candidates:R}),S=new Set(b.refinedCandidates);for(let C of b.refinedCandidates)if(!R.includes(C))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:C,message:`Custom source "${w.id}" tried to add tool "${C}" that was not in candidates; ignored.`,details:{customSourceId:w.id}}),S.delete(C);K=R.filter((C)=>S.has(C));let h=new Set;if(b.decisions){for(let C of b.decisions)if(j.addDecision({precedence:C.precedence??100+F,rule:C.rule,featureId:C.featureId,action:C.action,sourceType:C.sourceType,reason:C.reason,value:C.value}),C.action==="block")h.add(C.featureId)}for(let C of R){if(S.has(C))continue;if(h.has(C))continue;j.addDecision({precedence:100+F,rule:"custom-source",featureId:C,action:"block",sourceType:"custom",reason:`Custom policy source "${w.id}" removed tool "${C}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:w.id}})}}for(let F of K)for(let w of Z.unappliedItems??[]){let R=["restrictedTools","requiredTools"].filter((S)=>w.settings[S]?.includes(F)===!0);if(R.length===0)continue;let b={itemId:w.id,settings:R,toolbarLevel:Q.scope.level};$.push({code:"tool-policy.itemSettingNotApplied",level:Q.level,toolId:F,message:`Item "${w.id}" names "${F}" in ${R.join(" and ")}, but "${F}" is on the ${Q.scope.level}-level toolbar, which item settings do not reach. Place "${F}" at item level to enforce the setting per item.`,details:b})}let M=new Set(K),O=K.map((F)=>{let w=z?.perToolFlags.get(F);return{toolId:F,required:w?.required??!1,alwaysAvailable:w?.alwaysAvailable??!1,settings:w?.settings}});return j.reconcileFinalStates(M),{visibleTools:O,diagnostics:$,provenance:j.build()}}function d4(Z,Q){if(!Q.placement.includes(Z))return{hostRule:"placement-missing",hostValue:Q.placement};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.placement}}var I3={"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"};function K8(Z,Q,J){return{code:"tool-policy.overrideBlocked",...J?{level:J}:{},toolId:Z,message:`settings.testAdministration.toolOverrides grants "${Z}", but ${I3[Q]} withdraws it and outranks a granting override.`,details:{rule:Q}}}function V8(Z,Q,J){let Y=Q.map((X)=>I3[X]).join(", ");return{code:"tool-policy.unknownSupportId",...J?{level:J}:{},toolId:Z,message:`No tool is registered under "${Z}", named in ${Y}, so it matches nothing. These lists name tools by tool id.`,details:{origins:[...Q]}}}var l4=(Z)=>`No assessment is bound, so no policy source could grant "${Z}"`;function q8(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 v3(Z,Q,J){let Y=Q.decisions[0],X=Array.from(Q.perToolFlags.values())[0],G=Y?.action==="enable",j=Y?.reason??`Feature "${Z}" not configured`;return{featureId:Z,granted:G,action:Y?.action??"skip",rule:Y?.rule??"pnp-support",precedence:Y?.precedence??8,sourceType:Y?.sourceType??"system",reason:J.assessmentBound||G?j:l4(Z),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:J.assessmentBound,diagnostics:[...Array.from(Q.unmappedSupportIds,([B,U])=>V8(B,U)),...Array.from(Q.blockedOverrides,([B,U])=>K8(B,U))]}}function i4(Z){if(!Z)return!1;let Q=Z.personalNeedsProfile;if(Q){if(Array.isArray(Q.supports)&&Q.supports.length>0)return!0;if(Array.isArray(Q.prohibitedSupports)&&Q.prohibitedSupports.length>0)return!0}let J=Z.settings;if(J){let Y=J.districtPolicy;if(Y){if(Array.isArray(Y.blockedTools)&&Y.blockedTools.length>0)return!0;if(Array.isArray(Y.requiredTools)&&Y.requiredTools.length>0)return!0}let X=J.testAdministration?.toolOverrides;if(X&&typeof X==="object"&&Object.keys(X).length>0)return!0}return!1}function s4(Z){if(!Z)return!1;if(Array.isArray(Z.requiredTools)&&Z.requiredTools.length>0)return!0;if(Array.isArray(Z.restrictedTools)&&Z.restrictedTools.length>0)return!0;if(Z.toolParameters&&typeof Z.toolParameters==="object"&&Object.keys(Z.toolParameters).length>0)return!0;return!1}function h3(Z){if(i4(Z.assessment))return"on";if(s4(Z.itemSettings))return"on";return"off"}class p0{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((U)=>B.add(U)),Y?.prohibitedSupports?.forEach((U)=>B.add(U)),X?.blockedTools?.forEach((U)=>B.add(U)),X?.requiredTools?.forEach((U)=>B.add(U));for(let U of Object.keys(G?.toolOverrides??{}))B.add(U);j?.requiredTools?.forEach((U)=>B.add(U)),j?.restrictedTools?.forEach((U)=>B.add(U));for(let U of B)this.resolveSupport(U,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,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],unmappedSupportIds:this.unmappedIds(Y,X,G),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,toolConfigs:X?.toolConfigs},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}if(Y===!0){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Z,Q),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(Q.itemSettings?.requiredTools?.includes(Z)){J.mandatedToolIds.add(Z),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Z,Q),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(Q.districtPolicy?.requiredTools?.includes(Z)){J.mandatedToolIds.add(Z),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Z,Q),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(Q.pnp?.supports?.includes(Z)){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Z,Q),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}})}unmappedIds(Z,Q,J){let Y=new Map;if(this.toolRegistry.getAllTools().length===0)return Y;let X=[["district-block",Q?.districtPolicy?.blockedTools],["test-admin-override",Object.keys(Q?.testAdministration?.toolOverrides??{})],["item-restriction",J?.restrictedTools],["pnp-prohibited",Z?.prohibitedSupports],["item-requirement",J?.requiredTools],["district-requirement",Q?.districtPolicy?.requiredTools],["pnp-support",Z?.supports]];for(let[G,j]of X)for(let B of j??[]){if(this.toolRegistry.has(B))continue;let U=Y.get(B)??[];if(!U.includes(G))U.push(G);Y.set(B,U)}return Y}resolveToolSettings(Z,Q){return Q.itemSettings?.toolParameters?.[Z]??Q.toolConfigs?.[Z]}}var m3=c9({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class g0{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;pnpEnforcementOverride;itemSettings=new Map;disposed=!1;constructor(Z){this.toolRegistry=Z.toolRegistry,this.contextId=Z.contextId??"tool-policy",this.pnpPolicySource=new p0(this.toolRegistry),this.customSources=Z.customSources?[...Z.customSources]:[];let Q=Z.inputs??{};this.tools=Q.tools??m3,this.assessment=Q.assessment??null,this.pnpEnforcementOverride=Q.pnpEnforcement??null}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 f3({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){if(this.decideFeature(Z).granted)return!0;for(let Q of this.itemSettings.keys())if(this.decideFeature(Z,{level:"item",scopeId:Q}).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;return v3(Z,this.pnpPolicySource.resolveFeature(Z,{assessment:this.assessment??void 0,item:this.itemForScope(Q)}),{assessmentBound:this.assessment!==null})}hostFeatureGate(Z){let Q={assessmentBound:this.assessment!==null},J=h9(this.tools.policy.blocked);if(J.includes(Z))return q8(Z,"host-blocked",J,Q);let Y=h9(this.tools.policy.allowed);if(Y.length>0&&!Y.includes(Z))return q8(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??m3;if(!Object.is(this.tools,Y))this.tools=Y,Q=!0}if("assessment"in Z){let Y=Z.assessment??null;if(!t9(this.assessment,Y))Q=!0;this.assessment=Y}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.toolRegistry=Z,this.pnpPolicySource=new p0(Z),this.tools=Q,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){if(this.customSources.splice(Q,1),!this.disposed)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.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})}enforcementFor(Z){return this.pnpEnforcementOverride??h3({assessment:this.assessment,itemSettings:Z?.settings})}itemSettingsFor(Z){return this.itemSettings.get(Z)?.at(-1)?.settings}emitIfItemSettingsChanged(Z,Q){if(t9(Q,this.itemSettingsFor(Z)))return;this.emit({reason:"item-settings",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 n4,hasResponseValue as u3}from"@pie-players/pie-players-shared/pie";function e9(Z){return Boolean(Z)&&typeof Z==="object"&&!Array.isArray(Z)}function c0(Z){return e9(Z)&&e9(Z.session)?Z.session:Z}function r4(Z,Q){let J=e9(Z)?Z:{},Y=e9(Q)?Q:{},X=new Set([...Object.keys(J),...Object.keys(Y)]);for(let G of X)if(!t9(c0(J[G]),c0(Y[G])))return!1;return!0}function o4(Z,Q){for(let[J,Y]of Object.entries(Z)){if(Y===void 0)continue;if(J==="itemSessions"){if(!r4(Y,Q.itemSessions))return!1;continue}if(!t9(Y,Q[J]))return!1}return!0}function d0(Z,Q){if(!Z)return Q;let J=e9(Q.itemSessions)?{...Q.itemSessions}:{},Y=e9(Z.itemSessions)?Z.itemSessions:{};for(let[G,j]of Object.entries(Y)){if(!u3(c0(j)))continue;let B=c0(J[G]);if(u3(B)||n4(B))continue;J[G]=j}let X={...Q,itemSessions:J};return o4(X,Z)?null:X}class l extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class l0 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var p3=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),a4=(Z,Q,J)=>{let Y={...Q,...J};if(Z==="textToSpeech"&&p3(Q.mathSpeech)&&p3(J.mathSpeech))Y.mathSpeech={...Q.mathSpeech,...J.mathSpeech};return Y},t4=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],e4=["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 A8{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsDegraded=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadSettled=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;degradedTools=new Map;toolModuleFailures=new Set;readyChangeListeners=new Set;eagerInit;toolRegistry;toolRegistrySupplied;toolRegistrySettled;toolRegistryAbsent=!1;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new W8;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitEntries=new Map;sectionControllerDisposePromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;pnpEnforcementOverride=null;warnedPolicyDiagnostics=new Set;reportedUnboundFeaturePolicy=!1;reportedMissingTTSProvider=!1;heldMissingTTSProviderBackend=null;reportedRegistryUnavailable=!1;resolveConfig(Z){let Q=D1(Z.toolConfigStrictness),J=Z.toolRegistry??new $8,Y=Z.deferToolConfigValidation===!0?c9(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}=F1(Z,Q.toolRegistry),X=this.reportedRegistryUnavailable||this.toolRegistryPending()?Y.filter((G)=>G.code!=="tools.registryUnavailable"):Y;if(z1(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 $8,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks={...Q.hooks},this.lazyInit=Z.lazyInit===!0,this.eagerInit=Z.eagerInit??!this.lazyInit,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=Z.frameworkErrorBus??new B0,this.ownsFrameworkErrorBus=!Z.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new g3,this.highlightCoordinator=new $0,this.elementToolStateStore=new R1,this.catalogResolver=new w1(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new u0,this._registerToolProviders(),this.ttsService=new J8,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.ttsService.setReadinessGate(()=>this.ensureTTSReady()),this.ttsService.setMathSpeechSource(()=>B8(G8(this.resolveTTSToolConfig())).providerOptions?.mathSpeech),this.setupStatePersistenceHooks(),this.policyEngine=new g0({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,inputs:{tools:this.config.tools,assessment:null,pnpEnforcement:this.pnpEnforcementOverride}}),this.policyEngine.onPolicyChange((J)=>{if(J.reason!=="disposed")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="runtime"){let Y=s8({error:Z,context:Q,recoverable:Q.recoverable,scope:J});this.frameworkErrorBus.reportFrameworkError(Y)}isToolGranted(Z){try{return this.policyEngine.grantsFeatureAnywhere(Z)}catch{return!1}}reportToolFailure(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})}reportToolModuleFailure(Z,Q){if(this.toolRequests.notifyTargetsChange(),this.toolModuleFailures.has(Z))return;this.toolModuleFailures.add(Z);let J=Q instanceof Error&&Q.message.trim().length>0?Q.message:String(Q);this.reportToolFailure(Error(`Tool "${Z}" failed to load: ${J}`,{cause:Q}),{phase:"tool-module-load",details:{toolId:Z}},[Z])}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)}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.stateLoaded=!0,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??{},U=this.addToolTelemetryReporter(Y,B),q=this.createToolTelemetryForwarder(Y),K=J.getAuthFetcher?.(G)??G?.provider?.runtime?.authFetcher;X={provider:j,config:U,lazy:J.lazy??!0,authFetcher:K,onTelemetry:q}}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.reportToolFailure(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.reportToolFailure(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={assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId};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;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}clearActiveCohortIfMatches(Z){if(this.activeCohortMapKey!==Z)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.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||J){let X=Y?.type||null;if(Q&&(!X||!Q.has(X)))return!1;if(J){if(!Array.from(this.collectEventItemIds(Y)).some((j)=>J.has(j)))return!1}}return!0}}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,U=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:U,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||t4,itemIds:Z.itemIds,listener:Z.listener})}subscribeSectionLifecycleEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||e4,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={assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId},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(U){throw this.deliverSectionStartError(J,U),U}if(Y)return Y;let X=this.sectionControllerDisposePromises.get(J);if(X)await Promise.allSettled([X]);if(this.disposePromise!==null)throw new l;let G=this.sectionControllerInitEntries.get(J);if(G){if(!Z.initialSession)return G.promise;let U=await G.promise;return await this.assignSessionToPublishedController(U,Z.initialSession),U}let j={retired:!1,candidateClaimed:!1},B=this.initializeNewSectionController({args:Z,key:Q,mapKey:J,token:j}).catch((U)=>{throw this.handleSectionControllerInitError(U,Z),this.deliverSectionStartError(J,U),U}).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=d0(Z.getSession?.()??null,Q);if(!J)return;await Z.applySession(J,{mode:"replace"})}createSectionControllerRetirementError(){return this.disposePromise!==null?new l:new l0}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 l0)return;this.handleError(Z,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId},recoverable:!1},"cohort")}deliverSectionStartError(Z,Q){if(Q instanceof l||Q instanceof l0||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={assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId},J=this.getSectionControllerMapKey(Q),Y=this.sectionControllerInitEntries.get(J);if(Y)Y.token.retired=!0;let X=this.sectionControllers.get(J);if(!X){let q=this.sectionControllerDisposePromises.get(J);if(q)return q;if(!Y)return Promise.resolve();let K=Promise.allSettled([Y.promise]).then(()=>{return});return this.trackSectionControllerDisposal(J,K)}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}),U=Y?Promise.allSettled([Y.promise]).then(()=>B):B;return this.trackSectionControllerDisposal(J,U)}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 Promise.allSettled(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;this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Q(()=>this.ttsService.dispose()),await Q(()=>this.toolProviderRegistry.destroy()),await Q(()=>this.highlightCoordinator.destroy());for(let Y of this.toolCoordinator.getRegisteredTools())await Q(()=>this.toolCoordinator.releaseTool(Y));if(await Q(()=>this.catalogResolver.destroy()),await Q(()=>this.toolRequests.dispose()),await Q(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(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 Promise.allSettled(Z)}async ensureTTSReady(Z){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(Z).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(Z){if(this.ttsInitialized)return;let Q=this.resolveTTSToolConfig(Z),J=G8(Q),Y=j8(J),X=B8(J);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:Y}}),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:Y}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:Y}),this.toolProviderRegistry.has("textToSpeech"))try{let B=await(await this.initializeProvider("textToSpeech",!0)).createInstance();await this.initializeTTSService(B,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:Y,provider:"registry"});return}catch(j){if(j instanceof l)throw j;let B=j instanceof Error?j:Error(String(j));await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",operation:"tts-init",backend:Y,fromProvider:"registry",toProvider:"browser",reason:B.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",B)}else if(Y!=="browser")this.reportMissingTTSProvider(Y);let G=new X8;try{await this.initializeTTSService(G,Y==="browser"?X:y3(X)),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:Y,provider:"browser-fallback"})}catch(j){if(j instanceof l)throw j;let B=j instanceof Error?j:Error(String(j));throw this.reportToolFailure(B,{phase:"tts-init"},["textToSpeech"]),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:B.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:Y,errorType:"TTSInitError",message:B.message}),B}}resolveTTSToolConfig(Z){return Z||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(this.getTTSConfigFromProviders())}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]:a4(Z,J,Q)};this.config.tools=this.validateToolsConfig({...this.config.tools,providers:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}),this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId: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:this.config.tools})}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.warnedPolicyDiagnostics.has(Y))continue;this.warnedPolicyDiagnostics.add(Y),console.warn(`[ToolkitCoordinator] ${Q.message}`)}}registerItemSettings(Z,Q){return this.policyEngine.registerItemSettings(Z,Q)}decideFeaturePolicy(Z,Q){let J=this.policyEngine.decideFeature(Z,Q);this.warnPolicyDiagnostics(J.diagnostics);let Y=this.config.assessmentOptional!==!0||this.pnpEnforcementOverride==="on";if(!J.assessmentBound&&Y&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${Z}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);return J}onPolicyChange(Z){return this.policyEngine.onPolicyChange(Z)}onCatalogsChange(Z){return this.catalogResolver.onCatalogsChange(Z)}updateAssessment(Z){this.policyEngine.updateInputs({assessment:Z})}setPnpEnforcement(Z){this.pnpEnforcementOverride=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 Z2=()=>{};function c3(Z){return Z===P.PLAYING||Z===P.LOADING}function d3(Z){let{ttsService:Q,silence:J}=Z;if(typeof Q?.onStateChange!=="function")return Z2;let Y=Q.onStateChange((X)=>{if(c3(X))J()});return()=>{try{Y()}catch{}}}function l3(Z){try{if(c3(Z?.getState?.()))Z?.pause?.()}catch{}}import{timedMediaProjectionSignature as N2}from"@pie-players/pie-players-shared/timed-media";function i3(Z,Q,J){let Y=Z.detail?.runtimeId;if(typeof Y==="string"&&Y!=="")return Y===Q;return J(Z.target)}function s3(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 Q2=["a[href]","button","label","summary",...["button","checkbox","combobox","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","switch","tab","treeitem"].map((Z)=>`[role="${Z}"]`)].join(", "),n3=new Set(["mi","mn","mtext"]),J2=(Z)=>n3.has(Z.localName)||Z.localName==="mrow"&&Z.children.length===1&&n3.has(Z.children[0].localName),Y2=(Z)=>Array.from(Z.getElementsByTagName("mfrac")).every((Q)=>Array.from(Q.children).every(J2))?"Fraction_Over":"Fraction_General",X2=(Z)=>!Z||Z.toLowerCase().split("-")[0]==="en";function r3(Z,Q={}){if(typeof MutationObserver>"u")return()=>{};let J=new Map,Y=!1,X=async(K,$,D)=>{let z=await o9([{type:"math",mathml:K,fallbackText:""}],{language:D,loadSre:Q.loadSre,mathSpeech:{...X2(D)?{style:Y2($)}:{},engineOptions:Q.getMathSpeech?.()?.engineOptions}});return z.usedMathSpeech?z.speechText:null},G=(K)=>{if(!E1(K,Q2))return;let $=E9(K,"math"),D=$&&r9($.outerHTML);if(!$||!D)return;let z=MZ(K,{contentLanguage:Q.getContentLanguage?.()}),M=`${z??""}\x00${D}`,O=J.get(M);if(!O)O=X(D,$,z),J.set(M,O);O.then((F)=>{if(Y||!F||!K.isConnected)return;if(K.getAttribute("aria-label")!==F)K.setAttribute("aria-label",F)})},j=new WeakSet,B=(K)=>{if(j.has(K))return;j.add(K),q.observe(K,{childList:!0,subtree:!0})},U=(K)=>{if(K.nodeType!==1)return;let $=K,D=E1($,"mjx-container");if(D){G(D);return}if($.shadowRoot)B($.shadowRoot);W0($,(z)=>{if(z.nodeType!==1)return"skip";let M=z;if(M.localName==="mjx-container")return G(M),"skip";if(M.shadowRoot)B(M.shadowRoot);return})},q=new MutationObserver((K)=>{for(let $ of K)for(let D of $.addedNodes)U(D)});return B(Z),U(Z),()=>{Y=!0,q.disconnect()}}import{createPieLogger as j2,isGlobalDebugEnabled as B2}from"@pie-players/pie-players-shared";function G2(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 D8{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)=>G2(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 o3=j2("section-controller-binding",()=>B2());function W2(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}class F8{registry=new D8;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=W2(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){o3.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;if(!Q)return!0;return Q.has(Z.itemId)||!!Z.canonicalItemId&&Q.has(Z.canonicalItemId)}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(!X.renderableIds.has(Z.itemId)&&!(Z.canonicalItemId&&X.renderableIds.has(Z.canonicalItemId)))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)o3.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?.()}getRegistry(){return this.registry}async dispose(){if(this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null,this.coordinator&&this.sectionId)await this.coordinator.disposeSectionController({sectionId:this.sectionId,attemptId:this.attemptId});this.registry.clear(),this.loadedRenderableKeys.clear(),this.boundSections.clear(),this.controller=null,this.sectionRenderableIds=null,this.coordinator=null}}function a3(Z){let Q=Z.section?.identifier;return Z.sectionId||(typeof Q==="string"?Q:"")||`section-${Z.assessmentId||"default"}`}function t3(Z,Q){return["pnpEnforcement","assessment"].filter((Y)=>Z?!Object.is(Z[Y],Q[Y]):Q[Y]!==null)}function Z5(Z){if(!Z)return;let Q=Symbol.for("pie.assessmentToolkit.unclaimedRegistrationWatch"),J=Z;if(J[Q])return;J[Q]=!0,Z.addEventListener(i0,(Y)=>{let X=Y.detail,G=typeof X?.itemId==="string"?X.itemId:"";e3(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 Q5(Z={}){let Q=Z.frameDeadlineMs??100,J=!1,Y=null,X=null,G=null,j=null,B=null;function U(){if(J=!1,X!==null)j?.(X),X=null;if(G!==null)B?.(G),G=null;j=null,B=null}function q(D){if(!J)return;if(D==="frame")X=null;if(D==="timer")G=null;let z=Y;Y=null,U(),z?.()}function K(D){if(Y=D,J)return;J=!0;let z=globalThis,M=D0(Z.requestFrame,z.requestAnimationFrame);j=D0(Z.cancelFrame,z.cancelAnimationFrame);let O=D0(Z.setTimer,z.setTimeout);if(B=D0(Z.clearTimer,z.clearTimeout),M){let w=M(()=>q("frame"));if(!J)return;if(X=w,O){let R=O(()=>q("timer"),Q);if(J)G=R}return}let F=D0(Z.queueMicrotaskFn,z.queueMicrotask);if(F){F(()=>q("microtask"));return}if(O){let w=O(()=>q("timer"),0);if(J)G=w;return}q("microtask")}function $(){if(!J)return;Y=null,U()}return{schedule:K,cancel:$,isPending:()=>J}}function J5(Z="runtime"){return`${Z}-${Math.random().toString(16).slice(2)}-${Date.now()}`}function Y5(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function X5(Z){Z.lastSessionEventSignatureByItemId.clear(),Z.lastMetadataSignatureByItemId.clear()}function G5(Z){let{state:Q,itemId:J,payload:Y}=Z;if(K2(Y)){let j=V2(Y);if(Q.lastMetadataSignatureByItemId.get(J)===j)return!1;Q.lastMetadataSignatureByItemId.set(J,j)}let X=U2(Y);if(Q.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(J,X),!0}function U2(Z){let Q={...Z};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function K2(Z){return Z.intent==="metadata-only"}function V2(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 q2=(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}},w2=_8('<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>'),P2=_8('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),R2={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 b5(Z,Q){U5(Q,!0),z5(Z,R2);let J=H2("pie-assessment-toolkit",()=>_2()),Y=J5("toolkit"),X=new F8,G=new B0,j={mode:"gather",role:"student"},B={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},U=k(Q,"assessmentId",7,""),q=k(Q,"section",7,null),K=k(Q,"sectionId",7,""),$=k(Q,"attemptId",7,""),D=k(Q,"env",23,()=>({})),z=k(Q,"ndsIcons",7,!1),M=k(Q,"locale",7,""),O=k(Q,"contentLanguage",7,""),F=k(Q,"lazyInit",7,!1),w=k(Q,"toolConfigStrictness",7,"error"),R=k(Q,"tools",23,()=>({})),b=k(Q,"toolContextResolvers",7,null),S=k(Q,"enabledTools",7,""),h=k(Q,"toolRegistry",7,null),C=k(Q,"accessibility",23,()=>({})),U9=k(Q,"player",7,null),K9=k(Q,"playerType",7,""),u=k(Q,"coordinator",7,null),Q9=k(Q,"createSectionController",7,null),H9=k(Q,"onFrameworkError",7,null),_9=k(Q,"errorRenderer",7,null),M9=k(Q,"assessment",7,null),V9=k(Q,"isolation",7,"inherit"),L9=k(Q,"session",7,null),Z0=n(null),p=n(null),J9=n(null),M8=null,L8=null,Q0=!1,m9=null,u9=null,p9=null,F0=n(0),t0=n(null),Y9=n(null),e0=n("Unable to initialize assessment toolkit."),Z1=n(V5([])),O8="",Q1="",J0=null,Y0=null,z0=null,N8=null,J1=null,w8=null,H0=null,P8=!1,R8=null,E8=!1,C8=n(""),Y1=null,_0=Q5(),O9=[],M0=new Map,X1=new WeakMap,L0=new Map,b8=Y5(),X0=n(!1);function S5(){if(!A(Z0))return null;let W=A(Z0).getRootNode();if(W&&"host"in W)return W.host;return A(Z0).parentElement}let f=s(()=>S5());function N9(W,V){if(!A(f)){O9=[...O9,{name:W,detail:V}];return}H8(A(f),W,V)}T(()=>{if(!A(f))return;if(O9.length===0)return;let W=O9;O9=[],queueMicrotask(()=>{let V=A(f);if(!V){O9=[...W,...O9];return}for(let H of W)H8(V,H.name,H.detail)})});function T5(W){if(!_9())return{title:"Unable to initialize assessment toolkit.",details:W.details.length>0?W.details:[W.message]};try{let V=_9()(W)||{};return{title:typeof V.title==="string"&&V.title.trim().length>0?V.title:"Unable to initialize assessment toolkit.",details:Array.isArray(V.details)&&V.details.length>0?V.details.map((H)=>String(H)):W.details.length>0?W.details:[W.message]}}catch(V){let H=V instanceof Error&&V.message.trim().length>0?V.message:String(V||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...W.details,`Error renderer failed: ${H}`]}}}function w9(W){let V=A1({kind:W.kind,source:W.source,error:W.error,recoverable:W.recoverable,scope:W.scope});return G.reportFrameworkError(V),V}function y5(W){if(W?.type==="timed-media-policy-degraded"){let H=W.degradations||[];G.reportFrameworkError(E0({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:H.map((N)=>N?.message).filter((N)=>typeof N==="string"),recoverable:!0,scope:"cohort"}));return}if(W?.type!=="timed-media-invalid")return;let V=W.errors||[];G.reportFrameworkError(E0({kind:"timed-media",severity:"error",source:"pie-assessment-toolkit",message:'This section declares sectionType: "timed-media" but its timedMedia data is not deliverable; the section renders without cue behavior.',details:V.map((H)=>H?.message).filter((H)=>typeof H==="string"),recoverable:!1,scope:"cohort"}))}function x5(W){if(W?.type!=="timed-media-audio-started")return;if(!A(E))return;l3(A(E).ttsService)}function k5(W){return W==="coordinator-init"||W==="runtime-init"||W==="tool-config"}function G0(W){return`${W.kind}|${W.source}|${W.message}`}function S8(W){if(!H9())return;try{H9()(W),O8=G0(W)}catch(V){console.error(`[pie-framework:${W.kind}:${W.source}] framework error hook failed`,V)}}let T8=new WeakSet,y8=new WeakMap;function f5(W){if(typeof W!=="object"||W===null)return null;return y8.get(W)??null}function x8(W){let V=T5(W);v(Y9,W,!0),v(e0,V.title,!0),v(Z1,V.details,!0)}function k8(){v(Y9,null),v(e0,"Unable to initialize assessment toolkit."),v(Z1,[],!0)}T(()=>{let W=G.subscribeFrameworkErrors((V)=>{if(console.error(n8(V),V.cause),typeof V.cause==="object"&&V.cause!==null)y8.set(V.cause,V);if(k5(V.kind)&&!T8.has(V))x8(V);N9("framework-error",V),S8(V)});return()=>{W()}}),T(()=>{let W=u();if(!W||A(E)!==W)return;if(typeof W.subscribeFrameworkErrors!=="function")return;return I(()=>W.subscribeFrameworkErrors((V)=>{T8.add(V),G.reportFrameworkError(V)}))}),T(()=>{let W=A(E),V=h();if(!W||A(w0))return;if(typeof W.adoptToolRegistry!=="function")return;I(()=>{let H=W===A(p);if(H&&!V)return;if(W.adoptToolRegistry(V)&&H&&J0)J0={...J0,toolRegistry:V}})}),T(()=>{if(!A(Y9))return;if(O8===G0(A(Y9)))return;S8(A(Y9))});function I5(W){let V=5381;for(let H=0;H<W.length;H+=1)V=(V<<5)+V^W.charCodeAt(H);return(V>>>0).toString(36)}function r(W){return W&&typeof W==="object"?W:{}}function v5(W){let V=r(W.section),H=typeof V.identifier==="string"?V.identifier:"",N=typeof W.sectionId==="string"?W.sectionId:"";return H||N}function h5(W){return typeof W.currentItemIndex==="number"?W.currentItemIndex:-1}function m5(W){return(Array.isArray(W.renderables)?W.renderables:[]).map((H,N)=>{let L=r(H),_=r(L.entity),g=typeof _.id==="string"&&_.id||`renderable-${N}`,R0=r(_.config),$1=typeof _.version==="string"&&_.version||(typeof _.version==="number"?String(_.version):"")||(typeof R0.version==="string"?R0.version:"");return{id:g,version:$1}})}function u5(W){let V=r(W.itemSessionsByItemId);return Object.keys(V).sort((H,N)=>H.localeCompare(N)).map((H)=>{let N=r(V[H]),L=typeof N.id==="string"?N.id:"",_=Array.isArray(N.data)?N.data:[],g="";try{g=I5(JSON.stringify(_))}catch{g=String(_.length)}return{itemId:H,sessionId:L,payloadSignature:g}})}function p5(W){let V=r(r(W.formative).states);return Object.entries(V).map(([H,N])=>{let L=r(N),_=r(L.lastOutcome).correctness??"";return`${H}:${L.tryCount??0}:${L.revealed===!0?1:0}:${String(_)}:${String(L.revealOverride??"")}`}).sort().join("|")}function g5(W){let V=W.timedMedia;return N2(V)}function c5(W){let V=r(W),H=m5(V).map((L)=>`${L.id}:${L.version}`).join("|"),N=u5(V).map((L)=>`${L.itemId}:${L.sessionId}:${L.payloadSignature}`).join("|");return{sectionId:v5(V),currentItemIndex:h5(V),renderableSignature:H,itemSessionSignature:N,formativeSignature:p5(V),timedMediaSignature:g5(V)}}function d5(W){let V=c5(W);return`${V.sectionId}|${V.currentItemIndex}|${V.renderableSignature}|${V.itemSessionSignature}|${V.formativeSignature}|${V.timedMediaSignature}`}function f8(W){return W==="iife"||W==="esm"||W==="preloaded"||W==="custom"}function l5(W,V){let H=W?.type,N=f8(H)?H:f8(V)?V:W?.tagName?"custom":"iife",L=W?.tagName?.trim();if(N==="custom"&&!L)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:N,tagName:L||B[N],version:W?.version,source:W?.source,loaderConfig:W?.loaderConfig,loaderOptions:W?.loaderOptions,isDefault:!W&&!V}}function I8(W){let V=W||{},H=typeof V.mode==="string"&&V.mode.trim()?V.mode.trim():j.mode,N=typeof V.role==="string"&&V.role.trim()?V.role.trim():j.role;return{mode:H,role:N}}function i5(W){let V=I8(W);if(V.mode==="author")return"author";if(V.role==="instructor")return"scorer";return"candidate"}function s5(W,V){return W.sectionId===V.sectionId&&W.attemptId===V.attemptId}function v8(){if(!L9()||L9()===N8)return;N8=L9(),z0={value:L9(),cohort:{sectionId:A(a),attemptId:$()||void 0}}}function h8(W,V){v8();let H=z0;if(!H)return null;if(!s5(H.cohort,W)){if(V)z0=null;return null}return z0=null,H.value}function m8(){let W=J1,V=A(E);if(!W||!V)return;let H=h8(W,!1);if(!H)return;let N=V.getSectionController(W);if(!N)return;let L=d0(N.getSession?.()??null,H);if(!L)return;Promise.resolve().then(()=>{if(!N.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");return N.applySession(L,{mode:"replace"})}).catch((_)=>{w9({kind:"unknown",source:"pie-assessment-toolkit",error:_,recoverable:!0})})}async function n5(){if(Q9())return Q9()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function G1(){let W=R()||{},V=O5(S());if(V.length===0)return W;let H=W.placement||{},N=Array.isArray(H.section)?H.section:null;if(N&&N.length>0)return W;return{...W,placement:{...H,section:V}}}function r5(){return o8(G1(),{strictness:w(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:h()}).config}function o5(){let W="",V="";try{W=JSON.stringify(G1())}catch{W="[unserializable-tools]"}try{V=JSON.stringify(Object.entries(b()??{}).map(([H,N])=>[H,typeof N]))}catch{V="[unserializable-resolvers]"}return[U()||"",String(w()||"error"),W,V].join("|")}function a5(W){let V=W?.pnpEnforcement;return V==="on"||V==="off"?V:null}function t5(W){let V=U()||q()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new A8({assessmentId:V,lazyInit:F(),eagerInit:!1,toolConfigStrictness:w(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:W,toolRegistry:h(),toolContextResolvers:b(),accessibility:C(),frameworkErrorBus:G})}function u8(W){try{return JSON.stringify(W??null)}catch{return"[unserializable]"}}function p8(){return{signatures:{assessmentId:U()||"",toolConfigStrictness:String(w()||"error"),lazyInit:String(F()),tools:u8({...G1(),pnpEnforcement:void 0}),accessibility:u8(C())},toolRegistry:h()}}function e5(){let W=J0;if(!W)return[];let V=p8(),H=Object.keys(V.signatures).filter((N)=>V.signatures[N]!==W.signatures[N]);if(W.toolRegistry&&V.toolRegistry!==W.toolRegistry)H.push("toolRegistry");return H}function Z6(W,V){if(P8)return;P8=!0,console.warn(`[pie-assessment-toolkit] ${W.join(", ")} changed after ${V} 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 Q6(W){if(E8)return;E8=!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 O0(){let W=A(p);if(!W)return Promise.resolve();return v(p,null),W.dispose()}function N0(W){w9({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}let w0=s(()=>!u()&&V9()!=="force"&&A(J9)?.coordinator!=null),E=s(()=>{if(A(w0))return A(J9)?.coordinator;return u()||A(p)}),j1=s(()=>q()!=null);T(()=>{A(f),u(),V9(),A(J9),b(),A(j1),A(X0),R(),S(),U(),w(),F(),C(),h(),I(()=>{if(!A(f))return;if(u()){if(A(p))O0().catch(N0);m9=null;return}if(V9()!=="force"&&A(J9)?.coordinator){if(A(p))O0().catch(N0);m9=null;return}if(A(p)){let W=e5();if(W.length>0&&Y0)Z6(W,Y0);else if(W.length>0&&(q()||A(X0)))O0().catch(N0)}if(A(p)&&m9!==b()){try{A(p).setToolContextResolvers(b()),m9=b()}catch(W){w9({kind:"coordinator-init",source:"pie-assessment-toolkit",error:W})}return}if(!A(p)){if(V9()!=="force"&&!Q0){let V=B5(A(f),a0);if(V?.coordinator&&V.runtimeId!==Y){v(J9,V,!0),m9=null;return}}let W=o5();if(Q1===W)return;try{let V=r5();v(p,t5(V),!0),Q0=V9()!=="force",J0=p8(),Y0=null,m9=b(),Q1="",k8()}catch(V){v(p,null),Q1=W,w9({kind:"coordinator-init",source:"pie-assessment-toolkit",error:V})}}})}),T(()=>{if(!A(X0)||!A(E))return;let W=A(E);I(()=>{if(W===A(p))Y0??="an item registered"})});let P0=L2(),B1=n(0);T(()=>P0.subscribe(()=>{v(B1,A(B1)+1)})),T(()=>{let W=typeof M()==="string"?M().trim():"";I(()=>{Promise.resolve(P0.setLocale(W||O2)).catch((V)=>{w9({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:V instanceof Error?V:Error(String(V)),recoverable:!0})})})});let q9=s(()=>U()||A(E)?.assessmentId||""),a=s(()=>a3({sectionId:K(),section:q(),assessmentId:A(q9)})),W1=s(()=>I8(D())),J6=s(()=>i5(A(W1))),g9=s(()=>l5(U9(),K9())),j0=s(()=>D2({player:A(g9),component:"pie-assessment-toolkit"})),Y6=s(()=>{if(!A(E))return null;return{toolkitCoordinator:A(E),toolCoordinator:A(E).toolCoordinator,ttsService:A(E).ttsService,highlightCoordinator:A(E).highlightCoordinator,catalogResolver:A(E).catalogResolver,elementToolStateStore:A(E).elementToolStateStore,assessmentId:A(q9),sectionId:A(a),itemPlayer:A(g9),ndsIcons:z()===!0,locale:(A(B1),P0.getLocale()),i18n:P0,contentLanguage:O()?.trim()||void 0,reportSectionError:(W)=>{X.reportSectionError({source:"section-runtime",error:W,timestamp:Date.now()})}}}),X6=s(()=>{if(!A(E)||!A(f))return null;return{runtimeId:Y,coordinator:A(E),sectionBound:A(j1),eventTarget:A(f)}});function g8(W){if(W==null)return;let V=d5(W);if(V===A(C8))return;v(C8,V,!0),v(F0,A(F0)+1),v(t0,W,!0),N9("composition-changed",{composition:A(t0),version:A(F0)})}function U1(W){Y1=W??X.getCompositionModel(),_0.schedule(()=>{g8(Y1)})}function G6(){if(!_0.isPending())return;_0.cancel(),g8(Y1)}function K1(W){if(!W)return;let V=X1.get(W);if(!V)return;for(let H of V)H();X1.delete(W)}function c8(){for(let W of M0.values())K1(W.element)}function d8(W){if(K1(W.element),!A(E))return;X1.set(W.element,s3(A(E),W,{assessmentId:A(q9),sectionId:A(a)}))}function j6(){c8();for(let W of M0.values())d8(W)}function V1(W){if(!W)return;L0.get(W)?.(),L0.delete(W)}function B6(W){V1(W),L0.set(W,r3(W,{getMathSpeech:()=>A(E)?.ttsService.getMathSpeechOptions(),getContentLanguage:()=>O()}))}function W6(W){let H={...W.result?.eventDetail||W.fallbackSession,itemId:W.itemId,canonicalItemId:W.canonicalItemId||W.itemId,sourceRuntimeId:Y};if(!G5({state:b8,itemId:W.itemId,payload:H}))return;N9("session-changed",H)}function U6(W){if(!(W instanceof HTMLElement))return!1;return B5(W,a0)?.runtimeId===Y}function P9(W){return W.detail??null}function K6(W,V){for(let H of V)W.addEventListener(H.name,H.handler);return()=>{for(let H of V)W.removeEventListener(H.name,H.handler)}}T(()=>{let W=A(f),V=V9();return I(()=>{if(!W)return;if(V==="force")return v(J9,null),()=>{Q0=!1};let H=L5(W,(N)=>{if(N.runtimeId===Y)return;if(Q0){Q6(N.runtimeId);return}v(J9,N,!0)});return()=>{H(),v(J9,null),Q0=!1}})}),T(()=>{let W=A(E);if(!W)return;return I(()=>d3({ttsService:W.ttsService,silence:()=>X.requestMediaPauseForCompetingAudio()}))}),T(()=>{let W=A(w0)?A(J9)?.runtimeId??null:null,V=W?"inherited":"owned";if(V!==M8)M8=V,N9(V==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:W})}),T(()=>{let W=A(f);if(!W)return;I(()=>Z5(W.ownerDocument))}),T(()=>{let W=A(E);if(!W)return;let V=A(w0)?"inherited":"owned";I(()=>{if(W===L8)return;L8=W,N9("runtime-ready",{runtimeId:Y,coordinator:W,ownership:V})})}),T(()=>{let W=A(a),V=$()||"";X5(b8)}),T(()=>{if(!A(f))return;A(f).setAttribute("data-item-player-type",A(g9).type),A(f).setAttribute("data-item-player-tag",A(g9).tagName),A(f).setAttribute("data-env-mode",String(A(W1)?.mode||"")),A(f).setAttribute("data-env-role",String(A(W1)?.role||""))}),T(()=>{return A(E),A(q9),A(a),j6(),()=>{c8()}}),T(()=>{if(!A(f))return;return A2({host:A(f),instrumentationProvider:A(j0),component:"pie-assessment-toolkit",eventMap:F2,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:A(q9),sectionId:A(a),attemptId:$()||void 0}})});let q1=null;T(()=>{M9(),R();let W=A(E);if(!W)return;if(W!==A(p))return;I(()=>{let V={pnpEnforcement:a5(R()),assessment:M9()??null},H=q1?.coordinator===W?q1.inputs:null;q1={coordinator:W,inputs:V};for(let N of t3(H,V))if(N==="pnpEnforcement")W.setPnpEnforcement(V.pnpEnforcement);else W.updateAssessment(V.assessment)})}),T(()=>{if(!A(E))return;return A(E).subscribeTelemetry(({eventName:W,payload:V})=>{if(!M2(A(j0)))return;if(!A(j0).isReady())return;let H=W,N=new Date().toISOString(),L={...V||{},instrumentationLayer:"toolkit",assessmentId:A(q9),sectionId:A(a),attemptId:$()||void 0,component:"pie-assessment-toolkit",sourceEventName:W,timestamp:N};A(j0).trackEvent(H,L);let _=V&&typeof V.errorType==="string"?V.errorType:void 0;if(!W.endsWith("-error")&&!_)return;let g=V&&typeof V.message==="string"?V.message:`Toolkit telemetry error: ${W}`;A(j0).trackError(Error(g),{component:"pie-assessment-toolkit",errorType:_||"ToolkitTelemetryError",...L})})}),T(()=>{if(!q()||!A(E))return;let W=!1;if(A(E)===I(()=>A(p)))Y0??="a section initialized";let V={sectionId:A(a),attemptId:$()||void 0},H=w8;if(w8=V,H&&(H.sectionId!==V.sectionId||H.attemptId!==V.attemptId))I(()=>z2(A(f),{reason:"teardown",logger:J}));J1=null;let N=I(()=>h8(V,!0));return X.initialize({coordinator:A(E),section:q(),sectionId:A(a),assessmentId:A(q9),attemptId:$()||void 0,view:A(J6),initialSession:N,createDefaultController:n5,onCompositionChanged:(L)=>{if(W)return;U1(L)},onControllerEvent:(L)=>{if(W)return;x5(L),y5(L)}}).then(()=>{if(W)return;J1=V;let L=I(()=>A(Y9));if(L&&G0(L)===H0)k8();H0=null,I(()=>m8()),I(()=>G6()),queueMicrotask(()=>{if(W)return;N9("toolkit-ready",{runtimeId:Y,assessmentId:A(q9),sectionId:A(a),itemPlayer:A(g9),coordinator:A(E)}),N9("section-ready",{sectionId:V.sectionId,attemptId:V.attemptId,controller:A(E).getSectionController(V)??null})})}).catch((L)=>{if(W)return;let _=I(()=>f5(L));if(_)I(()=>x8(_)),H0=G0(_);else H0=G0(w9({kind:"runtime-init",source:"pie-assessment-toolkit",error:L,scope:"cohort"}))}),()=>{W=!0}}),T(()=>{L9(),I(()=>{v8(),m8()})}),T(()=>{if(!A(f))return;let W=A(f),V=(L)=>{if(!i3(L,Y,U6))return!1;return L.stopPropagation(),!0},N=K6(W,[{name:i0,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.element||!_?.itemId)return;let g=X.register(_);if(M0.set(_.element,_),v(X0,!0),d8(_),B6(_.element),X.handleContentRegistered(_),g)U1()}},{name:N5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;let g=_?.element?X.unregister(_.element):!1;if(K1(_.element),V1(_.element),_.element)M0.delete(_.element);if(X.handleContentUnregistered(_),g)U1()}},{name:w5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;let g=X.updateItemSession(_.itemId,_.session);W6({itemId:_.itemId,canonicalItemId:X.getCanonicalItemId(_.itemId),result:g,fallbackSession:_.session})}},{name:P5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;X.handleContentLoaded({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,detail:_.detail,timestamp:Date.now()})}},{name:R5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;X.handleItemPlayerError({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,error:_.error,timestamp:Date.now()})}},{name:E5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;if(_.action!=="check"&&_.action!=="retry")return;X.handleFormativeAction({itemId:_.itemId,canonicalItemId:_.canonicalItemId,action:_.action,outcomes:_.outcomes})}},{name:C5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.renderableId)return;if(_.action!=="attach"&&_.action!=="detach")return;X.handleMediaTimeSource({renderableId:_.renderableId,action:_.action,source:_.source,origin:_.origin})}}]);return()=>{N();for(let L of[...L0.keys()])V1(L)}}),T(()=>{if(!A(f))return;return()=>{p9?.disconnect(),p9=null,u9?.disconnect(),u9=null}}),T(()=>{let W=A(f),V=A(X6);if(!W||!V)return;I(()=>{if(p9){p9.setValue(V);return}p9=new j5(W,{context:a0,initialValue:V}),p9.connect()})}),T(()=>{let W=A(f),V=A(Y6);if(!W||!V)return;I(()=>{if(u9){u9.setValue(V);return}u9=new j5(W,{context:M5,initialValue:V}),u9.connect()})});async function V6(){if(!A(E))throw Error("Coordinator not initialized");await A(E).waitUntilReady()}function q6(W){if(!A(E))throw Error("Coordinator not initialized");A(E).setHooks(W)}function $6(W){return X.navigateToItem(W)}function A6(){return X.getCompositionModel()}function D6(){return A(g9)}async function F6(){await X.persist()}async function z6(){await X.hydrate()}T(()=>{let W=A(E);if(!W)return;let V=A(F0)>0||A(t0)!==null,H=!A(j1)&&A(X0);if(!V&&!H)return;I(()=>{if(W===R8)return;R8=W,W.waitUntilReady().catch(()=>{})})}),T(()=>{return()=>{_0.cancel(),X.dispose().catch((W)=>{w9({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}).then(()=>O0()).catch(N0).finally(()=>{G.dispose()})}});var H6={waitUntilReady:V6,setHooks:q6,navigateToItem:$6,getCompositionModel:A6,getItemPlayerConfig:D6,persist:F6,hydrate:z6,get assessmentId(){return U()},set assessmentId(W){U(W),x()},get section(){return q()},set section(W){q(W),x()},get sectionId(){return K()},set sectionId(W){K(W),x()},get attemptId(){return $()},set attemptId(W){$(W),x()},get env(){return D()},set env(W){D(W),x()},get ndsIcons(){return z()},set ndsIcons(W){z(W),x()},get locale(){return M()},set locale(W){M(W),x()},get contentLanguage(){return O()},set contentLanguage(W){O(W),x()},get lazyInit(){return F()},set lazyInit(W){F(W),x()},get toolConfigStrictness(){return w()},set toolConfigStrictness(W){w(W),x()},get tools(){return R()},set tools(W){R(W),x()},get toolContextResolvers(){return b()},set toolContextResolvers(W){b(W),x()},get enabledTools(){return S()},set enabledTools(W){S(W),x()},get toolRegistry(){return h()},set toolRegistry(W){h(W),x()},get accessibility(){return C()},set accessibility(W){C(W),x()},get player(){return U9()},set player(W){U9(W),x()},get playerType(){return K9()},set playerType(W){K9(W),x()},get coordinator(){return u()},set coordinator(W){u(W),x()},get createSectionController(){return Q9()},set createSectionController(W){Q9(W),x()},get onFrameworkError(){return H9()},set onFrameworkError(W){H9(W),x()},get errorRenderer(){return _9()},set errorRenderer(W){_9(W),x()},get assessment(){return M9()},set assessment(W){M9(W),x()},get isolation(){return V9()},set isolation(W){V9(W),x()},get session(){return L9()},set session(W){L9(W),x()}},l8=P2(),i8=z8(l8);H5(i8,(W)=>v(Z0,W),()=>A(Z0));var _6=n0(i8,2);{var M6=(W)=>{var V=w2(),H=q5(V),N=s0(H,!0),L=n0(H,2),_=s0(L,!0),g=n0(L,2),R0=s0(g,!0);W5(V),$5(($1)=>{o0(N,A(e0)),o0(_,A(Y9).message),o0(R0,$1)},[()=>A(Z1).join(`
|
|
225
|
+
`)]),r0(W,V)},L6=(W)=>{var V=A5(),H=z8(V);F5(H,Q,"default",{},null),r0(W,V)};D5(_6,(W)=>{if(A(Y9)&&!A(Y9).recoverable)W(M6);else W(L6,-1)})}return r0(Z,l8),K5(H6)}q2("pie-assessment-toolkit",_5(b5,{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"},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"},$2));export{b5 as default};
|