@supernal/tts-widget 1.0.3 → 1.0.5

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/dist/loader.js CHANGED
@@ -1,38 +1,38 @@
1
- var M=Object.defineProperty;var x=(S,e)=>()=>(S&&(e=S(S=0)),e);var P=(S,e)=>{for(var t in e)M(S,t,{get:e[t],enumerable:!0})};var A={};P(A,{SupernalTTS:()=>L,default:()=>B});var L,B,C=x(()=>{"use strict";L=class S{constructor(e={}){this.currentAudio=null;this.currentButton=null;this.isProcessing=!1;this.lastClickTime=0;this.debounceDelay=300;this.progressUpdateInterval=null;this.audioQueue=[];this.apiUrl=e.apiUrl||"https://www.tts.supernal.ai",this.defaultVoice=e.voice||"default",this.defaultProvider=e.provider||"openai",this.defaultSpeed=e.speed||1,this.autoHash=e.autoHash!==!1,this.cacheExpiry=e.cacheExpiry||7*24*60*60*1e3,this.apiKey=e.apiKey||this.detectApiKey(),this.showBranding=e.showBranding!==!1,this.version=e.version||"1.0.0",this.devMode=e.devMode===!0,this.clientSideSpeed=e.clientSideSpeed!==!1,this.generationMode=e.generationMode||"standard",this.progressiveThreshold=e.progressiveThreshold||2e3,this.cache=new Map,this.loadCacheFromStorage(),this.init()}detectApiKey(){if(typeof window>"u")return;let e=["NEXT_PUBLIC_TTS_API_KEY","VITE_TTS_API_KEY","PUBLIC_TTS_API_KEY","REACT_APP_TTS_API_KEY"];for(let t of e)try{let s=globalThis.process?.env;if(s?.[t])return console.log(`[TTS Widget] Auto-detected API key from process.env.${t}`),s[t];let i=globalThis.import?.meta?.env;if(i?.[t])return console.log(`[TTS Widget] Auto-detected API key from import.meta.env.${t}`),i[t]}catch{continue}}init(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initializeWidgets()):this.initializeWidgets(),this.observeDOM()}observeDOM(){new MutationObserver(t=>{t.forEach(s=>{s.addedNodes.forEach(i=>{if(i.nodeType===Node.ELEMENT_NODE){let o=i;o.classList?.contains("supernal-tts-widget")?this.setupWidget(o):o.querySelectorAll?.(".supernal-tts-widget")?.forEach(r=>this.setupWidget(r))}})})}).observe(document.body,{childList:!0,subtree:!0})}initializeWidgets(){let e=document.querySelectorAll(".supernal-tts-widget");e.forEach(t=>this.setupWidget(t)),this.devMode&&e.length>0&&this.addDevModeClearButton()}setupWidget(e){if(e.classList.contains("supernal-tts-widget-initialized"))return;let t=this.parseWidgetConfig(e);if(!t.text){console.warn("TTS Widget: No text found for widget",e);return}let s=this.generateHash(t.text,{voice:t.voice,provider:t.provider,speed:t.speed}),i=e.dataset.controls;if(i==="advanced"||i==="true"){this.setupAdvancedWidget(e,t.text,{voice:t.voice,provider:t.provider,speed:t.speed,hash:s,apiKey:t.apiKey});return}else if(i==="compact"){this.setupCompactWidget(e,t.text,{voice:t.voice,provider:t.provider,speed:t.speed,hash:s,apiKey:t.apiKey});return}this.setupModularWidget(e,t,s)}scrubText(e){if(!e)return"";let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1"),t=t.replace(/https?:\/\/[^\s]+/g,"link"),t=t.replace(/www\.[^\s]+/g,"link"),t}parseWidgetConfig(e){let t=e.dataset.text||e.textContent?.trim()||"",s=this.scrubText(t),i=e.dataset.voice||this.defaultVoice,o=e.dataset.provider||this.defaultProvider,n=e.dataset.speed?parseFloat(e.dataset.speed):this.defaultSpeed,r=e.dataset.voices||"",a=r?r.split(",").map(h=>h.trim()).filter(Boolean):[],l=e.dataset.enableSpeed==="true",d=e.dataset.enableProgress==="true",p=e.dataset.apiKey||this.apiKey;return{text:s,voices:a,enableSpeed:l,enableProgress:d,speed:n,provider:o,voice:i,apiKey:p}}setupBasicWidget(e,t,s){let{voice:i,provider:o,speed:n,hash:r,apiKey:a}=s;if(e.classList.contains("supernal-tts-widget-initialized"))return;let l=document.createElement("div");l.className="supernal-tts-button-container";let d=e.querySelector(".supernal-tts-play");if(d||(d=this.createPlayButton()),l.appendChild(d),this.showBranding&&!e.querySelector(".supernal-badge")){let p=this.createBrandingBadge();l.appendChild(p)}e.appendChild(l),e.classList.add("supernal-tts-widget-initialized"),d.addEventListener("click",p=>{p.preventDefault(),this.handlePlayClick(d,t,{voice:i,provider:o,speed:n,hash:r,apiKey:a})}),e._ttsWidget={text:t,voice:i,provider:o,speed:n,hash:r,playButton:d}}setupCompactWidget(e,t,s){let{hash:i,apiKey:o}=s,{voice:n,provider:r,speed:a}=s;if(e.classList.contains("supernal-tts-widget-initialized"))return;let l=document.createElement("div");l.className="supernal-tts-compact-widget";let d=document.createElement("div");d.className="supernal-tts-top-row";let p=this.createPlayButton(),h=document.createElement("select");if(h.className="supernal-tts-voice-select",h.innerHTML=`
2
- <option value="alloy" ${n==="alloy"?"selected":""}>Alloy</option>
3
- <option value="echo" ${n==="echo"?"selected":""}>Echo</option>
4
- <option value="fable" ${n==="fable"?"selected":""}>Fable</option>
5
- <option value="onyx" ${n==="onyx"?"selected":""}>Onyx</option>
6
- <option value="nova" ${n==="nova"?"selected":""}>Nova</option>
7
- <option value="shimmer" ${n==="shimmer"?"selected":""}>Shimmer</option>
8
- <option value="coral" ${n==="coral"?"selected":""}>Coral</option>
1
+ var M=Object.defineProperty;var x=(S,e)=>()=>(S&&(e=S(S=0)),e);var P=(S,e)=>{for(var t in e)M(S,t,{get:e[t],enumerable:!0})};var A={};P(A,{SupernalTTS:()=>L,default:()=>B});var L,B,C=x(()=>{"use strict";L=class S{constructor(e={}){this.currentAudio=null;this.currentButton=null;this.isProcessing=!1;this.lastClickTime=0;this.debounceDelay=300;this.progressUpdateInterval=null;this.audioQueue=[];this.apiUrl=e.apiUrl||"https://www.tts.supernal.ai",this.defaultVoice=e.voice||"default",this.defaultProvider=e.provider||"openai",this.defaultSpeed=e.speed||1,this.autoHash=e.autoHash!==!1,this.cacheExpiry=e.cacheExpiry||7*24*60*60*1e3,this.apiKey=e.apiKey||this.detectApiKey(),this.showBranding=e.showBranding!==!1,this.version=e.version||"1.0.0",this.devMode=e.devMode===!0,this.clientSideSpeed=e.clientSideSpeed!==!1,this.generationMode=e.generationMode||"standard",this.progressiveThreshold=e.progressiveThreshold||2e3,this.cache=new Map,this.loadCacheFromStorage(),this.init()}detectApiKey(){if(typeof window>"u")return;let e=["NEXT_PUBLIC_TTS_API_KEY","VITE_TTS_API_KEY","PUBLIC_TTS_API_KEY","REACT_APP_TTS_API_KEY"];for(let t of e)try{let s=globalThis.process?.env;if(s?.[t])return console.log(`[TTS Widget] Auto-detected API key from process.env.${t}`),s[t];let n=globalThis.import?.meta?.env;if(n?.[t])return console.log(`[TTS Widget] Auto-detected API key from import.meta.env.${t}`),n[t]}catch{continue}}init(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initializeWidgets()):this.initializeWidgets(),this.observeDOM()}observeDOM(){new MutationObserver(t=>{t.forEach(s=>{s.addedNodes.forEach(n=>{if(n.nodeType===Node.ELEMENT_NODE){let o=n;o.classList?.contains("supernal-tts-widget")?this.setupWidget(o):o.querySelectorAll?.(".supernal-tts-widget")?.forEach(r=>this.setupWidget(r))}})})}).observe(document.body,{childList:!0,subtree:!0})}initializeWidgets(){let e=document.querySelectorAll(".supernal-tts-widget");e.forEach(t=>this.setupWidget(t)),this.devMode&&e.length>0&&this.addDevModeClearButton()}setupWidget(e){if(e.classList.contains("supernal-tts-widget-initialized"))return;let t=this.parseWidgetConfig(e);if(!t.text){console.warn("TTS Widget: No text found for widget",e);return}let s=this.generateHash(t.text,{voice:t.voice,provider:t.provider,speed:t.speed}),n=e.dataset.controls;if(n==="advanced"||n==="true"){this.setupAdvancedWidget(e,t.text,{voice:t.voice,provider:t.provider,speed:t.speed,hash:s,apiKey:t.apiKey});return}else if(n==="compact"){this.setupCompactWidget(e,t.text,{voice:t.voice,provider:t.provider,speed:t.speed,hash:s,apiKey:t.apiKey});return}this.setupModularWidget(e,t,s)}scrubText(e){if(!e)return"";let t=e;return t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1"),t=t.replace(/https?:\/\/[^\s]+/g,"link"),t=t.replace(/www\.[^\s]+/g,"link"),t}parseWidgetConfig(e){let t=e.dataset.text||e.textContent?.trim()||"",s=this.scrubText(t),n=e.dataset.voice||this.defaultVoice,o=e.dataset.provider||this.defaultProvider,i=e.dataset.speed?parseFloat(e.dataset.speed):this.defaultSpeed,r=e.dataset.voices||"",a=r?r.split(",").map(h=>h.trim()).filter(Boolean):[],l=e.dataset.enableSpeed==="true",d=e.dataset.enableProgress==="true",p=e.dataset.apiKey||this.apiKey;return{text:s,voices:a,enableSpeed:l,enableProgress:d,speed:i,provider:o,voice:n,apiKey:p}}setupBasicWidget(e,t,s){let{voice:n,provider:o,speed:i,hash:r,apiKey:a}=s;if(e.classList.contains("supernal-tts-widget-initialized"))return;let l=document.createElement("div");l.className="supernal-tts-button-container";let d=e.querySelector(".supernal-tts-play");if(d||(d=this.createPlayButton()),l.appendChild(d),this.showBranding&&!e.querySelector(".supernal-badge")){let p=this.createBrandingBadge();l.appendChild(p)}e.appendChild(l),e.classList.add("supernal-tts-widget-initialized"),d.addEventListener("click",p=>{p.preventDefault(),this.handlePlayClick(d,t,{voice:n,provider:o,speed:i,hash:r,apiKey:a})}),e._ttsWidget={text:t,voice:n,provider:o,speed:i,hash:r,playButton:d}}setupCompactWidget(e,t,s){let{hash:n,apiKey:o}=s,{voice:i,provider:r,speed:a}=s;if(e.classList.contains("supernal-tts-widget-initialized"))return;let l=document.createElement("div");l.className="supernal-tts-compact-widget";let d=document.createElement("div");d.className="supernal-tts-top-row";let p=this.createPlayButton(),h=document.createElement("select");if(h.className="supernal-tts-voice-select",h.innerHTML=`
2
+ <option value="alloy" ${i==="alloy"?"selected":""}>Alloy</option>
3
+ <option value="echo" ${i==="echo"?"selected":""}>Echo</option>
4
+ <option value="fable" ${i==="fable"?"selected":""}>Fable</option>
5
+ <option value="onyx" ${i==="onyx"?"selected":""}>Onyx</option>
6
+ <option value="nova" ${i==="nova"?"selected":""}>Nova</option>
7
+ <option value="shimmer" ${i==="shimmer"?"selected":""}>Shimmer</option>
8
+ <option value="coral" ${i==="coral"?"selected":""}>Coral</option>
9
9
  `,d.appendChild(p),d.appendChild(h),this.showBranding){let m=this.createBrandingBadge();d.appendChild(m)}let v=document.createElement("div");v.className="supernal-tts-speed-control",v.innerHTML=`
10
10
  <label>Speed: <span class="supernal-tts-speed-value">${a}x</span></label>
11
11
  <input type="range" class="supernal-tts-speed-slider" min="0.25" max="4.0" step="0.25" value="${a}">
12
- `,l.appendChild(d),l.appendChild(v),e.innerHTML="",e.appendChild(l),e.classList.add("supernal-tts-widget-initialized","supernal-tts-widget-compact");let f=v.querySelector(".supernal-tts-speed-slider"),c=v.querySelector(".supernal-tts-speed-value");p.addEventListener("click",m=>{m.preventDefault(),a=parseFloat(f.value),n=h.value;let T=this.generateHash(t,{voice:n,provider:r,speed:a});this.handlePlayClick(p,t,{voice:n,provider:r,speed:a,hash:T,apiKey:o})}),f.addEventListener("input",m=>{a=parseFloat(m.target.value),c.textContent=`${a}x`}),h.addEventListener("change",()=>{n=h.value}),e._ttsWidget={text:t,voice:n,provider:r,speed:a,hash:i,playButton:p,compact:!0}}setupAdvancedWidget(e,t,s){let{hash:i,apiKey:o}=s,{voice:n,provider:r,speed:a}=s,l=document.createElement("div");l.className="supernal-tts-advanced-widget";let d=document.createElement("div");d.className="supernal-tts-button-group";let p=this.createPlayButton(),h=this.createStopButton();d.appendChild(p),d.appendChild(h);let v=document.createElement("select");v.className="supernal-tts-voice-select",v.innerHTML=`
13
- <option value="alloy" ${n==="alloy"?"selected":""}>Alloy</option>
14
- <option value="echo" ${n==="echo"?"selected":""}>Echo</option>
15
- <option value="fable" ${n==="fable"?"selected":""}>Fable</option>
16
- <option value="onyx" ${n==="onyx"?"selected":""}>Onyx</option>
17
- <option value="nova" ${n==="nova"?"selected":""}>Nova</option>
18
- <option value="shimmer" ${n==="shimmer"?"selected":""}>Shimmer</option>
19
- <option value="coral" ${n==="coral"?"selected":""}>Coral</option>
12
+ `,l.appendChild(d),l.appendChild(v),e.innerHTML="",e.appendChild(l),e.classList.add("supernal-tts-widget-initialized","supernal-tts-widget-compact");let f=v.querySelector(".supernal-tts-speed-slider"),c=v.querySelector(".supernal-tts-speed-value");p.addEventListener("click",m=>{m.preventDefault(),a=parseFloat(f.value),i=h.value;let T=this.generateHash(t,{voice:i,provider:r,speed:a});this.handlePlayClick(p,t,{voice:i,provider:r,speed:a,hash:T,apiKey:o})}),f.addEventListener("input",m=>{a=parseFloat(m.target.value),c.textContent=`${a}x`}),h.addEventListener("change",()=>{i=h.value}),e._ttsWidget={text:t,voice:i,provider:r,speed:a,hash:n,playButton:p,compact:!0}}setupAdvancedWidget(e,t,s){let{hash:n,apiKey:o}=s,{voice:i,provider:r,speed:a}=s,l=document.createElement("div");l.className="supernal-tts-advanced-widget";let d=document.createElement("div");d.className="supernal-tts-button-group";let p=this.createPlayButton(),h=this.createStopButton();d.appendChild(p),d.appendChild(h);let v=document.createElement("select");v.className="supernal-tts-voice-select",v.innerHTML=`
13
+ <option value="alloy" ${i==="alloy"?"selected":""}>Alloy</option>
14
+ <option value="echo" ${i==="echo"?"selected":""}>Echo</option>
15
+ <option value="fable" ${i==="fable"?"selected":""}>Fable</option>
16
+ <option value="onyx" ${i==="onyx"?"selected":""}>Onyx</option>
17
+ <option value="nova" ${i==="nova"?"selected":""}>Nova</option>
18
+ <option value="shimmer" ${i==="shimmer"?"selected":""}>Shimmer</option>
19
+ <option value="coral" ${i==="coral"?"selected":""}>Coral</option>
20
20
  `;let f=document.createElement("div");f.className="supernal-tts-speed-control",f.innerHTML=`
21
21
  <label>Speed: <span class="supernal-tts-speed-value">${a}x</span></label>
22
22
  <input type="range" class="supernal-tts-speed-slider" min="0.25" max="4.0" step="0.25" value="${a}">
23
23
  `;let c=document.createElement("div");if(c.className="supernal-tts-progress",c.innerHTML=`
24
24
  <input type="range" class="supernal-tts-progress-slider" min="0" max="100" value="0" step="0.1">
25
25
  <div class="supernal-tts-time"><span class="supernal-tts-current-time">0:00</span> / <span class="supernal-tts-duration">0:00</span></div>
26
- `,l.appendChild(d),l.appendChild(v),l.appendChild(f),l.appendChild(c),this.showBranding){let g=this.createBrandingBadge();l.appendChild(g)}e.innerHTML="",e.appendChild(l),e.classList.add("supernal-tts-widget-initialized","supernal-tts-widget-advanced");let m=f.querySelector(".supernal-tts-speed-slider"),T=f.querySelector(".supernal-tts-speed-value"),y=c.querySelector(".supernal-tts-progress-slider");p.addEventListener("click",g=>{g.preventDefault(),a=parseFloat(m.value),n=v.value;let E=this.generateHash(t,{voice:n,provider:r,speed:a});this.handlePlayClick(p,t,{voice:n,provider:r,speed:a,hash:E,apiKey:o})}),h.addEventListener("click",g=>{g.preventDefault(),this.stopAudio()}),m.addEventListener("input",g=>{a=parseFloat(g.target.value),T.textContent=`${a}x`}),v.addEventListener("change",()=>{n=v.value}),y.addEventListener("input",g=>{if(this.currentAudio){let E=parseFloat(g.target.value)/100;this.currentAudio.currentTime=this.currentAudio.duration*E}}),setInterval(()=>{if(this.currentAudio&&e._ttsWidget===this.currentWidget){let g=this.currentAudio.currentTime/this.currentAudio.duration*100;y.value=g.toString();let E=this.formatTime(this.currentAudio.currentTime),w=this.formatTime(this.currentAudio.duration);c.querySelector(".supernal-tts-current-time").textContent=E,c.querySelector(".supernal-tts-duration").textContent=w}},100),e._ttsWidget={text:t,voice:n,provider:r,speed:a,hash:i,playButton:p,stopButton:h,voiceSelect:v,speedSlider:m,progressSlider:y,advanced:!0},this.currentWidget=e._ttsWidget}setupModularWidget(e,t,s){let i=t.voice,o=t.speed,{text:n,voices:r,enableSpeed:a,enableProgress:l,provider:d,apiKey:p}=t,h=0,v=document.createElement("div");v.className="supernal-tts-modular-widget";let f=document.createElement("div");f.className="supernal-tts-controls-row";let c=this.createPlayButton(!0);f.appendChild(c);let m=null;r.length>0&&(m=this.createVoiceDropdown(r,i),f.appendChild(m),m.addEventListener("voice-changed",u=>{let g=u.detail.voice;if(g!==i&&this.currentButton===c&&this.currentAudio){i=g,this.currentAudio.duration>0&&(h=this.currentAudio.currentTime/this.currentAudio.duration);let w=e._ttsWidget?.progressBar;this.cleanStopAudioKeepProgress(w),setTimeout(()=>{this.handlePlayClickFromPosition(c,n,{voice:i,provider:d,speed:o,hash:this.generateHash(n,{voice:i,provider:d,speed:o}),progressBar:w,apiKey:p},h)},50)}else i=g}));let T=null;if(a&&(T=this.createSpeedDropdown(o),f.appendChild(T),T.addEventListener("speed-changed",u=>{let g=u.detail.speed;if(g!==o){if(o=g,this.clientSideSpeed&&this.currentAudio&&this.currentButton===c)this.currentAudio.playbackRate=g;else if(!this.clientSideSpeed&&this.currentButton===c&&this.currentAudio){this.currentAudio.duration>0&&(h=this.currentAudio.currentTime/this.currentAudio.duration);let w=e._ttsWidget?.progressBar;this.cleanStopAudioKeepProgress(w),setTimeout(()=>{this.handlePlayClickFromPosition(c,n,{voice:i,provider:d,speed:o,hash:this.generateHash(n,{voice:i,provider:d,speed:o}),progressBar:w,apiKey:p},h)},50)}}})),this.showBranding){let u=this.createBrandingBadge();f.appendChild(u)}v.appendChild(f);let y=null;l&&(y=this.createProgressBar(),v.appendChild(y)),e.insertBefore(v,e.firstChild),e.classList.add("supernal-tts-widget-initialized","supernal-tts-widget-modular"),l&&e.classList.add("has-progress"),c.addEventListener("click",u=>{u.preventDefault();let g=this.generateHash(n,{voice:i,provider:d,speed:o});this.handlePlayClick(c,n,{voice:i,provider:d,speed:o,hash:g,progressBar:y,apiKey:p})}),e._ttsWidget={text:n,voice:i,provider:d,speed:o,hash:s,playButton:c,voiceDropdown:m,speedDropdown:T,progressBar:y}}createVoiceDropdown(e,t){let s=document.createElement("div");s.className="supernal-tts-voice-control";let i=document.createElement("button");i.className="supernal-tts-voice-toggle",i.setAttribute("aria-label","Select voice"),i.setAttribute("aria-expanded","false"),i.innerHTML=`
26
+ `,l.appendChild(d),l.appendChild(v),l.appendChild(f),l.appendChild(c),this.showBranding){let g=this.createBrandingBadge();l.appendChild(g)}e.innerHTML="",e.appendChild(l),e.classList.add("supernal-tts-widget-initialized","supernal-tts-widget-advanced");let m=f.querySelector(".supernal-tts-speed-slider"),T=f.querySelector(".supernal-tts-speed-value"),y=c.querySelector(".supernal-tts-progress-slider");p.addEventListener("click",g=>{g.preventDefault(),a=parseFloat(m.value),i=v.value;let E=this.generateHash(t,{voice:i,provider:r,speed:a});this.handlePlayClick(p,t,{voice:i,provider:r,speed:a,hash:E,apiKey:o})}),h.addEventListener("click",g=>{g.preventDefault(),this.stopAudio()}),m.addEventListener("input",g=>{a=parseFloat(g.target.value),T.textContent=`${a}x`}),v.addEventListener("change",()=>{i=v.value}),y.addEventListener("input",g=>{if(this.currentAudio){let E=parseFloat(g.target.value)/100;this.currentAudio.currentTime=this.currentAudio.duration*E}}),setInterval(()=>{if(this.currentAudio&&e._ttsWidget===this.currentWidget){let g=this.currentAudio.currentTime/this.currentAudio.duration*100;y.value=g.toString();let E=this.formatTime(this.currentAudio.currentTime),w=this.formatTime(this.currentAudio.duration);c.querySelector(".supernal-tts-current-time").textContent=E,c.querySelector(".supernal-tts-duration").textContent=w}},100),e._ttsWidget={text:t,voice:i,provider:r,speed:a,hash:n,playButton:p,stopButton:h,voiceSelect:v,speedSlider:m,progressSlider:y,advanced:!0},this.currentWidget=e._ttsWidget}setupModularWidget(e,t,s){let n=t.voice,o=t.speed,{text:i,voices:r,enableSpeed:a,enableProgress:l,provider:d,apiKey:p}=t,h=0,v=document.createElement("div");v.className="supernal-tts-modular-widget";let f=document.createElement("div");f.className="supernal-tts-controls-row";let c=this.createPlayButton(!0);f.appendChild(c);let m=null;r.length>0&&(m=this.createVoiceDropdown(r,n),f.appendChild(m),m.addEventListener("voice-changed",u=>{let g=u.detail.voice;if(g!==n&&this.currentButton===c&&this.currentAudio){n=g,this.currentAudio.duration>0&&(h=this.currentAudio.currentTime/this.currentAudio.duration);let w=e._ttsWidget?.progressBar;this.cleanStopAudioKeepProgress(w),setTimeout(()=>{this.handlePlayClickFromPosition(c,i,{voice:n,provider:d,speed:o,hash:this.generateHash(i,{voice:n,provider:d,speed:o}),progressBar:w,apiKey:p},h)},50)}else n=g}));let T=null;if(a&&(T=this.createSpeedDropdown(o),f.appendChild(T),T.addEventListener("speed-changed",u=>{let g=u.detail.speed;if(g!==o){if(o=g,this.clientSideSpeed&&this.currentAudio&&this.currentButton===c)this.currentAudio.playbackRate=g;else if(!this.clientSideSpeed&&this.currentButton===c&&this.currentAudio){this.currentAudio.duration>0&&(h=this.currentAudio.currentTime/this.currentAudio.duration);let w=e._ttsWidget?.progressBar;this.cleanStopAudioKeepProgress(w),setTimeout(()=>{this.handlePlayClickFromPosition(c,i,{voice:n,provider:d,speed:o,hash:this.generateHash(i,{voice:n,provider:d,speed:o}),progressBar:w,apiKey:p},h)},50)}}})),this.showBranding){let u=this.createBrandingBadge();f.appendChild(u)}v.appendChild(f);let y=null;l&&(y=this.createProgressBar(),v.appendChild(y)),e.insertBefore(v,e.firstChild),e.classList.add("supernal-tts-widget-initialized","supernal-tts-widget-modular"),l&&e.classList.add("has-progress"),c.addEventListener("click",u=>{u.preventDefault();let g=this.generateHash(i,{voice:n,provider:d,speed:o});this.handlePlayClick(c,i,{voice:n,provider:d,speed:o,hash:g,progressBar:y,apiKey:p})}),e._ttsWidget={text:i,voice:n,provider:d,speed:o,hash:s,playButton:c,voiceDropdown:m,speedDropdown:T,progressBar:y}}createVoiceDropdown(e,t){let s=document.createElement("div");s.className="supernal-tts-voice-control";let n=document.createElement("button");n.className="supernal-tts-voice-toggle",n.setAttribute("aria-label","Select voice"),n.setAttribute("aria-expanded","false"),n.innerHTML=`
27
27
  <svg class="supernal-tts-voice-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
28
28
  <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/>
29
29
  </svg>
30
- `;let o=document.createElement("div");o.className="supernal-tts-voice-dropdown hidden",o.setAttribute("role","menu"),e.forEach(r=>{let a=document.createElement("button");a.className="supernal-tts-voice-option",a.textContent=this.formatVoiceName(r),a.dataset.voice=r,a.setAttribute("role","menuitem"),r===t&&a.classList.add("active"),a.addEventListener("click",l=>{l.stopPropagation(),l.preventDefault(),o.querySelectorAll(".supernal-tts-voice-option").forEach(d=>{d.classList.remove("active")}),a.classList.add("active"),s.dispatchEvent(new CustomEvent("voice-changed",{detail:{voice:r}}))}),o.appendChild(a)});let n=null;return s.addEventListener("mouseenter",()=>{n&&(clearTimeout(n),n=null),o.classList.remove("hidden"),i.setAttribute("aria-expanded","true"),setTimeout(()=>{let r=o.getBoundingClientRect(),a=window.innerHeight;r.bottom>a&&r.top>r.height?(o.style.bottom="100%",o.style.top="auto"):(o.style.top="calc(100% + 4px)",o.style.bottom="auto")},0)}),s.addEventListener("mouseleave",r=>{n=window.setTimeout(()=>{o.classList.add("hidden"),i.setAttribute("aria-expanded","false")},150)}),o.addEventListener("mouseenter",()=>{n&&(clearTimeout(n),n=null)}),o.addEventListener("mouseleave",()=>{n=window.setTimeout(()=>{o.classList.add("hidden"),i.setAttribute("aria-expanded","false")},150)}),i.addEventListener("click",r=>{r.stopPropagation();let a=o.classList.contains("hidden");o.classList.toggle("hidden"),i.setAttribute("aria-expanded",a?"true":"false")}),s.appendChild(i),s.appendChild(o),s}createSpeedDropdown(e){let t=document.createElement("div");t.className="supernal-tts-speed-control";let s=document.createElement("button");s.className="supernal-tts-speed-toggle",s.setAttribute("aria-label","Adjust playback speed"),s.innerHTML=`
30
+ `;let o=document.createElement("div");o.className="supernal-tts-voice-dropdown hidden",o.setAttribute("role","menu"),e.forEach(r=>{let a=document.createElement("button");a.className="supernal-tts-voice-option",a.textContent=this.formatVoiceName(r),a.dataset.voice=r,a.setAttribute("role","menuitem"),r===t&&a.classList.add("active"),a.addEventListener("click",l=>{l.stopPropagation(),l.preventDefault(),o.querySelectorAll(".supernal-tts-voice-option").forEach(d=>{d.classList.remove("active")}),a.classList.add("active"),s.dispatchEvent(new CustomEvent("voice-changed",{detail:{voice:r}}))}),o.appendChild(a)});let i=null;return s.addEventListener("mouseenter",()=>{i&&(clearTimeout(i),i=null),o.classList.remove("hidden"),n.setAttribute("aria-expanded","true"),setTimeout(()=>{let r=o.getBoundingClientRect(),a=window.innerHeight;r.bottom>a&&r.top>r.height?(o.style.bottom="100%",o.style.top="auto"):(o.style.top="calc(100% + 4px)",o.style.bottom="auto")},0)}),s.addEventListener("mouseleave",r=>{i=window.setTimeout(()=>{o.classList.add("hidden"),n.setAttribute("aria-expanded","false")},150)}),o.addEventListener("mouseenter",()=>{i&&(clearTimeout(i),i=null)}),o.addEventListener("mouseleave",()=>{i=window.setTimeout(()=>{o.classList.add("hidden"),n.setAttribute("aria-expanded","false")},150)}),n.addEventListener("click",r=>{r.stopPropagation();let a=o.classList.contains("hidden");o.classList.toggle("hidden"),n.setAttribute("aria-expanded",a?"true":"false")}),s.appendChild(n),s.appendChild(o),s}createSpeedDropdown(e){let t=document.createElement("div");t.className="supernal-tts-speed-control";let s=document.createElement("button");s.className="supernal-tts-speed-toggle",s.setAttribute("aria-label","Adjust playback speed"),s.innerHTML=`
31
31
  <svg class="supernal-tts-speed-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
32
32
  <path d="M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z"/>
33
33
  <path d="M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"/>
34
34
  </svg>
35
- `;let i=document.createElement("div");i.className="supernal-tts-speed-dropdown hidden",i.setAttribute("role","menu");let o=[];for(let r=.6;r<=3;r+=.2)o.push(Math.round(r*10)/10);o.forEach(r=>{let a=document.createElement("button");a.className="supernal-tts-speed-option",a.textContent=`${r.toFixed(1)}x`,a.dataset.speed=r.toString(),a.setAttribute("role","menuitem"),Math.abs(r-e)<.01&&a.classList.add("active"),a.addEventListener("click",l=>{l.stopPropagation(),l.preventDefault(),i.querySelectorAll(".supernal-tts-speed-option").forEach(d=>{d.classList.remove("active")}),a.classList.add("active"),t.dispatchEvent(new CustomEvent("speed-changed",{detail:{speed:r}}))}),i.appendChild(a)});let n=null;return t.addEventListener("mouseenter",()=>{n&&(clearTimeout(n),n=null),i.classList.remove("hidden"),setTimeout(()=>{let r=i.getBoundingClientRect(),a=window.innerHeight;r.bottom>a&&r.top>r.height?(i.style.bottom="100%",i.style.top="auto"):(i.style.top="calc(100% + 4px)",i.style.bottom="auto")},0)}),t.addEventListener("mouseleave",()=>{n=window.setTimeout(()=>{i.classList.add("hidden")},150)}),i.addEventListener("mouseenter",()=>{n&&(clearTimeout(n),n=null)}),i.addEventListener("mouseleave",()=>{n=window.setTimeout(()=>{i.classList.add("hidden")},150)}),t.appendChild(s),t.appendChild(i),t}createProgressBar(){let e=document.createElement("div");e.className="supernal-tts-progress-container";let t=document.createElement("input");t.type="range",t.className="supernal-tts-progress-slider",t.min="0",t.max="100",t.value="0",t.step="0.1",t.setAttribute("aria-label","Seek audio position");let s=document.createElement("div");return s.className="supernal-tts-time-display",s.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>',t.addEventListener("input",i=>{if(this.currentAudio){let o=parseFloat(i.target.value);this.currentAudio.currentTime=o/100*this.currentAudio.duration}}),e.appendChild(t),e.appendChild(s),e}formatTime(e){if(!e||isNaN(e))return"0:00";let t=Math.floor(e/60),s=Math.floor(e%60);return`${t}:${s.toString().padStart(2,"0")}`}formatVoiceName(e){return e.replace(/[-_]/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}createStopButton(){let e=document.createElement("button");return e.className="supernal-tts-stop",e.innerHTML=`
35
+ `;let n=document.createElement("div");n.className="supernal-tts-speed-dropdown hidden",n.setAttribute("role","menu");let o=[];for(let r=.6;r<=3;r+=.2)o.push(Math.round(r*10)/10);o.forEach(r=>{let a=document.createElement("button");a.className="supernal-tts-speed-option",a.textContent=`${r.toFixed(1)}x`,a.dataset.speed=r.toString(),a.setAttribute("role","menuitem"),Math.abs(r-e)<.01&&a.classList.add("active"),a.addEventListener("click",l=>{l.stopPropagation(),l.preventDefault(),n.querySelectorAll(".supernal-tts-speed-option").forEach(d=>{d.classList.remove("active")}),a.classList.add("active"),t.dispatchEvent(new CustomEvent("speed-changed",{detail:{speed:r}}))}),n.appendChild(a)});let i=null;return t.addEventListener("mouseenter",()=>{i&&(clearTimeout(i),i=null),n.classList.remove("hidden"),setTimeout(()=>{let r=n.getBoundingClientRect(),a=window.innerHeight;r.bottom>a&&r.top>r.height?(n.style.bottom="100%",n.style.top="auto"):(n.style.top="calc(100% + 4px)",n.style.bottom="auto")},0)}),t.addEventListener("mouseleave",()=>{i=window.setTimeout(()=>{n.classList.add("hidden")},150)}),n.addEventListener("mouseenter",()=>{i&&(clearTimeout(i),i=null)}),n.addEventListener("mouseleave",()=>{i=window.setTimeout(()=>{n.classList.add("hidden")},150)}),t.appendChild(s),t.appendChild(n),t}createProgressBar(){let e=document.createElement("div");e.className="supernal-tts-progress-container";let t=document.createElement("input");t.type="range",t.className="supernal-tts-progress-slider",t.min="0",t.max="100",t.value="0",t.step="0.1",t.setAttribute("aria-label","Seek audio position");let s=document.createElement("div");return s.className="supernal-tts-time-display",s.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>',t.addEventListener("input",n=>{if(this.currentAudio){let o=parseFloat(n.target.value);this.currentAudio.currentTime=o/100*this.currentAudio.duration}}),e.appendChild(t),e.appendChild(s),e}formatTime(e){if(!e||isNaN(e))return"0:00";let t=Math.floor(e/60),s=Math.floor(e%60);return`${t}:${s.toString().padStart(2,"0")}`}formatVoiceName(e){return e.replace(/[-_]/g," ").split(" ").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}createStopButton(){let e=document.createElement("button");return e.className="supernal-tts-stop",e.innerHTML=`
36
36
  <svg class="supernal-tts-icon" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
37
37
  <rect x="6" y="6" width="12" height="12"/>
38
38
  </svg>
@@ -90,7 +90,7 @@ var M=Object.defineProperty;var x=(S,e)=>()=>(S&&(e=S(S=0)),e);var P=(S,e)=>{for
90
90
  <span>\u{1F5D1}\uFE0F</span>
91
91
  <span>Clear Cache</span>
92
92
  <span style="opacity: 0.7; font-size: 10px;">\xD7</span>
93
- `;let i=r=>{r.addEventListener("mouseenter",()=>{r.style.transform="scale(1.05)",r.style.boxShadow="0 4px 12px rgba(0,0,0,0.4)"}),r.addEventListener("mouseleave",()=>{r.style.transform="scale(1)",r.style.boxShadow="0 2px 8px rgba(0,0,0,0.3)"})};i(s),i(t);let o=()=>{let r=this.cache.size;this.cache.clear(),localStorage.removeItem("supernal-tts-cache"),s.innerHTML=`<span>\u2713</span><span>Cleared ${r}</span><span style="opacity: 0.7; font-size: 10px;">\xD7</span>`,s.style.background="#28a745",setTimeout(()=>{s.innerHTML='<span>\u{1F5D1}\uFE0F</span><span>Clear Cache</span><span style="opacity: 0.7; font-size: 10px;">\xD7</span>',s.style.background="#dc3545"},2e3),console.log(`[Supernal TTS Dev] Cleared ${r} cached items`)};s.addEventListener("click",r=>{r.preventDefault();let a=r.clientX-r.target.getBoundingClientRect().left,l=s.getBoundingClientRect().width;a>l*.8?(s.style.display="none",t.style.display="block",localStorage.setItem("supernal-tts-dev-minimized","true")):o()}),t.addEventListener("click",r=>{r.preventDefault(),t.style.display="none",s.style.display="flex",localStorage.setItem("supernal-tts-dev-minimized","false")}),localStorage.getItem("supernal-tts-dev-minimized")==="true"&&(s.style.display="none",t.style.display="block"),e.appendChild(s),e.appendChild(t),document.body?document.body.appendChild(e):document.addEventListener("DOMContentLoaded",()=>{document.body.appendChild(e)})}async handlePlayClick(e,t,s){let{hash:i,progressBar:o}=s;if(e.classList.contains("supernal-tts-playing")&&this.currentButton===e){this.pauseAudio();return}if(e.classList.contains("supernal-tts-paused")&&this.currentButton===e){this.resumeAudio();return}if(!this.isProcessing){this.currentAudio&&this.currentButton&&this.currentButton!==e&&this.stopAudio();try{this.isProcessing=!0,this.setButtonState(e,"loading");let n=this.getCachedAudioUrl(i);if(!n)if(this.generationMode==="progressive"||this.generationMode==="standard"&&t.length>this.progressiveThreshold){await this.generateAudioProgressive(t,s,e,o);return}else{let a=await this.generateAudio(t,s);n=a.audioUrl.startsWith("http")?a.audioUrl:`${this.apiUrl}${a.audioUrl}`,this.cacheAudioUrl(i,n,a)}await this.playAudio(n,e,o)}catch(n){console.error("TTS Error:",n),this.setButtonState(e,"error"),this.showError(e,n.message),setTimeout(()=>this.setButtonState(e,"ready"),3e3),this.isProcessing=!1}}}async generateAudio(e,t){let s={text:e,options:{provider:t.provider,voice:t.voice,speed:t.speed||1}},i={"Content-Type":"application/json"},o=t.apiKey||this.apiKey;console.log("[TTS Widget] Generate Audio - API Key present:",!!o),console.log("[TTS Widget] Generate Audio - this.apiKey:",!!this.apiKey),console.log("[TTS Widget] Generate Audio - options.apiKey:",!!t.apiKey),o?(i.Authorization=`Bearer ${o}`,console.log("[TTS Widget] Generate Audio - Authorization header added")):console.warn("[TTS Widget] Generate Audio - NO API KEY, Authorization header NOT added");try{let n=await fetch(`${this.apiUrl}/api/v1/generate`,{method:"POST",headers:i,body:JSON.stringify(s)});if(!n.ok){let a=await n.json().catch(()=>({}));throw new Error(a.error||`HTTP ${n.status}: ${n.statusText}`)}let r=await n.json();return{audioUrl:`${this.apiUrl}${r.audioUrl}`,hash:r.hash,cached:r.cached,duration:r.duration,cost:r.cost}}catch(n){if(console.error("TTS generation failed:",n),n.message.includes("Failed to fetch")||n.message.includes("NetworkError")){let r=n.message;throw new Error(`TTS API unreachable: ${r}. Check if ${this.apiUrl} is accessible.`)}throw n}}async generateAudioProgressive(e,t,s,i){let o={text:e,options:{provider:t.provider,voice:t.voice,speed:t.speed||1}},n={"Content-Type":"application/json",Accept:"text/event-stream"},r=t.apiKey||this.apiKey;r&&(n.Authorization=`Bearer ${r}`);try{let a=await fetch(`${this.apiUrl}/api/v1/generate-progressive`,{method:"POST",headers:n,body:JSON.stringify(o)});if(!a.ok){let c=await a.json().catch(()=>({}));throw new Error(c.error||`HTTP ${a.status}: ${a.statusText}`)}if(!a.body)throw new Error("No response body for SSE stream");let l=a.body.getReader(),d=new TextDecoder,p="",h=0,v=0,f=(c,m)=>{if(i){let T=c/m*100,y=i.querySelector(".supernal-tts-progress-slider");y&&(y.value=T.toString());let u=i.querySelector(".current");u&&(u.textContent=`Chunk ${c}/${m}`)}};for(;;){let{done:c,value:m}=await l.read();if(c)break;p+=d.decode(m,{stream:!0});let T=p.split(`
93
+ `;let n=r=>{r.addEventListener("mouseenter",()=>{r.style.transform="scale(1.05)",r.style.boxShadow="0 4px 12px rgba(0,0,0,0.4)"}),r.addEventListener("mouseleave",()=>{r.style.transform="scale(1)",r.style.boxShadow="0 2px 8px rgba(0,0,0,0.3)"})};n(s),n(t);let o=()=>{let r=this.cache.size;this.cache.clear(),localStorage.removeItem("supernal-tts-cache"),s.innerHTML=`<span>\u2713</span><span>Cleared ${r}</span><span style="opacity: 0.7; font-size: 10px;">\xD7</span>`,s.style.background="#28a745",setTimeout(()=>{s.innerHTML='<span>\u{1F5D1}\uFE0F</span><span>Clear Cache</span><span style="opacity: 0.7; font-size: 10px;">\xD7</span>',s.style.background="#dc3545"},2e3),console.log(`[Supernal TTS Dev] Cleared ${r} cached items`)};s.addEventListener("click",r=>{r.preventDefault();let a=r.clientX-r.target.getBoundingClientRect().left,l=s.getBoundingClientRect().width;a>l*.8?(s.style.display="none",t.style.display="block",localStorage.setItem("supernal-tts-dev-minimized","true")):o()}),t.addEventListener("click",r=>{r.preventDefault(),t.style.display="none",s.style.display="flex",localStorage.setItem("supernal-tts-dev-minimized","false")}),localStorage.getItem("supernal-tts-dev-minimized")==="true"&&(s.style.display="none",t.style.display="block"),e.appendChild(s),e.appendChild(t),document.body?document.body.appendChild(e):document.addEventListener("DOMContentLoaded",()=>{document.body.appendChild(e)})}async handlePlayClick(e,t,s){let{hash:n,progressBar:o}=s;if(e.classList.contains("supernal-tts-playing")&&this.currentButton===e){this.pauseAudio();return}if(e.classList.contains("supernal-tts-paused")&&this.currentButton===e){this.resumeAudio();return}if(!this.isProcessing){this.currentAudio&&this.currentButton&&this.currentButton!==e&&this.stopAudio();try{this.isProcessing=!0,this.setButtonState(e,"loading");let i=this.getCachedAudioUrl(n);if(!i)if(this.generationMode==="progressive"||this.generationMode==="standard"&&t.length>this.progressiveThreshold){await this.generateAudioProgressive(t,s,e,o);return}else{let a=await this.generateAudio(t,s);i=a.audioUrl.startsWith("http")?a.audioUrl:`${this.apiUrl}${a.audioUrl}`,this.cacheAudioUrl(n,i,a)}await this.playAudio(i,e,o)}catch(i){console.error("TTS Error:",i),this.setButtonState(e,"error"),this.showError(e,i.message),setTimeout(()=>this.setButtonState(e,"ready"),3e3),this.isProcessing=!1}}}async generateAudio(e,t){let s={text:e,options:{provider:t.provider,voice:t.voice,speed:t.speed||1}},n={"Content-Type":"application/json"},o=t.apiKey||this.apiKey;console.log("[TTS Widget] Generate Audio - API Key present:",!!o),console.log("[TTS Widget] Generate Audio - this.apiKey:",!!this.apiKey),console.log("[TTS Widget] Generate Audio - options.apiKey:",!!t.apiKey),o?(n.Authorization=`Bearer ${o}`,console.log("[TTS Widget] Generate Audio - Authorization header added")):console.warn("[TTS Widget] Generate Audio - NO API KEY, Authorization header NOT added");try{let i=await fetch(`${this.apiUrl}/api/v1/generate`,{method:"POST",headers:n,body:JSON.stringify(s)});if(!i.ok){let a=await i.json().catch(()=>({}));throw new Error(a.error||`HTTP ${i.status}: ${i.statusText}`)}let r=await i.json();return{audioUrl:`${this.apiUrl}${r.audioUrl}`,hash:r.hash,cached:r.cached,duration:r.duration,cost:r.cost}}catch(i){if(console.error("TTS generation failed:",i),i.message.includes("Failed to fetch")||i.message.includes("NetworkError")){let r=i.message;throw new Error(`TTS API unreachable: ${r}. Check if ${this.apiUrl} is accessible.`)}throw i}}async generateAudioProgressive(e,t,s,n){let o={text:e,options:{provider:t.provider,voice:t.voice,speed:t.speed||1}},i={"Content-Type":"application/json",Accept:"text/event-stream"},r=t.apiKey||this.apiKey;r&&(i.Authorization=`Bearer ${r}`);try{let a=await fetch(`${this.apiUrl}/api/v1/generate-progressive`,{method:"POST",headers:i,body:JSON.stringify(o)});if(!a.ok){let c=await a.json().catch(()=>({}));throw new Error(c.error||`HTTP ${a.status}: ${a.statusText}`)}if(!a.body)throw new Error("No response body for SSE stream");let l=a.body.getReader(),d=new TextDecoder,p="",h=0,v=0,f=(c,m)=>{if(n){let T=c/m*100,y=n.querySelector(".supernal-tts-progress-slider");y&&(y.value=T.toString());let u=n.querySelector(".current");u&&(u.textContent=`Chunk ${c}/${m}`)}};for(;;){let{done:c,value:m}=await l.read();if(c)break;p+=d.decode(m,{stream:!0});let T=p.split(`
94
94
 
95
- `);p=T.pop()||"";for(let y of T)if(y.startsWith("data: "))try{let u=JSON.parse(y.substring(6));switch(u.type){case"started":h=u.totalChunks,console.log(`[Progressive TTS] Started: ${h} chunks`),this.setButtonState(s,"loading");break;case"progress":v=u.completed,console.log(`[Progressive TTS] Progress: ${v}/${h}`),f(v,h);break;case"complete":console.log("[Progressive TTS] Complete:",u);let g=u.audioUrl.startsWith("http")?u.audioUrl:`${this.apiUrl}${u.audioUrl}`;this.cacheAudioUrl(t.hash,g,{hash:u.hash,cached:!1,duration:u.duration,cost:u.cost}),await this.playAudio(g,s,i);break;case"error":throw new Error(u.message||"Progressive generation failed")}}catch(u){console.warn("[Progressive TTS] Failed to parse event:",y,u)}}}catch(a){throw console.error("Progressive TTS generation failed:",a),this.isProcessing=!1,a}}async playAudio(e,t,s,i){return new Promise((o,n)=>{let r=new Audio(e);this.currentAudio=r,this.currentButton=t,this.clientSideSpeed&&(r.preservesPitch=!0,r.mozPreservesPitch=!0,r.webkitPreservesPitch=!0),i!==void 0&&this.clientSideSpeed&&(r.playbackRate=i),this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),r.addEventListener("loadstart",()=>{this.currentAudio===r&&this.setButtonState(t,"loading")}),r.addEventListener("canplay",()=>{if(this.currentAudio===r){this.setButtonState(t,"playing"),this.isProcessing=!1;let a=r.play();a!==void 0&&a.catch(l=>{console.error("Audio play failed:",l),this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.isProcessing=!1,n(new Error("Audio playback failed")))}),s&&(s.classList.add("playing"),this.progressUpdateInterval=window.setInterval(()=>{this.updateProgressBar(r,s)},100))}}),r.addEventListener("ended",()=>{if(this.currentAudio===r){if(this.setButtonState(t,"ready"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s){s.classList.remove("playing");let a=s.querySelector(".supernal-tts-progress-slider");a&&(a.value="0");let l=s.querySelector(".supernal-tts-time-display");l&&(l.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>')}o()}}),r.addEventListener("error",a=>{this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s&&s.classList.remove("playing"),n(new Error("Audio playback failed")))}),r.load()})}updateProgressBar(e,t){if(!e||!t)return;let s=t.querySelector(".supernal-tts-progress-slider"),i=t.querySelector(".current"),o=t.querySelector(".duration");if(s&&!isNaN(e.duration)){let n=e.currentTime/e.duration*100;s.value=n.toString()}i&&(i.textContent=this.formatTime(e.currentTime)),o&&!isNaN(e.duration)&&(o.textContent=this.formatTime(e.duration))}pauseAudio(){this.currentAudio&&!this.currentAudio.paused&&this.currentAudio.pause(),this.currentButton&&this.setButtonState(this.currentButton,"paused")}resumeAudio(){if(this.currentAudio&&this.currentAudio.paused){let e=this.currentAudio.play();e!==void 0&&e.then(()=>{this.currentButton&&this.setButtonState(this.currentButton,"playing")}).catch(t=>{console.error("Audio resume failed:",t),this.currentButton&&this.setButtonState(this.currentButton,"error")})}}stopAudio(){this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null),this.currentButton&&(this.setButtonState(this.currentButton,"ready"),this.currentButton=null),this.isProcessing=!1}cleanStopAudio(e){if(this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null),this.currentButton&&(this.setButtonState(this.currentButton,"ready"),this.currentButton=null),e){e.classList.remove("playing");let t=e.querySelector(".supernal-tts-progress-slider");t&&(t.value="0");let s=e.querySelector(".supernal-tts-time-display");s&&(s.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>')}this.isProcessing=!1}cleanStopAudioKeepProgress(e){this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null),this.currentButton&&this.setButtonState(this.currentButton,"loading"),this.isProcessing=!1}async handlePlayClickFromPosition(e,t,s,i){let{hash:o,progressBar:n}=s;if(!this.isProcessing)try{this.isProcessing=!0,this.setButtonState(e,"loading");let r=this.getCachedAudioUrl(o);if(!r){let a=await this.generateAudio(t,s);r=a.audioUrl.startsWith("http")?a.audioUrl:`${this.apiUrl}${a.audioUrl}`,this.cacheAudioUrl(o,r,a)}await this.playAudioFromPosition(r,e,n,i)}catch(r){console.error("TTS Error:",r),this.setButtonState(e,"error"),this.showError(e,r.message),setTimeout(()=>this.setButtonState(e,"ready"),3e3),this.isProcessing=!1}}async playAudioFromPosition(e,t,s,i){return new Promise((o,n)=>{let r=new Audio(e);this.currentAudio=r,this.currentButton=t,this.clientSideSpeed&&(r.preservesPitch=!0,r.mozPreservesPitch=!0,r.webkitPreservesPitch=!0),this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null);let a=!1;r.addEventListener("loadstart",()=>{this.currentAudio===r&&this.setButtonState(t,"loading")}),r.addEventListener("loadedmetadata",()=>{this.currentAudio===r&&!a&&i>0&&(r.currentTime=r.duration*i,a=!0)}),r.addEventListener("canplay",()=>{if(this.currentAudio===r){!a&&i>0&&r.duration>0&&(r.currentTime=r.duration*i,a=!0),this.setButtonState(t,"playing"),this.isProcessing=!1;let l=r.play();l!==void 0&&l.catch(d=>{console.error("Audio play failed:",d),this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.isProcessing=!1,n(new Error("Audio playback failed")))}),s&&(s.classList.add("playing"),this.progressUpdateInterval=window.setInterval(()=>{this.updateProgressBar(r,s)},100))}}),r.addEventListener("ended",()=>{if(this.currentAudio===r){if(this.setButtonState(t,"ready"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s){s.classList.remove("playing");let l=s.querySelector(".supernal-tts-progress-slider");l&&(l.value="0");let d=s.querySelector(".supernal-tts-time-display");d&&(d.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>')}o()}}),r.addEventListener("error",l=>{this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s&&s.classList.remove("playing"),n(new Error("Audio playback failed")))}),r.load()})}setButtonState(e,t){e.classList.remove("supernal-tts-loading","supernal-tts-playing","supernal-tts-paused","supernal-tts-error");let s=e.querySelector(".supernal-tts-play-icon"),i=e.querySelector(".supernal-tts-text");switch(t){case"loading":e.classList.add("supernal-tts-loading"),e.disabled=!0,i&&(i.textContent="Loading...");break;case"playing":e.classList.add("supernal-tts-playing"),e.disabled=!1,s&&(s.innerHTML='<rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/>'),i&&(i.textContent="Pause");break;case"paused":e.classList.add("supernal-tts-paused"),e.disabled=!1,s&&(s.innerHTML='<path d="M8 5v14l11-7z"/>'),i&&(i.textContent="Resume");break;case"error":e.classList.add("supernal-tts-error"),e.disabled=!1,s&&(s.innerHTML='<path d="M12 2L2 7v10c0 5.55 3.84 9.95 9 11 5.16-1.05 9-5.45 9-11V7l-10-5z"/>'),i&&(i.textContent="Error");break;default:e.disabled=!1,s&&(s.innerHTML='<path d="M8 5v14l11-7z"/>'),i&&(i.textContent="Listen");break}}showError(e,t){let s=document.createElement("div");s.className="supernal-tts-error-tooltip",t.includes("development mode")?s.textContent=t:t.includes("Failed to fetch")?s.textContent="Service unavailable (dev mode)":s.textContent="Audio generation failed",e.parentNode?.appendChild(s),setTimeout(()=>{s.parentNode&&s.parentNode.removeChild(s)},3e3)}generateHash(e,t={}){let s=e+JSON.stringify(t),i=0;for(let o=0;o<s.length;o++){let n=s.charCodeAt(o);i=(i<<5)-i+n,i=i&i}return Math.abs(i).toString(36)}getCachedAudioUrl(e){let t=this.cache.get(e);if(!t)return null;if(Date.now()>t.expiry)return this.cache.delete(e),this.saveCacheToStorage(),null;let s=t.audioUrl;return s.startsWith("http")?s:`${this.apiUrl}${s}`}cacheAudioUrl(e,t,s={}){this.cache.set(e,{audioUrl:t,metadata:s,expiry:Date.now()+this.cacheExpiry,timestamp:Date.now()}),this.saveCacheToStorage()}loadCacheFromStorage(){try{let e=localStorage.getItem("supernal-tts-cache");if(e){let t=JSON.parse(e);this.cache=new Map(Object.entries(t))}}catch(e){console.warn("Failed to load TTS cache:",e)}}saveCacheToStorage(){try{let e=Object.fromEntries(this.cache);localStorage.setItem("supernal-tts-cache",JSON.stringify(e))}catch(e){console.warn("Failed to save TTS cache:",e)}}static init(e){return window.SupernalTTSInstance?(console.debug("SupernalTTS already initialized, returning existing instance"),window.SupernalTTSInstance):(window.SupernalTTSInstance=new S(e),window.SupernalTTSInstance)}static getInstance(){return window.SupernalTTSInstance}addWidget(e,t,s={}){let i=null;if(typeof e=="string"?i=document.querySelector(e):i=e,!i){console.error("TTS Widget: Element not found");return}i.classList.add("supernal-tts-widget"),i.dataset.text=this.scrubText(t),s.voice&&(i.dataset.voice=s.voice),s.provider&&(i.dataset.provider=s.provider),this.setupWidget(i)}};if(typeof window<"u")if(window.SupernalTTS)console.debug("SupernalTTS already loaded, skipping redeclaration");else{window.SupernalTTS=L;let S=document.querySelector("script[data-supernal-tts-auto-init]");if(S&&S.dataset){let e=JSON.parse(S.dataset.supernalTtsAutoInit||"{}");L.init(e)}}B=L});var b=class{static{this.instance=null}static{this.loadPromise=null}static async load(e={}){if(this.instance)return this.instance;if(this.loadPromise)return this.loadPromise;let{version:t="major",mode:s="auto",cdnUrl:i="https://unpkg.com/@supernal/tts-widget",timeout:o=3e3,onCdnFail:n,onCdnSuccess:r}=e;return this.loadPromise=this.loadWidget({version:t,mode:s,cdnUrl:i,timeout:o,onCdnFail:n,onCdnSuccess:r}),this.loadPromise}static async loadWidget(e){let{mode:t,version:s,cdnUrl:i,timeout:o,onCdnFail:n,onCdnSuccess:r}=e;if(t==="bundled")return console.log("[TTS Widget] Loading bundled version (mode: bundled)"),this.loadBundled();if(t==="cdn"||t==="auto")try{console.log("[TTS Widget] Attempting CDN load...");let a=await this.loadFromCdn(i,s,o);return console.log("[TTS Widget] CDN load successful"),r?.(),this.instance=a,a}catch(a){let l=a instanceof Error?a.message:String(a);if(console.warn("[TTS Widget] CDN load failed:",l),n?.(a instanceof Error?a:new Error(l)),t==="cdn")throw new Error(`Failed to load widget from CDN: ${l}`);return console.log("[TTS Widget] Falling back to bundled version"),this.loadBundled()}return this.loadBundled()}static async loadFromCdn(e,t,s){let i=this.resolveVersionPath(t),o=`${e}${i}/dist/widget.js`;console.log(`[TTS Widget] Loading from CDN: ${o}`);let n=new AbortController,r=setTimeout(()=>n.abort(),s);try{let a=import(o),l=new Promise((p,h)=>{setTimeout(()=>h(new Error(`CDN load timeout after ${s}ms`)),s)}),d=await Promise.race([a,l]);if(clearTimeout(r),!d||!d.SupernalTTS)throw new Error("CDN module missing SupernalTTS export");return this.instance=d.SupernalTTS,this.instance}catch(a){throw clearTimeout(r),a}}static async loadBundled(){try{let e=await Promise.resolve().then(()=>(C(),A));if(!e||!e.SupernalTTS)throw new Error("Bundled widget missing SupernalTTS export");return this.instance=e.SupernalTTS,this.instance}catch(e){let t=e instanceof Error?e.message:String(e);throw new Error(`Failed to load bundled widget: ${t}`)}}static resolveVersionPath(e){return e==="major"?`@${this.getMajorVersion()}`:e==="latest"?"@latest":`@${e}`}static getMajorVersion(){{let e="1.3.1".match(/^(\d+)\./);if(e)return e[1]}return"1"}static reset(){this.instance=null,this.loadPromise=null}static getInstance(){return this.instance}},I=b;export{b as WidgetLoader,I as default};
95
+ `);p=T.pop()||"";for(let y of T)if(y.startsWith("data: "))try{let u=JSON.parse(y.substring(6));switch(u.type){case"started":h=u.totalChunks,console.log(`[Progressive TTS] Started: ${h} chunks`),this.setButtonState(s,"loading");break;case"progress":v=u.completed,console.log(`[Progressive TTS] Progress: ${v}/${h}`),f(v,h);break;case"complete":console.log("[Progressive TTS] Complete:",u);let g=u.audioUrl.startsWith("http")?u.audioUrl:`${this.apiUrl}${u.audioUrl}`;this.cacheAudioUrl(t.hash,g,{hash:u.hash,cached:!1,duration:u.duration,cost:u.cost}),await this.playAudio(g,s,n);break;case"error":throw new Error(u.message||"Progressive generation failed")}}catch(u){console.warn("[Progressive TTS] Failed to parse event:",y,u)}}}catch(a){throw console.error("Progressive TTS generation failed:",a),this.isProcessing=!1,a}}async playAudio(e,t,s,n){return new Promise((o,i)=>{let r=new Audio(e);this.currentAudio=r,this.currentButton=t,this.clientSideSpeed&&(r.preservesPitch=!0,r.mozPreservesPitch=!0,r.webkitPreservesPitch=!0),n!==void 0&&this.clientSideSpeed&&(r.playbackRate=n),this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),r.addEventListener("loadstart",()=>{this.currentAudio===r&&this.setButtonState(t,"loading")}),r.addEventListener("canplay",()=>{if(this.currentAudio===r){this.setButtonState(t,"playing"),this.isProcessing=!1;let a=r.play();a!==void 0&&a.catch(l=>{console.error("Audio play failed:",l),this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.isProcessing=!1,i(new Error("Audio playback failed")))}),s&&(s.classList.add("playing"),this.progressUpdateInterval=window.setInterval(()=>{this.updateProgressBar(r,s)},100))}}),r.addEventListener("ended",()=>{if(this.currentAudio===r){if(this.setButtonState(t,"ready"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s){s.classList.remove("playing");let a=s.querySelector(".supernal-tts-progress-slider");a&&(a.value="0");let l=s.querySelector(".supernal-tts-time-display");l&&(l.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>')}o()}}),r.addEventListener("error",a=>{this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s&&s.classList.remove("playing"),i(new Error("Audio playback failed")))}),r.load()})}updateProgressBar(e,t){if(!e||!t)return;let s=t.querySelector(".supernal-tts-progress-slider"),n=t.querySelector(".current"),o=t.querySelector(".duration");if(s&&!isNaN(e.duration)){let i=e.currentTime/e.duration*100;s.value=i.toString()}n&&(n.textContent=this.formatTime(e.currentTime)),o&&!isNaN(e.duration)&&(o.textContent=this.formatTime(e.duration))}pauseAudio(){this.currentAudio&&!this.currentAudio.paused&&this.currentAudio.pause(),this.currentButton&&this.setButtonState(this.currentButton,"paused")}resumeAudio(){if(this.currentAudio&&this.currentAudio.paused){let e=this.currentAudio.play();e!==void 0&&e.then(()=>{this.currentButton&&this.setButtonState(this.currentButton,"playing")}).catch(t=>{console.error("Audio resume failed:",t),this.currentButton&&this.setButtonState(this.currentButton,"error")})}}stopAudio(){this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null),this.currentButton&&(this.setButtonState(this.currentButton,"ready"),this.currentButton=null),this.isProcessing=!1}cleanStopAudio(e){if(this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null),this.currentButton&&(this.setButtonState(this.currentButton,"ready"),this.currentButton=null),e){e.classList.remove("playing");let t=e.querySelector(".supernal-tts-progress-slider");t&&(t.value="0");let s=e.querySelector(".supernal-tts-time-display");s&&(s.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>')}this.isProcessing=!1}cleanStopAudioKeepProgress(e){this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.currentAudio=null),this.currentButton&&this.setButtonState(this.currentButton,"loading"),this.isProcessing=!1}async handlePlayClickFromPosition(e,t,s,n){let{hash:o,progressBar:i}=s;if(!this.isProcessing)try{this.isProcessing=!0,this.setButtonState(e,"loading");let r=this.getCachedAudioUrl(o);if(!r){let a=await this.generateAudio(t,s);r=a.audioUrl.startsWith("http")?a.audioUrl:`${this.apiUrl}${a.audioUrl}`,this.cacheAudioUrl(o,r,a)}await this.playAudioFromPosition(r,e,i,n)}catch(r){console.error("TTS Error:",r),this.setButtonState(e,"error"),this.showError(e,r.message),setTimeout(()=>this.setButtonState(e,"ready"),3e3),this.isProcessing=!1}}async playAudioFromPosition(e,t,s,n){return new Promise((o,i)=>{let r=new Audio(e);this.currentAudio=r,this.currentButton=t,this.clientSideSpeed&&(r.preservesPitch=!0,r.mozPreservesPitch=!0,r.webkitPreservesPitch=!0),this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null);let a=!1;r.addEventListener("loadstart",()=>{this.currentAudio===r&&this.setButtonState(t,"loading")}),r.addEventListener("loadedmetadata",()=>{this.currentAudio===r&&!a&&n>0&&(r.currentTime=r.duration*n,a=!0)}),r.addEventListener("canplay",()=>{if(this.currentAudio===r){!a&&n>0&&r.duration>0&&(r.currentTime=r.duration*n,a=!0),this.setButtonState(t,"playing"),this.isProcessing=!1;let l=r.play();l!==void 0&&l.catch(d=>{console.error("Audio play failed:",d),this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.isProcessing=!1,i(new Error("Audio playback failed")))}),s&&(s.classList.add("playing"),this.progressUpdateInterval=window.setInterval(()=>{this.updateProgressBar(r,s)},100))}}),r.addEventListener("ended",()=>{if(this.currentAudio===r){if(this.setButtonState(t,"ready"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s){s.classList.remove("playing");let l=s.querySelector(".supernal-tts-progress-slider");l&&(l.value="0");let d=s.querySelector(".supernal-tts-time-display");d&&(d.innerHTML='<span class="current">0:00</span> / <span class="duration">0:00</span>')}o()}}),r.addEventListener("error",l=>{this.currentAudio===r&&(this.setButtonState(t,"error"),this.currentAudio=null,this.currentButton=null,this.progressUpdateInterval&&(clearInterval(this.progressUpdateInterval),this.progressUpdateInterval=null),s&&s.classList.remove("playing"),i(new Error("Audio playback failed")))}),r.load()})}setButtonState(e,t){e.classList.remove("supernal-tts-loading","supernal-tts-playing","supernal-tts-paused","supernal-tts-error");let s=e.querySelector(".supernal-tts-play-icon"),n=e.querySelector(".supernal-tts-text");switch(t){case"loading":e.classList.add("supernal-tts-loading"),e.disabled=!0,n&&(n.textContent="Loading...");break;case"playing":e.classList.add("supernal-tts-playing"),e.disabled=!1,s&&(s.innerHTML='<rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/>'),n&&(n.textContent="Pause");break;case"paused":e.classList.add("supernal-tts-paused"),e.disabled=!1,s&&(s.innerHTML='<path d="M8 5v14l11-7z"/>'),n&&(n.textContent="Resume");break;case"error":e.classList.add("supernal-tts-error"),e.disabled=!1,s&&(s.innerHTML='<path d="M12 2L2 7v10c0 5.55 3.84 9.95 9 11 5.16-1.05 9-5.45 9-11V7l-10-5z"/>'),n&&(n.textContent="Error");break;default:e.disabled=!1,s&&(s.innerHTML='<path d="M8 5v14l11-7z"/>'),n&&(n.textContent="Listen");break}}showError(e,t){let s=document.createElement("div");s.className="supernal-tts-error-tooltip",t.includes("development mode")?s.textContent=t:t.includes("Failed to fetch")?s.textContent="Service unavailable (dev mode)":s.textContent="Audio generation failed",e.parentNode?.appendChild(s),setTimeout(()=>{s.parentNode&&s.parentNode.removeChild(s)},3e3)}generateHash(e,t={}){let s=e+JSON.stringify(t),n=0;for(let o=0;o<s.length;o++){let i=s.charCodeAt(o);n=(n<<5)-n+i,n=n&n}return Math.abs(n).toString(36)}getCachedAudioUrl(e){let t=this.cache.get(e);if(!t)return null;if(Date.now()>t.expiry)return this.cache.delete(e),this.saveCacheToStorage(),null;let s=t.audioUrl;return s.startsWith("http")?s:`${this.apiUrl}${s}`}cacheAudioUrl(e,t,s={}){this.cache.set(e,{audioUrl:t,metadata:s,expiry:Date.now()+this.cacheExpiry,timestamp:Date.now()}),this.saveCacheToStorage()}loadCacheFromStorage(){try{let e=localStorage.getItem("supernal-tts-cache");if(e){let t=JSON.parse(e);this.cache=new Map(Object.entries(t))}}catch(e){console.warn("Failed to load TTS cache:",e)}}saveCacheToStorage(){try{let e=Object.fromEntries(this.cache);localStorage.setItem("supernal-tts-cache",JSON.stringify(e))}catch(e){console.warn("Failed to save TTS cache:",e)}}static init(e){return window.SupernalTTSInstance?(console.debug("SupernalTTS already initialized, returning existing instance"),window.SupernalTTSInstance):(window.SupernalTTSInstance=new S(e),window.SupernalTTSInstance)}static getInstance(){return window.SupernalTTSInstance}addWidget(e,t,s={}){let n=null;if(typeof e=="string"?n=document.querySelector(e):n=e,!n){console.error("TTS Widget: Element not found");return}n.classList.add("supernal-tts-widget"),n.dataset.text=this.scrubText(t),s.voice&&(n.dataset.voice=s.voice),s.provider&&(n.dataset.provider=s.provider),this.setupWidget(n)}};if(typeof window<"u")if(window.SupernalTTS)console.debug("SupernalTTS already loaded, skipping redeclaration");else{window.SupernalTTS=L;let S=()=>{if(!window.SupernalTTSInstance){let s=document.querySelector("script[data-supernal-tts-auto-init]");if(s&&s.dataset){let n=JSON.parse(s.dataset.supernalTtsAutoInit||"{}");L.init(n)}}let t=document.querySelectorAll(".supernal-tts-widget");if(t.length>0&&window.SupernalTTSInstance){let s=window.SupernalTTSInstance;t.forEach(n=>{n.classList.contains("supernal-tts-widget-initialized")||s.setupWidget(n)})}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",S):S()}B=L});var b=class{static{this.instance=null}static{this.loadPromise=null}static async load(e={}){if(this.instance)return this.instance;if(this.loadPromise)return this.loadPromise;let{version:t="major",mode:s="auto",cdnUrl:n="https://unpkg.com/@supernal/tts-widget",timeout:o=3e3,onCdnFail:i,onCdnSuccess:r}=e;return this.loadPromise=this.loadWidget({version:t,mode:s,cdnUrl:n,timeout:o,onCdnFail:i,onCdnSuccess:r}),this.loadPromise}static async loadWidget(e){let{mode:t,version:s,cdnUrl:n,timeout:o,onCdnFail:i,onCdnSuccess:r}=e;if(t==="bundled")return console.log("[TTS Widget] Loading bundled version (mode: bundled)"),this.loadBundled();if(t==="cdn"||t==="auto")try{console.log("[TTS Widget] Attempting CDN load...");let a=await this.loadFromCdn(n,s,o);return console.log("[TTS Widget] CDN load successful"),r?.(),this.instance=a,a}catch(a){let l=a instanceof Error?a.message:String(a);if(console.warn("[TTS Widget] CDN load failed:",l),i?.(a instanceof Error?a:new Error(l)),t==="cdn")throw new Error(`Failed to load widget from CDN: ${l}`);return console.log("[TTS Widget] Falling back to bundled version"),this.loadBundled()}return this.loadBundled()}static async loadFromCdn(e,t,s){let n=this.resolveVersionPath(t),o=`${e}${n}/dist/widget.js`;console.log(`[TTS Widget] Loading from CDN: ${o}`);let i=new AbortController,r=setTimeout(()=>i.abort(),s);try{let a=import(o),l=new Promise((p,h)=>{setTimeout(()=>h(new Error(`CDN load timeout after ${s}ms`)),s)}),d=await Promise.race([a,l]);if(clearTimeout(r),!d||!d.SupernalTTS)throw new Error("CDN module missing SupernalTTS export");return this.instance=d.SupernalTTS,this.instance}catch(a){throw clearTimeout(r),a}}static async loadBundled(){try{let e=await Promise.resolve().then(()=>(C(),A));if(!e||!e.SupernalTTS)throw new Error("Bundled widget missing SupernalTTS export");return this.instance=e.SupernalTTS,this.instance}catch(e){let t=e instanceof Error?e.message:String(e);throw new Error(`Failed to load bundled widget: ${t}`)}}static resolveVersionPath(e){return e==="major"?`@${this.getMajorVersion()}`:e==="latest"?"@latest":`@${e}`}static getMajorVersion(){{let e="1.3.1".match(/^(\d+)\./);if(e)return e[1]}return"1"}static reset(){this.instance=null,this.loadPromise=null}static getInstance(){return this.instance}},I=b;export{b as WidgetLoader,I as default};
96
96
  //# sourceMappingURL=loader.js.map