1import{_ as R,r as c,U as A,G as W,V as O,I as P,b as $,e as z,o as F,f as w,aW as L,ba as q}from"./JPKKIjon.js";const U={class:"tts-text-highlight-wrapper"},H={class:"slot-content"},V={__name:"ReaderTtsTextHighlight",props:{wordsPerSecond:{type:Number,default:3},autoStart:{type:Boolean,default:!0},loop:{type:Boolean,default:!0},loopDelay:{type:Number,default:1500},wordTimestamps:{type:Array,default:null}},setup(D,{expose:I}){const d=D,f=c(null),_=c(null),m=c(-1),v=c([]),T=c([]),i=c([]),g=c(!1),x=c(0),h=c(null),p=c(null),E=a=>a.toLowerCase().replace(/[^\w-]/g,""),B=()=>{if(!f.value)return;const a=f.value,e=[],t=o=>{o.nodeType===Node.TEXT_NODE?(o.textContent||"").split(/\s+/).filter(r=>r.length>0).forEach(r=>{e.push({text:r,node:o})}):o.nodeType===Node.ELEMENT_NODE&&o.tagName!=="BR"&&o.childNodes.forEach(s=>t(s))},l=a.querySelector(".slot-content");l&&t(l),v.value=e.map(o=>o.text)},C=()=>{if(!v.value.length)return;if(d.wordTimestamps&&d.wordTimestamps.length>0){i.value=d.wordTimestamps.map(e=>({word:e.word,startTime:e.startTime,endTime:e.startTime+(e.duration||0)}));return}const a=1e3/d.wordsPerSecond;i.value=v.value.map((e,t)=>({word:e,startTime:t*a,endTime:(t+1)*a}))},S=()=>{if(!f.value)return;const a=f.value.querySelector(".slot-content");if(!a)return;let e=0;const t=l=>{if(l.nodeType===Node.TEXT_NODE){const s=(l.textContent||"").split(/(\s+)/),n=document.createDocumentFragment();s.forEach(r=>{if(/\S/.test(r)){const u=document.createElement("span");u.className="word-span relative inline-block px-px",u.setAttribute("data-word-index",e),u.textContent=r,n.appendChild(u),e++}else r&&n.appendChild(document.createTextNode(r))}),l.parentNode.replaceChild(n,l)}else l.nodeType===Node.ELEMENT_NODE&&l.tagName!=="BR"&&Array.from(l.childNodes).forEach(o=>t(o))};t(a)},k=()=>{if(!i.value.length||!v.value.length)return;const a=[];let e=0;for(let t=0;t<i.value.length;t++){const l=i.value[t].word,o=E(l);let s=!1;for(let n=e;n<v.value.length;n++){const r=v.value[n],u=E(r);if(o===u){a[t]=n,e=n+1,s=!0;break}}s||(a[t]=-1)}T.value=a},b=a=>{if(!i.value.length||!T.value.length)return;const e=a*1e3,t=50;let l=-1;for(let o=i.value.length-1;o>=0;o--){const{startTime:s}=i.value[o];if(e>=s-t){l=o;break}}if(l!==-1){const o=T.value[l];m.value=o!==void 0&&o!==-1?o:-1}else m.value=-1},y=()=>{if(g.value)return;p.value&&(clearTimeout(p.value),p.value=null),g.value=!0,x.value=0,m.value=-1;const a=Date.now(),e=i.value.length>0?i.value[i.value.length-1].endTime/1e3:0;h.value=q(()=>{const t=(Date.now()-a)/1e3;x.value=t,b(t),t>=e&&(clearInterval(h.value),h.value=null,g.value=!1,m.value=-1,d.loop&&(p.value=setTimeout(()=>{y()},d.loopDelay)))},16)},N=()=>{h.value&&(clearInterval(h.value),h.value=null),p.value&&(clearTimeout(p.value),p.value=null),g.value=!1,m.value=-1,x.value=0};A(m,async a=>{await W();const e=_.value,t=f.value;if(!e||!t)return;if(a===-1){e.style.opacity="0";return}const o=Array.from(t.querySelectorAll(".word-span"))[a];if(o){const s=t.getBoundingClientRect(),n=o.getBoundingClientRect(),r=n.left-s.left+t.scrollLeft,u=n.top-s.top+t.scrollTop;e.style.left=`${r}px`,e.style.top=`${u}px`,e.style.width=`${n.width}px`,e.style.height=`${n.height}px`,e.style.opacity="1"}else e.style.opacity="0"});const M=async()=>{await W(),B(),S(),C(),k(),d.autoStart&&setTimeout(()=>y(),500)};return O(()=>{M()}),P(()=>{N()}),I({start:y,stop:N,isPlaying:$(()=>g.value)}),(a,e)=>(F(),z("div",U,[w("div",{ref_key:"textContainer",ref:f,class:"relative text-content"},[w("div",{ref_key:"highlightDiv",ref:_,class:"text-highlight-div"},null,512),w("div",H,[L(a.$slots,"default",{},void 0,!0)])],512)]))}},G=R(V,[["__scopeId","data-v-6fa25820"]]);export{G as _};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.